@mrtdown/core 2.0.0-alpha.3 → 2.0.0-alpha.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.
- package/dist/cli/commands/create.d.ts +30 -0
- package/dist/cli/commands/create.js +189 -0
- package/dist/cli/commands/create.js.map +1 -0
- package/dist/cli/commands/list.d.ts +6 -0
- package/dist/cli/commands/list.js +106 -0
- package/dist/cli/commands/list.js.map +1 -0
- package/dist/cli/commands/show.d.ts +6 -0
- package/dist/cli/commands/show.js +156 -0
- package/dist/cli/commands/show.js.map +1 -0
- package/dist/cli/commands/validate.d.ts +6 -0
- package/dist/cli/commands/validate.js +19 -0
- package/dist/cli/commands/validate.js.map +1 -0
- package/dist/cli/index.d.ts +2 -0
- package/dist/cli/index.js +162 -0
- package/dist/cli/index.js.map +1 -0
- package/dist/helpers/keyForAffectedEntity.d.ts +1 -1
- package/dist/helpers/keyForAffectedEntity.js.map +1 -1
- package/dist/helpers/normalizeRecurringPeriod.d.ts +1 -1
- package/dist/helpers/normalizeRecurringPeriod.js +1 -1
- package/dist/helpers/normalizeRecurringPeriod.js.map +1 -1
- package/dist/helpers/normalizeRecurringPeriod.test.js.map +1 -1
- package/dist/helpers/resolvePeriods.d.ts +1 -1
- package/dist/helpers/resolvePeriods.js +1 -1
- package/dist/helpers/resolvePeriods.js.map +1 -1
- package/dist/helpers/resolvePeriods.test.js.map +1 -1
- package/dist/index.d.ts +25 -25
- package/dist/index.js +25 -25
- package/dist/index.js.map +1 -1
- package/dist/llm/client.d.ts +2 -0
- package/dist/llm/client.js +5 -0
- package/dist/llm/client.js.map +1 -0
- package/dist/llm/common/MemoryStore.d.ts +21 -0
- package/dist/llm/common/MemoryStore.js +100 -0
- package/dist/llm/common/MemoryStore.js.map +1 -0
- package/dist/llm/common/MemoryStore.test.d.ts +1 -0
- package/dist/llm/common/MemoryStore.test.js +225 -0
- package/dist/llm/common/MemoryStore.test.js.map +1 -0
- package/dist/llm/common/formatCurrentState.d.ts +10 -0
- package/dist/llm/common/formatCurrentState.js +342 -0
- package/dist/llm/common/formatCurrentState.js.map +1 -0
- package/dist/llm/common/tool.d.ts +32 -0
- package/dist/llm/common/tool.js +6 -0
- package/dist/llm/common/tool.js.map +1 -0
- package/dist/llm/functions/extractClaimsFromNewEvidence/eval.test.d.ts +1 -0
- package/dist/llm/functions/extractClaimsFromNewEvidence/eval.test.js +433 -0
- package/dist/llm/functions/extractClaimsFromNewEvidence/eval.test.js.map +1 -0
- package/dist/llm/functions/extractClaimsFromNewEvidence/index.d.ts +18 -0
- package/dist/llm/functions/extractClaimsFromNewEvidence/index.js +153 -0
- package/dist/llm/functions/extractClaimsFromNewEvidence/index.js.map +1 -0
- package/dist/llm/functions/extractClaimsFromNewEvidence/prompt.d.ts +1 -0
- package/dist/llm/functions/extractClaimsFromNewEvidence/prompt.js +168 -0
- package/dist/llm/functions/extractClaimsFromNewEvidence/prompt.js.map +1 -0
- package/dist/llm/functions/extractClaimsFromNewEvidence/tools/FindLinesTool.d.ts +19 -0
- package/dist/llm/functions/extractClaimsFromNewEvidence/tools/FindLinesTool.js +65 -0
- package/dist/llm/functions/extractClaimsFromNewEvidence/tools/FindLinesTool.js.map +1 -0
- package/dist/llm/functions/extractClaimsFromNewEvidence/tools/FindServicesTool.d.ts +21 -0
- package/dist/llm/functions/extractClaimsFromNewEvidence/tools/FindServicesTool.js +115 -0
- package/dist/llm/functions/extractClaimsFromNewEvidence/tools/FindServicesTool.js.map +1 -0
- package/dist/llm/functions/extractClaimsFromNewEvidence/tools/FindStationsTool.d.ts +24 -0
- package/dist/llm/functions/extractClaimsFromNewEvidence/tools/FindStationsTool.js +110 -0
- package/dist/llm/functions/extractClaimsFromNewEvidence/tools/FindStationsTool.js.map +1 -0
- package/dist/llm/functions/generateIssueTitleAndSlug/index.d.ts +14 -0
- package/dist/llm/functions/generateIssueTitleAndSlug/index.js +38 -0
- package/dist/llm/functions/generateIssueTitleAndSlug/index.js.map +1 -0
- package/dist/llm/functions/generateIssueTitleAndSlug/prompt.d.ts +1 -0
- package/dist/llm/functions/generateIssueTitleAndSlug/prompt.js +23 -0
- package/dist/llm/functions/generateIssueTitleAndSlug/prompt.js.map +1 -0
- package/dist/llm/functions/translate/index.d.ts +1 -0
- package/dist/llm/functions/translate/index.js +59 -0
- package/dist/llm/functions/translate/index.js.map +1 -0
- package/dist/llm/functions/triageNewEvidence/eval.test.d.ts +1 -0
- package/dist/llm/functions/triageNewEvidence/eval.test.js +139 -0
- package/dist/llm/functions/triageNewEvidence/eval.test.js.map +1 -0
- package/dist/llm/functions/triageNewEvidence/index.d.ts +37 -0
- package/dist/llm/functions/triageNewEvidence/index.js +121 -0
- package/dist/llm/functions/triageNewEvidence/index.js.map +1 -0
- package/dist/llm/functions/triageNewEvidence/prompt.d.ts +1 -0
- package/dist/llm/functions/triageNewEvidence/prompt.js +60 -0
- package/dist/llm/functions/triageNewEvidence/prompt.js.map +1 -0
- package/dist/llm/functions/triageNewEvidence/tools/FindIssuesTool.d.ts +19 -0
- package/dist/llm/functions/triageNewEvidence/tools/FindIssuesTool.js +65 -0
- package/dist/llm/functions/triageNewEvidence/tools/FindIssuesTool.js.map +1 -0
- package/dist/llm/functions/triageNewEvidence/tools/GetIssueTool.d.ts +19 -0
- package/dist/llm/functions/triageNewEvidence/tools/GetIssueTool.js +37 -0
- package/dist/llm/functions/triageNewEvidence/tools/GetIssueTool.js.map +1 -0
- package/dist/repo/issue/IssueRepository.d.ts +1 -1
- package/dist/repo/issue/IssueRepository.js +3 -3
- package/dist/repo/issue/IssueRepository.js.map +1 -1
- package/dist/repo/issue/helpers/deriveCurrentState.d.ts +6 -6
- package/dist/repo/issue/helpers/deriveCurrentState.js +1 -1
- package/dist/repo/issue/helpers/deriveCurrentState.js.map +1 -1
- package/dist/repo/issue/helpers/deriveCurrentState.test.js.map +1 -1
- package/dist/schema/issue/evidence.js +1 -1
- package/dist/schema/issue/evidence.js.map +1 -1
- package/dist/schema/issue/issue.js +1 -1
- package/dist/schema/issue/issue.js.map +1 -1
- package/dist/scripts/ingestViaWebhook.d.ts +1 -0
- package/dist/scripts/ingestViaWebhook.js +9 -0
- package/dist/scripts/ingestViaWebhook.js.map +1 -0
- package/dist/util/ingestContent/helpers/getSlugDateTimeFromClaims.d.ts +1 -1
- package/dist/util/ingestContent/helpers/getSlugDateTimeFromClaims.js +1 -1
- package/dist/util/ingestContent/helpers/getSlugDateTimeFromClaims.js.map +1 -1
- package/dist/util/ingestContent/index.js +9 -9
- package/dist/util/ingestContent/index.js.map +1 -1
- package/dist/validators/buildContext.d.ts +7 -0
- package/dist/validators/buildContext.js +164 -0
- package/dist/validators/buildContext.js.map +1 -0
- package/dist/validators/index.d.ts +17 -0
- package/dist/validators/index.js +58 -0
- package/dist/validators/index.js.map +1 -0
- package/dist/validators/issue.d.ts +13 -0
- package/dist/validators/issue.js +220 -0
- package/dist/validators/issue.js.map +1 -0
- package/dist/validators/landmark.d.ts +7 -0
- package/dist/validators/landmark.js +43 -0
- package/dist/validators/landmark.js.map +1 -0
- package/dist/validators/line.d.ts +8 -0
- package/dist/validators/line.js +87 -0
- package/dist/validators/line.js.map +1 -0
- package/dist/validators/operator.d.ts +7 -0
- package/dist/validators/operator.js +43 -0
- package/dist/validators/operator.js.map +1 -0
- package/dist/validators/service.d.ts +8 -0
- package/dist/validators/service.js +87 -0
- package/dist/validators/service.js.map +1 -0
- package/dist/validators/station.d.ts +8 -0
- package/dist/validators/station.js +93 -0
- package/dist/validators/station.js.map +1 -0
- package/dist/validators/town.d.ts +7 -0
- package/dist/validators/town.js +43 -0
- package/dist/validators/town.js.map +1 -0
- package/dist/validators/types.d.ts +19 -0
- package/dist/validators/types.js +2 -0
- package/dist/validators/types.js.map +1 -0
- package/dist/validators/utils.d.ts +2 -0
- package/dist/validators/utils.js +9 -0
- package/dist/validators/utils.js.map +1 -0
- package/dist/write/issue/IssueWriter.d.ts +3 -3
- package/dist/write/issue/IssueWriter.js.map +1 -1
- package/package.json +2 -7
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
import type { IStore } from '../../repo/common/store.js';
|
|
2
|
+
import type { IWriteStore } from '../../write/common/store.js';
|
|
3
|
+
export declare class MemoryStore implements IStore, IWriteStore {
|
|
4
|
+
private readonly files;
|
|
5
|
+
private readonly dirs;
|
|
6
|
+
constructor(seed?: {
|
|
7
|
+
files?: Record<string, string>;
|
|
8
|
+
});
|
|
9
|
+
private toStorePath;
|
|
10
|
+
exists(path: string): boolean;
|
|
11
|
+
readText(path: string): string;
|
|
12
|
+
readJson<T>(path: string): T;
|
|
13
|
+
listDir(path: string): string[];
|
|
14
|
+
ensureDir(path: string): void;
|
|
15
|
+
private addChild;
|
|
16
|
+
writeText(path: string, text: string): void;
|
|
17
|
+
writeJson(path: string, json: unknown): void;
|
|
18
|
+
appendText(path: string, text: string): void;
|
|
19
|
+
delete(path: string): void;
|
|
20
|
+
dumpFiles(): Record<string, string>;
|
|
21
|
+
}
|
|
@@ -0,0 +1,100 @@
|
|
|
1
|
+
import { basename, dirname, normalize } from 'node:path';
|
|
2
|
+
export class MemoryStore {
|
|
3
|
+
files = new Map();
|
|
4
|
+
dirs = new Map();
|
|
5
|
+
constructor(seed) {
|
|
6
|
+
// Root dir
|
|
7
|
+
this.dirs.set('', new Set());
|
|
8
|
+
if (seed?.files) {
|
|
9
|
+
for (const [path, text] of Object.entries(seed.files)) {
|
|
10
|
+
this.writeText(path, text);
|
|
11
|
+
}
|
|
12
|
+
}
|
|
13
|
+
}
|
|
14
|
+
// --------- IStore ---------
|
|
15
|
+
toStorePath(path) {
|
|
16
|
+
const p = normalize(path);
|
|
17
|
+
return p === '.' ? '' : p;
|
|
18
|
+
}
|
|
19
|
+
exists(path) {
|
|
20
|
+
const p = this.toStorePath(path);
|
|
21
|
+
return this.files.has(p) || this.dirs.has(p);
|
|
22
|
+
}
|
|
23
|
+
readText(path) {
|
|
24
|
+
const p = this.toStorePath(path);
|
|
25
|
+
const v = this.files.get(p);
|
|
26
|
+
if (v == null) {
|
|
27
|
+
throw new Error(`MemoryStore: File not found: ${path}`);
|
|
28
|
+
}
|
|
29
|
+
return v;
|
|
30
|
+
}
|
|
31
|
+
readJson(path) {
|
|
32
|
+
return JSON.parse(this.readText(path));
|
|
33
|
+
}
|
|
34
|
+
listDir(path) {
|
|
35
|
+
const p = this.toStorePath(path);
|
|
36
|
+
const children = this.dirs.get(p);
|
|
37
|
+
if (children == null) {
|
|
38
|
+
throw new Error(`MemoryStore: Directory not found: ${path}`);
|
|
39
|
+
}
|
|
40
|
+
return Array.from(children.values()).sort();
|
|
41
|
+
}
|
|
42
|
+
// --------- IWriteStore ---------
|
|
43
|
+
ensureDir(path) {
|
|
44
|
+
const p = this.toStorePath(path);
|
|
45
|
+
if (this.dirs.has(p)) {
|
|
46
|
+
return;
|
|
47
|
+
}
|
|
48
|
+
// Ensure parents (dirname returns '.' for root, treat as '')
|
|
49
|
+
const rawParent = dirname(p === '' ? '.' : p);
|
|
50
|
+
const parent = rawParent === '.' ? '' : rawParent;
|
|
51
|
+
if (parent !== '') {
|
|
52
|
+
this.ensureDir(parent);
|
|
53
|
+
}
|
|
54
|
+
// Create this directory
|
|
55
|
+
this.dirs.set(p, new Set());
|
|
56
|
+
// Register in parent (including root when parent is '')
|
|
57
|
+
this.addChild(parent, basename(p));
|
|
58
|
+
}
|
|
59
|
+
addChild(dir, child) {
|
|
60
|
+
const d = this.toStorePath(dir);
|
|
61
|
+
const set = this.dirs.get(d);
|
|
62
|
+
if (set == null) {
|
|
63
|
+
this.ensureDir(d);
|
|
64
|
+
this.addChild(d, child);
|
|
65
|
+
return;
|
|
66
|
+
}
|
|
67
|
+
set.add(child);
|
|
68
|
+
}
|
|
69
|
+
writeText(path, text) {
|
|
70
|
+
const p = this.toStorePath(path);
|
|
71
|
+
this.ensureDir(dirname(p));
|
|
72
|
+
this.addChild(dirname(p), basename(p));
|
|
73
|
+
this.files.set(p, text);
|
|
74
|
+
}
|
|
75
|
+
writeJson(path, json) {
|
|
76
|
+
this.writeText(path, JSON.stringify(json));
|
|
77
|
+
}
|
|
78
|
+
appendText(path, text) {
|
|
79
|
+
const p = this.toStorePath(path);
|
|
80
|
+
this.ensureDir(dirname(p));
|
|
81
|
+
this.addChild(dirname(p), basename(p));
|
|
82
|
+
const prevContent = this.files.get(p) ?? '';
|
|
83
|
+
this.files.set(p, prevContent + text);
|
|
84
|
+
}
|
|
85
|
+
delete(path) {
|
|
86
|
+
const p = this.toStorePath(path);
|
|
87
|
+
this.files.delete(p);
|
|
88
|
+
this.dirs.delete(p);
|
|
89
|
+
this.dirs.delete(path);
|
|
90
|
+
}
|
|
91
|
+
// Debug helpers
|
|
92
|
+
dumpFiles() {
|
|
93
|
+
const result = {};
|
|
94
|
+
for (const [path, text] of this.files.entries()) {
|
|
95
|
+
result[path] = text;
|
|
96
|
+
}
|
|
97
|
+
return result;
|
|
98
|
+
}
|
|
99
|
+
}
|
|
100
|
+
//# sourceMappingURL=MemoryStore.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"MemoryStore.js","sourceRoot":"/","sources":["llm/common/MemoryStore.ts"],"names":[],"mappings":"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","sourcesContent":["import { basename, dirname, normalize } from 'node:path';\nimport type { IStore } from '../../repo/common/store.js';\nimport type { IWriteStore } from '../../write/common/store.js';\n\nexport class MemoryStore implements IStore, IWriteStore {\n private readonly files = new Map<string, string>();\n private readonly dirs = new Map<string, Set<string>>();\n\n constructor(seed?: { files?: Record<string, string> }) {\n // Root dir\n this.dirs.set('', new Set());\n\n if (seed?.files) {\n for (const [path, text] of Object.entries(seed.files)) {\n this.writeText(path, text);\n }\n }\n }\n\n // --------- IStore ---------\n private toStorePath(path: string): string {\n const p = normalize(path);\n return p === '.' ? '' : p;\n }\n\n exists(path: string): boolean {\n const p = this.toStorePath(path);\n return this.files.has(p) || this.dirs.has(p);\n }\n\n readText(path: string): string {\n const p = this.toStorePath(path);\n const v = this.files.get(p);\n if (v == null) {\n throw new Error(`MemoryStore: File not found: ${path}`);\n }\n return v;\n }\n\n readJson<T>(path: string): T {\n return JSON.parse(this.readText(path));\n }\n\n listDir(path: string): string[] {\n const p = this.toStorePath(path);\n const children = this.dirs.get(p);\n if (children == null) {\n throw new Error(`MemoryStore: Directory not found: ${path}`);\n }\n return Array.from(children.values()).sort();\n }\n\n // --------- IWriteStore ---------\n ensureDir(path: string): void {\n const p = this.toStorePath(path);\n if (this.dirs.has(p)) {\n return;\n }\n\n // Ensure parents (dirname returns '.' for root, treat as '')\n const rawParent = dirname(p === '' ? '.' : p);\n const parent = rawParent === '.' ? '' : rawParent;\n if (parent !== '') {\n this.ensureDir(parent);\n }\n\n // Create this directory\n this.dirs.set(p, new Set());\n\n // Register in parent (including root when parent is '')\n this.addChild(parent, basename(p));\n }\n\n private addChild(dir: string, child: string): void {\n const d = this.toStorePath(dir);\n const set = this.dirs.get(d);\n if (set == null) {\n this.ensureDir(d);\n this.addChild(d, child);\n return;\n }\n set.add(child);\n }\n\n writeText(path: string, text: string): void {\n const p = this.toStorePath(path);\n this.ensureDir(dirname(p));\n this.addChild(dirname(p), basename(p));\n this.files.set(p, text);\n }\n\n writeJson(path: string, json: unknown): void {\n this.writeText(path, JSON.stringify(json));\n }\n\n appendText(path: string, text: string): void {\n const p = this.toStorePath(path);\n this.ensureDir(dirname(p));\n this.addChild(dirname(p), basename(p));\n const prevContent = this.files.get(p) ?? '';\n this.files.set(p, prevContent + text);\n }\n\n delete(path: string): void {\n const p = this.toStorePath(path);\n this.files.delete(p);\n this.dirs.delete(p);\n this.dirs.delete(path);\n }\n\n // Debug helpers\n dumpFiles(): Record<string, string> {\n const result: Record<string, string> = {};\n for (const [path, text] of this.files.entries()) {\n result[path] = text;\n }\n return result;\n }\n}\n"]}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export {};
|
|
@@ -0,0 +1,225 @@
|
|
|
1
|
+
import { describe, expect, test } from 'vitest';
|
|
2
|
+
import { MemoryStore } from './MemoryStore.js';
|
|
3
|
+
describe('MemoryStore', () => {
|
|
4
|
+
describe('constructor', () => {
|
|
5
|
+
test('creates empty store by default', () => {
|
|
6
|
+
const store = new MemoryStore();
|
|
7
|
+
expect(store.dumpFiles()).toEqual({});
|
|
8
|
+
expect(store.listDir('')).toEqual([]);
|
|
9
|
+
});
|
|
10
|
+
test('seeds store with files from seed object', () => {
|
|
11
|
+
const store = new MemoryStore({
|
|
12
|
+
files: {
|
|
13
|
+
'foo.txt': 'hello',
|
|
14
|
+
'bar/baz.json': '{"x":1}',
|
|
15
|
+
},
|
|
16
|
+
});
|
|
17
|
+
expect(store.readText('foo.txt')).toBe('hello');
|
|
18
|
+
expect(store.readText('bar/baz.json')).toBe('{"x":1}');
|
|
19
|
+
expect(store.listDir('')).toEqual(['bar', 'foo.txt']);
|
|
20
|
+
expect(store.listDir('bar')).toEqual(['baz.json']);
|
|
21
|
+
});
|
|
22
|
+
});
|
|
23
|
+
describe('exists', () => {
|
|
24
|
+
test('returns false for non-existent path', () => {
|
|
25
|
+
const store = new MemoryStore();
|
|
26
|
+
expect(store.exists('missing')).toBe(false);
|
|
27
|
+
expect(store.exists('a/b/c')).toBe(false);
|
|
28
|
+
});
|
|
29
|
+
test('returns true for root directory', () => {
|
|
30
|
+
const store = new MemoryStore();
|
|
31
|
+
expect(store.exists('')).toBe(true);
|
|
32
|
+
});
|
|
33
|
+
test('returns true for existing file', () => {
|
|
34
|
+
const store = new MemoryStore({ files: { 'foo.txt': 'hi' } });
|
|
35
|
+
expect(store.exists('foo.txt')).toBe(true);
|
|
36
|
+
});
|
|
37
|
+
test('returns true for existing directory', () => {
|
|
38
|
+
const store = new MemoryStore({ files: { 'dir/file.txt': 'hi' } });
|
|
39
|
+
expect(store.exists('dir')).toBe(true);
|
|
40
|
+
});
|
|
41
|
+
test('normalizes path when checking', () => {
|
|
42
|
+
const store = new MemoryStore({ files: { 'foo.txt': 'hi' } });
|
|
43
|
+
expect(store.exists('foo.txt')).toBe(true);
|
|
44
|
+
expect(store.exists('./foo.txt')).toBe(true);
|
|
45
|
+
});
|
|
46
|
+
});
|
|
47
|
+
describe('readText', () => {
|
|
48
|
+
test('returns content of existing file', () => {
|
|
49
|
+
const store = new MemoryStore({ files: { 'foo.txt': 'hello world' } });
|
|
50
|
+
expect(store.readText('foo.txt')).toBe('hello world');
|
|
51
|
+
});
|
|
52
|
+
test('throws for non-existent file', () => {
|
|
53
|
+
const store = new MemoryStore();
|
|
54
|
+
expect(() => store.readText('missing.txt')).toThrow('MemoryStore: File not found: missing.txt');
|
|
55
|
+
});
|
|
56
|
+
test('normalizes path when reading', () => {
|
|
57
|
+
const store = new MemoryStore({ files: { 'a/b.txt': 'content' } });
|
|
58
|
+
expect(store.readText('./a/b.txt')).toBe('content');
|
|
59
|
+
});
|
|
60
|
+
});
|
|
61
|
+
describe('readJson', () => {
|
|
62
|
+
test('parses and returns JSON', () => {
|
|
63
|
+
const store = new MemoryStore({
|
|
64
|
+
files: { 'data.json': '{"name":"test","count":42}' },
|
|
65
|
+
});
|
|
66
|
+
const data = store.readJson('data.json');
|
|
67
|
+
expect(data).toEqual({ name: 'test', count: 42 });
|
|
68
|
+
});
|
|
69
|
+
test('throws for invalid JSON', () => {
|
|
70
|
+
const store = new MemoryStore({ files: { 'bad.json': 'not json' } });
|
|
71
|
+
expect(() => store.readJson('bad.json')).toThrow();
|
|
72
|
+
});
|
|
73
|
+
});
|
|
74
|
+
describe('listDir', () => {
|
|
75
|
+
test('returns sorted list of children for root', () => {
|
|
76
|
+
const store = new MemoryStore({
|
|
77
|
+
files: {
|
|
78
|
+
'a.txt': 'a',
|
|
79
|
+
'z.txt': 'z',
|
|
80
|
+
'm.txt': 'm',
|
|
81
|
+
'dir/file.txt': 'f',
|
|
82
|
+
},
|
|
83
|
+
});
|
|
84
|
+
expect(store.listDir('')).toEqual(['a.txt', 'dir', 'm.txt', 'z.txt']);
|
|
85
|
+
});
|
|
86
|
+
test('returns sorted list of children for nested dir', () => {
|
|
87
|
+
const store = new MemoryStore({
|
|
88
|
+
files: {
|
|
89
|
+
'parent/child1.txt': '1',
|
|
90
|
+
'parent/child2.txt': '2',
|
|
91
|
+
'parent/subdir/file.txt': '3',
|
|
92
|
+
},
|
|
93
|
+
});
|
|
94
|
+
expect(store.listDir('parent')).toEqual(['child1.txt', 'child2.txt', 'subdir']);
|
|
95
|
+
});
|
|
96
|
+
test('returns empty array for empty directory', () => {
|
|
97
|
+
const store = new MemoryStore();
|
|
98
|
+
expect(store.listDir('')).toEqual([]);
|
|
99
|
+
});
|
|
100
|
+
test('throws for non-existent directory', () => {
|
|
101
|
+
const store = new MemoryStore();
|
|
102
|
+
expect(() => store.listDir('missing')).toThrow('MemoryStore: Directory not found: missing');
|
|
103
|
+
});
|
|
104
|
+
});
|
|
105
|
+
describe('ensureDir', () => {
|
|
106
|
+
test('creates nested directories recursively', () => {
|
|
107
|
+
const store = new MemoryStore();
|
|
108
|
+
store.ensureDir('a/b/c');
|
|
109
|
+
expect(store.exists('a')).toBe(true);
|
|
110
|
+
expect(store.exists('a/b')).toBe(true);
|
|
111
|
+
expect(store.exists('a/b/c')).toBe(true);
|
|
112
|
+
expect(store.listDir('a')).toEqual(['b']);
|
|
113
|
+
expect(store.listDir('a/b')).toEqual(['c']);
|
|
114
|
+
expect(store.listDir('a/b/c')).toEqual([]);
|
|
115
|
+
});
|
|
116
|
+
test('is idempotent for existing directory', () => {
|
|
117
|
+
const store = new MemoryStore();
|
|
118
|
+
store.ensureDir('x');
|
|
119
|
+
store.ensureDir('x');
|
|
120
|
+
expect(store.listDir('x')).toEqual([]);
|
|
121
|
+
});
|
|
122
|
+
});
|
|
123
|
+
describe('writeText', () => {
|
|
124
|
+
test('writes file and creates parent directories', () => {
|
|
125
|
+
const store = new MemoryStore();
|
|
126
|
+
store.writeText('deep/path/file.txt', 'content');
|
|
127
|
+
expect(store.readText('deep/path/file.txt')).toBe('content');
|
|
128
|
+
expect(store.listDir('deep')).toEqual(['path']);
|
|
129
|
+
expect(store.listDir('deep/path')).toEqual(['file.txt']);
|
|
130
|
+
});
|
|
131
|
+
test('overwrites existing file', () => {
|
|
132
|
+
const store = new MemoryStore({ files: { 'foo.txt': 'old' } });
|
|
133
|
+
store.writeText('foo.txt', 'new');
|
|
134
|
+
expect(store.readText('foo.txt')).toBe('new');
|
|
135
|
+
});
|
|
136
|
+
});
|
|
137
|
+
describe('writeJson', () => {
|
|
138
|
+
test('writes JSON-serialized data', () => {
|
|
139
|
+
const store = new MemoryStore();
|
|
140
|
+
store.writeJson('data.json', { foo: 'bar', num: 123 });
|
|
141
|
+
expect(store.readText('data.json')).toBe('{"foo":"bar","num":123}');
|
|
142
|
+
expect(store.readJson('data.json')).toEqual({ foo: 'bar', num: 123 });
|
|
143
|
+
});
|
|
144
|
+
});
|
|
145
|
+
describe('appendText', () => {
|
|
146
|
+
test('creates new file when path does not exist', () => {
|
|
147
|
+
const store = new MemoryStore();
|
|
148
|
+
store.appendText('log.txt', 'line1\n');
|
|
149
|
+
expect(store.readText('log.txt')).toBe('line1\n');
|
|
150
|
+
});
|
|
151
|
+
test('appends to existing file', () => {
|
|
152
|
+
const store = new MemoryStore({ files: { 'log.txt': 'line1\n' } });
|
|
153
|
+
store.appendText('log.txt', 'line2\n');
|
|
154
|
+
store.appendText('log.txt', 'line3\n');
|
|
155
|
+
expect(store.readText('log.txt')).toBe('line1\nline2\nline3\n');
|
|
156
|
+
});
|
|
157
|
+
test('creates parent directories when needed', () => {
|
|
158
|
+
const store = new MemoryStore();
|
|
159
|
+
store.appendText('logs/2025/app.log', 'entry\n');
|
|
160
|
+
expect(store.readText('logs/2025/app.log')).toBe('entry\n');
|
|
161
|
+
});
|
|
162
|
+
});
|
|
163
|
+
describe('delete', () => {
|
|
164
|
+
test('removes file', () => {
|
|
165
|
+
const store = new MemoryStore({ files: { 'foo.txt': 'hi' } });
|
|
166
|
+
store.delete('foo.txt');
|
|
167
|
+
expect(store.exists('foo.txt')).toBe(false);
|
|
168
|
+
expect(() => store.readText('foo.txt')).toThrow();
|
|
169
|
+
});
|
|
170
|
+
test('removes directory', () => {
|
|
171
|
+
const store = new MemoryStore({ files: { 'dir/file.txt': 'hi' } });
|
|
172
|
+
store.delete('dir');
|
|
173
|
+
expect(store.exists('dir')).toBe(false);
|
|
174
|
+
expect(() => store.listDir('dir')).toThrow();
|
|
175
|
+
});
|
|
176
|
+
test('removes both normalized and original path', () => {
|
|
177
|
+
const store = new MemoryStore({ files: { 'foo.txt': 'hi' } });
|
|
178
|
+
store.delete('./foo.txt');
|
|
179
|
+
expect(store.exists('foo.txt')).toBe(false);
|
|
180
|
+
});
|
|
181
|
+
});
|
|
182
|
+
describe('dumpFiles', () => {
|
|
183
|
+
test('returns copy of all files', () => {
|
|
184
|
+
const store = new MemoryStore({
|
|
185
|
+
files: {
|
|
186
|
+
'a.txt': 'a',
|
|
187
|
+
'b/c.txt': 'c',
|
|
188
|
+
},
|
|
189
|
+
});
|
|
190
|
+
const dumped = store.dumpFiles();
|
|
191
|
+
expect(dumped).toEqual({
|
|
192
|
+
'a.txt': 'a',
|
|
193
|
+
'b/c.txt': 'c',
|
|
194
|
+
});
|
|
195
|
+
});
|
|
196
|
+
test('returns empty object for empty store', () => {
|
|
197
|
+
const store = new MemoryStore();
|
|
198
|
+
expect(store.dumpFiles()).toEqual({});
|
|
199
|
+
});
|
|
200
|
+
});
|
|
201
|
+
describe('full workflow', () => {
|
|
202
|
+
test('write → read → append → read → delete cycle', () => {
|
|
203
|
+
const store = new MemoryStore();
|
|
204
|
+
store.writeText('notes.txt', 'First note\n');
|
|
205
|
+
expect(store.readText('notes.txt')).toBe('First note\n');
|
|
206
|
+
store.appendText('notes.txt', 'Second note\n');
|
|
207
|
+
expect(store.readText('notes.txt')).toBe('First note\nSecond note\n');
|
|
208
|
+
store.delete('notes.txt');
|
|
209
|
+
expect(store.exists('notes.txt')).toBe(false);
|
|
210
|
+
});
|
|
211
|
+
test('nested structure with multiple operations', () => {
|
|
212
|
+
const store = new MemoryStore();
|
|
213
|
+
store.writeText('issues/2025-01-01-disruption.json', '{}');
|
|
214
|
+
store.writeText('issues/2025-01-02-maintenance.json', '{}');
|
|
215
|
+
store.writeJson('config.json', { version: 1 });
|
|
216
|
+
expect(store.listDir('')).toEqual(['config.json', 'issues']);
|
|
217
|
+
expect(store.listDir('issues')).toEqual([
|
|
218
|
+
'2025-01-01-disruption.json',
|
|
219
|
+
'2025-01-02-maintenance.json',
|
|
220
|
+
]);
|
|
221
|
+
expect(store.readJson('config.json')).toEqual({ version: 1 });
|
|
222
|
+
});
|
|
223
|
+
});
|
|
224
|
+
});
|
|
225
|
+
//# sourceMappingURL=MemoryStore.test.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"MemoryStore.test.js","sourceRoot":"/","sources":["llm/common/MemoryStore.test.ts"],"names":[],"mappings":"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","sourcesContent":["import { describe, expect, test } from 'vitest';\nimport { MemoryStore } from './MemoryStore.js';\n\ndescribe('MemoryStore', () => {\n describe('constructor', () => {\n test('creates empty store by default', () => {\n const store = new MemoryStore();\n expect(store.dumpFiles()).toEqual({});\n expect(store.listDir('')).toEqual([]);\n });\n\n test('seeds store with files from seed object', () => {\n const store = new MemoryStore({\n files: {\n 'foo.txt': 'hello',\n 'bar/baz.json': '{\"x\":1}',\n },\n });\n expect(store.readText('foo.txt')).toBe('hello');\n expect(store.readText('bar/baz.json')).toBe('{\"x\":1}');\n expect(store.listDir('')).toEqual(['bar', 'foo.txt']);\n expect(store.listDir('bar')).toEqual(['baz.json']);\n });\n });\n\n describe('exists', () => {\n test('returns false for non-existent path', () => {\n const store = new MemoryStore();\n expect(store.exists('missing')).toBe(false);\n expect(store.exists('a/b/c')).toBe(false);\n });\n\n test('returns true for root directory', () => {\n const store = new MemoryStore();\n expect(store.exists('')).toBe(true);\n });\n\n test('returns true for existing file', () => {\n const store = new MemoryStore({ files: { 'foo.txt': 'hi' } });\n expect(store.exists('foo.txt')).toBe(true);\n });\n\n test('returns true for existing directory', () => {\n const store = new MemoryStore({ files: { 'dir/file.txt': 'hi' } });\n expect(store.exists('dir')).toBe(true);\n });\n\n test('normalizes path when checking', () => {\n const store = new MemoryStore({ files: { 'foo.txt': 'hi' } });\n expect(store.exists('foo.txt')).toBe(true);\n expect(store.exists('./foo.txt')).toBe(true);\n });\n });\n\n describe('readText', () => {\n test('returns content of existing file', () => {\n const store = new MemoryStore({ files: { 'foo.txt': 'hello world' } });\n expect(store.readText('foo.txt')).toBe('hello world');\n });\n\n test('throws for non-existent file', () => {\n const store = new MemoryStore();\n expect(() => store.readText('missing.txt')).toThrow(\n 'MemoryStore: File not found: missing.txt'\n );\n });\n\n test('normalizes path when reading', () => {\n const store = new MemoryStore({ files: { 'a/b.txt': 'content' } });\n expect(store.readText('./a/b.txt')).toBe('content');\n });\n });\n\n describe('readJson', () => {\n test('parses and returns JSON', () => {\n const store = new MemoryStore({\n files: { 'data.json': '{\"name\":\"test\",\"count\":42}' },\n });\n const data = store.readJson<{ name: string; count: number }>('data.json');\n expect(data).toEqual({ name: 'test', count: 42 });\n });\n\n test('throws for invalid JSON', () => {\n const store = new MemoryStore({ files: { 'bad.json': 'not json' } });\n expect(() => store.readJson('bad.json')).toThrow();\n });\n });\n\n describe('listDir', () => {\n test('returns sorted list of children for root', () => {\n const store = new MemoryStore({\n files: {\n 'a.txt': 'a',\n 'z.txt': 'z',\n 'm.txt': 'm',\n 'dir/file.txt': 'f',\n },\n });\n expect(store.listDir('')).toEqual(['a.txt', 'dir', 'm.txt', 'z.txt']);\n });\n\n test('returns sorted list of children for nested dir', () => {\n const store = new MemoryStore({\n files: {\n 'parent/child1.txt': '1',\n 'parent/child2.txt': '2',\n 'parent/subdir/file.txt': '3',\n },\n });\n expect(store.listDir('parent')).toEqual(['child1.txt', 'child2.txt', 'subdir']);\n });\n\n test('returns empty array for empty directory', () => {\n const store = new MemoryStore();\n expect(store.listDir('')).toEqual([]);\n });\n\n test('throws for non-existent directory', () => {\n const store = new MemoryStore();\n expect(() => store.listDir('missing')).toThrow(\n 'MemoryStore: Directory not found: missing'\n );\n });\n });\n\n describe('ensureDir', () => {\n test('creates nested directories recursively', () => {\n const store = new MemoryStore();\n store.ensureDir('a/b/c');\n expect(store.exists('a')).toBe(true);\n expect(store.exists('a/b')).toBe(true);\n expect(store.exists('a/b/c')).toBe(true);\n expect(store.listDir('a')).toEqual(['b']);\n expect(store.listDir('a/b')).toEqual(['c']);\n expect(store.listDir('a/b/c')).toEqual([]);\n });\n\n test('is idempotent for existing directory', () => {\n const store = new MemoryStore();\n store.ensureDir('x');\n store.ensureDir('x');\n expect(store.listDir('x')).toEqual([]);\n });\n });\n\n describe('writeText', () => {\n test('writes file and creates parent directories', () => {\n const store = new MemoryStore();\n store.writeText('deep/path/file.txt', 'content');\n expect(store.readText('deep/path/file.txt')).toBe('content');\n expect(store.listDir('deep')).toEqual(['path']);\n expect(store.listDir('deep/path')).toEqual(['file.txt']);\n });\n\n test('overwrites existing file', () => {\n const store = new MemoryStore({ files: { 'foo.txt': 'old' } });\n store.writeText('foo.txt', 'new');\n expect(store.readText('foo.txt')).toBe('new');\n });\n });\n\n describe('writeJson', () => {\n test('writes JSON-serialized data', () => {\n const store = new MemoryStore();\n store.writeJson('data.json', { foo: 'bar', num: 123 });\n expect(store.readText('data.json')).toBe('{\"foo\":\"bar\",\"num\":123}');\n expect(store.readJson('data.json')).toEqual({ foo: 'bar', num: 123 });\n });\n });\n\n describe('appendText', () => {\n test('creates new file when path does not exist', () => {\n const store = new MemoryStore();\n store.appendText('log.txt', 'line1\\n');\n expect(store.readText('log.txt')).toBe('line1\\n');\n });\n\n test('appends to existing file', () => {\n const store = new MemoryStore({ files: { 'log.txt': 'line1\\n' } });\n store.appendText('log.txt', 'line2\\n');\n store.appendText('log.txt', 'line3\\n');\n expect(store.readText('log.txt')).toBe('line1\\nline2\\nline3\\n');\n });\n\n test('creates parent directories when needed', () => {\n const store = new MemoryStore();\n store.appendText('logs/2025/app.log', 'entry\\n');\n expect(store.readText('logs/2025/app.log')).toBe('entry\\n');\n });\n });\n\n describe('delete', () => {\n test('removes file', () => {\n const store = new MemoryStore({ files: { 'foo.txt': 'hi' } });\n store.delete('foo.txt');\n expect(store.exists('foo.txt')).toBe(false);\n expect(() => store.readText('foo.txt')).toThrow();\n });\n\n test('removes directory', () => {\n const store = new MemoryStore({ files: { 'dir/file.txt': 'hi' } });\n store.delete('dir');\n expect(store.exists('dir')).toBe(false);\n expect(() => store.listDir('dir')).toThrow();\n });\n\n test('removes both normalized and original path', () => {\n const store = new MemoryStore({ files: { 'foo.txt': 'hi' } });\n store.delete('./foo.txt');\n expect(store.exists('foo.txt')).toBe(false);\n });\n });\n\n describe('dumpFiles', () => {\n test('returns copy of all files', () => {\n const store = new MemoryStore({\n files: {\n 'a.txt': 'a',\n 'b/c.txt': 'c',\n },\n });\n const dumped = store.dumpFiles();\n expect(dumped).toEqual({\n 'a.txt': 'a',\n 'b/c.txt': 'c',\n });\n });\n\n test('returns empty object for empty store', () => {\n const store = new MemoryStore();\n expect(store.dumpFiles()).toEqual({});\n });\n });\n\n describe('full workflow', () => {\n test('write → read → append → read → delete cycle', () => {\n const store = new MemoryStore();\n store.writeText('notes.txt', 'First note\\n');\n expect(store.readText('notes.txt')).toBe('First note\\n');\n\n store.appendText('notes.txt', 'Second note\\n');\n expect(store.readText('notes.txt')).toBe('First note\\nSecond note\\n');\n\n store.delete('notes.txt');\n expect(store.exists('notes.txt')).toBe(false);\n });\n\n test('nested structure with multiple operations', () => {\n const store = new MemoryStore();\n store.writeText('issues/2025-01-01-disruption.json', '{}');\n store.writeText('issues/2025-01-02-maintenance.json', '{}');\n store.writeJson('config.json', { version: 1 });\n\n expect(store.listDir('')).toEqual(['config.json', 'issues']);\n expect(store.listDir('issues')).toEqual([\n '2025-01-01-disruption.json',\n '2025-01-02-maintenance.json',\n ]);\n expect(store.readJson('config.json')).toEqual({ version: 1 });\n });\n });\n});\n"]}
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
import type { IssueBundleState } from '../../repo/issue/helpers/deriveCurrentState.js';
|
|
2
|
+
import type { Evidence } from '../../schema/issue/evidence.js';
|
|
3
|
+
export type FormatCurrentStateOptions = {
|
|
4
|
+
state: IssueBundleState | null;
|
|
5
|
+
evidence?: Evidence[];
|
|
6
|
+
};
|
|
7
|
+
/**
|
|
8
|
+
* Format the current state as markdown for better LLM readability
|
|
9
|
+
*/
|
|
10
|
+
export declare function formatCurrentState(stateOrOptions: IssueBundleState | null | FormatCurrentStateOptions): string;
|