@baoanaz/cviauto-core 0.6.5

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 (206) hide show
  1. package/LICENSE +235 -0
  2. package/dist/channel/api/assert.d.ts +3 -0
  3. package/dist/channel/api/assert.d.ts.map +1 -0
  4. package/dist/channel/api/assert.js +11 -0
  5. package/dist/channel/api/assert.js.map +1 -0
  6. package/dist/channel/api/context.d.ts +21 -0
  7. package/dist/channel/api/context.d.ts.map +1 -0
  8. package/dist/channel/api/context.js +99 -0
  9. package/dist/channel/api/context.js.map +1 -0
  10. package/dist/channel/api/create.d.ts +9 -0
  11. package/dist/channel/api/create.d.ts.map +1 -0
  12. package/dist/channel/api/create.js +104 -0
  13. package/dist/channel/api/create.js.map +1 -0
  14. package/dist/channel/api/inbox.d.ts +51 -0
  15. package/dist/channel/api/inbox.d.ts.map +1 -0
  16. package/dist/channel/api/inbox.js +176 -0
  17. package/dist/channel/api/inbox.js.map +1 -0
  18. package/dist/channel/api/interrupt.d.ts +31 -0
  19. package/dist/channel/api/interrupt.d.ts.map +1 -0
  20. package/dist/channel/api/interrupt.js +98 -0
  21. package/dist/channel/api/interrupt.js.map +1 -0
  22. package/dist/channel/api/post-thread.d.ts +14 -0
  23. package/dist/channel/api/post-thread.d.ts.map +1 -0
  24. package/dist/channel/api/post-thread.js +109 -0
  25. package/dist/channel/api/post-thread.js.map +1 -0
  26. package/dist/channel/api/read.d.ts +17 -0
  27. package/dist/channel/api/read.d.ts.map +1 -0
  28. package/dist/channel/api/read.js +44 -0
  29. package/dist/channel/api/read.js.map +1 -0
  30. package/dist/channel/api/resolve.d.ts +21 -0
  31. package/dist/channel/api/resolve.d.ts.map +1 -0
  32. package/dist/channel/api/resolve.js +28 -0
  33. package/dist/channel/api/resolve.js.map +1 -0
  34. package/dist/channel/api/runtime.d.ts +70 -0
  35. package/dist/channel/api/runtime.d.ts.map +1 -0
  36. package/dist/channel/api/runtime.js +11 -0
  37. package/dist/channel/api/runtime.js.map +1 -0
  38. package/dist/channel/api/send.d.ts +4 -0
  39. package/dist/channel/api/send.d.ts.map +1 -0
  40. package/dist/channel/api/send.js +52 -0
  41. package/dist/channel/api/send.js.map +1 -0
  42. package/dist/channel/api/spawn.d.ts +13 -0
  43. package/dist/channel/api/spawn.d.ts.map +1 -0
  44. package/dist/channel/api/spawn.js +52 -0
  45. package/dist/channel/api/spawn.js.map +1 -0
  46. package/dist/channel/api/title.d.ts +5 -0
  47. package/dist/channel/api/title.d.ts.map +1 -0
  48. package/dist/channel/api/title.js +40 -0
  49. package/dist/channel/api/title.js.map +1 -0
  50. package/dist/channel/api/types.d.ts +65 -0
  51. package/dist/channel/api/types.d.ts.map +1 -0
  52. package/dist/channel/api/types.js +2 -0
  53. package/dist/channel/api/types.js.map +1 -0
  54. package/dist/channel/api/watch-channels.d.ts +40 -0
  55. package/dist/channel/api/watch-channels.d.ts.map +1 -0
  56. package/dist/channel/api/watch-channels.js +143 -0
  57. package/dist/channel/api/watch-channels.js.map +1 -0
  58. package/dist/channel/api/watch.d.ts +11 -0
  59. package/dist/channel/api/watch.d.ts.map +1 -0
  60. package/dist/channel/api/watch.js +17 -0
  61. package/dist/channel/api/watch.js.map +1 -0
  62. package/dist/channel/api/workers.d.ts +69 -0
  63. package/dist/channel/api/workers.d.ts.map +1 -0
  64. package/dist/channel/api/workers.js +143 -0
  65. package/dist/channel/api/workers.js.map +1 -0
  66. package/dist/channel/index.d.ts +38 -0
  67. package/dist/channel/index.d.ts.map +1 -0
  68. package/dist/channel/index.js +23 -0
  69. package/dist/channel/index.js.map +1 -0
  70. package/dist/channel/internal/store/channel-metadata.d.ts +23 -0
  71. package/dist/channel/internal/store/channel-metadata.d.ts.map +1 -0
  72. package/dist/channel/internal/store/channel-metadata.js +94 -0
  73. package/dist/channel/internal/store/channel-metadata.js.map +1 -0
  74. package/dist/channel/internal/store/delivery.d.ts +27 -0
  75. package/dist/channel/internal/store/delivery.d.ts.map +1 -0
  76. package/dist/channel/internal/store/delivery.js +37 -0
  77. package/dist/channel/internal/store/delivery.js.map +1 -0
  78. package/dist/channel/internal/store/events.d.ts +215 -0
  79. package/dist/channel/internal/store/events.d.ts.map +1 -0
  80. package/dist/channel/internal/store/events.js +204 -0
  81. package/dist/channel/internal/store/events.js.map +1 -0
  82. package/dist/channel/internal/store/filter.d.ts +21 -0
  83. package/dist/channel/internal/store/filter.d.ts.map +1 -0
  84. package/dist/channel/internal/store/filter.js +75 -0
  85. package/dist/channel/internal/store/filter.js.map +1 -0
  86. package/dist/channel/internal/store/inbox.d.ts +17 -0
  87. package/dist/channel/internal/store/inbox.d.ts.map +1 -0
  88. package/dist/channel/internal/store/inbox.js +30 -0
  89. package/dist/channel/internal/store/inbox.js.map +1 -0
  90. package/dist/channel/internal/store/lock.d.ts +17 -0
  91. package/dist/channel/internal/store/lock.d.ts.map +1 -0
  92. package/dist/channel/internal/store/lock.js +88 -0
  93. package/dist/channel/internal/store/lock.js.map +1 -0
  94. package/dist/channel/internal/store/paths.d.ts +43 -0
  95. package/dist/channel/internal/store/paths.d.ts.map +1 -0
  96. package/dist/channel/internal/store/paths.js +233 -0
  97. package/dist/channel/internal/store/paths.js.map +1 -0
  98. package/dist/channel/internal/store/schema.d.ts +77 -0
  99. package/dist/channel/internal/store/schema.d.ts.map +1 -0
  100. package/dist/channel/internal/store/schema.js +127 -0
  101. package/dist/channel/internal/store/schema.js.map +1 -0
  102. package/dist/channel/internal/store/seq.d.ts +12 -0
  103. package/dist/channel/internal/store/seq.d.ts.map +1 -0
  104. package/dist/channel/internal/store/seq.js +134 -0
  105. package/dist/channel/internal/store/seq.js.map +1 -0
  106. package/dist/channel/internal/store/thread-state.d.ts +37 -0
  107. package/dist/channel/internal/store/thread-state.d.ts.map +1 -0
  108. package/dist/channel/internal/store/thread-state.js +208 -0
  109. package/dist/channel/internal/store/thread-state.js.map +1 -0
  110. package/dist/channel/internal/store/watch.d.ts +10 -0
  111. package/dist/channel/internal/store/watch.d.ts.map +1 -0
  112. package/dist/channel/internal/store/watch.js +122 -0
  113. package/dist/channel/internal/store/watch.js.map +1 -0
  114. package/dist/channel/internal/store/worker-state.d.ts +56 -0
  115. package/dist/channel/internal/store/worker-state.d.ts.map +1 -0
  116. package/dist/channel/internal/store/worker-state.js +220 -0
  117. package/dist/channel/internal/store/worker-state.js.map +1 -0
  118. package/dist/index.d.ts +3 -0
  119. package/dist/index.d.ts.map +1 -0
  120. package/dist/index.js +7 -0
  121. package/dist/index.js.map +1 -0
  122. package/dist/mem/adapters/claude.d.ts +22 -0
  123. package/dist/mem/adapters/claude.d.ts.map +1 -0
  124. package/dist/mem/adapters/claude.js +234 -0
  125. package/dist/mem/adapters/claude.js.map +1 -0
  126. package/dist/mem/adapters/codex.d.ts +35 -0
  127. package/dist/mem/adapters/codex.d.ts.map +1 -0
  128. package/dist/mem/adapters/codex.js +222 -0
  129. package/dist/mem/adapters/codex.js.map +1 -0
  130. package/dist/mem/adapters/opencode.d.ts +19 -0
  131. package/dist/mem/adapters/opencode.d.ts.map +1 -0
  132. package/dist/mem/adapters/opencode.js +25 -0
  133. package/dist/mem/adapters/opencode.js.map +1 -0
  134. package/dist/mem/adapters/pi.d.ts +20 -0
  135. package/dist/mem/adapters/pi.d.ts.map +1 -0
  136. package/dist/mem/adapters/pi.js +299 -0
  137. package/dist/mem/adapters/pi.js.map +1 -0
  138. package/dist/mem/context.d.ts +23 -0
  139. package/dist/mem/context.d.ts.map +1 -0
  140. package/dist/mem/context.js +118 -0
  141. package/dist/mem/context.js.map +1 -0
  142. package/dist/mem/dialogue.d.ts +17 -0
  143. package/dist/mem/dialogue.d.ts.map +1 -0
  144. package/dist/mem/dialogue.js +51 -0
  145. package/dist/mem/dialogue.js.map +1 -0
  146. package/dist/mem/filter.d.ts +31 -0
  147. package/dist/mem/filter.d.ts.map +1 -0
  148. package/dist/mem/filter.js +66 -0
  149. package/dist/mem/filter.js.map +1 -0
  150. package/dist/mem/index.d.ts +18 -0
  151. package/dist/mem/index.d.ts.map +1 -0
  152. package/dist/mem/index.js +17 -0
  153. package/dist/mem/index.js.map +1 -0
  154. package/dist/mem/internal/jsonl.d.ts +35 -0
  155. package/dist/mem/internal/jsonl.d.ts.map +1 -0
  156. package/dist/mem/internal/jsonl.js +125 -0
  157. package/dist/mem/internal/jsonl.js.map +1 -0
  158. package/dist/mem/internal/paths.d.ts +25 -0
  159. package/dist/mem/internal/paths.d.ts.map +1 -0
  160. package/dist/mem/internal/paths.js +97 -0
  161. package/dist/mem/internal/paths.js.map +1 -0
  162. package/dist/mem/phase.d.ts +45 -0
  163. package/dist/mem/phase.d.ts.map +1 -0
  164. package/dist/mem/phase.js +220 -0
  165. package/dist/mem/phase.js.map +1 -0
  166. package/dist/mem/projects.d.ts +13 -0
  167. package/dist/mem/projects.d.ts.map +1 -0
  168. package/dist/mem/projects.js +37 -0
  169. package/dist/mem/projects.js.map +1 -0
  170. package/dist/mem/search.d.ts +32 -0
  171. package/dist/mem/search.d.ts.map +1 -0
  172. package/dist/mem/search.js +125 -0
  173. package/dist/mem/search.js.map +1 -0
  174. package/dist/mem/sessions.d.ts +37 -0
  175. package/dist/mem/sessions.d.ts.map +1 -0
  176. package/dist/mem/sessions.js +279 -0
  177. package/dist/mem/sessions.js.map +1 -0
  178. package/dist/mem/types.d.ts +176 -0
  179. package/dist/mem/types.d.ts.map +1 -0
  180. package/dist/mem/types.js +10 -0
  181. package/dist/mem/types.js.map +1 -0
  182. package/dist/task/index.d.ts +9 -0
  183. package/dist/task/index.d.ts.map +1 -0
  184. package/dist/task/index.js +9 -0
  185. package/dist/task/index.js.map +1 -0
  186. package/dist/task/paths.d.ts +37 -0
  187. package/dist/task/paths.d.ts.map +1 -0
  188. package/dist/task/paths.js +49 -0
  189. package/dist/task/paths.js.map +1 -0
  190. package/dist/task/phase.d.ts +27 -0
  191. package/dist/task/phase.d.ts.map +1 -0
  192. package/dist/task/phase.js +24 -0
  193. package/dist/task/phase.js.map +1 -0
  194. package/dist/task/records.d.ts +39 -0
  195. package/dist/task/records.d.ts.map +1 -0
  196. package/dist/task/records.js +89 -0
  197. package/dist/task/records.js.map +1 -0
  198. package/dist/task/schema.d.ts +77 -0
  199. package/dist/task/schema.d.ts.map +1 -0
  200. package/dist/task/schema.js +220 -0
  201. package/dist/task/schema.js.map +1 -0
  202. package/dist/testing/index.d.ts +2 -0
  203. package/dist/testing/index.d.ts.map +1 -0
  204. package/dist/testing/index.js +4 -0
  205. package/dist/testing/index.js.map +1 -0
  206. package/package.json +78 -0
