🚀 Socket Launch Week Day 5:Introducing Repository Access Permissions and Custom Roles.Learn more
Sign In

@design-ai/cli

Package Overview
Dependencies
Maintainers
1
Versions
11
Alerts
File Explorer

Advanced tools

Socket logo

Install Socket

Detect and block malicious and high-risk dependencies

Install

@design-ai/cli - npm Package Compare versions

Comparing version
4.59.0
to
4.60.0
+435
cli/sdk/index.d.ts
// Type declarations for the design-ai Agent SDK — Phase A (read-only).
// Hand-written, zero-build: no TypeScript toolchain is required to produce or
// ship these. They mirror the runtime shapes exercised by cli/sdk/index.test.mjs
// (the semver anchor). The eight exported names and their return-shape top-level
// keys are the stable, semver-covered surface; deeper nested shapes follow the
// same JSON the CLI's `--json` mode emits.
//
// Import: `import { route, search } from "@design-ai/cli/sdk";`
// ── Shared building blocks ────────────────────────────────────────────────
/** A curated reference (skill/agent/knowledge/command) and whether it exists on disk. */
export interface RouteReference {
path: string;
exists: boolean;
}
/** One reference-coverage tally (available vs total) within a route explanation. */
export interface CoverageCount {
available: number;
total: number;
}
export interface ReferenceCoverage {
command: CoverageCount;
skills: CoverageCount;
agents: CoverageCount;
knowledge: CoverageCount;
total: CoverageCount;
}
export interface ScoreBreakdownEntry {
label: string;
value: number;
}
export interface RouteExplanation {
summary: string;
scoreBreakdown: ScoreBreakdownEntry[];
referenceCoverage: ReferenceCoverage;
missingReferences: string[];
}
/** Advisory brief-relevant knowledge recalled by the shared lexical scorer. */
export interface RelatedKnowledge {
id: string;
score: number;
matchedTokens: string[];
}
export type RouteConfidence = "high" | "medium" | "low" | "catalog" | "forced";
export interface RouteResult {
id: string;
label: string;
score: number;
confidence: RouteConfidence;
matchedKeywords: string[];
command: RouteReference | null;
skills: RouteReference[];
agents: RouteReference[];
knowledge: RouteReference[];
keywords: string[];
explanation: RouteExplanation;
/** Present only when `route(brief, { explain: true })` is requested. */
relatedKnowledge?: RelatedKnowledge[];
/** Present only when a route was forced via `routeId`. */
forced?: boolean;
/** Present only when the fallback route was used. */
fallback?: boolean;
}
export interface RouteCatalog {
version: string;
routes: RouteResult[];
}
// ── prompt / pack ─────────────────────────────────────────────────────────
export interface ReferenceExample {
relPath: string;
title: string;
category: string;
score: number;
preview: string;
}
/** A single recalled learning-profile entry. */
export interface LearningRecallEntry {
id: string;
category: string;
score: number;
matchedTokens: string[];
text: string;
}
/** A single recalled shipped-corpus knowledge entry. */
export interface CorpusRecallEntry {
id: string;
score: number;
matchedTokens: string[];
}
/** Recall block embedded in a prompt plan when `withRecall: true`. */
export interface PromptRecall {
query: string;
mode: string;
candidateCount: number;
selectedCount: number;
selected: CorpusRecallEntry[];
markdown: string;
}
/** A stored learning-profile entry, as surfaced in a prompt plan's learning context. */
export interface LearningEntry {
id: string;
category: string;
text: string;
source: string;
createdAt: string;
}
export interface LearningSelection {
mode: string;
query: string;
candidateCount: number;
matchedCount: number;
queryTokenCount: number;
fallbackEnabled: boolean;
selectedCount: number;
fallbackCount: number;
selected: LearningRecallEntry[];
}
export interface LearningAuditSummary {
status: string;
failures: number;
warnings: number;
}
/** Learning context embedded in a prompt plan when `withLearning: true`. */
export interface LearningContext {
file: string;
category: string;
limit: number;
query: string;
selection: LearningSelection;
entries: LearningEntry[];
empty: boolean;
auditSummary: LearningAuditSummary;
markdown: string;
}
export interface PromptPlan {
brief: string;
version: string;
route: RouteResult;
slashCommand: string;
referenceExamples: ReferenceExample[];
filesToRead: string[];
checklist: string[];
qualityCommand: string;
prompt: string;
/** Present only when `prompt(brief, { withLearning: true })` is requested. */
learningContext?: LearningContext;
/** Present only when `prompt(brief, { withRecall: true })` is requested. */
recall?: PromptRecall;
}
export interface PackSummary {
totalFiles: number;
includedFiles: number;
truncatedFiles: number;
missingFiles: number;
usedBytes: number;
maxBytes: number;
remainingBytes: number;
usedRatio: number;
status: string;
}
export interface PackFile {
path: string;
bytes: number;
includedBytes: number;
included: boolean;
truncated: boolean;
content: string;
}
export interface Pack {
brief: string;
version: string;
maxBytes: number;
usedBytes: number;
summary: PackSummary;
warnings: string[];
plan: PromptPlan;
files: PackFile[];
markdown: string;
}
// ── search ────────────────────────────────────────────────────────────────
/** A plain line hit (default `search`). */
export interface SearchHit {
file: string;
lineNumber: number;
relPath: string;
preview: string;
}
/** A ranked hit (`search(query, { ranked: true })`) with a BM25 score. */
export interface RankedSearchHit {
relPath: string;
file: string;
score: number;
matchedTokens: string[];
preview: string;
}
// ── recall ────────────────────────────────────────────────────────────────
export interface RecallCorpus {
candidateCount: number;
selectedCount: number;
selected: CorpusRecallEntry[];
}
export interface RecallLearning {
mode: string;
candidateCount: number;
selectedCount: number;
selected: LearningRecallEntry[];
}
export interface RecallResult {
corpus: RecallCorpus;
learning: RecallLearning;
}
// ── check ─────────────────────────────────────────────────────────────────
export type CheckLevel = "pass" | "warn" | "fail";
export interface CheckResult {
id: string;
title: string;
level: CheckLevel;
passed: boolean;
message: string;
/** Present only when the check has supporting evidence. */
evidence?: string;
}
export interface CheckReport {
filePath: string;
/** Present only when a `routeId` was supplied. */
routeId?: string;
status: CheckLevel;
passes: number;
warnings: number;
failures: number;
total: number;
/** Human-readable ratio, e.g. "6/8". */
score: string;
results: CheckResult[];
}
export interface VersionReport {
cli: string;
corpus: string;
}
// ── Option objects ────────────────────────────────────────────────────────
export interface RouteOptions {
/** Max routes to return. Default 3, range 1–10. */
limit?: number;
/** Include the advisory explanation + related-knowledge section. Default false. */
explain?: boolean;
}
export interface PromptOptions {
/** Force a specific route id instead of scoring the brief. */
routeId?: string;
/** Include local learning-profile guidance (read-only; never recorded). Default false. */
withLearning?: boolean;
/** Restrict learning guidance to a category. */
learningCategory?: string;
/** Max learning entries. Range 1–100. */
learningLimit?: number;
/** Include a brief-relevant corpus recall block. Default false. */
withRecall?: boolean;
/** Max recall entries. Range 1–20. */
recallLimit?: number;
}
export interface PackOptions extends PromptOptions {
/** Byte budget for the bundled context files. Default 120000, range 1000–1000000. */
maxBytes?: number;
}
export interface SearchOptions {
/** Restrict to one corpus directory (must be a known search dir). */
dir?: string;
/** Max hits. Default 20, range 1–500. */
limit?: number;
/** Return ranked BM25 hits (score + matchedTokens) instead of plain line hits. */
ranked?: boolean;
}
export interface RecallOptions {
/** Max entries per side (corpus/learning). Range 1–20. */
limit?: number;
/** Restrict learning recall to a category. */
category?: string;
}
export interface CheckOptions {
/** Apply route-specific requirements for this route id. */
routeId?: string;
/** Validated for parity with the CLI; has no effect in-process (no exit code). */
strict?: boolean;
}
// ── The eight Phase A verbs ─────────────────────────────────────────────────
/** Recommend the best route(s), commands, skills, and knowledge for a brief. */
export function route(brief: string, opts?: RouteOptions): RouteResult[];
/** List the full route catalog independent of any brief. */
export function routes(): RouteCatalog;
/** Build a ready-to-use agent prompt plan from a brief. */
export function prompt(brief: string, opts?: PromptOptions): PromptPlan;
/** Build a prompt plan plus a bounded context-file bundle from a brief. */
export function pack(brief: string, opts?: PackOptions): Pack;
/** Search the local corpus. Returns ranked hits when `ranked: true`, else plain line hits. */
export function search(query: string, opts: SearchOptions & { ranked: true }): RankedSearchHit[];
export function search(query: string, opts?: SearchOptions): SearchHit[];
/** Recall brief-relevant corpus knowledge and local learning-profile entries. */
export function recall(query: string, opts?: RecallOptions): RecallResult;
/** Check a Markdown artifact's content for grounding, accessibility, and route requirements. */
export function check(artifact: string, opts?: CheckOptions): CheckReport;
/** Report the CLI package version and the plugin/corpus version. */
export function version(): VersionReport;
// ── learn.* (Phase B — local writes) ─────────────────────────────────────
//
// The ONLY writing verbs in the SDK. Each writes exclusively to the local
// learning profile (`DESIGN_AI_LEARNING_FILE` / defaultLearningFile()), never
// the network. There is no `filePath` or `now`/timestamp option on any of
// these — target a specific profile via the `DESIGN_AI_LEARNING_FILE` env
// var, exactly like the CLI. See docs/SDK.md "Phase B — local writes".
export interface LearnRememberOptions {
/** Learning-profile category. Default "preference". */
category?: string;
}
export interface LearnFeedbackOptions {
/** Feedback outcome; normalized by the underlying lib (e.g. "keep" | "avoid" | "improve"). Default "improve". */
outcome?: string;
/** Learning-profile category. Default "workflow". */
category?: string;
}
export interface LearnCaptureOptions {
/** Add route-specific check requirements for this route id before capturing. */
routeId?: string;
}
/** A single stored learning-profile entry, as written by learn.remember/feedback/captureFromCheck. */
export interface LearningProfileEntry {
id: string;
category: string;
text: string;
source: string;
createdAt: string;
}
export interface LearningProfile {
version: number;
updatedAt: string;
entries: LearningProfileEntry[];
}
/** Return shape of learn.remember() and learn.feedback(). */
export interface RememberResult {
file: string;
entry: LearningProfileEntry;
profile: LearningProfile;
}
/** An entry skipped by learn.captureFromCheck() because it duplicates an existing profile entry. */
export interface CaptureSkippedEntry {
category: string;
text: string;
source: string;
reason: string;
}
/** Return shape of learn.captureFromCheck() — the `captureLearningEntries` result. */
export interface CaptureResult {
file: string;
dryRun: boolean;
applied: boolean;
source: string;
candidateCount: number;
addedCount: number;
skippedCount: number;
count: number;
entries: LearningProfileEntry[];
skipped: CaptureSkippedEntry[];
}
/**
* Phase B: the explicit, opt-in LOCAL-WRITE namespace. `learn.remember`,
* `learn.feedback`, and `learn.captureFromCheck` are the only SDK verbs that
* write files — each writes only the local learning profile.
*/
export declare const learn: {
/** Record a local learning-profile preference. */
remember(text: string, opts?: LearnRememberOptions): RememberResult;
/** Record feedback (keep/avoid/improve) as a local learning-profile entry. */
feedback(text: string, opts?: LearnFeedbackOptions): RememberResult;
/** Check a Markdown artifact and capture its non-pass results as local learning-profile entries. */
captureFromCheck(artifact: string, opts?: LearnCaptureOptions): CaptureResult;
};
// SDK namespace: learn.*. See docs/AGENT-SDK.md (Phase B) and docs/SDK.md.
//
// The ONLY writing verbs in the SDK. Phase A (route, prompt, pack, search,
// recall, check, routes, version) stays read-only and unchanged — this
// namespace is the explicit, opt-in write boundary: every verb here writes
// only the local learning profile (`DESIGN_AI_LEARNING_FILE` /
// `defaultLearningFile()`), never the network. Consumers target a specific
// profile file via the `DESIGN_AI_LEARNING_FILE` env var, exactly like the
// CLI — there is no `filePath` option and no `now`/timestamp option; the
// underlying cli/lib functions use their own defaults (the env var and
// `new Date()`).
import { checkArtifactContent, buildCheckLearningCapture } from "../lib/check.mjs";
import { rememberLearning, recordLearningFeedback } from "../lib/learn-profile.mjs";
import { assertKnownRouteId } from "../lib/route.mjs";
import { optionalString, requireNonEmptyString, requireOptions } from "./validate.mjs";
/**
* Record a local learning-profile preference. Writes only the local learning
* profile (`DESIGN_AI_LEARNING_FILE` / `defaultLearningFile()`); never the
* network. Pure adapter over `rememberLearning` from cli/lib/learn-profile.mjs.
*
* @param {string} text - Preference text to remember.
* @param {{category?: string}} [opts]
* @returns {{file: string, entry: object, profile: object}} RememberResult.
*/
function remember(text, opts = {}) {
requireNonEmptyString(text, "text");
const options = requireOptions(opts, "learn.remember");
const category = optionalString(options.category, "category", "preference");
return rememberLearning({
text,
category,
source: "sdk",
});
}
/**
* Record feedback (keep/avoid/improve) as a local learning-profile entry.
* Writes only the local learning profile; never the network. Pure adapter
* over `recordLearningFeedback` from cli/lib/learn-profile.mjs.
*
* @param {string} text - Feedback text.
* @param {{outcome?: string, category?: string}} [opts]
* @returns {{file: string, entry: object, profile: object}} RememberResult.
*/
function feedback(text, opts = {}) {
requireNonEmptyString(text, "text");
const options = requireOptions(opts, "learn.feedback");
// The lib normalizes the outcome itself (normalizeFeedbackOutcome); the SDK
// only validates that, if given, it is a string.
const outcome = optionalString(options.outcome, "outcome", "improve");
const category = optionalString(options.category, "category", "workflow");
return recordLearningFeedback({
text,
outcome,
category,
});
}
/**
* Check a Markdown artifact, then capture its non-pass results as local
* learning-profile entries. Writes only the local learning profile; never the
* network. Pure adapter over `checkArtifactContent` + `buildCheckLearningCapture`
* from cli/lib/check.mjs (the same path as the CLI's `check --learn --yes`).
*
* @param {string} artifact - Markdown artifact content to check and capture.
* @param {{routeId?: string}} [opts]
* @returns {object} CaptureResult — the `captureLearningEntries` return shape:
* { file, dryRun, applied, source, candidateCount, addedCount, skippedCount,
* count, entries, skipped }.
*/
function captureFromCheck(artifact, opts = {}) {
requireNonEmptyString(artifact, "artifact");
const options = requireOptions(opts, "learn.captureFromCheck");
const routeId = optionalString(options.routeId, "routeId");
if (routeId) assertKnownRouteId(routeId, { allowEmpty: false });
const report = checkArtifactContent({
content: artifact,
filePath: "sdk",
routeId,
});
return buildCheckLearningCapture(report, { dryRun: false });
}
/**
* The Phase B local-write namespace. `learn.remember`, `learn.feedback`, and
* `learn.captureFromCheck` are the only SDK verbs that write files; all three
* write exclusively to the local learning profile. See docs/SDK.md.
*/
export const learn = Object.freeze({
remember,
feedback,
captureFromCheck,
});
+1
-1
{
"name": "design-ai",
"version": "4.59.0",
"version": "4.60.0",
"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,0 +5,0 @@ "author": {

@@ -1,2 +0,3 @@

// design-ai Agent SDK — Phase A (read-only). See docs/AGENT-SDK.md and docs/SDK.md.
// design-ai Agent SDK — Phase A (read-only) + Phase B (local writes). See
// docs/AGENT-SDK.md and docs/SDK.md.
//

@@ -7,12 +8,19 @@ // A curated, semver-stable adapter over the same cli/lib functions the CLI and

// the same shape the CLI's --json mode emits. No network calls, no runtime
// dependencies. Phase A performs no file writes: no learning-usage sidecar
// writes, even from prompt/pack's withLearning option.
// dependencies. The 8 Phase A verbs below perform no file writes: no
// learning-usage sidecar writes, even from prompt/pack's withLearning option.
//
// Phase B adds a single `learn` namespace grouping the three explicit,
// opt-in LOCAL-WRITE verbs (`learn.remember`, `learn.feedback`,
// `learn.captureFromCheck`). This keeps the write boundary explicit: the 8
// Phase A verbs stay read-only and unchanged; `learn` is the only place the
// SDK writes files, and it only ever writes the local learning profile.
//
// Import path: `@design-ai/cli/sdk` (see the "exports" map in package.json).
// `cli/lib/*` stays internal and unstable; this barrel is the only supported
// public surface. Do not import `cli/lib/*.mjs` directly from outside this
// package — only the 8 named exports below are covered by the semver
// stability contract described in docs/SDK.md.
// package — only the 8 named function exports plus the `learn` namespace
// below are covered by the semver stability contract described in docs/SDK.md.
export { check } from "./check-adapter.mjs";
export { learn } from "./learn-adapter.mjs";
export { pack } from "./pack-adapter.mjs";

@@ -19,0 +27,0 @@ export { prompt } from "./prompt-adapter.mjs";

@@ -78,5 +78,5 @@ # Agent SDK design

### Phase B — optional, explicit local writes
### Phase B — explicit local writes (shipped)
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.
Implemented as a single `learn` namespace export grouping three opt-in adapters that mirror the CLI's local-write commands: `learn.remember`, `learn.feedback`, and `learn.captureFromCheck` (capture from a `check()` report). Each writes only the local learning profile (`DESIGN_AI_LEARNING_FILE` / `defaultLearningFile()`), never the network — no `filePath` or `now`/timestamp option; consumers target a profile via the env var, exactly like the CLI. The 8 Phase A verbs are unchanged and stay read-only; `check()` in particular gets no capture option — capture is reached only through the separate, explicitly-named `learn.captureFromCheck`, keeping the write boundary visible at the call site. See [`SDK.md`](SDK.md#phase-b--local-writes) for the full reference.

@@ -83,0 +83,0 @@ ## Integration points

@@ -8,3 +8,3 @@ # External Publication Status

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.
npm is publicly published at `@design-ai/cli@4.59.0` (npm dist-tag `latest` = `4.59.0`); publish run from tag `v4.59.0` succeeded with provenance and all pre-publish gates green. This release adds the read-only Agent SDK surface (`@design-ai/cli/sdk`, eight adapter verbs) — additive only, so CLI output is unchanged. The live `npm run registry:smoke` passes cleanly against published `@design-ai/cli@4.59.0` ("Registry smoke passed"), covering the retrieval surfaces (index/ranked/embeddings/recall) and route enrichment. GitHub Release `v4.59.0` is published, and the Homebrew tap formula points at the `v4.59.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.

@@ -15,8 +15,8 @@ ## Results

|---|---|---|---|
| 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" |
| npm registry | `@design-ai/cli` | Published latest is `4.59.0` (tag `v4.59.0`, provenance). Pre-publish packed-tarball smoke (incl. SDK import) and live `npm run registry:smoke` both pass for `@design-ai/cli@4.59.0`. | `npm view @design-ai/cli version` → `4.59.0`; live registry smoke "Registry smoke passed" |
| 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` |
| 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` |
| Homebrew tap | `Formula/design-ai.rb` | Formula pinned to `v4.59.0` release source tarball with SHA-256 `e711203fb96fee5f6e7f25d809bc42108553bc8108ddf3e8cd181f0a76f6e0f5` (recomputed from the published tag tarball) | `Formula/design-ai.rb` |
| 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` |
| GitHub Release | `v4.58.0` | Published for tag `v4.58.0` at commit `22dc8a9` | `gh release view v4.58.0` |
| 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` |
| GitHub Release | `v4.59.0` | Published for tag `v4.59.0` at commit `9f53345` | `gh release view v4.59.0` |
| MCP server | `@design-ai/cli@4.59.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` |

@@ -23,0 +23,0 @@ ## Interpretation

# Agent SDK reference
> Status: shipped (Phase A) — read-only verbs, semver-stable surface
> Status: shipped (Phase A + Phase B) — 8 read-only verbs plus the opt-in `learn.*` local-write namespace, semver-stable surface
`@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.
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.
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 (read-only) and Phase B (local-write) surface.

@@ -23,2 +23,12 @@ ## Install and import

### TypeScript
Hand-written type declarations ship with the package at `cli/sdk/index.d.ts` and are wired through the `exports` `types` condition, so TypeScript and editors resolve them automatically for `@design-ai/cli/sdk` — no `@types` install, and no build step on our side (the declarations are maintained by hand to preserve the zero-toolchain stance). Use `moduleResolution: node16`/`nodenext` (or `bundler`) so the subpath `types` condition is honored. All exported types (`RouteResult`, `PromptPlan`, `Pack`, `SearchHit`, `RankedSearchHit`, `RecallResult`, `CheckReport`, option interfaces, …) are importable:
```ts
import { route, type RouteResult, type SearchOptions } from "@design-ai/cli/sdk";
```
A `node --test` guard (`cli/sdk/types.test.mjs`) asserts the declaration file stays in exact sync with the runtime exports.
## Phase A: read-only

@@ -61,3 +71,3 @@

recallLimit?: number,
}): PromptPlan | null
}): PromptPlan
```

@@ -158,8 +168,85 @@

- Signature or return-shape changes are major version bumps.
- 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.
- The 8 read-only function exports (`route`, `prompt`, `pack`, `search`, `recall`, `check`, `routes`, `version`) plus the frozen `learn` namespace object (`learn.remember`, `learn.feedback`, `learn.captureFromCheck`) 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.
- `cli/lib/*` remains internal and unstable. Only `@design-ai/cli/sdk` is a supported import path.
- Determinism: the same inputs always produce the same outputs, with no randomness or time-dependence added by the adapter layer.
## Phase B (not yet shipped)
## Phase B — local writes
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.
Phase A (above) is read-only by design: the 8 verbs never write a file. Phase B adds a single namespace export, `learn`, grouping the three explicit, opt-in **LOCAL-WRITE** verbs. This is the only place the SDK writes files — every Phase A verb stays read-only and unchanged.
```js
import { learn } from "@design-ai/cli/sdk";
learn.remember(text, opts?) // opts: { category?: string }
learn.feedback(text, opts?) // opts: { outcome?: string, category?: string }
learn.captureFromCheck(artifact, opts?) // opts: { routeId?: string }
```
**Write boundary rationale:** an SDK consumer should never be surprised by a file write. Phase A's 8 verbs are safe to call from any context — a build script, a read path, a CI check — with zero side effects. `learn.*` is the deliberate, narrow exception: three verbs, one destination, no ambiguity about what gets written or where.
All three verbs write **only** the local learning profile — `DESIGN_AI_LEARNING_FILE` if set, otherwise the CLI's `defaultLearningFile()` default path — and never touch the network. There is no `filePath` option and no `now`/timestamp option on any of them: target a specific profile the same way the CLI does, by setting the `DESIGN_AI_LEARNING_FILE` environment variable before calling. The underlying library functions supply their own defaults (the env var and `new Date()`).
### `learn.remember(text, opts)`
Record a local learning-profile preference. Adapter over `rememberLearning` from `cli/lib/learn-profile.mjs`.
```js
learn.remember(text: string, opts?: { category?: string }): RememberResult
```
- `text` — required, non-empty string.
- `category` — one of the learning-profile categories (e.g. `preference`, `brand`, `workflow`, `constraint`, `accessibility`, `korean`, `other`); the library normalizes and validates it. Default: `"preference"`.
Returns a `RememberResult`: `{ file, entry, profile }`, where `entry` is `{ id, category, text, source, createdAt }` (`source` is always `"sdk"`) and `profile` is the full updated learning profile `{ version, updatedAt, entries }`.
### `learn.feedback(text, opts)`
Record feedback (keep/avoid/improve) as a local learning-profile entry. Adapter over `recordLearningFeedback` from `cli/lib/learn-profile.mjs`.
```js
learn.feedback(text: string, opts?: { outcome?: string, category?: string }): RememberResult
```
- `text` — required, non-empty string.
- `outcome` — any string; the library normalizes it (`normalizeFeedbackOutcome`) to one of `keep` / `avoid` / `improve` and folds it into both the stored entry's `text` (e.g. `"Avoid in future outputs: …"`) and its `source` (e.g. `"feedback:avoid"`). Default: `"improve"`.
- `category` — same category enum as `remember`. Default: `"workflow"`.
Returns the same `RememberResult` shape as `learn.remember`.
### `learn.captureFromCheck(artifact, opts)`
Check a Markdown artifact, then capture its non-pass results as local learning-profile entries — the SDK equivalent of the CLI's `check --learn --yes`. Adapter over `checkArtifactContent` + `buildCheckLearningCapture` from `cli/lib/check.mjs`.
```js
learn.captureFromCheck(artifact: string, opts?: { routeId?: string }): CaptureResult
```
- `artifact` — required, non-empty Markdown string.
- `routeId` — add route-specific check requirements before capturing; must be a known route id (validated with the same `assertKnownRouteId` helper the read-only `check` adapter uses).
Returns a `CaptureResult` — the `captureLearningEntries` return shape:
```
{
file: string, // the learning profile file written to
dryRun: false, // always false; captureFromCheck always applies
applied: true, // always true when dryRun is false
source: string, // "check:<routeId>" or "check:artifact"
candidateCount: number, // non-pass check results considered
addedCount: number, // entries newly written
skippedCount: number, // entries skipped as duplicates of existing entries
count: number, // total entries in the profile after this call
entries: LearningProfileEntry[], // the entries that were added
skipped: Array<{ category, text, source, reason }>, // reason is "duplicate-entry-text"
}
```
Calling `captureFromCheck` twice with the same artifact adds nothing the second time — every candidate is skipped with `reason: "duplicate-entry-text"`.
### Validation
All three verbs use the same `cli/sdk/validate.mjs` helpers as Phase A: `requireNonEmptyString` for `text`/`artifact`, `requireOptions` for the options bag, and `optionalString` for string options. `routeId` is validated with `assertKnownRouteId`, exactly like the read-only `check` adapter. Bad input throws a plain `Error` with a clear message — no process exit code, no silent fallback.
### What stays unchanged
`check()` (the Phase A read-only verb) is untouched: it still never writes, and it has no capture option. Capture is exclusively reached through `learn.captureFromCheck`, which is a separate, explicitly-named write verb — this keeps the read/write boundary visible at the call site rather than hidden behind an option flag on a read-only function.
{
"name": "@design-ai/cli",
"version": "4.59.0",
"version": "4.60.0",
"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.",

@@ -11,3 +11,6 @@ "bin": {

"exports": {
"./sdk": "./cli/sdk/index.mjs",
"./sdk": {
"types": "./cli/sdk/index.d.ts",
"default": "./cli/sdk/index.mjs"
},
"./package.json": "./package.json"

@@ -14,0 +17,0 @@ },

@@ -15,3 +15,3 @@ # Design AI

> **배포 상태, 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)를 확인하세요.
> **배포 상태, 2026-07-04 확인:** 로컬 `npm run release:check`는 통과했고, GitHub Pages 문서는 live 상태이며, GitHub Release `v4.59.0`과 npm `@design-ai/cli@4.59.0`(`latest`) publish가 provenance와 함께 확인됐어요. 이번 릴리스는 읽기 전용 Agent SDK 표면(`@design-ai/cli/sdk`, 8개 어댑터 verb)을 추가했고 additive라 CLI 출력은 그대로예요. live `npm run registry:smoke`가 published `@design-ai/cli@4.59.0`에 대해 깨끗이 통과했어요(retrieval 표면과 route enrichment 포함). Homebrew formula는 `v4.59.0`에 pinning되어 있고, VS Code Marketplace에는 `sungjin.design-ai-vscode@0.4.1`이 공개되어 있어요. 자세한 내용은 [`docs/external-status.md`](docs/external-status.md)를 확인하세요.

@@ -176,3 +176,3 @@ ## 한눈에 보는 커버리지

전체 단계 로그는 [`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가 완료됐어요.
전체 단계 로그는 [`docs/ROADMAP.md`](docs/ROADMAP.md), 현재 완료 범위는 [`docs/PRODUCT-READINESS.md`](docs/PRODUCT-READINESS.md)에서 확인하세요. 현재 **v4.59.0**: 읽기 전용 Agent SDK(`@design-ai/cli/sdk`), 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가 완료됐어요.

@@ -179,0 +179,0 @@ 핵심 디자인 컨설팅 워크플로우는 로컬 릴리스 기준으로 준비되어 있어요. 웹사이트 개선 컨트롤 타워는 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은 여전히 현재 배포 범위 밖이에요.

@@ -15,3 +15,3 @@ # Design AI

> **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).
> **Distribution status, checked 2026-07-04:** local `npm run release:check` passes, GitHub Pages docs are live, GitHub Release `v4.59.0` is published, `@design-ai/cli@4.59.0` is public on npm (`latest`) with provenance, and the live `npm run registry:smoke` passes cleanly against `@design-ai/cli@4.59.0`. The Homebrew formula is pinned to `v4.59.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).

@@ -218,3 +218,3 @@ ## Coverage at a glance

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.
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.59.0**: the read-only Agent SDK (`@design-ai/cli/sdk`), 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.

@@ -221,0 +221,0 @@ 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.

Sorry, the diff of this file is too big to display

Sorry, the diff of this file is too big to display

Sorry, the diff of this file is too big to display