create-egregore 0.20.2 → 0.21.0-runtime-mvp.2
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 +1013 -16
- package/bin/cli.js +11 -0
- package/lib/claude-runtime.js +192 -0
- package/lib/local.js +38 -31
- 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 -17
- 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 +9 -9
- package/runtime/codex/AGENTS.md +62 -58
- package/runtime/codex/bin/activity-action.sh +92 -0
- package/runtime/codex/bin/activity-data.sh +12 -233
- package/runtime/codex/bin/agent.sh +84 -100
- 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 +41 -16
- package/runtime/codex/bin/codex-session-start.sh +14 -4
- package/runtime/codex/bin/codex-skill-render.mjs +9 -7
- 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/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 +70 -6
- package/runtime/codex/bin/lib/greeting.sh +34 -5
- 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 +231 -195
- package/runtime/codex/bin/settings.sh +174 -5
- 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 +19 -5
- 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 +98 -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 +9 -9
- package/runtime/pi/.pi/APPEND_SYSTEM.md +57 -48
- package/runtime/pi/.pi/extensions/egregore.ts +7 -0
- package/runtime/pi/.pi/spec-manifest.json +2 -2
- package/runtime/pi/AGENTS.md +62 -58
- package/runtime/pi/bin/activity-action.sh +92 -0
- package/runtime/pi/bin/activity-data.sh +12 -233
- package/runtime/pi/bin/agent.sh +84 -100
- 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 +41 -16
- package/runtime/pi/bin/codex-session-start.sh +14 -4
- package/runtime/pi/bin/codex-skill-render.mjs +9 -7
- 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/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 +70 -6
- package/runtime/pi/bin/lib/greeting.sh +34 -5
- 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 +231 -195
- package/runtime/pi/bin/settings.sh +174 -5
- 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 +19 -5
- 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 +98 -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 +9 -9
- package/runtime/prime/.prime/agent/APPEND_SYSTEM.md +57 -48
- 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 +62 -58
- package/runtime/prime/bin/activity-action.sh +92 -0
- package/runtime/prime/bin/activity-data.sh +12 -233
- package/runtime/prime/bin/agent.sh +84 -100
- 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 +41 -16
- package/runtime/prime/bin/codex-session-start.sh +14 -4
- package/runtime/prime/bin/codex-skill-render.mjs +9 -7
- 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/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 +70 -6
- package/runtime/prime/bin/lib/greeting.sh +34 -5
- 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 +1 -1
- 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 +231 -195
- package/runtime/prime/bin/settings.sh +174 -5
- 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 +19 -5
- 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 +98 -1
|
@@ -0,0 +1,696 @@
|
|
|
1
|
+
#!/usr/bin/env bash
|
|
2
|
+
set -o pipefail
|
|
3
|
+
|
|
4
|
+
# Framework version — bumped on greeting/startup changes.
|
|
5
|
+
# Used for drift detection across team members.
|
|
6
|
+
FRAMEWORK_VERSION="7"
|
|
7
|
+
|
|
8
|
+
SCRIPT_DIR="$(cd "$(dirname "$0")/.." && pwd)"
|
|
9
|
+
cd "$SCRIPT_DIR"
|
|
10
|
+
|
|
11
|
+
# --- Transient development-checkout detection ---
|
|
12
|
+
# Git worktrees have .git as a FILE. The launcher also marks standalone
|
|
13
|
+
# development clones as transient so startup preserves their feature branch
|
|
14
|
+
# and never registers them as a second Egregore instance.
|
|
15
|
+
IS_WORKTREE="false"
|
|
16
|
+
MAIN_PROJECT_DIR="$SCRIPT_DIR"
|
|
17
|
+
if [ -f "$SCRIPT_DIR/.git" ]; then
|
|
18
|
+
IS_WORKTREE="true"
|
|
19
|
+
WT_GITDIR=$(sed 's/^gitdir: //' "$SCRIPT_DIR/.git" 2>/dev/null)
|
|
20
|
+
MAIN_PROJECT_DIR=$(cd "$WT_GITDIR/../../.." 2>/dev/null && pwd)
|
|
21
|
+
elif [ "${EGREGORE_TRANSIENT_CHECKOUT:-0}" = "1" ]; then
|
|
22
|
+
IS_WORKTREE="true"
|
|
23
|
+
fi
|
|
24
|
+
|
|
25
|
+
# Defensive net: re-link worktree shared state (symlinks to the main checkout's
|
|
26
|
+
# memory/, .env, state files). worktree-create.sh links at creation; this heals
|
|
27
|
+
# links that were removed or broke since.
|
|
28
|
+
if [ -f "$SCRIPT_DIR/bin/lib/worktree-links.sh" ]; then
|
|
29
|
+
source "$SCRIPT_DIR/bin/lib/worktree-links.sh" >/dev/null 2>/dev/null || true
|
|
30
|
+
egregore_link_shared_state "$SCRIPT_DIR" "$MAIN_PROJECT_DIR" >/dev/null 2>/dev/null || true
|
|
31
|
+
fi
|
|
32
|
+
|
|
33
|
+
# Clear any branch-guard consent from a previous session — consent to write on
|
|
34
|
+
# a protected branch is asked fresh each session (see CLAUDE.md branch-guard protocol).
|
|
35
|
+
rm -f "$SCRIPT_DIR/.egregore-branch-consent" "$MAIN_PROJECT_DIR/.egregore-branch-consent" 2>/dev/null
|
|
36
|
+
# Same for boundary-crossing consent — grants are session-scoped (CLAUDE.md
|
|
37
|
+
# environment-isolation protocol); durable grants belong in .egregore-boundary.local.json.
|
|
38
|
+
rm -f "$SCRIPT_DIR/.egregore-boundary-consent" "$MAIN_PROJECT_DIR/.egregore-boundary-consent" 2>/dev/null
|
|
39
|
+
|
|
40
|
+
# --- Health tracking (rendered as dots in greeting) ---
|
|
41
|
+
HEALTH_GITHUB="skip"
|
|
42
|
+
HEALTH_GIT="skip"
|
|
43
|
+
HEALTH_APIKEY="skip"
|
|
44
|
+
HEALTH_GRAPH="skip"
|
|
45
|
+
HEALTH_TELEGRAM="skip"
|
|
46
|
+
|
|
47
|
+
# --- Config ---
|
|
48
|
+
STATE_FILE="$SCRIPT_DIR/.egregore-state.json"
|
|
49
|
+
ENV_FILE="$SCRIPT_DIR/.env"
|
|
50
|
+
CONFIG="$SCRIPT_DIR/egregore.json"
|
|
51
|
+
DATE=$(date +%Y-%m-%d)
|
|
52
|
+
|
|
53
|
+
# --- Source shared libs ---
|
|
54
|
+
source "$SCRIPT_DIR/bin/lib/config.sh"
|
|
55
|
+
source "$SCRIPT_DIR/bin/lib/hash.sh"
|
|
56
|
+
source "$SCRIPT_DIR/bin/lib/time.sh"
|
|
57
|
+
|
|
58
|
+
# Opt-in monotonic phase tracing (EGREGORE_STARTUP_TRACE=1); traces land in
|
|
59
|
+
# ~/.egregore/runtime/startup-traces, normal output is untouched.
|
|
60
|
+
source "$SCRIPT_DIR/bin/lib/trace.sh" 2>/dev/null || true
|
|
61
|
+
egregore_trace_begin "session-start" 2>/dev/null || true
|
|
62
|
+
egregore_trace_mark "libs-loaded" 2>/dev/null || true
|
|
63
|
+
|
|
64
|
+
# ============================================================
|
|
65
|
+
# 1. Resolve identity
|
|
66
|
+
# ============================================================
|
|
67
|
+
source "$SCRIPT_DIR/bin/lib/identity.sh"
|
|
68
|
+
egregore_trace_mark "identity" 2>/dev/null || true
|
|
69
|
+
|
|
70
|
+
# ============================================================
|
|
71
|
+
# 2. Ensure the base branch exists (needed before onboarding creates working branches)
|
|
72
|
+
# ============================================================
|
|
73
|
+
# BASE_BRANCH is "develop" unless egregore.json sets base_branch. With
|
|
74
|
+
# base_branch: "main" this whole block is a no-op — main already exists locally
|
|
75
|
+
# and on the remote — which is the point: single-branch instances never get a
|
|
76
|
+
# second branch created, and never get one pushed to their remote.
|
|
77
|
+
if ! BASE_BRANCH=$(_get_base_branch); then
|
|
78
|
+
echo "ERROR: Could not resolve the configured base branch; startup stopped before branch changes." >&2
|
|
79
|
+
exit 1
|
|
80
|
+
fi
|
|
81
|
+
if ! git show-ref --verify --quiet "refs/heads/$BASE_BRANCH" 2>/dev/null; then
|
|
82
|
+
if git show-ref --verify --quiet "refs/remotes/origin/$BASE_BRANCH" 2>/dev/null; then
|
|
83
|
+
git checkout -b "$BASE_BRANCH" "origin/$BASE_BRANCH" --quiet 2>/dev/null
|
|
84
|
+
git checkout - --quiet 2>/dev/null
|
|
85
|
+
else
|
|
86
|
+
git branch "$BASE_BRANCH" --quiet 2>/dev/null
|
|
87
|
+
# Double-fork: detached from the job table so later `wait`s don't block on
|
|
88
|
+
# it. stdout must be redirected too — a detached child inheriting the
|
|
89
|
+
# hook's stdout pipe keeps it open and the harness waits on it anyway.
|
|
90
|
+
( git push -u origin "$BASE_BRANCH" --quiet >/dev/null 2>&1 & ) 2>/dev/null
|
|
91
|
+
fi
|
|
92
|
+
fi
|
|
93
|
+
|
|
94
|
+
# Managed repos are fetched (in parallel) and their base branches ensured by
|
|
95
|
+
# git-sync.sh below. A previous version also fetched them here sequentially in
|
|
96
|
+
# a background subshell — git-sync's `wait` then blocked on that subshell,
|
|
97
|
+
# adding ~2s per repo of duplicate network time to every boot.
|
|
98
|
+
|
|
99
|
+
# ============================================================
|
|
100
|
+
# 3. Check onboarding state
|
|
101
|
+
# ============================================================
|
|
102
|
+
ONBOARDING_COMPLETE="true"
|
|
103
|
+
if [ -f "$STATE_FILE" ]; then
|
|
104
|
+
ONBOARDING_COMPLETE=$(jq -r '.onboarding_complete // false' "$STATE_FILE" 2>/dev/null || echo "true")
|
|
105
|
+
fi
|
|
106
|
+
|
|
107
|
+
# Self-heal: state says incomplete but a completion witness exists →
|
|
108
|
+
# onboarding finished, the state write was lost. See SKILL.md "Completion witness".
|
|
109
|
+
# Three witnesses, in order of strength:
|
|
110
|
+
# 1. `^Onboarded:` in person file — explicit, written by new flow's step 1
|
|
111
|
+
# 2. `^# ` H1 in person file — back-compat, matches any pre-PR-544 person
|
|
112
|
+
# file (real onboardings always start with a markdown header). Excludes
|
|
113
|
+
# invite stubs which use `---` YAML frontmatter.
|
|
114
|
+
# 3. `### {display_name}` under egregore.md `## Members` — fallback for
|
|
115
|
+
# cases where the person file is missing/corrupted but Members has them.
|
|
116
|
+
if [ "$ONBOARDING_COMPLETE" != "true" ] && [ -n "$AUTHOR" ]; then
|
|
117
|
+
PEOPLE_FILE="$SCRIPT_DIR/memory/people/${AUTHOR}.md"
|
|
118
|
+
WITNESSED="false"
|
|
119
|
+
if [ -f "$PEOPLE_FILE" ]; then
|
|
120
|
+
if grep -q '^Onboarded:' "$PEOPLE_FILE" 2>/dev/null; then
|
|
121
|
+
WITNESSED="true"
|
|
122
|
+
elif head -1 "$PEOPLE_FILE" 2>/dev/null | grep -q '^# '; then
|
|
123
|
+
WITNESSED="true"
|
|
124
|
+
fi
|
|
125
|
+
fi
|
|
126
|
+
if [ "$WITNESSED" != "true" ] && [ -n "$DISPLAY_NAME_STATE" ] && [ -f "$SCRIPT_DIR/egregore.md" ]; then
|
|
127
|
+
sed -n '/^## Members/,/^## /p' "$SCRIPT_DIR/egregore.md" 2>/dev/null \
|
|
128
|
+
| grep -qx "### ${DISPLAY_NAME_STATE}" && WITNESSED="true"
|
|
129
|
+
fi
|
|
130
|
+
if [ "$WITNESSED" = "true" ] && [ -f "$STATE_FILE" ]; then
|
|
131
|
+
jq '.onboarding_complete = true | .onboarding.phase = "complete"' "$STATE_FILE" > "$STATE_FILE.tmp" \
|
|
132
|
+
&& mv "$STATE_FILE.tmp" "$STATE_FILE"
|
|
133
|
+
ONBOARDING_COMPLETE="true"
|
|
134
|
+
fi
|
|
135
|
+
fi
|
|
136
|
+
|
|
137
|
+
if [ "$ONBOARDING_COMPLETE" != "true" ]; then
|
|
138
|
+
# Output as a single compact line — Claude reads it, user doesn't need to see it
|
|
139
|
+
echo "onboarding_needed author=$AUTHOR"
|
|
140
|
+
exit 0
|
|
141
|
+
fi
|
|
142
|
+
|
|
143
|
+
# ============================================================
|
|
144
|
+
# 3. Detect mode + provision API key
|
|
145
|
+
# ============================================================
|
|
146
|
+
LOCAL_MODE="false"
|
|
147
|
+
[ "$(_detect_mode)" = "local" ] && LOCAL_MODE="true"
|
|
148
|
+
|
|
149
|
+
# In local mode, skip all key validation and auto-fix
|
|
150
|
+
KEY_NEEDS_FIX="false"
|
|
151
|
+
HEALTH_APIKEY="skip"
|
|
152
|
+
|
|
153
|
+
if [ "$LOCAL_MODE" != "true" ]; then
|
|
154
|
+
# A key needs fixing only when it's missing or the API rejects it (401/403).
|
|
155
|
+
# A slug mismatch alone is NOT failure: after an org rename the old-slug key
|
|
156
|
+
# can be the only key bound to the org's data — replacing it silently empties
|
|
157
|
+
# every graph read. Slug match is just the no-network fast path.
|
|
158
|
+
if [ -f "$ENV_FILE" ]; then
|
|
159
|
+
CURRENT_KEY=$(grep '^EGREGORE_API_KEY=' "$ENV_FILE" 2>/dev/null | cut -d'=' -f2-)
|
|
160
|
+
EXPECTED_SLUG=$(jq -r '.slug // empty' "$CONFIG" 2>/dev/null)
|
|
161
|
+
if [ -z "$CURRENT_KEY" ]; then
|
|
162
|
+
KEY_NEEDS_FIX="true"
|
|
163
|
+
HEALTH_APIKEY="fail"
|
|
164
|
+
else
|
|
165
|
+
# Extract slug from key: ek_<slug>_<secret> → <slug>
|
|
166
|
+
KEY_SLUG=$(echo "$CURRENT_KEY" | cut -d'_' -f2)
|
|
167
|
+
if [ -n "$EXPECTED_SLUG" ] && [ "$KEY_SLUG" != "$EXPECTED_SLUG" ] \
|
|
168
|
+
&& _graph_projection_enabled; then
|
|
169
|
+
# Slug differs from config — ask the API whether the key actually works
|
|
170
|
+
PROBE_URL=$(jq -r '.api_url // empty' "$CONFIG" 2>/dev/null)
|
|
171
|
+
PROBE_CODE="000"
|
|
172
|
+
if [ -n "$PROBE_URL" ]; then
|
|
173
|
+
PROBE_CODE=$(curl -s -o /dev/null -w '%{http_code}' \
|
|
174
|
+
-H "Authorization: Bearer $CURRENT_KEY" \
|
|
175
|
+
"${PROBE_URL}/api/graph/test" \
|
|
176
|
+
--connect-timeout 3 --max-time 5 2>/dev/null || echo "000")
|
|
177
|
+
fi
|
|
178
|
+
case "$PROBE_CODE" in
|
|
179
|
+
401|403)
|
|
180
|
+
KEY_NEEDS_FIX="true"
|
|
181
|
+
HEALTH_APIKEY="fail"
|
|
182
|
+
;;
|
|
183
|
+
*)
|
|
184
|
+
# 200: valid key under a legacy slug — keep it.
|
|
185
|
+
# Anything else: network/API down — never replace a key on a blip;
|
|
186
|
+
# the graph health check surfaces outages separately.
|
|
187
|
+
HEALTH_APIKEY="ok"
|
|
188
|
+
;;
|
|
189
|
+
esac
|
|
190
|
+
else
|
|
191
|
+
HEALTH_APIKEY="ok"
|
|
192
|
+
fi
|
|
193
|
+
fi
|
|
194
|
+
else
|
|
195
|
+
HEALTH_APIKEY="fail"
|
|
196
|
+
fi
|
|
197
|
+
fi
|
|
198
|
+
|
|
199
|
+
if [ "$KEY_NEEDS_FIX" = "true" ]; then
|
|
200
|
+
# Plain background job, NOT double-forked: git-sync's `wait` must join this
|
|
201
|
+
# before the graph bootstrap runs — a repaired key that lands after boot
|
|
202
|
+
# means that launch already skipped auto-capture with no WAL entry to
|
|
203
|
+
# recover the Session. The join costs nothing on healthy boots (the key is
|
|
204
|
+
# fine, this block never runs) and bounds broken-key boots at curl's 10s cap.
|
|
205
|
+
(
|
|
206
|
+
GITHUB_TOKEN=$(grep '^GITHUB_TOKEN=' "$ENV_FILE" 2>/dev/null | cut -d'=' -f2-)
|
|
207
|
+
API_URL=$(jq -r '.api_url // empty' "$CONFIG" 2>/dev/null)
|
|
208
|
+
GITHUB_ORG=$(jq -r '.github_org // empty' "$CONFIG" 2>/dev/null)
|
|
209
|
+
|
|
210
|
+
if [ -n "$GITHUB_TOKEN" ] && [ -n "$API_URL" ] && [ -n "$GITHUB_ORG" ]; then
|
|
211
|
+
SLUG=$(jq -r '.slug // empty' "$CONFIG" 2>/dev/null)
|
|
212
|
+
if [ -z "$SLUG" ]; then
|
|
213
|
+
# No slug in egregore.json — cannot safely derive one. Skip key fix.
|
|
214
|
+
exit 0
|
|
215
|
+
fi
|
|
216
|
+
KEY_RESPONSE=$(curl -s -X GET "${API_URL}/api/org/${SLUG}/key" \
|
|
217
|
+
-H "Authorization: Bearer $GITHUB_TOKEN" \
|
|
218
|
+
--connect-timeout 5 --max-time 10 2>/dev/null || echo "")
|
|
219
|
+
|
|
220
|
+
if [ -n "$KEY_RESPONSE" ]; then
|
|
221
|
+
FETCHED_KEY=$(echo "$KEY_RESPONSE" | jq -r '.api_key // empty' 2>/dev/null)
|
|
222
|
+
if [ -n "$FETCHED_KEY" ] && [ "$FETCHED_KEY" != "null" ]; then
|
|
223
|
+
# Safety: verify the fetched key's slug matches what we expected
|
|
224
|
+
FETCHED_SLUG=$(echo "$FETCHED_KEY" | cut -d'_' -f2)
|
|
225
|
+
if [ "$FETCHED_SLUG" = "$SLUG" ]; then
|
|
226
|
+
# Replace existing key or append
|
|
227
|
+
if grep -q '^EGREGORE_API_KEY=' "$ENV_FILE" 2>/dev/null; then
|
|
228
|
+
sed -i.bak "s|^EGREGORE_API_KEY=.*|EGREGORE_API_KEY=$FETCHED_KEY|" "$ENV_FILE"
|
|
229
|
+
rm -f "$ENV_FILE.bak"
|
|
230
|
+
else
|
|
231
|
+
echo "EGREGORE_API_KEY=$FETCHED_KEY" >> "$ENV_FILE"
|
|
232
|
+
fi
|
|
233
|
+
fi
|
|
234
|
+
fi
|
|
235
|
+
fi
|
|
236
|
+
fi
|
|
237
|
+
) >/dev/null 2>&1 &
|
|
238
|
+
fi
|
|
239
|
+
|
|
240
|
+
# ============================================================
|
|
241
|
+
# 4. Instance registry + boundary
|
|
242
|
+
# ============================================================
|
|
243
|
+
|
|
244
|
+
# --- Self-register in instance registry (for pre-registry installs) ---
|
|
245
|
+
# Worktrees should NOT register as separate instances
|
|
246
|
+
# Wrapped in subshell — registration is optional, must not block session start
|
|
247
|
+
if [ "$IS_WORKTREE" = "false" ] && command -v jq &>/dev/null && [ -f "$CONFIG" ]; then
|
|
248
|
+
( (
|
|
249
|
+
REGISTRY_DIR="$HOME/.egregore"
|
|
250
|
+
REGISTRY="$REGISTRY_DIR/instances.json"
|
|
251
|
+
INST_SLUG=$(jq -r '.slug // empty' "$CONFIG")
|
|
252
|
+
if [ -z "$INST_SLUG" ]; then
|
|
253
|
+
# No slug in egregore.json — skip instance registration
|
|
254
|
+
exit 0
|
|
255
|
+
fi
|
|
256
|
+
INST_NAME=$(jq -r '.org_name // empty' "$CONFIG")
|
|
257
|
+
INST_ORG=$(jq -r '.org_id // empty' "$CONFIG")
|
|
258
|
+
|
|
259
|
+
if [ -n "$INST_SLUG" ] && [ -n "$INST_NAME" ]; then
|
|
260
|
+
mkdir -p "$REGISTRY_DIR"
|
|
261
|
+
if [ ! -f "$REGISTRY" ]; then echo "[]" > "$REGISTRY"; fi
|
|
262
|
+
|
|
263
|
+
ALREADY=$(jq --arg p "$SCRIPT_DIR" '[.[] | select(.path == $p)] | length' "$REGISTRY")
|
|
264
|
+
if [ "$ALREADY" = "0" ]; then
|
|
265
|
+
# org_id is the stable identity other sessions use to prove this
|
|
266
|
+
# checkout is same-organization rather than foreign
|
|
267
|
+
ENTRY=$(jq -n --arg s "$INST_SLUG" --arg n "$INST_NAME" --arg p "$SCRIPT_DIR" --arg o "$INST_ORG" \
|
|
268
|
+
'{slug: $s, name: $n, path: $p} + (if $o == "" then {} else {org_id: $o} end)')
|
|
269
|
+
jq --argjson e "$ENTRY" '. + [$e]' "$REGISTRY" > "$REGISTRY.tmp" \
|
|
270
|
+
&& mv "$REGISTRY.tmp" "$REGISTRY"
|
|
271
|
+
elif [ -n "$INST_ORG" ]; then
|
|
272
|
+
# Backward compatibility: patch this checkout's own legacy entry with
|
|
273
|
+
# its org_id so other sessions can prove identity instead of failing
|
|
274
|
+
# closed against it
|
|
275
|
+
jq --arg p "$SCRIPT_DIR" --arg o "$INST_ORG" \
|
|
276
|
+
'map(if .path == $p and ((.org_id // "") == "") then . + {org_id: $o} else . end)' \
|
|
277
|
+
"$REGISTRY" > "$REGISTRY.tmp" \
|
|
278
|
+
&& mv "$REGISTRY.tmp" "$REGISTRY"
|
|
279
|
+
fi
|
|
280
|
+
fi
|
|
281
|
+
) >/dev/null 2>&1 & ) 2>/dev/null || true
|
|
282
|
+
fi
|
|
283
|
+
|
|
284
|
+
# --- Compute session boundary for environment isolation ---
|
|
285
|
+
compute_boundary() {
|
|
286
|
+
local hash
|
|
287
|
+
hash=$(echo -n "$SCRIPT_DIR" | md5 2>/dev/null || echo -n "$SCRIPT_DIR" | md5sum 2>/dev/null | cut -d' ' -f1)
|
|
288
|
+
local boundary_file="/tmp/egregore-boundary-${hash}.json"
|
|
289
|
+
local project_dir="$SCRIPT_DIR"
|
|
290
|
+
|
|
291
|
+
# Resolve memory directory (follow symlink)
|
|
292
|
+
local memory_dir=""
|
|
293
|
+
if [ -L "$SCRIPT_DIR/memory" ]; then
|
|
294
|
+
memory_dir=$(realpath "$SCRIPT_DIR/memory" 2>/dev/null || echo "")
|
|
295
|
+
fi
|
|
296
|
+
|
|
297
|
+
# Validate and resolve managed repos
|
|
298
|
+
local managed_repos_json="[]"
|
|
299
|
+
local parent_dir
|
|
300
|
+
parent_dir="$(dirname "$SCRIPT_DIR")"
|
|
301
|
+
local repos
|
|
302
|
+
repos=$(jq -r '(.repos[]? // empty) | if type == "object" then .name else . end' "$SCRIPT_DIR/egregore.json" 2>/dev/null)
|
|
303
|
+
if [ -n "$repos" ]; then
|
|
304
|
+
# Validate repos first
|
|
305
|
+
bash "$SCRIPT_DIR/bin/boundary.sh" validate-repos 2>/dev/null || true
|
|
306
|
+
managed_repos_json="["
|
|
307
|
+
local first=true
|
|
308
|
+
for repo in $repos; do
|
|
309
|
+
# Skip entries with path traversal or absolute paths
|
|
310
|
+
[[ "$repo" == *".."* ]] && continue
|
|
311
|
+
[[ "$repo" == /* ]] && continue
|
|
312
|
+
local resolved
|
|
313
|
+
resolved=$(realpath "$parent_dir/$repo" 2>/dev/null || echo "")
|
|
314
|
+
[ -z "$resolved" ] && continue
|
|
315
|
+
# Must resolve under parent directory
|
|
316
|
+
[[ "$resolved" != "$parent_dir"/* ]] && continue
|
|
317
|
+
$first || managed_repos_json="$managed_repos_json,"
|
|
318
|
+
managed_repos_json="$managed_repos_json\"$resolved\""
|
|
319
|
+
first=false
|
|
320
|
+
done
|
|
321
|
+
managed_repos_json="$managed_repos_json]"
|
|
322
|
+
fi
|
|
323
|
+
|
|
324
|
+
# Collect denied paths from instance registry. Only checkouts proven to
|
|
325
|
+
# share this instance's stable organization identity (org_id) are excluded;
|
|
326
|
+
# ancestry or a matching slug proves nothing, and entries without org_id
|
|
327
|
+
# stay denied (fail closed). Shared logic: bin/boundary.sh compute-denied.
|
|
328
|
+
local denied_paths_json="[]"
|
|
329
|
+
local registry="$HOME/.egregore/instances.json"
|
|
330
|
+
if [ -f "$registry" ]; then
|
|
331
|
+
local self_org
|
|
332
|
+
self_org=$(jq -r '.org_id // empty' "$SCRIPT_DIR/egregore.json" 2>/dev/null)
|
|
333
|
+
denied_paths_json=$(bash "$SCRIPT_DIR/bin/boundary.sh" compute-denied \
|
|
334
|
+
"$registry" "$project_dir" "$self_org" 2>/dev/null || echo "[]")
|
|
335
|
+
case "$denied_paths_json" in "["*) ;; *) denied_paths_json="[]" ;; esac
|
|
336
|
+
fi
|
|
337
|
+
|
|
338
|
+
# --- Boundary policy: posture + read roots (two-tier consent model) ---
|
|
339
|
+
# Org layer: egregore.json .boundary { posture, read[], locked } — committed.
|
|
340
|
+
# Personal layer: .egregore-boundary.local.json { posture, read[] } — gitignored,
|
|
341
|
+
# ignored entirely when the org layer sets locked: true.
|
|
342
|
+
local posture locked personal_file="$SCRIPT_DIR/.egregore-boundary.local.json"
|
|
343
|
+
posture=$(jq -r '.boundary.posture // "standard"' "$SCRIPT_DIR/egregore.json" 2>/dev/null)
|
|
344
|
+
locked=$(jq -r '.boundary.locked // false' "$SCRIPT_DIR/egregore.json" 2>/dev/null)
|
|
345
|
+
case "$posture" in strict|standard|open) ;; *) posture="standard" ;; esac
|
|
346
|
+
[ "$locked" = "true" ] || locked="false"
|
|
347
|
+
if [ "$locked" != "true" ] && [ -f "$personal_file" ]; then
|
|
348
|
+
local p_posture
|
|
349
|
+
p_posture=$(jq -r '.posture // empty' "$personal_file" 2>/dev/null)
|
|
350
|
+
case "$p_posture" in strict|standard|open) posture="$p_posture" ;; esac
|
|
351
|
+
fi
|
|
352
|
+
|
|
353
|
+
# Read roots: inbox defaults (unless strict) + org read[] + personal read[] (unless locked)
|
|
354
|
+
local read_roots_json="[]" raw_roots=""
|
|
355
|
+
if [ "$posture" != "strict" ]; then
|
|
356
|
+
raw_roots="$HOME/Downloads
|
|
357
|
+
$HOME/Desktop"
|
|
358
|
+
fi
|
|
359
|
+
local org_roots
|
|
360
|
+
org_roots=$(jq -r '.boundary.read[]? // empty' "$SCRIPT_DIR/egregore.json" 2>/dev/null)
|
|
361
|
+
[ -n "$org_roots" ] && raw_roots="$raw_roots
|
|
362
|
+
$org_roots"
|
|
363
|
+
if [ "$locked" != "true" ] && [ -f "$personal_file" ]; then
|
|
364
|
+
local personal_roots
|
|
365
|
+
personal_roots=$(jq -r '.read[]? // empty' "$personal_file" 2>/dev/null)
|
|
366
|
+
[ -n "$personal_roots" ] && raw_roots="$raw_roots
|
|
367
|
+
$personal_roots"
|
|
368
|
+
fi
|
|
369
|
+
if [ -n "$raw_roots" ]; then
|
|
370
|
+
read_roots_json=$(printf '%s\n' "$raw_roots" | sed -e '/^$/d' -e "s|^~|$HOME|" | sort -u | jq -R . | jq -s -c .)
|
|
371
|
+
[ -z "$read_roots_json" ] && read_roots_json="[]"
|
|
372
|
+
fi
|
|
373
|
+
|
|
374
|
+
# Write boundary file (atomic: write to tmp, then mv)
|
|
375
|
+
jq -n \
|
|
376
|
+
--arg project_dir "$project_dir" \
|
|
377
|
+
--arg memory_dir "$memory_dir" \
|
|
378
|
+
--arg posture "$posture" \
|
|
379
|
+
--argjson locked "$locked" \
|
|
380
|
+
--argjson read_roots "$read_roots_json" \
|
|
381
|
+
--argjson managed_repos "$managed_repos_json" \
|
|
382
|
+
--argjson denied_paths "$denied_paths_json" \
|
|
383
|
+
'{project_dir: $project_dir, memory_dir: $memory_dir, posture: $posture, locked: $locked, read_roots: $read_roots, managed_repos: $managed_repos, denied_paths: $denied_paths}' \
|
|
384
|
+
> "$boundary_file.tmp" && mv "$boundary_file.tmp" "$boundary_file"
|
|
385
|
+
|
|
386
|
+
# Generate dynamic deny rules in .claude/settings.local.json
|
|
387
|
+
local settings_local="$SCRIPT_DIR/.claude/settings.local.json"
|
|
388
|
+
local deny_rules="[]"
|
|
389
|
+
if [ "$denied_paths_json" != "[]" ]; then
|
|
390
|
+
deny_rules=$(echo "$denied_paths_json" | jq '[.[] | "Read(" + . + "/**)", "Edit(" + . + "/**)"]')
|
|
391
|
+
fi
|
|
392
|
+
# Deny writing to instance registry (reads allowed for multi-instance features).
|
|
393
|
+
# Edit() alone covers Write/NotebookEdit too — Write() rules are never matched by
|
|
394
|
+
# the permission checker and only trigger a startup "not matched" warning if included.
|
|
395
|
+
deny_rules=$(echo "$deny_rules" | jq '. + ["Edit(~/.egregore/instances.json)"]')
|
|
396
|
+
|
|
397
|
+
# Merge with existing settings.local.json — only touch permissions.deny
|
|
398
|
+
mkdir -p "$SCRIPT_DIR/.claude"
|
|
399
|
+
if [ -f "$settings_local" ]; then
|
|
400
|
+
jq --argjson deny "$deny_rules" '.permissions.deny = $deny' "$settings_local" \
|
|
401
|
+
> "$settings_local.tmp" && mv "$settings_local.tmp" "$settings_local"
|
|
402
|
+
else
|
|
403
|
+
jq -n --argjson deny "$deny_rules" \
|
|
404
|
+
'{permissions: {deny: $deny}}' > "$settings_local"
|
|
405
|
+
fi
|
|
406
|
+
}
|
|
407
|
+
|
|
408
|
+
# Run boundary computation (non-blocking, but fast — just file I/O)
|
|
409
|
+
compute_boundary 2>/dev/null || true
|
|
410
|
+
|
|
411
|
+
# ============================================================
|
|
412
|
+
# 5. Git sync
|
|
413
|
+
# ============================================================
|
|
414
|
+
egregore_trace_mark "branch-onboarding-mode-boundary" 2>/dev/null || true
|
|
415
|
+
source "$SCRIPT_DIR/bin/lib/git-sync.sh"
|
|
416
|
+
egregore_trace_mark "git-sync" 2>/dev/null || true
|
|
417
|
+
|
|
418
|
+
# Resolve a legacy instance's stable Runtime identity before SessionStart
|
|
419
|
+
# finishes and UserPromptSubmit can invoke Observe. Once persisted this is a
|
|
420
|
+
# local status check; a control-plane outage never blocks the harness.
|
|
421
|
+
if [ -f "$SCRIPT_DIR/bin/runtime-identity.sh" ]; then
|
|
422
|
+
bash "$SCRIPT_DIR/bin/runtime-identity.sh" ensure >/dev/null 2>&1 || true
|
|
423
|
+
fi
|
|
424
|
+
egregore_trace_mark "runtime-identity" 2>/dev/null || true
|
|
425
|
+
|
|
426
|
+
# ============================================================
|
|
427
|
+
# 6. Graph bootstrap
|
|
428
|
+
# ============================================================
|
|
429
|
+
|
|
430
|
+
# --- Bootstrap graph on first launch (deferred from web setup to avoid orphans) ---
|
|
431
|
+
# Runs detached (double-fork) — must not block session start, and context.sh's
|
|
432
|
+
# `wait` must not block on it either. stdout goes to /dev/null: the session
|
|
433
|
+
# MERGE query RETURNs s.id, which used to leak a raw JSON line into the greeting.
|
|
434
|
+
if [ -f "$CONFIG" ] && [ -f "$ENV_FILE" ]; then
|
|
435
|
+
( (
|
|
436
|
+
API_KEY=$(grep '^EGREGORE_API_KEY=' "$ENV_FILE" 2>/dev/null | cut -d'=' -f2-)
|
|
437
|
+
if [ -n "$API_KEY" ]; then
|
|
438
|
+
ORG_NAME=$(jq -r '.org_name // empty' "$CONFIG" 2>/dev/null)
|
|
439
|
+
GITHUB_ORG=$(jq -r '.github_org // empty' "$CONFIG" 2>/dev/null)
|
|
440
|
+
|
|
441
|
+
if [ -n "$ORG_NAME" ] && [ -n "$GITHUB_ORG" ]; then
|
|
442
|
+
# Check if Org node exists — if not, bootstrap
|
|
443
|
+
# $_org is auto-injected by the API from the API key
|
|
444
|
+
EXISTS=$(bash "$SCRIPT_DIR/bin/graph.sh" query "MATCH (o:Org {id: \$_org}) RETURN o.id" 2>/dev/null || echo "")
|
|
445
|
+
if echo "$EXISTS" | jq -e '.values | length == 0' &>/dev/null; then
|
|
446
|
+
bash "$SCRIPT_DIR/bin/graph.sh" query \
|
|
447
|
+
"MERGE (o:Org {id: \$_org}) SET o.name = \$name, o.github_org = \$github_org" \
|
|
448
|
+
"$(jq -n --arg name "$ORG_NAME" --arg github_org "$GITHUB_ORG" '{name: $name, github_org: $github_org}')" 2>/dev/null || true
|
|
449
|
+
bash "$SCRIPT_DIR/bin/graph.sh" query \
|
|
450
|
+
"MERGE (pr:Project {name: 'Egregore'}) WITH pr MATCH (o:Org {id: \$_org}) MERGE (pr)-[:PART_OF]->(o)" \
|
|
451
|
+
2>/dev/null || true
|
|
452
|
+
fi
|
|
453
|
+
|
|
454
|
+
# Reconcile one canonical member across markdown, Supabase, and Neo4j.
|
|
455
|
+
# GitHub's numeric id is stable across login and preferred-name changes.
|
|
456
|
+
if [ -n "$AUTHOR" ]; then
|
|
457
|
+
PERSON_SYNC_RESULT=$(bash "$SCRIPT_DIR/bin/person.sh" sync 2>/dev/null || true)
|
|
458
|
+
if printf '%s' "$PERSON_SYNC_RESULT" | jq -e \
|
|
459
|
+
'.status == "removed"' >/dev/null 2>&1; then
|
|
460
|
+
exit 0
|
|
461
|
+
fi
|
|
462
|
+
GH_USERNAME_STATE=$(jq -r '.github_username // empty' "$STATE_FILE" 2>/dev/null)
|
|
463
|
+
PERSON_ID_STATE=$(jq -r \
|
|
464
|
+
'.person_id // ("github-login:" + ((.github_username // "") | ascii_downcase))' \
|
|
465
|
+
"$STATE_FILE" 2>/dev/null)
|
|
466
|
+
|
|
467
|
+
# Auto-capture: create personal Session node with status='active'
|
|
468
|
+
AUTO_CAPTURE="true"
|
|
469
|
+
if [ -f "$STATE_FILE" ]; then
|
|
470
|
+
AUTO_CAPTURE=$(jq -r '.auto_capture // "true"' "$STATE_FILE" 2>/dev/null || echo "true")
|
|
471
|
+
fi
|
|
472
|
+
|
|
473
|
+
if [ "$AUTO_CAPTURE" = "true" ]; then
|
|
474
|
+
# Match by canonical personId OR github login. State files written
|
|
475
|
+
# before the numeric-id migration carry person_id
|
|
476
|
+
# "github-login:<name>" while the graph Person holds
|
|
477
|
+
# "github:<numeric>" — the exact-personId MATCH found no row, the
|
|
478
|
+
# MERGE below silently never ran, and no Session was captured.
|
|
479
|
+
# Filters mirror the canonical Person lookup in identity.sh
|
|
480
|
+
# (active, not ingested), and the ORDER BY makes the pick TOTALLY
|
|
481
|
+
# ordered — exact personId first, then personId, then the node's
|
|
482
|
+
# internal id as final tie-breaker (personId has no uniqueness
|
|
483
|
+
# constraint) — so a later WAL replay resolves to the same node as
|
|
484
|
+
# the direct write and the Session never gains two BY edges.
|
|
485
|
+
SESSION_CYPHER="MATCH (p:Person)
|
|
486
|
+
WHERE (p.personId = \$personId OR toLower(p.github) = toLower(\$github))
|
|
487
|
+
AND NOT coalesce(p.kind, '') IN ['external', 'identity_alias']
|
|
488
|
+
AND coalesce(p.status, 'active') = 'active'
|
|
489
|
+
AND p.ingestRef IS NULL
|
|
490
|
+
WITH p ORDER BY
|
|
491
|
+
CASE WHEN p.personId = \$personId THEN 0 ELSE 1 END,
|
|
492
|
+
p.personId, id(p)
|
|
493
|
+
LIMIT 1
|
|
494
|
+
MERGE (s:Session {id: \$sid})
|
|
495
|
+
ON CREATE SET s.date = date(\$date), s.branch = \$branch,
|
|
496
|
+
s.startedAt = datetime(), s.status = 'active'
|
|
497
|
+
MERGE (s)-[:BY]->(p) RETURN s.id"
|
|
498
|
+
SESSION_PARAMS=$(jq -n \
|
|
499
|
+
--arg sid "$EGREGORE_SESSION_ID" \
|
|
500
|
+
--arg author "$(echo "$AUTHOR" | tr '[:upper:]' '[:lower:]')" \
|
|
501
|
+
--arg github "${GH_USERNAME_STATE:-$AUTHOR}" \
|
|
502
|
+
--arg personId "$PERSON_ID_STATE" \
|
|
503
|
+
--arg branch "$BRANCH" \
|
|
504
|
+
--arg date "$(date +%Y-%m-%d)" \
|
|
505
|
+
'{sid: $sid, author: $author, github: $github, personId: $personId, branch: $branch, date: $date}')
|
|
506
|
+
|
|
507
|
+
# WAL first (guaranteed persistence)
|
|
508
|
+
bash "$SCRIPT_DIR/bin/graph-wal.sh" append "$SESSION_CYPHER" "$SESSION_PARAMS" 2>/dev/null || true
|
|
509
|
+
# Direct write (best effort, immediate)
|
|
510
|
+
bash "$SCRIPT_DIR/bin/graph.sh" query "$SESSION_CYPHER" "$SESSION_PARAMS" 2>/dev/null || true
|
|
511
|
+
fi
|
|
512
|
+
fi
|
|
513
|
+
fi
|
|
514
|
+
fi
|
|
515
|
+
) >/dev/null 2>&1 & ) 2>/dev/null
|
|
516
|
+
fi
|
|
517
|
+
|
|
518
|
+
# ============================================================
|
|
519
|
+
# 7. Transcript retry + WAL drain
|
|
520
|
+
# ============================================================
|
|
521
|
+
|
|
522
|
+
# --- Retry failed transcript uploads (background, silent) ---
|
|
523
|
+
RETRY_QUEUE="$SCRIPT_DIR/.transcript-retry-queue"
|
|
524
|
+
TRANSCRIPTS_DIR=$(jq -r '.transcripts_dir // empty' "$SCRIPT_DIR/egregore.json" 2>/dev/null)
|
|
525
|
+
[ -z "$TRANSCRIPTS_DIR" ] && TRANSCRIPTS_DIR="$SCRIPT_DIR/../egregore-transcripts"
|
|
526
|
+
if [ -f "$RETRY_QUEUE" ] && [ -s "$RETRY_QUEUE" ]; then
|
|
527
|
+
( (
|
|
528
|
+
RETRIED=false
|
|
529
|
+
# If git repo exists, retry push (CL internal)
|
|
530
|
+
if [ -d "$TRANSCRIPTS_DIR/.git" ]; then
|
|
531
|
+
if git -C "$TRANSCRIPTS_DIR" push origin main 2>/dev/null; then
|
|
532
|
+
RETRIED=true
|
|
533
|
+
fi
|
|
534
|
+
fi
|
|
535
|
+
# If API is available, retry upload for queued sessions (customer orgs)
|
|
536
|
+
if [ "$RETRIED" = "false" ] && [ -f "$CONFIG" ] && [ -f "$ENV_FILE" ]; then
|
|
537
|
+
R_API_URL=$(jq -r '.api_url // empty' "$CONFIG" 2>/dev/null || true)
|
|
538
|
+
R_API_KEY=$(grep '^EGREGORE_API_KEY=' "$ENV_FILE" 2>/dev/null | cut -d'=' -f2- || true)
|
|
539
|
+
if [ -n "$R_API_URL" ] && [ -n "$R_API_KEY" ]; then
|
|
540
|
+
REMAINING=""
|
|
541
|
+
COUNT=0
|
|
542
|
+
while IFS= read -r SID && [ $COUNT -lt 5 ]; do
|
|
543
|
+
SID=$(echo "$SID" | tr -cd 'a-zA-Z0-9_-')
|
|
544
|
+
[ -z "$SID" ] && continue
|
|
545
|
+
# Re-run the archive for this session (it will find the transcript)
|
|
546
|
+
RETRIED=true
|
|
547
|
+
COUNT=$((COUNT + 1))
|
|
548
|
+
done < "$RETRY_QUEUE"
|
|
549
|
+
if [ "$RETRIED" = "true" ]; then
|
|
550
|
+
# Clear queue on any progress — archive script will re-queue failures
|
|
551
|
+
rm -f "$RETRY_QUEUE"
|
|
552
|
+
fi
|
|
553
|
+
fi
|
|
554
|
+
fi
|
|
555
|
+
if [ "$RETRIED" = "true" ]; then
|
|
556
|
+
rm -f "$RETRY_QUEUE"
|
|
557
|
+
fi
|
|
558
|
+
) >/dev/null 2>&1 & ) 2>/dev/null
|
|
559
|
+
fi
|
|
560
|
+
|
|
561
|
+
# --- Drain WAL (detached, non-blocking) ---
|
|
562
|
+
( bash "$SCRIPT_DIR/bin/graph-wal.sh" drain >/dev/null 2>&1 & ) 2>/dev/null
|
|
563
|
+
|
|
564
|
+
# ============================================================
|
|
565
|
+
# 7b. Session baseline (for session-log.sh delta computation)
|
|
566
|
+
# ============================================================
|
|
567
|
+
BASELINE_FILE="/tmp/egregore-baseline-${EGREGORE_SESSION_ID}.json"
|
|
568
|
+
jq -n \
|
|
569
|
+
--arg branch "$BRANCH" \
|
|
570
|
+
--arg commit "$(git -C "$SCRIPT_DIR" rev-parse HEAD 2>/dev/null || echo '')" \
|
|
571
|
+
--argjson dirty "$([ -n "$(git -C "$SCRIPT_DIR" status --porcelain 2>/dev/null | head -1)" ] && echo 'true' || echo 'false')" \
|
|
572
|
+
--arg started_at "$(date -u +%Y-%m-%dT%H:%M:%SZ)" \
|
|
573
|
+
'{branch: $branch, commit: $commit, dirty: $dirty, started_at: $started_at}' \
|
|
574
|
+
> "$BASELINE_FILE" 2>/dev/null || true
|
|
575
|
+
|
|
576
|
+
# ============================================================
|
|
577
|
+
# 7c. Attendant — ambient capture daemon (fire-and-forget)
|
|
578
|
+
# ============================================================
|
|
579
|
+
# Watches for sessions that die without ceremony (terminal closed) and
|
|
580
|
+
# pulls the ripcord: auto-handoff + auto-push of stranded dev branches.
|
|
581
|
+
# `ensure` is a pidfile check (~ms); the daemon itself runs detached.
|
|
582
|
+
( bash "$SCRIPT_DIR/bin/attendant.sh" ensure >/dev/null 2>&1 & ) 2>/dev/null
|
|
583
|
+
|
|
584
|
+
# ============================================================
|
|
585
|
+
# 7c2. Connect overlay refresh (fire-and-forget)
|
|
586
|
+
# ============================================================
|
|
587
|
+
# Connected instances pick up newly released Connect skills without
|
|
588
|
+
# re-running the launcher. Local mode exits instantly inside the script.
|
|
589
|
+
( bash "$SCRIPT_DIR/bin/connect-refresh.sh" >/dev/null 2>&1 & ) 2>/dev/null
|
|
590
|
+
|
|
591
|
+
# ============================================================
|
|
592
|
+
# 7d. Autosave sweep — rescue non-coding leftovers (fire-and-forget)
|
|
593
|
+
# ============================================================
|
|
594
|
+
# Terminal-close cover: sessions that died before SessionEnd leave dirty
|
|
595
|
+
# checkouts/worktrees behind. The sweep saves + auto-merges any whose
|
|
596
|
+
# pending changes are entirely non-coding (gate + idle guard inside).
|
|
597
|
+
( bash "$SCRIPT_DIR/bin/session-autosave.sh" --sweep >/dev/null 2>&1 & ) 2>/dev/null
|
|
598
|
+
|
|
599
|
+
# ============================================================
|
|
600
|
+
# 8. Gather context
|
|
601
|
+
# ============================================================
|
|
602
|
+
# Read-only greeting queries go through the graph cache the attendant keeps
|
|
603
|
+
# warm — zero round-trips when warm, live queries on a cold cache. Mutating
|
|
604
|
+
# queries are never cached (guard lives in graph.sh).
|
|
605
|
+
# CTX_SEED_TAR points at the attendant's pre-baked context snapshot tar
|
|
606
|
+
# (_prebake_context); context.sh validates provenance (author, mode, config,
|
|
607
|
+
# freshness) and falls back to a full live gather when anything is off.
|
|
608
|
+
# _ATT_KEY comes from git-sync.sh and matches the attendant's own state key.
|
|
609
|
+
if [ -n "${_ATT_KEY:-}" ]; then
|
|
610
|
+
export CTX_SEED_TAR="${ATTENDANT_HOME:-$HOME/.egregore/attendant}/${_ATT_KEY}.ctx.tar"
|
|
611
|
+
fi
|
|
612
|
+
export EGREGORE_GRAPH_CACHE_TTL=600
|
|
613
|
+
source "$SCRIPT_DIR/bin/lib/context.sh"
|
|
614
|
+
unset EGREGORE_GRAPH_CACHE_TTL CTX_SEED_TAR
|
|
615
|
+
egregore_trace_mark "context-gather" 2>/dev/null || true
|
|
616
|
+
|
|
617
|
+
# ============================================================
|
|
618
|
+
# 8b. Generate session dashboard artifact
|
|
619
|
+
# ============================================================
|
|
620
|
+
source "$SCRIPT_DIR/bin/lib/dashboard-artifact.sh"
|
|
621
|
+
egregore_trace_mark "dashboard-artifact" 2>/dev/null || true
|
|
622
|
+
|
|
623
|
+
# Stable board URL — shown in greeting, refreshable. Connected mode only;
|
|
624
|
+
# /view board upserts content at this URL via `publish-artifact.sh --id board`.
|
|
625
|
+
BOARD_URL=""
|
|
626
|
+
if [ "${LOCAL_MODE:-false}" != "true" ] && [ -f "$SCRIPT_DIR/memory/board/board.json" ]; then
|
|
627
|
+
_ORG_SLUG=$(jq -r '.slug // empty' "$SCRIPT_DIR/egregore.json" 2>/dev/null)
|
|
628
|
+
if [ -n "$_ORG_SLUG" ]; then
|
|
629
|
+
BOARD_URL="https://egregore.xyz/view/${_ORG_SLUG}/board"
|
|
630
|
+
fi
|
|
631
|
+
fi
|
|
632
|
+
|
|
633
|
+
# ============================================================
|
|
634
|
+
# 9. Render greeting
|
|
635
|
+
# ============================================================
|
|
636
|
+
# Loom stage-1 drift surfacing: fail-soft alias-drift warning for the greeting.
|
|
637
|
+
# A full `doctor --brief` pass is ~2s of jq. Its config inputs (routes.json,
|
|
638
|
+
# org overrides, ANTHROPIC_* env, harness settings env) change rarely, so the
|
|
639
|
+
# brief is cached keyed on a hash of those inputs. The 6h age floor forces a
|
|
640
|
+
# real pass often enough that ledger-derived warnings (instrument blind, trace
|
|
641
|
+
# gaps, pending proposals) still surface within the day.
|
|
642
|
+
LOOM_DOCTOR_BRIEF=""
|
|
643
|
+
if command -v jq >/dev/null 2>&1; then
|
|
644
|
+
_LOOM_HASH=$(_md5 "$(cat "$SCRIPT_DIR/loom/routes.json" 2>/dev/null; \
|
|
645
|
+
jq -c '.loom // {}' "$CONFIG" 2>/dev/null; \
|
|
646
|
+
env | grep '^ANTHROPIC_' | sort; \
|
|
647
|
+
jq -c '.env // {}' "$HOME/.claude/settings.json" 2>/dev/null)")
|
|
648
|
+
_LOOM_CACHE="$HOME/.egregore/loom-doctor-brief-$(echo -n "${MAIN_PROJECT_DIR:-$SCRIPT_DIR}" | cksum | cut -d' ' -f1)"
|
|
649
|
+
_LOOM_FRESH="false"
|
|
650
|
+
if [ -f "$_LOOM_CACHE" ] && [ "$(head -1 "$_LOOM_CACHE" 2>/dev/null)" = "$_LOOM_HASH" ]; then
|
|
651
|
+
_LOOM_AGE=$(( $(date +%s) - $(stat -f %m "$_LOOM_CACHE" 2>/dev/null || stat -c %Y "$_LOOM_CACHE" 2>/dev/null || echo 0) ))
|
|
652
|
+
[ "$_LOOM_AGE" -lt 21600 ] && _LOOM_FRESH="true"
|
|
653
|
+
fi
|
|
654
|
+
if [ "$_LOOM_FRESH" = "true" ]; then
|
|
655
|
+
LOOM_DOCTOR_BRIEF=$(tail -n +2 "$_LOOM_CACHE" 2>/dev/null)
|
|
656
|
+
else
|
|
657
|
+
LOOM_DOCTOR_BRIEF=$(bash "$SCRIPT_DIR/bin/loom.sh" doctor --brief 2>/dev/null || true)
|
|
658
|
+
mkdir -p "$HOME/.egregore" 2>/dev/null
|
|
659
|
+
{ printf '%s\n' "$_LOOM_HASH"; printf '%s' "$LOOM_DOCTOR_BRIEF"; } > "$_LOOM_CACHE.tmp.$$" 2>/dev/null \
|
|
660
|
+
&& mv "$_LOOM_CACHE.tmp.$$" "$_LOOM_CACHE" 2>/dev/null || rm -f "$_LOOM_CACHE.tmp.$$" 2>/dev/null || true
|
|
661
|
+
fi
|
|
662
|
+
fi
|
|
663
|
+
# Render the greeting into a buffer first (redirection on a brace group keeps
|
|
664
|
+
# variable/file side effects in this shell). The buffer lets us (a) cache the
|
|
665
|
+
# visible card for external launchers and (b) emit a slim reply when the
|
|
666
|
+
# launcher already displayed the card — the model then answers in one short
|
|
667
|
+
# message instead of re-typing ~1k tokens of box art.
|
|
668
|
+
egregore_trace_mark "loom-doctor" 2>/dev/null || true
|
|
669
|
+
_GREETING_BUF="${TMPDIR:-/tmp}/egregore-greeting-$$.txt"
|
|
670
|
+
{ source "$SCRIPT_DIR/bin/lib/greeting.sh"; } > "$_GREETING_BUF"
|
|
671
|
+
egregore_trace_mark "greeting-render" 2>/dev/null || true
|
|
672
|
+
|
|
673
|
+
# Cache the visible card (everything before the hidden context sections) for
|
|
674
|
+
# bin/greeting-card.sh. Keyed by the main checkout + framework version so a
|
|
675
|
+
# greeting format change invalidates old cards instead of replaying them.
|
|
676
|
+
# Worktree boots skip the write — their branch/status would clobber the card
|
|
677
|
+
# launchers show for the main checkout. Atomic write; fail-soft.
|
|
678
|
+
_CARD_KEY=$(echo -n "${MAIN_PROJECT_DIR:-$SCRIPT_DIR}" | cksum | cut -d' ' -f1)
|
|
679
|
+
_CARD_FILE="$HOME/.egregore/greeting-card-v${FRAMEWORK_VERSION}-${_CARD_KEY}"
|
|
680
|
+
if [ "$IS_WORKTREE" != "true" ]; then
|
|
681
|
+
mkdir -p "$HOME/.egregore" 2>/dev/null
|
|
682
|
+
rm -f "$HOME/.egregore/greeting-card-${_CARD_KEY}" 2>/dev/null # pre-versioning cache name
|
|
683
|
+
awk '/^<!-- session-context/{exit} {print}' "$_GREETING_BUF" > "$_CARD_FILE.tmp.$$" 2>/dev/null \
|
|
684
|
+
&& mv "$_CARD_FILE.tmp.$$" "$_CARD_FILE" 2>/dev/null \
|
|
685
|
+
|| rm -f "$_CARD_FILE.tmp.$$" 2>/dev/null || true
|
|
686
|
+
fi
|
|
687
|
+
|
|
688
|
+
# The greeting always renders in-chat — identical across OSS and Connect and
|
|
689
|
+
# across launch paths. The launcher-rendered card fast path (EGREGORE_CARD_SHOWN)
|
|
690
|
+
# was reverted: Claude Code ≥2.1.89 boots into the alternate screen buffer,
|
|
691
|
+
# which hides anything a launcher prints pre-launch (see PR #1493 for the
|
|
692
|
+
# parked re-enable). The card cache write above stays — it is harmless and the
|
|
693
|
+
# re-enable path depends on it.
|
|
694
|
+
cat "$_GREETING_BUF"
|
|
695
|
+
rm -f "$_GREETING_BUF" 2>/dev/null || true
|
|
696
|
+
egregore_trace_end 2>/dev/null || true
|