@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.
Files changed (274) hide show
  1. package/CHANGELOG.md +329 -0
  2. package/README.md +46 -30
  3. package/dist/package/{ast-grep-napi.linux-x64-gnu-mkk8xwww.node → ast-grep-napi.linux-x64-gnu-swtppvy9.node} +0 -0
  4. package/dist/package/{ast-grep-napi.linux-x64-musl-ryqtgdv6.node → ast-grep-napi.linux-x64-musl-ttfcdtap.node} +0 -0
  5. package/dist/package/main.js +138903 -91477
  6. package/docs/README.md +14 -7
  7. package/docs/channels-remote-and-api.md +8 -5
  8. package/docs/connected-host.md +14 -12
  9. package/docs/getting-started.md +58 -30
  10. package/docs/knowledge-artifacts-and-multimodal.md +7 -5
  11. package/docs/project-planning.md +2 -2
  12. package/docs/providers-and-routing.md +11 -3
  13. package/docs/tools-and-commands.md +116 -45
  14. package/docs/voice-and-live-tts.md +3 -1
  15. package/package.json +3 -2
  16. package/release/release-notes.md +142 -5
  17. package/release/release-readiness.json +124 -94
  18. package/src/agent/assistant-cockpit.ts +247 -0
  19. package/src/agent/autonomy-schedule-format.ts +96 -0
  20. package/src/agent/autonomy-schedule.ts +514 -0
  21. package/src/agent/channel-delivery-receipts.ts +292 -0
  22. package/src/agent/competitive-feature-inventory.ts +294 -0
  23. package/src/agent/document-registry-types.ts +106 -0
  24. package/src/agent/document-registry.ts +734 -0
  25. package/src/agent/harness-control.ts +2 -2
  26. package/src/agent/memory-prompt.ts +2 -2
  27. package/src/agent/operator-actions.ts +50 -6
  28. package/src/agent/persona-registry.ts +8 -0
  29. package/src/agent/project-context-files.ts +273 -0
  30. package/src/agent/prompt-context-receipts.ts +502 -0
  31. package/src/agent/reminder-schedule-format.ts +16 -2
  32. package/src/agent/research-run-registry.ts +582 -0
  33. package/src/agent/research-source-registry.ts +441 -0
  34. package/src/agent/routine-registry.ts +19 -3
  35. package/src/agent/routine-schedule-format.ts +27 -2
  36. package/src/agent/runtime-profile-starters.ts +7 -0
  37. package/src/agent/runtime-profile.ts +106 -4
  38. package/src/agent/schedule-edit-format.ts +129 -0
  39. package/src/agent/schedule-edit.ts +496 -0
  40. package/src/agent/schedule-next-routes.ts +42 -0
  41. package/src/agent/setup-wizard-artifact-receipts.ts +366 -0
  42. package/src/agent/setup-wizard-checkpoint.ts +140 -0
  43. package/src/agent/setup-wizard.ts +683 -0
  44. package/src/agent/skill-registry-types.ts +102 -0
  45. package/src/agent/skill-registry.ts +81 -107
  46. package/src/agent/vibe-confirmation-routes.ts +62 -0
  47. package/src/agent/vibe-file.ts +285 -0
  48. package/src/cli/agent-knowledge-command.ts +45 -2
  49. package/src/cli/help.ts +3 -0
  50. package/src/cli/profiles-command.ts +25 -11
  51. package/src/config/agent-settings-policy.ts +1 -18
  52. package/src/input/agent-workspace-activation.ts +53 -0
  53. package/src/input/agent-workspace-artifact-browser-editor.ts +494 -0
  54. package/src/input/agent-workspace-artifact-metadata.ts +17 -0
  55. package/src/input/agent-workspace-basic-command-editors.ts +5 -1
  56. package/src/input/agent-workspace-categories.ts +153 -155
  57. package/src/input/agent-workspace-channel-triage.ts +481 -0
  58. package/src/input/agent-workspace-channels.ts +263 -0
  59. package/src/input/agent-workspace-command-editor.ts +152 -0
  60. package/src/input/agent-workspace-context-snapshot.ts +349 -0
  61. package/src/input/agent-workspace-delegation-editor-submission.ts +8 -0
  62. package/src/input/agent-workspace-document-editor.ts +502 -0
  63. package/src/input/agent-workspace-document-ops-editor.ts +523 -0
  64. package/src/input/agent-workspace-host-category.ts +1 -1
  65. package/src/input/agent-workspace-local-library-snapshot.ts +167 -0
  66. package/src/input/agent-workspace-model-compare-editor.ts +376 -0
  67. package/src/input/agent-workspace-model-compare-prompt-submission.ts +552 -0
  68. package/src/input/agent-workspace-model-compare-types.ts +82 -0
  69. package/src/input/agent-workspace-model-compare-utils.ts +35 -0
  70. package/src/input/agent-workspace-onboarding-categories.ts +141 -0
  71. package/src/input/agent-workspace-operations-command-editor-submission.ts +53 -0
  72. package/src/input/agent-workspace-operations-command-editors.ts +22 -0
  73. package/src/input/agent-workspace-research-report-editor.ts +212 -0
  74. package/src/input/agent-workspace-research-run-editor.ts +144 -0
  75. package/src/input/agent-workspace-research-source-editor.ts +167 -0
  76. package/src/input/agent-workspace-review-packet-snapshot.ts +593 -0
  77. package/src/input/agent-workspace-review-packet-utils.ts +265 -0
  78. package/src/input/agent-workspace-settings.ts +313 -30
  79. package/src/input/agent-workspace-setup-checkpoint-action.ts +127 -0
  80. package/src/input/agent-workspace-setup-snapshot.ts +217 -0
  81. package/src/input/agent-workspace-setup.ts +61 -1
  82. package/src/input/agent-workspace-snapshot.ts +184 -149
  83. package/src/input/agent-workspace-types.ts +287 -2
  84. package/src/input/agent-workspace.ts +23 -1
  85. package/src/input/command-registry.ts +9 -2
  86. package/src/input/commands/agent-runtime-profile-runtime.ts +28 -13
  87. package/src/input/commands/channels-runtime.ts +102 -114
  88. package/src/input/commands/delegation-runtime.ts +87 -24
  89. package/src/input/commands/knowledge-browser-flags.ts +12 -0
  90. package/src/input/commands/knowledge.ts +28 -14
  91. package/src/input/commands/operator-actions-runtime.ts +6 -3
  92. package/src/input/commands/schedule-runtime.ts +71 -14
  93. package/src/input/commands/session-content.ts +2 -2
  94. package/src/input/commands/shell-core.ts +2 -0
  95. package/src/input/commands/vibe-runtime.ts +140 -0
  96. package/src/input/commands.ts +2 -0
  97. package/src/input/connected-host-routes.ts +123 -0
  98. package/src/input/settings-modal-types.ts +14 -0
  99. package/src/input/setup-wizard-live-receipts.ts +76 -0
  100. package/src/main.ts +15 -15
  101. package/src/panels/qr-panel.ts +2 -2
  102. package/src/renderer/agent-workspace-context-lines.ts +701 -0
  103. package/src/renderer/agent-workspace.ts +68 -421
  104. package/src/renderer/settings-modal-helpers.ts +12 -0
  105. package/src/renderer/settings-modal.ts +12 -0
  106. package/src/runtime/bootstrap-command-context.ts +11 -1
  107. package/src/runtime/bootstrap-command-parts.ts +14 -3
  108. package/src/runtime/bootstrap-core.ts +39 -1
  109. package/src/runtime/bootstrap-shell.ts +6 -0
  110. package/src/runtime/bootstrap.ts +113 -30
  111. package/src/runtime/connected-host-auth.ts +3 -2
  112. package/src/runtime/execution-ledger.ts +231 -0
  113. package/src/runtime/services.ts +88 -10
  114. package/src/runtime/tool-permission-safety.ts +199 -5
  115. package/src/shell/session-continuity-hints.ts +39 -0
  116. package/src/tools/agent-artifacts-tool.ts +606 -0
  117. package/src/tools/agent-audit-tool.ts +155 -0
  118. package/src/tools/agent-autonomy-schedule-tool.ts +238 -0
  119. package/src/tools/agent-autonomy-tool.ts +140 -0
  120. package/src/tools/agent-channel-send-tool.ts +24 -2
  121. package/src/tools/agent-channels-tool.ts +140 -0
  122. package/src/tools/agent-computer-tool.ts +168 -0
  123. package/src/tools/agent-context-policy.ts +137 -7
  124. package/src/tools/agent-context-tool.ts +143 -0
  125. package/src/tools/agent-delegation-tool.ts +128 -0
  126. package/src/tools/agent-device-tool.ts +240 -0
  127. package/src/tools/agent-documents-tool.ts +684 -0
  128. package/src/tools/agent-execution-tool.ts +230 -0
  129. package/src/tools/agent-harness-agent-orchestration-policy.ts +75 -0
  130. package/src/tools/agent-harness-agent-orchestration.ts +791 -0
  131. package/src/tools/agent-harness-autonomy-intake.ts +785 -0
  132. package/src/tools/agent-harness-autonomy-live-records.ts +742 -0
  133. package/src/tools/agent-harness-autonomy-queue-types.ts +88 -0
  134. package/src/tools/agent-harness-autonomy-queue.ts +571 -0
  135. package/src/tools/agent-harness-autonomy-watcher-read-models.ts +509 -0
  136. package/src/tools/agent-harness-background-processes-types.ts +35 -0
  137. package/src/tools/agent-harness-background-processes.ts +798 -0
  138. package/src/tools/agent-harness-browser-cockpit-route.ts +373 -0
  139. package/src/tools/agent-harness-browser-control.ts +346 -0
  140. package/src/tools/agent-harness-browser-pwa-read-models.ts +622 -0
  141. package/src/tools/agent-harness-channel-metadata.ts +168 -10
  142. package/src/tools/agent-harness-cli-command-policy.ts +110 -0
  143. package/src/tools/agent-harness-command-catalog.ts +4 -2
  144. package/src/tools/agent-harness-command-runner.ts +42 -0
  145. package/src/tools/agent-harness-connected-host-status.ts +7 -4
  146. package/src/tools/agent-harness-delegation-posture.ts +234 -19
  147. package/src/tools/agent-harness-device-live-read-models.ts +366 -0
  148. package/src/tools/agent-harness-document-ops-reviewer-readiness.ts +234 -0
  149. package/src/tools/agent-harness-document-ops-types.ts +72 -0
  150. package/src/tools/agent-harness-document-ops.ts +671 -0
  151. package/src/tools/agent-harness-execution-history.ts +489 -0
  152. package/src/tools/agent-harness-execution-posture.ts +385 -0
  153. package/src/tools/agent-harness-file-recovery.ts +135 -0
  154. package/src/tools/agent-harness-interactive-runtime-records.ts +421 -0
  155. package/src/tools/agent-harness-keybinding-metadata.ts +16 -12
  156. package/src/tools/agent-harness-learning-curator-common.ts +102 -0
  157. package/src/tools/agent-harness-learning-curator-consolidation.ts +295 -0
  158. package/src/tools/agent-harness-learning-curator-proposals.ts +606 -0
  159. package/src/tools/agent-harness-learning-curator-types.ts +151 -0
  160. package/src/tools/agent-harness-learning-curator.ts +417 -0
  161. package/src/tools/agent-harness-local-model-benchmarks.ts +269 -0
  162. package/src/tools/agent-harness-local-model-cookbook.ts +238 -0
  163. package/src/tools/agent-harness-local-model-endpoints.ts +788 -0
  164. package/src/tools/agent-harness-local-model-smoke.ts +277 -0
  165. package/src/tools/agent-harness-local-model-url.ts +78 -0
  166. package/src/tools/agent-harness-media-posture.ts +223 -2
  167. package/src/tools/agent-harness-memory-external-providers.ts +796 -0
  168. package/src/tools/agent-harness-memory-posture.ts +672 -0
  169. package/src/tools/agent-harness-memory-provider-certification.ts +219 -0
  170. package/src/tools/agent-harness-memory-refinement.ts +340 -0
  171. package/src/tools/agent-harness-metadata.ts +100 -168
  172. package/src/tools/agent-harness-mode-catalog.ts +86 -33
  173. package/src/tools/agent-harness-model-catalog.ts +162 -0
  174. package/src/tools/agent-harness-model-provider-health.ts +283 -0
  175. package/src/tools/agent-harness-model-readiness.ts +432 -0
  176. package/src/tools/agent-harness-model-routing-types.ts +327 -0
  177. package/src/tools/agent-harness-model-routing-utils.ts +30 -0
  178. package/src/tools/agent-harness-model-routing.ts +165 -193
  179. package/src/tools/agent-harness-operator-methods.ts +115 -133
  180. package/src/tools/agent-harness-pairing-posture.ts +452 -18
  181. package/src/tools/agent-harness-personal-ops-certification.ts +116 -0
  182. package/src/tools/agent-harness-personal-ops-discovery.ts +533 -0
  183. package/src/tools/agent-harness-personal-ops-intake.ts +385 -0
  184. package/src/tools/agent-harness-personal-ops-lanes.ts +270 -0
  185. package/src/tools/agent-harness-personal-ops-operations.ts +225 -0
  186. package/src/tools/agent-harness-personal-ops-provider-records.ts +358 -0
  187. package/src/tools/agent-harness-personal-ops-provider-task-records.ts +321 -0
  188. package/src/tools/agent-harness-personal-ops-records.ts +684 -0
  189. package/src/tools/agent-harness-personal-ops-runner.ts +637 -0
  190. package/src/tools/agent-harness-personal-ops-types.ts +240 -0
  191. package/src/tools/agent-harness-personal-ops.ts +613 -0
  192. package/src/tools/agent-harness-project-context.ts +144 -0
  193. package/src/tools/agent-harness-prompt-context.ts +589 -0
  194. package/src/tools/agent-harness-provider-account-metadata.ts +2 -2
  195. package/src/tools/agent-harness-release-evidence.ts +9 -7
  196. package/src/tools/agent-harness-release-readiness.ts +9 -7
  197. package/src/tools/agent-harness-remote-read-models.ts +541 -0
  198. package/src/tools/agent-harness-research-briefing.ts +446 -0
  199. package/src/tools/agent-harness-research-live-read-models.ts +500 -0
  200. package/src/tools/agent-harness-research-queue.ts +250 -0
  201. package/src/tools/agent-harness-research-runs.ts +307 -0
  202. package/src/tools/agent-harness-research-workflow.ts +395 -0
  203. package/src/tools/agent-harness-security-posture.ts +2 -2
  204. package/src/tools/agent-harness-service-posture.ts +9 -9
  205. package/src/tools/agent-harness-session-metadata.ts +3 -3
  206. package/src/tools/agent-harness-setup-connected-host.ts +501 -0
  207. package/src/tools/agent-harness-setup-describe.ts +557 -0
  208. package/src/tools/agent-harness-setup-handoffs.ts +502 -0
  209. package/src/tools/agent-harness-setup-model-helpers.ts +102 -0
  210. package/src/tools/agent-harness-setup-plan.ts +253 -0
  211. package/src/tools/agent-harness-setup-posture-types.ts +218 -0
  212. package/src/tools/agent-harness-setup-posture-utils.ts +173 -0
  213. package/src/tools/agent-harness-setup-posture.ts +449 -221
  214. package/src/tools/agent-harness-setup-smoke.ts +533 -0
  215. package/src/tools/agent-harness-sudo-posture.ts +114 -0
  216. package/src/tools/agent-harness-tool-schema.ts +142 -7
  217. package/src/tools/agent-harness-tool-types.ts +83 -0
  218. package/src/tools/agent-harness-tool-utils.ts +43 -0
  219. package/src/tools/agent-harness-tool.ts +319 -370
  220. package/src/tools/agent-harness-ui-surface-metadata.ts +76 -69
  221. package/src/tools/agent-harness-ui-surface-types.ts +46 -0
  222. package/src/tools/agent-harness-vibe-health.ts +105 -0
  223. package/src/tools/agent-harness-workspace-action-runner.ts +149 -0
  224. package/src/tools/agent-harness-workspace-actions.ts +114 -8
  225. package/src/tools/agent-harness-workspace-editor-execution.ts +214 -0
  226. package/src/tools/agent-harness-workspace-editor-runner.ts +755 -0
  227. package/src/tools/agent-host-tool.ts +159 -0
  228. package/src/tools/agent-knowledge-ingest-tool.ts +34 -1
  229. package/src/tools/agent-learning-consolidation-core.ts +327 -0
  230. package/src/tools/agent-learning-consolidation-tool.ts +758 -0
  231. package/src/tools/agent-memory-tool.ts +253 -0
  232. package/src/tools/agent-model-compare-export.ts +315 -0
  233. package/src/tools/agent-model-compare-handoff.ts +592 -0
  234. package/src/tools/agent-model-compare-judgment.ts +633 -0
  235. package/src/tools/agent-model-compare-run.ts +735 -0
  236. package/src/tools/agent-model-compare-tool.ts +698 -0
  237. package/src/tools/agent-model-compare-types.ts +191 -0
  238. package/src/tools/agent-model-compare-utils.ts +93 -0
  239. package/src/tools/agent-models-tool.ts +208 -0
  240. package/src/tools/agent-operator-action-tool.ts +1 -1
  241. package/src/tools/agent-operator-method-tool.ts +643 -0
  242. package/src/tools/agent-personal-ops-tool.ts +197 -0
  243. package/src/tools/agent-policy-explanation.ts +415 -0
  244. package/src/tools/agent-research-report-tool.ts +608 -0
  245. package/src/tools/agent-research-runner.ts +367 -0
  246. package/src/tools/agent-research-runs-tool.ts +434 -0
  247. package/src/tools/agent-research-sources-tool.ts +443 -0
  248. package/src/tools/agent-research-tool.ts +515 -0
  249. package/src/tools/agent-review-packet-presets-core.ts +757 -0
  250. package/src/tools/agent-review-packet-presets-tool.ts +466 -0
  251. package/src/tools/agent-review-packet-share-tool.ts +305 -0
  252. package/src/tools/agent-route-planner-candidates-setup.ts +411 -0
  253. package/src/tools/agent-route-planner-candidates-surfaces.ts +432 -0
  254. package/src/tools/agent-route-planner-candidates-work.ts +251 -0
  255. package/src/tools/agent-route-planner-helpers.ts +667 -0
  256. package/src/tools/agent-route-planner.ts +185 -0
  257. package/src/tools/agent-route-tool.ts +105 -0
  258. package/src/tools/agent-schedule-edit-tool.ts +210 -0
  259. package/src/tools/agent-schedule-tool.ts +282 -0
  260. package/src/tools/agent-security-tool.ts +145 -0
  261. package/src/tools/agent-sessions-tool.ts +122 -0
  262. package/src/tools/agent-settings-import-tool.ts +104 -0
  263. package/src/tools/agent-settings-tool.ts +176 -0
  264. package/src/tools/agent-setup-tool.ts +226 -0
  265. package/src/tools/agent-support-tool.ts +122 -0
  266. package/src/tools/agent-terminal-process-tools.ts +167 -0
  267. package/src/tools/agent-tool-policy-guard-types.ts +77 -0
  268. package/src/tools/agent-tool-policy-guard.ts +106 -85
  269. package/src/tools/agent-vibe-tool.ts +297 -0
  270. package/src/tools/agent-work-plan-tool.ts +265 -6
  271. package/src/tools/agent-workspace-tool.ts +305 -0
  272. package/src/tools/artifact-archive.ts +169 -0
  273. package/src/tools/tool-definition-compaction.ts +36 -0
  274. package/src/version.ts +1 -1
