create-egregore 0.20.2 → 0.21.0-runtime-mvp.2

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 (706) hide show
  1. package/assets/egregore-launcher.js +1013 -16
  2. package/bin/cli.js +11 -0
  3. package/lib/claude-runtime.js +192 -0
  4. package/lib/local.js +38 -31
  5. package/lib/pi-runtime.js +1 -0
  6. package/lib/prime-runtime.js +1 -0
  7. package/lib/runtime-identity.js +146 -0
  8. package/lib/setup.js +116 -17
  9. package/package.json +10 -6
  10. package/runtime/claude/.claude/context/commit-format.md +110 -0
  11. package/runtime/claude/.claude/context/git-language.md +46 -0
  12. package/runtime/claude/.claude/context/notification-consent.md +66 -0
  13. package/runtime/claude/.claude/context/pr-format.md +67 -0
  14. package/runtime/claude/.claude/context/telemetry.md +133 -0
  15. package/runtime/claude/.claude/hooks/boundary-check.sh +333 -0
  16. package/runtime/claude/.claude/hooks/branch-guard.sh +231 -0
  17. package/runtime/claude/.claude/hooks/card-context.sh +38 -0
  18. package/runtime/claude/.claude/hooks/emissary-detect.sh +53 -0
  19. package/runtime/claude/.claude/hooks/memory-refresh.sh +67 -0
  20. package/runtime/claude/.claude/hooks/onboarding-guard.sh +86 -0
  21. package/runtime/claude/.claude/hooks/retrieval-context.sh +43 -0
  22. package/runtime/claude/.claude/rules/voice-bedrock.md +73 -0
  23. package/runtime/claude/.claude/settings.json +131 -0
  24. package/runtime/claude/.claude/skills/activity/SKILL.md +68 -0
  25. package/runtime/claude/.claude/skills/announce/SKILL.md +54 -0
  26. package/runtime/claude/.claude/skills/archive/SKILL.md +71 -0
  27. package/runtime/claude/.claude/skills/branch/SKILL.md +147 -0
  28. package/runtime/claude/.claude/skills/checkup/SKILL.md +159 -0
  29. package/runtime/claude/.claude/skills/commit/SKILL.md +103 -0
  30. package/runtime/claude/.claude/skills/contribute/SKILL.md +343 -0
  31. package/runtime/claude/.claude/skills/create-skill/SKILL.md +135 -0
  32. package/runtime/claude/.claude/skills/dark-mode/SKILL.md +410 -0
  33. package/runtime/claude/.claude/skills/dashboard/SKILL.md +43 -0
  34. package/runtime/claude/.claude/skills/deep-reflect/REPORT.md +140 -0
  35. package/runtime/claude/.claude/skills/deep-reflect/RESEARCH.md +132 -0
  36. package/runtime/claude/.claude/skills/deep-reflect/ROLES.md +104 -0
  37. package/runtime/claude/.claude/skills/deep-reflect/SKILL.md +170 -0
  38. package/runtime/claude/.claude/skills/delete-user/SKILL.md +150 -0
  39. package/runtime/claude/.claude/skills/emissary/SKILL.md +220 -0
  40. package/runtime/claude/.claude/skills/handoff/SKILL.md +124 -0
  41. package/runtime/claude/.claude/skills/harvest/AUDIT.md +546 -0
  42. package/runtime/claude/.claude/skills/harvest/FORMAT.md +436 -0
  43. package/runtime/claude/.claude/skills/harvest/PROCESS.md +395 -0
  44. package/runtime/claude/.claude/skills/harvest/QUESTION_PALETTE.md +76 -0
  45. package/runtime/claude/.claude/skills/harvest/SKILL.md +100 -0
  46. package/runtime/claude/.claude/skills/ingest/SKILL.md +112 -0
  47. package/runtime/claude/.claude/skills/ingest-corpus/SKILL.md +187 -0
  48. package/runtime/claude/.claude/skills/ingest-notion/SKILL.md +214 -0
  49. package/runtime/claude/.claude/skills/ingest-user-interview/SKILL.md +65 -0
  50. package/runtime/claude/.claude/skills/ingest-user-interview/references/analysis-contract.md +125 -0
  51. package/runtime/claude/.claude/skills/invite/SKILL.md +111 -0
  52. package/runtime/claude/.claude/skills/issue/SKILL.md +104 -0
  53. package/runtime/claude/.claude/skills/me/SKILL.md +81 -0
  54. package/runtime/claude/.claude/skills/meeting/SKILL.md +76 -0
  55. package/runtime/claude/.claude/skills/meeting/references/analysis-contract.md +102 -0
  56. package/runtime/claude/.claude/skills/note/SKILL.md +71 -0
  57. package/runtime/claude/.claude/skills/notion-connect/SKILL.md +124 -0
  58. package/runtime/claude/.claude/skills/onboarding/SKILL.md +159 -0
  59. package/runtime/claude/.claude/skills/pr/SKILL.md +85 -0
  60. package/runtime/claude/.claude/skills/pull/SKILL.md +79 -0
  61. package/runtime/claude/.claude/skills/push/SKILL.md +47 -0
  62. package/runtime/claude/.claude/skills/quest/SKILL.md +121 -0
  63. package/runtime/claude/.claude/skills/reflect/SKILL.md +69 -0
  64. package/runtime/claude/.claude/skills/review-pr/SKILL.md +276 -0
  65. package/runtime/claude/.claude/skills/save/SKILL.md +92 -0
  66. package/runtime/claude/.claude/skills/slack-connect/SKILL.md +148 -0
  67. package/runtime/claude/.claude/skills/summon/SKILL.md +240 -0
  68. package/runtime/claude/.claude/skills/sync-repos/SKILL.md +82 -0
  69. package/runtime/claude/.claude/skills/teams-connect/SKILL.md +216 -0
  70. package/runtime/claude/.claude/skills/telegram-connect/SKILL.md +110 -0
  71. package/runtime/claude/.claude/skills/telemetry/SKILL.md +117 -0
  72. package/runtime/claude/.claude/skills/test/SKILL.md +87 -0
  73. package/runtime/claude/.claude/skills/the-spiral/SKILL.md +492 -0
  74. package/runtime/claude/.claude/skills/tui-design/SKILL.md +188 -0
  75. package/runtime/claude/.claude/skills/tutorial/SKILL.md +100 -0
  76. package/runtime/claude/.claude/skills/update/SKILL.md +265 -0
  77. package/runtime/claude/.claude/skills/view/SKILL.md +393 -0
  78. package/runtime/claude/.claude/skills/view/compose-scaffold.html +221 -0
  79. package/runtime/claude/.claude/skills/visual-explain/SKILL.md +132 -0
  80. package/runtime/claude/.claude/skills/wrap/SKILL.md +98 -0
  81. package/runtime/claude/CLAUDE.md +447 -0
  82. package/runtime/claude/bin/activity-action.sh +92 -0
  83. package/runtime/claude/bin/activity-data.sh +17 -0
  84. package/runtime/claude/bin/agent.sh +783 -0
  85. package/runtime/claude/bin/artifact-register.sh +164 -0
  86. package/runtime/claude/bin/artifact-writeback.sh +53 -0
  87. package/runtime/claude/bin/artifacts.sh +288 -0
  88. package/runtime/claude/bin/attendant.sh +707 -0
  89. package/runtime/claude/bin/autosave.sh +112 -0
  90. package/runtime/claude/bin/boundary.sh +253 -0
  91. package/runtime/claude/bin/build-sealed-dataroom.mjs +722 -0
  92. package/runtime/claude/bin/capture-reconcile.sh +69 -0
  93. package/runtime/claude/bin/capture-run.sh +357 -0
  94. package/runtime/claude/bin/codex-install-skills.sh +78 -0
  95. package/runtime/claude/bin/codex-render-spec.mjs +462 -0
  96. package/runtime/claude/bin/codex-session-start.sh +275 -0
  97. package/runtime/claude/bin/codex-skill-render.mjs +349 -0
  98. package/runtime/claude/bin/codex-sync-skills.sh +237 -0
  99. package/runtime/claude/bin/connect-refresh.sh +33 -0
  100. package/runtime/claude/bin/contribute-guard.sh +79 -0
  101. package/runtime/claude/bin/corpus_map.py +806 -0
  102. package/runtime/claude/bin/corpus_survey.py +304 -0
  103. package/runtime/claude/bin/dashboard-data.sh +18 -0
  104. package/runtime/claude/bin/github-auth.sh +121 -0
  105. package/runtime/claude/bin/graph-batch.sh +86 -0
  106. package/runtime/claude/bin/graph-op.sh +1106 -0
  107. package/runtime/claude/bin/graph-projection.sh +54 -0
  108. package/runtime/claude/bin/graph-wal.sh +242 -0
  109. package/runtime/claude/bin/graph.sh +267 -0
  110. package/runtime/claude/bin/handoff-lifecycle-job.sh +146 -0
  111. package/runtime/claude/bin/handoff-lifecycle.sh +280 -0
  112. package/runtime/claude/bin/handoff-pr-backfill.sh +86 -0
  113. package/runtime/claude/bin/handoff-preview.sh +169 -0
  114. package/runtime/claude/bin/handoff-run.sh +692 -0
  115. package/runtime/claude/bin/handoff-save-egregore.sh +224 -0
  116. package/runtime/claude/bin/index-handoff.sh +322 -0
  117. package/runtime/claude/bin/ingest-graph.sh +86 -0
  118. package/runtime/claude/bin/ingest-item.sh +10 -0
  119. package/runtime/claude/bin/ingest-surface.html +495 -0
  120. package/runtime/claude/bin/ingest.py +1011 -0
  121. package/runtime/claude/bin/ingest.sh +308 -0
  122. package/runtime/claude/bin/ingest_graph.py +856 -0
  123. package/runtime/claude/bin/ingest_surface.py +544 -0
  124. package/runtime/claude/bin/invite.sh +6 -0
  125. package/runtime/claude/bin/issue.sh +10 -0
  126. package/runtime/claude/bin/knowledge.sh +10 -0
  127. package/runtime/claude/bin/lib/artifact-id.sh +46 -0
  128. package/runtime/claude/bin/lib/config.sh +136 -0
  129. package/runtime/claude/bin/lib/context.sh +642 -0
  130. package/runtime/claude/bin/lib/dashboard-artifact.sh +242 -0
  131. package/runtime/claude/bin/lib/ensure-develop.sh +183 -0
  132. package/runtime/claude/bin/lib/git-message.sh +37 -0
  133. package/runtime/claude/bin/lib/git-sync.sh +494 -0
  134. package/runtime/claude/bin/lib/greeting.sh +548 -0
  135. package/runtime/claude/bin/lib/handoff-meta.sh +97 -0
  136. package/runtime/claude/bin/lib/hash.sh +13 -0
  137. package/runtime/claude/bin/lib/identity.sh +213 -0
  138. package/runtime/claude/bin/lib/metrics.sh +374 -0
  139. package/runtime/claude/bin/lib/noncode.sh +31 -0
  140. package/runtime/claude/bin/lib/permissions.sh +106 -0
  141. package/runtime/claude/bin/lib/time.sh +56 -0
  142. package/runtime/claude/bin/lib/worktree-links.sh +85 -0
  143. package/runtime/claude/bin/node-run.sh +42 -0
  144. package/runtime/claude/bin/notification.sh +6 -0
  145. package/runtime/claude/bin/notify.sh +636 -0
  146. package/runtime/claude/bin/observe-context.sh +14 -0
  147. package/runtime/claude/bin/onboarding.sh +6 -0
  148. package/runtime/claude/bin/person.py +634 -0
  149. package/runtime/claude/bin/person.sh +481 -0
  150. package/runtime/claude/bin/pi-render-spec.mjs +140 -0
  151. package/runtime/claude/bin/post-update.sh +37 -0
  152. package/runtime/claude/bin/prime-render-spec.mjs +147 -0
  153. package/runtime/claude/bin/publish-artifact.sh +324 -0
  154. package/runtime/claude/bin/publish-references.sh +144 -0
  155. package/runtime/claude/bin/quest.sh +9 -0
  156. package/runtime/claude/bin/question.sh +8 -0
  157. package/runtime/claude/bin/repo-state.sh +96 -0
  158. package/runtime/claude/bin/research-ingest.sh +7 -0
  159. package/runtime/claude/bin/restore-owned-skills.sh +67 -0
  160. package/runtime/claude/bin/retrieval_eval.py +385 -0
  161. package/runtime/claude/bin/runtime-identity.sh +70 -0
  162. package/runtime/claude/bin/runtime-upgrade.sh +43 -0
  163. package/runtime/claude/bin/scroll.sh +9 -0
  164. package/runtime/claude/bin/search.sh +318 -0
  165. package/runtime/claude/bin/session-autosave.sh +220 -0
  166. package/runtime/claude/bin/session-log.sh +199 -0
  167. package/runtime/claude/bin/session-start.sh +696 -0
  168. package/runtime/claude/bin/settings.sh +532 -0
  169. package/runtime/claude/bin/startup-check.sh +136 -0
  170. package/runtime/claude/bin/statusline.sh +41 -0
  171. package/runtime/claude/bin/telemetry.sh +666 -0
  172. package/runtime/claude/bin/test-changes.sh +344 -0
  173. package/runtime/claude/bin/thread.sh +9 -0
  174. package/runtime/claude/bin/todo.sh +9 -0
  175. package/runtime/claude/bin/view-render.sh +126 -0
  176. package/runtime/claude/bin/worktree-create.sh +145 -0
  177. package/runtime/claude/bin/worktree-remove.sh +50 -0
  178. package/runtime/claude/bin/worktree.sh +198 -0
  179. package/runtime/claude/egregore_runtime/__init__.py +228 -0
  180. package/runtime/claude/egregore_runtime/adapters/__init__.py +5 -0
  181. package/runtime/claude/egregore_runtime/adapters/invitation.py +237 -0
  182. package/runtime/claude/egregore_runtime/adapters/notification.py +59 -0
  183. package/runtime/claude/egregore_runtime/adapters/qmd.py +1701 -0
  184. package/runtime/claude/egregore_runtime/adapters/qmd_cli.py +210 -0
  185. package/runtime/claude/egregore_runtime/adapters/qmd_embed_worker.py +59 -0
  186. package/runtime/claude/egregore_runtime/admin_gate.py +102 -0
  187. package/runtime/claude/egregore_runtime/artifacts.py +523 -0
  188. package/runtime/claude/egregore_runtime/contracts.py +499 -0
  189. package/runtime/claude/egregore_runtime/entitlements.py +85 -0
  190. package/runtime/claude/egregore_runtime/errors.py +10 -0
  191. package/runtime/claude/egregore_runtime/graph.py +356 -0
  192. package/runtime/claude/egregore_runtime/handoff_lookup.py +196 -0
  193. package/runtime/claude/egregore_runtime/harness_cli.py +1221 -0
  194. package/runtime/claude/egregore_runtime/identity.py +734 -0
  195. package/runtime/claude/egregore_runtime/identity_cli.py +91 -0
  196. package/runtime/claude/egregore_runtime/ingest.py +575 -0
  197. package/runtime/claude/egregore_runtime/ingest_cli.py +254 -0
  198. package/runtime/claude/egregore_runtime/ingest_index_cli.py +147 -0
  199. package/runtime/claude/egregore_runtime/invitation_cli.py +51 -0
  200. package/runtime/claude/egregore_runtime/invitations.py +116 -0
  201. package/runtime/claude/egregore_runtime/issue_cli.py +305 -0
  202. package/runtime/claude/egregore_runtime/issues.py +359 -0
  203. package/runtime/claude/egregore_runtime/knowledge.py +376 -0
  204. package/runtime/claude/egregore_runtime/knowledge_cli.py +173 -0
  205. package/runtime/claude/egregore_runtime/lifecycle.py +888 -0
  206. package/runtime/claude/egregore_runtime/lifecycle_cli.py +269 -0
  207. package/runtime/claude/egregore_runtime/notification_cli.py +125 -0
  208. package/runtime/claude/egregore_runtime/notifications.py +230 -0
  209. package/runtime/claude/egregore_runtime/observe.py +342 -0
  210. package/runtime/claude/egregore_runtime/onboarding.py +290 -0
  211. package/runtime/claude/egregore_runtime/onboarding_cli.py +110 -0
  212. package/runtime/claude/egregore_runtime/policy.py +144 -0
  213. package/runtime/claude/egregore_runtime/profile.py +193 -0
  214. package/runtime/claude/egregore_runtime/quest_cli.py +216 -0
  215. package/runtime/claude/egregore_runtime/question_cli.py +180 -0
  216. package/runtime/claude/egregore_runtime/questions.py +304 -0
  217. package/runtime/claude/egregore_runtime/quests.py +419 -0
  218. package/runtime/claude/egregore_runtime/readiness.py +379 -0
  219. package/runtime/claude/egregore_runtime/research_ingest.py +256 -0
  220. package/runtime/claude/egregore_runtime/research_ingest_cli.py +44 -0
  221. package/runtime/claude/egregore_runtime/runtime.py +464 -0
  222. package/runtime/claude/egregore_runtime/scroll_cli.py +185 -0
  223. package/runtime/claude/egregore_runtime/scrolls.py +726 -0
  224. package/runtime/claude/egregore_runtime/status.py +412 -0
  225. package/runtime/claude/egregore_runtime/status_cli.py +174 -0
  226. package/runtime/claude/egregore_runtime/sync.py +218 -0
  227. package/runtime/claude/egregore_runtime/teamsync.py +139 -0
  228. package/runtime/claude/egregore_runtime/telemetry.py +640 -0
  229. package/runtime/claude/egregore_runtime/thread_cli.py +173 -0
  230. package/runtime/claude/egregore_runtime/threads.py +517 -0
  231. package/runtime/claude/egregore_runtime/todo_cli.py +142 -0
  232. package/runtime/claude/egregore_runtime/todos.py +244 -0
  233. package/runtime/claude/egregore_runtime/upgrade.py +770 -0
  234. package/runtime/claude/egregore_runtime/upgrade_worker.py +53 -0
  235. package/runtime/claude/egregore_runtime/writeback.py +391 -0
  236. package/runtime/claude/egregore_runtime/writeback_cli.py +114 -0
  237. package/runtime/claude/manifest.json +284 -0
  238. package/runtime/codex/.codex/hooks/search-hint.js +21 -52
  239. package/runtime/codex/.codex/hooks.json +3 -3
  240. package/runtime/codex/.codex/skills/activity/SKILL.md +23 -66
  241. package/runtime/codex/.codex/skills/announce/SKILL.md +27 -50
  242. package/runtime/codex/.codex/skills/archive/SKILL.md +21 -36
  243. package/runtime/codex/.codex/skills/checkup/SKILL.md +77 -36
  244. package/runtime/codex/.codex/skills/dark-mode/SKILL.md +1 -1
  245. package/runtime/codex/.codex/skills/dashboard/SKILL.md +17 -47
  246. package/runtime/codex/.codex/skills/handoff/SKILL.md +84 -133
  247. package/runtime/codex/.codex/skills/harvest/SKILL.md +32 -117
  248. package/runtime/codex/.codex/skills/ingest/SKILL.md +47 -25
  249. package/runtime/codex/.codex/skills/ingest-user-interview/SKILL.md +18 -36
  250. package/runtime/codex/.codex/skills/ingest-user-interview/references/analysis-contract.md +42 -0
  251. package/runtime/codex/.codex/skills/invite/SKILL.md +21 -35
  252. package/runtime/codex/.codex/skills/issue/SKILL.md +60 -41
  253. package/runtime/codex/.codex/skills/me/SKILL.md +1 -1
  254. package/runtime/codex/.codex/skills/meeting/SKILL.md +16 -36
  255. package/runtime/codex/.codex/skills/meeting/references/analysis-contract.md +48 -0
  256. package/runtime/codex/.codex/skills/note/SKILL.md +30 -25
  257. package/runtime/codex/.codex/skills/onboarding/SKILL.md +36 -41
  258. package/runtime/codex/.codex/skills/pull/SKILL.md +1 -1
  259. package/runtime/codex/.codex/skills/quest/SKILL.md +27 -66
  260. package/runtime/codex/.codex/skills/reflect/SKILL.md +22 -36
  261. package/runtime/codex/.codex/skills/save/SKILL.md +2 -2
  262. package/runtime/codex/.codex/skills/telemetry/SKILL.md +1 -1
  263. package/runtime/codex/.codex/skills/test/SKILL.md +1 -1
  264. package/runtime/codex/.codex/skills/tutorial/SKILL.md +40 -41
  265. package/runtime/codex/.codex/skills/view/SKILL.md +115 -111
  266. package/runtime/codex/.codex/skills/wrap/SKILL.md +45 -41
  267. package/runtime/codex/.codex/spec-manifest.json +9 -9
  268. package/runtime/codex/AGENTS.md +62 -58
  269. package/runtime/codex/bin/activity-action.sh +92 -0
  270. package/runtime/codex/bin/activity-data.sh +12 -233
  271. package/runtime/codex/bin/agent.sh +84 -100
  272. package/runtime/codex/bin/artifact-register.sh +164 -0
  273. package/runtime/codex/bin/artifact-writeback.sh +53 -0
  274. package/runtime/codex/bin/artifacts.sh +288 -0
  275. package/runtime/codex/bin/build-sealed-dataroom.mjs +722 -0
  276. package/runtime/codex/bin/capture-run.sh +18 -2
  277. package/runtime/codex/bin/codex-render-spec.mjs +41 -16
  278. package/runtime/codex/bin/codex-session-start.sh +14 -4
  279. package/runtime/codex/bin/codex-skill-render.mjs +9 -7
  280. package/runtime/codex/bin/corpus_map.py +806 -0
  281. package/runtime/codex/bin/corpus_survey.py +304 -0
  282. package/runtime/codex/bin/dashboard-data.sh +11 -171
  283. package/runtime/codex/bin/github-auth.sh +121 -0
  284. package/runtime/codex/bin/graph-batch.sh +7 -0
  285. package/runtime/codex/bin/graph-op.sh +4 -0
  286. package/runtime/codex/bin/graph-projection.sh +54 -0
  287. package/runtime/codex/bin/graph-wal.sh +13 -0
  288. package/runtime/codex/bin/graph.sh +44 -0
  289. package/runtime/codex/bin/handoff-lifecycle-job.sh +146 -0
  290. package/runtime/codex/bin/handoff-lifecycle.sh +280 -0
  291. package/runtime/codex/bin/handoff-preview.sh +169 -0
  292. package/runtime/codex/bin/handoff-run.sh +42 -26
  293. package/runtime/codex/bin/ingest-graph.sh +6 -0
  294. package/runtime/codex/bin/ingest-item.sh +10 -0
  295. package/runtime/codex/bin/ingest.sh +59 -30
  296. package/runtime/codex/bin/invite.sh +6 -0
  297. package/runtime/codex/bin/issue.sh +10 -0
  298. package/runtime/codex/bin/knowledge.sh +10 -0
  299. package/runtime/codex/bin/lib/config.sh +20 -0
  300. package/runtime/codex/bin/lib/context.sh +46 -25
  301. package/runtime/codex/bin/lib/git-sync.sh +70 -6
  302. package/runtime/codex/bin/lib/greeting.sh +34 -5
  303. package/runtime/codex/bin/lib/handoff-meta.sh +97 -0
  304. package/runtime/codex/bin/lib/worktree-links.sh +6 -0
  305. package/runtime/codex/bin/node-run.sh +42 -0
  306. package/runtime/codex/bin/notification.sh +6 -0
  307. package/runtime/codex/bin/observe-context.sh +14 -0
  308. package/runtime/codex/bin/onboarding.sh +6 -0
  309. package/runtime/codex/bin/person.py +4 -0
  310. package/runtime/codex/bin/person.sh +43 -10
  311. package/runtime/codex/bin/pi-render-spec.mjs +140 -0
  312. package/runtime/codex/bin/post-update.sh +37 -0
  313. package/runtime/codex/bin/prime-render-spec.mjs +147 -0
  314. package/runtime/codex/bin/publish-artifact.sh +55 -2
  315. package/runtime/codex/bin/quest.sh +9 -0
  316. package/runtime/codex/bin/question.sh +8 -0
  317. package/runtime/codex/bin/research-ingest.sh +7 -0
  318. package/runtime/codex/bin/restore-owned-skills.sh +67 -0
  319. package/runtime/codex/bin/retrieval_eval.py +385 -0
  320. package/runtime/codex/bin/runtime-identity.sh +70 -0
  321. package/runtime/codex/bin/runtime-upgrade.sh +43 -0
  322. package/runtime/codex/bin/scroll.sh +9 -0
  323. package/runtime/codex/bin/search.sh +231 -195
  324. package/runtime/codex/bin/settings.sh +174 -5
  325. package/runtime/codex/bin/startup-check.sh +136 -0
  326. package/runtime/codex/bin/telemetry.sh +522 -247
  327. package/runtime/codex/bin/test-changes.sh +344 -0
  328. package/runtime/codex/bin/thread.sh +9 -0
  329. package/runtime/codex/bin/todo.sh +9 -0
  330. package/runtime/codex/bin/view-render.sh +126 -0
  331. package/runtime/codex/bin/worktree-create.sh +19 -5
  332. package/runtime/codex/egregore_runtime/__init__.py +228 -0
  333. package/runtime/codex/egregore_runtime/adapters/__init__.py +5 -0
  334. package/runtime/codex/egregore_runtime/adapters/invitation.py +237 -0
  335. package/runtime/codex/egregore_runtime/adapters/notification.py +59 -0
  336. package/runtime/codex/egregore_runtime/adapters/qmd.py +1701 -0
  337. package/runtime/codex/egregore_runtime/adapters/qmd_cli.py +210 -0
  338. package/runtime/codex/egregore_runtime/adapters/qmd_embed_worker.py +59 -0
  339. package/runtime/codex/egregore_runtime/admin_gate.py +102 -0
  340. package/runtime/codex/egregore_runtime/artifacts.py +523 -0
  341. package/runtime/codex/egregore_runtime/contracts.py +499 -0
  342. package/runtime/codex/egregore_runtime/entitlements.py +85 -0
  343. package/runtime/codex/egregore_runtime/errors.py +10 -0
  344. package/runtime/codex/egregore_runtime/graph.py +356 -0
  345. package/runtime/codex/egregore_runtime/handoff_lookup.py +196 -0
  346. package/runtime/codex/egregore_runtime/harness_cli.py +1221 -0
  347. package/runtime/codex/egregore_runtime/identity.py +734 -0
  348. package/runtime/codex/egregore_runtime/identity_cli.py +91 -0
  349. package/runtime/codex/egregore_runtime/ingest.py +575 -0
  350. package/runtime/codex/egregore_runtime/ingest_cli.py +254 -0
  351. package/runtime/codex/egregore_runtime/ingest_index_cli.py +147 -0
  352. package/runtime/codex/egregore_runtime/invitation_cli.py +51 -0
  353. package/runtime/codex/egregore_runtime/invitations.py +116 -0
  354. package/runtime/codex/egregore_runtime/issue_cli.py +305 -0
  355. package/runtime/codex/egregore_runtime/issues.py +359 -0
  356. package/runtime/codex/egregore_runtime/knowledge.py +376 -0
  357. package/runtime/codex/egregore_runtime/knowledge_cli.py +173 -0
  358. package/runtime/codex/egregore_runtime/lifecycle.py +888 -0
  359. package/runtime/codex/egregore_runtime/lifecycle_cli.py +269 -0
  360. package/runtime/codex/egregore_runtime/notification_cli.py +125 -0
  361. package/runtime/codex/egregore_runtime/notifications.py +230 -0
  362. package/runtime/codex/egregore_runtime/observe.py +342 -0
  363. package/runtime/codex/egregore_runtime/onboarding.py +290 -0
  364. package/runtime/codex/egregore_runtime/onboarding_cli.py +110 -0
  365. package/runtime/codex/egregore_runtime/policy.py +144 -0
  366. package/runtime/codex/egregore_runtime/profile.py +193 -0
  367. package/runtime/codex/egregore_runtime/quest_cli.py +216 -0
  368. package/runtime/codex/egregore_runtime/question_cli.py +180 -0
  369. package/runtime/codex/egregore_runtime/questions.py +304 -0
  370. package/runtime/codex/egregore_runtime/quests.py +419 -0
  371. package/runtime/codex/egregore_runtime/readiness.py +379 -0
  372. package/runtime/codex/egregore_runtime/research_ingest.py +256 -0
  373. package/runtime/codex/egregore_runtime/research_ingest_cli.py +44 -0
  374. package/runtime/codex/egregore_runtime/runtime.py +464 -0
  375. package/runtime/codex/egregore_runtime/scroll_cli.py +185 -0
  376. package/runtime/codex/egregore_runtime/scrolls.py +726 -0
  377. package/runtime/codex/egregore_runtime/status.py +412 -0
  378. package/runtime/codex/egregore_runtime/status_cli.py +174 -0
  379. package/runtime/codex/egregore_runtime/sync.py +218 -0
  380. package/runtime/codex/egregore_runtime/teamsync.py +139 -0
  381. package/runtime/codex/egregore_runtime/telemetry.py +640 -0
  382. package/runtime/codex/egregore_runtime/thread_cli.py +173 -0
  383. package/runtime/codex/egregore_runtime/threads.py +517 -0
  384. package/runtime/codex/egregore_runtime/todo_cli.py +142 -0
  385. package/runtime/codex/egregore_runtime/todos.py +244 -0
  386. package/runtime/codex/egregore_runtime/upgrade.py +770 -0
  387. package/runtime/codex/egregore_runtime/upgrade_worker.py +53 -0
  388. package/runtime/codex/egregore_runtime/writeback.py +391 -0
  389. package/runtime/codex/egregore_runtime/writeback_cli.py +114 -0
  390. package/runtime/codex/manifest.json +98 -1
  391. package/runtime/pi/.codex/hooks/search-hint.js +21 -52
  392. package/runtime/pi/.codex/hooks.json +3 -3
  393. package/runtime/pi/.codex/skills/activity/SKILL.md +23 -66
  394. package/runtime/pi/.codex/skills/announce/SKILL.md +27 -50
  395. package/runtime/pi/.codex/skills/archive/SKILL.md +21 -36
  396. package/runtime/pi/.codex/skills/checkup/SKILL.md +77 -36
  397. package/runtime/pi/.codex/skills/dark-mode/SKILL.md +1 -1
  398. package/runtime/pi/.codex/skills/dashboard/SKILL.md +17 -47
  399. package/runtime/pi/.codex/skills/handoff/SKILL.md +84 -133
  400. package/runtime/pi/.codex/skills/harvest/SKILL.md +32 -117
  401. package/runtime/pi/.codex/skills/ingest/SKILL.md +47 -25
  402. package/runtime/pi/.codex/skills/ingest-user-interview/SKILL.md +18 -36
  403. package/runtime/pi/.codex/skills/ingest-user-interview/references/analysis-contract.md +42 -0
  404. package/runtime/pi/.codex/skills/invite/SKILL.md +21 -35
  405. package/runtime/pi/.codex/skills/issue/SKILL.md +60 -41
  406. package/runtime/pi/.codex/skills/me/SKILL.md +1 -1
  407. package/runtime/pi/.codex/skills/meeting/SKILL.md +16 -36
  408. package/runtime/pi/.codex/skills/meeting/references/analysis-contract.md +48 -0
  409. package/runtime/pi/.codex/skills/note/SKILL.md +30 -25
  410. package/runtime/pi/.codex/skills/onboarding/SKILL.md +36 -41
  411. package/runtime/pi/.codex/skills/pull/SKILL.md +1 -1
  412. package/runtime/pi/.codex/skills/quest/SKILL.md +27 -66
  413. package/runtime/pi/.codex/skills/reflect/SKILL.md +22 -36
  414. package/runtime/pi/.codex/skills/save/SKILL.md +2 -2
  415. package/runtime/pi/.codex/skills/telemetry/SKILL.md +1 -1
  416. package/runtime/pi/.codex/skills/test/SKILL.md +1 -1
  417. package/runtime/pi/.codex/skills/tutorial/SKILL.md +40 -41
  418. package/runtime/pi/.codex/skills/view/SKILL.md +115 -111
  419. package/runtime/pi/.codex/skills/wrap/SKILL.md +45 -41
  420. package/runtime/pi/.codex/spec-manifest.json +9 -9
  421. package/runtime/pi/.pi/APPEND_SYSTEM.md +57 -48
  422. package/runtime/pi/.pi/extensions/egregore.ts +7 -0
  423. package/runtime/pi/.pi/spec-manifest.json +2 -2
  424. package/runtime/pi/AGENTS.md +62 -58
  425. package/runtime/pi/bin/activity-action.sh +92 -0
  426. package/runtime/pi/bin/activity-data.sh +12 -233
  427. package/runtime/pi/bin/agent.sh +84 -100
  428. package/runtime/pi/bin/artifact-register.sh +164 -0
  429. package/runtime/pi/bin/artifact-writeback.sh +53 -0
  430. package/runtime/pi/bin/artifacts.sh +288 -0
  431. package/runtime/pi/bin/build-sealed-dataroom.mjs +722 -0
  432. package/runtime/pi/bin/capture-run.sh +18 -2
  433. package/runtime/pi/bin/codex-render-spec.mjs +41 -16
  434. package/runtime/pi/bin/codex-session-start.sh +14 -4
  435. package/runtime/pi/bin/codex-skill-render.mjs +9 -7
  436. package/runtime/pi/bin/corpus_map.py +806 -0
  437. package/runtime/pi/bin/corpus_survey.py +304 -0
  438. package/runtime/pi/bin/dashboard-data.sh +11 -171
  439. package/runtime/pi/bin/github-auth.sh +121 -0
  440. package/runtime/pi/bin/graph-batch.sh +7 -0
  441. package/runtime/pi/bin/graph-op.sh +4 -0
  442. package/runtime/pi/bin/graph-projection.sh +54 -0
  443. package/runtime/pi/bin/graph-wal.sh +13 -0
  444. package/runtime/pi/bin/graph.sh +44 -0
  445. package/runtime/pi/bin/handoff-lifecycle-job.sh +146 -0
  446. package/runtime/pi/bin/handoff-lifecycle.sh +280 -0
  447. package/runtime/pi/bin/handoff-preview.sh +169 -0
  448. package/runtime/pi/bin/handoff-run.sh +42 -26
  449. package/runtime/pi/bin/ingest-graph.sh +6 -0
  450. package/runtime/pi/bin/ingest-item.sh +10 -0
  451. package/runtime/pi/bin/ingest.sh +59 -30
  452. package/runtime/pi/bin/invite.sh +6 -0
  453. package/runtime/pi/bin/issue.sh +10 -0
  454. package/runtime/pi/bin/knowledge.sh +10 -0
  455. package/runtime/pi/bin/lib/config.sh +20 -0
  456. package/runtime/pi/bin/lib/context.sh +46 -25
  457. package/runtime/pi/bin/lib/git-sync.sh +70 -6
  458. package/runtime/pi/bin/lib/greeting.sh +34 -5
  459. package/runtime/pi/bin/lib/handoff-meta.sh +97 -0
  460. package/runtime/pi/bin/lib/worktree-links.sh +6 -0
  461. package/runtime/pi/bin/node-run.sh +42 -0
  462. package/runtime/pi/bin/notification.sh +6 -0
  463. package/runtime/pi/bin/observe-context.sh +14 -0
  464. package/runtime/pi/bin/onboarding.sh +6 -0
  465. package/runtime/pi/bin/person.py +4 -0
  466. package/runtime/pi/bin/person.sh +43 -10
  467. package/runtime/pi/bin/pi-observe-context.mjs +93 -0
  468. package/runtime/pi/bin/pi-product-workflows.mjs +1 -1
  469. package/runtime/pi/bin/pi-render-spec.mjs +1 -1
  470. package/runtime/pi/bin/post-update.sh +37 -0
  471. package/runtime/pi/bin/prime-render-spec.mjs +147 -0
  472. package/runtime/pi/bin/publish-artifact.sh +55 -2
  473. package/runtime/pi/bin/quest.sh +9 -0
  474. package/runtime/pi/bin/question.sh +8 -0
  475. package/runtime/pi/bin/research-ingest.sh +7 -0
  476. package/runtime/pi/bin/restore-owned-skills.sh +67 -0
  477. package/runtime/pi/bin/retrieval_eval.py +385 -0
  478. package/runtime/pi/bin/runtime-identity.sh +70 -0
  479. package/runtime/pi/bin/runtime-upgrade.sh +43 -0
  480. package/runtime/pi/bin/scroll.sh +9 -0
  481. package/runtime/pi/bin/search.sh +231 -195
  482. package/runtime/pi/bin/settings.sh +174 -5
  483. package/runtime/pi/bin/startup-check.sh +136 -0
  484. package/runtime/pi/bin/telemetry.sh +522 -247
  485. package/runtime/pi/bin/test-changes.sh +344 -0
  486. package/runtime/pi/bin/thread.sh +9 -0
  487. package/runtime/pi/bin/todo.sh +9 -0
  488. package/runtime/pi/bin/view-render.sh +126 -0
  489. package/runtime/pi/bin/worktree-create.sh +19 -5
  490. package/runtime/pi/egregore_runtime/__init__.py +228 -0
  491. package/runtime/pi/egregore_runtime/adapters/__init__.py +5 -0
  492. package/runtime/pi/egregore_runtime/adapters/invitation.py +237 -0
  493. package/runtime/pi/egregore_runtime/adapters/notification.py +59 -0
  494. package/runtime/pi/egregore_runtime/adapters/qmd.py +1701 -0
  495. package/runtime/pi/egregore_runtime/adapters/qmd_cli.py +210 -0
  496. package/runtime/pi/egregore_runtime/adapters/qmd_embed_worker.py +59 -0
  497. package/runtime/pi/egregore_runtime/admin_gate.py +102 -0
  498. package/runtime/pi/egregore_runtime/artifacts.py +523 -0
  499. package/runtime/pi/egregore_runtime/contracts.py +499 -0
  500. package/runtime/pi/egregore_runtime/entitlements.py +85 -0
  501. package/runtime/pi/egregore_runtime/errors.py +10 -0
  502. package/runtime/pi/egregore_runtime/graph.py +356 -0
  503. package/runtime/pi/egregore_runtime/handoff_lookup.py +196 -0
  504. package/runtime/pi/egregore_runtime/harness_cli.py +1221 -0
  505. package/runtime/pi/egregore_runtime/identity.py +734 -0
  506. package/runtime/pi/egregore_runtime/identity_cli.py +91 -0
  507. package/runtime/pi/egregore_runtime/ingest.py +575 -0
  508. package/runtime/pi/egregore_runtime/ingest_cli.py +254 -0
  509. package/runtime/pi/egregore_runtime/ingest_index_cli.py +147 -0
  510. package/runtime/pi/egregore_runtime/invitation_cli.py +51 -0
  511. package/runtime/pi/egregore_runtime/invitations.py +116 -0
  512. package/runtime/pi/egregore_runtime/issue_cli.py +305 -0
  513. package/runtime/pi/egregore_runtime/issues.py +359 -0
  514. package/runtime/pi/egregore_runtime/knowledge.py +376 -0
  515. package/runtime/pi/egregore_runtime/knowledge_cli.py +173 -0
  516. package/runtime/pi/egregore_runtime/lifecycle.py +888 -0
  517. package/runtime/pi/egregore_runtime/lifecycle_cli.py +269 -0
  518. package/runtime/pi/egregore_runtime/notification_cli.py +125 -0
  519. package/runtime/pi/egregore_runtime/notifications.py +230 -0
  520. package/runtime/pi/egregore_runtime/observe.py +342 -0
  521. package/runtime/pi/egregore_runtime/onboarding.py +290 -0
  522. package/runtime/pi/egregore_runtime/onboarding_cli.py +110 -0
  523. package/runtime/pi/egregore_runtime/policy.py +144 -0
  524. package/runtime/pi/egregore_runtime/profile.py +193 -0
  525. package/runtime/pi/egregore_runtime/quest_cli.py +216 -0
  526. package/runtime/pi/egregore_runtime/question_cli.py +180 -0
  527. package/runtime/pi/egregore_runtime/questions.py +304 -0
  528. package/runtime/pi/egregore_runtime/quests.py +419 -0
  529. package/runtime/pi/egregore_runtime/readiness.py +379 -0
  530. package/runtime/pi/egregore_runtime/research_ingest.py +256 -0
  531. package/runtime/pi/egregore_runtime/research_ingest_cli.py +44 -0
  532. package/runtime/pi/egregore_runtime/runtime.py +464 -0
  533. package/runtime/pi/egregore_runtime/scroll_cli.py +185 -0
  534. package/runtime/pi/egregore_runtime/scrolls.py +726 -0
  535. package/runtime/pi/egregore_runtime/status.py +412 -0
  536. package/runtime/pi/egregore_runtime/status_cli.py +174 -0
  537. package/runtime/pi/egregore_runtime/sync.py +218 -0
  538. package/runtime/pi/egregore_runtime/teamsync.py +139 -0
  539. package/runtime/pi/egregore_runtime/telemetry.py +640 -0
  540. package/runtime/pi/egregore_runtime/thread_cli.py +173 -0
  541. package/runtime/pi/egregore_runtime/threads.py +517 -0
  542. package/runtime/pi/egregore_runtime/todo_cli.py +142 -0
  543. package/runtime/pi/egregore_runtime/todos.py +244 -0
  544. package/runtime/pi/egregore_runtime/upgrade.py +770 -0
  545. package/runtime/pi/egregore_runtime/upgrade_worker.py +53 -0
  546. package/runtime/pi/egregore_runtime/writeback.py +391 -0
  547. package/runtime/pi/egregore_runtime/writeback_cli.py +114 -0
  548. package/runtime/pi/manifest.json +98 -1
  549. package/runtime/prime/.codex/hooks/search-hint.js +21 -52
  550. package/runtime/prime/.codex/hooks.json +3 -3
  551. package/runtime/prime/.codex/skills/activity/SKILL.md +23 -66
  552. package/runtime/prime/.codex/skills/announce/SKILL.md +27 -50
  553. package/runtime/prime/.codex/skills/archive/SKILL.md +21 -36
  554. package/runtime/prime/.codex/skills/checkup/SKILL.md +77 -36
  555. package/runtime/prime/.codex/skills/dark-mode/SKILL.md +1 -1
  556. package/runtime/prime/.codex/skills/dashboard/SKILL.md +17 -47
  557. package/runtime/prime/.codex/skills/handoff/SKILL.md +84 -133
  558. package/runtime/prime/.codex/skills/harvest/SKILL.md +32 -117
  559. package/runtime/prime/.codex/skills/ingest/SKILL.md +47 -25
  560. package/runtime/prime/.codex/skills/ingest-user-interview/SKILL.md +18 -36
  561. package/runtime/prime/.codex/skills/ingest-user-interview/references/analysis-contract.md +42 -0
  562. package/runtime/prime/.codex/skills/invite/SKILL.md +21 -35
  563. package/runtime/prime/.codex/skills/issue/SKILL.md +60 -41
  564. package/runtime/prime/.codex/skills/me/SKILL.md +1 -1
  565. package/runtime/prime/.codex/skills/meeting/SKILL.md +16 -36
  566. package/runtime/prime/.codex/skills/meeting/references/analysis-contract.md +48 -0
  567. package/runtime/prime/.codex/skills/note/SKILL.md +30 -25
  568. package/runtime/prime/.codex/skills/onboarding/SKILL.md +36 -41
  569. package/runtime/prime/.codex/skills/pull/SKILL.md +1 -1
  570. package/runtime/prime/.codex/skills/quest/SKILL.md +27 -66
  571. package/runtime/prime/.codex/skills/reflect/SKILL.md +22 -36
  572. package/runtime/prime/.codex/skills/save/SKILL.md +2 -2
  573. package/runtime/prime/.codex/skills/telemetry/SKILL.md +1 -1
  574. package/runtime/prime/.codex/skills/test/SKILL.md +1 -1
  575. package/runtime/prime/.codex/skills/tutorial/SKILL.md +40 -41
  576. package/runtime/prime/.codex/skills/view/SKILL.md +115 -111
  577. package/runtime/prime/.codex/skills/wrap/SKILL.md +45 -41
  578. package/runtime/prime/.codex/spec-manifest.json +9 -9
  579. package/runtime/prime/.prime/agent/APPEND_SYSTEM.md +57 -48
  580. package/runtime/prime/.prime/agent/extensions/egregore.ts +7 -0
  581. package/runtime/prime/.prime/agent/spec-manifest.json +2 -2
  582. package/runtime/prime/AGENTS.md +62 -58
  583. package/runtime/prime/bin/activity-action.sh +92 -0
  584. package/runtime/prime/bin/activity-data.sh +12 -233
  585. package/runtime/prime/bin/agent.sh +84 -100
  586. package/runtime/prime/bin/artifact-register.sh +164 -0
  587. package/runtime/prime/bin/artifact-writeback.sh +53 -0
  588. package/runtime/prime/bin/artifacts.sh +288 -0
  589. package/runtime/prime/bin/build-sealed-dataroom.mjs +722 -0
  590. package/runtime/prime/bin/capture-run.sh +18 -2
  591. package/runtime/prime/bin/codex-render-spec.mjs +41 -16
  592. package/runtime/prime/bin/codex-session-start.sh +14 -4
  593. package/runtime/prime/bin/codex-skill-render.mjs +9 -7
  594. package/runtime/prime/bin/corpus_map.py +806 -0
  595. package/runtime/prime/bin/corpus_survey.py +304 -0
  596. package/runtime/prime/bin/dashboard-data.sh +11 -171
  597. package/runtime/prime/bin/github-auth.sh +121 -0
  598. package/runtime/prime/bin/graph-batch.sh +7 -0
  599. package/runtime/prime/bin/graph-op.sh +4 -0
  600. package/runtime/prime/bin/graph-projection.sh +54 -0
  601. package/runtime/prime/bin/graph-wal.sh +13 -0
  602. package/runtime/prime/bin/graph.sh +44 -0
  603. package/runtime/prime/bin/handoff-lifecycle-job.sh +146 -0
  604. package/runtime/prime/bin/handoff-lifecycle.sh +280 -0
  605. package/runtime/prime/bin/handoff-preview.sh +169 -0
  606. package/runtime/prime/bin/handoff-run.sh +42 -26
  607. package/runtime/prime/bin/ingest-graph.sh +6 -0
  608. package/runtime/prime/bin/ingest-item.sh +10 -0
  609. package/runtime/prime/bin/ingest.sh +59 -30
  610. package/runtime/prime/bin/invite.sh +6 -0
  611. package/runtime/prime/bin/issue.sh +10 -0
  612. package/runtime/prime/bin/knowledge.sh +10 -0
  613. package/runtime/prime/bin/lib/config.sh +20 -0
  614. package/runtime/prime/bin/lib/context.sh +46 -25
  615. package/runtime/prime/bin/lib/git-sync.sh +70 -6
  616. package/runtime/prime/bin/lib/greeting.sh +34 -5
  617. package/runtime/prime/bin/lib/handoff-meta.sh +97 -0
  618. package/runtime/prime/bin/lib/worktree-links.sh +6 -0
  619. package/runtime/prime/bin/node-run.sh +42 -0
  620. package/runtime/prime/bin/notification.sh +6 -0
  621. package/runtime/prime/bin/observe-context.sh +14 -0
  622. package/runtime/prime/bin/onboarding.sh +6 -0
  623. package/runtime/prime/bin/person.py +4 -0
  624. package/runtime/prime/bin/person.sh +43 -10
  625. package/runtime/prime/bin/pi-observe-context.mjs +93 -0
  626. package/runtime/prime/bin/pi-product-workflows.mjs +1 -1
  627. package/runtime/prime/bin/pi-render-spec.mjs +140 -0
  628. package/runtime/prime/bin/post-update.sh +37 -0
  629. package/runtime/prime/bin/prime-render-spec.mjs +1 -1
  630. package/runtime/prime/bin/publish-artifact.sh +55 -2
  631. package/runtime/prime/bin/quest.sh +9 -0
  632. package/runtime/prime/bin/question.sh +8 -0
  633. package/runtime/prime/bin/research-ingest.sh +7 -0
  634. package/runtime/prime/bin/restore-owned-skills.sh +67 -0
  635. package/runtime/prime/bin/retrieval_eval.py +385 -0
  636. package/runtime/prime/bin/runtime-identity.sh +70 -0
  637. package/runtime/prime/bin/runtime-upgrade.sh +43 -0
  638. package/runtime/prime/bin/scroll.sh +9 -0
  639. package/runtime/prime/bin/search.sh +231 -195
  640. package/runtime/prime/bin/settings.sh +174 -5
  641. package/runtime/prime/bin/startup-check.sh +136 -0
  642. package/runtime/prime/bin/telemetry.sh +522 -247
  643. package/runtime/prime/bin/test-changes.sh +344 -0
  644. package/runtime/prime/bin/thread.sh +9 -0
  645. package/runtime/prime/bin/todo.sh +9 -0
  646. package/runtime/prime/bin/view-render.sh +126 -0
  647. package/runtime/prime/bin/worktree-create.sh +19 -5
  648. package/runtime/prime/egregore_runtime/__init__.py +228 -0
  649. package/runtime/prime/egregore_runtime/adapters/__init__.py +5 -0
  650. package/runtime/prime/egregore_runtime/adapters/invitation.py +237 -0
  651. package/runtime/prime/egregore_runtime/adapters/notification.py +59 -0
  652. package/runtime/prime/egregore_runtime/adapters/qmd.py +1701 -0
  653. package/runtime/prime/egregore_runtime/adapters/qmd_cli.py +210 -0
  654. package/runtime/prime/egregore_runtime/adapters/qmd_embed_worker.py +59 -0
  655. package/runtime/prime/egregore_runtime/admin_gate.py +102 -0
  656. package/runtime/prime/egregore_runtime/artifacts.py +523 -0
  657. package/runtime/prime/egregore_runtime/contracts.py +499 -0
  658. package/runtime/prime/egregore_runtime/entitlements.py +85 -0
  659. package/runtime/prime/egregore_runtime/errors.py +10 -0
  660. package/runtime/prime/egregore_runtime/graph.py +356 -0
  661. package/runtime/prime/egregore_runtime/handoff_lookup.py +196 -0
  662. package/runtime/prime/egregore_runtime/harness_cli.py +1221 -0
  663. package/runtime/prime/egregore_runtime/identity.py +734 -0
  664. package/runtime/prime/egregore_runtime/identity_cli.py +91 -0
  665. package/runtime/prime/egregore_runtime/ingest.py +575 -0
  666. package/runtime/prime/egregore_runtime/ingest_cli.py +254 -0
  667. package/runtime/prime/egregore_runtime/ingest_index_cli.py +147 -0
  668. package/runtime/prime/egregore_runtime/invitation_cli.py +51 -0
  669. package/runtime/prime/egregore_runtime/invitations.py +116 -0
  670. package/runtime/prime/egregore_runtime/issue_cli.py +305 -0
  671. package/runtime/prime/egregore_runtime/issues.py +359 -0
  672. package/runtime/prime/egregore_runtime/knowledge.py +376 -0
  673. package/runtime/prime/egregore_runtime/knowledge_cli.py +173 -0
  674. package/runtime/prime/egregore_runtime/lifecycle.py +888 -0
  675. package/runtime/prime/egregore_runtime/lifecycle_cli.py +269 -0
  676. package/runtime/prime/egregore_runtime/notification_cli.py +125 -0
  677. package/runtime/prime/egregore_runtime/notifications.py +230 -0
  678. package/runtime/prime/egregore_runtime/observe.py +342 -0
  679. package/runtime/prime/egregore_runtime/onboarding.py +290 -0
  680. package/runtime/prime/egregore_runtime/onboarding_cli.py +110 -0
  681. package/runtime/prime/egregore_runtime/policy.py +144 -0
  682. package/runtime/prime/egregore_runtime/profile.py +193 -0
  683. package/runtime/prime/egregore_runtime/quest_cli.py +216 -0
  684. package/runtime/prime/egregore_runtime/question_cli.py +180 -0
  685. package/runtime/prime/egregore_runtime/questions.py +304 -0
  686. package/runtime/prime/egregore_runtime/quests.py +419 -0
  687. package/runtime/prime/egregore_runtime/readiness.py +379 -0
  688. package/runtime/prime/egregore_runtime/research_ingest.py +256 -0
  689. package/runtime/prime/egregore_runtime/research_ingest_cli.py +44 -0
  690. package/runtime/prime/egregore_runtime/runtime.py +464 -0
  691. package/runtime/prime/egregore_runtime/scroll_cli.py +185 -0
  692. package/runtime/prime/egregore_runtime/scrolls.py +726 -0
  693. package/runtime/prime/egregore_runtime/status.py +412 -0
  694. package/runtime/prime/egregore_runtime/status_cli.py +174 -0
  695. package/runtime/prime/egregore_runtime/sync.py +218 -0
  696. package/runtime/prime/egregore_runtime/teamsync.py +139 -0
  697. package/runtime/prime/egregore_runtime/telemetry.py +640 -0
  698. package/runtime/prime/egregore_runtime/thread_cli.py +173 -0
  699. package/runtime/prime/egregore_runtime/threads.py +517 -0
  700. package/runtime/prime/egregore_runtime/todo_cli.py +142 -0
  701. package/runtime/prime/egregore_runtime/todos.py +244 -0
  702. package/runtime/prime/egregore_runtime/upgrade.py +770 -0
  703. package/runtime/prime/egregore_runtime/upgrade_worker.py +53 -0
  704. package/runtime/prime/egregore_runtime/writeback.py +391 -0
  705. package/runtime/prime/egregore_runtime/writeback_cli.py +114 -0
  706. package/runtime/prime/manifest.json +98 -1
