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

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 (106) hide show
  1. package/analyzer-template/.build-info.json +6 -6
  2. package/analyzer-template/log.txt +3 -3
  3. package/analyzer-template/package.json +6 -6
  4. package/analyzer-template/packages/ai/package.json +1 -1
  5. package/analyzer-template/packages/aws/package.json +1 -1
  6. package/analyzer-template/packages/database/package.json +3 -3
  7. package/analyzer-template/packages/github/package.json +1 -1
  8. package/codeyam-cli/src/commands/editor.js +892 -90
  9. package/codeyam-cli/src/commands/editor.js.map +1 -1
  10. package/codeyam-cli/src/commands/init.js +6 -1
  11. package/codeyam-cli/src/commands/init.js.map +1 -1
  12. package/codeyam-cli/src/utils/__tests__/editorAudit.test.js +246 -0
  13. package/codeyam-cli/src/utils/__tests__/editorAudit.test.js.map +1 -0
  14. package/codeyam-cli/src/utils/__tests__/editorDevServer.test.js +126 -0
  15. package/codeyam-cli/src/utils/__tests__/editorDevServer.test.js.map +1 -0
  16. package/codeyam-cli/src/utils/__tests__/editorJournal.test.js +295 -0
  17. package/codeyam-cli/src/utils/__tests__/editorJournal.test.js.map +1 -0
  18. package/codeyam-cli/src/utils/__tests__/editorMockState.test.js +270 -0
  19. package/codeyam-cli/src/utils/__tests__/editorMockState.test.js.map +1 -0
  20. package/codeyam-cli/src/utils/__tests__/editorPreloadHelpers.test.js +100 -0
  21. package/codeyam-cli/src/utils/__tests__/editorPreloadHelpers.test.js.map +1 -0
  22. package/codeyam-cli/src/utils/__tests__/editorPreview.test.js +147 -0
  23. package/codeyam-cli/src/utils/__tests__/editorPreview.test.js.map +1 -0
  24. package/codeyam-cli/src/utils/__tests__/editorScenarios.test.js +76 -0
  25. package/codeyam-cli/src/utils/__tests__/editorScenarios.test.js.map +1 -0
  26. package/codeyam-cli/src/utils/__tests__/git.editor.test.js +134 -0
  27. package/codeyam-cli/src/utils/__tests__/git.editor.test.js.map +1 -0
  28. package/codeyam-cli/src/utils/__tests__/project.test.js +65 -0
  29. package/codeyam-cli/src/utils/__tests__/project.test.js.map +1 -0
  30. package/codeyam-cli/src/utils/__tests__/scenarioMarkers.test.js +121 -0
  31. package/codeyam-cli/src/utils/__tests__/scenarioMarkers.test.js.map +1 -0
  32. package/codeyam-cli/src/utils/buildFlags.js +4 -0
  33. package/codeyam-cli/src/utils/buildFlags.js.map +1 -0
  34. package/codeyam-cli/src/utils/editorAudit.js +82 -0
  35. package/codeyam-cli/src/utils/editorAudit.js.map +1 -0
  36. package/codeyam-cli/src/utils/editorDevServer.js +98 -0
  37. package/codeyam-cli/src/utils/editorDevServer.js.map +1 -0
  38. package/codeyam-cli/src/utils/editorJournal.js +137 -0
  39. package/codeyam-cli/src/utils/editorJournal.js.map +1 -0
  40. package/codeyam-cli/src/utils/editorMockState.js +248 -0
  41. package/codeyam-cli/src/utils/editorMockState.js.map +1 -0
  42. package/codeyam-cli/src/utils/editorPreloadHelpers.js +64 -0
  43. package/codeyam-cli/src/utils/editorPreloadHelpers.js.map +1 -0
  44. package/codeyam-cli/src/utils/editorPreview.js +66 -0
  45. package/codeyam-cli/src/utils/editorPreview.js.map +1 -0
  46. package/codeyam-cli/src/utils/editorScenarios.js +56 -0
  47. package/codeyam-cli/src/utils/editorScenarios.js.map +1 -0
  48. package/codeyam-cli/src/utils/git.js +51 -0
  49. package/codeyam-cli/src/utils/git.js.map +1 -1
  50. package/codeyam-cli/src/utils/install-skills.js +28 -17
  51. package/codeyam-cli/src/utils/install-skills.js.map +1 -1
  52. package/codeyam-cli/src/utils/project.js +15 -5
  53. package/codeyam-cli/src/utils/project.js.map +1 -1
  54. package/codeyam-cli/src/utils/scenarioMarkers.js +134 -0
  55. package/codeyam-cli/src/utils/scenarioMarkers.js.map +1 -0
  56. package/codeyam-cli/src/utils/testRunner.js +1 -1
  57. package/codeyam-cli/src/utils/testRunner.js.map +1 -1
  58. package/codeyam-cli/src/webserver/build/client/assets/Terminal-wkqC0AQk.js +41 -0
  59. package/codeyam-cli/src/webserver/build/client/assets/api.editor-audit-l0sNRNKZ.js +1 -0
  60. package/codeyam-cli/src/webserver/build/client/assets/api.editor-load-commit-l0sNRNKZ.js +1 -0
  61. package/codeyam-cli/src/webserver/build/client/assets/editor-CdjF_fX6.js +8 -0
  62. package/codeyam-cli/src/webserver/build/client/assets/entity._sha.scenarios._scenarioId.dev-D8ILZMR0.js +6 -0
  63. package/codeyam-cli/src/webserver/build/client/assets/globals-B17TBSS6.css +1 -0
  64. package/codeyam-cli/src/webserver/build/client/assets/manifest-b8fd6b07.js +1 -0
  65. package/codeyam-cli/src/webserver/build/client/assets/{root-DiRdBreB.js → root-DUKqhFlb.js} +7 -7
  66. package/codeyam-cli/src/webserver/build/client/assets/xterm-BqvuqXEL.js +27 -0
  67. package/codeyam-cli/src/webserver/build/server/assets/{index-BzAbACSx.js → index-BLhjL9Xi.js} +1 -1
  68. package/codeyam-cli/src/webserver/build/server/assets/server-build-DyMuI5mU.js +363 -0
  69. package/codeyam-cli/src/webserver/build/server/index.js +1 -1
  70. package/codeyam-cli/src/webserver/build-info.json +5 -5
  71. package/codeyam-cli/src/webserver/editorProxy.js +182 -14
  72. package/codeyam-cli/src/webserver/editorProxy.js.map +1 -1
  73. package/codeyam-cli/src/webserver/scripts/codeyam-preload.mjs +175 -0
  74. package/codeyam-cli/src/webserver/server.js +61 -12
  75. package/codeyam-cli/src/webserver/server.js.map +1 -1
  76. package/codeyam-cli/src/webserver/terminalServer.js +29 -103
  77. package/codeyam-cli/src/webserver/terminalServer.js.map +1 -1
  78. package/codeyam-cli/templates/editor-step-hook.py +6 -4
  79. package/codeyam-cli/templates/{codeyam-dev-mode.md → skills/codeyam-dev-mode/SKILL.md} +1 -1
  80. package/codeyam-cli/templates/{codeyam-editor.md → skills/codeyam-editor/SKILL.md} +5 -4
  81. package/codeyam-cli/templates/{codeyam-memory.md → skills/codeyam-memory/SKILL.md} +215 -0
  82. package/codeyam-cli/templates/skills/codeyam-memory/scripts/holistic-analysis/deprecated-prompt.md +100 -0
  83. package/codeyam-cli/templates/skills/codeyam-memory/scripts/holistic-analysis/detect-deprecated-patterns.sh +108 -0
  84. package/codeyam-cli/templates/skills/codeyam-memory/scripts/holistic-analysis/find-exports.sh +69 -0
  85. package/codeyam-cli/templates/skills/codeyam-memory/scripts/holistic-analysis/misleading-api-prompt.md +117 -0
  86. package/codeyam-cli/templates/skills/codeyam-memory/scripts/session-mining/analyze-prompt.md +46 -0
  87. package/codeyam-cli/templates/skills/codeyam-memory/scripts/session-mining/cleanup.sh +12 -0
  88. package/codeyam-cli/templates/skills/codeyam-memory/scripts/session-mining/filter.jq +45 -0
  89. package/codeyam-cli/templates/skills/codeyam-memory/scripts/session-mining/preprocess.sh +139 -0
  90. package/package.json +2 -2
  91. package/scripts/npm-post-install.cjs +12 -0
  92. package/codeyam-cli/src/webserver/build/client/assets/Terminal-CcG8YTLx.js +0 -41
  93. package/codeyam-cli/src/webserver/build/client/assets/editor-W_IGJ2Kd.js +0 -7
  94. package/codeyam-cli/src/webserver/build/client/assets/entity._sha.scenarios._scenarioId.dev-D6SEzMCu.js +0 -6
  95. package/codeyam-cli/src/webserver/build/client/assets/globals-BZB_H1w2.css +0 -1
  96. package/codeyam-cli/src/webserver/build/client/assets/manifest-8daa4147.js +0 -1
  97. package/codeyam-cli/src/webserver/build/client/assets/xterm-DMSzMhqy.js +0 -9
  98. package/codeyam-cli/src/webserver/build/server/assets/server-build-OdUocH6P.js +0 -362
  99. package/scripts/finalize-analyzer.cjs +0 -13
  100. /package/codeyam-cli/templates/{codeyam-diagnose.md → commands/codeyam-diagnose.md} +0 -0
  101. /package/codeyam-cli/templates/{codeyam-debug.md → skills/codeyam-debug/SKILL.md} +0 -0
  102. /package/codeyam-cli/templates/{codeyam-new-rule.md → skills/codeyam-new-rule/SKILL.md} +0 -0
  103. /package/codeyam-cli/templates/{codeyam-setup.md → skills/codeyam-setup/SKILL.md} +0 -0
  104. /package/codeyam-cli/templates/{codeyam-sim.md → skills/codeyam-sim/SKILL.md} +0 -0
  105. /package/codeyam-cli/templates/{codeyam-test.md → skills/codeyam-test/SKILL.md} +0 -0
  106. /package/codeyam-cli/templates/{codeyam-verify.md → skills/codeyam-verify/SKILL.md} +0 -0
