promptarch 1.0.2 → 1.0.4
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/dist/index.js +59 -35
- package/package.json +1 -1
package/dist/index.js
CHANGED
|
@@ -4,7 +4,7 @@
|
|
|
4
4
|
import { Command } from "commander";
|
|
5
5
|
|
|
6
6
|
// src/commands/init.ts
|
|
7
|
-
import { access, mkdir as mkdir2, writeFile as writeFile2 } from "fs/promises";
|
|
7
|
+
import { access, mkdir as mkdir2, readdir as readdir2, writeFile as writeFile2 } from "fs/promises";
|
|
8
8
|
import { dirname, join as join3, resolve } from "path";
|
|
9
9
|
|
|
10
10
|
// ../packages/core/context-model/types.ts
|
|
@@ -243,17 +243,21 @@ var STACK_HINTS = [
|
|
|
243
243
|
[/^vitest$|^jest$/, "unit tests"],
|
|
244
244
|
[/^@playwright\/test$|^playwright$/, "Playwright E2E"]
|
|
245
245
|
];
|
|
246
|
+
var FIELD_MAX = 1900;
|
|
247
|
+
function clampField(s) {
|
|
248
|
+
return s.length > FIELD_MAX ? `${s.slice(0, FIELD_MAX - 1)}\u2026` : s;
|
|
249
|
+
}
|
|
246
250
|
async function extractRepo(cwd) {
|
|
247
251
|
const pkg = await readJson(join(cwd, "package.json"));
|
|
248
252
|
const name = pkg?.name || basename(cwd);
|
|
249
253
|
const description = pkg?.description || await firstReadmeParagraph(cwd) || "";
|
|
250
254
|
return {
|
|
251
|
-
name,
|
|
252
|
-
description,
|
|
253
|
-
techStack: await detectStack(cwd, pkg),
|
|
254
|
-
tree: await buildTree(cwd),
|
|
255
|
-
commands: await detectCommands(cwd, pkg),
|
|
256
|
-
conventions: await readExistingConfig(cwd)
|
|
255
|
+
name: clampField(name),
|
|
256
|
+
description: clampField(description),
|
|
257
|
+
techStack: clampField(await detectStack(cwd, pkg)),
|
|
258
|
+
tree: clampField(await buildTree(cwd)),
|
|
259
|
+
commands: clampField(await detectCommands(cwd, pkg)),
|
|
260
|
+
conventions: clampField(await readExistingConfig(cwd))
|
|
257
261
|
};
|
|
258
262
|
}
|
|
259
263
|
async function readJson(path) {
|
|
@@ -447,6 +451,26 @@ async function fileExists(path) {
|
|
|
447
451
|
return false;
|
|
448
452
|
}
|
|
449
453
|
}
|
|
454
|
+
var STATIC_OUTPUTS = [
|
|
455
|
+
"AGENTS.md",
|
|
456
|
+
"CLAUDE.md",
|
|
457
|
+
".github/copilot-instructions.md"
|
|
458
|
+
];
|
|
459
|
+
var OUTPUT_DIRS = [".cursor/rules", ".github/instructions"];
|
|
460
|
+
async function existingOutputs(outDir) {
|
|
461
|
+
const hits = [];
|
|
462
|
+
for (const p of STATIC_OUTPUTS) {
|
|
463
|
+
if (await fileExists(join3(outDir, p))) hits.push(p);
|
|
464
|
+
}
|
|
465
|
+
for (const d of OUTPUT_DIRS) {
|
|
466
|
+
try {
|
|
467
|
+
const entries = await readdir2(join3(outDir, d));
|
|
468
|
+
if (entries.length > 0) hits.push(`${d}/ (${entries.length} file(s))`);
|
|
469
|
+
} catch {
|
|
470
|
+
}
|
|
471
|
+
}
|
|
472
|
+
return hits;
|
|
473
|
+
}
|
|
450
474
|
async function initCmd(opts) {
|
|
451
475
|
const cwd = process.cwd();
|
|
452
476
|
const info = await extractRepo(cwd);
|
|
@@ -477,6 +501,29 @@ async function initCmd(opts) {
|
|
|
477
501
|
process.exitCode = 1;
|
|
478
502
|
return;
|
|
479
503
|
}
|
|
504
|
+
const outDir = opts.out ? resolve(cwd, opts.out) : cwd;
|
|
505
|
+
if (!opts.force) {
|
|
506
|
+
const existing = await existingOutputs(outDir);
|
|
507
|
+
if (existing.length > 0) {
|
|
508
|
+
console.log(
|
|
509
|
+
`
|
|
510
|
+
init writes agent config files into ${outDir}, overwriting:
|
|
511
|
+
${existing.join("\n ")}`
|
|
512
|
+
);
|
|
513
|
+
if (!process.stdin.isTTY) {
|
|
514
|
+
console.error(
|
|
515
|
+
"\nAborted (non-interactive). Re-run with --force to overwrite, or --out <dir> to write elsewhere."
|
|
516
|
+
);
|
|
517
|
+
process.exitCode = 1;
|
|
518
|
+
return;
|
|
519
|
+
}
|
|
520
|
+
const ok = await confirm("\nContinue? Generating uses one credit. [y/N]");
|
|
521
|
+
if (!ok) {
|
|
522
|
+
console.log("Aborted. No credit used, no files written.");
|
|
523
|
+
return;
|
|
524
|
+
}
|
|
525
|
+
}
|
|
526
|
+
}
|
|
480
527
|
const url = `${resolveApiUrl(cfg)}/api/build`;
|
|
481
528
|
let res;
|
|
482
529
|
try {
|
|
@@ -504,7 +551,10 @@ async function initCmd(opts) {
|
|
|
504
551
|
return;
|
|
505
552
|
}
|
|
506
553
|
if (!res.ok) {
|
|
507
|
-
|
|
554
|
+
const detail = await res.json().catch(() => null);
|
|
555
|
+
console.error(
|
|
556
|
+
`Build failed (HTTP ${res.status})${detail?.error ? `: ${detail.error}` : ""}.`
|
|
557
|
+
);
|
|
508
558
|
process.exitCode = 1;
|
|
509
559
|
return;
|
|
510
560
|
}
|
|
@@ -516,32 +566,6 @@ async function initCmd(opts) {
|
|
|
516
566
|
}
|
|
517
567
|
const pack = parseContextModel(body.prompt);
|
|
518
568
|
const files = exportPack(pack, ALL_EXPORT_FORMATS);
|
|
519
|
-
const outDir = opts.out ? resolve(cwd, opts.out) : cwd;
|
|
520
|
-
if (!opts.force) {
|
|
521
|
-
const existing = [];
|
|
522
|
-
for (const f of files) {
|
|
523
|
-
if (await fileExists(join3(outDir, f.path))) existing.push(f.path);
|
|
524
|
-
}
|
|
525
|
-
if (existing.length > 0) {
|
|
526
|
-
console.log(
|
|
527
|
-
`
|
|
528
|
-
These file(s) already exist in ${outDir}:
|
|
529
|
-
${existing.join("\n ")}`
|
|
530
|
-
);
|
|
531
|
-
if (!process.stdin.isTTY) {
|
|
532
|
-
console.error(
|
|
533
|
-
"\nAborted (non-interactive). Re-run with --force to overwrite, or --out <dir> to write elsewhere."
|
|
534
|
-
);
|
|
535
|
-
process.exitCode = 1;
|
|
536
|
-
return;
|
|
537
|
-
}
|
|
538
|
-
const ok = await confirm("\nOverwrite them? [y/N]");
|
|
539
|
-
if (!ok) {
|
|
540
|
-
console.log("Aborted. No files written.");
|
|
541
|
-
return;
|
|
542
|
-
}
|
|
543
|
-
}
|
|
544
|
-
}
|
|
545
569
|
for (const f of files) {
|
|
546
570
|
const dest = join3(outDir, f.path);
|
|
547
571
|
await mkdir2(dirname(dest), { recursive: true });
|
|
@@ -1057,7 +1081,7 @@ async function login(opts) {
|
|
|
1057
1081
|
var program = new Command();
|
|
1058
1082
|
program.name("promptarch").description(
|
|
1059
1083
|
"Generate and lint AI coding-agent context files (CLAUDE.md, AGENTS.md, Cursor rules) from your repo."
|
|
1060
|
-
).version("1.0.
|
|
1084
|
+
).version("1.0.4");
|
|
1061
1085
|
program.command("login").description("Store a PromptArch API key (pk_...) in ~/.config/promptarch").option("--key <key>", "API key (non-interactive; for CI)").action(login);
|
|
1062
1086
|
program.command("lint").description("Lint agent context files offline (deterministic, free, CI-friendly)").argument("<files...>", "Files to lint (CLAUDE.md, AGENTS.md, *.mdc, ...)").option("--strict", "Fail on warnings too, not just errors").action((files, opts) => lintCmd(files, opts));
|
|
1063
1087
|
program.command("init").description("Extract repo context and generate CLAUDE.md / AGENTS.md / Cursor / Copilot files").option("--dry-run", "Print the extracted payload without calling the API").option("--out <dir>", "Output directory (default: current directory)").option("--force", "Overwrite existing files without prompting").action(initCmd);
|