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.
Files changed (2) hide show
  1. package/dist/index.js +59 -35
  2. 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
- console.error(`Build failed (HTTP ${res.status}).`);
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.2");
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);
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "promptarch",
3
- "version": "1.0.2",
3
+ "version": "1.0.4",
4
4
  "description": "Generate and lint AI coding-agent context files (CLAUDE.md, AGENTS.md, Cursor rules) from your repo.",
5
5
  "keywords": [
6
6
  "claude",