create-agent-rig 0.9.1 → 0.10.1

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 (235) hide show
  1. package/CHANGELOG.md +462 -3
  2. package/README.md +267 -305
  3. package/package.json +8 -14
  4. package/packages/cli/dist/commands/create.js +56 -88
  5. package/packages/cli/dist/commands/doctor.js +213 -0
  6. package/packages/cli/dist/commands/init.js +111 -50
  7. package/packages/cli/dist/commands/integrations.js +468 -0
  8. package/packages/cli/dist/commands/setup-wizard.js +61 -0
  9. package/packages/cli/dist/commands/uninstall.js +1223 -0
  10. package/packages/cli/dist/commands/upgrade.js +508 -101
  11. package/packages/cli/dist/index.js +658 -47
  12. package/packages/cli/dist/integrations/declaration.js +158 -0
  13. package/packages/cli/dist/integrations/doctor-guards.js +126 -0
  14. package/packages/cli/dist/integrations/doctor-workflow.js +25 -0
  15. package/packages/cli/dist/integrations/mcp-json.js +107 -0
  16. package/packages/cli/dist/integrations/memory-doctor.js +124 -0
  17. package/packages/cli/dist/integrations/registry.js +22 -0
  18. package/packages/cli/dist/integrations/spawn.js +228 -0
  19. package/packages/cli/dist/integrations/spec-kit.js +280 -0
  20. package/packages/cli/dist/integrations/verify.js +193 -0
  21. package/packages/cli/dist/integrations/windows-job.js +275 -0
  22. package/packages/cli/dist/lib/elevated-paths.js +74 -0
  23. package/packages/cli/dist/lib/install-set.js +1 -44
  24. package/packages/cli/dist/lib/manifest.js +64 -5
  25. package/packages/cli/dist/lib/prompts.js +0 -23
  26. package/packages/cli/dist/lib/safe-path.js +193 -2
  27. package/packages/cli/dist/lib/safe-text.js +78 -0
  28. package/packages/cli/dist/lib/substitute.js +1 -52
  29. package/packages/cli/dist/lib/summary.js +5 -5
  30. package/packages/cli/dist/templates.js +4 -14
  31. package/scripts/prepare.mjs +28 -12
  32. package/templates/agent-os/subagent-routing.json +4 -4
  33. package/templates/agent-os/universal/.agents/skills/check-premises/SKILL.md +45 -12
  34. package/templates/agent-os/universal/.agents/skills/loop/SKILL.md +31 -6
  35. package/templates/agent-os/universal/.agents/skills/new-invariant/SKILL.md +5 -5
  36. package/templates/agent-os/universal/.agents/skills/pr-ship/SKILL.md +1 -1
  37. package/templates/agent-os/universal/.agents/skills/worktree-task/SKILL.md +3 -3
  38. package/templates/agent-os/universal/.claude/agents/code-reviewer.md +8 -6
  39. package/templates/agent-os/universal/.claude/agents/implementation-agent.md +41 -0
  40. package/templates/agent-os/universal/.claude/agents/prose-reviewer.md +8 -4
  41. package/templates/agent-os/universal/.claude/agents/security-scanner.md +4 -2
  42. package/templates/agent-os/universal/.claude/agents/test-writer.md +2 -2
  43. package/templates/agent-os/universal/.claude/hooks/gate-stop-dod.mjs +4 -2
  44. package/templates/agent-os/universal/.claude/hooks/inject-rules.mjs +83 -4
  45. package/templates/agent-os/universal/.claude/rules/autonomy.md +55 -27
  46. package/templates/agent-os/universal/.claude/rules/invariants.md +9 -8
  47. package/templates/agent-os/universal/.claude/rules/workflow.md +59 -22
  48. package/templates/agent-os/universal/.claude/scripts/decision-router.mjs +1 -1
  49. package/templates/agent-os/universal/.claude/scripts/detect-missed-gate.mjs +12 -9
  50. package/templates/agent-os/universal/.claude/scripts/doctor.mjs +100 -2
  51. package/templates/agent-os/universal/.claude/scripts/lib/claim-records.mjs +236 -6
  52. package/templates/agent-os/universal/.claude/scripts/queue/state.mjs +2 -2
  53. package/templates/agent-os/universal/.claude/scripts/reconcile-external-prs.mjs +4 -3
  54. package/templates/agent-os/universal/.claude/scripts/revalidate.mjs +16 -0
  55. package/templates/agent-os/universal/.claude/settings.json +0 -8
  56. package/templates/agent-os/universal/.claude/skills/check-premises/SKILL.md +45 -12
  57. package/templates/agent-os/universal/.claude/skills/loop/SKILL.md +31 -6
  58. package/templates/agent-os/universal/.claude/skills/new-invariant/SKILL.md +5 -5
  59. package/templates/agent-os/universal/.claude/skills/pr-ship/SKILL.md +1 -1
  60. package/templates/agent-os/universal/.claude/skills/worktree-task/SKILL.md +3 -3
  61. package/templates/agent-os/universal/.codex/agents/code-reviewer.toml +2 -2
  62. package/templates/agent-os/universal/.codex/agents/implementation-agent.toml +6 -0
  63. package/templates/agent-os/universal/.codex/agents/prose-reviewer.toml +2 -2
  64. package/templates/agent-os/universal/.codex/agents/security-scanner.toml +1 -1
  65. package/templates/agent-os/universal/.codex/agents/test-writer.toml +1 -1
  66. package/templates/agent-os/universal/.codex/hooks.json +0 -10
  67. package/templates/agent-os/universal/AGENTS.md +208 -107
  68. package/templates/agent-os/universal/CLAUDE.md +15 -162
  69. package/templates/agent-os/universal/PLAN.md +17 -10
  70. package/templates/agent-os/universal/docs/decisions/agents-md-canonical.md +313 -0
  71. package/templates/agent-os/universal/docs/decisions/codex-adapter.md +15 -10
  72. package/templates/agent-os/universal/docs/decisions/review-lanes.md +12 -8
  73. package/templates/agent-os/universal/docs/decisions/session-start-wire-format.md +206 -0
  74. package/templates/agent-os/universal/docs/decisions/subagent-routing.md +6 -3
  75. package/templates/agent-os/universal/docs/decisions/workflow-layer-split.md +235 -0
  76. package/templates/agent-os/universal/layers.json +25 -30
  77. package/templates/hash-history.json +112 -40
  78. package/templates/release-ledger.json +3 -1
  79. package/packages/cli/dist/lib/composition.js +0 -20
  80. package/packages/cli/dist/lib/targets.js +0 -28
  81. package/packages/cli/dist/policy/benchmark/corpus.js +0 -165
  82. package/packages/cli/dist/policy/core/adapter.js +0 -18
  83. package/packages/cli/dist/policy/core/coverage.js +0 -253
  84. package/packages/cli/dist/policy/core/decision-record.js +0 -287
  85. package/packages/cli/dist/policy/core/declaration.js +0 -127
  86. package/packages/cli/dist/policy/core/evidence-matrix.js +0 -94
  87. package/packages/cli/dist/policy/core/probe.js +0 -442
  88. package/packages/cli/dist/policy/core/registry.js +0 -115
  89. package/packages/cli/dist/policy/core/validation.js +0 -275
  90. package/packages/cli/dist/policy/core/vocabulary.js +0 -123
  91. package/packages/cli/dist/policy/harness/claude.js +0 -47
  92. package/packages/cli/dist/policy/harness/codex.js +0 -87
  93. package/packages/cli/dist/policy/harness/index.js +0 -15
  94. package/packages/cli/dist/policy/harness/shared-hooks.js +0 -28
  95. package/packages/cli/dist/policy/index.js +0 -17
  96. package/templates/agent-os/init/AGENTS.md +0 -201
  97. package/templates/agent-os/init/CLAUDE.md +0 -201
  98. package/templates/agent-os/stack/aws-cdk/.agents/skills/post-deploy-verify/SKILL.md +0 -105
  99. package/templates/agent-os/stack/aws-cdk/.agents/skills/ro-debug/SKILL.md +0 -117
  100. package/templates/agent-os/stack/aws-cdk/.claude/agents/cdk-diff-reviewer.md +0 -89
  101. package/templates/agent-os/stack/aws-cdk/.claude/rules/aws-cdk.md +0 -105
  102. package/templates/agent-os/stack/aws-cdk/.claude/skills/post-deploy-verify/SKILL.md +0 -105
  103. package/templates/agent-os/stack/aws-cdk/.claude/skills/ro-debug/SKILL.md +0 -117
  104. package/templates/agent-os/stack/aws-cdk/.codex/agents/cdk-diff-reviewer.toml +0 -6
  105. package/templates/agent-os/stack/node-ts/.claude/hooks/dod-checks.json +0 -1
  106. package/templates/agent-os/stack/node-ts/.claude/rules/node-ts.md +0 -85
  107. package/templates/agent-os/universal/.claude/hooks/guard-core-purity.mjs +0 -89
  108. package/templates/agent-os/universal/.claude/hooks/guard-web-boundary.mjs +0 -68
  109. package/templates/agent-os/universal/.claude/rules/architecture.md +0 -81
  110. package/templates/skeleton/aws-serverless/.github/workflows/ci.yml +0 -28
  111. package/templates/skeleton/aws-serverless/.github/workflows/deploy.yml +0 -90
  112. package/templates/skeleton/aws-serverless/README.md +0 -181
  113. package/templates/skeleton/aws-serverless/apps/web/next.config.mjs +0 -17
  114. package/templates/skeleton/aws-serverless/apps/web/package.json +0 -19
  115. package/templates/skeleton/aws-serverless/apps/web/src/app/layout.tsx +0 -17
  116. package/templates/skeleton/aws-serverless/apps/web/src/app/page.tsx +0 -96
  117. package/templates/skeleton/aws-serverless/apps/web/src/lib/api.ts +0 -36
  118. package/templates/skeleton/aws-serverless/apps/web/src/lib/validate.ts +0 -23
  119. package/templates/skeleton/aws-serverless/apps/web/test/shared-validation.test.ts +0 -38
  120. package/templates/skeleton/aws-serverless/apps/web/tsconfig.json +0 -14
  121. package/templates/skeleton/aws-serverless/eslint.config.mjs +0 -20
  122. package/templates/skeleton/aws-serverless/gitignore +0 -56
  123. package/templates/skeleton/aws-serverless/infra/bin/app.ts +0 -79
  124. package/templates/skeleton/aws-serverless/infra/cdk.json +0 -3
  125. package/templates/skeleton/aws-serverless/infra/lib/app-stack.ts +0 -248
  126. package/templates/skeleton/aws-serverless/infra/lib/web-stack.ts +0 -45
  127. package/templates/skeleton/aws-serverless/infra/package.json +0 -18
  128. package/templates/skeleton/aws-serverless/infra/test/allowed-origins.test.ts +0 -301
  129. package/templates/skeleton/aws-serverless/infra/test/app-composition.test.ts +0 -137
  130. package/templates/skeleton/aws-serverless/infra/test/app-stack.test.ts +0 -120
  131. package/templates/skeleton/aws-serverless/infra/test/web-stack.test.ts +0 -44
  132. package/templates/skeleton/aws-serverless/package.json +0 -30
  133. package/templates/skeleton/aws-serverless/packages/core/package.json +0 -11
  134. package/templates/skeleton/aws-serverless/packages/core/src/events.ts +0 -14
  135. package/templates/skeleton/aws-serverless/packages/core/src/index.ts +0 -15
  136. package/templates/skeleton/aws-serverless/packages/core/src/note.ts +0 -69
  137. package/templates/skeleton/aws-serverless/packages/core/test/events.test.ts +0 -23
  138. package/templates/skeleton/aws-serverless/packages/core/test/note.test.ts +0 -101
  139. package/templates/skeleton/aws-serverless/packages/db/package.json +0 -14
  140. package/templates/skeleton/aws-serverless/packages/db/src/client.ts +0 -17
  141. package/templates/skeleton/aws-serverless/packages/db/src/index.ts +0 -2
  142. package/templates/skeleton/aws-serverless/packages/db/src/note-model.ts +0 -52
  143. package/templates/skeleton/aws-serverless/packages/db/test/note-model.test.ts +0 -91
  144. package/templates/skeleton/aws-serverless/packages/shared/package.json +0 -11
  145. package/templates/skeleton/aws-serverless/packages/shared/src/env.ts +0 -17
  146. package/templates/skeleton/aws-serverless/packages/shared/src/errors.ts +0 -33
  147. package/templates/skeleton/aws-serverless/packages/shared/src/index.ts +0 -3
  148. package/templates/skeleton/aws-serverless/packages/shared/src/logger.ts +0 -20
  149. package/templates/skeleton/aws-serverless/packages/shared/test/env.test.ts +0 -26
  150. package/templates/skeleton/aws-serverless/packages/shared/test/errors.test.ts +0 -28
  151. package/templates/skeleton/aws-serverless/packages/shared/test/logger.test.ts +0 -19
  152. package/templates/skeleton/aws-serverless/pnpm-lock.yaml +0 -2855
  153. package/templates/skeleton/aws-serverless/pnpm-workspace.yaml +0 -14
  154. package/templates/skeleton/aws-serverless/services/api/package.json +0 -15
  155. package/templates/skeleton/aws-serverless/services/api/src/adapters/sqs-publisher.ts +0 -26
  156. package/templates/skeleton/aws-serverless/services/api/src/handlers/create-note.ts +0 -69
  157. package/templates/skeleton/aws-serverless/services/api/src/handlers/list-notes.ts +0 -37
  158. package/templates/skeleton/aws-serverless/services/api/src/list-main.ts +0 -12
  159. package/templates/skeleton/aws-serverless/services/api/src/main.ts +0 -21
  160. package/templates/skeleton/aws-serverless/services/api/src/usecases/create-note.ts +0 -41
  161. package/templates/skeleton/aws-serverless/services/api/src/usecases/list-notes.ts +0 -14
  162. package/templates/skeleton/aws-serverless/services/api/test/create-note.handler.test.ts +0 -211
  163. package/templates/skeleton/aws-serverless/services/api/test/create-note.usecase.test.ts +0 -45
  164. package/templates/skeleton/aws-serverless/services/api/test/list-notes.test.ts +0 -122
  165. package/templates/skeleton/aws-serverless/services/api/test/sqs-publisher.test.ts +0 -22
  166. package/templates/skeleton/aws-serverless/services/worker/package.json +0 -12
  167. package/templates/skeleton/aws-serverless/services/worker/src/handlers/note-created.ts +0 -15
  168. package/templates/skeleton/aws-serverless/services/worker/src/main.ts +0 -7
  169. package/templates/skeleton/aws-serverless/services/worker/src/usecases/process-note-created.ts +0 -37
  170. package/templates/skeleton/aws-serverless/services/worker/test/note-created.test.ts +0 -61
  171. package/templates/skeleton/aws-serverless/tsconfig.base.json +0 -15
  172. package/templates/skeleton/aws-serverless/tsconfig.json +0 -16
  173. package/templates/skeleton/aws-serverless/vitest.config.ts +0 -14
  174. package/templates/skeleton/node-service/.github/workflows/ci.yml +0 -27
  175. package/templates/skeleton/node-service/.github/workflows/deploy.yml +0 -29
  176. package/templates/skeleton/node-service/README.md +0 -104
  177. package/templates/skeleton/node-service/apps/web/next.config.mjs +0 -17
  178. package/templates/skeleton/node-service/apps/web/package.json +0 -19
  179. package/templates/skeleton/node-service/apps/web/src/app/layout.tsx +0 -17
  180. package/templates/skeleton/node-service/apps/web/src/app/page.tsx +0 -96
  181. package/templates/skeleton/node-service/apps/web/src/lib/api.ts +0 -29
  182. package/templates/skeleton/node-service/apps/web/src/lib/validate.ts +0 -23
  183. package/templates/skeleton/node-service/apps/web/test/shared-validation.test.ts +0 -38
  184. package/templates/skeleton/node-service/apps/web/tsconfig.json +0 -14
  185. package/templates/skeleton/node-service/eslint.config.mjs +0 -20
  186. package/templates/skeleton/node-service/gitignore +0 -54
  187. package/templates/skeleton/node-service/package.json +0 -30
  188. package/templates/skeleton/node-service/packages/core/package.json +0 -11
  189. package/templates/skeleton/node-service/packages/core/src/events.ts +0 -14
  190. package/templates/skeleton/node-service/packages/core/src/index.ts +0 -15
  191. package/templates/skeleton/node-service/packages/core/src/note.ts +0 -69
  192. package/templates/skeleton/node-service/packages/core/test/events.test.ts +0 -23
  193. package/templates/skeleton/node-service/packages/core/test/note.test.ts +0 -101
  194. package/templates/skeleton/node-service/packages/db/package.json +0 -12
  195. package/templates/skeleton/node-service/packages/db/src/index.ts +0 -1
  196. package/templates/skeleton/node-service/packages/db/src/note-store.ts +0 -100
  197. package/templates/skeleton/node-service/packages/db/test/note-store.test.ts +0 -100
  198. package/templates/skeleton/node-service/packages/shared/package.json +0 -11
  199. package/templates/skeleton/node-service/packages/shared/src/env.ts +0 -17
  200. package/templates/skeleton/node-service/packages/shared/src/errors.ts +0 -33
  201. package/templates/skeleton/node-service/packages/shared/src/index.ts +0 -3
  202. package/templates/skeleton/node-service/packages/shared/src/logger.ts +0 -20
  203. package/templates/skeleton/node-service/packages/shared/test/env.test.ts +0 -26
  204. package/templates/skeleton/node-service/packages/shared/test/errors.test.ts +0 -28
  205. package/templates/skeleton/node-service/packages/shared/test/logger.test.ts +0 -19
  206. package/templates/skeleton/node-service/pnpm-lock.yaml +0 -2402
  207. package/templates/skeleton/node-service/pnpm-workspace.yaml +0 -13
  208. package/templates/skeleton/node-service/scripts/build-artifact.mjs +0 -34
  209. package/templates/skeleton/node-service/services/api/package.json +0 -17
  210. package/templates/skeleton/node-service/services/api/src/adapters/spool-publisher.ts +0 -23
  211. package/templates/skeleton/node-service/services/api/src/handlers/create-note.ts +0 -40
  212. package/templates/skeleton/node-service/services/api/src/handlers/list-notes.ts +0 -23
  213. package/templates/skeleton/node-service/services/api/src/main.ts +0 -40
  214. package/templates/skeleton/node-service/services/api/src/server.ts +0 -172
  215. package/templates/skeleton/node-service/services/api/src/static-dir.ts +0 -20
  216. package/templates/skeleton/node-service/services/api/src/usecases/create-note.ts +0 -30
  217. package/templates/skeleton/node-service/services/api/src/usecases/list-notes.ts +0 -14
  218. package/templates/skeleton/node-service/services/api/test/artifact.test.ts +0 -92
  219. package/templates/skeleton/node-service/services/api/test/create-note.handler.test.ts +0 -64
  220. package/templates/skeleton/node-service/services/api/test/create-note.usecase.test.ts +0 -43
  221. package/templates/skeleton/node-service/services/api/test/list-notes.test.ts +0 -48
  222. package/templates/skeleton/node-service/services/api/test/package-manager.test.ts +0 -40
  223. package/templates/skeleton/node-service/services/api/test/package-manager.ts +0 -51
  224. package/templates/skeleton/node-service/services/api/test/server.test.ts +0 -208
  225. package/templates/skeleton/node-service/services/api/test/spool-publisher.test.ts +0 -32
  226. package/templates/skeleton/node-service/services/api/test/static-dir.test.ts +0 -29
  227. package/templates/skeleton/node-service/services/worker/package.json +0 -16
  228. package/templates/skeleton/node-service/services/worker/src/main.ts +0 -28
  229. package/templates/skeleton/node-service/services/worker/src/spool.ts +0 -60
  230. package/templates/skeleton/node-service/services/worker/src/usecases/process-note-created.ts +0 -38
  231. package/templates/skeleton/node-service/services/worker/test/process-note-created.test.ts +0 -34
  232. package/templates/skeleton/node-service/services/worker/test/spool.test.ts +0 -76
  233. package/templates/skeleton/node-service/tsconfig.base.json +0 -15
  234. package/templates/skeleton/node-service/tsconfig.json +0 -13
  235. package/templates/skeleton/node-service/vitest.config.ts +0 -12
