create-egregore 0.19.20 → 0.19.22

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.
Files changed (226) hide show
  1. package/assets/egregore-launcher.js +124 -12
  2. package/bin/cli.js +3 -4
  3. package/lib/auth.js +3 -4
  4. package/lib/path-lookup.js +59 -0
  5. package/lib/setup.js +52 -6
  6. package/package.json +2 -2
  7. package/runtime/codex/.claude/context/notification-consent.md +66 -0
  8. package/runtime/codex/.codex/hooks/branch-guard.js +14 -3
  9. package/runtime/codex/.codex/skills/add/SKILL.md +8 -4
  10. package/runtime/codex/.codex/skills/announce/SKILL.md +21 -8
  11. package/runtime/codex/.codex/skills/answer/SKILL.md +8 -4
  12. package/runtime/codex/.codex/skills/archive/SKILL.md +8 -4
  13. package/runtime/codex/.codex/skills/ask/SKILL.md +14 -6
  14. package/runtime/codex/.codex/skills/audit/SKILL.md +29 -0
  15. package/runtime/codex/.codex/skills/autosave/SKILL.md +29 -0
  16. package/runtime/codex/.codex/skills/branch/SKILL.md +8 -4
  17. package/runtime/codex/.codex/skills/checkup/SKILL.md +8 -4
  18. package/runtime/codex/.codex/skills/commit/SKILL.md +8 -4
  19. package/runtime/codex/.codex/skills/contribute/SKILL.md +8 -4
  20. package/runtime/codex/.codex/skills/dark-mode/SKILL.md +8 -4
  21. package/runtime/codex/.codex/skills/delete-user/SKILL.md +8 -4
  22. package/runtime/codex/.codex/skills/demo-mode/SKILL.md +29 -0
  23. package/runtime/codex/.codex/skills/deploy-bridge/SKILL.md +8 -4
  24. package/runtime/codex/.codex/skills/design/SKILL.md +29 -0
  25. package/runtime/codex/.codex/skills/egregore-voice/SKILL.md +8 -4
  26. package/runtime/codex/.codex/skills/emissary/SKILL.md +8 -4
  27. package/runtime/codex/.codex/skills/env/SKILL.md +8 -4
  28. package/runtime/codex/.codex/skills/handoff/SKILL.md +15 -6
  29. package/runtime/codex/.codex/skills/harvest/QUESTION_PALETTE.md +76 -0
  30. package/runtime/codex/.codex/skills/harvest/SKILL.md +30 -6
  31. package/runtime/codex/.codex/skills/ingest/SKILL.md +8 -4
  32. package/runtime/codex/.codex/skills/ingest-google/SKILL.md +8 -4
  33. package/runtime/codex/.codex/skills/ingest-user-interview/SKILL.md +8 -4
  34. package/runtime/codex/.codex/skills/invite/SKILL.md +6 -2
  35. package/runtime/codex/.codex/skills/issue/SKILL.md +8 -4
  36. package/runtime/codex/.codex/skills/me/SKILL.md +8 -4
  37. package/runtime/codex/.codex/skills/meeting/SKILL.md +8 -4
  38. package/runtime/codex/.codex/skills/minion/SKILL.md +8 -4
  39. package/runtime/codex/.codex/skills/mock/SKILL.md +29 -0
  40. package/runtime/codex/.codex/skills/note/SKILL.md +8 -4
  41. package/runtime/codex/.codex/skills/onboarding/SKILL.md +8 -4
  42. package/runtime/codex/.codex/skills/pr/SKILL.md +8 -4
  43. package/runtime/codex/.codex/skills/product-voice/SKILL.md +29 -0
  44. package/runtime/codex/.codex/skills/project/SKILL.md +8 -4
  45. package/runtime/codex/.codex/skills/pull/SKILL.md +8 -4
  46. package/runtime/codex/.codex/skills/push/SKILL.md +8 -4
  47. package/runtime/codex/.codex/skills/quest/SKILL.md +6 -3
  48. package/runtime/codex/.codex/skills/quest-suggest/SKILL.md +8 -4
  49. package/runtime/codex/.codex/skills/reflect/SKILL.md +8 -4
  50. package/runtime/codex/.codex/skills/review-pr/SKILL.md +8 -4
  51. package/runtime/codex/.codex/skills/save/SKILL.md +6 -4
  52. package/runtime/codex/.codex/skills/scroll/SKILL.md +92 -23
  53. package/runtime/codex/.codex/skills/scroll/assets/shell.html +381 -52
  54. package/runtime/codex/.codex/skills/session-view/SKILL.md +8 -4
  55. package/runtime/codex/.codex/skills/setup/SKILL.md +8 -4
  56. package/runtime/codex/.codex/skills/summon/SKILL.md +8 -4
  57. package/runtime/codex/.codex/skills/sync-repos/SKILL.md +8 -4
  58. package/runtime/codex/.codex/skills/task/SKILL.md +9 -5
  59. package/runtime/codex/.codex/skills/teams-connect/SKILL.md +29 -0
  60. package/runtime/codex/.codex/skills/telegram-connect/SKILL.md +8 -4
  61. package/runtime/codex/.codex/skills/telemetry/SKILL.md +8 -4
  62. package/runtime/codex/.codex/skills/test/SKILL.md +8 -4
  63. package/runtime/codex/.codex/skills/thread/SKILL.md +8 -4
  64. package/runtime/codex/.codex/skills/todo/SKILL.md +8 -4
  65. package/runtime/codex/.codex/skills/tui-design/SKILL.md +8 -4
  66. package/runtime/codex/.codex/skills/tutorial/SKILL.md +8 -4
  67. package/runtime/codex/.codex/skills/update/SKILL.md +8 -4
  68. package/runtime/codex/.codex/skills/visual-explain/SKILL.md +8 -4
  69. package/runtime/codex/.codex/spec-manifest.json +4 -4
  70. package/runtime/codex/AGENTS.md +36 -14
  71. package/runtime/codex/bin/activity-data.sh +1 -1
  72. package/runtime/codex/bin/agent.sh +38 -19
  73. package/runtime/codex/bin/attendant.sh +8 -2
  74. package/runtime/codex/bin/autosave.sh +1 -1
  75. package/runtime/codex/bin/capture-reconcile.sh +8 -6
  76. package/runtime/codex/bin/capture-run.sh +1 -1
  77. package/runtime/codex/bin/codex-install-skills.sh +1 -1
  78. package/runtime/codex/bin/codex-render-spec.mjs +12 -5
  79. package/runtime/codex/bin/codex-session-start.sh +1 -1
  80. package/runtime/codex/bin/codex-sync-skills.sh +9 -5
  81. package/runtime/codex/bin/dashboard-data.sh +1 -1
  82. package/runtime/codex/bin/graph-batch.sh +1 -1
  83. package/runtime/codex/bin/graph-op.sh +1 -1
  84. package/runtime/codex/bin/graph-wal.sh +1 -1
  85. package/runtime/codex/bin/graph.sh +1 -1
  86. package/runtime/codex/bin/handoff-pr-backfill.sh +1 -1
  87. package/runtime/codex/bin/handoff-run.sh +53 -39
  88. package/runtime/codex/bin/handoff-save-egregore.sh +62 -32
  89. package/runtime/codex/bin/index-handoff.sh +1 -1
  90. package/runtime/codex/bin/ingest-graph.sh +1 -1
  91. package/runtime/codex/bin/ingest.sh +1 -1
  92. package/runtime/codex/bin/lib/artifact-id.sh +1 -1
  93. package/runtime/codex/bin/lib/config.sh +56 -20
  94. package/runtime/codex/bin/lib/context.sh +7 -1
  95. package/runtime/codex/bin/lib/ensure-develop.sh +1 -1
  96. package/runtime/codex/bin/lib/git-sync.sh +145 -59
  97. package/runtime/codex/bin/lib/greeting.sh +14 -0
  98. package/runtime/codex/bin/lib/hash.sh +1 -1
  99. package/runtime/codex/bin/lib/noncode.sh +1 -1
  100. package/runtime/codex/bin/lib/time.sh +1 -1
  101. package/runtime/codex/bin/notify.sh +492 -153
  102. package/runtime/codex/bin/person.sh +1 -1
  103. package/runtime/codex/bin/publish-artifact.sh +39 -4
  104. package/runtime/codex/bin/publish-references.sh +1 -1
  105. package/runtime/codex/bin/repo-state.sh +7 -10
  106. package/runtime/codex/bin/search.sh +1 -1
  107. package/runtime/codex/bin/session-autosave.sh +1 -1
  108. package/runtime/codex/bin/session-log.sh +1 -1
  109. package/runtime/codex/bin/settings.sh +32 -2
  110. package/runtime/codex/bin/telemetry.sh +1 -1
  111. package/runtime/codex/bin/worktree-create.sh +14 -4
  112. package/runtime/codex/bin/worktree-remove.sh +1 -1
  113. package/runtime/codex/bin/worktree.sh +1 -1
  114. package/runtime/codex/manifest.json +18 -1
  115. package/runtime/pi/.claude/context/notification-consent.md +66 -0
  116. package/runtime/pi/.codex/hooks/branch-guard.js +14 -3
  117. package/runtime/pi/.codex/skills/add/SKILL.md +8 -4
  118. package/runtime/pi/.codex/skills/announce/SKILL.md +21 -8
  119. package/runtime/pi/.codex/skills/answer/SKILL.md +8 -4
  120. package/runtime/pi/.codex/skills/archive/SKILL.md +8 -4
  121. package/runtime/pi/.codex/skills/ask/SKILL.md +14 -6
  122. package/runtime/pi/.codex/skills/audit/SKILL.md +29 -0
  123. package/runtime/pi/.codex/skills/autosave/SKILL.md +29 -0
  124. package/runtime/pi/.codex/skills/branch/SKILL.md +8 -4
  125. package/runtime/pi/.codex/skills/checkup/SKILL.md +8 -4
  126. package/runtime/pi/.codex/skills/commit/SKILL.md +8 -4
  127. package/runtime/pi/.codex/skills/contribute/SKILL.md +8 -4
  128. package/runtime/pi/.codex/skills/dark-mode/SKILL.md +8 -4
  129. package/runtime/pi/.codex/skills/delete-user/SKILL.md +8 -4
  130. package/runtime/pi/.codex/skills/demo-mode/SKILL.md +29 -0
  131. package/runtime/pi/.codex/skills/deploy-bridge/SKILL.md +8 -4
  132. package/runtime/pi/.codex/skills/design/SKILL.md +29 -0
  133. package/runtime/pi/.codex/skills/egregore-voice/SKILL.md +8 -4
  134. package/runtime/pi/.codex/skills/emissary/SKILL.md +8 -4
  135. package/runtime/pi/.codex/skills/env/SKILL.md +8 -4
  136. package/runtime/pi/.codex/skills/handoff/SKILL.md +15 -6
  137. package/runtime/pi/.codex/skills/harvest/QUESTION_PALETTE.md +76 -0
  138. package/runtime/pi/.codex/skills/harvest/SKILL.md +30 -6
  139. package/runtime/pi/.codex/skills/ingest/SKILL.md +8 -4
  140. package/runtime/pi/.codex/skills/ingest-google/SKILL.md +8 -4
  141. package/runtime/pi/.codex/skills/ingest-user-interview/SKILL.md +8 -4
  142. package/runtime/pi/.codex/skills/invite/SKILL.md +6 -2
  143. package/runtime/pi/.codex/skills/issue/SKILL.md +8 -4
  144. package/runtime/pi/.codex/skills/me/SKILL.md +8 -4
  145. package/runtime/pi/.codex/skills/meeting/SKILL.md +8 -4
  146. package/runtime/pi/.codex/skills/minion/SKILL.md +8 -4
  147. package/runtime/pi/.codex/skills/mock/SKILL.md +29 -0
  148. package/runtime/pi/.codex/skills/note/SKILL.md +8 -4
  149. package/runtime/pi/.codex/skills/onboarding/SKILL.md +8 -4
  150. package/runtime/pi/.codex/skills/pr/SKILL.md +8 -4
  151. package/runtime/pi/.codex/skills/product-voice/SKILL.md +29 -0
  152. package/runtime/pi/.codex/skills/project/SKILL.md +8 -4
  153. package/runtime/pi/.codex/skills/pull/SKILL.md +8 -4
  154. package/runtime/pi/.codex/skills/push/SKILL.md +8 -4
  155. package/runtime/pi/.codex/skills/quest/SKILL.md +6 -3
  156. package/runtime/pi/.codex/skills/quest-suggest/SKILL.md +8 -4
  157. package/runtime/pi/.codex/skills/reflect/SKILL.md +8 -4
  158. package/runtime/pi/.codex/skills/review-pr/SKILL.md +8 -4
  159. package/runtime/pi/.codex/skills/save/SKILL.md +6 -4
  160. package/runtime/pi/.codex/skills/scroll/SKILL.md +92 -23
  161. package/runtime/pi/.codex/skills/scroll/assets/shell.html +381 -52
  162. package/runtime/pi/.codex/skills/session-view/SKILL.md +8 -4
  163. package/runtime/pi/.codex/skills/setup/SKILL.md +8 -4
  164. package/runtime/pi/.codex/skills/summon/SKILL.md +8 -4
  165. package/runtime/pi/.codex/skills/sync-repos/SKILL.md +8 -4
  166. package/runtime/pi/.codex/skills/task/SKILL.md +9 -5
  167. package/runtime/pi/.codex/skills/teams-connect/SKILL.md +29 -0
  168. package/runtime/pi/.codex/skills/telegram-connect/SKILL.md +8 -4
  169. package/runtime/pi/.codex/skills/telemetry/SKILL.md +8 -4
  170. package/runtime/pi/.codex/skills/test/SKILL.md +8 -4
  171. package/runtime/pi/.codex/skills/thread/SKILL.md +8 -4
  172. package/runtime/pi/.codex/skills/todo/SKILL.md +8 -4
  173. package/runtime/pi/.codex/skills/tui-design/SKILL.md +8 -4
  174. package/runtime/pi/.codex/skills/tutorial/SKILL.md +8 -4
  175. package/runtime/pi/.codex/skills/update/SKILL.md +8 -4
  176. package/runtime/pi/.codex/skills/visual-explain/SKILL.md +8 -4
  177. package/runtime/pi/.codex/spec-manifest.json +4 -4
  178. package/runtime/pi/.pi/APPEND_SYSTEM.md +34 -12
  179. package/runtime/pi/.pi/extensions/egregore.ts +8 -1
  180. package/runtime/pi/.pi/spec-manifest.json +2 -2
  181. package/runtime/pi/AGENTS.md +36 -14
  182. package/runtime/pi/bin/activity-data.sh +1 -1
  183. package/runtime/pi/bin/agent.sh +38 -19
  184. package/runtime/pi/bin/attendant.sh +8 -2
  185. package/runtime/pi/bin/autosave.sh +1 -1
  186. package/runtime/pi/bin/capture-reconcile.sh +8 -6
  187. package/runtime/pi/bin/capture-run.sh +1 -1
  188. package/runtime/pi/bin/codex-install-skills.sh +1 -1
  189. package/runtime/pi/bin/codex-render-spec.mjs +12 -5
  190. package/runtime/pi/bin/codex-session-start.sh +1 -1
  191. package/runtime/pi/bin/codex-sync-skills.sh +9 -5
  192. package/runtime/pi/bin/dashboard-data.sh +1 -1
  193. package/runtime/pi/bin/graph-batch.sh +1 -1
  194. package/runtime/pi/bin/graph-op.sh +1 -1
  195. package/runtime/pi/bin/graph-wal.sh +1 -1
  196. package/runtime/pi/bin/graph.sh +1 -1
  197. package/runtime/pi/bin/handoff-pr-backfill.sh +1 -1
  198. package/runtime/pi/bin/handoff-run.sh +53 -39
  199. package/runtime/pi/bin/handoff-save-egregore.sh +62 -32
  200. package/runtime/pi/bin/index-handoff.sh +1 -1
  201. package/runtime/pi/bin/ingest-graph.sh +1 -1
  202. package/runtime/pi/bin/ingest.sh +1 -1
  203. package/runtime/pi/bin/lib/artifact-id.sh +1 -1
  204. package/runtime/pi/bin/lib/config.sh +56 -20
  205. package/runtime/pi/bin/lib/context.sh +7 -1
  206. package/runtime/pi/bin/lib/ensure-develop.sh +1 -1
  207. package/runtime/pi/bin/lib/git-sync.sh +145 -59
  208. package/runtime/pi/bin/lib/greeting.sh +14 -0
  209. package/runtime/pi/bin/lib/hash.sh +1 -1
  210. package/runtime/pi/bin/lib/noncode.sh +1 -1
  211. package/runtime/pi/bin/lib/time.sh +1 -1
  212. package/runtime/pi/bin/notify.sh +492 -153
  213. package/runtime/pi/bin/person.sh +1 -1
  214. package/runtime/pi/bin/pi-session-start.sh +1 -1
  215. package/runtime/pi/bin/publish-artifact.sh +39 -4
  216. package/runtime/pi/bin/publish-references.sh +1 -1
  217. package/runtime/pi/bin/repo-state.sh +7 -10
  218. package/runtime/pi/bin/search.sh +1 -1
  219. package/runtime/pi/bin/session-autosave.sh +1 -1
  220. package/runtime/pi/bin/session-log.sh +1 -1
  221. package/runtime/pi/bin/settings.sh +32 -2
  222. package/runtime/pi/bin/telemetry.sh +1 -1
  223. package/runtime/pi/bin/worktree-create.sh +14 -4
  224. package/runtime/pi/bin/worktree-remove.sh +1 -1
  225. package/runtime/pi/bin/worktree.sh +1 -1
  226. package/runtime/pi/manifest.json +18 -1
