elanous 0.2.6 → 0.2.8
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/.env.example +10 -7
- package/README.md +4 -0
- package/apps/pwa/out/404/index.html +1 -1
- package/apps/pwa/out/404.html +1 -1
- package/apps/pwa/out/_next/static/chunks/1105-c473ed46272fba79.js +1 -0
- package/apps/pwa/out/_next/static/chunks/1201-09613bce624467c0.js +1 -0
- package/apps/pwa/out/_next/static/chunks/1377-1efeffbbac0963ff.js +1 -0
- package/apps/pwa/out/_next/static/chunks/1470.98a6ab61ccb4131c.js +1 -0
- package/apps/pwa/out/_next/static/chunks/216-5acd01cbde4acda7.js +1 -0
- package/apps/pwa/out/_next/static/chunks/2330-c2f07246c8788af1.js +1 -0
- package/apps/pwa/out/_next/static/chunks/{3995-bee512a7063036ce.js → 2375-cb6debea56cce4fb.js} +1 -1
- package/apps/pwa/out/_next/static/chunks/2415.ed6428ff334c7ce2.js +1 -0
- package/apps/pwa/out/_next/static/chunks/2929-617f1e66a55be184.js +1 -0
- package/apps/pwa/out/_next/static/chunks/2977-e38442e86289f1d3.js +1 -0
- package/apps/pwa/out/_next/static/chunks/2982-2a2df543be3d2e5a.js +25 -0
- package/apps/pwa/out/_next/static/chunks/{8d0d9faf-97887ff99713b84e.js → 2ea96958-e8c7e112de50b067.js} +1 -1
- package/apps/pwa/out/_next/static/chunks/{5329.8b7e4bca684b6eec.js → 3403.4bc97b4066945a94.js} +2 -2
- package/apps/pwa/out/_next/static/chunks/3441-a1dd4acfeda14488.js +1 -0
- package/apps/pwa/out/_next/static/chunks/371-4ad6af55dad02ced.js +1 -0
- package/apps/pwa/out/_next/static/chunks/4114-3e63117452378807.js +1 -0
- package/apps/pwa/out/_next/static/chunks/{7633.0654fe6ea259c1ee.js → 4323.c5dfb6f503304775.js} +1 -1
- package/apps/pwa/out/_next/static/chunks/4836-3084c58c1725a40b.js +1 -0
- package/apps/pwa/out/_next/static/chunks/{2984-977cfa339fcd65a5.js → 5080-1613752891fcadb4.js} +3 -3
- package/apps/pwa/out/_next/static/chunks/5609-012bb3557211f07e.js +1 -0
- package/apps/pwa/out/_next/static/chunks/{763-7d0e1913b5074e98.js → 5791-bb82743fa6299562.js} +1 -1
- package/apps/pwa/out/_next/static/chunks/{4240-7153881b0b377306.js → 6062-73e68343a9814f6a.js} +1 -1
- package/apps/pwa/out/_next/static/chunks/6090-85a3f05f954e5697.js +1 -0
- package/apps/pwa/out/_next/static/chunks/6284-69db415193d5f8bd.js +1 -0
- package/apps/pwa/out/_next/static/chunks/6320-baac91d68843a9a6.js +1 -0
- package/apps/pwa/out/_next/static/chunks/6416-505ba707cacafbba.js +1 -0
- package/apps/pwa/out/_next/static/chunks/6725-68ab7cc0b1faf00d.js +1 -0
- package/apps/pwa/out/_next/static/chunks/6998-a654fe5c58271600.js +1 -0
- package/apps/pwa/out/_next/static/chunks/7032-f4ef698518fba61c.js +1 -0
- package/apps/pwa/out/_next/static/chunks/7647.2fcd30d894d5ee30.js +1 -0
- package/apps/pwa/out/_next/static/chunks/7673-2eda1507d38dadb8.js +1 -0
- package/apps/pwa/out/_next/static/chunks/7990-e12efba616f46e03.js +1 -0
- package/apps/pwa/out/_next/static/chunks/{91ff6dda-3b33d42d20657429.js → 8046cadf-211ca3c0e00f2b72.js} +1 -1
- package/apps/pwa/out/_next/static/chunks/8067-d976b441a104ab74.js +1 -0
- package/apps/pwa/out/_next/static/chunks/8142-744998d65d7bb17e.js +1 -0
- package/apps/pwa/out/_next/static/chunks/8519-5632377cce994f86.js +1 -0
- package/apps/pwa/out/_next/static/chunks/8619-4365e03a2862830f.js +1 -0
- package/apps/pwa/out/_next/static/chunks/8894-7317998f6cb97d8c.js +1 -0
- package/apps/pwa/out/_next/static/chunks/920-f7dceb78f1c585ef.js +1 -0
- package/apps/pwa/out/_next/static/chunks/9454-a3e0953307216c58.js +1 -0
- package/apps/pwa/out/_next/static/chunks/9651-3cd291a6fa1370d2.js +1 -0
- package/apps/pwa/out/_next/static/chunks/9740-8f5ff96c522b5f55.js +1 -0
- package/apps/pwa/out/_next/static/chunks/ae787e4c-f2998de7f1ba72a4.js +1 -0
- package/apps/pwa/out/_next/static/chunks/app/_not-found/page-859cea1570b6227a.js +1 -0
- package/apps/pwa/out/_next/static/chunks/app/approvals/page-9aa47b0bc6d570ff.js +1 -0
- package/apps/pwa/out/_next/static/chunks/app/autopilot/page-f4d2ecbbae6088d6.js +1 -0
- package/apps/pwa/out/_next/static/chunks/app/board/page-2053e49930c82748.js +1 -0
- package/apps/pwa/out/_next/static/chunks/app/botlab/page-d4b6df905f185055.js +1 -0
- package/apps/pwa/out/_next/static/chunks/app/bots/page-a70ba27c33003dd0.js +1 -0
- package/apps/pwa/out/_next/static/chunks/app/chat/page-186fc6952f027acc.js +1 -0
- package/apps/pwa/out/_next/static/chunks/app/consult/page-18166f885d831d3e.js +1 -0
- package/apps/pwa/out/_next/static/chunks/app/control/page-1c9d6cfe68b121c2.js +1 -0
- package/apps/pwa/out/_next/static/chunks/app/design-check/page-cbbe03c0da7b081a.js +1 -0
- package/apps/pwa/out/_next/static/chunks/app/editor/page-c108ff1fdb665c97.js +1 -0
- package/apps/pwa/out/_next/static/chunks/app/exec/page-147a328753d983e2.js +1 -0
- package/apps/pwa/out/_next/static/chunks/app/field/page-799395a9df7d95aa.js +1 -0
- package/apps/pwa/out/_next/static/chunks/app/healthz/route-859cea1570b6227a.js +1 -0
- package/apps/pwa/out/_next/static/chunks/app/intake/page-6a8158b71d1fe9d7.js +1 -0
- package/apps/pwa/out/_next/static/chunks/app/layout-9567560270857531.js +1 -0
- package/apps/pwa/out/_next/static/chunks/app/live/page-e7ed3d010153d818.js +1 -0
- package/apps/pwa/out/_next/static/chunks/app/market/page-c0c0d19d51342d3e.js +1 -0
- package/apps/pwa/out/_next/static/chunks/app/missions/[id]/page-2e002ad8faa43291.js +1 -0
- package/apps/pwa/out/_next/static/chunks/app/morning/page-b672e02e4bec8deb.js +1 -0
- package/apps/pwa/out/_next/static/chunks/app/not-found-1ba4a5d857276334.js +1 -0
- package/apps/pwa/out/_next/static/chunks/app/observatory/page-9db2226f38c542fb.js +1 -0
- package/apps/pwa/out/_next/static/chunks/app/page-70ee65f5f7a151dc.js +1 -0
- package/apps/pwa/out/_next/static/chunks/app/reflection/page-0bb8e43203efb23b.js +1 -0
- package/apps/pwa/out/_next/static/chunks/app/scheduler/page-092e1bcf27d751cc.js +1 -0
- package/apps/pwa/out/_next/static/chunks/app/sessions/page-eb52580c4b75b905.js +1 -0
- package/apps/pwa/out/_next/static/chunks/app/settings/devices/page-7464c1987dd76e6d.js +1 -0
- package/apps/pwa/out/_next/static/chunks/app/settings/page-e573437b0a1c728f.js +1 -0
- package/apps/pwa/out/_next/static/chunks/app/setup/done/page-294300625e49e4d3.js +1 -0
- package/apps/pwa/out/_next/static/chunks/app/setup/layout-859cea1570b6227a.js +1 -0
- package/apps/pwa/out/_next/static/chunks/app/setup/page-085847b088675978.js +1 -0
- package/apps/pwa/out/_next/static/chunks/app/share/page-9fe9d38c36999eb4.js +1 -0
- package/apps/pwa/out/_next/static/chunks/app/showroom/page-d8ab4d1489223459.js +1 -0
- package/apps/pwa/out/_next/static/chunks/app/tasks/page-6141f67f531d8b6a.js +1 -0
- package/apps/pwa/out/_next/static/chunks/app/term/page-295a02b1026b8255.js +1 -0
- package/apps/pwa/out/_next/static/chunks/app/trace/page-1eb9a0e1e054209d.js +1 -0
- package/apps/pwa/out/_next/static/chunks/app/vault/page-82efa177a30f3741.js +1 -0
- package/apps/pwa/out/_next/static/chunks/app/workflows/chat-ui/page-d0be51cec4f62606.js +1 -0
- package/apps/pwa/out/_next/static/chunks/app/workflows/page-2e367075ffdbc062.js +1 -0
- package/apps/pwa/out/_next/static/chunks/app/workspace/page-647ed2b66c1d49f1.js +1 -0
- package/apps/pwa/out/_next/static/chunks/app/worktrees/page-ba058c56e38f2792.js +1 -0
- package/apps/pwa/out/_next/static/chunks/framework-ea806bb57f2b8923.js +1 -0
- package/apps/pwa/out/_next/static/chunks/main-8d2302399c2c8f87.js +1 -0
- package/apps/pwa/out/_next/static/chunks/main-app-6870f30ea99f8346.js +1 -0
- package/apps/pwa/out/_next/static/chunks/pages/_app-b10928c60f0b8488.js +1 -0
- package/apps/pwa/out/_next/static/chunks/pages/_error-689039227d443fab.js +1 -0
- package/apps/pwa/out/_next/static/chunks/{webpack-37b8bf78a3c6eec5.js → webpack-e5bea36f183b25e6.js} +1 -1
- package/apps/pwa/out/_next/static/css/5ef72a618a8994f3.css +1 -0
- package/apps/pwa/out/_next/static/lywc8m_HDzH9MKSDQhyEj/_buildManifest.js +1 -0
- package/apps/pwa/out/approvals/index.html +1 -1
- package/apps/pwa/out/approvals/index.txt +22 -22
- package/apps/pwa/out/autopilot/index.html +1 -1
- package/apps/pwa/out/autopilot/index.txt +22 -22
- package/apps/pwa/out/board/index.html +1 -1
- package/apps/pwa/out/board/index.txt +22 -22
- package/apps/pwa/out/botlab/index.html +1 -1
- package/apps/pwa/out/botlab/index.txt +21 -21
- package/apps/pwa/out/bots/index.html +1 -1
- package/apps/pwa/out/bots/index.txt +21 -21
- package/apps/pwa/out/chat/index.html +1 -1
- package/apps/pwa/out/chat/index.txt +21 -21
- package/apps/pwa/out/consult/index.html +1 -0
- package/apps/pwa/out/consult/index.txt +32 -0
- package/apps/pwa/out/control/index.html +1 -1
- package/apps/pwa/out/control/index.txt +22 -22
- package/apps/pwa/out/design-check/index.html +1 -1
- package/apps/pwa/out/design-check/index.txt +22 -22
- package/apps/pwa/out/editor/index.html +1 -1
- package/apps/pwa/out/editor/index.txt +22 -22
- package/apps/pwa/out/exec/index.html +1 -0
- package/apps/pwa/out/exec/index.txt +32 -0
- package/apps/pwa/out/field/index.html +1 -0
- package/apps/pwa/out/field/index.txt +32 -0
- package/apps/pwa/out/healthz +1 -1
- package/apps/pwa/out/index.html +1 -1
- package/apps/pwa/out/index.txt +21 -21
- package/apps/pwa/out/intake/index.html +1 -1
- package/apps/pwa/out/intake/index.txt +22 -22
- package/apps/pwa/out/live/index.html +1 -1
- package/apps/pwa/out/live/index.txt +22 -22
- package/apps/pwa/out/market/index.html +1 -1
- package/apps/pwa/out/market/index.txt +21 -21
- package/apps/pwa/out/missions/placeholder/index.html +1 -1
- package/apps/pwa/out/missions/placeholder/index.txt +21 -21
- package/apps/pwa/out/morning/index.html +1 -1
- package/apps/pwa/out/morning/index.txt +22 -22
- package/apps/pwa/out/observatory/index.html +1 -1
- package/apps/pwa/out/observatory/index.txt +22 -22
- package/apps/pwa/out/reflection/index.html +1 -1
- package/apps/pwa/out/reflection/index.txt +22 -22
- package/apps/pwa/out/scheduler/index.html +1 -1
- package/apps/pwa/out/scheduler/index.txt +22 -22
- package/apps/pwa/out/sessions/index.html +1 -1
- package/apps/pwa/out/sessions/index.txt +21 -21
- package/apps/pwa/out/settings/devices/index.html +1 -1
- package/apps/pwa/out/settings/devices/index.txt +22 -22
- package/apps/pwa/out/settings/index.html +1 -1
- package/apps/pwa/out/settings/index.txt +22 -22
- package/apps/pwa/out/setup/done/index.html +1 -1
- package/apps/pwa/out/setup/done/index.txt +22 -22
- package/apps/pwa/out/setup/index.html +1 -1
- package/apps/pwa/out/setup/index.txt +22 -22
- package/apps/pwa/out/share/index.html +1 -1
- package/apps/pwa/out/share/index.txt +22 -22
- package/apps/pwa/out/showroom/index.html +1 -1
- package/apps/pwa/out/showroom/index.txt +21 -21
- package/apps/pwa/out/tasks/index.html +1 -1
- package/apps/pwa/out/tasks/index.txt +22 -22
- package/apps/pwa/out/term/index.html +1 -1
- package/apps/pwa/out/term/index.txt +22 -22
- package/apps/pwa/out/trace/index.html +1 -1
- package/apps/pwa/out/trace/index.txt +22 -22
- package/apps/pwa/out/vault/index.html +1 -1
- package/apps/pwa/out/vault/index.txt +22 -22
- package/apps/pwa/out/workflows/chat-ui/index.html +1 -1
- package/apps/pwa/out/workflows/chat-ui/index.txt +22 -22
- package/apps/pwa/out/workflows/index.html +1 -1
- package/apps/pwa/out/workflows/index.txt +22 -22
- package/apps/pwa/out/workspace/index.html +1 -1
- package/apps/pwa/out/workspace/index.txt +22 -22
- package/apps/pwa/out/worktrees/index.html +1 -1
- package/apps/pwa/out/worktrees/index.txt +22 -22
- package/bin/elanous.cjs +107 -0
- package/graphs/field/field-feed.yaml +24 -0
- package/graphs/field/recipes.yaml +12 -0
- package/graphs/landing/landing-heal.yaml +3 -1
- package/graphs/landing/recipes.yaml +3 -0
- package/graphs/release/recipes.yaml +10 -0
- package/graphs/release/release-loop.yaml +10 -3
- package/graphs/test-diet/recipes.yaml +9 -0
- package/graphs/test-diet/test-diet.yaml +22 -0
- package/package.json +6 -5
- package/persona-presets/_index.yaml +10 -0
- package/persona-presets/_schema.json +146 -0
- package/persona-presets/dana.yaml +26 -0
- package/persona-presets/haru.yaml +27 -0
- package/persona-presets/kai.yaml +27 -0
- package/persona-presets/leo.yaml +27 -0
- package/persona-presets/mira.yaml +30 -0
- package/persona-presets/nari.yaml +27 -0
- package/persona-presets/sora.yaml +27 -0
- package/persona-presets/yuna.yaml +27 -0
- package/plugins/card-followup/README.md +13 -4
- package/plugins/card-followup/graphs/card-followup.yaml +3 -1
- package/plugins/card-followup/graphs/recipes.yaml +5 -1
- package/plugins/card-followup/graphs/run-step.ts +122 -18
- package/plugins/card-followup/graphs/sales-strategy.ts +173 -0
- package/plugins/card-followup/plugin.json +1 -1
- package/plugins/doc-draft/README.md +13 -0
- package/plugins/doc-draft/examples/brief-sample.json +8 -0
- package/plugins/doc-draft/graphs/doc-draft.yaml +14 -0
- package/plugins/doc-draft/graphs/recipes.yaml +9 -0
- package/plugins/doc-draft/graphs/run-step.ts +113 -0
- package/plugins/doc-draft/plugin.json +24 -0
- package/plugins/geo-check/README.md +3 -1
- package/plugins/geo-check/graphs/run-step.ts +58 -13
- package/plugins/geo-check/plugin.json +1 -1
- package/plugins/job-coach/.codex-plugin/plugin.json +1 -1
- package/plugins/job-coach/README.md +1 -1
- package/plugins/job-coach/graphs/run-step.ts +2 -2
- package/plugins/job-coach/plugin.json +1 -1
- package/plugins/job-coach/plugin.ts +1 -1
- package/scripts/affinity/endcard.sh +3 -2
- package/scripts/affinity/reframe.sh +3 -1
- package/scripts/ci-public-export-leak-gate.ts +48 -0
- package/scripts/codex-quota-alert.ts +122 -258
- package/scripts/coord-tracks.json +4 -4
- package/scripts/field-feed/deliver-node.ts +57 -0
- package/scripts/field-feed/feed-node.ts +67 -0
- package/scripts/field-feed/lib.ts +164 -0
- package/scripts/field-feed/reel-node.ts +24 -0
- package/scripts/field-feed/start.ts +62 -0
- package/scripts/fixtures/vflow-sample.ndjson +6 -0
- package/scripts/install.sh +109 -21
- package/scripts/landing-heal/clean-checkout.ts +114 -0
- package/scripts/landing-heal/run-mission.ts +38 -3
- package/scripts/lib/pwa-scenarios/scenarios.ts +2 -1
- package/scripts/persona-presets/lint.ts +79 -0
- package/scripts/public-export.ts +8 -4
- package/scripts/release-loop/baseline-from-logs.ts +92 -0
- package/scripts/release-loop/checklist-gate-node.ts +2 -2
- package/scripts/release-loop/env-known-failures.ts +31 -0
- package/scripts/release-loop/gate-node.ts +108 -22
- package/scripts/release-loop/known-issues-node.ts +159 -0
- package/scripts/release-loop/npm-publish-node.ts +124 -0
- package/scripts/release-loop/ops-upgrade-node.ts +95 -0
- package/scripts/release-loop/publish-node.ts +23 -1
- package/scripts/release-loop/release-readiness.ts +58 -0
- package/scripts/release-loop/shard-plan.ts +17 -0
- package/scripts/release-loop/unattended-release.ts +93 -0
- package/scripts/storyboard/storyboard.ts +167 -0
- package/scripts/test-diet/lib.ts +88 -0
- package/scripts/test-diet/node.ts +102 -0
- package/scripts/ux/measure-first-text.ts +102 -0
- package/scripts/vflow-collect.ts +20 -7
- package/scripts/vflow-search.ts +73 -0
- package/scripts/video-free-line-test-walker.ts +36 -0
- package/scripts/video-pipeline.ts +2 -2
- package/skills/explainer-video/SKILL.md +12 -9
- package/skills/explainer-video/engine/build.mjs +1 -1
- package/skills/explainer-video/engine/reel.mjs +138 -31
- package/skills/explainer-video/engine/reel.sh +2 -1
- package/skills/explainer-video/examples/elanous-0.2.5/script.json +1 -1
- package/skills/grill-me/SKILL.md +1 -1
- package/skills/omni-digest/docs/diagrams/noncode-terminal-promotion-path-2026-08-13.mmd +1 -1
- package/src/a2a/server.ts +2 -0
- package/src/acp/auth-methods.ts +30 -0
- package/src/acp/elanous-aware-peers.ts +30 -0
- package/src/acp/server.ts +96 -20
- package/src/agent/monad-agent-turn.ts +25 -6
- package/src/agent/shared-app-tools.ts +5 -3
- package/src/agent-substrate/review-intent.ts +6 -2
- package/src/agent-substrate/shard-boundary-intent.ts +70 -0
- package/src/auth/github-app-token.ts +4 -1
- package/src/autopilot/track-agent-shadow.ts +151 -0
- package/src/autopilot/track-agent.ts +23 -3
- package/src/boot/acp-server-help.ts +16 -0
- package/src/boot/daemon-prompt-turn.ts +31 -10
- package/src/boot/daemon-tools/index.ts +7 -1
- package/src/budget/codex-credit-pace.ts +84 -0
- package/src/budget/codex-credit-plan.ts +154 -0
- package/src/budget/codex-reset-credit-state.ts +2 -0
- package/src/channel-import/detect.ts +191 -0
- package/src/channel-import/run.ts +111 -0
- package/src/chat/chat-cli.ts +4 -1
- package/src/chat/short-question.ts +40 -0
- package/src/cli/agent-cli.ts +24 -15
- package/src/cli/ask-bare.ts +42 -0
- package/src/cli/cli-user-error.ts +25 -0
- package/src/cli/codex-credit-plan-view.ts +25 -0
- package/src/cli/config-test-sync.ts +4 -0
- package/src/cli/decisions-cli.ts +13 -3
- package/src/cli/dependence-gauge.ts +237 -0
- package/src/cli/doctor-bundle.ts +128 -0
- package/src/cli/doctor-cli.ts +41 -1
- package/src/cli/doctor-local-llm.ts +95 -0
- package/src/cli/doctor-modes.ts +48 -0
- package/src/cli/import-cli.ts +60 -0
- package/src/cli/intake-cli.ts +12 -2
- package/src/cli/intake-source-cli.ts +58 -0
- package/src/cli/machine-cli.ts +23 -0
- package/src/cli/mcp-login.ts +13 -4
- package/src/cli/msg-cli.ts +137 -0
- package/src/cli/persona-cli.ts +116 -0
- package/src/cli/plugin-cli.ts +25 -0
- package/src/cli/pr-cli.ts +36 -0
- package/src/cli/provider-cli.ts +5 -0
- package/src/cli/release-cli.ts +50 -8
- package/src/cli/release-run-if-ready.ts +48 -0
- package/src/cli/setup-cli.ts +27 -6
- package/src/cli/setup-recommend.ts +8 -0
- package/src/cli/skills-cli.ts +173 -0
- package/src/cli/start-cli.ts +13 -4
- package/src/cli/usage-cli.ts +11 -1
- package/src/codex/setup.ts +37 -16
- package/src/dashboard/index.ts +18 -2
- package/src/dashboard/slash-runtime/dashboard-handlers.ts +2 -2
- package/src/dashboard/slash-runtime/help-from-registry.ts +4 -2
- package/src/decisions/decision-cards.ts +291 -0
- package/src/decisions/decision-ledger.ts +5 -2
- package/src/decisions/discord-decision-cards.ts +133 -0
- package/src/decisions/telegram-decision-cards.ts +100 -0
- package/src/directives/version-at.ts +77 -0
- package/src/discord.ts +73 -6
- package/src/domains/core-tools.ts +37 -14
- package/src/domains/outbound-alert.ts +94 -12
- package/src/domains/repeated-failure.ts +1 -1
- package/src/error-report/report.ts +200 -0
- package/src/exec-requests/planner.ts +146 -0
- package/src/exec-requests/runner.ts +378 -0
- package/src/exec-requests/store.ts +78 -0
- package/src/field/field-feed-auto.ts +48 -0
- package/src/field/field-media.ts +8 -3
- package/src/field/field-reel.ts +203 -0
- package/src/grok/credential.ts +7 -5
- package/src/harness/aside-run-status.ts +33 -0
- package/src/harness/browser-verify.ts +48 -17
- package/src/harness/harness-cli-command.ts +25 -3
- package/src/harness/image-load-state.ts +21 -0
- package/src/harness/process-garbage.ts +45 -0
- package/src/hooks/error-report.ts +210 -0
- package/src/hooks/receiver.ts +41 -1
- package/src/import/apply.ts +128 -0
- package/src/import/plan.ts +197 -0
- package/src/index.ts +168 -21
- package/src/input-core/text-entry.ts +13 -5
- package/src/instance/leader.ts +13 -1
- package/src/intake-plane/collect-github.ts +5 -3
- package/src/intake-plane/collect-telegram-saved.ts +15 -3
- package/src/intake-plane/discord-seat-work.ts +56 -0
- package/src/intake-plane/intake-sources.ts +202 -0
- package/src/intake-plane/items.ts +28 -12
- package/src/intake-plane/seat-answer.ts +96 -0
- package/src/intake-plane/seat-doc-route.ts +221 -0
- package/src/intake-plane/submit-intake-work.ts +9 -1
- package/src/intake-plane/telegram-seat-work.ts +72 -0
- package/src/llm/model-defaults.ts +24 -1
- package/src/llm.ts +5 -4
- package/src/machines/machine-ledger.ts +127 -0
- package/src/market/pack-internal-refs.ts +28 -0
- package/src/market/publish.ts +31 -4
- package/src/maturity/feature-maturity.ts +65 -0
- package/src/model-tier/turn-tier.ts +24 -0
- package/src/msg/msg-store.ts +149 -0
- package/src/native-tool-catalog.ts +2 -1
- package/src/nexus/api/chat-fast-path-config.ts +28 -0
- package/src/nexus/api/consult-requests.ts +128 -0
- package/src/nexus/api/discord-trigger-bot.ts +3 -0
- package/src/nexus/api/error-reports.ts +108 -0
- package/src/nexus/api/exec-requests.ts +51 -0
- package/src/nexus/api/field-uploads.ts +40 -3
- package/src/nexus/api/graph-approvals-feed.ts +140 -0
- package/src/nexus/api/graph-approvals.ts +71 -4
- package/src/nexus/api/http-server.ts +82 -8
- package/src/nexus/api/outbound-report.ts +7 -0
- package/src/nexus/api/running-runs-background.ts +68 -0
- package/src/nexus/api/running-runs-child.ts +6 -0
- package/src/nexus/api/seat-requests.ts +254 -0
- package/src/nexus/api/share-captures.ts +91 -0
- package/src/nexus/api/skill-problems.ts +56 -0
- package/src/nexus/api/terminals.ts +24 -8
- package/src/nexus/api/trace-run-scan.ts +37 -0
- package/src/nexus/api/trace.ts +19 -3
- package/src/nexus/index.ts +28 -1
- package/src/nexus/setup-status.ts +11 -7
- package/src/notify/llm-budget-alert.ts +16 -10
- package/src/oauth/browser-availability.ts +14 -0
- package/src/oauth/codex-account-rotation.ts +26 -4
- package/src/oauth/codex-account-store.ts +20 -2
- package/src/oauth/codex-browser-login.ts +173 -0
- package/src/oauth/codex-quota-policy.ts +16 -0
- package/src/oauth/codex.ts +4 -1
- package/src/oauth/fallback-chain.ts +5 -5
- package/src/oauth/store.ts +42 -5
- package/src/onboarding/continue-here.ts +34 -0
- package/src/onboarding/entry-hints.ts +8 -0
- package/src/onboarding/full-screen-io.ts +35 -3
- package/src/onboarding/help/skills.md +1 -1
- package/src/onboarding/non-interactive.ts +1 -0
- package/src/onboarding/subscription-hint.ts +27 -0
- package/src/onboarding/web-first.ts +90 -0
- package/src/onboarding.ts +287 -26
- package/src/persona/presets.ts +105 -0
- package/src/plugins/maker/node-install.ts +92 -0
- package/src/plugins/maker/node-maker.ts +139 -0
- package/src/plugins/maker/plugin-maker.ts +19 -7
- package/src/policy/llm-policy.ts +268 -0
- package/src/prompt-library/session-guidance.ts +7 -1
- package/src/prompt-library/universal-preamble.ts +2 -2
- package/src/relay/relay-cli.ts +20 -0
- package/src/relay/relay-server.ts +220 -0
- package/src/release-loop/checklist.ts +37 -13
- package/src/self-dev/decompose.ts +1 -0
- package/src/self-dev/dev-pipeline.ts +6 -3
- package/src/self-dev/orchestrate.ts +18 -11
- package/src/self-dev/run-record-mirror.ts +44 -0
- package/src/self-dev/run-store.ts +12 -3
- package/src/self-implement/harness-policy-gates.ts +4 -1
- package/src/self-implement/report-origin.ts +12 -1
- package/src/session/chat.ts +17 -5
- package/src/shell-env-bootstrap.ts +44 -7
- package/src/skills/connect-claude-plugin.ts +142 -0
- package/src/skills/connect.ts +70 -0
- package/src/skills/index.ts +29 -1
- package/src/skills/repair.ts +124 -0
- package/src/skills/runner.ts +11 -2
- package/src/skills/shared-agent-skill-roots.ts +25 -0
- package/src/skills/trigger-extract.ts +1 -1
- package/src/steward/failure-streak.ts +78 -0
- package/src/steward/steward-cards.ts +24 -0
- package/src/steward/triage-budget.ts +127 -0
- package/src/steward/triage-plan.ts +75 -0
- package/src/steward/triage.ts +244 -42
- package/src/task-cards/card-store.ts +1 -1
- package/src/task-orchestrator/surfaces/pod-command-job.ts +16 -8
- package/src/task-orchestrator/surfaces/pod-ledger-collect.ts +11 -5
- package/src/task-orchestrator/surfaces/pod-ledger-events.ts +68 -0
- package/src/task-orchestrator/surfaces/self-implement-pod.ts +78 -4
- package/src/telegram-commands.ts +13 -0
- package/src/telegram.ts +72 -2
- package/src/tool-runtime/elanous-skills-list-runtime.ts +3 -3
- package/src/tool-runtime/self-cognition-runtimes.ts +160 -2
- package/src/user-config.ts +189 -15
- package/src/version/packed-revision.json +1 -1
- package/src/video-pipeline/recipes/character.ts +42 -5
- package/src/video-pipeline/recipes/ffmpeg.ts +1 -1
- package/src/video-pipeline/recipes/free-line.ts +16 -3
- package/src/video-pipeline/recipes/remote.ts +7 -1
- package/src/video-pipeline/vflow-reference.ts +109 -0
- package/apps/pwa/out/_next/static/chunks/1169-696263ac7af8c4d4.js +0 -1
- package/apps/pwa/out/_next/static/chunks/1883.c91a2648af4842fd.js +0 -1
- package/apps/pwa/out/_next/static/chunks/1947-9d64872eeb9cfdec.js +0 -1
- package/apps/pwa/out/_next/static/chunks/2808-dc06482994b40f70.js +0 -1
- package/apps/pwa/out/_next/static/chunks/3165-95515ca5f299a120.js +0 -1
- package/apps/pwa/out/_next/static/chunks/3190-e9282753e7ebde85.js +0 -1
- package/apps/pwa/out/_next/static/chunks/4259-99614149577e77cb.js +0 -1
- package/apps/pwa/out/_next/static/chunks/4283-329eabeaf233e6cd.js +0 -1
- package/apps/pwa/out/_next/static/chunks/4328-cb5058b1acc2de5e.js +0 -25
- package/apps/pwa/out/_next/static/chunks/4801-ecee6ef62b349b18.js +0 -1
- package/apps/pwa/out/_next/static/chunks/5110-8058791dd25a2e14.js +0 -1
- package/apps/pwa/out/_next/static/chunks/5330-c41e9670f594c38f.js +0 -1
- package/apps/pwa/out/_next/static/chunks/5423-e95fd125d1794349.js +0 -1
- package/apps/pwa/out/_next/static/chunks/5478-b5eae07dc79ea619.js +0 -1
- package/apps/pwa/out/_next/static/chunks/5787-96ee6642b9a661e5.js +0 -1
- package/apps/pwa/out/_next/static/chunks/6448-79d72368589f98bc.js +0 -1
- package/apps/pwa/out/_next/static/chunks/6522-9866c002b5531836.js +0 -1
- package/apps/pwa/out/_next/static/chunks/6729-b4a558b7aa891e0c.js +0 -1
- package/apps/pwa/out/_next/static/chunks/6969-cb03f9410b7d2e03.js +0 -1
- package/apps/pwa/out/_next/static/chunks/7007-3b9861091bb8dd21.js +0 -1
- package/apps/pwa/out/_next/static/chunks/7930-8dc7e20fc6fc19ca.js +0 -1
- package/apps/pwa/out/_next/static/chunks/8071-187edbc22a86741f.js +0 -1
- package/apps/pwa/out/_next/static/chunks/8198-d4101ad70cb9a579.js +0 -1
- package/apps/pwa/out/_next/static/chunks/8250.4a2c5553a07cdf47.js +0 -1
- package/apps/pwa/out/_next/static/chunks/8293-123b91e7b0330dc0.js +0 -1
- package/apps/pwa/out/_next/static/chunks/8296-d6d5d87dfa911d41.js +0 -1
- package/apps/pwa/out/_next/static/chunks/8305-603963c33ee8eec3.js +0 -1
- package/apps/pwa/out/_next/static/chunks/8612-4a0066f20951b8fd.js +0 -1
- package/apps/pwa/out/_next/static/chunks/9181-cf4e1b61c4783f92.js +0 -1
- package/apps/pwa/out/_next/static/chunks/9262-26c2ecbd5a67e4a2.js +0 -1
- package/apps/pwa/out/_next/static/chunks/9328-45abdebce4fbecb7.js +0 -1
- package/apps/pwa/out/_next/static/chunks/9355-dbc67205adf8745f.js +0 -1
- package/apps/pwa/out/_next/static/chunks/9763.255b90dd69875689.js +0 -1
- package/apps/pwa/out/_next/static/chunks/9933-66d31ec25c0231af.js +0 -1
- package/apps/pwa/out/_next/static/chunks/app/_not-found/page-bd06fb55f4da0381.js +0 -1
- package/apps/pwa/out/_next/static/chunks/app/approvals/page-4e586142da455a25.js +0 -1
- package/apps/pwa/out/_next/static/chunks/app/autopilot/page-889ad5cddcf45b0d.js +0 -1
- package/apps/pwa/out/_next/static/chunks/app/board/page-47ba401d56572c27.js +0 -1
- package/apps/pwa/out/_next/static/chunks/app/botlab/page-0b54f9c83458e038.js +0 -1
- package/apps/pwa/out/_next/static/chunks/app/bots/page-4fcc296ef6c8ed90.js +0 -1
- package/apps/pwa/out/_next/static/chunks/app/chat/page-fe9fda494a87f4e5.js +0 -1
- package/apps/pwa/out/_next/static/chunks/app/control/page-f9642e25ce129590.js +0 -1
- package/apps/pwa/out/_next/static/chunks/app/design-check/page-e1063e8ba5f3e2e7.js +0 -1
- package/apps/pwa/out/_next/static/chunks/app/editor/page-9d0df30027d8aa9d.js +0 -1
- package/apps/pwa/out/_next/static/chunks/app/healthz/route-bd06fb55f4da0381.js +0 -1
- package/apps/pwa/out/_next/static/chunks/app/intake/page-d97adf2c9455b8d0.js +0 -1
- package/apps/pwa/out/_next/static/chunks/app/layout-236b80d202110362.js +0 -1
- package/apps/pwa/out/_next/static/chunks/app/live/page-21a30f35f1a276ad.js +0 -1
- package/apps/pwa/out/_next/static/chunks/app/market/page-b1a5be357c4fa25d.js +0 -1
- package/apps/pwa/out/_next/static/chunks/app/missions/[id]/page-1705a60303f7f573.js +0 -1
- package/apps/pwa/out/_next/static/chunks/app/morning/page-76b337c11ad0e237.js +0 -1
- package/apps/pwa/out/_next/static/chunks/app/not-found-7c0f85fbb56f64c6.js +0 -1
- package/apps/pwa/out/_next/static/chunks/app/observatory/page-65ca16b20617b44d.js +0 -1
- package/apps/pwa/out/_next/static/chunks/app/page-e7f9b8fc29411c1d.js +0 -1
- package/apps/pwa/out/_next/static/chunks/app/reflection/page-92ea6213d1aeec04.js +0 -1
- package/apps/pwa/out/_next/static/chunks/app/scheduler/page-a913a005aacb5476.js +0 -1
- package/apps/pwa/out/_next/static/chunks/app/sessions/page-2d78804a40dfdef6.js +0 -1
- package/apps/pwa/out/_next/static/chunks/app/settings/devices/page-08a99148e780ac00.js +0 -1
- package/apps/pwa/out/_next/static/chunks/app/settings/page-deb674e7ed36f815.js +0 -1
- package/apps/pwa/out/_next/static/chunks/app/setup/done/page-49f8de0534d192d7.js +0 -1
- package/apps/pwa/out/_next/static/chunks/app/setup/layout-bd06fb55f4da0381.js +0 -1
- package/apps/pwa/out/_next/static/chunks/app/setup/page-ba162a28d2176e18.js +0 -1
- package/apps/pwa/out/_next/static/chunks/app/share/page-1ff1a37b550ab41a.js +0 -1
- package/apps/pwa/out/_next/static/chunks/app/showroom/page-ccaa698f56c0fbdb.js +0 -1
- package/apps/pwa/out/_next/static/chunks/app/tasks/page-53b944082de1d7db.js +0 -1
- package/apps/pwa/out/_next/static/chunks/app/term/page-9b70adf1552789bf.js +0 -1
- package/apps/pwa/out/_next/static/chunks/app/trace/page-30d482aa63241fe8.js +0 -1
- package/apps/pwa/out/_next/static/chunks/app/vault/page-aecf786f54651d8a.js +0 -1
- package/apps/pwa/out/_next/static/chunks/app/workflows/chat-ui/page-6ab9b62c7b6e08f2.js +0 -1
- package/apps/pwa/out/_next/static/chunks/app/workflows/page-08949735455e0c9a.js +0 -1
- package/apps/pwa/out/_next/static/chunks/app/workspace/page-a1479005234a46c2.js +0 -1
- package/apps/pwa/out/_next/static/chunks/app/worktrees/page-c3890e90bd232732.js +0 -1
- package/apps/pwa/out/_next/static/chunks/beb5cf10-9adcc10b83930090.js +0 -1
- package/apps/pwa/out/_next/static/chunks/framework-d68d41c88e05c801.js +0 -1
- package/apps/pwa/out/_next/static/chunks/main-app-11c63971b7a9593b.js +0 -1
- package/apps/pwa/out/_next/static/chunks/main-d09452353bd0d9cc.js +0 -1
- package/apps/pwa/out/_next/static/chunks/pages/_app-184d727cebeca767.js +0 -1
- package/apps/pwa/out/_next/static/chunks/pages/_error-21bbbbac99b720b1.js +0 -1
- package/apps/pwa/out/_next/static/css/eaa74e8bb2f62269.css +0 -1
- package/apps/pwa/out/_next/static/qMI0jnlZaBjjm4aIDYNGM/_buildManifest.js +0 -1
- /package/apps/pwa/out/_next/static/{qMI0jnlZaBjjm4aIDYNGM → lywc8m_HDzH9MKSDQhyEj}/_ssgManifest.js +0 -0
|
@@ -3,7 +3,9 @@ import { join } from 'node:path';
|
|
|
3
3
|
import { debug } from '../../debug/log.js';
|
|
4
4
|
import { decideGraphApproval, lastJsonObject, type GraphRunState } from '../../graph-runner/runner.js';
|
|
5
5
|
import { effectiveInstanceRoot } from '../../instance/resolve.js';
|
|
6
|
+
import { getElanousConfigDir } from '../../elanous-config-dir.js';
|
|
6
7
|
import { jsonResponse } from './json-response.js';
|
|
8
|
+
import { applyFeedEdit, feedFolderFor, isFeedPreviewMessage, mediaContentType, readFeedDraft, resolveFeedMedia, writeFeedDraft, type FeedDraft } from './graph-approvals-feed.js';
|
|
7
9
|
|
|
8
10
|
export const GRAPH_APPROVALS_PATH = '/v1/graph-approvals';
|
|
9
11
|
const SEGMENT = /^[A-Za-z0-9][A-Za-z0-9._-]*$/;
|
|
@@ -16,6 +18,8 @@ interface GraphApprovalItem {
|
|
|
16
18
|
since: string;
|
|
17
19
|
path: string[];
|
|
18
20
|
recent: Array<{ nodeId: string; ok: boolean; outcome?: string; summary?: string }>;
|
|
21
|
+
/** EV10d — present only for a `{"kind":"feed-preview"}` approval whose run folder holds a valid draft. */
|
|
22
|
+
feed?: Omit<FeedDraft, 'folder'>;
|
|
19
23
|
}
|
|
20
24
|
|
|
21
25
|
/** One decision this daemon applied through `POST /v1/graph-approvals/:graphId/:runId`. */
|
|
@@ -72,6 +76,8 @@ interface GraphApprovalsDeps {
|
|
|
72
76
|
* `tailscale serve` every tailnet peer (Pod included) arrives from loopback. */
|
|
73
77
|
authReason?: (request: Request) => string | undefined;
|
|
74
78
|
root?: string;
|
|
79
|
+
/** Config dir whose `field/<slug>` folders may hold feed drafts (EV10d). */
|
|
80
|
+
configDir?: string;
|
|
75
81
|
}
|
|
76
82
|
|
|
77
83
|
const DECISION_AUTH_REASONS = new Set(['bearer-match', 'temp-token', 'noauth']);
|
|
@@ -96,7 +102,16 @@ function undecided(state: GraphRunState, root: string): boolean {
|
|
|
96
102
|
&& Array.isArray(state.path) && !existsSync(join(root, 'graph-runs', state.graphId, `${state.runId}.json.${state.path.length}.decision.json`));
|
|
97
103
|
}
|
|
98
104
|
|
|
99
|
-
function
|
|
105
|
+
function feedFor(state: GraphRunState, configDir: string): Omit<FeedDraft, 'folder'> | undefined {
|
|
106
|
+
if (!isFeedPreviewMessage(state.pending?.message ?? '')) return undefined;
|
|
107
|
+
const folder = feedFolderFor(state, configDir);
|
|
108
|
+
const draft = folder ? readFeedDraft(folder) : null;
|
|
109
|
+
if (!draft) return undefined;
|
|
110
|
+
const { folder: _folder, ...rest } = draft;
|
|
111
|
+
return rest;
|
|
112
|
+
}
|
|
113
|
+
|
|
114
|
+
function list(root: string, configDir: string): GraphApprovalItem[] {
|
|
100
115
|
const dir = join(root, 'graph-runs');
|
|
101
116
|
let graphs: Dirent[];
|
|
102
117
|
try { graphs = readdirSync(dir, { withFileTypes: true }); }
|
|
@@ -113,6 +128,7 @@ function list(root: string): GraphApprovalItem[] {
|
|
|
113
128
|
const state = readRun(root, graph.name, runId);
|
|
114
129
|
if (!state || !undecided(state, root) || !Array.isArray(state.nodes)) continue;
|
|
115
130
|
const pending = state.pending!;
|
|
131
|
+
const feed = feedFor(state, configDir);
|
|
116
132
|
items.push({
|
|
117
133
|
graphId: state.graphId, runId: state.runId, nodeId: pending.nodeId, message: pending.message,
|
|
118
134
|
since: pending.since, path: state.path,
|
|
@@ -124,6 +140,7 @@ function list(root: string): GraphApprovalItem[] {
|
|
|
124
140
|
...(typeof output?.summary === 'string' ? { summary: output.summary } : {}),
|
|
125
141
|
};
|
|
126
142
|
}),
|
|
143
|
+
...(feed ? { feed } : {}),
|
|
127
144
|
});
|
|
128
145
|
}
|
|
129
146
|
}
|
|
@@ -131,14 +148,17 @@ function list(root: string): GraphApprovalItem[] {
|
|
|
131
148
|
}
|
|
132
149
|
|
|
133
150
|
export async function handleGraphApprovals(req: Request, deps: GraphApprovalsDeps = {}): Promise<Response> {
|
|
134
|
-
const
|
|
151
|
+
const url = new URL(req.url);
|
|
152
|
+
const pathname = url.pathname;
|
|
153
|
+
const sub = /^\/v1\/graph-approvals\/([^/]+)\/([^/]+)\/(feed-draft|media)$/.exec(pathname);
|
|
135
154
|
const match = /^\/v1\/graph-approvals\/([^/]+)\/([^/]+)$/.exec(pathname);
|
|
136
|
-
if (pathname !== GRAPH_APPROVALS_PATH && !match) return jsonResponse({ error: 'not-found' }, 404);
|
|
155
|
+
if (pathname !== GRAPH_APPROVALS_PATH && !match && !sub) return jsonResponse({ error: 'not-found' }, 404);
|
|
137
156
|
if (!deps.authorize?.(req)) return jsonResponse({ error: 'unauthorized' }, 401);
|
|
157
|
+
if (sub) return handleFeed(req, url, sub[1]!, sub[2]!, sub[3] as 'feed-draft' | 'media', deps);
|
|
138
158
|
if (pathname === GRAPH_APPROVALS_PATH) {
|
|
139
159
|
if (req.method !== 'GET') return jsonResponse({ error: 'method-not-allowed' }, 405);
|
|
140
160
|
// ⭐ `items` is unchanged; `decided` is additive (newest first) for other devices' cards.
|
|
141
|
-
return jsonResponse({ items: list(deps.root ?? effectiveInstanceRoot()), decided: (deps.decisions ?? defaultDecisionRing).list() });
|
|
161
|
+
return jsonResponse({ items: list(deps.root ?? effectiveInstanceRoot(), deps.configDir ?? getElanousConfigDir()), decided: (deps.decisions ?? defaultDecisionRing).list() });
|
|
142
162
|
}
|
|
143
163
|
if (req.method !== 'POST') return jsonResponse({ error: 'method-not-allowed' }, 405);
|
|
144
164
|
const authReason = deps.authReason?.(req);
|
|
@@ -172,3 +192,50 @@ export async function handleGraphApprovals(req: Request, deps: GraphApprovalsDep
|
|
|
172
192
|
debug.log('approvals.graph', 'decided', { graphId, runId, nodeId, decision, by: `pwa:${authReason}` });
|
|
173
193
|
return jsonResponse({ graphId, runId, decision });
|
|
174
194
|
}
|
|
195
|
+
|
|
196
|
+
/** EV10d — `PUT …/:graphId/:runId/feed-draft` (사람 수정 저장) · `GET …/:graphId/:runId/media?path=` (초안 미디어). */
|
|
197
|
+
async function handleFeed(req: Request, url: URL, rawGraphId: string, rawRunId: string, kind: 'feed-draft' | 'media', deps: GraphApprovalsDeps): Promise<Response> {
|
|
198
|
+
let graphId: string;
|
|
199
|
+
let runId: string;
|
|
200
|
+
try { graphId = decodeURIComponent(rawGraphId); runId = decodeURIComponent(rawRunId); }
|
|
201
|
+
catch { return jsonResponse({ error: 'not-found' }, 404); }
|
|
202
|
+
if (!validSegment(graphId) || !validSegment(runId)) return jsonResponse({ error: 'not-found' }, 404);
|
|
203
|
+
const root = deps.root ?? effectiveInstanceRoot();
|
|
204
|
+
const state = readRun(root, graphId, runId);
|
|
205
|
+
const folder = state && isFeedPreviewMessage(state.pending?.message ?? '') ? feedFolderFor(state, deps.configDir ?? getElanousConfigDir()) : null;
|
|
206
|
+
if (!state || !folder) {
|
|
207
|
+
debug.log('approvals.feed', 'refused', { graphId, reason: 'not-feed' });
|
|
208
|
+
return jsonResponse({ error: 'not-found' }, 404);
|
|
209
|
+
}
|
|
210
|
+
if (kind === 'media') {
|
|
211
|
+
if (req.method !== 'GET') return jsonResponse({ error: 'method-not-allowed' }, 405);
|
|
212
|
+
const file = resolveFeedMedia(folder, url.searchParams.get('path') ?? '');
|
|
213
|
+
if (!file) {
|
|
214
|
+
debug.log('approvals.feed', 'refused', { graphId, reason: 'media-path' });
|
|
215
|
+
return jsonResponse({ error: 'not-found' }, 404);
|
|
216
|
+
}
|
|
217
|
+
debug.log('approvals.feed', 'media-served', { graphId });
|
|
218
|
+
return new Response(Bun.file(file), { headers: { 'content-type': mediaContentType(file), 'cache-control': 'private, max-age=60' } });
|
|
219
|
+
}
|
|
220
|
+
if (req.method !== 'PUT') return jsonResponse({ error: 'method-not-allowed' }, 405);
|
|
221
|
+
const authReason = deps.authReason?.(req);
|
|
222
|
+
if (!authReason || !DECISION_AUTH_REASONS.has(authReason)) {
|
|
223
|
+
debug.log('approvals.feed', 'refused', { graphId, reason: 'pairing-required' });
|
|
224
|
+
return jsonResponse({ error: 'pairing-required' }, 403);
|
|
225
|
+
}
|
|
226
|
+
if (!undecided(state, root)) return jsonResponse({ error: 'already-decided' }, 409);
|
|
227
|
+
const current = readFeedDraft(folder);
|
|
228
|
+
if (!current) return jsonResponse({ error: 'not-found' }, 404);
|
|
229
|
+
let body: unknown;
|
|
230
|
+
try { body = await req.json(); }
|
|
231
|
+
catch { return jsonResponse({ error: 'bad_request' }, 400); }
|
|
232
|
+
const result = applyFeedEdit(current, body);
|
|
233
|
+
if (!result.ok) {
|
|
234
|
+
debug.log('approvals.feed', 'refused', { graphId, reason: result.error });
|
|
235
|
+
return jsonResponse({ error: result.error }, 400);
|
|
236
|
+
}
|
|
237
|
+
writeFeedDraft(folder, result.draft);
|
|
238
|
+
debug.log('approvals.feed', 'draft-saved', { graphId, revision: result.draft.revision });
|
|
239
|
+
const { folder: _folder, ...feed } = result.draft;
|
|
240
|
+
return jsonResponse({ graphId, runId, feed });
|
|
241
|
+
}
|
|
@@ -15,6 +15,8 @@
|
|
|
15
15
|
// Port policy (N1-2 decision): auto-pick from 31415 upward. Actual port
|
|
16
16
|
// is recorded in runtime.json + printed in boot banner.
|
|
17
17
|
|
|
18
|
+
import { setInProcessOutbound } from '../../domains/outbound-alert.js';
|
|
19
|
+
import { getUserConfig } from '../../user-config.js';
|
|
18
20
|
import type { TelegramEvent } from '../../workflow-runtime/triggers/telegram-source.js';
|
|
19
21
|
import { spawnSync } from 'node:child_process';
|
|
20
22
|
import { compareTokenConstTime } from '../../acp/transport/auth.js';
|
|
@@ -198,7 +200,11 @@ import { handleMcpResourceGet, MCP_RESOURCE_ROUTE_PATH } from './mcp-resource-ro
|
|
|
198
200
|
import { APPROVALS_MERGES_PATH, DESIGN_DIRECTION_PATH, DESIGN_PREVIEW_PATH_PREFIX, DESIGN_PREVIEWS_PATH, DESIGN_SYSTEM_PATH, IPA_PATH_PREFIX, MANIFEST_PATH } from './rest-route-paths.js';
|
|
199
201
|
import { handleMergeApprovals } from './merge-approvals.js';
|
|
200
202
|
import { GRAPH_APPROVALS_PATH, handleGraphApprovals } from './graph-approvals.js';
|
|
201
|
-
import {
|
|
203
|
+
import { handleExecRequests } from './exec-requests.js';
|
|
204
|
+
import { handleSeatRequests, SEAT_REQUESTS_PATH, type SeatRequestsDeps } from './seat-requests.js';
|
|
205
|
+
import { handleConsultRequests, CONSULT_REQUESTS_PATH, type ConsultRequestsDeps } from './consult-requests.js';
|
|
206
|
+
import { ExecRequestRunner } from '../../exec-requests/runner.js';
|
|
207
|
+
import { FIELD_SERVER_MAX_BODY_BYTES, FIELD_UPLOADS_PATH, FIELD_REEL_PATH, FIELD_REEL_FILE_PATH, handleFieldUploads } from './field-uploads.js';
|
|
202
208
|
import { handleLiveDetail, LIVE_DETAIL_PATH } from './live-detail.js';
|
|
203
209
|
import { handleLiveShipped, LIVE_SHIPPED_PATH } from './live-shipped.js';
|
|
204
210
|
import { handleMcpWidgetCall, MCP_WIDGET_CALL_ROUTE_PATH, persistWidgetTurnToSessionStore } from './mcp-widget-call-route.js';
|
|
@@ -236,6 +242,7 @@ import {
|
|
|
236
242
|
parseErrorsPath,
|
|
237
243
|
} from './errors.js';
|
|
238
244
|
import { handleChatBackendDetection } from './chat-backend-detection.js';
|
|
245
|
+
import { handleChatFastPathConfig } from './chat-fast-path-config.js';
|
|
239
246
|
import { connectInfoTokenAllowed, handleConnectInfoGet, handleConnectTokenMint, type ConnectInfoCtx } from './connect-info.js';
|
|
240
247
|
import { handleStaticAppRequest, pathMatchesStaticPrefix } from './static-app.js';
|
|
241
248
|
import {
|
|
@@ -379,6 +386,8 @@ import {
|
|
|
379
386
|
import { handleSessionTurnControl, SESSION_TURN_CONTROL_PATH } from '../../session/session-turn-control.js';
|
|
380
387
|
import { authenticatePodCredential, handlePodGrokCredential, handlePodGithubCredential, POD_CREDENTIAL_GROK_PATH, POD_CREDENTIAL_GITHUB_PATH } from './pod-credential-api.js';
|
|
381
388
|
import { handleOutboundReport } from './outbound-report.js';
|
|
389
|
+
import { handleErrorReportIngest } from './error-reports.js';
|
|
390
|
+
import { routeOutboundInProcess } from './outbound-report.js';
|
|
382
391
|
import { handleSelfEvent } from './self-event.js';
|
|
383
392
|
/** 매매 «실행»은 애드온이다(대표 09-20 결정 ③ · 별도 상용 저장소 · release/trading-export.yaml) — 공개 코어엔 없다.
|
|
384
393
|
* 있으면 그 경로를 켜고, 없으면 501. 경로를 변수로 둬 공개본 타입 검사가 «모듈 없음»으로 막히지 않게 한다. */
|
|
@@ -446,6 +455,9 @@ export type NexusWsBridgeInit = Omit<WsBridgeOpts, 'hostname' | 'port'>;
|
|
|
446
455
|
export interface NexusHttpServerOpts {
|
|
447
456
|
/** Optional installer state root for isolated API consumers and tests. */
|
|
448
457
|
pluginStateRoot?: string;
|
|
458
|
+
execRequests?: ExecRequestRunner;
|
|
459
|
+
seatRequests?: SeatRequestsDeps;
|
|
460
|
+
consultRequests?: ConsultRequestsDeps;
|
|
449
461
|
state: NexusState;
|
|
450
462
|
registry: TabRegistry;
|
|
451
463
|
eventBus: NexusEventBus;
|
|
@@ -748,6 +760,10 @@ export function startNexusHttpServer(opts: NexusHttpServerOpts): NexusHttpServer
|
|
|
748
760
|
...(websocketHandler ? { websocket: websocketHandler } : {}),
|
|
749
761
|
} as unknown as Parameters<typeof Bun.serve>[0];
|
|
750
762
|
server = Bun.serve(fetchOpts);
|
|
763
|
+
// OB8 — this process now answers /v1/outbound itself; its own sendOutbound calls must not curl it.
|
|
764
|
+
setInProcessOutbound(routeOutboundInProcess);
|
|
765
|
+
// 데몬이 «실제로» 떴을 때만 재시작 복구(맡긴 일) — 주입된 러너(시험)는 건드리지 않는다.
|
|
766
|
+
if (!opts.execRequests) { try { execRequestRunner().reconcileInterrupted(); } catch { /* 복구 실패가 서버 기동을 막지 않는다 */ } }
|
|
751
767
|
resolvedPort = port;
|
|
752
768
|
break;
|
|
753
769
|
} catch (err) {
|
|
@@ -770,6 +786,7 @@ export function startNexusHttpServer(opts: NexusHttpServerOpts): NexusHttpServer
|
|
|
770
786
|
url,
|
|
771
787
|
stop() {
|
|
772
788
|
try { server!.stop(true); } catch { /* idempotent */ }
|
|
789
|
+
setInProcessOutbound(null);
|
|
773
790
|
},
|
|
774
791
|
};
|
|
775
792
|
}
|
|
@@ -786,6 +803,13 @@ function isPortBusy(err: unknown): boolean {
|
|
|
786
803
|
return /EADDRINUSE|address already in use/i.test(msg);
|
|
787
804
|
}
|
|
788
805
|
|
|
806
|
+
let execRequestRunnerInstance: ExecRequestRunner | undefined;
|
|
807
|
+
/** 게으른 한 벌 — import 만으로는 만들지 않는다(재시작 복구가 import 에 묶이지 않게). */
|
|
808
|
+
function execRequestRunner(): ExecRequestRunner {
|
|
809
|
+
execRequestRunnerInstance ??= new ExecRequestRunner();
|
|
810
|
+
return execRequestRunnerInstance;
|
|
811
|
+
}
|
|
812
|
+
|
|
789
813
|
export async function routeRequest(
|
|
790
814
|
req: Request,
|
|
791
815
|
opts: NexusHttpServerOpts,
|
|
@@ -834,21 +858,31 @@ export async function routeRequest(
|
|
|
834
858
|
// Per-route checkAuth calls below stay in place.
|
|
835
859
|
// OPTIONS is a CORS preflight and cannot carry Authorization; existing
|
|
836
860
|
// handlers answer it themselves, so the gate does not swallow it.
|
|
837
|
-
//
|
|
838
|
-
//
|
|
839
|
-
const
|
|
840
|
-
|
|
861
|
+
// Without metaApi, only the owner bearer may reach these runtime-less
|
|
862
|
+
// meta-API stubs. All other private paths remain default-denied.
|
|
863
|
+
const runtimeLessMetaRoute = !opts.metaApi && (
|
|
864
|
+
(method !== 'GET' && method !== 'OPTIONS'
|
|
865
|
+
&& (pathname === '/v1/nexus/tabs' || pathname.startsWith('/v1/nexus/tabs/')))
|
|
866
|
+
|| (method === 'GET' && (
|
|
867
|
+
['/v1/simulations', '/v1/tools', '/v1/intake', '/v1/sessions', '/v1/control-signals', '/v1/turns/last/screenshot'].includes(pathname)
|
|
868
|
+
|| pathname.startsWith('/v1/recordings/')
|
|
869
|
+
))
|
|
870
|
+
|| (method === 'POST' && (
|
|
871
|
+
['/v1/intake', '/v1/sessions/external', '/v1/control-signals', '/v1/prompt'].includes(pathname)
|
|
872
|
+
|| pathname.startsWith('/v1/hitl/callback/')
|
|
873
|
+
))
|
|
874
|
+
);
|
|
841
875
|
if (
|
|
842
876
|
method !== 'OPTIONS'
|
|
843
877
|
&& pathname.startsWith('/v1/')
|
|
844
878
|
&& !isPublicRoute(method, pathname, { setupMode: false })
|
|
845
879
|
) {
|
|
846
|
-
const fallbackToken =
|
|
880
|
+
const fallbackToken = runtimeLessMetaRoute ? ensureAuthToken().token : undefined;
|
|
847
881
|
const offered = req.headers.get('authorization');
|
|
848
882
|
const fallbackAuthorized = fallbackToken !== undefined && offered?.startsWith('Bearer ') === true
|
|
849
883
|
&& compareTokenConstTime(offered.slice('Bearer '.length).trim(), fallbackToken);
|
|
850
884
|
if (!(opts.metaApi ? checkAuth(req, opts.metaApi) : fallbackAuthorized)) {
|
|
851
|
-
const name = method === 'POST' && pathname === '/v1/tasks' && opts.metaApi
|
|
885
|
+
const name = method === 'POST' && (pathname === '/v1/tasks' || pathname === '/v1/reports/ingest') && opts.metaApi
|
|
852
886
|
? matchIngestAuthorization(req)?.name
|
|
853
887
|
: undefined;
|
|
854
888
|
if (name === undefined) {
|
|
@@ -919,6 +953,25 @@ export async function routeRequest(
|
|
|
919
953
|
});
|
|
920
954
|
}
|
|
921
955
|
|
|
956
|
+
if (pathname === SEAT_REQUESTS_PATH) {
|
|
957
|
+
if (!opts.metaApi || !checkAuth(req, opts.metaApi)) return jsonResponse({ error: 'unauthorized' }, 401);
|
|
958
|
+
return handleSeatRequests(req, opts.seatRequests);
|
|
959
|
+
}
|
|
960
|
+
|
|
961
|
+
if (pathname === CONSULT_REQUESTS_PATH) {
|
|
962
|
+
if (!opts.metaApi || !checkAuth(req, opts.metaApi)) return jsonResponse({ error: 'unauthorized' }, 401);
|
|
963
|
+
return handleConsultRequests(req, opts.consultRequests);
|
|
964
|
+
}
|
|
965
|
+
|
|
966
|
+
if (pathname === '/v1/exec-requests' || pathname.startsWith('/v1/exec-requests/')) {
|
|
967
|
+
if (!opts.metaApi || !checkAuth(req, opts.metaApi)) return jsonResponse({ error: 'unauthorized' }, 401);
|
|
968
|
+
if (/^\/v1\/exec-requests\/[^/]+\/files\//.test(pathname)) {
|
|
969
|
+
const credential = bearerCredential(req, opts.metaApi);
|
|
970
|
+
if (credential !== 'bearer-match' && credential !== 'temp-token') return jsonResponse({ error: 'unauthorized' }, 401);
|
|
971
|
+
}
|
|
972
|
+
return handleExecRequests(req, opts.execRequests ?? execRequestRunner());
|
|
973
|
+
}
|
|
974
|
+
|
|
922
975
|
if (pathname === GRAPH_APPROVALS_PATH || pathname.startsWith(`${GRAPH_APPROVALS_PATH}/`)) {
|
|
923
976
|
return handleGraphApprovals(req, {
|
|
924
977
|
authorize: (request) => !!opts.metaApi && checkAuth(request, opts.metaApi),
|
|
@@ -926,9 +979,11 @@ export async function routeRequest(
|
|
|
926
979
|
});
|
|
927
980
|
}
|
|
928
981
|
// 현장 업로드(owner 전용) — GET 목록 · POST 저장. 저장 규칙 정본 = src/field/field-media.ts.
|
|
929
|
-
if (pathname === FIELD_UPLOADS_PATH && (method === 'GET' || method === 'POST'))
|
|
982
|
+
if ((pathname === FIELD_UPLOADS_PATH && (method === 'GET' || method === 'POST'))
|
|
983
|
+
|| ((pathname === FIELD_REEL_PATH || pathname === FIELD_REEL_FILE_PATH) && method === 'GET')) {
|
|
930
984
|
return handleFieldUploads(req, {
|
|
931
985
|
authorize: (request) => !!opts.metaApi && checkAuth(request, opts.metaApi),
|
|
986
|
+
configuredEvent: () => { try { return getUserConfig().telegram?.fieldDefaultEvent; } catch { return undefined; } },
|
|
932
987
|
});
|
|
933
988
|
}
|
|
934
989
|
if (pathname === APPROVALS_MERGES_PATH || pathname.startsWith(`${APPROVALS_MERGES_PATH}/`)) {
|
|
@@ -1217,6 +1272,11 @@ export async function routeRequest(
|
|
|
1217
1272
|
return handleGraphsValidatePost(req, opts.metaApi);
|
|
1218
1273
|
}
|
|
1219
1274
|
|
|
1275
|
+
if (pathname === '/v1/config/chat-fast-path' && (method === 'GET' || method === 'PUT')) {
|
|
1276
|
+
if (!opts.metaApi || !checkAuth(req, opts.metaApi)) return jsonResponse({ error: 'unauthorized' }, 401);
|
|
1277
|
+
return handleChatFastPathConfig(req);
|
|
1278
|
+
}
|
|
1279
|
+
|
|
1220
1280
|
// Mutation routes (PR ι) — POST/PATCH/DELETE on /v1/nexus/tabs[/:id[/action]].
|
|
1221
1281
|
// Templates POST handled here too (PR κ).
|
|
1222
1282
|
// Config / secrets PUT/POST/DELETE here too (PR μ).
|
|
@@ -1250,6 +1310,8 @@ export async function routeRequest(
|
|
|
1250
1310
|
if (!opts.metaApi) return jsonResponse({ error: 'meta-api-not-wired' }, 503);
|
|
1251
1311
|
return handleTaskCreatePost(req, opts.metaApi);
|
|
1252
1312
|
}
|
|
1313
|
+
// ER2 — error reports forwarded by the bot VM (ingest token · same as /v1/tasks).
|
|
1314
|
+
if (method === 'POST' && pathname === '/v1/reports/ingest') return handleErrorReportIngest(req);
|
|
1253
1315
|
if (method === 'POST' && pathname.startsWith('/v1/tasks/') && pathname.endsWith('/approve')) {
|
|
1254
1316
|
if (!opts.metaApi) return jsonResponse({ error: 'meta-api-not-wired' }, 503);
|
|
1255
1317
|
let taskId: string;
|
|
@@ -1915,6 +1977,18 @@ export async function routeRequest(
|
|
|
1915
1977
|
}
|
|
1916
1978
|
// HANDOFF §4.2 follow-up — skill-side mirror of the workflow
|
|
1917
1979
|
// router. Same regex → LLM cascade, applied to the skill index.
|
|
1980
|
+
// SK2 (PWA) — skills the index could not read: list ⊕ confirmed repair.
|
|
1981
|
+
if (pathname === '/v1/skills/problems' || pathname === '/v1/skills/problems/repair') {
|
|
1982
|
+
if (!opts.metaApi) return jsonResponse({ error: 'meta-api-not-wired' }, 503);
|
|
1983
|
+
const { handleSkillProblems } = await import('./skill-problems.js');
|
|
1984
|
+
return handleSkillProblems(req, opts.metaApi);
|
|
1985
|
+
}
|
|
1986
|
+
// SC1 (PWA · beta) — «공유용 캡처»: masked screen PNG in, metadata chunks stripped, stored under <configDir>/captures.
|
|
1987
|
+
if (pathname === '/v1/captures' || pathname.startsWith('/v1/captures/')) {
|
|
1988
|
+
if (!opts.metaApi) return jsonResponse({ error: 'meta-api-not-wired' }, 503);
|
|
1989
|
+
const { handleShareCaptures } = await import('./share-captures.js');
|
|
1990
|
+
return handleShareCaptures(req, opts.metaApi);
|
|
1991
|
+
}
|
|
1918
1992
|
if (pathname === '/v1/skills/route' && method === 'POST') {
|
|
1919
1993
|
if (!opts.metaApi) return jsonResponse({ error: 'meta-api-not-wired' }, 503);
|
|
1920
1994
|
return handleSkillRoute(req, opts.metaApi);
|
|
@@ -44,6 +44,13 @@ function json(body: unknown, status: number): Response {
|
|
|
44
44
|
});
|
|
45
45
|
}
|
|
46
46
|
|
|
47
|
+
/** The daemon's own sendOutbound path (OB8) — what POST /v1/outbound does, without the HTTP self-call. */
|
|
48
|
+
export async function routeOutboundInProcess(text: string, kind: string): Promise<boolean> {
|
|
49
|
+
const result = await routeOutbound(getUserConfig(), { text, markdown: false, kind });
|
|
50
|
+
if (result.delivered) recordOutboundEvent(text, kind);
|
|
51
|
+
return result.delivered;
|
|
52
|
+
}
|
|
53
|
+
|
|
47
54
|
/** POST /v1/outbound — fan one message out to the routed channels. */
|
|
48
55
|
export async function handleOutboundReport(req: Request, metaApi: MetaApiOpts): Promise<Response> {
|
|
49
56
|
if (!checkAuth(req, metaApi)) return json({ error: 'unauthorized' }, 401);
|
|
@@ -0,0 +1,68 @@
|
|
|
1
|
+
// The terminals list must answer at once and must never share the event loop with a ledger scan: the running-runs query
|
|
2
|
+
// reads every run ledger synchronously (~5k files · 0.9–1.8 s on 10-02), which froze typing in the web terminal while the
|
|
3
|
+
// PWA polled the list. This keeps the last result as a snapshot and refreshes it in a separate bun process, on demand.
|
|
4
|
+
import { join } from 'node:path';
|
|
5
|
+
import { debug } from '../../debug/log.js';
|
|
6
|
+
import type { RunningRunsResult } from '../../self-implement/running-runs.js';
|
|
7
|
+
|
|
8
|
+
export const RUNNING_RUNS_REFRESH_MS = 15_000;
|
|
9
|
+
/** A refresh that has not answered by then is abandoned; the next request starts another. */
|
|
10
|
+
export const RUNNING_RUNS_REFRESH_TIMEOUT_MS = 60_000;
|
|
11
|
+
|
|
12
|
+
export interface RunningRunsSnapshot {
|
|
13
|
+
/** Last result, or null before the first refresh finished (subjects then keep unknown assessments). */
|
|
14
|
+
readonly result: RunningRunsResult | null;
|
|
15
|
+
/** Milliseconds since `result` was computed; null when there is none. */
|
|
16
|
+
readonly ageMs: number | null;
|
|
17
|
+
}
|
|
18
|
+
|
|
19
|
+
/** Runs the query somewhere other than this event loop and resolves with its JSON output. */
|
|
20
|
+
export type RunningRunsRunner = (includeTest: boolean) => Promise<RunningRunsResult>;
|
|
21
|
+
|
|
22
|
+
export const RUNNING_RUNS_CHILD_SCRIPT = join(import.meta.dir, 'running-runs-child.ts');
|
|
23
|
+
|
|
24
|
+
/** Default runner: `bun running-runs-child.ts [--include-test]` — the child does the ledger I/O, we only parse its stdout. */
|
|
25
|
+
export const childProcessRunner: RunningRunsRunner = async (includeTest) => {
|
|
26
|
+
const proc = Bun.spawn([process.execPath, RUNNING_RUNS_CHILD_SCRIPT, ...(includeTest ? ['--include-test'] : [])], {
|
|
27
|
+
stdout: 'pipe', stderr: 'ignore', stdin: 'ignore', env: process.env,
|
|
28
|
+
});
|
|
29
|
+
const timer = setTimeout(() => proc.kill(), RUNNING_RUNS_REFRESH_TIMEOUT_MS);
|
|
30
|
+
try {
|
|
31
|
+
const [out, code] = await Promise.all([new Response(proc.stdout).text(), proc.exited]);
|
|
32
|
+
if (code !== 0) throw new Error(`running-runs child exit ${code}`);
|
|
33
|
+
return JSON.parse(out) as RunningRunsResult;
|
|
34
|
+
} finally { clearTimeout(timer); }
|
|
35
|
+
};
|
|
36
|
+
|
|
37
|
+
export interface RunningRunsBackground {
|
|
38
|
+
/** Never blocks: returns the last snapshot and starts a refresh when it is stale and none is in flight. */
|
|
39
|
+
snapshot(options: { includeTest?: boolean }): RunningRunsSnapshot;
|
|
40
|
+
}
|
|
41
|
+
|
|
42
|
+
export function createRunningRunsBackground(runner: RunningRunsRunner = childProcessRunner, now: () => number = Date.now, refreshMs = RUNNING_RUNS_REFRESH_MS): RunningRunsBackground {
|
|
43
|
+
const slots = new Map<boolean, { at: number; result: RunningRunsResult }>();
|
|
44
|
+
const flights = new Set<boolean>();
|
|
45
|
+
const refresh = (includeTest: boolean): void => {
|
|
46
|
+
if (flights.has(includeTest)) return;
|
|
47
|
+
flights.add(includeTest);
|
|
48
|
+
const started = now();
|
|
49
|
+
void runner(includeTest)
|
|
50
|
+
.then((result) => {
|
|
51
|
+
slots.set(includeTest, { at: now(), result });
|
|
52
|
+
debug.log('nexus.terminals', 'running-runs-refreshed', { includeTest, ms: now() - started });
|
|
53
|
+
})
|
|
54
|
+
.catch((error: unknown) => {
|
|
55
|
+
debug.log('nexus.terminals', 'running-runs-refresh-failed', { includeTest, reason: error instanceof Error ? error.message.slice(0, 80) : 'unknown' }, { level: 'warn' });
|
|
56
|
+
})
|
|
57
|
+
.finally(() => { flights.delete(includeTest); });
|
|
58
|
+
};
|
|
59
|
+
return {
|
|
60
|
+
snapshot(options) {
|
|
61
|
+
const includeTest = options.includeTest === true;
|
|
62
|
+
const slot = slots.get(includeTest);
|
|
63
|
+
const t = now();
|
|
64
|
+
if (!slot || t - slot.at >= refreshMs) refresh(includeTest);
|
|
65
|
+
return slot ? { result: slot.result, ageMs: t - slot.at } : { result: null, ageMs: null };
|
|
66
|
+
},
|
|
67
|
+
};
|
|
68
|
+
}
|
|
@@ -0,0 +1,6 @@
|
|
|
1
|
+
#!/usr/bin/env bun
|
|
2
|
+
// Child of running-runs-background.ts: runs the running-runs query (all the ledger I/O) and prints the result as JSON.
|
|
3
|
+
import { queryRunningRuns } from '../../self-implement/running-runs.js';
|
|
4
|
+
|
|
5
|
+
const result = queryRunningRuns({ includeTest: process.argv.includes('--include-test'), caller: 'nexus.terminals' });
|
|
6
|
+
process.stdout.write(JSON.stringify(result));
|