@usepipr/cli 0.3.3 → 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 +135 -24
- package/dist/main.mjs.map +1 -1
- package/dist/skills/pipr-setup/SKILL.md +18 -5
- package/package.json +3 -3
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.
|
|
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
|
-
|
|
416
|
-
|
|
417
|
-
|
|
418
|
-
|
|
419
|
-
|
|
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").
|
|
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
|
-
|
|
592
|
+
writeConfigWarnings(settings.warnings);
|
|
586
593
|
}
|
|
587
594
|
async function runInspect(options) {
|
|
588
|
-
const
|
|
595
|
+
const { warnings, ...plan } = await runInspectCommand({
|
|
589
596
|
rootDir: process.cwd(),
|
|
590
597
|
configDir: options.configDir,
|
|
591
598
|
env: process.env
|
|
592
599
|
});
|
|
593
|
-
|
|
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)(
|
|
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
|
|
638
|
-
|
|
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
|
-
|
|
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
|
-
|
|
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":"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"}
|
|
1
|
+
{"version":3,"file":"main.mjs","names":["cliPackage.version","cliPackage.version"],"sources":["../package.json","../src/skill-catalog.ts","../src/skills.ts","../src/release/targets.ts","../src/update.ts","../src/runner.ts","../src/terminal-output.ts","../src/main.ts"],"sourcesContent":["","import { readdir } from \"node:fs/promises\";\nimport path from \"node:path\";\n\nexport const bundledSkillName = \"pipr-setup\";\nconst bundledSkillFilePaths = new Set([\n \"SKILL.md\",\n \"references/config-patterns.md\",\n \"references/recipes.md\",\n]);\n\nexport type BundledSkillFile = {\n path: string;\n contents: string;\n};\n\nexport type BundledSkill = {\n name: string;\n description: string;\n files: BundledSkillFile[];\n};\n\nexport type BundledSkillCatalog = {\n skills: BundledSkill[];\n};\n\nexport function singleBundledSkill(catalog: BundledSkillCatalog): BundledSkill {\n const [skill] = catalog.skills;\n if (catalog.skills.length !== 1 || skill?.name !== bundledSkillName) {\n throw new Error(\n `Expected exactly one bundled skill named '${bundledSkillName}', found: ${catalog.skills\n .map((item) => item.name)\n .join(\", \")}`,\n );\n }\n return skill;\n}\n\nexport function containedSkillFilePath(root: string, relativePath: string): string {\n if (path.isAbsolute(relativePath)) {\n throw new Error(`Bundled skill file path must be relative: ${relativePath}`);\n }\n const resolvedRoot = path.resolve(root);\n const target = path.resolve(resolvedRoot, relativePath);\n if (target !== resolvedRoot && !target.startsWith(`${resolvedRoot}${path.sep}`)) {\n throw new Error(`Bundled skill file path escapes the skill directory: ${relativePath}`);\n }\n return target;\n}\n\nexport async function readBundledSkillCatalog(skillsRoot: string): Promise<BundledSkillCatalog> {\n const entries = await readdir(skillsRoot, { withFileTypes: true });\n const skills = await Promise.all(\n entries\n .filter((entry) => entry.isDirectory())\n .map(async (entry) => {\n const skillDir = path.join(skillsRoot, entry.name);\n const files = await readSkillFiles(skillDir);\n validateBundledSkillFiles(entry.name, files);\n const skillMd = files.find((file) => file.path === \"SKILL.md\");\n if (!skillMd) {\n throw new Error(`${skillDir}: missing SKILL.md`);\n }\n return {\n name: entry.name,\n description: frontmatterDescription(skillMd.contents),\n files,\n };\n }),\n );\n const catalog = { skills: skills.sort((left, right) => left.name.localeCompare(right.name)) };\n singleBundledSkill(catalog);\n return catalog;\n}\n\nasync function readSkillFiles(skillDir: string, prefix = \"\"): Promise<BundledSkillFile[]> {\n const entries = await readdir(path.join(skillDir, prefix), { withFileTypes: true });\n const files = await Promise.all(\n entries\n .filter((entry) => !entry.name.startsWith(\".\"))\n .sort((left, right) => left.name.localeCompare(right.name))\n .map(async (entry) => {\n const relativePath = prefix ? path.join(prefix, entry.name) : entry.name;\n if (entry.isDirectory()) {\n return await readSkillFiles(skillDir, relativePath);\n }\n if (!entry.isFile()) {\n return [];\n }\n const contents = await Bun.file(path.join(skillDir, relativePath)).text();\n return [{ path: relativePath.split(path.sep).join(\"/\"), contents }];\n }),\n );\n return files.flat();\n}\n\nfunction frontmatterDescription(contents: string): string {\n const frontmatter = contents.match(/^---\\n(?<body>[\\s\\S]*?)\\n---/u)?.groups?.body;\n const description = frontmatter\n ?.split(\"\\n\")\n .find((line) => line.startsWith(\"description:\"))\n ?.replace(/^description:\\s*/u, \"\")\n .trim()\n .replace(/^[\"']|[\"']$/gu, \"\");\n if (!description) {\n throw new Error(\"Bundled skill SKILL.md is missing a description\");\n }\n return description;\n}\n\nfunction validateBundledSkillFiles(skillName: string, files: BundledSkillFile[]): void {\n if (skillName !== bundledSkillName) {\n return;\n }\n const found = new Set(files.map((file) => file.path));\n const unexpected = [...found].filter((filePath) => !bundledSkillFilePaths.has(filePath));\n const missing = [...bundledSkillFilePaths].filter((filePath) => !found.has(filePath));\n if (unexpected.length > 0 || missing.length > 0) {\n throw new Error(\n `${bundledSkillName} bundled files must match the release allowlist; ` +\n `unexpected: ${unexpected.join(\", \") || \"-\"}; missing: ${missing.join(\", \") || \"-\"}`,\n );\n }\n}\n","import { lstat, mkdir, mkdtemp, readdir, rename, rm } from \"node:fs/promises\";\nimport os from \"node:os\";\nimport path from \"node:path\";\nimport cliPackage from \"../package.json\" with { type: \"json\" };\nimport {\n type BundledSkill,\n type BundledSkillCatalog,\n type BundledSkillFile,\n bundledSkillName,\n containedSkillFilePath,\n readBundledSkillCatalog,\n singleBundledSkill,\n} from \"./skill-catalog.js\";\n\ndeclare const PIPR_EMBEDDED_SKILLS: string | undefined;\n\nlet skillPromise: Promise<BundledSkill> | undefined;\n\ntype SkillCatalogAttempt =\n | { catalog: BundledSkillCatalog; skillsRoot: string }\n | { error: string; skillsRoot: string };\n\nexport async function resolveBundledSkill(): Promise<BundledSkill> {\n skillPromise ??= loadBundledSkill();\n return await skillPromise;\n}\n\nexport function formatBundledSkill(skill: BundledSkill): string {\n const files = [...skill.files].sort(compareSkillFiles);\n return [\n `# ${skill.name}`,\n \"\",\n skill.description,\n \"\",\n ...files.flatMap((file) => [\n `----- BEGIN SKILL FILE: ${file.path} -----`,\n file.contents.trimEnd(),\n `----- END SKILL FILE: ${file.path} -----`,\n \"\",\n ]),\n ].join(\"\\n\");\n}\n\nfunction compareSkillFiles(left: BundledSkillFile, right: BundledSkillFile): number {\n if (left.path === \"SKILL.md\") {\n return -1;\n }\n if (right.path === \"SKILL.md\") {\n return 1;\n }\n return left.path.localeCompare(right.path);\n}\n\nexport async function materializeBundledSkill(): Promise<string> {\n const skill = await resolveBundledSkill();\n const versionDir = path.join(skillCacheRoot(), cliPackage.version);\n const skillDir = path.join(versionDir, skill.name);\n await mkdir(versionDir, { recursive: true });\n const stagingDir = await mkdtemp(path.join(versionDir, `${bundledSkillName}-`));\n try {\n for (const file of skill.files) {\n await writeSkillFile(stagingDir, file);\n }\n if (await skillDirectoryMatches(skillDir, skill.files)) {\n await rm(stagingDir, { recursive: true, force: true });\n return skillDir;\n }\n await rm(skillDir, { recursive: true, force: true });\n await renameSkillDirectory(stagingDir, skillDir, skill.files);\n } catch (error) {\n await rm(stagingDir, { recursive: true, force: true });\n throw error;\n }\n return skillDir;\n}\n\nasync function loadBundledSkill(): Promise<BundledSkill> {\n const embedded = embeddedSkillCatalog();\n return singleBundledSkill(embedded ?? (await loadFilesystemSkillCatalog()));\n}\n\nasync function loadFilesystemSkillCatalog(): Promise<BundledSkillCatalog> {\n const attempts = await Promise.all(skillRootCandidates().map(readSkillCatalogAttempt));\n const loaded = attempts.find(\n (attempt): attempt is Extract<SkillCatalogAttempt, { catalog: BundledSkillCatalog }> =>\n \"catalog\" in attempt,\n );\n if (loaded) {\n return loaded.catalog;\n }\n throw new Error(\n `Unable to load bundled Pipr skills.\\n${attempts\n .map((attempt) => `${attempt.skillsRoot}: ${\"error\" in attempt ? attempt.error : \"loaded\"}`)\n .join(\"\\n\")}`,\n );\n}\n\nasync function readSkillCatalogAttempt(skillsRoot: string): Promise<SkillCatalogAttempt> {\n try {\n return { skillsRoot, catalog: await readBundledSkillCatalog(skillsRoot) };\n } catch (error) {\n return { skillsRoot, error: error instanceof Error ? error.message : String(error) };\n }\n}\n\nfunction embeddedSkillCatalog(): BundledSkillCatalog | undefined {\n if (typeof PIPR_EMBEDDED_SKILLS !== \"string\" || PIPR_EMBEDDED_SKILLS.length === 0) {\n return undefined;\n }\n return JSON.parse(PIPR_EMBEDDED_SKILLS) as BundledSkillCatalog;\n}\n\nfunction skillRootCandidates(): string[] {\n const here = import.meta.dirname;\n return [path.join(here, \"skills\"), path.resolve(here, \"../../../skills\")];\n}\n\nasync function writeSkillFile(skillDir: string, file: BundledSkillFile): Promise<void> {\n const target = containedSkillFilePath(skillDir, file.path);\n await mkdir(path.dirname(target), { recursive: true });\n await Bun.write(target, file.contents);\n}\n\nasync function renameSkillDirectory(\n stagingDir: string,\n skillDir: string,\n files: BundledSkillFile[],\n): Promise<void> {\n try {\n await rename(stagingDir, skillDir);\n } catch (error) {\n if (isExistingDirectoryError(error) && (await skillDirectoryMatches(skillDir, files))) {\n await rm(stagingDir, { recursive: true, force: true });\n return;\n }\n throw error;\n }\n}\n\nasync function skillDirectoryMatches(\n skillDir: string,\n files: BundledSkillFile[],\n): Promise<boolean> {\n try {\n return (\n (await skillDirectoryPathsMatch(skillDir, files)) &&\n (await skillDirectoryContentsMatch(skillDir, files))\n );\n } catch {\n return false;\n }\n}\n\nasync function skillDirectoryPathsMatch(\n skillDir: string,\n files: BundledSkillFile[],\n): Promise<boolean> {\n 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
|
-
##
|
|
42
|
+
## Interview Gate
|
|
43
43
|
|
|
44
|
-
|
|
44
|
+
Do not run `pipr init` until recipe, model, secrets, triggers, publication behavior, and existing-file handling are explicit.
|
|
45
|
+
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
|
-
-
|
|
47
|
-
-
|
|
48
|
-
-
|
|
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.
|
|
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.
|
|
37
|
-
"@usepipr/sdk": "0.3.
|
|
36
|
+
"@usepipr/runtime": "0.3.5",
|
|
37
|
+
"@usepipr/sdk": "0.3.5",
|
|
38
38
|
"commander": "15.0.0"
|
|
39
39
|
}
|
|
40
40
|
}
|