forgeos 0.1.0-alpha.68 → 0.1.0-alpha.69

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 (57) hide show
  1. package/.agents/skills/forge-agent-fabric/SKILL.md +21 -1
  2. package/.agents/skills/forge-agent-fabric/references/repository-analysis.md +102 -0
  3. package/.agents/skills/forge-agent-fabric/scripts/repository.mjs +44 -0
  4. package/AGENTS.md +1 -1
  5. package/CHANGELOG.md +16 -0
  6. package/README.md +12 -3
  7. package/docs/agent-fabric.md +13 -0
  8. package/docs/architecture/agent-fabric/REPOSITORY_MANIFEST_PLAN.md +272 -0
  9. package/docs/changelog.md +32 -0
  10. package/docs/repository-agent-benchmark.md +179 -0
  11. package/docs/repository-analysis.md +139 -0
  12. package/docs/repository-context-quality.md +179 -0
  13. package/docs/repository-runtime-observation.md +82 -0
  14. package/package.json +14 -2
  15. package/schemas/forge-manifest.schema.json +385 -53
  16. package/src/forge/_generated/releaseManifest.json +1 -1
  17. package/src/forge/_generated/releaseManifest.ts +3 -3
  18. package/src/forge/agent-fabric/managed-run-contract.ts +1 -0
  19. package/src/forge/agent-fabric/managed-run-service.ts +10 -1
  20. package/src/forge/agent-fabric/managed-run-store.ts +20 -0
  21. package/src/forge/agent-fabric/managed-workspace.ts +56 -18
  22. package/src/forge/agent-fabric/repository-context.ts +83 -0
  23. package/src/forge/agent-memory/mcp.ts +38 -1
  24. package/src/forge/cair/index.ts +15 -3
  25. package/src/forge/cair/types.ts +9 -2
  26. package/src/forge/cli/commands.ts +19 -0
  27. package/src/forge/cli/main.ts +15 -0
  28. package/src/forge/cli/parse.ts +70 -16
  29. package/src/forge/cli/repository.ts +151 -0
  30. package/src/forge/compiler/external-manifest/registry.ts +21 -9
  31. package/src/forge/delta/process-identity.ts +22 -16
  32. package/src/forge/repository-analysis/adapters/common.ts +72 -0
  33. package/src/forge/repository-analysis/adapters/docker.ts +185 -0
  34. package/src/forge/repository-analysis/adapters/java.ts +133 -0
  35. package/src/forge/repository-analysis/adapters/typescript.ts +350 -0
  36. package/src/forge/repository-analysis/adapters/vue.ts +71 -0
  37. package/src/forge/repository-analysis/analyze.ts +434 -0
  38. package/src/forge/repository-analysis/benchmark.ts +336 -0
  39. package/src/forge/repository-analysis/cache-gc.ts +154 -0
  40. package/src/forge/repository-analysis/check-selection.ts +123 -0
  41. package/src/forge/repository-analysis/context-node.ts +17 -0
  42. package/src/forge/repository-analysis/context.ts +456 -0
  43. package/src/forge/repository-analysis/http-resolution.ts +135 -0
  44. package/src/forge/repository-analysis/identity.ts +45 -0
  45. package/src/forge/repository-analysis/index.ts +18 -0
  46. package/src/forge/repository-analysis/nuxt-resolution.ts +188 -0
  47. package/src/forge/repository-analysis/quality.ts +60 -0
  48. package/src/forge/repository-analysis/retrieval.ts +309 -0
  49. package/src/forge/repository-analysis/runtime-artifacts.ts +195 -0
  50. package/src/forge/repository-analysis/runtime-observation.ts +316 -0
  51. package/src/forge/repository-analysis/scanner.ts +174 -0
  52. package/src/forge/repository-analysis/storage.ts +193 -0
  53. package/src/forge/repository-analysis/test-associations.ts +59 -0
  54. package/src/forge/repository-analysis/types.ts +99 -0
  55. package/src/forge/repository-manifest/index.ts +178 -0
  56. package/src/forge/repository-manifest/types.ts +63 -0
  57. package/src/forge/version.ts +1 -1
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "forgeos",
3
- "version": "0.1.0-alpha.68",
3
+ "version": "0.1.0-alpha.69",
4
4
  "description": "Agent-native application framework and compiler for building Forge apps without a mandatory dashboard.",