@@ -0,0 +1,557 @@
1
+ import type { OnboardingStep1CapabilityItem } from '../runtime/onboarding/index.ts';
2
+ import type { AgentSetupWizard } from '../agent/setup-wizard.ts';
3
+ import { DEFAULT_AGENT_SETUP_WIZARD_REVIEW_ROUTE } from '../agent/setup-wizard.ts';
4
+ import { previewHarnessText } from './agent-harness-text.ts';
5
+ import { setupHandoffsForItem } from './agent-harness-setup-handoffs.ts';
6
+ import { collectSnapshot, lookupFromArgs, readLimit, safeIso, summarizeLocalBehavior } from './agent-harness-setup-posture-utils.ts';
7
+ import type { AgentHarnessSetupArgs, SetupHandoffCard, SetupPlanItem, SetupRepairCard, SetupRepairDecision, SetupServiceLifecycleDecision } from './agent-harness-setup-posture-types.ts';
8
+
9
+ export function planSearchText(item: SetupPlanItem): string {
10
+ return [
11
+ item.id,
12
+ item.label,
13
+ item.status,
14
+ item.reason,
15
+ item.nextAction,
16
+ item.userRoute,
17
+ item.modelRoute,
18
+ item.relatedSetupItemId ?? '',
19
+ item.signals?.join('\n') ?? '',
20
+ JSON.stringify(item.localModelReadiness ?? {}),
21
+ setupHandoffsForItem(item).map((handoff) => [
22
+ handoff.id,
23
+ handoff.label,
24
+ handoff.kind,
25
+ handoff.effect,
26
+ handoff.modelRoute,
27
+ handoff.userRoute,
28
+ handoff.nextStep,
29
+ handoff.safety,
30
+ handoff.prerequisite ?? '',
31
+ ].join(' ')).join('\n'),
32
+ item.repairCards?.map((card) => [
33
+ card.id,
34
+ card.label,
35
+ card.state,
36
+ card.effect,
37
+ card.methodId ?? '',
38
+ card.modelRoute ?? '',
39
+ card.prerequisite ?? '',
40
+ card.recommendation,
41
+ card.liveEvidence?.probeStatus ?? '',
42
+ card.liveEvidence?.summary ?? '',
43
+ card.recommendedWhen,
44
+ card.safety,
45
+ ].join(' ')).join('\n') ?? '',
46
+ JSON.stringify(item.serviceLifecycleDecision ?? {}),
47
+ JSON.stringify(item.serviceProbe ?? {}),
48
+ JSON.stringify(item.authPosture ?? {}),
49
+ JSON.stringify(item.installSmokePlan ?? {}),
50
+ JSON.stringify(item.sudoPosture ?? {}),
51
+ ].join('\n').toLowerCase();
52
+ }
53
+
54
+ export function describeRepairCard(card: SetupRepairCard): Record<string, unknown> {
55
+ return {
56
+ id: card.id,
57
+ label: card.label,
58
+ state: card.state,
59
+ effect: card.effect,
60
+ recommendation: card.recommendation,
61
+ ...(card.methodId ? { methodId: card.methodId } : {}),
62
+ ...(card.modelRoute ? { modelRoute: card.modelRoute } : {}),
63
+ userRoute: card.userRoute,
64
+ ...(card.prerequisite ? { prerequisite: previewHarnessText(card.prerequisite, 140) } : {}),
65
+ ...(card.liveEvidence ? { liveEvidence: {
66
+ probeStatus: card.liveEvidence.probeStatus,
67
+ summary: previewHarnessText(card.liveEvidence.summary, 160),
68
+ } } : {}),
69
+ ...(card.outcome ? { outcome: {
70
+ target: card.outcome.target,
71
+ successCriteria: card.outcome.successCriteria.map((criterion) => previewHarnessText(criterion, 160)),
72
+ evidenceFields: card.outcome.evidenceFields,
73
+ verificationRoute: previewHarnessText(card.outcome.verificationRoute, 160),
74
+ recoveryRoute: previewHarnessText(card.outcome.recoveryRoute, 160),
75
+ } } : {}),
76
+ recommendedWhen: previewHarnessText(card.recommendedWhen, 160),
77
+ safety: previewHarnessText(card.safety, 160),
78
+ };
79
+ }
80
+
81
+ export function describeServiceLifecycleDecision(decision: SetupServiceLifecycleDecision): Record<string, unknown> {
82
+ return {
83
+ status: decision.status,
84
+ recommendedAction: decision.recommendedAction,
85
+ modelRoute: previewHarnessText(decision.modelRoute, 160),
86
+ reason: previewHarnessText(decision.reason, 180),
87
+ evidence: decision.evidence,
88
+ receiptRules: decision.receiptRules,
89
+ blockedMutations: decision.blockedMutations,
90
+ };
91
+ }
92
+
93
+ export function describeHandoffCard(card: SetupHandoffCard, includeParameters: boolean): Record<string, unknown> {
94
+ return {
95
+ id: card.id,
96
+ label: card.label,
97
+ kind: card.kind,
98
+ effect: card.effect,
99
+ userRoute: previewHarnessText(card.userRoute, includeParameters ? 140 : 96),
100
+ modelRoute: previewHarnessText(card.modelRoute, includeParameters ? 220 : 120),
101
+ nextStep: previewHarnessText(card.nextStep, includeParameters ? 180 : 120),
102
+ safety: previewHarnessText(card.safety, includeParameters ? 180 : 120),
103
+ ...(card.requiresConfirmation ? { requiresConfirmation: true } : {}),
104
+ ...(card.prerequisite ? { prerequisite: previewHarnessText(card.prerequisite, includeParameters ? 160 : 100) } : {}),
105
+ };
106
+ }
107
+
108
+ export function describeRepairDecision(decision: SetupRepairDecision, includeParameters: boolean): Record<string, unknown> {
109
+ return {
110
+ id: decision.id,
111
+ label: decision.label,
112
+ status: decision.status,
113
+ effect: decision.effect,
114
+ modelRoute: previewHarnessText(decision.modelRoute, includeParameters ? 220 : 140),
115
+ userRoute: previewHarnessText(decision.userRoute, includeParameters ? 160 : 120),
116
+ nextStep: previewHarnessText(decision.nextStep, includeParameters ? 220 : 140),
117
+ reason: previewHarnessText(decision.reason, includeParameters ? 220 : 140),
118
+ safety: previewHarnessText(decision.safety, includeParameters ? 220 : 140),
119
+ ...(decision.requiresConfirmation ? { requiresConfirmation: true } : {}),
120
+ ...(decision.prerequisite ? { prerequisite: previewHarnessText(decision.prerequisite, includeParameters ? 180 : 120) } : {}),
121
+ };
122
+ }
123
+
124
+ export function setupRepairDecisionFromCard(
125
+ card: SetupRepairCard,
126
+ status: SetupRepairDecision['status'],
127
+ nextStep: string,
128
+ ): SetupRepairDecision | null {
129
+ if (!card.modelRoute) return null;
130
+ return {
131
+ id: card.id,
132
+ label: card.label,
133
+ status,
134
+ effect: card.effect,
135
+ modelRoute: card.modelRoute,
136
+ userRoute: card.userRoute,
137
+ nextStep,
138
+ reason: card.liveEvidence?.summary ?? card.recommendedWhen,
139
+ safety: card.safety,
140
+ ...(card.effect === 'confirmed-effect' ? { requiresConfirmation: true } : {}),
141
+ ...(card.prerequisite ? { prerequisite: card.prerequisite } : {}),
142
+ };
143
+ }
144
+
145
+ export function setupRepairDecisionFromHandoff(
146
+ handoff: SetupHandoffCard,
147
+ status: SetupRepairDecision['status'],
148
+ reason: string,
149
+ ): SetupRepairDecision {
150
+ return {
151
+ id: handoff.id,
152
+ label: handoff.label,
153
+ status,
154
+ effect: handoff.effect,
155
+ modelRoute: handoff.modelRoute,
156
+ userRoute: handoff.userRoute,
157
+ nextStep: handoff.nextStep,
158
+ reason,
159
+ safety: handoff.safety,
160
+ ...(handoff.requiresConfirmation ? { requiresConfirmation: true } : {}),
161
+ ...(handoff.prerequisite ? { prerequisite: handoff.prerequisite } : {}),
162
+ };
163
+ }
164
+
165
+ export function repairCardById(item: SetupPlanItem, id: string): SetupRepairCard | null {
166
+ return item.repairCards?.find((card) => card.id === id) ?? null;
167
+ }
168
+
169
+ export function confirmedRepairCandidates(item: SetupPlanItem): readonly SetupRepairDecision[] {
170
+ return (item.repairCards ?? [])
171
+ .filter((card) => card.state === 'available' && card.effect === 'confirmed-effect' && card.recommendation !== 'not-needed' && card.modelRoute)
172
+ .map((card) => setupRepairDecisionFromCard(
173
+ card,
174
+ 'confirmed-repair-available',
175
+ 'Run only after read-only status evidence proves this exact service lifecycle mutation is needed.',
176
+ ))
177
+ .filter((decision): decision is SetupRepairDecision => decision !== null);
178
+ }
179
+
180
+ export function primarySetupRepairDecision(item: SetupPlanItem): SetupRepairDecision {
181
+ if (item.id === 'connected-host-auth') {
182
+ const handoff = setupHandoffsForItem(item)[0];
183
+ if (handoff) {
184
+ return setupRepairDecisionFromHandoff(
185
+ handoff,
186
+ handoff.requiresConfirmation ? 'confirmed-repair-available' : 'inspect-first',
187
+ item.authPosture?.operatorToken.usable
188
+ ? 'Connected-host token is usable; verify protected daemon route readiness before relying on automation.'
189
+ : 'Connected-host token is missing or unusable; token provisioning is the narrow confirmed repair.',
190
+ );
191
+ }
192
+ }
193
+
194
+ if (item.id === 'connected-host-readiness') {
195
+ const lifecycle = item.serviceLifecycleDecision;
196
+ if (lifecycle?.status === 'bootstrap-first') {
197
+ return {
198
+ id: 'connected-host-bootstrap',
199
+ label: 'Show host bootstrap checklist',
200
+ status: 'user-run-bootstrap',
201
+ effect: 'user-run',
202
+ modelRoute: 'setup action:"item" setupItemId:"connected-host-readiness" includeParameters:true',
203
+ userRoute: item.userRoute,
204
+ nextStep: 'Show the user-run Bun install, GoodVibes host install/start, binary verification, and reconnect checks for the owning host.',
205
+ reason: lifecycle.reason,
206
+ safety: item.bootstrapPlan?.policy ?? 'Bootstrap remains user-run guidance; Agent does not start or install the owning host implicitly.',
207
+ };
208
+ }
209
+
210
+ if (lifecycle?.status === 'needs-status-receipt') {
211
+ const statusCard = repairCardById(item, 'service-status');
212
+ const decision = statusCard
213
+ ? setupRepairDecisionFromCard(
214
+ statusCard,
215
+ 'inspect-first',
216
+ 'Read services.status first; choose install, start, restart, or no mutation only from that receipt.',
217
+ )
218
+ : null;
219
+ if (decision) return decision;
220
+ }
221
+
222
+ if (lifecycle?.status === 'status-route-unavailable') {
223
+ const posture = repairCardById(item, 'service-posture');
224
+ const decision = posture
225
+ ? setupRepairDecisionFromCard(
226
+ posture,
227
+ 'inspect-first',
228
+ 'Inspect endpoint binding, reachability, and logs because the daemon contract does not publish services.status.',
229
+ )
230
+ : null;
231
+ if (decision) return decision;
232
+ }
233
+
234
+ if (lifecycle?.status === 'no-lifecycle-action') {
235
+ const status = repairCardById(item, 'connected-host-status');
236
+ const decision = status
237
+ ? setupRepairDecisionFromCard(
238
+ status,
239
+ 'ready',
240
+ 'Runtime is reachable; inspect host readiness and avoid install/start/restart unless later diagnostics prove a gap.',
241
+ )
242
+ : null;
243
+ if (decision) return decision;
244
+ }
245
+ }
246
+
247
+ const handoff = setupHandoffsForItem(item)[0];
248
+ if (handoff) {
249
+ return setupRepairDecisionFromHandoff(
250
+ handoff,
251
+ handoff.requiresConfirmation ? 'confirmed-repair-available' : item.status === 'ready' ? 'ready' : 'inspect-first',
252
+ item.reason,
253
+ );
254
+ }
255
+
256
+ return {
257
+ id: `${item.id}-inspect`,
258
+ label: `Inspect ${item.label}`,
259
+ status: item.status === 'ready' ? 'ready' : 'inspect-first',
260
+ effect: 'read-only',
261
+ modelRoute: item.modelRoute,
262
+ userRoute: item.userRoute,
263
+ nextStep: item.nextAction,
264
+ reason: item.reason,
265
+ safety: 'Read-only setup inspection. Mutating routes remain separate and confirmation-gated.',
266
+ };
267
+ }
268
+
269
+ export function setupRepairPlanCandidates(plan: readonly SetupPlanItem[], input: string): readonly SetupPlanItem[] {
270
+ const normalized = input.toLowerCase();
271
+ const tokens = normalized.split(/[^a-z0-9]+/).filter((token) => token.length > 0);
272
+ const scored = plan
273
+ .map((item, index) => {
274
+ const id = item.id.toLowerCase();
275
+ const label = item.label.toLowerCase();
276
+ const text = planSearchText(item);
277
+ let score = 0;
278
+ if (id === normalized || label === normalized) score += 10_000;
279
+ if (id.includes(normalized) || label.includes(normalized)) score += 3_000;
280
+ for (const token of tokens) {
281
+ if (id.includes(token)) score += 1_000;
282
+ if (label.includes(token)) score += 700;
283
+ if (text.includes(token)) score += 120;
284
+ }
285
+ if (item.blocksAutonomy && item.status !== 'ready') score += 200;
286
+ if (item.status === 'blocked') score += 120;
287
+ if (item.status === 'check') score += 60;
288
+ return { item, index, score };
289
+ })
290
+ .filter((entry) => entry.score > 0)
291
+ .sort((left, right) => right.score - left.score || left.item.priority - right.item.priority || left.index - right.index);
292
+ return scored.map((entry) => entry.item);
293
+ }
294
+
295
+ export function defaultSetupRepairItem(plan: readonly SetupPlanItem[], wizard: AgentSetupWizard): SetupPlanItem | null {
296
+ const current = wizard.currentStepId
297
+ ? plan.find((item) => item.id === wizard.currentStepId)
298
+ : null;
299
+ if (current) return current;
300
+ return plan.find((item) => item.blocksAutonomy && item.status !== 'ready')
301
+ ?? plan.find((item) => item.status === 'blocked')
302
+ ?? plan.find((item) => item.status === 'check')
303
+ ?? plan.find((item) => item.status === 'recommended')
304
+ ?? plan[0]
305
+ ?? null;
306
+ }
307
+
308
+ export function setupRepairTarget(
309
+ plan: readonly SetupPlanItem[],
310
+ wizard: AgentSetupWizard,
311
+ args: AgentHarnessSetupArgs,
312
+ ): { readonly item: SetupPlanItem; readonly lookup: Record<string, unknown> } | { readonly error: Record<string, unknown> } {
313
+ const lookup = lookupFromArgs(args);
314
+ if (!lookup) {
315
+ const item = defaultSetupRepairItem(plan, wizard);
316
+ if (!item) {
317
+ return {
318
+ error: {
319
+ status: 'no_setup_items',
320
+ usage: 'No setup repair target is available. Inspect setup action:"status".',
321
+ },
322
+ };
323
+ }
324
+ return {
325
+ item,
326
+ lookup: {
327
+ source: 'setup_wizard',
328
+ resolvedBy: wizard.currentStepId === item.id ? 'current-step' : 'first-actionable-plan-item',
329
+ },
330
+ };
331
+ }
332
+
333
+ const normalized = lookup.input.toLowerCase();
334
+ const exact = plan.find((item) => item.id === lookup.input);
335
+ if (exact) return { item: exact, lookup: { ...lookup, resolvedBy: 'plan-id' } };
336
+ const insensitive = plan.find((item) => item.id.toLowerCase() === normalized);
337
+ if (insensitive) return { item: insensitive, lookup: { ...lookup, resolvedBy: 'case-insensitive-plan-id' } };
338
+ const candidates = setupRepairPlanCandidates(plan, lookup.input);
339
+ if (candidates.length === 1) return { item: candidates[0]!, lookup: { ...lookup, resolvedBy: 'repair-search' } };
340
+ if (candidates.length > 1) {
341
+ const best = candidates[0]!;
342
+ return {
343
+ item: best,
344
+ lookup: {
345
+ ...lookup,
346
+ resolvedBy: 'ranked-repair-search',
347
+ candidates: candidates.slice(0, 6).map((item) => ({
348
+ setupItemId: item.id,
349
+ label: item.label,
350
+ status: item.status,
351
+ modelRoute: item.modelRoute,
352
+ })),
353
+ },
354
+ };
355
+ }
356
+ return {
357
+ error: {
358
+ status: 'missing_lookup',
359
+ usage: `Unknown setup repair target ${lookup.input}. Use setup action:"status" to inspect setup item ids.`,
360
+ },
361
+ };
362
+ }
363
+
364
+ export function describePlanItem(item: SetupPlanItem, includeParameters: boolean): Record<string, unknown> {
365
+ const availableRepairCards = item.repairCards
366
+ ?.filter((card) => card.state === 'available')
367
+ .map((card) => card.id);
368
+ const recommendedRepairCards = item.repairCards
369
+ ?.filter((card) => card.state === 'available' && card.recommendation === 'recommended')
370
+ .map((card) => card.id);
371
+ const handoffs = setupHandoffsForItem(item);
372
+ const primaryHandoff = handoffs[0];
373
+ return {
374
+ setupItemId: item.id,
375
+ label: item.label,
376
+ status: item.status,
377
+ priority: item.priority,
378
+ blocksAutonomy: item.blocksAutonomy,
379
+ summary: previewHarnessText(item.reason, includeParameters ? 180 : 96),
380
+ nextAction: previewHarnessText(item.nextAction, includeParameters ? 180 : 96),
381
+ userRoute: previewHarnessText(item.userRoute, includeParameters ? 140 : 96),
382
+ modelRoute: previewHarnessText(item.modelRoute, includeParameters ? 140 : 96),
383
+ ...(primaryHandoff ? { primaryHandoff: describeHandoffCard(primaryHandoff, includeParameters) } : {}),
384
+ ...(item.relatedSetupItemId ? { relatedSetupItemId: item.relatedSetupItemId } : {}),
385
+ ...(item.signals && item.signals.length > 0 ? { signals: item.signals.slice(0, includeParameters ? 10 : 3) } : {}),
386
+ ...(availableRepairCards && availableRepairCards.length > 0 ? { availableRepairCards } : {}),
387
+ ...(recommendedRepairCards && recommendedRepairCards.length > 0 ? { recommendedRepairCards } : {}),
388
+ ...(item.bootstrapPlan ? { bootstrapRoute: 'setup action:"item" setupItemId:"connected-host-readiness"' } : {}),
389
+ ...(includeParameters && item.serviceProbe ? { serviceProbe: item.serviceProbe } : {}),
390
+ ...(includeParameters && item.serviceLifecycleDecision ? { serviceLifecycleDecision: describeServiceLifecycleDecision(item.serviceLifecycleDecision) } : {}),
391
+ ...(includeParameters && item.authPosture ? { authPosture: item.authPosture } : {}),
392
+ ...(includeParameters && item.installSmokePlan ? { installSmokePlan: item.installSmokePlan } : {}),
393
+ ...(includeParameters && item.localModelReadiness ? { localModelReadiness: item.localModelReadiness } : {}),
394
+ ...(includeParameters && item.vibeHealth ? { vibeHealth: item.vibeHealth } : {}),
395
+ ...(includeParameters && item.sudoPosture ? { sudoPosture: item.sudoPosture } : {}),
396
+ ...(includeParameters && handoffs.length > 0 ? { handoffs: handoffs.map((handoff) => describeHandoffCard(handoff, true)) } : {}),
397
+ ...(includeParameters && item.repairCards && item.repairCards.length > 0 ? { repairCards: item.repairCards.map(describeRepairCard) } : {}),
398
+ ...(includeParameters && item.bootstrapPlan ? { bootstrapPlan: item.bootstrapPlan } : {}),
399
+ ...(includeParameters ? {
400
+ policy: {
401
+ effect: 'read-only',
402
+ mutation: 'Setup plan rows only point to visible setup, status, settings, read-only diagnostics, and confirmed tool routes. Destructive service stop/uninstall actions are intentionally excluded from first-run repair cards.',
403
+ },
404
+ } : {}),
405
+ };
406
+ }
407
+
408
+ export function planSummary(plan: readonly SetupPlanItem[]): Record<string, number> {
409
+ return {
410
+ ready: plan.filter((item) => item.status === 'ready').length,
411
+ blocked: plan.filter((item) => item.status === 'blocked').length,
412
+ recommended: plan.filter((item) => item.status === 'recommended').length,
413
+ optional: plan.filter((item) => item.status === 'optional').length,
414
+ check: plan.filter((item) => item.status === 'check').length,
415
+ blocksAutonomy: plan.filter((item) => item.blocksAutonomy && item.status !== 'ready').length,
416
+ };
417
+ }
418
+
419
+ export function nextSetupHandoffSummaries(plan: readonly SetupPlanItem[], limit: number): readonly Record<string, unknown>[] {
420
+ return plan
421
+ .filter((item) => item.status === 'blocked' || item.status === 'check' || item.status === 'recommended')
422
+ .slice(0, limit)
423
+ .map((item) => {
424
+ const primaryHandoff = setupHandoffsForItem(item)[0];
425
+ return {
426
+ setupItemId: item.id,
427
+ label: item.label,
428
+ status: item.status,
429
+ nextAction: previewHarnessText(item.nextAction, 140),
430
+ modelRoute: previewHarnessText(item.modelRoute, 96),
431
+ ...(primaryHandoff ? {
432
+ handoffLabel: primaryHandoff.label,
433
+ handoffKind: primaryHandoff.kind,
434
+ handoffRoute: previewHarnessText(primaryHandoff.modelRoute, 140),
435
+ handoffUserRoute: previewHarnessText(primaryHandoff.userRoute, 120),
436
+ ...(primaryHandoff.requiresConfirmation ? { requiresConfirmation: true } : {}),
437
+ } : {}),
438
+ };
439
+ });
440
+ }
441
+
442
+ export function signalsForItem(
443
+ item: OnboardingStep1CapabilityItem,
444
+ snapshot: Awaited<ReturnType<typeof collectSnapshot>>,
445
+ ): Record<string, unknown> {
446
+ if (item.id === 'provider-access') {
447
+ return {
448
+ currentRoute: snapshot.providerRouting,
449
+ providerAccounts: {
450
+ providers: snapshot.providerAccounts?.providers.length ?? 0,
451
+ configured: snapshot.providerAccounts?.configuredCount ?? 0,
452
+ issues: snapshot.providerAccounts?.issueCount ?? 0,
453
+ },
454
+ subscriptions: {
455
+ active: snapshot.subscriptions.active.length,
456
+ pending: snapshot.subscriptions.pending.length,
457
+ activeProviderIds: snapshot.subscriptions.activeProviderIds,
458
+ pendingProviderIds: snapshot.subscriptions.pendingProviderIds,
459
+ },
460
+ credentialReferences: snapshot.secrets.records.length,
461
+ };
462
+ }
463
+ if (item.id === 'local-behavior') {
464
+ return summarizeLocalBehavior(snapshot);
465
+ }
466
+ if (item.id === 'communication-channels') {
467
+ return {
468
+ configuredEnabledKinds: snapshot.surfaces.configuredEnabledKinds,
469
+ surfaces: snapshot.surfaces.records.map((surface) => ({
470
+ id: surface.id,
471
+ kind: surface.kind,
472
+ label: surface.label,
473
+ enabled: surface.enabled,
474
+ state: surface.state,
475
+ capabilities: surface.capabilities,
476
+ })),
477
+ };
478
+ }
479
+ if (item.id === 'automation-review') {
480
+ return {
481
+ permissionsMode: snapshot.runtimeDefaults.permissionsMode,
482
+ helperEnabled: snapshot.providerRouting.helperEnabled,
483
+ toolLlmEnabled: snapshot.providerRouting.toolLlmEnabled,
484
+ };
485
+ }
486
+ if (item.id === 'operator-terminal') {
487
+ return {
488
+ display: snapshot.runtimeDefaults.display,
489
+ setupMarker: {
490
+ scope: snapshot.acknowledgements.scope,
491
+ exists: snapshot.acknowledgements.exists,
492
+ updatedAt: safeIso(snapshot.acknowledgements.updatedAt),
493
+ source: snapshot.acknowledgements.source,
494
+ mode: snapshot.acknowledgements.mode ?? null,
495
+ },
496
+ collectionIssues: snapshot.collectionIssues,
497
+ };
498
+ }
499
+ return {
500
+ status: item.selected ? 'covered' : 'available',
501
+ };
502
+ }
503
+
504
+ export function describeItem(
505
+ item: OnboardingStep1CapabilityItem,
506
+ snapshot: Awaited<ReturnType<typeof collectSnapshot>>,
507
+ options: {
508
+ readonly includeParameters?: boolean;
509
+ readonly lookup?: Record<string, unknown>;
510
+ } = {},
511
+ ): Record<string, unknown> {
512
+ return {
513
+ setupItemId: item.id,
514
+ label: item.label,
515
+ selected: item.selected,
516
+ modelRoute: setupItemModelRoute(),
517
+ ...(options.lookup ? { lookup: options.lookup } : {}),
518
+ ...(options.includeParameters
519
+ ? {
520
+ detail: item.detail,
521
+ signals: signalsForItem(item, snapshot),
522
+ policy: {
523
+ effect: 'read-only',
524
+ values: 'Setup posture returns onboarding readiness, counts, safe setting keys, and route metadata only; secret values and raw provider tokens are never returned.',
525
+ mutation: 'Setup apply, provider auth, local behavior import/create, channel delivery, and starter profile changes stay visible workspace, settings, slash-command, or first-class tool flows.',
526
+ },
527
+ modelAccess: {
528
+ inspectSetup: DEFAULT_AGENT_SETUP_WIZARD_REVIEW_ROUTE,
529
+ inspectSetupItem: 'setup action:"item"',
530
+ openOnboarding: 'agent_harness mode:"open_ui_surface" surfaceId:"onboarding" confirm:true explicitUserRequest:"..."',
531
+ setupWorkspace: 'agent_harness mode:"workspace_action" target:"setup"',
532
+ settings: 'settings action:"list|get|set|reset"; compatibility detail remains in agent_harness settings modes',
533
+ providerRouting: 'models action:"status"',
534
+ providerAccounts: 'models action:"providers"',
535
+ channels: 'channels action:"status"',
536
+ media: 'agent_harness mode:"media_posture"',
537
+ security: 'agent_harness mode:"security_posture"',
538
+ },
539
+ }
540
+ : {
541
+ summary: previewHarnessText(item.detail),
542
+ }),
543
+ };
544
+ }
545
+
546
+ export function setupItemModelRoute(): string {
547
+ return 'setup action:"item" or agent_harness mode:"open_ui_surface"';
548
+ }
549
+
550
+ export function describeCandidate(item: OnboardingStep1CapabilityItem): Record<string, unknown> {
551
+ return {
552
+ setupItemId: item.id,
553
+ label: item.label,
554
+ selected: item.selected,
555
+ modelRoute: setupItemModelRoute(),
556
+ };
557
+ }