@codeyam/codeyam-cli 0.1.0-staging.ae0de75 → 0.1.0-staging.b8f4f94

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 (81) hide show
  1. package/analyzer-template/.build-info.json +7 -7
  2. package/analyzer-template/log.txt +3 -3
  3. package/analyzer-template/package.json +3 -3
  4. package/analyzer-template/packages/analyze/src/lib/ProjectAnalyzer.ts +13 -7
  5. package/analyzer-template/packages/analyze/src/lib/asts/index.ts +7 -2
  6. package/codeyam-cli/src/__tests__/memory-scripts/filter-session.test.js +196 -0
  7. package/codeyam-cli/src/__tests__/memory-scripts/filter-session.test.js.map +1 -0
  8. package/codeyam-cli/src/__tests__/memory-scripts/read-json-field.test.js +114 -0
  9. package/codeyam-cli/src/__tests__/memory-scripts/read-json-field.test.js.map +1 -0
  10. package/codeyam-cli/src/__tests__/memory-scripts/ripgrep-fallback.test.js +149 -0
  11. package/codeyam-cli/src/__tests__/memory-scripts/ripgrep-fallback.test.js.map +1 -0
  12. package/codeyam-cli/src/commands/default.js +3 -46
  13. package/codeyam-cli/src/commands/default.js.map +1 -1
  14. package/codeyam-cli/src/commands/editor.js +254 -66
  15. package/codeyam-cli/src/commands/editor.js.map +1 -1
  16. package/codeyam-cli/src/utils/__tests__/editorAudit.test.js +234 -0
  17. package/codeyam-cli/src/utils/__tests__/editorAudit.test.js.map +1 -1
  18. package/codeyam-cli/src/utils/__tests__/editorJournal.test.js +12 -1
  19. package/codeyam-cli/src/utils/__tests__/editorJournal.test.js.map +1 -1
  20. package/codeyam-cli/src/utils/__tests__/editorScenarios.test.js +29 -0
  21. package/codeyam-cli/src/utils/__tests__/editorScenarios.test.js.map +1 -1
  22. package/codeyam-cli/src/utils/__tests__/entityChangeStatus.test.js +1217 -0
  23. package/codeyam-cli/src/utils/__tests__/entityChangeStatus.test.js.map +1 -0
  24. package/codeyam-cli/src/utils/backgroundServer.js +2 -2
  25. package/codeyam-cli/src/utils/backgroundServer.js.map +1 -1
  26. package/codeyam-cli/src/utils/editorAudit.js +45 -5
  27. package/codeyam-cli/src/utils/editorAudit.js.map +1 -1
  28. package/codeyam-cli/src/utils/editorJournal.js +7 -0
  29. package/codeyam-cli/src/utils/editorJournal.js.map +1 -1
  30. package/codeyam-cli/src/utils/entityChangeStatus.js +255 -0
  31. package/codeyam-cli/src/utils/entityChangeStatus.js.map +1 -0
  32. package/codeyam-cli/src/utils/install-skills.js +1 -1
  33. package/codeyam-cli/src/utils/install-skills.js.map +1 -1
  34. package/codeyam-cli/src/utils/setupClaudeCodeSettings.js +5 -1
  35. package/codeyam-cli/src/utils/setupClaudeCodeSettings.js.map +1 -1
  36. package/codeyam-cli/src/webserver/build/client/assets/Terminal-nZNBALox.js +41 -0
  37. package/codeyam-cli/src/webserver/build/client/assets/api.editor-file-diff-l0sNRNKZ.js +1 -0
  38. package/codeyam-cli/src/webserver/build/client/assets/api.editor-file-l0sNRNKZ.js +1 -0
  39. package/codeyam-cli/src/webserver/build/client/assets/editor-DTwKl1Xu.js +10 -0
  40. package/codeyam-cli/src/webserver/build/client/assets/{entity._sha.scenarios._scenarioId.dev-D8ILZMR0.js → entity._sha.scenarios._scenarioId.dev-DjACbfdI.js} +1 -1
  41. package/codeyam-cli/src/webserver/build/client/assets/git-CdN8sCqs.js +1 -0
  42. package/codeyam-cli/src/webserver/build/client/assets/globals-h1-1oFYI.css +1 -0
  43. package/codeyam-cli/src/webserver/build/client/assets/index-yHOVb4rc.js +15 -0
  44. package/codeyam-cli/src/webserver/build/client/assets/manifest-9422aeab.js +1 -0
  45. package/codeyam-cli/src/webserver/build/client/assets/{memory-FweZHj5U.js → memory-Dg0mvYrI.js} +4 -1
  46. package/codeyam-cli/src/webserver/build/client/assets/{root-DUKqhFlb.js → root-BzQgN2ff.js} +1 -1
  47. package/codeyam-cli/src/webserver/build/server/assets/{index-BLhjL9Xi.js → index-Bh_pNxNA.js} +1 -1
  48. package/codeyam-cli/src/webserver/build/server/assets/server-build-Bqr22tlO.js +367 -0
  49. package/codeyam-cli/src/webserver/build/server/index.js +1 -1
  50. package/codeyam-cli/src/webserver/build-info.json +5 -5
  51. package/codeyam-cli/src/webserver/server.js +32 -6
  52. package/codeyam-cli/src/webserver/server.js.map +1 -1
  53. package/codeyam-cli/src/webserver/terminalServer.js +23 -4
  54. package/codeyam-cli/src/webserver/terminalServer.js.map +1 -1
  55. package/codeyam-cli/templates/editor-step-hook.py +53 -6
  56. package/codeyam-cli/templates/skills/codeyam-editor/SKILL.md +10 -5
  57. package/codeyam-cli/templates/skills/codeyam-memory/SKILL.md +10 -10
  58. package/codeyam-cli/templates/skills/codeyam-memory/scripts/holistic-analysis/detect-deprecated-patterns.mjs +139 -0
  59. package/codeyam-cli/templates/skills/codeyam-memory/scripts/holistic-analysis/find-exports.mjs +52 -0
  60. package/codeyam-cli/templates/skills/codeyam-memory/scripts/lib/read-json-field.mjs +61 -0
  61. package/codeyam-cli/templates/skills/codeyam-memory/scripts/lib/ripgrep-fallback.mjs +155 -0
  62. package/codeyam-cli/templates/skills/codeyam-memory/scripts/session-mining/cleanup.mjs +13 -0
  63. package/codeyam-cli/templates/skills/codeyam-memory/scripts/session-mining/filter-session.mjs +95 -0
  64. package/codeyam-cli/templates/skills/codeyam-memory/scripts/session-mining/preprocess.mjs +160 -0
  65. package/package.json +10 -10
  66. package/packages/analyze/src/lib/ProjectAnalyzer.js +10 -4
  67. package/packages/analyze/src/lib/ProjectAnalyzer.js.map +1 -1
  68. package/packages/analyze/src/lib/asts/index.js +4 -2
  69. package/packages/analyze/src/lib/asts/index.js.map +1 -1
  70. package/scripts/npm-post-install.cjs +22 -0
  71. package/codeyam-cli/src/webserver/build/client/assets/Terminal-wkqC0AQk.js +0 -41
  72. package/codeyam-cli/src/webserver/build/client/assets/editor-CdjF_fX6.js +0 -8
  73. package/codeyam-cli/src/webserver/build/client/assets/git-CFCTYk9I.js +0 -15
  74. package/codeyam-cli/src/webserver/build/client/assets/globals-B17TBSS6.css +0 -1
  75. package/codeyam-cli/src/webserver/build/client/assets/manifest-b8fd6b07.js +0 -1
  76. package/codeyam-cli/src/webserver/build/server/assets/server-build-DyMuI5mU.js +0 -363
  77. package/codeyam-cli/templates/skills/codeyam-memory/scripts/holistic-analysis/detect-deprecated-patterns.sh +0 -108
  78. package/codeyam-cli/templates/skills/codeyam-memory/scripts/holistic-analysis/find-exports.sh +0 -69
  79. package/codeyam-cli/templates/skills/codeyam-memory/scripts/session-mining/cleanup.sh +0 -12
  80. package/codeyam-cli/templates/skills/codeyam-memory/scripts/session-mining/filter.jq +0 -45
  81. package/codeyam-cli/templates/skills/codeyam-memory/scripts/session-mining/preprocess.sh +0 -139
