elanous 0.2.10 → 0.2.12
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/-6XrAoD3eU7NyMHAE4xPS/_buildManifest.js +1 -0
- package/apps/pwa/out/_next/static/chunks/1147-466ec15afacc1a65.js +1 -0
- package/apps/pwa/out/_next/static/chunks/1159-0c5ef8bc21cb6afb.js +1 -0
- package/apps/pwa/out/_next/static/chunks/1394-ee3795b112907122.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/2426.8c6ee0c668d53def.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-3cd46526879f454c.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/5532.6899a12958a89b72.js +1 -0
- package/apps/pwa/out/_next/static/chunks/{8067-87ce253ec2f23697.js → 5845-e6c003ce8d5fd36a.js} +1 -1
- package/apps/pwa/out/_next/static/chunks/5978-b27004c677119115.js +1 -0
- package/apps/pwa/out/_next/static/chunks/{8046cadf-211ca3c0e00f2b72.js → 5cd7e3a9-404fd6b8d0ecd44c.js} +1 -1
- package/apps/pwa/out/_next/static/chunks/6048-4c5c33579bc4ef78.js +1 -0
- package/apps/pwa/out/_next/static/chunks/6303-422dbf0f67c72aac.js +1 -0
- package/apps/pwa/out/_next/static/chunks/6751-bb3595948b2e311b.js +1 -0
- package/apps/pwa/out/_next/static/chunks/7274-19b7279f18b47ab3.js +1 -0
- package/apps/pwa/out/_next/static/chunks/7277-0b2fc7c16ba2d64b.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/7758-0b018a9e4fc56200.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-0259994816604c49.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/9920-5cfdc5e8fd209825.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-cb169620945d1952.js +1 -0
- package/apps/pwa/out/_next/static/chunks/app/autopilot/page-cefe8169e36cf62a.js +1 -0
- package/apps/pwa/out/_next/static/chunks/app/board/page-d2e35228bc497119.js +1 -0
- package/apps/pwa/out/_next/static/chunks/app/botlab/{page-54b32bd27726588d.js → page-5c05b0da4bc1392c.js} +1 -1
- package/apps/pwa/out/_next/static/chunks/app/bots/page-e0ccdb576812b523.js +1 -0
- package/apps/pwa/out/_next/static/chunks/app/chat/page-813c4a52c9d05ca8.js +1 -0
- package/apps/pwa/out/_next/static/chunks/app/consult/page-4731f2c215358937.js +1 -0
- package/apps/pwa/out/_next/static/chunks/app/control/page-a022b257950f39e6.js +1 -0
- package/apps/pwa/out/_next/static/chunks/app/design-check/page-a2ffc717e04b8b0a.js +1 -0
- package/apps/pwa/out/_next/static/chunks/app/editor/page-b59ee4e70fc18fcf.js +1 -0
- package/apps/pwa/out/_next/static/chunks/app/exec/page-a67e11ba962337b5.js +1 -0
- package/apps/pwa/out/_next/static/chunks/app/field/page-c172dabd796eb7a3.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-1efd0cb9e0ed9d13.js +1 -0
- package/apps/pwa/out/_next/static/chunks/app/intake/page-d5dc7ff69a37b4cf.js +1 -0
- package/apps/pwa/out/_next/static/chunks/app/layout-e71c84189e8c683e.js +1 -0
- package/apps/pwa/out/_next/static/chunks/app/live/page-1d6a533ce5a6efcb.js +1 -0
- package/apps/pwa/out/_next/static/chunks/app/market/page-dfca9b7d2de0b135.js +1 -0
- package/apps/pwa/out/_next/static/chunks/app/missions/[id]/page-793fa536b3a6ef37.js +1 -0
- package/apps/pwa/out/_next/static/chunks/app/morning/page-6dd3bfbbde2a5c2c.js +1 -0
- package/apps/pwa/out/_next/static/chunks/app/not-found-490653e8d4cc8852.js +1 -0
- package/apps/pwa/out/_next/static/chunks/app/observatory/page-77447356baad75d2.js +1 -0
- package/apps/pwa/out/_next/static/chunks/app/ops/checklist/page-29e961191f6057df.js +1 -0
- package/apps/pwa/out/_next/static/chunks/app/ops/release/page-c822f55b884d9104.js +1 -0
- package/apps/pwa/out/_next/static/chunks/app/ops/seats/page-fa4ccfc432424e52.js +1 -0
- package/apps/pwa/out/_next/static/chunks/app/outputs/page-6d604227e1664b71.js +1 -0
- package/apps/pwa/out/_next/static/chunks/app/page-9c7e8f744a765daf.js +1 -0
- package/apps/pwa/out/_next/static/chunks/app/reflection/page-4048543b4b7ad5e0.js +1 -0
- package/apps/pwa/out/_next/static/chunks/app/scheduler/page-4c3a3126abed551a.js +1 -0
- package/apps/pwa/out/_next/static/chunks/app/sessions/page-64b0aecb1ca75e75.js +1 -0
- package/apps/pwa/out/_next/static/chunks/app/settings/devices/page-4292d0149020e8a7.js +1 -0
- package/apps/pwa/out/_next/static/chunks/app/settings/page-db14d0be7f1c460c.js +1 -0
- package/apps/pwa/out/_next/static/chunks/app/setup/done/page-e5d8072cd7cfef73.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-9547b5cec7cf76bf.js +1 -0
- package/apps/pwa/out/_next/static/chunks/app/share/page-e6dcb83265530636.js +1 -0
- package/apps/pwa/out/_next/static/chunks/app/showroom/page-45248f08d6aecae5.js +1 -0
- package/apps/pwa/out/_next/static/chunks/app/tasks/page-2cddeb9e2aeedc55.js +1 -0
- package/apps/pwa/out/_next/static/chunks/app/term/page-e297866051595d81.js +1 -0
- package/apps/pwa/out/_next/static/chunks/app/today/page-baba2e047872fb0f.js +1 -0
- package/apps/pwa/out/_next/static/chunks/app/trace/page-e895da4ec9cac345.js +1 -0
- package/apps/pwa/out/_next/static/chunks/app/vault/page-4344faf20216233b.js +1 -0
- package/apps/pwa/out/_next/static/chunks/app/workflows/chat-ui/page-698bb29f11864b89.js +1 -0
- package/apps/pwa/out/_next/static/chunks/app/workflows/page-bd6a6dc1ddc273f2.js +1 -0
- package/apps/pwa/out/_next/static/chunks/app/workspace/page-2e9e2fb01c9da1c9.js +1 -0
- package/apps/pwa/out/_next/static/chunks/app/worktrees/page-d62ceb13411ebba4.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/128fb7fb670b2fbf.css +1 -0
- package/apps/pwa/out/approvals/index.html +1 -1
- package/apps/pwa/out/approvals/index.txt +23 -23
- package/apps/pwa/out/autopilot/index.html +1 -1
- package/apps/pwa/out/autopilot/index.txt +23 -23
- package/apps/pwa/out/board/index.html +1 -1
- package/apps/pwa/out/board/index.txt +23 -23
- package/apps/pwa/out/botlab/index.html +1 -1
- package/apps/pwa/out/botlab/index.txt +22 -22
- package/apps/pwa/out/bots/index.html +1 -1
- package/apps/pwa/out/bots/index.txt +22 -22
- package/apps/pwa/out/chat/index.html +1 -1
- package/apps/pwa/out/chat/index.txt +22 -22
- package/apps/pwa/out/consult/index.html +1 -1
- package/apps/pwa/out/consult/index.txt +23 -23
- package/apps/pwa/out/control/index.html +1 -1
- package/apps/pwa/out/control/index.txt +23 -23
- package/apps/pwa/out/design-check/index.html +1 -1
- package/apps/pwa/out/design-check/index.txt +23 -23
- package/apps/pwa/out/editor/index.html +1 -1
- package/apps/pwa/out/editor/index.txt +23 -23
- package/apps/pwa/out/exec/index.html +1 -1
- package/apps/pwa/out/exec/index.txt +23 -23
- package/apps/pwa/out/field/index.html +1 -1
- package/apps/pwa/out/field/index.txt +23 -23
- package/apps/pwa/out/healthz +1 -1
- package/apps/pwa/out/index.html +1 -1
- package/apps/pwa/out/index.txt +22 -22
- package/apps/pwa/out/inside/index.html +1 -0
- package/apps/pwa/out/inside/index.txt +31 -0
- package/apps/pwa/out/intake/index.html +1 -1
- package/apps/pwa/out/intake/index.txt +23 -23
- package/apps/pwa/out/live/index.html +1 -1
- package/apps/pwa/out/live/index.txt +23 -23
- package/apps/pwa/out/market/index.html +1 -1
- package/apps/pwa/out/market/index.txt +22 -22
- package/apps/pwa/out/missions/placeholder/index.html +1 -1
- package/apps/pwa/out/missions/placeholder/index.txt +22 -22
- package/apps/pwa/out/morning/index.html +1 -1
- package/apps/pwa/out/morning/index.txt +23 -23
- package/apps/pwa/out/observatory/index.html +1 -1
- package/apps/pwa/out/observatory/index.txt +23 -23
- package/apps/pwa/out/ops/checklist/index.html +1 -1
- package/apps/pwa/out/ops/checklist/index.txt +22 -22
- package/apps/pwa/out/ops/release/index.html +1 -1
- package/apps/pwa/out/ops/release/index.txt +22 -22
- package/apps/pwa/out/ops/seats/index.html +1 -1
- package/apps/pwa/out/ops/seats/index.txt +22 -22
- package/apps/pwa/out/outputs/index.html +1 -0
- package/apps/pwa/out/outputs/index.txt +30 -0
- package/apps/pwa/out/reflection/index.html +1 -1
- package/apps/pwa/out/reflection/index.txt +23 -23
- package/apps/pwa/out/scheduler/index.html +1 -1
- package/apps/pwa/out/scheduler/index.txt +23 -23
- package/apps/pwa/out/sessions/index.html +1 -1
- package/apps/pwa/out/sessions/index.txt +22 -22
- package/apps/pwa/out/settings/devices/index.html +1 -1
- package/apps/pwa/out/settings/devices/index.txt +23 -23
- package/apps/pwa/out/settings/index.html +1 -1
- package/apps/pwa/out/settings/index.txt +23 -23
- package/apps/pwa/out/setup/done/index.html +1 -1
- package/apps/pwa/out/setup/done/index.txt +23 -23
- package/apps/pwa/out/setup/index.html +1 -1
- package/apps/pwa/out/setup/index.txt +23 -23
- package/apps/pwa/out/share/index.html +1 -1
- package/apps/pwa/out/share/index.txt +23 -23
- package/apps/pwa/out/showroom/index.html +1 -1
- package/apps/pwa/out/showroom/index.txt +22 -22
- package/apps/pwa/out/tasks/index.html +1 -1
- package/apps/pwa/out/tasks/index.txt +23 -23
- package/apps/pwa/out/term/index.html +1 -1
- package/apps/pwa/out/term/index.txt +23 -24
- package/apps/pwa/out/today/index.html +1 -1
- package/apps/pwa/out/today/index.txt +23 -23
- package/apps/pwa/out/trace/index.html +1 -1
- package/apps/pwa/out/trace/index.txt +23 -23
- package/apps/pwa/out/vault/index.html +1 -1
- package/apps/pwa/out/vault/index.txt +23 -23
- package/apps/pwa/out/workflows/chat-ui/index.html +1 -1
- package/apps/pwa/out/workflows/chat-ui/index.txt +23 -23
- package/apps/pwa/out/workflows/index.html +1 -1
- package/apps/pwa/out/workflows/index.txt +23 -23
- package/apps/pwa/out/workspace/index.html +1 -1
- package/apps/pwa/out/workspace/index.txt +23 -24
- package/apps/pwa/out/worktrees/index.html +1 -1
- package/apps/pwa/out/worktrees/index.txt +23 -23
- package/graphs/context/nightly-condense.yaml +21 -0
- package/graphs/context/recipes.yaml +12 -0
- package/graphs/demo/inside-seed.yaml +20 -0
- package/graphs/demo/recipes.yaml +12 -0
- package/graphs/drafts/draft-cleanup.yaml +19 -0
- package/graphs/drafts/recipes.yaml +23 -0
- package/graphs/intake/intake-daily.yaml +2 -1
- package/graphs/ops/recipes.yaml +3 -0
- package/graphs/ops/secret-exposure.yaml +24 -0
- package/graphs/release/recipes.yaml +3 -0
- package/graphs/release/release-loop.yaml +4 -1
- package/graphs/video/explainer-line.yaml +2 -2
- package/package.json +2 -1
- package/plugins/card-followup/examples/sample-card.png +0 -0
- package/plugins/elanous-hwp/README.md +25 -0
- package/plugins/elanous-hwp/cli.ts +22 -0
- package/plugins/elanous-hwp/converter.ts +237 -0
- package/plugins/elanous-hwp/fixtures/fixed-controls.hwpx +0 -0
- package/plugins/elanous-hwp/fixtures/fixed-table-controls.hwpx +0 -0
- package/plugins/elanous-hwp/fixtures/fixed.hwpx +0 -0
- package/plugins/elanous-hwp/plugin.json +16 -0
- package/plugins/elanous-hwp/plugin.ts +40 -0
- package/scripts/ci-public-export-leak-gate.ts +75 -14
- package/scripts/ci-public-leak-gate.ts +44 -9
- package/scripts/context-hooks/claude-stop.sh +4 -0
- package/scripts/context-hooks/emit.ts +24 -0
- package/scripts/context-hooks/post-tool-use.sh +4 -0
- package/scripts/coord-channel-watch.sh +12 -0
- package/scripts/coord-requests-bridge.ts +143 -0
- package/scripts/field-feed/lib.ts +4 -0
- package/scripts/fleet/node-setup.sh +20 -3
- package/scripts/homebrew-formula-bump.ts +69 -0
- package/scripts/lib/telegram-inject-args.ts +31 -0
- package/scripts/marketing/measure-site-numbers.ts +169 -0
- package/scripts/measure-gate-shards.ts +309 -0
- package/scripts/measure-pod-memory-by-goal.ts +130 -0
- package/scripts/mission-request-judge.ts +31 -1
- package/scripts/morning-report.ts +2 -2
- package/scripts/opportunity-scan.ts +1 -1
- package/scripts/release-loop/auto-approve-node.ts +21 -4
- package/scripts/release-loop/checklist-gate-node.ts +2 -1
- package/scripts/release-loop/cut-branch.ts +84 -0
- package/scripts/release-loop/gate-node.ts +22 -15
- 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 +47 -6
- package/scripts/release-loop/publish-node.ts +4 -1
- 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 +74 -13
- package/scripts/signal-digest-cycle.ts +2 -7
- package/scripts/signal-digest-photo.ts +11 -0
- package/scripts/tech1-public-measure.ts +94 -0
- package/scripts/telegram-inject.ts +14 -6
- package/scripts/test-diet/node.ts +1 -1
- package/scripts/test-diet/remeasure-list.ts +112 -0
- package/scripts/tui-regress.ts +2 -2
- package/scripts/ux/demo-rehearsal.ts +247 -0
- package/scripts/ux/demo-seed.ts +108 -0
- package/scripts/ux/lib/rehearsal-verdict.ts +80 -0
- package/skills/diagram-master/SKILL.md +366 -0
- package/skills/diagram-master/references/engines/excalidraw/color-palette.md +67 -0
- package/skills/diagram-master/references/engines/excalidraw/element-templates.md +182 -0
- package/skills/diagram-master/references/engines/excalidraw/json-schema.md +71 -0
- package/skills/diagram-master/references/engines/excalidraw/render_excalidraw.py +189 -0
- package/skills/diagram-master/references/engines/excalidraw/render_template.html +57 -0
- package/skills/diagram-master/references/engines/matplotlib/matplotlib-patterns.md +235 -0
- package/skills/diagram-master/references/engines/matplotlib/render_matplotlib.py +184 -0
- package/skills/diagram-master/references/engines/mermaid/domain-templates.md +435 -0
- package/skills/diagram-master/references/engines/mermaid/render_mermaid.py +116 -0
- package/skills/diagram-master/references/engines/mermaid/syntax-reference.md +2247 -0
- package/skills/diagram-master/references/engines/nanobannana/render_nanobannana2.py +168 -0
- package/skills/diagram-master/references/engines/svg/color-palette.md +188 -0
- package/skills/diagram-master/references/engines/svg/html-base-template.html +332 -0
- package/skills/diagram-master/references/engines/svg/interactivity-patterns.md +435 -0
- package/skills/diagram-master/references/engines/svg/render_interactive_svg.py +212 -0
- package/skills/diagram-master/references/engines/svg/svg-element-templates.md +349 -0
- package/skills/diagram-master/references/examples/README.md +69 -0
- package/skills/diagram-master/references/examples/ref_grid_architecture.png +0 -0
- package/skills/diagram-master/references/examples/ref_layered_flow.png +0 -0
- package/skills/diagram-master/references/pyproject.toml +16 -0
- package/skills/diagram-master/references/quality-checklist.md +33 -0
- package/skills/diagram-master/references/routing-guide.md +164 -0
- package/skills/diagram-master/references/uv.lock +1356 -0
- package/skills/google-workspace/SKILL.md +33 -0
- package/skills/google-workspace/scripts/gws-safe.sh +177 -0
- package/skills/grill-me/SKILL.md +1 -1
- package/skills/lecture-note-digitizer/SKILL.md +926 -0
- package/skills/lecture-note-digitizer/references/convert_to_pdf.py +30 -0
- package/skills/lecture-note-digitizer/references/extract_slide_diagram.py +73 -0
- package/skills/lecture-note-digitizer/references/html-template.md +167 -0
- package/skills/lecture-note-digitizer/references/katex-style-guide.md +165 -0
- package/skills/omni-crawl/SKILL.md +21 -11
- package/skills/omni-crawl/scripts/main.ts +6 -6
- package/skills/omni-crawl/src/router.ts +3 -3
- package/skills/omni-digest/SKILL.md +17 -9
- package/skills/omni-digest/digest.md +2 -2
- package/skills/omni-digest/src/fetch.ts +30 -3
- package/skills/pitch-deck/SKILL.md +2 -2
- package/skills/pitch-deck/template.html +2 -2
- package/skills/youtube-master/SKILL.md +163 -0
- package/skills/youtube-master/package-lock.json +558 -0
- package/skills/youtube-master/package.json +13 -0
- package/skills/youtube-master/references/study-note-template.md +124 -0
- package/skills/youtube-master/scripts/main.ts +435 -0
- package/skills/youtube-master/scripts/transcribe-local.ts +24 -0
- package/skills/youtube-master/src/audio.ts +63 -0
- package/skills/youtube-master/src/domain-staging.ts +50 -0
- package/skills/youtube-master/src/env.ts +36 -0
- package/skills/youtube-master/src/obsidian.ts +155 -0
- package/skills/youtube-master/src/router.ts +110 -0
- package/skills/youtube-master/src/stt.ts +199 -0
- package/skills/youtube-master/src/study-note.ts +175 -0
- package/skills/youtube-master/src/summarize.ts +358 -0
- package/skills/youtube-master/src/transcript.ts +76 -0
- package/skills/youtube-master/src/types.ts +91 -0
- package/skills/youtube-master/src/util.ts +93 -0
- package/skills/youtube-master/src/youtube.ts +70 -0
- package/skills/youtube-master/tsconfig.json +13 -0
- package/src/acp/server.ts +5 -2
- package/src/agent-mission/driver.ts +215 -23
- package/src/agent-mission/pty-decision.ts +71 -0
- package/src/agent-mission/review-loop.ts +30 -0
- package/src/autopilot/build/llm-conflict-merge.ts +16 -3
- package/src/autopilot/pty-control-loop.ts +4 -1
- package/src/autopilot/tool-registry.ts +2 -0
- package/src/boot/daemon-prompt-turn.ts +5 -0
- package/src/boot/daemon-runtime.ts +9 -3
- package/src/boot/daemon-tools/web-search.ts +3 -0
- package/src/card-followup/core.ts +109 -0
- package/src/chat/index.ts +2 -0
- package/src/cli/drive-input-jail.ts +101 -0
- package/src/cli/hooks-cli.ts +17 -3
- package/src/cli/make-cli.ts +43 -0
- package/src/cli/persona-cli.ts +98 -9
- package/src/cli/plugin-cli.ts +31 -22
- package/src/cli/pod-cli.ts +36 -9
- package/src/cli/pod-memory-advice.ts +35 -0
- package/src/cli/pr-cli.ts +51 -15
- package/src/cli/pty-drive-cli.ts +41 -7
- package/src/cli/pty-drive-verdict.ts +40 -0
- package/src/cli/release-cli.ts +63 -10
- package/src/cli/setup-cli.ts +43 -1
- package/src/cli/skills-cli.ts +17 -1
- package/src/context-bus/claude-hooks-install.ts +10 -0
- package/src/context-bus/context-now-surfaces.ts +65 -0
- package/src/context-bus/context-now.ts +104 -0
- package/src/context-bus/coord-events.ts +2 -2
- package/src/context-bus/external-events.ts +52 -0
- package/src/context-bus/long-term-memory.ts +108 -0
- package/src/context-bus/nightly-condense.ts +153 -0
- package/src/context-bus/session-events.ts +35 -0
- package/src/dashboard/dashboard-status-lines.ts +2 -0
- package/src/dashboard/index.ts +17 -4
- package/src/dashboard/slash-runtime/dashboard-handlers.ts +31 -1
- package/src/decisions/decision-cards.ts +10 -3
- package/src/decisions/decision-ledger.ts +13 -5
- package/src/discord/sprint21-runtime.ts +5 -1
- package/src/discord-self-message.ts +32 -0
- package/src/discord-slash-wire.ts +5 -1
- package/src/discord.ts +17 -1
- package/src/domains/core-tools.ts +3 -2
- package/src/domains/outbound-alert.ts +105 -32
- package/src/domains/outbound-log-probe.ts +8 -0
- package/src/domains/telegram-kind-route.ts +51 -13
- package/src/exec-requests/default-outputs.ts +25 -0
- package/src/exec-requests/planner.ts +10 -2
- package/src/exec-requests/runner.ts +20 -6
- package/src/exec-requests/store.ts +3 -0
- package/src/execution-loop/launch-gate.ts +109 -0
- package/src/field/field-reel.ts +5 -1
- package/src/field-note/index.ts +201 -0
- package/src/field-note/telegram.ts +142 -0
- package/src/field-note/transcribe.ts +248 -0
- package/src/graph-kinds/registry.ts +3 -3
- package/src/graph-runner/graph-cli.ts +61 -1
- package/src/graph-runner/graph-grow-llm.ts +47 -0
- package/src/graph-runner/graph-grow.ts +50 -0
- package/src/graph-runner/runner.ts +329 -33
- package/src/grok/agent-search.ts +8 -2
- package/src/guardian/secret-exposure-scan.ts +101 -0
- package/src/harness/harness-cli-command.ts +375 -13
- package/src/harness/harness-pod-dispatch.ts +43 -23
- package/src/harness/harness-seams.ts +38 -4
- package/src/harness/harness-stop.ts +23 -4
- package/src/harness/launch-registry.ts +91 -0
- package/src/harness/process-garbage.ts +5 -3
- package/src/hooks/consult-intake.ts +153 -0
- 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 +94 -16
- package/src/index.ts +76 -14
- package/src/intake-plane/categorize.ts +18 -46
- package/src/intake-plane/discord-seat-work.ts +38 -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/telegram-seat-work.ts +36 -2
- package/src/intake-plane/wish-card.ts +33 -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/feature-maturity.ts +27 -4
- package/src/model-tier/index.ts +2 -2
- package/src/model-tier/tier-resolver.ts +20 -20
- package/src/model-tier/types.ts +6 -6
- package/src/mss/logging/log-store.ts +15 -0
- package/src/nexus/api/config-model-tier.ts +5 -4
- package/src/nexus/api/fabric-plans.ts +53 -0
- package/src/nexus/api/harness-api.ts +5 -1
- package/src/nexus/api/health.ts +2 -0
- package/src/nexus/api/http-server.ts +67 -8
- package/src/nexus/api/inside-events.ts +226 -0
- package/src/nexus/api/meta-api.ts +21 -8
- package/src/nexus/api/missions.ts +6 -1
- package/src/nexus/api/ops-seats.ts +33 -0
- package/src/nexus/api/outbound-report.ts +40 -7
- package/src/nexus/api/outputs-route.ts +44 -0
- package/src/nexus/api/personas.ts +95 -53
- package/src/nexus/api/seat-requests.ts +44 -2
- package/src/nexus/api/sessions-store.ts +17 -38
- package/src/nexus/api/sub-seat-charters.ts +34 -0
- package/src/nexus/api/tabs-mutations.ts +3 -1
- package/src/nexus/api/task-cards-api.ts +19 -0
- package/src/nexus/api/trace.ts +18 -6
- package/src/nexus/api/workflow-history.ts +88 -0
- package/src/nexus/api/workflow-run-event-bridge.ts +1 -0
- package/src/nexus/api/workflows.ts +132 -6
- package/src/nexus/index.ts +2 -0
- package/src/nexus/kinds/webterm.ts +2 -1
- package/src/nexus/outbound/delivery-ledger.ts +17 -8
- package/src/nexus/outbound/router.ts +8 -3
- package/src/nexus/webterm/pty.ts +6 -2
- package/src/onboarding/cli-auth-status.ts +80 -0
- package/src/onboarding/voice-ai.ts +3 -3
- package/src/org/seat-budget.ts +48 -0
- package/src/org/stall-escalation.ts +63 -0
- package/src/outputs/ledger.ts +120 -0
- package/src/persona/persona-todo.ts +79 -0
- package/src/persona/presets.ts +123 -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 +110 -0
- package/src/plugins/maker/plugin-maker.ts +254 -11
- package/src/plugins/maker/wizard-generate.ts +103 -0
- package/src/pod-lease/admission.ts +150 -0
- package/src/pod-lease/dependency-state.ts +85 -0
- package/src/pod-lease/host-lease.ts +127 -0
- package/src/project/project-suggestion.ts +16 -0
- package/src/project/session-context.ts +24 -0
- package/src/release-loop/checklist.ts +17 -5
- package/src/release-loop/feature-store.ts +29 -13
- package/src/release-loop/landed-but-yellow.ts +48 -0
- package/src/release-loop/next-md-merge.ts +58 -0
- package/src/release-loop/release-note.ts +59 -4
- package/src/seat-dispatch/seat-ask.ts +130 -0
- package/src/seat-dispatch/seat-questions.ts +100 -0
- package/src/seat-loop/seat-loop.ts +709 -29
- package/src/seat-loop/seat-report.ts +37 -2
- package/src/self-dev/dev-cli.ts +4 -1
- package/src/self-dev/dev-pipeline.ts +37 -1
- package/src/self-dev/draft-sweep.ts +79 -40
- package/src/self-dev/draft-triage-rules.ts +62 -7
- package/src/self-dev/fabric-plan-core.ts +297 -0
- package/src/self-dev/orchestrate.ts +36 -4
- package/src/self-dev/release-path-guard.ts +62 -0
- package/src/self-dev/shard-aggregate.ts +230 -0
- package/src/self-dev/shard-placement.ts +60 -0
- package/src/self-dev/shard-plan.ts +48 -0
- package/src/self-dev/shard-pod-run.ts +77 -0
- package/src/self-dev/shard-run.ts +105 -0
- package/src/self-implement/budget-gate.ts +29 -12
- package/src/self-implement/gate-baseline.ts +1 -1
- package/src/self-implement/gate-candidate-ranking.ts +60 -0
- package/src/self-implement/gate-cli.ts +40 -1
- package/src/self-implement/gate-scope.ts +44 -13
- 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 +27 -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 +257 -9
- package/src/self-implement/route-consumer-test-index.ts +122 -0
- package/src/self-implement/seams.ts +72 -11
- package/src/self-implement/test-seams.ts +2 -0
- package/src/self-implement/uncommitted-work.ts +59 -0
- package/src/session/index.ts +36 -13
- package/src/skills/gift-install.ts +215 -0
- package/src/skills/tools/web-search.ts +4 -1
- package/src/steward/launch.ts +42 -26
- package/src/steward/steward-cards.ts +17 -9
- package/src/steward/triage.ts +46 -14
- package/src/task-cards/card-cli.ts +25 -1
- package/src/task-orchestrator/mission.ts +5 -0
- package/src/task-orchestrator/store.ts +12 -3
- package/src/task-orchestrator/surfaces/pod-command-job.ts +43 -17
- package/src/task-orchestrator/surfaces/pod-lease.ts +156 -19
- package/src/task-orchestrator/surfaces/pod-pool.ts +127 -26
- package/src/task-orchestrator/surfaces/self-implement-pod.ts +222 -40
- package/src/task-orchestrator/surfaces/self-implement.ts +15 -2
- package/src/task-orchestrator/types.ts +2 -0
- package/src/telegram-card-followup.ts +16 -96
- package/src/telegram-commands.ts +31 -1
- package/src/telegram-project-command.ts +145 -0
- package/src/telegram-report.ts +21 -17
- package/src/telegram.ts +61 -8
- package/src/tool-runtime/self-cognition-runtimes.ts +13 -3
- package/src/user-config.ts +110 -24
- package/src/version/packed-revision.json +1 -1
- package/src/web-search/grok.ts +7 -1
- package/src/web-search/index.ts +28 -1
- package/src/web-search/provider.ts +4 -0
- package/src/web-search/x-intent.ts +5 -0
- package/src/workflow-runtime/executor.ts +277 -47
- package/src/workflow-runtime/index.ts +1 -0
- package/src/workflow-runtime/nodes/subworkflow.ts +60 -0
- package/src/workflow-runtime/plugin-kind-node.ts +1 -1
- package/src/workflow-runtime/schema.ts +79 -4
- package/src/workflow-runtime/types.ts +35 -4
- package/apps/pwa/out/_next/static/2DsiDfDCks44g1cPUMhiW/_buildManifest.js +0 -1
- package/apps/pwa/out/_next/static/chunks/1105-c473ed46272fba79.js +0 -1
- package/apps/pwa/out/_next/static/chunks/1377-1efeffbbac0963ff.js +0 -1
- package/apps/pwa/out/_next/static/chunks/1470.98a6ab61ccb4131c.js +0 -1
- package/apps/pwa/out/_next/static/chunks/216-5acd01cbde4acda7.js +0 -1
- package/apps/pwa/out/_next/static/chunks/2330-c2f07246c8788af1.js +0 -1
- package/apps/pwa/out/_next/static/chunks/2375-cb6debea56cce4fb.js +0 -1
- package/apps/pwa/out/_next/static/chunks/24-e6d28380efab7faf.js +0 -1
- package/apps/pwa/out/_next/static/chunks/2977-e38442e86289f1d3.js +0 -1
- package/apps/pwa/out/_next/static/chunks/2982-2a2df543be3d2e5a.js +0 -25
- package/apps/pwa/out/_next/static/chunks/3403.4bc97b4066945a94.js +0 -5
- package/apps/pwa/out/_next/static/chunks/3615-740dd270764ffa24.js +0 -1
- package/apps/pwa/out/_next/static/chunks/371-4ad6af55dad02ced.js +0 -1
- package/apps/pwa/out/_next/static/chunks/3734-1015fe991eb9b7e7.js +0 -1
- package/apps/pwa/out/_next/static/chunks/4114-3e63117452378807.js +0 -1
- package/apps/pwa/out/_next/static/chunks/5012-a7fe6f3c8b6fe45a.js +0 -1
- package/apps/pwa/out/_next/static/chunks/5609-012bb3557211f07e.js +0 -1
- package/apps/pwa/out/_next/static/chunks/5783-ef40ebfc91d55230.js +0 -1
- package/apps/pwa/out/_next/static/chunks/5791-bb82743fa6299562.js +0 -1
- package/apps/pwa/out/_next/static/chunks/62-ff227c3edb8b248b.js +0 -1
- package/apps/pwa/out/_next/static/chunks/6320-baac91d68843a9a6.js +0 -1
- package/apps/pwa/out/_next/static/chunks/6725-68ab7cc0b1faf00d.js +0 -1
- package/apps/pwa/out/_next/static/chunks/6998-a654fe5c58271600.js +0 -1
- package/apps/pwa/out/_next/static/chunks/7633-1b3709b0854c9412.js +0 -1
- package/apps/pwa/out/_next/static/chunks/7647.2fcd30d894d5ee30.js +0 -1
- package/apps/pwa/out/_next/static/chunks/7673-2eda1507d38dadb8.js +0 -1
- package/apps/pwa/out/_next/static/chunks/7951-8b03dbb10b24cd06.js +0 -1
- package/apps/pwa/out/_next/static/chunks/7990-e12efba616f46e03.js +0 -1
- package/apps/pwa/out/_next/static/chunks/8142-744998d65d7bb17e.js +0 -1
- package/apps/pwa/out/_next/static/chunks/8195-6fde3d7a39859206.js +0 -10
- package/apps/pwa/out/_next/static/chunks/8619-4365e03a2862830f.js +0 -1
- package/apps/pwa/out/_next/static/chunks/8894-b5fb36bab837cd29.js +0 -1
- package/apps/pwa/out/_next/static/chunks/920-f7dceb78f1c585ef.js +0 -1
- package/apps/pwa/out/_next/static/chunks/9454-84d0d5d77446bd92.js +0 -1
- package/apps/pwa/out/_next/static/chunks/9651-3cd291a6fa1370d2.js +0 -1
- package/apps/pwa/out/_next/static/chunks/988-5f92e7ab7ccea3dd.js +0 -1
- package/apps/pwa/out/_next/static/chunks/9989-5582582f06429840.js +0 -1
- package/apps/pwa/out/_next/static/chunks/ae787e4c-f2998de7f1ba72a4.js +0 -1
- package/apps/pwa/out/_next/static/chunks/app/_not-found/page-859cea1570b6227a.js +0 -1
- package/apps/pwa/out/_next/static/chunks/app/approvals/page-d2253d7e58ef1890.js +0 -1
- package/apps/pwa/out/_next/static/chunks/app/autopilot/page-5441d4a9ab35e518.js +0 -1
- package/apps/pwa/out/_next/static/chunks/app/board/page-d9b12d680922d980.js +0 -1
- package/apps/pwa/out/_next/static/chunks/app/bots/page-e268d6d145827a22.js +0 -1
- package/apps/pwa/out/_next/static/chunks/app/chat/page-f8116559c7424da7.js +0 -1
- package/apps/pwa/out/_next/static/chunks/app/consult/page-1085399fd0f32112.js +0 -1
- package/apps/pwa/out/_next/static/chunks/app/control/page-1df686a14f65895a.js +0 -1
- package/apps/pwa/out/_next/static/chunks/app/design-check/page-54e1f966ab60a4dc.js +0 -1
- package/apps/pwa/out/_next/static/chunks/app/editor/page-7ed95f296f5ee8e9.js +0 -1
- package/apps/pwa/out/_next/static/chunks/app/exec/page-11edac668d77e5c3.js +0 -1
- package/apps/pwa/out/_next/static/chunks/app/field/page-59e2b9a22cd5a6d5.js +0 -1
- package/apps/pwa/out/_next/static/chunks/app/healthz/route-859cea1570b6227a.js +0 -1
- package/apps/pwa/out/_next/static/chunks/app/intake/page-2976df21ad74ab48.js +0 -1
- package/apps/pwa/out/_next/static/chunks/app/layout-34d211a67f16d510.js +0 -1
- package/apps/pwa/out/_next/static/chunks/app/live/page-8ff652d5d950639b.js +0 -1
- package/apps/pwa/out/_next/static/chunks/app/market/page-b31610deda76337b.js +0 -1
- package/apps/pwa/out/_next/static/chunks/app/missions/[id]/page-6cb0e1bbefe5fb3d.js +0 -1
- package/apps/pwa/out/_next/static/chunks/app/morning/page-a286a152cf584576.js +0 -1
- package/apps/pwa/out/_next/static/chunks/app/not-found-d9237581e7003bcb.js +0 -1
- package/apps/pwa/out/_next/static/chunks/app/observatory/page-83274e761643fdd2.js +0 -1
- package/apps/pwa/out/_next/static/chunks/app/ops/checklist/page-ceee6cfb1d4e6d68.js +0 -1
- package/apps/pwa/out/_next/static/chunks/app/ops/release/page-9c9f8bb3e4a64091.js +0 -1
- package/apps/pwa/out/_next/static/chunks/app/ops/seats/page-c17217603ea3426a.js +0 -1
- package/apps/pwa/out/_next/static/chunks/app/page-efb6177cbf1e8a51.js +0 -1
- package/apps/pwa/out/_next/static/chunks/app/reflection/page-d307523703bc4df3.js +0 -1
- package/apps/pwa/out/_next/static/chunks/app/scheduler/page-462f4e4bab45ce7d.js +0 -1
- package/apps/pwa/out/_next/static/chunks/app/sessions/page-8990e96f33af3837.js +0 -1
- package/apps/pwa/out/_next/static/chunks/app/settings/devices/page-e168fa1030af0548.js +0 -1
- package/apps/pwa/out/_next/static/chunks/app/settings/page-1233e05a4068bc9c.js +0 -1
- package/apps/pwa/out/_next/static/chunks/app/setup/done/page-13a1840b1fac337a.js +0 -1
- package/apps/pwa/out/_next/static/chunks/app/setup/layout-859cea1570b6227a.js +0 -1
- package/apps/pwa/out/_next/static/chunks/app/setup/page-64a29fc80b11ab55.js +0 -1
- package/apps/pwa/out/_next/static/chunks/app/share/page-68e787339a16b3dc.js +0 -1
- package/apps/pwa/out/_next/static/chunks/app/showroom/page-4fddc90b23feb215.js +0 -1
- package/apps/pwa/out/_next/static/chunks/app/tasks/page-886ba8260dc79c79.js +0 -1
- package/apps/pwa/out/_next/static/chunks/app/term/page-0f26507a1722e40b.js +0 -1
- package/apps/pwa/out/_next/static/chunks/app/today/page-109d4ccd42259c9d.js +0 -1
- package/apps/pwa/out/_next/static/chunks/app/trace/page-f5c2a4e510726774.js +0 -1
- package/apps/pwa/out/_next/static/chunks/app/vault/page-b2e0039416f42522.js +0 -1
- package/apps/pwa/out/_next/static/chunks/app/workflows/chat-ui/page-26102fd7350f171e.js +0 -1
- package/apps/pwa/out/_next/static/chunks/app/workflows/page-708948bc8a802794.js +0 -1
- package/apps/pwa/out/_next/static/chunks/app/workspace/page-5e5611620f78fb0b.js +0 -1
- package/apps/pwa/out/_next/static/chunks/app/worktrees/page-139ba5c367bbf60a.js +0 -1
- package/apps/pwa/out/_next/static/chunks/framework-ea806bb57f2b8923.js +0 -1
- package/apps/pwa/out/_next/static/chunks/main-8d2302399c2c8f87.js +0 -1
- package/apps/pwa/out/_next/static/chunks/main-app-202b4e81f33895ea.js +0 -1
- package/apps/pwa/out/_next/static/chunks/pages/_app-b10928c60f0b8488.js +0 -1
- package/apps/pwa/out/_next/static/chunks/pages/_error-689039227d443fab.js +0 -1
- package/apps/pwa/out/_next/static/chunks/webpack-e5bea36f183b25e6.js +0 -1
- package/apps/pwa/out/_next/static/css/43feca5fd387dcbd.css +0 -1
- /package/apps/pwa/out/_next/static/{2DsiDfDCks44g1cPUMhiW → -6XrAoD3eU7NyMHAE4xPS}/_ssgManifest.js +0 -0
package/src/cli/persona-cli.ts
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
//
|
|
1
|
+
// `elanous persona list|add|edit|show`: 프리셋을 보고, 내 페르소나를 만들고 꾸민다.
|
|
2
2
|
// 만든 페르소나는 기존 페르소나 저장소(resolveStatePersonaDir · Discord·PWA 가 읽는 곳)의 `<id>.yaml` 한 파일이다.
|
|
3
3
|
import type { Command } from 'commander';
|
|
4
4
|
import { existsSync, mkdirSync, readdirSync, readFileSync, writeFileSync } from 'node:fs';
|
|
@@ -7,7 +7,8 @@ import { parse as parseYaml } from 'yaml';
|
|
|
7
7
|
import { debug } from '../debug/log.js';
|
|
8
8
|
import { parsePersonaYaml } from '../persona/loader.js';
|
|
9
9
|
import { resolveRepositoryPersonaDir, resolveStatePersonaDir } from '../persona/global-registry.js';
|
|
10
|
-
import { choosePersonaId, describePreset, findPreset, loadPresetIndex, loadPresets, presetToProfileYaml } from '../persona/presets.js';
|
|
10
|
+
import { UnknownPersonaSchemaKeyError, choosePersonaId, clonePreset, describePreset, editPersona, findPreset, loadPresetIndex, loadPresets, presetToProfileYaml } from '../persona/presets.js';
|
|
11
|
+
import { addTeamSet, listTeamSets, removeTeamSet } from '../persona/team-set.js';
|
|
11
12
|
|
|
12
13
|
interface StoredPersona { personaId: string; displayName: string; description?: string; preset?: string; title?: string; path: string }
|
|
13
14
|
|
|
@@ -36,8 +37,52 @@ function takenIds(stateDir: string): Set<string> {
|
|
|
36
37
|
return ids;
|
|
37
38
|
}
|
|
38
39
|
|
|
40
|
+
function mapping(value: unknown): value is Record<string, unknown> {
|
|
41
|
+
return value !== null && typeof value === 'object' && !Array.isArray(value);
|
|
42
|
+
}
|
|
43
|
+
|
|
44
|
+
function setEdit(edits: Record<string, unknown>, assignment: string): void {
|
|
45
|
+
const equals = assignment.indexOf('=');
|
|
46
|
+
if (equals < 0) throw new Error(`--set requires key=value: ${assignment}`);
|
|
47
|
+
const key = assignment.slice(0, equals);
|
|
48
|
+
const parts = key.split('.');
|
|
49
|
+
if (parts.some((part) => !part || ['__proto__', 'prototype', 'constructor'].includes(part))) {
|
|
50
|
+
throw new UnknownPersonaSchemaKeyError(key);
|
|
51
|
+
}
|
|
52
|
+
const value: unknown = parseYaml(assignment.slice(equals + 1));
|
|
53
|
+
let target = edits;
|
|
54
|
+
for (const part of parts.slice(0, -1)) {
|
|
55
|
+
if (!Object.hasOwn(target, part)) target[part] = {};
|
|
56
|
+
if (!mapping(target[part])) throw new Error(`--set key conflicts with a scalar: ${key}`);
|
|
57
|
+
target = target[part];
|
|
58
|
+
}
|
|
59
|
+
target[parts.at(-1)!] = value;
|
|
60
|
+
}
|
|
61
|
+
|
|
62
|
+
function editOptions(fromFile: string | undefined, assignments: readonly string[]): Record<string, unknown> {
|
|
63
|
+
const parsed: unknown = fromFile ? parseYaml(readFileSync(fromFile, 'utf8')) : {};
|
|
64
|
+
if (!mapping(parsed)) throw new Error('--from-file must contain a YAML mapping');
|
|
65
|
+
const edits = { ...parsed };
|
|
66
|
+
for (const assignment of assignments) setEdit(edits, assignment);
|
|
67
|
+
return edits;
|
|
68
|
+
}
|
|
69
|
+
|
|
39
70
|
export function registerPersonaCommands(program: Command): void {
|
|
40
|
-
const
|
|
71
|
+
const team = program.command('team-set').description('Install, remove and list persona team sets');
|
|
72
|
+
team.command('add <file>').description('Install a YAML team set').action((file: string) => {
|
|
73
|
+
try { const result = addTeamSet(file); console.log(`Installed team-set ${result['team-set']}`); }
|
|
74
|
+
catch (error) { console.error(error instanceof Error ? error.message : String(error)); process.exitCode = 1; }
|
|
75
|
+
});
|
|
76
|
+
team.command('remove <name>').description('Remove an installed team set').action((name: string) => {
|
|
77
|
+
try { removeTeamSet(name); console.log(`Removed team-set ${name}`); }
|
|
78
|
+
catch (error) { console.error(error instanceof Error ? error.message : String(error)); process.exitCode = 1; }
|
|
79
|
+
});
|
|
80
|
+
team.command('list').description('List installed team sets').action(() => {
|
|
81
|
+
try { for (const item of listTeamSets()) console.log(`${item['team-set']} ${item.members.map((member) => `${member.persona} (${member.title})`).join(', ')}`); }
|
|
82
|
+
catch (error) { console.error(error instanceof Error ? error.message : String(error)); process.exitCode = 1; }
|
|
83
|
+
});
|
|
84
|
+
|
|
85
|
+
const persona = program.command('persona').description('Persona presets — AI coworkers you pick and customise (list · add · edit · show)');
|
|
41
86
|
|
|
42
87
|
persona.command('list')
|
|
43
88
|
.description('List the persona presets, then the personas you have made')
|
|
@@ -49,7 +94,7 @@ export function registerPersonaCommands(program: Command): void {
|
|
|
49
94
|
if (opts.json) { console.log(JSON.stringify({ presets: presets.map((p) => ({ id: p.personaId, displayName: p.displayName, role: p.role, oneLine: p.oneLine })), mine }, null, 2)); return; }
|
|
50
95
|
if (!presets.length) console.log('페르소나 프리셋을 찾지 못했습니다(persona-presets/ 가 이 설치본에 없습니다).');
|
|
51
96
|
else {
|
|
52
|
-
console.log('프리셋 — 골라서 내 페르소나로 만들기: elanous persona add
|
|
97
|
+
console.log('프리셋 — 골라서 내 페르소나로 만들기: elanous persona add <이름> [--from <프리셋>]');
|
|
53
98
|
const width = Math.max(...presets.map((p) => p.personaId.length));
|
|
54
99
|
for (const p of presets) console.log(` ${p.personaId.padEnd(width)} ${p.displayName} — ${p.role} · ${p.oneLine}`);
|
|
55
100
|
}
|
|
@@ -60,19 +105,40 @@ export function registerPersonaCommands(program: Command): void {
|
|
|
60
105
|
}
|
|
61
106
|
});
|
|
62
107
|
|
|
63
|
-
persona.command('add <
|
|
64
|
-
.description('Make your own persona from a preset
|
|
108
|
+
persona.command('add <name>')
|
|
109
|
+
.description('Make your own persona from a preset — the preset file is not changed')
|
|
110
|
+
.option('--from <preset>', 'Preset to clone (defaults to the named preset)')
|
|
65
111
|
.option('--name <name>', 'What to call it (default: the preset’s first name)')
|
|
112
|
+
.option('--as <name>', 'Clone this preset under a new, unique name')
|
|
66
113
|
.option('--title <title>', 'Optional title, e.g. CMO')
|
|
67
114
|
.option('--json', 'JSON output')
|
|
68
|
-
.action((query: string, opts: { name?: string; title?: string; json?: boolean }) => {
|
|
115
|
+
.action((query: string, opts: { from?: string; name?: string; as?: string; title?: string; json?: boolean }) => {
|
|
69
116
|
const presets = loadPresets();
|
|
70
|
-
const
|
|
117
|
+
const presetQuery = opts.from ?? query;
|
|
118
|
+
const preset = findPreset(presets, presetQuery);
|
|
71
119
|
if (!preset) {
|
|
72
|
-
console.error(`프리셋 «${
|
|
120
|
+
console.error(`프리셋 «${presetQuery}» 을 찾지 못했습니다. 있는 것: ${presets.map((p) => p.personaId).join(', ')}`);
|
|
73
121
|
process.exitCode = 1;
|
|
74
122
|
return;
|
|
75
123
|
}
|
|
124
|
+
if (opts.as !== undefined || opts.from !== undefined) {
|
|
125
|
+
try {
|
|
126
|
+
if (opts.from !== undefined && (opts.as !== undefined || opts.name !== undefined || opts.title !== undefined)) throw new Error('--from cannot be combined with --as, --name or --title');
|
|
127
|
+
if (opts.as !== undefined && (opts.name !== undefined || opts.title !== undefined)) throw new Error('--as cannot be combined with --name or --title');
|
|
128
|
+
const result = clonePreset(preset, opts.from !== undefined ? query : opts.as!);
|
|
129
|
+
debug.log('persona.cli', 'cloned', { preset: preset.personaId, personaId: result.personaId });
|
|
130
|
+
if (opts.json) console.log(JSON.stringify({ personaId: result.personaId, displayName: result.displayName, preset: preset.personaId, path: result.path }, null, 2));
|
|
131
|
+
else {
|
|
132
|
+
console.log(`만들었습니다 — ${result.displayName} (id ${result.personaId} · 프리셋 ${preset.personaId})`);
|
|
133
|
+
console.log(` 처음 묻는 것: ${preset.firstQuestions.join(' / ')}`);
|
|
134
|
+
console.log(` 보기: elanous persona show ${result.personaId}`);
|
|
135
|
+
}
|
|
136
|
+
} catch (err) {
|
|
137
|
+
console.error(err instanceof Error ? err.message : String(err));
|
|
138
|
+
process.exitCode = 1;
|
|
139
|
+
}
|
|
140
|
+
return;
|
|
141
|
+
}
|
|
76
142
|
const dir = resolveStatePersonaDir();
|
|
77
143
|
const personaId = choosePersonaId(preset, opts.name, takenIds(dir));
|
|
78
144
|
const yaml = presetToProfileYaml(preset, loadPresetIndex().common, { personaId, ...(opts.name ? { name: opts.name } : {}), ...(opts.title ? { title: opts.title } : {}) });
|
|
@@ -89,6 +155,29 @@ export function registerPersonaCommands(program: Command): void {
|
|
|
89
155
|
console.log(` 보기: elanous persona show ${personaId}`);
|
|
90
156
|
});
|
|
91
157
|
|
|
158
|
+
persona.command('edit <name>')
|
|
159
|
+
.description('Edit a saved persona (schema fields only; the preset source is not changed)')
|
|
160
|
+
.option('--set <key=value>', 'Set a field (repeatable; YAML values)', (value: string, values: string[]) => [...values, value], [] as string[])
|
|
161
|
+
.option('--from-file <path>', 'Load edits from a YAML mapping')
|
|
162
|
+
.option('--dry-run', 'Validate and preview without writing')
|
|
163
|
+
.option('--json', 'JSON output')
|
|
164
|
+
.action((name: string, opts: { set: string[]; fromFile?: string; dryRun?: boolean; json?: boolean }) => {
|
|
165
|
+
try {
|
|
166
|
+
if (!opts.fromFile && !opts.set.length) throw new Error('persona edit requires --set or --from-file');
|
|
167
|
+
const result = editPersona(name, editOptions(opts.fromFile, opts.set), { dryRun: opts.dryRun });
|
|
168
|
+
debug.log('persona.cli', opts.dryRun ? 'edit-dry-run' : 'edited', { personaId: result.personaId });
|
|
169
|
+
if (opts.json) console.log(JSON.stringify(result, null, 2));
|
|
170
|
+
else {
|
|
171
|
+
console.log(`${opts.dryRun ? '미리 보기' : '수정했습니다'} — ${result.displayName} (id ${result.personaId})`);
|
|
172
|
+
console.log(result.yaml);
|
|
173
|
+
console.log(` 파일: ${result.path}`);
|
|
174
|
+
}
|
|
175
|
+
} catch (err) {
|
|
176
|
+
console.error(err instanceof Error ? err.message.replace(/\s+/g, ' ').trim() : String(err));
|
|
177
|
+
process.exitCode = err instanceof UnknownPersonaSchemaKeyError ? 2 : 1;
|
|
178
|
+
}
|
|
179
|
+
});
|
|
180
|
+
|
|
92
181
|
persona.command('show <name>')
|
|
93
182
|
.description('Show one of your personas (id or name), or a preset')
|
|
94
183
|
.option('--json', 'JSON output')
|
package/src/cli/plugin-cli.ts
CHANGED
|
@@ -12,6 +12,7 @@ import { OFFICIAL_INDEX_KEYS } from '../market/official-keys.js';
|
|
|
12
12
|
import { installPlugin, listInstalledPlugins, PluginInstallError, removePlugin, type InstallEvent } from '../plugins/install/plugin-install.js';
|
|
13
13
|
import { credentialStatus, setPluginCredentials } from '../plugins/install/plugin-credentials.js';
|
|
14
14
|
import { makePlugin } from '../plugins/maker/plugin-maker.js';
|
|
15
|
+
import { registerStandaloneLogSink } from '../domains/standalone-log-sink.js';
|
|
15
16
|
import { addAndInstallNode } from '../plugins/maker/node-install.js';
|
|
16
17
|
|
|
17
18
|
function keys(): ReadonlyArray<{ keyId: string; publicKey: string }> {
|
|
@@ -56,34 +57,42 @@ function safeCause(error: unknown): string {
|
|
|
56
57
|
return redactSecretText(error.message.replace(/https?:\/\/[^\s"'<>]+/gi, '[redacted URL]'));
|
|
57
58
|
}
|
|
58
59
|
|
|
60
|
+
export async function runPluginMake(request: string, opts: { name?: string; dir?: string; draftFile?: string; run?: boolean; marketBundleDir?: string; input?: string; json?: boolean } = {}): Promise<void> {
|
|
61
|
+
try {
|
|
62
|
+
await registerStandaloneLogSink('cli');
|
|
63
|
+
const result = await makePlugin({ request, name: opts.name, parentDir: opts.dir, draftFile: opts.draftFile, run: opts.run, marketBundleDir: opts.marketBundleDir,
|
|
64
|
+
...(opts.input === undefined ? {} : { input: JSON.parse(opts.input) as unknown }) });
|
|
65
|
+
debug.flush();
|
|
66
|
+
if (opts.json) stdout.write(JSON.stringify(result) + '\n');
|
|
67
|
+
else {
|
|
68
|
+
console.log(`뼈대 ${result.timings.scaffold}ms · 작성 ${result.timings.write}ms`);
|
|
69
|
+
console.log(`검증 오류 ${result.errors.length} · ${result.timings.validate}ms${result.timings.repair === undefined ? '' : ` · 수리 ${result.timings.repair}ms`}`);
|
|
70
|
+
console.log(`설치 ${result.status === 'draft' || result.timings.install === 0 ? '미실행' : result.status === 'failed' && result.timings.run === undefined ? '실패' : '완료'} · ${result.timings.install}ms (${result.dir})`);
|
|
71
|
+
if (result.status === 'draft') console.log('연구 초안만 생성됨 — 요청 처리 단계 구현 후 별도로 검증·설치 필요');
|
|
72
|
+
if (result.marketBundle) console.log(`마켓 꾸러미 ${result.marketBundle.path} · ${result.marketBundle.signature} · 게시 안 함`);
|
|
73
|
+
if (opts.run) console.log(`실행 ${result.runStatus ?? '미실행'} · ${result.timings.run ?? 0}ms`);
|
|
74
|
+
for (const error of result.errors) console.error(error);
|
|
75
|
+
}
|
|
76
|
+
if (result.status === 'failed') process.exitCode = 1;
|
|
77
|
+
} catch (error) {
|
|
78
|
+
const message = error instanceof Error ? error.message : String(error);
|
|
79
|
+
if (opts.json) stdout.write(JSON.stringify({ status: 'failed', errors: [message] }) + '\n');
|
|
80
|
+
else console.error(`plugin make failed: ${message}`);
|
|
81
|
+
process.exitCode = 1;
|
|
82
|
+
}
|
|
83
|
+
}
|
|
84
|
+
|
|
59
85
|
export function registerPluginCommands(program: Command): void {
|
|
60
86
|
const plugin = program.command('plugin').description('Install and manage Elanous plugins');
|
|
61
|
-
plugin.command('make <request>').description('Write, validate and install a local graph plugin
|
|
87
|
+
plugin.command('make <request>').description('Write, validate and install a local graph plugin, or generate an uninstalled research draft')
|
|
62
88
|
.option('--name <slug>', 'Local plugin name')
|
|
63
89
|
.option('--dir <parent>', 'Parent directory (default: instance plugins-local)')
|
|
64
|
-
.option('--
|
|
90
|
+
.option('--draft-file <path>', 'Generate an uninstalled research draft with connector and skill definitions')
|
|
91
|
+
.option('--run', 'Run the installed graph (not available for research drafts)')
|
|
92
|
+
.option('--market-bundle-dir <path>', 'Bundle installed plugin for human review; never publish')
|
|
65
93
|
.option('--input <json>', 'JSON input for --run')
|
|
66
94
|
.option('--json', 'Print the result as JSON')
|
|
67
|
-
.action(
|
|
68
|
-
try {
|
|
69
|
-
const result = await makePlugin({ request, name: opts.name, parentDir: opts.dir, run: opts.run,
|
|
70
|
-
...(opts.input === undefined ? {} : { input: JSON.parse(opts.input) as unknown }) });
|
|
71
|
-
if (opts.json) stdout.write(JSON.stringify(result) + '\n');
|
|
72
|
-
else {
|
|
73
|
-
console.log(`뼈대 ${result.timings.scaffold}ms · 작성 ${result.timings.write}ms`);
|
|
74
|
-
console.log(`검증 오류 ${result.errors.length} · ${result.timings.validate}ms${result.timings.repair === undefined ? '' : ` · 수리 ${result.timings.repair}ms`}`);
|
|
75
|
-
console.log(`설치 ${result.timings.install === 0 && result.status === 'failed' ? '미실행' : result.status === 'failed' && result.timings.run === undefined ? '실패' : '완료'} · ${result.timings.install}ms (${result.dir})`);
|
|
76
|
-
if (opts.run) console.log(`실행 ${result.runStatus ?? '미실행'} · ${result.timings.run ?? 0}ms`);
|
|
77
|
-
for (const error of result.errors) console.error(error);
|
|
78
|
-
}
|
|
79
|
-
if (result.status === 'failed') process.exitCode = 1;
|
|
80
|
-
} catch (error) {
|
|
81
|
-
const message = error instanceof Error ? error.message : String(error);
|
|
82
|
-
if (opts.json) stdout.write(JSON.stringify({ status: 'failed', errors: [message] }) + '\n');
|
|
83
|
-
else console.error(`plugin make failed: ${message}`);
|
|
84
|
-
process.exitCode = 1;
|
|
85
|
-
}
|
|
86
|
-
});
|
|
95
|
+
.action(runPluginMake);
|
|
87
96
|
plugin.command('node').description('Manage plugin workflow nodes')
|
|
88
97
|
.command('add <dir> <request>').description('Write, validate and install a workflow node in a plugin')
|
|
89
98
|
.option('--kind <slug>', 'Workflow node kind')
|
package/src/cli/pod-cli.ts
CHANGED
|
@@ -3,10 +3,11 @@
|
|
|
3
3
|
|
|
4
4
|
import type { Command } from 'commander';
|
|
5
5
|
import { debug } from '../debug/log.js';
|
|
6
|
+
import { readPodMemoryAdvice } from './pod-memory-advice.js';
|
|
6
7
|
import { getUserConfig } from '../user-config.js';
|
|
7
8
|
import { listCodexAccountsInStore } from '../oauth/codex-account-store.js';
|
|
8
9
|
import { parsePodPool, resolvePodPoolSpec, type PoolKubectl } from '../task-orchestrator/surfaces/pod-pool.js';
|
|
9
|
-
import { leaseKubectl, measurePoolLease, recommendConcurrency, type PoolLeaseMeasure } from '../task-orchestrator/surfaces/pod-lease.js';
|
|
10
|
+
import { leaseKubectl, measurePoolLease, probePoolDns, recommendConcurrency, type PoolLeaseMeasure, type PoolDnsProbe } from '../task-orchestrator/surfaces/pod-lease.js';
|
|
10
11
|
import { POD_COMMAND_DEADLINE_SECONDS, runPodCommand, type PodCommandResult, type RunPodCommandOptions } from '../task-orchestrator/surfaces/pod-command-job.js';
|
|
11
12
|
|
|
12
13
|
export interface PodCliIo {
|
|
@@ -19,9 +20,12 @@ export interface PodCliDeps {
|
|
|
19
20
|
io?: PodCliIo;
|
|
20
21
|
run?: (options: RunPodCommandOptions) => Promise<PodCommandResult>;
|
|
21
22
|
kubectl?: PoolKubectl;
|
|
23
|
+
dns?: (context: string, kubectl: PoolKubectl) => PoolDnsProbe;
|
|
22
24
|
accounts?: () => number;
|
|
23
25
|
perAccount?: () => number;
|
|
24
26
|
poolSpec?: (explicit?: string) => string | null;
|
|
27
|
+
harnessPool?: () => string | undefined;
|
|
28
|
+
memoryAdvice?: (logsDb?: string) => ReturnType<typeof readPodMemoryAdvice>;
|
|
25
29
|
}
|
|
26
30
|
|
|
27
31
|
const HELP = `elanous pod run [--pool <스펙>] [--skill <이름,…>] [--llm grok] [--clone] [--deadline <초>] -- <명령…>
|
|
@@ -36,19 +40,37 @@ export function registerPodCommands(program: Command, deps: PodCliDeps = {}): vo
|
|
|
36
40
|
};
|
|
37
41
|
const run = deps.run ?? ((options: RunPodCommandOptions) => runPodCommand(options));
|
|
38
42
|
const pod = program.command('pod').description('Pod 명령 Job — 하니스 없이 명령 하나를 돌리고 산출을 돌려받는다');
|
|
39
|
-
pod.command('
|
|
43
|
+
pod.command('memory').description('실측 기반 Pod 메모리 권고 (읽기 전용)')
|
|
44
|
+
.command('advise').description('골 종류별 standard 16Gi / high 32Gi 권고와 근거')
|
|
45
|
+
.option('--json', '권고와 측정 근거를 JSON 으로')
|
|
46
|
+
.option('--logs-db <path>', '기존 logs.db 경로')
|
|
47
|
+
.action((opts: { json?: boolean; logsDb?: string }) => {
|
|
48
|
+
try {
|
|
49
|
+
const advice = (deps.memoryAdvice ?? readPodMemoryAdvice)(opts.logsDb);
|
|
50
|
+
if (opts.json) io.log(JSON.stringify(advice));
|
|
51
|
+
else for (const row of advice.byGoalType) io.log(`${row.goalType}: ${row.recommended} ${row.limit} · ${row.reason}`);
|
|
52
|
+
io.exit(0);
|
|
53
|
+
} catch (err) {
|
|
54
|
+
io.error(err instanceof Error ? err.message : String(err));
|
|
55
|
+
io.exit(1);
|
|
56
|
+
}
|
|
57
|
+
});
|
|
58
|
+
pod.command('lease').description('Pod 풀 동시 실행 권장 (DNS 점검용 Pod 를 잠깐 만들었다 지움)')
|
|
40
59
|
.command('status').description('지금 추가로 쏠 수 있는 Pod 골과 제한 근거')
|
|
41
|
-
.option('--pool <spec>', '풀 스펙 — 컨텍스트[@ssh호스트][:상한] 쉼표')
|
|
60
|
+
.option('--pool <spec>', '풀 스펙 — 컨텍스트[@ssh호스트][:상한][#레지스트리:포트] 쉼표')
|
|
42
61
|
.option('--json', '표 대신 동일 측정값을 JSON 으로')
|
|
43
62
|
.action((opts: { pool?: string; json?: boolean }) => {
|
|
44
63
|
try {
|
|
45
64
|
const kubectl = deps.kubectl ?? leaseKubectl;
|
|
46
|
-
const spec = (deps.poolSpec ?? ((explicit?: string) => resolvePodPoolSpec(explicit
|
|
65
|
+
const spec = (deps.poolSpec ?? ((explicit?: string) => resolvePodPoolSpec(explicit, process.env, () => {
|
|
66
|
+
const config = deps.harnessPool ? null : getUserConfig();
|
|
67
|
+
return (deps.harnessPool?.() ?? config?.harness?.podPool) || config?.pod?.pool;
|
|
68
|
+
})))(opts.pool);
|
|
47
69
|
// No pool configured: mirror the Pod launch fallback to kubectl's current context.
|
|
48
70
|
const current = spec ? null : kubectl(['config', 'current-context']);
|
|
49
71
|
const context = spec ?? (current?.status === 0 ? current.stdout.trim() : '');
|
|
50
72
|
const members = context ? parsePodPool(context) : [];
|
|
51
|
-
const measure: PoolLeaseMeasure = members.length ? measurePoolLease(members, { kubectl }) : { members: [] };
|
|
73
|
+
const measure: PoolLeaseMeasure = members.length ? measurePoolLease(members, { kubectl, dns: (context) => (deps.dns ?? probePoolDns)(context, kubectl) }) : { members: [] };
|
|
52
74
|
let accounts: number | null = null;
|
|
53
75
|
let accountReason: string | null = null;
|
|
54
76
|
try { accounts = (deps.accounts ?? (() => listCodexAccountsInStore().length))(); }
|
|
@@ -57,17 +79,20 @@ export function registerPodCommands(program: Command, deps: PodCliDeps = {}): vo
|
|
|
57
79
|
const decision = recommendConcurrency(measure, { capacity: members.reduce((sum, m) => sum + m.capacity, 0), accounts: accounts ?? -1, perAccount });
|
|
58
80
|
if (!context) { decision.recommended = null; decision.limitedBy = null; decision.reason = '측정 불가: cluster (current context)'; }
|
|
59
81
|
const result = { pool: spec, ...measure, accounts, perAccount, ...decision };
|
|
60
|
-
debug.log('pod.lease', 'status', { pool: spec ? members.map((m) => ({ capacity: m.capacity })) : null, running: decision.running, pending: decision.pending, recommended: decision.recommended, limitedBy: decision.limitedBy });
|
|
82
|
+
debug.log('pod.lease', 'status', { pool: spec ? members.map((m) => ({ capacity: m.capacity })) : null, running: decision.running, pending: decision.pending, unleasedRunning: decision.unleasedRunning, recommended: decision.recommended, limitedBy: decision.limitedBy });
|
|
61
83
|
if (opts.json) io.log(JSON.stringify(result));
|
|
62
84
|
else {
|
|
85
|
+
io.log(`풀: ${(spec ?? context) || '?'}`);
|
|
63
86
|
io.log('컨텍스트 | 상한 | Running | Pending | 메모리(상한 합/할당 가능) | CPU(할당 가능)');
|
|
64
87
|
for (const m of measure.members) {
|
|
65
88
|
const mem = (v: number | null) => v === null ? '?' : `${(v / 1024 ** 3).toFixed(1)}Gi`;
|
|
66
89
|
io.log(`${m.context} | ${m.capacity} | ${m.running ?? '?'} | ${m.pending ?? '?'} | ${mem(m.memoryLimitBytes)}/${mem(m.allocatableMemoryBytes)} | ${m.allocatableCpuMillicores === null ? '?' : m.allocatableCpuMillicores / 1000}${m.reason ? ` (${m.reason})` : ''}`);
|
|
67
90
|
}
|
|
68
91
|
io.log(`권장 지금 ${decision.recommended ?? '?'} 개 더 (limitedBy=${decision.limitedBy ?? 'unknown'})${decision.reason ? ` · ${decision.reason}` : ''}`);
|
|
69
|
-
io.log(
|
|
92
|
+
io.log(`임대 없는 실행 ${decision.unleasedRunning ?? '?'}`);
|
|
93
|
+
io.log(`capacity: ${decision.capacitySlots ?? '?'} 칸 (상한 ${members.reduce((sum, m) => sum + m.capacity, 0)} − Running ${decision.running ?? '?'} − Pending ${decision.pending ?? '?'}; 권장 수에서 건강한 멤버의 임대 없는 실행 차감)`);
|
|
70
94
|
io.log(`memory: ${decision.memorySlots ?? '?'} 칸 (할당 가능 − Running 하니스 상한 합; 골당 16Gi · 모든 네임스페이스의 노드별 기존 예약을 반영해 배치 가능 ${decision.placeableSlots ?? '?'} 칸)`);
|
|
95
|
+
io.log(`lite: ${decision.liteMemorySlots ?? '?'} 칸 (같은 여유를 lite 골 2Gi 로 센 값 · 관측만 — 권장 수는 위 standard 기준)`);
|
|
71
96
|
io.log(`accounts (관측만 · 상한 아님): ${decision.accountSlots ?? '?'} 칸 (${accounts ?? '?'} × ${perAccount} − Running ${decision.running ?? '?'})${accountReason ? ` · ${accountReason}` : ''}`);
|
|
72
97
|
}
|
|
73
98
|
io.exit(0);
|
|
@@ -78,14 +103,15 @@ export function registerPodCommands(program: Command, deps: PodCliDeps = {}): vo
|
|
|
78
103
|
});
|
|
79
104
|
pod.command('run')
|
|
80
105
|
.description(HELP)
|
|
81
|
-
.option('--pool <spec>', '풀 스펙 — 컨텍스트[@ssh호스트][:상한] 쉼표')
|
|
106
|
+
.option('--pool <spec>', '풀 스펙 — 컨텍스트[@ssh호스트][:상한][#레지스트리:포트] 쉼표')
|
|
82
107
|
.option('--skill <names>', '스킬 이름(쉼표). 그 스킬 .env 만 Secret 으로 싣는다')
|
|
83
108
|
.option('--llm <provider>', 'grok 만 허용 — access 사본(refresh 없음)')
|
|
84
109
|
.option('--clone', '저장소를 clone 한다(비공개 · GitHub 토큰이 런 Secret 으로 간다 · 명시할 때만). 기본은 clone 없이 ~/work 에서 이미지의 elanous 로')
|
|
85
110
|
.option('--deadline <seconds>', `Job 수명 상한(초). 생략 시 ${POD_COMMAND_DEADLINE_SECONDS}`)
|
|
86
111
|
.allowUnknownOption(true)
|
|
87
112
|
.allowExcessArguments(true)
|
|
88
|
-
.
|
|
113
|
+
.option('--lite', '네트워크 스킬(omni-crawl·omni-digest)만 쓰는 명령 — 작은 이미지 ⊕ 2Gi 한도(POD7 · clone 불가)')
|
|
114
|
+
.action(async (opts: { pool?: string; skill?: string; llm?: string; clone?: boolean; deadline?: string; lite?: boolean }, command: Command) => {
|
|
89
115
|
const argv = process.argv.slice(2);
|
|
90
116
|
const sep = argv.indexOf('--');
|
|
91
117
|
const fromArgv = sep >= 0 ? argv.slice(sep + 1) : [];
|
|
@@ -117,6 +143,7 @@ export function registerPodCommands(program: Command, deps: PodCliDeps = {}): vo
|
|
|
117
143
|
...(skills.length ? { skills } : {}),
|
|
118
144
|
...(opts.llm === 'grok' ? { llm: 'grok' as const } : {}),
|
|
119
145
|
...(opts.clone ? { clone: true } : {}),
|
|
146
|
+
...(opts.lite ? { lite: true } : {}),
|
|
120
147
|
...(deadlineSeconds !== undefined ? { deadlineSeconds } : {}),
|
|
121
148
|
});
|
|
122
149
|
if (result.image) io.error(`[pod] image ${result.image} · job ${result.job}`);
|
|
@@ -0,0 +1,35 @@
|
|
|
1
|
+
import { readPodMemoryMeasurement, type MemoryMeasurement } from '../../scripts/measure-pod-memory-by-goal.js';
|
|
2
|
+
|
|
3
|
+
export type PodMemoryAdvice = {
|
|
4
|
+
window: MemoryMeasurement['window'];
|
|
5
|
+
sources: MemoryMeasurement['sources'];
|
|
6
|
+
byGoalType: Array<{
|
|
7
|
+
goalType: MemoryMeasurement['byGoalType'][number]['goalType'];
|
|
8
|
+
recommended: 'standard' | 'high';
|
|
9
|
+
limit: '16Gi' | '32Gi';
|
|
10
|
+
reason: string;
|
|
11
|
+
evidence: MemoryMeasurement['byGoalType'][number];
|
|
12
|
+
}>;
|
|
13
|
+
};
|
|
14
|
+
|
|
15
|
+
/** Advice only: the launch selector and its configuration remain independent. */
|
|
16
|
+
export function advisePodMemory(measurement: MemoryMeasurement): PodMemoryAdvice {
|
|
17
|
+
return {
|
|
18
|
+
window: measurement.window,
|
|
19
|
+
sources: measurement.sources,
|
|
20
|
+
byGoalType: measurement.byGoalType.map((evidence) => {
|
|
21
|
+
const high = evidence.oomKilled > 0 || (evidence.peakMiB.p95 !== null && evidence.peakMiB.p95 >= 16 * 1024);
|
|
22
|
+
const reason = evidence.oomKilled > 0
|
|
23
|
+
? `${evidence.oomKilled}/${evidence.runs} OOMKilled; measured peak p50=${evidence.peakMiB.p50 ?? 'n/a'} MiB, p95=${evidence.peakMiB.p95 ?? 'n/a'} MiB (${evidence.measured}/${evidence.runs} measured)`
|
|
24
|
+
: evidence.measured === 0
|
|
25
|
+
? `No measured peaks (${evidence.missingPeak}/${evidence.runs} missing); standard is provisional, not evidence of safety`
|
|
26
|
+
: `Measured peak p50=${evidence.peakMiB.p50} MiB, p95=${evidence.peakMiB.p95} MiB (${evidence.measured}/${evidence.runs} measured, ${evidence.missingPeak} missing); ${high ? 'at or above' : 'below'} 16Gi`;
|
|
27
|
+
return { goalType: evidence.goalType, recommended: high ? 'high' as const : 'standard' as const,
|
|
28
|
+
limit: high ? '32Gi' as const : '16Gi' as const, reason, evidence };
|
|
29
|
+
}),
|
|
30
|
+
};
|
|
31
|
+
}
|
|
32
|
+
|
|
33
|
+
export function readPodMemoryAdvice(path?: string): PodMemoryAdvice {
|
|
34
|
+
return advisePodMemory(readPodMemoryMeasurement(path));
|
|
35
|
+
}
|
package/src/cli/pr-cli.ts
CHANGED
|
@@ -18,7 +18,7 @@ import { runMockModuleRestoreGate } from '../../scripts/ci-mock-module-restore-g
|
|
|
18
18
|
import { runModelHardcodeGate } from '../../scripts/ci-model-hardcode-gate.js';
|
|
19
19
|
import { runDaemonPortGate } from '../../scripts/ci-daemon-port-gate.js';
|
|
20
20
|
import { runPublicLeakGate } from '../../scripts/ci-public-leak-gate.js';
|
|
21
|
-
import { exportLeakCheck, type ExportLeakCheck } from '../../scripts/ci-public-export-leak-gate.js';
|
|
21
|
+
import { exportLeakCheck, publicExportChangedFiles, type ExportLeakCheck } from '../../scripts/ci-public-export-leak-gate.js';
|
|
22
22
|
import { checkCommands, extractElanousCommands, type Finding as DocsCliFinding } from '../../scripts/docs-cli-check.js';
|
|
23
23
|
import { runTestInterferenceGate } from '../../scripts/ci-test-interference-gate.js';
|
|
24
24
|
import { isGoalDocumentFileName } from '../self-implement/goal-document.js';
|
|
@@ -104,7 +104,7 @@ export interface PrLandDeps {
|
|
|
104
104
|
runMockModuleRestoreGate?: (out: { log: (message: string) => void; error: (message: string) => void }) => boolean;
|
|
105
105
|
runModelHardcodeGate?: (out: { log: (message: string) => void; error: (message: string) => void }) => boolean;
|
|
106
106
|
runDaemonPortGate?: (out: { log: (message: string) => void; error: (message: string) => void }) => boolean;
|
|
107
|
-
/** 공개 유출 래칫(경고 전용) — 반환 0
|
|
107
|
+
/** 공개 유출 래칫(경고 전용) — 반환 0 동일 · 1 늘었다 · 2 못 쟀다 · 3 줄었다. */
|
|
108
108
|
runPublicLeakGate?: (changedFiles: readonly string[], out: { log: (message: string) => void; error: (message: string) => void }) => number;
|
|
109
109
|
/** Test seam — the post-transform export leak check on changed files. */
|
|
110
110
|
runExportLeakCheck?: (changedFiles: readonly string[], cwd: string) => ExportLeakCheck;
|
|
@@ -275,8 +275,10 @@ export function runPrLandIsolationGate(
|
|
|
275
275
|
|
|
276
276
|
/** ⭐ 2026-09-24 — 공개 유출 래칫은 «경고만» 낸다(착지를 막지 않는다 · 막는 것은 공개 결정 뒤 · 채널 합의).
|
|
277
277
|
* 계기: 기준선 뒤 3시간 만에 🅢 착지분에서 유출 증가 다섯을 이 게이트가 잡았다 — 착지 순간에 보여야 그 자리에서 고친다. */
|
|
278
|
-
function runPrLandPublicLeakGate(changedFiles: readonly string[], out: { log: (message: string) => void; error: (message: string) => void }): number {
|
|
279
|
-
|
|
278
|
+
function runPrLandPublicLeakGate(changedFiles: readonly string[], out: { log: (message: string) => void; error: (message: string) => void }, cwd: string, baselineRef: string): number {
|
|
279
|
+
const top = runGitCommand(cwd, ['rev-parse', '--show-toplevel'], { encoding: 'utf-8' });
|
|
280
|
+
if (top.status !== 0 || !String(top.stdout ?? '').trim()) return 2;
|
|
281
|
+
return runPublicLeakGate({ args: ['--changed-files', ...changedFiles], root: String(top.stdout).trim(), baselineRef, log: out.log, error: out.log });
|
|
280
282
|
}
|
|
281
283
|
|
|
282
284
|
/** The prepare check on this landing's changed files — scripts/ci-public-export-leak-gate.ts. */
|
|
@@ -285,23 +287,49 @@ export function runPrLandExportLeakCheck(changedFiles: readonly string[], cwd: s
|
|
|
285
287
|
return exportLeakCheck(changedFiles, top.status === 0 && String(top.stdout ?? '').trim() ? String(top.stdout).trim() : cwd);
|
|
286
288
|
}
|
|
287
289
|
|
|
288
|
-
/** Blocks
|
|
290
|
+
/** Blocks changed public files that leak or cannot be measured. */
|
|
289
291
|
export function exportLeakBlock(
|
|
290
292
|
changedFiles: readonly string[] | undefined,
|
|
291
293
|
check: () => ExportLeakCheck,
|
|
292
294
|
allow: boolean,
|
|
293
295
|
out: { log: (message: string) => void; error: (message: string) => void },
|
|
296
|
+
cwd: string = process.cwd(),
|
|
294
297
|
): boolean {
|
|
295
298
|
if (!changedFiles || changedFiles.length === 0) return true;
|
|
296
299
|
let result: ExportLeakCheck;
|
|
297
|
-
try { result = check(); } catch
|
|
298
|
-
|
|
299
|
-
if (!result.measured) {
|
|
300
|
-
|
|
300
|
+
try { result = check(); } catch { result = { measured: false, hits: [], detail: '검사 실행 실패' }; }
|
|
301
|
+
let publicFiles: string[] = [];
|
|
302
|
+
if (!result.measured) {
|
|
303
|
+
try { publicFiles = publicExportChangedFiles(changedFiles, cwd); }
|
|
304
|
+
catch { publicFiles = [...changedFiles]; } // A missing/invalid manifest cannot prove these files are private.
|
|
305
|
+
}
|
|
306
|
+
const applicable = result.hits.filter((hit) => hit.marker !== 'skill-boundary' || changedFiles.includes(hit.file));
|
|
307
|
+
const missingReason: ExportLeakCheck['hits'][number][] = [];
|
|
308
|
+
const blockedHits: ExportLeakCheck['hits'][number][] = [];
|
|
309
|
+
let allowed = 0;
|
|
310
|
+
for (const hit of applicable) {
|
|
311
|
+
let lines: string[];
|
|
312
|
+
try { lines = readFileSync(join(cwd, hit.file), 'utf8').split(/\r?\n/); }
|
|
313
|
+
catch { blockedHits.push(hit); continue; }
|
|
314
|
+
const notes = [lines[hit.line - 1], lines[hit.line - 2]].filter((line): line is string => line !== undefined)
|
|
315
|
+
.map((line) => /(?:\/\/|\/\*|\*|#|<!--)\s*public-export-allow:\s*(.*)/u.exec(line));
|
|
316
|
+
if (notes.some((note) => note?.[1]?.replace(/(?:\*\/|-->)\s*$/u, '').trim())) { allowed++; continue; }
|
|
317
|
+
blockedHits.push(hit);
|
|
318
|
+
if (notes.some(Boolean)) missingReason.push(hit);
|
|
319
|
+
}
|
|
320
|
+
const blocked = (!result.measured && publicFiles.length > 0) || (blockedHits.length > 0 && !allow);
|
|
321
|
+
record('public-export-leak', !blocked, { measured: result.measured, hits: applicable.length, allowed });
|
|
322
|
+
debug.log('pr.land', 'leak-gate', { blocked, hits: applicable.map(({ file, marker }) => ({ file, marker })), measured: result.measured, allowed });
|
|
323
|
+
if (!result.measured) {
|
|
324
|
+
const write = blocked ? out.error : out.log;
|
|
325
|
+
write(`${blocked ? '✗' : '⚠'} public-export-leak: 못 쟀다${blocked ? ' — 막는다' : ' — 공개 대상 변경 없음'}(${result.detail ?? '?'}) · 확인: bun scripts/public-export.ts --leak-check --json --all --files <파일…>`);
|
|
326
|
+
return !blocked;
|
|
327
|
+
}
|
|
328
|
+
if (blockedHits.length === 0) { out.log('✓ public-export-leak: 바뀐 파일이 공개본에 사적 흔적을 싣지 않는다(prepare 와 같은 변환 뒤).'); return true; }
|
|
301
329
|
const write = allow ? out.log : out.error;
|
|
302
|
-
write(`${allow ? '⚠' : '✗'} public-export-leak: 바뀐 파일 ${
|
|
303
|
-
for (const
|
|
304
|
-
if (
|
|
330
|
+
write(`${allow ? '⚠' : '✗'} public-export-leak: 바뀐 파일 ${blockedHits.length}곳이 공개본에 사적 흔적을 싣는다 — 다음 release prepare 가 여기서 실패한다:`);
|
|
331
|
+
for (const hit of blockedHits.slice(0, 20)) write(` ${hit.file}:${hit.line} · ${hit.marker}${missingReason.includes(hit) ? ' · 사유 없음' : ''}`);
|
|
332
|
+
if (blockedHits.length > 20) write(` … 외 ${blockedHits.length - 20}곳`);
|
|
305
333
|
write(' 확인: bun scripts/public-export.ts --leak-check --all --files <파일…>');
|
|
306
334
|
if (allow) { out.log(' --allow-public-leak 로 넘긴다(이유는 --land-reason).'); return true; }
|
|
307
335
|
out.error(' 고치거나, 공개본과 무관한 것이 확실하면 --allow-public-leak --land-reason "<이유>" 로 넘긴다.');
|
|
@@ -322,8 +350,12 @@ export function publicLeakWarning(
|
|
|
322
350
|
record('public-leak-gate', true, { warnOnly: true, measured: false });
|
|
323
351
|
return;
|
|
324
352
|
}
|
|
325
|
-
record('public-leak-gate', true, { warnOnly: true, measured: rc !== 2, grew: rc === 1 });
|
|
353
|
+
record('public-leak-gate', true, { warnOnly: true, measured: rc !== 2, grew: rc === 1, shrank: rc === 3 });
|
|
326
354
|
if (rc === 0) { out.log('✓ public-leak-gate(경고 전용): 공개 유출이 늘지 않았다.'); return; }
|
|
355
|
+
if (rc === 3) {
|
|
356
|
+
for (const line of captured.filter((l) => /→/.test(l))) out.log(`✓ public-leak-gate(경고 전용): 공개 유출이 줄었다 · 기준선 --update 권장 — ${line.trim()}`);
|
|
357
|
+
return;
|
|
358
|
+
}
|
|
327
359
|
if (rc === 1) {
|
|
328
360
|
out.log('⚠ public-leak-gate(경고 전용 · 착지는 막지 않는다): 공개 유출이 늘었다 —');
|
|
329
361
|
for (const line of captured.filter((l) => /→/.test(l))) out.log(` ${line.trim()}`);
|
|
@@ -1031,6 +1063,10 @@ export async function runPrLand(opts: PrLandOpts = {}, deps: PrLandDeps = {}): P
|
|
|
1031
1063
|
out.error('✗ body: --body와 --body-file은 함께 사용할 수 없습니다.');
|
|
1032
1064
|
return 1;
|
|
1033
1065
|
}
|
|
1066
|
+
if (opts.allowPublicLeak && !opts.landReason?.trim()) {
|
|
1067
|
+
out.error('✗ public-export-leak: --allow-public-leak 에는 --land-reason "<이유>" 가 필요합니다.');
|
|
1068
|
+
return 1;
|
|
1069
|
+
}
|
|
1034
1070
|
if (opts.includeActiveRunFiles && opts.excludeActiveRunFiles) {
|
|
1035
1071
|
out.error('✗ active-run-files: --include-active-run-files와 --exclude-active-run-files는 함께 사용할 수 없습니다.');
|
|
1036
1072
|
return 1;
|
|
@@ -1343,8 +1379,8 @@ export async function runPrLand(opts: PrLandOpts = {}, deps: PrLandDeps = {}): P
|
|
|
1343
1379
|
|
|
1344
1380
|
const changedPaths = currentChangePaths(run, cwd, staged, base, out);
|
|
1345
1381
|
nextMdWarning(body ?? '', changedPaths, out);
|
|
1346
|
-
publicLeakWarning(changedPaths, deps.runPublicLeakGate ?? runPrLandPublicLeakGate, out);
|
|
1347
|
-
if (!exportLeakBlock(changedPaths, () => (deps.runExportLeakCheck ?? runPrLandExportLeakCheck)(changedPaths ?? [], cwd), opts.allowPublicLeak === true, out)) return 1;
|
|
1382
|
+
publicLeakWarning(changedPaths, deps.runPublicLeakGate ?? ((files, sink) => runPrLandPublicLeakGate(files, sink, cwd, base)), out);
|
|
1383
|
+
if (!exportLeakBlock(changedPaths, () => (deps.runExportLeakCheck ?? runPrLandExportLeakCheck)(changedPaths ?? [], cwd), opts.allowPublicLeak === true, out, cwd)) return 1;
|
|
1348
1384
|
if (publicDocPaths(changedPaths, () => true).length > 0) {
|
|
1349
1385
|
const top = run('git', ['rev-parse', '--show-toplevel'], { cwd });
|
|
1350
1386
|
const docsRoot = top.ok && top.out.trim() ? top.out.trim() : cwd;
|