elanous 0.2.18 → 0.2.20
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/chunks/{1307-30dff22c9e1f3073.js → 1307-77fad80cf54477c6.js} +1 -1
- package/apps/pwa/out/_next/static/chunks/1612-f60c0c93ec773f81.js +1 -0
- package/apps/pwa/out/_next/static/chunks/2116-6429c188eb846ab8.js +1 -0
- package/apps/pwa/out/_next/static/chunks/224-e7be8f762fe74986.js +1 -0
- package/apps/pwa/out/_next/static/chunks/2489-ff55a35b202c0f94.js +1 -0
- package/apps/pwa/out/_next/static/chunks/2549-89c518a4c8ed4d00.js +1 -0
- package/apps/pwa/out/_next/static/chunks/3857-995ea9f5ef33d71e.js +1 -0
- package/apps/pwa/out/_next/static/chunks/4144-fad095b48a1862ee.js +1 -0
- package/apps/pwa/out/_next/static/chunks/5755-ea7ed88eb956f47b.js +1 -0
- package/apps/pwa/out/_next/static/chunks/5977-94ed6f78e9814b2b.js +1 -0
- package/apps/pwa/out/_next/static/chunks/7748-6e51bfe927019f5c.js +25 -0
- package/apps/pwa/out/_next/static/chunks/8401-35e94e9091f5eb8d.js +1 -0
- package/apps/pwa/out/_next/static/chunks/9247-c1753a059e7bac08.js +1 -0
- package/apps/pwa/out/_next/static/chunks/a9f2b54d-33c0689b70ed8cf3.js +1 -0
- package/apps/pwa/out/_next/static/chunks/app/approvals/{page-d92f7ee3994e84c7.js → page-c855c24de7db74fe.js} +1 -1
- package/apps/pwa/out/_next/static/chunks/app/autopilot/{page-4733c967b56a4277.js → page-85b316bb4235980b.js} +1 -1
- package/apps/pwa/out/_next/static/chunks/app/board/{page-d22fd849cc22f104.js → page-9b2b26a33cb2cd42.js} +1 -1
- package/apps/pwa/out/_next/static/chunks/app/botlab/{page-bb742f995c6769e7.js → page-c9955fde67b1bcb5.js} +1 -1
- package/apps/pwa/out/_next/static/chunks/app/bots/{page-02b073a2ac793b83.js → page-7a852956c74015a3.js} +1 -1
- package/apps/pwa/out/_next/static/chunks/app/ceo/page-c5a5c621be0e04ae.js +1 -0
- package/apps/pwa/out/_next/static/chunks/app/chat/{page-8a9b3594bc23289b.js → page-4ba4abe096b6c2a8.js} +1 -1
- package/apps/pwa/out/_next/static/chunks/app/consult/page-575d4a8b4f7becb2.js +1 -0
- package/apps/pwa/out/_next/static/chunks/app/control/{page-308111abadf35670.js → page-f5d56ff5f45ad164.js} +1 -1
- package/apps/pwa/out/_next/static/chunks/app/decisions/page-2260e9eef0357421.js +1 -0
- package/apps/pwa/out/_next/static/chunks/app/design-check/{page-5d97b2901e0d1ea6.js → page-7c058069c5e7fa63.js} +1 -1
- package/apps/pwa/out/_next/static/chunks/app/editor/page-dc5da0b8a2edb8a4.js +1 -0
- package/apps/pwa/out/_next/static/chunks/app/exec/{page-8c3d8e63ae2e1c98.js → page-466bf0ee16ad1432.js} +1 -1
- package/apps/pwa/out/_next/static/chunks/app/field/{page-9b72a07d424701c6.js → page-a23bc71713bcc08f.js} +1 -1
- package/apps/pwa/out/_next/static/chunks/app/inside/page-ed4a6f799f005d09.js +1 -0
- package/apps/pwa/out/_next/static/chunks/app/intake/{page-a572f58cd3ca5864.js → page-9cd565005b93aca6.js} +1 -1
- package/apps/pwa/out/_next/static/chunks/app/layout-55f0f40c6db95f15.js +1 -0
- package/apps/pwa/out/_next/static/chunks/app/live/{page-be5ea965a07fbc41.js → page-474cb5888ea0e8f3.js} +1 -1
- package/apps/pwa/out/_next/static/chunks/app/loops/page-35bfec2e631d3eae.js +1 -0
- package/apps/pwa/out/_next/static/chunks/app/market/{page-fa244bd146a00ae8.js → page-9ca21f9ad3208a61.js} +1 -1
- package/apps/pwa/out/_next/static/chunks/app/missions/[id]/{page-44d56d6391965a6a.js → page-f9ccb1b1adbea14d.js} +1 -1
- package/apps/pwa/out/_next/static/chunks/app/morning/{page-83a700d4c754d802.js → page-ec102c9b8b691e37.js} +1 -1
- package/apps/pwa/out/_next/static/chunks/app/{not-found-7b3170f374f77b9d.js → not-found-a9c2cfa8dda922a5.js} +1 -1
- package/apps/pwa/out/_next/static/chunks/app/observatory/page-6da35144878feb6d.js +1 -0
- package/apps/pwa/out/_next/static/chunks/app/ops/checklist/page-f6055495e9ed7ea8.js +1 -0
- package/apps/pwa/out/_next/static/chunks/app/ops/release/page-25204694fa9984a5.js +1 -0
- package/apps/pwa/out/_next/static/chunks/app/ops/seats/page-a60e035f151d84d3.js +1 -0
- package/apps/pwa/out/_next/static/chunks/app/outputs/page-189c587f36874538.js +1 -0
- package/apps/pwa/out/_next/static/chunks/app/page-c56634bde705a65d.js +1 -0
- package/apps/pwa/out/_next/static/chunks/app/reflection/{page-1467047104141297.js → page-db03ae3589a81c9e.js} +1 -1
- package/apps/pwa/out/_next/static/chunks/app/scheduler/page-4a6463b97f0ad94f.js +1 -0
- package/apps/pwa/out/_next/static/chunks/app/sessions/{page-102310930791197a.js → page-75bffecc9aa1004e.js} +1 -1
- package/apps/pwa/out/_next/static/chunks/app/settings/devices/page-a8d2fe0c669e0de4.js +1 -0
- package/apps/pwa/out/_next/static/chunks/app/settings/{page-6ed0b73bae8351d8.js → page-31d5b875760bb62d.js} +1 -1
- package/apps/pwa/out/_next/static/chunks/app/setup/done/page-c26fa10aac6c21c4.js +1 -0
- package/apps/pwa/out/_next/static/chunks/app/setup/{page-43336055451f6e37.js → page-68793c6e10331d66.js} +1 -1
- package/apps/pwa/out/_next/static/chunks/app/share/{page-3cc47dca0922ab9a.js → page-46d5201d2207a511.js} +1 -1
- package/apps/pwa/out/_next/static/chunks/app/showroom/{page-a77ee355a2304ff0.js → page-d81c07a7b4f618ae.js} +1 -1
- package/apps/pwa/out/_next/static/chunks/app/tasks/{page-b17cd46cf0e9b8cf.js → page-be1c4e8697f22360.js} +1 -1
- package/apps/pwa/out/_next/static/chunks/app/term/page-cf0a4b4abead71ea.js +1 -0
- package/apps/pwa/out/_next/static/chunks/app/today/page-a4717e2c4bf7a28f.js +1 -0
- package/apps/pwa/out/_next/static/chunks/app/trace/{page-7bf54c9bb9274af8.js → page-0fd895fab9b62c1b.js} +1 -1
- package/apps/pwa/out/_next/static/chunks/app/vault/page-8b6c1454a8e8f306.js +1 -0
- package/apps/pwa/out/_next/static/chunks/app/workflows/chat-ui/page-c6e4364d9de8f717.js +1 -0
- package/apps/pwa/out/_next/static/chunks/app/workflows/page-0acc8e198f7b0dfb.js +1 -0
- package/apps/pwa/out/_next/static/chunks/app/workspace/{page-134da468538baf48.js → page-34882c84f84021c5.js} +1 -1
- package/apps/pwa/out/_next/static/chunks/app/worktrees/page-0506a1e0e4bdb2f5.js +1 -0
- package/apps/pwa/out/_next/static/chunks/{webpack-c2782b330447ffb6.js → webpack-c260571513bf43c2.js} +1 -1
- package/apps/pwa/out/_next/static/css/{e99e3cff94ced78a.css → 599369d853c61df7.css} +1 -1
- package/apps/pwa/out/_next/static/css/c23d959d3ee15e57.css +1 -0
- package/apps/pwa/out/_next/static/css/d3427996da11e480.css +1 -0
- package/apps/pwa/out/approvals/index.html +1 -1
- package/apps/pwa/out/approvals/index.txt +14 -14
- package/apps/pwa/out/autopilot/index.html +1 -1
- package/apps/pwa/out/autopilot/index.txt +14 -14
- package/apps/pwa/out/board/index.html +1 -1
- package/apps/pwa/out/board/index.txt +14 -14
- package/apps/pwa/out/botlab/index.html +1 -1
- package/apps/pwa/out/botlab/index.txt +14 -14
- package/apps/pwa/out/bots/index.html +1 -1
- package/apps/pwa/out/bots/index.txt +14 -14
- package/apps/pwa/out/ceo/index.html +1 -1
- package/apps/pwa/out/ceo/index.txt +14 -14
- package/apps/pwa/out/chat/index.html +1 -1
- package/apps/pwa/out/chat/index.txt +14 -14
- package/apps/pwa/out/consult/index.html +1 -1
- package/apps/pwa/out/consult/index.txt +14 -14
- package/apps/pwa/out/control/index.html +1 -1
- package/apps/pwa/out/control/index.txt +14 -14
- package/apps/pwa/out/decisions/index.html +1 -1
- package/apps/pwa/out/decisions/index.txt +14 -14
- package/apps/pwa/out/design-check/index.html +1 -1
- package/apps/pwa/out/design-check/index.txt +14 -14
- package/apps/pwa/out/editor/index.html +1 -1
- package/apps/pwa/out/editor/index.txt +16 -15
- package/apps/pwa/out/exec/index.html +1 -1
- package/apps/pwa/out/exec/index.txt +14 -14
- package/apps/pwa/out/field/index.html +1 -1
- package/apps/pwa/out/field/index.txt +14 -14
- package/apps/pwa/out/healthz +1 -1
- package/apps/pwa/out/index.html +1 -1
- package/apps/pwa/out/index.txt +14 -14
- package/apps/pwa/out/inside/index.html +1 -1
- package/apps/pwa/out/inside/index.txt +16 -15
- package/apps/pwa/out/intake/index.html +1 -1
- package/apps/pwa/out/intake/index.txt +14 -14
- package/apps/pwa/out/live/index.html +1 -1
- package/apps/pwa/out/live/index.txt +14 -14
- package/apps/pwa/out/loops/index.html +1 -1
- package/apps/pwa/out/loops/index.txt +24 -23
- package/apps/pwa/out/market/index.html +1 -1
- package/apps/pwa/out/market/index.txt +14 -14
- package/apps/pwa/out/missions/placeholder/index.html +1 -1
- package/apps/pwa/out/missions/placeholder/index.txt +14 -14
- package/apps/pwa/out/morning/index.html +1 -1
- package/apps/pwa/out/morning/index.txt +14 -14
- package/apps/pwa/out/observatory/index.html +1 -1
- package/apps/pwa/out/observatory/index.txt +14 -14
- package/apps/pwa/out/ops/checklist/index.html +1 -1
- package/apps/pwa/out/ops/checklist/index.txt +14 -14
- package/apps/pwa/out/ops/release/index.html +1 -1
- package/apps/pwa/out/ops/release/index.txt +14 -14
- package/apps/pwa/out/ops/seats/index.html +1 -1
- package/apps/pwa/out/ops/seats/index.txt +14 -14
- package/apps/pwa/out/outputs/index.html +1 -1
- package/apps/pwa/out/outputs/index.txt +14 -14
- package/apps/pwa/out/reflection/index.html +1 -1
- package/apps/pwa/out/reflection/index.txt +15 -15
- package/apps/pwa/out/scheduler/index.html +1 -1
- package/apps/pwa/out/scheduler/index.txt +14 -14
- package/apps/pwa/out/sessions/index.html +1 -1
- package/apps/pwa/out/sessions/index.txt +14 -14
- package/apps/pwa/out/settings/devices/index.html +1 -1
- package/apps/pwa/out/settings/devices/index.txt +14 -14
- package/apps/pwa/out/settings/index.html +1 -1
- package/apps/pwa/out/settings/index.txt +14 -14
- package/apps/pwa/out/setup/done/index.html +1 -1
- package/apps/pwa/out/setup/done/index.txt +14 -14
- package/apps/pwa/out/setup/index.html +1 -1
- package/apps/pwa/out/setup/index.txt +14 -14
- package/apps/pwa/out/share/index.html +1 -1
- package/apps/pwa/out/share/index.txt +14 -14
- package/apps/pwa/out/showroom/index.html +1 -1
- package/apps/pwa/out/showroom/index.txt +14 -14
- package/apps/pwa/out/tasks/index.html +1 -1
- package/apps/pwa/out/tasks/index.txt +14 -14
- package/apps/pwa/out/term/index.html +1 -1
- package/apps/pwa/out/term/index.txt +14 -14
- package/apps/pwa/out/today/index.html +1 -1
- package/apps/pwa/out/today/index.txt +14 -14
- package/apps/pwa/out/trace/index.html +1 -1
- package/apps/pwa/out/trace/index.txt +14 -14
- package/apps/pwa/out/vault/index.html +1 -1
- package/apps/pwa/out/vault/index.txt +14 -14
- package/apps/pwa/out/workflows/chat-ui/index.html +1 -1
- package/apps/pwa/out/workflows/chat-ui/index.txt +14 -14
- package/apps/pwa/out/workflows/index.html +1 -1
- package/apps/pwa/out/workflows/index.txt +14 -14
- package/apps/pwa/out/workspace/index.html +1 -1
- package/apps/pwa/out/workspace/index.txt +14 -14
- package/apps/pwa/out/worktrees/index.html +1 -1
- package/apps/pwa/out/worktrees/index.txt +14 -14
- package/graphs/demo/editor-recipes.yaml +22 -0
- package/graphs/ops/guardian.yaml +26 -0
- package/graphs/ops/recipes.yaml +3 -0
- package/graphs/retro/daily.yaml +25 -0
- package/graphs/retro/recipes.yaml +24 -0
- package/package.json +1 -1
- package/scripts/ask-marker-check.ts +3 -1
- package/scripts/coord-channel-watch.sh +2 -2
- package/scripts/discord-seat-probe.ts +3 -1
- package/scripts/land-global-checks.ts +89 -0
- package/scripts/lib/pch-regress-map.ts +24 -0
- package/scripts/morning-report.ts +18 -4
- package/scripts/pch-regress.ts +88 -0
- package/scripts/release-loop/gate-diff.ts +18 -0
- package/scripts/release-loop/gate-node.ts +628 -65
- package/scripts/release-loop/gate-partial.ts +106 -0
- package/scripts/release-loop/gate-timing.ts +229 -0
- package/scripts/release-loop/preflight.ts +6 -4
- package/scripts/release-loop/publish-window.ts +141 -0
- package/scripts/release-loop/release-docs.ts +1 -4
- package/scripts/release-loop/release-universe.ts +38 -0
- package/scripts/release-loop/resume-release.ts +67 -5
- package/scripts/release-loop/shard-plan.ts +65 -0
- package/scripts/release-loop/unattended-release.ts +12 -2
- package/scripts/release-story/draft.ts +5 -1
- package/scripts/retro/shadow-compare.ts +71 -0
- package/scripts/rhythm/daily.ts +6 -1
- package/scripts/video/scene-table.ts +159 -0
- package/src/acp/core-turn-bridge.ts +39 -2
- package/src/agent-mission/driver.ts +34 -6
- package/src/autopilot/build/llm-conflict-merge.ts +132 -7
- package/src/autopilot/build/merge-intent.ts +135 -7
- package/src/away/presence.ts +40 -0
- package/src/away/release-watch.ts +272 -0
- package/src/chat/index.ts +2 -1
- package/src/chat/short-question.ts +3 -40
- package/src/cli/away-cli.ts +68 -0
- package/src/cli/config-drift.ts +513 -0
- package/src/cli/guardian-cli.ts +49 -0
- package/src/cli/intake-cli.ts +13 -7
- package/src/cli/log-event-names.ts +5 -0
- package/src/cli/pod-cli.ts +5 -1
- package/src/cli/pr-cli.ts +20 -0
- package/src/cli/pty-drive-cli.ts +14 -3
- package/src/cli/release-cli.ts +52 -12
- package/src/cli/retro-cli.ts +78 -0
- package/src/cli/setup-cli.ts +31 -1
- package/src/cli/tasks-cli.ts +193 -14
- package/src/context-bus/context-now-public.ts +1 -1
- package/src/context-bus/context-now-surfaces.ts +16 -6
- package/src/context-bus/context-now.ts +97 -3
- package/src/core-turn/short-question.ts +100 -0
- package/src/dashboard/dashboard-status-lines.ts +24 -4
- package/src/dashboard/index.ts +50 -5
- package/src/dashboard/input/slash-executor.ts +6 -2
- package/src/dashboard/slash-runtime/dashboard-handlers.ts +68 -40
- package/src/dashboard/slash-runtime/decide-slash.ts +60 -0
- package/src/dashboard/slash-runtime/help-from-registry.ts +62 -23
- package/src/dashboard/slash-runtime/help-groups.ts +44 -0
- package/src/dashboard/slash-runtime/model-choices.ts +125 -0
- package/src/domains/guardian-tick.ts +138 -0
- package/src/domains/outbound-alert.ts +44 -13
- package/src/domains/outbound-log-probe.ts +6 -1
- package/src/domains/schedule-registry.ts +23 -0
- package/src/domains/telegram-kind-route.ts +39 -0
- package/src/domains/watch-default-scheduler.ts +95 -0
- package/src/esc-abort-gate.ts +44 -0
- package/src/graph-runner/graph-run-api.ts +205 -0
- package/src/graph-runner/runner.ts +36 -6
- package/src/harness/harness-cli-command.ts +420 -51
- package/src/harness/harness-queue.ts +315 -25
- package/src/harness/harness-salvage-cli.ts +140 -0
- package/src/harness/harness-worktree-add.ts +68 -0
- package/src/harness/ledger-write-guard.ts +6 -16
- package/src/hq/fence-outcomes.ts +63 -0
- package/src/hq/fence-wrapper.ts +33 -0
- package/src/hq/hq.ts +17 -2
- package/src/index.ts +118 -6
- package/src/instance/test-write-guard-spy-first.fixture.ts +13 -0
- package/src/instance/test-write-guard.ts +200 -0
- package/src/intake-plane/digest.ts +39 -15
- package/src/intake-plane/harness-target.ts +4 -3
- package/src/intake-plane/intake-sources.ts +1 -0
- package/src/intake-plane/items.ts +1 -0
- package/src/loops/orchestrator/degradation.ts +57 -0
- package/src/loops/orchestrator/finish-rate.ts +33 -3
- package/src/loops/orchestrator/tick.ts +166 -45
- package/src/maturity/feature-maturity.ts +6 -4
- package/src/maturity/tui-slash-maturity.ts +1 -0
- package/src/mss/logging/log-store.ts +3 -0
- package/src/nexus/api/graph-kinds.ts +10 -4
- package/src/nexus/api/graphs-api.ts +178 -6
- package/src/nexus/api/http-server.ts +54 -8
- package/src/nexus/api/loop-edges.ts +292 -17
- package/src/nexus/api/ops-api.ts +112 -29
- package/src/nexus/api/ops-board-route.ts +48 -0
- package/src/nexus/index.ts +7 -0
- package/src/onboarding/entry-hints.ts +5 -0
- package/src/onboarding.ts +24 -6
- package/src/release-loop/checklist.ts +2 -0
- package/src/release-loop/feature-store.ts +68 -18
- package/src/release-loop/gate-shards.ts +158 -0
- package/src/release-loop/light-rc.ts +173 -0
- package/src/release-loop/placement.ts +51 -17
- package/src/release-loop/release-schedule.ts +6 -2
- package/src/release-loop/rubric.ts +57 -1
- package/src/retro/daily.ts +372 -0
- package/src/seat-loop/op-decide.ts +173 -0
- package/src/seat-loop/seat-loop.ts +60 -3
- package/src/seat-loop/seat-report.ts +58 -3
- package/src/self-dev/ask-launch-flow.ts +5 -4
- package/src/self-dev/ask-launch-io.ts +49 -1
- package/src/self-dev/ask-path-candidates.ts +40 -2
- package/src/self-dev/dev-cli.ts +36 -0
- package/src/self-dev/draft-sweep.ts +371 -16
- package/src/self-dev/draft-triage-rules.ts +19 -4
- package/src/self-dev/orchestrate.ts +1 -0
- package/src/self-dev/pr-preview.ts +247 -0
- package/src/self-dev/shard-run.ts +23 -7
- package/src/self-implement/blocked-draft-policy.ts +101 -0
- package/src/self-implement/execution-clarification.ts +11 -0
- package/src/self-implement/gate-cli.ts +29 -8
- package/src/self-implement/gate-env-retry.ts +83 -0
- package/src/self-implement/goal-author-clarification.ts +88 -13
- package/src/self-implement/goal-clarification-escalation.ts +2 -0
- package/src/self-implement/orchestrator.ts +220 -6
- package/src/self-implement/run-stop.ts +123 -0
- package/src/self-implement/run-ttl.ts +258 -0
- package/src/self-implement/salvage-branches.ts +254 -0
- package/src/self-implement/salvage-retention.ts +123 -0
- package/src/self-implement/seams.ts +4 -0
- package/src/self-implement/self-implement-cli.ts +2 -0
- package/src/self-implement/sibling-resync.ts +223 -0
- package/src/self-implement/stop-autoheal.ts +204 -0
- package/src/task-agent/actions.ts +63 -2
- package/src/task-agent/board.ts +132 -0
- package/src/task-agent/card-evidence.ts +292 -0
- package/src/task-agent/completion-evidence.ts +126 -0
- package/src/task-agent/judge.ts +25 -0
- package/src/task-agent/live-moves.ts +276 -0
- package/src/task-agent/mission.ts +33 -7
- package/src/task-agent/shadow.ts +192 -15
- package/src/task-agent/task-hand.ts +124 -17
- package/src/task-orchestrator/surfaces/pod-command-job.ts +82 -8
- package/src/task-orchestrator/surfaces/pod-failure-reason.ts +4 -0
- package/src/task-orchestrator/surfaces/pod-install-slots.ts +89 -0
- package/src/task-orchestrator/surfaces/pod-lease.ts +233 -21
- package/src/task-orchestrator/surfaces/pod-pool.ts +155 -34
- package/src/task-orchestrator/surfaces/self-implement-pod.ts +21 -5
- package/src/telegram-away-command.ts +38 -0
- package/src/telegram-commands.ts +52 -0
- package/src/telegram-report-log-probe.ts +21 -0
- package/src/telegram-report.ts +27 -3
- package/src/testing/real-cli-spawn.ts +106 -0
- package/src/tui-client/dashboard-session.ts +1 -0
- package/src/user-config.ts +190 -5
- package/src/version/packed-revision.json +1 -1
- package/apps/pwa/out/_next/static/chunks/224-798346143007ff65.js +0 -1
- package/apps/pwa/out/_next/static/chunks/3857-4f936cdb30322aa6.js +0 -1
- package/apps/pwa/out/_next/static/chunks/4144-a0041c8dc3be57ac.js +0 -1
- package/apps/pwa/out/_next/static/chunks/4554-5761612531d0146b.js +0 -1
- package/apps/pwa/out/_next/static/chunks/5977-a11f37254196b659.js +0 -1
- package/apps/pwa/out/_next/static/chunks/5994-ae92c0de046ab9ba.js +0 -1
- package/apps/pwa/out/_next/static/chunks/8401-8615a660c84cdb03.js +0 -1
- package/apps/pwa/out/_next/static/chunks/8868-10a3a4440fb0ccd8.js +0 -25
- package/apps/pwa/out/_next/static/chunks/9247-269e4464cc4b491c.js +0 -1
- package/apps/pwa/out/_next/static/chunks/a9f2b54d-7865aba0f4d2ee49.js +0 -1
- package/apps/pwa/out/_next/static/chunks/app/ceo/page-60c3da708f9a0ccc.js +0 -1
- package/apps/pwa/out/_next/static/chunks/app/consult/page-a0eb02638b1e6f31.js +0 -1
- package/apps/pwa/out/_next/static/chunks/app/decisions/page-6eaf7bac37830c21.js +0 -1
- package/apps/pwa/out/_next/static/chunks/app/editor/page-c39554c321576982.js +0 -1
- package/apps/pwa/out/_next/static/chunks/app/inside/page-bd5d586429167fea.js +0 -1
- package/apps/pwa/out/_next/static/chunks/app/layout-59b7834d497c2255.js +0 -1
- package/apps/pwa/out/_next/static/chunks/app/loops/page-c130b63862437814.js +0 -1
- package/apps/pwa/out/_next/static/chunks/app/observatory/page-5f23d0c66a3b4793.js +0 -1
- package/apps/pwa/out/_next/static/chunks/app/ops/checklist/page-a3c58f5c72a5f3f9.js +0 -1
- package/apps/pwa/out/_next/static/chunks/app/ops/release/page-a2c4625596f8d69c.js +0 -1
- package/apps/pwa/out/_next/static/chunks/app/ops/seats/page-0e9099531d239f11.js +0 -1
- package/apps/pwa/out/_next/static/chunks/app/outputs/page-e8e1ecaea7cd71d2.js +0 -1
- package/apps/pwa/out/_next/static/chunks/app/page-a1b7ffed710a93e0.js +0 -1
- package/apps/pwa/out/_next/static/chunks/app/scheduler/page-2da6f9b8a38c6978.js +0 -1
- package/apps/pwa/out/_next/static/chunks/app/settings/devices/page-f331e38fefc00393.js +0 -1
- package/apps/pwa/out/_next/static/chunks/app/setup/done/page-44d5f767491692bf.js +0 -1
- package/apps/pwa/out/_next/static/chunks/app/term/page-61553851aa606146.js +0 -1
- package/apps/pwa/out/_next/static/chunks/app/today/page-a1f585e154e61c59.js +0 -1
- package/apps/pwa/out/_next/static/chunks/app/vault/page-5150ef17b5383a57.js +0 -1
- package/apps/pwa/out/_next/static/chunks/app/workflows/chat-ui/page-b9d8ce70792c1672.js +0 -1
- package/apps/pwa/out/_next/static/chunks/app/workflows/page-a5a3de231f2cc7d5.js +0 -1
- package/apps/pwa/out/_next/static/chunks/app/worktrees/page-31ac4afa2dcd915c.js +0 -1
- package/apps/pwa/out/_next/static/css/7fa358fec7da7c47.css +0 -1
- /package/apps/pwa/out/_next/static/{P6YTVgzuZz5oTZhY4Din_ → Bam1YziK2iH9bN4K0utGk}/_buildManifest.js +0 -0
- /package/apps/pwa/out/_next/static/{P6YTVgzuZz5oTZhY4Din_ → Bam1YziK2iH9bN4K0utGk}/_ssgManifest.js +0 -0
package/src/cli/pod-cli.ts
CHANGED
|
@@ -71,7 +71,7 @@ export function registerPodCommands(program: Command, deps: PodCliDeps = {}): vo
|
|
|
71
71
|
const current = spec ? null : kubectl(['config', 'current-context']);
|
|
72
72
|
const context = spec ?? (current?.status === 0 ? current.stdout.trim() : '');
|
|
73
73
|
const members = context ? parsePodPool(context) : [];
|
|
74
|
-
const measure: PoolLeaseMeasure = members.length ? measurePoolLease(members, { kubectl, dns: (context) => (deps.dns ?? probePoolDns)(context, kubectl) }) : { members: [] };
|
|
74
|
+
const measure: PoolLeaseMeasure = members.length ? measurePoolLease(members, { kubectl, dns: (context) => (deps.dns ?? probePoolDns)(context, kubectl), measureUsage: true }) : { members: [] };
|
|
75
75
|
let accounts: number | null = null;
|
|
76
76
|
let accountReason: string | null = null;
|
|
77
77
|
try { accounts = (deps.accounts ?? (() => listCodexAccountsInStore().length))(); }
|
|
@@ -96,6 +96,10 @@ export function registerPodCommands(program: Command, deps: PodCliDeps = {}): vo
|
|
|
96
96
|
}
|
|
97
97
|
io.log(`실측 점유: ${measure.members.map((m) => `${m.context} ${m.running === null || m.pending === null ? '못 쟀다' : m.running + m.pending}/${m.capacity}`).join(' · ') || '?'}`);
|
|
98
98
|
io.log(`권장 지금 ${decision.recommended ?? '?'} 개 더 (limitedBy=${decision.limitedBy ?? 'unknown'})${decision.reason ? ` · ${decision.reason}` : ''}`);
|
|
99
|
+
if (decision.admission) {
|
|
100
|
+
const g = (v: number | null) => v === null ? '?' : `${(v / 1024 ** 3).toFixed(1)}Gi`;
|
|
101
|
+
io.log(`골당 입장 ${g(decision.admission.admitBytes)} (실사용 표본 ${decision.admission.samples} · p95 ${g(decision.admission.p95Bytes)}${decision.admission.fallback ? ` · 폴백: ${decision.admission.fallback}` : ''})`);
|
|
102
|
+
}
|
|
99
103
|
io.log(`예약(저작 중) ${host.reserved} · 대기 Job ${waitingJobs ?? '?'} · 실행 ${decision.running ?? '?'}`);
|
|
100
104
|
io.log(`임대 없는 실행 ${decision.unleasedRunning ?? '?'}`);
|
|
101
105
|
io.log(`capacity: ${decision.capacitySlots ?? '?'} 칸 (상한 ${members.reduce((sum, m) => sum + m.capacity, 0)} − Running ${decision.running ?? '?'} − Pending ${decision.pending ?? '?'}; 권장 수에서 건강한 멤버의 임대 없는 실행 차감)`);
|
package/src/cli/pr-cli.ts
CHANGED
|
@@ -22,6 +22,7 @@ import { exportLeakCheck, publicExportChangedFiles, type ExportLeakCheck } from
|
|
|
22
22
|
import { exportImportCheck, type ExportImportCheck } from '../../scripts/ci-public-export-import-gate.js';
|
|
23
23
|
import { checkCommands, extractElanousCommands, type Finding as DocsCliFinding } from '../../scripts/docs-cli-check.js';
|
|
24
24
|
import { runTestInterferenceGate } from '../../scripts/ci-test-interference-gate.js';
|
|
25
|
+
import { landGlobalChecks, runLandGlobalChecksGate } from '../../scripts/land-global-checks.js';
|
|
25
26
|
import { isGoalDocumentFileName } from '../self-implement/goal-document.js';
|
|
26
27
|
import { queryFederatedUnfinishedRunLedgers, type FederatedUnfinishedRunLedgerEntry, type FederatedUnfinishedRunLedgerQuery } from '../self-implement/run-ledger.js';
|
|
27
28
|
import { queryRunningRuns, type RunningRunsResult } from '../self-implement/running-runs.js';
|
|
@@ -120,6 +121,8 @@ export interface PrLandDeps {
|
|
|
120
121
|
runDocsCliCheck?: (docFiles: readonly string[]) => DocsCliFinding[];
|
|
121
122
|
/** 변경 시험 파일 간 간섭 검사 심(시험 주입용). */
|
|
122
123
|
runTestInterferenceGate?: (out: { log: (message: string) => void; error: (message: string) => void }, changedFiles: readonly string[]) => Promise<number>;
|
|
124
|
+
/** 전역 검사 게이트 심(시험 주입용) — 바뀐 파일 꼴로 끌려온 전역 시험(scripts/land-global-checks.ts)을 돌린다. */
|
|
125
|
+
runLandGlobalChecks?: (out: { log: (message: string) => void; error: (message: string) => void }, changedFiles: readonly string[]) => boolean;
|
|
123
126
|
/** 안드로이드 단위 시험 게이트 심(시험 주입용). */
|
|
124
127
|
runAndroidGate?: (out: { log: (message: string) => void; error: (message: string) => void }, changedFiles: readonly string[]) => boolean;
|
|
125
128
|
/** iOS 시험 게이트 심(시험 주입용). */
|
|
@@ -1471,6 +1474,23 @@ export async function runPrLand(opts: PrLandOpts = {}, deps: PrLandDeps = {}): P
|
|
|
1471
1474
|
out,
|
|
1472
1475
|
);
|
|
1473
1476
|
record('test-interference-gate', true, { measured: testInterference.measured });
|
|
1477
|
+
// LAND-GLOBAL-CHECKS — 바뀐 파일의 경로 꼴이 부르는 «전역 검사»를 끌어와 돌린다(표 = scripts/land-global-checks.ts).
|
|
1478
|
+
// 시험이 실패하면 막는다 · 러너가 못 돌았으면 「검사 못 함」으로 말하고 통과시킨다(gateVerdict).
|
|
1479
|
+
const landGlobal = gateVerdict(
|
|
1480
|
+
'land-global-checks',
|
|
1481
|
+
deps.runLandGlobalChecks
|
|
1482
|
+
? (o) => deps.runLandGlobalChecks!(o, changedPaths)
|
|
1483
|
+
: (o) => runLandGlobalChecksGate({ changedFiles: changedPaths, cwd, log: o.log, error: o.error }),
|
|
1484
|
+
out,
|
|
1485
|
+
);
|
|
1486
|
+
record('land-global-checks', landGlobal.ok, { measured: landGlobal.measured });
|
|
1487
|
+
if (!landGlobal.ok) {
|
|
1488
|
+
out.error('✗ land-global-checks: scripts/land-global-checks.ts blocked pr land — 바뀐 파일이 끌어온 전역 시험이 실패했다.');
|
|
1489
|
+
return 1;
|
|
1490
|
+
}
|
|
1491
|
+
if (landGlobal.measured && landGlobalChecks(changedPaths).length > 0) {
|
|
1492
|
+
out.log(`✓ land-global-checks: scripts/land-global-checks.ts PASS — 끌려온 전역 시험 ${landGlobalChecks(changedPaths).join(' · ')} 실패 0.`);
|
|
1493
|
+
}
|
|
1474
1494
|
|
|
1475
1495
|
const androidGate = gateVerdict(
|
|
1476
1496
|
'android-gate',
|
package/src/cli/pty-drive-cli.ts
CHANGED
|
@@ -51,6 +51,18 @@ export interface TuiWorkdirDecision {
|
|
|
51
51
|
readonly message?: string;
|
|
52
52
|
}
|
|
53
53
|
|
|
54
|
+
/** 「명시 격리」 판정 — `--test`(명시 플래그 층) 이거나 `--isolated-root` 를 줬을 때만 참.
|
|
55
|
+
*
|
|
56
|
+
* ⭐ 이 식은 «한 벌»이다 — `runPtyDriveInner`(거부)와 `src/index.ts` dev 의 자동 워크트리
|
|
57
|
+
* 판정(`decideAutoWorktree`)이 같이 쓴다. 둘이 갈리면 「자동으로 만들었어야 하는데 거부」나
|
|
58
|
+
* 「거부했어야 하는데 자동」이 조용히 생긴다. 3층(트리 파생)은 «명시»가 아니라서 빠진다. */
|
|
59
|
+
export function isExplicitlyIsolated(
|
|
60
|
+
resolution: { readonly kind: string; readonly layer: string },
|
|
61
|
+
isolatedRoot?: string,
|
|
62
|
+
): boolean {
|
|
63
|
+
return (resolution.kind === 'test' && resolution.layer === 'explicit-flag') || Boolean(isolatedRoot);
|
|
64
|
+
}
|
|
65
|
+
|
|
54
66
|
/** Reject the unsafe combination before a TUI child can inherit the caller's tree. */
|
|
55
67
|
export function decideTuiWorkdir(isolated: boolean, cwd: string | undefined): TuiWorkdirDecision {
|
|
56
68
|
const workdirProvided = Boolean(cwd?.trim());
|
|
@@ -62,7 +74,7 @@ export function decideTuiWorkdir(isolated: boolean, cwd: string | undefined): Tu
|
|
|
62
74
|
// ⛔⭐ 거부 문면은 **무엇을 주면 되는지**까지 말한다(교차 세션 제안 · 2026-08-02).
|
|
63
75
|
// 상대가 헤맨 이유가 *"어디에 config 를 쓰나"* 였다 — 실효 자리를 확인하는 한 줄을 함께 준다.
|
|
64
76
|
...(rejected
|
|
65
|
-
? { message: '격리 우주에서는 작업 디렉토리를 명시해야 한다 — `--cwd <worktree-path>` 를 주십시오. '
|
|
77
|
+
? { message: '격리 우주에서는 작업 디렉토리를 명시해야 한다 — `--worktree` 를 주거나 `--cwd <worktree-path>` 를 주십시오. '
|
|
66
78
|
+ '(안 주면 명령을 친 트리가 자식의 쓰기 허용 구역이 됩니다.) '
|
|
67
79
|
+ '지금 어느 우주인지는 `elanous where` 로 확인할 수 있습니다.' }
|
|
68
80
|
: {}),
|
|
@@ -499,8 +511,7 @@ async function runPtyDriveInner(opts: PtyDriveOpts): Promise<{ exitCode: number
|
|
|
499
511
|
const { effectiveInstanceRoot } = await import('../instance/resolve.js');
|
|
500
512
|
const scopeRoot = effectiveInstanceRoot();
|
|
501
513
|
const resolution = resolveCurrentInstance();
|
|
502
|
-
const explicitlyIsolated = (resolution
|
|
503
|
-
|| Boolean(opts.isolatedRoot);
|
|
514
|
+
const explicitlyIsolated = isExplicitlyIsolated(resolution, opts.isolatedRoot);
|
|
504
515
|
const workdirDecision = decideTuiWorkdir(explicitlyIsolated, opts.cwd);
|
|
505
516
|
debug.log('pty.drive', 'tui-workdir-decision', workdirDecision);
|
|
506
517
|
if (workdirDecision.rejected) throw new Error(workdirDecision.message);
|
package/src/cli/release-cli.ts
CHANGED
|
@@ -45,8 +45,10 @@ import type { PrereleaseKind } from '../../scripts/release-loop/release-version.
|
|
|
45
45
|
import { releaseReadiness } from '../../scripts/release-loop/release-readiness.js';
|
|
46
46
|
import { runReleaseIfReady } from './release-run-if-ready.js';
|
|
47
47
|
import { formatPreflight, releasePreflight } from '../../scripts/release-loop/preflight.js';
|
|
48
|
+
import { defaultReleaseGraphRunsRoot, formatPublishProposal, measurePublishWindow, proposePublishAt, publishWindowWarning } from '../../scripts/release-loop/publish-window.js';
|
|
48
49
|
import { autoStartScheduledRelease, type AutoStartDeferral } from '../release-loop/auto-start.js';
|
|
49
50
|
import { landingFreezeMessage, LandingFrozenError, readLandingFreeze } from '../release-loop/landing-freeze.js';
|
|
51
|
+
import { formatLightRc, runLightRc, type LightRcDeps } from '../release-loop/light-rc.js';
|
|
50
52
|
|
|
51
53
|
export const DEFAULT_PUBLIC_REPO = 'ElanvitalAI/elanous';
|
|
52
54
|
const SEMVER = /^\d+\.\d+\.\d+(?:-(?:rc|alpha|beta)\.\d+)?$/;
|
|
@@ -594,7 +596,7 @@ function compareReleaseVersions(a: string, b: string): number {
|
|
|
594
596
|
return 0;
|
|
595
597
|
}
|
|
596
598
|
|
|
597
|
-
export function registerReleaseCommands(program: Command, releaseRunDeps: UnattendedReleaseDeps = {}, landedDeps: LandedButYellowDeps = {}, hqDeps: HqDeps = {}): void {
|
|
599
|
+
export function registerReleaseCommands(program: Command, releaseRunDeps: UnattendedReleaseDeps = {}, landedDeps: LandedButYellowDeps = {}, hqDeps: HqDeps = {}, lightRcDeps: LightRcDeps = {}): void {
|
|
598
600
|
const release = program.command('release').description('공개 배포 한 판 — prepare(로컬) → publish(--yes) → verify (docs/manual/MANUAL-versioning-and-release-2026-09-25.md)');
|
|
599
601
|
const schedule = release.command('schedule').description('판별 컷·착지 마감 조회·갱신');
|
|
600
602
|
const scheduleLedgerRoot = () => releaseRunDeps.ledgerRoot ?? releaseLedgerRoot();
|
|
@@ -608,6 +610,8 @@ export function registerReleaseCommands(program: Command, releaseRunDeps: Unatte
|
|
|
608
610
|
}
|
|
609
611
|
return hqCliWriteAllowed(command, override, ledgerFenceDeps());
|
|
610
612
|
};
|
|
613
|
+
// PUBLISH-TIME-FROM-GATE: the measured cut→publish window comes from the same ledger as the schedule (prod by default).
|
|
614
|
+
const publishMeasure = () => measurePublishWindow({ root: defaultReleaseGraphRunsRoot(scheduleLedgerRoot()) });
|
|
611
615
|
schedule.command('list').option('--json', '결과 JSON').action((o: { json?: boolean }) => {
|
|
612
616
|
const rows = listSchedules(scheduleLedgerRoot());
|
|
613
617
|
if (o.json) console.log(JSON.stringify(rows));
|
|
@@ -617,15 +621,27 @@ export function registerReleaseCommands(program: Command, releaseRunDeps: Unatte
|
|
|
617
621
|
.action((o: { version: string; json?: boolean }) => {
|
|
618
622
|
const row = getSchedule(o.version, scheduleLedgerRoot());
|
|
619
623
|
if (!row) throw new CliUserError(`없는 판 일정: ${o.version}`, '판 일정 등록: elanous release schedule set --version <v> --cut-at <iso> --land-by <iso>');
|
|
620
|
-
|
|
624
|
+
const measure = publishMeasure();
|
|
625
|
+
const proposedPublishAt = proposePublishAt(row.cutAt, measure);
|
|
626
|
+
if (o.json) console.log(JSON.stringify({ ...row, proposedPublishAt, measuredPublishMedianSeconds: measure.medianSeconds, measuredPublishSamples: measure.samples.map(({ version, seconds }) => ({ version, seconds })) }));
|
|
627
|
+
else { console.log(formatSchedule(row)); console.log(formatPublishProposal(row.cutAt, measure)); }
|
|
621
628
|
});
|
|
622
629
|
schedule.command('set').requiredOption('--version <v>', '갱신할 판')
|
|
623
630
|
.option('--cut-at <iso>', '오프셋 포함 컷 시각').option('--land-by <iso>', '오프셋 포함 착지 마감')
|
|
624
|
-
.option('--freeze-from <iso>', '동결 시작').option('--freeze-until <iso>', '동결 종료')
|
|
625
|
-
.
|
|
626
|
-
|
|
631
|
+
.option('--freeze-from <iso>', '동결 시작').option('--freeze-until <iso>', '동결 종료')
|
|
632
|
+
.option('--publish-at <iso>', '오프셋 포함 발행 시각(실측 컷→발행 중앙값보다 짧으면 경고 · 제안은 schedule show)')
|
|
633
|
+
.option('--json', '결과 JSON').option('--hq-override')
|
|
634
|
+
.action((o: { version: string; cutAt?: string; landBy?: string; freezeFrom?: string; freezeUntil?: string; publishAt?: string; json?: boolean; hqOverride?: boolean }) => {
|
|
635
|
+
if (o.cutAt === undefined && o.landBy === undefined && o.freezeFrom === undefined && o.freezeUntil === undefined && o.publishAt === undefined) throw new CliUserError('갱신할 시각을 지정하라', '--cut-at <iso> 또는 --land-by <iso> 또는 --publish-at <iso>');
|
|
627
636
|
if (!mayWriteLedger('release schedule set', Boolean(o.hqOverride), scheduleLedgerRoot())) return;
|
|
628
|
-
const row = setSchedule(o.version, { cutAt: o.cutAt, landBy: o.landBy, freezeFrom: o.freezeFrom, freezeUntil: o.freezeUntil }, process.env.ELANOUS_TRACK || 'cli', scheduleLedgerRoot());
|
|
637
|
+
const row = setSchedule(o.version, { cutAt: o.cutAt, landBy: o.landBy, freezeFrom: o.freezeFrom, freezeUntil: o.freezeUntil, publishAt: o.publishAt }, process.env.ELANOUS_TRACK || 'cli', scheduleLedgerRoot());
|
|
638
|
+
// A stored publish time shorter than the measured median warns on stderr (one line) — --json stdout stays parseable.
|
|
639
|
+
if (row.publishAt && (o.publishAt !== undefined || o.cutAt !== undefined)) {
|
|
640
|
+
const measure = publishMeasure();
|
|
641
|
+
const warning = publishWindowWarning(row.cutAt, row.publishAt, measure);
|
|
642
|
+
debug.log('release.schedule', 'publish-window', { version: row.version, cutAt: row.cutAt, publishAt: row.publishAt, medianSeconds: measure.medianSeconds, samples: measure.samples.length, warned: warning !== null });
|
|
643
|
+
if (warning) console.error(warning);
|
|
644
|
+
}
|
|
629
645
|
if (o.json) console.log(JSON.stringify(row)); else console.log(formatSchedule(row));
|
|
630
646
|
});
|
|
631
647
|
release.command('place <id>').description('칸의 우선순위·마감·용량으로 판 배치')
|
|
@@ -793,17 +809,17 @@ export function registerReleaseCommands(program: Command, releaseRunDeps: Unatte
|
|
|
793
809
|
withContext(checklist.command('set <id>').description('칸 상태·근거·담당·처분 갱신'))
|
|
794
810
|
.option('--status <status>', 'green|yellow|red|done').option('--evidence <evidence>', '근거').option('--owner <owner>', '담당')
|
|
795
811
|
.option('--disposition <disposition>', 'move|known-issue|block').option('--kind <kind>', 'screen = 다섯 화면 짝 칸 · 근거에 짝: PWA … · 데스크톱 … · 폴드 … · 아이폰 … · 아이패드 … 한 줄')
|
|
796
|
-
.option('--priority <priority>', 'P0|P1|P2').option('--deadline-version <v>', '마감 판').option('--predecessor <id...>', '선행 칸 id')
|
|
812
|
+
.option('--priority <priority>', 'P0|P1|P2').option('--deadline-version <v>', '마감 판').option('--predecessor <id...>', '선행 칸 id').option('--no-predecessor', '선행 칸 비우기(진짜 의존이 아니면 · CHECKLIST-PRED-CLEAR)')
|
|
797
813
|
.option('--ceo-minutes <minutes>', '대표 손 분량(분)').option('--ceo-date <date>', '대표 손 날짜 YYYY-MM-DD')
|
|
798
814
|
.option('--accelerator', '가속 등급 부여').option('--no-accelerator', '가속 등급 해제(기본은 없음)')
|
|
799
815
|
.option('--ref <path...>', '근거 문서 더하기 — 저장소 상대 경로[#절] (반복 가능 · 중복 제거)')
|
|
800
|
-
.action((id: string, opts: { ref?: string[]; status?: string; evidence?: string; owner?: string; disposition?: string; kind?: string; priority?: string; deadlineVersion?: string; predecessor?: string[]; ceoMinutes?: string; ceoDate?: string; accelerator?: boolean }, cmd: Command) => {
|
|
816
|
+
.action((id: string, opts: { ref?: string[]; status?: string; evidence?: string; owner?: string; disposition?: string; kind?: string; priority?: string; deadlineVersion?: string; predecessor?: string[] | false; ceoMinutes?: string; ceoDate?: string; accelerator?: boolean }, cmd: Command) => {
|
|
801
817
|
const { version, json } = context(cmd);
|
|
802
818
|
if (opts.status !== undefined && !['green', 'yellow', 'red', 'done'].includes(opts.status)) throw new CliUserError(`잘못된 상태: ${opts.status}`, 'green|yellow|red|done');
|
|
803
819
|
if (opts.disposition !== undefined && !['move', 'known-issue', 'block'].includes(opts.disposition)) throw new CliUserError(`잘못된 처분: ${opts.disposition}`, 'move|known-issue|block');
|
|
804
820
|
if (opts.status === undefined && opts.evidence === undefined && opts.owner === undefined && opts.disposition === undefined && opts.kind === undefined && opts.priority === undefined && opts.deadlineVersion === undefined && opts.predecessor === undefined && opts.ceoMinutes === undefined && opts.ceoDate === undefined && opts.accelerator === undefined && opts.ref === undefined) throw new CliUserError('갱신할 칸을 지정하라', '--ref · --status · --evidence · --owner · --disposition · --kind · --priority · --deadline-version · --predecessor · --ceo-minutes · --ceo-date · --accelerator · --no-accelerator 중 하나');
|
|
805
821
|
if (!mayWrite(cmd)) return;
|
|
806
|
-
const data = setItem(version, id, { ...(opts.ref !== undefined ? { refs: opts.ref } : {}), ...(opts.status !== undefined ? { status: opts.status as ChecklistStatus } : {}), ...(opts.evidence !== undefined ? { evidence: opts.evidence } : {}), ...(opts.owner !== undefined ? { owner: opts.owner } : {}), ...(opts.disposition !== undefined ? { disposition: opts.disposition as ChecklistDisposition } : {}), ...(opts.kind !== undefined ? { kind: opts.kind as ChecklistKind } : {}), ...(opts.priority !== undefined ? { priority: opts.priority as PlacementPriority } : {}), ...(opts.deadlineVersion !== undefined ? { deadlineVersion: opts.deadlineVersion } : {}), ...(opts.predecessor !== undefined ? { predecessors: opts.predecessor } : {}), ...(opts.ceoMinutes !== undefined ? { ceoMinutes: ceoMinutes(opts.ceoMinutes) } : {}), ...(opts.ceoDate !== undefined ? { ceoDate: opts.ceoDate } : {}), ...(opts.accelerator !== undefined ? { accelerator: opts.accelerator ? true : null } : {}) }, process.env.ELANOUS_TRACK || 'cli');
|
|
822
|
+
const data = setItem(version, id, { ...(opts.ref !== undefined ? { refs: opts.ref } : {}), ...(opts.status !== undefined ? { status: opts.status as ChecklistStatus } : {}), ...(opts.evidence !== undefined ? { evidence: opts.evidence } : {}), ...(opts.owner !== undefined ? { owner: opts.owner } : {}), ...(opts.disposition !== undefined ? { disposition: opts.disposition as ChecklistDisposition } : {}), ...(opts.kind !== undefined ? { kind: opts.kind as ChecklistKind } : {}), ...(opts.priority !== undefined ? { priority: opts.priority as PlacementPriority } : {}), ...(opts.deadlineVersion !== undefined ? { deadlineVersion: opts.deadlineVersion } : {}), ...(opts.predecessor !== undefined ? { predecessors: opts.predecessor === false ? [] : opts.predecessor } : {}), ...(opts.ceoMinutes !== undefined ? { ceoMinutes: ceoMinutes(opts.ceoMinutes) } : {}), ...(opts.ceoDate !== undefined ? { ceoDate: opts.ceoDate } : {}), ...(opts.accelerator !== undefined ? { accelerator: opts.accelerator ? true : null } : {}) }, process.env.ELANOUS_TRACK || 'cli');
|
|
807
823
|
const item = data.items.find((entry) => entry.id === id);
|
|
808
824
|
const why = item?.kind === 'screen' && item.status === 'green' ? parityGap(item.evidence) : null;
|
|
809
825
|
if (why) {
|
|
@@ -1054,16 +1070,40 @@ export function registerReleaseCommands(program: Command, releaseRunDeps: Unatte
|
|
|
1054
1070
|
process.exitCode = 1;
|
|
1055
1071
|
}
|
|
1056
1072
|
});
|
|
1073
|
+
// LIGHT-RC (0.2.19) — read-only for the ledger · never touches the landing freeze or launches Pods.
|
|
1074
|
+
release.command('light-rc')
|
|
1075
|
+
.description('가벼운 RC 점검 — 직전 판 컷(또는 --base) 이후 변경 범위 self gate ⊕ 상시 목록(release/light-rc-always.txt)을 원격 게이트 호스트에서 · 새 회귀(introduced>0)면 exit 1')
|
|
1076
|
+
.requiredOption('--version <v>', '점검할 판(x.y.z)')
|
|
1077
|
+
.option('--base <ref>', '비교 기준(기본: git merge-base origin/main origin/release/<원장 직전 판>)')
|
|
1078
|
+
.option('--remote <host>', '게이트 호스트(기본 config gateRemote.host)')
|
|
1079
|
+
.option('--local', '원격 대신 이 기계에서 돌린다(원격 자식이 이것으로 다시 불린다)')
|
|
1080
|
+
.option('--shards <n>', '시험 분할 수', '4')
|
|
1081
|
+
.option('--json', '결과 한 줄 JSON(stdout) · 사람 줄은 stderr')
|
|
1082
|
+
.action(async (o: { version: string; base?: string; remote?: string; local?: boolean; shards: string; json?: boolean }) => {
|
|
1083
|
+
// The root strips `--local` from argv (remote-bookmark attach) before Commander sees it — same read as `self gate`.
|
|
1084
|
+
const local = !!o.local || process.argv.slice(2).includes('--local');
|
|
1085
|
+
await jsonAction(o.json, async (log) => {
|
|
1086
|
+
if (o.remote !== undefined && local) throw new Error('release light-rc: --remote and --local cannot be combined');
|
|
1087
|
+
const shards = Number(o.shards);
|
|
1088
|
+
const result = await runLightRc(o.version, { base: o.base, remote: o.remote, local, shards, ledgerRoot: releaseRunDeps.ledgerRoot, log: (l) => console.error(l) }, lightRcDeps);
|
|
1089
|
+
for (const line of formatLightRc(result)) log(line);
|
|
1090
|
+
return result;
|
|
1091
|
+
}, (r) => r.ok);
|
|
1092
|
+
});
|
|
1057
1093
|
release.command('resume')
|
|
1058
1094
|
.description('실패한 릴리스 런을 이어 달린다 — cut-branch --append 로 고친 release/<v> 새 끝을 version-release 기록에 반영(빨리감기만·상태 백업) 뒤 --from 노드부터')
|
|
1059
1095
|
.requiredOption('--run <runId>', '실패한 release-loop 런 ID')
|
|
1060
1096
|
.requiredOption('--from <node>', '다시 시작할 노드(예: gate)')
|
|
1097
|
+
.option('--partial', 'GATE-PARTIAL — --from gate 에서 앞 게이트 뒤 바뀐 시험 파일 ⊕ 앞 실패 파일만 다시 돈다(시험·문서만 바뀐 경우 · 아니면 전체 게이트로)')
|
|
1061
1098
|
.option('--json', '결과 한 줄 JSON(stdout)')
|
|
1062
|
-
.action(async (o: { run: string; from: string; json?: boolean }) => {
|
|
1099
|
+
.action(async (o: { run: string; from: string; partial?: boolean; json?: boolean }) => {
|
|
1063
1100
|
await jsonAction(o.json, async (log) => {
|
|
1064
|
-
const result = await resumeReleaseRun({ runId: o.run, from: o.from });
|
|
1101
|
+
const result = await resumeReleaseRun({ runId: o.run, from: o.from, partial: o.partial });
|
|
1102
|
+
if (result.partial.requested) log(result.partial.applied
|
|
1103
|
+
? `◐ 부분 재검: ${result.partial.files}파일 · 나머지는 앞 게이트(${result.partial.priorCommit.slice(0, 12)}) 결과를 잇는다`
|
|
1104
|
+
: `● 전체 게이트로: ${result.partial.reason}`);
|
|
1065
1105
|
log(`${result.tip.changed ? `↻ ${result.tip.branch} ${result.tip.from.slice(0, 12)} → ${result.tip.to.slice(0, 12)} (백업 ${result.tip.backup})` : `· ${result.tip.branch} 끝 그대로 ${result.tip.to.slice(0, 12)}`} · ${o.from} 부터 → ${result.state.status}`);
|
|
1066
|
-
return { tip: result.tip, status: result.state.status, runId: result.state.runId };
|
|
1106
|
+
return { tip: result.tip, partial: result.partial, status: result.state.status, runId: result.state.runId };
|
|
1067
1107
|
}, (r) => r.status === 'done' || r.status === 'awaiting-approval');
|
|
1068
1108
|
});
|
|
1069
1109
|
release.command('auto-start')
|
|
@@ -0,0 +1,78 @@
|
|
|
1
|
+
import { existsSync } from 'node:fs';
|
|
2
|
+
import type { Command } from 'commander';
|
|
3
|
+
import { LogStore, logsDbPath } from '../mss/logging/log-store.js';
|
|
4
|
+
|
|
5
|
+
type RetroFact = { store: string; at: string; category: string; event: string; kind: 'draft-birth' | 'draft-death' | 'stop-reason' | 'ta-outcome'; data: unknown };
|
|
6
|
+
|
|
7
|
+
const FACT_EVENTS = new Map<string, RetroFact['kind']>([
|
|
8
|
+
['rework-blocked-draft-pr', 'draft-birth'],
|
|
9
|
+
['lineage-supersede', 'draft-death'],
|
|
10
|
+
['resolved', 'stop-reason'],
|
|
11
|
+
['decision', 'stop-reason'],
|
|
12
|
+
['action', 'ta-outcome'],
|
|
13
|
+
['task-agent.action', 'ta-outcome'],
|
|
14
|
+
]);
|
|
15
|
+
|
|
16
|
+
export function parseRetroSince(value: string, now = Date.now()): number {
|
|
17
|
+
const match = /^([1-9]\d*)([smhd])$/.exec(value);
|
|
18
|
+
if (!match) throw new Error('--since requires a positive duration (e.g. 24h)');
|
|
19
|
+
const duration = Number(match[1]) * ({ s: 1000, m: 60000, h: 3600000, d: 86400000 }[match[2]!] ?? 0);
|
|
20
|
+
if (!Number.isSafeInteger(duration) || !Number.isSafeInteger(now - duration)) throw new Error('--since duration is out of range');
|
|
21
|
+
return now - duration;
|
|
22
|
+
}
|
|
23
|
+
|
|
24
|
+
export function collectRetroFacts(sinceMs: number, targets: readonly { name: string; dbPath: string }[] = [{ name: 'current', dbPath: logsDbPath() }]): { facts: RetroFact[]; unavailable: string[] } {
|
|
25
|
+
const facts: RetroFact[] = [];
|
|
26
|
+
const unavailable: string[] = [];
|
|
27
|
+
const untilMs = Date.now();
|
|
28
|
+
for (const target of targets) {
|
|
29
|
+
if (!existsSync(target.dbPath)) { unavailable.push(target.name); continue; }
|
|
30
|
+
try {
|
|
31
|
+
const store = LogStore.openReadOnly(target.dbPath);
|
|
32
|
+
try {
|
|
33
|
+
let beforeId: number | undefined;
|
|
34
|
+
for (;;) {
|
|
35
|
+
const rows = store.query({ sinceMs, beforeId, limit: 1000 });
|
|
36
|
+
for (const row of rows) {
|
|
37
|
+
if (Date.parse(row.ts) > untilMs) continue;
|
|
38
|
+
const kind = FACT_EVENTS.get(row.event);
|
|
39
|
+
if (!kind || (row.event === 'resolved' && row.category !== 'self-dev.supervisor') || ((row.event === 'task-agent.action' || row.event === 'action') && row.category !== 'task-agent')) continue;
|
|
40
|
+
let data: unknown;
|
|
41
|
+
try { data = row.data === null ? null : JSON.parse(row.data); } catch { data = row.data; }
|
|
42
|
+
const record = data && typeof data === 'object' && !Array.isArray(data) ? data as Record<string, unknown> : {};
|
|
43
|
+
if (row.event === 'rework-blocked-draft-pr' && (row.category !== 'self-implement' || !Number.isInteger(record.number) || record.skipped || record.error)) continue;
|
|
44
|
+
if (row.event === 'lineage-supersede' && (row.category !== 'self-implement' || !Array.isArray(record.closed) || record.closed.length === 0)) continue;
|
|
45
|
+
if (row.event === 'resolved' && typeof record.stopReason !== 'string') continue;
|
|
46
|
+
if (row.event === 'decision' && (row.category !== 'self-dev.supervisor' || record.action !== 'stop' || typeof record.stopReason !== 'string')) continue;
|
|
47
|
+
if ((row.event === 'task-agent.action' || row.event === 'action') && (row.category !== 'task-agent' || typeof record.result !== 'string' || !record.result.trim())) continue;
|
|
48
|
+
facts.push({ store: target.name, at: row.ts, category: row.category, event: row.event, kind, data });
|
|
49
|
+
}
|
|
50
|
+
if (rows.length < 1000) break;
|
|
51
|
+
beforeId = rows.at(-1)!.id;
|
|
52
|
+
}
|
|
53
|
+
} finally { store.close(); }
|
|
54
|
+
} catch { unavailable.push(target.name); }
|
|
55
|
+
}
|
|
56
|
+
facts.sort((a, b) => b.at.localeCompare(a.at));
|
|
57
|
+
return { facts, unavailable };
|
|
58
|
+
}
|
|
59
|
+
|
|
60
|
+
export function registerRetroCommands(program: Command): void {
|
|
61
|
+
program.command('retro').description('Read-only retrospective facts from existing logs')
|
|
62
|
+
.command('facts').description('Draft births/deaths, stop reasons and task-agent outcomes')
|
|
63
|
+
.option('--since <duration>', 'Lookback duration', '24h')
|
|
64
|
+
.option('--json', 'JSON output')
|
|
65
|
+
.action((opts: { since: string; json?: boolean }) => {
|
|
66
|
+
try {
|
|
67
|
+
const sinceMs = parseRetroSince(opts.since);
|
|
68
|
+
const result = { since: new Date(sinceMs).toISOString(), ...collectRetroFacts(sinceMs) };
|
|
69
|
+
console.log(opts.json ? JSON.stringify(result) : [
|
|
70
|
+
`retro facts since ${result.since} · ${result.facts.length} facts · unavailable: ${result.unavailable.join(', ') || 'none'}`,
|
|
71
|
+
...result.facts.map((fact) => `${fact.at} ${fact.kind} ${fact.category}.${fact.event} ${JSON.stringify(fact.data)}`),
|
|
72
|
+
].join('\n'));
|
|
73
|
+
} catch (error) {
|
|
74
|
+
console.error(`retro facts: ${error instanceof Error ? error.message : String(error)}`);
|
|
75
|
+
process.exitCode = 2;
|
|
76
|
+
}
|
|
77
|
+
});
|
|
78
|
+
}
|
package/src/cli/setup-cli.ts
CHANGED
|
@@ -1,13 +1,16 @@
|
|
|
1
1
|
import { existsSync, readFileSync } from 'node:fs';
|
|
2
2
|
import { homedir } from 'node:os';
|
|
3
3
|
import { join } from 'node:path';
|
|
4
|
+
import { createHash } from 'node:crypto';
|
|
5
|
+
import { addSource, listSources } from '../intake-plane/intake-sources.js';
|
|
6
|
+
import { effectiveInstanceRoot } from '../instance/resolve.js';
|
|
4
7
|
import { Command } from 'commander';
|
|
5
8
|
import { formatDoctorReport, registerDoctorCommand, runDoctor, type DoctorOptions, type DoctorReport } from './doctor-cli.js';
|
|
6
9
|
import { applyClaudePluginSetup, planClaudePluginSetup } from './claude-plugin-setup.js';
|
|
7
10
|
import { recommendedSetup } from './setup-recommend.js';
|
|
8
11
|
import { detectSkillCliAuth, type CliAuthStatus } from '../onboarding/cli-auth-status.js';
|
|
9
12
|
import { debug } from '../debug/log.js';
|
|
10
|
-
import { getUserConfig, saveUserConfig, type UserConfig } from '../user-config.js';
|
|
13
|
+
import { getUserConfig, saveUserConfig, userConfigPath, type UserConfig } from '../user-config.js';
|
|
11
14
|
|
|
12
15
|
const ELANOUS_LOGIN_COMMAND = 'elanous login openai-codex';
|
|
13
16
|
const PROVIDER_COMMAND = 'elanous config set llm.provider openai-codex';
|
|
@@ -29,6 +32,9 @@ export interface SetupCliDeps extends DoctorOptions {
|
|
|
29
32
|
homeDir?: () => string;
|
|
30
33
|
getUserConfig?: () => UserConfig;
|
|
31
34
|
saveUserConfig?: (config: UserConfig) => void;
|
|
35
|
+
watchRoot?: string;
|
|
36
|
+
/** Test seam: injected configs are treated as already provisioned unless explicitly first-run. */
|
|
37
|
+
firstRunTopics?: boolean;
|
|
32
38
|
planClaudePluginSetup?: typeof planClaudePluginSetup;
|
|
33
39
|
applyClaudePluginSetup?: typeof applyClaudePluginSetup;
|
|
34
40
|
prompt?: (message: string) => Promise<string | undefined>;
|
|
@@ -209,6 +215,7 @@ export function registerSetupCommand(program: Command, deps: SetupCliDeps = {}):
|
|
|
209
215
|
setExitCode(1);
|
|
210
216
|
return;
|
|
211
217
|
}
|
|
218
|
+
const isFirstRun = deps.firstRunTopics ?? (!deps.getUserConfig && !existsSync(userConfigPath()));
|
|
212
219
|
let steps = setupSteps(deps);
|
|
213
220
|
const provider = steps[1]!;
|
|
214
221
|
if (!provider.complete) {
|
|
@@ -224,6 +231,29 @@ export function registerSetupCommand(program: Command, deps: SetupCliDeps = {}):
|
|
|
224
231
|
out.log(formatSetupReport(doctor, steps, false));
|
|
225
232
|
showCliSkills(false);
|
|
226
233
|
for (const line of recommendedSetup((deps.getUserConfig ?? getUserConfig)())) out.log(line);
|
|
234
|
+
let configured = (deps.getUserConfig ?? getUserConfig)();
|
|
235
|
+
if (!configured.starter?.topics && configured.watch?.enabled !== false
|
|
236
|
+
&& isFirstRun
|
|
237
|
+
&& isStdinTty() && !opts.yes) {
|
|
238
|
+
const answer = (await prompt('관심 주제는 무엇인가요? (쉼표로 구분 · 건너뛰려면 Enter) '))?.trim();
|
|
239
|
+
if (answer) {
|
|
240
|
+
configured = { ...configured, starter: { topics: answer.split(',').map((topic) => topic.trim()).filter(Boolean) } };
|
|
241
|
+
(deps.saveUserConfig ?? saveUserConfig)(configured);
|
|
242
|
+
}
|
|
243
|
+
}
|
|
244
|
+
const starter = configured.starter;
|
|
245
|
+
if (Array.isArray(starter?.topics) && configured.watch?.enabled !== false) {
|
|
246
|
+
const root = deps.watchRoot ?? effectiveInstanceRoot();
|
|
247
|
+
const existing = listSources({ seat: 'user' }, root);
|
|
248
|
+
for (const rawTopic of starter.topics) {
|
|
249
|
+
if (typeof rawTopic !== 'string' || !rawTopic.trim()) continue;
|
|
250
|
+
const topic = rawTopic.trim();
|
|
251
|
+
if (existing.some((source) => source.kind === 'github-query' && source.spec === topic)) continue;
|
|
252
|
+
const id = `watch-${createHash('sha256').update(topic).digest('hex').slice(0, 12)}`;
|
|
253
|
+
if (listSources({}, root).some((source) => source.id === id)) continue;
|
|
254
|
+
existing.push(addSource({ id, seat: 'user', kind: 'github-query', spec: topic, every: '1d', why: 'starter.topics' }, root));
|
|
255
|
+
}
|
|
256
|
+
}
|
|
227
257
|
const accepted = opts.yes || (isStdinTty() && /^(?:y|yes)?$/i.test((await prompt('추천대로 켤까요? [Y/n] '))?.trim() ?? 'n'));
|
|
228
258
|
if (accepted) {
|
|
229
259
|
const runDoctorFix = deps.runDoctorFix ?? (async (args: readonly string[]) => {
|