@f-o-h/cli 0.1.71 → 0.1.72

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (2) hide show
  1. package/dist/foh.js +66 -7
  2. package/package.json +3 -2
package/dist/foh.js CHANGED
@@ -32790,7 +32790,7 @@ var StdioServerTransport = class {
32790
32790
  };
32791
32791
 
32792
32792
  // src/lib/cli-version.ts
32793
- var CLI_VERSION = "0.1.71";
32793
+ var CLI_VERSION = "0.1.72";
32794
32794
 
32795
32795
  // src/commands/mcp-serve.ts
32796
32796
  var DEFAULT_TIMEOUT_MS = 12e4;
@@ -39593,9 +39593,11 @@ function ranked(map3) {
39593
39593
  function collectDocUrls(text) {
39594
39594
  return Array.from(new Set((String(text || "").match(DOC_URL_RE) || []).map((url2) => url2.replace(/[.?!:]+$/g, "")).filter((url2) => url2.startsWith("https://frontofhouse.okii.uk/")))).sort();
39595
39595
  }
39596
- function findRunFiles(root) {
39596
+ function findRunCandidates(root) {
39597
39597
  if (!(0, import_fs16.existsSync)(root)) return [];
39598
- const files = [];
39598
+ const candidates = [];
39599
+ const seenRunDirs = /* @__PURE__ */ new Set();
39600
+ const captureDirs = [];
39599
39601
  const stack = [root];
39600
39602
  while (stack.length > 0) {
39601
39603
  const current = stack.pop();
@@ -39605,11 +39607,18 @@ function findRunFiles(root) {
39605
39607
  if (entry.isDirectory()) {
39606
39608
  stack.push(absolute);
39607
39609
  } else if (entry.isFile() && entry.name === "run.json") {
39608
- files.push(absolute);
39610
+ candidates.push({ path: absolute, synthetic: false });
39611
+ seenRunDirs.add((0, import_path15.dirname)(absolute));
39612
+ } else if (entry.isFile() && entry.name === "commands.ndjson") {
39613
+ captureDirs.push(current);
39609
39614
  }
39610
39615
  }
39611
39616
  }
39612
- return files.sort();
39617
+ for (const captureDir of captureDirs) {
39618
+ if (seenRunDirs.has(captureDir)) continue;
39619
+ candidates.push({ path: (0, import_path15.join)(captureDir, "run.json"), synthetic: true });
39620
+ }
39621
+ return candidates.sort((a, b) => a.path.localeCompare(b.path));
39613
39622
  }
39614
39623
  function validateExternalAgentRun(value) {
39615
39624
  const findings = [];
@@ -39642,6 +39651,55 @@ function runSortTime(run) {
39642
39651
  const time3 = Date.parse(raw);
39643
39652
  return Number.isFinite(time3) ? time3 : 0;
39644
39653
  }
39654
+ function latestCommandTime(commands) {
39655
+ const times = commands.map((command) => String(command.completed_at || command.started_at || command.recorded_at || "")).map((raw) => ({ raw, time: Date.parse(raw) })).filter((entry) => Number.isFinite(entry.time)).sort((a, b) => b.time - a.time);
39656
+ return times[0]?.raw ?? null;
39657
+ }
39658
+ function firstCommandTime(commands) {
39659
+ const times = commands.map((command) => String(command.started_at || command.recorded_at || command.completed_at || "")).map((raw) => ({ raw, time: Date.parse(raw) })).filter((entry) => Number.isFinite(entry.time)).sort((a, b) => a.time - b.time);
39660
+ return times[0]?.raw ?? null;
39661
+ }
39662
+ function synthesizeRunFromCapture(runPath) {
39663
+ const runDir = (0, import_path15.dirname)(runPath);
39664
+ const commands = collapseCommandRecords(readNdjson((0, import_path15.join)(runDir, "commands.ndjson")));
39665
+ const metadata = asObject((0, import_fs16.existsSync)((0, import_path15.join)(runDir, "external-agent-metadata.json")) ? readJson((0, import_path15.join)(runDir, "external-agent-metadata.json")) : {});
39666
+ const blockerCodes = toArray2(metadata?.blocker_reason_codes).map(String).filter(Boolean);
39667
+ const holdReason = blockerCodes[0] || "external_agent_capture_unfinalized";
39668
+ const firstCommand = commands[0] || {};
39669
+ const startedAt = firstCommandTime(commands) || (/* @__PURE__ */ new Date(0)).toISOString();
39670
+ const endedAt = latestCommandTime(commands) || startedAt;
39671
+ const status = blockerCodes.length > 0 ? "hold" : "pass";
39672
+ const docs = toArray2(metadata?.docs_pages_used).map(String).filter(Boolean);
39673
+ const runId = (0, import_path15.dirname)(runPath).split(/[\\/]/).filter(Boolean).slice(-3).join("-") || "capture-only-run";
39674
+ return {
39675
+ schema_version: "external_agent_run.v1",
39676
+ run_id: runId,
39677
+ status,
39678
+ failure_reason_code: status === "pass" ? null : holdReason,
39679
+ model_provider: "unknown",
39680
+ model_name: "unknown",
39681
+ prompt_version: String(firstCommand.prompt_version || "unknown"),
39682
+ started_at: startedAt,
39683
+ ended_at: endedAt,
39684
+ manual_intervention_count: 0,
39685
+ environment: {
39686
+ foh_cli_version: firstCommand.cli_version || null,
39687
+ capture_only: true
39688
+ },
39689
+ public_entrypoints: [
39690
+ "https://frontofhouse.okii.uk",
39691
+ "npx --yes @f-o-h/cli@latest"
39692
+ ],
39693
+ commands_run: commands.map((command) => String(command.command || "")).filter(Boolean),
39694
+ docs_pages_used: docs,
39695
+ artifacts: {
39696
+ command_log: "commands.ndjson",
39697
+ agent_metadata: (0, import_fs16.existsSync)((0, import_path15.join)(runDir, "external-agent-metadata.json")) ? "external-agent-metadata.json" : null,
39698
+ capture_only: true
39699
+ },
39700
+ summary: "Synthetic run record created from external-agent capture artifacts because run.json was missing."
39701
+ };
39702
+ }
39645
39703
  function cohortIdForRunPath(root, runPath) {
39646
39704
  const normalized = (0, import_path15.relative)(root, (0, import_path15.dirname)(runPath)).replaceAll("\\", "/");
39647
39705
  const parts = normalized.split("/").filter(Boolean);
@@ -39652,9 +39710,10 @@ function cohortIdForRunPath(root, runPath) {
39652
39710
  function readRunRecords(root, cwd) {
39653
39711
  const records = [];
39654
39712
  const invalid_runs = [];
39655
- for (const file2 of findRunFiles(root)) {
39713
+ for (const candidate of findRunCandidates(root)) {
39714
+ const file2 = candidate.path;
39656
39715
  try {
39657
- const parsed = readJson(file2);
39716
+ const parsed = candidate.synthetic ? synthesizeRunFromCapture(file2) : readJson(file2);
39658
39717
  const findings = validateExternalAgentRun(parsed);
39659
39718
  if (findings.length > 0) {
39660
39719
  invalid_runs.push({ path: (0, import_path15.relative)(cwd, file2).replaceAll("\\", "/"), findings });
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
- {
1
+ {
2
2
  "name": "@f-o-h/cli",
3
- "version": "0.1.71",
3
+ "version": "0.1.72",
4
4
  "description": "FOH CLI - AI-operator provisioning tool for Front Of House",
5
5
  "license": "UNLICENSED",
6
6
  "bin": {
@@ -39,3 +39,4 @@
39
39
  "vitest": "^2.0.0"
40
40
  }
41
41
  }
42
+