poe-code 3.0.213 → 3.0.215

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/index.js CHANGED
@@ -38279,7 +38279,7 @@ function selectNextExecution(plan, taskId) {
38279
38279
  function describeExecutionContext(selection) {
38280
38280
  return selection.stepName ? `task "${selection.task.id}" step "${selection.stepName}"` : `task "${selection.task.id}"`;
38281
38281
  }
38282
- async function resolveFileIncludes(template2, cwd, readFile45) {
38282
+ async function resolveFileIncludes(template2, cwd, readFile46) {
38283
38283
  const matches2 = [...template2.matchAll(FILE_INCLUDE_PATTERN)];
38284
38284
  if (matches2.length === 0) {
38285
38285
  return template2;
@@ -38287,7 +38287,7 @@ async function resolveFileIncludes(template2, cwd, readFile45) {
38287
38287
  let result = template2;
38288
38288
  for (const match of matches2) {
38289
38289
  const absolutePath = path51.resolve(cwd, match[1]);
38290
- const content = await readFile45(absolutePath, "utf8");
38290
+ const content = await readFile46(absolutePath, "utf8");
38291
38291
  result = result.replace(match[0], content);
38292
38292
  }
38293
38293
  return result;
@@ -38355,15 +38355,15 @@ async function resolveDocVarFromPath(options) {
38355
38355
  );
38356
38356
  }
38357
38357
  }
38358
- async function resolvePipelineVars(vars, cwd, readFile45) {
38358
+ async function resolvePipelineVars(vars, cwd, readFile46) {
38359
38359
  const resolved = {};
38360
38360
  for (const [key2, value] of Object.entries(vars)) {
38361
38361
  if (key2.endsWith("_doc") && looksLikeDocPath(value)) {
38362
- const docContent = await resolveDocVarFromPath({ key: key2, value, cwd, readFile: readFile45 });
38363
- resolved[key2] = await resolveFileIncludes(docContent, cwd, readFile45);
38362
+ const docContent = await resolveDocVarFromPath({ key: key2, value, cwd, readFile: readFile46 });
38363
+ resolved[key2] = await resolveFileIncludes(docContent, cwd, readFile46);
38364
38364
  continue;
38365
38365
  }
38366
- resolved[key2] = await resolveFileIncludes(value, cwd, readFile45);
38366
+ resolved[key2] = await resolveFileIncludes(value, cwd, readFile46);
38367
38367
  }
38368
38368
  return resolved;
38369
38369
  }
@@ -49593,6 +49593,316 @@ var init_require_comment_prefix = __esm({
49593
49593
  }
49594
49594
  });
49595
49595
 
49596
+ // packages/github-workflows/src/exec/trufflehog-pr-scan.ts
49597
+ import { appendFile as appendFile5, readFile as readFile24, writeFile as writeFile15 } from "node:fs/promises";
49598
+ async function runTruffleHogPrScanCommand(command, env, options = {}) {
49599
+ const runner = options.runner ?? runCommand;
49600
+ const cwd = options.cwd ?? process.cwd();
49601
+ if (command === "scan-for-secrets") {
49602
+ await scanForSecrets(env, cwd, runner);
49603
+ return null;
49604
+ }
49605
+ if (command === "report-advisory-result") {
49606
+ await reportAdvisoryResult(env, runner);
49607
+ return null;
49608
+ }
49609
+ await clearStaleAdvisoryResult(env, runner);
49610
+ return null;
49611
+ }
49612
+ function parseTruffleHogFindings(jsonl) {
49613
+ const findings = [];
49614
+ for (const line of jsonl.split("\n")) {
49615
+ if (line.trim() === "") {
49616
+ continue;
49617
+ }
49618
+ const parsed = parseJsonObject(line);
49619
+ const detector = stringValue(parsed.DetectorName);
49620
+ if (detector === void 0) {
49621
+ continue;
49622
+ }
49623
+ findings.push({
49624
+ detector,
49625
+ filePath: readFilePath(parsed),
49626
+ lineNumber: readLineNumber(parsed),
49627
+ status: readStatus(parsed)
49628
+ });
49629
+ }
49630
+ return findings;
49631
+ }
49632
+ function uniqueTruffleHogFindings(findings) {
49633
+ const unique = /* @__PURE__ */ new Map();
49634
+ for (const finding of findings) {
49635
+ const key2 = [finding.status, finding.detector, finding.filePath, String(finding.lineNumber)].join("\0");
49636
+ if (!unique.has(key2)) {
49637
+ unique.set(key2, finding);
49638
+ }
49639
+ }
49640
+ return [...unique.values()];
49641
+ }
49642
+ function renderTruffleHogFindingsTable(findings, options) {
49643
+ const uniqueFindings = uniqueTruffleHogFindings(findings);
49644
+ const rows = [
49645
+ "| Detector | Location | Verification |",
49646
+ "| --- | --- | --- |",
49647
+ ...uniqueFindings.slice(0, options.maxFindings).map((finding) => `| ${md(finding.detector)} | ${renderLocation(finding, options)} | ${md(finding.status)} |`)
49648
+ ];
49649
+ if (uniqueFindings.length > options.maxFindings) {
49650
+ rows.push("", `_Showing first ${options.maxFindings} of ${uniqueFindings.length} findings._`);
49651
+ }
49652
+ return rows.join("\n");
49653
+ }
49654
+ function renderTruffleHogComment(findings, options) {
49655
+ const uniqueFindings = uniqueTruffleHogFindings(findings);
49656
+ const heading = uniqueFindings.length === 1 ? "TruffleHog found a possible secret" : `TruffleHog found ${uniqueFindings.length} possible secrets`;
49657
+ return [
49658
+ COMMENT_MARKER,
49659
+ "",
49660
+ `### ${heading}`,
49661
+ "",
49662
+ renderTruffleHogFindingsTable(findings, options),
49663
+ "",
49664
+ FIX_MESSAGE
49665
+ ].join("\n");
49666
+ }
49667
+ async function scanForSecrets(env, cwd, runner) {
49668
+ const baseSha = requireEnv(env, "BASE_SHA");
49669
+ const headSha = requireEnv(env, "HEAD_SHA");
49670
+ const results = requireEnv(env, "RESULTS");
49671
+ const image = requireEnv(env, "TRUFFLEHOG_IMAGE");
49672
+ const resultsFile = env.get("TRUFFLEHOG_RESULTS_FILE") ?? DEFAULT_RESULTS_FILE;
49673
+ const stderrFile = env.get("TRUFFLEHOG_STDERR_FILE") ?? DEFAULT_STDERR_FILE;
49674
+ const result = await runner(
49675
+ "docker",
49676
+ [
49677
+ "run",
49678
+ "--rm",
49679
+ "-v",
49680
+ `${cwd}:/tmp`,
49681
+ "-w",
49682
+ "/tmp",
49683
+ image,
49684
+ "git",
49685
+ "file:///tmp/",
49686
+ "--since-commit",
49687
+ baseSha,
49688
+ "--branch",
49689
+ headSha,
49690
+ "--fail",
49691
+ "--no-update",
49692
+ "--json",
49693
+ `--results=${results}`
49694
+ ],
49695
+ { cwd }
49696
+ );
49697
+ await writeFile15(resultsFile, result.stdout, "utf8");
49698
+ await writeFile15(stderrFile, result.stderr, "utf8");
49699
+ process.stderr.write(result.stderr);
49700
+ const findingsCount = parseTruffleHogFindings(result.stdout).length;
49701
+ await setGitHubOutput(env, "exit_code", String(result.exitCode));
49702
+ await setGitHubOutput(env, "findings_count", String(findingsCount));
49703
+ if (result.exitCode !== 0 && findingsCount === 0) {
49704
+ throw new UserError(`TruffleHog exited with ${result.exitCode} without producing findings.`);
49705
+ }
49706
+ }
49707
+ async function reportAdvisoryResult(env, runner) {
49708
+ const githubToken = requireEnv(env, "GH_TOKEN");
49709
+ const headSha = requireEnv(env, "HEAD_SHA");
49710
+ const maxFindings = numberEnv(env, "MAX_FINDINGS");
49711
+ const prNumber = requireEnv(env, "PR_NUMBER");
49712
+ const repository = requireEnv(env, "REPOSITORY");
49713
+ const resultsFile = env.get("TRUFFLEHOG_RESULTS_FILE") ?? DEFAULT_RESULTS_FILE;
49714
+ const findings = uniqueTruffleHogFindings(parseTruffleHogFindings(await readFile24(resultsFile, "utf8")));
49715
+ const body = renderTruffleHogComment(findings, { repository, headSha, maxFindings });
49716
+ emitInlineAnnotations(findings, { maxFindings });
49717
+ const existingCommentId = await findExistingCommentId(runner, githubToken, repository, prNumber);
49718
+ if (existingCommentId === void 0) {
49719
+ await ghApi(runner, githubToken, ["repos", repository, "issues", prNumber, "comments"], [
49720
+ "--method",
49721
+ "POST",
49722
+ "--field",
49723
+ `body=${body}`
49724
+ ]);
49725
+ } else {
49726
+ await ghApi(runner, githubToken, ["repos", repository, "issues", "comments", existingCommentId], [
49727
+ "--method",
49728
+ "PATCH",
49729
+ "--field",
49730
+ `body=${body}`
49731
+ ]);
49732
+ }
49733
+ const heading = findings.length === 1 ? "TruffleHog found a possible secret" : `TruffleHog found ${findings.length} possible secrets`;
49734
+ const errorTitle = findings.length === 1 ? "TruffleHog finding" : "TruffleHog findings";
49735
+ const errorMessage = findings.length === 1 ? "Possible secret detected." : "Possible secrets detected.";
49736
+ console.log(`::error title=${errorTitle}::${errorMessage}`);
49737
+ await appendStepSummary(env, [
49738
+ `### ${heading}`,
49739
+ "",
49740
+ renderTruffleHogFindingsTable(findings, { repository, headSha, maxFindings }),
49741
+ "",
49742
+ FIX_MESSAGE
49743
+ ].join("\n"));
49744
+ }
49745
+ async function clearStaleAdvisoryResult(env, runner) {
49746
+ const githubToken = requireEnv(env, "GH_TOKEN");
49747
+ const prNumber = requireEnv(env, "PR_NUMBER");
49748
+ const repository = requireEnv(env, "REPOSITORY");
49749
+ const existingCommentId = await findExistingCommentId(runner, githubToken, repository, prNumber);
49750
+ if (existingCommentId !== void 0) {
49751
+ await ghApi(runner, githubToken, ["repos", repository, "issues", "comments", existingCommentId], [
49752
+ "--method",
49753
+ "DELETE"
49754
+ ]);
49755
+ }
49756
+ }
49757
+ function emitInlineAnnotations(findings, options) {
49758
+ for (const finding of findings.slice(0, options.maxFindings)) {
49759
+ if (finding.filePath === "" || finding.lineNumber <= 0) {
49760
+ continue;
49761
+ }
49762
+ console.log(
49763
+ `::error file=${commandValue(finding.filePath)},line=${finding.lineNumber},title=${commandValue(`TruffleHog: ${finding.detector}`)}::${messageValue(`Possible secret detected (${finding.status}). Remove it from the PR and rotate it if it was real.`)}`
49764
+ );
49765
+ }
49766
+ }
49767
+ async function findExistingCommentId(runner, githubToken, repository, prNumber) {
49768
+ const output = await ghApi(runner, githubToken, ["repos", repository, "issues", prNumber, "comments"]);
49769
+ const comments = parseJsonArray(output);
49770
+ for (let index = comments.length - 1; index >= 0; index -= 1) {
49771
+ const comment = comments[index];
49772
+ if (stringValue(comment.body)?.includes(COMMENT_MARKER) === true) {
49773
+ return stringValue(comment.id);
49774
+ }
49775
+ }
49776
+ return void 0;
49777
+ }
49778
+ async function ghApi(runner, githubToken, pathParts, args = []) {
49779
+ const result = await runner("gh", ["api", pathParts.join("/"), ...args], {
49780
+ env: { GH_TOKEN: githubToken }
49781
+ });
49782
+ if (result.exitCode !== 0) {
49783
+ throw new UserError(`GitHub API call failed with exit code ${result.exitCode}: ${result.stderr}`);
49784
+ }
49785
+ return result.stdout;
49786
+ }
49787
+ async function setGitHubOutput(env, key2, value) {
49788
+ const outputPath = env.get("GITHUB_OUTPUT");
49789
+ if (outputPath !== void 0 && outputPath !== "") {
49790
+ await appendFile5(outputPath, `${key2}=${value}
49791
+ `, "utf8");
49792
+ }
49793
+ }
49794
+ async function appendStepSummary(env, content) {
49795
+ const summaryPath = env.get("GITHUB_STEP_SUMMARY");
49796
+ if (summaryPath !== void 0 && summaryPath !== "") {
49797
+ await appendFile5(summaryPath, `${content}
49798
+ `, "utf8");
49799
+ }
49800
+ }
49801
+ function renderLocation(finding, options) {
49802
+ if (finding.lineNumber > 0 && finding.filePath !== "unknown") {
49803
+ return `[${finding.filePath}:${finding.lineNumber}](https://github.com/${options.repository}/blob/${options.headSha}/${finding.filePath}#L${finding.lineNumber})`;
49804
+ }
49805
+ if (finding.filePath !== "unknown") {
49806
+ return `\`${md(finding.filePath)}\``;
49807
+ }
49808
+ return "unknown";
49809
+ }
49810
+ function readStatus(record) {
49811
+ if (record.Verified === true) {
49812
+ return "verified";
49813
+ }
49814
+ const verificationError = stringValue(record.VerificationError);
49815
+ return verificationError === void 0 || verificationError === "" ? "unverified" : "unknown";
49816
+ }
49817
+ function readFilePath(record) {
49818
+ const metadata = objectValue(record.SourceMetadata);
49819
+ const gitMetadata = recordValue(recordValue(metadata.Data)?.Git) ?? recordValue(metadata.Git) ?? recordValue(metadata.git) ?? recordValue(recordValue(metadata.data)?.git) ?? {};
49820
+ const filesystemMetadata = recordValue(metadata.Filesystem) ?? recordValue(metadata.filesystem) ?? {};
49821
+ return stringValue(gitMetadata.file) ?? stringValue(gitMetadata.File) ?? stringValue(filesystemMetadata.file) ?? "unknown";
49822
+ }
49823
+ function readLineNumber(record) {
49824
+ const metadata = objectValue(record.SourceMetadata);
49825
+ const gitMetadata = recordValue(recordValue(metadata.Data)?.Git) ?? recordValue(metadata.Git) ?? recordValue(metadata.git) ?? recordValue(recordValue(metadata.data)?.git) ?? {};
49826
+ const filesystemMetadata = recordValue(metadata.Filesystem) ?? recordValue(metadata.filesystem) ?? {};
49827
+ return numberValue(gitMetadata.line) ?? numberValue(gitMetadata.Line) ?? numberValue(filesystemMetadata.line) ?? 0;
49828
+ }
49829
+ function requireEnv(env, name) {
49830
+ const value = env.get(name);
49831
+ if (value === void 0 || value === "") {
49832
+ throw new UserError(`${name} is required.`);
49833
+ }
49834
+ return value;
49835
+ }
49836
+ function numberEnv(env, name) {
49837
+ const value = Number(requireEnv(env, name));
49838
+ if (!Number.isFinite(value)) {
49839
+ throw new UserError(`${name} must be a number.`);
49840
+ }
49841
+ return value;
49842
+ }
49843
+ function parseJsonObject(value) {
49844
+ try {
49845
+ const parsed = JSON.parse(value);
49846
+ return objectValue(parsed);
49847
+ } catch {
49848
+ return {};
49849
+ }
49850
+ }
49851
+ function parseJsonArray(value) {
49852
+ try {
49853
+ const parsed = JSON.parse(value);
49854
+ return Array.isArray(parsed) ? parsed.map(objectValue) : [];
49855
+ } catch {
49856
+ return [];
49857
+ }
49858
+ }
49859
+ function objectValue(value) {
49860
+ return recordValue(value) ?? {};
49861
+ }
49862
+ function recordValue(value) {
49863
+ return typeof value === "object" && value !== null && !Array.isArray(value) ? value : void 0;
49864
+ }
49865
+ function stringValue(value) {
49866
+ if (typeof value === "string") {
49867
+ return value;
49868
+ }
49869
+ if (typeof value === "number") {
49870
+ return String(value);
49871
+ }
49872
+ return void 0;
49873
+ }
49874
+ function numberValue(value) {
49875
+ if (typeof value === "number") {
49876
+ return value;
49877
+ }
49878
+ if (typeof value !== "string") {
49879
+ return void 0;
49880
+ }
49881
+ const parsed = Number(value);
49882
+ return Number.isFinite(parsed) ? parsed : void 0;
49883
+ }
49884
+ function md(value) {
49885
+ return value.replaceAll("|", "\\|").replaceAll("`", "'").replaceAll("\r", " ").replaceAll("\n", " ");
49886
+ }
49887
+ function commandValue(value) {
49888
+ return value.replaceAll("%", "%25").replaceAll("\r", "%0D").replaceAll("\n", "%0A").replaceAll(":", "%3A").replaceAll(",", "%2C");
49889
+ }
49890
+ function messageValue(value) {
49891
+ return value.replaceAll("%", "%25").replaceAll("\r", "%0D").replaceAll("\n", "%0A");
49892
+ }
49893
+ var DEFAULT_RESULTS_FILE, DEFAULT_STDERR_FILE, COMMENT_MARKER, FIX_MESSAGE;
49894
+ var init_trufflehog_pr_scan = __esm({
49895
+ "packages/github-workflows/src/exec/trufflehog-pr-scan.ts"() {
49896
+ "use strict";
49897
+ init_src16();
49898
+ init_src12();
49899
+ DEFAULT_RESULTS_FILE = "/tmp/trufflehog-results.jsonl";
49900
+ DEFAULT_STDERR_FILE = "/tmp/trufflehog-stderr.log";
49901
+ COMMENT_MARKER = "<!-- trufflehog-pr-scan -->";
49902
+ FIX_MESSAGE = "Fix: remove the value, rotate it if it was real, and push a cleanup commit.";
49903
+ }
49904
+ });
49905
+
49596
49906
  // packages/github-workflows/src/preflight.ts
49597
49907
  function runPreflightChecks(context) {
49598
49908
  checkRequiredEnvVar(context.env, "POE_API_KEY");
@@ -49661,7 +49971,7 @@ var init_setup_agent = __esm({
49661
49971
 
49662
49972
  // packages/github-workflows/src/variables.ts
49663
49973
  import path75 from "node:path";
49664
- import { readFile as readFile24 } from "node:fs/promises";
49974
+ import { readFile as readFile25 } from "node:fs/promises";
49665
49975
  import { isMap as isMap4, parseDocument as parseDocument9, stringify as stringify4 } from "yaml";
49666
49976
  function isRecord25(value) {
49667
49977
  return typeof value === "object" && value !== null && !Array.isArray(value);
@@ -49752,7 +50062,7 @@ function extractUserOverrideBlocks(filePath, content) {
49752
50062
  }
49753
50063
  async function readOptionalVariablesContent(filePath) {
49754
50064
  try {
49755
- return await readFile24(filePath, "utf8");
50065
+ return await readFile25(filePath, "utf8");
49756
50066
  } catch (error2) {
49757
50067
  if (error2 instanceof Error && error2.code === "ENOENT") {
49758
50068
  return void 0;
@@ -49781,7 +50091,7 @@ function formatCommentedBlock(name, value) {
49781
50091
  }
49782
50092
  async function loadVariableSources(builtInDir, projectDir) {
49783
50093
  const builtInPath = path75.join(builtInDir, VARIABLES_FILE_NAME);
49784
- const builtInVariables = parseVariables(builtInPath, await readFile24(builtInPath, "utf8"));
50094
+ const builtInVariables = parseVariables(builtInPath, await readFile25(builtInPath, "utf8"));
49785
50095
  const projectVariablesPath = projectDir === void 0 ? void 0 : path75.join(projectDir, VARIABLES_FILE_NAME);
49786
50096
  const projectVariablesContent = projectVariablesPath === void 0 ? void 0 : await readOptionalVariablesContent(projectVariablesPath);
49787
50097
  if (projectVariablesPath === void 0 || projectVariablesContent === void 0) {
@@ -49795,7 +50105,7 @@ async function loadVariableSources(builtInDir, projectDir) {
49795
50105
  }
49796
50106
  async function loadVariables(builtInDir, projectDir) {
49797
50107
  const builtInPath = path75.join(builtInDir, VARIABLES_FILE_NAME);
49798
- const builtInContent = await readFile24(builtInPath, "utf8");
50108
+ const builtInContent = await readFile25(builtInPath, "utf8");
49799
50109
  const builtInVariables = parseVariables(builtInPath, builtInContent);
49800
50110
  if (projectDir === void 0) {
49801
50111
  return filterDisabledVariables(builtInVariables);
@@ -49819,7 +50129,7 @@ async function loadVariables(builtInDir, projectDir) {
49819
50129
  }
49820
50130
  ],
49821
50131
  {
49822
- fs: { readFile: readFile24 },
50132
+ fs: { readFile: readFile25 },
49823
50133
  autoExtend: true
49824
50134
  }
49825
50135
  );
@@ -49894,7 +50204,7 @@ var init_variables2 = __esm({
49894
50204
  });
49895
50205
 
49896
50206
  // packages/github-workflows/src/commands.ts
49897
- import { access as access3, mkdir as mkdir16, readFile as readFile25, unlink as unlink12, writeFile as writeFile15 } from "node:fs/promises";
50207
+ import { access as access3, mkdir as mkdir16, readFile as readFile26, unlink as unlink12, writeFile as writeFile16 } from "node:fs/promises";
49898
50208
  import path76 from "node:path";
49899
50209
  import { fileURLToPath as fileURLToPath8 } from "node:url";
49900
50210
  import Mustache3 from "mustache";
@@ -49918,7 +50228,7 @@ async function loadNamedAutomation(name, cwd) {
49918
50228
  }
49919
50229
  async function readBuiltInPromptFile(name) {
49920
50230
  try {
49921
- return await readFile25(path76.join(await resolveBuiltInPromptsDir(), `${name}.md`), "utf8");
50231
+ return await readFile26(path76.join(await resolveBuiltInPromptsDir(), `${name}.md`), "utf8");
49922
50232
  } catch (error2) {
49923
50233
  if (isMissingPathError2(error2)) {
49924
50234
  throw new UserError(`Automation "${name}" was not found.`);
@@ -49929,7 +50239,7 @@ async function readBuiltInPromptFile(name) {
49929
50239
  async function readBuiltInWorkflowTemplate(name, variant, automationName = name, promptPath) {
49930
50240
  const templatePath = path76.join(await resolveBuiltInWorkflowTemplatesDir(), `${name}.${variant}.yml`);
49931
50241
  try {
49932
- const content = await readFile25(templatePath, "utf8");
50242
+ const content = await readFile26(templatePath, "utf8");
49933
50243
  const header = promptPath !== void 0 ? `# Auto-generated by: poe-code github-workflows install ${name}
49934
50244
  # Edit ${path76.relative(process.cwd(), promptPath)} to customize the prompt.
49935
50245
  ` : `# Auto-generated by: poe-code github-workflows install ${name}
@@ -50082,6 +50392,29 @@ function buildPerItemTemplateContext(item, sharedContext) {
50082
50392
  function renderPrompt(template2, view) {
50083
50393
  return Mustache3.render(template2, view);
50084
50394
  }
50395
+ function requireSuccessfulRuns(name, items) {
50396
+ const succeeded = items.filter((item) => item.result.exitCode === 0).length;
50397
+ if (succeeded === items.length) {
50398
+ return;
50399
+ }
50400
+ const firstFailure = items.find((item) => item.result.exitCode !== 0);
50401
+ const details = [
50402
+ `Automation "${name}" failed: ${succeeded}/${items.length} spawned agent runs exited successfully.`
50403
+ ];
50404
+ if (firstFailure !== void 0) {
50405
+ details.push(`First failure exited with code ${firstFailure.result.exitCode}.`);
50406
+ appendCommandOutput(details, "stderr", firstFailure.result.stderr);
50407
+ appendCommandOutput(details, "stdout", firstFailure.result.stdout);
50408
+ }
50409
+ throw new UserError(details.join("\n"));
50410
+ }
50411
+ function appendCommandOutput(details, label, output) {
50412
+ const trimmed = output.trim();
50413
+ if (trimmed.length === 0) {
50414
+ return;
50415
+ }
50416
+ details.push(`${label}:`, trimmed);
50417
+ }
50085
50418
  function resolveSourceCommand(source, env) {
50086
50419
  const repo = env.get("GITHUB_REPOSITORY");
50087
50420
  if (repo === void 0) {
@@ -50140,10 +50473,10 @@ async function installAutomation(name, cwd, isEject) {
50140
50473
  ]);
50141
50474
  const workflowPath = path76.join(cwd, ".github", "workflows", `poe-code-${name}.yml`);
50142
50475
  await mkdir16(path76.dirname(workflowPath), { recursive: true });
50143
- await writeFile15(workflowPath, workflowTemplate, "utf8");
50476
+ await writeFile16(workflowPath, workflowTemplate, "utf8");
50144
50477
  if (promptPath !== void 0) {
50145
50478
  await mkdir16(path76.dirname(promptPath), { recursive: true });
50146
- await writeFile15(promptPath, addPromptHeader(rawPrompt, name), "utf8");
50479
+ await writeFile16(promptPath, addPromptHeader(rawPrompt, name), "utf8");
50147
50480
  }
50148
50481
  return {
50149
50482
  name,
@@ -50158,17 +50491,17 @@ async function ensureProjectSupportFiles(cwd, builtInVariables) {
50158
50491
  const variablesPath = path76.join(projectDir, "variables.yaml");
50159
50492
  const readmePath = path76.join(projectDir, "README.md");
50160
50493
  await mkdir16(projectDir, { recursive: true });
50161
- await writeFile15(
50494
+ await writeFile16(
50162
50495
  variablesPath,
50163
50496
  generateProjectVariablesFile(builtInVariables, await readOptionalFile4(variablesPath)),
50164
50497
  "utf8"
50165
50498
  );
50166
- await writeFile15(readmePath, renderProjectReadme(), "utf8");
50499
+ await writeFile16(readmePath, renderProjectReadme(), "utf8");
50167
50500
  return { readmePath, variablesPath };
50168
50501
  }
50169
50502
  async function readOptionalFile4(filePath) {
50170
50503
  try {
50171
- return await readFile25(filePath, "utf8");
50504
+ return await readFile26(filePath, "utf8");
50172
50505
  } catch (error2) {
50173
50506
  if (isMissingPathError2(error2)) {
50174
50507
  return void 0;
@@ -50215,7 +50548,7 @@ async function selectAutomationName(message2, automations) {
50215
50548
  }
50216
50549
  return selected;
50217
50550
  }
50218
- var UPSTREAM_REPO, builtInPromptsDirCandidates, builtInWorkflowTemplatesDirCandidates, installableAutomations, runCommandDef, listCommand, installCommand2, uninstallCommand, requireUserAllowCommand, requireCommentPrefixCommand, prepareCommand, promptPreviewCommand, variablesCommand, ghGroup;
50551
+ var UPSTREAM_REPO, builtInPromptsDirCandidates, builtInWorkflowTemplatesDirCandidates, installableAutomations, runCommandDef, listCommand, installCommand2, uninstallCommand, requireUserAllowCommand, requireCommentPrefixCommand, truffleHogPrScanCommand, prepareCommand, promptPreviewCommand, variablesCommand, ghGroup;
50219
50552
  var init_commands2 = __esm({
50220
50553
  "packages/github-workflows/src/commands.ts"() {
50221
50554
  "use strict";
@@ -50226,6 +50559,7 @@ var init_commands2 = __esm({
50226
50559
  init_discover2();
50227
50560
  init_check_user_allow();
50228
50561
  init_require_comment_prefix();
50562
+ init_trufflehog_pr_scan();
50229
50563
  init_preflight();
50230
50564
  init_setup_agent();
50231
50565
  init_variables2();
@@ -50277,21 +50611,23 @@ var init_commands2 = __esm({
50277
50611
  const sharedTemplateContext = { ...variables, ...buildTemplateContext5(env) };
50278
50612
  if (automation.source === void 0) {
50279
50613
  const prompt = renderPrompt(automation.prompt, sharedTemplateContext);
50614
+ const items2 = [
50615
+ {
50616
+ prompt,
50617
+ result: await spawn4(agent2, {
50618
+ prompt,
50619
+ cwd,
50620
+ ...params.model === void 0 ? {} : { model: params.model },
50621
+ ...params.mode === void 0 ? {} : { mode: params.mode },
50622
+ ...automation.mcp === void 0 ? {} : { mcpServers: resolveMcpConfig(automation.mcp, env) }
50623
+ })
50624
+ }
50625
+ ];
50626
+ requireSuccessfulRuns(automation.name, items2);
50280
50627
  return {
50281
50628
  automation: automation.name,
50282
50629
  agent: agent2,
50283
- items: [
50284
- {
50285
- prompt,
50286
- result: await spawn4(agent2, {
50287
- prompt,
50288
- cwd,
50289
- ...params.model === void 0 ? {} : { model: params.model },
50290
- ...params.mode === void 0 ? {} : { mode: params.mode },
50291
- ...automation.mcp === void 0 ? {} : { mcpServers: resolveMcpConfig(automation.mcp, env) }
50292
- })
50293
- }
50294
- ]
50630
+ items: items2
50295
50631
  };
50296
50632
  }
50297
50633
  const sourceResult = await runCommand("sh", ["-c", resolveSourceCommand(automation.source, env)], {
@@ -50318,6 +50654,7 @@ var init_commands2 = __esm({
50318
50654
  })
50319
50655
  });
50320
50656
  }
50657
+ requireSuccessfulRuns(automation.name, results);
50321
50658
  return {
50322
50659
  automation: automation.name,
50323
50660
  agent: agent2,
@@ -50485,6 +50822,16 @@ var init_commands2 = __esm({
50485
50822
  return null;
50486
50823
  }
50487
50824
  });
50825
+ truffleHogPrScanCommand = defineCommand({
50826
+ name: "trufflehog-pr-scan",
50827
+ description: "Run the TruffleHog PR scan workflow helper.",
50828
+ positional: ["command"],
50829
+ params: S.Object({
50830
+ command: S.Enum(["scan-for-secrets", "report-advisory-result", "clear-stale-advisory-result"])
50831
+ }),
50832
+ scope: ["cli"],
50833
+ handler: async ({ params, env }) => runTruffleHogPrScanCommand(params.command, env)
50834
+ });
50488
50835
  prepareCommand = defineCommand({
50489
50836
  name: "prepare",
50490
50837
  description: "Install and configure the agent required by a workflow automation.",
@@ -50571,6 +50918,7 @@ var init_commands2 = __esm({
50571
50918
  prepareCommand,
50572
50919
  requireUserAllowCommand,
50573
50920
  requireCommentPrefixCommand,
50921
+ truffleHogPrScanCommand,
50574
50922
  listCommand,
50575
50923
  installCommand2,
50576
50924
  uninstallCommand,
@@ -50591,6 +50939,7 @@ var init_src32 = __esm({
50591
50939
  init_commands2();
50592
50940
  init_check_user_allow();
50593
50941
  init_require_comment_prefix();
50942
+ init_trufflehog_pr_scan();
50594
50943
  }
50595
50944
  });
50596
50945
 
@@ -51831,7 +52180,7 @@ var init_renderer3 = __esm({
51831
52180
  });
51832
52181
 
51833
52182
  // packages/toolcraft/src/cli.ts
51834
- import { access as access4, readFile as readFile26, writeFile as writeFile16 } from "node:fs/promises";
52183
+ import { access as access4, readFile as readFile27, writeFile as writeFile17 } from "node:fs/promises";
51835
52184
  import path79 from "node:path";
51836
52185
  import {
51837
52186
  Command as CommanderCommand,
@@ -53083,9 +53432,9 @@ async function withOutputFormat2(output, fn) {
53083
53432
  }
53084
53433
  function createFs3() {
53085
53434
  return {
53086
- readFile: async (path108, encoding = "utf8") => readFile26(path108, { encoding }),
53435
+ readFile: async (path108, encoding = "utf8") => readFile27(path108, { encoding }),
53087
53436
  writeFile: async (path108, contents) => {
53088
- await writeFile16(path108, contents);
53437
+ await writeFile17(path108, contents);
53089
53438
  },
53090
53439
  exists: async (path108) => {
53091
53440
  try {
@@ -53192,7 +53541,7 @@ function validatePresetFieldValue(value, field, presetPath) {
53192
53541
  async function loadPresetValues(fields, presetPath) {
53193
53542
  let rawPreset;
53194
53543
  try {
53195
- rawPreset = await readFile26(presetPath, {
53544
+ rawPreset = await readFile27(presetPath, {
53196
53545
  encoding: "utf8"
53197
53546
  });
53198
53547
  } catch (error2) {
@@ -53449,7 +53798,7 @@ async function loadFixtureScenario(command, selector) {
53449
53798
  const fixturePath = resolveFixturePath(commandPath);
53450
53799
  let rawFixture;
53451
53800
  try {
53452
- rawFixture = await readFile26(fixturePath, {
53801
+ rawFixture = await readFile27(fixturePath, {
53453
53802
  encoding: "utf8"
53454
53803
  });
53455
53804
  } catch {
@@ -54530,12 +54879,12 @@ function createOverlayFileSystem(base) {
54530
54879
  }
54531
54880
  return base.readFile(filePath, "utf8");
54532
54881
  };
54533
- async function readFile45(filePath, encoding) {
54882
+ async function readFile46(filePath, encoding) {
54534
54883
  const content = await readOverlayText(filePath);
54535
54884
  return encoding ? content : Buffer.from(content);
54536
54885
  }
54537
54886
  const fs19 = {
54538
- readFile: readFile45,
54887
+ readFile: readFile46,
54539
54888
  async writeFile(filePath, content) {
54540
54889
  writes.set(filePath, stringifyFileContent(content));
54541
54890
  },
@@ -58885,7 +59234,7 @@ var init_dashboard_loop_shared = __esm({
58885
59234
 
58886
59235
  // src/cli/commands/pipeline.ts
58887
59236
  import path83 from "node:path";
58888
- import { readFile as readFile27, stat as stat18 } from "node:fs/promises";
59237
+ import { readFile as readFile28, stat as stat18 } from "node:fs/promises";
58889
59238
  import { fileURLToPath as fileURLToPath10 } from "node:url";
58890
59239
  async function resolvePipelineCommandConfig(container) {
58891
59240
  const [configDoc, pipelineYamlConfig] = await Promise.all([
@@ -59339,8 +59688,8 @@ async function loadPipelineTemplates() {
59339
59688
  continue;
59340
59689
  }
59341
59690
  const [skillPlan, steps] = await Promise.all([
59342
- readFile27(path83.join(templateRoot, "SKILL_plan.md"), "utf8"),
59343
- readFile27(path83.join(templateRoot, "steps.yaml.mustache"), "utf8")
59691
+ readFile28(path83.join(templateRoot, "SKILL_plan.md"), "utf8"),
59692
+ readFile28(path83.join(templateRoot, "steps.yaml.mustache"), "utf8")
59344
59693
  ]);
59345
59694
  pipelineTemplatesCache = { skillPlan, steps };
59346
59695
  return pipelineTemplatesCache;
@@ -59668,11 +60017,11 @@ function registerPipelineCommand(program, container) {
59668
60017
  if (typeof t.status === "string") return t.status === "done";
59669
60018
  return Object.values(t.status).every((s) => s === "done");
59670
60019
  }).length;
59671
- const readFile45 = container.fs.readFile.bind(container.fs);
60020
+ const readFile46 = container.fs.readFile.bind(container.fs);
59672
60021
  const resolvedVars = await resolvePipelineVars(
59673
60022
  plan.vars ?? {},
59674
60023
  container.env.cwd,
59675
- readFile45
60024
+ readFile46
59676
60025
  );
59677
60026
  const resolvedSetup = plan.setup === null ? void 0 : plan.setup ?? steps.setup;
59678
60027
  const resolvedTeardown = plan.teardown === null ? void 0 : plan.teardown ?? steps.teardown;
@@ -59694,7 +60043,7 @@ function registerPipelineCommand(program, container) {
59694
60043
  if (opts.preview) {
59695
60044
  if (resolvedSetup) {
59696
60045
  const raw = interpolatePipelineVars(resolvedSetup.prompt, resolvedVars, "setup");
59697
- const expanded = await resolveFileIncludes(raw, container.env.cwd, readFile45);
60046
+ const expanded = await resolveFileIncludes(raw, container.env.cwd, readFile46);
59698
60047
  resources.logger.resolved("setup", expanded);
59699
60048
  }
59700
60049
  for (const task of plan.tasks) {
@@ -59707,7 +60056,7 @@ function registerPipelineCommand(program, container) {
59707
60056
  vars: resolvedVars
59708
60057
  }),
59709
60058
  container.env.cwd,
59710
- readFile45
60059
+ readFile46
59711
60060
  );
59712
60061
  resources.logger.resolved(`task: ${task.id} \u2014 ${task.title}`, expanded);
59713
60062
  } else {
@@ -59720,7 +60069,7 @@ function registerPipelineCommand(program, container) {
59720
60069
  vars: resolvedVars
59721
60070
  }),
59722
60071
  container.env.cwd,
59723
- readFile45
60072
+ readFile46
59724
60073
  );
59725
60074
  resources.logger.resolved(`task: ${task.id} / ${stepName}`, expanded);
59726
60075
  }
@@ -59728,7 +60077,7 @@ function registerPipelineCommand(program, container) {
59728
60077
  }
59729
60078
  if (resolvedTeardown) {
59730
60079
  const raw = interpolatePipelineVars(resolvedTeardown.prompt, resolvedVars, "teardown");
59731
- const expanded = await resolveFileIncludes(raw, container.env.cwd, readFile45);
60080
+ const expanded = await resolveFileIncludes(raw, container.env.cwd, readFile46);
59732
60081
  resources.logger.resolved("teardown", expanded);
59733
60082
  }
59734
60083
  }
@@ -60483,7 +60832,7 @@ var init_ralph3 = __esm({
60483
60832
 
60484
60833
  // src/cli/commands/experiment.ts
60485
60834
  import path85 from "node:path";
60486
- import { readFile as readFile28, stat as stat19 } from "node:fs/promises";
60835
+ import { readFile as readFile29, stat as stat19 } from "node:fs/promises";
60487
60836
  import { fileURLToPath as fileURLToPath11 } from "node:url";
60488
60837
  function resolveExperimentPaths(scope, cwd, homeDir) {
60489
60838
  const rootPath = scope === "global" ? path85.join(homeDir, ".poe-code", "experiments") : path85.join(cwd, ".poe-code", "experiments");
@@ -60531,8 +60880,8 @@ async function loadExperimentTemplates() {
60531
60880
  continue;
60532
60881
  }
60533
60882
  const [skillPlan, runYaml] = await Promise.all([
60534
- readFile28(path85.join(templateRoot, "SKILL_experiment.md"), "utf8"),
60535
- readFile28(path85.join(templateRoot, "run.yaml.mustache"), "utf8")
60883
+ readFile29(path85.join(templateRoot, "SKILL_experiment.md"), "utf8"),
60884
+ readFile29(path85.join(templateRoot, "run.yaml.mustache"), "utf8")
60536
60885
  ]);
60537
60886
  experimentTemplatesCache = { skillPlan, runYaml };
60538
60887
  return experimentTemplatesCache;
@@ -76842,7 +77191,7 @@ var init_dump = __esm({
76842
77191
  });
76843
77192
 
76844
77193
  // packages/agent-script/src/snapshot/scheduler.ts
76845
- import { mkdir as mkdir21, rename as rename8, writeFile as writeFile23 } from "node:fs/promises";
77194
+ import { mkdir as mkdir21, rename as rename8, writeFile as writeFile24 } from "node:fs/promises";
76846
77195
  import { dirname as dirname6 } from "node:path";
76847
77196
  function createSnapshotScheduler(options) {
76848
77197
  if (options.snapshotPath === void 0) {
@@ -76875,7 +77224,7 @@ function createSnapshotScheduler(options) {
76875
77224
  async function writeSnapshotAtomically(snapshotPath, snapshot2) {
76876
77225
  const temporaryPath = `${snapshotPath}.tmp`;
76877
77226
  await mkdir21(dirname6(snapshotPath), { recursive: true });
76878
- await writeFile23(temporaryPath, JSON.stringify(snapshot2, null, 2));
77227
+ await writeFile24(temporaryPath, JSON.stringify(snapshot2, null, 2));
76879
77228
  await rename8(temporaryPath, snapshotPath);
76880
77229
  }
76881
77230
  var DEFAULT_SNAPSHOT_INTERVAL_MS;
@@ -79073,22 +79422,22 @@ function writeBlockSequence(state, level, object, compact) {
79073
79422
  state.dump = _result || "[]";
79074
79423
  }
79075
79424
  function writeFlowMapping(state, level, object) {
79076
- var _result = "", _tag = state.tag, objectKeyList = Object.keys(object), index, length, objectKey, objectValue, pairBuffer;
79425
+ var _result = "", _tag = state.tag, objectKeyList = Object.keys(object), index, length, objectKey, objectValue2, pairBuffer;
79077
79426
  for (index = 0, length = objectKeyList.length; index < length; index += 1) {
79078
79427
  pairBuffer = "";
79079
79428
  if (_result !== "") pairBuffer += ", ";
79080
79429
  if (state.condenseFlow) pairBuffer += '"';
79081
79430
  objectKey = objectKeyList[index];
79082
- objectValue = object[objectKey];
79431
+ objectValue2 = object[objectKey];
79083
79432
  if (state.replacer) {
79084
- objectValue = state.replacer.call(object, objectKey, objectValue);
79433
+ objectValue2 = state.replacer.call(object, objectKey, objectValue2);
79085
79434
  }
79086
79435
  if (!writeNode(state, level, objectKey, false, false)) {
79087
79436
  continue;
79088
79437
  }
79089
79438
  if (state.dump.length > 1024) pairBuffer += "? ";
79090
79439
  pairBuffer += state.dump + (state.condenseFlow ? '"' : "") + ":" + (state.condenseFlow ? "" : " ");
79091
- if (!writeNode(state, level, objectValue, false, false)) {
79440
+ if (!writeNode(state, level, objectValue2, false, false)) {
79092
79441
  continue;
79093
79442
  }
79094
79443
  pairBuffer += state.dump;
@@ -79098,7 +79447,7 @@ function writeFlowMapping(state, level, object) {
79098
79447
  state.dump = "{" + _result + "}";
79099
79448
  }
79100
79449
  function writeBlockMapping(state, level, object, compact) {
79101
- var _result = "", _tag = state.tag, objectKeyList = Object.keys(object), index, length, objectKey, objectValue, explicitPair, pairBuffer;
79450
+ var _result = "", _tag = state.tag, objectKeyList = Object.keys(object), index, length, objectKey, objectValue2, explicitPair, pairBuffer;
79102
79451
  if (state.sortKeys === true) {
79103
79452
  objectKeyList.sort();
79104
79453
  } else if (typeof state.sortKeys === "function") {
@@ -79112,9 +79461,9 @@ function writeBlockMapping(state, level, object, compact) {
79112
79461
  pairBuffer += generateNextLine(state, level);
79113
79462
  }
79114
79463
  objectKey = objectKeyList[index];
79115
- objectValue = object[objectKey];
79464
+ objectValue2 = object[objectKey];
79116
79465
  if (state.replacer) {
79117
- objectValue = state.replacer.call(object, objectKey, objectValue);
79466
+ objectValue2 = state.replacer.call(object, objectKey, objectValue2);
79118
79467
  }
79119
79468
  if (!writeNode(state, level + 1, objectKey, true, true, true)) {
79120
79469
  continue;
@@ -79131,7 +79480,7 @@ function writeBlockMapping(state, level, object, compact) {
79131
79480
  if (explicitPair) {
79132
79481
  pairBuffer += generateNextLine(state, level);
79133
79482
  }
79134
- if (!writeNode(state, level + 1, objectValue, true, explicitPair)) {
79483
+ if (!writeNode(state, level + 1, objectValue2, true, explicitPair)) {
79135
79484
  continue;
79136
79485
  }
79137
79486
  if (state.dump && CHAR_LINE_FEED === state.dump.charCodeAt(0)) {
@@ -79835,7 +80184,7 @@ var init_frontmatter6 = __esm({
79835
80184
  });
79836
80185
 
79837
80186
  // packages/agent-script/src/runner/run-harness.ts
79838
- import { readFile as readFile41 } from "node:fs/promises";
80187
+ import { readFile as readFile42 } from "node:fs/promises";
79839
80188
  import { extname as extname2 } from "node:path";
79840
80189
  var init_run_harness = __esm({
79841
80190
  "packages/agent-script/src/runner/run-harness.ts"() {
@@ -80697,7 +81046,7 @@ var init_validate3 = __esm({
80697
81046
  });
80698
81047
 
80699
81048
  // packages/agent-harness/src/loader/run.ts
80700
- import { mkdir as mkdir22, readFile as readFile43, unlink as unlink15, writeFile as writeFile24 } from "node:fs/promises";
81049
+ import { mkdir as mkdir22, readFile as readFile44, unlink as unlink15, writeFile as writeFile25 } from "node:fs/promises";
80701
81050
  import os12 from "node:os";
80702
81051
  import { dirname as dirname8, join as join8 } from "node:path";
80703
81052
  async function runHarnessPair(mdPath, options) {
@@ -80884,7 +81233,7 @@ async function createHostCallReplay(snapshotPath) {
80884
81233
  }
80885
81234
  async function readHostCallRecords(storePath) {
80886
81235
  try {
80887
- const parsed = JSON.parse(await readFile43(storePath, "utf8"));
81236
+ const parsed = JSON.parse(await readFile44(storePath, "utf8"));
80888
81237
  return Array.isArray(parsed) ? parsed : [];
80889
81238
  } catch (error2) {
80890
81239
  if (hasErrorCode5(error2, "ENOENT")) {
@@ -80901,7 +81250,7 @@ async function writeHostCallRecords(storePath, records) {
80901
81250
  return;
80902
81251
  }
80903
81252
  await mkdir22(dirname8(storePath), { recursive: true });
80904
- await writeFile24(storePath, serialized);
81253
+ await writeFile25(storePath, serialized);
80905
81254
  }
80906
81255
  async function cleanupCompletedSnapshot(snapshotPath) {
80907
81256
  await Promise.all([
@@ -80953,7 +81302,7 @@ function resolveSnapshotPath(mdPath, snapshotPath) {
80953
81302
  }
80954
81303
  async function readSnapshot(snapshotPath) {
80955
81304
  try {
80956
- return JSON.parse(await readFile43(snapshotPath, "utf8"));
81305
+ return JSON.parse(await readFile44(snapshotPath, "utf8"));
80957
81306
  } catch (error2) {
80958
81307
  if (hasErrorCode5(error2, "ENOENT")) {
80959
81308
  return void 0;
@@ -80962,7 +81311,7 @@ async function readSnapshot(snapshotPath) {
80962
81311
  }
80963
81312
  }
80964
81313
  async function readTextFile(path108) {
80965
- const source = await readFile43(path108, "utf8");
81314
+ const source = await readFile44(path108, "utf8");
80966
81315
  return source.startsWith("\uFEFF") ? source.slice(1) : source;
80967
81316
  }
80968
81317
  function formatLintErrorMessage(diagnostics) {
@@ -81040,7 +81389,7 @@ var init_src36 = __esm({
81040
81389
 
81041
81390
  // src/cli/commands/harness.ts
81042
81391
  import path107 from "node:path";
81043
- import { readFile as readFile44 } from "node:fs/promises";
81392
+ import { readFile as readFile45 } from "node:fs/promises";
81044
81393
  function registerHarnessCommand(program, container) {
81045
81394
  const harness = program.command("harness").description("Run and manage agent harness pairs.");
81046
81395
  harness.command("run").description("Run a harness pair.").argument("[md-path]", "Path to the harness .md file").option("-y, --yes", "Accept defaults without prompting.").action(async (mdPath, options) => {
@@ -81087,8 +81436,8 @@ async function executeHarnessNew(program, container, kind, basename4, options) {
81087
81436
  return;
81088
81437
  }
81089
81438
  const [mdSource, ajsSource] = await Promise.all([
81090
- readFile44(template2.mdPath, "utf8"),
81091
- readFile44(template2.ajsPath, "utf8")
81439
+ readFile45(template2.mdPath, "utf8"),
81440
+ readFile45(template2.ajsPath, "utf8")
81092
81441
  ]);
81093
81442
  await container.fs.mkdir(resolvedDir, { recursive: true });
81094
81443
  await Promise.all([
@@ -81360,7 +81709,7 @@ var init_package2 = __esm({
81360
81709
  "package.json"() {
81361
81710
  package_default2 = {
81362
81711
  name: "poe-code",
81363
- version: "3.0.213",
81712
+ version: "3.0.215",
81364
81713
  description: "CLI tool to configure Poe API for developer workflows.",
81365
81714
  type: "module",
81366
81715
  main: "./dist/index.js",