@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
package/cli/commands/learn.mjs
CHANGED
|
@@ -1,20 +1,18 @@
|
|
|
1
|
-
// `design-ai learn`
|
|
1
|
+
// `design-ai learn` command dispatch.
|
|
2
2
|
|
|
3
3
|
import path from "node:path";
|
|
4
4
|
|
|
5
5
|
import { resolveBriefInput } from "../lib/brief.mjs";
|
|
6
6
|
import {
|
|
7
|
-
LEARNING_CATEGORIES,
|
|
8
|
-
LEARNING_FEEDBACK_OUTCOMES,
|
|
9
|
-
auditLearningProfile,
|
|
10
7
|
applyLearningAuditFixes,
|
|
11
8
|
applyLearningCurationPlan,
|
|
12
|
-
|
|
9
|
+
auditLearningProfile,
|
|
13
10
|
buildLearningBackup,
|
|
14
11
|
buildLearningContext,
|
|
15
|
-
|
|
12
|
+
buildLearningEvalTemplate,
|
|
16
13
|
buildRedactedLearningBackup,
|
|
17
14
|
clearLearning,
|
|
15
|
+
diffLearningProfiles,
|
|
18
16
|
forgetLearning,
|
|
19
17
|
formatLearningJson,
|
|
20
18
|
importLearningProfile,
|
|
@@ -23,17 +21,15 @@ import {
|
|
|
23
21
|
learningStats,
|
|
24
22
|
learningUsageStats,
|
|
25
23
|
listLearningRestoreBackups,
|
|
26
|
-
loadLearningProfile,
|
|
27
24
|
parseLearnArgs,
|
|
28
25
|
pruneLearningRestoreBackups,
|
|
29
26
|
recordLearningFeedback,
|
|
30
27
|
rememberLearning,
|
|
31
28
|
renderLearningCurationReport,
|
|
32
29
|
restoreLearningProfile,
|
|
33
|
-
selectLearningEntrySet,
|
|
34
30
|
verifyLearningImportPayload,
|
|
35
31
|
} from "../lib/learn.mjs";
|
|
36
|
-
import {
|
|
32
|
+
import { header, info, success } from "../lib/log.mjs";
|
|
37
33
|
import { writeOutputFile } from "../lib/output.mjs";
|
|
38
34
|
import {
|
|
39
35
|
agentBacklogReport,
|
|
@@ -45,1281 +41,46 @@ import {
|
|
|
45
41
|
buildSkillEvolutionProposals,
|
|
46
42
|
buildSkillProposalApplyPlan,
|
|
47
43
|
buildSkillProposalReviewCheck,
|
|
48
|
-
renderSkillProposalApplyPlanReport,
|
|
49
|
-
renderSkillProposalReviewTemplate,
|
|
50
|
-
renderSkillProposalReviewCheckReport,
|
|
51
44
|
renderSkillEvolutionProposalPatch,
|
|
52
45
|
renderSkillEvolutionProposalReport,
|
|
46
|
+
renderSkillProposalApplyPlanReport,
|
|
47
|
+
renderSkillProposalReviewCheckReport,
|
|
48
|
+
renderSkillProposalReviewTemplate,
|
|
53
49
|
} from "../lib/skill-proposals.mjs";
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
console.log(" design-ai learn --eval-template [--query text] [--category kind] [--limit N] [--json] [--out file] [--force]");
|
|
89
|
-
console.log(" design-ai learn --eval --from-file eval.json [--category kind] [--limit N] [--strict] [--json] [--out file] [--force]");
|
|
90
|
-
console.log(" cat eval.json | design-ai learn --eval --stdin [--category kind] [--limit N] [--strict] [--json]");
|
|
91
|
-
console.log(" design-ai learn --forget id-or-number --yes [--json] [--out file] [--force]");
|
|
92
|
-
console.log(" design-ai learn --clear --yes [--json] [--out file] [--force]\n");
|
|
93
|
-
console.log("Stores local design preferences for explicit prompt personalization.");
|
|
94
|
-
console.log("This is local memory, not model training or fine-tuning.\n");
|
|
95
|
-
console.log("Options:");
|
|
96
|
-
console.log(" --init Preview or apply starter local learning entries for dogfood use");
|
|
97
|
-
console.log(" --remember text Remember an inline preference or project constraint");
|
|
98
|
-
console.log(" --feedback text Convert outcome feedback into a reusable local learning note");
|
|
99
|
-
console.log(` --outcome kind Feedback outcome: ${LEARNING_FEEDBACK_OUTCOMES.join(", ")}. Default: improve`);
|
|
100
|
-
console.log(" --from-file file Read remember/feedback text or import/verify/diff/restore/redact JSON from a file");
|
|
101
|
-
console.log(" --stdin Read remember/feedback text or import/verify/diff/restore/redact JSON from standard input");
|
|
102
|
-
console.log(" --category kind preference, brand, workflow, constraint, accessibility, korean, other");
|
|
103
|
-
console.log(" --query text Filter list/export output to entries whose category or text matches the query");
|
|
104
|
-
console.log(" --explain With --list, include selection score, matched tokens, and reason");
|
|
105
|
-
console.log(" --limit N Limit list/export output to the N most recent matching entries, 1-100");
|
|
106
|
-
console.log(" --list List saved learning entries. Default when no action is given");
|
|
107
|
-
console.log(" --export Print the learned-context block used by --with-learning");
|
|
108
|
-
console.log(" --backup Print a full portable learning-profile backup; use --json for importable JSON");
|
|
109
|
-
console.log(" --redact Print a portable JSON backup with sensitive-looking text redacted");
|
|
110
|
-
console.log(" --verify Validate a portable learning JSON payload without importing it");
|
|
111
|
-
console.log(" --diff Compare the active profile against a portable learning JSON payload without importing it");
|
|
112
|
-
console.log(" --restore Preview or apply replacing the active profile with a portable learning JSON payload");
|
|
113
|
-
console.log(" --restore-backups List sibling restore rollback backups for the active learning profile");
|
|
114
|
-
console.log(" --prune With --restore-backups, preview or delete older rollback backup files");
|
|
115
|
-
console.log(" --keep N With --restore-backups --prune, keep the N newest backups. Default: 5");
|
|
116
|
-
console.log(" --backup-file path With --restore, override the automatic rollback backup file path");
|
|
117
|
-
console.log(" --import Merge entries from a JSON learning profile or learn --export --json payload");
|
|
118
|
-
console.log(" --audit Inspect profile shape, sensitive content, and cleanup suggestions without changing it");
|
|
119
|
-
console.log(" --fix With --audit, prepare or apply safe cleanup suggestions");
|
|
120
|
-
console.log(" --curate Preview or apply archive-first curation for duplicate/sensitive entries, plus usage review hints");
|
|
121
|
-
console.log(" --report With --curate, --signals, --agent-backlog, or --propose-skills, emit a Markdown review report instead of human console output");
|
|
122
|
-
console.log(" --patch With --propose-skills, emit a preview-only unified diff handoff without editing skill files");
|
|
123
|
-
console.log(" --review-check With --propose-skills, verify the review file against current proposals without changing files");
|
|
124
|
-
console.log(" --apply-plan With --propose-skills, turn accepted review decisions into a read-only manual apply plan");
|
|
125
|
-
console.log(" --review-template With --propose-skills, emit a JSON proposal review-file template without changing review decisions");
|
|
126
|
-
console.log(" --dry-run Preview --init, --import, --restore, --curate, --restore-backups --prune, or --audit --fix without changing files");
|
|
127
|
-
console.log(" --stats Summarize profile counts, recency, and audit status without changing it");
|
|
128
|
-
console.log(" --usage Summarize prompt/pack --with-learning usage sidecar events without changing files");
|
|
129
|
-
console.log(" --signals Summarize local learning, usage, eval, check-capture, agent backlog, and workspace readiness signals without changing files");
|
|
130
|
-
console.log(" --agent-backlog Emit a focused local AI/agent development backlog from the signal registry without changing files");
|
|
131
|
-
console.log(" --propose-skills Preview skill instruction deltas from repeated check-capture learning signals without changing files");
|
|
132
|
-
console.log(" --min-evidence N With --propose-skills, require N related check-capture entries before emitting a proposal. Default: 2");
|
|
133
|
-
console.log(" --review-file path With --propose-skills, read proposal review decisions without changing the review file");
|
|
134
|
-
console.log(" --eval-template Generate a runnable learning eval checkpoint from the active profile");
|
|
135
|
-
console.log(" --eval Run deterministic learning-selection checkpoint cases without changing files");
|
|
136
|
-
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");
|
|
137
|
-
console.log(" --forget id-or-number Remove one entry by id or 1-based list number; requires --yes");
|
|
138
|
-
console.log(" --clear Remove all saved learning entries; requires --yes");
|
|
139
|
-
console.log(" --yes Confirm destructive local profile changes");
|
|
140
|
-
console.log(" --file path Override the learning profile path");
|
|
141
|
-
console.log(" --usage-file path Override the learning usage sidecar path used by --usage, --curate, --signals, --agent-backlog, or --propose-skills");
|
|
142
|
-
console.log(" --json Emit machine-readable output");
|
|
143
|
-
console.log(" --out file Write JSON output to a file, export Markdown for --export, or learning review report Markdown");
|
|
144
|
-
console.log(" --force Overwrite an existing --out file, or an existing --backup-file during --restore");
|
|
145
|
-
console.log("");
|
|
146
|
-
console.log("Environment:");
|
|
147
|
-
console.log(" DESIGN_AI_LEARNING_FILE=/path/learning.json Override the default profile path");
|
|
148
|
-
console.log(" DESIGN_AI_LEARNING_USAGE_FILE=/path/usage.json Override the default usage sidecar path");
|
|
149
|
-
console.log("");
|
|
150
|
-
console.log("Examples:");
|
|
151
|
-
console.log(" design-ai learn --init");
|
|
152
|
-
console.log(" design-ai learn --init --yes --json");
|
|
153
|
-
console.log(" design-ai learn --remember \"Prefer dense Korean product UI\" --category korean");
|
|
154
|
-
console.log(" design-ai learn --feedback \"Keep audit findings short and evidence-led\" --outcome keep");
|
|
155
|
-
console.log(" design-ai learn --feedback --from-file feedback.md --outcome improve");
|
|
156
|
-
console.log(" cat feedback.md | design-ai learn --feedback --stdin --outcome avoid --category brand");
|
|
157
|
-
console.log(" design-ai learn --list --category korean --limit 5");
|
|
158
|
-
console.log(" design-ai learn --list --query \"keyboard accessibility\" --explain --json");
|
|
159
|
-
console.log(" design-ai learn --export --query \"pricing page\" --limit 3");
|
|
160
|
-
console.log(" design-ai learn --backup --json --out learning-backup.json");
|
|
161
|
-
console.log(" design-ai learn --redact --json --out learning-redacted.json");
|
|
162
|
-
console.log(" design-ai learn --redact --from-file learning-backup.json --json --out learning-redacted.json --force");
|
|
163
|
-
console.log(" design-ai learn --verify --from-file learning-backup.json");
|
|
164
|
-
console.log(" design-ai learn --diff --from-file learning-backup.json --json");
|
|
165
|
-
console.log(" design-ai learn --restore --from-file learning-backup.json --dry-run");
|
|
166
|
-
console.log(" design-ai learn --restore --from-file learning-backup.json --yes --backup-file learning-before-restore.json");
|
|
167
|
-
console.log(" design-ai learn --restore-backups --json");
|
|
168
|
-
console.log(" design-ai learn --restore-backups --prune --keep 5");
|
|
169
|
-
console.log(" design-ai learn --restore-backups --prune --keep 5 --yes");
|
|
170
|
-
console.log(" design-ai learn --import --from-file learning.json --dry-run");
|
|
171
|
-
console.log(" design-ai learn --audit");
|
|
172
|
-
console.log(" design-ai learn --audit --fix --dry-run");
|
|
173
|
-
console.log(" design-ai learn --curate");
|
|
174
|
-
console.log(" design-ai learn --curate --usage-file ./learning.usage.json");
|
|
175
|
-
console.log(" design-ai learn --curate --report --out learning-curation-report.md");
|
|
176
|
-
console.log(" design-ai learn --curate --yes --json");
|
|
177
|
-
console.log(" design-ai learn --stats --json");
|
|
178
|
-
console.log(" design-ai learn --usage --json");
|
|
179
|
-
console.log(" design-ai learn --signals --from-file . --json");
|
|
180
|
-
console.log(" design-ai learn --signals --from-file . --report --out learning-signals.md");
|
|
181
|
-
console.log(" design-ai learn --agent-backlog --from-file . --report --out agent-backlog.md");
|
|
182
|
-
console.log(" design-ai learn --propose-skills --from-file . --min-evidence 3 --json");
|
|
183
|
-
console.log(" design-ai learn --propose-skills --from-file . --strict --json");
|
|
184
|
-
console.log(" design-ai learn --propose-skills --from-file . --review-file skill-proposals.review.json --strict --json");
|
|
185
|
-
console.log(" design-ai learn --propose-skills --from-file . --review-file skill-proposals.review.json --review-check --json");
|
|
186
|
-
console.log(" design-ai learn --propose-skills --from-file . --review-file skill-proposals.review.json --apply-plan --json");
|
|
187
|
-
console.log(" design-ai learn --propose-skills --from-file . --review-template --out skill-proposals.review.json");
|
|
188
|
-
console.log(" design-ai learn --propose-skills --from-file . --report --out skill-proposals.md");
|
|
189
|
-
console.log(" design-ai learn --propose-skills --from-file . --patch --out skill-proposals.patch");
|
|
190
|
-
console.log(" design-ai learn --eval-template --query \"keyboard accessibility\" --out learning-eval.json");
|
|
191
|
-
console.log(" design-ai learn --eval --from-file learning-eval.json --strict --json");
|
|
192
|
-
console.log(" design-ai learn --forget learn-abc123def0 --yes");
|
|
193
|
-
console.log(" design-ai prompt \"audit checkout UX\" --with-learning");
|
|
194
|
-
console.log(" design-ai pack \"spec a pricing page\" --with-learning");
|
|
195
|
-
}
|
|
196
|
-
|
|
197
|
-
function printLearningImportVerification(payload) {
|
|
198
|
-
header("design-ai learn", "Learning import verification");
|
|
199
|
-
info(`Source: ${payload.source}`);
|
|
200
|
-
info(`Importable: ${payload.importable ? "yes" : "no"}`);
|
|
201
|
-
info(`Entries: ${payload.count}`);
|
|
202
|
-
info(`Audit: ${payload.auditSummary.status} (${payload.auditSummary.failures} failure(s), ${payload.auditSummary.warnings} warning(s))`);
|
|
203
|
-
console.log();
|
|
204
|
-
|
|
205
|
-
if (payload.issues.length === 0) {
|
|
206
|
-
console.log("No learning import issues found. No changes made.");
|
|
207
|
-
return;
|
|
208
|
-
}
|
|
209
|
-
|
|
210
|
-
for (const issue of payload.issues) {
|
|
211
|
-
const entry = issue.entryId ? ` (${issue.entryId})` : "";
|
|
212
|
-
console.log(`${issue.level.toUpperCase()} ${issue.code}${entry}: ${issue.message}`);
|
|
213
|
-
}
|
|
214
|
-
console.log();
|
|
215
|
-
console.log("No changes made. Review warnings before importing or using learned context.");
|
|
216
|
-
}
|
|
217
|
-
|
|
218
|
-
function learningFilter(parsed) {
|
|
219
|
-
return {
|
|
220
|
-
category: parsed.categorySpecified ? parsed.category : "",
|
|
221
|
-
limit: parsed.limit,
|
|
222
|
-
query: parsed.query,
|
|
223
|
-
};
|
|
224
|
-
}
|
|
225
|
-
|
|
226
|
-
function listPayload(filePath, parsed) {
|
|
227
|
-
const profile = loadLearningProfile(filePath);
|
|
228
|
-
const filter = learningFilter(parsed);
|
|
229
|
-
const { entries, selection } = selectLearningEntrySet(profile, {
|
|
230
|
-
...filter,
|
|
231
|
-
includeFallback: false,
|
|
232
|
-
});
|
|
233
|
-
const payload = {
|
|
234
|
-
file: filePath,
|
|
235
|
-
version: profile.version,
|
|
236
|
-
updatedAt: profile.updatedAt,
|
|
237
|
-
category: filter.category,
|
|
238
|
-
query: filter.query,
|
|
239
|
-
limit: filter.limit || null,
|
|
240
|
-
entries,
|
|
241
|
-
count: entries.length,
|
|
242
|
-
totalCount: profile.entries.length,
|
|
243
|
-
};
|
|
244
|
-
if (parsed.explain) {
|
|
245
|
-
payload.selection = selection;
|
|
246
|
-
}
|
|
247
|
-
return payload;
|
|
248
|
-
}
|
|
249
|
-
|
|
250
|
-
function printList(payload) {
|
|
251
|
-
header("design-ai learn", "Local learning profile");
|
|
252
|
-
info(`File: ${payload.file}`);
|
|
253
|
-
info(`Entries: ${payload.count}/${payload.totalCount}`);
|
|
254
|
-
if (payload.category) info(`Category: ${payload.category}`);
|
|
255
|
-
if (payload.query) info(`Query: ${payload.query}`);
|
|
256
|
-
if (payload.limit) info(`Limit: ${payload.limit}`);
|
|
257
|
-
if (payload.selection) {
|
|
258
|
-
info("Explain: selection score, matched tokens, and reason");
|
|
259
|
-
}
|
|
260
|
-
console.log();
|
|
261
|
-
|
|
262
|
-
if (payload.entries.length === 0) {
|
|
263
|
-
console.log(payload.category || payload.query || payload.limit
|
|
264
|
-
? "No local learning preferences match the current filters."
|
|
265
|
-
: "No local learning preferences are stored yet.");
|
|
266
|
-
return;
|
|
267
|
-
}
|
|
268
|
-
|
|
269
|
-
for (let i = 0; i < payload.entries.length; i += 1) {
|
|
270
|
-
const entry = payload.entries[i];
|
|
271
|
-
const selected = payload.selection?.selected?.[i];
|
|
272
|
-
console.log(`${i + 1}. [${entry.category}] ${entry.text}`);
|
|
273
|
-
console.log(` ${dim(`${entry.id} · ${entry.createdAt || "unknown time"}`)}`);
|
|
274
|
-
if (selected) {
|
|
275
|
-
const matched = selected.matchedTokens.length > 0
|
|
276
|
-
? selected.matchedTokens.join(", ")
|
|
277
|
-
: "none";
|
|
278
|
-
console.log(` ${dim(`score ${selected.score} · matched ${matched} · reason ${selected.reason}`)}`);
|
|
279
|
-
}
|
|
280
|
-
}
|
|
281
|
-
}
|
|
282
|
-
|
|
283
|
-
function formatCategoryCounts(categoryCounts) {
|
|
284
|
-
return LEARNING_CATEGORIES
|
|
285
|
-
.filter((category) => categoryCounts[category])
|
|
286
|
-
.map((category) => `${category} ${categoryCounts[category]}`)
|
|
287
|
-
.join(", ");
|
|
288
|
-
}
|
|
289
|
-
|
|
290
|
-
function formatCounts(counts) {
|
|
291
|
-
return Object.entries(counts || {})
|
|
292
|
-
.sort((a, b) => b[1] - a[1] || a[0].localeCompare(b[0]))
|
|
293
|
-
.map(([key, count]) => `${key} ${count}`)
|
|
294
|
-
.join(", ");
|
|
295
|
-
}
|
|
296
|
-
|
|
297
|
-
function printAudit(payload) {
|
|
298
|
-
header("design-ai learn", "Local learning profile audit");
|
|
299
|
-
info(`File: ${payload.file}`);
|
|
300
|
-
info(`Exists: ${payload.exists ? "yes" : "no"}`);
|
|
301
|
-
info(`Entries: ${payload.count}`);
|
|
302
|
-
info(`Status: ${payload.summary.status}`);
|
|
303
|
-
info(`Issues: ${payload.summary.failures} failure(s), ${payload.summary.warnings} warning(s)`);
|
|
304
|
-
|
|
305
|
-
const categories = formatCategoryCounts(payload.categoryCounts);
|
|
306
|
-
if (categories) info(`Categories: ${categories}`);
|
|
307
|
-
console.log();
|
|
308
|
-
|
|
309
|
-
if (!payload.exists) {
|
|
310
|
-
console.log("No local learning profile file exists yet.");
|
|
311
|
-
return;
|
|
312
|
-
}
|
|
313
|
-
|
|
314
|
-
if (payload.issues.length === 0) {
|
|
315
|
-
console.log("No learning profile issues found.");
|
|
316
|
-
return;
|
|
317
|
-
}
|
|
318
|
-
|
|
319
|
-
for (const issue of payload.issues) {
|
|
320
|
-
const entry = issue.entryId ? ` (${issue.entryId})` : "";
|
|
321
|
-
console.log(`${issue.level.toUpperCase()} ${issue.code}${entry}: ${issue.message}`);
|
|
322
|
-
}
|
|
323
|
-
|
|
324
|
-
if (payload.suggestions.length > 0) {
|
|
325
|
-
console.log();
|
|
326
|
-
console.log("Suggested cleanup:");
|
|
327
|
-
for (const suggestion of payload.suggestions) {
|
|
328
|
-
const entry = suggestion.entryId ? ` (${suggestion.entryId})` : "";
|
|
329
|
-
console.log(`- ${suggestion.action}${entry}: ${suggestion.message}`);
|
|
330
|
-
if (suggestion.command) {
|
|
331
|
-
console.log(` ${dim(suggestion.command)}`);
|
|
332
|
-
}
|
|
333
|
-
}
|
|
334
|
-
}
|
|
335
|
-
}
|
|
336
|
-
|
|
337
|
-
function printAuditFix(payload) {
|
|
338
|
-
header("design-ai learn", payload.dryRun ? "Learning audit cleanup dry run" : "Learning audit cleanup applied");
|
|
339
|
-
info(`File: ${payload.file}`);
|
|
340
|
-
info(`Before: ${payload.before.status} (${payload.before.failures} failure(s), ${payload.before.warnings} warning(s))`);
|
|
341
|
-
info(`Cleanup entries: ${payload.cleanupCount}`);
|
|
342
|
-
if (payload.after) {
|
|
343
|
-
info(`After: ${payload.after.status} (${payload.after.failures} failure(s), ${payload.after.warnings} warning(s))`);
|
|
344
|
-
}
|
|
345
|
-
console.log();
|
|
346
|
-
|
|
347
|
-
if (payload.cleanup.length === 0) {
|
|
348
|
-
console.log("No safe cleanup suggestions are available.");
|
|
349
|
-
} else {
|
|
350
|
-
console.log(payload.dryRun ? "Would remove:" : "Removed:");
|
|
351
|
-
for (const fix of payload.cleanup) {
|
|
352
|
-
console.log(`- ${fix.entryId}: ${fix.actions.join(", ")} (${fix.issueCodes.join(", ")})`);
|
|
353
|
-
if (fix.command) {
|
|
354
|
-
console.log(` ${dim(fix.command)}`);
|
|
355
|
-
}
|
|
356
|
-
}
|
|
357
|
-
}
|
|
358
|
-
|
|
359
|
-
if (payload.skipped.length > 0) {
|
|
360
|
-
console.log();
|
|
361
|
-
console.log("Skipped:");
|
|
362
|
-
for (const skipped of payload.skipped) {
|
|
363
|
-
const entry = skipped.entryId ? ` (${skipped.entryId})` : "";
|
|
364
|
-
console.log(`- ${skipped.reason}${entry}: ${skipped.message}`);
|
|
365
|
-
}
|
|
366
|
-
}
|
|
367
|
-
|
|
368
|
-
if (payload.dryRun) {
|
|
369
|
-
console.log();
|
|
370
|
-
console.log("No changes made. Re-run with `--yes` instead of `--dry-run` to apply safe cleanup.");
|
|
371
|
-
}
|
|
372
|
-
}
|
|
373
|
-
|
|
374
|
-
function printCuration(payload) {
|
|
375
|
-
header("design-ai learn", payload.dryRun ? "Learning curation preview" : "Learning curation applied");
|
|
376
|
-
info(`File: ${payload.file}`);
|
|
377
|
-
info(`Archive: ${payload.archiveFile}`);
|
|
378
|
-
info(`Before: ${payload.before.status} (${payload.before.failures} failure(s), ${payload.before.warnings} warning(s))`);
|
|
379
|
-
info(`Proposals: ${payload.proposalCount}`);
|
|
380
|
-
info(`Archive candidates: ${payload.archiveCount}`);
|
|
381
|
-
info(`Manual review: ${payload.manualReviewCount}`);
|
|
382
|
-
if (payload.after) {
|
|
383
|
-
info(`After: ${payload.after.status} (${payload.after.failures} failure(s), ${payload.after.warnings} warning(s))`);
|
|
384
|
-
}
|
|
385
|
-
console.log();
|
|
386
|
-
|
|
387
|
-
if (payload.proposals.length === 0) {
|
|
388
|
-
console.log("No learning curation candidates found.");
|
|
389
|
-
} else {
|
|
390
|
-
const archiveCandidates = payload.proposals.filter((proposal) => proposal.action === "archive");
|
|
391
|
-
const manualCandidates = payload.proposals.filter((proposal) => proposal.action === "manual-review");
|
|
392
|
-
if (archiveCandidates.length > 0) {
|
|
393
|
-
console.log(payload.dryRun ? "Would archive:" : "Archived:");
|
|
394
|
-
for (const proposal of archiveCandidates) {
|
|
395
|
-
console.log(`- ${proposal.entryId}: ${proposal.reason} (${proposal.issueCodes.join(", ")})`);
|
|
396
|
-
if (proposal.textPreview) console.log(` ${dim(proposal.textPreview)}`);
|
|
397
|
-
}
|
|
398
|
-
console.log();
|
|
399
|
-
}
|
|
400
|
-
if (manualCandidates.length > 0) {
|
|
401
|
-
console.log("Needs manual review:");
|
|
402
|
-
for (const proposal of manualCandidates) {
|
|
403
|
-
const label = proposal.entryId || "profile";
|
|
404
|
-
console.log(`- ${label}: ${proposal.reason} (${proposal.issueCodes.join(", ")})`);
|
|
405
|
-
if (proposal.textPreview) console.log(` ${dim(proposal.textPreview)}`);
|
|
406
|
-
}
|
|
407
|
-
console.log();
|
|
408
|
-
}
|
|
409
|
-
}
|
|
410
|
-
|
|
411
|
-
if (payload.skipped.length > 0) {
|
|
412
|
-
console.log("Skipped:");
|
|
413
|
-
for (const skipped of payload.skipped) {
|
|
414
|
-
const entry = skipped.entryId ? `${skipped.entryId}: ` : "";
|
|
415
|
-
console.log(`- ${entry}${skipped.reason}`);
|
|
416
|
-
}
|
|
417
|
-
console.log();
|
|
418
|
-
}
|
|
419
|
-
|
|
420
|
-
if (payload.usage?.exists || payload.usage?.error) {
|
|
421
|
-
console.log("Usage review:");
|
|
422
|
-
console.log(`- sidecar: ${payload.usage.usageFile}`);
|
|
423
|
-
console.log(`- events: ${payload.usage.eventCount}`);
|
|
424
|
-
console.log(`- review items: ${payload.usage.reviewCount}`);
|
|
425
|
-
if (payload.usage.error) {
|
|
426
|
-
console.log(`- error: ${payload.usage.error}`);
|
|
427
|
-
} else if (payload.usage.reviews.length === 0) {
|
|
428
|
-
console.log("- no usage-based curation review items found");
|
|
429
|
-
} else {
|
|
430
|
-
for (const review of payload.usage.reviews) {
|
|
431
|
-
const label = review.entryId || "usage";
|
|
432
|
-
console.log(`- ${label}: ${review.reason} (${review.action})`);
|
|
433
|
-
if (review.textPreview) console.log(` ${dim(review.textPreview)}`);
|
|
434
|
-
}
|
|
435
|
-
}
|
|
436
|
-
console.log(dim("Usage review is advisory; --curate only archives duplicate/sensitive audit candidates."));
|
|
437
|
-
console.log();
|
|
438
|
-
}
|
|
439
|
-
|
|
440
|
-
if (payload.dryRun) {
|
|
441
|
-
console.log("No changes made. Re-run with `--yes` to move archive candidates into the learning archive.");
|
|
442
|
-
}
|
|
443
|
-
}
|
|
444
|
-
|
|
445
|
-
function printStats(payload) {
|
|
446
|
-
header("design-ai learn", "Local learning profile stats");
|
|
447
|
-
info(`File: ${payload.file}`);
|
|
448
|
-
info(`Exists: ${payload.exists ? "yes" : "no"}`);
|
|
449
|
-
info(`Entries: ${payload.count}`);
|
|
450
|
-
info(`Updated: ${payload.updatedAt || "unknown"}`);
|
|
451
|
-
info(`Audit: ${payload.auditSummary.status} (${payload.auditSummary.failures} failure(s), ${payload.auditSummary.warnings} warning(s))`);
|
|
452
|
-
|
|
453
|
-
const categories = formatCategoryCounts(payload.categoryCounts);
|
|
454
|
-
if (categories) info(`Categories: ${categories}`);
|
|
455
|
-
|
|
456
|
-
const sources = Object.entries(payload.sourceCounts)
|
|
457
|
-
.map(([source, count]) => `${source} ${count}`)
|
|
458
|
-
.join(", ");
|
|
459
|
-
if (sources) info(`Sources: ${sources}`);
|
|
460
|
-
console.log();
|
|
461
|
-
|
|
462
|
-
if (!payload.exists) {
|
|
463
|
-
console.log("No local learning profile file exists yet.");
|
|
464
|
-
return;
|
|
465
|
-
}
|
|
466
|
-
|
|
467
|
-
if (payload.auditSummary.failures > 0) {
|
|
468
|
-
console.log("Profile stats are limited because the profile has audit failures. Run `design-ai learn --audit` for details.");
|
|
469
|
-
return;
|
|
470
|
-
}
|
|
471
|
-
|
|
472
|
-
if (payload.count === 0) {
|
|
473
|
-
console.log("No local learning preferences are stored yet.");
|
|
474
|
-
return;
|
|
475
|
-
}
|
|
476
|
-
|
|
477
|
-
if (!payload.latestEntry) {
|
|
478
|
-
console.log("No parseable learning entry timestamps found. Run `design-ai learn --audit` for details.");
|
|
479
|
-
return;
|
|
480
|
-
}
|
|
481
|
-
|
|
482
|
-
if (payload.latestEntry) {
|
|
483
|
-
console.log(`Latest: [${payload.latestEntry.category}] ${payload.latestEntry.textPreview}`);
|
|
484
|
-
console.log(` ${dim(`${payload.latestEntry.id} · ${payload.latestEntry.createdAt}`)}`);
|
|
485
|
-
}
|
|
486
|
-
if (payload.oldestEntry && payload.oldestEntry.id !== payload.latestEntry?.id) {
|
|
487
|
-
console.log(`Oldest: [${payload.oldestEntry.category}] ${payload.oldestEntry.textPreview}`);
|
|
488
|
-
console.log(` ${dim(`${payload.oldestEntry.id} · ${payload.oldestEntry.createdAt}`)}`);
|
|
489
|
-
}
|
|
490
|
-
}
|
|
491
|
-
|
|
492
|
-
function printUsage(payload) {
|
|
493
|
-
header("design-ai learn", "Local learning usage report");
|
|
494
|
-
info(`File: ${payload.file}`);
|
|
495
|
-
info(`Usage sidecar: ${payload.usageFile}`);
|
|
496
|
-
info(`Usage exists: ${payload.exists ? "yes" : "no"}`);
|
|
497
|
-
info(`Events: ${payload.eventCount}`);
|
|
498
|
-
info(`Profile entries: ${payload.profileEntryCount}`);
|
|
499
|
-
info(`Used entries: ${payload.usedEntryCount}`);
|
|
500
|
-
info(`Unused entries: ${payload.unusedEntryCount}`);
|
|
501
|
-
info(`Stale selected ids: ${payload.staleSelectedEntryCount}`);
|
|
502
|
-
info(`Updated: ${payload.updatedAt || "unknown"}`);
|
|
503
|
-
|
|
504
|
-
const commands = formatCounts(payload.commandCounts);
|
|
505
|
-
if (commands) info(`Commands: ${commands}`);
|
|
506
|
-
const routes = formatCounts(payload.routeCounts);
|
|
507
|
-
if (routes) info(`Routes: ${routes}`);
|
|
508
|
-
const categories = formatCounts(payload.categoryCounts);
|
|
509
|
-
if (categories) info(`Categories: ${categories}`);
|
|
510
|
-
console.log();
|
|
511
|
-
|
|
512
|
-
if (!payload.exists) {
|
|
513
|
-
console.log("No local learning usage sidecar exists yet.");
|
|
514
|
-
console.log("Run `design-ai prompt \"...\" --with-learning` or `design-ai pack \"...\" --with-learning` to record usage metadata.");
|
|
515
|
-
return;
|
|
516
|
-
}
|
|
517
|
-
|
|
518
|
-
if (payload.eventCount === 0) {
|
|
519
|
-
console.log("No local learning usage events are stored yet.");
|
|
520
|
-
return;
|
|
521
|
-
}
|
|
522
|
-
|
|
523
|
-
if (payload.topSelectedEntries.length > 0) {
|
|
524
|
-
console.log("Top selected entries:");
|
|
525
|
-
for (const entry of payload.topSelectedEntries) {
|
|
526
|
-
console.log(`- ${entry.id}: ${entry.usageCount} use(s) [${entry.category}] ${entry.textPreview}`);
|
|
527
|
-
if (entry.latestUsedAt) console.log(` ${dim(`latest ${entry.latestUsedAt}`)}`);
|
|
528
|
-
}
|
|
529
|
-
console.log();
|
|
530
|
-
}
|
|
531
|
-
|
|
532
|
-
if (payload.recentEvents.length > 0) {
|
|
533
|
-
console.log("Recent events:");
|
|
534
|
-
for (const event of payload.recentEvents) {
|
|
535
|
-
const route = event.routeId || "unrouted";
|
|
536
|
-
const ids = event.selectedEntryIds.length > 0 ? event.selectedEntryIds.join(", ") : "none";
|
|
537
|
-
console.log(`- ${event.createdAt}: ${event.command} / ${route} selected ${ids}`);
|
|
538
|
-
console.log(` ${dim(`briefHash ${event.briefHash || "none"} · matched ${event.matchedCount}/${event.candidateCount} · fallback ${event.fallbackCount}`)}`);
|
|
539
|
-
}
|
|
540
|
-
console.log();
|
|
541
|
-
}
|
|
542
|
-
|
|
543
|
-
if (payload.unusedEntryIds.length > 0) {
|
|
544
|
-
console.log(`Unused active entry ids: ${payload.unusedEntryIds.join(", ")}`);
|
|
545
|
-
}
|
|
546
|
-
if (payload.staleSelectedEntryIds.length > 0) {
|
|
547
|
-
console.log(`Stale selected entry ids: ${payload.staleSelectedEntryIds.join(", ")}`);
|
|
548
|
-
}
|
|
549
|
-
|
|
550
|
-
if (payload.recommendations.length > 0) {
|
|
551
|
-
console.log();
|
|
552
|
-
console.log("Recommendations:");
|
|
553
|
-
for (const recommendation of payload.recommendations) {
|
|
554
|
-
console.log(`- ${recommendation.level}: ${recommendation.text}`);
|
|
555
|
-
}
|
|
556
|
-
}
|
|
557
|
-
|
|
558
|
-
console.log();
|
|
559
|
-
console.log("Privacy: usage events store selected entry ids and a short brief hash, not raw brief text.");
|
|
560
|
-
}
|
|
561
|
-
|
|
562
|
-
function printSignals(payload) {
|
|
563
|
-
header("design-ai learn", "Learning signal registry");
|
|
564
|
-
info(`File: ${payload.file}`);
|
|
565
|
-
info(`Status: ${payload.status}`);
|
|
566
|
-
info(`Signal source: ${payload.signalSource}`);
|
|
567
|
-
info(`Learning entries: ${payload.learning.count}`);
|
|
568
|
-
info(`Learning audit: ${payload.learning.auditSummary.status} (${payload.learning.auditSummary.failures} failure(s), ${payload.learning.auditSummary.warnings} warning(s))`);
|
|
569
|
-
info(`Usage events: ${payload.usage.eventCount}`);
|
|
570
|
-
info(`Eval signals: ${payload.evals.count} (${payload.evals.reports} report(s), ${payload.evals.templates} template(s))`);
|
|
571
|
-
info(`Check capture entries: ${payload.checkCapture.count}`);
|
|
572
|
-
info(`Workspace next actions: ${payload.workspace.nextActionCount}`);
|
|
573
|
-
console.log();
|
|
574
|
-
|
|
575
|
-
if (payload.evals.files.length > 0) {
|
|
576
|
-
console.log("Eval signals:");
|
|
577
|
-
for (const item of payload.evals.files) {
|
|
578
|
-
const label = path.basename(item.file);
|
|
579
|
-
const counts = item.shape === "report"
|
|
580
|
-
? ` · pass ${item.passed} / warn ${item.warned} / fail ${item.failed}`
|
|
581
|
-
: "";
|
|
582
|
-
console.log(`- ${label}: ${item.kind} ${item.shape} ${item.status} (${item.caseCount} case(s))${counts}`);
|
|
583
|
-
if (item.error) console.log(` ${dim(item.error)}`);
|
|
584
|
-
}
|
|
585
|
-
console.log();
|
|
586
|
-
}
|
|
587
|
-
|
|
588
|
-
if (payload.checkCapture.latestEntries.length > 0) {
|
|
589
|
-
console.log("Recent check captures:");
|
|
590
|
-
for (const entry of payload.checkCapture.latestEntries) {
|
|
591
|
-
console.log(`- ${entry.id}: [${entry.category}] ${entry.source}`);
|
|
592
|
-
if (entry.textPreview) console.log(` ${dim(entry.textPreview)}`);
|
|
593
|
-
}
|
|
594
|
-
console.log();
|
|
595
|
-
}
|
|
596
|
-
|
|
597
|
-
console.log("Workspace readiness:");
|
|
598
|
-
console.log(`- branch: ${payload.workspace.git.branch || "unknown"} (${payload.workspace.git.clean ? "clean" : "dirty"})`);
|
|
599
|
-
console.log(`- repository: ${payload.workspace.repository.status || "unknown"}`);
|
|
600
|
-
console.log(`- learning usage: ${payload.workspace.learningUsage?.status || "not checked"}`);
|
|
601
|
-
console.log(`- learning eval: ${payload.workspace.learningEval?.status || "not checked"}`);
|
|
602
|
-
console.log();
|
|
603
|
-
|
|
604
|
-
if (payload.agentDevelopment?.actions?.length > 0) {
|
|
605
|
-
console.log("Agent development backlog:");
|
|
606
|
-
for (const action of payload.agentDevelopment.actions.slice(0, 6)) {
|
|
607
|
-
console.log(`- ${action.rank}. ${action.priority} ${action.category}: ${action.title}`);
|
|
608
|
-
if (action.command) console.log(` ${dim(action.command)}`);
|
|
609
|
-
}
|
|
610
|
-
console.log();
|
|
611
|
-
}
|
|
612
|
-
|
|
613
|
-
if (payload.recommendations.length > 0) {
|
|
614
|
-
console.log("Recommendations:");
|
|
615
|
-
for (const recommendation of payload.recommendations) {
|
|
616
|
-
console.log(`- ${recommendation.level}: ${recommendation.text}`);
|
|
617
|
-
}
|
|
618
|
-
console.log();
|
|
619
|
-
}
|
|
620
|
-
|
|
621
|
-
console.log("Privacy: signal registry is read-only and does not mutate learning.json.");
|
|
622
|
-
}
|
|
623
|
-
|
|
624
|
-
function printAgentBacklog(payload) {
|
|
625
|
-
header("design-ai learn", "Agent development backlog");
|
|
626
|
-
info(`File: ${payload.file}`);
|
|
627
|
-
info(`Status: ${payload.status}`);
|
|
628
|
-
info(`Signal status: ${payload.signalStatus}`);
|
|
629
|
-
info(`Signal source: ${payload.signalSource}`);
|
|
630
|
-
info(`Actions: ${payload.counts.actions}`);
|
|
631
|
-
info(`Priority: P0 ${payload.counts.p0}, P1 ${payload.counts.p1}, P2 ${payload.counts.p2}, P3 ${payload.counts.p3}`);
|
|
632
|
-
info(`Learning entries: ${payload.counts.learningEntries}`);
|
|
633
|
-
info(`Usage events: ${payload.counts.usageEvents}`);
|
|
634
|
-
info(`Eval signals: ${payload.counts.evalSignals}`);
|
|
635
|
-
info(`Check captures: ${payload.counts.checkCaptures}`);
|
|
636
|
-
console.log();
|
|
637
|
-
|
|
638
|
-
if (payload.actions.length === 0) {
|
|
639
|
-
console.log("No agent development backlog actions emitted.");
|
|
640
|
-
} else {
|
|
641
|
-
console.log("Backlog actions:");
|
|
642
|
-
for (const action of payload.actions) {
|
|
643
|
-
console.log(`- ${action.rank}. ${action.priority} ${action.category}: ${action.title}`);
|
|
644
|
-
console.log(` ${dim(action.rationale)}`);
|
|
645
|
-
if (action.command) console.log(` ${dim(action.command)}`);
|
|
646
|
-
}
|
|
647
|
-
}
|
|
648
|
-
|
|
649
|
-
const planSteps = Array.isArray(payload.actionPlan?.steps) ? payload.actionPlan.steps : [];
|
|
650
|
-
if (planSteps.length > 0) {
|
|
651
|
-
console.log();
|
|
652
|
-
console.log("Action plan:");
|
|
653
|
-
const safety = payload.actionPlan?.safetySummary;
|
|
654
|
-
if (safety) {
|
|
655
|
-
console.log(` ${dim(`safety summary: ${safety.readOnly || 0} read-only, ${safety.writesLocalFile || 0} writes-local-file, ${safety.mutatesLocalState || 0} mutates-local-state`)}`);
|
|
656
|
-
}
|
|
657
|
-
const queue = payload.actionPlan?.executionQueue;
|
|
658
|
-
if (queue) {
|
|
659
|
-
console.log(` ${dim(`execution queue: ${queue.previewCount || 0} preview, ${queue.fileWriteReviewCount || 0} file-write review, ${queue.mutationReviewCount || 0} mutation review`)}`);
|
|
660
|
-
const effectSummary = queue.commandEffectSummary && typeof queue.commandEffectSummary === "object" ? queue.commandEffectSummary : null;
|
|
661
|
-
if (effectSummary) {
|
|
662
|
-
console.log(` ${dim(`command effects: ${effectSummary.outputTargetCount || 0} output, ${effectSummary.profileTargetCount || 0} profile, ${effectSummary.usageTargetCount || 0} usage, ${effectSummary.mutationFlagCount || 0} mutation flags`)}`);
|
|
663
|
-
}
|
|
664
|
-
const effectReview = queue.commandEffectReview && typeof queue.commandEffectReview === "object" ? queue.commandEffectReview : null;
|
|
665
|
-
if (effectReview?.headline) {
|
|
666
|
-
console.log(` ${dim(`command effect review: ${effectReview.headline}`)}`);
|
|
667
|
-
const gatePhaseSummary = effectReview.gatePhaseSummary && typeof effectReview.gatePhaseSummary === "object" ? effectReview.gatePhaseSummary : null;
|
|
668
|
-
if (gatePhaseSummary) {
|
|
669
|
-
const phases = Array.isArray(gatePhaseSummary.phases) && gatePhaseSummary.phases.length > 0
|
|
670
|
-
? gatePhaseSummary.phases.join(", ")
|
|
671
|
-
: "none";
|
|
672
|
-
console.log(` ${dim(`command effect gate phases: ${phases} (${gatePhaseSummary.requiredCount || 0}/${gatePhaseSummary.count || 0} required)`)}`);
|
|
673
|
-
}
|
|
674
|
-
const gateRunbook = effectReview.gateRunbook && typeof effectReview.gateRunbook === "object" ? effectReview.gateRunbook : null;
|
|
675
|
-
if (gateRunbook) {
|
|
676
|
-
const countFor = (phase) => Array.isArray(gateRunbook[phase]) ? gateRunbook[phase].length : 0;
|
|
677
|
-
console.log(` ${dim(`command effect gate runbook: before ${countFor("before")}, after ${countFor("after")}, refresh ${countFor("refresh")}`)}`);
|
|
678
|
-
}
|
|
679
|
-
const gateCommands = Array.isArray(effectReview.gateCommands) ? effectReview.gateCommands : [];
|
|
680
|
-
if (gateCommands.length > 0) {
|
|
681
|
-
const gateSummary = gateCommands
|
|
682
|
-
.map((item) => `${item.phase || "gate"}: ${item.command || ""}`.trim())
|
|
683
|
-
.filter((item) => item !== "")
|
|
684
|
-
.slice(0, 3)
|
|
685
|
-
.join(" -> ");
|
|
686
|
-
console.log(` ${dim(`command effect gates: ${gateSummary}`)}`);
|
|
687
|
-
}
|
|
688
|
-
}
|
|
689
|
-
const operatorRunbook = queue.operatorRunbook && typeof queue.operatorRunbook === "object" ? queue.operatorRunbook : null;
|
|
690
|
-
if (operatorRunbook) {
|
|
691
|
-
console.log(` ${dim(`operator runbook: ${operatorRunbook.stageCount || 0} stages, ${operatorRunbook.commandCount || 0} commands, ${operatorRunbook.requiredCommandCount || 0} required`)}`);
|
|
692
|
-
if (operatorRunbook.nextCommand) {
|
|
693
|
-
console.log(` ${dim(`operator next command: ${operatorRunbook.nextStage || "unknown"}: ${operatorRunbook.nextCommand}`)}`);
|
|
694
|
-
}
|
|
695
|
-
}
|
|
696
|
-
if (queue.nextActionId) console.log(` ${dim(`next action: ${queue.nextActionId}`)}`);
|
|
697
|
-
if (queue.nextCommand) console.log(` ${dim(`next command: ${queue.nextCommand}`)}`);
|
|
698
|
-
if (queue.nextCommandRunPolicy) console.log(` ${dim(`next command policy: ${queue.nextCommandRunPolicy}`)}`);
|
|
699
|
-
const ordered = Array.isArray(queue.ordered) ? queue.ordered : [];
|
|
700
|
-
if (ordered.length > 0) {
|
|
701
|
-
console.log(` ${dim(`queue order: ${ordered.slice(0, 3).map((item) => item.actionId).join(" -> ")}`)}`);
|
|
702
|
-
}
|
|
703
|
-
const commandManifest = Array.isArray(queue.commandManifest) ? queue.commandManifest : [];
|
|
704
|
-
if (commandManifest.length > 0) {
|
|
705
|
-
console.log(` ${dim(`command manifest: ${commandManifest.slice(0, 3).map((item) => {
|
|
706
|
-
const effects = item.commandEffects && typeof item.commandEffects === "object" ? item.commandEffects : {};
|
|
707
|
-
const targets = Array.isArray(effects.outputTargets) && effects.outputTargets.length > 0
|
|
708
|
-
? `:${effects.outputTargets.map((target) => target.value).join(",")}`
|
|
709
|
-
: "";
|
|
710
|
-
return `${item.actionId}:${item.runPolicy}${targets}`;
|
|
711
|
-
}).join(" -> ")}`)}`);
|
|
712
|
-
}
|
|
713
|
-
}
|
|
714
|
-
for (const step of planSteps.slice(0, 3)) {
|
|
715
|
-
console.log(`- ${step.rank}. ${step.priority} ${step.category}: ${step.title}`);
|
|
716
|
-
if (step.command) console.log(` ${dim(step.command)}`);
|
|
717
|
-
if (step.commandSafety?.level) console.log(` ${dim(`safety: ${step.commandSafety.level}`)}`);
|
|
718
|
-
console.log(` ${dim(`requires mutation review: ${step.requiresReviewBeforeMutation ? "yes" : "no"}`)}`);
|
|
719
|
-
}
|
|
720
|
-
}
|
|
721
|
-
|
|
722
|
-
if (payload.recommendations.length > 0) {
|
|
723
|
-
console.log();
|
|
724
|
-
console.log("Recommendations:");
|
|
725
|
-
for (const recommendation of payload.recommendations) {
|
|
726
|
-
console.log(`- ${recommendation.level}: ${recommendation.text}`);
|
|
727
|
-
}
|
|
728
|
-
}
|
|
729
|
-
|
|
730
|
-
console.log();
|
|
731
|
-
console.log("Privacy: agent backlog is read-only, local, and does not mutate learning.json or skill files.");
|
|
732
|
-
}
|
|
733
|
-
|
|
734
|
-
function printSkillProposals(payload) {
|
|
735
|
-
header("design-ai learn", "Skill evolution proposals");
|
|
736
|
-
info(`File: ${payload.file}`);
|
|
737
|
-
info(`Status: ${payload.status}`);
|
|
738
|
-
info(`Signal source: ${payload.signalSource}`);
|
|
739
|
-
info(`Signal status: ${payload.signalStatus}`);
|
|
740
|
-
info(`Min evidence: ${payload.minEvidenceCount}`);
|
|
741
|
-
info(`Check capture entries: ${payload.checkCaptureCount}`);
|
|
742
|
-
info(`Candidates: ${payload.candidateCount}`);
|
|
743
|
-
info(`Proposals: ${payload.proposalCount}`);
|
|
744
|
-
info(`Pending review: ${payload.pendingReviewCount ?? payload.proposalCount}`);
|
|
745
|
-
info(`Reviewed: ${payload.reviewedCount ?? 0}`);
|
|
746
|
-
info(`Skipped: ${payload.skippedCount}`);
|
|
747
|
-
if (payload.review?.file) {
|
|
748
|
-
info(`Review file: ${payload.review.file}`);
|
|
749
|
-
info(`Review status: ${payload.review.status} (${payload.review.matchedCount} matched, ${payload.review.staleCount} stale)`);
|
|
750
|
-
}
|
|
751
|
-
console.log();
|
|
752
|
-
|
|
753
|
-
if (payload.proposals.length === 0) {
|
|
754
|
-
console.log("No repeated check-capture groups crossed the proposal threshold.");
|
|
755
|
-
} else {
|
|
756
|
-
console.log("Proposed skill deltas:");
|
|
757
|
-
for (const proposal of payload.proposals) {
|
|
758
|
-
const routes = proposal.routeIds.length > 0 ? proposal.routeIds.join(", ") : "artifact";
|
|
759
|
-
console.log(`- ${proposal.id}: ${proposal.candidateSkillPath}`);
|
|
760
|
-
console.log(` ${dim(`${proposal.sourceIssueCount} issue(s) · ${proposal.category} · routes ${routes} · risk ${proposal.riskLevel} · review ${proposal.reviewStatus || "pending"}`)}`);
|
|
761
|
-
if (proposal.reviewDecision?.note) console.log(` Review note: ${proposal.reviewDecision.note}`);
|
|
762
|
-
console.log(` Delta: ${proposal.proposedInstructionDelta}`);
|
|
763
|
-
console.log(` Verify: ${proposal.verificationCommand}`);
|
|
764
|
-
for (const evidence of proposal.evidenceSources.slice(0, 3)) {
|
|
765
|
-
console.log(` Evidence: ${evidence.entryId} [${evidence.category}] ${evidence.source}`);
|
|
766
|
-
if (evidence.textPreview) console.log(` ${dim(evidence.textPreview)}`);
|
|
767
|
-
}
|
|
768
|
-
}
|
|
769
|
-
}
|
|
770
|
-
|
|
771
|
-
if (payload.skipped.length > 0) {
|
|
772
|
-
console.log();
|
|
773
|
-
console.log("Skipped groups:");
|
|
774
|
-
for (const item of payload.skipped) {
|
|
775
|
-
console.log(`- ${item.candidateSkillPath} [${item.category}]: ${item.reason}`);
|
|
776
|
-
}
|
|
777
|
-
}
|
|
778
|
-
|
|
779
|
-
if (payload.review?.warnings?.length > 0) {
|
|
780
|
-
console.log();
|
|
781
|
-
console.log("Review file warnings:");
|
|
782
|
-
for (const warning of payload.review.warnings) {
|
|
783
|
-
console.log(`- ${warning}`);
|
|
784
|
-
}
|
|
785
|
-
}
|
|
786
|
-
|
|
787
|
-
if (payload.recommendations.length > 0) {
|
|
788
|
-
console.log();
|
|
789
|
-
console.log("Recommendations:");
|
|
790
|
-
for (const recommendation of payload.recommendations) {
|
|
791
|
-
console.log(`- ${recommendation.level}: ${recommendation.text}`);
|
|
792
|
-
}
|
|
793
|
-
}
|
|
794
|
-
|
|
795
|
-
console.log();
|
|
796
|
-
console.log("No changes made. This command is preview-only and does not edit skill files or learning.json.");
|
|
797
|
-
}
|
|
798
|
-
|
|
799
|
-
function printSkillProposalReviewCheck(payload) {
|
|
800
|
-
header("design-ai learn", "Skill proposal review check");
|
|
801
|
-
info(`File: ${payload.file}`);
|
|
802
|
-
info(`Status: ${payload.status}`);
|
|
803
|
-
info(`Proposal status: ${payload.proposalStatus}`);
|
|
804
|
-
info(`Signal status: ${payload.signalStatus}`);
|
|
805
|
-
info(`Review file: ${payload.reviewFile || "not configured"}`);
|
|
806
|
-
info(`Proposals: ${payload.proposalCount}`);
|
|
807
|
-
info(`Pending review: ${payload.pendingReviewCount}`);
|
|
808
|
-
info(`Reviewed: ${payload.reviewedCount}`);
|
|
809
|
-
console.log();
|
|
810
|
-
|
|
811
|
-
console.log("Checks:");
|
|
812
|
-
for (const check of payload.checks || []) {
|
|
813
|
-
console.log(`- ${check.level}: ${check.id} - ${check.message}`);
|
|
814
|
-
}
|
|
815
|
-
|
|
816
|
-
if (payload.review?.warnings?.length > 0) {
|
|
817
|
-
console.log();
|
|
818
|
-
console.log("Review file warnings:");
|
|
819
|
-
for (const warning of payload.review.warnings) {
|
|
820
|
-
console.log(`- ${warning}`);
|
|
821
|
-
}
|
|
822
|
-
}
|
|
823
|
-
|
|
824
|
-
if (payload.recommendations.length > 0) {
|
|
825
|
-
console.log();
|
|
826
|
-
console.log("Recommendations:");
|
|
827
|
-
for (const recommendation of payload.recommendations) {
|
|
828
|
-
console.log(`- ${recommendation.level}: ${recommendation.text}`);
|
|
829
|
-
}
|
|
830
|
-
}
|
|
831
|
-
|
|
832
|
-
console.log();
|
|
833
|
-
console.log("Privacy: review check is read-only and does not mutate learning.json or skill files.");
|
|
834
|
-
}
|
|
835
|
-
|
|
836
|
-
function printSkillProposalApplyPlan(payload) {
|
|
837
|
-
header("design-ai learn", "Skill proposal apply plan");
|
|
838
|
-
info(`File: ${payload.file}`);
|
|
839
|
-
info(`Status: ${payload.status}`);
|
|
840
|
-
info(`Proposal status: ${payload.proposalStatus}`);
|
|
841
|
-
info(`Signal status: ${payload.signalStatus}`);
|
|
842
|
-
info(`Review file: ${payload.reviewFile || "not configured"}`);
|
|
843
|
-
info(`Accepted proposals: ${payload.acceptedCount}`);
|
|
844
|
-
info(`Pending review: ${payload.pendingReviewCount}`);
|
|
845
|
-
info(`Reviewed: ${payload.reviewedCount}`);
|
|
846
|
-
console.log();
|
|
847
|
-
|
|
848
|
-
if (!payload.tasks || payload.tasks.length === 0) {
|
|
849
|
-
console.log("No accepted skill proposals are ready for manual apply.");
|
|
850
|
-
} else {
|
|
851
|
-
console.log("Manual apply tasks:");
|
|
852
|
-
for (const task of payload.tasks) {
|
|
853
|
-
const routes = Array.isArray(task.routeIds) && task.routeIds.length > 0 ? task.routeIds.join(", ") : "artifact";
|
|
854
|
-
console.log(`- ${task.proposalId}: ${task.candidateSkillPath}`);
|
|
855
|
-
console.log(` ${dim(`${task.sourceIssueCount} issue(s) · ${task.category} · routes ${routes} · risk ${task.riskLevel}`)}`);
|
|
856
|
-
if (task.reviewDecision?.note) console.log(` Review note: ${task.reviewDecision.note}`);
|
|
857
|
-
console.log(` Delta: ${task.proposedInstructionDelta}`);
|
|
858
|
-
console.log(` Verify: ${task.verificationCommand}`);
|
|
859
|
-
for (const step of task.manualSteps || []) {
|
|
860
|
-
console.log(` Step: ${step}`);
|
|
861
|
-
}
|
|
862
|
-
}
|
|
863
|
-
}
|
|
864
|
-
|
|
865
|
-
if (payload.commands) {
|
|
866
|
-
console.log();
|
|
867
|
-
console.log("Follow-up commands:");
|
|
868
|
-
for (const [label, command] of Object.entries(payload.commands)) {
|
|
869
|
-
console.log(`- ${label}: ${command}`);
|
|
870
|
-
}
|
|
871
|
-
}
|
|
872
|
-
|
|
873
|
-
if (payload.commandContract) {
|
|
874
|
-
const contract = payload.commandContract;
|
|
875
|
-
console.log();
|
|
876
|
-
console.log("Command contract:");
|
|
877
|
-
console.log(`- valid: ${contract.valid ? "yes" : "no"}`);
|
|
878
|
-
console.log(`- status: ${contract.status || "unknown"}`);
|
|
879
|
-
console.log(`- required keys: ${(contract.requiredKeys || []).join(", ") || "none"}`);
|
|
880
|
-
console.log(`- command count: ${contract.commandCount || 0}`);
|
|
881
|
-
console.log(`- check count: ${contract.checkCount || 0}`);
|
|
882
|
-
console.log(`- pass count: ${contract.passCount || 0}`);
|
|
883
|
-
console.log(`- warning count: ${contract.warningCount || 0}`);
|
|
884
|
-
console.log(`- review file required: ${contract.reviewFileRequired ? "yes" : "no"}`);
|
|
885
|
-
console.log(`- forbidden flags: ${(contract.forbiddenFlags || []).join(", ") || "none"}`);
|
|
886
|
-
console.log(`- failure count: ${contract.failureCount || 0}`);
|
|
887
|
-
console.log(`- failed checks: ${(contract.failedCheckIds || []).join(", ") || "none"}`);
|
|
888
|
-
console.log(`- next command key: ${contract.nextCommandKey || "none"}`);
|
|
889
|
-
console.log(`- next command policy: ${contract.nextCommandRunPolicy || "none"}`);
|
|
890
|
-
if (contract.nextCommandSafety?.level) {
|
|
891
|
-
console.log(`- next command safety: ${contract.nextCommandSafety.level}`);
|
|
892
|
-
}
|
|
893
|
-
if (contract.nextCommand) {
|
|
894
|
-
console.log(`- next command: ${contract.nextCommand}`);
|
|
895
|
-
}
|
|
896
|
-
console.log(`- command sequence count: ${contract.commandSequenceCount || 0}`);
|
|
897
|
-
console.log(`- command sequence keys: ${(contract.commandSequenceKeys || []).join(", ") || "none"}`);
|
|
898
|
-
const sequenceSummary = contract.commandSequenceSummary || {};
|
|
899
|
-
console.log(`- command sequence policy: ${sequenceSummary.runPolicy || "none"}`);
|
|
900
|
-
console.log(`- command sequence executable: ${sequenceSummary.executable ? "yes" : "no"}`);
|
|
901
|
-
console.log(`- command sequence local outputs: ${sequenceSummary.localOutputStepCount || 0}`);
|
|
902
|
-
console.log(`- command sequence mutates profile: ${sequenceSummary.mutatesProfile ? "yes" : "no"}`);
|
|
903
|
-
console.log(`- command sequence mutates review file: ${sequenceSummary.mutatesReviewFile ? "yes" : "no"}`);
|
|
904
|
-
console.log(`- command sequence mutates skill files: ${sequenceSummary.mutatesSkillFiles ? "yes" : "no"}`);
|
|
905
|
-
console.log(`- command sequence calls external AI APIs: ${sequenceSummary.callsExternalAiApis ? "yes" : "no"}`);
|
|
906
|
-
const operatorRunbook = contract.operatorRunbook || {};
|
|
907
|
-
console.log(`- operator runbook stages: ${operatorRunbook.stageCount || 0}`);
|
|
908
|
-
console.log(`- operator runbook keys: ${(operatorRunbook.stageKeys || []).join(", ") || "none"}`);
|
|
909
|
-
console.log(`- operator runbook required stages: ${operatorRunbook.requiredStageCount || 0}`);
|
|
910
|
-
console.log(`- operator runbook next stage: ${operatorRunbook.nextStageKey || "none"}`);
|
|
911
|
-
console.log(`- operator runbook next required stage: ${operatorRunbook.nextRequiredStageKey || "none"}`);
|
|
912
|
-
console.log(`- operator runbook next required command stage: ${operatorRunbook.nextRequiredCommandStageKey || "none"}`);
|
|
913
|
-
if (operatorRunbook.stageSelection?.strategy) {
|
|
914
|
-
console.log(`- operator runbook stage selection: ${operatorRunbook.stageSelection.strategy}`);
|
|
915
|
-
if (operatorRunbook.stageSelection.decision?.action) {
|
|
916
|
-
console.log(`- operator runbook decision: ${operatorRunbook.stageSelection.decision.action}`);
|
|
917
|
-
if (operatorRunbook.stageSelection.decision.safety?.level) {
|
|
918
|
-
console.log(`- operator runbook decision safety: ${operatorRunbook.stageSelection.decision.safety.level}`);
|
|
919
|
-
}
|
|
920
|
-
if (Array.isArray(operatorRunbook.stageSelection.decision.commands)) {
|
|
921
|
-
console.log(`- operator runbook decision commands: ${operatorRunbook.stageSelection.decision.commands.map((command) => command.key).join(", ") || "none"}`);
|
|
922
|
-
}
|
|
923
|
-
if (operatorRunbook.stageSelection.decision.nextCommandKey) {
|
|
924
|
-
console.log(`- operator runbook decision next command: ${operatorRunbook.stageSelection.decision.nextCommandKey}`);
|
|
925
|
-
}
|
|
926
|
-
}
|
|
927
|
-
if (operatorRunbook.stageSelection.nextStage?.key) {
|
|
928
|
-
const nextStageLabel = operatorRunbook.stageSelection.nextStage.required ? "required" : "optional";
|
|
929
|
-
console.log(`- operator runbook selected stage: ${operatorRunbook.stageSelection.nextStage.key} (${nextStageLabel}, ${operatorRunbook.stageSelection.nextStage.kind})`);
|
|
930
|
-
}
|
|
931
|
-
}
|
|
932
|
-
if (Array.isArray(contract.commandSequence) && contract.commandSequence.length > 0) {
|
|
933
|
-
console.log("Command sequence:");
|
|
934
|
-
for (const item of contract.commandSequence) {
|
|
935
|
-
const safetyLevel = item.safety?.level || "unknown";
|
|
936
|
-
console.log(`- ${item.step}. ${item.key}: ${item.runPolicy || "unknown"} / ${safetyLevel}`);
|
|
937
|
-
}
|
|
938
|
-
}
|
|
939
|
-
if (Array.isArray(operatorRunbook.stages) && operatorRunbook.stages.length > 0) {
|
|
940
|
-
console.log("Operator runbook:");
|
|
941
|
-
for (const stage of operatorRunbook.stages) {
|
|
942
|
-
const required = stage.required ? "required" : "optional";
|
|
943
|
-
const commandKeys = Array.isArray(stage.commandKeys) && stage.commandKeys.length > 0
|
|
944
|
-
? stage.commandKeys.join(", ")
|
|
945
|
-
: "manual";
|
|
946
|
-
console.log(`- ${stage.step}. ${stage.key}: ${required} / ${stage.kind || "unknown"} / ${commandKeys}`);
|
|
947
|
-
}
|
|
948
|
-
}
|
|
949
|
-
if (contract.nextAction) {
|
|
950
|
-
console.log(`- next action: ${contract.nextAction}`);
|
|
951
|
-
}
|
|
952
|
-
if (Array.isArray(contract.missingCommandKeys) && contract.missingCommandKeys.length > 0) {
|
|
953
|
-
console.log(`- missing command keys: ${contract.missingCommandKeys.join(", ")}`);
|
|
954
|
-
}
|
|
955
|
-
if (Array.isArray(contract.unexpectedCommandKeys) && contract.unexpectedCommandKeys.length > 0) {
|
|
956
|
-
console.log(`- unexpected command keys: ${contract.unexpectedCommandKeys.join(", ")}`);
|
|
957
|
-
}
|
|
958
|
-
if (Array.isArray(contract.failedChecks) && contract.failedChecks.length > 0) {
|
|
959
|
-
console.log("Failed command checks:");
|
|
960
|
-
for (const check of contract.failedChecks) {
|
|
961
|
-
console.log(`- ${check.id}: ${check.message}`);
|
|
962
|
-
}
|
|
963
|
-
}
|
|
964
|
-
}
|
|
965
|
-
|
|
966
|
-
if (payload.recommendations.length > 0) {
|
|
967
|
-
console.log();
|
|
968
|
-
console.log("Recommendations:");
|
|
969
|
-
for (const recommendation of payload.recommendations) {
|
|
970
|
-
console.log(`- ${recommendation.level}: ${recommendation.text}`);
|
|
971
|
-
}
|
|
972
|
-
}
|
|
973
|
-
|
|
974
|
-
console.log();
|
|
975
|
-
console.log("Privacy: apply plan is read-only and does not mutate learning.json, review files, or skill files.");
|
|
976
|
-
}
|
|
977
|
-
|
|
978
|
-
function printDiff(payload) {
|
|
979
|
-
header("design-ai learn", "Learning profile diff");
|
|
980
|
-
info(`File: ${payload.file}`);
|
|
981
|
-
info(`Compare: ${payload.source}`);
|
|
982
|
-
info(`Profile entries: ${payload.profileCount}`);
|
|
983
|
-
info(`Comparison entries: ${payload.comparisonCount}`);
|
|
984
|
-
info(`Profile-only: ${payload.profileOnlyCount}`);
|
|
985
|
-
info(`Comparison-only: ${payload.comparisonOnlyCount}`);
|
|
986
|
-
info(`Metadata changes: ${payload.metadataChangedCount}`);
|
|
987
|
-
info(`ID conflicts: ${payload.idConflictCount}`);
|
|
988
|
-
info(`Profile audit: ${payload.profileAuditSummary.status} (${payload.profileAuditSummary.failures} failure(s), ${payload.profileAuditSummary.warnings} warning(s))`);
|
|
989
|
-
info(`Comparison audit: ${payload.comparisonAuditSummary.status} (${payload.comparisonAuditSummary.failures} failure(s), ${payload.comparisonAuditSummary.warnings} warning(s))`);
|
|
990
|
-
console.log();
|
|
991
|
-
|
|
992
|
-
if (
|
|
993
|
-
payload.profileOnly.length === 0
|
|
994
|
-
&& payload.comparisonOnly.length === 0
|
|
995
|
-
&& payload.metadataChanged.length === 0
|
|
996
|
-
&& payload.idConflicts.length === 0
|
|
997
|
-
) {
|
|
998
|
-
console.log("Profiles match by category, normalized text, id, source, and createdAt metadata.");
|
|
999
|
-
}
|
|
1000
|
-
|
|
1001
|
-
if (payload.profileOnly.length > 0) {
|
|
1002
|
-
console.log("Profile-only entries:");
|
|
1003
|
-
for (const entry of payload.profileOnly) {
|
|
1004
|
-
console.log(`- ${entry.id}: [${entry.category}] ${entry.textPreview}`);
|
|
1005
|
-
}
|
|
1006
|
-
console.log();
|
|
1007
|
-
}
|
|
1008
|
-
|
|
1009
|
-
if (payload.comparisonOnly.length > 0) {
|
|
1010
|
-
console.log("Comparison-only entries:");
|
|
1011
|
-
for (const entry of payload.comparisonOnly) {
|
|
1012
|
-
console.log(`- ${entry.id}: [${entry.category}] ${entry.textPreview}`);
|
|
1013
|
-
}
|
|
1014
|
-
console.log();
|
|
1015
|
-
}
|
|
1016
|
-
|
|
1017
|
-
if (payload.metadataChanged.length > 0) {
|
|
1018
|
-
console.log("Metadata changes:");
|
|
1019
|
-
for (const item of payload.metadataChanged) {
|
|
1020
|
-
console.log(`- ${item.profile.id}: ${item.changedFields.join(", ")}`);
|
|
1021
|
-
console.log(` ${dim(`profile ${item.profile.source} · ${item.profile.createdAt}`)}`);
|
|
1022
|
-
console.log(` ${dim(`comparison ${item.comparison.source} · ${item.comparison.createdAt}`)}`);
|
|
1023
|
-
}
|
|
1024
|
-
console.log();
|
|
1025
|
-
}
|
|
1026
|
-
|
|
1027
|
-
if (payload.idConflicts.length > 0) {
|
|
1028
|
-
console.log("ID conflicts:");
|
|
1029
|
-
for (const item of payload.idConflicts) {
|
|
1030
|
-
console.log(`- ${item.id}`);
|
|
1031
|
-
console.log(` profile: [${item.profile.category}] ${item.profile.textPreview}`);
|
|
1032
|
-
console.log(` comparison: [${item.comparison.category}] ${item.comparison.textPreview}`);
|
|
1033
|
-
}
|
|
1034
|
-
console.log();
|
|
1035
|
-
}
|
|
1036
|
-
|
|
1037
|
-
if (payload.recommendations.length > 0) {
|
|
1038
|
-
console.log("Recommendations:");
|
|
1039
|
-
for (const recommendation of payload.recommendations) {
|
|
1040
|
-
console.log(`- ${recommendation.level}: ${recommendation.text}`);
|
|
1041
|
-
}
|
|
1042
|
-
console.log();
|
|
1043
|
-
}
|
|
1044
|
-
|
|
1045
|
-
console.log("No changes made. Use `design-ai learn --import --dry-run` if comparison-only entries should be added.");
|
|
1046
|
-
}
|
|
1047
|
-
|
|
1048
|
-
function printRestore(payload) {
|
|
1049
|
-
header("design-ai learn", payload.dryRun ? "Learning restore preview" : "Learning restore applied");
|
|
1050
|
-
info(`File: ${payload.file}`);
|
|
1051
|
-
info(`Source: ${payload.source}`);
|
|
1052
|
-
info(`Restorable: ${payload.restorable ? "yes" : "no"}`);
|
|
1053
|
-
info(`Previous entries: ${payload.previousCount}`);
|
|
1054
|
-
info(`Restored entries: ${payload.restoredCount}`);
|
|
1055
|
-
info(`${payload.dryRun ? "Would remove" : "Removed"}: ${payload.removedCount}`);
|
|
1056
|
-
info(`${payload.dryRun ? "Would add" : "Added"}: ${payload.addedCount}`);
|
|
1057
|
-
info(`Metadata changes: ${payload.metadataChangedCount}`);
|
|
1058
|
-
info(`ID conflicts: ${payload.idConflictCount}`);
|
|
1059
|
-
info(`${payload.dryRun ? "Rollback backup target" : "Rollback backup"}: ${payload.backupFile}`);
|
|
1060
|
-
info(`Backup created: ${payload.backupCreated ? "yes" : "no"}`);
|
|
1061
|
-
info(`Restore audit: ${payload.auditSummary.status} (${payload.auditSummary.failures} failure(s), ${payload.auditSummary.warnings} warning(s))`);
|
|
1062
|
-
console.log();
|
|
1063
|
-
|
|
1064
|
-
if (payload.issues.length > 0) {
|
|
1065
|
-
console.log("Restore source issues:");
|
|
1066
|
-
for (const issue of payload.issues) {
|
|
1067
|
-
const entry = issue.entryId ? ` (${issue.entryId})` : "";
|
|
1068
|
-
console.log(`- ${issue.level.toUpperCase()} ${issue.code}${entry}: ${issue.message}`);
|
|
1069
|
-
}
|
|
1070
|
-
console.log();
|
|
1071
|
-
}
|
|
1072
|
-
|
|
1073
|
-
if (!payload.restorable) {
|
|
1074
|
-
console.log("No changes made. Fix the restore source audit failures before applying restore.");
|
|
1075
|
-
return;
|
|
1076
|
-
}
|
|
1077
|
-
|
|
1078
|
-
if (payload.diff.profileOnly.length > 0) {
|
|
1079
|
-
console.log(payload.dryRun ? "Entries that would be removed:" : "Removed entries:");
|
|
1080
|
-
for (const entry of payload.diff.profileOnly) {
|
|
1081
|
-
console.log(`- ${entry.id}: [${entry.category}] ${entry.textPreview}`);
|
|
1082
|
-
}
|
|
1083
|
-
console.log();
|
|
1084
|
-
}
|
|
1085
|
-
|
|
1086
|
-
if (payload.diff.comparisonOnly.length > 0) {
|
|
1087
|
-
console.log(payload.dryRun ? "Entries that would be added:" : "Added entries:");
|
|
1088
|
-
for (const entry of payload.diff.comparisonOnly) {
|
|
1089
|
-
console.log(`- ${entry.id}: [${entry.category}] ${entry.textPreview}`);
|
|
1090
|
-
}
|
|
1091
|
-
console.log();
|
|
1092
|
-
}
|
|
1093
|
-
|
|
1094
|
-
if (payload.idConflictCount > 0) {
|
|
1095
|
-
console.log("ID conflicts:");
|
|
1096
|
-
for (const item of payload.diff.idConflicts) {
|
|
1097
|
-
console.log(`- ${item.id}`);
|
|
1098
|
-
console.log(` active: [${item.profile.category}] ${item.profile.textPreview}`);
|
|
1099
|
-
console.log(` restore: [${item.comparison.category}] ${item.comparison.textPreview}`);
|
|
1100
|
-
}
|
|
1101
|
-
console.log();
|
|
1102
|
-
}
|
|
1103
|
-
|
|
1104
|
-
if (payload.dryRun) {
|
|
1105
|
-
console.log("No changes made. Re-run with `--yes` instead of `--dry-run` to replace the active learning profile.");
|
|
1106
|
-
console.log(`Rollback backup will be written before apply: ${payload.backupFile}`);
|
|
1107
|
-
} else {
|
|
1108
|
-
console.log(`Rollback preview: ${payload.rollbackCommand}`);
|
|
1109
|
-
}
|
|
1110
|
-
}
|
|
1111
|
-
|
|
1112
|
-
function printRestoreBackups(payload) {
|
|
1113
|
-
header("design-ai learn", "Learning restore rollback backups");
|
|
1114
|
-
info(`File: ${payload.file}`);
|
|
1115
|
-
info(`Directory: ${payload.directory}`);
|
|
1116
|
-
info(`Pattern: ${payload.pattern}`);
|
|
1117
|
-
info(`Backups: ${payload.count}/${payload.totalCount}`);
|
|
1118
|
-
info(`Limit: ${payload.limit}`);
|
|
1119
|
-
console.log();
|
|
1120
|
-
|
|
1121
|
-
if (payload.backups.length === 0) {
|
|
1122
|
-
console.log("No restore rollback backups found for this learning profile.");
|
|
1123
|
-
console.log("Confirmed `design-ai learn --restore --yes` runs create sibling rollback backups automatically.");
|
|
1124
|
-
return;
|
|
1125
|
-
}
|
|
1126
|
-
|
|
1127
|
-
for (let i = 0; i < payload.backups.length; i += 1) {
|
|
1128
|
-
const backup = payload.backups[i];
|
|
1129
|
-
console.log(`${i + 1}. ${backup.name}`);
|
|
1130
|
-
console.log(` ${dim(`created ${backup.createdAt || "unknown"} · modified ${backup.modifiedAt} · ${backup.sizeBytes} bytes`)}`);
|
|
1131
|
-
console.log(` ${dim(`entries ${backup.entryCount} · updatedAt ${backup.updatedAt || "unknown"} · audit ${backup.auditSummary.status} (${backup.auditSummary.failures} failure(s), ${backup.auditSummary.warnings} warning(s))`)}`);
|
|
1132
|
-
if (backup.issueCount > 0) {
|
|
1133
|
-
console.log(` ${dim(`issues ${backup.issueCount}`)}`);
|
|
1134
|
-
}
|
|
1135
|
-
console.log(` Preview: ${backup.restorePreviewCommand}`);
|
|
1136
|
-
}
|
|
1137
|
-
|
|
1138
|
-
console.log();
|
|
1139
|
-
console.log("No changes made. Run the preview command first, then add `--yes` only after reviewing the restore diff.");
|
|
1140
|
-
}
|
|
1141
|
-
|
|
1142
|
-
function printRestoreBackupPrune(payload) {
|
|
1143
|
-
const prune = payload.prune;
|
|
1144
|
-
header("design-ai learn", prune.dryRun ? "Learning restore backup prune preview" : "Learning restore backup prune applied");
|
|
1145
|
-
info(`File: ${payload.file}`);
|
|
1146
|
-
info(`Directory: ${payload.directory}`);
|
|
1147
|
-
info(`Pattern: ${payload.pattern}`);
|
|
1148
|
-
info(`Backups: ${payload.totalCount}`);
|
|
1149
|
-
info(`Keep newest: ${prune.keep}`);
|
|
1150
|
-
info(`Prune candidates: ${prune.candidateCount}`);
|
|
1151
|
-
if (!prune.dryRun) {
|
|
1152
|
-
info(`Deleted: ${prune.deletedCount}`);
|
|
1153
|
-
if (prune.failureCount > 0) {
|
|
1154
|
-
info(`Failures: ${prune.failureCount}`);
|
|
1155
|
-
}
|
|
1156
|
-
}
|
|
1157
|
-
console.log();
|
|
1158
|
-
|
|
1159
|
-
if (prune.candidateCount === 0) {
|
|
1160
|
-
console.log("No restore rollback backups are old enough to prune.");
|
|
1161
|
-
console.log("No changes made.");
|
|
1162
|
-
return;
|
|
1163
|
-
}
|
|
1164
|
-
|
|
1165
|
-
const candidateLabel = prune.dryRun ? "Would delete:" : "Deleted:";
|
|
1166
|
-
const rows = prune.dryRun ? prune.candidates : prune.deleted;
|
|
1167
|
-
console.log(candidateLabel);
|
|
1168
|
-
for (const backup of rows) {
|
|
1169
|
-
console.log(`- ${backup.name}`);
|
|
1170
|
-
console.log(` ${dim(`created ${backup.createdAt || "unknown"} · modified ${backup.modifiedAt} · ${backup.sizeBytes} bytes · audit ${backup.auditSummary.status}`)}`);
|
|
1171
|
-
}
|
|
1172
|
-
|
|
1173
|
-
if (prune.failures.length > 0) {
|
|
1174
|
-
console.log();
|
|
1175
|
-
console.log("Delete failures:");
|
|
1176
|
-
for (const failure of prune.failures) {
|
|
1177
|
-
console.log(`- ${failure.name}: ${failure.message}`);
|
|
1178
|
-
}
|
|
1179
|
-
}
|
|
1180
|
-
|
|
1181
|
-
console.log();
|
|
1182
|
-
if (prune.dryRun) {
|
|
1183
|
-
console.log("No changes made. Re-run with `--yes` after reviewing the prune candidates.");
|
|
1184
|
-
} else if (prune.failureCount > 0) {
|
|
1185
|
-
console.log("Some backup files could not be deleted. Review the failure list before retrying.");
|
|
1186
|
-
} else {
|
|
1187
|
-
console.log("Prune complete. Active learning profile was not changed.");
|
|
1188
|
-
}
|
|
1189
|
-
}
|
|
1190
|
-
|
|
1191
|
-
function printEval(payload) {
|
|
1192
|
-
header("design-ai learn", "Local learning eval report");
|
|
1193
|
-
info(`File: ${payload.file}`);
|
|
1194
|
-
info(`Checkpoint: ${payload.source}`);
|
|
1195
|
-
info(`Status: ${payload.status}`);
|
|
1196
|
-
info(`Cases: ${payload.caseCount}`);
|
|
1197
|
-
info(`Passed: ${payload.passed}`);
|
|
1198
|
-
info(`Warned: ${payload.warned}`);
|
|
1199
|
-
info(`Failed: ${payload.failed}`);
|
|
1200
|
-
info(`Profile entries: ${payload.profileEntryCount}`);
|
|
1201
|
-
info(`Default limit: ${payload.defaultLimit}`);
|
|
1202
|
-
if (payload.defaultCategory) info(`Default category: ${payload.defaultCategory}`);
|
|
1203
|
-
console.log();
|
|
1204
|
-
|
|
1205
|
-
for (const item of payload.cases) {
|
|
1206
|
-
const route = item.routeId ? ` / ${item.routeId}` : "";
|
|
1207
|
-
const category = item.category ? ` / ${item.category}` : "";
|
|
1208
|
-
console.log(`- ${item.id}${route}${category}: ${item.status}`);
|
|
1209
|
-
console.log(` ${dim(`briefHash ${item.briefHash} · matched ${item.matchedCount}/${item.candidateCount} · selected ${item.selectedEntryIds.join(", ") || "none"} · fallback ${item.fallbackCount}`)}`);
|
|
1210
|
-
if (item.missingExpectedIds.length > 0) {
|
|
1211
|
-
console.log(` missing expected: ${item.missingExpectedIds.join(", ")}`);
|
|
1212
|
-
}
|
|
1213
|
-
if (item.unexpectedAvoidedIds.length > 0) {
|
|
1214
|
-
console.log(` avoided selected: ${item.unexpectedAvoidedIds.join(", ")}`);
|
|
1215
|
-
}
|
|
1216
|
-
for (const issue of item.issues) {
|
|
1217
|
-
console.log(` ${issue.level.toUpperCase()} ${issue.code}: ${issue.message}`);
|
|
1218
|
-
}
|
|
1219
|
-
}
|
|
1220
|
-
|
|
1221
|
-
if (payload.recommendations.length > 0) {
|
|
1222
|
-
console.log();
|
|
1223
|
-
console.log("Recommendations:");
|
|
1224
|
-
for (const recommendation of payload.recommendations) {
|
|
1225
|
-
console.log(`- ${recommendation.level}: ${recommendation.text}`);
|
|
1226
|
-
}
|
|
1227
|
-
}
|
|
1228
|
-
|
|
1229
|
-
console.log();
|
|
1230
|
-
console.log("Privacy: eval reports expose brief hashes and selected ids, not raw brief text.");
|
|
1231
|
-
}
|
|
1232
|
-
|
|
1233
|
-
function printEvalTemplate(payload) {
|
|
1234
|
-
header("design-ai learn", "Learning eval checkpoint template");
|
|
1235
|
-
info(`File: ${payload.sourceProfile.file}`);
|
|
1236
|
-
info(`Profile entries: ${payload.sourceProfile.entryCount}`);
|
|
1237
|
-
info(`Cases: ${payload.caseCount}`);
|
|
1238
|
-
info(`Limit: ${payload.sourceProfile.limit}`);
|
|
1239
|
-
if (payload.sourceProfile.category) info(`Category: ${payload.sourceProfile.category}`);
|
|
1240
|
-
if (payload.sourceProfile.query) info(`Query: ${payload.sourceProfile.query}`);
|
|
1241
|
-
console.log();
|
|
1242
|
-
|
|
1243
|
-
if (payload.cases.length === 0) {
|
|
1244
|
-
console.log("No checkpoint cases generated.");
|
|
1245
|
-
} else {
|
|
1246
|
-
console.log("Generated cases:");
|
|
1247
|
-
for (const item of payload.cases) {
|
|
1248
|
-
const category = item.category ? ` / ${item.category}` : "";
|
|
1249
|
-
console.log(`- ${item.id}${category}: expects ${item.expectedSelectedIds.join(", ")}`);
|
|
1250
|
-
}
|
|
1251
|
-
}
|
|
1252
|
-
|
|
1253
|
-
if (payload.recommendations.length > 0) {
|
|
1254
|
-
console.log();
|
|
1255
|
-
console.log("Recommendations:");
|
|
1256
|
-
for (const recommendation of payload.recommendations) {
|
|
1257
|
-
console.log(`- ${recommendation.level}: ${recommendation.text}`);
|
|
1258
|
-
}
|
|
1259
|
-
}
|
|
1260
|
-
|
|
1261
|
-
console.log();
|
|
1262
|
-
console.log("Privacy: checkpoint templates store raw brief text so they can be re-run locally. Review before sharing.");
|
|
1263
|
-
}
|
|
1264
|
-
|
|
1265
|
-
function applyEvalStrictExit(parsed, payload) {
|
|
1266
|
-
if (parsed.strict && payload.status !== "pass") {
|
|
1267
|
-
process.exitCode = 1;
|
|
1268
|
-
}
|
|
1269
|
-
}
|
|
1270
|
-
|
|
1271
|
-
function applySignalsStrictExit(parsed, payload) {
|
|
1272
|
-
if (
|
|
1273
|
-
parsed.strict
|
|
1274
|
-
&& (payload.status !== "pass" || payload.agentDevelopment?.status !== "pass")
|
|
1275
|
-
) {
|
|
1276
|
-
process.exitCode = 1;
|
|
1277
|
-
}
|
|
1278
|
-
}
|
|
1279
|
-
|
|
1280
|
-
function applyAgentBacklogStrictExit(parsed, payload) {
|
|
1281
|
-
if (parsed.strict && (payload.status !== "pass" || payload.signalStatus === "fail")) {
|
|
1282
|
-
process.exitCode = 1;
|
|
1283
|
-
}
|
|
1284
|
-
}
|
|
1285
|
-
|
|
1286
|
-
function applySkillProposalsStrictExit(parsed, payload) {
|
|
1287
|
-
if (parsed.strict && payload.status !== "pass") {
|
|
1288
|
-
process.exitCode = 1;
|
|
1289
|
-
}
|
|
1290
|
-
}
|
|
1291
|
-
|
|
1292
|
-
function printInit(payload) {
|
|
1293
|
-
header("design-ai learn", payload.dryRun ? "Learning profile init preview" : "Learning profile init applied");
|
|
1294
|
-
info(`File: ${payload.file}`);
|
|
1295
|
-
info(`Candidates: ${payload.candidateCount}`);
|
|
1296
|
-
info(`Added: ${payload.addedCount}`);
|
|
1297
|
-
info(`Skipped: ${payload.skippedCount}`);
|
|
1298
|
-
info(`Entries: ${payload.count}`);
|
|
1299
|
-
console.log();
|
|
1300
|
-
|
|
1301
|
-
if (payload.entries.length > 0) {
|
|
1302
|
-
console.log(payload.dryRun ? "Would add:" : "Added:");
|
|
1303
|
-
for (const entry of payload.entries) {
|
|
1304
|
-
console.log(`- [${entry.category}] ${entry.text}`);
|
|
1305
|
-
}
|
|
1306
|
-
} else {
|
|
1307
|
-
console.log("No starter learning entries to add.");
|
|
1308
|
-
}
|
|
1309
|
-
|
|
1310
|
-
if (payload.skipped.length > 0) {
|
|
1311
|
-
console.log();
|
|
1312
|
-
console.log("Skipped:");
|
|
1313
|
-
for (const skipped of payload.skipped) {
|
|
1314
|
-
console.log(`- [${skipped.category}] ${skipped.reason}: ${skipped.textPreview}`);
|
|
1315
|
-
}
|
|
1316
|
-
}
|
|
1317
|
-
|
|
1318
|
-
if (payload.dryRun) {
|
|
1319
|
-
console.log();
|
|
1320
|
-
console.log("No changes made. Re-run with `--yes` to create the starter learning profile.");
|
|
1321
|
-
}
|
|
1322
|
-
}
|
|
50
|
+
import { printHelp } from "./learn-help.mjs";
|
|
51
|
+
import {
|
|
52
|
+
learningFilter,
|
|
53
|
+
listPayload,
|
|
54
|
+
printAudit,
|
|
55
|
+
printAuditFix,
|
|
56
|
+
printCuration,
|
|
57
|
+
printLearningImportVerification,
|
|
58
|
+
printList,
|
|
59
|
+
printStats,
|
|
60
|
+
printUsage,
|
|
61
|
+
} from "./learn-print-profile.mjs";
|
|
62
|
+
import {
|
|
63
|
+
applyAgentBacklogStrictExit,
|
|
64
|
+
applyEvalStrictExit,
|
|
65
|
+
applySignalsStrictExit,
|
|
66
|
+
applySkillProposalsStrictExit,
|
|
67
|
+
printDiff,
|
|
68
|
+
printEval,
|
|
69
|
+
printEvalTemplate,
|
|
70
|
+
printInit,
|
|
71
|
+
printRestore,
|
|
72
|
+
printRestoreBackups,
|
|
73
|
+
printRestoreBackupPrune,
|
|
74
|
+
} from "./learn-print-restore.mjs";
|
|
75
|
+
import {
|
|
76
|
+
printAgentBacklog,
|
|
77
|
+
printLearnRecall,
|
|
78
|
+
printSignals,
|
|
79
|
+
printSkillProposalApplyPlan,
|
|
80
|
+
printSkillProposalReviewCheck,
|
|
81
|
+
printSkillProposals,
|
|
82
|
+
} from "./learn-print-signals.mjs";
|
|
83
|
+
import { buildLearnRecall } from "../lib/recall.mjs";
|
|
1323
84
|
|
|
1324
85
|
function readLearningInput(parsed) {
|
|
1325
86
|
return resolveBriefInput(parsed);
|
|
@@ -1604,6 +365,24 @@ export async function runLearn(args) {
|
|
|
1604
365
|
return;
|
|
1605
366
|
}
|
|
1606
367
|
|
|
368
|
+
if (parsed.action === "recall") {
|
|
369
|
+
if (!parsed.brief) {
|
|
370
|
+
throw new Error("learn --recall requires a query, e.g. `design-ai learn --recall \"korean payment\"`");
|
|
371
|
+
}
|
|
372
|
+
const payload = buildLearnRecall({
|
|
373
|
+
query: parsed.brief,
|
|
374
|
+
limit: parsed.limit || undefined,
|
|
375
|
+
category: parsed.categorySpecified ? parsed.category : "",
|
|
376
|
+
learningFilePath: parsed.filePath,
|
|
377
|
+
});
|
|
378
|
+
if (parsed.json) {
|
|
379
|
+
printOrWriteJson(parsed, payload);
|
|
380
|
+
return;
|
|
381
|
+
}
|
|
382
|
+
printLearnRecall(payload);
|
|
383
|
+
return;
|
|
384
|
+
}
|
|
385
|
+
|
|
1607
386
|
if (parsed.action === "list") {
|
|
1608
387
|
const payload = listPayload(parsed.filePath, parsed);
|
|
1609
388
|
if (parsed.json) {
|