@@ -1,44 +1,62 @@
1
1
  #!/usr/bin/env bash
2
- # Egregore telemetry — privacy-respecting product analytics.
3
- # Mirrors bin/graph.sh and bin/notify.sh patterns.
2
+ # Local-first Egregore telemetry compatibility/user CLI.
4
3
  #
5
- # Subcommands:
6
- # emit <type> <json> Append event to local JSONL buffer (no network)
7
- # flush Send buffered events to API and clear buffer
8
- # status Show telemetry status (enabled/disabled, buffer size)
9
- # enable Enable telemetry
10
- # disable Disable telemetry
11
- # clear Clear local buffer
12
- # show [n] Show last N events from buffer (default 10)
13
- #
14
- # Consent: opt-out via EGREGORE_NO_TELEMETRY=1, DO_NOT_TRACK=1,
15
- # or .egregore-state.json → "telemetry": false
16
- #
17
- # Never collected: file paths, file contents, code, env var values,
18
- # conversation content, command arguments with user content.
19
- # Only collected: command names, timestamps, durations, error codes, branch names.
4
+ # Emission is always a local append. No command uploads automatically.
5
+ # Sharing is an explicit two-step operation bound to one disclosed dataset.
20
6
  set -euo pipefail
7
+ umask 077
21
8
 
