@design-ai/cli 4.57.0 → 4.59.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -0,0 +1,45 @@
1
+ // SDK adapter: route(brief, opts) and routes(). See docs/AGENT-SDK.md.
2
+
3
+ import { DESIGN_AI_HOME } from "../lib/paths.mjs";
4
+ import { readRouteManifestVersion, routeBrief, routeCatalog } from "../lib/route.mjs";
5
+ import {
6
+ optionalBoolean,
7
+ optionalInteger,
8
+ requireNonEmptyString,
9
+ requireOptions,
10
+ } from "./validate.mjs";
11
+
12
+ /**
13
+ * Recommend the best design-ai route(s), commands, skills, and knowledge files
14
+ * for a task brief. Pure, read-only adapter over `routeBrief` from cli/lib/route.mjs.
15
+ *
16
+ * @param {string} brief - Task brief text.
17
+ * @param {{limit?: number, explain?: boolean}} [opts]
18
+ * @returns {Array<object>} RouteResult[] — the same shape as `design-ai route --json`'s `routes` array.
19
+ */
20
+ export function route(brief, opts = {}) {
21
+ requireNonEmptyString(brief, "brief");
22
+ const options = requireOptions(opts, "route");
23
+ const limit = optionalInteger(options.limit, "limit", { fallback: 3, min: 1, max: 10 });
24
+ const explain = optionalBoolean(options.explain, "explain", false);
25
+
26
+ return routeBrief({
27
+ brief,
28
+ sourceRoot: DESIGN_AI_HOME,
29
+ limit,
30
+ explain,
31
+ });
32
+ }
33
+
34
+ /**
35
+ * List the full route catalog (all route ids with their static metadata),
36
+ * independent of any brief. Pure, read-only adapter over `routeCatalog`.
37
+ *
38
+ * @returns {{version: string, routes: Array<object>}} RouteCatalog
39
+ */
40
+ export function routes() {
41
+ return {
42
+ version: readRouteManifestVersion(DESIGN_AI_HOME),
43
+ routes: routeCatalog({ sourceRoot: DESIGN_AI_HOME }),
44
+ };
45
+ }
@@ -0,0 +1,55 @@
1
+ // SDK adapter: search(query, opts). See docs/AGENT-SDK.md.
2
+
3
+ import { DESIGN_AI_HOME } from "../lib/paths.mjs";
4
+ import { rankedSearchCorpus } from "../lib/search-ranked.mjs";
5
+ import { DEFAULT_SEARCH_DIRS, searchCorpus } from "../lib/search.mjs";
6
+ import {
7
+ optionalBoolean,
8
+ optionalInteger,
9
+ optionalString,
10
+ requireNonEmptyString,
11
+ requireOptions,
12
+ } from "./validate.mjs";
13
+
14
+ function resolveDirs(dirName) {
15
+ if (!dirName) return DEFAULT_SEARCH_DIRS;
16
+ if (!DEFAULT_SEARCH_DIRS.includes(dirName)) {
17
+ throw new Error(`dir must be one of: ${DEFAULT_SEARCH_DIRS.join(", ")}`);
18
+ }
19
+ return [dirName];
20
+ }
21
+
22
+ /**
23
+ * Search the local design-ai markdown corpus. Pure, read-only adapter over
24
+ * `searchCorpus` / `rankedSearchCorpus` from cli/lib/search.mjs and
25
+ * cli/lib/search-ranked.mjs.
26
+ *
27
+ * @param {string} query - Search query text.
28
+ * @param {{dir?: string, limit?: number, ranked?: boolean}} [opts]
29
+ * @returns {Array<object>} SearchHit[] — line hits by default, ranked (score + matchedTokens) hits when `ranked: true`.
30
+ */
31
+ export function search(query, opts = {}) {
32
+ requireNonEmptyString(query, "query");
33
+ const options = requireOptions(opts, "search");
34
+
35
+ const dirName = optionalString(options.dir, "dir");
36
+ const dirs = resolveDirs(dirName);
37
+ const limit = optionalInteger(options.limit, "limit", { fallback: 20, min: 1, max: 500 });
38
+ const ranked = optionalBoolean(options.ranked, "ranked", false);
39
+
40
+ if (ranked) {
41
+ return rankedSearchCorpus({
42
+ query,
43
+ designAiPath: DESIGN_AI_HOME,
44
+ dirs,
45
+ limit,
46
+ }).hits;
47
+ }
48
+
49
+ return searchCorpus({
50
+ query,
51
+ designAiPath: DESIGN_AI_HOME,
52
+ dirs,
53
+ limit,
54
+ });
55
+ }
@@ -0,0 +1,48 @@
1
+ // Input validation helpers shared by the SDK adapters (cli/sdk/*.mjs).
2
+ // Fail fast with a clear Error on bad input, per docs/AGENT-SDK.md Phase A.
3
+
4
+ export function requireNonEmptyString(value, label) {
5
+ if (typeof value !== "string" || value.trim() === "") {
6
+ throw new Error(`${label} must be a non-empty string`);
7
+ }
8
+ return value;
9
+ }
10
+
11
+ export function optionalString(value, label, fallback = "") {
12
+ if (value === undefined || value === null) return fallback;
13
+ if (typeof value !== "string") {
14
+ throw new Error(`${label} must be a string`);
15
+ }
16
+ return value;
17
+ }
18
+
19
+ export function optionalBoolean(value, label, fallback = false) {
20
+ if (value === undefined || value === null) return fallback;
21
+ if (typeof value !== "boolean") {
22
+ throw new Error(`${label} must be a boolean`);
23
+ }
24
+ return value;
25
+ }
26
+
27
+ // `zeroMeansUnset: true` is for options where the underlying cli/lib function
28
+ // treats 0 itself as "not set, use the library default" (e.g. learningLimit,
29
+ // recallLimit in prompt.mjs/pack.mjs use `learningLimit || 12`). In that case
30
+ // an explicit 0 is accepted and passed through unchecked against min/max,
31
+ // exactly like omitting the option.
32
+ export function optionalInteger(value, label, { fallback = 0, min = -Infinity, max = Infinity, zeroMeansUnset = false } = {}) {
33
+ if (value === undefined || value === null) return fallback;
34
+ if (zeroMeansUnset && value === 0) return 0;
35
+ const num = Number(value);
36
+ if (!Number.isInteger(num) || num < min || num > max) {
37
+ throw new Error(`${label} must be an integer from ${min} to ${max}`);
38
+ }
39
+ return num;
40
+ }
41
+
42
+ export function requireOptions(opts, label) {
43
+ if (opts === undefined || opts === null) return {};
44
+ if (typeof opts !== "object" || Array.isArray(opts)) {
45
+ throw new Error(`${label} options must be a plain object`);
46
+ }
47
+ return opts;
48
+ }
@@ -0,0 +1,17 @@
1
+ // SDK adapter: version(). See docs/AGENT-SDK.md.
2
+
3
+ import { collectVersionReport } from "../commands/version.mjs";
4
+
5
+ /**
6
+ * Report the CLI package version and the plugin/corpus version. Pure,
7
+ * read-only adapter over `collectVersionReport` from cli/commands/version.mjs.
8
+ *
9
+ * @returns {{cli: string, corpus: string}} version summary.
10
+ */
11
+ export function version() {
12
+ const report = collectVersionReport();
13
+ return {
14
+ cli: report.versions.cli,
15
+ corpus: report.versions.plugin,
16
+ };
17
+ }
@@ -0,0 +1,98 @@
1
+ # Agent SDK design
2
+
3
+ > Status: draft / planning — 2026-07-04
4
+
5
+ This document opens the Agent SDK phase — the fast-follow chosen in [NEXT-SURFACE-DECISION.md](NEXT-SURFACE-DECISION.md), now unblocked because the CLI recall interface has been stable across two releases (`--with-recall` / `learn --recall` shipped in v4.57.0 and stayed stable through v4.58.0's `route --explain` enrichment).
6
+
7
+ Nothing here is shipped until a phase below is implemented and release-gated. Until then, the only supported programmatic entry to design-ai is the CLI and the MCP server.
8
+
9
+ ## Goal
10
+
11
+ Let an external Node.js program — an agent runtime, a build script, a custom tool — use design-ai's deterministic design capabilities **as importable functions**, without shelling out to the CLI or spawning the MCP server. The SDK is a thin, documented, semver-stable adapter over the same `cli/lib` functions the CLI and MCP already call, so a capability that ships in the CLI is instantly available to an SDK consumer.
12
+
13
+ The decision record scored this surface highest on leverage and learning synergy precisely because it reuses the shared library verbatim: `route`, `prompt`, `pack`, `search --ranked`, `recall`, and `check` are already pure functions in `cli/lib`.
14
+
15
+ ## Non-goals
16
+
17
+ - No new capabilities. The SDK exposes existing CLI/MCP behavior; it does not add design logic.
18
+ - No runtime dependencies, no network calls, no telemetry — same posture as the CLI.
19
+ - No exposure of the entire `cli/lib` internal surface. The SDK is a curated, stable subset; `cli/lib/*` stays internal and free to refactor.
20
+ - No new process model — the SDK runs in the caller's process, deterministic and synchronous where the underlying functions are.
21
+ - No model inference or fine-tuning (unchanged product stance).
22
+
23
+ ## The stable surface
24
+
25
+ A single curated entry (`cli/sdk/index.mjs`) re-exports a small set of adapter functions with **their own stable signatures**, independent of the internal `cli/lib` shapes. Internal functions may be renamed or refactored; the SDK adapter absorbs that so the public API stays put.
26
+
27
+ Proposed surface (Phase A — read-only verbs):
28
+
29
+ ```js
30
+ import { route, prompt, pack, search, recall, check, routes, version } from "@design-ai/cli/sdk";
31
+
32
+ route(brief, { limit = 3, explain = false }) // → RouteResult[]
33
+ prompt(brief, { routeId, withLearning, learningCategory, learningLimit, withRecall, recallLimit }) // → PromptPlan
34
+ pack(brief, { routeId, maxBytes, withLearning, learningCategory, learningLimit, withRecall, recallLimit }) // → Pack
35
+ search(query, { dir, limit = 20, ranked = false }) // → SearchHit[] (ranked: BM25 hits with scores)
36
+ recall(query, { limit = 5, category = "" }) // → { corpus, learning } (combined recall view)
37
+ check(artifact, { routeId = "", strict = false }) // → CheckReport
38
+ routes() // → RouteCatalog
39
+ version() // → { cli, corpus }
40
+ ```
41
+
42
+ Every function is a pure adapter: it validates its inputs, calls the corresponding `cli/lib` function with the resolved package root, and returns a plain JSON-serializable object — the same shape the CLI's `--json` mode emits, which is already a contract covered by smoke tests. No function writes files or reads the network in Phase A. `recall` and the `withRecall`/`withLearning` options read the local corpus and the user's local `learning.json` (via `DESIGN_AI_LEARNING_FILE`) exactly as the CLI does; nothing else is read.
43
+
44
+ ## Packaging
45
+
46
+ Add an `exports` map to `package.json`:
47
+
48
+ ```json
49
+ "exports": {
50
+ "./sdk": "./cli/sdk/index.mjs",
51
+ "./package.json": "./package.json"
52
+ }
53
+ ```
54
+
55
+ - `@design-ai/cli/sdk` is the one public import path. The bare package (`.`) intentionally stays unexported so `import "@design-ai/cli"` does not accidentally couple callers to internals; the CLI is invoked as a bin, the SDK via the explicit subpath.
56
+ - `cli/` is already in `files`, so `cli/sdk/` ships with the package with no `files` change.
57
+ - The `package-contents` audit and `package:smoke` must cover the new entry: a packed-tarball smoke that `import`s `@design-ai/cli/sdk` and calls `route`/`search --ranked`/`recall` and asserts deterministic output.
58
+
59
+ ## Stability contract
60
+
61
+ - The `@design-ai/cli/sdk` surface is **semver-stable**: additive changes are minor, signature/return changes are major. This is stated in the SDK reference doc and enforced by SDK contract tests that pin the exported names and return-shape keys.
62
+ - `cli/lib/*` remains **internal and unstable** — importing `@design-ai/cli/cli/lib/...` is unsupported. The adapter layer is the seam that lets internals refactor (as they did repeatedly during the retrieval work) without breaking SDK consumers.
63
+ - Determinism: same inputs → same outputs, matching the CLI. The SDK adds no randomness or time-dependence.
64
+
65
+ ## Phased plan
66
+
67
+ ### Phase A — read-only SDK core
68
+
69
+ The verbs above (`route`, `prompt`, `pack`, `search`, `recall`, `check`, `routes`, `version`) as pure adapters over existing `cli/lib` functions. Read-only: no file writes, no network, no learning-usage sidecar writes (the SDK's `prompt`/`pack` default to not recording usage, unlike the CLI's opt-in `--with-learning` sidecar write — an SDK caller opts in explicitly if that is added later).
70
+
71
+ Verification gates:
72
+ - `node --test` unit coverage for each adapter: signature, option defaults, return-shape keys, determinism, and parity with the CLI `--json` output for a fixed brief.
73
+ - SDK contract test pinning the exported names and the return-shape key sets (the semver anchor).
74
+ - `npm run audit` 8/8 (the SDK reference doc's links resolve; frontmatter valid).
75
+ - `npm run release:check` additions: packed-tarball smoke that imports `@design-ai/cli/sdk` from the installed package and exercises `route`/`search`(ranked)/`recall`, plus a registry-smoke parity check after publish.
76
+ - `npm run release:metadata` unchanged (README stance preserved).
77
+
78
+ ### Phase B — optional, explicit local writes
79
+
80
+ Only if demand appears: opt-in adapters that mirror the CLI's local-write commands (`learn.remember`, `learn.feedback`, `check` with capture), each requiring an explicit option and writing only the local learning profile, never the network. Deferred until an adopter needs it; Phase A is read-only.
81
+
82
+ ## Integration points
83
+
84
+ - **MCP server** already wraps the same `cli/lib` functions; the SDK and MCP stay in lockstep because both are thin layers over one core. No MCP change is required for Phase A.
85
+ - **Retrieval** (`search` ranked, `recall`, `withRecall`) flows into the SDK for free — the shared lexical scorer and the generated-index exclusion apply identically.
86
+ - **Docs**: a `docs/SDK.md` (or this file, promoted from draft) becomes the public SDK reference; the README install table gains an "SDK" row pointing to it.
87
+
88
+ ## Risks and open questions
89
+
90
+ Risks:
91
+ - **Semver commitment.** Once published, the SDK surface is a promise. Mitigation: keep Phase A small (8 verbs), pin names/shapes in a contract test, and treat the adapter as the only stable seam.
92
+ - **Return-shape coupling.** SDK returns mirror the CLI `--json` shapes; if those change, the SDK breaks. Mitigation: the same smoke/parity tests that already guard the CLI JSON guard the SDK, and shape changes are already major-version events.
93
+
94
+ Open questions (answer during Phase A implementation review):
95
+ 1. Export the bare package root (`.`) as an alias for `./sdk`, or keep `./sdk` the only path? (Leaning: `./sdk` only, to avoid implying the whole package is the SDK.)
96
+ 2. Ship TypeScript types (`.d.ts`) hand-written for the 8 verbs, or JSDoc-only for the zero-toolchain stance? (Leaning: JSDoc + a hand-written `sdk/index.d.ts` with no build step.)
97
+ 3. Does `prompt`/`pack` via the SDK ever write the learning-usage sidecar, or is that strictly a Phase B explicit opt-in? (Leaning: never in Phase A; read-only.)
98
+ 4. Is `check` in Phase A (read-only quality check) or deferred with the other write-adjacent verbs? (Leaning: Phase A — `check` is read-only when capture is off.)
package/docs/ROADMAP.md CHANGED
@@ -1,5 +1,73 @@
1
1
  # Roadmap
2
2
 
3
+ ## Phase 758 — Agent SDK Phase A Release (v4.59.0) ✓ ready
4
+
5
+ Ships the Agent SDK Phase A work (Phase 757) as an npm version: the curated, semver-stable `@design-ai/cli/sdk` surface — eight read-only adapter verbs (`route`, `prompt`, `pack`, `search`, `recall`, `check`, `routes`, `version`) over the same `cli/lib` functions the CLI and MCP already call. No new capabilities, no runtime dependencies, no network, no telemetry; read-only, deterministic, backward-compatible.
6
+
7
+ ### Verified
8
+ - All 8 audits passed.
9
+ - `npm run release:check` (unit tests incl. 61 SDK tests, strict audits, whitespace, package contents, release metadata, release self-tests, packed-tarball smoke that imports `@design-ai/cli/sdk`).
10
+ - `npm run release:metadata`.
11
+ - `git diff --check`.
12
+ - Main-branch GitHub Actions (`Design-AI audit`, `Deploy doc site`) passed for the constituent commits.
13
+
14
+ ### Versions
15
+ - `package.json` + `.claude-plugin/plugin.json`: 4.58.0 → 4.59.0.
16
+ - `vscode-extension/package.json`: remains 0.4.1.
17
+
18
+ ### What this enables
19
+ - design-ai's routing, prompt/pack generation, ranked search, recall, and artifact checks become plain importable functions for agent runtimes, build scripts, and custom tools — deterministic, in-process, zero-dependency — behind a semver-stable contract that insulates callers from internal `cli/lib` refactors.
20
+
21
+ ### What's still ahead
22
+ - Optional `cli/sdk/index.d.ts` hand-written type declarations (zero-build), and Phase B explicit local-write adapters — both deferred until an adopter needs them.
23
+
24
+ ## Phase 757 — Agent SDK (Phase A implemented, unreleased)
25
+
26
+ Opens the Agent SDK phase — the fast-follow chosen in [NEXT-SURFACE-DECISION.md](NEXT-SURFACE-DECISION.md), unblocked now that the recall interface has been stable across two releases (v4.57.0/v4.58.0). Scope, the stable surface, packaging, and the stability contract are defined in [AGENT-SDK.md](AGENT-SDK.md). No new capabilities, no runtime dependencies, no network, no telemetry; the SDK is a thin, semver-stable adapter over the same `cli/lib` functions the CLI and MCP already call.
27
+
28
+ Phase A landed in `main` (commit `326ed0a`) as `cli/sdk/`; it is code-complete and gated but **not yet released as an npm version** — shipping it is the next release decision.
29
+
30
+ ### Delivered (Phase A)
31
+ - [x] Read-only SDK core at `@design-ai/cli/sdk` — `route`, `prompt`, `pack`, `search` (incl. ranked), `recall`, `check`, `routes`, `version` as pure adapters with stable signatures; `exports` map added; no file writes / no network. `check` operates on artifact content (not a path), so it reads and writes nothing.
32
+ - [x] Unit coverage per adapter (signature, defaults, return-shape keys, determinism, CLI `--json` parity) plus an SDK contract test (`cli/sdk/index.test.mjs`) pinning exported names and return-shape keys — the semver anchor. 61 new tests, 540/540 total.
33
+ - [x] Packed-tarball smoke (`package-smoke.py`) that imports `@design-ai/cli/sdk` from the installed package and exercises `route`/`search` ranked/`recall`/`version`/`routes`/`prompt`/`pack`/`check`, asserting determinism and the Phase A no-`learningUsage` guarantee.
34
+ - [x] `docs/SDK.md` public reference + README/README.ko "Node.js / Agent SDK" install-table row + mkdocs nav.
35
+ - [x] Open questions from [AGENT-SDK.md](AGENT-SDK.md) resolved: bare root `.` not exported (only `./sdk`); usage sidecar never written in Phase A; `check` is in Phase A (read-only). TS `.d.ts` deferred — adapters carry JSDoc; a hand-written `sdk/index.d.ts` remains an optional follow-up.
36
+
37
+ ### Remaining
38
+ - [ ] Release decision: bundle Phase A into the next npm version (e.g. v4.59.0) — version bump, CHANGELOG, registry-smoke parity after publish.
39
+ - [ ] Optional follow-up: hand-written `cli/sdk/index.d.ts` type declarations for the 8 verbs (zero-build stance preserved).
40
+ - [ ] Phase B (optional, deferred until an adopter needs it): explicit local-write adapters (`learn.remember`/`feedback`, capture).
41
+
42
+ ## Phase 756 — Retrieval Across Surfaces and Corpus Depth Release (v4.58.0) ✓ ready
43
+
44
+ Groups the post-v4.57.0 retrieval completion and corpus work into one release: `route --explain` related-knowledge enrichment (retrieval now spans every surface), recall exclusion of generated index/meta files, the async-control and Korean B2B density knowledge files, and the registry-smoke assertion fix that realigns the live post-publish smoke with the shared scorer. Defaults are unchanged; the release is additive and backward-compatible.
45
+
46
+ ### Changed
47
+ - `route --explain` gains an advisory related-knowledge section (routing unchanged), completing retrieval across `search`/`prompt`/`pack`/`learn`/`route`; carried to MCP via the existing `design_ai_route` `explain` parameter.
48
+ - Recall injection excludes generated index/meta files so injected context is real design knowledge; raw `search --ranked` is unchanged.
49
+ - Added `knowledge/patterns/async-control.md` and `knowledge/i18n/korean-density-conventions.md` (corpus now 94 files), closing the remaining dogfood-named gaps.
50
+ - Fixed the stale `registry-smoke.py` learn-relevance token-order assertion so the live post-publish registry smoke matches the published package.
51
+
52
+ ### Verified
53
+ - All 8 audits passed.
54
+ - `npm run release:check` (unit tests, strict audits, whitespace, package contents, release metadata, release self-tests, packed-tarball smoke).
55
+ - `npm run release:metadata`.
56
+ - `git diff --check`.
57
+ - Main-branch GitHub Actions (`Design-AI audit`, `Deploy doc site`) passed for the constituent commits.
58
+
59
+ ### Versions
60
+ - `package.json` + `.claude-plugin/plugin.json`: 4.57.0 → 4.58.0.
61
+ - `vscode-extension/package.json`: remains 0.4.1.
62
+
63
+ ### What this enables
64
+ - Retrieval is uniform across every design-ai surface and injects real design knowledge, not index tables; the Korean corpus gains async-control and B2B density depth.
65
+ - Publishing v4.58.0 realigns `main` with the published package so the live registry smoke verifies cleanly.
66
+
67
+ ### What's still ahead
68
+ - Push the v4.58.0 tag, then verify npm publish (provenance), GitHub Release, public `npm run registry:smoke` (now skew-free), and docs deployment.
69
+ - Refresh the Homebrew formula SHA-256 and the [external-status.md](external-status.md) / README distribution status from published `4.57.0` to `4.58.0` after the tag tarball exists.
70
+
3
71
  ## Phase 755 — Local Retrieval Memory Release (v4.57.0) ✓ ready
4
72
 
5
73
  Groups the Phase 754 A+B retrieval work, the MCP ranked-search parameter, the `refs/` reference-page migration, and the docs-deploy retry hardening into one public package release. Scope and data boundaries are defined in [AI-LEARNING-PHASE2.md](AI-LEARNING-PHASE2.md); defaults are unchanged, so the release is additive and backward-compatible.
package/docs/SDK.md ADDED
@@ -0,0 +1,162 @@
1
+ # Agent SDK reference
2
+
3
+ > Status: shipped (Phase A) — read-only verbs, semver-stable surface
4
+
5
+ `@design-ai/cli/sdk` lets an external Node.js program — an agent runtime, a build script, a custom tool — use design-ai's deterministic design capabilities as importable functions, without shelling out to the CLI or spawning the MCP server. It is a thin, curated adapter over the same `cli/lib` functions the CLI and MCP server already call, so a capability that ships in the CLI is instantly available to an SDK consumer.
6
+
7
+ See [`AGENT-SDK.md`](AGENT-SDK.md) for the full design rationale, phased plan, and open questions. This page is the public reference for the shipped Phase A surface.
8
+
9
+ ## Install and import
10
+
11
+ The SDK ships inside the `@design-ai/cli` package (no separate install):
12
+
13
+ ```bash
14
+ npm install @design-ai/cli
15
+ ```
16
+
17
+ ```js
18
+ import { route, prompt, pack, search, recall, check, routes, version } from "@design-ai/cli/sdk";
19
+ ```
20
+
21
+ Only the `./sdk` subpath is exported — `import "@design-ai/cli"` (the bare package root) is intentionally not exported, so importing the SDK is always an explicit `@design-ai/cli/sdk` import. `cli/lib/*` is internal and unstable; do not import it directly.
22
+
23
+ ## Phase A: read-only
24
+
25
+ Every verb below is a pure, read-only adapter:
26
+
27
+ - It validates its inputs and throws a plain `Error` with a clear message on bad input (e.g. a non-string brief).
28
+ - It resolves the package root the same way the CLI does.
29
+ - It calls the corresponding `cli/lib` function and returns a plain JSON-serializable object — the same shape the CLI's `--json` mode emits.
30
+ - It performs no file writes, no network calls, and no learning-usage sidecar writes. This is a deliberate difference from the CLI: `prompt`/`pack`'s `withLearning` option in the SDK only **reads** the local learning profile to build context — it never records a usage event, unlike the CLI's `--with-learning` flag. There is no SDK equivalent of `check --learn` (capture) in Phase A.
31
+ - Given the same inputs, it returns the same outputs (determinism), matching the CLI.
32
+
33
+ ## Verbs
34
+
35
+ ### `route(brief, opts)`
36
+
37
+ Recommend the best design-ai route(s), commands, skills, and knowledge files for a task brief.
38
+
39
+ ```js
40
+ route(brief: string, opts?: { limit?: number, explain?: boolean }): RouteResult[]
41
+ ```
42
+
43
+ - `limit` — maximum route recommendations, 1-10. Default: `3`.
44
+ - `explain` — include route scoring, reference coverage, and related-knowledge detail. Default: `false`.
45
+
46
+ Returns an array of `RouteResult` objects (`id`, `label`, `score`, `confidence`, `matchedKeywords`, `command`, `skills`, `agents`, `knowledge`, `keywords`, `explanation`, plus `relatedKnowledge` when `explain: true`) — the same shape as the `routes` array in `design-ai route --json`.
47
+
48
+ ### `prompt(brief, opts)`
49
+
50
+ Build a ready-to-use agent prompt plan from a task brief.
51
+
52
+ ```js
53
+ prompt(brief: string, opts?: {
54
+ routeId?: string,
55
+ withLearning?: boolean,
56
+ learningCategory?: string,
57
+ learningLimit?: number,
58
+ withRecall?: boolean,
59
+ recallLimit?: number,
60
+ }): PromptPlan | null
61
+ ```
62
+
63
+ - `routeId` — force a route id instead of scoring the brief.
64
+ - `withLearning` — include brief-relevant local learning preferences (reads `DESIGN_AI_LEARNING_FILE`; **never** records usage, unlike the CLI's `--with-learning`).
65
+ - `learningCategory`, `learningLimit` (1-100) — scope/limit the learning context; require `withLearning`.
66
+ - `withRecall` — include brief-relevant shipped corpus knowledge.
67
+ - `recallLimit` (1-20) — limit recalled corpus files; requires `withRecall`.
68
+
69
+ Returns a `PromptPlan` object (`brief`, `version`, `route`, `slashCommand`, `referenceExamples`, `filesToRead`, `checklist`, `qualityCommand`, `prompt`, plus `learningContext`/`recall` when requested) — the same shape as `design-ai prompt --json`, minus `learningUsage` (Phase A never writes it).
70
+
71
+ ### `pack(brief, opts)`
72
+
73
+ Build a ready-to-use prompt plus a bounded context-file bundle from a task brief.
74
+
75
+ ```js
76
+ pack(brief: string, opts?: {
77
+ routeId?: string,
78
+ maxBytes?: number,
79
+ withLearning?: boolean,
80
+ learningCategory?: string,
81
+ learningLimit?: number,
82
+ withRecall?: boolean,
83
+ recallLimit?: number,
84
+ }): Pack
85
+ ```
86
+
87
+ - `maxBytes` — maximum context bytes to include, 1000-1,000,000. Default: `120000`.
88
+ - The remaining options mirror `prompt`'s learning/recall options.
89
+
90
+ Returns a `Pack` object (`brief`, `version`, `maxBytes`, `usedBytes`, `summary`, `warnings`, `plan`, `files`, `markdown`) — the same shape as `design-ai pack --json`, minus `learningUsage`.
91
+
92
+ ### `search(query, opts)`
93
+
94
+ Search the local design-ai markdown corpus.
95
+
96
+ ```js
97
+ search(query: string, opts?: { dir?: string, limit?: number, ranked?: boolean }): SearchHit[]
98
+ ```
99
+
100
+ - `dir` — restrict to one corpus directory: `knowledge`, `examples`, `skills`, `docs`, `agents`, or `commands`.
101
+ - `limit` — maximum hits, 1-500. Default: `20`.
102
+ - `ranked` — rank results with the deterministic lexical (BM25-style) scorer instead of returning raw line hits. Default: `false`.
103
+
104
+ Returns `SearchHit[]`. Unranked hits: `{ file, relPath, lineNumber, preview }`. Ranked hits: `{ file, relPath, score, matchedTokens, preview }` — the same shapes as `design-ai search --json` and `design-ai search --ranked --json`.
105
+
106
+ ### `recall(query, opts)`
107
+
108
+ Recall brief-relevant shipped corpus knowledge and local learning-profile entries for a query — a combined read-only view.
109
+
110
+ ```js
111
+ recall(query: string, opts?: { limit?: number, category?: string }): { corpus: object, learning: object }
112
+ ```
113
+
114
+ - `limit` — applies to both the corpus and learning lists, 1-20. Default: `5`.
115
+ - `category` — scopes only the learning list.
116
+
117
+ Returns `{ corpus: { candidateCount, selectedCount, selected }, learning: { mode, candidateCount, selectedCount, selected } }` — the same shape as `design-ai learn --recall --json`.
118
+
119
+ ### `check(artifact, opts)`
120
+
121
+ Check a generated design Markdown artifact for grounding, accessibility, responsive, unresolved-marker, and route-specific requirements.
122
+
123
+ ```js
124
+ check(artifact: string, opts?: { routeId?: string, strict?: boolean }): CheckReport
125
+ ```
126
+
127
+ - `routeId` — add route-specific checks (e.g. `component-spec`, `palette-from-brand`). Must be a known route id.
128
+ - `strict` — accepted for CLI-flag parity but has no effect on the returned report; the SDK never sets a process exit code. Inspect `report.status` yourself.
129
+
130
+ Returns a `CheckReport` object (`filePath`, `status`, `passes`, `warnings`, `failures`, `total`, `score`, `results`, plus `routeId` when passed) — the same shape as `design-ai check --json` (minus any `--learn` capture, which Phase A does not support).
131
+
132
+ ### `routes()`
133
+
134
+ List the full route catalog (every route id with its static metadata), independent of any brief.
135
+
136
+ ```js
137
+ routes(): { version: string, routes: RouteResult[] }
138
+ ```
139
+
140
+ Returns the same shape as `design-ai route --list --json`.
141
+
142
+ ### `version()`
143
+
144
+ Report the CLI package version and the plugin/corpus version.
145
+
146
+ ```js
147
+ version(): { cli: string, corpus: string }
148
+ ```
149
+
150
+ ## Stability contract
151
+
152
+ `@design-ai/cli/sdk` is **semver-stable**:
153
+
154
+ - Additive changes (new optional fields, new opt-in options) are minor version bumps.
155
+ - Signature or return-shape changes are major version bumps.
156
+ - The 8 exported names (`route`, `prompt`, `pack`, `search`, `recall`, `check`, `routes`, `version`) and their return-shape key sets are pinned by an SDK contract test (`cli/sdk/index.test.mjs`) — this is the semver anchor. If a name or a top-level key drifts unintentionally, that test fails.
157
+ - `cli/lib/*` remains internal and unstable. Only `@design-ai/cli/sdk` is a supported import path.
158
+ - Determinism: the same inputs always produce the same outputs, with no randomness or time-dependence added by the adapter layer.
159
+
160
+ ## Phase B (not yet shipped)
161
+
162
+ Phase A is read-only by design. A future Phase B may add opt-in, explicit local-write adapters mirroring the CLI's local-write commands (`learn.remember`, `learn.feedback`, `check` with capture) — deferred until an adopter needs it. See [`AGENT-SDK.md`](AGENT-SDK.md#phase-b-optional-explicit-local-writes) for the current plan.
@@ -1,22 +1,22 @@
1
1
  # External Publication Status
2
2
 
3
- > Checked: 2026-07-02
3
+ > Checked: 2026-07-04
4
4
  > Scope: npm registry, GitHub Pages, Homebrew tap, VS Code Marketplace, Claude/Codex MCP
5
5
 
6
6
  ## Summary
7
7
 
8
- Local release readiness is verified, GitHub Pages docs are publicly reachable, GitHub Release `v4.56.0` is published, and the Homebrew tap formula points at the `v4.56.0` release source tarball with a verified SHA-256. npm is publicly published at `@design-ai/cli@4.56.0`; publish run `28569283984` succeeded with provenance and the public registry smoke passed. The VS Code extension `sungjin.design-ai-vscode` is published to the VS Code Marketplace at version `0.4.1`; the Gallery API is reachable. The public npm MCP entrypoint and the local Claude Code / Codex MCP client registrations were rechecked on 2026-07-02.
8
+ npm is publicly published at `@design-ai/cli@4.58.0` (npm dist-tag `latest` = `4.58.0`); publish run from tag `v4.58.0` succeeded with provenance and all pre-publish gates green. After fixing the remaining stale learn-relevance score-type assertions in `tools/audit/registry-smoke.py` (`16e97aa`), the live `npm run registry:smoke` passes cleanly against published `@design-ai/cli@4.58.0` ("Registry smoke passed"), covering the retrieval surfaces (index/ranked/embeddings/recall) and route enrichment. GitHub Release `v4.58.0` is published, and the Homebrew tap formula points at the `v4.58.0` release source tarball with a verified SHA-256. The VS Code extension `sungjin.design-ai-vscode` remains published at `0.4.1`. GitHub Pages docs are publicly reachable.
9
9
 
10
10
  ## Results
11
11
 
12
12
  | Surface | Checked target | Result | Evidence |
13
13
  |---|---|---|---|
14
- | npm registry | `@design-ai/cli` | Published latest is `4.56.0`; publish run `28569283984` succeeded and public registry smoke passed for `@design-ai/cli@4.56.0`. | `evidence/cli-logs/npm-registry-status.log`, `evidence/cli-logs/npm-registry-smoke.log`, `evidence/cli-logs/npm-publish-v4.56.0-success.log` |
14
+ | npm registry | `@design-ai/cli` | Published latest is `4.58.0` (tag `v4.58.0`, provenance). Pre-publish packed-tarball smoke and post-fix live `npm run registry:smoke` both pass for `@design-ai/cli@4.58.0`. | `npm view @design-ai/cli version` → `4.58.0`; live registry smoke "Registry smoke passed" |
15
15
  | GitHub Pages | `https://sungjin9288.github.io/design-ai/` | Published and reachable: HTTP `200`, design-ai MkDocs page rendered | `evidence/cli-logs/github-pages-status.log` |
16
- | Homebrew tap | `Formula/design-ai.rb` | Formula pinned to `v4.56.0` release source tarball with SHA-256 `507d2519296497defcd486c0ffc2b5164967a0bc540ddc31bc89502350688212`; Ruby syntax and `brew style` passed | `evidence/cli-logs/homebrew-formula-status.log` |
16
+ | Homebrew tap | `Formula/design-ai.rb` | Formula pinned to `v4.58.0` release source tarball with SHA-256 `45ec7fa4e82e7af38cdf948e1ad056a3758be848e5541013144e8d93d4c9da37` (recomputed from the published tag tarball) | `Formula/design-ai.rb` |
17
17
  | VS Code Marketplace | `sungjin.design-ai-vscode` | Published: run `28431571256` published `v0.4.1`, and the Marketplace Gallery API returned visible version `0.4.1` on 2026-07-02. | `evidence/cli-logs/vscode-marketplace-status.log`, `evidence/cli-logs/vscode-marketplace-secret-status.log`, `evidence/cli-logs/vscode-extension-vsce-package.log`, `evidence/cli-logs/vscode-publish-workflow-status.log` |
18
- | GitHub Release | `v4.56.0` | Published with release tarball asset `design-ai-cli-4.56.0.tgz` | `evidence/cli-logs/github-release-v4.56.0.log` |
19
- | MCP server | `@design-ai/cli@4.56.0` / local clone | Public npm `design-ai-mcp` responds to initialize and tools/list with 10 tools; local Codex and Claude Code both report `design-ai` MCP as configured and connected. | `evidence/cli-logs/npm-registry-smoke.log`, `evidence/cli-logs/design-ai-mcp-client-status.log` |
18
+ | GitHub Release | `v4.58.0` | Published for tag `v4.58.0` at commit `22dc8a9` | `gh release view v4.58.0` |
19
+ | MCP server | `@design-ai/cli@4.58.0` / local clone | Public npm `design-ai-mcp` responds to initialize and tools/list with 10 tools; local Codex and Claude Code both report `design-ai` MCP as configured and connected. | `evidence/cli-logs/npm-registry-smoke.log`, `evidence/cli-logs/design-ai-mcp-client-status.log` |
20
20
 
21
21
  ## Interpretation
22
22
 
@@ -12,7 +12,7 @@ generated_at: 2026-07-03
12
12
 
13
13
  | Layer | Count | Detail |
14
14
  | --- | --- | --- |
15
- | Knowledge files | 92 | 77 hand-written + 15 generated |
15
+ | Knowledge files | 94 | 79 hand-written + 15 generated |
16
16
  | Skills (PLAYBOOK + SKILL) | 20 | 20 with verification phase |
17
17
  | Worked examples | 221 | |
18
18
  | Extractors | 12 | |
@@ -30,12 +30,12 @@ generated_at: 2026-07-03
30
30
  | `conversational` | 5 | 5 | 0 |
31
31
  | `design-tokens` | 4 | 3 | 1 |
32
32
  | `game-ui` | 5 | 5 | 0 |
33
- | `i18n` | 6 | 6 | 0 |
33
+ | `i18n` | 7 | 7 | 0 |
34
34
  | `icons` | 1 | 0 | 1 |
35
35
  | `illustration` | 5 | 5 | 0 |
36
36
  | `layout` | 1 | 1 | 0 |
37
37
  | `motion` | 6 | 6 | 0 |
38
- | `patterns` | 30 | 24 | 6 |
38
+ | `patterns` | 31 | 25 | 6 |
39
39
  | `platforms` | 1 | 1 | 0 |
40
40
  | `print` | 6 | 6 | 0 |
41
41
  | `spatial` | 5 | 5 | 0 |
@@ -49,7 +49,7 @@ generated_at: 2026-07-03
49
49
 
50
50
  | File | Lines | Type | Title |
51
51
  | --- | --- | --- | --- |
52
- | [knowledge/COVERAGE.md](../knowledge/COVERAGE.md) | 741 | generated | Coverage report |
52
+ | [knowledge/COVERAGE.md](../knowledge/COVERAGE.md) | 743 | generated | Coverage report |
53
53
  | [knowledge/PRINCIPLES.md](../knowledge/PRINCIPLES.md) | 108 | hand-written | Design-AI principles |
54
54
 
55
55
  #### a11y
@@ -108,9 +108,10 @@ generated_at: 2026-07-03
108
108
  | File | Lines | Type | Title |
109
109
  | --- | --- | --- | --- |
110
110
  | [knowledge/i18n/korean-app-store-visual.md](../knowledge/i18n/korean-app-store-visual.md) | 223 | hand-written | Korean app store visual design |
111
+ | [knowledge/i18n/korean-density-conventions.md](../knowledge/i18n/korean-density-conventions.md) | 108 | hand-written | Korean B2B density conventions |
111
112
  | [knowledge/i18n/korean-document-style.md](../knowledge/i18n/korean-document-style.md) | 301 | hand-written | Korean document style |
112
113
  | [knowledge/i18n/korean-payments.md](../knowledge/i18n/korean-payments.md) | 211 | hand-written | Korean payments |
113
- | [knowledge/i18n/korean-product-conventions.md](../knowledge/i18n/korean-product-conventions.md) | 96 | hand-written | Korean product UX conventions |
114
+ | [knowledge/i18n/korean-product-conventions.md](../knowledge/i18n/korean-product-conventions.md) | 98 | hand-written | Korean product UX conventions |
114
115
  | [knowledge/i18n/korean-publishing.md](../knowledge/i18n/korean-publishing.md) | 139 | hand-written | Korean app store & publishing requirements |
115
116
  | [knowledge/i18n/korean-typography.md](../knowledge/i18n/korean-typography.md) | 123 | hand-written | Korean (Hangul) typography for product UI |
116
117
 
@@ -151,6 +152,7 @@ generated_at: 2026-07-03
151
152
 
152
153
  | File | Lines | Type | Title |
153
154
  | --- | --- | --- | --- |
155
+ | [knowledge/patterns/async-control.md](../knowledge/patterns/async-control.md) | 233 | hand-written | Async control patterns |
154
156
  | [knowledge/patterns/auth-flow-design.md](../knowledge/patterns/auth-flow-design.md) | 316 | hand-written | Authentication flow design |
155
157
  | [knowledge/patterns/b2b-onboarding-flows.md](../knowledge/patterns/b2b-onboarding-flows.md) | 182 | hand-written | B2B onboarding flows |
156
158
  | [knowledge/patterns/brand-identity.md](../knowledge/patterns/brand-identity.md) | 238 | hand-written | Brand identity |
@@ -162,8 +164,8 @@ generated_at: 2026-07-03
162
164
  | [knowledge/patterns/document-typography.md](../knowledge/patterns/document-typography.md) | 248 | hand-written | Document typography |
163
165
  | [knowledge/patterns/email-design.md](../knowledge/patterns/email-design.md) | 338 | hand-written | Email design |
164
166
  | [knowledge/patterns/empty-states.md](../knowledge/patterns/empty-states.md) | 263 | hand-written | Empty states |
165
- | [knowledge/patterns/error-states.md](../knowledge/patterns/error-states.md) | 318 | hand-written | Error states |
166
- | [knowledge/patterns/form-design.md](../knowledge/patterns/form-design.md) | 237 | hand-written | Form design patterns |
167
+ | [knowledge/patterns/error-states.md](../knowledge/patterns/error-states.md) | 319 | hand-written | Error states |
168
+ | [knowledge/patterns/form-design.md](../knowledge/patterns/form-design.md) | 239 | hand-written | Form design patterns |
167
169
  | [knowledge/patterns/information-architecture.md](../knowledge/patterns/information-architecture.md) | 341 | hand-written | Information architecture |
168
170
  | [knowledge/patterns/landing-hero-design.md](../knowledge/patterns/landing-hero-design.md) | 283 | hand-written | Landing hero design |
169
171
  | [knowledge/patterns/landing-page-patterns.md](../knowledge/patterns/landing-page-patterns.md) | 681 | generated | Landing page patterns |