@@ -449,10 +449,16 @@ fi
449
449
  ) > "$CTX_DIR/graph_health" 2>/dev/null &
450
450
 
451
451
  # 8. Telegram health (background)
452
+ # notify.sh test emits JSON, not prose: {"status":"ok"} connected,
453
+ # {"status":"configured"} local, {"status":"offline"} otherwise. Match the
454
+ # status field — an earlier grep for the word "connected" read a human sentence
455
+ # that the consent rewrite removed, so the footer showed telegram ✗ while the
456
+ # bot was answering.
452
457
  (
453
458
  if [ "$LOCAL_MODE" = "true" ]; then
454
459
  echo "skip"
455
- elif bash "$SCRIPT_DIR/bin/notify.sh" test 2>/dev/null | grep -q "connected"; then
460
+ elif bash "$SCRIPT_DIR/bin/notify.sh" test 2>/dev/null \
461
+ | jq -e '.status == "ok" or .status == "configured"' >/dev/null 2>&1; then
456
462
  echo "ok"
457
463
  else
458
464
  echo "fail"
@@ -1,4 +1,4 @@
1
- #!/bin/bash
1
+ #!/usr/bin/env bash
2
2
  # ensure-develop.sh — Ensure a repository has a develop branch.
3
3
  #
4
4
  # Usage:
@@ -11,12 +11,26 @@
11
11
  # - Managed repos sync
12
12
  #
13
13
  # Inputs: SCRIPT_DIR, IS_WORKTREE, MAIN_PROJECT_DIR, STATE_FILE, ENV_FILE,
14
- # HEALTH_GIT, MANAGED_REPOS (not yet set — read from config here)
14
+ # HEALTH_GIT, BASE_BRANCH (optional — resolved here if unset),
15
+ # MANAGED_REPOS (not yet set — read from config here)
15
16
  # Outputs: HEALTH_GIT, DEVELOP_SYNCED, COMMITS_AHEAD, ACTION, SAVED_BRANCH,
16
17
  # BRANCH, MEMORY_SYNCED, REPOS_STATUS, MANAGED_REPOS, CURRENT_BRANCH,
17
- # FRAMEWORK_UPDATED
18
+ # FRAMEWORK_UPDATED, FRAMEWORK_UPDATED_COUNT, FRAMEWORK_UPDATED_FILES,
19
+ # BASE_BRANCH, BASE_BRANCH_READY
18
20
 
19
21
  FRAMEWORK_UPDATED="false"
22
+ FRAMEWORK_UPDATED_COUNT=0
23
+ FRAMEWORK_UPDATED_FILES=""
24
+
25
+ # The core repo's integration branch: "develop" unless egregore.json sets
26
+ # base_branch. session-start.sh resolves this before sourcing; resolve it here
27
+ # too so the lib stands alone for other callers.
28
+ if [ -z "${BASE_BRANCH:-}" ]; then
29
+ if ! BASE_BRANCH=$(_get_base_branch); then
30
+ HEALTH_GIT="fail"
31
+ return 1 2>/dev/null || exit 1
32
+ fi
33
+ fi
20
34
 
21
35
  # --- Ensure pull.rebase is set (prevents "divergent branches" errors) ---
22
36
  git config pull.rebase true 2>/dev/null || true
@@ -73,13 +87,59 @@ wait 2>/dev/null || true
73
87
  # --- Auto-update framework from upstream (deferred) ---
74
88
  # Moved AFTER setup_develop() so framework commits land on develop, not on
75
89
  # working branches. See _apply_framework_update() below.
76
- _AUTO_UPDATE=$(jq -r '.auto_update // true' "$SCRIPT_DIR/egregore.json" 2>/dev/null)
90
+
91
+ # _read_auto_update — resolve the auto_update flag. Correct, and FAIL CLOSED.
92
+ #
93
+ # This flag is the only thing standing between a user's checkout and a blind
94
+ # `git checkout upstream/main --` over every framework path, so it has to be
95
+ # read exactly right. It was not.
96
+ #
97
+ # The bug: `jq -r '.auto_update // true'`. jq's `//` returns its right-hand
98
+ # side when the left is null *or false* — so a config saying
99
+ # {"auto_update": false} evaluated to the string "true", and the guard
100
+ # `[ "$_AUTO_UPDATE" = "false" ]` could never fire. The documented opt-out
101
+ # has never disabled anything for anyone. Do not reintroduce `// <bool>` for
102
+ # a flag whose `false` is meaningful; read the raw value and map it.
103
+ #
104
+ # Second failure: jq prints nothing and exits non-zero on a missing or
105
+ # malformed egregore.json, and an empty string is not "false" either — so an
106
+ # unreadable config also read as consent. Absent key means "on" (the intended
107
+ # default); everything else that is not a parsed `true` means "leave the
108
+ # user's files alone".
109
+ _read_auto_update() {
110
+ local _config="$SCRIPT_DIR/egregore.json"
111
+ local _val
112
+ [ -f "$_config" ] || { echo "false"; return; }
113
+ # `| tojson`, not a bare `-r` read: under -r a *string* "true" renders as bare
114
+ # true, indistinguishable from boolean true, so {"auto_update": "true"} would
115
+ # re-authorize the overwrite — a fail-open hole in the middle of a fail-closed
116
+ # resolver. tojson keeps the quotes, so the true arm matches only an absent key
117
+ # or a real boolean.
118
+ _val=$(jq -r '.auto_update | tojson' "$_config" 2>/dev/null) || { echo "false"; return; }
119
+ case "$_val" in
120
+ null|true) echo "true" ;; # key absent, or explicitly enabled
121
+ *) echo "false" ;; # false, "false", "true", garbage, or unparseable
122
+ esac
123
+ }
77
124
 