5
5
  "type": "module",
6
6
  "license": "MIT",
@@ -16,6 +16,11 @@
16
16
  "docs/cair-protocol.md",
17
17
  "docs/forge-protocol.md",
18
18
  "docs/agent-fabric.md",
19
+ "docs/repository-analysis.md",
20
+ "docs/repository-context-quality.md",
21
+ "docs/repository-agent-benchmark.md",
22
+ "docs/repository-runtime-observation.md",
23
+ "docs/architecture/agent-fabric/REPOSITORY_MANIFEST_PLAN.md",
19
24
  "docs/architecture/agent-fabric/PORTABLE_PROJECTS_PLAN.md",
20
25
  "examples/go-billing/",
21
26
  "examples/java-billing/",
@@ -53,7 +58,8 @@
53
58
  "./vue": "./src/forge/vue/index.ts",
54
59
  "./server": "./src/forge/server.ts",
55
60
  "./policy": "./src/forge/policy.ts",
56
- "./agent-fabric": "./src/forge/agent-fabric/index.ts"
61
+ "./agent-fabric": "./src/forge/agent-fabric/index.ts",
62
+ "./repository-analysis": "./src/forge/repository-analysis/index.ts"
57
63
  },
58
64
  "scripts": {
59
65
  "test": "node ./bin/forge-bun.mjs test --timeout 120000",
@@ -111,6 +117,7 @@
111
117
  "@electric-sql/pglite": "^0.2.17",
112
118
  "@openai/codex-sdk": "0.160.0",
113
119
  "@types/react": "^19.2.17",
120
+ "@vue/compiler-sfc": "3.5.38",
114
121
  "ai": "^6.0.205",
115
122
  "jose": "^6.2.3",
116
123
  "postgres": "^3.4.5",
@@ -120,6 +127,7 @@
120
127
  "tsx": "^4.20.6",
121
128
  "typescript": "^5.7.3",
122
129
  "vue": "^3.5.38",
130
+ "yaml": "2.9.1",
123
131
  "zod": "^3.25.76"
124
132
  },
125
133
  "devDependencies": {
@@ -133,6 +141,10 @@
133
141
  "react-test-renderer": "^19.2.7"
134
142
  },
135
143
  "overrides": {
144
+ "@ai-sdk/provider-utils": "4.0.33",
145
+ "fast-uri": "3.1.8",
146
+ "nanoid": "3.3.18",
147
+ "postcss": "8.5.29",
136
148
  "read-yaml-file": "^3.0.0"
137
149
  }
138
150
  }
