@yeseh/cortex-cli 0.6.8 → 0.6.9

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 (74) hide show
  1. package/dist/program.js +1538 -5
  2. package/dist/program.js.map +32 -3
  3. package/dist/run.d.ts +0 -1
  4. package/dist/run.d.ts.map +1 -1
  5. package/dist/run.js +3 -4
  6. package/dist/run.js.map +3 -3
  7. package/package.json +4 -6
  8. package/dist/chunk-dsfj4baj.js +0 -1543
  9. package/dist/chunk-dsfj4baj.js.map +0 -38
  10. package/src/category/commands/create.spec.ts +0 -139
  11. package/src/category/commands/create.ts +0 -119
  12. package/src/category/index.ts +0 -24
  13. package/src/commands/init.spec.ts +0 -203
  14. package/src/commands/init.ts +0 -301
  15. package/src/context.spec.ts +0 -60
  16. package/src/context.ts +0 -170
  17. package/src/errors.spec.ts +0 -264
  18. package/src/errors.ts +0 -105
  19. package/src/memory/commands/add.spec.ts +0 -169
  20. package/src/memory/commands/add.ts +0 -158
  21. package/src/memory/commands/definitions.spec.ts +0 -80
  22. package/src/memory/commands/list.spec.ts +0 -123
  23. package/src/memory/commands/list.ts +0 -269
  24. package/src/memory/commands/move.spec.ts +0 -85
  25. package/src/memory/commands/move.ts +0 -119
  26. package/src/memory/commands/remove.spec.ts +0 -79
  27. package/src/memory/commands/remove.ts +0 -108
  28. package/src/memory/commands/show.spec.ts +0 -71
  29. package/src/memory/commands/show.ts +0 -165
  30. package/src/memory/commands/test-helpers.spec.ts +0 -127
  31. package/src/memory/commands/update.spec.ts +0 -86
  32. package/src/memory/commands/update.ts +0 -230
  33. package/src/memory/index.spec.ts +0 -59
  34. package/src/memory/index.ts +0 -44
  35. package/src/memory/parsing.spec.ts +0 -105
  36. package/src/memory/parsing.ts +0 -22
  37. package/src/observability.spec.ts +0 -126
  38. package/src/observability.ts +0 -82
  39. package/src/output.spec.ts +0 -835
  40. package/src/output.ts +0 -119
  41. package/src/program.spec.ts +0 -46
  42. package/src/program.ts +0 -75
  43. package/src/run.spec.ts +0 -31
  44. package/src/run.ts +0 -9
  45. package/src/store/commands/add.spec.ts +0 -131
  46. package/src/store/commands/add.ts +0 -231
  47. package/src/store/commands/init.spec.ts +0 -220
  48. package/src/store/commands/init.ts +0 -272
  49. package/src/store/commands/list.spec.ts +0 -175
  50. package/src/store/commands/list.ts +0 -102
  51. package/src/store/commands/prune.spec.ts +0 -120
  52. package/src/store/commands/prune.ts +0 -152
  53. package/src/store/commands/reindexs.spec.ts +0 -94
  54. package/src/store/commands/reindexs.ts +0 -97
  55. package/src/store/commands/remove.spec.ts +0 -97
  56. package/src/store/commands/remove.ts +0 -189
  57. package/src/store/index.spec.ts +0 -60
  58. package/src/store/index.ts +0 -49
  59. package/src/store/utils/resolve-store-name.spec.ts +0 -62
  60. package/src/store/utils/resolve-store-name.ts +0 -79
  61. package/src/test-helpers.spec.ts +0 -430
  62. package/src/tests/cli.integration.spec.ts +0 -1306
  63. package/src/toon.spec.ts +0 -183
  64. package/src/toon.ts +0 -462
  65. package/src/utils/git.spec.ts +0 -95
  66. package/src/utils/git.ts +0 -51
  67. package/src/utils/input.spec.ts +0 -326
  68. package/src/utils/input.ts +0 -150
  69. package/src/utils/paths.spec.ts +0 -235
  70. package/src/utils/paths.ts +0 -75
  71. package/src/utils/prompts.spec.ts +0 -23
  72. package/src/utils/prompts.ts +0 -88
  73. package/src/utils/resolve-default-store.spec.ts +0 -135
  74. package/src/utils/resolve-default-store.ts +0 -74
