@pellux/goodvibes-agent 1.1.7 → 1.3.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/CHANGELOG.md +329 -0
- package/README.md +46 -30
- package/dist/package/{ast-grep-napi.linux-x64-gnu-mkk8xwww.node → ast-grep-napi.linux-x64-gnu-swtppvy9.node} +0 -0
- package/dist/package/{ast-grep-napi.linux-x64-musl-ryqtgdv6.node → ast-grep-napi.linux-x64-musl-ttfcdtap.node} +0 -0
- package/dist/package/main.js +138903 -91477
- package/docs/README.md +14 -7
- package/docs/channels-remote-and-api.md +8 -5
- package/docs/connected-host.md +14 -12
- package/docs/getting-started.md +58 -30
- package/docs/knowledge-artifacts-and-multimodal.md +7 -5
- package/docs/project-planning.md +2 -2
- package/docs/providers-and-routing.md +11 -3
- package/docs/tools-and-commands.md +116 -45
- package/docs/voice-and-live-tts.md +3 -1
- package/package.json +3 -2
- package/release/release-notes.md +142 -5
- package/release/release-readiness.json +124 -94
- package/src/agent/assistant-cockpit.ts +247 -0
- package/src/agent/autonomy-schedule-format.ts +96 -0
- package/src/agent/autonomy-schedule.ts +514 -0
- package/src/agent/channel-delivery-receipts.ts +292 -0
- package/src/agent/competitive-feature-inventory.ts +294 -0
- package/src/agent/document-registry-types.ts +106 -0
- package/src/agent/document-registry.ts +734 -0
- package/src/agent/harness-control.ts +2 -2
- package/src/agent/memory-prompt.ts +2 -2
- package/src/agent/operator-actions.ts +50 -6
- package/src/agent/persona-registry.ts +8 -0
- package/src/agent/project-context-files.ts +273 -0
- package/src/agent/prompt-context-receipts.ts +502 -0
- package/src/agent/reminder-schedule-format.ts +16 -2
- package/src/agent/research-run-registry.ts +582 -0
- package/src/agent/research-source-registry.ts +441 -0
- package/src/agent/routine-registry.ts +19 -3
- package/src/agent/routine-schedule-format.ts +27 -2
- package/src/agent/runtime-profile-starters.ts +7 -0
- package/src/agent/runtime-profile.ts +106 -4
- package/src/agent/schedule-edit-format.ts +129 -0
- package/src/agent/schedule-edit.ts +496 -0
- package/src/agent/schedule-next-routes.ts +42 -0
- package/src/agent/setup-wizard-artifact-receipts.ts +366 -0
- package/src/agent/setup-wizard-checkpoint.ts +140 -0
- package/src/agent/setup-wizard.ts +683 -0
- package/src/agent/skill-registry-types.ts +102 -0
- package/src/agent/skill-registry.ts +81 -107
- package/src/agent/vibe-confirmation-routes.ts +62 -0
- package/src/agent/vibe-file.ts +285 -0
- package/src/cli/agent-knowledge-command.ts +45 -2
- package/src/cli/help.ts +3 -0
- package/src/cli/profiles-command.ts +25 -11
- package/src/config/agent-settings-policy.ts +1 -18
- package/src/input/agent-workspace-activation.ts +53 -0
- package/src/input/agent-workspace-artifact-browser-editor.ts +494 -0
- package/src/input/agent-workspace-artifact-metadata.ts +17 -0
- package/src/input/agent-workspace-basic-command-editors.ts +5 -1
- package/src/input/agent-workspace-categories.ts +153 -155
- package/src/input/agent-workspace-channel-triage.ts +481 -0
- package/src/input/agent-workspace-channels.ts +263 -0
- package/src/input/agent-workspace-command-editor.ts +152 -0
- package/src/input/agent-workspace-context-snapshot.ts +349 -0
- package/src/input/agent-workspace-delegation-editor-submission.ts +8 -0
- package/src/input/agent-workspace-document-editor.ts +502 -0
- package/src/input/agent-workspace-document-ops-editor.ts +523 -0
- package/src/input/agent-workspace-host-category.ts +1 -1
- package/src/input/agent-workspace-local-library-snapshot.ts +167 -0
- package/src/input/agent-workspace-model-compare-editor.ts +376 -0
- package/src/input/agent-workspace-model-compare-prompt-submission.ts +552 -0
- package/src/input/agent-workspace-model-compare-types.ts +82 -0
- package/src/input/agent-workspace-model-compare-utils.ts +35 -0
- package/src/input/agent-workspace-onboarding-categories.ts +141 -0
- package/src/input/agent-workspace-operations-command-editor-submission.ts +53 -0
- package/src/input/agent-workspace-operations-command-editors.ts +22 -0
- package/src/input/agent-workspace-research-report-editor.ts +212 -0
- package/src/input/agent-workspace-research-run-editor.ts +144 -0
- package/src/input/agent-workspace-research-source-editor.ts +167 -0
- package/src/input/agent-workspace-review-packet-snapshot.ts +593 -0
- package/src/input/agent-workspace-review-packet-utils.ts +265 -0
- package/src/input/agent-workspace-settings.ts +313 -30
- package/src/input/agent-workspace-setup-checkpoint-action.ts +127 -0
- package/src/input/agent-workspace-setup-snapshot.ts +217 -0
- package/src/input/agent-workspace-setup.ts +61 -1
- package/src/input/agent-workspace-snapshot.ts +184 -149
- package/src/input/agent-workspace-types.ts +287 -2
- package/src/input/agent-workspace.ts +23 -1
- package/src/input/command-registry.ts +9 -2
- package/src/input/commands/agent-runtime-profile-runtime.ts +28 -13
- package/src/input/commands/channels-runtime.ts +102 -114
- package/src/input/commands/delegation-runtime.ts +87 -24
- package/src/input/commands/knowledge-browser-flags.ts +12 -0
- package/src/input/commands/knowledge.ts +28 -14
- package/src/input/commands/operator-actions-runtime.ts +6 -3
- package/src/input/commands/schedule-runtime.ts +71 -14
- package/src/input/commands/session-content.ts +2 -2
- package/src/input/commands/shell-core.ts +2 -0
- package/src/input/commands/vibe-runtime.ts +140 -0
- package/src/input/commands.ts +2 -0
- package/src/input/connected-host-routes.ts +123 -0
- package/src/input/settings-modal-types.ts +14 -0
- package/src/input/setup-wizard-live-receipts.ts +76 -0
- package/src/main.ts +15 -15
- package/src/panels/qr-panel.ts +2 -2
- package/src/renderer/agent-workspace-context-lines.ts +701 -0
- package/src/renderer/agent-workspace.ts +68 -421
- package/src/renderer/settings-modal-helpers.ts +12 -0
- package/src/renderer/settings-modal.ts +12 -0
- package/src/runtime/bootstrap-command-context.ts +11 -1
- package/src/runtime/bootstrap-command-parts.ts +14 -3
- package/src/runtime/bootstrap-core.ts +39 -1
- package/src/runtime/bootstrap-shell.ts +6 -0
- package/src/runtime/bootstrap.ts +113 -30
- package/src/runtime/connected-host-auth.ts +3 -2
- package/src/runtime/execution-ledger.ts +231 -0
- package/src/runtime/services.ts +88 -10
- package/src/runtime/tool-permission-safety.ts +199 -5
- package/src/shell/session-continuity-hints.ts +39 -0
- package/src/tools/agent-artifacts-tool.ts +606 -0
- package/src/tools/agent-audit-tool.ts +155 -0
- package/src/tools/agent-autonomy-schedule-tool.ts +238 -0
- package/src/tools/agent-autonomy-tool.ts +140 -0
- package/src/tools/agent-channel-send-tool.ts +24 -2
- package/src/tools/agent-channels-tool.ts +140 -0
- package/src/tools/agent-computer-tool.ts +168 -0
- package/src/tools/agent-context-policy.ts +137 -7
- package/src/tools/agent-context-tool.ts +143 -0
- package/src/tools/agent-delegation-tool.ts +128 -0
- package/src/tools/agent-device-tool.ts +240 -0
- package/src/tools/agent-documents-tool.ts +684 -0
- package/src/tools/agent-execution-tool.ts +230 -0
- package/src/tools/agent-harness-agent-orchestration-policy.ts +75 -0
- package/src/tools/agent-harness-agent-orchestration.ts +791 -0
- package/src/tools/agent-harness-autonomy-intake.ts +785 -0
- package/src/tools/agent-harness-autonomy-live-records.ts +742 -0
- package/src/tools/agent-harness-autonomy-queue-types.ts +88 -0
- package/src/tools/agent-harness-autonomy-queue.ts +571 -0
- package/src/tools/agent-harness-autonomy-watcher-read-models.ts +509 -0
- package/src/tools/agent-harness-background-processes-types.ts +35 -0
- package/src/tools/agent-harness-background-processes.ts +798 -0
- package/src/tools/agent-harness-browser-cockpit-route.ts +373 -0
- package/src/tools/agent-harness-browser-control.ts +346 -0
- package/src/tools/agent-harness-browser-pwa-read-models.ts +622 -0
- package/src/tools/agent-harness-channel-metadata.ts +168 -10
- package/src/tools/agent-harness-cli-command-policy.ts +110 -0
- package/src/tools/agent-harness-command-catalog.ts +4 -2
- package/src/tools/agent-harness-command-runner.ts +42 -0
- package/src/tools/agent-harness-connected-host-status.ts +7 -4
- package/src/tools/agent-harness-delegation-posture.ts +234 -19
- package/src/tools/agent-harness-device-live-read-models.ts +366 -0
- package/src/tools/agent-harness-document-ops-reviewer-readiness.ts +234 -0
- package/src/tools/agent-harness-document-ops-types.ts +72 -0
- package/src/tools/agent-harness-document-ops.ts +671 -0
- package/src/tools/agent-harness-execution-history.ts +489 -0
- package/src/tools/agent-harness-execution-posture.ts +385 -0
- package/src/tools/agent-harness-file-recovery.ts +135 -0
- package/src/tools/agent-harness-interactive-runtime-records.ts +421 -0
- package/src/tools/agent-harness-keybinding-metadata.ts +16 -12
- package/src/tools/agent-harness-learning-curator-common.ts +102 -0
- package/src/tools/agent-harness-learning-curator-consolidation.ts +295 -0
- package/src/tools/agent-harness-learning-curator-proposals.ts +606 -0
- package/src/tools/agent-harness-learning-curator-types.ts +151 -0
- package/src/tools/agent-harness-learning-curator.ts +417 -0
- package/src/tools/agent-harness-local-model-benchmarks.ts +269 -0
- package/src/tools/agent-harness-local-model-cookbook.ts +238 -0
- package/src/tools/agent-harness-local-model-endpoints.ts +788 -0
- package/src/tools/agent-harness-local-model-smoke.ts +277 -0
- package/src/tools/agent-harness-local-model-url.ts +78 -0
- package/src/tools/agent-harness-media-posture.ts +223 -2
- package/src/tools/agent-harness-memory-external-providers.ts +796 -0
- package/src/tools/agent-harness-memory-posture.ts +672 -0
- package/src/tools/agent-harness-memory-provider-certification.ts +219 -0
- package/src/tools/agent-harness-memory-refinement.ts +340 -0
- package/src/tools/agent-harness-metadata.ts +100 -168
- package/src/tools/agent-harness-mode-catalog.ts +86 -33
- package/src/tools/agent-harness-model-catalog.ts +162 -0
- package/src/tools/agent-harness-model-provider-health.ts +283 -0
- package/src/tools/agent-harness-model-readiness.ts +432 -0
- package/src/tools/agent-harness-model-routing-types.ts +327 -0
- package/src/tools/agent-harness-model-routing-utils.ts +30 -0
- package/src/tools/agent-harness-model-routing.ts +165 -193
- package/src/tools/agent-harness-operator-methods.ts +115 -133
- package/src/tools/agent-harness-pairing-posture.ts +452 -18
- package/src/tools/agent-harness-personal-ops-certification.ts +116 -0
- package/src/tools/agent-harness-personal-ops-discovery.ts +533 -0
- package/src/tools/agent-harness-personal-ops-intake.ts +385 -0
- package/src/tools/agent-harness-personal-ops-lanes.ts +270 -0
- package/src/tools/agent-harness-personal-ops-operations.ts +225 -0
- package/src/tools/agent-harness-personal-ops-provider-records.ts +358 -0
- package/src/tools/agent-harness-personal-ops-provider-task-records.ts +321 -0
- package/src/tools/agent-harness-personal-ops-records.ts +684 -0
- package/src/tools/agent-harness-personal-ops-runner.ts +637 -0
- package/src/tools/agent-harness-personal-ops-types.ts +240 -0
- package/src/tools/agent-harness-personal-ops.ts +613 -0
- package/src/tools/agent-harness-project-context.ts +144 -0
- package/src/tools/agent-harness-prompt-context.ts +589 -0
- package/src/tools/agent-harness-provider-account-metadata.ts +2 -2
- package/src/tools/agent-harness-release-evidence.ts +9 -7
- package/src/tools/agent-harness-release-readiness.ts +9 -7
- package/src/tools/agent-harness-remote-read-models.ts +541 -0
- package/src/tools/agent-harness-research-briefing.ts +446 -0
- package/src/tools/agent-harness-research-live-read-models.ts +500 -0
- package/src/tools/agent-harness-research-queue.ts +250 -0
- package/src/tools/agent-harness-research-runs.ts +307 -0
- package/src/tools/agent-harness-research-workflow.ts +395 -0
- package/src/tools/agent-harness-security-posture.ts +2 -2
- package/src/tools/agent-harness-service-posture.ts +9 -9
- package/src/tools/agent-harness-session-metadata.ts +3 -3
- package/src/tools/agent-harness-setup-connected-host.ts +501 -0
- package/src/tools/agent-harness-setup-describe.ts +557 -0
- package/src/tools/agent-harness-setup-handoffs.ts +502 -0
- package/src/tools/agent-harness-setup-model-helpers.ts +102 -0
- package/src/tools/agent-harness-setup-plan.ts +253 -0
- package/src/tools/agent-harness-setup-posture-types.ts +218 -0
- package/src/tools/agent-harness-setup-posture-utils.ts +173 -0
- package/src/tools/agent-harness-setup-posture.ts +449 -221
- package/src/tools/agent-harness-setup-smoke.ts +533 -0
- package/src/tools/agent-harness-sudo-posture.ts +114 -0
- package/src/tools/agent-harness-tool-schema.ts +142 -7
- package/src/tools/agent-harness-tool-types.ts +83 -0
- package/src/tools/agent-harness-tool-utils.ts +43 -0
- package/src/tools/agent-harness-tool.ts +319 -370
- package/src/tools/agent-harness-ui-surface-metadata.ts +76 -69
- package/src/tools/agent-harness-ui-surface-types.ts +46 -0
- package/src/tools/agent-harness-vibe-health.ts +105 -0
- package/src/tools/agent-harness-workspace-action-runner.ts +149 -0
- package/src/tools/agent-harness-workspace-actions.ts +114 -8
- package/src/tools/agent-harness-workspace-editor-execution.ts +214 -0
- package/src/tools/agent-harness-workspace-editor-runner.ts +755 -0
- package/src/tools/agent-host-tool.ts +159 -0
- package/src/tools/agent-knowledge-ingest-tool.ts +34 -1
- package/src/tools/agent-learning-consolidation-core.ts +327 -0
- package/src/tools/agent-learning-consolidation-tool.ts +758 -0
- package/src/tools/agent-memory-tool.ts +253 -0
- package/src/tools/agent-model-compare-export.ts +315 -0
- package/src/tools/agent-model-compare-handoff.ts +592 -0
- package/src/tools/agent-model-compare-judgment.ts +633 -0
- package/src/tools/agent-model-compare-run.ts +735 -0
- package/src/tools/agent-model-compare-tool.ts +698 -0
- package/src/tools/agent-model-compare-types.ts +191 -0
- package/src/tools/agent-model-compare-utils.ts +93 -0
- package/src/tools/agent-models-tool.ts +208 -0
- package/src/tools/agent-operator-action-tool.ts +1 -1
- package/src/tools/agent-operator-method-tool.ts +643 -0
- package/src/tools/agent-personal-ops-tool.ts +197 -0
- package/src/tools/agent-policy-explanation.ts +415 -0
- package/src/tools/agent-research-report-tool.ts +608 -0
- package/src/tools/agent-research-runner.ts +367 -0
- package/src/tools/agent-research-runs-tool.ts +434 -0
- package/src/tools/agent-research-sources-tool.ts +443 -0
- package/src/tools/agent-research-tool.ts +515 -0
- package/src/tools/agent-review-packet-presets-core.ts +757 -0
- package/src/tools/agent-review-packet-presets-tool.ts +466 -0
- package/src/tools/agent-review-packet-share-tool.ts +305 -0
- package/src/tools/agent-route-planner-candidates-setup.ts +411 -0
- package/src/tools/agent-route-planner-candidates-surfaces.ts +432 -0
- package/src/tools/agent-route-planner-candidates-work.ts +251 -0
- package/src/tools/agent-route-planner-helpers.ts +667 -0
- package/src/tools/agent-route-planner.ts +185 -0
- package/src/tools/agent-route-tool.ts +105 -0
- package/src/tools/agent-schedule-edit-tool.ts +210 -0
- package/src/tools/agent-schedule-tool.ts +282 -0
- package/src/tools/agent-security-tool.ts +145 -0
- package/src/tools/agent-sessions-tool.ts +122 -0
- package/src/tools/agent-settings-import-tool.ts +104 -0
- package/src/tools/agent-settings-tool.ts +176 -0
- package/src/tools/agent-setup-tool.ts +226 -0
- package/src/tools/agent-support-tool.ts +122 -0
- package/src/tools/agent-terminal-process-tools.ts +167 -0
- package/src/tools/agent-tool-policy-guard-types.ts +77 -0
- package/src/tools/agent-tool-policy-guard.ts +106 -85
- package/src/tools/agent-vibe-tool.ts +297 -0
- package/src/tools/agent-work-plan-tool.ts +265 -6
- package/src/tools/agent-workspace-tool.ts +305 -0
- package/src/tools/artifact-archive.ts +169 -0
- package/src/tools/tool-definition-compaction.ts +36 -0
- package/src/version.ts +1 -1
|
@@ -0,0 +1,683 @@
|
|
|
1
|
+
export type AgentSetupWizardSourceStatus = 'ready' | 'blocked' | 'recommended' | 'optional' | 'check';
|
|
2
|
+
export type AgentSetupWizardStatus = 'complete' | 'active' | 'blocked';
|
|
3
|
+
export type AgentSetupWizardStepStatus = 'done' | 'current' | 'pending' | 'blocked';
|
|
4
|
+
export type AgentSetupWizardCheckpointStatus = 'available' | 'none' | 'stale' | 'unavailable';
|
|
5
|
+
export type AgentSetupWizardCloseoutStatus = 'complete' | 'ready-to-finish' | 'needs-smoke-evidence' | 'blocked';
|
|
6
|
+
export type AgentSetupWizardReceiptSchemaStatus = 'certified' | 'legacy';
|
|
7
|
+
|
|
8
|
+
export interface AgentSetupWizardSourceItem {
|
|
9
|
+
readonly id: string;
|
|
10
|
+
readonly label: string;
|
|
11
|
+
readonly status: AgentSetupWizardSourceStatus;
|
|
12
|
+
readonly detail: string;
|
|
13
|
+
readonly userRoute: string;
|
|
14
|
+
readonly modelRoute: string;
|
|
15
|
+
readonly actionId?: string;
|
|
16
|
+
}
|
|
17
|
+
|
|
18
|
+
export interface AgentSetupWizardBlockedCheckFrequency {
|
|
19
|
+
readonly checkId: string;
|
|
20
|
+
readonly count: number;
|
|
21
|
+
}
|
|
22
|
+
|
|
23
|
+
export interface AgentSetupWizardSmokeHistory {
|
|
24
|
+
readonly status: 'available' | 'none' | 'unavailable';
|
|
25
|
+
readonly total: number;
|
|
26
|
+
readonly trend: string;
|
|
27
|
+
readonly latestResult: string | null;
|
|
28
|
+
readonly previousResult: string | null;
|
|
29
|
+
readonly latestEvidenceId?: string | null;
|
|
30
|
+
readonly latestEvidenceAt?: string | null;
|
|
31
|
+
readonly resultCounts: Readonly<Record<string, number>>;
|
|
32
|
+
readonly blockedCheckFrequency: readonly AgentSetupWizardBlockedCheckFrequency[];
|
|
33
|
+
readonly inspectLatestRoute: string | null;
|
|
34
|
+
readonly rerunRoute: string;
|
|
35
|
+
readonly saveRoute: string;
|
|
36
|
+
readonly reason?: string;
|
|
37
|
+
}
|
|
38
|
+
|
|
39
|
+
export type AgentSetupWizardDurableReceiptStatus = 'ready' | 'blocked' | 'failed' | 'unknown';
|
|
40
|
+
|
|
41
|
+
export interface AgentSetupWizardDurableReceipt {
|
|
42
|
+
readonly stepId: string;
|
|
43
|
+
readonly stepLabel?: string;
|
|
44
|
+
readonly status: AgentSetupWizardDurableReceiptStatus;
|
|
45
|
+
readonly receiptId: string;
|
|
46
|
+
readonly recordedAt: string;
|
|
47
|
+
readonly summary: string;
|
|
48
|
+
readonly inspectRoute: string | null;
|
|
49
|
+
readonly source?: string;
|
|
50
|
+
readonly schemaStatus?: AgentSetupWizardReceiptSchemaStatus;
|
|
51
|
+
readonly schemaVersion?: string;
|
|
52
|
+
readonly provenance?: readonly string[];
|
|
53
|
+
readonly publicationGuarantee?: string;
|
|
54
|
+
readonly eventCursor?: string;
|
|
55
|
+
readonly eventSequence?: number;
|
|
56
|
+
readonly publisher?: string;
|
|
57
|
+
}
|
|
58
|
+
|
|
59
|
+
export interface AgentSetupWizardRepeatedBlocker {
|
|
60
|
+
readonly setupItemId: string;
|
|
61
|
+
readonly checkId: string;
|
|
62
|
+
readonly count: number;
|
|
63
|
+
readonly summary: string;
|
|
64
|
+
}
|
|
65
|
+
|
|
66
|
+
export interface AgentSetupWizardStep {
|
|
67
|
+
readonly id: string;
|
|
68
|
+
readonly label: string;
|
|
69
|
+
readonly status: AgentSetupWizardStepStatus;
|
|
70
|
+
readonly sourceStatus: AgentSetupWizardSourceStatus;
|
|
71
|
+
readonly detail: string;
|
|
72
|
+
readonly userRoute: string;
|
|
73
|
+
readonly modelRoute: string;
|
|
74
|
+
readonly actionId: string;
|
|
75
|
+
readonly backtrackRoute: string | null;
|
|
76
|
+
}
|
|
77
|
+
|
|
78
|
+
export type AgentSetupWizardStepHistoryKind = 'checkpoint' | 'setup-smoke' | 'durable-receipt';
|
|
79
|
+
|
|
80
|
+
export interface AgentSetupWizardStepHistoryEntry {
|
|
81
|
+
readonly id: string;
|
|
82
|
+
readonly stepId: string;
|
|
83
|
+
readonly stepLabel: string;
|
|
84
|
+
readonly kind: AgentSetupWizardStepHistoryKind;
|
|
85
|
+
readonly receiptId: string;
|
|
86
|
+
readonly recordedAt: string;
|
|
87
|
+
readonly summary: string;
|
|
88
|
+
readonly inspectRoute: string | null;
|
|
89
|
+
readonly source?: string;
|
|
90
|
+
readonly receiptStatus?: string;
|
|
91
|
+
readonly satisfiesReceipt?: boolean;
|
|
92
|
+
readonly schemaStatus?: AgentSetupWizardReceiptSchemaStatus;
|
|
93
|
+
readonly schemaVersion?: string;
|
|
94
|
+
readonly provenance?: readonly string[];
|
|
95
|
+
readonly publicationGuarantee?: string;
|
|
96
|
+
readonly eventCursor?: string;
|
|
97
|
+
readonly eventSequence?: number;
|
|
98
|
+
readonly publisher?: string;
|
|
99
|
+
}
|
|
100
|
+
|
|
101
|
+
export interface AgentSetupWizardReceiptGap {
|
|
102
|
+
readonly stepId: string;
|
|
103
|
+
readonly stepLabel: string;
|
|
104
|
+
readonly requiredReceipt: string;
|
|
105
|
+
readonly summary: string;
|
|
106
|
+
}
|
|
107
|
+
|
|
108
|
+
export interface AgentSetupWizardCloseout {
|
|
109
|
+
readonly status: AgentSetupWizardCloseoutStatus;
|
|
110
|
+
readonly label: string;
|
|
111
|
+
readonly summary: string;
|
|
112
|
+
readonly nextAction: string;
|
|
113
|
+
readonly primaryStepId: string | null;
|
|
114
|
+
readonly primaryStepLabel: string | null;
|
|
115
|
+
readonly userRoute: string;
|
|
116
|
+
readonly modelRoute: string;
|
|
117
|
+
readonly requiresConfirmation: boolean;
|
|
118
|
+
readonly evidence: readonly string[];
|
|
119
|
+
readonly policy: string;
|
|
120
|
+
}
|
|
121
|
+
|
|
122
|
+
export interface AgentSetupWizardCheckpoint {
|
|
123
|
+
readonly status: AgentSetupWizardCheckpointStatus;
|
|
124
|
+
readonly currentStepId: string | null;
|
|
125
|
+
readonly currentStepLabel: string | null;
|
|
126
|
+
readonly savedAt: string | null;
|
|
127
|
+
readonly source: string | null;
|
|
128
|
+
readonly resumed: boolean;
|
|
129
|
+
readonly summary: string;
|
|
130
|
+
readonly path: string | null;
|
|
131
|
+
readonly note?: string;
|
|
132
|
+
readonly parseError?: string;
|
|
133
|
+
readonly autoAdvance?: AgentSetupWizardCheckpointAutoAdvance;
|
|
134
|
+
readonly markCurrentRoute: string;
|
|
135
|
+
readonly clearRoute: string;
|
|
136
|
+
readonly inspectRoute: string;
|
|
137
|
+
}
|
|
138
|
+
|
|
139
|
+
export interface AgentSetupWizardCheckpointAutoAdvance {
|
|
140
|
+
readonly status: 'advanced' | 'live-priority';
|
|
141
|
+
readonly fromStepId: string | null;
|
|
142
|
+
readonly fromStepLabel: string | null;
|
|
143
|
+
readonly toStepId: string | null;
|
|
144
|
+
readonly toStepLabel: string | null;
|
|
145
|
+
readonly reason: string;
|
|
146
|
+
readonly evidence: string;
|
|
147
|
+
readonly clearRoute: string;
|
|
148
|
+
readonly inspectRoute: string;
|
|
149
|
+
}
|
|
150
|
+
|
|
151
|
+
export interface AgentSetupWizard {
|
|
152
|
+
readonly available: true;
|
|
153
|
+
readonly status: AgentSetupWizardStatus;
|
|
154
|
+
readonly completedSteps: number;
|
|
155
|
+
readonly totalSteps: number;
|
|
156
|
+
readonly currentStepId: string | null;
|
|
157
|
+
readonly currentStepLabel: string | null;
|
|
158
|
+
readonly progressLabel: string;
|
|
159
|
+
readonly next: string;
|
|
160
|
+
readonly reviewRoute: string;
|
|
161
|
+
readonly repeatedBlocker: AgentSetupWizardRepeatedBlocker | null;
|
|
162
|
+
readonly smokeHistory: AgentSetupWizardSmokeHistory;
|
|
163
|
+
readonly stepHistory: readonly AgentSetupWizardStepHistoryEntry[];
|
|
164
|
+
readonly receiptGaps: readonly AgentSetupWizardReceiptGap[];
|
|
165
|
+
readonly closeout: AgentSetupWizardCloseout;
|
|
166
|
+
readonly checkpoint: AgentSetupWizardCheckpoint;
|
|
167
|
+
readonly steps: readonly AgentSetupWizardStep[];
|
|
168
|
+
}
|
|
169
|
+
|
|
170
|
+
export interface BuildAgentSetupWizardInput {
|
|
171
|
+
readonly items: readonly AgentSetupWizardSourceItem[];
|
|
172
|
+
readonly smokeHistory?: AgentSetupWizardSmokeHistory;
|
|
173
|
+
readonly checkpoint?: AgentSetupWizardCheckpoint;
|
|
174
|
+
readonly closeoutCriticalStepIds?: readonly string[];
|
|
175
|
+
readonly setupMarkerExists?: boolean;
|
|
176
|
+
readonly finishRoute?: string;
|
|
177
|
+
readonly finishUserRoute?: string;
|
|
178
|
+
readonly receiptRequiredStepIds?: readonly string[];
|
|
179
|
+
readonly durableReceipts?: readonly AgentSetupWizardDurableReceipt[];
|
|
180
|
+
readonly repeatedBlockerAliases?: Readonly<Record<string, readonly string[]>>;
|
|
181
|
+
readonly reviewRoute?: string;
|
|
182
|
+
}
|
|
183
|
+
|
|
184
|
+
export const DEFAULT_AGENT_SETUP_WIZARD_REVIEW_ROUTE = 'setup action:"status" includeParameters:true';
|
|
185
|
+
export const DEFAULT_AGENT_SETUP_WIZARD_RERUN_SMOKE_ROUTE = 'setup action:"smoke" setupItemId:"install-smoke" confirm:true explicitUserRequest:"..."';
|
|
186
|
+
export const DEFAULT_AGENT_SETUP_WIZARD_SAVE_SMOKE_ROUTE = 'setup action:"smoke" setupItemId:"install-smoke" fields:{...} confirm:true explicitUserRequest:"..."';
|
|
187
|
+
export const DEFAULT_AGENT_SETUP_WIZARD_MARK_CHECKPOINT_ROUTE = 'setup action:"save_checkpoint" confirm:true explicitUserRequest:"..."';
|
|
188
|
+
export const DEFAULT_AGENT_SETUP_WIZARD_CLEAR_CHECKPOINT_ROUTE = 'setup action:"clear_checkpoint" confirm:true explicitUserRequest:"..."';
|
|
189
|
+
export const DEFAULT_AGENT_SETUP_WIZARD_INSPECT_CHECKPOINT_ROUTE = 'setup action:"checkpoint"';
|
|
190
|
+
export const DEFAULT_AGENT_SETUP_WIZARD_FINISH_ROUTE = 'setup action:"finish" confirm:true explicitUserRequest:"Finish Agent onboarding after setup smoke evidence is ready."';
|
|
191
|
+
export const DEFAULT_AGENT_SETUP_WIZARD_FINISH_USER_ROUTE = 'Agent Workspace -> Finish -> Apply & close';
|
|
192
|
+
|
|
193
|
+
export function emptyAgentSetupSmokeHistory(reason = 'No saved setup smoke evidence artifact found.'): AgentSetupWizardSmokeHistory {
|
|
194
|
+
return {
|
|
195
|
+
status: 'none',
|
|
196
|
+
total: 0,
|
|
197
|
+
trend: 'none',
|
|
198
|
+
latestResult: null,
|
|
199
|
+
previousResult: null,
|
|
200
|
+
resultCounts: {},
|
|
201
|
+
blockedCheckFrequency: [],
|
|
202
|
+
inspectLatestRoute: null,
|
|
203
|
+
rerunRoute: DEFAULT_AGENT_SETUP_WIZARD_RERUN_SMOKE_ROUTE,
|
|
204
|
+
saveRoute: DEFAULT_AGENT_SETUP_WIZARD_SAVE_SMOKE_ROUTE,
|
|
205
|
+
reason,
|
|
206
|
+
};
|
|
207
|
+
}
|
|
208
|
+
|
|
209
|
+
export function emptyAgentSetupWizardCheckpoint(reason = 'No saved setup wizard checkpoint.'): AgentSetupWizardCheckpoint {
|
|
210
|
+
return {
|
|
211
|
+
status: 'none',
|
|
212
|
+
currentStepId: null,
|
|
213
|
+
currentStepLabel: null,
|
|
214
|
+
savedAt: null,
|
|
215
|
+
source: null,
|
|
216
|
+
resumed: false,
|
|
217
|
+
summary: reason,
|
|
218
|
+
path: null,
|
|
219
|
+
markCurrentRoute: DEFAULT_AGENT_SETUP_WIZARD_MARK_CHECKPOINT_ROUTE,
|
|
220
|
+
clearRoute: DEFAULT_AGENT_SETUP_WIZARD_CLEAR_CHECKPOINT_ROUTE,
|
|
221
|
+
inspectRoute: DEFAULT_AGENT_SETUP_WIZARD_INSPECT_CHECKPOINT_ROUTE,
|
|
222
|
+
};
|
|
223
|
+
}
|
|
224
|
+
|
|
225
|
+
function firstAttentionItem(items: readonly AgentSetupWizardSourceItem[]): AgentSetupWizardSourceItem | null {
|
|
226
|
+
return items.find((item) => item.status === 'blocked')
|
|
227
|
+
?? items.find((item) => item.status === 'check')
|
|
228
|
+
?? items.find((item) => item.status === 'recommended')
|
|
229
|
+
?? items.find((item) => item.status === 'optional')
|
|
230
|
+
?? null;
|
|
231
|
+
}
|
|
232
|
+
|
|
233
|
+
function firstBlockingItem(items: readonly AgentSetupWizardSourceItem[]): AgentSetupWizardSourceItem | null {
|
|
234
|
+
return items.find((item) => item.status === 'blocked')
|
|
235
|
+
?? items.find((item) => item.status === 'check')
|
|
236
|
+
?? null;
|
|
237
|
+
}
|
|
238
|
+
|
|
239
|
+
function itemFromRepeatedBlockers(
|
|
240
|
+
items: readonly AgentSetupWizardSourceItem[],
|
|
241
|
+
smokeHistory: AgentSetupWizardSmokeHistory,
|
|
242
|
+
aliases: Readonly<Record<string, readonly string[]>>,
|
|
243
|
+
): { readonly item: AgentSetupWizardSourceItem; readonly blocker: AgentSetupWizardRepeatedBlocker } | null {
|
|
244
|
+
const byId = new Map(items.map((item) => [item.id, item]));
|
|
245
|
+
for (const frequency of smokeHistory.blockedCheckFrequency) {
|
|
246
|
+
const candidates = aliases[frequency.checkId] ?? [frequency.checkId];
|
|
247
|
+
for (const candidate of candidates) {
|
|
248
|
+
const item = byId.get(candidate);
|
|
249
|
+
if (!item || item.status === 'ready') continue;
|
|
250
|
+
return {
|
|
251
|
+
item,
|
|
252
|
+
blocker: {
|
|
253
|
+
setupItemId: item.id,
|
|
254
|
+
checkId: frequency.checkId,
|
|
255
|
+
count: frequency.count,
|
|
256
|
+
summary: `${item.label} repeated in ${frequency.count} saved setup smoke run(s) as ${frequency.checkId}.`,
|
|
257
|
+
},
|
|
258
|
+
};
|
|
259
|
+
}
|
|
260
|
+
}
|
|
261
|
+
return null;
|
|
262
|
+
}
|
|
263
|
+
|
|
264
|
+
function itemFromCheckpoint(
|
|
265
|
+
items: readonly AgentSetupWizardSourceItem[],
|
|
266
|
+
checkpoint: AgentSetupWizardCheckpoint,
|
|
267
|
+
): AgentSetupWizardSourceItem | null {
|
|
268
|
+
if (checkpoint.status !== 'available' || !checkpoint.currentStepId) return null;
|
|
269
|
+
const item = items.find((candidate) => candidate.id === checkpoint.currentStepId);
|
|
270
|
+
if (!item || item.status === 'ready') return null;
|
|
271
|
+
return item;
|
|
272
|
+
}
|
|
273
|
+
|
|
274
|
+
function buildCheckpoint(
|
|
275
|
+
checkpoint: AgentSetupWizardCheckpoint,
|
|
276
|
+
items: readonly AgentSetupWizardSourceItem[],
|
|
277
|
+
resumedItem: AgentSetupWizardSourceItem | null,
|
|
278
|
+
blockingItem: AgentSetupWizardSourceItem | null,
|
|
279
|
+
): AgentSetupWizardCheckpoint {
|
|
280
|
+
const withRoutes: AgentSetupWizardCheckpoint = {
|
|
281
|
+
...checkpoint,
|
|
282
|
+
markCurrentRoute: checkpoint.markCurrentRoute || DEFAULT_AGENT_SETUP_WIZARD_MARK_CHECKPOINT_ROUTE,
|
|
283
|
+
clearRoute: checkpoint.clearRoute || DEFAULT_AGENT_SETUP_WIZARD_CLEAR_CHECKPOINT_ROUTE,
|
|
284
|
+
inspectRoute: checkpoint.inspectRoute || DEFAULT_AGENT_SETUP_WIZARD_INSPECT_CHECKPOINT_ROUTE,
|
|
285
|
+
};
|
|
286
|
+
if (checkpoint.status !== 'available') return withRoutes;
|
|
287
|
+
if (resumedItem) {
|
|
288
|
+
return {
|
|
289
|
+
...withRoutes,
|
|
290
|
+
currentStepLabel: checkpoint.currentStepLabel ?? resumedItem.label,
|
|
291
|
+
resumed: true,
|
|
292
|
+
summary: `Resuming ${resumedItem.label} from saved setup checkpoint.`,
|
|
293
|
+
};
|
|
294
|
+
}
|
|
295
|
+
const savedItem = checkpoint.currentStepId
|
|
296
|
+
? items.find((item) => item.id === checkpoint.currentStepId)
|
|
297
|
+
: null;
|
|
298
|
+
if (savedItem && savedItem.status !== 'ready' && blockingItem) {
|
|
299
|
+
return {
|
|
300
|
+
...withRoutes,
|
|
301
|
+
currentStepLabel: checkpoint.currentStepLabel ?? savedItem.label,
|
|
302
|
+
resumed: false,
|
|
303
|
+
summary: `Saved setup checkpoint for ${savedItem.label}; live blocker ${blockingItem.label} is taking priority.`,
|
|
304
|
+
autoAdvance: {
|
|
305
|
+
status: 'live-priority',
|
|
306
|
+
fromStepId: savedItem.id,
|
|
307
|
+
fromStepLabel: savedItem.label,
|
|
308
|
+
toStepId: blockingItem.id,
|
|
309
|
+
toStepLabel: blockingItem.label,
|
|
310
|
+
reason: 'A live blocking setup item takes priority over the saved checkpoint.',
|
|
311
|
+
evidence: `${blockingItem.label} is currently ${blockingItem.status}.`,
|
|
312
|
+
clearRoute: withRoutes.clearRoute,
|
|
313
|
+
inspectRoute: withRoutes.inspectRoute,
|
|
314
|
+
},
|
|
315
|
+
};
|
|
316
|
+
}
|
|
317
|
+
const nextItem = firstAttentionItem(items);
|
|
318
|
+
return {
|
|
319
|
+
...withRoutes,
|
|
320
|
+
status: 'stale',
|
|
321
|
+
resumed: false,
|
|
322
|
+
summary: savedItem?.status === 'ready'
|
|
323
|
+
? `Saved checkpoint ${savedItem.label} is already ready; live setup posture is taking over.`
|
|
324
|
+
: 'Saved checkpoint no longer matches a current setup step; live setup posture is taking over.',
|
|
325
|
+
autoAdvance: {
|
|
326
|
+
status: 'advanced',
|
|
327
|
+
fromStepId: savedItem?.id ?? checkpoint.currentStepId,
|
|
328
|
+
fromStepLabel: savedItem?.label ?? checkpoint.currentStepLabel,
|
|
329
|
+
toStepId: nextItem?.id ?? null,
|
|
330
|
+
toStepLabel: nextItem?.label ?? null,
|
|
331
|
+
reason: savedItem?.status === 'ready'
|
|
332
|
+
? 'The saved checkpoint step is ready, so the wizard advanced to live setup posture.'
|
|
333
|
+
: 'The saved checkpoint step is no longer in the live setup plan, so the wizard advanced to live setup posture.',
|
|
334
|
+
evidence: savedItem?.status === 'ready'
|
|
335
|
+
? `${savedItem.label} source status is ready.`
|
|
336
|
+
: 'No matching live setup item exists for the saved checkpoint id.',
|
|
337
|
+
clearRoute: withRoutes.clearRoute,
|
|
338
|
+
inspectRoute: withRoutes.inspectRoute,
|
|
339
|
+
},
|
|
340
|
+
};
|
|
341
|
+
}
|
|
342
|
+
|
|
343
|
+
function stepStatus(item: AgentSetupWizardSourceItem, currentId: string | null): AgentSetupWizardStepStatus {
|
|
344
|
+
if (item.status === 'ready') return 'done';
|
|
345
|
+
if (item.id === currentId) return 'current';
|
|
346
|
+
if (item.status === 'blocked' || item.status === 'check') return 'blocked';
|
|
347
|
+
return 'pending';
|
|
348
|
+
}
|
|
349
|
+
|
|
350
|
+
function buildStep(item: AgentSetupWizardSourceItem, currentId: string | null): AgentSetupWizardStep {
|
|
351
|
+
const status = stepStatus(item, currentId);
|
|
352
|
+
return {
|
|
353
|
+
id: item.id,
|
|
354
|
+
label: item.label,
|
|
355
|
+
status,
|
|
356
|
+
sourceStatus: item.status,
|
|
357
|
+
detail: item.detail,
|
|
358
|
+
userRoute: item.userRoute,
|
|
359
|
+
modelRoute: item.modelRoute,
|
|
360
|
+
actionId: item.actionId ?? item.id,
|
|
361
|
+
backtrackRoute: status === 'done' || status === 'current' ? item.modelRoute : null,
|
|
362
|
+
};
|
|
363
|
+
}
|
|
364
|
+
|
|
365
|
+
function validIso(value: string | null | undefined): string | null {
|
|
366
|
+
if (!value || Number.isNaN(Date.parse(value))) return null;
|
|
367
|
+
return new Date(value).toISOString();
|
|
368
|
+
}
|
|
369
|
+
|
|
370
|
+
function setupReceiptKind(stepId: string): string {
|
|
371
|
+
if (stepId === 'runtime' || stepId === 'connected-host-readiness') return 'connected-host service status receipt';
|
|
372
|
+
if (stepId === 'connected-host-auth') return 'connected-host auth receipt';
|
|
373
|
+
if (stepId === 'install-smoke') return 'setup smoke evidence receipt';
|
|
374
|
+
if (stepId === 'browser-pwa') return 'connected-host browser/PWA first-run receipt';
|
|
375
|
+
return 'durable setup receipt';
|
|
376
|
+
}
|
|
377
|
+
|
|
378
|
+
function setupStepAliases(stepId: string): readonly string[] {
|
|
379
|
+
if (stepId === 'runtime' || stepId === 'connected-host-readiness') return ['runtime', 'connected-host-readiness'];
|
|
380
|
+
return [stepId];
|
|
381
|
+
}
|
|
382
|
+
|
|
383
|
+
function setupStepMatches(left: string, right: string): boolean {
|
|
384
|
+
const leftAliases = new Set(setupStepAliases(left));
|
|
385
|
+
return setupStepAliases(right).some((alias) => leftAliases.has(alias));
|
|
386
|
+
}
|
|
387
|
+
|
|
388
|
+
function durableReceiptSatisfies(receipt: AgentSetupWizardDurableReceipt): boolean {
|
|
389
|
+
return receipt.status === 'ready' && Boolean(validIso(receipt.recordedAt)) && receipt.receiptId.trim().length > 0;
|
|
390
|
+
}
|
|
391
|
+
|
|
392
|
+
export function setupStepHasSatisfyingReceipt(
|
|
393
|
+
receipts: readonly AgentSetupWizardDurableReceipt[],
|
|
394
|
+
stepId: string,
|
|
395
|
+
): boolean {
|
|
396
|
+
return receipts.some((receipt) => durableReceiptSatisfies(receipt) && setupStepMatches(stepId, receipt.stepId));
|
|
397
|
+
}
|
|
398
|
+
|
|
399
|
+
function latestSatisfyingReceipt(
|
|
400
|
+
receipts: readonly AgentSetupWizardDurableReceipt[],
|
|
401
|
+
stepId: string,
|
|
402
|
+
): AgentSetupWizardDurableReceipt | null {
|
|
403
|
+
return receipts
|
|
404
|
+
.filter((receipt) => durableReceiptSatisfies(receipt) && setupStepMatches(stepId, receipt.stepId))
|
|
405
|
+
.sort((left, right) => Date.parse(right.recordedAt) - Date.parse(left.recordedAt) || left.receiptId.localeCompare(right.receiptId))[0] ?? null;
|
|
406
|
+
}
|
|
407
|
+
|
|
408
|
+
function applyDurableReceiptStatus(
|
|
409
|
+
items: readonly AgentSetupWizardSourceItem[],
|
|
410
|
+
receipts: readonly AgentSetupWizardDurableReceipt[],
|
|
411
|
+
): readonly AgentSetupWizardSourceItem[] {
|
|
412
|
+
if (receipts.length === 0) return items;
|
|
413
|
+
return items.map((item) => {
|
|
414
|
+
const receipt = latestSatisfyingReceipt(receipts, item.id);
|
|
415
|
+
if (!receipt) return item;
|
|
416
|
+
return {
|
|
417
|
+
...item,
|
|
418
|
+
status: 'ready',
|
|
419
|
+
detail: `${item.detail} Durable receipt ${receipt.receiptId}: ${receipt.summary}`,
|
|
420
|
+
};
|
|
421
|
+
});
|
|
422
|
+
}
|
|
423
|
+
|
|
424
|
+
function buildStepHistory(input: {
|
|
425
|
+
readonly items: readonly AgentSetupWizardSourceItem[];
|
|
426
|
+
readonly smokeHistory: AgentSetupWizardSmokeHistory;
|
|
427
|
+
readonly checkpoint: AgentSetupWizardCheckpoint;
|
|
428
|
+
readonly durableReceipts: readonly AgentSetupWizardDurableReceipt[];
|
|
429
|
+
}): readonly AgentSetupWizardStepHistoryEntry[] {
|
|
430
|
+
const byId = new Map(input.items.map((item) => [item.id, item]));
|
|
431
|
+
const history: AgentSetupWizardStepHistoryEntry[] = [];
|
|
432
|
+
|
|
433
|
+
const checkpointAt = validIso(input.checkpoint.savedAt);
|
|
434
|
+
if (input.checkpoint.status === 'available' && input.checkpoint.currentStepId && checkpointAt) {
|
|
435
|
+
const item = byId.get(input.checkpoint.currentStepId);
|
|
436
|
+
const stepLabel = item?.label ?? input.checkpoint.currentStepLabel ?? input.checkpoint.currentStepId;
|
|
437
|
+
const receiptId = `setup-wizard-checkpoint:${input.checkpoint.currentStepId}:${checkpointAt}`;
|
|
438
|
+
history.push({
|
|
439
|
+
id: `setup-step-history:${input.checkpoint.currentStepId}:checkpoint:${checkpointAt}`,
|
|
440
|
+
stepId: input.checkpoint.currentStepId,
|
|
441
|
+
stepLabel,
|
|
442
|
+
kind: 'checkpoint',
|
|
443
|
+
receiptId,
|
|
444
|
+
recordedAt: checkpointAt,
|
|
445
|
+
summary: `Saved checkpoint for ${stepLabel}.`,
|
|
446
|
+
inspectRoute: input.checkpoint.inspectRoute,
|
|
447
|
+
source: input.checkpoint.source ?? undefined,
|
|
448
|
+
satisfiesReceipt: false,
|
|
449
|
+
});
|
|
450
|
+
}
|
|
451
|
+
|
|
452
|
+
const smokeAt = validIso(input.smokeHistory.latestEvidenceAt);
|
|
453
|
+
if (input.smokeHistory.latestEvidenceId && smokeAt) {
|
|
454
|
+
const item = byId.get('install-smoke');
|
|
455
|
+
const result = input.smokeHistory.latestResult ?? 'unknown';
|
|
456
|
+
const ready = result === 'ready-for-user-run';
|
|
457
|
+
history.push({
|
|
458
|
+
id: `setup-step-history:install-smoke:setup-smoke:${input.smokeHistory.latestEvidenceId}`,
|
|
459
|
+
stepId: 'install-smoke',
|
|
460
|
+
stepLabel: item?.label ?? 'Install smoke',
|
|
461
|
+
kind: 'setup-smoke',
|
|
462
|
+
receiptId: input.smokeHistory.latestEvidenceId,
|
|
463
|
+
recordedAt: smokeAt,
|
|
464
|
+
summary: `Latest setup smoke evidence is ${result}.`,
|
|
465
|
+
inspectRoute: input.smokeHistory.inspectLatestRoute,
|
|
466
|
+
source: 'agent-setup-smoke-evidence',
|
|
467
|
+
receiptStatus: result,
|
|
468
|
+
satisfiesReceipt: ready,
|
|
469
|
+
});
|
|
470
|
+
}
|
|
471
|
+
|
|
472
|
+
for (const receipt of input.durableReceipts) {
|
|
473
|
+
const recordedAt = validIso(receipt.recordedAt);
|
|
474
|
+
if (!recordedAt || receipt.receiptId.trim().length === 0) continue;
|
|
475
|
+
const item = input.items.find((candidate) => setupStepMatches(candidate.id, receipt.stepId));
|
|
476
|
+
const stepLabel = receipt.stepLabel ?? item?.label ?? receipt.stepId;
|
|
477
|
+
history.push({
|
|
478
|
+
id: `setup-step-history:${receipt.stepId}:durable-receipt:${receipt.receiptId}`,
|
|
479
|
+
stepId: receipt.stepId,
|
|
480
|
+
stepLabel,
|
|
481
|
+
kind: 'durable-receipt',
|
|
482
|
+
receiptId: receipt.receiptId,
|
|
483
|
+
recordedAt,
|
|
484
|
+
summary: receipt.summary,
|
|
485
|
+
inspectRoute: receipt.inspectRoute,
|
|
486
|
+
source: receipt.source,
|
|
487
|
+
receiptStatus: receipt.status,
|
|
488
|
+
satisfiesReceipt: durableReceiptSatisfies(receipt),
|
|
489
|
+
schemaStatus: receipt.schemaStatus,
|
|
490
|
+
schemaVersion: receipt.schemaVersion,
|
|
491
|
+
provenance: receipt.provenance,
|
|
492
|
+
publicationGuarantee: receipt.publicationGuarantee,
|
|
493
|
+
eventCursor: receipt.eventCursor,
|
|
494
|
+
eventSequence: receipt.eventSequence,
|
|
495
|
+
publisher: receipt.publisher,
|
|
496
|
+
});
|
|
497
|
+
}
|
|
498
|
+
|
|
499
|
+
return history.sort((left, right) => Date.parse(right.recordedAt) - Date.parse(left.recordedAt) || left.id.localeCompare(right.id));
|
|
500
|
+
}
|
|
501
|
+
|
|
502
|
+
function buildReceiptGaps(input: {
|
|
503
|
+
readonly items: readonly AgentSetupWizardSourceItem[];
|
|
504
|
+
readonly stepHistory: readonly AgentSetupWizardStepHistoryEntry[];
|
|
505
|
+
readonly receiptRequiredStepIds: readonly string[];
|
|
506
|
+
}): readonly AgentSetupWizardReceiptGap[] {
|
|
507
|
+
return input.receiptRequiredStepIds
|
|
508
|
+
.filter((stepId) => !input.stepHistory.some((entry) => entry.satisfiesReceipt === true && setupStepMatches(stepId, entry.stepId)))
|
|
509
|
+
.map((stepId) => {
|
|
510
|
+
const item = input.items.find((candidate) => candidate.id === stepId);
|
|
511
|
+
const stepLabel = item?.label ?? stepId;
|
|
512
|
+
const requiredReceipt = setupReceiptKind(stepId);
|
|
513
|
+
return {
|
|
514
|
+
stepId,
|
|
515
|
+
stepLabel,
|
|
516
|
+
requiredReceipt,
|
|
517
|
+
summary: `${stepLabel} still needs a stable ${requiredReceipt} id and timestamp before release closeout can count it as durable setup evidence.`,
|
|
518
|
+
};
|
|
519
|
+
});
|
|
520
|
+
}
|
|
521
|
+
|
|
522
|
+
function buildCloseout(input: {
|
|
523
|
+
readonly items: readonly AgentSetupWizardSourceItem[];
|
|
524
|
+
readonly smokeHistory: AgentSetupWizardSmokeHistory;
|
|
525
|
+
readonly setupSmokeReceiptReady: boolean;
|
|
526
|
+
readonly stepHistory: readonly AgentSetupWizardStepHistoryEntry[];
|
|
527
|
+
readonly criticalStepIds: readonly string[];
|
|
528
|
+
readonly setupMarkerExists: boolean;
|
|
529
|
+
readonly reviewRoute: string;
|
|
530
|
+
readonly finishRoute: string;
|
|
531
|
+
readonly finishUserRoute: string;
|
|
532
|
+
}): AgentSetupWizardCloseout {
|
|
533
|
+
const critical = new Set(input.criticalStepIds);
|
|
534
|
+
const primaryBlocker = input.items.find((item) => (
|
|
535
|
+
critical.has(item.id) && item.status === 'blocked'
|
|
536
|
+
)) ?? null;
|
|
537
|
+
const smokeReady = input.setupSmokeReceiptReady
|
|
538
|
+
|| (input.smokeHistory.status === 'available' && input.smokeHistory.latestResult === 'ready-for-user-run');
|
|
539
|
+
const latestSmoke = input.smokeHistory.status === 'available'
|
|
540
|
+
? input.smokeHistory.latestResult ?? 'unknown'
|
|
541
|
+
: input.setupSmokeReceiptReady ? 'durable receipt ready' : input.smokeHistory.status;
|
|
542
|
+
const satisfyingSetupReceipts = input.stepHistory.filter((entry) => entry.kind === 'durable-receipt' && entry.satisfiesReceipt === true);
|
|
543
|
+
const certifiedSetupReceipts = satisfyingSetupReceipts.filter((entry) => entry.schemaStatus === 'certified');
|
|
544
|
+
const eventStreamSetupReceipts = satisfyingSetupReceipts.filter((entry) => entry.eventCursor);
|
|
545
|
+
const evidence = [
|
|
546
|
+
`critical setup blockers: ${primaryBlocker ? `${primaryBlocker.label} (${primaryBlocker.status})` : 'none'}`,
|
|
547
|
+
`setup marker: ${input.setupMarkerExists ? 'present' : 'missing'}`,
|
|
548
|
+
`latest setup smoke: ${latestSmoke}`,
|
|
549
|
+
`setup smoke receipt: ${input.setupSmokeReceiptReady ? 'ready' : 'missing'}`,
|
|
550
|
+
`certified setup receipts: ${certifiedSetupReceipts.length}/${satisfyingSetupReceipts.length}`,
|
|
551
|
+
`setup receipt event streams: ${eventStreamSetupReceipts.length}`,
|
|
552
|
+
`setup smoke history: ${input.smokeHistory.status}; total ${input.smokeHistory.total}; trend ${input.smokeHistory.trend}`,
|
|
553
|
+
];
|
|
554
|
+
const policy = 'Setup closeout is advisory until a confirmed finish route writes the local onboarding marker. Optional setup recommendations do not block closeout, but unresolved critical blockers or missing ready setup smoke evidence do.';
|
|
555
|
+
|
|
556
|
+
if (primaryBlocker) {
|
|
557
|
+
return {
|
|
558
|
+
status: 'blocked',
|
|
559
|
+
label: 'Fix setup blocker',
|
|
560
|
+
summary: `${primaryBlocker.label} is blocking normal Agent use.`,
|
|
561
|
+
nextAction: primaryBlocker.detail,
|
|
562
|
+
primaryStepId: primaryBlocker.id,
|
|
563
|
+
primaryStepLabel: primaryBlocker.label,
|
|
564
|
+
userRoute: primaryBlocker.userRoute,
|
|
565
|
+
modelRoute: primaryBlocker.modelRoute,
|
|
566
|
+
requiresConfirmation: false,
|
|
567
|
+
evidence,
|
|
568
|
+
policy,
|
|
569
|
+
};
|
|
570
|
+
}
|
|
571
|
+
|
|
572
|
+
if (!smokeReady) {
|
|
573
|
+
const prior = input.smokeHistory.latestResult === 'blocked'
|
|
574
|
+
? 'The latest saved setup smoke was blocked; rerun it now that critical setup is ready.'
|
|
575
|
+
: input.smokeHistory.status === 'unavailable'
|
|
576
|
+
? 'Critical setup is ready, but this runtime cannot prove a saved setup smoke artifact.'
|
|
577
|
+
: 'Critical setup is ready, but no ready setup smoke evidence is saved yet.';
|
|
578
|
+
return {
|
|
579
|
+
status: 'needs-smoke-evidence',
|
|
580
|
+
label: 'Run final setup smoke',
|
|
581
|
+
summary: prior,
|
|
582
|
+
nextAction: 'Run the confirmed setup smoke route, capture user-visible package/status and first-turn output, then save the redacted evidence.',
|
|
583
|
+
primaryStepId: 'install-smoke',
|
|
584
|
+
primaryStepLabel: 'Install smoke',
|
|
585
|
+
userRoute: 'Agent Workspace -> Start -> Install smoke',
|
|
586
|
+
modelRoute: input.smokeHistory.saveRoute,
|
|
587
|
+
requiresConfirmation: true,
|
|
588
|
+
evidence,
|
|
589
|
+
policy,
|
|
590
|
+
};
|
|
591
|
+
}
|
|
592
|
+
|
|
593
|
+
if (!input.setupMarkerExists) {
|
|
594
|
+
return {
|
|
595
|
+
status: 'ready-to-finish',
|
|
596
|
+
label: 'Finish setup',
|
|
597
|
+
summary: 'Critical setup is ready and the latest saved setup smoke evidence is ready for user-run closeout.',
|
|
598
|
+
nextAction: 'Write the onboarding completion marker so future launches start in the main conversation instead of first-run setup.',
|
|
599
|
+
primaryStepId: 'finish-onboarding',
|
|
600
|
+
primaryStepLabel: 'Finish onboarding state',
|
|
601
|
+
userRoute: input.finishUserRoute,
|
|
602
|
+
modelRoute: input.finishRoute,
|
|
603
|
+
requiresConfirmation: true,
|
|
604
|
+
evidence,
|
|
605
|
+
policy,
|
|
606
|
+
};
|
|
607
|
+
}
|
|
608
|
+
|
|
609
|
+
return {
|
|
610
|
+
status: 'complete',
|
|
611
|
+
label: 'Setup complete',
|
|
612
|
+
summary: 'Critical setup, setup smoke evidence, and the onboarding completion marker are all present.',
|
|
613
|
+
nextAction: 'Use setup only when provider, host, channel, automation, local behavior, or runtime-profile decisions change.',
|
|
614
|
+
primaryStepId: null,
|
|
615
|
+
primaryStepLabel: null,
|
|
616
|
+
userRoute: 'Agent Workspace -> Home',
|
|
617
|
+
modelRoute: input.reviewRoute,
|
|
618
|
+
requiresConfirmation: false,
|
|
619
|
+
evidence,
|
|
620
|
+
policy,
|
|
621
|
+
};
|
|
622
|
+
}
|
|
623
|
+
|
|
624
|
+
export function buildAgentSetupWizard(input: BuildAgentSetupWizardInput): AgentSetupWizard {
|
|
625
|
+
const smokeHistory = input.smokeHistory ?? emptyAgentSetupSmokeHistory();
|
|
626
|
+
const inputCheckpoint = input.checkpoint ?? emptyAgentSetupWizardCheckpoint();
|
|
627
|
+
const durableReceipts = input.durableReceipts ?? [];
|
|
628
|
+
const items = applyDurableReceiptStatus(input.items, durableReceipts);
|
|
629
|
+
const repeated = itemFromRepeatedBlockers(items, smokeHistory, input.repeatedBlockerAliases ?? {});
|
|
630
|
+
const blocking = firstBlockingItem(items);
|
|
631
|
+
const rawCheckpointItem = itemFromCheckpoint(items, inputCheckpoint);
|
|
632
|
+
const checkpointItem = blocking && rawCheckpointItem?.id !== blocking.id ? null : rawCheckpointItem;
|
|
633
|
+
const checkpoint = buildCheckpoint(inputCheckpoint, items, checkpointItem, blocking);
|
|
634
|
+
const current = repeated?.item ?? blocking ?? checkpointItem ?? firstAttentionItem(items);
|
|
635
|
+
const currentId = current?.id ?? null;
|
|
636
|
+
const steps = items.map((item) => buildStep(item, currentId));
|
|
637
|
+
const stepHistory = buildStepHistory({ items, smokeHistory, checkpoint, durableReceipts });
|
|
638
|
+
const setupSmokeReceiptReady = stepHistory.some((entry) => entry.satisfiesReceipt === true && setupStepMatches('install-smoke', entry.stepId));
|
|
639
|
+
const receiptGaps = buildReceiptGaps({
|
|
640
|
+
items,
|
|
641
|
+
stepHistory,
|
|
642
|
+
receiptRequiredStepIds: input.receiptRequiredStepIds ?? [],
|
|
643
|
+
});
|
|
644
|
+
const completedSteps = steps.filter((step) => step.status === 'done').length;
|
|
645
|
+
const status: AgentSetupWizardStatus = completedSteps === steps.length
|
|
646
|
+
? 'complete'
|
|
647
|
+
: current?.status === 'blocked' || current?.status === 'check'
|
|
648
|
+
? 'blocked'
|
|
649
|
+
: 'active';
|
|
650
|
+
const next = current
|
|
651
|
+
? repeated
|
|
652
|
+
? `${current.label}: ${repeated.blocker.summary} ${current.detail}`
|
|
653
|
+
: `${current.label}: ${current.detail}`
|
|
654
|
+
: 'Setup wizard is complete; rerun setup smoke if this machine was upgraded or moved.';
|
|
655
|
+
return {
|
|
656
|
+
available: true,
|
|
657
|
+
status,
|
|
658
|
+
completedSteps,
|
|
659
|
+
totalSteps: steps.length,
|
|
660
|
+
currentStepId: currentId,
|
|
661
|
+
currentStepLabel: current?.label ?? null,
|
|
662
|
+
progressLabel: `${completedSteps}/${steps.length} setup step(s) ready`,
|
|
663
|
+
next,
|
|
664
|
+
reviewRoute: input.reviewRoute ?? DEFAULT_AGENT_SETUP_WIZARD_REVIEW_ROUTE,
|
|
665
|
+
repeatedBlocker: repeated?.blocker ?? null,
|
|
666
|
+
smokeHistory,
|
|
667
|
+
stepHistory,
|
|
668
|
+
receiptGaps,
|
|
669
|
+
closeout: buildCloseout({
|
|
670
|
+
items,
|
|
671
|
+
smokeHistory,
|
|
672
|
+
setupSmokeReceiptReady,
|
|
673
|
+
stepHistory,
|
|
674
|
+
criticalStepIds: input.closeoutCriticalStepIds ?? [],
|
|
675
|
+
setupMarkerExists: input.setupMarkerExists === true,
|
|
676
|
+
reviewRoute: input.reviewRoute ?? DEFAULT_AGENT_SETUP_WIZARD_REVIEW_ROUTE,
|
|
677
|
+
finishRoute: input.finishRoute ?? DEFAULT_AGENT_SETUP_WIZARD_FINISH_ROUTE,
|
|
678
|
+
finishUserRoute: input.finishUserRoute ?? DEFAULT_AGENT_SETUP_WIZARD_FINISH_USER_ROUTE,
|
|
679
|
+
}),
|
|
680
|
+
checkpoint,
|
|
681
|
+
steps,
|
|
682
|
+
};
|
|
683
|
+
}
|