@nepopsx/cli 0.0.19 → 0.0.21

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 (129) hide show
  1. package/dist/agents/catalog.d.ts +19 -0
  2. package/dist/agents/catalog.d.ts.map +1 -0
  3. package/dist/agents/catalog.js +45 -0
  4. package/dist/agents/catalog.js.map +1 -0
  5. package/dist/agents/configuration.d.ts +1 -0
  6. package/dist/agents/configuration.d.ts.map +1 -1
  7. package/dist/agents/configuration.js +36 -0
  8. package/dist/agents/configuration.js.map +1 -1
  9. package/dist/agents/configuration.test.d.ts +2 -0
  10. package/dist/agents/configuration.test.d.ts.map +1 -0
  11. package/dist/agents/configuration.test.js +32 -0
  12. package/dist/agents/configuration.test.js.map +1 -0
  13. package/dist/commands/capture.d.ts +19 -0
  14. package/dist/commands/capture.d.ts.map +1 -0
  15. package/dist/commands/capture.js +105 -0
  16. package/dist/commands/capture.js.map +1 -0
  17. package/dist/commands/init.d.ts.map +1 -1
  18. package/dist/commands/init.js +11 -30
  19. package/dist/commands/init.js.map +1 -1
  20. package/dist/commands/install.d.ts +2 -0
  21. package/dist/commands/install.d.ts.map +1 -1
  22. package/dist/commands/install.js +86 -15
  23. package/dist/commands/install.js.map +1 -1
  24. package/dist/commands/login.d.ts +8 -1
  25. package/dist/commands/login.d.ts.map +1 -1
  26. package/dist/commands/login.js +169 -80
  27. package/dist/commands/login.js.map +1 -1
  28. package/dist/commands/push-learnings.d.ts.map +1 -1
  29. package/dist/commands/push-learnings.js +95 -63
  30. package/dist/commands/push-learnings.js.map +1 -1
  31. package/dist/commands/sync.d.ts +4 -0
  32. package/dist/commands/sync.d.ts.map +1 -1
  33. package/dist/commands/sync.js +120 -64
  34. package/dist/commands/sync.js.map +1 -1
  35. package/dist/commands/up.d.ts +23 -0
  36. package/dist/commands/up.d.ts.map +1 -0
  37. package/dist/commands/up.js +263 -0
  38. package/dist/commands/up.js.map +1 -0
  39. package/dist/enrichment/workflow.d.ts +1 -0
  40. package/dist/enrichment/workflow.d.ts.map +1 -1
  41. package/dist/enrichment/workflow.js +13 -0
  42. package/dist/enrichment/workflow.js.map +1 -1
  43. package/dist/generator/preview.d.ts +13 -0
  44. package/dist/generator/preview.d.ts.map +1 -0
  45. package/dist/generator/preview.js +242 -0
  46. package/dist/generator/preview.js.map +1 -0
  47. package/dist/generator/preview.test.d.ts +19 -0
  48. package/dist/generator/preview.test.d.ts.map +1 -0
  49. package/dist/generator/preview.test.js +289 -0
  50. package/dist/generator/preview.test.js.map +1 -0
  51. package/dist/generator/render.d.ts +2 -2
  52. package/dist/generator/render.d.ts.map +1 -1
  53. package/dist/generator/render.js +37 -18
  54. package/dist/generator/render.js.map +1 -1
  55. package/dist/generator/writer.d.ts +15 -1
  56. package/dist/generator/writer.d.ts.map +1 -1
  57. package/dist/generator/writer.js +41 -3
  58. package/dist/generator/writer.js.map +1 -1
  59. package/dist/hooks/capture-hooks.d.ts +9 -0
  60. package/dist/hooks/capture-hooks.d.ts.map +1 -0
  61. package/dist/hooks/capture-hooks.js +100 -0
  62. package/dist/hooks/capture-hooks.js.map +1 -0
  63. package/dist/hooks/capture-hooks.test.d.ts +2 -0
  64. package/dist/hooks/capture-hooks.test.d.ts.map +1 -0
  65. package/dist/hooks/capture-hooks.test.js +50 -0
  66. package/dist/hooks/capture-hooks.test.js.map +1 -0
  67. package/dist/index.js +26 -3
  68. package/dist/index.js.map +1 -1
  69. package/dist/learnings/yaml-learnings.d.ts +16 -2
  70. package/dist/learnings/yaml-learnings.d.ts.map +1 -1
  71. package/dist/learnings/yaml-learnings.js +43 -8
  72. package/dist/learnings/yaml-learnings.js.map +1 -1
  73. package/dist/learnings/yaml-learnings.test.d.ts +2 -0
  74. package/dist/learnings/yaml-learnings.test.d.ts.map +1 -0
  75. package/dist/learnings/yaml-learnings.test.js +39 -0
  76. package/dist/learnings/yaml-learnings.test.js.map +1 -0
  77. package/dist/licensing/installer.d.ts +2 -2
  78. package/dist/licensing/installer.d.ts.map +1 -1
  79. package/dist/licensing/installer.js +3 -1
  80. package/dist/licensing/installer.js.map +1 -1
  81. package/dist/licensing/template-fetch.d.ts +2 -2
  82. package/dist/licensing/template-fetch.d.ts.map +1 -1
  83. package/dist/licensing/template-fetch.js +4 -1
  84. package/dist/licensing/template-fetch.js.map +1 -1
  85. package/dist/mcp/config-generator.d.ts +42 -0
  86. package/dist/mcp/config-generator.d.ts.map +1 -0
  87. package/dist/mcp/config-generator.js +55 -0
  88. package/dist/mcp/config-generator.js.map +1 -0
  89. package/dist/mcp/config-generator.test.d.ts +7 -0
  90. package/dist/mcp/config-generator.test.d.ts.map +1 -0
  91. package/dist/mcp/config-generator.test.js +79 -0
  92. package/dist/mcp/config-generator.test.js.map +1 -0
  93. package/dist/ruflo/config-generator.d.ts +22 -0
  94. package/dist/ruflo/config-generator.d.ts.map +1 -0
  95. package/dist/ruflo/config-generator.js +89 -0
  96. package/dist/ruflo/config-generator.js.map +1 -0
  97. package/dist/ruflo/config-generator.test.d.ts +2 -0
  98. package/dist/ruflo/config-generator.test.d.ts.map +1 -0
  99. package/dist/ruflo/config-generator.test.js +18 -0
  100. package/dist/ruflo/config-generator.test.js.map +1 -0
  101. package/dist/ruflo/detect.d.ts +11 -0
  102. package/dist/ruflo/detect.d.ts.map +1 -0
  103. package/dist/ruflo/detect.js +30 -0
  104. package/dist/ruflo/detect.js.map +1 -0
  105. package/dist/ruflo/index.d.ts +3 -0
  106. package/dist/ruflo/index.d.ts.map +1 -0
  107. package/dist/ruflo/index.js +3 -0
  108. package/dist/ruflo/index.js.map +1 -0
  109. package/dist/security/index.d.ts +1 -1
  110. package/dist/security/index.d.ts.map +1 -1
  111. package/dist/security/index.js +1 -1
  112. package/dist/security/index.js.map +1 -1
  113. package/dist/security/integrity.d.ts +8 -0
  114. package/dist/security/integrity.d.ts.map +1 -1
  115. package/dist/security/integrity.js +28 -0
  116. package/dist/security/integrity.js.map +1 -1
  117. package/package.json +5 -3
  118. package/dist/generator/package-renderer.d.ts +0 -38
  119. package/dist/generator/package-renderer.d.ts.map +0 -1
  120. package/dist/generator/package-renderer.js +0 -181
  121. package/dist/generator/package-renderer.js.map +0 -1
  122. package/dist/generator/provider-transform.d.ts +0 -15
  123. package/dist/generator/provider-transform.d.ts.map +0 -1
  124. package/dist/generator/provider-transform.js +0 -163
  125. package/dist/generator/provider-transform.js.map +0 -1
  126. package/dist/licensing/fingerprint.test.d.ts +0 -2
  127. package/dist/licensing/fingerprint.test.d.ts.map +0 -1
  128. package/dist/licensing/fingerprint.test.js +0 -41
  129. package/dist/licensing/fingerprint.test.js.map +0 -1