22
9
  SCRIPT_DIR="$(cd "$(dirname "$0")/.." && pwd)"
23
- BUFFER_DIR="$HOME/.egregore"
10
+ if [ -n "${EGREGORE_TELEMETRY_DIR:-}" ]; then
11
+ BUFFER_DIR="$EGREGORE_TELEMETRY_DIR"
12
+ else
13
+ if [ -e "$SCRIPT_DIR/memory" ]; then
14
+ INSTANCE_ROOT="$(cd "$SCRIPT_DIR/memory" && pwd -P)"
15
+ else
16
+ INSTANCE_ROOT="$(cd "$SCRIPT_DIR" && pwd -P)"
17
+ fi
18
+ if command -v shasum >/dev/null 2>&1; then
19
+ INSTANCE_NAMESPACE=$(printf '%s' "$INSTANCE_ROOT" | LC_ALL=C LANG=C shasum -a 256 | awk '{print substr($1,1,20)}')
20
+ elif command -v sha256sum >/dev/null 2>&1; then
21
+ INSTANCE_NAMESPACE=$(printf '%s' "$INSTANCE_ROOT" | sha256sum | awk '{print substr($1,1,20)}')
22
+ else
23
+ INSTANCE_NAMESPACE=$(printf '%s' "$INSTANCE_ROOT" | cksum | awk '{print $1}')
24
+ fi
25
+ BUFFER_DIR="$HOME/.egregore/telemetry/$INSTANCE_NAMESPACE"
26
+ fi
24
27
  BUFFER_FILE="$BUFFER_DIR/telemetry.jsonl"
