@hivecommons/promptargs 0.6.0 → 0.7.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +46 -6
- package/dist/autodetect.d.ts +2 -0
- package/dist/autodetect.js +53 -3
- package/dist/autodetect.js.map +1 -1
- package/dist/autodetect.test.d.ts +1 -0
- package/dist/autodetect.test.js +207 -0
- package/dist/autodetect.test.js.map +1 -0
- package/dist/cli.js +13 -8
- package/dist/cli.js.map +1 -1
- package/dist/cli.test.d.ts +1 -0
- package/dist/cli.test.js +310 -0
- package/dist/cli.test.js.map +1 -0
- package/dist/index.test.d.ts +1 -0
- package/dist/index.test.js +59 -0
- package/dist/index.test.js.map +1 -0
- package/dist/iterate.d.ts +8 -0
- package/dist/iterate.js +28 -0
- package/dist/iterate.js.map +1 -0
- package/dist/iterate.test.d.ts +1 -0
- package/dist/iterate.test.js +20 -0
- package/dist/iterate.test.js.map +1 -0
- package/dist/loader.test.d.ts +1 -0
- package/dist/loader.test.js +65 -0
- package/dist/loader.test.js.map +1 -0
- package/dist/mustache.mjs +764 -0
- package/dist/parser.d.ts +1 -0
- package/dist/parser.js +16 -4
- package/dist/parser.js.map +1 -1
- package/dist/parser.test.js +37 -0
- package/dist/parser.test.js.map +1 -1
- package/dist/resolver.js +58 -44
- package/dist/resolver.js.map +1 -1
- package/dist/resolver.test.d.ts +1 -0
- package/dist/resolver.test.js +184 -0
- package/dist/resolver.test.js.map +1 -0
- package/dist/sanitize.d.ts +10 -0
- package/dist/sanitize.js +21 -0
- package/dist/sanitize.js.map +1 -0
- package/dist/sanitize.test.d.ts +1 -0
- package/dist/sanitize.test.js +38 -0
- package/dist/sanitize.test.js.map +1 -0
- package/dist/status.js +4 -1
- package/dist/status.js.map +1 -1
- package/dist/status.test.d.ts +1 -0
- package/dist/status.test.js +33 -0
- package/dist/status.test.js.map +1 -0
- package/dist/ui-bootstrap.test.d.ts +1 -0
- package/dist/ui-bootstrap.test.js +479 -0
- package/dist/ui-bootstrap.test.js.map +1 -0
- package/dist/ui-builder.test.d.ts +1 -0
- package/dist/ui-builder.test.js +272 -0
- package/dist/ui-builder.test.js.map +1 -0
- package/dist/ui-command-quoting.test.d.ts +1 -0
- package/dist/ui-command-quoting.test.js +95 -0
- package/dist/ui-command-quoting.test.js.map +1 -0
- package/dist/ui-harness.d.ts +20 -0
- package/dist/ui-harness.js +40 -0
- package/dist/ui-harness.js.map +1 -0
- package/dist/ui-harness.test.d.ts +1 -0
- package/dist/ui-harness.test.js +30 -0
- package/dist/ui-harness.test.js.map +1 -0
- package/dist/ui-inline.test.d.ts +1 -0
- package/dist/ui-inline.test.js +90 -0
- package/dist/ui-inline.test.js.map +1 -0
- package/dist/ui-interactions.test.d.ts +1 -0
- package/dist/ui-interactions.test.js +489 -0
- package/dist/ui-interactions.test.js.map +1 -0
- package/dist/ui.d.ts +13 -1
- package/dist/ui.html +30 -57
- package/dist/ui.js +61 -18
- package/dist/ui.js.map +1 -1
- package/dist/ui.test.d.ts +1 -0
- package/dist/ui.test.js +283 -0
- package/dist/ui.test.js.map +1 -0
- package/package.json +4 -3
package/dist/cli.test.js
ADDED
|
@@ -0,0 +1,310 @@
|
|
|
1
|
+
import { test } from 'node:test';
|
|
2
|
+
import assert from 'node:assert';
|
|
3
|
+
import { spawnSync } from 'node:child_process';
|
|
4
|
+
import { mkdtempSync, writeFileSync, mkdirSync, existsSync, readFileSync, rmSync } from 'node:fs';
|
|
5
|
+
import { join, dirname } from 'node:path';
|
|
6
|
+
import { tmpdir } from 'node:os';
|
|
7
|
+
import { fileURLToPath } from 'node:url';
|
|
8
|
+
const __dirname = dirname(fileURLToPath(import.meta.url));
|
|
9
|
+
const CLI = join(__dirname, 'cli.js');
|
|
10
|
+
function runCli(args, cwd, home) {
|
|
11
|
+
const result = spawnSync(process.execPath, [CLI, ...args], {
|
|
12
|
+
cwd,
|
|
13
|
+
encoding: 'utf-8',
|
|
14
|
+
env: { ...process.env, HOME: home, USERPROFILE: home },
|
|
15
|
+
});
|
|
16
|
+
return { status: result.status, stdout: result.stdout, stderr: result.stderr };
|
|
17
|
+
}
|
|
18
|
+
// Each test gets an isolated cwd and HOME so ~/.prompts and ./.prompts
|
|
19
|
+
// from the host machine never leak into template resolution.
|
|
20
|
+
function makeDirs() {
|
|
21
|
+
const base = mkdtempSync(join(tmpdir(), 'promptargs-cli-test-'));
|
|
22
|
+
const cwd = join(base, 'work');
|
|
23
|
+
const home = join(base, 'home');
|
|
24
|
+
mkdirSync(cwd, { recursive: true });
|
|
25
|
+
mkdirSync(home, { recursive: true });
|
|
26
|
+
return { cwd, home };
|
|
27
|
+
}
|
|
28
|
+
test('no args prints help and exits 0', () => {
|
|
29
|
+
const { cwd, home } = makeDirs();
|
|
30
|
+
const res = runCli([], cwd, home);
|
|
31
|
+
assert.strictEqual(res.status, 0);
|
|
32
|
+
assert.match(res.stdout, /promptargs — Template arguments for AI prompts/);
|
|
33
|
+
assert.match(res.stdout, /Auto-detected variables:/);
|
|
34
|
+
rmSync(dirname(cwd), { recursive: true, force: true });
|
|
35
|
+
});
|
|
36
|
+
test('help subcommand and --help flag print usage', () => {
|
|
37
|
+
const { cwd, home } = makeDirs();
|
|
38
|
+
for (const arg of ['help', '--help']) {
|
|
39
|
+
const res = runCli([arg], cwd, home);
|
|
40
|
+
assert.strictEqual(res.status, 0, `exit code for ${arg}`);
|
|
41
|
+
assert.match(res.stdout, /Usage:/);
|
|
42
|
+
}
|
|
43
|
+
rmSync(dirname(cwd), { recursive: true, force: true });
|
|
44
|
+
});
|
|
45
|
+
test('env subcommand lists every autodetect variable', () => {
|
|
46
|
+
const { cwd, home } = makeDirs();
|
|
47
|
+
const res = runCli(['env'], cwd, home);
|
|
48
|
+
assert.strictEqual(res.status, 0);
|
|
49
|
+
assert.match(res.stdout, /Auto-detected variables:/);
|
|
50
|
+
// Non-git cwd: variables should render as "(not detected)" rather than crash.
|
|
51
|
+
assert.match(res.stdout, /\{\{branch\}\}/);
|
|
52
|
+
assert.match(res.stdout, /\{\{repo\}\}/);
|
|
53
|
+
assert.match(res.stdout, /\{\{date\}\}/);
|
|
54
|
+
rmSync(dirname(cwd), { recursive: true, force: true });
|
|
55
|
+
});
|
|
56
|
+
test('inline template expands flag values', () => {
|
|
57
|
+
const { cwd, home } = makeDirs();
|
|
58
|
+
const res = runCli(['Hello {{name}}', '--name=World', '--no-interactive'], cwd, home);
|
|
59
|
+
assert.strictEqual(res.status, 0);
|
|
60
|
+
assert.strictEqual(res.stdout.trim(), 'Hello World');
|
|
61
|
+
rmSync(dirname(cwd), { recursive: true, force: true });
|
|
62
|
+
});
|
|
63
|
+
test('template without variables is printed as-is', () => {
|
|
64
|
+
const { cwd, home } = makeDirs();
|
|
65
|
+
mkdirSync(join(cwd, '.prompts'));
|
|
66
|
+
writeFileSync(join(cwd, '.prompts', 'plain.md'), 'No variables here.\n');
|
|
67
|
+
const res = runCli(['plain', '--no-interactive'], cwd, home);
|
|
68
|
+
assert.strictEqual(res.status, 0);
|
|
69
|
+
assert.match(res.stdout, /No variables here\./);
|
|
70
|
+
rmSync(dirname(cwd), { recursive: true, force: true });
|
|
71
|
+
});
|
|
72
|
+
test('unknown template exits 1 with guidance', () => {
|
|
73
|
+
const { cwd, home } = makeDirs();
|
|
74
|
+
const res = runCli(['nope', '--no-interactive'], cwd, home);
|
|
75
|
+
assert.strictEqual(res.status, 1);
|
|
76
|
+
assert.match(res.stderr, /Template "nope" not found\./);
|
|
77
|
+
assert.match(res.stderr, /promptargs list/);
|
|
78
|
+
assert.match(res.stderr, /promptargs init/);
|
|
79
|
+
rmSync(dirname(cwd), { recursive: true, force: true });
|
|
80
|
+
});
|
|
81
|
+
test('init creates .prompts with three example templates', () => {
|
|
82
|
+
const { cwd, home } = makeDirs();
|
|
83
|
+
const res = runCli(['init'], cwd, home);
|
|
84
|
+
assert.strictEqual(res.status, 0);
|
|
85
|
+
assert.match(res.stdout, /Created \.prompts\/ with 3 example templates:/);
|
|
86
|
+
for (const f of ['review.md', 'explain.md', 'fix.md']) {
|
|
87
|
+
assert.ok(existsSync(join(cwd, '.prompts', f)), `${f} should exist`);
|
|
88
|
+
}
|
|
89
|
+
const review = readFileSync(join(cwd, '.prompts', 'review.md'), 'utf-8');
|
|
90
|
+
assert.match(review, /\{\{file\}\}/);
|
|
91
|
+
assert.match(review, /\{\{focus=correctness\}\}/);
|
|
92
|
+
rmSync(dirname(cwd), { recursive: true, force: true });
|
|
93
|
+
});
|
|
94
|
+
test('init is a no-op when .prompts already exists', () => {
|
|
95
|
+
const { cwd, home } = makeDirs();
|
|
96
|
+
mkdirSync(join(cwd, '.prompts'));
|
|
97
|
+
writeFileSync(join(cwd, '.prompts', 'keep.md'), 'existing {{x}}');
|
|
98
|
+
const res = runCli(['init'], cwd, home);
|
|
99
|
+
assert.strictEqual(res.status, 0);
|
|
100
|
+
assert.match(res.stdout, /\.prompts\/ already exists!/);
|
|
101
|
+
assert.strictEqual(readFileSync(join(cwd, '.prompts', 'keep.md'), 'utf-8'), 'existing {{x}}');
|
|
102
|
+
assert.ok(!existsSync(join(cwd, '.prompts', 'review.md')));
|
|
103
|
+
rmSync(dirname(cwd), { recursive: true, force: true });
|
|
104
|
+
});
|
|
105
|
+
test('list shows template names, vars with defaults, and user source tag', () => {
|
|
106
|
+
const { cwd, home } = makeDirs();
|
|
107
|
+
mkdirSync(join(cwd, '.prompts'));
|
|
108
|
+
writeFileSync(join(cwd, '.prompts', 'review.md'), 'Review {{file}} for {{focus=bugs}}.');
|
|
109
|
+
mkdirSync(join(home, '.prompts'));
|
|
110
|
+
writeFileSync(join(home, '.prompts', 'personal.md'), 'Do {{thing}}.');
|
|
111
|
+
const res = runCli(['list'], cwd, home);
|
|
112
|
+
assert.strictEqual(res.status, 0);
|
|
113
|
+
assert.match(res.stdout, /review/);
|
|
114
|
+
assert.match(res.stdout, /\{\{file\}\}\s+\{\{focus=bugs\}\}/);
|
|
115
|
+
assert.match(res.stdout, /personal \(user\)/);
|
|
116
|
+
rmSync(dirname(cwd), { recursive: true, force: true });
|
|
117
|
+
});
|
|
118
|
+
test('list with no templates suggests init', () => {
|
|
119
|
+
const { cwd, home } = makeDirs();
|
|
120
|
+
const res = runCli(['list'], cwd, home);
|
|
121
|
+
assert.strictEqual(res.status, 0);
|
|
122
|
+
assert.match(res.stdout, /No templates found\./);
|
|
123
|
+
assert.match(res.stdout, /promptargs init/);
|
|
124
|
+
rmSync(dirname(cwd), { recursive: true, force: true });
|
|
125
|
+
});
|
|
126
|
+
test('show highlights required and defaulted variables', () => {
|
|
127
|
+
const { cwd, home } = makeDirs();
|
|
128
|
+
mkdirSync(join(cwd, '.prompts'));
|
|
129
|
+
writeFileSync(join(cwd, '.prompts', 'demo.md'), 'Fix {{issue}} in {{file=main.go}}.');
|
|
130
|
+
const res = runCli(['show', 'demo'], cwd, home);
|
|
131
|
+
assert.strictEqual(res.status, 0);
|
|
132
|
+
assert.match(res.stdout, /Template: demo/);
|
|
133
|
+
// Required var wrapped in red (31m), defaulted var in yellow (33m).
|
|
134
|
+
assert.match(res.stdout, /\x1b\[31m\{\{issue\}\}\x1b\[0m/);
|
|
135
|
+
assert.match(res.stdout, /\x1b\[33m\{\{file=main\.go\}\}\x1b\[0m/);
|
|
136
|
+
rmSync(dirname(cwd), { recursive: true, force: true });
|
|
137
|
+
});
|
|
138
|
+
test('show highlights whitespace-padded tags as written', () => {
|
|
139
|
+
const { cwd, home } = makeDirs();
|
|
140
|
+
mkdirSync(join(cwd, '.prompts'));
|
|
141
|
+
writeFileSync(join(cwd, '.prompts', 'padded.md'), 'Fix {{ issue }} in {{ file=main.go }}.');
|
|
142
|
+
const res = runCli(['show', 'padded'], cwd, home);
|
|
143
|
+
assert.strictEqual(res.status, 0);
|
|
144
|
+
assert.match(res.stdout, /\x1b\[31m\{\{ issue \}\}\x1b\[0m/);
|
|
145
|
+
assert.match(res.stdout, /\x1b\[33m\{\{ file=main\.go \}\}\x1b\[0m/);
|
|
146
|
+
rmSync(dirname(cwd), { recursive: true, force: true });
|
|
147
|
+
});
|
|
148
|
+
test('padded tags are filled from flags and reported in --status', () => {
|
|
149
|
+
const { cwd, home } = makeDirs();
|
|
150
|
+
const tpl = 'Review {{ file }} for {{ focus=bugs }}';
|
|
151
|
+
const run = runCli([tpl, '--file=a.ts', '--no-interactive'], cwd, home);
|
|
152
|
+
assert.strictEqual(run.status, 0);
|
|
153
|
+
assert.strictEqual(run.stdout.trim(), 'Review a.ts for bugs');
|
|
154
|
+
const status = runCli([tpl, '--no-interactive', '--status'], cwd, home);
|
|
155
|
+
assert.strictEqual(status.status, 0);
|
|
156
|
+
// Without padding support the status line claimed ✅ with only focus listed.
|
|
157
|
+
assert.match(status.stdout, /📋 inline: file=___ focus=bugs\(default\)/);
|
|
158
|
+
rmSync(dirname(cwd), { recursive: true, force: true });
|
|
159
|
+
});
|
|
160
|
+
test('show without a template name exits 1 with usage', () => {
|
|
161
|
+
const { cwd, home } = makeDirs();
|
|
162
|
+
const res = runCli(['show'], cwd, home);
|
|
163
|
+
assert.strictEqual(res.status, 1);
|
|
164
|
+
assert.match(res.stderr, /Usage: promptargs show <template>/);
|
|
165
|
+
rmSync(dirname(cwd), { recursive: true, force: true });
|
|
166
|
+
});
|
|
167
|
+
test('show with unknown template exits 1', () => {
|
|
168
|
+
const { cwd, home } = makeDirs();
|
|
169
|
+
const res = runCli(['show', 'ghost'], cwd, home);
|
|
170
|
+
assert.strictEqual(res.status, 1);
|
|
171
|
+
assert.match(res.stderr, /Template "ghost" not found\./);
|
|
172
|
+
rmSync(dirname(cwd), { recursive: true, force: true });
|
|
173
|
+
});
|
|
174
|
+
test('zip mode pairs array values positionally', () => {
|
|
175
|
+
const { cwd, home } = makeDirs();
|
|
176
|
+
const res = runCli(['Review {{file}} for {{focus}}', '--file=a.go,b.go', '--focus=x,y', '--no-interactive'], cwd, home);
|
|
177
|
+
assert.strictEqual(res.status, 0);
|
|
178
|
+
const runs = res.stdout.trim().split('\n---\n');
|
|
179
|
+
assert.strictEqual(runs.length, 2);
|
|
180
|
+
assert.match(runs[0], /Review a\.go for x/);
|
|
181
|
+
assert.match(runs[1], /Review b\.go for y/);
|
|
182
|
+
rmSync(dirname(cwd), { recursive: true, force: true });
|
|
183
|
+
});
|
|
184
|
+
test('--cross produces the full cross-product of array values', () => {
|
|
185
|
+
const { cwd, home } = makeDirs();
|
|
186
|
+
const res = runCli(['Review {{file}} for {{focus}}', '--file=a.go,b.go', '--focus=x,y', '--cross', '--no-interactive'], cwd, home);
|
|
187
|
+
assert.strictEqual(res.status, 0);
|
|
188
|
+
const runs = res.stdout.trim().split('\n---\n');
|
|
189
|
+
assert.strictEqual(runs.length, 4);
|
|
190
|
+
const combos = ['a.go for x', 'a.go for y', 'b.go for x', 'b.go for y'];
|
|
191
|
+
for (const combo of combos) {
|
|
192
|
+
assert.ok(runs.some(r => r.includes(combo)), `missing combination: ${combo}`);
|
|
193
|
+
}
|
|
194
|
+
// Multi-run mode also writes a progress status line per run to stderr.
|
|
195
|
+
assert.match(res.stderr, /\[1\/4\]/);
|
|
196
|
+
rmSync(dirname(cwd), { recursive: true, force: true });
|
|
197
|
+
});
|
|
198
|
+
test('--json emits a single string for one run and an array for many', () => {
|
|
199
|
+
const { cwd, home } = makeDirs();
|
|
200
|
+
const single = runCli(['Hi {{name}}', '--name=Ada', '--json', '--no-interactive'], cwd, home);
|
|
201
|
+
assert.strictEqual(single.status, 0);
|
|
202
|
+
assert.strictEqual(JSON.parse(single.stdout), 'Hi Ada');
|
|
203
|
+
const multi = runCli(['Hi {{name}}', '--name=Ada,Bob', '--json', '--no-interactive'], cwd, home);
|
|
204
|
+
assert.strictEqual(multi.status, 0);
|
|
205
|
+
assert.deepStrictEqual(JSON.parse(multi.stdout), ['Hi Ada', 'Hi Bob']);
|
|
206
|
+
rmSync(dirname(cwd), { recursive: true, force: true });
|
|
207
|
+
});
|
|
208
|
+
test('--status prints only the status line for the first iteration', () => {
|
|
209
|
+
const { cwd, home } = makeDirs();
|
|
210
|
+
const res = runCli(['Review {{file}} for {{focus=bugs}}', '--file=a.go', '--status', '--no-interactive'], cwd, home);
|
|
211
|
+
assert.strictEqual(res.status, 0);
|
|
212
|
+
assert.match(res.stdout, /file=a\.go/);
|
|
213
|
+
assert.match(res.stdout, /focus=bugs\(default\)/);
|
|
214
|
+
assert.doesNotMatch(res.stdout, /Review a\.go/);
|
|
215
|
+
rmSync(dirname(cwd), { recursive: true, force: true });
|
|
216
|
+
});
|
|
217
|
+
test('defaults fill unset variables in non-interactive mode', () => {
|
|
218
|
+
const { cwd, home } = makeDirs();
|
|
219
|
+
const res = runCli(['Be {{tone=concise}} about {{file}}', '--file=x.ts', '--no-interactive'], cwd, home);
|
|
220
|
+
assert.strictEqual(res.status, 0);
|
|
221
|
+
assert.match(res.stdout, /Be concise about x\.ts/);
|
|
222
|
+
rmSync(dirname(cwd), { recursive: true, force: true });
|
|
223
|
+
});
|
|
224
|
+
test('valueless flags are treated as boolean "true"', () => {
|
|
225
|
+
const { cwd, home } = makeDirs();
|
|
226
|
+
// --no-interactive has no "=", exercising the parseFlags boolean branch;
|
|
227
|
+
// {{flagged}} picks up an explicit value while iteration still succeeds.
|
|
228
|
+
const res = runCli(['{{a}} and {{b}}', '--a=1', '--b=2', '--no-interactive'], cwd, home);
|
|
229
|
+
assert.strictEqual(res.status, 0);
|
|
230
|
+
assert.strictEqual(res.stdout.trim(), '1 and 2');
|
|
231
|
+
rmSync(dirname(cwd), { recursive: true, force: true });
|
|
232
|
+
});
|
|
233
|
+
test('@file array syntax reads one value per line', () => {
|
|
234
|
+
const { cwd, home } = makeDirs();
|
|
235
|
+
writeFileSync(join(cwd, 'names.txt'), 'Ada\nBob\n');
|
|
236
|
+
const res = runCli(['Hi {{name}}', '--name=@names.txt', '--no-interactive'], cwd, home);
|
|
237
|
+
assert.strictEqual(res.status, 0);
|
|
238
|
+
const runs = res.stdout.trim().split('\n---\n');
|
|
239
|
+
assert.strictEqual(runs.length, 2);
|
|
240
|
+
assert.match(runs[0], /Hi Ada/);
|
|
241
|
+
assert.match(runs[1], /Hi Bob/);
|
|
242
|
+
rmSync(dirname(cwd), { recursive: true, force: true });
|
|
243
|
+
});
|
|
244
|
+
test('ui subcommand parses --port and surfaces server errors', async () => {
|
|
245
|
+
// Occupy a port so `promptargs ui` fails fast and deterministically —
|
|
246
|
+
// this exercises the ui dispatch path without leaving a server running.
|
|
247
|
+
const { createServer } = await import('node:net');
|
|
248
|
+
const blocker = createServer();
|
|
249
|
+
await new Promise(resolve => blocker.listen(0, '127.0.0.1', resolve));
|
|
250
|
+
const { port } = blocker.address();
|
|
251
|
+
try {
|
|
252
|
+
const { cwd, home } = makeDirs();
|
|
253
|
+
const res = runCli(['ui', `--port=${port}`], cwd, home);
|
|
254
|
+
assert.strictEqual(res.status, 1);
|
|
255
|
+
assert.match(res.stderr, new RegExp(`Port ${port} is in use`));
|
|
256
|
+
rmSync(dirname(cwd), { recursive: true, force: true });
|
|
257
|
+
}
|
|
258
|
+
finally {
|
|
259
|
+
await new Promise(resolve => blocker.close(resolve));
|
|
260
|
+
}
|
|
261
|
+
});
|
|
262
|
+
test('ui subcommand without --port targets the default port 3700', async () => {
|
|
263
|
+
// Occupy the default port so `promptargs ui` (no flags) fails fast on
|
|
264
|
+
// EADDRINUSE, proving the no-port dispatch path reaches startUI's default.
|
|
265
|
+
const { createServer } = await import('node:net');
|
|
266
|
+
const blocker = createServer();
|
|
267
|
+
const bound = await new Promise(resolve => {
|
|
268
|
+
blocker.once('error', () => resolve(false));
|
|
269
|
+
blocker.listen(3700, '127.0.0.1', () => resolve(true));
|
|
270
|
+
});
|
|
271
|
+
// If binding failed, another process already holds 3700 — the CLI will
|
|
272
|
+
// still hit EADDRINUSE, so the assertions below hold either way.
|
|
273
|
+
try {
|
|
274
|
+
const { cwd, home } = makeDirs();
|
|
275
|
+
const res = runCli(['ui'], cwd, home);
|
|
276
|
+
assert.strictEqual(res.status, 1);
|
|
277
|
+
assert.match(res.stderr, /Port 3700 is in use\. Try: promptargs ui --port=3701/);
|
|
278
|
+
rmSync(dirname(cwd), { recursive: true, force: true });
|
|
279
|
+
}
|
|
280
|
+
finally {
|
|
281
|
+
if (bound)
|
|
282
|
+
await new Promise(resolve => blocker.close(resolve));
|
|
283
|
+
}
|
|
284
|
+
});
|
|
285
|
+
test('env truncates a long staged diff to a preview with ellipsis', () => {
|
|
286
|
+
const { cwd, home } = makeDirs();
|
|
287
|
+
const git = (gitArgs) => spawnSync('git', gitArgs, { cwd, encoding: 'utf-8', env: { ...process.env, HOME: home } });
|
|
288
|
+
git(['init', '-q']);
|
|
289
|
+
writeFileSync(join(cwd, 'big.txt'), 'x'.repeat(300) + '\n');
|
|
290
|
+
git(['add', 'big.txt']);
|
|
291
|
+
const res = runCli(['env'], cwd, home);
|
|
292
|
+
assert.strictEqual(res.status, 0);
|
|
293
|
+
// The diff was detected (green, not "(not detected)") …
|
|
294
|
+
assert.match(res.stdout, /\x1b\[32m\{\{diff\}\}\x1b\[0m = diff --git/);
|
|
295
|
+
// … and truncated: the 300-char payload line never appears, the ellipsis does.
|
|
296
|
+
assert.ok(!res.stdout.includes('x'.repeat(100)), 'full diff body leaked into preview');
|
|
297
|
+
assert.match(res.stdout, /\.\.\./);
|
|
298
|
+
rmSync(dirname(cwd), { recursive: true, force: true });
|
|
299
|
+
});
|
|
300
|
+
test('template read errors reach the top-level handler and exit 1', () => {
|
|
301
|
+
const { cwd, home } = makeDirs();
|
|
302
|
+
// A directory named like a template makes readFileSync throw EISDIR,
|
|
303
|
+
// which propagates through main() to the final .catch handler.
|
|
304
|
+
mkdirSync(join(cwd, '.prompts', 'broken.md'), { recursive: true });
|
|
305
|
+
const res = runCli(['show', 'broken'], cwd, home);
|
|
306
|
+
assert.strictEqual(res.status, 1);
|
|
307
|
+
assert.match(res.stderr, /EISDIR/);
|
|
308
|
+
rmSync(dirname(cwd), { recursive: true, force: true });
|
|
309
|
+
});
|
|
310
|
+
//# sourceMappingURL=cli.test.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"cli.test.js","sourceRoot":"","sources":["../src/cli.test.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export {};
|
|
@@ -0,0 +1,59 @@
|
|
|
1
|
+
import { test } from 'node:test';
|
|
2
|
+
import assert from 'node:assert';
|
|
3
|
+
import * as api from './index.js';
|
|
4
|
+
// package.json "main" points at dist/index.js — this file is the public API
|
|
5
|
+
// surface consumers get from `import ... from '@hivecommons/promptargs'`.
|
|
6
|
+
// Pin every runtime export so a refactor of the barrel (or of a re-exported
|
|
7
|
+
// module) that drops or renames a symbol fails the suite instead of shipping
|
|
8
|
+
// a silent breaking change.
|
|
9
|
+
const EXPECTED_FUNCTION_EXPORTS = [
|
|
10
|
+
'parseVars',
|
|
11
|
+
'expand',
|
|
12
|
+
'autodetect',
|
|
13
|
+
'autodetectAll',
|
|
14
|
+
'loadTemplates',
|
|
15
|
+
'findTemplate',
|
|
16
|
+
'resolve',
|
|
17
|
+
'renderStatus',
|
|
18
|
+
].sort();
|
|
19
|
+
test('index exports exactly the documented runtime API', () => {
|
|
20
|
+
const actual = Object.keys(api).sort();
|
|
21
|
+
const expected = [...EXPECTED_FUNCTION_EXPORTS, 'AUTODETECT_VARS'].sort();
|
|
22
|
+
assert.deepStrictEqual(actual, expected);
|
|
23
|
+
});
|
|
24
|
+
test('every function export is callable', () => {
|
|
25
|
+
for (const name of EXPECTED_FUNCTION_EXPORTS) {
|
|
26
|
+
assert.strictEqual(typeof api[name], 'function', `expected export "${name}" to be a function`);
|
|
27
|
+
}
|
|
28
|
+
});
|
|
29
|
+
test('AUTODETECT_VARS is a non-empty list of var names', () => {
|
|
30
|
+
assert.ok(Array.isArray(api.AUTODETECT_VARS));
|
|
31
|
+
assert.ok(api.AUTODETECT_VARS.length > 0);
|
|
32
|
+
for (const v of api.AUTODETECT_VARS) {
|
|
33
|
+
assert.strictEqual(typeof v, 'string');
|
|
34
|
+
assert.ok(v.length > 0);
|
|
35
|
+
}
|
|
36
|
+
});
|
|
37
|
+
test('entry-point exports are the same objects as their source modules', async () => {
|
|
38
|
+
const parser = await import('./parser.js');
|
|
39
|
+
const autodetectMod = await import('./autodetect.js');
|
|
40
|
+
const loader = await import('./loader.js');
|
|
41
|
+
const resolver = await import('./resolver.js');
|
|
42
|
+
const status = await import('./status.js');
|
|
43
|
+
assert.strictEqual(api.parseVars, parser.parseVars);
|
|
44
|
+
assert.strictEqual(api.expand, parser.expand);
|
|
45
|
+
assert.strictEqual(api.autodetect, autodetectMod.autodetect);
|
|
46
|
+
assert.strictEqual(api.autodetectAll, autodetectMod.autodetectAll);
|
|
47
|
+
assert.strictEqual(api.AUTODETECT_VARS, autodetectMod.AUTODETECT_VARS);
|
|
48
|
+
assert.strictEqual(api.loadTemplates, loader.loadTemplates);
|
|
49
|
+
assert.strictEqual(api.findTemplate, loader.findTemplate);
|
|
50
|
+
assert.strictEqual(api.resolve, resolver.resolve);
|
|
51
|
+
assert.strictEqual(api.renderStatus, status.renderStatus);
|
|
52
|
+
});
|
|
53
|
+
test('smoke: exported parseVars + expand round-trip through the entry point', () => {
|
|
54
|
+
const vars = api.parseVars('Hello {{name}}, focus on {{focus}}');
|
|
55
|
+
assert.deepStrictEqual(vars.map((v) => v.name), ['name', 'focus']);
|
|
56
|
+
const out = api.expand('Hello {{name}}', { name: 'World' });
|
|
57
|
+
assert.strictEqual(out, 'Hello World');
|
|
58
|
+
});
|
|
59
|
+
//# sourceMappingURL=index.test.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.test.js","sourceRoot":"","sources":["../src/index.test.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Pure array-iteration helpers shared by the CLI resolver and the browser
|
|
3
|
+
* builder UI. Dependency-free so this module can be loaded directly in the
|
|
4
|
+
* browser (via ui.html's <script type="module">) as well as bundled/run in
|
|
5
|
+
* Node, keeping both surfaces on the exact same compiled logic.
|
|
6
|
+
*/
|
|
7
|
+
export declare function cartesian<T>(arrays: T[][]): T[][];
|
|
8
|
+
export declare function zip<T>(arrays: T[][]): T[][];
|
package/dist/iterate.js
ADDED
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Pure array-iteration helpers shared by the CLI resolver and the browser
|
|
3
|
+
* builder UI. Dependency-free so this module can be loaded directly in the
|
|
4
|
+
* browser (via ui.html's <script type="module">) as well as bundled/run in
|
|
5
|
+
* Node, keeping both surfaces on the exact same compiled logic.
|
|
6
|
+
*/
|
|
7
|
+
export function cartesian(arrays) {
|
|
8
|
+
if (arrays.length === 0)
|
|
9
|
+
return [[]];
|
|
10
|
+
const [first, ...rest] = arrays;
|
|
11
|
+
const restCombos = cartesian(rest);
|
|
12
|
+
const result = [];
|
|
13
|
+
for (const val of first) {
|
|
14
|
+
for (const combo of restCombos) {
|
|
15
|
+
result.push([val, ...combo]);
|
|
16
|
+
}
|
|
17
|
+
}
|
|
18
|
+
return result;
|
|
19
|
+
}
|
|
20
|
+
export function zip(arrays) {
|
|
21
|
+
const maxLen = Math.max(...arrays.map(a => a.length), 1);
|
|
22
|
+
const out = [];
|
|
23
|
+
for (let i = 0; i < maxLen; i++) {
|
|
24
|
+
out.push(arrays.map(a => a[i % a.length]));
|
|
25
|
+
}
|
|
26
|
+
return out;
|
|
27
|
+
}
|
|
28
|
+
//# sourceMappingURL=iterate.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"iterate.js","sourceRoot":"","sources":["../src/iterate.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAEH,MAAM,UAAU,SAAS,CAAI,MAAa;IACxC,IAAI,MAAM,CAAC,MAAM,KAAK,CAAC;QAAE,OAAO,CAAC,EAAE,CAAC,CAAC;IACrC,MAAM,CAAC,KAAK,EAAE,GAAG,IAAI,CAAC,GAAG,MAAM,CAAC;IAChC,MAAM,UAAU,GAAG,SAAS,CAAC,IAAI,CAAC,CAAC;IACnC,MAAM,MAAM,GAAU,EAAE,CAAC;IACzB,KAAK,MAAM,GAAG,IAAI,KAAK,EAAE,CAAC;QACxB,KAAK,MAAM,KAAK,IAAI,UAAU,EAAE,CAAC;YAC/B,MAAM,CAAC,IAAI,CAAC,CAAC,GAAG,EAAE,GAAG,KAAK,CAAC,CAAC,CAAC;QAC/B,CAAC;IACH,CAAC;IACD,OAAO,MAAM,CAAC;AAChB,CAAC;AAED,MAAM,UAAU,GAAG,CAAI,MAAa;IAClC,MAAM,MAAM,GAAG,IAAI,CAAC,GAAG,CAAC,GAAG,MAAM,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,MAAM,CAAC,EAAE,CAAC,CAAC,CAAC;IACzD,MAAM,GAAG,GAAU,EAAE,CAAC;IACtB,KAAK,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,MAAM,EAAE,CAAC,EAAE,EAAE,CAAC;QAChC,GAAG,CAAC,IAAI,CAAC,MAAM,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC;IAC7C,CAAC;IACD,OAAO,GAAG,CAAC;AACb,CAAC"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export {};
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
import { describe, it } from 'node:test';
|
|
2
|
+
import assert from 'node:assert';
|
|
3
|
+
import { cartesian, zip } from './iterate.js';
|
|
4
|
+
describe('cartesian', () => {
|
|
5
|
+
it('returns a single empty combo for no arrays', () => {
|
|
6
|
+
assert.deepStrictEqual(cartesian([]), [[]]);
|
|
7
|
+
});
|
|
8
|
+
it('builds every combination across arrays', () => {
|
|
9
|
+
assert.deepStrictEqual(cartesian([['a', 'b'], ['1', '2']]), [['a', '1'], ['a', '2'], ['b', '1'], ['b', '2']]);
|
|
10
|
+
});
|
|
11
|
+
});
|
|
12
|
+
describe('zip', () => {
|
|
13
|
+
it('pairs equal-length arrays 1:1', () => {
|
|
14
|
+
assert.deepStrictEqual(zip([['a', 'b', 'c'], ['1', '2', '3']]), [['a', '1'], ['b', '2'], ['c', '3']]);
|
|
15
|
+
});
|
|
16
|
+
it('wraps shorter arrays around to match the longest one', () => {
|
|
17
|
+
assert.deepStrictEqual(zip([['a', 'b', 'c'], ['1', '2']]), [['a', '1'], ['b', '2'], ['c', '1']]);
|
|
18
|
+
});
|
|
19
|
+
});
|
|
20
|
+
//# sourceMappingURL=iterate.test.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"iterate.test.js","sourceRoot":"","sources":["../src/iterate.test.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,QAAQ,EAAE,EAAE,EAAE,MAAM,WAAW,CAAC;AACzC,OAAO,MAAM,MAAM,aAAa,CAAC;AACjC,OAAO,EAAE,SAAS,EAAE,GAAG,EAAE,MAAM,cAAc,CAAC;AAE9C,QAAQ,CAAC,WAAW,EAAE,GAAG,EAAE;IACzB,EAAE,CAAC,4CAA4C,EAAE,GAAG,EAAE;QACpD,MAAM,CAAC,eAAe,CAAC,SAAS,CAAC,EAAE,CAAC,EAAE,CAAC,EAAE,CAAC,CAAC,CAAC;IAC9C,CAAC,CAAC,CAAC;IAEH,EAAE,CAAC,wCAAwC,EAAE,GAAG,EAAE;QAChD,MAAM,CAAC,eAAe,CACpB,SAAS,CAAC,CAAC,CAAC,GAAG,EAAE,GAAG,CAAC,EAAE,CAAC,GAAG,EAAE,GAAG,CAAC,CAAC,CAAC,EACnC,CAAC,CAAC,GAAG,EAAE,GAAG,CAAC,EAAE,CAAC,GAAG,EAAE,GAAG,CAAC,EAAE,CAAC,GAAG,EAAE,GAAG,CAAC,EAAE,CAAC,GAAG,EAAE,GAAG,CAAC,CAAC,CACjD,CAAC;IACJ,CAAC,CAAC,CAAC;AACL,CAAC,CAAC,CAAC;AAEH,QAAQ,CAAC,KAAK,EAAE,GAAG,EAAE;IACnB,EAAE,CAAC,+BAA+B,EAAE,GAAG,EAAE;QACvC,MAAM,CAAC,eAAe,CACpB,GAAG,CAAC,CAAC,CAAC,GAAG,EAAE,GAAG,EAAE,GAAG,CAAC,EAAE,CAAC,GAAG,EAAE,GAAG,EAAE,GAAG,CAAC,CAAC,CAAC,EACvC,CAAC,CAAC,GAAG,EAAE,GAAG,CAAC,EAAE,CAAC,GAAG,EAAE,GAAG,CAAC,EAAE,CAAC,GAAG,EAAE,GAAG,CAAC,CAAC,CACrC,CAAC;IACJ,CAAC,CAAC,CAAC;IAEH,EAAE,CAAC,sDAAsD,EAAE,GAAG,EAAE;QAC9D,MAAM,CAAC,eAAe,CACpB,GAAG,CAAC,CAAC,CAAC,GAAG,EAAE,GAAG,EAAE,GAAG,CAAC,EAAE,CAAC,GAAG,EAAE,GAAG,CAAC,CAAC,CAAC,EAClC,CAAC,CAAC,GAAG,EAAE,GAAG,CAAC,EAAE,CAAC,GAAG,EAAE,GAAG,CAAC,EAAE,CAAC,GAAG,EAAE,GAAG,CAAC,CAAC,CACrC,CAAC;IACJ,CAAC,CAAC,CAAC;AACL,CAAC,CAAC,CAAC"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export {};
|
|
@@ -0,0 +1,65 @@
|
|
|
1
|
+
import { describe, it, before, after } from 'node:test';
|
|
2
|
+
import assert from 'node:assert';
|
|
3
|
+
import { mkdtempSync, mkdirSync, writeFileSync, rmSync } from 'node:fs';
|
|
4
|
+
import { join } from 'node:path';
|
|
5
|
+
// loader.ts resolves the user template dir from homedir() at import time,
|
|
6
|
+
// so point HOME at a scratch dir before importing it (each test file runs
|
|
7
|
+
// in its own process under node --test).
|
|
8
|
+
const fakeHome = mkdtempSync(join(process.cwd(), '.pa-home-'));
|
|
9
|
+
process.env.HOME = fakeHome;
|
|
10
|
+
const { loadTemplates, findTemplate } = await import('./loader.js');
|
|
11
|
+
let projectRoot;
|
|
12
|
+
before(() => {
|
|
13
|
+
projectRoot = mkdtempSync(join(process.cwd(), '.pa-proj-'));
|
|
14
|
+
mkdirSync(join(projectRoot, '.prompts'));
|
|
15
|
+
writeFileSync(join(projectRoot, '.prompts', 'review.md'), 'Review {{file}}');
|
|
16
|
+
writeFileSync(join(projectRoot, '.prompts', 'notes.txt'), 'not a template');
|
|
17
|
+
mkdirSync(join(fakeHome, '.prompts'));
|
|
18
|
+
writeFileSync(join(fakeHome, '.prompts', 'review.md'), 'User review {{file}}');
|
|
19
|
+
writeFileSync(join(fakeHome, '.prompts', 'global.md'), 'Global {{x}}');
|
|
20
|
+
});
|
|
21
|
+
after(() => {
|
|
22
|
+
rmSync(projectRoot, { recursive: true, force: true });
|
|
23
|
+
rmSync(fakeHome, { recursive: true, force: true });
|
|
24
|
+
});
|
|
25
|
+
describe('loadTemplates', () => {
|
|
26
|
+
it('loads only .md files from the project .prompts dir', () => {
|
|
27
|
+
const names = loadTemplates(projectRoot).map(t => t.name);
|
|
28
|
+
assert.ok(names.includes('review'));
|
|
29
|
+
assert.ok(!names.includes('notes'));
|
|
30
|
+
});
|
|
31
|
+
it('project templates override user templates with the same name', () => {
|
|
32
|
+
const review = loadTemplates(projectRoot).find(t => t.name === 'review');
|
|
33
|
+
assert.strictEqual(review?.source, 'project');
|
|
34
|
+
assert.strictEqual(review?.content, 'Review {{file}}');
|
|
35
|
+
});
|
|
36
|
+
it('includes user templates not shadowed by the project', () => {
|
|
37
|
+
const global = loadTemplates(projectRoot).find(t => t.name === 'global');
|
|
38
|
+
assert.strictEqual(global?.source, 'user');
|
|
39
|
+
assert.strictEqual(global?.content, 'Global {{x}}');
|
|
40
|
+
});
|
|
41
|
+
it('returns user templates when the project has no .prompts dir', () => {
|
|
42
|
+
const empty = mkdtempSync(join(process.cwd(), '.pa-empty-'));
|
|
43
|
+
try {
|
|
44
|
+
const templates = loadTemplates(empty);
|
|
45
|
+
assert.ok(templates.every(t => t.source === 'user'));
|
|
46
|
+
assert.ok(templates.some(t => t.name === 'review'));
|
|
47
|
+
}
|
|
48
|
+
finally {
|
|
49
|
+
rmSync(empty, { recursive: true, force: true });
|
|
50
|
+
}
|
|
51
|
+
});
|
|
52
|
+
it('records the template path', () => {
|
|
53
|
+
const review = findTemplate('review', projectRoot);
|
|
54
|
+
assert.strictEqual(review?.path, join(projectRoot, '.prompts', 'review.md'));
|
|
55
|
+
});
|
|
56
|
+
});
|
|
57
|
+
describe('findTemplate', () => {
|
|
58
|
+
it('finds a template by name', () => {
|
|
59
|
+
assert.strictEqual(findTemplate('global', projectRoot)?.name, 'global');
|
|
60
|
+
});
|
|
61
|
+
it('returns undefined for unknown names', () => {
|
|
62
|
+
assert.strictEqual(findTemplate('nope', projectRoot), undefined);
|
|
63
|
+
});
|
|
64
|
+
});
|
|
65
|
+
//# sourceMappingURL=loader.test.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"loader.test.js","sourceRoot":"","sources":["../src/loader.test.ts"],"names":[],"mappings":"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"}
|