create-egregore 0.19.33 → 0.20.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/assets/egregore-launcher.js +118 -13
- package/bin/cli.js +19 -3
- package/lib/connect-runtime.js +4 -2
- package/lib/local.js +15 -1
- package/lib/prime-runtime.js +208 -0
- package/lib/setup.js +45 -3
- package/package.json +4 -3
- package/runtime/codex/.codex/skills/ingest-notion/SKILL.md +29 -0
- package/runtime/codex/.codex/skills/notion-connect/SKILL.md +29 -0
- package/runtime/codex/.codex/skills/teams-connect/SKILL.md +29 -0
- package/runtime/codex/.codex/spec-manifest.json +3 -3
- package/runtime/codex/AGENTS.md +11 -4
- package/runtime/codex/bin/activity-data.sh +4 -8
- package/runtime/codex/bin/attendant.sh +13 -0
- package/runtime/codex/bin/autosave.sh +27 -1
- package/runtime/codex/bin/codex-render-spec.mjs +6 -0
- package/runtime/codex/bin/codex-session-start.sh +3 -1
- package/runtime/codex/bin/graph-batch.sh +25 -6
- package/runtime/codex/bin/graph-op.sh +5 -4
- package/runtime/codex/bin/graph.sh +31 -5
- package/runtime/codex/bin/ingest.py +81 -5
- package/runtime/codex/bin/lib/context.sh +26 -1
- package/runtime/codex/bin/lib/greeting.sh +4 -1
- package/runtime/codex/bin/lib/worktree-links.sh +25 -0
- package/runtime/codex/manifest.json +7 -1
- package/runtime/pi/.codex/skills/ingest-notion/SKILL.md +29 -0
- package/runtime/pi/.codex/skills/notion-connect/SKILL.md +29 -0
- package/runtime/pi/.codex/skills/teams-connect/SKILL.md +29 -0
- package/runtime/pi/.codex/spec-manifest.json +3 -3
- package/runtime/pi/.pi/APPEND_SYSTEM.md +3 -2
- package/runtime/pi/.pi/extensions/egregore.ts +17 -6
- package/runtime/pi/.pi/spec-manifest.json +2 -2
- package/runtime/pi/AGENTS.md +11 -4
- package/runtime/pi/bin/activity-data.sh +4 -8
- package/runtime/pi/bin/attendant.sh +13 -0
- package/runtime/pi/bin/autosave.sh +27 -1
- package/runtime/pi/bin/codex-render-spec.mjs +6 -0
- package/runtime/pi/bin/codex-session-start.sh +3 -1
- package/runtime/pi/bin/graph-batch.sh +25 -6
- package/runtime/pi/bin/graph-op.sh +5 -4
- package/runtime/pi/bin/graph.sh +31 -5
- package/runtime/pi/bin/ingest.py +81 -5
- package/runtime/pi/bin/lib/context.sh +26 -1
- package/runtime/pi/bin/lib/greeting.sh +4 -1
- package/runtime/pi/bin/lib/worktree-links.sh +25 -0
- package/runtime/pi/bin/pi-branch-policy.mjs +138 -1
- package/runtime/pi/bin/pi-product-workflows.mjs +35 -7
- package/runtime/pi/manifest.json +7 -1
- package/runtime/prime/.claude/context/notification-consent.md +66 -0
- package/runtime/prime/.codex/config.toml +17 -0
- package/runtime/prime/.codex/hooks/branch-guard.js +461 -0
- package/runtime/prime/.codex/hooks/search-hint.js +67 -0
- package/runtime/prime/.codex/hooks.json +30 -0
- package/runtime/prime/.codex/skills/activity/SKILL.md +82 -0
- package/runtime/prime/.codex/skills/announce/SKILL.md +67 -0
- package/runtime/prime/.codex/skills/archive/SKILL.md +45 -0
- package/runtime/prime/.codex/skills/branch/SKILL.md +29 -0
- package/runtime/prime/.codex/skills/checkup/SKILL.md +45 -0
- package/runtime/prime/.codex/skills/commit/SKILL.md +29 -0
- package/runtime/prime/.codex/skills/contribute/SKILL.md +29 -0
- package/runtime/prime/.codex/skills/create-skill/SKILL.md +29 -0
- package/runtime/prime/.codex/skills/dark-mode/SKILL.md +29 -0
- package/runtime/prime/.codex/skills/dashboard/SKILL.md +59 -0
- package/runtime/prime/.codex/skills/deep-reflect/SKILL.md +109 -0
- package/runtime/prime/.codex/skills/delete-user/SKILL.md +29 -0
- package/runtime/prime/.codex/skills/emissary/SKILL.md +45 -0
- package/runtime/prime/.codex/skills/handoff/SKILL.md +166 -0
- package/runtime/prime/.codex/skills/harvest/QUESTION_PALETTE.md +76 -0
- package/runtime/prime/.codex/skills/harvest/SKILL.md +131 -0
- package/runtime/prime/.codex/skills/ingest/SKILL.md +29 -0
- package/runtime/prime/.codex/skills/ingest-notion/SKILL.md +29 -0
- package/runtime/prime/.codex/skills/ingest-user-interview/SKILL.md +45 -0
- package/runtime/prime/.codex/skills/invite/SKILL.md +44 -0
- package/runtime/prime/.codex/skills/issue/SKILL.md +45 -0
- package/runtime/prime/.codex/skills/me/SKILL.md +29 -0
- package/runtime/prime/.codex/skills/meeting/SKILL.md +45 -0
- package/runtime/prime/.codex/skills/note/SKILL.md +29 -0
- package/runtime/prime/.codex/skills/notion-connect/SKILL.md +29 -0
- package/runtime/prime/.codex/skills/onboarding/SKILL.md +45 -0
- package/runtime/prime/.codex/skills/pr/SKILL.md +29 -0
- package/runtime/prime/.codex/skills/pull/SKILL.md +29 -0
- package/runtime/prime/.codex/skills/push/SKILL.md +29 -0
- package/runtime/prime/.codex/skills/quest/SKILL.md +80 -0
- package/runtime/prime/.codex/skills/reflect/SKILL.md +45 -0
- package/runtime/prime/.codex/skills/review-pr/SKILL.md +45 -0
- package/runtime/prime/.codex/skills/save/SKILL.md +125 -0
- package/runtime/prime/.codex/skills/slack-connect/SKILL.md +29 -0
- package/runtime/prime/.codex/skills/summon/SKILL.md +45 -0
- package/runtime/prime/.codex/skills/sync-repos/SKILL.md +29 -0
- package/runtime/prime/.codex/skills/teams-connect/SKILL.md +29 -0
- package/runtime/prime/.codex/skills/telegram-connect/SKILL.md +29 -0
- package/runtime/prime/.codex/skills/telemetry/SKILL.md +29 -0
- package/runtime/prime/.codex/skills/test/SKILL.md +45 -0
- package/runtime/prime/.codex/skills/the-spiral/SKILL.md +84 -0
- package/runtime/prime/.codex/skills/tui-design/SKILL.md +45 -0
- package/runtime/prime/.codex/skills/tutorial/SKILL.md +45 -0
- package/runtime/prime/.codex/skills/update/SKILL.md +29 -0
- package/runtime/prime/.codex/skills/view/SKILL.md +156 -0
- package/runtime/prime/.codex/skills/view/agents/openai.yaml +4 -0
- package/runtime/prime/.codex/skills/view/assets/compose-scaffold.html +221 -0
- package/runtime/prime/.codex/skills/visual-explain/SKILL.md +45 -0
- package/runtime/prime/.codex/skills/wrap/SKILL.md +58 -0
- package/runtime/prime/.codex/spec-manifest.json +132 -0
- package/runtime/prime/.prime/agent/APPEND_SYSTEM.md +393 -0
- package/runtime/prime/.prime/agent/extensions/egregore.ts +460 -0
- package/runtime/prime/.prime/agent/settings.json +4 -0
- package/runtime/prime/.prime/agent/skills/egregore/SKILL.md +34 -0
- package/runtime/prime/.prime/agent/skills/egregore/pyproject.toml +13 -0
- package/runtime/prime/.prime/agent/skills/egregore/src/egregore/__init__.py +156 -0
- package/runtime/prime/.prime/agent/spec-manifest.json +12 -0
- package/runtime/prime/AGENTS.md +489 -0
- package/runtime/prime/bin/activity-data.sh +238 -0
- package/runtime/prime/bin/agent.sh +775 -0
- package/runtime/prime/bin/attendant.sh +707 -0
- package/runtime/prime/bin/autosave.sh +112 -0
- package/runtime/prime/bin/capture-reconcile.sh +69 -0
- package/runtime/prime/bin/capture-run.sh +341 -0
- package/runtime/prime/bin/codex-install-skills.sh +78 -0
- package/runtime/prime/bin/codex-render-spec.mjs +440 -0
- package/runtime/prime/bin/codex-session-start.sh +265 -0
- package/runtime/prime/bin/codex-skill-render.mjs +347 -0
- package/runtime/prime/bin/codex-sync-skills.sh +232 -0
- package/runtime/prime/bin/connect-refresh.sh +33 -0
- package/runtime/prime/bin/dashboard-data.sh +178 -0
- package/runtime/prime/bin/graph-batch.sh +79 -0
- package/runtime/prime/bin/graph-op.sh +1102 -0
- package/runtime/prime/bin/graph-wal.sh +229 -0
- package/runtime/prime/bin/graph.sh +223 -0
- package/runtime/prime/bin/handoff-pr-backfill.sh +86 -0
- package/runtime/prime/bin/handoff-run.sh +671 -0
- package/runtime/prime/bin/handoff-save-egregore.sh +212 -0
- package/runtime/prime/bin/index-handoff.sh +322 -0
- package/runtime/prime/bin/ingest-graph.sh +80 -0
- package/runtime/prime/bin/ingest-surface.html +495 -0
- package/runtime/prime/bin/ingest.py +756 -0
- package/runtime/prime/bin/ingest.sh +279 -0
- package/runtime/prime/bin/ingest_graph.py +856 -0
- package/runtime/prime/bin/ingest_surface.py +544 -0
- package/runtime/prime/bin/lib/artifact-id.sh +46 -0
- package/runtime/prime/bin/lib/config.sh +116 -0
- package/runtime/prime/bin/lib/context.sh +621 -0
- package/runtime/prime/bin/lib/dashboard-artifact.sh +242 -0
- package/runtime/prime/bin/lib/ensure-develop.sh +183 -0
- package/runtime/prime/bin/lib/git-sync.sh +406 -0
- package/runtime/prime/bin/lib/greeting.sh +519 -0
- package/runtime/prime/bin/lib/hash.sh +13 -0
- package/runtime/prime/bin/lib/identity.sh +213 -0
- package/runtime/prime/bin/lib/metrics.sh +374 -0
- package/runtime/prime/bin/lib/noncode.sh +31 -0
- package/runtime/prime/bin/lib/permissions.sh +106 -0
- package/runtime/prime/bin/lib/time.sh +56 -0
- package/runtime/prime/bin/lib/worktree-links.sh +79 -0
- package/runtime/prime/bin/notify.sh +636 -0
- package/runtime/prime/bin/person.py +630 -0
- package/runtime/prime/bin/person.sh +448 -0
- package/runtime/prime/bin/pi-branch-policy.mjs +312 -0
- package/runtime/prime/bin/pi-product-workflows.mjs +394 -0
- package/runtime/prime/bin/prime-render-spec.mjs +123 -0
- package/runtime/prime/bin/prime-session-start.sh +24 -0
- package/runtime/prime/bin/publish-artifact.sh +271 -0
- package/runtime/prime/bin/publish-references.sh +144 -0
- package/runtime/prime/bin/repo-state.sh +96 -0
- package/runtime/prime/bin/search.sh +240 -0
- package/runtime/prime/bin/session-autosave.sh +209 -0
- package/runtime/prime/bin/session-log.sh +199 -0
- package/runtime/prime/bin/settings.sh +304 -0
- package/runtime/prime/bin/telemetry.sh +391 -0
- package/runtime/prime/bin/worktree-create.sh +128 -0
- package/runtime/prime/bin/worktree-remove.sh +50 -0
- package/runtime/prime/bin/worktree.sh +198 -0
- package/runtime/prime/manifest.json +178 -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
|