open-multi-agent-kit 0.78.0 → 0.78.2

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 (132) hide show
  1. package/CHANGELOG.md +56 -15
  2. package/MATURITY.md +6 -2
  3. package/README.md +125 -26
  4. package/ROADMAP.md +36 -28
  5. package/dist/cli/register-basic-commands.js +3 -2
  6. package/dist/cli/register-mcp-dag-cron-screenshot-commands.js +2 -0
  7. package/dist/cli/register-spec-agent-goal-commands.js +45 -0
  8. package/dist/cli/register-tool-commands.js +11 -0
  9. package/dist/cli/register-workflow-commands.js +1 -0
  10. package/dist/cli/registry/tooling.js +3 -2
  11. package/dist/cli/release-promotion-gate.d.ts +14 -0
  12. package/dist/cli/release-promotion-gate.js +71 -0
  13. package/dist/cli/v2/release-commands.d.ts +29 -0
  14. package/dist/cli/v2/release-commands.js +95 -0
  15. package/dist/commands/chat/core.js +5 -0
  16. package/dist/commands/chat/native-root-loop.js +74 -1
  17. package/dist/commands/chat/slash/commands/session.js +19 -1
  18. package/dist/commands/dag-from-spec.d.ts +1 -0
  19. package/dist/commands/dag-from-spec.js +61 -1
  20. package/dist/commands/goal-interview.d.ts +18 -0
  21. package/dist/commands/goal-interview.js +396 -0
  22. package/dist/commands/graph.d.ts +62 -0
  23. package/dist/commands/graph.js +182 -0
  24. package/dist/commands/merge.d.ts +1 -0
  25. package/dist/commands/merge.js +88 -0
  26. package/dist/commands/parallel/core.js +3 -3
  27. package/dist/commands/provider.js +5 -3
  28. package/dist/commands/star.js +6 -1
  29. package/dist/commands/summary.d.ts +4 -1
  30. package/dist/commands/summary.js +103 -1
  31. package/dist/commands/team.d.ts +1 -0
  32. package/dist/commands/team.js +38 -0
  33. package/dist/contracts/interview.d.ts +106 -0
  34. package/dist/contracts/interview.js +9 -0
  35. package/dist/contracts/provider-health.d.ts +42 -0
  36. package/dist/contracts/provider-health.js +9 -0
  37. package/dist/evidence/index.d.ts +4 -0
  38. package/dist/evidence/index.js +2 -0
  39. package/dist/evidence/proof-trust-cli.d.ts +8 -0
  40. package/dist/evidence/proof-trust-cli.js +27 -0
  41. package/dist/evidence/proof-trust.d.ts +14 -0
  42. package/dist/evidence/proof-trust.js +381 -0
  43. package/dist/evidence/regression-proof-matrix.d.ts +42 -0
  44. package/dist/evidence/regression-proof-matrix.js +72 -0
  45. package/dist/goal/intent-frame.d.ts +30 -0
  46. package/dist/goal/intent-frame.js +39 -9
  47. package/dist/goal/interview-assimilation.d.ts +13 -0
  48. package/dist/goal/interview-assimilation.js +383 -0
  49. package/dist/goal/interview-question-bank.d.ts +11 -0
  50. package/dist/goal/interview-question-bank.js +225 -0
  51. package/dist/goal/interview-scoring.d.ts +31 -0
  52. package/dist/goal/interview-scoring.js +187 -0
  53. package/dist/goal/interview-session.d.ts +25 -0
  54. package/dist/goal/interview-session.js +116 -0
  55. package/dist/input/input-envelope.d.ts +22 -0
  56. package/dist/input/input-envelope.js +1 -0
  57. package/dist/memory/local-graph-memory-store.d.ts +15 -0
  58. package/dist/memory/local-graph-memory-store.js +176 -0
  59. package/dist/memory/memory-store.d.ts +18 -0
  60. package/dist/memory/memory-store.js +18 -0
  61. package/dist/orchestration/adaptorch-topology.d.ts +59 -0
  62. package/dist/orchestration/adaptorch-topology.js +194 -0
  63. package/dist/orchestration/capability-routing.d.ts +23 -0
  64. package/dist/orchestration/capability-routing.js +56 -0
  65. package/dist/orchestration/dag-compiler-types.d.ts +3 -0
  66. package/dist/orchestration/dag-compiler.js +14 -1
  67. package/dist/orchestration/parallel-orchestrator.d.ts +6 -0
  68. package/dist/orchestration/parallel-orchestrator.js +31 -0
  69. package/dist/providers/provider-health.d.ts +39 -0
  70. package/dist/providers/provider-health.js +161 -0
  71. package/dist/runtime/advanced-control-loop.d.ts +60 -0
  72. package/dist/runtime/advanced-control-loop.js +136 -0
  73. package/dist/runtime/agent-runtime.d.ts +10 -0
  74. package/dist/runtime/blast-radius.d.ts +10 -0
  75. package/dist/runtime/blast-radius.js +14 -0
  76. package/dist/runtime/context-broker.d.ts +13 -4
  77. package/dist/runtime/context-broker.js +14 -1
  78. package/dist/runtime/contracts/evidence.d.ts +87 -0
  79. package/dist/runtime/contracts/evidence.js +7 -0
  80. package/dist/runtime/contracts/router-v2.d.ts +44 -0
  81. package/dist/runtime/contracts/router-v2.js +4 -0
  82. package/dist/runtime/contracts/weakness-remediation.d.ts +67 -0
  83. package/dist/runtime/contracts/weakness-remediation.js +36 -0
  84. package/dist/runtime/headroom-policy.d.ts +37 -0
  85. package/dist/runtime/headroom-policy.js +122 -0
  86. package/dist/runtime/kimi-api-runtime.js +59 -1
  87. package/dist/runtime/ouroboros-policy.d.ts +57 -0
  88. package/dist/runtime/ouroboros-policy.js +134 -0
  89. package/dist/runtime/proof-bundle-trust.d.ts +74 -0
  90. package/dist/runtime/proof-bundle-trust.js +100 -0
  91. package/dist/runtime/provider-maturity-gate.d.ts +41 -0
  92. package/dist/runtime/provider-maturity-gate.js +101 -0
  93. package/dist/runtime/public-surface.d.ts +93 -0
  94. package/dist/runtime/public-surface.js +146 -0
  95. package/dist/runtime/router-v2-scoring.d.ts +11 -0
  96. package/dist/runtime/router-v2-scoring.js +151 -0
  97. package/dist/runtime/runtime-backed-task-runner.js +9 -1
  98. package/dist/runtime/tool-dispatch-contracts.d.ts +57 -1
  99. package/dist/runtime/tool-dispatch-contracts.js +79 -3
  100. package/dist/runtime/weakness-remediation-index.d.ts +27 -0
  101. package/dist/runtime/weakness-remediation-index.js +37 -0
  102. package/dist/safety/tool-authority-gate.d.ts +62 -0
  103. package/dist/safety/tool-authority-gate.js +108 -0
  104. package/dist/schema/proof-bundle.schema.d.ts +26 -26
  105. package/dist/schema/provider.schema.d.ts +4 -4
  106. package/dist/util/clipboard-image.d.ts +49 -0
  107. package/dist/util/clipboard-image.js +263 -0
  108. package/dist/util/first-run-star.d.ts +9 -0
  109. package/dist/util/first-run-star.js +42 -1
  110. package/dist/util/terminal-input.d.ts +20 -0
  111. package/dist/util/terminal-input.js +32 -0
  112. package/dist/util/update-check.d.ts +6 -1
  113. package/dist/util/update-check.js +35 -1
  114. package/docs/2026-06-08/critical-issues.md +20 -0
  115. package/docs/2026-06-08/improvements.md +14 -0
  116. package/docs/2026-06-08/init-checklist.md +25 -0
  117. package/docs/2026-06-08/plan.md +20 -0
  118. package/docs/2026-06-09/critical-issues.md +20 -0
  119. package/docs/2026-06-09/improvements.md +14 -0
  120. package/docs/2026-06-09/init-checklist.md +25 -0
  121. package/docs/2026-06-09/plan.md +20 -0
  122. package/docs/getting-started.md +31 -3
  123. package/docs/github-organic-promotion.md +127 -0
  124. package/docs/integrations/ouroboros.md +96 -0
  125. package/docs/native-root-runtime-algorithms.md +301 -0
  126. package/docs/provider-maturity.md +1 -1
  127. package/docs/versioning.md +3 -3
  128. package/package.json +4 -3
  129. package/readmeasset/ASSET_INDEX.md +1 -0
  130. package/templates/skills/agents/omk-agent-reach-websearch/SKILL.md +55 -0
  131. package/templates/skills/kimi/omk-agent-reach-websearch/SKILL.md +55 -0
  132. package/dist/native/linux-x64/omk-safety +0 -0
