elanous 0.2.10 → 0.2.11
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/apps/pwa/out/404/index.html +1 -1
- package/apps/pwa/out/404.html +1 -1
- package/apps/pwa/out/_next/static/Y4zKzL62sakG5momz3SoQ/_buildManifest.js +1 -0
- package/apps/pwa/out/_next/static/chunks/1159-0c5ef8bc21cb6afb.js +1 -0
- package/apps/pwa/out/_next/static/chunks/1394-556de6d71bbdb0fb.js +1 -0
- package/apps/pwa/out/_next/static/chunks/1452.93700483b9d4fc61.js +9 -0
- package/apps/pwa/out/_next/static/chunks/{6062-73e68343a9814f6a.js → 1829-b453a1b22d3999bb.js} +1 -1
- package/apps/pwa/out/_next/static/chunks/2176-c379e3ebce874151.js +1 -0
- package/apps/pwa/out/_next/static/chunks/2310-7a59f043f6db207e.js +1 -0
- package/apps/pwa/out/_next/static/chunks/2426.8c6ee0c668d53def.js +1 -0
- package/apps/pwa/out/_next/static/chunks/2548-6e316138d347cefe.js +1 -0
- package/apps/pwa/out/_next/static/chunks/3170-7ec60a56fa0e4728.js +1 -0
- package/apps/pwa/out/_next/static/chunks/3278-ae6ef084769f6195.js +1 -0
- package/apps/pwa/out/_next/static/chunks/3454-988a53dac60a1763.js +1 -0
- package/apps/pwa/out/_next/static/chunks/3638-aa80b4641ea439db.js +1 -0
- package/apps/pwa/out/_next/static/chunks/3735-fe3402553ac1c9c6.js +1 -0
- package/apps/pwa/out/_next/static/chunks/3869-a39d1d9921e10d43.js +1 -0
- package/apps/pwa/out/_next/static/chunks/390.c373e31b3b9d0c41.js +5 -0
- package/apps/pwa/out/_next/static/chunks/3992-2e522a8ac5f2afde.js +25 -0
- package/apps/pwa/out/_next/static/chunks/4215-c9d91dd644ec1719.js +1 -0
- package/apps/pwa/out/_next/static/chunks/4508-5d0161d1e724d735.js +1 -0
- package/apps/pwa/out/_next/static/chunks/4685-c3c1c625b71accd1.js +1 -0
- package/apps/pwa/out/_next/static/chunks/4733-623a79345b171e1c.js +1 -0
- package/apps/pwa/out/_next/static/chunks/4883.3bd969ea1d3aaaff.js +2 -0
- package/apps/pwa/out/_next/static/chunks/507-5acd98bd6dab2d8a.js +1 -0
- package/apps/pwa/out/_next/static/chunks/5445-745eb795c5963d79.js +1 -0
- package/apps/pwa/out/_next/static/chunks/5532.6899a12958a89b72.js +1 -0
- package/apps/pwa/out/_next/static/chunks/{8067-87ce253ec2f23697.js → 5845-e6c003ce8d5fd36a.js} +1 -1
- package/apps/pwa/out/_next/static/chunks/5978-b27004c677119115.js +1 -0
- package/apps/pwa/out/_next/static/chunks/{8046cadf-211ca3c0e00f2b72.js → 5cd7e3a9-404fd6b8d0ecd44c.js} +1 -1
- package/apps/pwa/out/_next/static/chunks/6048-4c5c33579bc4ef78.js +1 -0
- package/apps/pwa/out/_next/static/chunks/6303-422dbf0f67c72aac.js +1 -0
- package/apps/pwa/out/_next/static/chunks/6751-bb3595948b2e311b.js +1 -0
- package/apps/pwa/out/_next/static/chunks/7274-19b7279f18b47ab3.js +1 -0
- package/apps/pwa/out/_next/static/chunks/{4323.c5dfb6f503304775.js → 7334.a6679d9168f37aa8.js} +1 -1
- package/apps/pwa/out/_next/static/chunks/7551-a0e0707b79164ddd.js +1 -0
- package/apps/pwa/out/_next/static/chunks/7777-79f845045aa1ed86.js +1 -0
- package/apps/pwa/out/_next/static/chunks/79f8be9e-957d68913b590b08.js +1 -0
- package/apps/pwa/out/_next/static/chunks/8025-cc24ee5d8f2fb6f8.js +1 -0
- package/apps/pwa/out/_next/static/chunks/8039-df92e08fede5de8f.js +1 -0
- package/apps/pwa/out/_next/static/chunks/8206-c6684dcde12be721.js +1 -0
- package/apps/pwa/out/_next/static/chunks/8421-1c4acfb1395a0edf.js +1 -0
- package/apps/pwa/out/_next/static/chunks/8605-ea5bee9dfae512c7.js +1 -0
- package/apps/pwa/out/_next/static/chunks/8725.bf46bb1395dd0fa2.js +1 -0
- package/apps/pwa/out/_next/static/chunks/8734-252d511cd276c0dc.js +1 -0
- package/apps/pwa/out/_next/static/chunks/8834-ca1cb09c1cb1a6bf.js +1 -0
- package/apps/pwa/out/_next/static/chunks/{2415.ed6428ff334c7ce2.js → 9269.d2a4795bc6812717.js} +1 -1
- package/apps/pwa/out/_next/static/chunks/9538-2816b90923606459.js +1 -0
- package/apps/pwa/out/_next/static/chunks/9656-c1540088f5859c80.js +1 -0
- package/apps/pwa/out/_next/static/chunks/9906-482c6619b3fdda20.js +1 -0
- package/apps/pwa/out/_next/static/chunks/app/_not-found/page-d16993889b125c42.js +1 -0
- package/apps/pwa/out/_next/static/chunks/app/approvals/page-1dcdc58fc2de2454.js +1 -0
- package/apps/pwa/out/_next/static/chunks/app/autopilot/page-6a061bd97f0b9398.js +1 -0
- package/apps/pwa/out/_next/static/chunks/app/board/page-cb95a7432c9ee744.js +1 -0
- package/apps/pwa/out/_next/static/chunks/app/botlab/{page-54b32bd27726588d.js → page-b12b6d2f8d2d1aea.js} +1 -1
- package/apps/pwa/out/_next/static/chunks/app/bots/page-b9efe868bfd36255.js +1 -0
- package/apps/pwa/out/_next/static/chunks/app/chat/page-7c97dcdfe2e37a60.js +1 -0
- package/apps/pwa/out/_next/static/chunks/app/consult/page-8fd36984f549270a.js +1 -0
- package/apps/pwa/out/_next/static/chunks/app/control/page-5721537ca8a3598c.js +1 -0
- package/apps/pwa/out/_next/static/chunks/app/design-check/page-b654240a572e4c48.js +1 -0
- package/apps/pwa/out/_next/static/chunks/app/editor/page-b9750abc897508c3.js +1 -0
- package/apps/pwa/out/_next/static/chunks/app/exec/page-4cd1de371f8ad048.js +1 -0
- package/apps/pwa/out/_next/static/chunks/app/field/page-d99f89657828421c.js +1 -0
- package/apps/pwa/out/_next/static/chunks/app/healthz/route-d16993889b125c42.js +1 -0
- package/apps/pwa/out/_next/static/chunks/app/inside/page-50cb2a0eb15e6c83.js +1 -0
- package/apps/pwa/out/_next/static/chunks/app/intake/page-c8b1ccda6ba7ae98.js +1 -0
- package/apps/pwa/out/_next/static/chunks/app/layout-d6b1d156fb95e74b.js +1 -0
- package/apps/pwa/out/_next/static/chunks/app/live/page-2a9932ddb62d76bd.js +1 -0
- package/apps/pwa/out/_next/static/chunks/app/market/page-9688f5b4f1ff950f.js +1 -0
- package/apps/pwa/out/_next/static/chunks/app/missions/[id]/page-6b15dd6456c5df09.js +1 -0
- package/apps/pwa/out/_next/static/chunks/app/morning/page-35414e0a007b4082.js +1 -0
- package/apps/pwa/out/_next/static/chunks/app/not-found-e7a529e0507ac86c.js +1 -0
- package/apps/pwa/out/_next/static/chunks/app/observatory/page-e001823c35c9dd67.js +1 -0
- package/apps/pwa/out/_next/static/chunks/app/ops/checklist/page-371423d1a573d64b.js +1 -0
- package/apps/pwa/out/_next/static/chunks/app/ops/release/page-4b764b125339ac17.js +1 -0
- package/apps/pwa/out/_next/static/chunks/app/ops/seats/page-cdf8e4b01067bcf1.js +1 -0
- package/apps/pwa/out/_next/static/chunks/app/outputs/page-3a24072b35470157.js +1 -0
- package/apps/pwa/out/_next/static/chunks/app/page-94c82eb0ae5abb32.js +1 -0
- package/apps/pwa/out/_next/static/chunks/app/reflection/page-0be8d4b2ced75ba0.js +1 -0
- package/apps/pwa/out/_next/static/chunks/app/scheduler/page-d37cb0d52f9b6bd5.js +1 -0
- package/apps/pwa/out/_next/static/chunks/app/sessions/page-686da0df9bf23e5c.js +1 -0
- package/apps/pwa/out/_next/static/chunks/app/settings/devices/page-4dc614f3ce043e63.js +1 -0
- package/apps/pwa/out/_next/static/chunks/app/settings/page-53f80edc6b8dc07c.js +1 -0
- package/apps/pwa/out/_next/static/chunks/app/setup/done/page-d02c782fc792e2af.js +1 -0
- package/apps/pwa/out/_next/static/chunks/app/setup/layout-d16993889b125c42.js +1 -0
- package/apps/pwa/out/_next/static/chunks/app/setup/page-239c17b911b84e72.js +1 -0
- package/apps/pwa/out/_next/static/chunks/app/share/page-dc6a79fb003f746c.js +1 -0
- package/apps/pwa/out/_next/static/chunks/app/showroom/page-0fffb84cafdc9da6.js +1 -0
- package/apps/pwa/out/_next/static/chunks/app/tasks/page-1218753c82d585f6.js +1 -0
- package/apps/pwa/out/_next/static/chunks/app/term/page-4b5935e67531efb5.js +1 -0
- package/apps/pwa/out/_next/static/chunks/app/today/page-3285bc87caf1eaa5.js +1 -0
- package/apps/pwa/out/_next/static/chunks/app/trace/page-ad553b0e06505ecd.js +1 -0
- package/apps/pwa/out/_next/static/chunks/app/vault/page-fca096e3e860306f.js +1 -0
- package/apps/pwa/out/_next/static/chunks/app/workflows/chat-ui/page-9ebfa78f0d9885c3.js +1 -0
- package/apps/pwa/out/_next/static/chunks/app/workflows/page-3dc5f21f7e39622d.js +1 -0
- package/apps/pwa/out/_next/static/chunks/app/workspace/page-c6da2b468454532d.js +1 -0
- package/apps/pwa/out/_next/static/chunks/app/worktrees/page-93bc70e36f595414.js +1 -0
- package/apps/pwa/out/_next/static/chunks/{2ea96958-e8c7e112de50b067.js → f48170cc-d05d28bf87a43bf4.js} +1 -1
- package/apps/pwa/out/_next/static/chunks/framework-172630e6aa5e2d7f.js +1 -0
- package/apps/pwa/out/_next/static/chunks/main-app-f0fe2d7477845181.js +1 -0
- package/apps/pwa/out/_next/static/chunks/main-fc98ac70b44eccb0.js +1 -0
- package/apps/pwa/out/_next/static/chunks/pages/_app-5bd7f10271f72413.js +1 -0
- package/apps/pwa/out/_next/static/chunks/pages/_error-97d0d85ea05fef9b.js +1 -0
- package/apps/pwa/out/_next/static/chunks/webpack-9e4d02d567b98240.js +1 -0
- package/apps/pwa/out/_next/static/css/543f56bcb1f79fca.css +1 -0
- package/apps/pwa/out/approvals/index.html +1 -1
- package/apps/pwa/out/approvals/index.txt +23 -23
- package/apps/pwa/out/autopilot/index.html +1 -1
- package/apps/pwa/out/autopilot/index.txt +23 -23
- package/apps/pwa/out/board/index.html +1 -1
- package/apps/pwa/out/board/index.txt +23 -23
- package/apps/pwa/out/botlab/index.html +1 -1
- package/apps/pwa/out/botlab/index.txt +22 -22
- package/apps/pwa/out/bots/index.html +1 -1
- package/apps/pwa/out/bots/index.txt +22 -22
- package/apps/pwa/out/chat/index.html +1 -1
- package/apps/pwa/out/chat/index.txt +22 -22
- package/apps/pwa/out/consult/index.html +1 -1
- package/apps/pwa/out/consult/index.txt +23 -23
- package/apps/pwa/out/control/index.html +1 -1
- package/apps/pwa/out/control/index.txt +23 -23
- package/apps/pwa/out/design-check/index.html +1 -1
- package/apps/pwa/out/design-check/index.txt +23 -23
- package/apps/pwa/out/editor/index.html +1 -1
- package/apps/pwa/out/editor/index.txt +23 -23
- package/apps/pwa/out/exec/index.html +1 -1
- package/apps/pwa/out/exec/index.txt +23 -23
- package/apps/pwa/out/field/index.html +1 -1
- package/apps/pwa/out/field/index.txt +23 -23
- package/apps/pwa/out/healthz +1 -1
- package/apps/pwa/out/index.html +1 -1
- package/apps/pwa/out/index.txt +22 -22
- package/apps/pwa/out/inside/index.html +1 -0
- package/apps/pwa/out/inside/index.txt +31 -0
- package/apps/pwa/out/intake/index.html +1 -1
- package/apps/pwa/out/intake/index.txt +23 -23
- package/apps/pwa/out/live/index.html +1 -1
- package/apps/pwa/out/live/index.txt +23 -23
- package/apps/pwa/out/market/index.html +1 -1
- package/apps/pwa/out/market/index.txt +22 -22
- package/apps/pwa/out/missions/placeholder/index.html +1 -1
- package/apps/pwa/out/missions/placeholder/index.txt +22 -22
- package/apps/pwa/out/morning/index.html +1 -1
- package/apps/pwa/out/morning/index.txt +23 -23
- package/apps/pwa/out/observatory/index.html +1 -1
- package/apps/pwa/out/observatory/index.txt +23 -23
- package/apps/pwa/out/ops/checklist/index.html +1 -1
- package/apps/pwa/out/ops/checklist/index.txt +22 -22
- package/apps/pwa/out/ops/release/index.html +1 -1
- package/apps/pwa/out/ops/release/index.txt +22 -22
- package/apps/pwa/out/ops/seats/index.html +1 -1
- package/apps/pwa/out/ops/seats/index.txt +22 -22
- package/apps/pwa/out/outputs/index.html +1 -0
- package/apps/pwa/out/outputs/index.txt +30 -0
- package/apps/pwa/out/reflection/index.html +1 -1
- package/apps/pwa/out/reflection/index.txt +23 -23
- package/apps/pwa/out/scheduler/index.html +1 -1
- package/apps/pwa/out/scheduler/index.txt +23 -23
- package/apps/pwa/out/sessions/index.html +1 -1
- package/apps/pwa/out/sessions/index.txt +22 -22
- package/apps/pwa/out/settings/devices/index.html +1 -1
- package/apps/pwa/out/settings/devices/index.txt +23 -23
- package/apps/pwa/out/settings/index.html +1 -1
- package/apps/pwa/out/settings/index.txt +23 -23
- package/apps/pwa/out/setup/done/index.html +1 -1
- package/apps/pwa/out/setup/done/index.txt +23 -23
- package/apps/pwa/out/setup/index.html +1 -1
- package/apps/pwa/out/setup/index.txt +23 -23
- package/apps/pwa/out/share/index.html +1 -1
- package/apps/pwa/out/share/index.txt +23 -23
- package/apps/pwa/out/showroom/index.html +1 -1
- package/apps/pwa/out/showroom/index.txt +22 -22
- package/apps/pwa/out/tasks/index.html +1 -1
- package/apps/pwa/out/tasks/index.txt +23 -23
- package/apps/pwa/out/term/index.html +1 -1
- package/apps/pwa/out/term/index.txt +23 -24
- package/apps/pwa/out/today/index.html +1 -1
- package/apps/pwa/out/today/index.txt +23 -23
- package/apps/pwa/out/trace/index.html +1 -1
- package/apps/pwa/out/trace/index.txt +23 -23
- package/apps/pwa/out/vault/index.html +1 -1
- package/apps/pwa/out/vault/index.txt +23 -23
- package/apps/pwa/out/workflows/chat-ui/index.html +1 -1
- package/apps/pwa/out/workflows/chat-ui/index.txt +23 -23
- package/apps/pwa/out/workflows/index.html +1 -1
- package/apps/pwa/out/workflows/index.txt +23 -23
- package/apps/pwa/out/workspace/index.html +1 -1
- package/apps/pwa/out/workspace/index.txt +23 -24
- package/apps/pwa/out/worktrees/index.html +1 -1
- package/apps/pwa/out/worktrees/index.txt +23 -23
- package/graphs/drafts/draft-cleanup.yaml +19 -0
- package/graphs/drafts/recipes.yaml +23 -0
- package/graphs/intake/intake-daily.yaml +2 -1
- package/graphs/ops/recipes.yaml +3 -0
- package/graphs/ops/secret-exposure.yaml +24 -0
- package/graphs/release/recipes.yaml +3 -0
- package/graphs/release/release-loop.yaml +4 -1
- package/graphs/video/explainer-line.yaml +2 -2
- package/package.json +2 -1
- package/plugins/elanous-hwp/README.md +25 -0
- package/plugins/elanous-hwp/cli.ts +22 -0
- package/plugins/elanous-hwp/converter.ts +237 -0
- package/plugins/elanous-hwp/fixtures/fixed-controls.hwpx +0 -0
- package/plugins/elanous-hwp/fixtures/fixed-table-controls.hwpx +0 -0
- package/plugins/elanous-hwp/fixtures/fixed.hwpx +0 -0
- package/plugins/elanous-hwp/plugin.json +16 -0
- package/plugins/elanous-hwp/plugin.ts +40 -0
- package/scripts/ci-public-export-leak-gate.ts +75 -14
- package/scripts/ci-public-leak-gate.ts +44 -9
- package/scripts/context-hooks/claude-stop.sh +4 -0
- package/scripts/context-hooks/emit.ts +24 -0
- package/scripts/context-hooks/post-tool-use.sh +4 -0
- package/scripts/coord-channel-watch.sh +12 -0
- package/scripts/coord-requests-bridge.ts +143 -0
- package/scripts/field-feed/lib.ts +4 -0
- package/scripts/fleet/node-setup.sh +20 -3
- package/scripts/homebrew-formula-bump.ts +69 -0
- package/scripts/marketing/measure-site-numbers.ts +169 -0
- package/scripts/measure-gate-shards.ts +309 -0
- package/scripts/mission-request-judge.ts +31 -1
- package/scripts/morning-report.ts +2 -2
- package/scripts/opportunity-scan.ts +1 -1
- package/scripts/release-loop/auto-approve-node.ts +21 -4
- package/scripts/release-loop/cut-branch.ts +84 -0
- package/scripts/release-loop/gate-node.ts +14 -13
- package/scripts/release-loop/mac-smoke-node.ts +229 -0
- package/scripts/release-loop/node-verdict.ts +3 -3
- package/scripts/release-loop/tui-node-checks.ts +42 -0
- package/scripts/release-loop/tui-sim-node.ts +32 -8
- package/scripts/release-loop/unattended-release.ts +5 -3
- package/scripts/release-loop/version-node.ts +61 -10
- package/scripts/signal-digest-cycle.ts +2 -7
- package/scripts/signal-digest-photo.ts +11 -0
- package/scripts/tech1-public-measure.ts +94 -0
- package/scripts/test-diet/node.ts +1 -1
- package/scripts/tui-regress.ts +2 -2
- package/scripts/ux/demo-rehearsal.ts +243 -0
- package/scripts/ux/lib/rehearsal-verdict.ts +73 -0
- package/skills/diagram-master/SKILL.md +366 -0
- package/skills/diagram-master/references/engines/excalidraw/color-palette.md +67 -0
- package/skills/diagram-master/references/engines/excalidraw/element-templates.md +182 -0
- package/skills/diagram-master/references/engines/excalidraw/json-schema.md +71 -0
- package/skills/diagram-master/references/engines/excalidraw/render_excalidraw.py +189 -0
- package/skills/diagram-master/references/engines/excalidraw/render_template.html +57 -0
- package/skills/diagram-master/references/engines/matplotlib/matplotlib-patterns.md +235 -0
- package/skills/diagram-master/references/engines/matplotlib/render_matplotlib.py +184 -0
- package/skills/diagram-master/references/engines/mermaid/domain-templates.md +435 -0
- package/skills/diagram-master/references/engines/mermaid/render_mermaid.py +116 -0
- package/skills/diagram-master/references/engines/mermaid/syntax-reference.md +2247 -0
- package/skills/diagram-master/references/engines/nanobannana/render_nanobannana2.py +168 -0
- package/skills/diagram-master/references/engines/svg/color-palette.md +188 -0
- package/skills/diagram-master/references/engines/svg/html-base-template.html +332 -0
- package/skills/diagram-master/references/engines/svg/interactivity-patterns.md +435 -0
- package/skills/diagram-master/references/engines/svg/render_interactive_svg.py +212 -0
- package/skills/diagram-master/references/engines/svg/svg-element-templates.md +349 -0
- package/skills/diagram-master/references/examples/README.md +69 -0
- package/skills/diagram-master/references/examples/ref_grid_architecture.png +0 -0
- package/skills/diagram-master/references/examples/ref_layered_flow.png +0 -0
- package/skills/diagram-master/references/pyproject.toml +16 -0
- package/skills/diagram-master/references/quality-checklist.md +33 -0
- package/skills/diagram-master/references/routing-guide.md +164 -0
- package/skills/diagram-master/references/uv.lock +1356 -0
- package/skills/google-workspace/SKILL.md +33 -0
- package/skills/google-workspace/scripts/gws-safe.sh +177 -0
- package/skills/grill-me/SKILL.md +1 -1
- package/skills/lecture-note-digitizer/SKILL.md +926 -0
- package/skills/lecture-note-digitizer/references/convert_to_pdf.py +30 -0
- package/skills/lecture-note-digitizer/references/extract_slide_diagram.py +73 -0
- package/skills/lecture-note-digitizer/references/html-template.md +167 -0
- package/skills/lecture-note-digitizer/references/katex-style-guide.md +165 -0
- package/skills/omni-crawl/SKILL.md +21 -11
- package/skills/omni-crawl/scripts/main.ts +6 -6
- package/skills/omni-crawl/src/router.ts +3 -3
- package/skills/omni-digest/SKILL.md +17 -9
- package/skills/omni-digest/digest.md +2 -2
- package/skills/omni-digest/src/fetch.ts +30 -3
- package/skills/pitch-deck/SKILL.md +2 -2
- package/skills/pitch-deck/template.html +2 -2
- package/skills/youtube-master/SKILL.md +163 -0
- package/skills/youtube-master/package-lock.json +558 -0
- package/skills/youtube-master/package.json +13 -0
- package/skills/youtube-master/references/study-note-template.md +124 -0
- package/skills/youtube-master/scripts/main.ts +435 -0
- package/skills/youtube-master/scripts/transcribe-local.ts +24 -0
- package/skills/youtube-master/src/audio.ts +63 -0
- package/skills/youtube-master/src/domain-staging.ts +50 -0
- package/skills/youtube-master/src/env.ts +36 -0
- package/skills/youtube-master/src/obsidian.ts +155 -0
- package/skills/youtube-master/src/router.ts +110 -0
- package/skills/youtube-master/src/stt.ts +199 -0
- package/skills/youtube-master/src/study-note.ts +175 -0
- package/skills/youtube-master/src/summarize.ts +358 -0
- package/skills/youtube-master/src/transcript.ts +76 -0
- package/skills/youtube-master/src/types.ts +91 -0
- package/skills/youtube-master/src/util.ts +93 -0
- package/skills/youtube-master/src/youtube.ts +70 -0
- package/skills/youtube-master/tsconfig.json +13 -0
- package/src/acp/server.ts +5 -2
- package/src/agent-mission/driver.ts +80 -10
- package/src/agent-mission/pty-decision.ts +71 -0
- package/src/agent-mission/review-loop.ts +30 -0
- package/src/autopilot/build/llm-conflict-merge.ts +16 -3
- package/src/autopilot/tool-registry.ts +2 -0
- package/src/boot/daemon-prompt-turn.ts +5 -0
- package/src/boot/daemon-runtime.ts +9 -3
- package/src/boot/daemon-tools/web-search.ts +3 -0
- package/src/card-followup/core.ts +109 -0
- package/src/chat/index.ts +1 -0
- package/src/cli/drive-input-jail.ts +101 -0
- package/src/cli/hooks-cli.ts +17 -3
- package/src/cli/make-cli.ts +43 -0
- package/src/cli/persona-cli.ts +90 -4
- package/src/cli/plugin-cli.ts +31 -22
- package/src/cli/pod-cli.ts +19 -9
- package/src/cli/pr-cli.ts +51 -15
- package/src/cli/pty-drive-cli.ts +41 -7
- package/src/cli/pty-drive-verdict.ts +40 -0
- package/src/cli/release-cli.ts +17 -4
- package/src/cli/setup-cli.ts +43 -1
- package/src/cli/skills-cli.ts +17 -1
- package/src/context-bus/claude-hooks-install.ts +10 -0
- package/src/context-bus/context-now-surfaces.ts +48 -0
- package/src/context-bus/context-now.ts +104 -0
- package/src/context-bus/coord-events.ts +2 -2
- package/src/context-bus/external-events.ts +52 -0
- package/src/context-bus/long-term-memory.ts +108 -0
- package/src/dashboard/index.ts +9 -4
- package/src/dashboard/slash-runtime/dashboard-handlers.ts +7 -1
- package/src/decisions/decision-cards.ts +10 -3
- package/src/decisions/decision-ledger.ts +13 -5
- package/src/discord/sprint21-runtime.ts +5 -1
- package/src/discord-self-message.ts +32 -0
- package/src/discord-slash-wire.ts +5 -1
- package/src/discord.ts +17 -1
- package/src/domains/core-tools.ts +3 -2
- package/src/domains/outbound-alert.ts +6 -1
- package/src/domains/telegram-kind-route.ts +51 -13
- package/src/exec-requests/default-outputs.ts +25 -0
- package/src/exec-requests/planner.ts +10 -2
- package/src/exec-requests/runner.ts +20 -6
- package/src/exec-requests/store.ts +3 -0
- package/src/execution-loop/launch-gate.ts +100 -0
- package/src/field/field-reel.ts +5 -1
- package/src/field-note/index.ts +201 -0
- package/src/field-note/transcribe.ts +248 -0
- package/src/graph-kinds/registry.ts +3 -3
- package/src/graph-runner/graph-cli.ts +61 -1
- package/src/graph-runner/graph-grow-llm.ts +37 -0
- package/src/graph-runner/graph-grow.ts +47 -0
- package/src/graph-runner/runner.ts +317 -25
- package/src/grok/agent-search.ts +8 -2
- package/src/guardian/secret-exposure-scan.ts +101 -0
- package/src/harness/harness-cli-command.ts +247 -7
- package/src/harness/harness-pod-dispatch.ts +43 -23
- package/src/harness/harness-seams.ts +38 -4
- package/src/harness/harness-stop.ts +23 -4
- package/src/harness/launch-registry.ts +91 -0
- package/src/harness/process-garbage.ts +5 -3
- package/src/hooks/dispatch.ts +82 -0
- package/src/hooks/expose.ts +254 -0
- package/src/hooks/github-shadow.ts +108 -0
- package/src/hooks/providers.ts +71 -5
- package/src/hooks/queue.ts +1 -1
- package/src/hooks/receiver.ts +21 -20
- package/src/index.ts +52 -14
- package/src/intake-plane/categorize.ts +18 -46
- package/src/intake-plane/discord-seat-work.ts +10 -0
- package/src/intake-plane/front-route-classifier.ts +33 -39
- package/src/intake-plane/persona-answer.ts +30 -0
- package/src/intake-plane/runtime-callables.ts +8 -1
- package/src/intake-plane/telegram-seat-work.ts +36 -2
- package/src/intake-plane/wish-folder.ts +67 -0
- package/src/intent-gate/gate.ts +30 -10
- package/src/live/detail-switch.ts +5 -0
- package/src/llm/difficulty.ts +57 -0
- package/src/llm/judge-layer.ts +101 -0
- package/src/llm/mission-router.ts +33 -19
- package/src/loops/contract/examples/cmo-seat.loop.yaml +51 -0
- package/src/loops/contract/examples/orchestrator.loop.yaml +57 -0
- package/src/loops/contract/examples/steward.loop.yaml +50 -0
- package/src/loops/contract/loop-agent.schema.json +138 -0
- package/src/loops/contract/validate.ts +64 -0
- package/src/loops/registry.ts +20 -6
- package/src/market/signed-index.ts +4 -0
- package/src/maturity/bot-command-maturity.ts +45 -0
- package/src/maturity/feature-maturity.ts +26 -4
- package/src/model-tier/index.ts +2 -2
- package/src/model-tier/tier-resolver.ts +20 -20
- package/src/model-tier/types.ts +6 -6
- package/src/mss/logging/log-store.ts +15 -0
- package/src/nexus/api/config-model-tier.ts +5 -4
- package/src/nexus/api/fabric-plans.ts +53 -0
- package/src/nexus/api/harness-api.ts +5 -1
- package/src/nexus/api/health.ts +2 -0
- package/src/nexus/api/http-server.ts +36 -0
- package/src/nexus/api/inside-events.ts +226 -0
- package/src/nexus/api/meta-api.ts +21 -8
- package/src/nexus/api/missions.ts +6 -1
- package/src/nexus/api/ops-seats.ts +33 -0
- package/src/nexus/api/outputs-route.ts +44 -0
- package/src/nexus/api/seat-requests.ts +44 -2
- package/src/nexus/api/sessions-store.ts +17 -38
- package/src/nexus/api/sub-seat-charters.ts +34 -0
- package/src/nexus/api/tabs-mutations.ts +3 -1
- package/src/nexus/api/trace.ts +18 -6
- package/src/nexus/api/workflow-run-event-bridge.ts +1 -0
- package/src/nexus/api/workflows.ts +80 -6
- package/src/nexus/index.ts +2 -0
- package/src/nexus/kinds/webterm.ts +2 -1
- package/src/nexus/webterm/pty.ts +6 -2
- package/src/onboarding/cli-auth-status.ts +80 -0
- package/src/onboarding/voice-ai.ts +3 -3
- package/src/org/seat-budget.ts +48 -0
- package/src/org/stall-escalation.ts +63 -0
- package/src/outputs/ledger.ts +120 -0
- package/src/persona/persona-todo.ts +79 -0
- package/src/persona/presets.ts +116 -2
- package/src/persona/team-set.ts +155 -0
- package/src/plugins/install/plugin-install.ts +14 -0
- package/src/plugins/maker/market-bundle.ts +109 -0
- package/src/plugins/maker/plugin-maker.ts +254 -11
- package/src/plugins/maker/wizard-generate.ts +103 -0
- package/src/pod-lease/admission.ts +150 -0
- package/src/pod-lease/dependency-state.ts +85 -0
- package/src/pod-lease/host-lease.ts +127 -0
- package/src/project/project-suggestion.ts +16 -0
- package/src/project/session-context.ts +24 -0
- package/src/release-loop/checklist.ts +2 -2
- package/src/release-loop/feature-store.ts +5 -3
- package/src/release-loop/next-md-merge.ts +58 -0
- package/src/release-loop/release-note.ts +59 -4
- package/src/seat-dispatch/seat-ask.ts +130 -0
- package/src/seat-dispatch/seat-questions.ts +100 -0
- package/src/seat-loop/seat-loop.ts +548 -29
- package/src/seat-loop/seat-report.ts +37 -2
- package/src/self-dev/dev-cli.ts +4 -1
- package/src/self-dev/dev-pipeline.ts +37 -1
- package/src/self-dev/draft-sweep.ts +38 -33
- package/src/self-dev/draft-triage-rules.ts +8 -5
- package/src/self-dev/fabric-plan-core.ts +297 -0
- package/src/self-dev/orchestrate.ts +36 -4
- package/src/self-dev/release-path-guard.ts +62 -0
- package/src/self-dev/shard-aggregate.ts +230 -0
- package/src/self-dev/shard-placement.ts +60 -0
- package/src/self-dev/shard-plan.ts +48 -0
- package/src/self-dev/shard-pod-run.ts +77 -0
- package/src/self-dev/shard-run.ts +105 -0
- package/src/self-implement/gate-baseline.ts +1 -1
- package/src/self-implement/gate-cli.ts +40 -1
- package/src/self-implement/gate-scope.ts +37 -7
- package/src/self-implement/graph-variant.ts +171 -0
- package/src/self-implement/harness-policy-gates.ts +1 -1
- package/src/self-implement/headless-elanous-driver.ts +22 -3
- package/src/self-implement/host-regate.ts +22 -1
- package/src/self-implement/importer-test-index.ts +2 -1
- package/src/self-implement/l8-merge-queue.ts +130 -0
- package/src/self-implement/orchestrator.ts +242 -9
- package/src/self-implement/route-consumer-test-index.ts +122 -0
- package/src/self-implement/seams.ts +72 -11
- package/src/self-implement/test-seams.ts +1 -0
- package/src/self-implement/uncommitted-work.ts +59 -0
- package/src/session/index.ts +36 -13
- package/src/skills/gift-install.ts +215 -0
- package/src/skills/tools/web-search.ts +4 -1
- package/src/steward/launch.ts +42 -26
- package/src/steward/steward-cards.ts +17 -9
- package/src/steward/triage.ts +46 -14
- package/src/task-cards/card-cli.ts +25 -1
- package/src/task-orchestrator/mission.ts +5 -0
- package/src/task-orchestrator/store.ts +12 -3
- package/src/task-orchestrator/surfaces/pod-command-job.ts +29 -7
- package/src/task-orchestrator/surfaces/pod-lease.ts +156 -19
- package/src/task-orchestrator/surfaces/pod-pool.ts +127 -26
- package/src/task-orchestrator/surfaces/self-implement-pod.ts +214 -40
- package/src/task-orchestrator/surfaces/self-implement.ts +15 -2
- package/src/task-orchestrator/types.ts +2 -0
- package/src/telegram-card-followup.ts +16 -96
- package/src/telegram-commands.ts +10 -1
- package/src/telegram-project-command.ts +71 -0
- package/src/telegram-report.ts +21 -17
- package/src/telegram.ts +29 -3
- package/src/tool-runtime/self-cognition-runtimes.ts +13 -3
- package/src/user-config.ts +102 -20
- package/src/version/packed-revision.json +1 -1
- package/src/web-search/grok.ts +7 -1
- package/src/web-search/index.ts +28 -1
- package/src/web-search/provider.ts +4 -0
- package/src/web-search/x-intent.ts +5 -0
- package/src/workflow-runtime/executor.ts +277 -47
- package/src/workflow-runtime/index.ts +1 -0
- package/src/workflow-runtime/nodes/subworkflow.ts +60 -0
- package/src/workflow-runtime/plugin-kind-node.ts +1 -1
- package/src/workflow-runtime/schema.ts +79 -4
- package/src/workflow-runtime/types.ts +35 -4
- package/apps/pwa/out/_next/static/2DsiDfDCks44g1cPUMhiW/_buildManifest.js +0 -1
- package/apps/pwa/out/_next/static/chunks/1105-c473ed46272fba79.js +0 -1
- package/apps/pwa/out/_next/static/chunks/1377-1efeffbbac0963ff.js +0 -1
- package/apps/pwa/out/_next/static/chunks/1470.98a6ab61ccb4131c.js +0 -1
- package/apps/pwa/out/_next/static/chunks/216-5acd01cbde4acda7.js +0 -1
- package/apps/pwa/out/_next/static/chunks/2330-c2f07246c8788af1.js +0 -1
- package/apps/pwa/out/_next/static/chunks/2375-cb6debea56cce4fb.js +0 -1
- package/apps/pwa/out/_next/static/chunks/24-e6d28380efab7faf.js +0 -1
- package/apps/pwa/out/_next/static/chunks/2977-e38442e86289f1d3.js +0 -1
- package/apps/pwa/out/_next/static/chunks/2982-2a2df543be3d2e5a.js +0 -25
- package/apps/pwa/out/_next/static/chunks/3403.4bc97b4066945a94.js +0 -5
- package/apps/pwa/out/_next/static/chunks/3615-740dd270764ffa24.js +0 -1
- package/apps/pwa/out/_next/static/chunks/371-4ad6af55dad02ced.js +0 -1
- package/apps/pwa/out/_next/static/chunks/3734-1015fe991eb9b7e7.js +0 -1
- package/apps/pwa/out/_next/static/chunks/4114-3e63117452378807.js +0 -1
- package/apps/pwa/out/_next/static/chunks/5012-a7fe6f3c8b6fe45a.js +0 -1
- package/apps/pwa/out/_next/static/chunks/5609-012bb3557211f07e.js +0 -1
- package/apps/pwa/out/_next/static/chunks/5783-ef40ebfc91d55230.js +0 -1
- package/apps/pwa/out/_next/static/chunks/5791-bb82743fa6299562.js +0 -1
- package/apps/pwa/out/_next/static/chunks/62-ff227c3edb8b248b.js +0 -1
- package/apps/pwa/out/_next/static/chunks/6320-baac91d68843a9a6.js +0 -1
- package/apps/pwa/out/_next/static/chunks/6725-68ab7cc0b1faf00d.js +0 -1
- package/apps/pwa/out/_next/static/chunks/6998-a654fe5c58271600.js +0 -1
- package/apps/pwa/out/_next/static/chunks/7633-1b3709b0854c9412.js +0 -1
- package/apps/pwa/out/_next/static/chunks/7647.2fcd30d894d5ee30.js +0 -1
- package/apps/pwa/out/_next/static/chunks/7673-2eda1507d38dadb8.js +0 -1
- package/apps/pwa/out/_next/static/chunks/7951-8b03dbb10b24cd06.js +0 -1
- package/apps/pwa/out/_next/static/chunks/7990-e12efba616f46e03.js +0 -1
- package/apps/pwa/out/_next/static/chunks/8142-744998d65d7bb17e.js +0 -1
- package/apps/pwa/out/_next/static/chunks/8195-6fde3d7a39859206.js +0 -10
- package/apps/pwa/out/_next/static/chunks/8619-4365e03a2862830f.js +0 -1
- package/apps/pwa/out/_next/static/chunks/8894-b5fb36bab837cd29.js +0 -1
- package/apps/pwa/out/_next/static/chunks/920-f7dceb78f1c585ef.js +0 -1
- package/apps/pwa/out/_next/static/chunks/9454-84d0d5d77446bd92.js +0 -1
- package/apps/pwa/out/_next/static/chunks/9651-3cd291a6fa1370d2.js +0 -1
- package/apps/pwa/out/_next/static/chunks/988-5f92e7ab7ccea3dd.js +0 -1
- package/apps/pwa/out/_next/static/chunks/9989-5582582f06429840.js +0 -1
- package/apps/pwa/out/_next/static/chunks/ae787e4c-f2998de7f1ba72a4.js +0 -1
- package/apps/pwa/out/_next/static/chunks/app/_not-found/page-859cea1570b6227a.js +0 -1
- package/apps/pwa/out/_next/static/chunks/app/approvals/page-d2253d7e58ef1890.js +0 -1
- package/apps/pwa/out/_next/static/chunks/app/autopilot/page-5441d4a9ab35e518.js +0 -1
- package/apps/pwa/out/_next/static/chunks/app/board/page-d9b12d680922d980.js +0 -1
- package/apps/pwa/out/_next/static/chunks/app/bots/page-e268d6d145827a22.js +0 -1
- package/apps/pwa/out/_next/static/chunks/app/chat/page-f8116559c7424da7.js +0 -1
- package/apps/pwa/out/_next/static/chunks/app/consult/page-1085399fd0f32112.js +0 -1
- package/apps/pwa/out/_next/static/chunks/app/control/page-1df686a14f65895a.js +0 -1
- package/apps/pwa/out/_next/static/chunks/app/design-check/page-54e1f966ab60a4dc.js +0 -1
- package/apps/pwa/out/_next/static/chunks/app/editor/page-7ed95f296f5ee8e9.js +0 -1
- package/apps/pwa/out/_next/static/chunks/app/exec/page-11edac668d77e5c3.js +0 -1
- package/apps/pwa/out/_next/static/chunks/app/field/page-59e2b9a22cd5a6d5.js +0 -1
- package/apps/pwa/out/_next/static/chunks/app/healthz/route-859cea1570b6227a.js +0 -1
- package/apps/pwa/out/_next/static/chunks/app/intake/page-2976df21ad74ab48.js +0 -1
- package/apps/pwa/out/_next/static/chunks/app/layout-34d211a67f16d510.js +0 -1
- package/apps/pwa/out/_next/static/chunks/app/live/page-8ff652d5d950639b.js +0 -1
- package/apps/pwa/out/_next/static/chunks/app/market/page-b31610deda76337b.js +0 -1
- package/apps/pwa/out/_next/static/chunks/app/missions/[id]/page-6cb0e1bbefe5fb3d.js +0 -1
- package/apps/pwa/out/_next/static/chunks/app/morning/page-a286a152cf584576.js +0 -1
- package/apps/pwa/out/_next/static/chunks/app/not-found-d9237581e7003bcb.js +0 -1
- package/apps/pwa/out/_next/static/chunks/app/observatory/page-83274e761643fdd2.js +0 -1
- package/apps/pwa/out/_next/static/chunks/app/ops/checklist/page-ceee6cfb1d4e6d68.js +0 -1
- package/apps/pwa/out/_next/static/chunks/app/ops/release/page-9c9f8bb3e4a64091.js +0 -1
- package/apps/pwa/out/_next/static/chunks/app/ops/seats/page-c17217603ea3426a.js +0 -1
- package/apps/pwa/out/_next/static/chunks/app/page-efb6177cbf1e8a51.js +0 -1
- package/apps/pwa/out/_next/static/chunks/app/reflection/page-d307523703bc4df3.js +0 -1
- package/apps/pwa/out/_next/static/chunks/app/scheduler/page-462f4e4bab45ce7d.js +0 -1
- package/apps/pwa/out/_next/static/chunks/app/sessions/page-8990e96f33af3837.js +0 -1
- package/apps/pwa/out/_next/static/chunks/app/settings/devices/page-e168fa1030af0548.js +0 -1
- package/apps/pwa/out/_next/static/chunks/app/settings/page-1233e05a4068bc9c.js +0 -1
- package/apps/pwa/out/_next/static/chunks/app/setup/done/page-13a1840b1fac337a.js +0 -1
- package/apps/pwa/out/_next/static/chunks/app/setup/layout-859cea1570b6227a.js +0 -1
- package/apps/pwa/out/_next/static/chunks/app/setup/page-64a29fc80b11ab55.js +0 -1
- package/apps/pwa/out/_next/static/chunks/app/share/page-68e787339a16b3dc.js +0 -1
- package/apps/pwa/out/_next/static/chunks/app/showroom/page-4fddc90b23feb215.js +0 -1
- package/apps/pwa/out/_next/static/chunks/app/tasks/page-886ba8260dc79c79.js +0 -1
- package/apps/pwa/out/_next/static/chunks/app/term/page-0f26507a1722e40b.js +0 -1
- package/apps/pwa/out/_next/static/chunks/app/today/page-109d4ccd42259c9d.js +0 -1
- package/apps/pwa/out/_next/static/chunks/app/trace/page-f5c2a4e510726774.js +0 -1
- package/apps/pwa/out/_next/static/chunks/app/vault/page-b2e0039416f42522.js +0 -1
- package/apps/pwa/out/_next/static/chunks/app/workflows/chat-ui/page-26102fd7350f171e.js +0 -1
- package/apps/pwa/out/_next/static/chunks/app/workflows/page-708948bc8a802794.js +0 -1
- package/apps/pwa/out/_next/static/chunks/app/workspace/page-5e5611620f78fb0b.js +0 -1
- package/apps/pwa/out/_next/static/chunks/app/worktrees/page-139ba5c367bbf60a.js +0 -1
- package/apps/pwa/out/_next/static/chunks/framework-ea806bb57f2b8923.js +0 -1
- package/apps/pwa/out/_next/static/chunks/main-8d2302399c2c8f87.js +0 -1
- package/apps/pwa/out/_next/static/chunks/main-app-202b4e81f33895ea.js +0 -1
- package/apps/pwa/out/_next/static/chunks/pages/_app-b10928c60f0b8488.js +0 -1
- package/apps/pwa/out/_next/static/chunks/pages/_error-689039227d443fab.js +0 -1
- package/apps/pwa/out/_next/static/chunks/webpack-e5bea36f183b25e6.js +0 -1
- package/apps/pwa/out/_next/static/css/43feca5fd387dcbd.css +0 -1
- /package/apps/pwa/out/_next/static/{2DsiDfDCks44g1cPUMhiW → Y4zKzL62sakG5momz3SoQ}/_ssgManifest.js +0 -0
package/src/user-config.ts
CHANGED
|
@@ -50,7 +50,7 @@ import type { SkillTier } from './skills/runner.js';
|
|
|
50
50
|
import { sharedAgentSkillRoots } from './skills/shared-agent-skill-roots.js';
|
|
51
51
|
import {
|
|
52
52
|
isModelTier,
|
|
53
|
-
|
|
53
|
+
isModelTierProfile,
|
|
54
54
|
type BudgetUserConfig,
|
|
55
55
|
type ModelTier,
|
|
56
56
|
type ModelTierUserConfig,
|
|
@@ -450,6 +450,8 @@ export interface SkillSource {
|
|
|
450
450
|
export interface SkillsConfig {
|
|
451
451
|
activeSet: SkillSetName;
|
|
452
452
|
dirs: string[];
|
|
453
|
+
/** Gift redemption API origin; defaults to https://elanous.ai. */
|
|
454
|
+
giftEndpoint?: string;
|
|
453
455
|
/** Include the existing shared ~/.agents/skills directory. Default true; false opts out. */
|
|
454
456
|
includeSharedAgentSkills?: boolean;
|
|
455
457
|
/**
|
|
@@ -766,6 +768,7 @@ function skillsDefaults(): SkillsConfig {
|
|
|
766
768
|
return {
|
|
767
769
|
activeSet: 'claudecode',
|
|
768
770
|
dirs: d ? [d] : [],
|
|
771
|
+
giftEndpoint: 'https://elanous.ai',
|
|
769
772
|
includeSharedAgentSkills: true,
|
|
770
773
|
allow: [],
|
|
771
774
|
deny: [],
|
|
@@ -912,8 +915,8 @@ export interface TelegramConfig {
|
|
|
912
915
|
/** 누가 Q&A 폴링을 하나 — 기본(없음·`'nexus'`)은 넥서스 데몬, `'standalone'` 이면
|
|
913
916
|
* 넥서스는 폴링하지 않고 `elanous telegram run` 이 맡는다. */
|
|
914
917
|
poller?: 'nexus' | 'standalone';
|
|
915
|
-
/**
|
|
916
|
-
*
|
|
918
|
+
/** 레거시 kind→역할 설정(읽기 호환). 선택한 채널의 봇이 kind 정책의
|
|
919
|
+
* 운영/매매 경계를 지킬 때만 발송 라우팅에 적용한다. */
|
|
917
920
|
kindRoles?: Record<string, string>;
|
|
918
921
|
/** `#현장` 캡션에 행사 슬러그가 없을 때 쓸 기본 행사(예: `marketers-night-2026-10`). 없으면 `field-<로컬 날짜>`. */
|
|
919
922
|
fieldDefaultEvent?: string;
|
|
@@ -2023,7 +2026,12 @@ function parseModelTierFieldOrUndefined(v: unknown): ModelTier | undefined {
|
|
|
2023
2026
|
function parseModelTierConfig(raw: unknown): ModelTierUserConfig | undefined {
|
|
2024
2027
|
if (!raw || typeof raw !== 'object' || Array.isArray(raw)) return undefined;
|
|
2025
2028
|
const r = raw as Record<string, unknown>;
|
|
2026
|
-
|
|
2029
|
+
// Compatibility is read-only: the normalized config and subsequent writes use profile.
|
|
2030
|
+
let profile = isModelTierProfile(r.profile) ? r.profile : undefined;
|
|
2031
|
+
if (r.profile === undefined && r.persona !== undefined) {
|
|
2032
|
+
debug.log('config', 'deprecated-key', { from: 'modelTier.persona', to: 'modelTier.profile' });
|
|
2033
|
+
if (isModelTierProfile(r.persona)) profile = r.persona;
|
|
2034
|
+
}
|
|
2027
2035
|
const preset = typeof r.preset === 'string' && r.preset.trim().length > 0
|
|
2028
2036
|
? r.preset.trim()
|
|
2029
2037
|
: undefined;
|
|
@@ -2057,7 +2065,7 @@ function parseModelTierConfig(raw: unknown): ModelTierUserConfig | undefined {
|
|
|
2057
2065
|
const embedding = parseModelTierFieldOrUndefined(r.embedding);
|
|
2058
2066
|
const vision = parseModelTierFieldOrUndefined(r.vision);
|
|
2059
2067
|
const out: ModelTierUserConfig = {
|
|
2060
|
-
...spreadIfDefined('
|
|
2068
|
+
...spreadIfDefined('profile', profile),
|
|
2061
2069
|
...spreadIfDefined('preset', preset),
|
|
2062
2070
|
...spreadIfDefined('voice', voice),
|
|
2063
2071
|
...spreadIfDefined('llm', llm),
|
|
@@ -3429,7 +3437,9 @@ export interface RoleLlmResolveOptions {
|
|
|
3429
3437
|
* ⛔ 아무 override 도 없으면 ③~⑥ 만 타므로 산출이 종전과 «같다»(§4f 불변식 · NL 진입 무변경). */
|
|
3430
3438
|
export function resolveRoleLlm(role: ModelRole, opts: RoleLlmResolveOptions = {}): RoleLlmResolution {
|
|
3431
3439
|
const config = opts.config ?? getUserConfig();
|
|
3432
|
-
|
|
3440
|
+
// 전역 provider 는 필요할 때만 푼다 — 역할이 provider 를 명시했으면 전역 provider 가 없어도 해석된다.
|
|
3441
|
+
let activeProvider: LLMProviderName | undefined;
|
|
3442
|
+
const globalProvider = (): LLMProviderName => (activeProvider ??= resolveActiveProvider(config));
|
|
3433
3443
|
// 명시 인자가 있으면 그것이 진실 — 없을 때만 발사 시점에 정해진 값을 읽는다(둘 다 source='flag').
|
|
3434
3444
|
const flagSpec = (opts.overrides ?? launchRoleLlmOverrides)?.[role];
|
|
3435
3445
|
const layers: ReadonlyArray<readonly [RoleLlmSpec | undefined, RoleLlmSource]> = [
|
|
@@ -3438,7 +3448,7 @@ export function resolveRoleLlm(role: ModelRole, opts: RoleLlmResolveOptions = {}
|
|
|
3438
3448
|
];
|
|
3439
3449
|
for (const [spec, source] of layers) {
|
|
3440
3450
|
if (!spec) continue;
|
|
3441
|
-
const provider = spec.provider ?? globalProvider;
|
|
3451
|
+
const provider = spec.provider ?? globalProvider();
|
|
3442
3452
|
const pinned = spec.model?.trim();
|
|
3443
3453
|
let resolution: RoleLlmResolution | undefined;
|
|
3444
3454
|
if (pinned) resolution = { model: pinned, provider, ...(spec.tier ? { tier: spec.tier } : {}), source };
|
|
@@ -3447,7 +3457,7 @@ export function resolveRoleLlm(role: ModelRole, opts: RoleLlmResolveOptions = {}
|
|
|
3447
3457
|
if (resolution) { observeRoleLlm(role, resolution, spec); return resolution; }
|
|
3448
3458
|
// 세 칸이 «다 비었으면» 아래 층으로 흘린다 — 빈 칸은 선언이 아니다.
|
|
3449
3459
|
}
|
|
3450
|
-
const baseline = resolveRoleLlmBaseline(role, config, globalProvider);
|
|
3460
|
+
const baseline = resolveRoleLlmBaseline(role, config, globalProvider());
|
|
3451
3461
|
if (opts.overrides || launchRoleLlmOverrides || config.roleLlm?.[role]) observeRoleLlm(role, baseline, flagSpec);
|
|
3452
3462
|
return baseline;
|
|
3453
3463
|
}
|
|
@@ -3463,17 +3473,49 @@ export function resolveRoleModel(role: ModelRole, config: UserConfig = getUserCo
|
|
|
3463
3473
|
}
|
|
3464
3474
|
|
|
3465
3475
|
|
|
3476
|
+
export type StewardLoopMode = 'off' | 'shadow' | 'live';
|
|
3477
|
+
|
|
3466
3478
|
export type SeatLoopMode = 'off' | 'shadow' | 'on';
|
|
3467
3479
|
|
|
3480
|
+
export interface PersonaLoopConfig { enabled: boolean }
|
|
3481
|
+
|
|
3468
3482
|
export interface SeatLoopConfig {
|
|
3469
3483
|
/** No seat actions by default; shadow observes without execution, on permits the seat loop to act. */
|
|
3470
3484
|
mode: SeatLoopMode;
|
|
3485
|
+
/** Seat-to-seat and human questions default to shadow even when the checklist loop is on. */
|
|
3486
|
+
questions?: 'shadow' | 'on';
|
|
3471
3487
|
seats?: string[];
|
|
3472
3488
|
podPool?: string;
|
|
3473
3489
|
reportPr?: number;
|
|
3490
|
+
/** Parent routing and age limits for checklist stalls; omitted values use findStalls defaults. */
|
|
3491
|
+
stall?: { parents?: Record<string, string>; redMinutes?: number; blockedMinutes?: number };
|
|
3492
|
+
}
|
|
3493
|
+
|
|
3494
|
+
export type EventSeat = 'OP' | 'TC' | 'MK' | 'UX';
|
|
3495
|
+
export interface EventRoute { source: 'linear' | 'asana' | 'github'; kind: string; seat: EventSeat; loop: 'seat' }
|
|
3496
|
+
export interface EventsConfig { mode: 'shadow' | 'on'; routes: EventRoute[]; linearAssignees: Record<string, EventSeat> }
|
|
3497
|
+
|
|
3498
|
+
export function parseEventsConfig(input: unknown): EventsConfig {
|
|
3499
|
+
const events = input && typeof input === 'object' && !Array.isArray(input) ? input as Record<string, unknown> : {};
|
|
3500
|
+
const routes: EventRoute[] = [];
|
|
3501
|
+
const linearAssignees: Record<string, EventSeat> = Object.create(null);
|
|
3502
|
+
if (events.linearAssignees && typeof events.linearAssignees === 'object' && !Array.isArray(events.linearAssignees)) {
|
|
3503
|
+
for (const [id, seat] of Object.entries(events.linearAssignees)) {
|
|
3504
|
+
if (id.trim() && (seat === 'OP' || seat === 'TC' || seat === 'MK' || seat === 'UX')) linearAssignees[id] = seat;
|
|
3505
|
+
}
|
|
3506
|
+
}
|
|
3507
|
+
if (Array.isArray(events.routes)) for (const value of events.routes) {
|
|
3508
|
+
if (!value || typeof value !== 'object' || Array.isArray(value)) continue;
|
|
3509
|
+
const route = value as Record<string, unknown>;
|
|
3510
|
+
if ((route.source === 'linear' || route.source === 'asana' || route.source === 'github') && typeof route.kind === 'string' && route.kind.trim()
|
|
3511
|
+
&& (route.seat === 'OP' || route.seat === 'TC' || route.seat === 'MK' || route.seat === 'UX') && route.loop === 'seat')
|
|
3512
|
+
routes.push({ source: route.source, kind: route.kind, seat: route.seat, loop: route.loop });
|
|
3513
|
+
}
|
|
3514
|
+
return { mode: events.mode === 'on' ? 'on' : 'shadow', routes, linearAssignees };
|
|
3474
3515
|
}
|
|
3475
3516
|
|
|
3476
3517
|
export interface UserConfig {
|
|
3518
|
+
events?: EventsConfig;
|
|
3477
3519
|
/** Explicit HTTPS destination for doctor diagnostics; absent means no upload. */
|
|
3478
3520
|
diagnostics?: { uploadUrl?: string };
|
|
3479
3521
|
/** Root CLI help audience; absent or invalid means owner. */
|
|
@@ -3482,12 +3524,14 @@ export interface UserConfig {
|
|
|
3482
3524
|
hitl?: { executionDeadlineMinutes?: number };
|
|
3483
3525
|
coo?: { linearProject?: string };
|
|
3484
3526
|
decisions?: { linearProjection: { enabled: boolean } };
|
|
3527
|
+
/** Per-seat goal and Pod limits; missing or invalid limits use seat-budget defaults. */
|
|
3528
|
+
org?: { budget?: Record<string, { dailyGoals?: number; concurrentPods?: number }> };
|
|
3485
3529
|
/** Steward and seat loops are parsed independently. An absent seat remains off. */
|
|
3486
|
-
loops?: { steward?: { mode?:
|
|
3530
|
+
loops?: { steward?: { mode?: StewardLoopMode; linearTeam?: string; roles?: Record<string, { maxConcurrent?: number }>; budget?: number; tracks?: Record<string, string>; alertAfterFailures?: number; launch?: 'off' | 'shadow' | 'live'; maxParallel?: number; podPool?: string }; seat?: SeatLoopConfig; persona?: PersonaLoopConfig };
|
|
3487
3531
|
/** 🔐 Pod 의 Grok API 키 과금은 명시 opt-in 만. 생략·잘못된 값은 false.
|
|
3488
3532
|
* budgetGate 와 같은 `harness` 객체다 — 중복 선언이면 뒤 타입이 앞을 지운다. */
|
|
3489
3533
|
harness?: { pod?: { grokApiKeyOptIn: boolean }; budgetGate?: HarnessBudgetGateConfig; defaultRepo?: string; substrate?: 'local' | 'pod'; podPool?: string; worktreeAddTimeoutSec?: number };
|
|
3490
|
-
/** ☸️ Pod 실행 칸 — `pool` = 기존 기본 풀(`컨텍스트[@ssh호스트][:상한]` 쉼표 · 앞이 우선). harness 실행은 인자·ELANOUS_POD_POOL·harness.podPool 다음으로 읽는다. */
|
|
3534
|
+
/** ☸️ Pod 실행 칸 — `pool` = 기존 기본 풀(`컨텍스트[@ssh호스트][:상한][#k3d-레지스트리:포트]` 쉼표 · 앞이 우선). harness 실행은 인자·ELANOUS_POD_POOL·harness.podPool 다음으로 읽는다. */
|
|
3491
3535
|
pod?: { pool?: string; /** 호스트 Git 미러 디렉터리 — Pod Job 에 읽기 전용으로 마운트한다. */ hostMirror?: string; /** 원격 그라운딩 엔드포인트(호스트 nexus · tailnet 주소) — Pod 가 토큰으로 «질의→인용»만 묻는다(P13). */ groundingUrl?: string; /** 읽기 전용 Pod lease 권장에 쓰는 계정별 동시 수. */ lease?: { perAccount?: number } };
|
|
3492
3536
|
skillRouter: SkillRouterConfig;
|
|
3493
3537
|
llm: LLMConfig;
|
|
@@ -3815,7 +3859,7 @@ function defaultConfig(): UserConfig {
|
|
|
3815
3859
|
cli: { helpRole: 'owner' },
|
|
3816
3860
|
coo: { linearProject: '외부 행정·큰 일 (COO)' },
|
|
3817
3861
|
decisions: { linearProjection: { enabled: false } },
|
|
3818
|
-
loops: { seat: { mode: 'off', seats: ['MK'], podPool: 'pool-node-b@node-b:8' } },
|
|
3862
|
+
loops: { steward: { mode: 'shadow' }, seat: { mode: 'off', questions: 'shadow', seats: ['MK'], podPool: 'pool-node-b@node-b:8' }, persona: { enabled: false } },
|
|
3819
3863
|
skillRouter: { ...SR_DEFAULTS },
|
|
3820
3864
|
llm: { ...LLM_DEFAULTS },
|
|
3821
3865
|
skills: skillsDefaults(),
|
|
@@ -4296,7 +4340,7 @@ function parseStewardTracks(input: unknown): Record<string, string> | undefined
|
|
|
4296
4340
|
}
|
|
4297
4341
|
|
|
4298
4342
|
function parseSeatLoopsConfig(input: unknown): SeatLoopConfig {
|
|
4299
|
-
const defaults: SeatLoopConfig = { mode: 'off', seats: ['MK'], podPool: 'pool-node-b@node-b:8' };
|
|
4343
|
+
const defaults: SeatLoopConfig = { mode: 'off', questions: 'shadow', seats: ['MK'], podPool: 'pool-node-b@node-b:8' };
|
|
4300
4344
|
if (!input || typeof input !== 'object' || Array.isArray(input)) return defaults;
|
|
4301
4345
|
const seat = (input as Record<string, unknown>).seat;
|
|
4302
4346
|
if (!seat || typeof seat !== 'object' || Array.isArray(seat)) return defaults;
|
|
@@ -4304,20 +4348,35 @@ function parseSeatLoopsConfig(input: unknown): SeatLoopConfig {
|
|
|
4304
4348
|
const mode = values.mode;
|
|
4305
4349
|
return {
|
|
4306
4350
|
mode: mode === 'on' || mode === 'shadow' ? mode : 'off',
|
|
4351
|
+
questions: values.questions === 'on' ? 'on' : 'shadow',
|
|
4307
4352
|
seats: Array.isArray(values.seats) && values.seats.length > 0
|
|
4308
4353
|
&& values.seats.every((value) => typeof value === 'string' && /^(?:MK|OP|TC|UX)$/.test(value))
|
|
4309
4354
|
? [...new Set(values.seats as string[])] : ['MK'],
|
|
4310
4355
|
podPool: typeof values.podPool === 'string' && values.podPool.trim() ? values.podPool.trim() : defaults.podPool,
|
|
4311
4356
|
...(typeof values.reportPr === 'number' && Number.isSafeInteger(values.reportPr) && values.reportPr > 0
|
|
4312
4357
|
? { reportPr: values.reportPr } : {}),
|
|
4358
|
+
...(() => {
|
|
4359
|
+
const stall = values.stall;
|
|
4360
|
+
if (!stall || typeof stall !== 'object' || Array.isArray(stall)) return {};
|
|
4361
|
+
const raw = stall as Record<string, unknown>;
|
|
4362
|
+
const parents = raw.parents && typeof raw.parents === 'object' && !Array.isArray(raw.parents)
|
|
4363
|
+
? Object.fromEntries(Object.entries(raw.parents).filter(([from, to]) =>
|
|
4364
|
+
/^(?:MK|OP|TC|UX)$/.test(from) && typeof to === 'string' && /^(?:MK|OP|TC|UX)$/.test(to) && from !== to))
|
|
4365
|
+
: undefined;
|
|
4366
|
+
const minutes = (value: unknown): value is number => typeof value === 'number' && Number.isFinite(value) && value >= 0;
|
|
4367
|
+
return { stall: {
|
|
4368
|
+
...(parents ? { parents } : {}),
|
|
4369
|
+
...(minutes(raw.redMinutes) ? { redMinutes: raw.redMinutes } : {}),
|
|
4370
|
+
...(minutes(raw.blockedMinutes) ? { blockedMinutes: raw.blockedMinutes } : {}),
|
|
4371
|
+
} };
|
|
4372
|
+
})(),
|
|
4313
4373
|
};
|
|
4314
4374
|
}
|
|
4315
4375
|
|
|
4316
4376
|
function parseStewardLoopsConfig(input: unknown): UserConfig['loops'] {
|
|
4317
|
-
|
|
4318
|
-
const value =
|
|
4319
|
-
|
|
4320
|
-
const s = value as Record<string, unknown>;
|
|
4377
|
+
const loops = input && typeof input === 'object' && !Array.isArray(input) ? input as Record<string, unknown> : {};
|
|
4378
|
+
const value = loops.steward;
|
|
4379
|
+
const s = value && typeof value === 'object' && !Array.isArray(value) ? value as Record<string, unknown> : {};
|
|
4321
4380
|
const roles: NonNullable<NonNullable<UserConfig['loops']>['steward']>['roles'] = {};
|
|
4322
4381
|
if (s.roles && typeof s.roles === 'object' && !Array.isArray(s.roles)) {
|
|
4323
4382
|
for (const [role, entry] of Object.entries(s.roles)) {
|
|
@@ -4327,8 +4386,9 @@ function parseStewardLoopsConfig(input: unknown): UserConfig['loops'] {
|
|
|
4327
4386
|
}
|
|
4328
4387
|
}
|
|
4329
4388
|
return { steward: {
|
|
4330
|
-
mode: s.mode === '
|
|
4331
|
-
|
|
4389
|
+
mode: s.mode === 'off' || s.mode === 'shadow' || s.mode === 'live' ? s.mode :
|
|
4390
|
+
s.launch === 'off' || s.launch === 'shadow' || s.launch === 'live' ? s.launch : 'shadow',
|
|
4391
|
+
// A valid legacy launch setting remains effective when mode is absent; explicit mode always wins.
|
|
4332
4392
|
...(s.launch === 'off' || s.launch === 'shadow' || s.launch === 'live' ? { launch: s.launch } : {}),
|
|
4333
4393
|
...(typeof s.maxParallel === 'number' && Number.isSafeInteger(s.maxParallel) && s.maxParallel > 0 ? { maxParallel: s.maxParallel } : {}),
|
|
4334
4394
|
...(typeof s.podPool === 'string' && s.podPool.trim() ? { podPool: s.podPool.trim() } : {}),
|
|
@@ -4450,8 +4510,22 @@ export function buildUserConfig(path: string = defaultPath()): UserConfig {
|
|
|
4450
4510
|
const rawNotifications = rawGlobalObj?.notifications ?? rawObj.notifications;
|
|
4451
4511
|
const autopilotConfig = parseAutopilotConfig(rawObj.autopilot);
|
|
4452
4512
|
const stewardLoops = parseStewardLoopsConfig(rawObj.loops);
|
|
4513
|
+
const orgRaw = rawObj.org && typeof rawObj.org === 'object' && !Array.isArray(rawObj.org) ? rawObj.org as Record<string, unknown> : {};
|
|
4514
|
+
const budgetRaw = orgRaw.budget && typeof orgRaw.budget === 'object' && !Array.isArray(orgRaw.budget) ? orgRaw.budget as Record<string, unknown> : {};
|
|
4515
|
+
const seatBudgets: NonNullable<NonNullable<UserConfig['org']>['budget']> = Object.create(null);
|
|
4516
|
+
for (const [seat, value] of Object.entries(budgetRaw)) {
|
|
4517
|
+
if (!seat || !value || typeof value !== 'object' || Array.isArray(value)) continue;
|
|
4518
|
+
const row = value as Record<string, unknown>;
|
|
4519
|
+
const dailyGoals = row.dailyGoals;
|
|
4520
|
+
const concurrentPods = row.concurrentPods;
|
|
4521
|
+
seatBudgets[seat] = {
|
|
4522
|
+
...(typeof dailyGoals === 'number' && Number.isSafeInteger(dailyGoals) && dailyGoals >= 0 ? { dailyGoals } : {}),
|
|
4523
|
+
...(typeof concurrentPods === 'number' && Number.isSafeInteger(concurrentPods) && concurrentPods >= 0 ? { concurrentPods } : {}),
|
|
4524
|
+
};
|
|
4525
|
+
}
|
|
4453
4526
|
|
|
4454
4527
|
return {
|
|
4528
|
+
...(Object.keys(seatBudgets).length ? { org: { budget: seatBudgets } } : {}),
|
|
4455
4529
|
pod: {
|
|
4456
4530
|
...(typeof legacyPod.pool === 'string' && legacyPod.pool.trim() ? { pool: legacyPod.pool.trim() } : {}),
|
|
4457
4531
|
...(typeof legacyPod.hostMirror === 'string' && legacyPod.hostMirror.trim() ? { hostMirror: legacyPod.hostMirror.trim() } : {}),
|
|
@@ -4583,6 +4657,7 @@ export function buildUserConfig(path: string = defaultPath()): UserConfig {
|
|
|
4583
4657
|
skills: {
|
|
4584
4658
|
activeSet: normalizeSkillSet(sk.activeSet),
|
|
4585
4659
|
dirs: strArray(sk.dirs, skillsDefaults().dirs),
|
|
4660
|
+
giftEndpoint: str(sk.giftEndpoint) ?? 'https://elanous.ai',
|
|
4586
4661
|
includeSharedAgentSkills: sk.includeSharedAgentSkills !== false,
|
|
4587
4662
|
...(() => { const sources = parsePersistedSkillSources(sk.sources, sk.connected); return sources ? { sources } : {}; })(),
|
|
4588
4663
|
allow: strArray(sk.allow, []),
|
|
@@ -5112,7 +5187,9 @@ export function buildUserConfig(path: string = defaultPath()): UserConfig {
|
|
|
5112
5187
|
coo: { linearProject: typeof (rawObj.coo as { linearProject?: unknown } | undefined)?.linearProject === 'string' && (rawObj.coo as { linearProject: string }).linearProject.trim()
|
|
5113
5188
|
? (rawObj.coo as { linearProject: string }).linearProject.trim() : '외부 행정·큰 일 (COO)' },
|
|
5114
5189
|
decisions: { linearProjection: { enabled: ((rawObj.decisions as { linearProjection?: { enabled?: unknown } } | undefined)?.linearProjection?.enabled === true) } },
|
|
5115
|
-
loops: { ...(stewardLoops ?? {}), seat: parseSeatLoopsConfig(rawObj.loops)
|
|
5190
|
+
loops: { ...(stewardLoops ?? {}), seat: parseSeatLoopsConfig(rawObj.loops),
|
|
5191
|
+
persona: { enabled: (rawObj.loops as { persona?: { enabled?: unknown } } | undefined)?.persona?.enabled === true } },
|
|
5192
|
+
events: parseEventsConfig(rawObj.events),
|
|
5116
5193
|
// M1-1: sparse — undefined when the user hasn't set anything, so
|
|
5117
5194
|
// resolvers fall through to zero-config defaults.
|
|
5118
5195
|
...spreadIfDefined('modelTier', parseModelTierConfig(rawObj.modelTier)),
|
|
@@ -5692,6 +5769,8 @@ export function saveUserConfig(
|
|
|
5692
5769
|
? rawRest.autopilot as Record<string, unknown> : {};
|
|
5693
5770
|
const rawLoops = rawRest.loops && typeof rawRest.loops === 'object' && !Array.isArray(rawRest.loops)
|
|
5694
5771
|
? rawRest.loops as Record<string, unknown> : {};
|
|
5772
|
+
const rawSteward = rawLoops.steward && typeof rawLoops.steward === 'object' && !Array.isArray(rawLoops.steward)
|
|
5773
|
+
? rawLoops.steward as Record<string, unknown> : {};
|
|
5695
5774
|
if (cfg.loops) delete rawRest.loops;
|
|
5696
5775
|
if (cfg.pod?.hostMirror) {
|
|
5697
5776
|
const rawPod = rawRest.pod && typeof rawRest.pod === 'object' && !Array.isArray(rawRest.pod)
|
|
@@ -5711,8 +5790,10 @@ export function saveUserConfig(
|
|
|
5711
5790
|
...rawRest,
|
|
5712
5791
|
...(cfg.loops ? { loops: {
|
|
5713
5792
|
...rawLoops,
|
|
5793
|
+
...(cfg.loops.steward ? { steward: { ...rawSteward, mode: cfg.loops.steward.mode ?? cfg.loops.steward.launch ?? 'shadow' } } : {}),
|
|
5714
5794
|
...(cfg.loops.seat ? { seat: {
|
|
5715
5795
|
mode: cfg.loops.seat.mode,
|
|
5796
|
+
questions: cfg.loops.seat.questions ?? 'shadow',
|
|
5716
5797
|
seats: cfg.loops.seat.seats ?? ['MK'],
|
|
5717
5798
|
podPool: cfg.loops.seat.podPool ?? 'pool-node-b@node-b:8',
|
|
5718
5799
|
...(cfg.loops.seat.reportPr === undefined ? {} : { reportPr: cfg.loops.seat.reportPr }),
|
|
@@ -5783,6 +5864,7 @@ export function saveUserConfig(
|
|
|
5783
5864
|
skills: stripUndef({
|
|
5784
5865
|
activeSet: cfg.skills.activeSet,
|
|
5785
5866
|
dirs: [...cfg.skills.dirs],
|
|
5867
|
+
giftEndpoint: cfg.skills.giftEndpoint === 'https://elanous.ai' ? undefined : cfg.skills.giftEndpoint,
|
|
5786
5868
|
// EN5 — only connected roots are persisted (preset/shared/package are derived). The dev-only `connected` key is not written back.
|
|
5787
5869
|
sources: cfg.skills.sources && cfg.skills.sources.some((source) => source.kind === 'connected')
|
|
5788
5870
|
? cfg.skills.sources.filter((source) => source.kind === 'connected').map(({ id, path, enabled }) => ({ id, path, enabled }))
|
|
@@ -6039,7 +6121,7 @@ export function saveUserConfig(
|
|
|
6039
6121
|
...(cfg.tabs && Object.keys(cfg.tabs).length > 0 ? { tabs: cfg.tabs } : {}),
|
|
6040
6122
|
// M1-2b: sparse — emit only when explicitly set. Keeps Path-A-only
|
|
6041
6123
|
// users' file clean (no empty modelTier:{} blobs).
|
|
6042
|
-
...(cfg.modelTier ? { modelTier: cfg.modelTier } : {}),
|
|
6124
|
+
...(cfg.modelTier ? { modelTier: parseModelTierConfig(cfg.modelTier) } : {}),
|
|
6043
6125
|
...(cfg.sessionFabric ? { sessionFabric: cfg.sessionFabric } : {}),
|
|
6044
6126
|
...(cfg.nextFluent ? { nextFluent: cfg.nextFluent } : {}),
|
|
6045
6127
|
...(cfg.taste ? { taste: cfg.taste } : {}),
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"commit":"
|
|
1
|
+
{"commit":"e61a9846510a7f6ac0a0f223d8e4c8b384685df8"}
|
package/src/web-search/grok.ts
CHANGED
|
@@ -19,6 +19,7 @@
|
|
|
19
19
|
|
|
20
20
|
import { getGrokApiKey } from '../config.js';
|
|
21
21
|
import { grokAgentSearch, GROK_SEARCH_MODEL } from '../grok/agent-search.js';
|
|
22
|
+
import { wantsXSearch } from './x-intent.js';
|
|
22
23
|
import type { WebSearchHit, WebSearchProvider, WebSearchResult } from './provider.js';
|
|
23
24
|
|
|
24
25
|
const DEFAULT_LIMIT = 5;
|
|
@@ -52,10 +53,15 @@ export function buildGrokWebSearchProvider(): WebSearchProvider {
|
|
|
52
53
|
|
|
53
54
|
if (!r.ok) throw new Error(r.error ?? 'grok search failed');
|
|
54
55
|
|
|
55
|
-
const
|
|
56
|
+
const xSourceUrls = new Set(r.xSearchSources ?? []);
|
|
57
|
+
const citations = wantsXSearch(q.query)
|
|
58
|
+
? [...r.citations.filter(c => xSourceUrls.has(c.url)), ...r.citations.filter(c => !xSourceUrls.has(c.url))]
|
|
59
|
+
: r.citations;
|
|
60
|
+
const hits: WebSearchHit[] = citations.slice(0, limit).map(c => ({
|
|
56
61
|
url: c.url,
|
|
57
62
|
title: c.title ?? c.url,
|
|
58
63
|
snippet: '',
|
|
64
|
+
...(xSourceUrls.has(c.url) ? { xSearchSource: true } : {}),
|
|
59
65
|
}));
|
|
60
66
|
|
|
61
67
|
const note = r.text.length > 0 ? r.text.slice(0, 1500) : undefined;
|
package/src/web-search/index.ts
CHANGED
|
@@ -10,6 +10,8 @@ import { buildFirecrawlWebSearchProvider } from './firecrawl.js';
|
|
|
10
10
|
import { buildTavilyWebSearchProvider } from './tavily.js';
|
|
11
11
|
import { buildFreeWebSearchProvider } from './free.js';
|
|
12
12
|
import { isTavilySearchEnabled } from '../user-config.js';
|
|
13
|
+
import { debug } from '../debug/log.js';
|
|
14
|
+
import { wantsXSearch } from './x-intent.js';
|
|
13
15
|
import {
|
|
14
16
|
type WebSearchProvider,
|
|
15
17
|
type WebSearchQuery,
|
|
@@ -66,9 +68,14 @@ export async function searchWeb(
|
|
|
66
68
|
q: WebSearchQuery,
|
|
67
69
|
opts: { providerId?: string; signal?: AbortSignal } = {},
|
|
68
70
|
): Promise<WebSearchResult> {
|
|
71
|
+
const xIntent = !opts.providerId && wantsXSearch(q.query);
|
|
69
72
|
const candidates = opts.providerId
|
|
70
73
|
? providers.filter(p => p.id === opts.providerId)
|
|
71
74
|
: providers.filter(p => p.available());
|
|
75
|
+
if (xIntent) {
|
|
76
|
+
const grokIndex = candidates.findIndex(p => p.id === 'grok');
|
|
77
|
+
if (grokIndex > 0) candidates.unshift(...candidates.splice(grokIndex, 1));
|
|
78
|
+
}
|
|
72
79
|
if (candidates.length === 0) {
|
|
73
80
|
throw new WebSearchUnavailableError(
|
|
74
81
|
providers.map(p => p.id),
|
|
@@ -82,7 +89,27 @@ export async function searchWeb(
|
|
|
82
89
|
if (!provider.available()) continue;
|
|
83
90
|
tried.push(provider.id);
|
|
84
91
|
try {
|
|
85
|
-
|
|
92
|
+
const result = await provider.search(q, opts.signal);
|
|
93
|
+
if (!xIntent) return result;
|
|
94
|
+
if (provider.id === 'grok') {
|
|
95
|
+
const isXUrl = (raw: string): boolean => {
|
|
96
|
+
try {
|
|
97
|
+
const url = new URL(raw);
|
|
98
|
+
return url.protocol === 'https:' && ['x.com', 'www.x.com'].includes(url.hostname.toLowerCase());
|
|
99
|
+
} catch { return false; }
|
|
100
|
+
};
|
|
101
|
+
const hasXSource = result.hits.some(hit => hit.xSearchSource === true && isXUrl(hit.url));
|
|
102
|
+
if (hasXSource) {
|
|
103
|
+
debug.log('web-search.route', 'x-intent', { provider: provider.id, xIntent, fallback: false });
|
|
104
|
+
return { ...result, xSearch: 'grok' };
|
|
105
|
+
}
|
|
106
|
+
debug.log('web-search.route', 'x-intent', { provider: provider.id, xIntent, fallback: true });
|
|
107
|
+
const safeResult = { ...result };
|
|
108
|
+
delete safeResult.note;
|
|
109
|
+
return { ...safeResult, hits: result.hits.filter(hit => !isXUrl(hit.url)), xSearch: 'unavailable' };
|
|
110
|
+
}
|
|
111
|
+
debug.log('web-search.route', 'x-intent', { provider: provider.id, xIntent, fallback: true });
|
|
112
|
+
return { ...result, xSearch: 'unavailable' };
|
|
86
113
|
} catch (err: any) {
|
|
87
114
|
reasons.push(err?.message ?? String(err));
|
|
88
115
|
}
|
|
@@ -44,6 +44,8 @@ export interface WebSearchHit {
|
|
|
44
44
|
score?: number;
|
|
45
45
|
/** Unix ms timestamp of the page if the provider knows it. */
|
|
46
46
|
publishedAt?: number;
|
|
47
|
+
/** Whether this URL came from an actual Grok x_search_call. */
|
|
48
|
+
xSearchSource?: boolean;
|
|
47
49
|
/** Pass-through metadata (provider-specific). Callers shouldn't
|
|
48
50
|
* depend on specific keys. */
|
|
49
51
|
metadata?: Record<string, unknown>;
|
|
@@ -54,6 +56,8 @@ export interface WebSearchResult {
|
|
|
54
56
|
/** Which provider served this result. Included so the tool
|
|
55
57
|
* renderer can show "via grok" etc. */
|
|
56
58
|
providerName: string;
|
|
59
|
+
/** X-intent outcome; 'grok' requires an x_search_call with an x.com hit. Absent for ordinary or explicitly routed searches. */
|
|
60
|
+
xSearch?: 'grok' | 'unavailable';
|
|
57
61
|
/** Wall-clock ms the call took. Zero on cached results. */
|
|
58
62
|
durationMs: number;
|
|
59
63
|
/** Provider-level note the model might find useful (e.g., "rate
|
|
@@ -0,0 +1,5 @@
|
|
|
1
|
+
// Recognize explicit requests for X/Twitter sources, not incidental letters in words.
|
|
2
|
+
export function wantsXSearch(query: string): boolean {
|
|
3
|
+
return /(?:^|[^\p{L}\p{N}_])(?:x에서|엑스에서|x\s+(?:반응|여론)|트위터(?:에서|의|에|로|는|가)?|트윗(?:에서|의|을|이|들|은|도)?)(?![\p{L}\p{N}_])/iu.test(query)
|
|
4
|
+
|| /(?:^|[^\p{L}\p{N}_])(?:x\.com(?![\p{L}\p{N}_.-])|twitter(?:\.com)?(?![\p{L}\p{N}_])|on\s+x(?![\p{L}\p{N}_])|x\s+reactions?(?![\p{L}\p{N}_]))/iu.test(query);
|
|
5
|
+
}
|