@design-ai/cli 4.55.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 +75 -0
- package/README.ko.md +15 -32
- package/README.md +18 -31
- 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 +221 -13
- 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-analysis.mjs +297 -0
- package/cli/lib/site-args.mjs +433 -0
- package/cli/lib/site-bundle-build.mjs +127 -0
- package/cli/lib/site-bundle-check.mjs +454 -0
- package/cli/lib/site-bundle-commands.mjs +95 -0
- package/cli/lib/site-bundle-compare.mjs +157 -0
- package/cli/lib/site-bundle-contract.mjs +79 -0
- package/cli/lib/site-bundle-files.mjs +87 -0
- 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-actions.mjs +113 -0
- package/cli/lib/site-bundle-handoff-runbook-evidence-fields.mjs +164 -0
- package/cli/lib/site-bundle-handoff-runbook-evidence.mjs +334 -0
- package/cli/lib/site-bundle-handoff-runbook-format.mjs +31 -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-stage-metadata.mjs +84 -0
- package/cli/lib/site-bundle-handoff-runbook.mjs +444 -0
- package/cli/lib/site-bundle-handoff-summary.mjs +183 -0
- package/cli/lib/site-bundle-handoff.mjs +271 -0
- package/cli/lib/site-bundle-readme.mjs +98 -0
- package/cli/lib/site-bundle-repair-report.mjs +143 -0
- package/cli/lib/site-bundle-repair.mjs +68 -0
- package/cli/lib/site-content.mjs +399 -0
- package/cli/lib/site-evidence.mjs +35 -0
- package/cli/lib/site-mcp-commands.mjs +28 -0
- package/cli/lib/site-mcp-probes.mjs +159 -0
- package/cli/lib/site-mcp-readiness.mjs +157 -0
- package/cli/lib/site-mcp-report.mjs +324 -0
- package/cli/lib/site-next-actions.mjs +333 -0
- package/cli/lib/site-options.mjs +104 -0
- package/cli/lib/site-prompts.mjs +332 -0
- package/cli/lib/site-starter.mjs +153 -0
- package/cli/lib/site-strings.mjs +23 -0
- package/cli/lib/site-tasks.mjs +93 -0
- package/cli/lib/site-test-support.mjs +68 -0
- package/cli/lib/site-workflow-graph.mjs +309 -0
- package/cli/lib/site-workspace.mjs +492 -0
- package/cli/lib/site.mjs +108 -6617
- 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 +35 -6
- package/docs/DISTRIBUTION.md +35 -8
- package/docs/NEXT-SURFACE-DECISION.md +125 -0
- package/docs/PRODUCT-READINESS.md +3 -3
- package/docs/RELEASE-CHECKLIST.md +20 -3
- package/docs/RELEASE-GATES.ko.md +35 -0
- package/docs/RELEASE-GATES.md +234 -0
- package/docs/ROADMAP.md +2232 -8
- package/docs/external-status.md +20 -7
- package/docs/inspection-20260630.md +169 -0
- package/docs/integrations/design-ai-mcp-server.md +35 -3
- package/docs/integrations/vscode-walkthrough.ko.md +3 -3
- package/docs/integrations/vscode-walkthrough.md +3 -3
- 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/docs/site-overrides/main.html +1 -1
- 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 +717 -9
- package/tools/audit/registry-smoke.py +912 -10
- package/tools/audit/release-metadata.py +47 -1
- package/tools/audit/smoke_assertions.py +998 -35
- package/tools/migrations/refs-links-to-reference-pages.py +179 -0
|
@@ -0,0 +1,444 @@
|
|
|
1
|
+
import {
|
|
2
|
+
getStageActionAffordance,
|
|
3
|
+
getStageActionButtonLabel,
|
|
4
|
+
getStageActionDisabledReason,
|
|
5
|
+
getStageActionDisabledReasonCode,
|
|
6
|
+
getStageActionEnabled,
|
|
7
|
+
getStageActionEvidenceTarget,
|
|
8
|
+
getStageActionEvidenceTargetLabel,
|
|
9
|
+
getStageActionInstruction,
|
|
10
|
+
getStageActionLabel,
|
|
11
|
+
getStageActionStatus,
|
|
12
|
+
getStageActionStatusLabel,
|
|
13
|
+
getStageActionStatusTone,
|
|
14
|
+
getStageActionType,
|
|
15
|
+
} from "./site-bundle-handoff-runbook-actions.mjs";
|
|
16
|
+
import {
|
|
17
|
+
buildEvidenceCaptureInitialValidationChecklist,
|
|
18
|
+
buildEvidenceCaptureInitialValidationChecklistSummary,
|
|
19
|
+
buildEvidenceCaptureInitialValidationDisplayMetadata,
|
|
20
|
+
buildEvidenceCaptureInitialValidationStates,
|
|
21
|
+
buildEvidenceCaptureInitialValidationSummary,
|
|
22
|
+
buildEvidenceCapturePayloadBindings,
|
|
23
|
+
buildEvidenceCapturePayloadFlatTemplate,
|
|
24
|
+
buildEvidenceCapturePayloadTemplate,
|
|
25
|
+
buildEvidenceCaptureValidationSpecs,
|
|
26
|
+
uniqueValues,
|
|
27
|
+
} from "./site-bundle-handoff-runbook-evidence.mjs";
|
|
28
|
+
import {
|
|
29
|
+
getStageActionEvidenceCaptureFields,
|
|
30
|
+
} from "./site-bundle-handoff-runbook-evidence-fields.mjs";
|
|
31
|
+
import {
|
|
32
|
+
formatBundleHandoffOperatorRunbookStageLine,
|
|
33
|
+
} from "./site-bundle-handoff-runbook-format.mjs";
|
|
34
|
+
import {
|
|
35
|
+
getStageActionBlockedStageKeys,
|
|
36
|
+
getStageActionCompletionCriteria,
|
|
37
|
+
getStageActionDependencyReason,
|
|
38
|
+
getStageActionDependencyReasonCode,
|
|
39
|
+
getStageActionEvidenceRequirements,
|
|
40
|
+
getStageActionPrerequisiteKeys,
|
|
41
|
+
getStageActionPrerequisiteLabels,
|
|
42
|
+
getStageLabel,
|
|
43
|
+
} from "./site-bundle-handoff-runbook-stage-metadata.mjs";
|
|
44
|
+
|
|
45
|
+
import { buildActionSummary } from "./site-bundle-handoff-runbook-action-summary.mjs";
|
|
46
|
+
import { buildStageHumanLineMaps } from "./site-bundle-handoff-runbook-human-lines.mjs";
|
|
47
|
+
import {
|
|
48
|
+
buildStageActionDependencyMaps,
|
|
49
|
+
buildStageActionEvidenceCaptureMaps,
|
|
50
|
+
buildStageActionEvidenceMaps,
|
|
51
|
+
buildStageActionStatusMaps,
|
|
52
|
+
buildStageExecutionMaps,
|
|
53
|
+
buildStageIdentityMaps,
|
|
54
|
+
callsExternalSystem,
|
|
55
|
+
hasCommands,
|
|
56
|
+
isManualStage,
|
|
57
|
+
isOptionalStage,
|
|
58
|
+
isRequiredStage,
|
|
59
|
+
mutatesTargetRepo,
|
|
60
|
+
usesLocalOutputRunPolicy,
|
|
61
|
+
usesReadOnlyRunPolicy,
|
|
62
|
+
} from "./site-bundle-handoff-runbook-maps.mjs";
|
|
63
|
+
import { buildNextStepState } from "./site-bundle-handoff-runbook-next-step.mjs";
|
|
64
|
+
|
|
65
|
+
export function buildBundleHandoffCommandManifest({
|
|
66
|
+
sourceBundle,
|
|
67
|
+
taskCatalog,
|
|
68
|
+
defaultTask = null,
|
|
69
|
+
selectedTask = null,
|
|
70
|
+
effectiveTask = null,
|
|
71
|
+
} = {}) {
|
|
72
|
+
const commands = [];
|
|
73
|
+
const pushCommand = (entry) => {
|
|
74
|
+
if (!entry || !entry.command || !Array.isArray(entry.commandArgs) || entry.commandArgs.length === 0) return;
|
|
75
|
+
commands.push(entry);
|
|
76
|
+
};
|
|
77
|
+
const sourceValue = (field, fallback = "") => sourceBundle?.[field] || fallback;
|
|
78
|
+
const pushSourceCommand = (key, label, commandKey, argsKey, policyKey, safetyKey) => {
|
|
79
|
+
const safety = sourceValue(safetyKey, null);
|
|
80
|
+
pushCommand({
|
|
81
|
+
key,
|
|
82
|
+
scope: "source-bundle",
|
|
83
|
+
label,
|
|
84
|
+
command: sourceValue(commandKey),
|
|
85
|
+
commandArgs: sourceValue(argsKey, []),
|
|
86
|
+
runPolicy: sourceValue(policyKey),
|
|
87
|
+
safety,
|
|
88
|
+
strict: Boolean(safety?.strict),
|
|
89
|
+
taskId: "",
|
|
90
|
+
outputFile: "",
|
|
91
|
+
defaultTask: false,
|
|
92
|
+
selectedTask: false,
|
|
93
|
+
effectiveTask: false,
|
|
94
|
+
});
|
|
95
|
+
};
|
|
96
|
+
const pushTaskCommand = (task, { strict = false } = {}) => {
|
|
97
|
+
if (!task?.id) return;
|
|
98
|
+
const commandKey = strict ? "strictHandoffCommand" : "handoffCommand";
|
|
99
|
+
const argsKey = strict ? "strictHandoffCommandArgs" : "handoffCommandArgs";
|
|
100
|
+
const policyKey = strict ? "strictHandoffCommandRunPolicy" : "handoffCommandRunPolicy";
|
|
101
|
+
const safetyKey = strict ? "strictHandoffCommandSafety" : "handoffCommandSafety";
|
|
102
|
+
const taskValue = (field, fallback = "") => task[field] || fallback;
|
|
103
|
+
const safety = taskValue(safetyKey, null);
|
|
104
|
+
pushCommand({
|
|
105
|
+
key: `task.${task.id}.handoff.${strict ? "strict" : "default"}`,
|
|
106
|
+
scope: "task-handoff",
|
|
107
|
+
label: `${strict ? "Strict " : ""}Task handoff: ${task.id}`,
|
|
108
|
+
command: taskValue(commandKey),
|
|
109
|
+
commandArgs: taskValue(argsKey, []),
|
|
110
|
+
runPolicy: taskValue(policyKey),
|
|
111
|
+
safety,
|
|
112
|
+
strict,
|
|
113
|
+
taskId: task.id,
|
|
114
|
+
taskNumber: Number.isInteger(task.number) ? task.number : null,
|
|
115
|
+
outputFile: task.handoffOutFile || safety?.outputFile || "",
|
|
116
|
+
defaultTask: task.id === defaultTask?.id,
|
|
117
|
+
selectedTask: task.id === selectedTask?.id,
|
|
118
|
+
effectiveTask: task.id === effectiveTask?.id,
|
|
119
|
+
});
|
|
120
|
+
};
|
|
121
|
+
|
|
122
|
+
pushSourceCommand("source.bundleCheck", "Bundle check JSON", "checkCommand", "checkCommandArgs", "checkCommandRunPolicy", "checkCommandSafety");
|
|
123
|
+
pushSourceCommand("source.bundleCheck.strict", "Strict bundle check JSON", "strictCheckCommand", "strictCheckCommandArgs", "strictCheckCommandRunPolicy", "strictCheckCommandSafety");
|
|
124
|
+
pushSourceCommand("source.bundleHandoff", "Bundle handoff JSON", "handoffCommand", "handoffCommandArgs", "handoffCommandRunPolicy", "handoffCommandSafety");
|
|
125
|
+
pushSourceCommand("source.bundleHandoff.strict", "Strict bundle handoff JSON", "strictHandoffCommand", "strictHandoffCommandArgs", "strictHandoffCommandRunPolicy", "strictHandoffCommandSafety");
|
|
126
|
+
for (const task of taskCatalog?.items || []) {
|
|
127
|
+
pushTaskCommand(task);
|
|
128
|
+
pushTaskCommand(task, { strict: true });
|
|
129
|
+
}
|
|
130
|
+
|
|
131
|
+
const countBy = (predicate) => commands.filter(predicate).length;
|
|
132
|
+
const isSourceBundleCommand = (command) => command.scope === "source-bundle";
|
|
133
|
+
const isTaskHandoffCommand = (command) => command.scope === "task-handoff";
|
|
134
|
+
const usesReadOnlyRunPolicy = (command) => command.runPolicy === "read-only";
|
|
135
|
+
const usesLocalOutputRunPolicy = (command) => command.runPolicy === "writes-local-file";
|
|
136
|
+
const hasExternalCallSafety = (command) => command.safety?.externalCalls === true;
|
|
137
|
+
const hasTargetRepoMutationSafety = (command) => command.safety?.targetRepoMutation === true;
|
|
138
|
+
const requiresCleanWorkspaceSafety = (command) => command.safety?.requiresCleanWorkspace === true;
|
|
139
|
+
const requiresReviewBeforeMutationSafety = (command) => command.safety?.requiresReviewBeforeMutation === true;
|
|
140
|
+
const effectiveTaskId = effectiveTask?.id || "";
|
|
141
|
+
const selectedTaskId = selectedTask?.id || "";
|
|
142
|
+
const defaultTaskId = defaultTask?.id || "";
|
|
143
|
+
const manifestCountSummary = {
|
|
144
|
+
commandCount: commands.length,
|
|
145
|
+
sourceCommandCount: countBy(isSourceBundleCommand),
|
|
146
|
+
taskCommandCount: countBy(isTaskHandoffCommand),
|
|
147
|
+
readOnlyCount: countBy(usesReadOnlyRunPolicy),
|
|
148
|
+
localOutputFileCount: countBy(usesLocalOutputRunPolicy),
|
|
149
|
+
externalCallCount: countBy(hasExternalCallSafety),
|
|
150
|
+
targetRepoMutationCount: countBy(hasTargetRepoMutationSafety),
|
|
151
|
+
requiresCleanWorkspaceCount: countBy(requiresCleanWorkspaceSafety),
|
|
152
|
+
requiresReviewBeforeMutationCount: countBy(requiresReviewBeforeMutationSafety),
|
|
153
|
+
};
|
|
154
|
+
const manifestTaskSelection = {
|
|
155
|
+
defaultTaskId,
|
|
156
|
+
selectedTaskId,
|
|
157
|
+
effectiveTaskId,
|
|
158
|
+
};
|
|
159
|
+
const manifestStrictCommandKeys = {
|
|
160
|
+
defaultStrictTaskCommandKey: defaultTaskId ? `task.${defaultTaskId}.handoff.strict` : "",
|
|
161
|
+
selectedStrictTaskCommandKey: selectedTaskId ? `task.${selectedTaskId}.handoff.strict` : "",
|
|
162
|
+
effectiveStrictTaskCommandKey: effectiveTaskId ? `task.${effectiveTaskId}.handoff.strict` : "",
|
|
163
|
+
};
|
|
164
|
+
return {
|
|
165
|
+
version: 1,
|
|
166
|
+
source: "bundle-handoff",
|
|
167
|
+
...manifestCountSummary,
|
|
168
|
+
...manifestTaskSelection,
|
|
169
|
+
...manifestStrictCommandKeys,
|
|
170
|
+
commands,
|
|
171
|
+
};
|
|
172
|
+
}
|
|
173
|
+
|
|
174
|
+
export function buildBundleHandoffOperatorRunbook(commandManifest) {
|
|
175
|
+
const commands = Array.isArray(commandManifest?.commands) ? commandManifest.commands : [];
|
|
176
|
+
const commandByKey = new Map(commands.map((command) => [command.key, command]));
|
|
177
|
+
const buildStage = ({
|
|
178
|
+
step,
|
|
179
|
+
key,
|
|
180
|
+
label,
|
|
181
|
+
kind,
|
|
182
|
+
required,
|
|
183
|
+
commandKeys = [],
|
|
184
|
+
reason,
|
|
185
|
+
manual = false,
|
|
186
|
+
}) => {
|
|
187
|
+
const stageCommands = commandKeys
|
|
188
|
+
.map((commandKey) => commandByKey.get(commandKey))
|
|
189
|
+
.filter(Boolean);
|
|
190
|
+
const firstCommand = stageCommands[0] || null;
|
|
191
|
+
const firstCommandSafety = firstCommand?.safety || null;
|
|
192
|
+
const commandHasSafetyFlag = (command, field) => command.safety?.[field] === true;
|
|
193
|
+
const commandCount = stageCommands.length;
|
|
194
|
+
const stageIdentity = {
|
|
195
|
+
step,
|
|
196
|
+
key,
|
|
197
|
+
label,
|
|
198
|
+
kind,
|
|
199
|
+
required,
|
|
200
|
+
};
|
|
201
|
+
const stageCommandSummary = {
|
|
202
|
+
commandKeys,
|
|
203
|
+
commands: stageCommands,
|
|
204
|
+
commandCount,
|
|
205
|
+
runPolicy: manual ? "manual-target-repo" : (firstCommand?.runPolicy || ""),
|
|
206
|
+
safetyLevel: manual ? "operator-controlled-target-repo" : (firstCommandSafety?.safetyLevel || ""),
|
|
207
|
+
};
|
|
208
|
+
const stageSafetySummary = {
|
|
209
|
+
writesLocalFile: stageCommands.some((command) => commandHasSafetyFlag(command, "writesLocalFile")),
|
|
210
|
+
outputFiles: stageCommands.map((command) => command.outputFile).filter(Boolean),
|
|
211
|
+
externalCalls: stageCommands.some((command) => commandHasSafetyFlag(command, "externalCalls")),
|
|
212
|
+
targetRepoMutation: stageCommands.some((command) => commandHasSafetyFlag(command, "targetRepoMutation")),
|
|
213
|
+
};
|
|
214
|
+
return {
|
|
215
|
+
...stageIdentity,
|
|
216
|
+
...stageCommandSummary,
|
|
217
|
+
...stageSafetySummary,
|
|
218
|
+
reason,
|
|
219
|
+
};
|
|
220
|
+
};
|
|
221
|
+
const effectiveStrictTaskCommandKey = commandManifest?.effectiveStrictTaskCommandKey || "";
|
|
222
|
+
const stages = [
|
|
223
|
+
buildStage({
|
|
224
|
+
step: 1,
|
|
225
|
+
key: "verifySourceBundle",
|
|
226
|
+
label: "Verify source bundle integrity",
|
|
227
|
+
kind: "read-only-gate",
|
|
228
|
+
required: true,
|
|
229
|
+
commandKeys: ["source.bundleCheck.strict"],
|
|
230
|
+
reason: "Confirm the bundle still matches its checksum and generated-file contract before handoff execution.",
|
|
231
|
+
}),
|
|
232
|
+
buildStage({
|
|
233
|
+
step: 2,
|
|
234
|
+
key: "refreshHandoffSnapshot",
|
|
235
|
+
label: "Refresh strict handoff JSON snapshot",
|
|
236
|
+
kind: "read-only-preview",
|
|
237
|
+
required: false,
|
|
238
|
+
commandKeys: ["source.bundleHandoff.strict"],
|
|
239
|
+
reason: "Regenerate the machine-readable handoff snapshot when a wrapper or GUI needs the latest JSON contract.",
|
|
240
|
+
}),
|
|
241
|
+
buildStage({
|
|
242
|
+
step: 3,
|
|
243
|
+
key: "writeEffectiveTaskPrompt",
|
|
244
|
+
label: "Write effective task handoff prompt",
|
|
245
|
+
kind: "local-output",
|
|
246
|
+
required: true,
|
|
247
|
+
commandKeys: effectiveStrictTaskCommandKey ? [effectiveStrictTaskCommandKey] : [],
|
|
248
|
+
reason: "Create the selected task prompt as a local file before moving into the target website repository.",
|
|
249
|
+
}),
|
|
250
|
+
buildStage({
|
|
251
|
+
step: 4,
|
|
252
|
+
key: "executeInTargetRepo",
|
|
253
|
+
label: "Execute the task in the target website repo",
|
|
254
|
+
kind: "manual-target-repo",
|
|
255
|
+
required: true,
|
|
256
|
+
manual: true,
|
|
257
|
+
reason: "Open the generated task prompt in the target repo, inspect architecture first, then implement and verify there.",
|
|
258
|
+
}),
|
|
259
|
+
buildStage({
|
|
260
|
+
step: 5,
|
|
261
|
+
key: "recordEvidence",
|
|
262
|
+
label: "Record implementation evidence",
|
|
263
|
+
kind: "manual-reporting",
|
|
264
|
+
required: true,
|
|
265
|
+
manual: true,
|
|
266
|
+
reason: "Return changed files, verification commands, browser/viewport checks, remaining risks, and the bundle digest.",
|
|
267
|
+
}),
|
|
268
|
+
];
|
|
269
|
+
const commandStages = stages.filter(hasCommands);
|
|
270
|
+
const stageActionRows = stages.map((stage) => {
|
|
271
|
+
const prerequisiteKeys = getStageActionPrerequisiteKeys(stage);
|
|
272
|
+
const blockedStageKeys = getStageActionBlockedStageKeys(stage, stages);
|
|
273
|
+
const completionCriteria = getStageActionCompletionCriteria(stage);
|
|
274
|
+
const evidenceRequirements = getStageActionEvidenceRequirements(stage);
|
|
275
|
+
const evidenceCaptureFields = getStageActionEvidenceCaptureFields(stage);
|
|
276
|
+
const evidenceFieldValues = (field) => evidenceCaptureFields.map((evidenceField) => evidenceField[field]);
|
|
277
|
+
const evidenceCaptureSectionKeys = uniqueValues(evidenceFieldValues("sectionKey"));
|
|
278
|
+
const evidenceCaptureSectionLabels = uniqueValues(evidenceFieldValues("sectionLabel"));
|
|
279
|
+
const evidenceCapturePayloadNamespaces = uniqueValues(evidenceFieldValues("payloadNamespace"));
|
|
280
|
+
const requiredEvidenceCaptureFields = evidenceCaptureFields.filter((field) => field.required);
|
|
281
|
+
const optionalEvidenceCaptureFields = evidenceCaptureFields.filter((field) => !field.required);
|
|
282
|
+
const actionEvidenceSummary = {
|
|
283
|
+
actionEvidenceRequirements: evidenceRequirements,
|
|
284
|
+
actionEvidenceRequirementCount: evidenceRequirements.length,
|
|
285
|
+
actionRequiresEvidence: evidenceRequirements.length > 0,
|
|
286
|
+
actionEvidenceTarget: getStageActionEvidenceTarget(stage),
|
|
287
|
+
actionEvidenceTargetLabel: getStageActionEvidenceTargetLabel(stage),
|
|
288
|
+
};
|
|
289
|
+
const actionIdentity = {
|
|
290
|
+
step: stage.step,
|
|
291
|
+
key: stage.key,
|
|
292
|
+
label: stage.label,
|
|
293
|
+
};
|
|
294
|
+
const actionStatusSummary = {
|
|
295
|
+
actionType: getStageActionType(stage),
|
|
296
|
+
actionLabel: getStageActionLabel(stage),
|
|
297
|
+
actionInstruction: getStageActionInstruction(stage),
|
|
298
|
+
actionButtonLabel: getStageActionButtonLabel(stage),
|
|
299
|
+
actionAffordance: getStageActionAffordance(stage),
|
|
300
|
+
actionEnabled: getStageActionEnabled(stage),
|
|
301
|
+
actionStatus: getStageActionStatus(stage),
|
|
302
|
+
actionStatusLabel: getStageActionStatusLabel(stage),
|
|
303
|
+
actionStatusTone: getStageActionStatusTone(stage),
|
|
304
|
+
actionDisabledReasonCode: getStageActionDisabledReasonCode(stage),
|
|
305
|
+
actionDisabledReason: getStageActionDisabledReason(stage),
|
|
306
|
+
};
|
|
307
|
+
const actionDependencySummary = {
|
|
308
|
+
actionPrerequisiteKeys: prerequisiteKeys,
|
|
309
|
+
actionPrerequisiteLabels: getStageActionPrerequisiteLabels(stage, stages),
|
|
310
|
+
actionPrerequisiteCount: prerequisiteKeys.length,
|
|
311
|
+
actionHasPrerequisites: prerequisiteKeys.length > 0,
|
|
312
|
+
actionDependencyReasonCode: getStageActionDependencyReasonCode(stage),
|
|
313
|
+
actionDependencyReason: getStageActionDependencyReason(stage),
|
|
314
|
+
actionBlockedStageKeys: blockedStageKeys,
|
|
315
|
+
actionBlockedStageLabels: blockedStageKeys.map((stageKey) => getStageLabel(stages, stageKey)),
|
|
316
|
+
actionBlockedStageCount: blockedStageKeys.length,
|
|
317
|
+
actionBlocksStages: blockedStageKeys.length > 0,
|
|
318
|
+
actionCompletionCriteria: completionCriteria,
|
|
319
|
+
actionCompletionCriteriaCount: completionCriteria.length,
|
|
320
|
+
actionHasCompletionCriteria: completionCriteria.length > 0,
|
|
321
|
+
};
|
|
322
|
+
const actionEvidenceCaptureSummary = {
|
|
323
|
+
actionEvidenceCaptureFields: evidenceCaptureFields,
|
|
324
|
+
actionEvidenceCaptureFieldKeys: evidenceFieldValues("key"),
|
|
325
|
+
actionEvidenceCaptureFieldLabels: evidenceFieldValues("label"),
|
|
326
|
+
actionEvidenceCaptureFieldPlaceholders: evidenceFieldValues("placeholder"),
|
|
327
|
+
actionEvidenceCaptureFieldRequirementLabels: evidenceFieldValues("requirementLabel"),
|
|
328
|
+
actionEvidenceCaptureFieldAriaLabels: evidenceFieldValues("ariaLabel"),
|
|
329
|
+
actionEvidenceCaptureFieldHelpTexts: evidenceFieldValues("helpText"),
|
|
330
|
+
actionEvidenceCaptureFieldSectionKeys: evidenceFieldValues("sectionKey"),
|
|
331
|
+
actionEvidenceCaptureFieldSectionLabels: evidenceFieldValues("sectionLabel"),
|
|
332
|
+
actionEvidenceCaptureSectionKeys: evidenceCaptureSectionKeys,
|
|
333
|
+
actionEvidenceCaptureSectionLabels: evidenceCaptureSectionLabels,
|
|
334
|
+
actionEvidenceCaptureSectionCount: evidenceCaptureSectionKeys.length,
|
|
335
|
+
actionEvidenceCaptureFieldPayloadNamespaces: evidenceFieldValues("payloadNamespace"),
|
|
336
|
+
actionEvidenceCaptureFieldPayloadPaths: evidenceFieldValues("payloadPath"),
|
|
337
|
+
actionEvidenceCapturePayloadNamespaces: evidenceCapturePayloadNamespaces,
|
|
338
|
+
actionEvidenceCapturePayloadNamespaceCount: evidenceCapturePayloadNamespaces.length,
|
|
339
|
+
actionEvidenceCapturePayloadTemplate: buildEvidenceCapturePayloadTemplate(evidenceCaptureFields),
|
|
340
|
+
actionEvidenceCapturePayloadFlatTemplate: buildEvidenceCapturePayloadFlatTemplate(evidenceCaptureFields),
|
|
341
|
+
actionEvidenceCapturePayloadBindings: buildEvidenceCapturePayloadBindings(evidenceCaptureFields),
|
|
342
|
+
actionEvidenceCaptureValidationSpecs: buildEvidenceCaptureValidationSpecs(evidenceCaptureFields),
|
|
343
|
+
actionEvidenceCaptureInitialValidationStates: buildEvidenceCaptureInitialValidationStates(evidenceCaptureFields),
|
|
344
|
+
actionEvidenceCaptureInitialValidationDisplayMetadata: buildEvidenceCaptureInitialValidationDisplayMetadata(evidenceCaptureFields),
|
|
345
|
+
actionEvidenceCaptureInitialValidationChecklist: buildEvidenceCaptureInitialValidationChecklist(evidenceCaptureFields),
|
|
346
|
+
actionEvidenceCaptureInitialValidationChecklistSummary: buildEvidenceCaptureInitialValidationChecklistSummary(evidenceCaptureFields),
|
|
347
|
+
actionEvidenceCaptureInitialValidationSummary: buildEvidenceCaptureInitialValidationSummary(evidenceCaptureFields),
|
|
348
|
+
actionEvidenceCaptureFieldInputTypes: evidenceFieldValues("inputType"),
|
|
349
|
+
actionEvidenceCaptureFieldValueShapes: evidenceFieldValues("valueShape"),
|
|
350
|
+
actionEvidenceCaptureFieldAcceptsMultiple: evidenceFieldValues("acceptsMultiple"),
|
|
351
|
+
actionEvidenceCaptureFieldDefaultValues: evidenceFieldValues("defaultValue"),
|
|
352
|
+
actionEvidenceCaptureFieldEmptyValues: evidenceFieldValues("emptyValue"),
|
|
353
|
+
actionEvidenceCaptureFieldValidationRules: evidenceFieldValues("validationRule"),
|
|
354
|
+
actionEvidenceCaptureFieldMinLengths: evidenceFieldValues("minLength"),
|
|
355
|
+
actionEvidenceCaptureFieldExamples: evidenceFieldValues("example"),
|
|
356
|
+
actionEvidenceCaptureFieldValidationHints: evidenceFieldValues("validationHint"),
|
|
357
|
+
actionRequiredEvidenceCaptureFieldKeys: requiredEvidenceCaptureFields.map((field) => field.key),
|
|
358
|
+
actionOptionalEvidenceCaptureFieldKeys: optionalEvidenceCaptureFields.map((field) => field.key),
|
|
359
|
+
actionEvidenceCaptureFieldCount: evidenceCaptureFields.length,
|
|
360
|
+
actionRequiredEvidenceCaptureFieldCount: requiredEvidenceCaptureFields.length,
|
|
361
|
+
actionOptionalEvidenceCaptureFieldCount: optionalEvidenceCaptureFields.length,
|
|
362
|
+
actionHasEvidenceCaptureFields: evidenceCaptureFields.length > 0,
|
|
363
|
+
};
|
|
364
|
+
const actionExecutionSummary = {
|
|
365
|
+
required: stage.required,
|
|
366
|
+
runPolicy: stage.runPolicy,
|
|
367
|
+
safetyLevel: stage.safetyLevel,
|
|
368
|
+
commandKeys: stage.commandKeys,
|
|
369
|
+
commandCount: stage.commandCount,
|
|
370
|
+
outputFiles: stage.outputFiles,
|
|
371
|
+
manual: isManualStage(stage),
|
|
372
|
+
writesLocalFile: stage.writesLocalFile,
|
|
373
|
+
externalCalls: stage.externalCalls,
|
|
374
|
+
targetRepoMutation: stage.targetRepoMutation,
|
|
375
|
+
};
|
|
376
|
+
|
|
377
|
+
return {
|
|
378
|
+
...actionIdentity,
|
|
379
|
+
...actionStatusSummary,
|
|
380
|
+
...actionDependencySummary,
|
|
381
|
+
...actionEvidenceSummary,
|
|
382
|
+
...actionEvidenceCaptureSummary,
|
|
383
|
+
...actionExecutionSummary,
|
|
384
|
+
};
|
|
385
|
+
});
|
|
386
|
+
const stageIdentityMaps = buildStageIdentityMaps(stages);
|
|
387
|
+
const stageActionStatusMaps = buildStageActionStatusMaps(stageActionRows);
|
|
388
|
+
const stageActionDependencyMaps = buildStageActionDependencyMaps(stageActionRows);
|
|
389
|
+
const stageActionEvidenceMaps = buildStageActionEvidenceMaps(stageActionRows);
|
|
390
|
+
const stageActionEvidenceCaptureMaps = buildStageActionEvidenceCaptureMaps(stageActionRows);
|
|
391
|
+
const stageHumanLineMaps = buildStageHumanLineMaps(
|
|
392
|
+
stages,
|
|
393
|
+
stageActionRows,
|
|
394
|
+
stageActionEvidenceCaptureMaps.stageActionEvidenceCaptureInitialValidationChecklistSummaryByKey,
|
|
395
|
+
);
|
|
396
|
+
const stageExecutionMaps = buildStageExecutionMaps(stages);
|
|
397
|
+
const { nextActionSummary, nextStepSummary } = buildNextStepState({
|
|
398
|
+
stageByKey: stageIdentityMaps.stageByKey,
|
|
399
|
+
commandByKey,
|
|
400
|
+
stageActionRows,
|
|
401
|
+
stageHumanLineByKey: stageHumanLineMaps.stageHumanLineByKey,
|
|
402
|
+
stageHumanLineDisplayRowByKey: stageHumanLineMaps.stageHumanLineDisplayRowByKey,
|
|
403
|
+
});
|
|
404
|
+
const actionSummary = buildActionSummary({
|
|
405
|
+
stages,
|
|
406
|
+
commandStages,
|
|
407
|
+
stageActionRows,
|
|
408
|
+
stageHumanLineMaps,
|
|
409
|
+
nextActionSummary,
|
|
410
|
+
});
|
|
411
|
+
const countBy = (predicate) => stages.filter(predicate).length;
|
|
412
|
+
const runbookCountSummary = {
|
|
413
|
+
stageCount: stages.length,
|
|
414
|
+
commandStageCount: commandStages.length,
|
|
415
|
+
manualStageCount: countBy(isManualStage),
|
|
416
|
+
requiredStageCount: countBy(isRequiredStage),
|
|
417
|
+
optionalStageCount: countBy(isOptionalStage),
|
|
418
|
+
readOnlyCommandStageCount: countBy(usesReadOnlyRunPolicy),
|
|
419
|
+
localOutputCommandStageCount: countBy(usesLocalOutputRunPolicy),
|
|
420
|
+
externalCallCommandStageCount: countBy(callsExternalSystem),
|
|
421
|
+
targetRepoMutationCommandStageCount: countBy(mutatesTargetRepo),
|
|
422
|
+
effectiveTaskId: commandManifest?.effectiveTaskId || "",
|
|
423
|
+
effectiveStrictTaskCommandKey,
|
|
424
|
+
};
|
|
425
|
+
return {
|
|
426
|
+
version: 1,
|
|
427
|
+
source: "bundle-handoff",
|
|
428
|
+
...runbookCountSummary,
|
|
429
|
+
...stageIdentityMaps,
|
|
430
|
+
...stageHumanLineMaps,
|
|
431
|
+
...stageActionStatusMaps,
|
|
432
|
+
...stageActionDependencyMaps,
|
|
433
|
+
...stageActionEvidenceMaps,
|
|
434
|
+
...stageActionEvidenceCaptureMaps,
|
|
435
|
+
actionSummary,
|
|
436
|
+
...stageExecutionMaps,
|
|
437
|
+
...nextStepSummary,
|
|
438
|
+
stages,
|
|
439
|
+
};
|
|
440
|
+
}
|
|
441
|
+
|
|
442
|
+
export {
|
|
443
|
+
formatBundleHandoffOperatorRunbookLines,
|
|
444
|
+
} from "./site-bundle-handoff-runbook-format.mjs";
|
|
@@ -0,0 +1,183 @@
|
|
|
1
|
+
import {
|
|
2
|
+
buildBundleCheckCommand,
|
|
3
|
+
buildBundleCheckCommandArgs,
|
|
4
|
+
buildBundleHandoffCommand,
|
|
5
|
+
buildBundleHandoffCommandArgs,
|
|
6
|
+
buildBundleSourceCommandSafety,
|
|
7
|
+
buildBundleTaskHandoffCommand,
|
|
8
|
+
buildBundleTaskHandoffCommandArgs,
|
|
9
|
+
buildBundleTaskHandoffCommandSafety,
|
|
10
|
+
taskHandoffOutFile,
|
|
11
|
+
} from "./site-bundle-commands.mjs";
|
|
12
|
+
import { orderedRefactorTasks } from "./site-prompts.mjs";
|
|
13
|
+
import { normalizeStringArray } from "./site-strings.mjs";
|
|
14
|
+
|
|
15
|
+
export const SITE_TARGET_REPO_EXECUTION_CHECKLIST = [
|
|
16
|
+
{
|
|
17
|
+
id: "confirm-target-repo",
|
|
18
|
+
label: "Confirm target repo working directory",
|
|
19
|
+
required: true,
|
|
20
|
+
evidence: "State the target repo path and confirm it is not the design-ai repo before editing.",
|
|
21
|
+
},
|
|
22
|
+
{
|
|
23
|
+
id: "inspect-architecture",
|
|
24
|
+
label: "Inspect existing architecture and design system",
|
|
25
|
+
required: true,
|
|
26
|
+
evidence: "Name the routing, component, styling, token, and test/build surfaces inspected before implementation.",
|
|
27
|
+
},
|
|
28
|
+
{
|
|
29
|
+
id: "apply-focused-task",
|
|
30
|
+
label: "Apply one focused Website Improvement task",
|
|
31
|
+
required: true,
|
|
32
|
+
evidence: "Identify the completed task id/title, changed files, and why the scope stayed limited.",
|
|
33
|
+
},
|
|
34
|
+
{
|
|
35
|
+
id: "verify-quality-gates",
|
|
36
|
+
label: "Run target repo quality gates",
|
|
37
|
+
required: true,
|
|
38
|
+
evidence: "Record lint/typecheck/build/test results plus browser, viewport, accessibility, and deployment checks that were available.",
|
|
39
|
+
},
|
|
40
|
+
{
|
|
41
|
+
id: "record-handoff-evidence",
|
|
42
|
+
label: "Record implementation evidence and remaining risks",
|
|
43
|
+
required: true,
|
|
44
|
+
evidence: "Return executed work, verification results, remaining risks, next actions, and the bundle digest used.",
|
|
45
|
+
},
|
|
46
|
+
];
|
|
47
|
+
|
|
48
|
+
function summarizeBundleTaskItem(task, index, directory) {
|
|
49
|
+
return {
|
|
50
|
+
number: index + 1,
|
|
51
|
+
id: task.id,
|
|
52
|
+
title: task.title,
|
|
53
|
+
category: task.category,
|
|
54
|
+
priority: task.priority,
|
|
55
|
+
impact: task.impact,
|
|
56
|
+
effort: task.effort,
|
|
57
|
+
pages: normalizeStringArray(task.pages),
|
|
58
|
+
recommendedMcp: normalizeStringArray(task.recommendedMcp),
|
|
59
|
+
handoffTaskArg: task.id,
|
|
60
|
+
handoffOutFile: taskHandoffOutFile(task),
|
|
61
|
+
handoffCommand: buildBundleTaskHandoffCommand(directory, task),
|
|
62
|
+
handoffCommandArgs: buildBundleTaskHandoffCommandArgs(directory, task),
|
|
63
|
+
handoffCommandRunPolicy: "writes-local-file",
|
|
64
|
+
handoffCommandSafety: buildBundleTaskHandoffCommandSafety(task),
|
|
65
|
+
strictHandoffCommand: buildBundleTaskHandoffCommand(directory, task, { strict: true }),
|
|
66
|
+
strictHandoffCommandArgs: buildBundleTaskHandoffCommandArgs(directory, task, { strict: true }),
|
|
67
|
+
strictHandoffCommandRunPolicy: "writes-local-file",
|
|
68
|
+
strictHandoffCommandSafety: buildBundleTaskHandoffCommandSafety(task, { strict: true }),
|
|
69
|
+
};
|
|
70
|
+
}
|
|
71
|
+
|
|
72
|
+
export function summarizeBundleTaskCatalog(workspace, directory, selectedTask = null) {
|
|
73
|
+
const items = orderedRefactorTasks(workspace).map((task, index) => summarizeBundleTaskItem(task, index, directory));
|
|
74
|
+
const selectedTaskId = selectedTask?.id || "";
|
|
75
|
+
return {
|
|
76
|
+
source: "website-workspace.tasks.json",
|
|
77
|
+
count: items.length,
|
|
78
|
+
defaultTaskId: items[0]?.id || "",
|
|
79
|
+
selectedTaskId,
|
|
80
|
+
selectionMode: selectedTaskId ? "explicit" : "bundled-default",
|
|
81
|
+
items,
|
|
82
|
+
};
|
|
83
|
+
}
|
|
84
|
+
|
|
85
|
+
export function emptyBundleTaskCatalog(error = "") {
|
|
86
|
+
return {
|
|
87
|
+
source: "website-workspace.tasks.json",
|
|
88
|
+
count: 0,
|
|
89
|
+
defaultTaskId: "",
|
|
90
|
+
selectedTaskId: "",
|
|
91
|
+
selectionMode: "unavailable",
|
|
92
|
+
items: [],
|
|
93
|
+
error,
|
|
94
|
+
};
|
|
95
|
+
}
|
|
96
|
+
|
|
97
|
+
export function summarizeSelectedTask(task, taskSelector, source, directory = "") {
|
|
98
|
+
if (!task) return null;
|
|
99
|
+
return {
|
|
100
|
+
id: task.id,
|
|
101
|
+
title: task.title,
|
|
102
|
+
category: task.category,
|
|
103
|
+
priority: task.priority,
|
|
104
|
+
impact: task.impact,
|
|
105
|
+
effort: task.effort,
|
|
106
|
+
selector: String(taskSelector || "").trim(),
|
|
107
|
+
source,
|
|
108
|
+
handoffTaskArg: task.id,
|
|
109
|
+
handoffOutFile: taskHandoffOutFile(task),
|
|
110
|
+
handoffCommand: directory ? buildBundleTaskHandoffCommand(directory, task) : "",
|
|
111
|
+
handoffCommandArgs: directory ? buildBundleTaskHandoffCommandArgs(directory, task) : [],
|
|
112
|
+
handoffCommandRunPolicy: directory ? "writes-local-file" : "",
|
|
113
|
+
handoffCommandSafety: directory ? buildBundleTaskHandoffCommandSafety(task) : null,
|
|
114
|
+
strictHandoffCommand: directory ? buildBundleTaskHandoffCommand(directory, task, { strict: true }) : "",
|
|
115
|
+
strictHandoffCommandArgs: directory ? buildBundleTaskHandoffCommandArgs(directory, task, { strict: true }) : [],
|
|
116
|
+
strictHandoffCommandRunPolicy: directory ? "writes-local-file" : "",
|
|
117
|
+
strictHandoffCommandSafety: directory ? buildBundleTaskHandoffCommandSafety(task, { strict: true }) : null,
|
|
118
|
+
};
|
|
119
|
+
}
|
|
120
|
+
|
|
121
|
+
export function formatBundleHandoffTaskCatalogLines(taskCatalog) {
|
|
122
|
+
if (!taskCatalog || !Array.isArray(taskCatalog.items) || taskCatalog.items.length === 0) {
|
|
123
|
+
const reason = taskCatalog?.error ? ` ${taskCatalog.error}` : "";
|
|
124
|
+
return [`- No bundle task catalog is available.${reason}`];
|
|
125
|
+
}
|
|
126
|
+
return taskCatalog.items.map((task) => {
|
|
127
|
+
const pages = task.pages.length ? task.pages.join(", ") : "all pages";
|
|
128
|
+
const mcps = task.recommendedMcp.length ? task.recommendedMcp.join(", ") : "none";
|
|
129
|
+
const command = task.strictHandoffCommand || task.handoffCommand || `design-ai site <bundle-dir> --bundle-handoff --task ${task.handoffTaskArg}`;
|
|
130
|
+
return `- ${task.number}. [${task.priority}/${task.impact}/${task.effort}] ${task.id}: ${task.title} (pages: ${pages}; MCP: ${mcps}; command: \`${command}\`)`;
|
|
131
|
+
});
|
|
132
|
+
}
|
|
133
|
+
|
|
134
|
+
export function formatBundleHandoffIssueLines(issues) {
|
|
135
|
+
const actionable = issues.filter((issue) => issue.level !== "pass");
|
|
136
|
+
if (actionable.length === 0) return "- No blocking bundle-check issues were found.";
|
|
137
|
+
return actionable.map((issue) => `- [${issue.level}] ${issue.id}: ${issue.message}`).join("\n");
|
|
138
|
+
}
|
|
139
|
+
|
|
140
|
+
export function buildSiteBundleHandoffBoundaries(checkReport) {
|
|
141
|
+
return Array.from(new Set([
|
|
142
|
+
...normalizeStringArray(checkReport?.boundaries),
|
|
143
|
+
"target-repo-work-after-handoff",
|
|
144
|
+
]));
|
|
145
|
+
}
|
|
146
|
+
|
|
147
|
+
export function summarizeSiteBundleHandoffSource(checkReport) {
|
|
148
|
+
return {
|
|
149
|
+
directory: checkReport.directory,
|
|
150
|
+
sourceWorkspace: checkReport.summary.source || "",
|
|
151
|
+
siteName: checkReport.summary.siteName || "",
|
|
152
|
+
status: checkReport.status,
|
|
153
|
+
valid: checkReport.valid,
|
|
154
|
+
workspaceStatus: checkReport.workspaceStatus || "unknown",
|
|
155
|
+
mcpStatus: checkReport.mcpStatus || "unknown",
|
|
156
|
+
mcpProbeStatus: checkReport.mcpProbeStatus || "unknown",
|
|
157
|
+
checksumAlgorithm: checkReport.summary.checksumAlgorithm || "",
|
|
158
|
+
checksumBundleDigest: checkReport.summary.checksumBundleDigest || "",
|
|
159
|
+
verifiedChecksumFiles: checkReport.counts.verifiedChecksumFiles,
|
|
160
|
+
expectedChecksumFiles: checkReport.counts.expectedChecksumFiles,
|
|
161
|
+
verifiedGeneratedFiles: checkReport.counts.verifiedGeneratedFiles,
|
|
162
|
+
expectedGeneratedFiles: checkReport.counts.expectedGeneratedFiles,
|
|
163
|
+
issueCount: checkReport.issues.length,
|
|
164
|
+
warningCount: checkReport.counts.warnings,
|
|
165
|
+
failureCount: checkReport.counts.failures,
|
|
166
|
+
checkCommand: buildBundleCheckCommand(checkReport.directory),
|
|
167
|
+
checkCommandArgs: buildBundleCheckCommandArgs(checkReport.directory),
|
|
168
|
+
checkCommandRunPolicy: "read-only",
|
|
169
|
+
checkCommandSafety: buildBundleSourceCommandSafety(),
|
|
170
|
+
strictCheckCommand: buildBundleCheckCommand(checkReport.directory, { strict: true }),
|
|
171
|
+
strictCheckCommandArgs: buildBundleCheckCommandArgs(checkReport.directory, { strict: true }),
|
|
172
|
+
strictCheckCommandRunPolicy: "read-only",
|
|
173
|
+
strictCheckCommandSafety: buildBundleSourceCommandSafety({ strict: true }),
|
|
174
|
+
handoffCommand: buildBundleHandoffCommand(checkReport.directory),
|
|
175
|
+
handoffCommandArgs: buildBundleHandoffCommandArgs(checkReport.directory),
|
|
176
|
+
handoffCommandRunPolicy: "read-only",
|
|
177
|
+
handoffCommandSafety: buildBundleSourceCommandSafety(),
|
|
178
|
+
strictHandoffCommand: buildBundleHandoffCommand(checkReport.directory, { strict: true }),
|
|
179
|
+
strictHandoffCommandArgs: buildBundleHandoffCommandArgs(checkReport.directory, { strict: true }),
|
|
180
|
+
strictHandoffCommandRunPolicy: "read-only",
|
|
181
|
+
strictHandoffCommandSafety: buildBundleSourceCommandSafety({ strict: true }),
|
|
182
|
+
};
|
|
183
|
+
}
|