elanous 0.2.8 → 0.2.10
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/2DsiDfDCks44g1cPUMhiW/_buildManifest.js +1 -0
- package/apps/pwa/out/_next/static/chunks/24-e6d28380efab7faf.js +1 -0
- package/apps/pwa/out/_next/static/chunks/3615-740dd270764ffa24.js +1 -0
- package/apps/pwa/out/_next/static/chunks/3734-1015fe991eb9b7e7.js +1 -0
- package/apps/pwa/out/_next/static/chunks/5012-a7fe6f3c8b6fe45a.js +1 -0
- package/apps/pwa/out/_next/static/chunks/5783-ef40ebfc91d55230.js +1 -0
- package/apps/pwa/out/_next/static/chunks/62-ff227c3edb8b248b.js +1 -0
- package/apps/pwa/out/_next/static/chunks/7633-1b3709b0854c9412.js +1 -0
- package/apps/pwa/out/_next/static/chunks/7951-8b03dbb10b24cd06.js +1 -0
- package/apps/pwa/out/_next/static/chunks/8067-87ce253ec2f23697.js +1 -0
- package/apps/pwa/out/_next/static/chunks/{5080-1613752891fcadb4.js → 8195-6fde3d7a39859206.js} +5 -5
- package/apps/pwa/out/_next/static/chunks/8894-b5fb36bab837cd29.js +1 -0
- package/apps/pwa/out/_next/static/chunks/9454-84d0d5d77446bd92.js +1 -0
- package/apps/pwa/out/_next/static/chunks/988-5f92e7ab7ccea3dd.js +1 -0
- package/apps/pwa/out/_next/static/chunks/9989-5582582f06429840.js +1 -0
- package/apps/pwa/out/_next/static/chunks/app/approvals/page-d2253d7e58ef1890.js +1 -0
- package/apps/pwa/out/_next/static/chunks/app/autopilot/page-5441d4a9ab35e518.js +1 -0
- package/apps/pwa/out/_next/static/chunks/app/board/page-d9b12d680922d980.js +1 -0
- package/apps/pwa/out/_next/static/chunks/app/botlab/{page-d4b6df905f185055.js → page-54b32bd27726588d.js} +1 -1
- package/apps/pwa/out/_next/static/chunks/app/bots/page-e268d6d145827a22.js +1 -0
- package/apps/pwa/out/_next/static/chunks/app/chat/{page-186fc6952f027acc.js → page-f8116559c7424da7.js} +1 -1
- package/apps/pwa/out/_next/static/chunks/app/consult/page-1085399fd0f32112.js +1 -0
- package/apps/pwa/out/_next/static/chunks/app/control/page-1df686a14f65895a.js +1 -0
- package/apps/pwa/out/_next/static/chunks/app/design-check/{page-cbbe03c0da7b081a.js → page-54e1f966ab60a4dc.js} +1 -1
- package/apps/pwa/out/_next/static/chunks/app/editor/page-7ed95f296f5ee8e9.js +1 -0
- package/apps/pwa/out/_next/static/chunks/app/exec/page-11edac668d77e5c3.js +1 -0
- package/apps/pwa/out/_next/static/chunks/app/field/page-59e2b9a22cd5a6d5.js +1 -0
- package/apps/pwa/out/_next/static/chunks/app/intake/page-2976df21ad74ab48.js +1 -0
- package/apps/pwa/out/_next/static/chunks/app/layout-34d211a67f16d510.js +1 -0
- package/apps/pwa/out/_next/static/chunks/app/live/page-8ff652d5d950639b.js +1 -0
- package/apps/pwa/out/_next/static/chunks/app/market/{page-c0c0d19d51342d3e.js → page-b31610deda76337b.js} +1 -1
- package/apps/pwa/out/_next/static/chunks/app/missions/[id]/{page-2e002ad8faa43291.js → page-6cb0e1bbefe5fb3d.js} +1 -1
- package/apps/pwa/out/_next/static/chunks/app/morning/page-a286a152cf584576.js +1 -0
- package/apps/pwa/out/_next/static/chunks/app/not-found-d9237581e7003bcb.js +1 -0
- package/apps/pwa/out/_next/static/chunks/app/observatory/page-83274e761643fdd2.js +1 -0
- package/apps/pwa/out/_next/static/chunks/app/ops/checklist/page-ceee6cfb1d4e6d68.js +1 -0
- package/apps/pwa/out/_next/static/chunks/app/ops/release/page-9c9f8bb3e4a64091.js +1 -0
- package/apps/pwa/out/_next/static/chunks/app/ops/seats/page-c17217603ea3426a.js +1 -0
- package/apps/pwa/out/_next/static/chunks/app/page-efb6177cbf1e8a51.js +1 -0
- package/apps/pwa/out/_next/static/chunks/app/reflection/page-d307523703bc4df3.js +1 -0
- package/apps/pwa/out/_next/static/chunks/app/scheduler/page-462f4e4bab45ce7d.js +1 -0
- package/apps/pwa/out/_next/static/chunks/app/sessions/page-8990e96f33af3837.js +1 -0
- package/apps/pwa/out/_next/static/chunks/app/settings/devices/{page-7464c1987dd76e6d.js → page-e168fa1030af0548.js} +1 -1
- package/apps/pwa/out/_next/static/chunks/app/settings/page-1233e05a4068bc9c.js +1 -0
- package/apps/pwa/out/_next/static/chunks/app/setup/done/page-13a1840b1fac337a.js +1 -0
- package/apps/pwa/out/_next/static/chunks/app/setup/page-64a29fc80b11ab55.js +1 -0
- package/apps/pwa/out/_next/static/chunks/app/share/page-68e787339a16b3dc.js +1 -0
- package/apps/pwa/out/_next/static/chunks/app/showroom/{page-d8ab4d1489223459.js → page-4fddc90b23feb215.js} +1 -1
- package/apps/pwa/out/_next/static/chunks/app/tasks/page-886ba8260dc79c79.js +1 -0
- package/apps/pwa/out/_next/static/chunks/app/term/page-0f26507a1722e40b.js +1 -0
- package/apps/pwa/out/_next/static/chunks/app/today/page-109d4ccd42259c9d.js +1 -0
- package/apps/pwa/out/_next/static/chunks/app/trace/page-f5c2a4e510726774.js +1 -0
- package/apps/pwa/out/_next/static/chunks/app/vault/page-b2e0039416f42522.js +1 -0
- package/apps/pwa/out/_next/static/chunks/app/workflows/chat-ui/page-26102fd7350f171e.js +1 -0
- package/apps/pwa/out/_next/static/chunks/app/workflows/page-708948bc8a802794.js +1 -0
- package/apps/pwa/out/_next/static/chunks/app/workspace/page-5e5611620f78fb0b.js +1 -0
- package/apps/pwa/out/_next/static/chunks/app/worktrees/page-139ba5c367bbf60a.js +1 -0
- package/apps/pwa/out/_next/static/chunks/main-app-202b4e81f33895ea.js +1 -0
- package/apps/pwa/out/_next/static/css/43feca5fd387dcbd.css +1 -0
- package/apps/pwa/out/approvals/index.html +1 -1
- package/apps/pwa/out/approvals/index.txt +30 -29
- package/apps/pwa/out/autopilot/index.html +1 -1
- package/apps/pwa/out/autopilot/index.txt +30 -29
- package/apps/pwa/out/board/index.html +1 -1
- package/apps/pwa/out/board/index.txt +30 -29
- package/apps/pwa/out/botlab/index.html +1 -1
- package/apps/pwa/out/botlab/index.txt +27 -26
- package/apps/pwa/out/bots/index.html +1 -1
- package/apps/pwa/out/bots/index.txt +27 -26
- package/apps/pwa/out/chat/index.html +1 -1
- package/apps/pwa/out/chat/index.txt +27 -26
- package/apps/pwa/out/consult/index.html +1 -1
- package/apps/pwa/out/consult/index.txt +30 -29
- package/apps/pwa/out/control/index.html +1 -1
- package/apps/pwa/out/control/index.txt +30 -29
- package/apps/pwa/out/design-check/index.html +1 -1
- package/apps/pwa/out/design-check/index.txt +30 -29
- package/apps/pwa/out/editor/index.html +1 -1
- package/apps/pwa/out/editor/index.txt +30 -29
- package/apps/pwa/out/exec/index.html +1 -1
- package/apps/pwa/out/exec/index.txt +30 -29
- package/apps/pwa/out/field/index.html +1 -1
- package/apps/pwa/out/field/index.txt +30 -29
- package/apps/pwa/out/healthz +1 -1
- package/apps/pwa/out/index.html +1 -1
- package/apps/pwa/out/index.txt +27 -26
- package/apps/pwa/out/intake/index.html +1 -1
- package/apps/pwa/out/intake/index.txt +30 -29
- package/apps/pwa/out/live/index.html +1 -1
- package/apps/pwa/out/live/index.txt +30 -29
- package/apps/pwa/out/market/index.html +1 -1
- package/apps/pwa/out/market/index.txt +27 -26
- package/apps/pwa/out/missions/placeholder/index.html +1 -1
- package/apps/pwa/out/missions/placeholder/index.txt +27 -26
- package/apps/pwa/out/morning/index.html +1 -1
- package/apps/pwa/out/morning/index.txt +30 -29
- package/apps/pwa/out/observatory/index.html +1 -1
- package/apps/pwa/out/observatory/index.txt +30 -29
- package/apps/pwa/out/ops/checklist/index.html +1 -0
- package/apps/pwa/out/ops/checklist/index.txt +30 -0
- package/apps/pwa/out/ops/release/index.html +1 -0
- package/apps/pwa/out/ops/release/index.txt +30 -0
- package/apps/pwa/out/ops/seats/index.html +1 -0
- package/apps/pwa/out/ops/seats/index.txt +30 -0
- package/apps/pwa/out/reflection/index.html +1 -1
- package/apps/pwa/out/reflection/index.txt +28 -27
- package/apps/pwa/out/scheduler/index.html +1 -1
- package/apps/pwa/out/scheduler/index.txt +30 -29
- package/apps/pwa/out/sessions/index.html +1 -1
- package/apps/pwa/out/sessions/index.txt +27 -26
- package/apps/pwa/out/settings/devices/index.html +1 -1
- package/apps/pwa/out/settings/devices/index.txt +30 -29
- package/apps/pwa/out/settings/index.html +1 -1
- package/apps/pwa/out/settings/index.txt +30 -29
- package/apps/pwa/out/setup/done/index.html +1 -1
- package/apps/pwa/out/setup/done/index.txt +30 -29
- package/apps/pwa/out/setup/index.html +1 -1
- package/apps/pwa/out/setup/index.txt +30 -29
- package/apps/pwa/out/share/index.html +1 -1
- package/apps/pwa/out/share/index.txt +30 -29
- package/apps/pwa/out/showroom/index.html +1 -1
- package/apps/pwa/out/showroom/index.txt +27 -26
- package/apps/pwa/out/tasks/index.html +1 -1
- package/apps/pwa/out/tasks/index.txt +30 -29
- package/apps/pwa/out/term/index.html +1 -1
- package/apps/pwa/out/term/index.txt +30 -29
- package/apps/pwa/out/today/index.html +1 -0
- package/apps/pwa/out/today/index.txt +33 -0
- package/apps/pwa/out/trace/index.html +1 -1
- package/apps/pwa/out/trace/index.txt +30 -29
- package/apps/pwa/out/vault/index.html +1 -1
- package/apps/pwa/out/vault/index.txt +30 -29
- package/apps/pwa/out/workflows/chat-ui/index.html +1 -1
- package/apps/pwa/out/workflows/chat-ui/index.txt +30 -29
- package/apps/pwa/out/workflows/index.html +1 -1
- package/apps/pwa/out/workflows/index.txt +30 -29
- package/apps/pwa/out/workspace/index.html +1 -1
- package/apps/pwa/out/workspace/index.txt +30 -29
- package/apps/pwa/out/worktrees/index.html +1 -1
- package/apps/pwa/out/worktrees/index.txt +30 -29
- package/graphs/field/field-feed.yaml +2 -0
- package/graphs/implement-loop.yaml +1 -1
- package/graphs/release/recipes.yaml +3 -0
- package/graphs/release/release-loop.yaml +3 -1
- package/graphs/test-diet/nightly-audit.yaml +18 -0
- package/graphs/test-diet/recipes.yaml +3 -0
- package/package.json +1 -1
- package/plugins/card-followup/graphs/run-step.ts +48 -13
- package/plugins/doc-draft/graphs/doc-draft.yaml +3 -3
- package/plugins/doc-draft/graphs/run-step.ts +14 -7
- package/scripts/ci-pwa-build-gate.ts +160 -0
- package/scripts/coord-channel-watch.sh +42 -8
- package/scripts/coord-digest.ts +199 -0
- package/scripts/coord-post.sh +60 -3
- package/scripts/install.ps1 +68 -9
- package/scripts/install.sh +39 -12
- package/scripts/lib/pwa-scenarios/scenarios.ts +20 -0
- package/scripts/lib/tui-regress-checks.ts +146 -0
- package/scripts/memory-lifecycle-cycle.ts +2 -2
- package/scripts/ops-now-probe.ts +327 -0
- package/scripts/publish-internal-dist.ts +11 -1
- package/scripts/release-loop/cutoff.ts +31 -2
- package/scripts/release-loop/export-check-node.ts +85 -0
- package/scripts/release-loop/gate-node.ts +18 -4
- package/scripts/release-loop/node-verdict.ts +8 -1
- package/scripts/release-loop/ops-upgrade-node.ts +72 -16
- package/scripts/release-loop/release-readiness.ts +9 -0
- package/scripts/release-loop/version-node.ts +58 -10
- package/scripts/repo-watch-cycle.ts +1 -1
- package/scripts/retro-cycle.ts +2 -2
- package/scripts/schedule-health-report.ts +1 -1
- package/scripts/storyboard/storyboard.ts +5 -161
- package/scripts/test-diet/lib.ts +31 -1
- package/scripts/test-diet/node.ts +134 -17
- package/scripts/test-timeout-audit.ts +114 -0
- package/scripts/tree-sync-alert.ts +1 -1
- package/scripts/tui-regress.ts +71 -0
- package/scripts/waitlist-daily-digest.ts +1 -1
- package/skills/explainer-video/SKILL.md +4 -0
- package/skills/explainer-video/engine/reel.mjs +18 -13
- package/skills/explainer-video/engine/reel.sh +24 -5
- package/skills/explainer-video/engine/stitch.mjs +145 -0
- package/skills/pitch-deck/SKILL.md +36 -0
- package/skills/pitch-deck/template.html +80 -0
- package/src/acp/codex-approval-adapter.ts +9 -3
- package/src/acp/core-turn-bridge.ts +117 -18
- package/src/acp/fact-question.ts +11 -0
- package/src/acp/server.ts +48 -7
- package/src/acp/tool-approval.ts +126 -0
- package/src/acp/turn-runner.ts +36 -0
- package/src/agent/monad-agent-turn.ts +8 -0
- package/src/ask-user-question/pending-questions.ts +25 -10
- package/src/ask-user-question/types.ts +9 -0
- package/src/auth/setup-link-tokens.fixture.ts +19 -0
- package/src/auth/setup-link-tokens.ts +164 -0
- package/src/autopilot/build/integrity-gate.ts +12 -0
- package/src/boot/daemon-prompt-turn.ts +3 -0
- package/src/boot/daemon-tools/index.ts +8 -0
- package/src/boot/daemon-tools/types.ts +2 -0
- package/src/boot/daemon-tools/web-search.ts +1 -0
- package/src/budget/unified-usage.ts +75 -0
- package/src/channel-bot-token.ts +37 -10
- package/src/chat/ctrl-c-in-input.ts +14 -0
- package/src/chat/index.ts +61 -9
- package/src/chat/pickers/state.ts +6 -2
- package/src/cli/agent-cli.ts +7 -0
- package/src/cli/decisions-cli.ts +25 -3
- package/src/cli/doctor-bundle-upload.ts +68 -0
- package/src/cli/doctor-cli.ts +38 -4
- package/src/cli/op-proxy-sync.ts +83 -0
- package/src/cli/ops-cli.ts +20 -0
- package/src/cli/pod-cli.ts +49 -0
- package/src/cli/pr-cli.ts +37 -4
- package/src/cli/pwa-stop.ts +163 -13
- package/src/cli/pwa-test.ts +3 -0
- package/src/cli/release-cli.ts +98 -15
- package/src/cli/self-update.ts +14 -0
- package/src/cli/storyboard-cli.ts +37 -0
- package/src/cli/test-state-dir-flag.ts +11 -4
- package/src/connectors/linear.ts +146 -0
- package/src/context-bus/coord-events.ts +115 -0
- package/src/dashboard/dashboard-boot-fixture.ts +23 -0
- package/src/dashboard/dashboard-status-lines.ts +45 -0
- package/src/dashboard/first-screen-band.ts +35 -0
- package/src/dashboard/index.ts +128 -34
- package/src/dashboard/provider-slash-runtime.ts +28 -11
- package/src/dashboard/slash-runtime/dashboard-handlers.ts +17 -0
- package/src/dashboard/slash-runtime/help-from-registry.ts +43 -28
- package/src/dashboard/turn-stream-formatter.ts +1 -1
- package/src/decisions/decision-cards.ts +50 -2
- package/src/decisions/decision-ledger.ts +75 -4
- package/src/decisions/decision-linear-projection.ts +157 -0
- package/src/decisions/web-push-decision-cards.ts +50 -0
- package/src/directive/interpretation-card.ts +36 -0
- package/src/discord.ts +2 -1
- package/src/domains/coo-admin-tool.ts +62 -0
- package/src/domains/core-tools.ts +11 -3
- package/src/domains/elanous-card.ts +29 -0
- package/src/domains/ops-facts-tool.ts +76 -0
- package/src/domains/outbound-alert.ts +41 -13
- package/src/domains/release-tool.ts +168 -0
- package/src/domains/telegram-kind-route.ts +19 -1
- package/src/exec-requests/planner.ts +98 -28
- package/src/exec-requests/runner.ts +107 -10
- package/src/exec-requests/store.ts +8 -2
- package/src/field/field-media.ts +10 -7
- package/src/field/field-reel.ts +14 -4
- package/src/git-fs/worktree.ts +45 -6
- package/src/graph-runner/graph-approval-card.ts +113 -0
- package/src/graph-runner/graph-cli.ts +129 -4
- package/src/graph-runner/graph-notify.ts +25 -3
- package/src/graph-runner/runner.ts +142 -16
- package/src/harness/browser-verify.ts +25 -2
- package/src/harness/harness-cli-command.ts +231 -35
- package/src/harness/harness-incidents-writer.fixture.ts +24 -0
- package/src/harness/harness-incidents.ts +129 -0
- package/src/harness/harness-stop.ts +53 -3
- package/src/hitl/clarification-policy.ts +3 -1
- package/src/index.ts +172 -41
- package/src/intake-plane/author-goals.ts +37 -4
- package/src/intake-plane/check.ts +3 -0
- package/src/intake-plane/discord-seat-work.ts +47 -2
- package/src/intake-plane/seat-doc-route.ts +170 -6
- package/src/intake-plane/telegram-seat-work.ts +44 -2
- package/src/intake-plane/telegram-work.ts +1 -0
- package/src/maturity/cli-maturity.ts +34 -0
- package/src/maturity/feature-maturity.ts +100 -1
- package/src/maturity/tui-slash-maturity.ts +31 -0
- package/src/memory.ts +32 -4
- package/src/nexus/api/exec-requests.ts +33 -3
- package/src/nexus/api/http-server.ts +73 -1
- package/src/nexus/api/meta-api.ts +38 -0
- package/src/nexus/api/operator.ts +61 -0
- package/src/nexus/api/ops-api.ts +148 -0
- package/src/nexus/api/ops-seats-sources.ts +95 -0
- package/src/nexus/api/ops-seats.ts +124 -0
- package/src/nexus/api/public-routes.ts +14 -1
- package/src/nexus/api/seat-requests.ts +88 -8
- package/src/nexus/api/sessions-store.ts +63 -0
- package/src/nexus/api/setup-claim.ts +21 -0
- package/src/nexus/api/setup-codex-login.ts +160 -0
- package/src/nexus/api/usage-api.ts +102 -0
- package/src/nexus/config/secrets/file-backend.ts +56 -18
- package/src/nexus/index.ts +45 -4
- package/src/onboarding/first-run-doctor.ts +54 -0
- package/src/onboarding/first-run.ts +89 -0
- package/src/onboarding/lan-address.ts +45 -0
- package/src/onboarding/web-first.ts +119 -24
- package/src/onboarding.ts +4 -0
- package/src/ops-now/ops-now-refresh.ts +100 -0
- package/src/project/project-store.ts +115 -0
- package/src/release-loop/checklist.ts +76 -61
- package/src/release-loop/feature-store.ts +460 -0
- package/src/release-loop/manifest.ts +59 -5
- package/src/release-loop/release-schedule.ts +53 -0
- package/src/repl/index.ts +7 -0
- package/src/seat-dispatch/ceo-commands.ts +98 -0
- package/src/seat-dispatch/ceo-intent.ts +38 -0
- package/src/seat-loop/seat-loop.ts +231 -0
- package/src/seat-loop/seat-report.ts +64 -0
- package/src/self-dev/decompose.ts +66 -11
- package/src/self-dev/run-store.ts +10 -1
- package/src/self-implement/execution-clarification.ts +115 -0
- package/src/self-implement/gate-cli.ts +6 -3
- package/src/self-implement/orchestrator.ts +37 -3
- package/src/self-implement/pipeline-shape.ts +1 -1
- package/src/self-implement/run-status-mapping.ts +5 -3
- package/src/session/chat.ts +2 -0
- package/src/session/index.ts +9 -0
- package/src/shell-env-bootstrap.ts +17 -0
- package/src/skills/tools/usage-slash.ts +8 -7
- package/src/steward/directive.ts +51 -2
- package/src/steward/launch.ts +250 -0
- package/src/steward/outcome-notify.ts +115 -0
- package/src/steward/steward-cards.ts +8 -2
- package/src/steward/triage-plan.ts +32 -4
- package/src/steward/triage.ts +93 -9
- package/src/steward/working-backwards.ts +64 -0
- package/src/storyboard/storyboard.ts +141 -0
- package/src/task-cards/card-store.ts +2 -2
- package/src/task-orchestrator/surfaces/pod-lease.ts +260 -0
- package/src/telegram-card-followup.ts +233 -0
- package/src/telegram-commands.ts +16 -0
- package/src/telegram-report.ts +15 -9
- package/src/telegram-run.ts +90 -13
- package/src/telegram.ts +29 -8
- package/src/thinking-line.ts +28 -20
- package/src/tool-runtime/types.ts +4 -0
- package/src/tui/chat/execution-badge.ts +1 -1
- package/src/tui-client/dashboard-session.ts +2 -0
- package/src/user-config.ts +118 -11
- package/src/ux-sim/turn-states.ts +1 -1
- package/src/version/packed-revision.json +1 -1
- package/src/web-push/notify-exec-request.ts +32 -0
- package/apps/pwa/out/_next/static/chunks/1201-09613bce624467c0.js +0 -1
- package/apps/pwa/out/_next/static/chunks/2929-617f1e66a55be184.js +0 -1
- package/apps/pwa/out/_next/static/chunks/3441-a1dd4acfeda14488.js +0 -1
- package/apps/pwa/out/_next/static/chunks/4836-3084c58c1725a40b.js +0 -1
- package/apps/pwa/out/_next/static/chunks/6090-85a3f05f954e5697.js +0 -1
- package/apps/pwa/out/_next/static/chunks/6284-69db415193d5f8bd.js +0 -1
- package/apps/pwa/out/_next/static/chunks/6416-505ba707cacafbba.js +0 -1
- package/apps/pwa/out/_next/static/chunks/7032-f4ef698518fba61c.js +0 -1
- package/apps/pwa/out/_next/static/chunks/8067-d976b441a104ab74.js +0 -1
- package/apps/pwa/out/_next/static/chunks/8519-5632377cce994f86.js +0 -1
- package/apps/pwa/out/_next/static/chunks/8894-7317998f6cb97d8c.js +0 -1
- package/apps/pwa/out/_next/static/chunks/9454-a3e0953307216c58.js +0 -1
- package/apps/pwa/out/_next/static/chunks/9740-8f5ff96c522b5f55.js +0 -1
- package/apps/pwa/out/_next/static/chunks/app/approvals/page-9aa47b0bc6d570ff.js +0 -1
- package/apps/pwa/out/_next/static/chunks/app/autopilot/page-f4d2ecbbae6088d6.js +0 -1
- package/apps/pwa/out/_next/static/chunks/app/board/page-2053e49930c82748.js +0 -1
- package/apps/pwa/out/_next/static/chunks/app/bots/page-a70ba27c33003dd0.js +0 -1
- package/apps/pwa/out/_next/static/chunks/app/consult/page-18166f885d831d3e.js +0 -1
- package/apps/pwa/out/_next/static/chunks/app/control/page-1c9d6cfe68b121c2.js +0 -1
- package/apps/pwa/out/_next/static/chunks/app/editor/page-c108ff1fdb665c97.js +0 -1
- package/apps/pwa/out/_next/static/chunks/app/exec/page-147a328753d983e2.js +0 -1
- package/apps/pwa/out/_next/static/chunks/app/field/page-799395a9df7d95aa.js +0 -1
- package/apps/pwa/out/_next/static/chunks/app/intake/page-6a8158b71d1fe9d7.js +0 -1
- package/apps/pwa/out/_next/static/chunks/app/layout-9567560270857531.js +0 -1
- package/apps/pwa/out/_next/static/chunks/app/live/page-e7ed3d010153d818.js +0 -1
- package/apps/pwa/out/_next/static/chunks/app/morning/page-b672e02e4bec8deb.js +0 -1
- package/apps/pwa/out/_next/static/chunks/app/not-found-1ba4a5d857276334.js +0 -1
- package/apps/pwa/out/_next/static/chunks/app/observatory/page-9db2226f38c542fb.js +0 -1
- package/apps/pwa/out/_next/static/chunks/app/page-70ee65f5f7a151dc.js +0 -1
- package/apps/pwa/out/_next/static/chunks/app/reflection/page-0bb8e43203efb23b.js +0 -1
- package/apps/pwa/out/_next/static/chunks/app/scheduler/page-092e1bcf27d751cc.js +0 -1
- package/apps/pwa/out/_next/static/chunks/app/sessions/page-eb52580c4b75b905.js +0 -1
- package/apps/pwa/out/_next/static/chunks/app/settings/page-e573437b0a1c728f.js +0 -1
- package/apps/pwa/out/_next/static/chunks/app/setup/done/page-294300625e49e4d3.js +0 -1
- package/apps/pwa/out/_next/static/chunks/app/setup/page-085847b088675978.js +0 -1
- package/apps/pwa/out/_next/static/chunks/app/share/page-9fe9d38c36999eb4.js +0 -1
- package/apps/pwa/out/_next/static/chunks/app/tasks/page-6141f67f531d8b6a.js +0 -1
- package/apps/pwa/out/_next/static/chunks/app/term/page-295a02b1026b8255.js +0 -1
- package/apps/pwa/out/_next/static/chunks/app/trace/page-1eb9a0e1e054209d.js +0 -1
- package/apps/pwa/out/_next/static/chunks/app/vault/page-82efa177a30f3741.js +0 -1
- package/apps/pwa/out/_next/static/chunks/app/workflows/chat-ui/page-d0be51cec4f62606.js +0 -1
- package/apps/pwa/out/_next/static/chunks/app/workflows/page-2e367075ffdbc062.js +0 -1
- package/apps/pwa/out/_next/static/chunks/app/workspace/page-647ed2b66c1d49f1.js +0 -1
- package/apps/pwa/out/_next/static/chunks/app/worktrees/page-ba058c56e38f2792.js +0 -1
- package/apps/pwa/out/_next/static/chunks/main-app-6870f30ea99f8346.js +0 -1
- package/apps/pwa/out/_next/static/css/5ef72a618a8994f3.css +0 -1
- package/apps/pwa/out/_next/static/lywc8m_HDzH9MKSDQhyEj/_buildManifest.js +0 -1
- package/src/dashboard/turn-typeahead-echo.ts +0 -23
- /package/apps/pwa/out/_next/static/{lywc8m_HDzH9MKSDQhyEj → 2DsiDfDCks44g1cPUMhiW}/_ssgManifest.js +0 -0
package/src/telegram-run.ts
CHANGED
|
@@ -11,9 +11,14 @@
|
|
|
11
11
|
// - 워크플로 트리거는 core 의 `POST /v1/workflows/telegram-dispatch` 로 넘긴다(`telegram-dispatch-forward.ts`).
|
|
12
12
|
|
|
13
13
|
import { debug } from './debug/log.js';
|
|
14
|
+
import { existsSync, mkdirSync, readFileSync, renameSync, unlinkSync, writeFileSync } from 'node:fs';
|
|
15
|
+
import { randomUUID } from 'node:crypto';
|
|
16
|
+
import { dirname, join } from 'node:path';
|
|
17
|
+
import { effectiveInstanceRoot } from './instance/resolve.js';
|
|
14
18
|
import { getUserConfig } from './user-config.js';
|
|
15
19
|
import { resolveChannelBotToken } from './channel-bot-token.js';
|
|
16
20
|
import { forwardTelegramDispatch } from './telegram-dispatch-forward.js';
|
|
21
|
+
import { mergeCapturedPath, warmCapturedEnv } from './shell-env-bootstrap.js';
|
|
17
22
|
import type { NexusTelegramQaPollerWireHandle } from './nexus/index.js';
|
|
18
23
|
|
|
19
24
|
export interface TelegramRunResult {
|
|
@@ -55,10 +60,10 @@ export function setTelegramPollLockForTesting(deps: typeof pollLockForTesting):
|
|
|
55
60
|
/** 폴러를 띄우고 핸들을 돌려준다(시험용으로 분리 — 대기는 `runTelegramPoller` 가 한다). */
|
|
56
61
|
export async function startTelegramPollers(): Promise<TelegramRunResult> {
|
|
57
62
|
const cfg = getUserConfig();
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
63
|
+
if (cfg.telegram.enabled === false) throw new Error('telegram run: telegram.enabled 가 꺼져 있다');
|
|
64
|
+
const resolved = resolveChannelBotToken('telegram', cfg);
|
|
65
|
+
if (!resolved.token) throw new Error(`telegram run: bot token 못 풂 — ${resolved.reason}`);
|
|
66
|
+
const mainToken = resolved.token;
|
|
62
67
|
if (cfg.telegram.poller !== 'standalone') {
|
|
63
68
|
console.warn('[telegram run] ⚠️ telegram.poller 가 standalone 이 아니다 — 넥서스도 같은 토큰을 폴링하려 한다. 토큰 잠금이 먼저 잡은 쪽만 띄운다.');
|
|
64
69
|
}
|
|
@@ -105,25 +110,97 @@ export async function startTelegramPollers(): Promise<TelegramRunResult> {
|
|
|
105
110
|
return { started, refusedBotIds, late };
|
|
106
111
|
}
|
|
107
112
|
|
|
108
|
-
|
|
109
|
-
|
|
113
|
+
function failurePath(): string { return join(effectiveInstanceRoot(), 'telegram', 'run-failures.json'); }
|
|
114
|
+
|
|
115
|
+
function failureState(): { count: number; alerted: boolean } {
|
|
116
|
+
const path = failurePath();
|
|
117
|
+
if (!existsSync(path)) return { count: 0, alerted: false };
|
|
118
|
+
const data: unknown = JSON.parse(readFileSync(path, 'utf8'));
|
|
119
|
+
if (!data || typeof data !== 'object' || !('count' in data) || !Number.isSafeInteger(data.count)
|
|
120
|
+
|| (data.count as number) < 0 || ('alerted' in data && typeof data.alerted !== 'boolean')) {
|
|
121
|
+
throw new Error(`invalid telegram run failures at ${path}`);
|
|
122
|
+
}
|
|
123
|
+
return { count: data.count as number, alerted: 'alerted' in data ? data.alerted as boolean : false };
|
|
124
|
+
}
|
|
125
|
+
|
|
126
|
+
function writeFailureState(count: number, alerted: boolean): void {
|
|
127
|
+
const path = failurePath();
|
|
128
|
+
mkdirSync(dirname(path), { recursive: true });
|
|
129
|
+
const tmp = `${path}.${randomUUID()}.tmp`;
|
|
130
|
+
try {
|
|
131
|
+
writeFileSync(tmp, JSON.stringify({ count, alerted }), { mode: 0o600, flag: 'wx' });
|
|
132
|
+
renameSync(tmp, path);
|
|
133
|
+
} finally { if (existsSync(tmp)) unlinkSync(tmp); }
|
|
134
|
+
}
|
|
135
|
+
|
|
136
|
+
/** SIGINT/SIGTERM 까지 돈다. Failure exit policy is tested without a live poller. */
|
|
137
|
+
export async function runTelegramPoller(deps: {
|
|
138
|
+
start?: typeof startTelegramPollers;
|
|
139
|
+
alert?: (text: string, kind: string) => boolean;
|
|
140
|
+
wait?: () => Promise<void>;
|
|
141
|
+
registerLogSink?: () => Promise<void>;
|
|
142
|
+
warm?: () => Promise<boolean>;
|
|
143
|
+
} = {}): Promise<void> {
|
|
144
|
+
void (deps.warm ?? warmCapturedEnv)().then((ok) => {
|
|
145
|
+
if (ok) mergeCapturedPath();
|
|
146
|
+
}).catch((error) => {
|
|
147
|
+
debug.log('shell.envbootstrap.capture', 'warm-failed', { error: String(error) });
|
|
148
|
+
});
|
|
110
149
|
try {
|
|
111
|
-
|
|
112
|
-
|
|
150
|
+
if (deps.registerLogSink) await deps.registerLogSink();
|
|
151
|
+
else {
|
|
152
|
+
const { registerStandaloneLogSink } = await import('./domains/standalone-log-sink.js');
|
|
153
|
+
await registerStandaloneLogSink('telegram-run');
|
|
154
|
+
}
|
|
113
155
|
} catch (e) {
|
|
114
156
|
console.error(`[telegram run] ⚠️ 로그 싱크 등록 실패(관측 유실 가능): ${e instanceof Error ? e.message : String(e)}`);
|
|
115
157
|
}
|
|
116
158
|
console.log('[telegram run] 토큰 잠금을 잡는 중 (토큰마다 최대 30초)…');
|
|
117
|
-
|
|
159
|
+
let result: TelegramRunResult;
|
|
160
|
+
try {
|
|
161
|
+
if (!deps.start) {
|
|
162
|
+
const [{ registerAllCloudBackends }, { selectBackendFromConfig }] = await Promise.all([
|
|
163
|
+
import('./nexus/config/secrets/register-cloud.js'), import('./nexus/config/secrets/registry.js'),
|
|
164
|
+
]);
|
|
165
|
+
registerAllCloudBackends();
|
|
166
|
+
selectBackendFromConfig();
|
|
167
|
+
}
|
|
168
|
+
result = await (deps.start ?? startTelegramPollers)();
|
|
169
|
+
if (result.started.length === 0) throw new Error('telegram run: 띄운 폴러가 없다');
|
|
170
|
+
} catch (error) {
|
|
171
|
+
const reason = error instanceof Error ? error.message : 'unknown start failure';
|
|
172
|
+
const previous = failureState();
|
|
173
|
+
const count = previous.count + 1;
|
|
174
|
+
writeFailureState(count, previous.alerted);
|
|
175
|
+
debug.log('telegram.run', 'start-failed', { count, reason });
|
|
176
|
+
if (count >= 3) {
|
|
177
|
+
if (!previous.alerted) {
|
|
178
|
+
try {
|
|
179
|
+
const alert = deps.alert ?? (await import('./domains/outbound-alert.js')).sendOutbound;
|
|
180
|
+
if (!alert(`텔레그램 폴러가 3번 연속 못 떴다 — ${reason}`, 'alert')) {
|
|
181
|
+
throw new Error('telegram run: outbound alert not delivered');
|
|
182
|
+
}
|
|
183
|
+
} catch (alertError) {
|
|
184
|
+
debug.log('telegram.run', 'alert-failed', { count, reason });
|
|
185
|
+
throw alertError;
|
|
186
|
+
}
|
|
187
|
+
writeFailureState(count, true);
|
|
188
|
+
debug.log('telegram.run', 'alerted', { count, reason });
|
|
189
|
+
}
|
|
190
|
+
return;
|
|
191
|
+
}
|
|
192
|
+
throw error;
|
|
193
|
+
}
|
|
194
|
+
const { started, refusedBotIds, late } = result;
|
|
195
|
+
const path = failurePath();
|
|
196
|
+
if (existsSync(path)) unlinkSync(path);
|
|
118
197
|
debug.log('telegram.run', 'started', { pid: process.pid, pollers: started.length, refusedBotIds });
|
|
119
198
|
for (const botId of refusedBotIds) {
|
|
120
199
|
console.warn(`[telegram run] 봇 ${botId}: 다른 프로세스가 폴링 중 — 15초마다 다시 잡으러 간다 (elanous logs --category telegram.run)`);
|
|
121
200
|
}
|
|
122
|
-
// 하나도 못 잡았으면 끝낸다(exit≠0) — 서비스 관리자(launchd KeepAlive·systemd Restart)가 다시 띄운다.
|
|
123
|
-
if (started.length === 0) throw new Error('telegram run: 띄운 폴러가 없다');
|
|
124
201
|
for (const { channel } of started) console.log(`[telegram run] 채널 '${channel.name}' 폴러 활성 (${channel.botToken.split(':')[0]})`);
|
|
125
202
|
console.log('[telegram run] Ctrl-C 로 멈춘다.');
|
|
126
|
-
await new Promise<void>((resolve) => {
|
|
203
|
+
await (deps.wait?.() ?? new Promise<void>((resolve) => {
|
|
127
204
|
const stop = (): void => {
|
|
128
205
|
process.off('SIGINT', stop);
|
|
129
206
|
process.off('SIGTERM', stop);
|
|
@@ -135,5 +212,5 @@ export async function runTelegramPoller(): Promise<void> {
|
|
|
135
212
|
};
|
|
136
213
|
process.on('SIGINT', stop);
|
|
137
214
|
process.on('SIGTERM', stop);
|
|
138
|
-
});
|
|
215
|
+
}));
|
|
139
216
|
}
|
package/src/telegram.ts
CHANGED
|
@@ -71,6 +71,7 @@ import { effectiveInstanceRoot } from './instance/resolve.js';
|
|
|
71
71
|
import { getElanousConfigDir } from './elanous-config-dir.js';
|
|
72
72
|
import { defaultFieldEvent, FieldUploadError, parseFieldCaption, resolveFieldMime, saveFieldMedia } from './field/field-media.js';
|
|
73
73
|
import { scheduleFieldReel, type FieldReelOptions } from './field/field-reel.js';
|
|
74
|
+
import { maybeHandleCardPhoto, type CardPhotoDeps } from './telegram-card-followup.js';
|
|
74
75
|
|
|
75
76
|
export type TgAttachmentKind = 'photo' | 'voice' | 'audio' | 'document';
|
|
76
77
|
|
|
@@ -216,6 +217,8 @@ export interface TelegramBotOpts {
|
|
|
216
217
|
fieldRootDir?: () => string;
|
|
217
218
|
/** 시험에서는 실제 렌더 대신 가짜 실행기를 주입한다. */
|
|
218
219
|
fieldReel?: FieldReelOptions;
|
|
220
|
+
/** Test seam for the business-card graph and its private run root. */
|
|
221
|
+
cardFollowupDeps?: Pick<CardPhotoDeps, 'runGraph' | 'rootDir' | 'ocrText'>;
|
|
219
222
|
}
|
|
220
223
|
|
|
221
224
|
/** Surface-unification v2 (FU-2) — Telegram trigger event passed to
|
|
@@ -333,10 +336,11 @@ export class TelegramBot {
|
|
|
333
336
|
private readonly fieldDefaultEventOpt?: string;
|
|
334
337
|
private readonly fieldRootDir: () => string;
|
|
335
338
|
private readonly fieldReel?: FieldReelOptions;
|
|
339
|
+
private readonly cardFollowupDeps: Pick<CardPhotoDeps, 'runGraph' | 'rootDir' | 'ocrText'>;
|
|
336
340
|
private readonly seatWorkDeps: TelegramSeatWorkDeps;
|
|
337
341
|
/** 앨범 id → `#현장` 행사 · 답장 디바운스. 태그된 앨범만 들어온다. */
|
|
338
342
|
private readonly fieldGroups = new Map<string, {
|
|
339
|
-
event: string; at: number; chatId: number; threadId?: number; replyTo: number; count: number;
|
|
343
|
+
event: string; mode?: 'instant'; at: number; chatId: number; threadId?: number; replyTo: number; count: number;
|
|
340
344
|
timer?: ReturnType<typeof setTimeout>;
|
|
341
345
|
}>();
|
|
342
346
|
|
|
@@ -368,6 +372,7 @@ export class TelegramBot {
|
|
|
368
372
|
this.fieldDefaultEventOpt = opts.fieldDefaultEvent;
|
|
369
373
|
this.fieldRootDir = opts.fieldRootDir ?? getElanousConfigDir;
|
|
370
374
|
this.fieldReel = opts.fieldReel;
|
|
375
|
+
this.cardFollowupDeps = opts.cardFollowupDeps ?? {};
|
|
371
376
|
this.seatWorkDeps = opts.seatWorkDeps ?? {};
|
|
372
377
|
if (opts.onTriggerTap) {
|
|
373
378
|
// Assign through `as unknown` to bypass `readonly` + private —
|
|
@@ -376,7 +381,7 @@ export class TelegramBot {
|
|
|
376
381
|
}
|
|
377
382
|
}
|
|
378
383
|
|
|
379
|
-
|
|
384
|
+
isOwnerAllowed(userId: number): boolean {
|
|
380
385
|
return this.allowedUsers.size > 0 && this.allowedUsers.has(userId);
|
|
381
386
|
}
|
|
382
387
|
|
|
@@ -1415,6 +1420,10 @@ export class TelegramBot {
|
|
|
1415
1420
|
? tag.event ?? defaultFieldEvent(
|
|
1416
1421
|
this.fieldDefaultEventOpt ?? this.slashContext?.userConfig?.telegram?.fieldDefaultEvent, new Date(now))
|
|
1417
1422
|
: group!.event;
|
|
1423
|
+
const captionMode = tag?.mode ?? group?.mode;
|
|
1424
|
+
const configMode = this.slashContext?.userConfig?.telegram?.fieldReelMode;
|
|
1425
|
+
const mode = captionMode ?? configMode ?? 'standard';
|
|
1426
|
+
const source = captionMode ? 'caption' : configMode ? 'config' : 'default';
|
|
1418
1427
|
|
|
1419
1428
|
let count: number | null = null;
|
|
1420
1429
|
let failure: string | null = null;
|
|
@@ -1435,14 +1444,16 @@ export class TelegramBot {
|
|
|
1435
1444
|
// 글(자막)은 캡션이 달린 항목에만 있다 — 앨범이면 첫 장에만 붙는다(MK 2026-09-30).
|
|
1436
1445
|
const saved = saveFieldMedia(inputs, { rootDir: this.fieldRootDir(), event, device: 'telegram', ...(tag?.text ? { caption: tag.text } : {}) });
|
|
1437
1446
|
count = saved.count;
|
|
1447
|
+
debug.log('telegram.field', 'reel-mode', { event, mode, source });
|
|
1438
1448
|
scheduleFieldReel(saved.dir, {
|
|
1439
1449
|
...this.fieldReel,
|
|
1450
|
+
mode,
|
|
1440
1451
|
notificationKey: `telegram:${this.botId}:${ctx.chatId}:${ctx.threadId ?? ''}:${ctx.mediaGroupId ?? ctx.messageId}`,
|
|
1441
1452
|
onDone: async (result) => {
|
|
1442
1453
|
const reply = { replyTo: ctx.messageId, threadId: ctx.threadId };
|
|
1443
1454
|
if (result.ok && result.file) {
|
|
1444
1455
|
const sent = await this.sendDocument(ctx.chatId, readFileSync(result.file), 'reel-9x16.mp4', {
|
|
1445
|
-
...reply, mimeType: 'video/mp4', caption: `현장 영상 · ${event} · ${result.seconds}
|
|
1456
|
+
...reply, mimeType: 'video/mp4', caption: `현장 영상 · ${event} · ${result.seconds}초${mode === 'instant' ? ' (즉석판)' : ''}`,
|
|
1446
1457
|
});
|
|
1447
1458
|
if (!sent) throw new Error('sendDocument failed');
|
|
1448
1459
|
if (result.feed?.started) {
|
|
@@ -1469,7 +1480,8 @@ export class TelegramBot {
|
|
|
1469
1480
|
return true;
|
|
1470
1481
|
}
|
|
1471
1482
|
// 앨범은 항목마다 답하지 않는다 — 마지막 항목 뒤 한 번(디바운스)만 최신 수로 답한다.
|
|
1472
|
-
const entry = group ?? { event, at: now, chatId: ctx.chatId, threadId: ctx.threadId, replyTo: ctx.messageId, count: 0 };
|
|
1483
|
+
const entry = group ?? { event, mode: tag?.mode, at: now, chatId: ctx.chatId, threadId: ctx.threadId, replyTo: ctx.messageId, count: 0 };
|
|
1484
|
+
if (group && tag?.mode) group.mode = tag.mode;
|
|
1473
1485
|
entry.at = now;
|
|
1474
1486
|
entry.count = count!;
|
|
1475
1487
|
if (entry.timer) clearTimeout(entry.timer);
|
|
@@ -1490,10 +1502,18 @@ export class TelegramBot {
|
|
|
1490
1502
|
}
|
|
1491
1503
|
// 현장 업로드 — `#현장` 캡션(또는 태그된 앨범의 나머지)의 사진·영상은 LLM 대신 현장 폴더로.
|
|
1492
1504
|
if (await this.tryHandleFieldUpload(ctx)) return;
|
|
1493
|
-
if (ctx
|
|
1505
|
+
if (await maybeHandleCardPhoto(ctx, {
|
|
1506
|
+
isOwner: (userId) => this.isOwnerAllowed(userId),
|
|
1507
|
+
isFieldAlbum: (id) => this.fieldGroups.has(id),
|
|
1508
|
+
downloadFile: (fileId, dir) => this.downloadFile(fileId, dir),
|
|
1509
|
+
sendMessage: (chatId, text, opts) => this.sendMessage(chatId, text, opts),
|
|
1510
|
+
sendDocument: (chatId, body, filename, opts) => this.sendDocument(chatId, body, filename, opts),
|
|
1511
|
+
...this.cardFollowupDeps,
|
|
1512
|
+
})) return;
|
|
1513
|
+
if (ctx.text.startsWith('@') || (ctx.isDm && ctx.text && !ctx.text.startsWith('/'))) {
|
|
1494
1514
|
const reply = await handleTelegramSeatWork(ctx.text, {
|
|
1495
|
-
chatId: ctx.chatId, messageId: ctx.messageId, threadId: ctx.threadId, botId: ctx.botId,
|
|
1496
|
-
}, this.seatWorkDeps);
|
|
1515
|
+
chatId: ctx.chatId, userId: ctx.userId, messageId: ctx.messageId, threadId: ctx.threadId, botId: ctx.botId,
|
|
1516
|
+
}, { ...this.seatWorkDeps, config: this.seatWorkDeps.config ?? this.slashContext?.userConfig });
|
|
1497
1517
|
if (reply !== null) {
|
|
1498
1518
|
await this.sendMessage(ctx.chatId, reply, { replyTo: ctx.messageId, threadId: ctx.threadId });
|
|
1499
1519
|
return;
|
|
@@ -1529,7 +1549,7 @@ export class TelegramBot {
|
|
|
1529
1549
|
try {
|
|
1530
1550
|
const { addDirective } = await import('./steward/directive.js');
|
|
1531
1551
|
const text = ctx.text.startsWith('지시:') ? ctx.text.slice('지시:'.length) : ctx.text.slice('/directive '.length);
|
|
1532
|
-
const result = await addDirective(text, { source: 'telegram' });
|
|
1552
|
+
const result = await addDirective(text, { source: 'telegram', origin: { chatId: ctx.chatId, botId: ctx.botId, threadId: ctx.threadId } });
|
|
1533
1553
|
await this.sendMessage(ctx.chatId, `${result.issue}: ${result.status}`, { replyTo: ctx.messageId, threadId: ctx.threadId });
|
|
1534
1554
|
} catch {
|
|
1535
1555
|
await this.sendMessage(ctx.chatId, '지시 등록 실패 — Linear 연결과 자격을 확인하세요.', { replyTo: ctx.messageId, threadId: ctx.threadId });
|
|
@@ -2746,6 +2766,7 @@ export function botFromConfig(opts: BotFromConfigOpts): TelegramBot {
|
|
|
2746
2766
|
// (makeTelegramAgentRunTurn) threads it into `delegate_code_agent`
|
|
2747
2767
|
// so a delegated sub-agent's approval prompt lands back here.
|
|
2748
2768
|
hitlConfirmChannel: botRef.hitlConfirmChannelForChat(ctx.chatId, ctx.threadId),
|
|
2769
|
+
...(botRef.isOwnerAllowed(ctx.userId) ? { verifiedOwner: { id: `telegram:${ctx.userId}` } } : {}),
|
|
2749
2770
|
hitlQuestionChannel: botRef.hitlQuestionChannelForChat(ctx.chatId, ctx.threadId),
|
|
2750
2771
|
// P1.4 — surface file spill bound to THIS chat so the NL
|
|
2751
2772
|
// `delegate_code_agent` path spills big diffs/stdout back here.
|
package/src/thinking-line.ts
CHANGED
|
@@ -156,6 +156,14 @@ function renderLine(
|
|
|
156
156
|
return `${applyColor(glyph, 'claude')} ${C.muted(message + '…')}${tail}`;
|
|
157
157
|
}
|
|
158
158
|
|
|
159
|
+
function stoppedMessage(message: string, status: ThinkingStatus): string {
|
|
160
|
+
const taskName = message.replace(/^(?:Streaming|Thinking)(?=\b|…)(?:\s*…)?\s*/, '').trim();
|
|
161
|
+
const task = taskName ? `${taskName} ` : '';
|
|
162
|
+
if (status === 'completed') return `${task}완료`;
|
|
163
|
+
if (status === 'interrupted') return `${task}중단됨`;
|
|
164
|
+
return `${task}실패`;
|
|
165
|
+
}
|
|
166
|
+
|
|
159
167
|
export function startThinking(opts: StartThinkingOpts): ThinkingHandle {
|
|
160
168
|
let message = opts.message ?? 'Thinking';
|
|
161
169
|
let messageFactory: ((frame: number) => string) | null = null;
|
|
@@ -222,20 +230,19 @@ export function startThinking(opts: StartThinkingOpts): ThinkingHandle {
|
|
|
222
230
|
if (metrics.engine) detail.push(metrics.engine);
|
|
223
231
|
const tail = detail.length ? ' ' + C.muted('(' + detail.join(' · ') + ')') : '';
|
|
224
232
|
let finalText: string;
|
|
225
|
-
if (stopOpts?.finalText) {
|
|
233
|
+
if (stopOpts?.finalText !== undefined) {
|
|
226
234
|
finalText = stopOpts.finalText;
|
|
227
|
-
} else if (status === 'completed') {
|
|
228
|
-
// Green tick + verb kept visible (not muted) so it stands out.
|
|
229
|
-
const currentMessage = messageFactory ? messageFactory(frame) : message;
|
|
230
|
-
finalText = `${applyColor(FIGURES.TICK, 'success')} ${C.success(currentMessage)}${tail}`;
|
|
231
|
-
} else if (status === 'interrupted') {
|
|
232
|
-
const currentMessage = messageFactory ? messageFactory(frame) : message;
|
|
233
|
-
finalText = `${applyColor(FIGURES.CROSS, 'error')} ${C.warning(currentMessage + ' · interrupted')}${tail}`;
|
|
234
235
|
} else {
|
|
235
|
-
// failed
|
|
236
|
-
const err = stopOpts?.errorText ? ` — ${stopOpts.errorText}` : '';
|
|
237
236
|
const currentMessage = messageFactory ? messageFactory(frame) : message;
|
|
238
|
-
|
|
237
|
+
const label = stoppedMessage(currentMessage, status);
|
|
238
|
+
if (status === 'completed') {
|
|
239
|
+
finalText = `${applyColor(FIGURES.TICK, 'success')} ${C.success(label)}${tail}`;
|
|
240
|
+
} else if (status === 'interrupted') {
|
|
241
|
+
finalText = `${applyColor(FIGURES.CROSS, 'error')} ${C.warning(label)}${tail}`;
|
|
242
|
+
} else {
|
|
243
|
+
const err = stopOpts?.errorText ? ` — ${stopOpts.errorText}` : '';
|
|
244
|
+
finalText = `${applyColor(FIGURES.CROSS, 'error')} ${C.error(label + err)}${tail}`;
|
|
245
|
+
}
|
|
239
246
|
}
|
|
240
247
|
|
|
241
248
|
// Freeze at tail if sticky='tail' — the indicator was tracking
|
|
@@ -310,18 +317,19 @@ export function startPinnedThinking(opts: StartPinnedThinkingOpts): ThinkingHand
|
|
|
310
317
|
if (metrics.engine) detail.push(metrics.engine);
|
|
311
318
|
const tail = detail.length ? ' ' + C.muted('(' + detail.join(' · ') + ')') : '';
|
|
312
319
|
let finalText: string;
|
|
313
|
-
if (stopOpts?.finalText) {
|
|
320
|
+
if (stopOpts?.finalText !== undefined) {
|
|
314
321
|
finalText = stopOpts.finalText;
|
|
315
|
-
} else if (status === 'completed') {
|
|
316
|
-
const currentMessage = messageFactory ? messageFactory(frame) : message;
|
|
317
|
-
finalText = `${applyColor(FIGURES.TICK, 'success')} ${C.success(currentMessage)}${tail}`;
|
|
318
|
-
} else if (status === 'interrupted') {
|
|
319
|
-
const currentMessage = messageFactory ? messageFactory(frame) : message;
|
|
320
|
-
finalText = `${applyColor(FIGURES.CROSS, 'error')} ${C.warning(currentMessage + ' · interrupted')}${tail}`;
|
|
321
322
|
} else {
|
|
322
|
-
const err = stopOpts?.errorText ? ` — ${stopOpts.errorText}` : '';
|
|
323
323
|
const currentMessage = messageFactory ? messageFactory(frame) : message;
|
|
324
|
-
|
|
324
|
+
const label = stoppedMessage(currentMessage, status);
|
|
325
|
+
if (status === 'completed') {
|
|
326
|
+
finalText = `${applyColor(FIGURES.TICK, 'success')} ${C.success(label)}${tail}`;
|
|
327
|
+
} else if (status === 'interrupted') {
|
|
328
|
+
finalText = `${applyColor(FIGURES.CROSS, 'error')} ${C.warning(label)}${tail}`;
|
|
329
|
+
} else {
|
|
330
|
+
const err = stopOpts?.errorText ? ` — ${stopOpts.errorText}` : '';
|
|
331
|
+
finalText = `${applyColor(FIGURES.CROSS, 'error')} ${C.error(label + err)}${tail}`;
|
|
332
|
+
}
|
|
325
333
|
}
|
|
326
334
|
opts.target.current = finalText;
|
|
327
335
|
opts.onFrame();
|
|
@@ -91,8 +91,12 @@ export interface ToolRuntimeContext {
|
|
|
91
91
|
sessionId?: string;
|
|
92
92
|
/** Session that originated this execution when it was delegated through another runtime session. */
|
|
93
93
|
originSessionId?: string;
|
|
94
|
+
/** Server-verified owner principal. Never derive this from session source, tool args, or a client-declared origin. */
|
|
95
|
+
verifiedOwner?: { id: string };
|
|
94
96
|
/** Server-assigned provenance; omitted on existing owner tool paths. */
|
|
95
97
|
requestOrigin?: RequestOrigin;
|
|
98
|
+
/** Confirm through the originating chat's channels, not another user's global channel. */
|
|
99
|
+
confirmChannels?: import('../hitl/confirm.js').ConfirmChannel[];
|
|
96
100
|
}
|
|
97
101
|
|
|
98
102
|
/** Output shape the LLM layer expects back. Most tools produce
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
// ── TUI TRUE-execution badge (self-cognition §1) ──────────────────────
|
|
2
2
|
//
|
|
3
3
|
// Resolves the compact engine/model badge for the dashboard chat
|
|
4
|
-
// completion line — `✔
|
|
4
|
+
// completion line — `✔ 완료 (19s · ↓ 200 tokens · 🧠 terra(high))`.
|
|
5
5
|
// The value is the model that ACTUALLY ran this turn (from the route
|
|
6
6
|
// decision recorded in the ACP bridge's getActiveModel), not the config
|
|
7
7
|
// original — so the "config=opus but codex/terra ran" illusion is
|
|
@@ -210,6 +210,8 @@ export class DashboardSession {
|
|
|
210
210
|
transportFactory: pair.transportFactory,
|
|
211
211
|
shutdownSignal: shutdownCtrl.signal,
|
|
212
212
|
runTurn,
|
|
213
|
+
// PCH-2b — the in-process TUI dispatcher carries its own approval modals.
|
|
214
|
+
toolApproval: 'off',
|
|
213
215
|
...(opts.agentName ? { agentName: opts.agentName } : {}),
|
|
214
216
|
...(opts.agentVersion ? { agentVersion: opts.agentVersion } : {}),
|
|
215
217
|
...(opts.serverOptions ?? {}),
|