@pellux/goodvibes-agent 1.1.7 → 1.2.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 (255) hide show
  1. package/CHANGELOG.md +170 -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 +132577 -91483
  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 +56 -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 +114 -45
  14. package/docs/voice-and-live-tts.md +3 -1
  15. package/package.json +3 -2
  16. package/release/release-notes.md +130 -5
  17. package/release/release-readiness.json +120 -90
  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 +296 -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-checkpoint.ts +140 -0
  42. package/src/agent/setup-wizard.ts +447 -0
  43. package/src/agent/skill-registry-types.ts +102 -0
  44. package/src/agent/skill-registry.ts +81 -107
  45. package/src/agent/vibe-confirmation-routes.ts +62 -0
  46. package/src/agent/vibe-file.ts +285 -0
  47. package/src/cli/agent-knowledge-command.ts +45 -2
  48. package/src/cli/help.ts +3 -0
  49. package/src/cli/profiles-command.ts +25 -11
  50. package/src/config/agent-settings-policy.ts +1 -18
  51. package/src/input/agent-workspace-activation.ts +53 -0
  52. package/src/input/agent-workspace-artifact-browser-editor.ts +494 -0
  53. package/src/input/agent-workspace-artifact-metadata.ts +17 -0
  54. package/src/input/agent-workspace-basic-command-editors.ts +5 -1
  55. package/src/input/agent-workspace-categories.ts +153 -155
  56. package/src/input/agent-workspace-channel-triage.ts +481 -0
  57. package/src/input/agent-workspace-channels.ts +263 -0
  58. package/src/input/agent-workspace-command-editor.ts +152 -0
  59. package/src/input/agent-workspace-context-snapshot.ts +349 -0
  60. package/src/input/agent-workspace-delegation-editor-submission.ts +8 -0
  61. package/src/input/agent-workspace-document-editor.ts +502 -0
  62. package/src/input/agent-workspace-document-ops-editor.ts +523 -0
  63. package/src/input/agent-workspace-host-category.ts +1 -1
  64. package/src/input/agent-workspace-local-library-snapshot.ts +167 -0
  65. package/src/input/agent-workspace-model-compare-editor.ts +376 -0
  66. package/src/input/agent-workspace-model-compare-prompt-submission.ts +552 -0
  67. package/src/input/agent-workspace-model-compare-types.ts +82 -0
  68. package/src/input/agent-workspace-model-compare-utils.ts +35 -0
  69. package/src/input/agent-workspace-onboarding-categories.ts +141 -0
  70. package/src/input/agent-workspace-operations-command-editor-submission.ts +53 -0
  71. package/src/input/agent-workspace-operations-command-editors.ts +22 -0
  72. package/src/input/agent-workspace-research-report-editor.ts +212 -0
  73. package/src/input/agent-workspace-research-run-editor.ts +144 -0
  74. package/src/input/agent-workspace-research-source-editor.ts +167 -0
  75. package/src/input/agent-workspace-review-packet-snapshot.ts +593 -0
  76. package/src/input/agent-workspace-review-packet-utils.ts +265 -0
  77. package/src/input/agent-workspace-settings.ts +262 -30
  78. package/src/input/agent-workspace-setup-checkpoint-action.ts +127 -0
  79. package/src/input/agent-workspace-setup-snapshot.ts +198 -0
  80. package/src/input/agent-workspace-setup.ts +34 -1
  81. package/src/input/agent-workspace-snapshot.ts +162 -147
  82. package/src/input/agent-workspace-types.ts +287 -2
  83. package/src/input/agent-workspace.ts +18 -0
  84. package/src/input/command-registry.ts +9 -2
  85. package/src/input/commands/agent-runtime-profile-runtime.ts +28 -13
  86. package/src/input/commands/channels-runtime.ts +102 -114
  87. package/src/input/commands/delegation-runtime.ts +87 -24
  88. package/src/input/commands/knowledge-browser-flags.ts +12 -0
  89. package/src/input/commands/knowledge.ts +28 -14
  90. package/src/input/commands/operator-actions-runtime.ts +6 -3
  91. package/src/input/commands/schedule-runtime.ts +71 -14
  92. package/src/input/commands/session-content.ts +2 -2
  93. package/src/input/commands/shell-core.ts +2 -0
  94. package/src/input/commands/vibe-runtime.ts +140 -0
  95. package/src/input/commands.ts +2 -0
  96. package/src/input/connected-host-routes.ts +123 -0
  97. package/src/input/settings-modal-types.ts +14 -0
  98. package/src/main.ts +15 -15
  99. package/src/panels/qr-panel.ts +2 -2
  100. package/src/renderer/agent-workspace-context-lines.ts +686 -0
  101. package/src/renderer/agent-workspace.ts +30 -419
  102. package/src/renderer/settings-modal-helpers.ts +12 -0
  103. package/src/renderer/settings-modal.ts +12 -0
  104. package/src/runtime/bootstrap-command-context.ts +11 -1
  105. package/src/runtime/bootstrap-command-parts.ts +14 -3
  106. package/src/runtime/bootstrap-core.ts +39 -1
  107. package/src/runtime/bootstrap-shell.ts +6 -0
  108. package/src/runtime/bootstrap.ts +113 -30
  109. package/src/runtime/connected-host-auth.ts +3 -2
  110. package/src/runtime/execution-ledger.ts +231 -0
  111. package/src/runtime/services.ts +88 -10
  112. package/src/runtime/tool-permission-safety.ts +199 -5
  113. package/src/shell/session-continuity-hints.ts +39 -0
  114. package/src/tools/agent-artifacts-tool.ts +606 -0
  115. package/src/tools/agent-audit-tool.ts +155 -0
  116. package/src/tools/agent-autonomy-schedule-tool.ts +238 -0
  117. package/src/tools/agent-autonomy-tool.ts +140 -0
  118. package/src/tools/agent-channel-send-tool.ts +24 -2
  119. package/src/tools/agent-channels-tool.ts +140 -0
  120. package/src/tools/agent-computer-tool.ts +168 -0
  121. package/src/tools/agent-context-policy.ts +137 -7
  122. package/src/tools/agent-context-tool.ts +143 -0
  123. package/src/tools/agent-delegation-tool.ts +128 -0
  124. package/src/tools/agent-device-tool.ts +240 -0
  125. package/src/tools/agent-documents-tool.ts +684 -0
  126. package/src/tools/agent-execution-tool.ts +230 -0
  127. package/src/tools/agent-harness-agent-orchestration.ts +703 -0
  128. package/src/tools/agent-harness-autonomy-intake.ts +785 -0
  129. package/src/tools/agent-harness-autonomy-live-records.ts +588 -0
  130. package/src/tools/agent-harness-autonomy-queue-types.ts +88 -0
  131. package/src/tools/agent-harness-autonomy-queue.ts +560 -0
  132. package/src/tools/agent-harness-background-processes-types.ts +35 -0
  133. package/src/tools/agent-harness-background-processes.ts +794 -0
  134. package/src/tools/agent-harness-browser-cockpit-route.ts +219 -0
  135. package/src/tools/agent-harness-browser-control.ts +338 -0
  136. package/src/tools/agent-harness-channel-metadata.ts +168 -10
  137. package/src/tools/agent-harness-cli-command-policy.ts +110 -0
  138. package/src/tools/agent-harness-command-catalog.ts +4 -2
  139. package/src/tools/agent-harness-command-runner.ts +42 -0
  140. package/src/tools/agent-harness-connected-host-status.ts +7 -4
  141. package/src/tools/agent-harness-delegation-posture.ts +234 -19
  142. package/src/tools/agent-harness-document-ops-reviewer-readiness.ts +234 -0
  143. package/src/tools/agent-harness-document-ops-types.ts +72 -0
  144. package/src/tools/agent-harness-document-ops.ts +671 -0
  145. package/src/tools/agent-harness-execution-history.ts +489 -0
  146. package/src/tools/agent-harness-execution-posture.ts +382 -0
  147. package/src/tools/agent-harness-file-recovery.ts +135 -0
  148. package/src/tools/agent-harness-keybinding-metadata.ts +16 -12
  149. package/src/tools/agent-harness-learning-curator-common.ts +102 -0
  150. package/src/tools/agent-harness-learning-curator-consolidation.ts +295 -0
  151. package/src/tools/agent-harness-learning-curator-proposals.ts +606 -0
  152. package/src/tools/agent-harness-learning-curator-types.ts +151 -0
  153. package/src/tools/agent-harness-learning-curator.ts +417 -0
  154. package/src/tools/agent-harness-local-model-benchmarks.ts +199 -0
  155. package/src/tools/agent-harness-local-model-cookbook.ts +238 -0
  156. package/src/tools/agent-harness-local-model-endpoints.ts +673 -0
  157. package/src/tools/agent-harness-media-posture.ts +208 -2
  158. package/src/tools/agent-harness-memory-posture.ts +556 -0
  159. package/src/tools/agent-harness-metadata.ts +100 -168
  160. package/src/tools/agent-harness-mode-catalog.ts +84 -33
  161. package/src/tools/agent-harness-model-catalog.ts +162 -0
  162. package/src/tools/agent-harness-model-provider-health.ts +186 -0
  163. package/src/tools/agent-harness-model-readiness.ts +406 -0
  164. package/src/tools/agent-harness-model-routing-types.ts +266 -0
  165. package/src/tools/agent-harness-model-routing-utils.ts +30 -0
  166. package/src/tools/agent-harness-model-routing.ts +137 -190
  167. package/src/tools/agent-harness-operator-methods.ts +115 -133
  168. package/src/tools/agent-harness-pairing-posture.ts +431 -18
  169. package/src/tools/agent-harness-personal-ops-discovery.ts +533 -0
  170. package/src/tools/agent-harness-personal-ops-intake.ts +385 -0
  171. package/src/tools/agent-harness-personal-ops-lanes.ts +204 -0
  172. package/src/tools/agent-harness-personal-ops-records.ts +732 -0
  173. package/src/tools/agent-harness-personal-ops-runner.ts +637 -0
  174. package/src/tools/agent-harness-personal-ops-types.ts +222 -0
  175. package/src/tools/agent-harness-personal-ops.ts +606 -0
  176. package/src/tools/agent-harness-project-context.ts +144 -0
  177. package/src/tools/agent-harness-prompt-context.ts +589 -0
  178. package/src/tools/agent-harness-provider-account-metadata.ts +2 -2
  179. package/src/tools/agent-harness-release-evidence.ts +9 -7
  180. package/src/tools/agent-harness-release-readiness.ts +9 -7
  181. package/src/tools/agent-harness-research-briefing.ts +427 -0
  182. package/src/tools/agent-harness-research-queue.ts +250 -0
  183. package/src/tools/agent-harness-research-runs.ts +295 -0
  184. package/src/tools/agent-harness-research-workflow.ts +322 -0
  185. package/src/tools/agent-harness-security-posture.ts +2 -2
  186. package/src/tools/agent-harness-service-posture.ts +9 -9
  187. package/src/tools/agent-harness-session-metadata.ts +3 -3
  188. package/src/tools/agent-harness-setup-connected-host.ts +501 -0
  189. package/src/tools/agent-harness-setup-describe.ts +557 -0
  190. package/src/tools/agent-harness-setup-handoffs.ts +502 -0
  191. package/src/tools/agent-harness-setup-model-helpers.ts +101 -0
  192. package/src/tools/agent-harness-setup-plan.ts +253 -0
  193. package/src/tools/agent-harness-setup-posture-types.ts +218 -0
  194. package/src/tools/agent-harness-setup-posture-utils.ts +173 -0
  195. package/src/tools/agent-harness-setup-posture.ts +449 -221
  196. package/src/tools/agent-harness-setup-smoke.ts +508 -0
  197. package/src/tools/agent-harness-sudo-posture.ts +114 -0
  198. package/src/tools/agent-harness-tool-schema.ts +120 -7
  199. package/src/tools/agent-harness-tool-types.ts +78 -0
  200. package/src/tools/agent-harness-tool-utils.ts +43 -0
  201. package/src/tools/agent-harness-tool.ts +311 -370
  202. package/src/tools/agent-harness-ui-surface-metadata.ts +76 -69
  203. package/src/tools/agent-harness-ui-surface-types.ts +46 -0
  204. package/src/tools/agent-harness-vibe-health.ts +105 -0
  205. package/src/tools/agent-harness-workspace-action-runner.ts +149 -0
  206. package/src/tools/agent-harness-workspace-actions.ts +114 -8
  207. package/src/tools/agent-harness-workspace-editor-execution.ts +214 -0
  208. package/src/tools/agent-harness-workspace-editor-runner.ts +755 -0
  209. package/src/tools/agent-host-tool.ts +159 -0
  210. package/src/tools/agent-knowledge-ingest-tool.ts +34 -1
  211. package/src/tools/agent-learning-consolidation-core.ts +327 -0
  212. package/src/tools/agent-learning-consolidation-tool.ts +758 -0
  213. package/src/tools/agent-memory-tool.ts +214 -0
  214. package/src/tools/agent-model-compare-export.ts +315 -0
  215. package/src/tools/agent-model-compare-handoff.ts +592 -0
  216. package/src/tools/agent-model-compare-judgment.ts +633 -0
  217. package/src/tools/agent-model-compare-run.ts +722 -0
  218. package/src/tools/agent-model-compare-tool.ts +698 -0
  219. package/src/tools/agent-model-compare-types.ts +191 -0
  220. package/src/tools/agent-model-compare-utils.ts +93 -0
  221. package/src/tools/agent-models-tool.ts +208 -0
  222. package/src/tools/agent-operator-action-tool.ts +1 -1
  223. package/src/tools/agent-operator-method-tool.ts +643 -0
  224. package/src/tools/agent-personal-ops-tool.ts +197 -0
  225. package/src/tools/agent-policy-explanation.ts +415 -0
  226. package/src/tools/agent-research-report-tool.ts +608 -0
  227. package/src/tools/agent-research-runs-tool.ts +434 -0
  228. package/src/tools/agent-research-sources-tool.ts +443 -0
  229. package/src/tools/agent-research-tool.ts +687 -0
  230. package/src/tools/agent-review-packet-presets-core.ts +757 -0
  231. package/src/tools/agent-review-packet-presets-tool.ts +466 -0
  232. package/src/tools/agent-review-packet-share-tool.ts +305 -0
  233. package/src/tools/agent-route-planner-candidates-setup.ts +411 -0
  234. package/src/tools/agent-route-planner-candidates-surfaces.ts +432 -0
  235. package/src/tools/agent-route-planner-candidates-work.ts +251 -0
  236. package/src/tools/agent-route-planner-helpers.ts +667 -0
  237. package/src/tools/agent-route-planner.ts +185 -0
  238. package/src/tools/agent-route-tool.ts +105 -0
  239. package/src/tools/agent-schedule-edit-tool.ts +210 -0
  240. package/src/tools/agent-schedule-tool.ts +282 -0
  241. package/src/tools/agent-security-tool.ts +145 -0
  242. package/src/tools/agent-sessions-tool.ts +122 -0
  243. package/src/tools/agent-settings-import-tool.ts +104 -0
  244. package/src/tools/agent-settings-tool.ts +176 -0
  245. package/src/tools/agent-setup-tool.ts +226 -0
  246. package/src/tools/agent-support-tool.ts +122 -0
  247. package/src/tools/agent-terminal-process-tools.ts +167 -0
  248. package/src/tools/agent-tool-policy-guard-types.ts +77 -0
  249. package/src/tools/agent-tool-policy-guard.ts +106 -85
  250. package/src/tools/agent-vibe-tool.ts +297 -0
  251. package/src/tools/agent-work-plan-tool.ts +265 -6
  252. package/src/tools/agent-workspace-tool.ts +305 -0
  253. package/src/tools/artifact-archive.ts +169 -0
  254. package/src/tools/tool-definition-compaction.ts +36 -0
  255. package/src/version.ts +1 -1