@@ -1,10 +1,10 @@
1
1
  {
2
- "buildTimestamp": "2026-03-03T15:39:20.077Z",
3
- "buildTime": 1772552360077,
4
- "gitCommit": "ae0de758e679d36a7e66bc3b8c426c5ea24dcec5",
2
+ "buildTimestamp": "2026-03-05T14:58:11.774Z",
3
+ "buildTime": 1772722691774,
4
+ "gitCommit": "b8f4f94d19a17388b7e3c56faa1b9923d6bb1cd0",
5
5
  "nodeVersion": "v20.20.0",
6
- "contentHash": "56095f026fcf9575b86866f4fe3d3d61b9466cf70e4d3f16001752fd1febd7c2",
7
- "buildNumber": 824,
8
- "semanticVersion": "0.1.824",
9
- "version": "0.1.824 (2026-03-03T15:39+56095f0)"
6
+ "contentHash": "1348fb22a8854524e9b9fe65a720281456edd206f1009239c3ad46934f629fb5",
7
+ "buildNumber": 863,
8
+ "semanticVersion": "0.1.863",
9
+ "version": "0.1.863 (2026-03-05T14:58+1348fb2)"
10
10
  }
@@ -1,7 +1,7 @@
1
1
 
2
- [3/3/2026, 3:39:19 PM] > codeyam-combo@1.0.0 mergeDependencies
3
- [3/3/2026, 3:39:19 PM] > node ./scripts/mergePackageJsonFiles.cjs
2
+ [3/5/2026, 2:58:11 PM] > codeyam-combo@1.0.0 mergeDependencies
3
+ [3/5/2026, 2:58:11 PM] > node ./scripts/mergePackageJsonFiles.cjs
4
4
 
5
5
 
6
- [3/3/2026, 3:39:20 PM] Merged dependencies into root package.json
6
+ [3/5/2026, 2:58:11 PM] Merged dependencies into root package.json
7
7
 
