elanous 0.2.9 → 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/5845-e6c003ce8d5fd36a.js +1 -0
- 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-f972fc1c00a62e88.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-adfbd2ba9598e59a.js → page-35414e0a007b4082.js} +1 -1
- 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 -0
- package/apps/pwa/out/ops/seats/index.txt +30 -0
- 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 -0
- package/apps/pwa/out/today/index.txt +33 -0
- 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/field/field-feed.yaml +2 -0
- package/graphs/implement-loop.yaml +1 -1
- package/graphs/intake/intake-daily.yaml +2 -1
- package/graphs/ops/recipes.yaml +3 -0
- package/graphs/ops/secret-exposure.yaml +24 -0
- package/graphs/release/recipes.yaml +3 -0
- package/graphs/release/release-loop.yaml +4 -1
- package/graphs/video/explainer-line.yaml +2 -2
- package/package.json +2 -1
- package/plugins/card-followup/graphs/run-step.ts +48 -13
- package/plugins/doc-draft/graphs/doc-draft.yaml +3 -3
- package/plugins/doc-draft/graphs/run-step.ts +13 -6
- 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/ci-pwa-build-gate.ts +160 -0
- 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 +54 -8
- package/scripts/coord-digest.ts +199 -0
- package/scripts/coord-post.sh +60 -3
- 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/install.ps1 +68 -9
- package/scripts/install.sh +39 -12
- package/scripts/lib/pwa-scenarios/scenarios.ts +20 -0
- package/scripts/lib/tui-regress-checks.ts +146 -0
- package/scripts/marketing/measure-site-numbers.ts +169 -0
- package/scripts/measure-gate-shards.ts +309 -0
- package/scripts/memory-lifecycle-cycle.ts +2 -2
- package/scripts/mission-request-judge.ts +31 -1
- package/scripts/morning-report.ts +2 -2
- package/scripts/opportunity-scan.ts +1 -1
- package/scripts/ops-now-probe.ts +327 -0
- package/scripts/publish-internal-dist.ts +11 -1
- package/scripts/release-loop/auto-approve-node.ts +21 -4
- package/scripts/release-loop/cut-branch.ts +84 -0
- package/scripts/release-loop/cutoff.ts +19 -8
- 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/ops-upgrade-node.ts +72 -16
- package/scripts/release-loop/release-readiness.ts +9 -0
- 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 +112 -13
- package/scripts/repo-watch-cycle.ts +1 -1
- package/scripts/retro-cycle.ts +2 -2
- package/scripts/schedule-health-report.ts +1 -1
- package/scripts/signal-digest-cycle.ts +2 -7
- package/scripts/signal-digest-photo.ts +11 -0
- package/scripts/storyboard/storyboard.ts +5 -161
- package/scripts/tech1-public-measure.ts +94 -0
- package/scripts/test-diet/lib.ts +30 -1
- package/scripts/test-diet/node.ts +83 -8
- package/scripts/test-timeout-audit.ts +114 -0
- package/scripts/tree-sync-alert.ts +1 -1
- package/scripts/tui-regress.ts +71 -0
- package/scripts/ux/demo-rehearsal.ts +243 -0
- package/scripts/ux/lib/rehearsal-verdict.ts +73 -0
- package/scripts/waitlist-daily-digest.ts +1 -1
- 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/explainer-video/SKILL.md +4 -0
- package/skills/explainer-video/engine/reel.mjs +18 -13
- package/skills/explainer-video/engine/reel.sh +24 -5
- package/skills/explainer-video/engine/stitch.mjs +145 -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 +36 -0
- package/skills/pitch-deck/template.html +80 -0
- 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/codex-approval-adapter.ts +9 -3
- package/src/acp/core-turn-bridge.ts +117 -18
- package/src/acp/fact-question.ts +11 -0
- package/src/acp/server.ts +53 -9
- package/src/acp/tool-approval.ts +126 -0
- package/src/acp/turn-runner.ts +36 -0
- package/src/agent/monad-agent-turn.ts +8 -0
- 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/ask-user-question/pending-questions.ts +25 -10
- package/src/ask-user-question/types.ts +9 -0
- package/src/auth/setup-link-tokens.ts +16 -5
- package/src/autopilot/build/integrity-gate.ts +12 -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 +8 -0
- package/src/boot/daemon-runtime.ts +9 -3
- package/src/boot/daemon-tools/index.ts +8 -0
- package/src/boot/daemon-tools/types.ts +2 -0
- package/src/boot/daemon-tools/web-search.ts +4 -0
- package/src/card-followup/core.ts +109 -0
- package/src/chat/ctrl-c-in-input.ts +14 -0
- package/src/chat/index.ts +53 -0
- package/src/chat/pickers/state.ts +6 -2
- package/src/cli/agent-cli.ts +7 -0
- package/src/cli/decisions-cli.ts +25 -3
- package/src/cli/doctor-bundle-upload.ts +68 -0
- package/src/cli/doctor-cli.ts +38 -4
- 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/ops-cli.ts +20 -0
- package/src/cli/persona-cli.ts +90 -4
- package/src/cli/plugin-cli.ts +31 -22
- package/src/cli/pod-cli.ts +61 -2
- package/src/cli/pr-cli.ts +82 -17
- package/src/cli/pty-drive-cli.ts +41 -7
- package/src/cli/pty-drive-verdict.ts +40 -0
- package/src/cli/pwa-stop.ts +163 -13
- package/src/cli/pwa-test.ts +3 -0
- package/src/cli/release-cli.ts +80 -24
- package/src/cli/self-update.ts +14 -0
- package/src/cli/setup-cli.ts +43 -1
- package/src/cli/skills-cli.ts +17 -1
- package/src/cli/storyboard-cli.ts +37 -0
- package/src/cli/test-state-dir-flag.ts +11 -4
- package/src/connectors/linear.ts +146 -0
- 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 +115 -0
- package/src/context-bus/external-events.ts +52 -0
- package/src/context-bus/long-term-memory.ts +108 -0
- package/src/dashboard/dashboard-boot-fixture.ts +23 -0
- package/src/dashboard/index.ts +63 -21
- package/src/dashboard/slash-runtime/dashboard-handlers.ts +14 -1
- package/src/dashboard/slash-runtime/help-from-registry.ts +43 -28
- package/src/decisions/decision-cards.ts +58 -3
- package/src/decisions/decision-ledger.ts +85 -6
- package/src/decisions/decision-linear-projection.ts +157 -0
- package/src/decisions/web-push-decision-cards.ts +50 -0
- package/src/directive/interpretation-card.ts +36 -0
- 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 +19 -2
- package/src/domains/coo-admin-tool.ts +62 -0
- package/src/domains/core-tools.ts +13 -4
- package/src/domains/elanous-card.ts +29 -0
- package/src/domains/ops-facts-tool.ts +76 -0
- package/src/domains/outbound-alert.ts +46 -13
- package/src/domains/release-tool.ts +168 -0
- package/src/domains/telegram-kind-route.ts +65 -9
- package/src/exec-requests/default-outputs.ts +25 -0
- package/src/exec-requests/planner.ts +106 -28
- package/src/exec-requests/runner.ts +123 -12
- package/src/exec-requests/store.ts +11 -2
- package/src/execution-loop/launch-gate.ts +100 -0
- package/src/field/field-media.ts +10 -7
- package/src/field/field-reel.ts +19 -5
- package/src/field-note/index.ts +201 -0
- package/src/field-note/transcribe.ts +248 -0
- package/src/git-fs/worktree.ts +45 -6
- package/src/graph-kinds/registry.ts +3 -3
- package/src/graph-runner/graph-approval-card.ts +113 -0
- package/src/graph-runner/graph-cli.ts +189 -4
- package/src/graph-runner/graph-grow-llm.ts +37 -0
- package/src/graph-runner/graph-grow.ts +47 -0
- package/src/graph-runner/graph-notify.ts +25 -3
- package/src/graph-runner/runner.ts +453 -35
- package/src/grok/agent-search.ts +8 -2
- package/src/guardian/secret-exposure-scan.ts +101 -0
- package/src/harness/browser-verify.ts +25 -2
- package/src/harness/harness-cli-command.ts +478 -42
- package/src/harness/harness-incidents-writer.fixture.ts +24 -0
- package/src/harness/harness-incidents.ts +129 -0
- package/src/harness/harness-pod-dispatch.ts +43 -23
- package/src/harness/harness-seams.ts +38 -4
- package/src/harness/harness-stop.ts +75 -6
- package/src/harness/launch-registry.ts +91 -0
- package/src/harness/process-garbage.ts +5 -3
- package/src/hitl/clarification-policy.ts +3 -1
- 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 +206 -49
- package/src/intake-plane/author-goals.ts +37 -4
- package/src/intake-plane/categorize.ts +18 -46
- package/src/intake-plane/check.ts +3 -0
- package/src/intake-plane/discord-seat-work.ts +57 -2
- package/src/intake-plane/front-route-classifier.ts +33 -39
- package/src/intake-plane/persona-answer.ts +30 -0
- package/src/intake-plane/runtime-callables.ts +8 -1
- package/src/intake-plane/seat-doc-route.ts +170 -6
- package/src/intake-plane/telegram-seat-work.ts +80 -4
- package/src/intake-plane/telegram-work.ts +1 -0
- package/src/intake-plane/wish-folder.ts +67 -0
- package/src/intent-gate/gate.ts +30 -10
- package/src/live/detail-switch.ts +5 -0
- package/src/llm/difficulty.ts +57 -0
- package/src/llm/judge-layer.ts +101 -0
- package/src/llm/mission-router.ts +33 -19
- package/src/loops/contract/examples/cmo-seat.loop.yaml +51 -0
- package/src/loops/contract/examples/orchestrator.loop.yaml +57 -0
- package/src/loops/contract/examples/steward.loop.yaml +50 -0
- package/src/loops/contract/loop-agent.schema.json +138 -0
- package/src/loops/contract/validate.ts +64 -0
- package/src/loops/registry.ts +20 -6
- package/src/market/signed-index.ts +4 -0
- package/src/maturity/bot-command-maturity.ts +45 -0
- package/src/maturity/cli-maturity.ts +34 -0
- package/src/maturity/feature-maturity.ts +120 -1
- package/src/maturity/tui-slash-maturity.ts +31 -0
- package/src/memory.ts +32 -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/exec-requests.ts +33 -3
- 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 +89 -1
- package/src/nexus/api/inside-events.ts +226 -0
- package/src/nexus/api/meta-api.ts +32 -8
- package/src/nexus/api/missions.ts +6 -1
- package/src/nexus/api/ops-api.ts +10 -1
- package/src/nexus/api/ops-seats-sources.ts +37 -7
- package/src/nexus/api/ops-seats.ts +49 -6
- package/src/nexus/api/outputs-route.ts +44 -0
- package/src/nexus/api/seat-requests.ts +132 -10
- package/src/nexus/api/sessions-store.ts +42 -0
- package/src/nexus/api/setup-codex-login.ts +160 -0
- 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/usage-api.ts +102 -0
- package/src/nexus/api/workflow-run-event-bridge.ts +1 -0
- package/src/nexus/api/workflows.ts +80 -6
- package/src/nexus/index.ts +47 -4
- 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/first-run.ts +89 -0
- package/src/onboarding/lan-address.ts +45 -0
- package/src/onboarding/voice-ai.ts +3 -3
- package/src/onboarding/web-first.ts +119 -24
- package/src/onboarding.ts +4 -0
- package/src/ops-now/ops-now-refresh.ts +100 -0
- 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-store.ts +115 -0
- package/src/project/project-suggestion.ts +16 -0
- package/src/project/session-context.ts +24 -0
- package/src/release-loop/checklist.ts +79 -5
- package/src/release-loop/feature-store.ts +159 -24
- package/src/release-loop/next-md-merge.ts +58 -0
- package/src/release-loop/release-note.ts +59 -4
- package/src/release-loop/release-schedule.ts +53 -0
- package/src/repl/index.ts +7 -0
- package/src/seat-dispatch/ceo-commands.ts +41 -8
- package/src/seat-dispatch/ceo-intent.ts +38 -0
- 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 +750 -0
- package/src/seat-loop/seat-report.ts +99 -0
- package/src/self-dev/decompose.ts +66 -11
- 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/run-store.ts +10 -1
- 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/execution-clarification.ts +115 -0
- package/src/self-implement/gate-baseline.ts +1 -1
- package/src/self-implement/gate-cli.ts +46 -4
- 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 +279 -12
- package/src/self-implement/pipeline-shape.ts +1 -1
- package/src/self-implement/route-consumer-test-index.ts +122 -0
- package/src/self-implement/run-status-mapping.ts +5 -3
- 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/chat.ts +2 -0
- package/src/session/index.ts +45 -13
- package/src/shell-env-bootstrap.ts +17 -0
- package/src/skills/gift-install.ts +215 -0
- package/src/skills/tools/web-search.ts +4 -1
- package/src/steward/directive.ts +51 -2
- package/src/steward/launch.ts +266 -0
- package/src/steward/outcome-notify.ts +115 -0
- package/src/steward/steward-cards.ts +25 -11
- package/src/steward/triage-plan.ts +32 -4
- package/src/steward/triage.ts +129 -13
- package/src/steward/working-backwards.ts +64 -0
- package/src/storyboard/storyboard.ts +141 -0
- package/src/task-cards/card-cli.ts +25 -1
- package/src/task-cards/card-store.ts +2 -2
- 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 +397 -0
- 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 +153 -0
- package/src/telegram-commands.ts +10 -1
- package/src/telegram-project-command.ts +71 -0
- package/src/telegram-report.ts +29 -19
- package/src/telegram-run.ts +7 -0
- package/src/telegram.ts +58 -11
- package/src/tool-runtime/self-cognition-runtimes.ts +13 -3
- package/src/tool-runtime/types.ts +4 -0
- package/src/tui-client/dashboard-session.ts +2 -0
- package/src/user-config.ts +216 -27
- package/src/version/packed-revision.json +1 -1
- package/src/web-push/notify-exec-request.ts +32 -0
- 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/bFI5EEwg7T6aG88ibX4Zq/_buildManifest.js +0 -1
- package/apps/pwa/out/_next/static/chunks/1105-c473ed46272fba79.js +0 -1
- package/apps/pwa/out/_next/static/chunks/1201-09613bce624467c0.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/2929-617f1e66a55be184.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/3441-a1dd4acfeda14488.js +0 -1
- package/apps/pwa/out/_next/static/chunks/371-4ad6af55dad02ced.js +0 -1
- package/apps/pwa/out/_next/static/chunks/4114-3e63117452378807.js +0 -1
- package/apps/pwa/out/_next/static/chunks/5080-1613752891fcadb4.js +0 -10
- package/apps/pwa/out/_next/static/chunks/5609-012bb3557211f07e.js +0 -1
- package/apps/pwa/out/_next/static/chunks/5791-bb82743fa6299562.js +0 -1
- package/apps/pwa/out/_next/static/chunks/6090-85a3f05f954e5697.js +0 -1
- package/apps/pwa/out/_next/static/chunks/6284-69db415193d5f8bd.js +0 -1
- package/apps/pwa/out/_next/static/chunks/6320-baac91d68843a9a6.js +0 -1
- package/apps/pwa/out/_next/static/chunks/6416-505ba707cacafbba.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/7032-f4ef698518fba61c.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/7990-e12efba616f46e03.js +0 -1
- package/apps/pwa/out/_next/static/chunks/8067-d976b441a104ab74.js +0 -1
- package/apps/pwa/out/_next/static/chunks/8142-744998d65d7bb17e.js +0 -1
- package/apps/pwa/out/_next/static/chunks/8519-5632377cce994f86.js +0 -1
- package/apps/pwa/out/_next/static/chunks/8619-4365e03a2862830f.js +0 -1
- package/apps/pwa/out/_next/static/chunks/8630-cdfc61e82c653ffc.js +0 -1
- package/apps/pwa/out/_next/static/chunks/8894-e263b332208e3957.js +0 -1
- package/apps/pwa/out/_next/static/chunks/920-f7dceb78f1c585ef.js +0 -1
- package/apps/pwa/out/_next/static/chunks/9454-139040d37c79dbc9.js +0 -1
- package/apps/pwa/out/_next/static/chunks/9651-3cd291a6fa1370d2.js +0 -1
- package/apps/pwa/out/_next/static/chunks/9740-8f5ff96c522b5f55.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-fb7c2d458f32fcad.js +0 -1
- package/apps/pwa/out/_next/static/chunks/app/autopilot/page-35e2713597dd24d1.js +0 -1
- package/apps/pwa/out/_next/static/chunks/app/board/page-918b656f064577ba.js +0 -1
- package/apps/pwa/out/_next/static/chunks/app/bots/page-5f30e00693527ebd.js +0 -1
- package/apps/pwa/out/_next/static/chunks/app/chat/page-7fbae173b3c103a7.js +0 -1
- package/apps/pwa/out/_next/static/chunks/app/consult/page-3b4edcce364062ea.js +0 -1
- package/apps/pwa/out/_next/static/chunks/app/control/page-c5794f484c251f44.js +0 -1
- package/apps/pwa/out/_next/static/chunks/app/design-check/page-1130d8eefcd87e76.js +0 -1
- package/apps/pwa/out/_next/static/chunks/app/editor/page-973996d584f008c1.js +0 -1
- package/apps/pwa/out/_next/static/chunks/app/exec/page-016e2bda04eecb1f.js +0 -1
- package/apps/pwa/out/_next/static/chunks/app/field/page-b4d6d9a3b56f2940.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-ec49a466121233ba.js +0 -1
- package/apps/pwa/out/_next/static/chunks/app/layout-f72db356744ceade.js +0 -1
- package/apps/pwa/out/_next/static/chunks/app/live/page-a6fd9b50d1b85378.js +0 -1
- package/apps/pwa/out/_next/static/chunks/app/market/page-8b0402a46a749a3d.js +0 -1
- package/apps/pwa/out/_next/static/chunks/app/missions/[id]/page-037f83e2a1edc8e2.js +0 -1
- package/apps/pwa/out/_next/static/chunks/app/not-found-46fedff57d4bec67.js +0 -1
- package/apps/pwa/out/_next/static/chunks/app/observatory/page-0cf318e9dcee2bbf.js +0 -1
- package/apps/pwa/out/_next/static/chunks/app/ops/checklist/page-899b327cb8b6845c.js +0 -1
- package/apps/pwa/out/_next/static/chunks/app/ops/release/page-6c1e6ba743a29dfe.js +0 -1
- package/apps/pwa/out/_next/static/chunks/app/page-1a8e4807292f6b17.js +0 -1
- package/apps/pwa/out/_next/static/chunks/app/reflection/page-28deba6bcb834916.js +0 -1
- package/apps/pwa/out/_next/static/chunks/app/scheduler/page-de68e2205794037d.js +0 -1
- package/apps/pwa/out/_next/static/chunks/app/sessions/page-c71c33a573230672.js +0 -1
- package/apps/pwa/out/_next/static/chunks/app/settings/devices/page-0df30e0c7e50148a.js +0 -1
- package/apps/pwa/out/_next/static/chunks/app/settings/page-4fc56790fe0d2682.js +0 -1
- package/apps/pwa/out/_next/static/chunks/app/setup/done/page-59df2aebb38a7c1e.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-4647be5dbcbd0795.js +0 -1
- package/apps/pwa/out/_next/static/chunks/app/share/page-e025892bda74b743.js +0 -1
- package/apps/pwa/out/_next/static/chunks/app/showroom/page-a0955de73b89f078.js +0 -1
- package/apps/pwa/out/_next/static/chunks/app/tasks/page-369846d2921af584.js +0 -1
- package/apps/pwa/out/_next/static/chunks/app/term/page-72cbc1c8cdd0f65d.js +0 -1
- package/apps/pwa/out/_next/static/chunks/app/trace/page-77b28bfb0996d5ea.js +0 -1
- package/apps/pwa/out/_next/static/chunks/app/vault/page-3220c4934f49c6c2.js +0 -1
- package/apps/pwa/out/_next/static/chunks/app/workflows/chat-ui/page-90670589b87abea8.js +0 -1
- package/apps/pwa/out/_next/static/chunks/app/workflows/page-7df9243ed021a4cc.js +0 -1
- package/apps/pwa/out/_next/static/chunks/app/workspace/page-4498c3853f4f688d.js +0 -1
- package/apps/pwa/out/_next/static/chunks/app/worktrees/page-35bedde6d885f08f.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-6870f30ea99f8346.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/f92f63a5df0ba229.css +0 -1
- package/src/dashboard/turn-typeahead-echo.ts +0 -23
- /package/apps/pwa/out/_next/static/{bFI5EEwg7T6aG88ibX4Zq → Y4zKzL62sakG5momz3SoQ}/_ssgManifest.js +0 -0
|
@@ -0,0 +1,160 @@
|
|
|
1
|
+
import { debug } from '../../debug/log.js';
|
|
2
|
+
import { loginWithCodexBrowser } from '../../oauth/codex-browser-login.js';
|
|
3
|
+
import {
|
|
4
|
+
CODEX_DEVICE_LOGIN_URL,
|
|
5
|
+
exchangeDeviceAuthCode,
|
|
6
|
+
pollDeviceCode,
|
|
7
|
+
requestDeviceCode,
|
|
8
|
+
} from '../../oauth/codex.js';
|
|
9
|
+
import { expiresAtFromSeconds, saveTokens } from '../../oauth/store.js';
|
|
10
|
+
import { getUserConfig, reloadUserConfig, saveUserConfig } from '../../user-config.js';
|
|
11
|
+
|
|
12
|
+
type Mode = 'browser' | 'device';
|
|
13
|
+
type CodexLoginStatus =
|
|
14
|
+
| { state: 'idle' }
|
|
15
|
+
| { state: 'pending'; mode: Mode; authorizeUrl?: string; userCode?: string; verificationUrl?: string }
|
|
16
|
+
| { state: 'ok'; mode: Mode }
|
|
17
|
+
| { state: 'error'; mode: Mode; error: string };
|
|
18
|
+
|
|
19
|
+
const TIMEOUT_MS = 5 * 60_000;
|
|
20
|
+
const SAFE_ERRORS = [
|
|
21
|
+
'timeout', 'authorization-denied', 'browser-unavailable', 'port-unavailable',
|
|
22
|
+
'token-exchange', 'device-code-failed', 'device-poll-failed', 'config-save-failed',
|
|
23
|
+
] as const;
|
|
24
|
+
|
|
25
|
+
type Failure = typeof SAFE_ERRORS[number];
|
|
26
|
+
function reason(error: unknown, mode: Mode): Failure {
|
|
27
|
+
const message = error instanceof Error ? error.message : '';
|
|
28
|
+
for (const value of SAFE_ERRORS) if (message === value || message === `codex browser login failed: ${value}`) return value;
|
|
29
|
+
return mode === 'browser' ? 'browser-unavailable' : 'device-poll-failed';
|
|
30
|
+
}
|
|
31
|
+
|
|
32
|
+
interface LoginDeps {
|
|
33
|
+
browser: (openBrowser: (url: string) => boolean) => Promise<unknown>;
|
|
34
|
+
device: (ready: (userCode: string, verificationUrl: string) => void) => Promise<unknown>;
|
|
35
|
+
saveProvider: () => void;
|
|
36
|
+
observe: (event: 'started' | 'ok' | 'error', mode: Mode) => void;
|
|
37
|
+
}
|
|
38
|
+
|
|
39
|
+
async function deviceLogin(ready: (userCode: string, verificationUrl: string) => void): Promise<void> {
|
|
40
|
+
const controller = new AbortController();
|
|
41
|
+
const timer = setTimeout(() => controller.abort(), TIMEOUT_MS);
|
|
42
|
+
const fetchImpl = ((input, init) => fetch(input, { ...init, signal: controller.signal })) as typeof fetch;
|
|
43
|
+
try {
|
|
44
|
+
let code: Awaited<ReturnType<typeof requestDeviceCode>>;
|
|
45
|
+
try { code = await requestDeviceCode({ fetchImpl }); }
|
|
46
|
+
catch { throw new Error('device-code-failed'); }
|
|
47
|
+
if (controller.signal.aborted) throw new Error('timeout');
|
|
48
|
+
ready(code.user_code, code.verification_uri || CODEX_DEVICE_LOGIN_URL);
|
|
49
|
+
const interval = Math.max(3000, (code.interval ?? 0) * 1000);
|
|
50
|
+
const deadline = Date.now() + TIMEOUT_MS;
|
|
51
|
+
while (!controller.signal.aborted && Date.now() < deadline) {
|
|
52
|
+
await new Promise<void>((resolve) => setTimeout(resolve, Math.min(interval, Math.max(0, deadline - Date.now()))));
|
|
53
|
+
if (controller.signal.aborted || Date.now() >= deadline) break;
|
|
54
|
+
let result: Awaited<ReturnType<typeof pollDeviceCode>>;
|
|
55
|
+
try { result = await pollDeviceCode(code.device_auth_id, code.user_code, { fetchImpl }); }
|
|
56
|
+
catch { throw new Error('device-poll-failed'); }
|
|
57
|
+
if (!result) continue;
|
|
58
|
+
let token: Awaited<ReturnType<typeof exchangeDeviceAuthCode>>;
|
|
59
|
+
try { token = await exchangeDeviceAuthCode(result.authorization_code, result.code_verifier, { fetchImpl }); }
|
|
60
|
+
catch { throw new Error('token-exchange'); }
|
|
61
|
+
if (controller.signal.aborted) break;
|
|
62
|
+
saveTokens('openai-codex', {
|
|
63
|
+
accessToken: token.access_token,
|
|
64
|
+
refreshToken: token.refresh_token,
|
|
65
|
+
...(token.id_token ? { idToken: token.id_token } : {}),
|
|
66
|
+
expiresAt: expiresAtFromSeconds(token.expires_in),
|
|
67
|
+
scope: token.scope,
|
|
68
|
+
tokenType: token.token_type ?? 'Bearer',
|
|
69
|
+
}, { authMode: 'chatgpt' });
|
|
70
|
+
return;
|
|
71
|
+
}
|
|
72
|
+
throw new Error('timeout');
|
|
73
|
+
} catch (error) {
|
|
74
|
+
if (controller.signal.aborted) throw new Error('timeout');
|
|
75
|
+
throw error;
|
|
76
|
+
} finally {
|
|
77
|
+
clearTimeout(timer);
|
|
78
|
+
}
|
|
79
|
+
}
|
|
80
|
+
|
|
81
|
+
export function saveCodexProvider(): void {
|
|
82
|
+
const cur = getUserConfig();
|
|
83
|
+
saveUserConfig({ ...cur, llm: { ...cur.llm, provider: 'openai-codex', apiKey: undefined, baseUrl: undefined, model: undefined } });
|
|
84
|
+
reloadUserConfig();
|
|
85
|
+
}
|
|
86
|
+
|
|
87
|
+
const defaultDeps: LoginDeps = {
|
|
88
|
+
browser: (openBrowser) => loginWithCodexBrowser({ openBrowser, timeoutMs: TIMEOUT_MS }),
|
|
89
|
+
device: deviceLogin,
|
|
90
|
+
saveProvider: saveCodexProvider,
|
|
91
|
+
observe: (event, mode) => { debug.log('setup.codex-login', event, { mode }); },
|
|
92
|
+
};
|
|
93
|
+
|
|
94
|
+
function json(body: CodexLoginStatus | { error: string }, status = 200): Response {
|
|
95
|
+
return new Response(JSON.stringify(body), {
|
|
96
|
+
status, headers: { 'content-type': 'application/json; charset=utf-8', 'access-control-allow-origin': '*' },
|
|
97
|
+
});
|
|
98
|
+
}
|
|
99
|
+
|
|
100
|
+
/** One in-process login survives leaving or reloading the setup page. */
|
|
101
|
+
export function createCodexLoginHandlers(deps: LoginDeps = defaultDeps) {
|
|
102
|
+
let status: CodexLoginStatus = { state: 'idle' };
|
|
103
|
+
let preparing: Promise<void> | undefined;
|
|
104
|
+
let generation = 0;
|
|
105
|
+
|
|
106
|
+
const get = (): Response => json(status);
|
|
107
|
+
|
|
108
|
+
const post = async (req: Request): Promise<Response> => {
|
|
109
|
+
let body: unknown;
|
|
110
|
+
try { body = await req.json(); } catch { return json({ error: 'invalid-json' }, 400); }
|
|
111
|
+
const mode = body && typeof body === 'object' && 'mode' in body ? body.mode : undefined;
|
|
112
|
+
if (mode !== 'browser' && mode !== 'device') return json({ error: 'invalid-mode' }, 400);
|
|
113
|
+
// Same method again → the login already in flight. A different method → start over; the older
|
|
114
|
+
// attempt's result is ignored (generation). Browser → device is the recovery path when a popup
|
|
115
|
+
// was blocked; device needs no local port, so it never collides with the browser's callback server.
|
|
116
|
+
if (status.state === 'pending' && status.mode === mode) {
|
|
117
|
+
if (preparing) await preparing;
|
|
118
|
+
return json(status);
|
|
119
|
+
}
|
|
120
|
+
|
|
121
|
+
status = { state: 'pending', mode };
|
|
122
|
+
const attempt = ++generation;
|
|
123
|
+
deps.observe('started', mode);
|
|
124
|
+
let resolveReady!: () => void;
|
|
125
|
+
preparing = new Promise<void>((resolve) => { resolveReady = resolve; });
|
|
126
|
+
const ready = (fields: Pick<Extract<CodexLoginStatus, { state: 'pending' }>, 'authorizeUrl' | 'userCode' | 'verificationUrl'>) => {
|
|
127
|
+
if (generation === attempt && status.state === 'pending' && status.mode === mode) {
|
|
128
|
+
status = { ...status, ...fields };
|
|
129
|
+
resolveReady();
|
|
130
|
+
}
|
|
131
|
+
};
|
|
132
|
+
void (async () => {
|
|
133
|
+
try {
|
|
134
|
+
if (mode === 'browser') {
|
|
135
|
+
await deps.browser((url) => { ready({ authorizeUrl: url }); return true; });
|
|
136
|
+
} else {
|
|
137
|
+
await deps.device((userCode, verificationUrl) => ready({ userCode, verificationUrl }));
|
|
138
|
+
}
|
|
139
|
+
if (generation !== attempt) return;
|
|
140
|
+
try { deps.saveProvider(); } catch { throw new Error('config-save-failed'); }
|
|
141
|
+
status = { state: 'ok', mode };
|
|
142
|
+
deps.observe('ok', mode);
|
|
143
|
+
} catch (error) {
|
|
144
|
+
if (generation !== attempt) return;
|
|
145
|
+
status = { state: 'error', mode, error: reason(error, mode) };
|
|
146
|
+
deps.observe('error', mode);
|
|
147
|
+
} finally {
|
|
148
|
+
resolveReady();
|
|
149
|
+
if (generation === attempt) preparing = undefined;
|
|
150
|
+
}
|
|
151
|
+
})();
|
|
152
|
+
await preparing;
|
|
153
|
+
return json(status);
|
|
154
|
+
};
|
|
155
|
+
return { get, post };
|
|
156
|
+
}
|
|
157
|
+
|
|
158
|
+
const login = createCodexLoginHandlers();
|
|
159
|
+
export const handleSetupCodexLoginGet = login.get;
|
|
160
|
+
export const handleSetupCodexLoginPost = login.post;
|
|
@@ -0,0 +1,34 @@
|
|
|
1
|
+
import { readdirSync, readFileSync } from 'node:fs';
|
|
2
|
+
import { join } from 'node:path';
|
|
3
|
+
import { debug } from '../../debug/log.js';
|
|
4
|
+
|
|
5
|
+
export interface SubSeatCharter { id: string; seat: string; sub: string; title: string }
|
|
6
|
+
|
|
7
|
+
export function listSubSeatCharters(root = join(import.meta.dir, '..', '..', '..', 'docs', 'roles'), onUnreadable?: () => void): SubSeatCharter[] {
|
|
8
|
+
try {
|
|
9
|
+
readdirSync(root);
|
|
10
|
+
const charters: SubSeatCharter[] = [];
|
|
11
|
+
for (const seat of ['OP', 'MK', 'TC', 'UX']) {
|
|
12
|
+
let entries;
|
|
13
|
+
try { entries = readdirSync(join(root, seat), { withFileTypes: true }); }
|
|
14
|
+
catch (error) {
|
|
15
|
+
if ((error as NodeJS.ErrnoException).code === 'ENOENT') continue;
|
|
16
|
+
throw error;
|
|
17
|
+
}
|
|
18
|
+
for (const entry of entries) {
|
|
19
|
+
if (!entry.isFile() || !/^[a-z][a-z0-9-]{0,31}\.md$/.test(entry.name)) continue;
|
|
20
|
+
const sub = entry.name.slice(0, -3);
|
|
21
|
+
const id = `${seat}/${sub}`;
|
|
22
|
+
const content = readFileSync(join(root, seat, entry.name), 'utf8');
|
|
23
|
+
const heading = content.split(/\r?\n/).find((line) => line.startsWith('# '));
|
|
24
|
+
const title = heading?.slice(2).startsWith(`${id} — `) ? heading.slice(2 + id.length + 3).trim() || id : id;
|
|
25
|
+
charters.push({ id, seat, sub, title });
|
|
26
|
+
}
|
|
27
|
+
}
|
|
28
|
+
return charters.sort((a, b) => a.id.localeCompare(b.id));
|
|
29
|
+
} catch (error) {
|
|
30
|
+
debug.log('ops.seats', 'charters-unreadable', { root, error: error instanceof Error ? error.message : String(error) });
|
|
31
|
+
onUnreadable?.();
|
|
32
|
+
return [];
|
|
33
|
+
}
|
|
34
|
+
}
|
|
@@ -78,6 +78,8 @@ interface CreateTabBody {
|
|
|
78
78
|
kind?: string;
|
|
79
79
|
id?: string;
|
|
80
80
|
label?: string;
|
|
81
|
+
/** Conversation owning a newly created webterm. */
|
|
82
|
+
sessionId?: string;
|
|
81
83
|
/** Kind-specific factory opts (passed through to the factory). */
|
|
82
84
|
kindOpts?: Record<string, unknown>;
|
|
83
85
|
/** When true (default), supervisor.startTab is called immediately
|
|
@@ -95,7 +97,7 @@ function buildTabSpec(body: CreateTabBody, id: string): { spec: TabSpec; reason?
|
|
|
95
97
|
case 'chat':
|
|
96
98
|
return { spec: createChatTabSpec(opts as Parameters<typeof createChatTabSpec>[0]) };
|
|
97
99
|
case 'webterm':
|
|
98
|
-
return { spec: createWebtermTabSpec(opts as Parameters<typeof createWebtermTabSpec>[0]) };
|
|
100
|
+
return { spec: createWebtermTabSpec({ ...opts, sessionId: body.sessionId ?? opts.sessionId } as Parameters<typeof createWebtermTabSpec>[0]) };
|
|
99
101
|
case 'daemon':
|
|
100
102
|
return { spec: createDaemonTabSpec(opts as Parameters<typeof createDaemonTabSpec>[0]) };
|
|
101
103
|
case 'pwa-host':
|
package/src/nexus/api/trace.ts
CHANGED
|
@@ -9,6 +9,7 @@ import { checkAuth, type MetaApiOpts } from './meta-api.js';
|
|
|
9
9
|
import { jsonResponse } from './json-response.js';
|
|
10
10
|
import { runLedgerDir, runLedgerPath } from '../../self-implement/run-ledger.js';
|
|
11
11
|
import { scanStoresForRun } from './trace-run-scan.js';
|
|
12
|
+
import { listSessions } from '../../session/index.js';
|
|
12
13
|
|
|
13
14
|
export type TraceLevel = 'L0' | 'L1' | 'L2' | 'L3';
|
|
14
15
|
export interface TraceEvent {
|
|
@@ -17,6 +18,7 @@ export interface TraceEvent {
|
|
|
17
18
|
universe: string;
|
|
18
19
|
machine?: string;
|
|
19
20
|
runId?: string;
|
|
21
|
+
projectId?: string;
|
|
20
22
|
parentRunId?: string;
|
|
21
23
|
phase?: string;
|
|
22
24
|
shard?: string;
|
|
@@ -83,6 +85,7 @@ function eventFor(row: LogStoreRow): TraceEvent {
|
|
|
83
85
|
id: evidenceRef(universe, row.id), ts: row.ts, universe,
|
|
84
86
|
...(machine ? { machine } : {}),
|
|
85
87
|
...(runId ? { runId } : {}),
|
|
88
|
+
...(text(data.projectId) ? { projectId: text(data.projectId) } : {}),
|
|
86
89
|
...(text(data.parentRunId) ? { parentRunId: text(data.parentRunId) } : {}),
|
|
87
90
|
...(text(data.phase) ? { phase: text(data.phase) } : {}),
|
|
88
91
|
...(text(data.shard) ? { shard: text(data.shard) } : {}),
|
|
@@ -259,11 +262,15 @@ function options(url: URL): { level: TraceLevel; limit: number; from?: number; t
|
|
|
259
262
|
if (from === null || to === null || (from !== undefined && to !== undefined && from > to)) return { level, limit: n, error: 'invalid time range' };
|
|
260
263
|
return { level, limit: Math.min(n, TRACE_LIMIT), ...(from !== undefined ? { from } : {}), ...(to !== undefined ? { to } : {}) };
|
|
261
264
|
}
|
|
262
|
-
function matches(row: LogStoreRow, url: URL): boolean {
|
|
265
|
+
function matches(row: LogStoreRow, url: URL, projectSessions?: ReadonlySet<string>): boolean {
|
|
263
266
|
const data = dataFor(row);
|
|
264
267
|
const runId = url.searchParams.get('runId');
|
|
265
268
|
const universe = url.searchParams.get('universe');
|
|
266
269
|
const kind = url.searchParams.get('kind');
|
|
270
|
+
const projectId = url.searchParams.get('projectId');
|
|
271
|
+
if (projectId !== null && (Object.hasOwn(data, 'projectId')
|
|
272
|
+
? data.projectId !== projectId
|
|
273
|
+
: !projectSessions?.has(row.session_id ?? '') && !projectSessions?.has(text(data.sessionId) ?? ''))) return false;
|
|
267
274
|
const q = url.searchParams.get('q')?.toLowerCase();
|
|
268
275
|
if (runId && data.runId !== runId && data.run_id !== runId) return false;
|
|
269
276
|
if (universe && row.instance !== universe) return false;
|
|
@@ -295,6 +302,8 @@ function findRunUniverse(runId: string, selected: readonly string[], deps: Trace
|
|
|
295
302
|
export function handleTrace(req: Request, opts: MetaApiOpts, deps: TraceDeps = {}): Response {
|
|
296
303
|
if (!checkAuth(req, opts)) return jsonResponse({ error: 'unauthorized' }, 401);
|
|
297
304
|
const url = new URL(req.url);
|
|
305
|
+
const projectId = url.searchParams.get('projectId');
|
|
306
|
+
const projectSessions = projectId === null ? undefined : new Set(listSessions({ projectId }).map(session => session.id));
|
|
298
307
|
const parsed = options(url);
|
|
299
308
|
if (parsed.error) return jsonResponse({ ok: false, error: 'bad_request', reason: parsed.error }, 400);
|
|
300
309
|
const names = storeNames(url, deps);
|
|
@@ -315,7 +324,8 @@ export function handleTrace(req: Request, opts: MetaApiOpts, deps: TraceDeps = {
|
|
|
315
324
|
for (const entry of stores) {
|
|
316
325
|
if (!entry.store) { failures.push({ name: entry.name, reason: entry.error ?? 'log-store-unavailable' }); continue; }
|
|
317
326
|
try {
|
|
318
|
-
const page = entry.store.aggregateRuns({ sinceMs: parsed.from, untilMs: parsed.to
|
|
327
|
+
const page = entry.store.aggregateRuns({ sinceMs: parsed.from, untilMs: parsed.to,
|
|
328
|
+
...(projectId !== null ? { projectId, projectSessionIds: [...projectSessions!] } : {}) }, RUN_LIMIT);
|
|
319
329
|
if (page.length >= RUN_LIMIT) runLimitReached = true;
|
|
320
330
|
runs.push(...page.map((run) => ({ ...run, universe: entry.name })));
|
|
321
331
|
opened++;
|
|
@@ -334,7 +344,8 @@ export function handleTrace(req: Request, opts: MetaApiOpts, deps: TraceDeps = {
|
|
|
334
344
|
for (const entry of stores) {
|
|
335
345
|
if (!entry.store) { failures.push({ name: entry.name, reason: entry.error ?? 'log-store-unavailable' }); continue; }
|
|
336
346
|
try {
|
|
337
|
-
const query: LogQuery = { sinceMs: parsed.from, untilMs: parsed.to, limit: TRACE_LIMIT + 1
|
|
347
|
+
const query: LogQuery = { sinceMs: parsed.from, untilMs: parsed.to, limit: TRACE_LIMIT + 1,
|
|
348
|
+
...(projectId !== null ? { projectId, projectSessionIds: [...projectSessions!] } : {}) };
|
|
338
349
|
const search = url.searchParams.get('q');
|
|
339
350
|
if (search) query.grep = search;
|
|
340
351
|
// Restrict a run before paging; other JSON-only filters still apply to the bounded window.
|
|
@@ -349,7 +360,7 @@ export function handleTrace(req: Request, opts: MetaApiOpts, deps: TraceDeps = {
|
|
|
349
360
|
const runId = url.searchParams.get('runId');
|
|
350
361
|
let resolution: { universe?: string; checked: number; truncated?: boolean; unresolved?: boolean } | undefined;
|
|
351
362
|
let resolvedFrom: 'ledger' | 'log-scan' | undefined;
|
|
352
|
-
if ((parsed.level === 'L2' || parsed.level === 'L3') && runId && !rows.some((row) => matches(row, url)) && !requestedUniverse) {
|
|
363
|
+
if ((parsed.level === 'L2' || parsed.level === 'L3') && runId && !rows.some((row) => matches(row, url, projectSessions)) && !requestedUniverse) {
|
|
353
364
|
// A store with no log db at all («has no log store yet» — e.g. the daemon's own tree-derived universe) cannot
|
|
354
365
|
// hold the run, so it must not block the ledger lookup. A store that exists but failed to open/read still does:
|
|
355
366
|
// «could not read» is never answered as «not there». The reply keeps `failedStores` either way.
|
|
@@ -379,7 +390,8 @@ export function handleTrace(req: Request, opts: MetaApiOpts, deps: TraceDeps = {
|
|
|
379
390
|
if (!entry?.store) return jsonResponse({ ok: false, error: 'log-store-unavailable', failedStores: [{ name, reason: entry?.error ?? 'log-store-unavailable' }] }, 503);
|
|
380
391
|
stores.push(entry);
|
|
381
392
|
try {
|
|
382
|
-
const query: LogQuery = { sinceMs: parsed.from, untilMs: parsed.to, limit: TRACE_LIMIT + 1
|
|
393
|
+
const query: LogQuery = { sinceMs: parsed.from, untilMs: parsed.to, limit: TRACE_LIMIT + 1,
|
|
394
|
+
...(projectId !== null ? { projectId, projectSessionIds: [...projectSessions!] } : {}) };
|
|
383
395
|
const search = url.searchParams.get('q');
|
|
384
396
|
if (search) query.grep = search;
|
|
385
397
|
const page = entry.store.queryTraceRun(runId, query);
|
|
@@ -388,7 +400,7 @@ export function handleTrace(req: Request, opts: MetaApiOpts, deps: TraceDeps = {
|
|
|
388
400
|
} catch (e) { return jsonResponse({ ok: false, error: 'log-store-unavailable', failedStores: [{ name, reason: e instanceof Error ? e.message : String(e) }] }, 503); }
|
|
389
401
|
}
|
|
390
402
|
}
|
|
391
|
-
const filtered = rows.filter((row) => matches(row, url)).sort(sortRows);
|
|
403
|
+
const filtered = rows.filter((row) => matches(row, url, projectSessions)).sort(sortRows);
|
|
392
404
|
const trace = buildTrace(filtered.slice(0, parsed.limit), parsed.level, filtered.length > parsed.limit || candidateLimitReached || failures.length > 0 || resolution?.truncated === true);
|
|
393
405
|
try { (deps.queryLog ?? ((details) => debug.log('logs.trace', 'query', details)))({ stores: names, level: parsed.level, count: trace.events.length, truncated: trace.truncated, mode: 'rows', runs: trace.nodes.filter((node) => node.level === 'L1' && node.count > 0).length }); } catch { /* query logging must not block reads */ }
|
|
394
406
|
return jsonResponse({ ok: true, ...trace, stores: names, registeredStores: registeredStoreCount(deps), ...(resolution ? resolution.universe ? { resolvedFrom, runUniverse: resolution.universe, ...(resolvedFrom === 'log-scan' ? { checked: resolution.checked } : {}) } : { runUniverse: resolution.truncated || resolution.unresolved ? 'unresolved' as const : 'not-found' as const, checked: resolution.checked } : {}), ...(failures.length ? { failedStores: failures } : {}) }, 200);
|
|
@@ -0,0 +1,102 @@
|
|
|
1
|
+
import { collectUnifiedUsage } from '../../budget/unified-usage.js';
|
|
2
|
+
import type { UnifiedUsageReport } from '../../budget/types.js';
|
|
3
|
+
import { jsonResponse } from './json-response.js';
|
|
4
|
+
|
|
5
|
+
const CACHE_MS = 30_000;
|
|
6
|
+
|
|
7
|
+
// TC 조건(10-03 01:21): 계정 이름·이메일·토큰은 응답에 «하나도» 싣지 않는다 — 공급자·사용률·리셋만.
|
|
8
|
+
// 계정이 여럿이면 공급자 안 순번(«계정 1»)으로만 가른다(이름에서 비밀을 걸러 내는 방식은 쓰지 않는다).
|
|
9
|
+
function accountLabel(index: number, count: number): string {
|
|
10
|
+
return count > 1 ? `계정 ${index + 1}` : '계정';
|
|
11
|
+
}
|
|
12
|
+
|
|
13
|
+
const SAFE_REASONS = new Set(['query-does-not-supply', 'not-a-subscription']);
|
|
14
|
+
function safeReason(reason: unknown): string {
|
|
15
|
+
return typeof reason === 'string' && SAFE_REASONS.has(reason) ? reason : 'unknown';
|
|
16
|
+
}
|
|
17
|
+
|
|
18
|
+
function periodType(value: string | null): string | null {
|
|
19
|
+
return value && /^(?:session|weekly|monthly|daily|prepaid-usd|USAGE_PERIOD_TYPE_(?:SESSION|WEEKLY|MONTHLY|DAILY))$/.test(value) ? value : null;
|
|
20
|
+
}
|
|
21
|
+
|
|
22
|
+
function isoDate(value: string | null): string | null {
|
|
23
|
+
if (!value) return null;
|
|
24
|
+
const epoch = Date.parse(value);
|
|
25
|
+
return Number.isFinite(epoch) && epoch > 0 ? new Date(epoch).toISOString() : null;
|
|
26
|
+
}
|
|
27
|
+
|
|
28
|
+
function resetsInMs(resetsAt: number, nowMs: number): number | null {
|
|
29
|
+
return Number.isFinite(resetsAt) && resetsAt > 0 ? Math.max(0, resetsAt - nowMs) : null;
|
|
30
|
+
}
|
|
31
|
+
|
|
32
|
+
function projectUsage(report: UnifiedUsageReport, nowMs: number) {
|
|
33
|
+
return {
|
|
34
|
+
ok: true as const,
|
|
35
|
+
accountCounts: {
|
|
36
|
+
codex: report.accountCounts.codex,
|
|
37
|
+
grok: report.accountCounts.grok,
|
|
38
|
+
openrouter: report.accountCounts.openrouter,
|
|
39
|
+
},
|
|
40
|
+
rows: report.rows.map((row, _i, rows) => ({
|
|
41
|
+
provider: row.provider,
|
|
42
|
+
account: accountLabel(rows.filter((r) => r.provider === row.provider).indexOf(row), rows.filter((r) => r.provider === row.provider).length),
|
|
43
|
+
accountCount: row.accountCount,
|
|
44
|
+
soleAccount: row.soleAccount,
|
|
45
|
+
credits: row.credits.status === 'ok' ? {
|
|
46
|
+
status: 'ok' as const,
|
|
47
|
+
usedPercent: row.credits.usedPercent,
|
|
48
|
+
periodType: periodType(row.credits.periodType),
|
|
49
|
+
periodStart: isoDate(row.credits.periodStart),
|
|
50
|
+
periodEnd: isoDate(row.credits.periodEnd),
|
|
51
|
+
resetsInMs: resetsInMs(row.credits.periodEnd ? Date.parse(row.credits.periodEnd) : 0, nowMs),
|
|
52
|
+
monthlyLimit: row.credits.monthlyLimit,
|
|
53
|
+
used: row.credits.used,
|
|
54
|
+
onDemandCap: row.credits.onDemandCap,
|
|
55
|
+
onDemandUsed: row.credits.onDemandUsed,
|
|
56
|
+
prepaidBalance: row.credits.prepaidBalance,
|
|
57
|
+
balance: row.credits.balance,
|
|
58
|
+
hasCredits: row.credits.hasCredits,
|
|
59
|
+
unlimited: row.credits.unlimited,
|
|
60
|
+
} : { status: row.credits.status },
|
|
61
|
+
subscription: row.subscription.status === 'available' ? {
|
|
62
|
+
status: 'available' as const,
|
|
63
|
+
remainingPercent: row.subscription.remainingPercent,
|
|
64
|
+
resetsAt: row.subscription.resetsAt,
|
|
65
|
+
resetsInMs: resetsInMs(row.subscription.resetsAt, nowMs),
|
|
66
|
+
windowKind: row.subscription.windowKind,
|
|
67
|
+
} : { status: 'unavailable' as const, reason: safeReason(row.subscription.reason) },
|
|
68
|
+
resetCredits: row.resetCredits.status === 'available' || row.resetCredits.status === 'expiring-soon' || row.resetCredits.status === 'expired' ? {
|
|
69
|
+
status: row.resetCredits.status,
|
|
70
|
+
expiresAt: isoDate(row.resetCredits.expiresAt),
|
|
71
|
+
hasUnknownExpiry: row.resetCredits.hasUnknownExpiry,
|
|
72
|
+
} : { status: row.resetCredits.status },
|
|
73
|
+
})),
|
|
74
|
+
};
|
|
75
|
+
}
|
|
76
|
+
|
|
77
|
+
/** A per-daemon 30-second snapshot; concurrent requests share the same collection. */
|
|
78
|
+
export function createUsageHandler(
|
|
79
|
+
collect: () => Promise<UnifiedUsageReport> = collectUnifiedUsage,
|
|
80
|
+
now: () => number = Date.now,
|
|
81
|
+
): () => Promise<Response> {
|
|
82
|
+
let cached: ReturnType<typeof projectUsage> | undefined;
|
|
83
|
+
let cachedAt = 0;
|
|
84
|
+
let pending: Promise<ReturnType<typeof projectUsage>> | undefined;
|
|
85
|
+
return async () => {
|
|
86
|
+
if (cached && now() - cachedAt < CACHE_MS) return jsonResponse(cached);
|
|
87
|
+
pending ??= Promise.resolve().then(collect).then((report) => {
|
|
88
|
+
const value = projectUsage(report, now());
|
|
89
|
+
cached = value;
|
|
90
|
+
cachedAt = now();
|
|
91
|
+
return value;
|
|
92
|
+
}).finally(() => { pending = undefined; });
|
|
93
|
+
try {
|
|
94
|
+
return jsonResponse(await pending);
|
|
95
|
+
} catch {
|
|
96
|
+
// Upstream exceptions can contain credentials; never echo their messages.
|
|
97
|
+
return jsonResponse({ ok: false, reason: 'usage-collection-failed' });
|
|
98
|
+
}
|
|
99
|
+
};
|
|
100
|
+
}
|
|
101
|
+
|
|
102
|
+
export const handleUsageGet = createUsageHandler();
|
|
@@ -73,6 +73,7 @@ export function publishWorkflowRunEvent(
|
|
|
73
73
|
const detail: Record<string, unknown> = {
|
|
74
74
|
runId: ctx.runId,
|
|
75
75
|
workflowName: ctx.workflowName,
|
|
76
|
+
...(evt.mode !== undefined ? { mode: evt.mode } : {}),
|
|
76
77
|
};
|
|
77
78
|
if (evt.type === 'node_start' || evt.type === 'node_skipped' || evt.type === 'node_done') {
|
|
78
79
|
detail.nodeId = evt.nodeId;
|
|
@@ -40,8 +40,12 @@ import {
|
|
|
40
40
|
parseWorkflowYaml,
|
|
41
41
|
runWorkflow,
|
|
42
42
|
saveWorkflow,
|
|
43
|
+
topoSort,
|
|
43
44
|
type WorkflowDeps,
|
|
44
45
|
type WorkflowEvent,
|
|
46
|
+
type WorkflowRunMode,
|
|
47
|
+
type NodeOutput,
|
|
48
|
+
type RunWorkflowOpts,
|
|
45
49
|
} from '../../workflow-runtime/index.js';
|
|
46
50
|
import { buildRunCft, buildRunSkill } from '../../workflow-runtime/deps-bridge.js';
|
|
47
51
|
import {
|
|
@@ -59,6 +63,7 @@ import { runApprovalAcrossChannels } from './workflow-approval-multi-channel.js'
|
|
|
59
63
|
interface RunRecord {
|
|
60
64
|
runId: string;
|
|
61
65
|
workflowName: string;
|
|
66
|
+
mode: WorkflowRunMode;
|
|
62
67
|
startedAt: number;
|
|
63
68
|
events: WorkflowEvent[];
|
|
64
69
|
/** Settled state: undefined while running, true on workflow_done,
|
|
@@ -384,10 +389,51 @@ export async function handleWorkflowRunStart(
|
|
|
384
389
|
// so the PWA "▶ Run now" button runs the dependent chain straight
|
|
385
390
|
// through. Default false preserves the production wire.
|
|
386
391
|
const dryRun: boolean = Boolean(body && typeof body === 'object' && (body as { dryRun?: unknown }).dryRun === true);
|
|
392
|
+
const input = body && typeof body === 'object' ? body as Record<string, unknown> : {};
|
|
393
|
+
const { onlyNode, fromNode, fromRunId } = input;
|
|
394
|
+
if ('usePins' in input || (onlyNode !== undefined && (fromNode !== undefined || fromRunId !== undefined))
|
|
395
|
+
|| (onlyNode !== undefined && (typeof onlyNode !== 'string' || !onlyNode.trim()))
|
|
396
|
+
|| (fromNode !== undefined && (typeof fromNode !== 'string' || !fromNode.trim()))
|
|
397
|
+
|| (fromRunId !== undefined && (typeof fromRunId !== 'string' || !fromRunId.trim()))
|
|
398
|
+
|| (fromNode === undefined) !== (fromRunId === undefined)
|
|
399
|
+
|| (input.mode !== undefined && input.mode !== 'test')) {
|
|
400
|
+
return jsonResponse({ error: 'bad_request', reason: 'invalid run selection' }, 400);
|
|
401
|
+
}
|
|
402
|
+
if ((onlyNode && !entry.definition.nodes.some(n => n.id === onlyNode))
|
|
403
|
+
|| (fromNode && !entry.definition.nodes.some(n => n.id === fromNode))) {
|
|
404
|
+
return jsonResponse({ error: 'bad_request', reason: 'unknown selected node' }, 400);
|
|
405
|
+
}
|
|
406
|
+
let previousOutputs: Record<string, NodeOutput> | undefined;
|
|
407
|
+
if (typeof fromRunId === 'string') {
|
|
408
|
+
const previous = RUN_REGISTRY.get(fromRunId);
|
|
409
|
+
if (previous) {
|
|
410
|
+
if (previous.workflowName !== name || previous.ok === undefined) {
|
|
411
|
+
return jsonResponse({ error: 'bad_request', reason: 'source run must be settled for this workflow' }, 400);
|
|
412
|
+
}
|
|
413
|
+
const terminal = previous.events.find(e => e.type === 'workflow_done' || e.type === 'workflow_failed');
|
|
414
|
+
previousOutputs = terminal?.type === 'workflow_done' ? terminal.outputs
|
|
415
|
+
: terminal?.type === 'workflow_failed' ? terminal.partial : {};
|
|
416
|
+
} else {
|
|
417
|
+
const disk = readRunOutputSnapshot(fromRunId);
|
|
418
|
+
if (!disk || disk.workflowName !== name || (disk.status !== 'done' && disk.status !== 'failed')) {
|
|
419
|
+
return jsonResponse({ error: 'bad_request', reason: 'source run must be settled for this workflow' }, 400);
|
|
420
|
+
}
|
|
421
|
+
previousOutputs = disk.outputs;
|
|
422
|
+
}
|
|
423
|
+
let order: string[];
|
|
424
|
+
try { order = topoSort(entry.definition.nodes); }
|
|
425
|
+
catch { return jsonResponse({ error: 'bad_request', reason: 'invalid workflow topology' }, 400); }
|
|
426
|
+
const upstream = order.slice(0, order.indexOf(fromNode as string));
|
|
427
|
+
if (upstream.some(id => previousOutputs?.[id] === undefined)) {
|
|
428
|
+
return jsonResponse({ error: 'bad_request', reason: 'source run missing upstream outputs' }, 400);
|
|
429
|
+
}
|
|
430
|
+
}
|
|
431
|
+
const mode: WorkflowRunMode = input.mode === 'test' ? 'test' : onlyNode ? 'only' : fromNode ? 'from' : 'full';
|
|
387
432
|
const runId = `wf-${Date.now()}-${Math.random().toString(36).slice(2, 8)}`;
|
|
388
433
|
const record: RunRecord = {
|
|
389
434
|
runId,
|
|
390
435
|
workflowName: name,
|
|
436
|
+
mode,
|
|
391
437
|
startedAt: Date.now(),
|
|
392
438
|
events: [],
|
|
393
439
|
ok: undefined,
|
|
@@ -400,10 +446,14 @@ export async function handleWorkflowRunStart(
|
|
|
400
446
|
void (async () => {
|
|
401
447
|
const deps = buildDefaultWorkflowDeps({ runId });
|
|
402
448
|
try {
|
|
403
|
-
|
|
404
|
-
|
|
405
|
-
|
|
406
|
-
|
|
449
|
+
const runOpts: RunWorkflowOpts = {
|
|
450
|
+
workflow: entry.definition, arguments: args, runId, dryRun, mode,
|
|
451
|
+
...(typeof onlyNode === 'string' ? { onlyNode } : {}),
|
|
452
|
+
...(typeof fromNode === 'string' ? { fromNode } : {}),
|
|
453
|
+
...(previousOutputs ? { previousOutputs } : {}),
|
|
454
|
+
};
|
|
455
|
+
for await (const runtimeEvent of runWorkflow(runOpts, deps)) {
|
|
456
|
+
const evt = { ...runtimeEvent, mode };
|
|
407
457
|
record.events.push(evt);
|
|
408
458
|
// §15.8(b) — fan into NexusEventBus → PWA invalidates queries
|
|
409
459
|
// on push instead of polling. No-op when bus is unwired
|
|
@@ -423,13 +473,14 @@ export async function handleWorkflowRunStart(
|
|
|
423
473
|
type: 'workflow_failed' as const,
|
|
424
474
|
error: err instanceof Error ? err.message : String(err),
|
|
425
475
|
partial: {},
|
|
476
|
+
mode,
|
|
426
477
|
};
|
|
427
478
|
record.events.push(failEvt);
|
|
428
479
|
publishWorkflowRunEvent({ runId, workflowName: name }, failEvt);
|
|
429
480
|
}
|
|
430
481
|
})();
|
|
431
482
|
|
|
432
|
-
return jsonResponse({ ok: true, runId }, 202);
|
|
483
|
+
return jsonResponse({ ok: true, runId, mode }, 202);
|
|
433
484
|
}
|
|
434
485
|
|
|
435
486
|
export function handleWorkflowRunGet(
|
|
@@ -444,6 +495,7 @@ export function handleWorkflowRunGet(
|
|
|
444
495
|
{
|
|
445
496
|
runId: rec.runId,
|
|
446
497
|
workflowName: rec.workflowName,
|
|
498
|
+
mode: rec.mode,
|
|
447
499
|
startedAt: rec.startedAt,
|
|
448
500
|
ok: rec.ok,
|
|
449
501
|
events: rec.events,
|
|
@@ -597,6 +649,21 @@ interface DiskRunSummary {
|
|
|
597
649
|
* enough that abandoned runs don't pollute the list across sessions. */
|
|
598
650
|
const STALE_RUNNING_AFTER_MS = 30 * 60 * 1000;
|
|
599
651
|
|
|
652
|
+
function readRunOutputSnapshot(runId: string): {
|
|
653
|
+
workflowName: string;
|
|
654
|
+
status: string;
|
|
655
|
+
outputs: Record<string, NodeOutput>;
|
|
656
|
+
} | null {
|
|
657
|
+
if (!/^wf-[A-Za-z0-9-]+$/.test(runId) || runId.includes('..')) return null;
|
|
658
|
+
try {
|
|
659
|
+
const parsed = JSON.parse(readFileSync(join(workflowsRunsRoot(), runId, 'run.json'), 'utf-8')) as {
|
|
660
|
+
workflowName?: string; status?: string; outputs?: Record<string, NodeOutput>;
|
|
661
|
+
};
|
|
662
|
+
if (!parsed.workflowName || !parsed.status || !parsed.outputs || typeof parsed.outputs !== 'object') return null;
|
|
663
|
+
return { workflowName: parsed.workflowName, status: parsed.status, outputs: parsed.outputs };
|
|
664
|
+
} catch { return null; }
|
|
665
|
+
}
|
|
666
|
+
|
|
600
667
|
/** Read `<root>/<runId>/run.json` and translate into the same shape as
|
|
601
668
|
* GET /runs/<id> serves from memory. Returns null when the file is
|
|
602
669
|
* missing or unreadable. Events are reconstructed minimally from the
|
|
@@ -608,6 +675,7 @@ function loadRunFromDisk(runId: string): {
|
|
|
608
675
|
ok: boolean | undefined;
|
|
609
676
|
events: WorkflowEvent[];
|
|
610
677
|
outputs: Record<string, unknown>;
|
|
678
|
+
mode?: WorkflowRunMode;
|
|
611
679
|
} | null {
|
|
612
680
|
if (!runId || runId.includes('/') || runId.includes('..')) return null;
|
|
613
681
|
const root = workflowsRunsRoot();
|
|
@@ -623,6 +691,7 @@ function loadRunFromDisk(runId: string): {
|
|
|
623
691
|
completedAt?: number;
|
|
624
692
|
ok?: boolean;
|
|
625
693
|
status?: string;
|
|
694
|
+
mode?: WorkflowRunMode;
|
|
626
695
|
outputs?: Record<string, { output?: unknown }>;
|
|
627
696
|
};
|
|
628
697
|
if (!parsed.runId || !parsed.workflowName) return null;
|
|
@@ -634,7 +703,8 @@ function loadRunFromDisk(runId: string): {
|
|
|
634
703
|
// so a polling client still sees the node_done sequence even
|
|
635
704
|
// though the live run.json doesn't store events.
|
|
636
705
|
const events: WorkflowEvent[] = [];
|
|
637
|
-
events.push({ type: 'workflow_start', workflow: parsed.workflowName, runId: parsed.runId
|
|
706
|
+
events.push({ type: 'workflow_start', workflow: parsed.workflowName, runId: parsed.runId,
|
|
707
|
+
...(parsed.mode !== undefined ? { mode: parsed.mode } : {}) });
|
|
638
708
|
const nodesDir = join(runDir, 'nodes');
|
|
639
709
|
// Iterate `parsed.outputs` keys instead of `readdirSync(nodesDir)`
|
|
640
710
|
// so the reconstructed node_done sequence is in execution order
|
|
@@ -673,6 +743,7 @@ function loadRunFromDisk(runId: string): {
|
|
|
673
743
|
events.push({
|
|
674
744
|
type: 'node_done',
|
|
675
745
|
nodeId,
|
|
746
|
+
...(parsed.mode !== undefined ? { mode: parsed.mode } : {}),
|
|
676
747
|
result: {
|
|
677
748
|
ok: nodeData.ok,
|
|
678
749
|
output: nodeData.output ?? '',
|
|
@@ -684,6 +755,7 @@ function loadRunFromDisk(runId: string): {
|
|
|
684
755
|
if (parsed.status === 'done') {
|
|
685
756
|
events.push({
|
|
686
757
|
type: 'workflow_done',
|
|
758
|
+
...(parsed.mode !== undefined ? { mode: parsed.mode } : {}),
|
|
687
759
|
outputs: Object.fromEntries(
|
|
688
760
|
Object.entries(parsed.outputs ?? {}).map(([k, v]) => [
|
|
689
761
|
k,
|
|
@@ -694,6 +766,7 @@ function loadRunFromDisk(runId: string): {
|
|
|
694
766
|
} else if (parsed.status === 'failed') {
|
|
695
767
|
events.push({
|
|
696
768
|
type: 'workflow_failed',
|
|
769
|
+
...(parsed.mode !== undefined ? { mode: parsed.mode } : {}),
|
|
697
770
|
error: 'failed (see node events)',
|
|
698
771
|
partial: Object.fromEntries(
|
|
699
772
|
Object.entries(parsed.outputs ?? {}).map(([k, v]) => [
|
|
@@ -706,6 +779,7 @@ function loadRunFromDisk(runId: string): {
|
|
|
706
779
|
return {
|
|
707
780
|
runId: parsed.runId,
|
|
708
781
|
workflowName: parsed.workflowName,
|
|
782
|
+
...(parsed.mode !== undefined ? { mode: parsed.mode } : {}),
|
|
709
783
|
startedAt: parsed.startedAt ?? 0,
|
|
710
784
|
ok: parsed.status === 'done' ? true : parsed.status === 'failed' ? false : undefined,
|
|
711
785
|
events,
|