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
@@ -0,0 +1,304 @@
1
+ """Look at a folder of documents before asking its owner anything about it.
2
+
3
+ Setting up a knowledge base needs three decisions: what must be kept apart, which
4
+ sources win when two disagree, and what language the documents are written in.
5
+ Asked cold, none of them are answerable. Someone who has just dropped a folder on
6
+ a machine cannot say "what must never mix" — the question is about a model of the
7
+ system, not about their files.
8
+
9
+ So this looks first. It reports the groups the folder already has, the kinds of
10
+ document inside it, and the language it can detect. The questions that follow can
11
+ then name the user's own directories and counts, and be answered yes or no.
12
+
13
+ Everything here is counting and pattern-matching. It proposes; it never decides.
14
+ Where it cannot tell — a language it does not recognise, a folder with no obvious
15
+ grouping — it says so, because a confident wrong grouping is harder to notice
16
+ than an admitted gap.
17
+ """
18
+
19
+ from __future__ import annotations
20
+
21
+ import re
22
+ from collections import Counter
23
+ from dataclasses import dataclass, field
24
+ from pathlib import Path
25
+
26
+ # Extensions worth reading. Anything else is counted and reported, not parsed.
27
+ DOCUMENT_SUFFIXES = {".pdf", ".md", ".txt", ".docx", ".doc", ".rtf", ".html", ".htm"}
28
+ CATALOGUE_SUFFIXES = {".csv", ".xlsx", ".xls", ".tsv"}
29
+
30
+ # A group needs enough documents to be worth separating. Below this it is noise —
31
+ # a stray folder, a scratch directory — and offering it as a boundary would ask
32
+ # the user to rule on something that does not matter.
33
+ MIN_GROUP = 5
34
+
35
+ # Short, very common words that are distinctive to one language. Detection here
36
+ # is deliberately crude: it only has to be right often enough to propose, and it
37
+ # reports nothing rather than guessing when the evidence is thin.
38
+ LANGUAGE_MARKERS = {
39
+ "turkish": {"ve", "ile", "için", "olarak", "bir", "bu", "daha", "gibi", "olan"},
40
+ "english": {"the", "and", "for", "with", "that", "this", "from", "are", "which"},
41
+ "german": {"und", "der", "die", "das", "mit", "für", "eine", "nicht", "auch"},
42
+ "french": {"les", "des", "est", "pour", "dans", "une", "sur", "que", "par"},
43
+ "spanish": {"los", "las", "por", "para", "con", "una", "que", "del", "como"},
44
+ "italian": {"che", "per", "con", "una", "del", "sono", "nella", "alla", "dei"},
45
+ }
46
+ WORD = re.compile(r"[^\W\d_]{2,}", re.UNICODE)
47
+
48
+
49
+ @dataclass
50
+ class Group:
51
+ """A directory holding enough documents to be worth keeping separate."""
52
+
53
+ name: str
54
+ path: str
55
+ documents: int
56
+
57
+ def as_dict(self) -> dict:
58
+ return {"name": self.name, "path": self.path, "documents": self.documents}
59
+
60
+
61
+ @dataclass
62
+ class Survey:
63
+ root: str = ""
64
+ documents: int = 0
65
+ unreadable: int = 0
66
+ groups: list = field(default_factory=list)
67
+ by_suffix: dict = field(default_factory=dict)
68
+ catalogues: list = field(default_factory=list)
69
+ language: str = "unknown"
70
+ language_evidence: dict = field(default_factory=dict)
71
+ language_by_group: dict = field(default_factory=dict)
72
+ sample_titles: list = field(default_factory=list)
73
+ notes: list = field(default_factory=list)
74
+
75
+ @property
76
+ def needs_a_boundary_question(self) -> bool:
77
+ """Whether separating anything is even plausible.
78
+
79
+ One group means there is nothing to keep apart, so asking would be a
80
+ question with one answer.
81
+ """
82
+ return len(self.groups) > 1
83
+
84
+ def as_dict(self) -> dict:
85
+ return {
86
+ "root": self.root,
87
+ "documents": self.documents,
88
+ "unreadable": self.unreadable,
89
+ "groups": [g.as_dict() for g in self.groups],
90
+ "by_suffix": self.by_suffix,
91
+ "catalogues": self.catalogues,
92
+ "language": self.language,
93
+ "language_evidence": self.language_evidence,
94
+ "language_by_group": self.language_by_group,
95
+ "sample_titles": self.sample_titles,
96
+ "notes": self.notes,
97
+ }
98
+
99
+
100
+ def detect_language(samples: list) -> tuple:
101
+ """The language of some text, or that it cannot be told.
102
+
103
+ Returns the name and the per-language hit counts, so a caller can show its
104
+ working rather than assert a result. A near-tie reports unknown: proposing
105
+ the wrong grammar produces a profile that silently finds no advice at all.
106
+ """
107
+ text = " ".join(samples).lower()
108
+ words = set(WORD.findall(text))
109
+ if len(words) < 20:
110
+ return "unknown", {}
111
+ scores = {lang: len(words & markers) for lang, markers in LANGUAGE_MARKERS.items()}
112
+ ranked = sorted(scores.items(), key=lambda kv: -kv[1])
113
+ best, best_score = ranked[0]
114
+ runner_score = ranked[1][1] if len(ranked) > 1 else 0
115
+ if best_score < 3 or best_score - runner_score < 2:
116
+ return "unknown", scores
117
+ return best, scores
118
+
119
+
120
+ def _read_head(path: Path, limit: int = 4000) -> str:
121
+ """A little text from a file, for language detection only.
122
+
123
+ PDFs are read too, because a corpus of documents is usually a corpus of
124
+ PDFs. Reading only the plain-text files looks like it works and does not:
125
+ measured on a real 922-document archive, every file but one was a PDF, so
126
+ the language of the whole corpus was decided by a single stray markdown
127
+ file that happened to be lying in it.
128
+
129
+ Only the first page is taken, and a failure is silent — this informs a
130
+ question the user will answer anyway, so it must never be the reason a
131
+ survey fails.
132
+ """
133
+ suffix = path.suffix.lower()
134
+ try:
135
+ if suffix in {".md", ".txt", ".html", ".htm"}:
136
+ return path.read_text(encoding="utf-8", errors="replace")[:limit]
137
+ if suffix == ".pdf":
138
+ import subprocess
139
+
140
+ out = subprocess.run(
141
+ ["pdftotext", "-f", "1", "-l", "1", "-q", str(path), "-"],
142
+ capture_output=True, text=True, timeout=15,
143
+ )
144
+ return (out.stdout or "")[:limit]
145
+ except (OSError, subprocess.SubprocessError, ValueError):
146
+ return ""
147
+ return ""
148
+
149
+
150
+ def survey(root, max_depth: int = 2, sample_files: int = 40) -> Survey:
151
+ """What is in this folder, described so its owner can recognise it."""
152
+ root_path = Path(root)
153
+ result = Survey(root=str(root_path))
154
+ if not root_path.is_dir():
155
+ result.notes.append(f"{root_path} is not a folder")
156
+ return result
157
+
158
+ suffixes: Counter = Counter()
159
+ per_group: Counter = Counter()
160
+ group_paths: dict = {}
161
+ samples: list = []
162
+ group_samples: dict = {}
163
+ titles: list = []
164
+
165
+ for path in root_path.rglob("*"):
166
+ if not path.is_file():
167
+ continue
168
+ # Any hidden component, not just a hidden filename. A folder holding
169
+ # documents usually sits beside .git or .egregore, and counting those
170
+ # would report machinery as content.
171
+ if any(part.startswith(".") for part in path.relative_to(root_path).parts):
172
+ continue
173
+ suffix = path.suffix.lower()
174
+ if suffix in CATALOGUE_SUFFIXES:
175
+ result.catalogues.append(path.relative_to(root_path).as_posix())
176
+ continue
177
+ suffixes[suffix or "(no extension)"] += 1
178
+ if suffix not in DOCUMENT_SUFFIXES:
179
+ result.unreadable += 1
180
+ continue
181
+ result.documents += 1
182
+
183
+ relative = path.relative_to(root_path)
184
+ # The group is the outermost directory that is not the root itself. Files
185
+ # sitting loose at the top belong to no group.
186
+ if len(relative.parts) > 1:
187
+ depth = min(max_depth, len(relative.parts) - 1)
188
+ key = "/".join(relative.parts[:depth])
189
+ per_group[key] += 1
190
+ group_paths[key] = key
191
+
192
+ if len(titles) < 8:
193
+ titles.append(relative.as_posix())
194
+ if len(samples) < sample_files:
195
+ head = _read_head(path)
196
+ if head:
197
+ samples.append(head)
198
+ if len(relative.parts) > 1:
199
+ head = _read_head(path, limit=1500)
200
+ if head and len(group_samples.setdefault(key, [])) < 6:
201
+ group_samples[key].append(head)
202
+
203
+ result.by_suffix = dict(sorted(suffixes.items(), key=lambda kv: -kv[1]))
204
+ result.sample_titles = titles
205
+ result.groups = [
206
+ Group(name=key.split("/")[-1], path=group_paths[key], documents=count)
207
+ for key, count in sorted(per_group.items(), key=lambda kv: -kv[1])
208
+ if count >= MIN_GROUP
209
+ ]
210
+ result.language, result.language_evidence = detect_language(samples)
211
+ for key, heads in group_samples.items():
212
+ lang, _ = detect_language(heads)
213
+ if lang != "unknown":
214
+ result.language_by_group[key] = lang
215
+ # A corpus in two languages needs two sets of grammar. Reporting the majority
216
+ # language would leave every document in the other one silently unread — and
217
+ # nothing downstream would say why they produced no advice.
218
+ distinct = set(result.language_by_group.values())
219
+ if len(distinct) > 1:
220
+ result.language = "mixed"
221
+ result.notes.append(
222
+ "documents are in more than one language (" + ", ".join(sorted(distinct)) +
223
+ "); each language needs its own grammar, or the others yield no advice")
224
+
225
+ if not result.documents:
226
+ result.notes.append("no readable documents found")
227
+ if result.unreadable:
228
+ result.notes.append(
229
+ f"{result.unreadable} files are not a document type this reads; they are ignored")
230
+ if result.documents and len(result.groups) < 2:
231
+ # Fewer than two groups means there is nothing to hold apart, whether
232
+ # that is because the folder is flat or because only one part of it is
233
+ # substantial.
234
+ result.notes.append(
235
+ "nothing here needs separating; one boundary value will cover everything")
236
+ if result.language == "unknown" and result.documents:
237
+ result.notes.append(
238
+ "could not tell the language from the text available — it must be stated, "
239
+ "because finding advice depends on the grammar of the language")
240
+ if result.catalogues:
241
+ result.notes.append(
242
+ f"found {len(result.catalogues)} spreadsheet(s) that may describe these documents")
243
+ return result
244
+
245
+
246
+ def boundary_question(result: Survey) -> dict | None:
247
+ """The separation question, phrased with the owner's own folder names.
248
+
249
+ Returns None when there is nothing to separate, so the caller asks nothing
250
+ rather than asking a question with one possible answer.
251
+ """
252
+ if not result.needs_a_boundary_question:
253
+ return None
254
+ names = [g.name for g in result.groups[:3]]
255
+ return {
256
+ "found": [g.as_dict() for g in result.groups],
257
+ "question": (
258
+ f"Your folders are {', '.join(names)}. Are these different SUBJECTS, "
259
+ f"or things that must never be mixed?\n\n"
260
+ f"Separating them means a question about {names[0]} can never be answered "
261
+ f"from {names[1]} — not even when that is where the answer is."
262
+ ),
263
+ # Together first: most folder structures are subjects, and separating
264
+ # subjects removes real answers. Keeping them apart is the choice that
265
+ # needs a reason, so it is the one stated second.
266
+ "options": [
267
+ {"label": "Subjects — keep them together",
268
+ "effect": "one boundary value for everything",
269
+ "example": "pruning, fertiliser, pests — a question may need any of them"},
270
+ {"label": f"Must not mix — separate {', '.join(names)}",
271
+ "effect": "one boundary value per folder",
272
+ "example": "one client's contract must never answer for another"},
273
+ ],
274
+ }
275
+
276
+
277
+ def trust_question(result: Survey) -> dict | None:
278
+ """The ranking question, listing what was actually found."""
279
+ if not result.groups:
280
+ return None
281
+ return {
282
+ "found": [g.as_dict() for g in result.groups],
283
+ "question": ("Two of these disagree about the same thing. Which should win?"),
284
+ "options": [{"label": g.name, "documents": g.documents} for g in result.groups[:4]]
285
+ + [{"label": "Don't know", "effect": "nothing is ranked above anything else"}],
286
+ }
287
+
288
+
289
+ def summarise(result: Survey) -> str:
290
+ """The survey as the owner reads it, before any question is asked."""
291
+ lines = [f"{result.documents:,} documents in {result.root}"]
292
+ if result.groups:
293
+ lines.append("")
294
+ lines.append("groups:")
295
+ for g in result.groups[:6]:
296
+ lines.append(f" {g.path:<40} {g.documents:>6,} documents")
297
+ if result.by_suffix:
298
+ kinds = ", ".join(f"{k} {v:,}" for k, v in list(result.by_suffix.items())[:5])
299
+ lines.append("")
300
+ lines.append(f"file types: {kinds}")
301
+ lines.append(f"language: {result.language}")
302
+ for note in result.notes:
303
+ lines.append(f" ! {note}")
304
+ return "\n".join(lines)
@@ -1,178 +1,18 @@
1
1
  #!/usr/bin/env bash
