@design-ai/cli 4.58.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.
- package/.claude-plugin/plugin.json +1 -1
- package/CHANGELOG.md +27 -0
- package/README.ko.md +3 -2
- package/README.md +3 -2
- package/cli/sdk/check-adapter.mjs +36 -0
- package/cli/sdk/index.mjs +22 -0
- package/cli/sdk/pack-adapter.mjs +55 -0
- package/cli/sdk/prompt-adapter.mjs +49 -0
- package/cli/sdk/recall-adapter.mjs +39 -0
- package/cli/sdk/route-adapter.mjs +45 -0
- package/cli/sdk/search-adapter.mjs +55 -0
- package/cli/sdk/validate.mjs +48 -0
- package/cli/sdk/version-adapter.mjs +17 -0
- package/docs/AGENT-SDK.md +98 -0
- package/docs/ROADMAP.md +39 -0
- package/docs/SDK.md +162 -0
- package/docs/external-status.md +6 -6
- package/package.json +6 -2
- package/tools/audit/package-smoke.py +62 -0
- package/tools/audit/registry-smoke.py +2 -2
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "design-ai",
|
|
3
|
-
"version": "4.
|
|
3
|
+
"version": "4.59.0",
|
|
4
4
|
"description": "Senior product designer for any AI coding agent. 20 skills, 17 commands, 4 review agents covering UI/UX, website improvement, design systems, motion, illustration, print, video, game UI, conversational, and spatial design. Korean market depth.",
|
|
5
5
|
"author": {
|
|
6
6
|
"name": "Sungjin Park",
|
package/CHANGELOG.md
CHANGED
|
@@ -2,6 +2,33 @@
|
|
|
2
2
|
|
|
3
3
|
User-facing release notes for design-ai. Versions follow semver.
|
|
4
4
|
|
|
5
|
+
## v4.59.0 — Agent SDK Phase A (2026-07)
|
|
6
|
+
|
|
7
|
+
Adds a curated, semver-stable programmatic surface — `@design-ai/cli/sdk` — so an external Node.js program can call design-ai's deterministic design verbs as importable functions, without shelling out to the CLI or spawning the MCP server. The SDK is a thin adapter over the same `cli/lib` functions the CLI and MCP already call, so no design behavior changes. Phase A is read-only: no file writes, no network, no runtime dependencies. All additions are additive and backward-compatible.
|
|
8
|
+
|
|
9
|
+
### Added
|
|
10
|
+
- `@design-ai/cli/sdk` — eight read-only adapter verbs with their own stable signatures: `route(brief, opts)`, `prompt(brief, opts)`, `pack(brief, opts)`, `search(query, opts)`, `recall(query, opts)`, `check(artifact, opts)`, `routes()`, and `version()`. Each validates its inputs, resolves the package root the same way the CLI does, and returns the same JSON-serializable shape the CLI's `--json` mode emits. `check` operates on artifact content (not a path), so it reads and writes nothing.
|
|
11
|
+
- `package.json` `exports` map exposing `./sdk` (and `./package.json`) as the only public import paths; `cli/lib/*` stays internal and unstable, refactorable behind the adapter seam.
|
|
12
|
+
- `docs/SDK.md` — the public SDK reference (surface, return shapes, semver stability contract) — plus a "Node.js / Agent SDK" row in the README install tables and an Agent SDK mkdocs nav section.
|
|
13
|
+
|
|
14
|
+
### Changed
|
|
15
|
+
- `npm test` now also runs `cli/sdk/*.test.mjs` (61 new SDK tests, 540 total), including a contract test (`cli/sdk/index.test.mjs`) that pins the eight exported names and their return-shape keys — the semver anchor — and asserts Phase A writes no `learningUsage` sidecar.
|
|
16
|
+
- `tools/audit/package-smoke.py` now imports `@design-ai/cli/sdk` from the installed tarball and exercises the eight verbs, asserting determinism and the read-only guarantee.
|
|
17
|
+
|
|
18
|
+
### Verified
|
|
19
|
+
- All 8 audits passed.
|
|
20
|
+
- `npm run release:check`.
|
|
21
|
+
- `npm run release:metadata`.
|
|
22
|
+
- `git diff --check`.
|
|
23
|
+
- Main-branch GitHub Actions (`Design-AI audit`, `Deploy doc site`) passed for the constituent commits.
|
|
24
|
+
|
|
25
|
+
### Versions
|
|
26
|
+
- `package.json` + `.claude-plugin/plugin.json`: 4.58.0 → 4.59.0.
|
|
27
|
+
- `vscode-extension/package.json`: remains 0.4.1.
|
|
28
|
+
|
|
29
|
+
### What this enables
|
|
30
|
+
- Agent runtimes, build scripts, and custom tools can consume design-ai's routing, prompt/pack generation, ranked search, recall, and artifact checks as plain functions — deterministic, in-process, zero-dependency — with a semver-stable contract independent of the internal `cli/lib` shapes.
|
|
31
|
+
|
|
5
32
|
## v4.58.0 — Retrieval Across Surfaces and Corpus Depth (2026-07)
|
|
6
33
|
|
|
7
34
|
Completes the retrieval integration started in v4.57.0 by bringing it to the last untouched surface (`route --explain`), refines recall quality so injected knowledge is real design guidance rather than index files, and closes the remaining dogfood-named corpus gaps. All additions are additive and backward-compatible; default output is unchanged unless a flag is passed.
|
package/README.ko.md
CHANGED
|
@@ -12,7 +12,7 @@
|
|
|
12
12
|
|
|
13
13
|
> **모델이 아니에요. 파인튜닝도 아니에요.** 디자인 전문 지식을 구조화한 코퍼스 + 에이전트가 바로 실행할 수 있는 지시문이에요. 범용 LLM을 이번 세션에서만큼은 시니어 디자이너로 바꿔주는 셈이에요.
|
|
14
14
|
|
|
15
|
-
> **배포 상태, 2026-07-
|
|
15
|
+
> **배포 상태, 2026-07-04 확인:** 로컬 `npm run release:check`는 통과했고, GitHub Pages 문서는 live 상태이며, GitHub Release `v4.58.0`과 npm `@design-ai/cli@4.58.0`(`latest`) publish가 provenance와 함께 확인됐어요. 수정 후 live `npm run registry:smoke`가 published `@design-ai/cli@4.58.0`에 대해 깨끗이 통과했어요(retrieval 표면과 route enrichment 포함). Homebrew formula는 `v4.58.0`에 pinning되어 있고, VS Code Marketplace에는 `sungjin.design-ai-vscode@0.4.1`이 공개되어 있어요. 자세한 내용은 [`docs/external-status.md`](docs/external-status.md)를 확인하세요.
|
|
16
16
|
|
|
17
17
|
## 한눈에 보는 커버리지
|
|
18
18
|
|
|
@@ -88,6 +88,7 @@ CLI 명령어: `design-ai install [--json]`, `update [--dry-run] [--json]`, `uni
|
|
|
88
88
|
| **Cursor** | 이 폴더를 열고 `AGENTS.md`를 `.cursorrules`로 심볼릭 링크하거나 복사해요. [워크스루](docs/integrations/cursor-walkthrough.md). |
|
|
89
89
|
| **Aider** | `AGENTS.md`를 시스템 프롬프트로 전달해요. [워크스루](docs/integrations/aider-walkthrough.md). |
|
|
90
90
|
| **Anthropic / OpenAI SDK** | 관련 스킬 `PLAYBOOK.md` 파일을 프롬프트에 포함시켜요. [워크스루](docs/integrations/sdk-walkthrough.md). |
|
|
91
|
+
| **Node.js / Agent SDK** | `import { route, prompt, pack, search, recall, check, routes, version } from "@design-ai/cli/sdk"` — CLI 셸 실행이나 MCP 서버 없이 design-ai의 결정적 기능을 함수로 바로 호출해요. 읽기 전용(Phase A). [SDK 레퍼런스](docs/SDK.md). |
|
|
91
92
|
| **일반 프롬프트** | 어떤 `skills/*/PLAYBOOK.md` 본문이든 붙여넣으세요 — 각각 자기 완결적이에요. |
|
|
92
93
|
|
|
93
94
|
에이전트별 설치 방법은 [`docs/USING.md`](docs/USING.md)를, 구체적인 사용 예시는 위 워크스루 링크를 참고하세요.
|
|
@@ -171,7 +172,7 @@ design-ai는 한국 시장을 1순위로 만들어졌고, 글로벌 시장 패
|
|
|
171
172
|
|
|
172
173
|
## 상태
|
|
173
174
|
|
|
174
|
-
전체 단계 로그는 [`docs/ROADMAP.md`](docs/ROADMAP.md), 현재 완료 범위는 [`docs/PRODUCT-READINESS.md`](docs/PRODUCT-READINESS.md)에서 확인하세요. 현재 **v4.
|
|
175
|
+
전체 단계 로그는 [`docs/ROADMAP.md`](docs/ROADMAP.md), 현재 완료 범위는 [`docs/PRODUCT-READINESS.md`](docs/PRODUCT-READINESS.md)에서 확인하세요. 현재 **v4.58.0**: public npm publish, provenance-backed GitHub Actions release, public registry smoke, Website Console MCP readiness, workspace learning restore/eval coverage, handoff bundle verification, 90%+ component coverage가 완료됐어요.
|
|
175
176
|
|
|
176
177
|
핵심 디자인 컨설팅 워크플로우는 로컬 릴리스 기준으로 준비되어 있어요. 웹사이트 개선 컨트롤 타워는 zero-dependency static Web App과 `website-improvement` route/skill/command로 제공되고, Site Profile, audit checklist, MCP readiness, refactor prompt, handoff evidence tracking, bundle export/verify/repair를 한 번에 다뤄요. 로컬 학습 선호도는 `design-ai learn`으로 관리해요 — profile bootstrap, feedback 캡처, 읽기 전용 signal registry, 반복 QA 신호에서 만드는 skill 제안, 그리고 backup/restore/curate/audit까지 전부 로컬에서만 동작하는 opt-in 기능이에요. AI 모델 학습이나 fine-tuning은 여전히 현재 배포 범위 밖이에요.
|
|
177
178
|
|
package/README.md
CHANGED
|
@@ -12,7 +12,7 @@ A model-agnostic design knowledge base + skill system. Drop it in front of any A
|
|
|
12
12
|
|
|
13
13
|
> **Not a model. Not a fine-tune.** A structured corpus of design expertise + agent-ready instructions that turn a general-purpose LLM into an expert.
|
|
14
14
|
|
|
15
|
-
> **Distribution status, checked 2026-07-
|
|
15
|
+
> **Distribution status, checked 2026-07-04:** local `npm run release:check` passes, GitHub Pages docs are live, GitHub Release `v4.58.0` is published, `@design-ai/cli@4.58.0` is public on npm (`latest`) with provenance, and the live `npm run registry:smoke` passes cleanly against `@design-ai/cli@4.58.0`. The Homebrew formula is pinned to `v4.58.0`, and `sungjin.design-ai-vscode@0.4.1` is public on the VS Code Marketplace. See [`docs/external-status.md`](docs/external-status.md).
|
|
16
16
|
|
|
17
17
|
## Coverage at a glance
|
|
18
18
|
|
|
@@ -89,6 +89,7 @@ See [`docs/DISTRIBUTION.md`](docs/DISTRIBUTION.md) for the full distribution gui
|
|
|
89
89
|
| **Aider** | Pass `AGENTS.md` as system prompt. [Walkthrough](docs/integrations/aider-walkthrough.md). |
|
|
90
90
|
| **Anthropic / OpenAI SDK** | Embed relevant skill `PLAYBOOK.md` files in your prompt. [Walkthrough](docs/integrations/sdk-walkthrough.md). |
|
|
91
91
|
| **VS Code** | Install the public Marketplace extension for sidebar trees + quick-pick commands. [Walkthrough](docs/integrations/vscode-walkthrough.md). |
|
|
92
|
+
| **Node.js / Agent SDK** | `import { route, prompt, pack, search, recall, check, routes, version } from "@design-ai/cli/sdk"` — call design-ai's deterministic verbs as functions, no CLI shell-out or MCP server needed. Read-only (Phase A). [SDK reference](docs/SDK.md). |
|
|
92
93
|
| **Plain prompt** | Paste any `skills/*/PLAYBOOK.md` body — each is self-contained. |
|
|
93
94
|
|
|
94
95
|
See [`docs/USING.md`](docs/USING.md) for per-agent setup details, or the linked walkthroughs for concrete example sessions.
|
|
@@ -213,7 +214,7 @@ Refresh refs/ on demand: `./tools/extractors/run-all.sh`.
|
|
|
213
214
|
|
|
214
215
|
## Status
|
|
215
216
|
|
|
216
|
-
See [`docs/ROADMAP.md`](docs/ROADMAP.md) for the full phase log and [`docs/PRODUCT-READINESS.md`](docs/PRODUCT-READINESS.md) for the current completion boundary. Currently at **v4.
|
|
217
|
+
See [`docs/ROADMAP.md`](docs/ROADMAP.md) for the full phase log and [`docs/PRODUCT-READINESS.md`](docs/PRODUCT-READINESS.md) for the current completion boundary. Currently at **v4.58.0**: public npm publish, provenance-backed GitHub Actions release, public registry smoke, Website Console MCP readiness, workspace learning restore/eval coverage, handoff bundle verification, and 90%+ component coverage are complete.
|
|
217
218
|
|
|
218
219
|
Core design consulting workflows are locally release-ready. The website improvement control tower ships as a zero-dependency static Web App plus a `website-improvement` route/skill/command, covering Site Profiles, audit checklists, MCP readiness, refactor prompts, handoff evidence tracking, and bundle export/verify/repair. Local learning preferences are available through `design-ai learn` — profile bootstrap, feedback capture, a read-only signals registry, skill-proposal generation from repeated QA signals, and full backup/restore/curate/audit tooling, all local-only and opt-in. AI model training or fine-tuning remains outside the shipped scope.
|
|
219
220
|
|
|
@@ -0,0 +1,36 @@
|
|
|
1
|
+
// SDK adapter: check(artifact, opts). See docs/AGENT-SDK.md.
|
|
2
|
+
//
|
|
3
|
+
// Read-only: capture is never enabled from the SDK in Phase A (the CLI's
|
|
4
|
+
// `--learn` writes a local learning-profile capture; there is no equivalent
|
|
5
|
+
// opt-in here, consistent with "no file writes" for Phase A).
|
|
6
|
+
|
|
7
|
+
import { checkArtifactContent } from "../lib/check.mjs";
|
|
8
|
+
import { assertKnownRouteId } from "../lib/route.mjs";
|
|
9
|
+
import { optionalBoolean, optionalString, requireNonEmptyString, requireOptions } from "./validate.mjs";
|
|
10
|
+
|
|
11
|
+
/**
|
|
12
|
+
* Check a generated design Markdown artifact for grounding, accessibility,
|
|
13
|
+
* responsive, unresolved-marker, and route-specific requirements. Pure,
|
|
14
|
+
* read-only adapter over `checkArtifactContent` from cli/lib/check.mjs.
|
|
15
|
+
*
|
|
16
|
+
* @param {string} artifact - Markdown artifact content to check.
|
|
17
|
+
* @param {{routeId?: string, strict?: boolean}} [opts]
|
|
18
|
+
* @returns {object} CheckReport — the same shape as `design-ai check --json`.
|
|
19
|
+
*/
|
|
20
|
+
export function check(artifact, opts = {}) {
|
|
21
|
+
requireNonEmptyString(artifact, "artifact");
|
|
22
|
+
const options = requireOptions(opts, "check");
|
|
23
|
+
|
|
24
|
+
const routeId = optionalString(options.routeId, "routeId");
|
|
25
|
+
if (routeId) assertKnownRouteId(routeId, { allowEmpty: false });
|
|
26
|
+
// `strict` only affects CLI exit-code behavior; validated for type safety,
|
|
27
|
+
// but the SDK returns the report as-is and lets the caller decide what to
|
|
28
|
+
// do with report.status — there is no process exit code to influence here.
|
|
29
|
+
optionalBoolean(options.strict, "strict", false);
|
|
30
|
+
|
|
31
|
+
return checkArtifactContent({
|
|
32
|
+
content: artifact,
|
|
33
|
+
filePath: "sdk",
|
|
34
|
+
routeId,
|
|
35
|
+
});
|
|
36
|
+
}
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
// design-ai Agent SDK — Phase A (read-only). See docs/AGENT-SDK.md and docs/SDK.md.
|
|
2
|
+
//
|
|
3
|
+
// A curated, semver-stable adapter over the same cli/lib functions the CLI and
|
|
4
|
+
// MCP server call. Each verb validates its inputs, resolves the package root
|
|
5
|
+
// the same way the CLI does, and returns a plain JSON-serializable object —
|
|
6
|
+
// the same shape the CLI's --json mode emits. No network calls, no runtime
|
|
7
|
+
// dependencies. Phase A performs no file writes: no learning-usage sidecar
|
|
8
|
+
// writes, even from prompt/pack's withLearning option.
|
|
9
|
+
//
|
|
10
|
+
// Import path: `@design-ai/cli/sdk` (see the "exports" map in package.json).
|
|
11
|
+
// `cli/lib/*` stays internal and unstable; this barrel is the only supported
|
|
12
|
+
// public surface. Do not import `cli/lib/*.mjs` directly from outside this
|
|
13
|
+
// package — only the 8 named exports below are covered by the semver
|
|
14
|
+
// stability contract described in docs/SDK.md.
|
|
15
|
+
|
|
16
|
+
export { check } from "./check-adapter.mjs";
|
|
17
|
+
export { pack } from "./pack-adapter.mjs";
|
|
18
|
+
export { prompt } from "./prompt-adapter.mjs";
|
|
19
|
+
export { recall } from "./recall-adapter.mjs";
|
|
20
|
+
export { route, routes } from "./route-adapter.mjs";
|
|
21
|
+
export { search } from "./search-adapter.mjs";
|
|
22
|
+
export { version } from "./version-adapter.mjs";
|
|
@@ -0,0 +1,55 @@
|
|
|
1
|
+
// SDK adapter: pack(brief, opts). See docs/AGENT-SDK.md.
|
|
2
|
+
//
|
|
3
|
+
// Phase A is read-only: like the prompt adapter, this never records the
|
|
4
|
+
// learning-usage sidecar, even when withLearning is requested.
|
|
5
|
+
|
|
6
|
+
import { DESIGN_AI_HOME, SYMLINK_PREFIX } from "../lib/paths.mjs";
|
|
7
|
+
import { buildPromptPack } from "../lib/pack.mjs";
|
|
8
|
+
import {
|
|
9
|
+
optionalBoolean,
|
|
10
|
+
optionalInteger,
|
|
11
|
+
optionalString,
|
|
12
|
+
requireNonEmptyString,
|
|
13
|
+
requireOptions,
|
|
14
|
+
} from "./validate.mjs";
|
|
15
|
+
|
|
16
|
+
const DEFAULT_MAX_BYTES = 120_000;
|
|
17
|
+
|
|
18
|
+
/**
|
|
19
|
+
* Build a ready-to-use prompt plus bounded context-file bundle from a task
|
|
20
|
+
* brief. Pure, read-only adapter over `buildPromptPack` from cli/lib/pack.mjs.
|
|
21
|
+
* Never records learning-usage, even with withLearning: true.
|
|
22
|
+
*
|
|
23
|
+
* @param {string} brief - Task brief text.
|
|
24
|
+
* @param {{routeId?: string, maxBytes?: number, withLearning?: boolean, learningCategory?: string, learningLimit?: number, withRecall?: boolean, recallLimit?: number}} [opts]
|
|
25
|
+
* @returns {object} Pack — the same shape as `design-ai pack --json` (minus learningUsage).
|
|
26
|
+
*/
|
|
27
|
+
export function pack(brief, opts = {}) {
|
|
28
|
+
requireNonEmptyString(brief, "brief");
|
|
29
|
+
const options = requireOptions(opts, "pack");
|
|
30
|
+
|
|
31
|
+
const routeId = optionalString(options.routeId, "routeId");
|
|
32
|
+
const maxBytes = optionalInteger(options.maxBytes, "maxBytes", {
|
|
33
|
+
fallback: DEFAULT_MAX_BYTES,
|
|
34
|
+
min: 1000,
|
|
35
|
+
max: 1_000_000,
|
|
36
|
+
});
|
|
37
|
+
const withLearning = optionalBoolean(options.withLearning, "withLearning", false);
|
|
38
|
+
const learningCategory = optionalString(options.learningCategory, "learningCategory");
|
|
39
|
+
const learningLimit = optionalInteger(options.learningLimit, "learningLimit", { fallback: 0, min: 1, max: 100, zeroMeansUnset: true });
|
|
40
|
+
const withRecall = optionalBoolean(options.withRecall, "withRecall", false);
|
|
41
|
+
const recallLimit = optionalInteger(options.recallLimit, "recallLimit", { fallback: 0, min: 1, max: 20, zeroMeansUnset: true });
|
|
42
|
+
|
|
43
|
+
return buildPromptPack({
|
|
44
|
+
brief,
|
|
45
|
+
sourceRoot: DESIGN_AI_HOME,
|
|
46
|
+
prefix: SYMLINK_PREFIX,
|
|
47
|
+
maxBytes,
|
|
48
|
+
routeId,
|
|
49
|
+
withLearning,
|
|
50
|
+
learningCategory,
|
|
51
|
+
learningLimit,
|
|
52
|
+
withRecall,
|
|
53
|
+
recallLimit,
|
|
54
|
+
});
|
|
55
|
+
}
|
|
@@ -0,0 +1,49 @@
|
|
|
1
|
+
// SDK adapter: prompt(brief, opts). See docs/AGENT-SDK.md.
|
|
2
|
+
//
|
|
3
|
+
// Phase A is read-only: unlike the CLI's `--with-learning` (which records a
|
|
4
|
+
// local usage sidecar entry via recordLearningUsage), the SDK adapter never
|
|
5
|
+
// writes the learning-usage sidecar, even when withLearning is requested. It
|
|
6
|
+
// only reads the local learning profile to build the learning context.
|
|
7
|
+
|
|
8
|
+
import { DESIGN_AI_HOME, SYMLINK_PREFIX } from "../lib/paths.mjs";
|
|
9
|
+
import { buildPromptPlan } from "../lib/prompt.mjs";
|
|
10
|
+
import {
|
|
11
|
+
optionalBoolean,
|
|
12
|
+
optionalInteger,
|
|
13
|
+
optionalString,
|
|
14
|
+
requireNonEmptyString,
|
|
15
|
+
requireOptions,
|
|
16
|
+
} from "./validate.mjs";
|
|
17
|
+
|
|
18
|
+
/**
|
|
19
|
+
* Build a ready-to-use agent prompt plan from a task brief. Pure, read-only
|
|
20
|
+
* adapter over `buildPromptPlan` from cli/lib/prompt.mjs. Never records
|
|
21
|
+
* learning-usage, even with withLearning: true (Phase A is read-only).
|
|
22
|
+
*
|
|
23
|
+
* @param {string} brief - Task brief text.
|
|
24
|
+
* @param {{routeId?: string, withLearning?: boolean, learningCategory?: string, learningLimit?: number, withRecall?: boolean, recallLimit?: number}} [opts]
|
|
25
|
+
* @returns {object|null} PromptPlan — the same shape as `design-ai prompt --json` (minus learningUsage).
|
|
26
|
+
*/
|
|
27
|
+
export function prompt(brief, opts = {}) {
|
|
28
|
+
requireNonEmptyString(brief, "brief");
|
|
29
|
+
const options = requireOptions(opts, "prompt");
|
|
30
|
+
|
|
31
|
+
const routeId = optionalString(options.routeId, "routeId");
|
|
32
|
+
const withLearning = optionalBoolean(options.withLearning, "withLearning", false);
|
|
33
|
+
const learningCategory = optionalString(options.learningCategory, "learningCategory");
|
|
34
|
+
const learningLimit = optionalInteger(options.learningLimit, "learningLimit", { fallback: 0, min: 1, max: 100, zeroMeansUnset: true });
|
|
35
|
+
const withRecall = optionalBoolean(options.withRecall, "withRecall", false);
|
|
36
|
+
const recallLimit = optionalInteger(options.recallLimit, "recallLimit", { fallback: 0, min: 1, max: 20, zeroMeansUnset: true });
|
|
37
|
+
|
|
38
|
+
return buildPromptPlan({
|
|
39
|
+
brief,
|
|
40
|
+
sourceRoot: DESIGN_AI_HOME,
|
|
41
|
+
prefix: SYMLINK_PREFIX,
|
|
42
|
+
routeId,
|
|
43
|
+
withLearning,
|
|
44
|
+
learningCategory,
|
|
45
|
+
learningLimit,
|
|
46
|
+
withRecall,
|
|
47
|
+
recallLimit,
|
|
48
|
+
});
|
|
49
|
+
}
|
|
@@ -0,0 +1,39 @@
|
|
|
1
|
+
// SDK adapter: recall(query, opts). See docs/AGENT-SDK.md.
|
|
2
|
+
//
|
|
3
|
+
// Combined recall view: brief-relevant shipped corpus knowledge (`corpus`) plus
|
|
4
|
+
// brief-relevant local learning-profile entries (`learning`), both ranked by the
|
|
5
|
+
// same shipped deterministic lexical scorer used by `search --ranked`. Read-only:
|
|
6
|
+
// reads the local corpus and `DESIGN_AI_LEARNING_FILE` learning profile, exactly
|
|
7
|
+
// as `design-ai learn --recall` does, and never writes either.
|
|
8
|
+
|
|
9
|
+
import { DESIGN_AI_HOME } from "../lib/paths.mjs";
|
|
10
|
+
import { buildLearnRecall, DEFAULT_RECALL_LIMIT } from "../lib/recall.mjs";
|
|
11
|
+
import { optionalInteger, optionalString, requireNonEmptyString, requireOptions } from "./validate.mjs";
|
|
12
|
+
|
|
13
|
+
/**
|
|
14
|
+
* Recall brief-relevant corpus knowledge and local learning-profile entries for
|
|
15
|
+
* a query. Pure, read-only adapter over `buildLearnRecall` from cli/lib/recall.mjs.
|
|
16
|
+
*
|
|
17
|
+
* @param {string} query - Recall query text.
|
|
18
|
+
* @param {{limit?: number, category?: string}} [opts]
|
|
19
|
+
* @returns {{corpus: object, learning: object}} combined recall view.
|
|
20
|
+
*/
|
|
21
|
+
export function recall(query, opts = {}) {
|
|
22
|
+
requireNonEmptyString(query, "query");
|
|
23
|
+
const options = requireOptions(opts, "recall");
|
|
24
|
+
|
|
25
|
+
const limit = optionalInteger(options.limit, "limit", { fallback: DEFAULT_RECALL_LIMIT, min: 1, max: 20 });
|
|
26
|
+
const category = optionalString(options.category, "category");
|
|
27
|
+
|
|
28
|
+
const result = buildLearnRecall({
|
|
29
|
+
query,
|
|
30
|
+
limit,
|
|
31
|
+
category,
|
|
32
|
+
designAiPath: DESIGN_AI_HOME,
|
|
33
|
+
});
|
|
34
|
+
|
|
35
|
+
return {
|
|
36
|
+
corpus: result.corpus,
|
|
37
|
+
learning: result.learning,
|
|
38
|
+
};
|
|
39
|
+
}
|
|
@@ -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,44 @@
|
|
|
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
|
+
|
|
3
42
|
## Phase 756 — Retrieval Across Surfaces and Corpus Depth Release (v4.58.0) ✓ ready
|
|
4
43
|
|
|
5
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.
|
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.
|
package/docs/external-status.md
CHANGED
|
@@ -1,22 +1,22 @@
|
|
|
1
1
|
# External Publication Status
|
|
2
2
|
|
|
3
|
-
> Checked: 2026-07-
|
|
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
|
-
npm is publicly published at `@design-ai/cli@4.
|
|
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.
|
|
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.
|
|
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.
|
|
19
|
-
| MCP server | `@design-ai/cli@4.
|
|
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
|
|
package/package.json
CHANGED
|
@@ -1,17 +1,21 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@design-ai/cli",
|
|
3
|
-
"version": "4.
|
|
3
|
+
"version": "4.59.0",
|
|
4
4
|
"description": "Senior product designer for any AI coding agent. Installs design-ai (20 skills, 17 commands, 4 agents) into Claude Code globally. Korean market depth plus website improvement control tower.",
|
|
5
5
|
"bin": {
|
|
6
6
|
"design-ai": "cli/bin/design-ai.mjs",
|
|
7
7
|
"design-ai-mcp": "cli/bin/design-ai-mcp.mjs"
|
|
8
8
|
},
|
|
9
9
|
"type": "module",
|
|
10
|
+
"exports": {
|
|
11
|
+
"./sdk": "./cli/sdk/index.mjs",
|
|
12
|
+
"./package.json": "./package.json"
|
|
13
|
+
},
|
|
10
14
|
"engines": {
|
|
11
15
|
"node": ">=18"
|
|
12
16
|
},
|
|
13
17
|
"scripts": {
|
|
14
|
-
"test": "node --test cli/lib/*.test.mjs",
|
|
18
|
+
"test": "node --test cli/lib/*.test.mjs cli/sdk/*.test.mjs",
|
|
15
19
|
"audit": "python3 -B tools/audit/run-all.py",
|
|
16
20
|
"audit:strict": "python3 -B tools/audit/run-all.py --strict",
|
|
17
21
|
"audit:runner:self-test": "python3 -B tools/audit/run-all.py --self-test",
|
|
@@ -763,6 +763,63 @@ def assert_version_json_smoke(cmd: list[str], *, env: dict[str, str], cwd: Path
|
|
|
763
763
|
assert_version_json(result.stdout, context=context, cmd=cmd)
|
|
764
764
|
|
|
765
765
|
|
|
766
|
+
# Phase A Agent SDK packed-tarball smoke (docs/AGENT-SDK.md, docs/SDK.md): imports
|
|
767
|
+
# `@design-ai/cli/sdk` from the installed package (proving the package.json
|
|
768
|
+
# "exports" map resolves) and exercises route/search(ranked)/recall, asserting
|
|
769
|
+
# each call is deterministic (same input -> same JSON-serialized output) and
|
|
770
|
+
# that Phase A's read-only contract holds (prompt/pack never include
|
|
771
|
+
# learningUsage). This is a Node script, not a design-ai CLI invocation, so it
|
|
772
|
+
# is run directly rather than through npm_exec_cmd/design-ai bin helpers.
|
|
773
|
+
SDK_SMOKE_SCRIPT = """
|
|
774
|
+
import { check, pack, prompt, recall, route, routes, search, version } from "@design-ai/cli/sdk";
|
|
775
|
+
|
|
776
|
+
const brief = "Spec a Button component API with variants, props, and keyboard accessibility";
|
|
777
|
+
|
|
778
|
+
const r1 = route(brief, { limit: 1 });
|
|
779
|
+
const r2 = route(brief, { limit: 1 });
|
|
780
|
+
if (JSON.stringify(r1) !== JSON.stringify(r2)) throw new Error("route() not deterministic");
|
|
781
|
+
if (r1[0].id !== "component-spec") throw new Error(`unexpected route id: ${r1[0].id}`);
|
|
782
|
+
|
|
783
|
+
const s1 = search("accessibility", { ranked: true, limit: 3 });
|
|
784
|
+
const s2 = search("accessibility", { ranked: true, limit: 3 });
|
|
785
|
+
if (JSON.stringify(s1) !== JSON.stringify(s2)) throw new Error("search() not deterministic");
|
|
786
|
+
if (s1.length === 0) throw new Error("search() returned no hits");
|
|
787
|
+
|
|
788
|
+
const rec1 = recall("keyboard accessibility button", { limit: 2 });
|
|
789
|
+
const rec2 = recall("keyboard accessibility button", { limit: 2 });
|
|
790
|
+
if (JSON.stringify(rec1) !== JSON.stringify(rec2)) throw new Error("recall() not deterministic");
|
|
791
|
+
if (!rec1.corpus || !rec1.learning) throw new Error("recall() missing corpus/learning");
|
|
792
|
+
|
|
793
|
+
const v = version();
|
|
794
|
+
if (typeof v.cli !== "string" || typeof v.corpus !== "string") throw new Error("version() bad shape");
|
|
795
|
+
|
|
796
|
+
const rc = routes();
|
|
797
|
+
if (!Array.isArray(rc.routes) || rc.routes.length === 0) throw new Error("routes() bad shape");
|
|
798
|
+
|
|
799
|
+
const p = prompt(brief, { routeId: "component-spec" });
|
|
800
|
+
if (Object.hasOwn(p, "learningUsage")) throw new Error("prompt() must not include learningUsage in Phase A");
|
|
801
|
+
|
|
802
|
+
const pk = pack(brief, { routeId: "component-spec", maxBytes: 20000 });
|
|
803
|
+
if (Object.hasOwn(pk, "learningUsage")) throw new Error("pack() must not include learningUsage in Phase A");
|
|
804
|
+
|
|
805
|
+
const ck = check(
|
|
806
|
+
"# T\\n\\nAnatomy variants API contrast 4.5:1 keyboard focus screen reader aria- responsive mobile desktop.",
|
|
807
|
+
{ routeId: "component-spec" },
|
|
808
|
+
);
|
|
809
|
+
if (typeof ck.status !== "string") throw new Error("check() bad shape");
|
|
810
|
+
|
|
811
|
+
console.log("design-ai sdk smoke passed");
|
|
812
|
+
""".strip()
|
|
813
|
+
|
|
814
|
+
|
|
815
|
+
def assert_sdk_smoke(*, cwd: Path, env: dict[str, str], context: str) -> None:
|
|
816
|
+
result = run_plain(["node", "--input-type=module", "-e", SDK_SMOKE_SCRIPT], cwd=cwd, env=env)
|
|
817
|
+
if result.returncode != 0:
|
|
818
|
+
raise SystemExit(f"{context} failed (exit {result.returncode})")
|
|
819
|
+
if "design-ai sdk smoke passed" not in result.stdout:
|
|
820
|
+
raise SystemExit(f"{context}: expected success marker missing from output")
|
|
821
|
+
|
|
822
|
+
|
|
766
823
|
def assert_workspace_json_smoke(cmd: list[str], *, env: dict[str, str], cwd: Path | None = None, context: str) -> None:
|
|
767
824
|
result = run_plain(cmd, cwd=cwd, env=env)
|
|
768
825
|
assert_workspace_json(result.stdout, context=context, cmd=cmd)
|
|
@@ -20239,6 +20296,11 @@ def smoke_tarball(tarball: Path) -> None:
|
|
|
20239
20296
|
env=smoke_env,
|
|
20240
20297
|
context="package smoke installed bin version JSON",
|
|
20241
20298
|
)
|
|
20299
|
+
assert_sdk_smoke(
|
|
20300
|
+
cwd=install_root,
|
|
20301
|
+
env=smoke_env,
|
|
20302
|
+
context="package smoke installed Agent SDK (@design-ai/cli/sdk)",
|
|
20303
|
+
)
|
|
20242
20304
|
assert_design_ai_mcp_protocol_smoke(
|
|
20243
20305
|
[str(mcp_bin_path)],
|
|
20244
20306
|
cwd=install_root,
|
|
@@ -4637,7 +4637,7 @@ def assert_learning_relevance_context(payload: dict[str, object], *, context: st
|
|
|
4637
4637
|
message="learning selection explanation should mark the relevant entry as a brief match",
|
|
4638
4638
|
)
|
|
4639
4639
|
require_registry_smoke(
|
|
4640
|
-
|
|
4640
|
+
type(selected_entry.get("score")) in (int, float) and selected_entry.get("score") > 0,
|
|
4641
4641
|
context=context,
|
|
4642
4642
|
cmd=cmd,
|
|
4643
4643
|
message="learning selection explanation should include a positive relevance score",
|
|
@@ -4759,7 +4759,7 @@ def assert_learning_query_json(
|
|
|
4759
4759
|
require_registry_smoke(
|
|
4760
4760
|
selected[0].get("id") == "learn-relevant"
|
|
4761
4761
|
and selected[0].get("reason") == "brief-match"
|
|
4762
|
-
and
|
|
4762
|
+
and type(selected[0].get("score")) in (int, float)
|
|
4763
4763
|
and selected[0].get("score") > 0,
|
|
4764
4764
|
context=context,
|
|
4765
4765
|
cmd=cmd,
|