create-egregore 0.19.33 → 0.20.1
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 +141 -14
- package/bin/cli.js +19 -3
- package/lib/connect-runtime.js +4 -2
- package/lib/local.js +15 -1
- package/lib/prime-runtime.js +208 -0
- package/lib/setup.js +66 -5
- package/package.json +4 -3
- package/runtime/codex/.codex/config.toml +3 -0
- package/runtime/codex/.codex/skills/archive/SKILL.md +1 -1
- package/runtime/codex/.codex/skills/branch/SKILL.md +1 -1
- package/runtime/codex/.codex/skills/checkup/SKILL.md +1 -1
- package/runtime/codex/.codex/skills/commit/SKILL.md +1 -1
- package/runtime/codex/.codex/skills/contribute/SKILL.md +1 -1
- package/runtime/codex/.codex/skills/delete-user/SKILL.md +1 -1
- package/runtime/codex/.codex/skills/ingest/SKILL.md +1 -1
- package/runtime/codex/.codex/skills/ingest-corpus/SKILL.md +29 -0
- package/runtime/codex/.codex/skills/ingest-notion/SKILL.md +29 -0
- package/runtime/codex/.codex/skills/ingest-user-interview/SKILL.md +1 -1
- package/runtime/codex/.codex/skills/issue/SKILL.md +1 -1
- package/runtime/codex/.codex/skills/me/SKILL.md +1 -1
- package/runtime/codex/.codex/skills/meeting/SKILL.md +1 -1
- package/runtime/codex/.codex/skills/note/SKILL.md +1 -1
- package/runtime/codex/.codex/skills/notion-connect/SKILL.md +29 -0
- package/runtime/codex/.codex/skills/onboarding/SKILL.md +1 -1
- package/runtime/codex/.codex/skills/pr/SKILL.md +1 -1
- package/runtime/codex/.codex/skills/pull/SKILL.md +1 -1
- package/runtime/codex/.codex/skills/push/SKILL.md +1 -1
- package/runtime/codex/.codex/skills/reflect/SKILL.md +1 -1
- package/runtime/codex/.codex/skills/review-pr/SKILL.md +1 -1
- package/runtime/codex/.codex/skills/save/SKILL.md +3 -1
- package/runtime/codex/.codex/skills/slack-connect/SKILL.md +1 -1
- package/runtime/codex/.codex/skills/summon/SKILL.md +1 -1
- package/runtime/codex/.codex/skills/sync-repos/SKILL.md +1 -1
- package/runtime/codex/.codex/skills/teams-connect/SKILL.md +29 -0
- package/runtime/codex/.codex/skills/telegram-connect/SKILL.md +1 -1
- package/runtime/codex/.codex/skills/telemetry/SKILL.md +1 -1
- package/runtime/codex/.codex/skills/test/SKILL.md +1 -1
- package/runtime/codex/.codex/skills/tutorial/SKILL.md +1 -1
- package/runtime/codex/.codex/skills/update/SKILL.md +1 -1
- package/runtime/codex/.codex/spec-manifest.json +5 -5
- package/runtime/codex/AGENTS.md +41 -35
- package/runtime/codex/bin/activity-data.sh +4 -8
- package/runtime/codex/bin/agent.sh +17 -5
- package/runtime/codex/bin/attendant.sh +13 -0
- package/runtime/codex/bin/autosave.sh +27 -1
- package/runtime/codex/bin/codex-render-spec.mjs +33 -32
- package/runtime/codex/bin/codex-session-start.sh +3 -1
- package/runtime/codex/bin/codex-sync-skills.sh +6 -1
- package/runtime/codex/bin/graph-batch.sh +25 -6
- package/runtime/codex/bin/graph-op.sh +5 -4
- package/runtime/codex/bin/graph.sh +31 -5
- package/runtime/codex/bin/handoff-pr-backfill.sh +1 -1
- package/runtime/codex/bin/handoff-run.sh +8 -3
- package/runtime/codex/bin/handoff-save-egregore.sh +19 -7
- package/runtime/codex/bin/ingest.py +341 -10
- package/runtime/codex/bin/lib/context.sh +26 -1
- package/runtime/codex/bin/lib/git-message.sh +37 -0
- package/runtime/codex/bin/lib/git-sync.sh +10 -2
- package/runtime/codex/bin/lib/greeting.sh +4 -1
- package/runtime/codex/bin/lib/worktree-links.sh +25 -0
- package/runtime/codex/bin/session-autosave.sh +7 -1
- package/runtime/codex/bin/settings.sh +1 -1
- package/runtime/codex/manifest.json +10 -1
- package/runtime/pi/.codex/config.toml +3 -0
- package/runtime/pi/.codex/skills/archive/SKILL.md +1 -1
- package/runtime/pi/.codex/skills/branch/SKILL.md +1 -1
- package/runtime/pi/.codex/skills/checkup/SKILL.md +1 -1
- package/runtime/pi/.codex/skills/commit/SKILL.md +1 -1
- package/runtime/pi/.codex/skills/contribute/SKILL.md +1 -1
- package/runtime/pi/.codex/skills/delete-user/SKILL.md +1 -1
- package/runtime/pi/.codex/skills/ingest/SKILL.md +1 -1
- package/runtime/pi/.codex/skills/ingest-corpus/SKILL.md +29 -0
- package/runtime/pi/.codex/skills/ingest-notion/SKILL.md +29 -0
- package/runtime/pi/.codex/skills/ingest-user-interview/SKILL.md +1 -1
- package/runtime/pi/.codex/skills/issue/SKILL.md +1 -1
- package/runtime/pi/.codex/skills/me/SKILL.md +1 -1
- package/runtime/pi/.codex/skills/meeting/SKILL.md +1 -1
- package/runtime/pi/.codex/skills/note/SKILL.md +1 -1
- package/runtime/pi/.codex/skills/notion-connect/SKILL.md +29 -0
- package/runtime/pi/.codex/skills/onboarding/SKILL.md +1 -1
- package/runtime/pi/.codex/skills/pr/SKILL.md +1 -1
- package/runtime/pi/.codex/skills/pull/SKILL.md +1 -1
- package/runtime/pi/.codex/skills/push/SKILL.md +1 -1
- package/runtime/pi/.codex/skills/reflect/SKILL.md +1 -1
- package/runtime/pi/.codex/skills/review-pr/SKILL.md +1 -1
- package/runtime/pi/.codex/skills/save/SKILL.md +3 -1
- package/runtime/pi/.codex/skills/slack-connect/SKILL.md +1 -1
- package/runtime/pi/.codex/skills/summon/SKILL.md +1 -1
- package/runtime/pi/.codex/skills/sync-repos/SKILL.md +1 -1
- package/runtime/pi/.codex/skills/teams-connect/SKILL.md +29 -0
- package/runtime/pi/.codex/skills/telegram-connect/SKILL.md +1 -1
- package/runtime/pi/.codex/skills/telemetry/SKILL.md +1 -1
- package/runtime/pi/.codex/skills/test/SKILL.md +1 -1
- package/runtime/pi/.codex/skills/tutorial/SKILL.md +1 -1
- package/runtime/pi/.codex/skills/update/SKILL.md +1 -1
- package/runtime/pi/.codex/spec-manifest.json +5 -5
- package/runtime/pi/.pi/APPEND_SYSTEM.md +57 -33
- package/runtime/pi/.pi/extensions/egregore.ts +17 -6
- package/runtime/pi/.pi/spec-manifest.json +2 -2
- package/runtime/pi/AGENTS.md +41 -35
- package/runtime/pi/bin/activity-data.sh +4 -8
- package/runtime/pi/bin/agent.sh +17 -5
- package/runtime/pi/bin/attendant.sh +13 -0
- package/runtime/pi/bin/autosave.sh +27 -1
- package/runtime/pi/bin/codex-render-spec.mjs +33 -32
- package/runtime/pi/bin/codex-session-start.sh +3 -1
- package/runtime/pi/bin/codex-sync-skills.sh +6 -1
- package/runtime/pi/bin/graph-batch.sh +25 -6
- package/runtime/pi/bin/graph-op.sh +5 -4
- package/runtime/pi/bin/graph.sh +31 -5
- package/runtime/pi/bin/handoff-pr-backfill.sh +1 -1
- package/runtime/pi/bin/handoff-run.sh +8 -3
- package/runtime/pi/bin/handoff-save-egregore.sh +19 -7
- package/runtime/pi/bin/ingest.py +341 -10
- package/runtime/pi/bin/lib/context.sh +26 -1
- package/runtime/pi/bin/lib/git-message.sh +37 -0
- package/runtime/pi/bin/lib/git-sync.sh +10 -2
- package/runtime/pi/bin/lib/greeting.sh +4 -1
- package/runtime/pi/bin/lib/worktree-links.sh +25 -0
- package/runtime/pi/bin/pi-branch-policy.mjs +138 -1
- package/runtime/pi/bin/pi-product-workflows.mjs +35 -7
- package/runtime/pi/bin/pi-render-spec.mjs +52 -26
- package/runtime/pi/bin/session-autosave.sh +7 -1
- package/runtime/pi/bin/settings.sh +1 -1
- package/runtime/pi/manifest.json +10 -1
- package/runtime/prime/.claude/context/notification-consent.md +66 -0
- package/runtime/prime/.codex/config.toml +20 -0
- package/runtime/prime/.codex/hooks/branch-guard.js +461 -0
- package/runtime/prime/.codex/hooks/search-hint.js +67 -0
- package/runtime/prime/.codex/hooks.json +30 -0
- package/runtime/prime/.codex/skills/activity/SKILL.md +82 -0
- package/runtime/prime/.codex/skills/announce/SKILL.md +67 -0
- package/runtime/prime/.codex/skills/archive/SKILL.md +45 -0
- package/runtime/prime/.codex/skills/branch/SKILL.md +29 -0
- package/runtime/prime/.codex/skills/checkup/SKILL.md +45 -0
- package/runtime/prime/.codex/skills/commit/SKILL.md +29 -0
- package/runtime/prime/.codex/skills/contribute/SKILL.md +29 -0
- package/runtime/prime/.codex/skills/create-skill/SKILL.md +29 -0
- package/runtime/prime/.codex/skills/dark-mode/SKILL.md +29 -0
- package/runtime/prime/.codex/skills/dashboard/SKILL.md +59 -0
- package/runtime/prime/.codex/skills/deep-reflect/SKILL.md +109 -0
- package/runtime/prime/.codex/skills/delete-user/SKILL.md +29 -0
- package/runtime/prime/.codex/skills/emissary/SKILL.md +45 -0
- package/runtime/prime/.codex/skills/handoff/SKILL.md +166 -0
- package/runtime/prime/.codex/skills/harvest/QUESTION_PALETTE.md +76 -0
- package/runtime/prime/.codex/skills/harvest/SKILL.md +131 -0
- package/runtime/prime/.codex/skills/ingest/SKILL.md +29 -0
- package/runtime/prime/.codex/skills/ingest-corpus/SKILL.md +29 -0
- package/runtime/prime/.codex/skills/ingest-notion/SKILL.md +29 -0
- package/runtime/prime/.codex/skills/ingest-user-interview/SKILL.md +45 -0
- package/runtime/prime/.codex/skills/invite/SKILL.md +44 -0
- package/runtime/prime/.codex/skills/issue/SKILL.md +45 -0
- package/runtime/prime/.codex/skills/me/SKILL.md +29 -0
- package/runtime/prime/.codex/skills/meeting/SKILL.md +45 -0
- package/runtime/prime/.codex/skills/note/SKILL.md +29 -0
- package/runtime/prime/.codex/skills/notion-connect/SKILL.md +29 -0
- package/runtime/prime/.codex/skills/onboarding/SKILL.md +45 -0
- package/runtime/prime/.codex/skills/pr/SKILL.md +29 -0
- package/runtime/prime/.codex/skills/pull/SKILL.md +29 -0
- package/runtime/prime/.codex/skills/push/SKILL.md +29 -0
- package/runtime/prime/.codex/skills/quest/SKILL.md +80 -0
- package/runtime/prime/.codex/skills/reflect/SKILL.md +45 -0
- package/runtime/prime/.codex/skills/review-pr/SKILL.md +45 -0
- package/runtime/prime/.codex/skills/save/SKILL.md +127 -0
- package/runtime/prime/.codex/skills/slack-connect/SKILL.md +29 -0
- package/runtime/prime/.codex/skills/summon/SKILL.md +45 -0
- package/runtime/prime/.codex/skills/sync-repos/SKILL.md +29 -0
- package/runtime/prime/.codex/skills/teams-connect/SKILL.md +29 -0
- package/runtime/prime/.codex/skills/telegram-connect/SKILL.md +29 -0
- package/runtime/prime/.codex/skills/telemetry/SKILL.md +29 -0
- package/runtime/prime/.codex/skills/test/SKILL.md +45 -0
- package/runtime/prime/.codex/skills/the-spiral/SKILL.md +84 -0
- package/runtime/prime/.codex/skills/tui-design/SKILL.md +45 -0
- package/runtime/prime/.codex/skills/tutorial/SKILL.md +45 -0
- package/runtime/prime/.codex/skills/update/SKILL.md +29 -0
- package/runtime/prime/.codex/skills/view/SKILL.md +156 -0
- package/runtime/prime/.codex/skills/view/agents/openai.yaml +4 -0
- package/runtime/prime/.codex/skills/view/assets/compose-scaffold.html +221 -0
- package/runtime/prime/.codex/skills/visual-explain/SKILL.md +45 -0
- package/runtime/prime/.codex/skills/wrap/SKILL.md +58 -0
- package/runtime/prime/.codex/spec-manifest.json +132 -0
- package/runtime/prime/.prime/agent/APPEND_SYSTEM.md +416 -0
- package/runtime/prime/.prime/agent/extensions/egregore.ts +460 -0
- package/runtime/prime/.prime/agent/settings.json +4 -0
- package/runtime/prime/.prime/agent/skills/egregore/SKILL.md +34 -0
- package/runtime/prime/.prime/agent/skills/egregore/pyproject.toml +13 -0
- package/runtime/prime/.prime/agent/skills/egregore/src/egregore/__init__.py +156 -0
- package/runtime/prime/.prime/agent/spec-manifest.json +12 -0
- package/runtime/prime/AGENTS.md +488 -0
- package/runtime/prime/bin/activity-data.sh +238 -0
- package/runtime/prime/bin/agent.sh +787 -0
- package/runtime/prime/bin/attendant.sh +707 -0
- package/runtime/prime/bin/autosave.sh +112 -0
- package/runtime/prime/bin/capture-reconcile.sh +69 -0
- package/runtime/prime/bin/capture-run.sh +341 -0
- package/runtime/prime/bin/codex-install-skills.sh +78 -0
- package/runtime/prime/bin/codex-render-spec.mjs +435 -0
- package/runtime/prime/bin/codex-session-start.sh +265 -0
- package/runtime/prime/bin/codex-skill-render.mjs +347 -0
- package/runtime/prime/bin/codex-sync-skills.sh +237 -0
- package/runtime/prime/bin/connect-refresh.sh +33 -0
- package/runtime/prime/bin/dashboard-data.sh +178 -0
- package/runtime/prime/bin/graph-batch.sh +79 -0
- package/runtime/prime/bin/graph-op.sh +1102 -0
- package/runtime/prime/bin/graph-wal.sh +229 -0
- package/runtime/prime/bin/graph.sh +223 -0
- package/runtime/prime/bin/handoff-pr-backfill.sh +86 -0
- package/runtime/prime/bin/handoff-run.sh +676 -0
- package/runtime/prime/bin/handoff-save-egregore.sh +224 -0
- package/runtime/prime/bin/index-handoff.sh +322 -0
- package/runtime/prime/bin/ingest-graph.sh +80 -0
- package/runtime/prime/bin/ingest-surface.html +495 -0
- package/runtime/prime/bin/ingest.py +1011 -0
- package/runtime/prime/bin/ingest.sh +279 -0
- package/runtime/prime/bin/ingest_graph.py +856 -0
- package/runtime/prime/bin/ingest_surface.py +544 -0
- package/runtime/prime/bin/lib/artifact-id.sh +46 -0
- package/runtime/prime/bin/lib/config.sh +116 -0
- package/runtime/prime/bin/lib/context.sh +621 -0
- package/runtime/prime/bin/lib/dashboard-artifact.sh +242 -0
- package/runtime/prime/bin/lib/ensure-develop.sh +183 -0
- package/runtime/prime/bin/lib/git-message.sh +37 -0
- package/runtime/prime/bin/lib/git-sync.sh +414 -0
- package/runtime/prime/bin/lib/greeting.sh +519 -0
- package/runtime/prime/bin/lib/hash.sh +13 -0
- package/runtime/prime/bin/lib/identity.sh +213 -0
- package/runtime/prime/bin/lib/metrics.sh +374 -0
- package/runtime/prime/bin/lib/noncode.sh +31 -0
- package/runtime/prime/bin/lib/permissions.sh +106 -0
- package/runtime/prime/bin/lib/time.sh +56 -0
- package/runtime/prime/bin/lib/worktree-links.sh +79 -0
- package/runtime/prime/bin/notify.sh +636 -0
- package/runtime/prime/bin/person.py +630 -0
- package/runtime/prime/bin/person.sh +448 -0
- package/runtime/prime/bin/pi-branch-policy.mjs +312 -0
- package/runtime/prime/bin/pi-product-workflows.mjs +394 -0
- package/runtime/prime/bin/prime-render-spec.mjs +147 -0
- package/runtime/prime/bin/prime-session-start.sh +24 -0
- package/runtime/prime/bin/publish-artifact.sh +271 -0
- package/runtime/prime/bin/publish-references.sh +144 -0
- package/runtime/prime/bin/repo-state.sh +96 -0
- package/runtime/prime/bin/search.sh +240 -0
- package/runtime/prime/bin/session-autosave.sh +215 -0
- package/runtime/prime/bin/session-log.sh +199 -0
- package/runtime/prime/bin/settings.sh +304 -0
- package/runtime/prime/bin/telemetry.sh +391 -0
- package/runtime/prime/bin/worktree-create.sh +128 -0
- package/runtime/prime/bin/worktree-remove.sh +50 -0
- package/runtime/prime/bin/worktree.sh +198 -0
- package/runtime/prime/manifest.json +181 -0
|
@@ -99,6 +99,16 @@ _trigger_auto_thread() {
|
|
|
99
99
|
) >> "$LOGFILE" 2>&1 &
|
|
100
100
|
}
|
|
101
101
|
|
|
102
|
+
# Personal off switch for ambient capture. ripcord_enabled=false disables BOTH
|
|
103
|
+
# ripcord notes and auto-push of dirty worktrees — a user who opts out of
|
|
104
|
+
# ambient capture must not find silent commits either. The attendant's other
|
|
105
|
+
# duties (graph cache, context seed, handoff lifecycle) are unaffected.
|
|
106
|
+
# NOTE: jq's `//` treats false as empty (the auto_update:false gotcha), so the
|
|
107
|
+
# test compares the raw value, never `.key // true`.
|
|
108
|
+
_capture_enabled() {
|
|
109
|
+
[ "$(jq -r '.ripcord_enabled' "$MAIN_DIR/.egregore-state.json" 2>/dev/null)" != "false" ]
|
|
110
|
+
}
|
|
111
|
+
|
|
102
112
|
_author() {
|
|
103
113
|
local a
|
|
104
114
|
a=$(jq -r '.github_username // empty' "$MAIN_DIR/.egregore-state.json" 2>/dev/null)
|
|
@@ -249,6 +259,8 @@ _ripcord() {
|
|
|
249
259
|
local transcript="$1" base author date_ym date_d slug topic file prompts gitsum
|
|
250
260
|
base=$(basename "$transcript" .jsonl)
|
|
251
261
|
|
|
262
|
+
_capture_enabled || return 0
|
|
263
|
+
|
|
252
264
|
grep -q "$base" "$JOURNAL" 2>/dev/null && return 0
|
|
253
265
|
# Session already ended with ceremony? Then the attendant has no business
|
|
254
266
|
# here. Scan only the tail — a session that merely *read* the /handoff or
|
|
@@ -336,6 +348,7 @@ _ripcord() {
|
|
|
336
348
|
# --- Auto-push -------------------------------------------------------------
|
|
337
349
|
|
|
338
350
|
_auto_push() {
|
|
351
|
+
_capture_enabled || return 0
|
|
339
352
|
local wt branch dirty ahead upstream
|
|
340
353
|
git -C "$MAIN_DIR" worktree list --porcelain 2>/dev/null | awk '/^worktree /{print $2}' | while read -r wt; do
|
|
341
354
|
branch=$(git -C "$wt" branch --show-current 2>/dev/null)
|
|
@@ -28,6 +28,17 @@ set -uo pipefail
|
|
|
28
28
|
SCRIPT_DIR="$(cd "$(dirname "$0")/.." && pwd)"
|
|
29
29
|
STATE_FILE="$SCRIPT_DIR/.egregore-state.json"
|
|
30
30
|
|
|
31
|
+
# The attendant runs against the MAIN checkout and reads its state file, so
|
|
32
|
+
# ambient-capture settings must be written there — a worktree keeps its own
|
|
33
|
+
# copy, and writing the flag into it would silently do nothing.
|
|
34
|
+
MAIN_STATE_DIR="$SCRIPT_DIR"
|
|
35
|
+
if [ -f "$SCRIPT_DIR/.git" ]; then
|
|
36
|
+
_WT_GITDIR=$(sed 's/^gitdir: //' "$SCRIPT_DIR/.git" 2>/dev/null || true)
|
|
37
|
+
[ -n "$_WT_GITDIR" ] && MAIN_STATE_DIR=$(cd "$_WT_GITDIR/../../.." 2>/dev/null && pwd || echo "$SCRIPT_DIR")
|
|
38
|
+
fi
|
|
39
|
+
MAIN_STATE_FILE="$MAIN_STATE_DIR/.egregore-state.json"
|
|
40
|
+
[ -f "$MAIN_STATE_FILE" ] || MAIN_STATE_FILE="$STATE_FILE"
|
|
41
|
+
|
|
31
42
|
[ -f "$STATE_FILE" ] || echo '{}' > "$STATE_FILE"
|
|
32
43
|
|
|
33
44
|
# NB: jq's `//` swallows false — status would show "on" for enabled:false.
|
|
@@ -42,6 +53,11 @@ set_key() { # key value(json-encoded)
|
|
|
42
53
|
jq ".$1 = $2" "$STATE_FILE" > "$STATE_FILE.tmp" && mv "$STATE_FILE.tmp" "$STATE_FILE"
|
|
43
54
|
}
|
|
44
55
|
|
|
56
|
+
_set_main() { # key value(json-encoded) — writes where the attendant reads
|
|
57
|
+
jq ".$1 = $2" "$MAIN_STATE_FILE" > "$MAIN_STATE_FILE.tmp" \
|
|
58
|
+
&& mv "$MAIN_STATE_FILE.tmp" "$MAIN_STATE_FILE"
|
|
59
|
+
}
|
|
60
|
+
|
|
45
61
|
status() {
|
|
46
62
|
local enabled scope publish
|
|
47
63
|
enabled=$(get '.autosave_enabled' 'false')
|
|
@@ -50,6 +66,7 @@ status() {
|
|
|
50
66
|
echo "autosave: $([ "$enabled" = "true" ] && echo on || echo "off (opt-in — 'autosave on' to join the experiment)")"
|
|
51
67
|
echo "scope: $scope (all = handoffs + artifacts + docs · handoffs = memory repo only)"
|
|
52
68
|
echo "publish: $publish (gate = PRs wait for your merge · auto = merge to develop automatically)"
|
|
69
|
+
echo "ripcord: $(jq -r 'if (.ripcord_enabled != null) then (.ripcord_enabled|tostring) else "true" end' "$MAIN_STATE_FILE" 2>/dev/null || echo true) (crash-recovery notes + branch auto-push when a session dies without /wrap)"
|
|
53
70
|
}
|
|
54
71
|
|
|
55
72
|
case "${1:-status}" in
|
|
@@ -61,6 +78,15 @@ case "${1:-status}" in
|
|
|
61
78
|
all|handoffs) set_key autosave_scope "\"$2\"" && echo "scope: $2" ;;
|
|
62
79
|
*) echo "usage: autosave.sh scope all|handoffs" >&2; exit 2 ;;
|
|
63
80
|
esac ;;
|
|
81
|
+
ripcord)
|
|
82
|
+
# Ambient crash-recovery capture (the attendant): ripcord notes AND
|
|
83
|
+
# auto-push of dirty task branches. Separate from the autosave
|
|
84
|
+
# experiment above — this one defaults ON.
|
|
85
|
+
case "${2:-}" in
|
|
86
|
+
on) _set_main ripcord_enabled true && echo "ripcord: on — dead sessions leave a recovery note" ;;
|
|
87
|
+
off) _set_main ripcord_enabled false && echo "ripcord: off — no ambient notes, no branch auto-push" ;;
|
|
88
|
+
*) echo "usage: autosave.sh ripcord on|off" >&2; exit 2 ;;
|
|
89
|
+
esac ;;
|
|
64
90
|
publish)
|
|
65
91
|
case "${2:-}" in
|
|
66
92
|
gate|auto) set_key autosave_publish "\"$2\"" && echo "publish: $2" ;;
|
|
@@ -82,5 +108,5 @@ case "${1:-status}" in
|
|
|
82
108
|
echo "✗ PR #$n did not merge (conflict with develop?) — it stays open"
|
|
83
109
|
fi
|
|
84
110
|
done ;;
|
|
85
|
-
*) echo "usage: autosave.sh [status|on|off|scope all|handoffs|publish gate|auto|merge]" >&2; exit 2 ;;
|
|
111
|
+
*) echo "usage: autosave.sh [status|on|off|scope all|handoffs|publish gate|auto|merge|ripcord on|off]" >&2; exit 2 ;;
|
|
86
112
|
esac
|
|
@@ -58,6 +58,12 @@ const AGENTS_PREAMBLE = `# Egregore Agent Protocol
|
|
|
58
58
|
> \`.pi/APPEND_SYSTEM.md\`, and your workflows are exposed through the
|
|
59
59
|
> project-local \`.pi/\` runtime. Do not follow the Codex-specific block below.
|
|
60
60
|
>
|
|
61
|
+
> **If you are Prime Agent** (the \`prime-agent\` harness): **stop here.** Your
|
|
62
|
+
> authoritative Egregore instructions are loaded from
|
|
63
|
+
> \`.prime/agent/APPEND_SYSTEM.md\`, and your workflows are exposed through the
|
|
64
|
+
> project-local \`.prime/agent/\` runtime. Do not follow the Codex-specific
|
|
65
|
+
> block below.
|
|
66
|
+
>
|
|
61
67
|
> **If you are Codex or another shell-only agent:** this file is yours — continue.
|
|
62
68
|
|
|
63
69
|
Egregore is no longer only a Claude Code workspace. Claude Code remains the
|
|
@@ -173,26 +179,17 @@ function transformTokens(body) {
|
|
|
173
179
|
|
|
174
180
|
const INTRO_BODY = `You are a collaborator inside Egregore — a shared intelligence layer for organizations using AI coding agents. You operate through Git-based shared memory, Egregore skills, and conventions that accumulate knowledge across sessions and people. You are not a tool. You are a participant.
|
|
175
181
|
|
|
176
|
-
This block is the Codex-native Egregore behavioral spec, rendered from CLAUDE.md
|
|
182
|
+
This block is the Codex-native Egregore behavioral spec, rendered from CLAUDE.md by \`bin/codex-render-spec.mjs\`; the per-section manifest is \`.codex/spec-manifest.json\`. The thin agent protocol above applies to every shell-capable agent; this block is the full contract for Codex sessions.`;
|
|
177
183
|
|
|
178
|
-
const ON_LAUNCH_BODY = `The \`egregore\` launcher renders the
|
|
184
|
+
const ON_LAUNCH_BODY = `The \`egregore\` launcher renders the startup card (identity, momentum, pending work) via \`bin/codex-session-start.sh\` before Codex starts and installs project skills. Do not rerun or narrate startup. The card ends with **"What are you working on?"** — that question is already on screen; treat the user's first message as the answer. Re-show with \`bash bin/codex-session-start.sh --card\`.`;
|
|
179
185
|
|
|
180
186
|
const AFTER_GREETING_BODY = `**Mandatory behavioral rule.** When the user describes work, your **first action** — before reading files, exploring code, or anything else — is to get onto a working branch:
|
|
181
187
|
|
|
182
|
-
The integration branch is \`develop\`
|
|
183
|
-
\`egregore.json.base_branch\` is set, that configured branch replaces
|
|
184
|
-
\`develop\` as the branch point, rebase target, PR base, and protected
|
|
185
|
-
integration branch.
|
|
188
|
+
The integration branch is \`develop\` unless top-level \`egregore.json.base_branch\` sets another; the configured branch is then the branch point, rebase target, PR base, and protected branch everywhere below.
|
|
186
189
|
|
|
187
190
|
1. Derive a topic slug from what the user said (kebab-case, 2–4 words)
|
|
188
191
|
2. Run \`bin/agent.sh branch --topic "<topic>"\` — it resolves the configured base and creates a work branch from \`origin/{base}\` in a task worktree (\`dev/{author}/{slug}\`, or \`feature/{slug}\` / \`bugfix/{slug}\` when the topic reads as a feature or fix). Continue all file work from the printed path.
|
|
189
|
-
3. Give a value-first workspace receipt
|
|
190
|
-
|
|
191
|
-
\`Your stable project is protected. I’m working in a separate workspace for **{topic}**, where changes stay isolated, reviewable, and reversible.\`
|
|
192
|
-
|
|
193
|
-
Then expose the implementation as secondary detail:
|
|
194
|
-
|
|
195
|
-
\`Workspace: {branch} (worktree).\`
|
|
192
|
+
3. Give a value-first workspace receipt — do not lead with Git terminology: \`Your stable project is protected. I’m working in a separate workspace for **{topic}**, where changes stay isolated, reviewable, and reversible.\` Then, as secondary detail: \`Workspace: {branch} (worktree).\`
|
|
196
193
|
|
|
197
194
|
**Fallback:** If \`bin/agent.sh branch\` fails, resolve \`{base}\` with
|
|
198
195
|
\`_get_base_branch\`, then use
|
|
@@ -202,14 +199,20 @@ integration branch.
|
|
|
202
199
|
|
|
203
200
|
### Starting-work UX contract
|
|
204
201
|
|
|
205
|
-
|
|
202
|
+
Sequence: **intent → safe workspace → relevant context → consequential assumptions → execution**. Make Egregore's structure legible without turning task starts into a tutorial; keep technical identifiers secondary to user value.
|
|
203
|
+
|
|
204
|
+
- **Workspace** — the value-first receipt above, only for a new workspace or topic pivot; do not repeat it on the same branch.
|
|
205
|
+
- **Context** — when organizational retrieval materially informs the work, keep the required Egregore Retrieval Beat plus one compact receipt: \`↳ Context restored: {decision, handoff, or prior work} · {source/date}\`. Never claim context was restored when retrieval found nothing useful.
|
|
206
|
+
- **Assumptions** — surface only consequential ones: \`Assumption: {assumption} — based on {evidence}.\` Add a correction path when cheap; do not narrate obvious operational choices.
|
|
207
|
+
- **Transition** — state the outcome you are starting toward in one short sentence and begin.
|
|
208
|
+
|
|
209
|
+
### Returning-work UX contract
|
|
206
210
|
|
|
207
|
-
|
|
208
|
-
- **Context** — when organizational retrieval materially informs the work, keep the required Egregore Retrieval Beat and then add one compact result receipt: \`↳ Context restored: {decision, handoff, or prior work} · {source/date}\`. Never claim context was restored when retrieval found nothing useful.
|
|
209
|
-
- **Assumptions** — surface only consequential assumptions that could change the implementation. Use \`Assumption: {assumption} — based on {evidence}.\` Add a correction path when cheap; do not narrate obvious operational choices.
|
|
210
|
-
- **Transition** — once workspace, context, and assumptions are settled, state the outcome you are starting toward in one short sentence and begin.
|
|
211
|
+
When the user continues the current branch's work or asks to resume — sequence: **continuation intent → prior workspace → restored context → open threads → resumed execution**:
|
|
211
212
|
|
|
212
|
-
|
|
213
|
+
- Do not create a new workspace for the same topic. After confirming relevance, say: \`I found your previous work on **{topic}** and restored its workspace and context.\` Show \`Workspace: {branch} (worktree).\` secondarily.
|
|
214
|
+
- Retrieve relevant decisions, handoffs, or prior work; keep the Retrieval Beat and \`↳ Context restored:\` receipt. Never claim context was restored from a branch name alone.
|
|
215
|
+
- Name only unresolved items that could change the next move, state the next outcome briefly, and continue without replaying setup.
|
|
213
216
|
|
|
214
217
|
### Handoff claiming
|
|
215
218
|
|
|
@@ -218,7 +221,7 @@ If \`addressed_to_user\` handoffs exist and the user is picking one up, create t
|
|
|
218
221
|
bash bin/graph-op.sh claim-handoff "$SESSION_ID" "$HANDOFF_SESSION_ID" 2>/dev/null &
|
|
219
222
|
\`\`\`
|
|
220
223
|
|
|
221
|
-
**Auto-checkout repos from handoff**:
|
|
224
|
+
**Auto-checkout repos from handoff**: after claiming, if \`addressed_rich\` carries a non-empty \`repoState\`, check out each entry's branch in its managed repo:
|
|
222
225
|
|
|
223
226
|
\`\`\`bash
|
|
224
227
|
PARENT_DIR="$(cd .. && pwd)"
|
|
@@ -231,21 +234,19 @@ if [ -d "$REPO_DIR/.git" ] || [ -f "$REPO_DIR/.git" ]; then
|
|
|
231
234
|
fi
|
|
232
235
|
\`\`\`
|
|
233
236
|
|
|
234
|
-
Report
|
|
237
|
+
Report \`✓ Checked out {branch} in {repo1}, {repo2}\`; for a merged-away branch, \`◐ {repo}: PR #{N} merged — on {base}\`. If \`repoState\` is absent or empty, skip silently.
|
|
235
238
|
|
|
236
|
-
**Exceptions** — skip branching when
|
|
237
|
-
- The user explicitly created or named a branch themselves
|
|
238
|
-
- Already on a working branch AND the user's intent continues the current branch's topic
|
|
239
|
+
**Exceptions** — skip branching when the user explicitly created or named a branch themselves, or the intent continues the current working branch's topic.
|
|
239
240
|
|
|
240
|
-
**Topic pivot
|
|
241
|
+
**Topic pivot:** work **unrelated** to the current branch's topic gets a new branch (\`bin/agent.sh branch --topic "<new topic>"\`). Do NOT mix unrelated work on one branch.
|
|
241
242
|
|
|
242
243
|
If still on the configured base branch after two messages, create a branch immediately from whatever context you have.
|
|
243
244
|
|
|
244
245
|
### Branch-guard protocol
|
|
245
246
|
|
|
246
|
-
The \`.codex/hooks/branch-guard.js\` PreToolUse hook (
|
|
247
|
+
The \`.codex/hooks/branch-guard.js\` PreToolUse hook (launcher \`--enable hooks\`) protects project writes on the configured base plus \`develop\`/\`main\`/\`master\`. Its block message is operational guidance — do not interrupt the user with routine Git choices:
|
|
247
248
|
|
|
248
|
-
- **Topic is clear**
|
|
249
|
+
- **Topic is clear** → run \`bin/agent.sh branch --topic "<topic>"\` automatically, continue in the printed worktree, and say one short sentence so the change is visible — never ask approval for routine branching.
|
|
249
250
|
- **Topic is genuinely ambiguous** → ask only for the topic, using compact numbered options:
|
|
250
251
|
|
|
251
252
|
\`\`\`text
|
|
@@ -258,7 +259,7 @@ The \`.codex/hooks/branch-guard.js\` PreToolUse hook (enabled by the launcher vi
|
|
|
258
259
|
Wait for the reply, then branch.
|
|
259
260
|
- **The user explicitly requested the protected branch** → that request is consent. Record it with \`echo '{branch}' > .egregore-branch-consent\`, then retry. Never create the marker merely to silence the hook.
|
|
260
261
|
|
|
261
|
-
Memory, managed-repo, and runtime-state writes
|
|
262
|
+
Memory, managed-repo, and runtime-state writes bypass the project guard — if one triggers it, correct the target/context instead of asking for consent.
|
|
262
263
|
|
|
263
264
|
If this Codex build does not support hooks, follow the same discipline as a standing instruction: never write or commit on the configured base, develop, main, or master.
|
|
264
265
|
|
|
@@ -266,7 +267,7 @@ If this Codex build does not support hooks, follow the same discipline as a stan
|
|
|
266
267
|
|
|
267
268
|
If the startup card output contains \`onboarding_needed\`, invoke the \`$onboarding\` skill instead of greeting.`;
|
|
268
269
|
|
|
269
|
-
const COMMAND_AWARENESS_PREPEND = `Codex reserves leading \`/\` for built-ins, so Egregore workflows are **skills**, not slash commands. Invoke them with the matching \`$name\` skill token or from natural language intent ("show activity", "make a handoff"). Hand-written native Codex skills: \`$activity\`, \`$handoff\`, \`$wrap\`, \`$announce\`, \`$harvest\`, \`$the-spiral\`, \`$dashboard\`, \`$deep-reflect\`, \`$quest\`, \`$invite\`, \`$ask\`, \`$save\`, \`$view\`,
|
|
270
|
+
const COMMAND_AWARENESS_PREPEND = `Codex reserves leading \`/\` for built-ins, so Egregore workflows are **skills**, not slash commands. Invoke them with the matching \`$name\` skill token or from natural language intent ("show activity", "make a handoff"). Hand-written native Codex skills: \`$activity\`, \`$handoff\`, \`$wrap\`, \`$announce\`, \`$harvest\`, \`$the-spiral\`, \`$dashboard\`, \`$deep-reflect\`, \`$quest\`, \`$invite\`, \`$ask\`, \`$save\`, \`$view\`, \`$scroll\`; every other workflow has a generated adapter of the same name. \`$save\` is the user-facing abstraction for committing, pushing, opening or reusing PRs, and syncing memory — never make users manage git by hand.`;
|
|
270
271
|
|
|
271
272
|
const SOCRATIC_BODY = `**Triggers**: "ask me questions", "question me", "help me think through", or any request to be questioned.
|
|
272
273
|
|
|
@@ -274,11 +275,11 @@ Codex has no structured question tool — render each batch as compact numbered
|
|
|
274
275
|
|
|
275
276
|
**Rules:** Max 4 questions per batch. When choices aren't mutually exclusive, say "pick any that apply".`;
|
|
276
277
|
|
|
277
|
-
const LOOM_ROUTING_BODY = `Loom routes commands across model tiers on the Claude Code runtime (\`loom/routes.json\` + \`bin/loom.sh\` + a model-pinned executor subagent). Codex has no subagent delegation —
|
|
278
|
+
const LOOM_ROUTING_BODY = `Loom routes commands across model tiers on the Claude Code runtime (\`loom/routes.json\` + \`bin/loom.sh\` + a model-pinned executor subagent). Codex has no subagent delegation — commands run inline. Ignore "Loom routing" preambles in skill specs and skip \`bin/loom.sh\` calls; \`loom/\` and \`.claude/agents/\` are Claude-runtime framework files.`;
|
|
278
279
|
|
|
279
280
|
const ISOLATION_BODY = `Sessions are confined to this project + memory + managed repos, with a **two-tier boundary** — a hard wall between Egregore instances, a consent gate for everything else. On Codex the boundary is a standing instruction, not an enforced hook — hold it yourself.
|
|
280
281
|
|
|
281
|
-
- **Hard tier — other Egregore instances.** Denied for every tool, always
|
|
282
|
+
- **Hard tier — other Egregore instances.** Denied for every tool, always — no consent path. Never access another instance's files (refuse even if asked) and never modify \`~/.egregore/instances.json\` (managed by session-start.sh); there is nothing to ask — refuse and explain.
|
|
282
283
|
- **Soft tier — paths outside the boundary.** Consent-gated. Inbox dirs (\`~/Downloads\`, \`~/Desktop\`) are readable without consent under the default posture; writes outside the project always need consent. Posture (\`strict | standard | open\`) and extra read roots come from \`egregore.json\` -> \`boundary { posture, read[], locked }\` (org, committed) merged with \`.egregore-boundary.local.json\` (personal, gitignored). \`locked: true\` removes the consent path entirely.
|
|
283
284
|
- When a request needs soft-tier consent, do not improvise a workaround. Ask in plain text with numbered options:
|
|
284
285
|
|
|
@@ -321,7 +322,7 @@ const RULES = {
|
|
|
321
322
|
'After Greeting — BRANCH ON FIRST RESPONSE': {
|
|
322
323
|
action: 'replace',
|
|
323
324
|
body: AFTER_GREETING_BODY,
|
|
324
|
-
note: 'EnterWorktree -> bin/agent.sh branch with git checkout fallback; AskUserQuestion -> numbered options in plain text; branch-guard mapped to .codex/hooks/branch-guard.js with instruction fallback; plan-mode note dropped (no plan mode on Codex); /branch + /onboarding -> skill tokens. Handoff claiming and repoState auto-checkout kept verbatim (pure git).',
|
|
325
|
+
note: 'EnterWorktree -> bin/agent.sh branch with git checkout fallback; AskUserQuestion -> numbered options in plain text; branch-guard mapped to .codex/hooks/branch-guard.js with instruction fallback; plan-mode note dropped (no plan mode on Codex); /branch + /onboarding -> skill tokens. Handoff claiming and repoState auto-checkout bash kept verbatim (pure git); surrounding prose compressed 2026-08 for the 32 KiB budget, every rule retained.',
|
|
325
326
|
},
|
|
326
327
|
'Config Files': { action: 'keep', note: 'Kept verbatim — shell facts, runtime-neutral.' },
|
|
327
328
|
'Knowledge Graph': { action: 'keep', note: 'Kept verbatim — bin/graph.sh is runtime-neutral.' },
|
|
@@ -210,7 +210,9 @@ render_card() {
|
|
|
210
210
|
|
|
211
211
|
# Staged auto-saves awaiting the user's merge (the autosave consent gate).
|
|
212
212
|
# Live gh query so the line persists until the PRs actually merge.
|
|
213
|
-
|
|
213
|
+
# Shown only while the autosave experiment is enabled.
|
|
214
|
+
autosave_on=$(jq -r '.autosave_enabled // false' "$STATE_FILE" 2>/dev/null)
|
|
215
|
+
if [ "$autosave_on" = "true" ] && command -v gh >/dev/null 2>&1; then
|
|
214
216
|
gh_self=$(jq -r '.github_username // empty' "$STATE_FILE" 2>/dev/null)
|
|
215
217
|
if [ -n "$gh_self" ]; then
|
|
216
218
|
waiting_as=$(gh pr list --state open --author "$gh_self" --limit 20 \
|
|
@@ -101,7 +101,12 @@ skill_description() {
|
|
|
101
101
|
in_fm && $0 == "---" { exit }
|
|
102
102
|
in_fm && /^description:/ {
|
|
103
103
|
sub(/^description:[[:space:]]*/, "")
|
|
104
|
-
|
|
104
|
+
# Block scalars (description: >) keep the text on continuation lines we
|
|
105
|
+
# do not read. Emit nothing so the caller falls back, which the skill-v1
|
|
106
|
+
# contract check reports, rather than publishing the indicator itself.
|
|
107
|
+
if ($0 ~ /^[>|][-+]?[[:space:]]*$/) { exit }
|
|
108
|
+
if ($0 ~ /^".*"$/) { gsub(/^"|"$/, "") }
|
|
109
|
+
else if ($0 ~ /^\047.*\047$/) { gsub(/^\047|\047$/, ""); gsub(/\047\047/, "\047") }
|
|
105
110
|
print
|
|
106
111
|
exit
|
|
107
112
|
}
|
|
@@ -24,21 +24,40 @@ if [ "$_MODE" = "local" ]; then
|
|
|
24
24
|
exit 0
|
|
25
25
|
fi
|
|
26
26
|
|
|
27
|
-
# Load specific variables from .env if it exists (safe extraction, no arbitrary code execution)
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
27
|
+
# Load specific variables from .env if it exists (safe extraction, no arbitrary code execution).
|
|
28
|
+
# A worktree missing its .env symlink resolves through worktree-links.sh, which
|
|
29
|
+
# self-heals the link and falls back to the main checkout's .env.
|
|
30
|
+
_ENV_FILE="$SCRIPT_DIR/.env"
|
|
31
|
+
if [ ! -f "$_ENV_FILE" ] && [ -f "$SCRIPT_DIR/bin/lib/worktree-links.sh" ]; then
|
|
32
|
+
# shellcheck source=bin/lib/worktree-links.sh
|
|
33
|
+
source "$SCRIPT_DIR/bin/lib/worktree-links.sh" 2>/dev/null || true
|
|
34
|
+
_ENV_FILE="$(egregore_env_file "$SCRIPT_DIR" 2>/dev/null || true)"
|
|
35
|
+
fi
|
|
36
|
+
if [ -n "$_ENV_FILE" ] && [ -f "$_ENV_FILE" ]; then
|
|
37
|
+
EGREGORE_API_URL="${EGREGORE_API_URL:-$(grep '^EGREGORE_API_URL=' "$_ENV_FILE" 2>/dev/null | cut -d'=' -f2- || true)}"
|
|
38
|
+
EGREGORE_API_KEY="${EGREGORE_API_KEY:-$(grep '^EGREGORE_API_KEY=' "$_ENV_FILE" 2>/dev/null | cut -d'=' -f2- || true)}"
|
|
31
39
|
fi
|
|
32
40
|
|
|
33
41
|
API_URL="${EGREGORE_API_URL:-$(jq -r '.api_url // empty' "$CONFIG")}"
|
|
34
42
|
API_KEY="${EGREGORE_API_KEY:-}"
|
|
35
43
|
|
|
36
|
-
if [ -z "$API_URL" ]
|
|
37
|
-
# === OFFLINE MODE:
|
|
44
|
+
if [ -z "$API_URL" ]; then
|
|
45
|
+
# === OFFLINE MODE: no api_url configured (OSS/unconfigured) ===
|
|
38
46
|
echo '{"results":[]}'
|
|
39
47
|
exit 0
|
|
40
48
|
fi
|
|
41
49
|
|
|
50
|
+
if [ -z "$API_KEY" ]; then
|
|
51
|
+
# api_url is configured but no key was found — the local-mode gate exited
|
|
52
|
+
# above, so the org expects a live graph. Faking empty results here hides a
|
|
53
|
+
# missing .env (e.g. a worktree without its symlink) from every caller.
|
|
54
|
+
{
|
|
55
|
+
echo "Error: api_url is configured but EGREGORE_API_KEY is empty (looked in: ${_ENV_FILE:-$SCRIPT_DIR/.env})."
|
|
56
|
+
echo " If this is a worktree, its .env symlink may be missing. Run /env to configure."
|
|
57
|
+
} >&2
|
|
58
|
+
exit 1
|
|
59
|
+
fi
|
|
60
|
+
|
|
42
61
|
QUERIES_JSON="${1:?Usage: graph-batch.sh '<json array of queries>'}"
|
|
43
62
|
|
|
44
63
|
# Wrap the array into the batch request format
|
|
@@ -708,7 +708,8 @@ case "$OP" in
|
|
|
708
708
|
fi
|
|
709
709
|
bash "$GS" query "
|
|
710
710
|
MATCH (s:Session)-[:HANDED_TO]->(p:Person)
|
|
711
|
-
WHERE (
|
|
711
|
+
WHERE NOT coalesce(p.kind, '') IN ['identity_alias']
|
|
712
|
+
AND (
|
|
712
713
|
toLower(coalesce(p.name, '')) = toLower(\$user)
|
|
713
714
|
OR toLower(coalesce(p.github, '')) = toLower(\$user)
|
|
714
715
|
OR toLower(coalesce(p.githubUsername, '')) = toLower(\$user)
|
|
@@ -718,13 +719,13 @@ case "$OP" in
|
|
|
718
719
|
AND coalesce(s.handoffStatus, 'pending')
|
|
719
720
|
IN ['pending','unread','read','claimed']
|
|
720
721
|
WITH DISTINCT s
|
|
721
|
-
|
|
722
|
-
|
|
722
|
+
WITH s, head([(s)-[:BY]->(author:Person)
|
|
723
|
+
WHERE NOT coalesce(author.kind, '') IN ['identity_alias'] | author.name]) AS authorName,
|
|
723
724
|
CASE WHEN s.date IS NULL THEN null
|
|
724
725
|
ELSE duration.inDays(date(s.date), date()).days END AS ageDays
|
|
725
726
|
RETURN s.id AS id,
|
|
726
727
|
coalesce(s.topic, s.summary, s.branch) AS topic,
|
|
727
|
-
coalesce(
|
|
728
|
+
coalesce(authorName, s.author, 'unknown') AS author,
|
|
728
729
|
toString(s.date) AS date,
|
|
729
730
|
coalesce(s.handoffStatus, 'pending') AS status,
|
|
730
731
|
coalesce(s.handoffIntent, 'unclassified') AS intent,
|
package/runtime/pi/bin/graph.sh
CHANGED
|
@@ -21,10 +21,18 @@ if [ "$_MODE" = "local" ]; then
|
|
|
21
21
|
exit 0
|
|
22
22
|
fi
|
|
23
23
|
|
|
24
|
-
# Load specific variables from .env if it exists (safe extraction, no arbitrary code execution)
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
24
|
+
# Load specific variables from .env if it exists (safe extraction, no arbitrary code execution).
|
|
25
|
+
# A worktree missing its .env symlink resolves through worktree-links.sh, which
|
|
26
|
+
# self-heals the link and falls back to the main checkout's .env.
|
|
27
|
+
_ENV_FILE="$SCRIPT_DIR/.env"
|
|
28
|
+
if [ ! -f "$_ENV_FILE" ] && [ -f "$SCRIPT_DIR/bin/lib/worktree-links.sh" ]; then
|
|
29
|
+
# shellcheck source=bin/lib/worktree-links.sh
|
|
30
|
+
source "$SCRIPT_DIR/bin/lib/worktree-links.sh" 2>/dev/null || true
|
|
31
|
+
_ENV_FILE="$(egregore_env_file "$SCRIPT_DIR" 2>/dev/null || true)"
|
|
32
|
+
fi
|
|
33
|
+
if [ -n "$_ENV_FILE" ] && [ -f "$_ENV_FILE" ]; then
|
|
34
|
+
EGREGORE_API_URL="${EGREGORE_API_URL:-$(grep '^EGREGORE_API_URL=' "$_ENV_FILE" 2>/dev/null | cut -d'=' -f2- || true)}"
|
|
35
|
+
EGREGORE_API_KEY="${EGREGORE_API_KEY:-$(grep '^EGREGORE_API_KEY=' "$_ENV_FILE" 2>/dev/null | cut -d'=' -f2- || true)}"
|
|
28
36
|
fi
|
|
29
37
|
|
|
30
38
|
# api_url comes from egregore.json (committed, non-secret)
|
|
@@ -168,8 +176,26 @@ if [ -n "$API_URL" ] && [ -n "$API_KEY" ]; then
|
|
|
168
176
|
fi
|
|
169
177
|
}
|
|
170
178
|
|
|
179
|
+
elif [ -n "$API_URL" ]; then
|
|
180
|
+
# === CONNECTED CONFIG, MISSING KEY ===
|
|
181
|
+
# api_url is configured, so the org expects a live graph, but no API key was
|
|
182
|
+
# found. Faking '{"results":[]}' here made a missing credential (e.g. a
|
|
183
|
+
# worktree without its .env symlink) indistinguishable from an empty graph —
|
|
184
|
+
# fail loudly instead. `test` keeps its offline JSON contract: dashboards,
|
|
185
|
+
# render-card, and startup-check consume it.
|
|
186
|
+
_missing_credentials() {
|
|
187
|
+
{
|
|
188
|
+
echo "Error: api_url is configured but EGREGORE_API_KEY is empty (looked in: ${_ENV_FILE:-$SCRIPT_DIR/.env})."
|
|
189
|
+
echo " If this is a worktree, its .env symlink may be missing. Run /env to configure."
|
|
190
|
+
} >&2
|
|
191
|
+
exit 1
|
|
192
|
+
}
|
|
193
|
+
run_query() { _missing_credentials; }
|
|
194
|
+
get_schema() { _missing_credentials; }
|
|
195
|
+
test_connection() { echo '{"status":"offline","reason":"no_api_key"}'; }
|
|
196
|
+
|
|
171
197
|
else
|
|
172
|
-
# === OFFLINE MODE:
|
|
198
|
+
# === OFFLINE MODE: no api_url configured (OSS/unconfigured) ===
|
|
173
199
|
run_query() { echo '{"results":[]}'; }
|
|
174
200
|
get_schema() { echo '{}'; }
|
|
175
201
|
test_connection() { echo '{"status":"offline","reason":"no_api_key"}'; }
|
|
@@ -77,7 +77,7 @@ if [ -d "$MEMORY_DIR" ]; then
|
|
|
77
77
|
(
|
|
78
78
|
cd "$MEMORY_DIR" || exit 0
|
|
79
79
|
git add -A >/dev/null 2>&1
|
|
80
|
-
git commit -m "
|
|
80
|
+
git commit -m "chore(handoff): backfill PR numbers for $TOPIC" >/dev/null 2>&1 || exit 0
|
|
81
81
|
git pull --rebase origin main --quiet >/dev/null 2>&1
|
|
82
82
|
git push origin main --quiet >/dev/null 2>&1
|
|
83
83
|
) || true
|
|
@@ -36,6 +36,11 @@ set -euo pipefail
|
|
|
36
36
|
# 1 on unrecoverable failure (file write, memory push, bad args).
|
|
37
37
|
|
|
38
38
|
SCRIPT_DIR="$(cd "$(dirname "$0")/.." && pwd)"
|
|
39
|
+
# shellcheck source=bin/lib/git-message.sh
|
|
40
|
+
. "$SCRIPT_DIR/bin/lib/git-message.sh" 2>/dev/null || true
|
|
41
|
+
type egregore_commit >/dev/null 2>&1 || egregore_commit() {
|
|
42
|
+
local gd="$1" m="$3"; shift 3; git -C "$gd" commit -m "$m" "$@"
|
|
43
|
+
}
|
|
39
44
|
CONFIG="$SCRIPT_DIR/egregore.json"
|
|
40
45
|
|
|
41
46
|
if [[ "${1:-}" == "--help" || "${1:-}" == "-h" ]]; then
|
|
@@ -326,12 +331,12 @@ PID_ARTIFACTS=$!
|
|
|
326
331
|
git add "$REL_FILE" handoffs/index.md >/dev/null 2>&1
|
|
327
332
|
|
|
328
333
|
if [ -n "$RECIPIENT" ]; then
|
|
329
|
-
MSG_COMMIT="
|
|
334
|
+
MSG_COMMIT="chore(handoff): record ${TOPIC} (to ${RECIPIENT})"
|
|
330
335
|
else
|
|
331
|
-
MSG_COMMIT="
|
|
336
|
+
MSG_COMMIT="chore(handoff): record ${TOPIC}"
|
|
332
337
|
fi
|
|
333
338
|
|
|
334
|
-
|
|
339
|
+
egregore_commit . "$SCRIPT_DIR" "$MSG_COMMIT" >/dev/null 2>&1 || true
|
|
335
340
|
|
|
336
341
|
STASHED=0
|
|
337
342
|
if [ -n "$(git status --porcelain 2>/dev/null)" ]; then
|
|
@@ -47,19 +47,16 @@ done
|
|
|
47
47
|
|
|
48
48
|
case "$KIND" in
|
|
49
49
|
autosave)
|
|
50
|
-
MSG_PREFIX="
|
|
50
|
+
MSG_PREFIX="chore(autosave): save"
|
|
51
51
|
PR_WHAT="Save session content captured by the opted-in autosave workflow."
|
|
52
52
|
PR_WHY="This preserves unattended non-coding work without requiring an explicit /save."
|
|
53
53
|
;;
|
|
54
54
|
*)
|
|
55
|
-
MSG_PREFIX="
|
|
55
|
+
MSG_PREFIX="chore(handoff): record"
|
|
56
56
|
PR_WHAT="Save core-repository session work captured when the handoff was created."
|
|
57
57
|
PR_WHY="The handoff records shared context immediately; this companion PR keeps the originating checkout's work from remaining only local."
|
|
58
58
|
;;
|
|
59
59
|
esac
|
|
60
|
-
PR_BODY=$(printf '## What\n\n- %s\n\n## Why\n\n%s Topic: `%s`.\n\n## Verification\n\nNot verified — background %s save; review code or configuration changes before merging.\n\n🤖 Saved via `bin/handoff-save-egregore.sh`\n' \
|
|
61
|
-
"$PR_WHAT" "$PR_WHY" "$TOPIC" "$KIND")
|
|
62
|
-
|
|
63
60
|
[ -n "$AUTHOR" ] || { echo "handoff-save-egregore: missing author" >&2; exit 1; }
|
|
64
61
|
|
|
65
62
|
SCRIPT_DIR="$(cd "$(dirname "$0")/.." && pwd)"
|
|
@@ -88,6 +85,21 @@ BASE_REF="origin/$BASE_BRANCH"
|
|
|
88
85
|
. "$SCRIPT_DIR/bin/lib/git-safe.sh" 2>/dev/null || true
|
|
89
86
|
type git_add_guarded >/dev/null 2>&1 || git_add_guarded() { git add -A 2>/dev/null || true; }
|
|
90
87
|
|
|
88
|
+
# Shared commit/PR message mechanics (trailers + skeleton body shape).
|
|
89
|
+
# shellcheck source=bin/lib/git-message.sh
|
|
90
|
+
. "$SCRIPT_DIR/bin/lib/git-message.sh" 2>/dev/null || true
|
|
91
|
+
type egregore_commit >/dev/null 2>&1 || egregore_commit() {
|
|
92
|
+
local gd="$1" m="$3"; shift 3; git -C "$gd" commit -m "$m" "$@"
|
|
93
|
+
}
|
|
94
|
+
type egregore_pr_skeleton >/dev/null 2>&1 || egregore_pr_skeleton() {
|
|
95
|
+
printf '## What\n%s\n\n## Why\n%s\n\n## Verification\n%s\n\n%s\n' "$1" "$2" "$3" "$4"
|
|
96
|
+
}
|
|
97
|
+
PR_BODY=$(egregore_pr_skeleton \
|
|
98
|
+
"- $PR_WHAT" \
|
|
99
|
+
"$PR_WHY Topic: \`$TOPIC\`." \
|
|
100
|
+
"Not verified — background $KIND save; review code or configuration changes before merging." \
|
|
101
|
+
"🤖 Saved via \`bin/handoff-save-egregore.sh\`")
|
|
102
|
+
|
|
91
103
|
# Shared non-coding classifier (auto-merge policy lives in one place).
|
|
92
104
|
# shellcheck source=bin/lib/noncode.sh
|
|
93
105
|
. "$SCRIPT_DIR/bin/lib/noncode.sh" 2>/dev/null || true
|
|
@@ -131,7 +143,7 @@ fi
|
|
|
131
143
|
# --- Commit whatever is uncommitted --------------------------------------
|
|
132
144
|
if [ -n "$(git status --porcelain 2>/dev/null)" ]; then
|
|
133
145
|
git_add_guarded
|
|
134
|
-
|
|
146
|
+
egregore_commit . "$REPO_DIR" "${MSG_PREFIX} ${TOPIC}" --quiet 2>/dev/null || true
|
|
135
147
|
fi
|
|
136
148
|
|
|
137
149
|
# --- Rebase onto the configured base, fall back to merge on conflicts ----
|
|
@@ -182,7 +194,7 @@ else
|
|
|
182
194
|
PR_URL=$(gh pr create \
|
|
183
195
|
--base "$BASE_BRANCH" \
|
|
184
196
|
--head "$CURRENT_BRANCH" \
|
|
185
|
-
--title "${MSG_PREFIX}
|
|
197
|
+
--title "${MSG_PREFIX} ${TOPIC}" \
|
|
186
198
|
--body "$PR_BODY" \
|
|
187
199
|
2>/dev/null || echo "")
|
|
188
200
|
PR_NUMBER=$(echo "$PR_URL" | grep -oE '[0-9]+$' || echo "")
|