Back to marketplace

dsh-assembler

Agent & Workflow

TT-Wang/dsh-assembler

Assemble a working AI agent from one sentence and hand it over, using a capability catalog and induction pipeline.

  • dsh-plugin
GitHub Stars
1GitHub
Views
2DSH Plugin Hub
Forks
0GitHub
Open issues
0GitHub Issues
Manifest version
0.0.1@dsh-external/dsh-assembler
Latest push
Sep 8, 2026GitHub
License
BSD-3-ClauseJavaScript
Plugin type
ClientRuns in the Web Client

Verification and compatibility

This section shows evidence collected by the catalog. Undeclared information is labeled as unknown.

Static checked
01Exact source: github · @dsh-external/dsh-assembler@0.0.102Validated: Aug 26, 202603Verified Harness: 0.1.0-rc.7
Current-version compatibility
Verified on the catalog Harness version
Declared Harness range
Not declared
Declared platforms
Not declared
Profiles
web
Build approval
Unknown
Permissions
Not declared
External services
Not declared
Telemetry
Unknown
No known risk flags found

This is not a security endorsement. Review source, permissions, and configuration before installing.

View evidence and scope

Verification covers only the named source, version, and Harness environment. It does not guarantee future compatibility.

  • github:TT-Wang/dsh-assembler#02f74ca0bcf8e10a855835e696c3b565cf8889bf
  • The manifest and static structure passed checks; a runtime load check has not completed.

README

View source

dsh-assembler — Vibe Assembly for DSH

English | 中文

Assemble a working AI agent from one sentence — and be able to hand it over.

dsh-assembler is a DeepSeek Harness (DSH) plugin. You describe the agent you want in plain language ("build me a support bot that can look up orders, open tickets, and hand off to a human"); the assembler matches parts from a capability catalog, emits an agent preset, and then proves it works by running it in a real session. New sessions pick that preset from the roster and go.

The catalog grows through an induction pipeline: open-source libraries, public APIs, a client's own HTTP interfaces, and a client's documents all enter through one command each — and only past a quality gate. No glue code, only configuration.

