oh-my-opencode 4.13.0 → 4.14.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (445) hide show
  1. package/.agents/skills/codex-qa/SKILL.md +15 -0
  2. package/.agents/skills/codex-qa/references/logging-debug.md +12 -0
  3. package/.agents/skills/opencode-qa/SKILL.md +17 -0
  4. package/.agents/skills/opencode-qa/references/tui-tmux.md +17 -0
  5. package/.agents/skills/work-with-pr/SKILL.md +18 -10
  6. package/.opencode/skills/work-with-pr/SKILL.md +18 -10
  7. package/README.md +2 -2
  8. package/dist/cli/doctor/checks/telemetry.d.ts +2 -0
  9. package/dist/cli/doctor/framework/constants.d.ts +1 -0
  10. package/dist/cli/doctor/framework/doctor-target.d.ts +1 -1
  11. package/dist/cli/index.js +24651 -16452
  12. package/dist/cli-node/index.js +24651 -16452
  13. package/dist/config/schema/oh-my-opencode-config.d.ts +1 -0
  14. package/dist/features/team-mode/test-support/async-test-helpers.d.ts +19 -0
  15. package/dist/hooks/atlas/final-wave-approval-gate.d.ts +1 -0
  16. package/dist/hooks/atlas/subagent-completion-reminder.d.ts +30 -0
  17. package/dist/hooks/atlas/types.d.ts +2 -0
  18. package/dist/hooks/atlas/verification-reminders.d.ts +3 -0
  19. package/dist/hooks/team-session-events/team-idle-wake-hint.d.ts +1 -0
  20. package/dist/index.d.ts +1 -0
  21. package/dist/index.js +33232 -19559
  22. package/dist/mcp/context7.d.ts +9 -8
  23. package/dist/oh-my-opencode.schema.json +4 -0
  24. package/dist/shared/posthog.d.ts +17 -10
  25. package/dist/shared/telemetry-product-identity.d.ts +2 -0
  26. package/dist/skills/coding-agent-sessions/SKILL.md +128 -0
  27. package/dist/skills/coding-agent-sessions/agents/openai.yaml +4 -0
  28. package/dist/skills/coding-agent-sessions/references/all-platforms.md +71 -0
  29. package/dist/skills/coding-agent-sessions/references/claude.md +32 -0
  30. package/dist/skills/coding-agent-sessions/references/codex.md +30 -0
  31. package/dist/skills/coding-agent-sessions/references/opencode.md +43 -0
  32. package/dist/skills/coding-agent-sessions/references/senpi.md +17 -0
  33. package/dist/skills/coding-agent-sessions/scripts/agent_sessions/__init__.py +1 -0
  34. package/dist/skills/coding-agent-sessions/scripts/agent_sessions/claude.py +66 -0
  35. package/dist/skills/coding-agent-sessions/scripts/agent_sessions/cli.py +283 -0
  36. package/dist/skills/coding-agent-sessions/scripts/agent_sessions/codex.py +105 -0
  37. package/dist/skills/coding-agent-sessions/scripts/agent_sessions/file_scanners.py +275 -0
  38. package/dist/skills/coding-agent-sessions/scripts/agent_sessions/jsonio.py +55 -0
  39. package/dist/skills/coding-agent-sessions/scripts/agent_sessions/kiro_scanner.py +91 -0
  40. package/dist/skills/coding-agent-sessions/scripts/agent_sessions/opencode.py +289 -0
  41. package/dist/skills/coding-agent-sessions/scripts/agent_sessions/scanners.py +92 -0
  42. package/dist/skills/coding-agent-sessions/scripts/agent_sessions/sqlite_optional_scanners.py +203 -0
  43. package/dist/skills/coding-agent-sessions/scripts/agent_sessions/sqlite_scanners.py +177 -0
  44. package/dist/skills/coding-agent-sessions/scripts/agent_sessions/timeparse.py +51 -0
  45. package/dist/skills/coding-agent-sessions/scripts/agent_sessions/transcript.py +149 -0
  46. package/dist/skills/coding-agent-sessions/scripts/agent_sessions/types.py +57 -0
  47. package/dist/skills/coding-agent-sessions/scripts/find-agent-sessions.py +19 -0
  48. package/dist/skills/frontend/ATTRIBUTION.md +52 -8
  49. package/dist/skills/frontend/SKILL.md +29 -8
  50. package/dist/skills/frontend/references/design/README.md +29 -12
  51. package/dist/skills/frontend/references/design/_INDEX.md +3 -3
  52. package/dist/skills/frontend/references/design/design-system-architecture.md +22 -19
  53. package/dist/skills/frontend/references/designpowers/EVIDENCE.md +89 -0
  54. package/dist/skills/frontend/references/designpowers/README.md +48 -0
  55. package/dist/skills/frontend/references/designpowers/UPSTREAM.md +80 -0
  56. package/dist/skills/frontend/references/designpowers/lane-a-direction.md +64 -0
  57. package/dist/skills/frontend/references/designpowers/lane-b-execution.md +65 -0
  58. package/dist/skills/frontend/references/designpowers/lane-c-review.md +65 -0
  59. package/dist/skills/frontend/references/designpowers/lane-d-memory.md +83 -0
  60. package/dist/skills/frontend/references/designpowers/orchestration.md +80 -0
  61. package/dist/skills/frontend/references/designpowers/routing.md +79 -0
  62. package/dist/skills/frontend/references/designpowers/vendor/LICENSE +21 -0
  63. package/dist/skills/frontend/references/designpowers/vendor/agents/accessibility-reviewer.md +83 -0
  64. package/dist/skills/frontend/references/designpowers/vendor/agents/content-writer.md +132 -0
  65. package/dist/skills/frontend/references/designpowers/vendor/agents/design-builder.md +109 -0
  66. package/dist/skills/frontend/references/designpowers/vendor/agents/design-critic.md +89 -0
  67. package/dist/skills/frontend/references/designpowers/vendor/agents/design-lead.md +113 -0
  68. package/dist/skills/frontend/references/designpowers/vendor/agents/design-scout.md +78 -0
  69. package/dist/skills/frontend/references/designpowers/vendor/agents/design-strategist.md +121 -0
  70. package/dist/skills/frontend/references/designpowers/vendor/agents/heuristic-evaluator.md +268 -0
  71. package/dist/skills/frontend/references/designpowers/vendor/agents/inspiration-scout.md +107 -0
  72. package/dist/skills/frontend/references/designpowers/vendor/agents/motion-designer.md +120 -0
  73. package/dist/skills/frontend/references/designpowers/vendor/skills/accessible-content/SKILL.md +101 -0
  74. package/dist/skills/frontend/references/designpowers/vendor/skills/adaptive-interfaces/SKILL.md +109 -0
  75. package/dist/skills/frontend/references/designpowers/vendor/skills/cognitive-accessibility/SKILL.md +107 -0
  76. package/dist/skills/frontend/references/designpowers/vendor/skills/design-debate/SKILL.md +199 -0
  77. package/dist/skills/frontend/references/designpowers/vendor/skills/design-debt-tracker/SKILL.md +174 -0
  78. package/dist/skills/frontend/references/designpowers/vendor/skills/design-handoff/SKILL.md +125 -0
  79. package/dist/skills/frontend/references/designpowers/vendor/skills/design-md/SKILL.md +106 -0
  80. package/dist/skills/frontend/references/designpowers/vendor/skills/design-retrospective/SKILL.md +266 -0
  81. package/dist/skills/frontend/references/designpowers/vendor/skills/design-review/SKILL.md +123 -0
  82. package/dist/skills/frontend/references/designpowers/vendor/skills/design-system-alignment/SKILL.md +120 -0
  83. package/dist/skills/frontend/references/designpowers/vendor/skills/designpowers-critique/SKILL.md +164 -0
  84. package/dist/skills/frontend/references/designpowers/vendor/skills/heuristic-evaluation/SKILL.md +85 -0
  85. package/dist/skills/frontend/references/designpowers/vendor/skills/inclusive-personas/SKILL.md +98 -0
  86. package/dist/skills/frontend/references/designpowers/vendor/skills/inspiration-scouting/SKILL.md +165 -0
  87. package/dist/skills/frontend/references/designpowers/vendor/skills/interaction-design/SKILL.md +122 -0
  88. package/dist/skills/frontend/references/designpowers/vendor/skills/motion-choreography/SKILL.md +81 -0
  89. package/dist/skills/frontend/references/designpowers/vendor/skills/research-planning/SKILL.md +96 -0
  90. package/dist/skills/frontend/references/designpowers/vendor/skills/responsive-patterns/SKILL.md +77 -0
  91. package/dist/skills/frontend/references/designpowers/vendor/skills/synthetic-user-testing/SKILL.md +192 -0
  92. package/dist/skills/frontend/references/designpowers/vendor/skills/taste-feedback/SKILL.md +165 -0
  93. package/dist/skills/frontend/references/designpowers/vendor/skills/taste-report/SKILL.md +78 -0
  94. package/dist/skills/frontend/references/designpowers/vendor/skills/token-architecture/SKILL.md +75 -0
  95. package/dist/skills/frontend/references/designpowers/vendor/skills/ui-composition/SKILL.md +117 -0
  96. package/dist/skills/frontend/references/designpowers/vendor/skills/usability-testing/SKILL.md +78 -0
  97. package/dist/skills/frontend/references/designpowers/vendor/skills/verification-before-shipping/SKILL.md +125 -0
  98. package/dist/skills/frontend/references/designpowers/vendor/skills/voice-and-tone/SKILL.md +79 -0
  99. package/dist/skills/frontend/references/designpowers/vendor/skills/writing-design-plans/SKILL.md +119 -0
  100. package/dist/skills/frontend/references/ui-ux-db/scripts/core.py +0 -0
  101. package/dist/skills/git-master/SKILL.md +4 -0
  102. package/dist/skills/review-work/SKILL.md +3 -3
  103. package/dist/skills/start-work/SKILL.md +7 -5
  104. package/dist/skills/ultraresearch/SKILL.md +4 -252
  105. package/dist/skills/ulw-plan/SKILL.md +8 -6
  106. package/dist/skills/ulw-plan/references/full-workflow.md +11 -6
  107. package/dist/skills/ulw-plan/references/intent-clear.md +3 -3
  108. package/dist/skills/ulw-plan/references/intent-unclear.md +1 -1
  109. package/dist/skills/{ultraresearch → ulw-research}/ATTRIBUTION.md +1 -1
  110. package/dist/skills/ulw-research/SKILL.md +260 -0
  111. package/dist/skills/visual-qa/SKILL.md +105 -14
  112. package/dist/skills/visual-qa/scripts/skill-prompt-contract.test.ts +120 -1
  113. package/dist/testing/create-plugin-module.d.ts +2 -0
  114. package/dist/tui.js +23917 -16117
  115. package/docs/reference/github-attachment-upload.md +51 -0
  116. package/docs/reference/web-terminal-visual-qa.md +81 -0
  117. package/package.json +20 -14
  118. package/packages/lsp-core/src/lsp/process.ts +4 -1
  119. package/packages/lsp-core/src/mcp.ts +1 -0
  120. package/packages/lsp-daemon/dist/cli.js +5 -1
  121. package/packages/lsp-daemon/dist/index.js +5 -1
  122. package/packages/lsp-daemon/dist/proxy.js +1 -0
  123. package/packages/lsp-tools-mcp/dist/cli.js +5 -1
  124. package/packages/lsp-tools-mcp/dist/lsp/manager.js +4 -1
  125. package/packages/lsp-tools-mcp/dist/mcp.js +5 -1
  126. package/packages/lsp-tools-mcp/dist/tools.js +4 -1
  127. package/packages/omo-codex/plugin/.codex-plugin/plugin.json +1 -1
  128. package/packages/omo-codex/plugin/components/bootstrap/dist/cli.js +323 -62
  129. package/packages/omo-codex/plugin/components/bootstrap/package.json +1 -1
  130. package/packages/omo-codex/plugin/components/bootstrap/scripts/bootstrap.ps1 +37 -68
  131. package/packages/omo-codex/plugin/components/bootstrap/scripts/node-dispatch.ps1 +75 -0
  132. package/packages/omo-codex/plugin/components/bootstrap/src/cli.ts +1 -1
  133. package/packages/omo-codex/plugin/components/bootstrap/src/setup.ts +2 -18
  134. package/packages/omo-codex/plugin/components/codegraph/dist/cli.js +575 -334
  135. package/packages/omo-codex/plugin/components/codegraph/dist/serve.js +204 -39
  136. package/packages/omo-codex/plugin/components/codegraph/package.json +2 -2
  137. package/packages/omo-codex/plugin/components/codegraph/src/hook-types.ts +7 -1
  138. package/packages/omo-codex/plugin/components/codegraph/src/hook.ts +103 -3
  139. package/packages/omo-codex/plugin/components/codegraph/src/mcp-bridge.ts +114 -0
  140. package/packages/omo-codex/plugin/components/codegraph/src/serve-invocation.ts +29 -0
  141. package/packages/omo-codex/plugin/components/codegraph/src/serve.ts +31 -57
  142. package/packages/omo-codex/plugin/components/codegraph/src/session-start-worker.ts +7 -4
  143. package/packages/omo-codex/plugin/components/codegraph/test/hook.test.ts +43 -9
  144. package/packages/omo-codex/plugin/components/codegraph/test/serve-mcp-bridge.test.ts +146 -0
  145. package/packages/omo-codex/plugin/components/codegraph/test/serve.test.ts +12 -7
  146. package/packages/omo-codex/plugin/components/codegraph/test/session-start-worker-flow.test.ts +71 -1
  147. package/packages/omo-codex/plugin/components/comment-checker/package.json +1 -1
  148. package/packages/omo-codex/plugin/components/git-bash/package.json +1 -1
  149. package/packages/omo-codex/plugin/components/lazycodex-executor-verify/package.json +1 -1
  150. package/packages/omo-codex/plugin/components/lsp/dist/cli.js +4 -1
  151. package/packages/omo-codex/plugin/components/lsp/package.json +1 -1
  152. package/packages/omo-codex/plugin/components/rules/dist/cli.js +2 -2
  153. package/packages/omo-codex/plugin/components/rules/package.json +1 -1
  154. package/packages/omo-codex/plugin/components/rules/src/sparkshell-awareness.ts +2 -2
  155. package/packages/omo-codex/plugin/components/rules/test/sparkshell-awareness.test.ts +11 -2
  156. package/packages/omo-codex/plugin/components/start-work-continuation/directive.md +6 -6
  157. package/packages/omo-codex/plugin/components/start-work-continuation/package.json +1 -1
  158. package/packages/omo-codex/plugin/components/start-work-continuation/test/codex-hook.test.ts +23 -0
  159. package/packages/omo-codex/plugin/components/teammode/dist/cli.js +22 -4
  160. package/packages/omo-codex/plugin/components/teammode/package.json +1 -1
  161. package/packages/omo-codex/plugin/components/teammode/skills/teammode/SKILL.md +40 -2
  162. package/packages/omo-codex/plugin/components/teammode/skills/teammode/scripts/team-guide.mjs +32 -5
  163. package/packages/omo-codex/plugin/components/teammode/skills/teammode/scripts/team.mjs +7 -3
  164. package/packages/omo-codex/plugin/components/teammode/src/codex-hook.ts +19 -4
  165. package/packages/omo-codex/plugin/components/teammode/test/thread-title-hook.test.ts +32 -2
  166. package/packages/omo-codex/plugin/components/telemetry/package.json +1 -1
  167. package/packages/omo-codex/plugin/components/ultrawork/README.md +1 -1
  168. package/packages/omo-codex/plugin/components/ultrawork/agents/explorer.toml +1 -1
  169. package/packages/omo-codex/plugin/components/ultrawork/agents/plan.toml +2 -2
  170. package/packages/omo-codex/plugin/components/ultrawork/directive.md +23 -7
  171. package/packages/omo-codex/plugin/components/ultrawork/dist/cli.js +1 -1
  172. package/packages/omo-codex/plugin/components/ultrawork/package.json +1 -1
  173. package/packages/omo-codex/plugin/components/ultrawork/skills/ulw-plan/SKILL.md +6 -4
  174. package/packages/omo-codex/plugin/components/ultrawork/skills/ulw-plan/references/full-workflow.md +11 -6
  175. package/packages/omo-codex/plugin/components/ultrawork/skills/ulw-plan/references/intent-clear.md +3 -3
  176. package/packages/omo-codex/plugin/components/ultrawork/skills/ulw-plan/references/intent-unclear.md +1 -1
  177. package/packages/omo-codex/plugin/components/ultrawork/src/codex-hook.ts +1 -1
  178. package/packages/omo-codex/plugin/components/ultrawork/test/codex-hook-trigger-policy.test.ts +24 -0
  179. package/packages/omo-codex/plugin/components/ultrawork/test/package-smoke.test.ts +6 -1
  180. package/packages/omo-codex/plugin/components/ulw-loop/AGENTS.md +1 -1
  181. package/packages/omo-codex/plugin/components/ulw-loop/README.md +25 -21
  182. package/packages/omo-codex/plugin/components/ulw-loop/biome.json +1 -1
  183. package/packages/omo-codex/plugin/components/ulw-loop/directive.md +381 -0
  184. package/packages/omo-codex/plugin/components/ulw-loop/dist/cli-steering.js +14 -1
  185. package/packages/omo-codex/plugin/components/ulw-loop/dist/cli.js +145 -14
  186. package/packages/omo-codex/plugin/components/ulw-loop/dist/codex-hook.d.ts +6 -3
  187. package/packages/omo-codex/plugin/components/ulw-loop/dist/codex-hook.js +16 -6
  188. package/packages/omo-codex/plugin/components/ulw-loop/dist/ultrawork-directive.d.ts +5 -0
  189. package/packages/omo-codex/plugin/components/ulw-loop/dist/ultrawork-directive.js +104 -0
  190. package/packages/omo-codex/plugin/components/ulw-loop/hooks/hooks.json +1 -1
  191. package/packages/omo-codex/plugin/components/ulw-loop/package.json +2 -1
  192. package/packages/omo-codex/plugin/components/ulw-loop/skills/ulw-loop/references/full-workflow.md +19 -11
  193. package/packages/omo-codex/plugin/components/ulw-loop/src/cli-steering.ts +14 -1
  194. package/packages/omo-codex/plugin/components/ulw-loop/src/cli.ts +4 -2
  195. package/packages/omo-codex/plugin/components/ulw-loop/src/codex-hook.ts +28 -6
  196. package/packages/omo-codex/plugin/components/ulw-loop/src/ultrawork-directive.ts +113 -0
  197. package/packages/omo-codex/plugin/components/ulw-loop/test/cli-entrypoint.test.ts +33 -2
  198. package/packages/omo-codex/plugin/components/ulw-loop/test/cli-steering-kind-guidance.test.ts +31 -0
  199. package/packages/omo-codex/plugin/components/ulw-loop/test/codex-hook.test.ts +13 -0
  200. package/packages/omo-codex/plugin/components/ulw-loop/test/package-smoke.test.ts +36 -0
  201. package/packages/omo-codex/plugin/components/ulw-loop/test/skill-contract.test.ts +12 -0
  202. package/packages/omo-codex/plugin/components/ulw-loop/test/ultrawork-directive.test.ts +64 -0
  203. package/packages/omo-codex/plugin/hooks/post-compact-resetting-git-bash-mcp-reminder.json +2 -1
  204. package/packages/omo-codex/plugin/hooks/post-compact-resetting-lsp-diagnostics-cache.json +2 -1
  205. package/packages/omo-codex/plugin/hooks/post-compact-resetting-project-rule-cache.json +2 -1
  206. package/packages/omo-codex/plugin/hooks/post-tool-use-checking-codegraph-init-guidance.json +2 -1
  207. package/packages/omo-codex/plugin/hooks/post-tool-use-checking-comments.json +2 -1
  208. package/packages/omo-codex/plugin/hooks/post-tool-use-checking-lsp-diagnostics.json +2 -1
  209. package/packages/omo-codex/plugin/hooks/post-tool-use-checking-thread-title-hygiene.json +2 -1
  210. package/packages/omo-codex/plugin/hooks/post-tool-use-matching-project-rules.json +2 -1
  211. package/packages/omo-codex/plugin/hooks/pre-tool-use-enforcing-unlimited-goal-budget.json +2 -1
  212. package/packages/omo-codex/plugin/hooks/pre-tool-use-recommending-git-bash-mcp.json +2 -1
  213. package/packages/omo-codex/plugin/hooks/session-start-checking-auto-update.json +2 -1
  214. package/packages/omo-codex/plugin/hooks/session-start-checking-codegraph-bootstrap.json +2 -1
  215. package/packages/omo-codex/plugin/hooks/session-start-loading-project-rules.json +2 -1
  216. package/packages/omo-codex/plugin/hooks/session-start-recording-session-telemetry.json +2 -1
  217. package/packages/omo-codex/plugin/hooks/stop-checking-start-work-continuation.json +2 -1
  218. package/packages/omo-codex/plugin/hooks/subagent-stop-checking-start-work-continuation.json +2 -1
  219. package/packages/omo-codex/plugin/hooks/subagent-stop-verifying-lazycodex-executor-evidence.json +2 -1
  220. package/packages/omo-codex/plugin/hooks/user-prompt-submit-checking-ultrawork-trigger.json +2 -1
  221. package/packages/omo-codex/plugin/hooks/user-prompt-submit-checking-ulw-loop-steering.json +2 -1
  222. package/packages/omo-codex/plugin/hooks/user-prompt-submit-loading-project-rules.json +2 -1
  223. package/packages/omo-codex/plugin/package-lock.json +13 -13
  224. package/packages/omo-codex/plugin/package.json +1 -1
  225. package/packages/omo-codex/plugin/scripts/auto-update.mjs +9 -5
  226. package/packages/omo-codex/plugin/scripts/materialize-shared-upstreams.mjs +1 -0
  227. package/packages/omo-codex/plugin/scripts/migrate-codex-config/context7-placeholder-guard.mjs +131 -0
  228. package/packages/omo-codex/plugin/scripts/migrate-codex-config/multi-agent-mode-guard.mjs +60 -0
  229. package/packages/omo-codex/plugin/scripts/migrate-codex-config/multi-agent-v2-guard.mjs +3 -10
  230. package/packages/omo-codex/plugin/scripts/migrate-codex-config/root-settings.mjs +31 -1
  231. package/packages/omo-codex/plugin/scripts/migrate-codex-config/subagent-limit-guard.mjs +73 -0
  232. package/packages/omo-codex/plugin/scripts/migrate-codex-config.mjs +20 -3
  233. package/packages/omo-codex/plugin/scripts/sync-skills.mjs +30 -8
  234. package/packages/omo-codex/plugin/skills/coding-agent-sessions/SKILL.md +128 -0
  235. package/packages/omo-codex/plugin/skills/coding-agent-sessions/agents/openai.yaml +4 -0
  236. package/packages/omo-codex/plugin/skills/coding-agent-sessions/references/all-platforms.md +71 -0
  237. package/packages/omo-codex/plugin/skills/coding-agent-sessions/references/claude.md +32 -0
  238. package/packages/omo-codex/plugin/skills/coding-agent-sessions/references/codex.md +30 -0
  239. package/packages/omo-codex/plugin/skills/coding-agent-sessions/references/opencode.md +43 -0
  240. package/packages/omo-codex/plugin/skills/coding-agent-sessions/references/senpi.md +17 -0
  241. package/packages/omo-codex/plugin/skills/coding-agent-sessions/scripts/agent_sessions/__init__.py +1 -0
  242. package/packages/omo-codex/plugin/skills/coding-agent-sessions/scripts/agent_sessions/claude.py +66 -0
  243. package/packages/omo-codex/plugin/skills/coding-agent-sessions/scripts/agent_sessions/cli.py +283 -0
  244. package/packages/omo-codex/plugin/skills/coding-agent-sessions/scripts/agent_sessions/codex.py +105 -0
  245. package/packages/omo-codex/plugin/skills/coding-agent-sessions/scripts/agent_sessions/file_scanners.py +275 -0
  246. package/packages/omo-codex/plugin/skills/coding-agent-sessions/scripts/agent_sessions/jsonio.py +55 -0
  247. package/packages/omo-codex/plugin/skills/coding-agent-sessions/scripts/agent_sessions/kiro_scanner.py +91 -0
  248. package/packages/omo-codex/plugin/skills/coding-agent-sessions/scripts/agent_sessions/opencode.py +289 -0
  249. package/packages/omo-codex/plugin/skills/coding-agent-sessions/scripts/agent_sessions/scanners.py +92 -0
  250. package/packages/omo-codex/plugin/skills/coding-agent-sessions/scripts/agent_sessions/sqlite_optional_scanners.py +203 -0
  251. package/packages/omo-codex/plugin/skills/coding-agent-sessions/scripts/agent_sessions/sqlite_scanners.py +177 -0
  252. package/packages/omo-codex/plugin/skills/coding-agent-sessions/scripts/agent_sessions/timeparse.py +51 -0
  253. package/packages/omo-codex/plugin/skills/coding-agent-sessions/scripts/agent_sessions/transcript.py +149 -0
  254. package/packages/omo-codex/plugin/skills/coding-agent-sessions/scripts/agent_sessions/types.py +57 -0
  255. package/packages/omo-codex/plugin/skills/coding-agent-sessions/scripts/find-agent-sessions.py +19 -0
  256. package/packages/omo-codex/plugin/skills/frontend/ATTRIBUTION.md +52 -8
  257. package/packages/omo-codex/plugin/skills/frontend/SKILL.md +29 -8
  258. package/packages/omo-codex/plugin/skills/frontend/references/design/README.md +29 -12
  259. package/packages/omo-codex/plugin/skills/frontend/references/design/_INDEX.md +3 -3
  260. package/packages/omo-codex/plugin/skills/frontend/references/design/design-system-architecture.md +22 -19
  261. package/packages/omo-codex/plugin/skills/frontend/references/designpowers/EVIDENCE.md +89 -0
  262. package/packages/omo-codex/plugin/skills/frontend/references/designpowers/README.md +48 -0
  263. package/packages/omo-codex/plugin/skills/frontend/references/designpowers/UPSTREAM.md +80 -0
  264. package/packages/omo-codex/plugin/skills/frontend/references/designpowers/lane-a-direction.md +64 -0
  265. package/packages/omo-codex/plugin/skills/frontend/references/designpowers/lane-b-execution.md +65 -0
  266. package/packages/omo-codex/plugin/skills/frontend/references/designpowers/lane-c-review.md +65 -0
  267. package/packages/omo-codex/plugin/skills/frontend/references/designpowers/lane-d-memory.md +83 -0
  268. package/packages/omo-codex/plugin/skills/frontend/references/designpowers/orchestration.md +80 -0
  269. package/packages/omo-codex/plugin/skills/frontend/references/designpowers/routing.md +79 -0
  270. package/packages/omo-codex/plugin/skills/frontend/references/designpowers/vendor/LICENSE +21 -0
  271. package/packages/omo-codex/plugin/skills/frontend/references/designpowers/vendor/agents/accessibility-reviewer.md +83 -0
  272. package/packages/omo-codex/plugin/skills/frontend/references/designpowers/vendor/agents/content-writer.md +132 -0
  273. package/packages/omo-codex/plugin/skills/frontend/references/designpowers/vendor/agents/design-builder.md +109 -0
  274. package/packages/omo-codex/plugin/skills/frontend/references/designpowers/vendor/agents/design-critic.md +89 -0
  275. package/packages/omo-codex/plugin/skills/frontend/references/designpowers/vendor/agents/design-lead.md +113 -0
  276. package/packages/omo-codex/plugin/skills/frontend/references/designpowers/vendor/agents/design-scout.md +78 -0
  277. package/packages/omo-codex/plugin/skills/frontend/references/designpowers/vendor/agents/design-strategist.md +121 -0
  278. package/packages/omo-codex/plugin/skills/frontend/references/designpowers/vendor/agents/heuristic-evaluator.md +268 -0
  279. package/packages/omo-codex/plugin/skills/frontend/references/designpowers/vendor/agents/inspiration-scout.md +107 -0
  280. package/packages/omo-codex/plugin/skills/frontend/references/designpowers/vendor/agents/motion-designer.md +120 -0
  281. package/packages/omo-codex/plugin/skills/frontend/references/designpowers/vendor/skills/accessible-content/SKILL.md +101 -0
  282. package/packages/omo-codex/plugin/skills/frontend/references/designpowers/vendor/skills/adaptive-interfaces/SKILL.md +109 -0
  283. package/packages/omo-codex/plugin/skills/frontend/references/designpowers/vendor/skills/cognitive-accessibility/SKILL.md +107 -0
  284. package/packages/omo-codex/plugin/skills/frontend/references/designpowers/vendor/skills/design-debate/SKILL.md +199 -0
  285. package/packages/omo-codex/plugin/skills/frontend/references/designpowers/vendor/skills/design-debt-tracker/SKILL.md +174 -0
  286. package/packages/omo-codex/plugin/skills/frontend/references/designpowers/vendor/skills/design-handoff/SKILL.md +125 -0
  287. package/packages/omo-codex/plugin/skills/frontend/references/designpowers/vendor/skills/design-md/SKILL.md +106 -0
  288. package/packages/omo-codex/plugin/skills/frontend/references/designpowers/vendor/skills/design-retrospective/SKILL.md +266 -0
  289. package/packages/omo-codex/plugin/skills/frontend/references/designpowers/vendor/skills/design-review/SKILL.md +123 -0
  290. package/packages/omo-codex/plugin/skills/frontend/references/designpowers/vendor/skills/design-system-alignment/SKILL.md +120 -0
  291. package/packages/omo-codex/plugin/skills/frontend/references/designpowers/vendor/skills/designpowers-critique/SKILL.md +164 -0
  292. package/packages/omo-codex/plugin/skills/frontend/references/designpowers/vendor/skills/heuristic-evaluation/SKILL.md +85 -0
  293. package/packages/omo-codex/plugin/skills/frontend/references/designpowers/vendor/skills/inclusive-personas/SKILL.md +98 -0
  294. package/packages/omo-codex/plugin/skills/frontend/references/designpowers/vendor/skills/inspiration-scouting/SKILL.md +165 -0
  295. package/packages/omo-codex/plugin/skills/frontend/references/designpowers/vendor/skills/interaction-design/SKILL.md +122 -0
  296. package/packages/omo-codex/plugin/skills/frontend/references/designpowers/vendor/skills/motion-choreography/SKILL.md +81 -0
  297. package/packages/omo-codex/plugin/skills/frontend/references/designpowers/vendor/skills/research-planning/SKILL.md +96 -0
  298. package/packages/omo-codex/plugin/skills/frontend/references/designpowers/vendor/skills/responsive-patterns/SKILL.md +77 -0
  299. package/packages/omo-codex/plugin/skills/frontend/references/designpowers/vendor/skills/synthetic-user-testing/SKILL.md +192 -0
  300. package/packages/omo-codex/plugin/skills/frontend/references/designpowers/vendor/skills/taste-feedback/SKILL.md +165 -0
  301. package/packages/omo-codex/plugin/skills/frontend/references/designpowers/vendor/skills/taste-report/SKILL.md +78 -0
  302. package/packages/omo-codex/plugin/skills/frontend/references/designpowers/vendor/skills/token-architecture/SKILL.md +75 -0
  303. package/packages/omo-codex/plugin/skills/frontend/references/designpowers/vendor/skills/ui-composition/SKILL.md +117 -0
  304. package/packages/omo-codex/plugin/skills/frontend/references/designpowers/vendor/skills/usability-testing/SKILL.md +78 -0
  305. package/packages/omo-codex/plugin/skills/frontend/references/designpowers/vendor/skills/verification-before-shipping/SKILL.md +125 -0
  306. package/packages/omo-codex/plugin/skills/frontend/references/designpowers/vendor/skills/voice-and-tone/SKILL.md +79 -0
  307. package/packages/omo-codex/plugin/skills/frontend/references/designpowers/vendor/skills/writing-design-plans/SKILL.md +119 -0
  308. package/packages/omo-codex/plugin/skills/frontend/references/ui-ux-db/scripts/core.py +0 -0
  309. package/packages/omo-codex/plugin/skills/git-master/SKILL.md +4 -0
  310. package/packages/omo-codex/plugin/skills/init-deep/SKILL.md +4 -0
  311. package/packages/omo-codex/plugin/skills/refactor/SKILL.md +4 -0
  312. package/packages/omo-codex/plugin/skills/remove-ai-slops/SKILL.md +4 -0
  313. package/packages/omo-codex/plugin/skills/review-work/SKILL.md +12 -4
  314. package/packages/omo-codex/plugin/skills/start-work/SKILL.md +14 -8
  315. package/packages/omo-codex/plugin/skills/teammode/SKILL.md +40 -2
  316. package/packages/omo-codex/plugin/skills/teammode/scripts/team-guide.mjs +32 -5
  317. package/packages/omo-codex/plugin/skills/teammode/scripts/team.mjs +7 -3
  318. package/packages/omo-codex/plugin/skills/ultraresearch/SKILL.md +4 -250
  319. package/packages/omo-codex/plugin/skills/ulw-loop/references/full-workflow.md +19 -11
  320. package/packages/omo-codex/plugin/skills/ulw-plan/SKILL.md +6 -4
  321. package/packages/omo-codex/plugin/skills/ulw-plan/references/full-workflow.md +11 -6
  322. package/packages/omo-codex/plugin/skills/ulw-plan/references/intent-clear.md +3 -3
  323. package/packages/omo-codex/plugin/skills/ulw-plan/references/intent-unclear.md +1 -1
  324. package/packages/{shared-skills/skills/ultraresearch → omo-codex/plugin/skills/ulw-research}/ATTRIBUTION.md +1 -1
  325. package/packages/omo-codex/plugin/skills/ulw-research/SKILL.md +262 -0
  326. package/packages/omo-codex/plugin/skills/ulw-research/agents/openai.yaml +2 -0
  327. package/packages/omo-codex/plugin/skills/visual-qa/SKILL.md +109 -14
  328. package/packages/omo-codex/plugin/test/aggregate-hooks.test.mjs +23 -0
  329. package/packages/omo-codex/plugin/test/aggregate-manifest.test.mjs +1 -0
  330. package/packages/omo-codex/plugin/test/auto-update-release-notes.test.mjs +1 -0
  331. package/packages/omo-codex/plugin/test/auto-update-restart-notice.test.mjs +24 -1
  332. package/packages/omo-codex/plugin/test/bootstrap-binlinks.test.mjs +23 -5
  333. package/packages/omo-codex/plugin/test/bootstrap-hooks.test.mjs +38 -0
  334. package/packages/omo-codex/plugin/test/bootstrap-ps-guard.test.mjs +25 -0
  335. package/packages/omo-codex/plugin/test/bootstrap-setup.test.mjs +1 -7
  336. package/packages/omo-codex/plugin/test/migrate-codex-config.test.mjs +206 -6
  337. package/packages/omo-codex/plugin/test/subagent-limit-migration.test.mjs +44 -0
  338. package/packages/omo-codex/plugin/test/sync-skills-orchestration.test.mjs +50 -1
  339. package/packages/omo-codex/plugin/test/sync-skills-test-support.mjs +10 -7
  340. package/packages/omo-codex/plugin/test/sync-skills.test.mjs +28 -2
  341. package/packages/omo-codex/plugin/test/teammode-communication.test.mjs +20 -0
  342. package/packages/omo-codex/plugin/test/teammode-thread-links.test.mjs +117 -0
  343. package/packages/omo-codex/plugin/test/teammode-worktree.test.mjs +5 -2
  344. package/packages/omo-codex/plugin/test/ulw-research-skill-contract.test.mjs +285 -0
  345. package/packages/omo-codex/scripts/install-bin-links.test.mjs +6 -1
  346. package/packages/omo-codex/scripts/install-cache-copy.test.mjs +51 -0
  347. package/packages/omo-codex/scripts/install-config.test.mjs +198 -17
  348. package/packages/omo-codex/scripts/install-dist/install-local.mjs +701 -282
  349. package/packages/omo-codex/scripts/install-local-git-bash-preflight.test.mjs +24 -15
  350. package/packages/omo-codex/scripts/install-local.test.mjs +5 -1
  351. package/packages/omo-codex/scripts/install-mcp-context7-runtime.test.mjs +84 -0
  352. package/packages/shared-skills/skills/coding-agent-sessions/SKILL.md +128 -0
  353. package/packages/shared-skills/skills/coding-agent-sessions/agents/openai.yaml +4 -0
  354. package/packages/shared-skills/skills/coding-agent-sessions/references/all-platforms.md +71 -0
  355. package/packages/shared-skills/skills/coding-agent-sessions/references/claude.md +32 -0
  356. package/packages/shared-skills/skills/coding-agent-sessions/references/codex.md +30 -0
  357. package/packages/shared-skills/skills/coding-agent-sessions/references/opencode.md +43 -0
  358. package/packages/shared-skills/skills/coding-agent-sessions/references/senpi.md +17 -0
  359. package/packages/shared-skills/skills/coding-agent-sessions/scripts/agent_sessions/__init__.py +1 -0
  360. package/packages/shared-skills/skills/coding-agent-sessions/scripts/agent_sessions/claude.py +66 -0
  361. package/packages/shared-skills/skills/coding-agent-sessions/scripts/agent_sessions/cli.py +283 -0
  362. package/packages/shared-skills/skills/coding-agent-sessions/scripts/agent_sessions/codex.py +105 -0
  363. package/packages/shared-skills/skills/coding-agent-sessions/scripts/agent_sessions/file_scanners.py +275 -0
  364. package/packages/shared-skills/skills/coding-agent-sessions/scripts/agent_sessions/jsonio.py +55 -0
  365. package/packages/shared-skills/skills/coding-agent-sessions/scripts/agent_sessions/kiro_scanner.py +91 -0
  366. package/packages/shared-skills/skills/coding-agent-sessions/scripts/agent_sessions/opencode.py +289 -0
  367. package/packages/shared-skills/skills/coding-agent-sessions/scripts/agent_sessions/scanners.py +92 -0
  368. package/packages/shared-skills/skills/coding-agent-sessions/scripts/agent_sessions/sqlite_optional_scanners.py +203 -0
  369. package/packages/shared-skills/skills/coding-agent-sessions/scripts/agent_sessions/sqlite_scanners.py +177 -0
  370. package/packages/shared-skills/skills/coding-agent-sessions/scripts/agent_sessions/timeparse.py +51 -0
  371. package/packages/shared-skills/skills/coding-agent-sessions/scripts/agent_sessions/transcript.py +149 -0
  372. package/packages/shared-skills/skills/coding-agent-sessions/scripts/agent_sessions/types.py +57 -0
  373. package/packages/shared-skills/skills/coding-agent-sessions/scripts/find-agent-sessions.py +19 -0
  374. package/packages/shared-skills/skills/frontend/ATTRIBUTION.md +52 -8
  375. package/packages/shared-skills/skills/frontend/SKILL.md +29 -8
  376. package/packages/shared-skills/skills/frontend/references/design/README.md +29 -12
  377. package/packages/shared-skills/skills/frontend/references/design/_INDEX.md +3 -3
  378. package/packages/shared-skills/skills/frontend/references/design/design-system-architecture.md +22 -19
  379. package/packages/shared-skills/skills/frontend/references/designpowers/EVIDENCE.md +89 -0
  380. package/packages/shared-skills/skills/frontend/references/designpowers/README.md +48 -0
  381. package/packages/shared-skills/skills/frontend/references/designpowers/UPSTREAM.md +80 -0
  382. package/packages/shared-skills/skills/frontend/references/designpowers/lane-a-direction.md +64 -0
  383. package/packages/shared-skills/skills/frontend/references/designpowers/lane-b-execution.md +65 -0
  384. package/packages/shared-skills/skills/frontend/references/designpowers/lane-c-review.md +65 -0
  385. package/packages/shared-skills/skills/frontend/references/designpowers/lane-d-memory.md +83 -0
  386. package/packages/shared-skills/skills/frontend/references/designpowers/orchestration.md +80 -0
  387. package/packages/shared-skills/skills/frontend/references/designpowers/routing.md +79 -0
  388. package/packages/shared-skills/skills/frontend/references/designpowers/vendor/LICENSE +21 -0
  389. package/packages/shared-skills/skills/frontend/references/designpowers/vendor/agents/accessibility-reviewer.md +83 -0
  390. package/packages/shared-skills/skills/frontend/references/designpowers/vendor/agents/content-writer.md +132 -0
  391. package/packages/shared-skills/skills/frontend/references/designpowers/vendor/agents/design-builder.md +109 -0
  392. package/packages/shared-skills/skills/frontend/references/designpowers/vendor/agents/design-critic.md +89 -0
  393. package/packages/shared-skills/skills/frontend/references/designpowers/vendor/agents/design-lead.md +113 -0
  394. package/packages/shared-skills/skills/frontend/references/designpowers/vendor/agents/design-scout.md +78 -0
  395. package/packages/shared-skills/skills/frontend/references/designpowers/vendor/agents/design-strategist.md +121 -0
  396. package/packages/shared-skills/skills/frontend/references/designpowers/vendor/agents/heuristic-evaluator.md +268 -0
  397. package/packages/shared-skills/skills/frontend/references/designpowers/vendor/agents/inspiration-scout.md +107 -0
  398. package/packages/shared-skills/skills/frontend/references/designpowers/vendor/agents/motion-designer.md +120 -0
  399. package/packages/shared-skills/skills/frontend/references/designpowers/vendor/skills/accessible-content/SKILL.md +101 -0
  400. package/packages/shared-skills/skills/frontend/references/designpowers/vendor/skills/adaptive-interfaces/SKILL.md +109 -0
  401. package/packages/shared-skills/skills/frontend/references/designpowers/vendor/skills/cognitive-accessibility/SKILL.md +107 -0
  402. package/packages/shared-skills/skills/frontend/references/designpowers/vendor/skills/design-debate/SKILL.md +199 -0
  403. package/packages/shared-skills/skills/frontend/references/designpowers/vendor/skills/design-debt-tracker/SKILL.md +174 -0
  404. package/packages/shared-skills/skills/frontend/references/designpowers/vendor/skills/design-handoff/SKILL.md +125 -0
  405. package/packages/shared-skills/skills/frontend/references/designpowers/vendor/skills/design-md/SKILL.md +106 -0
  406. package/packages/shared-skills/skills/frontend/references/designpowers/vendor/skills/design-retrospective/SKILL.md +266 -0
  407. package/packages/shared-skills/skills/frontend/references/designpowers/vendor/skills/design-review/SKILL.md +123 -0
  408. package/packages/shared-skills/skills/frontend/references/designpowers/vendor/skills/design-system-alignment/SKILL.md +120 -0
  409. package/packages/shared-skills/skills/frontend/references/designpowers/vendor/skills/designpowers-critique/SKILL.md +164 -0
  410. package/packages/shared-skills/skills/frontend/references/designpowers/vendor/skills/heuristic-evaluation/SKILL.md +85 -0
  411. package/packages/shared-skills/skills/frontend/references/designpowers/vendor/skills/inclusive-personas/SKILL.md +98 -0
  412. package/packages/shared-skills/skills/frontend/references/designpowers/vendor/skills/inspiration-scouting/SKILL.md +165 -0
  413. package/packages/shared-skills/skills/frontend/references/designpowers/vendor/skills/interaction-design/SKILL.md +122 -0
  414. package/packages/shared-skills/skills/frontend/references/designpowers/vendor/skills/motion-choreography/SKILL.md +81 -0
  415. package/packages/shared-skills/skills/frontend/references/designpowers/vendor/skills/research-planning/SKILL.md +96 -0
  416. package/packages/shared-skills/skills/frontend/references/designpowers/vendor/skills/responsive-patterns/SKILL.md +77 -0
  417. package/packages/shared-skills/skills/frontend/references/designpowers/vendor/skills/synthetic-user-testing/SKILL.md +192 -0
  418. package/packages/shared-skills/skills/frontend/references/designpowers/vendor/skills/taste-feedback/SKILL.md +165 -0
  419. package/packages/shared-skills/skills/frontend/references/designpowers/vendor/skills/taste-report/SKILL.md +78 -0
  420. package/packages/shared-skills/skills/frontend/references/designpowers/vendor/skills/token-architecture/SKILL.md +75 -0
  421. package/packages/shared-skills/skills/frontend/references/designpowers/vendor/skills/ui-composition/SKILL.md +117 -0
  422. package/packages/shared-skills/skills/frontend/references/designpowers/vendor/skills/usability-testing/SKILL.md +78 -0
  423. package/packages/shared-skills/skills/frontend/references/designpowers/vendor/skills/verification-before-shipping/SKILL.md +125 -0
  424. package/packages/shared-skills/skills/frontend/references/designpowers/vendor/skills/voice-and-tone/SKILL.md +79 -0
  425. package/packages/shared-skills/skills/frontend/references/designpowers/vendor/skills/writing-design-plans/SKILL.md +119 -0
  426. package/packages/shared-skills/skills/frontend/references/ui-ux-db/scripts/core.py +0 -0
  427. package/packages/shared-skills/skills/git-master/SKILL.md +4 -0
  428. package/packages/shared-skills/skills/review-work/SKILL.md +3 -3
  429. package/packages/shared-skills/skills/start-work/SKILL.md +7 -5
  430. package/packages/shared-skills/skills/ultraresearch/SKILL.md +4 -252
  431. package/packages/shared-skills/skills/ulw-plan/SKILL.md +8 -6
  432. package/packages/shared-skills/skills/ulw-plan/references/full-workflow.md +11 -6
  433. package/packages/shared-skills/skills/ulw-plan/references/intent-clear.md +3 -3
  434. package/packages/shared-skills/skills/ulw-plan/references/intent-unclear.md +1 -1
  435. package/packages/{omo-codex/plugin/skills/ultraresearch → shared-skills/skills/ulw-research}/ATTRIBUTION.md +1 -1
  436. package/packages/shared-skills/skills/ulw-research/SKILL.md +260 -0
  437. package/packages/shared-skills/skills/visual-qa/SKILL.md +105 -14
  438. package/packages/shared-skills/skills/visual-qa/scripts/skill-prompt-contract.test.ts +120 -1
  439. package/script/qa/web-terminal-redaction.d.mts +13 -0
  440. package/script/qa/web-terminal-redaction.mjs +43 -0
  441. package/script/qa/web-terminal-renderer.mjs +218 -0
  442. package/script/qa/web-terminal-visual-qa.mjs +264 -0
  443. package/packages/omo-codex/plugin/skills/ultimate-browsing/scripts/tests/test_cookie_domain_filter.py +0 -110
  444. package/packages/omo-codex/plugin/skills/ultimate-browsing/scripts/tests/test_extract_cookies.py +0 -245
  445. package/packages/omo-codex/plugin/test/ultraresearch-skill-contract.test.mjs +0 -204
