@polpo-ai/file-stores 0.11.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 (70) hide show
  1. package/LICENSE +13 -0
  2. package/dist/file-agent-store.d.ts +24 -0
  3. package/dist/file-agent-store.d.ts.map +1 -0
  4. package/dist/file-agent-store.js +102 -0
  5. package/dist/file-agent-store.js.map +1 -0
  6. package/dist/file-approval-store.d.ts +20 -0
  7. package/dist/file-approval-store.d.ts.map +1 -0
  8. package/dist/file-approval-store.js +62 -0
  9. package/dist/file-approval-store.js.map +1 -0
  10. package/dist/file-checkpoint-store.d.ts +18 -0
  11. package/dist/file-checkpoint-store.d.ts.map +1 -0
  12. package/dist/file-checkpoint-store.js +52 -0
  13. package/dist/file-checkpoint-store.js.map +1 -0
  14. package/dist/file-delay-store.d.ts +18 -0
  15. package/dist/file-delay-store.d.ts.map +1 -0
  16. package/dist/file-delay-store.js +52 -0
  17. package/dist/file-delay-store.js.map +1 -0
  18. package/dist/file-log-store.d.ts +22 -0
  19. package/dist/file-log-store.d.ts.map +1 -0
  20. package/dist/file-log-store.js +123 -0
  21. package/dist/file-log-store.js.map +1 -0
  22. package/dist/file-memory-store.d.ts +21 -0
  23. package/dist/file-memory-store.d.ts.map +1 -0
  24. package/dist/file-memory-store.js +85 -0
  25. package/dist/file-memory-store.js.map +1 -0
  26. package/dist/file-playbook-store.d.ts +25 -0
  27. package/dist/file-playbook-store.d.ts.map +1 -0
  28. package/dist/file-playbook-store.js +35 -0
  29. package/dist/file-playbook-store.js.map +1 -0
  30. package/dist/file-run-store.d.ts +29 -0
  31. package/dist/file-run-store.d.ts.map +1 -0
  32. package/dist/file-run-store.js +131 -0
  33. package/dist/file-run-store.js.map +1 -0
  34. package/dist/file-session-store.d.ts +28 -0
  35. package/dist/file-session-store.d.ts.map +1 -0
  36. package/dist/file-session-store.js +245 -0
  37. package/dist/file-session-store.js.map +1 -0
  38. package/dist/file-skill-store.d.ts +26 -0
  39. package/dist/file-skill-store.d.ts.map +1 -0
  40. package/dist/file-skill-store.js +92 -0
  41. package/dist/file-skill-store.js.map +1 -0
  42. package/dist/file-task-store.d.ts +48 -0
  43. package/dist/file-task-store.d.ts.map +1 -0
  44. package/dist/file-task-store.js +296 -0
  45. package/dist/file-task-store.js.map +1 -0
  46. package/dist/file-team-store.d.ts +20 -0
  47. package/dist/file-team-store.d.ts.map +1 -0
  48. package/dist/file-team-store.js +91 -0
  49. package/dist/file-team-store.js.map +1 -0
  50. package/dist/index.d.ts +17 -0
  51. package/dist/index.d.ts.map +1 -0
  52. package/dist/index.js +19 -0
  53. package/dist/index.js.map +1 -0
  54. package/dist/json-config-store.d.ts +25 -0
  55. package/dist/json-config-store.d.ts.map +1 -0
  56. package/dist/json-config-store.js +66 -0
  57. package/dist/json-config-store.js.map +1 -0
  58. package/dist/json-task-store.d.ts +22 -0
  59. package/dist/json-task-store.d.ts.map +1 -0
  60. package/dist/json-task-store.js +112 -0
  61. package/dist/json-task-store.js.map +1 -0
  62. package/dist/paths.d.ts +11 -0
  63. package/dist/paths.d.ts.map +1 -0
  64. package/dist/paths.js +17 -0
  65. package/dist/paths.js.map +1 -0
  66. package/dist/playbook-files.d.ts +38 -0
  67. package/dist/playbook-files.d.ts.map +1 -0
  68. package/dist/playbook-files.js +159 -0
  69. package/dist/playbook-files.js.map +1 -0
  70. package/package.json +36 -0