@@ -0,0 +1,134 @@
1
+ import { validateCommitSha, verifyCommitExists, gitStash, gitCheckout, } from "../git.js";
2
+ import { execSync } from 'child_process';
3
+ import * as fs from 'fs';
4
+ import * as path from 'path';
5
+ import * as os from 'os';
6
+ describe('git editor utilities', () => {
7
+ describe('validateCommitSha', () => {
8
+ it('should accept a valid 7-char short SHA', () => {
9
+ expect(validateCommitSha('abc1234')).toBe(true);
10
+ });
11
+ it('should accept a valid 40-char full SHA', () => {
12
+ expect(validateCommitSha('abc1234567890def1234567890abc123456789de')).toBe(true);
13
+ });
14
+ it('should accept uppercase hex chars', () => {
15
+ expect(validateCommitSha('ABC1234DEF')).toBe(true);
16
+ });
17
+ it('should reject too-short SHAs (< 7 chars)', () => {
18
+ expect(validateCommitSha('abc12')).toBe(false);
19
+ });
20
+ it('should reject too-long SHAs (> 40 chars)', () => {
21
+ expect(validateCommitSha('a'.repeat(41))).toBe(false);
22
+ });
23
+ it('should reject non-hex characters', () => {
24
+ expect(validateCommitSha('abcdefg')).toBe(false);
25
+ });
26
+ it('should reject empty string', () => {
27
+ expect(validateCommitSha('')).toBe(false);
28
+ });
29
+ it('should reject command injection attempts', () => {
30
+ expect(validateCommitSha('abc1234; rm -rf /')).toBe(false);
31
+ });
32
+ });
33
+ describe('verifyCommitExists', () => {
34
+ let tempDir;
35
+ beforeEach(() => {
36
+ tempDir = fs.mkdtempSync(path.join(os.tmpdir(), 'git-test-'));
37
+ execSync('git init', { cwd: tempDir, stdio: 'pipe' });
38
+ execSync('git config user.email "test@test.com"', {
39
+ cwd: tempDir,
40
+ stdio: 'pipe',
41
+ });
42
+ execSync('git config user.name "Test"', { cwd: tempDir, stdio: 'pipe' });
43
+ fs.writeFileSync(path.join(tempDir, 'file.txt'), 'hello');
44
+ execSync('git add -A && git commit -m "initial"', {
45
+ cwd: tempDir,
46
+ stdio: 'pipe',
47
+ });
48
+ });
49
+ afterEach(() => {
50
+ fs.rmSync(tempDir, { recursive: true, force: true });
51
+ });
52
+ it('should return true for an existing commit', () => {
53
+ const sha = execSync('git rev-parse HEAD', {
54
+ cwd: tempDir,
55
+ encoding: 'utf8',
56
+ }).trim();
57
+ expect(verifyCommitExists(tempDir, sha)).toBe(true);
58
+ });
59
+ it('should return false for a non-existent commit', () => {
60
+ expect(verifyCommitExists(tempDir, 'deadbeefdeadbeef')).toBe(false);
61
+ });
62
+ });
63
+ describe('gitStash', () => {
64
+ let tempDir;
65
+ beforeEach(() => {
66
+ tempDir = fs.mkdtempSync(path.join(os.tmpdir(), 'git-stash-test-'));
67
+ execSync('git init', { cwd: tempDir, stdio: 'pipe' });
68
+ execSync('git config user.email "test@test.com"', {
69
+ cwd: tempDir,
70
+ stdio: 'pipe',
71
+ });
72
+ execSync('git config user.name "Test"', { cwd: tempDir, stdio: 'pipe' });
73
+ fs.writeFileSync(path.join(tempDir, 'file.txt'), 'hello');
74
+ execSync('git add -A && git commit -m "initial"', {
75
+ cwd: tempDir,
76
+ stdio: 'pipe',
77
+ });
78
+ });
79
+ afterEach(() => {
80
+ fs.rmSync(tempDir, { recursive: true, force: true });
81
+ });
82
+ it('should stash uncommitted changes', () => {
83
+ fs.writeFileSync(path.join(tempDir, 'file.txt'), 'modified');
84
+ const result = gitStash(tempDir, 'test stash');
85
+ expect(result.stashed).toBe(true);
86
+ // File should be restored to committed state
87
+ const content = fs.readFileSync(path.join(tempDir, 'file.txt'), 'utf8');
88
+ expect(content).toBe('hello');
89
+ });
90
+ it('should return stashed=false when nothing to stash', () => {
91
+ const result = gitStash(tempDir, 'test stash');
92
+ expect(result.stashed).toBe(false);
93
+ });
94
+ });
95
+ describe('gitCheckout', () => {
96
+ let tempDir;
97
+ let firstSha;
98
+ beforeEach(() => {
99
+ tempDir = fs.mkdtempSync(path.join(os.tmpdir(), 'git-checkout-test-'));
100
+ execSync('git init', { cwd: tempDir, stdio: 'pipe' });
101
+ execSync('git config user.email "test@test.com"', {
102
+ cwd: tempDir,
103
+ stdio: 'pipe',
104
+ });
105
+ execSync('git config user.name "Test"', { cwd: tempDir, stdio: 'pipe' });
106
+ fs.writeFileSync(path.join(tempDir, 'file.txt'), 'v1');
107
+ execSync('git add -A && git commit -m "first"', {
108
+ cwd: tempDir,
109
+ stdio: 'pipe',
110
+ });
111
+ firstSha = execSync('git rev-parse HEAD', {
112
+ cwd: tempDir,
113
+ encoding: 'utf8',
114
+ }).trim();
115
+ fs.writeFileSync(path.join(tempDir, 'file.txt'), 'v2');
116
+ execSync('git add -A && git commit -m "second"', {
117
+ cwd: tempDir,
118
+ stdio: 'pipe',
119
+ });
120
+ });
121
+ afterEach(() => {
122
+ fs.rmSync(tempDir, { recursive: true, force: true });
123
+ });
124
+ it('should checkout a specific commit', () => {
125
+ gitCheckout(tempDir, firstSha);
126
+ const content = fs.readFileSync(path.join(tempDir, 'file.txt'), 'utf8');
127
+ expect(content).toBe('v1');
128
+ });
129
+ it('should throw on invalid ref', () => {
130
+ expect(() => gitCheckout(tempDir, 'nonexistent_ref')).toThrow();
131
+ });
132
+ });
133
+ });
134
+ //# sourceMappingURL=git.editor.test.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"git.editor.test.js","sourceRoot":"","sources":["../../../../../src/utils/__tests__/git.editor.test.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,65 @@
1
+ import * as fs from 'fs';
2
+ import * as path from 'path';
3
+ import * as os from 'os';
4
+ import { findProjectRoot, isForbiddenProjectRoot } from "../project.js";
5
+ describe('isForbiddenProjectRoot', () => {
6
+ it('returns true for the home directory', () => {
7
+ expect(isForbiddenProjectRoot(os.homedir())).toBe(true);
8
+ });
9
+ it('returns true for the filesystem root', () => {
10
+ expect(isForbiddenProjectRoot('/')).toBe(true);
11
+ });
12
+ it('returns true for home dir with trailing slash', () => {
13
+ expect(isForbiddenProjectRoot(os.homedir() + '/')).toBe(true);
14
+ });
15
+ it('returns false for a normal project directory', () => {
16
+ expect(isForbiddenProjectRoot(path.join(os.homedir(), 'projects', 'my-app'))).toBe(false);
17
+ });
18
+ it('returns false for a directory just inside home', () => {
19
+ expect(isForbiddenProjectRoot(path.join(os.homedir(), 'my-project'))).toBe(false);
20
+ });
21
+ });
22
+ describe('findProjectRoot', () => {
23
+ let tempDir;
24
+ beforeEach(() => {
25
+ tempDir = fs.mkdtempSync(path.join(os.tmpdir(), 'codeyam-test-'));
26
+ });
27
+ afterEach(() => {
28
+ fs.rmSync(tempDir, { recursive: true, force: true });
29
+ });
30
+ it('finds a project in the start directory', () => {
31
+ const codeyamDir = path.join(tempDir, '.codeyam');
32
+ fs.mkdirSync(codeyamDir);
33
+ fs.writeFileSync(path.join(codeyamDir, 'config.json'), JSON.stringify({ projectSlug: 'test' }));
34
+ expect(findProjectRoot(tempDir)).toBe(tempDir);
35
+ });
36
+ it('finds a project in a parent directory', () => {
37
+ const codeyamDir = path.join(tempDir, '.codeyam');
38
+ fs.mkdirSync(codeyamDir);
39
+ fs.writeFileSync(path.join(codeyamDir, 'config.json'), JSON.stringify({ projectSlug: 'test' }));
40
+ const subDir = path.join(tempDir, 'src', 'components');
41
+ fs.mkdirSync(subDir, { recursive: true });
42
+ expect(findProjectRoot(subDir)).toBe(tempDir);
43
+ });
44
+ it('returns null when no project is found', () => {
45
+ const subDir = path.join(tempDir, 'src');
46
+ fs.mkdirSync(subDir, { recursive: true });
47
+ expect(findProjectRoot(subDir)).toBeNull();
48
+ });
49
+ it('does not return the home directory as a project root', () => {
50
+ // Even if ~/.codeyam/config.json exists, findProjectRoot should skip it.
51
+ // We can't create files in the real home dir in a test, but we can verify
52
+ // the guard logic by checking that findProjectRoot stops at home.
53
+ // Start from a subdirectory of home with no .codeyam anywhere —
54
+ // it should return null without ever checking ~.
55
+ const subDir = path.join(os.homedir(), 'nonexistent-codeyam-test-dir');
56
+ // Don't create it — findProjectRoot uses existsSync on config.json, not the dir
57
+ expect(findProjectRoot(subDir)).toBeNull();
58
+ });
59
+ it('does not return the filesystem root as a project root', () => {
60
+ // Starting from /tmp/something with no .codeyam, should return null
61
+ // (and not check / for .codeyam/config.json)
62
+ expect(findProjectRoot(tempDir)).toBeNull();
63
+ });
64
+ });
65
+ //# sourceMappingURL=project.test.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"project.test.js","sourceRoot":"","sources":["../../../../../src/utils/__tests__/project.test.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,121 @@
1
+ import { transformScenarioMarkers, createMarkerTransformer, } from "../scenarioMarkers.js";
2
+ const PORT = '3111';
3
+ describe('scenarioMarkers', () => {
4
+ describe('transformScenarioMarkers', () => {
5
+ it('should transform a simple marker into an OSC 8 hyperlink', () => {
6
+ const input = '{{scenario:Default:abc-123}}';
7
+ const result = transformScenarioMarkers(input, PORT);
8
+ expect(result).toContain('\x1b]8;;');
9
+ expect(result).toContain('http://localhost:3111/editor?scenario=abc-123&ref=link');
10
+ expect(result).toContain('Default');
11
+ expect(result).not.toContain('{{scenario:');
12
+ });
13
+ it('should transform a marker with spaces in the name', () => {
14
+ const input = '{{scenario:Long Name:abc-123}}';
15
+ const result = transformScenarioMarkers(input, PORT);
16
+ expect(result).toContain('Long Name');
17
+ expect(result).not.toContain('{{scenario:');
18
+ });
19
+ it('should transform multiple markers in one string', () => {
20
+ const input = '| DrinkCard | {{scenario:Default:id1}} |\n| | {{scenario:Dark Mode:id2}} |';
21
+ const result = transformScenarioMarkers(input, PORT);
22
+ expect(result).not.toContain('{{scenario:');
23
+ expect(result).toContain('Default');
24
+ expect(result).toContain('Dark Mode');
25
+ });
26
+ it('should return input unchanged when no markers present', () => {
27
+ const input = 'Hello world, no markers here';
28
+ expect(transformScenarioMarkers(input, PORT)).toBe(input);
29
+ });
30
+ it('should handle markers with ANSI escape codes interleaved', () => {
31
+ // Claude Code's renderer inserts ANSI styling within marker text
32
+ const input = '\x1b[33m{{scenario:\x1b[1mDefault\x1b[22m:\x1b[0mabc-123\x1b[33m}}\x1b[0m';
33
+ const result = transformScenarioMarkers(input, PORT);
34
+ expect(result).toContain('Default');
35
+ expect(result).not.toContain('{{scenario:');
36
+ });
37
+ it('should pad the replacement to maintain table alignment', () => {
38
+ const input = '{{scenario:Tea:abc-123}}';
39
+ const result = transformScenarioMarkers(input, PORT);
40
+ // The original marker is 24 chars visible, "Tea" is 3 chars → 21 spaces of padding
41
+ const linkEnd = '\x1b]8;;\x07';
42
+ const afterLink = result.slice(result.lastIndexOf(linkEnd) + linkEnd.length);
43
+ // Should have padding spaces
44
+ expect(afterLink.length).toBeGreaterThan(0);
45
+ });
46
+ });
47
+ describe('createMarkerTransformer (cross-chunk buffering)', () => {
48
+ it('should handle a marker split across two chunks', () => {
49
+ const transform = createMarkerTransformer(PORT);
50
+ const out1 = transform('before {{scenario:Def');
51
+ const out2 = transform('ault:abc-123}} after');
52
+ const combined = out1 + out2;
53
+ expect(combined).toContain('Default');
54
+ expect(combined).not.toContain('{{scenario:');
55
+ expect(combined).toContain('before');
56
+ expect(combined).toContain('after');
57
+ });
58
+ it('should handle a marker split across three chunks', () => {
59
+ const transform = createMarkerTransformer(PORT);
60
+ const out1 = transform('│ {{scenario:');
61
+ const out2 = transform('Long Name:');
62
+ const out3 = transform('abc-123}} │');
63
+ const combined = out1 + out2 + out3;
64
+ expect(combined).toContain('Long Name');
65
+ expect(combined).not.toContain('{{scenario:');
66
+ });
67
+ it('should handle complete markers in a single chunk', () => {
68
+ const transform = createMarkerTransformer(PORT);
69
+ const result = transform('│ {{scenario:Default:abc-123}} │');
70
+ expect(result).toContain('Default');
71
+ expect(result).not.toContain('{{scenario:');
72
+ });
73
+ it('should handle multiple complete markers in a single chunk', () => {
74
+ const transform = createMarkerTransformer(PORT);
75
+ const result = transform('{{scenario:A:id1}} and {{scenario:B:id2}}');
76
+ expect(result).not.toContain('{{scenario:');
77
+ expect(result).toContain('A');
78
+ expect(result).toContain('B');
79
+ });
80
+ it('should discard stale buffer on carriage return (Ink line rewrite)', () => {
81
+ const transform = createMarkerTransformer(PORT);
82
+ // Ink renders partial: "│ {{scenario:Lo"
83
+ const out1 = transform('│ {{scenario:Lo');
84
+ // Ink rewrites the line with more content
85
+ const out2 = transform('\r\x1b[K│ {{scenario:Long Na');
86
+ // Ink completes the line
87
+ const out3 = transform('me:abc-123}} │\n');
88
+ const combined = out1 + out2 + out3;
89
+ // The final output should have the transformed marker, not the raw one
90
+ expect(combined).toContain('Long Name');
91
+ expect(combined).not.toContain('{{scenario:');
92
+ });
93
+ it('should handle carriage return mid-buffer without losing the new marker', () => {
94
+ const transform = createMarkerTransformer(PORT);
95
+ // Buffer has partial marker, then line gets rewritten with a complete marker
96
+ const out1 = transform('{{scenario:Te');
97
+ const out2 = transform('\r\x1b[K{{scenario:Tea:id1}} │');
98
+ const combined = out1 + out2;
99
+ expect(combined).toContain('Tea');
100
+ expect(combined).not.toContain('{{scenario:');
101
+ });
102
+ it('should handle ANSI codes within a split marker', () => {
103
+ const transform = createMarkerTransformer(PORT);
104
+ const out1 = transform('\x1b[33m{{scenario:\x1b[1mDef');
105
+ const out2 = transform('ault\x1b[22m:abc-123\x1b[0m}}');
106
+ const combined = out1 + out2;
107
+ expect(combined).toContain('Default');
108
+ expect(combined).not.toContain('{{scenario:');
109
+ });
110
+ it('should flush stale partial on carriage return even without \\x1b[K', () => {
111
+ const transform = createMarkerTransformer(PORT);
112
+ const out1 = transform('│ {{scenario:Partia');
113
+ // Just \r, no erase sequence — Ink sometimes does this
114
+ const out2 = transform('\r│ {{scenario:Full Name:id1}} │');
115
+ const combined = out1 + out2;
116
+ expect(combined).toContain('Full Name');
117
+ expect(combined).not.toContain('{{scenario:');
118
+ });
119
+ });
120
+ });
121
+ //# sourceMappingURL=scenarioMarkers.test.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"scenarioMarkers.test.js","sourceRoot":"","sources":["../../../../../src/utils/__tests__/scenarioMarkers.test.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,4 @@
1
+ export const IS_INTERNAL_BUILD = typeof false !== 'undefined'
2
+ ? false
3
+ : false;
4
+ //# sourceMappingURL=buildFlags.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"buildFlags.js","sourceRoot":"","sources":["../../../../src/utils/buildFlags.ts"],"names":[],"mappings":"AAAA,MAAM,CAAC,MAAM,iBAAiB,GAC5B,OAAO,0BAA0B,KAAK,WAAW;IAC/C,CAAC,CAAC,0BAA0B;IAC5B,CAAC,CAAC,KAAK,CAAC"}
@@ -0,0 +1,82 @@
1
+ /**
2
+ * Pure logic for `codeyam editor audit` — zero I/O, fully testable.
3
+ *
4
+ * Cross-references glossary entries against registered scenarios (components)
5
+ * and test files (functions) to detect gaps Claude may have missed.
6
+ */
7
+ // ─── Logic ───────────────────────────────────────────────────────────
8
+ const COMPONENT_RETURN_PATTERNS = ['JSX', 'React', 'Element', 'ReactNode'];
9
+ /**
10
+ * Returns true when the entry's returnType indicates a React component
11
+ * (contains "JSX", "React", "Element", or "ReactNode").
12
+ */
13
+ export function isComponent(entry) {
14
+ if (!entry.returnType)
15
+ return false;
16
+ return COMPONENT_RETURN_PATTERNS.some((pat) => entry.returnType.includes(pat));
17
+ }
18
+ /**
19
+ * Split glossary entries into components (JSX-returning) and functions (everything else).
20
+ */
21
+ export function classifyGlossaryEntries(entries) {
22
+ const components = [];
23
+ const functions = [];
24
+ for (const entry of entries) {
25
+ if (isComponent(entry)) {
26
+ components.push(entry);
27
+ }
28
+ else {
29
+ functions.push(entry);
30
+ }
31
+ }
32
+ return { components, functions };
33
+ }
34
+ /**
35
+ * Given classified entries and coverage data, produce a structured audit result.
36
+ *
37
+ * @param components - Glossary entries classified as components
38
+ * @param functions - Glossary entries classified as functions
39
+ * @param scenarioCounts - Map of component_name → number of registered scenarios
40
+ * @param testFileExistence - Map of testFile path → whether the file exists on disk
41
+ */
42
+ export function computeAudit({ components, functions, scenarioCounts, testFileExistence, }) {
43
+ const componentResults = components.map((c) => {
44
+ const count = scenarioCounts[c.name] || 0;
45
+ return {
46
+ name: c.name,
47
+ filePath: c.filePath,
48
+ scenarioCount: count,
49
+ status: count > 0 ? 'ok' : 'missing',
50
+ };
51
+ });
52
+ const functionResults = functions.map((f) => {
53
+ const exists = f.testFile
54
+ ? (testFileExistence[f.testFile] ?? false)
55
+ : false;
56
+ return {
57
+ name: f.name,
58
+ filePath: f.filePath,
59
+ testFile: f.testFile,
60
+ testFileExists: exists,
61
+ status: exists ? 'ok' : 'missing',
62
+ };
63
+ });
64
+ const componentsOk = componentResults.filter((c) => c.status === 'ok').length;
65
+ const componentsMissing = componentResults.length - componentsOk;
66
+ const functionsOk = functionResults.filter((f) => f.status === 'ok').length;
67
+ const functionsMissing = functionResults.length - functionsOk;
68
+ return {
69
+ components: componentResults,
70
+ functions: functionResults,
71
+ summary: {
72
+ totalComponents: componentResults.length,
73
+ componentsOk,
74
+ componentsMissing,
75
+ totalFunctions: functionResults.length,
76
+ functionsOk,
77
+ functionsMissing,
78
+ allPassing: componentsMissing === 0 && functionsMissing === 0,
79
+ },
80
+ };
81
+ }
82
+ //# sourceMappingURL=editorAudit.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"editorAudit.js","sourceRoot":"","sources":["../../../../src/utils/editorAudit.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,98 @@
1
+ /**
2
+ * Dev server process management utilities for the editor.
3
+ *
4
+ * Extracted from inline logic in api.editor-dev-server.ts.
5
+ */
6
+ import fs from 'fs';
7
+ import path from 'path';
8
+ /**
9
+ * Detect the package manager and start script for a project.
10
+ *
11
+ * Returns `{ command, args }` on success, or `{ error }` if the project
12
+ * lacks a runnable dev/start script or package.json.
13
+ */
14
+ export function detectPackageManagerAndScript(projectRoot) {
15
+ const packageJsonPath = path.join(projectRoot, 'package.json');
16
+ if (!fs.existsSync(packageJsonPath)) {
17
+ return { error: 'No package.json found.' };
18
+ }
19
+ let command = 'npm';
20
+ let args = ['run', 'dev'];
21
+ try {
22
+ const pkg = JSON.parse(fs.readFileSync(packageJsonPath, 'utf8'));
23
+ // Detect package manager from lockfile
24
+ if (fs.existsSync(path.join(projectRoot, 'pnpm-lock.yaml'))) {
25
+ command = 'pnpm';
26
+ }
27
+ else if (fs.existsSync(path.join(projectRoot, 'yarn.lock'))) {
28
+ command = 'yarn';
29
+ }
30
+ else if (fs.existsSync(path.join(projectRoot, 'bun.lockb'))) {
31
+ command = 'bun';
32
+ }
33
+ // Check for dev or start script
34
+ if (!pkg.scripts?.dev) {
35
+ if (pkg.scripts?.start) {
36
+ args = ['run', 'start'];
37
+ }
38
+ else {
39
+ return { error: 'No "dev" or "start" script found in package.json.' };
40
+ }
41
+ }
42
+ }
43
+ catch {
44
+ // Use defaults (npm run dev)
45
+ }
46
+ return { command, args };
47
+ }
48
+ /** URL patterns matched in dev server output to detect the running URL. */
49
+ const URL_PATTERNS = [
50
+ /Local:\s+(https?:\/\/[^\s]+)/, // Vite
51
+ /Ready on\s+(https?:\/\/[^\s]+)/i, // Next.js
52
+ /started at\s+(https?:\/\/[^\s]+)/i, // Remix
53
+ /listening on\s+(https?:\/\/[^\s]+)/i, // Generic
54
+ /http:\/\/localhost:\d+/, // Bare URL
55
+ ];
56
+ /**
57
+ * Extract a dev server URL from process output text.
58
+ * Matches common patterns from Vite, Next.js, Remix, and generic servers.
59
+ * Strips ANSI codes from the result.
60
+ * Returns null if no URL is found.
61
+ */
62
+ export function extractDevServerUrl(text) {
63
+ for (const pattern of URL_PATTERNS) {
64
+ const match = text.match(pattern);
65
+ if (match) {
66
+ const url = match[1] || match[0];
67
+ return stripAnsiCodes(url).trim();
68
+ }
69
+ }
70
+ return null;
71
+ }
72
+ /**
73
+ * Remove ANSI escape sequences from text.
74
+ */
75
+ export function stripAnsiCodes(text) {
76
+ return text.replace(/\x1b\[[0-9;]*m/g, '');
77
+ }
78
+ /**
79
+ * Determine what action to take when the dev server process exits.
80
+ *
81
+ * - Quick failure (< 10s) on first attempt → retry
82
+ * - Non-zero exit after retry or after long uptime → error
83
+ * - Zero or null exit → stopped normally
84
+ */
85
+ export function determineProcessExitState(params) {
86
+ const { exitCode, uptime, retryCount } = params;
87
+ const quickFailure = uptime < 10000;
88
+ if (exitCode !== 0 && exitCode !== null && quickFailure && retryCount === 0) {
89
+ return { action: 'retry' };
90
+ }
91
+ else if (exitCode !== 0 && exitCode !== null) {
92
+ return { action: 'error' };
93
+ }
94
+ else {
95
+ return { action: 'stopped' };
96
+ }
97
+ }
98
+ //# sourceMappingURL=editorDevServer.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"editorDevServer.js","sourceRoot":"","sources":["../../../../src/utils/editorDevServer.ts"],"names":[],"mappings":"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"}