elanous 0.2.5 → 0.2.7
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/.env.example +10 -7
- package/README.md +9 -4
- package/apps/pwa/out/404/index.html +1 -1
- package/apps/pwa/out/404.html +1 -1
- package/apps/pwa/out/_next/static/chunks/1105-c473ed46272fba79.js +1 -0
- package/apps/pwa/out/_next/static/chunks/1201-09613bce624467c0.js +1 -0
- package/apps/pwa/out/_next/static/chunks/1377-1efeffbbac0963ff.js +1 -0
- package/apps/pwa/out/_next/static/chunks/1470.98a6ab61ccb4131c.js +1 -0
- package/apps/pwa/out/_next/static/chunks/216-5acd01cbde4acda7.js +1 -0
- package/apps/pwa/out/_next/static/chunks/2330-c2f07246c8788af1.js +1 -0
- package/apps/pwa/out/_next/static/chunks/{5391-8793f88b03b30161.js → 2375-cb6debea56cce4fb.js} +1 -1
- package/apps/pwa/out/_next/static/chunks/{1751.50b96ea9c37b49b6.js → 2415.ed6428ff334c7ce2.js} +1 -1
- package/apps/pwa/out/_next/static/chunks/2929-617f1e66a55be184.js +1 -0
- package/apps/pwa/out/_next/static/chunks/2977-e38442e86289f1d3.js +1 -0
- package/apps/pwa/out/_next/static/chunks/2982-2a2df543be3d2e5a.js +25 -0
- package/apps/pwa/out/_next/static/chunks/{4daa2798-1363d725c79f3593.js → 2ea96958-e8c7e112de50b067.js} +1 -1
- package/apps/pwa/out/_next/static/chunks/3403.4bc97b4066945a94.js +5 -0
- package/apps/pwa/out/_next/static/chunks/3441-a1dd4acfeda14488.js +1 -0
- package/apps/pwa/out/_next/static/chunks/371-4ad6af55dad02ced.js +1 -0
- package/apps/pwa/out/_next/static/chunks/4114-3e63117452378807.js +1 -0
- package/apps/pwa/out/_next/static/chunks/{8617.465ca22a319c95b3.js → 4323.c5dfb6f503304775.js} +1 -1
- package/apps/pwa/out/_next/static/chunks/4836-2eba6079f31b88d4.js +1 -0
- package/apps/pwa/out/_next/static/chunks/{8918-482b30ce2a8ebf4c.js → 5080-1613752891fcadb4.js} +3 -3
- package/apps/pwa/out/_next/static/chunks/5609-012bb3557211f07e.js +1 -0
- package/apps/pwa/out/_next/static/chunks/{5348-bbf838e119661eee.js → 5791-bb82743fa6299562.js} +1 -1
- package/apps/pwa/out/_next/static/chunks/{9704-3221c102623c8d73.js → 6062-73e68343a9814f6a.js} +1 -1
- package/apps/pwa/out/_next/static/chunks/{4440-18bb160d95819f4e.js → 6090-85a3f05f954e5697.js} +1 -1
- package/apps/pwa/out/_next/static/chunks/6284-69db415193d5f8bd.js +1 -0
- package/apps/pwa/out/_next/static/chunks/6320-baac91d68843a9a6.js +1 -0
- package/apps/pwa/out/_next/static/chunks/6416-505ba707cacafbba.js +1 -0
- package/apps/pwa/out/_next/static/chunks/6725-68ab7cc0b1faf00d.js +1 -0
- package/apps/pwa/out/_next/static/chunks/6998-a654fe5c58271600.js +1 -0
- package/apps/pwa/out/_next/static/chunks/7647.2fcd30d894d5ee30.js +1 -0
- package/apps/pwa/out/_next/static/chunks/7673-2eda1507d38dadb8.js +1 -0
- package/apps/pwa/out/_next/static/chunks/7990-e12efba616f46e03.js +1 -0
- package/apps/pwa/out/_next/static/chunks/{f6f3850d-7f324c6566002113.js → 8046cadf-211ca3c0e00f2b72.js} +1 -1
- package/apps/pwa/out/_next/static/chunks/8067-f74bf14d67ad98f1.js +1 -0
- package/apps/pwa/out/_next/static/chunks/8142-744998d65d7bb17e.js +1 -0
- package/apps/pwa/out/_next/static/chunks/8519-f6b5d8a5833a7603.js +1 -0
- package/apps/pwa/out/_next/static/chunks/8619-4365e03a2862830f.js +1 -0
- package/apps/pwa/out/_next/static/chunks/8894-e92491a164192cc1.js +1 -0
- package/apps/pwa/out/_next/static/chunks/920-f7dceb78f1c585ef.js +1 -0
- package/apps/pwa/out/_next/static/chunks/9454-a3e0953307216c58.js +1 -0
- package/apps/pwa/out/_next/static/chunks/9651-3cd291a6fa1370d2.js +1 -0
- package/apps/pwa/out/_next/static/chunks/9740-67051141115ce775.js +1 -0
- package/apps/pwa/out/_next/static/chunks/9804-64c02c3c127d5014.js +1 -0
- package/apps/pwa/out/_next/static/chunks/ae787e4c-f2998de7f1ba72a4.js +1 -0
- package/apps/pwa/out/_next/static/chunks/app/_not-found/page-859cea1570b6227a.js +1 -0
- package/apps/pwa/out/_next/static/chunks/app/approvals/page-d5ebde04844689e6.js +1 -0
- package/apps/pwa/out/_next/static/chunks/app/autopilot/{page-f89e9a303515a033.js → page-10ed24f413ed66e9.js} +1 -1
- package/apps/pwa/out/_next/static/chunks/app/board/{page-4f403cd060442c95.js → page-211810b6c93ab66a.js} +1 -1
- package/apps/pwa/out/_next/static/chunks/app/botlab/{page-0ac5d053f0444d21.js → page-624f7a2f89b60c8f.js} +1 -1
- package/apps/pwa/out/_next/static/chunks/app/bots/page-5a5fb385a4df0ffe.js +1 -0
- package/apps/pwa/out/_next/static/chunks/app/chat/page-80497e93a878ddc5.js +1 -0
- package/apps/pwa/out/_next/static/chunks/app/consult/page-7457f52683562161.js +1 -0
- package/apps/pwa/out/_next/static/chunks/app/control/page-cee86394de407aa6.js +1 -0
- package/apps/pwa/out/_next/static/chunks/app/design-check/page-4ff8edab44196b8c.js +1 -0
- package/apps/pwa/out/_next/static/chunks/app/editor/page-92e4f44428d5e290.js +1 -0
- package/apps/pwa/out/_next/static/chunks/app/exec/page-b7dcf5d48a854b76.js +1 -0
- package/apps/pwa/out/_next/static/chunks/app/field/page-51480757e7d68b92.js +1 -0
- package/apps/pwa/out/_next/static/chunks/app/healthz/route-859cea1570b6227a.js +1 -0
- package/apps/pwa/out/_next/static/chunks/app/intake/page-2a05dfe80c8bdf16.js +1 -0
- package/apps/pwa/out/_next/static/chunks/app/layout-d9979633aa82f8e6.js +1 -0
- package/apps/pwa/out/_next/static/chunks/app/live/page-30533117beb53625.js +1 -0
- package/apps/pwa/out/_next/static/chunks/app/market/page-f7857826c2f97ad7.js +1 -0
- package/apps/pwa/out/_next/static/chunks/app/missions/[id]/page-07267f1391b96aba.js +1 -0
- package/apps/pwa/out/_next/static/chunks/app/morning/{page-bccce0babceae30f.js → page-55d50e9b0006a91d.js} +1 -1
- package/apps/pwa/out/_next/static/chunks/app/not-found-9699b1786be6171d.js +1 -0
- package/apps/pwa/out/_next/static/chunks/app/observatory/page-43dd772aee8af75f.js +1 -0
- package/apps/pwa/out/_next/static/chunks/app/page-a7e37af7d0399cb8.js +1 -0
- package/apps/pwa/out/_next/static/chunks/app/reflection/page-973ab7af59c718b7.js +1 -0
- package/apps/pwa/out/_next/static/chunks/app/scheduler/page-a9f8d3865b91e436.js +1 -0
- package/apps/pwa/out/_next/static/chunks/app/sessions/page-15e5a15db84c56aa.js +1 -0
- package/apps/pwa/out/_next/static/chunks/app/settings/devices/page-a2e572e4511f2a16.js +1 -0
- package/apps/pwa/out/_next/static/chunks/app/settings/page-dd107bf1c7d52a90.js +1 -0
- package/apps/pwa/out/_next/static/chunks/app/setup/done/page-d42b99cdfb9f27c6.js +1 -0
- package/apps/pwa/out/_next/static/chunks/app/setup/layout-859cea1570b6227a.js +1 -0
- package/apps/pwa/out/_next/static/chunks/app/setup/page-2764ff40dad5a995.js +1 -0
- package/apps/pwa/out/_next/static/chunks/app/share/page-c5f1152db116ff96.js +1 -0
- package/apps/pwa/out/_next/static/chunks/app/showroom/page-f933bca81ea38a6f.js +1 -0
- package/apps/pwa/out/_next/static/chunks/app/tasks/page-c1c95739c0bff3b8.js +1 -0
- package/apps/pwa/out/_next/static/chunks/app/term/page-a7aaffcf771662d8.js +1 -0
- package/apps/pwa/out/_next/static/chunks/app/trace/page-71d18eec33b9c667.js +1 -0
- package/apps/pwa/out/_next/static/chunks/app/vault/page-56adbe1a1f1379bd.js +1 -0
- package/apps/pwa/out/_next/static/chunks/app/workflows/chat-ui/page-2c4e59079ee357ac.js +1 -0
- package/apps/pwa/out/_next/static/chunks/app/workflows/page-a81f113f3ef89d72.js +1 -0
- package/apps/pwa/out/_next/static/chunks/app/workspace/page-5d422f38c052967e.js +1 -0
- package/apps/pwa/out/_next/static/chunks/app/worktrees/page-fc27b00e20733146.js +1 -0
- package/apps/pwa/out/_next/static/chunks/framework-ea806bb57f2b8923.js +1 -0
- package/apps/pwa/out/_next/static/chunks/main-8d2302399c2c8f87.js +1 -0
- package/apps/pwa/out/_next/static/chunks/main-app-6870f30ea99f8346.js +1 -0
- package/apps/pwa/out/_next/static/chunks/pages/_app-b10928c60f0b8488.js +1 -0
- package/apps/pwa/out/_next/static/chunks/pages/_error-689039227d443fab.js +1 -0
- package/apps/pwa/out/_next/static/chunks/{webpack-2bf59c720fe9542c.js → webpack-e5bea36f183b25e6.js} +1 -1
- package/apps/pwa/out/_next/static/css/f537bdb19c69306a.css +1 -0
- package/apps/pwa/out/_next/static/keajW7DDyghEs1y8oJe6T/_buildManifest.js +1 -0
- package/apps/pwa/out/approvals/index.html +1 -1
- package/apps/pwa/out/approvals/index.txt +22 -22
- package/apps/pwa/out/autopilot/index.html +1 -1
- package/apps/pwa/out/autopilot/index.txt +22 -22
- package/apps/pwa/out/board/index.html +1 -1
- package/apps/pwa/out/board/index.txt +22 -22
- package/apps/pwa/out/botlab/index.html +1 -1
- package/apps/pwa/out/botlab/index.txt +21 -21
- package/apps/pwa/out/bots/index.html +1 -1
- package/apps/pwa/out/bots/index.txt +21 -21
- package/apps/pwa/out/chat/index.html +1 -1
- package/apps/pwa/out/chat/index.txt +21 -21
- package/apps/pwa/out/consult/index.html +1 -0
- package/apps/pwa/out/consult/index.txt +32 -0
- package/apps/pwa/out/control/index.html +1 -1
- package/apps/pwa/out/control/index.txt +22 -22
- package/apps/pwa/out/design-check/index.html +1 -1
- package/apps/pwa/out/design-check/index.txt +22 -22
- package/apps/pwa/out/editor/index.html +1 -1
- package/apps/pwa/out/editor/index.txt +22 -22
- package/apps/pwa/out/exec/index.html +1 -0
- package/apps/pwa/out/exec/index.txt +32 -0
- package/apps/pwa/out/field/index.html +1 -0
- package/apps/pwa/out/field/index.txt +32 -0
- package/apps/pwa/out/healthz +1 -1
- package/apps/pwa/out/icons/elanous-16.png +0 -0
- package/apps/pwa/out/icons/elanous-180.png +0 -0
- package/apps/pwa/out/icons/elanous-192.png +0 -0
- package/apps/pwa/out/icons/elanous-32.png +0 -0
- package/apps/pwa/out/icons/elanous-512.png +0 -0
- package/apps/pwa/out/index.html +1 -1
- package/apps/pwa/out/index.txt +21 -21
- package/apps/pwa/out/intake/index.html +1 -1
- package/apps/pwa/out/intake/index.txt +22 -22
- package/apps/pwa/out/live/index.html +1 -1
- package/apps/pwa/out/live/index.txt +22 -22
- package/apps/pwa/out/market/index.html +1 -1
- package/apps/pwa/out/market/index.txt +21 -21
- package/apps/pwa/out/missions/placeholder/index.html +1 -1
- package/apps/pwa/out/missions/placeholder/index.txt +21 -21
- package/apps/pwa/out/morning/index.html +1 -1
- package/apps/pwa/out/morning/index.txt +22 -22
- package/apps/pwa/out/observatory/index.html +1 -1
- package/apps/pwa/out/observatory/index.txt +22 -22
- package/apps/pwa/out/reflection/index.html +1 -1
- package/apps/pwa/out/reflection/index.txt +22 -22
- package/apps/pwa/out/scheduler/index.html +1 -1
- package/apps/pwa/out/scheduler/index.txt +22 -22
- package/apps/pwa/out/sessions/index.html +1 -1
- package/apps/pwa/out/sessions/index.txt +21 -21
- package/apps/pwa/out/settings/devices/index.html +1 -1
- package/apps/pwa/out/settings/devices/index.txt +22 -22
- package/apps/pwa/out/settings/index.html +1 -1
- package/apps/pwa/out/settings/index.txt +22 -22
- package/apps/pwa/out/setup/done/index.html +1 -1
- package/apps/pwa/out/setup/done/index.txt +22 -22
- package/apps/pwa/out/setup/index.html +1 -1
- package/apps/pwa/out/setup/index.txt +22 -22
- package/apps/pwa/out/share/index.html +1 -1
- package/apps/pwa/out/share/index.txt +22 -22
- package/apps/pwa/out/showroom/index.html +1 -1
- package/apps/pwa/out/showroom/index.txt +21 -21
- package/apps/pwa/out/tasks/index.html +1 -1
- package/apps/pwa/out/tasks/index.txt +22 -22
- package/apps/pwa/out/term/index.html +1 -1
- package/apps/pwa/out/term/index.txt +22 -22
- package/apps/pwa/out/trace/index.html +1 -1
- package/apps/pwa/out/trace/index.txt +22 -22
- package/apps/pwa/out/vault/index.html +1 -1
- package/apps/pwa/out/vault/index.txt +22 -22
- package/apps/pwa/out/workflows/chat-ui/index.html +1 -1
- package/apps/pwa/out/workflows/chat-ui/index.txt +22 -22
- package/apps/pwa/out/workflows/index.html +1 -1
- package/apps/pwa/out/workflows/index.txt +22 -22
- package/apps/pwa/out/workspace/index.html +1 -1
- package/apps/pwa/out/workspace/index.txt +22 -22
- package/apps/pwa/out/worktrees/index.html +1 -1
- package/apps/pwa/out/worktrees/index.txt +22 -22
- package/bin/elanous.cjs +107 -0
- package/graphs/field/field-feed.yaml +24 -0
- package/graphs/field/recipes.yaml +12 -0
- package/graphs/landing/landing-heal.yaml +3 -1
- package/graphs/landing/recipes.yaml +3 -0
- package/graphs/release/recipes.yaml +13 -0
- package/graphs/release/release-loop.yaml +13 -4
- package/package.json +5 -5
- package/plugins/card-followup/README.md +42 -0
- package/plugins/card-followup/examples/card-sample.json +7 -0
- package/plugins/card-followup/graphs/card-followup.yaml +18 -0
- package/plugins/card-followup/graphs/recipes.yaml +16 -0
- package/plugins/card-followup/graphs/run-step.ts +276 -0
- package/plugins/card-followup/graphs/sales-strategy.ts +173 -0
- package/plugins/card-followup/plugin.json +25 -0
- package/plugins/doc-draft/README.md +13 -0
- package/plugins/doc-draft/examples/brief-sample.json +8 -0
- package/plugins/doc-draft/graphs/doc-draft.yaml +14 -0
- package/plugins/doc-draft/graphs/recipes.yaml +9 -0
- package/plugins/doc-draft/graphs/run-step.ts +113 -0
- package/plugins/doc-draft/plugin.json +24 -0
- package/plugins/geo-check/README.md +15 -0
- package/plugins/geo-check/examples/brand-sample.json +8 -0
- package/plugins/geo-check/graphs/geo-check.yaml +20 -0
- package/plugins/geo-check/graphs/recipes.yaml +18 -0
- package/plugins/geo-check/graphs/run-step.ts +198 -0
- package/plugins/geo-check/plugin.json +24 -0
- package/plugins/job-coach/.codex-plugin/plugin.json +1 -1
- package/plugins/job-coach/README.md +31 -1
- package/plugins/job-coach/graphs/run-step.ts +2 -2
- package/plugins/job-coach/plugin.json +1 -1
- package/plugins/job-coach/plugin.ts +1 -1
- package/scripts/affinity/endcard.sh +3 -2
- package/scripts/affinity/reframe.sh +3 -1
- package/scripts/ci-public-export-leak-gate.ts +48 -0
- package/scripts/codex-quota-alert.ts +122 -258
- package/scripts/coord-tracks.json +4 -4
- package/scripts/daemon-port-baseline.txt +1 -2
- package/scripts/field-feed/deliver-node.ts +52 -0
- package/scripts/field-feed/feed-node.ts +67 -0
- package/scripts/field-feed/lib.ts +162 -0
- package/scripts/field-feed/reel-node.ts +24 -0
- package/scripts/field-feed/start.ts +62 -0
- package/scripts/fixtures/vflow-sample.ndjson +6 -0
- package/scripts/install.sh +92 -13
- package/scripts/landing-heal/clean-checkout.ts +114 -0
- package/scripts/landing-heal/run-mission.ts +38 -3
- package/scripts/lib/android-test-device.ts +32 -0
- package/scripts/lib/pwa-scenarios/scenarios.ts +2 -1
- package/scripts/public-export.ts +8 -4
- package/scripts/release-loop/baseline-from-logs.ts +92 -0
- package/scripts/release-loop/checklist-gate-node.ts +35 -0
- package/scripts/release-loop/env-known-failures.ts +31 -0
- package/scripts/release-loop/gate-diff.ts +29 -0
- package/scripts/release-loop/gate-node.ts +124 -29
- package/scripts/release-loop/known-issues-node.ts +159 -0
- package/scripts/release-loop/npm-publish-node.ts +118 -0
- package/scripts/release-loop/ops-upgrade-node.ts +87 -0
- package/scripts/release-loop/release-readiness.ts +58 -0
- package/scripts/release-loop/shard-plan.ts +47 -0
- package/scripts/release-loop/unattended-release.ts +93 -0
- package/scripts/ux/measure-first-text.ts +102 -0
- package/scripts/ux/record-page.ts +4 -1
- package/scripts/vflow-collect.ts +20 -7
- package/scripts/vflow-search.ts +73 -0
- package/scripts/video-free-line-test-walker.ts +36 -0
- package/scripts/video-pipeline.ts +2 -2
- package/skills/explainer-video/SKILL.md +24 -3
- package/skills/explainer-video/engine/brand/elanous-mark-on-dark.svg +1 -1
- package/skills/explainer-video/engine/build.mjs +2 -2
- package/skills/explainer-video/engine/reel.mjs +235 -0
- package/skills/explainer-video/engine/reel.sh +9 -0
- package/skills/explainer-video/engine/vo.ts +58 -16
- package/skills/explainer-video/examples/elanous-0.2.5/script.json +1 -1
- package/skills/grill-me/SKILL.md +1 -1
- package/skills/omni-digest/docs/diagrams/noncode-terminal-promotion-path-2026-08-13.mmd +1 -1
- package/src/a2a/server.ts +2 -0
- package/src/acp/elanous-aware-peers.ts +30 -0
- package/src/acp/server.ts +91 -15
- package/src/agent/monad-agent-turn.ts +25 -6
- package/src/agent/shared-app-tools.ts +5 -3
- package/src/agent-substrate/review-intent.ts +6 -2
- package/src/agent-substrate/shard-boundary-intent.ts +70 -0
- package/src/auth/github-app-token.ts +4 -1
- package/src/autopilot/mission-origin.ts +20 -4
- package/src/autopilot/mission-phase-track.ts +11 -1
- package/src/autopilot/track-agent-shadow.ts +151 -0
- package/src/autopilot/track-agent.ts +26 -6
- package/src/autopilot/track-courier.ts +2 -2
- package/src/boot/acp-server-help.ts +16 -0
- package/src/boot/daemon-prompt-turn.ts +31 -10
- package/src/boot/daemon-tools/index.ts +7 -1
- package/src/budget/codex-credit-pace.ts +84 -0
- package/src/budget/codex-credit-plan.ts +154 -0
- package/src/budget/codex-reset-credit-state.ts +2 -0
- package/src/chat/chat-cli.ts +4 -1
- package/src/chat/short-question.ts +40 -0
- package/src/cli/agent-cli.ts +24 -15
- package/src/cli/ask-bare.ts +42 -0
- package/src/cli/cli-user-error.ts +25 -0
- package/src/cli/codex-credit-plan-view.ts +25 -0
- package/src/cli/dependence-gauge.ts +237 -0
- package/src/cli/doctor-cli.ts +5 -0
- package/src/cli/doctor-modes.ts +48 -0
- package/src/cli/intake-cli.ts +12 -2
- package/src/cli/intake-source-cli.ts +58 -0
- package/src/cli/machine-cli.ts +23 -0
- package/src/cli/msg-cli.ts +137 -0
- package/src/cli/nexus-ios-bind.ts +25 -8
- package/src/cli/phone-link.ts +117 -0
- package/src/cli/plugin-cli.ts +52 -0
- package/src/cli/pr-cli.ts +36 -0
- package/src/cli/private-ledger-commands.ts +31 -0
- package/src/cli/provider-cli.ts +5 -0
- package/src/cli/release-cli.ts +56 -12
- package/src/cli/release-run-if-ready.ts +48 -0
- package/src/cli/setup-cli.ts +27 -6
- package/src/cli/setup-recommend.ts +8 -0
- package/src/cli/usage-cli.ts +11 -1
- package/src/codex/setup.ts +27 -8
- package/src/dashboard/index.ts +1 -1
- package/src/discord.ts +56 -6
- package/src/domains/core-tools.ts +37 -14
- package/src/domains/outbound-alert.ts +55 -16
- package/src/exec-requests/planner.ts +140 -0
- package/src/exec-requests/runner.ts +338 -0
- package/src/exec-requests/store.ts +76 -0
- package/src/field/field-media.ts +250 -0
- package/src/field/field-reel.ts +196 -0
- package/src/grok/credential.ts +7 -5
- package/src/harness/aside-run-status.ts +33 -0
- package/src/harness/browser-verify.ts +48 -17
- package/src/harness/harness-cli-command.ts +25 -3
- package/src/harness/image-load-state.ts +21 -0
- package/src/harness/process-garbage.ts +45 -0
- package/src/index.ts +104 -38
- package/src/instance/leader.ts +13 -1
- package/src/intake-plane/collect-github.ts +5 -3
- package/src/intake-plane/collect-telegram-saved.ts +15 -3
- package/src/intake-plane/discord-seat-work.ts +56 -0
- package/src/intake-plane/intake-sources.ts +202 -0
- package/src/intake-plane/items.ts +28 -12
- package/src/intake-plane/seat-doc-route.ts +207 -0
- package/src/intake-plane/submit-intake-work.ts +9 -1
- package/src/intake-plane/telegram-seat-work.ts +72 -0
- package/src/llm/model-defaults.ts +24 -1
- package/src/llm.ts +5 -4
- package/src/machines/machine-ledger.ts +127 -0
- package/src/market/pack-internal-refs.ts +28 -0
- package/src/market/publish.ts +31 -4
- package/src/maturity/feature-maturity.ts +65 -0
- package/src/model-tier/turn-tier.ts +24 -0
- package/src/msg/msg-store.ts +149 -0
- package/src/native-tool-catalog.ts +2 -1
- package/src/nexus/api/chat-fast-path-config.ts +28 -0
- package/src/nexus/api/consult-requests.ts +117 -0
- package/src/nexus/api/discord-trigger-bot.ts +3 -0
- package/src/nexus/api/exec-requests.ts +51 -0
- package/src/nexus/api/field-uploads.ts +180 -0
- package/src/nexus/api/graph-approvals-feed.ts +140 -0
- package/src/nexus/api/graph-approvals.ts +120 -4
- package/src/nexus/api/harness-api.ts +219 -5
- package/src/nexus/api/http-server.ts +68 -5
- package/src/nexus/api/seat-requests.ts +254 -0
- package/src/nexus/api/trace-run-scan.ts +37 -0
- package/src/nexus/api/trace.ts +19 -3
- package/src/nexus/index.ts +3 -0
- package/src/nexus/setup-status.ts +4 -5
- package/src/notify/llm-budget-alert.ts +125 -0
- package/src/oauth/codex-account-rotation.ts +26 -4
- package/src/oauth/codex-account-store.ts +20 -2
- package/src/oauth/codex-browser-login.ts +173 -0
- package/src/oauth/codex.ts +4 -1
- package/src/oauth/fallback-chain.ts +5 -5
- package/src/oauth/store.ts +42 -5
- package/src/onboarding/continue-here.ts +29 -0
- package/src/onboarding/entry-hints.ts +8 -0
- package/src/onboarding/full-screen-io.ts +35 -3
- package/src/onboarding/help/skills.md +1 -1
- package/src/onboarding/non-interactive.ts +1 -0
- package/src/onboarding/subscription-hint.ts +27 -0
- package/src/onboarding/web-first.ts +83 -0
- package/src/onboarding.ts +230 -23
- package/src/plugins/maker/node-install.ts +92 -0
- package/src/plugins/maker/node-maker.ts +139 -0
- package/src/plugins/maker/plugin-maker.ts +220 -0
- package/src/policy/llm-policy.ts +268 -0
- package/src/prompt-library/session-guidance.ts +7 -1
- package/src/prompt-library/universal-preamble.ts +2 -2
- package/src/relay/channel.ts +184 -0
- package/src/relay/mux.ts +182 -0
- package/src/relay/relay-cli.ts +20 -0
- package/src/relay/relay-server.ts +220 -0
- package/src/relay/test-vectors.json +29 -0
- package/src/release-loop/checklist.ts +36 -9
- package/src/seat-address/seat-address.ts +34 -0
- package/src/self-dev/decompose.ts +1 -0
- package/src/self-dev/dev-pipeline.ts +6 -3
- package/src/self-dev/run-record-mirror.ts +44 -0
- package/src/self-dev/run-store.ts +12 -3
- package/src/self-implement/harness-policy-gates.ts +4 -1
- package/src/self-implement/report-origin.ts +12 -1
- package/src/self-implement/run-ledger-compact.ts +1 -1
- package/src/session/chat.ts +17 -5
- package/src/session/index.ts +23 -10
- package/src/skills/shared-agent-skill-roots.ts +25 -0
- package/src/steward/failure-streak.ts +78 -0
- package/src/steward/steward-cards.ts +24 -0
- package/src/steward/triage-budget.ts +127 -0
- package/src/steward/triage-plan.ts +75 -0
- package/src/steward/triage.ts +244 -42
- package/src/task-cards/card-store.ts +1 -1
- package/src/task-orchestrator/surfaces/pod-bun-cache.ts +18 -0
- package/src/task-orchestrator/surfaces/pod-command-job.ts +12 -3
- package/src/task-orchestrator/surfaces/pod-ledger-collect.ts +11 -5
- package/src/task-orchestrator/surfaces/pod-ledger-events.ts +68 -0
- package/src/task-orchestrator/surfaces/self-implement-pod.ts +78 -4
- package/src/telegram.ts +145 -2
- package/src/tool-runtime/elanous-skills-list-runtime.ts +3 -3
- package/src/tool-runtime/self-cognition-runtimes.ts +160 -2
- package/src/user-config.ts +84 -4
- package/src/version/packed-revision.json +1 -1
- package/src/video-pipeline/recipes/character.ts +42 -5
- package/src/video-pipeline/recipes/explainer.ts +213 -0
- package/src/video-pipeline/recipes/ffmpeg.ts +1 -1
- package/src/video-pipeline/recipes/free-line.ts +16 -3
- package/src/video-pipeline/recipes/remote.ts +7 -1
- package/src/video-pipeline/vflow-reference.ts +109 -0
- package/src/video-pipeline/walk-line.ts +3 -2
- package/apps/pwa/out/_next/static/chunks/06ef2eba-d1b99ac6d2ea663c.js +0 -1
- package/apps/pwa/out/_next/static/chunks/1413-7179a49332db5a80.js +0 -1
- package/apps/pwa/out/_next/static/chunks/150-25c277137a9638ab.js +0 -1
- package/apps/pwa/out/_next/static/chunks/1640-bc99ec23bbe29d12.js +0 -1
- package/apps/pwa/out/_next/static/chunks/2300-de059d0ab2a16630.js +0 -1
- package/apps/pwa/out/_next/static/chunks/2684-05b0a81e75298c16.js +0 -1
- package/apps/pwa/out/_next/static/chunks/3026-2ed7e317d9b02102.js +0 -25
- package/apps/pwa/out/_next/static/chunks/3611-77496ada38cd6358.js +0 -1
- package/apps/pwa/out/_next/static/chunks/3717-68957c4dc9ceec90.js +0 -1
- package/apps/pwa/out/_next/static/chunks/3929-46ba9af6f9d895cc.js +0 -1
- package/apps/pwa/out/_next/static/chunks/4015-62c5a3744698a8da.js +0 -1
- package/apps/pwa/out/_next/static/chunks/4217-3c4317a7905f9eeb.js +0 -1
- package/apps/pwa/out/_next/static/chunks/4240-3230f230fae2d7d5.js +0 -1
- package/apps/pwa/out/_next/static/chunks/4271-e53e075ebd48593b.js +0 -1
- package/apps/pwa/out/_next/static/chunks/4377.3b125fef79576dfd.js +0 -5
- package/apps/pwa/out/_next/static/chunks/4853-35fdbe6bdbcdc0fc.js +0 -1
- package/apps/pwa/out/_next/static/chunks/5007-6a3b30e23ff68a6e.js +0 -1
- package/apps/pwa/out/_next/static/chunks/5244-12b424c42070f5ff.js +0 -1
- package/apps/pwa/out/_next/static/chunks/5611-df00af3e4e4a61bb.js +0 -1
- package/apps/pwa/out/_next/static/chunks/5890-dca2321773be829a.js +0 -1
- package/apps/pwa/out/_next/static/chunks/6123-37c9dc57ddaa7ab0.js +0 -1
- package/apps/pwa/out/_next/static/chunks/6588-b7975304a302ab91.js +0 -1
- package/apps/pwa/out/_next/static/chunks/6604-c03961962b6273b6.js +0 -1
- package/apps/pwa/out/_next/static/chunks/7109-cf8c87e968e83a65.js +0 -1
- package/apps/pwa/out/_next/static/chunks/7178-30f77877525a2efb.js +0 -1
- package/apps/pwa/out/_next/static/chunks/7262-871563fc9663730b.js +0 -1
- package/apps/pwa/out/_next/static/chunks/7294-f0eeebb92aa93459.js +0 -1
- package/apps/pwa/out/_next/static/chunks/7429-881af44deed6958f.js +0 -1
- package/apps/pwa/out/_next/static/chunks/7527.943753b6ed829f09.js +0 -1
- package/apps/pwa/out/_next/static/chunks/764-a01e858525a190c0.js +0 -1
- package/apps/pwa/out/_next/static/chunks/7868-e35d5f7985ecd3f1.js +0 -1
- package/apps/pwa/out/_next/static/chunks/8320-51484af7b01fdfa5.js +0 -1
- package/apps/pwa/out/_next/static/chunks/9131-52f5fad51cceca04.js +0 -1
- package/apps/pwa/out/_next/static/chunks/9238.2cd5f47f4bf7a2c3.js +0 -1
- package/apps/pwa/out/_next/static/chunks/app/_not-found/page-70c404c7bb6d7f0f.js +0 -1
- package/apps/pwa/out/_next/static/chunks/app/approvals/page-3ffd80166b1050aa.js +0 -1
- package/apps/pwa/out/_next/static/chunks/app/bots/page-4bcc63e272ae8205.js +0 -1
- package/apps/pwa/out/_next/static/chunks/app/chat/page-880734bd07d62882.js +0 -1
- package/apps/pwa/out/_next/static/chunks/app/control/page-72bd384898d88955.js +0 -1
- package/apps/pwa/out/_next/static/chunks/app/design-check/page-1018bbc9586ecae5.js +0 -1
- package/apps/pwa/out/_next/static/chunks/app/editor/page-de86f8c38076dd7b.js +0 -1
- package/apps/pwa/out/_next/static/chunks/app/healthz/route-70c404c7bb6d7f0f.js +0 -1
- package/apps/pwa/out/_next/static/chunks/app/intake/page-cd6447196d8bafe6.js +0 -1
- package/apps/pwa/out/_next/static/chunks/app/layout-e733630c47fa102b.js +0 -1
- package/apps/pwa/out/_next/static/chunks/app/live/page-d1c1a8357b161875.js +0 -1
- package/apps/pwa/out/_next/static/chunks/app/market/page-60c514128e81d787.js +0 -1
- package/apps/pwa/out/_next/static/chunks/app/missions/[id]/page-8b637b7e325e13c1.js +0 -1
- package/apps/pwa/out/_next/static/chunks/app/not-found-63301d11dbe73836.js +0 -1
- package/apps/pwa/out/_next/static/chunks/app/observatory/page-a8cf0dc472060db2.js +0 -1
- package/apps/pwa/out/_next/static/chunks/app/page-02fba54881ccfa49.js +0 -1
- package/apps/pwa/out/_next/static/chunks/app/reflection/page-d5e8e90f0038f8de.js +0 -1
- package/apps/pwa/out/_next/static/chunks/app/scheduler/page-b1ef6824f494466a.js +0 -1
- package/apps/pwa/out/_next/static/chunks/app/sessions/page-d589bb0f233b1009.js +0 -1
- package/apps/pwa/out/_next/static/chunks/app/settings/devices/page-c9bbaebef4cda059.js +0 -1
- package/apps/pwa/out/_next/static/chunks/app/settings/page-3639ce7916b92fed.js +0 -1
- package/apps/pwa/out/_next/static/chunks/app/setup/done/page-7450ae7478955653.js +0 -1
- package/apps/pwa/out/_next/static/chunks/app/setup/layout-70c404c7bb6d7f0f.js +0 -1
- package/apps/pwa/out/_next/static/chunks/app/setup/page-b41ca4abfd618452.js +0 -1
- package/apps/pwa/out/_next/static/chunks/app/share/page-b333dd79ebee3fa9.js +0 -1
- package/apps/pwa/out/_next/static/chunks/app/showroom/page-8be1227492793655.js +0 -1
- package/apps/pwa/out/_next/static/chunks/app/tasks/page-6e03e9371b552e0d.js +0 -1
- package/apps/pwa/out/_next/static/chunks/app/term/page-911411e9fca18d03.js +0 -1
- package/apps/pwa/out/_next/static/chunks/app/trace/page-792170e649b37088.js +0 -1
- package/apps/pwa/out/_next/static/chunks/app/vault/page-c40463466937bc91.js +0 -1
- package/apps/pwa/out/_next/static/chunks/app/workflows/chat-ui/page-509c798b80384536.js +0 -1
- package/apps/pwa/out/_next/static/chunks/app/workflows/page-1cac2aa21d77c417.js +0 -1
- package/apps/pwa/out/_next/static/chunks/app/workspace/page-9626799d9b4a2cd1.js +0 -1
- package/apps/pwa/out/_next/static/chunks/app/worktrees/page-84cd419494e16b0f.js +0 -1
- package/apps/pwa/out/_next/static/chunks/framework-361487d2da603917.js +0 -1
- package/apps/pwa/out/_next/static/chunks/main-app-607f5beb94cb2e07.js +0 -1
- package/apps/pwa/out/_next/static/chunks/main-d0222d219e29dddf.js +0 -1
- package/apps/pwa/out/_next/static/chunks/pages/_app-a26980a31126decc.js +0 -1
- package/apps/pwa/out/_next/static/chunks/pages/_error-edb2b37decf23e4d.js +0 -1
- package/apps/pwa/out/_next/static/css/eaa74e8bb2f62269.css +0 -1
- package/apps/pwa/out/_next/static/ktMqfrBbf8BMGac0jqLrb/_buildManifest.js +0 -1
- /package/apps/pwa/out/_next/static/{ktMqfrBbf8BMGac0jqLrb → keajW7DDyghEs1y8oJe6T}/_ssgManifest.js +0 -0
package/src/index.ts
CHANGED
|
@@ -26,6 +26,7 @@ import { CLI_HARNESS_DOGFOOD_ENTRANCE, CLI_HARNESS_ORCHESTRATE_ENTRANCE, describ
|
|
|
26
26
|
import { collectCommandEntrances, renderCommandEntrances } from './self-dev/entrance-inventory.js';
|
|
27
27
|
import { isGoalAuthorFileName } from './self-implement/goal-document.js';
|
|
28
28
|
import { DEV_PIPELINE_SINK_SURFACE } from './self-implement/self-cli-sink-surface.js';
|
|
29
|
+
import { registerPrivateLedgerCommands } from './cli/private-ledger-commands.js';
|
|
29
30
|
import { applyTestStateDirFlagFromArgv } from './cli/test-state-dir-flag.js';
|
|
30
31
|
import { applyTestFlagFromArgv, observeTestFlagOwnership, uncoveredTestFlagPaths, staleTestFlagPaths } from './cli/test-flag.js';
|
|
31
32
|
import { registerPtyTakeoverCommands } from './cli/pty-takeover-cli.js';
|
|
@@ -61,6 +62,7 @@ import { registerModelWatchCommand } from './cli/model-watch-cli.js';
|
|
|
61
62
|
import { registerIntakeCommands } from './cli/intake-cli.js';
|
|
62
63
|
import { registerTasksCommands } from './cli/tasks-cli.js';
|
|
63
64
|
import { registerLabelsCommands } from './cli/labels-cli.js';
|
|
65
|
+
import { registerMsgCommands } from './cli/msg-cli.js';
|
|
64
66
|
import { registerDoctorCommand } from './cli/doctor-cli.js';
|
|
65
67
|
import { registerProviderCommands } from './cli/provider-cli.js';
|
|
66
68
|
export { buildCodexAccountImportGuidance, setCodexAccountLogSinkModuleForTesting } from './cli/provider-cli.js';
|
|
@@ -73,6 +75,7 @@ import { registerGraphCommands } from './graph-runner/graph-cli.js';
|
|
|
73
75
|
import { registerLoopCommands } from './loops/loop-cli.js';
|
|
74
76
|
import { registerCardCommand } from './task-cards/card-cli.js';
|
|
75
77
|
import { registerLaunchHeadCommands } from './launch-head/launch-head-cli.js';
|
|
78
|
+
import { acpServerHelpText } from './boot/acp-server-help.js';
|
|
76
79
|
// IMPORTANT: parse `--config-dir <dir>` + `--test-state-dir <dir>`
|
|
77
80
|
// BEFORE Commander loads — the resolvers are read at module-init
|
|
78
81
|
// time by several config-touching imports below, so the override
|
|
@@ -94,7 +97,8 @@ import type { AdPipelinePlan, AdPipelineResult } from './ad-pipeline/run.js';
|
|
|
94
97
|
import type { AcpPermissionApprover } from './acp/client.js';
|
|
95
98
|
import { runGitCommand } from './git-fs/runner.js';
|
|
96
99
|
import { debug, redactSecretText, redactSecrets } from './debug/log.js';
|
|
97
|
-
import {
|
|
100
|
+
import { installHarnessCliCommand, type HarnessAskSayChildLlmOptions, type HarnessAskSayOptions, type HarnessPlanOptions } from './harness/harness-cli-command.js';
|
|
101
|
+
import { formatCliUserError, isCliUserError } from './cli/cli-user-error.js';
|
|
98
102
|
import { dispatchSolveMission } from './skills/tools/solve-mission.js';
|
|
99
103
|
import { performBrowserAction, type BrowserActionDeps, type BrowserActionResult } from './harness/browser-act.js';
|
|
100
104
|
import { decideTypeAction, type TypeActionDecision, type TypeTarget } from './harness/browser-act-type.js';
|
|
@@ -151,7 +155,7 @@ async function readStdinLine(prompt: string = ''): Promise<string> {
|
|
|
151
155
|
finally { rl.close(); }
|
|
152
156
|
}
|
|
153
157
|
import { loginWithCodex, CODEX_DEVICE_LOGIN_URL } from './oauth/codex.js';
|
|
154
|
-
import { authStorePath, loadTokens, deleteTokens, listProviders as listAuthProviders } from './oauth/store.js';
|
|
158
|
+
import { authStorePath, loadTokens, deleteTokens, saveTokens, listProviders as listAuthProviders, type CodexMirrorResult } from './oauth/store.js';
|
|
155
159
|
import { renderKeyHelp, CONTEXT_LABELS, type KeyContext } from './keybindings.js';
|
|
156
160
|
import { auditKeybindings, renderKeymapAudit } from './keymap-audit.js';
|
|
157
161
|
import { runCodexSetup } from './codex/setup.js';
|
|
@@ -163,6 +167,7 @@ import { initSessionWorkingDir } from './session/working-dir.js';
|
|
|
163
167
|
import { rewriteBareNexusToStatus } from './cli/nexus-entry.js';
|
|
164
168
|
import { registerIngestTokenCommands } from './cli/ingest-token-cli.js';
|
|
165
169
|
import { registerMcpGatewayCommands } from './cli/mcp-gateway-cli.js';
|
|
170
|
+
import { registerRelayCommand } from './relay/relay-cli.js';
|
|
166
171
|
import type { ReviewImage } from './agent-substrate/pr-reviewer.js';
|
|
167
172
|
import {
|
|
168
173
|
describeMissionRouting,
|
|
@@ -863,6 +868,14 @@ registerDoctorCommand(program);
|
|
|
863
868
|
registerControlCommands(program);
|
|
864
869
|
registerHooksCommands(program);
|
|
865
870
|
registerSetupCommand(program);
|
|
871
|
+
program.commands.find(command => command.name() === 'setup')!
|
|
872
|
+
.option('--terminal', 'Run the terminal onboarding wizard')
|
|
873
|
+
.hook('preAction', async (_command, action) => {
|
|
874
|
+
if (action.name() === 'setup' && action.opts().terminal) {
|
|
875
|
+
const completed = await runOnboardingForCli();
|
|
876
|
+
process.exit(completed ? 0 : (process.exitCode || 2));
|
|
877
|
+
}
|
|
878
|
+
});
|
|
866
879
|
registerStartCommand(program);
|
|
867
880
|
registerGroundingSourcesCli(program);
|
|
868
881
|
registerGraphCommands(program);
|
|
@@ -904,6 +917,10 @@ marketCmd.command('publish').description('Publish a local signed marketplace ind
|
|
|
904
917
|
console.log(`Published ${result.published.length} plugins (sequence ${result.sequence}); skipped ${result.skipped.length}`);
|
|
905
918
|
for (const warning of result.warnings) console.warn(`⚠ ${warning.dir}: ${warning.graph} uses recipes it does not ship (${warning.recipes.join(', ')}) — third-party graphs should use their own recipes.yaml or custom nodes`);
|
|
906
919
|
}
|
|
920
|
+
for (const item of result.skipped) {
|
|
921
|
+
for (const hit of item.hits ?? []) console.error(`${item.dir}/${hit.file}:${hit.line}: ${hit.marker}`);
|
|
922
|
+
}
|
|
923
|
+
if (!result.ok) process.exitCode = 1;
|
|
907
924
|
} catch (error) {
|
|
908
925
|
console.error(`market publish: ${error instanceof Error ? error.message : 'failed'}`);
|
|
909
926
|
process.exitCode = 1;
|
|
@@ -1001,7 +1018,7 @@ program.command('self-update')
|
|
|
1001
1018
|
|
|
1002
1019
|
program
|
|
1003
1020
|
.name('elanous')
|
|
1004
|
-
.description('
|
|
1021
|
+
.description('말 한 줄로 시작: elanous harness say "…" — 끝까지 간다 · 다 보인다 · 스스로를 만들었다')
|
|
1005
1022
|
.version(cliVersion())
|
|
1006
1023
|
// Documentation-only entry — the flag is extracted from argv by
|
|
1007
1024
|
// `applyConfigDirFlagFromArgv` at module init (above) so Commander
|
|
@@ -1027,6 +1044,7 @@ program
|
|
|
1027
1044
|
'--test',
|
|
1028
1045
|
'격리 테스트 인스턴스로 실행 — cwd 의 git 트리(worktree 포함)에서 `<트리>/.elanous-test` 를 루트로 잡고 state·config 두 축을 함께 격리한다. config 사본이 없으면 자동 물질화. `--test=<dir>` 로 루트 직접 지정 가능(값 문법은 `=` 형태 하나 — 모호함 없음). ELANOUS_STATE_DIR/--config-dir 을 손으로 줄 필요가 없다.',
|
|
1029
1046
|
);
|
|
1047
|
+
program.addHelpText('after', acpServerHelpText());
|
|
1030
1048
|
|
|
1031
1049
|
program
|
|
1032
1050
|
.command('measure-fabric-arc-ab')
|
|
@@ -1075,6 +1093,8 @@ const mcpCmd = program
|
|
|
1075
1093
|
.description('MCP (Model Context Protocol) server / client integration');
|
|
1076
1094
|
registerMcpGatewayCommands(mcpCmd);
|
|
1077
1095
|
|
|
1096
|
+
registerRelayCommand(program);
|
|
1097
|
+
|
|
1078
1098
|
mcpCmd
|
|
1079
1099
|
.command('serve')
|
|
1080
1100
|
.description('Run a stdio MCP server exposing the configured mcp.servers as proxy tools (used by `claude mcp add elanous -- elanous mcp serve`)')
|
|
@@ -2951,6 +2971,9 @@ const harnessOrchestrateCmd = registerHarnessOrchestrateCapabilityOptions(
|
|
|
2951
2971
|
|
|
2952
2972
|
const selfCmd = program.command('self').description('Self-awareness memory — 외부 도구(Claude Code/Codex)가 구현/변경 이력을 elanous 기억에 주입·회상');
|
|
2953
2973
|
|
|
2974
|
+
// M12 Claude Code 의존도 계기판 — `elanous self dependence [--since] [--until] [--json]`(읽기만).
|
|
2975
|
+
{ const { registerDependenceCommand } = await import('./cli/dependence-gauge.js'); registerDependenceCommand(selfCmd); }
|
|
2976
|
+
|
|
2954
2977
|
function printExtendedOrchestrateHelp(command: Command, positional = '[goals...]'): void {
|
|
2955
2978
|
const optionLines = command.options
|
|
2956
2979
|
.filter((option) => option.long !== '--help-all')
|
|
@@ -5429,30 +5452,7 @@ program.command('ad [input...]')
|
|
|
5429
5452
|
});
|
|
5430
5453
|
|
|
5431
5454
|
registerDocsCommands(program);
|
|
5432
|
-
|
|
5433
|
-
if (existsSync(resolve(import.meta.dir, 'cli/decisions-cli.ts')) || existsSync(resolve(import.meta.dir, 'cli/decisions-cli.js'))) {
|
|
5434
|
-
program.command('decisions').description('대표 결정 로컬 원장').allowUnknownOption().allowExcessArguments(true)
|
|
5435
|
-
.action(async (_opts: unknown, command: Command) => {
|
|
5436
|
-
try { await (await import('./domains/standalone-log-sink.js')).registerStandaloneLogSink('decisions'); }
|
|
5437
|
-
catch { /* Logging must not prevent recording a decision. */ }
|
|
5438
|
-
const privateDecisionsModule: string = './cli/decisions-cli.js';
|
|
5439
|
-
const { registerDecisionsCommands } = await import(privateDecisionsModule) as { registerDecisionsCommands: (program: Command) => void };
|
|
5440
|
-
const privateProgram = new Command();
|
|
5441
|
-
registerDecisionsCommands(privateProgram);
|
|
5442
|
-
await privateProgram.parseAsync(['decisions', ...command.args], { from: 'user' });
|
|
5443
|
-
});
|
|
5444
|
-
}
|
|
5445
|
-
// Private command is absent from the public export; JS-only distributions still register it.
|
|
5446
|
-
if (existsSync(resolve(import.meta.dir, 'cli/directives-cli.ts')) || existsSync(resolve(import.meta.dir, 'cli/directives-cli.js'))) {
|
|
5447
|
-
program.command('directives').description('대표 지시 로컬 색인·검색').allowUnknownOption().allowExcessArguments(true)
|
|
5448
|
-
.action(async (_opts: unknown, command: Command) => {
|
|
5449
|
-
const privateDirectivesModule: string = './cli/directives-cli.js';
|
|
5450
|
-
const { registerDirectivesCommands } = await import(privateDirectivesModule) as { registerDirectivesCommands: (program: Command) => void };
|
|
5451
|
-
const privateProgram = new Command();
|
|
5452
|
-
registerDirectivesCommands(privateProgram);
|
|
5453
|
-
await privateProgram.parseAsync(['directives', ...command.args], { from: 'user' });
|
|
5454
|
-
});
|
|
5455
|
-
}
|
|
5455
|
+
registerPrivateLedgerCommands(program);
|
|
5456
5456
|
registerFleetCommands(program);
|
|
5457
5457
|
|
|
5458
5458
|
// ── ops (운영 관측 — 지금 뭐 도나·이상 없나·상태 전이) ──
|
|
@@ -7041,6 +7041,7 @@ missionCmd
|
|
|
7041
7041
|
|
|
7042
7042
|
registerTasksCommands(program);
|
|
7043
7043
|
registerLabelsCommands(program);
|
|
7044
|
+
registerMsgCommands(program);
|
|
7044
7045
|
|
|
7045
7046
|
// ── ask alias (script-friendly one-shot query) ──
|
|
7046
7047
|
program
|
|
@@ -7049,7 +7050,28 @@ program
|
|
|
7049
7050
|
.option('--reuse', 'Reuse the active CLI session instead of creating a new one')
|
|
7050
7051
|
.option('--session <id>', 'Continue an explicit session (id or unique prefix). Overrides --reuse and active session.')
|
|
7051
7052
|
.option('--json', 'Emit a single JSON line {sessionId, provider, model, reply, logPath, budget} instead of streaming text + ui.info trailer. Stable shape for LLM self-spawn.')
|
|
7052
|
-
.
|
|
7053
|
+
.option('--bare', 'Send only this text to the model: no Elanous preamble, project tree, memory, tools or session')
|
|
7054
|
+
.action(async (parts: string[], opts: { reuse?: boolean; session?: string; json?: boolean; bare?: boolean }) => {
|
|
7055
|
+
if (opts.bare) {
|
|
7056
|
+
try {
|
|
7057
|
+
const { askBare } = await import('./cli/ask-bare.js');
|
|
7058
|
+
const llm = await import('./llm.js');
|
|
7059
|
+
const { getUserConfig } = await import('./user-config.js');
|
|
7060
|
+
const { trimToBudget } = await import('./tokens.js');
|
|
7061
|
+
const result = await askBare({ text: parts.join(' '), deps: {
|
|
7062
|
+
getUserConfig, decideProviderForConfig: llm.decideProviderForConfig, getProviderForConfig: llm.getProviderForConfig,
|
|
7063
|
+
streamLLM: llm.streamLLM, trimToBudget,
|
|
7064
|
+
} });
|
|
7065
|
+
if (opts.json) process.stdout.write(JSON.stringify({ sessionId: null, ...result, logPath: null, budget: null, bare: true }) + '\n');
|
|
7066
|
+
else process.stdout.write(result.reply.endsWith('\n') ? result.reply : `${result.reply}\n`);
|
|
7067
|
+
} catch (error) {
|
|
7068
|
+
const message = error instanceof Error ? error.message : String(error);
|
|
7069
|
+
if (opts.json) process.stdout.write(JSON.stringify({ error: message, bare: true }) + '\n');
|
|
7070
|
+
else console.error(`ask --bare failed: ${message}`);
|
|
7071
|
+
process.exitCode = 1;
|
|
7072
|
+
}
|
|
7073
|
+
return;
|
|
7074
|
+
}
|
|
7053
7075
|
const cfg = reloadUserConfig();
|
|
7054
7076
|
await runChatTurnCli({
|
|
7055
7077
|
cfg,
|
|
@@ -7215,9 +7237,13 @@ program
|
|
|
7215
7237
|
});
|
|
7216
7238
|
|
|
7217
7239
|
// ── login (provider OAuth) ──
|
|
7218
|
-
export function codexLoginSuccessMessage(mirrorResult?:
|
|
7240
|
+
export function codexLoginSuccessMessage(mirrorResult?: CodexMirrorResult): string {
|
|
7219
7241
|
const prefix = `Signed in. Tokens at ${authStorePath()}.`;
|
|
7220
7242
|
if (mirrorResult === 'written') return `${prefix} Mirrored to ~/.codex/auth.json.`;
|
|
7243
|
+
if (mirrorResult === 'skipped-different-account') {
|
|
7244
|
+
return `${prefix} Your Codex CLI login (~/.codex/auth.json) belongs to a different account — left unchanged. To switch it, run \`elanous login openai-codex --replace-codex-cli-login\`.`;
|
|
7245
|
+
}
|
|
7246
|
+
if (mirrorResult === 'skipped-unknown-account') return `${prefix} Codex CLI login left unchanged.`;
|
|
7221
7247
|
if (mirrorResult === 'not-created-missing-cli-fields') {
|
|
7222
7248
|
return `${prefix} Codex CLI mirror was not created because this login response lacked its required fields; run \`codex login\` once to initialize ~/.codex/auth.json.`;
|
|
7223
7249
|
}
|
|
@@ -7230,7 +7256,8 @@ const loginCmd = program.command('login').description('Authenticate to an LLM pr
|
|
|
7230
7256
|
loginCmd
|
|
7231
7257
|
.command('openai-codex')
|
|
7232
7258
|
.description('Sign in to OpenAI Codex via the ChatGPT device-code flow')
|
|
7233
|
-
.
|
|
7259
|
+
.option('--replace-codex-cli-login', 'if the Codex CLI (~/.codex/auth.json) is signed in to a different account, replace it with this login')
|
|
7260
|
+
.action(async (opts: { replaceCodexCliLogin?: boolean }) => {
|
|
7234
7261
|
ui.header('OpenAI Codex — device-code sign-in');
|
|
7235
7262
|
try {
|
|
7236
7263
|
const state = await loginWithCodex({
|
|
@@ -7255,7 +7282,21 @@ loginCmd
|
|
|
7255
7282
|
}
|
|
7256
7283
|
},
|
|
7257
7284
|
});
|
|
7258
|
-
|
|
7285
|
+
// AUTH1 — another account's Codex CLI login is left alone unless the user says to replace it.
|
|
7286
|
+
let mirrorResult = state.codexMirrorResult;
|
|
7287
|
+
if (mirrorResult === 'skipped-different-account') {
|
|
7288
|
+
let replace = opts.replaceCodexCliLogin === true;
|
|
7289
|
+
if (!replace && process.stdin.isTTY && process.stdout.isTTY) {
|
|
7290
|
+
const { createInterface } = await import('node:readline/promises');
|
|
7291
|
+
const rl = createInterface({ input: process.stdin, output: process.stdout });
|
|
7292
|
+
try {
|
|
7293
|
+
const answer = await rl.question(' Your Codex CLI (~/.codex/auth.json) is signed in to a different account. Replace it with this login? [y/N] ');
|
|
7294
|
+
replace = /^y(es)?$/i.test(answer.trim());
|
|
7295
|
+
} finally { rl.close(); }
|
|
7296
|
+
}
|
|
7297
|
+
if (replace) mirrorResult = saveTokens('openai-codex', state.tokens, { replaceDifferentCodexAccount: true }).codexMirrorResult;
|
|
7298
|
+
}
|
|
7299
|
+
ui.info(codexLoginSuccessMessage(mirrorResult));
|
|
7259
7300
|
ui.info(`Expires in ~${state.tokens.expiresAt ? Math.round((state.tokens.expiresAt - Date.now()) / 60000) : '?'}min; auto-refresh on next use.`);
|
|
7260
7301
|
} catch (err: any) {
|
|
7261
7302
|
ui.error(`login failed: ${err?.message ?? err}`);
|
|
@@ -7843,6 +7884,15 @@ sessionCmd
|
|
|
7843
7884
|
console.log(res.formatted ?? '(no context)');
|
|
7844
7885
|
});
|
|
7845
7886
|
|
|
7887
|
+
async function runFirstSetupForCli(cfg: ReturnType<typeof getUserConfig>, announceFallback = false): Promise<boolean> {
|
|
7888
|
+
if (cfg.onboarding.webFirst === true) {
|
|
7889
|
+
const { runWebFirstSetup } = await import('./onboarding/web-first.js');
|
|
7890
|
+
if (await runWebFirstSetup({ config: cfg }) === 'link-shown') return false;
|
|
7891
|
+
if (announceFallback) ui.info('No config yet — launching setup wizard first.');
|
|
7892
|
+
}
|
|
7893
|
+
return runOnboardingForCli();
|
|
7894
|
+
}
|
|
7895
|
+
|
|
7846
7896
|
async function runOnboardingForCli(): Promise<boolean> {
|
|
7847
7897
|
try {
|
|
7848
7898
|
await runOnboarding();
|
|
@@ -7878,8 +7928,8 @@ program
|
|
|
7878
7928
|
if (opts.tools) announceChatToolsCompatibility();
|
|
7879
7929
|
const cfg = getUserConfig();
|
|
7880
7930
|
if (needsOnboarding(cfg)) {
|
|
7881
|
-
ui.info('No config yet — launching setup wizard first.');
|
|
7882
|
-
if (!await
|
|
7931
|
+
if (cfg.onboarding.webFirst !== true) ui.info('No config yet — launching setup wizard first.');
|
|
7932
|
+
if (!await runFirstSetupForCli(cfg, true)) return;
|
|
7883
7933
|
}
|
|
7884
7934
|
const refreshed = reloadUserConfig();
|
|
7885
7935
|
// ★ 관측갭 수리(2026-07-21·제1원칙·트랙A) — self-implement 자식 goal-loop(`chat --goal-loop`)은 데몬과
|
|
@@ -7945,8 +7995,8 @@ program
|
|
|
7945
7995
|
}
|
|
7946
7996
|
const cfg = getUserConfig();
|
|
7947
7997
|
if (needsOnboarding(cfg)) {
|
|
7948
|
-
ui.info('No config yet — launching setup wizard first.');
|
|
7949
|
-
if (!await
|
|
7998
|
+
if (cfg.onboarding.webFirst !== true) ui.info('No config yet — launching setup wizard first.');
|
|
7999
|
+
if (!await runFirstSetupForCli(cfg, true)) return;
|
|
7950
8000
|
}
|
|
7951
8001
|
const refreshed = reloadUserConfig();
|
|
7952
8002
|
const { runRepl } = await import('./repl/index.js');
|
|
@@ -9935,6 +9985,22 @@ nexusCmd
|
|
|
9935
9985
|
}
|
|
9936
9986
|
});
|
|
9937
9987
|
|
|
9988
|
+
// 휴대폰 앱 온보딩 — 링크 하나(⊕ QR)로 이 Mac 의 넥서스에 붙인다(대표 2026-09-30 · 아이폰 첫 화면 단순화).
|
|
9989
|
+
program
|
|
9990
|
+
.command('phone')
|
|
9991
|
+
.description('Connect the phone app to this Mac')
|
|
9992
|
+
.command('link')
|
|
9993
|
+
.description('Print a one-tap connect link (and a QR code) for the Elanous phone app')
|
|
9994
|
+
.option('--simulator', 'Use the loopback address (the simulator on this Mac) instead of the tailnet address — `--local` is taken by the global remote flag')
|
|
9995
|
+
.option('--android [serial]', 'Hand the link straight to a USB-connected Android phone (adb reverse + am start · the token is never printed)')
|
|
9996
|
+
.option('--temp', 'Use a short-lived token instead of the owner token')
|
|
9997
|
+
.option('--ttl <duration>', 'Lifetime for --temp (max 24h)', '24h')
|
|
9998
|
+
.option('--no-qr', 'Do not print a QR code')
|
|
9999
|
+
.action(async (opts: { simulator?: boolean; android?: boolean | string; temp?: boolean; ttl: string; qr: boolean }) => {
|
|
10000
|
+
const { runPhoneLink } = await import('./cli/phone-link.js');
|
|
10001
|
+
process.exitCode = await runPhoneLink({ local: opts.simulator, android: opts.android, temp: opts.temp, ttl: opts.ttl, qr: opts.qr });
|
|
10002
|
+
});
|
|
10003
|
+
|
|
9938
10004
|
// ── ACP — Agent Client Protocol (claude-code, codex, ...) ──
|
|
9939
10005
|
const tokenCmd = program
|
|
9940
10006
|
.command('token')
|
|
@@ -10603,7 +10669,7 @@ async function main(): Promise<void> {
|
|
|
10603
10669
|
// gates on config completeness — no entry-mode branch.)
|
|
10604
10670
|
const cfg = getUserConfig();
|
|
10605
10671
|
if (needsOnboarding(cfg)) {
|
|
10606
|
-
if (!await
|
|
10672
|
+
if (!await runFirstSetupForCli(cfg)) return;
|
|
10607
10673
|
}
|
|
10608
10674
|
|
|
10609
10675
|
// Active-provider banner so users know WHICH model/auth is about to
|
|
@@ -10687,8 +10753,8 @@ async function main(): Promise<void> {
|
|
|
10687
10753
|
export function runCli(): void {
|
|
10688
10754
|
main().catch((err) => {
|
|
10689
10755
|
closeTui();
|
|
10690
|
-
if (err
|
|
10691
|
-
console.error(
|
|
10756
|
+
if (isCliUserError(err)) {
|
|
10757
|
+
console.error(formatCliUserError(err));
|
|
10692
10758
|
process.exit(1);
|
|
10693
10759
|
}
|
|
10694
10760
|
throw err;
|
package/src/instance/leader.ts
CHANGED
|
@@ -2,7 +2,7 @@
|
|
|
2
2
|
import { INSTALLED_PACKAGE_MARKERS, isInstalledPackagePath } from './installed-package.js';
|
|
3
3
|
import { existsSync, mkdirSync, readFileSync, realpathSync, renameSync, unlinkSync, writeFileSync } from 'node:fs';
|
|
4
4
|
import { homedir } from 'node:os';
|
|
5
|
-
import { dirname, join, resolve } from 'node:path';
|
|
5
|
+
import { dirname, join, resolve, basename } from 'node:path';
|
|
6
6
|
|
|
7
7
|
export interface LeaderRefusalRecord {
|
|
8
8
|
refusedAt: string;
|
|
@@ -53,10 +53,22 @@ export function normalizeTree(p: string): string {
|
|
|
53
53
|
try { return realpathSync(abs); } catch { return abs; }
|
|
54
54
|
}
|
|
55
55
|
|
|
56
|
+
/** npm/Homebrew/nvm `<prefix>/lib/node_modules` · bun `…/install/global/node_modules` · pnpm `…/global/<n>/node_modules`. */
|
|
57
|
+
export function isGlobalNodeModules(dir: string): boolean {
|
|
58
|
+
if (basename(dir) !== 'node_modules') return false;
|
|
59
|
+
const parent = basename(dirname(dir));
|
|
60
|
+
return parent === 'lib' || parent === 'global' || (/^\d+$/.test(parent) && basename(dirname(dirname(dir))) === 'global');
|
|
61
|
+
}
|
|
62
|
+
|
|
56
63
|
export function treeFromScriptPath(scriptPath: string): string | null {
|
|
57
64
|
let dir = dirname(normalizeTree(scriptPath));
|
|
58
65
|
for (let i = 0; i < 30; i++) {
|
|
59
66
|
if (existsSync(join(dir, '.git'))) return dir;
|
|
67
|
+
// A GLOBAL install stops at its node_modules: a git repo around the install prefix (Homebrew's /opt/homebrew
|
|
68
|
+
// is one; so is a dotfiles-managed home) is not this code's source tree. Without this stop `npm i -g` under
|
|
69
|
+
// Homebrew ran as a «source tree» test universe writing config to /opt/homebrew/.elanous-test (OB3 · 10-01).
|
|
70
|
+
// A project-local <checkout>/node_modules/elanous still resolves to the checkout (the existing design).
|
|
71
|
+
if (isGlobalNodeModules(dir)) return null;
|
|
60
72
|
const parent = dirname(dir);
|
|
61
73
|
if (parent === dir) return null;
|
|
62
74
|
dir = parent;
|
|
@@ -131,7 +131,7 @@ export function signalsFromSnapshot(stars: number, prev: StarSnapshot | undefine
|
|
|
131
131
|
return { stars, starsDelta, starsPerDay: starsDelta / span };
|
|
132
132
|
}
|
|
133
133
|
|
|
134
|
-
function
|
|
134
|
+
export function appendGithubStarSnapshots(root: string, rows: StarSnapshot[]): void {
|
|
135
135
|
if (!rows.length) return;
|
|
136
136
|
mkdirSync(intakeLedgerDir(root), { recursive: true });
|
|
137
137
|
appendFileSync(githubStarsFile(root), rows.map((r) => JSON.stringify(r)).join('\n') + '\n');
|
|
@@ -154,6 +154,8 @@ export interface CollectGithubOpts {
|
|
|
154
154
|
/** 스냅숏·비교의 «오늘». 생략하면 UTC 날짜. */
|
|
155
155
|
day?: string;
|
|
156
156
|
now?: () => Date;
|
|
157
|
+
/** 등록 원천이 질의 하나만 수집할 때; 생략 시 기존 관심 질의 전부. */
|
|
158
|
+
queries?: readonly string[];
|
|
157
159
|
}
|
|
158
160
|
|
|
159
161
|
/**
|
|
@@ -173,7 +175,7 @@ export async function collectGithubStars(
|
|
|
173
175
|
const found: GithubStarRepo[] = [];
|
|
174
176
|
// «급상승»은 최근에 생긴 저장소 중 별 순이다 — 전체 기간 별 순이면 활발한 거대 저장소가 매일 같은 목록으로 나온다(2026-09-26 검토).
|
|
175
177
|
const windowStart = new Date(Date.parse(`${day}T00:00:00.000Z`) - days * 86_400_000).toISOString().slice(0, 10);
|
|
176
|
-
for (const query of GITHUB_STAR_QUERIES) {
|
|
178
|
+
for (const query of opts.queries ?? GITHUB_STAR_QUERIES) {
|
|
177
179
|
const rows = await search(`${query} created:>=${windowStart}`, perQuery);
|
|
178
180
|
const recent = rows.filter((r) => isRecentRepo(r, day, days));
|
|
179
181
|
queries.push({ query, received: recent.length });
|
|
@@ -208,7 +210,7 @@ export async function collectGithubStars(
|
|
|
208
210
|
day, days, perQuery, dryRun: !!opts.dryRun, queries, repos, raws: raws.length,
|
|
209
211
|
};
|
|
210
212
|
if (!opts.dryRun) {
|
|
211
|
-
|
|
213
|
+
appendGithubStarSnapshots(root, repos.map((row) => ({ day, repo: row.repo, stars: row.stars })));
|
|
212
214
|
result.ingest = ingestIntakeItems(root, 'github', raws);
|
|
213
215
|
}
|
|
214
216
|
debug.log('intake.collect', 'github-stars', {
|
|
@@ -60,14 +60,26 @@ export async function collectTelegramSaved(root: string, fetch: FetchSavedMessag
|
|
|
60
60
|
}
|
|
61
61
|
|
|
62
62
|
/** GramJS 사용자 세션으로 `me` 대화를 읽는 실제 구현. 자격이 없으면 이유를 담아 던진다(값은 싣지 않는다). */
|
|
63
|
-
|
|
63
|
+
type GramjsModules = { TelegramClient: typeof import('telegram').TelegramClient; StringSession: typeof import('telegram/sessions').StringSession };
|
|
64
|
+
const loadGramjs = async (): Promise<GramjsModules> => ({
|
|
65
|
+
TelegramClient: (await import('telegram')).TelegramClient,
|
|
66
|
+
StringSession: (await import('telegram/sessions')).StringSession,
|
|
67
|
+
});
|
|
68
|
+
|
|
69
|
+
export async function gramjsFetchSaved(
|
|
70
|
+
env: NodeJS.ProcessEnv = process.env,
|
|
71
|
+
load: () => Promise<GramjsModules> = loadGramjs,
|
|
72
|
+
): Promise<{ fetch: FetchSavedMessages; close: () => Promise<void> }> {
|
|
64
73
|
const apiId = Number(env.TELEGRAM_API_ID ?? 0);
|
|
65
74
|
const apiHash = env.TELEGRAM_API_HASH ?? '';
|
|
66
75
|
const session = env.TELEGRAM_USER_SESSION ?? '';
|
|
67
76
|
const missing = [!apiId && 'TELEGRAM_API_ID', !apiHash && 'TELEGRAM_API_HASH', !session && 'TELEGRAM_USER_SESSION'].filter(Boolean);
|
|
68
77
|
if (missing.length) throw new Error(`텔레그램 사용자 세션 자격이 없다: ${missing.join(' · ')} (docs/manual/MANUAL-telegram-unmanned-test-2026-07-21.md §1~§3)`);
|
|
69
|
-
|
|
70
|
-
|
|
78
|
+
// `telegram` is an optional dependency: its native websocket helpers have no Linux ARM64 build, so npm may leave it out.
|
|
79
|
+
let modules: GramjsModules;
|
|
80
|
+
try { modules = await load(); }
|
|
81
|
+
catch { throw new Error('텔레그램 사용자 세션 모듈(telegram)이 이 설치에 없다 — 선택 의존이라 Linux ARM64 등에서는 빠진다(npm i -g telegram 으로 따로 깔 수 있다)'); }
|
|
82
|
+
const { TelegramClient, StringSession } = modules;
|
|
71
83
|
const client = new TelegramClient(new StringSession(session), apiId, apiHash, { connectionRetries: 3 });
|
|
72
84
|
client.setLogLevel('error' as never); // 연결 로그가 표준출력을 채우지 않게
|
|
73
85
|
await client.connect();
|
|
@@ -0,0 +1,56 @@
|
|
|
1
|
+
import { parseSeatAddress, resolveSeat } from '../seat-address/seat-address.js';
|
|
2
|
+
import {
|
|
3
|
+
submitIntakeWork,
|
|
4
|
+
type SubmitIntakeWorkDeps,
|
|
5
|
+
} from './submit-intake-work.js';
|
|
6
|
+
|
|
7
|
+
export interface DiscordSeatWorkMessage {
|
|
8
|
+
channelId: string;
|
|
9
|
+
messageId: string;
|
|
10
|
+
threadId?: string;
|
|
11
|
+
}
|
|
12
|
+
|
|
13
|
+
export interface DiscordSeatWorkDeps extends SubmitIntakeWorkDeps {
|
|
14
|
+
submit?: typeof submitIntakeWork;
|
|
15
|
+
}
|
|
16
|
+
|
|
17
|
+
/** Addressed Discord work goes through the graph intake door, not the chat turn. */
|
|
18
|
+
export async function handleDiscordSeatWork(
|
|
19
|
+
text: string,
|
|
20
|
+
msg: DiscordSeatWorkMessage,
|
|
21
|
+
deps: DiscordSeatWorkDeps = {},
|
|
22
|
+
): Promise<string | null> {
|
|
23
|
+
const address = parseSeatAddress(text);
|
|
24
|
+
if (!address) return null;
|
|
25
|
+
|
|
26
|
+
const seats = address.seats.map((name) => ({ name, seat: resolveSeat(name) }));
|
|
27
|
+
const unknown = seats.filter(({ seat }) => !seat).map(({ name }) => `@${name}`);
|
|
28
|
+
if (unknown.length) return `어느 좌석을 말씀하시나요? ${unknown.join(', ')}은(는) 등록된 좌석이 아닙니다. 좌석을 확인해 다시 보내 주세요.`;
|
|
29
|
+
const body = address.body.trim();
|
|
30
|
+
if (!body) return '어떤 일을 맡길까요? 좌석 주소 뒤에 요청 내용을 적어 다시 보내 주세요.';
|
|
31
|
+
|
|
32
|
+
const reportTo = {
|
|
33
|
+
channel: 'discord' as const,
|
|
34
|
+
channelId: msg.channelId,
|
|
35
|
+
...(msg.threadId ? { discordThreadId: msg.threadId } : {}),
|
|
36
|
+
};
|
|
37
|
+
const replies: string[] = [];
|
|
38
|
+
for (const { seat } of seats) {
|
|
39
|
+
if (!seat) continue;
|
|
40
|
+
const label = seat.title ?? seat.id;
|
|
41
|
+
const result = await (deps.submit ?? submitIntakeWork)({
|
|
42
|
+
text: `@${label} ${body}`,
|
|
43
|
+
track: 'graph',
|
|
44
|
+
origin: {
|
|
45
|
+
kind: 'external', ledgerSource: 'memo', provider: 'other',
|
|
46
|
+
ref: `discord:${msg.channelId}:${msg.messageId}`, reportTo,
|
|
47
|
+
},
|
|
48
|
+
}, deps);
|
|
49
|
+
if (result.ok && result.track === 'graph') {
|
|
50
|
+
replies.push(`@${label} 접수번호: ${result.acceptanceId}`);
|
|
51
|
+
} else {
|
|
52
|
+
replies.push(`@${label} 접수 실패 — ${result.ok ? '접수번호가 없습니다' : result.reason.split('\n')[0]!.slice(0, 200)}`);
|
|
53
|
+
}
|
|
54
|
+
}
|
|
55
|
+
return replies.join('\n');
|
|
56
|
+
}
|