elanous 0.2.10 → 0.2.12
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.
- package/apps/pwa/out/404/index.html +1 -1
- package/apps/pwa/out/404.html +1 -1
- package/apps/pwa/out/_next/static/-6XrAoD3eU7NyMHAE4xPS/_buildManifest.js +1 -0
- package/apps/pwa/out/_next/static/chunks/1147-466ec15afacc1a65.js +1 -0
- package/apps/pwa/out/_next/static/chunks/1159-0c5ef8bc21cb6afb.js +1 -0
- package/apps/pwa/out/_next/static/chunks/1394-ee3795b112907122.js +1 -0
- package/apps/pwa/out/_next/static/chunks/1452.93700483b9d4fc61.js +9 -0
- package/apps/pwa/out/_next/static/chunks/{6062-73e68343a9814f6a.js → 1829-b453a1b22d3999bb.js} +1 -1
- package/apps/pwa/out/_next/static/chunks/2176-c379e3ebce874151.js +1 -0
- package/apps/pwa/out/_next/static/chunks/2426.8c6ee0c668d53def.js +1 -0
- package/apps/pwa/out/_next/static/chunks/3170-7ec60a56fa0e4728.js +1 -0
- package/apps/pwa/out/_next/static/chunks/3278-ae6ef084769f6195.js +1 -0
- package/apps/pwa/out/_next/static/chunks/3454-988a53dac60a1763.js +1 -0
- package/apps/pwa/out/_next/static/chunks/3638-aa80b4641ea439db.js +1 -0
- package/apps/pwa/out/_next/static/chunks/3735-fe3402553ac1c9c6.js +1 -0
- package/apps/pwa/out/_next/static/chunks/3869-3cd46526879f454c.js +1 -0
- package/apps/pwa/out/_next/static/chunks/390.c373e31b3b9d0c41.js +5 -0
- package/apps/pwa/out/_next/static/chunks/3992-2e522a8ac5f2afde.js +25 -0
- package/apps/pwa/out/_next/static/chunks/4215-c9d91dd644ec1719.js +1 -0
- package/apps/pwa/out/_next/static/chunks/4508-5d0161d1e724d735.js +1 -0
- package/apps/pwa/out/_next/static/chunks/4685-c3c1c625b71accd1.js +1 -0
- package/apps/pwa/out/_next/static/chunks/4733-623a79345b171e1c.js +1 -0
- package/apps/pwa/out/_next/static/chunks/4883.3bd969ea1d3aaaff.js +2 -0
- package/apps/pwa/out/_next/static/chunks/5532.6899a12958a89b72.js +1 -0
- package/apps/pwa/out/_next/static/chunks/{8067-87ce253ec2f23697.js → 5845-e6c003ce8d5fd36a.js} +1 -1
- package/apps/pwa/out/_next/static/chunks/5978-b27004c677119115.js +1 -0
- package/apps/pwa/out/_next/static/chunks/{8046cadf-211ca3c0e00f2b72.js → 5cd7e3a9-404fd6b8d0ecd44c.js} +1 -1
- package/apps/pwa/out/_next/static/chunks/6048-4c5c33579bc4ef78.js +1 -0
- package/apps/pwa/out/_next/static/chunks/6303-422dbf0f67c72aac.js +1 -0
- package/apps/pwa/out/_next/static/chunks/6751-bb3595948b2e311b.js +1 -0
- package/apps/pwa/out/_next/static/chunks/7274-19b7279f18b47ab3.js +1 -0
- package/apps/pwa/out/_next/static/chunks/7277-0b2fc7c16ba2d64b.js +1 -0
- package/apps/pwa/out/_next/static/chunks/{4323.c5dfb6f503304775.js → 7334.a6679d9168f37aa8.js} +1 -1
- package/apps/pwa/out/_next/static/chunks/7551-a0e0707b79164ddd.js +1 -0
- package/apps/pwa/out/_next/static/chunks/7758-0b018a9e4fc56200.js +1 -0
- package/apps/pwa/out/_next/static/chunks/7777-79f845045aa1ed86.js +1 -0
- package/apps/pwa/out/_next/static/chunks/79f8be9e-957d68913b590b08.js +1 -0
- package/apps/pwa/out/_next/static/chunks/8025-cc24ee5d8f2fb6f8.js +1 -0
- package/apps/pwa/out/_next/static/chunks/8039-df92e08fede5de8f.js +1 -0
- package/apps/pwa/out/_next/static/chunks/8206-c6684dcde12be721.js +1 -0
- package/apps/pwa/out/_next/static/chunks/8421-1c4acfb1395a0edf.js +1 -0
- package/apps/pwa/out/_next/static/chunks/8605-0259994816604c49.js +1 -0
- package/apps/pwa/out/_next/static/chunks/8725.bf46bb1395dd0fa2.js +1 -0
- package/apps/pwa/out/_next/static/chunks/8734-252d511cd276c0dc.js +1 -0
- package/apps/pwa/out/_next/static/chunks/8834-ca1cb09c1cb1a6bf.js +1 -0
- package/apps/pwa/out/_next/static/chunks/{2415.ed6428ff334c7ce2.js → 9269.d2a4795bc6812717.js} +1 -1
- package/apps/pwa/out/_next/static/chunks/9538-2816b90923606459.js +1 -0
- package/apps/pwa/out/_next/static/chunks/9656-c1540088f5859c80.js +1 -0
- package/apps/pwa/out/_next/static/chunks/9906-482c6619b3fdda20.js +1 -0
- package/apps/pwa/out/_next/static/chunks/9920-5cfdc5e8fd209825.js +1 -0
- package/apps/pwa/out/_next/static/chunks/app/_not-found/page-d16993889b125c42.js +1 -0
- package/apps/pwa/out/_next/static/chunks/app/approvals/page-cb169620945d1952.js +1 -0
- package/apps/pwa/out/_next/static/chunks/app/autopilot/page-cefe8169e36cf62a.js +1 -0
- package/apps/pwa/out/_next/static/chunks/app/board/page-d2e35228bc497119.js +1 -0
- package/apps/pwa/out/_next/static/chunks/app/botlab/{page-54b32bd27726588d.js → page-5c05b0da4bc1392c.js} +1 -1
- package/apps/pwa/out/_next/static/chunks/app/bots/page-e0ccdb576812b523.js +1 -0
- package/apps/pwa/out/_next/static/chunks/app/chat/page-813c4a52c9d05ca8.js +1 -0
- package/apps/pwa/out/_next/static/chunks/app/consult/page-4731f2c215358937.js +1 -0
- package/apps/pwa/out/_next/static/chunks/app/control/page-a022b257950f39e6.js +1 -0
- package/apps/pwa/out/_next/static/chunks/app/design-check/page-a2ffc717e04b8b0a.js +1 -0
- package/apps/pwa/out/_next/static/chunks/app/editor/page-b59ee4e70fc18fcf.js +1 -0
- package/apps/pwa/out/_next/static/chunks/app/exec/page-a67e11ba962337b5.js +1 -0
- package/apps/pwa/out/_next/static/chunks/app/field/page-c172dabd796eb7a3.js +1 -0
- package/apps/pwa/out/_next/static/chunks/app/healthz/route-d16993889b125c42.js +1 -0
- package/apps/pwa/out/_next/static/chunks/app/inside/page-1efd0cb9e0ed9d13.js +1 -0
- package/apps/pwa/out/_next/static/chunks/app/intake/page-d5dc7ff69a37b4cf.js +1 -0
- package/apps/pwa/out/_next/static/chunks/app/layout-e71c84189e8c683e.js +1 -0
- package/apps/pwa/out/_next/static/chunks/app/live/page-1d6a533ce5a6efcb.js +1 -0
- package/apps/pwa/out/_next/static/chunks/app/market/page-dfca9b7d2de0b135.js +1 -0
- package/apps/pwa/out/_next/static/chunks/app/missions/[id]/page-793fa536b3a6ef37.js +1 -0
- package/apps/pwa/out/_next/static/chunks/app/morning/page-6dd3bfbbde2a5c2c.js +1 -0
- package/apps/pwa/out/_next/static/chunks/app/not-found-490653e8d4cc8852.js +1 -0
- package/apps/pwa/out/_next/static/chunks/app/observatory/page-77447356baad75d2.js +1 -0
- package/apps/pwa/out/_next/static/chunks/app/ops/checklist/page-29e961191f6057df.js +1 -0
- package/apps/pwa/out/_next/static/chunks/app/ops/release/page-c822f55b884d9104.js +1 -0
- package/apps/pwa/out/_next/static/chunks/app/ops/seats/page-fa4ccfc432424e52.js +1 -0
- package/apps/pwa/out/_next/static/chunks/app/outputs/page-6d604227e1664b71.js +1 -0
- package/apps/pwa/out/_next/static/chunks/app/page-9c7e8f744a765daf.js +1 -0
- package/apps/pwa/out/_next/static/chunks/app/reflection/page-4048543b4b7ad5e0.js +1 -0
- package/apps/pwa/out/_next/static/chunks/app/scheduler/page-4c3a3126abed551a.js +1 -0
- package/apps/pwa/out/_next/static/chunks/app/sessions/page-64b0aecb1ca75e75.js +1 -0
- package/apps/pwa/out/_next/static/chunks/app/settings/devices/page-4292d0149020e8a7.js +1 -0
- package/apps/pwa/out/_next/static/chunks/app/settings/page-db14d0be7f1c460c.js +1 -0
- package/apps/pwa/out/_next/static/chunks/app/setup/done/page-e5d8072cd7cfef73.js +1 -0
- package/apps/pwa/out/_next/static/chunks/app/setup/layout-d16993889b125c42.js +1 -0
- package/apps/pwa/out/_next/static/chunks/app/setup/page-9547b5cec7cf76bf.js +1 -0
- package/apps/pwa/out/_next/static/chunks/app/share/page-e6dcb83265530636.js +1 -0
- package/apps/pwa/out/_next/static/chunks/app/showroom/page-45248f08d6aecae5.js +1 -0
- package/apps/pwa/out/_next/static/chunks/app/tasks/page-2cddeb9e2aeedc55.js +1 -0
- package/apps/pwa/out/_next/static/chunks/app/term/page-e297866051595d81.js +1 -0
- package/apps/pwa/out/_next/static/chunks/app/today/page-baba2e047872fb0f.js +1 -0
- package/apps/pwa/out/_next/static/chunks/app/trace/page-e895da4ec9cac345.js +1 -0
- package/apps/pwa/out/_next/static/chunks/app/vault/page-4344faf20216233b.js +1 -0
- package/apps/pwa/out/_next/static/chunks/app/workflows/chat-ui/page-698bb29f11864b89.js +1 -0
- package/apps/pwa/out/_next/static/chunks/app/workflows/page-bd6a6dc1ddc273f2.js +1 -0
- package/apps/pwa/out/_next/static/chunks/app/workspace/page-2e9e2fb01c9da1c9.js +1 -0
- package/apps/pwa/out/_next/static/chunks/app/worktrees/page-d62ceb13411ebba4.js +1 -0
- package/apps/pwa/out/_next/static/chunks/{2ea96958-e8c7e112de50b067.js → f48170cc-d05d28bf87a43bf4.js} +1 -1
- package/apps/pwa/out/_next/static/chunks/framework-172630e6aa5e2d7f.js +1 -0
- package/apps/pwa/out/_next/static/chunks/main-app-f0fe2d7477845181.js +1 -0
- package/apps/pwa/out/_next/static/chunks/main-fc98ac70b44eccb0.js +1 -0
- package/apps/pwa/out/_next/static/chunks/pages/_app-5bd7f10271f72413.js +1 -0
- package/apps/pwa/out/_next/static/chunks/pages/_error-97d0d85ea05fef9b.js +1 -0
- package/apps/pwa/out/_next/static/chunks/webpack-9e4d02d567b98240.js +1 -0
- package/apps/pwa/out/_next/static/css/128fb7fb670b2fbf.css +1 -0
- package/apps/pwa/out/approvals/index.html +1 -1
- package/apps/pwa/out/approvals/index.txt +23 -23
- package/apps/pwa/out/autopilot/index.html +1 -1
- package/apps/pwa/out/autopilot/index.txt +23 -23
- package/apps/pwa/out/board/index.html +1 -1
- package/apps/pwa/out/board/index.txt +23 -23
- package/apps/pwa/out/botlab/index.html +1 -1
- package/apps/pwa/out/botlab/index.txt +22 -22
- package/apps/pwa/out/bots/index.html +1 -1
- package/apps/pwa/out/bots/index.txt +22 -22
- package/apps/pwa/out/chat/index.html +1 -1
- package/apps/pwa/out/chat/index.txt +22 -22
- package/apps/pwa/out/consult/index.html +1 -1
- package/apps/pwa/out/consult/index.txt +23 -23
- package/apps/pwa/out/control/index.html +1 -1
- package/apps/pwa/out/control/index.txt +23 -23
- package/apps/pwa/out/design-check/index.html +1 -1
- package/apps/pwa/out/design-check/index.txt +23 -23
- package/apps/pwa/out/editor/index.html +1 -1
- package/apps/pwa/out/editor/index.txt +23 -23
- package/apps/pwa/out/exec/index.html +1 -1
- package/apps/pwa/out/exec/index.txt +23 -23
- package/apps/pwa/out/field/index.html +1 -1
- package/apps/pwa/out/field/index.txt +23 -23
- package/apps/pwa/out/healthz +1 -1
- package/apps/pwa/out/index.html +1 -1
- package/apps/pwa/out/index.txt +22 -22
- package/apps/pwa/out/inside/index.html +1 -0
- package/apps/pwa/out/inside/index.txt +31 -0
- package/apps/pwa/out/intake/index.html +1 -1
- package/apps/pwa/out/intake/index.txt +23 -23
- package/apps/pwa/out/live/index.html +1 -1
- package/apps/pwa/out/live/index.txt +23 -23
- package/apps/pwa/out/market/index.html +1 -1
- package/apps/pwa/out/market/index.txt +22 -22
- package/apps/pwa/out/missions/placeholder/index.html +1 -1
- package/apps/pwa/out/missions/placeholder/index.txt +22 -22
- package/apps/pwa/out/morning/index.html +1 -1
- package/apps/pwa/out/morning/index.txt +23 -23
- package/apps/pwa/out/observatory/index.html +1 -1
- package/apps/pwa/out/observatory/index.txt +23 -23
- package/apps/pwa/out/ops/checklist/index.html +1 -1
- package/apps/pwa/out/ops/checklist/index.txt +22 -22
- package/apps/pwa/out/ops/release/index.html +1 -1
- package/apps/pwa/out/ops/release/index.txt +22 -22
- package/apps/pwa/out/ops/seats/index.html +1 -1
- package/apps/pwa/out/ops/seats/index.txt +22 -22
- package/apps/pwa/out/outputs/index.html +1 -0
- package/apps/pwa/out/outputs/index.txt +30 -0
- package/apps/pwa/out/reflection/index.html +1 -1
- package/apps/pwa/out/reflection/index.txt +23 -23
- package/apps/pwa/out/scheduler/index.html +1 -1
- package/apps/pwa/out/scheduler/index.txt +23 -23
- package/apps/pwa/out/sessions/index.html +1 -1
- package/apps/pwa/out/sessions/index.txt +22 -22
- package/apps/pwa/out/settings/devices/index.html +1 -1
- package/apps/pwa/out/settings/devices/index.txt +23 -23
- package/apps/pwa/out/settings/index.html +1 -1
- package/apps/pwa/out/settings/index.txt +23 -23
- package/apps/pwa/out/setup/done/index.html +1 -1
- package/apps/pwa/out/setup/done/index.txt +23 -23
- package/apps/pwa/out/setup/index.html +1 -1
- package/apps/pwa/out/setup/index.txt +23 -23
- package/apps/pwa/out/share/index.html +1 -1
- package/apps/pwa/out/share/index.txt +23 -23
- package/apps/pwa/out/showroom/index.html +1 -1
- package/apps/pwa/out/showroom/index.txt +22 -22
- package/apps/pwa/out/tasks/index.html +1 -1
- package/apps/pwa/out/tasks/index.txt +23 -23
- package/apps/pwa/out/term/index.html +1 -1
- package/apps/pwa/out/term/index.txt +23 -24
- package/apps/pwa/out/today/index.html +1 -1
- package/apps/pwa/out/today/index.txt +23 -23
- package/apps/pwa/out/trace/index.html +1 -1
- package/apps/pwa/out/trace/index.txt +23 -23
- package/apps/pwa/out/vault/index.html +1 -1
- package/apps/pwa/out/vault/index.txt +23 -23
- package/apps/pwa/out/workflows/chat-ui/index.html +1 -1
- package/apps/pwa/out/workflows/chat-ui/index.txt +23 -23
- package/apps/pwa/out/workflows/index.html +1 -1
- package/apps/pwa/out/workflows/index.txt +23 -23
- package/apps/pwa/out/workspace/index.html +1 -1
- package/apps/pwa/out/workspace/index.txt +23 -24
- package/apps/pwa/out/worktrees/index.html +1 -1
- package/apps/pwa/out/worktrees/index.txt +23 -23
- package/graphs/context/nightly-condense.yaml +21 -0
- package/graphs/context/recipes.yaml +12 -0
- package/graphs/demo/inside-seed.yaml +20 -0
- package/graphs/demo/recipes.yaml +12 -0
- package/graphs/drafts/draft-cleanup.yaml +19 -0
- package/graphs/drafts/recipes.yaml +23 -0
- package/graphs/intake/intake-daily.yaml +2 -1
- package/graphs/ops/recipes.yaml +3 -0
- package/graphs/ops/secret-exposure.yaml +24 -0
- package/graphs/release/recipes.yaml +3 -0
- package/graphs/release/release-loop.yaml +4 -1
- package/graphs/video/explainer-line.yaml +2 -2
- package/package.json +2 -1
- package/plugins/card-followup/examples/sample-card.png +0 -0
- package/plugins/elanous-hwp/README.md +25 -0
- package/plugins/elanous-hwp/cli.ts +22 -0
- package/plugins/elanous-hwp/converter.ts +237 -0
- package/plugins/elanous-hwp/fixtures/fixed-controls.hwpx +0 -0
- package/plugins/elanous-hwp/fixtures/fixed-table-controls.hwpx +0 -0
- package/plugins/elanous-hwp/fixtures/fixed.hwpx +0 -0
- package/plugins/elanous-hwp/plugin.json +16 -0
- package/plugins/elanous-hwp/plugin.ts +40 -0
- package/scripts/ci-public-export-leak-gate.ts +75 -14
- package/scripts/ci-public-leak-gate.ts +44 -9
- package/scripts/context-hooks/claude-stop.sh +4 -0
- package/scripts/context-hooks/emit.ts +24 -0
- package/scripts/context-hooks/post-tool-use.sh +4 -0
- package/scripts/coord-channel-watch.sh +12 -0
- package/scripts/coord-requests-bridge.ts +143 -0
- package/scripts/field-feed/lib.ts +4 -0
- package/scripts/fleet/node-setup.sh +20 -3
- package/scripts/homebrew-formula-bump.ts +69 -0
- package/scripts/lib/telegram-inject-args.ts +31 -0
- package/scripts/marketing/measure-site-numbers.ts +169 -0
- package/scripts/measure-gate-shards.ts +309 -0
- package/scripts/measure-pod-memory-by-goal.ts +130 -0
- package/scripts/mission-request-judge.ts +31 -1
- package/scripts/morning-report.ts +2 -2
- package/scripts/opportunity-scan.ts +1 -1
- package/scripts/release-loop/auto-approve-node.ts +21 -4
- package/scripts/release-loop/checklist-gate-node.ts +2 -1
- package/scripts/release-loop/cut-branch.ts +84 -0
- package/scripts/release-loop/gate-node.ts +22 -15
- package/scripts/release-loop/mac-smoke-node.ts +229 -0
- package/scripts/release-loop/node-verdict.ts +3 -3
- package/scripts/release-loop/ops-upgrade-node.ts +47 -6
- package/scripts/release-loop/publish-node.ts +4 -1
- package/scripts/release-loop/tui-node-checks.ts +42 -0
- package/scripts/release-loop/tui-sim-node.ts +32 -8
- package/scripts/release-loop/unattended-release.ts +5 -3
- package/scripts/release-loop/version-node.ts +74 -13
- package/scripts/signal-digest-cycle.ts +2 -7
- package/scripts/signal-digest-photo.ts +11 -0
- package/scripts/tech1-public-measure.ts +94 -0
- package/scripts/telegram-inject.ts +14 -6
- package/scripts/test-diet/node.ts +1 -1
- package/scripts/test-diet/remeasure-list.ts +112 -0
- package/scripts/tui-regress.ts +2 -2
- package/scripts/ux/demo-rehearsal.ts +247 -0
- package/scripts/ux/demo-seed.ts +108 -0
- package/scripts/ux/lib/rehearsal-verdict.ts +80 -0
- package/skills/diagram-master/SKILL.md +366 -0
- package/skills/diagram-master/references/engines/excalidraw/color-palette.md +67 -0
- package/skills/diagram-master/references/engines/excalidraw/element-templates.md +182 -0
- package/skills/diagram-master/references/engines/excalidraw/json-schema.md +71 -0
- package/skills/diagram-master/references/engines/excalidraw/render_excalidraw.py +189 -0
- package/skills/diagram-master/references/engines/excalidraw/render_template.html +57 -0
- package/skills/diagram-master/references/engines/matplotlib/matplotlib-patterns.md +235 -0
- package/skills/diagram-master/references/engines/matplotlib/render_matplotlib.py +184 -0
- package/skills/diagram-master/references/engines/mermaid/domain-templates.md +435 -0
- package/skills/diagram-master/references/engines/mermaid/render_mermaid.py +116 -0
- package/skills/diagram-master/references/engines/mermaid/syntax-reference.md +2247 -0
- package/skills/diagram-master/references/engines/nanobannana/render_nanobannana2.py +168 -0
- package/skills/diagram-master/references/engines/svg/color-palette.md +188 -0
- package/skills/diagram-master/references/engines/svg/html-base-template.html +332 -0
- package/skills/diagram-master/references/engines/svg/interactivity-patterns.md +435 -0
- package/skills/diagram-master/references/engines/svg/render_interactive_svg.py +212 -0
- package/skills/diagram-master/references/engines/svg/svg-element-templates.md +349 -0
- package/skills/diagram-master/references/examples/README.md +69 -0
- package/skills/diagram-master/references/examples/ref_grid_architecture.png +0 -0
- package/skills/diagram-master/references/examples/ref_layered_flow.png +0 -0
- package/skills/diagram-master/references/pyproject.toml +16 -0
- package/skills/diagram-master/references/quality-checklist.md +33 -0
- package/skills/diagram-master/references/routing-guide.md +164 -0
- package/skills/diagram-master/references/uv.lock +1356 -0
- package/skills/google-workspace/SKILL.md +33 -0
- package/skills/google-workspace/scripts/gws-safe.sh +177 -0
- package/skills/grill-me/SKILL.md +1 -1
- package/skills/lecture-note-digitizer/SKILL.md +926 -0
- package/skills/lecture-note-digitizer/references/convert_to_pdf.py +30 -0
- package/skills/lecture-note-digitizer/references/extract_slide_diagram.py +73 -0
- package/skills/lecture-note-digitizer/references/html-template.md +167 -0
- package/skills/lecture-note-digitizer/references/katex-style-guide.md +165 -0
- package/skills/omni-crawl/SKILL.md +21 -11
- package/skills/omni-crawl/scripts/main.ts +6 -6
- package/skills/omni-crawl/src/router.ts +3 -3
- package/skills/omni-digest/SKILL.md +17 -9
- package/skills/omni-digest/digest.md +2 -2
- package/skills/omni-digest/src/fetch.ts +30 -3
- package/skills/pitch-deck/SKILL.md +2 -2
- package/skills/pitch-deck/template.html +2 -2
- package/skills/youtube-master/SKILL.md +163 -0
- package/skills/youtube-master/package-lock.json +558 -0
- package/skills/youtube-master/package.json +13 -0
- package/skills/youtube-master/references/study-note-template.md +124 -0
- package/skills/youtube-master/scripts/main.ts +435 -0
- package/skills/youtube-master/scripts/transcribe-local.ts +24 -0
- package/skills/youtube-master/src/audio.ts +63 -0
- package/skills/youtube-master/src/domain-staging.ts +50 -0
- package/skills/youtube-master/src/env.ts +36 -0
- package/skills/youtube-master/src/obsidian.ts +155 -0
- package/skills/youtube-master/src/router.ts +110 -0
- package/skills/youtube-master/src/stt.ts +199 -0
- package/skills/youtube-master/src/study-note.ts +175 -0
- package/skills/youtube-master/src/summarize.ts +358 -0
- package/skills/youtube-master/src/transcript.ts +76 -0
- package/skills/youtube-master/src/types.ts +91 -0
- package/skills/youtube-master/src/util.ts +93 -0
- package/skills/youtube-master/src/youtube.ts +70 -0
- package/skills/youtube-master/tsconfig.json +13 -0
- package/src/acp/server.ts +5 -2
- package/src/agent-mission/driver.ts +215 -23
- package/src/agent-mission/pty-decision.ts +71 -0
- package/src/agent-mission/review-loop.ts +30 -0
- package/src/autopilot/build/llm-conflict-merge.ts +16 -3
- package/src/autopilot/pty-control-loop.ts +4 -1
- package/src/autopilot/tool-registry.ts +2 -0
- package/src/boot/daemon-prompt-turn.ts +5 -0
- package/src/boot/daemon-runtime.ts +9 -3
- package/src/boot/daemon-tools/web-search.ts +3 -0
- package/src/card-followup/core.ts +109 -0
- package/src/chat/index.ts +2 -0
- package/src/cli/drive-input-jail.ts +101 -0
- package/src/cli/hooks-cli.ts +17 -3
- package/src/cli/make-cli.ts +43 -0
- package/src/cli/persona-cli.ts +98 -9
- package/src/cli/plugin-cli.ts +31 -22
- package/src/cli/pod-cli.ts +36 -9
- package/src/cli/pod-memory-advice.ts +35 -0
- package/src/cli/pr-cli.ts +51 -15
- package/src/cli/pty-drive-cli.ts +41 -7
- package/src/cli/pty-drive-verdict.ts +40 -0
- package/src/cli/release-cli.ts +63 -10
- package/src/cli/setup-cli.ts +43 -1
- package/src/cli/skills-cli.ts +17 -1
- package/src/context-bus/claude-hooks-install.ts +10 -0
- package/src/context-bus/context-now-surfaces.ts +65 -0
- package/src/context-bus/context-now.ts +104 -0
- package/src/context-bus/coord-events.ts +2 -2
- package/src/context-bus/external-events.ts +52 -0
- package/src/context-bus/long-term-memory.ts +108 -0
- package/src/context-bus/nightly-condense.ts +153 -0
- package/src/context-bus/session-events.ts +35 -0
- package/src/dashboard/dashboard-status-lines.ts +2 -0
- package/src/dashboard/index.ts +17 -4
- package/src/dashboard/slash-runtime/dashboard-handlers.ts +31 -1
- package/src/decisions/decision-cards.ts +10 -3
- package/src/decisions/decision-ledger.ts +13 -5
- package/src/discord/sprint21-runtime.ts +5 -1
- package/src/discord-self-message.ts +32 -0
- package/src/discord-slash-wire.ts +5 -1
- package/src/discord.ts +17 -1
- package/src/domains/core-tools.ts +3 -2
- package/src/domains/outbound-alert.ts +105 -32
- package/src/domains/outbound-log-probe.ts +8 -0
- package/src/domains/telegram-kind-route.ts +51 -13
- package/src/exec-requests/default-outputs.ts +25 -0
- package/src/exec-requests/planner.ts +10 -2
- package/src/exec-requests/runner.ts +20 -6
- package/src/exec-requests/store.ts +3 -0
- package/src/execution-loop/launch-gate.ts +109 -0
- package/src/field/field-reel.ts +5 -1
- package/src/field-note/index.ts +201 -0
- package/src/field-note/telegram.ts +142 -0
- package/src/field-note/transcribe.ts +248 -0
- package/src/graph-kinds/registry.ts +3 -3
- package/src/graph-runner/graph-cli.ts +61 -1
- package/src/graph-runner/graph-grow-llm.ts +47 -0
- package/src/graph-runner/graph-grow.ts +50 -0
- package/src/graph-runner/runner.ts +329 -33
- package/src/grok/agent-search.ts +8 -2
- package/src/guardian/secret-exposure-scan.ts +101 -0
- package/src/harness/harness-cli-command.ts +375 -13
- package/src/harness/harness-pod-dispatch.ts +43 -23
- package/src/harness/harness-seams.ts +38 -4
- package/src/harness/harness-stop.ts +23 -4
- package/src/harness/launch-registry.ts +91 -0
- package/src/harness/process-garbage.ts +5 -3
- package/src/hooks/consult-intake.ts +153 -0
- package/src/hooks/dispatch.ts +82 -0
- package/src/hooks/expose.ts +254 -0
- package/src/hooks/github-shadow.ts +108 -0
- package/src/hooks/providers.ts +71 -5
- package/src/hooks/queue.ts +1 -1
- package/src/hooks/receiver.ts +94 -16
- package/src/index.ts +76 -14
- package/src/intake-plane/categorize.ts +18 -46
- package/src/intake-plane/discord-seat-work.ts +38 -2
- package/src/intake-plane/front-route-classifier.ts +33 -39
- package/src/intake-plane/persona-answer.ts +30 -0
- package/src/intake-plane/runtime-callables.ts +8 -1
- package/src/intake-plane/telegram-seat-work.ts +36 -2
- package/src/intake-plane/wish-card.ts +33 -0
- package/src/intake-plane/wish-folder.ts +67 -0
- package/src/intent-gate/gate.ts +30 -10
- package/src/live/detail-switch.ts +5 -0
- package/src/llm/difficulty.ts +57 -0
- package/src/llm/judge-layer.ts +101 -0
- package/src/llm/mission-router.ts +33 -19
- package/src/loops/contract/examples/cmo-seat.loop.yaml +51 -0
- package/src/loops/contract/examples/orchestrator.loop.yaml +57 -0
- package/src/loops/contract/examples/steward.loop.yaml +50 -0
- package/src/loops/contract/loop-agent.schema.json +138 -0
- package/src/loops/contract/validate.ts +64 -0
- package/src/loops/registry.ts +20 -6
- package/src/market/signed-index.ts +4 -0
- package/src/maturity/bot-command-maturity.ts +45 -0
- package/src/maturity/feature-maturity.ts +27 -4
- package/src/model-tier/index.ts +2 -2
- package/src/model-tier/tier-resolver.ts +20 -20
- package/src/model-tier/types.ts +6 -6
- package/src/mss/logging/log-store.ts +15 -0
- package/src/nexus/api/config-model-tier.ts +5 -4
- package/src/nexus/api/fabric-plans.ts +53 -0
- package/src/nexus/api/harness-api.ts +5 -1
- package/src/nexus/api/health.ts +2 -0
- package/src/nexus/api/http-server.ts +67 -8
- package/src/nexus/api/inside-events.ts +226 -0
- package/src/nexus/api/meta-api.ts +21 -8
- package/src/nexus/api/missions.ts +6 -1
- package/src/nexus/api/ops-seats.ts +33 -0
- package/src/nexus/api/outbound-report.ts +40 -7
- package/src/nexus/api/outputs-route.ts +44 -0
- package/src/nexus/api/personas.ts +95 -53
- package/src/nexus/api/seat-requests.ts +44 -2
- package/src/nexus/api/sessions-store.ts +17 -38
- package/src/nexus/api/sub-seat-charters.ts +34 -0
- package/src/nexus/api/tabs-mutations.ts +3 -1
- package/src/nexus/api/task-cards-api.ts +19 -0
- package/src/nexus/api/trace.ts +18 -6
- package/src/nexus/api/workflow-history.ts +88 -0
- package/src/nexus/api/workflow-run-event-bridge.ts +1 -0
- package/src/nexus/api/workflows.ts +132 -6
- package/src/nexus/index.ts +2 -0
- package/src/nexus/kinds/webterm.ts +2 -1
- package/src/nexus/outbound/delivery-ledger.ts +17 -8
- package/src/nexus/outbound/router.ts +8 -3
- package/src/nexus/webterm/pty.ts +6 -2
- package/src/onboarding/cli-auth-status.ts +80 -0
- package/src/onboarding/voice-ai.ts +3 -3
- package/src/org/seat-budget.ts +48 -0
- package/src/org/stall-escalation.ts +63 -0
- package/src/outputs/ledger.ts +120 -0
- package/src/persona/persona-todo.ts +79 -0
- package/src/persona/presets.ts +123 -2
- package/src/persona/team-set.ts +155 -0
- package/src/plugins/install/plugin-install.ts +14 -0
- package/src/plugins/maker/market-bundle.ts +110 -0
- package/src/plugins/maker/plugin-maker.ts +254 -11
- package/src/plugins/maker/wizard-generate.ts +103 -0
- package/src/pod-lease/admission.ts +150 -0
- package/src/pod-lease/dependency-state.ts +85 -0
- package/src/pod-lease/host-lease.ts +127 -0
- package/src/project/project-suggestion.ts +16 -0
- package/src/project/session-context.ts +24 -0
- package/src/release-loop/checklist.ts +17 -5
- package/src/release-loop/feature-store.ts +29 -13
- package/src/release-loop/landed-but-yellow.ts +48 -0
- package/src/release-loop/next-md-merge.ts +58 -0
- package/src/release-loop/release-note.ts +59 -4
- package/src/seat-dispatch/seat-ask.ts +130 -0
- package/src/seat-dispatch/seat-questions.ts +100 -0
- package/src/seat-loop/seat-loop.ts +709 -29
- package/src/seat-loop/seat-report.ts +37 -2
- package/src/self-dev/dev-cli.ts +4 -1
- package/src/self-dev/dev-pipeline.ts +37 -1
- package/src/self-dev/draft-sweep.ts +79 -40
- package/src/self-dev/draft-triage-rules.ts +62 -7
- package/src/self-dev/fabric-plan-core.ts +297 -0
- package/src/self-dev/orchestrate.ts +36 -4
- package/src/self-dev/release-path-guard.ts +62 -0
- package/src/self-dev/shard-aggregate.ts +230 -0
- package/src/self-dev/shard-placement.ts +60 -0
- package/src/self-dev/shard-plan.ts +48 -0
- package/src/self-dev/shard-pod-run.ts +77 -0
- package/src/self-dev/shard-run.ts +105 -0
- package/src/self-implement/budget-gate.ts +29 -12
- package/src/self-implement/gate-baseline.ts +1 -1
- package/src/self-implement/gate-candidate-ranking.ts +60 -0
- package/src/self-implement/gate-cli.ts +40 -1
- package/src/self-implement/gate-scope.ts +44 -13
- package/src/self-implement/graph-variant.ts +171 -0
- package/src/self-implement/harness-policy-gates.ts +1 -1
- package/src/self-implement/headless-elanous-driver.ts +27 -3
- package/src/self-implement/host-regate.ts +22 -1
- package/src/self-implement/importer-test-index.ts +2 -1
- package/src/self-implement/l8-merge-queue.ts +130 -0
- package/src/self-implement/orchestrator.ts +257 -9
- package/src/self-implement/route-consumer-test-index.ts +122 -0
- package/src/self-implement/seams.ts +72 -11
- package/src/self-implement/test-seams.ts +2 -0
- package/src/self-implement/uncommitted-work.ts +59 -0
- package/src/session/index.ts +36 -13
- package/src/skills/gift-install.ts +215 -0
- package/src/skills/tools/web-search.ts +4 -1
- package/src/steward/launch.ts +42 -26
- package/src/steward/steward-cards.ts +17 -9
- package/src/steward/triage.ts +46 -14
- package/src/task-cards/card-cli.ts +25 -1
- package/src/task-orchestrator/mission.ts +5 -0
- package/src/task-orchestrator/store.ts +12 -3
- package/src/task-orchestrator/surfaces/pod-command-job.ts +43 -17
- package/src/task-orchestrator/surfaces/pod-lease.ts +156 -19
- package/src/task-orchestrator/surfaces/pod-pool.ts +127 -26
- package/src/task-orchestrator/surfaces/self-implement-pod.ts +222 -40
- package/src/task-orchestrator/surfaces/self-implement.ts +15 -2
- package/src/task-orchestrator/types.ts +2 -0
- package/src/telegram-card-followup.ts +16 -96
- package/src/telegram-commands.ts +31 -1
- package/src/telegram-project-command.ts +145 -0
- package/src/telegram-report.ts +21 -17
- package/src/telegram.ts +61 -8
- package/src/tool-runtime/self-cognition-runtimes.ts +13 -3
- package/src/user-config.ts +110 -24
- package/src/version/packed-revision.json +1 -1
- package/src/web-search/grok.ts +7 -1
- package/src/web-search/index.ts +28 -1
- package/src/web-search/provider.ts +4 -0
- package/src/web-search/x-intent.ts +5 -0
- package/src/workflow-runtime/executor.ts +277 -47
- package/src/workflow-runtime/index.ts +1 -0
- package/src/workflow-runtime/nodes/subworkflow.ts +60 -0
- package/src/workflow-runtime/plugin-kind-node.ts +1 -1
- package/src/workflow-runtime/schema.ts +79 -4
- package/src/workflow-runtime/types.ts +35 -4
- package/apps/pwa/out/_next/static/2DsiDfDCks44g1cPUMhiW/_buildManifest.js +0 -1
- package/apps/pwa/out/_next/static/chunks/1105-c473ed46272fba79.js +0 -1
- package/apps/pwa/out/_next/static/chunks/1377-1efeffbbac0963ff.js +0 -1
- package/apps/pwa/out/_next/static/chunks/1470.98a6ab61ccb4131c.js +0 -1
- package/apps/pwa/out/_next/static/chunks/216-5acd01cbde4acda7.js +0 -1
- package/apps/pwa/out/_next/static/chunks/2330-c2f07246c8788af1.js +0 -1
- package/apps/pwa/out/_next/static/chunks/2375-cb6debea56cce4fb.js +0 -1
- package/apps/pwa/out/_next/static/chunks/24-e6d28380efab7faf.js +0 -1
- package/apps/pwa/out/_next/static/chunks/2977-e38442e86289f1d3.js +0 -1
- package/apps/pwa/out/_next/static/chunks/2982-2a2df543be3d2e5a.js +0 -25
- package/apps/pwa/out/_next/static/chunks/3403.4bc97b4066945a94.js +0 -5
- package/apps/pwa/out/_next/static/chunks/3615-740dd270764ffa24.js +0 -1
- package/apps/pwa/out/_next/static/chunks/371-4ad6af55dad02ced.js +0 -1
- package/apps/pwa/out/_next/static/chunks/3734-1015fe991eb9b7e7.js +0 -1
- package/apps/pwa/out/_next/static/chunks/4114-3e63117452378807.js +0 -1
- package/apps/pwa/out/_next/static/chunks/5012-a7fe6f3c8b6fe45a.js +0 -1
- package/apps/pwa/out/_next/static/chunks/5609-012bb3557211f07e.js +0 -1
- package/apps/pwa/out/_next/static/chunks/5783-ef40ebfc91d55230.js +0 -1
- package/apps/pwa/out/_next/static/chunks/5791-bb82743fa6299562.js +0 -1
- package/apps/pwa/out/_next/static/chunks/62-ff227c3edb8b248b.js +0 -1
- package/apps/pwa/out/_next/static/chunks/6320-baac91d68843a9a6.js +0 -1
- package/apps/pwa/out/_next/static/chunks/6725-68ab7cc0b1faf00d.js +0 -1
- package/apps/pwa/out/_next/static/chunks/6998-a654fe5c58271600.js +0 -1
- package/apps/pwa/out/_next/static/chunks/7633-1b3709b0854c9412.js +0 -1
- package/apps/pwa/out/_next/static/chunks/7647.2fcd30d894d5ee30.js +0 -1
- package/apps/pwa/out/_next/static/chunks/7673-2eda1507d38dadb8.js +0 -1
- package/apps/pwa/out/_next/static/chunks/7951-8b03dbb10b24cd06.js +0 -1
- package/apps/pwa/out/_next/static/chunks/7990-e12efba616f46e03.js +0 -1
- package/apps/pwa/out/_next/static/chunks/8142-744998d65d7bb17e.js +0 -1
- package/apps/pwa/out/_next/static/chunks/8195-6fde3d7a39859206.js +0 -10
- package/apps/pwa/out/_next/static/chunks/8619-4365e03a2862830f.js +0 -1
- package/apps/pwa/out/_next/static/chunks/8894-b5fb36bab837cd29.js +0 -1
- package/apps/pwa/out/_next/static/chunks/920-f7dceb78f1c585ef.js +0 -1
- package/apps/pwa/out/_next/static/chunks/9454-84d0d5d77446bd92.js +0 -1
- package/apps/pwa/out/_next/static/chunks/9651-3cd291a6fa1370d2.js +0 -1
- package/apps/pwa/out/_next/static/chunks/988-5f92e7ab7ccea3dd.js +0 -1
- package/apps/pwa/out/_next/static/chunks/9989-5582582f06429840.js +0 -1
- package/apps/pwa/out/_next/static/chunks/ae787e4c-f2998de7f1ba72a4.js +0 -1
- package/apps/pwa/out/_next/static/chunks/app/_not-found/page-859cea1570b6227a.js +0 -1
- package/apps/pwa/out/_next/static/chunks/app/approvals/page-d2253d7e58ef1890.js +0 -1
- package/apps/pwa/out/_next/static/chunks/app/autopilot/page-5441d4a9ab35e518.js +0 -1
- package/apps/pwa/out/_next/static/chunks/app/board/page-d9b12d680922d980.js +0 -1
- package/apps/pwa/out/_next/static/chunks/app/bots/page-e268d6d145827a22.js +0 -1
- package/apps/pwa/out/_next/static/chunks/app/chat/page-f8116559c7424da7.js +0 -1
- package/apps/pwa/out/_next/static/chunks/app/consult/page-1085399fd0f32112.js +0 -1
- package/apps/pwa/out/_next/static/chunks/app/control/page-1df686a14f65895a.js +0 -1
- package/apps/pwa/out/_next/static/chunks/app/design-check/page-54e1f966ab60a4dc.js +0 -1
- package/apps/pwa/out/_next/static/chunks/app/editor/page-7ed95f296f5ee8e9.js +0 -1
- package/apps/pwa/out/_next/static/chunks/app/exec/page-11edac668d77e5c3.js +0 -1
- package/apps/pwa/out/_next/static/chunks/app/field/page-59e2b9a22cd5a6d5.js +0 -1
- package/apps/pwa/out/_next/static/chunks/app/healthz/route-859cea1570b6227a.js +0 -1
- package/apps/pwa/out/_next/static/chunks/app/intake/page-2976df21ad74ab48.js +0 -1
- package/apps/pwa/out/_next/static/chunks/app/layout-34d211a67f16d510.js +0 -1
- package/apps/pwa/out/_next/static/chunks/app/live/page-8ff652d5d950639b.js +0 -1
- package/apps/pwa/out/_next/static/chunks/app/market/page-b31610deda76337b.js +0 -1
- package/apps/pwa/out/_next/static/chunks/app/missions/[id]/page-6cb0e1bbefe5fb3d.js +0 -1
- package/apps/pwa/out/_next/static/chunks/app/morning/page-a286a152cf584576.js +0 -1
- package/apps/pwa/out/_next/static/chunks/app/not-found-d9237581e7003bcb.js +0 -1
- package/apps/pwa/out/_next/static/chunks/app/observatory/page-83274e761643fdd2.js +0 -1
- package/apps/pwa/out/_next/static/chunks/app/ops/checklist/page-ceee6cfb1d4e6d68.js +0 -1
- package/apps/pwa/out/_next/static/chunks/app/ops/release/page-9c9f8bb3e4a64091.js +0 -1
- package/apps/pwa/out/_next/static/chunks/app/ops/seats/page-c17217603ea3426a.js +0 -1
- package/apps/pwa/out/_next/static/chunks/app/page-efb6177cbf1e8a51.js +0 -1
- package/apps/pwa/out/_next/static/chunks/app/reflection/page-d307523703bc4df3.js +0 -1
- package/apps/pwa/out/_next/static/chunks/app/scheduler/page-462f4e4bab45ce7d.js +0 -1
- package/apps/pwa/out/_next/static/chunks/app/sessions/page-8990e96f33af3837.js +0 -1
- package/apps/pwa/out/_next/static/chunks/app/settings/devices/page-e168fa1030af0548.js +0 -1
- package/apps/pwa/out/_next/static/chunks/app/settings/page-1233e05a4068bc9c.js +0 -1
- package/apps/pwa/out/_next/static/chunks/app/setup/done/page-13a1840b1fac337a.js +0 -1
- package/apps/pwa/out/_next/static/chunks/app/setup/layout-859cea1570b6227a.js +0 -1
- package/apps/pwa/out/_next/static/chunks/app/setup/page-64a29fc80b11ab55.js +0 -1
- package/apps/pwa/out/_next/static/chunks/app/share/page-68e787339a16b3dc.js +0 -1
- package/apps/pwa/out/_next/static/chunks/app/showroom/page-4fddc90b23feb215.js +0 -1
- package/apps/pwa/out/_next/static/chunks/app/tasks/page-886ba8260dc79c79.js +0 -1
- package/apps/pwa/out/_next/static/chunks/app/term/page-0f26507a1722e40b.js +0 -1
- package/apps/pwa/out/_next/static/chunks/app/today/page-109d4ccd42259c9d.js +0 -1
- package/apps/pwa/out/_next/static/chunks/app/trace/page-f5c2a4e510726774.js +0 -1
- package/apps/pwa/out/_next/static/chunks/app/vault/page-b2e0039416f42522.js +0 -1
- package/apps/pwa/out/_next/static/chunks/app/workflows/chat-ui/page-26102fd7350f171e.js +0 -1
- package/apps/pwa/out/_next/static/chunks/app/workflows/page-708948bc8a802794.js +0 -1
- package/apps/pwa/out/_next/static/chunks/app/workspace/page-5e5611620f78fb0b.js +0 -1
- package/apps/pwa/out/_next/static/chunks/app/worktrees/page-139ba5c367bbf60a.js +0 -1
- package/apps/pwa/out/_next/static/chunks/framework-ea806bb57f2b8923.js +0 -1
- package/apps/pwa/out/_next/static/chunks/main-8d2302399c2c8f87.js +0 -1
- package/apps/pwa/out/_next/static/chunks/main-app-202b4e81f33895ea.js +0 -1
- package/apps/pwa/out/_next/static/chunks/pages/_app-b10928c60f0b8488.js +0 -1
- package/apps/pwa/out/_next/static/chunks/pages/_error-689039227d443fab.js +0 -1
- package/apps/pwa/out/_next/static/chunks/webpack-e5bea36f183b25e6.js +0 -1
- package/apps/pwa/out/_next/static/css/43feca5fd387dcbd.css +0 -1
- /package/apps/pwa/out/_next/static/{2DsiDfDCks44g1cPUMhiW → -6XrAoD3eU7NyMHAE4xPS}/_ssgManifest.js +0 -0
|
@@ -0,0 +1,297 @@
|
|
|
1
|
+
import { randomUUID } from 'node:crypto';
|
|
2
|
+
import { spawnSync } from 'node:child_process';
|
|
3
|
+
import { appendFileSync, closeSync, existsSync, linkSync, mkdirSync, openSync, readFileSync, statSync, truncateSync, unlinkSync, writeFileSync } from 'node:fs';
|
|
4
|
+
import { join } from 'node:path';
|
|
5
|
+
import { debug } from '../debug/log.js';
|
|
6
|
+
import {
|
|
7
|
+
decomposeFabricRequest,
|
|
8
|
+
type FabricDecomposeRequestOptions,
|
|
9
|
+
} from './fabric-decompose-adapter.js';
|
|
10
|
+
import type { JobKind } from './orchestrate.js';
|
|
11
|
+
|
|
12
|
+
export interface FabricPlanNode {
|
|
13
|
+
id: string;
|
|
14
|
+
title: string;
|
|
15
|
+
kind: JobKind;
|
|
16
|
+
dependsOn: string[];
|
|
17
|
+
expectedOutput: string;
|
|
18
|
+
children: FabricPlanNode[];
|
|
19
|
+
}
|
|
20
|
+
|
|
21
|
+
export interface FabricPlan {
|
|
22
|
+
id: string;
|
|
23
|
+
request: string;
|
|
24
|
+
status: 'draft' | 'approved';
|
|
25
|
+
nodes: FabricPlanNode[];
|
|
26
|
+
createdAt: string;
|
|
27
|
+
updatedAt: string;
|
|
28
|
+
}
|
|
29
|
+
|
|
30
|
+
export interface FabricPlanEdit {
|
|
31
|
+
id: string;
|
|
32
|
+
title?: string;
|
|
33
|
+
kind?: JobKind;
|
|
34
|
+
dependsOn?: string[];
|
|
35
|
+
expectedOutput?: string;
|
|
36
|
+
}
|
|
37
|
+
|
|
38
|
+
export interface FabricExecutionCandidate {
|
|
39
|
+
planId: string;
|
|
40
|
+
nodes: FabricPlanNode[];
|
|
41
|
+
approvedAt: string;
|
|
42
|
+
}
|
|
43
|
+
|
|
44
|
+
type FabricPlanEvent =
|
|
45
|
+
| { type: 'plan'; plan: FabricPlan }
|
|
46
|
+
| { type: 'execution-candidate'; candidate: FabricExecutionCandidate };
|
|
47
|
+
/** An approval is one line, so a torn write can never leave «approved» without its candidate (review must-fix). */
|
|
48
|
+
type FabricPlanLine = FabricPlanEvent | { type: 'approved'; plan: FabricPlan; candidate: FabricExecutionCandidate };
|
|
49
|
+
|
|
50
|
+
function ledgerPath(root: string): string {
|
|
51
|
+
return join(root, 'fabric', 'plans.jsonl');
|
|
52
|
+
}
|
|
53
|
+
|
|
54
|
+
// One ledger lock also protects reads: a reader must not observe half of an approval pair.
|
|
55
|
+
// The owner file is fully written before its hard link becomes the visible lock.
|
|
56
|
+
function lockOwnerAlive(pid: number): boolean {
|
|
57
|
+
try {
|
|
58
|
+
process.kill(pid, 0);
|
|
59
|
+
return true;
|
|
60
|
+
} catch (error) {
|
|
61
|
+
return (error as NodeJS.ErrnoException).code !== 'ESRCH';
|
|
62
|
+
}
|
|
63
|
+
}
|
|
64
|
+
|
|
65
|
+
/** Process start time as `ps` reports it — with the pid it identifies one process even after the pid is reused. */
|
|
66
|
+
function processStart(pid: number): string | null {
|
|
67
|
+
const r = spawnSync('ps', ['-o', 'lstart=', '-p', String(pid)], { encoding: 'utf8' });
|
|
68
|
+
const value = r.status === 0 ? r.stdout.trim() : '';
|
|
69
|
+
return value || null;
|
|
70
|
+
}
|
|
71
|
+
|
|
72
|
+
function reclaimAbandonedLock(lockPath: string): void {
|
|
73
|
+
let observed: string;
|
|
74
|
+
let inode: number;
|
|
75
|
+
try {
|
|
76
|
+
observed = readFileSync(lockPath, 'utf8');
|
|
77
|
+
inode = statSync(lockPath).ino;
|
|
78
|
+
} catch (error) {
|
|
79
|
+
if ((error as NodeJS.ErrnoException).code === 'ENOENT') return;
|
|
80
|
+
throw error;
|
|
81
|
+
}
|
|
82
|
+
const [pidText, ...startParts] = observed.trim().split('|');
|
|
83
|
+
const pid = Number(pidText);
|
|
84
|
+
const ownerStart = startParts.join('|');
|
|
85
|
+
// Unidentified locks are not evidence that their owner has died.
|
|
86
|
+
if (!Number.isSafeInteger(pid) || pid <= 0) return;
|
|
87
|
+
// Alive pid with a different start time = the pid was reused by another process; the owner is gone (review must-fix).
|
|
88
|
+
const reused = ownerStart !== '' && lockOwnerAlive(pid) && processStart(pid) !== null && processStart(pid) !== ownerStart;
|
|
89
|
+
if (lockOwnerAlive(pid) && !reused) return;
|
|
90
|
+
try {
|
|
91
|
+
if (statSync(lockPath).ino === inode && readFileSync(lockPath, 'utf8') === observed) unlinkSync(lockPath);
|
|
92
|
+
} catch (error) {
|
|
93
|
+
if ((error as NodeJS.ErrnoException).code !== 'ENOENT') throw error;
|
|
94
|
+
}
|
|
95
|
+
}
|
|
96
|
+
|
|
97
|
+
function withLedgerLock<T>(root: string, operation: () => T): T {
|
|
98
|
+
const directory = join(root, 'fabric');
|
|
99
|
+
mkdirSync(directory, { recursive: true });
|
|
100
|
+
const lockPath = join(directory, 'plans.lock');
|
|
101
|
+
const ownerPath = join(directory, `plans.lock.${process.pid}.${randomUUID()}`);
|
|
102
|
+
writeFileSync(ownerPath, `${process.pid}|${processStart(process.pid) ?? ''}`, { flag: 'wx' });
|
|
103
|
+
const deadline = Date.now() + 10_000;
|
|
104
|
+
let acquired = false;
|
|
105
|
+
try {
|
|
106
|
+
while (!acquired) {
|
|
107
|
+
try {
|
|
108
|
+
linkSync(ownerPath, lockPath);
|
|
109
|
+
acquired = true;
|
|
110
|
+
} catch (error) {
|
|
111
|
+
if ((error as NodeJS.ErrnoException).code !== 'EEXIST') throw error;
|
|
112
|
+
reclaimAbandonedLock(lockPath);
|
|
113
|
+
if (Date.now() >= deadline) throw new Error('fabric plan ledger lock timeout');
|
|
114
|
+
Bun.sleepSync(5);
|
|
115
|
+
}
|
|
116
|
+
}
|
|
117
|
+
return operation();
|
|
118
|
+
} finally {
|
|
119
|
+
if (acquired) unlinkSync(lockPath);
|
|
120
|
+
unlinkSync(ownerPath);
|
|
121
|
+
}
|
|
122
|
+
}
|
|
123
|
+
|
|
124
|
+
function appendLines(root: string, lines: readonly FabricPlanLine[]): void {
|
|
125
|
+
const path = ledgerPath(root);
|
|
126
|
+
mkdirSync(join(root, 'fabric'), { recursive: true });
|
|
127
|
+
appendFileSync(path, lines.map((line) => JSON.stringify(line)).join('\n') + '\n');
|
|
128
|
+
}
|
|
129
|
+
|
|
130
|
+
function appendEvent(root: string, event: FabricPlanEvent): void {
|
|
131
|
+
appendLines(root, [event]);
|
|
132
|
+
}
|
|
133
|
+
|
|
134
|
+
/** Called under the ledger lock. A torn last line (crash mid-append) is cut back to the last whole line so the ledger stays usable. */
|
|
135
|
+
function readEvents(root: string): FabricPlanEvent[] {
|
|
136
|
+
const path = ledgerPath(root);
|
|
137
|
+
if (!existsSync(path)) return [];
|
|
138
|
+
const text = readFileSync(path, 'utf8');
|
|
139
|
+
const lines = text.split('\n');
|
|
140
|
+
const events: FabricPlanEvent[] = [];
|
|
141
|
+
let offset = 0;
|
|
142
|
+
for (let i = 0; i < lines.length; i++) {
|
|
143
|
+
const line = lines[i]!;
|
|
144
|
+
const complete = i < lines.length - 1;
|
|
145
|
+
if (line) {
|
|
146
|
+
let parsed: FabricPlanLine | undefined;
|
|
147
|
+
try { parsed = JSON.parse(line) as FabricPlanLine; } catch { parsed = undefined; }
|
|
148
|
+
if (!parsed || !complete) {
|
|
149
|
+
// Only the tail may be torn; a bad line in the middle is real corruption and must not be silently skipped.
|
|
150
|
+
if (lines.slice(i + 1).some(Boolean)) throw new Error(`fabric plan ledger corrupt at line ${i + 1}`);
|
|
151
|
+
truncateSync(path, Buffer.byteLength(text.slice(0, offset)));
|
|
152
|
+
debug.log('fabric.plan', 'torn-tail-repaired', { line: i + 1, bytes: Buffer.byteLength(line) });
|
|
153
|
+
break;
|
|
154
|
+
}
|
|
155
|
+
if (parsed.type === 'approved') events.push({ type: 'plan', plan: parsed.plan }, { type: 'execution-candidate', candidate: parsed.candidate });
|
|
156
|
+
else events.push(parsed);
|
|
157
|
+
}
|
|
158
|
+
offset += line.length + 1;
|
|
159
|
+
}
|
|
160
|
+
return events;
|
|
161
|
+
}
|
|
162
|
+
|
|
163
|
+
function inferredKind(text: string): JobKind {
|
|
164
|
+
if (/영상|비디오|video|media|편집|촬영/i.test(text)) return 'media';
|
|
165
|
+
if (/배포|출시|deploy|release|publish/i.test(text)) return 'deploy';
|
|
166
|
+
if (/조사|검색|분석|research|search|investigat/i.test(text)) return 'search';
|
|
167
|
+
return 'dev';
|
|
168
|
+
}
|
|
169
|
+
|
|
170
|
+
function flatten(nodes: readonly FabricPlanNode[]): FabricPlanNode[] {
|
|
171
|
+
return nodes.flatMap((node) => [node, ...flatten(node.children)]);
|
|
172
|
+
}
|
|
173
|
+
|
|
174
|
+
function validateNodes(nodes: readonly FabricPlanNode[]): void {
|
|
175
|
+
const all = flatten(nodes);
|
|
176
|
+
if (!all.length) throw new Error('fabric plan requires nodes');
|
|
177
|
+
const byId = new Map(all.map((node) => [node.id, node]));
|
|
178
|
+
if (byId.size !== all.length) throw new Error('duplicate fabric plan node id');
|
|
179
|
+
const visiting = new Set<string>();
|
|
180
|
+
const visited = new Set<string>();
|
|
181
|
+
const visit = (id: string): void => {
|
|
182
|
+
if (visiting.has(id)) throw new Error('cyclic fabric plan dependency');
|
|
183
|
+
if (visited.has(id)) return;
|
|
184
|
+
const node = byId.get(id);
|
|
185
|
+
if (!node) throw new Error(`unknown fabric plan dependency: ${id}`);
|
|
186
|
+
visiting.add(id);
|
|
187
|
+
for (const dependency of node.dependsOn) visit(dependency);
|
|
188
|
+
visiting.delete(id);
|
|
189
|
+
visited.add(id);
|
|
190
|
+
};
|
|
191
|
+
for (const node of all) {
|
|
192
|
+
if (typeof node.title !== 'string' || !node.title.trim()
|
|
193
|
+
|| typeof node.expectedOutput !== 'string' || !node.expectedOutput.trim()) {
|
|
194
|
+
throw new Error('fabric plan node requires title and expected output');
|
|
195
|
+
}
|
|
196
|
+
if (!['dev', 'search', 'deploy', 'media'].includes(node.kind)) throw new Error('invalid fabric plan node kind');
|
|
197
|
+
if (!Array.isArray(node.dependsOn) || node.dependsOn.some((id) => typeof id !== 'string')) {
|
|
198
|
+
throw new Error('invalid fabric plan dependencies');
|
|
199
|
+
}
|
|
200
|
+
visit(node.id);
|
|
201
|
+
}
|
|
202
|
+
}
|
|
203
|
+
|
|
204
|
+
function loadPlanUnlocked(root: string, id: string): FabricPlan | null {
|
|
205
|
+
const events = readEvents(root);
|
|
206
|
+
return events.filter((event): event is Extract<FabricPlanEvent, { type: 'plan' }> => event.type === 'plan')
|
|
207
|
+
.map((event) => event.plan).reverse().find((plan) => plan.id === id) ?? null;
|
|
208
|
+
}
|
|
209
|
+
|
|
210
|
+
export function loadFabricPlan(root: string, id: string): FabricPlan | null {
|
|
211
|
+
return withLedgerLock(root, () => loadPlanUnlocked(root, id));
|
|
212
|
+
}
|
|
213
|
+
|
|
214
|
+
export function listFabricExecutionCandidates(root: string): FabricExecutionCandidate[] {
|
|
215
|
+
return withLedgerLock(root, () => readEvents(root)
|
|
216
|
+
.filter((event): event is Extract<FabricPlanEvent, { type: 'execution-candidate' }> => event.type === 'execution-candidate')
|
|
217
|
+
.map((event) => event.candidate));
|
|
218
|
+
}
|
|
219
|
+
|
|
220
|
+
/** Drafting and human edits record plan versions, never executable candidates. */
|
|
221
|
+
export async function createFabricPlan(
|
|
222
|
+
root: string,
|
|
223
|
+
request: string,
|
|
224
|
+
options: FabricDecomposeRequestOptions = {},
|
|
225
|
+
): Promise<FabricPlan> {
|
|
226
|
+
if (!request.trim()) throw new Error('fabric plan request is empty');
|
|
227
|
+
const result = await decomposeFabricRequest(request, options);
|
|
228
|
+
if (result.status !== 'decomposed' || result.rfc.arcs.length === 0) {
|
|
229
|
+
throw new Error(`fabric plan decomposition failed: ${result.status}`);
|
|
230
|
+
}
|
|
231
|
+
const nodes: FabricPlanNode[] = result.rfc.arcs.map((arc, arcIndex) => {
|
|
232
|
+
const id = `arc-${arcIndex + 1}`;
|
|
233
|
+
const previousArc = result.rfc.arcs[arcIndex - 1];
|
|
234
|
+
const previous = previousArc ? [`arc-${arcIndex}:task-${previousArc.workItems.length}`] : [];
|
|
235
|
+
const children: FabricPlanNode[] = arc.workItems.map((item, itemIndex) => ({
|
|
236
|
+
id: `${id}:task-${itemIndex + 1}`,
|
|
237
|
+
title: item.title,
|
|
238
|
+
kind: inferredKind(`${arc.heading} ${item.title}`),
|
|
239
|
+
dependsOn: itemIndex ? [`${id}:task-${itemIndex}`] : [id],
|
|
240
|
+
expectedOutput: item.detail?.trim() || item.title,
|
|
241
|
+
children: [],
|
|
242
|
+
}));
|
|
243
|
+
return {
|
|
244
|
+
id,
|
|
245
|
+
title: arc.heading,
|
|
246
|
+
kind: inferredKind(arc.heading),
|
|
247
|
+
dependsOn: previous,
|
|
248
|
+
expectedOutput: arc.workItems.map((item) => item.detail?.trim() || item.title).join('; '),
|
|
249
|
+
children,
|
|
250
|
+
};
|
|
251
|
+
});
|
|
252
|
+
validateNodes(nodes);
|
|
253
|
+
const now = new Date().toISOString();
|
|
254
|
+
const plan: FabricPlan = { id: randomUUID(), request, status: 'draft', nodes, createdAt: now, updatedAt: now };
|
|
255
|
+
withLedgerLock(root, () => appendEvent(root, { type: 'plan', plan }));
|
|
256
|
+
return plan;
|
|
257
|
+
}
|
|
258
|
+
|
|
259
|
+
export function reviseFabricPlan(root: string, id: string, edits: readonly FabricPlanEdit[]): FabricPlan {
|
|
260
|
+
return withLedgerLock(root, () => {
|
|
261
|
+
const current = loadPlanUnlocked(root, id);
|
|
262
|
+
if (!current) throw new Error(`fabric plan not found: ${id}`);
|
|
263
|
+
if (current.status !== 'draft' || readEvents(root).some((event) => event.type === 'execution-candidate' && event.candidate.planId === id)) {
|
|
264
|
+
throw new Error('approved fabric plan cannot be revised');
|
|
265
|
+
}
|
|
266
|
+
const ids = new Set(flatten(current.nodes).map((node) => node.id));
|
|
267
|
+
if (new Set(edits.map((edit) => edit.id)).size !== edits.length || edits.some((edit) => !ids.has(edit.id))) {
|
|
268
|
+
throw new Error('duplicate or unknown fabric plan edit id');
|
|
269
|
+
}
|
|
270
|
+
const byId = new Map(edits.map((edit) => [edit.id, edit]));
|
|
271
|
+
const apply = (node: FabricPlanNode): FabricPlanNode => {
|
|
272
|
+
const edit = byId.get(node.id);
|
|
273
|
+
return { ...node, ...edit, dependsOn: [...(edit?.dependsOn ?? node.dependsOn)], children: node.children.map(apply) };
|
|
274
|
+
};
|
|
275
|
+
const nodes = current.nodes.map(apply);
|
|
276
|
+
validateNodes(nodes);
|
|
277
|
+
const plan: FabricPlan = { ...current, nodes, updatedAt: new Date().toISOString() };
|
|
278
|
+
appendEvent(root, { type: 'plan', plan });
|
|
279
|
+
return plan;
|
|
280
|
+
});
|
|
281
|
+
}
|
|
282
|
+
|
|
283
|
+
/** Approval is the sole operation allowed to append an execution candidate. */
|
|
284
|
+
export function approveFabricPlan(root: string, id: string): FabricExecutionCandidate {
|
|
285
|
+
return withLedgerLock(root, () => {
|
|
286
|
+
const current = loadPlanUnlocked(root, id);
|
|
287
|
+
if (!current) throw new Error(`fabric plan not found: ${id}`);
|
|
288
|
+
if (current.status !== 'draft' || readEvents(root).some((event) => event.type === 'execution-candidate' && event.candidate.planId === id)) {
|
|
289
|
+
throw new Error('fabric plan already approved');
|
|
290
|
+
}
|
|
291
|
+
validateNodes(current.nodes);
|
|
292
|
+
const approvedAt = new Date().toISOString();
|
|
293
|
+
const candidate: FabricExecutionCandidate = { planId: id, nodes: current.nodes, approvedAt };
|
|
294
|
+
appendLines(root, [{ type: 'approved', plan: { ...current, status: 'approved', updatedAt: approvedAt }, candidate }]);
|
|
295
|
+
return candidate;
|
|
296
|
+
});
|
|
297
|
+
}
|
|
@@ -21,7 +21,8 @@ import { spawn, execFileSync } from 'node:child_process';
|
|
|
21
21
|
import { emitDecision } from '../live/detail-switch.js';
|
|
22
22
|
import { parentUnlandedProgressLine } from './run-supervisor.js';
|
|
23
23
|
import { mkdirSync, openSync, writeFileSync, closeSync, renameSync, unlinkSync } from 'node:fs';
|
|
24
|
-
import { join } from 'node:path';
|
|
24
|
+
import { join, resolve } from 'node:path';
|
|
25
|
+
import { goalPathFromArgv, launchRegistryDir, removeLaunchBinding, writeLaunchBinding } from '../harness/launch-registry.js';
|
|
25
26
|
import { availableParallelism, cpus } from 'node:os';
|
|
26
27
|
import { selfDevRunsDir } from './run-store.js';
|
|
27
28
|
import { HARNESS_RUN_ID_ENV, normalizeRunId } from '../harness/harness-space.js';
|
|
@@ -56,6 +57,7 @@ import {
|
|
|
56
57
|
} from '../task-orchestrator/surfaces/self-implement.js';
|
|
57
58
|
import { collectOrchestrateUnionDiff, type UnionDiffFileReader } from './orchestrate-union-diff.js';
|
|
58
59
|
import { debug } from '../debug/log.js';
|
|
60
|
+
import { parseGoalReleaseNoteSection, type ReleaseNoteSection } from '../release-loop/release-note.js';
|
|
59
61
|
import { readHarnessScreen, readHarnessScreenTail, resolveHarnessScreenKey } from '../harness/harness-screen.js';
|
|
60
62
|
import {
|
|
61
63
|
dedupWorkingMemory,
|
|
@@ -101,6 +103,7 @@ export type JobKindRegistry = Readonly<Partial<Record<JobKind, JobKindDefinition
|
|
|
101
103
|
interface SelfDevShardIdentity {
|
|
102
104
|
orchestrationId: string;
|
|
103
105
|
parentRequest?: string;
|
|
106
|
+
releaseNote?: ReleaseNoteSection;
|
|
104
107
|
shardId: string;
|
|
105
108
|
totalShards: number;
|
|
106
109
|
position: number;
|
|
@@ -199,6 +202,8 @@ export interface SelfDevGoal {
|
|
|
199
202
|
goalType?: SelfDevGoalType;
|
|
200
203
|
/** Feature/goal text → `elanous self implement <feature>` for dev jobs. */
|
|
201
204
|
feature: string;
|
|
205
|
+
/** Pod lease predecessor goal ID or PR number. */
|
|
206
|
+
after?: string | number;
|
|
202
207
|
base?: string;
|
|
203
208
|
autoMerge?: boolean;
|
|
204
209
|
/** G8 — attach `auto-review` opt-in label on PR (subject to eligibility self-assessment). */
|
|
@@ -890,6 +895,8 @@ export interface OrchestrateSelfDevOptions {
|
|
|
890
895
|
runId?: string;
|
|
891
896
|
/** Override the run directory root for isolated tests. */
|
|
892
897
|
runsDir?: string;
|
|
898
|
+
/** Host-wide run → process binding for `harness stop` across worktrees · `null` = do not write · default: write only when `runsDir` is not overridden. */
|
|
899
|
+
launchRegistryDir?: string | null;
|
|
893
900
|
/** Signal source and kubectl seams for isolated lifecycle tests. */
|
|
894
901
|
signalSource?: Pick<NodeJS.Process, 'on' | 'off'>;
|
|
895
902
|
/** Pod context/namespace pairs chosen by the caller that launched the Jobs. */
|
|
@@ -990,7 +997,7 @@ async function deleteLabelledJobs(runId: string, selectedTargets: readonly { con
|
|
|
990
997
|
/** `self-dev-runs/<runId>/pid.json` — what `harness stop <runId>` reads (start time guards PID reuse).
|
|
991
998
|
* HS1: written as soon as the run ID exists, not only when the jobs start — pod planning and image sync can
|
|
992
999
|
* take minutes before that, and a stop in that window found «no process» (10-01 · three runs). */
|
|
993
|
-
export function writeRunPidRecord(runId: string, runsDir: string = selfDevRunsDir()): string {
|
|
1000
|
+
export function writeRunPidRecord(runId: string, runsDir: string = selfDevRunsDir(), registryDir: string | null = launchRegistryDir()): string {
|
|
994
1001
|
const pidPath = join(runsDir, runId, 'pid.json');
|
|
995
1002
|
mkdirSync(join(runsDir, runId), { recursive: true });
|
|
996
1003
|
const temporary = `${pidPath}.${process.pid}.${randomUUID()}.tmp`;
|
|
@@ -1001,6 +1008,13 @@ export function writeRunPidRecord(runId: string, runsDir: string = selfDevRunsDi
|
|
|
1001
1008
|
} finally { closeSync(fd); }
|
|
1002
1009
|
renameSync(temporary, pidPath);
|
|
1003
1010
|
} catch (error) { unlinkSync(temporary); throw error; }
|
|
1011
|
+
// A stop from another worktree/universe cannot see this pid.json — leave the same binding in the host-wide registry.
|
|
1012
|
+
if (registryDir !== null) {
|
|
1013
|
+
const cwd = process.cwd();
|
|
1014
|
+
const goalPath = goalPathFromArgv(process.argv, cwd);
|
|
1015
|
+
writeLaunchBinding(runId, { pid: process.pid, startedAt: Date.now() - Math.floor(process.uptime() * 1000), argv0: process.argv0,
|
|
1016
|
+
cwd, ...(goalPath ? { goalPath } : {}), runsDir: resolve(runsDir) }, registryDir);
|
|
1017
|
+
}
|
|
1004
1018
|
return pidPath;
|
|
1005
1019
|
}
|
|
1006
1020
|
|
|
@@ -1013,6 +1027,8 @@ export function orchestrateSelfDev(opts: OrchestrateSelfDevOptions): Promise<Sel
|
|
|
1013
1027
|
const runId = opts.runId ?? process.env[HARNESS_RUN_ID_ENV];
|
|
1014
1028
|
if (runId && runId !== normalizeRunId(runId)) throw new Error(`invalid self-dev run ID: ${runId}`);
|
|
1015
1029
|
const pidPath = runId ? join(opts.runsDir ?? selfDevRunsDir(), runId, 'pid.json') : undefined;
|
|
1030
|
+
// Only the real run directory gets a host-wide binding by default — an overridden runsDir is an isolated test.
|
|
1031
|
+
const registryDir = opts.launchRegistryDir !== undefined ? opts.launchRegistryDir : opts.runsDir === undefined ? launchRegistryDir() : null;
|
|
1016
1032
|
const graph = new TaskGraph();
|
|
1017
1033
|
const bus = new TaskEventBus();
|
|
1018
1034
|
const registry = new SurfaceRegistry();
|
|
@@ -1186,6 +1202,7 @@ export function orchestrateSelfDev(opts: OrchestrateSelfDevOptions): Promise<Sel
|
|
|
1186
1202
|
surface: (goal) => ({
|
|
1187
1203
|
kind: 'self-implement',
|
|
1188
1204
|
feature: goal.feature,
|
|
1205
|
+
...(goal.after !== undefined ? { after: goal.after } : {}),
|
|
1189
1206
|
...(goal.base !== undefined ? { base: goal.base } : {}),
|
|
1190
1207
|
...(goal.autoMerge !== undefined ? { autoMerge: goal.autoMerge } : {}),
|
|
1191
1208
|
...(goal.autoReview !== undefined ? { autoReview: goal.autoReview } : {}),
|
|
@@ -1307,6 +1324,7 @@ export function orchestrateSelfDev(opts: OrchestrateSelfDevOptions): Promise<Sel
|
|
|
1307
1324
|
});
|
|
1308
1325
|
|
|
1309
1326
|
if (opts.goals.length > 0) {
|
|
1327
|
+
const releaseNote = opts.parentRequest === undefined ? undefined : parseGoalReleaseNoteSection(opts.parentRequest).fragment;
|
|
1310
1328
|
const orchestrationId = randomUUID();
|
|
1311
1329
|
const shards = opts.goals.map((goal, index) => ({
|
|
1312
1330
|
goal,
|
|
@@ -1320,6 +1338,7 @@ export function orchestrateSelfDev(opts: OrchestrateSelfDevOptions): Promise<Sel
|
|
|
1320
1338
|
const identity: SelfDevShardIdentity = {
|
|
1321
1339
|
orchestrationId,
|
|
1322
1340
|
...(opts.parentRequest === undefined ? {} : { parentRequest: opts.parentRequest }),
|
|
1341
|
+
...(releaseNote ? { releaseNote } : {}),
|
|
1323
1342
|
shardId: shard.shardId,
|
|
1324
1343
|
totalShards: shards.length,
|
|
1325
1344
|
position: shard.position,
|
|
@@ -1328,7 +1347,7 @@ export function orchestrateSelfDev(opts: OrchestrateSelfDevOptions): Promise<Sel
|
|
|
1328
1347
|
.filter((sibling) => sibling !== shard)
|
|
1329
1348
|
.map(({ shardId, summary }) => ({ shardId, summary })),
|
|
1330
1349
|
};
|
|
1331
|
-
|
|
1350
|
+
const task = graph.getTask(taskId);
|
|
1332
1351
|
if (task?.surface.kind === 'self-implement') {
|
|
1333
1352
|
graph.updateTask(taskId, {
|
|
1334
1353
|
surface: { ...task.surface, feature: shardIdentityFeature(shard.goal.feature, identity) },
|
|
@@ -1401,6 +1420,7 @@ export function orchestrateSelfDev(opts: OrchestrateSelfDevOptions): Promise<Sel
|
|
|
1401
1420
|
catch (error) {
|
|
1402
1421
|
if ((error as NodeJS.ErrnoException).code !== 'ENOENT') debug.log('self-dev.orchestrate', 'pid-cleanup-failed', { pidPath, error: String(error) }, { level: 'warn' });
|
|
1403
1422
|
}
|
|
1423
|
+
if (registryDir !== null) removeLaunchBinding(runId!, registryDir);
|
|
1404
1424
|
}
|
|
1405
1425
|
};
|
|
1406
1426
|
const cancel = (signal: NodeJS.Signals): void => {
|
|
@@ -1436,7 +1456,7 @@ export function orchestrateSelfDev(opts: OrchestrateSelfDevOptions): Promise<Sel
|
|
|
1436
1456
|
signals.on('SIGTERM', onTerm);
|
|
1437
1457
|
signals.on('SIGINT', onInt);
|
|
1438
1458
|
try {
|
|
1439
|
-
if (pidPath) writeRunPidRecord(runId!, opts.runsDir ?? selfDevRunsDir());
|
|
1459
|
+
if (pidPath) writeRunPidRecord(runId!, opts.runsDir ?? selfDevRunsDir(), registryDir);
|
|
1440
1460
|
} catch (error) { cleanup(); reject(error); return; }
|
|
1441
1461
|
|
|
1442
1462
|
// Current full result set: resumed-done goals + each running task's
|
|
@@ -1488,6 +1508,18 @@ export function orchestrateSelfDev(opts: OrchestrateSelfDevOptions): Promise<Sel
|
|
|
1488
1508
|
if (settled) return;
|
|
1489
1509
|
settled = true;
|
|
1490
1510
|
const out = buildResults();
|
|
1511
|
+
for (const result of out) {
|
|
1512
|
+
try {
|
|
1513
|
+
debug.log('self-implement.result', 'final', {
|
|
1514
|
+
runId: result.runId ?? null,
|
|
1515
|
+
taskId: result.taskId,
|
|
1516
|
+
stage: result.stage ?? null,
|
|
1517
|
+
mergeReason: result.mergeReason ?? null,
|
|
1518
|
+
failureClassification: result.failureClassification ?? null,
|
|
1519
|
+
prNumber: result.prNumber ?? null,
|
|
1520
|
+
});
|
|
1521
|
+
} catch { /* terminal observation must not change the result */ }
|
|
1522
|
+
}
|
|
1491
1523
|
// S3 — teardown (opt-in): remove each job's worktree (fail-soft),
|
|
1492
1524
|
// preserving any job that opened a PR (branch/worktree still needed).
|
|
1493
1525
|
if (opts.teardown === true && !cancelling) {
|
|
@@ -0,0 +1,62 @@
|
|
|
1
|
+
// Release path = what publishing reads directly: the release scripts and graph, plus the manifest, release notes and cut schedule
|
|
2
|
+
// in `src/release-loop/`. The checklist store (`checklist.ts`, `feature-store.ts`) is shared ops ledger code — the gate catches its regressions (OP 10-03).
|
|
3
|
+
export const RELEASE_PATH_PREFIXES = ['scripts/release-loop/', 'graphs/release/', 'src/release-loop/manifest', 'src/release-loop/release-note', 'src/release-loop/release-schedule'] as const;
|
|
4
|
+
export const RELEASE_PATH_LABEL = 'elanous:release-path';
|
|
5
|
+
|
|
6
|
+
/** Flatten every GitHub PR file page, including the source of a rename. */
|
|
7
|
+
export function releasePrFilePaths(pages: unknown): string[] {
|
|
8
|
+
if (!Array.isArray(pages) || pages.length === 0 || !pages.every((page: unknown) => Array.isArray(page) && page.every((file: unknown) =>
|
|
9
|
+
!!file && typeof file === 'object' && 'filename' in file && typeof file.filename === 'string'
|
|
10
|
+
&& (!('previous_filename' in file) || typeof file.previous_filename === 'string')
|
|
11
|
+
&& (!('status' in file) || file.status !== 'renamed' || ('previous_filename' in file && typeof file.previous_filename === 'string'))))) {
|
|
12
|
+
throw new Error('gh api PR files returned an invalid file list');
|
|
13
|
+
}
|
|
14
|
+
return pages.flatMap((page: Array<{ filename: string; previous_filename?: string }>) =>
|
|
15
|
+
page.flatMap((file) => file.previous_filename ? [file.filename, file.previous_filename] : [file.filename]));
|
|
16
|
+
}
|
|
17
|
+
|
|
18
|
+
/** git diff --name-status -z emits status then one path (or two for rename/copy). */
|
|
19
|
+
export function releaseGitDiffPaths(output: string): string[] {
|
|
20
|
+
const tokens = output.split('\0');
|
|
21
|
+
if (tokens.pop() !== '') throw new Error('invalid NUL-delimited git diff');
|
|
22
|
+
const paths: string[] = [];
|
|
23
|
+
for (let i = 0; i < tokens.length;) {
|
|
24
|
+
const status = tokens[i++];
|
|
25
|
+
if (!status || !/^[ACDMRTUXB][0-9]*$/.test(status)) throw new Error('invalid git diff status');
|
|
26
|
+
const count = /^[RC]/.test(status) ? 2 : 1;
|
|
27
|
+
for (let n = 0; n < count; n++) {
|
|
28
|
+
const path = tokens[i++];
|
|
29
|
+
if (!path) throw new Error('missing git diff path');
|
|
30
|
+
paths.push(path);
|
|
31
|
+
}
|
|
32
|
+
}
|
|
33
|
+
return paths;
|
|
34
|
+
}
|
|
35
|
+
|
|
36
|
+
/** Evaluate the paths from the opened PR, not the requested goal or local working tree. */
|
|
37
|
+
export function releasePathHold(paths: readonly string[]): string | undefined {
|
|
38
|
+
return paths.find((path) => RELEASE_PATH_PREFIXES.some((prefix) => path.startsWith(prefix)));
|
|
39
|
+
}
|
|
40
|
+
|
|
41
|
+
/** Fixed opening of the hold comment — also how a PR held by several merge surfaces (or polls) is recognised, so it is posted once. */
|
|
42
|
+
export const RELEASE_PATH_HOLD_MARKER = 'OP approval required: automatic merge held because this PR changes ';
|
|
43
|
+
|
|
44
|
+
export function releasePathHoldComment(path: string): string {
|
|
45
|
+
return `${RELEASE_PATH_HOLD_MARKER}${path}.`;
|
|
46
|
+
}
|
|
47
|
+
|
|
48
|
+
/** True when the PR's issue-comment pages (gh api --paginate --slurp) already carry a hold comment. */
|
|
49
|
+
export function releasePathHoldAlreadyPosted(pages: unknown): boolean {
|
|
50
|
+
if (!Array.isArray(pages)) throw new Error('gh api PR comments returned an invalid list');
|
|
51
|
+
return pages.some((page: unknown) => Array.isArray(page) && page.some((comment: unknown) =>
|
|
52
|
+
!!comment && typeof comment === 'object' && 'body' in comment && typeof comment.body === 'string' && comment.body.startsWith(RELEASE_PATH_HOLD_MARKER)));
|
|
53
|
+
}
|
|
54
|
+
|
|
55
|
+
/** Unknown comment history must not drop the hold comment: when it cannot be read, post (a duplicate beats a silent hold). */
|
|
56
|
+
export function releasePathHoldShouldPost(readPages: () => unknown): boolean {
|
|
57
|
+
try { return !releasePathHoldAlreadyPosted(readPages()); } catch { return true; }
|
|
58
|
+
}
|
|
59
|
+
|
|
60
|
+
export function releasePathHoldCommentsArgs(pr: string | number): string[] {
|
|
61
|
+
return ['api', '--paginate', '--slurp', '--method', 'GET', '-f', 'per_page=100', `repos/{owner}/{repo}/issues/${pr}/comments`];
|
|
62
|
+
}
|