presubmit 0.1.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 (220) hide show
  1. package/LICENSE +202 -0
  2. package/README.md +51 -0
  3. package/THIRD_PARTY_NOTICES.md +24 -0
  4. package/apps/web/dist/assets/FileCode-CZZH52o7.js +5 -0
  5. package/apps/web/dist/assets/FileCode-DovDO7Jh.css +1 -0
  6. package/apps/web/dist/assets/SettingsPage-CRvOwdjt.js +4 -0
  7. package/apps/web/dist/assets/SettingsPage-UbYSCwJj.css +1 -0
  8. package/apps/web/dist/assets/TerminalPanel-0sw-J6YS.css +1 -0
  9. package/apps/web/dist/assets/TerminalPanel-BqUjPWav.js +16 -0
  10. package/apps/web/dist/assets/index-BhqNNFja.js +54 -0
  11. package/apps/web/dist/assets/index-DD8VXy8H.css +1 -0
  12. package/apps/web/dist/assets/presubmit-mark-BBQ19Fmr.svg +7 -0
  13. package/apps/web/dist/assets/presubmit-mark-busy-CwBC-7on.svg +8 -0
  14. package/apps/web/dist/assets/react-vendor-wiHys0m2.js +9 -0
  15. package/apps/web/dist/assets/rolldown-runtime-hePW80VL.js +1 -0
  16. package/apps/web/dist/index.html +6 -0
  17. package/apps/web/dist/service-worker.js +11 -0
  18. package/dist/apps/server/src/agent-builder.js +204 -0
  19. package/dist/apps/server/src/attach.js +163 -0
  20. package/dist/apps/server/src/attachments.js +86 -0
  21. package/dist/apps/server/src/browser-access.js +131 -0
  22. package/dist/apps/server/src/check-provenance.js +95 -0
  23. package/dist/apps/server/src/check-supervisor.js +112 -0
  24. package/dist/apps/server/src/checks.js +402 -0
  25. package/dist/apps/server/src/child-collaboration-guidance.js +2 -0
  26. package/dist/apps/server/src/child-sessions.js +191 -0
  27. package/dist/apps/server/src/cli.js +162 -0
  28. package/dist/apps/server/src/conversation-search.js +12 -0
  29. package/dist/apps/server/src/coordinator-messages.js +72 -0
  30. package/dist/apps/server/src/dev-auth.js +54 -0
  31. package/dist/apps/server/src/dev-server.js +201 -0
  32. package/dist/apps/server/src/dev-worker.js +48 -0
  33. package/dist/apps/server/src/diagnostics.js +105 -0
  34. package/dist/apps/server/src/fast-mode.js +8 -0
  35. package/dist/apps/server/src/folder-picker.js +54 -0
  36. package/dist/apps/server/src/git-blobs.js +62 -0
  37. package/dist/apps/server/src/git-handoff.js +127 -0
  38. package/dist/apps/server/src/history-sources.js +59 -0
  39. package/dist/apps/server/src/hub.js +159 -0
  40. package/dist/apps/server/src/internal-transport.js +38 -0
  41. package/dist/apps/server/src/local-embeddings.js +70 -0
  42. package/dist/apps/server/src/ollama-setup.js +56 -0
  43. package/dist/apps/server/src/planning.js +30 -0
  44. package/dist/apps/server/src/project-agents.js +276 -0
  45. package/dist/apps/server/src/project-memory.js +94 -0
  46. package/dist/apps/server/src/projects.js +106 -0
  47. package/dist/apps/server/src/queued-launch.js +13 -0
  48. package/dist/apps/server/src/reply-search.js +172 -0
  49. package/dist/apps/server/src/review-context.js +60 -0
  50. package/dist/apps/server/src/review-refresh.js +14 -0
  51. package/dist/apps/server/src/reviewers.js +75 -0
  52. package/dist/apps/server/src/search-settings.js +22 -0
  53. package/dist/apps/server/src/semantic-history.js +186 -0
  54. package/dist/apps/server/src/server.js +4338 -0
  55. package/dist/apps/server/src/session-changes.js +181 -0
  56. package/dist/apps/server/src/session-router-settings.js +198 -0
  57. package/dist/apps/server/src/session-workspaces.js +135 -0
  58. package/dist/apps/server/src/sessions.js +579 -0
  59. package/dist/apps/server/src/shared-auth.js +70 -0
  60. package/dist/apps/server/src/shell-evaluator-settings.js +53 -0
  61. package/dist/apps/server/src/store.js +203 -0
  62. package/dist/apps/server/src/tailscale-process.js +115 -0
  63. package/dist/apps/server/src/tailscale-serve-worker.js +33 -0
  64. package/dist/apps/server/src/tailscale-serve.js +276 -0
  65. package/dist/apps/server/src/task-capacity.js +92 -0
  66. package/dist/apps/server/src/task-graph.js +190 -0
  67. package/dist/apps/server/src/task-logs.js +74 -0
  68. package/dist/apps/server/src/task-numbers.js +25 -0
  69. package/dist/apps/server/src/task-orchestrator.js +1088 -0
  70. package/dist/apps/server/src/terminal.js +182 -0
  71. package/dist/apps/server/src/terminals.js +80 -0
  72. package/dist/apps/server/src/tool-safety.js +2 -0
  73. package/dist/apps/server/src/workspace-lock.js +140 -0
  74. package/dist/apps/server/src/workspace-watcher.js +65 -0
  75. package/dist/apps/server/src/workspace.js +517 -0
  76. package/dist/packages/agent-pi/src/agent-builder-tool.js +32 -0
  77. package/dist/packages/agent-pi/src/agent-capabilities.js +44 -0
  78. package/dist/packages/agent-pi/src/ask-user.js +86 -0
  79. package/dist/packages/agent-pi/src/auth.js +510 -0
  80. package/dist/packages/agent-pi/src/check-tools.js +72 -0
  81. package/dist/packages/agent-pi/src/command-policy.js +246 -0
  82. package/dist/packages/agent-pi/src/coordinator-tools.js +122 -0
  83. package/dist/packages/agent-pi/src/fast-mode.js +67 -0
  84. package/dist/packages/agent-pi/src/file-tools.js +163 -0
  85. package/dist/packages/agent-pi/src/history-tool.js +40 -0
  86. package/dist/packages/agent-pi/src/history.js +34 -0
  87. package/dist/packages/agent-pi/src/index.js +177 -0
  88. package/dist/packages/agent-pi/src/ipc.js +314 -0
  89. package/dist/packages/agent-pi/src/jev-session-router.js +408 -0
  90. package/dist/packages/agent-pi/src/jev-tools.js +71 -0
  91. package/dist/packages/agent-pi/src/local-model.js +277 -0
  92. package/dist/packages/agent-pi/src/memory-tools.js +119 -0
  93. package/dist/packages/agent-pi/src/model.js +25 -0
  94. package/dist/packages/agent-pi/src/planning.js +206 -0
  95. package/dist/packages/agent-pi/src/resource-loader.js +23 -0
  96. package/dist/packages/agent-pi/src/review-tools.js +158 -0
  97. package/dist/packages/agent-pi/src/review-transition.js +73 -0
  98. package/dist/packages/agent-pi/src/review.js +40 -0
  99. package/dist/packages/agent-pi/src/routing.js +27 -0
  100. package/dist/packages/agent-pi/src/session-setup.js +118 -0
  101. package/dist/packages/agent-pi/src/shell-context.js +51 -0
  102. package/dist/packages/agent-pi/src/shell-policy.js +281 -0
  103. package/dist/packages/agent-pi/src/shell-safety.js +205 -0
  104. package/dist/packages/agent-pi/src/shell.js +121 -0
  105. package/dist/packages/agent-pi/src/snapshot-permissions.js +12 -0
  106. package/dist/packages/agent-pi/src/spike.js +41 -0
  107. package/dist/packages/agent-pi/src/task-tools.js +53 -0
  108. package/dist/packages/agent-pi/src/types.js +1 -0
  109. package/dist/packages/agent-pi/src/usage.js +30 -0
  110. package/dist/packages/agent-pi/src/worker.js +602 -0
  111. package/dist/packages/protocol/src/activity-summary.js +77 -0
  112. package/dist/packages/protocol/src/agents.js +301 -0
  113. package/dist/packages/protocol/src/browser-access.js +1 -0
  114. package/dist/packages/protocol/src/checks.js +40 -0
  115. package/dist/packages/protocol/src/child-sessions.js +28 -0
  116. package/dist/packages/protocol/src/command-policy.js +3 -0
  117. package/dist/packages/protocol/src/coordinator.js +135 -0
  118. package/dist/packages/protocol/src/delegation.js +40 -0
  119. package/dist/packages/protocol/src/git-diff.js +71 -0
  120. package/dist/packages/protocol/src/git-handoff.js +1 -0
  121. package/dist/packages/protocol/src/index.js +1 -0
  122. package/dist/packages/protocol/src/memory.js +46 -0
  123. package/dist/packages/protocol/src/metrics.js +70 -0
  124. package/dist/packages/protocol/src/planning.js +138 -0
  125. package/dist/packages/protocol/src/retrieval.js +36 -0
  126. package/dist/packages/protocol/src/reviewers.js +17 -0
  127. package/dist/packages/protocol/src/search.js +16 -0
  128. package/dist/packages/protocol/src/session-changes.js +29 -0
  129. package/dist/packages/protocol/src/session-router.js +123 -0
  130. package/dist/packages/protocol/src/shell-evaluator.js +43 -0
  131. package/dist/packages/protocol/src/task-graph.js +1 -0
  132. package/dist/packages/protocol/src/token-usage.js +17 -0
  133. package/dist/packages/protocol/src/user-questions.js +106 -0
  134. package/package.json +71 -0
  135. package/vendor/lancedb/NODEJS_THIRD_PARTY_LICENSES.md +668 -0
  136. package/vendor/lancedb/RUST_THIRD_PARTY_LICENSES.html +14607 -0
  137. package/vendor/lancedb/dist/arrow.d.ts +296 -0
  138. package/vendor/lancedb/dist/arrow.js +1145 -0
  139. package/vendor/lancedb/dist/arrow_type.d.ts +9 -0
  140. package/vendor/lancedb/dist/arrow_type.js +29 -0
  141. package/vendor/lancedb/dist/connection.d.ts +508 -0
  142. package/vendor/lancedb/dist/connection.js +298 -0
  143. package/vendor/lancedb/dist/embedding/embedding_function.d.ts +103 -0
  144. package/vendor/lancedb/dist/embedding/embedding_function.js +192 -0
  145. package/vendor/lancedb/dist/embedding/index.d.ts +37 -0
  146. package/vendor/lancedb/dist/embedding/index.js +108 -0
  147. package/vendor/lancedb/dist/embedding/openai.d.ts +16 -0
  148. package/vendor/lancedb/dist/embedding/openai.js +81 -0
  149. package/vendor/lancedb/dist/embedding/registry.d.ts +94 -0
  150. package/vendor/lancedb/dist/embedding/registry.js +221 -0
  151. package/vendor/lancedb/dist/embedding/transformers.d.ts +36 -0
  152. package/vendor/lancedb/dist/embedding/transformers.js +110 -0
  153. package/vendor/lancedb/dist/header.d.ts +162 -0
  154. package/vendor/lancedb/dist/header.js +217 -0
  155. package/vendor/lancedb/dist/index.d.ts +246 -0
  156. package/vendor/lancedb/dist/index.js +176 -0
  157. package/vendor/lancedb/dist/indices.d.ts +721 -0
  158. package/vendor/lancedb/dist/indices.js +166 -0
  159. package/vendor/lancedb/dist/materialized_view.d.ts +69 -0
  160. package/vendor/lancedb/dist/materialized_view.js +112 -0
  161. package/vendor/lancedb/dist/merge.d.ts +104 -0
  162. package/vendor/lancedb/dist/merge.js +120 -0
  163. package/vendor/lancedb/dist/native.d.ts +1193 -0
  164. package/vendor/lancedb/dist/native.js +688 -0
  165. package/vendor/lancedb/dist/oauth.d.ts +66 -0
  166. package/vendor/lancedb/dist/oauth.js +15 -0
  167. package/vendor/lancedb/dist/otel.d.ts +26 -0
  168. package/vendor/lancedb/dist/otel.js +114 -0
  169. package/vendor/lancedb/dist/permutation.d.ts +143 -0
  170. package/vendor/lancedb/dist/permutation.js +184 -0
  171. package/vendor/lancedb/dist/query.d.ts +663 -0
  172. package/vendor/lancedb/dist/query.js +966 -0
  173. package/vendor/lancedb/dist/rerankers/index.d.ts +5 -0
  174. package/vendor/lancedb/dist/rerankers/index.js +19 -0
  175. package/vendor/lancedb/dist/rerankers/rrf.d.ts +14 -0
  176. package/vendor/lancedb/dist/rerankers/rrf.js +28 -0
  177. package/vendor/lancedb/dist/sanitize.d.ts +32 -0
  178. package/vendor/lancedb/dist/sanitize.js +544 -0
  179. package/vendor/lancedb/dist/scannable.d.ts +92 -0
  180. package/vendor/lancedb/dist/scannable.js +200 -0
  181. package/vendor/lancedb/dist/schema.d.ts +16 -0
  182. package/vendor/lancedb/dist/schema.js +387 -0
  183. package/vendor/lancedb/dist/table.d.ts +1069 -0
  184. package/vendor/lancedb/dist/table.js +498 -0
  185. package/vendor/lancedb/dist/util.d.ts +14 -0
  186. package/vendor/lancedb/dist/util.js +77 -0
  187. package/vendor/lancedb/license_header.txt +2 -0
  188. package/vendor/lancedb/package.json +56 -0
  189. package/vendor/transformers/LICENSE +202 -0
  190. package/vendor/transformers/dist/transformers.cjs +30844 -0
  191. package/vendor/transformers/dist/transformers.mjs +31404 -0
  192. package/vendor/transformers/package.json +55 -0
  193. package/vendor/transformers/types/backends/onnx.d.ts +30 -0
  194. package/vendor/transformers/types/configs.d.ts +85 -0
  195. package/vendor/transformers/types/env.d.ts +110 -0
  196. package/vendor/transformers/types/generation/configuration_utils.d.ts +320 -0
  197. package/vendor/transformers/types/generation/logits_process.d.ts +354 -0
  198. package/vendor/transformers/types/generation/logits_sampler.d.ts +51 -0
  199. package/vendor/transformers/types/generation/parameters.d.ts +47 -0
  200. package/vendor/transformers/types/generation/stopping_criteria.d.ts +81 -0
  201. package/vendor/transformers/types/generation/streamers.d.ts +81 -0
  202. package/vendor/transformers/types/models/whisper/common_whisper.d.ts +8 -0
  203. package/vendor/transformers/types/models/whisper/generation_whisper.d.ts +76 -0
  204. package/vendor/transformers/types/models.d.ts +3684 -0
  205. package/vendor/transformers/types/ops/registry.d.ts +11 -0
  206. package/vendor/transformers/types/pipelines.d.ts +2402 -0
  207. package/vendor/transformers/types/processors.d.ts +924 -0
  208. package/vendor/transformers/types/tokenizers.d.ts +990 -0
  209. package/vendor/transformers/types/transformers.d.ts +13 -0
  210. package/vendor/transformers/types/utils/audio.d.ts +130 -0
  211. package/vendor/transformers/types/utils/constants.d.ts +2 -0
  212. package/vendor/transformers/types/utils/core.d.ts +98 -0
  213. package/vendor/transformers/types/utils/data-structures.d.ts +236 -0
  214. package/vendor/transformers/types/utils/devices.d.ts +18 -0
  215. package/vendor/transformers/types/utils/dtypes.d.ts +19 -0
  216. package/vendor/transformers/types/utils/generic.d.ts +11 -0
  217. package/vendor/transformers/types/utils/hub.d.ts +152 -0
  218. package/vendor/transformers/types/utils/image.d.ts +119 -0
  219. package/vendor/transformers/types/utils/maths.d.ts +280 -0
  220. package/vendor/transformers/types/utils/tensor.d.ts +418 -0