@@ -0,0 +1,193 @@
1
+ import { createHash } from 'node:crypto';
2
+ import { constants } from 'node:fs';
3
+ import { access, open, stat } from 'node:fs/promises';
4
+ import path from 'node:path';
5
+ import { DECLARATION_REL, MAX_DECLARATION_BYTES, parseDeclaration } from './declaration.js';
6
+ import { readMcpConfig } from './mcp-json.js';
7
+ import { REGISTRY } from './registry.js';
8
+ import { resolveReadableInside } from '../lib/safe-path.js';
9
+ const MCP_REL = '.mcp.json';
10
+ const CODEX_REL = '.codex/config.toml';
11
+ const MAX_WIRING_BYTES = 64 * 1024;
12
+ function sha256(value) {
13
+ const input = Buffer.isBuffer(value) ? value : JSON.stringify(value);
14
+ return createHash('sha256').update(input).digest('hex');
15
+ }
16
+ /** Read only regular, in-repository files and cap every allocation before I/O. */
17
+ export async function readBounded(repoDir, rel, max) {
18
+ const resolved = await resolveReadableInside(repoDir, rel, 'file');
19
+ if (resolved.status === 'absent')
20
+ return { status: 'absent' };
21
+ if (resolved.status !== 'ok')
22
+ return { status: 'unsafe' };
23
+ const flags = constants.O_RDONLY |
24
+ (process.platform === 'win32' ? 0 : constants.O_NOFOLLOW | constants.O_NONBLOCK);
25
+ let handle;
26
+ try {
27
+ handle = await open(resolved.path, flags);
28
+ }
29
+ catch {
30
+ return { status: 'unsafe' };
31
+ }
32
+ try {
33
+ const info = await handle.stat();
34
+ if (!info.isFile())
35
+ return { status: 'unsafe' };
36
+ if (info.size > max)
37
+ return { status: 'too-large' };
38
+ const bytes = Buffer.alloc(max + 1);
39
+ let offset = 0;
40
+ while (offset < bytes.length) {
41
+ const { bytesRead } = await handle.read(bytes, offset, bytes.length - offset, null);
42
+ if (bytesRead === 0)
43
+ break;
44
+ offset += bytesRead;
45
+ }
46
+ if (offset > max)
47
+ return { status: 'too-large' };
48
+ return { status: 'ok', bytes: bytes.subarray(0, offset) };
49
+ }
50
+ catch {
51
+ return { status: 'unsafe' };
52
+ }
53
+ finally {
54
+ await handle.close().catch(() => undefined);
55
+ }
56
+ }
57
+ function decode(bytes) {
58
+ try {
59
+ return new TextDecoder('utf-8', { fatal: true, ignoreBOM: true }).decode(bytes);
60
+ }
61
+ catch {
62
+ return null;
63
+ }
64
+ }
65
+ async function defaultLocateLauncher(name, env = process.env) {
66
+ const variable = env.PATH ?? env.Path;
67
+ if (variable === undefined)
68
+ return null;
69
+ for (const directory of variable.split(path.delimiter)) {
70
+ if (!path.isAbsolute(directory))
71
+ continue;
72
+ const candidate = path.join(directory, process.platform === 'win32' ? `${name}.exe` : name);
73
+ try {
74
+ // Follow a machine-installed launcher symlink, but never execute it.
75
+ if (!(await stat(candidate)).isFile())
76
+ continue;
77
+ await access(candidate, process.platform === 'win32' ? constants.F_OK : constants.X_OK);
78
+ return candidate;
79
+ }
80
+ catch {
81
+ // A PATH member not present on this machine is not a diagnostic failure.
82
+ }
83
+ }
84
+ return null;
85
+ }
86
+ function verification(wiring, launcher) {
87
+ return {
88
+ wiring,
89
+ launcher,
90
+ runtime: 'unverified',
91
+ connectivity: 'not-observed',
92
+ trust: 'not-observed',
93
+ };
94
+ }
95
+ function mcpServerName(id) {
96
+ if (id === 'figma-mcp')
97
+ return 'figma';
98
+ if (id === 'atlassian-mcp')
99
+ return 'atlassian';
100
+ if (id === 'basic-memory')
101
+ return 'basic-memory';
102
+ return undefined;
103
+ }
104
+ /**
105
+ * Pure doctor surface for Rig-owned wiring. It deliberately neither starts a
106
+ * launcher nor connects to a provider, so launcher presence is only observed
107
+ * and provider runtime/connectivity/trust remain unverified.
108
+ */
109
+ export async function verifyIntegrations(options) {
110
+ const declaration = await readBounded(options.repoDir, DECLARATION_REL, MAX_DECLARATION_BYTES);
111
+ if (declaration.status === 'absent')
112
+ return { integrations: [], issues: [{ scope: 'declaration', status: 'missing' }] };
113
+ if (declaration.status !== 'ok')
114
+ return { integrations: [], issues: [{ scope: 'declaration', status: 'invalid' }] };
115
+ const declarationText = decode(declaration.bytes);
116
+ if (declarationText === null)
117
+ return { integrations: [], issues: [{ scope: 'declaration', status: 'invalid' }] };
118
+ const parsed = parseDeclaration(declarationText, REGISTRY);
119
+ if (parsed.status === 'invalid')
120
+ return { integrations: [], issues: [{ scope: 'declaration', status: 'invalid' }] };
121
+ const issues = parsed.rejected.map(({ reason }) => ({
122
+ scope: 'integration',
123
+ status: 'rejected',
124
+ reason,
125
+ }));
126
+ const claudeFile = await readBounded(options.repoDir, MCP_REL, MAX_WIRING_BYTES);
127
+ let claudeServers;
128
+ if (claudeFile.status === 'ok') {
129
+ const text = decode(claudeFile.bytes);
130
+ if (text !== null) {
131
+ try {
132
+ claudeServers = readMcpConfig(text).mcpServers;
133
+ }
134
+ catch {
135
+ // The status below reports drift without echoing untrusted JSON.
136
+ }
137
+ }
138
+ }
139
+ const codexFile = await readBounded(options.repoDir, CODEX_REL, MAX_WIRING_BYTES);
140
+ const codexHash = codexFile.status === 'ok' ? sha256(codexFile.bytes) : undefined;
141
+ const locator = options.locateLauncher ?? ((name) => defaultLocateLauncher(name, options.env));
142
+ const integrations = [];
143
+ for (const entry of parsed.entries) {
144
+ const harnesses = {};
145
+ for (const harness of entry.harnesses ?? []) {
146
+ if (harness === 'claude-code') {
147
+ const entryHash = entry.targets?.['claude-code']?.entryHash;
148
+ const name = mcpServerName(entry.id);
149
+ let wiring;
150
+ if (entryHash === undefined)
151
+ wiring = 'unowned';
152
+ else if (claudeFile.status === 'absent')
153
+ wiring = 'missing';
154
+ else if (claudeServers === undefined)
155
+ wiring = 'unreadable';
156
+ else if (name === undefined)
157
+ wiring = 'unowned';
158
+ else if (!(name in claudeServers))
159
+ wiring = 'missing';
160
+ else
161
+ wiring = sha256(claudeServers[name]) === entryHash ? 'healthy' : 'drift';
162
+ let launcher = 'not-applicable';
163
+ if (entry.id === 'basic-memory' && wiring === 'healthy')
164
+ launcher = (await locator('uvx')) === null ? 'missing' : 'observed';
165
+ harnesses[harness] = verification(wiring, launcher);
166
+ if (wiring === 'unreadable')
167
+ harnesses[harness].reason =
168
+ claudeFile.status === 'ok' ? 'invalid-config' : 'unsafe-or-too-large';
169
+ continue;
170
+ }
171
+ const expectedHash = parsed.targets?.codex?.fileHash;
172
+ const wiring = expectedHash === undefined
173
+ ? 'unowned'
174
+ : codexFile.status === 'absent'
175
+ ? 'missing'
176
+ : codexFile.status !== 'ok'
177
+ ? 'unreadable'
178
+ : codexHash === expectedHash
179
+ ? 'healthy'
180
+ : 'drift';
181
+ const launcher = entry.id === 'basic-memory' && wiring === 'healthy'
182
+ ? (await locator('uvx')) === null
183
+ ? 'missing'
184
+ : 'observed'
185
+ : 'not-applicable';
186
+ harnesses[harness] = verification(wiring, launcher);
187
+ if (wiring === 'unreadable')
188
+ harnesses[harness].reason = 'unsafe-or-too-large';
189
+ }
190
+ integrations.push({ id: entry.id, harnesses });
191
+ }
192
+ return { integrations, issues };
193
+ }
@@ -0,0 +1,275 @@
1
+ // Fixed Windows-only supervisor. The payload is constructed by a compiled
2
+ // adapter; repository declarations never reach this script as executable code.
3
+ export const WINDOWS_JOB_SUPERVISOR = String.raw `
4
+ $ErrorActionPreference = 'Stop'
5
+ $source = @'
6
+ using System;
7
+ using System.ComponentModel;
8
+ using System.Runtime.InteropServices;
9
+ using System.Text;
10
+ using System.Threading;
11
+
12
+ public static class RigJob
13
+ {
14
+ const uint EXTENDED_STARTUPINFO_PRESENT = 0x00080000;
15
+ const uint JOB_OBJECT_LIMIT_KILL_ON_JOB_CLOSE = 0x00002000;
16
+ const int JobObjectExtendedLimitInformation = 9;
17
+ const int JobObjectBasicAccountingInformation = 1;
18
+ const int JobObjectAssociateCompletionPortInformation = 7;
19
+ static readonly IntPtr PROC_THREAD_ATTRIBUTE_JOB_LIST = (IntPtr)0x0002000D;
20
+ const uint INFINITE = 0xffffffff;
21
+ const uint JOB_OBJECT_MSG_NEW_PROCESS = 6;
22
+ const uint JOB_OBJECT_MSG_EXIT_PROCESS = 7;
23
+ const uint JOB_OBJECT_MSG_ABNORMAL_EXIT_PROCESS = 8;
24
+
25
+ [StructLayout(LayoutKind.Sequential, CharSet = CharSet.Unicode)]
26
+ struct STARTUPINFO
27
+ {
28
+ public int cb;
29
+ public string lpReserved, lpDesktop, lpTitle;
30
+ public int dwX, dwY, dwXSize, dwYSize, dwXCountChars, dwYCountChars, dwFillAttribute, dwFlags;
31
+ public short wShowWindow, cbReserved2;
32
+ public IntPtr lpReserved2, hStdInput, hStdOutput, hStdError;
33
+ }
34
+
35
+ [StructLayout(LayoutKind.Sequential)]
36
+ struct STARTUPINFOEX
37
+ {
38
+ public STARTUPINFO StartupInfo;
39
+ public IntPtr lpAttributeList;
40
+ }
41
+
42
+ [StructLayout(LayoutKind.Sequential)]
43
+ struct PROCESS_INFORMATION
44
+ {
45
+ public IntPtr hProcess, hThread;
46
+ public int dwProcessId, dwThreadId;
47
+ }
48
+
49
+ [StructLayout(LayoutKind.Sequential)]
50
+ struct JOBOBJECT_BASIC_LIMIT_INFORMATION
51
+ {
52
+ public long PerProcessUserTimeLimit, PerJobUserTimeLimit;
53
+ public uint LimitFlags;
54
+ public UIntPtr MinimumWorkingSetSize, MaximumWorkingSetSize;
55
+ public uint ActiveProcessLimit;
56
+ public IntPtr Affinity;
57
+ public uint PriorityClass, SchedulingClass;
58
+ }
59
+
60
+ [StructLayout(LayoutKind.Sequential)]
61
+ struct IO_COUNTERS
62
+ {
63
+ public ulong ReadOperationCount, WriteOperationCount, OtherOperationCount;
64
+ public ulong ReadTransferCount, WriteTransferCount, OtherTransferCount;
65
+ }
66
+
67
+ [StructLayout(LayoutKind.Sequential)]
68
+ struct JOBOBJECT_EXTENDED_LIMIT_INFORMATION
69
+ {
70
+ public JOBOBJECT_BASIC_LIMIT_INFORMATION BasicLimitInformation;
71
+ public IO_COUNTERS IoInfo;
72
+ public UIntPtr ProcessMemoryLimit, JobMemoryLimit, PeakProcessMemoryUsed, PeakJobMemoryUsed;
73
+ }
74
+
75
+ [StructLayout(LayoutKind.Sequential)]
76
+ struct JOBOBJECT_BASIC_ACCOUNTING_INFORMATION
77
+ {
78
+ public long TotalUserTime, TotalKernelTime, ThisPeriodTotalUserTime, ThisPeriodTotalKernelTime;
79
+ public uint TotalPageFaultCount, TotalProcesses, ActiveProcesses, TotalTerminatedProcesses;
80
+ }
81
+
82
+ [StructLayout(LayoutKind.Sequential)]
83
+ struct JOBOBJECT_ASSOCIATE_COMPLETION_PORT
84
+ {
85
+ public IntPtr CompletionKey;
86
+ public IntPtr CompletionPort;
87
+ }
88
+
89
+ [DllImport("kernel32.dll", CharSet = CharSet.Unicode, SetLastError = true)]
90
+ static extern IntPtr CreateJobObject(IntPtr attributes, string name);
91
+ [DllImport("kernel32.dll", SetLastError = true)]
92
+ static extern bool SetInformationJobObject(IntPtr job, int infoClass, IntPtr info, int length);
93
+ [DllImport("kernel32.dll", SetLastError = true)]
94
+ static extern bool QueryInformationJobObject(IntPtr job, int infoClass,
95
+ out JOBOBJECT_BASIC_ACCOUNTING_INFORMATION info, int length, IntPtr returnLength);
96
+ [DllImport("kernel32.dll", SetLastError = true)]
97
+ static extern IntPtr CreateIoCompletionPort(IntPtr fileHandle, IntPtr existingPort,
98
+ IntPtr completionKey, uint threads);
99
+ [DllImport("kernel32.dll", SetLastError = true)]
100
+ static extern bool GetQueuedCompletionStatus(IntPtr port, out uint bytes,
101
+ out IntPtr completionKey, out IntPtr overlapped, uint milliseconds);
102
+ [DllImport("kernel32.dll", SetLastError = true)]
103
+ static extern bool InitializeProcThreadAttributeList(IntPtr list, int count, int flags, ref IntPtr size);
104
+ [DllImport("kernel32.dll")]
105
+ static extern void DeleteProcThreadAttributeList(IntPtr list);
106
+ [DllImport("kernel32.dll", SetLastError = true)]
107
+ static extern bool UpdateProcThreadAttribute(IntPtr list, uint flags, IntPtr attribute,
108
+ IntPtr value, IntPtr size, IntPtr previous, IntPtr returnSize);
109
+ [DllImport("kernel32.dll", CharSet = CharSet.Unicode, SetLastError = true)]
110
+ static extern bool CreateProcess(string application, StringBuilder commandLine,
111
+ IntPtr processAttributes, IntPtr threadAttributes, bool inheritHandles, uint flags,
112
+ IntPtr environment, string currentDirectory, ref STARTUPINFOEX startupInfo,
113
+ out PROCESS_INFORMATION processInformation);
114
+ [DllImport("kernel32.dll")]
115
+ static extern uint WaitForSingleObject(IntPtr handle, uint milliseconds);
116
+ [DllImport("kernel32.dll", SetLastError = true)]
117
+ static extern bool GetExitCodeProcess(IntPtr process, out uint exitCode);
118
+ [DllImport("kernel32.dll")]
119
+ static extern bool CloseHandle(IntPtr handle);
120
+
121
+ static void Check(bool value)
122
+ {
123
+ if (!value) throw new Win32Exception(Marshal.GetLastWin32Error());
124
+ }
125
+
126
+ public static string Quote(string value)
127
+ {
128
+ var result = new StringBuilder("\"");
129
+ int slashes = 0;
130
+ foreach (char character in value)
131
+ {
132
+ if (character == '\\') { slashes++; continue; }
133
+ result.Append('\\', character == '"' ? slashes * 2 + 1 : slashes);
134
+ result.Append(character);
135
+ slashes = 0;
136
+ }
137
+ result.Append('\\', slashes * 2);
138
+ result.Append('"');
139
+ return result.ToString();
140
+ }
141
+
142
+ static IntPtr CreateJob(IntPtr port)
143
+ {
144
+ IntPtr job = CreateJobObject(IntPtr.Zero, null);
145
+ if (job == IntPtr.Zero) throw new Win32Exception(Marshal.GetLastWin32Error());
146
+ var limits = new JOBOBJECT_EXTENDED_LIMIT_INFORMATION();
147
+ limits.BasicLimitInformation.LimitFlags = JOB_OBJECT_LIMIT_KILL_ON_JOB_CLOSE;
148
+ int size = Marshal.SizeOf(limits);
149
+ IntPtr buffer = Marshal.AllocHGlobal(size);
150
+ try
151
+ {
152
+ Marshal.StructureToPtr(limits, buffer, false);
153
+ Check(SetInformationJobObject(job, JobObjectExtendedLimitInformation, buffer, size));
154
+ var association = new JOBOBJECT_ASSOCIATE_COMPLETION_PORT();
155
+ association.CompletionKey = (IntPtr)1;
156
+ association.CompletionPort = port;
157
+ int associationSize = Marshal.SizeOf(association);
158
+ IntPtr associationBuffer = Marshal.AllocHGlobal(associationSize);
159
+ try
160
+ {
161
+ Marshal.StructureToPtr(association, associationBuffer, false);
162
+ Check(SetInformationJobObject(job, JobObjectAssociateCompletionPortInformation,
163
+ associationBuffer, associationSize));
164
+ }
165
+ finally { Marshal.FreeHGlobal(associationBuffer); }
166
+ return job;
167
+ }
168
+ catch
169
+ {
170
+ CloseHandle(job);
171
+ throw;
172
+ }
173
+ finally { Marshal.FreeHGlobal(buffer); }
174
+ }
175
+
176
+ static int DrainEvents(IntPtr port, int members)
177
+ {
178
+ uint message;
179
+ IntPtr key, process;
180
+ while (GetQueuedCompletionStatus(port, out message, out key, out process, 0))
181
+ {
182
+ if (message == JOB_OBJECT_MSG_NEW_PROCESS) members++;
183
+ if (message == JOB_OBJECT_MSG_EXIT_PROCESS ||
184
+ message == JOB_OBJECT_MSG_ABNORMAL_EXIT_PROCESS) members--;
185
+ }
186
+ return members;
187
+ }
188
+
189
+ // The JOB_LIST attribute is attached to CreateProcess itself, so there is
190
+ // no created-but-unassigned provider interval for a helper kill to expose.
191
+ static PROCESS_INFORMATION CreateInJob(IntPtr job, string executable, string command, string cwd)
192
+ {
193
+ IntPtr attributeList = IntPtr.Zero;
194
+ IntPtr jobList = IntPtr.Zero;
195
+ bool initialized = false;
196
+ try
197
+ {
198
+ IntPtr attributeBytes = IntPtr.Zero;
199
+ InitializeProcThreadAttributeList(IntPtr.Zero, 1, 0, ref attributeBytes);
200
+ if (attributeBytes == IntPtr.Zero) throw new Win32Exception(Marshal.GetLastWin32Error());
201
+ attributeList = Marshal.AllocHGlobal(attributeBytes);
202
+ Check(InitializeProcThreadAttributeList(attributeList, 1, 0, ref attributeBytes));
203
+ initialized = true;
204
+ jobList = Marshal.AllocHGlobal(IntPtr.Size);
205
+ Marshal.WriteIntPtr(jobList, job);
206
+ Check(UpdateProcThreadAttribute(attributeList, 0, PROC_THREAD_ATTRIBUTE_JOB_LIST,
207
+ jobList, (IntPtr)IntPtr.Size, IntPtr.Zero, IntPtr.Zero));
208
+ var startup = new STARTUPINFOEX();
209
+ startup.StartupInfo.cb = Marshal.SizeOf(typeof(STARTUPINFOEX));
210
+ startup.lpAttributeList = attributeList;
211
+ PROCESS_INFORMATION process;
212
+ Check(CreateProcess(executable, new StringBuilder(command), IntPtr.Zero, IntPtr.Zero,
213
+ true, EXTENDED_STARTUPINFO_PRESENT, IntPtr.Zero, cwd, ref startup, out process));
214
+ return process;
215
+ }
216
+ finally
217
+ {
218
+ if (initialized) DeleteProcThreadAttributeList(attributeList);
219
+ if (attributeList != IntPtr.Zero) Marshal.FreeHGlobal(attributeList);
220
+ if (jobList != IntPtr.Zero) Marshal.FreeHGlobal(jobList);
221
+ }
222
+ }
223
+
224
+ public static int Run(string executable, string command, string cwd)
225
+ {
226
+ IntPtr port = CreateIoCompletionPort((IntPtr)(-1), IntPtr.Zero, IntPtr.Zero, 1);
227
+ if (port == IntPtr.Zero) throw new Win32Exception(Marshal.GetLastWin32Error());
228
+ IntPtr job = IntPtr.Zero;
229
+ int members = 0;
230
+ try
231
+ {
232
+ job = CreateJob(port);
233
+ PROCESS_INFORMATION process = CreateInJob(job, executable, command, cwd);
234
+ try
235
+ {
236
+ WaitForSingleObject(process.hProcess, INFINITE);
237
+ members = DrainEvents(port, members);
238
+ uint exitCode;
239
+ Check(GetExitCodeProcess(process.hProcess, out exitCode));
240
+ JOBOBJECT_BASIC_ACCOUNTING_INFORMATION accounting;
241
+ do
242
+ {
243
+ Check(QueryInformationJobObject(job, JobObjectBasicAccountingInformation,
244
+ out accounting, Marshal.SizeOf(typeof(JOBOBJECT_BASIC_ACCOUNTING_INFORMATION)),
245
+ IntPtr.Zero));
246
+ if (accounting.ActiveProcesses != 0) Thread.Sleep(10);
247
+ } while (accounting.ActiveProcesses != 0);
248
+ // Give job notifications already queued by a just-exited root
249
+ // one bounded scheduling turn before accepting active-zero.
250
+ Thread.Sleep(20);
251
+ members = DrainEvents(port, members);
252
+ return members == 0 ? unchecked((int)exitCode) : 125;
253
+ }
254
+ finally
255
+ {
256
+ CloseHandle(process.hThread);
257
+ CloseHandle(process.hProcess);
258
+ }
259
+ }
260
+ finally
261
+ {
262
+ if (job != IntPtr.Zero) CloseHandle(job);
263
+ CloseHandle(port);
264
+ }
265
+ }
266
+ }
267
+ '@
268
+ Add-Type -TypeDefinition $source -Language CSharp
269
+ $payload = [Text.Encoding]::UTF8.GetString([Convert]::FromBase64String($env:RIG_WINDOWS_JOB_PAYLOAD)) | ConvertFrom-Json
270
+ $exe = [string]$payload.executable
271
+ $cwd = [string]$payload.cwd
272
+ $parts = @($payload.args | ForEach-Object { [RigJob]::Quote([string]$_) })
273
+ $command = ([RigJob]::Quote($exe)) + (($parts | ForEach-Object { ' ' + $_ }) -join '')
274
+ exit [RigJob]::Run($exe, $command, $cwd)
275
+ `;
@@ -0,0 +1,74 @@
1
+ /**
2
+ * Mirrors `parseElevatedPaths` in
3
+ * `templates/agent-os/universal/.claude/scripts/detect-missed-gate.mjs` —
4
+ * the gate sweep's own parser for the fenced ```elevated-paths block a
5
+ * rulebook file declares. Kept in step with it by a correspondence test
6
+ * (`packages/cli/test/elevated-paths-correspondence.test.ts`) that feeds the
7
+ * same literal fixtures to both and fails the moment they disagree, rather
8
+ * than by a shared import — the `.mjs` is the gate sweep's own copy, shipped
9
+ * into every generated rig, and this file is the generator's own, used only
10
+ * to DECIDE whether `upgrade` can trust an on-disk AGENTS.md as a rulebook
11
+ * (round 5, design ruling replacing round 4's verdict-only rule). Two
12
+ * different consumers, one semantics, proven equal rather than assumed so.
13
+ *
14
+ * Bounded, one forward pass: a hostile or merely enormous AGENTS.md cannot
15
+ * make this cost more than a fixed amount of work. The cap is applied BEFORE
16
+ * the regex ever runs, so the single `matchAll` pass is always over a string
17
+ * no longer than {@link ELEVATED_PATHS_SCAN_CAP}, never proportional to an
18
+ * attacker-chosen input size.
19
+ */
20
+ export const ELEVATED_PATHS_SCAN_CAP = 1_000_000;
21
+ /**
22
+ * Normalise a path so both sides of a comparison agree — identical to the
23
+ * `.mjs` sweep's own `normalizePath`, restated here because the correspondence
24
+ * test proves the two produce the same answer rather than sharing an import.
25
+ */
26
+ export function normalizeElevatedPath(path) {
27
+ return String(path ?? '')
28
+ .replace(/\\/g, '/')
29
+ .replace(/\/{2,}/g, '/')
30
+ .replace(/^\.\//, '')
31
+ .replace(/^\//, '');
32
+ }
33
+ /**
34
+ * Every declared path across every ```elevated-paths block in `markdown`, or
35
+ * `null` when there is no such block at all. An empty array (block present,
36
+ * nothing left after stripping comments and blank lines) is a real, distinct
37
+ * answer from `null` — round 5's own trigger: a hostile or stale
38
+ * `elevated-paths` block with only a comment ("Everything is Tier 0") parses
39
+ * to `[]`, and {@link isReadableRulebook} treats that exactly like no block
40
+ * at all, never like a real declaration.
41
+ *
42
+ * State limit, tested rather than merely claimed: content beyond
43
+ * {@link ELEVATED_PATHS_SCAN_CAP} characters is never read at all — a block
44
+ * that starts after the cap, or a path line that straddles it, is invisible
45
+ * to this function. `elevated-paths-correspondence.test.ts` pins this pair:
46
+ * a fixture within the cap agrees with the `.mjs` sweep (which has no cap),
47
+ * and the cap's own behaviour on an over-limit fixture is tested against
48
+ * this function alone, never against the `.mjs` (which would legitimately
49
+ * disagree there — the cap is this file's own limit, not a shared one).
50
+ */
51
+ export function parseElevatedPaths(markdown) {
52
+ const text = String(markdown ?? '');
53
+ const bounded = text.length > ELEVATED_PATHS_SCAN_CAP ? text.slice(0, ELEVATED_PATHS_SCAN_CAP) : text;
54
+ const blocks = [...bounded.matchAll(/```elevated-paths\r?\n([\s\S]*?)```/g)];
55
+ if (blocks.length === 0)
56
+ return null;
57
+ return blocks.flatMap((block) => (block[1] ?? '')
58
+ .split('\n')
59
+ // An inline comment after the path is a comment, not part of the path.
60
+ .map((line) => normalizeElevatedPath(line.replace(/\s+#.*$/, '').trim()))
61
+ .filter((line) => line.length > 0 && !line.startsWith('#')));
62
+ }
63
+ /**
64
+ * Round 5's content-based hold-back rule (replacing round 4's verdict-only
65
+ * rule): whether `content` can serve as the rulebook AGENTS.md is meant to
66
+ * be — at least one non-empty, non-comment path declared in a fenced
67
+ * ```elevated-paths block. Absence of the FILE is decided by the caller
68
+ * (`upgrade.ts`'s `deleted` verdict); this only ever judges bytes that are
69
+ * actually present.
70
+ */
71
+ export function isReadableRulebook(content) {
72
+ const parsed = parseElevatedPaths(content);
73
+ return parsed !== null && parsed.length > 0;
74
+ }
@@ -1,44 +1 @@
1
- import { readFile } from 'node:fs/promises';
2
- import { listTreeEntries, mapConcurrent } from './copy-tree.js';
3
- import { substituteContent, substituteFileName } from './substitute.js';
4
- import { agentOsStackDir, agentOsUniversalDir } from '../templates.js';
5
- /**
6
- * The agent-os layers of a target, in composition order. One definition, read
7
- * by `create` when it copies them and by `upgrade` when it refreshes them —
8
- * two lists would drift, and the one nobody looks at would be the wrong one.
9
- */
10
- export function agentOsLayerDirs(stacks) {
11
- return [
12
- { name: 'agent-os/universal', dir: agentOsUniversalDir() },
13
- ...stacks.map((stack) => ({ name: `agent-os/stack/${stack}`, dir: agentOsStackDir(stack) })),
14
- ];
15
- }
16
- /**
17
- * Exactly the agent-os bytes `create` writes, for a given target and project.
18
- *
19
- * The skeleton is deliberately absent: after generation the code is the user's
20
- * project, not the rig's — `upgrade` refreshes the process layer and nothing
21
- * else. Layers claim disjoint paths (`composition.ts` refuses otherwise), so
22
- * this is a plain concatenation.
23
- *
24
- * 🔴 Two assumptions, both load-bearing and both true today: the layer is all
25
- * **text** (this reads every file as UTF-8; a template test pins it for the
26
- * process half) and none of it is **executable** (`upgrade` writes with a bare
27
- * `writeFile` and does not carry the mode across the way `copyTree` does —
28
- * nothing in `templates/agent-os` currently has a mode to carry). Adding the
29
- * first binary asset or executable script here means teaching both.
30
- */
31
- export async function agentOsInstallSet(stacks, ctx) {
32
- const files = [];
33
- for (const layer of agentOsLayerDirs(stacks)) {
34
- const entries = await listTreeEntries(layer.dir, {
35
- transformName: (name) => substituteFileName(name, ctx),
36
- });
37
- files.push(...(await mapConcurrent(entries, 16, async (entry) => ({
38
- rel: entry.rel,
39
- source: entry.source,
40
- content: substituteContent(await readFile(entry.source, 'utf8'), ctx),
41
- }))));
42
- }
43
- return files;
44
- }
1
+ export {};