@@ -1,59 +0,0 @@
1
- /**
2
- * Unit tests for memory command group wiring.
3
- *
4
- * Verifies that the `memory` command group is correctly configured with
5
- * the expected name, description, options, and subcommands.
6
- *
7
- * @module cli/memory/index.spec
8
- */
9
-
10
- import { describe, it, expect } from 'bun:test';
11
-
12
- import { memoryCommand } from './index.ts';
13
-
14
- describe('memoryCommand', () => {
15
- it('should have name "memory"', () => {
16
- expect(memoryCommand.name()).toBe('memory');
17
- });
18
-
19
- it('should have description', () => {
20
- expect(memoryCommand.description()).toBeTruthy();
21
- });
22
-
23
- it('should have --store option', () => {
24
- const options = memoryCommand.options;
25
- const storeOption = options.find((o) => o.long === '--store');
26
- expect(storeOption).toBeDefined();
27
- expect(storeOption?.short).toBe('-s');
28
- });
29
-
30
- it('should have "add" subcommand registered', () => {
31
- const names = memoryCommand.commands.map((c) => c.name());
32
- expect(names).toContain('add');
33
- });
34
-
35
- it('should have "show" subcommand registered', () => {
36
- const names = memoryCommand.commands.map((c) => c.name());
37
- expect(names).toContain('show');
38
- });
39
-
40
- it('should have "update" subcommand registered', () => {
41
- const names = memoryCommand.commands.map((c) => c.name());
42
- expect(names).toContain('update');
43
- });
44
-
45
- it('should have "remove" subcommand registered', () => {
46
- const names = memoryCommand.commands.map((c) => c.name());
47
- expect(names).toContain('remove');
48
- });
49
-
50
- it('should have "move" subcommand registered', () => {
51
- const names = memoryCommand.commands.map((c) => c.name());
52
- expect(names).toContain('move');
53
- });
54
-
55
- it('should have "list" subcommand registered', () => {
56
- const names = memoryCommand.commands.map((c) => c.name());
57
- expect(names).toContain('list');
58
- });
59
- });
@@ -1,44 +0,0 @@
1
- /**
2
- * Memory command group for the CLI.
3
- *
4
- * This module defines the `memory` command group, which provides operations
5
- * for managing memories in the Cortex memory system. The `--store` option
6
- * is defined at the group level and inherited by all subcommands.
7
- *
8
- * @example
9
- * ```bash
10
- * # Use default store
11
- * cortex memory add project/notes --content "Hello"
12
- *
13
- * # Use specific store
14
- * cortex memory --store my-store add project/notes --content "Hello"
15
- * cortex memory -s my-store list
16
- * ```
17
- */
18
-
19
- import { Command } from '@commander-js/extra-typings';
20
-
21
- import { addCommand } from './commands/add.ts';
22
- import { showCommand } from './commands/show.ts';
23
- import { updateCommand } from './commands/update.ts';
24
- import { removeCommand } from './commands/remove.ts';
25
- import { moveCommand } from './commands/move.ts';
26
- import { listCommand } from './commands/list.ts';
27
-
28
- /**
29
- * The `memory` command group.
30
- *
31
- * Provides memory management operations. The `--store` option allows
32
- * targeting a specific named store instead of the default store.
33
- * This option is inherited by all subcommands.
34
- */
35
- export const memoryCommand = new Command('memory')
36
- .description('Memory operations')
37
- .option('-s, --store <name>', 'Use a specific named store');
38
-
39
- memoryCommand.addCommand(addCommand);
40
- memoryCommand.addCommand(showCommand);
41
- memoryCommand.addCommand(updateCommand);
42
- memoryCommand.addCommand(removeCommand);
43
- memoryCommand.addCommand(moveCommand);
44
- memoryCommand.addCommand(listCommand);
@@ -1,105 +0,0 @@
1
- /**
2
- * Unit tests for memory/parsing.ts
3
- *
4
- * @module cli/memory/parsing.spec
5
- */
6
-
7
- import { describe, it, expect } from 'bun:test';
8
- import { parseTags, parseExpiresAt } from './parsing';
9
- import { expectInvalidArgumentError } from '../test-helpers.spec';
10
-
11
- // ============================================================================
12
- // parseTags
13
- // ============================================================================
14
-
15
- describe('parseTags', () => {
16
- it('should return empty array for undefined input', () => {
17
- expect(parseTags(undefined)).toEqual([]);
18
- });
19
-
20
- it('should return empty array for empty array input', () => {
21
- expect(parseTags([])).toEqual([]);
22
- });
23
-
24
- it('should split comma-separated tags from a single string', () => {
25
- expect(parseTags(['foo,bar,baz'])).toEqual([
26
- 'foo',
27
- 'bar',
28
- 'baz',
29
- ]);
30
- });
31
-
32
- it('should handle multiple string entries in the array', () => {
33
- expect(parseTags([
34
- 'foo', 'bar',
35
- ])).toEqual([
36
- 'foo', 'bar',
37
- ]);
38
- });
39
-
40
- it('should trim whitespace from each tag', () => {
41
- expect(parseTags([' foo , bar , baz '])).toEqual([
42
- 'foo',
43
- 'bar',
44
- 'baz',
45
- ]);
46
- });
47
-
48
- it('should filter empty strings after splitting and trimming', () => {
49
- expect(parseTags([
50
- ',,,', ' , ',
51
- ])).toEqual([]);
52
- });
53
-
54
- it('should preserve duplicate tags without deduplication', () => {
55
- expect(parseTags([
56
- 'foo,foo', 'foo',
57
- ])).toEqual([
58
- 'foo',
59
- 'foo',
60
- 'foo',
61
- ]);
62
- });
63
- });
64
-
65
- // ============================================================================
66
- // parseExpiresAt
67
- // ============================================================================
68
-
69
- describe('parseExpiresAt', () => {
70
- it('should return undefined for undefined input', () => {
71
- expect(parseExpiresAt(undefined)).toBeUndefined();
72
- });
73
-
74
- it('should return undefined for empty string', () => {
75
- expect(parseExpiresAt('')).toBeUndefined();
76
- });
77
-
78
- it('should return a Date for valid ISO 8601 string', () => {
79
- const result = parseExpiresAt('2025-12-31T23:59:59.000Z');
80
- expect(result).toBeInstanceOf(Date);
81
- expect(result!.toISOString()).toBe('2025-12-31T23:59:59.000Z');
82
- });
83
-
84
- it('should return a Date for valid date-only string "2025-12-31"', () => {
85
- const result = parseExpiresAt('2025-12-31');
86
- expect(result).toBeInstanceOf(Date);
87
- expect(result!.getFullYear()).toBe(2025);
88
- expect(result!.getMonth()).toBe(11); // 0-indexed December
89
- expect(result!.getDate()).toBe(31);
90
- });
91
-
92
- it('should throw InvalidArgumentError for invalid date string "not-a-date"', async () => {
93
- await expectInvalidArgumentError(
94
- () => parseExpiresAt('not-a-date'),
95
- 'Invalid expiration date format',
96
- );
97
- });
98
-
99
- it('should throw InvalidArgumentError for garbage string "abc123"', async () => {
100
- await expectInvalidArgumentError(
101
- () => parseExpiresAt('abc123'),
102
- 'Invalid expiration date format',
103
- );
104
- });
105
- });
@@ -1,22 +0,0 @@
1
- import { throwCliError } from '../errors';
2
-
3
- export const parseTags = (raw?: string[]): string[] =>
4
- raw
5
- ? raw
6
- .flatMap((tag) => tag.split(','))
7
- .map((tag) => tag.trim())
8
- .filter(Boolean)
9
- : [];
10
-
11
- export const parseExpiresAt = (raw?: string): Date | undefined => {
12
- if (!raw) {
13
- return undefined;
14
- }
15
-
16
- const parsed = new Date(raw);
17
- if (Number.isNaN(parsed.getTime())) {
18
- throwCliError({ code: 'INVALID_ARGUMENTS', message: 'Invalid expiration date format' });
19
- }
20
-
21
- return parsed;
22
- };
@@ -1,126 +0,0 @@
1
- import { describe, it, expect, beforeEach, afterEach } from 'bun:test';
2
- import { createCliLogger } from './observability.ts';
3
-
4
- describe('createCliLogger', () => {
5
- let stderrLines: string[];
6
- let origWrite: typeof process.stderr.write;
7
- let origDebugEnv: string | undefined;
8
-
9
- beforeEach(() => {
10
- stderrLines = [];
11
- origWrite = process.stderr.write.bind(process.stderr);
12
- origDebugEnv = process.env.DEBUG;
13
- process.stderr.write = ((chunk: string | Uint8Array) => {
14
- stderrLines.push(typeof chunk === 'string' ? chunk : Buffer.from(chunk).toString());
15
- return true;
16
- }) as any;
17
- });
18
-
19
- afterEach(() => {
20
- process.stderr.write = origWrite;
21
- if (origDebugEnv === undefined) {
22
- delete process.env.DEBUG;
23
- }
24
- else {
25
- process.env.DEBUG = origDebugEnv;
26
- }
27
- });
28
-
29
- describe('info()', () => {
30
- it('should write human-friendly info log to stderr', () => {
31
- const logger = createCliLogger();
32
- logger.info('hello world');
33
- expect(stderrLines.length).toBe(1);
34
- expect(stderrLines[0]).toBe('INFO: hello world\n');
35
- });
36
-
37
- it('should include metadata in the log line', () => {
38
- const logger = createCliLogger();
39
- logger.info('test', { store: 'default', count: 5 });
40
- expect(stderrLines[0]).toBe('INFO: test store=default count=5\n');
41
- });
42
- });
43
-
44
- describe('warn()', () => {
45
- it('should write warn log to stderr', () => {
46
- const logger = createCliLogger();
47
- logger.warn('warning message');
48
- expect(stderrLines.length).toBe(1);
49
- expect(stderrLines[0]).toBe('WARN: warning message\n');
50
- });
51
- });
52
-
53
- describe('error()', () => {
54
- it('should write error log with Error object details', () => {
55
- const logger = createCliLogger();
56
- logger.error('something failed', new Error('boom'));
57
- expect(stderrLines.length).toBe(1);
58
- expect(stderrLines[0]).toBe('ERROR: something failed error=boom\n');
59
- });
60
-
61
- it('should handle string error argument', () => {
62
- const logger = createCliLogger();
63
- logger.error('failed', 'string error');
64
- expect(stderrLines[0]).toBe('ERROR: failed error="string error"\n');
65
- });
66
-
67
- it('should handle missing error argument', () => {
68
- const logger = createCliLogger();
69
- logger.error('failed');
70
- expect(stderrLines.length).toBe(1);
71
- expect(stderrLines[0]).toBe('ERROR: failed\n');
72
- });
73
- });
74
-
75
- describe('debug()', () => {
76
- it('should suppress debug output when DEBUG env is not set', () => {
77
- delete process.env.DEBUG;
78
- const logger = createCliLogger();
79
- logger.debug('debug message');
80
- expect(stderrLines.length).toBe(0);
81
- });
82
-
83
- it('should write debug output when DEBUG=cortex', () => {
84
- process.env.DEBUG = 'cortex';
85
- const logger = createCliLogger();
86
- logger.debug('debug message');
87
- expect(stderrLines.length).toBe(1);
88
- expect(stderrLines[0]).toBe('DEBUG: debug message\n');
89
- });
90
-
91
- it('should write debug output when DEBUG includes cortex alongside other values', () => {
92
- process.env.DEBUG = 'express,cortex,http';
93
- const logger = createCliLogger();
94
- logger.debug('debug message');
95
- expect(stderrLines.length).toBe(1);
96
- });
97
-
98
- it('should suppress debug when DEBUG is set to a different value', () => {
99
- process.env.DEBUG = 'express';
100
- const logger = createCliLogger();
101
- logger.debug('debug message');
102
- expect(stderrLines.length).toBe(0);
103
- });
104
- });
105
-
106
- describe('Logger interface compliance', () => {
107
- it('should not write to stdout', () => {
108
- const stdoutLines: string[] = [];
109
- const origStdoutWrite = process.stdout.write.bind(process.stdout);
110
- process.stdout.write = ((chunk: string | Uint8Array) => {
111
- stdoutLines.push(typeof chunk === 'string' ? chunk : Buffer.from(chunk).toString());
112
- return true;
113
- }) as any;
114
- try {
115
- const logger = createCliLogger();
116
- logger.info('test');
117
- logger.warn('test');
118
- logger.error('test');
119
- expect(stdoutLines.length).toBe(0);
120
- }
121
- finally {
122
- process.stdout.write = origStdoutWrite;
123
- }
124
- });
125
- });
126
- });
@@ -1,82 +0,0 @@
1
- /**
2
- * CLI observability — plain ConsoleLogger writing human-readable lines to stderr.
3
- *
4
- * No OTel SDK dependency — keeps the CLI binary small.
5
- * Debug output is gated by the `DEBUG=cortex` environment variable.
6
- *
7
- * @module cli/observability
8
- */
9
- import type { Logger } from '@yeseh/cortex-core';
10
-
11
- /**
12
- * Creates a plain console logger for CLI usage.
13
- *
14
- * Writes human-readable log lines to stderr (not stdout) to avoid
15
- * polluting piped command output. Debug output is gated by the
16
- * `DEBUG=cortex` environment variable.
17
- *
18
- * @returns Logger instance writing to stderr
19
- *
20
- * @example
21
- * ```typescript
22
- * const logger = createCliLogger();
23
- * logger.info('Starting command', { store: 'global' });
24
- * // → INFO: Starting command store=global
25
- * ```
26
- *
27
- * @example
28
- * ```bash
29
- * # Enable debug output
30
- * DEBUG=cortex cortex memory list
31
- * ```
32
- */
33
- export const createCliLogger = (): Logger => {
34
- const debugEnabled =
35
- typeof process.env.DEBUG === 'string' && process.env.DEBUG.includes('cortex');
36
-
37
- const stringifyMetaValue = (value: unknown): string => {
38
- if (typeof value === 'string') {
39
- return value.includes(' ') ? JSON.stringify(value) : value;
40
- }
41
- if (typeof value === 'number' || typeof value === 'boolean' || value === null) {
42
- return String(value);
43
- }
44
- return JSON.stringify(value);
45
- };
46
-
47
- const formatMeta = (meta?: Record<string, unknown>): string => {
48
- if (!meta || Object.keys(meta).length === 0) return '';
49
- return Object.entries(meta)
50
- .map(([key, value]) => `${key}=${stringifyMetaValue(value)}`)
51
- .join(' ');
52
- };
53
-
54
- const write = (level: string, msg: string, meta?: Record<string, unknown>): void => {
55
- const line = `${level.toUpperCase()}: ${msg}`;
56
- const metaText = formatMeta(meta);
57
- process.stderr.write(metaText.length > 0 ? `${line} ${metaText}\n` : `${line}\n`);
58
- };
59
-
60
- return {
61
- debug(msg: string, meta?: Record<string, unknown>): void {
62
- if (debugEnabled) write('debug', msg, meta);
63
- },
64
- info(msg: string, meta?: Record<string, unknown>): void {
65
- write('info', msg, meta);
66
- },
67
- warn(msg: string, meta?: Record<string, unknown>): void {
68
- write('warn', msg, meta);
69
- },
70
- error(msg: string, err?: Error | unknown, meta?: Record<string, unknown>): void {
71
- const errMeta =
72
- err instanceof Error
73
- ? debugEnabled
74
- ? { error: err.message, stack: err.stack }
75
- : { error: err.message }
76
- : err !== null && err !== undefined
77
- ? { error: String(err) }
78
- : {};
79
- write('error', msg, { ...meta, ...errMeta });
80
- },
81
- };
82
- };