@design-ai/cli 4.56.0 → 4.57.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 +109 -25
- package/CHANGELOG.md +36 -0
- package/README.ko.md +9 -26
- package/README.md +10 -23
- package/cli/bin/design-ai.mjs +1 -0
- package/cli/commands/help.mjs +7 -4
- package/cli/commands/index.mjs +292 -0
- package/cli/commands/learn-help.mjs +149 -0
- package/cli/commands/learn-print-profile.mjs +373 -0
- package/cli/commands/learn-print-restore.mjs +349 -0
- package/cli/commands/learn-print-signals.mjs +453 -0
- package/cli/commands/learn.mjs +60 -1281
- package/cli/commands/pack.mjs +7 -3
- package/cli/commands/prompt.mjs +7 -3
- package/cli/commands/search.mjs +94 -1
- package/cli/lib/dispatch.mjs +3 -0
- package/cli/lib/embedding-index.mjs +199 -0
- package/cli/lib/embedding-provider.mjs +121 -0
- package/cli/lib/embedding-rerank.mjs +52 -0
- package/cli/lib/learn-args.mjs +490 -0
- package/cli/lib/learn-backup.mjs +748 -0
- package/cli/lib/learn-curation.mjs +612 -0
- package/cli/lib/learn-eval.mjs +459 -0
- package/cli/lib/learn-profile.mjs +763 -0
- package/cli/lib/learn-select.mjs +223 -0
- package/cli/lib/learn-shared.mjs +158 -0
- package/cli/lib/learn-test-support.mjs +218 -0
- package/cli/lib/learn-usage.mjs +360 -0
- package/cli/lib/learn.mjs +83 -3694
- package/cli/lib/lexical.mjs +137 -0
- package/cli/lib/local-config.mjs +110 -0
- package/cli/lib/mcp-server.mjs +13 -3
- package/cli/lib/pack.mjs +31 -4
- package/cli/lib/prompt.mjs +42 -4
- package/cli/lib/recall.mjs +193 -0
- package/cli/lib/retrieval-index.mjs +0 -0
- package/cli/lib/search-ranked.mjs +170 -0
- package/cli/lib/search.mjs +11 -1
- package/cli/lib/signals-backlog-commands.mjs +673 -0
- package/cli/lib/signals-backlog.mjs +361 -0
- package/cli/lib/signals-eval.mjs +176 -0
- package/cli/lib/signals-readiness.mjs +247 -0
- package/cli/lib/signals-registry.mjs +377 -0
- package/cli/lib/signals-render.mjs +478 -0
- package/cli/lib/signals-shared.mjs +75 -0
- package/cli/lib/signals.mjs +16 -2337
- package/cli/lib/site-bundle-handoff-expected.mjs +173 -0
- package/cli/lib/site-bundle-handoff-runbook-action-summary.mjs +332 -0
- package/cli/lib/site-bundle-handoff-runbook-human-lines.mjs +167 -0
- package/cli/lib/site-bundle-handoff-runbook-maps.mjs +238 -0
- package/cli/lib/site-bundle-handoff-runbook-next-step.mjs +278 -0
- package/cli/lib/site-bundle-handoff-runbook.mjs +44 -931
- package/cli/lib/site-test-support.mjs +68 -0
- package/cli/lib/skill-proposals-apply-commands.mjs +135 -0
- package/cli/lib/skill-proposals-apply-contract.mjs +750 -0
- package/cli/lib/skill-proposals-apply-plan.mjs +118 -0
- package/cli/lib/skill-proposals-generate.mjs +298 -0
- package/cli/lib/skill-proposals-render.mjs +532 -0
- package/cli/lib/skill-proposals-review.mjs +262 -0
- package/cli/lib/skill-proposals.mjs +15 -2046
- package/cli/lib/workspace-args.mjs +83 -0
- package/cli/lib/workspace-git.mjs +169 -0
- package/cli/lib/workspace-learning.mjs +483 -0
- package/cli/lib/workspace-repo.mjs +139 -0
- package/cli/lib/workspace-report.mjs +283 -0
- package/cli/lib/workspace-test-support.mjs +99 -0
- package/cli/lib/workspace.mjs +30 -1056
- package/docs/AI-LEARNING-PHASE2.md +215 -0
- package/docs/DISTRIBUTION.ko.md +2 -2
- package/docs/DISTRIBUTION.md +2 -2
- package/docs/NEXT-SURFACE-DECISION.md +125 -0
- package/docs/PRODUCT-READINESS.md +3 -3
- package/docs/RELEASE-GATES.ko.md +35 -0
- package/docs/RELEASE-GATES.md +234 -0
- package/docs/ROADMAP.md +53 -8
- package/docs/external-status.md +6 -8
- package/docs/inspection-20260630.md +169 -0
- package/docs/integrations/design-ai-mcp-server.md +4 -4
- package/docs/reference/ant-design.md +413 -0
- package/docs/reference/awesome-design-md.md +439 -0
- package/docs/reference/mui.md +783 -0
- package/docs/reference/shadcn-ui.md +298 -0
- package/examples/component-accordion-actions.md +5 -5
- package/examples/component-accordion-details.md +5 -5
- package/examples/component-accordion-summary.md +5 -5
- package/examples/component-accordion.md +3 -3
- package/examples/component-affix.md +1 -1
- package/examples/component-alert-dialog.md +1 -1
- package/examples/component-alert-title.md +1 -1
- package/examples/component-alert.md +3 -3
- package/examples/component-anchor.md +1 -1
- package/examples/component-app-bar.md +1 -1
- package/examples/component-aspect-ratio.md +1 -1
- package/examples/component-auto-complete.md +2 -2
- package/examples/component-avatar-group.md +5 -5
- package/examples/component-avatar.md +3 -3
- package/examples/component-back-top.md +1 -1
- package/examples/component-backdrop.md +1 -1
- package/examples/component-badge.md +3 -3
- package/examples/component-border-beam.md +3 -3
- package/examples/component-bottom-navigation.md +1 -1
- package/examples/component-box.md +1 -1
- package/examples/component-breadcrumb.md +3 -3
- package/examples/component-button-base.md +3 -3
- package/examples/component-button-group.md +2 -2
- package/examples/component-button.md +3 -3
- package/examples/component-calendar.md +2 -2
- package/examples/component-card-actions.md +1 -1
- package/examples/component-card-content.md +1 -1
- package/examples/component-card-header.md +1 -1
- package/examples/component-card-media.md +1 -1
- package/examples/component-card.md +3 -3
- package/examples/component-carousel.md +2 -2
- package/examples/component-cascader.md +1 -1
- package/examples/component-chart.md +1 -1
- package/examples/component-checkbox.md +3 -3
- package/examples/component-click-away-listener.md +1 -1
- package/examples/component-code.md +1 -1
- package/examples/component-collapsible.md +1 -1
- package/examples/component-color-picker.md +1 -1
- package/examples/component-combobox.md +1 -1
- package/examples/component-command.md +1 -1
- package/examples/component-config-provider.md +3 -3
- package/examples/component-context-menu.md +1 -1
- package/examples/component-css-baseline.md +3 -3
- package/examples/component-date-picker.md +2 -2
- package/examples/component-descriptions.md +1 -1
- package/examples/component-dialog-actions.md +1 -1
- package/examples/component-dialog-content-text.md +1 -1
- package/examples/component-dialog-content.md +1 -1
- package/examples/component-dialog-title.md +1 -1
- package/examples/component-dialog.md +2 -2
- package/examples/component-divider.md +3 -3
- package/examples/component-drawer.md +3 -3
- package/examples/component-dropdown.md +3 -3
- package/examples/component-empty.md +2 -2
- package/examples/component-fade.md +1 -1
- package/examples/component-field.md +1 -1
- package/examples/component-filled-input.md +1 -1
- package/examples/component-flex.md +1 -1
- package/examples/component-float-button.md +2 -2
- package/examples/component-form-control-label.md +1 -1
- package/examples/component-form-control.md +1 -1
- package/examples/component-form-controls.md +1 -1
- package/examples/component-form-group.md +1 -1
- package/examples/component-form-helper-text.md +1 -1
- package/examples/component-form-label.md +1 -1
- package/examples/component-form.md +2 -2
- package/examples/component-grid.md +2 -2
- package/examples/component-grow.md +1 -1
- package/examples/component-hover-card.md +1 -1
- package/examples/component-icon-button.md +1 -1
- package/examples/component-icon.md +1 -1
- package/examples/component-image-list.md +1 -1
- package/examples/component-image.md +1 -1
- package/examples/component-input-adornment.md +1 -1
- package/examples/component-input-base.md +1 -1
- package/examples/component-input-number.md +1 -1
- package/examples/component-input-otp.md +2 -2
- package/examples/component-input.md +3 -3
- package/examples/component-item.md +1 -1
- package/examples/component-label.md +1 -1
- package/examples/component-layout.md +1 -1
- package/examples/component-link.md +1 -1
- package/examples/component-list-item-avatar.md +1 -1
- package/examples/component-list-item-button.md +1 -1
- package/examples/component-list-item-icon.md +1 -1
- package/examples/component-list-item-text.md +1 -1
- package/examples/component-list-item.md +1 -1
- package/examples/component-list-subheader.md +1 -1
- package/examples/component-list.md +2 -2
- package/examples/component-masonry.md +1 -1
- package/examples/component-mentions.md +1 -1
- package/examples/component-menu-item.md +1 -1
- package/examples/component-menu-list.md +1 -1
- package/examples/component-menu.md +1 -1
- package/examples/component-menubar.md +1 -1
- package/examples/component-message.md +1 -1
- package/examples/component-mobile-stepper.md +1 -1
- package/examples/component-modal.md +5 -5
- package/examples/component-navigation-menu.md +1 -1
- package/examples/component-notification.md +1 -1
- package/examples/component-outlined-input.md +1 -1
- package/examples/component-pagination.md +3 -3
- package/examples/component-paper.md +1 -1
- package/examples/component-popconfirm.md +1 -1
- package/examples/component-popover.md +3 -3
- package/examples/component-popper.md +1 -1
- package/examples/component-progress.md +2 -2
- package/examples/component-qr-code.md +1 -1
- package/examples/component-radio.md +3 -3
- package/examples/component-rate.md +2 -2
- package/examples/component-resizable.md +1 -1
- package/examples/component-result.md +1 -1
- package/examples/component-scroll-area.md +1 -1
- package/examples/component-segmented.md +3 -3
- package/examples/component-select.md +3 -3
- package/examples/component-separator.md +1 -1
- package/examples/component-sheet.md +1 -1
- package/examples/component-sidebar.md +1 -1
- package/examples/component-skeleton.md +3 -3
- package/examples/component-slide.md +1 -1
- package/examples/component-slider.md +3 -3
- package/examples/component-snackbar-content.md +1 -1
- package/examples/component-snackbar.md +1 -1
- package/examples/component-sonner.md +1 -1
- package/examples/component-space.md +1 -1
- package/examples/component-speed-dial-action.md +1 -1
- package/examples/component-speed-dial.md +1 -1
- package/examples/component-spin.md +2 -2
- package/examples/component-spinner.md +1 -1
- package/examples/component-splitter.md +2 -2
- package/examples/component-stack.md +1 -1
- package/examples/component-statistic.md +1 -1
- package/examples/component-step-button.md +4 -4
- package/examples/component-step-connector.md +4 -4
- package/examples/component-step-content.md +1 -1
- package/examples/component-step-icon.md +1 -1
- package/examples/component-step-label.md +1 -1
- package/examples/component-step.md +2 -2
- package/examples/component-steps.md +2 -2
- package/examples/component-swipeable-drawer.md +1 -1
- package/examples/component-switch.md +3 -3
- package/examples/component-tab-scroll-button.md +5 -5
- package/examples/component-tab.md +1 -1
- package/examples/component-table-body.md +1 -1
- package/examples/component-table-cell.md +1 -1
- package/examples/component-table-container.md +1 -1
- package/examples/component-table-footer.md +1 -1
- package/examples/component-table-head.md +1 -1
- package/examples/component-table-pagination.md +1 -1
- package/examples/component-table-row.md +1 -1
- package/examples/component-table-sort-label.md +1 -1
- package/examples/component-table.md +2 -2
- package/examples/component-tabs.md +3 -3
- package/examples/component-tag-badge.md +2 -2
- package/examples/component-tag.md +1 -1
- package/examples/component-textarea-autosize.md +1 -1
- package/examples/component-textarea.md +1 -1
- package/examples/component-time-picker.md +1 -1
- package/examples/component-timeline.md +1 -1
- package/examples/component-toast.md +4 -4
- package/examples/component-toggle-button.md +1 -1
- package/examples/component-toggle.md +1 -1
- package/examples/component-toolbar.md +1 -1
- package/examples/component-tooltip.md +3 -3
- package/examples/component-tour.md +1 -1
- package/examples/component-transfer.md +1 -1
- package/examples/component-tree-select.md +1 -1
- package/examples/component-tree.md +1 -1
- package/examples/component-typography.md +2 -2
- package/examples/component-upload.md +1 -1
- package/examples/component-watermark.md +1 -1
- package/examples/component-zoom.md +1 -1
- package/knowledge/COVERAGE.md +4 -3
- package/knowledge/components/INDEX.md +202 -202
- package/knowledge/patterns/brand-references.md +72 -72
- package/package.json +1 -1
- package/tools/audit/local-ci.py +16 -1
- package/tools/audit/package-smoke.py +611 -9
- package/tools/audit/registry-smoke.py +534 -0
- package/tools/audit/release-metadata.py +47 -1
- package/tools/audit/smoke_assertions.py +915 -13
- package/tools/migrations/refs-links-to-reference-pages.py +179 -0
|
@@ -0,0 +1,292 @@
|
|
|
1
|
+
// `design-ai index` — build, inspect, and verify the local retrieval index.
|
|
2
|
+
// Explicit-only: nothing here runs in the background or on behalf of other commands.
|
|
3
|
+
|
|
4
|
+
import { DESIGN_AI_HOME } from "../lib/paths.mjs";
|
|
5
|
+
import { dim, header, info, success, warn } from "../lib/log.mjs";
|
|
6
|
+
import {
|
|
7
|
+
buildEmbeddingIndex,
|
|
8
|
+
embeddingIndexStatus,
|
|
9
|
+
loadEmbeddingIndexFile,
|
|
10
|
+
writeEmbeddingIndex,
|
|
11
|
+
} from "../lib/embedding-index.mjs";
|
|
12
|
+
import { configuredEmbeddingProvider, defaultConfigFile } from "../lib/local-config.mjs";
|
|
13
|
+
import {
|
|
14
|
+
buildCorpusIndex,
|
|
15
|
+
buildLearningIndex,
|
|
16
|
+
defaultIndexDir,
|
|
17
|
+
retrievalIndexStatus,
|
|
18
|
+
verifyRetrievalIndexes,
|
|
19
|
+
writeRetrievalIndexes,
|
|
20
|
+
} from "../lib/retrieval-index.mjs";
|
|
21
|
+
import { defaultLearningFile } from "../lib/learn-shared.mjs";
|
|
22
|
+
import { unknownOptionMessage } from "../lib/suggest.mjs";
|
|
23
|
+
|
|
24
|
+
const INDEX_OPTIONS = ["-h", "--help", "--build", "--status", "--verify", "--json", "--embeddings", "--provider"];
|
|
25
|
+
|
|
26
|
+
// A bare --provider command string is split on spaces (documented here and in
|
|
27
|
+
// printHelp): "python3 embed.py --quiet" -> command "python3", args ["embed.py",
|
|
28
|
+
// "--quiet"]. Providers whose command or args need spaces/quoting should be
|
|
29
|
+
// configured via ~/.design-ai/config.json embeddings.provider.args instead — that
|
|
30
|
+
// is the robust path; --provider is the quick one-shot override.
|
|
31
|
+
function parseProviderFlag(value) {
|
|
32
|
+
const parts = String(value || "").trim().split(/\s+/).filter(Boolean);
|
|
33
|
+
if (parts.length === 0) return null;
|
|
34
|
+
return { command: parts[0], args: parts.slice(1) };
|
|
35
|
+
}
|
|
36
|
+
|
|
37
|
+
export function parseIndexArgs(args) {
|
|
38
|
+
const out = { action: "status", json: false, help: false, embeddings: false, provider: "" };
|
|
39
|
+
for (let i = 0; i < args.length; i += 1) {
|
|
40
|
+
const arg = args[i];
|
|
41
|
+
if (arg === "-h" || arg === "--help") {
|
|
42
|
+
out.help = true;
|
|
43
|
+
} else if (arg === "--json") {
|
|
44
|
+
out.json = true;
|
|
45
|
+
} else if (arg === "--build") {
|
|
46
|
+
out.action = "build";
|
|
47
|
+
} else if (arg === "--status") {
|
|
48
|
+
out.action = "status";
|
|
49
|
+
} else if (arg === "--verify") {
|
|
50
|
+
out.action = "verify";
|
|
51
|
+
} else if (arg === "--embeddings") {
|
|
52
|
+
out.embeddings = true;
|
|
53
|
+
} else if (arg === "--provider") {
|
|
54
|
+
out.provider = args[i + 1] || "";
|
|
55
|
+
i += 1;
|
|
56
|
+
} else {
|
|
57
|
+
throw new Error(unknownOptionMessage("index", arg, INDEX_OPTIONS));
|
|
58
|
+
}
|
|
59
|
+
}
|
|
60
|
+
return out;
|
|
61
|
+
}
|
|
62
|
+
|
|
63
|
+
function printHelp() {
|
|
64
|
+
console.log("Usage: design-ai index [--build|--status|--verify] [--json] [--embeddings [--provider \"cmd args\"]]\n");
|
|
65
|
+
console.log("Manages the local retrieval index (derived, rebuildable cache files).");
|
|
66
|
+
console.log("Index files stay on this machine and are safe to delete at any time.\n");
|
|
67
|
+
console.log("Options:");
|
|
68
|
+
console.log(" --build Build/refresh the corpus + learning retrieval index (explicit, never background)");
|
|
69
|
+
console.log(" --status Report index paths, digests, staleness, and document counts. Default action");
|
|
70
|
+
console.log(" --verify Rebuild in memory and compare against the stored index; read-only");
|
|
71
|
+
console.log(" --json Emit machine-readable output");
|
|
72
|
+
console.log(" --embeddings Also build the opt-in local embedding sidecar (requires a provider)");
|
|
73
|
+
console.log(" --provider \"cmd args\" Embedding provider command for this invocation (overrides config).");
|
|
74
|
+
console.log(" Split on spaces; for commands needing quoting, use the config file's");
|
|
75
|
+
console.log(" embeddings.provider.args array instead (~/.design-ai/config.json)");
|
|
76
|
+
console.log("\nEmbeddings are never built by default: --embeddings requires a provider from --provider or");
|
|
77
|
+
console.log("~/.design-ai/config.json (embeddings.provider), and both a config AND the --embeddings flag");
|
|
78
|
+
console.log("are required — config alone never silently enables it.");
|
|
79
|
+
}
|
|
80
|
+
|
|
81
|
+
function statusLine(label, entry) {
|
|
82
|
+
if (!entry.present) return `${label}: missing (run design-ai index --build)`;
|
|
83
|
+
if (entry.error) return `${label}: unreadable — ${entry.error}`;
|
|
84
|
+
const freshness = entry.fresh ? "fresh" : "stale (run design-ai index --build)";
|
|
85
|
+
return `${label}: ${freshness} — ${entry.documentCount} documents, generated ${entry.generatedAt}`;
|
|
86
|
+
}
|
|
87
|
+
|
|
88
|
+
function embeddingsStatusLine(embeddings) {
|
|
89
|
+
if (!embeddings) return "Embeddings: not built (opt-in; design-ai index --build --embeddings --provider ...)";
|
|
90
|
+
if (embeddings.error) return `Embeddings: unreadable — ${embeddings.error}`;
|
|
91
|
+
const freshness = embeddings.fresh ? "fresh" : "stale (run design-ai index --build --embeddings)";
|
|
92
|
+
const providerLabel = embeddings.provider ? ` (provider: ${embeddings.provider.command})` : "";
|
|
93
|
+
return `Embeddings: ${freshness} — ${embeddings.documentCount} vectors, generated ${embeddings.generatedAt}${providerLabel}`;
|
|
94
|
+
}
|
|
95
|
+
|
|
96
|
+
function printStatus(status) {
|
|
97
|
+
header("design-ai index", "status");
|
|
98
|
+
info(`Index dir: ${status.indexDir}`);
|
|
99
|
+
info(statusLine("Corpus index", status.corpus));
|
|
100
|
+
info(statusLine("Learning index", status.learning));
|
|
101
|
+
info(embeddingsStatusLine(status.embeddings));
|
|
102
|
+
if (status.fresh) {
|
|
103
|
+
success("Index is fresh.");
|
|
104
|
+
} else {
|
|
105
|
+
warn(`Index is not fresh. Rebuild with: ${status.buildCommand}`);
|
|
106
|
+
}
|
|
107
|
+
}
|
|
108
|
+
|
|
109
|
+
function resolveProvider({ flagProvider, configFile }) {
|
|
110
|
+
if (flagProvider) return { provider: parseProviderFlag(flagProvider), source: "flag" };
|
|
111
|
+
const configured = configuredEmbeddingProvider(configFile);
|
|
112
|
+
if (configured) return { provider: configured, source: "config" };
|
|
113
|
+
return { provider: null, source: "" };
|
|
114
|
+
}
|
|
115
|
+
|
|
116
|
+
function embeddingsUnavailableError({ configFile }) {
|
|
117
|
+
return [
|
|
118
|
+
"--embeddings requires a provider: pass --provider \"command args\" for this invocation,",
|
|
119
|
+
`or configure embeddings.provider in ${configFile} (see docs/AI-LEARNING-PHASE2.md, Phase B).`,
|
|
120
|
+
].join("\n");
|
|
121
|
+
}
|
|
122
|
+
|
|
123
|
+
// index --status embeddings section shape (nullable, present only when the sidecar
|
|
124
|
+
// file exists): { file, present, fresh, sourceMatch, generatedAt, documentCount,
|
|
125
|
+
// provider, storedDigest, currentDigest, error }. Positioned after "learning" and
|
|
126
|
+
// before top-level "fresh" in the JSON payload (documented contract).
|
|
127
|
+
function embeddingsStatusSection(context) {
|
|
128
|
+
const raw = embeddingIndexStatus(context);
|
|
129
|
+
if (!raw.present) return null;
|
|
130
|
+
return raw;
|
|
131
|
+
}
|
|
132
|
+
|
|
133
|
+
export async function runIndex(args) {
|
|
134
|
+
const parsed = parseIndexArgs(args);
|
|
135
|
+
if (parsed.help) {
|
|
136
|
+
printHelp();
|
|
137
|
+
return;
|
|
138
|
+
}
|
|
139
|
+
|
|
140
|
+
const context = {
|
|
141
|
+
designAiPath: DESIGN_AI_HOME,
|
|
142
|
+
indexDir: defaultIndexDir(),
|
|
143
|
+
learningFile: defaultLearningFile(),
|
|
144
|
+
};
|
|
145
|
+
const configFile = defaultConfigFile();
|
|
146
|
+
|
|
147
|
+
if (parsed.action === "build") {
|
|
148
|
+
const corpus = buildCorpusIndex({ designAiPath: context.designAiPath });
|
|
149
|
+
const learning = buildLearningIndex({ filePath: context.learningFile });
|
|
150
|
+
const written = writeRetrievalIndexes({ indexDir: context.indexDir, corpus, learning });
|
|
151
|
+
|
|
152
|
+
let embeddingsResult = null;
|
|
153
|
+
if (parsed.embeddings) {
|
|
154
|
+
const { provider } = resolveProvider({ flagProvider: parsed.provider, configFile });
|
|
155
|
+
if (!provider) {
|
|
156
|
+
embeddingsResult = { ok: false, error: embeddingsUnavailableError({ configFile }) };
|
|
157
|
+
} else {
|
|
158
|
+
const built = buildEmbeddingIndex({
|
|
159
|
+
provider,
|
|
160
|
+
designAiPath: context.designAiPath,
|
|
161
|
+
learningFile: context.learningFile,
|
|
162
|
+
});
|
|
163
|
+
if (built.ok) {
|
|
164
|
+
const writtenEmbeddings = writeEmbeddingIndex({ indexDir: context.indexDir, payload: built.payload });
|
|
165
|
+
embeddingsResult = {
|
|
166
|
+
ok: true,
|
|
167
|
+
file: writtenEmbeddings.file,
|
|
168
|
+
documentCount: built.payload.vectors.length,
|
|
169
|
+
provider: { command: built.payload.provider.command, modelLabel: built.payload.provider.modelLabel, dimensions: built.payload.provider.dimensions },
|
|
170
|
+
};
|
|
171
|
+
} else {
|
|
172
|
+
embeddingsResult = { ok: false, error: built.error };
|
|
173
|
+
}
|
|
174
|
+
}
|
|
175
|
+
}
|
|
176
|
+
|
|
177
|
+
if (parsed.json) {
|
|
178
|
+
const payload = {
|
|
179
|
+
action: "build",
|
|
180
|
+
indexDir: context.indexDir,
|
|
181
|
+
corpus: { file: written.corpusFile, documentCount: corpus.stats.documentCount, digest: corpus.source.corpusDigest },
|
|
182
|
+
learning: { file: written.learningFile, documentCount: learning.stats.documentCount, digest: learning.source.learningDigest },
|
|
183
|
+
};
|
|
184
|
+
if (embeddingsResult) payload.embeddings = embeddingsResult;
|
|
185
|
+
console.log(JSON.stringify(payload, null, 2));
|
|
186
|
+
if (embeddingsResult && !embeddingsResult.ok) process.exitCode = 1;
|
|
187
|
+
return;
|
|
188
|
+
}
|
|
189
|
+
|
|
190
|
+
header("design-ai index", "build");
|
|
191
|
+
info(`Corpus index: ${written.corpusFile} (${corpus.stats.documentCount} documents)`);
|
|
192
|
+
info(`Learning index: ${written.learningFile} (${learning.stats.documentCount} entries)`);
|
|
193
|
+
success("Index built.");
|
|
194
|
+
if (embeddingsResult) {
|
|
195
|
+
if (embeddingsResult.ok) {
|
|
196
|
+
success(`Embedding index built: ${embeddingsResult.file} (${embeddingsResult.documentCount} vectors)`);
|
|
197
|
+
} else {
|
|
198
|
+
warn(`Embedding index not built: ${embeddingsResult.error}`);
|
|
199
|
+
process.exitCode = 1;
|
|
200
|
+
}
|
|
201
|
+
}
|
|
202
|
+
return;
|
|
203
|
+
}
|
|
204
|
+
|
|
205
|
+
if (parsed.action === "verify") {
|
|
206
|
+
const verify = verifyRetrievalIndexes(context);
|
|
207
|
+
const embeddings = embeddingsStatusSection(context);
|
|
208
|
+
let embeddingsCheck = null;
|
|
209
|
+
if (embeddings) {
|
|
210
|
+
if (embeddings.error) {
|
|
211
|
+
embeddingsCheck = { name: "embeddings", file: embeddings.file, matches: false, reason: embeddings.error };
|
|
212
|
+
} else {
|
|
213
|
+
const { provider } = resolveProvider({ flagProvider: parsed.provider, configFile });
|
|
214
|
+
if (!provider) {
|
|
215
|
+
embeddingsCheck = {
|
|
216
|
+
name: "embeddings",
|
|
217
|
+
file: embeddings.file,
|
|
218
|
+
matches: true,
|
|
219
|
+
skipped: true,
|
|
220
|
+
reason: "skipped: provider unavailable (pass --provider or configure ~/.design-ai/config.json to verify embedding content)",
|
|
221
|
+
};
|
|
222
|
+
} else {
|
|
223
|
+
const rebuilt = buildEmbeddingIndex({
|
|
224
|
+
provider,
|
|
225
|
+
designAiPath: context.designAiPath,
|
|
226
|
+
learningFile: context.learningFile,
|
|
227
|
+
});
|
|
228
|
+
if (!rebuilt.ok) {
|
|
229
|
+
embeddingsCheck = {
|
|
230
|
+
name: "embeddings",
|
|
231
|
+
file: embeddings.file,
|
|
232
|
+
matches: true,
|
|
233
|
+
skipped: true,
|
|
234
|
+
reason: `skipped: provider unavailable (${rebuilt.error})`,
|
|
235
|
+
};
|
|
236
|
+
} else {
|
|
237
|
+
const stored = loadEmbeddingIndexFile(embeddings.file);
|
|
238
|
+
const normalize = (payload) => {
|
|
239
|
+
const { generatedAt, ...rest } = payload || {};
|
|
240
|
+
return JSON.stringify(rest);
|
|
241
|
+
};
|
|
242
|
+
const matches = normalize(stored.payload) === normalize(rebuilt.payload);
|
|
243
|
+
embeddingsCheck = {
|
|
244
|
+
name: "embeddings",
|
|
245
|
+
file: embeddings.file,
|
|
246
|
+
matches,
|
|
247
|
+
reason: matches ? "" : "stored embedding index differs from an in-memory rebuild of its sources",
|
|
248
|
+
};
|
|
249
|
+
}
|
|
250
|
+
}
|
|
251
|
+
}
|
|
252
|
+
verify.checks.push(embeddingsCheck);
|
|
253
|
+
verify.ok = verify.ok && (embeddingsCheck.matches !== false);
|
|
254
|
+
}
|
|
255
|
+
|
|
256
|
+
if (parsed.json) {
|
|
257
|
+
console.log(JSON.stringify({ action: "verify", ...verify }, null, 2));
|
|
258
|
+
} else {
|
|
259
|
+
header("design-ai index", "verify");
|
|
260
|
+
for (const check of verify.checks) {
|
|
261
|
+
if (check.matches) {
|
|
262
|
+
info(check.skipped ? `${check.name}: ${check.reason}` : `${check.name}: matches an in-memory rebuild`);
|
|
263
|
+
} else {
|
|
264
|
+
warn(`${check.name}: ${check.reason}`);
|
|
265
|
+
console.log(` ${dim(check.file)}`);
|
|
266
|
+
}
|
|
267
|
+
}
|
|
268
|
+
if (verify.ok) success("Stored index matches its sources.");
|
|
269
|
+
}
|
|
270
|
+
if (!verify.ok) process.exitCode = 1;
|
|
271
|
+
return;
|
|
272
|
+
}
|
|
273
|
+
|
|
274
|
+
const status = retrievalIndexStatus(context);
|
|
275
|
+
const embeddings = embeddingsStatusSection(context);
|
|
276
|
+
const fresh = embeddings ? status.fresh && embeddings.fresh : status.fresh;
|
|
277
|
+
// Key order is a documented contract (embeddings sits after learning, before
|
|
278
|
+
// fresh) — build the object explicitly rather than relying on spread order.
|
|
279
|
+
const fullStatus = {
|
|
280
|
+
indexDir: status.indexDir,
|
|
281
|
+
corpus: status.corpus,
|
|
282
|
+
learning: status.learning,
|
|
283
|
+
embeddings,
|
|
284
|
+
fresh,
|
|
285
|
+
buildCommand: status.buildCommand,
|
|
286
|
+
};
|
|
287
|
+
if (parsed.json) {
|
|
288
|
+
console.log(JSON.stringify({ action: "status", ...fullStatus }, null, 2));
|
|
289
|
+
return;
|
|
290
|
+
}
|
|
291
|
+
printStatus(fullStatus);
|
|
292
|
+
}
|
|
@@ -0,0 +1,149 @@
|
|
|
1
|
+
// Help text for `design-ai learn`.
|
|
2
|
+
|
|
3
|
+
import { LEARNING_FEEDBACK_OUTCOMES } from "../lib/learn.mjs";
|
|
4
|
+
|
|
5
|
+
export function printHelp() {
|
|
6
|
+
console.log("Usage: design-ai learn [--list] [--category kind] [--query text] [--explain] [--limit N] [--json] [--out file] [--force]");
|
|
7
|
+
console.log(" design-ai learn --recall query [--limit N] [--category kind] [--json]");
|
|
8
|
+
console.log(" design-ai learn <mode> ... Bare-word alias for a mode flag, e.g. `learn signals --json` = `learn --signals --json`");
|
|
9
|
+
console.log(" design-ai learn --init [--yes|--dry-run] [--json] [--out file] [--force]");
|
|
10
|
+
console.log(" design-ai learn --remember text [--category kind] [--json] [--out file] [--force]");
|
|
11
|
+
console.log(" design-ai learn --feedback text [--outcome keep|improve|avoid] [--category kind] [--json] [--out file] [--force]");
|
|
12
|
+
console.log(" design-ai learn --feedback --from-file notes.md [--outcome keep|improve|avoid] [--category kind] [--json] [--out file] [--force]");
|
|
13
|
+
console.log(" cat notes.md | design-ai learn --feedback --stdin [--outcome keep|improve|avoid] [--category kind] [--json] [--out file] [--force]");
|
|
14
|
+
console.log(" design-ai learn --from-file notes.md [--category kind] [--json] [--out file] [--force]");
|
|
15
|
+
console.log(" cat notes.md | design-ai learn --stdin [--category kind] [--json] [--out file] [--force]");
|
|
16
|
+
console.log(" design-ai learn --export [--category kind] [--query text] [--limit N] [--json] [--out file] [--force]");
|
|
17
|
+
console.log(" design-ai learn --backup [--json] [--out file] [--force]");
|
|
18
|
+
console.log(" design-ai learn --redact [--json] [--out file] [--force]");
|
|
19
|
+
console.log(" design-ai learn --redact --from-file learning-backup.json [--json] [--out file] [--force]");
|
|
20
|
+
console.log(" cat learning-backup.json | design-ai learn --redact --stdin [--json] [--out file] [--force]");
|
|
21
|
+
console.log(" design-ai learn --verify --from-file learning.json [--json] [--out file] [--force]");
|
|
22
|
+
console.log(" cat learning.json | design-ai learn --verify --stdin [--json] [--out file] [--force]");
|
|
23
|
+
console.log(" design-ai learn --diff --from-file learning.json [--json] [--out file] [--force]");
|
|
24
|
+
console.log(" cat learning.json | design-ai learn --diff --stdin [--json] [--out file] [--force]");
|
|
25
|
+
console.log(" design-ai learn --restore --from-file learning-backup.json [--dry-run|--yes] [--backup-file path] [--json] [--out file] [--force]");
|
|
26
|
+
console.log(" cat learning-backup.json | design-ai learn --restore --stdin [--dry-run|--yes] [--backup-file path] [--json] [--out file] [--force]");
|
|
27
|
+
console.log(" design-ai learn --restore-backups [--limit N] [--json] [--out file] [--force]");
|
|
28
|
+
console.log(" design-ai learn --restore-backups --prune [--keep N] [--dry-run|--yes] [--json] [--out file] [--force]");
|
|
29
|
+
console.log(" design-ai learn --import --from-file learning.json --dry-run [--json] [--out file] [--force]");
|
|
30
|
+
console.log(" cat learning.json | design-ai learn --import --stdin --yes [--json] [--out file] [--force]");
|
|
31
|
+
console.log(" design-ai learn --audit [--json] [--out file] [--force]");
|
|
32
|
+
console.log(" design-ai learn --audit --fix --dry-run [--json] [--out file] [--force]");
|
|
33
|
+
console.log(" design-ai learn --audit --fix --yes [--json] [--out file] [--force]");
|
|
34
|
+
console.log(" design-ai learn --curate [--dry-run|--yes] [--usage-file path] [--json|--report] [--out file] [--force]");
|
|
35
|
+
console.log(" design-ai learn --stats [--json] [--out file] [--force]");
|
|
36
|
+
console.log(" design-ai learn --usage [--limit N] [--usage-file path] [--json] [--out file] [--force]");
|
|
37
|
+
console.log(" design-ai learn --signals [--from-file signal-file-or-dir] [--usage-file path] [--strict] [--json|--report] [--out file] [--force]");
|
|
38
|
+
console.log(" design-ai learn --agent-backlog [--from-file signal-file-or-dir] [--usage-file path] [--strict] [--json|--report] [--out file] [--force]");
|
|
39
|
+
console.log(" design-ai learn --propose-skills [--from-file signal-file-or-dir] [--usage-file path] [--review-file path] [--review-check|--apply-plan] [--min-evidence N] [--strict] [--json|--report|--patch|--review-template] [--out file] [--force]");
|
|
40
|
+
console.log(" design-ai learn --eval-template [--query text] [--category kind] [--limit N] [--json] [--out file] [--force]");
|
|
41
|
+
console.log(" design-ai learn --eval --from-file eval.json [--category kind] [--limit N] [--strict] [--json] [--out file] [--force]");
|
|
42
|
+
console.log(" cat eval.json | design-ai learn --eval --stdin [--category kind] [--limit N] [--strict] [--json]");
|
|
43
|
+
console.log(" design-ai learn --forget id-or-number --yes [--json] [--out file] [--force]");
|
|
44
|
+
console.log(" design-ai learn --clear --yes [--json] [--out file] [--force]\n");
|
|
45
|
+
console.log("Stores local design preferences for explicit prompt personalization.");
|
|
46
|
+
console.log("This is local memory, not model training or fine-tuning.\n");
|
|
47
|
+
console.log("Options:");
|
|
48
|
+
console.log(" --init Preview or apply starter local learning entries for dogfood use");
|
|
49
|
+
console.log(" --remember text Remember an inline preference or project constraint");
|
|
50
|
+
console.log(" --feedback text Convert outcome feedback into a reusable local learning note");
|
|
51
|
+
console.log(` --outcome kind Feedback outcome: ${LEARNING_FEEDBACK_OUTCOMES.join(", ")}. Default: improve`);
|
|
52
|
+
console.log(" --from-file file Read remember/feedback text or import/verify/diff/restore/redact JSON from a file");
|
|
53
|
+
console.log(" --stdin Read remember/feedback text or import/verify/diff/restore/redact JSON from standard input");
|
|
54
|
+
console.log(" --category kind preference, brand, workflow, constraint, accessibility, korean, other");
|
|
55
|
+
console.log(" --query text Filter list/export output to entries whose category or text matches the query");
|
|
56
|
+
console.log(" --explain With --list, include selection score, matched tokens, and reason");
|
|
57
|
+
console.log(" --limit N Limit list/export output to the N most recent matching entries, 1-100");
|
|
58
|
+
console.log(" --recall query Read-only combined recall: top corpus knowledge files plus local learning entries ranked for the query");
|
|
59
|
+
console.log(" --list List saved learning entries. Default when no action is given");
|
|
60
|
+
console.log(" --export Print the learned-context block used by --with-learning");
|
|
61
|
+
console.log(" --backup Print a full portable learning-profile backup; use --json for importable JSON");
|
|
62
|
+
console.log(" --redact Print a portable JSON backup with sensitive-looking text redacted");
|
|
63
|
+
console.log(" --verify Validate a portable learning JSON payload without importing it");
|
|
64
|
+
console.log(" --diff Compare the active profile against a portable learning JSON payload without importing it");
|
|
65
|
+
console.log(" --restore Preview or apply replacing the active profile with a portable learning JSON payload");
|
|
66
|
+
console.log(" --restore-backups List sibling restore rollback backups for the active learning profile");
|
|
67
|
+
console.log(" --prune With --restore-backups, preview or delete older rollback backup files");
|
|
68
|
+
console.log(" --keep N With --restore-backups --prune, keep the N newest backups. Default: 5");
|
|
69
|
+
console.log(" --backup-file path With --restore, override the automatic rollback backup file path");
|
|
70
|
+
console.log(" --import Merge entries from a JSON learning profile or learn --export --json payload");
|
|
71
|
+
console.log(" --audit Inspect profile shape, sensitive content, and cleanup suggestions without changing it");
|
|
72
|
+
console.log(" --fix With --audit, prepare or apply safe cleanup suggestions");
|
|
73
|
+
console.log(" --curate Preview or apply archive-first curation for duplicate/sensitive entries, plus usage review hints");
|
|
74
|
+
console.log(" --report With --curate, --signals, --agent-backlog, or --propose-skills, emit a Markdown review report instead of human console output");
|
|
75
|
+
console.log(" --patch With --propose-skills, emit a preview-only unified diff handoff without editing skill files");
|
|
76
|
+
console.log(" --review-check With --propose-skills, verify the review file against current proposals without changing files");
|
|
77
|
+
console.log(" --apply-plan With --propose-skills, turn accepted review decisions into a read-only manual apply plan");
|
|
78
|
+
console.log(" --review-template With --propose-skills, emit a JSON proposal review-file template without changing review decisions");
|
|
79
|
+
console.log(" --dry-run Preview --init, --import, --restore, --curate, --restore-backups --prune, or --audit --fix without changing files");
|
|
80
|
+
console.log(" --stats Summarize profile counts, recency, and audit status without changing it");
|
|
81
|
+
console.log(" --usage Summarize prompt/pack --with-learning usage sidecar events without changing files");
|
|
82
|
+
console.log(" --signals Summarize local learning, usage, eval, check-capture, agent backlog, and workspace readiness signals without changing files");
|
|
83
|
+
console.log(" --agent-backlog Emit a focused local AI/agent development backlog from the signal registry without changing files");
|
|
84
|
+
console.log(" --propose-skills Preview skill instruction deltas from repeated check-capture learning signals without changing files");
|
|
85
|
+
console.log(" --min-evidence N With --propose-skills, require N related check-capture entries before emitting a proposal. Default: 2");
|
|
86
|
+
console.log(" --review-file path With --propose-skills, read proposal review decisions without changing the review file");
|
|
87
|
+
console.log(" --eval-template Generate a runnable learning eval checkpoint from the active profile");
|
|
88
|
+
console.log(" --eval Run deterministic learning-selection checkpoint cases without changing files");
|
|
89
|
+
console.log(" --strict With --eval, --signals, --agent-backlog, or --propose-skills, exit non-zero when any checkpoint, signal, backlog, or proposal gate warns or fails");
|
|
90
|
+
console.log(" --forget id-or-number Remove one entry by id or 1-based list number; requires --yes");
|
|
91
|
+
console.log(" --clear Remove all saved learning entries; requires --yes");
|
|
92
|
+
console.log(" --yes Confirm destructive local profile changes");
|
|
93
|
+
console.log(" --file path Override the learning profile path");
|
|
94
|
+
console.log(" --usage-file path Override the learning usage sidecar path used by --usage, --curate, --signals, --agent-backlog, or --propose-skills");
|
|
95
|
+
console.log(" --json Emit machine-readable output");
|
|
96
|
+
console.log(" --out file Write JSON output to a file, export Markdown for --export, or learning review report Markdown");
|
|
97
|
+
console.log(" --force Overwrite an existing --out file, or an existing --backup-file during --restore");
|
|
98
|
+
console.log("");
|
|
99
|
+
console.log("Environment:");
|
|
100
|
+
console.log(" DESIGN_AI_LEARNING_FILE=/path/learning.json Override the default profile path");
|
|
101
|
+
console.log(" DESIGN_AI_LEARNING_USAGE_FILE=/path/usage.json Override the default usage sidecar path");
|
|
102
|
+
console.log("");
|
|
103
|
+
console.log("Examples:");
|
|
104
|
+
console.log(" design-ai learn --init");
|
|
105
|
+
console.log(" design-ai learn --init --yes --json");
|
|
106
|
+
console.log(" design-ai learn --remember \"Prefer dense Korean product UI\" --category korean");
|
|
107
|
+
console.log(" design-ai learn --feedback \"Keep audit findings short and evidence-led\" --outcome keep");
|
|
108
|
+
console.log(" design-ai learn --feedback --from-file feedback.md --outcome improve");
|
|
109
|
+
console.log(" cat feedback.md | design-ai learn --feedback --stdin --outcome avoid --category brand");
|
|
110
|
+
console.log(" design-ai learn --recall \"korean payment\" --limit 5");
|
|
111
|
+
console.log(" design-ai learn --list --category korean --limit 5");
|
|
112
|
+
console.log(" design-ai learn --list --query \"keyboard accessibility\" --explain --json");
|
|
113
|
+
console.log(" design-ai learn --export --query \"pricing page\" --limit 3");
|
|
114
|
+
console.log(" design-ai learn --backup --json --out learning-backup.json");
|
|
115
|
+
console.log(" design-ai learn --redact --json --out learning-redacted.json");
|
|
116
|
+
console.log(" design-ai learn --redact --from-file learning-backup.json --json --out learning-redacted.json --force");
|
|
117
|
+
console.log(" design-ai learn --verify --from-file learning-backup.json");
|
|
118
|
+
console.log(" design-ai learn --diff --from-file learning-backup.json --json");
|
|
119
|
+
console.log(" design-ai learn --restore --from-file learning-backup.json --dry-run");
|
|
120
|
+
console.log(" design-ai learn --restore --from-file learning-backup.json --yes --backup-file learning-before-restore.json");
|
|
121
|
+
console.log(" design-ai learn --restore-backups --json");
|
|
122
|
+
console.log(" design-ai learn --restore-backups --prune --keep 5");
|
|
123
|
+
console.log(" design-ai learn --restore-backups --prune --keep 5 --yes");
|
|
124
|
+
console.log(" design-ai learn --import --from-file learning.json --dry-run");
|
|
125
|
+
console.log(" design-ai learn --audit");
|
|
126
|
+
console.log(" design-ai learn --audit --fix --dry-run");
|
|
127
|
+
console.log(" design-ai learn --curate");
|
|
128
|
+
console.log(" design-ai learn --curate --usage-file ./learning.usage.json");
|
|
129
|
+
console.log(" design-ai learn --curate --report --out learning-curation-report.md");
|
|
130
|
+
console.log(" design-ai learn --curate --yes --json");
|
|
131
|
+
console.log(" design-ai learn --stats --json");
|
|
132
|
+
console.log(" design-ai learn --usage --json");
|
|
133
|
+
console.log(" design-ai learn --signals --from-file . --json");
|
|
134
|
+
console.log(" design-ai learn --signals --from-file . --report --out learning-signals.md");
|
|
135
|
+
console.log(" design-ai learn --agent-backlog --from-file . --report --out agent-backlog.md");
|
|
136
|
+
console.log(" design-ai learn --propose-skills --from-file . --min-evidence 3 --json");
|
|
137
|
+
console.log(" design-ai learn --propose-skills --from-file . --strict --json");
|
|
138
|
+
console.log(" design-ai learn --propose-skills --from-file . --review-file skill-proposals.review.json --strict --json");
|
|
139
|
+
console.log(" design-ai learn --propose-skills --from-file . --review-file skill-proposals.review.json --review-check --json");
|
|
140
|
+
console.log(" design-ai learn --propose-skills --from-file . --review-file skill-proposals.review.json --apply-plan --json");
|
|
141
|
+
console.log(" design-ai learn --propose-skills --from-file . --review-template --out skill-proposals.review.json");
|
|
142
|
+
console.log(" design-ai learn --propose-skills --from-file . --report --out skill-proposals.md");
|
|
143
|
+
console.log(" design-ai learn --propose-skills --from-file . --patch --out skill-proposals.patch");
|
|
144
|
+
console.log(" design-ai learn --eval-template --query \"keyboard accessibility\" --out learning-eval.json");
|
|
145
|
+
console.log(" design-ai learn --eval --from-file learning-eval.json --strict --json");
|
|
146
|
+
console.log(" design-ai learn --forget learn-abc123def0 --yes");
|
|
147
|
+
console.log(" design-ai prompt \"audit checkout UX\" --with-learning");
|
|
148
|
+
console.log(" design-ai pack \"spec a pricing page\" --with-learning");
|
|
149
|
+
}
|