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,213 @@
|
|
|
1
|
+
# shellcheck shell=bash
|
|
2
|
+
# identity.sh — User identity resolution for session-start.sh
|
|
3
|
+
#
|
|
4
|
+
# Resolves the current user's identity through multiple fallback layers:
|
|
5
|
+
# 1. .egregore-state.json github_username (stored during setup)
|
|
6
|
+
# 2. GitHub API auto-detect via GITHUB_TOKEN
|
|
7
|
+
# 3. Graph person lookup (existing team member on new machine)
|
|
8
|
+
# 4. Global git config user.name (last resort)
|
|
9
|
+
#
|
|
10
|
+
# Inputs: STATE_FILE, ENV_FILE, SCRIPT_DIR, HEALTH_GITHUB
|
|
11
|
+
# Outputs: AUTHOR, DISPLAY_NAME_STATE, FIRST_SESSION, HEALTH_GITHUB,
|
|
12
|
+
# EGREGORE_USER, EGREGORE_ORG, EGREGORE_SESSION_ID
|
|
13
|
+
# Writes .egregore-session-id and ~/.egregore/session-*.id
|
|
14
|
+
|
|
15
|
+
STORED_USERNAME=""
|
|
16
|
+
FIRST_SESSION=""
|
|
17
|
+
AUTHOR=""
|
|
18
|
+
if [ -f "$STATE_FILE" ]; then
|
|
19
|
+
STORED_USERNAME=$(jq -r '.github_username // empty' "$STATE_FILE" 2>/dev/null)
|
|
20
|
+
fi
|
|
21
|
+
|
|
22
|
+
DISPLAY_NAME_STATE=""
|
|
23
|
+
if [ -f "$STATE_FILE" ]; then
|
|
24
|
+
DISPLAY_NAME_STATE=$(jq -r '.display_name // empty' "$STATE_FILE" 2>/dev/null)
|
|
25
|
+
fi
|
|
26
|
+
|
|
27
|
+
if [ -n "$STORED_USERNAME" ]; then
|
|
28
|
+
# Identity stored during setup — use it and ensure repo-local git config matches
|
|
29
|
+
AUTHOR="$STORED_USERNAME"
|
|
30
|
+
HEALTH_GITHUB="ok"
|
|
31
|
+
CURRENT_LOCAL=$(git config --local user.name 2>/dev/null || echo "")
|
|
32
|
+
if [ "$CURRENT_LOCAL" != "$STORED_USERNAME" ]; then
|
|
33
|
+
STORED_NAME=$(jq -r '.github_name // empty' "$STATE_FILE" 2>/dev/null)
|
|
34
|
+
git config user.name "${STORED_NAME:-$STORED_USERNAME}" 2>/dev/null || true
|
|
35
|
+
git config user.email "${STORED_USERNAME}@users.noreply.github.com" 2>/dev/null || true
|
|
36
|
+
fi
|
|
37
|
+
else
|
|
38
|
+
# No stored identity — try GitHub API to auto-detect (self-healing for pre-fix installs)
|
|
39
|
+
if [ -f "$ENV_FILE" ]; then
|
|
40
|
+
GH_TOKEN=$(grep '^GITHUB_TOKEN=' "$ENV_FILE" 2>/dev/null | cut -d'=' -f2-)
|
|
41
|
+
if [ -n "$GH_TOKEN" ]; then
|
|
42
|
+
GH_USER_JSON=$(curl -s -H "Authorization: token $GH_TOKEN" https://api.github.com/user --max-time 5 2>/dev/null || echo "")
|
|
43
|
+
GH_LOGIN=$(echo "$GH_USER_JSON" | jq -r '.login // empty' 2>/dev/null)
|
|
44
|
+
GH_ID=$(echo "$GH_USER_JSON" | jq -r '.id // empty' 2>/dev/null)
|
|
45
|
+
GH_NAME=$(echo "$GH_USER_JSON" | jq -r '.name // empty' 2>/dev/null)
|
|
46
|
+
GH_EMAIL=$(echo "$GH_USER_JSON" | jq -r '.email // empty' 2>/dev/null)
|
|
47
|
+
if [ -n "$GH_LOGIN" ]; then
|
|
48
|
+
GH_ID_JSON="null"
|
|
49
|
+
GH_PERSON_ID="github-login:$(echo "$GH_LOGIN" | tr '[:upper:]' '[:lower:]')"
|
|
50
|
+
if [[ "$GH_ID" =~ ^[0-9]+$ ]]; then
|
|
51
|
+
GH_ID_JSON="$GH_ID"
|
|
52
|
+
GH_PERSON_ID="github:$GH_ID"
|
|
53
|
+
fi
|
|
54
|
+
AUTHOR="$GH_LOGIN"
|
|
55
|
+
HEALTH_GITHUB="ok"
|
|
56
|
+
# Set repo-local config and save to state for next time
|
|
57
|
+
git config user.name "${GH_NAME:-$GH_LOGIN}" 2>/dev/null || true
|
|
58
|
+
git config user.email "${GH_LOGIN}@users.noreply.github.com" 2>/dev/null || true
|
|
59
|
+
# Save to state file so we don't need API call next time
|
|
60
|
+
# Include onboarding_complete + name so it doesn't re-trigger onboarding
|
|
61
|
+
# Determine if founder or joiner: if github_username != github_org, they're a joiner
|
|
62
|
+
GITHUB_ORG_CFG=$(jq -r '.github_org // empty' "$SCRIPT_DIR/egregore.json" 2>/dev/null)
|
|
63
|
+
if [ -n "$GITHUB_ORG_CFG" ] && [ "$GH_LOGIN" != "$GITHUB_ORG_CFG" ]; then
|
|
64
|
+
USAGE_TYPE="joiner_group"
|
|
65
|
+
else
|
|
66
|
+
USAGE_TYPE="founder_group"
|
|
67
|
+
fi
|
|
68
|
+
if [ -f "$STATE_FILE" ]; then
|
|
69
|
+
# Existing state file — update identity but preserve onboarding status
|
|
70
|
+
HAS_ONBOARDING=$(jq -r '.onboarding_complete // "unset"' "$STATE_FILE" 2>/dev/null)
|
|
71
|
+
if [ "$HAS_ONBOARDING" = "unset" ]; then
|
|
72
|
+
# State file exists but no onboarding flag — set to false to trigger it
|
|
73
|
+
jq --arg u "$GH_LOGIN" --arg n "${GH_NAME:-$GH_LOGIN}" --arg ut "$USAGE_TYPE" \
|
|
74
|
+
--argjson gid "$GH_ID_JSON" --arg pid "$GH_PERSON_ID" --arg email "$GH_EMAIL" \
|
|
75
|
+
'.github_username = $u | .github_id = $gid | .person_id = $pid |
|
|
76
|
+
.github_name = $n | .name = $n |
|
|
77
|
+
(if $email != "" then .email = ($email | ascii_downcase) else . end) |
|
|
78
|
+
.onboarding_complete = false | .usage_type = $ut' "$STATE_FILE" > "$STATE_FILE.tmp" \
|
|
79
|
+
&& mv "$STATE_FILE.tmp" "$STATE_FILE"
|
|
80
|
+
else
|
|
81
|
+
jq --arg u "$GH_LOGIN" --arg n "${GH_NAME:-$GH_LOGIN}" --arg ut "$USAGE_TYPE" \
|
|
82
|
+
--argjson gid "$GH_ID_JSON" --arg pid "$GH_PERSON_ID" --arg email "$GH_EMAIL" \
|
|
83
|
+
'.github_username = $u | .github_id = $gid | .person_id = $pid |
|
|
84
|
+
.github_name = $n | .name = $n |
|
|
85
|
+
(if $email != "" then .email = ($email | ascii_downcase) else . end) |
|
|
86
|
+
.usage_type = $ut' "$STATE_FILE" > "$STATE_FILE.tmp" \
|
|
87
|
+
&& mv "$STATE_FILE.tmp" "$STATE_FILE"
|
|
88
|
+
fi
|
|
89
|
+
FIRST_SESSION="false"
|
|
90
|
+
else
|
|
91
|
+
# No state file — check graph to see if this person already exists
|
|
92
|
+
# (handles fresh clone / new machine for existing team members)
|
|
93
|
+
GRAPH_PERSON=""
|
|
94
|
+
GRAPH_DISPLAY_NAME=""
|
|
95
|
+
GRAPH_PERSON=$(bash "$SCRIPT_DIR/bin/graph.sh" query \
|
|
96
|
+
"MATCH (p:Person)
|
|
97
|
+
WHERE NOT coalesce(p.kind, '') IN ['external', 'identity_alias']
|
|
98
|
+
AND coalesce(p.status, 'active') = 'active'
|
|
99
|
+
AND p.ingestRef IS NULL
|
|
100
|
+
AND (p.github = \$github
|
|
101
|
+
OR (\$githubId <> '' AND coalesce(toString(p.githubId), '') = \$githubId)
|
|
102
|
+
OR toLower(\$github) IN [alias IN coalesce(p.githubAliases, []) | toLower(alias)])
|
|
103
|
+
RETURN p.name AS name" \
|
|
104
|
+
"$(jq -n --arg github "$GH_LOGIN" --arg githubId "$GH_ID" \
|
|
105
|
+
'{github: $github, githubId: $githubId}')" 2>/dev/null || echo "")
|
|
106
|
+
if echo "$GRAPH_PERSON" | jq -e '.values | length > 0' &>/dev/null; then
|
|
107
|
+
GRAPH_DISPLAY_NAME=$(echo "$GRAPH_PERSON" | jq -r '.values[0][0] // empty' 2>/dev/null)
|
|
108
|
+
# Existing team member — skip onboarding
|
|
109
|
+
jq -n --arg github "$GH_LOGIN" --argjson githubId "$GH_ID_JSON" \
|
|
110
|
+
--arg personId "$GH_PERSON_ID" --arg githubName "${GH_NAME:-$GH_LOGIN}" \
|
|
111
|
+
--arg name "${GRAPH_DISPLAY_NAME:-${GH_NAME:-$GH_LOGIN}}" \
|
|
112
|
+
--arg displayName "${GRAPH_DISPLAY_NAME:-}" --arg email "$GH_EMAIL" \
|
|
113
|
+
--arg usageType "$USAGE_TYPE" \
|
|
114
|
+
'{
|
|
115
|
+
github_username: $github, github_id: $githubId, person_id: $personId,
|
|
116
|
+
github_name: $githubName, name: $name, display_name: $displayName,
|
|
117
|
+
email: (if $email == "" then null else ($email | ascii_downcase) end),
|
|
118
|
+
onboarding_complete: true, usage_type: $usageType,
|
|
119
|
+
session_tracking: true, transcript_sharing: true, telemetry: true,
|
|
120
|
+
contact_preference: "all", telemetry_noticed: true
|
|
121
|
+
}' > "$STATE_FILE"
|
|
122
|
+
FIRST_SESSION="false"
|
|
123
|
+
else
|
|
124
|
+
# Genuinely new user — trigger onboarding
|
|
125
|
+
jq -n --arg github "$GH_LOGIN" --argjson githubId "$GH_ID_JSON" \
|
|
126
|
+
--arg personId "$GH_PERSON_ID" --arg githubName "${GH_NAME:-$GH_LOGIN}" \
|
|
127
|
+
--arg email "$GH_EMAIL" --arg usageType "$USAGE_TYPE" \
|
|
128
|
+
'{
|
|
129
|
+
github_username: $github, github_id: $githubId, person_id: $personId,
|
|
130
|
+
github_name: $githubName, name: $githubName,
|
|
131
|
+
email: (if $email == "" then null else ($email | ascii_downcase) end),
|
|
132
|
+
onboarding_complete: false, usage_type: $usageType, first_session: true
|
|
133
|
+
}' > "$STATE_FILE"
|
|
134
|
+
FIRST_SESSION="true"
|
|
135
|
+
fi
|
|
136
|
+
fi
|
|
137
|
+
fi
|
|
138
|
+
fi
|
|
139
|
+
fi
|
|
140
|
+
|
|
141
|
+
# Final fallback: git config user.name (global or local)
|
|
142
|
+
if [ -z "$AUTHOR" ]; then
|
|
143
|
+
FULLNAME=$(git config user.name 2>/dev/null || echo "")
|
|
144
|
+
AUTHOR=$(echo "$FULLNAME" | tr '[:upper:]' '[:lower:]' | cut -d' ' -f1)
|
|
145
|
+
fi
|
|
146
|
+
fi
|
|
147
|
+
|
|
148
|
+
if [ -z "$AUTHOR" ]; then
|
|
149
|
+
AUTHOR="unknown"
|
|
150
|
+
HEALTH_GITHUB="fail"
|
|
151
|
+
fi
|
|
152
|
+
|
|
153
|
+
# --- Validate gh CLI identity matches git identity ---
|
|
154
|
+
# The gh CLI has its own auth (keyring) separate from .env GITHUB_TOKEN.
|
|
155
|
+
# If they diverge, PRs get created under the wrong account.
|
|
156
|
+
# The `gh api user` round-trip (~1s) is off the boot path: each start reports
|
|
157
|
+
# the marker the previous background check left, then refreshes it detached.
|
|
158
|
+
# A mismatch therefore surfaces one session late — acceptable for a warning
|
|
159
|
+
# about a rare, persistent condition.
|
|
160
|
+
if command -v gh &>/dev/null && [ -n "$AUTHOR" ] && [ "$AUTHOR" != "unknown" ]; then
|
|
161
|
+
_GH_MISMATCH_FILE="$HOME/.egregore/gh-identity-mismatch-$(echo -n "${MAIN_PROJECT_DIR:-$SCRIPT_DIR}" | cksum | cut -d' ' -f1)"
|
|
162
|
+
# Marker format: line 1 = the AUTHOR the check ran as, line 2 = the gh login
|
|
163
|
+
# observed. Warn only when line 1 matches the current AUTHOR — the same
|
|
164
|
+
# machine/instance can serve different git identities, and Alice's stale
|
|
165
|
+
# marker must not tell Bob that Bob mismatches Bob.
|
|
166
|
+
_GH_MARKER_AUTHOR=$(sed -n '1p' "$_GH_MISMATCH_FILE" 2>/dev/null || true)
|
|
167
|
+
GH_CLI_USER=$(sed -n '2p' "$_GH_MISMATCH_FILE" 2>/dev/null || true)
|
|
168
|
+
if [ -n "$GH_CLI_USER" ] && [ "$_GH_MARKER_AUTHOR" = "$AUTHOR" ]; then
|
|
169
|
+
echo ""
|
|
170
|
+
echo "WARNING: Identity mismatch detected."
|
|
171
|
+
echo " Git identity (.env): $AUTHOR"
|
|
172
|
+
echo " gh CLI (active): $GH_CLI_USER"
|
|
173
|
+
echo " PRs will be created as '$GH_CLI_USER', not '$AUTHOR'."
|
|
174
|
+
echo " Fix: gh auth switch --user $AUTHOR"
|
|
175
|
+
echo ""
|
|
176
|
+
fi
|
|
177
|
+
( (
|
|
178
|
+
_GH_LIVE=$(gh api user --jq '.login' 2>/dev/null || true)
|
|
179
|
+
if [ -n "$_GH_LIVE" ]; then
|
|
180
|
+
if [ "$(echo "$_GH_LIVE" | tr '[:upper:]' '[:lower:]')" != "$(echo "$AUTHOR" | tr '[:upper:]' '[:lower:]')" ]; then
|
|
181
|
+
mkdir -p "$HOME/.egregore" 2>/dev/null
|
|
182
|
+
printf '%s\n%s\n' "$AUTHOR" "$_GH_LIVE" > "$_GH_MISMATCH_FILE.tmp" \
|
|
183
|
+
&& mv "$_GH_MISMATCH_FILE.tmp" "$_GH_MISMATCH_FILE"
|
|
184
|
+
else
|
|
185
|
+
rm -f "$_GH_MISMATCH_FILE"
|
|
186
|
+
fi
|
|
187
|
+
fi
|
|
188
|
+
) >/dev/null 2>&1 & ) 2>/dev/null
|
|
189
|
+
fi
|
|
190
|
+
|
|
191
|
+
# --- Export telemetry identity env vars ---
|
|
192
|
+
export EGREGORE_USER="$AUTHOR"
|
|
193
|
+
export EGREGORE_ORG="$(jq -r '.slug // .github_org // empty' "$SCRIPT_DIR/egregore.json" 2>/dev/null || true)"
|
|
194
|
+
export EGREGORE_SESSION_ID="$(date -u +%Y%m%dT%H%M%S)-${AUTHOR}-$$"
|
|
195
|
+
|
|
196
|
+
# Persist session ID to file so telemetry.sh can read it
|
|
197
|
+
# (env vars from hooks don't propagate into the Claude Code agent)
|
|
198
|
+
SESSION_ID_DIR="$HOME/.egregore"
|
|
199
|
+
mkdir -p "$SESSION_ID_DIR"
|
|
200
|
+
PROJ_HASH=$(echo -n "$SCRIPT_DIR" | md5 2>/dev/null || echo -n "$SCRIPT_DIR" | md5sum 2>/dev/null | cut -d' ' -f1)
|
|
201
|
+
echo "$EGREGORE_SESSION_ID" > "$SESSION_ID_DIR/session-${PROJ_HASH}.id"
|
|
202
|
+
# Also write project-local file (CLAUDE.md reads this — no glob needed)
|
|
203
|
+
echo "$EGREGORE_SESSION_ID" > "$SCRIPT_DIR/.egregore-session-id"
|
|
204
|
+
|
|
205
|
+
# Model stamp hashes the git common-dir root because telemetry.sh resolves it that way.
|
|
206
|
+
MODEL_REPO_ROOT=$(git -C "$SCRIPT_DIR" rev-parse --path-format=absolute --git-common-dir 2>/dev/null | sed 's|/\.git$||') || MODEL_REPO_ROOT="$SCRIPT_DIR"
|
|
207
|
+
MODEL_PROJ_HASH=$(echo -n "$MODEL_REPO_ROOT" | md5 2>/dev/null || echo -n "$MODEL_REPO_ROOT" | md5sum 2>/dev/null | cut -d' ' -f1)
|
|
208
|
+
MODEL_STAMP_FILE="$SESSION_ID_DIR/session-model-${MODEL_PROJ_HASH}"
|
|
209
|
+
if [ -n "${CLAUDE_MODEL:-}" ]; then
|
|
210
|
+
echo "$CLAUDE_MODEL" > "$MODEL_STAMP_FILE"
|
|
211
|
+
else
|
|
212
|
+
rm -f "$MODEL_STAMP_FILE"
|
|
213
|
+
fi
|
|
@@ -0,0 +1,374 @@
|
|
|
1
|
+
# shellcheck shell=bash
|
|
2
|
+
# metrics.sh — Momentum metrics gathering and rendering for startup greetings.
|
|
3
|
+
#
|
|
4
|
+
# Function-only library. Safe to source from bash or zsh.
|
|
5
|
+
|
|
6
|
+
_metrics_zero_json() {
|
|
7
|
+
printf '%s\n' '{"source":"local","sessions":{"buckets":[0,0,0,0,0],"week":0,"prev":0,"all":0},"commits":{"buckets":[0,0,0,0,0],"week":0,"prev":0,"authors":0,"all":0},"handoffs":{"buckets":[0,0,0,0,0],"week":0,"prev":0,"avg_resolution_days":null,"all":0},"knowledge":{"buckets":[0,0,0,0,0],"week":0,"prev":0,"all":0},"members":{"active":0,"total":0}}'
|
|
8
|
+
}
|
|
9
|
+
|
|
10
|
+
_num() {
|
|
11
|
+
awk '{n=$1+0; if (n < 0) n=0; printf "%d\n", n}' 2>/dev/null <<EOF
|
|
12
|
+
$1
|
|
13
|
+
EOF
|
|
14
|
+
}
|
|
15
|
+
|
|
16
|
+
_num_float() {
|
|
17
|
+
awk '{n=$1+0; if (n < 0) n=0; printf "%.1f\n", n}' 2>/dev/null <<EOF
|
|
18
|
+
$1
|
|
19
|
+
EOF
|
|
20
|
+
}
|
|
21
|
+
|
|
22
|
+
_normalize_buckets() {
|
|
23
|
+
set -- $(printf '%s' "$1")
|
|
24
|
+
printf '%d %d %d %d %d\n' "$(_num "${1:-0}")" "$(_num "${2:-0}")" "$(_num "${3:-0}")" "$(_num "${4:-0}")" "$(_num "${5:-0}")"
|
|
25
|
+
}
|
|
26
|
+
|
|
27
|
+
_buckets_json() {
|
|
28
|
+
set -- $(printf '%s' "$(_normalize_buckets "$1")")
|
|
29
|
+
jq -n --argjson a "$(_num "${1:-0}")" --argjson b "$(_num "${2:-0}")" \
|
|
30
|
+
--argjson c "$(_num "${3:-0}")" --argjson d "$(_num "${4:-0}")" \
|
|
31
|
+
--argjson e "$(_num "${5:-0}")" '[$a,$b,$c,$d,$e]' 2>/dev/null || echo '[0,0,0,0,0]'
|
|
32
|
+
}
|
|
33
|
+
|
|
34
|
+
_bucket_week() {
|
|
35
|
+
set -- $(printf '%s' "$(_normalize_buckets "$1")")
|
|
36
|
+
_num "${5:-0}"
|
|
37
|
+
}
|
|
38
|
+
|
|
39
|
+
_bucket_prev() {
|
|
40
|
+
set -- $(printf '%s' "$(_normalize_buckets "$1")")
|
|
41
|
+
_num "${4:-0}"
|
|
42
|
+
}
|
|
43
|
+
|
|
44
|
+
_spark() {
|
|
45
|
+
local values max out v idx glyph
|
|
46
|
+
values="${1:-0 0 0 0 0}"
|
|
47
|
+
max=0
|
|
48
|
+
set -- $(printf '%s' "$values")
|
|
49
|
+
[ "$#" -eq 0 ] && set -- 0 0 0 0 0
|
|
50
|
+
for v in "$@"; do
|
|
51
|
+
v=$(_num "$v")
|
|
52
|
+
[ "$v" -gt "$max" ] 2>/dev/null && max="$v"
|
|
53
|
+
done
|
|
54
|
+
out=""
|
|
55
|
+
for v in "$@"; do
|
|
56
|
+
v=$(_num "$v")
|
|
57
|
+
if [ "$max" -le 0 ] 2>/dev/null; then
|
|
58
|
+
idx=0
|
|
59
|
+
else
|
|
60
|
+
idx=$(( (v * 7) / max ))
|
|
61
|
+
fi
|
|
62
|
+
# Select glyphs explicitly: substring slicing can split UTF-8 characters
|
|
63
|
+
# under Bash 3.2 or a C locale.
|
|
64
|
+
case "$idx" in
|
|
65
|
+
0) glyph="▁" ;;
|
|
66
|
+
1) glyph="▂" ;;
|
|
67
|
+
2) glyph="▃" ;;
|
|
68
|
+
3) glyph="▄" ;;
|
|
69
|
+
4) glyph="▅" ;;
|
|
70
|
+
5) glyph="▆" ;;
|
|
71
|
+
6) glyph="▇" ;;
|
|
72
|
+
*) glyph="█" ;;
|
|
73
|
+
esac
|
|
74
|
+
out="${out}${glyph}"
|
|
75
|
+
done
|
|
76
|
+
printf '%s\n' "$out"
|
|
77
|
+
}
|
|
78
|
+
|
|
79
|
+
_pct_delta() {
|
|
80
|
+
local cur prev pct
|
|
81
|
+
cur=$(_num "${1:-0}")
|
|
82
|
+
prev=$(_num "${2:-0}")
|
|
83
|
+
[ "$prev" -le 0 ] 2>/dev/null && return 0
|
|
84
|
+
pct=$(( ((cur - prev) * 100) / prev ))
|
|
85
|
+
if [ "$pct" -gt 0 ] 2>/dev/null; then
|
|
86
|
+
printf '↑ %d%%\n' "$pct"
|
|
87
|
+
elif [ "$pct" -lt 0 ] 2>/dev/null; then
|
|
88
|
+
printf '↓ %d%%\n' "$(( -pct ))"
|
|
89
|
+
else
|
|
90
|
+
printf '→ 0%%\n'
|
|
91
|
+
fi
|
|
92
|
+
}
|
|
93
|
+
|
|
94
|
+
_commafy() {
|
|
95
|
+
awk '
|
|
96
|
+
function comma(s, out, sign) {
|
|
97
|
+
s = int(s + 0)
|
|
98
|
+
if (s < 0) { sign = "-"; s = -s } else { sign = "" }
|
|
99
|
+
s = sprintf("%d", s)
|
|
100
|
+
out = ""
|
|
101
|
+
while (length(s) > 3) {
|
|
102
|
+
out = "," substr(s, length(s) - 2, 3) out
|
|
103
|
+
s = substr(s, 1, length(s) - 3)
|
|
104
|
+
}
|
|
105
|
+
return sign s out
|
|
106
|
+
}
|
|
107
|
+
{ print comma($1) }
|
|
108
|
+
' 2>/dev/null <<EOF
|
|
109
|
+
${1:-0}
|
|
110
|
+
EOF
|
|
111
|
+
}
|
|
112
|
+
|
|
113
|
+
_git_added_buckets() {
|
|
114
|
+
local repo now paths
|
|
115
|
+
repo="$1"
|
|
116
|
+
shift
|
|
117
|
+
now=$(date +%s)
|
|
118
|
+
if [ -d "$repo" ] || [ -f "$repo" ]; then
|
|
119
|
+
git -C "$repo" log --diff-filter=A --since="35 days ago" --format='%ct' -- "$@" 2>/dev/null | \
|
|
120
|
+
awk -v now="$now" '
|
|
121
|
+
BEGIN { for (i=0;i<5;i++) b[i]=0 }
|
|
122
|
+
/^[0-9]+$/ {
|
|
123
|
+
days = int((now - $1) / 86400)
|
|
124
|
+
idx = 4 - int(days / 7)
|
|
125
|
+
if (idx >= 0 && idx < 5) b[idx]++
|
|
126
|
+
}
|
|
127
|
+
END { printf "%d %d %d %d %d\n", b[0], b[1], b[2], b[3], b[4] }
|
|
128
|
+
' 2>/dev/null || echo "0 0 0 0 0"
|
|
129
|
+
else
|
|
130
|
+
echo "0 0 0 0 0"
|
|
131
|
+
fi
|
|
132
|
+
}
|
|
133
|
+
|
|
134
|
+
_find_count_md() {
|
|
135
|
+
find -L "$@" -name '*.md' ! -name 'index*' 2>/dev/null | wc -l | awk '{print $1+0}' 2>/dev/null || echo 0
|
|
136
|
+
}
|
|
137
|
+
|
|
138
|
+
_metrics_gather() {
|
|
139
|
+
local _root _mem _scratch _API_URL _API_KEY _connected
|
|
140
|
+
_root="${SCRIPT_DIR:-$PWD}"
|
|
141
|
+
_mem="$_root/memory"
|
|
142
|
+
_scratch=$(mktemp -d 2>/dev/null || mktemp -d -t egregore-metrics)
|
|
143
|
+
_API_URL=$(jq -r '.api_url // empty' "$_root/egregore.json" 2>/dev/null || echo "")
|
|
144
|
+
_API_KEY=$(grep '^EGREGORE_API_KEY=' "${ENV_FILE:-$_root/.env}" 2>/dev/null | cut -d'=' -f2- || true)
|
|
145
|
+
_connected=false
|
|
146
|
+
[ -n "$_API_URL" ] && [ -n "$_API_KEY" ] && _connected=true
|
|
147
|
+
|
|
148
|
+
(
|
|
149
|
+
if [ "$_connected" = true ]; then
|
|
150
|
+
raw=$(bash "$_root/bin/graph.sh" query "MATCH (s:Session) WHERE date(s.date) >= date() - duration('P35D')
|
|
151
|
+
OPTIONAL MATCH (s)-[:BY]->(p:Person)
|
|
152
|
+
WITH duration.inDays(date(s.date), date()).days / 7 AS weeksAgo,
|
|
153
|
+
count(s) AS sessions, count(DISTINCT p) AS people
|
|
154
|
+
RETURN weeksAgo, sessions, people ORDER BY weeksAgo" 2>/dev/null || echo "")
|
|
155
|
+
printf '%s' "$raw" | jq -r '
|
|
156
|
+
(.values // []) as $v
|
|
157
|
+
| if ($v|length) == 0 then empty else
|
|
158
|
+
reduce $v[] as $r ({b:[0,0,0,0,0], a:0, ok:0};
|
|
159
|
+
($r[0] // 99 | tonumber? // 99) as $w
|
|
160
|
+
| if $w >= 0 and $w <= 4 then
|
|
161
|
+
.b[4 - $w] = (($r[1] // 0 | tonumber? // 0) | floor)
|
|
162
|
+
| .ok = 1
|
|
163
|
+
| if $w == 0 then .a = (($r[2] // 0 | tonumber? // 0) | floor) else . end
|
|
164
|
+
else . end)
|
|
165
|
+
| "\(.b|join(" "))|\(.a)|\(.ok)"
|
|
166
|
+
end
|
|
167
|
+
' 2>/dev/null || echo "0 0 0 0 0|0|0"
|
|
168
|
+
else
|
|
169
|
+
echo "0 0 0 0 0|0|0"
|
|
170
|
+
fi
|
|
171
|
+
) > "$_scratch/graph_sessions" 2>/dev/null &
|
|
172
|
+
|
|
173
|
+
(
|
|
174
|
+
if [ "$_connected" = true ]; then
|
|
175
|
+
raw=$(bash "$_root/bin/graph.sh" query "MATCH (s:Session) WITH count(s) AS totalSessions MATCH (p:Person)-[:MEMBER_OF]->(:Org) RETURN totalSessions, count(DISTINCT p) AS members" 2>/dev/null || echo "")
|
|
176
|
+
total=$(printf '%s' "$raw" | jq -r '.values[0][0] // 0' 2>/dev/null || echo 0)
|
|
177
|
+
members=$(printf '%s' "$raw" | jq -r '.values[0][1] // 0' 2>/dev/null || echo 0)
|
|
178
|
+
if [ "$(_num "$members")" -eq 0 ] 2>/dev/null; then
|
|
179
|
+
raw2=$(bash "$_root/bin/graph.sh" query "MATCH (p:Person) RETURN count(p)" 2>/dev/null || echo "")
|
|
180
|
+
members=$(printf '%s' "$raw2" | jq -r '.values[0][0] // 0' 2>/dev/null || echo 0)
|
|
181
|
+
fi
|
|
182
|
+
printf '%s|%s\n' "$(_num "$total")" "$(_num "$members")"
|
|
183
|
+
else
|
|
184
|
+
echo "0|0"
|
|
185
|
+
fi
|
|
186
|
+
) > "$_scratch/graph_totals" 2>/dev/null &
|
|
187
|
+
|
|
188
|
+
(
|
|
189
|
+
if [ "$_connected" = true ]; then
|
|
190
|
+
raw=$(bash "$_root/bin/graph.sh" query "MATCH (s:Session)-[:HANDED_TO]->(:Person)
|
|
191
|
+
WHERE s.handoffStatus = 'done' AND date(s.date) >= date() - duration('P30D')
|
|
192
|
+
AND s.handoffReadDate IS NOT NULL
|
|
193
|
+
WITH duration.inDays(date(s.date), date(s.handoffReadDate)).days AS d
|
|
194
|
+
RETURN avg(d) AS avgDays, count(*) AS n" 2>/dev/null || echo "")
|
|
195
|
+
avg=$(printf '%s' "$raw" | jq -r '.values[0][0] // empty' 2>/dev/null || echo "")
|
|
196
|
+
n=$(printf '%s' "$raw" | jq -r '.values[0][1] // 0' 2>/dev/null || echo 0)
|
|
197
|
+
if [ "$(_num "$n")" -gt 0 ] 2>/dev/null && [ -n "$avg" ]; then _num_float "$avg"; else echo ""; fi
|
|
198
|
+
else
|
|
199
|
+
echo ""
|
|
200
|
+
fi
|
|
201
|
+
) > "$_scratch/handoff_resolution" 2>/dev/null &
|
|
202
|
+
|
|
203
|
+
(
|
|
204
|
+
buckets=$(_git_added_buckets "$_mem" sessions wraps)
|
|
205
|
+
all=$(_find_count_md "$_root/memory/sessions" "$_root/memory/wraps")
|
|
206
|
+
printf '%s|%s\n' "$buckets" "$all"
|
|
207
|
+
) > "$_scratch/local_sessions" 2>/dev/null &
|
|
208
|
+
|
|
209
|
+
(
|
|
210
|
+
now=$(date +%s)
|
|
211
|
+
if [ -d "$_mem" ] || [ -f "$_mem" ]; then
|
|
212
|
+
git -C "$_mem" log --since="35 days ago" --format='%ct|%ae' 2>/dev/null | \
|
|
213
|
+
awk -F'|' -v now="$now" '
|
|
214
|
+
BEGIN { for (i=0;i<5;i++) b[i]=0 }
|
|
215
|
+
{
|
|
216
|
+
days = int((now - $1) / 86400)
|
|
217
|
+
idx = 4 - int(days / 7)
|
|
218
|
+
if (idx >= 0 && idx < 5) {
|
|
219
|
+
b[idx]++
|
|
220
|
+
if (idx == 4 && $2 != "") a[$2]=1
|
|
221
|
+
}
|
|
222
|
+
}
|
|
223
|
+
END {
|
|
224
|
+
n=0; for (k in a) n++
|
|
225
|
+
printf "%d %d %d %d %d|%d\n", b[0], b[1], b[2], b[3], b[4], n
|
|
226
|
+
}
|
|
227
|
+
' 2>/dev/null || echo "0 0 0 0 0|0"
|
|
228
|
+
else
|
|
229
|
+
echo "0 0 0 0 0|0"
|
|
230
|
+
fi
|
|
231
|
+
) > "$_scratch/commits" 2>/dev/null &
|
|
232
|
+
|
|
233
|
+
(
|
|
234
|
+
if [ -d "$_mem" ] || [ -f "$_mem" ]; then git -C "$_mem" rev-list --count HEAD 2>/dev/null || echo 0; else echo 0; fi
|
|
235
|
+
) > "$_scratch/commits_all" 2>/dev/null &
|
|
236
|
+
|
|
237
|
+
(
|
|
238
|
+
buckets=$(_git_added_buckets "$_mem" handoffs)
|
|
239
|
+
all=$(_find_count_md "$_root/memory/handoffs")
|
|
240
|
+
printf '%s|%s\n' "$buckets" "$all"
|
|
241
|
+
) > "$_scratch/handoffs" 2>/dev/null &
|
|
242
|
+
|
|
243
|
+
(
|
|
244
|
+
buckets=$(_git_added_buckets "$_mem" knowledge/decisions knowledge/findings knowledge/patterns)
|
|
245
|
+
all=$(_find_count_md "$_root/memory/knowledge/decisions" "$_root/memory/knowledge/findings" "$_root/memory/knowledge/patterns")
|
|
246
|
+
printf '%s|%s\n' "$buckets" "$all"
|
|
247
|
+
) > "$_scratch/knowledge" 2>/dev/null &
|
|
248
|
+
|
|
249
|
+
(
|
|
250
|
+
_find_count_md "$_root/memory/people"
|
|
251
|
+
) > "$_scratch/members_total_local" 2>/dev/null &
|
|
252
|
+
|
|
253
|
+
wait
|
|
254
|
+
|
|
255
|
+
gs=$(cat "$_scratch/graph_sessions" 2>/dev/null || echo "0 0 0 0 0|0|0")
|
|
256
|
+
gt=$(cat "$_scratch/graph_totals" 2>/dev/null || echo "0|0")
|
|
257
|
+
lsess=$(cat "$_scratch/local_sessions" 2>/dev/null || echo "0 0 0 0 0|0")
|
|
258
|
+
commits=$(cat "$_scratch/commits" 2>/dev/null || echo "0 0 0 0 0|0")
|
|
259
|
+
handoffs=$(cat "$_scratch/handoffs" 2>/dev/null || echo "0 0 0 0 0|0")
|
|
260
|
+
knowledge=$(cat "$_scratch/knowledge" 2>/dev/null || echo "0 0 0 0 0|0")
|
|
261
|
+
|
|
262
|
+
graph_valid=$(_num "$(printf '%s' "$gs" | awk -F'|' '{print $3}')")
|
|
263
|
+
if [ "$graph_valid" -gt 0 ] 2>/dev/null; then
|
|
264
|
+
source_name="graph"
|
|
265
|
+
session_buckets=$(_normalize_buckets "$(printf '%s' "$gs" | awk -F'|' '{print $1}')")
|
|
266
|
+
session_all=$(_num "$(printf '%s' "$gt" | awk -F'|' '{print $1}')")
|
|
267
|
+
members_active=$(_num "$(printf '%s' "$gs" | awk -F'|' '{print $2}')")
|
|
268
|
+
members_total=$(_num "$(printf '%s' "$gt" | awk -F'|' '{print $2}')")
|
|
269
|
+
if [ "$session_all" -le 0 ] 2>/dev/null; then
|
|
270
|
+
session_all=$(_num "$(printf '%s' "$lsess" | awk -F'|' '{print $2}')")
|
|
271
|
+
fi
|
|
272
|
+
if [ "$members_total" -le 0 ] 2>/dev/null; then
|
|
273
|
+
members_total=$(_num "$(cat "$_scratch/members_total_local" 2>/dev/null || echo 0)")
|
|
274
|
+
fi
|
|
275
|
+
else
|
|
276
|
+
source_name="local"
|
|
277
|
+
session_buckets=$(_normalize_buckets "$(printf '%s' "$lsess" | awk -F'|' '{print $1}')")
|
|
278
|
+
session_all=$(_num "$(printf '%s' "$lsess" | awk -F'|' '{print $2}')")
|
|
279
|
+
members_active=$(_num "$(printf '%s' "$commits" | awk -F'|' '{print $2}')")
|
|
280
|
+
members_total=$(_num "$(cat "$_scratch/members_total_local" 2>/dev/null || echo 0)")
|
|
281
|
+
fi
|
|
282
|
+
|
|
283
|
+
commit_buckets=$(_normalize_buckets "$(printf '%s' "$commits" | awk -F'|' '{print $1}')")
|
|
284
|
+
handoff_buckets=$(_normalize_buckets "$(printf '%s' "$handoffs" | awk -F'|' '{print $1}')")
|
|
285
|
+
knowledge_buckets=$(_normalize_buckets "$(printf '%s' "$knowledge" | awk -F'|' '{print $1}')")
|
|
286
|
+
avg_res=$(cat "$_scratch/handoff_resolution" 2>/dev/null || echo "")
|
|
287
|
+
|
|
288
|
+
session_buckets_json=$(_buckets_json "$session_buckets")
|
|
289
|
+
commit_buckets_json=$(_buckets_json "$commit_buckets")
|
|
290
|
+
handoff_buckets_json=$(_buckets_json "$handoff_buckets")
|
|
291
|
+
knowledge_buckets_json=$(_buckets_json "$knowledge_buckets")
|
|
292
|
+
|
|
293
|
+
if [ -n "$avg_res" ]; then
|
|
294
|
+
jq -n --arg source "$source_name" \
|
|
295
|
+
--argjson sb "$session_buckets_json" --argjson sw "$(_bucket_week "$session_buckets")" --argjson sp "$(_bucket_prev "$session_buckets")" --argjson sall "$session_all" \
|
|
296
|
+
--argjson cb "$commit_buckets_json" --argjson cw "$(_bucket_week "$commit_buckets")" --argjson cp "$(_bucket_prev "$commit_buckets")" --argjson ca "$(_num "$(printf '%s' "$commits" | awk -F'|' '{print $2}')")" --argjson call "$(_num "$(cat "$_scratch/commits_all" 2>/dev/null || echo 0)")" \
|
|
297
|
+
--argjson hb "$handoff_buckets_json" --argjson hw "$(_bucket_week "$handoff_buckets")" --argjson hp "$(_bucket_prev "$handoff_buckets")" --argjson havg "$avg_res" --argjson hall "$(_num "$(printf '%s' "$handoffs" | awk -F'|' '{print $2}')")" \
|
|
298
|
+
--argjson kb "$knowledge_buckets_json" --argjson kw "$(_bucket_week "$knowledge_buckets")" --argjson kp "$(_bucket_prev "$knowledge_buckets")" --argjson kall "$(_num "$(printf '%s' "$knowledge" | awk -F'|' '{print $2}')")" \
|
|
299
|
+
--argjson ma "$members_active" --argjson mt "$members_total" \
|
|
300
|
+
'{source:$source,sessions:{buckets:$sb,week:$sw,prev:$sp,all:$sall},commits:{buckets:$cb,week:$cw,prev:$cp,authors:$ca,all:$call},handoffs:{buckets:$hb,week:$hw,prev:$hp,avg_resolution_days:$havg,all:$hall},knowledge:{buckets:$kb,week:$kw,prev:$kp,all:$kall},members:{active:$ma,total:$mt}}' 2>/dev/null || _metrics_zero_json
|
|
301
|
+
else
|
|
302
|
+
jq -n --arg source "$source_name" \
|
|
303
|
+
--argjson sb "$session_buckets_json" --argjson sw "$(_bucket_week "$session_buckets")" --argjson sp "$(_bucket_prev "$session_buckets")" --argjson sall "$session_all" \
|
|
304
|
+
--argjson cb "$commit_buckets_json" --argjson cw "$(_bucket_week "$commit_buckets")" --argjson cp "$(_bucket_prev "$commit_buckets")" --argjson ca "$(_num "$(printf '%s' "$commits" | awk -F'|' '{print $2}')")" --argjson call "$(_num "$(cat "$_scratch/commits_all" 2>/dev/null || echo 0)")" \
|
|
305
|
+
--argjson hb "$handoff_buckets_json" --argjson hw "$(_bucket_week "$handoff_buckets")" --argjson hp "$(_bucket_prev "$handoff_buckets")" --argjson hall "$(_num "$(printf '%s' "$handoffs" | awk -F'|' '{print $2}')")" \
|
|
306
|
+
--argjson kb "$knowledge_buckets_json" --argjson kw "$(_bucket_week "$knowledge_buckets")" --argjson kp "$(_bucket_prev "$knowledge_buckets")" --argjson kall "$(_num "$(printf '%s' "$knowledge" | awk -F'|' '{print $2}')")" \
|
|
307
|
+
--argjson ma "$members_active" --argjson mt "$members_total" \
|
|
308
|
+
'{source:$source,sessions:{buckets:$sb,week:$sw,prev:$sp,all:$sall},commits:{buckets:$cb,week:$cw,prev:$cp,authors:$ca,all:$call},handoffs:{buckets:$hb,week:$hw,prev:$hp,avg_resolution_days:null,all:$hall},knowledge:{buckets:$kb,week:$kw,prev:$kp,all:$kall},members:{active:$ma,total:$mt}}' 2>/dev/null || _metrics_zero_json
|
|
309
|
+
fi
|
|
310
|
+
rm -rf "$_scratch" 2>/dev/null || true
|
|
311
|
+
}
|
|
312
|
+
|
|
313
|
+
_metrics_read() {
|
|
314
|
+
local file filter fallback
|
|
315
|
+
file="${CTX_DIR:-}/metrics"
|
|
316
|
+
filter="$1"
|
|
317
|
+
fallback="$2"
|
|
318
|
+
if [ -f "$file" ]; then
|
|
319
|
+
jq -r "$filter" "$file" 2>/dev/null || echo "$fallback"
|
|
320
|
+
else
|
|
321
|
+
echo "$fallback"
|
|
322
|
+
fi
|
|
323
|
+
}
|
|
324
|
+
|
|
325
|
+
_render_momentum_board() {
|
|
326
|
+
local separator line_width header_left header_right pad
|
|
327
|
+
local sb sw sp sall cb cw ca call hb hw havg hall kb kw kall active total
|
|
328
|
+
local sdelta sann cann hann kann know_week
|
|
329
|
+
separator="${SEPARATOR:- ┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄}"
|
|
330
|
+
line_width="${LINE_WIDTH:-67}"
|
|
331
|
+
|
|
332
|
+
sb=$(_metrics_read '(.sessions.buckets // [0,0,0,0,0]) | .[0:5] | map(. // 0) | join(" ")' "0 0 0 0 0")
|
|
333
|
+
sw=$(_num "$(_metrics_read '.sessions.week // 0' "0")")
|
|
334
|
+
sp=$(_num "$(_metrics_read '.sessions.prev // 0' "0")")
|
|
335
|
+
sall=$(_num "$(_metrics_read '.sessions.all // 0' "0")")
|
|
336
|
+
cb=$(_metrics_read '(.commits.buckets // [0,0,0,0,0]) | .[0:5] | map(. // 0) | join(" ")' "0 0 0 0 0")
|
|
337
|
+
cw=$(_num "$(_metrics_read '.commits.week // 0' "0")")
|
|
338
|
+
ca=$(_num "$(_metrics_read '.commits.authors // 0' "0")")
|
|
339
|
+
call=$(_num "$(_metrics_read '.commits.all // 0' "0")")
|
|
340
|
+
hb=$(_metrics_read '(.handoffs.buckets // [0,0,0,0,0]) | .[0:5] | map(. // 0) | join(" ")' "0 0 0 0 0")
|
|
341
|
+
hw=$(_num "$(_metrics_read '.handoffs.week // 0' "0")")
|
|
342
|
+
havg=$(_metrics_read '.handoffs.avg_resolution_days // empty' "")
|
|
343
|
+
hall=$(_num "$(_metrics_read '.handoffs.all // 0' "0")")
|
|
344
|
+
kb=$(_metrics_read '(.knowledge.buckets // [0,0,0,0,0]) | .[0:5] | map(. // 0) | join(" ")' "0 0 0 0 0")
|
|
345
|
+
kw=$(_num "$(_metrics_read '.knowledge.week // 0' "0")")
|
|
346
|
+
kall=$(_num "$(_metrics_read '.knowledge.all // 0' "0")")
|
|
347
|
+
active=$(_num "$(_metrics_read '.members.active // 0' "0")")
|
|
348
|
+
total=$(_num "$(_metrics_read '.members.total // 0' "0")")
|
|
349
|
+
|
|
350
|
+
header_left=" ◦ momentum · this week"
|
|
351
|
+
header_right="${active} of ${total} active"
|
|
352
|
+
pad=$((line_width - ${#header_left} - ${#header_right}))
|
|
353
|
+
[ "$pad" -lt 1 ] && pad=1
|
|
354
|
+
printf "%s%*s%s\n" "$header_left" "$pad" "" "$header_right"
|
|
355
|
+
|
|
356
|
+
sdelta=$(_pct_delta "$sw" "$sp")
|
|
357
|
+
sann=""
|
|
358
|
+
[ -n "$sdelta" ] && sann="${sdelta} vs last week"
|
|
359
|
+
cann=""
|
|
360
|
+
if [ "$ca" -gt 0 ] 2>/dev/null; then
|
|
361
|
+
if [ "$ca" -eq 1 ] 2>/dev/null; then cann="1 author"; else cann="${ca} authors"; fi
|
|
362
|
+
fi
|
|
363
|
+
hann=""
|
|
364
|
+
if [ -n "$havg" ]; then hann="$(_num_float "$havg")d avg resolution"; fi
|
|
365
|
+
kann="$(_commafy "$kall") artifacts total"
|
|
366
|
+
know_week="+${kw}"
|
|
367
|
+
|
|
368
|
+
printf " %-11s%5s 5-week %s %s\n\n" "sessions" "$sw" "$(_spark "$sb")" "$sann"
|
|
369
|
+
printf " %-11s%5s 5-week %s %s\n\n" "commits" "$cw" "$(_spark "$cb")" "$cann"
|
|
370
|
+
printf " %-11s%5s 5-week %s %s\n\n" "handoffs" "$hw" "$(_spark "$hb")" "$hann"
|
|
371
|
+
printf " %-11s%5s 5-week %s %s\n" "knowledge" "$know_week" "$(_spark "$kb")" "$kann"
|
|
372
|
+
echo "$separator"
|
|
373
|
+
printf " %s sessions · %s commits · %s handoffs all-time\n" "$(_commafy "$sall")" "$(_commafy "$call")" "$(_commafy "$hall")"
|
|
374
|
+
}
|
|
@@ -0,0 +1,31 @@
|
|
|
1
|
+
#!/usr/bin/env bash
|
|
2
|
+
# noncode.sh — shared "non-coding change" classifier for auto-merge decisions.
|
|
3
|
+
#
|
|
4
|
+
# The org rule: non-coding PRs auto-merge to develop; code goes to review.
|
|
5
|
+
# Non-coding means:
|
|
6
|
+
# - any .md file, anywhere
|
|
7
|
+
# - anything under content directories (artifacts/, docs/, .threads/) —
|
|
8
|
+
# html/css/images/design bundles there are authored content, not shipped code
|
|
9
|
+
# - session-state droppings (.egregore-worktree-tty)
|
|
10
|
+
# Everything else — bin/, api/, packages/, .claude/, site 2/, root config — is
|
|
11
|
+
# code and stays open for review.
|
|
12
|
+
#
|
|
13
|
+
# Sourced by handoff-save-egregore.sh, session-autosave.sh, agent.sh, and the
|
|
14
|
+
# /save skill. Keep the policy HERE — call sites must not grow their own.
|
|
15
|
+
|
|
16
|
+
# noncode_filter — reads paths on stdin, prints the first code-bearing path.
|
|
17
|
+
# Empty output = everything is non-coding.
|
|
18
|
+
noncode_filter() {
|
|
19
|
+
grep -Ev '\.md$' \
|
|
20
|
+
| grep -Ev '^(artifacts|docs|\.threads)/' \
|
|
21
|
+
| grep -Ev '^\.egregore-worktree-tty$' \
|
|
22
|
+
| head -1 || true
|
|
23
|
+
}
|
|
24
|
+
|
|
25
|
+
# noncode_blockers [base-ref] [repo-dir] — first code-bearing path committed
|
|
26
|
+
# on HEAD relative to base (three-dot: only our side of the diff).
|
|
27
|
+
# Empty output = the branch is non-coding and safe to auto-merge.
|
|
28
|
+
noncode_blockers() {
|
|
29
|
+
local base="${1:-origin/develop}" dir="${2:-.}"
|
|
30
|
+
git -C "$dir" diff "$base...HEAD" --name-only 2>/dev/null | noncode_filter
|
|
31
|
+
}
|