@usepipr/cli 0.3.2 → 0.3.5

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/main.mjs CHANGED
@@ -2,17 +2,17 @@
2
2
  import * as core from "@actions/core";
3
3
  import { PublicationError, runActionCommand, runDryRunCommand, runInitCommand, runInspectCommand, runLocalReviewCommand, runValidateCommand, supportedOfficialInitAdapters, supportedOfficialInitRecipes } from "@usepipr/runtime";
4
4
  import { inspect } from "node:util";
5
- import { Command } from "commander";
5
+ import { Command, CommanderError } from "commander";
6
6
  import { chmod, lstat, mkdir, mkdtemp, open, readdir, rename, rm } from "node:fs/promises";
7
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.2";
11
+ var version = "0.3.5";
12
12
  //#endregion
13
13
  //#region src/skill-catalog.ts
14
14
  const bundledSkillName = "pipr-setup";
15
- const bundledSkillFilePaths = new Set([
15
+ const bundledSkillFilePaths = /* @__PURE__ */ new Set([
16
16
  "SKILL.md",
17
17
  "references/config-patterns.md",
18
18
  "references/recipes.md"
@@ -205,7 +205,7 @@ async function listSkillDirectoryEntries(skillDir, prefix = "") {
205
205
  function samePaths(left, right) {
206
206
  return left.length === right.length && left.every((value, index) => value === right[index]);
207
207
  }
208
- const existingDirectoryErrorCodes = new Set(["EEXIST", "ENOTEMPTY"]);
208
+ const existingDirectoryErrorCodes = /* @__PURE__ */ new Set(["EEXIST", "ENOTEMPTY"]);
209
209
  function isExistingDirectoryError(error) {
210
210
  return existingDirectoryErrorCodes.has(error?.code ?? "");
211
211
  }
@@ -412,24 +412,31 @@ function compareSemver(left, right) {
412
412
  //#region src/runner.ts
413
413
  async function runMain(options = {}) {
414
414
  const argv = options.argv ?? process.argv;
415
- await writeAvailableUpdateNotice(options);
416
- const program = createProgram();
417
- if (argv.length <= 2) {
418
- program.outputHelp();
419
- return;
415
+ const env = options.env ?? process.env;
416
+ if (!isUpdateCommand(argv)) await writeAvailableUpdateNotice(options);
417
+ const program = createProgram({ exitOverride: env.GITHUB_ACTIONS === "true" });
418
+ try {
419
+ if (argv.length <= 2) {
420
+ program.outputHelp();
421
+ return;
422
+ }
423
+ await program.parseAsync(argv);
424
+ } catch (error) {
425
+ if (error instanceof CommanderError && error.exitCode === 0) return;
426
+ throw error;
420
427
  }
421
- await program.parseAsync(argv);
422
428
  }
423
- function createProgram() {
429
+ function createProgram(options = {}) {
424
430
  const program = new Command();
425
431
  program.name("pipr").version(version).showHelpAfterError();
432
+ if (options.exitOverride) program.exitOverride();
426
433
  program.addHelpText("after", agentHelpText);
427
434
  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);
428
435
  program.command("action").description("Run inside GitHub Docker Action").option("--config-dir <dir>", "Config directory", ".pipr").action(runAction);
429
436
  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);
430
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);
431
438
  program.command("inspect").description("Print models, agents, tasks, commands, and tools").option("--config-dir <dir>", "Config directory", ".pipr").action(runInspect);
432
- program.command("review").description("Run configured change-request review tasks locally without publishing").option("--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);
439
+ 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);
433
440
  program.command("version").description("Print the CLI version").action(runVersion);
434
441
  program.command("update").description("Update a GitHub Release binary install").action(runUpdate);
435
442
  program.command("skill").description("Print the bundled Pipr setup skill").action(runSkillGet).command("path").description("Materialize the bundled Pipr setup skill and print its directory path").action(runSkillPath);
@@ -582,19 +589,23 @@ async function runCheck(options) {
582
589
  requireProviderEnv: options.requireEnv === true
583
590
  });
584
591
  console.log(`valid: ${settings.source}`);
585
- for (const warning of settings.warnings) console.log(`warning: ${warning}`);
592
+ writeConfigWarnings(settings.warnings);
586
593
  }
587
594
  async function runInspect(options) {
588
- const result = await runInspectCommand({
595
+ const { warnings, ...plan } = await runInspectCommand({
589
596
  rootDir: process.cwd(),
590
597
  configDir: options.configDir,
591
598
  env: process.env
592
599
  });
593
- console.log(inspect(result, {
600
+ writeConfigWarnings(warnings);
601
+ console.log(inspect(plan, {
594
602
  depth: 8,
595
603
  colors: false
596
604
  }));
597
605
  }
606
+ function writeConfigWarnings(warnings) {
607
+ for (const warning of warnings) console.log(`warning: ${warning}`);
608
+ }
598
609
  async function runSkillGet() {
599
610
  console.log(formatBundledSkill(await resolveBundledSkill()));
600
611
  }
@@ -623,7 +634,7 @@ async function writeAvailableUpdateNotice(options) {
623
634
  fetch: options.updateNoticeFetch,
624
635
  timeoutMs: 750
625
636
  });
626
- if (notice) (options.writeUpdateNotice ?? console.error)(formatUpdateNotice(notice));
637
+ if (notice) (options.writeUpdateNotice ?? console.error)(`pipr ${notice.latestVersion} is available (current ${notice.currentVersion}). Run \`pipr update\` for release binaries, or reinstall @usepipr/cli with npm/Bun.`);
627
638
  } catch {
628
639
  return;
629
640
  }
@@ -634,11 +645,12 @@ function shouldSkipUpdateNotice(env) {
634
645
  const ci = env.CI?.trim().toLowerCase();
635
646
  return ci !== void 0 && ci !== "" && ci !== "0" && ci !== "false" || env.GITHUB_ACTIONS !== void 0;
636
647
  }
637
- function formatUpdateNotice(notice) {
638
- return `pipr ${notice.latestVersion} is available (current ${notice.currentVersion}). Run \`pipr update\` for release binaries, or reinstall @usepipr/cli with npm/Bun.`;
648
+ function isUpdateCommand(argv) {
649
+ const args = argv.slice(2);
650
+ if (args[0] === "--") return args[1] === "update";
651
+ return args[0] === "update" || args.length >= 2 && args[0] === "help" && args[1] === "update" || args.length >= 2 && args[0] === "--help" && args[1] === "update";
639
652
  }
640
653
  async function runLocalReview(options) {
641
- if (!options.base) throw new Error("pipr review requires --base <sha>");
642
654
  writeLocalReviewResult(await runLocalReviewCommand({
643
655
  rootDir: process.cwd(),
644
656
  configDir: options.configDir,
@@ -689,7 +701,7 @@ const localLogNumberFields = {
689
701
  stderrBytes: (value) => `stderr=${value}B`,
690
702
  stdoutBytes: (value) => `stdout=${value}B`
691
703
  };
692
- const localLogPlainLevels = new Set(["info", "notice"]);
704
+ const localLogPlainLevels = /* @__PURE__ */ new Set(["info", "notice"]);
693
705
  function formatLocalLogField(key, value) {
694
706
  if (value == null) return;
695
707
  return formatLocalLogFieldValue(key, value);
@@ -762,6 +774,7 @@ async function runDryRun(options) {
762
774
  env: process.env,
763
775
  eventPath: options.event
764
776
  });
777
+ writeConfigWarnings(result.warnings);
765
778
  console.log(inspect({
766
779
  configSource: result.configSource,
767
780
  event: result.event
@@ -771,16 +784,114 @@ async function runDryRun(options) {
771
784
  }));
772
785
  }
773
786
  //#endregion
787
+ //#region src/terminal-output.ts
788
+ function sanitizeTerminalMessage(message) {
789
+ let sanitized = "";
790
+ for (let index = 0; index < message.length; index += 1) {
791
+ const code = message.charCodeAt(index);
792
+ if (code === 27) {
793
+ index = skipTerminalControlSequence(message, index);
794
+ continue;
795
+ }
796
+ if (code === c1OscIntroducer) {
797
+ index = skipUntilTerminator(message, index + 1, bellTerminator);
798
+ continue;
799
+ }
800
+ if (c1StringControlIntroducers.has(code)) {
801
+ index = skipUntilTerminator(message, index + 1);
802
+ continue;
803
+ }
804
+ if (code === c1CsiIntroducer) {
805
+ index = skipCsiSequence(message, index + 1);
806
+ continue;
807
+ }
808
+ if (isUnsafeTerminalControl(code)) continue;
809
+ sanitized += message[index];
810
+ }
811
+ return sanitized;
812
+ }
813
+ const oscIntroducer = 93;
814
+ const csiIntroducer = 91;
815
+ const c1OscIntroducer = 157;
816
+ const c1CsiIntroducer = 155;
817
+ const bellTerminator = 7;
818
+ const stringTerminator = 156;
819
+ const stringControlIntroducers = /* @__PURE__ */ new Set([
820
+ 80,
821
+ 88,
822
+ 94,
823
+ 95
824
+ ]);
825
+ const c1StringControlIntroducers = /* @__PURE__ */ new Set([
826
+ 144,
827
+ 152,
828
+ 158,
829
+ 159
830
+ ]);
831
+ function skipTerminalControlSequence(message, index) {
832
+ const next = message.charCodeAt(index + 1);
833
+ if (Number.isNaN(next)) return index;
834
+ if (next === oscIntroducer) return skipUntilTerminator(message, index + 2, bellTerminator);
835
+ if (stringControlIntroducers.has(next)) return skipUntilTerminator(message, index + 2);
836
+ if (next === csiIntroducer) return skipCsiSequence(message, index + 2);
837
+ if (isEscapeIntermediate(next)) return skipEscapeSequenceWithIntermediates(message, index + 1);
838
+ if (isSingleEscapeSequenceFinal(next)) return index + 1;
839
+ return index;
840
+ }
841
+ function skipCsiSequence(message, index) {
842
+ for (let cursor = index; cursor < message.length; cursor += 1) {
843
+ const code = message.charCodeAt(cursor);
844
+ if (code >= 64 && code <= 126) return cursor;
845
+ }
846
+ return message.length - 1;
847
+ }
848
+ function skipUntilTerminator(message, index, terminator) {
849
+ for (let cursor = index; cursor < message.length; cursor += 1) {
850
+ const code = message.charCodeAt(cursor);
851
+ if (code === stringTerminator) return cursor;
852
+ if (terminator !== void 0 && code === terminator) return cursor;
853
+ if (code === 27 && cursor + 1 < message.length && message.charCodeAt(cursor + 1) === 92) return cursor + 1;
854
+ }
855
+ return message.length - 1;
856
+ }
857
+ function skipEscapeSequenceWithIntermediates(message, index) {
858
+ for (let cursor = index; cursor < message.length; cursor += 1) {
859
+ const code = message.charCodeAt(cursor);
860
+ if (isEscapeIntermediate(code)) continue;
861
+ if (isSingleEscapeSequenceFinal(code)) return cursor;
862
+ return Math.max(cursor - 1, index);
863
+ }
864
+ return message.length - 1;
865
+ }
866
+ function isEscapeIntermediate(code) {
867
+ return code >= 32 && code <= 47;
868
+ }
869
+ function isSingleEscapeSequenceFinal(code) {
870
+ return code >= 48 && code <= 126;
871
+ }
872
+ function isUnsafeTerminalControl(code) {
873
+ return code < 32 && code !== 9 && code !== 10 || code >= 127 && code <= 159;
874
+ }
875
+ //#endregion
774
876
  //#region src/main.ts
775
- runMain().catch((error) => {
877
+ const env = process.env;
878
+ runMain({ env }).catch((error) => handleFatalError(error, env));
879
+ function handleFatalError(error, env) {
880
+ const sanitizedMessage = sanitizeTerminalMessage(error instanceof Error ? error.message : String(error));
881
+ if (env.GITHUB_ACTIONS !== "true") {
882
+ console.error(`error: ${sanitizedMessage}`);
883
+ process.exit(1);
884
+ }
885
+ writeGitHubActionsFailure(error, sanitizedMessage);
886
+ process.exitCode = 1;
887
+ }
888
+ function writeGitHubActionsFailure(error, message) {
776
889
  if (error instanceof PublicationError && error.result) {
777
890
  core.setOutput("publication", JSON.stringify(error.result));
778
891
  core.error(`pipr publication metadata: ${JSON.stringify(error.result)}`);
779
892
  }
780
- const message = error instanceof Error ? error.message : String(error);
781
893
  core.setFailed(message);
782
- process.exitCode = 1;
783
- });
894
+ }
784
895
  //#endregion
785
896
  export {};
786
897
 
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/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 } 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 type UpdateNotice,\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 await writeAvailableUpdateNotice(options);\n const program = createProgram();\n if (argv.length <= 2) {\n program.outputHelp();\n return;\n }\n await program.parseAsync(argv);\n}\n\nfunction createProgram(): Command {\n const program = new Command();\n program.name(\"pipr\").version(cliPackage.version).showHelpAfterError();\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 .option(\"--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 for (const warning of settings.warnings) {\n console.log(`warning: ${warning}`);\n }\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 console.log(inspect(result, { depth: 8, colors: false }));\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)(formatUpdateNotice(notice));\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 formatUpdateNotice(notice: UpdateNotice): string {\n return (\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\nasync function runLocalReview(options: CliOptions): Promise<void> {\n if (!options.base) {\n throw new Error(\"pipr review requires --base <sha>\");\n }\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 console.log(\n inspect(\n {\n configSource: result.configSource,\n event: result.event,\n },\n { depth: 6, colors: false },\n ),\n );\n}\n","#!/usr/bin/env bun\nimport * as core from \"@actions/core\";\nimport { PublicationError } from \"@usepipr/runtime\";\nimport { runMain } from \"./runner.js\";\n\nrunMain().catch((error: unknown) => {\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 const message = error instanceof Error ? error.message : String(error);\n core.setFailed(message);\n process.exitCode = 1;\n});\n"],"mappings":";;;;;;;;;;;;;ACGA,MAAa,mBAAmB;AAChC,MAAM,wBAAwB,IAAI,IAAI;CACpC;CACA;CACA;AACF,CAAC;AAiBD,SAAgB,mBAAmB,SAA4C;CAC7E,MAAM,CAAC,SAAS,QAAQ;CACxB,IAAI,QAAQ,OAAO,WAAW,KAAK,OAAO,SAAA,cACxC,MAAM,IAAI,MACR,6CAA6C,iBAAiB,YAAY,QAAQ,OAC/E,KAAK,SAAS,KAAK,IAAI,CAAC,CACxB,KAAK,IAAI,GACd;CAEF,OAAO;AACT;AAEA,SAAgB,uBAAuB,MAAc,cAA8B;CACjF,IAAI,KAAK,WAAW,YAAY,GAC9B,MAAM,IAAI,MAAM,6CAA6C,cAAc;CAE7E,MAAM,eAAe,KAAK,QAAQ,IAAI;CACtC,MAAM,SAAS,KAAK,QAAQ,cAAc,YAAY;CACtD,IAAI,WAAW,gBAAgB,CAAC,OAAO,WAAW,GAAG,eAAe,KAAK,KAAK,GAC5E,MAAM,IAAI,MAAM,wDAAwD,cAAc;CAExF,OAAO;AACT;AAEA,eAAsB,wBAAwB,YAAkD;CAC9F,MAAM,UAAU,MAAM,QAAQ,YAAY,EAAE,eAAe,KAAK,CAAC;CAmBjE,MAAM,UAAU,EAAE,SAAQ,MAlBL,QAAQ,IAC3B,QACG,QAAQ,UAAU,MAAM,YAAY,CAAC,CAAC,CACtC,IAAI,OAAO,UAAU;EACpB,MAAM,WAAW,KAAK,KAAK,YAAY,MAAM,IAAI;EACjD,MAAM,QAAQ,MAAM,eAAe,QAAQ;EAC3C,0BAA0B,MAAM,MAAM,KAAK;EAC3C,MAAM,UAAU,MAAM,MAAM,SAAS,KAAK,SAAS,UAAU;EAC7D,IAAI,CAAC,SACH,MAAM,IAAI,MAAM,GAAG,SAAS,mBAAmB;EAEjD,OAAO;GACL,MAAM,MAAM;GACZ,aAAa,uBAAuB,QAAQ,QAAQ;GACpD;EACF;CACF,CAAC,CACL,EAAA,CACiC,MAAM,MAAM,UAAU,KAAK,KAAK,cAAc,MAAM,IAAI,CAAC,EAAE;CAC5F,mBAAmB,OAAO;CAC1B,OAAO;AACT;AAEA,eAAe,eAAe,UAAkB,SAAS,IAAiC;CACxF,MAAM,UAAU,MAAM,QAAQ,KAAK,KAAK,UAAU,MAAM,GAAG,EAAE,eAAe,KAAK,CAAC;CAiBlF,QAAO,MAhBa,QAAQ,IAC1B,QACG,QAAQ,UAAU,CAAC,MAAM,KAAK,WAAW,GAAG,CAAC,CAAC,CAC9C,MAAM,MAAM,UAAU,KAAK,KAAK,cAAc,MAAM,IAAI,CAAC,CAAC,CAC1D,IAAI,OAAO,UAAU;EACpB,MAAM,eAAe,SAAS,KAAK,KAAK,QAAQ,MAAM,IAAI,IAAI,MAAM;EACpE,IAAI,MAAM,YAAY,GACpB,OAAO,MAAM,eAAe,UAAU,YAAY;EAEpD,IAAI,CAAC,MAAM,OAAO,GAChB,OAAO,CAAC;EAEV,MAAM,WAAW,MAAM,IAAI,KAAK,KAAK,KAAK,UAAU,YAAY,CAAC,CAAC,CAAC,KAAK;EACxE,OAAO,CAAC;GAAE,MAAM,aAAa,MAAM,KAAK,GAAG,CAAC,CAAC,KAAK,GAAG;GAAG;EAAS,CAAC;CACpE,CAAC,CACL,EAAA,CACa,KAAK;AACpB;AAEA,SAAS,uBAAuB,UAA0B;CAExD,MAAM,eADc,SAAS,MAAM,+BAA+B,CAAC,EAAE,QAAQ,KAAA,EAEzE,MAAM,IAAI,CAAC,CACZ,MAAM,SAAS,KAAK,WAAW,cAAc,CAAC,CAAC,EAC9C,QAAQ,qBAAqB,EAAE,CAAC,CACjC,KAAK,CAAC,CACN,QAAQ,iBAAiB,EAAE;CAC9B,IAAI,CAAC,aACH,MAAM,IAAI,MAAM,iDAAiD;CAEnE,OAAO;AACT;AAEA,SAAS,0BAA0B,WAAmB,OAAiC;CACrF,IAAI,cAAA,cACF;CAEF,MAAM,QAAQ,IAAI,IAAI,MAAM,KAAK,SAAS,KAAK,IAAI,CAAC;CACpD,MAAM,aAAa,CAAC,GAAG,KAAK,CAAC,CAAC,QAAQ,aAAa,CAAC,sBAAsB,IAAI,QAAQ,CAAC;CACvF,MAAM,UAAU,CAAC,GAAG,qBAAqB,CAAC,CAAC,QAAQ,aAAa,CAAC,MAAM,IAAI,QAAQ,CAAC;CACpF,IAAI,WAAW,SAAS,KAAK,QAAQ,SAAS,GAC5C,MAAM,IAAI,MACR,GAAG,iBAAiB,+DACH,WAAW,KAAK,IAAI,KAAK,IAAI,aAAa,QAAQ,KAAK,IAAI,KAAK,KACnF;AAEJ;;;AC1GA,IAAI;AAMJ,eAAsB,sBAA6C;CACjE,iBAAiB,iBAAiB;CAClC,OAAO,MAAM;AACf;AAEA,SAAgB,mBAAmB,OAA6B;CAC9D,MAAM,QAAQ,CAAC,GAAG,MAAM,KAAK,CAAC,CAAC,KAAK,iBAAiB;CACrD,OAAO;EACL,KAAK,MAAM;EACX;EACA,MAAM;EACN;EACA,GAAG,MAAM,SAAS,SAAS;GACzB,2BAA2B,KAAK,KAAK;GACrC,KAAK,SAAS,QAAQ;GACtB,yBAAyB,KAAK,KAAK;GACnC;EACF,CAAC;CACH,CAAC,CAAC,KAAK,IAAI;AACb;AAEA,SAAS,kBAAkB,MAAwB,OAAiC;CAClF,IAAI,KAAK,SAAS,YAChB,OAAO;CAET,IAAI,MAAM,SAAS,YACjB,OAAO;CAET,OAAO,KAAK,KAAK,cAAc,MAAM,IAAI;AAC3C;AAEA,eAAsB,0BAA2C;CAC/D,MAAM,QAAQ,MAAM,oBAAoB;CACxC,MAAM,aAAa,KAAK,KAAK,eAAe,GAAGA,OAAkB;CACjE,MAAM,WAAW,KAAK,KAAK,YAAY,MAAM,IAAI;CACjD,MAAM,MAAM,YAAY,EAAE,WAAW,KAAK,CAAC;CAC3C,MAAM,aAAa,MAAM,QAAQ,KAAK,KAAK,YAAY,GAAG,iBAAiB,EAAE,CAAC;CAC9E,IAAI;EACF,KAAK,MAAM,QAAQ,MAAM,OACvB,MAAM,eAAe,YAAY,IAAI;EAEvC,IAAI,MAAM,sBAAsB,UAAU,MAAM,KAAK,GAAG;GACtD,MAAM,GAAG,YAAY;IAAE,WAAW;IAAM,OAAO;GAAK,CAAC;GACrD,OAAO;EACT;EACA,MAAM,GAAG,UAAU;GAAE,WAAW;GAAM,OAAO;EAAK,CAAC;EACnD,MAAM,qBAAqB,YAAY,UAAU,MAAM,KAAK;CAC9D,SAAS,OAAO;EACd,MAAM,GAAG,YAAY;GAAE,WAAW;GAAM,OAAO;EAAK,CAAC;EACrD,MAAM;CACR;CACA,OAAO;AACT;AAEA,eAAe,mBAA0C;CAEvD,OAAO,mBADU,qBACgB,KAAM,MAAM,2BAA2B,CAAE;AAC5E;AAEA,eAAe,6BAA2D;CACxE,MAAM,WAAW,MAAM,QAAQ,IAAI,oBAAoB,CAAC,CAAC,IAAI,uBAAuB,CAAC;CACrF,MAAM,SAAS,SAAS,MACrB,YACC,aAAa,OACjB;CACA,IAAI,QACF,OAAO,OAAO;CAEhB,MAAM,IAAI,MACR,wCAAwC,SACrC,KAAK,YAAY,GAAG,QAAQ,WAAW,IAAI,WAAW,UAAU,QAAQ,QAAQ,UAAU,CAAC,CAC3F,KAAK,IAAI,GACd;AACF;AAEA,eAAe,wBAAwB,YAAkD;CACvF,IAAI;EACF,OAAO;GAAE;GAAY,SAAS,MAAM,wBAAwB,UAAU;EAAE;CAC1E,SAAS,OAAO;EACd,OAAO;GAAE;GAAY,OAAO,iBAAiB,QAAQ,MAAM,UAAU,OAAO,KAAK;EAAE;CACrF;AACF;AAEA,SAAS,uBAAwD;CAC/D,IAAI,OAAO,yBAAyB,YAAY,qBAAqB,WAAW,GAC9E;CAEF,OAAO,KAAK,MAAM,oBAAoB;AACxC;AAEA,SAAS,sBAAgC;CACvC,MAAM,OAAO,OAAO,KAAK;CACzB,OAAO,CAAC,KAAK,KAAK,MAAM,QAAQ,GAAG,KAAK,QAAQ,MAAM,iBAAiB,CAAC;AAC1E;AAEA,eAAe,eAAe,UAAkB,MAAuC;CACrF,MAAM,SAAS,uBAAuB,UAAU,KAAK,IAAI;CACzD,MAAM,MAAM,KAAK,QAAQ,MAAM,GAAG,EAAE,WAAW,KAAK,CAAC;CACrD,MAAM,IAAI,MAAM,QAAQ,KAAK,QAAQ;AACvC;AAEA,eAAe,qBACb,YACA,UACA,OACe;CACf,IAAI;EACF,MAAM,OAAO,YAAY,QAAQ;CACnC,SAAS,OAAO;EACd,IAAI,yBAAyB,KAAK,KAAM,MAAM,sBAAsB,UAAU,KAAK,GAAI;GACrF,MAAM,GAAG,YAAY;IAAE,WAAW;IAAM,OAAO;GAAK,CAAC;GACrD;EACF;EACA,MAAM;CACR;AACF;AAEA,eAAe,sBACb,UACA,OACkB;CAClB,IAAI;EACF,OACG,MAAM,yBAAyB,UAAU,KAAK,KAC9C,MAAM,4BAA4B,UAAU,KAAK;CAEtD,QAAQ;EACN,OAAO;CACT;AACF;AAEA,eAAe,yBACb,UACA,OACkB;CAClB,OAAO,UACL,MAAM,0BAA0B,QAAQ,GACxC,MAAM,KAAK,SAAS,KAAK,IAAI,CAAC,CAAC,KAAK,CACtC;AACF;AAEA,eAAe,4BACb,UACA,OACkB;CAClB,KAAK,MAAM,QAAQ,OACjB,IAAI,CAAE,MAAM,iBAAiB,UAAU,IAAI,GACzC,OAAO;CAGX,OAAO;AACT;AAEA,eAAe,iBAAiB,UAAkB,MAA0C;CAC1F,MAAM,SAAS,uBAAuB,UAAU,KAAK,IAAI;CACzD,QAAQ,MAAM,MAAM,MAAM,EAAA,CAAG,OAAO,KAAM,MAAM,IAAI,KAAK,MAAM,CAAC,CAAC,KAAK,MAAO,KAAK;AACpF;AAEA,eAAe,0BAA0B,UAAkB,SAAS,IAAuB;CACzF,MAAM,UAAU,MAAM,QAAQ,KAAK,KAAK,UAAU,MAAM,GAAG,EAAE,eAAe,KAAK,CAAC;CAYlF,QAAO,MAXa,QAAQ,IAC1B,QACG,QAAQ,UAAU,CAAC,MAAM,KAAK,WAAW,GAAG,CAAC,CAAC,CAC9C,IAAI,OAAO,UAAU;EACpB,MAAM,eAAe,SAAS,KAAK,KAAK,QAAQ,MAAM,IAAI,IAAI,MAAM;EACpE,IAAI,MAAM,YAAY,GACpB,OAAO,MAAM,0BAA0B,UAAU,YAAY;EAE/D,OAAO,CAAC,aAAa,MAAM,KAAK,GAAG,CAAC,CAAC,KAAK,GAAG,CAAC;CAChD,CAAC,CACL,EAAA,CACa,KAAK,CAAC,CAAC,KAAK;AAC3B;AAEA,SAAS,UAAU,MAAgB,OAA0B;CAC3D,OAAO,KAAK,WAAW,MAAM,UAAU,KAAK,OAAO,OAAO,UAAU,UAAU,MAAM,MAAM;AAC5F;AAEA,MAAM,8BAA8B,IAAI,IAAI,CAAC,UAAU,WAAW,CAAC;AAEnE,SAAS,yBAAyB,OAAyB;CACzD,OAAO,4BAA4B,IAAK,OAAyC,QAAQ,EAAE;AAC7F;AAEA,SAAS,iBAAyB;CAChC,MAAM,WAAW,QAAQ,IAAI;CAC7B,IAAI,YAAY,SAAS,KAAK,CAAC,CAAC,SAAS,GACvC,OAAO,KAAK,QAAQ,QAAQ;CAE9B,MAAM,YAAY,QAAQ,IAAI,kBAAkB,KAAK,KAAK,GAAG,QAAQ,GAAG,QAAQ;CAChF,OAAO,KAAK,KAAK,WAAW,QAAQ,QAAQ;AAC9C;;;AC3MA,MAAa,iBAAkC;CAC7C;EAAE,UAAU;EAAS,MAAM;EAAO,QAAQ;EAA0B,SAAS;CAAiB;CAC9F;EAAE,UAAU;EAAS,MAAM;EAAS,QAAQ;EAAmB,SAAS;CAAmB;CAC3F;EAAE,UAAU;EAAU,MAAM;EAAO,QAAQ;EAAkB,SAAS;CAAkB;CACxF;EACE,UAAU;EACV,MAAM;EACN,QAAQ;EACR,SAAS;CACX;AACF;AAEA,SAAgB,yBAAyB,UAAsD;CAC7F,OAAO,eAAe,MACnB,WAAW,OAAO,aAAa,SAAS,YAAY,OAAO,SAAS,SAAS,IAChF;AACF;AAEA,SAAgB,wBAAwB,UAAmC;CACzE,MAAM,SAAS,yBAAyB,QAAQ;CAChD,IAAI,QACF,OAAO,OAAO;CAEhB,IAAI,CAAC,eAAe,MAAM,SAAS,KAAK,aAAa,SAAS,QAAQ,GACpE,MAAM,IAAI,MAAM,+BAA+B,SAAS,UAAU;CAEpE,MAAM,IAAI,MAAM,yCAAyC,SAAS,MAAM;AAC1E;;;ACAA,MAAM,eAAe;AACrB,MAAM,2BAA2B;CAC/B;CACA;CACA;CACA;AACF,CAAC,CAAC,KAAK,IAAI;AAEX,SAAgB,6BACd,UAAkD,CAAC,GAC3C;CACR,MAAM,WAAW,QAAQ,YAAY,QAAQ;CAC7C,MAAM,OAAO,QAAQ,QAAQ,QAAQ;CACrC,MAAM,WAAW,KAAK,SAAS,QAAQ,CAAC,CAAC,YAAY;CACrD,MAAM,aAAa,KAAK;CACxB,IACE,aAAa,SACb,SAAS,WAAW,MAAM,KAC1B,aAAa,UACb,SAAS,WAAW,OAAO,KAC3B,YAAY,SAAS,KAAK,KAC1B,YAAY,SAAS,MAAM,GAE3B,MAAM,IAAI,MAAM,wBAAwB;CAE1C,OAAO;AACT;AAEA,eAAsB,cAAc,SAA+C;CACjF,IAAI,CAAC,eAAe,QAAQ,cAAc,GACxC,MAAM,IAAI,MACR,wDAAwD,QAAQ,gBAClE;CAEF,MAAM,eAAe,QAAQ,SAAS,WAAW,MAAM,KAAK,UAAU;CAEtE,MAAM,QAAQ,wBADG,QAAQ,YAAY;EAAE,UAAU,QAAQ;EAAU,MAAM,QAAQ;CAAK,CACxC;CAC9C,MAAM,UAAU,MAAM,cAAc,YAAY;CAChD,MAAM,UAAU,QAAQ;CACxB,IAAI,cAAc,SAAS,QAAQ,cAAc,KAAK,GACpD,OAAO;EAAE,MAAM;EAAc,SAAS,QAAQ;CAAe;CAE/D,MAAM,CAAC,QAAQ,aAAa,MAAM,QAAQ,IAAI,CAC5C,cAAc,cAAc,mBAAmB,QAAQ,KAAK,KAAK,CAAC,GAClE,aAAa,cAAc,mBAAmB,QAAQ,KAAK,YAAY,CAAC,CAC1E,CAAC;CACD,eAAe,QAAQ,iBAAiB,WAAW,KAAK,GAAG,KAAK;CAEhE,MAAM,WAAW,KAAK,KACpB,KAAK,QAAQ,QAAQ,cAAc,GACnC,gBAAgB,QAAQ,IAAI,GAAG,KAAK,IAAI,GAC1C;CACA,IAAI,cAAc;CAClB,IAAI,WAAW;CACf,IAAI;EACF,MAAM,WAAW,MAAM,KAAK,UAAU,MAAM,GAAK;EACjD,cAAc;EACd,IAAI;GACF,MAAM,SAAS,UAAU,MAAM;EACjC,UAAU;GACR,MAAM,SAAS,MAAM;EACvB;EACA,MAAM,MAAM,UAAU,GAAK;EAC3B,MAAM,gBAAgB,MAAM,kBAAkB,QAAQ;EACtD,IAAI,CAAC,eAAe,aAAa,GAC/B,MAAM,IAAI,MAAM,oDAAoD,eAAe;EAErF,IAAI,kBAAkB,SACpB,MAAM,IAAI,MACR,mCAAmC,cAAc,oBAAoB,SACvE;EAEF,MAAM,OAAO,UAAU,QAAQ,cAAc;EAC7C,WAAW;EACX,OAAO;GAAE,MAAM;GAAW,iBAAiB,QAAQ;GAAgB;EAAQ;CAC7E,UAAU;EACR,IAAI,eAAe,CAAC,UAClB,MAAM,GAAG,UAAU,EAAE,OAAO,KAAK,CAAC;CAEtC;AACF;AAEA,eAAsB,0BACpB,SACmC;CACnC,IAAI,CAAC,eAAe,QAAQ,cAAc,GACxC;CAMF,MAAM,UAAU,MAAM,cAJD,iBACnB,QAAQ,SAAS,WAAW,MAAM,KAAK,UAAU,GACjD,QAAQ,SAEqC,CAAC;CAChD,IAAI,cAAc,QAAQ,SAAS,QAAQ,cAAc,KAAK,GAC5D;CAEF,OAAO;EAAE,gBAAgB,QAAQ;EAAgB,eAAe,QAAQ;CAAQ;AAClF;AAEA,SAAS,iBAAiB,cAA4B,WAA6C;CACjG,IAAI,cAAc,KAAA,GAChB,OAAO;CAET,OAAO,OAAO,KAAK,SAAS;EAC1B,MAAM,aAAa,IAAI,gBAAgB;EACvC,MAAM,UAAU,iBAAiB,WAAW,MAAM,GAAG,SAAS;EAC9D,IAAI;GACF,OAAO,MAAM,aAAa,KAAK;IAAE,GAAG;IAAM,QAAQ,WAAW;GAAO,CAAC;EACvE,UAAU;GACR,aAAa,OAAO;EACtB;CACF;AACF;AAEA,eAAe,cAAc,cAG1B;CACD,MAAM,WAAW,MAAM,aACrB,gCAAgC,aAAa,iBAC/C;CACA,IAAI,CAAC,SAAS,IACZ,MAAM,IAAI,MAAM,iDAAiD,SAAS,QAAQ;CAEpF,MAAM,UAAW,MAAM,SAAS,KAAK;CACrC,IAAI,OAAO,QAAQ,aAAa,UAC9B,MAAM,IAAI,MAAM,6CAA6C;CAE/D,MAAM,UAAU,QAAQ,SAAS,QAAQ,MAAM,EAAE;CACjD,IAAI,CAAC,eAAe,OAAO,GACzB,MAAM,IAAI,MAAM,sDAAsD,QAAQ,UAAU;CAE1F,OAAO;EAAE,KAAK,QAAQ;EAAU;CAAQ;AAC1C;AAEA,SAAS,mBAAmB,KAAa,OAAuB;CAC9D,OAAO,sBAAsB,aAAa,qBAAqB,IAAI,GAAG;AACxE;AAEA,eAAe,cACb,cACA,KACiB;CACjB,MAAM,WAAW,MAAM,aAAa,GAAG;CACvC,IAAI,CAAC,SAAS,IACZ,MAAM,IAAI,MAAM,sBAAsB,IAAI,SAAS,SAAS,QAAQ;CAEtE,OAAO,OAAO,KAAK,MAAM,SAAS,YAAY,CAAC;AACjD;AAEA,eAAe,aACb,cACA,KACiB;CACjB,MAAM,WAAW,MAAM,aAAa,GAAG;CACvC,IAAI,CAAC,SAAS,IACZ,MAAM,IAAI,MAAM,sBAAsB,IAAI,SAAS,SAAS,QAAQ;CAEtE,OAAO,MAAM,SAAS,KAAK;AAC7B;AAEA,SAAS,iBAAiB,WAAmB,OAAuB;CAClE,KAAK,MAAM,QAAQ,UAAU,MAAM,OAAO,GAAG;EAC3C,MAAM,CAAC,UAAU,QAAQ,KAAK,KAAK,CAAC,CAAC,MAAM,KAAK;EAChD,IAAI,SAAS,SAAS,UACpB,OAAO;CAEX;CACA,MAAM,IAAI,MAAM,gBAAgB,MAAM,WAAW;AACnD;AAEA,SAAS,eAAe,QAAgB,UAAkB,OAAqB;CAE7E,IADe,WAAW,QAAQ,CAAC,CAAC,OAAO,MAAM,CAAC,CAAC,OAAO,KACjD,MAAM,UACb,MAAM,IAAI,MAAM,yBAAyB,OAAO;AAEpD;AAEA,eAAe,kBAAkB,gBAAyC;CACxE,MAAM,gBAAgB,MAAM,QAAQ,KAAK,KAAK,GAAG,OAAO,GAAG,sBAAsB,CAAC;CAClF,IAAI;EACF,MAAM,UAAU,IAAI,MAAM,CAAC,gBAAgB,WAAW,GAAG;GACvD,KAAK;GACL,KAAK;IACH,MAAM;IACN,MAAM;IACN,QAAQ;GACV;GACA,QAAQ;GACR,QAAQ;EACV,CAAC;EACD,MAAM,CAAC,UAAU,QAAQ,UAAU,MAAM,QAAQ,IAAI;GACnD,QAAQ;GACR,QAAQ,SAAS,IAAI,SAAS,QAAQ,MAAM,CAAC,CAAC,KAAK,IAAI;GACvD,QAAQ,SAAS,IAAI,SAAS,QAAQ,MAAM,CAAC,CAAC,KAAK,IAAI;EACzD,CAAC;EACD,IAAI,aAAa,GACf,MAAM,IAAI,MACR,4CAA4C,OAAO,KAAK,KAAK,OAAO,KAAK,KAAK,UAChF;EAEF,OAAO,OAAO,KAAK;CACrB,UAAU;EACR,MAAM,GAAG,eAAe;GAAE,OAAO;GAAM,WAAW;EAAK,CAAC;CAC1D;AACF;AAEA,SAAS,eAAe,SAA0B;CAChD,OAAO,kBAAkB,KAAK,OAAO;AACvC;AAEA,SAAS,cAAc,MAAc,OAAuB;CAC1D,MAAM,YAAY,KAAK,MAAM,GAAG,CAAC,CAAC,IAAI,MAAM;CAC5C,MAAM,aAAa,MAAM,MAAM,GAAG,CAAC,CAAC,IAAI,MAAM;CAC9C,KAAK,IAAI,QAAQ,GAAG,QAAQ,GAAG,SAAS,GAAG;EACzC,MAAM,aAAa,UAAU,SAAS,WAAW;EACjD,IAAI,eAAe,GACjB,OAAO;CAEX;CACA,OAAO;AACT;;;AClNA,eAAsB,QAAQ,UAAuB,CAAC,GAAkB;CACtE,MAAM,OAAO,QAAQ,QAAQ,QAAQ;CACrC,MAAM,2BAA2B,OAAO;CACxC,MAAM,UAAU,cAAc;CAC9B,IAAI,KAAK,UAAU,GAAG;EACpB,QAAQ,WAAW;EACnB;CACF;CACA,MAAM,QAAQ,WAAW,IAAI;AAC/B;AAEA,SAAS,gBAAyB;CAChC,MAAM,UAAU,IAAI,QAAQ;CAC5B,QAAQ,KAAK,MAAM,CAAC,CAAC,QAAQC,OAAkB,CAAC,CAAC,mBAAmB;CACpE,QAAQ,YAAY,SAAS,aAAa;CAE1C,QACG,QAAQ,MAAM,CAAC,CACf,YAAY,mCAAmC,CAAC,CAChD,OAAO,sBAAsB,oBAAoB,OAAO,CAAC,CACzD,OACC,yBACA,2BAA2B,8BAA8B,KAAK,IAAI,EAAE,oCACtE,CAAC,CACA,OAAO,qBAAqB,mBAAmB,6BAA6B,KAAK,IAAI,EAAE,EAAE,CAAC,CAC1F,OAAO,aAAa,6DAA6D,CAAC,CAClF,OAAO,WAAW,+BAA+B,CAAC,CAClD,OAAO,OAAO;CAEjB,QACG,QAAQ,QAAQ,CAAC,CACjB,YAAY,iCAAiC,CAAC,CAC9C,OAAO,sBAAsB,oBAAoB,OAAO,CAAC,CACzD,OAAO,SAAS;CAEnB,QACG,QAAQ,OAAO,CAAC,CAChB,YAAY,gDAAgD,CAAC,CAC7D,OAAO,sBAAsB,oBAAoB,OAAO,CAAC,CACzD,OAAO,iBAAiB,sCAAsC,CAAC,CAC/D,OAAO,QAAQ;CAElB,QACG,QAAQ,SAAS,CAAC,CAClB,YAAY,0CAA0C,CAAC,CACvD,eAAe,kBAAkB,wBAAwB,CAAC,CAC1D,OAAO,sBAAsB,oBAAoB,OAAO,CAAC,CACzD,OAAO,SAAS;CAEnB,QACG,QAAQ,SAAS,CAAC,CAClB,YAAY,kDAAkD,CAAC,CAC/D,OAAO,sBAAsB,oBAAoB,OAAO,CAAC,CACzD,OAAO,UAAU;CAEpB,QACG,QAAQ,QAAQ,CAAC,CACjB,YAAY,uEAAuE,CAAC,CACpF,OAAO,gBAAgB,iBAAiB,CAAC,CACzC,OAAO,gBAAgB,0DAA0D,CAAC,CAClF,OAAO,sBAAsB,oBAAoB,OAAO,CAAC,CACzD,OAAO,0BAA0B,oBAAoB,CAAC,CACtD,OAAO,UAAU,8BAA8B,CAAC,CAChD,OAAO,cAAc;CAExB,QAAQ,QAAQ,SAAS,CAAC,CAAC,YAAY,uBAAuB,CAAC,CAAC,OAAO,UAAU;CAEjF,QAAQ,QAAQ,QAAQ,CAAC,CAAC,YAAY,wCAAwC,CAAC,CAAC,OAAO,SAAS;CAMhG,QAHG,QAAQ,OAAO,CAAC,CAChB,YAAY,oCAAoC,CAAC,CACjD,OAAO,WACN,CAAC,CACF,QAAQ,MAAM,CAAC,CACf,YAAY,uEAAuE,CAAC,CACpF,OAAO,YAAY;CAEtB,OAAO;AACT;AAEA,MAAM,gBAAgB;;;;;;;;;;;AAYtB,eAAe,UAAU,SAAoC;CAC3D,kBAAkB,MAAM,iBAAiB,cAAc,OAAO,CAAC,CAAC;AAClE;AAEA,SAAS,cAAc,SAAoC;CACzD,MAAM,YAAY,QAAQ,IAAI;CAC9B,IAAI,CAAC,WACH,MAAM,IAAI,MAAM,+CAA+C;CAEjE,OAAO;EACL,SAAS,QAAQ,IAAI,oBAAoB,QAAQ,IAAI;EACrD,WAAW,QAAQ,IAAI,uBAAuB,QAAQ;EACtD,KAAK,QAAQ;EACb;EACA,QAAQ,QAAQ,IAAI,iBAAiB;EACrC,SAAS;CACX;AACF;AAEA,MAAM,uBAAsC;CAC1C,IAAI,QAAQ;EACV,uBAAuB,OAAO,MAAM,CAAC,4BAA4B,MAAM,CAAC;CAC1E;CACA,MAAM,MAAM,MAAM,KAAK;EACrB,OAAO,MAAM,KAAK,MAAM,MAAM,GAAG;CACnC;AACF;AAEA,MAAM,yBAAyB;CAC7B,MAAM,KAAK;CACX,QAAQ,KAAK;CACb,SAAS,KAAK;CACd,OAAO,KAAK;CACZ,OAAO,KAAK;AACd;AAEA,SAAS,4BAA4B,QAAiC;CACpE,MAAM,OAAO,KAAK,UAAU;EAC1B,OAAO,OAAO;EACd,OAAO,OAAO;EACd,GAAG,OAAO;CACZ,CAAC;CACD,OAAO,OAAO,SAAS,KAAA,IAAY,OAAO,GAAG,KAAK,IAAI,OAAO;AAC/D;AAEA,SAAS,kBAAkB,QAAmC;CAC5D,IAAI,OAAO,SAAS,WAAW;EAC7B,KAAK,KAAK,uBAAuB,OAAO,QAAQ;EAChD;CACF;CACA,wBAAwB,MAAM;AAChC;AAUA,SAAS,wBAAwB,QAAkC;CACjE,KAAK,KACH,uBAAuB,OAAO,MAAM,OAAO,OAAO,OAAO,OAAO,MAAM,WAAW,MACnF;CACA,KAAK,KAAK,uBAAuB,OAAO,cAAc;CACtD,IAAI,OAAO,SAAS,WAAW;EAC7B,wBAAwB,MAAM;EAC9B;CACF;CACA,2BAA2B,MAAM;AACnC;AAEA,SAAS,2BAA2B,QAAqC;CACvE,IAAI,OAAO,SAAS,kBAAkB,OAAO,SAAS,oBAAoB;EACxE,yBAAyB,MAAM;EAC/B;CACF;CACA,gCAAgC,MAAM;AACxC;AAEA,SAAS,yBAAyB,QAAmC;CACnE,QAAQ,OAAO,MAAf;EACE,KAAK;GACH,6BAA6B,MAAM;GACnC;EACF,KAAK;GACH,iCAAiC,MAAM;GACvC;EACF;CAEF;AACF;AAEA,SAAS,gCAAgC,QAA0C;CACjF,QAAQ,OAAO,MAAf;EACE,KAAK;GACH,wBAAwB,MAAM;GAC9B;EACF,KAAK;GACH,0BAA0B,MAAM;GAChC;EACF;CAEF;AACF;AAEA,SAAS,wBAAwB,QAAiE;CAEhG,KAAK,KAAK,mFAAmF;AAC/F;AAEA,SAAS,6BACP,QACM;CACN,KAAK,KAAK,sBAAsB,OAAO,QAAQ;CAC/C,KAAK,UAAU,gBAAgB,OAAO,IAAI;AAC5C;AAEA,SAAS,iCACP,QACM;CACN,KAAK,KACH,iBAAiB,OAAO,QAAQ,gCAAgC,OAAO,YAAY,OAAO,EAC5F;CACA,KAAK,UAAU,gBAAgB,OAAO,SAAS,IAAI;CACnD,KAAK,UAAU,eAAe,KAAK,UAAU,OAAO,WAAW,CAAC;AAClE;AAEA,SAAS,0BACP,QACM;CACN,KAAK,KACH,qDAAqD,OAAO,OAAO,OAAO,sBAC5E;CACA,2BAA2B,OAAO,MAAM;CACxC,KAAK,UAAU,eAAe,KAAK,UAAU,EAAE,wBAAwB,OAAO,OAAO,CAAC,CAAC;AACzF;AAEA,SAAS,wBAAwB,QAAgE;CAC/F,KAAK,KACH,wBAAwB,OAAO,OAAO,UAAU,cAAc,OAAO,4BAChE,OAAO,OAAO,UAAU,gBAAgB,OAAO,oBACtD;CACA,KAAK,KACH,gCAAgC,OAAO,YAAY,YAAY,OAAO,QACjE,OAAO,YAAY,eAAe,OAAO,sBACzC,OAAO,YAAY,eAAe,QAAQ,SACjD;CACA,2BAA2B,OAAO,YAAY,SAAS,sBAAsB;CAC7E,IAAI,OAAO,OAAO,iBAChB,KAAK,KAAK,oDAAoD;CAEhE,KAAK,UAAU,gBAAgB,OAAO,OAAO,WAAW;CACxD,KAAK,UAAU,mBAAmB,KAAK,UAAU,OAAO,OAAO,mBAAmB,CAAC;CACnF,KAAK,UAAU,oBAAoB,KAAK,UAAU,OAAO,OAAO,UAAU,eAAe,CAAC;CAC1F,KAAK,UAAU,eAAe,KAAK,UAAU,OAAO,WAAW,CAAC;AAClE;AAEA,SAAS,2BAA2B,QAAwB;CAC1D,KAAK,MAAM,SAAS,QAClB,KAAK,QAAQ,kCAAkC,OAAO;AAE1D;AAEA,eAAe,QAAQ,SAAoC;CACzD,MAAM,SAAS,MAAM,eAAe;EAClC,SAAS,QAAQ,IAAI;EACrB,WAAW,QAAQ;EACnB,OAAO,QAAQ,UAAU;EACzB,UAAU,kBAAkB,QAAQ,QAAQ;EAC5C,QAAQ,QAAQ;EAChB,SAAS,QAAQ,YAAY;CAC/B,CAAC;CACD,QAAQ,IACN,WAAW,OAAO,QAAQ,OAAO,aAC9B,OAAO,YAAY,SAAS,IAAI,eAAe,OAAO,YAAY,WAAW,GAClF;CACA,IAAI,QAAQ,YAAY,MACtB,QAAQ,IACN,sFACF;AAEJ;AAEA,SAAS,kBAAkB,UAAoD;CAC7E,OAAO,UAAU,MAAM,GAAG,CAAC,CAAC,KAAK,YAAY,QAAQ,KAAK,CAAC;AAC7D;AAEA,eAAe,SAAS,SAAoC;CAC1D,MAAM,WAAW,MAAM,mBAAmB;EACxC,SAAS,QAAQ,IAAI;EACrB,WAAW,QAAQ;EACnB,KAAK,QAAQ;EACb,oBAAoB,QAAQ,eAAe;CAC7C,CAAC;CACD,QAAQ,IAAI,UAAU,SAAS,QAAQ;CACvC,KAAK,MAAM,WAAW,SAAS,UAC7B,QAAQ,IAAI,YAAY,SAAS;AAErC;AAEA,eAAe,WAAW,SAAoC;CAC5D,MAAM,SAAS,MAAM,kBAAkB;EACrC,SAAS,QAAQ,IAAI;EACrB,WAAW,QAAQ;EACnB,KAAK,QAAQ;CACf,CAAC;CACD,QAAQ,IAAI,QAAQ,QAAQ;EAAE,OAAO;EAAG,QAAQ;CAAM,CAAC,CAAC;AAC1D;AAEA,eAAe,cAA6B;CAC1C,QAAQ,IAAI,mBAAmB,MAAM,oBAAoB,CAAC,CAAC;AAC7D;AAEA,eAAe,eAA8B;CAC3C,QAAQ,IAAI,MAAM,wBAAwB,CAAC;AAC7C;AAEA,SAAS,aAAmB;CAC1B,QAAQ,IAAIA,OAAkB;AAChC;AAEA,eAAe,YAA2B;CACxC,MAAM,SAAS,MAAM,cAAc;EACjC,gBAAgBA;EAChB,gBAAgB,6BAA6B;CAC/C,CAAC;CACD,IAAI,OAAO,SAAS,cAAc;EAChC,QAAQ,IAAI,QAAQ,OAAO,QAAQ,uBAAuB;EAC1D;CACF;CACA,QAAQ,IAAI,qBAAqB,OAAO,gBAAgB,MAAM,OAAO,SAAS;AAChF;AAEA,eAAe,2BAA2B,SAAqC;CAE7E,IAAI,uBADQ,QAAQ,OAAO,QAAQ,GACL,GAC5B;CAEF,IAAI;EACF,MAAM,SAAS,MAAM,0BAA0B;GAC7C,gBAAgBA;GAChB,OAAO,QAAQ;GACf,WAAW;EACb,CAAC;EACD,IAAI,QACF,CAAC,QAAQ,qBAAqB,QAAQ,MAAA,CAAO,mBAAmB,MAAM,CAAC;CAE3E,QAAQ;EACN;CACF;AACF;AAEA,SAAS,uBAAuB,KAAiC;CAC/D,IAAI,IAAI,uBAAuB,KAC7B,OAAO;CAET,IAAI,IAAI,uBAAuB,KAC7B,OAAO;CAGT,MAAM,KAAK,IAAI,IAAI,KAAK,CAAC,CAAC,YAAY;CACtC,OACG,OAAO,KAAA,KAAa,OAAO,MAAM,OAAO,OAAO,OAAO,WACvD,IAAI,mBAAmB,KAAA;AAE3B;AAEA,SAAS,mBAAmB,QAA8B;CACxD,OACE,QAAQ,OAAO,cAAc,yBAAyB,OAAO,eAAe;AAGhF;AAEA,eAAe,eAAe,SAAoC;CAChE,IAAI,CAAC,QAAQ,MACX,MAAM,IAAI,MAAM,mCAAmC;CAYrD,uBAAuB,MAVF,sBAAsB;EACzC,SAAS,QAAQ,IAAI;EACrB,WAAW,QAAQ;EACnB,KAAK,QAAQ;EACb,SAAS,QAAQ;EACjB,SAAS,QAAQ;EACjB,cAAc,QAAQ;EACtB,SAAS;EACT,SAAS;CACX,CAAC,GAC8B,QAAQ,SAAS,IAAI;AACtD;AAIA,MAAM,gBAAgB;CACpB,KAAK,SAAiB;EACpB,QAAQ,MAAM,UAAU,SAAS;CACnC;CACA,KAAK,SAAiB;EACpB,QAAQ,MAAM,UAAU,SAAS;CACnC;CACA,MAAM,SAAiB;EACrB,QAAQ,MAAM,WAAW,SAAS;CACpC;AACF;AAEA,MAAM,sBAAqC;CACzC,IAAI,QAAQ;EACV,QAAQ,MAAM,qBAAqB,MAAM,CAAC;CAC5C;CACA,MAAM,MAAM,OAAO,KAAK;EACtB,OAAO,MAAM,IAAI;CACnB;AACF;AAEA,SAAS,qBAAqB,QAAiC;CAC7D,MAAM,SAAS,OAAO,QAAQ,OAAO,MAAM,CAAC,CACzC,KAAK,CAAC,KAAK,WAAW,oBAAoB,KAAK,KAAK,CAAC,CAAC,CACtD,QAAQ,UAA2B,UAAU,KAAA,CAAS;CAEzD,MAAM,YAAY,CAAC,GADJ,qBAAqB,MACT,GAAG,GAAG,MAAM,CAAC,CAAC,KAAK,GAAG;CACjD,OAAO,OAAO,SAAS,KAAA,IAAY,YAAY,GAAG,UAAU,IAAI,OAAO;AACzE;AAEA,SAAS,qBAAqB,QAAmC;CAC/D,OAAO;EAAC;EAAQ,oBAAoB,IAAI,OAAO,KAAK,IAAI,KAAK,OAAO;EAAO,OAAO;CAAK,CAAC,CAAC,OACvF,OACF;AACF;AAEA,MAAM,uBAAkE;CACtE,YAAY,UAAU,IAAI;CAC1B,YAAY,UAAU,IAAI;CAC1B,aAAa,UACX,YAAY,QAAQ,MAAO,GAAG,MAAM,MAAM,IAAI,QAAQ,IAAA,CAAM,QAAQ,CAAC,EAAE;CACzE,cAAc,UAAU,UAAU,MAAM;CACxC,cAAc,UAAU,UAAU,MAAM;CACxC,cAAc,UAAU,UAAU,MAAM;AAC1C;AAEA,MAAM,sBAAsB,IAAI,IAAI,CAAC,QAAQ,QAAQ,CAAC;AAEtD,SAAS,oBAAoB,KAAa,OAAoC;CAC5E,IAAI,SAAS,MACX;CAGF,OAAO,yBAAyB,KAAK,KAAK;AAC5C;AAEA,SAAS,yBAAyB,KAAa,OAAwB;CAGrE,QADE,OAAO,UAAU,WAAW,qBAAqB,IAAI,GAAG,KAAK,IAAI,KAAA,MACzC,GAAG,IAAI,GAAG,oBAAoB,KAAK;AAC/D;AAEA,MAAM,0BAAsE;CAC1E,SAAS;CACT,QAAQ;CACR,SAAS,UACP,MAAM,QAAQ,KAAK,IACf,MAAM,WAAW,IACf,MACA,MAAM,IAAI,mBAAmB,CAAC,CAAC,KAAK,GAAG,IACzC,KAAK,UAAU,KAAK;CAC1B,SAAS,UAAU;EACjB,MAAM,OAAO,OAAO,KAAK;EACzB,OAAO,KAAK,KAAK,IAAI,IAAI,KAAK,UAAU,IAAI,IAAI;CAClD;AACF;AAEA,SAAS,oBAAoB,OAAwB;CACnD,QAAQ,wBAAwB,OAAO,UAAU,KAAK,UAAA,CAAW,KAAK;AACxE;AAEA,SAAS,uBAAuB,QAA2B,MAAqB;CAC9E,IAAI,MAAM;EACR,QAAQ,IAAI,KAAK,UAAU,gBAAgB,MAAM,GAAG,MAAM,CAAC,CAAC;EAC5D;CACF;CACA,IAAI,OAAO,SAAS,WAAW;EAC7B,QAAQ,IAAI,YAAY,OAAO,cAAc,mBAAmB;EAChE;CACF;CACA,QAAQ,IAAI,kBAAkB,MAAM,CAAC;AACvC;AAEA,SAAS,kBAAkB,QAAgE;CACzF,MAAM,cAAc,uBAAuB,OAAO,WAAW;CAC7D,MAAM,iBAAiB,OAAO,oBAAoB,KAAK,OAAO,UAAU;EACtE,MAAM,QACJ,MAAM,cAAc,MAAM,UACtB,GAAG,MAAM,KAAK,GAAG,MAAM,cACvB,GAAG,MAAM,KAAK,GAAG,MAAM,UAAU,GAAG,MAAM;EAChD,OAAO;GACL,GAAG,QAAQ,EAAE,IAAI;GACjB,UAAU,MAAM,QAAQ,WAAW;GACnC,MAAM,QAAQ;EAChB,CAAC,CAAC,KAAK,IAAI;CACb,CAAC;CACD,OAAO,eAAe,WAAW,IAC7B,cACA;EAAC,YAAY,QAAQ;EAAG;EAAI;EAAsB;EAAI,eAAe,KAAK,MAAM;CAAC,CAAC,CAAC,KAAK,IAAI;AAClG;AAEA,SAAS,uBAAuB,SAAyB;CACvD,OAAO,QACJ,MAAM,IAAI,CAAC,CACX,QAAQ,SAAS,CAAC,KAAK,WAAW,yBAAyB,CAAC,CAAC,CAC7D,KAAK,IAAI,CAAC,CACV,UAAU;AACf;AAEA,SAAS,gBAAgB,QAA2B;CAClD,OAAO;EACL,MAAM,OAAO;EACb,GAAI,OAAO,SAAS,YAAY,EAAE,YAAY,OAAO,WAAW,IAAI,CAAC;EACrE,aAAa,OAAO;EACpB,gBAAgB,OAAO;EACvB,iBAAiB,OAAO,UAAU;EAClC,YAAY,OAAO;EACnB,UAAU,OAAO;EACjB,gBAAgB,OAAO,gBAAgB,SAAS,kBAAkB,CAAC,OAAO,SAAS,KAAK;EACxF,iBAAiB,OAAO;CAC1B;AACF;AAEA,eAAe,UAAU,SAAoC;CAC3D,IAAI,CAAC,QAAQ,OACX,MAAM,IAAI,MAAM,iCAAiC;CAEnD,MAAM,SAAS,MAAM,iBAAiB;EACpC,SAAS,QAAQ,IAAI;EACrB,WAAW,QAAQ;EACnB,KAAK,QAAQ;EACb,WAAW,QAAQ;CACrB,CAAC;CACD,QAAQ,IACN,QACE;EACE,cAAc,OAAO;EACrB,OAAO,OAAO;CAChB,GACA;EAAE,OAAO;EAAG,QAAQ;CAAM,CAC5B,CACF;AACF;;;ACvkBA,QAAQ,CAAC,CAAC,OAAO,UAAmB;CAClC,IAAI,iBAAiB,oBAAoB,MAAM,QAAQ;EACrD,KAAK,UAAU,eAAe,KAAK,UAAU,MAAM,MAAM,CAAC;EAC1D,KAAK,MAAM,8BAA8B,KAAK,UAAU,MAAM,MAAM,GAAG;CACzE;CACA,MAAM,UAAU,iBAAiB,QAAQ,MAAM,UAAU,OAAO,KAAK;CACrE,KAAK,UAAU,OAAO;CACtB,QAAQ,WAAW;AACrB,CAAC"}
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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"}
@@ -39,17 +39,30 @@ 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
- ## Short Interview
42
+ ## Interview Gate
43
43
 
44
- Ask only for missing choices. Combine questions so the interview stays short.
44
+ Do not run `pipr init` until recipe, model, secrets, triggers, publication behavior, and existing-file handling are explicit.
45
+ Defaults are allowed only when the user says to use Pipr defaults, accepts your proposed defaults, or provided equivalent intent.
46
+ Combine questions so the interview stays short.
45
47
 
46
- - Setup surface: config directory, GitHub workflow generation, and whether existing Pipr files may be edited. Never use `pipr init --force` without explicit approval.
47
- - 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.
48
- - Model policy: provider, model, secret env var names, fallback model, and whether local runs should require provider env vars.
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.
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.
49
51
  - Trigger policy: automatic change request actions, `@pipr` commands, command permissions, local review behavior, and command-only workflows.
50
52
  - Publication policy: inline comment cap, check runs, aggregate checks, required gates, auto-resolve behavior, and who may trigger verifier replies.
51
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.
52
54
 
55
+ Example compact interview:
56
+
57
+ ```text
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.
61
+ 2. Model: use Pipr default DeepSeek, or specify provider/model/secret env var names.
62
+ 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.
64
+ ```
65
+
53
66
  Completion criterion: recipe, model, secrets, triggers, publication behavior, and repo-specific review policy are explicit enough to write `.pipr/config.ts`.
54
67
 
55
68
  ## Build
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@usepipr/cli",
3
- "version": "0.3.2",
3
+ "version": "0.3.5",
4
4
  "description": "Command line interface for pipr pull request review automation",
5
5
  "type": "module",
6
6
  "license": "MIT",
@@ -33,8 +33,8 @@
33
33
  },
34
34
  "dependencies": {
35
35
  "@actions/core": "3.0.1",
36
- "@usepipr/runtime": "0.3.2",
37
- "@usepipr/sdk": "0.3.2",
36
+ "@usepipr/runtime": "0.3.5",
37
+ "@usepipr/sdk": "0.3.5",
38
38
  "commander": "15.0.0"
39
39
  }
40
40
  }