thehood 0.1.0-preview.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/CODE_OF_CONDUCT.md +21 -0
  2. package/CONTRIBUTING.md +58 -0
  3. package/LICENSE +21 -0
  4. package/PRIVACY.md +49 -0
  5. package/README.md +264 -0
  6. package/SECURITY.md +31 -0
  7. package/dist/bridges/chatgptWebBridge.d.ts +2 -0
  8. package/dist/bridges/chatgptWebBridge.js +981 -0
  9. package/dist/bridges/chatgptWebBridge.js.map +1 -0
  10. package/dist/cli/args.d.ts +9 -0
  11. package/dist/cli/args.js +82 -0
  12. package/dist/cli/args.js.map +1 -0
  13. package/dist/cli/format.d.ts +56 -0
  14. package/dist/cli/format.js +752 -0
  15. package/dist/cli/format.js.map +1 -0
  16. package/dist/cli/main.d.ts +2 -0
  17. package/dist/cli/main.js +996 -0
  18. package/dist/cli/main.js.map +1 -0
  19. package/dist/cli/mcpConfig.d.ts +36 -0
  20. package/dist/cli/mcpConfig.js +98 -0
  21. package/dist/cli/mcpConfig.js.map +1 -0
  22. package/dist/index.d.ts +37 -0
  23. package/dist/index.js +38 -0
  24. package/dist/index.js.map +1 -0
  25. package/dist/mcp/protocol.d.ts +44 -0
  26. package/dist/mcp/protocol.js +33 -0
  27. package/dist/mcp/protocol.js.map +1 -0
  28. package/dist/mcp/server.d.ts +1 -0
  29. package/dist/mcp/server.js +106 -0
  30. package/dist/mcp/server.js.map +1 -0
  31. package/dist/mcp/tools.d.ts +10 -0
  32. package/dist/mcp/tools.js +2200 -0
  33. package/dist/mcp/tools.js.map +1 -0
  34. package/dist/mcp/validation.d.ts +8 -0
  35. package/dist/mcp/validation.js +67 -0
  36. package/dist/mcp/validation.js.map +1 -0
  37. package/dist/providers/chatgptWeb.d.ts +2 -0
  38. package/dist/providers/chatgptWeb.js +26 -0
  39. package/dist/providers/chatgptWeb.js.map +1 -0
  40. package/dist/providers/claudeCode.d.ts +4 -0
  41. package/dist/providers/claudeCode.js +32 -0
  42. package/dist/providers/claudeCode.js.map +1 -0
  43. package/dist/providers/codexCli.d.ts +6 -0
  44. package/dist/providers/codexCli.js +25 -0
  45. package/dist/providers/codexCli.js.map +1 -0
  46. package/dist/providers/codexCliModels.d.ts +23 -0
  47. package/dist/providers/codexCliModels.js +147 -0
  48. package/dist/providers/codexCliModels.js.map +1 -0
  49. package/dist/providers/localCommand.d.ts +26 -0
  50. package/dist/providers/localCommand.js +614 -0
  51. package/dist/providers/localCommand.js.map +1 -0
  52. package/dist/providers/markdownPayload.d.ts +7 -0
  53. package/dist/providers/markdownPayload.js +29 -0
  54. package/dist/providers/markdownPayload.js.map +1 -0
  55. package/dist/providers/responseSchema.d.ts +3 -0
  56. package/dist/providers/responseSchema.js +187 -0
  57. package/dist/providers/responseSchema.js.map +1 -0
  58. package/dist/providers/router.d.ts +3 -0
  59. package/dist/providers/router.js +21 -0
  60. package/dist/providers/router.js.map +1 -0
  61. package/dist/providers/stub.d.ts +2 -0
  62. package/dist/providers/stub.js +177 -0
  63. package/dist/providers/stub.js.map +1 -0
  64. package/dist/providers/types.d.ts +37 -0
  65. package/dist/providers/types.js +2 -0
  66. package/dist/providers/types.js.map +1 -0
  67. package/dist/runtime/agentBoard.d.ts +79 -0
  68. package/dist/runtime/agentBoard.js +166 -0
  69. package/dist/runtime/agentBoard.js.map +1 -0
  70. package/dist/runtime/agentBoardArtifact.d.ts +9 -0
  71. package/dist/runtime/agentBoardArtifact.js +171 -0
  72. package/dist/runtime/agentBoardArtifact.js.map +1 -0
  73. package/dist/runtime/agentRunner.d.ts +17 -0
  74. package/dist/runtime/agentRunner.js +92 -0
  75. package/dist/runtime/agentRunner.js.map +1 -0
  76. package/dist/runtime/approvalInbox.d.ts +54 -0
  77. package/dist/runtime/approvalInbox.js +143 -0
  78. package/dist/runtime/approvalInbox.js.map +1 -0
  79. package/dist/runtime/approvalPolicy.d.ts +11 -0
  80. package/dist/runtime/approvalPolicy.js +58 -0
  81. package/dist/runtime/approvalPolicy.js.map +1 -0
  82. package/dist/runtime/artifacts.d.ts +23 -0
  83. package/dist/runtime/artifacts.js +48 -0
  84. package/dist/runtime/artifacts.js.map +1 -0
  85. package/dist/runtime/browserManager.d.ts +37 -0
  86. package/dist/runtime/browserManager.js +356 -0
  87. package/dist/runtime/browserManager.js.map +1 -0
  88. package/dist/runtime/canonicalMemory.d.ts +23 -0
  89. package/dist/runtime/canonicalMemory.js +134 -0
  90. package/dist/runtime/canonicalMemory.js.map +1 -0
  91. package/dist/runtime/chatGptPageReadiness.d.ts +16 -0
  92. package/dist/runtime/chatGptPageReadiness.js +74 -0
  93. package/dist/runtime/chatGptPageReadiness.js.map +1 -0
  94. package/dist/runtime/commandRunner.d.ts +18 -0
  95. package/dist/runtime/commandRunner.js +115 -0
  96. package/dist/runtime/commandRunner.js.map +1 -0
  97. package/dist/runtime/commandSafety.d.ts +7 -0
  98. package/dist/runtime/commandSafety.js +61 -0
  99. package/dist/runtime/commandSafety.js.map +1 -0
  100. package/dist/runtime/config.d.ts +10 -0
  101. package/dist/runtime/config.js +107 -0
  102. package/dist/runtime/config.js.map +1 -0
  103. package/dist/runtime/crewLanes.d.ts +2 -0
  104. package/dist/runtime/crewLanes.js +123 -0
  105. package/dist/runtime/crewLanes.js.map +1 -0
  106. package/dist/runtime/criticPolicy.d.ts +17 -0
  107. package/dist/runtime/criticPolicy.js +50 -0
  108. package/dist/runtime/criticPolicy.js.map +1 -0
  109. package/dist/runtime/defaults.d.ts +5 -0
  110. package/dist/runtime/defaults.js +100 -0
  111. package/dist/runtime/defaults.js.map +1 -0
  112. package/dist/runtime/directives.d.ts +3 -0
  113. package/dist/runtime/directives.js +218 -0
  114. package/dist/runtime/directives.js.map +1 -0
  115. package/dist/runtime/doctor.d.ts +36 -0
  116. package/dist/runtime/doctor.js +185 -0
  117. package/dist/runtime/doctor.js.map +1 -0
  118. package/dist/runtime/errors.d.ts +20 -0
  119. package/dist/runtime/errors.js +41 -0
  120. package/dist/runtime/errors.js.map +1 -0
  121. package/dist/runtime/externalTransfer.d.ts +20 -0
  122. package/dist/runtime/externalTransfer.js +156 -0
  123. package/dist/runtime/externalTransfer.js.map +1 -0
  124. package/dist/runtime/fanout.d.ts +64 -0
  125. package/dist/runtime/fanout.js +263 -0
  126. package/dist/runtime/fanout.js.map +1 -0
  127. package/dist/runtime/gitEvidence.d.ts +10 -0
  128. package/dist/runtime/gitEvidence.js +80 -0
  129. package/dist/runtime/gitEvidence.js.map +1 -0
  130. package/dist/runtime/handoffs.d.ts +32 -0
  131. package/dist/runtime/handoffs.js +100 -0
  132. package/dist/runtime/handoffs.js.map +1 -0
  133. package/dist/runtime/ids.d.ts +2 -0
  134. package/dist/runtime/ids.js +4 -0
  135. package/dist/runtime/ids.js.map +1 -0
  136. package/dist/runtime/localStateIgnore.d.ts +9 -0
  137. package/dist/runtime/localStateIgnore.js +98 -0
  138. package/dist/runtime/localStateIgnore.js.map +1 -0
  139. package/dist/runtime/loop.d.ts +14 -0
  140. package/dist/runtime/loop.js +1863 -0
  141. package/dist/runtime/loop.js.map +1 -0
  142. package/dist/runtime/loopRecommendation.d.ts +109 -0
  143. package/dist/runtime/loopRecommendation.js +566 -0
  144. package/dist/runtime/loopRecommendation.js.map +1 -0
  145. package/dist/runtime/loopResponsibilities.d.ts +2 -0
  146. package/dist/runtime/loopResponsibilities.js +395 -0
  147. package/dist/runtime/loopResponsibilities.js.map +1 -0
  148. package/dist/runtime/loopRunner.d.ts +28 -0
  149. package/dist/runtime/loopRunner.js +81 -0
  150. package/dist/runtime/loopRunner.js.map +1 -0
  151. package/dist/runtime/operatorNextActions.d.ts +2 -0
  152. package/dist/runtime/operatorNextActions.js +344 -0
  153. package/dist/runtime/operatorNextActions.js.map +1 -0
  154. package/dist/runtime/paths.d.ts +9 -0
  155. package/dist/runtime/paths.js +14 -0
  156. package/dist/runtime/paths.js.map +1 -0
  157. package/dist/runtime/permissions.d.ts +9 -0
  158. package/dist/runtime/permissions.js +73 -0
  159. package/dist/runtime/permissions.js.map +1 -0
  160. package/dist/runtime/progressPacket.d.ts +12 -0
  161. package/dist/runtime/progressPacket.js +512 -0
  162. package/dist/runtime/progressPacket.js.map +1 -0
  163. package/dist/runtime/protectedPaths.d.ts +6 -0
  164. package/dist/runtime/protectedPaths.js +48 -0
  165. package/dist/runtime/protectedPaths.js.map +1 -0
  166. package/dist/runtime/providers.d.ts +13 -0
  167. package/dist/runtime/providers.js +60 -0
  168. package/dist/runtime/providers.js.map +1 -0
  169. package/dist/runtime/reconciliation.d.ts +17 -0
  170. package/dist/runtime/reconciliation.js +283 -0
  171. package/dist/runtime/reconciliation.js.map +1 -0
  172. package/dist/runtime/redaction.d.ts +1 -0
  173. package/dist/runtime/redaction.js +5 -0
  174. package/dist/runtime/redaction.js.map +1 -0
  175. package/dist/runtime/remoteRepoContext.d.ts +77 -0
  176. package/dist/runtime/remoteRepoContext.js +316 -0
  177. package/dist/runtime/remoteRepoContext.js.map +1 -0
  178. package/dist/runtime/repoContext.d.ts +50 -0
  179. package/dist/runtime/repoContext.js +399 -0
  180. package/dist/runtime/repoContext.js.map +1 -0
  181. package/dist/runtime/repoGateway.d.ts +64 -0
  182. package/dist/runtime/repoGateway.js +308 -0
  183. package/dist/runtime/repoGateway.js.map +1 -0
  184. package/dist/runtime/responseContracts.d.ts +3 -0
  185. package/dist/runtime/responseContracts.js +86 -0
  186. package/dist/runtime/responseContracts.js.map +1 -0
  187. package/dist/runtime/reviewLanes.d.ts +2 -0
  188. package/dist/runtime/reviewLanes.js +343 -0
  189. package/dist/runtime/reviewLanes.js.map +1 -0
  190. package/dist/runtime/reviewRouting.d.ts +51 -0
  191. package/dist/runtime/reviewRouting.js +152 -0
  192. package/dist/runtime/reviewRouting.js.map +1 -0
  193. package/dist/runtime/revisionPacket.d.ts +38 -0
  194. package/dist/runtime/revisionPacket.js +144 -0
  195. package/dist/runtime/revisionPacket.js.map +1 -0
  196. package/dist/runtime/revisionTrail.d.ts +2 -0
  197. package/dist/runtime/revisionTrail.js +162 -0
  198. package/dist/runtime/revisionTrail.js.map +1 -0
  199. package/dist/runtime/role-assignment.d.ts +4 -0
  200. package/dist/runtime/role-assignment.js +21 -0
  201. package/dist/runtime/role-assignment.js.map +1 -0
  202. package/dist/runtime/roleRoster.d.ts +28 -0
  203. package/dist/runtime/roleRoster.js +96 -0
  204. package/dist/runtime/roleRoster.js.map +1 -0
  205. package/dist/runtime/runInsights.d.ts +121 -0
  206. package/dist/runtime/runInsights.js +305 -0
  207. package/dist/runtime/runInsights.js.map +1 -0
  208. package/dist/runtime/runMonitor.d.ts +33 -0
  209. package/dist/runtime/runMonitor.js +143 -0
  210. package/dist/runtime/runMonitor.js.map +1 -0
  211. package/dist/runtime/runtime.d.ts +15 -0
  212. package/dist/runtime/runtime.js +199 -0
  213. package/dist/runtime/runtime.js.map +1 -0
  214. package/dist/runtime/runtimeInfo.d.ts +9 -0
  215. package/dist/runtime/runtimeInfo.js +76 -0
  216. package/dist/runtime/runtimeInfo.js.map +1 -0
  217. package/dist/runtime/store.d.ts +4 -0
  218. package/dist/runtime/store.js +48 -0
  219. package/dist/runtime/store.js.map +1 -0
  220. package/dist/runtime/summons.d.ts +25 -0
  221. package/dist/runtime/summons.js +403 -0
  222. package/dist/runtime/summons.js.map +1 -0
  223. package/dist/runtime/teamPresets.d.ts +14 -0
  224. package/dist/runtime/teamPresets.js +153 -0
  225. package/dist/runtime/teamPresets.js.map +1 -0
  226. package/dist/runtime/types.d.ts +505 -0
  227. package/dist/runtime/types.js +28 -0
  228. package/dist/runtime/types.js.map +1 -0
  229. package/dist/runtime/validationCommands.d.ts +18 -0
  230. package/dist/runtime/validationCommands.js +106 -0
  231. package/dist/runtime/validationCommands.js.map +1 -0
  232. package/dist/tui/dashboard.d.ts +41 -0
  233. package/dist/tui/dashboard.js +1115 -0
  234. package/dist/tui/dashboard.js.map +1 -0
  235. package/docs/ARCHITECTURE.md +277 -0
  236. package/docs/CLI_SPEC.md +396 -0
  237. package/docs/CODEX_SETUP.md +288 -0
  238. package/docs/COMPLETION_CONTRACT.md +52 -0
  239. package/docs/CONTRIBUTOR_GUIDE.md +70 -0
  240. package/docs/DEMO.md +62 -0
  241. package/docs/GLOSSARY.md +46 -0
  242. package/docs/GOAL_LOOP_SCHEDULE.md +50 -0
  243. package/docs/KNOWN_LIMITATIONS.md +29 -0
  244. package/docs/LICENSING.md +21 -0
  245. package/docs/LOOP_RECIPES.md +290 -0
  246. package/docs/LOOP_SELECTION_UX.md +118 -0
  247. package/docs/MCP_SPEC.md +689 -0
  248. package/docs/MEMORY_AND_RECONCILIATION.md +222 -0
  249. package/docs/NPM_PUBLISHING.md +51 -0
  250. package/docs/OPEN_DECISIONS.md +81 -0
  251. package/docs/PROMPT_SCHEMAS.md +411 -0
  252. package/docs/PROVIDER_ADAPTERS.md +323 -0
  253. package/docs/PROVIDER_MATRIX.md +21 -0
  254. package/docs/PUBLIC_REPO_READINESS.md +49 -0
  255. package/docs/RESEARCH_NOTES.md +92 -0
  256. package/docs/ROADMAP.md +94 -0
  257. package/docs/ROLE_CONTRACTS.md +252 -0
  258. package/docs/RUNTIME_LOOP.md +240 -0
  259. package/docs/SECURITY_AND_PRIVACY.md +161 -0
  260. package/docs/TESTING_AND_VERIFICATION.md +180 -0
  261. package/docs/TRUST_MODEL.md +65 -0
  262. package/docs/decisions/0001-runtime-first-cli-and-mcp.md +23 -0
  263. package/docs/decisions/0002-provider-neutral-role-mapping.md +43 -0
  264. package/docs/decisions/0003-separate-implementation-and-verification.md +27 -0
  265. package/docs/product/README.md +14 -0
  266. package/docs/product/model-selection.md +88 -0
  267. package/docs/product/positioning.md +37 -0
  268. package/docs/product/pro-usage-modes.md +70 -0
  269. package/docs/product/roadmap.md +57 -0
  270. package/docs/product/role-policy.md +89 -0
  271. package/docs/product/runtime-invariants.md +44 -0
  272. package/docs/release/v0.1.0-preview.0.md +48 -0
  273. package/examples/stub-demo/README.md +25 -0
  274. package/package.json +55 -0
