create-egregore 0.20.1 → 0.21.0-runtime-mvp.1
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/assets/egregore-launcher.js +1059 -21
- package/bin/cli.js +11 -0
- package/lib/claude-runtime.js +192 -0
- package/lib/local.js +42 -51
- package/lib/pi-runtime.js +1 -0
- package/lib/prime-runtime.js +1 -0
- package/lib/runtime-identity.js +146 -0
- package/lib/setup.js +116 -19
- package/package.json +10 -6
- package/runtime/claude/.claude/context/commit-format.md +110 -0
- package/runtime/claude/.claude/context/git-language.md +46 -0
- package/runtime/claude/.claude/context/notification-consent.md +66 -0
- package/runtime/claude/.claude/context/pr-format.md +67 -0
- package/runtime/claude/.claude/context/telemetry.md +133 -0
- package/runtime/claude/.claude/hooks/boundary-check.sh +333 -0
- package/runtime/claude/.claude/hooks/branch-guard.sh +231 -0
- package/runtime/claude/.claude/hooks/card-context.sh +38 -0
- package/runtime/claude/.claude/hooks/emissary-detect.sh +53 -0
- package/runtime/claude/.claude/hooks/memory-refresh.sh +67 -0
- package/runtime/claude/.claude/hooks/onboarding-guard.sh +86 -0
- package/runtime/claude/.claude/hooks/retrieval-context.sh +43 -0
- package/runtime/claude/.claude/rules/voice-bedrock.md +73 -0
- package/runtime/claude/.claude/settings.json +131 -0
- package/runtime/claude/.claude/skills/activity/SKILL.md +68 -0
- package/runtime/claude/.claude/skills/announce/SKILL.md +54 -0
- package/runtime/claude/.claude/skills/archive/SKILL.md +71 -0
- package/runtime/claude/.claude/skills/branch/SKILL.md +147 -0
- package/runtime/claude/.claude/skills/checkup/SKILL.md +159 -0
- package/runtime/claude/.claude/skills/commit/SKILL.md +103 -0
- package/runtime/claude/.claude/skills/contribute/SKILL.md +343 -0
- package/runtime/claude/.claude/skills/create-skill/SKILL.md +135 -0
- package/runtime/claude/.claude/skills/dark-mode/SKILL.md +410 -0
- package/runtime/claude/.claude/skills/dashboard/SKILL.md +43 -0
- package/runtime/claude/.claude/skills/deep-reflect/REPORT.md +140 -0
- package/runtime/claude/.claude/skills/deep-reflect/RESEARCH.md +132 -0
- package/runtime/claude/.claude/skills/deep-reflect/ROLES.md +104 -0
- package/runtime/claude/.claude/skills/deep-reflect/SKILL.md +170 -0
- package/runtime/claude/.claude/skills/delete-user/SKILL.md +150 -0
- package/runtime/claude/.claude/skills/emissary/SKILL.md +220 -0
- package/runtime/claude/.claude/skills/handoff/SKILL.md +124 -0
- package/runtime/claude/.claude/skills/harvest/AUDIT.md +546 -0
- package/runtime/claude/.claude/skills/harvest/FORMAT.md +436 -0
- package/runtime/claude/.claude/skills/harvest/PROCESS.md +395 -0
- package/runtime/claude/.claude/skills/harvest/QUESTION_PALETTE.md +76 -0
- package/runtime/claude/.claude/skills/harvest/SKILL.md +100 -0
- package/runtime/claude/.claude/skills/ingest/SKILL.md +112 -0
- package/runtime/claude/.claude/skills/ingest-corpus/SKILL.md +187 -0
- package/runtime/claude/.claude/skills/ingest-notion/SKILL.md +214 -0
- package/runtime/claude/.claude/skills/ingest-user-interview/SKILL.md +65 -0
- package/runtime/claude/.claude/skills/ingest-user-interview/references/analysis-contract.md +125 -0
- package/runtime/claude/.claude/skills/invite/SKILL.md +111 -0
- package/runtime/claude/.claude/skills/issue/SKILL.md +104 -0
- package/runtime/claude/.claude/skills/me/SKILL.md +81 -0
- package/runtime/claude/.claude/skills/meeting/SKILL.md +76 -0
- package/runtime/claude/.claude/skills/meeting/references/analysis-contract.md +102 -0
- package/runtime/claude/.claude/skills/note/SKILL.md +71 -0
- package/runtime/claude/.claude/skills/notion-connect/SKILL.md +124 -0
- package/runtime/claude/.claude/skills/onboarding/SKILL.md +159 -0
- package/runtime/claude/.claude/skills/pr/SKILL.md +85 -0
- package/runtime/claude/.claude/skills/pull/SKILL.md +79 -0
- package/runtime/claude/.claude/skills/push/SKILL.md +47 -0
- package/runtime/claude/.claude/skills/quest/SKILL.md +121 -0
- package/runtime/claude/.claude/skills/reflect/SKILL.md +69 -0
- package/runtime/claude/.claude/skills/review-pr/SKILL.md +276 -0
- package/runtime/claude/.claude/skills/save/SKILL.md +92 -0
- package/runtime/claude/.claude/skills/slack-connect/SKILL.md +148 -0
- package/runtime/claude/.claude/skills/summon/SKILL.md +240 -0
- package/runtime/claude/.claude/skills/sync-repos/SKILL.md +82 -0
- package/runtime/claude/.claude/skills/teams-connect/SKILL.md +216 -0
- package/runtime/claude/.claude/skills/telegram-connect/SKILL.md +110 -0
- package/runtime/claude/.claude/skills/telemetry/SKILL.md +117 -0
- package/runtime/claude/.claude/skills/test/SKILL.md +87 -0
- package/runtime/claude/.claude/skills/the-spiral/SKILL.md +492 -0
- package/runtime/claude/.claude/skills/tui-design/SKILL.md +188 -0
- package/runtime/claude/.claude/skills/tutorial/SKILL.md +100 -0
- package/runtime/claude/.claude/skills/update/SKILL.md +265 -0
- package/runtime/claude/.claude/skills/view/SKILL.md +393 -0
- package/runtime/claude/.claude/skills/view/compose-scaffold.html +221 -0
- package/runtime/claude/.claude/skills/visual-explain/SKILL.md +132 -0
- package/runtime/claude/.claude/skills/wrap/SKILL.md +98 -0
- package/runtime/claude/CLAUDE.md +447 -0
- package/runtime/claude/bin/activity-action.sh +92 -0
- package/runtime/claude/bin/activity-data.sh +17 -0
- package/runtime/claude/bin/agent.sh +783 -0
- package/runtime/claude/bin/artifact-register.sh +164 -0
- package/runtime/claude/bin/artifact-writeback.sh +53 -0
- package/runtime/claude/bin/artifacts.sh +288 -0
- package/runtime/claude/bin/attendant.sh +707 -0
- package/runtime/claude/bin/autosave.sh +112 -0
- package/runtime/claude/bin/boundary.sh +253 -0
- package/runtime/claude/bin/build-sealed-dataroom.mjs +722 -0
- package/runtime/claude/bin/capture-reconcile.sh +69 -0
- package/runtime/claude/bin/capture-run.sh +357 -0
- package/runtime/claude/bin/codex-install-skills.sh +78 -0
- package/runtime/claude/bin/codex-render-spec.mjs +462 -0
- package/runtime/claude/bin/codex-session-start.sh +275 -0
- package/runtime/claude/bin/codex-skill-render.mjs +349 -0
- package/runtime/claude/bin/codex-sync-skills.sh +237 -0
- package/runtime/claude/bin/connect-refresh.sh +33 -0
- package/runtime/claude/bin/contribute-guard.sh +79 -0
- package/runtime/claude/bin/corpus_map.py +806 -0
- package/runtime/claude/bin/corpus_survey.py +304 -0
- package/runtime/claude/bin/dashboard-data.sh +18 -0
- package/runtime/claude/bin/github-auth.sh +121 -0
- package/runtime/claude/bin/graph-batch.sh +86 -0
- package/runtime/claude/bin/graph-op.sh +1106 -0
- package/runtime/claude/bin/graph-projection.sh +54 -0
- package/runtime/claude/bin/graph-wal.sh +242 -0
- package/runtime/claude/bin/graph.sh +267 -0
- package/runtime/claude/bin/handoff-lifecycle-job.sh +146 -0
- package/runtime/claude/bin/handoff-lifecycle.sh +280 -0
- package/runtime/claude/bin/handoff-pr-backfill.sh +86 -0
- package/runtime/claude/bin/handoff-preview.sh +169 -0
- package/runtime/claude/bin/handoff-run.sh +692 -0
- package/runtime/claude/bin/handoff-save-egregore.sh +224 -0
- package/runtime/claude/bin/index-handoff.sh +322 -0
- package/runtime/claude/bin/ingest-graph.sh +86 -0
- package/runtime/claude/bin/ingest-item.sh +10 -0
- package/runtime/claude/bin/ingest-surface.html +495 -0
- package/runtime/claude/bin/ingest.py +1011 -0
- package/runtime/claude/bin/ingest.sh +308 -0
- package/runtime/claude/bin/ingest_graph.py +856 -0
- package/runtime/claude/bin/ingest_surface.py +544 -0
- package/runtime/claude/bin/invite.sh +6 -0
- package/runtime/claude/bin/issue.sh +10 -0
- package/runtime/claude/bin/knowledge.sh +10 -0
- package/runtime/claude/bin/lib/artifact-id.sh +46 -0
- package/runtime/claude/bin/lib/config.sh +136 -0
- package/runtime/claude/bin/lib/context.sh +642 -0
- package/runtime/claude/bin/lib/dashboard-artifact.sh +242 -0
- package/runtime/claude/bin/lib/ensure-develop.sh +183 -0
- package/runtime/claude/bin/lib/git-message.sh +37 -0
- package/runtime/claude/bin/lib/git-sync.sh +494 -0
- package/runtime/claude/bin/lib/greeting.sh +548 -0
- package/runtime/claude/bin/lib/handoff-meta.sh +97 -0
- package/runtime/claude/bin/lib/hash.sh +13 -0
- package/runtime/claude/bin/lib/identity.sh +213 -0
- package/runtime/claude/bin/lib/metrics.sh +374 -0
- package/runtime/claude/bin/lib/noncode.sh +31 -0
- package/runtime/claude/bin/lib/permissions.sh +106 -0
- package/runtime/claude/bin/lib/time.sh +56 -0
- package/runtime/claude/bin/lib/worktree-links.sh +85 -0
- package/runtime/claude/bin/node-run.sh +42 -0
- package/runtime/claude/bin/notification.sh +6 -0
- package/runtime/claude/bin/notify.sh +636 -0
- package/runtime/claude/bin/observe-context.sh +14 -0
- package/runtime/claude/bin/onboarding.sh +6 -0
- package/runtime/claude/bin/person.py +634 -0
- package/runtime/claude/bin/person.sh +481 -0
- package/runtime/claude/bin/pi-render-spec.mjs +140 -0
- package/runtime/claude/bin/post-update.sh +37 -0
- package/runtime/claude/bin/prime-render-spec.mjs +147 -0
- package/runtime/claude/bin/publish-artifact.sh +324 -0
- package/runtime/claude/bin/publish-references.sh +144 -0
- package/runtime/claude/bin/quest.sh +9 -0
- package/runtime/claude/bin/question.sh +8 -0
- package/runtime/claude/bin/repo-state.sh +96 -0
- package/runtime/claude/bin/research-ingest.sh +7 -0
- package/runtime/claude/bin/restore-owned-skills.sh +67 -0
- package/runtime/claude/bin/retrieval_eval.py +385 -0
- package/runtime/claude/bin/runtime-identity.sh +70 -0
- package/runtime/claude/bin/runtime-upgrade.sh +43 -0
- package/runtime/claude/bin/scroll.sh +9 -0
- package/runtime/claude/bin/search.sh +318 -0
- package/runtime/claude/bin/session-autosave.sh +220 -0
- package/runtime/claude/bin/session-log.sh +199 -0
- package/runtime/claude/bin/session-start.sh +696 -0
- package/runtime/claude/bin/settings.sh +532 -0
- package/runtime/claude/bin/startup-check.sh +136 -0
- package/runtime/claude/bin/statusline.sh +41 -0
- package/runtime/claude/bin/telemetry.sh +666 -0
- package/runtime/claude/bin/test-changes.sh +344 -0
- package/runtime/claude/bin/thread.sh +9 -0
- package/runtime/claude/bin/todo.sh +9 -0
- package/runtime/claude/bin/view-render.sh +126 -0
- package/runtime/claude/bin/worktree-create.sh +145 -0
- package/runtime/claude/bin/worktree-remove.sh +50 -0
- package/runtime/claude/bin/worktree.sh +198 -0
- package/runtime/claude/egregore_runtime/__init__.py +228 -0
- package/runtime/claude/egregore_runtime/adapters/__init__.py +5 -0
- package/runtime/claude/egregore_runtime/adapters/invitation.py +237 -0
- package/runtime/claude/egregore_runtime/adapters/notification.py +59 -0
- package/runtime/claude/egregore_runtime/adapters/qmd.py +1701 -0
- package/runtime/claude/egregore_runtime/adapters/qmd_cli.py +210 -0
- package/runtime/claude/egregore_runtime/adapters/qmd_embed_worker.py +59 -0
- package/runtime/claude/egregore_runtime/admin_gate.py +102 -0
- package/runtime/claude/egregore_runtime/artifacts.py +523 -0
- package/runtime/claude/egregore_runtime/contracts.py +499 -0
- package/runtime/claude/egregore_runtime/entitlements.py +85 -0
- package/runtime/claude/egregore_runtime/errors.py +10 -0
- package/runtime/claude/egregore_runtime/graph.py +356 -0
- package/runtime/claude/egregore_runtime/handoff_lookup.py +196 -0
- package/runtime/claude/egregore_runtime/harness_cli.py +1221 -0
- package/runtime/claude/egregore_runtime/identity.py +734 -0
- package/runtime/claude/egregore_runtime/identity_cli.py +91 -0
- package/runtime/claude/egregore_runtime/ingest.py +575 -0
- package/runtime/claude/egregore_runtime/ingest_cli.py +254 -0
- package/runtime/claude/egregore_runtime/ingest_index_cli.py +147 -0
- package/runtime/claude/egregore_runtime/invitation_cli.py +51 -0
- package/runtime/claude/egregore_runtime/invitations.py +116 -0
- package/runtime/claude/egregore_runtime/issue_cli.py +305 -0
- package/runtime/claude/egregore_runtime/issues.py +359 -0
- package/runtime/claude/egregore_runtime/knowledge.py +376 -0
- package/runtime/claude/egregore_runtime/knowledge_cli.py +173 -0
- package/runtime/claude/egregore_runtime/lifecycle.py +888 -0
- package/runtime/claude/egregore_runtime/lifecycle_cli.py +269 -0
- package/runtime/claude/egregore_runtime/notification_cli.py +125 -0
- package/runtime/claude/egregore_runtime/notifications.py +230 -0
- package/runtime/claude/egregore_runtime/observe.py +342 -0
- package/runtime/claude/egregore_runtime/onboarding.py +290 -0
- package/runtime/claude/egregore_runtime/onboarding_cli.py +110 -0
- package/runtime/claude/egregore_runtime/policy.py +144 -0
- package/runtime/claude/egregore_runtime/profile.py +193 -0
- package/runtime/claude/egregore_runtime/quest_cli.py +216 -0
- package/runtime/claude/egregore_runtime/question_cli.py +180 -0
- package/runtime/claude/egregore_runtime/questions.py +304 -0
- package/runtime/claude/egregore_runtime/quests.py +419 -0
- package/runtime/claude/egregore_runtime/readiness.py +379 -0
- package/runtime/claude/egregore_runtime/research_ingest.py +256 -0
- package/runtime/claude/egregore_runtime/research_ingest_cli.py +44 -0
- package/runtime/claude/egregore_runtime/runtime.py +464 -0
- package/runtime/claude/egregore_runtime/scroll_cli.py +185 -0
- package/runtime/claude/egregore_runtime/scrolls.py +726 -0
- package/runtime/claude/egregore_runtime/status.py +412 -0
- package/runtime/claude/egregore_runtime/status_cli.py +174 -0
- package/runtime/claude/egregore_runtime/sync.py +218 -0
- package/runtime/claude/egregore_runtime/teamsync.py +139 -0
- package/runtime/claude/egregore_runtime/telemetry.py +640 -0
- package/runtime/claude/egregore_runtime/thread_cli.py +173 -0
- package/runtime/claude/egregore_runtime/threads.py +517 -0
- package/runtime/claude/egregore_runtime/todo_cli.py +142 -0
- package/runtime/claude/egregore_runtime/todos.py +244 -0
- package/runtime/claude/egregore_runtime/upgrade.py +770 -0
- package/runtime/claude/egregore_runtime/upgrade_worker.py +53 -0
- package/runtime/claude/egregore_runtime/writeback.py +391 -0
- package/runtime/claude/egregore_runtime/writeback_cli.py +114 -0
- package/runtime/claude/manifest.json +284 -0
- package/runtime/codex/.codex/hooks/search-hint.js +21 -52
- package/runtime/codex/.codex/hooks.json +3 -3
- package/runtime/codex/.codex/skills/activity/SKILL.md +23 -66
- package/runtime/codex/.codex/skills/announce/SKILL.md +27 -50
- package/runtime/codex/.codex/skills/archive/SKILL.md +21 -36
- package/runtime/codex/.codex/skills/checkup/SKILL.md +77 -36
- package/runtime/codex/.codex/skills/dark-mode/SKILL.md +1 -1
- package/runtime/codex/.codex/skills/dashboard/SKILL.md +17 -47
- package/runtime/codex/.codex/skills/handoff/SKILL.md +84 -133
- package/runtime/codex/.codex/skills/harvest/SKILL.md +32 -117
- package/runtime/codex/.codex/skills/ingest/SKILL.md +47 -25
- package/runtime/codex/.codex/skills/ingest-user-interview/SKILL.md +18 -36
- package/runtime/codex/.codex/skills/ingest-user-interview/references/analysis-contract.md +42 -0
- package/runtime/codex/.codex/skills/invite/SKILL.md +21 -35
- package/runtime/codex/.codex/skills/issue/SKILL.md +60 -41
- package/runtime/codex/.codex/skills/me/SKILL.md +1 -1
- package/runtime/codex/.codex/skills/meeting/SKILL.md +16 -36
- package/runtime/codex/.codex/skills/meeting/references/analysis-contract.md +48 -0
- package/runtime/codex/.codex/skills/note/SKILL.md +30 -25
- package/runtime/codex/.codex/skills/onboarding/SKILL.md +36 -41
- package/runtime/codex/.codex/skills/pull/SKILL.md +1 -1
- package/runtime/codex/.codex/skills/quest/SKILL.md +27 -66
- package/runtime/codex/.codex/skills/reflect/SKILL.md +22 -36
- package/runtime/codex/.codex/skills/save/SKILL.md +2 -2
- package/runtime/codex/.codex/skills/telemetry/SKILL.md +1 -1
- package/runtime/codex/.codex/skills/test/SKILL.md +1 -1
- package/runtime/codex/.codex/skills/tutorial/SKILL.md +40 -41
- package/runtime/codex/.codex/skills/view/SKILL.md +115 -111
- package/runtime/codex/.codex/skills/wrap/SKILL.md +45 -41
- package/runtime/codex/.codex/spec-manifest.json +11 -11
- package/runtime/codex/AGENTS.md +85 -67
- package/runtime/codex/bin/activity-action.sh +92 -0
- package/runtime/codex/bin/activity-data.sh +12 -233
- package/runtime/codex/bin/agent.sh +99 -103
- package/runtime/codex/bin/artifact-register.sh +164 -0
- package/runtime/codex/bin/artifact-writeback.sh +53 -0
- package/runtime/codex/bin/artifacts.sh +288 -0
- package/runtime/codex/bin/build-sealed-dataroom.mjs +722 -0
- package/runtime/codex/bin/capture-run.sh +18 -2
- package/runtime/codex/bin/codex-render-spec.mjs +46 -19
- package/runtime/codex/bin/codex-session-start.sh +14 -4
- package/runtime/codex/bin/codex-skill-render.mjs +9 -7
- package/runtime/codex/bin/contribute-guard.sh +79 -0
- package/runtime/codex/bin/corpus_map.py +806 -0
- package/runtime/codex/bin/corpus_survey.py +304 -0
- package/runtime/codex/bin/dashboard-data.sh +11 -171
- package/runtime/codex/bin/github-auth.sh +121 -0
- package/runtime/codex/bin/graph-batch.sh +7 -0
- package/runtime/codex/bin/graph-op.sh +4 -0
- package/runtime/codex/bin/graph-projection.sh +54 -0
- package/runtime/codex/bin/graph-wal.sh +13 -0
- package/runtime/codex/bin/graph.sh +44 -0
- package/runtime/codex/bin/handoff-lifecycle-job.sh +146 -0
- package/runtime/codex/bin/handoff-lifecycle.sh +280 -0
- package/runtime/codex/bin/handoff-preview.sh +169 -0
- package/runtime/codex/bin/handoff-run.sh +42 -26
- package/runtime/codex/bin/handoff-save-egregore.sh +1 -1
- package/runtime/codex/bin/ingest-graph.sh +6 -0
- package/runtime/codex/bin/ingest-item.sh +10 -0
- package/runtime/codex/bin/ingest.sh +59 -30
- package/runtime/codex/bin/invite.sh +6 -0
- package/runtime/codex/bin/issue.sh +10 -0
- package/runtime/codex/bin/knowledge.sh +10 -0
- package/runtime/codex/bin/lib/config.sh +20 -0
- package/runtime/codex/bin/lib/context.sh +46 -25
- package/runtime/codex/bin/lib/git-sync.sh +86 -6
- package/runtime/codex/bin/lib/greeting.sh +36 -7
- package/runtime/codex/bin/lib/handoff-meta.sh +97 -0
- package/runtime/codex/bin/lib/worktree-links.sh +6 -0
- package/runtime/codex/bin/node-run.sh +42 -0
- package/runtime/codex/bin/notification.sh +6 -0
- package/runtime/codex/bin/observe-context.sh +14 -0
- package/runtime/codex/bin/onboarding.sh +6 -0
- package/runtime/codex/bin/person.py +4 -0
- package/runtime/codex/bin/person.sh +43 -10
- package/runtime/codex/bin/pi-render-spec.mjs +140 -0
- package/runtime/codex/bin/post-update.sh +37 -0
- package/runtime/codex/bin/prime-render-spec.mjs +147 -0
- package/runtime/codex/bin/publish-artifact.sh +55 -2
- package/runtime/codex/bin/quest.sh +9 -0
- package/runtime/codex/bin/question.sh +8 -0
- package/runtime/codex/bin/research-ingest.sh +7 -0
- package/runtime/codex/bin/restore-owned-skills.sh +67 -0
- package/runtime/codex/bin/retrieval_eval.py +385 -0
- package/runtime/codex/bin/runtime-identity.sh +70 -0
- package/runtime/codex/bin/runtime-upgrade.sh +43 -0
- package/runtime/codex/bin/scroll.sh +9 -0
- package/runtime/codex/bin/search.sh +243 -165
- package/runtime/codex/bin/session-autosave.sh +6 -1
- package/runtime/codex/bin/settings.sh +235 -7
- package/runtime/codex/bin/startup-check.sh +136 -0
- package/runtime/codex/bin/telemetry.sh +522 -247
- package/runtime/codex/bin/test-changes.sh +344 -0
- package/runtime/codex/bin/thread.sh +9 -0
- package/runtime/codex/bin/todo.sh +9 -0
- package/runtime/codex/bin/view-render.sh +126 -0
- package/runtime/codex/bin/worktree-create.sh +23 -6
- package/runtime/codex/egregore_runtime/__init__.py +228 -0
- package/runtime/codex/egregore_runtime/adapters/__init__.py +5 -0
- package/runtime/codex/egregore_runtime/adapters/invitation.py +237 -0
- package/runtime/codex/egregore_runtime/adapters/notification.py +59 -0
- package/runtime/codex/egregore_runtime/adapters/qmd.py +1701 -0
- package/runtime/codex/egregore_runtime/adapters/qmd_cli.py +210 -0
- package/runtime/codex/egregore_runtime/adapters/qmd_embed_worker.py +59 -0
- package/runtime/codex/egregore_runtime/admin_gate.py +102 -0
- package/runtime/codex/egregore_runtime/artifacts.py +523 -0
- package/runtime/codex/egregore_runtime/contracts.py +499 -0
- package/runtime/codex/egregore_runtime/entitlements.py +85 -0
- package/runtime/codex/egregore_runtime/errors.py +10 -0
- package/runtime/codex/egregore_runtime/graph.py +356 -0
- package/runtime/codex/egregore_runtime/handoff_lookup.py +196 -0
- package/runtime/codex/egregore_runtime/harness_cli.py +1221 -0
- package/runtime/codex/egregore_runtime/identity.py +734 -0
- package/runtime/codex/egregore_runtime/identity_cli.py +91 -0
- package/runtime/codex/egregore_runtime/ingest.py +575 -0
- package/runtime/codex/egregore_runtime/ingest_cli.py +254 -0
- package/runtime/codex/egregore_runtime/ingest_index_cli.py +147 -0
- package/runtime/codex/egregore_runtime/invitation_cli.py +51 -0
- package/runtime/codex/egregore_runtime/invitations.py +116 -0
- package/runtime/codex/egregore_runtime/issue_cli.py +305 -0
- package/runtime/codex/egregore_runtime/issues.py +359 -0
- package/runtime/codex/egregore_runtime/knowledge.py +376 -0
- package/runtime/codex/egregore_runtime/knowledge_cli.py +173 -0
- package/runtime/codex/egregore_runtime/lifecycle.py +888 -0
- package/runtime/codex/egregore_runtime/lifecycle_cli.py +269 -0
- package/runtime/codex/egregore_runtime/notification_cli.py +125 -0
- package/runtime/codex/egregore_runtime/notifications.py +230 -0
- package/runtime/codex/egregore_runtime/observe.py +342 -0
- package/runtime/codex/egregore_runtime/onboarding.py +290 -0
- package/runtime/codex/egregore_runtime/onboarding_cli.py +110 -0
- package/runtime/codex/egregore_runtime/policy.py +144 -0
- package/runtime/codex/egregore_runtime/profile.py +193 -0
- package/runtime/codex/egregore_runtime/quest_cli.py +216 -0
- package/runtime/codex/egregore_runtime/question_cli.py +180 -0
- package/runtime/codex/egregore_runtime/questions.py +304 -0
- package/runtime/codex/egregore_runtime/quests.py +419 -0
- package/runtime/codex/egregore_runtime/readiness.py +379 -0
- package/runtime/codex/egregore_runtime/research_ingest.py +256 -0
- package/runtime/codex/egregore_runtime/research_ingest_cli.py +44 -0
- package/runtime/codex/egregore_runtime/runtime.py +464 -0
- package/runtime/codex/egregore_runtime/scroll_cli.py +185 -0
- package/runtime/codex/egregore_runtime/scrolls.py +726 -0
- package/runtime/codex/egregore_runtime/status.py +412 -0
- package/runtime/codex/egregore_runtime/status_cli.py +174 -0
- package/runtime/codex/egregore_runtime/sync.py +218 -0
- package/runtime/codex/egregore_runtime/teamsync.py +139 -0
- package/runtime/codex/egregore_runtime/telemetry.py +640 -0
- package/runtime/codex/egregore_runtime/thread_cli.py +173 -0
- package/runtime/codex/egregore_runtime/threads.py +517 -0
- package/runtime/codex/egregore_runtime/todo_cli.py +142 -0
- package/runtime/codex/egregore_runtime/todos.py +244 -0
- package/runtime/codex/egregore_runtime/upgrade.py +770 -0
- package/runtime/codex/egregore_runtime/upgrade_worker.py +53 -0
- package/runtime/codex/egregore_runtime/writeback.py +391 -0
- package/runtime/codex/egregore_runtime/writeback_cli.py +114 -0
- package/runtime/codex/manifest.json +99 -1
- package/runtime/pi/.codex/hooks/search-hint.js +21 -52
- package/runtime/pi/.codex/hooks.json +3 -3
- package/runtime/pi/.codex/skills/activity/SKILL.md +23 -66
- package/runtime/pi/.codex/skills/announce/SKILL.md +27 -50
- package/runtime/pi/.codex/skills/archive/SKILL.md +21 -36
- package/runtime/pi/.codex/skills/checkup/SKILL.md +77 -36
- package/runtime/pi/.codex/skills/dark-mode/SKILL.md +1 -1
- package/runtime/pi/.codex/skills/dashboard/SKILL.md +17 -47
- package/runtime/pi/.codex/skills/handoff/SKILL.md +84 -133
- package/runtime/pi/.codex/skills/harvest/SKILL.md +32 -117
- package/runtime/pi/.codex/skills/ingest/SKILL.md +47 -25
- package/runtime/pi/.codex/skills/ingest-user-interview/SKILL.md +18 -36
- package/runtime/pi/.codex/skills/ingest-user-interview/references/analysis-contract.md +42 -0
- package/runtime/pi/.codex/skills/invite/SKILL.md +21 -35
- package/runtime/pi/.codex/skills/issue/SKILL.md +60 -41
- package/runtime/pi/.codex/skills/me/SKILL.md +1 -1
- package/runtime/pi/.codex/skills/meeting/SKILL.md +16 -36
- package/runtime/pi/.codex/skills/meeting/references/analysis-contract.md +48 -0
- package/runtime/pi/.codex/skills/note/SKILL.md +30 -25
- package/runtime/pi/.codex/skills/onboarding/SKILL.md +36 -41
- package/runtime/pi/.codex/skills/pull/SKILL.md +1 -1
- package/runtime/pi/.codex/skills/quest/SKILL.md +27 -66
- package/runtime/pi/.codex/skills/reflect/SKILL.md +22 -36
- package/runtime/pi/.codex/skills/save/SKILL.md +2 -2
- package/runtime/pi/.codex/skills/telemetry/SKILL.md +1 -1
- package/runtime/pi/.codex/skills/test/SKILL.md +1 -1
- package/runtime/pi/.codex/skills/tutorial/SKILL.md +40 -41
- package/runtime/pi/.codex/skills/view/SKILL.md +115 -111
- package/runtime/pi/.codex/skills/wrap/SKILL.md +45 -41
- package/runtime/pi/.codex/spec-manifest.json +11 -11
- package/runtime/pi/.pi/APPEND_SYSTEM.md +80 -57
- package/runtime/pi/.pi/extensions/egregore.ts +7 -0
- package/runtime/pi/.pi/spec-manifest.json +2 -2
- package/runtime/pi/AGENTS.md +85 -67
- package/runtime/pi/bin/activity-action.sh +92 -0
- package/runtime/pi/bin/activity-data.sh +12 -233
- package/runtime/pi/bin/agent.sh +99 -103
- package/runtime/pi/bin/artifact-register.sh +164 -0
- package/runtime/pi/bin/artifact-writeback.sh +53 -0
- package/runtime/pi/bin/artifacts.sh +288 -0
- package/runtime/pi/bin/build-sealed-dataroom.mjs +722 -0
- package/runtime/pi/bin/capture-run.sh +18 -2
- package/runtime/pi/bin/codex-render-spec.mjs +46 -19
- package/runtime/pi/bin/codex-session-start.sh +14 -4
- package/runtime/pi/bin/codex-skill-render.mjs +9 -7
- package/runtime/pi/bin/contribute-guard.sh +79 -0
- package/runtime/pi/bin/corpus_map.py +806 -0
- package/runtime/pi/bin/corpus_survey.py +304 -0
- package/runtime/pi/bin/dashboard-data.sh +11 -171
- package/runtime/pi/bin/github-auth.sh +121 -0
- package/runtime/pi/bin/graph-batch.sh +7 -0
- package/runtime/pi/bin/graph-op.sh +4 -0
- package/runtime/pi/bin/graph-projection.sh +54 -0
- package/runtime/pi/bin/graph-wal.sh +13 -0
- package/runtime/pi/bin/graph.sh +44 -0
- package/runtime/pi/bin/handoff-lifecycle-job.sh +146 -0
- package/runtime/pi/bin/handoff-lifecycle.sh +280 -0
- package/runtime/pi/bin/handoff-preview.sh +169 -0
- package/runtime/pi/bin/handoff-run.sh +42 -26
- package/runtime/pi/bin/handoff-save-egregore.sh +1 -1
- package/runtime/pi/bin/ingest-graph.sh +6 -0
- package/runtime/pi/bin/ingest-item.sh +10 -0
- package/runtime/pi/bin/ingest.sh +59 -30
- package/runtime/pi/bin/invite.sh +6 -0
- package/runtime/pi/bin/issue.sh +10 -0
- package/runtime/pi/bin/knowledge.sh +10 -0
- package/runtime/pi/bin/lib/config.sh +20 -0
- package/runtime/pi/bin/lib/context.sh +46 -25
- package/runtime/pi/bin/lib/git-sync.sh +86 -6
- package/runtime/pi/bin/lib/greeting.sh +36 -7
- package/runtime/pi/bin/lib/handoff-meta.sh +97 -0
- package/runtime/pi/bin/lib/worktree-links.sh +6 -0
- package/runtime/pi/bin/node-run.sh +42 -0
- package/runtime/pi/bin/notification.sh +6 -0
- package/runtime/pi/bin/observe-context.sh +14 -0
- package/runtime/pi/bin/onboarding.sh +6 -0
- package/runtime/pi/bin/person.py +4 -0
- package/runtime/pi/bin/person.sh +43 -10
- package/runtime/pi/bin/pi-observe-context.mjs +93 -0
- package/runtime/pi/bin/pi-product-workflows.mjs +1 -1
- package/runtime/pi/bin/pi-render-spec.mjs +1 -1
- package/runtime/pi/bin/post-update.sh +37 -0
- package/runtime/pi/bin/prime-render-spec.mjs +147 -0
- package/runtime/pi/bin/publish-artifact.sh +55 -2
- package/runtime/pi/bin/quest.sh +9 -0
- package/runtime/pi/bin/question.sh +8 -0
- package/runtime/pi/bin/research-ingest.sh +7 -0
- package/runtime/pi/bin/restore-owned-skills.sh +67 -0
- package/runtime/pi/bin/retrieval_eval.py +385 -0
- package/runtime/pi/bin/runtime-identity.sh +70 -0
- package/runtime/pi/bin/runtime-upgrade.sh +43 -0
- package/runtime/pi/bin/scroll.sh +9 -0
- package/runtime/pi/bin/search.sh +243 -165
- package/runtime/pi/bin/session-autosave.sh +6 -1
- package/runtime/pi/bin/settings.sh +235 -7
- package/runtime/pi/bin/startup-check.sh +136 -0
- package/runtime/pi/bin/telemetry.sh +522 -247
- package/runtime/pi/bin/test-changes.sh +344 -0
- package/runtime/pi/bin/thread.sh +9 -0
- package/runtime/pi/bin/todo.sh +9 -0
- package/runtime/pi/bin/view-render.sh +126 -0
- package/runtime/pi/bin/worktree-create.sh +23 -6
- package/runtime/pi/egregore_runtime/__init__.py +228 -0
- package/runtime/pi/egregore_runtime/adapters/__init__.py +5 -0
- package/runtime/pi/egregore_runtime/adapters/invitation.py +237 -0
- package/runtime/pi/egregore_runtime/adapters/notification.py +59 -0
- package/runtime/pi/egregore_runtime/adapters/qmd.py +1701 -0
- package/runtime/pi/egregore_runtime/adapters/qmd_cli.py +210 -0
- package/runtime/pi/egregore_runtime/adapters/qmd_embed_worker.py +59 -0
- package/runtime/pi/egregore_runtime/admin_gate.py +102 -0
- package/runtime/pi/egregore_runtime/artifacts.py +523 -0
- package/runtime/pi/egregore_runtime/contracts.py +499 -0
- package/runtime/pi/egregore_runtime/entitlements.py +85 -0
- package/runtime/pi/egregore_runtime/errors.py +10 -0
- package/runtime/pi/egregore_runtime/graph.py +356 -0
- package/runtime/pi/egregore_runtime/handoff_lookup.py +196 -0
- package/runtime/pi/egregore_runtime/harness_cli.py +1221 -0
- package/runtime/pi/egregore_runtime/identity.py +734 -0
- package/runtime/pi/egregore_runtime/identity_cli.py +91 -0
- package/runtime/pi/egregore_runtime/ingest.py +575 -0
- package/runtime/pi/egregore_runtime/ingest_cli.py +254 -0
- package/runtime/pi/egregore_runtime/ingest_index_cli.py +147 -0
- package/runtime/pi/egregore_runtime/invitation_cli.py +51 -0
- package/runtime/pi/egregore_runtime/invitations.py +116 -0
- package/runtime/pi/egregore_runtime/issue_cli.py +305 -0
- package/runtime/pi/egregore_runtime/issues.py +359 -0
- package/runtime/pi/egregore_runtime/knowledge.py +376 -0
- package/runtime/pi/egregore_runtime/knowledge_cli.py +173 -0
- package/runtime/pi/egregore_runtime/lifecycle.py +888 -0
- package/runtime/pi/egregore_runtime/lifecycle_cli.py +269 -0
- package/runtime/pi/egregore_runtime/notification_cli.py +125 -0
- package/runtime/pi/egregore_runtime/notifications.py +230 -0
- package/runtime/pi/egregore_runtime/observe.py +342 -0
- package/runtime/pi/egregore_runtime/onboarding.py +290 -0
- package/runtime/pi/egregore_runtime/onboarding_cli.py +110 -0
- package/runtime/pi/egregore_runtime/policy.py +144 -0
- package/runtime/pi/egregore_runtime/profile.py +193 -0
- package/runtime/pi/egregore_runtime/quest_cli.py +216 -0
- package/runtime/pi/egregore_runtime/question_cli.py +180 -0
- package/runtime/pi/egregore_runtime/questions.py +304 -0
- package/runtime/pi/egregore_runtime/quests.py +419 -0
- package/runtime/pi/egregore_runtime/readiness.py +379 -0
- package/runtime/pi/egregore_runtime/research_ingest.py +256 -0
- package/runtime/pi/egregore_runtime/research_ingest_cli.py +44 -0
- package/runtime/pi/egregore_runtime/runtime.py +464 -0
- package/runtime/pi/egregore_runtime/scroll_cli.py +185 -0
- package/runtime/pi/egregore_runtime/scrolls.py +726 -0
- package/runtime/pi/egregore_runtime/status.py +412 -0
- package/runtime/pi/egregore_runtime/status_cli.py +174 -0
- package/runtime/pi/egregore_runtime/sync.py +218 -0
- package/runtime/pi/egregore_runtime/teamsync.py +139 -0
- package/runtime/pi/egregore_runtime/telemetry.py +640 -0
- package/runtime/pi/egregore_runtime/thread_cli.py +173 -0
- package/runtime/pi/egregore_runtime/threads.py +517 -0
- package/runtime/pi/egregore_runtime/todo_cli.py +142 -0
- package/runtime/pi/egregore_runtime/todos.py +244 -0
- package/runtime/pi/egregore_runtime/upgrade.py +770 -0
- package/runtime/pi/egregore_runtime/upgrade_worker.py +53 -0
- package/runtime/pi/egregore_runtime/writeback.py +391 -0
- package/runtime/pi/egregore_runtime/writeback_cli.py +114 -0
- package/runtime/pi/manifest.json +99 -1
- package/runtime/prime/.codex/hooks/search-hint.js +21 -52
- package/runtime/prime/.codex/hooks.json +3 -3
- package/runtime/prime/.codex/skills/activity/SKILL.md +23 -66
- package/runtime/prime/.codex/skills/announce/SKILL.md +27 -50
- package/runtime/prime/.codex/skills/archive/SKILL.md +21 -36
- package/runtime/prime/.codex/skills/checkup/SKILL.md +77 -36
- package/runtime/prime/.codex/skills/dark-mode/SKILL.md +1 -1
- package/runtime/prime/.codex/skills/dashboard/SKILL.md +17 -47
- package/runtime/prime/.codex/skills/handoff/SKILL.md +84 -133
- package/runtime/prime/.codex/skills/harvest/SKILL.md +32 -117
- package/runtime/prime/.codex/skills/ingest/SKILL.md +47 -25
- package/runtime/prime/.codex/skills/ingest-user-interview/SKILL.md +18 -36
- package/runtime/prime/.codex/skills/ingest-user-interview/references/analysis-contract.md +42 -0
- package/runtime/prime/.codex/skills/invite/SKILL.md +21 -35
- package/runtime/prime/.codex/skills/issue/SKILL.md +60 -41
- package/runtime/prime/.codex/skills/me/SKILL.md +1 -1
- package/runtime/prime/.codex/skills/meeting/SKILL.md +16 -36
- package/runtime/prime/.codex/skills/meeting/references/analysis-contract.md +48 -0
- package/runtime/prime/.codex/skills/note/SKILL.md +30 -25
- package/runtime/prime/.codex/skills/onboarding/SKILL.md +36 -41
- package/runtime/prime/.codex/skills/pull/SKILL.md +1 -1
- package/runtime/prime/.codex/skills/quest/SKILL.md +27 -66
- package/runtime/prime/.codex/skills/reflect/SKILL.md +22 -36
- package/runtime/prime/.codex/skills/save/SKILL.md +2 -2
- package/runtime/prime/.codex/skills/telemetry/SKILL.md +1 -1
- package/runtime/prime/.codex/skills/test/SKILL.md +1 -1
- package/runtime/prime/.codex/skills/tutorial/SKILL.md +40 -41
- package/runtime/prime/.codex/skills/view/SKILL.md +115 -111
- package/runtime/prime/.codex/skills/wrap/SKILL.md +45 -41
- package/runtime/prime/.codex/spec-manifest.json +11 -11
- package/runtime/prime/.prime/agent/APPEND_SYSTEM.md +81 -58
- package/runtime/prime/.prime/agent/extensions/egregore.ts +7 -0
- package/runtime/prime/.prime/agent/spec-manifest.json +2 -2
- package/runtime/prime/AGENTS.md +85 -67
- package/runtime/prime/bin/activity-action.sh +92 -0
- package/runtime/prime/bin/activity-data.sh +12 -233
- package/runtime/prime/bin/agent.sh +99 -103
- package/runtime/prime/bin/artifact-register.sh +164 -0
- package/runtime/prime/bin/artifact-writeback.sh +53 -0
- package/runtime/prime/bin/artifacts.sh +288 -0
- package/runtime/prime/bin/build-sealed-dataroom.mjs +722 -0
- package/runtime/prime/bin/capture-run.sh +18 -2
- package/runtime/prime/bin/codex-render-spec.mjs +46 -19
- package/runtime/prime/bin/codex-session-start.sh +14 -4
- package/runtime/prime/bin/codex-skill-render.mjs +9 -7
- package/runtime/prime/bin/contribute-guard.sh +79 -0
- package/runtime/prime/bin/corpus_map.py +806 -0
- package/runtime/prime/bin/corpus_survey.py +304 -0
- package/runtime/prime/bin/dashboard-data.sh +11 -171
- package/runtime/prime/bin/github-auth.sh +121 -0
- package/runtime/prime/bin/graph-batch.sh +7 -0
- package/runtime/prime/bin/graph-op.sh +4 -0
- package/runtime/prime/bin/graph-projection.sh +54 -0
- package/runtime/prime/bin/graph-wal.sh +13 -0
- package/runtime/prime/bin/graph.sh +44 -0
- package/runtime/prime/bin/handoff-lifecycle-job.sh +146 -0
- package/runtime/prime/bin/handoff-lifecycle.sh +280 -0
- package/runtime/prime/bin/handoff-preview.sh +169 -0
- package/runtime/prime/bin/handoff-run.sh +42 -26
- package/runtime/prime/bin/handoff-save-egregore.sh +1 -1
- package/runtime/prime/bin/ingest-graph.sh +6 -0
- package/runtime/prime/bin/ingest-item.sh +10 -0
- package/runtime/prime/bin/ingest.sh +59 -30
- package/runtime/prime/bin/invite.sh +6 -0
- package/runtime/prime/bin/issue.sh +10 -0
- package/runtime/prime/bin/knowledge.sh +10 -0
- package/runtime/prime/bin/lib/config.sh +20 -0
- package/runtime/prime/bin/lib/context.sh +46 -25
- package/runtime/prime/bin/lib/git-sync.sh +86 -6
- package/runtime/prime/bin/lib/greeting.sh +36 -7
- package/runtime/prime/bin/lib/handoff-meta.sh +97 -0
- package/runtime/prime/bin/lib/worktree-links.sh +6 -0
- package/runtime/prime/bin/node-run.sh +42 -0
- package/runtime/prime/bin/notification.sh +6 -0
- package/runtime/prime/bin/observe-context.sh +14 -0
- package/runtime/prime/bin/onboarding.sh +6 -0
- package/runtime/prime/bin/person.py +4 -0
- package/runtime/prime/bin/person.sh +43 -10
- package/runtime/prime/bin/pi-observe-context.mjs +93 -0
- package/runtime/prime/bin/pi-product-workflows.mjs +1 -1
- package/runtime/prime/bin/pi-render-spec.mjs +140 -0
- package/runtime/prime/bin/post-update.sh +37 -0
- package/runtime/prime/bin/prime-render-spec.mjs +2 -2
- package/runtime/prime/bin/publish-artifact.sh +55 -2
- package/runtime/prime/bin/quest.sh +9 -0
- package/runtime/prime/bin/question.sh +8 -0
- package/runtime/prime/bin/research-ingest.sh +7 -0
- package/runtime/prime/bin/restore-owned-skills.sh +67 -0
- package/runtime/prime/bin/retrieval_eval.py +385 -0
- package/runtime/prime/bin/runtime-identity.sh +70 -0
- package/runtime/prime/bin/runtime-upgrade.sh +43 -0
- package/runtime/prime/bin/scroll.sh +9 -0
- package/runtime/prime/bin/search.sh +243 -165
- package/runtime/prime/bin/session-autosave.sh +6 -1
- package/runtime/prime/bin/settings.sh +235 -7
- package/runtime/prime/bin/startup-check.sh +136 -0
- package/runtime/prime/bin/telemetry.sh +522 -247
- package/runtime/prime/bin/test-changes.sh +344 -0
- package/runtime/prime/bin/thread.sh +9 -0
- package/runtime/prime/bin/todo.sh +9 -0
- package/runtime/prime/bin/view-render.sh +126 -0
- package/runtime/prime/bin/worktree-create.sh +23 -6
- package/runtime/prime/egregore_runtime/__init__.py +228 -0
- package/runtime/prime/egregore_runtime/adapters/__init__.py +5 -0
- package/runtime/prime/egregore_runtime/adapters/invitation.py +237 -0
- package/runtime/prime/egregore_runtime/adapters/notification.py +59 -0
- package/runtime/prime/egregore_runtime/adapters/qmd.py +1701 -0
- package/runtime/prime/egregore_runtime/adapters/qmd_cli.py +210 -0
- package/runtime/prime/egregore_runtime/adapters/qmd_embed_worker.py +59 -0
- package/runtime/prime/egregore_runtime/admin_gate.py +102 -0
- package/runtime/prime/egregore_runtime/artifacts.py +523 -0
- package/runtime/prime/egregore_runtime/contracts.py +499 -0
- package/runtime/prime/egregore_runtime/entitlements.py +85 -0
- package/runtime/prime/egregore_runtime/errors.py +10 -0
- package/runtime/prime/egregore_runtime/graph.py +356 -0
- package/runtime/prime/egregore_runtime/handoff_lookup.py +196 -0
- package/runtime/prime/egregore_runtime/harness_cli.py +1221 -0
- package/runtime/prime/egregore_runtime/identity.py +734 -0
- package/runtime/prime/egregore_runtime/identity_cli.py +91 -0
- package/runtime/prime/egregore_runtime/ingest.py +575 -0
- package/runtime/prime/egregore_runtime/ingest_cli.py +254 -0
- package/runtime/prime/egregore_runtime/ingest_index_cli.py +147 -0
- package/runtime/prime/egregore_runtime/invitation_cli.py +51 -0
- package/runtime/prime/egregore_runtime/invitations.py +116 -0
- package/runtime/prime/egregore_runtime/issue_cli.py +305 -0
- package/runtime/prime/egregore_runtime/issues.py +359 -0
- package/runtime/prime/egregore_runtime/knowledge.py +376 -0
- package/runtime/prime/egregore_runtime/knowledge_cli.py +173 -0
- package/runtime/prime/egregore_runtime/lifecycle.py +888 -0
- package/runtime/prime/egregore_runtime/lifecycle_cli.py +269 -0
- package/runtime/prime/egregore_runtime/notification_cli.py +125 -0
- package/runtime/prime/egregore_runtime/notifications.py +230 -0
- package/runtime/prime/egregore_runtime/observe.py +342 -0
- package/runtime/prime/egregore_runtime/onboarding.py +290 -0
- package/runtime/prime/egregore_runtime/onboarding_cli.py +110 -0
- package/runtime/prime/egregore_runtime/policy.py +144 -0
- package/runtime/prime/egregore_runtime/profile.py +193 -0
- package/runtime/prime/egregore_runtime/quest_cli.py +216 -0
- package/runtime/prime/egregore_runtime/question_cli.py +180 -0
- package/runtime/prime/egregore_runtime/questions.py +304 -0
- package/runtime/prime/egregore_runtime/quests.py +419 -0
- package/runtime/prime/egregore_runtime/readiness.py +379 -0
- package/runtime/prime/egregore_runtime/research_ingest.py +256 -0
- package/runtime/prime/egregore_runtime/research_ingest_cli.py +44 -0
- package/runtime/prime/egregore_runtime/runtime.py +464 -0
- package/runtime/prime/egregore_runtime/scroll_cli.py +185 -0
- package/runtime/prime/egregore_runtime/scrolls.py +726 -0
- package/runtime/prime/egregore_runtime/status.py +412 -0
- package/runtime/prime/egregore_runtime/status_cli.py +174 -0
- package/runtime/prime/egregore_runtime/sync.py +218 -0
- package/runtime/prime/egregore_runtime/teamsync.py +139 -0
- package/runtime/prime/egregore_runtime/telemetry.py +640 -0
- package/runtime/prime/egregore_runtime/thread_cli.py +173 -0
- package/runtime/prime/egregore_runtime/threads.py +517 -0
- package/runtime/prime/egregore_runtime/todo_cli.py +142 -0
- package/runtime/prime/egregore_runtime/todos.py +244 -0
- package/runtime/prime/egregore_runtime/upgrade.py +770 -0
- package/runtime/prime/egregore_runtime/upgrade_worker.py +53 -0
- package/runtime/prime/egregore_runtime/writeback.py +391 -0
- package/runtime/prime/egregore_runtime/writeback_cli.py +114 -0
- package/runtime/prime/manifest.json +99 -1
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
#!/usr/bin/env node
|
|
2
|
-
// egregore-launcher-version: 0.
|
|
2
|
+
// egregore-launcher-version: 0.21.0-runtime-mvp.1
|
|
3
3
|
//
|
|
4
4
|
// egregore — launch and browse Egregore instances from your terminal.
|
|
5
5
|
// Installed by create-egregore. Reads ~/.egregore/instances.json.
|
|
@@ -14,6 +14,8 @@
|
|
|
14
14
|
// egregore ls | list list instances (non-interactive table)
|
|
15
15
|
// egregore use <slug> set the default for bare `egregore`
|
|
16
16
|
// egregore connect [slug] activate Connected for an existing instance
|
|
17
|
+
// egregore telemetry <verb> manage local telemetry for an instance
|
|
18
|
+
// egregore runtime <verb> inspect or synchronize Local retrieval
|
|
17
19
|
// egregore /invite <user> invite a GitHub user to an instance
|
|
18
20
|
// egregore settings [slug] hosting on/off, managed repos, admins (s in browser)
|
|
19
21
|
// egregore prune [--dry-run] remove entries whose path is gone
|
|
@@ -33,7 +35,7 @@ const crypto = require("node:crypto");
|
|
|
33
35
|
const { spawnSync, spawn } = require("node:child_process");
|
|
34
36
|
const readline = require("node:readline");
|
|
35
37
|
|
|
36
|
-
const VERSION = "0.
|
|
38
|
+
const VERSION = "0.21.0-runtime-mvp.1";
|
|
37
39
|
const REGISTRY = path.join(os.homedir(), ".egregore", "instances.json");
|
|
38
40
|
const DEFAULT_FILE = path.join(os.homedir(), ".egregore", "default");
|
|
39
41
|
const UPDATE_CACHE_FILE = path.join(os.homedir(), ".egregore", "update-check.json");
|
|
@@ -360,6 +362,52 @@ function initialCursorForCwd(registry, cwd = safeCwd()) {
|
|
|
360
362
|
return 0;
|
|
361
363
|
}
|
|
362
364
|
|
|
365
|
+
function currentWorktreeInstance(registry, cwd = safeCwd()) {
|
|
366
|
+
// Development checkouts are intentionally not persisted as separate
|
|
367
|
+
// Egregore instances, but launching from one must preserve the exact code
|
|
368
|
+
// under test. A linked worktree has a `.git` file; a safe standalone clone
|
|
369
|
+
// has a `.git` directory. Walk upward and borrow only display/runtime
|
|
370
|
+
// preferences from a registered parent when one exists.
|
|
371
|
+
let candidate = path.resolve(cwd);
|
|
372
|
+
const filesystemRoot = path.parse(candidate).root;
|
|
373
|
+
while (candidate !== filesystemRoot) {
|
|
374
|
+
const marker = path.join(candidate, ".git");
|
|
375
|
+
const config = path.join(candidate, "egregore.json");
|
|
376
|
+
try {
|
|
377
|
+
const gitMarker = fs.statSync(marker);
|
|
378
|
+
if ((gitMarker.isFile() || gitMarker.isDirectory()) && fs.statSync(config).isFile()) {
|
|
379
|
+
const exact = registry.find(
|
|
380
|
+
(entry) => entry?.path && path.resolve(entry.path) === candidate,
|
|
381
|
+
);
|
|
382
|
+
if (exact) return null;
|
|
383
|
+
const parent = registry
|
|
384
|
+
.filter((entry) => entry?.path && pathContains(entry.path, candidate))
|
|
385
|
+
.sort((a, b) => path.resolve(b.path).length - path.resolve(a.path).length)[0];
|
|
386
|
+
if (parent) return { ...parent, path: candidate, transientWorktree: true };
|
|
387
|
+
const local = JSON.parse(fs.readFileSync(config, "utf-8"));
|
|
388
|
+
return {
|
|
389
|
+
slug: local.slug || path.basename(candidate),
|
|
390
|
+
name: local.org_name || local.slug || path.basename(candidate),
|
|
391
|
+
path: candidate,
|
|
392
|
+
transientWorktree: true,
|
|
393
|
+
};
|
|
394
|
+
}
|
|
395
|
+
} catch {
|
|
396
|
+
// Keep walking: normal subdirectories do not contain both markers.
|
|
397
|
+
}
|
|
398
|
+
candidate = path.dirname(candidate);
|
|
399
|
+
}
|
|
400
|
+
return null;
|
|
401
|
+
}
|
|
402
|
+
|
|
403
|
+
function isLinkedGitWorktree(directory) {
|
|
404
|
+
try {
|
|
405
|
+
return fs.statSync(path.join(directory, ".git")).isFile();
|
|
406
|
+
} catch {
|
|
407
|
+
return false;
|
|
408
|
+
}
|
|
409
|
+
}
|
|
410
|
+
|
|
363
411
|
// ── launch ──────────────────────────────────────────────────────────
|
|
364
412
|
|
|
365
413
|
function normalizeRuntime(raw) {
|
|
@@ -676,7 +724,7 @@ async function renderCodexStartupCard(egregoreDir) {
|
|
|
676
724
|
}, "Preparing Codex startup");
|
|
677
725
|
let output = result.stdout || "";
|
|
678
726
|
if (isConnectedPath(egregoreDir) && !output.includes("◆ CONNECTED")) {
|
|
679
|
-
const connectedLine =
|
|
727
|
+
const connectedLine = ` ◆ CONNECTED ${connectedModeSuffix(egregoreDir)}\n`;
|
|
680
728
|
output = output.includes("\nWhat are you working on?")
|
|
681
729
|
? output.replace("\nWhat are you working on?", `\n${connectedLine}\nWhat are you working on?`)
|
|
682
730
|
: `${output}${output.endsWith("\n") || !output ? "" : "\n"}${connectedLine}`;
|
|
@@ -702,7 +750,9 @@ function codexSupportMessage(egregoreDir) {
|
|
|
702
750
|
" .codex/hooks.json",
|
|
703
751
|
" .codex/hooks/",
|
|
704
752
|
"",
|
|
705
|
-
"
|
|
753
|
+
"Automatic repair did not complete. Retry with:",
|
|
754
|
+
" npx -y create-egregore@latest --refresh-launcher",
|
|
755
|
+
"Then rerun egregore.",
|
|
706
756
|
"Egregore workflows appear as slash commands. In Codex, invoke them with the matching $skill token or ask in natural language.",
|
|
707
757
|
].join("\n");
|
|
708
758
|
}
|
|
@@ -756,6 +806,27 @@ function primeSupportMessage(egregoreDir) {
|
|
|
756
806
|
].join("\n");
|
|
757
807
|
}
|
|
758
808
|
|
|
809
|
+
function repairPortableRuntime(egregoreDir, runtime) {
|
|
810
|
+
const label = runtimeLabel(runtime);
|
|
811
|
+
process.stdout.write(`\n ${CYAN}↻${RESET} ${BOLD}Repairing ${label} support${RESET}${DIM} — updating this checkout${RESET}\n`);
|
|
812
|
+
const result = spawnSync(
|
|
813
|
+
"npx",
|
|
814
|
+
["-y", `${PUBLIC_NPX_PACKAGE}@latest`, "--refresh-launcher"],
|
|
815
|
+
{
|
|
816
|
+
cwd: egregoreDir,
|
|
817
|
+
stdio: "inherit",
|
|
818
|
+
env: { ...process.env, EGREGORE_RUNTIME_REPAIR: runtime },
|
|
819
|
+
timeout: 3 * 60 * 1000,
|
|
820
|
+
},
|
|
821
|
+
);
|
|
822
|
+
if (result.error || result.status !== 0) {
|
|
823
|
+
process.stderr.write(` ${YELLOW}!${RESET} Automatic ${label} repair failed; the checkout was left in place.\n`);
|
|
824
|
+
return false;
|
|
825
|
+
}
|
|
826
|
+
process.stdout.write(` ${GREEN}✓${RESET} ${label} support repaired\n\n`);
|
|
827
|
+
return true;
|
|
828
|
+
}
|
|
829
|
+
|
|
759
830
|
// Minimal y/N line prompt for pre-launch decisions (the TUI select machinery
|
|
760
831
|
// is torn down by the time launch() runs).
|
|
761
832
|
function confirmLine(question) {
|
|
@@ -823,6 +894,9 @@ function installCodexSkills(egregoreDir) {
|
|
|
823
894
|
}
|
|
824
895
|
|
|
825
896
|
function claudeLaunchArgs(egregoreDir) {
|
|
897
|
+
// Claude treats the positional value as the initial user prompt. Egregore
|
|
898
|
+
// deliberately submits `start` so the opening experience renders without
|
|
899
|
+
// requiring the user to type first.
|
|
826
900
|
const args = ["start"];
|
|
827
901
|
const memoryLink = path.join(egregoreDir, "memory");
|
|
828
902
|
try {
|
|
@@ -840,14 +914,21 @@ function claudeLaunchArgs(egregoreDir) {
|
|
|
840
914
|
return args;
|
|
841
915
|
}
|
|
842
916
|
|
|
843
|
-
function runtimeLaunchArgs(runtime, egregoreDir) {
|
|
917
|
+
function runtimeLaunchArgs(runtime, egregoreDir, options = {}) {
|
|
844
918
|
if (runtime === "codex") {
|
|
845
|
-
|
|
919
|
+
const args = [
|
|
846
920
|
"--enable", "hooks",
|
|
847
921
|
"--sandbox", "danger-full-access",
|
|
848
922
|
"--ask-for-approval", "never",
|
|
849
923
|
"--cd", egregoreDir,
|
|
850
924
|
];
|
|
925
|
+
// Codex treats each linked worktree as a separate hook-trust root, while
|
|
926
|
+
// project hooks may still be discovered from the registered primary
|
|
927
|
+
// checkout. The Egregore launcher validates the Runtime surface above;
|
|
928
|
+
// trust that bounded hook set for this transient invocation so Observe
|
|
929
|
+
// and the branch guard are not silently skipped in the worktree.
|
|
930
|
+
if (options.bypassHookTrust) args.push("--dangerously-bypass-hook-trust");
|
|
931
|
+
return args;
|
|
851
932
|
}
|
|
852
933
|
if (runtime === "pi") return piTrustArgs();
|
|
853
934
|
if (runtime === "prime") return primeTrustArgs();
|
|
@@ -871,6 +952,12 @@ async function launch(inst, runtimeOverride) {
|
|
|
871
952
|
}
|
|
872
953
|
const runtime = await chooseRuntimeForLaunch(inst, runtimeOverride);
|
|
873
954
|
if (!runtime) return;
|
|
955
|
+
if (runtime === "claude-code" && isLinkedGitWorktree(inst.path)) {
|
|
956
|
+
die(
|
|
957
|
+
"Claude Code automatically removes linked Git worktrees when its worktree session ends.\n" +
|
|
958
|
+
" Launch Claude from a standalone clone of this branch instead; Codex, Pi, and Prime may use this worktree directly.",
|
|
959
|
+
);
|
|
960
|
+
}
|
|
874
961
|
if (runtime === "claude-code") {
|
|
875
962
|
normalizeClaudeDenyRules(inst.path);
|
|
876
963
|
ensureClaudeModeStatusLine(inst.path);
|
|
@@ -886,7 +973,9 @@ async function launch(inst, runtimeOverride) {
|
|
|
886
973
|
}
|
|
887
974
|
if (runtime === "codex") {
|
|
888
975
|
if (!hasCodexCoreSupport(inst.path)) {
|
|
889
|
-
|
|
976
|
+
if (!repairPortableRuntime(inst.path, runtime) || !hasCodexCoreSupport(inst.path)) {
|
|
977
|
+
die(codexSupportMessage(inst.path));
|
|
978
|
+
}
|
|
890
979
|
}
|
|
891
980
|
const skillsInstalled = installCodexSkills(inst.path);
|
|
892
981
|
const cardRendered = await renderCodexStartupCard(inst.path);
|
|
@@ -894,7 +983,10 @@ async function launch(inst, runtimeOverride) {
|
|
|
894
983
|
die(codexSupportMessage(inst.path));
|
|
895
984
|
}
|
|
896
985
|
} else if (runtime === "pi") {
|
|
897
|
-
if (!hasPiCoreSupport(inst.path)
|
|
986
|
+
if (!hasPiCoreSupport(inst.path) &&
|
|
987
|
+
(!repairPortableRuntime(inst.path, runtime) || !hasPiCoreSupport(inst.path))) {
|
|
988
|
+
die(piSupportMessage(inst.path));
|
|
989
|
+
}
|
|
898
990
|
}
|
|
899
991
|
let launchArgs = null;
|
|
900
992
|
if (runtime === "prime") {
|
|
@@ -903,7 +995,10 @@ async function launch(inst, runtimeOverride) {
|
|
|
903
995
|
// check + the trust-flag probe, which shells out to the binary), then a
|
|
904
996
|
// single handoff line explains the remaining in-harness startup.
|
|
905
997
|
const stopLoader = startSpinner("Starting Prime Agent");
|
|
906
|
-
|
|
998
|
+
let coreOk = hasPrimeCoreSupport(inst.path);
|
|
999
|
+
if (!coreOk && repairPortableRuntime(inst.path, runtime)) {
|
|
1000
|
+
coreOk = hasPrimeCoreSupport(inst.path);
|
|
1001
|
+
}
|
|
907
1002
|
launchArgs = coreOk ? runtimeLaunchArgs(runtime, inst.path) : null;
|
|
908
1003
|
stopLoader();
|
|
909
1004
|
if (!coreOk) die(primeSupportMessage(inst.path));
|
|
@@ -918,9 +1013,12 @@ async function launch(inst, runtimeOverride) {
|
|
|
918
1013
|
const launchEnv = {
|
|
919
1014
|
...process.env,
|
|
920
1015
|
EGREGORE_RUNTIME: runtime,
|
|
1016
|
+
EGREGORE_TRANSIENT_CHECKOUT: inst.transientWorktree ? "1" : process.env.EGREGORE_TRANSIENT_CHECKOUT,
|
|
921
1017
|
EGREGORE_CODEX_TRUSTED: runtime === "codex" ? "1" : process.env.EGREGORE_CODEX_TRUSTED,
|
|
922
1018
|
};
|
|
923
|
-
const child = spawn(binary, launchArgs || runtimeLaunchArgs(runtime, inst.path
|
|
1019
|
+
const child = spawn(binary, launchArgs || runtimeLaunchArgs(runtime, inst.path, {
|
|
1020
|
+
bypassHookTrust: runtime === "codex" && Boolean(inst.transientWorktree),
|
|
1021
|
+
}), {
|
|
924
1022
|
cwd: inst.path,
|
|
925
1023
|
stdio: "inherit",
|
|
926
1024
|
env: launchEnv,
|
|
@@ -1049,8 +1147,11 @@ function cmdHelp() {
|
|
|
1049
1147
|
` ${CYAN}egregore ls${RESET} ${DIM}| list${RESET} list installed instances`,
|
|
1050
1148
|
` ${CYAN}egregore use${RESET} ${DIM}<slug>${RESET} set the default for bare ${BOLD}egregore${RESET}`,
|
|
1051
1149
|
` ${CYAN}egregore connect${RESET} ${DIM}[slug]${RESET} activate Connected for an existing instance`,
|
|
1150
|
+
` ${CYAN}egregore telemetry${RESET} ${DIM}<verb>${RESET} status, inspect, enable, disable, export, or share`,
|
|
1151
|
+
` ${CYAN}egregore runtime${RESET} ${DIM}<verb>${RESET} status, sync, start, or stop Local retrieval`,
|
|
1052
1152
|
` ${CYAN}egregore /invite${RESET} ${DIM}<user> [slug]${RESET} invite a GitHub user`,
|
|
1053
1153
|
` ${CYAN}egregore settings${RESET} ${DIM}[slug]${RESET} hosting on/off, repos, admins`,
|
|
1154
|
+
` ${CYAN}egregore settings${RESET} ${DIM}<slug> runtime${RESET} Runtime update: review, prepare, activate, roll back`,
|
|
1054
1155
|
` ${CYAN}egregore prune${RESET} ${DIM}[--dry-run]${RESET} remove entries with missing paths`,
|
|
1055
1156
|
` ${CYAN}egregore rm${RESET} ${DIM}<slug|path>${RESET} remove a specific entry`,
|
|
1056
1157
|
``,
|
|
@@ -2085,6 +2186,79 @@ async function cmdInvite(args) {
|
|
|
2085
2186
|
return inviteToInstance(inst, username);
|
|
2086
2187
|
}
|
|
2087
2188
|
|
|
2189
|
+
function cmdTelemetry(args) {
|
|
2190
|
+
const registry = readRegistry();
|
|
2191
|
+
if (registry.length === 0) die("no egregores installed yet.\n run: npx -y create-egregore@latest");
|
|
2192
|
+
|
|
2193
|
+
const forwarded = args.slice();
|
|
2194
|
+
let instanceQuery = "";
|
|
2195
|
+
const marker = forwarded.indexOf("--instance");
|
|
2196
|
+
if (marker !== -1) {
|
|
2197
|
+
instanceQuery = forwarded[marker + 1] || "";
|
|
2198
|
+
if (!instanceQuery) die("usage: egregore telemetry <verb> [args] --instance <slug>");
|
|
2199
|
+
forwarded.splice(marker, 2);
|
|
2200
|
+
}
|
|
2201
|
+
if (forwarded.length === 0) forwarded.push("status");
|
|
2202
|
+
|
|
2203
|
+
const inst = resolveInviteInstance(registry, instanceQuery);
|
|
2204
|
+
if (!inst) {
|
|
2205
|
+
die("multiple egregores installed; choose one:\n egregore telemetry <verb> --instance <slug>\n run: egregore ls");
|
|
2206
|
+
}
|
|
2207
|
+
const script = path.join(inst.path, "bin", "telemetry.sh");
|
|
2208
|
+
if (!fs.existsSync(script)) {
|
|
2209
|
+
die("bin/telemetry.sh not found — update this Egregore before managing telemetry");
|
|
2210
|
+
}
|
|
2211
|
+
const result = spawnSync("bash", [script, ...forwarded], {
|
|
2212
|
+
cwd: inst.path,
|
|
2213
|
+
stdio: "inherit",
|
|
2214
|
+
env: { ...process.env },
|
|
2215
|
+
});
|
|
2216
|
+
if (result.error) die(`telemetry command failed: ${result.error.message}`);
|
|
2217
|
+
process.exitCode = result.status ?? 1;
|
|
2218
|
+
}
|
|
2219
|
+
|
|
2220
|
+
function cmdRuntime(args) {
|
|
2221
|
+
const registry = readRegistry();
|
|
2222
|
+
if (registry.length === 0) die("no egregores installed yet.\n run: npx -y create-egregore@latest");
|
|
2223
|
+
|
|
2224
|
+
const forwarded = args.slice();
|
|
2225
|
+
let instanceQuery = "";
|
|
2226
|
+
const marker = forwarded.indexOf("--instance");
|
|
2227
|
+
if (marker !== -1) {
|
|
2228
|
+
instanceQuery = forwarded[marker + 1] || "";
|
|
2229
|
+
if (!instanceQuery) die("usage: egregore runtime <status|sync|start|stop> --instance <slug>");
|
|
2230
|
+
forwarded.splice(marker, 2);
|
|
2231
|
+
}
|
|
2232
|
+
const verb = forwarded[0] || "status";
|
|
2233
|
+
if (!["status", "sync", "start", "stop", "update"].includes(verb) || forwarded.length > 1) {
|
|
2234
|
+
die("usage: egregore runtime <status|sync|start|stop> [--instance <slug>]");
|
|
2235
|
+
}
|
|
2236
|
+
const inst = resolveInviteInstance(registry, instanceQuery);
|
|
2237
|
+
if (!inst) {
|
|
2238
|
+
die("multiple egregores installed; choose one:\n egregore runtime status --instance <slug>\n run: egregore ls");
|
|
2239
|
+
}
|
|
2240
|
+
|
|
2241
|
+
let script;
|
|
2242
|
+
let scriptArgs;
|
|
2243
|
+
if (verb === "sync" || verb === "update") {
|
|
2244
|
+
script = path.join(inst.path, "bin", "agent.sh");
|
|
2245
|
+
scriptArgs = ["sync"];
|
|
2246
|
+
} else {
|
|
2247
|
+
script = path.join(inst.path, "bin", "search.sh");
|
|
2248
|
+
scriptArgs = [verb];
|
|
2249
|
+
}
|
|
2250
|
+
if (!fs.existsSync(script)) {
|
|
2251
|
+
die("Local Runtime controls are missing — update this Egregore before managing retrieval");
|
|
2252
|
+
}
|
|
2253
|
+
const result = spawnSync("bash", [script, ...scriptArgs], {
|
|
2254
|
+
cwd: inst.path,
|
|
2255
|
+
stdio: "inherit",
|
|
2256
|
+
env: { ...process.env },
|
|
2257
|
+
});
|
|
2258
|
+
if (result.error) die(`runtime command failed: ${result.error.message}`);
|
|
2259
|
+
process.exitCode = result.status ?? 1;
|
|
2260
|
+
}
|
|
2261
|
+
|
|
2088
2262
|
// ── settings ───────────────────────────────────────────────────────
|
|
2089
2263
|
//
|
|
2090
2264
|
// The launcher stays a THIN caller: every config change shells out to the
|
|
@@ -2102,7 +2276,7 @@ function runSettings(inst, args) {
|
|
|
2102
2276
|
return { status: 127, stdout: "", stderr: "bin/settings.sh not found — update this egregore (run /pull) to get settings.\n", missing: true };
|
|
2103
2277
|
}
|
|
2104
2278
|
try {
|
|
2105
|
-
return spawnSync("bash", [script, ...args], { cwd: inst.path, stdio: "pipe", encoding: "utf-8", timeout:
|
|
2279
|
+
return spawnSync("bash", [script, ...args], { cwd: inst.path, stdio: "pipe", encoding: "utf-8", timeout: 45000 });
|
|
2106
2280
|
} catch (err) {
|
|
2107
2281
|
return { status: 1, stdout: "", stderr: String(err) };
|
|
2108
2282
|
}
|
|
@@ -2114,17 +2288,440 @@ function settingsDump(inst) {
|
|
|
2114
2288
|
try { return JSON.parse(r.stdout); } catch { return null; }
|
|
2115
2289
|
}
|
|
2116
2290
|
|
|
2291
|
+
// ── runtime upgrade (per-instance, settings-first) ──────────────────
|
|
2292
|
+
// The launcher stays a thin caller: the transactional engine, gates,
|
|
2293
|
+
// activation, and rollback live in the instance's Python Runtime behind
|
|
2294
|
+
// bin/runtime-upgrade.sh. The launcher renders that state and forwards
|
|
2295
|
+
// explicit verbs — one source of truth, no JS reimplementation.
|
|
2296
|
+
|
|
2297
|
+
const RUNTIME_MVP_VERSION_RE = /^(0|[1-9]\d*)\.(0|[1-9]\d*)\.(0|[1-9]\d*)-runtime-mvp\.(0|[1-9]\d*)$/;
|
|
2298
|
+
const RUNTIME_MVP_REGISTRY_URL = process.env.EGREGORE_RUNTIME_MVP_REGISTRY_URL
|
|
2299
|
+
|| "https://registry.npmjs.org/create-egregore/runtime-mvp";
|
|
2300
|
+
|
|
2301
|
+
function upgradeScriptPath(inst) {
|
|
2302
|
+
return path.join(inst.path, "bin", "runtime-upgrade.sh");
|
|
2303
|
+
}
|
|
2304
|
+
|
|
2305
|
+
// After the Runtime cutover, a Connected instance's hosted link no longer
|
|
2306
|
+
// serves retrieval — saying "hosted graph active" would misstate what the
|
|
2307
|
+
// connection is for. Mirror the shell gate (bin/search.sh): stable org
|
|
2308
|
+
// identity composed with the main installation path keys the activation
|
|
2309
|
+
// record; only a real record flips the wording.
|
|
2310
|
+
function upgradedGraphRetrievalOff(instPath) {
|
|
2311
|
+
try {
|
|
2312
|
+
const cfg = JSON.parse(fs.readFileSync(path.join(instPath, "egregore.json"), "utf-8"));
|
|
2313
|
+
const orgId = String(cfg.org_id || "").trim();
|
|
2314
|
+
if (!orgId) return false;
|
|
2315
|
+
let main = instPath;
|
|
2316
|
+
const gitFile = path.join(instPath, ".git");
|
|
2317
|
+
if (fs.existsSync(gitFile) && fs.statSync(gitFile).isFile()) {
|
|
2318
|
+
const m = /^gitdir: (.*)$/m.exec(fs.readFileSync(gitFile, "utf-8"));
|
|
2319
|
+
if (m && m[1].includes("/.git/worktrees/")) main = m[1].split("/.git/worktrees/")[0];
|
|
2320
|
+
}
|
|
2321
|
+
main = fs.realpathSync(main);
|
|
2322
|
+
const key = crypto.createHash("sha256").update(`${orgId}|${main}`).digest("hex").slice(0, 16);
|
|
2323
|
+
const base = process.env.EGREGORE_UPGRADE_ROOT || path.join(os.homedir(), ".egregore", "runtime", "upgrade");
|
|
2324
|
+
const record = JSON.parse(fs.readFileSync(path.join(base, key, "active.json"), "utf-8"));
|
|
2325
|
+
return record.retrieval === "runtime-qmd";
|
|
2326
|
+
} catch {
|
|
2327
|
+
return false;
|
|
2328
|
+
}
|
|
2329
|
+
}
|
|
2330
|
+
|
|
2331
|
+
function connectedModeSuffix(instPath) {
|
|
2332
|
+
return upgradedGraphRetrievalOff(instPath)
|
|
2333
|
+
? "· hosted services · graph retrieval off"
|
|
2334
|
+
: "· hosted graph active";
|
|
2335
|
+
}
|
|
2336
|
+
|
|
2337
|
+
// An instance that predates the bridge (0.20.1 and earlier) is still
|
|
2338
|
+
// upgradable: the installed launcher package carries the candidate's own
|
|
2339
|
+
// engine, so the bootstrap never depends on a git sync delivering it.
|
|
2340
|
+
// EGREGORE_RUNTIME_PACKAGED_BRIDGE is the test seam ("" disables).
|
|
2341
|
+
function packagedUpgradeScript() {
|
|
2342
|
+
const seeded = process.env.EGREGORE_RUNTIME_PACKAGED_BRIDGE;
|
|
2343
|
+
if (seeded !== undefined) return seeded || null;
|
|
2344
|
+
const script = path.join(__dirname, "..", "runtime", "claude", "bin", "runtime-upgrade.sh");
|
|
2345
|
+
return fs.existsSync(script) ? script : null;
|
|
2346
|
+
}
|
|
2347
|
+
|
|
2348
|
+
function resolveUpgradeBridge(inst) {
|
|
2349
|
+
const own = upgradeScriptPath(inst);
|
|
2350
|
+
if (fs.existsSync(own)) return { script: own, env: {} };
|
|
2351
|
+
const packaged = packagedUpgradeScript();
|
|
2352
|
+
if (packaged && fs.existsSync(packaged)) {
|
|
2353
|
+
return { script: packaged, env: { EGREGORE_INSTANCE_ROOT: inst.path } };
|
|
2354
|
+
}
|
|
2355
|
+
return null;
|
|
2356
|
+
}
|
|
2357
|
+
|
|
2358
|
+
function runUpgrade(inst, args, timeout = 60000) {
|
|
2359
|
+
const bridge = resolveUpgradeBridge(inst);
|
|
2360
|
+
if (!bridge) {
|
|
2361
|
+
return { status: 127, stdout: "", stderr: "Runtime update is unavailable — no upgrade engine in this egregore or the installed launcher package.\n", missing: true };
|
|
2362
|
+
}
|
|
2363
|
+
try {
|
|
2364
|
+
return spawnSync("bash", [bridge.script, ...args], { cwd: inst.path, stdio: "pipe", encoding: "utf-8", timeout, env: { ...process.env, ...bridge.env } });
|
|
2365
|
+
} catch (err) {
|
|
2366
|
+
return { status: 1, stdout: "", stderr: String(err) };
|
|
2367
|
+
}
|
|
2368
|
+
}
|
|
2369
|
+
|
|
2370
|
+
// ── privacy & access + telemetry (Settings sections) ───────────────
|
|
2371
|
+
// Thin callers over deterministic adapters: bin/settings.sh privacy and
|
|
2372
|
+
// bin/telemetry.sh. The Runtime authorization backend supplies identity,
|
|
2373
|
+
// membership, and capability truth; the launcher only renders it. No model
|
|
2374
|
+
// round-trip, no raw JSON shown, no secrets or internal paths.
|
|
2375
|
+
|
|
2376
|
+
function runTelemetry(inst, args) {
|
|
2377
|
+
const script = path.join(inst.path, "bin", "telemetry.sh");
|
|
2378
|
+
if (!fs.existsSync(script)) return { status: 127, stdout: "", stderr: "telemetry adapter unavailable\n" };
|
|
2379
|
+
try {
|
|
2380
|
+
return spawnSync("bash", [script, ...args], { cwd: inst.path, stdio: "pipe", encoding: "utf-8", timeout: 15000 });
|
|
2381
|
+
} catch (err) {
|
|
2382
|
+
return { status: 1, stdout: "", stderr: String(err) };
|
|
2383
|
+
}
|
|
2384
|
+
}
|
|
2385
|
+
|
|
2386
|
+
function privacySnapshot(inst) {
|
|
2387
|
+
const r = runSettings(inst, ["privacy"]);
|
|
2388
|
+
if (!r || r.status !== 0 || !r.stdout) return null;
|
|
2389
|
+
try { return JSON.parse(r.stdout); } catch { return null; }
|
|
2390
|
+
}
|
|
2391
|
+
|
|
2392
|
+
function telemetrySnapshot(inst) {
|
|
2393
|
+
const r = runTelemetry(inst, ["status", "--json"]);
|
|
2394
|
+
if (!r || r.status !== 0 || !r.stdout) return null;
|
|
2395
|
+
try { return JSON.parse(r.stdout); } catch { return null; }
|
|
2396
|
+
}
|
|
2397
|
+
|
|
2398
|
+
function formatPrivacyLines(snapshot) {
|
|
2399
|
+
if (!snapshot) return ["Privacy & access state is unavailable for this egregore."];
|
|
2400
|
+
const a = snapshot.access || {};
|
|
2401
|
+
const b = snapshot.boundary || {};
|
|
2402
|
+
const lines = [];
|
|
2403
|
+
if (a.status !== "ok") {
|
|
2404
|
+
lines.push("Access needs attention — identity could not be resolved.");
|
|
2405
|
+
return lines;
|
|
2406
|
+
}
|
|
2407
|
+
lines.push(`Member: ${a.display_name || "unknown"}`);
|
|
2408
|
+
lines.push(`Organization: ${a.org_name || "unknown"} — membership ${a.membership_status || "unknown"}`);
|
|
2409
|
+
lines.push(`Details: actor ${String(a.actor_id || "").slice(0, 18)}…`);
|
|
2410
|
+
lines.push("");
|
|
2411
|
+
const caps = a.capabilities || {};
|
|
2412
|
+
const capLine = ["read", "create", "update", "publish", "notify", "org_settings"]
|
|
2413
|
+
.map((k) => `${k.replace("_", " ")} ${caps[k] ? "yes" : "no"}`)
|
|
2414
|
+
.join(" · ");
|
|
2415
|
+
lines.push(`Authorized capabilities: ${capLine}`);
|
|
2416
|
+
lines.push("For publish and notify, yes means you may request the action —");
|
|
2417
|
+
lines.push("every delivery still needs its own explicit approval.");
|
|
2418
|
+
lines.push("Custom roles: not enabled in this MVP.");
|
|
2419
|
+
lines.push(a.admin ? "Admin content: visible (you are an organization admin)" : "Admin content: hidden on Egregore surfaces");
|
|
2420
|
+
lines.push("");
|
|
2421
|
+
lines.push("Shared memory: available to authorized organization members");
|
|
2422
|
+
lines.push("Per-document restrictions: not enabled (raw repository access is organization-wide)");
|
|
2423
|
+
lines.push("Admin-marked content: hidden in Egregore surfaces from non-admin members");
|
|
2424
|
+
lines.push("External publication of admin-marked content: blocked unless an authorized admin separately confirms");
|
|
2425
|
+
lines.push("Publications require approval; notifications require separate exact approval.");
|
|
2426
|
+
lines.push("");
|
|
2427
|
+
lines.push(`Boundary posture: ${b.posture || "standard"}${b.locked ? " · organization policy locked" : ""}`);
|
|
2428
|
+
lines.push(`Other Egregore instances: ${snapshot.isolation ? snapshot.isolation.foreign_instances_denied : 0} isolated (hard, no consent path)`);
|
|
2429
|
+
const orgRoots = (b.org_read_roots || []).length;
|
|
2430
|
+
const personalRoots = b.personal_read_roots || [];
|
|
2431
|
+
lines.push(`Organization read roots: ${orgRoots} (managed by your organization)`);
|
|
2432
|
+
lines.push(`Personal read roots: ${personalRoots.length ? personalRoots.join(", ") : "none"}`);
|
|
2433
|
+
lines.push(
|
|
2434
|
+
snapshot.graph_retrieval === "not-used-by-this-runtime"
|
|
2435
|
+
? "Graph retrieval: not used by this Runtime"
|
|
2436
|
+
: "Graph retrieval: legacy configuration",
|
|
2437
|
+
);
|
|
2438
|
+
return lines;
|
|
2439
|
+
}
|
|
2440
|
+
|
|
2441
|
+
function telemetryEvents(inst, n = 50) {
|
|
2442
|
+
const r = runTelemetry(inst, ["inspect", String(n), "--json"]);
|
|
2443
|
+
if (!r || r.status !== 0 || !r.stdout) return [];
|
|
2444
|
+
try {
|
|
2445
|
+
const events = JSON.parse(r.stdout);
|
|
2446
|
+
return Array.isArray(events) ? events : [];
|
|
2447
|
+
} catch { return []; }
|
|
2448
|
+
}
|
|
2449
|
+
|
|
2450
|
+
function formatEventRow(event) {
|
|
2451
|
+
const at = String(event.occurred_at || "").replace("T", " ").slice(0, 16) || "????-?? ??:??";
|
|
2452
|
+
const metrics = event.metrics || {};
|
|
2453
|
+
const what = metrics.command || metrics.subcommand || metrics.action || "";
|
|
2454
|
+
const extras = [];
|
|
2455
|
+
if (metrics.duration_ms != null) extras.push(`${metrics.duration_ms}ms`);
|
|
2456
|
+
if (metrics.model) extras.push(String(metrics.model));
|
|
2457
|
+
if (metrics.result) extras.push(String(metrics.result));
|
|
2458
|
+
return `${at} ${pad(String(event.event_type || "event"), 12)} ${pad(String(what), 16)} ${extras.join(" · ")}`;
|
|
2459
|
+
}
|
|
2460
|
+
|
|
2461
|
+
function listSubdirectories(dir, showHidden) {
|
|
2462
|
+
try {
|
|
2463
|
+
return fs.readdirSync(dir, { withFileTypes: true })
|
|
2464
|
+
.filter((entry) => entry.isDirectory() && (showHidden || !entry.name.startsWith(".")))
|
|
2465
|
+
.map((entry) => entry.name)
|
|
2466
|
+
.sort();
|
|
2467
|
+
} catch { return []; }
|
|
2468
|
+
}
|
|
2469
|
+
|
|
2470
|
+
function formatTelemetryLines(status) {
|
|
2471
|
+
if (!status) return ["Telemetry state is unavailable for this egregore."];
|
|
2472
|
+
const lines = [];
|
|
2473
|
+
lines.push(`Telemetry: ${status.enabled ? "On" : "Off"}${status.reason ? ` (${status.reason})` : ""}`);
|
|
2474
|
+
lines.push(`Notice shown: ${status.notice_shown ? "yes" : "not yet"}`);
|
|
2475
|
+
lines.push(
|
|
2476
|
+
status.buffered_events > 0
|
|
2477
|
+
? `Local events waiting: ${status.buffered_events}`
|
|
2478
|
+
: "No buffered events",
|
|
2479
|
+
);
|
|
2480
|
+
if (status.last_event_at) lines.push(`Last event: ${status.last_event_at}`);
|
|
2481
|
+
lines.push("Events are held in a local buffer and never shared automatically.");
|
|
2482
|
+
lines.push("Collected: command names, timings, counts, model tiers — documented metadata only.");
|
|
2483
|
+
lines.push("Never collected: file contents, code, prompts, document excerpts,");
|
|
2484
|
+
lines.push("environment values, credentials, message bodies, personal memory content.");
|
|
2485
|
+
lines.push("Turning telemetry on or off is a personal setting for this member only.");
|
|
2486
|
+
return lines;
|
|
2487
|
+
}
|
|
2488
|
+
|
|
2489
|
+
function upgradeStatus(inst, { fetch = false } = {}) {
|
|
2490
|
+
const args = ["status"]; if (fetch) args.push("--fetch");
|
|
2491
|
+
const r = runUpgrade(inst, args);
|
|
2492
|
+
if (!r || r.status !== 0 || !r.stdout) return null;
|
|
2493
|
+
try { return JSON.parse(r.stdout); } catch { return null; }
|
|
2494
|
+
}
|
|
2495
|
+
|
|
2496
|
+
function upgradeStatusAsync(inst, cb) {
|
|
2497
|
+
const bridge = resolveUpgradeBridge(inst);
|
|
2498
|
+
if (!bridge) return cb(null);
|
|
2499
|
+
let buf = "";
|
|
2500
|
+
try {
|
|
2501
|
+
const child = spawn("bash", [bridge.script, "status"], { cwd: inst.path, stdio: ["ignore", "pipe", "ignore"], env: { ...process.env, ...bridge.env } });
|
|
2502
|
+
child.stdout.on("data", (d) => { buf += d; });
|
|
2503
|
+
child.on("close", () => { try { cb(JSON.parse(buf)); } catch { cb(null); } });
|
|
2504
|
+
child.on("error", () => cb(null));
|
|
2505
|
+
} catch { cb(null); }
|
|
2506
|
+
}
|
|
2507
|
+
|
|
2508
|
+
// Exact candidate resolution: the runtime-mvp dist-tag only, validated
|
|
2509
|
+
// against the prerelease scheme — never latest, never a retired scheme.
|
|
2510
|
+
// EGREGORE_RUNTIME_MVP_CANDIDATE is the offline/test seam.
|
|
2511
|
+
async function fetchRuntimeMvpCandidate() {
|
|
2512
|
+
const seeded = process.env.EGREGORE_RUNTIME_MVP_CANDIDATE;
|
|
2513
|
+
if (seeded !== undefined) return RUNTIME_MVP_VERSION_RE.test(seeded) ? seeded : null;
|
|
2514
|
+
try {
|
|
2515
|
+
const url = new URL(RUNTIME_MVP_REGISTRY_URL);
|
|
2516
|
+
const result = await requestJson({
|
|
2517
|
+
hostname: url.hostname,
|
|
2518
|
+
port: url.port || undefined,
|
|
2519
|
+
path: `${url.pathname}${url.search}`,
|
|
2520
|
+
method: "GET",
|
|
2521
|
+
protocol: url.protocol,
|
|
2522
|
+
timeoutMs: 1500,
|
|
2523
|
+
unref: true,
|
|
2524
|
+
headers: { Accept: "application/json" },
|
|
2525
|
+
});
|
|
2526
|
+
const version = result.status === 200 && result.data && result.data.version;
|
|
2527
|
+
return version && RUNTIME_MVP_VERSION_RE.test(version) ? version : null;
|
|
2528
|
+
} catch {
|
|
2529
|
+
return null;
|
|
2530
|
+
}
|
|
2531
|
+
}
|
|
2532
|
+
|
|
2533
|
+
const UPGRADE_STATUS_LABEL = {
|
|
2534
|
+
none: "no update staged",
|
|
2535
|
+
pending: "staged, not started",
|
|
2536
|
+
preparing: "preparing…",
|
|
2537
|
+
interrupted: "interrupted — resume to continue",
|
|
2538
|
+
failed: "needs attention",
|
|
2539
|
+
"ready-to-activate": "ready to activate",
|
|
2540
|
+
active: "active",
|
|
2541
|
+
cancelled: "cancelled",
|
|
2542
|
+
"rolled-back": "rolled back",
|
|
2543
|
+
};
|
|
2544
|
+
|
|
2545
|
+
function upgradeSummary(st) {
|
|
2546
|
+
if (!st || st.status === "none") return "up to date";
|
|
2547
|
+
if (st.status === "active") return `${st.active_version || "?"} active`;
|
|
2548
|
+
return UPGRADE_STATUS_LABEL[st.status] || st.status;
|
|
2549
|
+
}
|
|
2550
|
+
|
|
2551
|
+
function upgradeElapsed(st) {
|
|
2552
|
+
const worker = (st && st.worker) || {};
|
|
2553
|
+
const from = worker.started_at || st?.started_at;
|
|
2554
|
+
if (!from) return "";
|
|
2555
|
+
const s = Math.max(0, Math.floor(Date.now() / 1000 - from));
|
|
2556
|
+
return s >= 3600 ? `${Math.floor(s / 3600)}h ${Math.floor((s % 3600) / 60)}m` : s >= 60 ? `${Math.floor(s / 60)}m ${s % 60}s` : `${s}s`;
|
|
2557
|
+
}
|
|
2558
|
+
|
|
2559
|
+
// Plain-language body shared by the non-interactive `settings <slug> runtime`
|
|
2560
|
+
// output and the interactive panel. Returns undecorated strings; callers add
|
|
2561
|
+
// color. Never JSON, never internal paths beyond the instance's own root.
|
|
2562
|
+
function formatUpgradeLines(inst, st, { candidate = "" } = {}) {
|
|
2563
|
+
const lines = [];
|
|
2564
|
+
const d = st || { status: "none" };
|
|
2565
|
+
lines.push(`Selected Egregore: ${inst.name || inst.slug} (${inst.slug || "?"})`);
|
|
2566
|
+
lines.push(`Location: ${inst.path}`);
|
|
2567
|
+
lines.push("");
|
|
2568
|
+
lines.push(`Runtime: ${d.active_version || "unknown"} active`
|
|
2569
|
+
+ (d.candidate_version ? ` → candidate ${d.candidate_version}` : candidate ? ` → candidate ${candidate} available` : ""));
|
|
2570
|
+
lines.push(`Status: ${UPGRADE_STATUS_LABEL[d.status] || d.status}`);
|
|
2571
|
+
if (d.candidate_digest) lines.push(`Package digest: sha256 ${String(d.candidate_digest).slice(0, 16)}…`);
|
|
2572
|
+
if (d.failure && d.failure.message) lines.push(`Attention: ${d.failure.message}`);
|
|
2573
|
+
if (d.rollback_version && d.status !== "none") lines.push(`Rollback target: ${d.rollback_version}`);
|
|
2574
|
+
const ts = d.team_sync;
|
|
2575
|
+
if (ts && ts.label) lines.push(`Team memory: ${ts.label}`);
|
|
2576
|
+
if (d.status === "active") {
|
|
2577
|
+
lines.push("Organizational retrieval: Runtime/QMD");
|
|
2578
|
+
lines.push("Graph retrieval: not used by this Runtime version");
|
|
2579
|
+
} else if (d.status !== "none") {
|
|
2580
|
+
lines.push("Previous Runtime remains active until activation.");
|
|
2581
|
+
}
|
|
2582
|
+
if (Array.isArray(d.stages) && d.status !== "none" && d.status !== "active") {
|
|
2583
|
+
lines.push("");
|
|
2584
|
+
for (const stage of d.stages) {
|
|
2585
|
+
const glyph = stage.state === "done" ? "✓" : stage.state === "running" ? "◦" : stage.state === "failed" ? "✗" : "·";
|
|
2586
|
+
let detail = "";
|
|
2587
|
+
if (stage.key === "embed" || stage.key === "delta") {
|
|
2588
|
+
const p = d.progress || {};
|
|
2589
|
+
if (stage.state === "running") {
|
|
2590
|
+
const parts = [];
|
|
2591
|
+
if (p.vectors) parts.push(`${p.vectors} chunks embedded`);
|
|
2592
|
+
if (p.pending) parts.push(`${p.pending} pending`);
|
|
2593
|
+
parts.push(`${upgradeElapsed(d)} elapsed`);
|
|
2594
|
+
detail = ` — ${parts.join(" · ")}`;
|
|
2595
|
+
} else if (stage.state === "done" && stage.detail) {
|
|
2596
|
+
detail = ` — ${stage.detail}`;
|
|
2597
|
+
}
|
|
2598
|
+
} else if (stage.state === "failed" && stage.detail) {
|
|
2599
|
+
detail = ` — ${stage.detail}`;
|
|
2600
|
+
}
|
|
2601
|
+
lines.push(` ${glyph} ${stage.label}${detail}`);
|
|
2602
|
+
}
|
|
2603
|
+
}
|
|
2604
|
+
return lines;
|
|
2605
|
+
}
|
|
2606
|
+
|
|
2607
|
+
const UPGRADE_STAYS = [
|
|
2608
|
+
"Your team memory and organizational history",
|
|
2609
|
+
"Your identity and organization membership",
|
|
2610
|
+
"Permissions and authorization",
|
|
2611
|
+
"Projects, handoffs, and artifacts",
|
|
2612
|
+
"Connection configuration",
|
|
2613
|
+
"The current Runtime, until the new one is fully ready",
|
|
2614
|
+
];
|
|
2615
|
+
const UPGRADE_CHANGES = [
|
|
2616
|
+
"Runtime version",
|
|
2617
|
+
"Organizational retrieval moves to Runtime/QMD",
|
|
2618
|
+
"Keyword and meaning search become owned by this Egregore",
|
|
2619
|
+
"Graph retrieval stops after activation (kept only for rollback)",
|
|
2620
|
+
"Cross-session continuity uses the new Runtime",
|
|
2621
|
+
"Readiness and synchronization become visible here in Settings",
|
|
2622
|
+
];
|
|
2623
|
+
|
|
2624
|
+
async function cmdSettingsRuntime(inst, args) {
|
|
2625
|
+
const action = args[0] || "status";
|
|
2626
|
+
const fetchFlag = args.includes("--fetch");
|
|
2627
|
+
const emit = (st, extra = {}) => {
|
|
2628
|
+
for (const line of formatUpgradeLines(inst, st, extra)) process.stdout.write(line + "\n");
|
|
2629
|
+
};
|
|
2630
|
+
if (action === "status" || action === "review") {
|
|
2631
|
+
const st = upgradeStatus(inst, { fetch: fetchFlag });
|
|
2632
|
+
if (st === null) { process.stderr.write("Runtime update state is unavailable for this egregore.\n"); process.exitCode = 1; return; }
|
|
2633
|
+
emit(st);
|
|
2634
|
+
if (action === "review" || (st.status !== "active" && st.status !== "none")) {
|
|
2635
|
+
process.stdout.write("\nWhat stays:\n");
|
|
2636
|
+
for (const s of UPGRADE_STAYS) process.stdout.write(` · ${s}\n`);
|
|
2637
|
+
process.stdout.write("What changes:\n");
|
|
2638
|
+
for (const c of UPGRADE_CHANGES) process.stdout.write(` · ${c}\n`);
|
|
2639
|
+
}
|
|
2640
|
+
return;
|
|
2641
|
+
}
|
|
2642
|
+
if (action === "init") {
|
|
2643
|
+
const version = (args[1] || "").trim();
|
|
2644
|
+
const tarball = (args[2] || "").trim();
|
|
2645
|
+
if (!RUNTIME_MVP_VERSION_RE.test(version)) {
|
|
2646
|
+
process.stderr.write("Runtime update needs an exact candidate like 0.21.0-runtime-mvp.1.\n");
|
|
2647
|
+
process.exitCode = 1; return;
|
|
2648
|
+
}
|
|
2649
|
+
if (!tarball || !fs.existsSync(tarball)) {
|
|
2650
|
+
process.stderr.write("Runtime update installs actual packaged bytes: egregore settings <slug> runtime init <version> <candidate.tgz>\n");
|
|
2651
|
+
process.exitCode = 1; return;
|
|
2652
|
+
}
|
|
2653
|
+
const r = runUpgrade(inst, ["init", "--candidate", version, "--tarball", path.resolve(tarball)]);
|
|
2654
|
+
if (r.status !== 0) { process.stderr.write(r.stderr || "could not stage the candidate\n"); process.exitCode = r.status; return; }
|
|
2655
|
+
emit(upgradeStatus(inst) || null);
|
|
2656
|
+
return;
|
|
2657
|
+
}
|
|
2658
|
+
if (["prepare", "activate", "cancel", "rollback"].includes(action)) {
|
|
2659
|
+
const r = runUpgrade(inst, [action]);
|
|
2660
|
+
if (r.status !== 0) { process.stderr.write(r.stderr || `${action} failed\n`); process.exitCode = r.status; return; }
|
|
2661
|
+
const st = upgradeStatus(inst);
|
|
2662
|
+
emit(st);
|
|
2663
|
+
if (action === "activate" && st && st.status === "active") {
|
|
2664
|
+
process.stdout.write("\nUpdate complete. Start a session to work on the new Runtime.\n");
|
|
2665
|
+
}
|
|
2666
|
+
return;
|
|
2667
|
+
}
|
|
2668
|
+
process.stderr.write("usage: egregore settings <slug> runtime [status|review|init <version>|prepare|activate|cancel|rollback]\n");
|
|
2669
|
+
process.exitCode = 2;
|
|
2670
|
+
}
|
|
2671
|
+
|
|
2117
2672
|
async function cmdSettings(args) {
|
|
2118
2673
|
const registry = readRegistry();
|
|
2119
2674
|
if (registry.length === 0) die("no egregores installed yet.\n run: npx -y create-egregore@latest");
|
|
2120
|
-
const DOMAINS = new Set(["hosting", "repo", "admin", "people", "dump"]);
|
|
2675
|
+
const DOMAINS = new Set(["hosting", "workflow", "repo", "admin", "people", "dump", "runtime", "privacy", "telemetry", "boundary"]);
|
|
2121
2676
|
let rest = args.slice();
|
|
2122
2677
|
let slug = "";
|
|
2123
2678
|
if (rest.length && !DOMAINS.has(rest[0])) { slug = rest[0]; rest = rest.slice(1); }
|
|
2124
2679
|
const inst = resolveInviteInstance(registry, slug);
|
|
2125
2680
|
if (!inst) {
|
|
2126
|
-
die(`multiple egregores installed; choose one:\n egregore settings <slug> [hosting|repo|admin]\n run: egregore ls`);
|
|
2681
|
+
die(`multiple egregores installed; choose one:\n egregore settings <slug> [runtime|hosting|workflow|repo|admin|people|privacy|telemetry]\n run: egregore ls`);
|
|
2682
|
+
}
|
|
2683
|
+
// Runtime update is Runtime-owned state, not org config — it routes to the
|
|
2684
|
+
// upgrade bridge instead of bin/settings.sh.
|
|
2685
|
+
if (rest[0] === "runtime") return cmdSettingsRuntime(inst, rest.slice(1));
|
|
2686
|
+
// Privacy & access: rendered plain-language snapshot backed by the Runtime
|
|
2687
|
+
// authorization decision — never raw JSON, secrets, or internal paths.
|
|
2688
|
+
if (rest[0] === "privacy") {
|
|
2689
|
+
for (const line of formatPrivacyLines(privacySnapshot(inst))) console.log(line);
|
|
2690
|
+
return;
|
|
2127
2691
|
}
|
|
2692
|
+
// Telemetry: personal, opt-out, content-free. Mutations require the exact
|
|
2693
|
+
// --confirm because a non-interactive verb has no y/N checkpoint.
|
|
2694
|
+
if (rest[0] === "telemetry") {
|
|
2695
|
+
const verb = rest[1] || "status";
|
|
2696
|
+
if (verb === "status") {
|
|
2697
|
+
for (const line of formatTelemetryLines(telemetrySnapshot(inst))) console.log(line);
|
|
2698
|
+
return;
|
|
2699
|
+
}
|
|
2700
|
+
if (verb === "inspect") {
|
|
2701
|
+
const n = /^\d+$/.test(rest[2] || "") ? Number(rest[2]) : 20;
|
|
2702
|
+
const events = telemetryEvents(inst, n);
|
|
2703
|
+
if (!events.length) { console.log("No buffered events."); return; }
|
|
2704
|
+
for (const event of events) console.log(formatEventRow(event));
|
|
2705
|
+
return;
|
|
2706
|
+
}
|
|
2707
|
+
if (verb === "on" || verb === "off" || verb === "clear") {
|
|
2708
|
+
if (!rest.includes("--confirm")) {
|
|
2709
|
+
const what = verb === "clear"
|
|
2710
|
+
? `delete ${(telemetrySnapshot(inst) || {}).buffered_events || 0} locally buffered event(s); nothing else is removed`
|
|
2711
|
+
: `turn telemetry ${verb} for this member only`;
|
|
2712
|
+
process.stderr.write(`this will ${what}.\nre-run with --confirm to proceed: egregore settings ${inst.slug} telemetry ${verb} --confirm\n`);
|
|
2713
|
+
process.exitCode = 1;
|
|
2714
|
+
return;
|
|
2715
|
+
}
|
|
2716
|
+
const r = runTelemetry(inst, [verb]);
|
|
2717
|
+
if (r.stdout) process.stdout.write(r.stdout);
|
|
2718
|
+
if (r.stderr) process.stderr.write(r.stderr);
|
|
2719
|
+
process.exitCode = r.status || 0;
|
|
2720
|
+
return;
|
|
2721
|
+
}
|
|
2722
|
+
die("usage: egregore settings <slug> telemetry [status|inspect [n]|on|off|clear] [--confirm]");
|
|
2723
|
+
}
|
|
2724
|
+
|
|
2128
2725
|
// Interactive editing lives in the launcher (press `s`). With no verb, print
|
|
2129
2726
|
// the snapshot; otherwise forward straight to the deterministic verb.
|
|
2130
2727
|
if (rest.length === 0) rest = ["dump"];
|
|
@@ -2342,7 +2939,7 @@ function renderRuntimePanel({ inst, cursor, width, height }) {
|
|
|
2342
2939
|
boxLine(`${DIM}${inst.path}${RESET}`, innerWidth, margin),
|
|
2343
2940
|
boxLine(
|
|
2344
2941
|
isConnectedInstance(inst)
|
|
2345
|
-
? `${CYAN}◆ CONNECTED${RESET} ${DIM}
|
|
2942
|
+
? `${CYAN}◆ CONNECTED${RESET} ${DIM}${connectedModeSuffix(inst.path)}${RESET}`
|
|
2346
2943
|
: `${DIM}◇ LOCAL · Markdown + Git${RESET}`,
|
|
2347
2944
|
innerWidth,
|
|
2348
2945
|
margin,
|
|
@@ -2382,7 +2979,67 @@ const SETTINGS_DOMAIN_LABEL = { repo: "Managed repos", admin: "Admins", people:
|
|
|
2382
2979
|
const SETTINGS_DOMAIN_NOUN = { repo: "repo name", admin: "github handle", people: "github handle" };
|
|
2383
2980
|
|
|
2384
2981
|
// Same box geometry as renderRuntimePanel so pressing `s` keeps the frame put.
|
|
2385
|
-
|
|
2982
|
+
// Runtime-update panel: renders the durable upgrade state from the Python
|
|
2983
|
+
// engine. Same geometry as the settings panel; plain-language body from
|
|
2984
|
+
// formatUpgradeLines with launcher glyph decoration only.
|
|
2985
|
+
function renderUpgradePanel({ inst, data, candidate, mode, notice, width }) {
|
|
2986
|
+
const outerWidth = Math.min(Math.max(50, width - 2), 126);
|
|
2987
|
+
const innerWidth = Math.max(48, outerWidth - 2);
|
|
2988
|
+
const margin = " ".repeat(Math.max(0, Math.floor((width - outerWidth) / 2)));
|
|
2989
|
+
const label = " runtime update ";
|
|
2990
|
+
const lines = [
|
|
2991
|
+
`${margin}${DIM}┌${"─".repeat(2)}${label}${"─".repeat(Math.max(0, innerWidth - label.length - 2))}┐${RESET}`,
|
|
2992
|
+
emptyBoxLine(innerWidth, margin),
|
|
2993
|
+
];
|
|
2994
|
+
const body = data === undefined
|
|
2995
|
+
? ["Checking this egregore's Runtime state…"]
|
|
2996
|
+
: data === null
|
|
2997
|
+
? ["Runtime update state is unavailable for this egregore."]
|
|
2998
|
+
: formatUpgradeLines(inst, data, { candidate });
|
|
2999
|
+
for (const raw of body) {
|
|
3000
|
+
let line = raw;
|
|
3001
|
+
if (/^ ✓ /.test(raw)) line = ` ${GREEN}✓${RESET} ${raw.slice(4)}`;
|
|
3002
|
+
else if (/^ ◦ /.test(raw)) line = ` ${CYAN}◦${RESET} ${raw.slice(4)}`;
|
|
3003
|
+
else if (/^ ✗ /.test(raw)) line = ` ${RED}✗${RESET} ${raw.slice(4)}`;
|
|
3004
|
+
else if (/^ · /.test(raw)) line = ` ${DIM}·${RESET} ${DIM}${raw.slice(4)}${RESET}`;
|
|
3005
|
+
else if (/^(Location|Rollback target):/.test(raw)) line = `${DIM}${raw}${RESET}`;
|
|
3006
|
+
lines.push(boxLine(line, innerWidth, margin));
|
|
3007
|
+
}
|
|
3008
|
+
const status = data && data.status;
|
|
3009
|
+
if (mode === "confirm-prepare") {
|
|
3010
|
+
lines.push(emptyBoxLine(innerWidth, margin));
|
|
3011
|
+
lines.push(boxLine(`${BOLD}What stays${RESET}`, innerWidth, margin));
|
|
3012
|
+
for (const s of UPGRADE_STAYS) lines.push(boxLine(` · ${s}`, innerWidth, margin));
|
|
3013
|
+
lines.push(boxLine(`${BOLD}What changes${RESET}`, innerWidth, margin));
|
|
3014
|
+
for (const c of UPGRADE_CHANGES) lines.push(boxLine(` · ${c}`, innerWidth, margin));
|
|
3015
|
+
lines.push(emptyBoxLine(innerWidth, margin));
|
|
3016
|
+
lines.push(boxLine(`${YELLOW}Prepare the update for ${BOLD}${inst.slug}${RESET}${YELLOW} at this location only?${RESET} ${DIM}y / N${RESET}`, innerWidth, margin));
|
|
3017
|
+
} else if (mode === "confirm-activate") {
|
|
3018
|
+
lines.push(emptyBoxLine(innerWidth, margin));
|
|
3019
|
+
lines.push(boxLine(`${YELLOW}Activate the new Runtime for ${BOLD}${inst.slug}${RESET}${YELLOW}?${RESET} ${DIM}y / N${RESET}`, innerWidth, margin));
|
|
3020
|
+
} else if (mode === "confirm-rollback") {
|
|
3021
|
+
lines.push(emptyBoxLine(innerWidth, margin));
|
|
3022
|
+
lines.push(boxLine(`${YELLOW}Roll ${BOLD}${inst.slug}${RESET}${YELLOW} back to ${data?.rollback_version || "the previous Runtime"}?${RESET} ${DIM}y / N${RESET}`, innerWidth, margin));
|
|
3023
|
+
} else if (mode === "confirm-cancel") {
|
|
3024
|
+
lines.push(emptyBoxLine(innerWidth, margin));
|
|
3025
|
+
lines.push(boxLine(`${YELLOW}Cancel preparation? The current Runtime stays untouched.${RESET} ${DIM}y / N${RESET}`, innerWidth, margin));
|
|
3026
|
+
} else {
|
|
3027
|
+
lines.push(emptyBoxLine(innerWidth, margin));
|
|
3028
|
+
if (notice) lines.push(boxLine(notice, innerWidth, margin));
|
|
3029
|
+
const keys = [];
|
|
3030
|
+
if (!status || status === "none" || ["pending", "failed", "interrupted", "cancelled", "rolled-back"].includes(status)) keys.push(`${BOLD}p${RESET}${DIM} prepare${RESET}`);
|
|
3031
|
+
if (status === "ready-to-activate") keys.push(`${BOLD}a${RESET}${DIM} activate${RESET}`);
|
|
3032
|
+
if (status === "preparing") keys.push(`${BOLD}c${RESET}${DIM} cancel${RESET}`);
|
|
3033
|
+
if (status === "active") keys.push(`${BOLD}r${RESET}${DIM} roll back${RESET}`);
|
|
3034
|
+
keys.push(`${DIM}← back · q quit${RESET}`);
|
|
3035
|
+
lines.push(boxLine(keys.join(`${DIM} · ${RESET}`), innerWidth, margin));
|
|
3036
|
+
}
|
|
3037
|
+
lines.push(emptyBoxLine(innerWidth, margin));
|
|
3038
|
+
lines.push(`${margin}${DIM}└${"─".repeat(innerWidth)}┘${RESET}`);
|
|
3039
|
+
return lines;
|
|
3040
|
+
}
|
|
3041
|
+
|
|
3042
|
+
function renderSettingsPanel({ inst, data, cursor, view, domain, items, listCursor, mode, input, notice, width, upgrade }) {
|
|
2386
3043
|
const title = inst.slug || inst.name || path.basename(inst.path);
|
|
2387
3044
|
const outerWidth = Math.min(Math.max(50, width - 2), 126);
|
|
2388
3045
|
const innerWidth = Math.max(48, outerWidth - 2);
|
|
@@ -2397,6 +3054,114 @@ function renderSettingsPanel({ inst, data, cursor, view, domain, items, listCurs
|
|
|
2397
3054
|
emptyBoxLine(innerWidth, margin),
|
|
2398
3055
|
];
|
|
2399
3056
|
|
|
3057
|
+
if (view === "privacy" || view === "telemetry") {
|
|
3058
|
+
lines.push(boxLine(`${BOLD}${view === "privacy" ? "Privacy & access" : "Telemetry"}${RESET}`, innerWidth, margin));
|
|
3059
|
+
lines.push(emptyBoxLine(innerWidth, margin));
|
|
3060
|
+
if (mode === "shareinfo") {
|
|
3061
|
+
const shareLines = (data && data.shareLines) || ["share proposal unavailable"];
|
|
3062
|
+
lines.push(boxLine(`${BOLD}Share proposal${RESET} ${DIM}(nothing has been sent)${RESET}`, innerWidth, margin));
|
|
3063
|
+
lines.push(emptyBoxLine(innerWidth, margin));
|
|
3064
|
+
for (const line of shareLines.slice(0, 16)) {
|
|
3065
|
+
lines.push(boxLine(`${line.includes("--confirm") ? "" : DIM}${line}${RESET}`, innerWidth, margin));
|
|
3066
|
+
}
|
|
3067
|
+
lines.push(emptyBoxLine(innerWidth, margin));
|
|
3068
|
+
lines.push(boxLine(`${DIM}Sharing completes only by running the confirm command above in a terminal. ← back${RESET}`, innerWidth, margin));
|
|
3069
|
+
lines.push(emptyBoxLine(innerWidth, margin));
|
|
3070
|
+
lines.push(`${margin}${DIM}└${"─".repeat(innerWidth)}┘${RESET}`);
|
|
3071
|
+
return lines;
|
|
3072
|
+
}
|
|
3073
|
+
if (mode === "events") {
|
|
3074
|
+
const events = (data && data.telemetryEvents) || [];
|
|
3075
|
+
lines.push(boxLine(`${BOLD}Local events${RESET} ${DIM}(newest last · nothing here ever uploads by itself)${RESET}`, innerWidth, margin));
|
|
3076
|
+
lines.push(emptyBoxLine(innerWidth, margin));
|
|
3077
|
+
if (!events.length) {
|
|
3078
|
+
lines.push(boxLine(`${DIM}(no buffered events)${RESET}`, innerWidth, margin));
|
|
3079
|
+
} else {
|
|
3080
|
+
const cursorAt = Math.min(listCursor || 0, events.length - 1);
|
|
3081
|
+
const windowSize = 12;
|
|
3082
|
+
const start = Math.max(0, Math.min(cursorAt - Math.floor(windowSize / 2), events.length - windowSize));
|
|
3083
|
+
events.slice(start, start + windowSize).forEach((event, i) => {
|
|
3084
|
+
const sel = start + i === cursorAt;
|
|
3085
|
+
lines.push(boxLine(`${sel ? `${CYAN}❯${RESET} ` : " "}${sel ? "" : DIM}${formatEventRow(event)}${RESET}`, innerWidth, margin));
|
|
3086
|
+
});
|
|
3087
|
+
if (events.length > windowSize) lines.push(boxLine(`${DIM}${cursorAt + 1}/${events.length}${RESET}`, innerWidth, margin));
|
|
3088
|
+
}
|
|
3089
|
+
lines.push(emptyBoxLine(innerWidth, margin));
|
|
3090
|
+
if (notice) lines.push(boxLine(notice, innerWidth, margin));
|
|
3091
|
+
lines.push(boxLine(`${DIM}↑↓ scroll · ${RESET}${BOLD}e${RESET}${DIM} export to file · ${RESET}${BOLD}s${RESET}${DIM} share (two-step consent) · ← back${RESET}`, innerWidth, margin));
|
|
3092
|
+
lines.push(emptyBoxLine(innerWidth, margin));
|
|
3093
|
+
lines.push(`${margin}${DIM}└${"─".repeat(innerWidth)}┘${RESET}`);
|
|
3094
|
+
return lines;
|
|
3095
|
+
}
|
|
3096
|
+
if (mode === "pickdir") {
|
|
3097
|
+
const pick = (data && data.dirPick) || { dir: os.homedir(), entries: [], cursor: 0, hidden: false };
|
|
3098
|
+
lines.push(boxLine(`${BOLD}Choose a directory to allow reading${RESET}`, innerWidth, margin));
|
|
3099
|
+
lines.push(boxLine(`${DIM}${pick.dir}${RESET}`, innerWidth, margin));
|
|
3100
|
+
lines.push(emptyBoxLine(innerWidth, margin));
|
|
3101
|
+
if (!pick.entries.length) {
|
|
3102
|
+
lines.push(boxLine(`${DIM}(no subdirectories${pick.hidden ? "" : " — press . to show hidden"})${RESET}`, innerWidth, margin));
|
|
3103
|
+
} else {
|
|
3104
|
+
const windowSize = 10;
|
|
3105
|
+
const start = Math.max(0, Math.min(pick.cursor - Math.floor(windowSize / 2), pick.entries.length - windowSize));
|
|
3106
|
+
pick.entries.slice(start, start + windowSize).forEach((name, i) => {
|
|
3107
|
+
const sel = start + i === pick.cursor;
|
|
3108
|
+
lines.push(boxLine(`${sel ? `${CYAN}❯${RESET} ` : " "}${sel ? BOLD : DIM}${name}/${RESET}`, innerWidth, margin));
|
|
3109
|
+
});
|
|
3110
|
+
}
|
|
3111
|
+
lines.push(emptyBoxLine(innerWidth, margin));
|
|
3112
|
+
if (notice) lines.push(boxLine(notice, innerWidth, margin));
|
|
3113
|
+
lines.push(boxLine(`${DIM}↑↓ nav · → enter descend · ← up · ${RESET}${BOLD}space${RESET}${DIM} allow this directory · . hidden · esc cancel${RESET}`, innerWidth, margin));
|
|
3114
|
+
lines.push(emptyBoxLine(innerWidth, margin));
|
|
3115
|
+
lines.push(`${margin}${DIM}└${"─".repeat(innerWidth)}┘${RESET}`);
|
|
3116
|
+
return lines;
|
|
3117
|
+
}
|
|
3118
|
+
if (mode === "pickroot") {
|
|
3119
|
+
const roots = (data && data.privacySnapshot && data.privacySnapshot.boundary && data.privacySnapshot.boundary.personal_read_roots) || [];
|
|
3120
|
+
lines.push(boxLine(`${BOLD}Remove a personal read root${RESET}`, innerWidth, margin));
|
|
3121
|
+
lines.push(emptyBoxLine(innerWidth, margin));
|
|
3122
|
+
if (!roots.length) {
|
|
3123
|
+
lines.push(boxLine(`${DIM}(no personal read roots)${RESET}`, innerWidth, margin));
|
|
3124
|
+
} else {
|
|
3125
|
+
roots.forEach((root, i) => {
|
|
3126
|
+
const sel = i === (listCursor || 0);
|
|
3127
|
+
lines.push(boxLine(`${sel ? `${CYAN}❯${RESET} ` : " "}${sel ? BOLD : DIM}${root}${RESET}`, innerWidth, margin));
|
|
3128
|
+
});
|
|
3129
|
+
}
|
|
3130
|
+
lines.push(emptyBoxLine(innerWidth, margin));
|
|
3131
|
+
if (notice) lines.push(boxLine(notice, innerWidth, margin));
|
|
3132
|
+
lines.push(boxLine(`${DIM}↑↓ nav · enter remove · esc cancel${RESET}`, innerWidth, margin));
|
|
3133
|
+
lines.push(emptyBoxLine(innerWidth, margin));
|
|
3134
|
+
lines.push(`${margin}${DIM}└${"─".repeat(innerWidth)}┘${RESET}`);
|
|
3135
|
+
return lines;
|
|
3136
|
+
}
|
|
3137
|
+
const body = view === "privacy" ? formatPrivacyLines(data && data.privacySnapshot) : formatTelemetryLines(data && data.telemetrySnapshot);
|
|
3138
|
+
for (const line of body) {
|
|
3139
|
+
lines.push(line === "" ? emptyBoxLine(innerWidth, margin) : boxLine(`${line.startsWith("Access needs") || line.startsWith("Telemetry needs") ? YELLOW : ""}${line}${RESET}`, innerWidth, margin));
|
|
3140
|
+
}
|
|
3141
|
+
lines.push(emptyBoxLine(innerWidth, margin));
|
|
3142
|
+
if (mode === "confirm" && input) {
|
|
3143
|
+
lines.push(boxLine(`${YELLOW}${input}${RESET}`, innerWidth, margin));
|
|
3144
|
+
} else if (mode === "input") {
|
|
3145
|
+
lines.push(boxLine(`${BOLD}directory:${RESET} ${input}${DIM}▌${RESET}`, innerWidth, margin));
|
|
3146
|
+
}
|
|
3147
|
+
if (notice) lines.push(boxLine(notice, innerWidth, margin));
|
|
3148
|
+
if (view === "privacy") {
|
|
3149
|
+
const locked = !!(data && data.privacySnapshot && data.privacySnapshot.boundary && data.privacySnapshot.boundary.locked);
|
|
3150
|
+
lines.push(boxLine(
|
|
3151
|
+
locked
|
|
3152
|
+
? `${DIM}Boundary policy is managed by your organization. ← back · q quit${RESET}`
|
|
3153
|
+
: `${DIM}${RESET}${BOLD}a${RESET}${DIM} add personal read root · ${RESET}${BOLD}r${RESET}${DIM} remove · ← back · q quit${RESET}`,
|
|
3154
|
+
innerWidth, margin,
|
|
3155
|
+
));
|
|
3156
|
+
} else {
|
|
3157
|
+
const on = !!(data && data.telemetrySnapshot && data.telemetrySnapshot.enabled);
|
|
3158
|
+
lines.push(boxLine(`${DIM}${RESET}${BOLD}i${RESET}${DIM} view events · ${RESET}${BOLD}t${RESET}${DIM} turn ${on ? "off" : "on"} · ${RESET}${BOLD}x${RESET}${DIM} clear local buffer · ← back · q quit${RESET}`, innerWidth, margin));
|
|
3159
|
+
}
|
|
3160
|
+
lines.push(emptyBoxLine(innerWidth, margin));
|
|
3161
|
+
lines.push(`${margin}${DIM}└${"─".repeat(innerWidth)}┘${RESET}`);
|
|
3162
|
+
return lines;
|
|
3163
|
+
}
|
|
3164
|
+
|
|
2400
3165
|
if (view === "list") {
|
|
2401
3166
|
lines.push(boxLine(`${BOLD}${SETTINGS_DOMAIN_LABEL[domain] || domain}${RESET}`, innerWidth, margin));
|
|
2402
3167
|
lines.push(emptyBoxLine(innerWidth, margin));
|
|
@@ -2419,8 +3184,28 @@ function renderSettingsPanel({ inst, data, cursor, view, domain, items, listCurs
|
|
|
2419
3184
|
lines.push(boxLine(`${DIM}↑↓ nav · ${RESET}${BOLD}a${RESET}${DIM} add · ${RESET}${BOLD}d${RESET}${DIM} delete · ← back · q quit${RESET}`, innerWidth, margin));
|
|
2420
3185
|
}
|
|
2421
3186
|
} else {
|
|
3187
|
+
const upgradeValue = upgrade === undefined
|
|
3188
|
+
? `${DIM}checking…${RESET}`
|
|
3189
|
+
: upgrade === null
|
|
3190
|
+
? `${DIM}unavailable${RESET}`
|
|
3191
|
+
: upgrade.status === "ready-to-activate"
|
|
3192
|
+
? `${GREEN}${upgradeSummary(upgrade)}${RESET}`
|
|
3193
|
+
: upgrade.status === "failed" || upgrade.status === "interrupted"
|
|
3194
|
+
? `${YELLOW}${upgradeSummary(upgrade)}${RESET}`
|
|
3195
|
+
: `${DIM}${upgradeSummary(upgrade)}${RESET}`;
|
|
2422
3196
|
const rows = [
|
|
3197
|
+
{ name: "Runtime update", value: upgradeValue },
|
|
3198
|
+
{ name: "Privacy & access", value: `${DIM}identity · boundary · consent${RESET}` },
|
|
3199
|
+
{ name: "Telemetry", value: `${DIM}personal · opt-out${RESET}` },
|
|
2423
3200
|
{ name: "Hosted Artifacts", value: (d.hosting !== false) ? `${GREEN}ON${RESET}` : `${YELLOW}OFF${RESET}` },
|
|
3201
|
+
{
|
|
3202
|
+
name: "Git workflow",
|
|
3203
|
+
value: d.workflow === "simple"
|
|
3204
|
+
? `${DIM}PRs → main${RESET}`
|
|
3205
|
+
: d.workflow === "staged"
|
|
3206
|
+
? `${DIM}PRs → develop → main${RESET}`
|
|
3207
|
+
: `${DIM}PRs → ${d.base_branch || "custom"}${RESET}`,
|
|
3208
|
+
},
|
|
2424
3209
|
{ name: "Managed repos", value: `${DIM}${(d.repos || []).length}${RESET}` },
|
|
2425
3210
|
{ name: "Admins", value: `${DIM}${(d.admins || []).length}${RESET}` },
|
|
2426
3211
|
{ name: "People", value: `${DIM}${(d.people || []).length}${RESET}` },
|
|
@@ -2433,7 +3218,7 @@ function renderSettingsPanel({ inst, data, cursor, view, domain, items, listCurs
|
|
|
2433
3218
|
});
|
|
2434
3219
|
lines.push(emptyBoxLine(innerWidth, margin));
|
|
2435
3220
|
if (notice) lines.push(boxLine(notice, innerWidth, margin));
|
|
2436
|
-
lines.push(boxLine(`${DIM}↑↓ nav · ${RESET}${BOLD}enter${RESET}${DIM} ${cursor ===
|
|
3221
|
+
lines.push(boxLine(`${DIM}↑↓ nav · ${RESET}${BOLD}enter${RESET}${DIM} ${cursor === 3 || cursor === 4 ? "toggle" : "open"} · ← back · q quit${RESET}`, innerWidth, margin));
|
|
2437
3222
|
}
|
|
2438
3223
|
|
|
2439
3224
|
lines.push(emptyBoxLine(innerWidth, margin));
|
|
@@ -2558,6 +3343,22 @@ async function browser(args = {}) {
|
|
|
2558
3343
|
return;
|
|
2559
3344
|
}
|
|
2560
3345
|
|
|
3346
|
+
if (state.upgradeInst) {
|
|
3347
|
+
const upgradeLines = renderUpgradePanel({
|
|
3348
|
+
inst: state.upgradeInst,
|
|
3349
|
+
data: state.upgradeData,
|
|
3350
|
+
candidate: state.upgradeCandidate,
|
|
3351
|
+
mode: state.upgradeMode,
|
|
3352
|
+
notice: state.upgradeNotice,
|
|
3353
|
+
width: w,
|
|
3354
|
+
});
|
|
3355
|
+
for (const line of upgradeLines) out.push(line + ANSI.clearLine + "\n");
|
|
3356
|
+
const upgradeRemaining = Math.max(0, h - upgradeLines.length - 1);
|
|
3357
|
+
for (let i = 0; i < upgradeRemaining; i++) out.push(ANSI.clearLine + "\n");
|
|
3358
|
+
process.stdout.write(out.join(""));
|
|
3359
|
+
return;
|
|
3360
|
+
}
|
|
3361
|
+
|
|
2561
3362
|
if (state.settingsInst) {
|
|
2562
3363
|
const settingsLines = renderSettingsPanel({
|
|
2563
3364
|
inst: state.settingsInst,
|
|
@@ -2571,6 +3372,7 @@ async function browser(args = {}) {
|
|
|
2571
3372
|
input: state.settingsInput,
|
|
2572
3373
|
notice: state.settingsNotice,
|
|
2573
3374
|
width: w,
|
|
3375
|
+
upgrade: state.settingsUpgrade,
|
|
2574
3376
|
});
|
|
2575
3377
|
for (const line of settingsLines) out.push(line + ANSI.clearLine + "\n");
|
|
2576
3378
|
const remainingRows = Math.max(0, h - settingsLines.length - 1);
|
|
@@ -2697,7 +3499,7 @@ async function browser(args = {}) {
|
|
|
2697
3499
|
: ` ${label("path")} ${truncate(selected.path, valW)}`);
|
|
2698
3500
|
if (pv.org) previewLines.push(` ${label("org")} ${truncate(`${pv.org} ${DIM}(${pv.githubOrg || "?"})${RESET}`, valW)}`);
|
|
2699
3501
|
previewLines.push(pv.connected
|
|
2700
|
-
? ` ${label("mode")} ${CYAN}◆ CONNECTED${RESET} ${DIM}
|
|
3502
|
+
? ` ${label("mode")} ${CYAN}◆ CONNECTED${RESET} ${DIM}${connectedModeSuffix(selected.path)}${RESET}`
|
|
2701
3503
|
: ` ${label("mode")} ${DIM}◇ LOCAL · Markdown + Git${RESET}`);
|
|
2702
3504
|
if (pv.branch) previewLines.push(` ${label("branch")} ${BOLD}${pv.branch}${RESET}`);
|
|
2703
3505
|
if (pv.lastCommit) previewLines.push(` ${label("last")} ${DIM}${truncate(pv.lastCommit, valW)}${RESET}`);
|
|
@@ -2798,9 +3600,27 @@ async function browser(args = {}) {
|
|
|
2798
3600
|
const onResize = () => render(); // render() itself no-ops once done is set
|
|
2799
3601
|
let onSigint;
|
|
2800
3602
|
let onSigterm;
|
|
3603
|
+
const stopUpgradePoll = () => {
|
|
3604
|
+
if (state.upgradePoll) { clearInterval(state.upgradePoll); state.upgradePoll = null; }
|
|
3605
|
+
};
|
|
3606
|
+
const refreshUpgrade = () => {
|
|
3607
|
+
if (!state.upgradeInst) return;
|
|
3608
|
+
upgradeStatusAsync(state.upgradeInst, (st) => {
|
|
3609
|
+
if (!state.upgradeInst) return;
|
|
3610
|
+
state.upgradeData = st;
|
|
3611
|
+
if (st && st.status === "preparing") {
|
|
3612
|
+
if (!state.upgradePoll) state.upgradePoll = setInterval(refreshUpgrade, 2500);
|
|
3613
|
+
} else {
|
|
3614
|
+
stopUpgradePoll();
|
|
3615
|
+
}
|
|
3616
|
+
render();
|
|
3617
|
+
});
|
|
3618
|
+
};
|
|
3619
|
+
|
|
2801
3620
|
const cleanup = () => {
|
|
2802
3621
|
if (done) return;
|
|
2803
3622
|
done = true;
|
|
3623
|
+
stopUpgradePoll();
|
|
2804
3624
|
process.stdin.setRawMode(false);
|
|
2805
3625
|
process.stdin.pause();
|
|
2806
3626
|
process.stdin.removeAllListeners("keypress");
|
|
@@ -2854,11 +3674,195 @@ async function browser(args = {}) {
|
|
|
2854
3674
|
if (!key) return;
|
|
2855
3675
|
if (isMouseEvent(chunk, key)) return; // drop scroll-wheel / mouse escape sequences
|
|
2856
3676
|
|
|
3677
|
+
if (state.upgradeInst) {
|
|
3678
|
+
if (key.ctrl && key.name === "c") { cleanup(); process.exit(130); }
|
|
3679
|
+
if (key.name === "q") { cleanup(); resolve(); return; }
|
|
3680
|
+
if (state.upgradeMode && state.upgradeMode.startsWith("confirm-")) {
|
|
3681
|
+
const mode = state.upgradeMode;
|
|
3682
|
+
state.upgradeMode = "view";
|
|
3683
|
+
if (chunk === "y" || chunk === "Y") {
|
|
3684
|
+
const inst = state.upgradeInst;
|
|
3685
|
+
if (mode === "confirm-prepare") {
|
|
3686
|
+
const r = runUpgrade(inst, ["prepare"]);
|
|
3687
|
+
state.upgradeNotice = r.status === 0
|
|
3688
|
+
? `${DIM}Preparing in the background — safe to leave this screen.${RESET}`
|
|
3689
|
+
: `${YELLOW}${(r.stderr || "prepare failed").trim().split("\n")[0]}${RESET}`;
|
|
3690
|
+
} else if (mode === "confirm-activate") {
|
|
3691
|
+
const r = runUpgrade(inst, ["activate"]);
|
|
3692
|
+
state.upgradeNotice = r.status === 0
|
|
3693
|
+
? `${GREEN}Update complete. Start a session to work on the new Runtime.${RESET}`
|
|
3694
|
+
: `${YELLOW}${(r.stderr || "activation refused — a gate has not passed").trim().split("\n")[0]}${RESET}`;
|
|
3695
|
+
} else if (mode === "confirm-rollback") {
|
|
3696
|
+
const r = runUpgrade(inst, ["rollback"]);
|
|
3697
|
+
state.upgradeNotice = r.status === 0
|
|
3698
|
+
? `${DIM}Rolled back. The previous Runtime is active again.${RESET}`
|
|
3699
|
+
: `${YELLOW}${(r.stderr || "rollback failed").trim().split("\n")[0]}${RESET}`;
|
|
3700
|
+
} else if (mode === "confirm-cancel") {
|
|
3701
|
+
runUpgrade(inst, ["cancel"]);
|
|
3702
|
+
state.upgradeNotice = `${DIM}Preparation cancelled. The current Runtime was never touched.${RESET}`;
|
|
3703
|
+
}
|
|
3704
|
+
refreshUpgrade();
|
|
3705
|
+
}
|
|
3706
|
+
render(); return;
|
|
3707
|
+
}
|
|
3708
|
+
if (key.name === "escape" || key.name === "left") {
|
|
3709
|
+
stopUpgradePoll();
|
|
3710
|
+
state.settingsUpgrade = state.upgradeData;
|
|
3711
|
+
state.upgradeInst = null; state.upgradeNotice = "";
|
|
3712
|
+
render(); return;
|
|
3713
|
+
}
|
|
3714
|
+
const status = state.upgradeData && state.upgradeData.status;
|
|
3715
|
+
if (chunk === "p" && (!status || ["none", "pending", "failed", "interrupted", "cancelled", "rolled-back"].includes(status))) {
|
|
3716
|
+
const staged = state.upgradeData
|
|
3717
|
+
&& !["none", "cancelled", "rolled-back"].includes(status)
|
|
3718
|
+
&& state.upgradeData.candidate_version;
|
|
3719
|
+
if (!staged) {
|
|
3720
|
+
state.upgradeNotice = `${DIM}Stage a candidate package first: egregore settings ${state.upgradeInst.slug} runtime init <version> <candidate.tgz>${RESET}`;
|
|
3721
|
+
render(); return;
|
|
3722
|
+
}
|
|
3723
|
+
state.upgradeMode = "confirm-prepare"; render(); return;
|
|
3724
|
+
}
|
|
3725
|
+
if (chunk === "a" && status === "ready-to-activate") { state.upgradeMode = "confirm-activate"; render(); return; }
|
|
3726
|
+
if (chunk === "c" && status === "preparing") { state.upgradeMode = "confirm-cancel"; render(); return; }
|
|
3727
|
+
if (chunk === "r" && status === "active") { state.upgradeMode = "confirm-rollback"; render(); return; }
|
|
3728
|
+
return;
|
|
3729
|
+
}
|
|
3730
|
+
|
|
2857
3731
|
if (state.settingsInst) {
|
|
2858
3732
|
const S = state;
|
|
2859
3733
|
if (key.ctrl && key.name === "c") { cleanup(); process.exit(130); }
|
|
2860
3734
|
if (key.name === "q") { cleanup(); resolve(); return; }
|
|
2861
3735
|
|
|
3736
|
+
if (S.settingsView === "privacy" || S.settingsView === "telemetry") {
|
|
3737
|
+
const backToMenu = () => {
|
|
3738
|
+
S.settingsView = "menu"; S.settingsMode = "browse"; S.settingsInput = ""; S.settingsNotice = ""; render();
|
|
3739
|
+
};
|
|
3740
|
+
const refreshPanel = () => {
|
|
3741
|
+
if (S.settingsView === "privacy") S.settingsData = { ...(S.settingsData || {}), privacySnapshot: privacySnapshot(S.settingsInst) };
|
|
3742
|
+
else S.settingsData = { ...(S.settingsData || {}), telemetrySnapshot: telemetrySnapshot(S.settingsInst) };
|
|
3743
|
+
};
|
|
3744
|
+
if (S.settingsMode === "events") {
|
|
3745
|
+
const events = (S.settingsData && S.settingsData.telemetryEvents) || [];
|
|
3746
|
+
if (key.name === "escape" || key.name === "left") { S.settingsMode = "browse"; S.settingsListCursor = 0; S.settingsNotice = ""; render(); return; }
|
|
3747
|
+
if (key.name === "up" || key.name === "k") { S.settingsListCursor = Math.max(0, (S.settingsListCursor || 0) - 1); render(); return; }
|
|
3748
|
+
if (key.name === "down" || key.name === "j") { S.settingsListCursor = Math.min(Math.max(0, events.length - 1), (S.settingsListCursor || 0) + 1); render(); return; }
|
|
3749
|
+
if (chunk === "e") {
|
|
3750
|
+
const stamp = new Date().toISOString().slice(0, 10);
|
|
3751
|
+
S.settingsPendingDir = path.join(os.homedir(), "Desktop", `egregore-telemetry-${S.settingsInst.slug}-${stamp}.jsonl`);
|
|
3752
|
+
S.settingsAction = "tele-export";
|
|
3753
|
+
S.settingsMode = "confirm";
|
|
3754
|
+
S.settingsInput = `Export ${events.length} local event(s) to ${S.settingsPendingDir}? [y/N]`;
|
|
3755
|
+
render(); return;
|
|
3756
|
+
}
|
|
3757
|
+
if (chunk === "s") {
|
|
3758
|
+
const r = runTelemetry(S.settingsInst, ["share"]);
|
|
3759
|
+
const shareLines = ((r && (r.stdout || r.stderr)) || "share preview unavailable").split("\n").filter(Boolean);
|
|
3760
|
+
S.settingsData = { ...(S.settingsData || {}), shareLines };
|
|
3761
|
+
S.settingsMode = "shareinfo"; S.settingsNotice = "";
|
|
3762
|
+
render(); return;
|
|
3763
|
+
}
|
|
3764
|
+
return;
|
|
3765
|
+
}
|
|
3766
|
+
if (S.settingsMode === "shareinfo") {
|
|
3767
|
+
if (key.name === "escape" || key.name === "left") { S.settingsMode = "events"; render(); return; }
|
|
3768
|
+
return;
|
|
3769
|
+
}
|
|
3770
|
+
if (S.settingsMode === "pickdir") {
|
|
3771
|
+
const pick = S.settingsData.dirPick;
|
|
3772
|
+
const reload = () => { pick.entries = listSubdirectories(pick.dir, pick.hidden); pick.cursor = Math.min(pick.cursor, Math.max(0, pick.entries.length - 1)); };
|
|
3773
|
+
if (key.name === "escape") { S.settingsMode = "browse"; S.settingsNotice = ""; render(); return; }
|
|
3774
|
+
if (key.name === "up" || key.name === "k") { pick.cursor = Math.max(0, pick.cursor - 1); render(); return; }
|
|
3775
|
+
if (key.name === "down" || key.name === "j") { pick.cursor = Math.min(Math.max(0, pick.entries.length - 1), pick.cursor + 1); render(); return; }
|
|
3776
|
+
if (key.name === "right" || key.name === "return") {
|
|
3777
|
+
if (pick.entries.length) { pick.dir = path.join(pick.dir, pick.entries[pick.cursor]); pick.cursor = 0; reload(); }
|
|
3778
|
+
render(); return;
|
|
3779
|
+
}
|
|
3780
|
+
if (key.name === "left") {
|
|
3781
|
+
const parent = path.dirname(pick.dir);
|
|
3782
|
+
if (parent !== pick.dir) { pick.dir = parent; pick.cursor = 0; reload(); }
|
|
3783
|
+
render(); return;
|
|
3784
|
+
}
|
|
3785
|
+
if (chunk === ".") { pick.hidden = !pick.hidden; reload(); render(); return; }
|
|
3786
|
+
if (chunk === " ") {
|
|
3787
|
+
S.settingsPendingDir = pick.dir;
|
|
3788
|
+
S.settingsAction = "add";
|
|
3789
|
+
S.settingsMode = "confirm";
|
|
3790
|
+
S.settingsInput = `Allow reading ${pick.dir} for this member? [y/N]`;
|
|
3791
|
+
render(); return;
|
|
3792
|
+
}
|
|
3793
|
+
return;
|
|
3794
|
+
}
|
|
3795
|
+
if (S.settingsMode === "pickroot") {
|
|
3796
|
+
const roots = (S.settingsData.privacySnapshot && S.settingsData.privacySnapshot.boundary && S.settingsData.privacySnapshot.boundary.personal_read_roots) || [];
|
|
3797
|
+
if (key.name === "escape" || key.name === "left") { S.settingsMode = "browse"; S.settingsListCursor = 0; render(); return; }
|
|
3798
|
+
if (key.name === "up" || key.name === "k") { S.settingsListCursor = Math.max(0, (S.settingsListCursor || 0) - 1); render(); return; }
|
|
3799
|
+
if (key.name === "down" || key.name === "j") { S.settingsListCursor = Math.min(Math.max(0, roots.length - 1), (S.settingsListCursor || 0) + 1); render(); return; }
|
|
3800
|
+
if (key.name === "return" && roots.length) {
|
|
3801
|
+
S.settingsPendingDir = roots[Math.min(S.settingsListCursor || 0, roots.length - 1)];
|
|
3802
|
+
S.settingsAction = "remove";
|
|
3803
|
+
S.settingsMode = "confirm";
|
|
3804
|
+
S.settingsInput = `Stop allowing reads of ${S.settingsPendingDir}? [y/N]`;
|
|
3805
|
+
render(); return;
|
|
3806
|
+
}
|
|
3807
|
+
return;
|
|
3808
|
+
}
|
|
3809
|
+
if (S.settingsMode === "confirm") {
|
|
3810
|
+
if (chunk === "y" || chunk === "Y") {
|
|
3811
|
+
let r = null;
|
|
3812
|
+
if (S.settingsAction === "add" || S.settingsAction === "remove") {
|
|
3813
|
+
r = runSettings(S.settingsInst, ["boundary", S.settingsAction, S.settingsPendingDir]);
|
|
3814
|
+
} else if (S.settingsAction === "tele-export") {
|
|
3815
|
+
r = runTelemetry(S.settingsInst, ["export", S.settingsPendingDir]);
|
|
3816
|
+
} else if (S.settingsAction === "tele-on") {
|
|
3817
|
+
r = runTelemetry(S.settingsInst, ["on"]);
|
|
3818
|
+
} else if (S.settingsAction === "tele-off") {
|
|
3819
|
+
r = runTelemetry(S.settingsInst, ["off"]);
|
|
3820
|
+
} else if (S.settingsAction === "tele-clear") {
|
|
3821
|
+
r = runTelemetry(S.settingsInst, ["clear"]);
|
|
3822
|
+
}
|
|
3823
|
+
S.settingsNotice = r && r.status === 0
|
|
3824
|
+
? `${GREEN}done${RESET}`
|
|
3825
|
+
: `${YELLOW}${((r && (r.stderr || r.stdout)) || "action failed").split("\n")[0]}${RESET}`;
|
|
3826
|
+
S.settingsMode = "browse"; S.settingsInput = ""; S.settingsPendingDir = "";
|
|
3827
|
+
refreshPanel(); render(); return;
|
|
3828
|
+
}
|
|
3829
|
+
S.settingsMode = "browse"; S.settingsInput = ""; S.settingsPendingDir = ""; S.settingsNotice = ""; render(); return;
|
|
3830
|
+
}
|
|
3831
|
+
if (key.name === "escape" || key.name === "left") { backToMenu(); return; }
|
|
3832
|
+
if (S.settingsView === "privacy") {
|
|
3833
|
+
const locked = !!(S.settingsData && S.settingsData.privacySnapshot && S.settingsData.privacySnapshot.boundary && S.settingsData.privacySnapshot.boundary.locked);
|
|
3834
|
+
if (!locked && chunk === "a") {
|
|
3835
|
+
const dir = os.homedir();
|
|
3836
|
+
S.settingsData = { ...(S.settingsData || {}), dirPick: { dir, entries: listSubdirectories(dir, false), cursor: 0, hidden: false } };
|
|
3837
|
+
S.settingsMode = "pickdir"; S.settingsNotice = ""; render(); return;
|
|
3838
|
+
}
|
|
3839
|
+
if (!locked && chunk === "r") {
|
|
3840
|
+
S.settingsMode = "pickroot"; S.settingsListCursor = 0; S.settingsNotice = ""; render(); return;
|
|
3841
|
+
}
|
|
3842
|
+
return;
|
|
3843
|
+
}
|
|
3844
|
+
// telemetry view
|
|
3845
|
+
if (chunk === "i") {
|
|
3846
|
+
S.settingsData = { ...(S.settingsData || {}), telemetryEvents: telemetryEvents(S.settingsInst, 100) };
|
|
3847
|
+
S.settingsMode = "events"; S.settingsListCursor = 0; S.settingsNotice = ""; render(); return;
|
|
3848
|
+
}
|
|
3849
|
+
if (chunk === "t") {
|
|
3850
|
+
const on = !!(S.settingsData && S.settingsData.telemetrySnapshot && S.settingsData.telemetrySnapshot.enabled);
|
|
3851
|
+
S.settingsAction = on ? "tele-off" : "tele-on";
|
|
3852
|
+
S.settingsMode = "confirm";
|
|
3853
|
+
S.settingsInput = `Turn telemetry ${on ? "off" : "on"} for this member only? [y/N]`;
|
|
3854
|
+
render(); return;
|
|
3855
|
+
}
|
|
3856
|
+
if (chunk === "x") {
|
|
3857
|
+
const count = (S.settingsData && S.settingsData.telemetrySnapshot && S.settingsData.telemetrySnapshot.buffered_events) || 0;
|
|
3858
|
+
S.settingsAction = "tele-clear";
|
|
3859
|
+
S.settingsMode = "confirm";
|
|
3860
|
+
S.settingsInput = `Delete ${count} locally buffered telemetry event(s)? Nothing else is removed. [y/N]`;
|
|
3861
|
+
render(); return;
|
|
3862
|
+
}
|
|
3863
|
+
return;
|
|
3864
|
+
}
|
|
3865
|
+
|
|
2862
3866
|
if (S.settingsView === "list") {
|
|
2863
3867
|
if (S.settingsMode === "add") {
|
|
2864
3868
|
if (key.name === "escape") { S.settingsMode = "browse"; S.settingsInput = ""; render(); return; }
|
|
@@ -2891,15 +3895,40 @@ async function browser(args = {}) {
|
|
|
2891
3895
|
|
|
2892
3896
|
// menu view
|
|
2893
3897
|
if (key.name === "escape" || key.name === "left") { S.settingsInst = null; S.settingsNotice = ""; render(); return; }
|
|
2894
|
-
if (key.name === "up" || key.name === "k") { S.settingsCursor = (S.settingsCursor - 1 +
|
|
2895
|
-
if (key.name === "down" || key.name === "j") { S.settingsCursor = (S.settingsCursor + 1) %
|
|
3898
|
+
if (key.name === "up" || key.name === "k") { S.settingsCursor = (S.settingsCursor - 1 + 8) % 8; render(); return; }
|
|
3899
|
+
if (key.name === "down" || key.name === "j") { S.settingsCursor = (S.settingsCursor + 1) % 8; render(); return; }
|
|
2896
3900
|
if (key.name === "return" || chunk === " ") {
|
|
2897
3901
|
if (S.settingsCursor === 0) {
|
|
3902
|
+
state.upgradeInst = S.settingsInst;
|
|
3903
|
+
state.upgradeData = S.settingsUpgrade;
|
|
3904
|
+
state.upgradeMode = "view";
|
|
3905
|
+
state.upgradeNotice = "";
|
|
3906
|
+
refreshUpgrade();
|
|
3907
|
+
if (!state.upgradeCandidate) {
|
|
3908
|
+
fetchRuntimeMvpCandidate().then((v) => {
|
|
3909
|
+
state.upgradeCandidate = v || "";
|
|
3910
|
+
if (state.upgradeInst) render();
|
|
3911
|
+
});
|
|
3912
|
+
}
|
|
3913
|
+
render();
|
|
3914
|
+
} else if (S.settingsCursor === 1) {
|
|
3915
|
+
S.settingsView = "privacy"; S.settingsMode = "browse"; S.settingsInput = ""; S.settingsNotice = "";
|
|
3916
|
+
S.settingsData = { ...(S.settingsData || {}), privacySnapshot: privacySnapshot(S.settingsInst) };
|
|
3917
|
+
render();
|
|
3918
|
+
} else if (S.settingsCursor === 2) {
|
|
3919
|
+
S.settingsView = "telemetry"; S.settingsMode = "browse"; S.settingsInput = ""; S.settingsNotice = "";
|
|
3920
|
+
S.settingsData = { ...(S.settingsData || {}), telemetrySnapshot: telemetrySnapshot(S.settingsInst) };
|
|
3921
|
+
render();
|
|
3922
|
+
} else if (S.settingsCursor === 3) {
|
|
2898
3923
|
const on = (S.settingsData && S.settingsData.hosting) !== false;
|
|
2899
3924
|
settingsRunVerb(["hosting", on ? "off" : "on"]);
|
|
2900
3925
|
render();
|
|
3926
|
+
} else if (S.settingsCursor === 4) {
|
|
3927
|
+
const simple = (S.settingsData && S.settingsData.workflow) === "simple";
|
|
3928
|
+
settingsRunVerb(["workflow", simple ? "staged" : "simple"]);
|
|
3929
|
+
render();
|
|
2901
3930
|
} else {
|
|
2902
|
-
const domain = S.settingsCursor ===
|
|
3931
|
+
const domain = S.settingsCursor === 5 ? "repo" : S.settingsCursor === 6 ? "admin" : "people";
|
|
2903
3932
|
S.settingsView = "list"; S.settingsDomain = domain;
|
|
2904
3933
|
S.settingsItems = settingsItemsFor(S.settingsData, domain);
|
|
2905
3934
|
S.settingsListCursor = 0; S.settingsMode = "browse"; S.settingsNotice = "";
|
|
@@ -3155,9 +4184,14 @@ async function browser(args = {}) {
|
|
|
3155
4184
|
return;
|
|
3156
4185
|
}
|
|
3157
4186
|
state.settingsInst = pick;
|
|
3158
|
-
state.settingsData = settingsDump(pick) || { hosting: true, repos: [], admins: [], people: [] };
|
|
4187
|
+
state.settingsData = settingsDump(pick) || { hosting: true, workflow: "staged", base_branch: "develop", repos: [], admins: [], people: [] };
|
|
3159
4188
|
state.settingsCursor = 0;
|
|
3160
4189
|
state.settingsView = "menu";
|
|
4190
|
+
state.settingsUpgrade = undefined;
|
|
4191
|
+
upgradeStatusAsync(pick, (st) => {
|
|
4192
|
+
state.settingsUpgrade = st;
|
|
4193
|
+
if (state.settingsInst === pick && !state.upgradeInst) render();
|
|
4194
|
+
});
|
|
3161
4195
|
state.settingsNotice = "";
|
|
3162
4196
|
render();
|
|
3163
4197
|
return;
|
|
@@ -3285,6 +4319,8 @@ function main() {
|
|
|
3285
4319
|
if (cmd === "ls" || cmd === "list") return cmdLs();
|
|
3286
4320
|
if (cmd === "use") return cmdUse(args[1]);
|
|
3287
4321
|
if (cmd === "connect") return cmdConnect(args.slice(1));
|
|
4322
|
+
if (cmd === "telemetry") return cmdTelemetry(args.slice(1));
|
|
4323
|
+
if (cmd === "runtime") return cmdRuntime(args.slice(1));
|
|
3288
4324
|
if (cmd === "/invite" || cmd === "invite") return cmdInvite(args.slice(1));
|
|
3289
4325
|
if (cmd === "settings" || cmd === "config") return cmdSettings(args.slice(1));
|
|
3290
4326
|
if (cmd === "prune") return cmdPruneNonInteractive(args[1] === "--dry-run" || args[1] === "-n");
|
|
@@ -3295,6 +4331,8 @@ function main() {
|
|
|
3295
4331
|
if (cmd.startsWith("-")) die(`unknown flag: ${cmd}\n run: egregore help`);
|
|
3296
4332
|
|
|
3297
4333
|
const registry = readRegistry();
|
|
4334
|
+
const worktree = currentWorktreeInstance(registry);
|
|
4335
|
+
if (!cmd && worktree) return launch(worktree, runtimeOverride);
|
|
3298
4336
|
if (registry.length === 0) {
|
|
3299
4337
|
if (canPrompt()) return setupNewEgregore(runtimeOverride);
|
|
3300
4338
|
die("no egregores installed yet.\n run: npx -y create-egregore@latest");
|