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,304 @@
|
|
|
1
|
+
"""Look at a folder of documents before asking its owner anything about it.
|
|
2
|
+
|
|
3
|
+
Setting up a knowledge base needs three decisions: what must be kept apart, which
|
|
4
|
+
sources win when two disagree, and what language the documents are written in.
|
|
5
|
+
Asked cold, none of them are answerable. Someone who has just dropped a folder on
|
|
6
|
+
a machine cannot say "what must never mix" — the question is about a model of the
|
|
7
|
+
system, not about their files.
|
|
8
|
+
|
|
9
|
+
So this looks first. It reports the groups the folder already has, the kinds of
|
|
10
|
+
document inside it, and the language it can detect. The questions that follow can
|
|
11
|
+
then name the user's own directories and counts, and be answered yes or no.
|
|
12
|
+
|
|
13
|
+
Everything here is counting and pattern-matching. It proposes; it never decides.
|
|
14
|
+
Where it cannot tell — a language it does not recognise, a folder with no obvious
|
|
15
|
+
grouping — it says so, because a confident wrong grouping is harder to notice
|
|
16
|
+
than an admitted gap.
|
|
17
|
+
"""
|
|
18
|
+
|
|
19
|
+
from __future__ import annotations
|
|
20
|
+
|
|
21
|
+
import re
|
|
22
|
+
from collections import Counter
|
|
23
|
+
from dataclasses import dataclass, field
|
|
24
|
+
from pathlib import Path
|
|
25
|
+
|
|
26
|
+
# Extensions worth reading. Anything else is counted and reported, not parsed.
|
|
27
|
+
DOCUMENT_SUFFIXES = {".pdf", ".md", ".txt", ".docx", ".doc", ".rtf", ".html", ".htm"}
|
|
28
|
+
CATALOGUE_SUFFIXES = {".csv", ".xlsx", ".xls", ".tsv"}
|
|
29
|
+
|
|
30
|
+
# A group needs enough documents to be worth separating. Below this it is noise —
|
|
31
|
+
# a stray folder, a scratch directory — and offering it as a boundary would ask
|
|
32
|
+
# the user to rule on something that does not matter.
|
|
33
|
+
MIN_GROUP = 5
|
|
34
|
+
|
|
35
|
+
# Short, very common words that are distinctive to one language. Detection here
|
|
36
|
+
# is deliberately crude: it only has to be right often enough to propose, and it
|
|
37
|
+
# reports nothing rather than guessing when the evidence is thin.
|
|
38
|
+
LANGUAGE_MARKERS = {
|
|
39
|
+
"turkish": {"ve", "ile", "için", "olarak", "bir", "bu", "daha", "gibi", "olan"},
|
|
40
|
+
"english": {"the", "and", "for", "with", "that", "this", "from", "are", "which"},
|
|
41
|
+
"german": {"und", "der", "die", "das", "mit", "für", "eine", "nicht", "auch"},
|
|
42
|
+
"french": {"les", "des", "est", "pour", "dans", "une", "sur", "que", "par"},
|
|
43
|
+
"spanish": {"los", "las", "por", "para", "con", "una", "que", "del", "como"},
|
|
44
|
+
"italian": {"che", "per", "con", "una", "del", "sono", "nella", "alla", "dei"},
|
|
45
|
+
}
|
|
46
|
+
WORD = re.compile(r"[^\W\d_]{2,}", re.UNICODE)
|
|
47
|
+
|
|
48
|
+
|
|
49
|
+
@dataclass
|
|
50
|
+
class Group:
|
|
51
|
+
"""A directory holding enough documents to be worth keeping separate."""
|
|
52
|
+
|
|
53
|
+
name: str
|
|
54
|
+
path: str
|
|
55
|
+
documents: int
|
|
56
|
+
|
|
57
|
+
def as_dict(self) -> dict:
|
|
58
|
+
return {"name": self.name, "path": self.path, "documents": self.documents}
|
|
59
|
+
|
|
60
|
+
|
|
61
|
+
@dataclass
|
|
62
|
+
class Survey:
|
|
63
|
+
root: str = ""
|
|
64
|
+
documents: int = 0
|
|
65
|
+
unreadable: int = 0
|
|
66
|
+
groups: list = field(default_factory=list)
|
|
67
|
+
by_suffix: dict = field(default_factory=dict)
|
|
68
|
+
catalogues: list = field(default_factory=list)
|
|
69
|
+
language: str = "unknown"
|
|
70
|
+
language_evidence: dict = field(default_factory=dict)
|
|
71
|
+
language_by_group: dict = field(default_factory=dict)
|
|
72
|
+
sample_titles: list = field(default_factory=list)
|
|
73
|
+
notes: list = field(default_factory=list)
|
|
74
|
+
|
|
75
|
+
@property
|
|
76
|
+
def needs_a_boundary_question(self) -> bool:
|
|
77
|
+
"""Whether separating anything is even plausible.
|
|
78
|
+
|
|
79
|
+
One group means there is nothing to keep apart, so asking would be a
|
|
80
|
+
question with one answer.
|
|
81
|
+
"""
|
|
82
|
+
return len(self.groups) > 1
|
|
83
|
+
|
|
84
|
+
def as_dict(self) -> dict:
|
|
85
|
+
return {
|
|
86
|
+
"root": self.root,
|
|
87
|
+
"documents": self.documents,
|
|
88
|
+
"unreadable": self.unreadable,
|
|
89
|
+
"groups": [g.as_dict() for g in self.groups],
|
|
90
|
+
"by_suffix": self.by_suffix,
|
|
91
|
+
"catalogues": self.catalogues,
|
|
92
|
+
"language": self.language,
|
|
93
|
+
"language_evidence": self.language_evidence,
|
|
94
|
+
"language_by_group": self.language_by_group,
|
|
95
|
+
"sample_titles": self.sample_titles,
|
|
96
|
+
"notes": self.notes,
|
|
97
|
+
}
|
|
98
|
+
|
|
99
|
+
|
|
100
|
+
def detect_language(samples: list) -> tuple:
|
|
101
|
+
"""The language of some text, or that it cannot be told.
|
|
102
|
+
|
|
103
|
+
Returns the name and the per-language hit counts, so a caller can show its
|
|
104
|
+
working rather than assert a result. A near-tie reports unknown: proposing
|
|
105
|
+
the wrong grammar produces a profile that silently finds no advice at all.
|
|
106
|
+
"""
|
|
107
|
+
text = " ".join(samples).lower()
|
|
108
|
+
words = set(WORD.findall(text))
|
|
109
|
+
if len(words) < 20:
|
|
110
|
+
return "unknown", {}
|
|
111
|
+
scores = {lang: len(words & markers) for lang, markers in LANGUAGE_MARKERS.items()}
|
|
112
|
+
ranked = sorted(scores.items(), key=lambda kv: -kv[1])
|
|
113
|
+
best, best_score = ranked[0]
|
|
114
|
+
runner_score = ranked[1][1] if len(ranked) > 1 else 0
|
|
115
|
+
if best_score < 3 or best_score - runner_score < 2:
|
|
116
|
+
return "unknown", scores
|
|
117
|
+
return best, scores
|
|
118
|
+
|
|
119
|
+
|
|
120
|
+
def _read_head(path: Path, limit: int = 4000) -> str:
|
|
121
|
+
"""A little text from a file, for language detection only.
|
|
122
|
+
|
|
123
|
+
PDFs are read too, because a corpus of documents is usually a corpus of
|
|
124
|
+
PDFs. Reading only the plain-text files looks like it works and does not:
|
|
125
|
+
measured on a real 922-document archive, every file but one was a PDF, so
|
|
126
|
+
the language of the whole corpus was decided by a single stray markdown
|
|
127
|
+
file that happened to be lying in it.
|
|
128
|
+
|
|
129
|
+
Only the first page is taken, and a failure is silent — this informs a
|
|
130
|
+
question the user will answer anyway, so it must never be the reason a
|
|
131
|
+
survey fails.
|
|
132
|
+
"""
|
|
133
|
+
suffix = path.suffix.lower()
|
|
134
|
+
try:
|
|
135
|
+
if suffix in {".md", ".txt", ".html", ".htm"}:
|
|
136
|
+
return path.read_text(encoding="utf-8", errors="replace")[:limit]
|
|
137
|
+
if suffix == ".pdf":
|
|
138
|
+
import subprocess
|
|
139
|
+
|
|
140
|
+
out = subprocess.run(
|
|
141
|
+
["pdftotext", "-f", "1", "-l", "1", "-q", str(path), "-"],
|
|
142
|
+
capture_output=True, text=True, timeout=15,
|
|
143
|
+
)
|
|
144
|
+
return (out.stdout or "")[:limit]
|
|
145
|
+
except (OSError, subprocess.SubprocessError, ValueError):
|
|
146
|
+
return ""
|
|
147
|
+
return ""
|
|
148
|
+
|
|
149
|
+
|
|
150
|
+
def survey(root, max_depth: int = 2, sample_files: int = 40) -> Survey:
|
|
151
|
+
"""What is in this folder, described so its owner can recognise it."""
|
|
152
|
+
root_path = Path(root)
|
|
153
|
+
result = Survey(root=str(root_path))
|
|
154
|
+
if not root_path.is_dir():
|
|
155
|
+
result.notes.append(f"{root_path} is not a folder")
|
|
156
|
+
return result
|
|
157
|
+
|
|
158
|
+
suffixes: Counter = Counter()
|
|
159
|
+
per_group: Counter = Counter()
|
|
160
|
+
group_paths: dict = {}
|
|
161
|
+
samples: list = []
|
|
162
|
+
group_samples: dict = {}
|
|
163
|
+
titles: list = []
|
|
164
|
+
|
|
165
|
+
for path in root_path.rglob("*"):
|
|
166
|
+
if not path.is_file():
|
|
167
|
+
continue
|
|
168
|
+
# Any hidden component, not just a hidden filename. A folder holding
|
|
169
|
+
# documents usually sits beside .git or .egregore, and counting those
|
|
170
|
+
# would report machinery as content.
|
|
171
|
+
if any(part.startswith(".") for part in path.relative_to(root_path).parts):
|
|
172
|
+
continue
|
|
173
|
+
suffix = path.suffix.lower()
|
|
174
|
+
if suffix in CATALOGUE_SUFFIXES:
|
|
175
|
+
result.catalogues.append(path.relative_to(root_path).as_posix())
|
|
176
|
+
continue
|
|
177
|
+
suffixes[suffix or "(no extension)"] += 1
|
|
178
|
+
if suffix not in DOCUMENT_SUFFIXES:
|
|
179
|
+
result.unreadable += 1
|
|
180
|
+
continue
|
|
181
|
+
result.documents += 1
|
|
182
|
+
|
|
183
|
+
relative = path.relative_to(root_path)
|
|
184
|
+
# The group is the outermost directory that is not the root itself. Files
|
|
185
|
+
# sitting loose at the top belong to no group.
|
|
186
|
+
if len(relative.parts) > 1:
|
|
187
|
+
depth = min(max_depth, len(relative.parts) - 1)
|
|
188
|
+
key = "/".join(relative.parts[:depth])
|
|
189
|
+
per_group[key] += 1
|
|
190
|
+
group_paths[key] = key
|
|
191
|
+
|
|
192
|
+
if len(titles) < 8:
|
|
193
|
+
titles.append(relative.as_posix())
|
|
194
|
+
if len(samples) < sample_files:
|
|
195
|
+
head = _read_head(path)
|
|
196
|
+
if head:
|
|
197
|
+
samples.append(head)
|
|
198
|
+
if len(relative.parts) > 1:
|
|
199
|
+
head = _read_head(path, limit=1500)
|
|
200
|
+
if head and len(group_samples.setdefault(key, [])) < 6:
|
|
201
|
+
group_samples[key].append(head)
|
|
202
|
+
|
|
203
|
+
result.by_suffix = dict(sorted(suffixes.items(), key=lambda kv: -kv[1]))
|
|
204
|
+
result.sample_titles = titles
|
|
205
|
+
result.groups = [
|
|
206
|
+
Group(name=key.split("/")[-1], path=group_paths[key], documents=count)
|
|
207
|
+
for key, count in sorted(per_group.items(), key=lambda kv: -kv[1])
|
|
208
|
+
if count >= MIN_GROUP
|
|
209
|
+
]
|
|
210
|
+
result.language, result.language_evidence = detect_language(samples)
|
|
211
|
+
for key, heads in group_samples.items():
|
|
212
|
+
lang, _ = detect_language(heads)
|
|
213
|
+
if lang != "unknown":
|
|
214
|
+
result.language_by_group[key] = lang
|
|
215
|
+
# A corpus in two languages needs two sets of grammar. Reporting the majority
|
|
216
|
+
# language would leave every document in the other one silently unread — and
|
|
217
|
+
# nothing downstream would say why they produced no advice.
|
|
218
|
+
distinct = set(result.language_by_group.values())
|
|
219
|
+
if len(distinct) > 1:
|
|
220
|
+
result.language = "mixed"
|
|
221
|
+
result.notes.append(
|
|
222
|
+
"documents are in more than one language (" + ", ".join(sorted(distinct)) +
|
|
223
|
+
"); each language needs its own grammar, or the others yield no advice")
|
|
224
|
+
|
|
225
|
+
if not result.documents:
|
|
226
|
+
result.notes.append("no readable documents found")
|
|
227
|
+
if result.unreadable:
|
|
228
|
+
result.notes.append(
|
|
229
|
+
f"{result.unreadable} files are not a document type this reads; they are ignored")
|
|
230
|
+
if result.documents and len(result.groups) < 2:
|
|
231
|
+
# Fewer than two groups means there is nothing to hold apart, whether
|
|
232
|
+
# that is because the folder is flat or because only one part of it is
|
|
233
|
+
# substantial.
|
|
234
|
+
result.notes.append(
|
|
235
|
+
"nothing here needs separating; one boundary value will cover everything")
|
|
236
|
+
if result.language == "unknown" and result.documents:
|
|
237
|
+
result.notes.append(
|
|
238
|
+
"could not tell the language from the text available — it must be stated, "
|
|
239
|
+
"because finding advice depends on the grammar of the language")
|
|
240
|
+
if result.catalogues:
|
|
241
|
+
result.notes.append(
|
|
242
|
+
f"found {len(result.catalogues)} spreadsheet(s) that may describe these documents")
|
|
243
|
+
return result
|
|
244
|
+
|
|
245
|
+
|
|
246
|
+
def boundary_question(result: Survey) -> dict | None:
|
|
247
|
+
"""The separation question, phrased with the owner's own folder names.
|
|
248
|
+
|
|
249
|
+
Returns None when there is nothing to separate, so the caller asks nothing
|
|
250
|
+
rather than asking a question with one possible answer.
|
|
251
|
+
"""
|
|
252
|
+
if not result.needs_a_boundary_question:
|
|
253
|
+
return None
|
|
254
|
+
names = [g.name for g in result.groups[:3]]
|
|
255
|
+
return {
|
|
256
|
+
"found": [g.as_dict() for g in result.groups],
|
|
257
|
+
"question": (
|
|
258
|
+
f"Your folders are {', '.join(names)}. Are these different SUBJECTS, "
|
|
259
|
+
f"or things that must never be mixed?\n\n"
|
|
260
|
+
f"Separating them means a question about {names[0]} can never be answered "
|
|
261
|
+
f"from {names[1]} — not even when that is where the answer is."
|
|
262
|
+
),
|
|
263
|
+
# Together first: most folder structures are subjects, and separating
|
|
264
|
+
# subjects removes real answers. Keeping them apart is the choice that
|
|
265
|
+
# needs a reason, so it is the one stated second.
|
|
266
|
+
"options": [
|
|
267
|
+
{"label": "Subjects — keep them together",
|
|
268
|
+
"effect": "one boundary value for everything",
|
|
269
|
+
"example": "pruning, fertiliser, pests — a question may need any of them"},
|
|
270
|
+
{"label": f"Must not mix — separate {', '.join(names)}",
|
|
271
|
+
"effect": "one boundary value per folder",
|
|
272
|
+
"example": "one client's contract must never answer for another"},
|
|
273
|
+
],
|
|
274
|
+
}
|
|
275
|
+
|
|
276
|
+
|
|
277
|
+
def trust_question(result: Survey) -> dict | None:
|
|
278
|
+
"""The ranking question, listing what was actually found."""
|
|
279
|
+
if not result.groups:
|
|
280
|
+
return None
|
|
281
|
+
return {
|
|
282
|
+
"found": [g.as_dict() for g in result.groups],
|
|
283
|
+
"question": ("Two of these disagree about the same thing. Which should win?"),
|
|
284
|
+
"options": [{"label": g.name, "documents": g.documents} for g in result.groups[:4]]
|
|
285
|
+
+ [{"label": "Don't know", "effect": "nothing is ranked above anything else"}],
|
|
286
|
+
}
|
|
287
|
+
|
|
288
|
+
|
|
289
|
+
def summarise(result: Survey) -> str:
|
|
290
|
+
"""The survey as the owner reads it, before any question is asked."""
|
|
291
|
+
lines = [f"{result.documents:,} documents in {result.root}"]
|
|
292
|
+
if result.groups:
|
|
293
|
+
lines.append("")
|
|
294
|
+
lines.append("groups:")
|
|
295
|
+
for g in result.groups[:6]:
|
|
296
|
+
lines.append(f" {g.path:<40} {g.documents:>6,} documents")
|
|
297
|
+
if result.by_suffix:
|
|
298
|
+
kinds = ", ".join(f"{k} {v:,}" for k, v in list(result.by_suffix.items())[:5])
|
|
299
|
+
lines.append("")
|
|
300
|
+
lines.append(f"file types: {kinds}")
|
|
301
|
+
lines.append(f"language: {result.language}")
|
|
302
|
+
for note in result.notes:
|
|
303
|
+
lines.append(f" ! {note}")
|
|
304
|
+
return "\n".join(lines)
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
#!/usr/bin/env bash
|
|
2
|
+
# One bounded, authorized, canonical Runtime snapshot for the dashboard ritual.
|
|
3
|
+
set -euo pipefail
|
|
4
|
+
|
|
5
|
+
ROOT="$(cd "$(dirname "$0")/.." && pwd)"
|
|
6
|
+
TIME_RANGE="${2:-${1:-P7D}}"
|
|
7
|
+
|
|
8
|
+
# Keep the historical `[username] [range]` shape without treating a provider
|
|
9
|
+
# alias as identity. A recognized range in argv[1] is the new compact form.
|
|
10
|
+
case "$TIME_RANGE" in
|
|
11
|
+
P1D|P7D|P30D|P365D) ;;
|
|
12
|
+
*) TIME_RANGE="P7D" ;;
|
|
13
|
+
esac
|
|
14
|
+
|
|
15
|
+
ARGS=(dashboard --time-range "$TIME_RANGE")
|
|
16
|
+
[ "${EGREGORE_STATUS_CONNECTED_ENRICH:-0}" = "1" ] && ARGS+=(--connected-enrichment)
|
|
17
|
+
EGREGORE_ROOT="$ROOT" PYTHONPATH="$ROOT${PYTHONPATH:+:$PYTHONPATH}" \
|
|
18
|
+
exec python3 -m egregore_runtime.status_cli "${ARGS[@]}"
|
|
@@ -0,0 +1,121 @@
|
|
|
1
|
+
#!/usr/bin/env bash
|
|
2
|
+
set -euo pipefail
|
|
3
|
+
|
|
4
|
+
SCRIPT_DIR="$(cd "$(dirname "$0")/.." && pwd)"
|
|
5
|
+
|
|
6
|
+
# Default: official Egregore GitHub App (Device Flow — Client ID is public by design)
|
|
7
|
+
# Override per-org via github_app_client_id in egregore.json
|
|
8
|
+
CLIENT_ID="Iv23li2obNsAjakoK2RE"
|
|
9
|
+
if [ -f "$SCRIPT_DIR/egregore.json" ]; then
|
|
10
|
+
_CUSTOM_ID=$(jq -r '.github_app_client_id // .github_oauth_client_id // empty' "$SCRIPT_DIR/egregore.json" 2>/dev/null || true)
|
|
11
|
+
[ -n "$_CUSTOM_ID" ] && CLIENT_ID="$_CUSTOM_ID"
|
|
12
|
+
fi
|
|
13
|
+
|
|
14
|
+
SCOPE="" # GitHub App — permissions managed via installation, not OAuth scope
|
|
15
|
+
TIMEOUT=300
|
|
16
|
+
ENV_FILE="$SCRIPT_DIR/.env"
|
|
17
|
+
|
|
18
|
+
# Request device code
|
|
19
|
+
response=$(curl -s -X POST "https://github.com/login/device/code" \
|
|
20
|
+
-H "Accept: application/json" \
|
|
21
|
+
-d "client_id=$CLIENT_ID&scope=$SCOPE")
|
|
22
|
+
|
|
23
|
+
device_code=$(echo "$response" | jq -r '.device_code')
|
|
24
|
+
user_code=$(echo "$response" | jq -r '.user_code')
|
|
25
|
+
verification_uri=$(echo "$response" | jq -r '.verification_uri')
|
|
26
|
+
verification_uri_complete=$(echo "$response" | jq -r '.verification_uri_complete // empty')
|
|
27
|
+
interval=$(echo "$response" | jq -r '.interval')
|
|
28
|
+
|
|
29
|
+
if [ "$device_code" = "null" ] || [ -z "$device_code" ]; then
|
|
30
|
+
echo "Failed to get device code from GitHub."
|
|
31
|
+
echo "$response" | jq . 2>/dev/null || echo "$response"
|
|
32
|
+
exit 1
|
|
33
|
+
fi
|
|
34
|
+
|
|
35
|
+
# Copy code to clipboard
|
|
36
|
+
if command -v pbcopy >/dev/null 2>&1; then
|
|
37
|
+
printf '%s' "$user_code" | pbcopy
|
|
38
|
+
echo ""
|
|
39
|
+
echo " Code copied to clipboard: $user_code"
|
|
40
|
+
echo " Opening your browser — just paste and hit Continue."
|
|
41
|
+
echo ""
|
|
42
|
+
elif command -v xclip >/dev/null 2>&1; then
|
|
43
|
+
printf '%s' "$user_code" | xclip -selection clipboard
|
|
44
|
+
echo ""
|
|
45
|
+
echo " Code copied to clipboard: $user_code"
|
|
46
|
+
echo " Opening your browser — just paste and hit Continue."
|
|
47
|
+
echo ""
|
|
48
|
+
else
|
|
49
|
+
echo ""
|
|
50
|
+
echo " Your code: $user_code"
|
|
51
|
+
echo " Opening your browser — enter the code above."
|
|
52
|
+
echo ""
|
|
53
|
+
fi
|
|
54
|
+
|
|
55
|
+
# Open browser — use verification_uri_complete if available, otherwise plain URI
|
|
56
|
+
url="${verification_uri_complete:-$verification_uri}"
|
|
57
|
+
echo " Opening your browser..."
|
|
58
|
+
echo " If it doesn't open, visit: $url"
|
|
59
|
+
echo ""
|
|
60
|
+
if command -v open >/dev/null 2>&1; then
|
|
61
|
+
open "$url"
|
|
62
|
+
elif command -v xdg-open >/dev/null 2>&1; then
|
|
63
|
+
xdg-open "$url"
|
|
64
|
+
fi
|
|
65
|
+
|
|
66
|
+
# Poll for authorization
|
|
67
|
+
elapsed=0
|
|
68
|
+
while [ "$elapsed" -lt "$TIMEOUT" ]; do
|
|
69
|
+
sleep "$interval"
|
|
70
|
+
elapsed=$((elapsed + interval))
|
|
71
|
+
|
|
72
|
+
token_response=$(curl -s -X POST "https://github.com/login/oauth/access_token" \
|
|
73
|
+
-H "Accept: application/json" \
|
|
74
|
+
-d "client_id=$CLIENT_ID&device_code=$device_code&grant_type=urn:ietf:params:oauth:grant-type:device_code")
|
|
75
|
+
|
|
76
|
+
error=$(echo "$token_response" | jq -r '.error // empty')
|
|
77
|
+
access_token=$(echo "$token_response" | jq -r '.access_token // empty')
|
|
78
|
+
|
|
79
|
+
if [ -n "$access_token" ]; then
|
|
80
|
+
# Write token to .env
|
|
81
|
+
if [ -f "$ENV_FILE" ] && grep -q '^GITHUB_TOKEN=' "$ENV_FILE"; then
|
|
82
|
+
# Replace existing token (portable: write to temp file, then move)
|
|
83
|
+
tmp="$ENV_FILE.tmp.$$"
|
|
84
|
+
while IFS= read -r line || [ -n "$line" ]; do
|
|
85
|
+
case "$line" in
|
|
86
|
+
GITHUB_TOKEN=*) echo "GITHUB_TOKEN=$access_token" ;;
|
|
87
|
+
*) echo "$line" ;;
|
|
88
|
+
esac
|
|
89
|
+
done < "$ENV_FILE" > "$tmp"
|
|
90
|
+
mv "$tmp" "$ENV_FILE"
|
|
91
|
+
else
|
|
92
|
+
echo "GITHUB_TOKEN=$access_token" >> "$ENV_FILE"
|
|
93
|
+
fi
|
|
94
|
+
|
|
95
|
+
# Configure git credential helper (local to this repo, not global)
|
|
96
|
+
git config credential.helper store
|
|
97
|
+
# Write credential for github.com
|
|
98
|
+
protocol_line="protocol=https
|
|
99
|
+
host=github.com
|
|
100
|
+
username=x-access-token
|
|
101
|
+
password=$access_token
|
|
102
|
+
"
|
|
103
|
+
echo "$protocol_line" | git credential-store store 2>/dev/null || true
|
|
104
|
+
|
|
105
|
+
echo " Authorized!"
|
|
106
|
+
exit 0
|
|
107
|
+
fi
|
|
108
|
+
|
|
109
|
+
case "$error" in
|
|
110
|
+
authorization_pending) continue ;;
|
|
111
|
+
slow_down) interval=$((interval + 5)) ;;
|
|
112
|
+
*)
|
|
113
|
+
echo " Authorization failed: $error"
|
|
114
|
+
echo "$token_response" | jq -r '.error_description // empty'
|
|
115
|
+
exit 1
|
|
116
|
+
;;
|
|
117
|
+
esac
|
|
118
|
+
done
|
|
119
|
+
|
|
120
|
+
echo " Timed out waiting for authorization (${TIMEOUT}s)."
|
|
121
|
+
exit 1
|
|
@@ -0,0 +1,86 @@
|
|
|
1
|
+
#!/usr/bin/env bash
|
|
2
|
+
set -euo pipefail
|
|
3
|
+
|
|
4
|
+
# Execute multiple Cypher queries in a single HTTP call.
|
|
5
|
+
# Usage: graph-batch.sh '<json array of {statement, parameters} objects>'
|
|
6
|
+
#
|
|
7
|
+
# Example:
|
|
8
|
+
# graph-batch.sh '[{"statement":"MATCH (p:Person) RETURN p.name"},{"statement":"MATCH (q:Quest) RETURN q.id"}]'
|
|
9
|
+
#
|
|
10
|
+
# Returns: {"results": [{...}, {...}]}
|
|
11
|
+
|
|
12
|
+
SCRIPT_DIR="$(cd "$(dirname "$0")/.." && pwd)"
|
|
13
|
+
CONFIG="$SCRIPT_DIR/egregore.json"
|
|
14
|
+
|
|
15
|
+
if [ ! -f "$CONFIG" ]; then
|
|
16
|
+
echo "Error: egregore.json not found. Run onboarding first." >&2
|
|
17
|
+
exit 1
|
|
18
|
+
fi
|
|
19
|
+
|
|
20
|
+
# shellcheck source=bin/lib/config.sh
|
|
21
|
+
source "$SCRIPT_DIR/bin/lib/config.sh"
|
|
22
|
+
if ! _graph_projection_enabled; then
|
|
23
|
+
echo '{"results":[],"status":"disabled","reason":"graph_projection_disabled"}'
|
|
24
|
+
exit 0
|
|
25
|
+
fi
|
|
26
|
+
|
|
27
|
+
# --- Local mode gate: bail immediately ---
|
|
28
|
+
_MODE=$(jq -r '.mode // "connected"' "$CONFIG" 2>/dev/null)
|
|
29
|
+
if [ "$_MODE" = "local" ]; then
|
|
30
|
+
echo '{"results":[]}'
|
|
31
|
+
exit 0
|
|
32
|
+
fi
|
|
33
|
+
|
|
34
|
+
# Load specific variables from .env if it exists (safe extraction, no arbitrary code execution).
|
|
35
|
+
# A worktree missing its .env symlink resolves through worktree-links.sh, which
|
|
36
|
+
# self-heals the link and falls back to the main checkout's .env.
|
|
37
|
+
_ENV_FILE="$SCRIPT_DIR/.env"
|
|
38
|
+
if [ ! -f "$_ENV_FILE" ] && [ -f "$SCRIPT_DIR/bin/lib/worktree-links.sh" ]; then
|
|
39
|
+
# shellcheck source=bin/lib/worktree-links.sh
|
|
40
|
+
source "$SCRIPT_DIR/bin/lib/worktree-links.sh" 2>/dev/null || true
|
|
41
|
+
_ENV_FILE="$(egregore_env_file "$SCRIPT_DIR" 2>/dev/null || true)"
|
|
42
|
+
fi
|
|
43
|
+
if [ -n "$_ENV_FILE" ] && [ -f "$_ENV_FILE" ]; then
|
|
44
|
+
EGREGORE_API_URL="${EGREGORE_API_URL:-$(grep '^EGREGORE_API_URL=' "$_ENV_FILE" 2>/dev/null | cut -d'=' -f2- || true)}"
|
|
45
|
+
EGREGORE_API_KEY="${EGREGORE_API_KEY:-$(grep '^EGREGORE_API_KEY=' "$_ENV_FILE" 2>/dev/null | cut -d'=' -f2- || true)}"
|
|
46
|
+
fi
|
|
47
|
+
|
|
48
|
+
API_URL="${EGREGORE_API_URL:-$(jq -r '.api_url // empty' "$CONFIG")}"
|
|
49
|
+
API_KEY="${EGREGORE_API_KEY:-}"
|
|
50
|
+
|
|
51
|
+
if [ -z "$API_URL" ]; then
|
|
52
|
+
# === OFFLINE MODE: no api_url configured (OSS/unconfigured) ===
|
|
53
|
+
echo '{"results":[]}'
|
|
54
|
+
exit 0
|
|
55
|
+
fi
|
|
56
|
+
|
|
57
|
+
if [ -z "$API_KEY" ]; then
|
|
58
|
+
# api_url is configured but no key was found — the local-mode gate exited
|
|
59
|
+
# above, so the org expects a live graph. Faking empty results here hides a
|
|
60
|
+
# missing .env (e.g. a worktree without its symlink) from every caller.
|
|
61
|
+
{
|
|
62
|
+
echo "Error: api_url is configured but EGREGORE_API_KEY is empty (looked in: ${_ENV_FILE:-$SCRIPT_DIR/.env})."
|
|
63
|
+
echo " If this is a worktree, its .env symlink may be missing. Run /env to configure."
|
|
64
|
+
} >&2
|
|
65
|
+
exit 1
|
|
66
|
+
fi
|
|
67
|
+
|
|
68
|
+
QUERIES_JSON="${1:?Usage: graph-batch.sh '<json array of queries>'}"
|
|
69
|
+
|
|
70
|
+
# Wrap the array into the batch request format
|
|
71
|
+
BODY=$(jq -n --argjson queries "$QUERIES_JSON" '{queries: $queries}')
|
|
72
|
+
|
|
73
|
+
RESPONSE=$(curl -s -X POST "${API_URL}/api/graph/batch" \
|
|
74
|
+
-H "Authorization: Bearer $API_KEY" \
|
|
75
|
+
-H "Content-Type: application/json" \
|
|
76
|
+
-d "$BODY" \
|
|
77
|
+
--max-time 60)
|
|
78
|
+
|
|
79
|
+
# Check for HTTP-level errors
|
|
80
|
+
if echo "$RESPONSE" | jq -e '.detail' >/dev/null 2>&1; then
|
|
81
|
+
echo "API error:" >&2
|
|
82
|
+
echo "$RESPONSE" | jq '.detail' >&2
|
|
83
|
+
exit 1
|
|
84
|
+
fi
|
|
85
|
+
|
|
86
|
+
echo "$RESPONSE"
|