@@ -0,0 +1,589 @@
1
+ import type { MemoryApi } from '@pellux/goodvibes-sdk/platform/knowledge';
2
+ import { getTierForContextWindow, getTierPromptSupplement } from '@pellux/goodvibes-sdk/platform/providers';
3
+ import type { MemoryRecord } from '@pellux/goodvibes-sdk/platform/state';
4
+ import { isPromptActiveMemory, MIN_PROMPT_MEMORY_CONFIDENCE } from '../agent/memory-prompt.ts';
5
+ import { AgentPersonaRegistry, buildActivePersonaPrompt } from '../agent/persona-registry.ts';
6
+ import { buildProjectContextPrompt, discoverProjectContextFiles } from '../agent/project-context-files.ts';
7
+ import { AgentRoutineRegistry, buildEnabledRoutinesPrompt, evaluateAgentRoutineReadiness } from '../agent/routine-registry.ts';
8
+ import { AgentSkillRegistry, buildEnabledSkillsPrompt, evaluateAgentSkillBundleReadiness, evaluateAgentSkillReadiness } from '../agent/skill-registry.ts';
9
+ import { buildVibePrompt, discoverVibeFiles } from '../agent/vibe-file.ts';
10
+ import type { PromptContextReceipt } from '../agent/prompt-context-receipts.ts';
11
+ import type { CommandContext } from '../input/command-registry.ts';
12
+ import { previewHarnessText } from './agent-harness-text.ts';
13
+
14
+ interface PromptContextArgs {
15
+ readonly includeParameters?: unknown;
16
+ readonly receiptId?: unknown;
17
+ readonly turnId?: unknown;
18
+ readonly outcomeStatus?: unknown;
19
+ readonly limit?: unknown;
20
+ }
21
+
22
+ type PromptContextSegmentStatus = 'active' | 'attention' | 'empty' | 'unavailable';
23
+ type PromptContextReceiptOutcomeFilter = 'completed' | 'error' | 'cancelled' | 'pending';
24
+
25
+ interface PromptContextSegment {
26
+ readonly id: string;
27
+ readonly label: string;
28
+ readonly status: PromptContextSegmentStatus;
29
+ readonly order: number;
30
+ readonly activeCount: number;
31
+ readonly suppressedCount: number;
32
+ readonly promptChars: number;
33
+ readonly approxTokens: number;
34
+ readonly route?: string;
35
+ readonly selected?: readonly Record<string, unknown>[];
36
+ readonly suppressed?: readonly Record<string, unknown>[];
37
+ readonly note?: string;
38
+ readonly preview?: string;
39
+ }
40
+
41
+ type PromptMemoryApi = Pick<MemoryApi, 'getAll'>;
42
+
43
+ interface PromptModelInfo {
44
+ readonly model: unknown;
45
+ readonly label: string;
46
+ readonly contextWindow: number;
47
+ }
48
+
49
+ interface CompactPromptContextReceipt {
50
+ readonly receiptId: string;
51
+ readonly turnId: string | null;
52
+ readonly source: string;
53
+ readonly createdAt: number;
54
+ readonly provider: string;
55
+ readonly model: string;
56
+ readonly contextWindow: number;
57
+ readonly turnOutcome?: {
58
+ readonly status: string;
59
+ readonly terminalEvent: string;
60
+ readonly stopReason: string;
61
+ readonly completedAt: number;
62
+ readonly detail?: string;
63
+ };
64
+ readonly promptHash?: string;
65
+ readonly promptChars?: number;
66
+ readonly approxPromptTokens?: number;
67
+ readonly activeRecords?: number;
68
+ readonly suppressedRecords?: number;
69
+ readonly segments?: readonly {
70
+ readonly id: string;
71
+ readonly status: string;
72
+ readonly activeCount: number;
73
+ readonly suppressedCount: number;
74
+ readonly promptChars: number;
75
+ readonly approxTokens: number;
76
+ }[];
77
+ }
78
+
79
+ function readPromptString(value: unknown): string {
80
+ return typeof value === 'string' ? value.trim() : '';
81
+ }
82
+
83
+ function readPromptLimit(value: unknown, fallback: number): number {
84
+ const parsed = typeof value === 'string' && value.trim() ? Number(value) : value;
85
+ if (typeof parsed !== 'number' || !Number.isFinite(parsed)) return fallback;
86
+ return Math.max(1, Math.min(50, Math.trunc(parsed)));
87
+ }
88
+
89
+ function readOutcomeStatus(value: unknown): PromptContextReceiptOutcomeFilter | null {
90
+ if (value === 'completed' || value === 'error' || value === 'cancelled' || value === 'pending') return value;
91
+ return null;
92
+ }
93
+
94
+ function promptContextReceiptOutcomeStatus(receipt: PromptContextReceipt): PromptContextReceiptOutcomeFilter {
95
+ return receipt.turnOutcome?.status ?? 'pending';
96
+ }
97
+
98
+ function promptContextQuote(value: string): string {
99
+ return JSON.stringify(value);
100
+ }
101
+
102
+ function promptContextReceiptRoute(receiptId: string): string {
103
+ return `context action:"receipt" receiptId:${promptContextQuote(receiptId)} includeParameters:true`;
104
+ }
105
+
106
+ function promptContextTurnRoute(turnId: string): string {
107
+ return `context action:"receipt" turnId:${promptContextQuote(turnId)} includeParameters:true`;
108
+ }
109
+
110
+ function promptContextOutcomeRoute(status: PromptContextReceiptOutcomeFilter): string {
111
+ return `context action:"receipts" outcomeStatus:${promptContextQuote(status)} includeParameters:true`;
112
+ }
113
+
114
+ function approxTokens(text: string): number {
115
+ return Math.ceil(text.length / 4);
116
+ }
117
+
118
+ function modelLabel(model: unknown): string {
119
+ if (typeof model === 'string' && model.trim()) return model.trim();
120
+ if (typeof model === 'object' && model !== null) {
121
+ const candidate = model as { readonly registryKey?: unknown; readonly id?: unknown; readonly modelId?: unknown };
122
+ for (const value of [candidate.registryKey, candidate.id, candidate.modelId]) {
123
+ if (typeof value === 'string' && value.trim()) return value.trim();
124
+ }
125
+ }
126
+ return 'unknown';
127
+ }
128
+
129
+ function promptModelInfo(context: CommandContext): PromptModelInfo {
130
+ const registry = context.provider.providerRegistry as {
131
+ readonly getCurrentModel?: () => unknown;
132
+ readonly getContextWindowForModel?: (model: unknown) => number;
133
+ };
134
+ let model: unknown = context.session.runtime.model ?? 'unknown';
135
+ if (typeof registry.getCurrentModel === 'function') {
136
+ try {
137
+ model = registry.getCurrentModel();
138
+ } catch {
139
+ model = context.session.runtime.model ?? model;
140
+ }
141
+ }
142
+ let contextWindow = 0;
143
+ if (typeof registry.getContextWindowForModel === 'function') {
144
+ const value = registry.getContextWindowForModel(model);
145
+ contextWindow = Number.isFinite(value) ? Math.max(0, Math.trunc(value)) : 0;
146
+ }
147
+ return { model, label: modelLabel(model), contextWindow };
148
+ }
149
+
150
+ function promptMemoryApi(value: unknown): PromptMemoryApi | undefined {
151
+ if (typeof value !== 'object' || value === null) return undefined;
152
+ const candidate = value as { readonly getAll?: unknown };
153
+ return typeof candidate.getAll === 'function' ? candidate as PromptMemoryApi : undefined;
154
+ }
155
+
156
+ function segment(
157
+ input: Omit<PromptContextSegment, 'approxTokens'> & { readonly promptText?: string | null },
158
+ includeParameters: boolean,
159
+ ): PromptContextSegment {
160
+ const promptChars = input.promptText?.length ?? input.promptChars;
161
+ return {
162
+ id: input.id,
163
+ label: input.label,
164
+ status: input.status,
165
+ order: input.order,
166
+ activeCount: input.activeCount,
167
+ suppressedCount: input.suppressedCount,
168
+ promptChars,
169
+ approxTokens: approxTokens(input.promptText ?? ''),
170
+ ...(input.route ? { route: input.route } : {}),
171
+ ...(input.selected ? { selected: input.selected } : {}),
172
+ ...(input.suppressed ? { suppressed: input.suppressed } : {}),
173
+ ...(input.note ? { note: input.note } : {}),
174
+ ...(includeParameters && input.promptText ? { preview: previewHarnessText(input.promptText, 360) } : {}),
175
+ };
176
+ }
177
+
178
+ function memorySort(left: MemoryRecord, right: MemoryRecord): number {
179
+ if (right.confidence !== left.confidence) return right.confidence - left.confidence;
180
+ return right.updatedAt - left.updatedAt;
181
+ }
182
+
183
+ function formatMemoryLine(record: MemoryRecord): string {
184
+ const tags = record.tags.length > 0 ? ` tags=${record.tags.join(',')}` : '';
185
+ const provenance = record.provenance.length > 0
186
+ ? ` source=${record.provenance.slice(0, 2).map((entry) => `${entry.kind}:${entry.ref}`).join(',')}`
187
+ : '';
188
+ return `- [${record.scope}/${record.cls} ${record.confidence}%${tags}${provenance}] ${record.summary}`;
189
+ }
190
+
191
+ function promptMemoryRecords(memory: PromptMemoryApi | undefined): readonly MemoryRecord[] {
192
+ if (!memory) return [];
193
+ return memory.getAll().filter(isPromptActiveMemory).sort(memorySort).slice(0, 10);
194
+ }
195
+
196
+ function buildMemoryPromptFromRecords(records: readonly MemoryRecord[]): string {
197
+ return [
198
+ '## Reviewed GoodVibes Agent Memory',
199
+ `Use these local, reviewed, non-secret memory records with confidence >= ${MIN_PROMPT_MEMORY_CONFIDENCE}% to avoid asking repeat questions and to preserve durable user preferences, constraints, and operating facts.`,
200
+ ...records.map(formatMemoryLine),
201
+ ].join('\n');
202
+ }
203
+
204
+ function memorySegment(memory: PromptMemoryApi | undefined, includeParameters: boolean): PromptContextSegment {
205
+ if (!memory) {
206
+ return segment({
207
+ id: 'memory',
208
+ label: 'Reviewed memory',
209
+ status: 'unavailable',
210
+ order: 4,
211
+ activeCount: 0,
212
+ suppressedCount: 0,
213
+ promptChars: 0,
214
+ route: 'memory action:"status"',
215
+ note: 'Agent-local memory API is unavailable in this runtime.',
216
+ }, includeParameters);
217
+ }
218
+ const all = memory.getAll();
219
+ const active = promptMemoryRecords(memory);
220
+ const activeIds = new Set(active.map((record) => record.id));
221
+ const suppressed = all.filter((record) => !activeIds.has(record.id));
222
+ const promptText = active.length > 0 ? buildMemoryPromptFromRecords(active) : '';
223
+ return segment({
224
+ id: 'memory',
225
+ label: 'Reviewed memory',
226
+ status: suppressed.length > 0 ? 'attention' : active.length > 0 ? 'active' : 'empty',
227
+ order: 4,
228
+ activeCount: active.length,
229
+ suppressedCount: suppressed.length,
230
+ promptChars: promptText.length,
231
+ promptText,
232
+ route: 'memory action:"status"',
233
+ selected: active.map((record) => ({
234
+ id: record.id,
235
+ scope: record.scope,
236
+ class: record.cls,
237
+ confidence: record.confidence,
238
+ inspectRoute: `agent_local_registry domain:"memory" action:"get" recordId:"${record.id}"`,
239
+ })),
240
+ suppressed: suppressed.slice(0, 12).map((record) => ({
241
+ id: record.id,
242
+ reviewState: record.reviewState,
243
+ confidence: record.confidence,
244
+ reason: record.reviewState !== 'reviewed'
245
+ ? 'not reviewed'
246
+ : record.confidence < MIN_PROMPT_MEMORY_CONFIDENCE
247
+ ? `confidence below ${MIN_PROMPT_MEMORY_CONFIDENCE}`
248
+ : 'outside prompt limit',
249
+ inspectRoute: `agent_local_registry domain:"memory" action:"get" recordId:"${record.id}"`,
250
+ })),
251
+ }, includeParameters);
252
+ }
253
+
254
+ function promptStatus(active: number, suppressed: number): PromptContextSegmentStatus {
255
+ if (suppressed > 0) return 'attention';
256
+ if (active > 0) return 'active';
257
+ return 'empty';
258
+ }
259
+
260
+ function compactPromptContextReceipt(
261
+ receipt: PromptContextReceipt,
262
+ includeParameters: boolean,
263
+ ): CompactPromptContextReceipt {
264
+ return {
265
+ receiptId: receipt.receiptId,
266
+ turnId: receipt.turnId,
267
+ source: receipt.source,
268
+ createdAt: receipt.createdAt,
269
+ provider: receipt.provider,
270
+ model: receipt.model,
271
+ contextWindow: receipt.contextWindow,
272
+ ...(receipt.turnOutcome ? {
273
+ turnOutcome: {
274
+ status: receipt.turnOutcome.status,
275
+ terminalEvent: receipt.turnOutcome.terminalEvent,
276
+ stopReason: receipt.turnOutcome.stopReason,
277
+ completedAt: receipt.turnOutcome.completedAt,
278
+ ...(receipt.turnOutcome.detail ? { detail: receipt.turnOutcome.detail } : {}),
279
+ },
280
+ } : {}),
281
+ ...(includeParameters ? {
282
+ promptHash: receipt.promptHash,
283
+ promptChars: receipt.promptChars,
284
+ approxPromptTokens: receipt.approxPromptTokens,
285
+ activeRecords: receipt.activeRecords,
286
+ suppressedRecords: receipt.suppressedRecords,
287
+ segments: receipt.segments.map((segment) => ({
288
+ id: segment.id,
289
+ status: segment.status,
290
+ activeCount: segment.activeCount,
291
+ suppressedCount: segment.suppressedCount,
292
+ promptChars: segment.promptChars,
293
+ approxTokens: segment.approxTokens,
294
+ })),
295
+ } : {}),
296
+ };
297
+ }
298
+
299
+ function promptContextReceiptSummary(context: CommandContext, args: PromptContextArgs, includeParameters: boolean): Record<string, unknown> {
300
+ const store = context.clients?.promptContextReceipts;
301
+ if (!store) {
302
+ return {
303
+ status: 'unavailable',
304
+ count: 0,
305
+ latestReceiptId: null,
306
+ latestTurnId: null,
307
+ latestCreatedAt: null,
308
+ note: 'Prompt-context receipt storage is unavailable in this runtime.',
309
+ };
310
+ }
311
+ const receiptId = readPromptString(args.receiptId);
312
+ const turnId = readPromptString(args.turnId);
313
+ const outcomeStatus = readOutcomeStatus(args.outcomeStatus);
314
+ const hasFilter = Boolean(receiptId || turnId || outcomeStatus);
315
+ const limit = readPromptLimit(args.limit, includeParameters ? 5 : 3);
316
+ const latest = store.latest();
317
+ const allReceipts = store.list(Math.max(store.count(), limit));
318
+ const baseReceipts = receiptId ? allReceipts.filter((receipt) => receipt.receiptId === receiptId) : allReceipts;
319
+ const matchingReceipts = baseReceipts.filter((receipt) => {
320
+ if (turnId && receipt.turnId !== turnId) return false;
321
+ if (outcomeStatus && promptContextReceiptOutcomeStatus(receipt) !== outcomeStatus) return false;
322
+ return true;
323
+ });
324
+ const recent = matchingReceipts.slice(0, limit);
325
+ const selected = hasFilter ? recent[0] ?? null : null;
326
+ const filters = {
327
+ ...(receiptId ? { receiptId } : {}),
328
+ ...(turnId ? { turnId } : {}),
329
+ ...(outcomeStatus ? { outcomeStatus } : {}),
330
+ limit,
331
+ };
332
+ return {
333
+ status: latest ? hasFilter && recent.length === 0 ? 'not_found' : 'ready' : 'empty',
334
+ count: store.count(),
335
+ latestReceiptId: latest?.receiptId ?? null,
336
+ latestTurnId: latest?.turnId ?? null,
337
+ latestCreatedAt: latest?.createdAt ?? null,
338
+ inspectRoute: 'context action:"prompt" includeParameters:true',
339
+ matchingCount: matchingReceipts.length,
340
+ ...(hasFilter ? { filters } : {}),
341
+ selected: selected ? compactPromptContextReceipt(selected, includeParameters) : null,
342
+ recent: recent.map((receipt) => compactPromptContextReceipt(receipt, includeParameters)),
343
+ routes: {
344
+ latestReceipt: latest ? promptContextReceiptRoute(latest.receiptId) : null,
345
+ filterCompleted: promptContextOutcomeRoute('completed'),
346
+ filterErrors: promptContextOutcomeRoute('error'),
347
+ filterCancelled: promptContextOutcomeRoute('cancelled'),
348
+ filterPending: promptContextOutcomeRoute('pending'),
349
+ ...(latest?.turnId ? { latestTurn: promptContextTurnRoute(latest.turnId) } : {}),
350
+ ...(selected ? { selectedReceipt: promptContextReceiptRoute(selected.receiptId) } : {}),
351
+ },
352
+ ...(includeParameters ? { latest: latest ? compactPromptContextReceipt(latest, true) : null } : {}),
353
+ };
354
+ }
355
+
356
+ function promptContextSegments(context: CommandContext, includeParameters: boolean): readonly PromptContextSegment[] {
357
+ const shellPaths = context.workspace.shellPaths;
358
+ const runtimePrompt = context.session.runtime.systemPrompt ?? '';
359
+ const { label: currentModel, contextWindow } = promptModelInfo(context);
360
+ const tier = getTierForContextWindow(contextWindow);
361
+ const tierPrompt = getTierPromptSupplement(tier);
362
+ if (!shellPaths) {
363
+ return [
364
+ segment({
365
+ id: 'base_system_prompt',
366
+ label: 'Base system prompt',
367
+ status: runtimePrompt ? 'active' : 'empty',
368
+ order: 1,
369
+ activeCount: runtimePrompt ? 1 : 0,
370
+ suppressedCount: 0,
371
+ promptChars: runtimePrompt.length,
372
+ promptText: runtimePrompt,
373
+ }, includeParameters),
374
+ segment({
375
+ id: 'agent_local_context',
376
+ label: 'Agent-local context',
377
+ status: 'unavailable',
378
+ order: 2,
379
+ activeCount: 0,
380
+ suppressedCount: 0,
381
+ promptChars: 0,
382
+ note: 'Agent shell paths are unavailable, so VIBE.md, project context, personas, skills, routines, and local registry files cannot be inspected.',
383
+ }, includeParameters),
384
+ ];
385
+ }
386
+
387
+ const vibe = discoverVibeFiles(shellPaths);
388
+ const vibePrompt = buildVibePrompt(shellPaths) ?? '';
389
+ const projectContext = discoverProjectContextFiles(shellPaths);
390
+ const projectContextPrompt = buildProjectContextPrompt(shellPaths) ?? '';
391
+ const personaSnapshot = AgentPersonaRegistry.fromShellPaths(shellPaths).snapshot();
392
+ const activePersona = personaSnapshot.activePersona;
393
+ const personaPrompt = buildActivePersonaPrompt(shellPaths) ?? '';
394
+ const routineSnapshot = AgentRoutineRegistry.fromShellPaths(shellPaths).snapshot();
395
+ const activeRoutines = routineSnapshot.enabledRoutines.filter((routine) => routine.reviewState === 'reviewed' && evaluateAgentRoutineReadiness(routine).ready);
396
+ const suppressedRoutines = routineSnapshot.enabledRoutines.filter((routine) => !activeRoutines.some((active) => active.id === routine.id));
397
+ const routinePrompt = buildEnabledRoutinesPrompt(shellPaths) ?? '';
398
+ const skillSnapshot = AgentSkillRegistry.fromShellPaths(shellPaths).snapshot();
399
+ const activeBundles = skillSnapshot.enabledBundles.filter((bundle) => {
400
+ if (bundle.reviewState !== 'reviewed') return false;
401
+ const readiness = evaluateAgentSkillBundleReadiness(bundle, skillSnapshot.skills);
402
+ return readiness.ready && readiness.includedSkills.every((skill) => skill.reviewState === 'reviewed');
403
+ });
404
+ const activeSkillIds = new Set([
405
+ ...skillSnapshot.enabledSkills.map((skill) => skill.id),
406
+ ...activeBundles.flatMap((bundle) => bundle.skillIds),
407
+ ]);
408
+ const activeSkills = skillSnapshot.skills.filter((skill) => activeSkillIds.has(skill.id) && skill.reviewState === 'reviewed' && evaluateAgentSkillReadiness(skill).ready);
409
+ const candidateSkillIds = new Set([
410
+ ...skillSnapshot.enabledSkills.map((skill) => skill.id),
411
+ ...skillSnapshot.enabledBundles.flatMap((bundle) => bundle.skillIds),
412
+ ]);
413
+ const suppressedSkills = skillSnapshot.skills.filter((skill) => candidateSkillIds.has(skill.id) && !activeSkills.some((active) => active.id === skill.id));
414
+ const suppressedBundles = skillSnapshot.enabledBundles.filter((bundle) => !activeBundles.some((active) => active.id === bundle.id));
415
+ const skillPrompt = buildEnabledSkillsPrompt(shellPaths) ?? '';
416
+ const memory = promptMemoryApi(context.clients?.agentKnowledgeApi?.memory);
417
+
418
+ return [
419
+ segment({
420
+ id: 'base_system_prompt',
421
+ label: 'Base system prompt',
422
+ status: runtimePrompt ? 'active' : 'empty',
423
+ order: 1,
424
+ activeCount: runtimePrompt ? 1 : 0,
425
+ suppressedCount: 0,
426
+ promptChars: runtimePrompt.length,
427
+ promptText: runtimePrompt,
428
+ note: 'Runtime-owned base instructions are applied before Agent-local context.',
429
+ }, includeParameters),
430
+ segment({
431
+ id: 'vibe',
432
+ label: 'VIBE.md personality',
433
+ status: promptStatus(vibe.files.length, vibe.blocked.length + vibe.files.filter((file) => file.truncated).length),
434
+ order: 2,
435
+ activeCount: vibe.files.length,
436
+ suppressedCount: vibe.blocked.length,
437
+ promptChars: vibePrompt.length,
438
+ promptText: vibePrompt,
439
+ route: 'vibe action:"status"',
440
+ selected: vibe.files.map((file) => ({ path: file.path, scope: file.scope, truncated: file.truncated })),
441
+ suppressed: vibe.blocked.map((file) => ({ path: file.path, scope: file.scope, reason: file.reason })),
442
+ }, includeParameters),
443
+ segment({
444
+ id: 'project_context',
445
+ label: 'Project context files',
446
+ status: promptStatus(projectContext.files.length, projectContext.blocked.length + projectContext.files.filter((file) => file.truncated).length),
447
+ order: 3,
448
+ activeCount: projectContext.files.length,
449
+ suppressedCount: projectContext.blocked.length,
450
+ promptChars: projectContextPrompt.length,
451
+ promptText: projectContextPrompt,
452
+ route: 'context action:"files"',
453
+ selected: projectContext.files.map((file) => ({
454
+ id: file.id,
455
+ source: file.source,
456
+ scope: file.scope,
457
+ truncated: file.truncated,
458
+ inspectRoute: `context action:"file" contextFileId:"${file.id}"`,
459
+ })),
460
+ suppressed: projectContext.blocked.map((file) => ({ id: file.id, source: file.source, reason: file.reason })),
461
+ }, includeParameters),
462
+ memorySegment(memory, includeParameters),
463
+ segment({
464
+ id: 'routines',
465
+ label: 'Reviewed setup-ready routines',
466
+ status: promptStatus(activeRoutines.length, suppressedRoutines.length),
467
+ order: 5,
468
+ activeCount: activeRoutines.length,
469
+ suppressedCount: suppressedRoutines.length,
470
+ promptChars: routinePrompt.length,
471
+ promptText: routinePrompt,
472
+ route: 'memory action:"curator" query:"routine"',
473
+ selected: activeRoutines.map((routine) => ({ id: routine.id, name: routine.name, inspectRoute: `agent_local_registry domain:"routine" action:"get" recordId:"${routine.id}"` })),
474
+ suppressed: suppressedRoutines.slice(0, 12).map((routine) => ({
475
+ id: routine.id,
476
+ reviewState: routine.reviewState,
477
+ missingRequirements: evaluateAgentRoutineReadiness(routine).missing.length,
478
+ })),
479
+ }, includeParameters),
480
+ segment({
481
+ id: 'skills',
482
+ label: 'Reviewed setup-ready skills and bundles',
483
+ status: promptStatus(activeSkills.length + activeBundles.length, suppressedSkills.length + suppressedBundles.length),
484
+ order: 6,
485
+ activeCount: activeSkills.length + activeBundles.length,
486
+ suppressedCount: suppressedSkills.length + suppressedBundles.length,
487
+ promptChars: skillPrompt.length,
488
+ promptText: skillPrompt,
489
+ route: 'memory action:"curator" query:"skill"',
490
+ selected: [
491
+ ...activeBundles.map((bundle) => ({ id: bundle.id, domain: 'skill_bundle', name: bundle.name, inspectRoute: `agent_local_registry domain:"skill_bundle" action:"get" recordId:"${bundle.id}"` })),
492
+ ...activeSkills.map((skill) => ({ id: skill.id, domain: 'skill', name: skill.name, inspectRoute: `agent_local_registry domain:"skill" action:"get" recordId:"${skill.id}"` })),
493
+ ],
494
+ suppressed: [
495
+ ...suppressedBundles.slice(0, 6).map((bundle) => ({ id: bundle.id, domain: 'skill_bundle', reviewState: bundle.reviewState })),
496
+ ...suppressedSkills.slice(0, 12).map((skill) => ({
497
+ id: skill.id,
498
+ domain: 'skill',
499
+ reviewState: skill.reviewState,
500
+ missingRequirements: evaluateAgentSkillReadiness(skill).missing.length,
501
+ })),
502
+ ],
503
+ }, includeParameters),
504
+ segment({
505
+ id: 'persona',
506
+ label: 'Active persona',
507
+ status: activePersona && activePersona.reviewState !== 'reviewed' ? 'attention' : activePersona ? 'active' : 'empty',
508
+ order: 7,
509
+ activeCount: activePersona?.reviewState === 'reviewed' ? 1 : 0,
510
+ suppressedCount: activePersona && activePersona.reviewState !== 'reviewed' ? 1 : 0,
511
+ promptChars: personaPrompt.length,
512
+ promptText: personaPrompt,
513
+ route: 'memory action:"curator" query:"persona"',
514
+ selected: activePersona?.reviewState === 'reviewed' ? [{ id: activePersona.id, name: activePersona.name, inspectRoute: `agent_local_registry domain:"persona" action:"get" recordId:"${activePersona.id}"` }] : [],
515
+ suppressed: activePersona && activePersona.reviewState !== 'reviewed' ? [{ id: activePersona.id, name: activePersona.name, reviewState: activePersona.reviewState }] : [],
516
+ }, includeParameters),
517
+ segment({
518
+ id: 'context_window_supplement',
519
+ label: 'Context-window supplement',
520
+ status: tierPrompt ? 'active' : 'empty',
521
+ order: 8,
522
+ activeCount: tierPrompt ? 1 : 0,
523
+ suppressedCount: 0,
524
+ promptChars: tierPrompt.length,
525
+ promptText: tierPrompt,
526
+ note: `Model ${currentModel} has context window ${contextWindow}; tier ${tier}.`,
527
+ }, includeParameters),
528
+ ];
529
+ }
530
+
531
+ export function promptContextSummary(context: CommandContext, args: PromptContextArgs): Record<string, unknown> {
532
+ const includeParameters = args.includeParameters === true;
533
+ const segments = [...promptContextSegments(context, includeParameters)].sort((left, right) => left.order - right.order);
534
+ const activeRecords = segments.reduce((total, entry) => total + entry.activeCount, 0);
535
+ const suppressedRecords = segments.reduce((total, entry) => total + entry.suppressedCount, 0);
536
+ const promptChars = segments.reduce((total, entry) => total + entry.promptChars, 0);
537
+ const approxPromptTokens = segments.reduce((total, entry) => total + entry.approxTokens, 0);
538
+ const { label: currentModel, contextWindow } = promptModelInfo(context);
539
+ const status = segments.some((entry) => entry.status === 'unavailable')
540
+ ? 'unavailable'
541
+ : suppressedRecords > 0 || segments.some((entry) => entry.status === 'attention')
542
+ ? 'attention'
543
+ : activeRecords > 0
544
+ ? 'ready'
545
+ : 'empty';
546
+ return {
547
+ status,
548
+ order: ['base_system_prompt', 'vibe', 'project_context', 'operator_policy', 'memory', 'routines', 'skills', 'persona', 'context_window_supplement'],
549
+ model: currentModel,
550
+ provider: context.session.runtime.provider,
551
+ contextWindow,
552
+ activeSegments: segments.filter((entry) => entry.status === 'active' || entry.status === 'attention').length,
553
+ activeRecords,
554
+ suppressedRecords,
555
+ promptChars,
556
+ approxPromptTokens,
557
+ budget: {
558
+ approxPromptTokens,
559
+ contextWindow,
560
+ percentOfWindow: contextWindow > 0 ? Math.round((approxPromptTokens / contextWindow) * 1000) / 10 : null,
561
+ },
562
+ receipts: promptContextReceiptSummary(context, args, includeParameters),
563
+ segments,
564
+ routes: {
565
+ promptPlan: 'memory action:"curator" includeParameters:true',
566
+ memoryPosture: 'memory action:"status"',
567
+ projectContext: 'context action:"files"',
568
+ vibeStatus: 'vibe action:"status"',
569
+ learningCurator: 'memory action:"curator"',
570
+ },
571
+ policy: 'Read-only prompt context inspection. It reports current prompt composition, selected records, suppressed review/setup work, and approximate token budget without creating memory, mutating behavior, or dumping raw secrets.',
572
+ };
573
+ }
574
+
575
+ export function promptContextCatalogStatus(context: CommandContext): Record<string, unknown> {
576
+ const summary = promptContextSummary(context, {});
577
+ const receipts = context.clients?.promptContextReceipts;
578
+ const latestReceipt = receipts?.latest() ?? null;
579
+ return {
580
+ modes: ['prompt_context'],
581
+ status: summary.status,
582
+ activeRecords: summary.activeRecords,
583
+ suppressedRecords: summary.suppressedRecords,
584
+ approxPromptTokens: summary.approxPromptTokens,
585
+ receiptCount: receipts?.count() ?? 0,
586
+ latestReceiptId: latestReceipt?.receiptId ?? null,
587
+ modelRoute: 'context action:"prompt" includeParameters:true',
588
+ };
589
+ }
@@ -189,7 +189,7 @@ export async function describeHarnessProviderAccount(
189
189
  if (!lookup) {
190
190
  return {
191
191
  status: 'missing_lookup',
192
- usage: 'provider_account requires providerId, target, or query. Use mode:"provider_accounts" to inspect provider ids.',
192
+ usage: 'provider_account requires providerId, target, or query. Prefer models action:"providers" to inspect provider ids.',
193
193
  };
194
194
  }
195
195
  const snapshot = await loadSnapshot(context);
@@ -211,6 +211,6 @@ export async function describeHarnessProviderAccount(
211
211
  }
212
212
  return {
213
213
  status: 'missing_lookup',
214
- usage: `Unknown provider account ${lookup.input}. Use mode:"provider_accounts" to inspect provider ids.`,
214
+ usage: `Unknown provider account ${lookup.input}. Prefer models action:"providers" to inspect provider ids.`,
215
215
  };
216
216
  }
