@hivecommons/promptargs 0.6.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/LICENSE +190 -0
- package/README.md +423 -0
- package/dist/autodetect.d.ts +6 -0
- package/dist/autodetect.js +62 -0
- package/dist/autodetect.js.map +1 -0
- package/dist/cli.d.ts +12 -0
- package/dist/cli.js +245 -0
- package/dist/cli.js.map +1 -0
- package/dist/index.d.ts +8 -0
- package/dist/index.js +6 -0
- package/dist/index.js.map +1 -0
- package/dist/loader.d.ts +11 -0
- package/dist/loader.js +36 -0
- package/dist/loader.js.map +1 -0
- package/dist/parser.d.ts +11 -0
- package/dist/parser.js +41 -0
- package/dist/parser.js.map +1 -0
- package/dist/parser.test.d.ts +1 -0
- package/dist/parser.test.js +56 -0
- package/dist/parser.test.js.map +1 -0
- package/dist/resolver.d.ts +10 -0
- package/dist/resolver.js +133 -0
- package/dist/resolver.js.map +1 -0
- package/dist/status.d.ts +9 -0
- package/dist/status.js +22 -0
- package/dist/status.js.map +1 -0
- package/dist/ui.d.ts +1 -0
- package/dist/ui.html +1065 -0
- package/dist/ui.js +85 -0
- package/dist/ui.js.map +1 -0
- package/package.json +51 -0
package/dist/cli.js
ADDED
|
@@ -0,0 +1,245 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
/**
|
|
3
|
+
* promptargs CLI — Template arguments for AI prompts.
|
|
4
|
+
*
|
|
5
|
+
* Usage:
|
|
6
|
+
* promptargs <template> # interactive mode
|
|
7
|
+
* promptargs <template> --var=value # fill from flags
|
|
8
|
+
* promptargs list # show available templates
|
|
9
|
+
* promptargs init # create .prompts/ with examples
|
|
10
|
+
* promptargs show <template> # show template with vars highlighted
|
|
11
|
+
*/
|
|
12
|
+
import { mkdirSync, writeFileSync, existsSync } from 'node:fs';
|
|
13
|
+
import { join } from 'node:path';
|
|
14
|
+
import { parseVars, expand } from './parser.js';
|
|
15
|
+
import { findTemplate, loadTemplates } from './loader.js';
|
|
16
|
+
import { resolve } from './resolver.js';
|
|
17
|
+
import { renderStatus } from './status.js';
|
|
18
|
+
import { autodetect, AUTODETECT_VARS } from './autodetect.js';
|
|
19
|
+
import { startUI } from './ui.js';
|
|
20
|
+
const HELP = `
|
|
21
|
+
promptargs — Template arguments for AI prompts 🏴☠️
|
|
22
|
+
|
|
23
|
+
Usage:
|
|
24
|
+
promptargs <template> Run a template (interactive)
|
|
25
|
+
promptargs <template> --var=value Fill variables from flags
|
|
26
|
+
promptargs list Show available templates
|
|
27
|
+
promptargs init Create .prompts/ with examples
|
|
28
|
+
promptargs show <template> Preview a template
|
|
29
|
+
promptargs env Show auto-detected variable values
|
|
30
|
+
promptargs ui Open the builder UI in your browser
|
|
31
|
+
promptargs help Show this help
|
|
32
|
+
|
|
33
|
+
Flags:
|
|
34
|
+
--no-interactive Skip interactive prompts (use defaults/auto only)
|
|
35
|
+
--cross Cross-product mode: all combinations of array values
|
|
36
|
+
--parallel Run array iterations in parallel (print all at once)
|
|
37
|
+
--json Output as JSON instead of plain text
|
|
38
|
+
--status Print status line only (for IDE integration)
|
|
39
|
+
|
|
40
|
+
Array values:
|
|
41
|
+
--file=a.go,b.go Comma-separated → one run per value
|
|
42
|
+
--file="src/*.go" Glob → expands to matching files
|
|
43
|
+
--file=@list.txt File → one value per line
|
|
44
|
+
|
|
45
|
+
Iteration modes:
|
|
46
|
+
Default (zip): --file=a,b --focus=x,y → 2 runs (a+x, b+y)
|
|
47
|
+
Cross-product: --file=a,b --focus=x,y --cross → 4 runs (a+x, a+y, b+x, b+y)
|
|
48
|
+
|
|
49
|
+
Templates live in:
|
|
50
|
+
.prompts/ Project-level (checked into repo)
|
|
51
|
+
~/.prompts/ User-level (personal templates)
|
|
52
|
+
`;
|
|
53
|
+
const EXAMPLE_REVIEW = `Review {{file}} for {{focus=correctness}} issues.
|
|
54
|
+
Be {{tone=concise}} in your feedback.
|
|
55
|
+
Focus on real bugs, not style nitpicks.
|
|
56
|
+
`;
|
|
57
|
+
const EXAMPLE_EXPLAIN = `Explain what {{file}} does in {{style=simple}} terms.
|
|
58
|
+
Assume the reader is a {{audience=junior developer}}.
|
|
59
|
+
`;
|
|
60
|
+
const EXAMPLE_FIX = `Fix the {{issue}} in {{file}}.
|
|
61
|
+
The expected behavior is: {{expected}}
|
|
62
|
+
The actual behavior is: {{actual}}
|
|
63
|
+
`;
|
|
64
|
+
async function main() {
|
|
65
|
+
const args = process.argv.slice(2);
|
|
66
|
+
if (args.length === 0 || args[0] === 'help' || args[0] === '--help') {
|
|
67
|
+
console.log(HELP);
|
|
68
|
+
printEnv();
|
|
69
|
+
return;
|
|
70
|
+
}
|
|
71
|
+
if (args[0] === 'env') {
|
|
72
|
+
printEnv();
|
|
73
|
+
return;
|
|
74
|
+
}
|
|
75
|
+
if (args[0] === 'ui') {
|
|
76
|
+
const flags = parseFlags(args.slice(1));
|
|
77
|
+
const port = flags['port'] ? Number(flags['port']) : undefined;
|
|
78
|
+
startUI(port);
|
|
79
|
+
return;
|
|
80
|
+
}
|
|
81
|
+
if (args[0] === 'init') {
|
|
82
|
+
return doInit();
|
|
83
|
+
}
|
|
84
|
+
if (args[0] === 'list') {
|
|
85
|
+
return doList();
|
|
86
|
+
}
|
|
87
|
+
if (args[0] === 'show') {
|
|
88
|
+
return doShow(args[1]);
|
|
89
|
+
}
|
|
90
|
+
// Run a template
|
|
91
|
+
const templateName = args[0];
|
|
92
|
+
const flags = parseFlags(args.slice(1));
|
|
93
|
+
const interactive = !flags['no-interactive'];
|
|
94
|
+
const cross = 'cross' in flags;
|
|
95
|
+
const asJson = 'json' in flags;
|
|
96
|
+
const statusOnly = 'status' in flags;
|
|
97
|
+
// Check for inline template (quoted string with {{vars}})
|
|
98
|
+
let content;
|
|
99
|
+
let name;
|
|
100
|
+
if (templateName.includes('{{')) {
|
|
101
|
+
content = templateName;
|
|
102
|
+
name = 'inline';
|
|
103
|
+
}
|
|
104
|
+
else {
|
|
105
|
+
const tpl = findTemplate(templateName);
|
|
106
|
+
if (!tpl) {
|
|
107
|
+
console.error(`Template "${templateName}" not found.`);
|
|
108
|
+
console.error('Run "promptargs list" to see available templates.');
|
|
109
|
+
console.error('Run "promptargs init" to create example templates.');
|
|
110
|
+
process.exit(1);
|
|
111
|
+
return;
|
|
112
|
+
}
|
|
113
|
+
content = tpl.content;
|
|
114
|
+
name = tpl.name;
|
|
115
|
+
}
|
|
116
|
+
const vars = parseVars(content);
|
|
117
|
+
if (vars.length === 0) {
|
|
118
|
+
// No variables — just output the template as-is
|
|
119
|
+
console.log(content);
|
|
120
|
+
return;
|
|
121
|
+
}
|
|
122
|
+
const { iterations } = await resolve(vars, flags, interactive, cross);
|
|
123
|
+
if (statusOnly) {
|
|
124
|
+
const status = renderStatus(name, vars, iterations[0]);
|
|
125
|
+
console.log(status);
|
|
126
|
+
return;
|
|
127
|
+
}
|
|
128
|
+
const results = [];
|
|
129
|
+
for (let i = 0; i < iterations.length; i++) {
|
|
130
|
+
const values = iterations[i];
|
|
131
|
+
const expanded = expand(content, values);
|
|
132
|
+
if (iterations.length > 1) {
|
|
133
|
+
const status = renderStatus(name, vars, values, {
|
|
134
|
+
current: i + 1,
|
|
135
|
+
total: iterations.length,
|
|
136
|
+
});
|
|
137
|
+
console.error(status);
|
|
138
|
+
}
|
|
139
|
+
results.push(expanded);
|
|
140
|
+
}
|
|
141
|
+
if (asJson) {
|
|
142
|
+
console.log(JSON.stringify(results.length === 1 ? results[0] : results, null, 2));
|
|
143
|
+
}
|
|
144
|
+
else {
|
|
145
|
+
console.log(results.join('\n---\n'));
|
|
146
|
+
}
|
|
147
|
+
}
|
|
148
|
+
function parseFlags(args) {
|
|
149
|
+
const flags = {};
|
|
150
|
+
for (const arg of args) {
|
|
151
|
+
if (arg.startsWith('--')) {
|
|
152
|
+
const eq = arg.indexOf('=');
|
|
153
|
+
if (eq > 0) {
|
|
154
|
+
flags[arg.slice(2, eq)] = arg.slice(eq + 1);
|
|
155
|
+
}
|
|
156
|
+
else {
|
|
157
|
+
flags[arg.slice(2)] = 'true';
|
|
158
|
+
}
|
|
159
|
+
}
|
|
160
|
+
}
|
|
161
|
+
return flags;
|
|
162
|
+
}
|
|
163
|
+
function doInit() {
|
|
164
|
+
const dir = join(process.cwd(), '.prompts');
|
|
165
|
+
if (existsSync(dir)) {
|
|
166
|
+
console.log('.prompts/ already exists!');
|
|
167
|
+
return;
|
|
168
|
+
}
|
|
169
|
+
mkdirSync(dir, { recursive: true });
|
|
170
|
+
writeFileSync(join(dir, 'review.md'), EXAMPLE_REVIEW);
|
|
171
|
+
writeFileSync(join(dir, 'explain.md'), EXAMPLE_EXPLAIN);
|
|
172
|
+
writeFileSync(join(dir, 'fix.md'), EXAMPLE_FIX);
|
|
173
|
+
console.log('Created .prompts/ with 3 example templates:');
|
|
174
|
+
console.log(' review.md — Code review with focus area');
|
|
175
|
+
console.log(' explain.md — Explain code simply');
|
|
176
|
+
console.log(' fix.md — Bug fix template');
|
|
177
|
+
console.log('');
|
|
178
|
+
console.log('Try it: promptargs review --file=src/main.ts');
|
|
179
|
+
}
|
|
180
|
+
function doList() {
|
|
181
|
+
const templates = loadTemplates();
|
|
182
|
+
if (templates.length === 0) {
|
|
183
|
+
console.log('No templates found.');
|
|
184
|
+
console.log('Run "promptargs init" to create example templates.');
|
|
185
|
+
return;
|
|
186
|
+
}
|
|
187
|
+
console.log('Available templates:\n');
|
|
188
|
+
for (const t of templates) {
|
|
189
|
+
const vars = parseVars(t.content);
|
|
190
|
+
const varNames = vars.map(v => {
|
|
191
|
+
if (v.defaultValue !== undefined)
|
|
192
|
+
return `${v.name}=${v.defaultValue}`;
|
|
193
|
+
return v.name;
|
|
194
|
+
});
|
|
195
|
+
const source = t.source === 'user' ? ' (user)' : '';
|
|
196
|
+
console.log(` ${t.name}${source}`);
|
|
197
|
+
console.log(` vars: {{${varNames.join('}} {{')}}}`);
|
|
198
|
+
console.log('');
|
|
199
|
+
}
|
|
200
|
+
}
|
|
201
|
+
function doShow(templateName) {
|
|
202
|
+
if (!templateName) {
|
|
203
|
+
console.error('Usage: promptargs show <template>');
|
|
204
|
+
process.exit(1);
|
|
205
|
+
return;
|
|
206
|
+
}
|
|
207
|
+
const tpl = findTemplate(templateName);
|
|
208
|
+
if (!tpl) {
|
|
209
|
+
console.error(`Template "${templateName}" not found.`);
|
|
210
|
+
process.exit(1);
|
|
211
|
+
return;
|
|
212
|
+
}
|
|
213
|
+
const highlighted = tpl.content.replace(/\{\{(\w+)(?:=([^}]*))?\}\}/g, (_m, varName, defaultVal) => {
|
|
214
|
+
if (defaultVal !== undefined) {
|
|
215
|
+
return `\x1b[33m{{${varName}=${defaultVal}}}\x1b[0m`;
|
|
216
|
+
}
|
|
217
|
+
return `\x1b[31m{{${varName}}}\x1b[0m`;
|
|
218
|
+
});
|
|
219
|
+
console.log(`Template: ${tpl.name} (${tpl.path})\n`);
|
|
220
|
+
console.log(highlighted);
|
|
221
|
+
console.log('\n\x1b[31mred\x1b[0m = required \x1b[33myellow\x1b[0m = has default');
|
|
222
|
+
}
|
|
223
|
+
const DIFF_PREVIEW_MAX_CHARS = 60;
|
|
224
|
+
function printEnv() {
|
|
225
|
+
console.log('Auto-detected variables:\n');
|
|
226
|
+
for (const name of AUTODETECT_VARS) {
|
|
227
|
+
const value = autodetect(name);
|
|
228
|
+
if (value !== undefined) {
|
|
229
|
+
let display = value;
|
|
230
|
+
if (name === 'diff' && display.length > DIFF_PREVIEW_MAX_CHARS) {
|
|
231
|
+
display = display.slice(0, DIFF_PREVIEW_MAX_CHARS) + '...';
|
|
232
|
+
}
|
|
233
|
+
console.log(` \x1b[32m{{${name}}}\x1b[0m = ${display}`);
|
|
234
|
+
}
|
|
235
|
+
else {
|
|
236
|
+
console.log(` \x1b[90m{{${name}}}\x1b[0m = (not detected)`);
|
|
237
|
+
}
|
|
238
|
+
}
|
|
239
|
+
console.log('');
|
|
240
|
+
}
|
|
241
|
+
main().catch(err => {
|
|
242
|
+
console.error(err.message);
|
|
243
|
+
process.exit(1);
|
|
244
|
+
});
|
|
245
|
+
//# sourceMappingURL=cli.js.map
|
package/dist/cli.js.map
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"cli.js","sourceRoot":"","sources":["../src/cli.ts"],"names":[],"mappings":"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"}
|
package/dist/index.d.ts
ADDED
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
export { parseVars, expand } from './parser.js';
|
|
2
|
+
export type { TemplateVar } from './parser.js';
|
|
3
|
+
export { autodetect, autodetectAll, AUTODETECT_VARS } from './autodetect.js';
|
|
4
|
+
export { loadTemplates, findTemplate } from './loader.js';
|
|
5
|
+
export type { PromptTemplate } from './loader.js';
|
|
6
|
+
export { resolve } from './resolver.js';
|
|
7
|
+
export type { ResolvedValues } from './resolver.js';
|
|
8
|
+
export { renderStatus } from './status.js';
|
package/dist/index.js
ADDED
|
@@ -0,0 +1,6 @@
|
|
|
1
|
+
export { parseVars, expand } from './parser.js';
|
|
2
|
+
export { autodetect, autodetectAll, AUTODETECT_VARS } from './autodetect.js';
|
|
3
|
+
export { loadTemplates, findTemplate } from './loader.js';
|
|
4
|
+
export { resolve } from './resolver.js';
|
|
5
|
+
export { renderStatus } from './status.js';
|
|
6
|
+
//# sourceMappingURL=index.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,SAAS,EAAE,MAAM,EAAE,MAAM,aAAa,CAAC;AAEhD,OAAO,EAAE,UAAU,EAAE,aAAa,EAAE,eAAe,EAAE,MAAM,iBAAiB,CAAC;AAC7E,OAAO,EAAE,aAAa,EAAE,YAAY,EAAE,MAAM,aAAa,CAAC;AAE1D,OAAO,EAAE,OAAO,EAAE,MAAM,eAAe,CAAC;AAExC,OAAO,EAAE,YAAY,EAAE,MAAM,aAAa,CAAC"}
|
package/dist/loader.d.ts
ADDED
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Find and load prompt templates from .prompts/ directories.
|
|
3
|
+
*/
|
|
4
|
+
export interface PromptTemplate {
|
|
5
|
+
name: string;
|
|
6
|
+
content: string;
|
|
7
|
+
path: string;
|
|
8
|
+
source: 'project' | 'user';
|
|
9
|
+
}
|
|
10
|
+
export declare function loadTemplates(cwd?: string): PromptTemplate[];
|
|
11
|
+
export declare function findTemplate(name: string, cwd?: string): PromptTemplate | undefined;
|
package/dist/loader.js
ADDED
|
@@ -0,0 +1,36 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Find and load prompt templates from .prompts/ directories.
|
|
3
|
+
*/
|
|
4
|
+
import { readFileSync, readdirSync, existsSync } from 'node:fs';
|
|
5
|
+
import { join, basename, extname } from 'node:path';
|
|
6
|
+
import { homedir } from 'node:os';
|
|
7
|
+
const PROJECT_DIR = '.prompts';
|
|
8
|
+
const USER_DIR = join(homedir(), '.prompts');
|
|
9
|
+
function loadFromDir(dir, source) {
|
|
10
|
+
if (!existsSync(dir))
|
|
11
|
+
return [];
|
|
12
|
+
return readdirSync(dir)
|
|
13
|
+
.filter((f) => f.endsWith('.md'))
|
|
14
|
+
.map((f) => ({
|
|
15
|
+
name: basename(f, extname(f)),
|
|
16
|
+
content: readFileSync(join(dir, f), 'utf8'),
|
|
17
|
+
path: join(dir, f),
|
|
18
|
+
source,
|
|
19
|
+
}));
|
|
20
|
+
}
|
|
21
|
+
export function loadTemplates(cwd) {
|
|
22
|
+
const projectDir = join(cwd || process.cwd(), PROJECT_DIR);
|
|
23
|
+
const projectTemplates = loadFromDir(projectDir, 'project');
|
|
24
|
+
const userTemplates = loadFromDir(USER_DIR, 'user');
|
|
25
|
+
// Project templates override user templates with same name
|
|
26
|
+
const byName = new Map();
|
|
27
|
+
for (const t of userTemplates)
|
|
28
|
+
byName.set(t.name, t);
|
|
29
|
+
for (const t of projectTemplates)
|
|
30
|
+
byName.set(t.name, t);
|
|
31
|
+
return Array.from(byName.values());
|
|
32
|
+
}
|
|
33
|
+
export function findTemplate(name, cwd) {
|
|
34
|
+
return loadTemplates(cwd).find(t => t.name === name);
|
|
35
|
+
}
|
|
36
|
+
//# sourceMappingURL=loader.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"loader.js","sourceRoot":"","sources":["../src/loader.ts"],"names":[],"mappings":"AAAA;;GAEG;AAEH,OAAO,EAAE,YAAY,EAAE,WAAW,EAAE,UAAU,EAAE,MAAM,SAAS,CAAC;AAChE,OAAO,EAAE,IAAI,EAAE,QAAQ,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AACpD,OAAO,EAAE,OAAO,EAAE,MAAM,SAAS,CAAC;AAElC,MAAM,WAAW,GAAG,UAAU,CAAC;AAC/B,MAAM,QAAQ,GAAG,IAAI,CAAC,OAAO,EAAE,EAAE,UAAU,CAAC,CAAC;AAS7C,SAAS,WAAW,CAAC,GAAW,EAAE,MAA0B;IAC1D,IAAI,CAAC,UAAU,CAAC,GAAG,CAAC;QAAE,OAAO,EAAE,CAAC;IAEhC,OAAO,WAAW,CAAC,GAAG,CAAC;SACpB,MAAM,CAAC,CAAC,CAAS,EAAE,EAAE,CAAC,CAAC,CAAC,QAAQ,CAAC,KAAK,CAAC,CAAC;SACxC,GAAG,CAAC,CAAC,CAAS,EAAE,EAAE,CAAC,CAAC;QACnB,IAAI,EAAE,QAAQ,CAAC,CAAC,EAAE,OAAO,CAAC,CAAC,CAAC,CAAC;QAC7B,OAAO,EAAE,YAAY,CAAC,IAAI,CAAC,GAAG,EAAE,CAAC,CAAC,EAAE,MAAM,CAAC;QAC3C,IAAI,EAAE,IAAI,CAAC,GAAG,EAAE,CAAC,CAAC;QAClB,MAAM;KACP,CAAC,CAAC,CAAC;AACR,CAAC;AAED,MAAM,UAAU,aAAa,CAAC,GAAY;IACxC,MAAM,UAAU,GAAG,IAAI,CAAC,GAAG,IAAI,OAAO,CAAC,GAAG,EAAE,EAAE,WAAW,CAAC,CAAC;IAC3D,MAAM,gBAAgB,GAAG,WAAW,CAAC,UAAU,EAAE,SAAS,CAAC,CAAC;IAC5D,MAAM,aAAa,GAAG,WAAW,CAAC,QAAQ,EAAE,MAAM,CAAC,CAAC;IAEpD,2DAA2D;IAC3D,MAAM,MAAM,GAAG,IAAI,GAAG,EAA0B,CAAC;IACjD,KAAK,MAAM,CAAC,IAAI,aAAa;QAAE,MAAM,CAAC,GAAG,CAAC,CAAC,CAAC,IAAI,EAAE,CAAC,CAAC,CAAC;IACrD,KAAK,MAAM,CAAC,IAAI,gBAAgB;QAAE,MAAM,CAAC,GAAG,CAAC,CAAC,CAAC,IAAI,EAAE,CAAC,CAAC,CAAC;IAExD,OAAO,KAAK,CAAC,IAAI,CAAC,MAAM,CAAC,MAAM,EAAE,CAAC,CAAC;AACrC,CAAC;AAED,MAAM,UAAU,YAAY,CAAC,IAAY,EAAE,GAAY;IACrD,OAAO,aAAa,CAAC,GAAG,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,IAAI,KAAK,IAAI,CAAC,CAAC;AACvD,CAAC"}
|
package/dist/parser.d.ts
ADDED
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Parse {{variables}} and {{variables=defaults}} from template strings.
|
|
3
|
+
* Uses Mustache for expansion, with a promptargs extension for defaults.
|
|
4
|
+
*/
|
|
5
|
+
export interface TemplateVar {
|
|
6
|
+
name: string;
|
|
7
|
+
defaultValue?: string;
|
|
8
|
+
raw: string;
|
|
9
|
+
}
|
|
10
|
+
export declare function parseVars(template: string): TemplateVar[];
|
|
11
|
+
export declare function expand(template: string, values: Record<string, string>): string;
|
package/dist/parser.js
ADDED
|
@@ -0,0 +1,41 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Parse {{variables}} and {{variables=defaults}} from template strings.
|
|
3
|
+
* Uses Mustache for expansion, with a promptargs extension for defaults.
|
|
4
|
+
*/
|
|
5
|
+
import Mustache from 'mustache';
|
|
6
|
+
const VAR_PATTERN = /\{\{(\w+)(?:=([^}]*))?\}\}/g;
|
|
7
|
+
export function parseVars(template) {
|
|
8
|
+
const seen = new Set();
|
|
9
|
+
const vars = [];
|
|
10
|
+
for (const match of template.matchAll(VAR_PATTERN)) {
|
|
11
|
+
const name = match[1];
|
|
12
|
+
if (seen.has(name))
|
|
13
|
+
continue;
|
|
14
|
+
seen.add(name);
|
|
15
|
+
vars.push({
|
|
16
|
+
name,
|
|
17
|
+
defaultValue: match[2],
|
|
18
|
+
raw: match[0],
|
|
19
|
+
});
|
|
20
|
+
}
|
|
21
|
+
return vars;
|
|
22
|
+
}
|
|
23
|
+
export function expand(template, values) {
|
|
24
|
+
const vars = parseVars(template);
|
|
25
|
+
const view = { ...values };
|
|
26
|
+
for (const v of vars) {
|
|
27
|
+
if (!(v.name in view) && v.defaultValue !== undefined) {
|
|
28
|
+
view[v.name] = v.defaultValue;
|
|
29
|
+
}
|
|
30
|
+
// Preserve unfilled vars as {{name}} in output
|
|
31
|
+
if (!(v.name in view)) {
|
|
32
|
+
view[v.name] = `{{${v.name}}}`;
|
|
33
|
+
}
|
|
34
|
+
}
|
|
35
|
+
// Convert {{var=default}} to {{var}} so Mustache can handle it
|
|
36
|
+
const normalized = template.replace(VAR_PATTERN, (_match, name) => `{{${name}}}`);
|
|
37
|
+
// Disable HTML escaping — we want raw text output
|
|
38
|
+
Mustache.escape = (text) => text;
|
|
39
|
+
return Mustache.render(normalized, view);
|
|
40
|
+
}
|
|
41
|
+
//# sourceMappingURL=parser.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"parser.js","sourceRoot":"","sources":["../src/parser.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAEH,OAAO,QAAQ,MAAM,UAAU,CAAC;AAQhC,MAAM,WAAW,GAAG,6BAA6B,CAAC;AAElD,MAAM,UAAU,SAAS,CAAC,QAAgB;IACxC,MAAM,IAAI,GAAG,IAAI,GAAG,EAAU,CAAC;IAC/B,MAAM,IAAI,GAAkB,EAAE,CAAC;IAE/B,KAAK,MAAM,KAAK,IAAI,QAAQ,CAAC,QAAQ,CAAC,WAAW,CAAC,EAAE,CAAC;QACnD,MAAM,IAAI,GAAG,KAAK,CAAC,CAAC,CAAC,CAAC;QACtB,IAAI,IAAI,CAAC,GAAG,CAAC,IAAI,CAAC;YAAE,SAAS;QAC7B,IAAI,CAAC,GAAG,CAAC,IAAI,CAAC,CAAC;QACf,IAAI,CAAC,IAAI,CAAC;YACR,IAAI;YACJ,YAAY,EAAE,KAAK,CAAC,CAAC,CAAC;YACtB,GAAG,EAAE,KAAK,CAAC,CAAC,CAAC;SACd,CAAC,CAAC;IACL,CAAC;IAED,OAAO,IAAI,CAAC;AACd,CAAC;AAED,MAAM,UAAU,MAAM,CAAC,QAAgB,EAAE,MAA8B;IACrE,MAAM,IAAI,GAAG,SAAS,CAAC,QAAQ,CAAC,CAAC;IACjC,MAAM,IAAI,GAA2B,EAAE,GAAG,MAAM,EAAE,CAAC;IAEnD,KAAK,MAAM,CAAC,IAAI,IAAI,EAAE,CAAC;QACrB,IAAI,CAAC,CAAC,CAAC,CAAC,IAAI,IAAI,IAAI,CAAC,IAAI,CAAC,CAAC,YAAY,KAAK,SAAS,EAAE,CAAC;YACtD,IAAI,CAAC,CAAC,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC,YAAY,CAAC;QAChC,CAAC;QACD,+CAA+C;QAC/C,IAAI,CAAC,CAAC,CAAC,CAAC,IAAI,IAAI,IAAI,CAAC,EAAE,CAAC;YACtB,IAAI,CAAC,CAAC,CAAC,IAAI,CAAC,GAAG,KAAK,CAAC,CAAC,IAAI,IAAI,CAAC;QACjC,CAAC;IACH,CAAC;IAED,+DAA+D;IAC/D,MAAM,UAAU,GAAG,QAAQ,CAAC,OAAO,CAAC,WAAW,EAAE,CAAC,MAAM,EAAE,IAAY,EAAE,EAAE,CAAC,KAAK,IAAI,IAAI,CAAC,CAAC;IAE1F,kDAAkD;IAClD,QAAQ,CAAC,MAAM,GAAG,CAAC,IAAY,EAAE,EAAE,CAAC,IAAI,CAAC;IAEzC,OAAO,QAAQ,CAAC,MAAM,CAAC,UAAU,EAAE,IAAI,CAAC,CAAC;AAC3C,CAAC"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export {};
|
|
@@ -0,0 +1,56 @@
|
|
|
1
|
+
import { describe, it } from 'node:test';
|
|
2
|
+
import assert from 'node:assert';
|
|
3
|
+
import { parseVars, expand } from './parser.js';
|
|
4
|
+
describe('parseVars', () => {
|
|
5
|
+
it('finds simple variables', () => {
|
|
6
|
+
const vars = parseVars('Hello {{name}}, welcome to {{place}}');
|
|
7
|
+
assert.strictEqual(vars.length, 2);
|
|
8
|
+
assert.strictEqual(vars[0].name, 'name');
|
|
9
|
+
assert.strictEqual(vars[1].name, 'place');
|
|
10
|
+
});
|
|
11
|
+
it('finds variables with defaults', () => {
|
|
12
|
+
const vars = parseVars('Be {{tone=concise}} please');
|
|
13
|
+
assert.strictEqual(vars.length, 1);
|
|
14
|
+
assert.strictEqual(vars[0].name, 'tone');
|
|
15
|
+
assert.strictEqual(vars[0].defaultValue, 'concise');
|
|
16
|
+
});
|
|
17
|
+
it('deduplicates variables', () => {
|
|
18
|
+
const vars = parseVars('{{name}} said hi to {{name}}');
|
|
19
|
+
assert.strictEqual(vars.length, 1);
|
|
20
|
+
});
|
|
21
|
+
it('returns empty for no variables', () => {
|
|
22
|
+
const vars = parseVars('No variables here');
|
|
23
|
+
assert.strictEqual(vars.length, 0);
|
|
24
|
+
});
|
|
25
|
+
});
|
|
26
|
+
describe('expand', () => {
|
|
27
|
+
it('substitutes values', () => {
|
|
28
|
+
const result = expand('Hello {{name}}!', { name: 'World' });
|
|
29
|
+
assert.strictEqual(result, 'Hello World!');
|
|
30
|
+
});
|
|
31
|
+
it('uses defaults when no value provided', () => {
|
|
32
|
+
const result = expand('Be {{tone=concise}}', {});
|
|
33
|
+
assert.strictEqual(result, 'Be concise');
|
|
34
|
+
});
|
|
35
|
+
it('overrides defaults with provided values', () => {
|
|
36
|
+
const result = expand('Be {{tone=concise}}', { tone: 'verbose' });
|
|
37
|
+
assert.strictEqual(result, 'Be verbose');
|
|
38
|
+
});
|
|
39
|
+
it('leaves unfilled vars as-is', () => {
|
|
40
|
+
const result = expand('Hello {{name}}', {});
|
|
41
|
+
assert.strictEqual(result, 'Hello {{name}}');
|
|
42
|
+
});
|
|
43
|
+
it('handles multiple vars', () => {
|
|
44
|
+
const result = expand('Review {{file}} for {{focus=correctness}}. Be {{tone=concise}}.', { file: 'main.go' });
|
|
45
|
+
assert.strictEqual(result, 'Review main.go for correctness. Be concise.');
|
|
46
|
+
});
|
|
47
|
+
it('handles arrays in comma-separated values', () => {
|
|
48
|
+
const result = expand('Check {{file}}', { file: 'a.go' });
|
|
49
|
+
assert.strictEqual(result, 'Check a.go');
|
|
50
|
+
});
|
|
51
|
+
it('does not HTML-escape values', () => {
|
|
52
|
+
const result = expand('{{code}}', { code: '<div class="test">' });
|
|
53
|
+
assert.strictEqual(result, '<div class="test">');
|
|
54
|
+
});
|
|
55
|
+
});
|
|
56
|
+
//# sourceMappingURL=parser.test.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"parser.test.js","sourceRoot":"","sources":["../src/parser.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,MAAM,EAAE,MAAM,aAAa,CAAC;AAEhD,QAAQ,CAAC,WAAW,EAAE,GAAG,EAAE;IACzB,EAAE,CAAC,wBAAwB,EAAE,GAAG,EAAE;QAChC,MAAM,IAAI,GAAG,SAAS,CAAC,sCAAsC,CAAC,CAAC;QAC/D,MAAM,CAAC,WAAW,CAAC,IAAI,CAAC,MAAM,EAAE,CAAC,CAAC,CAAC;QACnC,MAAM,CAAC,WAAW,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,IAAI,EAAE,MAAM,CAAC,CAAC;QACzC,MAAM,CAAC,WAAW,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,IAAI,EAAE,OAAO,CAAC,CAAC;IAC5C,CAAC,CAAC,CAAC;IAEH,EAAE,CAAC,+BAA+B,EAAE,GAAG,EAAE;QACvC,MAAM,IAAI,GAAG,SAAS,CAAC,4BAA4B,CAAC,CAAC;QACrD,MAAM,CAAC,WAAW,CAAC,IAAI,CAAC,MAAM,EAAE,CAAC,CAAC,CAAC;QACnC,MAAM,CAAC,WAAW,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,IAAI,EAAE,MAAM,CAAC,CAAC;QACzC,MAAM,CAAC,WAAW,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,YAAY,EAAE,SAAS,CAAC,CAAC;IACtD,CAAC,CAAC,CAAC;IAEH,EAAE,CAAC,wBAAwB,EAAE,GAAG,EAAE;QAChC,MAAM,IAAI,GAAG,SAAS,CAAC,8BAA8B,CAAC,CAAC;QACvD,MAAM,CAAC,WAAW,CAAC,IAAI,CAAC,MAAM,EAAE,CAAC,CAAC,CAAC;IACrC,CAAC,CAAC,CAAC;IAEH,EAAE,CAAC,gCAAgC,EAAE,GAAG,EAAE;QACxC,MAAM,IAAI,GAAG,SAAS,CAAC,mBAAmB,CAAC,CAAC;QAC5C,MAAM,CAAC,WAAW,CAAC,IAAI,CAAC,MAAM,EAAE,CAAC,CAAC,CAAC;IACrC,CAAC,CAAC,CAAC;AACL,CAAC,CAAC,CAAC;AAEH,QAAQ,CAAC,QAAQ,EAAE,GAAG,EAAE;IACtB,EAAE,CAAC,oBAAoB,EAAE,GAAG,EAAE;QAC5B,MAAM,MAAM,GAAG,MAAM,CAAC,iBAAiB,EAAE,EAAE,IAAI,EAAE,OAAO,EAAE,CAAC,CAAC;QAC5D,MAAM,CAAC,WAAW,CAAC,MAAM,EAAE,cAAc,CAAC,CAAC;IAC7C,CAAC,CAAC,CAAC;IAEH,EAAE,CAAC,sCAAsC,EAAE,GAAG,EAAE;QAC9C,MAAM,MAAM,GAAG,MAAM,CAAC,qBAAqB,EAAE,EAAE,CAAC,CAAC;QACjD,MAAM,CAAC,WAAW,CAAC,MAAM,EAAE,YAAY,CAAC,CAAC;IAC3C,CAAC,CAAC,CAAC;IAEH,EAAE,CAAC,yCAAyC,EAAE,GAAG,EAAE;QACjD,MAAM,MAAM,GAAG,MAAM,CAAC,qBAAqB,EAAE,EAAE,IAAI,EAAE,SAAS,EAAE,CAAC,CAAC;QAClE,MAAM,CAAC,WAAW,CAAC,MAAM,EAAE,YAAY,CAAC,CAAC;IAC3C,CAAC,CAAC,CAAC;IAEH,EAAE,CAAC,4BAA4B,EAAE,GAAG,EAAE;QACpC,MAAM,MAAM,GAAG,MAAM,CAAC,gBAAgB,EAAE,EAAE,CAAC,CAAC;QAC5C,MAAM,CAAC,WAAW,CAAC,MAAM,EAAE,gBAAgB,CAAC,CAAC;IAC/C,CAAC,CAAC,CAAC;IAEH,EAAE,CAAC,uBAAuB,EAAE,GAAG,EAAE;QAC/B,MAAM,MAAM,GAAG,MAAM,CACnB,iEAAiE,EACjE,EAAE,IAAI,EAAE,SAAS,EAAE,CACpB,CAAC;QACF,MAAM,CAAC,WAAW,CAAC,MAAM,EAAE,6CAA6C,CAAC,CAAC;IAC5E,CAAC,CAAC,CAAC;IAEH,EAAE,CAAC,0CAA0C,EAAE,GAAG,EAAE;QAClD,MAAM,MAAM,GAAG,MAAM,CAAC,gBAAgB,EAAE,EAAE,IAAI,EAAE,MAAM,EAAE,CAAC,CAAC;QAC1D,MAAM,CAAC,WAAW,CAAC,MAAM,EAAE,YAAY,CAAC,CAAC;IAC3C,CAAC,CAAC,CAAC;IAEH,EAAE,CAAC,6BAA6B,EAAE,GAAG,EAAE;QACrC,MAAM,MAAM,GAAG,MAAM,CAAC,UAAU,EAAE,EAAE,IAAI,EAAE,oBAAoB,EAAE,CAAC,CAAC;QAClE,MAAM,CAAC,WAAW,CAAC,MAAM,EAAE,oBAAoB,CAAC,CAAC;IACnD,CAAC,CAAC,CAAC;AACL,CAAC,CAAC,CAAC"}
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Resolve variable values: flags → auto-detect → defaults → ask.
|
|
3
|
+
* Handles array expansion (comma-separated, globs, @file, stdin).
|
|
4
|
+
*/
|
|
5
|
+
import type { TemplateVar } from './parser.js';
|
|
6
|
+
export interface ResolvedValues {
|
|
7
|
+
values: Record<string, string>;
|
|
8
|
+
iterations: Record<string, string>[];
|
|
9
|
+
}
|
|
10
|
+
export declare function resolve(vars: TemplateVar[], flags: Record<string, string>, interactive: boolean, cross?: boolean): Promise<ResolvedValues>;
|
package/dist/resolver.js
ADDED
|
@@ -0,0 +1,133 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Resolve variable values: flags → auto-detect → defaults → ask.
|
|
3
|
+
* Handles array expansion (comma-separated, globs, @file, stdin).
|
|
4
|
+
*/
|
|
5
|
+
import { createInterface } from 'node:readline';
|
|
6
|
+
import { readFileSync, existsSync } from 'node:fs';
|
|
7
|
+
import { execSync } from 'node:child_process';
|
|
8
|
+
import { autodetect } from './autodetect.js';
|
|
9
|
+
function expandArrayValue(raw) {
|
|
10
|
+
// @file — read lines from file
|
|
11
|
+
if (raw.startsWith('@') && existsSync(raw.slice(1))) {
|
|
12
|
+
return readFileSync(raw.slice(1), 'utf8')
|
|
13
|
+
.split('\n')
|
|
14
|
+
.map((l) => l.trim())
|
|
15
|
+
.filter(Boolean);
|
|
16
|
+
}
|
|
17
|
+
// - (stdin) handled at CLI level before this
|
|
18
|
+
if (raw === '-')
|
|
19
|
+
return [raw];
|
|
20
|
+
// Glob pattern
|
|
21
|
+
if (raw.includes('*') || raw.includes('?')) {
|
|
22
|
+
try {
|
|
23
|
+
const files = execSync(`ls -1 ${raw}`, { encoding: 'utf8', stdio: ['pipe', 'pipe', 'pipe'] })
|
|
24
|
+
.trim()
|
|
25
|
+
.split('\n')
|
|
26
|
+
.filter(Boolean);
|
|
27
|
+
if (files.length > 0)
|
|
28
|
+
return files;
|
|
29
|
+
}
|
|
30
|
+
catch {
|
|
31
|
+
// Not a valid glob, treat as literal
|
|
32
|
+
}
|
|
33
|
+
}
|
|
34
|
+
// Comma-separated
|
|
35
|
+
if (raw.includes(',')) {
|
|
36
|
+
return raw.split(',').map(s => s.trim()).filter(Boolean);
|
|
37
|
+
}
|
|
38
|
+
return [raw];
|
|
39
|
+
}
|
|
40
|
+
function cartesian(arrays) {
|
|
41
|
+
if (arrays.length === 0)
|
|
42
|
+
return [[]];
|
|
43
|
+
const [first, ...rest] = arrays;
|
|
44
|
+
const restCombos = cartesian(rest);
|
|
45
|
+
const result = [];
|
|
46
|
+
for (const val of first) {
|
|
47
|
+
for (const combo of restCombos) {
|
|
48
|
+
result.push([val, ...combo]);
|
|
49
|
+
}
|
|
50
|
+
}
|
|
51
|
+
return result;
|
|
52
|
+
}
|
|
53
|
+
export async function resolve(vars, flags, interactive, cross = false) {
|
|
54
|
+
const values = {};
|
|
55
|
+
const arrayVars = {};
|
|
56
|
+
let hasArrays = false;
|
|
57
|
+
for (const v of vars) {
|
|
58
|
+
// 1. Check flags
|
|
59
|
+
if (v.name in flags) {
|
|
60
|
+
const expanded = expandArrayValue(flags[v.name]);
|
|
61
|
+
if (expanded.length > 1) {
|
|
62
|
+
arrayVars[v.name] = expanded;
|
|
63
|
+
hasArrays = true;
|
|
64
|
+
}
|
|
65
|
+
else {
|
|
66
|
+
values[v.name] = expanded[0];
|
|
67
|
+
}
|
|
68
|
+
continue;
|
|
69
|
+
}
|
|
70
|
+
// 2. Auto-detect
|
|
71
|
+
const auto = autodetect(v.name);
|
|
72
|
+
if (auto !== undefined) {
|
|
73
|
+
values[v.name] = auto;
|
|
74
|
+
continue;
|
|
75
|
+
}
|
|
76
|
+
// 3. Default
|
|
77
|
+
if (v.defaultValue !== undefined) {
|
|
78
|
+
values[v.name] = v.defaultValue;
|
|
79
|
+
continue;
|
|
80
|
+
}
|
|
81
|
+
// 4. Ask interactively
|
|
82
|
+
if (interactive) {
|
|
83
|
+
const answer = await ask(` ${v.name}: `);
|
|
84
|
+
const expanded = expandArrayValue(answer);
|
|
85
|
+
if (expanded.length > 1) {
|
|
86
|
+
arrayVars[v.name] = expanded;
|
|
87
|
+
hasArrays = true;
|
|
88
|
+
}
|
|
89
|
+
else {
|
|
90
|
+
values[v.name] = expanded[0];
|
|
91
|
+
}
|
|
92
|
+
}
|
|
93
|
+
}
|
|
94
|
+
// Build iterations
|
|
95
|
+
if (!hasArrays) {
|
|
96
|
+
return { values, iterations: [values] };
|
|
97
|
+
}
|
|
98
|
+
const arrayNames = Object.keys(arrayVars);
|
|
99
|
+
const iterations = [];
|
|
100
|
+
if (cross) {
|
|
101
|
+
const arrays = arrayNames.map(n => arrayVars[n]);
|
|
102
|
+
const combos = cartesian(arrays);
|
|
103
|
+
for (const combo of combos) {
|
|
104
|
+
const iter = { ...values };
|
|
105
|
+
for (let j = 0; j < arrayNames.length; j++) {
|
|
106
|
+
iter[arrayNames[j]] = combo[j];
|
|
107
|
+
}
|
|
108
|
+
iterations.push(iter);
|
|
109
|
+
}
|
|
110
|
+
}
|
|
111
|
+
else {
|
|
112
|
+
const maxLen = Math.max(...arrayNames.map(n => arrayVars[n].length));
|
|
113
|
+
for (let i = 0; i < maxLen; i++) {
|
|
114
|
+
const iter = { ...values };
|
|
115
|
+
for (const name of arrayNames) {
|
|
116
|
+
const arr = arrayVars[name];
|
|
117
|
+
iter[name] = arr[i % arr.length];
|
|
118
|
+
}
|
|
119
|
+
iterations.push(iter);
|
|
120
|
+
}
|
|
121
|
+
}
|
|
122
|
+
return { values, iterations };
|
|
123
|
+
}
|
|
124
|
+
function ask(prompt) {
|
|
125
|
+
const rl = createInterface({ input: process.stdin, output: process.stderr });
|
|
126
|
+
return new Promise(resolve => {
|
|
127
|
+
rl.question(prompt, (answer) => {
|
|
128
|
+
rl.close();
|
|
129
|
+
resolve(answer.trim());
|
|
130
|
+
});
|
|
131
|
+
});
|
|
132
|
+
}
|
|
133
|
+
//# sourceMappingURL=resolver.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"resolver.js","sourceRoot":"","sources":["../src/resolver.ts"],"names":[],"mappings":"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"}
|
package/dist/status.d.ts
ADDED
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Status line rendering for Claude Code's status area.
|
|
3
|
+
* Shows current template state: filled vars, unfilled vars, progress.
|
|
4
|
+
*/
|
|
5
|
+
import type { TemplateVar } from './parser.js';
|
|
6
|
+
export declare function renderStatus(templateName: string, vars: TemplateVar[], values: Record<string, string>, iteration?: {
|
|
7
|
+
current: number;
|
|
8
|
+
total: number;
|
|
9
|
+
}): string;
|
package/dist/status.js
ADDED
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Status line rendering for Claude Code's status area.
|
|
3
|
+
* Shows current template state: filled vars, unfilled vars, progress.
|
|
4
|
+
*/
|
|
5
|
+
export function renderStatus(templateName, vars, values, iteration) {
|
|
6
|
+
const parts = [];
|
|
7
|
+
for (const v of vars) {
|
|
8
|
+
const val = values[v.name];
|
|
9
|
+
if (val !== undefined) {
|
|
10
|
+
const source = v.defaultValue === val ? '(default)' : '';
|
|
11
|
+
parts.push(`${v.name}=${val}${source}`);
|
|
12
|
+
}
|
|
13
|
+
else {
|
|
14
|
+
parts.push(`${v.name}=___`);
|
|
15
|
+
}
|
|
16
|
+
}
|
|
17
|
+
const allFilled = vars.every(v => v.name in values);
|
|
18
|
+
const icon = allFilled ? '✅' : '📋';
|
|
19
|
+
const progress = iteration ? ` [${iteration.current}/${iteration.total}]` : '';
|
|
20
|
+
return `${icon} ${templateName}${progress}: ${parts.join(' ')}`;
|
|
21
|
+
}
|
|
22
|
+
//# sourceMappingURL=status.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"status.js","sourceRoot":"","sources":["../src/status.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAIH,MAAM,UAAU,YAAY,CAC1B,YAAoB,EACpB,IAAmB,EACnB,MAA8B,EAC9B,SAA8C;IAE9C,MAAM,KAAK,GAAa,EAAE,CAAC;IAE3B,KAAK,MAAM,CAAC,IAAI,IAAI,EAAE,CAAC;QACrB,MAAM,GAAG,GAAG,MAAM,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC;QAC3B,IAAI,GAAG,KAAK,SAAS,EAAE,CAAC;YACtB,MAAM,MAAM,GAAG,CAAC,CAAC,YAAY,KAAK,GAAG,CAAC,CAAC,CAAC,WAAW,CAAC,CAAC,CAAC,EAAE,CAAC;YACzD,KAAK,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC,IAAI,IAAI,GAAG,GAAG,MAAM,EAAE,CAAC,CAAC;QAC1C,CAAC;aAAM,CAAC;YACN,KAAK,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC,IAAI,MAAM,CAAC,CAAC;QAC9B,CAAC;IACH,CAAC;IAED,MAAM,SAAS,GAAG,IAAI,CAAC,KAAK,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,IAAI,IAAI,MAAM,CAAC,CAAC;IACpD,MAAM,IAAI,GAAG,SAAS,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,IAAI,CAAC;IACpC,MAAM,QAAQ,GAAG,SAAS,CAAC,CAAC,CAAC,KAAK,SAAS,CAAC,OAAO,IAAI,SAAS,CAAC,KAAK,GAAG,CAAC,CAAC,CAAC,EAAE,CAAC;IAE/E,OAAO,GAAG,IAAI,IAAI,YAAY,GAAG,QAAQ,KAAK,KAAK,CAAC,IAAI,CAAC,IAAI,CAAC,EAAE,CAAC;AACnE,CAAC"}
|
package/dist/ui.d.ts
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export declare function startUI(port?: number): void;
|