@@ -1,10 +1,86 @@
1
1
  import { createToolExecutionBatches } from "./tool-registry-contract.js";
2
- export async function dispatchToolCallsByContract(calls, registry, dispatchOne) {
2
+ import { decideToolAuthority, mapToolNameToOp, } from "../safety/tool-authority-gate.js";
3
+ const ENFORCE_PATTERN = /^(1|true|yes|on)$/i;
4
+ /**
5
+ * Resolve the global enforcement opt-in from the environment. Default OFF means
6
+ * the gate runs in shadow mode (record only). Set `OMK_TOOL_AUTHORITY_ENFORCE=1`
7
+ * to enable fail-closed enforcement at the dispatch checkpoint.
8
+ */
9
+ export function resolveToolAuthorityEnforcement(env = process.env) {
10
+ return ENFORCE_PATTERN.test((env.OMK_TOOL_AUTHORITY_ENFORCE ?? "").trim());
11
+ }
12
+ /** Build a redacted reason string from non-secret authority signals only. */
13
+ function redactedAuthorityReason(op, decision, wiring) {
14
+ return (`tool-authority ${decision} for ${op} op ` +
15
+ `(write=${wiring.writeAuthority}, shell=${wiring.shellAuthority}, ` +
16
+ `policy=${wiring.approvalPolicy}, sandbox=${wiring.sandboxMode}, tty=${wiring.tty})`);
17
+ }
18
+ /** Error used to reject a tool call rejected by the authority gate (enforce mode). */
19
+ export class ToolAuthorityBlockedError extends Error {
20
+ toolName;
21
+ op;
22
+ decision;
23
+ constructor(record) {
24
+ super(record.reason);
25
+ this.name = "ToolAuthorityBlockedError";
26
+ this.toolName = record.toolName;
27
+ this.op = record.op;
28
+ this.decision = record.decision;
29
+ }
30
+ }
31
+ /** Compute the gate verdict for a single call. Pure (no IO, no env reads). */
32
+ export function evaluateToolAuthority(toolName, wiring) {
33
+ const op = mapToolNameToOp(toolName);
34
+ const decision = decideToolAuthority({
35
+ op,
36
+ writeAuthority: wiring.writeAuthority,
37
+ shellAuthority: wiring.shellAuthority,
38
+ approvalPolicy: wiring.approvalPolicy,
39
+ sandboxMode: wiring.sandboxMode,
40
+ tty: wiring.tty,
41
+ });
42
+ const enforce = wiring.enforce === true;
43
+ // Fail-closed: a non-TTY "ask" is treated as a block (decideToolAuthority
44
+ // already returns "block" for non-TTY interactive; the second clause is a
45
+ // defensive guard in case the caller ever surfaces "ask" without a TTY).
46
+ const wouldBlock = decision === "block" || (decision === "ask" && !wiring.tty);
47
+ const blocked = enforce && wouldBlock;
48
+ return {
49
+ record: {
50
+ toolName,
51
+ op,
52
+ decision,
53
+ mode: enforce ? "enforce" : "shadow",
54
+ enforced: blocked,
55
+ reason: redactedAuthorityReason(op, decision, wiring),
56
+ },
57
+ blocked,
58
+ };
59
+ }
60
+ /**
61
+ * Wrap a dispatch function with the authority checkpoint. In shadow mode the
62
+ * wrapper records the verdict and always delegates to `dispatchOne`. In enforce
63
+ * mode a blocked verdict rejects the call with a redacted reason.
64
+ */
65
+ function buildGatedDispatch(wiring, dispatchOne) {
66
+ return async (call) => {
67
+ const { record, blocked } = evaluateToolAuthority(call.toolName, wiring);
68
+ wiring.onDecision?.(record);
69
+ if (blocked) {
70
+ throw new ToolAuthorityBlockedError(record);
71
+ }
72
+ return dispatchOne(call);
73
+ };
74
+ }
75
+ export async function dispatchToolCallsByContract(calls, registry, dispatchOne, authority) {
76
+ // When no authority wiring is supplied the dispatch path is byte-identical to
77
+ // the pre-gate behavior (the checkpoint is a no-op).
78
+ const effectiveDispatch = authority ? buildGatedDispatch(authority, dispatchOne) : dispatchOne;
3
79
  const batches = createToolExecutionBatches(calls, registry);
4
80
  const appended = [];
5
81
  for (const batch of batches) {
6
82
  if (batch.kind === "parallel") {
7
- const settled = await Promise.allSettled(batch.calls.map((call) => dispatchOne(call)));
83
+ const settled = await Promise.allSettled(batch.calls.map((call) => effectiveDispatch(call)));
8
84
  settled.forEach((result, index) => {
9
85
  const call = batch.calls[index];
10
86
  if (!call)
@@ -15,7 +91,7 @@ export async function dispatchToolCallsByContract(calls, registry, dispatchOne)
15
91
  }
16
92
  for (const call of batch.calls) {
17
93
  try {
18
- appended.push({ call, status: "fulfilled", value: await dispatchOne(call) });
94
+ appended.push({ call, status: "fulfilled", value: await effectiveDispatch(call) });
19
95
  }
20
96
  catch (reason) {
21
97
  appended.push({ call, status: "rejected", reason });
@@ -0,0 +1,27 @@
1
+ /**
2
+ * Weakness Remediation Index — Public factory that instantiates all
3
+ * Phase 1–6 engines with sensible defaults.
4
+ */
5
+ export { type IntegrationResultKind, type WeaknessRemediationState, type AdvancedControlLoopInput, type AdvancedControlLoopResult, type AdvancedControlLoop, type AdvancedControlLoopOptions, createAdvancedControlLoop, } from "./advanced-control-loop.js";
6
+ export { type SurfaceItem, type ScoredSurfaceItem, type MandatoryAnchor, type CompressionResult, type PublicSurfaceCompressorOptions, computeSurfaceScore, enforceFlowInvariant, PublicSurfaceCompressor, } from "./public-surface.js";
7
+ export { type ProofBundleScores, type TrustScoreResult, type ProofBundleTrustEngine, type DeriveScoresOptions, createProofBundleTrustEngine, } from "./proof-bundle-trust.js";
8
+ export { type MaturityResult, type ProviderMaturityGate, createProviderMaturityGate, } from "./provider-maturity-gate.js";
9
+ export { type RuntimeScoreV2, type RuntimeRouterDecisionV2, type RouterV2Options, type RouterV2ScoringEngine, type BlastRadiusParams, type EvidenceHistoryEntry, type NodeIntent, } from "./contracts/router-v2.js";
10
+ export { createRouterV2ScoringEngine, } from "./router-v2-scoring.js";
11
+ export { type ReleasePromotionInputs, type ReleasePromotionResult, type ReleaseVerdict, RELEASE_GATE_WEIGHTS, TAU_EVIDENCE, TAU_EVIDENCE_HIGH, TAU_PROOF, TAU_STABLE, BETA_PRIOR_ALPHA0, BETA_PRIOR_BETA0, SURFACE_BUDGET_K, } from "./contracts/weakness-remediation.js";
12
+ export { createReleasePromotionGate, type ReleasePromotionGate, } from "../cli/release-promotion-gate.js";
13
+ import { PublicSurfaceCompressor } from "./public-surface.js";
14
+ import { createProofBundleTrustEngine } from "./proof-bundle-trust.js";
15
+ import { createProviderMaturityGate } from "./provider-maturity-gate.js";
16
+ import { createRouterV2ScoringEngine } from "./router-v2-scoring.js";
17
+ import { createReleasePromotionGate } from "../cli/release-promotion-gate.js";
18
+ import { createAdvancedControlLoop } from "./advanced-control-loop.js";
19
+ export interface WeaknessRemediationIndex {
20
+ readonly publicSurfaceCompressor: PublicSurfaceCompressor;
21
+ readonly proofBundleTrustEngine: ReturnType<typeof createProofBundleTrustEngine>;
22
+ readonly providerMaturityGate: ReturnType<typeof createProviderMaturityGate>;
23
+ readonly routerV2ScoringEngine: ReturnType<typeof createRouterV2ScoringEngine>;
24
+ readonly releasePromotionGate: ReturnType<typeof createReleasePromotionGate>;
25
+ readonly advancedControlLoop: ReturnType<typeof createAdvancedControlLoop>;
26
+ }
27
+ export declare function createWeaknessRemediationIndex(): WeaknessRemediationIndex;
@@ -0,0 +1,37 @@
1
+ /**
2
+ * Weakness Remediation Index — Public factory that instantiates all
3
+ * Phase 1–6 engines with sensible defaults.
4
+ */
5
+ export { createAdvancedControlLoop, } from "./advanced-control-loop.js";
6
+ export { computeSurfaceScore, enforceFlowInvariant, PublicSurfaceCompressor, } from "./public-surface.js";
7
+ export { createProofBundleTrustEngine, } from "./proof-bundle-trust.js";
8
+ export { createProviderMaturityGate, } from "./provider-maturity-gate.js";
9
+ export { createRouterV2ScoringEngine, } from "./router-v2-scoring.js";
10
+ export { RELEASE_GATE_WEIGHTS, TAU_EVIDENCE, TAU_EVIDENCE_HIGH, TAU_PROOF, TAU_STABLE, BETA_PRIOR_ALPHA0, BETA_PRIOR_BETA0, SURFACE_BUDGET_K, } from "./contracts/weakness-remediation.js";
11
+ export { createReleasePromotionGate, } from "../cli/release-promotion-gate.js";
12
+ // ─── Convenience factory ─────────────────────────────────────────────────────
13
+ import { PublicSurfaceCompressor } from "./public-surface.js";
14
+ import { createProofBundleTrustEngine } from "./proof-bundle-trust.js";
15
+ import { createProviderMaturityGate } from "./provider-maturity-gate.js";
16
+ import { createRouterV2ScoringEngine } from "./router-v2-scoring.js";
17
+ import { createReleasePromotionGate } from "../cli/release-promotion-gate.js";
18
+ import { createAdvancedControlLoop } from "./advanced-control-loop.js";
19
+ export function createWeaknessRemediationIndex() {
20
+ const publicSurfaceCompressor = new PublicSurfaceCompressor();
21
+ const proofBundleTrustEngine = createProofBundleTrustEngine();
22
+ const providerMaturityGate = createProviderMaturityGate();
23
+ const routerV2ScoringEngine = createRouterV2ScoringEngine();
24
+ const releasePromotionGate = createReleasePromotionGate();
25
+ const advancedControlLoop = createAdvancedControlLoop({
26
+ releaseGate: releasePromotionGate,
27
+ releaseGateEnabled: true,
28
+ });
29
+ return {
30
+ publicSurfaceCompressor,
31
+ proofBundleTrustEngine,
32
+ providerMaturityGate,
33
+ routerV2ScoringEngine,
34
+ releasePromotionGate,
35
+ advancedControlLoop,
36
+ };
37
+ }
@@ -0,0 +1,62 @@
1
+ /**
2
+ * Pure tool-authority decision primitive.
3
+ *
4
+ * Decides allow / ask / block for a tool operation given the provider's
5
+ * write/shell authority, the active approval policy, the sandbox mode, and
6
+ * whether a TTY is attached. The function is intentionally pure: no IO, no
7
+ * environment reads, no secrets, no side effects.
8
+ *
9
+ * STATUS (0.78.2 stabilization): this primitive is NOT wired into any live
10
+ * tool-dispatch path. It exists so 0.78.3 can wire it into
11
+ * `dispatchToolCallsByContract` (src/runtime/tool-dispatch-contracts.ts) and
12
+ * the kimi runner tool loop without re-deriving the policy. Zero behavior
13
+ * change to current execution.
14
+ *
15
+ * Design rules (authority outranks policy; fail-closed):
16
+ * 1. read ops are always allowed.
17
+ * 2. a read-only sandbox is a hard floor: any non-read op is blocked.
18
+ * 3. authority must be satisfied for the op before policy is consulted:
19
+ * write -> writeAuthority === "full"
20
+ * shell -> shellAuthority === "full"
21
+ * merge -> writeAuthority === "full" AND shellAuthority === "full"
22
+ * 4. once authority is satisfied, the approval policy decides:
23
+ * block -> block
24
+ * yolo -> allow
25
+ * auto -> allow
26
+ * interactive -> ask when a TTY is present, otherwise block
27
+ * (ask in a non-TTY context = deny-by-default).
28
+ */
29
+ import type { ProviderAuthorityLevel } from "../contracts/provider-health.js";
30
+ /** Coarse operation class used by the authority gate. */
31
+ export type ToolOp = "read" | "write" | "shell" | "merge";
32
+ /** Gate verdict for a single tool operation. */
33
+ export type ToolAuthorityDecision = "allow" | "ask" | "block";
34
+ /** Inputs to the authority decision. Fully self-contained and side-effect free. */
35
+ export interface ToolAuthorityContext {
36
+ /** Operation class derived from the tool being invoked. */
37
+ readonly op: ToolOp;
38
+ /** Provider authority for write/mutation work. */
39
+ readonly writeAuthority: ProviderAuthorityLevel;
40
+ /** Provider authority for shell/CLI work. */
41
+ readonly shellAuthority: ProviderAuthorityLevel;
42
+ /** Active approval policy for the run. */
43
+ readonly approvalPolicy: "interactive" | "auto" | "yolo" | "block";
44
+ /** Active sandbox mode; "read-only" is a hard floor for non-read ops. */
45
+ readonly sandboxMode: "read-only" | "workspace-write";
46
+ /** Whether an interactive TTY is attached (gates "interactive" -> ask). */
47
+ readonly tty: boolean;
48
+ }
49
+ /**
50
+ * Map a raw tool name to its coarse {@link ToolOp} class.
51
+ *
52
+ * Matching is case-insensitive. Unrecognized tools fail closed to the most
53
+ * restrictive sensible op (`shell` = arbitrary effect execution) rather than
54
+ * `read`, so an unknown tool is never silently treated as harmless.
55
+ */
56
+ export declare function mapToolNameToOp(toolName: string): ToolOp;
57
+ /**
58
+ * Decide allow / ask / block for a tool operation. Pure and fail-closed.
59
+ *
60
+ * @see ToolAuthorityContext for the decision inputs and ordering rules.
61
+ */
62
+ export declare function decideToolAuthority(ctx: ToolAuthorityContext): ToolAuthorityDecision;
@@ -0,0 +1,108 @@
1
+ /**
2
+ * Pure tool-authority decision primitive.
3
+ *
4
+ * Decides allow / ask / block for a tool operation given the provider's
5
+ * write/shell authority, the active approval policy, the sandbox mode, and
6
+ * whether a TTY is attached. The function is intentionally pure: no IO, no
7
+ * environment reads, no secrets, no side effects.
8
+ *
9
+ * STATUS (0.78.2 stabilization): this primitive is NOT wired into any live
10
+ * tool-dispatch path. It exists so 0.78.3 can wire it into
11
+ * `dispatchToolCallsByContract` (src/runtime/tool-dispatch-contracts.ts) and
12
+ * the kimi runner tool loop without re-deriving the policy. Zero behavior
13
+ * change to current execution.
14
+ *
15
+ * Design rules (authority outranks policy; fail-closed):
16
+ * 1. read ops are always allowed.
17
+ * 2. a read-only sandbox is a hard floor: any non-read op is blocked.
18
+ * 3. authority must be satisfied for the op before policy is consulted:
19
+ * write -> writeAuthority === "full"
20
+ * shell -> shellAuthority === "full"
21
+ * merge -> writeAuthority === "full" AND shellAuthority === "full"
22
+ * 4. once authority is satisfied, the approval policy decides:
23
+ * block -> block
24
+ * yolo -> allow
25
+ * auto -> allow
26
+ * interactive -> ask when a TTY is present, otherwise block
27
+ * (ask in a non-TTY context = deny-by-default).
28
+ */
29
+ /**
30
+ * Map a raw tool name to its coarse {@link ToolOp} class.
31
+ *
32
+ * Matching is case-insensitive. Unrecognized tools fail closed to the most
33
+ * restrictive sensible op (`shell` = arbitrary effect execution) rather than
34
+ * `read`, so an unknown tool is never silently treated as harmless.
35
+ */
36
+ export function mapToolNameToOp(toolName) {
37
+ const name = toolName.trim().toLowerCase();
38
+ // Highest-risk git operations publish or rewrite history -> merge.
39
+ const mergeSignals = ["push", "merge", "cherry-pick", "cherrypick", "rebase", "tag"];
40
+ const looksLikeGit = name.startsWith("git") || /\bgit\b/.test(name);
41
+ if (looksLikeGit && mergeSignals.some((signal) => name.includes(signal))) {
42
+ return "merge";
43
+ }
44
+ // Bare verbs used directly as tool names (e.g. "merge", "rebase").
45
+ if (mergeSignals.some((signal) => name === signal)) {
46
+ return "merge";
47
+ }
48
+ // Shell / command execution.
49
+ if (name === "shell" || name === "bash" || name.includes("shell") || name.includes("bash")) {
50
+ return "shell";
51
+ }
52
+ // Write / mutation tools.
53
+ const writeSignals = ["write", "str_replace", "strreplace", "applydiff", "apply_diff", "edit"];
54
+ if (writeSignals.some((signal) => name.includes(signal))) {
55
+ return "write";
56
+ }
57
+ // Read-only tools (exact names to avoid accidental substring matches).
58
+ const readSignals = ["read", "grep", "glob", "ls", "cat"];
59
+ if (readSignals.includes(name)) {
60
+ return "read";
61
+ }
62
+ // Unknown / unrecognized -> most restrictive sensible op (fail-closed).
63
+ return "shell";
64
+ }
65
+ /** Returns true when provider authority is sufficient for the requested op. */
66
+ function isAuthoritySatisfied(ctx) {
67
+ switch (ctx.op) {
68
+ case "read":
69
+ return true;
70
+ case "write":
71
+ return ctx.writeAuthority === "full";
72
+ case "shell":
73
+ return ctx.shellAuthority === "full";
74
+ case "merge":
75
+ return ctx.writeAuthority === "full" && ctx.shellAuthority === "full";
76
+ }
77
+ }
78
+ /**
79
+ * Decide allow / ask / block for a tool operation. Pure and fail-closed.
80
+ *
81
+ * @see ToolAuthorityContext for the decision inputs and ordering rules.
82
+ */
83
+ export function decideToolAuthority(ctx) {
84
+ // Rule 1: reads are always allowed.
85
+ if (ctx.op === "read") {
86
+ return "allow";
87
+ }
88
+ // Rule 2: a read-only sandbox is a hard floor for any non-read op.
89
+ if (ctx.sandboxMode === "read-only") {
90
+ return "block";
91
+ }
92
+ // Rule 3: authority outranks policy. Insufficient authority => block.
93
+ if (!isAuthoritySatisfied(ctx)) {
94
+ return "block";
95
+ }
96
+ // Rule 4: authority satisfied -> apply approval policy.
97
+ if (ctx.approvalPolicy === "block") {
98
+ return "block";
99
+ }
100
+ if (ctx.approvalPolicy === "yolo") {
101
+ return "allow";
102
+ }
103
+ if (ctx.approvalPolicy === "auto") {
104
+ return "allow";
105
+ }
106
+ // interactive: ask only when a TTY is attached; non-TTY ask = deny-by-default.
107
+ return ctx.tty ? "ask" : "block";
108
+ }
@@ -16,29 +16,29 @@ export declare const ProofBundleFilesSchema: z.ZodObject<{
16
16
  }, "strip", z.ZodTypeAny, {
17
17
  commands: string;
18
18
  rawPrompt: string;
19
- verifyJson: string;
19
+ limitations: string;
20
20
  decisionsJsonl: string;
21
- runManifest: string;
22
21
  evidenceJsonl: string;
23
- limitations: string;
22
+ verifyJson: string;
23
+ runManifest: string;
24
24
  stdout?: string | undefined;
25
25
  stderr?: string | undefined;
26
26
  replay?: string | undefined;
27
- diffPatch?: string | undefined;
28
27
  inspectJson?: string | undefined;
28
+ diffPatch?: string | undefined;
29
29
  }, {
30
30
  commands: string;
31
31
  rawPrompt: string;
32
- verifyJson: string;
32
+ limitations: string;
33
33
  decisionsJsonl: string;
34
- runManifest: string;
35
34
  evidenceJsonl: string;
36
- limitations: string;
35
+ verifyJson: string;
36
+ runManifest: string;
37
37
  stdout?: string | undefined;
38
38
  stderr?: string | undefined;
39
39
  replay?: string | undefined;
40
- diffPatch?: string | undefined;
41
40
  inspectJson?: string | undefined;
41
+ diffPatch?: string | undefined;
42
42
  }>;
43
43
  export declare const ProofBundleSchema: z.ZodObject<{
44
44
  schemaVersion: z.ZodLiteral<"omk.proof-bundle.v1">;
@@ -66,29 +66,29 @@ export declare const ProofBundleSchema: z.ZodObject<{
66
66
  }, "strip", z.ZodTypeAny, {
67
67
  commands: string;
68
68
  rawPrompt: string;
69
- verifyJson: string;
69
+ limitations: string;
70
70
  decisionsJsonl: string;
71
- runManifest: string;
72
71
  evidenceJsonl: string;
73
- limitations: string;
72
+ verifyJson: string;
73
+ runManifest: string;
74
74
  stdout?: string | undefined;
75
75
  stderr?: string | undefined;
76
76
  replay?: string | undefined;
77
- diffPatch?: string | undefined;
78
77
  inspectJson?: string | undefined;
78
+ diffPatch?: string | undefined;
79
79
  }, {
80
80
  commands: string;
81
81
  rawPrompt: string;
82
- verifyJson: string;
82
+ limitations: string;
83
83
  decisionsJsonl: string;
84
- runManifest: string;
85
84
  evidenceJsonl: string;
86
- limitations: string;
85
+ verifyJson: string;
86
+ runManifest: string;
87
87
  stdout?: string | undefined;
88
88
  stderr?: string | undefined;
89
89
  replay?: string | undefined;
90
- diffPatch?: string | undefined;
91
90
  inspectJson?: string | undefined;
91
+ diffPatch?: string | undefined;
92
92
  }>;
93
93
  verdict: z.ZodEnum<["passed", "failed", "partial"]>;
94
94
  knownLimitations: z.ZodArray<z.ZodString, "many">;
@@ -101,21 +101,21 @@ export declare const ProofBundleSchema: z.ZodObject<{
101
101
  files: {
102
102
  commands: string;
103
103
  rawPrompt: string;
104
- verifyJson: string;
104
+ limitations: string;
105
105
  decisionsJsonl: string;
106
- runManifest: string;
107
106
  evidenceJsonl: string;
108
- limitations: string;
107
+ verifyJson: string;
108
+ runManifest: string;
109
109
  stdout?: string | undefined;
110
110
  stderr?: string | undefined;
111
111
  replay?: string | undefined;
112
- diffPatch?: string | undefined;
113
112
  inspectJson?: string | undefined;
113
+ diffPatch?: string | undefined;
114
114
  };
115
115
  providerPolicy: string;
116
116
  omkVersion: string;
117
- runtimeVersion: "v1.2";
118
117
  proofId: string;
118
+ runtimeVersion: "v1.2";
119
119
  scenario: "no-kimi-smoke" | "evidence-block" | "fallback-route" | "dag-dependent-block" | "replay-inspect" | "example-generation" | "doctor-provider" | "native-safety" | "contract-version-smoke";
120
120
  verdict: "failed" | "partial" | "passed";
121
121
  knownLimitations: string[];
@@ -128,21 +128,21 @@ export declare const ProofBundleSchema: z.ZodObject<{
128
128
  files: {
129
129
  commands: string;
130
130
  rawPrompt: string;
131
- verifyJson: string;
131
+ limitations: string;
132
132
  decisionsJsonl: string;
133
- runManifest: string;
134
133
  evidenceJsonl: string;
135
- limitations: string;
134
+ verifyJson: string;
135
+ runManifest: string;
136
136
  stdout?: string | undefined;
137
137
  stderr?: string | undefined;
138
138
  replay?: string | undefined;
139
- diffPatch?: string | undefined;
140
139
  inspectJson?: string | undefined;
140
+ diffPatch?: string | undefined;
141
141
  };
142
142
  providerPolicy: string;
143
143
  omkVersion: string;
144
- runtimeVersion: "v1.2";
145
144
  proofId: string;
145
+ runtimeVersion: "v1.2";
146
146
  scenario: "no-kimi-smoke" | "evidence-block" | "fallback-route" | "dag-dependent-block" | "replay-inspect" | "example-generation" | "doctor-provider" | "native-safety" | "contract-version-smoke";
147
147
  verdict: "failed" | "partial" | "passed";
148
148
  knownLimitations: string[];
@@ -47,16 +47,16 @@ export declare const ProviderCapabilitySchema: z.ZodObject<{
47
47
  cli: boolean;
48
48
  api: boolean;
49
49
  mcp: boolean;
50
- streaming: boolean;
51
50
  tools: boolean;
51
+ streaming: boolean;
52
52
  screenshots: boolean;
53
53
  worktreeSafe: boolean;
54
54
  }, {
55
55
  cli: boolean;
56
56
  api: boolean;
57
57
  mcp: boolean;
58
- streaming: boolean;
59
58
  tools: boolean;
59
+ streaming: boolean;
60
60
  screenshots: boolean;
61
61
  worktreeSafe: boolean;
62
62
  }>;
@@ -102,8 +102,8 @@ export declare const ProviderCapabilitySchema: z.ZodObject<{
102
102
  cli: boolean;
103
103
  api: boolean;
104
104
  mcp: boolean;
105
- streaming: boolean;
106
105
  tools: boolean;
106
+ streaming: boolean;
107
107
  screenshots: boolean;
108
108
  worktreeSafe: boolean;
109
109
  };
@@ -130,8 +130,8 @@ export declare const ProviderCapabilitySchema: z.ZodObject<{
130
130
  cli: boolean;
131
131
  api: boolean;
132
132
  mcp: boolean;
133
- streaming: boolean;
134
133
  tools: boolean;
134
+ streaming: boolean;
135
135
  screenshots: boolean;
136
136
  worktreeSafe: boolean;
137
137
  };
@@ -0,0 +1,49 @@
1
+ /**
2
+ * Cross-platform clipboard image reader.
3
+ *
4
+ * Wraps the platform-specific clipboard reading from screenshot-store patterns
5
+ * into a reusable utility for the chat REPL, goal commands, and any input
6
+ * surface that needs Ctrl+V / paste image support.
7
+ *
8
+ * Platforms:
9
+ * - macOS: `pngpaste -` (brew) or `osascript` with TIFF→PNG conversion
10
+ * - Linux: `xclip -selection clipboard -target image/png`
11
+ * - Windows: PowerShell System.Windows.Forms.Clipboard
12
+ *
13
+ * Output: PNG Buffer + saved file path under .omk/screenshots/
14
+ */
15
+ export declare const SCREENSHOT_DIR = ".omk/screenshots";
16
+ export declare const MAX_IMAGE_BYTES: number;
17
+ export interface ClipboardImage {
18
+ ok: boolean;
19
+ /** Absolute path to the saved PNG/JPG/WebP/GIF file. */
20
+ path?: string;
21
+ /** Project-relative path (e.g. .omk/screenshots/2026-06-08/screenshot-....png). */
22
+ relativePath?: string;
23
+ /** Base64 data URI suitable for wire protocol image_url. */
24
+ dataUri?: string;
25
+ /** Base64 raw (no prefix). */
26
+ base64?: string;
27
+ /** Detected extension: png, jpg, webp, gif. */
28
+ ext?: string;
29
+ /** Error message when ok=false. */
30
+ error?: string;
31
+ }
32
+ export declare function detectImageExt(buf: Buffer): string | null;
33
+ export declare function toDataUri(base64: string, ext: string): string;
34
+ /**
35
+ * Read an image from the system clipboard. Returns null if clipboard is empty
36
+ * or contains no image. Platform-specific: macOS (pngpaste/osascript), Linux
37
+ * (xclip/wl-paste), Windows (PowerShell).
38
+ */
39
+ export declare function readClipboardImage(platform?: NodeJS.Platform): Buffer | null;
40
+ /**
41
+ * Read clipboard image, validate, save to .omk/screenshots/, and return
42
+ * both the file path and base64 data URI for wire protocol use.
43
+ */
44
+ export declare function pasteClipboardImage(projectRoot: string): ClipboardImage;
45
+ /**
46
+ * Read an image file from disk, validate, and return base64 data URI.
47
+ * Used for --image <file> flag support.
48
+ */
49
+ export declare function readImageFile(filePath: string): ClipboardImage;