@@ -0,0 +1,71 @@
1
+ # Cross-Platform Session Search
2
+
3
+ ## Default locations
4
+
5
+ Search these first, then add user-supplied roots with `--root`:
6
+
7
+ Registered platform keys: `codex`, `claude`, `senpi`, `opencode`, `openclaw`, `droid`, `amp`, `gemini`, `kimi`, `qwen`, `codebuff`, `roo-code`, `kilo-code`, `cline`, `kodu`, `cursor-cli`, `aider`, `kilo-cli`, `hermes`, `goose`, `crush`, `zed`, `kiro`.
8
+
9
+ | Platform | Unix/macOS | Windows |
10
+ |---|---|---|
11
+ | Codex | `$CODEX_HOME`, `~/.codex` | `%CODEX_HOME%`, `%USERPROFILE%\.codex` |
12
+ | Claude | `~/.claude` | `%USERPROFILE%\.claude`, `%APPDATA%\Claude` |
13
+ | Senpi / pi | `~/.senpi/agent`, `~/.pi/agent` | `%USERPROFILE%\.senpi\agent`, `%USERPROFILE%\.pi\agent` |
14
+ | OpenCode | `$OPENCODE_HOME`, `~/.opencode`, `~/.local/share/opencode` | `%OPENCODE_HOME%`, `%APPDATA%\opencode`, `%USERPROFILE%\.opencode` |
15
+ | OpenClaw | `~/.openclaw/agents/*/sessions`, `~/.openclaw/session-backups` | pass `--root` |
16
+ | Factory Droid | `~/.factory/sessions/*/*.jsonl` | pass `--root` |
17
+ | Amp | `~/.local/share/amp/threads/T-*.json` | pass `--root` |
18
+ | Gemini / Kimi / Qwen | `~/.gemini/tmp/*/chats`, `~/.kimi/sessions/*/*/wire.jsonl`, `~/.qwen/projects/*/chats` | pass `--root` |
19
+ | Codebuff | `~/.config/manicode*/projects/*/chats/*/chat-messages.json` | pass `--root` |
20
+ | Roo Code (`roo-code`) / Kilo Code (`kilo-code`) / Cline | VS Code `globalStorage/<extension>/tasks/*` | VS Code `globalStorage\<extension>\tasks\*` |
21
+ | Kodu | VS Code `globalStorage/kodu-ai.claude-dev-experimental/db/Azad.db` | VS Code `globalStorage\kodu-ai.claude-dev-experimental\db\Azad.db` |
22
+ | Cursor CLI | `~/.cursor/chats/*/*/store.db`, `~/.cursor/prompt_history.json` | `%USERPROFILE%\.cursor\chats` |
23
+ | Aider | bounded project roots containing `.aider.chat.history.md`; use `--root` for other repos | pass `--root` |
24
+ | Kilo CLI (`kilo-cli`) / Hermes / Goose / Crush / Zed | Known SQLite roots are probed cheaply; unsupported schemas return empty | pass `--root` |
25
+ | Kiro | `~/.kiro/sessions/cli/*.json` plus paired `*.jsonl` prompt events | pass `--root` |
26
+
27
+ ## Excluded usage-only sources
28
+
29
+ Do not add these as default transcript platforms without a separate prompt-reconstruction source:
30
+
31
+ | Source | Why excluded |
32
+ |---|---|
33
+ | Copilot OTEL | Token/telemetry rows, not prompts |
34
+ | Mux | `session-usage.json` usage buckets only |
35
+ | Antigravity | tokscale cache/RPC data, not raw chat transcripts |
36
+ | Synthetic | Provider retagging over another platform, not an independent session store |
37
+ | Cursor IDE usage CSV | Usage accounting; use `cursor-cli` for local CLI chat stores |
38
+
39
+ ## Workflow
40
+
41
+ 1. Run `scripts/find-agent-sessions.py search <query>` across all platforms, or repeat `--query` for several searches in one scan. Add `--include-subagents` when the work may have run inside a delegated agent — child transcripts are excluded from `list`/`search` by default.
42
+ 2. If results are noisy, add `--cwd`, `--model`, `--from`, or repeated `--platform` filters.
43
+ 3. Run `get <session-id>` on likely hits. The result includes a `subagents` array: every child session (Claude Task/workflow agents, Codex thread spawns, OpenCode child sessions) with its own id, `agent` label, and raw path — follow up with `get <child-id>` for a child's events.
44
+ 4. Open raw `path` files for exact quotes, tool calls, and evidence.
45
+
46
+ ## Subagent linkage cheat sheet
47
+
48
+ | Platform | Child identity | Parent linkage | Agent label |
49
+ |---|---|---|---|
50
+ | Claude | `projects/<proj>/<sid>/subagents/**/agent-<agentId>.jsonl` | directory `<sid>` | `agent-*.meta.json` `agentType` |
51
+ | Codex | thread row + own rollout JSONL | `thread_spawn_edges` / `source.subagent.thread_spawn.parent_thread_id` | `agent_nickname (agent_role)` |
52
+ | OpenCode | `session` table row / `storage/session/**.json` | `parent_id` column / `parentID` field | `agent` column |
53
+
54
+ ## Parallelism
55
+
56
+ The finder scans selected platforms concurrently, parses transcript files concurrently, joins OpenCode message/part files concurrently, and evaluates repeated `--query` values concurrently. Increase `--workers` for large local stores:
57
+
58
+ ```bash
59
+ python3 scripts/find-agent-sessions.py search --query "commit" --query "deploy" --workers 64
60
+ python3 scripts/find-agent-sessions.py search --query "commit" --platform senpi --platform opencode --workers 64
61
+ ```
62
+
63
+ Omit `--platform` for the full multi-platform search. Add repeated platform flags such as `--platform openclaw --platform droid` only when the user already knows the likely stores. Comma-separated platform values are intentionally unsupported.
64
+
65
+ The default scan is intentionally probe-first: optional platforms check for exact store roots before globbing or opening files. This avoids expensive home-wide searches while still making newly installed local agents visible without changing the command.
66
+
67
+ OpenCode is optimized differently from raw JSONL stores: it calls `opencode db path`, reads the SQLite session table directly, falls back to `opencode session list --format json`, and only scans `messages/` / `parts/` when the DB/CLI is unavailable or explicit `--root` values force a file-store lookup.
68
+
69
+ ## Evidence rule
70
+
71
+ Never answer "what happened in a session" from the normalized preview alone. Use the preview to locate candidates, then inspect the raw transcript or `get` output.
@@ -0,0 +1,32 @@
1
+ # Claude Session Stores
2
+
3
+ Observed Claude formats:
4
+
5
+ - `~/.claude/projects/<encoded-cwd>/*.jsonl`: Claude Code project sessions (main sessions; filename = session ID).
6
+ - `~/.claude/transcripts/ses_*.jsonl`: compact transcript exports with simple `type`, `timestamp`, `content`, and tool fields.
7
+ - `~/.claude/pre-compact-session-histories/*.jsonl`: pre-compaction histories with `sessionId`, `cwd`, `message`, `uuid`, `parentUuid`, and tool result metadata.
8
+
9
+ For project files, `sessionId`, `cwd`, `version`, `gitBranch`, and `message.model` are usually embedded in each line. For transcript exports, the filename may be the only stable session ID.
10
+
11
+ When reconstructing a Claude session, preserve the event order from the JSONL file and distinguish assistant text, thinking, tool use, tool result, and progress events.
12
+
13
+ ## Subagent transcripts (per-session directory)
14
+
15
+ Each main session may own a sibling directory named after the session ID:
16
+
17
+ ```
18
+ projects/<encoded-cwd>/<session-id>/
19
+ ├── subagents/
20
+ │ ├── agent-<agentId>.jsonl # Task-tool subagent transcript
21
+ │ ├── agent-<agentId>.meta.json # {"agentType", "description", "toolUseId"}
22
+ │ └── workflows/wf_<id>/
23
+ │ ├── agent-<agentId>.jsonl # Workflow-spawned agent transcripts
24
+ │ ├── agent-<agentId>.meta.json
25
+ │ └── journal.jsonl # workflow orchestration journal — NOT a session
26
+ ├── workflows/wf_<id>.json # workflow run metadata
27
+ └── tool-results/*.txt # persisted oversized tool outputs
28
+ ```
29
+
30
+ Subagent JSONL lines look like main-session lines but carry `isSidechain: true`, `agentId`, `promptId`, and `sessionId` pointing at the PARENT session — never treat a subagent file's `sessionId` as its own identity; use the `agentId` (also in the filename) and take the parent from the directory path. The first line's user message is the delegated task prompt; `agent-*.meta.json` gives the human-readable `description` and `agentType`.
31
+
32
+ The finder models these as `platform: claude` sessions with `id = <agentId>`, `parent_id = <session-id>`, `agent = agentType`. `get <main-session-id>` lists them under `subagents`; `get <agentId>` returns the child transcript events. Older Claude Code versions inlined sidechains in the main JSONL (`isSidechain: true` lines) instead of separate files.
@@ -0,0 +1,30 @@
1
+ # Codex Sessions
2
+
3
+ Codex has two useful surfaces:
4
+
5
+ - `$CODEX_HOME/state_*.sqlite` stores thread metadata.
6
+ - `$CODEX_HOME/sessions/**/rollout-*.jsonl` and archived rollout files store event transcripts.
7
+
8
+ Use the broad finder for Codex discovery:
9
+
10
+ ```bash
11
+ python3 scripts/find-agent-sessions.py list --platform codex --limit 10
12
+ python3 scripts/find-agent-sessions.py search "deploy" --platform codex
13
+ python3 scripts/find-agent-sessions.py search --query "deploy" --query "token usage" --platform codex --workers 32
14
+ python3 scripts/find-agent-sessions.py get <session-id> --platform codex
15
+ ```
16
+
17
+ Important filters: `--from`, `--to`, `--cwd`, `--model`, `--root`, `--limit`, and `--include-subagents`.
18
+
19
+ ## Spawned (subagent) threads
20
+
21
+ Codex subagent threads are ordinary rows in `threads` with their own rollout files. Two linkage sources:
22
+
23
+ - `thread_spawn_edges(parent_thread_id, child_thread_id, status)` — authoritative parent→child table.
24
+ - `threads.source` — `cli` / `exec` / `vscode` for user-started threads, or JSON for spawned ones:
25
+ - `{"subagent": "review"}`, `{"subagent": "memory_consolidation"}` — built-in side threads.
26
+ - `{"subagent": {"thread_spawn": {"parent_thread_id": "...", "depth": 1, "agent_nickname": "Tesla", "agent_role": "explorer"}}}` — collab/multi-agent spawns (depth can exceed 1: children spawn grandchildren).
27
+
28
+ `threads` also carries `agent_nickname`, `agent_role`, `model`, `first_user_message`, `tokens_used`. Without the SQLite DB, the same linkage is in each rollout file's first line: `type: "session_meta"` whose `payload` has `id`, `cwd`, `model_provider`, `forked_from_id`, and the same `source.subagent.thread_spawn` object.
29
+
30
+ The finder maps these to `parent_id` and `agent = "nickname (role)"`; `get <parent-thread-id>` lists children under `subagents`, and `get <child-thread-id>` returns the child's rollout events.
@@ -0,0 +1,43 @@
1
+ # OpenCode Session Stores
2
+
3
+ ## Fast path
4
+
5
+ Prefer the OpenCode CLI index before touching session files:
6
+
7
+ ```bash
8
+ opencode db path
9
+ sqlite3 "$(opencode db path)" 'select id, title, directory, time_updated from session order by time_updated desc limit 2000'
10
+ opencode session list --format json --max-count 100
11
+ ```
12
+
13
+ Use direct SQLite via `opencode db path` for ordinary `list` and title/session-ID/cwd searches. It queries OpenCode's own indexed session database and avoids expensive scans across `messages/` and `parts/`. Use `opencode session list --format json` as the next fallback when direct DB access is unavailable.
14
+
15
+ Only fall back to file joins when `opencode` is not installed, the command fails, or the user passes an explicit `--root` for a nonstandard store.
16
+
17
+ ## Subagent (child) sessions
18
+
19
+ Child sessions spawned by the task tool / subagents are ordinary rows in the `session` table:
20
+
21
+ - `session.parent_id` — parent session ID (`NULL` for main sessions). Tens of thousands of child rows are normal.
22
+ - `session.agent` — subagent name (`explore`, `plan`, `librarian`, `Sisyphus-Junior`, ...).
23
+ - Child titles often end with the convention `"... (@<agent> subagent)"`.
24
+
25
+ ```bash
26
+ sqlite3 "$(opencode db path)" "select id, agent, title from session where parent_id='<parent-id>' order by time_created"
27
+ ```
28
+
29
+ In the file store, the same linkage is the `parentID` field of `storage/session/<project-hash>/ses_*.json` info files. The finder surfaces children with `parent_id` + `agent` set; `get <parent-id>` lists them under `subagents`.
30
+
31
+ ## File fallback
32
+
33
+ Observed OpenCode layouts vary by version:
34
+
35
+ - `~/.opencode/messages/ses_*/*.json`: message metadata.
36
+ - `~/.opencode/parts/msg_*/*.json`: message parts, including text and synthetic compaction context.
37
+ - `~/.opencode/sessions/**`: newer session indexes or compatibility storage.
38
+ - `~/.local/share/opencode/storage/session/<project-hash>/ses_*.json`: session info files (`id`, `parentID`, `title`, `directory`, `time.created/updated`) — sibling `storage/message/` and `storage/part/` (singular) dirs hold content.
39
+ - `~/.local/share/opencode/storage/**`: older or Linux/XDG storage, often with session/message JSON or SQLite-backed data.
40
+
41
+ Message metadata usually contains `sessionID`, `role`, `time.created`, `agent`, `model.providerID`, `model.modelID`, and `path.cwd`. Text content may live in `parts/<message-id>/*.json`.
42
+
43
+ When answering from OpenCode, join messages to parts by `messageID` and order by `time.created` or part time. Compaction injections are useful for continuity but should be labeled as synthetic.
@@ -0,0 +1,17 @@
1
+ # Senpi / pi Coding-Agent Sessions
2
+
3
+ Observed Senpi layout:
4
+
5
+ - `~/.senpi/agent/sessions/<encoded-cwd>/<timestamp>_<uuid>.jsonl`
6
+ - `~/.senpi/agent/settings.json`, `models.json`, and `auth.json` provide environment context.
7
+ - `~/.pi/agent/sessions/**` can use the same family of JSONL formats.
8
+
9
+ Common event types:
10
+
11
+ - `session`: includes `id`, `timestamp`, and `cwd`.
12
+ - `model_change`: includes `provider` and `modelId`.
13
+ - `thinking_level_change`: includes effort metadata.
14
+ - `message`: wraps provider-native messages, tool calls, usage, and costs.
15
+ - `custom` with `customType: senpi.todo-state`: stores todo state.
16
+
17
+ Prefer Senpi usage fields when present: `usage.input`, `usage.output`, `usage.cacheRead`, `usage.cacheWrite`, `usage.totalTokens`, and `usage.cost.total`.
@@ -0,0 +1,66 @@
1
+ from __future__ import annotations
2
+
3
+ from concurrent.futures import ThreadPoolExecutor, as_completed
4
+ from pathlib import Path
5
+
6
+ from .jsonio import as_map, iter_jsonl, read_json, text
7
+ from .timeparse import file_time
8
+ from .transcript import content_text, env_path, existing, jsonl_parallel, recent
9
+ from .types import Session
10
+
11
+
12
+ def scan_claude(extra_roots: tuple[Path, ...], workers: int) -> list[Session]:
13
+ appdata = env_path("APPDATA")
14
+ roots = existing([Path.home() / ".claude", *(path / "Claude" for path in (appdata,) if path is not None), *extra_roots])
15
+ mains: list[Path] = []
16
+ subagents: list[Path] = []
17
+ for root in roots:
18
+ mains.extend((root / "transcripts").glob("*.jsonl"))
19
+ mains.extend((root / "projects").glob("*/*.jsonl"))
20
+ mains.extend((root / "pre-compact-session-histories").glob("*.jsonl"))
21
+ subagents.extend((root / "projects").glob("*/*/subagents/**/agent-*.jsonl"))
22
+ sessions = jsonl_parallel(recent(mains), workers, "claude", lambda path: path.stem)
23
+ sessions.extend(_subagent_parallel(recent(subagents), workers))
24
+ return sessions
25
+
26
+
27
+ def _subagent_parallel(paths: list[Path], workers: int) -> list[Session]:
28
+ if not paths:
29
+ return []
30
+ sessions: list[Session] = []
31
+ with ThreadPoolExecutor(max_workers=min(workers, max(len(paths), 1))) as pool:
32
+ futures = [pool.submit(_subagent_session, path) for path in paths]
33
+ for future in as_completed(futures):
34
+ session = future.result()
35
+ if session is not None:
36
+ sessions.append(session)
37
+ return sessions
38
+
39
+
40
+ def _subagent_session(path: Path) -> Session | None:
41
+ parts = path.parts
42
+ if "subagents" not in parts:
43
+ return None
44
+ parent_sid = parts[parts.index("subagents") - 1]
45
+ meta = as_map(read_json(path.with_name(path.stem + ".meta.json"))) or {}
46
+ first = next(iter_jsonl(path), None) or {}
47
+ message = as_map(first.get("message")) or {}
48
+ description = text(meta.get("description")) or ""
49
+ task = content_text(message.get("content"))
50
+ prompt = "\n".join(part for part in (description, task) if part)
51
+ created = text(first.get("timestamp")) or file_time(path)
52
+ return Session(
53
+ "claude",
54
+ path.stem.removeprefix("agent-"),
55
+ str(path),
56
+ text(first.get("cwd")),
57
+ created,
58
+ file_time(path) or created,
59
+ None,
60
+ None,
61
+ prompt,
62
+ {},
63
+ parent_sid,
64
+ text(meta.get("agentType")),
65
+ prompt,
66
+ )
@@ -0,0 +1,283 @@
1
+ from __future__ import annotations
2
+
3
+ import os
4
+ from concurrent.futures import ThreadPoolExecutor, as_completed
5
+ from pathlib import Path
6
+
7
+ from .jsonio import as_map, dumps, iter_jsonl
8
+ from .scanners import DEFAULT_PLATFORMS, scan
9
+ from .timeparse import date_bound, parse_stamp
10
+ from .transcript import user_text
11
+ from .types import Json, JsonMap, Options, Session
12
+
13
+
14
+ def main() -> int:
15
+ command, opts, rest = _parse()
16
+ sessions = sorted(scan(opts.platforms, opts.roots, opts.workers), key=lambda item: item.created_at or "", reverse=True)
17
+ if command == "list":
18
+ _emit(_list_payload(_filter(sessions, opts), sessions, opts.limit, include_subagents=opts.include_subagents))
19
+ return 0
20
+ if command == "search":
21
+ queries = _queries(opts, rest)
22
+ _require(list(queries), "search requires a query")
23
+ _emit(_search_payload(_filter(sessions, opts), sessions, queries, opts.limit, opts.workers, include_subagents=opts.include_subagents))
24
+ return 0
25
+ if command == "get":
26
+ _require(rest, "read requires at least one session id")
27
+ _emit(_get_payload(sessions, rest))
28
+ return 0
29
+ raise SystemExit(f"unknown command: {command}")
30
+
31
+
32
+ def _parse() -> tuple[str, Options, list[str]]:
33
+ import sys
34
+
35
+ args = sys.argv[1:]
36
+ if not args or args[0] in {"-h", "--help"}:
37
+ usage = (
38
+ "Usage: find-agent-sessions.py list|find|search|read|get [query|ids...] [--query TEXT ...] "
39
+ "[--platform NAME ...] [--root PATH] [--from DATE] [--to DATE] [--cwd TEXT] "
40
+ "[--model TEXT] [--limit N] [--workers N] [--include-subagents]"
41
+ )
42
+ print(usage)
43
+ raise SystemExit(0)
44
+ command = args.pop(0)
45
+ if command == "find":
46
+ command = "search"
47
+ elif command == "read":
48
+ command = "get"
49
+ roots: list[Path] = []
50
+ queries: list[str] = []
51
+ platforms: list[str] = []
52
+ date_from = date_to = cwd = model = None
53
+ limit = 20
54
+ workers = _default_workers()
55
+ include_subagents = False
56
+ rest: list[str] = []
57
+ index = 0
58
+ while index < len(args):
59
+ arg = args[index]
60
+ if arg == "--root":
61
+ roots.append(Path(args[index + 1]).expanduser())
62
+ index += 2
63
+ elif arg == "--query":
64
+ queries.append(args[index + 1])
65
+ index += 2
66
+ elif arg == "--platform":
67
+ platform = args[index + 1].strip().lower()
68
+ if "," in platform:
69
+ raise SystemExit("Use repeated --platform flags, for example: --platform senpi --platform opencode")
70
+ platforms.append(platform)
71
+ index += 2
72
+ elif arg == "--from":
73
+ date_from = args[index + 1]
74
+ index += 2
75
+ elif arg == "--to":
76
+ date_to = args[index + 1]
77
+ index += 2
78
+ elif arg == "--cwd":
79
+ cwd = args[index + 1].lower()
80
+ index += 2
81
+ elif arg == "--model":
82
+ model = args[index + 1].lower()
83
+ index += 2
84
+ elif arg == "--limit":
85
+ limit = int(args[index + 1])
86
+ index += 2
87
+ elif arg == "--workers":
88
+ workers = max(int(args[index + 1]), 1)
89
+ index += 2
90
+ elif arg == "--include-subagents":
91
+ include_subagents = True
92
+ index += 1
93
+ else:
94
+ rest.append(arg)
95
+ index += 1
96
+ selected_platforms = frozenset(platforms) if platforms else DEFAULT_PLATFORMS
97
+ return command, Options(selected_platforms, tuple(roots), tuple(queries), date_from, date_to, cwd, model, limit, workers, include_subagents), rest
98
+
99
+
100
+ def _filter(sessions: list[Session], opts: Options) -> list[Session]:
101
+ start = date_bound(opts.date_from)
102
+ end = date_bound(opts.date_to, end=True)
103
+ result: list[Session] = []
104
+ for item in sessions:
105
+ stamp = parse_stamp(item.created_at)
106
+ if start is not None and stamp is not None and stamp < start:
107
+ continue
108
+ if end is not None and stamp is not None and stamp >= end:
109
+ continue
110
+ if opts.cwd is not None and opts.cwd not in (item.cwd or "").lower():
111
+ continue
112
+ if opts.model is not None and opts.model not in (item.model or "").lower():
113
+ continue
114
+ result.append(item)
115
+ return result
116
+
117
+
118
+ def _child_counts(sessions: list[Session]) -> dict[tuple[str, str], int]:
119
+ counts: dict[tuple[str, str], int] = {}
120
+ for item in sessions:
121
+ if item.parent_id is not None:
122
+ key = (item.platform, item.parent_id)
123
+ counts[key] = counts.get(key, 0) + 1
124
+ return counts
125
+
126
+
127
+ def _annotate(item: Session, counts: dict[tuple[str, str], int]) -> JsonMap:
128
+ data = item.to_json()
129
+ data["subagent_count"] = counts.get((item.platform, item.id), 0)
130
+ data["detail_hint"] = _detail_hint(item)
131
+ return data
132
+
133
+
134
+ def _list_payload(filtered: list[Session], all_sessions: list[Session], limit: int, include_subagents: bool = False) -> JsonMap:
135
+ counts = _child_counts(all_sessions)
136
+ candidates = filtered if include_subagents else [item for item in filtered if item.parent_id is None]
137
+ results: list[Json] = [_annotate(item, counts) for item in candidates[:limit]]
138
+ return {"count": len(results), "results": results}
139
+
140
+
141
+ def _search_payload(filtered: list[Session], all_sessions: list[Session], queries: tuple[str, ...], limit: int, workers: int, include_subagents: bool = False) -> JsonMap:
142
+ counts = _child_counts(all_sessions)
143
+ candidates = filtered if include_subagents else [item for item in filtered if item.parent_id is None]
144
+ per_query: list[Json] = []
145
+ merged: dict[tuple[str, str], tuple[Session, list[JsonMap]]] = {}
146
+ with ThreadPoolExecutor(max_workers=min(workers, max(len(queries), 1))) as pool:
147
+ futures = [pool.submit(_search_one, candidates, query, limit) for query in queries]
148
+ for future in as_completed(futures):
149
+ query, matches = future.result()
150
+ per_query.append({"query": query, "count": len(matches), "results": [_annotate_search(item, counts, reasons) for item, reasons in matches]})
151
+ for item, reasons in matches:
152
+ key = (item.platform, item.id)
153
+ if key not in merged:
154
+ merged[key] = (item, reasons)
155
+ results: list[Json] = [_annotate_search(item, counts, reasons) for item, reasons in list(merged.values())[:limit]]
156
+ return {"count": len(results), "queries": per_query, "results": results}
157
+
158
+
159
+ def _get_payload(sessions: list[Session], ids: list[str]) -> JsonMap:
160
+ counts = _child_counts(sessions)
161
+ results: list[Json] = []
162
+ for item in sessions:
163
+ if item.id not in ids and not any(item.id.startswith(prefix) for prefix in ids):
164
+ continue
165
+ events = _events(item)
166
+ first_prompt, last_prompt = _prompt_edges(item, events)
167
+ session = _annotate(item, counts)
168
+ session["first_user_message"] = first_prompt[:300]
169
+ session["last_user_message"] = last_prompt[:300]
170
+ children = sorted(
171
+ (child for child in sessions if child.platform == item.platform and child.parent_id == item.id),
172
+ key=lambda child: child.created_at or "",
173
+ )
174
+ results.append(
175
+ {
176
+ "session": session,
177
+ "prompts": {"first_user_message": first_prompt, "last_user_message": last_prompt},
178
+ "events": events,
179
+ "subagents": [_annotate(child, counts) for child in children],
180
+ "detail_hint": _detail_hint(item),
181
+ }
182
+ )
183
+ return {"count": len(results), "results": results}
184
+
185
+
186
+ def _annotate_search(item: Session, counts: dict[tuple[str, str], int], reasons: list[JsonMap]) -> JsonMap:
187
+ data = _annotate(item, counts)
188
+ reason_rows: list[Json] = []
189
+ reason_rows.extend(reasons)
190
+ data["match_reasons"] = reason_rows
191
+ return data
192
+
193
+
194
+ def _detail_hint(item: Session) -> str:
195
+ return f"python3 scripts/find-agent-sessions.py read {item.id} --platform {item.platform}"
196
+
197
+
198
+ def _events(item: Session) -> list[Json]:
199
+ if item.path.endswith(".jsonl"):
200
+ return list(iter_jsonl(Path(item.path)))
201
+ events: list[Json] = []
202
+ if item.first_user_message:
203
+ events.append({"type": "message", "message": {"role": "user", "content": item.first_user_message}})
204
+ if item.last_user_message and item.last_user_message != item.first_user_message:
205
+ events.append({"type": "message", "message": {"role": "user", "content": item.last_user_message}})
206
+ return events
207
+
208
+
209
+ def _prompt_edges(item: Session, events: list[Json]) -> tuple[str, str]:
210
+ first_prompt = item.first_user_message
211
+ last_prompt = item.last_user_message or item.first_user_message
212
+ for event in events:
213
+ if not isinstance(event, dict):
214
+ continue
215
+ message = as_map(event.get("message")) or as_map(event.get("payload")) or {}
216
+ prompt = user_text(event, message)
217
+ if prompt:
218
+ first_prompt = first_prompt or prompt
219
+ last_prompt = prompt
220
+ return first_prompt, last_prompt
221
+
222
+
223
+ def _match_reasons(item: Session, query: str) -> list[JsonMap]:
224
+ needle = query.lower()
225
+ reasons: list[JsonMap] = []
226
+ for field, value in _search_fields(item):
227
+ if needle in value.lower():
228
+ reasons.append({"query": query, "platform": item.platform, "field": field, "snippet": _snippet(value, needle)})
229
+ return reasons
230
+
231
+
232
+ def _search_fields(item: Session) -> tuple[tuple[str, str], ...]:
233
+ return (
234
+ ("platform", item.platform),
235
+ ("id", item.id),
236
+ ("path", item.path),
237
+ ("cwd", item.cwd or ""),
238
+ ("provider", item.provider or ""),
239
+ ("model", item.model or ""),
240
+ ("agent", item.agent or ""),
241
+ ("first_user_message", item.first_user_message),
242
+ ("last_user_message", item.last_user_message),
243
+ )
244
+
245
+
246
+ def _snippet(value: str, needle: str) -> str:
247
+ start = max(value.lower().find(needle) - 60, 0)
248
+ end = min(start + 160, len(value))
249
+ return value[start:end]
250
+
251
+
252
+ def _queries(opts: Options, rest: list[str]) -> tuple[str, ...]:
253
+ if opts.queries:
254
+ return opts.queries
255
+ joined = " ".join(rest).strip()
256
+ return (joined,) if joined else ()
257
+
258
+
259
+ def _search_one(sessions: list[Session], query: str, limit: int) -> tuple[str, list[tuple[Session, list[JsonMap]]]]:
260
+ matches: list[tuple[Session, list[JsonMap]]] = []
261
+ for item in sessions:
262
+ reasons = _match_reasons(item, query)
263
+ if reasons:
264
+ matches.append((item, reasons))
265
+ return query, matches[:limit]
266
+
267
+
268
+ def _emit(value: JsonMap) -> None:
269
+ print(dumps(value))
270
+
271
+
272
+ def _require(values: list[str], message: str) -> None:
273
+ if not values:
274
+ raise SystemExit(message)
275
+
276
+
277
+ def _default_workers() -> int:
278
+ cpu = os.cpu_count() or 4
279
+ return min(max(cpu * 4, 8), 64)
280
+
281
+
282
+ if __name__ == "__main__":
283
+ raise SystemExit(main())
@@ -0,0 +1,105 @@
1
+ from __future__ import annotations
2
+
3
+ import sqlite3
4
+ from pathlib import Path
5
+ from typing import TypeAlias
6
+
7
+ from .timeparse import unix_seconds
8
+ from .transcript import env_path, existing, flat_parallel, jsonl_parallel, nick_role, recent, spawn_info, stem_id
9
+ from .types import Json, Session
10
+
11
+ THREADS_SQL = (
12
+ "SELECT id, rollout_path, cwd, created_at, updated_at, model_provider, model, first_user_message, tokens_used, "
13
+ "source, agent_nickname, agent_role FROM threads"
14
+ )
15
+ LEGACY_THREADS_SQL = (
16
+ "SELECT id, rollout_path, cwd, created_at, updated_at, model_provider, model, first_user_message, tokens_used FROM threads"
17
+ )
18
+ SPAWN_EDGES_SQL = "SELECT child_thread_id, parent_thread_id FROM thread_spawn_edges"
19
+
20
+ SqliteScalar: TypeAlias = str | int | float | bytes | None
21
+ CodexRow: TypeAlias = tuple[SqliteScalar, ...]
22
+
23
+
24
+ def scan_codex(extra_roots: tuple[Path, ...], workers: int) -> list[Session]:
25
+ roots = existing([*(path for path in (env_path("CODEX_HOME"),) if path is not None), Path.home() / ".codex", *extra_roots])
26
+ db_paths: list[Path] = []
27
+ rollouts: list[Path] = []
28
+ for root in roots:
29
+ db_paths.extend(root.glob("state_*.sqlite"))
30
+ rollouts.extend((root / "sessions").rglob("rollout-*.jsonl"))
31
+ rollouts.extend((root / "archived_sessions").glob("rollout-*.jsonl"))
32
+ sessions = flat_parallel(db_paths, workers, _codex_db)
33
+ sessions.extend(jsonl_parallel(recent(rollouts), workers, "codex", lambda path: stem_id(path, "rollout-")))
34
+ return sessions
35
+
36
+
37
+ def _codex_db(path: Path) -> list[Session]:
38
+ conn: sqlite3.Connection | None = None
39
+ try:
40
+ conn = sqlite3.connect(str(path), timeout=3)
41
+ edges = _spawn_edges(conn)
42
+ rows = _thread_rows(conn)
43
+ except sqlite3.Error:
44
+ return []
45
+ finally:
46
+ if conn is not None:
47
+ conn.close()
48
+ return [_codex_row(path, row, edges) for row in rows]
49
+
50
+
51
+ def _thread_rows(conn: sqlite3.Connection) -> list[CodexRow]:
52
+ try:
53
+ primary_rows: list[CodexRow] = conn.execute(THREADS_SQL).fetchall()
54
+ return primary_rows
55
+ except sqlite3.Error:
56
+ legacy_rows: list[CodexRow] = conn.execute(LEGACY_THREADS_SQL).fetchall()
57
+ return legacy_rows
58
+
59
+
60
+ def _spawn_edges(conn: sqlite3.Connection) -> dict[str, str]:
61
+ try:
62
+ rows: list[CodexRow] = conn.execute(SPAWN_EDGES_SQL).fetchall()
63
+ except sqlite3.Error:
64
+ return {}
65
+ edges: dict[str, str] = {}
66
+ for row in rows:
67
+ child = _row_text(_row_value(row, 0))
68
+ parent = _row_text(_row_value(row, 1))
69
+ if child is not None and parent is not None:
70
+ edges[child] = parent
71
+ return edges
72
+
73
+
74
+ def _codex_row(path: Path, row: CodexRow, edges: dict[str, str]) -> Session:
75
+ thread_id = str(_row_value(row, 0))
76
+ source_parent, source_agent = spawn_info(_row_text(_row_value(row, 9)))
77
+ return Session(
78
+ "codex",
79
+ thread_id,
80
+ str(_row_value(row, 1) or path),
81
+ _row_text(_row_value(row, 2)),
82
+ unix_seconds(_row_number(_row_value(row, 3))),
83
+ unix_seconds(_row_number(_row_value(row, 4))),
84
+ _row_text(_row_value(row, 5)),
85
+ _row_text(_row_value(row, 6)),
86
+ _row_text(_row_value(row, 7)) or "",
87
+ {"total_tokens": _row_number(_row_value(row, 8))},
88
+ edges.get(thread_id) or source_parent,
89
+ nick_role(_row_text(_row_value(row, 10)), _row_text(_row_value(row, 11))) or source_agent,
90
+ )
91
+
92
+
93
+ def _row_text(value: Json | int | float | None) -> str | None:
94
+ return value if isinstance(value, str) else None
95
+
96
+
97
+ def _row_number(value: Json | int | float | None) -> int | float | None:
98
+ return value if isinstance(value, int | float) else None
99
+
100
+
101
+ def _row_value(row: CodexRow, index: int) -> Json | int | float | None:
102
+ value = row[index] if index < len(row) else None
103
+ if value is None or isinstance(value, str | int | float | bool):
104
+ return value
105
+ return None