@@ -0,0 +1,301 @@
1
+ /** Project-local, declarative agents. No executable plugins or authority in instructions. */
2
+ export const agentCapabilities = [
3
+ 'workspace.read',
4
+ 'snapshot.read',
5
+ 'findings.report',
6
+ 'user.ask',
7
+ ];
8
+ function object(value, keys) {
9
+ if (!value ||
10
+ typeof value !== 'object' ||
11
+ Array.isArray(value) ||
12
+ Object.keys(value).some((k) => !keys.includes(k)))
13
+ throw new Error('Invalid agent contract fields.');
14
+ return value;
15
+ }
16
+ export function agentText(value, label, max = 120) {
17
+ if (typeof value !== 'string' || !value.trim() || value.length > max)
18
+ throw new Error(`Invalid ${label}.`);
19
+ return value;
20
+ }
21
+ export function agentId(value) {
22
+ const id = agentText(value, 'agent identifier');
23
+ if (!/^[a-zA-Z0-9][a-zA-Z0-9_-]*$/.test(id))
24
+ throw new Error('Invalid agent identifier.');
25
+ return id;
26
+ }
27
+ function version(value) {
28
+ if (!Number.isSafeInteger(value) || value < 1)
29
+ throw new Error('Invalid agent version.');
30
+ return value;
31
+ }
32
+ export function parseAgentCapabilities(value) {
33
+ if (!Array.isArray(value) ||
34
+ value.length > agentCapabilities.length ||
35
+ new Set(value).size !== value.length ||
36
+ value.some((c) => !agentCapabilities.includes(c)))
37
+ throw new Error('Unsupported or duplicate agent capability. V1 supports bounded reads, findings and user questions only.');
38
+ return [...value];
39
+ }
40
+ export function parseAgentDefinition(value) {
41
+ const v = object(value, [
42
+ 'schemaVersion',
43
+ 'projectId',
44
+ 'id',
45
+ 'version',
46
+ 'name',
47
+ 'instructions',
48
+ 'requestedCapabilities',
49
+ 'contextRequirements',
50
+ 'output',
51
+ ]);
52
+ if (v.schemaVersion !== 1)
53
+ throw new Error('Unsupported agent schema version.');
54
+ const requestedCapabilities = parseAgentCapabilities(v.requestedCapabilities);
55
+ if (!Array.isArray(v.contextRequirements) ||
56
+ v.contextRequirements.length > 3 ||
57
+ new Set(v.contextRequirements).size !== v.contextRequirements.length ||
58
+ v.contextRequirements.some((c) => !['prompt', 'workspace', 'snapshot'].includes(c)))
59
+ throw new Error('Invalid context requirements.');
60
+ if (v.output !== 'conversation' && v.output !== 'review-findings')
61
+ throw new Error('Unsupported output contract.');
62
+ const contextRequirements = [...v.contextRequirements];
63
+ if (requestedCapabilities.includes('workspace.read') &&
64
+ !contextRequirements.includes('workspace'))
65
+ throw new Error('Workspace reads require workspace context.');
66
+ if ((requestedCapabilities.includes('snapshot.read') ||
67
+ requestedCapabilities.includes('findings.report')) &&
68
+ !contextRequirements.includes('snapshot'))
69
+ throw new Error('Snapshot tools require snapshot context.');
70
+ if (v.output === 'review-findings' && !requestedCapabilities.includes('findings.report'))
71
+ throw new Error('Findings output requires findings.report.');
72
+ if (v.output === 'conversation' && requestedCapabilities.includes('findings.report'))
73
+ throw new Error('Conversation output cannot publish findings.');
74
+ return {
75
+ schemaVersion: 1,
76
+ projectId: agentId(v.projectId),
77
+ id: agentId(v.id),
78
+ version: version(v.version),
79
+ name: agentText(v.name, 'name'),
80
+ instructions: agentText(v.instructions, 'instructions', 16000),
81
+ requestedCapabilities,
82
+ contextRequirements,
83
+ output: v.output,
84
+ };
85
+ }
86
+ export function parseAgentConnection(value) {
87
+ const v = object(value, [
88
+ 'schemaVersion',
89
+ 'projectId',
90
+ 'id',
91
+ 'version',
92
+ 'agent',
93
+ 'placement',
94
+ 'trigger',
95
+ 'inputMapping',
96
+ 'permissionCeiling',
97
+ 'resultDestination',
98
+ ]);
99
+ const agent = object(v.agent, ['id', 'version']);
100
+ const mapping = object(v.inputMapping, ['prompt', 'workspace', 'snapshot']);
101
+ const sources = {
102
+ prompt: 'user-message',
103
+ workspace: 'project-workspace',
104
+ snapshot: 'captured-snapshot',
105
+ };
106
+ for (const [key, source] of Object.entries(mapping))
107
+ if (source !== sources[key])
108
+ throw new Error('Unsupported input mapping.');
109
+ if (mapping.prompt !== 'user-message')
110
+ throw new Error('Manual connections require a prompt input mapping.');
111
+ if (v.schemaVersion !== 1 || v.trigger !== 'manual')
112
+ throw new Error('Only schema v1 manual connections are supported.');
113
+ if (v.placement !== 'conversation-action' && v.placement !== 'snapshot-action')
114
+ throw new Error('Unsupported placement.');
115
+ if (v.resultDestination !== 'conversation' && v.resultDestination !== 'review-findings')
116
+ throw new Error('Unsupported result destination.');
117
+ // A conversation action may run a snapshot reviewer, but its output still belongs
118
+ // to Reviews. Placement never changes the immutable-context security boundary.
119
+ if (v.resultDestination === 'review-findings' && !mapping.snapshot)
120
+ throw new Error('Findings destinations require immutable snapshot context.');
121
+ if (mapping.snapshot && mapping.workspace)
122
+ throw new Error('Snapshot context prohibits live workspace context.');
123
+ if (v.placement === 'snapshot-action' && (mapping.workspace || !mapping.snapshot))
124
+ throw new Error('Snapshot placement requires immutable snapshot context and prohibits live workspace context.');
125
+ const permissionCeiling = parseAgentCapabilities(v.permissionCeiling);
126
+ if (mapping.snapshot && permissionCeiling.includes('workspace.read'))
127
+ throw new Error('Snapshot context prohibits live workspace capabilities.');
128
+ return {
129
+ schemaVersion: 1,
130
+ projectId: agentId(v.projectId),
131
+ id: agentId(v.id),
132
+ version: version(v.version),
133
+ agent: { id: agentId(agent.id), version: version(agent.version) },
134
+ placement: v.placement,
135
+ trigger: 'manual',
136
+ inputMapping: { ...mapping },
137
+ permissionCeiling,
138
+ resultDestination: v.resultDestination,
139
+ };
140
+ }
141
+ /** Unknown host capabilities fail rather than silently claiming support. Restrictions only narrow. */
142
+ export function resolveAgentCapabilities(definition, connection, host) {
143
+ const d = parseAgentDefinition(definition), c = parseAgentConnection(connection);
144
+ const supported = parseAgentCapabilities(host);
145
+ if (d.projectId !== c.projectId || d.id !== c.agent.id || d.version !== c.agent.version)
146
+ throw new Error('Connection belongs to another project or definition version.');
147
+ if (d.output !== c.resultDestination || d.contextRequirements.some((k) => !c.inputMapping[k]))
148
+ throw new Error('Incompatible connection context or result destination.');
149
+ const effective = d.requestedCapabilities.filter((cap) => supported.includes(cap) && c.permissionCeiling.includes(cap));
150
+ if (d.output === 'review-findings' && !effective.includes('findings.report'))
151
+ throw new Error('Connection or host denies required findings output capability.');
152
+ return effective;
153
+ }
154
+ export function parseAgentInput(value, connection) {
155
+ const v = object(value, ['prompt', 'snapshot']);
156
+ const prompt = agentText(v.prompt, 'invocation prompt', 20000);
157
+ if (JSON.stringify(value).length > 2_000_000)
158
+ throw new Error('Invocation input exceeds 2 MB character limit.');
159
+ if (!connection.inputMapping.prompt)
160
+ throw new Error('Connection does not map prompt input.');
161
+ if (!connection.inputMapping.snapshot) {
162
+ if (v.snapshot !== undefined)
163
+ throw new Error('Invocation snapshot does not match connection context.');
164
+ return { prompt };
165
+ }
166
+ if (!v.snapshot)
167
+ throw new Error('Invocation requires an immutable snapshot.');
168
+ const snapshot = object(v.snapshot, ['revision', 'files', 'baseFiles', 'diff', 'base', 'target']);
169
+ const files = (input) => {
170
+ if (!input ||
171
+ typeof input !== 'object' ||
172
+ Array.isArray(input) ||
173
+ Object.values(input).some((v) => typeof v !== 'string'))
174
+ throw new Error('Invalid snapshot files.');
175
+ return { ...input };
176
+ };
177
+ const parsed = {
178
+ revision: agentText(snapshot.revision, 'snapshot revision', 200),
179
+ files: files(snapshot.files),
180
+ };
181
+ if (snapshot.baseFiles !== undefined)
182
+ parsed.baseFiles = files(snapshot.baseFiles);
183
+ for (const key of ['base', 'target', 'diff']) {
184
+ if (snapshot[key] !== undefined) {
185
+ if (typeof snapshot[key] !== 'string')
186
+ throw new Error(`Invalid snapshot ${key}.`);
187
+ parsed[key] = snapshot[key];
188
+ }
189
+ }
190
+ return { prompt, snapshot: parsed };
191
+ }
192
+ /** Validate durable records too: corrupt/future state must not become launch authority. */
193
+ export function parseAgentInvocation(value) {
194
+ const v = object(value, [
195
+ 'schemaVersion',
196
+ 'projectId',
197
+ 'id',
198
+ 'sessionId',
199
+ 'runId',
200
+ 'definition',
201
+ 'connection',
202
+ 'effectiveCapabilities',
203
+ 'input',
204
+ 'status',
205
+ 'revision',
206
+ 'createdAt',
207
+ 'updatedAt',
208
+ 'error',
209
+ ]);
210
+ if (v.schemaVersion !== 1)
211
+ throw new Error('Unsupported invocation schema version.');
212
+ const definition = parseAgentDefinition(v.definition), connection = parseAgentConnection(v.connection);
213
+ const projectId = agentId(v.projectId), id = agentId(v.id), sessionId = agentId(v.sessionId), runId = agentId(v.runId);
214
+ if (definition.projectId !== projectId || new Set([id, sessionId, runId]).size !== 3)
215
+ throw new Error('Invalid invocation project or isolated identity.');
216
+ const effectiveCapabilities = parseAgentCapabilities(v.effectiveCapabilities);
217
+ const allowed = resolveAgentCapabilities(definition, connection, effectiveCapabilities);
218
+ if (effectiveCapabilities.some((c) => !allowed.includes(c)))
219
+ throw new Error('Invocation capabilities exceed frozen authority.');
220
+ if (![
221
+ 'prepared',
222
+ 'running',
223
+ 'cancelling',
224
+ 'completed',
225
+ 'failed',
226
+ 'cancelled',
227
+ 'interrupted',
228
+ ].includes(String(v.status)))
229
+ throw new Error('Invalid invocation status.');
230
+ const timestamp = (input) => {
231
+ const text = agentText(input, 'invocation timestamp', 40);
232
+ if (!Number.isFinite(Date.parse(text)) || new Date(text).toISOString() !== text)
233
+ throw new Error('Invalid invocation timestamp.');
234
+ return text;
235
+ };
236
+ return {
237
+ schemaVersion: 1,
238
+ projectId,
239
+ id,
240
+ sessionId,
241
+ runId,
242
+ definition,
243
+ connection,
244
+ effectiveCapabilities,
245
+ input: parseAgentInput(v.input, connection),
246
+ status: v.status,
247
+ revision: version(v.revision),
248
+ createdAt: timestamp(v.createdAt),
249
+ updatedAt: timestamp(v.updatedAt),
250
+ ...(v.error === undefined ? {} : { error: agentText(v.error, 'invocation error', 4000) }),
251
+ };
252
+ }
253
+ export function agentExamples(projectId) {
254
+ return [
255
+ {
256
+ id: 'snapshot-reviewer',
257
+ name: 'Snapshot reviewer',
258
+ instructions: 'Review the supplied immutable snapshot for actionable bugs. Report evidence-backed findings and finish with a concise summary.',
259
+ requestedCapabilities: ['snapshot.read', 'findings.report', 'user.ask'],
260
+ contextRequirements: ['prompt', 'snapshot'],
261
+ output: 'review-findings',
262
+ placement: 'snapshot-action',
263
+ inputMapping: { prompt: 'user-message', snapshot: 'captured-snapshot' },
264
+ },
265
+ {
266
+ id: 'project-summary',
267
+ name: 'Project summary',
268
+ instructions: 'Inspect the project and explain its purpose and structure in ordinary conversation. Cite relevant files and acknowledge uncertainty.',
269
+ requestedCapabilities: ['workspace.read', 'user.ask'],
270
+ contextRequirements: ['prompt', 'workspace'],
271
+ output: 'conversation',
272
+ placement: 'conversation-action',
273
+ inputMapping: { prompt: 'user-message', workspace: 'project-workspace' },
274
+ },
275
+ ].map((v) => {
276
+ const definition = parseAgentDefinition({
277
+ schemaVersion: 1,
278
+ projectId,
279
+ id: v.id,
280
+ version: 1,
281
+ name: v.name,
282
+ instructions: v.instructions,
283
+ requestedCapabilities: v.requestedCapabilities,
284
+ contextRequirements: v.contextRequirements,
285
+ output: v.output,
286
+ });
287
+ const connection = parseAgentConnection({
288
+ schemaVersion: 1,
289
+ projectId,
290
+ id: `${v.id}-manual`,
291
+ version: 1,
292
+ agent: { id: v.id, version: 1 },
293
+ placement: v.placement,
294
+ trigger: 'manual',
295
+ inputMapping: v.inputMapping,
296
+ permissionCeiling: v.requestedCapabilities,
297
+ resultDestination: v.output,
298
+ });
299
+ return { definition, connection };
300
+ });
301
+ }
@@ -0,0 +1 @@
1
+ export {};
@@ -0,0 +1,40 @@
1
+ /** Finite commands only. Results are passive observations, never task/review gates. */
2
+ export const checkLimits = {
3
+ session: 2,
4
+ host: 4,
5
+ lifetimeMs: 60 * 60 * 1000,
6
+ tailBytes: 64 * 1024,
7
+ logBytes: 10 * 1024 * 1024,
8
+ hostBytes: 250 * 1024 * 1024,
9
+ retentionMs: 7 * 24 * 60 * 60 * 1000,
10
+ };
11
+ export const activeCheck = (check) => ['awaiting_approval', 'starting', 'running'].includes(check.state);
12
+ export function parseCheckRequest(value) {
13
+ if (!value || typeof value !== 'object' || Array.isArray(value))
14
+ throw new Error('Invalid check request');
15
+ const v = value;
16
+ const text = (key, max) => {
17
+ const t = v[key];
18
+ if (typeof t !== 'string' || !t.trim() || t.length > max || t.includes('\0'))
19
+ throw new Error(`Invalid check ${key}`);
20
+ return t;
21
+ };
22
+ if (v.action === 'start')
23
+ return {
24
+ action: 'start',
25
+ requestId: text('requestId', 128),
26
+ command: text('command', 20000),
27
+ purpose: text('purpose', 1000),
28
+ ...(v.taskId === undefined ? {} : { taskId: text('taskId', 128) }),
29
+ };
30
+ if (v.action === 'read') {
31
+ if (v.offset !== undefined && (!Number.isSafeInteger(v.offset) || Number(v.offset) < 0))
32
+ throw new Error('Invalid output offset');
33
+ return {
34
+ action: 'read',
35
+ checkId: text('checkId', 128),
36
+ offset: v.offset,
37
+ };
38
+ }
39
+ throw new Error('Unknown check action');
40
+ }
@@ -0,0 +1,28 @@
1
+ export const childSessionLimits = { depth: 2, totalSpawns: 8 };
2
+ export function parseStartChildRequest(value) {
3
+ const v = value;
4
+ if (!v ||
5
+ typeof v !== 'object' ||
6
+ Array.isArray(v) ||
7
+ v.action !== 'start' ||
8
+ Object.keys(v).some((key) => !['action', 'requestKey', 'prompt', 'contextMode', 'attachments'].includes(key)) ||
9
+ typeof v.requestKey !== 'string' ||
10
+ !/^[a-zA-Z0-9_-]{1,128}$/.test(v.requestKey) ||
11
+ typeof v.prompt !== 'string' ||
12
+ !v.prompt.trim() ||
13
+ v.prompt.length > 200000 ||
14
+ (v.contextMode !== undefined && !['inherit', 'fresh'].includes(v.contextMode)) ||
15
+ (v.attachments !== undefined &&
16
+ (!Array.isArray(v.attachments) ||
17
+ v.attachments.length > 10 ||
18
+ v.attachments.some((id) => typeof id !== 'string' ||
19
+ !/^[0-9a-f]{8}-[0-9a-f]{4}-4[0-9a-f]{3}-[89ab][0-9a-f]{3}-[0-9a-f]{12}$/i.test(id)))))
20
+ throw new Error('Supply a stable requestKey, self-contained prompt, inherit/fresh context, and at most 10 uploaded attachment IDs.');
21
+ return {
22
+ action: 'start',
23
+ requestKey: v.requestKey,
24
+ prompt: v.prompt,
25
+ contextMode: v.contextMode ?? 'inherit',
26
+ attachments: [...new Set(v.attachments ?? [])],
27
+ };
28
+ }
@@ -0,0 +1,3 @@
1
+ /** Application-owned versions. Changing either invalidates outstanding dispatch grants. */
2
+ export const commandPolicyRevision = 'command-policy-v1';
3
+ export const commandGrammarVersion = 'literal-shell-v1';
@@ -0,0 +1,135 @@
1
+ import { parseStartChildRequest, } from './child-sessions.js';
2
+ import { parseReviewRequest } from './reviewers.js';
3
+ export function parseCoordinatorRequest(value) {
4
+ if (!value || typeof value !== 'object' || Array.isArray(value))
5
+ throw new Error('Invalid coordinator request.');
6
+ const v = value;
7
+ if (v.action === 'start_review_session') {
8
+ if (Object.keys(v).some((key) => !['action', 'requestKey', 'scope', 'base', 'target', 'focus'].includes(key)) ||
9
+ typeof v.requestKey !== 'string' ||
10
+ !/^[a-zA-Z0-9_-]{1,128}$/.test(v.requestKey) ||
11
+ (v.focus !== undefined &&
12
+ !['general', 'correctness', 'security', 'tests'].includes(String(v.focus))))
13
+ throw new Error('Supply a stable requestKey and a valid reviewer focus.');
14
+ return {
15
+ action: 'start_review_session',
16
+ requestKey: v.requestKey,
17
+ ...parseReviewRequest(v),
18
+ ...(v.focus === undefined
19
+ ? {}
20
+ : { focus: v.focus }),
21
+ };
22
+ }
23
+ if (v.action === 'launch_tasks') {
24
+ if (Object.keys(v).some((key) => !['action', 'requestKey', 'revision', 'version', 'taskIds'].includes(key)) ||
25
+ typeof v.requestKey !== 'string' ||
26
+ !/^[a-zA-Z0-9_-]{1,128}$/.test(v.requestKey) ||
27
+ !Number.isSafeInteger(v.revision) ||
28
+ Number(v.revision) < 0 ||
29
+ !Number.isSafeInteger(v.version) ||
30
+ Number(v.version) < 0 ||
31
+ !Array.isArray(v.taskIds) ||
32
+ !v.taskIds.length ||
33
+ v.taskIds.length > 50 ||
34
+ new Set(v.taskIds).size !== v.taskIds.length ||
35
+ v.taskIds.some((id) => typeof id !== 'string' || !id.trim() || id.length > 80))
36
+ throw new Error('Supply a stable requestKey, current revision and version, and distinct stable task IDs from get_tasks.');
37
+ return {
38
+ action: 'launch_tasks',
39
+ requestKey: v.requestKey,
40
+ revision: v.revision,
41
+ version: v.version,
42
+ taskIds: [...v.taskIds],
43
+ };
44
+ }
45
+ if (v.action === 'start')
46
+ return parseStartChildRequest(v);
47
+ if (v.action === 'list' && Object.keys(v).length === 1)
48
+ return { action: 'list' };
49
+ if (v.action !== 'send' ||
50
+ Object.keys(v).some((key) => !['action', 'version', 'attemptId', 'message', 'attachments', 'requestKey', 'followUpToken'].includes(key)) ||
51
+ (v.requestKey !== undefined &&
52
+ (typeof v.requestKey !== 'string' || !/^[a-zA-Z0-9_-]{1,128}$/.test(v.requestKey))) ||
53
+ (v.followUpToken !== undefined &&
54
+ (typeof v.followUpToken !== 'string' || !/^[0-9a-f]{64}$/.test(v.followUpToken))) ||
55
+ !Number.isSafeInteger(v.version) ||
56
+ Number(v.version) < 0 ||
57
+ typeof v.attemptId !== 'string' ||
58
+ !v.attemptId.trim() ||
59
+ v.attemptId.length > 128 ||
60
+ typeof v.message !== 'string' ||
61
+ !v.message.trim() ||
62
+ v.message.length > 200000 ||
63
+ (v.attachments !== undefined &&
64
+ (!Array.isArray(v.attachments) ||
65
+ v.attachments.length > 10 ||
66
+ v.attachments.some((id) => typeof id !== 'string' ||
67
+ !/^[0-9a-f]{8}-[0-9a-f]{4}-4[0-9a-f]{3}-[89ab][0-9a-f]{3}-[0-9a-f]{12}$/i.test(id)))))
68
+ throw new Error('Supply a child attempt, current version, message, and at most 10 attachment IDs.');
69
+ return {
70
+ action: 'send',
71
+ ...(v.requestKey === undefined ? {} : { requestKey: v.requestKey }),
72
+ ...(v.followUpToken === undefined ? {} : { followUpToken: v.followUpToken }),
73
+ version: v.version,
74
+ attemptId: v.attemptId,
75
+ message: v.message,
76
+ ...(v.attachments === undefined
77
+ ? {}
78
+ : { attachments: [...new Set(v.attachments)] }),
79
+ };
80
+ }
81
+ export function parseCoordinatorResult(value) {
82
+ const v = value;
83
+ if (!v ||
84
+ !Number.isSafeInteger(v.version) ||
85
+ v.version < 0 ||
86
+ (v.launch !== undefined &&
87
+ (!v.launch ||
88
+ v.launch.acceptance !== 'queued' ||
89
+ typeof v.launch.requestKey !== 'string' ||
90
+ !Array.isArray(v.launch.attempts) ||
91
+ !v.launch.attempts.length ||
92
+ v.launch.attempts.length > 50 ||
93
+ v.launch.attempts.some((a) => !a ||
94
+ ![a.taskId, a.attemptId, a.sessionId].every((id) => typeof id === 'string' && !!id)))) ||
95
+ (v.startedSessionId !== undefined && typeof v.startedSessionId !== 'string') ||
96
+ (v.ordinaryChildren !== undefined &&
97
+ (!Array.isArray(v.ordinaryChildren) ||
98
+ v.ordinaryChildren.length > 100 ||
99
+ v.ordinaryChildren.some((child) => !child ||
100
+ !['sessionId', 'parentSessionId', 'title', 'status', 'url'].every((key) => typeof child[key] === 'string')))) ||
101
+ !Array.isArray(v.children) ||
102
+ v.children.length > 100 ||
103
+ !Array.isArray(v.attachments) ||
104
+ v.attachments.length > 100 ||
105
+ (v.messageId !== undefined && typeof v.messageId !== 'string') ||
106
+ v.children.some((child) => !child ||
107
+ !['attemptId', 'sessionId', 'taskId', 'title'].every((key) => typeof child[key] === 'string') ||
108
+ ![
109
+ 'queued',
110
+ 'starting',
111
+ 'running',
112
+ 'waiting',
113
+ 'needs_review',
114
+ 'done',
115
+ 'failed',
116
+ 'interrupted',
117
+ 'cancelled',
118
+ ].includes(child.status) ||
119
+ !Number.isSafeInteger(child.pendingReplies) ||
120
+ child.pendingReplies < 0 ||
121
+ typeof child.paused !== 'boolean' ||
122
+ (child.followUpToken !== undefined &&
123
+ (typeof child.followUpToken !== 'string' || !/^[0-9a-f]{64}$/.test(child.followUpToken))) ||
124
+ (child.question !== undefined && typeof child.question !== 'string') ||
125
+ (child.blockedReason !== undefined && typeof child.blockedReason !== 'string') ||
126
+ (child.summary !== undefined && typeof child.summary !== 'string')) ||
127
+ v.attachments.some((a) => !a ||
128
+ typeof a.id !== 'string' ||
129
+ typeof a.name !== 'string' ||
130
+ typeof a.type !== 'string' ||
131
+ !Number.isSafeInteger(a.size) ||
132
+ a.size < 0))
133
+ throw new Error('Invalid coordinator response.');
134
+ return v;
135
+ }
@@ -0,0 +1,40 @@
1
+ export function parseTaskResult(value) {
2
+ if (!value || typeof value !== 'object')
3
+ throw new Error('Invalid task result.');
4
+ const v = value;
5
+ for (const [key, max] of Object.entries({
6
+ summary: 8000,
7
+ changedAreas: 4000,
8
+ verification: 8000,
9
+ unresolved: 4000,
10
+ })) {
11
+ if (typeof v[key] !== 'string' ||
12
+ v[key].length > max ||
13
+ (['summary', 'verification'].includes(key) && !v[key].trim()))
14
+ throw new Error('Invalid task result. Include a summary and verification actually performed.');
15
+ }
16
+ return {
17
+ summary: v.summary,
18
+ changedAreas: v.changedAreas,
19
+ verification: v.verification,
20
+ unresolved: v.unresolved,
21
+ };
22
+ }
23
+ export function taskQueuedMessages(attempt) {
24
+ return (attempt.queuedReplies ?? []).map((reply) => ({
25
+ ...reply,
26
+ attachments: reply.attachments ?? [],
27
+ createdAt: reply.createdAt ?? attempt.createdAt,
28
+ }));
29
+ }
30
+ export const defaultDelegatedExecutionLimit = 5;
31
+ export const minDelegatedExecutionLimit = 1;
32
+ export const maxDelegatedExecutionLimit = 10;
33
+ export const emptyDelegationState = () => ({
34
+ version: 0,
35
+ paused: true,
36
+ concurrency: defaultDelegatedExecutionLimit,
37
+ hostLimit: defaultDelegatedExecutionLimit,
38
+ batches: [],
39
+ attempts: [],
40
+ });
@@ -0,0 +1,71 @@
1
+ /** Git quotes control characters and, by default, non-ASCII bytes in diff headers. */
2
+ function quotedPath(path, octal) {
3
+ const escapes = {
4
+ 7: '\\a',
5
+ 8: '\\b',
6
+ 9: '\\t',
7
+ 10: '\\n',
8
+ 11: '\\v',
9
+ 12: '\\f',
10
+ 13: '\\r',
11
+ 34: '\\"',
12
+ 92: '\\\\',
13
+ };
14
+ if (!octal)
15
+ return JSON.stringify(path);
16
+ return ('"' +
17
+ Array.from(new TextEncoder().encode(path), (byte) => escapes[byte] ??
18
+ (byte < 32 || byte >= 127
19
+ ? '\\' + byte.toString(8).padStart(3, '0')
20
+ : String.fromCharCode(byte))).join('') +
21
+ '"');
22
+ }
23
+ /** Workspace and review diffs use --no-renames, so both header paths identify the same file. */
24
+ function headersForFile(path) {
25
+ const variants = (prefix) => [
26
+ prefix + path,
27
+ quotedPath(prefix + path, false),
28
+ quotedPath(prefix + path, true),
29
+ ];
30
+ return variants('a/').flatMap((left) => variants('b/').map((right) => `diff --git ${left} ${right}`));
31
+ }
32
+ /** Preserve unmatched sections too: file lists and live diffs can refresh independently. */
33
+ export function diffSections(diff, paths) {
34
+ const names = new Map(paths.flatMap((path) => headersForFile(path).map((header) => [header, path])));
35
+ return diff
36
+ .split(/(?=^diff --git |^Untracked file excluded: )/m)
37
+ .filter(Boolean)
38
+ .map((value) => {
39
+ const header = value.split('\n', 1)[0];
40
+ let path = names.get(header) ?? header;
41
+ if (header.startsWith('Untracked file excluded: ')) {
42
+ try {
43
+ const excluded = JSON.parse(header.slice('Untracked file excluded: '.length));
44
+ if (typeof excluded === 'string')
45
+ path = excluded;
46
+ }
47
+ catch {
48
+ // Preserve the original notice if its filename cannot be decoded.
49
+ }
50
+ }
51
+ let additions = 0;
52
+ let deletions = 0;
53
+ let inHunk = false;
54
+ for (const line of value.split('\n')) {
55
+ if (line.startsWith('@@ '))
56
+ inHunk = true;
57
+ else if (inHunk && line.startsWith('+'))
58
+ additions++;
59
+ else if (inHunk && line.startsWith('-'))
60
+ deletions++;
61
+ }
62
+ return { value, path, additions, deletions };
63
+ });
64
+ }
65
+ export function diffForFile(diff, path) {
66
+ const headers = new Set(headersForFile(path));
67
+ return diff
68
+ .split(/(?=^diff --git )/m)
69
+ .filter((section) => headers.has(section.split('\n', 1)[0]))
70
+ .join('');
71
+ }
@@ -0,0 +1 @@
1
+ export {};
@@ -0,0 +1 @@
1
+ export const reasoningLevels = ['off', 'minimal', 'low', 'medium', 'high', 'xhigh', 'max'];