@hivecommons/promptargs 0.7.0 → 0.8.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 +100 -15
- package/dist/autodetect.js +24 -9
- package/dist/autodetect.js.map +1 -1
- package/dist/cli.js +51 -147
- package/dist/cli.js.map +1 -1
- package/dist/commands.d.ts +4 -0
- package/dist/commands.js +130 -0
- package/dist/commands.js.map +1 -0
- package/dist/flags.d.ts +14 -0
- package/dist/flags.js +57 -0
- package/dist/flags.js.map +1 -0
- package/dist/loader.d.ts +2 -0
- package/dist/loader.js +64 -11
- package/dist/loader.js.map +1 -1
- package/dist/log.d.ts +19 -0
- package/dist/log.js +41 -0
- package/dist/log.js.map +1 -0
- package/dist/parser.js +33 -7
- package/dist/parser.js.map +1 -1
- package/dist/resolver.d.ts +2 -0
- package/dist/resolver.js +60 -30
- package/dist/resolver.js.map +1 -1
- package/dist/status.d.ts +1 -1
- package/dist/status.js +5 -4
- package/dist/status.js.map +1 -1
- package/dist/ui.html +18 -5
- package/dist/ui.js +36 -11
- package/dist/ui.js.map +1 -1
- package/package.json +13 -4
- package/dist/autodetect.test.d.ts +0 -1
- package/dist/autodetect.test.js +0 -207
- package/dist/autodetect.test.js.map +0 -1
- package/dist/cli.test.d.ts +0 -1
- package/dist/cli.test.js +0 -310
- package/dist/cli.test.js.map +0 -1
- package/dist/index.test.d.ts +0 -1
- package/dist/index.test.js +0 -59
- package/dist/index.test.js.map +0 -1
- package/dist/iterate.test.d.ts +0 -1
- package/dist/iterate.test.js +0 -20
- package/dist/iterate.test.js.map +0 -1
- package/dist/loader.test.d.ts +0 -1
- package/dist/loader.test.js +0 -65
- package/dist/loader.test.js.map +0 -1
- package/dist/parser.test.d.ts +0 -1
- package/dist/parser.test.js +0 -93
- package/dist/parser.test.js.map +0 -1
- package/dist/resolver.test.d.ts +0 -1
- package/dist/resolver.test.js +0 -184
- package/dist/resolver.test.js.map +0 -1
- package/dist/sanitize.test.d.ts +0 -1
- package/dist/sanitize.test.js +0 -38
- package/dist/sanitize.test.js.map +0 -1
- package/dist/status.test.d.ts +0 -1
- package/dist/status.test.js +0 -33
- package/dist/status.test.js.map +0 -1
- package/dist/ui-bootstrap.test.d.ts +0 -1
- package/dist/ui-bootstrap.test.js +0 -479
- package/dist/ui-bootstrap.test.js.map +0 -1
- package/dist/ui-builder.test.d.ts +0 -1
- package/dist/ui-builder.test.js +0 -272
- package/dist/ui-builder.test.js.map +0 -1
- package/dist/ui-command-quoting.test.d.ts +0 -1
- package/dist/ui-command-quoting.test.js +0 -95
- package/dist/ui-command-quoting.test.js.map +0 -1
- package/dist/ui-harness.d.ts +0 -20
- package/dist/ui-harness.js +0 -40
- package/dist/ui-harness.js.map +0 -1
- package/dist/ui-harness.test.d.ts +0 -1
- package/dist/ui-harness.test.js +0 -30
- package/dist/ui-harness.test.js.map +0 -1
- package/dist/ui-inline.test.d.ts +0 -1
- package/dist/ui-inline.test.js +0 -90
- package/dist/ui-inline.test.js.map +0 -1
- package/dist/ui-interactions.test.d.ts +0 -1
- package/dist/ui-interactions.test.js +0 -489
- package/dist/ui-interactions.test.js.map +0 -1
- package/dist/ui.test.d.ts +0 -1
- package/dist/ui.test.js +0 -283
- package/dist/ui.test.js.map +0 -1
package/README.md
CHANGED
|
@@ -28,6 +28,8 @@ Works as a **CLI** and as a **skill** in Claude Code, Copilot, Goose, and Bob.
|
|
|
28
28
|
|
|
29
29
|
## Install
|
|
30
30
|
|
|
31
|
+
Requires Node.js 22 or newer.
|
|
32
|
+
|
|
31
33
|
### CLI
|
|
32
34
|
|
|
33
35
|
```bash
|
|
@@ -40,9 +42,29 @@ Or just run it without installing:
|
|
|
40
42
|
npx @hivecommons/promptargs help
|
|
41
43
|
```
|
|
42
44
|
|
|
43
|
-
### As
|
|
45
|
+
### As an Agent Skill
|
|
46
|
+
|
|
47
|
+
promptargs ships an [Agent Skill](https://agentskills.io/specification) at [`skills/promptargs/SKILL.md`](skills/promptargs/SKILL.md), loaded by GitHub Copilot (CLI, cloud agent, VS Code agent mode) and Claude Code.
|
|
48
|
+
|
|
49
|
+
**With the GitHub CLI** (2.90.0 or later):
|
|
50
|
+
```bash
|
|
51
|
+
gh skill install hivecommons/promptargs promptargs
|
|
52
|
+
```
|
|
53
|
+
|
|
54
|
+
**Manually** (copy the `skills/promptargs/` directory):
|
|
55
|
+
```bash
|
|
56
|
+
# Copilot
|
|
57
|
+
mkdir -p ~/.copilot/skills
|
|
58
|
+
cp -r skills/promptargs ~/.copilot/skills/
|
|
59
|
+
|
|
60
|
+
# Claude Code
|
|
61
|
+
mkdir -p ~/.claude/skills
|
|
62
|
+
cp -r skills/promptargs ~/.claude/skills/
|
|
63
|
+
```
|
|
64
|
+
|
|
65
|
+
Use `.github/skills/` or `.claude/skills/` inside a project instead to share it with your team.
|
|
44
66
|
|
|
45
|
-
|
|
67
|
+
### As a Slash Command (other tools)
|
|
46
68
|
|
|
47
69
|
**Claude Code:**
|
|
48
70
|
```bash
|
|
@@ -65,8 +87,6 @@ curl -o ~/.bob/skills/promptargs.md \
|
|
|
65
87
|
https://raw.githubusercontent.com/hivecommons/promptargs/main/.bob/skills/promptargs.md
|
|
66
88
|
```
|
|
67
89
|
|
|
68
|
-
**Copilot:** Automatically detected from `.github/copilot-instructions.md` when you clone this repo.
|
|
69
|
-
|
|
70
90
|
---
|
|
71
91
|
|
|
72
92
|
## Quick Start (3 steps)
|
|
@@ -124,6 +144,10 @@ A blank with a default looks like this: `{{name=hello}}` (promptargs extension)
|
|
|
124
144
|
|
|
125
145
|
Padding inside the braces is fine too — `{{ name }}` and `{{ name=hello }}` mean the same thing.
|
|
126
146
|
|
|
147
|
+
Names may use letters, digits, `_` and `-` (`{{file-name}}`). Dotted names such as `{{repo.owner}}` are rejected with an error — use `{{repo_owner}}`; the switch names `no-interactive`, `cross`, `json` and `status` are also rejected, as they are reserved for CLI switches. Likewise, the template file names `help`, `env`, `ui`, `init`, `list` and `show` are reserved for the subcommands of the same name; such a template is listed as unreachable by `promptargs list` (and `show` warns), because the subcommand always wins.
|
|
148
|
+
|
|
149
|
+
A default may appear on any occurrence of a blank (`{{name}} … {{name=hello}}`); if two occurrences give different defaults, the first one wins.
|
|
150
|
+
|
|
127
151
|
That's the basics. Mustache comments (`{{! ignore me}}`) work as documented and are safe to use.
|
|
128
152
|
|
|
129
153
|
Mustache **sections** (`{{#flag}}...{{/flag}}`) and **partials** (`{{>name}}`) are parsed too, but aren't practically usable yet: promptargs only resolves plain `{{name}}` / `{{name=default}}` tags from `--flag=value`, auto-detected context, defaults, or interactive fill — a section's condition name is never filled this way (so its content is always dropped, or always kept for an inverted `{{^name}}` section), and partial content is never supplied, so `{{>name}}` always expands to nothing. Stick to plain blanks and comments; avoid sections and partials for now.
|
|
@@ -222,6 +246,34 @@ promptargs "Review {{file}} for {{focus}}" \
|
|
|
222
246
|
✅ [3/3]: file=db.go focus=correctness
|
|
223
247
|
```
|
|
224
248
|
|
|
249
|
+
When arrays have different lengths, the number of runs is the length of the longest array, and shorter arrays repeat (cycle around):
|
|
250
|
+
|
|
251
|
+
```bash
|
|
252
|
+
promptargs "Review {{file}} for {{focus}}" \
|
|
253
|
+
--file=api.go,auth.go,db.go \
|
|
254
|
+
--focus=security
|
|
255
|
+
```
|
|
256
|
+
|
|
257
|
+
```
|
|
258
|
+
✅ [1/3]: file=api.go focus=security
|
|
259
|
+
✅ [2/3]: file=auth.go focus=security
|
|
260
|
+
✅ [3/3]: file=db.go focus=security
|
|
261
|
+
```
|
|
262
|
+
|
|
263
|
+
Or with two unequal arrays:
|
|
264
|
+
|
|
265
|
+
```bash
|
|
266
|
+
promptargs "Review {{file}} for {{focus}}" \
|
|
267
|
+
--file=a.go,b.go,c.go \
|
|
268
|
+
--focus=x,y
|
|
269
|
+
```
|
|
270
|
+
|
|
271
|
+
```
|
|
272
|
+
✅ [1/3]: file=a.go focus=x
|
|
273
|
+
✅ [2/3]: file=b.go focus=y
|
|
274
|
+
✅ [3/3]: file=c.go focus=x
|
|
275
|
+
```
|
|
276
|
+
|
|
225
277
|
**Cross-product mode (`--cross`):** every combination of every value:
|
|
226
278
|
|
|
227
279
|
```bash
|
|
@@ -245,12 +297,6 @@ promptargs "Review {{file}} for {{focus}}" \
|
|
|
245
297
|
|
|
246
298
|
3 files × 3 focuses = 9 runs. Use `--cross` when you want the full matrix.
|
|
247
299
|
|
|
248
|
-
By default, array iterations run one at a time and print as they finish. Add `--parallel` to run every iteration at once and print all results together:
|
|
249
|
-
|
|
250
|
-
```bash
|
|
251
|
-
promptargs review --file=api.go,auth.go,db.go --parallel
|
|
252
|
-
```
|
|
253
|
-
|
|
254
300
|
---
|
|
255
301
|
|
|
256
302
|
## Where Templates Live
|
|
@@ -262,6 +308,8 @@ promptargs review --file=api.go,auth.go,db.go --parallel
|
|
|
262
308
|
|
|
263
309
|
Project templates override personal ones with the same name.
|
|
264
310
|
|
|
311
|
+
Symlinked `*.md` entries are followed only when their real target is inside the same `.prompts/` directory (a sub-directory is fine); a symlink whose target escapes the directory is listed with an error and refused when run, so a cloned repo cannot make `promptargs` read files elsewhere on your machine. Symlinks to directories and dangling symlinks are skipped.
|
|
312
|
+
|
|
265
313
|
---
|
|
266
314
|
|
|
267
315
|
## Auto-Magic Variables ✨
|
|
@@ -375,10 +423,35 @@ promptargs does not collect or export telemetry. There is no telemetry SDK, metr
|
|
|
375
423
|
|
|
376
424
|
All runtime diagnostics are human-readable console output (CLI status/errors, UI startup/port messages). The **Builder UI** (`promptargs ui`) binds to loopback only (`127.0.0.1`) and rejects requests with a non-local `Host` header, so the page — including the auto-detected Git and terminal environment values it embeds (see [Auto-Magic Variables](#auto-magic-variables-)) — is never reachable from other machines on your network.
|
|
377
425
|
|
|
426
|
+
**Opt-in structured diagnostics:** set `PROMPTARGS_LOG=json` to make diagnostics (CLI errors and iteration progress, UI Host rejections, asset failures, unreadable prompts directories, and one line per UI request) print as JSON lines on stderr with a fixed field set: `event`, plus `status`, `duration_ms`, `error_class` (`usage`, `not_found`, `io`, `port_in_use`, `unknown`), `count`, `current`, `total` where relevant. Template contents, argument values, paths and error messages are never logged. When unset, output is unchanged. Nothing is sent over the network.
|
|
427
|
+
|
|
378
428
|
If observability is ever added in the future, it will be explicit opt-in, bounded to local diagnostics, and will exclude environment values, template/prompt content, file paths, diffs, and user identifiers. No network exporter will be added unless you explicitly configure a backend yourself.
|
|
379
429
|
|
|
380
430
|
---
|
|
381
431
|
|
|
432
|
+
## Use as a Library
|
|
433
|
+
|
|
434
|
+
The package also exports its building blocks as an ES module (Node.js 22+). Install it first with `npm install @hivecommons/promptargs`.
|
|
435
|
+
|
|
436
|
+
```js
|
|
437
|
+
import { parseVars, expand } from '@hivecommons/promptargs';
|
|
438
|
+
|
|
439
|
+
const template = 'Review {{file}} for {{focus=correctness}} issues.';
|
|
440
|
+
|
|
441
|
+
parseVars(template);
|
|
442
|
+
// [{ name: 'file', ... }, { name: 'focus', defaultValue: 'correctness', ... }]
|
|
443
|
+
|
|
444
|
+
expand(template, { file: 'src/app.ts', focus: 'security' });
|
|
445
|
+
// 'Review src/app.ts for security issues.'
|
|
446
|
+
|
|
447
|
+
expand(template, { file: 'src/app.ts' });
|
|
448
|
+
// 'Review src/app.ts for correctness issues.' (defaults fill missing values)
|
|
449
|
+
```
|
|
450
|
+
|
|
451
|
+
Variables with no value and no default are left as `{{name}}` in the output. Other exports: `autodetect`, `autodetectAll`, `AUTODETECT_VARS`, `loadTemplates`, `findTemplate`, `resolve` and `renderStatus`.
|
|
452
|
+
|
|
453
|
+
---
|
|
454
|
+
|
|
382
455
|
## Write Your Own Template
|
|
383
456
|
|
|
384
457
|
Create a file in `.prompts/` with any name ending in `.md`:
|
|
@@ -415,13 +488,13 @@ promptargs review --file=src/main.ts --no-interactive | claude -p "do this revie
|
|
|
415
488
|
# Goose
|
|
416
489
|
promptargs review --file=src/main.ts --no-interactive | goose run
|
|
417
490
|
|
|
418
|
-
# Copilot
|
|
419
|
-
promptargs review --file=src/main.ts --no-interactive
|
|
491
|
+
# Copilot CLI (needs the standalone `copilot` CLI, installed and signed in)
|
|
492
|
+
copilot -p "$(promptargs review --file=src/main.ts --no-interactive)"
|
|
420
493
|
```
|
|
421
494
|
|
|
422
495
|
### As a skill inside your AI tool
|
|
423
496
|
|
|
424
|
-
If you installed the skill (see [Install](#as-
|
|
497
|
+
If you installed the skill (see [Install](#as-an-agent-skill)), use it directly inside your session:
|
|
425
498
|
|
|
426
499
|
**Claude Code:**
|
|
427
500
|
```
|
|
@@ -430,7 +503,7 @@ If you installed the skill (see [Install](#as-a-skill)), use it directly inside
|
|
|
430
503
|
|
|
431
504
|
**Goose / Bob:** The skill is automatically available after install — ask your agent to "use promptargs" or run a template.
|
|
432
505
|
|
|
433
|
-
**Copilot:**
|
|
506
|
+
**Copilot:** Installed skills load automatically; ask Copilot to use promptargs.
|
|
434
507
|
|
|
435
508
|
---
|
|
436
509
|
|
|
@@ -448,12 +521,24 @@ If you installed the skill (see [Install](#as-a-skill)), use it directly inside
|
|
|
448
521
|
| `promptargs env` | Show auto-detected variable values |
|
|
449
522
|
| `--no-interactive` | Skip questions, use defaults only |
|
|
450
523
|
| `--cross` | Cross-product mode (all combinations) |
|
|
451
|
-
| `--parallel` | Run array iterations in parallel |
|
|
452
524
|
| `--json` | Output as JSON |
|
|
453
525
|
| `--status` | Output status line only |
|
|
454
526
|
| `... \| claude -p "do this"` | Pipe to Claude |
|
|
455
527
|
| `... \| goose run` | Pipe to Goose |
|
|
456
528
|
|
|
529
|
+
The switch names `no-interactive`, `cross`, `json` and `status` are reserved and cannot be used as template variable names.
|
|
530
|
+
|
|
531
|
+
---
|
|
532
|
+
|
|
533
|
+
## Contributing & Community
|
|
534
|
+
|
|
535
|
+
promptargs is part of [Hive Commons](https://hivecommons.dev), a family of tools for working with AI agents.
|
|
536
|
+
|
|
537
|
+
- Want to contribute? See [CONTRIBUTING.md](CONTRIBUTING.md) for setup, checks, and pull request guidelines.
|
|
538
|
+
- Found a bug or have an idea? Open an [issue](https://github.com/hivecommons/promptargs/issues).
|
|
539
|
+
- Reporting a security vulnerability? Follow [SECURITY.md](SECURITY.md) to report it privately, not through public issues.
|
|
540
|
+
- Please follow the [Hive Commons Code of Conduct](https://github.com/hivecommons/.github/blob/main/CODE_OF_CONDUCT.md).
|
|
541
|
+
|
|
457
542
|
---
|
|
458
543
|
|
|
459
544
|
## License
|
package/dist/autodetect.js
CHANGED
|
@@ -2,9 +2,20 @@
|
|
|
2
2
|
* Auto-detect variable values from the current environment.
|
|
3
3
|
*/
|
|
4
4
|
import { execSync } from 'node:child_process';
|
|
5
|
+
// gh is the only network call on the UI startup path; bound it so a stalled gh
|
|
6
|
+
// (hung proxy, expired auth) cannot hang startup.
|
|
7
|
+
const GH_TIMEOUT_MS = 5000;
|
|
8
|
+
// execSync's default 1 MiB maxBuffer makes `git diff` on a large staged change
|
|
9
|
+
// throw ENOBUFS, which the catch below turns into a silent "nothing detected"
|
|
10
|
+
// (#281). Raise it so large diffs are returned rather than dropped.
|
|
11
|
+
const GIT_MAX_BUFFER_BYTES = 64 * 1024 * 1024;
|
|
5
12
|
function git(cmd) {
|
|
6
13
|
try {
|
|
7
|
-
const out = execSync(`git ${cmd}`, {
|
|
14
|
+
const out = execSync(`git ${cmd}`, {
|
|
15
|
+
encoding: 'utf8',
|
|
16
|
+
stdio: ['pipe', 'pipe', 'pipe'],
|
|
17
|
+
maxBuffer: GIT_MAX_BUFFER_BYTES,
|
|
18
|
+
}).trim();
|
|
8
19
|
// Success with empty output (detached HEAD for `branch --show-current`,
|
|
9
20
|
// clean tree for `diff`) is "nothing detected", not an empty value —
|
|
10
21
|
// otherwise it would override the template default and skip the prompt.
|
|
@@ -36,6 +47,7 @@ const DETECTORS = {
|
|
|
36
47
|
const out = execSync('gh pr view --json number --jq .number', {
|
|
37
48
|
encoding: 'utf8',
|
|
38
49
|
stdio: ['pipe', 'pipe', 'pipe'],
|
|
50
|
+
timeout: GH_TIMEOUT_MS,
|
|
39
51
|
}).trim();
|
|
40
52
|
return out || undefined;
|
|
41
53
|
}
|
|
@@ -44,7 +56,7 @@ const DETECTORS = {
|
|
|
44
56
|
}
|
|
45
57
|
},
|
|
46
58
|
user: () => git('config user.name'),
|
|
47
|
-
date: () => new Date().
|
|
59
|
+
date: () => new Date().toLocaleDateString('sv-SE'),
|
|
48
60
|
};
|
|
49
61
|
export const AUTODETECT_VARS = Object.keys(DETECTORS);
|
|
50
62
|
// Env var names that look like credentials. The implicit process.env fallback
|
|
@@ -57,7 +69,7 @@ export const AUTODETECT_VARS = Object.keys(DETECTORS);
|
|
|
57
69
|
const SENSITIVE_ENV_PATTERN = new RegExp([
|
|
58
70
|
'TOKEN', 'SECRET', 'PASSWORD', 'PASSWD', 'PASSPHRASE', 'CREDENTIAL',
|
|
59
71
|
'API_?KEY', 'ACCESS_KEY', 'PRIVATE_KEY', 'BEARER', 'COOKIE', 'WEBHOOK',
|
|
60
|
-
'JWT', 'HMAC', 'OAUTH', 'CONN(?:ECTION)?_?STR(?:ING)?',
|
|
72
|
+
'JWT', 'HMAC', 'OAUTH', 'AUTHORI[SZ]ATION', 'CONN(?:ECTION)?_?STR(?:ING)?',
|
|
61
73
|
'(?:^|_)AUTH(?:_|$)', '(?:^|_)KEYS?(?:_|$)', '_PWD(?:_|$)',
|
|
62
74
|
'(?:^|_)PAT(?:_|$)', '(?:^|_)PASS(?:_|$)', '(?:^|_)DSN(?:_|$)',
|
|
63
75
|
].join('|'), 'i');
|
|
@@ -66,12 +78,14 @@ export function isSensitiveEnvName(name) {
|
|
|
66
78
|
}
|
|
67
79
|
// Values that are credentials regardless of what the variable is called:
|
|
68
80
|
// a URL carrying a password in its userinfo (DATABASE_URL, REDIS_URL,
|
|
69
|
-
// MONGO_URI, SENTRY_DSN), PEM blocks, JWTs,
|
|
70
|
-
// stamp on their tokens so
|
|
81
|
+
// MONGO_URI, SENTRY_DSN), PEM blocks, JWTs, HTTP Authorization header values
|
|
82
|
+
// (Bearer/Basic), and the fixed prefixes vendors stamp on their tokens so
|
|
83
|
+
// scanners can recognise them.
|
|
71
84
|
const SENSITIVE_ENV_VALUE_PATTERN = new RegExp([
|
|
72
85
|
'^[a-z][a-z0-9+.-]*://[^/\\s:@]*:[^/\\s@]+@',
|
|
73
86
|
'-----BEGIN ',
|
|
74
87
|
'^eyJ[\\w-]+\\.eyJ[\\w-]+\\.',
|
|
88
|
+
'^(?:Bearer|Basic)\\s+\\S+',
|
|
75
89
|
'^(?:gh[pousr]_|github_pat_)[A-Za-z0-9_]{20,}',
|
|
76
90
|
'^glpat-[\\w-]{20,}',
|
|
77
91
|
'^sk-[A-Za-z0-9_-]{20,}',
|
|
@@ -86,14 +100,15 @@ export function isSensitiveEnvValue(value) {
|
|
|
86
100
|
return SENSITIVE_ENV_VALUE_PATTERN.test(value);
|
|
87
101
|
}
|
|
88
102
|
export function autodetect(varName) {
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
103
|
+
// Own-property check: {{constructor}} / {{toString}} must not resolve to
|
|
104
|
+
// Object.prototype members.
|
|
105
|
+
if (Object.hasOwn(DETECTORS, varName))
|
|
106
|
+
return DETECTORS[varName]();
|
|
92
107
|
// Fall back to terminal environment variables — but never implicitly expand
|
|
93
108
|
// credential-looking names ({{GITHUB_TOKEN}} in a repo template must not
|
|
94
109
|
// exfiltrate secrets into the generated prompt) or credential-shaped values
|
|
95
110
|
// under innocuous names ({{DATABASE_URL}}). Explicit --flags still work.
|
|
96
|
-
if (isSensitiveEnvName(varName))
|
|
111
|
+
if (isSensitiveEnvName(varName) || !Object.hasOwn(process.env, varName))
|
|
97
112
|
return undefined;
|
|
98
113
|
const value = process.env[varName];
|
|
99
114
|
if (value === undefined || isSensitiveEnvValue(value))
|
package/dist/autodetect.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"autodetect.js","sourceRoot":"","sources":["../src/autodetect.ts"],"names":[],"mappings":"AAAA;;GAEG;AAEH,OAAO,EAAE,QAAQ,EAAE,MAAM,oBAAoB,CAAC;AAE9C,SAAS,GAAG,CAAC,GAAW;IACtB,IAAI,CAAC;QACH,MAAM,GAAG,GAAG,QAAQ,CAAC,OAAO,GAAG,EAAE,EAAE,
|
|
1
|
+
{"version":3,"file":"autodetect.js","sourceRoot":"","sources":["../src/autodetect.ts"],"names":[],"mappings":"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"}
|
package/dist/cli.js
CHANGED
|
@@ -9,15 +9,15 @@
|
|
|
9
9
|
* promptargs init # create .prompts/ with examples
|
|
10
10
|
* promptargs show <template> # show template with vars highlighted
|
|
11
11
|
*/
|
|
12
|
-
import {
|
|
13
|
-
import {
|
|
14
|
-
import { parseVars, expand, VAR_PATTERN } from './parser.js';
|
|
15
|
-
import { findTemplate, loadTemplates } from './loader.js';
|
|
12
|
+
import { parseVars, expand } from './parser.js';
|
|
13
|
+
import { findTemplate } from './loader.js';
|
|
16
14
|
import { resolve } from './resolver.js';
|
|
17
15
|
import { renderStatus } from './status.js';
|
|
18
|
-
import { autodetect, AUTODETECT_VARS } from './autodetect.js';
|
|
19
|
-
import { sanitizeForTerminal } from './sanitize.js';
|
|
20
16
|
import { startUI } from './ui.js';
|
|
17
|
+
import { UsageError, assertNoReservedVars, parseFlags, parsePort, SUBCOMMANDS } from './flags.js';
|
|
18
|
+
import { diag, classifyError } from './log.js';
|
|
19
|
+
import { doInit, doList, doShow, printEnv } from './commands.js';
|
|
20
|
+
import { sanitizeForTerminal } from './sanitize.js';
|
|
21
21
|
const HELP = `
|
|
22
22
|
promptargs — Template arguments for AI prompts 🏴☠️
|
|
23
23
|
|
|
@@ -34,9 +34,9 @@ Usage:
|
|
|
34
34
|
Flags:
|
|
35
35
|
--no-interactive Skip interactive prompts (use defaults/auto only)
|
|
36
36
|
--cross Cross-product mode: all combinations of array values
|
|
37
|
-
--parallel Run array iterations in parallel (print all at once)
|
|
38
37
|
--json Output as JSON instead of plain text
|
|
39
38
|
--status Print status line only (for IDE integration)
|
|
39
|
+
--var value Same as --var=value (switches above take no value)
|
|
40
40
|
|
|
41
41
|
Array values:
|
|
42
42
|
--file=a.go,b.go Comma-separated → one run per value
|
|
@@ -44,54 +44,48 @@ Array values:
|
|
|
44
44
|
--file=@list.txt File → one value per line
|
|
45
45
|
|
|
46
46
|
Iteration modes:
|
|
47
|
-
Default (zip): --file=a,b --focus=x,y → 2 runs (a+x, b+y)
|
|
47
|
+
Default (zip): --file=a,b --focus=x,y → 2 runs (a+x, b+y); shorter arrays repeat
|
|
48
48
|
Cross-product: --file=a,b --focus=x,y --cross → 4 runs (a+x, a+y, b+x, b+y)
|
|
49
49
|
|
|
50
50
|
Templates live in:
|
|
51
51
|
.prompts/ Project-level (checked into repo)
|
|
52
52
|
~/.prompts/ User-level (personal templates)
|
|
53
53
|
`;
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
54
|
+
// The shared set supplies the runtime gate and its names supply the key union.
|
|
55
|
+
// The Record makes adding a subcommand without a handler (or vice versa) a type error.
|
|
56
|
+
const SUBCOMMAND_HANDLERS = {
|
|
57
|
+
help: () => {
|
|
58
|
+
console.log(HELP);
|
|
59
|
+
printEnv();
|
|
60
|
+
},
|
|
61
|
+
env: () => printEnv(),
|
|
62
|
+
ui: (args) => {
|
|
63
|
+
const flags = parseFlags(args);
|
|
64
|
+
startUI(parsePort(flags));
|
|
65
|
+
},
|
|
66
|
+
init: () => doInit(),
|
|
67
|
+
list: () => doList(),
|
|
68
|
+
show: (args) => doShow(args[0]),
|
|
69
|
+
};
|
|
70
|
+
function isSubcommand(value) {
|
|
71
|
+
return SUBCOMMANDS.has(value);
|
|
72
|
+
}
|
|
65
73
|
async function main() {
|
|
66
74
|
const args = process.argv.slice(2);
|
|
67
|
-
if (args.length === 0 || args[0] === '
|
|
75
|
+
if (args.length === 0 || args[0] === '--help') {
|
|
68
76
|
console.log(HELP);
|
|
69
77
|
printEnv();
|
|
70
78
|
return;
|
|
71
79
|
}
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
}
|
|
76
|
-
if (args[0] === 'ui') {
|
|
77
|
-
const flags = parseFlags(args.slice(1));
|
|
78
|
-
const port = flags['port'] ? Number(flags['port']) : undefined;
|
|
79
|
-
startUI(port);
|
|
80
|
+
const command = args[0];
|
|
81
|
+
if (isSubcommand(command)) {
|
|
82
|
+
await SUBCOMMAND_HANDLERS[command](args.slice(1));
|
|
80
83
|
return;
|
|
81
84
|
}
|
|
82
|
-
if (args[0] === 'init') {
|
|
83
|
-
return doInit();
|
|
84
|
-
}
|
|
85
|
-
if (args[0] === 'list') {
|
|
86
|
-
return doList();
|
|
87
|
-
}
|
|
88
|
-
if (args[0] === 'show') {
|
|
89
|
-
return doShow(args[1]);
|
|
90
|
-
}
|
|
91
85
|
// Run a template
|
|
92
86
|
const templateName = args[0];
|
|
93
87
|
const flags = parseFlags(args.slice(1));
|
|
94
|
-
const interactive = !flags['no-interactive'];
|
|
88
|
+
const interactive = !flags['no-interactive'] && process.stdin.isTTY === true;
|
|
95
89
|
const cross = 'cross' in flags;
|
|
96
90
|
const asJson = 'json' in flags;
|
|
97
91
|
const statusOnly = 'status' in flags;
|
|
@@ -105,24 +99,31 @@ async function main() {
|
|
|
105
99
|
else {
|
|
106
100
|
const tpl = findTemplate(templateName);
|
|
107
101
|
if (!tpl) {
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
process.exit(1);
|
|
112
|
-
return;
|
|
102
|
+
throw new UsageError(`Template "${templateName}" not found.\n` +
|
|
103
|
+
'Run "promptargs list" to see available templates.\n' +
|
|
104
|
+
'Run "promptargs init" to create example templates.');
|
|
113
105
|
}
|
|
114
106
|
content = tpl.content;
|
|
115
107
|
name = tpl.name;
|
|
116
108
|
}
|
|
117
109
|
const vars = parseVars(content);
|
|
110
|
+
assertNoReservedVars(vars);
|
|
118
111
|
if (vars.length === 0) {
|
|
119
|
-
// No variables —
|
|
120
|
-
|
|
112
|
+
// No variables — skip expand() so Mustache-style content that is not a promptargs blank stays untouched
|
|
113
|
+
if (statusOnly) {
|
|
114
|
+
console.log(renderStatus(name, vars, {}, undefined, new Set()));
|
|
115
|
+
}
|
|
116
|
+
else if (asJson) {
|
|
117
|
+
console.log(JSON.stringify(content, null, 2));
|
|
118
|
+
}
|
|
119
|
+
else {
|
|
120
|
+
console.log(content);
|
|
121
|
+
}
|
|
121
122
|
return;
|
|
122
123
|
}
|
|
123
|
-
const { iterations } = await resolve(vars, flags, interactive, cross);
|
|
124
|
+
const { iterations, defaulted } = await resolve(vars, flags, interactive, cross);
|
|
124
125
|
if (statusOnly) {
|
|
125
|
-
const status = renderStatus(name, vars, iterations[0]);
|
|
126
|
+
const status = renderStatus(name, vars, iterations[0], undefined, defaulted);
|
|
126
127
|
console.log(status);
|
|
127
128
|
return;
|
|
128
129
|
}
|
|
@@ -134,8 +135,8 @@ async function main() {
|
|
|
134
135
|
const status = renderStatus(name, vars, values, {
|
|
135
136
|
current: i + 1,
|
|
136
137
|
total: iterations.length,
|
|
137
|
-
});
|
|
138
|
-
|
|
138
|
+
}, defaulted);
|
|
139
|
+
diag('cli_iteration', { current: i + 1, total: iterations.length }, status);
|
|
139
140
|
}
|
|
140
141
|
results.push(expanded);
|
|
141
142
|
}
|
|
@@ -146,105 +147,8 @@ async function main() {
|
|
|
146
147
|
console.log(results.join('\n---\n'));
|
|
147
148
|
}
|
|
148
149
|
}
|
|
149
|
-
function parseFlags(args) {
|
|
150
|
-
const flags = {};
|
|
151
|
-
for (const arg of args) {
|
|
152
|
-
if (arg.startsWith('--')) {
|
|
153
|
-
const eq = arg.indexOf('=');
|
|
154
|
-
if (eq > 0) {
|
|
155
|
-
flags[arg.slice(2, eq)] = arg.slice(eq + 1);
|
|
156
|
-
}
|
|
157
|
-
else {
|
|
158
|
-
flags[arg.slice(2)] = 'true';
|
|
159
|
-
}
|
|
160
|
-
}
|
|
161
|
-
}
|
|
162
|
-
return flags;
|
|
163
|
-
}
|
|
164
|
-
function doInit() {
|
|
165
|
-
const dir = join(process.cwd(), '.prompts');
|
|
166
|
-
if (existsSync(dir)) {
|
|
167
|
-
console.log('.prompts/ already exists!');
|
|
168
|
-
return;
|
|
169
|
-
}
|
|
170
|
-
mkdirSync(dir, { recursive: true });
|
|
171
|
-
writeFileSync(join(dir, 'review.md'), EXAMPLE_REVIEW);
|
|
172
|
-
writeFileSync(join(dir, 'explain.md'), EXAMPLE_EXPLAIN);
|
|
173
|
-
writeFileSync(join(dir, 'fix.md'), EXAMPLE_FIX);
|
|
174
|
-
console.log('Created .prompts/ with 3 example templates:');
|
|
175
|
-
console.log(' review.md — Code review with focus area');
|
|
176
|
-
console.log(' explain.md — Explain code simply');
|
|
177
|
-
console.log(' fix.md — Bug fix template');
|
|
178
|
-
console.log('');
|
|
179
|
-
console.log('Try it: promptargs review --file=src/main.ts');
|
|
180
|
-
}
|
|
181
|
-
function doList() {
|
|
182
|
-
const templates = loadTemplates();
|
|
183
|
-
if (templates.length === 0) {
|
|
184
|
-
console.log('No templates found.');
|
|
185
|
-
console.log('Run "promptargs init" to create example templates.');
|
|
186
|
-
return;
|
|
187
|
-
}
|
|
188
|
-
console.log('Available templates:\n');
|
|
189
|
-
for (const t of templates) {
|
|
190
|
-
const vars = parseVars(t.content);
|
|
191
|
-
const varNames = vars.map(v => {
|
|
192
|
-
if (v.defaultValue !== undefined)
|
|
193
|
-
return `${v.name}=${v.defaultValue}`;
|
|
194
|
-
return v.name;
|
|
195
|
-
});
|
|
196
|
-
const source = t.source === 'user' ? ' (user)' : '';
|
|
197
|
-
console.log(sanitizeForTerminal(` ${t.name}${source}`));
|
|
198
|
-
console.log(sanitizeForTerminal(` vars: {{${varNames.join('}} {{')}}}`));
|
|
199
|
-
console.log('');
|
|
200
|
-
}
|
|
201
|
-
}
|
|
202
|
-
function doShow(templateName) {
|
|
203
|
-
if (!templateName) {
|
|
204
|
-
console.error('Usage: promptargs show <template>');
|
|
205
|
-
process.exit(1);
|
|
206
|
-
return;
|
|
207
|
-
}
|
|
208
|
-
const tpl = findTemplate(templateName);
|
|
209
|
-
if (!tpl) {
|
|
210
|
-
console.error(`Template "${templateName}" not found.`);
|
|
211
|
-
process.exit(1);
|
|
212
|
-
return;
|
|
213
|
-
}
|
|
214
|
-
// Sanitize first: templates are repo-controlled and must not be able to
|
|
215
|
-
// inject their own terminal escapes; only our highlighting below may.
|
|
216
|
-
const highlighted = sanitizeForTerminal(tpl.content).replace(VAR_PATTERN, (raw, _varName, defaultVal) => {
|
|
217
|
-
// Colour the tag exactly as written so padded tags ({{ name }}) are
|
|
218
|
-
// shown as the author typed them.
|
|
219
|
-
if (defaultVal !== undefined) {
|
|
220
|
-
return `\x1b[33m${raw}\x1b[0m`;
|
|
221
|
-
}
|
|
222
|
-
return `\x1b[31m${raw}\x1b[0m`;
|
|
223
|
-
});
|
|
224
|
-
console.log(sanitizeForTerminal(`Template: ${tpl.name} (${tpl.path})`) + '\n');
|
|
225
|
-
console.log(highlighted);
|
|
226
|
-
console.log('\n\x1b[31mred\x1b[0m = required \x1b[33myellow\x1b[0m = has default');
|
|
227
|
-
}
|
|
228
|
-
const DIFF_PREVIEW_MAX_CHARS = 60;
|
|
229
|
-
function printEnv() {
|
|
230
|
-
console.log('Auto-detected variables:\n');
|
|
231
|
-
for (const name of AUTODETECT_VARS) {
|
|
232
|
-
const value = autodetect(name);
|
|
233
|
-
if (value !== undefined) {
|
|
234
|
-
let display = value;
|
|
235
|
-
if (name === 'diff' && display.length > DIFF_PREVIEW_MAX_CHARS) {
|
|
236
|
-
display = display.slice(0, DIFF_PREVIEW_MAX_CHARS) + '...';
|
|
237
|
-
}
|
|
238
|
-
console.log(` \x1b[32m{{${name}}}\x1b[0m = ${sanitizeForTerminal(display)}`);
|
|
239
|
-
}
|
|
240
|
-
else {
|
|
241
|
-
console.log(` \x1b[90m{{${name}}}\x1b[0m = (not detected)`);
|
|
242
|
-
}
|
|
243
|
-
}
|
|
244
|
-
console.log('');
|
|
245
|
-
}
|
|
246
150
|
main().catch(err => {
|
|
247
|
-
|
|
151
|
+
diag('cli_error', { error_class: classifyError(err) }, sanitizeForTerminal(String(err.message)));
|
|
248
152
|
process.exit(1);
|
|
249
153
|
});
|
|
250
154
|
//# sourceMappingURL=cli.js.map
|
package/dist/cli.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"cli.js","sourceRoot":"","sources":["../src/cli.ts"],"names":[],"mappings":";AAEA;;;;;;;;;GASG;
|
|
1
|
+
{"version":3,"file":"cli.js","sourceRoot":"","sources":["../src/cli.ts"],"names":[],"mappings":"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"}
|