@f-o-h/cli 0.1.29 → 0.1.31

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 (3) hide show
  1. package/README.md +1 -1
  2. package/dist/foh.js +31 -11
  3. package/package.json +1 -1
package/README.md CHANGED
@@ -4,7 +4,7 @@ AI-operator provisioning CLI for Front Of House.
4
4
 
5
5
  Public mirror: https://github.com/iiko38/front-of-house-cli
6
6
 
7
- Current published baseline: `@f-o-h/cli@0.1.29`
7
+ Current published baseline: `@f-o-h/cli@0.1.31`
8
8
 
9
9
  This mirror is a generated release artifact. The private product monorepo is not
10
10
  published here, and no open-source license is granted unless stated separately.
package/dist/foh.js CHANGED
@@ -32698,7 +32698,7 @@ var StdioServerTransport = class {
32698
32698
  };
32699
32699
 
32700
32700
  // src/lib/cli-version.ts
32701
- var CLI_VERSION = "0.1.29";
32701
+ var CLI_VERSION = "0.1.31";
32702
32702
 
32703
32703
  // src/commands/mcp-serve.ts
32704
32704
  var DEFAULT_TIMEOUT_MS = 12e4;
@@ -34343,8 +34343,8 @@ function buildMissingOptionsPlan(missing, opts) {
34343
34343
  "foh auth signup --web --json",
34344
34344
  "foh auth login --web --json",
34345
34345
  ...buildCliAuthFallbackCommands(),
34346
- "foh templates list --json",
34347
- 'foh setup --org <org-id> --agent-template <template-id> --agent-name "Demo Agent" --widget-domains <domain> --report-out setup-report.json --json'
34346
+ "foh templates list --category buyer --json",
34347
+ 'foh setup --org <org-id> --agent-template <buyer-template-id> --agent-name "Demo Buyer Agent" --widget-domains <domain> --voice-provider openai --voice-id alloy --report-out setup-report.json --json'
34348
34348
  ],
