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,130 @@
|
|
|
1
|
+
import { spawnSync } from 'node:child_process';
|
|
2
|
+
import { existsSync, mkdirSync, mkdtempSync, rmSync, writeFileSync } from 'node:fs';
|
|
3
|
+
import { tmpdir } from 'node:os';
|
|
4
|
+
import { join } from 'node:path';
|
|
5
|
+
import { NEXT_MD_PATH, resolveNextMdConflict } from '../release-loop/next-md-merge.js';
|
|
6
|
+
|
|
7
|
+
type Command = (bin: string, args: readonly string[], cwd: string) => { status: number | null; stdout: string; stderr: string };
|
|
8
|
+
export type L8MergeQueueInput = { number: number; cwd: string; matchHeadCommit: string };
|
|
9
|
+
export type L8MergeQueueResult = { merged: boolean; baseRefName?: string; mergeCommit?: string; detail?: string };
|
|
10
|
+
export type L8MergeQueueDeps = {
|
|
11
|
+
command?: Command;
|
|
12
|
+
/** Must identify the same shared repository across all harness processes. */
|
|
13
|
+
acquire?: (cwd: string) => Promise<() => void>;
|
|
14
|
+
};
|
|
15
|
+
|
|
16
|
+
const command: Command = (bin, args, cwd) => {
|
|
17
|
+
const r = spawnSync(bin, [...args], { cwd, encoding: 'utf8', timeout: 600_000, maxBuffer: 32 * 1024 * 1024 });
|
|
18
|
+
return { status: r.status, stdout: r.stdout ?? '', stderr: (r.stderr ?? '') + (r.error?.message ?? '') };
|
|
19
|
+
};
|
|
20
|
+
|
|
21
|
+
/** Serialize the whole read/integrate/test/merge transaction, not just the final push. */
|
|
22
|
+
export async function acquireL8MergeQueue(cwd: string): Promise<() => void> {
|
|
23
|
+
const git = command('git', ['rev-parse', '--path-format=absolute', '--git-common-dir'], cwd);
|
|
24
|
+
if (git.status !== 0 || !git.stdout.trim()) throw new Error('merge queue common git directory unavailable');
|
|
25
|
+
const slot = join(git.stdout.trim(), 'elanous-l8-merge-queue');
|
|
26
|
+
const deadline = Date.now() + 30 * 60_000;
|
|
27
|
+
for (;;) {
|
|
28
|
+
try {
|
|
29
|
+
mkdirSync(slot);
|
|
30
|
+
try { writeFileSync(join(slot, 'pid'), String(process.pid)); }
|
|
31
|
+
catch (error) { rmSync(slot, { recursive: true, force: true }); throw new Error(`merge queue pid write failed: ${String(error)}`); }
|
|
32
|
+
return () => rmSync(slot, { recursive: true, force: true });
|
|
33
|
+
} catch (error) {
|
|
34
|
+
if ((error as NodeJS.ErrnoException).code !== 'EEXIST') throw error;
|
|
35
|
+
// Fail closed on abandoned slots: never steal a slot while a live merge can own it.
|
|
36
|
+
if (Date.now() >= deadline) throw new Error('merge queue occupied for 30 minutes');
|
|
37
|
+
await new Promise((resolve) => setTimeout(resolve, 250));
|
|
38
|
+
}
|
|
39
|
+
}
|
|
40
|
+
}
|
|
41
|
+
|
|
42
|
+
/** One PR per shared git directory, integrated on a freshly fetched main in a disposable worktree. */
|
|
43
|
+
export async function runL8MergeQueue(input: L8MergeQueueInput, deps: L8MergeQueueDeps = {}): Promise<L8MergeQueueResult> {
|
|
44
|
+
if (!Number.isSafeInteger(input.number) || input.number <= 0 || !/^[0-9a-f]{40}$/i.test(input.matchHeadCommit)) {
|
|
45
|
+
return { merged: false, detail: 'invalid PR number or pinned head' };
|
|
46
|
+
}
|
|
47
|
+
const execute = deps.command ?? command;
|
|
48
|
+
const run = (bin: string, args: readonly string[], cwd: string): string => {
|
|
49
|
+
const result = execute(bin, args, cwd);
|
|
50
|
+
if (result.status !== 0) throw new Error(`${bin} ${args.join(' ')}: ${(result.stderr || result.stdout || `exit ${result.status}`).trim().slice(0, 500)}`);
|
|
51
|
+
return args.includes('-z') ? result.stdout : result.stdout.trim();
|
|
52
|
+
};
|
|
53
|
+
let release: (() => void) | undefined;
|
|
54
|
+
let temp: string | undefined;
|
|
55
|
+
let attached = false;
|
|
56
|
+
try {
|
|
57
|
+
release = await (deps.acquire ?? acquireL8MergeQueue)(input.cwd);
|
|
58
|
+
type View = { headRefOid?: string; headRefName?: string; baseRefName?: string; state?: string; isDraft?: boolean; isCrossRepository?: boolean; mergeCommit?: { oid?: string } | null };
|
|
59
|
+
const view = (): View => JSON.parse(run('gh', ['pr', 'view', String(input.number), '--json', 'headRefOid,headRefName,baseRefName,state,isDraft,isCrossRepository,mergeCommit'], input.cwd));
|
|
60
|
+
const first = view();
|
|
61
|
+
if (first.headRefOid !== input.matchHeadCommit || first.baseRefName !== 'main' || first.state !== 'OPEN' || first.isDraft !== false || first.isCrossRepository !== false || !first.headRefName || !/^[\w./-]+$/.test(first.headRefName) || first.headRefName.startsWith('-') || first.headRefName === 'main') {
|
|
62
|
+
throw new Error('PR head, base, or ready/open state changed');
|
|
63
|
+
}
|
|
64
|
+
run('git', ['fetch', 'origin', 'refs/heads/main'], input.cwd);
|
|
65
|
+
const base = run('git', ['rev-parse', 'FETCH_HEAD'], input.cwd);
|
|
66
|
+
run('git', ['fetch', 'origin', `refs/pull/${input.number}/head`], input.cwd);
|
|
67
|
+
if (run('git', ['rev-parse', 'FETCH_HEAD'], input.cwd) !== input.matchHeadCommit) throw new Error('fetched PR head changed');
|
|
68
|
+
temp = mkdtempSync(join(tmpdir(), 'elanous-l8-'));
|
|
69
|
+
run('git', ['worktree', 'add', '--detach', temp, input.matchHeadCommit], input.cwd);
|
|
70
|
+
attached = true;
|
|
71
|
+
const fork = run('git', ['merge-base', base, input.matchHeadCommit], temp);
|
|
72
|
+
const paths = run('git', ['diff', '--name-only', '-z', fork, input.matchHeadCommit], temp).split('\0').filter(Boolean);
|
|
73
|
+
if (!paths.length) throw new Error('PR changed-file paths unavailable');
|
|
74
|
+
if (paths.some((path) => path.startsWith('-') || path.startsWith('/') || path.split('/').includes('..') || path.includes('\\'))) throw new Error('unsafe PR changed-file path');
|
|
75
|
+
// Deleted tests are not runnable; a successful diff with no runnable paths is not a failed lookup.
|
|
76
|
+
const livePaths = run('git', ['diff', '--name-only', '-z', '--diff-filter=ACMRT', fork, input.matchHeadCommit], temp).split('\0').filter(Boolean);
|
|
77
|
+
const isBunTest = (path: string) => /(?:^|\/)[^/]+\.(?:test|spec)\.(?:[cm]?[jt]sx?)$/.test(path);
|
|
78
|
+
const tests = livePaths.filter(isBunTest);
|
|
79
|
+
const merge = execute('git', ['-c', 'user.name=elanous merge queue', '-c', 'user.email=queue@localhost', 'merge', '--no-ff', '--no-edit', base], temp);
|
|
80
|
+
if (merge.status !== 0) {
|
|
81
|
+
const unresolved = run('git', ['diff', '--name-only', '--diff-filter=U'], temp).split('\n').filter(Boolean);
|
|
82
|
+
if (unresolved.length !== 1 || unresolved[0] !== NEXT_MD_PATH) throw new Error(`merge conflicts: ${unresolved.join(', ') || merge.stderr}`);
|
|
83
|
+
const stage = (n: number): string => {
|
|
84
|
+
const result = execute('git', ['show', `:${n}:${NEXT_MD_PATH}`], temp!);
|
|
85
|
+
if (result.status !== 0) throw new Error(`release/next.md stage ${n} unavailable: ${result.stderr}`);
|
|
86
|
+
return result.stdout;
|
|
87
|
+
};
|
|
88
|
+
// Git stage 2 is the PR and stage 3 is main; the resolver preserves stage 2 and unions main's additions.
|
|
89
|
+
const resolved = resolveNextMdConflict(stage(1), stage(3), stage(2));
|
|
90
|
+
if (resolved === null) throw new Error('release/next.md conflict is not append-only');
|
|
91
|
+
writeFileSync(join(temp, NEXT_MD_PATH), resolved);
|
|
92
|
+
run('git', ['add', '--', NEXT_MD_PATH], temp);
|
|
93
|
+
run('git', ['-c', 'user.name=elanous merge queue', '-c', 'user.email=queue@localhost', 'commit', '-m', 'Integrate latest main for L8 merge queue'], temp);
|
|
94
|
+
}
|
|
95
|
+
if (tests.length) {
|
|
96
|
+
const unavailable = tests.filter((path) => !existsSync(join(temp!, path)));
|
|
97
|
+
if (unavailable.length) throw new Error(`changed test paths unavailable: ${unavailable.join(', ')}`);
|
|
98
|
+
// The disposable checkout must resolve the integrated candidate's lockfile, never the caller's modules.
|
|
99
|
+
run('bun', ['install', '--frozen-lockfile'], temp);
|
|
100
|
+
const result = execute('bun', ['test', ...tests], temp);
|
|
101
|
+
const output = `${result.stdout}\n${result.stderr}`;
|
|
102
|
+
if (result.status !== 0 || !/\b[1-9]\d* pass\b/.test(output) || !/\b0 fail\b/.test(output) || !/Ran [1-9]\d* tests? across [1-9]\d* files?/.test(output)) throw new Error(`changed tests failed or unmeasured: ${output.slice(-400)}`);
|
|
103
|
+
}
|
|
104
|
+
run('git', ['fetch', 'origin', 'refs/heads/main'], input.cwd);
|
|
105
|
+
if (run('git', ['rev-parse', 'FETCH_HEAD'], input.cwd) !== base) throw new Error('main advanced during queue verification; retry on latest main');
|
|
106
|
+
const current = view();
|
|
107
|
+
if (current.headRefOid !== first.headRefOid || current.headRefName !== first.headRefName || current.baseRefName !== 'main' || current.state !== 'OPEN' || current.isDraft !== false || current.isCrossRepository !== false) throw new Error('PR changed during queue verification');
|
|
108
|
+
const integrated = run('git', ['rev-parse', 'HEAD'], temp);
|
|
109
|
+
const remoteHead = run('git', ['ls-remote', 'origin', `refs/heads/${first.headRefName}`], temp).split(/\s+/)[0];
|
|
110
|
+
if (remoteHead !== input.matchHeadCommit) throw new Error('PR branch advanced before queue push');
|
|
111
|
+
run('git', ['fetch', 'origin', 'refs/heads/main'], input.cwd);
|
|
112
|
+
if (run('git', ['rev-parse', 'FETCH_HEAD'], input.cwd) !== base) throw new Error('main advanced before queue merge; retry on latest main');
|
|
113
|
+
// One atomic push (review must-fix: head check and merge were not atomic): the PR branch moves to the tested commit only
|
|
114
|
+
// while it still equals the pinned head (lease), and main moves to the same commit only as a fast-forward. The server
|
|
115
|
+
// applies both ref updates or neither, so an advanced PR head or main rejects the whole merge — nothing stale lands.
|
|
116
|
+
// main then contains the PR head, so GitHub records the PR as merged.
|
|
117
|
+
run('git', ['push', '--atomic', `--force-with-lease=refs/heads/${first.headRefName}:${input.matchHeadCommit}`, 'origin',
|
|
118
|
+
`HEAD:refs/heads/${first.headRefName}`, 'HEAD:refs/heads/main'], temp);
|
|
119
|
+
// The push itself is the merge decision; confirm main holds exactly the tested commit (a later push to the PR branch is a new change, not this merge).
|
|
120
|
+
run('git', ['fetch', 'origin', 'refs/heads/main'], input.cwd);
|
|
121
|
+
if (run('git', ['rev-parse', 'FETCH_HEAD'], input.cwd) !== integrated) throw new Error('main does not point to tested merge commit');
|
|
122
|
+
return { merged: true, baseRefName: 'main', mergeCommit: integrated };
|
|
123
|
+
} catch (error) {
|
|
124
|
+
return { merged: false, detail: String(error) };
|
|
125
|
+
} finally {
|
|
126
|
+
if (attached && temp) execute('git', ['worktree', 'remove', '--force', temp], input.cwd);
|
|
127
|
+
if (temp) rmSync(temp, { recursive: true, force: true });
|
|
128
|
+
release?.();
|
|
129
|
+
}
|
|
130
|
+
}
|
|
@@ -63,10 +63,12 @@ import { GoalRunStore, insertGoalRunRecord, type GoalPriorRuns } from './goal-ru
|
|
|
63
63
|
import { writeGoalRunRecordFragment } from './goal-execution-records.js';
|
|
64
64
|
import { getUserConfig } from '../user-config.js';
|
|
65
65
|
import { appendRunLedgerEntry, loadRunLedger, parseRunShardIdentity, queryRunChain, type RunChainShardSibling, type RunLedgerEntry, type RunLedgerWriter, type RunOriginData, type RunShardIdentity } from './run-ledger.js';
|
|
66
|
+
import { emitSessionEvent, type SessionEventInput } from '../context-bus/session-events.js';
|
|
66
67
|
import { decideLineageSupersede, lineageSupersedeCloseComment, type LineageSupersedeOpenDraft } from './lineage-supersede.js';
|
|
67
68
|
import { basename, isAbsolute, join, relative, resolve, sep } from 'node:path';
|
|
68
69
|
import { enqueueControlMemo, readSoftStopRequestStatus, type SoftStopRequestRead } from '../harness/control-inbox.js';
|
|
69
70
|
import { debug } from '../debug/log.js';
|
|
71
|
+
import { releasePathHold, releasePathHoldComment, RELEASE_PATH_LABEL } from '../self-dev/release-path-guard.js';
|
|
70
72
|
import { emitDecision } from '../live/detail-switch.js';
|
|
71
73
|
import { reworkDecision } from './decision-events.js';
|
|
72
74
|
import type { LogSink } from '../mss/logging/sink.js';
|
|
@@ -93,10 +95,10 @@ import { originObservationFields } from '../agent/origin-observation.js';
|
|
|
93
95
|
import { getHarnessSpace, normalizeSpaceId, resolveRunIdentity } from '../harness/harness-space.js';
|
|
94
96
|
import { getElanousConfigDir } from '../elanous-config-dir.js';
|
|
95
97
|
import { elanousStateRoot } from '../autopilot/state-paths.js';
|
|
96
|
-
import { harnessReleaseNote, releaseNotesDir, renderReleaseNoteSection, writeReleaseNote, type ReleaseNoteFragment } from '../release-loop/release-note.js';
|
|
98
|
+
import { addNextMdReleaseNote, harnessReleaseNote, parseReleaseNoteSection, releaseNotesDir, renderReleaseNoteSection, writeReleaseNote, type ReleaseNoteFragment, type ReleaseNoteSection } from '../release-loop/release-note.js';
|
|
97
99
|
import { plannedSelfImplBranch } from '../harness/worktree-branch-prefix.js';
|
|
98
100
|
export { slugifyFeature } from '../harness/worktree-branch-prefix.js';
|
|
99
|
-
import { resolveAutoReviewLabels } from './context-capsule.js';
|
|
101
|
+
import { AUTO_REVIEW_LABEL, resolveAutoReviewLabels } from './context-capsule.js';
|
|
100
102
|
import { GOAL_TYPES, extractVerbatimOriginalAsk, leadingGoalMetadata, parseAskFile, parseGoalType, type GoalType } from './goal-author.js';
|
|
101
103
|
import { resolveAdaptiveMaxReworkDecision, resolveEscalateTier, resolveEscalateTarget, buildReworkFeature, failIndicator, isRepeatedUnverifiedOnlyGateFailure, unverifiedRepeatKey, appendReworkHistory, truncateReworkHistoryByItem, applyReworkBudgetDecision, parseContractConflictRelaxation, parseReworkBudgetDecision, resolveReworkBudgetCarry, stripReworkBudgetHeaders, countConsecutiveMustFixIds, mergeReworkNotes, resolveReworkKind, type ReworkPlanRevision, type ReworkNotePart } from './rework-policy.js';
|
|
102
104
|
import type { SupervisionReworkSource } from './supervision-vocabulary.js';
|
|
@@ -178,6 +180,8 @@ import type { EscalateTier } from './rework-policy.js';
|
|
|
178
180
|
import type { ClassifyShadowCallLLM } from './classify-shadow.js';
|
|
179
181
|
import { hasModuleLoadFailure, type GateTestFailure } from './gate-baseline.js';
|
|
180
182
|
import { commitWorktree, defaultBranchRef } from './seams.js';
|
|
183
|
+
import { detectUncommittedWork } from './uncommitted-work.js';
|
|
184
|
+
import { spawnSync } from 'node:child_process';
|
|
181
185
|
import { blockedDraftDisposition } from './blocked-draft-policy.js';
|
|
182
186
|
import { formatLlmMergeOutcome } from '../autopilot/build/llm-conflict-merge.js';
|
|
183
187
|
import { FOUND_CITED_PATH_REFUTATION_QUOTE, MISSING_CITED_PATH_REFUTATION_QUOTE, MUST_FIX_REFUTATION_ACKNOWLEDGEMENT_WITH_REASON, REFUTATION_QUOTE_GRAMMAR, observeMustFixCitedPaths, parseMustFixRefutationAcknowledgement, parseMustFixRefutations, renderMustFixCitedPathFacts, snapshotMustFixFindings, stableMustFixId, type ReflectEvidenceFacts, type ReflectGateFacts, type MustFixCitedPathFact, type MustFixFinding, type MustFixRecurrenceHistory, type MustFixRefutation, type MustFixRefutationKind } from './reflect-mustfix.js';
|
|
@@ -871,6 +875,8 @@ export type ImplementTerminalStatus = {
|
|
|
871
875
|
export interface SelfImplementSeams {
|
|
872
876
|
/** Run-observer ledger sink. Tests inject an in-memory sink to avoid touching user state. */
|
|
873
877
|
writeRunLedger?: RunLedgerWriter;
|
|
878
|
+
/** Optional context-journal sink for isolated runs. */
|
|
879
|
+
emitContextEvent?: (input: SessionEventInput) => void;
|
|
874
880
|
/** Registers this run as an ephemeral loop-agent asset; failures are observed but never affect execution. */
|
|
875
881
|
registerLoopAgent?: (input: LoopAgentInput) => void;
|
|
876
882
|
/** Wraps implementation and gate promises with their effective wall-clock timeout; tests observe the actual stage budgets. */
|
|
@@ -935,6 +941,10 @@ export interface SelfImplementSeams {
|
|
|
935
941
|
* PR 直前 main-싱크 전에 impl 변경을 먼저 커밋). 기본=commitWorktree. 미주입 시 G2 pre-PR 싱크 skip(fail-safe).
|
|
936
942
|
* [[ROADMAP-elanous-is-all-pty-unified-autonomy-2026-07-21]] G2. */
|
|
937
943
|
commitWork?: (cwd: string, message: string) => void;
|
|
944
|
+
/** Observe a finished child's uncommitted work before classifying a missing diff. */
|
|
945
|
+
detectUncommittedWork?: typeof detectUncommittedWork;
|
|
946
|
+
/** Commit only the measured, eligible target paths. An injected seam preserves the same path boundary. */
|
|
947
|
+
commitFinishedChildWork?: (cwd: string, paths: readonly string[], message: string) => { ok: boolean; out: string };
|
|
938
948
|
/** --ground 코드베이스 prepass seam. cwd는 구현 대상 worktree이며 실패는 goal-loop를 막지 않는다. */
|
|
939
949
|
groundGoal?: (goalText: string, deps: { cwd: string }) => Promise<string>;
|
|
940
950
|
/** ③ 구현 — cwd(worktree)에서 코딩 에이전트 구동(P1: 헤드리스 elanous spawn·goal-loop 아밍).
|
|
@@ -1010,6 +1020,8 @@ export interface SelfImplementSeams {
|
|
|
1010
1020
|
openPr: (opts: { title: string; body: string; head: string; base?: string; draft?: boolean; labels?: string[]; cwd: string }) => Promise<{ url: string; number: number }>;
|
|
1011
1021
|
/** PR 생성 뒤 런의 라운드 대화를 게시한다. 실패는 PR 개설을 되돌리지 않는다. */
|
|
1012
1022
|
postPrComment?: (opts: { number: number; body: string; cwd: string }) => Promise<void>;
|
|
1023
|
+
addPrLabel?: (opts: { number: number; label: string; cwd: string }) => Promise<void>;
|
|
1024
|
+
readPrFiles?: (opts: { number: number; cwd: string }) => Promise<string[]>;
|
|
1013
1025
|
/** PR의 base/head SHA와 관측된 PR base를 한 응답에서 고정한다. 미주입·실패·빈 SHA면 검사 대상을 증명할 수 없어 fail-closed로 PR을 열어 둔다. */
|
|
1014
1026
|
readPrCommitShas?: (opts: { number: number; cwd: string }) => Promise<{ baseCommit: string; headCommit: string; baseRefName?: string }>;
|
|
1015
1027
|
/** 고정한 base/head SHA 쌍의 unified diff. 가변 PR 조회를 다시 사용하면 ABA head 변경에 안전하지 않으므로 두 SHA는 필수 입력이다. */
|
|
@@ -1948,6 +1960,8 @@ export interface SelfImplementOptions {
|
|
|
1948
1960
|
onNodeEntry?: (node: PipelineNodeId, round: number) => void;
|
|
1949
1961
|
/** 시험이 런치 오버레이를 빼 «지금 YAML 예산»을 읽게 할 때 쓴다. 생략하면 디스크 오버레이다. */
|
|
1950
1962
|
graphOverlays?: readonly GraphOverlaySpec[];
|
|
1963
|
+
/** Validated, run-local graph variant injected at launch; rejected plans never start the pipeline. */
|
|
1964
|
+
graphVariantPlan?: import('./graph-variant.js').GraphVariantPlan;
|
|
1951
1965
|
/** ★ K run-identity — 이 self-implement 호출의 per-run join anchor. 미지정 시 상속(env)→canonical mint.
|
|
1952
1966
|
* 리워크 라운드 전부가 이 값을 공유한다(`elanous self run <runId>` 가 호출 전체를 조인). */
|
|
1953
1967
|
runId?: string;
|
|
@@ -2510,8 +2524,40 @@ function goalDocumentForReleaseNote(goalFile?: string): string {
|
|
|
2510
2524
|
catch { return ''; }
|
|
2511
2525
|
}
|
|
2512
2526
|
|
|
2527
|
+
function shardReleaseNote(feature: string): ReleaseNoteSection | undefined {
|
|
2528
|
+
const matches = [...feature.matchAll(/^## Shard identity\r?\n([^\r\n]+)/gm)];
|
|
2529
|
+
const identity = matches.at(-1)?.[1];
|
|
2530
|
+
if (!identity) return undefined;
|
|
2531
|
+
try {
|
|
2532
|
+
const value: unknown = JSON.parse(identity);
|
|
2533
|
+
if (!value || typeof value !== 'object' || !('releaseNote' in value)) return undefined;
|
|
2534
|
+
const note = (value as { releaseNote: unknown }).releaseNote;
|
|
2535
|
+
if (!note || typeof note !== 'object' || Array.isArray(note)) return undefined;
|
|
2536
|
+
const candidate = note as Record<string, unknown>;
|
|
2537
|
+
if (typeof candidate.line !== 'string' || typeof candidate.kind !== 'string'
|
|
2538
|
+
|| typeof candidate.target !== 'string' || !candidate.docs || typeof candidate.docs !== 'object') return undefined;
|
|
2539
|
+
const doc = candidate.docs as Record<string, unknown>;
|
|
2540
|
+
if (typeof doc.path !== 'string' && typeof doc.none !== 'string') return undefined;
|
|
2541
|
+
const section = `## 릴리스 노트\n- 한 줄: ${candidate.line}\n- 종류: ${candidate.kind}\n- 문서: ${typeof doc.path === 'string' ? doc.path : `없음(${doc.none})`}\n- 대상: ${candidate.target}\n`;
|
|
2542
|
+
return parseReleaseNoteSection(section).fragment;
|
|
2543
|
+
} catch { return undefined; }
|
|
2544
|
+
}
|
|
2545
|
+
|
|
2546
|
+
function releaseNoteForRun(goalFile: string | undefined, feature: string): ReleaseNoteSection {
|
|
2547
|
+
const note = goalFile ? undefined : shardReleaseNote(feature);
|
|
2548
|
+
if (note) return note;
|
|
2549
|
+
const shard = !goalFile && feature.includes('## Shard identity');
|
|
2550
|
+
return harnessReleaseNote(goalDocumentForReleaseNote(goalFile), prTitle(feature), shard);
|
|
2551
|
+
}
|
|
2552
|
+
|
|
2553
|
+
/** GATE-CALLERS (OP 10-03): caller tests that exceeded the gate cap must stay visible in the PR body even when the gate log is cut. */
|
|
2554
|
+
export function gateNotRunSection(gateLog?: string): string[] {
|
|
2555
|
+
const lines = (gateLog ?? '').split('\n').filter((line) => line.startsWith('⚠️ caller test cap exceeded'));
|
|
2556
|
+
return lines.length ? ['', '## Gate · 안 돈 소비자 시험(상한 초과)', ...lines.map((line) => `- ${line.replace(/^⚠️ caller test cap exceeded — not run: /, '')}`)] : [];
|
|
2557
|
+
}
|
|
2558
|
+
|
|
2513
2559
|
function prBody(feature: string, implSummary: string, gateLog?: string, review?: SelfImplementReview, reviewIntent?: string, autoReviewDeclineReasons?: readonly string[], evidence?: string, goalFile?: string, planRevision?: ReworkPlanRevision, releaseNote?: ReturnType<typeof harnessReleaseNote>): string {
|
|
2514
|
-
const note = releaseNote ??
|
|
2560
|
+
const note = releaseNote ?? releaseNoteForRun(goalFile, feature);
|
|
2515
2561
|
const relaxation = planRevision?.relaxation
|
|
2516
2562
|
? ['', '## 감독 수용 기준 완화', `- 대상: ${planRevision.relaxation.target}`, `- 이전: ${planRevision.relaxation.expected}`, `- 완화: ${planRevision.relaxation.replacement}`, `- 이유: ${planRevision.reason}`, `- 적용: ${planRevision.application?.status ?? 'failed'}${planRevision.application?.detail ? ` (${planRevision.application.detail})` : ''}`, ...(planRevision.disposition ? [`- 충돌 처분: ${planRevision.disposition}`] : [])]
|
|
2517
2563
|
: [];
|
|
@@ -2530,6 +2576,7 @@ function prBody(feature: string, implSummary: string, gateLog?: string, review?:
|
|
|
2530
2576
|
...(review ? ['', `## 내부 리뷰 — ${review.verdict}`, review.summary.trim().slice(0, 1500),
|
|
2531
2577
|
...(review.shouldFix.length ? ['', '**should-fix (비블로킹):**', ...review.shouldFix.slice(0, 8).map((f) => `- ${f}`)] : [])] : []),
|
|
2532
2578
|
...(autoReviewDeclineReasons?.length ? ['', '## Auto-review label not applied', 'The requested auto-review label was declined by the autonomy gate:', ...autoReviewDeclineReasons.map((reason) => `- ${reason}`)] : []),
|
|
2579
|
+
...gateNotRunSection(gateLog),
|
|
2533
2580
|
...(gateLog ? ['', '## Gate', '```', gateLog.trim().slice(0, 3000), '```'] : []),
|
|
2534
2581
|
...relaxation,
|
|
2535
2582
|
'',
|
|
@@ -3340,6 +3387,16 @@ export async function runSelfImplement(opts: SelfImplementOptions): Promise<Self
|
|
|
3340
3387
|
detail: 'observe-only: SelfImplement execution skipped before child boot',
|
|
3341
3388
|
};
|
|
3342
3389
|
}
|
|
3390
|
+
const emitContext = (kind: 'task-claimed' | 'task-done', text: string, pr?: number): void => {
|
|
3391
|
+
try {
|
|
3392
|
+
(opts.seams.emitContextEvent ?? emitSessionEvent)({ kind, seat: 'TC', text,
|
|
3393
|
+
ref: `runId=${runId}${pr === undefined ? '' : ` PR=#${pr}`}` });
|
|
3394
|
+
} catch (error) {
|
|
3395
|
+
try { logRunAwareFailSoft(runId, 'context-event-failed', { kind, error: safeErrorDescription(error) }); }
|
|
3396
|
+
catch { /* context publication never changes the run result */ }
|
|
3397
|
+
}
|
|
3398
|
+
};
|
|
3399
|
+
emitContext('task-claimed', `Self-implement claimed: ${opts.feature.split(/\r?\n/, 1)[0]}`);
|
|
3343
3400
|
const parentHarnessSpaceId = getHarnessSpace()?.id || undefined;
|
|
3344
3401
|
const configRoot = getElanousConfigDir() || undefined;
|
|
3345
3402
|
const stateRoot = elanousStateRoot() || undefined;
|
|
@@ -4047,6 +4104,8 @@ export async function runSelfImplement(opts: SelfImplementOptions): Promise<Self
|
|
|
4047
4104
|
}, { level: 'warn' });
|
|
4048
4105
|
} catch { /* fail-soft — 종결 기록 실패가 원래 예외를 덮으면 안 된다 */ }
|
|
4049
4106
|
}
|
|
4107
|
+
emitContext('task-done', `Self-implement ${terminalResult?.stage ?? 'crashed'}: ${opts.feature.split(/\r?\n/, 1)[0]}`,
|
|
4108
|
+
terminalResult?.prNumber ?? capturedPrNumber);
|
|
4050
4109
|
finalizeTraversal();
|
|
4051
4110
|
try { unregisterProviderErrorSink(); } catch { /* fail-soft — cleanup must not change the terminal result */ }
|
|
4052
4111
|
}
|
|
@@ -4453,6 +4512,51 @@ async function runSelfImplementInner(
|
|
|
4453
4512
|
// ⛔⭐ `let` 인 이유는 ③ «다이나믹»이다 — 라운드마다 runtime 오버레이가 «앞을 보는 것»만 바꾼다.
|
|
4454
4513
|
// ⛔ 지난 노드를 재정의하지 않는다(RFC §6: 그러면 원장을 사후에 해석할 수 없다).
|
|
4455
4514
|
let graphTemplate = graphDecision.template;
|
|
4515
|
+
let variantSpec: import('./graph-yaml.js').GraphTemplateSpec | undefined;
|
|
4516
|
+
if (opts.graphVariantPlan !== undefined) {
|
|
4517
|
+
const { GRAPH_SPECS, specToTemplate } = await import('./graph-templates.js');
|
|
4518
|
+
const { graphVersionHash } = await import('./graph-yaml.js');
|
|
4519
|
+
const { applyGraphOverlays } = await import('./graph-overlay-yaml.js');
|
|
4520
|
+
const { createGraphVariant } = await import('./graph-variant.js');
|
|
4521
|
+
const { runLedgerPath } = await import('./run-ledger.js');
|
|
4522
|
+
const { stringify } = await import('yaml');
|
|
4523
|
+
const baseSpec = GRAPH_SPECS[graphTemplate.graphId];
|
|
4524
|
+
const variantRunId = identity?.runId ?? opts.runId;
|
|
4525
|
+
if (!baseSpec || !variantRunId || graphDecision.rejections.length) {
|
|
4526
|
+
throw new Error('graph variant rejected: missing graph specification, run identity, or valid launch overlay');
|
|
4527
|
+
}
|
|
4528
|
+
const launch = graphDecision.appliedIds.length
|
|
4529
|
+
? applyGraphOverlays(baseSpec, graphOverlays.filter(overlay => graphDecision.appliedIds.includes(overlay.overlayId)))
|
|
4530
|
+
: undefined;
|
|
4531
|
+
if (launch && !launch.ok) throw new Error(`graph variant rejected: ${JSON.stringify(launch.rejections)}`);
|
|
4532
|
+
const sourceSpec = launch?.ok ? launch.template : baseSpec;
|
|
4533
|
+
const variant = createGraphVariant({ template: sourceSpec, goal: `g_${variantRunId.replace(/[^a-z0-9_-]/gi, '_')}`, plan: opts.graphVariantPlan });
|
|
4534
|
+
if (!variant.ok) throw new Error(`graph variant rejected: ${JSON.stringify(variant.rejections)}`);
|
|
4535
|
+
variantSpec = variant.template;
|
|
4536
|
+
graphTemplate = { ...specToTemplate(variantSpec), version: graphVersionHash(variantSpec) };
|
|
4537
|
+
const { runLedgerDir } = await import('./run-ledger.js');
|
|
4538
|
+
const graphFile = `${runLedgerPath(variantRunId)}.graph.yaml`;
|
|
4539
|
+
mkdirSync(runLedgerDir(), { recursive: true });
|
|
4540
|
+
const { writeFileSync } = await import('node:fs');
|
|
4541
|
+
writeFileSync(graphFile, stringify({
|
|
4542
|
+
graph_id: variantSpec.graphId, version: variantSpec.version,
|
|
4543
|
+
entry_node: variantSpec.entryNode, terminal_nodes: variantSpec.terminalNodes,
|
|
4544
|
+
...(variantSpec.runContract ? { run_contract: variantSpec.runContract } : {}),
|
|
4545
|
+
nodes: variantSpec.nodes.map(n => ({
|
|
4546
|
+
node_id: n.nodeId, kind: n.kind, recipe: n.recipe, max_visits: n.maxVisits,
|
|
4547
|
+
...(n.progress ? { progress: n.progress } : {}), ...(n.phases ? { phases: n.phases } : {}),
|
|
4548
|
+
...(n.terminalStages ? { terminal_stages: n.terminalStages } : {}),
|
|
4549
|
+
...(n.fanOut ? { fan_out: n.fanOut } : {}), ...(n.contract ? { contract: n.contract } : {}),
|
|
4550
|
+
})),
|
|
4551
|
+
edges: variantSpec.edges.map(e => ({
|
|
4552
|
+
from: e.from, ...(e.to === undefined ? { on: e.on, map: e.map } : { to: e.to }),
|
|
4553
|
+
...(e.fallback ? { fallback: e.fallback } : {}),
|
|
4554
|
+
...(e.observed === undefined ? {} : { observed: e.observed }),
|
|
4555
|
+
})),
|
|
4556
|
+
}), { flag: 'wx' });
|
|
4557
|
+
observe('graph-variant-applied', { graphId: variant.template.graphId, overlayId: variant.overlay.overlayId,
|
|
4558
|
+
graphFile, patches: variant.patches });
|
|
4559
|
+
}
|
|
4456
4560
|
/** 단계 이름 → 그 템플릿의 노드 이름. */
|
|
4457
4561
|
const node = (stage: PipelineNodeId): PipelineNodeId => nodeNameForStage(stage, graphTemplate) as PipelineNodeId;
|
|
4458
4562
|
// ⛔⭐ 맥락이 정해진 «직후» 관측기에 심는다 — 이 줄이 없으면 걸음은 YAML 을 따르고 «신원은 안 따른다».
|
|
@@ -4485,6 +4589,7 @@ async function runSelfImplementInner(
|
|
|
4485
4589
|
overlays: graphOverlays,
|
|
4486
4590
|
state: runtimeOverlayState,
|
|
4487
4591
|
stage: 'runtime',
|
|
4592
|
+
...(variantSpec ? { specs: { [variantSpec.graphId]: variantSpec } } : {}),
|
|
4488
4593
|
});
|
|
4489
4594
|
if (decision.appliedIds.length > 0) graphTemplate = decision.template;
|
|
4490
4595
|
// ⛔⭐ 승격이 켜져 있으면 «언제나» 낸다 — 후보가 0이어도 낸다.
|
|
@@ -5171,6 +5276,9 @@ async function runSelfImplementInner(
|
|
|
5171
5276
|
cachedQuotaExhaustionAssessment ??= readQuotaExhausted(s.inspectCodexRotation, runProviderName);
|
|
5172
5277
|
return cachedQuotaExhaustionAssessment;
|
|
5173
5278
|
};
|
|
5279
|
+
let finishedChildCommitMissing = false;
|
|
5280
|
+
let finishedChildCommitFailure: string | undefined;
|
|
5281
|
+
let finishedChildCommitted = false;
|
|
5174
5282
|
const classifyUnfinishedRun = (stage: SelfImplementStage, verdict?: ReworkBudgetVerdict, decomposition?: TerminalDecomposition): AbandonedClassificationResult => {
|
|
5175
5283
|
const quotaExhaustionAssessment = quotaExhaustionAssessmentForRun();
|
|
5176
5284
|
const worktree = unfinishedWorktreeObservation(wt.path);
|
|
@@ -5183,7 +5291,7 @@ async function runSelfImplementInner(
|
|
|
5183
5291
|
...(hasCurrentProviderError() && providerErrorCategory() ? { providerErrorCategory: providerErrorCategory() } : {}),
|
|
5184
5292
|
worktreePorcelain: worktree.worktreePorcelain,
|
|
5185
5293
|
...(worktree.gitResidue ? { gitResidue: worktree.gitResidue } : {}),
|
|
5186
|
-
...(impl.completionDisposition ? { completionDisposition: impl.completionDisposition } : {}),
|
|
5294
|
+
...(!finishedChildCommitMissing && !finishedChildCommitted && impl.completionDisposition ? { completionDisposition: impl.completionDisposition } : {}),
|
|
5187
5295
|
...(verdict ? { supervisorVerdict: verdict } : lastSupervisorVerdict ? { supervisorVerdict: lastSupervisorVerdict } : {}),
|
|
5188
5296
|
...(hasMultipleStructuredTerminalPieces(decomposition ?? terminalDecomposition) ? { goalCauseObserved: true } : {}),
|
|
5189
5297
|
stage,
|
|
@@ -5502,8 +5610,12 @@ async function runSelfImplementInner(
|
|
|
5502
5610
|
return { decision };
|
|
5503
5611
|
}
|
|
5504
5612
|
const followUpMustFix = `\n\n## Follow-up must-fix (${decision.unresolvedMustFix.length})\n${decision.unresolvedMustFix.map((finding) => `- ${finding}`).join('\n')}`;
|
|
5613
|
+
const releaseNote = releaseNoteForRun(opts.goalFile, opts.feature);
|
|
5614
|
+
// openPr's default seam delegates to PrManager.upsertPr, which stages, commits,
|
|
5615
|
+
// and pushes this worktree after the note is written and before creating the PR.
|
|
5616
|
+
addNextMdReleaseNote(wt.path, releaseNote);
|
|
5505
5617
|
const preparedPrBody = preparePrBody(
|
|
5506
|
-
`${prBody(opts.feature, impl.summary, gate.log, review, reviewIntent, undefined, harvestedForPr(), opts.goalFile, lastPlanRevision)}${followUpMustFix}`,
|
|
5618
|
+
`${prBody(opts.feature, impl.summary, gate.log, review, reviewIntent, undefined, harvestedForPr(), opts.goalFile, lastPlanRevision, releaseNote)}${followUpMustFix}`,
|
|
5507
5619
|
s.persistPrBodyArtifact,
|
|
5508
5620
|
'self-implement-review-budget-pr',
|
|
5509
5621
|
followUpMustFix,
|
|
@@ -6160,6 +6272,76 @@ async function runSelfImplementInner(
|
|
|
6160
6272
|
// ⭐ 성공 경로에서도 닫는다 — 이 호출은 끝났고, 이후 자식이 늦게 보내는 입력은
|
|
6161
6273
|
// 「이 라운드의 재투입」이 아니다(다음 라운드는 자기 콜백을 새로 만든다).
|
|
6162
6274
|
closeSupervisorInput();
|
|
6275
|
+
// A finished child can leave edits without a commit. Measure them before any
|
|
6276
|
+
// diff/no-changes classification, and commit only paths declared in the goal.
|
|
6277
|
+
finishedChildCommitMissing = false;
|
|
6278
|
+
finishedChildCommitFailure = undefined;
|
|
6279
|
+
finishedChildCommitted = false;
|
|
6280
|
+
if (impl.ok) {
|
|
6281
|
+
const work = (s.detectUncommittedWork ?? detectUncommittedWork)(wt.path);
|
|
6282
|
+
if (work.status === 'unavailable') {
|
|
6283
|
+
// Fail closed when the branch already carries commits: a PR could open without knowing whether the
|
|
6284
|
+
// goal's changes were committed (HARV1 review round 3). With no commits, the no-changes path decides.
|
|
6285
|
+
let branchFiles: readonly string[] | undefined;
|
|
6286
|
+
try { branchFiles = (s.changedFilesForGateRoute ?? changedFiles)(wt.path); } catch { branchFiles = undefined; }
|
|
6287
|
+
// Only a run that would open a PR needs the block — worktree-only completion opens none.
|
|
6288
|
+
// A path that isn't a git worktree at all (no .git) has nothing to open a PR from — only real worktrees block.
|
|
6289
|
+
const blocks = opts.completion !== 'worktree-only' && existsSync(join(wt.path, '.git'))
|
|
6290
|
+
&& (branchFiles === undefined || branchFiles.length > 0);
|
|
6291
|
+
if (blocks) {
|
|
6292
|
+
finishedChildCommitMissing = true;
|
|
6293
|
+
finishedChildCommitFailure = `working tree status unavailable: ${work.reason ?? 'unknown'}`;
|
|
6294
|
+
}
|
|
6295
|
+
observe('finished-child-commit', { round, status: 'unavailable', reason: work.reason, blocked: blocks }, { level: 'warn' });
|
|
6296
|
+
} else if (work.status === 'changes') {
|
|
6297
|
+
let goalDocument: string | undefined;
|
|
6298
|
+
if (opts.goalFile) {
|
|
6299
|
+
try { goalDocument = readFileSync(opts.goalFile, 'utf8'); } catch { /* no declared scope */ }
|
|
6300
|
+
}
|
|
6301
|
+
const declared = goalDocument === undefined ? undefined : declaredPathsFromGoalDocumentText(goalDocument);
|
|
6302
|
+
const targets = declared?.readable
|
|
6303
|
+
? declared.paths
|
|
6304
|
+
: inferHotPaths(targetScopedGoalText(opts.feature));
|
|
6305
|
+
const eligible = [...new Set([...work.trackedChanges, ...work.untrackedFiles])]
|
|
6306
|
+
.filter((path) => !harnessSeededPaths.includes(path)
|
|
6307
|
+
&& targets.some((target) => changedFileIsInsideDeclaredTarget(path, target)));
|
|
6308
|
+
if (eligible.length) {
|
|
6309
|
+
const message = `self-implement: ${prTitle(opts.feature)}`;
|
|
6310
|
+
let outcome: { ok: boolean; out: string };
|
|
6311
|
+
try {
|
|
6312
|
+
outcome = (s.commitFinishedChildWork ?? ((cwd, paths, title) => {
|
|
6313
|
+
const env = { ...process.env };
|
|
6314
|
+
for (const key of Object.keys(env)) if (key.startsWith('GIT_')) delete env[key];
|
|
6315
|
+
const childName = `elanous child ${runId}`;
|
|
6316
|
+
const childEmail = `child+${runId.replace(/[^a-zA-Z0-9-]/g, '')}@elanous.local`;
|
|
6317
|
+
env.GIT_AUTHOR_NAME = childName;
|
|
6318
|
+
env.GIT_AUTHOR_EMAIL = childEmail;
|
|
6319
|
+
env.GIT_COMMITTER_NAME = childName;
|
|
6320
|
+
env.GIT_COMMITTER_EMAIL = childEmail;
|
|
6321
|
+
const git = (args: string[]) => spawnSync('git', ['--no-optional-locks', ...args], {
|
|
6322
|
+
cwd, env, encoding: 'utf8', timeout: 20_000,
|
|
6323
|
+
});
|
|
6324
|
+
const staged = git(['add', '-A', '--', ...paths]);
|
|
6325
|
+
if (staged.status !== 0) return { ok: false, out: staged.stderr || staged.stdout || staged.error?.message || 'git add failed' };
|
|
6326
|
+
// --only commits these paths even when unrelated edits were staged before the child finished.
|
|
6327
|
+
const commit = git(['commit', '-m', title, '--only', '--', ...paths]);
|
|
6328
|
+
return { ok: commit.status === 0, out: commit.stderr || commit.stdout || commit.error?.message || '' };
|
|
6329
|
+
}))(wt.path, eligible, message);
|
|
6330
|
+
} catch (error) {
|
|
6331
|
+
outcome = { ok: false, out: safeErrorDescription(error) };
|
|
6332
|
+
}
|
|
6333
|
+
finishedChildCommitMissing = !outcome.ok;
|
|
6334
|
+
finishedChildCommitFailure = outcome.ok ? undefined : outcome.out;
|
|
6335
|
+
finishedChildCommitted = outcome.ok;
|
|
6336
|
+
observe('finished-child-commit', {
|
|
6337
|
+
round, status: outcome.ok ? 'committed' : 'commit-missing', paths: eligible,
|
|
6338
|
+
...(outcome.ok ? {} : { reason: outcome.out.slice(0, 500) }),
|
|
6339
|
+
}, outcome.ok ? {} : { level: 'warn' });
|
|
6340
|
+
} else {
|
|
6341
|
+
observe('finished-child-commit', { round, status: 'out-of-scope' });
|
|
6342
|
+
}
|
|
6343
|
+
}
|
|
6344
|
+
}
|
|
6163
6345
|
// ⭐ S3 — 자식 요약에서 diff 밖 이행 주장을 분류한다(자식 반환 계약은 그대로 둔다).
|
|
6164
6346
|
// ⛔ 버린 것을 **세어서** 남긴다 — 조용히 버리면 관측값이 항상 0이 되어 거짓 초록이 된다.
|
|
6165
6347
|
// ★ I-9/RUN-T6 — 꼬리 2000자가 아니라 **수확본**에서 판다. 자식이 먼저 돌린 tsc·뮤테이션 출력이
|
|
@@ -6242,9 +6424,10 @@ async function runSelfImplementInner(
|
|
|
6242
6424
|
orphanResult: offDiffEvidence.orphanResult,
|
|
6243
6425
|
...harvestObs,
|
|
6244
6426
|
}, { compact: { stringMax: Math.max(MAX_HARVESTED_EVIDENCE_CHARS, harvestObs.harvestedEvidence?.length ?? 0) } });
|
|
6245
|
-
|
|
6427
|
+
if (impl.ok) completionDisposition = finishedChildCommitMissing || finishedChildCommitted ? undefined : impl.completionDisposition;
|
|
6428
|
+
const effectiveDisposition = impl.ok ? completionDisposition : impl.completionDisposition;
|
|
6429
|
+
observe('implemented', { ok: impl.ok, round, ...(effectiveDisposition ? { completionDisposition: effectiveDisposition } : {}) });
|
|
6246
6430
|
progress('implemented', impl.ok ? (round === 0 ? '구현 완료' : `rework ${round} 완료`) : impl.completionDisposition ? '변경 없이 완료 검증' : '구현 실패(worktree 보존)');
|
|
6247
|
-
if (impl.ok) completionDisposition = impl.completionDisposition;
|
|
6248
6431
|
if (!impl.ok) {
|
|
6249
6432
|
finalizeSupervisorDeliveries('next-round-implement-not-ok');
|
|
6250
6433
|
const abort = buildImplementAbortRecord(impl.summary, impl.terminalStatus);
|
|
@@ -6271,6 +6454,13 @@ async function runSelfImplementInner(
|
|
|
6271
6454
|
return { ok: false, stage: 'aborted', node: 'implement', ...resolveRunOutcome({ termination: 'abandoned' }), sessionId, worktreePath: wt.path, branch: wt.branch, quotaExhaustionAssessment: quotaExhaustionAssessmentForRun(), ...(impl.completionDisposition ? { completionDisposition: impl.completionDisposition } : {}), ...(pr ? { prUrl: pr.url, prNumber: pr.number } : {}), detail: impl.summary };
|
|
6272
6455
|
}
|
|
6273
6456
|
|
|
6457
|
+
if (finishedChildCommitMissing) {
|
|
6458
|
+
finalizeSupervisorDeliveries('finished-child-commit-missing');
|
|
6459
|
+
const detail = `finished child changes could not be committed: ${finishedChildCommitFailure ?? 'commit failed'}`;
|
|
6460
|
+
progress('aborted', detail);
|
|
6461
|
+
return { ok: false, stage: 'aborted', node: 'implement', ...resolveRunOutcome({ termination: 'abandoned' }), sessionId, worktreePath: wt.path, branch: wt.branch, detail };
|
|
6462
|
+
}
|
|
6463
|
+
|
|
6274
6464
|
// Measure the existing declared-target boundary after implementation, before gate/PR.
|
|
6275
6465
|
// Unknown declaration or changed files cannot justify an invented choice.
|
|
6276
6466
|
let gateRouteFiles: readonly string[] | undefined;
|
|
@@ -7073,7 +7263,10 @@ async function runSelfImplementInner(
|
|
|
7073
7263
|
...(prEvidenceDecision.reason ? { reason: prEvidenceDecision.reason } : {}),
|
|
7074
7264
|
...(prEvidenceDecision.body ? { bodyChars: prEvidenceDecision.body.length } : {}),
|
|
7075
7265
|
});
|
|
7076
|
-
const releaseNote =
|
|
7266
|
+
const releaseNote = releaseNoteForRun(opts.goalFile, opts.feature);
|
|
7267
|
+
// openPr's default seam delegates to PrManager.upsertPr, which stages, commits,
|
|
7268
|
+
// and pushes this worktree after the note is written and before creating the PR.
|
|
7269
|
+
addNextMdReleaseNote(wt.path, releaseNote);
|
|
7077
7270
|
const preparedPrBody = preparePrBody(
|
|
7078
7271
|
[
|
|
7079
7272
|
prBody(opts.feature, impl.summary, gate.log, review, reviewIntent, declineReasons, harvestedForPr(), opts.goalFile, lastPlanRevision, releaseNote),
|
|
@@ -7090,7 +7283,8 @@ async function runSelfImplementInner(
|
|
|
7090
7283
|
head: wt.branch,
|
|
7091
7284
|
...(opts.base ? { base: opts.base } : {}),
|
|
7092
7285
|
draft: canAuto ? false : (opts.draft ?? true),
|
|
7093
|
-
|
|
7286
|
+
// The review poller must not see this PR before its actual paths have been inspected.
|
|
7287
|
+
...(labels?.length ? { labels: labels.filter((label) => label !== AUTO_REVIEW_LABEL) } : {}),
|
|
7094
7288
|
cwd: wt.path,
|
|
7095
7289
|
}), T.pr, 'pr');
|
|
7096
7290
|
} catch (error) {
|
|
@@ -7116,6 +7310,60 @@ async function runSelfImplementInner(
|
|
|
7116
7310
|
});
|
|
7117
7311
|
await flushPrComments(pr);
|
|
7118
7312
|
|
|
7313
|
+
// Inspect the opened PR itself: the goal text and the pre-sync worktree can differ from its final file list.
|
|
7314
|
+
let releaseHoldPath: string | undefined;
|
|
7315
|
+
let releasePathInspectionError: string | undefined;
|
|
7316
|
+
if (s.readPrFiles) {
|
|
7317
|
+
try {
|
|
7318
|
+
const files = await withStepTimeout(s.readPrFiles({ number: pr.number, cwd: wt.path }), T.pr, 'pr');
|
|
7319
|
+
if (!Array.isArray(files) || !files.every((path) => typeof path === 'string')) throw new Error('invalid PR file list');
|
|
7320
|
+
releaseHoldPath = releasePathHold(files);
|
|
7321
|
+
} catch (error) {
|
|
7322
|
+
releasePathInspectionError = safeErrorDescription(error);
|
|
7323
|
+
}
|
|
7324
|
+
} else if (canAuto || labels?.includes(AUTO_REVIEW_LABEL)) {
|
|
7325
|
+
releasePathInspectionError = 'readPrFiles seam unavailable';
|
|
7326
|
+
}
|
|
7327
|
+
if (releaseHoldPath) {
|
|
7328
|
+
debug.log('self-dev.merge', 'release-path-hold', { number: pr.number, path: releaseHoldPath, label: RELEASE_PATH_LABEL });
|
|
7329
|
+
canAuto = false;
|
|
7330
|
+
mergeSkipReason = mergeReason = 'release-path-hold';
|
|
7331
|
+
// Suppress the independent auto-review poller as well as this immediate merge path.
|
|
7332
|
+
// No merge is attempted even when an annotation fails; each failure is observable for OP repair.
|
|
7333
|
+
for (const [action, annotate] of [
|
|
7334
|
+
['add-label', s.addPrLabel && (() => s.addPrLabel!({ number: pr.number, label: RELEASE_PATH_LABEL, cwd: wt.path }))],
|
|
7335
|
+
['comment', s.postPrComment && (() => s.postPrComment!({ number: pr.number, body: releasePathHoldComment(releaseHoldPath), cwd: wt.path }))],
|
|
7336
|
+
] as const) {
|
|
7337
|
+
if (!annotate) {
|
|
7338
|
+
observe('release-path-annotation-failed', { number: pr.number, path: releaseHoldPath, action, error: 'annotation seam unavailable' }, { level: 'error' });
|
|
7339
|
+
continue;
|
|
7340
|
+
}
|
|
7341
|
+
try { await annotate(); }
|
|
7342
|
+
catch (error) {
|
|
7343
|
+
observe('release-path-annotation-failed', { number: pr.number, path: releaseHoldPath, action, error: safeErrorDescription(error) }, { level: 'error' });
|
|
7344
|
+
}
|
|
7345
|
+
}
|
|
7346
|
+
recordMergeDecision();
|
|
7347
|
+
progress('pr-opened', `OP 승인 대기 (#${pr.number}): ${releaseHoldPath}`);
|
|
7348
|
+
return { ok: true, stage: 'pr-opened', node: 'open-pr', ...resolveRunOutcome({ termination: 'completed' }), ...decisionSignalResult, ...preservedCompletionResult, ...(completionStatus ? { completionStatus } : {}), sessionId, worktreePath: wt.path, branch: wt.branch, gate, ...(review ? { review } : {}), mergeReason, prUrl: pr.url, prNumber: pr.number, detail: `OP approval required: ${releaseHoldPath}` };
|
|
7349
|
+
}
|
|
7350
|
+
if (!releasePathInspectionError && labels?.includes(AUTO_REVIEW_LABEL)) {
|
|
7351
|
+
try {
|
|
7352
|
+
if (!s.addPrLabel) throw new Error('addPrLabel seam unavailable');
|
|
7353
|
+
await s.addPrLabel({ number: pr.number, label: AUTO_REVIEW_LABEL, cwd: wt.path });
|
|
7354
|
+
} catch (error) {
|
|
7355
|
+
observe('auto-review-label-failed', { number: pr.number, error: safeErrorDescription(error) }, { level: 'warn' });
|
|
7356
|
+
}
|
|
7357
|
+
}
|
|
7358
|
+
if (releasePathInspectionError && (canAuto || labels?.includes(AUTO_REVIEW_LABEL))) {
|
|
7359
|
+
observe('release-path-inspection-failed', { number: pr.number, error: releasePathInspectionError }, { level: 'error' });
|
|
7360
|
+
canAuto = false;
|
|
7361
|
+
mergeSkipReason = mergeReason = 'release-path-inspection-failed';
|
|
7362
|
+
recordMergeDecision();
|
|
7363
|
+
progress('pr-opened', `OP 승인 대기 (#${pr.number}): PR 경로 조회 실패`);
|
|
7364
|
+
return { ok: true, stage: 'pr-opened', node: 'open-pr', ...resolveRunOutcome({ termination: 'completed' }), ...decisionSignalResult, ...preservedCompletionResult, ...(completionStatus ? { completionStatus } : {}), sessionId, worktreePath: wt.path, branch: wt.branch, gate, ...(review ? { review } : {}), mergeReason, prUrl: pr.url, prNumber: pr.number };
|
|
7365
|
+
}
|
|
7366
|
+
|
|
7119
7367
|
if (canAuto && (s.mergePr || opts.mergeByHost)) {
|
|
7120
7368
|
let docsMarkdownDeletions: number | undefined;
|
|
7121
7369
|
let nonDocsMarkdownDeletions: number | undefined;
|