25
- STATE_FILE="$SCRIPT_DIR/.egregore-state.json"
26
- CONFIG="$SCRIPT_DIR/egregore.json"
27
- ENV_FILE="$SCRIPT_DIR/.env"
28
- MAX_BUFFER_BYTES=1048576 # 1MB
29
- MAX_EVENTS_AFTER_TRUNCATE=500
30
28
  LOCK_DIR="$BUFFER_DIR/telemetry.lock"
31
- # Public relay for local/OSS egregores without API keys
32
- TELEMETRY_RELAY_URL="https://egregore-production-55f2.up.railway.app"
29
+ SHARE_CONSENT_FILE="$BUFFER_DIR/telemetry-share-consent.json"
30
+ STATE_FILE="${EGREGORE_STATE_FILE:-$SCRIPT_DIR/.egregore-state.json}"
31
+ CONFIG="${EGREGORE_CONFIG_FILE:-$SCRIPT_DIR/egregore.json}"
32
+ ENV_FILE="${EGREGORE_ENV_FILE:-$SCRIPT_DIR/.env}"
33
+ MAX_BUFFER_BYTES=1048576
34
+ MAX_EVENTS_AFTER_TRUNCATE=500
35
+ SHARE_CONSENT_SECONDS=600
36
+ SCHEMA_VERSION="egregore.telemetry/v1"
37
+ LEGACY_RELAY_URL="https://egregore-production-55f2.up.railway.app/api/telemetry/relay"
38
+
39
+ ALLOWED_METRICS_JSON='[
40
+ "action","branch","class","command","connector","cost_usd","count",
41
+ "degraded","docs_read","duration_ms","edges","error_code","escalated",
42
+ "failure_code","index_revision","input_tokens","items","kind","latency_ms",
43
+ "lex_fingerprint","message_count","mode","model","opened_count",
44
+ "output_tokens","override","pass","query_type","rank","result",
45
+ "retrieval_type","route_tier","routed","service","signals","source",
46
+ "status","step","stop_reason","subcommand","success","tier","token_count",
47
+ "tokens_in","tokens_out","tool_call_count","transport","type",
48
+ "vec_fingerprint","waves","writeback_result"
49
+ ]'
33
50
 