@@ -122,8 +122,8 @@ function artifactSearchText(artifact: ReleaseEvidenceArtifact): string {
122
122
  }
123
123
 
124
124
  function releaseEvidenceModelRoute(artifact?: ReleaseEvidenceArtifact): string {
125
- if (artifact) return 'agent_harness mode:"release_evidence_artifact"';
126
- return 'agent_harness mode:"release_evidence" or mode:"release_evidence_artifact"';
125
+ if (artifact) return 'audit action:"artifact"';
126
+ return 'audit action:"evidence" or action:"artifact"';
127
127
  }
128
128
 
129
129
  function releaseEvidencePolicy(): Record<string, unknown> {
@@ -273,8 +273,9 @@ function summarizeLoadedArtifact(
273
273
  summary,
274
274
  policy: releaseEvidencePolicy(),
275
275
  modelAccess: {
276
- listArtifacts: 'agent_harness mode:"release_evidence"',
277
- inspectArtifact: `agent_harness mode:"release_evidence_artifact" artifactId:"${loaded.artifact.id}"`,
276
+ listArtifacts: 'audit action:"evidence"',
277
+ inspectArtifact: `audit action:"artifact" artifactId:"${loaded.artifact.id}"`,
278
+ lowerLevelArtifact: `agent_harness mode:"release_evidence_artifact" artifactId:"${loaded.artifact.id}" includeParameters:true`,
278
279
  includeContent: 'Pass includeParameters:true only when release audit requires artifact content.',
279
280
  },
280
281
  ...(options.includeSource
@@ -323,10 +324,11 @@ export function releaseEvidenceSummary(args: ReleaseEvidenceArgs): Record<string
323
324
  artifactsList: loaded.map((artifact) => summarizeLoadedArtifact(artifact, { includeSource: args.includeParameters === true })),
324
325
  policy: releaseEvidencePolicy(),
325
326
  modelAccess: {
326
- listArtifacts: 'agent_harness mode:"release_evidence"',
327
- inspectArtifact: 'agent_harness mode:"release_evidence_artifact" with artifactId, target, or query',
327
+ listArtifacts: 'audit action:"evidence"',
328
+ inspectArtifact: 'audit action:"artifact" with artifactId, target, or query',
329
+ lowerLevelArtifact: 'agent_harness mode:"release_evidence_artifact" artifactId:"..." includeParameters:true',
328
330
  },
329
- artifactLookup: 'Use mode:"release_evidence_artifact" with artifactId, target, or query to inspect one release evidence artifact.',
331
+ artifactLookup: 'Use audit action:"artifact" with artifactId, target, or query to inspect one release evidence artifact; lower-level agent_harness mode:"release_evidence_artifact" remains available.',
330
332
  };
331
333
  }
332
334