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.
Files changed (250) hide show
  1. package/assets/egregore-launcher.js +141 -14
  2. package/bin/cli.js +19 -3
  3. package/lib/connect-runtime.js +4 -2
  4. package/lib/local.js +15 -1
  5. package/lib/prime-runtime.js +208 -0
  6. package/lib/setup.js +66 -5
  7. package/package.json +4 -3
  8. package/runtime/codex/.codex/config.toml +3 -0
  9. package/runtime/codex/.codex/skills/archive/SKILL.md +1 -1
  10. package/runtime/codex/.codex/skills/branch/SKILL.md +1 -1
  11. package/runtime/codex/.codex/skills/checkup/SKILL.md +1 -1
  12. package/runtime/codex/.codex/skills/commit/SKILL.md +1 -1
  13. package/runtime/codex/.codex/skills/contribute/SKILL.md +1 -1
  14. package/runtime/codex/.codex/skills/delete-user/SKILL.md +1 -1
  15. package/runtime/codex/.codex/skills/ingest/SKILL.md +1 -1
  16. package/runtime/codex/.codex/skills/ingest-corpus/SKILL.md +29 -0
  17. package/runtime/codex/.codex/skills/ingest-notion/SKILL.md +29 -0
  18. package/runtime/codex/.codex/skills/ingest-user-interview/SKILL.md +1 -1
  19. package/runtime/codex/.codex/skills/issue/SKILL.md +1 -1
  20. package/runtime/codex/.codex/skills/me/SKILL.md +1 -1
  21. package/runtime/codex/.codex/skills/meeting/SKILL.md +1 -1
  22. package/runtime/codex/.codex/skills/note/SKILL.md +1 -1
  23. package/runtime/codex/.codex/skills/notion-connect/SKILL.md +29 -0
  24. package/runtime/codex/.codex/skills/onboarding/SKILL.md +1 -1
  25. package/runtime/codex/.codex/skills/pr/SKILL.md +1 -1
  26. package/runtime/codex/.codex/skills/pull/SKILL.md +1 -1
  27. package/runtime/codex/.codex/skills/push/SKILL.md +1 -1
  28. package/runtime/codex/.codex/skills/reflect/SKILL.md +1 -1
  29. package/runtime/codex/.codex/skills/review-pr/SKILL.md +1 -1
  30. package/runtime/codex/.codex/skills/save/SKILL.md +3 -1
  31. package/runtime/codex/.codex/skills/slack-connect/SKILL.md +1 -1
  32. package/runtime/codex/.codex/skills/summon/SKILL.md +1 -1
  33. package/runtime/codex/.codex/skills/sync-repos/SKILL.md +1 -1
  34. package/runtime/codex/.codex/skills/teams-connect/SKILL.md +29 -0
  35. package/runtime/codex/.codex/skills/telegram-connect/SKILL.md +1 -1
  36. package/runtime/codex/.codex/skills/telemetry/SKILL.md +1 -1
  37. package/runtime/codex/.codex/skills/test/SKILL.md +1 -1
  38. package/runtime/codex/.codex/skills/tutorial/SKILL.md +1 -1
  39. package/runtime/codex/.codex/skills/update/SKILL.md +1 -1
  40. package/runtime/codex/.codex/spec-manifest.json +5 -5
  41. package/runtime/codex/AGENTS.md +41 -35
  42. package/runtime/codex/bin/activity-data.sh +4 -8
  43. package/runtime/codex/bin/agent.sh +17 -5
  44. package/runtime/codex/bin/attendant.sh +13 -0
  45. package/runtime/codex/bin/autosave.sh +27 -1
  46. package/runtime/codex/bin/codex-render-spec.mjs +33 -32
  47. package/runtime/codex/bin/codex-session-start.sh +3 -1
  48. package/runtime/codex/bin/codex-sync-skills.sh +6 -1
  49. package/runtime/codex/bin/graph-batch.sh +25 -6
  50. package/runtime/codex/bin/graph-op.sh +5 -4
  51. package/runtime/codex/bin/graph.sh +31 -5
  52. package/runtime/codex/bin/handoff-pr-backfill.sh +1 -1
  53. package/runtime/codex/bin/handoff-run.sh +8 -3
  54. package/runtime/codex/bin/handoff-save-egregore.sh +19 -7
  55. package/runtime/codex/bin/ingest.py +341 -10
  56. package/runtime/codex/bin/lib/context.sh +26 -1
  57. package/runtime/codex/bin/lib/git-message.sh +37 -0
  58. package/runtime/codex/bin/lib/git-sync.sh +10 -2
  59. package/runtime/codex/bin/lib/greeting.sh +4 -1
  60. package/runtime/codex/bin/lib/worktree-links.sh +25 -0
  61. package/runtime/codex/bin/session-autosave.sh +7 -1
  62. package/runtime/codex/bin/settings.sh +1 -1
  63. package/runtime/codex/manifest.json +10 -1
  64. package/runtime/pi/.codex/config.toml +3 -0
  65. package/runtime/pi/.codex/skills/archive/SKILL.md +1 -1
  66. package/runtime/pi/.codex/skills/branch/SKILL.md +1 -1
  67. package/runtime/pi/.codex/skills/checkup/SKILL.md +1 -1
  68. package/runtime/pi/.codex/skills/commit/SKILL.md +1 -1
  69. package/runtime/pi/.codex/skills/contribute/SKILL.md +1 -1
  70. package/runtime/pi/.codex/skills/delete-user/SKILL.md +1 -1
  71. package/runtime/pi/.codex/skills/ingest/SKILL.md +1 -1
  72. package/runtime/pi/.codex/skills/ingest-corpus/SKILL.md +29 -0
  73. package/runtime/pi/.codex/skills/ingest-notion/SKILL.md +29 -0
  74. package/runtime/pi/.codex/skills/ingest-user-interview/SKILL.md +1 -1
  75. package/runtime/pi/.codex/skills/issue/SKILL.md +1 -1
  76. package/runtime/pi/.codex/skills/me/SKILL.md +1 -1
  77. package/runtime/pi/.codex/skills/meeting/SKILL.md +1 -1
  78. package/runtime/pi/.codex/skills/note/SKILL.md +1 -1
  79. package/runtime/pi/.codex/skills/notion-connect/SKILL.md +29 -0
  80. package/runtime/pi/.codex/skills/onboarding/SKILL.md +1 -1
  81. package/runtime/pi/.codex/skills/pr/SKILL.md +1 -1
  82. package/runtime/pi/.codex/skills/pull/SKILL.md +1 -1
  83. package/runtime/pi/.codex/skills/push/SKILL.md +1 -1
  84. package/runtime/pi/.codex/skills/reflect/SKILL.md +1 -1
  85. package/runtime/pi/.codex/skills/review-pr/SKILL.md +1 -1
  86. package/runtime/pi/.codex/skills/save/SKILL.md +3 -1
  87. package/runtime/pi/.codex/skills/slack-connect/SKILL.md +1 -1
  88. package/runtime/pi/.codex/skills/summon/SKILL.md +1 -1
  89. package/runtime/pi/.codex/skills/sync-repos/SKILL.md +1 -1
  90. package/runtime/pi/.codex/skills/teams-connect/SKILL.md +29 -0
  91. package/runtime/pi/.codex/skills/telegram-connect/SKILL.md +1 -1
  92. package/runtime/pi/.codex/skills/telemetry/SKILL.md +1 -1
  93. package/runtime/pi/.codex/skills/test/SKILL.md +1 -1
  94. package/runtime/pi/.codex/skills/tutorial/SKILL.md +1 -1
  95. package/runtime/pi/.codex/skills/update/SKILL.md +1 -1
  96. package/runtime/pi/.codex/spec-manifest.json +5 -5
  97. package/runtime/pi/.pi/APPEND_SYSTEM.md +57 -33
  98. package/runtime/pi/.pi/extensions/egregore.ts +17 -6
  99. package/runtime/pi/.pi/spec-manifest.json +2 -2
  100. package/runtime/pi/AGENTS.md +41 -35
  101. package/runtime/pi/bin/activity-data.sh +4 -8
  102. package/runtime/pi/bin/agent.sh +17 -5
  103. package/runtime/pi/bin/attendant.sh +13 -0
  104. package/runtime/pi/bin/autosave.sh +27 -1
  105. package/runtime/pi/bin/codex-render-spec.mjs +33 -32
  106. package/runtime/pi/bin/codex-session-start.sh +3 -1
  107. package/runtime/pi/bin/codex-sync-skills.sh +6 -1
  108. package/runtime/pi/bin/graph-batch.sh +25 -6
  109. package/runtime/pi/bin/graph-op.sh +5 -4
  110. package/runtime/pi/bin/graph.sh +31 -5
  111. package/runtime/pi/bin/handoff-pr-backfill.sh +1 -1
  112. package/runtime/pi/bin/handoff-run.sh +8 -3
  113. package/runtime/pi/bin/handoff-save-egregore.sh +19 -7
  114. package/runtime/pi/bin/ingest.py +341 -10
  115. package/runtime/pi/bin/lib/context.sh +26 -1
  116. package/runtime/pi/bin/lib/git-message.sh +37 -0
  117. package/runtime/pi/bin/lib/git-sync.sh +10 -2
  118. package/runtime/pi/bin/lib/greeting.sh +4 -1
  119. package/runtime/pi/bin/lib/worktree-links.sh +25 -0
  120. package/runtime/pi/bin/pi-branch-policy.mjs +138 -1
  121. package/runtime/pi/bin/pi-product-workflows.mjs +35 -7
  122. package/runtime/pi/bin/pi-render-spec.mjs +52 -26
  123. package/runtime/pi/bin/session-autosave.sh +7 -1
  124. package/runtime/pi/bin/settings.sh +1 -1
  125. package/runtime/pi/manifest.json +10 -1
  126. package/runtime/prime/.claude/context/notification-consent.md +66 -0
  127. package/runtime/prime/.codex/config.toml +20 -0
  128. package/runtime/prime/.codex/hooks/branch-guard.js +461 -0
  129. package/runtime/prime/.codex/hooks/search-hint.js +67 -0
  130. package/runtime/prime/.codex/hooks.json +30 -0
  131. package/runtime/prime/.codex/skills/activity/SKILL.md +82 -0
  132. package/runtime/prime/.codex/skills/announce/SKILL.md +67 -0
  133. package/runtime/prime/.codex/skills/archive/SKILL.md +45 -0
  134. package/runtime/prime/.codex/skills/branch/SKILL.md +29 -0
  135. package/runtime/prime/.codex/skills/checkup/SKILL.md +45 -0
  136. package/runtime/prime/.codex/skills/commit/SKILL.md +29 -0
  137. package/runtime/prime/.codex/skills/contribute/SKILL.md +29 -0
  138. package/runtime/prime/.codex/skills/create-skill/SKILL.md +29 -0
  139. package/runtime/prime/.codex/skills/dark-mode/SKILL.md +29 -0
  140. package/runtime/prime/.codex/skills/dashboard/SKILL.md +59 -0
  141. package/runtime/prime/.codex/skills/deep-reflect/SKILL.md +109 -0
  142. package/runtime/prime/.codex/skills/delete-user/SKILL.md +29 -0
  143. package/runtime/prime/.codex/skills/emissary/SKILL.md +45 -0
  144. package/runtime/prime/.codex/skills/handoff/SKILL.md +166 -0
  145. package/runtime/prime/.codex/skills/harvest/QUESTION_PALETTE.md +76 -0
  146. package/runtime/prime/.codex/skills/harvest/SKILL.md +131 -0
  147. package/runtime/prime/.codex/skills/ingest/SKILL.md +29 -0
  148. package/runtime/prime/.codex/skills/ingest-corpus/SKILL.md +29 -0
  149. package/runtime/prime/.codex/skills/ingest-notion/SKILL.md +29 -0
  150. package/runtime/prime/.codex/skills/ingest-user-interview/SKILL.md +45 -0
  151. package/runtime/prime/.codex/skills/invite/SKILL.md +44 -0
  152. package/runtime/prime/.codex/skills/issue/SKILL.md +45 -0
  153. package/runtime/prime/.codex/skills/me/SKILL.md +29 -0
  154. package/runtime/prime/.codex/skills/meeting/SKILL.md +45 -0
  155. package/runtime/prime/.codex/skills/note/SKILL.md +29 -0
  156. package/runtime/prime/.codex/skills/notion-connect/SKILL.md +29 -0
  157. package/runtime/prime/.codex/skills/onboarding/SKILL.md +45 -0
  158. package/runtime/prime/.codex/skills/pr/SKILL.md +29 -0
  159. package/runtime/prime/.codex/skills/pull/SKILL.md +29 -0
  160. package/runtime/prime/.codex/skills/push/SKILL.md +29 -0
  161. package/runtime/prime/.codex/skills/quest/SKILL.md +80 -0
  162. package/runtime/prime/.codex/skills/reflect/SKILL.md +45 -0
  163. package/runtime/prime/.codex/skills/review-pr/SKILL.md +45 -0
  164. package/runtime/prime/.codex/skills/save/SKILL.md +127 -0
  165. package/runtime/prime/.codex/skills/slack-connect/SKILL.md +29 -0
  166. package/runtime/prime/.codex/skills/summon/SKILL.md +45 -0
  167. package/runtime/prime/.codex/skills/sync-repos/SKILL.md +29 -0
  168. package/runtime/prime/.codex/skills/teams-connect/SKILL.md +29 -0
  169. package/runtime/prime/.codex/skills/telegram-connect/SKILL.md +29 -0
  170. package/runtime/prime/.codex/skills/telemetry/SKILL.md +29 -0
  171. package/runtime/prime/.codex/skills/test/SKILL.md +45 -0
  172. package/runtime/prime/.codex/skills/the-spiral/SKILL.md +84 -0
  173. package/runtime/prime/.codex/skills/tui-design/SKILL.md +45 -0
  174. package/runtime/prime/.codex/skills/tutorial/SKILL.md +45 -0
  175. package/runtime/prime/.codex/skills/update/SKILL.md +29 -0
  176. package/runtime/prime/.codex/skills/view/SKILL.md +156 -0
  177. package/runtime/prime/.codex/skills/view/agents/openai.yaml +4 -0
  178. package/runtime/prime/.codex/skills/view/assets/compose-scaffold.html +221 -0
  179. package/runtime/prime/.codex/skills/visual-explain/SKILL.md +45 -0
  180. package/runtime/prime/.codex/skills/wrap/SKILL.md +58 -0
  181. package/runtime/prime/.codex/spec-manifest.json +132 -0
  182. package/runtime/prime/.prime/agent/APPEND_SYSTEM.md +416 -0
  183. package/runtime/prime/.prime/agent/extensions/egregore.ts +460 -0
  184. package/runtime/prime/.prime/agent/settings.json +4 -0
  185. package/runtime/prime/.prime/agent/skills/egregore/SKILL.md +34 -0
  186. package/runtime/prime/.prime/agent/skills/egregore/pyproject.toml +13 -0
  187. package/runtime/prime/.prime/agent/skills/egregore/src/egregore/__init__.py +156 -0
  188. package/runtime/prime/.prime/agent/spec-manifest.json +12 -0
  189. package/runtime/prime/AGENTS.md +488 -0
  190. package/runtime/prime/bin/activity-data.sh +238 -0
  191. package/runtime/prime/bin/agent.sh +787 -0
  192. package/runtime/prime/bin/attendant.sh +707 -0
  193. package/runtime/prime/bin/autosave.sh +112 -0
  194. package/runtime/prime/bin/capture-reconcile.sh +69 -0
  195. package/runtime/prime/bin/capture-run.sh +341 -0
  196. package/runtime/prime/bin/codex-install-skills.sh +78 -0
  197. package/runtime/prime/bin/codex-render-spec.mjs +435 -0
  198. package/runtime/prime/bin/codex-session-start.sh +265 -0
  199. package/runtime/prime/bin/codex-skill-render.mjs +347 -0
  200. package/runtime/prime/bin/codex-sync-skills.sh +237 -0
  201. package/runtime/prime/bin/connect-refresh.sh +33 -0
  202. package/runtime/prime/bin/dashboard-data.sh +178 -0
  203. package/runtime/prime/bin/graph-batch.sh +79 -0
  204. package/runtime/prime/bin/graph-op.sh +1102 -0
  205. package/runtime/prime/bin/graph-wal.sh +229 -0
  206. package/runtime/prime/bin/graph.sh +223 -0
  207. package/runtime/prime/bin/handoff-pr-backfill.sh +86 -0
  208. package/runtime/prime/bin/handoff-run.sh +676 -0
  209. package/runtime/prime/bin/handoff-save-egregore.sh +224 -0
  210. package/runtime/prime/bin/index-handoff.sh +322 -0
  211. package/runtime/prime/bin/ingest-graph.sh +80 -0
  212. package/runtime/prime/bin/ingest-surface.html +495 -0
  213. package/runtime/prime/bin/ingest.py +1011 -0
  214. package/runtime/prime/bin/ingest.sh +279 -0
  215. package/runtime/prime/bin/ingest_graph.py +856 -0
  216. package/runtime/prime/bin/ingest_surface.py +544 -0
  217. package/runtime/prime/bin/lib/artifact-id.sh +46 -0
  218. package/runtime/prime/bin/lib/config.sh +116 -0
  219. package/runtime/prime/bin/lib/context.sh +621 -0
  220. package/runtime/prime/bin/lib/dashboard-artifact.sh +242 -0
  221. package/runtime/prime/bin/lib/ensure-develop.sh +183 -0
  222. package/runtime/prime/bin/lib/git-message.sh +37 -0
  223. package/runtime/prime/bin/lib/git-sync.sh +414 -0
  224. package/runtime/prime/bin/lib/greeting.sh +519 -0
  225. package/runtime/prime/bin/lib/hash.sh +13 -0
  226. package/runtime/prime/bin/lib/identity.sh +213 -0
  227. package/runtime/prime/bin/lib/metrics.sh +374 -0
  228. package/runtime/prime/bin/lib/noncode.sh +31 -0
  229. package/runtime/prime/bin/lib/permissions.sh +106 -0
  230. package/runtime/prime/bin/lib/time.sh +56 -0
  231. package/runtime/prime/bin/lib/worktree-links.sh +79 -0
  232. package/runtime/prime/bin/notify.sh +636 -0
  233. package/runtime/prime/bin/person.py +630 -0
  234. package/runtime/prime/bin/person.sh +448 -0
  235. package/runtime/prime/bin/pi-branch-policy.mjs +312 -0
  236. package/runtime/prime/bin/pi-product-workflows.mjs +394 -0
  237. package/runtime/prime/bin/prime-render-spec.mjs +147 -0
  238. package/runtime/prime/bin/prime-session-start.sh +24 -0
  239. package/runtime/prime/bin/publish-artifact.sh +271 -0
  240. package/runtime/prime/bin/publish-references.sh +144 -0
  241. package/runtime/prime/bin/repo-state.sh +96 -0
  242. package/runtime/prime/bin/search.sh +240 -0
  243. package/runtime/prime/bin/session-autosave.sh +215 -0
  244. package/runtime/prime/bin/session-log.sh +199 -0
  245. package/runtime/prime/bin/settings.sh +304 -0
  246. package/runtime/prime/bin/telemetry.sh +391 -0
  247. package/runtime/prime/bin/worktree-create.sh +128 -0
  248. package/runtime/prime/bin/worktree-remove.sh +50 -0
  249. package/runtime/prime/bin/worktree.sh +198 -0
  250. package/runtime/prime/manifest.json +181 -0