2
- # Fetches personal dashboard data: single API call + parallel git ops.
3
- # Usage: bash bin/dashboard-data.sh [username] [time_range]
4
- # Returns a single JSON object with all query results.
5
- #
6
- # time_range: P1D (today), P7D (week, default), P30D (month), P365D (all)
2
+ # One bounded, authorized, canonical Runtime snapshot for the dashboard ritual.
7
3
  set -euo pipefail
8
4
 
9
- SCRIPT_DIR="$(cd "$(dirname "$0")/.." && pwd)"
10
- TMPDIR=$(mktemp -d)
11
- trap "rm -rf $TMPDIR" EXIT
5
+ ROOT="$(cd "$(dirname "$0")/.." && pwd)"
6
+ TIME_RANGE="${2:-${1:-P7D}}"
12
7
 
13
- # --- Read config ---
14
- API_URL=$(jq -r '.api_url // empty' "$SCRIPT_DIR/egregore.json" 2>/dev/null)
15
- API_KEY=$(grep '^EGREGORE_API_KEY=' "$SCRIPT_DIR/.env" 2>/dev/null | cut -d'=' -f2- || true)
16
- ORG=$(jq -r '.org_name // "Egregore"' "$SCRIPT_DIR/egregore.json" 2>/dev/null || echo "Egregore")
17
- DATE=$(date '+%b %d')
18
-
19
- # --- Detect user ---
20
- GH_USER="${1:-}"
21
- if [ -z "$GH_USER" ]; then
22
- STATE_FILE="$SCRIPT_DIR/.egregore-state.json"
23
- if [ -f "$STATE_FILE" ]; then
24
- GH_USER=$(jq -r '.github_username // empty' "$STATE_FILE" 2>/dev/null)
25
- fi
26
- if [ -z "$GH_USER" ]; then
27
- GH_USER=$(git -C "$SCRIPT_DIR" config user.name 2>/dev/null || echo "unknown")
28
- fi
29
- fi
30
-
31
- # --- Time range (default P7D) ---
32
- TIME_RANGE="${2:-P7D}"
33
-
34
- # --- Read current session ID (client-side fallback for WAL-not-yet-drained) ---
35
- PROJ_HASH=$(echo -n "$SCRIPT_DIR" | md5 2>/dev/null || echo -n "$SCRIPT_DIR" | md5sum 2>/dev/null | cut -d' ' -f1)
36
- SESSION_ID=$(cat "$HOME/.egregore/session-${PROJ_HASH}.id" 2>/dev/null || echo "")
37
-
38
- # --- Fire API call + git ops in parallel ---
39
-
40
- # Graph data: single API call (all queries run server-side)
41
- (
42
- GRAPH_STATUS="offline"
43
- GRAPH_REASON=""
44
- if [ -z "$API_URL" ] || [ -z "$API_KEY" ]; then
45
- GRAPH_REASON="missing_config"
46
- else
47
- # Keep curl's transport status separate from %{http_code}; otherwise a
48
- # failed request can concatenate 000 + fallback text and look like an
49
- # unexpected API response.
50
- CURL_STATUS=0
51
- HTTP_CODE=$(curl -s -o "$TMPDIR/dashboard_raw.json" -w "%{http_code}" \
52
- "${API_URL}/api/personal/dashboard?github_username=$(printf '%s' "$GH_USER" | jq -sRr @uri)&time_range=$(printf '%s' "$TIME_RANGE" | jq -sRr @uri)&session_id=$(printf '%s' "$SESSION_ID" | jq -sRr @uri)" \
53
- -H "Authorization: Bearer $API_KEY" \
54
- --connect-timeout 5 --max-time 15 2>/dev/null) || CURL_STATUS=$?
55
-
56
- if [ "$CURL_STATUS" -ne 0 ] || [ "$HTTP_CODE" = "000" ] || ! [[ "$HTTP_CODE" =~ ^[0-9][0-9][0-9]$ ]]; then
57
- GRAPH_REASON="unreachable"
58
- elif [ "$HTTP_CODE" = "401" ] || [ "$HTTP_CODE" = "403" ]; then
59
- GRAPH_REASON="auth_error"
60
- elif [ "$HTTP_CODE" -ge 500 ] 2>/dev/null; then
61
- GRAPH_REASON="server_error"
62
- elif [ -s "$TMPDIR/dashboard_raw.json" ] && jq -e '.me' "$TMPDIR/dashboard_raw.json" >/dev/null 2>&1; then
63
- cp "$TMPDIR/dashboard_raw.json" "$TMPDIR/dashboard.json"
64
- GRAPH_STATUS="connected"
65
- else
66
- GRAPH_REASON="invalid_response"
67
- fi
68
- fi
69
-
70
- # If not connected, write status-only response
71
- if [ "$GRAPH_STATUS" != "connected" ]; then
72
- jq -n --arg status "$GRAPH_STATUS" --arg reason "$GRAPH_REASON" \
73
- '{graph_status: $status, graph_reason: $reason}' > "$TMPDIR/dashboard.json"
74
- else
75
- jq --arg status "$GRAPH_STATUS" '. + {graph_status: $status}' \
76
- "$TMPDIR/dashboard.json" > "$TMPDIR/dashboard_merged.json" \
77
- && mv "$TMPDIR/dashboard_merged.json" "$TMPDIR/dashboard.json"
78
- fi
79
- ) &
80
- API_PID=$!
81
-
82
- # Git: branch + dirty status (parallel, stays client-side)
83
- (
84
- CURRENT=$(git -C "$SCRIPT_DIR" branch --show-current 2>/dev/null || echo "unknown")
85
- DIRTY="false"
86
- if [ -n "$(git -C "$SCRIPT_DIR" status --porcelain 2>/dev/null | head -1)" ]; then
87
- DIRTY="true"
88
- fi
89
- jq -n --arg branch "$CURRENT" --argjson dirty "$DIRTY" \
90
- '{branch: $branch, dirty: $dirty}' > "$TMPDIR/git.json"
91
- ) &
92
- GIT_PID=$!
93
-
94
- # Local sessions: parse memory files when graph is offline (parallel)
95
- (
96
- GH_LC=$(echo "$GH_USER" | tr '[:upper:]' '[:lower:]')
97
- DISPLAY_LC=""
98
- if [ -f "$SCRIPT_DIR/.egregore-state.json" ]; then
99
- DISPLAY_LC=$(jq -r '.display_name // empty' "$SCRIPT_DIR/.egregore-state.json" 2>/dev/null | tr '[:upper:]' '[:lower:]')
100
- fi
101
-
102
- # Compute cutoff date from time range
103
- case "$TIME_RANGE" in
104
- P1D) CUTOFF=$(date -v-1d +%Y-%m-%d 2>/dev/null || date -d '1 day ago' +%Y-%m-%d 2>/dev/null || echo "2000-01-01") ;;
105
- P7D) CUTOFF=$(date -v-7d +%Y-%m-%d 2>/dev/null || date -d '7 days ago' +%Y-%m-%d 2>/dev/null || echo "2000-01-01") ;;
106
- P30D) CUTOFF=$(date -v-30d +%Y-%m-%d 2>/dev/null || date -d '30 days ago' +%Y-%m-%d 2>/dev/null || echo "2000-01-01") ;;
107
- P365D) CUTOFF="2000-01-01" ;;
108
- *) CUTOFF=$(date -v-7d +%Y-%m-%d 2>/dev/null || date -d '7 days ago' +%Y-%m-%d 2>/dev/null || echo "2000-01-01") ;;
109
- esac
110
-
111
- # Scan sessions, wraps, and handoffs for this user
112
- for DIR in "$SCRIPT_DIR/memory/sessions" "$SCRIPT_DIR/memory/wraps" "$SCRIPT_DIR/memory/handoffs"; do
113
- [ -d "$DIR" ] || continue
114
- TYPE=$(basename "$DIR")
115
- find -L "$DIR" -name '*.md' -not -name 'index*' -type f 2>/dev/null | xargs ls -t 2>/dev/null | head -20 | while read -r MFILE; do
116
- [ -z "$MFILE" ] && continue
117
- M_AUTH=$(head -10 "$MFILE" 2>/dev/null | grep -m1 '^\*\*Author\*\*:' | sed 's/^\*\*Author\*\*:[[:space:]]*//' || true)
118
- [ -z "$M_AUTH" ] && continue
119
- M_AUTH_LC=$(echo "$M_AUTH" | tr '[:upper:]' '[:lower:]')
120
- # Filter to this user only
121
- [ "$M_AUTH_LC" != "$GH_LC" ] && { [ -z "$DISPLAY_LC" ] || [ "$M_AUTH_LC" != "$DISPLAY_LC" ]; } && continue
122
- M_DATE=$(head -10 "$MFILE" 2>/dev/null | grep -m1 '^\*\*Date\*\*:' | sed 's/^\*\*Date\*\*:[[:space:]]*//' || true)
123
- M_DAY="${M_DATE%%T*}"
124
- [ -n "$M_DAY" ] && [ "$M_DAY" \< "$CUTOFF" ] && continue
125
- M_BRANCH=$(head -10 "$MFILE" 2>/dev/null | grep -m1 '^\*\*Branch\*\*:' | sed 's/^\*\*Branch\*\*:[[:space:]]*//' || true)
126
- M_DURATION=$(head -10 "$MFILE" 2>/dev/null | grep -m1 '^\*\*Duration\*\*:' | sed 's/^\*\*Duration\*\*:[[:space:]]*//' || true)
127
- M_TOPIC=$(head -3 "$MFILE" 2>/dev/null | grep -m1 '^# ' | sed 's/^# [^:]*:[[:space:]]*//' || true)
128
- echo "${M_DATE}|${M_TOPIC}|${M_BRANCH}|${M_DURATION}|${TYPE}"
129
- done
130
- done | jq -Rn '
131
- [inputs | split("|") |
132
- {date: .[0], topic: .[1], branch: .[2], duration: .[3], type: .[4]}
133
- ] | sort_by(.date) | reverse | {
134
- sessions: .,
135
- session_count: length
136
- }
137
- ' 2>/dev/null > "$TMPDIR/local_sessions.json" || echo '{"sessions":[],"session_count":0}' > "$TMPDIR/local_sessions.json"
138
- ) &
139
- LOCAL_PID=$!
140
-
141
- # --- Wait for all ---
142
- wait $API_PID $GIT_PID $LOCAL_PID 2>/dev/null || true
143
-
144
- # --- Read results ---
145
- GIT_INFO=$(cat "$TMPDIR/git.json" 2>/dev/null || echo '{"branch":"unknown","dirty":false}')
146
- BRANCH=$(echo "$GIT_INFO" | jq -r '.branch' 2>/dev/null || echo "unknown")
147
- LOCAL_SESSIONS=$(cat "$TMPDIR/local_sessions.json" 2>/dev/null || echo '{"sessions":[],"session_count":0}')
148
- echo "$LOCAL_SESSIONS" | jq . >/dev/null 2>&1 || LOCAL_SESSIONS='{"sessions":[],"session_count":0}'
149
-
150
- # --- Client-side current session fallback ---
151
- # If the graph returned no current_session (WAL hasn't drained yet),
152
- # inject one from the local session ID file so the TUI always renders it.
153
- DASHBOARD=$(cat "$TMPDIR/dashboard.json" 2>/dev/null || echo '{"graph_status":"offline"}')
154
- CS_ID=$(echo "$DASHBOARD" | jq -r '.current_session.id // empty' 2>/dev/null)
155
- if [ -z "$CS_ID" ] && [ -n "$SESSION_ID" ]; then
156
- DASHBOARD=$(echo "$DASHBOARD" | jq \
157
- --arg sid "$SESSION_ID" \
158
- --arg branch "$BRANCH" \
159
- '.current_session = {id: $sid, status: "active", topic: null, branch: $branch}' 2>/dev/null || echo "$DASHBOARD")
160
- fi
161
-
162
- # --- Derive time range label ---
8
+ # Keep the historical `[username] [range]` shape without treating a provider
9
+ # alias as identity. A recognized range in argv[1] is the new compact form.
163
10
  case "$TIME_RANGE" in
