create-egregore 0.21.6 → 0.22.0
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 +58 -6
- package/assets/egregore-launcher.sh +15 -2
- package/lib/claude-runtime.js +2 -0
- package/lib/codex-runtime.js +2 -0
- package/lib/setup.js +20 -3
- package/package.json +2 -2
- package/runtime/claude/.claude/context/commit-format.md +7 -4
- package/runtime/claude/.claude/context/handoff-claiming.md +32 -0
- package/runtime/claude/.claude/context/notification-consent.md +12 -9
- package/runtime/claude/.claude/hooks/boundary-check.sh +14 -331
- package/runtime/claude/.claude/hooks/memory-read-guard.sh +9 -1
- package/runtime/claude/.claude/rules/voice-bedrock.md +6 -2
- package/runtime/claude/.claude/settings.json +1 -1
- package/runtime/claude/.claude/skills/commit/SKILL.md +5 -3
- package/runtime/claude/.claude/skills/dark-mode/SKILL.md +48 -369
- package/runtime/claude/.claude/skills/records/SKILL.md +158 -0
- package/runtime/claude/.claude/skills/reflect/SKILL.md +50 -21
- package/runtime/claude/.claude/skills/review-pr/SKILL.md +4 -2
- package/runtime/claude/.claude/skills/save/SKILL.md +9 -3
- package/runtime/claude/.claude/skills/summon/SKILL.md +138 -207
- package/runtime/claude/.claude/skills/tui-design/SKILL.md +1 -1
- package/runtime/claude/.claude/skills/update/SKILL.md +1 -1
- package/runtime/claude/.claude/skills/view/SKILL.md +52 -16
- package/runtime/claude/.claude/skills/view/compose-scaffold.html +19 -13
- package/runtime/claude/CLAUDE.md +59 -95
- package/runtime/claude/bin/agent.sh +231 -7
- package/runtime/claude/bin/api-call.sh +44 -23
- package/runtime/claude/bin/artifact-register.sh +7 -1
- package/runtime/claude/bin/artifact-writeback.sh +1 -1
- package/runtime/claude/bin/artifacts.sh +66 -265
- package/runtime/claude/bin/attendant.sh +4 -1
- package/runtime/claude/bin/boundary-guard.cjs +1848 -0
- package/runtime/claude/bin/boundary-hook.sh +41 -0
- package/runtime/claude/bin/boundary.sh +15 -155
- package/runtime/claude/bin/capture-run.sh +32 -2
- package/runtime/claude/bin/codex-render-spec.mjs +24 -46
- package/runtime/claude/bin/codex-session-start.sh +19 -0
- package/runtime/claude/bin/codex-skill-render.mjs +18 -0
- package/runtime/claude/bin/config-get.sh +10 -1
- package/runtime/claude/bin/connect-refresh.sh +16 -0
- package/runtime/claude/bin/corpus_map.py +5 -0
- package/runtime/claude/bin/data/capabilities/claude.json +1480 -0
- package/runtime/claude/bin/genui.sh +19 -0
- package/runtime/claude/bin/graph-batch.sh +1 -1
- package/runtime/claude/bin/graph-op.sh +14 -0
- package/runtime/claude/bin/graph.sh +1 -1
- package/runtime/claude/bin/handoff-pr-backfill.sh +1 -1
- package/runtime/claude/bin/handoff-run.sh +11 -6
- package/runtime/claude/bin/ingest-item.sh +1 -1
- package/runtime/claude/bin/ingest-surface.html +22 -4
- package/runtime/claude/bin/issue.sh +1 -1
- package/runtime/claude/bin/knowledge.sh +1 -1
- package/runtime/claude/bin/lib/card-delivery.sh +329 -0
- package/runtime/claude/bin/lib/config.sh +148 -3
- package/runtime/claude/bin/lib/context.sh +38 -67
- package/runtime/claude/bin/lib/genui-entry.py +36 -0
- package/runtime/claude/bin/lib/git-message.sh +25 -6
- package/runtime/claude/bin/lib/git-sync.sh +12 -4
- package/runtime/claude/bin/lib/greeting.sh +255 -28
- package/runtime/claude/bin/lib/handoff_meta.py +294 -0
- package/runtime/claude/bin/lib/health-footer.sh +83 -2
- package/runtime/claude/bin/lib/identity.sh +31 -10
- package/runtime/claude/bin/lib/instance-registry.sh +71 -0
- package/runtime/claude/bin/lib/local_ci_receipt.py +249 -0
- package/runtime/claude/bin/lib/metrics.sh +121 -8
- package/runtime/claude/bin/lib/notices.sh +36 -0
- package/runtime/claude/bin/lib/record_outcomes.py +729 -0
- package/runtime/claude/bin/lib/reflexes.py +267 -0
- package/runtime/claude/bin/lib/retrieval_scorecard.py +624 -0
- package/runtime/claude/bin/lib/session-record-prompt.txt +18 -0
- package/runtime/claude/bin/lib/session_record.py +3747 -0
- package/runtime/claude/bin/lib/session_trail.py +1983 -0
- package/runtime/claude/bin/lib/settings-drift.sh +8 -5
- package/runtime/claude/bin/lib/startup-restart.sh +41 -0
- package/runtime/claude/bin/lib/worktree-links.sh +92 -0
- package/runtime/claude/bin/memory-push.sh +6 -0
- package/runtime/claude/bin/merge-gate.sh +498 -0
- package/runtime/claude/bin/notify.sh +5 -2
- package/runtime/claude/bin/page-access.sh +103 -0
- package/runtime/claude/bin/person.sh +13 -2
- package/runtime/claude/bin/pi-render-spec.mjs +0 -1
- package/runtime/claude/bin/pi-spirit-discovery.mjs +34 -0
- package/runtime/claude/bin/post-update.sh +181 -0
- package/runtime/claude/bin/prime-render-spec.mjs +0 -1
- package/runtime/claude/bin/publish-artifact.sh +89 -42
- package/runtime/claude/bin/qa-inventory.sh +2 -2
- package/runtime/claude/bin/quest.sh +1 -1
- package/runtime/claude/bin/records.sh +11 -0
- package/runtime/claude/bin/reflexes/05-vitals.sh +9 -0
- package/runtime/claude/bin/reflexes/10-open-items.sh +12 -0
- package/runtime/claude/bin/reflexes/15-retrieval.sh +8 -0
- package/runtime/claude/bin/reflexes/20-nightly.sh +100 -0
- package/runtime/claude/bin/reflexes/20-sandbox.sh +85 -0
- package/runtime/claude/bin/reflexes/30-cost.py +116 -0
- package/runtime/claude/bin/reflexes/40-shells.py +51 -0
- package/runtime/claude/bin/reflexes/README.md +61 -0
- package/runtime/claude/bin/reflexes.sh +7 -0
- package/runtime/claude/bin/runtime-identity.sh +140 -42
- package/runtime/claude/bin/screenshot.sh +77 -0
- package/runtime/claude/bin/scroll.sh +1 -1
- package/runtime/claude/bin/search.sh +31 -5
- package/runtime/claude/bin/session-autosave.sh +6 -3
- package/runtime/claude/bin/session-id.sh +147 -0
- package/runtime/claude/bin/session-log.sh +19 -0
- package/runtime/claude/bin/session-record.sh +26 -0
- package/runtime/claude/bin/session-start.sh +121 -151
- package/runtime/claude/bin/settings.sh +13 -8
- package/runtime/claude/bin/spirit-discovery-claude.sh +4 -0
- package/runtime/claude/bin/spirit-discovery-codex.sh +4 -0
- package/runtime/claude/bin/spirit-discovery-pi.sh +4 -0
- package/runtime/claude/bin/spirit-discovery-prime.sh +4 -0
- package/runtime/claude/bin/spirit-discovery.sh +4 -0
- package/runtime/claude/bin/startup-check.sh +1 -1
- package/runtime/claude/bin/telemetry.sh +11 -4
- package/runtime/claude/bin/test-baseline.sh +33 -5
- package/runtime/claude/bin/todo.sh +1 -1
- package/runtime/claude/bin/worktree-create.sh +15 -45
- package/runtime/claude/bin/worktree.sh +6 -0
- package/runtime/claude/docs/spirit-discovery.md +96 -0
- package/runtime/claude/egregore_runtime/__init__.py +18 -12
- package/runtime/claude/egregore_runtime/access.py +608 -0
- package/runtime/claude/egregore_runtime/access_cli.py +190 -0
- package/runtime/claude/egregore_runtime/adapters/invitation.py +5 -3
- package/runtime/claude/egregore_runtime/adapters/qmd.py +521 -47
- package/runtime/claude/egregore_runtime/admin_entry.py +56 -0
- package/runtime/claude/egregore_runtime/artifacts.py +222 -16
- package/runtime/claude/egregore_runtime/contracts.py +27 -0
- package/runtime/claude/egregore_runtime/eligibility.py +5 -12
- package/runtime/claude/egregore_runtime/episode_binding.py +16 -5
- package/runtime/claude/egregore_runtime/github_issues.py +2 -2
- package/runtime/claude/egregore_runtime/handoff_lookup.py +9 -20
- package/runtime/claude/egregore_runtime/harness_cli.py +674 -149
- package/runtime/claude/egregore_runtime/held.py +2436 -0
- package/runtime/claude/egregore_runtime/hosted_api.py +137 -0
- package/runtime/claude/egregore_runtime/identity.py +196 -65
- package/runtime/claude/egregore_runtime/identity_transfer.py +6 -2
- package/runtime/claude/egregore_runtime/ingest_cli.py +2 -2
- package/runtime/claude/egregore_runtime/ingest_index_cli.py +4 -16
- package/runtime/claude/egregore_runtime/installation.py +119 -0
- package/runtime/claude/egregore_runtime/investigation.py +64 -41
- package/runtime/claude/egregore_runtime/investigation_guidance.py +16 -11
- package/runtime/claude/egregore_runtime/issue_cli.py +51 -32
- package/runtime/claude/egregore_runtime/issue_reporting.py +4 -3
- package/runtime/claude/egregore_runtime/issue_triage_service.py +2 -2
- package/runtime/claude/egregore_runtime/issues.py +12 -6
- package/runtime/claude/egregore_runtime/knowledge.py +331 -5
- package/runtime/claude/egregore_runtime/knowledge_cli.py +57 -17
- package/runtime/claude/egregore_runtime/lifecycle.py +88 -22
- package/runtime/claude/egregore_runtime/lifecycle_cli.py +21 -13
- package/runtime/claude/egregore_runtime/line_ids.py +10 -0
- package/runtime/claude/egregore_runtime/memory_push.py +349 -0
- package/runtime/claude/egregore_runtime/observe.py +64 -25
- package/runtime/claude/egregore_runtime/observers.py +19 -0
- package/runtime/claude/egregore_runtime/optional_modules.py +13 -0
- package/runtime/claude/egregore_runtime/outputs_cli.py +321 -0
- package/runtime/claude/egregore_runtime/policy.py +651 -24
- package/runtime/claude/egregore_runtime/private_result.py +2 -1
- package/runtime/claude/egregore_runtime/projection.py +946 -0
- package/runtime/claude/egregore_runtime/quest_cli.py +20 -23
- package/runtime/claude/egregore_runtime/question_cli.py +15 -11
- package/runtime/claude/egregore_runtime/questions.py +10 -10
- package/runtime/claude/egregore_runtime/quests.py +10 -10
- package/runtime/claude/egregore_runtime/record_publish.py +548 -0
- package/runtime/claude/egregore_runtime/record_subject.py +564 -0
- package/runtime/claude/egregore_runtime/research_ingest.py +2 -4
- package/runtime/claude/egregore_runtime/runtime.py +169 -60
- package/runtime/claude/egregore_runtime/sandbox.py +194 -0
- package/runtime/claude/egregore_runtime/scroll_cli.py +22 -32
- package/runtime/claude/egregore_runtime/scrolls.py +23 -15
- package/runtime/claude/egregore_runtime/shadow.py +262 -0
- package/runtime/claude/egregore_runtime/spirit_discovery.py +487 -0
- package/runtime/claude/egregore_runtime/spirit_discovery_cli.py +25 -0
- package/runtime/claude/egregore_runtime/spirit_discovery_transport.py +18 -0
- package/runtime/claude/egregore_runtime/status.py +101 -44
- package/runtime/claude/egregore_runtime/status_cli.py +13 -5
- package/runtime/claude/egregore_runtime/sync.py +39 -21
- package/runtime/claude/egregore_runtime/taste.py +934 -0
- package/runtime/claude/egregore_runtime/taste_cli.py +242 -0
- package/runtime/claude/egregore_runtime/taste_rules.py +91 -0
- package/runtime/claude/egregore_runtime/telemetry.py +26 -3
- package/runtime/claude/egregore_runtime/todo_cli.py +15 -12
- package/runtime/claude/egregore_runtime/todos.py +3 -2
- package/runtime/claude/egregore_runtime/upgrade.py +85 -58
- package/runtime/claude/egregore_runtime/writeback.py +330 -24
- package/runtime/claude/manifest.json +65 -5
- package/runtime/codex/.claude/context/handoff-claiming.md +32 -0
- package/runtime/codex/.claude/context/notification-consent.md +12 -9
- package/runtime/codex/.claude/skills/view/SKILL.md +438 -0
- package/runtime/codex/.codex/hooks.json +11 -0
- package/runtime/codex/.codex/skills/dark-mode/SKILL.md +1 -1
- package/runtime/codex/.codex/skills/records/SKILL.md +29 -0
- package/runtime/codex/.codex/skills/summon/SKILL.md +1 -1
- package/runtime/codex/.codex/skills/view/assets/compose-scaffold.html +19 -13
- package/runtime/codex/.codex/spec-manifest.json +13 -19
- package/runtime/codex/AGENTS.md +54 -105
- package/runtime/codex/bin/agent.sh +231 -7
- package/runtime/codex/bin/api-call.sh +44 -23
- package/runtime/codex/bin/artifact-register.sh +7 -1
- package/runtime/codex/bin/artifact-writeback.sh +1 -1
- package/runtime/codex/bin/artifacts.sh +66 -265
- package/runtime/codex/bin/attendant.sh +4 -1
- package/runtime/codex/bin/boundary-guard.cjs +1848 -0
- package/runtime/codex/bin/boundary-hook.sh +41 -0
- package/runtime/codex/bin/capture-run.sh +32 -2
- package/runtime/codex/bin/codex-render-spec.mjs +24 -46
- package/runtime/codex/bin/codex-session-start.sh +19 -0
- package/runtime/codex/bin/codex-skill-render.mjs +18 -0
- package/runtime/codex/bin/config-get.sh +10 -1
- package/runtime/codex/bin/connect-refresh.sh +16 -0
- package/runtime/codex/bin/corpus_map.py +5 -0
- package/runtime/codex/bin/data/capabilities/codex.json +1458 -0
- package/runtime/codex/bin/genui.sh +19 -0
- package/runtime/codex/bin/graph-batch.sh +1 -1
- package/runtime/codex/bin/graph-op.sh +14 -0
- package/runtime/codex/bin/graph.sh +1 -1
- package/runtime/codex/bin/handoff-pr-backfill.sh +1 -1
- package/runtime/codex/bin/handoff-run.sh +11 -6
- package/runtime/codex/bin/ingest-item.sh +1 -1
- package/runtime/codex/bin/ingest-surface.html +22 -4
- package/runtime/codex/bin/issue.sh +1 -1
- package/runtime/codex/bin/knowledge.sh +1 -1
- package/runtime/codex/bin/lib/card-delivery.sh +329 -0
- package/runtime/codex/bin/lib/config.sh +148 -3
- package/runtime/codex/bin/lib/context.sh +38 -67
- package/runtime/codex/bin/lib/genui-entry.py +36 -0
- package/runtime/codex/bin/lib/git-message.sh +25 -6
- package/runtime/codex/bin/lib/git-sync.sh +12 -4
- package/runtime/codex/bin/lib/greeting.sh +255 -28
- package/runtime/codex/bin/lib/handoff_meta.py +294 -0
- package/runtime/codex/bin/lib/health-footer.sh +83 -2
- package/runtime/codex/bin/lib/identity.sh +31 -10
- package/runtime/codex/bin/lib/instance-registry.sh +71 -0
- package/runtime/codex/bin/lib/local_ci_receipt.py +249 -0
- package/runtime/codex/bin/lib/metrics.sh +121 -8
- package/runtime/codex/bin/lib/notices.sh +36 -0
- package/runtime/codex/bin/lib/record_outcomes.py +729 -0
- package/runtime/codex/bin/lib/reflexes.py +267 -0
- package/runtime/codex/bin/lib/retrieval_scorecard.py +624 -0
- package/runtime/codex/bin/lib/session-record-prompt.txt +18 -0
- package/runtime/codex/bin/lib/session_record.py +3747 -0
- package/runtime/codex/bin/lib/session_trail.py +1983 -0
- package/runtime/codex/bin/lib/settings-drift.sh +8 -5
- package/runtime/codex/bin/lib/startup-restart.sh +41 -0
- package/runtime/codex/bin/lib/worktree-links.sh +92 -0
- package/runtime/codex/bin/memory-push.sh +6 -0
- package/runtime/codex/bin/merge-gate.sh +498 -0
- package/runtime/codex/bin/notify.sh +5 -2
- package/runtime/codex/bin/page-access.sh +103 -0
- package/runtime/codex/bin/person.sh +13 -2
- package/runtime/codex/bin/pi-render-spec.mjs +0 -1
- package/runtime/codex/bin/pi-spirit-discovery.mjs +34 -0
- package/runtime/codex/bin/post-update.sh +181 -0
- package/runtime/codex/bin/prime-render-spec.mjs +0 -1
- package/runtime/codex/bin/publish-artifact.sh +89 -42
- package/runtime/codex/bin/qa-inventory.sh +2 -2
- package/runtime/codex/bin/quest.sh +1 -1
- package/runtime/codex/bin/records.sh +11 -0
- package/runtime/codex/bin/reflexes/05-vitals.sh +9 -0
- package/runtime/codex/bin/reflexes/10-open-items.sh +12 -0
- package/runtime/codex/bin/reflexes/15-retrieval.sh +8 -0
- package/runtime/codex/bin/reflexes/20-nightly.sh +100 -0
- package/runtime/codex/bin/reflexes/20-sandbox.sh +85 -0
- package/runtime/codex/bin/reflexes/30-cost.py +116 -0
- package/runtime/codex/bin/reflexes/40-shells.py +51 -0
- package/runtime/codex/bin/reflexes/README.md +61 -0
- package/runtime/codex/bin/reflexes.sh +7 -0
- package/runtime/codex/bin/runtime-identity.sh +140 -42
- package/runtime/codex/bin/screenshot.sh +77 -0
- package/runtime/codex/bin/scroll.sh +1 -1
- package/runtime/codex/bin/search.sh +31 -5
- package/runtime/codex/bin/session-autosave.sh +6 -3
- package/runtime/codex/bin/session-id.sh +147 -0
- package/runtime/codex/bin/session-log.sh +19 -0
- package/runtime/codex/bin/session-record.sh +26 -0
- package/runtime/codex/bin/settings.sh +13 -8
- package/runtime/codex/bin/spirit-discovery-claude.sh +4 -0
- package/runtime/codex/bin/spirit-discovery-codex.sh +4 -0
- package/runtime/codex/bin/spirit-discovery-pi.sh +4 -0
- package/runtime/codex/bin/spirit-discovery-prime.sh +4 -0
- package/runtime/codex/bin/spirit-discovery.sh +4 -0
- package/runtime/codex/bin/startup-check.sh +1 -1
- package/runtime/codex/bin/telemetry.sh +11 -4
- package/runtime/codex/bin/test-baseline.sh +33 -5
- package/runtime/codex/bin/todo.sh +1 -1
- package/runtime/codex/bin/worktree-create.sh +15 -45
- package/runtime/codex/bin/worktree.sh +6 -0
- package/runtime/codex/docs/spirit-discovery.md +96 -0
- package/runtime/codex/egregore_runtime/__init__.py +18 -12
- package/runtime/codex/egregore_runtime/access.py +608 -0
- package/runtime/codex/egregore_runtime/access_cli.py +190 -0
- package/runtime/codex/egregore_runtime/adapters/invitation.py +5 -3
- package/runtime/codex/egregore_runtime/adapters/qmd.py +521 -47
- package/runtime/codex/egregore_runtime/admin_entry.py +56 -0
- package/runtime/codex/egregore_runtime/artifacts.py +222 -16
- package/runtime/codex/egregore_runtime/contracts.py +27 -0
- package/runtime/codex/egregore_runtime/eligibility.py +5 -12
- package/runtime/codex/egregore_runtime/episode_binding.py +16 -5
- package/runtime/codex/egregore_runtime/github_issues.py +2 -2
- package/runtime/codex/egregore_runtime/handoff_lookup.py +9 -20
- package/runtime/codex/egregore_runtime/harness_cli.py +674 -149
- package/runtime/codex/egregore_runtime/held.py +2436 -0
- package/runtime/codex/egregore_runtime/hosted_api.py +137 -0
- package/runtime/codex/egregore_runtime/identity.py +196 -65
- package/runtime/codex/egregore_runtime/identity_transfer.py +6 -2
- package/runtime/codex/egregore_runtime/ingest_cli.py +2 -2
- package/runtime/codex/egregore_runtime/ingest_index_cli.py +4 -16
- package/runtime/codex/egregore_runtime/installation.py +119 -0
- package/runtime/codex/egregore_runtime/investigation.py +64 -41
- package/runtime/codex/egregore_runtime/investigation_guidance.py +16 -11
- package/runtime/codex/egregore_runtime/issue_cli.py +51 -32
- package/runtime/codex/egregore_runtime/issue_reporting.py +4 -3
- package/runtime/codex/egregore_runtime/issue_triage_service.py +2 -2
- package/runtime/codex/egregore_runtime/issues.py +12 -6
- package/runtime/codex/egregore_runtime/knowledge.py +331 -5
- package/runtime/codex/egregore_runtime/knowledge_cli.py +57 -17
- package/runtime/codex/egregore_runtime/lifecycle.py +88 -22
- package/runtime/codex/egregore_runtime/lifecycle_cli.py +21 -13
- package/runtime/codex/egregore_runtime/line_ids.py +10 -0
- package/runtime/codex/egregore_runtime/memory_push.py +349 -0
- package/runtime/codex/egregore_runtime/observe.py +64 -25
- package/runtime/codex/egregore_runtime/observers.py +19 -0
- package/runtime/codex/egregore_runtime/optional_modules.py +13 -0
- package/runtime/codex/egregore_runtime/outputs_cli.py +321 -0
- package/runtime/codex/egregore_runtime/policy.py +651 -24
- package/runtime/codex/egregore_runtime/private_result.py +2 -1
- package/runtime/codex/egregore_runtime/projection.py +946 -0
- package/runtime/codex/egregore_runtime/quest_cli.py +20 -23
- package/runtime/codex/egregore_runtime/question_cli.py +15 -11
- package/runtime/codex/egregore_runtime/questions.py +10 -10
- package/runtime/codex/egregore_runtime/quests.py +10 -10
- package/runtime/codex/egregore_runtime/record_publish.py +548 -0
- package/runtime/codex/egregore_runtime/record_subject.py +564 -0
- package/runtime/codex/egregore_runtime/research_ingest.py +2 -4
- package/runtime/codex/egregore_runtime/runtime.py +169 -60
- package/runtime/codex/egregore_runtime/sandbox.py +194 -0
- package/runtime/codex/egregore_runtime/scroll_cli.py +22 -32
- package/runtime/codex/egregore_runtime/scrolls.py +23 -15
- package/runtime/codex/egregore_runtime/shadow.py +262 -0
- package/runtime/codex/egregore_runtime/spirit_discovery.py +487 -0
- package/runtime/codex/egregore_runtime/spirit_discovery_cli.py +25 -0
- package/runtime/codex/egregore_runtime/spirit_discovery_transport.py +18 -0
- package/runtime/codex/egregore_runtime/status.py +101 -44
- package/runtime/codex/egregore_runtime/status_cli.py +13 -5
- package/runtime/codex/egregore_runtime/sync.py +39 -21
- package/runtime/codex/egregore_runtime/taste.py +934 -0
- package/runtime/codex/egregore_runtime/taste_cli.py +242 -0
- package/runtime/codex/egregore_runtime/taste_rules.py +91 -0
- package/runtime/codex/egregore_runtime/telemetry.py +26 -3
- package/runtime/codex/egregore_runtime/todo_cli.py +15 -12
- package/runtime/codex/egregore_runtime/todos.py +3 -2
- package/runtime/codex/egregore_runtime/upgrade.py +85 -58
- package/runtime/codex/egregore_runtime/writeback.py +330 -24
- package/runtime/codex/manifest.json +66 -5
- package/runtime/pi/.claude/context/handoff-claiming.md +32 -0
- package/runtime/pi/.claude/context/notification-consent.md +12 -9
- package/runtime/pi/.claude/skills/view/SKILL.md +438 -0
- package/runtime/pi/.codex/hooks.json +11 -0
- package/runtime/pi/.codex/skills/dark-mode/SKILL.md +1 -1
- package/runtime/pi/.codex/skills/records/SKILL.md +29 -0
- package/runtime/pi/.codex/skills/summon/SKILL.md +1 -1
- package/runtime/pi/.codex/skills/view/assets/compose-scaffold.html +19 -13
- package/runtime/pi/.codex/spec-manifest.json +13 -19
- package/runtime/pi/.pi/APPEND_SYSTEM.md +53 -99
- package/runtime/pi/.pi/extensions/egregore.ts +13 -1
- package/runtime/pi/.pi/spec-manifest.json +2 -2
- package/runtime/pi/AGENTS.md +54 -105
- package/runtime/pi/bin/agent.sh +231 -7
- package/runtime/pi/bin/api-call.sh +44 -23
- package/runtime/pi/bin/artifact-register.sh +7 -1
- package/runtime/pi/bin/artifact-writeback.sh +1 -1
- package/runtime/pi/bin/artifacts.sh +66 -265
- package/runtime/pi/bin/attendant.sh +4 -1
- package/runtime/pi/bin/boundary-guard.cjs +1848 -0
- package/runtime/pi/bin/boundary-hook.sh +41 -0
- package/runtime/pi/bin/capture-run.sh +32 -2
- package/runtime/pi/bin/codex-render-spec.mjs +24 -46
- package/runtime/pi/bin/codex-session-start.sh +19 -0
- package/runtime/pi/bin/codex-skill-render.mjs +18 -0
- package/runtime/pi/bin/config-get.sh +10 -1
- package/runtime/pi/bin/connect-refresh.sh +16 -0
- package/runtime/pi/bin/corpus_map.py +5 -0
- package/runtime/pi/bin/data/capabilities/pi.json +1458 -0
- package/runtime/pi/bin/genui.sh +19 -0
- package/runtime/pi/bin/graph-batch.sh +1 -1
- package/runtime/pi/bin/graph-op.sh +14 -0
- package/runtime/pi/bin/graph.sh +1 -1
- package/runtime/pi/bin/handoff-pr-backfill.sh +1 -1
- package/runtime/pi/bin/handoff-run.sh +11 -6
- package/runtime/pi/bin/ingest-item.sh +1 -1
- package/runtime/pi/bin/ingest-surface.html +22 -4
- package/runtime/pi/bin/issue.sh +1 -1
- package/runtime/pi/bin/knowledge.sh +1 -1
- package/runtime/pi/bin/lib/card-delivery.sh +329 -0
- package/runtime/pi/bin/lib/config.sh +148 -3
- package/runtime/pi/bin/lib/context.sh +38 -67
- package/runtime/pi/bin/lib/genui-entry.py +36 -0
- package/runtime/pi/bin/lib/git-message.sh +25 -6
- package/runtime/pi/bin/lib/git-sync.sh +12 -4
- package/runtime/pi/bin/lib/greeting.sh +255 -28
- package/runtime/pi/bin/lib/handoff_meta.py +294 -0
- package/runtime/pi/bin/lib/health-footer.sh +83 -2
- package/runtime/pi/bin/lib/identity.sh +31 -10
- package/runtime/pi/bin/lib/instance-registry.sh +71 -0
- package/runtime/pi/bin/lib/local_ci_receipt.py +249 -0
- package/runtime/pi/bin/lib/metrics.sh +121 -8
- package/runtime/pi/bin/lib/notices.sh +36 -0
- package/runtime/pi/bin/lib/record_outcomes.py +729 -0
- package/runtime/pi/bin/lib/reflexes.py +267 -0
- package/runtime/pi/bin/lib/retrieval_scorecard.py +624 -0
- package/runtime/pi/bin/lib/session-record-prompt.txt +18 -0
- package/runtime/pi/bin/lib/session_record.py +3747 -0
- package/runtime/pi/bin/lib/session_trail.py +1983 -0
- package/runtime/pi/bin/lib/settings-drift.sh +8 -5
- package/runtime/pi/bin/lib/startup-restart.sh +41 -0
- package/runtime/pi/bin/lib/worktree-links.sh +92 -0
- package/runtime/pi/bin/memory-push.sh +6 -0
- package/runtime/pi/bin/merge-gate.sh +498 -0
- package/runtime/pi/bin/notify.sh +5 -2
- package/runtime/pi/bin/page-access.sh +103 -0
- package/runtime/pi/bin/person.sh +13 -2
- package/runtime/pi/bin/pi-branch-policy.mjs +37 -0
- package/runtime/pi/bin/pi-observe-context.mjs +97 -4
- package/runtime/pi/bin/pi-render-spec.mjs +0 -1
- package/runtime/pi/bin/pi-session-start.sh +4 -1
- package/runtime/pi/bin/pi-spirit-discovery.mjs +34 -0
- package/runtime/pi/bin/post-update.sh +181 -0
- package/runtime/pi/bin/prime-render-spec.mjs +0 -1
- package/runtime/pi/bin/publish-artifact.sh +89 -42
- package/runtime/pi/bin/qa-inventory.sh +2 -2
- package/runtime/pi/bin/quest.sh +1 -1
- package/runtime/pi/bin/records.sh +11 -0
- package/runtime/pi/bin/reflexes/05-vitals.sh +9 -0
- package/runtime/pi/bin/reflexes/10-open-items.sh +12 -0
- package/runtime/pi/bin/reflexes/15-retrieval.sh +8 -0
- package/runtime/pi/bin/reflexes/20-nightly.sh +100 -0
- package/runtime/pi/bin/reflexes/20-sandbox.sh +85 -0
- package/runtime/pi/bin/reflexes/30-cost.py +116 -0
- package/runtime/pi/bin/reflexes/40-shells.py +51 -0
- package/runtime/pi/bin/reflexes/README.md +61 -0
- package/runtime/pi/bin/reflexes.sh +7 -0
- package/runtime/pi/bin/runtime-identity.sh +140 -42
- package/runtime/pi/bin/screenshot.sh +77 -0
- package/runtime/pi/bin/scroll.sh +1 -1
- package/runtime/pi/bin/search.sh +31 -5
- package/runtime/pi/bin/session-autosave.sh +6 -3
- package/runtime/pi/bin/session-id.sh +147 -0
- package/runtime/pi/bin/session-log.sh +19 -0
- package/runtime/pi/bin/session-record.sh +26 -0
- package/runtime/pi/bin/settings.sh +13 -8
- package/runtime/pi/bin/spirit-discovery-claude.sh +4 -0
- package/runtime/pi/bin/spirit-discovery-codex.sh +4 -0
- package/runtime/pi/bin/spirit-discovery-pi.sh +4 -0
- package/runtime/pi/bin/spirit-discovery-prime.sh +4 -0
- package/runtime/pi/bin/spirit-discovery.sh +4 -0
- package/runtime/pi/bin/startup-check.sh +1 -1
- package/runtime/pi/bin/telemetry.sh +11 -4
- package/runtime/pi/bin/test-baseline.sh +33 -5
- package/runtime/pi/bin/todo.sh +1 -1
- package/runtime/pi/bin/worktree-create.sh +15 -45
- package/runtime/pi/bin/worktree.sh +6 -0
- package/runtime/pi/docs/spirit-discovery.md +96 -0
- package/runtime/pi/egregore_runtime/__init__.py +18 -12
- package/runtime/pi/egregore_runtime/access.py +608 -0
- package/runtime/pi/egregore_runtime/access_cli.py +190 -0
- package/runtime/pi/egregore_runtime/adapters/invitation.py +5 -3
- package/runtime/pi/egregore_runtime/adapters/qmd.py +521 -47
- package/runtime/pi/egregore_runtime/admin_entry.py +56 -0
- package/runtime/pi/egregore_runtime/artifacts.py +222 -16
- package/runtime/pi/egregore_runtime/contracts.py +27 -0
- package/runtime/pi/egregore_runtime/eligibility.py +5 -12
- package/runtime/pi/egregore_runtime/episode_binding.py +16 -5
- package/runtime/pi/egregore_runtime/github_issues.py +2 -2
- package/runtime/pi/egregore_runtime/handoff_lookup.py +9 -20
- package/runtime/pi/egregore_runtime/harness_cli.py +674 -149
- package/runtime/pi/egregore_runtime/held.py +2436 -0
- package/runtime/pi/egregore_runtime/hosted_api.py +137 -0
- package/runtime/pi/egregore_runtime/identity.py +196 -65
- package/runtime/pi/egregore_runtime/identity_transfer.py +6 -2
- package/runtime/pi/egregore_runtime/ingest_cli.py +2 -2
- package/runtime/pi/egregore_runtime/ingest_index_cli.py +4 -16
- package/runtime/pi/egregore_runtime/installation.py +119 -0
- package/runtime/pi/egregore_runtime/investigation.py +64 -41
- package/runtime/pi/egregore_runtime/investigation_guidance.py +16 -11
- package/runtime/pi/egregore_runtime/issue_cli.py +51 -32
- package/runtime/pi/egregore_runtime/issue_reporting.py +4 -3
- package/runtime/pi/egregore_runtime/issue_triage_service.py +2 -2
- package/runtime/pi/egregore_runtime/issues.py +12 -6
- package/runtime/pi/egregore_runtime/knowledge.py +331 -5
- package/runtime/pi/egregore_runtime/knowledge_cli.py +57 -17
- package/runtime/pi/egregore_runtime/lifecycle.py +88 -22
- package/runtime/pi/egregore_runtime/lifecycle_cli.py +21 -13
- package/runtime/pi/egregore_runtime/line_ids.py +10 -0
- package/runtime/pi/egregore_runtime/memory_push.py +349 -0
- package/runtime/pi/egregore_runtime/observe.py +64 -25
- package/runtime/pi/egregore_runtime/observers.py +19 -0
- package/runtime/pi/egregore_runtime/optional_modules.py +13 -0
- package/runtime/pi/egregore_runtime/outputs_cli.py +321 -0
- package/runtime/pi/egregore_runtime/policy.py +651 -24
- package/runtime/pi/egregore_runtime/private_result.py +2 -1
- package/runtime/pi/egregore_runtime/projection.py +946 -0
- package/runtime/pi/egregore_runtime/quest_cli.py +20 -23
- package/runtime/pi/egregore_runtime/question_cli.py +15 -11
- package/runtime/pi/egregore_runtime/questions.py +10 -10
- package/runtime/pi/egregore_runtime/quests.py +10 -10
- package/runtime/pi/egregore_runtime/record_publish.py +548 -0
- package/runtime/pi/egregore_runtime/record_subject.py +564 -0
- package/runtime/pi/egregore_runtime/research_ingest.py +2 -4
- package/runtime/pi/egregore_runtime/runtime.py +169 -60
- package/runtime/pi/egregore_runtime/sandbox.py +194 -0
- package/runtime/pi/egregore_runtime/scroll_cli.py +22 -32
- package/runtime/pi/egregore_runtime/scrolls.py +23 -15
- package/runtime/pi/egregore_runtime/shadow.py +262 -0
- package/runtime/pi/egregore_runtime/spirit_discovery.py +487 -0
- package/runtime/pi/egregore_runtime/spirit_discovery_cli.py +25 -0
- package/runtime/pi/egregore_runtime/spirit_discovery_transport.py +18 -0
- package/runtime/pi/egregore_runtime/status.py +101 -44
- package/runtime/pi/egregore_runtime/status_cli.py +13 -5
- package/runtime/pi/egregore_runtime/sync.py +39 -21
- package/runtime/pi/egregore_runtime/taste.py +934 -0
- package/runtime/pi/egregore_runtime/taste_cli.py +242 -0
- package/runtime/pi/egregore_runtime/taste_rules.py +91 -0
- package/runtime/pi/egregore_runtime/telemetry.py +26 -3
- package/runtime/pi/egregore_runtime/todo_cli.py +15 -12
- package/runtime/pi/egregore_runtime/todos.py +3 -2
- package/runtime/pi/egregore_runtime/upgrade.py +85 -58
- package/runtime/pi/egregore_runtime/writeback.py +330 -24
- package/runtime/pi/manifest.json +66 -5
- package/runtime/prime/.claude/context/handoff-claiming.md +32 -0
- package/runtime/prime/.claude/context/notification-consent.md +12 -9
- package/runtime/prime/.claude/skills/view/SKILL.md +438 -0
- package/runtime/prime/.codex/hooks.json +11 -0
- package/runtime/prime/.codex/skills/dark-mode/SKILL.md +1 -1
- package/runtime/prime/.codex/skills/records/SKILL.md +29 -0
- package/runtime/prime/.codex/skills/summon/SKILL.md +1 -1
- package/runtime/prime/.codex/skills/view/assets/compose-scaffold.html +19 -13
- package/runtime/prime/.codex/spec-manifest.json +13 -19
- package/runtime/prime/.prime/agent/APPEND_SYSTEM.md +53 -99
- package/runtime/prime/.prime/agent/extensions/egregore.ts +14 -1
- package/runtime/prime/.prime/agent/skills/egregore/SKILL.md +14 -6
- package/runtime/prime/.prime/agent/skills/egregore/src/egregore/__init__.py +66 -1
- package/runtime/prime/.prime/agent/spec-manifest.json +2 -2
- package/runtime/prime/AGENTS.md +54 -105
- package/runtime/prime/bin/agent.sh +231 -7
- package/runtime/prime/bin/api-call.sh +44 -23
- package/runtime/prime/bin/artifact-register.sh +7 -1
- package/runtime/prime/bin/artifact-writeback.sh +1 -1
- package/runtime/prime/bin/artifacts.sh +66 -265
- package/runtime/prime/bin/attendant.sh +4 -1
- package/runtime/prime/bin/boundary-guard.cjs +1848 -0
- package/runtime/prime/bin/boundary-hook.sh +41 -0
- package/runtime/prime/bin/capture-run.sh +32 -2
- package/runtime/prime/bin/codex-render-spec.mjs +24 -46
- package/runtime/prime/bin/codex-session-start.sh +19 -0
- package/runtime/prime/bin/codex-skill-render.mjs +18 -0
- package/runtime/prime/bin/config-get.sh +10 -1
- package/runtime/prime/bin/connect-refresh.sh +16 -0
- package/runtime/prime/bin/corpus_map.py +5 -0
- package/runtime/prime/bin/data/capabilities/prime.json +1458 -0
- package/runtime/prime/bin/genui.sh +19 -0
- package/runtime/prime/bin/graph-batch.sh +1 -1
- package/runtime/prime/bin/graph-op.sh +14 -0
- package/runtime/prime/bin/graph.sh +1 -1
- package/runtime/prime/bin/handoff-pr-backfill.sh +1 -1
- package/runtime/prime/bin/handoff-run.sh +11 -6
- package/runtime/prime/bin/ingest-item.sh +1 -1
- package/runtime/prime/bin/ingest-surface.html +22 -4
- package/runtime/prime/bin/issue.sh +1 -1
- package/runtime/prime/bin/knowledge.sh +1 -1
- package/runtime/prime/bin/lib/card-delivery.sh +329 -0
- package/runtime/prime/bin/lib/config.sh +148 -3
- package/runtime/prime/bin/lib/context.sh +38 -67
- package/runtime/prime/bin/lib/genui-entry.py +36 -0
- package/runtime/prime/bin/lib/git-message.sh +25 -6
- package/runtime/prime/bin/lib/git-sync.sh +12 -4
- package/runtime/prime/bin/lib/greeting.sh +255 -28
- package/runtime/prime/bin/lib/handoff_meta.py +294 -0
- package/runtime/prime/bin/lib/health-footer.sh +83 -2
- package/runtime/prime/bin/lib/identity.sh +31 -10
- package/runtime/prime/bin/lib/instance-registry.sh +71 -0
- package/runtime/prime/bin/lib/local_ci_receipt.py +249 -0
- package/runtime/prime/bin/lib/metrics.sh +121 -8
- package/runtime/prime/bin/lib/notices.sh +36 -0
- package/runtime/prime/bin/lib/record_outcomes.py +729 -0
- package/runtime/prime/bin/lib/reflexes.py +267 -0
- package/runtime/prime/bin/lib/retrieval_scorecard.py +624 -0
- package/runtime/prime/bin/lib/session-record-prompt.txt +18 -0
- package/runtime/prime/bin/lib/session_record.py +3747 -0
- package/runtime/prime/bin/lib/session_trail.py +1983 -0
- package/runtime/prime/bin/lib/settings-drift.sh +8 -5
- package/runtime/prime/bin/lib/startup-restart.sh +41 -0
- package/runtime/prime/bin/lib/worktree-links.sh +92 -0
- package/runtime/prime/bin/memory-push.sh +6 -0
- package/runtime/prime/bin/merge-gate.sh +498 -0
- package/runtime/prime/bin/notify.sh +5 -2
- package/runtime/prime/bin/page-access.sh +103 -0
- package/runtime/prime/bin/person.sh +13 -2
- package/runtime/prime/bin/pi-branch-policy.mjs +37 -0
- package/runtime/prime/bin/pi-observe-context.mjs +97 -4
- package/runtime/prime/bin/pi-render-spec.mjs +0 -1
- package/runtime/prime/bin/pi-spirit-discovery.mjs +34 -0
- package/runtime/prime/bin/post-update.sh +181 -0
- package/runtime/prime/bin/prime-render-spec.mjs +0 -1
- package/runtime/prime/bin/prime-session-start.sh +3 -1
- package/runtime/prime/bin/publish-artifact.sh +89 -42
- package/runtime/prime/bin/qa-inventory.sh +2 -2
- package/runtime/prime/bin/quest.sh +1 -1
- package/runtime/prime/bin/records.sh +11 -0
- package/runtime/prime/bin/reflexes/05-vitals.sh +9 -0
- package/runtime/prime/bin/reflexes/10-open-items.sh +12 -0
- package/runtime/prime/bin/reflexes/15-retrieval.sh +8 -0
- package/runtime/prime/bin/reflexes/20-nightly.sh +100 -0
- package/runtime/prime/bin/reflexes/20-sandbox.sh +85 -0
- package/runtime/prime/bin/reflexes/30-cost.py +116 -0
- package/runtime/prime/bin/reflexes/40-shells.py +51 -0
- package/runtime/prime/bin/reflexes/README.md +61 -0
- package/runtime/prime/bin/reflexes.sh +7 -0
- package/runtime/prime/bin/runtime-identity.sh +140 -42
- package/runtime/prime/bin/screenshot.sh +77 -0
- package/runtime/prime/bin/scroll.sh +1 -1
- package/runtime/prime/bin/search.sh +31 -5
- package/runtime/prime/bin/session-autosave.sh +6 -3
- package/runtime/prime/bin/session-id.sh +147 -0
- package/runtime/prime/bin/session-log.sh +19 -0
- package/runtime/prime/bin/session-record.sh +26 -0
- package/runtime/prime/bin/settings.sh +13 -8
- package/runtime/prime/bin/spirit-discovery-claude.sh +4 -0
- package/runtime/prime/bin/spirit-discovery-codex.sh +4 -0
- package/runtime/prime/bin/spirit-discovery-pi.sh +4 -0
- package/runtime/prime/bin/spirit-discovery-prime.sh +4 -0
- package/runtime/prime/bin/spirit-discovery.sh +4 -0
- package/runtime/prime/bin/startup-check.sh +1 -1
- package/runtime/prime/bin/telemetry.sh +11 -4
- package/runtime/prime/bin/test-baseline.sh +33 -5
- package/runtime/prime/bin/todo.sh +1 -1
- package/runtime/prime/bin/worktree-create.sh +15 -45
- package/runtime/prime/bin/worktree.sh +6 -0
- package/runtime/prime/docs/spirit-discovery.md +96 -0
- package/runtime/prime/egregore_runtime/__init__.py +18 -12
- package/runtime/prime/egregore_runtime/access.py +608 -0
- package/runtime/prime/egregore_runtime/access_cli.py +190 -0
- package/runtime/prime/egregore_runtime/adapters/invitation.py +5 -3
- package/runtime/prime/egregore_runtime/adapters/qmd.py +521 -47
- package/runtime/prime/egregore_runtime/admin_entry.py +56 -0
- package/runtime/prime/egregore_runtime/artifacts.py +222 -16
- package/runtime/prime/egregore_runtime/contracts.py +27 -0
- package/runtime/prime/egregore_runtime/eligibility.py +5 -12
- package/runtime/prime/egregore_runtime/episode_binding.py +16 -5
- package/runtime/prime/egregore_runtime/github_issues.py +2 -2
- package/runtime/prime/egregore_runtime/handoff_lookup.py +9 -20
- package/runtime/prime/egregore_runtime/harness_cli.py +674 -149
- package/runtime/prime/egregore_runtime/held.py +2436 -0
- package/runtime/prime/egregore_runtime/hosted_api.py +137 -0
- package/runtime/prime/egregore_runtime/identity.py +196 -65
- package/runtime/prime/egregore_runtime/identity_transfer.py +6 -2
- package/runtime/prime/egregore_runtime/ingest_cli.py +2 -2
- package/runtime/prime/egregore_runtime/ingest_index_cli.py +4 -16
- package/runtime/prime/egregore_runtime/installation.py +119 -0
- package/runtime/prime/egregore_runtime/investigation.py +64 -41
- package/runtime/prime/egregore_runtime/investigation_guidance.py +16 -11
- package/runtime/prime/egregore_runtime/issue_cli.py +51 -32
- package/runtime/prime/egregore_runtime/issue_reporting.py +4 -3
- package/runtime/prime/egregore_runtime/issue_triage_service.py +2 -2
- package/runtime/prime/egregore_runtime/issues.py +12 -6
- package/runtime/prime/egregore_runtime/knowledge.py +331 -5
- package/runtime/prime/egregore_runtime/knowledge_cli.py +57 -17
- package/runtime/prime/egregore_runtime/lifecycle.py +88 -22
- package/runtime/prime/egregore_runtime/lifecycle_cli.py +21 -13
- package/runtime/prime/egregore_runtime/line_ids.py +10 -0
- package/runtime/prime/egregore_runtime/memory_push.py +349 -0
- package/runtime/prime/egregore_runtime/observe.py +64 -25
- package/runtime/prime/egregore_runtime/observers.py +19 -0
- package/runtime/prime/egregore_runtime/optional_modules.py +13 -0
- package/runtime/prime/egregore_runtime/outputs_cli.py +321 -0
- package/runtime/prime/egregore_runtime/policy.py +651 -24
- package/runtime/prime/egregore_runtime/private_result.py +2 -1
- package/runtime/prime/egregore_runtime/projection.py +946 -0
- package/runtime/prime/egregore_runtime/quest_cli.py +20 -23
- package/runtime/prime/egregore_runtime/question_cli.py +15 -11
- package/runtime/prime/egregore_runtime/questions.py +10 -10
- package/runtime/prime/egregore_runtime/quests.py +10 -10
- package/runtime/prime/egregore_runtime/record_publish.py +548 -0
- package/runtime/prime/egregore_runtime/record_subject.py +564 -0
- package/runtime/prime/egregore_runtime/research_ingest.py +2 -4
- package/runtime/prime/egregore_runtime/runtime.py +169 -60
- package/runtime/prime/egregore_runtime/sandbox.py +194 -0
- package/runtime/prime/egregore_runtime/scroll_cli.py +22 -32
- package/runtime/prime/egregore_runtime/scrolls.py +23 -15
- package/runtime/prime/egregore_runtime/shadow.py +262 -0
- package/runtime/prime/egregore_runtime/spirit_discovery.py +487 -0
- package/runtime/prime/egregore_runtime/spirit_discovery_cli.py +25 -0
- package/runtime/prime/egregore_runtime/spirit_discovery_transport.py +18 -0
- package/runtime/prime/egregore_runtime/status.py +101 -44
- package/runtime/prime/egregore_runtime/status_cli.py +13 -5
- package/runtime/prime/egregore_runtime/sync.py +39 -21
- package/runtime/prime/egregore_runtime/taste.py +934 -0
- package/runtime/prime/egregore_runtime/taste_cli.py +242 -0
- package/runtime/prime/egregore_runtime/taste_rules.py +91 -0
- package/runtime/prime/egregore_runtime/telemetry.py +26 -3
- package/runtime/prime/egregore_runtime/todo_cli.py +15 -12
- package/runtime/prime/egregore_runtime/todos.py +3 -2
- package/runtime/prime/egregore_runtime/upgrade.py +85 -58
- package/runtime/prime/egregore_runtime/writeback.py +330 -24
- package/runtime/prime/manifest.json +66 -5
- package/runtime/claude/bin/thread.sh +0 -9
- package/runtime/claude/egregore_runtime/admin_gate.py +0 -102
- package/runtime/claude/egregore_runtime/thread_cli.py +0 -173
- package/runtime/claude/egregore_runtime/threads.py +0 -521
- package/runtime/codex/bin/thread.sh +0 -9
- package/runtime/codex/egregore_runtime/admin_gate.py +0 -102
- package/runtime/codex/egregore_runtime/thread_cli.py +0 -173
- package/runtime/codex/egregore_runtime/threads.py +0 -521
- package/runtime/pi/bin/thread.sh +0 -9
- package/runtime/pi/egregore_runtime/admin_gate.py +0 -102
- package/runtime/pi/egregore_runtime/thread_cli.py +0 -173
- package/runtime/pi/egregore_runtime/threads.py +0 -521
- package/runtime/prime/bin/thread.sh +0 -9
- package/runtime/prime/egregore_runtime/admin_gate.py +0 -102
- package/runtime/prime/egregore_runtime/thread_cli.py +0 -173
- package/runtime/prime/egregore_runtime/threads.py +0 -521
|
@@ -25,6 +25,15 @@ set -euo pipefail
|
|
|
25
25
|
# Set automatically when publish-references.sh invokes us for a child,
|
|
26
26
|
# preventing recursion.
|
|
27
27
|
#
|
|
28
|
+
# --expires <days|never>: close the page's link that many days from now (1-365),
|
|
29
|
+
# or keep it open with never. Left out, a republish keeps the
|
|
30
|
+
# link's current closing date. Org pages only; close, reopen and
|
|
31
|
+
# see opens with bin/artifacts.sh close|reopen|opens <id>.
|
|
32
|
+
#
|
|
33
|
+
# --visible-to <@handle|email,...|public>: open the page only to these signed-in
|
|
34
|
+
# people (Connected only; refused in Local). public reopens it to
|
|
35
|
+
# anyone with the link; left out, a republish keeps the list.
|
|
36
|
+
#
|
|
28
37
|
# Outputs artifact URL on success, exits silently on soft failure (the server
|
|
29
38
|
# could not be reached).
|
|
30
39
|
# Designed for fire-and-forget use: `bash bin/publish-artifact.sh handoff file.md &`
|
|
@@ -40,6 +49,8 @@ set -euo pipefail
|
|
|
40
49
|
|
|
41
50
|
SCRIPT_DIR="$(cd "$(dirname "$0")/.." && pwd)"
|
|
42
51
|
CONFIG="$SCRIPT_DIR/egregore.json"
|
|
52
|
+
# shellcheck source=bin/lib/config.sh
|
|
53
|
+
source "$SCRIPT_DIR/bin/lib/config.sh"
|
|
43
54
|
|
|
44
55
|
# --- Parse arguments ---
|
|
45
56
|
TYPE=""
|
|
@@ -69,6 +80,8 @@ while [[ $# -gt 0 ]]; do
|
|
|
69
80
|
--raw-html) RAW_HTML=1; shift ;;
|
|
70
81
|
--allow-admin) ALLOW_ADMIN=1; shift ;;
|
|
71
82
|
--no-references) SKIP_REFERENCES=1; shift ;;
|
|
83
|
+
--expires) EXPIRES="$2"; shift 2 ;;
|
|
84
|
+
--visible-to) VISIBLE_TO="$2"; shift 2 ;;
|
|
72
85
|
*)
|
|
73
86
|
if [ -z "$TYPE" ]; then
|
|
74
87
|
TYPE="$1"
|
|
@@ -89,6 +102,14 @@ if [ -n "$ARTIFACT_ID" ] && ! [[ "$ARTIFACT_ID" =~ ^[a-zA-Z0-9_-]{1,50}$ ]]; the
|
|
|
89
102
|
echo "--id must be 1-50 chars, alphanumeric/hyphen/underscore only" >&2
|
|
90
103
|
exit 1
|
|
91
104
|
fi
|
|
105
|
+
if [ -n "${EXPIRES:-}" ] && ! [[ "$EXPIRES" =~ ^([1-9][0-9]{0,2}|never)$ && ( "$EXPIRES" == never || "$EXPIRES" -le 365 ) ]]; then
|
|
106
|
+
echo "--expires takes a number of days from 1 to 365, or never" >&2
|
|
107
|
+
exit 1
|
|
108
|
+
fi
|
|
109
|
+
if [ -n "${VISIBLE_TO:-}" ] && ! [[ "$VISIBLE_TO" =~ ^(public|[^,[:space:]]+(,[^,[:space:]]+){0,49})$ ]]; then
|
|
110
|
+
echo "--visible-to takes @handles or emails separated by commas, or public" >&2
|
|
111
|
+
exit 1
|
|
112
|
+
fi
|
|
92
113
|
if [ -n "$CANONICAL_ID" ] && ! [[ "$CANONICAL_ID" =~ ^[mh]-[0-9a-f]{12}$ ]]; then
|
|
93
114
|
echo "--canonical-id must be a memory file id (m- or h- and 12 hex characters)" >&2
|
|
94
115
|
exit 1
|
|
@@ -115,11 +136,24 @@ if [ ! -f "$CONFIG" ] || ! jq -e 'type == "object"' "$CONFIG" >/dev/null 2>&1; t
|
|
|
115
136
|
exit 4
|
|
116
137
|
fi
|
|
117
138
|
|
|
118
|
-
|
|
139
|
+
# A refused address stops here: a Connected org's page must never fall back
|
|
140
|
+
# to the public relay because its saved address is not plain.
|
|
141
|
+
if ! API_URL="$(_hosted_api_url "${EGREGORE_API_URL:-$(jq -r '.api_url // empty' "$CONFIG" 2>/dev/null)}")"; then
|
|
142
|
+
echo "Not published — nothing left this machine." >&2
|
|
143
|
+
exit 4
|
|
144
|
+
fi
|
|
119
145
|
API_KEY="${EGREGORE_API_KEY:-}"
|
|
120
146
|
ORG_SLUG="$(jq -r '.slug // empty' "$CONFIG" 2>/dev/null)"
|
|
121
147
|
VIEW_BASE="https://egregore.xyz/view"
|
|
122
148
|
|
|
149
|
+
# A page opened by identity needs the hosted sign-in, so it is org-only. The
|
|
150
|
+
# public relay would show it to anyone with the link: refuse, upload nothing.
|
|
151
|
+
if [ -n "${VISIBLE_TO:-}" ] && { [ -z "$API_URL" ] || [ -z "$API_KEY" ]; }; then
|
|
152
|
+
echo "Not published — nothing left this machine." >&2
|
|
153
|
+
echo "--visible-to opens a page by identity, which needs Connected mode. In Local mode, hand over the password-protected file instead." >&2
|
|
154
|
+
exit 4
|
|
155
|
+
fi
|
|
156
|
+
|
|
123
157
|
# Resolve "use published renderer" from env first, then egregore.json. The
|
|
124
158
|
# env var lets individuals override per-shell; egregore.json lets an
|
|
125
159
|
# instance (e.g. the upstream dev repo) opt in for every teammate.
|
|
@@ -132,7 +166,7 @@ fi
|
|
|
132
166
|
|
|
133
167
|
# Public relay for OSS share endpoint. Unauthenticated: anything posted here is
|
|
134
168
|
# readable by anyone holding the URL, for 7 days, with nothing in front of it.
|
|
135
|
-
RELAY_URL="
|
|
169
|
+
RELAY_URL="$EGREGORE_HOSTED_API_ORIGIN"
|
|
136
170
|
|
|
137
171
|
# --- Artifact hosting off-switch (compliance / privacy) ---
|
|
138
172
|
# An instance can disable ALL egregore.xyz publishing via `bin/settings.sh hosting off`
|
|
@@ -166,48 +200,40 @@ if [ -z "$API_URL" ] || [ -z "$API_KEY" ]; then
|
|
|
166
200
|
fi
|
|
167
201
|
fi
|
|
168
202
|
|
|
169
|
-
# ---
|
|
170
|
-
#
|
|
171
|
-
#
|
|
172
|
-
#
|
|
173
|
-
# the explicit --allow-admin confirmation, which is
|
|
174
|
-
# replaces normal publication approval.
|
|
175
|
-
|
|
176
|
-
|
|
177
|
-
|
|
178
|
-
|
|
179
|
-
|
|
180
|
-
|
|
203
|
+
# --- Held-content gate: a publish is a hand-over -----------------------------
|
|
204
|
+
# The source and every backtick-referenced memory file go through one
|
|
205
|
+
# `access check --hand-over`: every held class is refused to a non-admin,
|
|
206
|
+
# under every policy, and a failed check refuses too. An admin may publish
|
|
207
|
+
# held material only with the explicit --allow-admin confirmation, which is
|
|
208
|
+
# separate from and never replaces normal publication approval.
|
|
209
|
+
MEMORY_REAL="$(cd "$SCRIPT_DIR/memory" 2>/dev/null && pwd -P || true)"
|
|
210
|
+
SOURCE_REAL="$(cd "$(dirname "$FILE")" && pwd -P)/$(basename "$FILE")"
|
|
211
|
+
if [ -n "$MEMORY_REAL" ] && [[ "$SOURCE_REAL" == "$MEMORY_REAL"/* ]]; then
|
|
212
|
+
SOURCES=("memory/${SOURCE_REAL#"$MEMORY_REAL"/}")
|
|
213
|
+
else
|
|
214
|
+
SOURCES=("$SOURCE_REAL")
|
|
181
215
|
fi
|
|
182
216
|
if [ "$RAW_HTML" -eq 0 ]; then
|
|
183
217
|
while IFS= read -r ref; do
|
|
184
|
-
|
|
185
|
-
rel
|
|
186
|
-
rel="${rel%\`}"
|
|
187
|
-
if [ -f "$SCRIPT_DIR/$rel" ] && _is_admin_only_file "$SCRIPT_DIR/$rel"; then
|
|
188
|
-
ADMIN_MARKED+=("$rel")
|
|
189
|
-
fi
|
|
218
|
+
rel="${ref//\`/}"
|
|
219
|
+
[ -f "$SCRIPT_DIR/$rel" ] && SOURCES+=("$rel")
|
|
190
220
|
done < <(grep -Eo '`memory/[^`[:space:]]+\.(md|html)`' "$FILE" 2>/dev/null | sort -u)
|
|
191
221
|
fi
|
|
192
|
-
|
|
193
|
-
|
|
194
|
-
|
|
195
|
-
|
|
196
|
-
|
|
197
|
-
|
|
198
|
-
|
|
199
|
-
|
|
200
|
-
|
|
201
|
-
|
|
202
|
-
|
|
203
|
-
|
|
204
|
-
|
|
205
|
-
|
|
206
|
-
|
|
207
|
-
echo "re-run with --allow-admin to confirm publishing admin-marked content" >&2
|
|
208
|
-
echo "(this confirmation is separate from normal publication approval)" >&2
|
|
209
|
-
exit 5
|
|
210
|
-
fi
|
|
222
|
+
HELD_CHECK=0
|
|
223
|
+
CHECKED="$(cd "$SCRIPT_DIR" && EGREGORE_ROOT="$SCRIPT_DIR" PYTHONSAFEPATH=1 \
|
|
224
|
+
PYTHONPATH="$SCRIPT_DIR${PYTHONPATH:+:$PYTHONPATH}" \
|
|
225
|
+
python3 -m egregore_runtime.harness_cli access check --hand-over "${SOURCES[@]}" 2>/dev/null)" || HELD_CHECK=$?
|
|
226
|
+
if [ "$HELD_CHECK" -ne 0 ] || [ -z "$CHECKED" ]; then
|
|
227
|
+
echo "publish refused: a non-admin cannot publish held material, or access could not be checked:" >&2
|
|
228
|
+
printf '%s\n' "$CHECKED" | awk -F '\t' '$3 != "allowed" && NF { print " " $1 }' >&2
|
|
229
|
+
exit 5
|
|
230
|
+
fi
|
|
231
|
+
if [ "$ALLOW_ADMIN" -ne 1 ] && printf '%s\n' "$CHECKED" | grep -q ' for everyone else$'; then
|
|
232
|
+
echo "publish refused: this content is held from everyone but admins:" >&2
|
|
233
|
+
printf '%s\n' "$CHECKED" | awk -F '\t' '/ for everyone else$/ { print " " $1 " (" $4 ")" }' >&2
|
|
234
|
+
echo "re-run with --allow-admin to confirm publishing it" >&2
|
|
235
|
+
echo "(this confirmation is separate from normal publication approval)" >&2
|
|
236
|
+
exit 5
|
|
211
237
|
fi
|
|
212
238
|
|
|
213
239
|
# --- Prepare HTML ---
|
|
@@ -291,8 +317,12 @@ fi
|
|
|
291
317
|
RESPONSE=""
|
|
292
318
|
|
|
293
319
|
if [ -n "$API_URL" ] && [ -n "$API_KEY" ]; then
|
|
294
|
-
# Connected mode: permanent, org-scoped
|
|
295
|
-
|
|
320
|
+
# Connected mode: permanent, org-scoped. A list goes to publish-restricted,
|
|
321
|
+
# which a server that cannot open pages by identity does not have: it
|
|
322
|
+
# refuses there instead of ignoring the list and opening the page to all.
|
|
323
|
+
PUBLISH_PATH="/api/artifacts/publish"
|
|
324
|
+
[ -z "${VISIBLE_TO:-}" ] || PUBLISH_PATH="/api/artifacts/publish-restricted"
|
|
325
|
+
RESPONSE=$(curl -s -X POST "${API_URL}${PUBLISH_PATH}" \
|
|
296
326
|
-H "Authorization: Bearer $API_KEY" \
|
|
297
327
|
-F "file=@${TMP_HTML}" \
|
|
298
328
|
-F "artifact_type=${TYPE}" \
|
|
@@ -300,9 +330,14 @@ if [ -n "$API_URL" ] && [ -n "$API_KEY" ]; then
|
|
|
300
330
|
-F "author=${AUTHOR}" \
|
|
301
331
|
-F "description=${DESCRIPTION}" \
|
|
302
332
|
-F "artifact_id=${ARTIFACT_ID}" \
|
|
333
|
+
-F "expires_in_days=${EXPIRES:-}" \
|
|
334
|
+
--form-string "visible_to=${VISIBLE_TO:-}" \
|
|
303
335
|
--max-time 15 2>/dev/null) || true
|
|
304
336
|
else
|
|
305
337
|
# OSS mode: ephemeral, 7-day TTL
|
|
338
|
+
if [ -n "${EXPIRES:-}" ]; then
|
|
339
|
+
echo "Note: --expires applies to organization pages; this public copy closes after 7 days." >&2
|
|
340
|
+
fi
|
|
306
341
|
RESPONSE=$(curl -s -X POST "${RELAY_URL}/api/artifacts/share" \
|
|
307
342
|
-F "file=@${TMP_HTML}" \
|
|
308
343
|
-F "artifact_type=${TYPE}" \
|
|
@@ -334,6 +369,9 @@ if [ -n "$RESPONSE" ]; then
|
|
|
334
369
|
# The server refused (409 for an id another org holds, 400, 413, 503…).
|
|
335
370
|
# A distinct exit code lets callers that report stderr on failure show why.
|
|
336
371
|
DETAIL=$(echo "$RESPONSE" | jq -r 'if (.detail | type) == "string" then .detail else empty end' 2>/dev/null || true)
|
|
372
|
+
if [ -n "${VISIBLE_TO:-}" ] && { [ "$DETAIL" = "Not Found" ] || [ "$DETAIL" = "Method Not Allowed" ]; }; then
|
|
373
|
+
DETAIL="the hosted service cannot open pages by identity yet, so nothing was stored."
|
|
374
|
+
fi
|
|
337
375
|
echo "Not published: ${DETAIL:-the server answered without a URL.}" >&2
|
|
338
376
|
exit 6
|
|
339
377
|
fi
|
|
@@ -345,7 +383,16 @@ fi
|
|
|
345
383
|
# - parent publish failed (no URL),
|
|
346
384
|
# - --raw-html (HTML attachments don't embed markdown refs we'd parse),
|
|
347
385
|
# - --no-references (caller explicitly opts out / recursion guard).
|
|
348
|
-
|
|
386
|
+
# - the page opens by identity (its stored list, so a republish that keeps
|
|
387
|
+
# the list counts): the files it links to would open to anyone.
|
|
388
|
+
RESTRICTED=0
|
|
389
|
+
if [ -n "$URL" ] && [ "$(echo "$RESPONSE" | jq -r '.visible_to | type' 2>/dev/null || true)" = "array" ]; then
|
|
390
|
+
RESTRICTED=1
|
|
391
|
+
if [ -n "$REF_IDS" ] && [ "$SKIP_REFERENCES" -eq 0 ]; then
|
|
392
|
+
echo "Note: the files this page links to were not published; it opens only for the people it is shared with." >&2
|
|
393
|
+
fi
|
|
394
|
+
fi
|
|
395
|
+
if [ -n "$URL" ] && [ "$RESTRICTED" -eq 0 ] && [ "$RAW_HTML" -eq 0 ] && [ "$SKIP_REFERENCES" -eq 0 ]; then
|
|
349
396
|
EGREGORE_REF_IDS="$REF_IDS" bash "$SCRIPT_DIR/bin/publish-references.sh" "$FILE" >/dev/null 2>&1 &
|
|
350
397
|
disown 2>/dev/null || true
|
|
351
398
|
fi
|
|
@@ -236,7 +236,7 @@ if $requested_tree; then
|
|
|
236
236
|
($path | split("/")[-1]) as $basename | .[$basename] += [$path])' \
|
|
237
237
|
"$scratch/head-paths" > "$scratch/head-basenames.json"
|
|
238
238
|
else
|
|
239
|
-
for suite in "$SCRIPT_DIR"/tests/*.sh "$SCRIPT_DIR"/tests/*.py "$SCRIPT_DIR"/bin/tests/*.sh "$SCRIPT_DIR"/bin/tests/*.mjs; do
|
|
239
|
+
for suite in "$SCRIPT_DIR"/tests/*.sh "$SCRIPT_DIR"/tests/*.py "$SCRIPT_DIR"/tests/*.mjs "$SCRIPT_DIR"/bin/tests/*.sh "$SCRIPT_DIR"/bin/tests/*.mjs; do
|
|
240
240
|
if [ -L "$suite" ]; then
|
|
241
241
|
suite_paths_skipped=$((suite_paths_skipped + 1))
|
|
242
242
|
continue
|
|
@@ -286,7 +286,7 @@ while IFS= read -r -d '' file; do
|
|
|
286
286
|
code=0
|
|
287
287
|
if $requested_tree; then
|
|
288
288
|
git -C "$SCRIPT_DIR" grep -l -z -F "${patterns[@]}" "$head_oid" -- \
|
|
289
|
-
':(top,glob)tests/*.sh' ':(top,glob)tests/*.py' \
|
|
289
|
+
':(top,glob)tests/*.sh' ':(top,glob)tests/*.py' ':(top,glob)tests/*.mjs' \
|
|
290
290
|
':(top,glob)bin/tests/*.sh' ':(top,glob)bin/tests/*.mjs' > "$scratch/hits" || code=$?
|
|
291
291
|
while IFS= read -r -d '' suite; do
|
|
292
292
|
jq -cn --arg suite "${suite#"$head_oid":}" --arg match "$file" \
|
package/runtime/pi/bin/quest.sh
CHANGED
|
@@ -3,7 +3,7 @@ set -euo pipefail
|
|
|
3
3
|
|
|
4
4
|
ROOT="$(cd "$(dirname "$0")/.." && pwd)"
|
|
5
5
|
export EGREGORE_ROOT="$ROOT"
|
|
6
|
-
export EGREGORE_SESSION_ID="${EGREGORE_SESSION_ID:-$(cat "$ROOT/.egregore-session-id" 2>/dev/null || true)}"
|
|
6
|
+
export EGREGORE_SESSION_ID="${EGREGORE_SESSION_ID:-$(bash "$ROOT/bin/session-id.sh" --root "$ROOT" 2>/dev/null || cat "$ROOT/.egregore-session-id" 2>/dev/null || true)}"
|
|
7
7
|
export PYTHONSAFEPATH=1 PYTHONPATH="$ROOT${PYTHONPATH:+:$PYTHONPATH}"
|
|
8
8
|
|
|
9
9
|
exec python3 -m egregore_runtime.quest_cli "$@"
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
#!/usr/bin/env bash
|
|
2
|
+
# Personal controls and batch actions for session records.
|
|
3
|
+
set -uo pipefail
|
|
4
|
+
SCRIPT_DIR="$(cd "$(dirname "$0")/.." && pwd)" || exit 0
|
|
5
|
+
command -v jq >/dev/null 2>&1 || exit 0
|
|
6
|
+
command -v python3 >/dev/null 2>&1 || exit 0
|
|
7
|
+
[ -n "${HOME:-}" ] || exit 0
|
|
8
|
+
# The organization's vitals read the records and the gate ledger only.
|
|
9
|
+
[ "${1:-}" = vitals ] && shift && exec python3 "$SCRIPT_DIR/bin/lib/session_record.py" vitals --root "$SCRIPT_DIR" "$@"
|
|
10
|
+
[ "${1:-}" = retrieval ] && shift && exec python3 "$SCRIPT_DIR/bin/lib/retrieval_scorecard.py" --root "$SCRIPT_DIR" "$@"
|
|
11
|
+
exec python3 "$SCRIPT_DIR/bin/lib/session_record.py" records --root "$SCRIPT_DIR" "$@"
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
#!/usr/bin/env bash
|
|
2
|
+
# The organization's pulse: sessions by harness, cost, friction and the merge
|
|
3
|
+
# gate's decisions over the last seven days beside the seven before, from the
|
|
4
|
+
# session records and memory/sessions/gate.jsonl. Silent under two sessions.
|
|
5
|
+
# Writes nothing. Contract: bin/reflexes/README.md.
|
|
6
|
+
set -uo pipefail
|
|
7
|
+
root="${EGREGORE_ROOT:-}"
|
|
8
|
+
[ -n "$root" ] && [ -f "$root/bin/lib/session_record.py" ] && command -v python3 >/dev/null 2>&1 || exit 0
|
|
9
|
+
exec python3 "$root/bin/lib/session_record.py" vitals-line --root "$root" --memory "${EGREGORE_MEMORY:-$root/memory}"
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
#!/usr/bin/env bash
|
|
2
|
+
# Open items carried from the session records: how many, and the oldest. An
|
|
3
|
+
# ownerless item past three days adds the count and the oldest's age; past
|
|
4
|
+
# seven days the line ends with the command that drafts an issue for it.
|
|
5
|
+
# Reads the records of the last fourteen days and the open-items ledger;
|
|
6
|
+
# writes nothing. Contract: bin/reflexes/README.md.
|
|
7
|
+
set -uo pipefail
|
|
8
|
+
root="${EGREGORE_ROOT:-}"
|
|
9
|
+
[ -n "$root" ] && [ -f "$root/bin/lib/session_record.py" ] || exit 0
|
|
10
|
+
command -v python3 >/dev/null 2>&1 || exit 0
|
|
11
|
+
exec python3 "$root/bin/lib/session_record.py" open-items-line --root "$root" \
|
|
12
|
+
--memory "${EGREGORE_MEMORY:-$root/memory}"
|
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
#!/usr/bin/env bash
|
|
2
|
+
# Show: this installation's memory lookups and the organization's session reach
|
|
3
|
+
# over seven days. Silent below two lookups or when organization records are off.
|
|
4
|
+
# One line, at most 160 characters; writes nothing. Contract: README.md.
|
|
5
|
+
set -uo pipefail
|
|
6
|
+
root="${EGREGORE_ROOT:-}"
|
|
7
|
+
[ -n "$root" ] && [ -f "$root/bin/lib/retrieval_scorecard.py" ] && command -v python3 >/dev/null 2>&1 || exit 0
|
|
8
|
+
exec python3 "$root/bin/lib/retrieval_scorecard.py" line --root "$root" --memory "${EGREGORE_MEMORY:-$root/memory}"
|
|
@@ -0,0 +1,100 @@
|
|
|
1
|
+
#!/usr/bin/env bash
|
|
2
|
+
# Reflex, show then propose: the runs of ci.yml on develop, the push run
|
|
3
|
+
# each merge starts and the workflow_dispatch run the nightly dispatcher
|
|
4
|
+
# requests. A run cancelled because a newer merge superseded it is no verdict
|
|
5
|
+
# and is skipped.
|
|
6
|
+
#
|
|
7
|
+
# Silent while the latest finished run is green, or red once. Two or more red
|
|
8
|
+
# runs running name the failing jobs of the latest run; three end with a
|
|
9
|
+
# proposal to give the failure an owner.
|
|
10
|
+
#
|
|
11
|
+
# The answer is cached for six hours in tmp/reflexes/nightly.json, so a warm
|
|
12
|
+
# card makes no gh call. A cold one makes one request, and a second for the
|
|
13
|
+
# failing jobs only when the line will print; both go through gh's own
|
|
14
|
+
# six-hour response cache, which outlives the sweep of tmp/ at session end.
|
|
15
|
+
# Silent when gh or jq is missing, gh is signed out or offline, or the
|
|
16
|
+
# request outlasts the runner's one-second budget.
|
|
17
|
+
set -uo pipefail
|
|
18
|
+
|
|
19
|
+
ROOT="${EGREGORE_ROOT:-$(cd "$(dirname "$0")/../.." 2>/dev/null && pwd)}"
|
|
20
|
+
[ -n "$ROOT" ] && [ -d "$ROOT" ] || exit 0
|
|
21
|
+
CACHE="$ROOT/tmp/reflexes/nightly.json"
|
|
22
|
+
TTL=21600
|
|
23
|
+
BRANCH=develop
|
|
24
|
+
|
|
25
|
+
command -v jq >/dev/null 2>&1 || exit 0
|
|
26
|
+
now="$(date +%s)"
|
|
27
|
+
|
|
28
|
+
fresh() {
|
|
29
|
+
local at
|
|
30
|
+
at="$(jq -r '.fetched_at // 0 | floor' "$CACHE" 2>/dev/null)" || return 1
|
|
31
|
+
case "$at" in ''|*[!0-9]*) return 1 ;; esac
|
|
32
|
+
[ $((at + TTL)) -gt "$now" ]
|
|
33
|
+
}
|
|
34
|
+
|
|
35
|
+
# Reads run conclusions, latest first; prints how many in a row are red.
|
|
36
|
+
red_streak() {
|
|
37
|
+
local conclusion count=0 open=1
|
|
38
|
+
while IFS= read -r conclusion; do
|
|
39
|
+
[ "$open" -eq 1 ] || continue
|
|
40
|
+
case "$conclusion" in
|
|
41
|
+
failure|timed_out|action_required|startup_failure) count=$((count + 1)) ;;
|
|
42
|
+
*) open=0 ;;
|
|
43
|
+
esac
|
|
44
|
+
done
|
|
45
|
+
printf '%s\n' "$count"
|
|
46
|
+
}
|
|
47
|
+
|
|
48
|
+
refresh() {
|
|
49
|
+
local runs jobs='[]' streak latest tmp
|
|
50
|
+
command -v gh >/dev/null 2>&1 || return 1
|
|
51
|
+
[ -f "$ROOT/.github/workflows/ci.yml" ] || return 1
|
|
52
|
+
runs="$(cd "$ROOT" && gh api --cache 6h \
|
|
53
|
+
"repos/{owner}/{repo}/actions/workflows/ci.yml/runs?branch=$BRANCH&per_page=10" 2>/dev/null \
|
|
54
|
+
| jq -c '[.workflow_runs[]? | select(.status == "completed" and .conclusion != "cancelled")
|
|
55
|
+
| {conclusion, createdAt: .created_at, databaseId: .id}] | .[:3]')" || return 1
|
|
56
|
+
streak="$(jq -r '.[].conclusion' <<<"$runs" | red_streak)"
|
|
57
|
+
if [ "$streak" -ge 2 ]; then
|
|
58
|
+
latest="$(jq -r '.[0].databaseId' <<<"$runs")"
|
|
59
|
+
case "$latest" in ''|*[!0-9]*) return 1 ;; esac
|
|
60
|
+
jobs="$(cd "$ROOT" && gh api --cache 6h "repos/{owner}/{repo}/actions/runs/$latest/jobs?per_page=100" 2>/dev/null \
|
|
61
|
+
| jq -c '[.jobs[]? | select(.conclusion == "failure" or .conclusion == "timed_out"
|
|
62
|
+
or .conclusion == "startup_failure" or .conclusion == "action_required")
|
|
63
|
+
| .name | gsub("\\s*[—–-]*\\s*[0-9a-f]{40}"; "")]')" || return 1
|
|
64
|
+
fi
|
|
65
|
+
mkdir -p "${CACHE%/*}" 2>/dev/null || return 1
|
|
66
|
+
tmp="$(mktemp "${CACHE%/*}/.nightly.XXXXXX" 2>/dev/null)" || return 1
|
|
67
|
+
if jq -n --argjson at "$now" --arg branch "$BRANCH" --argjson runs "$runs" --argjson jobs "$jobs" \
|
|
68
|
+
'{fetched_at: $at, branch: $branch, runs: $runs, failing_jobs: $jobs}' >"$tmp" 2>/dev/null; then
|
|
69
|
+
mv -f "$tmp" "$CACHE" || { rm -f "$tmp"; return 1; }
|
|
70
|
+
else
|
|
71
|
+
rm -f "$tmp"
|
|
72
|
+
return 1
|
|
73
|
+
fi
|
|
74
|
+
}
|
|
75
|
+
|
|
76
|
+
render() {
|
|
77
|
+
local streak prefix suffix="" names="" name budget extra=0
|
|
78
|
+
streak="$(jq -r '.runs[]?.conclusion' "$CACHE" 2>/dev/null | red_streak)"
|
|
79
|
+
[ "$streak" -ge 2 ] || return 0
|
|
80
|
+
[ "$streak" -lt 3 ] || suffix=" · propose an owner: /issue"
|
|
81
|
+
prefix="$(jq -r '.branch // "develop"' "$CACHE") red $streak runs running: "
|
|
82
|
+
# The runner cuts a line at 160 characters; keep the proposal inside it.
|
|
83
|
+
budget=$((160 - ${#prefix} - ${#suffix} - 12))
|
|
84
|
+
while IFS= read -r name; do
|
|
85
|
+
[ -n "$name" ] || continue
|
|
86
|
+
if [ -z "$names" ]; then
|
|
87
|
+
names="$name"
|
|
88
|
+
elif [ $((${#names} + 2 + ${#name})) -le "$budget" ]; then
|
|
89
|
+
names="$names, $name"
|
|
90
|
+
else
|
|
91
|
+
extra=$((extra + 1))
|
|
92
|
+
fi
|
|
93
|
+
done < <(jq -r '.failing_jobs[]?' "$CACHE" 2>/dev/null)
|
|
94
|
+
[ "$extra" -eq 0 ] || names="$names and $extra more"
|
|
95
|
+
[ -n "$names" ] || names="$(jq -r '.runs[0].conclusion // "failure"' "$CACHE")"
|
|
96
|
+
printf '%s%s%s\n' "$prefix" "$names" "$suffix"
|
|
97
|
+
}
|
|
98
|
+
|
|
99
|
+
fresh || refresh || exit 0
|
|
100
|
+
render
|
|
@@ -0,0 +1,85 @@
|
|
|
1
|
+
#!/usr/bin/env bash
|
|
2
|
+
# Reflex (show): a session inside a sandbox says what runs degraded and
|
|
3
|
+
# what will not work.
|
|
4
|
+
#
|
|
5
|
+
# Positive markers only, the predicate bin/lib/secret_entry.py and
|
|
6
|
+
# egregore_runtime/sandbox.py use: CODEX_SANDBOX set to anything but empty,
|
|
7
|
+
# none, false or 0, or APP_SANDBOX_CONTAINER_ID set. No marker, no line, on
|
|
8
|
+
# every harness; a missing DISPLAY or a failing write never names a sandbox.
|
|
9
|
+
# With a marker, one file is created and removed where the runtime keeps its
|
|
10
|
+
# per-user state (search and telemetry, resolved as egregore_runtime does).
|
|
11
|
+
# The line follows the result: writable state, and search and browser checks
|
|
12
|
+
# will not work; refused state, and search runs degraded on the workspace
|
|
13
|
+
# copy, with a second line saying that state is read-only here.
|
|
14
|
+
set -u
|
|
15
|
+
|
|
16
|
+
marker="$(printf '%s' "${CODEX_SANDBOX:-}" | tr '[:upper:]' '[:lower:]')"
|
|
17
|
+
case "$marker" in
|
|
18
|
+
""|none|false|0) [ -n "${APP_SANDBOX_CONTAINER_ID:-}" ] || exit 0 ;;
|
|
19
|
+
esac
|
|
20
|
+
|
|
21
|
+
# Create and remove one file in the nearest existing ancestor of a directory;
|
|
22
|
+
# fails when that location refuses the write or keeps the file. A probe file
|
|
23
|
+
# that outlives its test is removed again on the way out, and that retry
|
|
24
|
+
# never fails the probe, even under an inherited errexit.
|
|
25
|
+
probe_file=""
|
|
26
|
+
trap 'if [ -n "$probe_file" ]; then rm -f "$probe_file" 2>/dev/null || true; fi' EXIT
|
|
27
|
+
writable() {
|
|
28
|
+
local dir="$1" parent
|
|
29
|
+
case "$dir" in \~/*) dir="${HOME:-}/${dir#\~/}" ;; esac
|
|
30
|
+
# A relative override is relative to the current directory, as the runtime
|
|
31
|
+
# resolves it; the walk must reach that directory, never stop short of it.
|
|
32
|
+
case "$dir" in /*) ;; *) dir="$PWD/$dir" ;; esac
|
|
33
|
+
while [ ! -e "$dir" ]; do
|
|
34
|
+
parent="${dir%/*}"
|
|
35
|
+
[ -n "$parent" ] || parent=/
|
|
36
|
+
[ "$parent" != "$dir" ] || break
|
|
37
|
+
dir="$parent"
|
|
38
|
+
done
|
|
39
|
+
[ -d "$dir" ] || return 0
|
|
40
|
+
probe_file="$(mktemp "$dir/.egregore-write-probe.XXXXXX" 2>/dev/null)" || { probe_file=""; return 1; }
|
|
41
|
+
rm -f "$probe_file" 2>/dev/null || return 1
|
|
42
|
+
probe_file=""
|
|
43
|
+
}
|
|
44
|
+
|
|
45
|
+
# Both stores key their per-user directory by the resolved memory checkout
|
|
46
|
+
# (QmdLocalRetriever._instance_hash, LocalTelemetrySink's namespace).
|
|
47
|
+
root="${EGREGORE_ROOT:-.}"
|
|
48
|
+
memory="$(cd "$root/memory" 2>/dev/null && pwd -P)" \
|
|
49
|
+
|| memory="$(cd "$root" 2>/dev/null && pwd -P)/memory"
|
|
50
|
+
digest=""
|
|
51
|
+
if command -v shasum >/dev/null 2>&1; then
|
|
52
|
+
digest="$(printf '%s' "$memory" | LC_ALL=C shasum -a 256 2>/dev/null)"
|
|
53
|
+
elif command -v sha256sum >/dev/null 2>&1; then
|
|
54
|
+
digest="$(printf '%s' "$memory" | sha256sum 2>/dev/null)"
|
|
55
|
+
fi
|
|
56
|
+
digest="${digest%% *}"
|
|
57
|
+
|
|
58
|
+
search_state="${EGREGORE_QMD_RUNTIME_DIR:-}"
|
|
59
|
+
telemetry_state="${EGREGORE_TELEMETRY_DIR:-}"
|
|
60
|
+
if [ -n "${HOME:-}" ]; then
|
|
61
|
+
[ -n "$search_state" ] || search_state="$HOME/.egregore/runtime/qmd${digest:+/${digest:0:16}}"
|
|
62
|
+
[ -n "$telemetry_state" ] || telemetry_state="$HOME/.egregore/telemetry${digest:+/${digest:0:20}}"
|
|
63
|
+
fi
|
|
64
|
+
|
|
65
|
+
refused=""
|
|
66
|
+
for state in "$search_state" "$telemetry_state"; do
|
|
67
|
+
[ -n "$state" ] || continue
|
|
68
|
+
if ! writable "$state"; then
|
|
69
|
+
refused=1
|
|
70
|
+
break
|
|
71
|
+
fi
|
|
72
|
+
done
|
|
73
|
+
|
|
74
|
+
# shellcheck disable=SC2016 # the backticks are part of each line
|
|
75
|
+
if [ -n "$refused" ]; then
|
|
76
|
+
# The runtime falls back to the workspace copy: lexical search, telemetry
|
|
77
|
+
# kept there. The read-only fact gets its own line, because this one uses
|
|
78
|
+
# 157 of the runner's 160 characters.
|
|
79
|
+
printf '%s\n' 'this session runs in a sandbox: search runs degraded, telemetry stays in the workspace and browser checks will not work · start through `egregore` to lift it'
|
|
80
|
+
printf '%s\n' 'per-user state is read-only here'
|
|
81
|
+
else
|
|
82
|
+
# Per-user state stays in use, but the sandbox refuses the loopback port
|
|
83
|
+
# of the query worker, so search fails instead of degrading.
|
|
84
|
+
printf '%s\n' 'this session runs in a sandbox: search and browser checks will not work · start through `egregore` to lift it'
|
|
85
|
+
fi
|
|
@@ -0,0 +1,116 @@
|
|
|
1
|
+
#!/usr/bin/env python3
|
|
2
|
+
"""Reflex: your session cost over seven days. Show tier.
|
|
3
|
+
|
|
4
|
+
Reads the current person's session records from the last seven days, today
|
|
5
|
+
included, and only the files whose names fall in that window. A priced record
|
|
6
|
+
counts under its harness (a record priced at list price is a Codex session);
|
|
7
|
+
an unpriced record counts apart, with the input tokens from its Cost section.
|
|
8
|
+
Prints one line, leaving out the parts that are zero, and nothing without
|
|
9
|
+
records. Numbers only: no topic, branch or prompt text.
|
|
10
|
+
"""
|
|
11
|
+
import datetime
|
|
12
|
+
import json
|
|
13
|
+
import math
|
|
14
|
+
import os
|
|
15
|
+
import re
|
|
16
|
+
import sys
|
|
17
|
+
from pathlib import Path
|
|
18
|
+
|
|
19
|
+
DAYS = 7
|
|
20
|
+
READ_LIMIT = 256 * 1024
|
|
21
|
+
PRICED = ("ledger", "estimate", "list price")
|
|
22
|
+
LABELS = {"claude": "Claude", "codex": "Codex", "pi": "Pi", "prime": "Prime", "other": "Other"}
|
|
23
|
+
TOKENS = re.compile(r"^- tokens: (\d+) input\b", re.M)
|
|
24
|
+
|
|
25
|
+
|
|
26
|
+
def front_matter(text):
|
|
27
|
+
if not text.startswith("---\n"):
|
|
28
|
+
return {}
|
|
29
|
+
block = text[4:].partition("\n---")[0]
|
|
30
|
+
fields = {}
|
|
31
|
+
for line in block.splitlines():
|
|
32
|
+
key, sep, value = line.partition(":")
|
|
33
|
+
if not sep:
|
|
34
|
+
continue
|
|
35
|
+
value = value.strip()
|
|
36
|
+
try:
|
|
37
|
+
value = json.loads(value)
|
|
38
|
+
except ValueError:
|
|
39
|
+
pass
|
|
40
|
+
fields[key.strip()] = value
|
|
41
|
+
return fields
|
|
42
|
+
|
|
43
|
+
|
|
44
|
+
def amount(value):
|
|
45
|
+
try:
|
|
46
|
+
number = float(value)
|
|
47
|
+
except (TypeError, ValueError):
|
|
48
|
+
return 0.0
|
|
49
|
+
return number if math.isfinite(number) and number > 0 else 0.0
|
|
50
|
+
|
|
51
|
+
|
|
52
|
+
def compact(count):
|
|
53
|
+
value, unit = float(count), ""
|
|
54
|
+
for name in ("K", "M", "B"):
|
|
55
|
+
if round(value, 1) < 1000:
|
|
56
|
+
break
|
|
57
|
+
value, unit = value / 1000, name
|
|
58
|
+
return (f"{value:.1f}".removesuffix(".0") if unit else str(count)) + unit
|
|
59
|
+
|
|
60
|
+
|
|
61
|
+
def main():
|
|
62
|
+
memory = os.environ.get("EGREGORE_MEMORY", "")
|
|
63
|
+
author = re.sub(r"[^a-z0-9_-]", "", os.environ.get("EGREGORE_AUTHOR", "").strip().lower())
|
|
64
|
+
sessions = Path(memory) / "sessions" if memory else None
|
|
65
|
+
if not author or sessions is None or not sessions.is_dir():
|
|
66
|
+
return 0
|
|
67
|
+
today = datetime.date.today()
|
|
68
|
+
priced = dict.fromkeys(LABELS.values(), 0.0)
|
|
69
|
+
unpriced, tokens, seen = 0, 0, set()
|
|
70
|
+
for offset in range(DAYS):
|
|
71
|
+
day = today - datetime.timedelta(days=offset)
|
|
72
|
+
try:
|
|
73
|
+
paths = sorted((sessions / day.strftime("%Y-%m")).glob(day.strftime("%d-") + author + "-*.md"))
|
|
74
|
+
except OSError:
|
|
75
|
+
continue
|
|
76
|
+
for path in paths:
|
|
77
|
+
try:
|
|
78
|
+
with path.open("rb") as stream:
|
|
79
|
+
text = stream.read(READ_LIMIT).decode("utf-8", errors="replace")
|
|
80
|
+
except OSError:
|
|
81
|
+
continue
|
|
82
|
+
meta = front_matter(text)
|
|
83
|
+
owner = str(meta.get("from", "")).strip().lower()
|
|
84
|
+
# Producer-bearing records are never a person's session, including
|
|
85
|
+
# malformed metadata and records copied without a private adapter.
|
|
86
|
+
if any(key.strip().strip("\"'").casefold() in
|
|
87
|
+
{"producer", "producer_principal_id", "producer_identity", "record_owner_actor_id", "subject_kind"}
|
|
88
|
+
and (key != "subject_kind" or value != "human-session") for key, value in meta.items()):
|
|
89
|
+
continue
|
|
90
|
+
session = str(meta.get("session", path.name))
|
|
91
|
+
if meta.get("kind") != "session-record" or owner != author or session in seen:
|
|
92
|
+
continue
|
|
93
|
+
seen.add(session)
|
|
94
|
+
source = meta.get("cost_source", "estimate")
|
|
95
|
+
if source in PRICED:
|
|
96
|
+
harness = "codex" if source == "list price" else str(meta.get("harness") or "claude").lower()
|
|
97
|
+
priced[LABELS.get(harness, "Other")] += amount(meta.get("cost_usd"))
|
|
98
|
+
continue
|
|
99
|
+
unpriced += 1
|
|
100
|
+
match = TOKENS.search(text.partition("\n## Cost\n")[2])
|
|
101
|
+
tokens += int(match.group(1)) if match else 0
|
|
102
|
+
parts = []
|
|
103
|
+
total = sum(priced.values())
|
|
104
|
+
if round(total, 2) > 0:
|
|
105
|
+
split = ", ".join(f"{label} ${value:,.2f}" for label, value in priced.items() if round(value, 2) > 0)
|
|
106
|
+
parts.append(f"${total:,.2f} priced ({split})")
|
|
107
|
+
if unpriced:
|
|
108
|
+
part = f"{unpriced} unpriced session" + ("" if unpriced == 1 else "s")
|
|
109
|
+
parts.append(part + (f", {compact(tokens)} input tokens" if tokens else ""))
|
|
110
|
+
if parts:
|
|
111
|
+
print("7 days: " + " · ".join(parts))
|
|
112
|
+
return 0
|
|
113
|
+
|
|
114
|
+
|
|
115
|
+
if __name__ == "__main__":
|
|
116
|
+
sys.exit(main())
|
|
@@ -0,0 +1,51 @@
|
|
|
1
|
+
#!/usr/bin/env python3
|
|
2
|
+
"""Reflex: refused shell shapes. Show tier.
|
|
3
|
+
|
|
4
|
+
Reads yesterday's session records of the current person and sums the
|
|
5
|
+
`worktree-guard refusals` counter from their Friction sections. Three or
|
|
6
|
+
more prints one line with the count and the pointer to the plain forms.
|
|
7
|
+
"""
|
|
8
|
+
import datetime
|
|
9
|
+
import os
|
|
10
|
+
import re
|
|
11
|
+
import sys
|
|
12
|
+
from pathlib import Path
|
|
13
|
+
|
|
14
|
+
COUNTER = re.compile(r"^- worktree-guard refusals: (\d+)\s*$", re.M)
|
|
15
|
+
FROM = re.compile(r"^from:\s*(.+?)\s*$", re.M)
|
|
16
|
+
|
|
17
|
+
|
|
18
|
+
def main():
|
|
19
|
+
memory = os.environ.get("EGREGORE_MEMORY", "")
|
|
20
|
+
author = os.environ.get("EGREGORE_AUTHOR", "").strip().casefold()
|
|
21
|
+
sessions = Path(memory) / "sessions" if memory else None
|
|
22
|
+
if sessions is None or not sessions.is_dir():
|
|
23
|
+
return 0
|
|
24
|
+
yesterday = datetime.date.today() - datetime.timedelta(days=1)
|
|
25
|
+
folder = sessions / yesterday.strftime("%Y-%m")
|
|
26
|
+
total, files = 0, 0
|
|
27
|
+
try:
|
|
28
|
+
paths = sorted(folder.glob(yesterday.strftime("%d-") + "*.md"))
|
|
29
|
+
except OSError:
|
|
30
|
+
return 0
|
|
31
|
+
for path in paths:
|
|
32
|
+
try:
|
|
33
|
+
text = path.read_text(encoding="utf-8", errors="replace")[:200000]
|
|
34
|
+
except OSError:
|
|
35
|
+
continue
|
|
36
|
+
head = text.partition("\n---")[0]
|
|
37
|
+
owner = FROM.search(head)
|
|
38
|
+
if author and owner and owner.group(1).strip("\"'").casefold() != author:
|
|
39
|
+
continue
|
|
40
|
+
match = COUNTER.search(text)
|
|
41
|
+
if match:
|
|
42
|
+
total += int(match.group(1))
|
|
43
|
+
files += 1
|
|
44
|
+
if total >= 3:
|
|
45
|
+
noun = "session" if files == 1 else "sessions"
|
|
46
|
+
print(f"{total} refused shell commands yesterday across {files} {noun} · plain forms: .claude/context/plain-shell.md")
|
|
47
|
+
return 0
|
|
48
|
+
|
|
49
|
+
|
|
50
|
+
if __name__ == "__main__":
|
|
51
|
+
sys.exit(main())
|