34
- # --- Cross-platform file locking via mkdir (atomic on all POSIX systems) ---
35
51
  _lock() {
36
52
  local attempts=0
53
+ mkdir -p "$BUFFER_DIR"
54
+ chmod 700 "$BUFFER_DIR"
37
55
  while ! mkdir "$LOCK_DIR" 2>/dev/null; do
38
56
  attempts=$((attempts + 1))
39
57
  if [ "$attempts" -gt 50 ]; then
40
- local holder_pid
41
- holder_pid=$(cat "$LOCK_DIR/pid" 2>/dev/null || echo "")
58
+ local holder_pid=""
59
+ holder_pid=$(cat "$LOCK_DIR/pid" 2>/dev/null || true)
42
60
  if [ -n "$holder_pid" ] && ! kill -0 "$holder_pid" 2>/dev/null; then
43
61
  rm -rf "$LOCK_DIR" 2>/dev/null
44
62
  continue
@@ -56,64 +74,85 @@ _unlock() {
56
74
 
57
75
  trap '_unlock' EXIT
58
76
 
59
- # --- Consent check (fast path) ---
60
77
  _check_consent() {
61
- # Environment variable opt-outs (fastest check)
62
78
  [ "${EGREGORE_NO_TELEMETRY:-}" = "1" ] && return 1
63
79
  [ "${DO_NOT_TRACK:-}" = "1" ] && return 1
64
-
65
- # State file opt-out
66
80
  if [ -f "$STATE_FILE" ]; then
67
- local val
68
- val=$(jq -r '.telemetry // "true"' "$STATE_FILE" 2>/dev/null || echo "true")
69
- [ "$val" = "false" ] && return 1
81
+ local value="true"
82
+ value=$(jq -r 'if has("telemetry") then .telemetry else true end' "$STATE_FILE" 2>/dev/null || echo "true")
83
+ [ "$value" = "false" ] && return 1
70
84
  fi
71
-
72
85
  return 0
73
86
  }
74
87
 
75
- # --- Debug mode ---
76
88
  _is_debug() {
77
89
  [ "${EGREGORE_TELEMETRY_DEBUG:-}" = "1" ]
78
90
  }
79
91
 
80
- # --- Resolve identity (from env vars first, fallback to config files) ---
81
- _resolve_user() {
82
- if [ -n "${EGREGORE_USER:-}" ]; then
83
- echo "$EGREGORE_USER"
92
+ _resolve_actor() {
93
+ if [ -n "${EGREGORE_ACTOR_ID:-}" ]; then
94
+ printf '%s\n' "$EGREGORE_ACTOR_ID"
84
95
  elif [ -f "$STATE_FILE" ]; then
85
- jq -r '.github_username // .name // "unknown"' "$STATE_FILE" 2>/dev/null || echo "unknown"
96
+ local actor=""
97
+ actor=$(jq -r '.actor_id // empty' "$STATE_FILE" 2>/dev/null || true)
98
+ if [ -n "$actor" ]; then
99
+ printf '%s\n' "$actor"
100
+ else
101
+ local legacy=""
102
+ legacy=$(jq -r '.github_username // "unknown"' "$STATE_FILE" 2>/dev/null || echo "unknown")
103
+ printf 'legacy:%s\n' "$legacy"
104
+ fi
86
105
  else
87
- echo "unknown"
106
+ printf 'unknown\n'
88
107
  fi
89
108
  }
90
109
 
91
110
  _resolve_org() {
92
- if [ -n "${EGREGORE_ORG:-}" ]; then
93
- echo "$EGREGORE_ORG"
111
+ if [ -n "${EGREGORE_ORG_ID:-}" ]; then
112
+ printf '%s\n' "$EGREGORE_ORG_ID"
94
113
  elif [ -f "$CONFIG" ]; then
95
- jq -r '.slug // .github_org // "unknown"' "$CONFIG" 2>/dev/null || echo "unknown"
114
+ local org=""
115
+ org=$(jq -r '.org_id // empty' "$CONFIG" 2>/dev/null || true)
116
+ if [ -n "$org" ]; then
117
+ printf '%s\n' "$org"
118
+ else
119
+ local legacy=""
120
+ legacy=$(jq -r '.slug // .github_org // "unknown"' "$CONFIG" 2>/dev/null || echo "unknown")
121
+ printf 'legacy-org:%s\n' "$legacy"
122
+ fi
96
123
  else
97
- echo "unknown"
124
+ printf 'unknown\n'
125
+ fi
126
+ }
127
+
128
+ _resolve_org_revision() {
129
+ if [ -n "${EGREGORE_ORG_REVISION:-}" ]; then
130
+ printf '%s\n' "$EGREGORE_ORG_REVISION"
131
+ elif [ -f "$CONFIG" ]; then
132
+ jq -r '.profile.revision // .revision // empty' "$CONFIG" 2>/dev/null || true
133
+ fi
134
+ }
135
+
136
+ _resolve_index_spec_version() {
137
+ if [ -n "${EGREGORE_INDEX_SPEC_VERSION:-}" ]; then
138
+ printf '%s\n' "$EGREGORE_INDEX_SPEC_VERSION"
139
+ elif [ -f "$CONFIG" ]; then
140
+ jq -r '.retrieval.index_spec_version // .index_spec_version // empty' "$CONFIG" 2>/dev/null || true
98
141
  fi
99
142
  }
100
143
 
101
144
  _resolve_proj_hash() {
102
- # Use git common dir so worktrees hash to the same path as the main checkout
103
- local repo_root
145
+ local repo_root=""
104
146
  repo_root=$(git -C "$SCRIPT_DIR" rev-parse --path-format=absolute --git-common-dir 2>/dev/null | sed 's|/\.git$||') || repo_root="$SCRIPT_DIR"
105
147
  echo -n "$repo_root" | md5 2>/dev/null || echo -n "$repo_root" | md5sum 2>/dev/null | cut -d' ' -f1
106
148
  }
107
149
 
108
150
  _resolve_session_id() {
109
151
  if [ -n "${EGREGORE_SESSION_ID:-}" ]; then
110
- echo "$EGREGORE_SESSION_ID"
152
+ printf '%s\n' "$EGREGORE_SESSION_ID"
111
153
  return
112
154
  fi
113
-
114
- # Fallback: read from file written by session-start.sh
115
- # (env vars from hooks don't propagate into the Claude Code agent)
116
- local proj_hash
155
+ local proj_hash=""
117
156
  proj_hash=$(_resolve_proj_hash)
118
157
  local sid_file="$HOME/.egregore/session-${proj_hash}.id"
119
158
  if [ -f "$sid_file" ]; then
@@ -124,268 +163,504 @@ _resolve_session_id() {
124
163
  }
125
164
 
126
165
  _resolve_model() {
127
- local proj_hash
166
+ local proj_hash=""
128
167
  proj_hash=$(_resolve_proj_hash)
129
168
  local model_file="$HOME/.egregore/session-model-${proj_hash}"
130
- if [ ! -s "$model_file" ]; then
131
- return 0
132
- fi
169
+ [ -s "$model_file" ] || return 0
170
+ head -n 1 "$model_file"
171
+ }
133
172
 
173
+ _stamp_model_if_absent() {
174
+ local data="$1"
175
+ if printf '%s' "$data" | jq -e 'has("model")' >/dev/null 2>&1; then
176
+ printf '%s' "$data"
177
+ return
178
+ fi
134
179
  local model=""
135
- IFS= read -r model < "$model_file" || true
180
+ model=$(_resolve_model 2>/dev/null || true)
136
181
  if [ -n "$model" ]; then
137
- printf '%s\n' "$model"
182
+ printf '%s' "$data" | jq -c --arg model "$model" '. + {model:$model}'
183
+ else
184
+ printf '%s' "$data"
138
185
  fi
139
186
  }
140
187
 
141
- _stamp_model_if_absent() {
142
- local compact_data="$1"
143
- local has_model=""
144
- has_model=$(printf '%s' "$compact_data" | jq -e 'has("model")' 2>/dev/null || true)
145
- if [ "$has_model" != "false" ]; then
146
- printf '%s' "$compact_data"
147
- return 0
188
+ _sha256_file() {
189
+ if command -v shasum >/dev/null 2>&1; then
190
+ LC_ALL=C LANG=C shasum -a 256 "$1" | cut -d' ' -f1
191
+ else
192
+ sha256sum "$1" | cut -d' ' -f1
148
193
  fi
194
+ }
149
195
 
150
- local model=""
151
- model=$(_resolve_model 2>/dev/null || true)
152
- if [ -z "$model" ]; then
153
- printf '%s' "$compact_data"
154
- return 0
196
+ _sha256_text() {
197
+ if command -v shasum >/dev/null 2>&1; then
198
+ printf '%s' "$1" | LC_ALL=C LANG=C shasum -a 256 | cut -d' ' -f1
199
+ else
200
+ printf '%s' "$1" | sha256sum | cut -d' ' -f1
155
201
  fi
202
+ }
156
203
 
157
- local stamped_data=""
158
- if stamped_data=$(printf '%s' "$compact_data" | jq -c --arg m "$model" 'if has("model") then . else . + {model:$m} end' 2>/dev/null); then
159
- printf '%s' "$stamped_data"
204
+ _random_token() {
205
+ if command -v openssl >/dev/null 2>&1; then
206
+ openssl rand -hex 24
160
207
  else
161
- printf '%s' "$compact_data"
208
+ local seed=""
209
+ seed="$(date +%s)-$$-${RANDOM:-0}"
210
+ _sha256_text "$seed"
162
211
  fi
163
212
  }
164
213
 
165
- # --- emit: append event to local JSONL buffer ---
214
+ _validate_metrics() {
215
+ local metrics="$1"
216
+ printf '%s' "$metrics" | jq -e --argjson allowed "$ALLOWED_METRICS_JSON" '
217
+ type == "object" and
218
+ ((keys - $allowed) | length == 0) and
219
+ all(to_entries[];
220
+ (.value == null or
221
+ (.value | type) == "boolean" or
222
+ (.value | type) == "number" or
223
+ ((.value | type) == "string" and (.value | length) > 0 and (.value | length) <= 200 and
224
+ (.value | test("^[A-Za-z0-9_.:+@/\\[\\]-]+$")) and
225
+ (.value | contains("/") | not) and
226
+ ((.key == "lex_fingerprint" or .key == "vec_fingerprint") | not or
227
+ (.value | test("^sha256:[0-9a-f]{6,64}$"))) and
228
+ (.key != "source" or (["framework","org","default","fallback","user","unknown","local","test"] | index(.value)) != null))))
229
+ ' >/dev/null
230
+ }
231
+
232
+ _validate_buffer() {
233
+ [ -s "$BUFFER_FILE" ] || return 0
234
+ jq -e --arg schema "$SCHEMA_VERSION" --argjson allowed "$ALLOWED_METRICS_JSON" '
235
+ def safe_id:
236
+ type == "string" and length > 0 and length <= 256 and
237
+ test("^[A-Za-z0-9_.:+@/\\[\\]-]+$");
238
+ def safe_metrics:
239
+ type == "object" and
240
+ ((keys - $allowed) | length == 0) and
241
+ all(to_entries[];
242
+ (.value == null or
243
+ (.value | type) == "boolean" or
244
+ (.value | type) == "number" or
245
+ ((.value | type) == "string" and (.value | length) > 0 and (.value | length) <= 200 and
246
+ (.value | test("^[A-Za-z0-9_.:+@/\\[\\]-]+$")) and
247
+ (.value | contains("/") | not) and
248
+ ((.key == "lex_fingerprint" or .key == "vec_fingerprint") | not or
249
+ (.value | test("^sha256:[0-9a-f]{6,64}$"))) and
250
+ (.key != "source" or (["framework","org","default","fallback","user","unknown","local","test"] | index(.value)) != null))));
251
+ if .schema_version == $schema then
252
+ ((keys - ["actor_id","artifact_ids","event_id","event_type",
253
+ "index_spec_version","metrics","occurred_at","org_id","org_revision",
254
+ "schema_version","session_id","shared","task_id"]) | length == 0) and
255
+ (.metrics | safe_metrics) and
256
+ (.event_id | safe_id) and (.event_type | safe_id) and
257
+ (.org_id | safe_id) and (.actor_id | safe_id) and (.session_id | safe_id) and
258
+ (.task_id == null or (.task_id | safe_id)) and
259
+ (.org_revision == null or (.org_revision | safe_id)) and
260
+ (.index_spec_version == null or (.index_spec_version | safe_id)) and
261
+ (.artifact_ids | type == "array" and all(.[]; safe_id))
262
+ else
263
+ ((keys - ["data","event_id","org","sid","ts","type","user"]) | length == 0) and
264
+ (.data | safe_metrics) and (.ts | type == "string") and
265
+ (.type | safe_id) and (.sid | safe_id) and (.org | safe_id) and (.user | safe_id)
266
+ end
267
+ ' "$BUFFER_FILE" >/dev/null 2>&1
268
+ }
269
+
166
270
  cmd_emit() {
167
271
  local event_type="${1:?Usage: telemetry.sh emit <type> <json>}"
168
- local data="${2:-"{}"}"
272
+ local data="${2:-{}}"
273
+ _check_consent || return 0
169
274
 
170
- # Consent gate
171
- if ! _check_consent; then
275
+ local compact_data=""
276
+ if ! compact_data=$(printf '%s' "$data" | jq -c . 2>/dev/null); then
277
+ echo "Telemetry event rejected: payload must be valid JSON." >&2
172
278
  return 0
173
279
  fi
280
+ compact_data=$(_stamp_model_if_absent "$compact_data")
174
281
 
175
- local ts
282
+ local task_id org_revision index_spec_version artifact_ids metrics
283
+ task_id=$(printf '%s' "$compact_data" | jq -r '.task_id // empty')
284
+ org_revision=$(printf '%s' "$compact_data" | jq -r '.org_revision // empty')
285
+ [ -n "$org_revision" ] || org_revision=$(_resolve_org_revision)
286
+ index_spec_version=$(printf '%s' "$compact_data" | jq -r '.index_spec_version // empty')
287
+ [ -n "$index_spec_version" ] || index_spec_version=$(_resolve_index_spec_version)
288
+ artifact_ids=$(printf '%s' "$compact_data" | jq -c '.artifact_ids // .opened_artifact_ids // []')
289
+ metrics=$(printf '%s' "$compact_data" | jq -c 'del(.task_id,.org_revision,.index_spec_version,.artifact_ids,.opened_artifact_ids)')
290
+
291
+ if ! printf '%s' "$artifact_ids" | jq -e 'type == "array" and all(.[]; type == "string" and length > 0 and length <= 256 and test("^[A-Za-z0-9_.:+@/\\[\\]-]+$"))' >/dev/null 2>&1 \
292
+ || ! printf '%s\n%s\n%s\n%s\n' "$event_type" "$task_id" "$org_revision" "$index_spec_version" | awk 'length($0) > 256 { exit 1 } /[^A-Za-z0-9_.:+@\/\[\]-]/ && length($0) > 0 { exit 1 }' \
293
+ || ! _validate_metrics "$metrics"; then
294
+ echo "Telemetry event rejected: only allowlisted, content-free metrics are accepted." >&2
295
+ return 0
296
+ fi
297
+
298
+ local ts event_id line
176
299
  ts=$(date -u +%Y-%m-%dT%H:%M:%SZ)
177
- # Compact data to single line — callers may pass pretty-printed JSON
178
- local compact_data
179
- compact_data=$(printf '%s' "$data" | tr -d '\n' | tr -s ' ')
180
- compact_data=$(_stamp_model_if_absent "$compact_data")
300
+ event_id="tel_$(_random_token)"
301
+ line=$(jq -cn \
302
+ --arg schema "$SCHEMA_VERSION" \
303
+ --arg event_id "$event_id" \
304
+ --arg event_type "$event_type" \
305
+ --arg occurred_at "$ts" \
306
+ --arg org_id "$(_resolve_org)" \
307
+ --arg actor_id "$(_resolve_actor)" \
308
+ --arg session_id "$(_resolve_session_id)" \
309
+ --arg task_id "$task_id" \
310
+ --arg org_revision "$org_revision" \
311
+ --arg index_spec_version "$index_spec_version" \
312
+ --argjson metrics "$metrics" \
313
+ --argjson artifact_ids "$artifact_ids" \
314
+ '{schema_version:$schema,event_id:$event_id,event_type:$event_type,
315
+ occurred_at:$occurred_at,org_id:$org_id,actor_id:$actor_id,
316
+ session_id:$session_id,task_id:(if $task_id == "" then null else $task_id end),
317
+ org_revision:(if $org_revision == "" then null else $org_revision end),
318
+ index_spec_version:(if $index_spec_version == "" then null else $index_spec_version end),
319
+ metrics:$metrics,artifact_ids:$artifact_ids,shared:false}')
181
320
 
182
- # Debug mode: print to stderr instead of writing
183
321
  if _is_debug; then
184
- printf '{"ts":"%s","type":"%s","sid":"%s","org":"%s","user":"%s","data":%s}\n' \
185
- "$ts" "$event_type" "$(_resolve_session_id)" "$(_resolve_org)" "$(_resolve_user)" "$compact_data" >&2
322
+ printf '%s\n' "$line" >&2
186
323
  return 0
187
324
  fi
188
325
 
189
- # Ensure buffer directory exists
190
326
  mkdir -p "$BUFFER_DIR"
327
+ _lock || { printf '%s\n' "$line" >> "$BUFFER_FILE" 2>/dev/null; return 0; }
328
+ printf '%s\n' "$line" >> "$BUFFER_FILE"
329
+ chmod 600 "$BUFFER_FILE"
330
+ local size=0
331
+ size=$(wc -c < "$BUFFER_FILE" 2>/dev/null | tr -d ' ')
332
+ if [ "$size" -gt "$MAX_BUFFER_BYTES" ] 2>/dev/null; then
333
+ local temporary="$BUFFER_FILE.truncate.$$"
334
+ if tail -n "$MAX_EVENTS_AFTER_TRUNCATE" "$BUFFER_FILE" > "$temporary" 2>/dev/null; then
335
+ mv "$temporary" "$BUFFER_FILE"
336
+ else
337
+ rm -f "$temporary"
338
+ fi
339
+ fi
340
+ _unlock
341
+ }
191
342
 
192
- # Build event line (outside lock for minimal hold time)
193
- local line
194
- line=$(printf '{"ts":"%s","type":"%s","sid":"%s","org":"%s","user":"%s","data":%s}' \
195
- "$ts" "$event_type" "$(_resolve_session_id)" "$(_resolve_org)" "$(_resolve_user)" "$compact_data")
196
-
197
- # Append under lock
198
- _lock || { echo "$line" >> "$BUFFER_FILE" 2>/dev/null; return 0; }
199
- echo "$line" >> "$BUFFER_FILE"
200
-
201
- # Buffer guard: if file exceeds max size, truncate to last N events
343
+ cmd_status() {
344
+ local enabled="yes" reason="" count=0 size=0
345
+ if ! _check_consent; then
346
+ enabled="no"
347
+ if [ "${EGREGORE_NO_TELEMETRY:-}" = "1" ]; then
348
+ reason="EGREGORE_NO_TELEMETRY=1"
349
+ elif [ "${DO_NOT_TRACK:-}" = "1" ]; then
350
+ reason="DO_NOT_TRACK=1"
351
+ else
352
+ reason="telemetry=false in .egregore-state.json"
353
+ fi
354
+ fi
202
355
  if [ -f "$BUFFER_FILE" ]; then
203
- local size
356
+ count=$(grep -c '^{' "$BUFFER_FILE" 2>/dev/null || true)
204
357
  size=$(wc -c < "$BUFFER_FILE" 2>/dev/null | tr -d ' ')
205
- if [ "$size" -gt "$MAX_BUFFER_BYTES" ] 2>/dev/null; then
206
- local tmp="$BUFFER_FILE.truncate.$$"
207
- tail -n "$MAX_EVENTS_AFTER_TRUNCATE" "$BUFFER_FILE" > "$tmp" 2>/dev/null \
208
- && mv "$tmp" "$BUFFER_FILE" \
209
- || rm -f "$tmp"
210
- fi
211
358
  fi
359
+ if [ "${1:-}" = "--json" ]; then
360
+ # Machine snapshot for the Settings panel. Deliberately excludes buffer
361
+ # paths and raw events — the panel never renders payloads or internal
362
+ # locations.
363
+ local noticed="false" last=""
364
+ [ -f "$STATE_FILE" ] && noticed=$(jq -r 'if .telemetry_noticed == true then "true" else "false" end' "$STATE_FILE" 2>/dev/null || echo false)
365
+ [ -f "$BUFFER_FILE" ] && last=$(tail -1 "$BUFFER_FILE" 2>/dev/null | jq -r '.occurred_at // .ts // empty' 2>/dev/null || true)
366
+ jq -n \
367
+ --arg enabled "$([ "$enabled" = "yes" ] && echo true || echo false)" \
368
+ --arg reason "$reason" \
369
+ --argjson events "${count:-0}" \
370
+ --argjson bytes "${size:-0}" \
371
+ --argjson noticed "$noticed" \
372
+ --arg last "$last" \
373
+ '{
374
+ enabled: ($enabled == "true"),
375
+ reason: (if $reason == "" then null else $reason end),
376
+ buffered_events: $events,
377
+ buffered_bytes: $bytes,
378
+ notice_shown: $noticed,
379
+ last_event_at: (if $last == "" then null else $last end),
380
+ storage: "local buffer only — never shared automatically"
381
+ }'
382
+ return 0
383
+ fi
384
+ echo "Telemetry status:"
385
+ echo ""
386
+ echo " Enabled: $enabled"
387
+ [ -z "$reason" ] || echo " Reason: $reason"
388
+ echo " Storage: local only (never shared automatically)"
389
+ echo " Buffer: $count events ($size bytes)"
390
+ echo " Path: $BUFFER_FILE"
391
+ echo ""
392
+ echo " Inspect: bash bin/telemetry.sh inspect 10"
393
+ echo " Export: bash bin/telemetry.sh export <destination.jsonl>"
394
+ echo " Share: bash bin/telemetry.sh share (requires a second confirmation step)"
395
+ echo " Opt out: set EGREGORE_NO_TELEMETRY=1 or run /telemetry off"
396
+ }
397
+
398
+ _set_enabled() {
399
+ local value="$1"
400
+ local temporary="$STATE_FILE.tmp.$$"
401
+ if [ -f "$STATE_FILE" ]; then
402
+ jq --argjson value "$value" '.telemetry = $value' "$STATE_FILE" > "$temporary" \
403
+ && chmod 600 "$temporary" && mv "$temporary" "$STATE_FILE"
404
+ else
405
+ jq -n --argjson value "$value" '{telemetry:$value}' > "$temporary" \
406
+ && chmod 600 "$temporary" && mv "$temporary" "$STATE_FILE"
407
+ fi
408
+ }
409
+
410
+ cmd_enable() {
411
+ _set_enabled true
412
+ echo "Telemetry enabled. Events remain local until an explicit share is confirmed."
413
+ }
414
+
415
+ cmd_disable() {
416
+ _set_enabled false
417
+ echo "Telemetry disabled. Existing local events were not deleted."
418
+ }
419
+
420
+ cmd_clear() {
421
+ if ! _lock; then
422
+ echo "Could not acquire the telemetry lock; nothing was cleared." >&2
423
+ return 1
424
+ fi
425
+ rm -f "$BUFFER_FILE" "$SHARE_CONSENT_FILE"
212
426
  _unlock
427
+ echo "Local telemetry buffer cleared."
213
428
  }
214
429
 
215
- # --- flush: send buffered events to API ---
216
- cmd_flush() {
217
- if [ ! -f "$BUFFER_FILE" ] || [ ! -s "$BUFFER_FILE" ]; then
430
+ cmd_inspect() {
431
+ local n="${1:-10}" json=0
432
+ [ "${2:-}" = "--json" ] && json=1
433
+ [ "$n" = "--json" ] && { json=1; n=10; }
434
+ case "$n" in
435
+ ''|*[!0-9]*) echo "inspect limit must be a non-negative integer" >&2; return 2 ;;
436
+ esac
437
+ if [ ! -s "$BUFFER_FILE" ]; then
438
+ [ "$json" -eq 1 ] && echo '[]' || echo "No buffered events."
439
+ return 0
440
+ fi
441
+ if [ "$json" -eq 1 ]; then
442
+ tail -n "$n" "$BUFFER_FILE" | jq -sc 'map({occurred_at, event_type, metrics})' 2>/dev/null || echo '[]'
218
443
  return 0
219
444
  fi
445
+ echo "Last $n local events:"
446
+ echo ""
447
+ tail -n "$n" "$BUFFER_FILE" | jq -c . 2>/dev/null || tail -n "$n" "$BUFFER_FILE"
448
+ }
220
449
 
221
- # Read API config
222
- local api_url=""
223
- local api_key=""
224
- local endpoint=""
225
- local auth_header=""
450
+ cmd_export() {
451
+ local destination="${1:?Usage: telemetry.sh export <destination.jsonl>}"
452
+ if ! _validate_buffer; then
453
+ echo "Export blocked: the local buffer contains an invalid or content-bearing event." >&2
454
+ return 2
455
+ fi
456
+ mkdir -p "$(dirname "$destination")"
457
+ if [ -s "$BUFFER_FILE" ]; then
458
+ cp "$BUFFER_FILE" "$destination"
459
+ else
460
+ : > "$destination"
461
+ fi
462
+ echo "Exported local telemetry to $destination"
463
+ }
464
+
465
+ _resolve_share_target() {
466
+ local requested_endpoint="$1"
467
+ local allow_legacy_relay="$2"
468
+ if [ -n "$requested_endpoint" ]; then
469
+ printf '%s\n' "$requested_endpoint"
470
+ return
471
+ fi
472
+ local api_url="" api_key=""
226
473
  if [ -f "$CONFIG" ]; then
227
474
  api_url=$(jq -r '.api_url // empty' "$CONFIG" 2>/dev/null || true)
228
475
  fi
229
476
  if [ -f "$ENV_FILE" ]; then
230
477
  api_key=$(grep '^EGREGORE_API_KEY=' "$ENV_FILE" 2>/dev/null | cut -d'=' -f2- || true)
231
478
  fi
232
-
233
479
  if [ -n "$api_url" ] && [ -n "$api_key" ]; then
234
- # Connected mode: authenticated ingest
235
- endpoint="${api_url}/api/telemetry/ingest"
236
- auth_header="Authorization: Bearer $api_key"
237
- else
238
- # Local/OSS mode: public relay (no auth needed)
239
- endpoint="${TELEMETRY_RELAY_URL}/api/telemetry/relay"
240
- auth_header=""
480
+ printf '%s/api/telemetry/ingest\n' "${api_url%/}"
481
+ elif [ "$allow_legacy_relay" = "true" ]; then
482
+ printf '%s\n' "$LEGACY_RELAY_URL"
241
483
  fi
484
+ }
242
485
 
243
- # Atomic rotate under lock: move buffer so new events can keep writing
244
- _lock || return 0
245
- local flush_file="$BUFFER_FILE.flush.$$"
246
- mv "$BUFFER_FILE" "$flush_file" 2>/dev/null || { _unlock; return 0; }
247
- _unlock
486
+ cmd_share() {
487
+ local confirmation="" requested_endpoint="" allow_legacy_relay="false"
488
+ while [ "$#" -gt 0 ]; do
489
+ case "$1" in
490
+ --confirm)
491
+ confirmation="${2:-}"
492
+ shift 2
493
+ ;;
494
+ --endpoint)
495
+ requested_endpoint="${2:-}"
496
+ shift 2
497
+ ;;
498
+ --legacy-public-relay)
499
+ allow_legacy_relay="true"
500
+ shift
501
+ ;;
502
+ *)
503
+ echo "Unknown share option: $1" >&2
504
+ return 2
505
+ ;;
506
+ esac
507
+ done
248
508
 
249
- # POST to API
250
- local response
251
- local http_code
252
- local curl_args=(-s -o /dev/null -w '%{http_code}' -X POST "$endpoint"
253
- -H "Content-Type: application/x-ndjson"
254
- --data-binary "@$flush_file"
255
- --max-time 15)
256
- if [ -n "$auth_header" ]; then
257
- curl_args+=(-H "$auth_header")
509
+ if [ -n "$confirmation" ] && [ -z "$requested_endpoint" ] && [ -f "$SHARE_CONSENT_FILE" ]; then
510
+ requested_endpoint=$(jq -r '.target // empty' "$SHARE_CONSENT_FILE" 2>/dev/null || true)
258
511
  fi
259
- http_code=$(curl "${curl_args[@]}" 2>/dev/null || echo "000")
260
512
 
261
- if [ "$http_code" -ge 200 ] 2>/dev/null && [ "$http_code" -lt 300 ] 2>/dev/null; then
262
- # Success — remove flush file
263
- rm -f "$flush_file"
264
- else
265
- # Failure — move events back so they aren't lost (under lock to prevent races)
266
- _lock || { mv "$flush_file" "$BUFFER_FILE" 2>/dev/null || true; return 1; }
267
- if [ -f "$BUFFER_FILE" ]; then
268
- # New events were written while we were flushing; prepend old events
269
- cat "$flush_file" "$BUFFER_FILE" > "$BUFFER_FILE.merge.$$" 2>/dev/null \
270
- && mv "$BUFFER_FILE.merge.$$" "$BUFFER_FILE" \
271
- && rm -f "$flush_file" \
272
- || rm -f "$BUFFER_FILE.merge.$$"
273
- else
274
- mv "$flush_file" "$BUFFER_FILE" 2>/dev/null || true
275
- fi
276
- _unlock
513
+ local endpoint=""
514
+ endpoint=$(_resolve_share_target "$requested_endpoint" "$allow_legacy_relay")
515
+ if [ -z "$endpoint" ]; then
516
+ echo "No shared telemetry sink is configured. Export locally, or name an explicit --endpoint." >&2
517
+ echo "The former public relay remains available only with --legacy-public-relay." >&2
518
+ return 2
277
519
  fi
278
- }
279
-
280
- # --- status: show telemetry status ---
281
- cmd_status() {
282
- echo "Telemetry status:"
283
- echo ""
284
-
285
- # Consent
286
- if _check_consent; then
287
- echo " Enabled: yes"
288
- else
289
- echo " Enabled: no"
290
- if [ "${EGREGORE_NO_TELEMETRY:-}" = "1" ]; then
291
- echo " Reason: EGREGORE_NO_TELEMETRY=1"
292
- elif [ "${DO_NOT_TRACK:-}" = "1" ]; then
293
- echo " Reason: DO_NOT_TRACK=1"
294
- else
295
- echo " Reason: telemetry=false in .egregore-state.json"
296
- fi
520
+ case "$endpoint" in
521
+ https://*|http://127.0.0.1*|http://localhost*|http://\[::1\]*) ;;
522
+ *) echo "Share endpoint must use https (or loopback http)." >&2; return 2 ;;
523
+ esac
524
+ if ! _validate_buffer; then
525
+ echo "Share blocked: the local buffer contains an invalid or content-bearing event." >&2
526
+ return 2
297
527
  fi
