elanous 0.2.10 → 0.2.11
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/Y4zKzL62sakG5momz3SoQ/_buildManifest.js +1 -0
- package/apps/pwa/out/_next/static/chunks/1159-0c5ef8bc21cb6afb.js +1 -0
- package/apps/pwa/out/_next/static/chunks/1394-556de6d71bbdb0fb.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/2310-7a59f043f6db207e.js +1 -0
- package/apps/pwa/out/_next/static/chunks/2426.8c6ee0c668d53def.js +1 -0
- package/apps/pwa/out/_next/static/chunks/2548-6e316138d347cefe.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-a39d1d9921e10d43.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/507-5acd98bd6dab2d8a.js +1 -0
- package/apps/pwa/out/_next/static/chunks/5445-745eb795c5963d79.js +1 -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/{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/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-ea5bee9dfae512c7.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/app/_not-found/page-d16993889b125c42.js +1 -0
- package/apps/pwa/out/_next/static/chunks/app/approvals/page-1dcdc58fc2de2454.js +1 -0
- package/apps/pwa/out/_next/static/chunks/app/autopilot/page-6a061bd97f0b9398.js +1 -0
- package/apps/pwa/out/_next/static/chunks/app/board/page-cb95a7432c9ee744.js +1 -0
- package/apps/pwa/out/_next/static/chunks/app/botlab/{page-54b32bd27726588d.js → page-b12b6d2f8d2d1aea.js} +1 -1
- package/apps/pwa/out/_next/static/chunks/app/bots/page-b9efe868bfd36255.js +1 -0
- package/apps/pwa/out/_next/static/chunks/app/chat/page-7c97dcdfe2e37a60.js +1 -0
- package/apps/pwa/out/_next/static/chunks/app/consult/page-8fd36984f549270a.js +1 -0
- package/apps/pwa/out/_next/static/chunks/app/control/page-5721537ca8a3598c.js +1 -0
- package/apps/pwa/out/_next/static/chunks/app/design-check/page-b654240a572e4c48.js +1 -0
- package/apps/pwa/out/_next/static/chunks/app/editor/page-b9750abc897508c3.js +1 -0
- package/apps/pwa/out/_next/static/chunks/app/exec/page-4cd1de371f8ad048.js +1 -0
- package/apps/pwa/out/_next/static/chunks/app/field/page-d99f89657828421c.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-50cb2a0eb15e6c83.js +1 -0
- package/apps/pwa/out/_next/static/chunks/app/intake/page-c8b1ccda6ba7ae98.js +1 -0
- package/apps/pwa/out/_next/static/chunks/app/layout-d6b1d156fb95e74b.js +1 -0
- package/apps/pwa/out/_next/static/chunks/app/live/page-2a9932ddb62d76bd.js +1 -0
- package/apps/pwa/out/_next/static/chunks/app/market/page-9688f5b4f1ff950f.js +1 -0
- package/apps/pwa/out/_next/static/chunks/app/missions/[id]/page-6b15dd6456c5df09.js +1 -0
- package/apps/pwa/out/_next/static/chunks/app/morning/page-35414e0a007b4082.js +1 -0
- package/apps/pwa/out/_next/static/chunks/app/not-found-e7a529e0507ac86c.js +1 -0
- package/apps/pwa/out/_next/static/chunks/app/observatory/page-e001823c35c9dd67.js +1 -0
- package/apps/pwa/out/_next/static/chunks/app/ops/checklist/page-371423d1a573d64b.js +1 -0
- package/apps/pwa/out/_next/static/chunks/app/ops/release/page-4b764b125339ac17.js +1 -0
- package/apps/pwa/out/_next/static/chunks/app/ops/seats/page-cdf8e4b01067bcf1.js +1 -0
- package/apps/pwa/out/_next/static/chunks/app/outputs/page-3a24072b35470157.js +1 -0
- package/apps/pwa/out/_next/static/chunks/app/page-94c82eb0ae5abb32.js +1 -0
- package/apps/pwa/out/_next/static/chunks/app/reflection/page-0be8d4b2ced75ba0.js +1 -0
- package/apps/pwa/out/_next/static/chunks/app/scheduler/page-d37cb0d52f9b6bd5.js +1 -0
- package/apps/pwa/out/_next/static/chunks/app/sessions/page-686da0df9bf23e5c.js +1 -0
- package/apps/pwa/out/_next/static/chunks/app/settings/devices/page-4dc614f3ce043e63.js +1 -0
- package/apps/pwa/out/_next/static/chunks/app/settings/page-53f80edc6b8dc07c.js +1 -0
- package/apps/pwa/out/_next/static/chunks/app/setup/done/page-d02c782fc792e2af.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-239c17b911b84e72.js +1 -0
- package/apps/pwa/out/_next/static/chunks/app/share/page-dc6a79fb003f746c.js +1 -0
- package/apps/pwa/out/_next/static/chunks/app/showroom/page-0fffb84cafdc9da6.js +1 -0
- package/apps/pwa/out/_next/static/chunks/app/tasks/page-1218753c82d585f6.js +1 -0
- package/apps/pwa/out/_next/static/chunks/app/term/page-4b5935e67531efb5.js +1 -0
- package/apps/pwa/out/_next/static/chunks/app/today/page-3285bc87caf1eaa5.js +1 -0
- package/apps/pwa/out/_next/static/chunks/app/trace/page-ad553b0e06505ecd.js +1 -0
- package/apps/pwa/out/_next/static/chunks/app/vault/page-fca096e3e860306f.js +1 -0
- package/apps/pwa/out/_next/static/chunks/app/workflows/chat-ui/page-9ebfa78f0d9885c3.js +1 -0
- package/apps/pwa/out/_next/static/chunks/app/workflows/page-3dc5f21f7e39622d.js +1 -0
- package/apps/pwa/out/_next/static/chunks/app/workspace/page-c6da2b468454532d.js +1 -0
- package/apps/pwa/out/_next/static/chunks/app/worktrees/page-93bc70e36f595414.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/543f56bcb1f79fca.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/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/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/marketing/measure-site-numbers.ts +169 -0
- package/scripts/measure-gate-shards.ts +309 -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/cut-branch.ts +84 -0
- package/scripts/release-loop/gate-node.ts +14 -13
- package/scripts/release-loop/mac-smoke-node.ts +229 -0
- package/scripts/release-loop/node-verdict.ts +3 -3
- 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 +61 -10
- 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/test-diet/node.ts +1 -1
- package/scripts/tui-regress.ts +2 -2
- package/scripts/ux/demo-rehearsal.ts +243 -0
- package/scripts/ux/lib/rehearsal-verdict.ts +73 -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 +80 -10
- 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/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 +1 -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 +90 -4
- package/src/cli/plugin-cli.ts +31 -22
- package/src/cli/pod-cli.ts +19 -9
- 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 +17 -4
- 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 +48 -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/dashboard/index.ts +9 -4
- package/src/dashboard/slash-runtime/dashboard-handlers.ts +7 -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 +6 -1
- 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 +100 -0
- package/src/field/field-reel.ts +5 -1
- package/src/field-note/index.ts +201 -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 +37 -0
- package/src/graph-runner/graph-grow.ts +47 -0
- package/src/graph-runner/runner.ts +317 -25
- package/src/grok/agent-search.ts +8 -2
- package/src/guardian/secret-exposure-scan.ts +101 -0
- package/src/harness/harness-cli-command.ts +247 -7
- 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/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 +21 -20
- package/src/index.ts +52 -14
- package/src/intake-plane/categorize.ts +18 -46
- package/src/intake-plane/discord-seat-work.ts +10 -0
- 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-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 +26 -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 +36 -0
- 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/outputs-route.ts +44 -0
- 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/trace.ts +18 -6
- package/src/nexus/api/workflow-run-event-bridge.ts +1 -0
- package/src/nexus/api/workflows.ts +80 -6
- package/src/nexus/index.ts +2 -0
- package/src/nexus/kinds/webterm.ts +2 -1
- 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 +116 -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 +109 -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 +2 -2
- package/src/release-loop/feature-store.ts +5 -3
- 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 +548 -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 +38 -33
- package/src/self-dev/draft-triage-rules.ts +8 -5
- 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/gate-baseline.ts +1 -1
- package/src/self-implement/gate-cli.ts +40 -1
- package/src/self-implement/gate-scope.ts +37 -7
- 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 +22 -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 +242 -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 +1 -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 +29 -7
- 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 +214 -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 +10 -1
- package/src/telegram-project-command.ts +71 -0
- package/src/telegram-report.ts +21 -17
- package/src/telegram.ts +29 -3
- package/src/tool-runtime/self-cognition-runtimes.ts +13 -3
- package/src/user-config.ts +102 -20
- 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 → Y4zKzL62sakG5momz3SoQ}/_ssgManifest.js +0 -0
|
@@ -67,6 +67,7 @@ import { decideLineageSupersede, lineageSupersedeCloseComment, type LineageSuper
|
|
|
67
67
|
import { basename, isAbsolute, join, relative, resolve, sep } from 'node:path';
|
|
68
68
|
import { enqueueControlMemo, readSoftStopRequestStatus, type SoftStopRequestRead } from '../harness/control-inbox.js';
|
|
69
69
|
import { debug } from '../debug/log.js';
|
|
70
|
+
import { releasePathHold, releasePathHoldComment, RELEASE_PATH_LABEL } from '../self-dev/release-path-guard.js';
|
|
70
71
|
import { emitDecision } from '../live/detail-switch.js';
|
|
71
72
|
import { reworkDecision } from './decision-events.js';
|
|
72
73
|
import type { LogSink } from '../mss/logging/sink.js';
|
|
@@ -93,10 +94,10 @@ import { originObservationFields } from '../agent/origin-observation.js';
|
|
|
93
94
|
import { getHarnessSpace, normalizeSpaceId, resolveRunIdentity } from '../harness/harness-space.js';
|
|
94
95
|
import { getElanousConfigDir } from '../elanous-config-dir.js';
|
|
95
96
|
import { elanousStateRoot } from '../autopilot/state-paths.js';
|
|
96
|
-
import { harnessReleaseNote, releaseNotesDir, renderReleaseNoteSection, writeReleaseNote, type ReleaseNoteFragment } from '../release-loop/release-note.js';
|
|
97
|
+
import { addNextMdReleaseNote, harnessReleaseNote, parseReleaseNoteSection, releaseNotesDir, renderReleaseNoteSection, writeReleaseNote, type ReleaseNoteFragment, type ReleaseNoteSection } from '../release-loop/release-note.js';
|
|
97
98
|
import { plannedSelfImplBranch } from '../harness/worktree-branch-prefix.js';
|
|
98
99
|
export { slugifyFeature } from '../harness/worktree-branch-prefix.js';
|
|
99
|
-
import { resolveAutoReviewLabels } from './context-capsule.js';
|
|
100
|
+
import { AUTO_REVIEW_LABEL, resolveAutoReviewLabels } from './context-capsule.js';
|
|
100
101
|
import { GOAL_TYPES, extractVerbatimOriginalAsk, leadingGoalMetadata, parseAskFile, parseGoalType, type GoalType } from './goal-author.js';
|
|
101
102
|
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
103
|
import type { SupervisionReworkSource } from './supervision-vocabulary.js';
|
|
@@ -178,6 +179,8 @@ import type { EscalateTier } from './rework-policy.js';
|
|
|
178
179
|
import type { ClassifyShadowCallLLM } from './classify-shadow.js';
|
|
179
180
|
import { hasModuleLoadFailure, type GateTestFailure } from './gate-baseline.js';
|
|
180
181
|
import { commitWorktree, defaultBranchRef } from './seams.js';
|
|
182
|
+
import { detectUncommittedWork } from './uncommitted-work.js';
|
|
183
|
+
import { spawnSync } from 'node:child_process';
|
|
181
184
|
import { blockedDraftDisposition } from './blocked-draft-policy.js';
|
|
182
185
|
import { formatLlmMergeOutcome } from '../autopilot/build/llm-conflict-merge.js';
|
|
183
186
|
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';
|
|
@@ -935,6 +938,10 @@ export interface SelfImplementSeams {
|
|
|
935
938
|
* PR 直前 main-싱크 전에 impl 변경을 먼저 커밋). 기본=commitWorktree. 미주입 시 G2 pre-PR 싱크 skip(fail-safe).
|
|
936
939
|
* [[ROADMAP-elanous-is-all-pty-unified-autonomy-2026-07-21]] G2. */
|
|
937
940
|
commitWork?: (cwd: string, message: string) => void;
|
|
941
|
+
/** Observe a finished child's uncommitted work before classifying a missing diff. */
|
|
942
|
+
detectUncommittedWork?: typeof detectUncommittedWork;
|
|
943
|
+
/** Commit only the measured, eligible target paths. An injected seam preserves the same path boundary. */
|
|
944
|
+
commitFinishedChildWork?: (cwd: string, paths: readonly string[], message: string) => { ok: boolean; out: string };
|
|
938
945
|
/** --ground 코드베이스 prepass seam. cwd는 구현 대상 worktree이며 실패는 goal-loop를 막지 않는다. */
|
|
939
946
|
groundGoal?: (goalText: string, deps: { cwd: string }) => Promise<string>;
|
|
940
947
|
/** ③ 구현 — cwd(worktree)에서 코딩 에이전트 구동(P1: 헤드리스 elanous spawn·goal-loop 아밍).
|
|
@@ -1010,6 +1017,8 @@ export interface SelfImplementSeams {
|
|
|
1010
1017
|
openPr: (opts: { title: string; body: string; head: string; base?: string; draft?: boolean; labels?: string[]; cwd: string }) => Promise<{ url: string; number: number }>;
|
|
1011
1018
|
/** PR 생성 뒤 런의 라운드 대화를 게시한다. 실패는 PR 개설을 되돌리지 않는다. */
|
|
1012
1019
|
postPrComment?: (opts: { number: number; body: string; cwd: string }) => Promise<void>;
|
|
1020
|
+
addPrLabel?: (opts: { number: number; label: string; cwd: string }) => Promise<void>;
|
|
1021
|
+
readPrFiles?: (opts: { number: number; cwd: string }) => Promise<string[]>;
|
|
1013
1022
|
/** PR의 base/head SHA와 관측된 PR base를 한 응답에서 고정한다. 미주입·실패·빈 SHA면 검사 대상을 증명할 수 없어 fail-closed로 PR을 열어 둔다. */
|
|
1014
1023
|
readPrCommitShas?: (opts: { number: number; cwd: string }) => Promise<{ baseCommit: string; headCommit: string; baseRefName?: string }>;
|
|
1015
1024
|
/** 고정한 base/head SHA 쌍의 unified diff. 가변 PR 조회를 다시 사용하면 ABA head 변경에 안전하지 않으므로 두 SHA는 필수 입력이다. */
|
|
@@ -1948,6 +1957,8 @@ export interface SelfImplementOptions {
|
|
|
1948
1957
|
onNodeEntry?: (node: PipelineNodeId, round: number) => void;
|
|
1949
1958
|
/** 시험이 런치 오버레이를 빼 «지금 YAML 예산»을 읽게 할 때 쓴다. 생략하면 디스크 오버레이다. */
|
|
1950
1959
|
graphOverlays?: readonly GraphOverlaySpec[];
|
|
1960
|
+
/** Validated, run-local graph variant injected at launch; rejected plans never start the pipeline. */
|
|
1961
|
+
graphVariantPlan?: import('./graph-variant.js').GraphVariantPlan;
|
|
1951
1962
|
/** ★ K run-identity — 이 self-implement 호출의 per-run join anchor. 미지정 시 상속(env)→canonical mint.
|
|
1952
1963
|
* 리워크 라운드 전부가 이 값을 공유한다(`elanous self run <runId>` 가 호출 전체를 조인). */
|
|
1953
1964
|
runId?: string;
|
|
@@ -2510,8 +2521,40 @@ function goalDocumentForReleaseNote(goalFile?: string): string {
|
|
|
2510
2521
|
catch { return ''; }
|
|
2511
2522
|
}
|
|
2512
2523
|
|
|
2524
|
+
function shardReleaseNote(feature: string): ReleaseNoteSection | undefined {
|
|
2525
|
+
const matches = [...feature.matchAll(/^## Shard identity\r?\n([^\r\n]+)/gm)];
|
|
2526
|
+
const identity = matches.at(-1)?.[1];
|
|
2527
|
+
if (!identity) return undefined;
|
|
2528
|
+
try {
|
|
2529
|
+
const value: unknown = JSON.parse(identity);
|
|
2530
|
+
if (!value || typeof value !== 'object' || !('releaseNote' in value)) return undefined;
|
|
2531
|
+
const note = (value as { releaseNote: unknown }).releaseNote;
|
|
2532
|
+
if (!note || typeof note !== 'object' || Array.isArray(note)) return undefined;
|
|
2533
|
+
const candidate = note as Record<string, unknown>;
|
|
2534
|
+
if (typeof candidate.line !== 'string' || typeof candidate.kind !== 'string'
|
|
2535
|
+
|| typeof candidate.target !== 'string' || !candidate.docs || typeof candidate.docs !== 'object') return undefined;
|
|
2536
|
+
const doc = candidate.docs as Record<string, unknown>;
|
|
2537
|
+
if (typeof doc.path !== 'string' && typeof doc.none !== 'string') return undefined;
|
|
2538
|
+
const section = `## 릴리스 노트\n- 한 줄: ${candidate.line}\n- 종류: ${candidate.kind}\n- 문서: ${typeof doc.path === 'string' ? doc.path : `없음(${doc.none})`}\n- 대상: ${candidate.target}\n`;
|
|
2539
|
+
return parseReleaseNoteSection(section).fragment;
|
|
2540
|
+
} catch { return undefined; }
|
|
2541
|
+
}
|
|
2542
|
+
|
|
2543
|
+
function releaseNoteForRun(goalFile: string | undefined, feature: string): ReleaseNoteSection {
|
|
2544
|
+
const note = goalFile ? undefined : shardReleaseNote(feature);
|
|
2545
|
+
if (note) return note;
|
|
2546
|
+
const shard = !goalFile && feature.includes('## Shard identity');
|
|
2547
|
+
return harnessReleaseNote(goalDocumentForReleaseNote(goalFile), prTitle(feature), shard);
|
|
2548
|
+
}
|
|
2549
|
+
|
|
2550
|
+
/** 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. */
|
|
2551
|
+
export function gateNotRunSection(gateLog?: string): string[] {
|
|
2552
|
+
const lines = (gateLog ?? '').split('\n').filter((line) => line.startsWith('⚠️ caller test cap exceeded'));
|
|
2553
|
+
return lines.length ? ['', '## Gate · 안 돈 소비자 시험(상한 초과)', ...lines.map((line) => `- ${line.replace(/^⚠️ caller test cap exceeded — not run: /, '')}`)] : [];
|
|
2554
|
+
}
|
|
2555
|
+
|
|
2513
2556
|
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 ??
|
|
2557
|
+
const note = releaseNote ?? releaseNoteForRun(goalFile, feature);
|
|
2515
2558
|
const relaxation = planRevision?.relaxation
|
|
2516
2559
|
? ['', '## 감독 수용 기준 완화', `- 대상: ${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
2560
|
: [];
|
|
@@ -2530,6 +2573,7 @@ function prBody(feature: string, implSummary: string, gateLog?: string, review?:
|
|
|
2530
2573
|
...(review ? ['', `## 내부 리뷰 — ${review.verdict}`, review.summary.trim().slice(0, 1500),
|
|
2531
2574
|
...(review.shouldFix.length ? ['', '**should-fix (비블로킹):**', ...review.shouldFix.slice(0, 8).map((f) => `- ${f}`)] : [])] : []),
|
|
2532
2575
|
...(autoReviewDeclineReasons?.length ? ['', '## Auto-review label not applied', 'The requested auto-review label was declined by the autonomy gate:', ...autoReviewDeclineReasons.map((reason) => `- ${reason}`)] : []),
|
|
2576
|
+
...gateNotRunSection(gateLog),
|
|
2533
2577
|
...(gateLog ? ['', '## Gate', '```', gateLog.trim().slice(0, 3000), '```'] : []),
|
|
2534
2578
|
...relaxation,
|
|
2535
2579
|
'',
|
|
@@ -4453,6 +4497,51 @@ async function runSelfImplementInner(
|
|
|
4453
4497
|
// ⛔⭐ `let` 인 이유는 ③ «다이나믹»이다 — 라운드마다 runtime 오버레이가 «앞을 보는 것»만 바꾼다.
|
|
4454
4498
|
// ⛔ 지난 노드를 재정의하지 않는다(RFC §6: 그러면 원장을 사후에 해석할 수 없다).
|
|
4455
4499
|
let graphTemplate = graphDecision.template;
|
|
4500
|
+
let variantSpec: import('./graph-yaml.js').GraphTemplateSpec | undefined;
|
|
4501
|
+
if (opts.graphVariantPlan !== undefined) {
|
|
4502
|
+
const { GRAPH_SPECS, specToTemplate } = await import('./graph-templates.js');
|
|
4503
|
+
const { graphVersionHash } = await import('./graph-yaml.js');
|
|
4504
|
+
const { applyGraphOverlays } = await import('./graph-overlay-yaml.js');
|
|
4505
|
+
const { createGraphVariant } = await import('./graph-variant.js');
|
|
4506
|
+
const { runLedgerPath } = await import('./run-ledger.js');
|
|
4507
|
+
const { stringify } = await import('yaml');
|
|
4508
|
+
const baseSpec = GRAPH_SPECS[graphTemplate.graphId];
|
|
4509
|
+
const variantRunId = identity?.runId ?? opts.runId;
|
|
4510
|
+
if (!baseSpec || !variantRunId || graphDecision.rejections.length) {
|
|
4511
|
+
throw new Error('graph variant rejected: missing graph specification, run identity, or valid launch overlay');
|
|
4512
|
+
}
|
|
4513
|
+
const launch = graphDecision.appliedIds.length
|
|
4514
|
+
? applyGraphOverlays(baseSpec, graphOverlays.filter(overlay => graphDecision.appliedIds.includes(overlay.overlayId)))
|
|
4515
|
+
: undefined;
|
|
4516
|
+
if (launch && !launch.ok) throw new Error(`graph variant rejected: ${JSON.stringify(launch.rejections)}`);
|
|
4517
|
+
const sourceSpec = launch?.ok ? launch.template : baseSpec;
|
|
4518
|
+
const variant = createGraphVariant({ template: sourceSpec, goal: `g_${variantRunId.replace(/[^a-z0-9_-]/gi, '_')}`, plan: opts.graphVariantPlan });
|
|
4519
|
+
if (!variant.ok) throw new Error(`graph variant rejected: ${JSON.stringify(variant.rejections)}`);
|
|
4520
|
+
variantSpec = variant.template;
|
|
4521
|
+
graphTemplate = { ...specToTemplate(variantSpec), version: graphVersionHash(variantSpec) };
|
|
4522
|
+
const { runLedgerDir } = await import('./run-ledger.js');
|
|
4523
|
+
const graphFile = `${runLedgerPath(variantRunId)}.graph.yaml`;
|
|
4524
|
+
mkdirSync(runLedgerDir(), { recursive: true });
|
|
4525
|
+
const { writeFileSync } = await import('node:fs');
|
|
4526
|
+
writeFileSync(graphFile, stringify({
|
|
4527
|
+
graph_id: variantSpec.graphId, version: variantSpec.version,
|
|
4528
|
+
entry_node: variantSpec.entryNode, terminal_nodes: variantSpec.terminalNodes,
|
|
4529
|
+
...(variantSpec.runContract ? { run_contract: variantSpec.runContract } : {}),
|
|
4530
|
+
nodes: variantSpec.nodes.map(n => ({
|
|
4531
|
+
node_id: n.nodeId, kind: n.kind, recipe: n.recipe, max_visits: n.maxVisits,
|
|
4532
|
+
...(n.progress ? { progress: n.progress } : {}), ...(n.phases ? { phases: n.phases } : {}),
|
|
4533
|
+
...(n.terminalStages ? { terminal_stages: n.terminalStages } : {}),
|
|
4534
|
+
...(n.fanOut ? { fan_out: n.fanOut } : {}), ...(n.contract ? { contract: n.contract } : {}),
|
|
4535
|
+
})),
|
|
4536
|
+
edges: variantSpec.edges.map(e => ({
|
|
4537
|
+
from: e.from, ...(e.to === undefined ? { on: e.on, map: e.map } : { to: e.to }),
|
|
4538
|
+
...(e.fallback ? { fallback: e.fallback } : {}),
|
|
4539
|
+
...(e.observed === undefined ? {} : { observed: e.observed }),
|
|
4540
|
+
})),
|
|
4541
|
+
}), { flag: 'wx' });
|
|
4542
|
+
observe('graph-variant-applied', { graphId: variant.template.graphId, overlayId: variant.overlay.overlayId,
|
|
4543
|
+
graphFile, patches: variant.patches });
|
|
4544
|
+
}
|
|
4456
4545
|
/** 단계 이름 → 그 템플릿의 노드 이름. */
|
|
4457
4546
|
const node = (stage: PipelineNodeId): PipelineNodeId => nodeNameForStage(stage, graphTemplate) as PipelineNodeId;
|
|
4458
4547
|
// ⛔⭐ 맥락이 정해진 «직후» 관측기에 심는다 — 이 줄이 없으면 걸음은 YAML 을 따르고 «신원은 안 따른다».
|
|
@@ -4485,6 +4574,7 @@ async function runSelfImplementInner(
|
|
|
4485
4574
|
overlays: graphOverlays,
|
|
4486
4575
|
state: runtimeOverlayState,
|
|
4487
4576
|
stage: 'runtime',
|
|
4577
|
+
...(variantSpec ? { specs: { [variantSpec.graphId]: variantSpec } } : {}),
|
|
4488
4578
|
});
|
|
4489
4579
|
if (decision.appliedIds.length > 0) graphTemplate = decision.template;
|
|
4490
4580
|
// ⛔⭐ 승격이 켜져 있으면 «언제나» 낸다 — 후보가 0이어도 낸다.
|
|
@@ -5171,6 +5261,9 @@ async function runSelfImplementInner(
|
|
|
5171
5261
|
cachedQuotaExhaustionAssessment ??= readQuotaExhausted(s.inspectCodexRotation, runProviderName);
|
|
5172
5262
|
return cachedQuotaExhaustionAssessment;
|
|
5173
5263
|
};
|
|
5264
|
+
let finishedChildCommitMissing = false;
|
|
5265
|
+
let finishedChildCommitFailure: string | undefined;
|
|
5266
|
+
let finishedChildCommitted = false;
|
|
5174
5267
|
const classifyUnfinishedRun = (stage: SelfImplementStage, verdict?: ReworkBudgetVerdict, decomposition?: TerminalDecomposition): AbandonedClassificationResult => {
|
|
5175
5268
|
const quotaExhaustionAssessment = quotaExhaustionAssessmentForRun();
|
|
5176
5269
|
const worktree = unfinishedWorktreeObservation(wt.path);
|
|
@@ -5183,7 +5276,7 @@ async function runSelfImplementInner(
|
|
|
5183
5276
|
...(hasCurrentProviderError() && providerErrorCategory() ? { providerErrorCategory: providerErrorCategory() } : {}),
|
|
5184
5277
|
worktreePorcelain: worktree.worktreePorcelain,
|
|
5185
5278
|
...(worktree.gitResidue ? { gitResidue: worktree.gitResidue } : {}),
|
|
5186
|
-
...(impl.completionDisposition ? { completionDisposition: impl.completionDisposition } : {}),
|
|
5279
|
+
...(!finishedChildCommitMissing && !finishedChildCommitted && impl.completionDisposition ? { completionDisposition: impl.completionDisposition } : {}),
|
|
5187
5280
|
...(verdict ? { supervisorVerdict: verdict } : lastSupervisorVerdict ? { supervisorVerdict: lastSupervisorVerdict } : {}),
|
|
5188
5281
|
...(hasMultipleStructuredTerminalPieces(decomposition ?? terminalDecomposition) ? { goalCauseObserved: true } : {}),
|
|
5189
5282
|
stage,
|
|
@@ -5502,8 +5595,12 @@ async function runSelfImplementInner(
|
|
|
5502
5595
|
return { decision };
|
|
5503
5596
|
}
|
|
5504
5597
|
const followUpMustFix = `\n\n## Follow-up must-fix (${decision.unresolvedMustFix.length})\n${decision.unresolvedMustFix.map((finding) => `- ${finding}`).join('\n')}`;
|
|
5598
|
+
const releaseNote = releaseNoteForRun(opts.goalFile, opts.feature);
|
|
5599
|
+
// openPr's default seam delegates to PrManager.upsertPr, which stages, commits,
|
|
5600
|
+
// and pushes this worktree after the note is written and before creating the PR.
|
|
5601
|
+
addNextMdReleaseNote(wt.path, releaseNote);
|
|
5505
5602
|
const preparedPrBody = preparePrBody(
|
|
5506
|
-
`${prBody(opts.feature, impl.summary, gate.log, review, reviewIntent, undefined, harvestedForPr(), opts.goalFile, lastPlanRevision)}${followUpMustFix}`,
|
|
5603
|
+
`${prBody(opts.feature, impl.summary, gate.log, review, reviewIntent, undefined, harvestedForPr(), opts.goalFile, lastPlanRevision, releaseNote)}${followUpMustFix}`,
|
|
5507
5604
|
s.persistPrBodyArtifact,
|
|
5508
5605
|
'self-implement-review-budget-pr',
|
|
5509
5606
|
followUpMustFix,
|
|
@@ -6160,6 +6257,76 @@ async function runSelfImplementInner(
|
|
|
6160
6257
|
// ⭐ 성공 경로에서도 닫는다 — 이 호출은 끝났고, 이후 자식이 늦게 보내는 입력은
|
|
6161
6258
|
// 「이 라운드의 재투입」이 아니다(다음 라운드는 자기 콜백을 새로 만든다).
|
|
6162
6259
|
closeSupervisorInput();
|
|
6260
|
+
// A finished child can leave edits without a commit. Measure them before any
|
|
6261
|
+
// diff/no-changes classification, and commit only paths declared in the goal.
|
|
6262
|
+
finishedChildCommitMissing = false;
|
|
6263
|
+
finishedChildCommitFailure = undefined;
|
|
6264
|
+
finishedChildCommitted = false;
|
|
6265
|
+
if (impl.ok) {
|
|
6266
|
+
const work = (s.detectUncommittedWork ?? detectUncommittedWork)(wt.path);
|
|
6267
|
+
if (work.status === 'unavailable') {
|
|
6268
|
+
// Fail closed when the branch already carries commits: a PR could open without knowing whether the
|
|
6269
|
+
// goal's changes were committed (HARV1 review round 3). With no commits, the no-changes path decides.
|
|
6270
|
+
let branchFiles: readonly string[] | undefined;
|
|
6271
|
+
try { branchFiles = (s.changedFilesForGateRoute ?? changedFiles)(wt.path); } catch { branchFiles = undefined; }
|
|
6272
|
+
// Only a run that would open a PR needs the block — worktree-only completion opens none.
|
|
6273
|
+
// A path that isn't a git worktree at all (no .git) has nothing to open a PR from — only real worktrees block.
|
|
6274
|
+
const blocks = opts.completion !== 'worktree-only' && existsSync(join(wt.path, '.git'))
|
|
6275
|
+
&& (branchFiles === undefined || branchFiles.length > 0);
|
|
6276
|
+
if (blocks) {
|
|
6277
|
+
finishedChildCommitMissing = true;
|
|
6278
|
+
finishedChildCommitFailure = `working tree status unavailable: ${work.reason ?? 'unknown'}`;
|
|
6279
|
+
}
|
|
6280
|
+
observe('finished-child-commit', { round, status: 'unavailable', reason: work.reason, blocked: blocks }, { level: 'warn' });
|
|
6281
|
+
} else if (work.status === 'changes') {
|
|
6282
|
+
let goalDocument: string | undefined;
|
|
6283
|
+
if (opts.goalFile) {
|
|
6284
|
+
try { goalDocument = readFileSync(opts.goalFile, 'utf8'); } catch { /* no declared scope */ }
|
|
6285
|
+
}
|
|
6286
|
+
const declared = goalDocument === undefined ? undefined : declaredPathsFromGoalDocumentText(goalDocument);
|
|
6287
|
+
const targets = declared?.readable
|
|
6288
|
+
? declared.paths
|
|
6289
|
+
: inferHotPaths(targetScopedGoalText(opts.feature));
|
|
6290
|
+
const eligible = [...new Set([...work.trackedChanges, ...work.untrackedFiles])]
|
|
6291
|
+
.filter((path) => !harnessSeededPaths.includes(path)
|
|
6292
|
+
&& targets.some((target) => changedFileIsInsideDeclaredTarget(path, target)));
|
|
6293
|
+
if (eligible.length) {
|
|
6294
|
+
const message = `self-implement: ${prTitle(opts.feature)}`;
|
|
6295
|
+
let outcome: { ok: boolean; out: string };
|
|
6296
|
+
try {
|
|
6297
|
+
outcome = (s.commitFinishedChildWork ?? ((cwd, paths, title) => {
|
|
6298
|
+
const env = { ...process.env };
|
|
6299
|
+
for (const key of Object.keys(env)) if (key.startsWith('GIT_')) delete env[key];
|
|
6300
|
+
const childName = `elanous child ${runId}`;
|
|
6301
|
+
const childEmail = `child+${runId.replace(/[^a-zA-Z0-9-]/g, '')}@elanous.local`;
|
|
6302
|
+
env.GIT_AUTHOR_NAME = childName;
|
|
6303
|
+
env.GIT_AUTHOR_EMAIL = childEmail;
|
|
6304
|
+
env.GIT_COMMITTER_NAME = childName;
|
|
6305
|
+
env.GIT_COMMITTER_EMAIL = childEmail;
|
|
6306
|
+
const git = (args: string[]) => spawnSync('git', ['--no-optional-locks', ...args], {
|
|
6307
|
+
cwd, env, encoding: 'utf8', timeout: 20_000,
|
|
6308
|
+
});
|
|
6309
|
+
const staged = git(['add', '-A', '--', ...paths]);
|
|
6310
|
+
if (staged.status !== 0) return { ok: false, out: staged.stderr || staged.stdout || staged.error?.message || 'git add failed' };
|
|
6311
|
+
// --only commits these paths even when unrelated edits were staged before the child finished.
|
|
6312
|
+
const commit = git(['commit', '-m', title, '--only', '--', ...paths]);
|
|
6313
|
+
return { ok: commit.status === 0, out: commit.stderr || commit.stdout || commit.error?.message || '' };
|
|
6314
|
+
}))(wt.path, eligible, message);
|
|
6315
|
+
} catch (error) {
|
|
6316
|
+
outcome = { ok: false, out: safeErrorDescription(error) };
|
|
6317
|
+
}
|
|
6318
|
+
finishedChildCommitMissing = !outcome.ok;
|
|
6319
|
+
finishedChildCommitFailure = outcome.ok ? undefined : outcome.out;
|
|
6320
|
+
finishedChildCommitted = outcome.ok;
|
|
6321
|
+
observe('finished-child-commit', {
|
|
6322
|
+
round, status: outcome.ok ? 'committed' : 'commit-missing', paths: eligible,
|
|
6323
|
+
...(outcome.ok ? {} : { reason: outcome.out.slice(0, 500) }),
|
|
6324
|
+
}, outcome.ok ? {} : { level: 'warn' });
|
|
6325
|
+
} else {
|
|
6326
|
+
observe('finished-child-commit', { round, status: 'out-of-scope' });
|
|
6327
|
+
}
|
|
6328
|
+
}
|
|
6329
|
+
}
|
|
6163
6330
|
// ⭐ S3 — 자식 요약에서 diff 밖 이행 주장을 분류한다(자식 반환 계약은 그대로 둔다).
|
|
6164
6331
|
// ⛔ 버린 것을 **세어서** 남긴다 — 조용히 버리면 관측값이 항상 0이 되어 거짓 초록이 된다.
|
|
6165
6332
|
// ★ I-9/RUN-T6 — 꼬리 2000자가 아니라 **수확본**에서 판다. 자식이 먼저 돌린 tsc·뮤테이션 출력이
|
|
@@ -6242,9 +6409,10 @@ async function runSelfImplementInner(
|
|
|
6242
6409
|
orphanResult: offDiffEvidence.orphanResult,
|
|
6243
6410
|
...harvestObs,
|
|
6244
6411
|
}, { compact: { stringMax: Math.max(MAX_HARVESTED_EVIDENCE_CHARS, harvestObs.harvestedEvidence?.length ?? 0) } });
|
|
6245
|
-
|
|
6412
|
+
if (impl.ok) completionDisposition = finishedChildCommitMissing || finishedChildCommitted ? undefined : impl.completionDisposition;
|
|
6413
|
+
const effectiveDisposition = impl.ok ? completionDisposition : impl.completionDisposition;
|
|
6414
|
+
observe('implemented', { ok: impl.ok, round, ...(effectiveDisposition ? { completionDisposition: effectiveDisposition } : {}) });
|
|
6246
6415
|
progress('implemented', impl.ok ? (round === 0 ? '구현 완료' : `rework ${round} 완료`) : impl.completionDisposition ? '변경 없이 완료 검증' : '구현 실패(worktree 보존)');
|
|
6247
|
-
if (impl.ok) completionDisposition = impl.completionDisposition;
|
|
6248
6416
|
if (!impl.ok) {
|
|
6249
6417
|
finalizeSupervisorDeliveries('next-round-implement-not-ok');
|
|
6250
6418
|
const abort = buildImplementAbortRecord(impl.summary, impl.terminalStatus);
|
|
@@ -6271,6 +6439,13 @@ async function runSelfImplementInner(
|
|
|
6271
6439
|
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
6440
|
}
|
|
6273
6441
|
|
|
6442
|
+
if (finishedChildCommitMissing) {
|
|
6443
|
+
finalizeSupervisorDeliveries('finished-child-commit-missing');
|
|
6444
|
+
const detail = `finished child changes could not be committed: ${finishedChildCommitFailure ?? 'commit failed'}`;
|
|
6445
|
+
progress('aborted', detail);
|
|
6446
|
+
return { ok: false, stage: 'aborted', node: 'implement', ...resolveRunOutcome({ termination: 'abandoned' }), sessionId, worktreePath: wt.path, branch: wt.branch, detail };
|
|
6447
|
+
}
|
|
6448
|
+
|
|
6274
6449
|
// Measure the existing declared-target boundary after implementation, before gate/PR.
|
|
6275
6450
|
// Unknown declaration or changed files cannot justify an invented choice.
|
|
6276
6451
|
let gateRouteFiles: readonly string[] | undefined;
|
|
@@ -7073,7 +7248,10 @@ async function runSelfImplementInner(
|
|
|
7073
7248
|
...(prEvidenceDecision.reason ? { reason: prEvidenceDecision.reason } : {}),
|
|
7074
7249
|
...(prEvidenceDecision.body ? { bodyChars: prEvidenceDecision.body.length } : {}),
|
|
7075
7250
|
});
|
|
7076
|
-
const releaseNote =
|
|
7251
|
+
const releaseNote = releaseNoteForRun(opts.goalFile, opts.feature);
|
|
7252
|
+
// openPr's default seam delegates to PrManager.upsertPr, which stages, commits,
|
|
7253
|
+
// and pushes this worktree after the note is written and before creating the PR.
|
|
7254
|
+
addNextMdReleaseNote(wt.path, releaseNote);
|
|
7077
7255
|
const preparedPrBody = preparePrBody(
|
|
7078
7256
|
[
|
|
7079
7257
|
prBody(opts.feature, impl.summary, gate.log, review, reviewIntent, declineReasons, harvestedForPr(), opts.goalFile, lastPlanRevision, releaseNote),
|
|
@@ -7090,7 +7268,8 @@ async function runSelfImplementInner(
|
|
|
7090
7268
|
head: wt.branch,
|
|
7091
7269
|
...(opts.base ? { base: opts.base } : {}),
|
|
7092
7270
|
draft: canAuto ? false : (opts.draft ?? true),
|
|
7093
|
-
|
|
7271
|
+
// The review poller must not see this PR before its actual paths have been inspected.
|
|
7272
|
+
...(labels?.length ? { labels: labels.filter((label) => label !== AUTO_REVIEW_LABEL) } : {}),
|
|
7094
7273
|
cwd: wt.path,
|
|
7095
7274
|
}), T.pr, 'pr');
|
|
7096
7275
|
} catch (error) {
|
|
@@ -7116,6 +7295,60 @@ async function runSelfImplementInner(
|
|
|
7116
7295
|
});
|
|
7117
7296
|
await flushPrComments(pr);
|
|
7118
7297
|
|
|
7298
|
+
// Inspect the opened PR itself: the goal text and the pre-sync worktree can differ from its final file list.
|
|
7299
|
+
let releaseHoldPath: string | undefined;
|
|
7300
|
+
let releasePathInspectionError: string | undefined;
|
|
7301
|
+
if (s.readPrFiles) {
|
|
7302
|
+
try {
|
|
7303
|
+
const files = await withStepTimeout(s.readPrFiles({ number: pr.number, cwd: wt.path }), T.pr, 'pr');
|
|
7304
|
+
if (!Array.isArray(files) || !files.every((path) => typeof path === 'string')) throw new Error('invalid PR file list');
|
|
7305
|
+
releaseHoldPath = releasePathHold(files);
|
|
7306
|
+
} catch (error) {
|
|
7307
|
+
releasePathInspectionError = safeErrorDescription(error);
|
|
7308
|
+
}
|
|
7309
|
+
} else if (canAuto || labels?.includes(AUTO_REVIEW_LABEL)) {
|
|
7310
|
+
releasePathInspectionError = 'readPrFiles seam unavailable';
|
|
7311
|
+
}
|
|
7312
|
+
if (releaseHoldPath) {
|
|
7313
|
+
debug.log('self-dev.merge', 'release-path-hold', { number: pr.number, path: releaseHoldPath, label: RELEASE_PATH_LABEL });
|
|
7314
|
+
canAuto = false;
|
|
7315
|
+
mergeSkipReason = mergeReason = 'release-path-hold';
|
|
7316
|
+
// Suppress the independent auto-review poller as well as this immediate merge path.
|
|
7317
|
+
// No merge is attempted even when an annotation fails; each failure is observable for OP repair.
|
|
7318
|
+
for (const [action, annotate] of [
|
|
7319
|
+
['add-label', s.addPrLabel && (() => s.addPrLabel!({ number: pr.number, label: RELEASE_PATH_LABEL, cwd: wt.path }))],
|
|
7320
|
+
['comment', s.postPrComment && (() => s.postPrComment!({ number: pr.number, body: releasePathHoldComment(releaseHoldPath), cwd: wt.path }))],
|
|
7321
|
+
] as const) {
|
|
7322
|
+
if (!annotate) {
|
|
7323
|
+
observe('release-path-annotation-failed', { number: pr.number, path: releaseHoldPath, action, error: 'annotation seam unavailable' }, { level: 'error' });
|
|
7324
|
+
continue;
|
|
7325
|
+
}
|
|
7326
|
+
try { await annotate(); }
|
|
7327
|
+
catch (error) {
|
|
7328
|
+
observe('release-path-annotation-failed', { number: pr.number, path: releaseHoldPath, action, error: safeErrorDescription(error) }, { level: 'error' });
|
|
7329
|
+
}
|
|
7330
|
+
}
|
|
7331
|
+
recordMergeDecision();
|
|
7332
|
+
progress('pr-opened', `OP 승인 대기 (#${pr.number}): ${releaseHoldPath}`);
|
|
7333
|
+
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}` };
|
|
7334
|
+
}
|
|
7335
|
+
if (!releasePathInspectionError && labels?.includes(AUTO_REVIEW_LABEL)) {
|
|
7336
|
+
try {
|
|
7337
|
+
if (!s.addPrLabel) throw new Error('addPrLabel seam unavailable');
|
|
7338
|
+
await s.addPrLabel({ number: pr.number, label: AUTO_REVIEW_LABEL, cwd: wt.path });
|
|
7339
|
+
} catch (error) {
|
|
7340
|
+
observe('auto-review-label-failed', { number: pr.number, error: safeErrorDescription(error) }, { level: 'warn' });
|
|
7341
|
+
}
|
|
7342
|
+
}
|
|
7343
|
+
if (releasePathInspectionError && (canAuto || labels?.includes(AUTO_REVIEW_LABEL))) {
|
|
7344
|
+
observe('release-path-inspection-failed', { number: pr.number, error: releasePathInspectionError }, { level: 'error' });
|
|
7345
|
+
canAuto = false;
|
|
7346
|
+
mergeSkipReason = mergeReason = 'release-path-inspection-failed';
|
|
7347
|
+
recordMergeDecision();
|
|
7348
|
+
progress('pr-opened', `OP 승인 대기 (#${pr.number}): PR 경로 조회 실패`);
|
|
7349
|
+
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 };
|
|
7350
|
+
}
|
|
7351
|
+
|
|
7119
7352
|
if (canAuto && (s.mergePr || opts.mergeByHost)) {
|
|
7120
7353
|
let docsMarkdownDeletions: number | undefined;
|
|
7121
7354
|
let nonDocsMarkdownDeletions: number | undefined;
|
|
@@ -0,0 +1,122 @@
|
|
|
1
|
+
import { readFileSync } from 'node:fs';
|
|
2
|
+
import { spawnSync } from 'node:child_process';
|
|
3
|
+
import { resolve } from 'node:path/posix';
|
|
4
|
+
import ts from 'typescript';
|
|
5
|
+
import { isTestPath } from './importer-test-index.js';
|
|
6
|
+
|
|
7
|
+
export interface RouteConsumerTestIndex {
|
|
8
|
+
readonly testsBySource: ReadonlyMap<string, readonly string[]>;
|
|
9
|
+
/** Base routes could not be inspected for these sources; an empty match is not evidence of no consumers. */
|
|
10
|
+
readonly lookupFailures: readonly { readonly source: string; readonly reason: string }[];
|
|
11
|
+
}
|
|
12
|
+
|
|
13
|
+
const ROUTE_RE = /^\/(?:v\d+|api)\/[^\s]+$/;
|
|
14
|
+
|
|
15
|
+
function dynamicRoutePattern(route: string): RegExp | null {
|
|
16
|
+
const segments = route.split('/').slice(1);
|
|
17
|
+
if (!segments.some((segment) => segment.startsWith(':') || segment === '*')) return null;
|
|
18
|
+
const pattern = segments.map((segment) => {
|
|
19
|
+
if (segment === '*') return '.*';
|
|
20
|
+
if (/^:[\w]+$/.test(segment)) return '[^/?#]+';
|
|
21
|
+
return segment.replace(/[.*+?^${}()|[\]\\]/g, '\\$&');
|
|
22
|
+
}).join('/');
|
|
23
|
+
return new RegExp(`^/${pattern}(?:[?#].*)?$`);
|
|
24
|
+
}
|
|
25
|
+
|
|
26
|
+
function testStringValues(text: string, path: string): string[] {
|
|
27
|
+
const ast = ts.createSourceFile(path, text, ts.ScriptTarget.Latest, false);
|
|
28
|
+
const values: string[] = [];
|
|
29
|
+
const visit = (node: ts.Node): void => {
|
|
30
|
+
if (ts.isStringLiteralLike(node)) values.push(node.text);
|
|
31
|
+
ts.forEachChild(node, visit);
|
|
32
|
+
};
|
|
33
|
+
visit(ast);
|
|
34
|
+
return values;
|
|
35
|
+
}
|
|
36
|
+
|
|
37
|
+
/** Index paths in both the current and comparison-base server source, so removing a route still selects its consumers. */
|
|
38
|
+
export function buildRouteConsumerTestIndex(
|
|
39
|
+
cwd: string,
|
|
40
|
+
testPaths: readonly string[],
|
|
41
|
+
changedSources: readonly string[],
|
|
42
|
+
baseRef = 'HEAD',
|
|
43
|
+
readBase: (source: string) => { text: string } | { absent: true } | { lookupFailed: string } = (source) => {
|
|
44
|
+
const options = { cwd, encoding: 'utf8' as const, timeout: 20_000, maxBuffer: 8 * 1024 * 1024 };
|
|
45
|
+
const result = spawnSync('git', ['show', `${baseRef}:${source}`], options);
|
|
46
|
+
if (result.status === 0 && !result.error) return { text: result.stdout };
|
|
47
|
+
const tree = spawnSync('git', ['ls-tree', '--name-only', baseRef, '--', source], options);
|
|
48
|
+
if (tree.status === 0 && !tree.error && !tree.stdout.trim()) return { absent: true };
|
|
49
|
+
return { lookupFailed: (result.stderr || result.error?.message || tree.stderr || tree.error?.message || 'git show failed').trim() };
|
|
50
|
+
},
|
|
51
|
+
/** Lines added/removed in the diff for `source`; null = diff unavailable (then every route in the file counts). */
|
|
52
|
+
changedLines: (source: string) => string[] | null = (source) => {
|
|
53
|
+
const r = spawnSync('git', ['diff', '-U0', baseRef, '--', source], { cwd, encoding: 'utf8' as const, timeout: 20_000, maxBuffer: 8 * 1024 * 1024 });
|
|
54
|
+
if (r.status !== 0 || r.error) return null;
|
|
55
|
+
// `git diff` omits untracked files — a new, not-yet-added server file is all new lines (every route counts).
|
|
56
|
+
if (!r.stdout.trim() && spawnSync('git', ['ls-files', '--error-unmatch', '--', source], { cwd, encoding: 'utf8' as const, timeout: 20_000, maxBuffer: 8 * 1024 * 1024 }).status !== 0) return null;
|
|
57
|
+
return r.stdout.split('\n').filter((line) => /^[+-](?![+-]{2})/.test(line)).map((line) => line.slice(1));
|
|
58
|
+
},
|
|
59
|
+
): RouteConsumerTestIndex {
|
|
60
|
+
const routesBySource = new Map<string, string[]>();
|
|
61
|
+
const lookupFailures: { source: string; reason: string }[] = [];
|
|
62
|
+
for (const source of changedSources) {
|
|
63
|
+
if (!source.startsWith('src/') || isTestPath(source) || !/\.[cm]?[jt]sx?$/.test(source)) continue;
|
|
64
|
+
const routes = new Set<string>();
|
|
65
|
+
const collect = (text: string): void => {
|
|
66
|
+
const ast = ts.createSourceFile(source, text, ts.ScriptTarget.Latest, false);
|
|
67
|
+
const visit = (node: ts.Node): void => {
|
|
68
|
+
if (ts.isCallExpression(node) && ts.isPropertyAccessExpression(node.expression)
|
|
69
|
+
&& /^(get|post|put|patch|delete|route|register)$/.test(node.expression.name.text)) {
|
|
70
|
+
const path = node.arguments[0];
|
|
71
|
+
if (path && ts.isStringLiteralLike(path) && ROUTE_RE.test(path.text)) routes.add(path.text);
|
|
72
|
+
}
|
|
73
|
+
if (ts.isBinaryExpression(node) && node.operatorToken.kind === ts.SyntaxKind.EqualsEqualsEqualsToken
|
|
74
|
+
&& /(?:pathname|path)$/.test(node.left.getText(ast)) && ts.isStringLiteralLike(node.right)
|
|
75
|
+
&& ROUTE_RE.test(node.right.text)) routes.add(node.right.text);
|
|
76
|
+
if (ts.isVariableDeclaration(node) && /(?:PATH|ROUTE)$/.test(node.name.getText(ast))
|
|
77
|
+
&& node.initializer && ts.isStringLiteralLike(node.initializer)
|
|
78
|
+
&& ROUTE_RE.test(node.initializer.text)) routes.add(node.initializer.text);
|
|
79
|
+
if (ts.isCaseClause(node) && ts.isStringLiteralLike(node.expression)
|
|
80
|
+
&& ROUTE_RE.test(node.expression.text)) routes.add(node.expression.text);
|
|
81
|
+
if (ts.isPropertyAssignment(node) && /^(path|route)$/.test(node.name.getText(ast))
|
|
82
|
+
&& ts.isStringLiteralLike(node.initializer) && ROUTE_RE.test(node.initializer.text)) routes.add(node.initializer.text);
|
|
83
|
+
ts.forEachChild(node, visit);
|
|
84
|
+
};
|
|
85
|
+
visit(ast);
|
|
86
|
+
};
|
|
87
|
+
try { collect(readFileSync(resolve(cwd, source), 'utf8')); } catch { /* Deleted source: base may still contain registered routes. */ }
|
|
88
|
+
try {
|
|
89
|
+
const previous = readBase(source);
|
|
90
|
+
if ('text' in previous) collect(previous.text);
|
|
91
|
+
else if ('lookupFailed' in previous) lookupFailures.push({ source, reason: previous.lookupFailed });
|
|
92
|
+
} catch (error) {
|
|
93
|
+
lookupFailures.push({ source, reason: error instanceof Error ? error.message : String(error) });
|
|
94
|
+
}
|
|
95
|
+
// A hub server file registers every route; only routes on lines the diff touched select consumers (TC review:
|
|
96
|
+
// http-server.ts alone matched 279 tests and the cap kept the alphabetically first 30). New/deleted files keep all routes.
|
|
97
|
+
const touched = changedLines(source);
|
|
98
|
+
const selected = touched === null ? [...routes] : [...routes].filter((route) => touched.some((line) => line.includes(route)));
|
|
99
|
+
if (selected.length) routesBySource.set(source, selected);
|
|
100
|
+
}
|
|
101
|
+
const testsBySource = new Map<string, string[]>();
|
|
102
|
+
if (routesBySource.size === 0) return { testsBySource, lookupFailures };
|
|
103
|
+
for (const test of testPaths) {
|
|
104
|
+
if (!isTestPath(test)) continue;
|
|
105
|
+
let text: string;
|
|
106
|
+
try { text = readFileSync(resolve(cwd, test), 'utf8'); } catch { continue; } // deleted test
|
|
107
|
+
const literalValues = testStringValues(text, test);
|
|
108
|
+
for (const [source, routes] of routesBySource) {
|
|
109
|
+
if (routes.some((route) => {
|
|
110
|
+
const dynamic = dynamicRoutePattern(route);
|
|
111
|
+
if (dynamic) return literalValues.some((value) => dynamic.test(value));
|
|
112
|
+
let at = text.indexOf(route);
|
|
113
|
+
while (at !== -1) {
|
|
114
|
+
if (!/[\w/-]/.test(text[at + route.length] ?? '')) return true;
|
|
115
|
+
at = text.indexOf(route, at + 1);
|
|
116
|
+
}
|
|
117
|
+
return false;
|
|
118
|
+
})) testsBySource.set(source, [...(testsBySource.get(source) ?? []), test]);
|
|
119
|
+
}
|
|
120
|
+
}
|
|
121
|
+
return { testsBySource, lookupFailures };
|
|
122
|
+
}
|