@@ -0,0 +1,97 @@
1
+ /**
2
+ * Default home-based session roots for the persisted-session adapters.
3
+ *
4
+ * `HOME` is captured once at module load — consumers that need to point the
5
+ * adapters at a fake home (tests) must mock `node:os` before importing any
6
+ * mem module.
7
+ */
8
+ import * as fs from "node:fs";
9
+ import * as os from "node:os";
10
+ import * as path from "node:path";
11
+ export const HOME = os.homedir();
12
+ export const CLAUDE_PROJECTS = path.join(HOME, ".claude", "projects");
13
+ export const CODEX_SESSIONS = path.join(HOME, ".codex", "sessions");
14
+ function expandHome(p) {
15
+ if (p === "~")
16
+ return HOME;
17
+ if (p.startsWith(`~${path.sep}`))
18
+ return path.join(HOME, p.slice(2));
19
+ if (p.startsWith("~/"))
20
+ return path.join(HOME, p.slice(2));
21
+ return p;
22
+ }
23
+ export const PI_AGENT_DIR = expandHome(process.env.PI_CODING_AGENT_DIR ?? path.join(HOME, ".pi", "agent"));
24
+ export const PI_SESSIONS = expandHome(process.env.PI_CODING_AGENT_SESSION_DIR ??
25
+ path.join(PI_AGENT_DIR, "sessions"));
26
+ function readPiSettingsSessionDir() {
27
+ const settingsFile = path.join(PI_AGENT_DIR, "settings.json");
28
+ try {
29
+ const raw = JSON.parse(fs.readFileSync(settingsFile, "utf8"));
30
+ if (!raw || typeof raw !== "object" || Array.isArray(raw))
31
+ return undefined;
32
+ const sessionDir = raw.sessionDir;
33
+ return typeof sessionDir === "string" && sessionDir.trim()
34
+ ? expandHome(sessionDir)
35
+ : undefined;
36
+ }
37
+ catch {
38
+ return undefined;
39
+ }
40
+ }
41
+ /** Claude sanitizes a cwd into its on-disk project dir name by replacing
42
+ * every path separator (`/` and Windows `\`), drive colon (`:`), `_`, and `.`
43
+ * with `-`. Confirmed empirically against `~/.claude/projects/`:
44
+ * `/Users/x/.codex/...` → `-Users-x--codex-...`, `snap_note` → `snap-note`. */
45
+ export function claudeProjectDirFromCwd(cwd) {
46
+ return path.join(CLAUDE_PROJECTS, cwd.replace(/[/\\:_.]/g, "-"));
47
+ }
48
+ /** Pi encodes a cwd as `--<resolved-cwd-with-separators-as-dashes>--`. */
49
+ export function piProjectDirFromCwd(cwd) {
50
+ const resolvedCwd = path.resolve(cwd);
51
+ const safePath = `--${resolvedCwd.replace(/^[/\\]/, "").replace(/[/\\:]/g, "-")}--`;
52
+ return path.join(path.join(PI_AGENT_DIR, "sessions"), safePath);
53
+ }
54
+ /** Discover Pi session roots visible from the current process. */
55
+ export function piSessionRoots() {
56
+ const roots = [path.join(PI_AGENT_DIR, "sessions"), PI_SESSIONS];
57
+ const settingsSessionDir = readPiSettingsSessionDir();
58
+ if (settingsSessionDir)
59
+ roots.push(settingsSessionDir);
60
+ const seen = new Set();
61
+ const out = [];
62
+ for (const root of roots) {
63
+ const normalized = path.resolve(root);
64
+ if (seen.has(normalized))
65
+ continue;
66
+ seen.add(normalized);
67
+ out.push(root);
68
+ }
69
+ return out;
70
+ }
71
+ /** Lazy stack-based recursive file walk — yields every file path under
72
+ * `root`. Missing roots and unreadable directories are skipped silently. */
73
+ export function* walkDir(root) {
74
+ if (!fs.existsSync(root))
75
+ return;
76
+ const stack = [root];
77
+ while (stack.length) {
78
+ const cur = stack.pop();
79
+ if (cur === undefined)
80
+ break;
81
+ let entries;
82
+ try {
83
+ entries = fs.readdirSync(cur, { withFileTypes: true });
84
+ }
85
+ catch {
86
+ continue;
87
+ }
88
+ for (const e of entries) {
89
+ const p = path.join(cur, e.name);
90
+ if (e.isDirectory())
91
+ stack.push(p);
92
+ else if (e.isFile())
93
+ yield p;
94
+ }
95
+ }
96
+ }
97
+ //# sourceMappingURL=paths.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"paths.js","sourceRoot":"","sources":["../../../src/mem/internal/paths.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,45 @@
1
+ /**
2
+ * `task.py` command parsing and brainstorm-window slicing.
3
+ *
4
+ * Pure logic only — boundary signals are recovered from raw shell-call strings;
5
+ * the per-platform raw-JSONL pass that produces those strings lives in the
6
+ * adapters.
7
+ */
8
+ import type { BrainstormWindow, ParsedTaskPyCommand, TaskPyEvent } from "./types.js";
9
+ /**
10
+ * Find ALL `task.py create|start` invocations in a single Bash command string.
11
+ * A real Bash invocation can contain several (e.g.
12
+ * `SMOKE=$(task.py create …); task.py start "$SMOKE"`). Returned in source
13
+ * order; each entry's args are bounded to the next `task.py` invocation or
14
+ * end-of-line.
15
+ *
16
+ * False-positive guard: `task.py` must appear at the start of the command,
17
+ * after whitespace, or after a path separator — never embedded inside a flag
18
+ * value like `--slug=task.py-create-foo`.
19
+ */
20
+ export declare function parseTaskPyCommandsAll(cmd: string): ParsedTaskPyCommand[];
21
+ /** Single-result wrapper — returns the first occurrence, or `null` if none. */
22
+ export declare function parseTaskPyCommand(cmd: string): ParsedTaskPyCommand | null;
23
+ /** Best-effort shell-arg splitter: respects `"…"` / `'…'` quoting, splits on
24
+ * whitespace, treats `;`, `|`, `&`, `(`, `)` as token boundaries, and strips
25
+ * trailing shell-meta cruft (`)};&|>`) from each token. Not a full POSIX
26
+ * parser — sufficient for pulling slugs / paths out of `task.py` invocations. */
27
+ export declare function splitShellArgs(s: string): string[];
28
+ /** Derive a slug from a `start` task-dir path like
29
+ * `.cviauto/tasks/05-08-mem-phase-slice/` → `mem-phase-slice` (the `MM-DD-`
30
+ * date prefix is stripped so it matches a `--slug` on the paired `create`). */
31
+ export declare function slugFromTaskDir(p: string | undefined): string | undefined;
32
+ /**
33
+ * Pair `create` → `start` events into brainstorm windows.
34
+ *
35
+ * Pairing strategy:
36
+ * 1. Slug match wins regardless of position.
37
+ * 2. FIFO fallback: remaining creates pair with the next unmatched start
38
+ * appearing after them in event order.
39
+ * 3. Unmatched create → `[create, totalTurns)`.
40
+ * 4. Unmatched start → `[0, start)`.
41
+ *
42
+ * Windows are sorted by `startTurn` ascending for stable output ordering.
43
+ */
44
+ export declare function buildBrainstormWindows(events: readonly TaskPyEvent[], totalTurns: number): BrainstormWindow[];
45
+ //# sourceMappingURL=phase.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"phase.d.ts","sourceRoot":"","sources":["../../src/mem/phase.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;AAEH,OAAO,KAAK,EACV,gBAAgB,EAChB,mBAAmB,EACnB,WAAW,EACZ,MAAM,YAAY,CAAC;AAEpB;;;;;;;;;;GAUG;AACH,wBAAgB,sBAAsB,CAAC,GAAG,EAAE,MAAM,GAAG,mBAAmB,EAAE,CAgCzE;AAED,+EAA+E;AAC/E,wBAAgB,kBAAkB,CAAC,GAAG,EAAE,MAAM,GAAG,mBAAmB,GAAG,IAAI,CAG1E;AAqCD;;;iFAGiF;AACjF,wBAAgB,cAAc,CAAC,CAAC,EAAE,MAAM,GAAG,MAAM,EAAE,CAmClD;AAED;;+EAE+E;AAC/E,wBAAgB,eAAe,CAAC,CAAC,EAAE,MAAM,GAAG,SAAS,GAAG,MAAM,GAAG,SAAS,CAOzE;AAED;;;;;;;;;;;GAWG;AACH,wBAAgB,sBAAsB,CACpC,MAAM,EAAE,SAAS,WAAW,EAAE,EAC9B,UAAU,EAAE,MAAM,GACjB,gBAAgB,EAAE,CA2EpB"}
@@ -0,0 +1,220 @@
1
+ /**
2
+ * `task.py` command parsing and brainstorm-window slicing.
3
+ *
4
+ * Pure logic only — boundary signals are recovered from raw shell-call strings;
5
+ * the per-platform raw-JSONL pass that produces those strings lives in the
6
+ * adapters.
7
+ */
8
+ /**
9
+ * Find ALL `task.py create|start` invocations in a single Bash command string.
10
+ * A real Bash invocation can contain several (e.g.
11
+ * `SMOKE=$(task.py create …); task.py start "$SMOKE"`). Returned in source
12
+ * order; each entry's args are bounded to the next `task.py` invocation or
13
+ * end-of-line.
14
+ *
15
+ * False-positive guard: `task.py` must appear at the start of the command,
16
+ * after whitespace, or after a path separator — never embedded inside a flag
17
+ * value like `--slug=task.py-create-foo`.
18
+ */
19
+ export function parseTaskPyCommandsAll(cmd) {
20
+ if (typeof cmd !== "string" || cmd.length === 0)
21
+ return [];
22
+ const all = [];
23
+ const findRe = /(^|[\s/\\])task\.py\s+(create|start)(?:\s+|$)/g;
24
+ const matches = [];
25
+ for (const m of cmd.matchAll(findRe)) {
26
+ const action = m[2];
27
+ const bodyStart = m.index + m[0].length;
28
+ matches.push({ action, bodyStart });
29
+ }
30
+ for (let i = 0; i < matches.length; i++) {
31
+ const cur = matches[i];
32
+ if (!cur)
33
+ continue;
34
+ const next = matches[i + 1];
35
+ const slice = cmd.slice(cur.bodyStart, next?.bodyStart ?? cmd.length);
36
+ const restRaw = (slice.split("\n")[0] ?? "").trim();
37
+ // Reject prose-embedded matches: a bare alphanumeric word followed by
38
+ // another all-letters word is English prose, not a real invocation.
39
+ if (/^[A-Za-z][A-Za-z0-9_-]*\s+[A-Za-z]{2,}\b/.test(restRaw))
40
+ continue;
41
+ const parsed = parseRestOfTaskPyCommand(cur.action, restRaw);
42
+ if (cur.action === "create" &&
43
+ parsed.action === "create" &&
44
+ !parsed.slug &&
45
+ !parsed.titleArg)
46
+ continue;
47
+ if (cur.action === "start" && parsed.action === "start" && !parsed.taskDir)
48
+ continue;
49
+ all.push(parsed);
50
+ }
51
+ return all;
52
+ }
53
+ /** Single-result wrapper — returns the first occurrence, or `null` if none. */
54
+ export function parseTaskPyCommand(cmd) {
55
+ const all = parseTaskPyCommandsAll(cmd);
56
+ return all[0] ?? null;
57
+ }
58
+ function parseRestOfTaskPyCommand(action, restRaw) {
59
+ if (action === "create") {
60
+ const args = splitShellArgs(restRaw);
61
+ let slug;
62
+ let titleArg;
63
+ for (let i = 0; i < args.length; i++) {
64
+ const a = args[i];
65
+ if (a === undefined)
66
+ continue;
67
+ if (a === "--slug" || a === "-s") {
68
+ slug = args[i + 1];
69
+ i++;
70
+ continue;
71
+ }
72
+ if (a.startsWith("--slug=")) {
73
+ slug = a.slice("--slug=".length);
74
+ continue;
75
+ }
76
+ if (a.startsWith("-"))
77
+ continue;
78
+ titleArg ??= a;
79
+ }
80
+ return { action: "create", slug, titleArg };
81
+ }
82
+ const args = splitShellArgs(restRaw);
83
+ let taskDir;
84
+ for (const a of args) {
85
+ if (a.startsWith("-"))
86
+ continue;
87
+ taskDir = a;
88
+ break;
89
+ }
90
+ return { action: "start", taskDir };
91
+ }
92
+ /** Best-effort shell-arg splitter: respects `"…"` / `'…'` quoting, splits on
93
+ * whitespace, treats `;`, `|`, `&`, `(`, `)` as token boundaries, and strips
94
+ * trailing shell-meta cruft (`)};&|>`) from each token. Not a full POSIX
95
+ * parser — sufficient for pulling slugs / paths out of `task.py` invocations. */
96
+ export function splitShellArgs(s) {
97
+ const out = [];
98
+ let cur = "";
99
+ let quote = null;
100
+ const flush = () => {
101
+ if (!cur)
102
+ return;
103
+ const cleaned = cur.replace(/[)};&|>]+$/, "");
104
+ if (cleaned)
105
+ out.push(cleaned);
106
+ cur = "";
107
+ };
108
+ for (const ch of s) {
109
+ if (quote) {
110
+ if (ch === quote) {
111
+ quote = null;
112
+ continue;
113
+ }
114
+ cur += ch;
115
+ continue;
116
+ }
117
+ if (ch === '"' || ch === "'") {
118
+ quote = ch;
119
+ continue;
120
+ }
121
+ if (/\s/.test(ch)) {
122
+ flush();
123
+ continue;
124
+ }
125
+ if (ch === ";" || ch === "|" || ch === "&" || ch === "(" || ch === ")") {
126
+ flush();
127
+ continue;
128
+ }
129
+ cur += ch;
130
+ }
131
+ flush();
132
+ return out;
133
+ }
134
+ /** Derive a slug from a `start` task-dir path like
135
+ * `.cviauto/tasks/05-08-mem-phase-slice/` → `mem-phase-slice` (the `MM-DD-`
136
+ * date prefix is stripped so it matches a `--slug` on the paired `create`). */
137
+ export function slugFromTaskDir(p) {
138
+ if (!p)
139
+ return undefined;
140
+ const norm = p.replace(/\\+/g, "/").replace(/\/+$/g, "");
141
+ const parts = norm.split("/").filter(Boolean);
142
+ const last = parts[parts.length - 1];
143
+ if (last === undefined)
144
+ return undefined;
145
+ return last.replace(/^\d{2}-\d{2}-/, "");
146
+ }
147
+ /**
148
+ * Pair `create` → `start` events into brainstorm windows.
149
+ *
150
+ * Pairing strategy:
151
+ * 1. Slug match wins regardless of position.
152
+ * 2. FIFO fallback: remaining creates pair with the next unmatched start
153
+ * appearing after them in event order.
154
+ * 3. Unmatched create → `[create, totalTurns)`.
155
+ * 4. Unmatched start → `[0, start)`.
156
+ *
157
+ * Windows are sorted by `startTurn` ascending for stable output ordering.
158
+ */
159
+ export function buildBrainstormWindows(events, totalTurns) {
160
+ const creates = events
161
+ .map((e, i) => ({ e, i }))
162
+ .filter(({ e }) => e.action === "create");
163
+ const starts = events
164
+ .map((e, i) => ({ e, i }))
165
+ .filter(({ e }) => e.action === "start");
166
+ const usedStartIdx = new Set();
167
+ const usedCreateIdx = new Set();
168
+ const windows = [];
169
+ let windowCounter = 0;
170
+ // Pass 1: pair by slug match.
171
+ for (const { e: createEv, i: ci } of creates) {
172
+ if (!createEv.slug)
173
+ continue;
174
+ const matchIdx = starts.findIndex(({ e, i }) => !usedStartIdx.has(i) && slugFromTaskDir(e.taskDir) === createEv.slug);
175
+ if (matchIdx === -1)
176
+ continue;
177
+ const startEntry = starts[matchIdx];
178
+ if (!startEntry)
179
+ continue;
180
+ usedStartIdx.add(startEntry.i);
181
+ usedCreateIdx.add(ci);
182
+ pushWindow(windows, createEv.turnIndex, startEntry.e.turnIndex, createEv.slug, ++windowCounter);
183
+ }
184
+ // Pass 2: FIFO pair remaining creates with later starts.
185
+ for (const { e: createEv, i: ci } of creates) {
186
+ if (usedCreateIdx.has(ci))
187
+ continue;
188
+ const pairedStart = starts.find(({ i }) => !usedStartIdx.has(i) && i > ci);
189
+ if (pairedStart) {
190
+ usedStartIdx.add(pairedStart.i);
191
+ usedCreateIdx.add(ci);
192
+ const slug = createEv.slug ?? slugFromTaskDir(pairedStart.e.taskDir);
193
+ pushWindow(windows, createEv.turnIndex, pairedStart.e.turnIndex, slug, ++windowCounter);
194
+ }
195
+ else {
196
+ usedCreateIdx.add(ci);
197
+ pushWindow(windows, createEv.turnIndex, totalTurns, createEv.slug, ++windowCounter);
198
+ }
199
+ }
200
+ // Pass 3: unmatched starts → [0, start).
201
+ for (const { e: startEv, i } of starts) {
202
+ if (usedStartIdx.has(i))
203
+ continue;
204
+ pushWindow(windows, 0, startEv.turnIndex, slugFromTaskDir(startEv.taskDir), ++windowCounter);
205
+ }
206
+ windows.sort((a, b) => a.startTurn - b.startTurn);
207
+ return windows;
208
+ }
209
+ function pushWindow(windows, startTurn, endTurn, slug, counter) {
210
+ // Guard against malformed windows (start before create due to event
211
+ // interleave) rather than emitting a negative slice.
212
+ if (endTurn < startTurn)
213
+ return;
214
+ windows.push({
215
+ label: slug ?? `window-${counter}`,
216
+ startTurn,
217
+ endTurn,
218
+ });
219
+ }
220
+ //# sourceMappingURL=phase.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"phase.js","sourceRoot":"","sources":["../../src/mem/phase.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,13 @@
1
+ /**
2
+ * Project aggregation: distinct session cwds with last-active timestamp and
3
+ * per-platform counts.
4
+ */
5
+ import type { ListMemProjectsOptions, MemProjectSummary } from "./types.js";
6
+ /**
7
+ * Aggregate distinct project cwds across every platform. Always scans
8
+ * globally (cwd scoping is dropped) — `since` / `until` / `platform` still
9
+ * apply. Results are sorted by `last_active` descending; the caller decides
10
+ * any display cap.
11
+ */
12
+ export declare function listMemProjects(options?: ListMemProjectsOptions): MemProjectSummary[];
13
+ //# sourceMappingURL=projects.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"projects.d.ts","sourceRoot":"","sources":["../../src/mem/projects.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAGH,OAAO,KAAK,EAAE,sBAAsB,EAAE,iBAAiB,EAAE,MAAM,YAAY,CAAC;AAE5E;;;;;GAKG;AACH,wBAAgB,eAAe,CAC7B,OAAO,CAAC,EAAE,sBAAsB,GAC/B,iBAAiB,EAAE,CA0BrB"}
@@ -0,0 +1,37 @@
1
+ /**
2
+ * Project aggregation: distinct session cwds with last-active timestamp and
3
+ * per-platform counts.
4
+ */
5
+ import { listAll, resolveFilter, WIDE_LIMIT } from "./sessions.js";
6
+ /**
7
+ * Aggregate distinct project cwds across every platform. Always scans
8
+ * globally (cwd scoping is dropped) — `since` / `until` / `platform` still
9
+ * apply. Results are sorted by `last_active` descending; the caller decides
10
+ * any display cap.
11
+ */
12
+ export function listMemProjects(options) {
13
+ const f = resolveFilter(options?.filter);
14
+ const all = listAll({ ...f, cwd: undefined, limit: WIDE_LIMIT });
15
+ const byCwd = new Map();
16
+ for (const s of all) {
17
+ if (!s.cwd)
18
+ continue;
19
+ const ts = s.updated ?? s.created ?? "";
20
+ let agg = byCwd.get(s.cwd);
21
+ if (!agg) {
22
+ agg = {
23
+ cwd: s.cwd,
24
+ last_active: ts,
25
+ sessions: 0,
26
+ by_platform: { claude: 0, codex: 0, opencode: 0, pi: 0 },
27
+ };
28
+ byCwd.set(s.cwd, agg);
29
+ }
30
+ agg.sessions++;
31
+ agg.by_platform[s.platform]++;
32
+ if (ts > agg.last_active)
33
+ agg.last_active = ts;
34
+ }
35
+ return [...byCwd.values()].sort((a, b) => b.last_active.localeCompare(a.last_active));
36
+ }
37
+ //# sourceMappingURL=projects.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"projects.js","sourceRoot":"","sources":["../../src/mem/projects.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAEH,OAAO,EAAE,OAAO,EAAE,aAAa,EAAE,UAAU,EAAE,MAAM,eAAe,CAAC;AAGnE;;;;;GAKG;AACH,MAAM,UAAU,eAAe,CAC7B,OAAgC;IAEhC,MAAM,CAAC,GAAG,aAAa,CAAC,OAAO,EAAE,MAAM,CAAC,CAAC;IACzC,MAAM,GAAG,GAAG,OAAO,CAAC,EAAE,GAAG,CAAC,EAAE,GAAG,EAAE,SAAS,EAAE,KAAK,EAAE,UAAU,EAAE,CAAC,CAAC;IAEjE,MAAM,KAAK,GAAG,IAAI,GAAG,EAA6B,CAAC;IACnD,KAAK,MAAM,CAAC,IAAI,GAAG,EAAE,CAAC;QACpB,IAAI,CAAC,CAAC,CAAC,GAAG;YAAE,SAAS;QACrB,MAAM,EAAE,GAAG,CAAC,CAAC,OAAO,IAAI,CAAC,CAAC,OAAO,IAAI,EAAE,CAAC;QACxC,IAAI,GAAG,GAAG,KAAK,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC;QAC3B,IAAI,CAAC,GAAG,EAAE,CAAC;YACT,GAAG,GAAG;gBACJ,GAAG,EAAE,CAAC,CAAC,GAAG;gBACV,WAAW,EAAE,EAAE;gBACf,QAAQ,EAAE,CAAC;gBACX,WAAW,EAAE,EAAE,MAAM,EAAE,CAAC,EAAE,KAAK,EAAE,CAAC,EAAE,QAAQ,EAAE,CAAC,EAAE,EAAE,EAAE,CAAC,EAAE;aACzD,CAAC;YACF,KAAK,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,EAAE,GAAG,CAAC,CAAC;QACxB,CAAC;QACD,GAAG,CAAC,QAAQ,EAAE,CAAC;QACf,GAAG,CAAC,WAAW,CAAC,CAAC,CAAC,QAAQ,CAAC,EAAE,CAAC;QAC9B,IAAI,EAAE,GAAG,GAAG,CAAC,WAAW;YAAE,GAAG,CAAC,WAAW,GAAG,EAAE,CAAC;IACjD,CAAC;IAED,OAAO,CAAC,GAAG,KAAK,CAAC,MAAM,EAAE,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,EAAE,CACvC,CAAC,CAAC,WAAW,CAAC,aAAa,CAAC,CAAC,CAAC,WAAW,CAAC,CAC3C,CAAC;AACJ,CAAC"}
@@ -0,0 +1,32 @@
1
+ /**
2
+ * Search scoring and text matching over cleaned dialogue.
3
+ */
4
+ import type { DialogueTurn, SearchHit } from "./types.js";
5
+ /**
6
+ * Weighted-density relevance score:
7
+ * `(3 * userCount + asstCount) / totalTurns`
8
+ * Higher = the session is more topically concentrated on the query AND the
9
+ * user themselves brought it up (user hits weighted ×3 — the user's own words
10
+ * anchor "what they actually cared about"; assistant elaboration is downstream
11
+ * noise). Normalized by `totalTurns` so a tight short session can outrank a
12
+ * sprawling long one.
13
+ */
14
+ export declare function relevanceScore(h: SearchHit): number;
15
+ /** Find the paragraph-aligned chunk surrounding a hit position. A "chunk" is
16
+ * the contiguous text bounded by the nearest blank-line breaks (`\n\n`) on
17
+ * either side. If the natural paragraph exceeds `maxChars`, fall back to a
18
+ * centered char window — and report the truncation so callers can mark it. */
19
+ export declare function chunkAround(text: string, hitIdx: number, maxChars: number): {
20
+ start: number;
21
+ end: number;
22
+ truncated: boolean;
23
+ };
24
+ /**
25
+ * Multi-token AND grep over cleaned dialogue. Whitespace-split tokens; a turn
26
+ * matches iff every token (case-insensitive) appears in it. `count` is the
27
+ * total occurrence count across all tokens within matching turns. Excerpts are
28
+ * paragraph-aligned chunks around each hit, deduped by chunk start; user-role
29
+ * chunks are listed before assistant chunks.
30
+ */
31
+ export declare function searchInDialogue(turns: readonly DialogueTurn[], kw: string, maxExcerpts?: number, chunkChars?: number): SearchHit;
32
+ //# sourceMappingURL=search.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"search.d.ts","sourceRoot":"","sources":["../../src/mem/search.ts"],"names":[],"mappings":"AAAA;;GAEG;AAEH,OAAO,KAAK,EAAE,YAAY,EAAiB,SAAS,EAAE,MAAM,YAAY,CAAC;AAEzE;;;;;;;;GAQG;AACH,wBAAgB,cAAc,CAAC,CAAC,EAAE,SAAS,GAAG,MAAM,CAGnD;AAED;;;8EAG8E;AAC9E,wBAAgB,WAAW,CACzB,IAAI,EAAE,MAAM,EACZ,MAAM,EAAE,MAAM,EACd,QAAQ,EAAE,MAAM,GACf;IAAE,KAAK,EAAE,MAAM,CAAC;IAAC,GAAG,EAAE,MAAM,CAAC;IAAC,SAAS,EAAE,OAAO,CAAA;CAAE,CAYpD;AAED;;;;;;GAMG;AACH,wBAAgB,gBAAgB,CAC9B,KAAK,EAAE,SAAS,YAAY,EAAE,EAC9B,EAAE,EAAE,MAAM,EACV,WAAW,SAAI,EACf,UAAU,SAAM,GACf,SAAS,CAqFX"}
@@ -0,0 +1,125 @@
1
+ /**
2
+ * Search scoring and text matching over cleaned dialogue.
3
+ */
4
+ /**
5
+ * Weighted-density relevance score:
6
+ * `(3 * userCount + asstCount) / totalTurns`
7
+ * Higher = the session is more topically concentrated on the query AND the
8
+ * user themselves brought it up (user hits weighted ×3 — the user's own words
9
+ * anchor "what they actually cared about"; assistant elaboration is downstream
10
+ * noise). Normalized by `totalTurns` so a tight short session can outrank a
11
+ * sprawling long one.
12
+ */
13
+ export function relevanceScore(h) {
14
+ if (h.totalTurns === 0)
15
+ return 0;
16
+ return (3 * h.userCount + h.asstCount) / h.totalTurns;
17
+ }
18
+ /** Find the paragraph-aligned chunk surrounding a hit position. A "chunk" is
19
+ * the contiguous text bounded by the nearest blank-line breaks (`\n\n`) on
20
+ * either side. If the natural paragraph exceeds `maxChars`, fall back to a
21
+ * centered char window — and report the truncation so callers can mark it. */
22
+ export function chunkAround(text, hitIdx, maxChars) {
23
+ const startPara = text.lastIndexOf("\n\n", hitIdx);
24
+ let start = startPara === -1 ? 0 : startPara + 2;
25
+ const endPara = text.indexOf("\n\n", hitIdx);
26
+ let end = endPara === -1 ? text.length : endPara;
27
+ let truncated = false;
28
+ if (end - start > maxChars) {
29
+ start = Math.max(0, hitIdx - Math.floor(maxChars / 2));
30
+ end = Math.min(text.length, hitIdx + Math.ceil(maxChars / 2));
31
+ truncated = true;
32
+ }
33
+ return { start, end, truncated };
34
+ }
35
+ /**
36
+ * Multi-token AND grep over cleaned dialogue. Whitespace-split tokens; a turn
37
+ * matches iff every token (case-insensitive) appears in it. `count` is the
38
+ * total occurrence count across all tokens within matching turns. Excerpts are
39
+ * paragraph-aligned chunks around each hit, deduped by chunk start; user-role
40
+ * chunks are listed before assistant chunks.
41
+ */
42
+ export function searchInDialogue(turns, kw, maxExcerpts = 3, chunkChars = 400) {
43
+ const tokens = kw.toLowerCase().split(/\s+/).filter(Boolean);
44
+ if (tokens.length === 0) {
45
+ return {
46
+ count: 0,
47
+ userCount: 0,
48
+ asstCount: 0,
49
+ totalTurns: turns.length,
50
+ excerpts: [],
51
+ };
52
+ }
53
+ let userCount = 0;
54
+ let asstCount = 0;
55
+ const userExcerpts = [];
56
+ const asstExcerpts = [];
57
+ for (const t of turns) {
58
+ const hay = t.text.toLowerCase();
59
+ if (!tokens.every((tok) => hay.includes(tok)))
60
+ continue;
61
+ const hitPositions = [];
62
+ const tokenFreq = new Map();
63
+ let turnHits = 0;
64
+ for (const tok of tokens) {
65
+ let from = 0;
66
+ let n = 0;
67
+ while (true) {
68
+ const idx = hay.indexOf(tok, from);
69
+ if (idx === -1)
70
+ break;
71
+ n++;
72
+ turnHits++;
73
+ hitPositions.push({ idx, tok });
74
+ from = idx + tok.length;
75
+ }
76
+ tokenFreq.set(tok, n);
77
+ }
78
+ if (t.role === "user")
79
+ userCount += turnHits;
80
+ else
81
+ asstCount += turnHits;
82
+ hitPositions.sort((a, b) => a.idx - b.idx);
83
+ const candidates = [];
84
+ const seenStarts = new Set();
85
+ for (const { idx, tok } of hitPositions) {
86
+ const { start, end, truncated } = chunkAround(t.text, idx, chunkChars);
87
+ if (seenStarts.has(start))
88
+ continue;
89
+ seenStarts.add(start);
90
+ const slice = hay.slice(start, end);
91
+ const coverage = tokens.filter((tk) => slice.includes(tk)).length;
92
+ const rarity = 1 / (tokenFreq.get(tok) ?? 1);
93
+ candidates.push({ start, end, truncated, coverage, rarity });
94
+ }
95
+ candidates.sort((a, b) => {
96
+ if (b.coverage !== a.coverage)
97
+ return b.coverage - a.coverage;
98
+ if (b.rarity !== a.rarity)
99
+ return b.rarity - a.rarity;
100
+ return a.start - b.start;
101
+ });
102
+ for (const c of candidates) {
103
+ let snippet = t.text.slice(c.start, c.end).trim();
104
+ if (c.truncated) {
105
+ if (c.start > 0)
106
+ snippet = "…" + snippet;
107
+ if (c.end < t.text.length)
108
+ snippet += "…";
109
+ }
110
+ (t.role === "user" ? userExcerpts : asstExcerpts).push({
111
+ role: t.role,
112
+ snippet,
113
+ });
114
+ }
115
+ }
116
+ const excerpts = [...userExcerpts, ...asstExcerpts].slice(0, maxExcerpts);
117
+ return {
118
+ count: userCount + asstCount,
119
+ userCount,
120
+ asstCount,
121
+ totalTurns: turns.length,
122
+ excerpts,
123
+ };
124
+ }
125
+ //# sourceMappingURL=search.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"search.js","sourceRoot":"","sources":["../../src/mem/search.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,37 @@
1
+ /**
2
+ * Session orchestration: source fan-out, platform dispatch, sub-agent child
3
+ * merging, session lookup, phase slicing, and the public `listMemSessions`,
4
+ * `searchMemSessions`, and `extractMemDialogue` entry points.
5
+ */
6
+ import type { DialogueTurn, ExtractMemDialogueOptions, ListMemSessionsOptions, MemExtractResult, MemFilter, MemSearchResult, MemSessionInfo, SearchMemSessionsOptions } from "./types.js";
7
+ /** Internal wide limit — `limit` only caps display; search recall and session
8
+ * lookup must scan everything. */
9
+ export declare const WIDE_LIMIT = 1000000;
10
+ /** Thrown by `readMemContext` / `extractMemDialogue` when the requested
11
+ * session id cannot be resolved. */
12
+ export declare class MemSessionNotFoundError extends Error {
13
+ readonly sessionId: string;
14
+ constructor(sessionId: string);
15
+ }
16
+ /** Fill platform / limit defaults so internal helpers see a complete filter. */
17
+ export declare function resolveFilter(filter?: MemFilter): MemFilter;
18
+ /** Fan out to every in-scope platform, merge by recency, cap at `f.limit`. */
19
+ export declare function listAll(f: MemFilter): MemSessionInfo[];
20
+ declare function extractDialogue(s: MemSessionInfo): DialogueTurn[];
21
+ /** Build a parent → descendants index (transitively flattened) for OpenCode
22
+ * sub-agent chains. Other platforms have no native `parent_id`. */
23
+ declare function buildChildIndex(sessions: readonly MemSessionInfo[]): Map<string, MemSessionInfo[]>;
24
+ /** Resolve a session by exact id or id prefix, scanning every project. */
25
+ export declare function findSessionById(id: string, f: MemFilter): MemSessionInfo | undefined;
26
+ /** List session metadata across Claude / Codex / OpenCode / Pi, sorted by
27
+ * recency and capped at the filter's `limit` (default 50). */
28
+ export declare function listMemSessions(options?: ListMemSessionsOptions): MemSessionInfo[];
29
+ /** Multi-token AND grep over cleaned dialogue across all matching sessions,
30
+ * ranked by weighted-density relevance. `matches` is capped at the filter's
31
+ * `limit`; `totalMatches` is the full match count. */
32
+ export declare function searchMemSessions(options: SearchMemSessionsOptions): MemSearchResult;
33
+ /** Dump cleaned dialogue for one session, optionally sliced by brainstorm
34
+ * phase and filtered by a multi-token AND `grep`. */
35
+ export declare function extractMemDialogue(options: ExtractMemDialogueOptions): MemExtractResult;
36
+ export { extractDialogue, buildChildIndex };
37
+ //# sourceMappingURL=sessions.d.ts.map