34349
34349
  extra: {
34350
34350
  code: "setup_required_options_missing",
@@ -34355,7 +34355,8 @@ function buildMissingOptionsPlan(missing, opts) {
34355
34355
  ai_agent_instruction: [
34356
34356
  "Do not guess org IDs, template IDs, or customer domains.",
34357
34357
  "If no browser is available, print sign_in_url and ask the user to sign in.",
34358
- "After auth, discover orgs and templates with the listed commands.",
34358
+ "After auth, discover orgs and certification-oriented buyer templates with the listed commands.",
34359
+ "Prefer UK Buyer Qualification or Viewing Booking; do not use greeting-only templates for proof/certification.",
34359
34360
  "Rerun setup only after all missing_options are resolved."
34360
34361
  ]
34361
34362
  }
@@ -38496,6 +38497,20 @@ function commandIdFor(input) {
38496
38497
  function outputArtifactName(commandId) {
38497
38498
  return `command-output-${commandId}.txt`;
38498
38499
  }
38500
+ function collectCheckReasonCodes(parsed) {
38501
+ const checks = Array.isArray(parsed.checks) ? parsed.checks : [];
38502
+ const codes = /* @__PURE__ */ new Set();
38503
+ for (const check2 of checks) {
38504
+ if (!check2 || typeof check2 !== "object") continue;
38505
+ const record2 = check2;
38506
+ const status = typeof record2.status === "string" ? record2.status.toLowerCase() : "";
38507
+ const reasonCode = typeof record2.reason_code === "string" ? record2.reason_code.trim() : "";
38508
+ if (reasonCode && status && status !== "pass" && status !== "skipped") {
38509
+ codes.add(reasonCode);
38510
+ }
38511
+ }
38512
+ return Array.from(codes);
38513
+ }
38499
38514
  function parseEnvelope(text) {
38500
38515
  const candidates = [
38501
38516
  ...text.split(/\r?\n/).map((line) => line.trim()).filter((line) => line.startsWith("{") && line.endsWith("}")).reverse()
@@ -38508,11 +38523,12 @@ function parseEnvelope(text) {
38508
38523
  const parsed = JSON.parse(candidate);
38509
38524
  const status = typeof parsed.status === "string" ? parsed.status : parsed.ok === true ? "pass" : parsed.ok === false ? "fail" : null;
38510
38525
  const reasonCode = typeof parsed.reason_code === "string" ? parsed.reason_code : typeof parsed.code === "string" ? parsed.code : null;
38511
- if (status || reasonCode) return { status, reasonCode };
38526
+ const checkReasonCodes = collectCheckReasonCodes(parsed);
38527
+ if (status || reasonCode || checkReasonCodes.length > 0) return { status, reasonCode, checkReasonCodes };
38512
38528
  } catch {
38513
38529
  }
38514
38530
  }
38515
- return { status: null, reasonCode: null };
38531
+ return { status: null, reasonCode: null, checkReasonCodes: [] };
38516
38532
  }
38517
38533
  function recordExternalAgentCliInvocation(input) {
38518
38534
  const runDir = getExternalAgentRunDir();
@@ -38615,6 +38631,7 @@ function completeExternalAgentCliInvocation(capture, input) {
38615
38631
  exit_code: Number.isInteger(input.exitCode) ? Number(input.exitCode) : null,
38616
38632
  status: parsed.status,
38617
38633
  reason_code: parsed.reasonCode,
38634
+ check_reason_codes: parsed.checkReasonCodes,
38618
38635
  output_artifact: artifact,
38619
38636
  output_bytes: Buffer.byteLength(output, "utf8")
38620
38637
  };
@@ -39009,17 +39026,20 @@ function classifyRun(input) {
39009
39026
  if (input.timedOut) return { status: "hold", reasonCode: "codex_runner_timeout" };
39010
39027
  if (!input.artifactSafetyOk) return { status: "fail", reasonCode: "external_agent_artifact_safety_blocked" };
39011
39028
  const completedCommands = readCommandRecords(input.run.run_dir).filter((record2) => record2.phase === "completed");
39012
- const commandReasonCodes = completedCommands.map((record2) => String(record2.reason_code || "")).filter(Boolean);
39029
+ const commandReasonCodes = completedCommands.flatMap((record2) => [
39030
+ String(record2.reason_code || ""),
39031
+ ...Array.isArray(record2.check_reason_codes) ? record2.check_reason_codes.map((code) => String(code || "")) : []
39032
+ ]).filter(Boolean);
39013
39033
  const hasCommandReason = (pattern) => commandReasonCodes.some((reason) => pattern.test(reason));
39014
39034
  if (hasCommandReason(/contact_phone_missing/i)) {
39015
39035
  return { status: "hold", reasonCode: "voice_contact_phone_missing" };
39016
39036
  }
39017
- if (hasCommandReason(/proof_held/i)) {
39018
- return { status: "hold", reasonCode: "external_agent_proof_held" };
39019
- }
39020
39037
  if (hasCommandReason(/sim(?:ulation)?[_-]?cert(?:ify|ification)?.*failed|simulation_certification_failed/i)) {
39021
39038
  return { status: "hold", reasonCode: "simulation_certification_failed" };
39022
39039
  }
39040
+ if (hasCommandReason(/proof_held/i)) {
39041
+ return { status: "hold", reasonCode: "external_agent_proof_held" };
39042
+ }
39023
39043
  if (hasCommandReason(/agent_limit_reached/i)) {
39024
39044
  return { status: "hold", reasonCode: "eval_org_agent_limit_reached" };
39025
39045
  }
@@ -39249,7 +39269,7 @@ async function executeExternalAgentExecutorPlan(plan, options = {}) {
39249
39269
  var DEFAULT_PROMPT_VERSION = "blank-setup.v1";
39250
39270
  var DEFAULT_BATCH_MODELS = "openai/codex,anthropic/claude,cursor/agent";
39251
39271
  var PROMPTS = {
39252
- "blank-setup.v1": "Go to https://frontofhouse.okii.uk. Use only public docs, public API docs, and the public npm CLI package. Install the FOH CLI, authenticate or reach a deterministic auth blocker, create or configure a Front Of House voice agent and website widget, run proof/smoke/certification where available, and produce a final evidence summary with commands run, docs used, artifacts created, and any blocker reason codes. Do not assume access to the private source repository.",
39272
+ "blank-setup.v1": "Go to https://frontofhouse.okii.uk. Use only public docs, public API docs, and the public npm CLI package. Install the FOH CLI, authenticate or reach a deterministic auth blocker, then create or configure a Front Of House voice agent and website widget. Prefer the certification-oriented buyer templates: run `foh templates list --category buyer --json` and use `UK Buyer Qualification` or `Viewing Booking` when available; do not use a greeting-only template for proof/certification. Prefer `foh setup` for end-to-end provisioning because it can provision the contact phone path, widget, voice config, smoke test, certification, and publish readiness together. Run proof/smoke/certification where available, including widget proof and voice proof. If voice proof returns `contact_phone_missing`, run the printed provision command or report that exact reason code. Produce a final evidence summary with commands run, docs used, artifacts created, and any blocker reason codes. Do not assume access to the private source repository.",
39253
39273
  "debug-proof-failure.v1": "You are given a FOH proof or debug artifact. Use public docs and FOH CLI/API behavior to classify whether the blocker is docs, auth, org setup, agent config, widget, channel, runtime, or product bug. Produce a redacted improvement packet or the exact command needed to produce one. Do not ask the human to interpret logs manually unless no machine-readable artifact exists.",
39254
39274
  "knowledge-miss.v1": "A FOH agent failed to answer a business question. Use CLI/API/docs to determine whether this is a knowledge-ingestion issue, retrieval issue, config issue, prompt/behavior issue, or runtime issue. Prefer foh knowledge query, transcript export, replay, and foh bug improve artifacts over screenshots.",
39255
39275
  "replay-failure.v1": "You are given a FOH transcript or replay artifact. Use CLI/API/docs to replay or inspect the failed interaction, identify expected vs actual behavior, and produce a scenario-test or improvement-packet candidate."
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@f-o-h/cli",
3
- "version": "0.1.29",
3
+ "version": "0.1.31",
4
4
  "description": "FOH CLI - AI-operator provisioning tool for Front Of House",
5
5
  "license": "UNLICENSED",
6
6
  "bin": {