How it works, from your seat: you describe the agent you want in one sentence. The assistant first shows you the architecture — capabilities, data model, workflow, and any gaps the catalog cannot cover (each gap is your call: build the missing part on the spot, degrade, or drop it) — and waits for your go-ahead. Parts are then found by instant catalog search, with every candidate priced (what its manual adds to the agent's prompt each turn, whether it spawns a process, which credentials it needs). The preset is emitted deterministically with every safety gate intact, and an independent examiner proves it works by running it in a real session before it reaches you — together with its web page, a supply-chain BOM, and a self-check pack it can re-run after any later change.

No graduation penalty: everything is a real, inspectable artifact — parts are ordinary processes with pinned provenance, a delivered agent is a git-diffable text composition plus its BOM, and the execution layer is framework-agnostic. Outgrow the assembler and you keep everything: the parts keep running, the presets keep mounting, nothing is held hostage.


At a glance

Catalog103 parts / 311 tools — 71 library-backed, 27 service-backed, 5 first-party (index/catalog.yml)
Verificationevery assembly ends with an independent black-box probe in a real session; every web page passes a reachability gate and a live-session loop gate
Wall timea single agent typically lands in minutes, verification included

What it does

  • Just talk — describe the agent in any DSH session. The assistant reviews the architecture with you (gaps included — each one is your decision), finds parts by instant search, assembles, and hands over only what an independent probe has verified.
  • Assemble-then-verify — after emitting a preset, the assembler derives an acceptance probe, runs it in a real session bound to that preset, and judges the reply against content-bearing marks. A FAIL comes back with evidence — which turn, which missing acceptance mark, what the agent actually replied — so the fix is surgical (swap a part, tighten the persona, re-emit under the same name) rather than a blind retry; a PASS also drops a selfcheck.json beside the preset, so the agent can be re-examined with the same probe after any later change. find → assemble → **verify**, on by default. The probe fails fast and honestly: an agent that asks the (absent) user for help is scored FAIL with the question quoted back, and every probe turn narrates its tool actions live.
  • Multi-turn scenario probes — the deriver picks the probe shape itself: one turn for pure-compute agents, a 2–4 turn scenario when the requirement implies work that outlives a turn (bookkeeping, filing, tracking). Scenario turns run in one session, and a later turn queries what an earlier turn wrote. Judgement stays black-box: replies only, never the trajectory.
  • Multi-agent teams — ask for a suite ("one agent for support, one for reconciliation, one for inventory — all on the same product/order data") and the agents are assembled one by one against one shared database, then the handoff itself is proven: an independent probe has one agent write a record and a different agent read it back.
  • Gap work orders — when selection reports a capability the catalog cannot yet cover, the assembler writes an actionable work order to <preset>/gaps/: the spec, the real induction-pipeline commands to build the missing part, and the exact re-assemble command that closes the loop. The writing of the missing part is handed to the calling agent (which has a full coding harness); the assembly spine stays deterministic, and the verdict always comes from the assembler's own black-box probe.
  • Assembly console (live) — every assembly dual-writes its action chain to <preset>/progress.log; a live console page (/assembler/ui/_console) polls it so a slow assembly is a visible, timestamped trail — "stuck or working?" answered at a glance — not a silent spinner. Selection, emission, probe rounds, per-turn tool actions and a 20s heartbeat all scroll there.
  • Knowledge packs (via: knowledge) — a client's manuals, SOPs and product catalogues enter as static teaching material, past a retrieval-hit gate (a probe question whose expected snippet cannot be found is refused), and are copied into the preset's kb/ at assembly time. The handover is one self-contained directory.
  • Credential contract (interface first, key later) — parts declare the environment variable they need and what it is for; the value never enters a preset. Unconfigured, a part still starts, listTools still succeeds, and a call returns an actionable error (which variable, what for, where to get it). On the assembly side: assembly succeeds, the probe degrades to SKIPPED with configuration guidance. Optional credentials (GitHub public reads, polite-pool mailtos) take the anonymous path and do not hold verification back.
  • Client-private catalogs — catalogs/<client>/ carries its own generated/, index/, capabilities.yml and knowledge/. One client's parts cannot surface in another's assembly, because isolation is by separate files, not by a filter someone can forget.
  • Service-backed parts — 13 live data services are wired in (weather, FX, geocoding, holidays, macro data, SEC filings, scholarly search, wiki facts, research graph, package intel, Feishu, Slack, GitHub Issues). A library part pins repo@rev; a service has no bytes to pin, so it pins terms + rate limit + data licence instead — and those travel into the BOM, because a client's compliance desk asks about them first.
  • Parts BOM — every assembly emits parts.lock.yml beside the preset: per part its origin, licence, verified status and the serverName actually mounted, plus knowledge sources with versions and the pending-credential list.
  • Federation cache — each part's tool list is cached under (connection config + adapter file fingerprint): cold ~5s, warm 0.002s.
  • persona lint — mechanical checks on the persona text: every tool it names must be in the mounted surface, step-numbered choreography is rejected, length is bounded.
  • Constitution & design notes — docs/CONSTITUTION.md (vibe assembly governed as a programming language, nine articles each with a test) · DESIGN.md states what the assembler does, what it deliberately does not, and where the boundary sits.

Every assembly ships a web UI

Assembly does not stop at the preset — every agent also gets an operable web frontend, served same-origin by the assembler on the host (/assembler/ui/<preset>). The page speaks the host's public wire (session.create / session.prompt / events.mux) and shares the same agent and the same durable workspace as the DSH conversation view; it pulls current state on open.

Each screenshot below is the real product of a single assembly (real assembly, real data, real capture — verdict lines quoted verbatim):

任务管理助手 … 要一个可以拖拽的任务看板页面 → 自动验证:PASS · 前端验收:页面门+环路门 PASS

Kanban (dark)

Approval desk

Data desk

Chat console

How it works:

  • Frontend template parts (via: frontend) — 7 templates: chat console (default for every preset), form desk, data desk, dashboard, drag-and-drop kanban, approval desk, file desk; the matcher picks exactly one by interaction shape
  • Look — built on Franken UI (the no-build HTML port of shadcn/ui, MIT), vendored locally — zero CDN dependency for offline/intranet delivery; auto light/dark
  • Page↔agent contract — pages embed a ```json fence contract in their prompts (no persona coupling); replies render as boards/tables/stat cards
  • Frontends are verified too — assemble-then-verify gains two frontend gates: page gate (HTTP 200 + slots filled) and loop gate (a real session opened with the page's exact parameters must echo a token); carried runs re-run the page gate only
  • One durable ledger — the equipment lane pins the default database (workspace data.db) and pre-builds its schema, so frontend sessions and DSH conversations write the same store
  • Pages the templates can't cover get written — the scaffold writer's seat: emit_app lays down a locked-vocabulary frontend skeleton (Vite + React + shadcn/ui + a fixed comms SDK, with record-desk and kanban starter pages you can copy whole), the assistant writes any page shape inside the single free zone src/pages/ against a PAGE-SPEC (every action routed face/wire/ai-thin/local); verify_app examines black-box through five gates (build / skeleton-lock / pages-lint / asset reach / behavior: face actions really execute SQL with effect assertions, wire actions run real-session probes), and deploy_app publishes into the preset same-origin with a snapshot for one-call rollback. Measured: a custom kanban's face round-trip at 5.1ms; the page and the chat sessions still share one ledger (two-faced delivery), the handoff proven by an independent examiner (one face writes, the other reads back)

Architecture

┌───────── Induction pipeline (supply chain) ────────────────────────────┐
│ OSS library / public API / client OpenAPI / client documents           │
│   → slice capabilities → MCP adapter → gate (smoke / retrieval) → catalog │
└───────────────────────────────────────────────────────────────────────┘
                              ↓
┌───────── Assembly (capability consumption) ───────────────────────────┐
│ capabilities.yml (public or client) + parallel federation             │
│   → instant parts search (priced candidates) → orchestrator decides   │
│   → deterministic emission + BOM + knowledge copied into kb/          │
│   → independent verification: probe in a real session → PASS/FAIL     │
└───────────────────────────────────────────────────────────────────────┘
                              ↓
┌───────── Delivery (FDE) ──────────────────────────────────────────────┐
│ multi-agent suite: emit_preset per agent, pinned to one sharedDb      │
│   → verify_shared_data handoff exam (one writes, another reads back)  │
│   → every agent carries its own parts.lock.yml BOM record             │
└───────────────────────────────────────────────────────────────────────┘
                              ↓
┌───────── Runtime (the harness's territory) ───────────────────────────┐
│ session picks the preset → DSH mounts each row → agent calls the parts │
└───────────────────────────────────────────────────────────────────────┘

The assembler is a Cordis plugin and its output is a Cordis composition manifest (one preset row = one plugin instance); parts are external MCP server processes bridged by @deepseek-ai/dsh-mcp-client. The assembler exists only at assembly time — once a session is running its process is gone and nothing changes.


Quick start

1. Install

Add the plugin to a DSH profile's patch layer (e.g. ~/.dsh/profiles/web/cordis.patch.yml):

- insert:
    - id: dsh-assembler
      name: '@dsh-external/dsh-assembler'

Dependency: "@dsh-external/dsh-assembler": "link:/path/to/dsh-assembler".

Some service parts need the operator's contact details (SEC mandates a contactable User-Agent; Crossref/OpenAlex polite pools want a mailto). Copy .env.example to .env and fill in your own — not credentials, but not anyone else's address either.

2. Assemble one agent

Open the DSH web UI and just say it:

帮我装配一个记账 agent:随手记收支,按月汇总,能设预算超支提醒,有查账网页

You will be shown the architecture (and any catalog gaps, each yours to decide) before anything is built; after your go-ahead the agent assembles, an independent probe verifies it in a real session, and you get the preset id, the verdict with evidence, and a web page at /assembler/ui/<preset>. Artifacts land in ~/.dsh/.agent-presets/<preset>/ — parts.lock.yml (BOM), selfcheck.json, progress.log.

3. Deliver a whole team (the FDE path)

Just ask for a suite of agents in one session — "give me a set of ops agents: one for support, one for reconciliation, one for inventory, one for content, all sharing the same product/order data". The assistant splits the request into focused agents, assembles and verifies each (emit_preset pins every member to one shared sharedDb), and the handoff itself is examined independently (verify_shared_data: one agent writes a record, a different agent reads it back — the reader's instruction may not contain the answer, the copy gate). Each agent's parts.lock.yml is its delivery record: verdict, part provenance, pending credentials, knowledge versions — all grown from artifacts.


Layout

dsh-assembler/
├── src/
│   ├── index.ts            # assembly core: catalog, federation, deterministic emission, BOM, equipment, knowledge
│   ├── orchestrated-tools.ts # the tool surface: parts search · deterministic emit · independent examiner
│   ├── verify.ts           # assemble-then-verify: probe machinery (single/scenario) + real-session driver
│   ├── capability-index.ts # BM25 parts search backend
│   ├── persona-lint.ts     # mechanical persona checks
│   ├── frontend.ts         # frontend lane: template emission + same-origin route + live console
│   └── client/             # browser half: assembly console tab in the DSH sidebar
├── capabilities.yml        # ★ public catalog: capability entries + mcp-servers + requiredSecrets
├── index/                  # ★ public part index (origin/licence/terms) + smoke reports
├── generated/              # ★ part library: 80+ MCP adapter servers, one directory each
├── catalogs/<client>/      # ★ client-private catalog: its own generated/ index/ capabilities.yml knowledge/
├── bench/results/          # assembly-quality ledgers (run-tagged, committed)
├── presets/
│   └── agent-template.yml  # preset template ({{persona}}/{{packageRows}}/{{extraRows}}/{{param:k}})
└── scripts/
    ├── index-add.mjs       # ★ induction pipeline CLI
    └── link-dsh.mjs        # link DSH peer packages

The capability catalog

Four kinds of capability:

viaSourceExample
packagea tool from this repo / an own plugin packagecrm-query
harnessa DSH built-in toolcontent-search
mcpMCP server tools (federated at assembly time)mcp-weather-forecast-current-weather, 229 of them
knowledgeclient teaching material (copied into kb/)acme-policies-kb

103 parts / 311 tools — 71 library-backed, 27 service-backed, 5 first-party.

Service-backed parts — live data and external systems

PartToolsSourceLicence / termsCredentials
package-registrypackage-info package-versions check-licensenpm + PyPI registriesregistry ToSnone
weather-forecastcurrent-weather daily-forecastOpen-MeteoCC-BY-4.0none
currency-rateslatest-rates historical-rate convert-amountFrankfurter (ECB data)Public-Domain-ECBnone
geocodegeocode-address reverse-geocodeOpenStreetMap NominatimODbL-1.0none
public-holidayslist-holidays is-workday available-countriesNager.DateMITnone
worldbank-datacountry-indicator common-indicatorsWorld Bank Open DataCC-BY-4.0none
sec-filingslookup-cik company-filingsU.S. SEC EDGARPublic-Domain-US-Govnone
scholar-searchsearch-published search-preprints doi-lookupCrossref + arXivCC0-1.0 / arXiv termsnone
wiki-factspage-summary search-entity entity-factsWikimedia (Wikipedia + Wikidata)CC-BY-SA-4.0none
research-graphsearch-works work-citations author-worksOpenAlexCC0-1.0none
feishu-messagingsend-message list-chats feishu-capabilities飞书开放平台Feishu API ToSFEISHU_APP_ID FEISHU_APP_SECRET
slack-messagingpost-message list-channels slack-capabilitiesSlack APISlack API ToSSLACK_BOT_TOKEN
github-issueslist-issues get-issue create-issue github-capabilitiesGitHub REST APIGitHub ToSGITHUB_TOKEN (optional)

First-party parts — thin shells over Node built-ins, zero third-party deps

binary-write(write-binary-file) · crypto-hash(hash-text, hmac-sign, generate-uuid) · compress-gzip(compress, decompress) · dns-lookup(resolve-domain, reverse-lookup) · book-intake(browser→workspace file channel + epub parsing) · webhook-intake(inbound event intake) · ai-call(standalone AI completion for apps) · static-deploy(publish a built site as an agent page) · app-scaffold(official create-vite scaffolding)

Library-backed parts, by domain

DomainParts (tool count)
Documents & officepdf-generate(4) · pdf-extract(3) · pdf-report(1) · docx-generate(3) · docx-extract(2) · pptx-generate(1) · excel-read-write(4) · zip-archive(4)
Data formatscsv-parse(3) · yaml-convert(2) · toml-parse(2) · xml-parse(3) · json-query(2) · json-schema-validate(2) · html-parse(4) · html-to-text(4)
Text processingmarkdown-render(3) · html-to-markdown(1) · readability-extract(2) · text-diff(3) · template-render(4) · fuzzy-search(4) · text-encoding(2)
Chinese languagepinyin-convert(2) · chinese-convert(2) · word-segment(2) · num-to-chinese(2)
Computationmath-eval(2) · currency-calc(4) · number-format(4) · semver-check(3) · geo-distance(3) · color-convert(2)
Time & calendarsdate-format(4) · cron-parse(2) · calendar-parse(3) · calendar-generate(4) · rrule-expand(2)
Databasessqlite-query(3) · mysql-query(4) · postgres-query(4)
Network & messaginghttp-request(4) · email-send(4) · email-fetch(4) · rss-parse(4)
Media & recognitionimage-process(4) · ocr-parse(3) · qrcode-generate(4) · barcode-generate(2) · exif-read(1) · file-type-detect(1)
Security & validationjwt-decode(2) · ip-utils(2) · string-validate(2) · fake-data(2) · phone-parse(2)
Engineering toolsgithub-api(4) · browser-automate(4) · url-slugify(3) · transliterate(2) · safe-filename(2)
  • email-send — send-email, verify-smtp-config, parse-email-addresses, create-test-account nodemailer/nodemailer@v6.9.13 · MIT
  • email-fetch — list-mailboxes, search-messages, fetch-message, list-message-summaries postalsys/imapflow@v1.0.162 · MIT
  • http-request — http-request, http-get, http-post, build-url axios/axios@v1.7.2 · MIT
  • html-parse — extract-text, extract-attributes, query-elements, serialize-html cheeriojs/cheerio@v1.0.0-rc.12 · MIT
  • csv-parse — parse-csv, unparse-csv, validate-csv papaparse/papaparse@5.4.1 · MIT
  • pdf-generate — create-pdf, merge-pdfs, extract-pages, pdf-info Hopding/pdf-lib@v1.17.1 · MIT
  • date-format — format-date, parse-date, date-diff, date-manipulate iamkun/dayjs@v1.11.11 · MIT
  • sqlite-query — query, execute, list-tables WiseLibs/better-sqlite3@v11.1.2 · MIT
  • github-api — get-user, get-repo, list-org-repos, search-repositories octokit/rest.js@v20.1.1 · MIT
  • markdown-render — render-markdown, render-markdown-inline, tokenize-markdown markedjs/marked@v12.0.2 · MIT
  • pdf-extract — get-pdf-text, get-pdf-info, search-pdf-text pdf-parse/pdf-parse@1.1.1 · MIT
  • excel-read-write — read-xlsx-file, write-xlsx-file, read-csv-file, write-csv-file exceljs/exceljs@v4.4.0 · MIT
  • docx-generate — docx-generate-text, docx-generate-table, docx-patch-document dolanmiu/docx@8.5.0 · MIT
  • zip-archive — zip-list-entries, zip-read-file, zip-create-archive, zip-update-archive cthackers/adm-zip@v0.5.12 · MIT
  • fuzzy-search — fuzzy-search, fuse-create-index, fuse-search-with-index, fuse-config krisk/Fuse@v7.0.0 · Apache-2.0
  • template-render — render-template, precompile-template, render-precompiled, validate-template handlebars-lang/handlebars.js@v4.7.8 · MIT
  • html-to-text — html-to-text, html-to-text-batch, html-to-text-table, html-to-text-links html-to-text/node-html-to-text@9.0.5 · MIT
  • xml-parse — xml-validate, xml-parse, xml-build NaturalIntelligence/fast-xml-parser@v4.4.0 · MIT
  • image-process — image-info, image-resize, image-convert, image-thumbnail lovell/sharp@v0.33.4 · Apache-2.0
  • rss-parse — parse-rss-string, parse-rss-url, extract-feed-items, parse-feed-metadata rbren/rss-parser@v3.13.0 · MIT
  • calendar-parse — parse-ics, parse-ics-file, fetch-ics-url jens-maus/node-ical@0.19.0 · Apache-2.0
  • calendar-generate — create-calendar, create-event, create-all-day-event, create-recurring-event sebbo2002/ical-generator@v7.1.0 · MIT
  • mysql-query — mysql-query, mysql-list-tables, mysql-describe-table, mysql-test-connection sidorares/node-mysql2@v3.10.0 · MIT
  • number-format — format-number, unformat-number, arithmetic, validate-number adamwdraper/Numeral-js@2.0.6 · MIT
  • qrcode-generate — qr-generate-png, qr-generate-data-url, qr-generate-svg, qr-generate-terminal soldair/node-qrcode@v1.5.3 · MIT
  • postgres-query — postgres-test-connection, postgres-list-tables, postgres-describe-table, postgres-query brianc/node-postgres@pg@8.12.0 · MIT
  • browser-automate — browser-open, browser-extract, browser-click, browser-screenshot microsoft/playwright@v1.45.0 · Apache-2.0
  • ocr-parse — ocr-languages, ocr-psm-modes, ocr-recognize naptha/tesseract.js@v5.1.0 · Apache-2.0
  • currency-calc — currency-calc, currency-format, currency-distribute, currency-parse scurker/currency.js@v2.0.4 · MIT
  • readability-extract — extract-article, extract-batch mozilla/readability@0.5.0 · MIT
  • pdf-report — create-report-pdf Hopding/pdf-lib@v1.17.1 · MIT
  • binary-write — write-binary-file first-party@- · BSD-3-Clause
  • text-diff — create-patch, apply-patch, diff-words kpdecker/jsdiff@v9.0.0 · BSD-3-Clause
  • crypto-hash — hash-text, hmac-sign, generate-uuid first-party@v- · BSD-3-Clause
  • math-eval — evaluate, unit-convert josdejong/mathjs@v15.2.0 · Apache-2.0
  • cron-parse — next-runs, describe-fields harrisiirak/cron-parser@v5.10.0 · MIT
  • semver-check — compare, satisfies, coerce-valid npm/node-semver@v7.8.5 · ISC
  • yaml-convert — yaml-to-json, json-to-yaml eemeli/yaml@v2.9.0 · ISC
  • pinyin-convert — to-pinyin, multi-tone zh-lx/pinyin-pro@v3.29.2 · MIT
  • chinese-convert — s2t, t2s nk2028/opencc-js@v1.4.1 · MIT AND Apache-2.0
  • html-to-markdown — html-to-markdown mixmark-io/turndown@v7.2.4 · MIT
  • text-encoding — decode-base64, encode-to-base64 ashtuchkin/iconv-lite@v0.7.3 · MIT
  • phone-parse — parse-phone, format-phone catamphetamine/libphonenumber-js@v1.13.11 · MIT
  • compress-gzip — compress, decompress first-party@v- · BSD-3-Clause
  • dns-lookup — resolve-domain, reverse-lookup first-party@v- · BSD-3-Clause
  • json-query — query, query-multi jmespath/jmespath.js@v0.16.0 · Apache-2.0
  • json-schema-validate — validate, check-schema ajv-validator/ajv@v8.20.0 · MIT
  • toml-parse — toml-to-json, json-to-toml squirrelchat/smol-toml@v1.8.0 · BSD-3-Clause
  • docx-extract — docx-to-text, docx-to-html mwilliamson/mammoth.js@v1.12.1 · BSD-2-Clause
  • pptx-generate — create-pptx gitbrent/pptxgenjs@v4.0.1 · MIT
  • barcode-generate — barcode-png, barcode-types metafloor/bwip-js@v4.11.2 · MIT
  • string-validate — validate-string, sanitize-string validatorjs/validator.js@v13.15.35 · MIT
  • fake-data — fake-records, fake-text faker-js/faker@v10.6.0 · MIT
  • num-to-chinese — to-chinese, from-chinese cnwhy/nzh@v1.0.14 · BSD-2-Clause
  • jwt-decode — decode-jwt, verify-jwt-hs256 panva/jose@v6.2.9 · MIT
  • ip-utils — parse-ip, cidr-match whitequark/ipaddr.js@v2.5.0 · MIT
  • transliterate — transliterate-text, make-slug dzcpy/transliteration@v2.6.1 · MIT
  • rrule-expand — expand-rrule, describe-rrule jkbrzt/rrule@v2.8.1 · BSD-3-Clause
  • exif-read — read-exif MikeKovarik/exifr@v7.1.3 · MIT
  • file-type-detect — detect-file-type sindresorhus/file-type@v22.0.2 · MIT
  • color-convert — convert-color, contrast-check Evercoder/culori@v4.0.2 · MIT
  • word-segment — segment-text, extract-keywords linonetwo/segmentit@v2.0.3 · MIT
  • geo-distance — distance, bearing, center-and-bounds manuelbieh/geolib@v3.3.14 · MIT
  • url-slugify — slugify, slugify-unique, slugify-custom sindresorhus/slugify@v3.0.0 · MIT
  • safe-filename — sanitize, sanitize-path sindresorhus/filenamify@v7.0.2 · MIT
  • package-registry — package-info, package-versions, check-license https://registry.npmjs.org · registry ToS
  • weather-forecast — current-weather, daily-forecast https://api.open-meteo.com/v1 · CC-BY-4.0
  • currency-rates — latest-rates, historical-rate, convert-amount https://api.frankfurter.dev/v1 · Public-Domain-ECB
  • geocode — geocode-address, reverse-geocode https://nominatim.openstreetmap.org · ODbL-1.0
  • public-holidays — list-holidays, is-workday, available-countries https://date.nager.at/api/v3 · MIT
  • worldbank-data — country-indicator, common-indicators https://api.worldbank.org/v2 · CC-BY-4.0
  • sec-filings — lookup-cik, company-filings https://data.sec.gov · Public-Domain-US-Gov
  • scholar-search — search-published, search-preprints, doi-lookup https://api.crossref.org · CC0-1.0 / arXiv terms
  • wiki-facts — page-summary, search-entity, entity-facts https://en.wikipedia.org/api/rest_v1 · CC-BY-SA-4.0
  • research-graph — search-works, work-citations, author-works https://api.openalex.org · CC0-1.0
  • feishu-messaging — send-message, list-chats, feishu-capabilities https://open.feishu.cn/open-apis · Feishu API ToS
  • slack-messaging — post-message, list-channels, slack-capabilities https://slack.com/api · Slack API ToS
  • github-issues — list-issues, get-issue, create-issue, github-capabilities https://api.github.com · GitHub ToS

Licences

Wrapped code (library + first-party parts): MIT 46 · Apache-2.0 7 · BSD-3-Clause 7 · ISC 2 · BSD-2-Clause 2 · MIT AND Apache-2.0 1

Data licence / terms (service-backed parts): CC-BY-4.0 2 · registry ToS 1 · Public-Domain-ECB 1 · ODbL-1.0 1 · MIT 1 · Public-Domain-US-Gov 1 · CC0-1.0 / arXiv terms 1 · CC-BY-SA-4.0 1 · CC0-1.0 1 · Feishu API ToS 1 · Slack API ToS 1 · GitHub ToS 1

All permissive — no copyleft exposure in code. Service parts additionally record the data licence, which is a different obligation: Nominatim is ODbL and Wikipedia is CC-BY-SA (attribution / share-alike duties), so both are recorded per entry and travel into each assembly's BOM.

Machine-readable inventory with every repo@rev, licence, terms, rate limit and tool description: index/catalog.yml.


Induction pipeline (the CLI)

The design premise is that the caller is an agent. The CLI does the deterministic half — fetch the source, inventory it, write a work order, install, gate, register — and leaves "which capabilities to slice, and how to write the adapter" to the caller. Every subcommand ends with one machine-readable JSON verdict.

# an OSS library
npm run index:add -- kpdecker/jsdiff --pkg diff --id text-diff
npm run index:verify -- text-diff        # install → smoke (exit 0 required) → independent listTools → report
npm run index:register -- text-diff      # idempotent; federation picks it up on the next assembly

# a public API (pins terms/rate-limit/data-licence instead of a version)
node scripts/index-add.mjs scaffold - --service https://api.open-meteo.com/v1 --id weather-forecast \
  --provider 'Open-Meteo' --license CC-BY-4.0 --terms https://open-meteo.com/en/terms --rate-limit 'free for non-commercial'

# a client's own system (the FDE day-one move): OpenAPI → endpoint work order → client catalog
node scripts/index-add.mjs from-spec <spec-url|file> --id <id> --client acme \
  --requires-secret "TOKEN:what it is for, commas allowed;OTHER:second one"

# a client's documents (past the retrieval gate)
node scripts/index-add.mjs knowledge <docs-dir> --id acme-policies --client acme --version 2026-08
# write probes.json (questions + expected snippets), then:
node scripts/index-add.mjs knowledge-verify acme-policies --client acme

# hands-free: one command, start to finish (needs a running web profile)
npm run index:auto -- sindresorhus/slugify --pkg @sindresorhus/slugify --id url-slugify

npm run index:check     # full regression: every part's smoke (network parts recorded SKIPPED when offline)
node scripts/index-add.mjs coverage   # capability map, for semantic dedup

The gate lives in the pipeline: if verify fails, register refuses. Dedup has two layers — a mechanical gate (same id / same npm package / same upstream repo), and capability-level judgement against the coverage map: the catalog holds capabilities, not libraries.


Sample output

Assemble-then-verify, multi-turn

For "a bookkeeping assistant that records income and expenses locally and can query and total them later", the deriver judged the work to outlive a turn and produced a 3-turn scenario:

自动验证:PASS — 多轮场景「prove the assistant persists entries to SQLite and can query/total them in later turns」共 3 轮,逐轮通过
  turn 1 ✓ "record income: project payment 8899, memo INV-7781…"      marks [INV-7781, 8899]
  turn 2 ✓ "record expense: office supplies 1200, memo OFFICE-2201…"  marks [OFFICE-2201, 1200]
  turn 3 ✓ "query the ledger, list every entry and total them"        marks [INV-7781, OFFICE-2201, 8899]

Turn 3 reads what turns 1 and 2 wrote, which is what makes state continuity provable rather than assumed. A pure-compute requirement gets a single-turn probe instead.

The four credential states

# required credential missing: assembly succeeds, probe SKIPPED, guidance given
自动验证:跳过(pending credential: SLACK_BOT_TOKEN — the assembly is correct but cannot reach the service;
              configure it and re-run the assembly to verify)
所需凭证:SLACK_BOT_TOKEN(pending) — Slack Bot User OAuth Token (xoxb-…)

# optional credential: the anonymous path is exercised and verification PASSes
自动验证:PASS — probe "inspect the public repo octocat/Hello-World…" passed
所需凭证:GITHUB_TOKEN(optional; degrades to anonymous when unset)

Parts BOM — parts.lock.yml (excerpt)

preset: currency-qr-assistant
parts:
  - capability: mcp-qrcode-generate-qr-generate-png
    server: qrcode-generate
    serverName: qrcode-generate-d0fb25cc   # read back from the preset bytes, always matches what mounts
    repo: soldair/node-qrcode
    rev: v1.5.3
    license: MIT
    verified: true
  - capability: mcp-weather-forecast-current-weather
    kind: service
    service: https://api.open-meteo.com/v1
    terms: https://open-meteo.com/en/terms
    rateLimit: free for non-commercial; commercial needs a subscription
knowledge:
  - id: acme-policies
    docs: 2
    source: ACME support knowledge base export
    version: 2026-08

Development

npm run link:dsh   # link DSH peer packages (needs DSH_SOURCE or ~/.dsh/source/current)
npm run build      # tsc → lib/
npm test           # build + the full unit-test chain (emission gates / verdicts / federation cache / tool-surface contract pins…)
npm run index:check   # full part-smoke regression

Changes under lib/ need a DSH web restart; changes to capabilities.yml do not (the catalog is read at assembly time).

Two environment facts to know when writing a network part: Node's global fetch ignores HTTP(S)_PROXY unless NODE_USE_ENV_PROXY=1, and the MCP SDK's StdioClientTransport only forwards a whitelist of environment variables, so proxy settings do not reach a part process by themselves. The pipeline handles both; a hand-written smoke must pass the environment down itself.


Licence

BSD-3-Clause. Upstream licences for the wrapped libraries are recorded per entry in index/catalog.yml; service-backed parts record their data licence and terms in their catalog entry the same way.

Comments

0
Newest first