298
528
 
299
- # Buffer
300
- if [ -f "$BUFFER_FILE" ]; then
301
- local count size
302
- count=$(grep -c '^{' "$BUFFER_FILE" 2>/dev/null || echo 0)
529
+ local count=0 size=0 dataset_sha256=""
530
+ if [ -s "$BUFFER_FILE" ]; then
531
+ count=$(grep -c '^{' "$BUFFER_FILE" 2>/dev/null || true)
303
532
  size=$(wc -c < "$BUFFER_FILE" 2>/dev/null | tr -d ' ')
304
- echo " Buffer: $count events ($size bytes)"
305
- echo " Path: $BUFFER_FILE"
533
+ dataset_sha256=$(_sha256_file "$BUFFER_FILE")
306
534
  else
307
- echo " Buffer: empty"
535
+ local empty_file="$BUFFER_DIR/telemetry.empty.$$"
536
+ mkdir -p "$BUFFER_DIR"
537
+ : > "$empty_file"
538
+ dataset_sha256=$(_sha256_file "$empty_file")
539
+ rm -f "$empty_file"
308
540
  fi
309
541
 
310
- echo ""
311
- echo " Opt-out: set EGREGORE_NO_TELEMETRY=1 in .env, or run /telemetry off"
312
- }
542
+ if [ -z "$confirmation" ]; then
543
+ local fields="none"
544
+ if [ -s "$BUFFER_FILE" ]; then
545
+ fields=$(jq -rs '
546
+ [.[].metrics // .[].data // {} | keys[]] | unique |
547
+ if length == 0 then "none" else map("metrics." + .) | join(", ") end
548
+ ' "$BUFFER_FILE" 2>/dev/null || echo "unable to inspect")
549
+ fi
550
+ local token token_sha256 expires_at
551
+ token=$(_random_token)
552
+ token_sha256=$(_sha256_text "$token")
553
+ expires_at=$(($(date +%s) + SHARE_CONSENT_SECONDS))
554
+ mkdir -p "$BUFFER_DIR"
555
+ jq -n \
556
+ --arg target "$endpoint" \
557
+ --arg dataset_sha256 "$dataset_sha256" \
558
+ --arg token_sha256 "$token_sha256" \
559
+ --argjson expires_at "$expires_at" \
560
+ '{target:$target,dataset_sha256:$dataset_sha256,token_sha256:$token_sha256,expires_at:$expires_at}' \
561
+ > "$SHARE_CONSENT_FILE"
562
+ chmod 600 "$SHARE_CONSENT_FILE"
563
+
564
+ echo "Telemetry share proposal (nothing sent):"
565
+ echo ""
566
+ echo " Target: $endpoint"
567
+ echo " Events: $count"
568
+ echo " Bytes: $size"
569
+ echo " Dataset SHA-256: $dataset_sha256"
570
+ echo " Top-level fields: schema/version, event/task/org/actor/session identifiers, timestamps, artifact ids, shared flag"
571
+ echo " Metric fields: $fields"
572
+ echo " Excluded by validation: prompts, content, passages, file paths, arguments, secrets, env values"
573
+ echo ""
574
+ echo "Inspect first: bash bin/telemetry.sh inspect $count"
575
+ echo "Confirm within 10 minutes with this one-time token:"
576
+ echo " bash bin/telemetry.sh share --confirm '$token'"
577
+ return 0
578
+ fi
313
579
 
314
- # --- enable: turn telemetry on ---
315
- cmd_enable() {
316
- if [ -f "$STATE_FILE" ]; then
317
- jq '.telemetry = true' "$STATE_FILE" > "$STATE_FILE.tmp" \
318
- && mv "$STATE_FILE.tmp" "$STATE_FILE"
580
+ if [ ! -f "$SHARE_CONSENT_FILE" ]; then
581
+ echo "Share blocked: run share without --confirm to inspect and prepare this dataset first." >&2
582
+ return 2
583
+ fi
584
+ local expected_target expected_dataset expected_token expires_at actual_token
585
+ expected_target=$(jq -r '.target // empty' "$SHARE_CONSENT_FILE")
586
+ expected_dataset=$(jq -r '.dataset_sha256 // empty' "$SHARE_CONSENT_FILE")
587
+ expected_token=$(jq -r '.token_sha256 // empty' "$SHARE_CONSENT_FILE")
588
+ expires_at=$(jq -r '.expires_at // 0' "$SHARE_CONSENT_FILE")
589
+ actual_token=$(_sha256_text "$confirmation")
590
+ if [ "$(date +%s)" -gt "$expires_at" ] 2>/dev/null; then
591
+ rm -f "$SHARE_CONSENT_FILE"
592
+ echo "Share blocked: confirmation expired; prepare a new share." >&2
593
+ return 2
594
+ fi
595
+ if [ "$endpoint" != "$expected_target" ] || [ "$dataset_sha256" != "$expected_dataset" ] || [ "$actual_token" != "$expected_token" ]; then
596
+ echo "Share blocked: target, dataset, or confirmation token changed; prepare a new share." >&2
597
+ return 2
319
598
  fi
320
- echo "Telemetry enabled."
321
- }
322
599
 
323
- # --- disable: turn telemetry off ---
324
- cmd_disable() {
325
- if [ -f "$STATE_FILE" ]; then
326
- jq '.telemetry = false' "$STATE_FILE" > "$STATE_FILE.tmp" \
327
- && mv "$STATE_FILE.tmp" "$STATE_FILE"
600
+ local share_file="$BUFFER_DIR/telemetry.share.$$"
601
+ if [ -s "$BUFFER_FILE" ]; then
602
+ jq -c --arg schema "$SCHEMA_VERSION" '
603
+ if .schema_version == $schema then
604
+ {ts:.occurred_at,type:.event_type,sid:.session_id,org:.org_id,user:.actor_id,
605
+ data:(.metrics + {event_id:.event_id,schema_version:.schema_version,
606
+ artifact_ids:.artifact_ids,task_id:.task_id,org_revision:.org_revision,
607
+ index_spec_version:.index_spec_version,shared:true})}
608
+ else . end
609
+ ' "$BUFFER_FILE" > "$share_file"
328
610
  else
329
- echo '{"telemetry": false}' > "$STATE_FILE"
611
+ : > "$share_file"
612
+ fi
613
+
614
+ local curl_args=(-s -o /dev/null -w '%{http_code}' -X POST "$endpoint"
615
+ -H "Content-Type: application/x-ndjson" --data-binary "@$share_file" --max-time 15)
616
+ local api_key="" configured_endpoint=""
617
+ configured_endpoint=$(_resolve_share_target "" "false")
618
+ if [ -n "$configured_endpoint" ] && [ "$endpoint" = "$configured_endpoint" ] && [ -f "$ENV_FILE" ]; then
619
+ api_key=$(grep '^EGREGORE_API_KEY=' "$ENV_FILE" 2>/dev/null | cut -d'=' -f2- || true)
620
+ fi
621
+ [ -z "$api_key" ] || curl_args+=(-H "Authorization: Bearer $api_key")
622
+ local http_code="000"
623
+ http_code=$(curl "${curl_args[@]}" 2>/dev/null || echo "000")
624
+ rm -f "$share_file"
625
+ if [ "$http_code" -ge 200 ] 2>/dev/null && [ "$http_code" -lt 300 ] 2>/dev/null; then
626
+ rm -f "$SHARE_CONSENT_FILE"
627
+ echo "Shared $count telemetry events with $endpoint. Local events were retained."
628
+ else
629
+ echo "Share failed (HTTP $http_code). Nothing was removed locally." >&2
630
+ return 1
330
631
  fi
331
- echo "Telemetry disabled."
332
632
  }
333
633
 
334
- # --- clear: delete local buffer ---
335
- cmd_clear() {
336
- rm -f "$BUFFER_FILE"
337
- echo "Telemetry buffer cleared."
634
+ cmd_flush() {
635
+ # Compatibility boundary for old startup/session-end callers. Deliberately
636
+ # does no I/O so an unattended lifecycle hook can never grant share consent.
637
+ echo "Automatic telemetry sharing is disabled; use 'telemetry.sh share' explicitly." >&2
338
638
  }
339
639
 
340
- # --- show: display last N events ---
341
- cmd_show() {
342
- local n="${1:-10}"
343
- if [ ! -f "$BUFFER_FILE" ] || [ ! -s "$BUFFER_FILE" ]; then
344
- echo "No buffered events."
345
- return 0
346
- fi
347
- echo "Last $n events:"
640
+ cmd_help() {
641
+ echo "Usage: telemetry.sh <command>"
348
642
  echo ""
349
- # Extract JSON objects (handles both single-line and legacy multi-line format)
350
- grep '^{' "$BUFFER_FILE" | tail -n "$n" | jq -c . 2>/dev/null \
351
- || grep '^{' "$BUFFER_FILE" | tail -n "$n"
643
+ echo "Commands:"
644
+ echo " emit <type> <json> Append a validated event locally (no network)"
645
+ echo " status Show local collection status"
646
+ echo " inspect [n] Inspect the last N local events"
647
+ echo " export <path> Export the validated local dataset"
648
+ echo " share [options] Prepare or confirm an explicit share"
649
+ echo " enable | disable Change local collection setting"
650
+ echo " clear Delete the local buffer"
651
+ echo " flush Compatibility no-op; never uploads"
352
652
  }
353
653
 
354
- # --- Main dispatch ---
355
654
  case "${1:-status}" in
356
- emit)
357
- shift
358
- cmd_emit "$@"
359
- ;;
360
- flush)
361
- cmd_flush
362
- ;;
363
- status)
364
- cmd_status
365
- ;;
366
- enable)
367
- cmd_enable
368
- ;;
369
- disable)
370
- cmd_disable
371
- ;;
372
- clear)
373
- cmd_clear
374
- ;;
375
- show)
376
- shift
377
- cmd_show "${1:-10}"
378
- ;;
379
- help|*)
380
- echo "Usage: telemetry.sh <command>"
381
- echo ""
382
- echo "Commands:"
383
- echo " emit <type> <json> Append event to local buffer (no network)"
384
- echo " flush Send buffered events to API"
385
- echo " status Show telemetry status"
386
- echo " enable Enable telemetry"
387
- echo " disable Disable telemetry"
388
- echo " clear Clear local buffer"
389
- echo " show [n] Show last N events (default 10)"
390
- ;;
655
+ emit) shift; cmd_emit "$@" ;;
656
+ status) shift; cmd_status "$@" ;;
657
+ enable|on) cmd_enable ;;
658
+ disable|off) cmd_disable ;;
659
+ clear) cmd_clear ;;
660
+ inspect|show) shift; cmd_inspect "$@" ;;
661
+ export) shift; cmd_export "$@" ;;
662
+ share) shift; cmd_share "$@" ;;
663
+ flush) cmd_flush ;;
664
+ help|-h|--help) cmd_help ;;
665
+ *) cmd_help >&2; exit 2 ;;
391
666
  esac