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
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
{
|
|
2
|
+
"compilerOptions": {
|
|
3
|
+
"target": "ES2022",
|
|
4
|
+
"module": "NodeNext",
|
|
5
|
+
"moduleResolution": "NodeNext",
|
|
6
|
+
"strict": true,
|
|
7
|
+
"esModuleInterop": true,
|
|
8
|
+
"skipLibCheck": true,
|
|
9
|
+
"outDir": "dist",
|
|
10
|
+
"rootDir": "."
|
|
11
|
+
},
|
|
12
|
+
"include": ["src/**/*.ts", "scripts/**/*.ts"]
|
|
13
|
+
}
|
package/src/acp/server.ts
CHANGED
|
@@ -241,6 +241,8 @@ export interface AcpServerOptions {
|
|
|
241
241
|
/** ACP standalone entry: require session cwd or an explicit boot default. */
|
|
242
242
|
requireSessionToolCwd?: boolean;
|
|
243
243
|
bootToolCwd?: string;
|
|
244
|
+
/** Optional PTY factory for the web terminal; production uses PreviewTerminal. */
|
|
245
|
+
createWebTerminal?: (opts: ConstructorParameters<typeof import('../preview/terminal.js').PreviewTerminal>[0]) => import('../preview/terminal.js').PreviewTerminal;
|
|
244
246
|
/** Test seam for exercising stdio EOF with controlled byte streams. */
|
|
245
247
|
stdioInput?: ReadableStream<Uint8Array>;
|
|
246
248
|
stdioOutput?: WritableStream<Uint8Array>;
|
|
@@ -2190,7 +2192,8 @@ function wireAcpConnection(
|
|
|
2190
2192
|
throw new Error('terminal/spawn: sessionId required');
|
|
2191
2193
|
}
|
|
2192
2194
|
const tid = resolveAcpTerminalId(p.terminalId);
|
|
2193
|
-
const cwd = typeof p.cwd === 'string' && p.cwd.length > 0 ? p.cwd
|
|
2195
|
+
const cwd = typeof p.cwd === 'string' && p.cwd.length > 0 ? p.cwd
|
|
2196
|
+
: (await import('../project/session-context.js')).resolveSessionProjectContext(p.sessionId)?.cwd ?? process.cwd();
|
|
2194
2197
|
const cols = typeof p.cols === 'number' && p.cols > 0 ? p.cols : 80;
|
|
2195
2198
|
const rows = typeof p.rows === 'number' && p.rows > 0 ? p.rows : 24;
|
|
2196
2199
|
|
|
@@ -2234,7 +2237,7 @@ function wireAcpConnection(
|
|
|
2234
2237
|
}
|
|
2235
2238
|
|
|
2236
2239
|
const { PreviewTerminal } = await import('../preview/terminal.js');
|
|
2237
|
-
const pt = new PreviewTerminal({
|
|
2240
|
+
const pt = (opts.createWebTerminal ?? ((terminalOpts) => new PreviewTerminal(terminalOpts)))({
|
|
2238
2241
|
cols, rows, cwd,
|
|
2239
2242
|
// Web-terminal child shell renders inside the PWA's xterm.js,
|
|
2240
2243
|
// which implements the xterm-256color terminfo. When the daemon
|
|
@@ -20,6 +20,8 @@ import { configuredWorktreeRoot } from '../user-config.js';
|
|
|
20
20
|
import { worktreeHasChanges, commitWorktree, changedFiles } from '../self-implement/seams.js';
|
|
21
21
|
import { streamLLM, type LLMMessage } from '../llm.js';
|
|
22
22
|
import { debug } from '../debug/log.js';
|
|
23
|
+
import { emitPtyDecision, type DecisionInput } from './pty-decision.js';
|
|
24
|
+
import { observeExternalEvent } from '../context-bus/external-events.js';
|
|
23
25
|
import { emitDecision } from '../live/detail-switch.js';
|
|
24
26
|
import { resolvePtyWebAddress } from '../cli/pty-web-address.js';
|
|
25
27
|
import { reemitPtyUsage } from '../budget/pty-usage-reemit.js';
|
|
@@ -522,6 +524,8 @@ export interface AgentMissionDeps {
|
|
|
522
524
|
createWorktree?: typeof createWorktree;
|
|
523
525
|
recordWorktreeProvenance?: typeof recordHarnessWorktreeProvenance;
|
|
524
526
|
runControlLoop?: typeof runPtyControlLoop;
|
|
527
|
+
/** Capture decisions in tests without replacing the process-wide debug logger. */
|
|
528
|
+
emitPtyDecision?: typeof emitPtyDecision;
|
|
525
529
|
/** Inject controller responses while keeping the production control loop. */
|
|
526
530
|
controlStream?: StreamLLMFn;
|
|
527
531
|
resolvePtyWebAddress?: typeof resolvePtyWebAddress;
|
|
@@ -830,6 +834,7 @@ export interface MissionControlBrainOpts {
|
|
|
830
834
|
readonly handoffEnabled?: boolean;
|
|
831
835
|
/** Screen-grounded brain summary for the next backend, never the raw PTY screen. */
|
|
832
836
|
readonly onSummary?: (summary: string) => void;
|
|
837
|
+
readonly onDecision?: (text: string, reply?: { question: string; answer: string }) => void;
|
|
833
838
|
}
|
|
834
839
|
|
|
835
840
|
/** 기존 5-action mission 판단을 canonical PTY control-loop 결정으로 축소한다. search는 이 경계에서만
|
|
@@ -855,7 +860,7 @@ export function createMissionControlBrain(opts: MissionControlBrainOpts): RunSup
|
|
|
855
860
|
행동(action):
|
|
856
861
|
- "wait": ${backendName} 가 아직 작업 중(도구 실행/생성)이면 대기.
|
|
857
862
|
- "verify": ${backendName} 가 MISSION-COMPLETE/완료를 주장하면 증거 게이트(내가 실행)로 검증. 완료주장 시 이걸 우선.
|
|
858
|
-
- "send": ${backendName} 가 멈추거나 계속 진행이 필요하면 짧고 명확한 지시(text).
|
|
863
|
+
- "send": ${backendName} 가 멈추거나 계속 진행이 필요하면 짧고 명확한 지시(text). 화면의 질문에 직접 답하는 경우에만 reason 을 Answering question: <화면의 질문 원문> 으로 기록하라. 다른 send 의 reason 은 종전처럼 행동 이유를 적어라.
|
|
859
864
|
- "search": ${backendName} 가 정보/라이브러리/문법/외부자원에 막혔으면 omni-crawl 로 조사(query). ⭐외부 힌트 없이 스스로 판단.
|
|
860
865
|
${opts.handoffEnabled ? ` - "handoff": 다른 담당자로 넘길 때 to(codex/claude/elanous), mission(다음 지시), carry(diff/summary 선택). carry=summary 면 reason 에 화면에서 확인한 리뷰 지적을 구체적으로 요약하라(다음 backend 에 전달된다). claude 리뷰 뒤 지적은 codex 에 summary 로 되돌려라. elanous 는 증거 게이트와 PR.
|
|
861
866
|
- "ask-human": 화면에 로그인 URL/장치 코드가 보이면 reason, url/code(보이는 것만). 토큰·자격파일을 열지 마라.` : ''}${opts.provision ? `
|
|
@@ -873,6 +878,12 @@ ${opts.handoffEnabled ? ` - "handoff": 다른 담당자로 넘길 때 to(codex/c
|
|
|
873
878
|
history.push(`s${obs.step}:${decision.action}`);
|
|
874
879
|
debug.log('agent-mission', 'brain', { step: obs.step, action: decision.action,
|
|
875
880
|
...(decision.action === 'ask-human' ? {} : { reason: decision.reason.slice(0, 120) }) });
|
|
881
|
+
// A '?' on screen alone does not establish that this send answered it. Only an
|
|
882
|
+
// explicit question citation in the brain's reason can attribute the reply.
|
|
883
|
+
const citedQuestion = /^Answering question:\s*(.+\?)\s*$/i.exec(decision.reason)?.[1]?.trim();
|
|
884
|
+
const question = citedQuestion && classifierFrameLines(obs.screen).find((line) => line === citedQuestion);
|
|
885
|
+
opts.onDecision?.(`step ${obs.step}: ${decision.action}${decision.action === 'ask-human' ? '' : ` — ${decision.reason || decision.text || decision.query || ''}`}`,
|
|
886
|
+
decision.action === 'send' && decision.text?.trim() && question ? { question, answer: decision.text } : undefined);
|
|
876
887
|
if (decision.reason && decision.action !== 'ask-human') opts.onSummary?.(decision.reason.slice(0, 2000));
|
|
877
888
|
if (decision.action === 'handoff' && decision.to && decision.mission) return { action: 'handoff', to: decision.to, mission: decision.mission, ...(decision.carry ? { carry: decision.carry } : {}) };
|
|
878
889
|
if (decision.action === 'ask-human') return { action: 'ask-human', reason: decision.reason, ...(decision.url ? { url: decision.url } : {}), ...(decision.code ? { code: decision.code } : {}) };
|
|
@@ -974,6 +985,7 @@ export function makeMissionObserveStep(deps: {
|
|
|
974
985
|
bus: ChannelBus;
|
|
975
986
|
ident: { ptyId: string; instance: string; runId?: string };
|
|
976
987
|
now?: () => number;
|
|
988
|
+
onPublishedFrame?: (obs: ControlObservation) => void;
|
|
977
989
|
}): (obs: ControlObservation, decision: ControlDecision) => Promise<void> {
|
|
978
990
|
const now = deps.now ?? ((): number => Date.now());
|
|
979
991
|
let lastFrameState: FrameState | null = null;
|
|
@@ -1008,6 +1020,7 @@ export function makeMissionObserveStep(deps: {
|
|
|
1008
1020
|
...(deps.ident.runId ? { runId: deps.ident.runId } : {}),
|
|
1009
1021
|
...(pngRef ? { pngRef } : {}),
|
|
1010
1022
|
});
|
|
1023
|
+
deps.onPublishedFrame?.(obs);
|
|
1011
1024
|
// capture 는 원 semantics 유지 — 예외 전파(증거/전사 계약 불변).
|
|
1012
1025
|
await deps.capture(`s${obs.step}-${decision.action}`);
|
|
1013
1026
|
};
|
|
@@ -1574,9 +1587,19 @@ async function runAgentMissionBody(spec: AgentMissionSpec, deps: AgentMissionDep
|
|
|
1574
1587
|
if (deps.isMissionAborted?.()) { offLive(); throw new Error('MISSION_ABORTED'); }
|
|
1575
1588
|
try { h = spawnPty(ptyOpts); }
|
|
1576
1589
|
catch (error) { offLive(); throw error; }
|
|
1577
|
-
|
|
1578
|
-
|
|
1579
|
-
|
|
1590
|
+
if (backend.name === 'codex') observeExternalEvent({ origin: 'codex-agent-mission', kind: 'started',
|
|
1591
|
+
summary: 'Codex agent mission started', source: `elanous://agent-mission/${encodeURIComponent(runId)}/${encodeURIComponent(h.id)}` });
|
|
1592
|
+
let contextFinished = false;
|
|
1593
|
+
const finishContext = (ok: boolean): void => {
|
|
1594
|
+
if (contextFinished || backend.name !== 'codex') return;
|
|
1595
|
+
contextFinished = true;
|
|
1596
|
+
observeExternalEvent({ origin: 'codex-agent-mission', kind: 'finished',
|
|
1597
|
+
summary: `Codex agent mission ${ok ? 'completed' : 'failed'}`,
|
|
1598
|
+
source: `elanous://agent-mission/${encodeURIComponent(runId)}/${encodeURIComponent(h.id)}` });
|
|
1599
|
+
};
|
|
1600
|
+
deps.onPtyStarted?.(h, () => { if (liveTimer) clearInterval(liveTimer); offLive(); finishContext(false); });
|
|
1601
|
+
if (deps.isMissionAborted?.()) { finishContext(false); return { ok: false, reason: 'aborted', worktree: wt.path, branch: wt.branch,
|
|
1602
|
+
rounds: 0, evidencePath: null, committed: false, usedOmniCrawl: false, detail: 'aborted' }; }
|
|
1580
1603
|
const executorRef = buildExecutorPtyRef({
|
|
1581
1604
|
ptyId: h.id,
|
|
1582
1605
|
backend: backend.name,
|
|
@@ -1589,6 +1612,12 @@ async function runAgentMissionBody(spec: AgentMissionSpec, deps: AgentMissionDep
|
|
|
1589
1612
|
process.stderr.write(`[agent-mission] pty=${h.id} watch=${webAddress.webUrl ?? `(web unavailable: ${webAddress.pwaUnavailableReason ?? 'not-resolved'})`}\n`);
|
|
1590
1613
|
debug.log('agent-mission', 'pty-link', { id: h.id, webUrl: webAddress.webUrl, webUrlSource: webAddress.webUrlSource });
|
|
1591
1614
|
|
|
1615
|
+
const decisionIdentity = { missionId: runId, sessionId: runId, terminalId: h.id, agent: backend.name };
|
|
1616
|
+
const decisionEvent = (event: Omit<DecisionInput, keyof typeof decisionIdentity>): void => {
|
|
1617
|
+
try { (deps.emitPtyDecision ?? emitPtyDecision)({ ...decisionIdentity, ...event } as DecisionInput); }
|
|
1618
|
+
catch { /* Observation must not change mission control or handoff. */ }
|
|
1619
|
+
};
|
|
1620
|
+
|
|
1592
1621
|
// ⭐P2 arbiter: the child is accessMode='auto' (brain-owned), so the driver —
|
|
1593
1622
|
// the autonomous brain — must write as 'agent' or the arbiter denies it. This
|
|
1594
1623
|
// makes "protected autonomy" real: a human attaching mid-mission (read) can't
|
|
@@ -1615,6 +1644,7 @@ async function runAgentMissionBody(spec: AgentMissionSpec, deps: AgentMissionDep
|
|
|
1615
1644
|
: 'AGENT_YIELDED: PTY 제어가 사람에게 이양됨(takeover) — 자율 미션 중단');
|
|
1616
1645
|
}
|
|
1617
1646
|
h['write'](s, 'agent');
|
|
1647
|
+
decisionEvent({ step: 'input', text: s === '\r' ? 'Sent Enter' : `Sent ${s.startsWith('\x1b') ? 'key' : 'text'}: ${s.startsWith('\x1b') ? 'navigation' : s}` });
|
|
1618
1648
|
};
|
|
1619
1649
|
|
|
1620
1650
|
let seq = 0;
|
|
@@ -1638,7 +1668,8 @@ async function runAgentMissionBody(spec: AgentMissionSpec, deps: AgentMissionDep
|
|
|
1638
1668
|
if (liveChunks % 20 === 0) debug.log('agent-mission', 'live', { chunks: liveChunks, tail: s.slice(-80).replace(/\s+/g, ' ') });
|
|
1639
1669
|
}).catch(() => { /* noop */ });
|
|
1640
1670
|
}, 800);
|
|
1641
|
-
const stopLive = (): void => { if (liveTimer) clearInterval(liveTimer); offLive(); };
|
|
1671
|
+
const stopLive = (ok = false): void => { if (liveTimer) clearInterval(liveTimer); offLive(); if (ok) finishContext(true); };
|
|
1672
|
+
try {
|
|
1642
1673
|
|
|
1643
1674
|
// ready + trust — backend 별 신뢰/권한 프롬프트 처리(codex=1, 이후 백엔드는 자체 handler).
|
|
1644
1675
|
await (deps.awaitMission ? deps.awaitMission(waitForQuiet(h, 1500, 20000)) : waitForQuiet(h, 1500, 20000));
|
|
@@ -1648,7 +1679,11 @@ async function runAgentMissionBody(spec: AgentMissionSpec, deps: AgentMissionDep
|
|
|
1648
1679
|
// A trust menu can need more than one key (claude: ↓ to «Yes», then Enter) — answer until it is gone, at most 3 times.
|
|
1649
1680
|
// 🩸 09-29: one pass sent only ↓, the mission text went into the menu and its Enter confirmed «Yes» instead of
|
|
1650
1681
|
// submitting the mission, which then sat unsent in the input box.
|
|
1651
|
-
for (let pass = 0; pass < 3 && backend.handleTrust?.(screen, (s) =>
|
|
1682
|
+
for (let pass = 0; pass < 3 && backend.handleTrust?.(screen, (s) => {
|
|
1683
|
+
drive(s);
|
|
1684
|
+
// Moving the selection is only input; the trust question is answered when the choice is confirmed.
|
|
1685
|
+
if (s === '\r') decisionEvent({ step: 'answer', text: 'Answered folder trust prompt', detail: { question: 'Trust this folder?', answer: 'Confirm selected choice' } });
|
|
1686
|
+
}); pass++) {
|
|
1652
1687
|
debug.log('agent-mission', 'trust', { agent: backend.name, action: 'handled', pass });
|
|
1653
1688
|
const trusted = (async () => { await waitForQuiet(h, 1500, 15000); return capture('trusted'); })();
|
|
1654
1689
|
screen = await (deps.awaitMission ? deps.awaitMission(trusted) : trusted);
|
|
@@ -1761,6 +1796,7 @@ async function runAgentMissionBody(spec: AgentMissionSpec, deps: AgentMissionDep
|
|
|
1761
1796
|
let controllerSummary = deps.previousSummary ?? '';
|
|
1762
1797
|
let reviewSummary = '';
|
|
1763
1798
|
let coverageRetries = enhanceActive && checklist.length ? 2 : 0;
|
|
1799
|
+
let pendingAnswer: { text: string; question: string; answer: string } | undefined;
|
|
1764
1800
|
const search = createMissionSearch({ worktree: wt.path, omniPath });
|
|
1765
1801
|
const brain = createMissionControlBrain({
|
|
1766
1802
|
mission: spec.mission,
|
|
@@ -1768,6 +1804,10 @@ async function runAgentMissionBody(spec: AgentMissionSpec, deps: AgentMissionDep
|
|
|
1768
1804
|
stream: deps.controlStream,
|
|
1769
1805
|
handoffEnabled: true,
|
|
1770
1806
|
onSummary: (summary) => { controllerSummary = summary; },
|
|
1807
|
+
onDecision: (text, reply) => {
|
|
1808
|
+
pendingAnswer = reply ? { text: `${reply.answer || 'continue'}\r`, ...reply } : undefined;
|
|
1809
|
+
decisionEvent({ step: 'judge', text });
|
|
1810
|
+
},
|
|
1771
1811
|
evidenceReady: () => spec.chain && spec.chain.length > 1 ? true : verifyEvidence(wt.path, spec.evidence).ok,
|
|
1772
1812
|
search: async (query, step) => {
|
|
1773
1813
|
usedOmni = true;
|
|
@@ -1784,9 +1824,13 @@ async function runAgentMissionBody(spec: AgentMissionSpec, deps: AgentMissionDep
|
|
|
1784
1824
|
// before asking the LLM — otherwise the mission text is typed into the prompt and the run stalls.
|
|
1785
1825
|
const trustAwareBrain: RunSupervisor = {
|
|
1786
1826
|
decide: (obs, signal) => {
|
|
1827
|
+
pendingAnswer = undefined;
|
|
1787
1828
|
let answer: string | undefined;
|
|
1788
1829
|
if (backend.handleTrust?.(obs.screen, (bytes) => { answer = bytes; }) && answer !== undefined) {
|
|
1789
1830
|
debug.log('agent-mission', 'trust', { agent: backend.name, action: 'handled-in-loop', step: obs.step });
|
|
1831
|
+
decisionEvent({ step: 'judge', text: `step ${obs.step}: trust prompt` });
|
|
1832
|
+
// Only the confirming Enter answers the trust question; a navigation key stays an input event.
|
|
1833
|
+
if (answer === '\r') pendingAnswer = { text: answer, question: 'Trust this folder?', answer: 'Confirm selected choice' };
|
|
1790
1834
|
emitDecision({ kind: 'ROUTE', what: `${backend.name} 폴더 신뢰 화면 → 계속`, reason: '시작 뒤 늦게 뜬 신뢰 확인', purpose: '미션을 이어 간다', target: backend.name, phase: 'implement' });
|
|
1791
1835
|
return { action: 'input', text: answer };
|
|
1792
1836
|
}
|
|
@@ -1872,6 +1916,7 @@ async function runAgentMissionBody(spec: AgentMissionSpec, deps: AgentMissionDep
|
|
|
1872
1916
|
renderPng: () => h.renderScreenPng(),
|
|
1873
1917
|
bus,
|
|
1874
1918
|
ident: { ptyId: h.id, instance: resolveInstanceName(), runId },
|
|
1919
|
+
onPublishedFrame: (obs) => decisionEvent({ step: 'read', text: `step ${obs.step} (${obs.state}): ${classifierFrameLines(obs.screen).at(-1) ?? 'empty screen'}` }),
|
|
1875
1920
|
});
|
|
1876
1921
|
debug.log('agent-mission', 'takeover-wait', { id: h.id, maxWaitMs: AGENT_MISSION_TAKEOVER_WAIT_MS });
|
|
1877
1922
|
const controlRun = runWithControlObserve(
|
|
@@ -1879,9 +1924,24 @@ async function runAgentMissionBody(spec: AgentMissionSpec, deps: AgentMissionDep
|
|
|
1879
1924
|
(d) => debug.log('agent-mission.observe', 'progress', { surfaceId: d.surfaceId, state: d.state, summary: d.summary, unknownInput: d.unknownInput, frame: d.frameCount, runId: d.runId }),
|
|
1880
1925
|
() => {
|
|
1881
1926
|
const handleDeps = controlDepsForHandle(h);
|
|
1927
|
+
const inject = backend.name === 'claude' ? submitSeparately(handleDeps.inject) : handleDeps.inject;
|
|
1882
1928
|
const pending = (deps.runControlLoop ?? runPtyControlLoop)(trustAwareBrain, {
|
|
1883
1929
|
...handleDeps,
|
|
1884
|
-
|
|
1930
|
+
inject: (text) => {
|
|
1931
|
+
const reply = pendingAnswer?.text === text ? pendingAnswer : undefined;
|
|
1932
|
+
pendingAnswer = undefined;
|
|
1933
|
+
const accepted = inject(text);
|
|
1934
|
+
if (accepted) {
|
|
1935
|
+
decisionEvent({ step: 'input', text: `Sent ${text.startsWith('\x1b') ? 'key' : 'text'}: ${text.startsWith('\x1b') ? 'navigation' : text}` });
|
|
1936
|
+
if (reply) decisionEvent({ step: 'answer', text: 'Answered agent question', detail: { question: reply.question, answer: reply.answer } });
|
|
1937
|
+
}
|
|
1938
|
+
return accepted;
|
|
1939
|
+
},
|
|
1940
|
+
injectKey: handleDeps.injectKey && ((name, repeat) => {
|
|
1941
|
+
const accepted = handleDeps.injectKey!(name, repeat);
|
|
1942
|
+
if (accepted) decisionEvent({ step: 'input', text: `Pressed ${name}${repeat ? ` ×${repeat}` : ''}`, detail: { keys: name } });
|
|
1943
|
+
return accepted;
|
|
1944
|
+
}),
|
|
1885
1945
|
...(deps.isMissionAborted ? {
|
|
1886
1946
|
controlStance: () => deps.isMissionAborted!() ? 'unknown' as const : probeControlStance(h, 'agent', (e) =>
|
|
1887
1947
|
debug.log('agent-mission', 'hascontrol-error', { id: h.id, error: (e as Error)?.message ?? String(e) })),
|
|
@@ -1903,7 +1963,11 @@ async function runAgentMissionBody(spec: AgentMissionSpec, deps: AgentMissionDep
|
|
|
1903
1963
|
}
|
|
1904
1964
|
}
|
|
1905
1965
|
},
|
|
1906
|
-
verifyDone: spec.chain && spec.chain.length > 1 ? async () => ({ ok: true as const }) :
|
|
1966
|
+
verifyDone: spec.chain && spec.chain.length > 1 ? async () => ({ ok: true as const }) : async (obs) => {
|
|
1967
|
+
const verdict = await verifyDone(obs);
|
|
1968
|
+
if (!verdict.ok) decisionEvent({ step: 'recover', text: 'Evidence check requires another attempt', detail: { blocked: verdict.retry, action: 'Retry after fixing evidence' } });
|
|
1969
|
+
return verdict;
|
|
1970
|
+
},
|
|
1907
1971
|
handoff: async (decision, obs) => {
|
|
1908
1972
|
try {
|
|
1909
1973
|
if (spec.chain && decision.to !== spec.chain[1]) throw new Error(`chain order violation: expected ${spec.chain[1] ?? 'completion'}, got ${decision.to}`);
|
|
@@ -1916,6 +1980,7 @@ async function runAgentMissionBody(spec: AgentMissionSpec, deps: AgentMissionDep
|
|
|
1916
1980
|
askHuman: async (decision) => {
|
|
1917
1981
|
try {
|
|
1918
1982
|
await waitForHumanLogin(decision, handoffOps);
|
|
1983
|
+
decisionEvent({ step: 'answer', text: 'Human login question resolved', detail: { question: decision.reason, answer: 'Login completed' } });
|
|
1919
1984
|
} catch (error) {
|
|
1920
1985
|
transitionFailure = error instanceof Error ? error.message : String(error);
|
|
1921
1986
|
throw error;
|
|
@@ -1954,7 +2019,9 @@ async function runAgentMissionBody(spec: AgentMissionSpec, deps: AgentMissionDep
|
|
|
1954
2019
|
}
|
|
1955
2020
|
// A gate/PR handoff only counts as success when the control loop itself did not end in error.
|
|
1956
2021
|
if (gatedHandoff && control.termination.kind !== 'error') {
|
|
1957
|
-
|
|
2022
|
+
// The gate hands off a branch, not a file: record what is known instead of mislabeling the worktree directory.
|
|
2023
|
+
decisionEvent({ step: 'done', text: 'Mission handoff gate completed', detail: { result: { kind: 'text', ref: `branch ${wt.branch}` } } });
|
|
2024
|
+
stopLive(true);
|
|
1958
2025
|
try { h.kill(); } catch { /* noop */ }
|
|
1959
2026
|
return { ok: true, worktree: wt.path, branch: wt.branch, rounds: control.steps, evidencePath: wt.path, committed: true, usedOmniCrawl: usedOmni,
|
|
1960
2027
|
...(handoffPrSkipped ? { pr: 'skipped' as const, reason: 'origin-not-github' as const } : {}),
|
|
@@ -1985,6 +2052,7 @@ async function runAgentMissionBody(spec: AgentMissionSpec, deps: AgentMissionDep
|
|
|
1985
2052
|
maxFallbackDescents: runtimeFallback.maxDescents,
|
|
1986
2053
|
});
|
|
1987
2054
|
if (nextBackend && !deps.isMissionAborted?.()) {
|
|
2055
|
+
decisionEvent({ step: 'recover', text: `Switching ${backend.name} to ${nextBackend.name}`, detail: { blocked: control.termination.message, action: `Retry with ${nextBackend.name}` } });
|
|
1988
2056
|
const nextStep: FallbackStep = nextBackend.name === 'grok' ? 'grok' : 'codex-rotate';
|
|
1989
2057
|
stopLive();
|
|
1990
2058
|
if (h.pid) await (deps.terminateProcessTree ?? terminateMissionProcessTree)(h.pid);
|
|
@@ -2019,7 +2087,8 @@ async function runAgentMissionBody(spec: AgentMissionSpec, deps: AgentMissionDep
|
|
|
2019
2087
|
debug.log('agent-mission', 'commit', { ok: c.ok, out: c.out.slice(0, 120) });
|
|
2020
2088
|
}
|
|
2021
2089
|
debug.log('agent-mission', 'result', { ok: finalEv.ok, rounds: round, evidencePath, committed, usedOmni });
|
|
2022
|
-
|
|
2090
|
+
decisionEvent({ step: 'done', text: finalEv.ok ? 'Mission evidence accepted' : 'Mission ended without sufficient evidence', detail: { result: { kind: evidencePath ? 'file' : 'text', ref: evidencePath ?? (control.termination.kind === 'error' ? control.termination.message : 'evidence unavailable') } } });
|
|
2091
|
+
stopLive(finalEv.ok);
|
|
2023
2092
|
if (h.pid) await terminateMissionProcessTree(h.pid);
|
|
2024
2093
|
try { h.kill(); } catch { /* noop */ }
|
|
2025
2094
|
|
|
@@ -2029,6 +2098,7 @@ async function runAgentMissionBody(spec: AgentMissionSpec, deps: AgentMissionDep
|
|
|
2029
2098
|
ptyId: h.id, webUrl: webAddress.webUrl,
|
|
2030
2099
|
detail: done ? '완료(증거 충족)' : (finalEv.ok ? '증거 충족(루프 종료)' : '미완(증거 부족)'),
|
|
2031
2100
|
};
|
|
2101
|
+
} finally { stopLive(); finishContext(false); }
|
|
2032
2102
|
}
|
|
2033
2103
|
|
|
2034
2104
|
/** @deprecated codex 특정 이름 — runAgentMission 을 쓰라(codex 는 기본 backend). */
|
|
@@ -0,0 +1,71 @@
|
|
|
1
|
+
import { debug } from '../debug/log.js';
|
|
2
|
+
|
|
3
|
+
type Identity = {
|
|
4
|
+
ts: string;
|
|
5
|
+
missionId: string;
|
|
6
|
+
seq: number;
|
|
7
|
+
sessionId: string;
|
|
8
|
+
terminalId: string;
|
|
9
|
+
agent: string;
|
|
10
|
+
text: string;
|
|
11
|
+
};
|
|
12
|
+
type Detail = { keys?: string; row?: number };
|
|
13
|
+
|
|
14
|
+
export type PtyDecision = Identity & (
|
|
15
|
+
| { step: 'read' | 'judge' | 'input'; detail?: Detail }
|
|
16
|
+
| { step: 'answer'; detail: Detail & { question: string; answer: string } }
|
|
17
|
+
| { step: 'recover'; detail: Detail & { blocked: string; action: string } }
|
|
18
|
+
| { step: 'done'; detail: Detail & { result: { kind: 'pr' | 'file' | 'text'; ref: string } } }
|
|
19
|
+
);
|
|
20
|
+
|
|
21
|
+
export type DecisionInput = Omit<Identity, 'ts' | 'seq'> & (
|
|
22
|
+
| { step: 'read' | 'judge' | 'input'; detail?: Detail }
|
|
23
|
+
| { step: 'answer'; detail: Detail & { question: string; answer: string } }
|
|
24
|
+
| { step: 'recover'; detail: Detail & { blocked: string; action: string } }
|
|
25
|
+
| { step: 'done'; detail: Detail & { result: { kind: 'pr' | 'file' | 'text'; ref: string } } }
|
|
26
|
+
);
|
|
27
|
+
|
|
28
|
+
const missionStreams = new Map<string, { alias: string; seq: number }>();
|
|
29
|
+
export const PTY_DECISION_TEXT_MAX = 240;
|
|
30
|
+
|
|
31
|
+
function safe(value: string): string {
|
|
32
|
+
const masked = value
|
|
33
|
+
.replace(/\bBearer\s+(?:"[^"]*"|'[^']*'|[^\s"'<>]+)/gi, 'Bearer [redacted]')
|
|
34
|
+
.replace(/\b([a-z0-9_]*(?:token|key(?:[_-]?id)?|secret|password|authorization)\s*[:=]\s*)(?:"[^"]*"|'[^']*'|[^\s"'<>]+)/gi, '$1[redacted]')
|
|
35
|
+
.replace(/\b(?:sk-[a-z0-9_-]+|gh[pousr]_[a-z0-9_]+|github_pat_[a-z0-9_]+|AIza[a-z0-9_-]+|xox[baprs]-[a-z0-9-]+)\b/gi, '[redacted]')
|
|
36
|
+
.replace(/\b[A-Z0-9._%+-]+@[A-Z0-9.-]+\.[A-Z]{2,}\b/gi, '[redacted]')
|
|
37
|
+
.replace(/[\x00-\x1f\x7f-\x9f]/g, ' ')
|
|
38
|
+
.trim();
|
|
39
|
+
const clipped = masked.slice(0, PTY_DECISION_TEXT_MAX);
|
|
40
|
+
return clipped.replace(/[\uD800-\uDBFF]$/, '') || '[redacted]';
|
|
41
|
+
}
|
|
42
|
+
|
|
43
|
+
/** The only emission point for the inside-PTY decision stream. Never log unsanitized input. */
|
|
44
|
+
export function emitPtyDecision(input: DecisionInput, log: typeof debug.log = debug.log): PtyDecision {
|
|
45
|
+
let stream = missionStreams.get(input.missionId);
|
|
46
|
+
if (!stream) {
|
|
47
|
+
stream = { alias: `mission-${missionStreams.size + 1}`, seq: -1 };
|
|
48
|
+
missionStreams.set(input.missionId, stream);
|
|
49
|
+
}
|
|
50
|
+
stream.seq += 1;
|
|
51
|
+
const base = {
|
|
52
|
+
ts: new Date().toISOString(),
|
|
53
|
+
missionId: stream.alias,
|
|
54
|
+
seq: stream.seq,
|
|
55
|
+
sessionId: safe(input.sessionId),
|
|
56
|
+
terminalId: safe(input.terminalId),
|
|
57
|
+
agent: safe(input.agent),
|
|
58
|
+
text: safe(input.text),
|
|
59
|
+
};
|
|
60
|
+
const common = input.detail ? {
|
|
61
|
+
...(input.detail.keys !== undefined ? { keys: safe(input.detail.keys) } : {}),
|
|
62
|
+
...(input.detail.row !== undefined ? { row: input.detail.row } : {}),
|
|
63
|
+
} : {};
|
|
64
|
+
let decision: PtyDecision;
|
|
65
|
+
if (input.step === 'answer') decision = { ...base, step: input.step, detail: { ...common, question: safe(input.detail.question), answer: safe(input.detail.answer) } };
|
|
66
|
+
else if (input.step === 'recover') decision = { ...base, step: input.step, detail: { ...common, blocked: safe(input.detail.blocked), action: safe(input.detail.action) } };
|
|
67
|
+
else if (input.step === 'done') decision = { ...base, step: input.step, detail: { ...common, result: { kind: input.detail.result.kind, ref: safe(input.detail.result.ref) } } };
|
|
68
|
+
else decision = { ...base, step: input.step, ...(input.detail ? { detail: common } : {}) };
|
|
69
|
+
log('pty.decision', decision.step, decision);
|
|
70
|
+
return decision;
|
|
71
|
+
}
|
|
@@ -11,6 +11,7 @@ import { runGitCommand } from '../git-fs/runner.js';
|
|
|
11
11
|
import * as llm from '../llm.js';
|
|
12
12
|
import type { LLMMessage } from '../llm.js';
|
|
13
13
|
import { debug } from '../debug/log.js';
|
|
14
|
+
import { releasePathHold, releasePathHoldShouldPost, releasePathHoldComment, releasePathHoldCommentsArgs, releasePrFilePaths, RELEASE_PATH_LABEL } from '../self-dev/release-path-guard.js';
|
|
14
15
|
import { runAgentMission, resolveBackend, type AgentMissionResult, type EvidenceMode } from './driver.js';
|
|
15
16
|
import { judgeWithAcp, prepareJudgeDiff } from './acp-judge.js';
|
|
16
17
|
import { verifyMergeAndMaybeRevert } from './merge-safety.js';
|
|
@@ -114,6 +115,31 @@ function gh(args: string[]): string {
|
|
|
114
115
|
return execFileSync('gh', args, { encoding: 'utf8', timeout: 60000, maxBuffer: 20 * 1024 * 1024, env: process.env });
|
|
115
116
|
}
|
|
116
117
|
|
|
118
|
+
/** Check every page of the PR file list immediately before an unattended review-loop merge. */
|
|
119
|
+
function holdReleasePathBeforeReviewMerge(pr: string, runGh: (args: string[]) => string): boolean {
|
|
120
|
+
let paths: string[];
|
|
121
|
+
try {
|
|
122
|
+
paths = releasePrFilePaths(JSON.parse(runGh(['api', '--paginate', '--slurp', '--method', 'GET', '-f', 'per_page=100', `repos/{owner}/{repo}/pulls/${pr}/files`])));
|
|
123
|
+
} catch (error) {
|
|
124
|
+
debug.log('self-dev.merge', 'release-path-inspection-failed', { pr, error: String(error) });
|
|
125
|
+
return true;
|
|
126
|
+
}
|
|
127
|
+
const path = releasePathHold(paths);
|
|
128
|
+
if (!path) return false;
|
|
129
|
+
debug.log('self-dev.merge', 'release-path-hold', { pr, path, label: RELEASE_PATH_LABEL, surface: 'review-loop' });
|
|
130
|
+
try {
|
|
131
|
+
const names: unknown = JSON.parse(runGh(['label', 'list', '--search', RELEASE_PATH_LABEL, '--json', 'name']));
|
|
132
|
+
if (!Array.isArray(names)) throw new Error('invalid label list');
|
|
133
|
+
if (!names.some((item: unknown) => !!item && typeof item === 'object' && 'name' in item && item.name === RELEASE_PATH_LABEL)) {
|
|
134
|
+
runGh(['label', 'create', RELEASE_PATH_LABEL, '--color', 'D93F0B', '--description', 'Release path requires OP approval']);
|
|
135
|
+
}
|
|
136
|
+
runGh(['pr', 'edit', pr, '--add-label', RELEASE_PATH_LABEL]);
|
|
137
|
+
} catch (error) { debug.log('self-dev.merge', 'release-path-annotation-failed', { pr, action: 'label', error: String(error) }); }
|
|
138
|
+
try { if (releasePathHoldShouldPost(() => JSON.parse(runGh(releasePathHoldCommentsArgs(pr))))) runGh(['pr', 'comment', pr, '--body', releasePathHoldComment(path)]); }
|
|
139
|
+
catch (error) { debug.log('self-dev.merge', 'release-path-annotation-failed', { pr, action: 'comment', error: String(error) }); }
|
|
140
|
+
return true;
|
|
141
|
+
}
|
|
142
|
+
|
|
117
143
|
/** ★ G10 안전봉투 — 자율머지 직후 회귀검증(verifyMerge 시). 회귀면 revert PR 이 이미 생성됨(알림 포함) →
|
|
118
144
|
* 원 PR 에 링크 코멘트만. fail-open(검증 오류는 머지를 막지 않음). */
|
|
119
145
|
async function runMergeSafety(pr: string, opts: ReviewLoopOpts, depth: ReviewDepth): Promise<void> {
|
|
@@ -233,6 +259,7 @@ export async function judgeAndFinalize(
|
|
|
233
259
|
|
|
234
260
|
if (j.verdict === 'merge') {
|
|
235
261
|
if (opts.autoMerge) {
|
|
262
|
+
if (holdReleasePathBeforeReviewMerge(pr, runGh)) return { pr, branch, verdict: 'reinforce', asks, action: 'parked', reworkOk: true, pushed: lastPushed, rounds: round, detail: 'OP approval required: release-path hold or PR file inspection unavailable' };
|
|
236
263
|
const approve = opts.approve ?? approvePr;
|
|
237
264
|
const recordReviewOutcome = opts.recordReviewOutcome ?? recordOutcome;
|
|
238
265
|
approve(pr, `2차 ACP 최종심판 MERGE (round ${round})`);
|
|
@@ -480,6 +507,9 @@ export async function runReviewLoop(pr: string, opts: ReviewLoopOpts = {}): Prom
|
|
|
480
507
|
if (cls.verdict === 'ok') {
|
|
481
508
|
// light: 1차 clean 으로 충분 → approve + 머지. heavy: 1차 ok 여도 2차 심판 머스트.
|
|
482
509
|
if (!effectiveFinalJudge) {
|
|
510
|
+
if ((opts.autoMergeOnOk || opts.autoMerge) && holdReleasePathBeforeReviewMerge(pr, runGh)) {
|
|
511
|
+
return { pr, branch, verdict: 'ok', asks: [], action: 'parked', detail: 'OP approval required: release-path hold or PR file inspection unavailable' };
|
|
512
|
+
}
|
|
483
513
|
approve(pr, `소작업(light)·1차 리뷰 clean`);
|
|
484
514
|
let merged = false;
|
|
485
515
|
if (opts.autoMergeOnOk || opts.autoMerge) {
|
|
@@ -9,6 +9,17 @@ import { join } from 'node:path';
|
|
|
9
9
|
import { readFileSync, writeFileSync } from 'node:fs';
|
|
10
10
|
import { runGitCommand } from '../../git-fs/runner.js';
|
|
11
11
|
import { countTestDeclarations } from '../../self-implement/test-declarations.js';
|
|
12
|
+
import { NEXT_MD_PATH, resolveNextMdConflict } from '../../release-loop/next-md-merge.js';
|
|
13
|
+
|
|
14
|
+
function deterministicNextMd(git: MergeGitSeam, worktreePath: string, file: string): string | null {
|
|
15
|
+
try {
|
|
16
|
+
const resolved = resolveNextMdConflict(git.readIndexStage(worktreePath, 1, file), git.readIndexStage(worktreePath, 2, file), git.readIndexStage(worktreePath, 3, file));
|
|
17
|
+
void import('../../debug/log.js').then(({ debug }) => debug.log('self-dev.merge', 'next-md-deterministic', { resolved: resolved !== null })).catch(() => {});
|
|
18
|
+
return resolved;
|
|
19
|
+
} catch {
|
|
20
|
+
return null; // a stage is missing (added/deleted on one side) — the usual resolver decides
|
|
21
|
+
}
|
|
22
|
+
}
|
|
12
23
|
|
|
13
24
|
/** 충돌 마커가 남아있나(LLM 이 해결 못 함 판별). ours/base/theirs 3-way 마커 모두. 순수. */
|
|
14
25
|
export function hasConflictMarkers(s: string): boolean {
|
|
@@ -130,8 +141,8 @@ export interface MergeGitSeam {
|
|
|
130
141
|
merge: (wt: string, mergeTarget: string) => { ok: boolean; conflict: boolean; stdout: string; errorDetail?: string };
|
|
131
142
|
/** 충돌(unmerged) 파일 목록(worktree 상대 경로). */
|
|
132
143
|
conflictedFiles: (wt: string) => string[];
|
|
133
|
-
/** Reads an unmerged index stage (2=ours, 3=theirs) for a conflicted file. */
|
|
134
|
-
readIndexStage: (wt: string, stage: 2 | 3, file: string) => string;
|
|
144
|
+
/** Reads an unmerged index stage (1=base, 2=ours, 3=theirs) for a conflicted file. */
|
|
145
|
+
readIndexStage: (wt: string, stage: 1 | 2 | 3, file: string) => string;
|
|
135
146
|
readFile: (absPath: string) => string;
|
|
136
147
|
writeFile: (absPath: string, content: string) => void;
|
|
137
148
|
/** 해결된 파일 스테이징. */
|
|
@@ -193,7 +204,9 @@ export async function mergeMainWithLlmResolve(
|
|
|
193
204
|
let merged: string;
|
|
194
205
|
try {
|
|
195
206
|
conflicted = git.readFile(abs);
|
|
196
|
-
|
|
207
|
+
// release/next.md: concurrent landings each append a line — keep both without asking the LLM (REL7c).
|
|
208
|
+
const deterministic = f === NEXT_MD_PATH ? deterministicNextMd(git, worktreePath, f) : null;
|
|
209
|
+
merged = deterministic ?? await resolve(f, conflicted);
|
|
197
210
|
} catch {
|
|
198
211
|
git.abort(worktreePath); // LLM 예외 → base 유지
|
|
199
212
|
return measuredOutcome({ status: 'conflict-unresolved', resolvedFiles });
|
|
@@ -116,6 +116,8 @@ export async function runDaemonPromptTurn(opts: {
|
|
|
116
116
|
* `--tool-cwd` / `ELANOUS_TOOL_CWD` to keep `/v1/prompt` and ACP WS
|
|
117
117
|
* on the same path-guard boundary. */
|
|
118
118
|
toolCwd?: string;
|
|
119
|
+
/** Per-turn project instructions; unlike the base system preamble these must survive subsequent turns. */
|
|
120
|
+
projectInstructions?: string;
|
|
119
121
|
/** Phase 4 (WT-A-3b) — external abort signal. When provided and
|
|
120
122
|
* fired, the internal AbortController fans the abort through to
|
|
121
123
|
* `runCoreTurn` (LLM stream + tool dispatch). Callers without an
|
|
@@ -286,6 +288,9 @@ export async function runDaemonPromptTurn(opts: {
|
|
|
286
288
|
if (fast && !isFirstTurn) {
|
|
287
289
|
messages.unshift({ role: 'system', content: fastPathGuidance });
|
|
288
290
|
}
|
|
291
|
+
if (!isFirstTurn && opts.projectInstructions) {
|
|
292
|
+
messages.unshift({ role: 'system', content: opts.projectInstructions });
|
|
293
|
+
}
|
|
289
294
|
const result = await runCoreTurn({
|
|
290
295
|
sessionId: request.sessionId,
|
|
291
296
|
userText: request.userText,
|
|
@@ -53,6 +53,7 @@ import {
|
|
|
53
53
|
import type { CoreTurnDispatchTool } from '../core-turn/index.js';
|
|
54
54
|
import { elanousSelfAccessPrompt } from '../agent/self-ambient.js';
|
|
55
55
|
import { createToolCwdResolver, type ToolCwdResolver } from './tool-cwd.js';
|
|
56
|
+
import { resolveSessionProjectContext } from '../project/session-context.js';
|
|
56
57
|
import { debug } from '../debug/log.js';
|
|
57
58
|
|
|
58
59
|
/** C4 (2026-07-12) — arm the non-detached-PTY kill ONCE per turn signal.
|
|
@@ -579,7 +580,9 @@ export function createDaemonRunTurn(
|
|
|
579
580
|
// moved this out of an inline closure to fix the user-message
|
|
580
581
|
// persistence bug uniformly across all daemon paths.
|
|
581
582
|
getMessages: ({ sessionId, userText, promptBlocks, promptMeta }) => {
|
|
582
|
-
const
|
|
583
|
+
const projectInstructions = resolveSessionProjectContext(sessionId)?.instructions;
|
|
584
|
+
const baseSystemPrompt = [composeDaemonSystemPrompt(opts.systemPrompt, promptMeta, sessionId), projectInstructions]
|
|
585
|
+
.filter(Boolean).join('\n\n');
|
|
583
586
|
// Image-pipeline followup #4 (2026-05-05) — append daemon webterm
|
|
584
587
|
// context (current ACP sessionId + active terminal summary) to
|
|
585
588
|
// the system prompt when the webterm surface is active. Helper
|
|
@@ -720,8 +723,11 @@ export function createDaemonRunTurn(
|
|
|
720
723
|
});
|
|
721
724
|
debugBridge.activate();
|
|
722
725
|
}
|
|
723
|
-
|
|
724
|
-
|
|
726
|
+
const projectCwd = resolveSessionProjectContext(turnCtx.sessionId)?.cwd;
|
|
727
|
+
if (projectCwd || opts.acpSessionCwd) {
|
|
728
|
+
// An ACP session's explicit cwd wins; the project folder is only the default when none was given (IA3 review).
|
|
729
|
+
const explicitCwd = opts.acpSessionCwd && turnCtx.cwd ? turnCtx.cwd : undefined;
|
|
730
|
+
const resolver = createToolCwdResolver({ tools: opts.tools ?? 'none', toolCwd: explicitCwd ?? projectCwd ?? turnCtx.cwd });
|
|
725
731
|
await turnToolCwd.run(resolver, () => inner(turnCtx));
|
|
726
732
|
} else {
|
|
727
733
|
await inner(turnCtx);
|
|
@@ -23,6 +23,8 @@ export interface DaemonWebSearchArgs {
|
|
|
23
23
|
export interface DaemonWebSearchResult {
|
|
24
24
|
query: string;
|
|
25
25
|
providerName: string;
|
|
26
|
+
/** Absent for ordinary searches; signals whether X sources were actually cited. */
|
|
27
|
+
xSearch?: 'grok' | 'unavailable';
|
|
26
28
|
hits: Array<{
|
|
27
29
|
url: string;
|
|
28
30
|
title: string;
|
|
@@ -90,6 +92,7 @@ export async function dispatchWebSearch(
|
|
|
90
92
|
return {
|
|
91
93
|
query,
|
|
92
94
|
providerName: result.providerName,
|
|
95
|
+
...(result.xSearch ? { xSearch: result.xSearch } : {}),
|
|
93
96
|
hits: result.hits.map((h) => ({
|
|
94
97
|
url: h.url,
|
|
95
98
|
title: h.title,
|