@@ -0,0 +1,242 @@
1
+ import chalk from 'chalk';
2
+ import * as Diff from 'diff';
3
+ import { existsSync, readFileSync } from 'node:fs';
4
+ import { join } from 'node:path';
5
+ import { loadLocalAgentConfig } from '../agents/remote-config.js';
6
+ // ---------------------------------------------------------------------------
7
+ // T2.1 — Binary heuristic (ADR-6)
8
+ // ---------------------------------------------------------------------------
9
+ function isProbablyBinary(content) {
10
+ const head = content.slice(0, 8192);
11
+ return head.includes('\0') || /[\x01-\x08\x0E-\x1F\x7F]/.test(head);
12
+ }
13
+ // ---------------------------------------------------------------------------
14
+ // T2.2 — On-disk reader with per-invocation cache
15
+ // ---------------------------------------------------------------------------
16
+ function readOnDiskContent(rootDir, relPath, cache) {
17
+ const absPath = join(rootDir, relPath);
18
+ if (cache.has(absPath)) {
19
+ return cache.get(absPath);
20
+ }
21
+ let value = null;
22
+ if (existsSync(absPath)) {
23
+ try {
24
+ value = readFileSync(absPath, 'utf-8');
25
+ }
26
+ catch {
27
+ value = null;
28
+ }
29
+ }
30
+ cache.set(absPath, value);
31
+ return value;
32
+ }
33
+ function diffOperation(rootDir, op, cache) {
34
+ const onDisk = readOnDiskContent(rootDir, op.path, cache);
35
+ // ---- NEW file ----
36
+ if (onDisk === null) {
37
+ const isBinary = isProbablyBinary(op.content);
38
+ let rendered;
39
+ if (isBinary) {
40
+ rendered =
41
+ chalk.bold.green('+ new: ' + op.path) +
42
+ '\n' +
43
+ chalk.dim('[binary] ' + Buffer.byteLength(op.content, 'utf-8') + ' bytes') +
44
+ '\n';
45
+ }
46
+ else {
47
+ const lines = op.content.split('\n');
48
+ // Remove the trailing empty string that split adds when content ends with \n
49
+ const contentLines = lines[lines.length - 1] === '' ? lines.slice(0, -1) : lines;
50
+ const body = contentLines.map((line) => chalk.green('+ ' + line)).join('\n');
51
+ rendered = chalk.bold.green('+ new: ' + op.path) + '\n' + body + '\n';
52
+ }
53
+ return { kind: 'new', rendered, isBinary };
54
+ }
55
+ // ---- UNCHANGED ----
56
+ if (onDisk === op.content) {
57
+ return { kind: 'unchanged', rendered: '', isBinary: false };
58
+ }
59
+ // ---- UPDATED ----
60
+ const oldIsBinary = isProbablyBinary(onDisk);
61
+ const newIsBinary = isProbablyBinary(op.content);
62
+ const isBinary = oldIsBinary || newIsBinary;
63
+ let rendered;
64
+ if (isBinary) {
65
+ rendered =
66
+ chalk.bold.yellow('~ updated: ' + op.path) +
67
+ '\n' +
68
+ chalk.dim('[binary] ' +
69
+ Buffer.byteLength(onDisk, 'utf-8') +
70
+ ' → ' +
71
+ Buffer.byteLength(op.content, 'utf-8') +
72
+ ' bytes') +
73
+ '\n';
74
+ }
75
+ else {
76
+ const patch = Diff.createTwoFilesPatch(op.path, op.path, onDisk, op.content, undefined, undefined, { context: 3 });
77
+ const colorized = patch
78
+ .split('\n')
79
+ .map((line) => {
80
+ if (line.startsWith('+++') || line.startsWith('---')) {
81
+ return chalk.bold(line);
82
+ }
83
+ if (line.startsWith('@@')) {
84
+ return chalk.cyan(line);
85
+ }
86
+ if (line.startsWith('+')) {
87
+ return chalk.green(line);
88
+ }
89
+ if (line.startsWith('-')) {
90
+ return chalk.red(line);
91
+ }
92
+ return line;
93
+ })
94
+ .join('\n');
95
+ rendered = chalk.bold.yellow('~ updated: ' + op.path) + '\n' + colorized + '\n';
96
+ }
97
+ return { kind: 'updated', rendered, isBinary };
98
+ }
99
+ const MAX_COL_WIDTH = 40;
100
+ function truncate(s, maxLen) {
101
+ if (s.length <= maxLen)
102
+ return s;
103
+ return s.slice(0, maxLen - 1) + '…';
104
+ }
105
+ function pad(s, width) {
106
+ return s.padEnd(width);
107
+ }
108
+ function renderConfigPatchesTable(rootDir, configPatches) {
109
+ if (!configPatches || Object.keys(configPatches).length === 0) {
110
+ return { output: '', count: 0, hasDestructive: false };
111
+ }
112
+ const rows = [];
113
+ for (const [key, patch] of Object.entries(configPatches)) {
114
+ const { slug, agent: agentName, path: dotPath, value: incomingValue } = patch;
115
+ // Load the local agent config to resolve the current value
116
+ const localConfig = loadLocalAgentConfig(rootDir, agentName);
117
+ let currentValue = null;
118
+ if (localConfig !== null) {
119
+ // Walk the dot-path to extract the current value
120
+ const parts = dotPath.split('.');
121
+ let cursor = localConfig;
122
+ for (const part of parts) {
123
+ if (cursor !== null &&
124
+ typeof cursor === 'object' &&
125
+ !Array.isArray(cursor) &&
126
+ Object.prototype.hasOwnProperty.call(cursor, part)) {
127
+ cursor = cursor[part];
128
+ }
129
+ else {
130
+ cursor = null;
131
+ break;
132
+ }
133
+ }
134
+ currentValue = cursor;
135
+ }
136
+ const destructive = currentValue !== null &&
137
+ JSON.stringify(currentValue) !== JSON.stringify(incomingValue);
138
+ rows.push({
139
+ slug: slug ?? key,
140
+ agent: agentName,
141
+ path: dotPath,
142
+ current: currentValue !== null ? JSON.stringify(currentValue, null, 0) : '(none)',
143
+ incoming: JSON.stringify(incomingValue, null, 0),
144
+ destructive,
145
+ });
146
+ }
147
+ if (rows.length === 0) {
148
+ return { output: '', count: 0, hasDestructive: false };
149
+ }
150
+ const headers = ['slug', 'agent', 'path', 'current', 'incoming', 'destructive'];
151
+ // Compute column widths
152
+ const stringKeys = ['slug', 'agent', 'path', 'current', 'incoming'];
153
+ const colWidths = headers.map((h, i) => {
154
+ const headerLen = h.length;
155
+ if (i < 5) {
156
+ const key = stringKeys[i];
157
+ return Math.min(MAX_COL_WIDTH, Math.max(headerLen, ...rows.map((r) => r[key].length)));
158
+ }
159
+ // i === 5: destructive column (boolean)
160
+ return Math.min(MAX_COL_WIDTH, Math.max(headerLen, ...rows.map((r) => String(r.destructive).length)));
161
+ });
162
+ const formatRow = (cells) => cells.map((cell, i) => pad(truncate(cell, colWidths[i]), colWidths[i])).join(' | ');
163
+ const separator = colWidths.map((w) => '-'.repeat(w)).join('-+-');
164
+ const headerRow = formatRow(headers);
165
+ const lines = [chalk.bold(headerRow), separator];
166
+ for (const row of rows) {
167
+ const cells = [
168
+ row.slug,
169
+ row.agent,
170
+ row.path,
171
+ row.current,
172
+ row.incoming,
173
+ String(row.destructive),
174
+ ];
175
+ const line = formatRow(cells);
176
+ lines.push(row.destructive ? chalk.red(line) : line);
177
+ }
178
+ const tableOutput = chalk.bold('\nConfig patches:\n') + lines.join('\n') + '\n';
179
+ return {
180
+ output: tableOutput,
181
+ count: rows.length,
182
+ hasDestructive: rows.some((r) => r.destructive),
183
+ };
184
+ }
185
+ // ---------------------------------------------------------------------------
186
+ // T2.5 — Top-level renderPreview (pure function)
187
+ // ---------------------------------------------------------------------------
188
+ export function renderPreview(rootDir, operations, approvedLearnings) {
189
+ const cache = new Map();
190
+ let createdCount = 0;
191
+ let updatedCount = 0;
192
+ let unchangedCount = 0;
193
+ const parts = [];
194
+ for (const op of operations) {
195
+ const result = diffOperation(rootDir, op, cache);
196
+ if (result.kind === 'new') {
197
+ createdCount++;
198
+ parts.push(result.rendered);
199
+ }
200
+ else if (result.kind === 'updated') {
201
+ updatedCount++;
202
+ parts.push(result.rendered);
203
+ }
204
+ else {
205
+ unchangedCount++;
206
+ // unchanged rendered is '' — skip
207
+ }
208
+ }
209
+ const patchesResult = renderConfigPatchesTable(rootDir, approvedLearnings?.config_patches);
210
+ const configPatchCount = patchesResult.count;
211
+ const hasDestructive = patchesResult.hasDestructive;
212
+ let output;
213
+ if (createdCount + updatedCount + configPatchCount === 0) {
214
+ output = chalk.bold('\nNo changes pending.\n');
215
+ if (unchangedCount > 0) {
216
+ output += chalk.dim('\n[= unchanged] ' + unchangedCount + ' file(s)\n');
217
+ }
218
+ }
219
+ else {
220
+ output = parts.join('') + patchesResult.output;
221
+ if (unchangedCount > 0) {
222
+ output += chalk.dim('\n[= unchanged] ' + unchangedCount + ' file(s)\n');
223
+ }
224
+ }
225
+ return {
226
+ output,
227
+ createdCount,
228
+ updatedCount,
229
+ unchangedCount,
230
+ configPatchCount,
231
+ hasDestructive,
232
+ };
233
+ }
234
+ // ---------------------------------------------------------------------------
235
+ // T2.6 — Exit code helper (exported)
236
+ // ---------------------------------------------------------------------------
237
+ export function computeExitCode(result, exitOnChanges) {
238
+ if (!exitOnChanges)
239
+ return 0;
240
+ return (result.createdCount + result.updatedCount + result.configPatchCount) > 0 ? 1 : 0;
241
+ }
242
+ //# sourceMappingURL=preview.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"preview.js","sourceRoot":"","sources":["../../src/generator/preview.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,19 @@
1
+ /**
2
+ * Unit tests for optx-package/packages/cli/src/generator/preview.ts
3
+ *
4
+ * Covers:
5
+ * T5.2 — No changes pending (AC-2)
6
+ * T5.3 — New file tagged [+ new] with green + prefix (AC-3, FR-5)
7
+ * T5.4 — Updated file produces unified diff (AC-1, FR-3)
8
+ * T5.5 — Unchanged file collapsed (FR-4)
9
+ * T5.6 — Destructive config_patches flagged (AC-4, FR-6)
10
+ * T5.7 — Config patches section omitted when approvedLearnings is null (FR-6)
11
+ * T5.8 — computeExitCode formula (AC-6, FR-9)
12
+ * T5.9 — Byte-identical idempotency (AC-10, NFR-2)
13
+ * T5.10 — No ANSI escapes when chalk.level=0 (AC-9, NFR-3)
14
+ * T5.11 — Binary content rendered as [binary] (ADR-6)
15
+ *
16
+ * Run: pnpm --filter @nepopsx/cli build && pnpm --filter @nepopsx/cli test
17
+ */
18
+ export {};
19
+ //# sourceMappingURL=preview.test.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"preview.test.d.ts","sourceRoot":"","sources":["../../src/generator/preview.test.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;GAgBG"}
@@ -0,0 +1,289 @@
1
+ /**
2
+ * Unit tests for optx-package/packages/cli/src/generator/preview.ts
3
+ *
4
+ * Covers:
5
+ * T5.2 — No changes pending (AC-2)
6
+ * T5.3 — New file tagged [+ new] with green + prefix (AC-3, FR-5)
7
+ * T5.4 — Updated file produces unified diff (AC-1, FR-3)
8
+ * T5.5 — Unchanged file collapsed (FR-4)
9
+ * T5.6 — Destructive config_patches flagged (AC-4, FR-6)
10
+ * T5.7 — Config patches section omitted when approvedLearnings is null (FR-6)
11
+ * T5.8 — computeExitCode formula (AC-6, FR-9)
12
+ * T5.9 — Byte-identical idempotency (AC-10, NFR-2)
13
+ * T5.10 — No ANSI escapes when chalk.level=0 (AC-9, NFR-3)
14
+ * T5.11 — Binary content rendered as [binary] (ADR-6)
15
+ *
16
+ * Run: pnpm --filter @nepopsx/cli build && pnpm --filter @nepopsx/cli test
17
+ */
18
+ import { strict as assert } from 'node:assert';
19
+ import { mkdtempSync, mkdirSync, writeFileSync, rmSync, } from 'node:fs';
20
+ import { join, dirname } from 'node:path';
21
+ import { tmpdir } from 'node:os';
22
+ import { describe, it, before, after } from 'node:test';
23
+ import chalk from 'chalk';
24
+ import { renderPreview, computeExitCode } from './preview.js';
25
+ function makeFixture() {
26
+ const rootDir = mkdtempSync(join(tmpdir(), 'nepopsx-preview-test-'));
27
+ function seedFile(relPath, content) {
28
+ const absPath = join(rootDir, relPath);
29
+ mkdirSync(dirname(absPath), { recursive: true });
30
+ writeFileSync(absPath, content, 'utf-8');
31
+ }
32
+ function makeOp(relPath, content) {
33
+ return { path: relPath, content, source: 'test' };
34
+ }
35
+ function cleanup() {
36
+ rmSync(rootDir, { recursive: true, force: true });
37
+ }
38
+ return { rootDir, seedFile, makeOp, cleanup };
39
+ }
40
+ /** Strip ANSI escape codes from a string so we can assert on plain text. */
41
+ function stripAnsi(s) {
42
+ // eslint-disable-next-line no-control-regex
43
+ return s.replace(/\x1b\[[0-9;]*m/g, '');
44
+ }
45
+ // ---------------------------------------------------------------------------
46
+ // T5.2 — No changes pending
47
+ // ---------------------------------------------------------------------------
48
+ describe('renderPreview() — no changes pending (AC-2)', () => {
49
+ let fix;
50
+ before(() => { fix = makeFixture(); });
51
+ after(() => { fix.cleanup(); });
52
+ it('prints "No changes pending" and returns zero counts when every op matches disk', () => {
53
+ fix.seedFile('file-a.md', 'hello world\n');
54
+ fix.seedFile('file-b.md', 'goodbye world\n');
55
+ const ops = [
56
+ fix.makeOp('file-a.md', 'hello world\n'),
57
+ fix.makeOp('file-b.md', 'goodbye world\n'),
58
+ ];
59
+ const result = renderPreview(fix.rootDir, ops, null);
60
+ assert.strictEqual(result.createdCount, 0);
61
+ assert.strictEqual(result.updatedCount, 0);
62
+ assert.strictEqual(result.unchangedCount, 2);
63
+ assert.strictEqual(result.configPatchCount, 0);
64
+ assert.ok(stripAnsi(result.output).includes('No changes pending'), `Expected "No changes pending" in output, got:\n${result.output}`);
65
+ });
66
+ });
67
+ // ---------------------------------------------------------------------------
68
+ // T5.3 — New file tagged [+ new] with green + prefix
69
+ // ---------------------------------------------------------------------------
70
+ describe('renderPreview() — new file (AC-3, FR-5)', () => {
71
+ let fix;
72
+ before(() => { fix = makeFixture(); });
73
+ after(() => { fix.cleanup(); });
74
+ it('tags a brand-new file as [+ new] and prints content with + prefix', () => {
75
+ const content = 'line one\nline two\n';
76
+ const ops = [fix.makeOp('brand-new.md', content)];
77
+ const result = renderPreview(fix.rootDir, ops, null);
78
+ const plain = stripAnsi(result.output);
79
+ assert.strictEqual(result.createdCount, 1);
80
+ assert.strictEqual(result.updatedCount, 0);
81
+ assert.ok(plain.includes('+ new:'), `Expected "+ new:" label in output, got:\n${plain}`);
82
+ assert.ok(plain.includes('+ line one'), `Expected "+ line one" prefix in output, got:\n${plain}`);
83
+ assert.ok(plain.includes('+ line two'), `Expected "+ line two" prefix in output, got:\n${plain}`);
84
+ });
85
+ });
86
+ // ---------------------------------------------------------------------------
87
+ // T5.4 — Updated file produces unified diff
88
+ // ---------------------------------------------------------------------------
89
+ describe('renderPreview() — updated file produces unified diff (AC-1, FR-3)', () => {
90
+ let fix;
91
+ before(() => { fix = makeFixture(); });
92
+ after(() => { fix.cleanup(); });
93
+ it('emits @@ hunk header and +/- lines for a changed file', () => {
94
+ fix.seedFile('existing.md', 'old line\n');
95
+ const ops = [fix.makeOp('existing.md', 'new line\n')];
96
+ const result = renderPreview(fix.rootDir, ops, null);
97
+ const plain = stripAnsi(result.output);
98
+ assert.strictEqual(result.updatedCount, 1);
99
+ assert.strictEqual(result.createdCount, 0);
100
+ assert.ok(plain.includes('@@'), `Expected @@ hunk header in diff output, got:\n${plain}`);
101
+ assert.ok(plain.includes('-old line'), `Expected "-old line" removed line in diff, got:\n${plain}`);
102
+ assert.ok(plain.includes('+new line'), `Expected "+new line" added line in diff, got:\n${plain}`);
103
+ });
104
+ });
105
+ // ---------------------------------------------------------------------------
106
+ // T5.5 — Unchanged files collapsed
107
+ // ---------------------------------------------------------------------------
108
+ describe('renderPreview() — unchanged files collapsed (FR-4)', () => {
109
+ let fix;
110
+ before(() => { fix = makeFixture(); });
111
+ after(() => { fix.cleanup(); });
112
+ it('collapses an unchanged file to a single count line while showing changed ops', () => {
113
+ fix.seedFile('unchanged.md', 'same content\n');
114
+ fix.seedFile('changed.md', 'old\n');
115
+ const ops = [
116
+ fix.makeOp('unchanged.md', 'same content\n'), // unchanged
117
+ fix.makeOp('changed.md', 'new\n'), // updated
118
+ ];
119
+ const result = renderPreview(fix.rootDir, ops, null);
120
+ const plain = stripAnsi(result.output);
121
+ assert.strictEqual(result.unchangedCount, 1);
122
+ assert.strictEqual(result.updatedCount, 1);
123
+ assert.ok(plain.includes('[= unchanged]') && plain.includes('1'), `Expected "[= unchanged] 1" summary line, got:\n${plain}`);
124
+ });
125
+ });
126
+ // ---------------------------------------------------------------------------
127
+ // T5.6 — Destructive config_patches flagged
128
+ // ---------------------------------------------------------------------------
129
+ describe('renderPreview() — destructive config_patches (AC-4, FR-6)', () => {
130
+ let fix;
131
+ before(() => { fix = makeFixture(); });
132
+ after(() => { fix.cleanup(); });
133
+ it('sets hasDestructive=true and configPatchCount=1 when a patch overwrites an existing value', () => {
134
+ // Seed the agent config YAML at the expected location: .nepopsx/agents/<name>.yaml
135
+ fix.seedFile('.nepopsx/agents/feature-factory.yaml', 'model: gpt-4\n');
136
+ const approvedLearnings = {
137
+ customs: {},
138
+ skills: {},
139
+ config_patches: {
140
+ 'patch-1': {
141
+ slug: 'change-model',
142
+ agent: 'feature-factory',
143
+ path: 'model',
144
+ value: 'claude-sonnet-4-6',
145
+ title: 'Update model',
146
+ },
147
+ },
148
+ merged_learnings: {},
149
+ };
150
+ // Provide a dummy op so there's no separate "No changes pending" path confusion
151
+ fix.seedFile('dummy.md', 'content\n');
152
+ const ops = [fix.makeOp('dummy.md', 'content\n')];
153
+ const result = renderPreview(fix.rootDir, ops, approvedLearnings);
154
+ assert.strictEqual(result.hasDestructive, true, 'hasDestructive should be true');
155
+ assert.strictEqual(result.configPatchCount, 1, 'configPatchCount should be 1');
156
+ const plain = stripAnsi(result.output);
157
+ assert.ok(plain.includes('Config patches'), `Expected "Config patches" section header, got:\n${plain}`);
158
+ // The row should show the destructive flag
159
+ assert.ok(plain.includes('true'), `Expected "true" in destructive column, got:\n${plain}`);
160
+ });
161
+ });
162
+ // ---------------------------------------------------------------------------
163
+ // T5.7 — Config patches section omitted when approvedLearnings is null
164
+ // ---------------------------------------------------------------------------
165
+ describe('renderPreview() — config patches omitted when approvedLearnings is null (FR-6)', () => {
166
+ let fix;
167
+ before(() => { fix = makeFixture(); });
168
+ after(() => { fix.cleanup(); });
169
+ it('does not include "Config patches" header when approvedLearnings is null', () => {
170
+ fix.seedFile('file.md', 'content\n');
171
+ const ops = [fix.makeOp('file.md', 'content\n')];
172
+ const result = renderPreview(fix.rootDir, ops, null);
173
+ assert.strictEqual(result.configPatchCount, 0);
174
+ assert.ok(!stripAnsi(result.output).includes('Config patches'), `Output should NOT contain "Config patches" when approvedLearnings is null, got:\n${result.output}`);
175
+ });
176
+ });
177
+ // ---------------------------------------------------------------------------
178
+ // T5.8 — computeExitCode formula (AC-6, FR-9)
179
+ // ---------------------------------------------------------------------------
180
+ describe('computeExitCode() — exit code formula (AC-6, FR-9)', () => {
181
+ const baseResult = {
182
+ output: '',
183
+ createdCount: 0,
184
+ updatedCount: 0,
185
+ unchangedCount: 0,
186
+ configPatchCount: 0,
187
+ hasDestructive: false,
188
+ };
189
+ it('returns 0 when exitOnChanges=false even with changes', () => {
190
+ const result = { ...baseResult, createdCount: 3, updatedCount: 2 };
191
+ assert.strictEqual(computeExitCode(result, false), 0);
192
+ });
193
+ it('returns 0 when exitOnChanges=false and all counts are zero', () => {
194
+ assert.strictEqual(computeExitCode(baseResult, false), 0);
195
+ });
196
+ it('returns 0 when exitOnChanges=true but all counts are zero', () => {
197
+ assert.strictEqual(computeExitCode(baseResult, true), 0);
198
+ });
199
+ it('returns 1 when exitOnChanges=true and createdCount > 0', () => {
200
+ const result = { ...baseResult, createdCount: 1 };
201
+ assert.strictEqual(computeExitCode(result, true), 1);
202
+ });
203
+ it('returns 1 when exitOnChanges=true and updatedCount > 0', () => {
204
+ const result = { ...baseResult, updatedCount: 2 };
205
+ assert.strictEqual(computeExitCode(result, true), 1);
206
+ });
207
+ it('returns 1 when exitOnChanges=true and configPatchCount > 0', () => {
208
+ const result = { ...baseResult, configPatchCount: 1 };
209
+ assert.strictEqual(computeExitCode(result, true), 1);
210
+ });
211
+ });
212
+ // ---------------------------------------------------------------------------
213
+ // T5.9 — Byte-identical idempotency (AC-10, NFR-2)
214
+ // ---------------------------------------------------------------------------
215
+ describe('renderPreview() — byte-identical across two calls (AC-10, NFR-2)', () => {
216
+ let fix;
217
+ before(() => { fix = makeFixture(); });
218
+ after(() => { fix.cleanup(); });
219
+ it('produces byte-identical output on two successive calls with the same inputs', () => {
220
+ fix.seedFile('a.md', 'first\n');
221
+ fix.seedFile('b.md', 'match\n');
222
+ const ops = [
223
+ fix.makeOp('a.md', 'modified\n'), // updated
224
+ fix.makeOp('b.md', 'match\n'), // unchanged
225
+ fix.makeOp('c.md', 'brand new\n'), // new
226
+ ];
227
+ const result1 = renderPreview(fix.rootDir, ops, null);
228
+ const result2 = renderPreview(fix.rootDir, ops, null);
229
+ assert.strictEqual(result1.output, result2.output, 'renderPreview must produce byte-identical output for the same inputs');
230
+ });
231
+ });
232
+ // ---------------------------------------------------------------------------
233
+ // T5.10 — No ANSI escapes when chalk.level=0 (AC-9, NFR-3)
234
+ // ---------------------------------------------------------------------------
235
+ describe('renderPreview() — no ANSI escape sequences when chalk.level=0 (AC-9, NFR-3)', () => {
236
+ let fix;
237
+ let originalChalkLevel;
238
+ before(() => {
239
+ fix = makeFixture();
240
+ originalChalkLevel = chalk.level;
241
+ chalk.level = 0;
242
+ });
243
+ after(() => {
244
+ chalk.level = originalChalkLevel;
245
+ fix.cleanup();
246
+ });
247
+ it('output contains no ANSI escape codes when chalk.level is 0', () => {
248
+ fix.seedFile('existing.md', 'old content\n');
249
+ const ops = [
250
+ fix.makeOp('existing.md', 'new content\n'), // updated
251
+ fix.makeOp('brand-new.md', 'hello\n'), // new
252
+ ];
253
+ const result = renderPreview(fix.rootDir, ops, null);
254
+ // eslint-disable-next-line no-control-regex
255
+ const hasAnsi = /\x1b\[/.test(result.output);
256
+ assert.strictEqual(hasAnsi, false, `Output must contain no ANSI escapes when chalk.level=0, got:\n${result.output}`);
257
+ });
258
+ });
259
+ // ---------------------------------------------------------------------------
260
+ // T5.11 — Binary content rendered as [binary] (ADR-6)
261
+ // ---------------------------------------------------------------------------
262
+ describe('renderPreview() — binary content renders [binary] (ADR-6)', () => {
263
+ let fix;
264
+ before(() => { fix = makeFixture(); });
265
+ after(() => { fix.cleanup(); });
266
+ it('emits "[binary]" for content with embedded null bytes and skips unified diff', () => {
267
+ // Content with a null byte — should trigger the binary heuristic
268
+ const binaryContent = 'before\0after';
269
+ const ops = [fix.makeOp('image.bin', binaryContent)];
270
+ const result = renderPreview(fix.rootDir, ops, null);
271
+ const plain = stripAnsi(result.output);
272
+ assert.ok(plain.includes('[binary]'), `Expected "[binary]" in output for binary content, got:\n${plain}`);
273
+ // Unified diff would have +++ and --- headers; these must NOT appear for binary
274
+ assert.ok(!plain.includes('+++'), `Output must NOT contain "+++" (unified diff header) for binary content, got:\n${plain}`);
275
+ // createdCount=1 because the file doesn't exist on disk
276
+ assert.strictEqual(result.createdCount, 1);
277
+ });
278
+ it('emits "[binary]" for an updated binary file and skips unified diff', () => {
279
+ // Seed an existing binary file
280
+ fix.seedFile('binary-update.bin', 'old\0data');
281
+ const ops = [fix.makeOp('binary-update.bin', 'new\0bytes')];
282
+ const result = renderPreview(fix.rootDir, ops, null);
283
+ const plain = stripAnsi(result.output);
284
+ assert.ok(plain.includes('[binary]'), `Expected "[binary]" in output for updated binary content, got:\n${plain}`);
285
+ assert.ok(!plain.includes('+++'), `Output must NOT contain "+++" for updated binary content, got:\n${plain}`);
286
+ assert.strictEqual(result.updatedCount, 1);
287
+ });
288
+ });
289
+ //# sourceMappingURL=preview.test.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"preview.test.js","sourceRoot":"","sources":["../../src/generator/preview.test.ts"],"names":[],"mappings":"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"}
@@ -5,8 +5,8 @@
5
5
  * - renderTemplateFile (reads template from disk)
6
6
  * - applyLicenseWatermark (steganographic fingerprint)
7
7
  */
8
- import type { WorkspaceConfig, WatermarkData } from '@nepopsx/core';
9
- import { renderTemplate, registerAgentPartialsFromMap, clearPartialNames, renderTemplateMap, setPhilosophyBlock, setCustomInstructions, type AgentRenderContext, type CustomInstruction, type RenderContext } from '@nepopsx/core';
8
+ import type { WorkspaceConfig, WatermarkData } from "@nepopsx/core";
9
+ import { renderTemplate, registerAgentPartialsFromMap, clearPartialNames, renderTemplateMap, setPhilosophyBlock, setCustomInstructions, type AgentRenderContext, type CustomInstruction, type RenderContext } from "@nepopsx/core";
10
10
  export { renderTemplate, registerAgentPartialsFromMap, clearPartialNames, renderTemplateMap, setPhilosophyBlock, setCustomInstructions, type AgentRenderContext, type CustomInstruction, type RenderContext, };
11
11
  /**
12
12
  * Register all partials from a package's partials/ directory on disk.
@@ -1 +1 @@
1
- {"version":3,"file":"render.d.ts","sourceRoot":"","sources":["../../src/generator/render.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;AAKH,OAAO,KAAK,EAAE,eAAe,EAAE,aAAa,EAAE,MAAM,eAAe,CAAC;AACpE,OAAO,EAEL,cAAc,EACd,4BAA4B,EAC5B,iBAAiB,EACjB,iBAAiB,EACjB,kBAAkB,EAClB,qBAAqB,EAErB,KAAK,kBAAkB,EACvB,KAAK,iBAAiB,EACtB,KAAK,aAAa,EACnB,MAAM,eAAe,CAAC;AAIvB,OAAO,EACL,cAAc,EACd,4BAA4B,EAC5B,iBAAiB,EACjB,iBAAiB,EACjB,kBAAkB,EAClB,qBAAqB,EACrB,KAAK,kBAAkB,EACvB,KAAK,iBAAiB,EACtB,KAAK,aAAa,GACnB,CAAC;AAIF;;GAEG;AACH,wBAAgB,qBAAqB,CACnC,WAAW,EAAE,MAAM,EACnB,MAAM,EAAE,eAAe,EACvB,SAAS,CAAC,EAAE,kBAAkB,GAC7B,IAAI,CAiBN;AAED;;GAEG;AACH,wBAAgB,aAAa,CAAC,WAAW,EAAE,MAAM,GAAG,IAAI,CAQvD;AAED;;GAEG;AACH,wBAAgB,kBAAkB,CAChC,YAAY,EAAE,MAAM,EACpB,MAAM,EAAE,eAAe,EACvB,SAAS,CAAC,EAAE,kBAAkB,GAC7B,MAAM,CAGR;AAMD,wBAAgB,gBAAgB,CAAC,IAAI,EAAE,aAAa,GAAG,IAAI,GAAG,IAAI,CAEjE;AAeD,wBAAgB,qBAAqB,CAAC,OAAO,EAAE,MAAM,EAAE,UAAU,CAAC,EAAE,MAAM,GAAG,MAAM,CAMlF"}
1
+ {"version":3,"file":"render.d.ts","sourceRoot":"","sources":["../../src/generator/render.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;AAKH,OAAO,KAAK,EAAE,eAAe,EAAE,aAAa,EAAE,MAAM,eAAe,CAAC;AACpE,OAAO,EAEL,cAAc,EACd,4BAA4B,EAC5B,iBAAiB,EACjB,iBAAiB,EACjB,kBAAkB,EAClB,qBAAqB,EAErB,KAAK,kBAAkB,EACvB,KAAK,iBAAiB,EACtB,KAAK,aAAa,EACnB,MAAM,eAAe,CAAC;AAIvB,OAAO,EACL,cAAc,EACd,4BAA4B,EAC5B,iBAAiB,EACjB,iBAAiB,EACjB,kBAAkB,EAClB,qBAAqB,EACrB,KAAK,kBAAkB,EACvB,KAAK,iBAAiB,EACtB,KAAK,aAAa,GACnB,CAAC;AAIF;;GAEG;AACH,wBAAgB,qBAAqB,CACnC,WAAW,EAAE,MAAM,EACnB,MAAM,EAAE,eAAe,EACvB,SAAS,CAAC,EAAE,kBAAkB,GAC7B,IAAI,CAoBN;AAED;;GAEG;AACH,wBAAgB,aAAa,CAAC,WAAW,EAAE,MAAM,GAAG,IAAI,CAQvD;AAED;;GAEG;AACH,wBAAgB,kBAAkB,CAChC,YAAY,EAAE,MAAM,EACpB,MAAM,EAAE,eAAe,EACvB,SAAS,CAAC,EAAE,kBAAkB,GAC7B,MAAM,CAGR;AASD,wBAAgB,gBAAgB,CAAC,IAAI,EAAE,aAAa,GAAG,IAAI,GAAG,IAAI,CAEjE;AA4CD,wBAAgB,qBAAqB,CACnC,OAAO,EAAE,MAAM,EACf,UAAU,CAAC,EAAE,MAAM,GAClB,MAAM,CAOR"}