@algosuite/vo-mcp 0.2.0-beta.37 → 0.2.0-beta.39

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.
@@ -289,6 +289,8 @@ var DEFAULT_PERMISSION_MODE = "acceptEdits";
289
289
  var VO_SESSION_STATE_TOOL = "mcp__vo-mcp__vo_report_session_state";
290
290
  var VO_HEADLESS_PNPM_TOOL = "Bash(pnpm *)";
291
291
  var VO_HEADLESS_PNPM_FROM_DIR_TOOL = "Bash(pnpm --dir *)";
292
+ var VO_RESEARCH_TOOLS = ["WebFetch", "WebSearch"];
293
+ var VO_WORKFLOW_TOOLS = ["Workflow"];
292
294
  var SAFE_PERMISSION_MODES = /* @__PURE__ */ new Set(["acceptEdits", "plan", "default", "dontAsk", "delegate"]);
293
295
  function normalizeClaudePermissionMode(value) {
294
296
  const normalized = String(value ?? "").trim() || DEFAULT_PERMISSION_MODE;
@@ -297,9 +299,14 @@ function normalizeClaudePermissionMode(value) {
297
299
  }
298
300
  return normalized;
299
301
  }
300
- function buildClaudeArgs({ permissionMode = DEFAULT_PERMISSION_MODE, maxTurns, model, effort, maxBudgetUsd, env = process.env } = {}) {
302
+ function buildClaudeArgs({ permissionMode = DEFAULT_PERMISSION_MODE, maxTurns, model, effort, maxBudgetUsd, researchHarness = false, env = process.env } = {}) {
301
303
  const effectivePermissionMode = normalizeClaudePermissionMode(permissionMode);
302
- const allowedTools = effectivePermissionMode === DEFAULT_PERMISSION_MODE ? `${VO_SESSION_STATE_TOOL},${VO_HEADLESS_PNPM_TOOL},${VO_HEADLESS_PNPM_FROM_DIR_TOOL}` : VO_SESSION_STATE_TOOL;
304
+ const noWeb = String(env?.VO_CODE_RUNNER_NO_WEB ?? "").trim() === "1";
305
+ const research = noWeb ? [] : VO_RESEARCH_TOOLS;
306
+ const noWorkflow = noWeb || String(env?.VO_CODE_RUNNER_NO_WORKFLOW ?? "").trim() === "1";
307
+ const workflow = researchHarness === true && !noWorkflow ? VO_WORKFLOW_TOOLS : [];
308
+ const baseTools = effectivePermissionMode === DEFAULT_PERMISSION_MODE ? [VO_SESSION_STATE_TOOL, VO_HEADLESS_PNPM_TOOL, VO_HEADLESS_PNPM_FROM_DIR_TOOL] : [VO_SESSION_STATE_TOOL];
309
+ const allowedTools = [...baseTools, ...research, ...workflow].join(",");
303
310
  const args = [
304
311
  "-p",
305
312
  "--output-format",
@@ -338,6 +345,7 @@ import path2 from "node:path";
338
345
  // ../../scripts/virtual-office/code-runner/agent-token-usage.mjs
339
346
  var MAX_TOKEN_COUNT = 1e9;
340
347
  var MAX_COST_USD = 1e4;
348
+ var NO_AGENT_SPAWNED_ECONOMICS = Object.freeze({ cost_usd: 0, cost_basis: "no_agent_spawned" });
341
349
  function count(value) {
342
350
  if (typeof value !== "number" || !Number.isFinite(value) || value < 0) return null;
343
351
  return Math.min(MAX_TOKEN_COUNT, Math.round(value));
@@ -612,8 +620,8 @@ var ClaudeRunner = class {
612
620
  get binary() {
613
621
  return "claude";
614
622
  }
615
- buildArgs({ permissionMode, maxTurns, model, effort, maxBudgetUsd } = {}) {
616
- return buildClaudeArgs({ permissionMode, maxTurns, model, effort, maxBudgetUsd });
623
+ buildArgs({ permissionMode, maxTurns, model, effort, maxBudgetUsd, researchHarness } = {}) {
624
+ return buildClaudeArgs({ permissionMode, maxTurns, model, effort, maxBudgetUsd, researchHarness });
617
625
  }
618
626
  parseEvent(line) {
619
627
  return parseStreamEvent(line);
package/dist/cli.js CHANGED
@@ -3009,6 +3009,8 @@ async function handleVerifyAnswer(deps, rawInput, signal) {
3009
3009
  engine_version: engineResult.engine_version,
3010
3010
  degraded: engineResult.degraded,
3011
3011
  ...engineResult.quorum_failed === true ? { quorum_failed: true } : {},
3012
+ // The verification receipt (moat decision_id) — the thing an agent pastes as `receipt id: <uuid>`.
3013
+ ...engineResult.receipt_id ? { receipt_id: engineResult.receipt_id } : {},
3012
3014
  gate_type: gateType,
3013
3015
  ...kbResult.error !== null ? { kb_unavailable: true } : {},
3014
3016
  ...kbTruncated > 0 ? { kb_rules_truncated: kbTruncated } : {}
@@ -3276,6 +3278,10 @@ async function handleConsensusJudgment(deps, rawInput, signal) {
3276
3278
  engine_version: engineResult.engine_version,
3277
3279
  degraded: engineResult.degraded,
3278
3280
  ...engineResult.quorum_failed === true ? { quorum_failed: true } : {},
3281
+ // The verification receipt (moat decision_id) — the thing an agent pastes as `receipt id: <uuid>`.
3282
+ // NOTE: a content-hash cache hit replays the ORIGINAL call's receipt_id (same claim, same verdict, no new spend) —
3283
+ // a receipt asserts the stage ran for this claim, not one-receipt-per-call.
3284
+ ...engineResult.receipt_id ? { receipt_id: engineResult.receipt_id } : {},
3279
3285
  gate_type: gateType,
3280
3286
  // ─── Consensus-engine feature outputs (additive; 2026-06-13) ─────────────
3281
3287
  // Feature 2 (calibrated-confidence) — ON by default; the engine attaches
@@ -6758,6 +6764,7 @@ init_common();
6758
6764
  var UPSERT_TOOL_NAME = "vo_private_knowledge_upsert";
6759
6765
  var CONTEXT_TOOL_NAME = "vo_private_knowledge_context";
6760
6766
  var INVALIDATE_TOOL_NAME = "vo_private_knowledge_invalidate";
6767
+ var STALE_TOOL_NAME = "vo_private_knowledge_stale";
6761
6768
  var KNOWLEDGE_CLASSES = ["memory", "skill", "doctrine", "hook", "command"];
6762
6769
  var PRECISION_CHAR_BUDGET = 12e3;
6763
6770
  var upsertInputSchema = {
@@ -6790,9 +6797,26 @@ var invalidateInputSchema = {
6790
6797
  required: ["knowledge_class", "source_path"],
6791
6798
  additionalProperties: false
6792
6799
  };
6800
+ var staleInputSchema = {
6801
+ type: "object",
6802
+ properties: {
6803
+ days: { type: "number", minimum: 1, maximum: 3650, description: "Window in days (default 90): entries at least this old that were never recalled into an agent context, or not within the window." },
6804
+ limit: { type: "number", minimum: 1, maximum: 500 }
6805
+ },
6806
+ additionalProperties: false
6807
+ };
6808
+ var staleDescription = `The FORGETTING REPORT: lists the authenticated operator\u2019s live private-knowledge entries that are at least N days old and have never been recalled into an agent context (or not within N days). Metadata only. SURFACES ONLY \u2014 never auto-invalidates or auto-merges: two memories that disagree may both have been right in different contexts, so you decide. Act on a candidate deliberately with ${INVALIDATE_TOOL_NAME}; recall counts come from ${CONTEXT_TOOL_NAME} reads that actually placed the entry into returned context.`;
6793
6809
  var upsertDescription = "Uploads or refreshes the authenticated operator\u2019s private cloud knowledge. Works for Claude, Codex, Cursor, and cowork clients via the same vo-mcp login credential. Returns metadata only, not raw stored content. PRECISION DISCIPLINE: keep each entry tight and focused (~1-3 pages) with a descriptive retrieval-friendly title \u2014 retrieval surfaces whole entries, so small dense entries beat bulk dumps. Split large corpora into focused entries, then run a retrieval self-test via vo_private_knowledge_context before relying on the knowledge.";
6794
6810
  var contextDescription = "Retrieves prompt-ready private knowledge context for the authenticated operator. Returns snippets/context only; no raw corpus download. Also the retrieval self-test surface: after upserting critical knowledge, query for it here and confirm the entry surfaces before trusting it in downstream work.";
6795
6811
  var invalidateDescription = `Soft-deletes one private-knowledge entry for the authenticated operator: closes the live entry\u2019s validity window (bi-temporal) so it stops surfacing in retrieval. Never destroys data \u2014 invalidated versions remain queryable server-side via include_invalidated. Identify the entry by the same { knowledge_class, source_path } used at upsert; a not_found response means no live entry matches. After invalidating, self-test via ${CONTEXT_TOOL_NAME} to confirm the entry no longer surfaces.`;
6812
+ function isStaleInput(value) {
6813
+ if (value === void 0 || value === null) return true;
6814
+ if (typeof value !== "object") return false;
6815
+ const input = value;
6816
+ if (input["days"] !== void 0 && typeof input["days"] !== "number") return false;
6817
+ if (input["limit"] !== void 0 && typeof input["limit"] !== "number") return false;
6818
+ return true;
6819
+ }
6796
6820
  function isKnowledgeClass(value) {
6797
6821
  return typeof value === "string" && KNOWLEDGE_CLASSES.includes(value);
6798
6822
  }
@@ -6872,6 +6896,30 @@ async function handlePrivateKnowledgeInvalidate(_deps, rawInput, _signal, fetchF
6872
6896
  const payload = await callPrivateKnowledge("/api/v1/knowledge/private/invalidate", rawInput, fetchFn);
6873
6897
  return jsonContent({ tool: INVALIDATE_TOOL_NAME, schema_version: 1, payload });
6874
6898
  }
6899
+ async function handlePrivateKnowledgeStale(_deps, rawInput, _signal, fetchFn = globalThis.fetch) {
6900
+ if (!isStaleInput(rawInput)) {
6901
+ throw invalidParams(STALE_TOOL_NAME, "expected { optional days, optional limit }.");
6902
+ }
6903
+ const auth = await getCloudAuth(fetchFn);
6904
+ if (!auth.ok) return jsonContent({ tool: STALE_TOOL_NAME, schema_version: 1, payload: { ok: false, reason: auth.reason } });
6905
+ const params = new URLSearchParams();
6906
+ if (rawInput?.days !== void 0) params.set("days", String(Math.trunc(rawInput.days)));
6907
+ if (rawInput?.limit !== void 0) params.set("limit", String(Math.trunc(rawInput.limit)));
6908
+ const qs = params.toString();
6909
+ const response = await fetchFn(`${auth.controlPlaneUrl}/api/v1/knowledge/private/stale${qs ? `?${qs}` : ""}`, {
6910
+ method: "GET",
6911
+ headers: { authorization: `Bearer ${auth.token}` }
6912
+ });
6913
+ const text = await response.text();
6914
+ let parsed;
6915
+ try {
6916
+ parsed = text ? JSON.parse(text) : null;
6917
+ } catch {
6918
+ parsed = null;
6919
+ }
6920
+ const payload = response.status < 200 || response.status >= 300 ? { ok: false, status: response.status, response: parsed ?? text } : parsed;
6921
+ return jsonContent({ tool: STALE_TOOL_NAME, schema_version: 1, payload });
6922
+ }
6875
6923
  async function handlePrivateKnowledgeContext(_deps, rawInput, _signal, fetchFn = globalThis.fetch) {
6876
6924
  if (!isContextInput(rawInput)) {
6877
6925
  throw invalidParams(CONTEXT_TOOL_NAME, "expected { query, optional limit, optional knowledge_class }.");
@@ -7416,6 +7464,14 @@ function buildToolRegistry() {
7416
7464
  },
7417
7465
  handler: handlePrivateKnowledgeInvalidate
7418
7466
  },
7467
+ [STALE_TOOL_NAME]: {
7468
+ definition: {
7469
+ name: STALE_TOOL_NAME,
7470
+ description: staleDescription,
7471
+ inputSchema: staleInputSchema
7472
+ },
7473
+ handler: handlePrivateKnowledgeStale
7474
+ },
7419
7475
  [POST_TOOL_NAME]: {
7420
7476
  definition: {
7421
7477
  name: POST_TOOL_NAME,
@@ -8272,8 +8328,10 @@ function createMoatConsensusClient(opts) {
8272
8328
  }
8273
8329
  const agreeing = normalizeAgreeing(parsed.models_agreeing);
8274
8330
  const reasoning = agreeing !== void 0 ? `${parsed.reason} (${agreeing} models agreeing)` : parsed.reason;
8331
+ const receiptId = typeof parsed.decision_id === "string" && parsed.decision_id.trim().length > 0 ? parsed.decision_id.trim().slice(0, 120) : null;
8275
8332
  return {
8276
8333
  ok: true,
8334
+ ...receiptId ? { receipt_id: receiptId } : {},
8277
8335
  synthesized_verdict: {
8278
8336
  verdict: parsed.approved ? "pass" : "fail",
8279
8337
  confidence: normalizeConfidence(parsed.confidence),