create-egregore 0.19.21 → 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 +29 -3
  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
@@ -1,4 +1,4 @@
1
- #!/bin/bash
1
+ #!/usr/bin/env bash
2
2
  # Runtime-neutral Egregore agent bridge.
3
3
  #
4
4
  # This script exposes the Git-backed memory protocol without requiring
@@ -19,6 +19,10 @@ if [ -f "$SCRIPT_DIR/bin/lib/worktree-links.sh" ]; then
19
19
  fi
20
20
  CONFIG="$SCRIPT_DIR/egregore.json"
21
21
  MEMORY_DIR="${EGREGORE_MEMORY_DIR:-$SCRIPT_DIR/memory}"
22
+ if [ -f "$SCRIPT_DIR/bin/lib/config.sh" ]; then
23
+ # shellcheck source=bin/lib/config.sh
24
+ source "$SCRIPT_DIR/bin/lib/config.sh"
25
+ fi
22
26
 
23
27
  usage() {
24
28
  cat <<'EOF'
@@ -55,6 +59,15 @@ die() {
55
59
  exit 1
56
60
  }
57
61
 
62
+ resolve_base_branch() {
63
+ local base
64
+ if ! base=$(_get_base_branch); then
65
+ echo "agent.sh: could not resolve the configured base branch" >&2
66
+ return 1
67
+ fi
68
+ echo "$base"
69
+ }
70
+
58
71
  slugify() {
59
72
  echo "$1" \
60
73
  | tr '[:upper:]' '[:lower:]' \
@@ -152,13 +165,16 @@ worktree_for_branch() {
152
165
  }
153
166
 
154
167
  base_ref() {
155
- git -C "$MAIN_PROJECT_DIR" fetch origin develop --quiet 2>/dev/null || true
156
- if git -C "$MAIN_PROJECT_DIR" show-ref --verify --quiet refs/remotes/origin/develop 2>/dev/null; then
157
- echo "origin/develop"
158
- elif git -C "$MAIN_PROJECT_DIR" show-ref --verify --quiet refs/heads/develop 2>/dev/null; then
159
- echo "develop"
168
+ local base
169
+ base="$(resolve_base_branch)" || return 1
170
+ git -C "$MAIN_PROJECT_DIR" fetch origin "$base" --quiet 2>/dev/null || true
171
+ if git -C "$MAIN_PROJECT_DIR" show-ref --verify --quiet "refs/remotes/origin/$base" 2>/dev/null; then
172
+ echo "origin/$base"
173
+ elif git -C "$MAIN_PROJECT_DIR" show-ref --verify --quiet "refs/heads/$base" 2>/dev/null; then
174
+ echo "$base"
160
175
  else
161
- echo "HEAD"
176
+ echo "agent.sh: configured base branch '$base' does not exist locally or on origin" >&2
177
+ return 1
162
178
  fi
163
179
  }
164
180
 
@@ -275,7 +291,7 @@ cmd_branch() {
275
291
  bugfix) branch="bugfix/${slug}" ;;
276
292
  esac
277
293
 
278
- base="$(base_ref)"
294
+ base="$(base_ref)" || die "could not find a safe branch point"
279
295
 
280
296
  if [ -f "$SCRIPT_DIR/.git" ]; then
281
297
  if git -C "$SCRIPT_DIR" show-ref --verify --quiet "refs/heads/$branch" 2>/dev/null; then
@@ -326,7 +342,7 @@ ensure_working_branch() {
326
342
  slug="$(slugify "$topic")"
327
343
  [ -n "$slug" ] || slug="$(date +%Y-%m-%d)"
328
344
  branch="dev/${author}/${slug}"
329
- base="$(base_ref)"
345
+ base="$(base_ref)" || die "could not find a safe branch point"
330
346
 
331
347
  if git -C "$SCRIPT_DIR" show-ref --verify --quiet "refs/heads/$branch" 2>/dev/null; then
332
348
  git -C "$SCRIPT_DIR" checkout "$branch" --quiet || die "failed to checkout $branch"
@@ -339,16 +355,17 @@ ensure_working_branch() {
339
355
  build_pr_body() {
340
356
  # Compliant fallback PR body (spec: .claude/context/pr-format.md) built
341
357
  # from the commit log + diff when the calling agent supplies none.
342
- local topic="${1:-portable save}" commits stat
343
- commits="$(git -C "$SCRIPT_DIR" log --pretty='- %s' "origin/develop..HEAD" 2>/dev/null | head -8)"
358
+ local topic="${1:-portable save}" base commits stat
359
+ base="$(resolve_base_branch)" || return 1
360
+ commits="$(git -C "$SCRIPT_DIR" log --pretty='- %s' "origin/$base..HEAD" 2>/dev/null | head -8)"
344
361
  [ -n "$commits" ] || commits="- (commit list unavailable — see the Files tab)"
345
- stat="$(git -C "$SCRIPT_DIR" diff --shortstat "origin/develop...HEAD" 2>/dev/null | sed 's/^ *//')"
362
+ stat="$(git -C "$SCRIPT_DIR" diff --shortstat "origin/$base...HEAD" 2>/dev/null | sed 's/^ *//')"
346
363
  printf '## What\n%s\n\n## Why\nShell-agent session save — topic: %s. Body auto-generated by bin/agent.sh; pass --pr-body for a hand-written description.\n\n## Verification\nNot verified — auto-generated skeleton; review the diff before merging.%s\n\n🤖 Saved via bin/agent.sh\n' \
347
364
  "$commits" "$topic" "${stat:+ ($stat)}"
348
365
  }
349
366
 
350
367
  cmd_save() {
351
- local message="" topic="" no_pr=0 branch pushed="false" committed="false" pr_url="" existing_pr="" pr_number="" non_md="" merged="false" pr_body="" pr_body_file=""
368
+ local message="" topic="" no_pr=0 branch base pushed="false" committed="false" pr_url="" existing_pr="" pr_number="" non_md="" merged="false" pr_body="" pr_body_file=""
352
369
 
353
370
  while [ $# -gt 0 ]; do
354
371
  case "$1" in
@@ -363,6 +380,7 @@ cmd_save() {
363
380
 
364
381
  [ -n "$topic" ] || topic="portable save"
365
382
  [ -n "$message" ] || message="Save: $topic"
383
+ base="$(resolve_base_branch)" || die "save stopped before Git changes"
366
384
 
367
385
  if [ -d "$MEMORY_DIR" ]; then
368
386
  save_memory "$message" "."
@@ -397,11 +415,11 @@ cmd_save() {
397
415
  pr_body="$(cat "$pr_body_file")"
398
416
  fi
399
417
  [ -n "$pr_body" ] || pr_body="$(build_pr_body "$topic")"
400
- pr_url="$(gh pr create --base develop --head "$branch" --title "$message" --body "$pr_body" 2>/dev/null || true)"
418
+ pr_url="$(gh pr create --base "$base" --head "$branch" --title "$message" --body "$pr_body" 2>/dev/null || true)"
401
419
  fi
402
420
  fi
403
421
 
404
- # Non-coding saves auto-merge to develop (same rule as /save and the
422
+ # Non-coding saves auto-merge to the configured base (same rule as /save and the
405
423
  # handoff helper; policy in bin/lib/noncode.sh). `--auto` needs repo
406
424
  # auto-merge + pending required checks; without branch protection it always
407
425
  # errors, so fall back to a direct merge.
@@ -409,10 +427,10 @@ cmd_save() {
409
427
  # shellcheck source=bin/lib/noncode.sh
410
428
  . "$SCRIPT_DIR/bin/lib/noncode.sh" 2>/dev/null || true
411
429
  type noncode_blockers >/dev/null 2>&1 || noncode_blockers() {
412
- git -C "${2:-.}" diff "${1:-origin/develop}...HEAD" --name-only 2>/dev/null | grep -v '\.md$' | head -1 || true
430
+ git -C "${2:-.}" diff "${1:-origin/$base}...HEAD" --name-only 2>/dev/null | grep -v '\.md$' | head -1 || true
413
431
  }
414
432
  pr_number="${pr_url##*/}"
415
- non_code="$(noncode_blockers origin/develop "$SCRIPT_DIR")"
433
+ non_code="$(noncode_blockers "origin/$base" "$SCRIPT_DIR")"
416
434
  if [ -z "$non_code" ] && [ -n "$pr_number" ]; then
417
435
  if gh pr merge "$pr_number" --auto --merge >/dev/null 2>&1 \
418
436
  || gh pr merge "$pr_number" --merge >/dev/null 2>&1; then
@@ -425,7 +443,7 @@ cmd_save() {
425
443
  echo "commit: $committed"
426
444
  echo "push: $pushed"
427
445
  [ -n "$pr_url" ] && echo "pr: $pr_url"
428
- [ "$merged" = "true" ] && echo "merge: non-coding, merged to develop"
446
+ [ "$merged" = "true" ] && echo "merge: non-coding, merged to $base"
429
447
  return 0
430
448
  }
431
449
 
@@ -569,7 +587,8 @@ cmd_handoff() {
569
587
  echo "result: $result_out"
570
588
 
571
589
  # Parity with the Claude /handoff skill: save core-repo session work in the
572
- # background (non-coding diffs auto-merge to develop, code stays in a PR).
590
+ # background (non-coding diffs auto-merge to the configured base; code stays
591
+ # in a PR).
573
592
  if [ "$NO_PUSH" = "0" ]; then
574
593
  ( bash "$SCRIPT_DIR/bin/handoff-save-egregore.sh" "$from" "$topic" --repo-dir "$SCRIPT_DIR" >/dev/null 2>&1 & ) >/dev/null 2>&1
575
594
  fi
@@ -1,4 +1,4 @@
1
- #!/bin/bash
1
+ #!/usr/bin/env bash
2
2
  # The attendant — Egregore's ambient listener. A per-instance daemon that
3
3
  # watches for work Claude Code sessions leave behind when they die without
4
4
  # ceremony (terminal closed, laptop shut) and captures it:
@@ -426,7 +426,13 @@ LIFECYCLE_MARKER="$STATE_DIR/$KEY.handoff-lifecycle-ts"
426
426
 
427
427
  _handoff_lifecycle() {
428
428
  local now last mode api_url api_key result
429
- [ "$(jq -r '.features.handoff_lifecycle // true' "$CONFIG" 2>/dev/null)" = "true" ] || return 0
429
+ # Read the raw value, not `// true` — jq's `//` returns its right-hand side
430
+ # for null *and false*, so `{"features":{"handoff_lifecycle":false}}` used to
431
+ # resolve to "true" and the opt-out did nothing. Absent key still means on.
432
+ case "$(jq -r '.features.handoff_lifecycle | tojson' "$CONFIG" 2>/dev/null)" in
433
+ null|true) ;;
434
+ *) return 0 ;;
435
+ esac
430
436
  [ -f "$MAIN_DIR/bin/handoff-lifecycle-job.sh" ] || return 0
431
437
 
432
438
  mode=$(jq -r '.mode // "connected"' "$CONFIG" 2>/dev/null)
@@ -1,4 +1,4 @@
1
- #!/bin/bash
1
+ #!/usr/bin/env bash
2
2
  # autosave.sh — per-user autosave settings. The consent surface for ambient
3
3
  # session capture (see bin/session-autosave.sh, docs/autosave.md).
4
4
  #
@@ -1,9 +1,10 @@
1
- #!/bin/bash
1
+ #!/usr/bin/env bash
2
2
  set -euo pipefail
3
3
 
4
4
  # Detached reconciliation worker for explicit captures.
5
5
  # The foreground path only appends to graph-wal.sh; this worker pays network
6
- # latency, retries queued writes, and sends completion notifications.
6
+ # latency and retries queued writes. It may propose completion notifications,
7
+ # but detached reconciliation never approves or dispatches them.
7
8
 
8
9
  SCRIPT_DIR="$(cd "$(dirname "$0")/.." && pwd)"
9
10
  MODE="$(jq -r '.mode // "connected"' "$SCRIPT_DIR/egregore.json" 2>/dev/null || echo connected)"
@@ -32,6 +33,7 @@ CLAIM_CYPHER='
32
33
  MATCH (impl:Session {id: $sessionId})-[r:IMPLEMENTS]->(ho:Session)-[:BY]->(origin:Person)
33
34
  WHERE ho.handoffStatus = "done"
34
35
  AND r.completionNotifiedAt IS NULL
36
+ AND r.completionNotifyProposedAt IS NULL
35
37
  AND (r.completionNotifyClaimedAt IS NULL
36
38
  OR r.completionNotifyClaimedAt < datetime() - duration("PT1H"))
37
39
  SET r.completionNotifyClaimedAt = datetime()
@@ -46,11 +48,11 @@ while IFS=$'\t' read -r handoff_id topic recipient; do
46
48
  message="${AUTHOR:-A teammate} completed your handoff '${topic:-$handoff_id}'"
47
49
  [ -n "$SUMMARY" ] && message="${message} — $(printf '%s' "$SUMMARY" | tr '\n' ' ' | cut -c1-180)"
48
50
 
49
- notify_result="$(bash "$SCRIPT_DIR/bin/notify.sh" send "$recipient" "$message" 2>/dev/null || echo Failed)"
50
- if printf '%s' "$notify_result" | grep -qi '^Sent'; then
51
+ notify_result="$(bash "$SCRIPT_DIR/bin/notify.sh" plan send "$recipient" "$message" 2>/dev/null || echo '{}')"
52
+ if printf '%s' "$notify_result" | jq -e '.status == "approval_required"' >/dev/null 2>&1; then
51
53
  bash "$SCRIPT_DIR/bin/graph.sh" query '
52
54
  MATCH (impl:Session {id: $sessionId})-[r:IMPLEMENTS]->(ho:Session {id: $handoffId})
53
- SET r.completionNotifiedAt = datetime(),
55
+ SET r.completionNotifyProposedAt = datetime(),
54
56
  r.completionNotifyClaimedAt = null
55
57
  RETURN ho.id AS id
56
58
  ' "$(jq -nc --arg sessionId "$SESSION_ID" --arg handoffId "$handoff_id" \
@@ -59,7 +61,7 @@ while IFS=$'\t' read -r handoff_id topic recipient; do
59
61
  bash "$SCRIPT_DIR/bin/graph.sh" query '
60
62
  MATCH (impl:Session {id: $sessionId})-[r:IMPLEMENTS]->(ho:Session {id: $handoffId})
61
63
  SET r.completionNotifyClaimedAt = null,
62
- r.completionNotifyFailedAt = datetime()
64
+ r.completionNotifyProposalFailedAt = datetime()
63
65
  RETURN ho.id AS id
64
66
  ' "$(jq -nc --arg sessionId "$SESSION_ID" --arg handoffId "$handoff_id" \
65
67
  '{sessionId:$sessionId,handoffId:$handoffId}')" >/dev/null 2>&1 || true
@@ -1,4 +1,4 @@
1
- #!/bin/bash
1
+ #!/usr/bin/env bash
2
2
  set -euo pipefail
3
3
 
4
4
  # Shared capture engine for the three ways an Egregore session leaves a trace.
@@ -1,4 +1,4 @@
1
- #!/bin/bash
1
+ #!/usr/bin/env bash
2
2
  # Make Egregore's project-local Codex skills available without duplicating
3
3
  # them in CODEX_HOME.
4
4
  set -euo pipefail
@@ -179,11 +179,18 @@ const ON_LAUNCH_BODY = `The \`egregore\` launcher renders the Egregore startup c
179
179
 
180
180
  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
181
 
182
+ The integration branch is \`develop\` by default. When top-level
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.
186
+
182
187
  1. Derive a topic slug from what the user said (kebab-case, 2–4 words)
183
- 2. Run \`bin/agent.sh branch --topic "<topic>"\` — it creates a work branch from \`origin/develop\` in a task worktree (\`dev/{author}/{slug}\`, or \`feature/{slug}\` / \`bugfix/{slug}\` when the topic reads as a feature or fix) and prints the worktree path. Continue all file work from that printed path.
188
+ 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.
184
189
  3. Confirm: \`On {branch} (worktree).\`
185
190
 
186
- **Fallback:** If \`bin/agent.sh branch\` fails, use \`git checkout -b dev/{author}/{slug} origin/develop\`.
191
+ **Fallback:** If \`bin/agent.sh branch\` fails, resolve \`{base}\` with
192
+ \`_get_base_branch\`, then use
193
+ \`git checkout -b dev/{author}/{slug} origin/{base}\`.
187
194
 
188
195
  4. Update graph (fire-and-forget): \`bash bin/graph-op.sh set-topic "$(cat .egregore-session-id 2>/dev/null)" "topic from slug" "dev/author/slug" 2>/dev/null &\`
189
196
 
@@ -215,11 +222,11 @@ Report results: \`✓ Checked out {branch} in {repo1}, {repo2}\`. If a branch no
215
222
 
216
223
  **Topic pivot while on a working branch:** If the user describes work **unrelated** to the current branch's topic, treat it as a new topic and create a new branch (\`bin/agent.sh branch --topic "<new topic>"\`). Do NOT mix unrelated work on one branch.
217
224
 
218
- If on develop after two messages, create a branch immediately from whatever context you have.
225
+ If still on the configured base branch after two messages, create a branch immediately from whatever context you have.
219
226
 
220
227
  ### Branch-guard protocol
221
228
 
222
- The \`.codex/hooks/branch-guard.js\` PreToolUse hook (enabled by the launcher via \`--enable hooks\`) protects project writes on \`develop\`/\`main\`/\`master\`. Its block message is operational guidance, not a reason to interrupt the user with routine Git choices:
229
+ The \`.codex/hooks/branch-guard.js\` PreToolUse hook (enabled by the launcher via \`--enable hooks\`) protects project writes on the configured base branch as well as \`develop\`/\`main\`/\`master\`. Its block message is operational guidance, not a reason to interrupt the user with routine Git choices:
223
230
 
224
231
  - **Topic is clear** (the user said "fix X", "add Y feature") → run \`bin/agent.sh branch --topic "<topic>"\` automatically, continue in the printed worktree, and say one short sentence so the branch change is visible. Do not ask the user to approve routine branching.
225
232
  - **Topic is genuinely ambiguous** → ask only for the topic, using compact numbered options:
@@ -236,7 +243,7 @@ The \`.codex/hooks/branch-guard.js\` PreToolUse hook (enabled by the launcher vi
236
243
 
237
244
  Memory, managed-repo, and runtime-state writes should bypass the project guard. If one triggers it, correct the operation target/context instead of asking for protected-branch consent.
238
245
 
239
- If this Codex build does not support hooks, follow the same discipline as a standing instruction: never write or commit on develop/main/master.
246
+ 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.
240
247
 
241
248
  ### Onboarding exception
242
249
 
@@ -1,4 +1,4 @@
1
- #!/bin/bash
1
+ #!/usr/bin/env bash
2
2
  set -o pipefail
3
3
 
4
4
  # Codex does not run Claude Code SessionStart hooks. This is the runtime-neutral
@@ -1,4 +1,4 @@
1
- #!/bin/bash
1
+ #!/usr/bin/env bash
2
2
  set -euo pipefail
3
3
 
4
4
  SCRIPT_DIR="$(cd "$(dirname "$0")/.." && pwd)"
@@ -162,11 +162,15 @@ EOF
162
162
  cat <<EOF
163
163
  1. Read \`${source}\` for the workflow details.
164
164
  2. Run the referenced \`bin/\` scripts directly from Codex.
165
- 3. Treat graph, publish, and notify steps as best-effort unless that workflow
166
- explicitly says they are required.
167
- 4. Keep local-mode behavior filesystem-first and avoid graph or notification
165
+ 3. Treat graph and publish steps as best-effort unless that workflow explicitly
166
+ says they are required.
167
+ 4. For every external notification, follow
168
+ \`.claude/context/notification-consent.md\`: plan without sending, then show
169
+ a separate exact Send / Edit / Cancel checkpoint. Never infer notification
170
+ consent from the workflow request or a batch approval.
171
+ 5. Keep local-mode behavior filesystem-first and avoid graph or notification
168
172
  calls when \`egregore.json\` declares \`"mode": "local"\`.
169
- 5. Never call the deprecated \`egregore-handoff\` CLI for Egregore project
173
+ 6. Never call the deprecated \`egregore-handoff\` CLI for Egregore project
170
174
  handoffs.
171
175
  EOF
172
176
  }
@@ -1,4 +1,4 @@
1
- #!/bin/bash
1
+ #!/usr/bin/env bash
2
2
  # Fetches personal dashboard data: single API call + parallel git ops.
3
3
  # Usage: bash bin/dashboard-data.sh [username] [time_range]
4
4
  # Returns a single JSON object with all query results.
@@ -1,4 +1,4 @@
1
- #!/bin/bash
1
+ #!/usr/bin/env bash
2
2
  set -euo pipefail
3
3
 
4
4
  # Execute multiple Cypher queries in a single HTTP call.
@@ -1,4 +1,4 @@
1
- #!/bin/bash
1
+ #!/usr/bin/env bash
2
2
  set -euo pipefail
3
3
  # Named graph operations — clean interface over raw Cypher.
4
4
  # Keeps implementation details out of the TUI.
@@ -1,4 +1,4 @@
1
- #!/bin/bash
1
+ #!/usr/bin/env bash
2
2
  # Graph Write-Ahead Log — resilient graph writes with local buffer.
3
3
  # Mirrors bin/telemetry.sh architecture.
4
4
  #
@@ -1,4 +1,4 @@
1
- #!/bin/bash
1
+ #!/usr/bin/env bash
2
2
  set -euo pipefail
3
3
 
4
4
  SCRIPT_DIR="$(cd "$(dirname "$0")/.." && pwd)"
@@ -1,4 +1,4 @@
1
- #!/bin/bash
1
+ #!/usr/bin/env bash
2
2
  # handoff-pr-backfill.sh — fill in PR numbers in a handoff file's ## Repo State
3
3
  # table, then re-commit + push the memory repo. Detached fire-and-forget from
4
4
  # /handoff's hot path so user-visible latency doesn't include N × `gh pr list`.
@@ -1,4 +1,4 @@
1
- #!/bin/bash
1
+ #!/usr/bin/env bash
2
2
  set -euo pipefail
3
3
  # handoff-run.sh — atomic orchestrator for /handoff.
4
4
  #
@@ -25,7 +25,7 @@ set -euo pipefail
25
25
  # and returns a subgraph snapshot in the result JSON
26
26
  # 6. Commits + pushes memory repo (with orphan-stash dance if needed)
27
27
  # 7. Publishes HTML artifact via bin/publish-artifact.sh
28
- # 8. Sends Telegram notification via bin/notify.sh (if recipient)
28
+ # 8. Creates an exact notification proposal via bin/notify.sh (never sends)
29
29
  # 9. Emits ONE status line and ONE JSON blob on stdout
30
30
  #
31
31
  # Exit codes:
@@ -231,14 +231,14 @@ awk -v line="$IDX_LINE" '
231
231
  END { if (!inserted) print line }
232
232
  ' "$INDEX" > "$INDEX.new" && mv "$INDEX.new" "$INDEX"
233
233
 
234
- # --- Parallel stage: graph + memory + (publish → notify) ----------------
234
+ # --- Parallel stage: graph + memory + (publish → notification proposal) -
235
235
  #
236
236
  # Three independent branches fork here and join before we emit the result:
237
237
  # A. Graph index — reads ABS_FILE, writes Session node to Neo4j, and
238
238
  # returns the handoff's neighborhood as subgraph JSON.
239
239
  # B. Memory push — commits + pushes memory repo (orphan-stash dance).
240
- # C. Publish+notify — publishes HTML artifact, then (if recipient is set)
241
- # sends Telegram with the artifact URL embedded.
240
+ # C. Publish+plan — publishes HTML artifact, then creates an immutable
241
+ # notification proposal with the artifact URL embedded.
242
242
  #
243
243
  # Each branch writes its result to a tmpfile. Wall-clock is max(A,B,C).
244
244
  #
@@ -251,7 +251,7 @@ MEMORY_DIR="$SCRIPT_DIR/memory"
251
251
  TMPD=$(mktemp -d -t handoff-run-XXXXXX)
252
252
  trap 'rm -rf "$TMPD"' EXIT
253
253
 
254
- # Extract briefing text once (used by publish and notify) so we don't
254
+ # Extract briefing text once (used by publish and the proposal) so we don't
255
255
  # re-awk the same file inside multiple workers.
256
256
  BRIEFING_LEAD=$(awk '/^## Briefing/{found=1; next} found && /^##/{exit} found && NF{print}' "$ABS_FILE" 2>/dev/null \
257
257
  | head -2 | tr '\n' ' ' | cut -c1-200 || true)
@@ -390,7 +390,11 @@ PID_MEMORY=$!
390
390
  fi
391
391
  EMISSARY_API_URL="${EMISSARY_API_URL:-https://egregore-production-55f2.up.railway.app/api/v1/emissary}"
392
392
 
393
- if [ -n "$EMISSARY_TOKEN" ]; then
393
+ # /handoff is an internal team primitive, not an implicit public-emissary
394
+ # composer. Use the emissary route only for an explicit recipient, and make
395
+ # that artifact directed-private. Recipient-less handoffs fall through to
396
+ # the org-scoped publisher (connected) or opt-in relay (local).
397
+ if [ -n "$EMISSARY_TOKEN" ] && [ -n "$RECIPIENT" ]; then
394
398
  # Step 1: render the handoff to HTML locally using egregore-artifacts.
395
399
  # Same renderer + template publish-artifact.sh uses today — handoffs
396
400
  # keep their familiar look.
@@ -422,12 +426,8 @@ PID_MEMORY=$!
422
426
  DISPLAY_NAME=$(head -1 "$PERSON_FILE" | sed 's/^# //')
423
427
  fi
424
428
 
425
- # addressed_to: only set if there's a recipient
426
- ADDRESSED_TO="[]"
427
- if [ -n "$RECIPIENT" ]; then
428
- RECIP_HANDLE=$(echo "$RECIPIENT" | tr '[:upper:]' '[:lower:]' | awk '{print $1}')
429
- ADDRESSED_TO=$(jq -nc --arg h "$RECIP_HANDLE" --arg d "$RECIPIENT" '[{"handle":$h,"display":$d}]')
430
- fi
429
+ RECIP_HANDLE=$(echo "$RECIPIENT" | tr '[:upper:]' '[:lower:]' | awk '{print $1}')
430
+ ADDRESSED_TO=$(jq -nc --arg h "$RECIP_HANDLE" --arg d "$RECIPIENT" '[{"handle":$h,"display":$d}]')
431
431
 
432
432
  CLAIM=$(echo "$BRIEFING_LEAD" | cut -c1-200)
433
433
 
@@ -456,8 +456,8 @@ PID_MEMORY=$!
456
456
  body: { prose: $prose },
457
457
  audience: {
458
458
  addressed_to: $addressed,
459
- visible_to: "public",
460
- extendable_by: "anyone"
459
+ visible_to: $addressed,
460
+ extendable_by: $addressed
461
461
  },
462
462
  parents: [],
463
463
  render_mode: "custom",
@@ -475,15 +475,30 @@ PID_MEMORY=$!
475
475
  fi
476
476
  fi
477
477
 
478
- # Fallback: if the emissary publish didn't produce a URL (no token, no
479
- # network, size cap, render failure), fire the legacy publish-artifact.sh
480
- # so handoffs still get a Telegram-able URL.
478
+ # Fallback: if a directed emissary publish didn't produce a URL—or this is a
479
+ # recipient-less team handoff—use publish-artifact.sh. Connected mode is
480
+ # authenticated and org-scoped; local mode's public relay is opt-in.
481
+ PUBLISH_RC=0
481
482
  if [ -z "$V1URL" ] && [ "$NO_PUBLISH" = "0" ] && [ -x "$SCRIPT_DIR/bin/publish-artifact.sh" ]; then
482
483
  AURL=$(bash "$SCRIPT_DIR/bin/publish-artifact.sh" "$RENDER_TYPE" "${RENDER_SRC:-$ABS_FILE}" \
483
484
  --title "$TOPIC" \
484
485
  --author "$AUTHOR" \
485
- --description "$BRIEFING_LEAD" 2>/dev/null || echo "")
486
+ --description "$BRIEFING_LEAD" 2>/dev/null) || PUBLISH_RC=$?
487
+ fi
488
+
489
+ PS="published"
490
+ if [ "$NO_PUBLISH" = "1" ]; then
491
+ PS="disabled"
492
+ elif [ -n "$V1URL" ] || [ -n "$AURL" ]; then
493
+ PS="published"
494
+ elif [ "$PUBLISH_RC" = "4" ]; then
495
+ PS="relay-off"
496
+ elif [ "$PUBLISH_RC" = "3" ]; then
497
+ PS="hosting-off"
498
+ else
499
+ PS="failed"
486
500
  fi
501
+ echo "$PS" > "$TMPD/publish"
487
502
 
488
503
  # Prefer v1 (emissary-rendered) URL when available; fall back to the
489
504
  # legacy egregore-artifacts URL only if the v1 publish failed.
@@ -497,6 +512,7 @@ PID_MEMORY=$!
497
512
  fi
498
513
 
499
514
  NS="skipped"
515
+ echo '{}' > "$TMPD/notify-plan"
500
516
  if [ "$NO_NOTIFY" = "0" ]; then
501
517
  if [ -n "$NOTIFY_URL" ]; then
502
518
  MSG_NOTIFY="Handoff from ${AUTHOR}: ${TOPIC}
@@ -510,21 +526,19 @@ View: ${NOTIFY_URL}"
510
526
  \"${BRIEFING_SHORT}\""
511
527
  fi
512
528
 
513
- # Always notify. With a recipient (connected mode) → DM. Otherwise → group.
514
- # Self-handoffs still post to the group so they're visible on /activity
515
- # and in the Telegram feed — a handoff without a Telegram beat is invisible.
516
- if [ -n "$RECIPIENT" ] && [ "$MODE" = "connected" ]; then
517
- NR=$(bash "$SCRIPT_DIR/bin/notify.sh" send "$RECIPIENT" "$MSG_NOTIFY" 2>/dev/null || echo "Failed")
529
+ # Resolve the exact destination, but never approve or dispatch here. The
530
+ # interactive harness must show this proposal in a separate checkpoint.
531
+ if [ -n "$RECIPIENT" ]; then
532
+ NR=$(bash "$SCRIPT_DIR/bin/notify.sh" plan send "$RECIPIENT" "$MSG_NOTIFY" 2>/dev/null || echo '{}')
518
533
  else
519
- NR=$(bash "$SCRIPT_DIR/bin/notify.sh" group "$MSG_NOTIFY" 2>/dev/null || echo "Failed")
534
+ NR=$(bash "$SCRIPT_DIR/bin/notify.sh" plan group "$MSG_NOTIFY" 2>/dev/null || echo '{}')
520
535
  fi
521
536
 
522
- if echo "$NR" | grep -qi "^Sent"; then
523
- NS="sent"
524
- elif echo "$NR" | grep -qi "^Failed"; then
525
- NS="failed"
537
+ if printf '%s' "$NR" | jq -e '.status == "approval_required"' >/dev/null 2>&1; then
538
+ NS="approval_required"
539
+ printf '%s\n' "$NR" > "$TMPD/notify-plan"
526
540
  else
527
- NS="unknown"
541
+ NS="unavailable"
528
542
  fi
529
543
  fi
530
544
  echo "$NS" > "$TMPD/notify"
@@ -574,6 +588,9 @@ fi
574
588
  MEMORY_STATUS=$(cat "$TMPD/memory" 2>/dev/null || echo "skipped")
575
589
  ARTIFACT_URL=$(cat "$TMPD/artifact" 2>/dev/null || echo "")
576
590
  NOTIFY_STATUS=$(cat "$TMPD/notify" 2>/dev/null || echo "skipped")
591
+ NOTIFY_PLAN=$(cat "$TMPD/notify-plan" 2>/dev/null || echo "{}")
592
+ PUBLISH_STATUS=$(cat "$TMPD/publish" 2>/dev/null || echo "skipped")
593
+ [ -z "$PUBLISH_STATUS" ] && PUBLISH_STATUS="skipped"
577
594
  ARTIFACTS_ARR=$(cat "$TMPD/artifacts" 2>/dev/null || echo "[]")
578
595
  [ -z "$ARTIFACTS_ARR" ] && ARTIFACTS_ARR="[]"
579
596
 
@@ -594,16 +611,9 @@ fi
594
611
  STATUS_BITS=("saved")
595
612
  [ "$GRAPH_STATUS" = "ok" ] && STATUS_BITS+=("graphed")
596
613
  [ "$MEMORY_STATUS" = "ok" ] && STATUS_BITS+=("pushed")
597
- if [ "$NOTIFY_STATUS" = "sent" ]; then
598
- if [ -n "$RECIPIENT" ]; then
599
- STATUS_BITS+=("${RECIPIENT} notified")
600
- else
601
- STATUS_BITS+=("group notified")
602
- fi
603
- elif [ "$NOTIFY_STATUS" = "unknown" ] && [ -n "$RECIPIENT" ]; then
604
- STATUS_BITS+=("${RECIPIENT} relayed to group")
605
- fi
614
+ [ "$NOTIFY_STATUS" = "approval_required" ] && STATUS_BITS+=("notify approval pending")
606
615
  [ -n "$ARTIFACT_URL" ] && STATUS_BITS+=("published")
616
+ [ "$PUBLISH_STATUS" = "relay-off" ] && STATUS_BITS+=("not published")
607
617
 
608
618
  STATUS_LINE=""
609
619
  for bit in "${STATUS_BITS[@]}"; do
@@ -625,7 +635,9 @@ jq -cn \
625
635
  --arg graphStatus "$GRAPH_STATUS" \
626
636
  --arg memoryStatus "$MEMORY_STATUS" \
627
637
  --arg notifyStatus "$NOTIFY_STATUS" \
638
+ --argjson notifyPlan "$NOTIFY_PLAN" \
628
639
  --arg artifactUrl "$ARTIFACT_URL" \
640
+ --arg publishStatus "$PUBLISH_STATUS" \
629
641
  --arg recipient "$RECIPIENT" \
630
642
  --arg topic "$TOPIC" \
631
643
  --arg author "$AUTHOR" \
@@ -640,7 +652,9 @@ jq -cn \
640
652
  graphStatus:$graphStatus,
641
653
  memoryStatus:$memoryStatus,
642
654
  notifyStatus:$notifyStatus,
655
+ notifyPlan:$notifyPlan,
643
656
  artifactUrl:$artifactUrl,
657
+ publishStatus:$publishStatus,
644
658
  recipient:$recipient,
645
659
  topic:$topic,
646
660
  author:$author,