@usepipr/cli 0.3.8 → 0.4.1

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 CHANGED
@@ -11,7 +11,8 @@ GitHub Releases publish compiled CLI binaries for supported platforms.
11
11
  The binary exposes these command groups:
12
12
 
13
13
  - `pipr init`
14
- - `pipr action`
14
+ - `pipr host-run`
15
+ - `pipr webhook serve`
15
16
  - `pipr check`
16
17
  - `pipr dry-run`
17
18
  - `pipr inspect`
@@ -43,17 +44,17 @@ npm install -g @usepipr/cli@latest
43
44
  bun install -g @usepipr/cli@latest
44
45
  ```
45
46
 
46
- `pipr update` updates only the local CLI executable. It does not update GitHub
47
- Action workflow pins.
47
+ `pipr update` updates only the local CLI executable. It does not update a
48
+ repository's generated integration files.
48
49
 
49
- ## Technical Notes
50
+ ## Technical notes
50
51
 
51
52
  - Package build emits `dist/main.mjs`.
52
53
  - Release binary builds run through `packages/cli/build-release.ts`.
53
54
  - The package publishes the `pipr` bin through npm and release artifacts through
54
55
  GitHub Releases.
55
56
 
56
- ## Local Checks
57
+ ## Local checks
57
58
 
58
59
  ```bash
59
60
  bun run --cwd packages/cli check
@@ -62,6 +63,6 @@ bun run build:release:cli
62
63
 
63
64
  ## Docs
64
65
 
