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
|
@@ -75,7 +75,6 @@ function adapt(sourceSpec) {
|
|
|
75
75
|
["Egregore on Codex", "Egregore on Pi"],
|
|
76
76
|
["Codex-native", "Pi-native"],
|
|
77
77
|
["Codex sessions", "Pi sessions"],
|
|
78
|
-
["On Codex", "On Pi"],
|
|
79
78
|
["bin/codex-session-start.sh", "bin/pi-session-start.sh"],
|
|
80
79
|
[".codex/hooks/branch-guard.js", ".pi/extensions/egregore.ts"],
|
|
81
80
|
["PreToolUse hook (launcher `--enable hooks`)", "`tool_call` gate (loaded after Pi project trust)"],
|
|
@@ -0,0 +1,34 @@
|
|
|
1
|
+
// Pi and Prime share this thin adapter; the reader owns all evidence semantics.
|
|
2
|
+
import { join } from 'node:path';
|
|
3
|
+
export function registerSpiritDiscovery(pi, { root, runtime, Type }) {
|
|
4
|
+
if (!['pi', 'prime'].includes(runtime)) throw new Error('invalid discovery adapter');
|
|
5
|
+
pi.registerTool({
|
|
6
|
+
name: 'egregore_discover_capabilities', label: 'Egregore capabilities',
|
|
7
|
+
description: 'Inspect local installed-file evidence and separately authenticated spirit capabilities. Read-only; does not grant or execute work.',
|
|
8
|
+
parameters: Type.Object({ operation: Type.Union(['capabilities.list','capabilities.find','capabilities.describe','capabilities.explain','system.explain'].map(Type.Literal)),
|
|
9
|
+
query: Type.Optional(Type.String({ maxLength: 200 })), id: Type.Optional(Type.String({ maxLength: 160 })) }, { additionalProperties: false }),
|
|
10
|
+
async execute(_id, params) {
|
|
11
|
+
// JSON is argv data; the fixed adapter never accepts a root or runtime selector.
|
|
12
|
+
if (!params || typeof params !== 'object' || Array.isArray(params)
|
|
13
|
+
|| !['capabilities.list','capabilities.find','capabilities.describe','capabilities.explain','system.explain'].includes(params.operation)) throw new Error('invalid discovery query');
|
|
14
|
+
const args = [join(root, 'bin', `spirit-discovery-${runtime}.sh`), params.operation];
|
|
15
|
+
const allowed = params.operation === 'capabilities.find' ? ['operation','query']
|
|
16
|
+
: ['capabilities.describe','capabilities.explain'].includes(params.operation) ? ['operation','id']
|
|
17
|
+
: params.operation === 'system.explain' && Object.hasOwn(params,'id') ? ['operation','id'] : ['operation'];
|
|
18
|
+
if (Object.keys(params).sort().join() !== allowed.sort().join()) throw new Error('invalid discovery query');
|
|
19
|
+
for (const [field, limit] of [['query', 200], ['id', 160]]) {
|
|
20
|
+
if (Object.hasOwn(params, field) && (typeof params[field] !== 'string' || !params[field].trim()
|
|
21
|
+
|| Buffer.from(params[field], 'utf8').toString('utf8') !== params[field]
|
|
22
|
+
|| Buffer.byteLength(params[field]) > limit || /[\x00-\x1f\x7f]/.test(params[field]))) throw new Error('invalid discovery query');
|
|
23
|
+
}
|
|
24
|
+
if (Object.hasOwn(params,'query')) args.push(params.query);
|
|
25
|
+
if (Object.hasOwn(params,'id')) args.push(params.id);
|
|
26
|
+
const response = await pi.exec('bash', args, { timeout: 15000 });
|
|
27
|
+
if (Number(response.code ?? response.status ?? 0) !== 0) throw new Error('discovery is unavailable');
|
|
28
|
+
let value;
|
|
29
|
+
try { value = JSON.parse(response.stdout); } catch { throw new Error('discovery is unavailable'); }
|
|
30
|
+
if (value.schema !== 'egregore.capability-query/v1') throw new Error('discovery is unavailable');
|
|
31
|
+
return { content: [{ type: 'text', text: JSON.stringify(value) }], details: value };
|
|
32
|
+
},
|
|
33
|
+
});
|
|
34
|
+
}
|
|
@@ -43,6 +43,187 @@ if [ ! -e "$SCRIPT_DIR/egregore_runtime" ] && \
|
|
|
43
43
|
MIGRATED=1
|
|
44
44
|
fi
|
|
45
45
|
|
|
46
|
+
# --- Migration: saved hosted address after the October 2026 security reset ---
|
|
47
|
+
# Connected setups before 22 Oct 2026 saved the hosted API's old Railway origin
|
|
48
|
+
# in egregore.json. That origin is retired; requests already resolve it to the
|
|
49
|
+
# hosted API (bin/lib/config.sh), and this rewrites the saved value once so the
|
|
50
|
+
# committed file says where requests go. Only that origin, without a path,
|
|
51
|
+
# changes; other keys, custom origins and Local configs are left alone.
|
|
52
|
+
#
|
|
53
|
+
# The working file and the index copy are handled separately, so /update
|
|
54
|
+
# commits this change and never an unrelated edit someone left in the file.
|
|
55
|
+
# Only the api_url string itself is replaced, byte for byte: formatting, key
|
|
56
|
+
# order, line endings, a byte-order mark and the file mode all stay as they
|
|
57
|
+
# were. An api_url written any other way (escaped, repeated) is left for the
|
|
58
|
+
# person to change by hand. Nothing is rewritten when either copy is Local,
|
|
59
|
+
# when egregore.json is a link (its target may belong to something else; the
|
|
60
|
+
# warning says to change it there), or when the working file is missing or
|
|
61
|
+
# unreadable. Nothing is staged for an untracked, sparse or assume-unchanged
|
|
62
|
+
# file. The index copy is staged first and the working file written second; a
|
|
63
|
+
# failed write restores the index, so the two never disagree about the
|
|
64
|
+
# address. A skip warns on stderr and never stops /update: the resolver
|
|
65
|
+
# already sends every request to the hosted API. Never at session start, where
|
|
66
|
+
# a modified tracked file would stop the startup sync. A source instance
|
|
67
|
+
# (upstream_url "none") skips the update commit, so it is left to the
|
|
68
|
+
# resolver.
|
|
69
|
+
# shellcheck source=bin/lib/config.sh
|
|
70
|
+
source "$SCRIPT_DIR/bin/lib/config.sh"
|
|
71
|
+
address_warn() { echo " ! $*" >&2; }
|
|
72
|
+
# saved_api_url TEXT — the api_url string jq reads from TEXT, if any.
|
|
73
|
+
saved_api_url() { jq -r '.api_url | strings' 2>/dev/null <<< "$1" || true; }
|
|
74
|
+
# other_keys TEXT — everything jq reads from TEXT apart from api_url.
|
|
75
|
+
other_keys() { jq -cS 'del(.api_url)' 2>/dev/null <<< "$1"; }
|
|
76
|
+
# address_state TEXT — "retired" for a Connected config (the _detect_mode
|
|
77
|
+
# test) whose saved address is the retired origin, "local" for a Local one,
|
|
78
|
+
# "keep" for anything else, including text that is not a JSON object.
|
|
79
|
+
address_state() {
|
|
80
|
+
local text="$1" saved
|
|
81
|
+
if ! jq -e 'type == "object"' >/dev/null 2>&1 <<< "$text"; then echo keep; return 0; fi
|
|
82
|
+
if ! jq -e "$EGREGORE_CONNECTED_JQ" >/dev/null 2>&1 <<< "$text"; then echo local; return 0; fi
|
|
83
|
+
saved="$(saved_api_url "$text")"
|
|
84
|
+
if [ "$(jq -r '.upstream_url | strings' 2>/dev/null <<< "$text" || true)" != none ] \
|
|
85
|
+
&& _retired_api_url "$saved" \
|
|
86
|
+
&& [ "$(_hosted_api_url "$saved" 2>/dev/null || true)" = "$EGREGORE_HOSTED_API_ORIGIN" ]; then
|
|
87
|
+
echo retired
|
|
88
|
+
else
|
|
89
|
+
echo keep
|
|
90
|
+
fi
|
|
91
|
+
}
|
|
92
|
+
# hosted_address_text TEXT — sets ADDRESS_TEXT to TEXT with only its api_url
|
|
93
|
+
# string replaced by the hosted address. Fails, leaving it empty, unless TEXT
|
|
94
|
+
# holds "api_url" exactly once, as a string without escapes that is the value
|
|
95
|
+
# jq reads, and the replacement changes nothing else jq can see.
|
|
96
|
+
hosted_address_text() {
|
|
97
|
+
local LC_ALL=C
|
|
98
|
+
local text="$1" key='"api_url"' value_re='^([[:space:]]*:[[:space:]]*")([^"\\]*)"' after updated before_keys after_keys
|
|
99
|
+
ADDRESS_TEXT=""
|
|
100
|
+
case "$text" in *"$key"*) ;; *) return 1 ;; esac
|
|
101
|
+
after="${text#*"$key"}"
|
|
102
|
+
case "$after" in *"$key"*) return 1 ;; esac
|
|
103
|
+
[[ "$after" =~ $value_re ]] || return 1
|
|
104
|
+
[ "${BASH_REMATCH[2]}" = "$(saved_api_url "$text")" ] || return 1
|
|
105
|
+
updated="${text%%"$key"*}$key${BASH_REMATCH[1]}$EGREGORE_HOSTED_API_ORIGIN\"${after#"${BASH_REMATCH[0]}"}"
|
|
106
|
+
[ "$(saved_api_url "$updated")" = "$EGREGORE_HOSTED_API_ORIGIN" ] || return 1
|
|
107
|
+
before_keys="$(other_keys "$text")" && after_keys="$(other_keys "$updated")" \
|
|
108
|
+
&& [ "$before_keys" = "$after_keys" ] || return 1
|
|
109
|
+
ADDRESS_TEXT="$updated"
|
|
110
|
+
}
|
|
111
|
+
# read_exact FILE — sets EXACT_TEXT to FILE's bytes, trailing newlines kept.
|
|
112
|
+
read_exact() {
|
|
113
|
+
local text
|
|
114
|
+
text="$(cat -- "$1" 2>/dev/null && printf .)" || return 1
|
|
115
|
+
EXACT_TEXT="${text%.}"
|
|
116
|
+
}
|
|
117
|
+
config_path="$SCRIPT_DIR/egregore.json"
|
|
118
|
+
worktree_state=absent
|
|
119
|
+
worktree_text=""
|
|
120
|
+
if [ -L "$config_path" ]; then
|
|
121
|
+
worktree_state=link
|
|
122
|
+
elif [ -f "$config_path" ]; then
|
|
123
|
+
if [ -r "$config_path" ] && read_exact "$config_path"; then
|
|
124
|
+
worktree_text="$EXACT_TEXT"
|
|
125
|
+
worktree_state="$(address_state "$worktree_text")"
|
|
126
|
+
else
|
|
127
|
+
worktree_state=unreadable
|
|
128
|
+
fi
|
|
129
|
+
fi
|
|
130
|
+
index_state=untracked
|
|
131
|
+
index_stageable=false
|
|
132
|
+
index_entry="$(git -C "$SCRIPT_DIR" ls-files -s -- egregore.json 2>/dev/null || true)"
|
|
133
|
+
index_mode="${index_entry%% *}"
|
|
134
|
+
index_sha="${index_entry#* }"
|
|
135
|
+
index_sha="${index_sha%% *}"
|
|
136
|
+
index_text=""
|
|
137
|
+
case "$index_entry" in
|
|
138
|
+
100644\ *\ 0$'\t'egregore.json|100755\ *\ 0$'\t'egregore.json)
|
|
139
|
+
index_text="$(git -C "$SCRIPT_DIR" cat-file blob "$index_sha" 2>/dev/null && printf .)" || index_text=""
|
|
140
|
+
if [ -n "$index_text" ]; then
|
|
141
|
+
index_text="${index_text%.}"
|
|
142
|
+
index_state="$(address_state "$index_text")"
|
|
143
|
+
# Only a normal entry ("H"): skip-worktree and assume-unchanged files
|
|
144
|
+
# are set aside from this checkout, so their commits are not ours to make.
|
|
145
|
+
index_tag="$(git -C "$SCRIPT_DIR" ls-files -v -- egregore.json 2>/dev/null || true)"
|
|
146
|
+
[ "${index_tag%% *}" = H ] && index_stageable=true
|
|
147
|
+
else
|
|
148
|
+
index_state=other
|
|
149
|
+
fi
|
|
150
|
+
;;
|
|
151
|
+
'') ;;
|
|
152
|
+
*) index_state=other ;;
|
|
153
|
+
esac
|
|
154
|
+
address_updated=false
|
|
155
|
+
by_hand="set api_url to $EGREGORE_HOSTED_API_ORIGIN by hand"
|
|
156
|
+
if [ "$worktree_state" = link ]; then
|
|
157
|
+
if read_exact "$config_path" && [ "$(address_state "$EXACT_TEXT")" = retired ]; then
|
|
158
|
+
address_warn "egregore.json is a link, so its saved hosted address was left as is; requests still use $EGREGORE_HOSTED_API_ORIGIN. Set api_url to it in the file the link points to."
|
|
159
|
+
fi
|
|
160
|
+
elif [ "$worktree_state" = unreadable ]; then
|
|
161
|
+
address_warn "egregore.json can't be read, so its saved hosted address wasn't checked. If it names the retired address, $by_hand."
|
|
162
|
+
elif [ "$worktree_state" = local ] || [ "$index_state" = local ]; then
|
|
163
|
+
if [ "$worktree_state" = retired ] || [ "$index_state" = retired ]; then
|
|
164
|
+
address_warn "egregore.json is Local in one copy and Connected in the other, so its saved hosted address was left as is; requests still use $EGREGORE_HOSTED_API_ORIGIN."
|
|
165
|
+
fi
|
|
166
|
+
else
|
|
167
|
+
stage_index=false
|
|
168
|
+
write_worktree=false
|
|
169
|
+
if [ "$index_state" = retired ]; then
|
|
170
|
+
if [ "$worktree_state" = absent ]; then
|
|
171
|
+
address_warn "egregore.json is missing from this checkout, so its committed hosted address was left as is."
|
|
172
|
+
elif [ "$index_stageable" != true ]; then
|
|
173
|
+
address_warn "egregore.json is set aside from this checkout (sparse or assume-unchanged), so its committed hosted address was left as is."
|
|
174
|
+
else
|
|
175
|
+
stage_index=true
|
|
176
|
+
fi
|
|
177
|
+
fi
|
|
178
|
+
[ "$worktree_state" != retired ] || write_worktree=true
|
|
179
|
+
index_new=""
|
|
180
|
+
worktree_new=""
|
|
181
|
+
plan_ok=true
|
|
182
|
+
if [ "$stage_index" = true ]; then
|
|
183
|
+
if hosted_address_text "$index_text"; then index_new="$ADDRESS_TEXT"; else plan_ok=false; fi
|
|
184
|
+
fi
|
|
185
|
+
if [ "$write_worktree" = true ]; then
|
|
186
|
+
if hosted_address_text "$worktree_text"; then worktree_new="$ADDRESS_TEXT"; else plan_ok=false; fi
|
|
187
|
+
fi
|
|
188
|
+
if [ "$plan_ok" != true ]; then
|
|
189
|
+
address_warn "egregore.json's api_url is written in a way this update can't change safely, so it was left as is; requests still use $EGREGORE_HOSTED_API_ORIGIN. Please $by_hand."
|
|
190
|
+
elif [ "$stage_index" = true ] || [ "$write_worktree" = true ]; then
|
|
191
|
+
landed=true
|
|
192
|
+
index_staged=false
|
|
193
|
+
if [ "$stage_index" = true ]; then
|
|
194
|
+
if index_blob="$(printf '%s' "$index_new" | git -C "$SCRIPT_DIR" hash-object -w --no-filters --stdin 2>/dev/null)" \
|
|
195
|
+
&& git -C "$SCRIPT_DIR" update-index --cacheinfo "$index_mode,$index_blob,egregore.json" 2>/dev/null; then
|
|
196
|
+
index_staged=true
|
|
197
|
+
else
|
|
198
|
+
landed=false
|
|
199
|
+
address_warn "Could not stage the hosted services address, so egregore.json was left as is; requests still use $EGREGORE_HOSTED_API_ORIGIN. Run /update again, or $by_hand."
|
|
200
|
+
fi
|
|
201
|
+
fi
|
|
202
|
+
if [ "$landed" = true ] && [ "$write_worktree" = true ]; then
|
|
203
|
+
config_mode="$(stat -c '%a' "$config_path" 2>/dev/null || stat -f '%Lp' "$config_path" 2>/dev/null || echo 644)"
|
|
204
|
+
config_tmp="$(mktemp "$config_path.XXXXXX" 2>/dev/null || true)"
|
|
205
|
+
if [ -n "$config_tmp" ] && printf '%s' "$worktree_new" > "$config_tmp" \
|
|
206
|
+
&& chmod "$config_mode" "$config_tmp" && mv -f "$config_tmp" "$config_path"; then
|
|
207
|
+
:
|
|
208
|
+
else
|
|
209
|
+
landed=false
|
|
210
|
+
[ -z "$config_tmp" ] || rm -f "$config_tmp"
|
|
211
|
+
if [ "$index_staged" = true ] \
|
|
212
|
+
&& ! git -C "$SCRIPT_DIR" update-index --cacheinfo "$index_mode,$index_sha,egregore.json" 2>/dev/null; then
|
|
213
|
+
address_warn "Could not update the hosted services address in egregore.json, and its staged copy could not be put back; run git restore --staged egregore.json, then $by_hand."
|
|
214
|
+
else
|
|
215
|
+
address_warn "Could not update the hosted services address in egregore.json; it is unchanged, and requests still use $EGREGORE_HOSTED_API_ORIGIN."
|
|
216
|
+
fi
|
|
217
|
+
fi
|
|
218
|
+
fi
|
|
219
|
+
[ "$landed" != true ] || address_updated=true
|
|
220
|
+
fi
|
|
221
|
+
fi
|
|
222
|
+
if [ "$address_updated" = true ]; then
|
|
223
|
+
echo " ✓ Hosted services address updated after the October security reset"
|
|
224
|
+
MIGRATED=1
|
|
225
|
+
fi
|
|
226
|
+
|
|
46
227
|
# --- Future migrations go here ---
|
|
47
228
|
# Each migration should:
|
|
48
229
|
# 1. Check if it needs to run (idempotent guard)
|
|
@@ -74,7 +74,6 @@ function adapt(sourceSpec) {
|
|
|
74
74
|
["Egregore on Codex", "Egregore on Prime Agent"],
|
|
75
75
|
["Codex-native", "Prime-native"],
|
|
76
76
|
["Codex sessions", "Prime Agent sessions"],
|
|
77
|
-
["On Codex", "On Prime Agent"],
|
|
78
77
|
["bin/codex-session-start.sh", "bin/prime-session-start.sh"],
|
|
79
78
|
[".codex/hooks/branch-guard.js", ".prime/agent/extensions/egregore.ts"],
|
|
80
79
|
["PreToolUse hook (launcher `--enable hooks`)", "`tool_call` gate (loaded from the project-local extension)"],
|
|
@@ -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" \
|
|
@@ -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
|