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
|
@@ -3,12 +3,15 @@
|
|
|
3
3
|
* manifest transforms and private redactions applied, then the leak markers. A hit here fails the next prepare
|
|
4
4
|
* (0.2.7: one test title), so `pr land` and the harness policy gates run it before landing.
|
|
5
5
|
*
|
|
6
|
-
* bun scripts/ci-public-export-leak-gate.ts --changed-files a b … # exit 1 on a hit · 0 when clean
|
|
6
|
+
* bun scripts/ci-public-export-leak-gate.ts --changed-files a b … # exit 1 on a hit · 0 when clean
|
|
7
7
|
*/
|
|
8
8
|
import { spawnSync } from 'node:child_process';
|
|
9
|
-
import { existsSync } from 'node:fs';
|
|
10
|
-
import {
|
|
11
|
-
import {
|
|
9
|
+
import { existsSync, mkdtempSync, rmSync, writeFileSync } from 'node:fs';
|
|
10
|
+
import { tmpdir } from 'node:os';
|
|
11
|
+
import { join, relative, resolve } from 'node:path';
|
|
12
|
+
import { stringify } from 'yaml';
|
|
13
|
+
import { computeSkillBoundaries, filterFilesBySkillVerdict } from './skill-boundary.js';
|
|
14
|
+
import { loadExportConfig, privateRedactionsPath, selectExportFiles } from './public-export.js';
|
|
12
15
|
|
|
13
16
|
export interface ExportLeakCheck {
|
|
14
17
|
readonly measured: boolean;
|
|
@@ -16,29 +19,87 @@ export interface ExportLeakCheck {
|
|
|
16
19
|
readonly detail?: string;
|
|
17
20
|
}
|
|
18
21
|
|
|
19
|
-
export
|
|
22
|
+
/** Changed source paths that the public manifest would export; unknown skill boundaries remain in scope. */
|
|
23
|
+
export function publicExportChangedFiles(changedFiles: readonly string[], root: string): string[] {
|
|
24
|
+
const config = loadExportConfig(root);
|
|
25
|
+
const selected = [...new Set([
|
|
26
|
+
...selectExportFiles(changedFiles, config),
|
|
27
|
+
...changedFiles.filter((file) => Object.values(config.replace).includes(file)),
|
|
28
|
+
])];
|
|
29
|
+
if (!config.skills || !selected.some((file) => file.startsWith('skills/'))) return selected;
|
|
30
|
+
try {
|
|
31
|
+
const boundary = computeSkillBoundaries(root);
|
|
32
|
+
if (boundary.errors.length) return selected;
|
|
33
|
+
return filterFilesBySkillVerdict(selected, boundary, config.skills);
|
|
34
|
+
} catch { return selected; }
|
|
35
|
+
}
|
|
36
|
+
|
|
37
|
+
export function exportLeakCheck(changedFiles: readonly string[], root: string, spawn: typeof spawnSync = spawnSync): ExportLeakCheck {
|
|
20
38
|
const script = join(root, 'scripts', 'public-export.ts');
|
|
21
39
|
if (!existsSync(script)) return { measured: false, hits: [], detail: 'scripts/public-export.ts 없음' };
|
|
22
40
|
// Without the private table (a Pod, a fresh machine) the markers still run; private identifiers are not checked.
|
|
23
41
|
const privateList = existsSync(privateRedactionsPath()) ? [] : ['--no-private-list'];
|
|
24
|
-
const
|
|
42
|
+
const args = ['--leak-check', '--json', '--all', ...privateList, '--files', ...changedFiles];
|
|
43
|
+
const run = (flags: string[]) => spawn('bun', [script, ...flags], { cwd: root, encoding: 'utf-8', timeout: 180_000, maxBuffer: 64 * 1024 * 1024 });
|
|
44
|
+
const initial = run(args);
|
|
45
|
+
if (initial.status !== 2) return measuredLeaks(initial);
|
|
46
|
+
|
|
47
|
+
const hits = [...String(initial.stderr).matchAll(/^⛔ skill boundary: ([^:\r\n]+):[^\r\n]*$/gm)]
|
|
48
|
+
.map((match) => ({ file: `skills/${match[1]}/SKILL.md`, line: 1, marker: 'skill-boundary' }));
|
|
49
|
+
if (!hits.length || !String(initial.stderr).trim().split(/\r?\n/).every((line) => /^⛔ skill boundary: [^:\r\n]+:[^\r\n]*$/.test(line))) {
|
|
50
|
+
return { measured: false, hits: [], detail: 'rc=2' };
|
|
51
|
+
}
|
|
52
|
+
|
|
53
|
+
// The exporter stops before scanning any changed file on a boundary error. Re-run its
|
|
54
|
+
// same transforms and leak check with only boundary selection disabled; retain the boundary hits.
|
|
55
|
+
let dir: string | undefined;
|
|
56
|
+
try {
|
|
57
|
+
const config = loadExportConfig(root);
|
|
58
|
+
dir = mkdtempSync(join(tmpdir(), 'public-export-leak-'));
|
|
59
|
+
const configPath = join(dir, 'export.yaml');
|
|
60
|
+
writeFileSync(configPath, stringify({ ...config, skills: undefined }));
|
|
61
|
+
const measured = measuredLeaks(run(['--config', relative(root, configPath), ...args]));
|
|
62
|
+
return { ...measured, hits: [...hits, ...measured.hits] };
|
|
63
|
+
} catch {
|
|
64
|
+
return { measured: false, hits, detail: 'skill boundary 뒤 재검사 실패' };
|
|
65
|
+
} finally {
|
|
66
|
+
if (dir) rmSync(dir, { recursive: true, force: true });
|
|
67
|
+
}
|
|
68
|
+
}
|
|
69
|
+
|
|
70
|
+
function measuredLeaks(r: ReturnType<typeof spawnSync>): ExportLeakCheck {
|
|
25
71
|
if (r.status !== 0 && r.status !== 1) return { measured: false, hits: [], detail: `rc=${r.status ?? r.signal}` };
|
|
26
72
|
try {
|
|
27
|
-
const parsed = JSON.parse(String(r.stdout).trim().split('\n').at(-1) ?? '')
|
|
28
|
-
|
|
73
|
+
const parsed: unknown = JSON.parse(String(r.stdout).trim().split('\n').at(-1) ?? '');
|
|
74
|
+
if (!parsed || typeof parsed !== 'object' || !('hits' in parsed) || !Array.isArray(parsed.hits)
|
|
75
|
+
|| parsed.hits.some((h: unknown) => !h || typeof h !== 'object'
|
|
76
|
+
|| typeof (h as { file?: unknown }).file !== 'string'
|
|
77
|
+
|| typeof (h as { line?: unknown }).line !== 'number'
|
|
78
|
+
|| typeof (h as { marker?: unknown }).marker !== 'string')) throw new Error('invalid hits');
|
|
79
|
+
return { measured: true, hits: parsed.hits.map((h: { file: string; line: number; marker: string }) => ({ file: h.file, line: h.line, marker: h.marker })) };
|
|
29
80
|
} catch { return { measured: false, hits: [], detail: 'JSON 을 못 읽었다' }; }
|
|
30
81
|
}
|
|
31
82
|
|
|
32
|
-
/** Gate form for the harness policy gates: 1 on a hit, 0 when clean
|
|
83
|
+
/** Gate form for the harness policy gates: 1 on a hit, 0 when clean (said in a line). */
|
|
33
84
|
export function runPublicExportLeakGate(io: { args: readonly string[]; cwd: string; log: (line: string) => void; error: (line: string) => void }): number {
|
|
34
85
|
const at = io.args.indexOf('--changed-files');
|
|
35
86
|
const files = at >= 0 ? io.args.slice(at + 1).filter((a) => !a.startsWith('--')) : [];
|
|
36
87
|
if (files.length === 0) return 0;
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
88
|
+
let result: ExportLeakCheck;
|
|
89
|
+
try { result = exportLeakCheck(files, io.cwd); }
|
|
90
|
+
catch { result = { measured: false, hits: [], detail: '검사 실행 실패' }; }
|
|
91
|
+
if (!result.measured) {
|
|
92
|
+
let publicFiles: string[];
|
|
93
|
+
try { publicFiles = publicExportChangedFiles(files, io.cwd); }
|
|
94
|
+
catch { publicFiles = files; }
|
|
95
|
+
if (publicFiles.length === 0) { io.log('⚠ public-export-leak: 못 쟀다 — 공개 대상 변경 없음'); return 0; }
|
|
96
|
+
io.error(`✗ public-export-leak: 못 쟀다 — 막는다(${result.detail ?? '?'})`);
|
|
97
|
+
return 1;
|
|
98
|
+
}
|
|
99
|
+
const hits = result.hits.filter((hit) => hit.marker !== 'skill-boundary' || files.includes(hit.file));
|
|
100
|
+
if (hits.length === 0) return 0;
|
|
101
|
+
io.error(`✗ public-export-leak: 바뀐 파일 ${hits.length}곳이 공개본에 사적 흔적을 싣는다 — 다음 release prepare 가 여기서 실패한다:`);
|
|
102
|
+
for (const h of hits) io.error(` ${h.file}:${h.line} · ${h.marker}`);
|
|
42
103
|
io.error(' 그 줄에서 표식·홈 경로·내부 문서 이름을 빼라(주석이면 공개본 변환이 지우는지 bun scripts/public-export.ts --leak-check --files <파일> 로 확인).');
|
|
43
104
|
return 1;
|
|
44
105
|
}
|
|
@@ -10,8 +10,8 @@
|
|
|
10
10
|
* bun scripts/ci-public-leak-gate.ts --changed-files a b … # 그 파일들만 검사
|
|
11
11
|
* bun scripts/ci-public-leak-gate.ts --update # 기준선 재스냅샷(치운 뒤)
|
|
12
12
|
*
|
|
13
|
-
*
|
|
14
|
-
*
|
|
13
|
+
* `pr land` 는 변경 파일을 PR 트리에서 스캔하고 기준선은 base ref 에서 읽어 방향을 경고 전용으로 표시한다.
|
|
14
|
+
* 단독 CLI 의 기본 기준선은 현재 트리의 파일이며, 증가는 exit 1 이다.
|
|
15
15
|
*/
|
|
16
16
|
import { existsSync, readFileSync, writeFileSync } from 'node:fs';
|
|
17
17
|
import { join, resolve } from 'node:path';
|
|
@@ -57,6 +57,19 @@ export function renderBaseline(counts: ReadonlyMap<string, number>): string {
|
|
|
57
57
|
|
|
58
58
|
export interface LeakGrowth { readonly marker: string; readonly file: string; readonly allowed: number; readonly now: number }
|
|
59
59
|
|
|
60
|
+
/** 기준선과 현재 트리의 모든 차이(사라진 표지 포함). */
|
|
61
|
+
export function findLeakChanges(current: ReadonlyMap<string, number>, baseline: ReadonlyMap<string, number>, only?: ReadonlySet<string>): LeakGrowth[] {
|
|
62
|
+
const out: LeakGrowth[] = [];
|
|
63
|
+
for (const key of new Set([...baseline.keys(), ...current.keys()])) {
|
|
64
|
+
const [marker, file] = key.split('\t') as [string, string];
|
|
65
|
+
if (only && !only.has(file)) continue;
|
|
66
|
+
const allowed = baseline.get(key) ?? 0;
|
|
67
|
+
const now = current.get(key) ?? 0;
|
|
68
|
+
if (now !== allowed) out.push({ marker, file, allowed, now });
|
|
69
|
+
}
|
|
70
|
+
return out.sort((a, b) => a.file.localeCompare(b.file) || a.marker.localeCompare(b.marker));
|
|
71
|
+
}
|
|
72
|
+
|
|
60
73
|
/** 기준선보다 «늘어난» (표지, 파일). `only` 가 있으면 그 파일만 본다. */
|
|
61
74
|
export function findGrowth(current: ReadonlyMap<string, number>, baseline: ReadonlyMap<string, number>, only?: ReadonlySet<string>): LeakGrowth[] {
|
|
62
75
|
const out: LeakGrowth[] = [];
|
|
@@ -81,6 +94,8 @@ export interface PublicLeakGateIo {
|
|
|
81
94
|
readonly args?: readonly string[];
|
|
82
95
|
readonly root?: string;
|
|
83
96
|
readonly scan?: () => LeakHit[];
|
|
97
|
+
/** Read the baseline from the landing base commit, not the PR's working tree. */
|
|
98
|
+
readonly baselineRef?: string;
|
|
84
99
|
readonly log?: (s: string) => void;
|
|
85
100
|
readonly error?: (s: string) => void;
|
|
86
101
|
}
|
|
@@ -100,14 +115,34 @@ export function runPublicLeakGate(io: PublicLeakGateIo = {}): number {
|
|
|
100
115
|
log(`[public-leak-gate] baseline updated — ${[...current.values()].reduce((a, n) => a + n, 0)} hits · ${current.size} entries`);
|
|
101
116
|
return 0;
|
|
102
117
|
}
|
|
103
|
-
|
|
104
|
-
|
|
118
|
+
let baselineText: string;
|
|
119
|
+
if (io.baselineRef) {
|
|
120
|
+
const shown = spawnSync('git', ['-C', root, 'show', `${io.baselineRef}:${BASELINE_REL}`], { encoding: 'utf8', maxBuffer: 1 << 28 });
|
|
121
|
+
if (shown.status !== 0) { error(`[public-leak-gate] FAIL — ${io.baselineRef} 기준선을 못 읽었다: ${BASELINE_REL}`); return 2; }
|
|
122
|
+
baselineText = shown.stdout;
|
|
123
|
+
} else {
|
|
124
|
+
if (!existsSync(baselinePath)) { error(`[public-leak-gate] FAIL — 기준선이 없다: ${BASELINE_REL} (--update 로 만든다)`); return 2; }
|
|
125
|
+
baselineText = readFileSync(baselinePath, 'utf8');
|
|
126
|
+
}
|
|
127
|
+
const baseline = parseBaseline(baselineText);
|
|
128
|
+
const growth = findGrowth(current, baseline, only);
|
|
105
129
|
const scope = only ? `변경 파일 ${only.size}개` : '전체';
|
|
106
|
-
if (growth.length
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
130
|
+
if (growth.length > 0) {
|
|
131
|
+
error(`[public-leak-gate] FAIL — 유출이 늘었다 (${scope} · ${growth.length}곳):`);
|
|
132
|
+
for (const g of growth) error(` ${g.file} ${g.marker} ${g.allowed} → ${g.now}`);
|
|
133
|
+
error(' 확인: bun scripts/public-export.ts --leak-check --path <파일> --all');
|
|
134
|
+
return 1;
|
|
135
|
+
}
|
|
136
|
+
if (io.baselineRef) {
|
|
137
|
+
const shrunk = findLeakChanges(current, baseline, only).filter((change) => change.now < change.allowed);
|
|
138
|
+
if (shrunk.length > 0) {
|
|
139
|
+
log(`[public-leak-gate] SHRANK — 유출이 줄었다 · 기준선 --update 권장 (${scope} · ${shrunk.length}곳):`);
|
|
140
|
+
for (const g of shrunk) log(` ${g.file} ${g.marker} ${g.allowed} → ${g.now}`);
|
|
141
|
+
return 3;
|
|
142
|
+
}
|
|
143
|
+
}
|
|
144
|
+
log(`[public-leak-gate] PASS — 유출이 늘지 않았다 (${scope})`);
|
|
145
|
+
return 0;
|
|
111
146
|
}
|
|
112
147
|
|
|
113
148
|
if (import.meta.main) process.exit(runPublicLeakGate());
|
|
@@ -0,0 +1,160 @@
|
|
|
1
|
+
#!/usr/bin/env bun
|
|
2
|
+
// PWA build gate (GATE-PWA · 10-02 MAT1b near-miss: a PWA-bundled src module gained a TUI import and every gate passed).
|
|
3
|
+
// The PWA is a static export outside `bun test`/tsc, so a change that reaches its bundle graph is built here.
|
|
4
|
+
// Reach is decided by the TypeScript program of apps/pwa/tsconfig.json (aliases, extends, type imports included);
|
|
5
|
+
// anything the program cannot decide is treated as reaching the PWA — «unsure» builds, it never skips.
|
|
6
|
+
import { spawnSync } from 'node:child_process';
|
|
7
|
+
import { existsSync, readdirSync } from 'node:fs';
|
|
8
|
+
import { basename, dirname, extname, join, relative, resolve, sep } from 'node:path';
|
|
9
|
+
import ts from 'typescript';
|
|
10
|
+
import { debug } from '../src/debug/log.js';
|
|
11
|
+
import { checkPwaBuildDeps } from '../src/cli/pwa-build.js';
|
|
12
|
+
import { prepareDeterministicChildEnvironment } from './lib/deterministic-env.js';
|
|
13
|
+
import { parseChangedFiles } from './ci-ios-unit-tests.js';
|
|
14
|
+
|
|
15
|
+
const ROOT = join(import.meta.dir, '..');
|
|
16
|
+
const PWA_PREFIX = 'apps/pwa/';
|
|
17
|
+
const PWA_IGNORED = /^apps\/pwa\/(?:node_modules|\.next|out)\//;
|
|
18
|
+
const TS_SOURCE = /\.(?:tsx?|mts|cts)$/;
|
|
19
|
+
const CODE_OR_ASSET = /\.(?:[cm]?[jt]sx?|json|css|scss|svg|png|jpe?g|webp|woff2?)$/;
|
|
20
|
+
|
|
21
|
+
export type BuildResult = { status: number | null; output: string; error?: Error };
|
|
22
|
+
export type PwaGraph = { files: Set<string>; uncertain: string | null };
|
|
23
|
+
export type PwaGateIo = {
|
|
24
|
+
args?: readonly string[];
|
|
25
|
+
cwd?: string;
|
|
26
|
+
log?: (line: string) => void;
|
|
27
|
+
error?: (line: string) => void;
|
|
28
|
+
/** Repo-relative changed files when `--changed-files` is absent (test seam · default git diff vs origin/main). */
|
|
29
|
+
changedFiles?: (root: string) => string[] | null;
|
|
30
|
+
graph?: (root: string) => PwaGraph;
|
|
31
|
+
runBuild?: (root: string) => BuildResult;
|
|
32
|
+
};
|
|
33
|
+
|
|
34
|
+
function defaultBuild(root: string): BuildResult {
|
|
35
|
+
const pwa = join(root, 'apps/pwa');
|
|
36
|
+
let deps = checkPwaBuildDeps(pwa);
|
|
37
|
+
if (!deps.ok) {
|
|
38
|
+
// Pod worktrees and fresh harvest trees often have no apps/pwa/node_modules — install once from the lockfile, then re-check.
|
|
39
|
+
const install = spawnSync('bun', ['install', '--frozen-lockfile'], { cwd: pwa, encoding: 'utf8', timeout: 300_000, maxBuffer: 16 * 1024 * 1024 });
|
|
40
|
+
try { debug.log('gate.pwa', 'deps-install', { status: install.status }); } catch { /* fail-soft */ }
|
|
41
|
+
deps = checkPwaBuildDeps(pwa);
|
|
42
|
+
if (!deps.ok) return { status: null, output: `apps/pwa/node_modules incomplete after install (rc=${install.status}): ${deps.missing.slice(0, 3).join(', ')}` };
|
|
43
|
+
}
|
|
44
|
+
const isolated = prepareDeterministicChildEnvironment('elanous-pwa-build-gate-');
|
|
45
|
+
try {
|
|
46
|
+
// Same build `nexus build` runs (runPwaBuild → bun run build), with HOME/state/config confined to a temp child env.
|
|
47
|
+
const result = spawnSync('bun', ['run', 'build'], { cwd: pwa, env: isolated.env, encoding: 'utf8', timeout: 300_000, maxBuffer: 32 * 1024 * 1024 });
|
|
48
|
+
return { status: result.status, output: `${result.stdout ?? ''}\n${result.stderr ?? ''}`, error: result.error };
|
|
49
|
+
} finally {
|
|
50
|
+
isolated.cleanup();
|
|
51
|
+
}
|
|
52
|
+
}
|
|
53
|
+
|
|
54
|
+
function defaultChangedFiles(root: string): string[] | null {
|
|
55
|
+
const r = spawnSync('git', ['diff', '--name-only', 'origin/main...HEAD'], { cwd: root, encoding: 'utf8' });
|
|
56
|
+
if (r.status !== 0) return null;
|
|
57
|
+
return r.stdout.split('\n').map((l) => l.trim()).filter(Boolean);
|
|
58
|
+
}
|
|
59
|
+
|
|
60
|
+
/** Dynamic import()/require() whose argument is not a string literal — the program cannot follow it. */
|
|
61
|
+
function opaqueLoad(sf: ts.SourceFile): boolean {
|
|
62
|
+
let found = false;
|
|
63
|
+
const visit = (node: ts.Node): void => {
|
|
64
|
+
if (found) return;
|
|
65
|
+
if (ts.isCallExpression(node) && (node.expression.kind === ts.SyntaxKind.ImportKeyword
|
|
66
|
+
|| (ts.isIdentifier(node.expression) && node.expression.text === 'require'))) {
|
|
67
|
+
const arg = node.arguments[0];
|
|
68
|
+
if (!arg || !(ts.isStringLiteral(arg) || ts.isNoSubstitutionTemplateLiteral(arg))) { found = true; return; }
|
|
69
|
+
}
|
|
70
|
+
ts.forEachChild(node, visit);
|
|
71
|
+
};
|
|
72
|
+
visit(sf);
|
|
73
|
+
return found;
|
|
74
|
+
}
|
|
75
|
+
|
|
76
|
+
/** Every repo file the PWA program loads, plus same-stem siblings (a `.d.ts` may stand in for the `.js` the bundler reads). */
|
|
77
|
+
export function pwaGraph(root: string): PwaGraph {
|
|
78
|
+
const configPath = join(root, 'apps/pwa/tsconfig.json');
|
|
79
|
+
const read = ts.readConfigFile(configPath, ts.sys.readFile);
|
|
80
|
+
if (read.error) return { files: new Set(), uncertain: `tsconfig unreadable: ${ts.flattenDiagnosticMessageText(read.error.messageText, ' ')}` };
|
|
81
|
+
const parsed = ts.parseJsonConfigFileContent(read.config, ts.sys, dirname(configPath));
|
|
82
|
+
if (parsed.errors.some((d) => d.category === ts.DiagnosticCategory.Error)) {
|
|
83
|
+
return { files: new Set(), uncertain: `tsconfig invalid: ${ts.flattenDiagnosticMessageText(parsed.errors[0]!.messageText, ' ')}` };
|
|
84
|
+
}
|
|
85
|
+
const program = ts.createProgram({ rootNames: parsed.fileNames, options: { ...parsed.options, noEmit: true } });
|
|
86
|
+
const files = new Set<string>();
|
|
87
|
+
const absRoot = resolve(root) + sep;
|
|
88
|
+
for (const sf of program.getSourceFiles()) {
|
|
89
|
+
const abs = resolve(sf.fileName);
|
|
90
|
+
if (!abs.startsWith(absRoot) || abs.includes(`${sep}node_modules${sep}`)) continue;
|
|
91
|
+
const rel = relative(root, abs).split(sep).join('/');
|
|
92
|
+
files.add(rel);
|
|
93
|
+
// A non-literal import()/require() is a bundler «context»: anything beside it may be loaded — take the whole directory.
|
|
94
|
+
if (opaqueLoad(sf)) {
|
|
95
|
+
const dir = dirname(abs);
|
|
96
|
+
try {
|
|
97
|
+
for (const name of readdirSync(dir)) if (/\.(?:[cm]?[jt]sx?|json)$/.test(name)) files.add(relative(root, join(dir, name)).split(sep).join('/'));
|
|
98
|
+
} catch { return { files, uncertain: `cannot list ${relative(root, dir)} beside a non-literal import` }; }
|
|
99
|
+
}
|
|
100
|
+
const stem = basename(rel).replace(/\.d\.ts$|\.[^.]+$/, '');
|
|
101
|
+
for (const ext of ['.ts', '.tsx', '.js', '.jsx', '.mjs', '.cjs', '.d.ts', '.json', '.css']) {
|
|
102
|
+
const sibling = join(dirname(rel), stem + ext).split(sep).join('/');
|
|
103
|
+
if (existsSync(join(root, sibling))) files.add(sibling);
|
|
104
|
+
}
|
|
105
|
+
}
|
|
106
|
+
return { files, uncertain: null };
|
|
107
|
+
}
|
|
108
|
+
|
|
109
|
+
export type PwaReach = { reaches: boolean; reason: string; hits: string[] };
|
|
110
|
+
|
|
111
|
+
/** Decide whether a change set reaches the PWA build. Unknowns reach. */
|
|
112
|
+
export function pwaReach(changed: readonly string[], graph: () => PwaGraph): PwaReach {
|
|
113
|
+
const pwaHits = changed.filter((f) => f.startsWith(PWA_PREFIX) && !PWA_IGNORED.test(f));
|
|
114
|
+
if (pwaHits.length) return { reaches: true, reason: `apps/pwa 변경 ${pwaHits.length}개`, hits: pwaHits };
|
|
115
|
+
// Any repo file the PWA program loads counts (src/, scripts/, shared roots); non-code files under src/ build conservatively.
|
|
116
|
+
const candidates = changed.filter((f) => CODE_OR_ASSET.test(f));
|
|
117
|
+
if (!candidates.length) return { reaches: false, reason: `변경 ${changed.length}개 중 코드·자산 파일 0개`, hits: [] };
|
|
118
|
+
let g: PwaGraph;
|
|
119
|
+
try { g = graph(); } catch (err) { return { reaches: true, reason: `PWA 그래프를 못 읽었다(${err instanceof Error ? err.message : String(err)}) — 닿는 것으로 본다`, hits: candidates }; }
|
|
120
|
+
if (g.uncertain) return { reaches: true, reason: `PWA 그래프 판정 불가(${g.uncertain}) — 닿는 것으로 본다`, hits: candidates };
|
|
121
|
+
const hits = candidates.filter((f) => g.files.has(f) || (f.startsWith('src/') && !TS_SOURCE.test(f)));
|
|
122
|
+
if (hits.length) return { reaches: true, reason: `PWA 가 닿는 파일 ${hits.length}개`, hits };
|
|
123
|
+
return { reaches: false, reason: `코드 변경 ${candidates.length}개 — PWA 그래프(${g.files.size}개) 밖`, hits: [] };
|
|
124
|
+
}
|
|
125
|
+
|
|
126
|
+
export function runPwaBuildGate(io: PwaGateIo = {}): number {
|
|
127
|
+
const log = io.log ?? console.log;
|
|
128
|
+
const error = io.error ?? console.error;
|
|
129
|
+
const root = io.cwd ?? ROOT;
|
|
130
|
+
if (!io.graph && !existsSync(join(root, 'apps/pwa/package.json'))) {
|
|
131
|
+
log('[pwa-gate] 해당 없음 — 이 트리에 apps/pwa 가 없다.');
|
|
132
|
+
return 0;
|
|
133
|
+
}
|
|
134
|
+
const changed = parseChangedFiles(io.args ?? process.argv.slice(2)) ?? (io.changedFiles ?? defaultChangedFiles)(root);
|
|
135
|
+
if (changed === null) {
|
|
136
|
+
error('[pwa-gate] 측정 불가 — 변경 파일 목록을 못 얻었다(git diff 실패).');
|
|
137
|
+
return 1;
|
|
138
|
+
}
|
|
139
|
+
const reach = pwaReach(changed, () => (io.graph ?? pwaGraph)(root));
|
|
140
|
+
try { debug.log('gate.pwa', reach.reaches ? 'reach' : 'skip', { changed: changed.length, hits: reach.hits.slice(0, 20), reason: reach.reason }); } catch { /* fail-soft */ }
|
|
141
|
+
if (!reach.reaches) {
|
|
142
|
+
log(`[pwa-gate] 해당 없음 — ${reach.reason}.`);
|
|
143
|
+
return 0;
|
|
144
|
+
}
|
|
145
|
+
log(`[pwa-gate] 대상 — ${reach.reason}${reach.hits.length ? ` (${reach.hits.slice(0, 5).join(', ')}${reach.hits.length > 5 ? ' …' : ''})` : ''} — PWA 빌드를 돌린다.`);
|
|
146
|
+
const started = Date.now();
|
|
147
|
+
const result = (io.runBuild ?? defaultBuild)(root);
|
|
148
|
+
const seconds = Math.round((Date.now() - started) / 1000);
|
|
149
|
+
try { debug.log('gate.pwa', 'build', { status: result.status, seconds }); } catch { /* fail-soft */ }
|
|
150
|
+
if (result.status === 0) {
|
|
151
|
+
log(`[pwa-gate] PASS — PWA 빌드 성공(${seconds}s).`);
|
|
152
|
+
return 0;
|
|
153
|
+
}
|
|
154
|
+
const tail = result.output.trim().split('\n').slice(-15).join('\n');
|
|
155
|
+
if (result.status === null) error(`[pwa-gate] 측정 불가 — 빌드를 못 돌렸다: ${result.error?.message ?? tail.split('\n').pop() ?? 'unknown'}`);
|
|
156
|
+
else error(`[pwa-gate] FAIL — PWA 빌드 실패(rc=${result.status} · ${seconds}s):\n${tail}`);
|
|
157
|
+
return 1;
|
|
158
|
+
}
|
|
159
|
+
|
|
160
|
+
if (import.meta.main) process.exit(runPwaBuildGate());
|
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
import { spawnSync } from 'node:child_process';
|
|
2
|
+
|
|
3
|
+
const event = process.argv[2];
|
|
4
|
+
if (event !== 'stop' && event !== 'post-tool-use') process.exit(0);
|
|
5
|
+
|
|
6
|
+
try {
|
|
7
|
+
const payload = JSON.parse(await Bun.stdin.text()) as Record<string, unknown>;
|
|
8
|
+
// A locator is useful only when it is a session ID, not arbitrary hook input.
|
|
9
|
+
const session = payload.session_id;
|
|
10
|
+
if (typeof session !== 'string' || !/^[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}$/i.test(session)) process.exit(0);
|
|
11
|
+
const tool = payload.tool_name;
|
|
12
|
+
if (event === 'post-tool-use' && (typeof tool !== 'string' || !/^[a-z][a-z0-9_.:-]{0,63}$/i.test(tool))) process.exit(0);
|
|
13
|
+
// Only known tool identifiers can appear in the generated summary. Never copy hook free text.
|
|
14
|
+
const knownTools = new Set(['Read', 'Write', 'Edit', 'MultiEdit', 'Bash', 'Glob', 'Grep', 'LS',
|
|
15
|
+
'Task', 'WebFetch', 'WebSearch', 'NotebookEdit', 'TodoWrite', 'AskUserQuestion']);
|
|
16
|
+
const summary = event === 'stop' ? 'Claude Code session stopped'
|
|
17
|
+
: `Claude Code tool ${knownTools.has(tool as string) ? tool : 'other'} completed`;
|
|
18
|
+
const source = `elanous://context/claude-code/${session}`;
|
|
19
|
+
spawnSync('elanous', ['context', 'emit', '--kind', 'done', '--summary', summary, '--source', source], {
|
|
20
|
+
stdio: 'ignore', timeout: 3000,
|
|
21
|
+
});
|
|
22
|
+
} catch {
|
|
23
|
+
// Hooks must not interrupt the seat session on malformed input or unavailable CLI.
|
|
24
|
+
}
|
|
@@ -48,8 +48,8 @@
|
|
|
48
48
|
|
|
49
49
|
set -u
|
|
50
50
|
|
|
51
|
-
PR_NUM="${CH_PR:-
|
|
52
|
-
# 📏 이력: #5730(07-28~08-12) → #8328(08-11~08-25) → #12577(08-25~09-10) → #16815(09-10~09-27) → #20798.
|
|
51
|
+
PR_NUM="${CH_PR:-23032}" # ⛔ 2026-10-03: #20798 가 2,500 상한 → 채널 «6»(OP) # ⛔ 2026-09-27: #16815 가 2,500 상한에 닿아 채널 «5» 로 옮김(🅞 · 벽에 «닿은 뒤» — 미리 못 옮겼다)
|
|
52
|
+
# 📏 이력: #5730(07-28~08-12) → #8328(08-11~08-25) → #12577(08-25~09-10) → #16815(09-10~09-27) → #20798(09-27~10-03) → #23032.
|
|
53
53
|
# ***수명이 «2주 안팎»이다 — 세 판이 전부 그랬다.*** 다음 벽은 09-24 언저리.
|
|
54
54
|
# 🩹 발신이 rc=1 이면 먼저 세라: gh api repos/ElanvitalAI/elanous/issues/<n> --jq .comments
|
|
55
55
|
REPO="${CH_REPO:-ElanvitalAI/elanous}"
|
|
@@ -79,6 +79,18 @@ WATCH_EXIT_ANNOUNCED=0 # 종료 줄 중복 방지(INT→EXIT 로 trap 이 두
|
|
|
79
79
|
# 「거의 비었다」로 «의심»할 자수 — 이 아래로 떨어지면 «변경»이 아니라 «의심»으로 말한다.
|
|
80
80
|
BODY_MIN="${CH_BODY_MIN:-100}"
|
|
81
81
|
|
|
82
|
+
# ⛔⭐ WATCH1(10-03 MK 6시간 실명): 감시자에 고정 토큰(GH_TOKEN·GITHUB_TOKEN — App 토큰은 1시간)을 넣어 띄우면
|
|
83
|
+
# 만료 뒤 조회가 조용히 계속 실패한다. 읽기는 신원이 필요 없다 ⇒ 고정 토큰을 «비우고» keyring gh 인증으로 읽는다.
|
|
84
|
+
# 그 토큰을 꼭 써야 하면 WATCH_KEEP_TOKEN=1 (그때도 경고 줄은 낸다).
|
|
85
|
+
if [ -n "${GH_TOKEN:-}${GITHUB_TOKEN:-}" ]; then
|
|
86
|
+
if [ "${WATCH_KEEP_TOKEN:-}" = "1" ]; then
|
|
87
|
+
echo "⚠️ [watch] GH_TOKEN/GITHUB_TOKEN 고정 토큰으로 읽는다(WATCH_KEEP_TOKEN=1) — 만료되면 «⛔ 조회 실패» 줄이 뜬다"
|
|
88
|
+
else
|
|
89
|
+
echo "⚠️ [watch] GH_TOKEN/GITHUB_TOKEN 이 들어 있어 비웠다 — 읽기는 keyring gh 인증으로(고정 토큰은 만료돼 감시가 눈이 먼다 · WATCH1)"
|
|
90
|
+
unset GH_TOKEN GITHUB_TOKEN
|
|
91
|
+
fi
|
|
92
|
+
fi
|
|
93
|
+
|
|
82
94
|
CMD="ensure"
|
|
83
95
|
TRACK=""
|
|
84
96
|
ADOPT_PID=""
|
|
@@ -418,6 +430,23 @@ FALLBACK_USES=0
|
|
|
418
430
|
# 「파이프를 통과하면 성패가 사라진다」와 같은 뿌리다.
|
|
419
431
|
FALLBACK_FLAG="${TMPDIR:-/tmp}/ch-watch-fallback-$PR_NUM-$TRACK.$$"
|
|
420
432
|
|
|
433
|
+
emit_comments() { # $1=JSONL (line, archive, comment)
|
|
434
|
+
local out="$1" deferred
|
|
435
|
+
[ -n "$out" ] || return 0
|
|
436
|
+
if [ "${COORD_WATCH_SKIP_OTHERS_REPORTS:-}" = "1" ]; then
|
|
437
|
+
deferred=$(printf '%s\n' "$out" | jq -c 'select(.archive) | .comment') || return 1
|
|
438
|
+
if [ -n "$deferred" ]; then
|
|
439
|
+
mkdir -p "$HOME/.elanous/coord" || return 1
|
|
440
|
+
printf '%s\n' "$deferred" >> "$HOME/.elanous/coord/$SELF_ID-reports.jsonl" || return 1
|
|
441
|
+
fi
|
|
442
|
+
fi
|
|
443
|
+
if [ "${COORD_WATCH_SKIP_OTHERS_REPORTS:-}" = "1" ]; then
|
|
444
|
+
printf '%s\n' "$out" | jq -r 'select(.archive | not) | .line' || return 1
|
|
445
|
+
else
|
|
446
|
+
printf '%s\n' "$out" | jq -r '.line' || return 1
|
|
447
|
+
fi
|
|
448
|
+
}
|
|
449
|
+
|
|
421
450
|
fetch_comments() { # $1=since(ISO8601) → stdout=포맷된 신규 행 · rc=0 성공 / rc=1 두 경로 다 실패
|
|
422
451
|
local since="$1" out fmt
|
|
423
452
|
# 두 경로가 «같은 형태»를 내도록 정규화된 객체 하나만 본다: {id, created_at, login, body}
|
|
@@ -426,13 +455,30 @@ fetch_comments() { # $1=since(ISO8601) → stdout=포맷된 신규 행 · rc=0
|
|
|
426
455
|
# 그 글은 필터를 «통과»했고 창에도 떴다 — 그런데 다른 글 사이에 섞여 «요청»으로 안 보였다.
|
|
427
456
|
# 🔑 그러므로 결손은 「고르기」가 아니라 ***「고른 뒤 «구분»하지 않은 것」***이다.
|
|
428
457
|
# ⛔ 표지를 «본문 앞»에 둔다 — 뒤에 두면 BODY_CHARS 절단에 잘려 사라진다.
|
|
429
|
-
fmt
|
|
430
|
-
|
|
431
|
-
|
|
432
|
-
|
|
458
|
+
fmt=$(cat <<JQ
|
|
459
|
+
select(((.body | sub("^[[:space:]#]+"; "")) | (startswith("**[$SELF_ID]") or startswith("[$SELF_ID]") or startswith("**[$SELF_ALIAS]") or startswith("[$SELF_ALIAS]"))) | not)
|
|
460
|
+
| . as \$comment
|
|
461
|
+
| ((.body | split("\n")[0] | capture("^[[:space:]#]*[*][*][[][^]]+[]][*][*][^\n]*→[[:space:]]*(?<to>[^\n]+?)[[:space:]]*·[[:space:]]*(?<kind>요청|결정|사고|보고|정정)[[:space:]]*·")) // null) as \$envelope
|
|
462
|
+
| (if \$envelope == null then false else
|
|
463
|
+
(\$envelope.to | split("·") | map(gsub("^[[:space:]]+|[[:space:]]+$"; "")))
|
|
464
|
+
| any(.[]; . == "$SELF_ID" or . == "$SELF_ALIAS" or . == "전원")
|
|
465
|
+
end) as \$mine
|
|
466
|
+
| ((.body | test("$REQ_ADDR")) or ((.body | test("$REQ_MARK")) and (.body | test("부탁드립니다|부탁합니다")))) as \$legacy_request
|
|
467
|
+
| (\$envelope != null and \$envelope.kind == "보고" and (\$mine | not)) as \$archive
|
|
468
|
+
| {comment: \$comment, archive: \$archive,
|
|
469
|
+
line: ("[#$PR_NUM 신규 id=" + (.id|tostring) + " " + .created_at + " @" + .login + "]"
|
|
470
|
+
+ (if \$mine and \$envelope.kind == "결정" then " 🙋 나에게 «결정»"
|
|
471
|
+
elif \$mine and \$envelope.kind == "요청" then " 🙋 나에게 «요청»"
|
|
472
|
+
else "" end)
|
|
473
|
+
+ (if \$legacy_request then " 🙋‼️ 나에게 온 «요청»" else "" end)
|
|
474
|
+
+ (if \$envelope != null and (\$envelope.kind == "사고" or \$envelope.kind == "정정") then " 🚨"
|
|
475
|
+
elif \$archive then " 📄 보고" else "" end)
|
|
476
|
+
+ " " + (.body[:$BODY_CHARS] | gsub("\n"; " ⏎ ")))}
|
|
477
|
+
JQ
|
|
478
|
+
)
|
|
433
479
|
if out=$(gh api --paginate "repos/$REPO/issues/$PR_NUM/comments?since=$since" \
|
|
434
480
|
--jq ".[] | {id, created_at, login: .user.login, body} | $fmt" 2>/dev/null); then
|
|
435
|
-
|
|
481
|
+
emit_comments "$out"; return $?
|
|
436
482
|
fi
|
|
437
483
|
local owner="${REPO%%/*}" name="${REPO##*/}"
|
|
438
484
|
if out=$(gh api graphql -f query="query{repository(owner:\"$owner\",name:\"$name\"){pullRequest(number:$PR_NUM){comments(last:$COMMENT_FALLBACK_LAST){nodes{databaseId createdAt author{login} body}}}}}" \
|
|
@@ -443,7 +489,7 @@ fetch_comments() { # $1=since(ISO8601) → stdout=포맷된 신규 행 · rc=0
|
|
|
443
489
|
# ⭐ 폴백이 «쓰였다»는 사실만 남긴다 — 세는 것도 알릴지 정하는 것도 «부모 셸»이 한다.
|
|
444
490
|
# ⛔ 여기서 세면 서브셸과 함께 사라진다(위 머리말).
|
|
445
491
|
: > "$FALLBACK_FLAG" 2>/dev/null || true
|
|
446
|
-
|
|
492
|
+
emit_comments "$out"; return $?
|
|
447
493
|
fi
|
|
448
494
|
return 1
|
|
449
495
|
}
|