@@ -0,0 +1,279 @@
1
+ #!/usr/bin/env bash
2
+ set -euo pipefail
3
+
4
+ # Org-scoped intake plane. Shared manifests live in memory/; normalized bodies
5
+ # stay in this checkout's gitignored cache; qmd uses a separate per-org index.
6
+
7
+ ROOT="$(cd "$(dirname "$0")/.." && pwd)"
8
+ export NODE_NO_WARNINGS=1
9
+ PY="$ROOT/bin/ingest.py"
10
+ SURFACE="$ROOT/bin/ingest_surface.py"
11
+ SLUG="$(jq -r '.slug // "egregore"' "$ROOT/egregore.json")"
12
+ INDEX="${SLUG}-ingest"
13
+ COLLECTION="${SLUG}-ingest"
14
+ INGEST_ROOT="${EGREGORE_INGEST_ROOT:-$ROOT/.egregore/ingest}"
15
+ INGEST_META_ROOT="${EGREGORE_INGEST_META_ROOT:-$ROOT/memory/ingest}"
16
+ QMD_VERSION="2.5.3"
17
+ GRAPH_PROJECTOR="${EGREGORE_INGEST_GRAPH_PROJECTOR:-$ROOT/bin/ingest-graph.sh}"
18
+
19
+ _qmd() {
20
+ if command -v qmd >/dev/null 2>&1; then
21
+ qmd --index "$INDEX" "$@"
22
+ else
23
+ npx -y "@tobilu/qmd@${QMD_VERSION}" --index "$INDEX" "$@"
24
+ fi
25
+ }
26
+
27
+ _ensure_index() {
28
+ mkdir -p "$INGEST_ROOT"
29
+ if ! _qmd collection list 2>/dev/null | grep -q "^${COLLECTION} "; then
30
+ _qmd collection add "$INGEST_ROOT" --name "$COLLECTION" >/dev/null
31
+ fi
32
+ _qmd update >/dev/null
33
+ }
34
+
35
+ _graph_sync() {
36
+ local source="${1:-}" manifest result status
37
+ local total=0 succeeded=0 failed=0 stored=0 queries=0
38
+ local manifests=()
39
+ if [ -n "$source" ]; then
40
+ manifests+=("$INGEST_META_ROOT/sources/$source/manifest.json")
41
+ else
42
+ while IFS= read -r manifest; do manifests+=("$manifest"); done < <(
43
+ find "$INGEST_META_ROOT/sources" "$INGEST_META_ROOT/knowledge" \
44
+ -type f -name '*.json' 2>/dev/null | sort
45
+ )
46
+ fi
47
+ for manifest in "${manifests[@]}"; do
48
+ [ -f "$manifest" ] || continue
49
+ total=$((total + 1))
50
+ if result="$(bash "$GRAPH_PROJECTOR" apply "$manifest")"; then
51
+ status="$(printf '%s' "$result" | jq -r '.status')"
52
+ queries=$((queries + $(printf '%s' "$result" | jq -r '.queries // 0')))
53
+ if [ "$status" = "stored" ]; then stored=$((stored + 1)); else succeeded=$((succeeded + 1)); fi
54
+ else
55
+ failed=$((failed + 1))
56
+ fi
57
+ done
58
+ if [ "$failed" -gt 0 ]; then
59
+ jq -cn --argjson manifests "$total" --argjson succeeded "$succeeded" --argjson stored "$stored" --argjson failed "$failed" --argjson queries "$queries" \
60
+ '{status:"partial",manifests:$manifests,succeeded:$succeeded,stored:$stored,failed:$failed,queries:$queries,replayable:true}'
61
+ return 1
62
+ fi
63
+ if [ "$total" -eq 0 ]; then
64
+ printf '%s\n' '{"status":"nothing-to-project","manifests":0,"failed":0,"queries":0,"replayable":true}'
65
+ elif [ "$stored" -eq "$total" ]; then
66
+ jq -cn --argjson manifests "$total" --argjson queries "$queries" \
67
+ '{status:"stored-local",manifests:$manifests,failed:0,queries:$queries,replayable:true}'
68
+ else
69
+ jq -cn --argjson manifests "$total" --argjson queries "$queries" \
70
+ '{status:"synced",manifests:$manifests,failed:0,queries:$queries,replayable:true}'
71
+ fi
72
+ }
73
+
74
+ _journal() {
75
+ local source="$1" phase="$2" detail="${3:-}"
76
+ [ -n "$detail" ] || detail='{}'
77
+ python3 "$PY" journal --source "$source" --phase "$phase" --detail "$detail"
78
+ }
79
+
80
+ _journal_clear() {
81
+ python3 "$PY" journal --source "$1" --clear
82
+ }
83
+
84
+ _notify_receipt() {
85
+ local url="$1" token="$2" payload="$3"
86
+ [ -z "$url" ] && return 0
87
+ python3 - "$url" "$token" "$payload" <<'PY' >/dev/null 2>&1 || true
88
+ import sys, urllib.request
89
+ body = sys.argv[3].encode()
90
+ request = urllib.request.Request(
91
+ sys.argv[1] + "/api/result",
92
+ data=body,
93
+ method="POST",
94
+ headers={"Content-Type": "application/json", "X-Egregore-Token": sys.argv[2]},
95
+ )
96
+ urllib.request.urlopen(request, timeout=5).read()
97
+ PY
98
+ }
99
+
100
+ cmd_add() {
101
+ local source="" summary graph final qmd_status
102
+ local args=("$@")
103
+ local i
104
+ for ((i=0; i<${#args[@]}; i++)); do
105
+ if [ "${args[$i]}" = "--source" ] && [ $((i+1)) -lt ${#args[@]} ]; then source="${args[$((i+1))]}"; fi
106
+ done
107
+ summary="$(python3 "$PY" add "$@")"
108
+ _journal "$source" "normalized" "$(printf '%s' "$summary" | jq -c '{ingested,unchanged,metadata_updated,skipped,pruned}')"
109
+ if ! _ensure_index; then
110
+ qmd_status='{"status":"failed"}'
111
+ _journal "$source" "index_failed" "$qmd_status"
112
+ printf '%s\n' "$summary" | jq --argjson qmd "$qmd_status" '. + {status:"failed",qmd:$qmd,graph:{status:"not-attempted"}}'
113
+ return 1
114
+ fi
115
+ qmd_status='{"status":"indexed"}'
116
+ if graph="$(_graph_sync "$source")"; then :; else :; fi
117
+ if [ "$(printf '%s' "$summary" | jq -r .skipped)" -gt 0 ]; then
118
+ _journal "$source" "extraction_attention" "$(printf '%s' "$summary" | jq -c '{skipped}')"
119
+ final="$(printf '%s' "$summary" | jq --argjson qmd "$qmd_status" --argjson graph "$graph" '. + {status:"attention",qmd:$qmd,graph:$graph}')"
120
+ elif [ "$(printf '%s' "$graph" | jq -r .status)" = "partial" ]; then
121
+ _journal "$source" "graph_pending" "$graph"
122
+ final="$(printf '%s' "$summary" | jq --argjson qmd "$qmd_status" --argjson graph "$graph" '. + {status:"attention",qmd:$qmd,graph:$graph}')"
123
+ else
124
+ _journal_clear "$source"
125
+ final="$(printf '%s' "$summary" | jq --argjson qmd "$qmd_status" --argjson graph "$graph" '. + {status:"complete",qmd:$qmd,graph:$graph}')"
126
+ fi
127
+ printf '%s\n' "$final"
128
+ }
129
+
130
+ cmd_add_selection() {
131
+ local manifest="${1:?usage: bin/ingest.sh add-selection MANIFEST}"
132
+ local source receipt_url receipt_token summary graph qmd_status outcome final message contract
133
+ contract="$(python3 - "$manifest" <<'PY'
134
+ import json, sys
135
+ value = json.load(open(sys.argv[1], encoding="utf-8"))
136
+ print(json.dumps({"source": value["source"]["id"], "url": value.get("receipt", {}).get("url", ""), "token": value.get("receipt", {}).get("token", "")}))
137
+ PY
138
+ )"
139
+ source="$(printf '%s' "$contract" | jq -r .source)"
140
+ receipt_url="$(printf '%s' "$contract" | jq -r .url)"
141
+ receipt_token="$(printf '%s' "$contract" | jq -r .token)"
142
+ if ! summary="$(python3 "$PY" add-selection "$manifest")"; then
143
+ final="$(jq -cn --arg source "$source" '{status:"failed",outcome:"normalization failed",source:$source,message:"The selection failed validation or extraction. Its staging directory was retained for diagnosis."}')"
144
+ _notify_receipt "$receipt_url" "$receipt_token" "$final"
145
+ return 2
146
+ fi
147
+ _journal "$source" "normalized" "$(printf '%s' "$summary" | jq -c '{ingested,unchanged,metadata_updated,skipped,pruned}')"
148
+ if _ensure_index; then
149
+ qmd_status='{"status":"indexed"}'
150
+ else
151
+ qmd_status='{"status":"failed"}'
152
+ _journal "$source" "index_failed" "$qmd_status"
153
+ fi
154
+ if [ "$(printf '%s' "$qmd_status" | jq -r .status)" = "indexed" ]; then
155
+ if graph="$(_graph_sync "$source")"; then :; else :; fi
156
+ else
157
+ graph='{"status":"not-attempted","batches":0,"failed":0}'
158
+ fi
159
+ if [ "$(printf '%s' "$qmd_status" | jq -r .status)" != "indexed" ]; then
160
+ outcome="index failed"
161
+ message="The normalized source was retained, but QMD did not finish indexing it. Run bin/ingest.sh reindex to repair it."
162
+ final="$(printf '%s' "$summary" | jq --argjson qmd "$qmd_status" --argjson graph "$graph" --arg outcome "$outcome" --arg message "$message" '. + {status:"failed",outcome:$outcome,message:$message,qmd:$qmd,graph:$graph}')"
163
+ elif [ "$(printf '%s' "$summary" | jq -r '.skipped')" -gt 0 ]; then
164
+ outcome="indexed with skipped files"
165
+ message="Searchable files were indexed, but one or more files still need a compatible extractor. Their staging bytes were retained."
166
+ _journal "$source" "extraction_attention" "$(printf '%s' "$summary" | jq -c '{skipped,selection_path}')"
167
+ final="$(printf '%s' "$summary" | jq --argjson qmd "$qmd_status" --argjson graph "$graph" --arg outcome "$outcome" --arg message "$message" '. + {status:"attention",outcome:$outcome,message:$message,qmd:$qmd,graph:$graph}')"
168
+ elif [ "$(printf '%s' "$graph" | jq -r .status)" = "partial" ]; then
169
+ outcome="indexed · graph pending"
170
+ message="The source is searchable now. Graph projection was incomplete and is recorded for retry."
171
+ _journal "$source" "graph_pending" "$graph"
172
+ final="$(printf '%s' "$summary" | jq --argjson qmd "$qmd_status" --argjson graph "$graph" --arg outcome "$outcome" --arg message "$message" '. + {status:"attention",outcome:$outcome,message:$message,qmd:$qmd,graph:$graph}')"
173
+ else
174
+ outcome="indexed · org-scoped · unverified"
175
+ message="The files were validated, normalized, and added to this organization’s retrieval index."
176
+ _journal_clear "$source"
177
+ final="$(printf '%s' "$summary" | jq --argjson qmd "$qmd_status" --argjson graph "$graph" --arg outcome "$outcome" --arg message "$message" '. + {status:"complete",outcome:$outcome,message:$message,qmd:$qmd,graph:$graph}')"
178
+ fi
179
+ _notify_receipt "$receipt_url" "$receipt_token" "$final"
180
+ printf '%s\n' "$final"
181
+ }
182
+
183
+ cmd_search() {
184
+ local query="${1:?usage: bin/ingest.sh search \"query\" [--source id] [--boundary key=value] [-n N]}"
185
+ shift
186
+ local limit=8 raw filtered filter_args=() qmd_n=200
187
+ while [ $# -gt 0 ]; do
188
+ case "$1" in
189
+ -n) limit="$2"; shift 2 ;;
190
+ --source) filter_args+=(--source "$2"); shift 2 ;;
191
+ --boundary) filter_args+=(--boundary "$2"); shift 2 ;;
192
+ *) echo "unknown search option: $1" >&2; exit 2 ;;
193
+ esac
194
+ done
195
+ _ensure_index
196
+ raw="$(_qmd search "$query" -c "$COLLECTION" -n "$qmd_n" --all --json 2>/dev/null || echo '[]')"
197
+ if [ ${#filter_args[@]} -gt 0 ]; then
198
+ filtered="$(printf '%s' "$raw" | python3 "$PY" filter-results "${filter_args[@]}" --limit "$limit")"
199
+ else
200
+ filtered="$(printf '%s' "$raw" | python3 "$PY" filter-results --limit "$limit")"
201
+ fi
202
+ printf '%s' "$filtered" | jq -r --arg org "$SLUG" '
203
+ "⌕ ingest · keyword · \(length) hit\(if length == 1 then "" else "s" end) · org=" + $org,
204
+ (.[] | "\n### " + (.title // .file) + "\n" + .file + "\n\n" + (.snippet // ""))'
205
+ }
206
+
207
+ cmd_select() {
208
+ # Stitch the Google sign-in into the picker itself: when the shim ships and
209
+ # no account is connected yet, pre-start the OAuth listener and hand its
210
+ # consent URL to the surface — clicking Google then continues the SAME tab
211
+ # into sign-in instead of bouncing through the terminal. Already connected:
212
+ # pass the account so the page says so honestly. Everything degrades to the
213
+ # terminal-guided flow when the URL isn't ready in time.
214
+ local auth_urls="{}" accounts="{}" auth_pid="" auth_log="" result status=0
215
+ if [ -x "$ROOT/bin/connector-google.sh" ]; then
216
+ local active_account
217
+ active_account="$(jq -r '.google_account // empty' "$ROOT/.egregore-state.json" 2>/dev/null)"
218
+ if [ -n "$active_account" ]; then
219
+ accounts="$(jq -cn --arg a "$active_account" '{google: $a}')"
220
+ else
221
+ auth_log="$(mktemp)"
222
+ bash "$ROOT/bin/connector-google.sh" auth --print-url > "$auth_log" 2>/dev/null &
223
+ auth_pid=$!
224
+ local waited=0 url=""
225
+ while [ "$waited" -lt 15 ]; do
226
+ url="$(head -1 "$auth_log" 2>/dev/null | jq -r '.auth_url // empty' 2>/dev/null)"
227
+ [ -n "$url" ] && break
228
+ sleep 1; waited=$((waited + 1))
229
+ done
230
+ if [ -n "$url" ]; then
231
+ auth_urls="$(jq -cn --arg u "$url" '{google: $u}')"
232
+ fi
233
+ fi
234
+ fi
235
+ result="$(EGREGORE_CONNECTOR_AUTH_URLS="$auth_urls" EGREGORE_CONNECTOR_ACCOUNTS="$accounts" python3 "$SURFACE" "$@")" || status=$?
236
+ if [ -n "$auth_pid" ]; then
237
+ if [ "$(printf '%s' "$result" | jq -r '.auth // empty' 2>/dev/null)" = "in-browser" ]; then
238
+ # The user is on Google's consent page in their tab; the listener
239
+ # finishes the token exchange. Wait for it and fold in the outcome.
240
+ if wait "$auth_pid" 2>/dev/null; then
241
+ result="$(printf '%s' "$result" | jq -c '. + {auth: "connected"}')"
242
+ else
243
+ result="$(printf '%s' "$result" | jq -c '. + {auth: "failed"}')"
244
+ fi
245
+ else
246
+ kill "$auth_pid" 2>/dev/null || true
247
+ wait "$auth_pid" 2>/dev/null || true
248
+ fi
249
+ fi
250
+ [ -n "$auth_log" ] && rm -f "$auth_log"
251
+ printf '%s\n' "$result"
252
+ return "$status"
253
+ }
254
+
255
+ case "${1:-}" in
256
+ select) shift; cmd_select "$@" ;;
257
+ add) shift; cmd_add "$@" ;;
258
+ add-selection) shift; cmd_add_selection "$@" ;;
259
+ register-extraction) shift; python3 "$PY" register-extraction "$@" ;;
260
+ search) shift; cmd_search "$@" ;;
261
+ reindex)
262
+ _ensure_index
263
+ if graph="$(_graph_sync "")"; then
264
+ find "$INGEST_ROOT/.state" -type f -name '*.json' -delete 2>/dev/null || true
265
+ fi
266
+ printf '%s\n' "$graph"
267
+ ;;
268
+ graph-sync) shift; _graph_sync "${1:-}" ;;
269
+ status) python3 "$PY" status; _qmd status 2>/dev/null || true ;;
270
+ *)
271
+ echo 'usage: bash bin/ingest.sh {select|add|add-selection|register-extraction|search|reindex|graph-sync|status}' >&2
272
+ echo ' select [--no-open] [--timeout SECONDS]' >&2
273
+ echo ' add PATH --source ID [--name NAME] [--kind TYPE] [--boundary key=value]... [--prune]' >&2
274
+ echo ' add-selection MANIFEST' >&2
275
+ echo ' register-extraction MANIFEST RELATIVE_PATH --extractor NAME < normalized.txt' >&2
276
+ echo ' search "QUERY" [--source ID] [--boundary key=value]... [-n N]' >&2
277
+ exit 2
278
+ ;;
279
+ esac