@@ -0,0 +1,85 @@
1
+ import { existsSync, readFileSync, writeFileSync, appendFileSync, mkdirSync, renameSync, readdirSync } from "node:fs";
2
+ import { join, dirname, basename } from "node:path";
3
+ /**
4
+ * File-backed MemoryStore.
5
+ * Reads/writes `.polpo/memory.md` for shared memory (no scope).
6
+ * Agent-scoped memory lives in `.polpo/memory/<agent-name>.md`.
7
+ */
8
+ export class FileMemoryStore {
9
+ sharedPath;
10
+ scopeDir;
11
+ constructor(polpoDir) {
12
+ this.sharedPath = join(polpoDir, "memory.md");
13
+ this.scopeDir = join(polpoDir, "memory");
14
+ }
15
+ /** Resolve the file path for a given scope. Undefined = shared memory. */
16
+ resolvePath(scope) {
17
+ if (!scope)
18
+ return this.sharedPath;
19
+ // scope is "agent:<name>" — extract the name part for the filename
20
+ const name = scope.startsWith("agent:") ? scope.slice(6) : scope;
21
+ return join(this.scopeDir, `${name}.md`);
22
+ }
23
+ async exists(scope) {
24
+ return existsSync(this.resolvePath(scope));
25
+ }
26
+ async get(scope) {
27
+ const filePath = this.resolvePath(scope);
28
+ if (!existsSync(filePath))
29
+ return "";
30
+ try {
31
+ return readFileSync(filePath, "utf-8");
32
+ }
33
+ catch { /* unreadable memory file */
34
+ return "";
35
+ }
36
+ }
37
+ async save(content, scope) {
38
+ const filePath = this.resolvePath(scope);
39
+ const dir = dirname(filePath);
40
+ if (!existsSync(dir))
41
+ mkdirSync(dir, { recursive: true });
42
+ const tmpPath = filePath + ".tmp";
43
+ writeFileSync(tmpPath, content, "utf-8");
44
+ renameSync(tmpPath, filePath);
45
+ }
46
+ async append(line, scope) {
47
+ const filePath = this.resolvePath(scope);
48
+ const dir = dirname(filePath);
49
+ if (!existsSync(dir))
50
+ mkdirSync(dir, { recursive: true });
51
+ const ts = new Date().toISOString().slice(0, 10);
52
+ appendFileSync(filePath, `\n- ${ts}: ${line}\n`, "utf-8");
53
+ }
54
+ async update(oldText, newText, scope) {
55
+ const filePath = this.resolvePath(scope);
56
+ if (!existsSync(filePath))
57
+ return "Memory file does not exist. Use save_memory to create it first.";
58
+ const content = await this.get(scope);
59
+ if (!content.includes(oldText)) {
60
+ return "oldString not found in memory. Use get_memory to see the current content.";
61
+ }
62
+ const firstIdx = content.indexOf(oldText);
63
+ const secondIdx = content.indexOf(oldText, firstIdx + 1);
64
+ if (secondIdx !== -1) {
65
+ return "oldString found multiple times in memory. Provide more surrounding context to make the match unique.";
66
+ }
67
+ const updated = content.replace(oldText, newText);
68
+ await this.save(updated, scope);
69
+ return true;
70
+ }
71
+ /** List all agent scopes that have memory files. Returns agent names (without "agent:" prefix). */
72
+ async listScopes() {
73
+ if (!existsSync(this.scopeDir))
74
+ return [];
75
+ try {
76
+ return readdirSync(this.scopeDir)
77
+ .filter(f => f.endsWith(".md"))
78
+ .map(f => basename(f, ".md"));
79
+ }
80
+ catch {
81
+ return [];
82
+ }
83
+ }
84
+ }
85
+ //# sourceMappingURL=file-memory-store.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"file-memory-store.js","sourceRoot":"","sources":["../src/file-memory-store.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,UAAU,EAAE,YAAY,EAAE,aAAa,EAAE,cAAc,EAAE,SAAS,EAAE,UAAU,EAAE,WAAW,EAAE,MAAM,SAAS,CAAC;AACtH,OAAO,EAAE,IAAI,EAAE,OAAO,EAAE,QAAQ,EAAE,MAAM,WAAW,CAAC;AAGpD;;;;GAIG;AACH,MAAM,OAAO,eAAe;IACT,UAAU,CAAS;IACnB,QAAQ,CAAS;IAElC,YAAY,QAAgB;QAC1B,IAAI,CAAC,UAAU,GAAG,IAAI,CAAC,QAAQ,EAAE,WAAW,CAAC,CAAC;QAC9C,IAAI,CAAC,QAAQ,GAAG,IAAI,CAAC,QAAQ,EAAE,QAAQ,CAAC,CAAC;IAC3C,CAAC;IAED,0EAA0E;IAClE,WAAW,CAAC,KAAc;QAChC,IAAI,CAAC,KAAK;YAAE,OAAO,IAAI,CAAC,UAAU,CAAC;QACnC,mEAAmE;QACnE,MAAM,IAAI,GAAG,KAAK,CAAC,UAAU,CAAC,QAAQ,CAAC,CAAC,CAAC,CAAC,KAAK,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,KAAK,CAAC;QACjE,OAAO,IAAI,CAAC,IAAI,CAAC,QAAQ,EAAE,GAAG,IAAI,KAAK,CAAC,CAAC;IAC3C,CAAC;IAED,KAAK,CAAC,MAAM,CAAC,KAAc;QACzB,OAAO,UAAU,CAAC,IAAI,CAAC,WAAW,CAAC,KAAK,CAAC,CAAC,CAAC;IAC7C,CAAC;IAED,KAAK,CAAC,GAAG,CAAC,KAAc;QACtB,MAAM,QAAQ,GAAG,IAAI,CAAC,WAAW,CAAC,KAAK,CAAC,CAAC;QACzC,IAAI,CAAC,UAAU,CAAC,QAAQ,CAAC;YAAE,OAAO,EAAE,CAAC;QACrC,IAAI,CAAC;YACH,OAAO,YAAY,CAAC,QAAQ,EAAE,OAAO,CAAC,CAAC;QACzC,CAAC;QAAC,MAAM,CAAC,CAAC,4BAA4B;YACpC,OAAO,EAAE,CAAC;QACZ,CAAC;IACH,CAAC;IAED,KAAK,CAAC,IAAI,CAAC,OAAe,EAAE,KAAc;QACxC,MAAM,QAAQ,GAAG,IAAI,CAAC,WAAW,CAAC,KAAK,CAAC,CAAC;QACzC,MAAM,GAAG,GAAG,OAAO,CAAC,QAAQ,CAAC,CAAC;QAC9B,IAAI,CAAC,UAAU,CAAC,GAAG,CAAC;YAAE,SAAS,CAAC,GAAG,EAAE,EAAE,SAAS,EAAE,IAAI,EAAE,CAAC,CAAC;QAC1D,MAAM,OAAO,GAAG,QAAQ,GAAG,MAAM,CAAC;QAClC,aAAa,CAAC,OAAO,EAAE,OAAO,EAAE,OAAO,CAAC,CAAC;QACzC,UAAU,CAAC,OAAO,EAAE,QAAQ,CAAC,CAAC;IAChC,CAAC;IAED,KAAK,CAAC,MAAM,CAAC,IAAY,EAAE,KAAc;QACvC,MAAM,QAAQ,GAAG,IAAI,CAAC,WAAW,CAAC,KAAK,CAAC,CAAC;QACzC,MAAM,GAAG,GAAG,OAAO,CAAC,QAAQ,CAAC,CAAC;QAC9B,IAAI,CAAC,UAAU,CAAC,GAAG,CAAC;YAAE,SAAS,CAAC,GAAG,EAAE,EAAE,SAAS,EAAE,IAAI,EAAE,CAAC,CAAC;QAC1D,MAAM,EAAE,GAAG,IAAI,IAAI,EAAE,CAAC,WAAW,EAAE,CAAC,KAAK,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC;QACjD,cAAc,CAAC,QAAQ,EAAE,OAAO,EAAE,KAAK,IAAI,IAAI,EAAE,OAAO,CAAC,CAAC;IAC5D,CAAC;IAED,KAAK,CAAC,MAAM,CAAC,OAAe,EAAE,OAAe,EAAE,KAAc;QAC3D,MAAM,QAAQ,GAAG,IAAI,CAAC,WAAW,CAAC,KAAK,CAAC,CAAC;QACzC,IAAI,CAAC,UAAU,CAAC,QAAQ,CAAC;YAAE,OAAO,iEAAiE,CAAC;QACpG,MAAM,OAAO,GAAG,MAAM,IAAI,CAAC,GAAG,CAAC,KAAK,CAAC,CAAC;QACtC,IAAI,CAAC,OAAO,CAAC,QAAQ,CAAC,OAAO,CAAC,EAAE,CAAC;YAC/B,OAAO,2EAA2E,CAAC;QACrF,CAAC;QACD,MAAM,QAAQ,GAAG,OAAO,CAAC,OAAO,CAAC,OAAO,CAAC,CAAC;QAC1C,MAAM,SAAS,GAAG,OAAO,CAAC,OAAO,CAAC,OAAO,EAAE,QAAQ,GAAG,CAAC,CAAC,CAAC;QACzD,IAAI,SAAS,KAAK,CAAC,CAAC,EAAE,CAAC;YACrB,OAAO,sGAAsG,CAAC;QAChH,CAAC;QACD,MAAM,OAAO,GAAG,OAAO,CAAC,OAAO,CAAC,OAAO,EAAE,OAAO,CAAC,CAAC;QAClD,MAAM,IAAI,CAAC,IAAI,CAAC,OAAO,EAAE,KAAK,CAAC,CAAC;QAChC,OAAO,IAAI,CAAC;IACd,CAAC;IAED,mGAAmG;IACnG,KAAK,CAAC,UAAU;QACd,IAAI,CAAC,UAAU,CAAC,IAAI,CAAC,QAAQ,CAAC;YAAE,OAAO,EAAE,CAAC;QAC1C,IAAI,CAAC;YACH,OAAO,WAAW,CAAC,IAAI,CAAC,QAAQ,CAAC;iBAC9B,MAAM,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,QAAQ,CAAC,KAAK,CAAC,CAAC;iBAC9B,GAAG,CAAC,CAAC,CAAC,EAAE,CAAC,QAAQ,CAAC,CAAC,EAAE,KAAK,CAAC,CAAC,CAAC;QAClC,CAAC;QAAC,MAAM,CAAC;YACP,OAAO,EAAE,CAAC;QACZ,CAAC;IACH,CAAC;CACF"}
@@ -0,0 +1,25 @@
1
+ /**
2
+ * FilePlaybookStore — file-system backed PlaybookStore.
3
+ *
4
+ * Wraps the existing discovery/persistence logic from src/core/playbook.ts
5
+ * behind the async PlaybookStore interface.
6
+ *
7
+ * Discovery paths (in priority order, first occurrence wins by name):
8
+ * 1. <polpoDir>/playbooks/ — project-level
9
+ * 2. <cwd>/.polpo/playbooks/ — alias when polpoDir != .polpo
10
+ * 3. ~/.polpo/playbooks/ — user-level
11
+ *
12
+ * Also scans legacy templates/ directories for backward compatibility.
13
+ */
14
+ import type { PlaybookStore } from "@polpo-ai/core/playbook-store";
15
+ import type { PlaybookDefinition, PlaybookInfo } from "@polpo-ai/core/playbook-store";
16
+ export declare class FilePlaybookStore implements PlaybookStore {
17
+ private readonly cwd;
18
+ private readonly polpoDir;
19
+ constructor(cwd: string, polpoDir: string);
20
+ list(): Promise<PlaybookInfo[]>;
21
+ get(name: string): Promise<PlaybookDefinition | null>;
22
+ save(definition: PlaybookDefinition): Promise<string>;
23
+ delete(name: string): Promise<boolean>;
24
+ }
25
+ //# sourceMappingURL=file-playbook-store.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"file-playbook-store.d.ts","sourceRoot":"","sources":["../src/file-playbook-store.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;GAYG;AAEH,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,+BAA+B,CAAC;AACnE,OAAO,KAAK,EAAE,kBAAkB,EAAE,YAAY,EAAE,MAAM,+BAA+B,CAAC;AAQtF,qBAAa,iBAAkB,YAAW,aAAa;IAEnD,OAAO,CAAC,QAAQ,CAAC,GAAG;IACpB,OAAO,CAAC,QAAQ,CAAC,QAAQ;gBADR,GAAG,EAAE,MAAM,EACX,QAAQ,EAAE,MAAM;IAG7B,IAAI,IAAI,OAAO,CAAC,YAAY,EAAE,CAAC;IAI/B,GAAG,CAAC,IAAI,EAAE,MAAM,GAAG,OAAO,CAAC,kBAAkB,GAAG,IAAI,CAAC;IAIrD,IAAI,CAAC,UAAU,EAAE,kBAAkB,GAAG,OAAO,CAAC,MAAM,CAAC;IAIrD,MAAM,CAAC,IAAI,EAAE,MAAM,GAAG,OAAO,CAAC,OAAO,CAAC;CAG7C"}
@@ -0,0 +1,35 @@
1
+ /**
2
+ * FilePlaybookStore — file-system backed PlaybookStore.
3
+ *
4
+ * Wraps the existing discovery/persistence logic from src/core/playbook.ts
5
+ * behind the async PlaybookStore interface.
6
+ *
7
+ * Discovery paths (in priority order, first occurrence wins by name):
8
+ * 1. <polpoDir>/playbooks/ — project-level
9
+ * 2. <cwd>/.polpo/playbooks/ — alias when polpoDir != .polpo
10
+ * 3. ~/.polpo/playbooks/ — user-level
11
+ *
12
+ * Also scans legacy templates/ directories for backward compatibility.
13
+ */
14
+ import { discoverPlaybooks, loadPlaybook, savePlaybook, deletePlaybook, } from "./playbook-files.js";
15
+ export class FilePlaybookStore {
16
+ cwd;
17
+ polpoDir;
18
+ constructor(cwd, polpoDir) {
19
+ this.cwd = cwd;
20
+ this.polpoDir = polpoDir;
21
+ }
22
+ async list() {
23
+ return discoverPlaybooks(this.cwd, this.polpoDir);
24
+ }
25
+ async get(name) {
26
+ return loadPlaybook(this.cwd, this.polpoDir, name);
27
+ }
28
+ async save(definition) {
29
+ return savePlaybook(this.polpoDir, definition);
30
+ }
31
+ async delete(name) {
32
+ return deletePlaybook(this.cwd, this.polpoDir, name);
33
+ }
34
+ }
35
+ //# sourceMappingURL=file-playbook-store.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"file-playbook-store.js","sourceRoot":"","sources":["../src/file-playbook-store.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;GAYG;AAIH,OAAO,EACL,iBAAiB,EACjB,YAAY,EACZ,YAAY,EACZ,cAAc,GACf,MAAM,qBAAqB,CAAC;AAE7B,MAAM,OAAO,iBAAiB;IAET;IACA;IAFnB,YACmB,GAAW,EACX,QAAgB;QADhB,QAAG,GAAH,GAAG,CAAQ;QACX,aAAQ,GAAR,QAAQ,CAAQ;IAChC,CAAC;IAEJ,KAAK,CAAC,IAAI;QACR,OAAO,iBAAiB,CAAC,IAAI,CAAC,GAAG,EAAE,IAAI,CAAC,QAAQ,CAAC,CAAC;IACpD,CAAC;IAED,KAAK,CAAC,GAAG,CAAC,IAAY;QACpB,OAAO,YAAY,CAAC,IAAI,CAAC,GAAG,EAAE,IAAI,CAAC,QAAQ,EAAE,IAAI,CAAC,CAAC;IACrD,CAAC;IAED,KAAK,CAAC,IAAI,CAAC,UAA8B;QACvC,OAAO,YAAY,CAAC,IAAI,CAAC,QAAQ,EAAE,UAAU,CAAC,CAAC;IACjD,CAAC;IAED,KAAK,CAAC,MAAM,CAAC,IAAY;QACvB,OAAO,cAAc,CAAC,IAAI,CAAC,GAAG,EAAE,IAAI,CAAC,QAAQ,EAAE,IAAI,CAAC,CAAC;IACvD,CAAC;CACF"}
@@ -0,0 +1,29 @@
1
+ import type { AgentActivity, TaskResult, TaskOutcome } from "@polpo-ai/core/types";
2
+ import type { RunStore, RunRecord, RunStatus } from "@polpo-ai/core/run-store";
3
+ /**
4
+ * Filesystem-based RunStore.
5
+ * Each run is a single JSON file in .polpo/runs/<runId>.json.
6
+ *
7
+ * Concurrency model: the runner subprocess owns its run file (writes),
8
+ * the orchestrator only reads. No cross-process write conflicts.
9
+ */
10
+ export declare class FileRunStore implements RunStore {
11
+ private runsDir;
12
+ constructor(polpoDir: string);
13
+ private runPath;
14
+ private readRun;
15
+ private writeRun;
16
+ private listRunIds;
17
+ private allRuns;
18
+ upsertRun(run: RunRecord): Promise<void>;
19
+ updateActivity(runId: string, activity: AgentActivity): Promise<void>;
20
+ updateOutcomes(runId: string, outcomes: TaskOutcome[]): Promise<void>;
21
+ completeRun(runId: string, status: RunStatus, result: TaskResult): Promise<void>;
22
+ getRun(runId: string): Promise<RunRecord | undefined>;
23
+ getRunByTaskId(taskId: string): Promise<RunRecord | undefined>;
24
+ getActiveRuns(): Promise<RunRecord[]>;
25
+ getTerminalRuns(): Promise<RunRecord[]>;
26
+ deleteRun(runId: string): Promise<void>;
27
+ close(): Promise<void>;
28
+ }
29
+ //# sourceMappingURL=file-run-store.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"file-run-store.d.ts","sourceRoot":"","sources":["../src/file-run-store.ts"],"names":[],"mappings":"AAUA,OAAO,KAAK,EAAE,aAAa,EAAE,UAAU,EAAE,WAAW,EAAE,MAAM,sBAAsB,CAAC;AACnF,OAAO,KAAK,EAAE,QAAQ,EAAE,SAAS,EAAE,SAAS,EAAE,MAAM,0BAA0B,CAAC;AAiB/E;;;;;;GAMG;AACH,qBAAa,YAAa,YAAW,QAAQ;IAC3C,OAAO,CAAC,OAAO,CAAS;gBAEZ,QAAQ,EAAE,MAAM;IAK5B,OAAO,CAAC,OAAO;IAIf,OAAO,CAAC,OAAO;IAaf,OAAO,CAAC,QAAQ;IAIhB,OAAO,CAAC,UAAU;IAOlB,OAAO,CAAC,OAAO;IAST,SAAS,CAAC,GAAG,EAAE,SAAS,GAAG,OAAO,CAAC,IAAI,CAAC;IAIxC,cAAc,CAAC,KAAK,EAAE,MAAM,EAAE,QAAQ,EAAE,aAAa,GAAG,OAAO,CAAC,IAAI,CAAC;IASrE,cAAc,CAAC,KAAK,EAAE,MAAM,EAAE,QAAQ,EAAE,WAAW,EAAE,GAAG,OAAO,CAAC,IAAI,CAAC;IAQrE,WAAW,CAAC,KAAK,EAAE,MAAM,EAAE,MAAM,EAAE,SAAS,EAAE,MAAM,EAAE,UAAU,GAAG,OAAO,CAAC,IAAI,CAAC;IAchF,MAAM,CAAC,KAAK,EAAE,MAAM,GAAG,OAAO,CAAC,SAAS,GAAG,SAAS,CAAC;IAIrD,cAAc,CAAC,MAAM,EAAE,MAAM,GAAG,OAAO,CAAC,SAAS,GAAG,SAAS,CAAC;IAS9D,aAAa,IAAI,OAAO,CAAC,SAAS,EAAE,CAAC;IAIrC,eAAe,IAAI,OAAO,CAAC,SAAS,EAAE,CAAC;IAMvC,SAAS,CAAC,KAAK,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC;IASvC,KAAK,IAAI,OAAO,CAAC,IAAI,CAAC;CAG7B"}
@@ -0,0 +1,131 @@
1
+ import { join } from "node:path";
2
+ import { existsSync, mkdirSync, readFileSync, writeFileSync, renameSync, readdirSync, unlinkSync, } from "node:fs";
3
+ function safeJsonParse(raw, fallback) {
4
+ try {
5
+ return JSON.parse(raw);
6
+ }
7
+ catch {
8
+ return fallback;
9
+ }
10
+ }
11
+ /** Atomic write: write to tmp file then rename. */
12
+ function atomicWrite(filePath, data) {
13
+ const tmp = filePath + ".tmp";
14
+ writeFileSync(tmp, JSON.stringify(data, null, 2), "utf-8");
15
+ renameSync(tmp, filePath);
16
+ }
17
+ /**
18
+ * Filesystem-based RunStore.
19
+ * Each run is a single JSON file in .polpo/runs/<runId>.json.
20
+ *
21
+ * Concurrency model: the runner subprocess owns its run file (writes),
22
+ * the orchestrator only reads. No cross-process write conflicts.
23
+ */
24
+ export class FileRunStore {
25
+ runsDir;
26
+ constructor(polpoDir) {
27
+ this.runsDir = join(polpoDir, "runs");
28
+ if (!existsSync(this.runsDir))
29
+ mkdirSync(this.runsDir, { recursive: true });
30
+ }
31
+ runPath(id) {
32
+ return join(this.runsDir, `${id}.json`);
33
+ }
34
+ readRun(id) {
35
+ const path = this.runPath(id);
36
+ if (!existsSync(path))
37
+ return undefined;
38
+ try {
39
+ return safeJsonParse(readFileSync(path, "utf-8"), undefined);
40
+ }
41
+ catch {
42
+ return undefined;
43
+ }
44
+ }
45
+ writeRun(run) {
46
+ atomicWrite(this.runPath(run.id), run);
47
+ }
48
+ listRunIds() {
49
+ if (!existsSync(this.runsDir))
50
+ return [];
51
+ return readdirSync(this.runsDir)
52
+ .filter(f => f.endsWith(".json") && !f.endsWith(".tmp"))
53
+ .map(f => f.slice(0, -5));
54
+ }
55
+ allRuns() {
56
+ const records = [];
57
+ for (const id of this.listRunIds()) {
58
+ const run = this.readRun(id);
59
+ if (run)
60
+ records.push(run);
61
+ }
62
+ return records;
63
+ }
64
+ async upsertRun(run) {
65
+ this.writeRun(run);
66
+ }
67
+ async updateActivity(runId, activity) {
68
+ const run = this.readRun(runId);
69
+ if (!run)
70
+ return;
71
+ run.activity = activity;
72
+ if (activity.sessionId)
73
+ run.sessionId = activity.sessionId;
74
+ run.updatedAt = new Date().toISOString();
75
+ this.writeRun(run);
76
+ }
77
+ async updateOutcomes(runId, outcomes) {
78
+ const run = this.readRun(runId);
79
+ if (!run)
80
+ return;
81
+ run.outcomes = outcomes;
82
+ run.updatedAt = new Date().toISOString();
83
+ this.writeRun(run);
84
+ }
85
+ async completeRun(runId, status, result) {
86
+ const run = this.readRun(runId);
87
+ if (!run)
88
+ return;
89
+ // Don't let a later write overwrite a run already in terminal state.
90
+ // This prevents the runner process from clobbering the orchestrator's
91
+ // "killed" status with a stale "completed" result (race condition).
92
+ const terminal = ["completed", "failed", "killed"];
93
+ if (terminal.includes(run.status))
94
+ return;
95
+ run.status = status;
96
+ run.result = result;
97
+ run.updatedAt = new Date().toISOString();
98
+ this.writeRun(run);
99
+ }
100
+ async getRun(runId) {
101
+ return this.readRun(runId);
102
+ }
103
+ async getRunByTaskId(taskId) {
104
+ // Scan all runs — small directory, fast enough
105
+ for (const id of this.listRunIds()) {
106
+ const run = this.readRun(id);
107
+ if (run && run.taskId === taskId)
108
+ return run;
109
+ }
110
+ return undefined;
111
+ }
112
+ async getActiveRuns() {
113
+ return this.allRuns().filter(r => r.status === "running");
114
+ }
115
+ async getTerminalRuns() {
116
+ return this.allRuns().filter(r => r.status === "completed" || r.status === "failed" || r.status === "killed");
117
+ }
118
+ async deleteRun(runId) {
119
+ const path = this.runPath(runId);
120
+ try {
121
+ unlinkSync(path);
122
+ }
123
+ catch {
124
+ /* already gone */
125
+ }
126
+ }
127
+ async close() {
128
+ // No-op for filesystem store
129
+ }
130
+ }
131
+ //# sourceMappingURL=file-run-store.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"file-run-store.js","sourceRoot":"","sources":["../src/file-run-store.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,28 @@
1
+ import type { SessionStore, Session, Message, MessageRole, ToolCallInfo, SessionContentPart, SessionCreateOptions, SessionListFilter } from "@polpo-ai/core/session-store";
2
+ /**
3
+ * File-backed SessionStore.
4
+ * Writes JSONL files to `.polpo/sessions/`, one per session.
5
+ *
6
+ * File naming: `{sessionId}.jsonl`
7
+ * First line of each file: `{"_session":true,"id":"...","title":"...","createdAt":"..."}`
8
+ */
9
+ export declare class FileSessionStore implements SessionStore {
10
+ private readonly sessionsDir;
11
+ constructor(polpoDir: string);
12
+ create(arg1?: string | SessionCreateOptions, arg2?: string): Promise<string>;
13
+ addMessage(sessionId: string, role: MessageRole, content: string | SessionContentPart[]): Promise<Message>;
14
+ updateMessage(sessionId: string, messageId: string, content: string | SessionContentPart[], toolCalls?: ToolCallInfo[]): Promise<boolean>;
15
+ getMessages(sessionId: string): Promise<Message[]>;
16
+ getRecentMessages(sessionId: string, limit: number): Promise<Message[]>;
17
+ /** Build a Session out of a session file's first line + mtime. */
18
+ private headerToSession;
19
+ listSessions(filter?: SessionListFilter): Promise<Session[]>;
20
+ getSession(sessionId: string): Promise<Session | undefined>;
21
+ getLatestSession(agent?: string | null): Promise<Session | undefined>;
22
+ renameSession(sessionId: string, title: string): Promise<boolean>;
23
+ deleteSession(sessionId: string): Promise<boolean>;
24
+ prune(keepSessions: number): Promise<number>;
25
+ close(): Promise<void>;
26
+ private sessionFile;
27
+ }
28
+ //# sourceMappingURL=file-session-store.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"file-session-store.d.ts","sourceRoot":"","sources":["../src/file-session-store.ts"],"names":[],"mappings":"AAYA,OAAO,KAAK,EACV,YAAY,EACZ,OAAO,EACP,OAAO,EACP,WAAW,EACX,YAAY,EACZ,kBAAkB,EAClB,oBAAoB,EACpB,iBAAiB,EAClB,MAAM,8BAA8B,CAAC;AAGtC;;;;;;GAMG;AACH,qBAAa,gBAAiB,YAAW,YAAY;IACnD,OAAO,CAAC,QAAQ,CAAC,WAAW,CAAS;gBAEzB,QAAQ,EAAE,MAAM;IAItB,MAAM,CAAC,IAAI,CAAC,EAAE,MAAM,GAAG,oBAAoB,EAAE,IAAI,CAAC,EAAE,MAAM,GAAG,OAAO,CAAC,MAAM,CAAC;IAsB5E,UAAU,CAAC,SAAS,EAAE,MAAM,EAAE,IAAI,EAAE,WAAW,EAAE,OAAO,EAAE,MAAM,GAAG,kBAAkB,EAAE,GAAG,OAAO,CAAC,OAAO,CAAC;IAe1G,aAAa,CAAC,SAAS,EAAE,MAAM,EAAE,SAAS,EAAE,MAAM,EAAE,OAAO,EAAE,MAAM,GAAG,kBAAkB,EAAE,EAAE,SAAS,CAAC,EAAE,YAAY,EAAE,GAAG,OAAO,CAAC,OAAO,CAAC;IA2BzI,WAAW,CAAC,SAAS,EAAE,MAAM,GAAG,OAAO,CAAC,OAAO,EAAE,CAAC;IAkBlD,iBAAiB,CAAC,SAAS,EAAE,MAAM,EAAE,KAAK,EAAE,MAAM,GAAG,OAAO,CAAC,OAAO,EAAE,CAAC;IAK7E,kEAAkE;IAClE,OAAO,CAAC,eAAe;IAcjB,YAAY,CAAC,MAAM,CAAC,EAAE,iBAAiB,GAAG,OAAO,CAAC,OAAO,EAAE,CAAC;IAuC5D,UAAU,CAAC,SAAS,EAAE,MAAM,GAAG,OAAO,CAAC,OAAO,GAAG,SAAS,CAAC;IAe3D,gBAAgB,CAAC,KAAK,CAAC,EAAE,MAAM,GAAG,IAAI,GAAG,OAAO,CAAC,OAAO,GAAG,SAAS,CAAC;IAcrE,aAAa,CAAC,SAAS,EAAE,MAAM,EAAE,KAAK,EAAE,MAAM,GAAG,OAAO,CAAC,OAAO,CAAC;IAkBjE,aAAa,CAAC,SAAS,EAAE,MAAM,GAAG,OAAO,CAAC,OAAO,CAAC;IAWlD,KAAK,CAAC,YAAY,EAAE,MAAM,GAAG,OAAO,CAAC,MAAM,CAAC;IAc5C,KAAK,IAAI,OAAO,CAAC,IAAI,CAAC;IAI5B,OAAO,CAAC,WAAW;CAGpB"}
@@ -0,0 +1,245 @@
1
+ import { existsSync, mkdirSync, appendFileSync, readFileSync, writeFileSync, readdirSync, unlinkSync, statSync, } from "node:fs";
2
+ import { join } from "node:path";
3
+ import { nanoid } from "nanoid";
4
+ import { normalizeSessionCreateArgs } from "@polpo-ai/core/session-store";
5
+ /**
6
+ * File-backed SessionStore.
7
+ * Writes JSONL files to `.polpo/sessions/`, one per session.
8
+ *
9
+ * File naming: `{sessionId}.jsonl`
10
+ * First line of each file: `{"_session":true,"id":"...","title":"...","createdAt":"..."}`
11
+ */
12
+ export class FileSessionStore {
13
+ sessionsDir;
14
+ constructor(polpoDir) {
15
+ this.sessionsDir = join(polpoDir, "sessions");
16
+ }
17
+ async create(arg1, arg2) {
18
+ const opts = normalizeSessionCreateArgs(arg1, arg2);
19
+ if (!existsSync(this.sessionsDir)) {
20
+ mkdirSync(this.sessionsDir, { recursive: true });
21
+ }
22
+ const sessionId = nanoid(10);
23
+ const header = {
24
+ _session: true,
25
+ id: sessionId,
26
+ title: opts.title,
27
+ createdAt: new Date().toISOString(),
28
+ };
29
+ if (opts.agent)
30
+ header.agent = opts.agent;
31
+ if (opts.user)
32
+ header.user = opts.user;
33
+ if (opts.metadata)
34
+ header.metadata = opts.metadata;
35
+ try {
36
+ appendFileSync(this.sessionFile(sessionId), JSON.stringify(header) + "\n", "utf-8");
37
+ }
38
+ catch { /* best-effort: non-critical */
39
+ }
40
+ return sessionId;
41
+ }
42
+ async addMessage(sessionId, role, content) {
43
+ const message = {
44
+ id: nanoid(10),
45
+ role,
46
+ content,
47
+ ts: new Date().toISOString(),
48
+ };
49
+ try {
50
+ const line = JSON.stringify(message);
51
+ appendFileSync(this.sessionFile(sessionId), line + "\n", "utf-8");
52
+ }
53
+ catch { /* best-effort: non-critical */
54
+ }
55
+ return message;
56
+ }
57
+ async updateMessage(sessionId, messageId, content, toolCalls) {
58
+ const file = this.sessionFile(sessionId);
59
+ if (!existsSync(file))
60
+ return false;
61
+ try {
62
+ const raw = readFileSync(file, "utf-8");
63
+ const lines = raw.split("\n").filter(Boolean);
64
+ let found = false;
65
+ const updated = lines.map((line) => {
66
+ const obj = JSON.parse(line);
67
+ if (!obj._session && obj.id === messageId) {
68
+ found = true;
69
+ const patched = { ...obj, content };
70
+ if (toolCalls && toolCalls.length > 0) {
71
+ patched.toolCalls = toolCalls;
72
+ }
73
+ return JSON.stringify(patched);
74
+ }
75
+ return line;
76
+ });
77
+ if (!found)
78
+ return false;
79
+ writeFileSync(file, updated.join("\n") + "\n", "utf-8");
80
+ return true;
81
+ }
82
+ catch {
83
+ return false;
84
+ }
85
+ }
86
+ async getMessages(sessionId) {
87
+ const file = this.sessionFile(sessionId);
88
+ if (!existsSync(file))
89
+ return [];
90
+ try {
91
+ const lines = readFileSync(file, "utf-8").split("\n").filter(Boolean);
92
+ const messages = [];
93
+ for (const line of lines) {
94
+ const obj = JSON.parse(line);
95
+ // Skip session header
96
+ if (obj._session)
97
+ continue;
98
+ messages.push(obj);
99
+ }
100
+ return messages;
101
+ }
102
+ catch { /* unreadable session file */
103
+ return [];
104
+ }
105
+ }
106
+ async getRecentMessages(sessionId, limit) {
107
+ const messages = await this.getMessages(sessionId);
108
+ return messages.slice(-limit);
109
+ }
110
+ /** Build a Session out of a session file's first line + mtime. */
111
+ headerToSession(header, filePath, fallbackId) {
112
+ const updatedAt = new Date(statSync(filePath).mtimeMs).toISOString();
113
+ return {
114
+ id: header.id ?? fallbackId,
115
+ title: header.title,
116
+ createdAt: header.createdAt ?? updatedAt,
117
+ updatedAt,
118
+ messageCount: 0,
119
+ ...(header.agent ? { agent: header.agent } : {}),
120
+ ...(header.user ? { user: header.user } : {}),
121
+ ...(header.metadata ? { metadata: header.metadata } : {}),
122
+ };
123
+ }
124
+ async listSessions(filter) {
125
+ if (!existsSync(this.sessionsDir))
126
+ return [];
127
+ const files = readdirSync(this.sessionsDir)
128
+ .filter(f => f.endsWith(".jsonl"));
129
+ // Sort by modification time (most recent first)
130
+ const withMtime = files.map(f => ({
131
+ file: f,
132
+ mtime: statSync(join(this.sessionsDir, f)).mtimeMs,
133
+ }));
134
+ withMtime.sort((a, b) => b.mtime - a.mtime);
135
+ const sessions = [];
136
+ for (const { file } of withMtime) {
137
+ const filePath = join(this.sessionsDir, file);
138
+ try {
139
+ const content = readFileSync(filePath, "utf-8");
140
+ const lines = content.split("\n").filter(Boolean);
141
+ const header = JSON.parse(lines[0]);
142
+ const session = this.headerToSession(header, filePath, file.replace(".jsonl", ""));
143
+ session.messageCount = lines.length - 1;
144
+ // In-memory filter — file store has no index, so we scan + filter.
145
+ // Acceptable here because file store is for dev/CLI, not high-traffic.
146
+ if (filter?.user && session.user !== filter.user)
147
+ continue;
148
+ if (filter?.metadata) {
149
+ const sessMeta = session.metadata ?? {};
150
+ const allMatch = Object.entries(filter.metadata).every(([k, v]) => sessMeta[k] === v);
151
+ if (!allMatch)
152
+ continue;
153
+ }
154
+ sessions.push(session);
155
+ }
156
+ catch { /* skip corrupt file */
157
+ }
158
+ }
159
+ return sessions;
160
+ }
161
+ async getSession(sessionId) {
162
+ const file = this.sessionFile(sessionId);
163
+ if (!existsSync(file))
164
+ return undefined;
165
+ try {
166
+ const content = readFileSync(file, "utf-8");
167
+ const lines = content.split("\n").filter(Boolean);
168
+ const header = JSON.parse(lines[0]);
169
+ const session = this.headerToSession(header, file, sessionId);
170
+ session.messageCount = lines.length - 1;
171
+ return session;
172
+ }
173
+ catch { /* unreadable session file */
174
+ return undefined;
175
+ }
176
+ }
177
+ async getLatestSession(agent) {
178
+ const sessions = await this.listSessions();
179
+ if (agent === undefined) {
180
+ // No filter — return the most recent session regardless of agent
181
+ return sessions[0];
182
+ }
183
+ if (agent === null) {
184
+ // Orchestrator sessions only (no agent)
185
+ return sessions.find(s => !s.agent);
186
+ }
187
+ // Agent-specific sessions
188
+ return sessions.find(s => s.agent === agent);
189
+ }
190
+ async renameSession(sessionId, title) {
191
+ const file = this.sessionFile(sessionId);
192
+ if (!existsSync(file))
193
+ return false;
194
+ try {
195
+ const raw = readFileSync(file, "utf-8");
196
+ const lines = raw.split("\n").filter(Boolean);
197
+ if (lines.length === 0)
198
+ return false;
199
+ const header = JSON.parse(lines[0]);
200
+ if (!header._session)
201
+ return false;
202
+ header.title = title;
203
+ lines[0] = JSON.stringify(header);
204
+ writeFileSync(file, lines.join("\n") + "\n", "utf-8");
205
+ return true;
206
+ }
207
+ catch {
208
+ return false;
209
+ }
210
+ }
211
+ async deleteSession(sessionId) {
212
+ const file = this.sessionFile(sessionId);
213
+ if (!existsSync(file))
214
+ return false;
215
+ try {
216
+ unlinkSync(file);
217
+ return true;
218
+ }
219
+ catch { /* file already removed */
220
+ return false;
221
+ }
222
+ }
223
+ async prune(keepSessions) {
224
+ const sessions = await this.listSessions();
225
+ if (sessions.length <= keepSessions)
226
+ return 0;
227
+ const toRemove = sessions.slice(keepSessions);
228
+ let removed = 0;
229
+ for (const s of toRemove) {
230
+ try {
231
+ unlinkSync(this.sessionFile(s.id));
232
+ removed++;
233
+ }
234
+ catch { /* file already removed */ }
235
+ }
236
+ return removed;
237
+ }
238
+ async close() {
239
+ // No resources to release for file-based store
240
+ }
241
+ sessionFile(sessionId) {
242
+ return join(this.sessionsDir, `${sessionId}.jsonl`);
243
+ }
244
+ }
245
+ //# sourceMappingURL=file-session-store.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"file-session-store.js","sourceRoot":"","sources":["../src/file-session-store.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,26 @@
1
+ import type { SkillStore, SkillRecord } from "@polpo-ai/core";
2
+ /**
3
+ * File-backed SkillStore.
4
+ *
5
+ * Persists the full catalog to `${polpoDir}/skills-index.json` as a
6
+ * JSON object keyed by skill name. Writes are atomic (tmp + rename).
7
+ *
8
+ * Legacy compatibility: the old `skills-index.json` format contained
9
+ * only `{ tags?, category? }` per skill. This store reads those files
10
+ * transparently (treating them as partial records) and the caller —
11
+ * typically the upsert triggered by skills/add — fills in the full
12
+ * record on next write.
13
+ */
14
+ export declare class FileSkillStore implements SkillStore {
15
+ private readonly filePath;
16
+ constructor(polpoDir: string);
17
+ list(): Promise<SkillRecord[]>;
18
+ get(name: string): Promise<SkillRecord | undefined>;
19
+ upsert(record: SkillRecord): Promise<void>;
20
+ remove(name: string): Promise<boolean>;
21
+ /** Read the JSON file, normalising legacy shapes. */
22
+ private readAll;
23
+ /** Write the full catalog atomically (tmp + rename). */
24
+ private writeAll;
25
+ }
26
+ //# sourceMappingURL=file-skill-store.d.ts.map