@@ -0,0 +1,20 @@
1
+ import type { ExternalTransferManifest, ExternalTransferPurpose, JsonObject, RoleAssignment, RunArtifact, RunRecord, RuntimeRole } from "./types.js";
2
+ export interface BuildExternalTransferManifestInput {
3
+ run: RunRecord;
4
+ role: RuntimeRole;
5
+ destination: RoleAssignment;
6
+ purpose: ExternalTransferPurpose;
7
+ approvalPhrase: string;
8
+ artifacts: RunArtifact[];
9
+ }
10
+ export interface ExternalTransferPreview {
11
+ manifestArtifact: RunArtifact;
12
+ manifest: ExternalTransferManifest;
13
+ }
14
+ export declare const buildExternalTransferManifest: (input: BuildExternalTransferManifestInput) => Promise<ExternalTransferManifest>;
15
+ export declare const writeExternalTransferManifestArtifact: (input: BuildExternalTransferManifestInput) => Promise<{
16
+ manifest: ExternalTransferManifest;
17
+ artifact: RunArtifact;
18
+ }>;
19
+ export declare const readLatestExternalTransferManifest: (run: RunRecord) => Promise<ExternalTransferPreview>;
20
+ export declare const transferManifestSummary: (manifest: ExternalTransferManifest) => JsonObject;
@@ -0,0 +1,156 @@
1
+ import crypto from "node:crypto";
2
+ import { readRunArtifact, writeRunArtifact } from "./artifacts.js";
3
+ import { InputError } from "./errors.js";
4
+ import { newId, nowIso } from "./ids.js";
5
+ const maxArtifactBytes = 200_000;
6
+ const previewBytes = 4_000;
7
+ const secretPatterns = [
8
+ /(?:api[_-]?key|secret|password|token)\s*[:=]\s*["']?[A-Za-z0-9_./+=-]{8,}/i,
9
+ /authorization:\s*bearer/i,
10
+ /ssh-rsa|-----BEGIN [A-Z ]*PRIVATE KEY-----/
11
+ ];
12
+ const sha256 = (value) => crypto.createHash("sha256").update(value).digest("hex");
13
+ const artifactRiskClass = (purpose) => {
14
+ switch (purpose) {
15
+ case "progress_packet":
16
+ case "memory_packet":
17
+ case "reconciliation":
18
+ return "private_runtime_memory";
19
+ case "repo_context":
20
+ return "repo_context";
21
+ }
22
+ };
23
+ const detectSecretPatternHits = (content) => secretPatterns.filter((pattern) => pattern.test(content)).length;
24
+ const buildRisk = (purpose, artifactContents) => {
25
+ const secretPatternHits = artifactContents.reduce((count, content) => count + detectSecretPatternHits(content), 0);
26
+ const reasons = [
27
+ purpose === "repo_context"
28
+ ? "Transfer includes runtime-captured repository context."
29
+ : "Transfer includes private TheHood runtime memory."
30
+ ];
31
+ if (secretPatternHits > 0) {
32
+ reasons.push("Secret-like text was detected in the transfer source artifact preview.");
33
+ }
34
+ return {
35
+ class: secretPatternHits > 0 ? "secret_risk" : artifactRiskClass(purpose),
36
+ reasons,
37
+ secretPatternHits
38
+ };
39
+ };
40
+ const artifactRef = async (run, artifact) => {
41
+ const result = await readRunArtifact({
42
+ repoPath: run.repoPath,
43
+ runId: run.runId,
44
+ ref: artifact.ref,
45
+ maxBytes: maxArtifactBytes
46
+ });
47
+ if (result.truncated) {
48
+ throw new InputError(`External transfer source artifact is too large to review safely: ${artifact.ref}`);
49
+ }
50
+ return {
51
+ ref: {
52
+ kind: artifact.kind,
53
+ ref: artifact.ref,
54
+ summary: artifact.summary,
55
+ byteLength: result.byteLength,
56
+ truncated: result.truncated,
57
+ sha256: sha256(result.content)
58
+ },
59
+ content: result.content
60
+ };
61
+ };
62
+ const previewContent = (contents) => {
63
+ const joined = contents.join("\n\n--- artifact boundary ---\n\n");
64
+ const truncated = Buffer.byteLength(joined, "utf8") > previewBytes;
65
+ return {
66
+ content: joined.slice(0, previewBytes),
67
+ truncated
68
+ };
69
+ };
70
+ export const buildExternalTransferManifest = async (input) => {
71
+ const inspected = await Promise.all(input.artifacts.map((artifact) => artifactRef(input.run, artifact)));
72
+ const contents = inspected.map((item) => item.content);
73
+ const preview = previewContent(contents);
74
+ const approvalHint = `I approve ${input.approvalPhrase} for run ${input.run.runId}.`;
75
+ return {
76
+ schemaVersion: 1,
77
+ kind: "external_transfer_manifest",
78
+ runId: input.run.runId,
79
+ createdAt: nowIso(),
80
+ destination: input.destination,
81
+ role: input.role,
82
+ purpose: input.purpose,
83
+ approvalPhrase: input.approvalPhrase,
84
+ approvalHint,
85
+ artifacts: inspected.map((item) => item.ref),
86
+ totalBytes: inspected.reduce((total, item) => total + item.ref.byteLength, 0),
87
+ risk: buildRisk(input.purpose, contents),
88
+ redaction: {
89
+ status: "not_applied",
90
+ notes: [
91
+ "The manifest previews the exact bounded artifact content before external transfer.",
92
+ "Source artifacts remain canonical; provider-visible packets are built from these artifacts."
93
+ ]
94
+ },
95
+ preview: {
96
+ maxBytes: previewBytes,
97
+ content: preview.content,
98
+ truncated: preview.truncated
99
+ },
100
+ provenance: {
101
+ sourceArtifactRefs: input.artifacts.map((artifact) => artifact.ref),
102
+ notes: [
103
+ "Generated by the runtime before an external provider transfer approval gate.",
104
+ "Approval should be based on this manifest, not on provider session context."
105
+ ]
106
+ }
107
+ };
108
+ };
109
+ export const writeExternalTransferManifestArtifact = async (input) => {
110
+ const manifest = await buildExternalTransferManifest(input);
111
+ const artifact = await writeRunArtifact({
112
+ repoPath: input.run.repoPath,
113
+ runId: input.run.runId,
114
+ kind: "transfer_manifest",
115
+ name: `${input.purpose}-${input.destination.provider}-${newId("transfer")}.json`,
116
+ content: `${JSON.stringify(manifest, null, 2)}\n`,
117
+ summary: `${input.purpose} transfer manifest for ${input.destination.provider}:${input.destination.model}.`
118
+ });
119
+ return {
120
+ manifest,
121
+ artifact
122
+ };
123
+ };
124
+ const isManifest = (value) => value !== null &&
125
+ typeof value === "object" &&
126
+ !Array.isArray(value) &&
127
+ value.kind === "external_transfer_manifest";
128
+ export const readLatestExternalTransferManifest = async (run) => {
129
+ const manifestArtifact = run.artifacts.filter((artifact) => artifact.kind === "transfer_manifest").at(-1);
130
+ if (!manifestArtifact) {
131
+ throw new InputError(`Run ${run.runId} does not have a transfer manifest artifact.`);
132
+ }
133
+ const result = await readRunArtifact({
134
+ repoPath: run.repoPath,
135
+ runId: run.runId,
136
+ ref: manifestArtifact.ref,
137
+ maxBytes: maxArtifactBytes
138
+ });
139
+ const parsed = JSON.parse(result.content);
140
+ if (!isManifest(parsed)) {
141
+ throw new InputError(`Transfer manifest artifact is invalid: ${manifestArtifact.ref}`);
142
+ }
143
+ return {
144
+ manifestArtifact,
145
+ manifest: parsed
146
+ };
147
+ };
148
+ export const transferManifestSummary = (manifest) => ({
149
+ destination: `${manifest.destination.provider}:${manifest.destination.model}`,
150
+ purpose: manifest.purpose,
151
+ riskClass: manifest.risk.class,
152
+ totalBytes: manifest.totalBytes,
153
+ artifactCount: manifest.artifacts.length,
154
+ approvalPhrase: manifest.approvalPhrase
155
+ });
156
+ //# sourceMappingURL=externalTransfer.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"externalTransfer.js","sourceRoot":"","sources":["../../src/runtime/externalTransfer.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,64 @@
1
+ import type { AgentResponse } from "../providers/types.js";
2
+ import type { JsonObject, RoleAssignment, RunArtifact, RunRecord, RuntimeRole } from "./types.js";
3
+ export type FanoutStatus = "completed" | "blocked" | "failed";
4
+ export type FanoutItemStatus = "completed" | "blocked" | "failed";
5
+ export interface FanoutItemInput {
6
+ role: RuntimeRole;
7
+ brief: string;
8
+ summonKind?: string;
9
+ persona?: string;
10
+ agent?: RoleAssignment;
11
+ constraints?: string[];
12
+ evidenceRefs?: string[];
13
+ }
14
+ export interface FanoutAgentsInput {
15
+ repoPath: string;
16
+ runId: string;
17
+ items: FanoutItemInput[];
18
+ maxItems?: number;
19
+ }
20
+ export interface FanoutBounds {
21
+ requestedItems: number;
22
+ maxItems: number;
23
+ hardMaxItems: number;
24
+ executedItems: number;
25
+ execution: "sequential";
26
+ }
27
+ export interface FanoutItemResult {
28
+ index: number;
29
+ role: RuntimeRole;
30
+ summonKind: string;
31
+ brief: string;
32
+ status: FanoutItemStatus;
33
+ stopReason: string;
34
+ providerResponseCount: number;
35
+ assignment?: RoleAssignment;
36
+ providerStatus?: AgentResponse["status"];
37
+ directiveArtifact?: RunArtifact;
38
+ responseArtifact?: RunArtifact;
39
+ error?: string;
40
+ }
41
+ export interface FanoutAgentsResult {
42
+ run: RunRecord;
43
+ status: FanoutStatus;
44
+ bounds: FanoutBounds;
45
+ items: FanoutItemResult[];
46
+ artifact: RunArtifact;
47
+ }
48
+ export interface FanoutArtifactPayload {
49
+ schemaVersion: 1;
50
+ kind: "fanout";
51
+ runId: string;
52
+ createdAt: string;
53
+ status: FanoutStatus;
54
+ bounds: FanoutBounds;
55
+ safety: {
56
+ sidecarOnly: boolean;
57
+ readOnlyRolesOnly: boolean;
58
+ canSatisfyRequiredGates: boolean;
59
+ instruction: string;
60
+ };
61
+ items: JsonObject[];
62
+ }
63
+ export declare const defaultFanoutMaxItems = 8;
64
+ export declare const fanoutAgents: (input: FanoutAgentsInput) => Promise<FanoutAgentsResult>;
@@ -0,0 +1,263 @@
1
+ import { writeRunArtifact } from "./artifacts.js";
2
+ import { loadConfig } from "./config.js";
3
+ import { InputError } from "./errors.js";
4
+ import { newId, nowIso } from "./ids.js";
5
+ import { defaultRolePermissions } from "./permissions.js";
6
+ import { loadRun, saveRun } from "./store.js";
7
+ import { summonAgent } from "./summons.js";
8
+ const fanoutRoles = [
9
+ "orchestrator",
10
+ "planner",
11
+ "researcher",
12
+ "qa",
13
+ "verifier",
14
+ "critic"
15
+ ];
16
+ export const defaultFanoutMaxItems = 8;
17
+ const hardFanoutMaxItems = 8;
18
+ const maxTextLength = 500;
19
+ const createEvent = (type, message, data) => ({
20
+ id: newId("event"),
21
+ createdAt: nowIso(),
22
+ type,
23
+ message,
24
+ ...(data ? { data } : {})
25
+ });
26
+ const truncateText = (value) => value.length <= maxTextLength ? value : `${value.slice(0, maxTextLength - 3)}...`;
27
+ const isFanoutRole = (role) => fanoutRoles.includes(role) && !defaultRolePermissions[role].edit;
28
+ const normalizeItems = (items, maxItems) => {
29
+ if (items.length === 0) {
30
+ throw new InputError("Fan-out requires at least one item.");
31
+ }
32
+ if (items.length > maxItems) {
33
+ throw new InputError(`Fan-out accepts at most ${maxItems} item(s) for this call.`);
34
+ }
35
+ return items.map((item, index) => {
36
+ if (!isFanoutRole(item.role)) {
37
+ throw new InputError(`Fan-out item ${index + 1} role must be orchestrator, planner, researcher, qa, verifier, or critic.`);
38
+ }
39
+ const brief = item.brief.trim();
40
+ if (!brief) {
41
+ throw new InputError(`Fan-out item ${index + 1} brief cannot be empty.`);
42
+ }
43
+ return {
44
+ role: item.role,
45
+ brief,
46
+ ...(item.summonKind ? { summonKind: item.summonKind } : {}),
47
+ ...(item.persona ? { persona: item.persona } : {}),
48
+ ...(item.agent ? { agent: item.agent } : {}),
49
+ constraints: item.constraints ?? [],
50
+ evidenceRefs: item.evidenceRefs ?? []
51
+ };
52
+ });
53
+ };
54
+ const resolveConfiguredMaxItems = (value) => {
55
+ if (!Number.isSafeInteger(value) || value < 1) {
56
+ throw new InputError("Configured defaults.fanoutMaxItems must be a positive integer.");
57
+ }
58
+ if (value > hardFanoutMaxItems) {
59
+ throw new InputError(`Configured defaults.fanoutMaxItems cannot exceed ${hardFanoutMaxItems}.`);
60
+ }
61
+ return value;
62
+ };
63
+ const resolveMaxItems = (value, configuredMaxItems) => {
64
+ const policyMaxItems = resolveConfiguredMaxItems(configuredMaxItems);
65
+ if (value === undefined) {
66
+ return policyMaxItems;
67
+ }
68
+ if (!Number.isSafeInteger(value) || value < 1) {
69
+ throw new InputError("Fan-out maxItems must be a positive integer.");
70
+ }
71
+ if (value > policyMaxItems) {
72
+ throw new InputError(`Fan-out maxItems cannot exceed configured defaults.fanoutMaxItems (${policyMaxItems}).`);
73
+ }
74
+ if (value > hardFanoutMaxItems) {
75
+ throw new InputError(`Fan-out maxItems cannot exceed ${hardFanoutMaxItems}.`);
76
+ }
77
+ return value;
78
+ };
79
+ const itemStatusFromResponse = (run, response) => {
80
+ if (run.approvalRequired || response?.status === "blocked") {
81
+ return "blocked";
82
+ }
83
+ if (response?.status === "failed") {
84
+ return "failed";
85
+ }
86
+ return "completed";
87
+ };
88
+ const resultFromSummon = (index, brief, result) => {
89
+ const latestResponse = result.providerResponses.at(-1);
90
+ const status = itemStatusFromResponse(result.run, latestResponse);
91
+ return {
92
+ index,
93
+ role: result.role,
94
+ summonKind: result.summonKind,
95
+ brief: truncateText(brief),
96
+ status,
97
+ stopReason: result.stopReason,
98
+ providerResponseCount: result.providerResponses.length,
99
+ assignment: result.assignment,
100
+ ...(latestResponse ? { providerStatus: latestResponse.status } : {}),
101
+ ...(result.directiveArtifact ? { directiveArtifact: result.directiveArtifact } : {}),
102
+ ...(result.responseArtifact ? { responseArtifact: result.responseArtifact } : {})
103
+ };
104
+ };
105
+ const failedItem = (index, item, error) => {
106
+ const message = error instanceof Error ? error.message : String(error);
107
+ return {
108
+ index,
109
+ role: item.role,
110
+ summonKind: item.summonKind ?? (item.role === "qa" ? "qa" : "review"),
111
+ brief: truncateText(item.brief),
112
+ status: "failed",
113
+ stopReason: message,
114
+ providerResponseCount: 0,
115
+ ...(item.agent ? { assignment: item.agent } : {}),
116
+ error: message
117
+ };
118
+ };
119
+ const fanoutStatus = (items) => {
120
+ if (items.some((item) => item.status === "blocked")) {
121
+ return "blocked";
122
+ }
123
+ if (items.some((item) => item.status === "failed")) {
124
+ return "failed";
125
+ }
126
+ return "completed";
127
+ };
128
+ const artifactSummary = (artifact) => artifact
129
+ ? {
130
+ kind: artifact.kind,
131
+ ref: artifact.ref,
132
+ summary: artifact.summary
133
+ }
134
+ : undefined;
135
+ const assignmentSummary = (assignment) => assignment
136
+ ? {
137
+ provider: assignment.provider,
138
+ model: assignment.model
139
+ }
140
+ : undefined;
141
+ const itemPayload = (item) => {
142
+ const assignment = assignmentSummary(item.assignment);
143
+ const directiveArtifact = artifactSummary(item.directiveArtifact);
144
+ const responseArtifact = artifactSummary(item.responseArtifact);
145
+ return {
146
+ index: item.index,
147
+ role: item.role,
148
+ summonKind: item.summonKind,
149
+ status: item.status,
150
+ brief: item.brief,
151
+ stopReason: item.stopReason,
152
+ providerResponseCount: item.providerResponseCount,
153
+ ...(item.providerStatus ? { providerStatus: item.providerStatus } : {}),
154
+ ...(assignment ? { assignment } : {}),
155
+ ...(directiveArtifact ? { directiveArtifact } : {}),
156
+ ...(responseArtifact ? { responseArtifact } : {}),
157
+ ...(item.error ? { error: item.error } : {})
158
+ };
159
+ };
160
+ const buildFanoutPayload = (run, status, bounds, items) => ({
161
+ schemaVersion: 1,
162
+ kind: "fanout",
163
+ runId: run.runId,
164
+ createdAt: nowIso(),
165
+ status,
166
+ bounds,
167
+ safety: {
168
+ sidecarOnly: true,
169
+ readOnlyRolesOnly: true,
170
+ canSatisfyRequiredGates: false,
171
+ instruction: "Fan-out evidence is advisory. It cannot satisfy verifier, runtime QA, approval, or completion gates."
172
+ },
173
+ items: items.map(itemPayload)
174
+ });
175
+ const appendFanoutArtifact = async (run, status, bounds, items) => {
176
+ const latest = await loadRun(run.repoPath, run.runId);
177
+ const payload = buildFanoutPayload(latest, status, bounds, items);
178
+ const artifact = await writeRunArtifact({
179
+ repoPath: latest.repoPath,
180
+ runId: latest.runId,
181
+ kind: "fanout",
182
+ name: `fanout-${newId("fanout")}.json`,
183
+ content: `${JSON.stringify(payload, null, 2)}\n`,
184
+ summary: `Agent fan-out ${status}: ${bounds.executedItems}/${bounds.requestedItems} item(s)`
185
+ });
186
+ const updated = {
187
+ ...latest,
188
+ updatedAt: nowIso(),
189
+ artifacts: [...latest.artifacts, artifact],
190
+ events: [
191
+ ...latest.events,
192
+ createEvent("agent_fanout_completed", artifact.summary, {
193
+ status,
194
+ artifactRef: artifact.ref,
195
+ requestedItems: bounds.requestedItems,
196
+ executedItems: bounds.executedItems,
197
+ maxItems: bounds.maxItems
198
+ })
199
+ ]
200
+ };
201
+ await saveRun(updated);
202
+ return {
203
+ run: updated,
204
+ artifact
205
+ };
206
+ };
207
+ export const fanoutAgents = async (input) => {
208
+ const config = await loadConfig(input.repoPath);
209
+ const maxItems = resolveMaxItems(input.maxItems, config.defaults.fanoutMaxItems);
210
+ const items = normalizeItems(input.items, maxItems);
211
+ const initialRun = await loadRun(input.repoPath, input.runId);
212
+ if (initialRun.approvalRequired) {
213
+ throw new InputError(`Run ${initialRun.runId} is waiting for approval: ${initialRun.approvalReason ?? "approval required"}.`);
214
+ }
215
+ let currentRun = initialRun;
216
+ const results = [];
217
+ for (const [index, item] of items.entries()) {
218
+ try {
219
+ const result = await summonAgent({
220
+ repoPath: input.repoPath,
221
+ runId: input.runId,
222
+ role: item.role,
223
+ brief: item.brief,
224
+ ...(item.summonKind ? { summonKind: item.summonKind } : {}),
225
+ ...(item.persona ? { persona: item.persona } : {}),
226
+ ...(item.agent ? { agent: item.agent } : {}),
227
+ constraints: item.constraints ?? [],
228
+ evidenceRefs: item.evidenceRefs ?? []
229
+ });
230
+ const itemResult = resultFromSummon(index, item.brief, result);
231
+ results.push(itemResult);
232
+ currentRun = result.run;
233
+ if (itemResult.status !== "completed" && currentRun.approvalRequired) {
234
+ break;
235
+ }
236
+ }
237
+ catch (error) {
238
+ const itemResult = failedItem(index, item, error);
239
+ results.push(itemResult);
240
+ currentRun = await loadRun(input.repoPath, input.runId);
241
+ if (currentRun.approvalRequired) {
242
+ break;
243
+ }
244
+ }
245
+ }
246
+ const status = fanoutStatus(results);
247
+ const bounds = {
248
+ requestedItems: items.length,
249
+ maxItems,
250
+ hardMaxItems: hardFanoutMaxItems,
251
+ executedItems: results.length,
252
+ execution: "sequential"
253
+ };
254
+ const appended = await appendFanoutArtifact(currentRun, status, bounds, results);
255
+ return {
256
+ run: appended.run,
257
+ status,
258
+ bounds,
259
+ items: results,
260
+ artifact: appended.artifact
261
+ };
262
+ };
263
+ //# sourceMappingURL=fanout.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"fanout.js","sourceRoot":"","sources":["../../src/runtime/fanout.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,10 @@
1
+ import { type ProtectedPathMatch } from "./protectedPaths.js";
2
+ import type { RunArtifact, RunRecord } from "./types.js";
3
+ export interface GitEvidenceResult {
4
+ run: RunRecord;
5
+ changedPaths: string[];
6
+ protectedChanges: ProtectedPathMatch[];
7
+ artifacts: RunArtifact[];
8
+ }
9
+ export declare const parseGitStatusPaths: (stdout: string) => string[];
10
+ export declare const captureGitEvidence: (repoPathInput: string, runId: string) => Promise<GitEvidenceResult>;
@@ -0,0 +1,80 @@
1
+ import { writeRunArtifact } from "./artifacts.js";
2
+ import { runRuntimeCommand } from "./commandRunner.js";
3
+ import { loadConfig } from "./config.js";
4
+ import { newId, nowIso } from "./ids.js";
5
+ import { findProtectedPathMatches } from "./protectedPaths.js";
6
+ import { resolveRepoPath } from "./paths.js";
7
+ import { loadRun, saveRun } from "./store.js";
8
+ const parseStatusPath = (line) => {
9
+ const payload = line.slice(3).trim();
10
+ if (!payload)
11
+ return [];
12
+ if (payload.includes(" -> ")) {
13
+ return payload.split(" -> ").map((value) => value.trim()).filter(Boolean);
14
+ }
15
+ return [payload.replace(/^"|"$/g, "")];
16
+ };
17
+ export const parseGitStatusPaths = (stdout) => Array.from(new Set(stdout
18
+ .split("\n")
19
+ .filter((line) => line.trim().length > 0)
20
+ .flatMap(parseStatusPath))).sort((left, right) => left.localeCompare(right));
21
+ export const captureGitEvidence = async (repoPathInput, runId) => {
22
+ const repoPath = resolveRepoPath(repoPathInput);
23
+ const config = await loadConfig(repoPath);
24
+ const statusResult = await runRuntimeCommand({
25
+ repoPath,
26
+ runId,
27
+ tool: "git_status",
28
+ command: "git",
29
+ args: ["status", "--short", "--untracked-files=all", "--", ".", ":(exclude).thehood"]
30
+ });
31
+ const diffResult = await runRuntimeCommand({
32
+ repoPath,
33
+ runId,
34
+ tool: "git_diff",
35
+ command: "git",
36
+ args: ["diff", "--no-ext-diff", "--", ".", ":(exclude).thehood"]
37
+ });
38
+ const changedPaths = parseGitStatusPaths(statusResult.stdout);
39
+ const protectedChanges = findProtectedPathMatches(changedPaths, config.defaults.protectedTestPaths);
40
+ const summaryArtifact = await writeRunArtifact({
41
+ repoPath,
42
+ runId,
43
+ kind: "metadata",
44
+ name: "git-evidence-summary.json",
45
+ content: `${JSON.stringify({
46
+ changedPaths,
47
+ protectedChanges,
48
+ statusRef: statusResult.event.stdoutRef,
49
+ diffRef: diffResult.event.stdoutRef
50
+ }, null, 2)}\n`,
51
+ summary: `Git evidence summary for ${changedPaths.length} changed path(s).`
52
+ });
53
+ const run = await loadRun(repoPath, runId);
54
+ const updated = {
55
+ ...run,
56
+ updatedAt: nowIso(),
57
+ artifacts: [...run.artifacts, summaryArtifact],
58
+ events: [
59
+ ...run.events,
60
+ {
61
+ id: newId("event"),
62
+ createdAt: nowIso(),
63
+ type: "git_evidence_captured",
64
+ message: `Captured git evidence for ${changedPaths.length} changed path(s).`,
65
+ data: {
66
+ changedPathCount: changedPaths.length,
67
+ protectedChangeCount: protectedChanges.length
68
+ }
69
+ }
70
+ ]
71
+ };
72
+ await saveRun(updated);
73
+ return {
74
+ run: updated,
75
+ changedPaths,
76
+ protectedChanges,
77
+ artifacts: [summaryArtifact]
78
+ };
79
+ };
80
+ //# sourceMappingURL=gitEvidence.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"gitEvidence.js","sourceRoot":"","sources":["../../src/runtime/gitEvidence.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,32 @@
1
+ import type { RunHandoffEvent, RunHandoffKind, RunRecord, RunState, RuntimeRole } from "./types.js";
2
+ export interface CreateRunHandoffInput {
3
+ kind: RunHandoffKind;
4
+ reason: string;
5
+ stateAfter: RunState;
6
+ fromRole?: RuntimeRole | undefined;
7
+ toRole?: RuntimeRole | undefined;
8
+ gate?: string | undefined;
9
+ approvalEventId?: string | undefined;
10
+ artifactRefs?: string[] | undefined;
11
+ }
12
+ export interface RunHandoffSummary {
13
+ id: string;
14
+ createdAt: string;
15
+ kind: RunHandoffKind;
16
+ reason: string;
17
+ stateBefore: RunState;
18
+ stateAfter: RunState;
19
+ fromLabel?: string;
20
+ fromAssignment?: string;
21
+ toLabel?: string;
22
+ toAssignment?: string;
23
+ gate?: string;
24
+ artifactRefs?: string[];
25
+ }
26
+ export declare const roleLaneLabel: (role: RuntimeRole) => string;
27
+ export declare const createRunHandoff: (run: RunRecord, input: CreateRunHandoffInput) => RunHandoffEvent;
28
+ export declare const appendRunHandoffs: (run: RunRecord, handoffs: RunHandoffEvent[]) => RunRecord;
29
+ export declare const latestRunHandoff: (run: RunRecord) => RunHandoffEvent | undefined;
30
+ export declare const recentRunHandoffs: (run: RunRecord, limit: number) => RunHandoffEvent[];
31
+ export declare const summarizeRunHandoff: (handoff: RunHandoffEvent) => RunHandoffSummary;
32
+ export declare const recentRunHandoffSummaries: (run: RunRecord, limit: number) => RunHandoffSummary[];