164
- P1D) RANGE_LABEL="today" ;;
165
- P7D) RANGE_LABEL="last 7 days" ;;
166
- P30D) RANGE_LABEL="last 30 days" ;;
167
- P365D) RANGE_LABEL="all time" ;;
168
- *) RANGE_LABEL="last 7 days" ;;
11
+ P1D|P7D|P30D|P365D) ;;
12
+ *) TIME_RANGE="P7D" ;;
169
13
  esac
170
14
 
171
- # --- Merge server response + local data ---
172
- echo "$DASHBOARD" | jq \
173
- --arg org "$ORG" \
174
- --arg date "$DATE" \
175
- --arg range_label "$RANGE_LABEL" \
176
- --argjson git "$GIT_INFO" \
177
- --argjson local_sessions "$LOCAL_SESSIONS" \
178
- '. + {org: $org, date: $date, range_label: $range_label, git: $git, local_sessions: $local_sessions}'
15
+ ARGS=(dashboard --time-range "$TIME_RANGE")
16
+ [ "${EGREGORE_STATUS_CONNECTED_ENRICH:-0}" = "1" ] && ARGS+=(--connected-enrichment)
17
+ EGREGORE_ROOT="$ROOT" PYTHONPATH="$ROOT${PYTHONPATH:+:$PYTHONPATH}" \
18
+ exec python3 -m egregore_runtime.status_cli "${ARGS[@]}"
@@ -0,0 +1,121 @@
1
+ #!/usr/bin/env bash
2
+ set -euo pipefail
3
+
4
+ SCRIPT_DIR="$(cd "$(dirname "$0")/.." && pwd)"
5
+
6
+ # Default: official Egregore GitHub App (Device Flow — Client ID is public by design)
7
+ # Override per-org via github_app_client_id in egregore.json
8
+ CLIENT_ID="Iv23li2obNsAjakoK2RE"
9
+ if [ -f "$SCRIPT_DIR/egregore.json" ]; then
10
+ _CUSTOM_ID=$(jq -r '.github_app_client_id // .github_oauth_client_id // empty' "$SCRIPT_DIR/egregore.json" 2>/dev/null || true)
11
+ [ -n "$_CUSTOM_ID" ] && CLIENT_ID="$_CUSTOM_ID"
12
+ fi
13
+
14
+ SCOPE="" # GitHub App — permissions managed via installation, not OAuth scope
15
+ TIMEOUT=300
16
+ ENV_FILE="$SCRIPT_DIR/.env"
17
+
18
+ # Request device code
19
+ response=$(curl -s -X POST "https://github.com/login/device/code" \
20
+ -H "Accept: application/json" \
21
+ -d "client_id=$CLIENT_ID&scope=$SCOPE")
22
+
23
+ device_code=$(echo "$response" | jq -r '.device_code')
24
+ user_code=$(echo "$response" | jq -r '.user_code')
25
+ verification_uri=$(echo "$response" | jq -r '.verification_uri')
26
+ verification_uri_complete=$(echo "$response" | jq -r '.verification_uri_complete // empty')
27
+ interval=$(echo "$response" | jq -r '.interval')
28
+
29
+ if [ "$device_code" = "null" ] || [ -z "$device_code" ]; then
30
+ echo "Failed to get device code from GitHub."
31
+ echo "$response" | jq . 2>/dev/null || echo "$response"
32
+ exit 1
33
+ fi
34
+
35
+ # Copy code to clipboard
36
+ if command -v pbcopy >/dev/null 2>&1; then
37
+ printf '%s' "$user_code" | pbcopy
38
+ echo ""
39
+ echo " Code copied to clipboard: $user_code"
40
+ echo " Opening your browser — just paste and hit Continue."
41
+ echo ""
42
+ elif command -v xclip >/dev/null 2>&1; then
43
+ printf '%s' "$user_code" | xclip -selection clipboard
44
+ echo ""
45
+ echo " Code copied to clipboard: $user_code"
46
+ echo " Opening your browser — just paste and hit Continue."
47
+ echo ""
48
+ else
49
+ echo ""
50
+ echo " Your code: $user_code"
51
+ echo " Opening your browser — enter the code above."
52
+ echo ""
53
+ fi
54
+
55
+ # Open browser — use verification_uri_complete if available, otherwise plain URI
56
+ url="${verification_uri_complete:-$verification_uri}"
57
+ echo " Opening your browser..."
58
+ echo " If it doesn't open, visit: $url"
59
+ echo ""
60
+ if command -v open >/dev/null 2>&1; then
61
+ open "$url"
62
+ elif command -v xdg-open >/dev/null 2>&1; then
63
+ xdg-open "$url"
64
+ fi
65
+
66
+ # Poll for authorization
67
+ elapsed=0
68
+ while [ "$elapsed" -lt "$TIMEOUT" ]; do
69
+ sleep "$interval"
70
+ elapsed=$((elapsed + interval))
71
+
72
+ token_response=$(curl -s -X POST "https://github.com/login/oauth/access_token" \
73
+ -H "Accept: application/json" \
74
+ -d "client_id=$CLIENT_ID&device_code=$device_code&grant_type=urn:ietf:params:oauth:grant-type:device_code")
75
+
76
+ error=$(echo "$token_response" | jq -r '.error // empty')
77
+ access_token=$(echo "$token_response" | jq -r '.access_token // empty')
78
+
79
+ if [ -n "$access_token" ]; then
80
+ # Write token to .env
81
+ if [ -f "$ENV_FILE" ] && grep -q '^GITHUB_TOKEN=' "$ENV_FILE"; then
82
+ # Replace existing token (portable: write to temp file, then move)
83
+ tmp="$ENV_FILE.tmp.$$"
84
+ while IFS= read -r line || [ -n "$line" ]; do
85
+ case "$line" in
86
+ GITHUB_TOKEN=*) echo "GITHUB_TOKEN=$access_token" ;;
87
+ *) echo "$line" ;;
88
+ esac
89
+ done < "$ENV_FILE" > "$tmp"
90
+ mv "$tmp" "$ENV_FILE"
91
+ else
92
+ echo "GITHUB_TOKEN=$access_token" >> "$ENV_FILE"
93
+ fi
94
+
95
+ # Configure git credential helper (local to this repo, not global)
96
+ git config credential.helper store
97
+ # Write credential for github.com
98
+ protocol_line="protocol=https
99
+ host=github.com
100
+ username=x-access-token
101
+ password=$access_token
102
+ "
103
+ echo "$protocol_line" | git credential-store store 2>/dev/null || true
104
+
105
+ echo " Authorized!"
106
+ exit 0
107
+ fi
108
+
109
+ case "$error" in
110
+ authorization_pending) continue ;;
111
+ slow_down) interval=$((interval + 5)) ;;
112
+ *)
113
+ echo " Authorization failed: $error"
114
+ echo "$token_response" | jq -r '.error_description // empty'
115
+ exit 1
116
+ ;;
117
+ esac
118
+ done
119
+
120
+ echo " Timed out waiting for authorization (${TIMEOUT}s)."
121
+ exit 1
@@ -17,6 +17,13 @@ if [ ! -f "$CONFIG" ]; then
17
17
  exit 1
18
18
  fi
19
19
 
20
+ # shellcheck source=bin/lib/config.sh
21
+ source "$SCRIPT_DIR/bin/lib/config.sh"
22
+ if ! _graph_projection_enabled; then
23
+ echo '{"results":[],"status":"disabled","reason":"graph_projection_disabled"}'
24
+ exit 0
25
+ fi
26
+
20
27
  # --- Local mode gate: bail immediately ---
21
28
  _MODE=$(jq -r '.mode // "connected"' "$CONFIG" 2>/dev/null)
22
29
  if [ "$_MODE" = "local" ]; then
@@ -70,6 +70,10 @@ fi
70
70
 
71
71
  GS="$SCRIPT_DIR/bin/graph.sh"
72
72
 
73
+ # Named reads are explicit projection requests by definition — they pass the
74
+ # Runtime cutover gate that silences background graph callers.
75
+ export EGREGORE_GRAPH_EXPLICIT=1
76
+
73
77
  OP="${1:-}"
74
78
  shift || true
75
79