65
- - [CLI Reference](https://pipr.run/docs/reference/cli)
66
+ - [CLI reference](https://pipr.run/docs/reference/cli)
66
67
  - [Quickstart](https://pipr.run/docs/guide/quickstart)
67
- - [Local Runs](https://pipr.run/docs/guide/local-runs)
68
+ - [Local runs](https://pipr.run/docs/guide/local-runs)
package/dist/main.mjs CHANGED
@@ -1,6 +1,6 @@
1
1
  #!/usr/bin/env bun
2
2
  import * as core from "@actions/core";
3
- import { PublicationError, runActionCommand, runDryRunCommand, runInitCommand, runInspectCommand, runLocalReviewCommand, runValidateCommand, supportedOfficialInitAdapters, supportedOfficialInitRecipes } from "@usepipr/runtime";
3
+ import { PublicationError, runDryRunCommand, runHostRunCommand, runInitCommand, runInspectCommand, runLocalReviewCommand, runValidateCommand, supportedOfficialInitAdapters, supportedOfficialInitRecipes } from "@usepipr/runtime";
4
4
  import { inspect } from "node:util";
5
5
  import { Command, CommanderError } from "commander";
6
6
  import { chmod, lstat, mkdir, mkdtemp, open, readdir, rename, rm } from "node:fs/promises";
@@ -8,7 +8,7 @@ import os from "node:os";
8
8
  import path from "node:path";
9
9
  import { createHash } from "node:crypto";
10
10
  //#region package.json
11
- var version = "0.3.8";
11
+ var version = "0.4.1";
12
12
  //#endregion
13
13
  //#region src/skill-catalog.ts
14
14
  const bundledSkillName = "pipr-setup";
@@ -184,7 +184,9 @@ async function skillDirectoryMatches(skillDir, files) {
184
184
  }
185
185
  }
186
186
  async function skillDirectoryPathsMatch(skillDir, files) {
187
- return samePaths(await listSkillDirectoryEntries(skillDir), files.map((file) => file.path).sort());
187
+ const actualPaths = await listSkillDirectoryEntries(skillDir);
188
+ const expectedPaths = files.map((file) => file.path).sort();
189
+ return actualPaths.length === expectedPaths.length && actualPaths.every((value, index) => value === expectedPaths[index]);
188
190
  }
189
191
  async function skillDirectoryContentsMatch(skillDir, files) {
190
192
  for (const file of files) if (!await skillFileMatches(skillDir, file)) return false;
@@ -202,9 +204,6 @@ async function listSkillDirectoryEntries(skillDir, prefix = "") {
202
204
  return [relativePath.split(path.sep).join("/")];
203
205
  }))).flat().sort();
204
206
  }
205
- function samePaths(left, right) {
206
- return left.length === right.length && left.every((value, index) => value === right[index]);
207
- }
208
207
  const existingDirectoryErrorCodes = /* @__PURE__ */ new Set(["EEXIST", "ENOTEMPTY"]);
209
208
  function isExistingDirectoryError(error) {
210
209
  return existingDirectoryErrorCodes.has(error?.code ?? "");
@@ -282,7 +281,8 @@ async function runPiprUpdate(options) {
282
281
  kind: "up-to-date",
283
282
  version: options.currentVersion
284
283
  };
285
- const [binary, checksums] = await Promise.all([downloadBytes(fetchRelease, releaseDownloadUrl(release.tag, asset)), downloadText(fetchRelease, releaseDownloadUrl(release.tag, "SHA256SUMS"))]);
284
+ const releaseDownloadBaseUrl = `https://github.com/${officialRepo}/releases/download/${release.tag}`;
285
+ const [binary, checksums] = await Promise.all([downloadBytes(fetchRelease, `${releaseDownloadBaseUrl}/${asset}`), downloadText(fetchRelease, `${releaseDownloadBaseUrl}/SHA256SUMS`)]);
286
286
  verifyChecksum(binary, expectedChecksum(checksums, asset), asset);
287
287
  const tempPath = path.join(path.dirname(options.executablePath), `.pipr-update-${process.pid}-${Date.now()}`);
288
288
  let createdTemp = false;
@@ -346,9 +346,6 @@ async function latestRelease(fetchRelease) {
346
346
  version
347
347
  };
348
348
  }
349
- function releaseDownloadUrl(tag, asset) {
350
- return `https://github.com/${officialRepo}/releases/download/${tag}/${asset}`;
351
- }
352
349
  async function downloadBytes(fetchRelease, url) {
353
350
  const response = await fetchRelease(url);
354
351
  if (!response.ok) throw new Error(`failed to download ${url}: HTTP ${response.status}`);
@@ -432,9 +429,10 @@ function createProgram(options = {}) {
432
429
  if (options.exitOverride) program.exitOverride();
433
430
  program.addHelpText("after", agentHelpText);
434
431
  program.command("init").description("Create editable TypeScript config").option("--config-dir <dir>", "Config directory", ".pipr").option("--adapters <adapters>", `Adapters to initialize (${supportedOfficialInitAdapters.join(", ")}; use 'none' to skip adapter files)`).option("--recipe <recipe>", `Starter recipe (${supportedOfficialInitRecipes.join(", ")})`).option("--minimal", "Scaffold a single-file .pipr/config.ts without package.json").option("--force", "Overwrite existing pipr files").action(runInit);
435
- program.command("action").description("Run inside GitHub Docker Action").option("--config-dir <dir>", "Config directory", ".pipr").action(runAction);
432
+ program.command("host-run").description("Run a change request event through a Code Host Adapter").option("--host <host>", "Code host adapter").option("--event <path>", "Native event payload path").option("--config-dir <dir>", "Config directory", ".pipr").action(runHostRun);
433
+ program.command("webhook").description("Run trusted webhook ingress").command("serve").description("Serve one repository with a durable webhook queue").requiredOption("--host <host>", "Code host adapter").requiredOption("--workspace <path>", "Trusted repository workspace").requiredOption("--repository <repository>", "Expected provider repository ID or path").option("--database <path>", "SQLite delivery database", ".pipr/webhooks.sqlite").option("--hostname <hostname>", "Listen hostname", "127.0.0.1").option("--port <port>", "Listen port", "8787").option("--config-dir <dir>", "Config directory", ".pipr").action(runWebhookServe);
436
434
  program.command("check").description("Type-load config and validate the runtime plan").option("--config-dir <dir>", "Config directory", ".pipr").option("--require-env", "Require configured provider env vars").action(runCheck);
437
- program.command("dry-run").description("Load config and event without publishing").requiredOption("--event <path>", "GitHub event JSON path").option("--config-dir <dir>", "Config directory", ".pipr").action(runDryRun);
435
+ program.command("dry-run").description("Load config and event without publishing").requiredOption("--event <path>", "Native event payload path").option("--host <host>", "Code host adapter").option("--config-dir <dir>", "Config directory", ".pipr").action(runDryRun);
438
436
  program.command("inspect").description("Print models, agents, tasks, commands, and tools").option("--config-dir <dir>", "Config directory", ".pipr").action(runInspect);
439
437
  program.command("review").description("Run configured change-request review tasks locally without publishing").requiredOption("--base <sha>", "Base commit SHA").option("--head <sha>", "Head commit SHA or ref; omitted reviews the working tree").option("--config-dir <dir>", "Config directory", ".pipr").option("--pi-executable <path>", "Pi executable path").option("--json", "Print structured JSON output").action(runLocalReview);
440
438
  program.command("version").description("Print the CLI version").action(runVersion);
@@ -453,24 +451,66 @@ Prefer it over guessing commands or config shape from memory.
453
451
  skill Print the bundled setup skill and references
454
452
  skill path Materialize the setup skill and print its directory path
455
453
  `;
456
- async function runAction(options) {
457
- writeActionResult(await runActionCommand(actionOptions(options)));
454
+ async function runHostRun(options) {
455
+ const env = process.env;
456
+ const isGitHubAction = env.GITHUB_ACTIONS === "true";
457
+ const result = await runHostRunCommand({
458
+ rootDir: hostRunRootDir(env),
459
+ configDir: options.configDir,
460
+ host: options.host,
461
+ eventPath: options.event ?? env.PIPR_EVENT_PATH ?? env.GITHUB_EVENT_PATH,
462
+ env,
463
+ dryRun: env.PIPR_DRY_RUN === "1",
464
+ logSink: isGitHubAction ? githubActionsLogSink : localConsoleLogSink
465
+ });
466
+ if (isGitHubAction) {
467
+ writeGitHubActionResult(result);
468
+ return;
469
+ }
470
+ if (result.kind === "ignored") {
471
+ console.log(`ignored: ${result.reason}`);
472
+ return;
473
+ }
474
+ console.log(`pipr ${result.kind} completed for change #${result.event.change.number}`);
475
+ }
476
+ function hostRunRootDir(env) {
477
+ return env.GITHUB_WORKSPACE ?? env.CI_PROJECT_DIR ?? env.BITBUCKET_CLONE_DIR ?? env.BUILD_SOURCESDIRECTORY ?? process.cwd();
478
+ }
479
+ async function runWebhookServe(options) {
480
+ const { runWebhookServer } = await import("@usepipr/runtime");
481
+ const secret = process.env.PIPR_WEBHOOK_SECRET;
482
+ if (!secret) throw new Error("PIPR_WEBHOOK_SECRET is required");
483
+ const host = webhookHost(options.host);
484
+ const port = webhookPort(options.port);
485
+ await runWebhookServer({
486
+ host,
487
+ workspace: options.workspace ?? process.cwd(),
488
+ configDir: options.configDir,
489
+ databasePath: options.database ?? ".pipr/webhooks.sqlite",
490
+ expectedRepository: options.repository ?? "",
491
+ secret,
492
+ hostname: options.hostname,
493
+ port,
494
+ env: process.env
495
+ });
458
496
  }
459
- function actionOptions(options) {
460
- const eventPath = process.env.GITHUB_EVENT_PATH;
461
- if (!eventPath) throw new Error("GITHUB_EVENT_PATH is required for pipr action");
462
- return {
463
- rootDir: process.env.GITHUB_WORKSPACE ?? process.cwd(),
464
- configDir: process.env["INPUT_CONFIG-DIR"] || options.configDir,
465
- env: process.env,
466
- eventPath,
467
- dryRun: process.env.PIPR_DRY_RUN === "1",
468
- logSink: githubActionsLogSink
469
- };
497
+ function webhookHost(value) {
498
+ if (value === "gitlab" || value === "azure-devops" || value === "bitbucket") return value;
499
+ throw new Error("webhook serve supports --host gitlab, azure-devops, or bitbucket");
500
+ }
501
+ function webhookPort(value) {
502
+ const port = Number(value);
503
+ if (!Number.isInteger(port) || port < 1 || port > 65535) throw new Error("--port must be an integer from 1 to 65535");
504
+ return port;
470
505
  }
471
506
  const githubActionsLogSink = {
472
507
  log(record) {
473
- githubActionLogWriters[record.level](formatGitHubActionLogRecord(record));
508
+ const line = JSON.stringify({
509
+ level: record.level,
510
+ event: record.event,
511
+ ...record.fields
512
+ });
513
+ githubActionLogWriters[record.level](record.text === void 0 ? line : `${line}\n${record.text}`);
474
514
  },
475
515
  async group(name, run) {
476
516
  return await core.group(name, run);
@@ -483,77 +523,69 @@ const githubActionLogWriters = {
483
523
  error: core.error,
484
524
  debug: core.debug
485
525
  };
486
- function formatGitHubActionLogRecord(record) {
487
- const line = JSON.stringify({
488
- level: record.level,
489
- event: record.event,
490
- ...record.fields
491
- });
492
- return record.text === void 0 ? line : `${line}\n${record.text}`;
493
- }
494
- function writeActionResult(result) {
526
+ function writeGitHubActionResult(result) {
495
527
  if (result.kind === "ignored") {
496
528
  core.info(`pipr ignored event: ${result.reason}`);
497
529
  return;
498
530
  }
499
- writeLoadedActionResult(result);
531
+ writeLoadedGitHubActionResult(result);
500
532
  }
501
- function writeLoadedActionResult(result) {
533
+ function writeLoadedGitHubActionResult(result) {
502
534
  core.info(`pipr loaded change #${result.event.change.number} for ${result.event.repository.slug}`);
503
535
  core.info(`pipr config source: ${result.configSource}`);
504
536
  if (result.kind === "dry-run") {
505
- writeDryRunActionResult(result);
537
+ writeDryRunGitHubActionResult(result);
506
538
  return;
507
539
  }
508
- writePublishedActionResult(result);
540
+ writePublishedGitHubActionResult(result);
509
541
  }
510
- function writePublishedActionResult(result) {
542
+ function writePublishedGitHubActionResult(result) {
511
543
  if (result.kind === "command-help" || result.kind === "command-response") {
512
- writeCommandActionResult(result);
544
+ writeCommandGitHubActionResult(result);
513
545
  return;
514
546
  }
515
- writeReviewWorkflowActionResult(result);
547
+ writeReviewWorkflowGitHubActionResult(result);
516
548
  }
517
- function writeCommandActionResult(result) {
549
+ function writeCommandGitHubActionResult(result) {
518
550
  switch (result.kind) {
519
551
  case "command-help":
520
- writeCommandHelpActionResult(result);
552
+ writeCommandHelpGitHubActionResult(result);
521
553
  break;
522
554
  case "command-response":
523
- writeCommandResponseActionResult(result);
555
+ writeCommandResponseGitHubActionResult(result);
524
556
  break;
525
557
  default:
526
558
  }
527
559
  }
528
- function writeReviewWorkflowActionResult(result) {
560
+ function writeReviewWorkflowGitHubActionResult(result) {
529
561
  switch (result.kind) {
530
562
  case "review":
531
- writeReviewActionResult(result);
563
+ writeReviewGitHubActionResult(result);
532
564
  break;
533
565
  case "verifier":
534
- writeVerifierActionResult(result);
566
+ writeVerifierGitHubActionResult(result);
535
567
  break;
536
568
  default:
537
569
  }
538
570
  }
539
- function writeDryRunActionResult(result) {
571
+ function writeDryRunGitHubActionResult(result) {
540
572
  core.info("PIPR_DRY_RUN=1; stopping before review runtime, model, or GitHub publishing calls");
541
573
  }
542
- function writeCommandHelpActionResult(result) {
574
+ function writeCommandHelpGitHubActionResult(result) {
543
575
  core.info(`pipr command help: ${result.reason}`);
544
576
  core.setOutput("main-comment", result.body);
545
577
  }
546
- function writeCommandResponseActionResult(result) {
578
+ function writeCommandResponseGitHubActionResult(result) {
547
579
  core.info(`pipr command '${result.command}' published response comment (${result.publication.action})`);
548
580
  core.setOutput("main-comment", result.response.body);
549
581
  core.setOutput("publication", JSON.stringify(result.publication));
550
582
  }
551
- function writeVerifierActionResult(result) {
583
+ function writeVerifierGitHubActionResult(result) {
552
584
  core.info(`pipr verifier processed review comment reply with ${result.errors.length} publication error(s)`);
553
585
  warnInlineResolutionErrors(result.errors);
554
586
  core.setOutput("publication", JSON.stringify({ inlineResolutionErrors: result.errors }));
555
587
  }
556
- function writeReviewActionResult(result) {
588
+ function writeReviewGitHubActionResult(result) {
557
589
  core.info(`pipr review produced ${result.review.validated.validFindings.length} valid inline finding(s), ${result.review.validated.droppedFindings.length} dropped finding(s)`);
558
590
  core.info(`pipr published main comment (${result.publication.mainComment.action}) and ${result.publication.inlineComments.posted} inline comment(s); ${result.publication.inlineComments.skipped} skipped`);
559
591
  warnInlineResolutionErrors(result.publication.metadata.inlineResolutionErrors);
@@ -571,16 +603,13 @@ async function runInit(options) {
571
603
  rootDir: process.cwd(),
572
604
  configDir: options.configDir,
573
605
  force: options.force === true,
574
- adapters: parseInitAdapters(options.adapters),
606
+ adapters: options.adapters?.split(",").map((adapter) => adapter.trim()),
575
607
  recipe: options.recipe,
576
608
  minimal: options.minimal === true
577
609
  });
578
610
  console.log(`created ${result.created.length} file(s)` + (result.overwritten.length > 0 ? `; overwrote ${result.overwritten.length}` : ""));
579
611
  if (options.minimal === true) console.log("For editor types, install @usepipr/sdk at the repo root: npm install -D @usepipr/sdk");
580
612
  }
581
- function parseInitAdapters(adapters) {
582
- return adapters?.split(",").map((adapter) => adapter.trim());
583
- }
584
613
  async function runCheck(options) {
585
614
  const settings = await runValidateCommand({
586
615
  rootDir: process.cwd(),
@@ -733,7 +762,7 @@ function writeLocalReviewResult(result, json) {
733
762
  console.log(formatLocalReview(result));
734
763
  }
735
764
  function formatLocalReview(result) {
736
- const mainComment = stripMainCommentMarker(result.mainComment);
765
+ const mainComment = result.mainComment.split("\n").filter((line) => !line.startsWith("<!-- pipr:main-comment ")).join("\n").trimStart();
737
766
  const inlineFindings = result.inlineCommentDrafts.map((draft, index) => {
738
767
  const range = draft.startLine === draft.endLine ? `${draft.path}:${draft.startLine}` : `${draft.path}:${draft.startLine}-${draft.endLine}`;
739
768
  return [
@@ -750,9 +779,6 @@ function formatLocalReview(result) {
750
779
  inlineFindings.join("\n\n")
751
780
  ].join("\n");
752
781
  }
753
- function stripMainCommentMarker(comment) {
754
- return comment.split("\n").filter((line) => !line.startsWith("<!-- pipr:main-comment ")).join("\n").trimStart();
755
- }
756
782
  function localReviewJson(result) {
757
783
  return {
758
784
  kind: result.kind,
@@ -771,6 +797,7 @@ async function runDryRun(options) {
771
797
  const result = await runDryRunCommand({
772
798
  rootDir: process.cwd(),
773
799
  configDir: options.configDir,
800
+ host: options.host,
774
801
  env: process.env,
775
802
  eventPath: options.event
776
803
  });
package/dist/main.mjs.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"file":"main.mjs","names":["cliPackage.version","cliPackage.version"],"sources":["../package.json","../src/skill-catalog.ts","../src/skills.ts","../src/release/targets.ts","../src/update.ts","../src/runner.ts","../src/terminal-output.ts","../src/main.ts"],"sourcesContent":["","import { readdir } from \"node:fs/promises\";\nimport path from \"node:path\";\n\nexport const bundledSkillName = \"pipr-setup\";\nconst bundledSkillFilePaths = new Set([\n \"SKILL.md\",\n \"references/config-patterns.md\",\n \"references/recipes.md\",\n]);\n\nexport type BundledSkillFile = {\n path: string;\n contents: string;\n};\n\nexport type BundledSkill = {\n name: string;\n description: string;\n files: BundledSkillFile[];\n};\n\nexport type BundledSkillCatalog = {\n skills: BundledSkill[];\n};\n\nexport function singleBundledSkill(catalog: BundledSkillCatalog): BundledSkill {\n const [skill] = catalog.skills;\n if (catalog.skills.length !== 1 || skill?.name !== bundledSkillName) {\n throw new Error(\n `Expected exactly one bundled skill named '${bundledSkillName}', found: ${catalog.skills\n .map((item) => item.name)\n .join(\", \")}`,\n );\n }\n return skill;\n}\n\nexport function containedSkillFilePath(root: string, relativePath: string): string {\n if (path.isAbsolute(relativePath)) {\n throw new Error(`Bundled skill file path must be relative: ${relativePath}`);\n }\n const resolvedRoot = path.resolve(root);\n const target = path.resolve(resolvedRoot, relativePath);\n if (target !== resolvedRoot && !target.startsWith(`${resolvedRoot}${path.sep}`)) {\n throw new Error(`Bundled skill file path escapes the skill directory: ${relativePath}`);\n }\n return target;\n}\n\nexport async function readBundledSkillCatalog(skillsRoot: string): Promise<BundledSkillCatalog> {\n const entries = await readdir(skillsRoot, { withFileTypes: true });\n const skills = await Promise.all(\n entries\n .filter((entry) => entry.isDirectory())\n .map(async (entry) => {\n const skillDir = path.join(skillsRoot, entry.name);\n const files = await readSkillFiles(skillDir);\n validateBundledSkillFiles(entry.name, files);\n const skillMd = files.find((file) => file.path === \"SKILL.md\");\n if (!skillMd) {\n throw new Error(`${skillDir}: missing SKILL.md`);\n }\n return {\n name: entry.name,\n description: frontmatterDescription(skillMd.contents),\n files,\n };\n }),\n );\n const catalog = { skills: skills.sort((left, right) => left.name.localeCompare(right.name)) };\n singleBundledSkill(catalog);\n return catalog;\n}\n\nasync function readSkillFiles(skillDir: string, prefix = \"\"): Promise<BundledSkillFile[]> {\n const entries = await readdir(path.join(skillDir, prefix), { withFileTypes: true });\n const files = await Promise.all(\n entries\n .filter((entry) => !entry.name.startsWith(\".\"))\n .sort((left, right) => left.name.localeCompare(right.name))\n .map(async (entry) => {\n const relativePath = prefix ? path.join(prefix, entry.name) : entry.name;\n if (entry.isDirectory()) {\n return await readSkillFiles(skillDir, relativePath);\n }\n if (!entry.isFile()) {\n return [];\n }\n const contents = await Bun.file(path.join(skillDir, relativePath)).text();\n return [{ path: relativePath.split(path.sep).join(\"/\"), contents }];\n }),\n );\n return files.flat();\n}\n\nfunction frontmatterDescription(contents: string): string {\n const frontmatter = contents.match(/^---\\n(?<body>[\\s\\S]*?)\\n---/u)?.groups?.body;\n const description = frontmatter\n ?.split(\"\\n\")\n .find((line) => line.startsWith(\"description:\"))\n ?.replace(/^description:\\s*/u, \"\")\n .trim()\n .replace(/^[\"']|[\"']$/gu, \"\");\n if (!description) {\n throw new Error(\"Bundled skill SKILL.md is missing a description\");\n }\n return description;\n}\n\nfunction validateBundledSkillFiles(skillName: string, files: BundledSkillFile[]): void {\n if (skillName !== bundledSkillName) {\n return;\n }\n const found = new Set(files.map((file) => file.path));\n const unexpected = [...found].filter((filePath) => !bundledSkillFilePaths.has(filePath));\n const missing = [...bundledSkillFilePaths].filter((filePath) => !found.has(filePath));\n if (unexpected.length > 0 || missing.length > 0) {\n throw new Error(\n `${bundledSkillName} bundled files must match the release allowlist; ` +\n `unexpected: ${unexpected.join(\", \") || \"-\"}; missing: ${missing.join(\", \") || \"-\"}`,\n );\n }\n}\n","import { lstat, mkdir, mkdtemp, readdir, rename, rm } from \"node:fs/promises\";\nimport os from \"node:os\";\nimport path from \"node:path\";\nimport cliPackage from \"../package.json\" with { type: \"json\" };\nimport {\n type BundledSkill,\n type BundledSkillCatalog,\n type BundledSkillFile,\n bundledSkillName,\n containedSkillFilePath,\n readBundledSkillCatalog,\n singleBundledSkill,\n} from \"./skill-catalog.js\";\n\ndeclare const PIPR_EMBEDDED_SKILLS: string | undefined;\n\nlet skillPromise: Promise<BundledSkill> | undefined;\n\ntype SkillCatalogAttempt =\n | { catalog: BundledSkillCatalog; skillsRoot: string }\n | { error: string; skillsRoot: string };\n\nexport async function resolveBundledSkill(): Promise<BundledSkill> {\n skillPromise ??= loadBundledSkill();\n return await skillPromise;\n}\n\nexport function formatBundledSkill(skill: BundledSkill): string {\n const files = [...skill.files].sort(compareSkillFiles);\n return [\n `# ${skill.name}`,\n \"\",\n skill.description,\n \"\",\n ...files.flatMap((file) => [\n `----- BEGIN SKILL FILE: ${file.path} -----`,\n file.contents.trimEnd(),\n `----- END SKILL FILE: ${file.path} -----`,\n \"\",\n ]),\n ].join(\"\\n\");\n}\n\nfunction compareSkillFiles(left: BundledSkillFile, right: BundledSkillFile): number {\n if (left.path === \"SKILL.md\") {\n return -1;\n }\n if (right.path === \"SKILL.md\") {\n return 1;\n }\n return left.path.localeCompare(right.path);\n}\n\nexport async function materializeBundledSkill(): Promise<string> {\n const skill = await resolveBundledSkill();\n const versionDir = path.join(skillCacheRoot(), cliPackage.version);\n const skillDir = path.join(versionDir, skill.name);\n await mkdir(versionDir, { recursive: true });\n const stagingDir = await mkdtemp(path.join(versionDir, `${bundledSkillName}-`));\n try {\n for (const file of skill.files) {\n await writeSkillFile(stagingDir, file);\n }\n if (await skillDirectoryMatches(skillDir, skill.files)) {\n await rm(stagingDir, { recursive: true, force: true });\n return skillDir;\n }\n await rm(skillDir, { recursive: true, force: true });\n await renameSkillDirectory(stagingDir, skillDir, skill.files);\n } catch (error) {\n await rm(stagingDir, { recursive: true, force: true });\n throw error;\n }\n return skillDir;\n}\n\nasync function loadBundledSkill(): Promise<BundledSkill> {\n const embedded = embeddedSkillCatalog();\n return singleBundledSkill(embedded ?? (await loadFilesystemSkillCatalog()));\n}\n\nasync function loadFilesystemSkillCatalog(): Promise<BundledSkillCatalog> {\n const attempts = await Promise.all(skillRootCandidates().map(readSkillCatalogAttempt));\n const loaded = attempts.find(\n (attempt): attempt is Extract<SkillCatalogAttempt, { catalog: BundledSkillCatalog }> =>\n \"catalog\" in attempt,\n );\n if (loaded) {\n return loaded.catalog;\n }\n throw new Error(\n `Unable to load bundled Pipr skills.\\n${attempts\n .map((attempt) => `${attempt.skillsRoot}: ${\"error\" in attempt ? attempt.error : \"loaded\"}`)\n .join(\"\\n\")}`,\n );\n}\n\nasync function readSkillCatalogAttempt(skillsRoot: string): Promise<SkillCatalogAttempt> {\n try {\n return { skillsRoot, catalog: await readBundledSkillCatalog(skillsRoot) };\n } catch (error) {\n return { skillsRoot, error: error instanceof Error ? error.message : String(error) };\n }\n}\n\nfunction embeddedSkillCatalog(): BundledSkillCatalog | undefined {\n if (typeof PIPR_EMBEDDED_SKILLS !== \"string\" || PIPR_EMBEDDED_SKILLS.length === 0) {\n return undefined;\n }\n return JSON.parse(PIPR_EMBEDDED_SKILLS) as BundledSkillCatalog;\n}\n\nfunction skillRootCandidates(): string[] {\n const here = import.meta.dirname;\n return [path.join(here, \"skills\"), path.resolve(here, \"../../../skills\")];\n}\n\nasync function writeSkillFile(skillDir: string, file: BundledSkillFile): Promise<void> {\n const target = containedSkillFilePath(skillDir, file.path);\n await mkdir(path.dirname(target), { recursive: true });\n await Bun.write(target, file.contents);\n}\n\nasync function renameSkillDirectory(\n stagingDir: string,\n skillDir: string,\n files: BundledSkillFile[],\n): Promise<void> {\n try {\n await rename(stagingDir, skillDir);\n } catch (error) {\n if (isExistingDirectoryError(error) && (await skillDirectoryMatches(skillDir, files))) {\n await rm(stagingDir, { recursive: true, force: true });\n return;\n }\n throw error;\n }\n}\n\nasync function skillDirectoryMatches(\n skillDir: string,\n files: BundledSkillFile[],\n): Promise<boolean> {\n try {\n return (\n (await skillDirectoryPathsMatch(skillDir, files)) &&\n (await skillDirectoryContentsMatch(skillDir, files))\n );\n } catch {\n return false;\n }\n}\n\nasync function skillDirectoryPathsMatch(\n skillDir: string,\n files: BundledSkillFile[],\n): Promise<boolean> {\n return samePaths(\n await listSkillDirectoryEntries(skillDir),\n files.map((file) => file.path).sort(),\n );\n}\n\nasync function skillDirectoryContentsMatch(\n skillDir: string,\n files: BundledSkillFile[],\n): Promise<boolean> {\n for (const file of files) {\n if (!(await skillFileMatches(skillDir, file))) {\n return false;\n }\n }\n return true;\n}\n\nasync function skillFileMatches(skillDir: string, file: BundledSkillFile): Promise<boolean> {\n const target = containedSkillFilePath(skillDir, file.path);\n return (await lstat(target)).isFile() && (await Bun.file(target).text()) === file.contents;\n}\n\nasync function listSkillDirectoryEntries(skillDir: string, prefix = \"\"): Promise<string[]> {\n const entries = await readdir(path.join(skillDir, prefix), { withFileTypes: true });\n const paths = await Promise.all(\n entries\n .filter((entry) => !entry.name.startsWith(\".\"))\n .map(async (entry) => {\n const relativePath = prefix ? path.join(prefix, entry.name) : entry.name;\n if (entry.isDirectory()) {\n return await listSkillDirectoryEntries(skillDir, relativePath);\n }\n return [relativePath.split(path.sep).join(\"/\")];\n }),\n );\n return paths.flat().sort();\n}\n\nfunction samePaths(left: string[], right: string[]): boolean {\n return left.length === right.length && left.every((value, index) => value === right[index]);\n}\n\nconst existingDirectoryErrorCodes = new Set([\"EEXIST\", \"ENOTEMPTY\"]);\n\nfunction isExistingDirectoryError(error: unknown): boolean {\n return existingDirectoryErrorCodes.has((error as { code?: string } | undefined)?.code ?? \"\");\n}\n\nfunction skillCacheRoot(): string {\n const override = process.env.PIPR_SKILL_CACHE_DIR;\n if (override && override.trim().length > 0) {\n return path.resolve(override);\n }\n const cacheHome = process.env.XDG_CACHE_HOME || path.join(os.homedir(), \".cache\");\n return path.join(cacheHome, \"pipr\", \"skills\");\n}\n","export type ReleasePlatform = {\n platform: NodeJS.Platform;\n arch: NodeJS.Architecture;\n};\n\nexport type ReleaseTarget = ReleasePlatform & {\n target: string;\n outfile: string;\n};\n\nexport const releaseTargets: ReleaseTarget[] = [\n { platform: \"linux\", arch: \"x64\", target: \"bun-linux-x64-baseline\", outfile: \"pipr-linux-x64\" },\n { platform: \"linux\", arch: \"arm64\", target: \"bun-linux-arm64\", outfile: \"pipr-linux-arm64\" },\n { platform: \"darwin\", arch: \"x64\", target: \"bun-darwin-x64\", outfile: \"pipr-darwin-x64\" },\n {\n platform: \"darwin\",\n arch: \"arm64\",\n target: \"bun-darwin-arm64\",\n outfile: \"pipr-darwin-arm64\",\n },\n];\n\nexport function releaseTargetForPlatform(platform: ReleasePlatform): ReleaseTarget | undefined {\n return releaseTargets.find(\n (target) => target.platform === platform.platform && target.arch === platform.arch,\n );\n}\n\nexport function releaseAssetForPlatform(platform: ReleasePlatform): string {\n const target = releaseTargetForPlatform(platform);\n if (target) {\n return target.outfile;\n }\n if (!releaseTargets.some((item) => item.platform === platform.platform)) {\n throw new Error(`pipr update unsupported OS: ${platform.platform}`);\n }\n throw new Error(`pipr update unsupported architecture: ${platform.arch}`);\n}\n","import { createHash } from \"node:crypto\";\nimport { chmod, mkdtemp, open, rename, rm } from \"node:fs/promises\";\nimport os from \"node:os\";\nimport path from \"node:path\";\nimport type { ReleasePlatform } from \"./release/targets.js\";\nimport { releaseAssetForPlatform } from \"./release/targets.js\";\n\nexport { releaseAssetForPlatform } from \"./release/targets.js\";\n\nexport type UpdateResult =\n | { kind: \"up-to-date\"; version: string }\n | { kind: \"updated\"; previousVersion: string; version: string };\n\nexport type UpdateNotice = {\n currentVersion: string;\n latestVersion: string;\n};\n\ntype ReleaseFetch = (url: string, init?: RequestInit) => Promise<Response>;\n\ntype UpdateOptions = {\n currentVersion: string;\n executablePath: string;\n fetch?: ReleaseFetch;\n platform?: ReleasePlatform;\n};\n\ntype UpdateNoticeOptions = {\n currentVersion: string;\n fetch?: ReleaseFetch;\n timeoutMs?: number;\n};\n\ntype LatestRelease = {\n tag_name?: unknown;\n};\n\nconst officialRepo = \"somus/pipr\";\nconst packageManagerUpdateHelp = [\n \"pipr update only supports compiled GitHub Release binaries.\",\n \"If you installed with npm, run: npm install -g @usepipr/cli@latest\",\n \"If you installed with Bun, run: bun install -g @usepipr/cli@latest\",\n \"If you installed from source, pull the repository and rebuild the CLI.\",\n].join(\"\\n\");\n\nexport function resolveCurrentExecutablePath(\n options: { argv?: string[]; execPath?: string } = {},\n): string {\n const execPath = options.execPath ?? process.execPath;\n const argv = options.argv ?? process.argv;\n const execName = path.basename(execPath).toLowerCase();\n const scriptPath = argv[1];\n if (\n execName === \"bun\" ||\n execName.startsWith(\"bun-\") ||\n execName === \"node\" ||\n execName.startsWith(\"node-\") ||\n scriptPath?.endsWith(\".ts\") ||\n scriptPath?.endsWith(\".mjs\")\n ) {\n throw new Error(packageManagerUpdateHelp);\n }\n return execPath;\n}\n\nexport async function runPiprUpdate(options: UpdateOptions): Promise<UpdateResult> {\n if (!isStableSemver(options.currentVersion)) {\n throw new Error(\n `current pipr version is not a stable semver version: ${options.currentVersion}`,\n );\n }\n const fetchRelease = options.fetch ?? globalThis.fetch.bind(globalThis);\n const platform = options.platform ?? { platform: process.platform, arch: process.arch };\n const asset = releaseAssetForPlatform(platform);\n const release = await latestRelease(fetchRelease);\n const version = release.version;\n if (compareSemver(version, options.currentVersion) <= 0) {\n return { kind: \"up-to-date\", version: options.currentVersion };\n }\n const [binary, checksums] = await Promise.all([\n downloadBytes(fetchRelease, releaseDownloadUrl(release.tag, asset)),\n downloadText(fetchRelease, releaseDownloadUrl(release.tag, \"SHA256SUMS\")),\n ]);\n verifyChecksum(binary, expectedChecksum(checksums, asset), asset);\n\n const tempPath = path.join(\n path.dirname(options.executablePath),\n `.pipr-update-${process.pid}-${Date.now()}`,\n );\n let createdTemp = false;\n let replaced = false;\n try {\n const tempFile = await open(tempPath, \"wx\", 0o700);\n createdTemp = true;\n try {\n await tempFile.writeFile(binary);\n } finally {\n await tempFile.close();\n }\n await chmod(tempPath, 0o755);\n const binaryVersion = await downloadedVersion(tempPath);\n if (!isStableSemver(binaryVersion)) {\n throw new Error(`downloaded pipr binary reported invalid version: ${binaryVersion}`);\n }\n if (binaryVersion !== version) {\n throw new Error(\n `downloaded pipr binary reported ${binaryVersion}, expected latest ${version}`,\n );\n }\n await rename(tempPath, options.executablePath);\n replaced = true;\n return { kind: \"updated\", previousVersion: options.currentVersion, version };\n } finally {\n if (createdTemp && !replaced) {\n await rm(tempPath, { force: true });\n }\n }\n}\n\nexport async function availablePiprUpdateNotice(\n options: UpdateNoticeOptions,\n): Promise<UpdateNotice | undefined> {\n if (!isStableSemver(options.currentVersion)) {\n return undefined;\n }\n const fetchRelease = withFetchTimeout(\n options.fetch ?? globalThis.fetch.bind(globalThis),\n options.timeoutMs,\n );\n const release = await latestRelease(fetchRelease);\n if (compareSemver(release.version, options.currentVersion) <= 0) {\n return undefined;\n }\n return { currentVersion: options.currentVersion, latestVersion: release.version };\n}\n\nfunction withFetchTimeout(fetchRelease: ReleaseFetch, timeoutMs: number | undefined): ReleaseFetch {\n if (timeoutMs === undefined) {\n return fetchRelease;\n }\n return async (url, init) => {\n const controller = new AbortController();\n const timeout = setTimeout(() => controller.abort(), timeoutMs);\n try {\n return await fetchRelease(url, { ...init, signal: controller.signal });\n } finally {\n clearTimeout(timeout);\n }\n };\n}\n\nasync function latestRelease(fetchRelease: ReleaseFetch): Promise<{\n tag: string;\n version: string;\n}> {\n const response = await fetchRelease(\n `https://api.github.com/repos/${officialRepo}/releases/latest`,\n );\n if (!response.ok) {\n throw new Error(`failed to fetch latest release metadata: HTTP ${response.status}`);\n }\n const release = (await response.json()) as LatestRelease;\n if (typeof release.tag_name !== \"string\") {\n throw new Error(\"latest release metadata is missing tag_name\");\n }\n const version = release.tag_name.replace(/^v/, \"\");\n if (!isStableSemver(version)) {\n throw new Error(`latest release tag is not a stable semver version: ${release.tag_name}`);\n }\n return { tag: release.tag_name, version };\n}\n\nfunction releaseDownloadUrl(tag: string, asset: string): string {\n return `https://github.com/${officialRepo}/releases/download/${tag}/${asset}`;\n}\n\nasync function downloadBytes(\n fetchRelease: (url: string) => Promise<Response>,\n url: string,\n): Promise<Buffer> {\n const response = await fetchRelease(url);\n if (!response.ok) {\n throw new Error(`failed to download ${url}: HTTP ${response.status}`);\n }\n return Buffer.from(await response.arrayBuffer());\n}\n\nasync function downloadText(\n fetchRelease: (url: string) => Promise<Response>,\n url: string,\n): Promise<string> {\n const response = await fetchRelease(url);\n if (!response.ok) {\n throw new Error(`failed to download ${url}: HTTP ${response.status}`);\n }\n return await response.text();\n}\n\nfunction expectedChecksum(checksums: string, asset: string): string {\n for (const line of checksums.split(/\\r?\\n/)) {\n const [checksum, name] = line.trim().split(/\\s+/);\n if (name === asset && checksum) {\n return checksum;\n }\n }\n throw new Error(`checksum for ${asset} not found`);\n}\n\nfunction verifyChecksum(binary: Buffer, expected: string, asset: string): void {\n const actual = createHash(\"sha256\").update(binary).digest(\"hex\");\n if (actual !== expected) {\n throw new Error(`checksum mismatch for ${asset}`);\n }\n}\n\nasync function downloadedVersion(executablePath: string): Promise<string> {\n const validationCwd = await mkdtemp(path.join(os.tmpdir(), \"pipr-update-version-\"));\n try {\n const process = Bun.spawn([executablePath, \"--version\"], {\n cwd: validationCwd,\n env: {\n HOME: validationCwd,\n PATH: \"/usr/bin:/bin\",\n TMPDIR: validationCwd,\n },\n stderr: \"pipe\",\n stdout: \"pipe\",\n });\n const [exitCode, stdout, stderr] = await Promise.all([\n process.exited,\n process.stdout ? new Response(process.stdout).text() : \"\",\n process.stderr ? new Response(process.stderr).text() : \"\",\n ]);\n if (exitCode !== 0) {\n throw new Error(\n `downloaded pipr binary failed --version: ${stderr.trim() || stdout.trim() || exitCode}`,\n );\n }\n return stdout.trim();\n } finally {\n await rm(validationCwd, { force: true, recursive: true });\n }\n}\n\nfunction isStableSemver(version: string): boolean {\n return /^\\d+\\.\\d+\\.\\d+$/.test(version);\n}\n\nfunction compareSemver(left: string, right: string): number {\n const leftParts = left.split(\".\").map(Number);\n const rightParts = right.split(\".\").map(Number);\n for (let index = 0; index < 3; index += 1) {\n const difference = leftParts[index] - rightParts[index];\n if (difference !== 0) {\n return difference;\n }\n }\n return 0;\n}\n","import { inspect } from \"node:util\";\nimport * as core from \"@actions/core\";\nimport {\n type ActionCommandResult,\n type ActionLogRecord,\n type ActionLogSink,\n runActionCommand,\n runDryRunCommand,\n runInitCommand,\n runInspectCommand,\n runLocalReviewCommand,\n runValidateCommand,\n supportedOfficialInitAdapters,\n supportedOfficialInitRecipes,\n} from \"@usepipr/runtime\";\nimport { Command, CommanderError } from \"commander\";\nimport cliPackage from \"../package.json\" with { type: \"json\" };\nimport { formatBundledSkill, materializeBundledSkill, resolveBundledSkill } from \"./skills.js\";\nimport {\n availablePiprUpdateNotice,\n resolveCurrentExecutablePath,\n runPiprUpdate,\n} from \"./update.js\";\n\ntype ActionOptions = Parameters<typeof runActionCommand>[0];\n\ntype CliOptions = {\n configDir: string;\n event?: string;\n force?: boolean;\n adapters?: string;\n recipe?: string;\n minimal?: boolean;\n requireEnv?: boolean;\n base?: string;\n head?: string;\n piExecutable?: string;\n json?: boolean;\n};\n\ntype MainOptions = {\n argv?: string[];\n env?: NodeJS.ProcessEnv;\n updateNoticeFetch?: typeof fetch;\n writeUpdateNotice?: (message: string) => void;\n};\n\nexport async function runMain(options: MainOptions = {}): Promise<void> {\n const argv = options.argv ?? process.argv;\n const env = options.env ?? process.env;\n if (!isUpdateCommand(argv)) {\n await writeAvailableUpdateNotice(options);\n }\n const program = createProgram({ exitOverride: env.GITHUB_ACTIONS === \"true\" });\n try {\n if (argv.length <= 2) {\n program.outputHelp();\n return;\n }\n await program.parseAsync(argv);\n } catch (error) {\n if (error instanceof CommanderError && error.exitCode === 0) {\n return;\n }\n throw error;\n }\n}\n\nfunction createProgram(options: { exitOverride?: boolean } = {}): Command {\n const program = new Command();\n program.name(\"pipr\").version(cliPackage.version).showHelpAfterError();\n if (options.exitOverride) {\n program.exitOverride();\n }\n program.addHelpText(\"after\", agentHelpText);\n\n program\n .command(\"init\")\n .description(\"Create editable TypeScript config\")\n .option(\"--config-dir <dir>\", \"Config directory\", \".pipr\")\n .option(\n \"--adapters <adapters>\",\n `Adapters to initialize (${supportedOfficialInitAdapters.join(\", \")}; use 'none' to skip adapter files)`,\n )\n .option(\"--recipe <recipe>\", `Starter recipe (${supportedOfficialInitRecipes.join(\", \")})`)\n .option(\"--minimal\", \"Scaffold a single-file .pipr/config.ts without package.json\")\n .option(\"--force\", \"Overwrite existing pipr files\")\n .action(runInit);\n\n program\n .command(\"action\")\n .description(\"Run inside GitHub Docker Action\")\n .option(\"--config-dir <dir>\", \"Config directory\", \".pipr\")\n .action(runAction);\n\n program\n .command(\"check\")\n .description(\"Type-load config and validate the runtime plan\")\n .option(\"--config-dir <dir>\", \"Config directory\", \".pipr\")\n .option(\"--require-env\", \"Require configured provider env vars\")\n .action(runCheck);\n\n program\n .command(\"dry-run\")\n .description(\"Load config and event without publishing\")\n .requiredOption(\"--event <path>\", \"GitHub event JSON path\")\n .option(\"--config-dir <dir>\", \"Config directory\", \".pipr\")\n .action(runDryRun);\n\n program\n .command(\"inspect\")\n .description(\"Print models, agents, tasks, commands, and tools\")\n .option(\"--config-dir <dir>\", \"Config directory\", \".pipr\")\n .action(runInspect);\n\n program\n .command(\"review\")\n .description(\"Run configured change-request review tasks locally without publishing\")\n .requiredOption(\"--base <sha>\", \"Base commit SHA\")\n .option(\"--head <sha>\", \"Head commit SHA or ref; omitted reviews the working tree\")\n .option(\"--config-dir <dir>\", \"Config directory\", \".pipr\")\n .option(\"--pi-executable <path>\", \"Pi executable path\")\n .option(\"--json\", \"Print structured JSON output\")\n .action(runLocalReview);\n\n program.command(\"version\").description(\"Print the CLI version\").action(runVersion);\n\n program.command(\"update\").description(\"Update a GitHub Release binary install\").action(runUpdate);\n\n const skill = program\n .command(\"skill\")\n .description(\"Print the bundled Pipr setup skill\")\n .action(runSkillGet);\n skill\n .command(\"path\")\n .description(\"Materialize the bundled Pipr setup skill and print its directory path\")\n .action(runSkillPath);\n\n return program;\n}\n\nconst agentHelpText = `\n\nStart here (for AI agents):\n pipr skill\n\nThe Pipr setup skill ships with the CLI and is version-matched to this release.\nPrefer it over guessing commands or config shape from memory.\n\n skill Print the bundled setup skill and references\n skill path Materialize the setup skill and print its directory path\n`;\n\nasync function runAction(options: CliOptions): Promise<void> {\n writeActionResult(await runActionCommand(actionOptions(options)));\n}\n\nfunction actionOptions(options: CliOptions): ActionOptions {\n const eventPath = process.env.GITHUB_EVENT_PATH;\n if (!eventPath) {\n throw new Error(\"GITHUB_EVENT_PATH is required for pipr action\");\n }\n return {\n rootDir: process.env.GITHUB_WORKSPACE ?? process.cwd(),\n configDir: process.env[\"INPUT_CONFIG-DIR\"] || options.configDir,\n env: process.env,\n eventPath,\n dryRun: process.env.PIPR_DRY_RUN === \"1\",\n logSink: githubActionsLogSink,\n };\n}\n\nconst githubActionsLogSink: ActionLogSink = {\n log(record) {\n githubActionLogWriters[record.level](formatGitHubActionLogRecord(record));\n },\n async group(name, run) {\n return await core.group(name, run);\n },\n};\n\nconst githubActionLogWriters = {\n info: core.info,\n notice: core.notice,\n warning: core.warning,\n error: core.error,\n debug: core.debug,\n} satisfies Record<ActionLogRecord[\"level\"], (message: string) => void>;\n\nfunction formatGitHubActionLogRecord(record: ActionLogRecord): string {\n const line = JSON.stringify({\n level: record.level,\n event: record.event,\n ...record.fields,\n });\n return record.text === undefined ? line : `${line}\\n${record.text}`;\n}\n\nfunction writeActionResult(result: ActionCommandResult): void {\n if (result.kind === \"ignored\") {\n core.info(`pipr ignored event: ${result.reason}`);\n return;\n }\n writeLoadedActionResult(result);\n}\n\ntype LoadedActionResult = Exclude<ActionCommandResult, { kind: \"ignored\" }>;\ntype PublishedActionResult = Exclude<LoadedActionResult, { kind: \"dry-run\" }>;\ntype CommandActionResult = Extract<\n PublishedActionResult,\n { kind: \"command-help\" | \"command-response\" }\n>;\ntype ReviewWorkflowActionResult = Exclude<PublishedActionResult, CommandActionResult>;\n\nfunction writeLoadedActionResult(result: LoadedActionResult): void {\n core.info(\n `pipr loaded change #${result.event.change.number} for ${result.event.repository.slug}`,\n );\n core.info(`pipr config source: ${result.configSource}`);\n if (result.kind === \"dry-run\") {\n writeDryRunActionResult(result);\n return;\n }\n writePublishedActionResult(result);\n}\n\nfunction writePublishedActionResult(result: PublishedActionResult): void {\n if (result.kind === \"command-help\" || result.kind === \"command-response\") {\n writeCommandActionResult(result);\n return;\n }\n writeReviewWorkflowActionResult(result);\n}\n\nfunction writeCommandActionResult(result: CommandActionResult): void {\n switch (result.kind) {\n case \"command-help\":\n writeCommandHelpActionResult(result);\n break;\n case \"command-response\":\n writeCommandResponseActionResult(result);\n break;\n default:\n result satisfies never;\n }\n}\n\nfunction writeReviewWorkflowActionResult(result: ReviewWorkflowActionResult): void {\n switch (result.kind) {\n case \"review\":\n writeReviewActionResult(result);\n break;\n case \"verifier\":\n writeVerifierActionResult(result);\n break;\n default:\n result satisfies never;\n }\n}\n\nfunction writeDryRunActionResult(result: Extract<ActionCommandResult, { kind: \"dry-run\" }>): void {\n void result;\n core.info(\"PIPR_DRY_RUN=1; stopping before review runtime, model, or GitHub publishing calls\");\n}\n\nfunction writeCommandHelpActionResult(\n result: Extract<ActionCommandResult, { kind: \"command-help\" }>,\n): void {\n core.info(`pipr command help: ${result.reason}`);\n core.setOutput(\"main-comment\", result.body);\n}\n\nfunction writeCommandResponseActionResult(\n result: Extract<ActionCommandResult, { kind: \"command-response\" }>,\n): void {\n core.info(\n `pipr command '${result.command}' published response comment (${result.publication.action})`,\n );\n core.setOutput(\"main-comment\", result.response.body);\n core.setOutput(\"publication\", JSON.stringify(result.publication));\n}\n\nfunction writeVerifierActionResult(\n result: Extract<ActionCommandResult, { kind: \"verifier\" }>,\n): void {\n core.info(\n `pipr verifier processed review comment reply with ${result.errors.length} publication error(s)`,\n );\n warnInlineResolutionErrors(result.errors);\n core.setOutput(\"publication\", JSON.stringify({ inlineResolutionErrors: result.errors }));\n}\n\nfunction writeReviewActionResult(result: Extract<ActionCommandResult, { kind: \"review\" }>): void {\n core.info(\n `pipr review produced ${result.review.validated.validFindings.length} valid inline finding(s), ` +\n `${result.review.validated.droppedFindings.length} dropped finding(s)`,\n );\n core.info(\n `pipr published main comment (${result.publication.mainComment.action}) and ` +\n `${result.publication.inlineComments.posted} inline comment(s); ` +\n `${result.publication.inlineComments.skipped} skipped`,\n );\n warnInlineResolutionErrors(result.publication.metadata.inlineResolutionErrors);\n if (result.review.repairAttempted) {\n core.info(\"pipr repaired reviewer JSON once before validation\");\n }\n core.setOutput(\"main-comment\", result.review.mainComment);\n core.setOutput(\"inline-comments\", JSON.stringify(result.review.inlineCommentDrafts));\n core.setOutput(\"dropped-findings\", JSON.stringify(result.review.validated.droppedFindings));\n core.setOutput(\"publication\", JSON.stringify(result.publication));\n}\n\nfunction warnInlineResolutionErrors(errors: string[]): void {\n for (const error of errors) {\n core.warning(`pipr inline resolution failed: ${error}`);\n }\n}\n\nasync function runInit(options: CliOptions): Promise<void> {\n const result = await runInitCommand({\n rootDir: process.cwd(),\n configDir: options.configDir,\n force: options.force === true,\n adapters: parseInitAdapters(options.adapters),\n recipe: options.recipe,\n minimal: options.minimal === true,\n });\n console.log(\n `created ${result.created.length} file(s)` +\n (result.overwritten.length > 0 ? `; overwrote ${result.overwritten.length}` : \"\"),\n );\n if (options.minimal === true) {\n console.log(\n \"For editor types, install @usepipr/sdk at the repo root: npm install -D @usepipr/sdk\",\n );\n }\n}\n\nfunction parseInitAdapters(adapters: string | undefined): string[] | undefined {\n return adapters?.split(\",\").map((adapter) => adapter.trim());\n}\n\nasync function runCheck(options: CliOptions): Promise<void> {\n const settings = await runValidateCommand({\n rootDir: process.cwd(),\n configDir: options.configDir,\n env: process.env,\n requireProviderEnv: options.requireEnv === true,\n });\n console.log(`valid: ${settings.source}`);\n writeConfigWarnings(settings.warnings);\n}\n\nasync function runInspect(options: CliOptions): Promise<void> {\n const result = await runInspectCommand({\n rootDir: process.cwd(),\n configDir: options.configDir,\n env: process.env,\n });\n const { warnings, ...plan } = result;\n writeConfigWarnings(warnings);\n console.log(inspect(plan, { depth: 8, colors: false }));\n}\n\nfunction writeConfigWarnings(warnings: readonly string[]): void {\n for (const warning of warnings) {\n console.log(`warning: ${warning}`);\n }\n}\n\nasync function runSkillGet(): Promise<void> {\n console.log(formatBundledSkill(await resolveBundledSkill()));\n}\n\nasync function runSkillPath(): Promise<void> {\n console.log(await materializeBundledSkill());\n}\n\nfunction runVersion(): void {\n console.log(cliPackage.version);\n}\n\nasync function runUpdate(): Promise<void> {\n const result = await runPiprUpdate({\n currentVersion: cliPackage.version,\n executablePath: resolveCurrentExecutablePath(),\n });\n if (result.kind === \"up-to-date\") {\n console.log(`pipr ${result.version} is already up to date`);\n return;\n }\n console.log(`updated pipr from ${result.previousVersion} to ${result.version}`);\n}\n\nasync function writeAvailableUpdateNotice(options: MainOptions): Promise<void> {\n const env = options.env ?? process.env;\n if (shouldSkipUpdateNotice(env)) {\n return;\n }\n try {\n const notice = await availablePiprUpdateNotice({\n currentVersion: cliPackage.version,\n fetch: options.updateNoticeFetch,\n timeoutMs: 750,\n });\n if (notice) {\n (options.writeUpdateNotice ?? console.error)(\n `pipr ${notice.latestVersion} is available (current ${notice.currentVersion}). ` +\n \"Run `pipr update` for release binaries, or reinstall @usepipr/cli with npm/Bun.\",\n );\n }\n } catch {\n return;\n }\n}\n\nfunction shouldSkipUpdateNotice(env: NodeJS.ProcessEnv): boolean {\n if (env.PIPR_UPDATE_NOTICE === \"0\") {\n return true;\n }\n if (env.PIPR_UPDATE_NOTICE === \"1\") {\n return false;\n }\n\n const ci = env.CI?.trim().toLowerCase();\n return (\n (ci !== undefined && ci !== \"\" && ci !== \"0\" && ci !== \"false\") ||\n env.GITHUB_ACTIONS !== undefined\n );\n}\n\nfunction isUpdateCommand(argv: string[]): boolean {\n const args = argv.slice(2);\n if (args[0] === \"--\") {\n return args[1] === \"update\";\n }\n return (\n args[0] === \"update\" ||\n (args.length >= 2 && args[0] === \"help\" && args[1] === \"update\") ||\n (args.length >= 2 && args[0] === \"--help\" && args[1] === \"update\")\n );\n}\n\nasync function runLocalReview(options: CliOptions & { base: string }): Promise<void> {\n const result = await runLocalReviewCommand({\n rootDir: process.cwd(),\n configDir: options.configDir,\n env: process.env,\n baseSha: options.base,\n headSha: options.head,\n piExecutable: options.piExecutable,\n logSink: localConsoleLogSink,\n taskLog: stderrTaskLog,\n });\n writeLocalReviewResult(result, options.json === true);\n}\n\ntype LocalReviewResult = Awaited<ReturnType<typeof runLocalReviewCommand>>;\n\nconst stderrTaskLog = {\n info(message: string) {\n console.error(`[info] ${message}`);\n },\n warn(message: string) {\n console.error(`[warn] ${message}`);\n },\n error(message: string) {\n console.error(`[error] ${message}`);\n },\n};\n\nconst localConsoleLogSink: ActionLogSink = {\n log(record) {\n console.error(formatLocalLogRecord(record));\n },\n async group(_name, run) {\n return await run();\n },\n};\n\nfunction formatLocalLogRecord(record: ActionLogRecord): string {\n const fields = Object.entries(record.fields)\n .map(([key, value]) => formatLocalLogField(key, value))\n .filter((field): field is string => field !== undefined);\n const prefix = formatLocalLogPrefix(record);\n const formatted = [...prefix, ...fields].join(\" \");\n return record.text === undefined ? formatted : `${formatted}\\n${record.text}`;\n}\n\nfunction formatLocalLogPrefix(record: ActionLogRecord): string[] {\n return [\"pipr\", localLogPlainLevels.has(record.level) ? \"\" : record.level, record.event].filter(\n Boolean,\n );\n}\n\nconst localLogNumberFields: Record<string, (value: number) => string> = {\n additions: (value) => `+${value}`,\n deletions: (value) => `-${value}`,\n durationMs: (value) =>\n `duration=${value < 1000 ? `${value}ms` : `${(value / 1000).toFixed(1)}s`}`,\n promptBytes: (value) => `prompt=${value}B`,\n stderrBytes: (value) => `stderr=${value}B`,\n stdoutBytes: (value) => `stdout=${value}B`,\n};\n\nconst localLogPlainLevels = new Set([\"info\", \"notice\"]);\n\nfunction formatLocalLogField(key: string, value: unknown): string | undefined {\n if (value == null) {\n return undefined;\n }\n\n return formatLocalLogFieldValue(key, value);\n}\n\nfunction formatLocalLogFieldValue(key: string, value: unknown): string {\n const formattedNumber =\n typeof value === \"number\" ? localLogNumberFields[key]?.(value) : undefined;\n return formattedNumber ?? `${key}=${formatLocalLogValue(value)}`;\n}\n\nconst localLogValueFormatters: Record<string, (value: unknown) => string> = {\n boolean: String,\n number: String,\n object: (value) =>\n Array.isArray(value)\n ? value.length === 0\n ? \"-\"\n : value.map(formatLocalLogValue).join(\",\")\n : JSON.stringify(value),\n string: (value) => {\n const text = String(value);\n return /\\s/.test(text) ? JSON.stringify(text) : text;\n },\n};\n\nfunction formatLocalLogValue(value: unknown): string {\n return (localLogValueFormatters[typeof value] ?? JSON.stringify)(value);\n}\n\nfunction writeLocalReviewResult(result: LocalReviewResult, json: boolean): void {\n if (json) {\n console.log(JSON.stringify(localReviewJson(result), null, 2));\n return;\n }\n if (result.kind === \"skipped\") {\n console.log(`skipped: ${result.skipReason ?? \"no task matched\"}`);\n return;\n }\n console.log(formatLocalReview(result));\n}\n\nfunction formatLocalReview(result: Extract<LocalReviewResult, { kind: \"review\" }>): string {\n const mainComment = stripMainCommentMarker(result.mainComment);\n const inlineFindings = result.inlineCommentDrafts.map((draft, index) => {\n const range =\n draft.startLine === draft.endLine\n ? `${draft.path}:${draft.startLine}`\n : `${draft.path}:${draft.startLine}-${draft.endLine}`;\n return [\n `${index + 1}. ${range}`,\n `Range: ${draft.finding.rangeId ?? \"-\"}`,\n draft.finding.body,\n ].join(\"\\n\");\n });\n return inlineFindings.length === 0\n ? mainComment\n : [mainComment.trimEnd(), \"\", \"## Inline Findings\", \"\", inlineFindings.join(\"\\n\\n\")].join(\"\\n\");\n}\n\nfunction stripMainCommentMarker(comment: string): string {\n return comment\n .split(\"\\n\")\n .filter((line) => !line.startsWith(\"<!-- pipr:main-comment \"))\n .join(\"\\n\")\n .trimStart();\n}\n\nfunction localReviewJson(result: LocalReviewResult) {\n return {\n kind: result.kind,\n ...(result.kind === \"skipped\" ? { skipReason: result.skipReason } : {}),\n mainComment: result.mainComment,\n inlineFindings: result.inlineCommentDrafts,\n droppedFindings: result.validated.droppedFindings,\n taskChecks: result.taskChecks,\n provider: result.provider,\n providerModels: result.publicationPlan.metadata.providerModels ?? [result.provider.model],\n repairAttempted: result.repairAttempted,\n };\n}\n\nasync function runDryRun(options: CliOptions): Promise<void> {\n if (!options.event) {\n throw new Error(\"dry-run requires --event <path>\");\n }\n const result = await runDryRunCommand({\n rootDir: process.cwd(),\n configDir: options.configDir,\n env: process.env,\n eventPath: options.event,\n });\n writeConfigWarnings(result.warnings);\n console.log(\n inspect(\n {\n configSource: result.configSource,\n event: result.event,\n },\n { depth: 6, colors: false },\n ),\n );\n}\n","export function sanitizeTerminalMessage(message: string): string {\n let sanitized = \"\";\n for (let index = 0; index < message.length; index += 1) {\n const code = message.charCodeAt(index);\n if (code === 0x1b) {\n index = skipTerminalControlSequence(message, index);\n continue;\n }\n if (code === c1OscIntroducer) {\n index = skipUntilTerminator(message, index + 1, bellTerminator);\n continue;\n }\n if (c1StringControlIntroducers.has(code)) {\n index = skipUntilTerminator(message, index + 1);\n continue;\n }\n if (code === c1CsiIntroducer) {\n index = skipCsiSequence(message, index + 1);\n continue;\n }\n if (isUnsafeTerminalControl(code)) {\n continue;\n }\n sanitized += message[index];\n }\n return sanitized;\n}\n\nconst oscIntroducer = 0x5d;\nconst csiIntroducer = 0x5b;\nconst c1OscIntroducer = 0x9d;\nconst c1CsiIntroducer = 0x9b;\nconst bellTerminator = 0x07;\nconst stringTerminator = 0x9c;\nconst stringControlIntroducers = new Set([0x50, 0x58, 0x5e, 0x5f]);\nconst c1StringControlIntroducers = new Set([0x90, 0x98, 0x9e, 0x9f]);\n\nfunction skipTerminalControlSequence(message: string, index: number): number {\n const next = message.charCodeAt(index + 1);\n if (Number.isNaN(next)) {\n return index;\n }\n if (next === oscIntroducer) {\n return skipUntilTerminator(message, index + 2, bellTerminator);\n }\n if (stringControlIntroducers.has(next)) {\n return skipUntilTerminator(message, index + 2);\n }\n if (next === csiIntroducer) {\n return skipCsiSequence(message, index + 2);\n }\n if (isEscapeIntermediate(next)) {\n return skipEscapeSequenceWithIntermediates(message, index + 1);\n }\n if (isSingleEscapeSequenceFinal(next)) {\n return index + 1;\n }\n return index;\n}\n\nfunction skipCsiSequence(message: string, index: number): number {\n for (let cursor = index; cursor < message.length; cursor += 1) {\n const code = message.charCodeAt(cursor);\n if (code >= 0x40 && code <= 0x7e) {\n return cursor;\n }\n }\n return message.length - 1;\n}\n\nfunction skipUntilTerminator(message: string, index: number, terminator?: number): number {\n for (let cursor = index; cursor < message.length; cursor += 1) {\n const code = message.charCodeAt(cursor);\n if (code === stringTerminator) {\n return cursor;\n }\n if (terminator !== undefined && code === terminator) {\n return cursor;\n }\n if (code === 0x1b && cursor + 1 < message.length && message.charCodeAt(cursor + 1) === 0x5c) {\n return cursor + 1;\n }\n }\n return message.length - 1;\n}\n\nfunction skipEscapeSequenceWithIntermediates(message: string, index: number): number {\n for (let cursor = index; cursor < message.length; cursor += 1) {\n const code = message.charCodeAt(cursor);\n if (isEscapeIntermediate(code)) {\n continue;\n }\n if (isSingleEscapeSequenceFinal(code)) {\n return cursor;\n }\n return Math.max(cursor - 1, index);\n }\n return message.length - 1;\n}\n\nfunction isEscapeIntermediate(code: number): boolean {\n return code >= 0x20 && code <= 0x2f;\n}\n\nfunction isSingleEscapeSequenceFinal(code: number): boolean {\n return code >= 0x30 && code <= 0x7e;\n}\n\nfunction isUnsafeTerminalControl(code: number): boolean {\n return (code < 0x20 && code !== 0x09 && code !== 0x0a) || (code >= 0x7f && code <= 0x9f);\n}\n","#!/usr/bin/env bun\nimport * as core from \"@actions/core\";\nimport { PublicationError } from \"@usepipr/runtime\";\nimport { runMain } from \"./runner.js\";\nimport { sanitizeTerminalMessage } from \"./terminal-output.js\";\n\nconst env = process.env;\n\nrunMain({ env }).catch((error) => handleFatalError(error, env));\n\nfunction handleFatalError(error: unknown, env: NodeJS.ProcessEnv): void {\n const message = error instanceof Error ? error.message : String(error);\n const sanitizedMessage = sanitizeTerminalMessage(message);\n if (env.GITHUB_ACTIONS !== \"true\") {\n console.error(`error: ${sanitizedMessage}`);\n process.exit(1);\n }\n writeGitHubActionsFailure(error, sanitizedMessage);\n process.exitCode = 1;\n}\n\nfunction writeGitHubActionsFailure(error: unknown, message: string): void {\n if (error instanceof PublicationError && error.result) {\n core.setOutput(\"publication\", JSON.stringify(error.result));\n core.error(`pipr publication metadata: ${JSON.stringify(error.result)}`);\n }\n core.setFailed(message);\n}\n"],"mappings":"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"}
1
+ {"version":3,"file":"main.mjs","names":["cliPackage.version","cliPackage.version"],"sources":["../package.json","../src/skill-catalog.ts","../src/skills.ts","../src/release/targets.ts","../src/update.ts","../src/runner.ts","../src/terminal-output.ts","../src/main.ts"],"sourcesContent":["","import { readdir } from \"node:fs/promises\";\nimport path from \"node:path\";\n\nexport const bundledSkillName = \"pipr-setup\";\nconst bundledSkillFilePaths = new Set([\n \"SKILL.md\",\n \"references/config-patterns.md\",\n \"references/recipes.md\",\n]);\n\nexport type BundledSkillFile = {\n path: string;\n contents: string;\n};\n\nexport type BundledSkill = {\n name: string;\n description: string;\n files: BundledSkillFile[];\n};\n\nexport type BundledSkillCatalog = {\n skills: BundledSkill[];\n};\n\nexport function singleBundledSkill(catalog: BundledSkillCatalog): BundledSkill {\n const [skill] = catalog.skills;\n if (catalog.skills.length !== 1 || skill?.name !== bundledSkillName) {\n throw new Error(\n `Expected exactly one bundled skill named '${bundledSkillName}', found: ${catalog.skills\n .map((item) => item.name)\n .join(\", \")}`,\n );\n }\n return skill;\n}\n\nexport function containedSkillFilePath(root: string, relativePath: string): string {\n if (path.isAbsolute(relativePath)) {\n throw new Error(`Bundled skill file path must be relative: ${relativePath}`);\n }\n const resolvedRoot = path.resolve(root);\n const target = path.resolve(resolvedRoot, relativePath);\n if (target !== resolvedRoot && !target.startsWith(`${resolvedRoot}${path.sep}`)) {\n throw new Error(`Bundled skill file path escapes the skill directory: ${relativePath}`);\n }\n return target;\n}\n\nexport async function readBundledSkillCatalog(skillsRoot: string): Promise<BundledSkillCatalog> {\n const entries = await readdir(skillsRoot, { withFileTypes: true });\n const skills = await Promise.all(\n entries\n .filter((entry) => entry.isDirectory())\n .map(async (entry) => {\n const skillDir = path.join(skillsRoot, entry.name);\n const files = await readSkillFiles(skillDir);\n validateBundledSkillFiles(entry.name, files);\n const skillMd = files.find((file) => file.path === \"SKILL.md\");\n if (!skillMd) {\n throw new Error(`${skillDir}: missing SKILL.md`);\n }\n return {\n name: entry.name,\n description: frontmatterDescription(skillMd.contents),\n files,\n };\n }),\n );\n const catalog = { skills: skills.sort((left, right) => left.name.localeCompare(right.name)) };\n singleBundledSkill(catalog);\n return catalog;\n}\n\nasync function readSkillFiles(skillDir: string, prefix = \"\"): Promise<BundledSkillFile[]> {\n const entries = await readdir(path.join(skillDir, prefix), { withFileTypes: true });\n const files = await Promise.all(\n entries\n .filter((entry) => !entry.name.startsWith(\".\"))\n .sort((left, right) => left.name.localeCompare(right.name))\n .map(async (entry) => {\n const relativePath = prefix ? path.join(prefix, entry.name) : entry.name;\n if (entry.isDirectory()) {\n return await readSkillFiles(skillDir, relativePath);\n }\n if (!entry.isFile()) {\n return [];\n }\n const contents = await Bun.file(path.join(skillDir, relativePath)).text();\n return [{ path: relativePath.split(path.sep).join(\"/\"), contents }];\n }),\n );\n return files.flat();\n}\n\nfunction frontmatterDescription(contents: string): string {\n const frontmatter = contents.match(/^---\\n(?<body>[\\s\\S]*?)\\n---/u)?.groups?.body;\n const description = frontmatter\n ?.split(\"\\n\")\n .find((line) => line.startsWith(\"description:\"))\n ?.replace(/^description:\\s*/u, \"\")\n .trim()\n .replace(/^[\"']|[\"']$/gu, \"\");\n if (!description) {\n throw new Error(\"Bundled skill SKILL.md is missing a description\");\n }\n return description;\n}\n\nfunction validateBundledSkillFiles(skillName: string, files: BundledSkillFile[]): void {\n if (skillName !== bundledSkillName) {\n return;\n }\n const found = new Set(files.map((file) => file.path));\n const unexpected = [...found].filter((filePath) => !bundledSkillFilePaths.has(filePath));\n const missing = [...bundledSkillFilePaths].filter((filePath) => !found.has(filePath));\n if (unexpected.length > 0 || missing.length > 0) {\n throw new Error(\n `${bundledSkillName} bundled files must match the release allowlist; ` +\n `unexpected: ${unexpected.join(\", \") || \"-\"}; missing: ${missing.join(\", \") || \"-\"}`,\n );\n }\n}\n","import { lstat, mkdir, mkdtemp, readdir, rename, rm } from \"node:fs/promises\";\nimport os from \"node:os\";\nimport path from \"node:path\";\nimport cliPackage from \"../package.json\" with { type: \"json\" };\nimport {\n type BundledSkill,\n type BundledSkillCatalog,\n type BundledSkillFile,\n bundledSkillName,\n containedSkillFilePath,\n readBundledSkillCatalog,\n singleBundledSkill,\n} from \"./skill-catalog.js\";\n\ndeclare const PIPR_EMBEDDED_SKILLS: string | undefined;\n\nlet skillPromise: Promise<BundledSkill> | undefined;\n\ntype SkillCatalogAttempt =\n | { catalog: BundledSkillCatalog; skillsRoot: string }\n | { error: string; skillsRoot: string };\n\nexport async function resolveBundledSkill(): Promise<BundledSkill> {\n skillPromise ??= loadBundledSkill();\n return await skillPromise;\n}\n\nexport function formatBundledSkill(skill: BundledSkill): string {\n const files = [...skill.files].sort(compareSkillFiles);\n return [\n `# ${skill.name}`,\n \"\",\n skill.description,\n \"\",\n ...files.flatMap((file) => [\n `----- BEGIN SKILL FILE: ${file.path} -----`,\n file.contents.trimEnd(),\n `----- END SKILL FILE: ${file.path} -----`,\n \"\",\n ]),\n ].join(\"\\n\");\n}\n\nfunction compareSkillFiles(left: BundledSkillFile, right: BundledSkillFile): number {\n if (left.path === \"SKILL.md\") {\n return -1;\n }\n if (right.path === \"SKILL.md\") {\n return 1;\n }\n return left.path.localeCompare(right.path);\n}\n\nexport async function materializeBundledSkill(): Promise<string> {\n const skill = await resolveBundledSkill();\n const versionDir = path.join(skillCacheRoot(), cliPackage.version);\n const skillDir = path.join(versionDir, skill.name);\n await mkdir(versionDir, { recursive: true });\n const stagingDir = await mkdtemp(path.join(versionDir, `${bundledSkillName}-`));\n try {\n for (const file of skill.files) {\n await writeSkillFile(stagingDir, file);\n }\n if (await skillDirectoryMatches(skillDir, skill.files)) {\n await rm(stagingDir, { recursive: true, force: true });\n return skillDir;\n }\n await rm(skillDir, { recursive: true, force: true });\n await renameSkillDirectory(stagingDir, skillDir, skill.files);\n } catch (error) {\n await rm(stagingDir, { recursive: true, force: true });\n throw error;\n }\n return skillDir;\n}\n\nasync function loadBundledSkill(): Promise<BundledSkill> {\n const embedded = embeddedSkillCatalog();\n return singleBundledSkill(embedded ?? (await loadFilesystemSkillCatalog()));\n}\n\nasync function loadFilesystemSkillCatalog(): Promise<BundledSkillCatalog> {\n const attempts = await Promise.all(skillRootCandidates().map(readSkillCatalogAttempt));\n const loaded = attempts.find(\n (attempt): attempt is Extract<SkillCatalogAttempt, { catalog: BundledSkillCatalog }> =>\n \"catalog\" in attempt,\n );\n if (loaded) {\n return loaded.catalog;\n }\n throw new Error(\n `Unable to load bundled Pipr skills.\\n${attempts\n .map((attempt) => `${attempt.skillsRoot}: ${\"error\" in attempt ? attempt.error : \"loaded\"}`)\n .join(\"\\n\")}`,\n );\n}\n\nasync function readSkillCatalogAttempt(skillsRoot: string): Promise<SkillCatalogAttempt> {\n try {\n return { skillsRoot, catalog: await readBundledSkillCatalog(skillsRoot) };\n } catch (error) {\n return { skillsRoot, error: error instanceof Error ? error.message : String(error) };\n }\n}\n\nfunction embeddedSkillCatalog(): BundledSkillCatalog | undefined {\n if (typeof PIPR_EMBEDDED_SKILLS !== \"string\" || PIPR_EMBEDDED_SKILLS.length === 0) {\n return undefined;\n }\n return JSON.parse(PIPR_EMBEDDED_SKILLS) as BundledSkillCatalog;\n}\n\nfunction skillRootCandidates(): string[] {\n const here = import.meta.dirname;\n return [path.join(here, \"skills\"), path.resolve(here, \"../../../skills\")];\n}\n\nasync function writeSkillFile(skillDir: string, file: BundledSkillFile): Promise<void> {\n const target = containedSkillFilePath(skillDir, file.path);\n await mkdir(path.dirname(target), { recursive: true });\n await Bun.write(target, file.contents);\n}\n\nasync function renameSkillDirectory(\n stagingDir: string,\n skillDir: string,\n files: BundledSkillFile[],\n): Promise<void> {\n try {\n await rename(stagingDir, skillDir);\n } catch (error) {\n if (isExistingDirectoryError(error) && (await skillDirectoryMatches(skillDir, files))) {\n await rm(stagingDir, { recursive: true, force: true });\n return;\n }\n throw error;\n }\n}\n\nasync function skillDirectoryMatches(\n skillDir: string,\n files: BundledSkillFile[],\n): Promise<boolean> {\n try {\n return (\n (await skillDirectoryPathsMatch(skillDir, files)) &&\n (await skillDirectoryContentsMatch(skillDir, files))\n );\n } catch {\n return false;\n }\n}\n\nasync function skillDirectoryPathsMatch(\n skillDir: string,\n files: BundledSkillFile[],\n): Promise<boolean> {\n const actualPaths = await listSkillDirectoryEntries(skillDir);\n const expectedPaths = files.map((file) => file.path).sort();\n return (\n actualPaths.length === expectedPaths.length &&\n actualPaths.every((value, index) => value === expectedPaths[index])\n );\n}\n\nasync function skillDirectoryContentsMatch(\n skillDir: string,\n files: BundledSkillFile[],\n): Promise<boolean> {\n for (const file of files) {\n if (!(await skillFileMatches(skillDir, file))) {\n return false;\n }\n }\n return true;\n}\n\nasync function skillFileMatches(skillDir: string, file: BundledSkillFile): Promise<boolean> {\n const target = containedSkillFilePath(skillDir, file.path);\n return (await lstat(target)).isFile() && (await Bun.file(target).text()) === file.contents;\n}\n\nasync function listSkillDirectoryEntries(skillDir: string, prefix = \"\"): Promise<string[]> {\n const entries = await readdir(path.join(skillDir, prefix), { withFileTypes: true });\n const paths = await Promise.all(\n entries\n .filter((entry) => !entry.name.startsWith(\".\"))\n .map(async (entry) => {\n const relativePath = prefix ? path.join(prefix, entry.name) : entry.name;\n if (entry.isDirectory()) {\n return await listSkillDirectoryEntries(skillDir, relativePath);\n }\n return [relativePath.split(path.sep).join(\"/\")];\n }),\n );\n return paths.flat().sort();\n}\n\nconst existingDirectoryErrorCodes = new Set([\"EEXIST\", \"ENOTEMPTY\"]);\n\nfunction isExistingDirectoryError(error: unknown): boolean {\n return existingDirectoryErrorCodes.has((error as { code?: string } | undefined)?.code ?? \"\");\n}\n\nfunction skillCacheRoot(): string {\n const override = process.env.PIPR_SKILL_CACHE_DIR;\n if (override && override.trim().length > 0) {\n return path.resolve(override);\n }\n const cacheHome = process.env.XDG_CACHE_HOME || path.join(os.homedir(), \".cache\");\n return path.join(cacheHome, \"pipr\", \"skills\");\n}\n","export type ReleasePlatform = {\n platform: NodeJS.Platform;\n arch: NodeJS.Architecture;\n};\n\nexport type ReleaseTarget = ReleasePlatform & {\n target: string;\n outfile: string;\n};\n\nexport const releaseTargets: ReleaseTarget[] = [\n { platform: \"linux\", arch: \"x64\", target: \"bun-linux-x64-baseline\", outfile: \"pipr-linux-x64\" },\n { platform: \"linux\", arch: \"arm64\", target: \"bun-linux-arm64\", outfile: \"pipr-linux-arm64\" },\n { platform: \"darwin\", arch: \"x64\", target: \"bun-darwin-x64\", outfile: \"pipr-darwin-x64\" },\n {\n platform: \"darwin\",\n arch: \"arm64\",\n target: \"bun-darwin-arm64\",\n outfile: \"pipr-darwin-arm64\",\n },\n];\n\nexport function releaseTargetForPlatform(platform: ReleasePlatform): ReleaseTarget | undefined {\n return releaseTargets.find(\n (target) => target.platform === platform.platform && target.arch === platform.arch,\n );\n}\n\nexport function releaseAssetForPlatform(platform: ReleasePlatform): string {\n const target = releaseTargetForPlatform(platform);\n if (target) {\n return target.outfile;\n }\n if (!releaseTargets.some((item) => item.platform === platform.platform)) {\n throw new Error(`pipr update unsupported OS: ${platform.platform}`);\n }\n throw new Error(`pipr update unsupported architecture: ${platform.arch}`);\n}\n","import { createHash } from \"node:crypto\";\nimport { chmod, mkdtemp, open, rename, rm } from \"node:fs/promises\";\nimport os from \"node:os\";\nimport path from \"node:path\";\nimport type { ReleasePlatform } from \"./release/targets.js\";\nimport { releaseAssetForPlatform } from \"./release/targets.js\";\n\nexport { releaseAssetForPlatform } from \"./release/targets.js\";\n\nexport type UpdateResult =\n | { kind: \"up-to-date\"; version: string }\n | { kind: \"updated\"; previousVersion: string; version: string };\n\nexport type UpdateNotice = {\n currentVersion: string;\n latestVersion: string;\n};\n\ntype ReleaseFetch = (url: string, init?: RequestInit) => Promise<Response>;\n\ntype UpdateOptions = {\n currentVersion: string;\n executablePath: string;\n fetch?: ReleaseFetch;\n platform?: ReleasePlatform;\n};\n\ntype UpdateNoticeOptions = {\n currentVersion: string;\n fetch?: ReleaseFetch;\n timeoutMs?: number;\n};\n\ntype LatestRelease = {\n tag_name?: unknown;\n};\n\nconst officialRepo = \"somus/pipr\";\nconst packageManagerUpdateHelp = [\n \"pipr update only supports compiled GitHub Release binaries.\",\n \"If you installed with npm, run: npm install -g @usepipr/cli@latest\",\n \"If you installed with Bun, run: bun install -g @usepipr/cli@latest\",\n \"If you installed from source, pull the repository and rebuild the CLI.\",\n].join(\"\\n\");\n\nexport function resolveCurrentExecutablePath(\n options: { argv?: string[]; execPath?: string } = {},\n): string {\n const execPath = options.execPath ?? process.execPath;\n const argv = options.argv ?? process.argv;\n const execName = path.basename(execPath).toLowerCase();\n const scriptPath = argv[1];\n if (\n execName === \"bun\" ||\n execName.startsWith(\"bun-\") ||\n execName === \"node\" ||\n execName.startsWith(\"node-\") ||\n scriptPath?.endsWith(\".ts\") ||\n scriptPath?.endsWith(\".mjs\")\n ) {\n throw new Error(packageManagerUpdateHelp);\n }\n return execPath;\n}\n\nexport async function runPiprUpdate(options: UpdateOptions): Promise<UpdateResult> {\n if (!isStableSemver(options.currentVersion)) {\n throw new Error(\n `current pipr version is not a stable semver version: ${options.currentVersion}`,\n );\n }\n const fetchRelease = options.fetch ?? globalThis.fetch.bind(globalThis);\n const platform = options.platform ?? { platform: process.platform, arch: process.arch };\n const asset = releaseAssetForPlatform(platform);\n const release = await latestRelease(fetchRelease);\n const version = release.version;\n if (compareSemver(version, options.currentVersion) <= 0) {\n return { kind: \"up-to-date\", version: options.currentVersion };\n }\n const releaseDownloadBaseUrl = `https://github.com/${officialRepo}/releases/download/${release.tag}`;\n const [binary, checksums] = await Promise.all([\n downloadBytes(fetchRelease, `${releaseDownloadBaseUrl}/${asset}`),\n downloadText(fetchRelease, `${releaseDownloadBaseUrl}/SHA256SUMS`),\n ]);\n verifyChecksum(binary, expectedChecksum(checksums, asset), asset);\n\n const tempPath = path.join(\n path.dirname(options.executablePath),\n `.pipr-update-${process.pid}-${Date.now()}`,\n );\n let createdTemp = false;\n let replaced = false;\n try {\n const tempFile = await open(tempPath, \"wx\", 0o700);\n createdTemp = true;\n try {\n await tempFile.writeFile(binary);\n } finally {\n await tempFile.close();\n }\n await chmod(tempPath, 0o755);\n const binaryVersion = await downloadedVersion(tempPath);\n if (!isStableSemver(binaryVersion)) {\n throw new Error(`downloaded pipr binary reported invalid version: ${binaryVersion}`);\n }\n if (binaryVersion !== version) {\n throw new Error(\n `downloaded pipr binary reported ${binaryVersion}, expected latest ${version}`,\n );\n }\n await rename(tempPath, options.executablePath);\n replaced = true;\n return { kind: \"updated\", previousVersion: options.currentVersion, version };\n } finally {\n if (createdTemp && !replaced) {\n await rm(tempPath, { force: true });\n }\n }\n}\n\nexport async function availablePiprUpdateNotice(\n options: UpdateNoticeOptions,\n): Promise<UpdateNotice | undefined> {\n if (!isStableSemver(options.currentVersion)) {\n return undefined;\n }\n const fetchRelease = withFetchTimeout(\n options.fetch ?? globalThis.fetch.bind(globalThis),\n options.timeoutMs,\n );\n const release = await latestRelease(fetchRelease);\n if (compareSemver(release.version, options.currentVersion) <= 0) {\n return undefined;\n }\n return { currentVersion: options.currentVersion, latestVersion: release.version };\n}\n\nfunction withFetchTimeout(fetchRelease: ReleaseFetch, timeoutMs: number | undefined): ReleaseFetch {\n if (timeoutMs === undefined) {\n return fetchRelease;\n }\n return async (url, init) => {\n const controller = new AbortController();\n const timeout = setTimeout(() => controller.abort(), timeoutMs);\n try {\n return await fetchRelease(url, { ...init, signal: controller.signal });\n } finally {\n clearTimeout(timeout);\n }\n };\n}\n\nasync function latestRelease(fetchRelease: ReleaseFetch): Promise<{\n tag: string;\n version: string;\n}> {\n const response = await fetchRelease(\n `https://api.github.com/repos/${officialRepo}/releases/latest`,\n );\n if (!response.ok) {\n throw new Error(`failed to fetch latest release metadata: HTTP ${response.status}`);\n }\n const release = (await response.json()) as LatestRelease;\n if (typeof release.tag_name !== \"string\") {\n throw new Error(\"latest release metadata is missing tag_name\");\n }\n const version = release.tag_name.replace(/^v/, \"\");\n if (!isStableSemver(version)) {\n throw new Error(`latest release tag is not a stable semver version: ${release.tag_name}`);\n }\n return { tag: release.tag_name, version };\n}\n\nasync function downloadBytes(\n fetchRelease: (url: string) => Promise<Response>,\n url: string,\n): Promise<Buffer> {\n const response = await fetchRelease(url);\n if (!response.ok) {\n throw new Error(`failed to download ${url}: HTTP ${response.status}`);\n }\n return Buffer.from(await response.arrayBuffer());\n}\n\nasync function downloadText(\n fetchRelease: (url: string) => Promise<Response>,\n url: string,\n): Promise<string> {\n const response = await fetchRelease(url);\n if (!response.ok) {\n throw new Error(`failed to download ${url}: HTTP ${response.status}`);\n }\n return await response.text();\n}\n\nfunction expectedChecksum(checksums: string, asset: string): string {\n for (const line of checksums.split(/\\r?\\n/)) {\n const [checksum, name] = line.trim().split(/\\s+/);\n if (name === asset && checksum) {\n return checksum;\n }\n }\n throw new Error(`checksum for ${asset} not found`);\n}\n\nfunction verifyChecksum(binary: Buffer, expected: string, asset: string): void {\n const actual = createHash(\"sha256\").update(binary).digest(\"hex\");\n if (actual !== expected) {\n throw new Error(`checksum mismatch for ${asset}`);\n }\n}\n\nasync function downloadedVersion(executablePath: string): Promise<string> {\n const validationCwd = await mkdtemp(path.join(os.tmpdir(), \"pipr-update-version-\"));\n try {\n const process = Bun.spawn([executablePath, \"--version\"], {\n cwd: validationCwd,\n env: {\n HOME: validationCwd,\n PATH: \"/usr/bin:/bin\",\n TMPDIR: validationCwd,\n },\n stderr: \"pipe\",\n stdout: \"pipe\",\n });\n const [exitCode, stdout, stderr] = await Promise.all([\n process.exited,\n process.stdout ? new Response(process.stdout).text() : \"\",\n process.stderr ? new Response(process.stderr).text() : \"\",\n ]);\n if (exitCode !== 0) {\n throw new Error(\n `downloaded pipr binary failed --version: ${stderr.trim() || stdout.trim() || exitCode}`,\n );\n }\n return stdout.trim();\n } finally {\n await rm(validationCwd, { force: true, recursive: true });\n }\n}\n\nfunction isStableSemver(version: string): boolean {\n return /^\\d+\\.\\d+\\.\\d+$/.test(version);\n}\n\nfunction compareSemver(left: string, right: string): number {\n const leftParts = left.split(\".\").map(Number);\n const rightParts = right.split(\".\").map(Number);\n for (let index = 0; index < 3; index += 1) {\n const difference = leftParts[index] - rightParts[index];\n if (difference !== 0) {\n return difference;\n }\n }\n return 0;\n}\n","import { inspect } from \"node:util\";\nimport * as core from \"@actions/core\";\nimport {\n type HostRunCommandResult,\n type RuntimeLogRecord,\n type RuntimeLogSink,\n runDryRunCommand,\n runHostRunCommand,\n runInitCommand,\n runInspectCommand,\n runLocalReviewCommand,\n runValidateCommand,\n supportedOfficialInitAdapters,\n supportedOfficialInitRecipes,\n} from \"@usepipr/runtime\";\nimport { Command, CommanderError } from \"commander\";\nimport cliPackage from \"../package.json\" with { type: \"json\" };\nimport { formatBundledSkill, materializeBundledSkill, resolveBundledSkill } from \"./skills.js\";\nimport {\n availablePiprUpdateNotice,\n resolveCurrentExecutablePath,\n runPiprUpdate,\n} from \"./update.js\";\n\ntype CliOptions = {\n configDir: string;\n database?: string;\n host?: string;\n hostname?: string;\n port?: string;\n repository?: string;\n workspace?: string;\n event?: string;\n force?: boolean;\n adapters?: string;\n recipe?: string;\n minimal?: boolean;\n requireEnv?: boolean;\n base?: string;\n head?: string;\n piExecutable?: string;\n json?: boolean;\n};\n\ntype MainOptions = {\n argv?: string[];\n env?: NodeJS.ProcessEnv;\n updateNoticeFetch?: typeof fetch;\n writeUpdateNotice?: (message: string) => void;\n};\n\nexport async function runMain(options: MainOptions = {}): Promise<void> {\n const argv = options.argv ?? process.argv;\n const env = options.env ?? process.env;\n if (!isUpdateCommand(argv)) {\n await writeAvailableUpdateNotice(options);\n }\n const program = createProgram({ exitOverride: env.GITHUB_ACTIONS === \"true\" });\n try {\n if (argv.length <= 2) {\n program.outputHelp();\n return;\n }\n await program.parseAsync(argv);\n } catch (error) {\n if (error instanceof CommanderError && error.exitCode === 0) {\n return;\n }\n throw error;\n }\n}\n\nfunction createProgram(options: { exitOverride?: boolean } = {}): Command {\n const program = new Command();\n program.name(\"pipr\").version(cliPackage.version).showHelpAfterError();\n if (options.exitOverride) {\n program.exitOverride();\n }\n program.addHelpText(\"after\", agentHelpText);\n\n program\n .command(\"init\")\n .description(\"Create editable TypeScript config\")\n .option(\"--config-dir <dir>\", \"Config directory\", \".pipr\")\n .option(\n \"--adapters <adapters>\",\n `Adapters to initialize (${supportedOfficialInitAdapters.join(\", \")}; use 'none' to skip adapter files)`,\n )\n .option(\"--recipe <recipe>\", `Starter recipe (${supportedOfficialInitRecipes.join(\", \")})`)\n .option(\"--minimal\", \"Scaffold a single-file .pipr/config.ts without package.json\")\n .option(\"--force\", \"Overwrite existing pipr files\")\n .action(runInit);\n\n program\n .command(\"host-run\")\n .description(\"Run a change request event through a Code Host Adapter\")\n .option(\"--host <host>\", \"Code host adapter\")\n .option(\"--event <path>\", \"Native event payload path\")\n .option(\"--config-dir <dir>\", \"Config directory\", \".pipr\")\n .action(runHostRun);\n\n const webhook = program.command(\"webhook\").description(\"Run trusted webhook ingress\");\n webhook\n .command(\"serve\")\n .description(\"Serve one repository with a durable webhook queue\")\n .requiredOption(\"--host <host>\", \"Code host adapter\")\n .requiredOption(\"--workspace <path>\", \"Trusted repository workspace\")\n .requiredOption(\"--repository <repository>\", \"Expected provider repository ID or path\")\n .option(\"--database <path>\", \"SQLite delivery database\", \".pipr/webhooks.sqlite\")\n .option(\"--hostname <hostname>\", \"Listen hostname\", \"127.0.0.1\")\n .option(\"--port <port>\", \"Listen port\", \"8787\")\n .option(\"--config-dir <dir>\", \"Config directory\", \".pipr\")\n .action(runWebhookServe);\n\n program\n .command(\"check\")\n .description(\"Type-load config and validate the runtime plan\")\n .option(\"--config-dir <dir>\", \"Config directory\", \".pipr\")\n .option(\"--require-env\", \"Require configured provider env vars\")\n .action(runCheck);\n\n program\n .command(\"dry-run\")\n .description(\"Load config and event without publishing\")\n .requiredOption(\"--event <path>\", \"Native event payload path\")\n .option(\"--host <host>\", \"Code host adapter\")\n .option(\"--config-dir <dir>\", \"Config directory\", \".pipr\")\n .action(runDryRun);\n\n program\n .command(\"inspect\")\n .description(\"Print models, agents, tasks, commands, and tools\")\n .option(\"--config-dir <dir>\", \"Config directory\", \".pipr\")\n .action(runInspect);\n\n program\n .command(\"review\")\n .description(\"Run configured change-request review tasks locally without publishing\")\n .requiredOption(\"--base <sha>\", \"Base commit SHA\")\n .option(\"--head <sha>\", \"Head commit SHA or ref; omitted reviews the working tree\")\n .option(\"--config-dir <dir>\", \"Config directory\", \".pipr\")\n .option(\"--pi-executable <path>\", \"Pi executable path\")\n .option(\"--json\", \"Print structured JSON output\")\n .action(runLocalReview);\n\n program.command(\"version\").description(\"Print the CLI version\").action(runVersion);\n\n program.command(\"update\").description(\"Update a GitHub Release binary install\").action(runUpdate);\n\n const skill = program\n .command(\"skill\")\n .description(\"Print the bundled Pipr setup skill\")\n .action(runSkillGet);\n skill\n .command(\"path\")\n .description(\"Materialize the bundled Pipr setup skill and print its directory path\")\n .action(runSkillPath);\n\n return program;\n}\n\nconst agentHelpText = `\n\nStart here (for AI agents):\n pipr skill\n\nThe Pipr setup skill ships with the CLI and is version-matched to this release.\nPrefer it over guessing commands or config shape from memory.\n\n skill Print the bundled setup skill and references\n skill path Materialize the setup skill and print its directory path\n`;\n\nasync function runHostRun(options: CliOptions): Promise<void> {\n const env = process.env;\n const isGitHubAction = env.GITHUB_ACTIONS === \"true\";\n const result = await runHostRunCommand({\n rootDir: hostRunRootDir(env),\n configDir: options.configDir,\n host: options.host,\n eventPath: options.event ?? env.PIPR_EVENT_PATH ?? env.GITHUB_EVENT_PATH,\n env,\n dryRun: env.PIPR_DRY_RUN === \"1\",\n logSink: isGitHubAction ? githubActionsLogSink : localConsoleLogSink,\n });\n if (isGitHubAction) {\n writeGitHubActionResult(result);\n return;\n }\n if (result.kind === \"ignored\") {\n console.log(`ignored: ${result.reason}`);\n return;\n }\n console.log(`pipr ${result.kind} completed for change #${result.event.change.number}`);\n}\n\nfunction hostRunRootDir(env: NodeJS.ProcessEnv): string {\n return (\n env.GITHUB_WORKSPACE ??\n env.CI_PROJECT_DIR ??\n env.BITBUCKET_CLONE_DIR ??\n env.BUILD_SOURCESDIRECTORY ??\n process.cwd()\n );\n}\n\nasync function runWebhookServe(options: CliOptions): Promise<void> {\n const { runWebhookServer } = await import(\"@usepipr/runtime\");\n const secret = process.env.PIPR_WEBHOOK_SECRET;\n if (!secret) throw new Error(\"PIPR_WEBHOOK_SECRET is required\");\n const host = webhookHost(options.host);\n const port = webhookPort(options.port);\n await runWebhookServer({\n host,\n workspace: options.workspace ?? process.cwd(),\n configDir: options.configDir,\n databasePath: options.database ?? \".pipr/webhooks.sqlite\",\n expectedRepository: options.repository ?? \"\",\n secret,\n hostname: options.hostname,\n port,\n env: process.env,\n });\n}\n\nfunction webhookHost(value: string | undefined): \"gitlab\" | \"azure-devops\" | \"bitbucket\" {\n if (value === \"gitlab\" || value === \"azure-devops\" || value === \"bitbucket\") return value;\n throw new Error(\"webhook serve supports --host gitlab, azure-devops, or bitbucket\");\n}\n\nfunction webhookPort(value: string | undefined): number {\n const port = Number(value);\n if (!Number.isInteger(port) || port < 1 || port > 65_535) {\n throw new Error(\"--port must be an integer from 1 to 65535\");\n }\n return port;\n}\n\nconst githubActionsLogSink: RuntimeLogSink = {\n log(record) {\n const line = JSON.stringify({\n level: record.level,\n event: record.event,\n ...record.fields,\n });\n githubActionLogWriters[record.level](\n record.text === undefined ? line : `${line}\\n${record.text}`,\n );\n },\n async group(name, run) {\n return await core.group(name, run);\n },\n};\n\nconst githubActionLogWriters = {\n info: core.info,\n notice: core.notice,\n warning: core.warning,\n error: core.error,\n debug: core.debug,\n} satisfies Record<RuntimeLogRecord[\"level\"], (message: string) => void>;\n\nfunction writeGitHubActionResult(result: HostRunCommandResult): void {\n if (result.kind === \"ignored\") {\n core.info(`pipr ignored event: ${result.reason}`);\n return;\n }\n writeLoadedGitHubActionResult(result);\n}\n\ntype LoadedGitHubActionResult = Exclude<HostRunCommandResult, { kind: \"ignored\" }>;\ntype PublishedGitHubActionResult = Exclude<LoadedGitHubActionResult, { kind: \"dry-run\" }>;\ntype CommandGitHubActionResult = Extract<\n PublishedGitHubActionResult,\n { kind: \"command-help\" | \"command-response\" }\n>;\ntype ReviewWorkflowGitHubActionResult = Exclude<\n PublishedGitHubActionResult,\n CommandGitHubActionResult\n>;\n\nfunction writeLoadedGitHubActionResult(result: LoadedGitHubActionResult): void {\n core.info(\n `pipr loaded change #${result.event.change.number} for ${result.event.repository.slug}`,\n );\n core.info(`pipr config source: ${result.configSource}`);\n if (result.kind === \"dry-run\") {\n writeDryRunGitHubActionResult(result);\n return;\n }\n writePublishedGitHubActionResult(result);\n}\n\nfunction writePublishedGitHubActionResult(result: PublishedGitHubActionResult): void {\n if (result.kind === \"command-help\" || result.kind === \"command-response\") {\n writeCommandGitHubActionResult(result);\n return;\n }\n writeReviewWorkflowGitHubActionResult(result);\n}\n\nfunction writeCommandGitHubActionResult(result: CommandGitHubActionResult): void {\n switch (result.kind) {\n case \"command-help\":\n writeCommandHelpGitHubActionResult(result);\n break;\n case \"command-response\":\n writeCommandResponseGitHubActionResult(result);\n break;\n default:\n result satisfies never;\n }\n}\n\nfunction writeReviewWorkflowGitHubActionResult(result: ReviewWorkflowGitHubActionResult): void {\n switch (result.kind) {\n case \"review\":\n writeReviewGitHubActionResult(result);\n break;\n case \"verifier\":\n writeVerifierGitHubActionResult(result);\n break;\n default:\n result satisfies never;\n }\n}\n\nfunction writeDryRunGitHubActionResult(\n result: Extract<HostRunCommandResult, { kind: \"dry-run\" }>,\n): void {\n void result;\n core.info(\"PIPR_DRY_RUN=1; stopping before review runtime, model, or GitHub publishing calls\");\n}\n\nfunction writeCommandHelpGitHubActionResult(\n result: Extract<HostRunCommandResult, { kind: \"command-help\" }>,\n): void {\n core.info(`pipr command help: ${result.reason}`);\n core.setOutput(\"main-comment\", result.body);\n}\n\nfunction writeCommandResponseGitHubActionResult(\n result: Extract<HostRunCommandResult, { kind: \"command-response\" }>,\n): void {\n core.info(\n `pipr command '${result.command}' published response comment (${result.publication.action})`,\n );\n core.setOutput(\"main-comment\", result.response.body);\n core.setOutput(\"publication\", JSON.stringify(result.publication));\n}\n\nfunction writeVerifierGitHubActionResult(\n result: Extract<HostRunCommandResult, { kind: \"verifier\" }>,\n): void {\n core.info(\n `pipr verifier processed review comment reply with ${result.errors.length} publication error(s)`,\n );\n warnInlineResolutionErrors(result.errors);\n core.setOutput(\"publication\", JSON.stringify({ inlineResolutionErrors: result.errors }));\n}\n\nfunction writeReviewGitHubActionResult(\n result: Extract<HostRunCommandResult, { kind: \"review\" }>,\n): void {\n core.info(\n `pipr review produced ${result.review.validated.validFindings.length} valid inline finding(s), ` +\n `${result.review.validated.droppedFindings.length} dropped finding(s)`,\n );\n core.info(\n `pipr published main comment (${result.publication.mainComment.action}) and ` +\n `${result.publication.inlineComments.posted} inline comment(s); ` +\n `${result.publication.inlineComments.skipped} skipped`,\n );\n warnInlineResolutionErrors(result.publication.metadata.inlineResolutionErrors);\n if (result.review.repairAttempted) {\n core.info(\"pipr repaired reviewer JSON once before validation\");\n }\n core.setOutput(\"main-comment\", result.review.mainComment);\n core.setOutput(\"inline-comments\", JSON.stringify(result.review.inlineCommentDrafts));\n core.setOutput(\"dropped-findings\", JSON.stringify(result.review.validated.droppedFindings));\n core.setOutput(\"publication\", JSON.stringify(result.publication));\n}\n\nfunction warnInlineResolutionErrors(errors: string[]): void {\n for (const error of errors) {\n core.warning(`pipr inline resolution failed: ${error}`);\n }\n}\n\nasync function runInit(options: CliOptions): Promise<void> {\n const result = await runInitCommand({\n rootDir: process.cwd(),\n configDir: options.configDir,\n force: options.force === true,\n adapters: options.adapters?.split(\",\").map((adapter) => adapter.trim()),\n recipe: options.recipe,\n minimal: options.minimal === true,\n });\n console.log(\n `created ${result.created.length} file(s)` +\n (result.overwritten.length > 0 ? `; overwrote ${result.overwritten.length}` : \"\"),\n );\n if (options.minimal === true) {\n console.log(\n \"For editor types, install @usepipr/sdk at the repo root: npm install -D @usepipr/sdk\",\n );\n }\n}\n\nasync function runCheck(options: CliOptions): Promise<void> {\n const settings = await runValidateCommand({\n rootDir: process.cwd(),\n configDir: options.configDir,\n env: process.env,\n requireProviderEnv: options.requireEnv === true,\n });\n console.log(`valid: ${settings.source}`);\n writeConfigWarnings(settings.warnings);\n}\n\nasync function runInspect(options: CliOptions): Promise<void> {\n const result = await runInspectCommand({\n rootDir: process.cwd(),\n configDir: options.configDir,\n env: process.env,\n });\n const { warnings, ...plan } = result;\n writeConfigWarnings(warnings);\n console.log(inspect(plan, { depth: 8, colors: false }));\n}\n\nfunction writeConfigWarnings(warnings: readonly string[]): void {\n for (const warning of warnings) {\n console.log(`warning: ${warning}`);\n }\n}\n\nasync function runSkillGet(): Promise<void> {\n console.log(formatBundledSkill(await resolveBundledSkill()));\n}\n\nasync function runSkillPath(): Promise<void> {\n console.log(await materializeBundledSkill());\n}\n\nfunction runVersion(): void {\n console.log(cliPackage.version);\n}\n\nasync function runUpdate(): Promise<void> {\n const result = await runPiprUpdate({\n currentVersion: cliPackage.version,\n executablePath: resolveCurrentExecutablePath(),\n });\n if (result.kind === \"up-to-date\") {\n console.log(`pipr ${result.version} is already up to date`);\n return;\n }\n console.log(`updated pipr from ${result.previousVersion} to ${result.version}`);\n}\n\nasync function writeAvailableUpdateNotice(options: MainOptions): Promise<void> {\n const env = options.env ?? process.env;\n if (shouldSkipUpdateNotice(env)) {\n return;\n }\n try {\n const notice = await availablePiprUpdateNotice({\n currentVersion: cliPackage.version,\n fetch: options.updateNoticeFetch,\n timeoutMs: 750,\n });\n if (notice) {\n (options.writeUpdateNotice ?? console.error)(\n `pipr ${notice.latestVersion} is available (current ${notice.currentVersion}). ` +\n \"Run `pipr update` for release binaries, or reinstall @usepipr/cli with npm/Bun.\",\n );\n }\n } catch {\n return;\n }\n}\n\nfunction shouldSkipUpdateNotice(env: NodeJS.ProcessEnv): boolean {\n if (env.PIPR_UPDATE_NOTICE === \"0\") {\n return true;\n }\n if (env.PIPR_UPDATE_NOTICE === \"1\") {\n return false;\n }\n\n const ci = env.CI?.trim().toLowerCase();\n return (\n (ci !== undefined && ci !== \"\" && ci !== \"0\" && ci !== \"false\") ||\n env.GITHUB_ACTIONS !== undefined\n );\n}\n\nfunction isUpdateCommand(argv: string[]): boolean {\n const args = argv.slice(2);\n if (args[0] === \"--\") {\n return args[1] === \"update\";\n }\n return (\n args[0] === \"update\" ||\n (args.length >= 2 && args[0] === \"help\" && args[1] === \"update\") ||\n (args.length >= 2 && args[0] === \"--help\" && args[1] === \"update\")\n );\n}\n\nasync function runLocalReview(options: CliOptions & { base: string }): Promise<void> {\n const result = await runLocalReviewCommand({\n rootDir: process.cwd(),\n configDir: options.configDir,\n env: process.env,\n baseSha: options.base,\n headSha: options.head,\n piExecutable: options.piExecutable,\n logSink: localConsoleLogSink,\n taskLog: stderrTaskLog,\n });\n writeLocalReviewResult(result, options.json === true);\n}\n\ntype LocalReviewResult = Awaited<ReturnType<typeof runLocalReviewCommand>>;\n\nconst stderrTaskLog = {\n info(message: string) {\n console.error(`[info] ${message}`);\n },\n warn(message: string) {\n console.error(`[warn] ${message}`);\n },\n error(message: string) {\n console.error(`[error] ${message}`);\n },\n};\n\nconst localConsoleLogSink: RuntimeLogSink = {\n log(record) {\n console.error(formatLocalLogRecord(record));\n },\n async group(_name, run) {\n return await run();\n },\n};\n\nfunction formatLocalLogRecord(record: RuntimeLogRecord): string {\n const fields = Object.entries(record.fields)\n .map(([key, value]) => formatLocalLogField(key, value))\n .filter((field): field is string => field !== undefined);\n const prefix = formatLocalLogPrefix(record);\n const formatted = [...prefix, ...fields].join(\" \");\n return record.text === undefined ? formatted : `${formatted}\\n${record.text}`;\n}\n\nfunction formatLocalLogPrefix(record: RuntimeLogRecord): string[] {\n return [\"pipr\", localLogPlainLevels.has(record.level) ? \"\" : record.level, record.event].filter(\n Boolean,\n );\n}\n\nconst localLogNumberFields: Record<string, (value: number) => string> = {\n additions: (value) => `+${value}`,\n deletions: (value) => `-${value}`,\n durationMs: (value) =>\n `duration=${value < 1000 ? `${value}ms` : `${(value / 1000).toFixed(1)}s`}`,\n promptBytes: (value) => `prompt=${value}B`,\n stderrBytes: (value) => `stderr=${value}B`,\n stdoutBytes: (value) => `stdout=${value}B`,\n};\n\nconst localLogPlainLevels = new Set([\"info\", \"notice\"]);\n\nfunction formatLocalLogField(key: string, value: unknown): string | undefined {\n if (value == null) {\n return undefined;\n }\n\n return formatLocalLogFieldValue(key, value);\n}\n\nfunction formatLocalLogFieldValue(key: string, value: unknown): string {\n const formattedNumber =\n typeof value === \"number\" ? localLogNumberFields[key]?.(value) : undefined;\n return formattedNumber ?? `${key}=${formatLocalLogValue(value)}`;\n}\n\nconst localLogValueFormatters: Record<string, (value: unknown) => string> = {\n boolean: String,\n number: String,\n object: (value) =>\n Array.isArray(value)\n ? value.length === 0\n ? \"-\"\n : value.map(formatLocalLogValue).join(\",\")\n : JSON.stringify(value),\n string: (value) => {\n const text = String(value);\n return /\\s/.test(text) ? JSON.stringify(text) : text;\n },\n};\n\nfunction formatLocalLogValue(value: unknown): string {\n return (localLogValueFormatters[typeof value] ?? JSON.stringify)(value);\n}\n\nfunction writeLocalReviewResult(result: LocalReviewResult, json: boolean): void {\n if (json) {\n console.log(JSON.stringify(localReviewJson(result), null, 2));\n return;\n }\n if (result.kind === \"skipped\") {\n console.log(`skipped: ${result.skipReason ?? \"no task matched\"}`);\n return;\n }\n console.log(formatLocalReview(result));\n}\n\nfunction formatLocalReview(result: Extract<LocalReviewResult, { kind: \"review\" }>): string {\n const mainComment = result.mainComment\n .split(\"\\n\")\n .filter((line) => !line.startsWith(\"<!-- pipr:main-comment \"))\n .join(\"\\n\")\n .trimStart();\n const inlineFindings = result.inlineCommentDrafts.map((draft, index) => {\n const range =\n draft.startLine === draft.endLine\n ? `${draft.path}:${draft.startLine}`\n : `${draft.path}:${draft.startLine}-${draft.endLine}`;\n return [\n `${index + 1}. ${range}`,\n `Range: ${draft.finding.rangeId ?? \"-\"}`,\n draft.finding.body,\n ].join(\"\\n\");\n });\n return inlineFindings.length === 0\n ? mainComment\n : [mainComment.trimEnd(), \"\", \"## Inline Findings\", \"\", inlineFindings.join(\"\\n\\n\")].join(\"\\n\");\n}\n\nfunction localReviewJson(result: LocalReviewResult) {\n return {\n kind: result.kind,\n ...(result.kind === \"skipped\" ? { skipReason: result.skipReason } : {}),\n mainComment: result.mainComment,\n inlineFindings: result.inlineCommentDrafts,\n droppedFindings: result.validated.droppedFindings,\n taskChecks: result.taskChecks,\n provider: result.provider,\n providerModels: result.publicationPlan.metadata.providerModels ?? [result.provider.model],\n repairAttempted: result.repairAttempted,\n };\n}\n\nasync function runDryRun(options: CliOptions): Promise<void> {\n if (!options.event) {\n throw new Error(\"dry-run requires --event <path>\");\n }\n const result = await runDryRunCommand({\n rootDir: process.cwd(),\n configDir: options.configDir,\n host: options.host,\n env: process.env,\n eventPath: options.event,\n });\n writeConfigWarnings(result.warnings);\n console.log(\n inspect(\n {\n configSource: result.configSource,\n event: result.event,\n },\n { depth: 6, colors: false },\n ),\n );\n}\n","export function sanitizeTerminalMessage(message: string): string {\n let sanitized = \"\";\n for (let index = 0; index < message.length; index += 1) {\n const code = message.charCodeAt(index);\n if (code === 0x1b) {\n index = skipTerminalControlSequence(message, index);\n continue;\n }\n if (code === c1OscIntroducer) {\n index = skipUntilTerminator(message, index + 1, bellTerminator);\n continue;\n }\n if (c1StringControlIntroducers.has(code)) {\n index = skipUntilTerminator(message, index + 1);\n continue;\n }\n if (code === c1CsiIntroducer) {\n index = skipCsiSequence(message, index + 1);\n continue;\n }\n if (isUnsafeTerminalControl(code)) {\n continue;\n }\n sanitized += message[index];\n }\n return sanitized;\n}\n\nconst oscIntroducer = 0x5d;\nconst csiIntroducer = 0x5b;\nconst c1OscIntroducer = 0x9d;\nconst c1CsiIntroducer = 0x9b;\nconst bellTerminator = 0x07;\nconst stringTerminator = 0x9c;\nconst stringControlIntroducers = new Set([0x50, 0x58, 0x5e, 0x5f]);\nconst c1StringControlIntroducers = new Set([0x90, 0x98, 0x9e, 0x9f]);\n\nfunction skipTerminalControlSequence(message: string, index: number): number {\n const next = message.charCodeAt(index + 1);\n if (Number.isNaN(next)) {\n return index;\n }\n if (next === oscIntroducer) {\n return skipUntilTerminator(message, index + 2, bellTerminator);\n }\n if (stringControlIntroducers.has(next)) {\n return skipUntilTerminator(message, index + 2);\n }\n if (next === csiIntroducer) {\n return skipCsiSequence(message, index + 2);\n }\n if (isEscapeIntermediate(next)) {\n return skipEscapeSequenceWithIntermediates(message, index + 1);\n }\n if (isSingleEscapeSequenceFinal(next)) {\n return index + 1;\n }\n return index;\n}\n\nfunction skipCsiSequence(message: string, index: number): number {\n for (let cursor = index; cursor < message.length; cursor += 1) {\n const code = message.charCodeAt(cursor);\n if (code >= 0x40 && code <= 0x7e) {\n return cursor;\n }\n }\n return message.length - 1;\n}\n\nfunction skipUntilTerminator(message: string, index: number, terminator?: number): number {\n for (let cursor = index; cursor < message.length; cursor += 1) {\n const code = message.charCodeAt(cursor);\n if (code === stringTerminator) {\n return cursor;\n }\n if (terminator !== undefined && code === terminator) {\n return cursor;\n }\n if (code === 0x1b && cursor + 1 < message.length && message.charCodeAt(cursor + 1) === 0x5c) {\n return cursor + 1;\n }\n }\n return message.length - 1;\n}\n\nfunction skipEscapeSequenceWithIntermediates(message: string, index: number): number {\n for (let cursor = index; cursor < message.length; cursor += 1) {\n const code = message.charCodeAt(cursor);\n if (isEscapeIntermediate(code)) {\n continue;\n }\n if (isSingleEscapeSequenceFinal(code)) {\n return cursor;\n }\n return Math.max(cursor - 1, index);\n }\n return message.length - 1;\n}\n\nfunction isEscapeIntermediate(code: number): boolean {\n return code >= 0x20 && code <= 0x2f;\n}\n\nfunction isSingleEscapeSequenceFinal(code: number): boolean {\n return code >= 0x30 && code <= 0x7e;\n}\n\nfunction isUnsafeTerminalControl(code: number): boolean {\n return (code < 0x20 && code !== 0x09 && code !== 0x0a) || (code >= 0x7f && code <= 0x9f);\n}\n","#!/usr/bin/env bun\nimport * as core from \"@actions/core\";\nimport { PublicationError } from \"@usepipr/runtime\";\nimport { runMain } from \"./runner.js\";\nimport { sanitizeTerminalMessage } from \"./terminal-output.js\";\n\nconst env = process.env;\n\nrunMain({ env }).catch((error) => handleFatalError(error, env));\n\nfunction handleFatalError(error: unknown, env: NodeJS.ProcessEnv): void {\n const message = error instanceof Error ? error.message : String(error);\n const sanitizedMessage = sanitizeTerminalMessage(message);\n if (env.GITHUB_ACTIONS !== \"true\") {\n console.error(`error: ${sanitizedMessage}`);\n process.exit(1);\n }\n writeGitHubActionsFailure(error, sanitizedMessage);\n process.exitCode = 1;\n}\n\nfunction writeGitHubActionsFailure(error: unknown, message: string): void {\n if (error instanceof PublicationError && error.result) {\n core.setOutput(\"publication\", JSON.stringify(error.result));\n core.error(`pipr publication metadata: ${JSON.stringify(error.result)}`);\n }\n core.setFailed(message);\n}\n"],"mappings":"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"}
@@ -1,25 +1,25 @@
1
1
  ---
2
2
  name: pipr-setup
3
- description: Install and configure Pipr through a short interview. Use when a user wants an agent to add Pipr to a repository, customize .pipr/config.ts, choose review recipes, wire GitHub Actions, or verify Pipr CLI setup.
3
+ description: Install and configure Pipr through a short interview. Use when a user wants an agent to add Pipr to a repository, customize .pipr/config.ts, choose review recipes, configure a supported code host integration, or verify Pipr CLI setup.
4
4
  disable-model-invocation: true
5
5
  ---
6
6
 
7
- # Pipr Setup
7
+ # Pipr setup
8
8
 
9
9
  Use this skill to add Pipr to a repository and produce a custom Pipr Configuration, not just a stock `pipr init` output.
10
10
 
11
- ## Ground First
11
+ ## Ground first
12
12
 
13
13
  Inspect before asking:
14
14
 
15
15
  - Repository instructions and existing AI agent guidance.
16
- - Existing `.pipr/`, `.github/workflows/pipr.yml`, provider secret names or workflow mappings, and package manager files. Do not open `.env*` or other files that may contain raw secret values; ask for missing secret names instead.
16
+ - Existing `.pipr/`, generated adapter files, provider secret names, integration mappings, and package manager files. Do not open `.env*` or other files that may contain raw secret values; ask for missing secret names instead.
17
17
  - Project language, test layout, dependency manifests, generated files, docs, and CI workflows.
18
- - Existing pull request review expectations in docs, templates, or contribution guides.
18
+ - Existing change request review expectations in docs, templates, or contribution guides.
19
19
 
20
20
  Completion criterion: you know whether this is a new setup or an edit, which files Pipr may touch, and which repo-specific review policies can be inferred without asking.
21
21
 
22
- ## Install Check
22
+ ## Install check
23
23
 
24
24
  1. Run `command -v pipr` and verify with `pipr --help`. Do not rely on `pipr --version`.
25
25
  2. If `pipr` is missing, detect the OS and architecture. On Linux and macOS x64 or arm64, ask before running the official release installer for a specific release tag. Do not execute installer scripts from a mutable branch such as `main`.
@@ -39,15 +39,15 @@ Completion criterion: you know whether this is a new setup or an edit, which fil
39
39
 
40
40
  Completion criterion: a `pipr` command is available, and the user has approved any install command that changes their machine.
41
41
 
42
- ## Interview Gate
42
+ ## Interview gate
43
43
 
44
44
  Do not run `pipr init` until recipe, model, secrets, triggers, publication behavior, and existing-file handling are explicit.
45
45
  Defaults are allowed only when the user says to use Pipr defaults, accepts your proposed defaults, or provided equivalent intent.
46
46
  Combine questions so the interview stays short.
47
47
 
48
- - Existing-file handling: config directory, GitHub workflow generation, and whether existing Pipr files may be edited. Never use `pipr init --force` without explicit approval.
48
+ - Existing-file handling: config directory, selected adapter files, and whether existing Pipr files may be edited. Never use `pipr init --force` without explicit approval.
49
49
  - Recipe or review goal: general review, bugs, security, quality gate, dependency risk, PR hygiene, diagnostics, briefing, changelog, interactive ask, CI triage, multi-agent review, or durable memory tools.
50
- - Provider policy: provider, model, secret env var names, fallback model, and whether local runs should require provider env vars.
50
+ - Provider policy: GitHub, GitLab, Azure DevOps, Bitbucket, or no generated adapter files; model and code-host secret names; fallback model; and whether local runs should require provider env vars.
51
51
  - Trigger policy: automatic change request actions, `@pipr` commands, command permissions, local review behavior, and command-only workflows.
52
52
  - Publication policy: inline comment cap, check runs, aggregate checks, required gates, auto-resolve behavior, and who may trigger verifier replies.
53
53
  - Repo policy: path include/exclude scopes, generated or lockfile rules, test and docs expectations, package manager quirks, security-sensitive areas, and release-note conventions.
@@ -56,11 +56,14 @@ Example compact interview:
56
56
 
57
57
  ```text
58
58
  Before I initialize Pipr, choose the setup policy:
59
- 1. Recipe or goal: default-review, bug-hunter, security-sast, quality-gate,
60
- pr-hygiene, dependency-risk, multi-agent-review, interactive-ask, or another recipe from pipr skill references.
59
+ 1. Recipe or goal: default-review, bug-hunter, rich-review, fix-suggestions,
60
+ security-sast, quality-gate, diff-diagnostics, pr-hygiene, dependency-risk,
61
+ ci-triage-command, multi-agent-review, plugin-tool-review, pr-briefing,
62
+ interactive-ask, changelog-draft, or a custom workflow.
61
63
  2. Model: use Pipr default DeepSeek, or specify provider/model/secret env var names.
62
64
  3. Triggers and publishing: automatic PR review plus @pipr review with capped inline comments, command-only, or merge-gate checks.
63
- 4. Existing files: edit existing Pipr files, create new files only, or approve replacement.
65
+ 4. Code host and existing files: choose github, gitlab, azure-devops, bitbucket,
66
+ or no adapter files; then choose whether to edit existing Pipr files, create new files only, or approve replacement.
64
67
  ```
65
68
 
66
69
  Completion criterion: recipe, model, secrets, triggers, publication behavior, and repo-specific review policy are explicit enough to write `.pipr/config.ts`.
@@ -71,8 +74,8 @@ Read [recipes.md](references/recipes.md) before selecting a starter recipe. Read
71
74
 
72
75
  For new setups:
73
76
 
74
- - Choose the smallest matching recipe and run `pipr init --recipe <id>`.
75
- - Add `--adapters none` only when the user does not want GitHub workflow files.
77
+ - Choose the smallest matching recipe and run `pipr init --recipe <id> --adapters <adapter-list>` when the user selected an adapter. Omit `--adapters` only for the default GitHub setup.
78
+ - Use `github` for `.github/workflows/pipr.yml`, `gitlab` for `.gitlab-ci.yml`, and `azure-devops` or `bitbucket` for trusted-webhook environment templates. Use `--adapters none` only when the user does not want generated adapter files.
76
79
  - Use `--minimal` only when the user chose a single-file config or Bun cannot be installed.
77
80
 
78
81
  For existing setups:
@@ -102,7 +105,7 @@ pipr check
102
105
 
103
106
  Use `pipr check --require-env` only when the required provider env vars should already be present. Use `pipr review --base <ref>` only when the user has a safe local base ref, Pi is available, and provider secrets are intentionally exported.
104
107
 
105
- For GitHub workflow or event behavior, inspect `.github/workflows/pipr.yml`; use `pipr dry-run --event <path>` only when a real event fixture is available.
108
+ For generated adapter files, inspect the selected integration artifact. Use `pipr dry-run --host <host> --event <path>` only when a real native event fixture is available. Use `pipr webhook serve --host <host>` only after the user has approved the trusted workspace, repository identifier, and webhook secret handling.
106
109
 
107
110
  Completion criterion: `pipr inspect` shows the expected models, agents, tasks, commands, tools, checks, and limits; `pipr check` succeeds or reports a blocker you can name exactly.
108
111
 
@@ -112,6 +115,6 @@ End with:
112
115
 
113
116
  - Files created or changed.
114
117
  - Recipe and major customizations.
115
- - Required GitHub Actions secrets and local env vars by name only.
118
+ - Required code host integration secrets and local env vars by name only.
116
119
  - Verification commands and results.
117
120
  - Remaining manual steps, such as adding repository secrets or enabling branch protection.
@@ -1,20 +1,22 @@
1
- # Pipr Config Patterns
1
+ # Pipr config patterns
2
2
 
3
3
  Use these patterns when customizing `.pipr/config.ts`.
4
4
 
5
- ## CLI Commands
5
+ ## CLI commands
6
6
 
7
7
  | Command | Use |
8
8
  | --- | --- |
9
- | `pipr init` | Create `.pipr/config.ts`, `.pipr/package.json`, `.pipr/bun.lock`, `.pipr/tsconfig.json`, `.pipr/.gitignore`, and the GitHub workflow. |
9
+ | `pipr init` | Create `.pipr/config.ts`, `.pipr/package.json`, `.pipr/bun.lock`, `.pipr/tsconfig.json`, `.pipr/.gitignore`, and the default GitHub workflow. |
10
+ | `pipr init --adapters <list>` | Generate selected adapter artifacts for `github`, `gitlab`, `azure-devops`, or `bitbucket`; use `none` to skip adapter files. |
10
11
  | `pipr init --minimal` | Create only `.pipr/config.ts`; editor types come from a repo-root `@usepipr/sdk` install. |
11
12
  | `pipr inspect` | Print models, agents, tasks, commands, tools, publication settings, checks, and limits. |
12
13
  | `pipr check` | Type-load config and validate the runtime plan. |
13
14
  | `pipr check --require-env` | Also require configured provider env vars. |
14
15
  | `pipr review --base <ref>` | Run change-request tasks locally without publishing comments. |
15
- | `pipr dry-run --event <path>` | Load a GitHub event and config without model calls or publication. |
16
+ | `pipr dry-run --host <host> --event <path>` | Load a native provider event and config without model calls or publication. |
17
+ | `pipr webhook serve --host <host> --workspace <path> --repository <id>` | Run trusted webhook ingress for GitLab, Azure DevOps, or Bitbucket. |
16
18
 
17
- ## Model And Review Basics
19
+ ## Model and review basics
18
20
 
19
21
  ```ts
20
22
  import { definePipr } from "@usepipr/sdk";
@@ -33,7 +35,7 @@ export default definePipr((pipr) => {
33
35
  id: "review",
34
36
  model,
35
37
  instructions: `
36
- Review the pull request diff for correctness, security,
38
+ Review the change request diff for correctness, security,
37
39
  maintainability, and test coverage.
38
40
  Return only actionable findings that target valid diff ranges.
39
41
  `,
@@ -76,7 +78,7 @@ Use a final rest capture for free-form command text:
76
78
  pipr.command({ pattern: "@pipr ask <question...>", permission: "read", task });
77
79
  ```
78
80
 
79
- ## Path Scopes
81
+ ## Path scopes
80
82
 
81
83
  Use `paths` to filter the Diff Manifest and publishable Inline Review Comments:
82
84
 
@@ -94,7 +96,7 @@ pipr.review({
94
96
 
95
97
  For custom tasks, pass the same path scope to `ctx.change.diffManifest(...)` and `ctx.pi.run(...)`.
96
98
 
97
- ## Custom Tasks
99
+ ## Custom tasks
98
100
 
99
101
  Use `pipr.agent`, `pipr.task`, and `pipr.on.changeRequest` when `pipr.review(...)` is too small.
100
102
 
@@ -134,7 +136,7 @@ Task rules:
134
136
  - Use `ctx.command.reply(...)` for command response workflows.
135
137
  - Use `local: false` only for tasks that should never run through `pipr review`.
136
138
 
137
- ## Checks And Publication
139
+ ## Checks and publication
138
140
 
139
141
  ```ts
140
142
  pipr.config({
@@ -164,4 +166,4 @@ Use only secret names in config:
164
166
  apiKey: pipr.secret({ name: "DEEPSEEK_API_KEY" })
165
167
  ```
166
168
 
167
- Add matching GitHub Actions secret mappings in `.github/workflows/pipr.yml`. Never commit raw provider keys, local `.env` values, or personal credentials.
169
+ Add secret mappings in the selected code host integration. GitHub uses `.github/workflows/pipr.yml`; GitLab uses masked CI/CD variables; Azure DevOps and Bitbucket webhook runners use their trusted secret stores. Never commit raw provider keys, local `.env` values, or personal credentials.
@@ -1,13 +1,15 @@
1
- # Pipr Recipe Selection
1
+ # Pipr recipe selection
2
2
 
3
3
  Choose the smallest recipe that matches the requested workflow, then customize `.pipr/config.ts`.
4
4
 
5
- ## Starter Recipes
5
+ ## Starter recipes
6
6
 
7
7
  | Recipe | Use When | Main Customization Points |
8
8
  | --- | --- | --- |
9
- | `default-review` | The user wants a bounded general pull request reviewer. | Review instructions, inline cap, command pattern, path scope. |
9
+ | `default-review` | The user wants a bounded general change request reviewer. | Review instructions, inline cap, command pattern, path scope. |
10
10
  | `bug-hunter` | The user wants correctness defects, edge cases, races, regressions, and missing tests. | Excluded docs paths, fallback model, inline cap. |
11
+ | `rich-review` | The user wants a structured review with grouped findings and explicit coverage. | Finding categories, summary format, inline cap. |
12
+ | `fix-suggestions` | The user wants concise, exact suggested replacements when a finding has a small fix. | Suggested-fix policy, inline cap, review scope. |
11
13
  | `security-sast` | The user wants concrete security findings with severity, category, and attack path. | Risk categories, required check policy, security path scopes. |
12
14
  | `quality-gate` | The user wants a merge gate for blocking correctness, reliability, security, or test risks. | Required check name, fail criteria, auto-resolve policy. |
13
15
  | `diff-diagnostics` | The workflow maps diagnostics into Pipr Inline Review Comments. | Diagnostic schema, path and range mapping, external diagnostic source. |
@@ -20,7 +22,7 @@ Choose the smallest recipe that matches the requested workflow, then customize `
20
22
  | `interactive-ask` | Reviewers need a free-form `@pipr ask <question...>` command. | Command permission, prompt boundaries, prior review usage. |
21
23
  | `changelog-draft` | Maintainers want release-note style command responses. | Changelog format, audience, release channels. |
22
24
 
23
- ## Selection Rules
25
+ ## Selection rules
24
26
 
25
27
  - Start from `default-review` unless another row directly matches the user's main workflow.
26
28
  - Prefer one custom task over multiple independent tasks when the final output should be one coherent Main Review Comment.
@@ -29,7 +31,7 @@ Choose the smallest recipe that matches the requested workflow, then customize `
29
31
  - Prefer `plugin-tool-review` only when the interview identifies durable context or external lookup tools that cannot fit in prompt instructions.
30
32
  - Combine recipes by editing config, not by running `pipr init` repeatedly. `pipr init` is a starter, not a merger.
31
33
 
32
- ## Init Commands
34
+ ## Init commands
33
35
 
34
36
  ```bash
35
37
  pipr init
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "@usepipr/cli",
3
- "version": "0.3.8",
4
- "description": "Command line interface for pipr pull request review automation",
3
+ "version": "0.4.1",
4
+ "description": "Command-line interface for Pipr code host review automation",
5
5
  "type": "module",
6
6
  "license": "MIT",
7
7
  "repository": {
@@ -33,8 +33,8 @@
33
33
  },
34
34
  "dependencies": {
35
35
  "@actions/core": "3.0.1",
36
- "@usepipr/runtime": "0.3.8",
37
- "@usepipr/sdk": "0.3.8",
36
+ "@usepipr/runtime": "0.4.1",
37
+ "@usepipr/sdk": "0.4.1",
38
38
  "commander": "15.0.0"
39
39
  }
40
40
  }