78
125
  _apply_framework_update() {
79
- # Applies framework paths from upstream to the CURRENT branch (must be develop).
126
+ # Applies framework paths from upstream to the CURRENT branch, which must be
127
+ # the configured base branch.
80
128
  # Disable with "auto_update": false in egregore.json.
81
129
  # Dev repos (upstream_url: "none") skip this entirely.
82
- if [ "$_UPSTREAM_URL" = "none" ] || [ "$_AUTO_UPDATE" = "false" ]; then
130
+ #
131
+ # The flag is read HERE, not at source time: callers reach this function
132
+ # after setup_develop() has switched branches, and egregore.json may differ
133
+ # between the branch the session opened on and the configured base. Reading
134
+ # late means the config that is actually checked out is the config that
135
+ # decides.
136
+ local _update_branch
137
+ _update_branch=$(git branch --show-current 2>/dev/null) || return 1
138
+ if [ "$_update_branch" != "$BASE_BRANCH" ]; then
139
+ return 1
140
+ fi
141
+ _AUTO_UPDATE=$(_read_auto_update)
142
+ if [ "$_UPSTREAM_URL" = "none" ] || [ "$_AUTO_UPDATE" != "true" ]; then
83
143
  return 0
84
144
  fi
85
145
  if ! git show-ref --verify --quiet refs/remotes/upstream/main 2>/dev/null; then
@@ -90,8 +150,14 @@ _apply_framework_update() {
90
150
  for _p in bin/ .claude/commands/ .claude/skills/ .claude/hooks/ .claude/context/ .claude/agents/ loom/ CLAUDE.md skills/; do
91
151
  git checkout upstream/main -- "$_p" 2>/dev/null || true
92
152
  done
93
- # Only commit if there are actual changes
94
- if [ -n "$(git status --porcelain bin/ .claude/ loom/ CLAUDE.md skills/ 2>/dev/null | head -1)" ]; then
153
+ # Only commit if there are actual changes. Record WHAT changed before
154
+ # committing — an overwrite of local edits is the one outcome the user has
155
+ # to be able to see afterwards, and the commit is the only other record.
156
+ local _changed
157
+ _changed=$(git status --porcelain bin/ .claude/ loom/ CLAUDE.md skills/ 2>/dev/null)
158
+ if [ -n "$_changed" ]; then
159
+ FRAMEWORK_UPDATED_COUNT=$(printf '%s\n' "$_changed" | grep -c . || echo 0)
160
+ FRAMEWORK_UPDATED_FILES=$(printf '%s\n' "$_changed" | awk '{print $NF}' | head -3 | tr '\n' ' ')
95
161
  git add bin/ .claude/ loom/ CLAUDE.md skills/ 2>/dev/null
96
162
  EGREGORE_FRAMEWORK_UPDATE=1 git commit -m "Auto-update Egregore framework" --quiet 2>/dev/null || true
97
163
  FRAMEWORK_UPDATED="true"
@@ -102,7 +168,7 @@ _apply_framework_update() {
102
168
  git worktree prune 2>/dev/null || true
103
169
 
104
170
  # --- Git health check ---
105
- if git show-ref --verify --quiet refs/remotes/origin/develop 2>/dev/null; then
171
+ if git show-ref --verify --quiet "refs/remotes/origin/$BASE_BRANCH" 2>/dev/null; then
106
172
  HEALTH_GIT="ok"
107
173
  else
108
174
  HEALTH_GIT="fail"
@@ -118,54 +184,56 @@ if ! type git_add_guarded >/dev/null 2>&1; then
118
184
  git_add_guarded() { git add -A 2>/dev/null || true; }
119
185
  fi
120
186
 
121
- # --- Setup develop (wrapped — failures set HEALTH_GIT but don't crash) ---
187
+ # --- Setup base branch (wrapped — failures set HEALTH_GIT but don't crash) ---
188
+ # Named setup_develop for continuity; it operates on $BASE_BRANCH, which is
189
+ # "develop" by default and whatever egregore.json's base_branch says otherwise.
122
190
  setup_develop() {
123
- # Ensure develop branch exists locally
124
- if ! git show-ref --verify --quiet refs/heads/develop 2>/dev/null; then
125
- if git show-ref --verify --quiet refs/remotes/origin/develop 2>/dev/null; then
126
- git checkout -b develop origin/develop --quiet 2>/dev/null
191
+ # Ensure the base branch exists locally
192
+ if ! git show-ref --verify --quiet "refs/heads/$BASE_BRANCH" 2>/dev/null; then
193
+ if git show-ref --verify --quiet "refs/remotes/origin/$BASE_BRANCH" 2>/dev/null; then
194
+ git checkout -b "$BASE_BRANCH" "origin/$BASE_BRANCH" --quiet 2>/dev/null || return 1
127
195
  else
128
- # No develop on remote either — create from main
129
- git checkout -b develop --quiet 2>/dev/null
130
- git push -u origin develop --quiet 2>/dev/null
196
+ # Not on the remote either — create it and publish it
197
+ git checkout -b "$BASE_BRANCH" --quiet 2>/dev/null || return 1
198
+ git push -u origin "$BASE_BRANCH" --quiet 2>/dev/null || return 1
131
199
  fi
132
200
  fi
133
201
 
134
- # Sync develop (without checkout — safe for concurrent sessions)
135
- CURRENT_BRANCH=$(git branch --show-current)
202
+ # Sync the base branch (without checkout — safe for concurrent sessions)
203
+ CURRENT_BRANCH=$(git branch --show-current 2>/dev/null) || return 1
136
204
 
137
- # Update local develop ref from remote without switching branches
205
+ # Update the local ref from remote without switching branches
138
206
  # Use fetch + force-update to handle divergence (e.g., from auto-update commits)
139
- git fetch origin develop --quiet 2>/dev/null || true
140
- if [[ "$CURRENT_BRANCH" != "develop" ]]; then
207
+ git fetch origin "$BASE_BRANCH" --quiet 2>/dev/null || true
208
+ if [[ "$CURRENT_BRANCH" != "$BASE_BRANCH" ]]; then
141
209
  # Safe to force-update when not checked out
142
- git branch -f develop origin/develop 2>/dev/null || true
210
+ git branch -f "$BASE_BRANCH" "origin/$BASE_BRANCH" 2>/dev/null || true
143
211
  else
144
- # On develop — try ff merge, fall back to reset only if no unpushed work
145
- git merge --ff-only origin/develop --quiet 2>/dev/null || {
146
- # Only reset if there are no unpushed commits on develop
147
- LOCAL_AHEAD=$(git rev-list origin/develop..develop --count 2>/dev/null || echo "0")
148
- if [ "$LOCAL_AHEAD" = "0" ]; then
149
- git reset --hard origin/develop --quiet 2>/dev/null || true
212
+ # On the base branch — try ff merge, fall back to reset only if no unpushed work
213
+ git merge --ff-only "origin/$BASE_BRANCH" --quiet 2>/dev/null || {
214
+ # Only reset if there are no unpushed commits and no dirty tracked work.
215
+ # A reset here runs before autosave and must never discard local changes.
216
+ LOCAL_AHEAD=$(git rev-list "origin/$BASE_BRANCH..$BASE_BRANCH" --count 2>/dev/null || echo "0")
217
+ if [ "$LOCAL_AHEAD" = "0" ] && [ -z "$(git status --porcelain 2>/dev/null)" ]; then
218
+ git reset --hard "origin/$BASE_BRANCH" --quiet 2>/dev/null || true
150
219
  fi
151
220
  }
152
221
  fi
153
- DEVELOP_SYNCED="true"
154
-
155
- # Count commits on develop ahead of main
222
+ # Count commits on the base branch ahead of main. Meaningless in
223
+ # single-branch mode, where the base branch IS main.
156
224
  COMMITS_AHEAD=0
157
- if git show-ref --verify --quiet refs/remotes/origin/main 2>/dev/null; then
158
- COMMITS_AHEAD=$(git rev-list origin/main..develop --count 2>/dev/null || echo "0")
225
+ if [ "$BASE_BRANCH" != "main" ] && git show-ref --verify --quiet refs/remotes/origin/main 2>/dev/null; then
226
+ COMMITS_AHEAD=$(git rev-list "origin/main..$BASE_BRANCH" --count 2>/dev/null || echo "0")
159
227
  fi
160
228
 
161
- # Always start from develop
162
- # Every session begins on develop. Claude creates a fresh topic branch
229
+ # Always start from the base branch
230
+ # Every session begins there. Claude creates a fresh topic branch
163
231
  # (dev/{author}/{topic-slug}) when the user says what they're working on.
164
232
  # If we're on a working branch with uncommitted work, save it first.
165
233
  ACTION="ready"
166
234
  SAVED_BRANCH=""
167
235
 
168
- if [[ "$CURRENT_BRANCH" != "develop" ]]; then
236
+ if [[ "$CURRENT_BRANCH" != "$BASE_BRANCH" ]]; then
169
237
  # Check for uncommitted work (staged + unstaged + untracked in tracked dirs)
170
238
  if [ -n "$(git status --porcelain 2>/dev/null | head -1)" ]; then
171
239
  # Save uncommitted work so nothing is lost (guarded: never auto-commit
@@ -184,14 +252,26 @@ setup_develop() {
184
252
  fi
185
253
  fi
186
254
 
187
- # Switch to develop (already updated by fetch origin develop:develop above)
188
- git checkout develop --quiet 2>/dev/null || true
255
+ # Switch to the base branch (already updated by the fetch above)
256
+ if ! git checkout "$BASE_BRANCH" --quiet 2>/dev/null; then
257
+ BRANCH=$(git branch --show-current 2>/dev/null || echo "?")
258
+ return 1
259
+ fi
189
260
  else
190
- # Already on develop — fetch couldn't update it (checked-out branch), so pull
191
- git merge --ff-only origin/develop --quiet 2>/dev/null || true
261
+ # Already on it — fetch couldn't update a checked-out branch, so pull
262
+ git merge --ff-only "origin/$BASE_BRANCH" --quiet 2>/dev/null || true
192
263
  fi
193
264
 
194
- BRANCH="develop"
265
+ # Never report the intended branch as the actual branch. A checkout can fail
266
+ # when the base is held by another worktree or the index blocks the switch.
267
+ # setup_develop must fail in that case so callers cannot apply framework files
268
+ # to the user's working branch.
269
+ BRANCH=$(git branch --show-current 2>/dev/null || echo "?")
270
+ if [ "$BRANCH" != "$BASE_BRANCH" ]; then
271
+ return 1
272
+ fi
273
+ DEVELOP_SYNCED="true"
274
+ return 0
195
275
  }
196
276
 
197
277
  # Initialize defaults used by setup_develop
@@ -200,25 +280,26 @@ DEVELOP_SYNCED="false"
200
280
  COMMITS_AHEAD=0
201
281
  ACTION="ready"
202
282
  SAVED_BRANCH=""
203
- BRANCH="${CURRENT_BRANCH:-develop}"
283
+ BRANCH="${CURRENT_BRANCH:-$BASE_BRANCH}"
284
+ BASE_BRANCH_READY="false"
204
285
 
205
286
  if [ "$IS_WORKTREE" = "true" ]; then
206
- # Inside a worktree — skip develop checkout and framework update.
207
- # Worktrees are isolated working copies; framework updates belong on develop.
287
+ # Inside a worktree — skip the base-branch checkout and framework update.
288
+ # Worktrees are isolated working copies; framework updates belong on the base.
208
289
  BRANCH=$(git branch --show-current 2>/dev/null || echo "?")
209
290
  DEVELOP_SYNCED="true"
210
291
 
211
292
  # --- Worktree branch health check ---
212
- # Detect if the branch was already merged into develop (e.g., PR merged
213
- # but worktree not cleaned up). This prevents working on a stale branch
214
- # whose commits are already in develop.
293
+ # Detect if the branch was already merged into the base branch (e.g., PR
294
+ # merged but worktree not cleaned up). This prevents working on a stale
295
+ # branch whose commits already landed.
215
296
  WORKTREE_STALE="false"
216
- if [ "$BRANCH" != "?" ] && [ "$BRANCH" != "develop" ] && [ "$BRANCH" != "main" ]; then
297
+ if [ "$BRANCH" != "?" ] && [ "$BRANCH" != "$BASE_BRANCH" ] && [ "$BRANCH" != "main" ]; then
217
298
  # Check if remote branch still exists
218
299
  if ! git ls-remote --heads origin "$BRANCH" 2>/dev/null | grep -q "$BRANCH"; then
219
- # Remote branch gone — check if it was merged into develop
220
- if git branch -r --merged origin/develop 2>/dev/null | grep -q "origin/$BRANCH" 2>/dev/null || \
221
- git merge-base --is-ancestor HEAD origin/develop 2>/dev/null; then
300
+ # Remote branch gone — check if it was merged into the base branch
301
+ if git branch -r --merged "origin/$BASE_BRANCH" 2>/dev/null | grep -q "origin/$BRANCH" 2>/dev/null || \
302
+ git merge-base --is-ancestor HEAD "origin/$BASE_BRANCH" 2>/dev/null; then
222
303
  WORKTREE_STALE="merged"
223
304
  else
224
305
  WORKTREE_STALE="remote_deleted"
@@ -228,16 +309,16 @@ if [ "$IS_WORKTREE" = "true" ]; then
228
309
 
229
310
  if [ "$WORKTREE_STALE" = "merged" ]; then
230
311
  echo ""
231
- echo "WARNING: Branch '$BRANCH' was already merged into develop."
232
- echo "This worktree is stale — your work here is already in develop."
312
+ echo "WARNING: Branch '$BRANCH' was already merged into $BASE_BRANCH."
313
+ echo "This worktree is stale — your work here is already in $BASE_BRANCH."
233
314
  echo "Start a new session in the main project to get a fresh branch."
234
315
  echo ""
235
316
  HEALTH_GIT="fail"
236
317
  elif [ "$WORKTREE_STALE" = "remote_deleted" ]; then
237
318
  echo ""
238
- echo "WARNING: Remote branch '$BRANCH' was deleted but NOT merged into develop."
319
+ echo "WARNING: Remote branch '$BRANCH' was deleted but NOT merged into $BASE_BRANCH."
239
320
  echo "This worktree may contain unique local commits. Check before discarding:"
240
- echo " git log origin/develop..HEAD --oneline"
321
+ echo " git log origin/$BASE_BRANCH..HEAD --oneline"
241
322
  echo ""
242
323
  fi
243
324
 
@@ -245,12 +326,14 @@ if [ "$IS_WORKTREE" = "true" ]; then
245
326
  if [ ! -f "$SCRIPT_DIR/.env" ] && [ -f "$MAIN_PROJECT_DIR/.env" ]; then
246
327
  export ENV_FILE="$MAIN_PROJECT_DIR/.env"
247
328
  fi
248
- elif ! setup_develop 2>/dev/null; then
329
+ elif setup_develop 2>/dev/null; then
330
+ BASE_BRANCH_READY="true"
331
+ else
249
332
  HEALTH_GIT="fail"
250
333
  fi
251
334
 
252
- # Apply framework update now — we're on develop (or worktree skipped above)
253
- if [ "$IS_WORKTREE" != "true" ]; then
335
+ # Apply a framework update only after setup verified the configured base branch.
336
+ if [ "$IS_WORKTREE" != "true" ] && [ "$BASE_BRANCH_READY" = "true" ]; then
254
337
  _apply_framework_update 2>/dev/null || true
255
338
  fi
256
339
 
@@ -272,7 +355,10 @@ for REPO in $MANAGED_REPOS; do
272
355
  REPO_DIR="$SCRIPT_DIR/../$REPO"
273
356
  if [ -d "$REPO_DIR/.git" ]; then
274
357
  # Resolve base branch for this repo (from egregore.json or auto-detect)
275
- REPO_BASE=$(_get_base_branch "$REPO")
358
+ if ! REPO_BASE=$(_get_base_branch "$REPO"); then
359
+ HEALTH_GIT="fail"
360
+ continue
361
+ fi
276
362
  # Sync base branch with remote (if not checked out)
277
363
  R_BRANCH=$(git -C "$REPO_DIR" branch --show-current 2>/dev/null || echo "?")
278
364
  if [ "$R_BRANCH" != "$REPO_BASE" ]; then
@@ -152,6 +152,20 @@ else
152
152
  fi
153
153
  fi
154
154
 
155
+ # Framework update trail — an auto-update overwrites every framework path from
156
+ # upstream, local edits included. It used to surface as the footer word
157
+ # "updated" in local mode and as nothing at all in connected mode, which is not
158
+ # enough notice for files being replaced under you. Name the count, name the
159
+ # first few, and point at the commit that did it.
160
+ if [ "${FRAMEWORK_UPDATED:-false}" = "true" ] && [ "${FRAMEWORK_UPDATED_COUNT:-0}" -gt 0 ]; then
161
+ FU_SHA=$(git rev-parse --short HEAD 2>/dev/null || echo "")
162
+ printf " ◆ framework updated from upstream — %s file(s) replaced: %s\n" \
163
+ "$FRAMEWORK_UPDATED_COUNT" "${FRAMEWORK_UPDATED_FILES% }"
164
+ if [ -n "$FU_SHA" ]; then
165
+ printf " local edits to framework paths are replaced by design — git show %s\n" "$FU_SHA"
166
+ fi
167
+ fi
168
+
155
169
  # Autosave trail — background saves (Stop-hook, sweep, SessionEnd) since the
156
170
  # last greeting. The ledger is machine-scoped; this is where sweep rescues of
157
171
  # abandoned sessions become visible to the user.
@@ -1,4 +1,4 @@
1
- #!/bin/bash
1
+ #!/usr/bin/env bash
2
2
  # Cross-platform hash helpers — sourced by scripts that need hashing.
3
3
 
4
4
  # Compute MD5 hash of a string (macOS + Linux compatible)
@@ -1,4 +1,4 @@
1
- #!/bin/bash
1
+ #!/usr/bin/env bash
2
2
  # noncode.sh — shared "non-coding change" classifier for auto-merge decisions.
3
3
  #
4
4
  # The org rule: non-coding PRs auto-merge to develop; code goes to review.
@@ -1,4 +1,4 @@
1
- #!/bin/bash
1
+ #!/usr/bin/env bash
2
2
  # Cross-platform time helpers — sourced by scripts that need time formatting.
3
3
 
4
4
  # Convert ISO timestamp to epoch seconds (macOS + Linux compatible)