@@ -1,57 +1,389 @@
1
- {
2
- "$schema": "https://json-schema.org/draft/2020-12/schema",
3
- "$id": "https://forgeos.dev/schemas/forge-manifest.schema.json",
4
- "title": "Forge external runtime manifest",
5
- "type": "object",
6
- "required": ["forgeProtocol", "language", "service", "entries"],
7
- "properties": {
8
- "forgeProtocol": { "const": "1.0" },
9
- "language": { "type": "string", "minLength": 1 },
10
- "framework": { "type": "string", "minLength": 1 },
11
- "service": {
12
- "type": "object",
13
- "required": ["name", "transport"],
14
- "properties": {
15
- "name": { "type": "string", "minLength": 1 },
16
- "transport": { "enum": ["http", "grpc", "stdio"] },
17
- "baseUrl": { "type": "string", "minLength": 1 },
18
- "command": { "type": "string", "minLength": 1 },
19
- "health": { "type": "string", "minLength": 1 }
20
- },
21
- "additionalProperties": false
22
- },
23
- "entries": {
24
- "type": "array",
25
- "items": {
26
- "type": "object",
27
- "required": ["name", "kind"],
28
- "properties": {
29
- "name": { "type": "string", "minLength": 1 },
30
- "kind": { "enum": ["command", "query"] },
31
- "description": { "type": "string" },
32
- "path": { "type": "string", "minLength": 1 },
33
- "method": { "enum": ["GET", "POST"] },
34
- "inputSchema": {},
35
- "outputSchema": {},
36
- "policy": { "type": "string", "minLength": 1 },
37
- "tenantScoped": { "type": "boolean" },
38
- "transaction": {
39
- "enum": ["read-only", "external-managed", "forge-managed", "saga"]
40
- },
41
- "risk": { "enum": ["read", "write", "destructive", "external"] },
42
- "needsApproval": { "type": "boolean" },
43
- "effects": {
44
- "type": "array",
45
- "items": { "type": "string" }
1
+ {
2
+ "$schema": "https://json-schema.org/draft/2020-12/schema",
3
+ "$id": "https://forgeos.dev/schemas/forge-manifest.schema.json",
4
+ "title": "Forge external runtime manifest",
5
+ "oneOf": [
6
+ {
7
+ "$ref": "#/$defs/service"
8
+ },
9
+ {
10
+ "$ref": "#/$defs/repository"
11
+ }
12
+ ],
13
+ "$defs": {
14
+ "service": {
15
+ "type": "object",
16
+ "required": [
17
+ "forgeProtocol",
18
+ "language",
19
+ "service",
20
+ "entries"
21
+ ],
22
+ "properties": {
23
+ "forgeProtocol": {
24
+ "const": "1.0"
25
+ },
26
+ "language": {
27
+ "type": "string",
28
+ "minLength": 1
29
+ },
30
+ "framework": {
31
+ "type": "string",
32
+ "minLength": 1
33
+ },
34
+ "service": {
35
+ "type": "object",
36
+ "required": [
37
+ "name",
38
+ "transport"
39
+ ],
40
+ "properties": {
41
+ "name": {
42
+ "type": "string",
43
+ "minLength": 1
44
+ },
45
+ "transport": {
46
+ "enum": [
47
+ "http",
48
+ "grpc",
49
+ "stdio"
50
+ ]
51
+ },
52
+ "baseUrl": {
53
+ "type": "string",
54
+ "minLength": 1
55
+ },
56
+ "command": {
57
+ "type": "string",
58
+ "minLength": 1
59
+ },
60
+ "health": {
61
+ "type": "string",
62
+ "minLength": 1
63
+ },
64
+ "commandArgs": {
65
+ "type": "array",
66
+ "minItems": 1,
67
+ "prefixItems": [
68
+ {
69
+ "type": "string",
70
+ "minLength": 1
71
+ }
72
+ ],
73
+ "items": {
74
+ "type": "string"
75
+ }
76
+ }
77
+ },
78
+ "additionalProperties": false
79
+ },
80
+ "entries": {
81
+ "type": "array",
82
+ "items": {
83
+ "type": "object",
84
+ "required": [
85
+ "name",
86
+ "kind"
87
+ ],
88
+ "properties": {
89
+ "name": {
90
+ "type": "string",
91
+ "minLength": 1
92
+ },
93
+ "kind": {
94
+ "enum": [
95
+ "command",
96
+ "query"
97
+ ]
98
+ },
99
+ "description": {
100
+ "type": "string"
101
+ },
102
+ "path": {
103
+ "type": "string",
104
+ "minLength": 1
105
+ },
106
+ "method": {
107
+ "enum": [
108
+ "GET",
109
+ "POST"
110
+ ]
111
+ },
112
+ "inputSchema": {},
113
+ "outputSchema": {},
114
+ "policy": {
115
+ "type": "string",
116
+ "minLength": 1
117
+ },
118
+ "tenantScoped": {
119
+ "type": "boolean"
120
+ },
121
+ "transaction": {
122
+ "enum": [
123
+ "read-only",
124
+ "external-managed",
125
+ "forge-managed",
126
+ "saga"
127
+ ]
128
+ },
129
+ "risk": {
130
+ "enum": [
131
+ "read",
132
+ "write",
133
+ "destructive",
134
+ "external"
135
+ ]
136
+ },
137
+ "needsApproval": {
138
+ "type": "boolean"
139
+ },
140
+ "effects": {
141
+ "type": "array",
142
+ "items": {
143
+ "type": "string"
144
+ }
145
+ }
146
+ },
147
+ "additionalProperties": false
148
+ }
149
+ },
150
+ "schemas": {
151
+ "type": "object",
152
+ "additionalProperties": true
153
+ }
154
+ },
155
+ "additionalProperties": false
156
+ },
157
+ "repository": {
158
+ "type": "object",
159
+ "required": [
160
+ "forgeProtocol",
161
+ "kind",
162
+ "components"
163
+ ],
164
+ "additionalProperties": false,
165
+ "properties": {
166
+ "forgeProtocol": {
167
+ "const": "2.0"
168
+ },
169
+ "kind": {
170
+ "const": "repository"
171
+ },
172
+ "components": {
173
+ "type": "array",
174
+ "minItems": 1,
175
+ "maxItems": 1000,
176
+ "items": {
177
+ "type": "object",
178
+ "required": [
179
+ "id",
180
+ "root",
181
+ "adapters"
182
+ ],
183
+ "additionalProperties": false,
184
+ "properties": {
185
+ "id": {
186
+ "type": "string",
187
+ "pattern": "^[a-zA-Z0-9][a-zA-Z0-9._-]{0,79}$"
188
+ },
189
+ "root": {
190
+ "type": "string",
191
+ "minLength": 1,
192
+ "maxLength": 4096,
193
+ "pattern": "^(?!/)(?!.*[:\\u0000-\\u001f])(?!.*\\\\)(?!.*(?:^|/)\\.\\.(?:/|$)).+$"
194
+ },
195
+ "adapters": {
196
+ "type": "array",
197
+ "minItems": 1,
198
+ "uniqueItems": true,
199
+ "items": {
200
+ "enum": [
201
+ "typescript",
202
+ "javascript",
203
+ "vue",
204
+ "nuxt",
205
+ "java",
206
+ "spring",
207
+ "maven",
208
+ "gradle",
209
+ "docker"
210
+ ]
211
+ }
212
+ },
213
+ "files": {
214
+ "type": "array",
215
+ "maxItems": 1000,
216
+ "items": {
217
+ "type": "string",
218
+ "minLength": 1,
219
+ "maxLength": 4096,
220
+ "pattern": "^(?!/)(?!.*[:\\u0000-\\u001f])(?!.*\\\\)(?!.*(?:^|/)\\.\\.(?:/|$)).+$"
221
+ }
222
+ },
223
+ "analysis": {
224
+ "type": "object",
225
+ "additionalProperties": false,
226
+ "properties": {
227
+ "aliases": {
228
+ "type": "object", "maxProperties": 100,
229
+ "propertyNames": { "type": "string", "pattern": "^(?!__proto__$|prototype$|constructor$)(?!.*(?:^|/)\\.\\.(?:/|$))[A-Za-z_$@~][A-Za-z0-9_$@~./-]{0,127}$" },
230
+ "additionalProperties": { "$ref": "#/$defs/repositoryPath" }
231
+ },
232
+ "nuxt": {
233
+ "type": "object", "additionalProperties": false,
234
+ "properties": {
235
+ "rootDir": { "$ref": "#/$defs/repositoryPath" },
236
+ "srcDir": { "$ref": "#/$defs/repositoryPath" },
237
+ "components": { "type": "array", "maxItems": 100, "items": { "$ref": "#/$defs/repositoryPath" } },
238
+ "imports": { "type": "array", "maxItems": 100, "items": { "$ref": "#/$defs/repositoryPath" } }
239
+ }
240
+ }
241
+ }
242
+ }
243
+ }
244
+ }
245
+ },
246
+ "exclude": {
247
+ "type": "array",
248
+ "maxItems": 1000,
249
+ "items": {
250
+ "type": "string",
251
+ "minLength": 1,
252
+ "maxLength": 4096,
253
+ "pattern": "^(?!/)(?!.*[:\\u0000-\\u001f])(?!.*\\\\)(?!.*(?:^|/)\\.\\.(?:/|$)).+$"
254
+ }
255
+ },
256
+ "services": {
257
+ "type": "array",
258
+ "maxItems": 1000,
259
+ "items": {
260
+ "type": "string",
261
+ "minLength": 1,
262
+ "maxLength": 4096,
263
+ "pattern": "^(?!/)(?!.*[:\\u0000-\\u001f])(?!.*\\\\)(?!.*(?:^|/)\\.\\.(?:/|$)).+$"
264
+ }
265
+ },
266
+ "checks": {
267
+ "type": "array",
268
+ "maxItems": 1000,
269
+ "items": {
270
+ "type": "object",
271
+ "required": [
272
+ "id",
273
+ "component",
274
+ "argv"
275
+ ],
276
+ "additionalProperties": false,
277
+ "properties": {
278
+ "id": {
279
+ "type": "string",
280
+ "pattern": "^[a-zA-Z0-9][a-zA-Z0-9._-]{0,79}$"
281
+ },
282
+ "component": {
283
+ "type": "string",
284
+ "pattern": "^[a-zA-Z0-9][a-zA-Z0-9._-]{0,79}$"
285
+ },
286
+ "argv": {
287
+ "type": "array",
288
+ "minItems": 1,
289
+ "maxItems": 1000,
290
+ "items": {
291
+ "type": "string",
292
+ "minLength": 1,
293
+ "maxLength": 4096
294
+ }
295
+ },
296
+ "cwd": { "$ref": "#/$defs/repositoryPath" },
297
+ "files": { "type": "array", "maxItems": 1000, "items": { "$ref": "#/$defs/repositoryPath" } },
298
+ "category": { "enum": ["typecheck", "test", "lint", "build", "integration", "security", "other"] },
299
+ "cost": { "enum": ["low", "medium", "high"] },
300
+ "requires": {
301
+ "type": "array", "maxItems": 32, "uniqueItems": true,
302
+ "items": { "type": "string", "pattern": "^[a-zA-Z0-9][a-zA-Z0-9._-]{0,79}$" }
303
+ }
304
+ }
305
+ }
306
+ },
307
+ "httpClients": {
308
+ "type": "array", "maxItems": 1000,
309
+ "items": {
310
+ "type": "object", "additionalProperties": false,
311
+ "required": ["id", "component"],
312
+ "properties": {
313
+ "id": { "type": "string", "pattern": "^[A-Za-z_$][A-Za-z0-9_$.-]{0,79}$" },
314
+ "component": { "type": "string", "pattern": "^[a-zA-Z0-9][a-zA-Z0-9._-]{0,79}$" },
315
+ "apiComponent": { "type": "string", "pattern": "^[a-zA-Z0-9][a-zA-Z0-9._-]{0,79}$" },
316
+ "files": { "type": "array", "maxItems": 1000, "items": { "$ref": "#/$defs/repositoryPath" } },
317
+ "basePath": { "type": "string", "maxLength": 2048, "pattern": "^/(?!/)(?!.*(?:^|/)\\.\\.(?:/|$))[A-Za-z0-9_~!()*+,;=:@./-]*$" }
318
+ }
46
319
  }
47
320
  },
48
- "additionalProperties": false
49
- }
321
+ "runtime": {
322
+ "type": "object", "additionalProperties": false, "required": ["observations"],
323
+ "properties": { "observations": {
324
+ "type": "array", "minItems": 1, "maxItems": 32,
325
+ "items": {
326
+ "type": "object", "additionalProperties": false, "required": ["id", "component", "commands", "artifacts"],
327
+ "properties": {
328
+ "id": { "type": "string", "pattern": "^[a-zA-Z0-9][a-zA-Z0-9._-]{0,79}$" },
329
+ "component": { "type": "string", "pattern": "^[a-zA-Z0-9][a-zA-Z0-9._-]{0,79}$" },
330
+ "commands": { "type": "array", "minItems": 1, "maxItems": 16, "items": {
331
+ "type": "object", "additionalProperties": false, "required": ["argv"],
332
+ "properties": {
333
+ "argv": { "type": "array", "minItems": 1, "maxItems": 128, "items": { "type": "string", "minLength": 1, "maxLength": 4096, "pattern": "^[^\\u0000-\\u001f\\u007f]+$" } },
334
+ "cwd": { "$ref": "#/$defs/repositoryPath" },
335
+ "timeoutMs": { "type": "integer", "minimum": 100, "maximum": 120000 }
336
+ }
337
+ } },
338
+ "artifacts": { "type": "array", "minItems": 1, "maxItems": 32, "items": {
339
+ "type": "object", "additionalProperties": false, "required": ["path", "format"],
340
+ "properties": {
341
+ "path": { "$ref": "#/$defs/repositoryPath" },
342
+ "format": { "enum": ["nuxt-components", "nuxt-imports", "spring-mappings", "spring-beans", "docker-inspect", "http-trace", "forge-runtime"] }
343
+ }
344
+ } }
345
+ }
346
+ }
347
+ } }
348
+ },
349
+ "scenario": {
350
+ "type": "object",
351
+ "additionalProperties": false,
352
+ "properties": {
353
+ "id": {
354
+ "type": "string",
355
+ "pattern": "^[a-zA-Z0-9][a-zA-Z0-9._-]{0,79}$"
356
+ },
357
+ "mode": {
358
+ "type": "string",
359
+ "pattern": "^[a-zA-Z0-9][a-zA-Z0-9._-]{0,79}$"
360
+ },
361
+ "profiles": {
362
+ "type": "array",
363
+ "maxItems": 1000,
364
+ "items": {
365
+ "type": "string",
366
+ "minLength": 1,
367
+ "maxLength": 4096
368
+ }
369
+ },
370
+ "composeFiles": {
371
+ "type": "array",
372
+ "maxItems": 1000,
373
+ "items": {
374
+ "type": "string",
375
+ "minLength": 1,
376
+ "maxLength": 4096,
377
+ "pattern": "^(?!/)(?!.*[:\\u0000-\\u001f])(?!.*\\\\)(?!.*(?:^|/)\\.\\.(?:/|$)).+$"
378
+ }
379
+ }
380
+ }
381
+ }
382
+ }
50
383
  },
51
- "schemas": {
52
- "type": "object",
53
- "additionalProperties": true
384
+ "repositoryPath": {
385
+ "type": "string", "minLength": 1, "maxLength": 4096,
386
+ "pattern": "^(?!/)(?!.*[:\\u0000-\\u001f])(?!.*\\\\)(?!.*(?:^|/)\\.\\.(?:/|$)).+$"
54
387
  }
55
- },
56
- "additionalProperties": false
57
- }
388
+ }
389
+ }
@@ -1 +1 @@
1
- {"defaultProvider":"local","diagnostics":[],"env":{"deployEnv":"FORGE_DEPLOY_ENV","deployId":"FORGE_DEPLOY_ID","publicReleaseId":"NEXT_PUBLIC_FORGE_RELEASE_ID","releaseId":"FORGE_RELEASE_ID"},"gitSha":"unknown","optionalProviders":["local","sentry-compatible","sentry","glitchtip","bugsink","otel","custom"],"packageName":"forgeos","packageVersion":"0.1.0-alpha.68","releaseId":"forgeos@0.1.0-alpha.68+unknown","schemaVersion":"0.1.0"}
1
+ {"defaultProvider":"local","diagnostics":[],"env":{"deployEnv":"FORGE_DEPLOY_ENV","deployId":"FORGE_DEPLOY_ID","publicReleaseId":"NEXT_PUBLIC_FORGE_RELEASE_ID","releaseId":"FORGE_RELEASE_ID"},"gitSha":"unknown","optionalProviders":["local","sentry-compatible","sentry","glitchtip","bugsink","otel","custom"],"packageName":"forgeos","packageVersion":"0.1.0-alpha.69","releaseId":"forgeos@0.1.0-alpha.69+unknown","schemaVersion":"0.1.0"}
@@ -1,4 +1,4 @@
1
- // @forge-generated generator=0.1.0-alpha.68 input=eb85ce79777e8854119a312edd29262099578bdd5f8be82c03b5f0caae80f391 content=146d6370b923fb349aebc9c7cab538dab545ebbadccabe2f67f16e4018c91fb9
1
+ // @forge-generated generator=0.1.0-alpha.69 input=a62f6d9631d76e83840b1f77cac5b6c6e1f6da1acab63d41614e2fe47b9d5ca7 content=358bd274474845d7c2050f21c82cb785f59de808ecbe5c04b8c833969b3f1e10
2
2
  export const releaseManifest = {
3
3
  "defaultProvider": "local",
4
4
  "diagnostics": [],
@@ -19,7 +19,7 @@ export const releaseManifest = {
19
19
  "custom"
20
20
  ],
21
21
  "packageName": "forgeos",
22
- "packageVersion": "0.1.0-alpha.68",
23
- "releaseId": "forgeos@0.1.0-alpha.68+unknown",
22
+ "packageVersion": "0.1.0-alpha.69",
23
+ "releaseId": "forgeos@0.1.0-alpha.69+unknown",
24
24
  "schemaVersion": "0.1.0"
25
25
  } as const;
@@ -23,6 +23,7 @@ export interface ManagedStep {
23
23
  usage?: { input_tokens: number; cached_input_tokens: number; output_tokens: number };
24
24
  artifact?: import("./managed-workspace.ts").ManagedArtifact;
25
25
  environment?: import("./managed-environment.ts").ManagedEnvironment;
26
+ repositoryContext?: import("./repository-context.ts").FabricRepositoryContextMetadata;
26
27
  }
27
28
  export interface ManagedRunState {
28
29
  schemaVersion: 1; runId: string; repositoryRoot: string; ownerPid: number; version: number;
@@ -9,6 +9,7 @@ import {
9
9
  import { ManagedRunStore } from "./managed-run-store.ts";
10
10
  import { runCodexWorker, type CodexWorkerInput, type CodexWorkerOutput, codexWorkerEnvironment } from "./codex-sdk-worker.ts";
11
11
  import { prepareManagedEnvironment } from "./managed-environment.ts";
12
+ import { prepareFabricRepositoryContext } from "./repository-context.ts";
12
13
  import {
13
14
  captureManagedBase, prepareManagedWorkspace, captureManagedArtifact, publishManagedArtifacts,
14
15
  previewManagedArtifacts, confirmManagedPublication, confirmManagedBaseline, type ManagedArtifact,
@@ -298,9 +299,17 @@ export class ManagedRunService {
298
299
  if (this.closed || controller.signal.aborted) managedFail("AF_RUN_ABORTED", "Worker canceled during environment preparation");
299
300
  let report: ManagedStep["report"], usage: ManagedStep["usage"], threadId: string | undefined, outputDigest: string;
300
301
  if (executor.type === "codex") {
302
+ const repository = await prepareFabricRepositoryContext(state.repositoryRoot, prepared.directory, executor.prompt ?? state.spec.goal, executor.writeScope ?? state.spec.scope);
303
+ if (this.closed || controller.signal.aborted) managedFail("AF_RUN_ABORTED", "Worker canceled during repository analysis");
304
+ if (repository) await this.update(runId, current => {
305
+ const step = current.steps.find(item => item.attemptId === attemptId)!;
306
+ if (this.closed || controller.signal.aborted || step.status !== "running") return;
307
+ step.repositoryContext = repository.metadata;
308
+ event(current, "repository.context", `Repository maps ${repository.metadata.status} for prepared clone`, { nodeId, attemptId });
309
+ });
301
310
  const previous = [...state.steps].reverse().find(step => step.nodeId === nodeId && step.threadId);
302
311
  const output = await (this.options.worker ?? runCodexWorker)({ cwd: prepared.directory, role: executor.role!, model: executor.model, threadId: previous?.threadId, signal: controller.signal,
303
- prompt: `${executor.prompt}\n\nTask goal: ${state.spec.goal}\nYour current checkout: ${prepared.directory}\nActual input snapshot: ${prepared.inputDigest}\nWrite scope: ${JSON.stringify(executor.writeScope ?? [])}. Do not change files outside it. Do not commit, publish, deploy, install packages or send external messages. Dependencies already applied to this checkout. Reports from dependencies: ${JSON.stringify(applicableSteps(state).filter(step => state.workflow.nodes.find(node => node.nodeId === nodeId)!.dependsOn.includes(step.nodeId)).map(step => ({ nodeId: step.nodeId, summary: step.summary, report: step.report })))}\nCoordinator instructions for this attempt: ${state.instructions.join("\n")}`,
312
+ prompt: `${executor.prompt}\n\nTask goal: ${state.spec.goal}\nYour current checkout: ${prepared.directory}\nActual input snapshot: ${prepared.inputDigest}\nWrite scope: ${JSON.stringify(executor.writeScope ?? [])}. Do not change files outside it. Do not commit, publish, deploy, install packages or send external messages. Dependencies already applied to this checkout. Reports from dependencies: ${JSON.stringify(applicableSteps(state).filter(step => state.workflow.nodes.find(node => node.nodeId === nodeId)!.dependsOn.includes(step.nodeId)).map(step => ({ nodeId: step.nodeId, summary: step.summary, report: step.report })))}\nCoordinator instructions for this attempt: ${state.instructions.join("\n")}${repository ? `\n\n${repository.prompt}` : ""}`,
304
313
  onEvent: async notification => {
305
314
  if (this.closed || controller.signal.aborted) return;
306
315
  await this.update(runId, current => {
@@ -48,6 +48,26 @@ function validateState(state: ManagedRunState, root: string, runId: string) {
48
48
  managedId(step.attemptId, "attemptId"); managedId(step.nodeId, "nodeId");
49
49
  assert(["running", "succeeded", "failed", "uncertain"].includes(step.status) && state.workflow.runs.some(run => run.attemptId === step.attemptId && run.nodeId === step.nodeId && run.status === step.status), "Step attempt mismatch");
50
50
  assert(step.directory === undefined || (isAbsolute(step.directory) && resolve(step.directory) === step.directory), "Invalid workspace directory");
51
+ if (step.repositoryContext !== undefined) {
52
+ const context = step.repositoryContext;
53
+ assert(context && Object.keys(context).every(key => ["provider", "phase", "status", "sourceRoot", "cloneRoot", "snapshotId", "diagnostics", "quality", "runtime"].includes(key)), "Invalid repository context fields");
54
+ assert(context.provider === "repository" && context.phase === "prepared-input" && ["ready", "unavailable"].includes(context.status) && context.sourceRoot === root && context.cloneRoot === step.directory, "Repository context belongs to another checkout");
55
+ assert(Array.isArray(context.diagnostics) && context.diagnostics.length <= 20 && context.diagnostics.every(message => typeof message === "string" && message.length <= 512), "Invalid repository context diagnostics");
56
+ assert(context.snapshotId === undefined || (typeof context.snapshotId === "string" && context.snapshotId.length <= 256 && context.snapshotId.length > 0), "Invalid repository context snapshot");
57
+ assert(context.status !== "ready" || context.snapshotId !== undefined, "Ready repository context requires a snapshot");
58
+ if (context.runtime !== undefined) {
59
+ const runtime = context.runtime;
60
+ assert(runtime && Object.keys(runtime).every(key => ["reportId", "environmentId", "phase"].includes(key))
61
+ && context.status === "ready" && runtime.phase === "source-observed-matching-input"
62
+ && typeof runtime.reportId === "string" && runtime.reportId.length > 0 && runtime.reportId.length <= 128
63
+ && /^[a-zA-Z0-9][a-zA-Z0-9._-]{0,79}$/.test(runtime.environmentId), "Invalid runtime repository evidence metadata");
64
+ }
65
+ if (context.quality !== undefined) {
66
+ const quality = context.quality, counts = ["factsReused", "unresolvedLocalImports", "unresolvedUiReferences", "dynamicHttpCalls", "httpEndpointLinks", "analysisErrors"] as const;
67
+ assert(quality && Object.keys(quality).every(key => ["completeness", "runtimeObserved", ...counts].includes(key))
68
+ && quality.completeness === "partial" && quality.runtimeObserved === false && counts.every(key => Number.isSafeInteger(quality[key]) && quality[key] >= 0 && quality[key] <= 1_000_000), "Invalid static repository quality");
69
+ }
70
+ }
51
71
  }
52
72
  assert(Number.isSafeInteger(state.cursor) && state.cursor >= 0 && Array.isArray(state.events) && state.events.length <= 10000, "Invalid event history");
53
73
  let cursor = 0; for (const event of state.events) { assert(Number.isSafeInteger(event.cursor) && event.cursor > cursor && event.cursor <= state.cursor && typeof event.summary === "string" && typeof event.type === "string" && Number.isFinite(Date.parse(event.at)), "Invalid event"); cursor = event.cursor; }