@yeseh/cortex-cli 0.6.6 → 0.6.8
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/category/commands/create.d.ts.map +1 -1
- package/dist/chunk-dsfj4baj.js +1543 -0
- package/dist/chunk-dsfj4baj.js.map +38 -0
- package/dist/commands/init.d.ts +26 -5
- package/dist/commands/init.d.ts.map +1 -1
- package/dist/context.d.ts +22 -17
- package/dist/context.d.ts.map +1 -1
- package/dist/context.spec.d.ts +8 -0
- package/dist/context.spec.d.ts.map +1 -1
- package/dist/memory/commands/add.d.ts.map +1 -1
- package/dist/memory/commands/list.d.ts.map +1 -1
- package/dist/memory/commands/move.d.ts.map +1 -1
- package/dist/memory/commands/remove.d.ts.map +1 -1
- package/dist/memory/commands/show.d.ts.map +1 -1
- package/dist/memory/commands/update.d.ts.map +1 -1
- package/dist/observability.d.ts +33 -0
- package/dist/observability.d.ts.map +1 -0
- package/dist/observability.spec.d.ts +2 -0
- package/dist/observability.spec.d.ts.map +1 -0
- package/dist/output.d.ts +21 -1
- package/dist/output.d.ts.map +1 -1
- package/dist/program.d.ts.map +1 -1
- package/dist/program.js +11 -0
- package/dist/program.js.map +9 -0
- package/dist/run.js +10 -0
- package/dist/run.js.map +10 -0
- package/dist/store/commands/init.d.ts +23 -7
- package/dist/store/commands/init.d.ts.map +1 -1
- package/dist/store/commands/prune.d.ts.map +1 -1
- package/dist/store/commands/reindexs.d.ts.map +1 -1
- package/dist/test-helpers.spec.d.ts +2 -2
- package/dist/utils/input.d.ts.map +1 -0
- package/dist/{input.spec.d.ts.map → utils/input.spec.d.ts.map} +1 -1
- package/dist/{paths.d.ts → utils/paths.d.ts} +10 -0
- package/dist/utils/paths.d.ts.map +1 -0
- package/dist/utils/paths.spec.d.ts.map +1 -0
- package/dist/utils/prompts.d.ts +86 -0
- package/dist/utils/prompts.d.ts.map +1 -0
- package/dist/utils/prompts.spec.d.ts +2 -0
- package/dist/utils/prompts.spec.d.ts.map +1 -0
- package/dist/utils/resolve-default-store.d.ts +44 -0
- package/dist/utils/resolve-default-store.d.ts.map +1 -0
- package/dist/utils/resolve-default-store.spec.d.ts +7 -0
- package/dist/utils/resolve-default-store.spec.d.ts.map +1 -0
- package/package.json +9 -9
- package/src/run.ts +0 -0
- package/src/tests/cli.integration.spec.ts +270 -79
- package/src/utils/input.ts +9 -4
- package/src/utils/resolve-default-store.spec.ts +1 -1
- package/src/utils/resolve-default-store.ts +6 -2
- package/dist/create-cli-command.d.ts +0 -23
- package/dist/create-cli-command.d.ts.map +0 -1
- package/dist/create-cli-command.spec.d.ts +0 -10
- package/dist/create-cli-command.spec.d.ts.map +0 -1
- package/dist/input.d.ts.map +0 -1
- package/dist/memory/commands/handlers.spec.d.ts +0 -2
- package/dist/memory/commands/handlers.spec.d.ts.map +0 -1
- package/dist/paths.d.ts.map +0 -1
- package/dist/paths.spec.d.ts.map +0 -1
- /package/dist/{input.d.ts → utils/input.d.ts} +0 -0
- /package/dist/{input.spec.d.ts → utils/input.spec.d.ts} +0 -0
- /package/dist/{paths.spec.d.ts → utils/paths.spec.d.ts} +0 -0
|
@@ -18,7 +18,7 @@ const diagnosticsEnabled = process.env.CORTEX_TEST_DIAGNOSTICS === '1';
|
|
|
18
18
|
const formatCliFailure = (
|
|
19
19
|
args: string[],
|
|
20
20
|
result: CliResult,
|
|
21
|
-
extra?: Record<string, unknown
|
|
21
|
+
extra?: Record<string, unknown>,
|
|
22
22
|
): string => {
|
|
23
23
|
const extraLines = extra ? `\nextra: ${JSON.stringify(extra, null, 2)}` : '';
|
|
24
24
|
return (
|
|
@@ -88,12 +88,19 @@ const runCortexCli = async (args: string[], options: CliOptions): Promise<CliRes
|
|
|
88
88
|
// Preserve TERM if available (some help formatting can depend on it)
|
|
89
89
|
if (process.env.TERM) env.TERM = process.env.TERM;
|
|
90
90
|
|
|
91
|
-
for (const [
|
|
91
|
+
for (const [
|
|
92
|
+
key, value,
|
|
93
|
+
] of Object.entries(options.env ?? {})) {
|
|
92
94
|
if (typeof value === 'string') env[key] = value;
|
|
93
95
|
}
|
|
94
96
|
|
|
95
97
|
// Use Bun.spawn for cross-platform subprocess spawning
|
|
96
|
-
const proc = Bun.spawn([
|
|
98
|
+
const proc = Bun.spawn([
|
|
99
|
+
'bun',
|
|
100
|
+
'run',
|
|
101
|
+
scriptPath,
|
|
102
|
+
...args,
|
|
103
|
+
], {
|
|
97
104
|
cwd: options.cwd,
|
|
98
105
|
env,
|
|
99
106
|
stdin: options.stdin !== undefined ? 'pipe' : 'inherit',
|
|
@@ -109,7 +116,9 @@ const runCortexCli = async (args: string[], options: CliOptions): Promise<CliRes
|
|
|
109
116
|
proc.stdin.end();
|
|
110
117
|
}
|
|
111
118
|
|
|
112
|
-
const [
|
|
119
|
+
const [
|
|
120
|
+
stdout, stderr,
|
|
121
|
+
] = await Promise.all([
|
|
113
122
|
new Response(proc.stdout).text(),
|
|
114
123
|
new Response(proc.stderr).text(),
|
|
115
124
|
]);
|
|
@@ -136,7 +145,8 @@ const runCortexCli = async (args: string[], options: CliOptions): Promise<CliRes
|
|
|
136
145
|
resolvedConfigPath,
|
|
137
146
|
resolvedStoreRoot,
|
|
138
147
|
};
|
|
139
|
-
}
|
|
148
|
+
}
|
|
149
|
+
catch (error) {
|
|
140
150
|
// Handle process errors
|
|
141
151
|
const processError = error as { stdout?: Buffer; stderr?: Buffer; exitCode?: number };
|
|
142
152
|
const stdoutTrimmed = processError.stdout?.toString().trim() ?? '';
|
|
@@ -207,7 +217,7 @@ const createMemoryFile = async (
|
|
|
207
217
|
expiresAt?: Date;
|
|
208
218
|
createdAt?: Date;
|
|
209
219
|
updatedAt?: Date;
|
|
210
|
-
} = {}
|
|
220
|
+
} = {},
|
|
211
221
|
): Promise<void> => {
|
|
212
222
|
const content = options.content ?? 'Test memory content.';
|
|
213
223
|
const tags = options.tags ?? ['test'];
|
|
@@ -229,7 +239,7 @@ const createMemoryFile = async (
|
|
|
229
239
|
expiresAt: options.expiresAt,
|
|
230
240
|
citations: [],
|
|
231
241
|
},
|
|
232
|
-
content
|
|
242
|
+
content,
|
|
233
243
|
);
|
|
234
244
|
if (!memoryResult.ok()) {
|
|
235
245
|
throw new Error(`Failed to create memory: ${memoryResult.error.message}`);
|
|
@@ -237,7 +247,7 @@ const createMemoryFile = async (
|
|
|
237
247
|
|
|
238
248
|
const adapter = new FilesystemStorageAdapter(
|
|
239
249
|
new FilesystemConfigAdapter(join(storeRoot, 'config.yaml')),
|
|
240
|
-
{ rootDirectory: storeRoot }
|
|
250
|
+
{ rootDirectory: storeRoot },
|
|
241
251
|
);
|
|
242
252
|
const writeResult = await adapter.memories.save(memoryResult.value.path, memoryResult.value);
|
|
243
253
|
if (!writeResult.ok()) {
|
|
@@ -270,7 +280,8 @@ const createCategory = async (categoryPath: string, storeRoot: string): Promise<
|
|
|
270
280
|
const rootIndexPath = join(storeRoot, 'index.yaml');
|
|
271
281
|
try {
|
|
272
282
|
await fs.access(rootIndexPath);
|
|
273
|
-
}
|
|
283
|
+
}
|
|
284
|
+
catch {
|
|
274
285
|
await fs.writeFile(rootIndexPath, 'memories: []\nsubcategories: []', 'utf8');
|
|
275
286
|
}
|
|
276
287
|
};
|
|
@@ -284,14 +295,15 @@ const createCategoryIndex = async (
|
|
|
284
295
|
storeRoot: string,
|
|
285
296
|
categoryPath: string,
|
|
286
297
|
memories: { path: string; tokenEstimate: number; summary?: string }[] = [],
|
|
287
|
-
subcategories: { path: string; memoryCount?: number }[] = []
|
|
298
|
+
subcategories: { path: string; memoryCount?: number }[] = [],
|
|
288
299
|
): Promise<void> => {
|
|
289
300
|
const lines: string[] = [];
|
|
290
301
|
|
|
291
302
|
// Memory section
|
|
292
303
|
if (memories.length === 0) {
|
|
293
304
|
lines.push('memories: []');
|
|
294
|
-
}
|
|
305
|
+
}
|
|
306
|
+
else {
|
|
295
307
|
lines.push('memories:');
|
|
296
308
|
for (const memory of memories) {
|
|
297
309
|
lines.push(' -');
|
|
@@ -308,7 +320,8 @@ const createCategoryIndex = async (
|
|
|
308
320
|
// Subcategories section
|
|
309
321
|
if (subcategories.length === 0) {
|
|
310
322
|
lines.push('subcategories: []');
|
|
311
|
-
}
|
|
323
|
+
}
|
|
324
|
+
else {
|
|
312
325
|
lines.push('subcategories:');
|
|
313
326
|
for (const sub of subcategories) {
|
|
314
327
|
lines.push(' -');
|
|
@@ -330,7 +343,8 @@ const memoryExists = async (storeRoot: string, slugPath: string): Promise<boolea
|
|
|
330
343
|
try {
|
|
331
344
|
await fs.access(join(storeRoot, `${slugPath}.md`));
|
|
332
345
|
return true;
|
|
333
|
-
}
|
|
346
|
+
}
|
|
347
|
+
catch {
|
|
334
348
|
return false;
|
|
335
349
|
}
|
|
336
350
|
};
|
|
@@ -341,7 +355,8 @@ const memoryExists = async (storeRoot: string, slugPath: string): Promise<boolea
|
|
|
341
355
|
const readMemoryFile = async (storeRoot: string, slugPath: string): Promise<string | null> => {
|
|
342
356
|
try {
|
|
343
357
|
return await fs.readFile(join(storeRoot, `${slugPath}.md`), 'utf8');
|
|
344
|
-
}
|
|
358
|
+
}
|
|
359
|
+
catch {
|
|
345
360
|
return null;
|
|
346
361
|
}
|
|
347
362
|
};
|
|
@@ -365,13 +380,25 @@ describe('Cortex CLI Integration Tests', () => {
|
|
|
365
380
|
it('should add a new memory with inline content', async () => {
|
|
366
381
|
await createCategory('project', storeDir);
|
|
367
382
|
const result = await runCortexCli(
|
|
368
|
-
[
|
|
369
|
-
|
|
383
|
+
[
|
|
384
|
+
'memory',
|
|
385
|
+
'add',
|
|
386
|
+
'project/test-memory',
|
|
387
|
+
'--content',
|
|
388
|
+
'This is test content.',
|
|
389
|
+
],
|
|
390
|
+
{ cwd: testProject },
|
|
370
391
|
);
|
|
371
392
|
|
|
372
393
|
expectCliOk(
|
|
373
|
-
[
|
|
374
|
-
|
|
394
|
+
[
|
|
395
|
+
'memory',
|
|
396
|
+
'add',
|
|
397
|
+
'project/test-memory',
|
|
398
|
+
'--content',
|
|
399
|
+
'This is test content.',
|
|
400
|
+
],
|
|
401
|
+
result,
|
|
375
402
|
);
|
|
376
403
|
expect(result.exitCode).toBe(0);
|
|
377
404
|
expect(result.stdout).toContain('Added memory');
|
|
@@ -396,7 +423,7 @@ describe('Cortex CLI Integration Tests', () => {
|
|
|
396
423
|
'--tags',
|
|
397
424
|
'tag1,tag2,tag3',
|
|
398
425
|
],
|
|
399
|
-
{ cwd: testProject }
|
|
426
|
+
{ cwd: testProject },
|
|
400
427
|
);
|
|
401
428
|
|
|
402
429
|
expect(result.exitCode).toBe(0);
|
|
@@ -424,7 +451,7 @@ describe('Cortex CLI Integration Tests', () => {
|
|
|
424
451
|
'-t',
|
|
425
452
|
'third',
|
|
426
453
|
],
|
|
427
|
-
{ cwd: testProject }
|
|
454
|
+
{ cwd: testProject },
|
|
428
455
|
);
|
|
429
456
|
|
|
430
457
|
expect(result.exitCode).toBe(0);
|
|
@@ -450,7 +477,7 @@ describe('Cortex CLI Integration Tests', () => {
|
|
|
450
477
|
'-t',
|
|
451
478
|
'gamma',
|
|
452
479
|
],
|
|
453
|
-
{ cwd: testProject }
|
|
480
|
+
{ cwd: testProject },
|
|
454
481
|
);
|
|
455
482
|
|
|
456
483
|
expect(result.exitCode).toBe(0);
|
|
@@ -475,7 +502,7 @@ describe('Cortex CLI Integration Tests', () => {
|
|
|
475
502
|
'--expires-at',
|
|
476
503
|
expiryDate,
|
|
477
504
|
],
|
|
478
|
-
{ cwd: testProject }
|
|
505
|
+
{ cwd: testProject },
|
|
479
506
|
);
|
|
480
507
|
|
|
481
508
|
expect(result.exitCode).toBe(0);
|
|
@@ -486,7 +513,12 @@ describe('Cortex CLI Integration Tests', () => {
|
|
|
486
513
|
});
|
|
487
514
|
|
|
488
515
|
it('should fail when memory path is missing', async () => {
|
|
489
|
-
const result = await runCortexCli([
|
|
516
|
+
const result = await runCortexCli([
|
|
517
|
+
'memory',
|
|
518
|
+
'add',
|
|
519
|
+
'--content',
|
|
520
|
+
'No path provided.',
|
|
521
|
+
], {
|
|
490
522
|
cwd: testProject,
|
|
491
523
|
});
|
|
492
524
|
|
|
@@ -497,8 +529,14 @@ describe('Cortex CLI Integration Tests', () => {
|
|
|
497
529
|
|
|
498
530
|
it('should fail for invalid memory path format', async () => {
|
|
499
531
|
const result = await runCortexCli(
|
|
500
|
-
[
|
|
501
|
-
|
|
532
|
+
[
|
|
533
|
+
'memory',
|
|
534
|
+
'add',
|
|
535
|
+
'invalid-single-segment',
|
|
536
|
+
'--content',
|
|
537
|
+
'Bad path.',
|
|
538
|
+
],
|
|
539
|
+
{ cwd: testProject },
|
|
502
540
|
);
|
|
503
541
|
|
|
504
542
|
expect(result.exitCode).toBe(1);
|
|
@@ -506,10 +544,16 @@ describe('Cortex CLI Integration Tests', () => {
|
|
|
506
544
|
|
|
507
545
|
it('should fail for unknown flags', async () => {
|
|
508
546
|
const result = await runCortexCli(
|
|
509
|
-
[
|
|
547
|
+
[
|
|
548
|
+
'memory',
|
|
549
|
+
'add',
|
|
550
|
+
'project/memory',
|
|
551
|
+
'--unknown-flag',
|
|
552
|
+
'value',
|
|
553
|
+
],
|
|
510
554
|
{
|
|
511
555
|
cwd: testProject,
|
|
512
|
-
}
|
|
556
|
+
},
|
|
513
557
|
);
|
|
514
558
|
|
|
515
559
|
expect(result.exitCode).toBe(1);
|
|
@@ -524,10 +568,16 @@ describe('Cortex CLI Integration Tests', () => {
|
|
|
524
568
|
await fs.writeFile(contentFile, 'Content from file.', 'utf8');
|
|
525
569
|
|
|
526
570
|
const result = await runCortexCli(
|
|
527
|
-
[
|
|
571
|
+
[
|
|
572
|
+
'memory',
|
|
573
|
+
'add',
|
|
574
|
+
'project/file-memory',
|
|
575
|
+
'--file',
|
|
576
|
+
contentFile,
|
|
577
|
+
],
|
|
528
578
|
{
|
|
529
579
|
cwd: testProject,
|
|
530
|
-
}
|
|
580
|
+
},
|
|
531
581
|
);
|
|
532
582
|
|
|
533
583
|
expect(result.exitCode).toBe(0);
|
|
@@ -546,7 +596,7 @@ describe('Cortex CLI Integration Tests', () => {
|
|
|
546
596
|
'--content',
|
|
547
597
|
'Deeply nested content.',
|
|
548
598
|
],
|
|
549
|
-
{ cwd: testProject }
|
|
599
|
+
{ cwd: testProject },
|
|
550
600
|
);
|
|
551
601
|
|
|
552
602
|
expect(result.exitCode).toBe(0);
|
|
@@ -559,8 +609,14 @@ describe('Cortex CLI Integration Tests', () => {
|
|
|
559
609
|
await createCategory('project', storeDir);
|
|
560
610
|
const specialContent = 'Special chars: $HOME, `backticks`, "quotes", \'single\'';
|
|
561
611
|
const result = await runCortexCli(
|
|
562
|
-
[
|
|
563
|
-
|
|
612
|
+
[
|
|
613
|
+
'memory',
|
|
614
|
+
'add',
|
|
615
|
+
'project/special-memory',
|
|
616
|
+
'--content',
|
|
617
|
+
specialContent,
|
|
618
|
+
],
|
|
619
|
+
{ cwd: testProject },
|
|
564
620
|
);
|
|
565
621
|
|
|
566
622
|
expect(result.exitCode).toBe(0);
|
|
@@ -586,7 +642,9 @@ describe('Cortex CLI Integration Tests', () => {
|
|
|
586
642
|
});
|
|
587
643
|
|
|
588
644
|
it('should list all memories across categories', async () => {
|
|
589
|
-
const result = await runCortexCli([
|
|
645
|
+
const result = await runCortexCli([
|
|
646
|
+
'memory', 'list',
|
|
647
|
+
], { cwd: testProject });
|
|
590
648
|
|
|
591
649
|
expect(result.exitCode).toBe(0);
|
|
592
650
|
expect(result.stdout).toContain('project/memory-one');
|
|
@@ -595,7 +653,11 @@ describe('Cortex CLI Integration Tests', () => {
|
|
|
595
653
|
});
|
|
596
654
|
|
|
597
655
|
it('should list memories in a specific category', async () => {
|
|
598
|
-
const result = await runCortexCli([
|
|
656
|
+
const result = await runCortexCli([
|
|
657
|
+
'memory',
|
|
658
|
+
'list',
|
|
659
|
+
'project',
|
|
660
|
+
], {
|
|
599
661
|
cwd: testProject,
|
|
600
662
|
});
|
|
601
663
|
|
|
@@ -606,7 +668,12 @@ describe('Cortex CLI Integration Tests', () => {
|
|
|
606
668
|
});
|
|
607
669
|
|
|
608
670
|
it('should output in JSON format', async () => {
|
|
609
|
-
const result = await runCortexCli([
|
|
671
|
+
const result = await runCortexCli([
|
|
672
|
+
'memory',
|
|
673
|
+
'list',
|
|
674
|
+
'--format',
|
|
675
|
+
'json',
|
|
676
|
+
], {
|
|
610
677
|
cwd: testProject,
|
|
611
678
|
});
|
|
612
679
|
|
|
@@ -624,7 +691,11 @@ describe('Cortex CLI Integration Tests', () => {
|
|
|
624
691
|
expiresAt: new Date('2020-01-01T00:00:00.000Z'),
|
|
625
692
|
});
|
|
626
693
|
|
|
627
|
-
const result = await runCortexCli([
|
|
694
|
+
const result = await runCortexCli([
|
|
695
|
+
'memory',
|
|
696
|
+
'list',
|
|
697
|
+
'project',
|
|
698
|
+
], {
|
|
628
699
|
cwd: testProject,
|
|
629
700
|
});
|
|
630
701
|
|
|
@@ -640,7 +711,12 @@ describe('Cortex CLI Integration Tests', () => {
|
|
|
640
711
|
expiresAt: new Date('2020-01-01T00:00:00.000Z'),
|
|
641
712
|
});
|
|
642
713
|
|
|
643
|
-
const result = await runCortexCli([
|
|
714
|
+
const result = await runCortexCli([
|
|
715
|
+
'memory',
|
|
716
|
+
'list',
|
|
717
|
+
'project',
|
|
718
|
+
'--include-expired',
|
|
719
|
+
], {
|
|
644
720
|
cwd: testProject,
|
|
645
721
|
});
|
|
646
722
|
|
|
@@ -650,7 +726,11 @@ describe('Cortex CLI Integration Tests', () => {
|
|
|
650
726
|
});
|
|
651
727
|
|
|
652
728
|
it('should return empty list for non-existent category', async () => {
|
|
653
|
-
const result = await runCortexCli([
|
|
729
|
+
const result = await runCortexCli([
|
|
730
|
+
'memory',
|
|
731
|
+
'list',
|
|
732
|
+
'nonexistent',
|
|
733
|
+
], {
|
|
654
734
|
cwd: testProject,
|
|
655
735
|
});
|
|
656
736
|
|
|
@@ -661,7 +741,12 @@ describe('Cortex CLI Integration Tests', () => {
|
|
|
661
741
|
|
|
662
742
|
it('should use yaml format for invalid format option', async () => {
|
|
663
743
|
// Invalid formats fall back to default YAML formatting
|
|
664
|
-
const result = await runCortexCli([
|
|
744
|
+
const result = await runCortexCli([
|
|
745
|
+
'memory',
|
|
746
|
+
'list',
|
|
747
|
+
'--format',
|
|
748
|
+
'invalid',
|
|
749
|
+
], {
|
|
665
750
|
cwd: testProject,
|
|
666
751
|
});
|
|
667
752
|
|
|
@@ -681,8 +766,14 @@ describe('Cortex CLI Integration Tests', () => {
|
|
|
681
766
|
|
|
682
767
|
it('should update memory content', async () => {
|
|
683
768
|
const result = await runCortexCli(
|
|
684
|
-
[
|
|
685
|
-
|
|
769
|
+
[
|
|
770
|
+
'memory',
|
|
771
|
+
'update',
|
|
772
|
+
'project/updatable',
|
|
773
|
+
'--content',
|
|
774
|
+
'Updated content.',
|
|
775
|
+
],
|
|
776
|
+
{ cwd: testProject },
|
|
686
777
|
);
|
|
687
778
|
|
|
688
779
|
expect(result.exitCode).toBe(0);
|
|
@@ -695,8 +786,14 @@ describe('Cortex CLI Integration Tests', () => {
|
|
|
695
786
|
|
|
696
787
|
it('should update memory tags', async () => {
|
|
697
788
|
const result = await runCortexCli(
|
|
698
|
-
[
|
|
699
|
-
|
|
789
|
+
[
|
|
790
|
+
'memory',
|
|
791
|
+
'update',
|
|
792
|
+
'project/updatable',
|
|
793
|
+
'--tags',
|
|
794
|
+
'new-tag,updated',
|
|
795
|
+
],
|
|
796
|
+
{ cwd: testProject },
|
|
700
797
|
);
|
|
701
798
|
|
|
702
799
|
expect(result.exitCode).toBe(0);
|
|
@@ -715,7 +812,7 @@ describe('Cortex CLI Integration Tests', () => {
|
|
|
715
812
|
'--expires-at',
|
|
716
813
|
'2030-01-01T00:00:00.000Z',
|
|
717
814
|
],
|
|
718
|
-
{ cwd: testProject }
|
|
815
|
+
{ cwd: testProject },
|
|
719
816
|
);
|
|
720
817
|
|
|
721
818
|
expect(result.exitCode).toBe(0);
|
|
@@ -733,10 +830,15 @@ describe('Cortex CLI Integration Tests', () => {
|
|
|
733
830
|
});
|
|
734
831
|
|
|
735
832
|
const result = await runCortexCli(
|
|
736
|
-
[
|
|
833
|
+
[
|
|
834
|
+
'memory',
|
|
835
|
+
'update',
|
|
836
|
+
'project/with-expiry',
|
|
837
|
+
'--no-expires-at',
|
|
838
|
+
],
|
|
737
839
|
{
|
|
738
840
|
cwd: testProject,
|
|
739
|
-
}
|
|
841
|
+
},
|
|
740
842
|
);
|
|
741
843
|
|
|
742
844
|
expect(result.exitCode).toBe(0);
|
|
@@ -747,8 +849,14 @@ describe('Cortex CLI Integration Tests', () => {
|
|
|
747
849
|
|
|
748
850
|
it('should fail when memory does not exist', async () => {
|
|
749
851
|
const result = await runCortexCli(
|
|
750
|
-
[
|
|
751
|
-
|
|
852
|
+
[
|
|
853
|
+
'memory',
|
|
854
|
+
'update',
|
|
855
|
+
'project/nonexistent',
|
|
856
|
+
'--content',
|
|
857
|
+
'New content.',
|
|
858
|
+
],
|
|
859
|
+
{ cwd: testProject },
|
|
752
860
|
);
|
|
753
861
|
|
|
754
862
|
expect(result.exitCode).toBe(1);
|
|
@@ -756,7 +864,11 @@ describe('Cortex CLI Integration Tests', () => {
|
|
|
756
864
|
});
|
|
757
865
|
|
|
758
866
|
it('should fail when no updates provided', async () => {
|
|
759
|
-
const result = await runCortexCli([
|
|
867
|
+
const result = await runCortexCli([
|
|
868
|
+
'memory',
|
|
869
|
+
'update',
|
|
870
|
+
'project/updatable',
|
|
871
|
+
], {
|
|
760
872
|
cwd: testProject,
|
|
761
873
|
});
|
|
762
874
|
|
|
@@ -769,10 +881,16 @@ describe('Cortex CLI Integration Tests', () => {
|
|
|
769
881
|
await fs.writeFile(contentFile, 'Content from file update.', 'utf8');
|
|
770
882
|
|
|
771
883
|
const result = await runCortexCli(
|
|
772
|
-
[
|
|
884
|
+
[
|
|
885
|
+
'memory',
|
|
886
|
+
'update',
|
|
887
|
+
'project/updatable',
|
|
888
|
+
'--file',
|
|
889
|
+
contentFile,
|
|
890
|
+
],
|
|
773
891
|
{
|
|
774
892
|
cwd: testProject,
|
|
775
|
-
}
|
|
893
|
+
},
|
|
776
894
|
);
|
|
777
895
|
|
|
778
896
|
expect(result.exitCode).toBe(0);
|
|
@@ -783,10 +901,16 @@ describe('Cortex CLI Integration Tests', () => {
|
|
|
783
901
|
|
|
784
902
|
it('should preserve original content when only updating tags', async () => {
|
|
785
903
|
const result = await runCortexCli(
|
|
786
|
-
[
|
|
904
|
+
[
|
|
905
|
+
'memory',
|
|
906
|
+
'update',
|
|
907
|
+
'project/updatable',
|
|
908
|
+
'--tags',
|
|
909
|
+
'new-tag',
|
|
910
|
+
],
|
|
787
911
|
{
|
|
788
912
|
cwd: testProject,
|
|
789
|
-
}
|
|
913
|
+
},
|
|
790
914
|
);
|
|
791
915
|
|
|
792
916
|
expect(result.exitCode).toBe(0);
|
|
@@ -809,7 +933,7 @@ describe('Cortex CLI Integration Tests', () => {
|
|
|
809
933
|
'-t',
|
|
810
934
|
'tag-c',
|
|
811
935
|
],
|
|
812
|
-
{ cwd: testProject }
|
|
936
|
+
{ cwd: testProject },
|
|
813
937
|
);
|
|
814
938
|
|
|
815
939
|
expect(result.exitCode).toBe(0);
|
|
@@ -823,8 +947,16 @@ describe('Cortex CLI Integration Tests', () => {
|
|
|
823
947
|
|
|
824
948
|
it('should update memory tags with mixed formats (comma-separated and multiple flags)', async () => {
|
|
825
949
|
const result = await runCortexCli(
|
|
826
|
-
[
|
|
827
|
-
|
|
950
|
+
[
|
|
951
|
+
'memory',
|
|
952
|
+
'update',
|
|
953
|
+
'project/updatable',
|
|
954
|
+
'-t',
|
|
955
|
+
'x,y',
|
|
956
|
+
'-t',
|
|
957
|
+
'z',
|
|
958
|
+
],
|
|
959
|
+
{ cwd: testProject },
|
|
828
960
|
);
|
|
829
961
|
|
|
830
962
|
expect(result.exitCode).toBe(0);
|
|
@@ -855,7 +987,11 @@ describe('Cortex CLI Integration Tests', () => {
|
|
|
855
987
|
});
|
|
856
988
|
|
|
857
989
|
it('should report expired memories with --dry-run', async () => {
|
|
858
|
-
const result = await runCortexCli([
|
|
990
|
+
const result = await runCortexCli([
|
|
991
|
+
'store',
|
|
992
|
+
'prune',
|
|
993
|
+
'--dry-run',
|
|
994
|
+
], {
|
|
859
995
|
cwd: testProject,
|
|
860
996
|
});
|
|
861
997
|
|
|
@@ -870,7 +1006,9 @@ describe('Cortex CLI Integration Tests', () => {
|
|
|
870
1006
|
});
|
|
871
1007
|
|
|
872
1008
|
it('should delete expired memories without --dry-run', async () => {
|
|
873
|
-
const result = await runCortexCli([
|
|
1009
|
+
const result = await runCortexCli([
|
|
1010
|
+
'store', 'prune',
|
|
1011
|
+
], {
|
|
874
1012
|
cwd: testProject,
|
|
875
1013
|
});
|
|
876
1014
|
|
|
@@ -891,11 +1029,11 @@ describe('Cortex CLI Integration Tests', () => {
|
|
|
891
1029
|
await fs.rm(join(storeDir, 'project', 'expired-one.md'));
|
|
892
1030
|
await fs.rm(join(storeDir, 'project', 'expired-two.md'));
|
|
893
1031
|
|
|
894
|
-
await createCategoryIndex(storeDir, 'project', [
|
|
895
|
-
{ path: 'project/fresh-memory', tokenEstimate: 10 },
|
|
896
|
-
]);
|
|
1032
|
+
await createCategoryIndex(storeDir, 'project', [{ path: 'project/fresh-memory', tokenEstimate: 10 }]);
|
|
897
1033
|
|
|
898
|
-
const result = await runCortexCli([
|
|
1034
|
+
const result = await runCortexCli([
|
|
1035
|
+
'store', 'prune',
|
|
1036
|
+
], {
|
|
899
1037
|
cwd: testProject,
|
|
900
1038
|
});
|
|
901
1039
|
|
|
@@ -916,7 +1054,9 @@ describe('Cortex CLI Integration Tests', () => {
|
|
|
916
1054
|
});
|
|
917
1055
|
|
|
918
1056
|
it('should rebuild indexes', async () => {
|
|
919
|
-
const result = await runCortexCli([
|
|
1057
|
+
const result = await runCortexCli([
|
|
1058
|
+
'store', 'reindex',
|
|
1059
|
+
], {
|
|
920
1060
|
cwd: testProject,
|
|
921
1061
|
});
|
|
922
1062
|
|
|
@@ -963,14 +1103,17 @@ describe('Cortex CLI Integration Tests', () => {
|
|
|
963
1103
|
await fs.mkdir(fakeCortex, { recursive: true });
|
|
964
1104
|
// Note: .cortex/memory doesn't exist, so resolution should fail
|
|
965
1105
|
try {
|
|
966
|
-
const result = await runCortexCli([
|
|
1106
|
+
const result = await runCortexCli([
|
|
1107
|
+
'memory', 'list',
|
|
1108
|
+
], {
|
|
967
1109
|
cwd: emptyDir,
|
|
968
1110
|
});
|
|
969
1111
|
|
|
970
1112
|
// Either fails because no store found, or succeeds with empty list
|
|
971
1113
|
// depending on whether global store exists
|
|
972
1114
|
expect(result.exitCode).toBeGreaterThanOrEqual(0);
|
|
973
|
-
}
|
|
1115
|
+
}
|
|
1116
|
+
finally {
|
|
974
1117
|
await fs.rm(emptyDir, { recursive: true, force: true });
|
|
975
1118
|
}
|
|
976
1119
|
});
|
|
@@ -998,7 +1141,9 @@ describe('Cortex CLI Integration Tests', () => {
|
|
|
998
1141
|
});
|
|
999
1142
|
|
|
1000
1143
|
it('should show memory subcommand help', async () => {
|
|
1001
|
-
const result = await runCortexCli([
|
|
1144
|
+
const result = await runCortexCli([
|
|
1145
|
+
'memory', '--help',
|
|
1146
|
+
], {
|
|
1002
1147
|
cwd: testProject,
|
|
1003
1148
|
});
|
|
1004
1149
|
|
|
@@ -1010,7 +1155,9 @@ describe('Cortex CLI Integration Tests', () => {
|
|
|
1010
1155
|
});
|
|
1011
1156
|
|
|
1012
1157
|
it('should show store subcommand help', async () => {
|
|
1013
|
-
const result = await runCortexCli([
|
|
1158
|
+
const result = await runCortexCli([
|
|
1159
|
+
'store', '--help',
|
|
1160
|
+
], {
|
|
1014
1161
|
cwd: testProject,
|
|
1015
1162
|
});
|
|
1016
1163
|
|
|
@@ -1034,14 +1181,28 @@ describe('Cortex CLI Integration Tests', () => {
|
|
|
1034
1181
|
|
|
1035
1182
|
try {
|
|
1036
1183
|
const result = await runCortexCli(
|
|
1037
|
-
[
|
|
1184
|
+
[
|
|
1185
|
+
'store',
|
|
1186
|
+
'init',
|
|
1187
|
+
storePath,
|
|
1188
|
+
'--name',
|
|
1189
|
+
'my-project',
|
|
1190
|
+
'--format',
|
|
1191
|
+
'json',
|
|
1192
|
+
],
|
|
1038
1193
|
{
|
|
1039
1194
|
cwd: freshDir,
|
|
1040
1195
|
env: { CORTEX_CONFIG_DIR: configDir },
|
|
1041
|
-
}
|
|
1196
|
+
},
|
|
1042
1197
|
);
|
|
1043
1198
|
|
|
1044
|
-
expectCliOk([
|
|
1199
|
+
expectCliOk([
|
|
1200
|
+
'store',
|
|
1201
|
+
'init',
|
|
1202
|
+
storePath,
|
|
1203
|
+
'--name',
|
|
1204
|
+
'my-project',
|
|
1205
|
+
], result);
|
|
1045
1206
|
expect(result.exitCode).toBe(0);
|
|
1046
1207
|
|
|
1047
1208
|
const parsed = JSON.parse(result.stdout) as {
|
|
@@ -1054,7 +1215,8 @@ describe('Cortex CLI Integration Tests', () => {
|
|
|
1054
1215
|
const configContent = await fs.readFile(join(configDir, 'config.yaml'), 'utf8');
|
|
1055
1216
|
expect(configContent).toContain('my-project');
|
|
1056
1217
|
expect(configContent).toContain(storePath);
|
|
1057
|
-
}
|
|
1218
|
+
}
|
|
1219
|
+
finally {
|
|
1058
1220
|
await fs.rm(freshDir, { recursive: true, force: true });
|
|
1059
1221
|
}
|
|
1060
1222
|
});
|
|
@@ -1070,19 +1232,34 @@ describe('Cortex CLI Integration Tests', () => {
|
|
|
1070
1232
|
|
|
1071
1233
|
try {
|
|
1072
1234
|
const result = await runCortexCli(
|
|
1073
|
-
[
|
|
1235
|
+
[
|
|
1236
|
+
'store',
|
|
1237
|
+
'init',
|
|
1238
|
+
storePath,
|
|
1239
|
+
'--name',
|
|
1240
|
+
'new-dir-store',
|
|
1241
|
+
'--format',
|
|
1242
|
+
'json',
|
|
1243
|
+
],
|
|
1074
1244
|
{
|
|
1075
1245
|
cwd: freshDir,
|
|
1076
1246
|
env: { CORTEX_CONFIG_DIR: configDir },
|
|
1077
|
-
}
|
|
1247
|
+
},
|
|
1078
1248
|
);
|
|
1079
1249
|
|
|
1080
|
-
expectCliOk([
|
|
1250
|
+
expectCliOk([
|
|
1251
|
+
'store',
|
|
1252
|
+
'init',
|
|
1253
|
+
storePath,
|
|
1254
|
+
'--name',
|
|
1255
|
+
'new-dir-store',
|
|
1256
|
+
], result);
|
|
1081
1257
|
|
|
1082
1258
|
// The directory must have been created by the init command
|
|
1083
1259
|
const dirStat = await fs.stat(storePath);
|
|
1084
1260
|
expect(dirStat.isDirectory()).toBe(true);
|
|
1085
|
-
}
|
|
1261
|
+
}
|
|
1262
|
+
finally {
|
|
1086
1263
|
await fs.rm(freshDir, { recursive: true, force: true });
|
|
1087
1264
|
}
|
|
1088
1265
|
});
|
|
@@ -1091,10 +1268,24 @@ describe('Cortex CLI Integration Tests', () => {
|
|
|
1091
1268
|
// Register a store first using the existing testProject setup
|
|
1092
1269
|
const storePath = join(testProject, '.cortex', 'memory2');
|
|
1093
1270
|
const firstInit = await runCortexCli(
|
|
1094
|
-
[
|
|
1095
|
-
|
|
1271
|
+
[
|
|
1272
|
+
'store',
|
|
1273
|
+
'init',
|
|
1274
|
+
storePath,
|
|
1275
|
+
'--name',
|
|
1276
|
+
'existing-store',
|
|
1277
|
+
'--format',
|
|
1278
|
+
'json',
|
|
1279
|
+
],
|
|
1280
|
+
{ cwd: testProject },
|
|
1096
1281
|
);
|
|
1097
|
-
expectCliOk([
|
|
1282
|
+
expectCliOk([
|
|
1283
|
+
'store',
|
|
1284
|
+
'init',
|
|
1285
|
+
storePath,
|
|
1286
|
+
'--name',
|
|
1287
|
+
'existing-store',
|
|
1288
|
+
], firstInit);
|
|
1098
1289
|
|
|
1099
1290
|
// Attempt to init the same name again — should fail
|
|
1100
1291
|
const secondInit = await runCortexCli(
|
|
@@ -1105,7 +1296,7 @@ describe('Cortex CLI Integration Tests', () => {
|
|
|
1105
1296
|
'--name',
|
|
1106
1297
|
'existing-store',
|
|
1107
1298
|
],
|
|
1108
|
-
{ cwd: testProject }
|
|
1299
|
+
{ cwd: testProject },
|
|
1109
1300
|
);
|
|
1110
1301
|
|
|
1111
1302
|
expect(secondInit.exitCode).toBe(1);
|