@@ -9,7 +9,7 @@
9
9
  "dependencies": {
10
10
  "@aws-sdk/client-cloudwatch-logs": "^3.990.0",
11
11
  "@aws-sdk/client-cloudfront": "^3.990.0",
12
- "@aws-sdk/client-codebuild": "^3.990.0",
12
+ "@aws-sdk/client-codebuild": "^3.1000.0",
13
13
  "@aws-sdk/client-dynamodb": "^3.990.0",
14
14
  "@aws-sdk/client-ec2": "^3.990.0",
15
15
  "@aws-sdk/client-ecr": "^3.990.0",
@@ -38,7 +38,7 @@
38
38
  "pixelmatch": "^5.3.0",
39
39
  "playwright": "1.58.0",
40
40
  "sharp": "^0.34.5",
41
- "simple-git": "^3.28.0",
41
+ "simple-git": "^3.32.2",
42
42
  "undici": "^7.18.2",
43
43
  "uuid": "^11.1.0",
44
44
  "pluralize": "^8.0.0",
@@ -57,7 +57,7 @@
57
57
  "devDependencies": {
58
58
  "typescript": "^5.9.3",
59
59
  "@jest/types": "^30.2.0",
60
- "@types/node": "^25.0.2",
60
+ "@types/node": "^25.3.3",
61
61
  "@types/yargs": "^17.0.34",
62
62
  "@types/jsdom": "^27.0.0",
63
63
  "@types/better-sqlite3": "^7.6.13",
@@ -340,17 +340,23 @@ export class ProjectAnalyzer {
340
340
  * Refresh the TypeScript program to pick up file changes
341
341
  */
342
342
  refreshProgram(): void {
343
- // Memory logging: Capture state before refresh
344
- const memBefore = process.memoryUsage();
345
-
346
343
  // Apply the same unapprovedPaths filtering when refreshing
347
344
  const excludePatterns =
348
345
  this.project.metadata?.unapprovedPaths?.filter(Boolean) || [];
349
346
 
350
- // Refresh all programs
351
- this.programs = this.tsConfigPaths.map((configPath) =>
352
- lib.asts.createProgramFromTsConfigPath(configPath, excludePatterns),
353
- );
347
+ // Release old programs and caches BEFORE creating new ones to reduce peak memory.
348
+ // Without this, both old (~1.7GB) and new (~1.7GB) programs coexist during creation,
349
+ // causing OOM on monorepos with multiple tsconfigs.
350
+ this.programs = [];
351
+ this.sourceFileByPath.clear();
352
+ this.typeCheckerByPath.clear();
353
+
354
+ // Create programs one at a time so each old program can be GC'd before the next
355
+ for (const configPath of this.tsConfigPaths) {
356
+ this.programs.push(
357
+ lib.asts.createProgramFromTsConfigPath(configPath, excludePatterns),
358
+ );
359
+ }
354
360
 
355
361
  // Update primary program for backward compatibility
356
362
  this.program = this.programs[0];
@@ -95,8 +95,13 @@ export function createProgramFromTsConfigPath(
95
95
  throw new Error('Could not parse tsconfig.json');
96
96
  }
97
97
 
98
- // Filter file names based on exclude patterns to reduce memory usage
99
- let fileNames = parsedCommandLine.fileNames;
98
+ // Always filter out node_modules from root files to prevent OOM on large projects.
99
+ // This only removes them as root compilation targets — TypeScript's module resolution
100
+ // still follows imports into node_modules for type info when processing source files.
101
+ let fileNames = parsedCommandLine.fileNames.filter(
102
+ (f) => !f.includes('/node_modules/'),
103
+ );
104
+
100
105
  if (excludePatterns && excludePatterns.length > 0) {
101
106
  const regexPatterns = excludePatterns
102
107
  .map((pattern) => {
@@ -0,0 +1,196 @@
1
+ import { execFileSync } from 'child_process';
2
+ import * as fs from 'fs';
3
+ import * as os from 'os';
4
+ import * as path from 'path';
5
+ const SCRIPTS_DIR = path.resolve(__dirname, '../../../templates/skills/codeyam-memory/scripts');
6
+ const FILTER_SCRIPT = path.join(SCRIPTS_DIR, 'session-mining/filter-session.mjs');
7
+ function runFilter(lines) {
8
+ const tmp = path.join(os.tmpdir(), `filter-test-${Date.now()}.jsonl`);
9
+ try {
10
+ fs.writeFileSync(tmp, lines.map((l) => JSON.stringify(l)).join('\n'));
11
+ const stdout = execFileSync('node', [FILTER_SCRIPT, tmp], {
12
+ encoding: 'utf-8',
13
+ });
14
+ return stdout
15
+ .trim()
16
+ .split('\n')
17
+ .filter(Boolean)
18
+ .map((line) => JSON.parse(line));
19
+ }
20
+ finally {
21
+ fs.unlinkSync(tmp);
22
+ }
23
+ }
24
+ function assistantMsg(content) {
25
+ return {
26
+ type: 'assistant',
27
+ timestamp: '2024-01-15T10:00:00Z',
28
+ message: { content },
29
+ };
30
+ }
31
+ function userMsg(content) {
32
+ return {
33
+ type: 'user',
34
+ timestamp: '2024-01-15T10:00:01Z',
35
+ message: { content },
36
+ };
37
+ }
38
+ describe('filter-session.mjs', () => {
39
+ it('passes through assistant text content', () => {
40
+ const input = assistantMsg([{ type: 'text', text: 'Hello world' }]);
41
+ const [result] = runFilter([input]);
42
+ expect(result.type).toBe('assistant');
43
+ expect(result.ts).toBe('2024-01-15T10:00:00Z');
44
+ expect(result.content).toEqual([{ t: 'text', text: 'Hello world' }]);
45
+ });
46
+ it('truncates thinking at 1000 chars with ...[truncated]', () => {
47
+ const longThinking = 'x'.repeat(1500);
48
+ const input = assistantMsg([{ type: 'thinking', thinking: longThinking }]);
49
+ const [result] = runFilter([input]);
50
+ const item = result.content[0];
51
+ expect(item.t).toBe('think');
52
+ expect(item.thinking).toHaveLength(1000 + '...[truncated]'.length);
53
+ expect(item.thinking.endsWith('...[truncated]')).toBe(true);
54
+ });
55
+ it('does not truncate thinking under 1000 chars', () => {
56
+ const shortThinking = 'y'.repeat(999);
57
+ const input = assistantMsg([{ type: 'thinking', thinking: shortThinking }]);
58
+ const [result] = runFilter([input]);
59
+ expect(result.content[0].thinking).toBe(shortThinking);
60
+ });
61
+ it('stringifies object tool input and truncates at 300 chars with ...', () => {
62
+ const bigInput = { key: 'v'.repeat(400) };
63
+ const input = assistantMsg([
64
+ { type: 'tool_use', name: 'readFile', input: bigInput },
65
+ ]);
66
+ const [result] = runFilter([input]);
67
+ const item = result.content[0];
68
+ expect(item.t).toBe('tool');
69
+ expect(item.name).toBe('readFile');
70
+ expect(item.input).toHaveLength(300 + '...'.length);
71
+ expect(item.input.endsWith('...')).toBe(true);
72
+ });
73
+ it('does not double-stringify string tool input (tostring gotcha)', () => {
74
+ // jq's `tostring` on a string is a no-op. JSON.stringify("str") would
75
+ // produce '"str"' with extra quotes. The script must handle this.
76
+ const input = assistantMsg([
77
+ { type: 'tool_use', name: 'bash', input: 'echo hello' },
78
+ ]);
79
+ const [result] = runFilter([input]);
80
+ const item = result.content[0];
81
+ // Should be the raw string, not '"echo hello"'
82
+ expect(item.input).toBe('echo hello');
83
+ });
84
+ it('passes through user string content', () => {
85
+ const input = userMsg('Please fix the bug');
86
+ const [result] = runFilter([input]);
87
+ expect(result.type).toBe('user');
88
+ expect(result.ts).toBe('2024-01-15T10:00:01Z');
89
+ expect(result.content).toBe('Please fix the bug');
90
+ });
91
+ it('truncates user tool_result content at 500 chars with ...[truncated]', () => {
92
+ const longContent = 'z'.repeat(600);
93
+ const input = userMsg([
94
+ {
95
+ type: 'tool_result',
96
+ tool_use_id: 'tool_123',
97
+ is_error: false,
98
+ content: longContent,
99
+ },
100
+ ]);
101
+ const [result] = runFilter([input]);
102
+ const item = result.content[0];
103
+ expect(item.t).toBe('result');
104
+ expect(item.id).toBe('tool_123');
105
+ expect(item.err).toBe(false);
106
+ expect(item.content).toHaveLength(500 + '...[truncated]'.length);
107
+ expect(item.content.endsWith('...[truncated]')).toBe(true);
108
+ });
109
+ it('does not truncate tool_result content under 500 chars', () => {
110
+ const input = userMsg([
111
+ {
112
+ type: 'tool_result',
113
+ tool_use_id: 'tool_456',
114
+ content: 'short result',
115
+ },
116
+ ]);
117
+ const [result] = runFilter([input]);
118
+ expect(result.content[0].content).toBe('short result');
119
+ });
120
+ it('wraps non-tool-result array items as msg with truncation at 500', () => {
121
+ const longText = 'w'.repeat(600);
122
+ const input = userMsg([{ type: 'text', text: longText }]);
123
+ const [result] = runFilter([input]);
124
+ const item = result.content[0];
125
+ expect(item.t).toBe('msg');
126
+ expect(item.text).toHaveLength(500 + '...[truncated]'.length);
127
+ expect(item.text.endsWith('...[truncated]')).toBe(true);
128
+ });
129
+ it('filters out non-user/non-assistant types', () => {
130
+ const lines = [
131
+ { type: 'system', timestamp: '2024-01-15T10:00:00Z', message: {} },
132
+ { type: 'progress', timestamp: '2024-01-15T10:00:00Z', data: {} },
133
+ userMsg('keep me'),
134
+ ];
135
+ const results = runFilter(lines);
136
+ expect(results).toHaveLength(1);
137
+ expect(results[0].content).toBe('keep me');
138
+ });
139
+ it('silently skips malformed JSON lines', () => {
140
+ const tmp = path.join(os.tmpdir(), `filter-malformed-${Date.now()}.jsonl`);
141
+ try {
142
+ const lines = [
143
+ JSON.stringify(userMsg('before')),
144
+ 'not valid json {{{',
145
+ JSON.stringify(userMsg('after')),
146
+ ].join('\n');
147
+ fs.writeFileSync(tmp, lines);
148
+ const stdout = execFileSync('node', [FILTER_SCRIPT, tmp], {
149
+ encoding: 'utf-8',
150
+ });
151
+ const results = stdout
152
+ .trim()
153
+ .split('\n')
154
+ .filter(Boolean)
155
+ .map((l) => JSON.parse(l));
156
+ expect(results).toHaveLength(2);
157
+ expect(results[0].content).toBe('before');
158
+ expect(results[1].content).toBe('after');
159
+ }
160
+ finally {
161
+ fs.unlinkSync(tmp);
162
+ }
163
+ });
164
+ it('handles multiple content types in a single assistant message', () => {
165
+ const input = assistantMsg([
166
+ { type: 'text', text: 'Let me think...' },
167
+ { type: 'thinking', thinking: 'analyzing the problem' },
168
+ { type: 'tool_use', name: 'grep', input: { pattern: 'foo' } },
169
+ ]);
170
+ const [result] = runFilter([input]);
171
+ expect(result.content).toHaveLength(3);
172
+ expect(result.content[0].t).toBe('text');
173
+ expect(result.content[1].t).toBe('think');
174
+ expect(result.content[2].t).toBe('tool');
175
+ });
176
+ it('defaults is_error to false when not present in tool_result', () => {
177
+ const input = userMsg([
178
+ { type: 'tool_result', tool_use_id: 'tool_789', content: 'ok' },
179
+ ]);
180
+ const [result] = runFilter([input]);
181
+ expect(result.content[0].err).toBe(false);
182
+ });
183
+ it('preserves is_error=true on tool_result', () => {
184
+ const input = userMsg([
185
+ {
186
+ type: 'tool_result',
187
+ tool_use_id: 'tool_err',
188
+ is_error: true,
189
+ content: 'command failed',
190
+ },
191
+ ]);
192
+ const [result] = runFilter([input]);
193
+ expect(result.content[0].err).toBe(true);
194
+ });
195
+ });
196
+ //# sourceMappingURL=filter-session.test.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"filter-session.test.js","sourceRoot":"","sources":["../../../../../src/__tests__/memory-scripts/filter-session.test.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,114 @@
1
+ import { execFileSync } from 'child_process';
2
+ import * as fs from 'fs';
3
+ import * as os from 'os';
4
+ import * as path from 'path';
5
+ const SCRIPTS_DIR = path.resolve(__dirname, '../../../templates/skills/codeyam-memory/scripts');
6
+ const READ_SCRIPT = path.join(SCRIPTS_DIR, 'lib/read-json-field.mjs');
7
+ let tmpFile;
8
+ const testData = {
9
+ name: 'test-project',
10
+ version: '1.0.0',
11
+ stats: {
12
+ total_exports: 42,
13
+ total_files: 7,
14
+ },
15
+ dependencies: ['react', 'typescript', 'jest'],
16
+ explicit_markers: [
17
+ { file: 'a.ts', line: 10 },
18
+ { file: 'b.ts', line: 20 },
19
+ ],
20
+ nested: {
21
+ deep: {
22
+ value: 'found-it',
23
+ },
24
+ },
25
+ };
26
+ beforeAll(() => {
27
+ tmpFile = path.join(os.tmpdir(), `read-json-test-${Date.now()}.json`);
28
+ fs.writeFileSync(tmpFile, JSON.stringify(testData));
29
+ });
30
+ afterAll(() => {
31
+ fs.unlinkSync(tmpFile);
32
+ });
33
+ function readField(expr) {
34
+ return execFileSync('node', [READ_SCRIPT, tmpFile, expr], {
35
+ encoding: 'utf-8',
36
+ }).trim();
37
+ }
38
+ describe('read-json-field.mjs', () => {
39
+ describe('simple field access', () => {
40
+ it('reads a top-level string field', () => {
41
+ expect(readField('.name')).toBe('test-project');
42
+ });
43
+ it('reads a top-level number field', () => {
44
+ expect(readField('.version')).toBe('1.0.0');
45
+ });
46
+ it('reads a nested field with dot path', () => {
47
+ expect(readField('.stats.total_exports')).toBe('42');
48
+ });
49
+ it('reads deeply nested fields', () => {
50
+ expect(readField('.nested.deep.value')).toBe('found-it');
51
+ });
52
+ });
53
+ describe('pipe expressions', () => {
54
+ it('gets length of an array', () => {
55
+ expect(readField('.dependencies | length')).toBe('3');
56
+ });
57
+ it('gets length of an object', () => {
58
+ expect(readField('.stats | length')).toBe('2');
59
+ });
60
+ it('gets length of a nested array', () => {
61
+ expect(readField('.explicit_markers | length')).toBe('2');
62
+ });
63
+ });
64
+ describe('the 4 SKILL.md expressions', () => {
65
+ // These are the exact expressions used in SKILL.md Step 2
66
+ it('.dependencies | length', () => {
67
+ expect(readField('.dependencies | length')).toBe('3');
68
+ });
69
+ it('.explicit_markers | length', () => {
70
+ expect(readField('.explicit_markers | length')).toBe('2');
71
+ });
72
+ it('.stats.total_exports', () => {
73
+ expect(readField('.stats.total_exports')).toBe('42');
74
+ });
75
+ it('.stats.total_files', () => {
76
+ expect(readField('.stats.total_files')).toBe('7');
77
+ });
78
+ });
79
+ describe('error handling', () => {
80
+ it('exits non-zero for missing field', () => {
81
+ expect(() => execFileSync('node', [READ_SCRIPT, tmpFile, '.nonexistent.deep'], {
82
+ encoding: 'utf-8',
83
+ stdio: ['pipe', 'pipe', 'pipe'],
84
+ })).toThrow();
85
+ });
86
+ it('exits non-zero for missing file', () => {
87
+ expect(() => execFileSync('node', [READ_SCRIPT, '/tmp/does-not-exist.json', '.foo'], { encoding: 'utf-8', stdio: ['pipe', 'pipe', 'pipe'] })).toThrow();
88
+ });
89
+ it('exits non-zero with no arguments', () => {
90
+ expect(() => execFileSync('node', [READ_SCRIPT], {
91
+ encoding: 'utf-8',
92
+ stdio: ['pipe', 'pipe', 'pipe'],
93
+ })).toThrow();
94
+ });
95
+ });
96
+ describe('output format', () => {
97
+ it('prints strings without JSON quotes', () => {
98
+ // jq prints strings without quotes by default; we match that
99
+ const result = readField('.name');
100
+ expect(result.startsWith('"')).toBe(false);
101
+ expect(result.endsWith('"')).toBe(false);
102
+ });
103
+ it('prints numbers as plain values', () => {
104
+ const result = readField('.stats.total_exports');
105
+ expect(result).toBe('42');
106
+ expect(Number(result)).toBe(42);
107
+ });
108
+ it('prints arrays as JSON', () => {
109
+ const result = readField('.dependencies');
110
+ expect(JSON.parse(result)).toEqual(['react', 'typescript', 'jest']);
111
+ });
112
+ });
113
+ });
114
+ //# sourceMappingURL=read-json-field.test.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"read-json-field.test.js","sourceRoot":"","sources":["../../../../../src/__tests__/memory-scripts/read-json-field.test.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,149 @@
1
+ import { execFileSync } from 'child_process';
2
+ import * as fs from 'fs';
3
+ import * as os from 'os';
4
+ import * as path from 'path';
5
+ const SCRIPTS_DIR = path.resolve(__dirname, '../../../templates/skills/codeyam-memory/scripts');
6
+ const RG_FALLBACK = path.resolve(SCRIPTS_DIR, 'lib/ripgrep-fallback.mjs');
7
+ let tmpDir;
8
+ let harnessPath;
9
+ beforeAll(() => {
10
+ tmpDir = fs.mkdtempSync(path.join(os.tmpdir(), 'rg-fallback-test-'));
11
+ // Create test source files
12
+ const srcDir = path.join(tmpDir, 'src');
13
+ fs.mkdirSync(srcDir);
14
+ fs.writeFileSync(path.join(srcDir, 'hello.ts'), [
15
+ 'export function greet(name: string) {',
16
+ ' return `Hello, ${name}!`;',
17
+ '}',
18
+ '',
19
+ 'export const DEFAULT_NAME = "World";',
20
+ ].join('\n'));
21
+ fs.writeFileSync(path.join(srcDir, 'math.ts'), [
22
+ 'export function add(a: number, b: number) {',
23
+ ' return a + b;',
24
+ '}',
25
+ ].join('\n'));
26
+ // A file in node_modules that should be excluded
27
+ const nmDir = path.join(tmpDir, 'node_modules', 'some-pkg');
28
+ fs.mkdirSync(nmDir, { recursive: true });
29
+ fs.writeFileSync(path.join(nmDir, 'index.ts'), 'export function shouldNotMatch() {}');
30
+ // Harness that calls _nodeFallback directly (the pure-Node path)
31
+ harnessPath = path.join(tmpDir, 'harness.mjs');
32
+ fs.writeFileSync(harnessPath, `const { _nodeFallback } = await import(${JSON.stringify(RG_FALLBACK)});
33
+ const result = await _nodeFallback(process.argv[2], JSON.parse(process.argv[3]));
34
+ process.stdout.write(result);
35
+ `);
36
+ });
37
+ afterAll(() => {
38
+ fs.rmSync(tmpDir, { recursive: true, force: true });
39
+ });
40
+ function runFallback(pattern, opts) {
41
+ return execFileSync('node', [harnessPath, pattern, JSON.stringify({ cwd: tmpDir, ...opts })], { encoding: 'utf-8', timeout: 10000 });
42
+ }
43
+ describe('ripgrep-fallback.mjs — Node fallback path', () => {
44
+ it('finds matching lines with file:line:text format', () => {
45
+ const result = runFallback('^export', { types: ['ts'] });
46
+ const lines = result.trim().split('\n').filter(Boolean);
47
+ expect(lines.length).toBeGreaterThanOrEqual(3);
48
+ for (const line of lines) {
49
+ expect(line).toMatch(/^[^:]+:\d+:.+$/);
50
+ }
51
+ });
52
+ it('filters by file type', () => {
53
+ const result = runFallback('^export', { types: ['ts'] });
54
+ const files = result
55
+ .trim()
56
+ .split('\n')
57
+ .filter(Boolean)
58
+ .map((l) => l.split(':')[0]);
59
+ for (const f of files) {
60
+ expect(f).toMatch(/\.ts$/);
61
+ }
62
+ });
63
+ it('respects glob ignore patterns', () => {
64
+ const result = runFallback('export function', {
65
+ types: ['ts'],
66
+ globs: ['!node_modules'],
67
+ });
68
+ const files = result
69
+ .trim()
70
+ .split('\n')
71
+ .filter(Boolean)
72
+ .map((l) => l.split(':')[0]);
73
+ for (const f of files) {
74
+ expect(f).not.toContain('node_modules');
75
+ }
76
+ });
77
+ it('returns empty string for no matches', () => {
78
+ const result = runFallback('xyzzy_no_match_12345', { types: ['ts'] });
79
+ expect(result).toBe('');
80
+ });
81
+ it('includes correct line numbers', () => {
82
+ const result = runFallback('DEFAULT_NAME', {
83
+ types: ['ts'],
84
+ lineNumbers: true,
85
+ });
86
+ const lines = result.trim().split('\n').filter(Boolean);
87
+ expect(lines).toHaveLength(1);
88
+ // Line 5 of hello.ts: export const DEFAULT_NAME = "World";
89
+ expect(lines[0]).toMatch(/hello\.ts:5:/);
90
+ });
91
+ it('excludes files matching negative glob extensions', () => {
92
+ // Add a .d.ts file that should be excluded
93
+ fs.writeFileSync(path.join(tmpDir, 'src', 'types.d.ts'), 'export type Foo = string;');
94
+ const result = runFallback('^export', {
95
+ types: ['ts'],
96
+ globs: ['!*.d.ts'],
97
+ });
98
+ const files = result
99
+ .trim()
100
+ .split('\n')
101
+ .filter(Boolean)
102
+ .map((l) => l.split(':')[0]);
103
+ for (const f of files) {
104
+ expect(f).not.toMatch(/\.d\.ts$/);
105
+ }
106
+ });
107
+ });
108
+ // Test the full ripgrepSearch (rg path) if rg is installed
109
+ const rgAvailable = (() => {
110
+ try {
111
+ execFileSync('rg', ['--version'], { encoding: 'utf-8' });
112
+ return true;
113
+ }
114
+ catch {
115
+ return false;
116
+ }
117
+ })();
118
+ (rgAvailable ? describe : describe.skip)('ripgrep-fallback.mjs — rg path (rg installed)', () => {
119
+ let rgHarness;
120
+ beforeAll(() => {
121
+ rgHarness = path.join(tmpDir, 'harness-rg.mjs');
122
+ fs.writeFileSync(rgHarness, `const { ripgrepSearch } = await import(${JSON.stringify(RG_FALLBACK)});
123
+ const result = await ripgrepSearch(process.argv[2], JSON.parse(process.argv[3]));
124
+ process.stdout.write(result);
125
+ `);
126
+ });
127
+ function runRg(pattern, opts) {
128
+ return execFileSync('node', [rgHarness, pattern, JSON.stringify({ cwd: tmpDir, ...opts })], { encoding: 'utf-8', timeout: 10000 });
129
+ }
130
+ it('finds matching lines', () => {
131
+ const result = runRg('^export', { types: ['ts'] });
132
+ const lines = result.trim().split('\n').filter(Boolean);
133
+ expect(lines.length).toBeGreaterThanOrEqual(3);
134
+ });
135
+ it('returns empty string for no matches', () => {
136
+ const result = runRg('xyzzy_no_match_12345', { types: ['ts'] });
137
+ expect(result).toBe('');
138
+ });
139
+ it('completes without hanging (regression: rg must not read stdin)', () => {
140
+ // Without explicit '.' path arg, rg reads stdin and hangs under execFile.
141
+ const result = runRg('DEFAULT_NAME', {
142
+ types: ['ts'],
143
+ lineNumbers: true,
144
+ });
145
+ const lines = result.trim().split('\n').filter(Boolean);
146
+ expect(lines).toHaveLength(1);
147
+ });
148
+ });
149
+ //# sourceMappingURL=ripgrep-fallback.test.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"ripgrep-fallback.test.js","sourceRoot":"","sources":["../../../../../src/__tests__/memory-scripts/ripgrep-fallback.test.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,YAAY,EAAE,MAAM,eAAe,CAAC;AAC7C,OAAO,KAAK,EAAE,MAAM,IAAI,CAAC;AACzB,OAAO,KAAK,EAAE,MAAM,IAAI,CAAC;AACzB,OAAO,KAAK,IAAI,MAAM,MAAM,CAAC;AAE7B,MAAM,WAAW,GAAG,IAAI,CAAC,OAAO,CAC9B,SAAS,EACT,kDAAkD,CACnD,CAAC;AACF,MAAM,WAAW,GAAG,IAAI,CAAC,OAAO,CAAC,WAAW,EAAE,0BAA0B,CAAC,CAAC;AAE1E,IAAI,MAAc,CAAC;AACnB,IAAI,WAAmB,CAAC;AAExB,SAAS,CAAC,GAAG,EAAE;IACb,MAAM,GAAG,EAAE,CAAC,WAAW,CAAC,IAAI,CAAC,IAAI,CAAC,EAAE,CAAC,MAAM,EAAE,EAAE,mBAAmB,CAAC,CAAC,CAAC;IAErE,2BAA2B;IAC3B,MAAM,MAAM,GAAG,IAAI,CAAC,IAAI,CAAC,MAAM,EAAE,KAAK,CAAC,CAAC;IACxC,EAAE,CAAC,SAAS,CAAC,MAAM,CAAC,CAAC;IACrB,EAAE,CAAC,aAAa,CACd,IAAI,CAAC,IAAI,CAAC,MAAM,EAAE,UAAU,CAAC,EAC7B;QACE,uCAAuC;QACvC,6BAA6B;QAC7B,GAAG;QACH,EAAE;QACF,sCAAsC;KACvC,CAAC,IAAI,CAAC,IAAI,CAAC,CACb,CAAC;IACF,EAAE,CAAC,aAAa,CACd,IAAI,CAAC,IAAI,CAAC,MAAM,EAAE,SAAS,CAAC,EAC5B;QACE,6CAA6C;QAC7C,iBAAiB;QACjB,GAAG;KACJ,CAAC,IAAI,CAAC,IAAI,CAAC,CACb,CAAC;IAEF,iDAAiD;IACjD,MAAM,KAAK,GAAG,IAAI,CAAC,IAAI,CAAC,MAAM,EAAE,cAAc,EAAE,UAAU,CAAC,CAAC;IAC5D,EAAE,CAAC,SAAS,CAAC,KAAK,EAAE,EAAE,SAAS,EAAE,IAAI,EAAE,CAAC,CAAC;IACzC,EAAE,CAAC,aAAa,CACd,IAAI,CAAC,IAAI,CAAC,KAAK,EAAE,UAAU,CAAC,EAC5B,qCAAqC,CACtC,CAAC;IAEF,iEAAiE;IACjE,WAAW,GAAG,IAAI,CAAC,IAAI,CAAC,MAAM,EAAE,aAAa,CAAC,CAAC;IAC/C,EAAE,CAAC,aAAa,CACd,WAAW,EACX,0CAA0C,IAAI,CAAC,SAAS,CAAC,WAAW,CAAC;;;CAGxE,CACE,CAAC;AACJ,CAAC,CAAC,CAAC;AAEH,QAAQ,CAAC,GAAG,EAAE;IACZ,EAAE,CAAC,MAAM,CAAC,MAAM,EAAE,EAAE,SAAS,EAAE,IAAI,EAAE,KAAK,EAAE,IAAI,EAAE,CAAC,CAAC;AACtD,CAAC,CAAC,CAAC;AAEH,SAAS,WAAW,CAAC,OAAe,EAAE,IAA6B;IACjE,OAAO,YAAY,CACjB,MAAM,EACN,CAAC,WAAW,EAAE,OAAO,EAAE,IAAI,CAAC,SAAS,CAAC,EAAE,GAAG,EAAE,MAAM,EAAE,GAAG,IAAI,EAAE,CAAC,CAAC,EAChE,EAAE,QAAQ,EAAE,OAAO,EAAE,OAAO,EAAE,KAAM,EAAE,CACvC,CAAC;AACJ,CAAC;AAED,QAAQ,CAAC,2CAA2C,EAAE,GAAG,EAAE;IACzD,EAAE,CAAC,iDAAiD,EAAE,GAAG,EAAE;QACzD,MAAM,MAAM,GAAG,WAAW,CAAC,SAAS,EAAE,EAAE,KAAK,EAAE,CAAC,IAAI,CAAC,EAAE,CAAC,CAAC;QACzD,MAAM,KAAK,GAAG,MAAM,CAAC,IAAI,EAAE,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC,MAAM,CAAC,OAAO,CAAC,CAAC;QAExD,MAAM,CAAC,KAAK,CAAC,MAAM,CAAC,CAAC,sBAAsB,CAAC,CAAC,CAAC,CAAC;QAC/C,KAAK,MAAM,IAAI,IAAI,KAAK,EAAE,CAAC;YACzB,MAAM,CAAC,IAAI,CAAC,CAAC,OAAO,CAAC,gBAAgB,CAAC,CAAC;QACzC,CAAC;IACH,CAAC,CAAC,CAAC;IAEH,EAAE,CAAC,sBAAsB,EAAE,GAAG,EAAE;QAC9B,MAAM,MAAM,GAAG,WAAW,CAAC,SAAS,EAAE,EAAE,KAAK,EAAE,CAAC,IAAI,CAAC,EAAE,CAAC,CAAC;QACzD,MAAM,KAAK,GAAG,MAAM;aACjB,IAAI,EAAE;aACN,KAAK,CAAC,IAAI,CAAC;aACX,MAAM,CAAC,OAAO,CAAC;aACf,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC;QAE/B,KAAK,MAAM,CAAC,IAAI,KAAK,EAAE,CAAC;YACtB,MAAM,CAAC,CAAC,CAAC,CAAC,OAAO,CAAC,OAAO,CAAC,CAAC;QAC7B,CAAC;IACH,CAAC,CAAC,CAAC;IAEH,EAAE,CAAC,+BAA+B,EAAE,GAAG,EAAE;QACvC,MAAM,MAAM,GAAG,WAAW,CAAC,iBAAiB,EAAE;YAC5C,KAAK,EAAE,CAAC,IAAI,CAAC;YACb,KAAK,EAAE,CAAC,eAAe,CAAC;SACzB,CAAC,CAAC;QACH,MAAM,KAAK,GAAG,MAAM;aACjB,IAAI,EAAE;aACN,KAAK,CAAC,IAAI,CAAC;aACX,MAAM,CAAC,OAAO,CAAC;aACf,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC;QAE/B,KAAK,MAAM,CAAC,IAAI,KAAK,EAAE,CAAC;YACtB,MAAM,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,SAAS,CAAC,cAAc,CAAC,CAAC;QAC1C,CAAC;IACH,CAAC,CAAC,CAAC;IAEH,EAAE,CAAC,qCAAqC,EAAE,GAAG,EAAE;QAC7C,MAAM,MAAM,GAAG,WAAW,CAAC,sBAAsB,EAAE,EAAE,KAAK,EAAE,CAAC,IAAI,CAAC,EAAE,CAAC,CAAC;QACtE,MAAM,CAAC,MAAM,CAAC,CAAC,IAAI,CAAC,EAAE,CAAC,CAAC;IAC1B,CAAC,CAAC,CAAC;IAEH,EAAE,CAAC,+BAA+B,EAAE,GAAG,EAAE;QACvC,MAAM,MAAM,GAAG,WAAW,CAAC,cAAc,EAAE;YACzC,KAAK,EAAE,CAAC,IAAI,CAAC;YACb,WAAW,EAAE,IAAI;SAClB,CAAC,CAAC;QACH,MAAM,KAAK,GAAG,MAAM,CAAC,IAAI,EAAE,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC,MAAM,CAAC,OAAO,CAAC,CAAC;QACxD,MAAM,CAAC,KAAK,CAAC,CAAC,YAAY,CAAC,CAAC,CAAC,CAAC;QAC9B,2DAA2D;QAC3D,MAAM,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,CAAC,OAAO,CAAC,cAAc,CAAC,CAAC;IAC3C,CAAC,CAAC,CAAC;IAEH,EAAE,CAAC,kDAAkD,EAAE,GAAG,EAAE;QAC1D,2CAA2C;QAC3C,EAAE,CAAC,aAAa,CACd,IAAI,CAAC,IAAI,CAAC,MAAM,EAAE,KAAK,EAAE,YAAY,CAAC,EACtC,2BAA2B,CAC5B,CAAC;QAEF,MAAM,MAAM,GAAG,WAAW,CAAC,SAAS,EAAE;YACpC,KAAK,EAAE,CAAC,IAAI,CAAC;YACb,KAAK,EAAE,CAAC,SAAS,CAAC;SACnB,CAAC,CAAC;QACH,MAAM,KAAK,GAAG,MAAM;aACjB,IAAI,EAAE;aACN,KAAK,CAAC,IAAI,CAAC;aACX,MAAM,CAAC,OAAO,CAAC;aACf,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC;QAE/B,KAAK,MAAM,CAAC,IAAI,KAAK,EAAE,CAAC;YACtB,MAAM,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,OAAO,CAAC,UAAU,CAAC,CAAC;QACpC,CAAC;IACH,CAAC,CAAC,CAAC;AACL,CAAC,CAAC,CAAC;AAEH,2DAA2D;AAC3D,MAAM,WAAW,GAAG,CAAC,GAAG,EAAE;IACxB,IAAI,CAAC;QACH,YAAY,CAAC,IAAI,EAAE,CAAC,WAAW,CAAC,EAAE,EAAE,QAAQ,EAAE,OAAO,EAAE,CAAC,CAAC;QACzD,OAAO,IAAI,CAAC;IACd,CAAC;IAAC,MAAM,CAAC;QACP,OAAO,KAAK,CAAC;IACf,CAAC;AACH,CAAC,CAAC,EAAE,CAAC;AAEL,CAAC,WAAW,CAAC,CAAC,CAAC,QAAQ,CAAC,CAAC,CAAC,QAAQ,CAAC,IAAI,CAAC,CACtC,+CAA+C,EAC/C,GAAG,EAAE;IACH,IAAI,SAAiB,CAAC;IAEtB,SAAS,CAAC,GAAG,EAAE;QACb,SAAS,GAAG,IAAI,CAAC,IAAI,CAAC,MAAM,EAAE,gBAAgB,CAAC,CAAC;QAChD,EAAE,CAAC,aAAa,CACd,SAAS,EACT,0CAA0C,IAAI,CAAC,SAAS,CAAC,WAAW,CAAC;;;CAG5E,CACM,CAAC;IACJ,CAAC,CAAC,CAAC;IAEH,SAAS,KAAK,CAAC,OAAe,EAAE,IAA6B;QAC3D,OAAO,YAAY,CACjB,MAAM,EACN,CAAC,SAAS,EAAE,OAAO,EAAE,IAAI,CAAC,SAAS,CAAC,EAAE,GAAG,EAAE,MAAM,EAAE,GAAG,IAAI,EAAE,CAAC,CAAC,EAC9D,EAAE,QAAQ,EAAE,OAAO,EAAE,OAAO,EAAE,KAAM,EAAE,CACvC,CAAC;IACJ,CAAC;IAED,EAAE,CAAC,sBAAsB,EAAE,GAAG,EAAE;QAC9B,MAAM,MAAM,GAAG,KAAK,CAAC,SAAS,EAAE,EAAE,KAAK,EAAE,CAAC,IAAI,CAAC,EAAE,CAAC,CAAC;QACnD,MAAM,KAAK,GAAG,MAAM,CAAC,IAAI,EAAE,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC,MAAM,CAAC,OAAO,CAAC,CAAC;QACxD,MAAM,CAAC,KAAK,CAAC,MAAM,CAAC,CAAC,sBAAsB,CAAC,CAAC,CAAC,CAAC;IACjD,CAAC,CAAC,CAAC;IAEH,EAAE,CAAC,qCAAqC,EAAE,GAAG,EAAE;QAC7C,MAAM,MAAM,GAAG,KAAK,CAAC,sBAAsB,EAAE,EAAE,KAAK,EAAE,CAAC,IAAI,CAAC,EAAE,CAAC,CAAC;QAChE,MAAM,CAAC,MAAM,CAAC,CAAC,IAAI,CAAC,EAAE,CAAC,CAAC;IAC1B,CAAC,CAAC,CAAC;IAEH,EAAE,CAAC,gEAAgE,EAAE,GAAG,EAAE;QACxE,0EAA0E;QAC1E,MAAM,MAAM,GAAG,KAAK,CAAC,cAAc,EAAE;YACnC,KAAK,EAAE,CAAC,IAAI,CAAC;YACb,WAAW,EAAE,IAAI;SAClB,CAAC,CAAC;QACH,MAAM,KAAK,GAAG,MAAM,CAAC,IAAI,EAAE,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC,MAAM,CAAC,OAAO,CAAC,CAAC;QACxD,MAAM,CAAC,KAAK,CAAC,CAAC,YAAY,CAAC,CAAC,CAAC,CAAC;IAChC,CAAC,CAAC,CAAC;AACL,CAAC,CACF,CAAC"}