@mcp-com-ai/plugin-capability-graph 0.0.0-stage → 1.3.0
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/LICENSE +92 -0
- package/README.md +443 -2
- package/dist/canonical.d.ts +9 -0
- package/dist/classifier.d.ts +11 -0
- package/dist/commands.d.ts +9 -0
- package/dist/compiler.d.ts +9 -0
- package/dist/evaluation.d.ts +24 -0
- package/dist/execution-digests.d.ts +7 -0
- package/dist/execution-envelope.d.ts +19 -0
- package/dist/execution-preflight.d.ts +38 -0
- package/dist/executor.d.ts +21 -0
- package/dist/extensions.d.ts +100 -0
- package/dist/fact-audit.d.ts +34 -0
- package/dist/fact-closure.d.ts +41 -0
- package/dist/graphml.d.ts +2 -0
- package/dist/index.d.ts +6 -0
- package/dist/index.js +315 -0
- package/dist/json-schema.d.ts +6 -0
- package/dist/openapi-document.d.ts +9 -0
- package/dist/planner.d.ts +14 -0
- package/dist/planning-gates.d.ts +10 -0
- package/dist/response-outcomes.d.ts +6 -0
- package/dist/runtime.d.ts +15 -0
- package/dist/runtime.js +5 -0
- package/dist/triggers.d.ts +15 -0
- package/dist/visualization-api.d.ts +3 -0
- package/dist/visualization-api.js +163 -0
- package/dist/visualization-assets.d.ts +2 -0
- package/dist/visualization-flow-cards.d.ts +26 -0
- package/dist/visualization-renderer.d.ts +2 -0
- package/dist/visualization-shared.d.ts +7 -0
- package/dist/visualization-types.d.ts +343 -0
- package/dist/visualization.d.ts +3 -0
- package/package.json +66 -4
|
@@ -0,0 +1,6 @@
|
|
|
1
|
+
export interface CapabilityJsonSchemaError {
|
|
2
|
+
readonly instancePath: string;
|
|
3
|
+
readonly keyword: string;
|
|
4
|
+
}
|
|
5
|
+
/** Browser-safe JSON Schema subset used for guarded preflight validation. */
|
|
6
|
+
export declare function validateCapabilityJsonSchema(schema: unknown, value: unknown): readonly CapabilityJsonSchemaError[];
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
/** Small, dependency-free helpers for reading an OpenAPI document. */
|
|
2
|
+
export type JsonObject = Record<string, unknown>;
|
|
3
|
+
export declare const HTTP_METHODS: readonly ["delete", "get", "head", "options", "patch", "post", "put", "trace"];
|
|
4
|
+
export declare function isRecord(value: unknown): value is JsonObject;
|
|
5
|
+
export declare function readNonEmptyString(value: unknown): string | undefined;
|
|
6
|
+
export declare function escapePointer(value: string): string;
|
|
7
|
+
export declare function unescapePointer(value: string): string;
|
|
8
|
+
/** Resolve a local `#/...` reference, returning the input when unresolvable. */
|
|
9
|
+
export declare function resolveLocalComponent(document: JsonObject, value: unknown): unknown;
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
import type { CapabilityGraphPlannerV1, CapabilityGraphPlanningRequestV1, CapabilityGraphPlanningResultV1, PlanningFactV1 } from "@mcp-com-ai/core";
|
|
2
|
+
export declare const DEFAULT_PLANNING_BOUNDS: Readonly<{
|
|
3
|
+
maxDepth: 12;
|
|
4
|
+
maxStates: 2000;
|
|
5
|
+
maxFrontier: 1000;
|
|
6
|
+
maxExpansionsPerState: 100;
|
|
7
|
+
}>;
|
|
8
|
+
export declare class DeterministicCapabilityGraphPlanner implements CapabilityGraphPlannerV1 {
|
|
9
|
+
readonly id = "deterministic-planner-v1";
|
|
10
|
+
plan(request: CapabilityGraphPlanningRequestV1): Promise<CapabilityGraphPlanningResultV1>;
|
|
11
|
+
}
|
|
12
|
+
export declare function normalizePlanningFacts(facts: readonly PlanningFactV1[]): readonly PlanningFactV1[];
|
|
13
|
+
export declare function planningStateDigest(facts: readonly PlanningFactV1[]): Promise<string>;
|
|
14
|
+
export declare function planningPlanDigest(graphFingerprint: string, initialFacts: readonly PlanningFactV1[], goalFacts: readonly PlanningFactV1[], transitionIds: readonly string[]): Promise<string>;
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
import type { CapabilityGraphPlanningGateV1 } from "@mcp-com-ai/core";
|
|
2
|
+
/**
|
|
3
|
+
* Whether a plan step gate is satisfied by a planning request.
|
|
4
|
+
*
|
|
5
|
+
* Shared by the planner and offline projections so both apply one rule:
|
|
6
|
+
* authorization is satisfied by any supplied principal (eligibility was
|
|
7
|
+
* already filtered), and every other gate by its code or by a
|
|
8
|
+
* transition-scoped `<transitionId>:<code>` entry.
|
|
9
|
+
*/
|
|
10
|
+
export declare function isPlanningGateSatisfied(gate: CapabilityGraphPlanningGateV1, transitionId: string, satisfiedGates: ReadonlySet<string>, principalSupplied: boolean): boolean;
|
|
@@ -0,0 +1,6 @@
|
|
|
1
|
+
import type { CapabilityGraphPlanningOutcomeV1 } from "@mcp-com-ai/core";
|
|
2
|
+
/**
|
|
3
|
+
* Find the declared outcome for an HTTP status: exact code first, then the
|
|
4
|
+
* `NXX` range, then `default`. Returns undefined when nothing matches.
|
|
5
|
+
*/
|
|
6
|
+
export declare function matchDeclaredOutcome(outcomes: readonly CapabilityGraphPlanningOutcomeV1[] | undefined, status: number | undefined): CapabilityGraphPlanningOutcomeV1 | undefined;
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
import type { CapabilityGraphClassifierFactoryV1, CapabilityGraphRuntimeProvider } from "@mcp-com-ai/core";
|
|
2
|
+
export declare const capabilityGraphRuntimeProvider: CapabilityGraphRuntimeProvider;
|
|
3
|
+
export declare const deterministicCapabilityGraphClassifierFactory: CapabilityGraphClassifierFactoryV1;
|
|
4
|
+
export { CapabilityGraphCompilationError, compileCapabilityGraph, type CompileCapabilityGraphOptions, } from "./compiler";
|
|
5
|
+
export { HAPI_PLANNING_EXTENSION_KEY, HAPI_PLANNING_EXTENSION_SCHEMA_V1, parsePlanningExtensionV1, type ParsedPlanningExtensionV1, } from "./extensions";
|
|
6
|
+
export { canonicalizeJson, canonicalSchemaStringify, canonicalStringify, hashCanonicalSchema, serializeCapabilityGraph, sha256, } from "./canonical";
|
|
7
|
+
export { DeterministicCapabilityGraphClassifier, isOperationAuthorized, type CapabilityGraphPrincipalContext, } from "./classifier";
|
|
8
|
+
export { serializeCapabilityGraphMl } from "./graphml";
|
|
9
|
+
export { DEFAULT_PLANNING_BOUNDS, DeterministicCapabilityGraphPlanner, normalizePlanningFacts, planningPlanDigest, planningStateDigest, } from "./planner";
|
|
10
|
+
export { capabilityExecutionArgumentDigest, capabilityExecutionConfirmationBinding, capabilityExecutionEnvelopeDigest, capabilityExecutionMutationSet, capabilityExecutionMutationSetDigest, capabilityExecutionPrincipalDigest, } from "./execution-digests";
|
|
11
|
+
export { validateCapabilityExecutionConfirmations, validateCapabilityExecutionEnvelope, type CapabilityExecutionConfirmationPolicy, type ValidatedCapabilityExecutionEnvelope, } from "./execution-envelope";
|
|
12
|
+
export { preflightCapabilityExecutionStep, validateCapabilityExecutionResult, type CapabilityExecutionInvocationResult, type CapabilityExecutionPreflightDependencies, type CapabilityExecutionPreflightResult, type CapabilityExecutionStateResult, } from "./execution-preflight";
|
|
13
|
+
export { CAPABILITY_EXECUTION_SAFETY_CEILINGS, DEFAULT_CAPABILITY_EXECUTION_LIMITS, GuardedCapabilityExecutor, createGuardedCapabilityExecutorFactory, type GuardedCapabilityExecutorOptions, } from "./executor";
|
|
14
|
+
export { validateCapabilityJsonSchema, type CapabilityJsonSchemaError, } from "./json-schema";
|
|
15
|
+
export { classifyEvaluationStatus, evaluateCapabilityGraph, type CapabilityGraphEvaluationCase, type CapabilityGraphEvaluationFixture, type CapabilityGraphEvaluationResult, type CapabilityGraphEvaluationStatus, } from "./evaluation";
|
package/dist/runtime.js
ADDED
|
@@ -0,0 +1,5 @@
|
|
|
1
|
+
// @bun
|
|
2
|
+
var Vt=new Set(["a","an","and","as","at","be","by","for","from","in","it","of","on","or","the","them","this","to","user","without"]);class B{id="deterministic-v1";async classify(n){Mn(n.signal);let t=[],i=n.query.trim();if(!i)return{outcome:"no-match",matches:[],diagnostics:t};if(i.length>2000)return{outcome:"no-match",matches:[],diagnostics:[{code:"query-too-long",severity:"error",message:"Capability graph queries are limited to 2000 characters"}]};let e=new Map(n.graph.operations.map((p)=>[p.id,p])),a=new Map(n.graph.capabilities.map((p)=>[p.id,p.label])),o=n.mode==="regex"?vt(i,t):void 0;if(n.mode==="regex"&&!o)return{outcome:"no-match",matches:[],diagnostics:t};let r=[];for(let p of n.candidates){Mn(n.signal);let l=e.get(p.operationId);if(!l||!N(l,n.principal))continue;let u=o?Gt(o,p.toolName,l,a):wt(i,p.toolName,l,a);if(u.score<=0)continue;r.push({toolName:p.toolName,operationId:l.id,score:u.score,reason:u.reason})}r.sort(Ot);let s=St(n.limit),c=r.slice(0,s);return{outcome:c.length>0?"ranked":"no-match",matches:c,diagnostics:t}}}function N(n,t){if(n.authorization.length===0)return!0;if(!Dt(t))return t===void 0;if(t.authorizedOperationIds)return t.authorizedOperationIds.includes(n.id);let i=new Set(t.scopes??[]),e=t.schemes??{};return n.authorization.some((a)=>a.schemes.every((o)=>{let r=e[o.scheme];if(r){let s=new Set(r);return o.scopes.every((c)=>s.has(c))}return o.scopes.length>0&&o.scopes.every((s)=>i.has(s))}))}function wt(n,t,i,e){let a=ln(n),o=_n(t,i,e),r=0,s=[];for(let c of o.positive){let p=jn(a,ln(c.text));if(p===0)continue;r+=p*c.weight,s.push(c.label)}for(let c of i.avoidWhen){let p=jn(a,ln(c));if(p>0)r-=p*100,s.push("avoid-when penalty")}return{score:$t(r),reason:[...new Set(s)].join(", ")||"no lexical overlap"}}function Gt(n,t,i,e){let a=_n(t,i,e).positive.map((o)=>o.text).join(" ");return n.lastIndex=0,n.test(a)?{score:1,reason:"regex match"}:{score:0,reason:"no regex match"}}function _n(n,t,i){let e=t.capabilityIds.flatMap((s)=>[s,i.get(s)??""]).join(" "),a=t.inputs.flatMap((s)=>[s.name,s.description??""]).join(" "),o=t.outputs.flatMap((s)=>[s.description??"",...s.fields]).join(" "),r=t.bodyVariants.map((s)=>`${s.title??""} ${JSON.stringify(s.schema)}`).join(" ");return{positive:[{text:`${n} ${t.id} ${t.sourceOperationId??""}`,weight:8,label:"operation identity"},{text:e,weight:6,label:"capability taxonomy"},{text:t.purpose,weight:5,label:"purpose"},{text:t.useWhen.join(" "),weight:5,label:"use-when"},{text:a,weight:2,label:"inputs"},{text:r,weight:5,label:"body variants"},{text:o,weight:2,label:"outputs"},{text:t.prerequisites.join(" "),weight:1,label:"prerequisites"}]}}function ln(n){let i=n.replace(/([a-z\d])([A-Z])/g,"$1 $2").toLowerCase().match(/[\p{L}\p{N}]+/gu)??[];return new Set(i.map(kt).filter((e)=>e.length>1&&!Vt.has(e)))}function kt(n){if(n.length>5&&n.endsWith("ing")){let t=n.slice(0,-3);return t.endsWith("s")?`${t}e`:t}if(n.length>4&&n.endsWith("ed"))return n.slice(0,-2);if(n.length>3&&n.endsWith("s"))return n.slice(0,-1);return n}function jn(n,t){let i=0;for(let e of n)if(t.has(e))i++;return i}function vt(n,t){try{return new RegExp(n,"iu")}catch{t.push({code:"invalid-regex",severity:"error",message:`Invalid capability graph regex: ${n}`});return}}function St(n){if(!Number.isFinite(n))return 5;return Math.min(50,Math.max(1,Math.floor(n)))}function Ot(n,t){return t.score-n.score||n.operationId.localeCompare(t.operationId)||n.toolName.localeCompare(t.toolName)}function $t(n){return Math.round(n*1000)/1000}function Mn(n){if(!n?.aborted)return;if(typeof n.throwIfAborted==="function")n.throwIfAborted();throw new DOMException("Capability graph classification aborted","AbortError")}function Dt(n){return Boolean(n&&typeof n==="object"&&!Array.isArray(n))}var fn="x-hapi-planning",At=Object.freeze({type:"object",additionalProperties:!1,required:["produces"],properties:{requires:{type:"array",items:{$ref:"#/$defs/fact"}},produces:{type:"array",minItems:1,items:{$ref:"#/$defs/fact"}},removes:{type:"array",items:{$ref:"#/$defs/fact"}},cost:{type:"number",minimum:0}},$defs:{fact:{type:"object",additionalProperties:!1,required:["predicate"],properties:{predicate:{type:"string",pattern:"^[a-z][a-z0-9]*(?:[._-][a-z0-9]+)*$"},value:{}}}}}),Rt=new Set(["read","create","update","delete","action"]),Jn=["side-effecting","destructive","idempotent","requires-confirmation"];function zn(n,t,i,e){return{capabilities:Ft(n,t,i,e),intent:Nt(n,t,i,e),effects:jt(n,t,i,e),prerequisites:Mt(n,t,i,e),planning:Bn(n,t,i,e)}}function Bn(n,t,i,e){if(!("x-hapi-planning"in n))return;let o=n["x-hapi-planning"],r=`${t}/x-hapi-planning`;if(!T(o)){C(e,i,r,"invalid-planning","x-hapi-planning must be an object");return}let s=new Set(["requires","produces","removes","cost"]),c=Object.keys(o).filter((b)=>!s.has(b));if(c.length>0){C(e,i,r,"invalid-planning-field",`x-hapi-planning contains unknown field${c.length===1?"":"s"}: ${c.sort().join(", ")}`);return}let p=I(o.requires??[],`${r}/requires`,i,e),l=I(o.produces,`${r}/produces`,i,e),u=I(o.removes??[],`${r}/removes`,i,e),y=o.cost??1;if(!Array.isArray(o.produces)||o.produces.length===0)C(e,i,`${r}/produces`,"invalid-planning-produces","x-hapi-planning.produces must be a non-empty array of canonical facts");if(typeof y!=="number"||!Number.isFinite(y)||y<0)C(e,i,`${r}/cost`,"invalid-planning-cost","x-hapi-planning.cost must be a finite nonnegative number");if(!p||!l||!u||typeof y!=="number")return;let f=new Set(l.map(v));if(u.filter((b)=>f.has(v(b))).length>0){C(e,i,r,"conflicting-planning-fact","x-hapi-planning cannot produce and remove the same fact");return}if(!Number.isFinite(y)||y<0||l.length===0)return;return{requires:p,produces:l,removes:u,cost:y}}var M="x-hapi-outcome";function Tt(n){return/^2(?:\d\d|xx)$/i.test(n)}function Hn(n,t,i,e,a){let o=M;if(Tt(i)){C(a,e,t,"outcome-on-success-response",`${o} cannot be declared on success response ${i}; use x-hapi-planning`);return}if(!T(n)){C(a,e,t,"invalid-outcome",`${o} must be an object`);return}let r=Object.keys(n).filter((l)=>l!=="produces"&&l!=="removes");if(r.length>0){C(a,e,t,"invalid-outcome-field",`${o} contains unknown field${r.length===1?"":"s"}: ${r.sort().join(", ")}`);return}let s=I(n.produces??[],`${t}/produces`,e,a),c=I(n.removes??[],`${t}/removes`,e,a);if(!s||!c)return;if(s.length===0&&c.length===0){C(a,e,t,"empty-outcome",`${o} must produce or remove at least one fact`);return}let p=new Set(s.map(v));if(c.some((l)=>p.has(v(l)))){C(a,e,t,"conflicting-outcome-fact",`${o} cannot produce and remove the same fact`);return}return{produces:s,removes:c}}var Z="x-hapi-client-facts";function Wn(n,t){let i=Z,e=`/${i}`;if(!Array.isArray(n)){t.push({code:"invalid-client-facts",severity:"error",message:`${i} must be an array of facts`,pointer:e});return}let a=[],o=new Set;for(let[r,s]of n.entries()){let c=`${e}/${r}`,p=(P,x)=>t.push({code:P,severity:"error",message:x,pointer:c});if(!T(s)){p("invalid-client-fact","A client fact must be an object");continue}let l=Object.keys(s).filter((P)=>!["predicate","value","description"].includes(P));if(l.length){p("invalid-client-fact-field",`A client fact contains unknown field${l.length===1?"":"s"}: ${l.sort().join(", ")}`);continue}if(s.description!==void 0&&(typeof s.description!=="string"||s.description.trim()==="")){p("invalid-client-fact-description","description must be a non-empty string");continue}let{description:u,...y}=s,d=I([y],c,"document",t)?.[0];if(!d)continue;let b=v(d);if(o.has(b)){p("duplicate-client-fact","Client facts cannot contain duplicates");continue}o.add(b),a.push({fact:d,...typeof u==="string"?{description:u.trim()}:{},pointer:c})}return a.sort((r,s)=>v(r.fact).localeCompare(v(s.fact)))}var R="x-hapi-event";function Un(n,t,i,e){let a=R;if(!T(n)){C(e,i,t,"invalid-event",`${a} must be an object`);return}let o=Object.keys(n).filter((r)=>r!=="produces");if(o.length>0){C(e,i,t,"invalid-event-field",`${a} contains unknown field${o.length===1?"":"s"}: ${o.sort().join(", ")}`);return}if(!Array.isArray(n.produces)||n.produces.length===0){C(e,i,`${t}/produces`,"invalid-event-produces",`${a}.produces must be a non-empty array of canonical facts`);return}return I(n.produces,`${t}/produces`,i,e)}function I(n,t,i,e){if(!Array.isArray(n)){C(e,i,t,"invalid-planning-facts","Planning facts must be an array");return}let a=[];for(let[r,s]of n.entries()){let c=`${t}/${r}`;if(!T(s)||Object.keys(s).some((p)=>p!=="predicate"&&p!=="value")||typeof s.predicate!=="string"||!It.test(s.predicate)||Object.hasOwn(s,"value")&&!dn(s.value)){C(e,i,c,"invalid-planning-fact","A planning fact requires a canonical lowercase predicate and optional JSON-safe value");continue}a.push({predicate:s.predicate,...Object.hasOwn(s,"value")?{value:s.value}:{}})}if(a.length!==n.length)return;let o=a.map(v);if(new Set(o).size!==o.length){C(e,i,t,"duplicate-planning-fact","Planning fact arrays cannot contain duplicates");return}return a.sort((r,s)=>v(r).localeCompare(v(s)))}var It=/^[a-z][a-z0-9]*(?:[._-][a-z0-9]+)*$/;function v(n){return`${n.predicate}:${un(n.value??null)}`}function un(n){if(Array.isArray(n))return`[${n.map(un).join(",")}]`;if(T(n))return`{${Object.keys(n).sort().map((t)=>`${JSON.stringify(t)}:${un(n[t])}`).join(",")}}`;return JSON.stringify(n)}function dn(n,t=new Set){if(n===null||typeof n==="string"||typeof n==="boolean")return!0;if(typeof n==="number")return Number.isFinite(n);if(!n||typeof n!=="object"||t.has(n))return!1;let i=new Set(t).add(n);if(Array.isArray(n))return n.every((e)=>dn(e,i));if(Object.getPrototypeOf(n)!==Object.prototype)return!1;return Object.values(n).every((e)=>dn(e,i))}function Ft(n,t,i,e){if(!("x-hapi-capability"in n))return;let o=n["x-hapi-capability"],r=typeof o==="string"?[o]:o;if(!_t(r)){C(e,i,`${t}/x-hapi-capability`,"invalid-capability","x-hapi-capability must be a non-empty string or array of non-empty strings");return}return Q(r.map((s)=>s.trim()))}function Nt(n,t,i,e){if(!("x-hapi-intent"in n))return;let o=n["x-hapi-intent"];if(!T(o)){C(e,i,`${t}/x-hapi-intent`,"invalid-intent","x-hapi-intent must be an object");return}let r=Object.keys(o).filter((p)=>!["use-when","avoid-when"].includes(p)),s=o["use-when"]??[],c=o["avoid-when"]??[];if(r.length>0||!Y(s)||!Y(c)){C(e,i,`${t}/x-hapi-intent`,"invalid-intent","x-hapi-intent accepts only use-when and avoid-when arrays of non-empty strings");return}return{useWhen:Q(s.map((p)=>p.trim())),avoidWhen:Q(c.map((p)=>p.trim()))}}function jt(n,t,i,e){if(!("x-hapi-effects"in n))return;let o=n["x-hapi-effects"];if(!T(o)){C(e,i,`${t}/x-hapi-effects`,"invalid-effects","x-hapi-effects must be an object");return}let r=new Set(["mode",...Jn]),s=o.mode,c=Jn.find((l)=>o[l]!==void 0&&typeof o[l]!=="boolean");if(typeof s!=="string"||!Rt.has(s)||c||Object.keys(o).some((l)=>!r.has(l))){C(e,i,`${t}/x-hapi-effects`,"invalid-effects","x-hapi-effects requires a valid mode and accepts only boolean effect flags");return}let p=j(s);return{mode:s,sideEffecting:Ln(o,"side-effecting",p.sideEffecting),destructive:Ln(o,"destructive",p.destructive),idempotent:qn(o,"idempotent",p.idempotent),requiresConfirmation:qn(o,"requires-confirmation",p.requiresConfirmation)}}function Mt(n,t,i,e){if(!("x-hapi-prerequisites"in n))return;let o=n["x-hapi-prerequisites"];if(!Y(o)){C(e,i,`${t}/x-hapi-prerequisites`,"invalid-prerequisites","x-hapi-prerequisites must be an array of non-empty strings");return}return Q(o.map((r)=>r.trim()))}function Xn(n){let t=n.toLowerCase();if(["get","head","options"].includes(t))return j("read");if(t==="post")return j("create");if(t==="delete")return j("delete");if(["put","patch"].includes(t))return{...j("update"),idempotent:t==="put"};return j("action")}function j(n){let t=n==="read",i=n==="delete";return{mode:n,sideEffecting:!t,destructive:i,idempotent:t||n==="delete",requiresConfirmation:i}}function C(n,t,i,e,a){n.push({code:e,severity:"error",message:a,pointer:i,operationId:t})}function Ln(n,t,i){return typeof n[t]==="boolean"?n[t]:i}function qn(n,t,i){return typeof n[t]==="boolean"?n[t]:i}function T(n){return Boolean(n&&typeof n==="object"&&!Array.isArray(n))}function Y(n){return Array.isArray(n)&&n.every((t)=>typeof t==="string"&&t.trim()!=="")}function _t(n){return Y(n)&&n.length>0}function Q(n){return[...new Set(n)].sort((t,i)=>t.localeCompare(i))}var nn=["delete","get","head","options","patch","post","put","trace"];function g(n){return Boolean(n&&typeof n==="object"&&!Array.isArray(n))}function m(n){return typeof n==="string"&&n.trim()!==""?n.trim():void 0}function D(n){return n.replace(/~/g,"~0").replace(/\//g,"~1")}function yn(n){return n.replace(/~1/g,"/").replace(/~0/g,"~")}function V(n,t){if(!g(t)||typeof t.$ref!=="string"||!t.$ref.startsWith("#/"))return t;let i=n;for(let e of t.$ref.slice(2).split("/").map(yn)){if(!g(i))return t;i=i[e]}return i??t}function Yn(n,t,i){let e=[],a=n.webhooks;if(g(a))for(let o of Object.keys(a).sort()){let r=V(n,a[o]),s=`/webhooks/${D(o)}`;if(!g(r)){gn(i,s);continue}e.push(...Kn(r,s,i,(c)=>({id:`webhook:${o}:${c}`,kind:"webhook",name:o})))}for(let o of t){let r=o.operation.callbacks;if(!g(r))continue;for(let s of Object.keys(r).sort()){let c=V(n,r[s]),p=`${o.pointer}/callbacks/${D(s)}`;if(!g(c)){gn(i,p);continue}for(let l of Object.keys(c).sort()){if(l.startsWith("x-"))continue;let u=V(n,c[l]),y=`${p}/${D(l)}`;if(!g(u)){gn(i,y);continue}e.push(...Kn(u,y,i,(f)=>({id:`callback:${o.id}:${s}:${f}`,kind:"callback",name:s,expression:l,operationId:o.id})))}}}return e.sort((o,r)=>o.id.localeCompare(r.id))}function Qn(n,t){if(!(R in n.operation))return;t.push({code:"event-on-path-operation",severity:"warning",message:`${R} applies only to webhook and callback operations and is ignored here`,pointer:`${n.pointer}/${R}`,operationId:n.id})}function Kn(n,t,i,e){let a=[];for(let o of nn){let r=n[o];if(!g(r))continue;let s=e(o),c=`${t}/${o}`,p=[];if(R in r){let l=Un(r[R],`${c}/${R}`,s.id,i);if(!l)continue;p=l}a.push({...s,method:o,purpose:m(r.summary)??m(r.description)??s.name,produces:p,provenance:{kind:"document",pointer:c}})}return a}function gn(n,t){n.push({code:"unresolved-trigger",severity:"warning",message:"Webhook or callback could not be resolved and is skipped",pointer:t})}var Jt=new Set(["allOf","anyOf","enum","oneOf","required"]);function bn(n,t={}){return mn(n,t.schema===!0,new WeakSet,void 0)}function h(n){return JSON.stringify(bn(n))}function H(n){return JSON.stringify(bn(n,{schema:!0}))}async function S(n){let t=new TextEncoder().encode(n),i=await crypto.subtle.digest("SHA-256",t);return[...new Uint8Array(i)].map((e)=>e.toString(16).padStart(2,"0")).join("")}async function hn(n){return S(H(n))}function Lt(n){return`${h(n)}
|
|
3
|
+
`}function mn(n,t,i,e){if(n===null||typeof n==="string"||typeof n==="boolean")return n;if(typeof n==="number")return Number.isFinite(n)?n:null;if(Array.isArray(n)){let o=n.map((r)=>mn(r,t,i,e));if(t&&e&&Jt.has(e))return o.sort(qt);return o}if(!n||typeof n!=="object")return String(n);if(i.has(n))throw TypeError("Cannot canonicalize a cyclic object; use document references instead");i.add(n);let a={};for(let o of Object.keys(n).sort()){let r=n[o];if(r!==void 0)a[o]=mn(r,t,i,o)}return i.delete(n),a}function qt(n,t){return JSON.stringify(n).localeCompare(JSON.stringify(t))}class tn extends Error{diagnostics;constructor(n){let t=n.filter((i)=>i.severity==="error").length;super(`Capability graph compilation failed with ${t} error${t===1?"":"s"}`);this.diagnostics=n;this.name="CapabilityGraphCompilationError"}}async function wn(n,t={}){let i=[],e=zt(n,i);if(!e)throw new tn(xn(i));let a=Bt(e,i);await Ht(a);for(let x of a)x.extensions=zn(x.operation,x.pointer,x.id,i),x.outcomes=oi(e,x,i),Qn(x,i);let o=Yn(e,a,i),r=Z in e?Wn(e[Z],i):void 0;if(it(i))throw new tn(xn(i));let s=new Map,c=[];for(let x of a){let z=Wt(e,x);for(let O of z)if(!s.has(O.node.id))s.set(O.node.id,O.node);c.push(await Ut(e,x,z))}let p=[...s.values()].sort(Vn);c.sort(Vn);let l=ni(e,a,c,i),u=si(a,c,l),y=ri(r,u,i),f=ui(e,t.source),d=xn(i),b={schemaVersion:"1",source:f,capabilities:p,operations:c,edges:l,...u?{planning:u}:{},...o.length?{triggers:o}:{},...y?.length?{clientFacts:y}:{},diagnostics:d},P=await di(b);return et({...b,fingerprint:P})}function zt(n,t){if(!g(n)){t.push(En("invalid-document","OpenAPI document root must be an object",""));return}if(typeof n.openapi!=="string"||!n.openapi.startsWith("3."))t.push(En("unsupported-openapi-version","Capability graphs require an OpenAPI 3.x document","/openapi"));if(!g(n.paths))t.push(En("invalid-paths","OpenAPI document paths must be an object","/paths"));return it(t)?void 0:n}function Bt(n,t){let i=n.paths,e=[];for(let a of Object.keys(i).sort()){let o=i[a];if(!g(o))continue;for(let r of nn){let s=o[r];if(!g(s))continue;let c=`/paths/${D(a)}/${r}`,p=m(s.operationId);if(s.operationId!==void 0&&!p)t.push({code:"invalid-operation-id",severity:"warning",message:"operationId is not a non-empty string; a stable identity was inferred",pointer:`${c}/operationId`});let l=p?_(p):_(`${r}-${a}`);e.push({path:a,method:r,pointer:c,pathItem:o,operation:s,sourceOperationId:p,baseId:l,id:l})}}return e}async function Ht(n){let t=new Map;for(let i of n){let e=t.get(i.baseId)??[];e.push(i),t.set(i.baseId,e)}for(let i of t.values()){if(i.length===1)continue;let e=new Map;for(let a of i.sort(Ci)){let o=_(`${a.method}-${a.path}`),r=e.get(o)??[];r.push(a),e.set(o,r)}for(let[a,o]of e)for(let r of o){let s=o.length>1?`-${(await S(`${r.method}:${r.path}`)).slice(0,12)}`:"";r.id=`${r.baseId}--${a}${s}`}}}function Wt(n,t){let i=t.extensions?.capabilities,e=Array.isArray(t.operation.tags)?t.operation.tags.filter((c)=>typeof c==="string"&&c.trim()!==""):[],a=i&&i.length>0?i:e.length>0?[...new Set(e.map((c)=>c.trim()))].sort():[gi(t.path)],o=i?{kind:"extension",pointer:`${t.pointer}/x-hapi-capability`}:e.length>0?{kind:"document",pointer:`${t.pointer}/tags`}:{kind:"inferred",pointer:t.pointer,detail:"first static path segment"},r=fi(n),s=new Map;for(let c of a){let p=yi(c),l=p.map(mi).join(".")||"root";s.set(l,{provenance:o,node:{id:l,label:c,path:p,description:r.get(c),provenance:o}})}return[...s.values()].sort((c,p)=>c.node.id.localeCompare(p.node.id))}async function Ut(n,t,i){let e=m(t.operation.summary)??m(t.operation.description)??t.id,a=t.extensions?.intent??{useWhen:[e],avoidWhen:[]},o=Xt(n,t),r=V(n,t.operation.requestBody),s=await Yt(r),c=Kt(o,r),p=t.extensions?.prerequisites??li(c,Boolean(g(r)&&r.required===!0)),l=t.extensions?.effects,u=Object.hasOwn(t.operation,"security")?`${t.pointer}/security`:"/security";return{id:t.id,...t.sourceOperationId?{sourceOperationId:t.sourceOperationId}:{},capabilityIds:i.map((y)=>y.node.id),purpose:e,useWhen:a.useWhen,avoidWhen:a.avoidWhen,transport:{kind:"http",method:t.method.toUpperCase(),path:t.path},inputs:c,bodyVariants:s,outputs:Qt(n,t.operation.responses),effects:l??Xn(t.method),authorization:Zt(n,t.operation),prerequisites:p,provenance:{identity:t.sourceOperationId?{kind:"document",pointer:`${t.pointer}/operationId`}:{kind:"inferred",pointer:t.pointer,detail:"HTTP method and path"},capabilities:i[0]?.provenance,purpose:m(t.operation.summary)?{kind:"document",pointer:`${t.pointer}/summary`}:m(t.operation.description)?{kind:"document",pointer:`${t.pointer}/description`}:{kind:"inferred",pointer:t.pointer,detail:"stable operation identity"},intent:t.extensions?.intent?{kind:"extension",pointer:`${t.pointer}/x-hapi-intent`}:{kind:"inferred",pointer:t.pointer,detail:"operation purpose"},transport:{kind:"document",pointer:t.pointer},inputs:{kind:"document",pointer:t.pointer},outputs:{kind:"document",pointer:`${t.pointer}/responses`},effects:l?{kind:"extension",pointer:`${t.pointer}/x-hapi-effects`}:{kind:"inferred",pointer:t.pointer,detail:"HTTP method semantics"},authorization:{kind:"document",pointer:u},prerequisites:t.extensions?.prerequisites?{kind:"extension",pointer:`${t.pointer}/x-hapi-prerequisites`}:{kind:"inferred",pointer:t.pointer,detail:"required inputs"}}}}function Xt(n,t){let i=new Map;for(let e of[t.pathItem.parameters,t.operation.parameters]){if(!Array.isArray(e))continue;for(let a of e){let o=V(n,a);if(!g(o))continue;let r=m(o.name),s=m(o.in);if(r&&s)i.set(`${s}:${r}`,o)}}return[...i.values()].sort((e,a)=>`${e.in}:${e.name}`.localeCompare(`${a.in}:${a.name}`))}function Kt(n,t){let i=n.map((e)=>({name:String(e.name),location:bi(e.in),required:e.in==="path"||e.required===!0,...m(e.description)?{description:m(e.description)}:{},...g(e.schema)?{schema:an(e.schema)}:{}}));if(g(t))i.push({name:"body",location:"body",required:t.required===!0,...m(t.description)?{description:m(t.description)}:{},...tt(t)?{schema:an(tt(t))}:{}});return i.sort((e,a)=>`${e.location}:${e.name}`.localeCompare(`${a.location}:${a.name}`))}async function Yt(n){if(!g(n)||!g(n.content))return[];let t=[];for(let i of Object.keys(n.content).sort()){let e=n.content[i];if(!g(e)||!g(e.schema))continue;let a=Array.isArray(e.schema.oneOf)&&e.schema.oneOf.length>0?[...e.schema.oneOf].filter(g).sort((o,r)=>H(o).localeCompare(H(r))):[e.schema];for(let o of a){let r=await hn(o);t.push({id:`${_(i)}-${r.slice(0,12)}`,mediaType:i,required:n.required===!0,...m(o.title)?{title:m(o.title)}:{},schemaHash:r,schema:an(o)})}}return Ei(t,(i)=>`${i.mediaType}:${i.schemaHash}`).sort((i,e)=>i.id.localeCompare(e.id))}function Qt(n,t){if(!g(t))return[];let i=[];for(let e of Object.keys(t).sort()){let a=V(n,t[e]);if(!g(a))continue;let o=g(a.content)?a.content:{},r=Object.keys(o).sort(),s=new Set;for(let c of r){let p=o[c];if(!g(p)||!g(p.schema))continue;for(let l of pi(p.schema))s.add(l)}i.push({status:e,...m(a.description)?{description:m(a.description)}:{},mediaTypes:r,fields:[...s].sort()})}return i}function Zt(n,t){let i=Object.hasOwn(t,"security")?t.security:n.security;if(!Array.isArray(i))return[];return i.filter(g).map((e)=>({schemes:Object.keys(e).sort().map((a)=>({scheme:a,scopes:Array.isArray(e[a])?e[a].filter((o)=>typeof o==="string").sort():[]}))})).sort((e,a)=>h(e).localeCompare(h(a)))}function ni(n,t,i,e){let a=[];for(let o of i)for(let r of o.capabilityIds)a.push({id:`capability:${r}->operation:${o.id}`,type:"capability-operation",from:r,to:o.id,planningEligible:!1,provenance:o.provenance.capabilities??{kind:"inferred"}});return a.push(...ti(n,t,i,e)),a.sort(xi)}function ti(n,t,i,e){let a=[],o=new Map,r=new Map(t.map((c)=>[`${c.method} ${c.path}`,c])),s=new Map(i.map((c)=>[c.id,c]));for(let c of t){if(!c.sourceOperationId)continue;let p=o.get(c.sourceOperationId)??[];p.push(c),o.set(c.sourceOperationId,p)}for(let c of t){let p=g(c.operation.responses)?c.operation.responses:{};for(let l of Object.keys(p).sort()){let u=V(n,p[l]);if(!g(u)||!g(u.links))continue;for(let y of Object.keys(u.links).sort()){let f=V(n,u.links[y]);if(!g(f))continue;let d=ii(f,o,r),b=`${c.pointer}/responses/${D(l)}/links/${D(y)}`;if(!d){e.push({code:"unresolved-operation-link",severity:"warning",message:`OpenAPI Link '${y}' does not resolve to one compiled operation`,pointer:b,operationId:c.id});continue}let P=ei(f,s.get(d.id),b,c.id,y,e);a.push({id:`link:${c.id}->${d.id}:${_(y)}`,type:"operation-link",from:c.id,to:d.id,label:y,planningEligible:P,provenance:{kind:"document",pointer:b}})}}}return a}function ii(n,t,i){let e=m(n.operationId);if(e){let r=t.get(e);return r?.length===1?r[0]:void 0}let a=m(n.operationRef);if(!a?.startsWith("#/paths/"))return;let o=a.slice(2).split("/").map(yn);if(o.length!==3||o[0]!=="paths")return;return i.get(`${o[2]?.toLowerCase()} ${o[1]}`)}function ei(n,t,i,e,a,o){if(!t)return!1;let r=n.parameters??{};if(!g(r))return Zn(o,e,i,a,"parameters must be an object"),!1;let s=t.inputs.filter((d)=>d.location!=="body"),c=new Set(s.map((d)=>d.name)),p=Object.keys(r).filter((d)=>!c.has(d)),l=Object.entries(r).find(([,d])=>!en(d)),u=s.filter((d)=>d.required&&!Object.hasOwn(r,d.name)).map((d)=>d.name),f=!t.inputs.some((d)=>d.location==="body"&&d.required)||en(n.requestBody);if(p.length>0||l||u.length>0||!f){let d=[...p.length?[`unknown parameters: ${p.sort().join(", ")}`]:[],...l?[`invalid mapping for ${l[0]}`]:[],...u.length?[`missing required parameters: ${u.sort().join(", ")}`]:[],...!f?["missing or invalid required requestBody mapping"]:[]];return Zn(o,e,i,a,d.join("; ")),!1}return!0}function Zn(n,t,i,e,a){n.push({code:"ineligible-operation-link",severity:"warning",message:`OpenAPI Link '${e}' is descriptive-only: ${a}`,pointer:i,operationId:t})}function en(n){if(typeof n==="string")return!n.startsWith("$")||ai(n);if(n===null||typeof n==="boolean")return!0;if(typeof n==="number")return Number.isFinite(n);if(Array.isArray(n))return n.every(en);if(!g(n))return!1;return Object.values(n).every(en)}function ai(n){return/^\$(?:url|method|statusCode)$/.test(n)||/^\$(?:request|response)\.(?:path|query|header)\.[^\s.]+$/.test(n)||/^\$(?:request|response)\.body#(?:\/.*)?$/.test(n)}function oi(n,t,i){let e=t.operation.responses;if(!g(e))return;let a=[];for(let o of Object.keys(e).sort()){let r=V(n,e[o]);if(!g(r)||!(M in r))continue;let s=`${t.pointer}/responses/${D(o)}/${M}`,c=Hn(r[M],s,o,t.id,i);if(!c)continue;if(!(fn in t.operation)){i.push({code:"outcome-without-planning",severity:"warning",message:`${M} on response ${o} is ignored because the operation has no x-hapi-planning`,pointer:s,operationId:t.id});continue}a.push({status:o,produces:c.produces,removes:c.removes,provenance:{kind:"extension",pointer:s}})}return a.length?a:void 0}function ri(n,t,i){if(!n?.length)return;let e=new Set((t?.transitions??[]).flatMap((a)=>a.requires.map((o)=>h(o))));return n.map((a)=>{if(!e.has(h(a.fact)))i.push({code:"unused-client-fact",severity:"warning",message:`Client fact ${a.fact.predicate} is not required by any planning transition`,pointer:a.pointer});return{fact:a.fact,...a.description?{description:a.description}:{},provenance:{kind:"extension",pointer:a.pointer}}})}function si(n,t,i){let e=new Map(t.map((r)=>[r.id,r])),a=new Map(n.map((r)=>[r.id,r])),o=new Map;for(let r of t){let s=a.get(r.id),c=s?.extensions?.planning;if(!s||!c)continue;let p=Cn(r,c,{kind:"x-hapi-planning",provenance:{kind:"extension",pointer:`${s.pointer}/x-hapi-planning`}});o.set(r.id,s.outcomes?.length?{...p,outcomes:s.outcomes}:p)}for(let r of i){if(r.type!=="operation-link"||!r.planningEligible)continue;let s=e.get(r.from),c=e.get(r.to);if(!s||!c)continue;let p={kind:"openapi-link",provenance:r.provenance},l=o.get(s.id)??Cn(s,void 0,p);o.set(s.id,{...l,produces:W([...l.produces,Pn(s.id)]),sources:nt([...l.sources,p])});let u=o.get(c.id)??Cn(c,void 0,p);o.set(c.id,{...u,requires:W([...u.requires,Pn(s.id)]),sources:nt([...u.sources,p])})}if(o.size===0)return;return{schemaVersion:"1",transitions:[...o.values()].sort(Vn)}}function Cn(n,t,i){return{id:`operation:${n.id}`,target:{kind:"operation",id:n.id},requires:W(t?.requires??[]),produces:W([...t?.produces??[],Pn(n.id)]),removes:W(t?.removes??[]),cost:t?.cost??1,gates:ci(n),sources:[i]}}function ci(n){let t=[];if(n.authorization.length>0)t.push({kind:"authorization",status:"required",code:"operation-authorization"});if(n.effects.destructive)t.push({kind:"risk",status:"required",code:"destructive-operation"});if(n.effects.requiresConfirmation)t.push({kind:"confirmation",status:"required",code:"mutation-confirmation"});return t.sort((i,e)=>`${i.kind}:${i.code}`.localeCompare(`${e.kind}:${e.code}`))}function Pn(n){return{predicate:`operation.${_(n).toLowerCase()}.completed`}}function W(n){return[...new Map(n.map((i)=>[h(i),i])).entries()].sort(([i],[e])=>i.localeCompare(e)).map(([,i])=>i)}function nt(n){return[...new Map(n.map((i)=>[h(i),i])).entries()].sort(([i],[e])=>i.localeCompare(e)).map(([,i])=>i)}function an(n){if(!g(n))return{};let t=m(n.$ref);if(t)return{ref:t};let i=g(n.properties)?Object.keys(n.properties).sort():void 0,e=Array.isArray(n.required)?n.required.filter((o)=>typeof o==="string").sort():void 0,a=Array.isArray(n.enum)?n.enum.filter(hi).sort((o,r)=>JSON.stringify(o).localeCompare(JSON.stringify(r))):void 0;return{...m(n.type)?{type:m(n.type)}:{},...m(n.format)?{format:m(n.format)}:{},...m(n.title)?{title:m(n.title)}:{},...m(n.description)?{description:m(n.description)}:{},...a&&a.length>0?{enum:a}:{},...e&&e.length>0?{required:e}:{},...i&&i.length>0?{properties:i}:{},...g(n.items)?{items:an(n.items)}:{}}}function pi(n){if(g(n.properties))return Object.keys(n.properties).sort();if(g(n.items)&&g(n.items.properties))return Object.keys(n.items.properties).sort();return[]}function li(n,t){let i=n.filter((e)=>e.required&&e.location!=="body").map((e)=>`Provide required ${e.location} parameter '${e.name}'`);if(t)i.push("Provide the required request body");return i.sort()}function tt(n){if(!g(n.content))return;for(let t of Object.keys(n.content).sort()){let i=n.content[t];if(g(i)&&g(i.schema))return i.schema}return}function ui(n,t){let i=g(n.info)?n.info:{};return{kind:t?.kind??"openapi",identifier:t?.identifier??m(i.title)??"in-memory",...t?.canonicalUri?{canonicalUri:t.canonicalUri}:{},documentVersion:String(n.openapi),...m(i.title)?{title:m(i.title)}:{},...m(i.version)?{version:m(i.version)}:{}}}async function di(n){return S(h({schemaVersion:n.schemaVersion,source:{kind:n.source.kind,documentVersion:n.source.documentVersion,title:n.source.title,version:n.source.version},capabilities:n.capabilities,operations:n.operations,edges:n.edges,planning:n.planning,triggers:n.triggers,clientFacts:n.clientFacts}))}function fi(n){let t=new Map;if(!Array.isArray(n.tags))return t;for(let i of n.tags){if(!g(i))continue;let e=m(i.name),a=m(i.description);if(e&&a)t.set(e,a)}return t}function yi(n){let t=n.split(/[./>]+/).map((i)=>i.trim()).filter(Boolean);return t.length>0?t:["root"]}function gi(n){return n.split("/").find((t)=>t&&!t.startsWith("{"))??"root"}function mi(n){return n.trim().toLowerCase().replace(/[^a-z0-9_-]+/g,"-").replace(/-+/g,"-").replace(/^-+|-+$/g,"")||"root"}function _(n){return n.trim().replace(/[^A-Za-z0-9_.-]+/g,"-").replace(/-+/g,"-").replace(/^-+|-+$/g,"")||"operation"}function bi(n){return["path","query","header","cookie"].includes(String(n))?String(n):"query"}function xn(n){return[...n].sort((t,i)=>`${t.severity}:${t.pointer??""}:${t.code}:${t.operationId??""}`.localeCompare(`${i.severity}:${i.pointer??""}:${i.code}:${i.operationId??""}`))}function it(n){return n.some((t)=>t.severity==="error")}function En(n,t,i){return{code:n,severity:"error",message:t,pointer:i}}function hi(n){return n===null||["string","number","boolean"].includes(typeof n)}function Vn(n,t){return n.id.localeCompare(t.id)}function Ci(n,t){return`${n.method}:${n.path}`.localeCompare(`${t.method}:${t.path}`)}function xi(n,t){return`${n.type}:${n.from}:${n.to}:${n.id}`.localeCompare(`${t.type}:${t.from}:${t.to}:${t.id}`)}function Ei(n,t){let i=new Set;return n.filter((e)=>{let a=t(e);if(i.has(a))return!1;return i.add(a),!0})}function et(n){if(!n||typeof n!=="object"||Object.isFrozen(n))return n;Object.freeze(n);for(let t of Object.values(n))et(t);return n}function at(n,t,i,e){if(n.kind==="authorization")return e;return i.has(n.code)||i.has(`${t}:${n.code}`)}var Pi=Object.freeze({maxDepth:12,maxStates:2000,maxFrontier:1000,maxExpansionsPerState:100});class J{id="deterministic-planner-v1";async plan(n){rt(n.signal);let t=E(n.initialFacts),i=E(n.goalFacts),e=await rn(t),a={schemaVersion:"1",graphFingerprint:n.graph.fingerprint,initialStateDigest:e},o=Vi(n);if(o.length>0)return{...a,outcome:"unplannable",totalCost:0,steps:[],missingFacts:i,unsatisfiedGates:[],diagnostics:o};if(kn(t,i))return{...a,outcome:"complete",planDigest:await Gn(n.graph.fingerprint,t,i,[]),totalCost:0,steps:[],missingFacts:[],unsatisfiedGates:[],diagnostics:[]};let{transitions:r,diagnostics:s}=wi(n),c=ki(t,i,r,n.bounds,n.signal);if(!c.node){let f=Oi(t,i,r),d=f.length>0?{code:"missing-planning-facts",severity:"warning",phase:"search",message:"Planning requires additional explicit state facts that no transition can produce"}:void 0;return{...a,outcome:f.length>0?"clarification-required":"unplannable",totalCost:0,steps:[],missingFacts:f,unsatisfiedGates:[],diagnostics:[...s,d,c.diagnostic].filter((b)=>Boolean(b))}}let p=Si(c.node.transitions),l=new Set(n.satisfiedGates??[]),u=n.principal!==void 0,y=p.flatMap((f)=>f.gates.filter((d)=>!at(d,f.transitionId,l,u))).sort(Di);return{...a,outcome:y.length>0?"clarification-required":"planned",planDigest:await Gn(n.graph.fingerprint,t,i,p.map((f)=>f.transitionId)),totalCost:c.node.cost,steps:p,missingFacts:[],unsatisfiedGates:y,diagnostics:s}}}function E(n){let t=new Map;for(let i of n)t.set(w(i),i);return[...t.entries()].sort(([i],[e])=>i.localeCompare(e)).map(([,i])=>i)}async function rn(n){return S(h(E(n)))}async function Gn(n,t,i,e){return S(h({graphFingerprint:n,initialFacts:E(t),goalFacts:E(i),transitionIds:[...e]}))}function Vi(n){let t=[],i=n.bounds;for(let[e,a]of Object.entries(i))if(!Number.isSafeInteger(a)||a<1)t.push({code:"invalid-planning-bound",severity:"error",phase:"validation",message:`${e} must be a positive safe integer`});for(let e of n.graph.planning?.transitions??[])if(!Number.isFinite(e.cost)||e.cost<0)t.push({code:"invalid-transition-cost",severity:"error",phase:"validation",transitionId:e.id,message:`Transition '${e.id}' has a non-finite or negative cost`});return t.sort(Ai)}function wi(n){let t=new Map(n.graph.operations.map((a)=>[a.id,a])),i=[],e=[];for(let a of n.graph.planning?.transitions??[]){let o=Gi(a,t);if(o&&!N(o,n.principal)){e.push({code:"transition-unauthorized",severity:"warning",phase:"eligibility",transitionId:a.id,message:`Transition '${a.id}' is not authorized for the supplied principal`});continue}i.push(a)}return i.sort((a,o)=>a.id.localeCompare(o.id)),{transitions:i,diagnostics:e}}function Gi(n,t){return n.target.kind==="operation"?t.get(n.target.id):void 0}function ki(n,t,i,e,a){let o={facts:n,key:ot(n),cost:0,transitionIds:[],transitions:[]},r=[o],s=new Map([[o.key,{cost:0,path:""}]]),c=1,p=!1;while(r.length>0){rt(a),r.sort($i);let l=r.shift();if(kn(l.facts,t))return{node:l};if(l.transitions.length>=e.maxDepth){p=!0;continue}let u=i.filter((f)=>kn(l.facts,f.requires));if(u.length>e.maxExpansionsPerState)return{diagnostic:on("max-expansions-per-state-exceeded",e.maxExpansionsPerState)};let y=u.slice(0,e.maxExpansionsPerState);for(let f of y){let d=vi(l.facts,f),b=ot(d),P=[...l.transitionIds,f.id],x=l.cost+f.cost,z=P.join("\x00"),O=s.get(b);if(O&&(O.cost<x||O.cost===x&&O.path<=z))continue;if(!O){if(c++,c>e.maxStates)return{diagnostic:on("max-states-exceeded",e.maxStates)}}if(s.set(b,{cost:x,path:z}),r.push({facts:d,key:b,cost:x,transitionIds:P,transitions:[...l.transitions,f]}),r.length>e.maxFrontier)return{diagnostic:on("max-frontier-exceeded",e.maxFrontier)}}}if(p)return{diagnostic:on("max-depth-exceeded",e.maxDepth)};return{diagnostic:{code:"goal-unreachable",severity:"warning",phase:"search",message:"No eligible bounded transition sequence reaches the requested goal"}}}function vi(n,t){let i=new Map(n.map((e)=>[w(e),e]));for(let e of t.removes)i.delete(w(e));for(let e of t.produces)i.set(w(e),e);return E([...i.values()])}function Si(n){let t=0;return n.map((i,e)=>(t+=i.cost,{index:e,transitionId:i.id,target:i.target,cost:i.cost,cumulativeCost:t,requires:i.requires,produces:i.produces,removes:i.removes,gates:i.gates,sources:i.sources,...i.outcomes?.length?{outcomes:i.outcomes}:{}}))}function kn(n,t){let i=new Set(n.map(w));return t.every((e)=>i.has(w(e)))}function Oi(n,t,i){let e=new Set(n.map(w)),a=new Set(t.map(w)),o=new Map;for(let p of i)for(let l of p.produces){let u=o.get(w(l))??[];u.push(p),o.set(w(l),u)}let r=[...t],s=new Set,c=[];while(r.length>0){let p=r.shift(),l=w(p);if(e.has(l)||s.has(l))continue;s.add(l);let u=o.get(l)??[];if(u.length===0){if(!a.has(l))c.push(p);continue}for(let y of u)r.push(...y.requires)}return E(c)}function w(n){return h(n)}function ot(n){return h(E(n))}function $i(n,t){return n.cost-t.cost||n.transitionIds.join("\x00").localeCompare(t.transitionIds.join("\x00"))||n.key.localeCompare(t.key)}function Di(n,t){return`${n.kind}:${n.code}`.localeCompare(`${t.kind}:${t.code}`)}function Ai(n,t){return`${n.phase}:${n.transitionId??""}:${n.code}`.localeCompare(`${t.phase}:${t.transitionId??""}:${t.code}`)}function on(n,t){return{code:n,severity:"warning",phase:"search",message:`Planning stopped at configured bound ${t}`}}function rt(n){if(!n?.aborted)return;if(typeof n.throwIfAborted==="function")n.throwIfAborted();throw new DOMException("Capability graph planning aborted","AbortError")}import{resolveCapabilityExecutionConfirmationVerifier as Ri}from"@mcp-com-ai/core/capability-execution";async function vn(n){return cn(n??null,"principal")}async function st(n){return cn(n,"step arguments")}async function sn(n,t,i){let e=new Map(n.operations.map((r)=>[r.id,r])),a=new Map(i.map((r)=>[r.index,r])),o=[];for(let r of t){let s=r.target.kind==="operation"?e.get(r.target.id):void 0;if(!(r.target.kind==="workflow"||s?.effects.sideEffecting===!0||s?.effects.destructive===!0||s!==void 0&&s.effects.mode!=="read"||r.gates.some((l)=>l.kind==="confirmation")))continue;let p=a.get(r.index);if(!p)continue;o.push({index:r.index,transitionId:r.transitionId,target:r.target,argumentDigest:await st(p.arguments),...p.workflowSourceFingerprint?{workflowSourceFingerprint:p.workflowSourceFingerprint}:{}})}return o}async function ct(n){return cn(n,"mutation set")}async function Sn(n,t){let i=await vn(n.principal),e=await sn(t,n.plan.steps,n.stepArguments);return{schemaVersion:"1",planDigest:n.plan.planDigest??"",graphFingerprint:t.fingerprint,principalDigest:i,mutationSetDigest:await ct(e)}}async function On(n){let t=await vn(n.principal);return cn({schemaVersion:n.schemaVersion,graphFingerprint:n.graphFingerprint,planDigest:n.plan.planDigest??null,initialFacts:E(n.initialFacts),goalFacts:E(n.goalFacts),currentFacts:E(n.currentFacts),satisfiedGates:[...n.satisfiedGates??[]].sort(),principalDigest:t,planningBounds:n.planningBounds,stepArguments:n.stepArguments.map((i)=>({index:i.index,transitionId:i.transitionId,arguments:i.arguments,bodyVariantId:i.bodyVariantId??null,workflowSourceFingerprint:i.workflowSourceFingerprint??null})),limits:n.limits},"execution envelope")}async function cn(n,t){return pt(n,t,new Set),S(h(n))}function pt(n,t,i){if(n===null||typeof n==="string"||typeof n==="boolean")return;if(typeof n==="number"){if(Number.isFinite(n))return;throw TypeError(`${t} must contain only finite JSON numbers`)}if(!n||typeof n!=="object")throw TypeError(`${t} must be JSON-safe`);if(i.has(n))throw TypeError(`${t} must not contain cyclic values`);let e=Object.getPrototypeOf(n);if(!Array.isArray(n)&&e!==Object.prototype&&e!==null)throw TypeError(`${t} must contain only JSON objects and arrays`);i.add(n);let a=Array.isArray(n)?n:Object.values(n);for(let o of a)pt(o,t,i);i.delete(n)}async function Dn(n,t,i={}){dt(t.signal);let e=Mi(n,t),a=e.length===0?await Ti(n,t,e):ut();if(e.length===0&&!await Ii(n,t,i.planner))e.push(Bi());if(e.length===0&&a.binding)e.push(...await lt(t,a.mutations,a.binding,i.confirmation));return{ok:e.length===0,...a.executionDigest?{executionDigest:a.executionDigest}:{},...a.binding?{binding:a.binding}:{},mutations:a.mutations,transitions:a.transitions,diagnostics:e}}async function Ti(n,t,i){let e=qi(n,t);try{let[a,o,r]=await Promise.all([On(t),sn(n,t.plan.steps,t.stepArguments),Sn(t,n)]);return{executionDigest:a,mutations:o,binding:r,transitions:e}}catch{return i.push(zi()),{...ut(),transitions:e}}}async function Ii(n,t,i){let e=await(i??new J).plan({schemaVersion:"1",graph:n,initialFacts:t.initialFacts,goalFacts:t.goalFacts,satisfiedGates:t.satisfiedGates,principal:t.principal,bounds:t.planningBounds,signal:t.signal});return Hi(e,t.plan)}async function lt(n,t,i,e={}){if(t.length===0)return[];if(n.confirmations.length===0)return[G("execution-confirmation-required","The planned mutation set requires a trusted confirmation receipt","confirmation")];let a=(e.now??Date.now)(),o=e.clockSkewMs??30000,r=e.maxReceiptLifetimeMs??300000,s=new Set;for(let c of n.confirmations){dt(n.signal);let p=await Fi(c,i,n.signal,a,o,r);if(p==="valid")return[];s.add(p)}return[G(ji(s),"No trusted confirmation receipt validates the exact execution binding","confirmation")]}async function Fi(n,t,i,e,a,o){if(!Ui(n,t))return"binding";if(!Ni(n,e,a,o))return"time";let r=Ri(n.verifierId);if(!r)return"verifier";try{return await r.verify(n,t,i)?"valid":"proof"}catch{return"proof"}}function Ni(n,t,i,e){let a=Date.parse(n.issuedAt),o=Date.parse(n.expiresAt);return Number.isFinite(a)&&Number.isFinite(o)&&o>a&&a<=t+i&&o>=t-i&&o-a<=e}function ji(n){if(n.has("binding"))return"execution-confirmation-binding-mismatch";if(n.has("time"))return"execution-confirmation-expired";if(n.has("verifier"))return"execution-confirmation-verifier-unavailable";return"execution-confirmation-invalid"}function Mi(n,t){let i=[];return _i(n,t,i),Li(t,i),Ji(n,t,i),i}function _i(n,t,i){if(t.schemaVersion!=="1")i.push(G("unsupported-execution-version","Execution request schemaVersion must be '1'","envelope"));if(t.graphFingerprint!==n.fingerprint||t.plan.graphFingerprint!==n.fingerprint)i.push(G("execution-graph-mismatch","The execution request does not match the retained graph fingerprint","envelope"));if(t.plan.outcome!=="planned"&&t.plan.outcome!=="complete"||!t.plan.planDigest)i.push(G("execution-plan-not-executable","Guarded execution requires a planned or complete result with a plan digest","envelope"));if(t.plan.steps.length>t.limits.maxPlanSteps)i.push(G("execution-step-limit-exceeded","The plan exceeds the configured execution step limit","envelope"))}function Ji(n,t,i){if(t.stepArguments.length!==t.plan.steps.length)i.push(G("execution-step-arguments-mismatch","Execution arguments must contain exactly one ordered entry per plan step","envelope"));let e=new Set,a=new Map((n.planning?.transitions??[]).map((r)=>[r.id,r])),o=0;for(let[r,s]of t.plan.steps.entries()){let c=t.stepArguments[r],p=a.get(s.transitionId);if(o+=p?.cost??0,e.has(s.transitionId))i.push($n("execution-duplicate-transition","An execution plan cannot repeat a transition",r,s.transitionId));if(e.add(s.transitionId),!p||!Wi(s,p,r,o))i.push($n("execution-transition-mismatch","A plan step does not match its retained graph transition",r,s.transitionId));if(!c||c.index!==r||c.transitionId!==s.transitionId)i.push($n("execution-step-arguments-mismatch","Step arguments are missing, reordered, or bound to another transition",r,s.transitionId))}}function Li(n,t){for(let[i,e]of Object.entries(n.limits)){let a=i==="maxRetriesPerStep";if(!Number.isSafeInteger(e)||e<(a?0:1))t.push(G("invalid-execution-limit",`${i} must be ${a?"a nonnegative":"a positive"} safe integer`,"envelope"))}}function qi(n,t){let i=new Map((n.planning?.transitions??[]).map((e)=>[e.id,e]));return t.plan.steps.map((e)=>i.get(e.transitionId)).filter((e)=>e!==void 0)}function ut(){return{mutations:[],transitions:[]}}function zi(){return G("execution-envelope-not-json-safe","The execution envelope must contain only finite JSON-safe values","envelope")}function Bi(){return G("execution-plan-not-canonical","The supplied plan is not the canonical current plan for this graph and request","envelope")}function Hi(n,t){return n.outcome===t.outcome&&n.planDigest===t.planDigest&&n.initialStateDigest===t.initialStateDigest&&n.totalCost===t.totalCost&&h(n.steps)===h(t.steps)}function Wi(n,t,i,e){return h(n)===h({index:i,transitionId:t.id,target:t.target,cost:t.cost,cumulativeCost:e,requires:t.requires,produces:t.produces,removes:t.removes,gates:t.gates,sources:t.sources,...t.outcomes?.length?{outcomes:t.outcomes}:{}})}function Ui(n,t){return n.schemaVersion===t.schemaVersion&&n.planDigest===t.planDigest&&n.graphFingerprint===t.graphFingerprint&&n.principalDigest===t.principalDigest&&n.mutationSetDigest===t.mutationSetDigest}function G(n,t,i){return{code:n,message:t,phase:i,severity:"error"}}function $n(n,t,i,e){return{...G(n,t,"envelope"),stepIndex:i,transitionId:e}}function dt(n){if(!n?.aborted)return;if(typeof n.throwIfAborted==="function")n.throwIfAborted();throw new DOMException("Capability execution validation aborted","AbortError")}function X(n,t){let i=[];return F(n,t,"",n,i,new Set),i}function F(n,t,i,e,a,o){if(n===!0||n===void 0)return;if(n===!1||!U(n)){a.push({instancePath:i,keyword:"false-schema"});return}if(typeof n.$ref==="string"){let r=n.$ref;if(!r.startsWith("#/")||o.has(r)){a.push({instancePath:i,keyword:"$ref"});return}let s=ne(e,r.slice(1));if(s===void 0){a.push({instancePath:i,keyword:"$ref"});return}F(s,t,i,e,a,new Set(o).add(r))}if(Array.isArray(n.allOf))for(let r of n.allOf)F(r,t,i,e,a,o);if(ft("anyOf",n.anyOf,t,i,e,a,o),ft("oneOf",n.oneOf,t,i,e,a,o),n.const!==void 0&&!gt(t,n.const))a.push({instancePath:i,keyword:"const"});if(Array.isArray(n.enum)&&!n.enum.some((r)=>gt(t,r)))a.push({instancePath:i,keyword:"enum"});if(n.type!==void 0&&!Zi(t,n.type)){a.push({instancePath:i,keyword:"type"});return}if(typeof t==="string")Xi(n,t,i,a);if(typeof t==="number")Ki(n,t,i,a);if(Array.isArray(t))Yi(n,t,i,e,a,o);if(U(t))Qi(n,t,i,e,a,o)}function ft(n,t,i,e,a,o,r){if(!Array.isArray(t))return;let s=t.filter((c)=>{let p=[];return F(c,i,e,a,p,r),p.length===0}).length;if(n==="anyOf"&&s===0||n==="oneOf"&&s!==1)o.push({instancePath:e,keyword:n})}function Xi(n,t,i,e){if(typeof n.minLength==="number"&&t.length<n.minLength)e.push({instancePath:i,keyword:"minLength"});if(typeof n.maxLength==="number"&&t.length>n.maxLength)e.push({instancePath:i,keyword:"maxLength"});if(typeof n.pattern==="string")try{if(!new RegExp(n.pattern).test(t))e.push({instancePath:i,keyword:"pattern"})}catch{e.push({instancePath:i,keyword:"pattern"})}}function Ki(n,t,i,e){if(typeof n.minimum==="number"&&t<n.minimum)e.push({instancePath:i,keyword:"minimum"});if(typeof n.maximum==="number"&&t>n.maximum)e.push({instancePath:i,keyword:"maximum"})}function Yi(n,t,i,e,a,o){if(typeof n.minItems==="number"&&t.length<n.minItems)a.push({instancePath:i,keyword:"minItems"});if(typeof n.maxItems==="number"&&t.length>n.maxItems)a.push({instancePath:i,keyword:"maxItems"});if(n.items!==void 0)t.forEach((r,s)=>F(n.items,r,`${i}/${s}`,e,a,o))}function Qi(n,t,i,e,a,o){let r=U(n.properties)?n.properties:{};for(let s of Array.isArray(n.required)?n.required:[])if(typeof s==="string"&&!(s in t))a.push({instancePath:i,keyword:"required"});for(let[s,c]of Object.entries(t))if(r[s]!==void 0)F(r[s],c,`${i}/${yt(s)}`,e,a,o);else if(n.additionalProperties===!1)a.push({instancePath:i,keyword:"additionalProperties"});else if(n.additionalProperties!==void 0&&n.additionalProperties!==!0)F(n.additionalProperties,c,`${i}/${yt(s)}`,e,a,o)}function Zi(n,t){return(Array.isArray(t)?t:[t]).some((e)=>{if(e==="null")return n===null;if(e==="array")return Array.isArray(n);if(e==="object")return U(n);if(e==="integer")return typeof n==="number"&&Number.isInteger(n);return typeof n===e})}function ne(n,t){return t.split("/").slice(1).reduce((i,e)=>{if(!U(i)&&!Array.isArray(i))return;let a=e.replaceAll("~1","/").replaceAll("~0","~");return i[a]},n)}function yt(n){return n.replaceAll("~","~0").replaceAll("/","~1")}function U(n){return Boolean(n)&&typeof n==="object"&&!Array.isArray(n)}function gt(n,t){return JSON.stringify(n)===JSON.stringify(t)}async function An(n,t,i,e,a){be(t.signal);let o=await Dn(n,t,{confirmation:a.confirmation}),r=[...o.diagnostics];if(!o.ok)return{ok:!1,envelope:o,diagnostics:r};if(fe(a))return r.push(ge(i)),{ok:!1,envelope:o,diagnostics:r};let s=te(n,t,o,i,a,r);if(!s)return{ok:!1,envelope:o,diagnostics:r};let c=E(e);return r.push(...await ie(s,t,c,i,a),...oe(s,t,i)),{ok:r.length===0,envelope:o,transition:s.transition,...s.descriptor?{descriptor:s.descriptor}:{},diagnostics:r}}function te(n,t,i,e,a,o){let r=t.plan.steps[e],s=i.transitions[e];if(!r||!s){o.push(me(e));return}let c=a.descriptors.get(s.target.id);if(!ye(s,c))o.push(k("execution-target-descriptor-mismatch","The retained runtime descriptor does not match the planned target",e,s.id,"preflight"));let p=s.target.kind==="operation"?n.operations.find((l)=>l.id===s.target.id):void 0;return{transition:s,operation:p,descriptor:c}}async function ie(n,t,i,e,a){let o=[];if(!de(i,n.transition.requires))o.push(pn("execution-prerequisite-missing","Current state does not satisfy every planned transition prerequisite",n.transition,e));if(!await ee(n,t,a))o.push(pn("execution-authorization-denied","Current authorization does not permit the planned transition",n.transition,e));if(n.transition.gates.some((r)=>r.status==="denied"))o.push(pn("execution-gate-denied","A planned transition gate is currently denied",n.transition,e));if(!await ae(n,t,i,a))o.push(pn("execution-policy-denied","Current policy does not permit the planned transition",n.transition,e));return o}async function ee(n,t,i){if(i.authorize)return i.authorize({transition:n.transition,operation:n.operation,principal:t.principal});if(n.operation)return N(n.operation,t.principal);return!n.transition.gates.some((e)=>e.kind==="authorization")}async function ae(n,t,i,e){if(!n.transition.gates.some((a)=>a.kind==="policy"))return!0;return e.evaluatePolicy?e.evaluatePolicy({transition:n.transition,principal:t.principal,currentFacts:i}):!1}function oe(n,t,i){let e=t.stepArguments[i];if(!n.descriptor||!e)return[];return[...re(n.operation,n.transition,n.descriptor,e,i),...X(n.descriptor.inputSchema,e.arguments).map((o)=>k("execution-arguments-invalid",`Argument schema validation failed${o.instancePath?` at ${o.instancePath}`:""} (${o.keyword})`,i,n.transition.id,"arguments"))]}async function Rn(n,t,i){if(!n.ok||!n.transition||!n.descriptor)return{ok:!1,facts:E(t),diagnostics:n.diagnostics};let{transition:e,descriptor:a}=n,o=[];if(a.kind==="operation"&&(i.status===void 0||i.status<200||i.status>=300))o.push(k("execution-response-unsuccessful","The operation did not satisfy its success status contract",mt(n),e.id,"response"));let r=le(a,i);if(r!==void 0)for(let c of X(r,i.body))o.push(k("execution-response-invalid",`Response schema validation failed${c.instancePath?` at ${c.instancePath}`:""} (${c.keyword})`,mt(n),e.id,"response"));if(o.length>0)return{ok:!1,facts:E(t),diagnostics:o};let s=ue(t,e);return{ok:!0,facts:s,stateDigest:await rn(s),diagnostics:[]}}function re(n,t,i,e,a){if(i.kind==="workflow")return e.workflowSourceFingerprint===i.sourceFingerprint?[]:[pe(a,t.id)];if(!n)return[k("execution-operation-not-found","The planned operation is absent from the retained graph",a,t.id,"preflight")];return se(n,t,i,e,a)}function se(n,t,i,e,a){let o=[];if(e.bodyVariantId){if(!n.bodyVariants.some((r)=>r.id===e.bodyVariantId))o.push(k("execution-body-variant-mismatch","The selected request body variant is absent from the retained graph operation",a,t.id,"arguments"));o.push(...ce(i,e,t.id,a))}else if(n.bodyVariants.length>1)o.push(k("execution-body-variant-required","A canonical request body variant must be selected before execution",a,t.id,"arguments"));return o}function ce(n,t,i,e){let a=n.bodyVariants?.find((o)=>o.id===t.bodyVariantId);if(!a)return[k("execution-body-schema-missing","The retained tool descriptor has no schema for the selected request body variant",e,i,"arguments")];return X(a.schema,t.arguments[a.argumentName]).map((o)=>k("execution-body-invalid",`Request body schema validation failed${o.instancePath?` at ${o.instancePath}`:""} (${o.keyword})`,e,i,"arguments"))}function pe(n,t){return k("execution-workflow-fingerprint-mismatch","The planned workflow source no longer matches its validated runtime descriptor",n,t,"preflight")}function le(n,t){if(n.kind==="workflow")return n.outputSchema;if(t.status===void 0)return;let i=String(t.status),e=`${i[0]}XX`,a=n.responseSchemas.filter((r)=>r.status===i||r.status.toUpperCase()===e||r.status.toLowerCase()==="default"),o=t.mediaType?.split(";",1)[0]?.trim().toLowerCase();return a.find((r)=>!r.mediaType||r.mediaType.toLowerCase()===o)?.schema??a[0]?.schema}function ue(n,t){let i=new Map(E(n).map((e)=>[K(e),e]));for(let e of t.removes)i.delete(K(e));for(let e of t.produces)i.set(K(e),e);return E([...i.values()])}function de(n,t){let i=new Set(n.map(K));return t.every((e)=>i.has(K(e)))}function K(n){return h(n)}function fe(n){return n.deadlineEpochMs!==void 0&&(n.now??Date.now)()>=n.deadlineEpochMs}function ye(n,t){return Boolean(t&&t.targetId===n.target.id&&t.kind===n.target.kind)}function ge(n){return bt("execution-deadline-exceeded","The execution deadline was reached before step preflight",n)}function me(n){return bt("execution-step-not-found","The requested execution step is absent from the validated plan",n)}function pn(n,t,i,e){return k(n,t,e,i.id,"preflight")}function mt(n){return Math.max(0,n.envelope.transitions.findIndex((t)=>t.id===n.transition?.id))}function bt(n,t,i){return{code:n,message:t,phase:"preflight",severity:"error",stepIndex:i}}function k(n,t,i,e,a){return{code:n,message:t,phase:a,severity:"error",stepIndex:i,transitionId:e}}function be(n){if(!n?.aborted)return;if(typeof n.throwIfAborted==="function")n.throwIfAborted();throw new DOMException("Capability execution preflight aborted","AbortError")}function ht(n,t){if(!n?.length||t===void 0)return;let i=String(t),e=`${i[0]}XX`;return n.find((a)=>a.status===i)??n.find((a)=>a.status.toUpperCase()===e)??n.find((a)=>a.status==="default")}var Ct=Object.freeze({maxPlanSteps:50,maxTotalTimeMs:300000,maxStepTimeMs:60000,maxTotalAttempts:100,maxRetriesPerStep:3,maxResponseBytes:10485760,maxResultRecords:100,maxEventRecords:500}),xt=Object.freeze({maxPlanSteps:12,maxTotalTimeMs:60000,maxStepTimeMs:15000,maxTotalAttempts:16,maxRetriesPerStep:1,maxResponseBytes:1048576,maxResultRecords:50,maxEventRecords:100});class In{options;id="guarded-capability-executor-v1";constructor(n){this.options=n}async execute(n){let t=this.options.bindings.now??Date.now,i=this.options.bindings.createCorrelationId?.()??crypto.randomUUID(),e=he(n.limits,this.options.bindings.limits),a={...n,limits:e},o=t(),r=o+e.maxTotalTimeMs,s=new Et(this.options.bindings.eventSink,e.maxEventRecords),c=a.plan.planDigest??"unavailable";await s.emit(Tn("execution-start",i,a));let p={facts:a.currentFacts,results:[],diagnostics:[],totalAttempts:0},l,u="unavailable";for(let f=0;f<a.plan.steps.length;f+=1){if(l)break;if(f>=e.maxPlanSteps){l=Pe(p,f,"execution-step-limit-exceeded");break}let d;try{d=await this.executeStep({request:a,index:f,state:p,correlationId:i,deadlineEpochMs:r,now:t,events:s})}catch{let b=a.signal?.aborted===!0;d=L(p,f,a.plan.steps[f]?.transitionId,0,t(),t,b?"cancelled":"failed",b?"execution-cancelled":"execution-internal-failure")}u=d.executionDigest??u,l=d.terminal}Ve(a,p,e.maxResultRecords);let y=l?.outcome??"completed";return await s.emit({...Tn(y==="completed"?"execution-complete":Ge(y),i,a),durationMs:Math.max(0,t()-o),outcome:y,reasonCode:l?.reasonCode}),{schemaVersion:"1",outcome:y,correlationId:i,graphFingerprint:this.options.graph.fingerprint,planDigest:c,executionDigest:u,steps:p.results.slice(0,e.maxResultRecords),diagnostics:p.diagnostics.slice(0,e.maxResultRecords)}}async executeStep(n){let{request:t,index:i,state:e,correlationId:a,deadlineEpochMs:o,now:r,events:s}=n,c=xe(this.options.graph,t,i),p=Ee(this.options.graph,c),l=Ce(p,c,t.limits),u=r(),y;for(let f=1;f<=l+1;f+=1){if(e.totalAttempts>=t.limits.maxTotalAttempts)return L(e,i,c?.id,f-1,u,r,"rejected","execution-attempt-limit-exceeded");e.totalAttempts+=1,await s.emit(q("step-start",a,t,i,f));let d=await this.preflight(t,i,e.facts,o);if(y=d.envelope.executionDigest,!d.ok||!d.transition){e.diagnostics.push(...d.diagnostics);let x=d.diagnostics[0]?.code??"execution-preflight-rejected";return await s.emit({...q("step-failure",a,t,i,f),reasonCode:x}),L(e,i,c?.id,f,u,r,"rejected",x,d.diagnostics[0],y)}let b=await this.invokeAttempt(t,i,f,a,o,r),P=await this.handleInvocation({request:t,index:i,attempt:f,state:e,correlationId:a,deadlineEpochMs:o,stepStartedAt:u,now:r,events:s,preflight:d,invocation:b,canRetry:f<=l,executionDigest:y});if(P.retry){await ke(b.retryAfterMs,t.signal);continue}return P.result}return{executionDigest:y}}preflight(n,t,i,e){return An(this.options.graph,n,t,i,{descriptors:this.options.descriptors,deadlineEpochMs:e,now:this.options.bindings.now,confirmation:this.options.confirmation,authorize:this.options.bindings.authorize,evaluatePolicy:this.options.bindings.evaluatePolicy})}async invokeAttempt(n,t,i,e,a,o){let r=n.plan.steps[t],s=n.stepArguments[t],c=Math.max(1,Math.min(n.limits.maxStepTimeMs,a-o())),p=new AbortController,l=setTimeout(()=>p.abort("step-timeout"),c),u=()=>p.abort(n.signal?.reason??"cancelled");n.signal?.addEventListener("abort",u,{once:!0});try{return await this.options.bindings.invoker.invoke({correlationId:e,stepIndex:t,transitionId:r.transitionId,target:r.target,arguments:s.arguments,attempt:i,timeoutMs:c,maxResponseBytes:n.limits.maxResponseBytes,signal:p.signal})}catch{return{outcome:n.signal?.aborted?"failure":"indeterminate",reasonCode:n.signal?.aborted?"execution-cancelled":"execution-invocation-unknown",retryable:!n.signal?.aborted}}finally{clearTimeout(l),n.signal?.removeEventListener("abort",u)}}async handleInvocation(n){let{request:t,index:i,attempt:e,state:a,correlationId:o,stepStartedAt:r,now:s,events:c,preflight:p,invocation:l,canRetry:u,executionDigest:y}=n;if(t.signal?.aborted)return await c.emit(q("step-cancel",o,t,i,e)),{retry:!1,result:L(a,i,p.transition.id,e,r,s,"cancelled","execution-cancelled",void 0,y)};if(l.outcome!=="success"){if(u&&l.retryable)return await c.emit({...q("step-retry",o,t,i,e),responseStatus:l.status,reasonCode:l.reasonCode??"execution-transient-failure"}),{retry:!0};let d=l.outcome==="indeterminate"?"indeterminate":"failed",b=l.reasonCode??(d==="indeterminate"?"execution-upstream-indeterminate":"execution-upstream-failed"),P=Nn(b,i,p.transition.id);return a.diagnostics.push(P),await c.emit({...q("step-failure",o,t,i,e),responseStatus:l.status,reasonCode:b}),{retry:!1,result:L(a,i,p.transition.id,e,r,s,d,b,P,y,l.status,ht(p.transition.outcomes,l.status))}}let f=await Rn(p,a.facts,l);if(!f.ok){a.diagnostics.push(...f.diagnostics);let d=f.diagnostics[0]?.code??"execution-response-invalid";return{retry:!1,result:L(a,i,p.transition.id,e,r,s,"failed",d,f.diagnostics[0],y,l.status)}}return a.facts=f.facts,a.results.push({index:i,transitionId:p.transition.id,status:"completed",attempts:e,durationMs:Math.max(0,s()-r),responseStatus:l.status,appliedStateDigest:f.stateDigest}),await c.emit({...q("step-success",o,t,i,e),responseStatus:l.status,durationMs:Math.max(0,s()-r)}),{retry:!1,result:{executionDigest:y}}}}function Fn(n,t){return{id:"guarded-capability-executor-factory-v1",create(i){return new In({graph:n,descriptors:i.descriptors,bindings:i,confirmation:t})}}}class Et{sink;limit;count=0;constructor(n,t){this.sink=n;this.limit=t}async emit(n){if(!this.sink||this.count>=this.limit)return;this.count+=1;try{await this.sink(n)}catch{}}}function he(n,t){return Object.fromEntries(Object.entries(Ct).map(([i,e])=>{let a=i,o=t?.[a]??xt[a];return[i,Math.min(n[a],o,e)]}))}function Ce(n,t,i){if(!n||t?.target.kind!=="operation")return 0;return n.effects.mode==="read"||n.effects.idempotent?i.maxRetriesPerStep:0}function xe(n,t,i){let e=t.plan.steps[i]?.transitionId;return n.planning?.transitions.find((a)=>a.id===e)}function Ee(n,t){return t?.target.kind==="operation"?n.operations.find((i)=>i.id===t.target.id):void 0}function L(n,t,i,e,a,o,r,s,c,p,l,u){let y=c??we(s,t,i);if(!c)n.diagnostics.push(y);n.results.push({index:t,transitionId:i??"unknown",status:r,attempts:e,durationMs:Math.max(0,o()-a),responseStatus:l,diagnostic:y,...u?{declaredOutcome:{status:u.status,produces:u.produces,removes:u.removes}}:{}});let f=r==="cancelled"?"cancelled":n.results.some((d)=>d.index<t&&d.status==="completed")?"partial":r==="rejected"?"rejected":"failed";return{executionDigest:p,terminal:{outcome:f,reasonCode:s}}}function Pe(n,t,i){return n.diagnostics.push(Nn(i,t)),{outcome:n.results.some((e)=>e.status==="completed")?"partial":"rejected",reasonCode:i}}function Ve(n,t,i){let e=new Set(t.results.map((a)=>a.index));for(let[a,o]of n.plan.steps.entries()){if(t.results.length>=i)break;if(!e.has(a))t.results.push({index:a,transitionId:o.transitionId,status:"not-started",attempts:0,durationMs:0})}t.results.sort((a,o)=>a.index-o.index)}function Nn(n,t,i){return{code:n,severity:"error",message:"Guarded execution stopped at this step",phase:"invocation",stepIndex:t,transitionId:i}}function we(n,t,i){return Nn(n,t,i)}function Tn(n,t,i){return{schemaVersion:"1",name:n,correlationId:t,graphFingerprint:i.graphFingerprint,planDigest:i.plan.planDigest??"unavailable"}}function q(n,t,i,e,a){return{...Tn(n,t,i),stepIndex:e,transitionId:i.plan.steps[e]?.transitionId,attempt:a}}function Ge(n){return n==="cancelled"?"execution-cancel":"execution-failure"}async function ke(n,t){let i=Math.max(0,Math.min(n??25,1000));if(i===0)return;await new Promise((e)=>{let a=setTimeout(e,i);t?.addEventListener("abort",()=>{clearTimeout(a),e()},{once:!0})})}function ve(n){let t=['<?xml version="1.0" encoding="UTF-8"?>','<graphml xmlns="http://graphml.graphdrawing.org/xmlns">',' <key id="kind" for="node" attr.name="kind" attr.type="string"/>',' <key id="label" for="node" attr.name="label" attr.type="string"/>',' <key id="edgeType" for="edge" attr.name="type" attr.type="string"/>',' <key id="planningEligible" for="edge" attr.name="planningEligible" attr.type="boolean"/>',` <graph id="${A(n.fingerprint)}" edgedefault="directed">`];for(let i of n.capabilities)t.push(` <node id="${A(i.id)}"><data key="kind">capability</data><data key="label">${A(i.label)}</data></node>`);for(let i of n.operations)t.push(` <node id="${A(i.id)}"><data key="kind">operation</data><data key="label">${A(i.purpose)}</data></node>`);for(let i of n.edges)t.push(` <edge id="${A(i.id)}" source="${A(i.from)}" target="${A(i.to)}"><data key="edgeType">${A(i.type)}</data><data key="planningEligible">${String(i.planningEligible)}</data></edge>`);return t.push(" </graph>","</graphml>"),`${t.join(`
|
|
4
|
+
`)}
|
|
5
|
+
`}function A(n){return n.replaceAll("&","&").replaceAll('"',""").replaceAll("<","<").replaceAll(">",">")}async function Se(n,t,i){return Promise.all(t.cases.map(async(e)=>{let a=await i.classify({graph:n,candidates:n.operations.map((c)=>({toolName:c.sourceOperationId??c.id,operationId:c.id,description:c.purpose})),query:e.query,mode:"lexical",limit:10,principal:e.principalScopes?{scopes:e.principalScopes}:void 0,authority:"decision"}),o=a.matches.map((c)=>c.operationId),r=Pt(n,e.query,a),s=[];for(let c of e.expectedOperationIds??[])if(!o.includes(c))s.push(`missing expected operation ${c}`);for(let c of e.excludedOperationIds??[])if(o.includes(c))s.push(`included excluded operation ${c}`);if(e.expectedOperationIds?.length===0&&o.length>0)s.push(`expected no matches, received ${o.join(", ")}`);if(e.expectedStatus&&e.expectedStatus!==r)s.push(`expected status ${e.expectedStatus}, received ${r}`);return{id:e.id,passed:s.length===0,status:r,operationIds:o,diagnostics:a.diagnostics,failures:s}}))}function Pt(n,t,i){let[e,a]=i.matches;if(!e)return"no-match";if(a&&a.score>=e.score*0.75)return"ambiguous";let o=n.operations.find((r)=>r.id===e.operationId);if(o&&Oe(o,t))return"clarification-required";return"matched"}function Oe(n,t){let i=n.inputs.filter((s)=>s.required).map((s)=>s.name),e=n.bodyVariants.some((s)=>s.required);if(i.length===0&&!e)return!1;let a=t.toLowerCase(),o=i.some((s)=>a.includes(s.toLowerCase())),r=/\b\d+\b|["'][^"']+["']/.test(t);return!o&&!r}var ha={id:"capability-graph-v1",async create(n,t){let i=await wn(n,t);return{graph:i,classifier:new B,planner:new J,executorFactory:Fn(i),authority:"decision"}}},Ca={version:"1",id:"deterministic",create(){return new B}};export{Ct as CAPABILITY_EXECUTION_SAFETY_CEILINGS,tn as CapabilityGraphCompilationError,xt as DEFAULT_CAPABILITY_EXECUTION_LIMITS,Pi as DEFAULT_PLANNING_BOUNDS,B as DeterministicCapabilityGraphClassifier,J as DeterministicCapabilityGraphPlanner,In as GuardedCapabilityExecutor,fn as HAPI_PLANNING_EXTENSION_KEY,At as HAPI_PLANNING_EXTENSION_SCHEMA_V1,H as canonicalSchemaStringify,h as canonicalStringify,bn as canonicalizeJson,st as capabilityExecutionArgumentDigest,Sn as capabilityExecutionConfirmationBinding,On as capabilityExecutionEnvelopeDigest,sn as capabilityExecutionMutationSet,ct as capabilityExecutionMutationSetDigest,vn as capabilityExecutionPrincipalDigest,ha as capabilityGraphRuntimeProvider,Pt as classifyEvaluationStatus,wn as compileCapabilityGraph,Fn as createGuardedCapabilityExecutorFactory,Ca as deterministicCapabilityGraphClassifierFactory,Se as evaluateCapabilityGraph,hn as hashCanonicalSchema,N as isOperationAuthorized,E as normalizePlanningFacts,Bn as parsePlanningExtensionV1,Gn as planningPlanDigest,rn as planningStateDigest,An as preflightCapabilityExecutionStep,Lt as serializeCapabilityGraph,ve as serializeCapabilityGraphMl,S as sha256,lt as validateCapabilityExecutionConfirmations,Dn as validateCapabilityExecutionEnvelope,Rn as validateCapabilityExecutionResult,X as validateCapabilityJsonSchema};
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
import type { CapabilityGraphDiagnostic, CapabilityGraphTriggerV1 } from "@mcp-com-ai/core";
|
|
2
|
+
import { type JsonObject } from "./openapi-document";
|
|
3
|
+
/** An enumerated `paths` operation that may declare callbacks. */
|
|
4
|
+
export interface TriggerSourceOperation {
|
|
5
|
+
readonly id: string;
|
|
6
|
+
readonly pointer: string;
|
|
7
|
+
readonly operation: JsonObject;
|
|
8
|
+
}
|
|
9
|
+
/**
|
|
10
|
+
* Compile OpenAPI `webhooks` and operation `callbacks` into descriptive
|
|
11
|
+
* triggers sorted by id. Triggers never become planning transitions.
|
|
12
|
+
*/
|
|
13
|
+
export declare function collectTriggers(document: JsonObject, operations: readonly TriggerSourceOperation[], diagnostics: CapabilityGraphDiagnostic[]): CapabilityGraphTriggerV1[];
|
|
14
|
+
/** Warn when `x-hapi-event` is placed on an ordinary `paths` operation. */
|
|
15
|
+
export declare function warnMisplacedEvent(source: TriggerSourceOperation, diagnostics: CapabilityGraphDiagnostic[]): void;
|
|
@@ -0,0 +1,3 @@
|
|
|
1
|
+
export { effectiveVisualizationLimits, projectCapabilityGraphVisualization, } from "./visualization";
|
|
2
|
+
export { renderCapabilityGraphVisualizationHtml } from "./visualization-renderer";
|
|
3
|
+
export { CAPABILITY_GRAPH_VISUALIZATION_LIMITS, CAPABILITY_GRAPH_VISUALIZATION_VIEWS, CapabilityGraphVisualizationError, type CapabilityGraphVisualizationBusinessStatesV1, type CapabilityGraphVisualizationDiagnosticV1, type CapabilityGraphVisualizationDocumentV1, type CapabilityGraphVisualizationEdgeV1, type CapabilityGraphVisualizationFactAuditV1, type CapabilityGraphVisualizationFactFindingV1, type CapabilityGraphVisualizationFactNodeV1, type CapabilityGraphVisualizationFilterStateV1, type CapabilityGraphVisualizationFlowCardKind, type CapabilityGraphVisualizationFlowCardV1, type CapabilityGraphVisualizationFlowCardsV1, type CapabilityGraphVisualizationFlowInputHintV1, type CapabilityGraphVisualizationFlowInputV1, type CapabilityGraphVisualizationFlowLinkSourceV1, type CapabilityGraphVisualizationFlowOtherwiseV1, type CapabilityGraphVisualizationFlowWaitV1, type CapabilityGraphVisualizationFilterValuesV1, type CapabilityGraphVisualizationLayoutV1, type CapabilityGraphVisualizationLimitsV1, type CapabilityGraphVisualizationNodeV1, type CapabilityGraphVisualizationPlanStateV1, type CapabilityGraphVisualizationPlanTraceInputV1, type CapabilityGraphVisualizationPlanTraceV1, type CapabilityGraphVisualizationRenderOptions, type CapabilityGraphVisualizationSelectionV1, type CapabilityGraphVisualizationStateRelationKind, type CapabilityGraphVisualizationStateRelationV1, type CapabilityGraphVisualizationStateTransitionNodeV1, type CapabilityGraphVisualizationTransitionV1, type CapabilityGraphVisualizationTriggerV1, type CapabilityGraphVisualizationViewName, } from "./visualization-types";
|
|
@@ -0,0 +1,163 @@
|
|
|
1
|
+
// @bun
|
|
2
|
+
var Vt=new Set(["allOf","anyOf","enum","oneOf","required"]);function it(t,a={}){return U(t,a.schema===!0,new WeakSet,void 0)}function I(t){return JSON.stringify(it(t))}function vt(t){return JSON.stringify(it(t,{schema:!0}))}async function Ct(t){let a=new TextEncoder().encode(t),e=await crypto.subtle.digest("SHA-256",a);return[...new Uint8Array(e)].map((i)=>i.toString(16).padStart(2,"0")).join("")}async function ye(t){return Ct(vt(t))}function ge(t){return`${I(t)}
|
|
3
|
+
`}function U(t,a,e,i){if(t===null||typeof t==="string"||typeof t==="boolean")return t;if(typeof t==="number")return Number.isFinite(t)?t:null;if(Array.isArray(t)){let o=t.map((l)=>U(l,a,e,i));if(a&&i&&Vt.has(i))return o.sort(wt);return o}if(!t||typeof t!=="object")return String(t);if(e.has(t))throw TypeError("Cannot canonicalize a cyclic object; use document references instead");e.add(t);let n={};for(let o of Object.keys(t).sort()){let l=t[o];if(l!==void 0)n[o]=U(l,a,e,o)}return e.delete(t),n}function wt(t,a){return JSON.stringify(t).localeCompare(JSON.stringify(a))}function B(t){return/^operation\..+\.completed$/u.test(t.predicate)}function z(t){return I(t)}function S(t){return{predicate:t.predicate,...t.value!==void 0?{value:JSON.parse(I(t.value))}:{}}}function x(t){return`viz-${[...new TextEncoder().encode(t)].map((a)=>a.toString(16).padStart(2,"0")).join("")}`}function P(t){return t.flatMap((a)=>typeof a==="string"?[a]:[]).join(" ").normalize("NFKC").toLocaleLowerCase("en-US")}function nt(t,a,e,i){if(t.kind==="authorization")return i;return e.has(t.code)||e.has(`${a}:${t.code}`)}var ot="flow-card:start",rt="flow-card:outcome",lt=(t)=>`flow-card:step:${t}`;function dt(t,a){let{result:e}=a,i=new Map(t.operations.map((u)=>[u.id,u])),n=N(a.initialFacts),o=Gt(e.steps),l=xt(o),r=kt(a),d=e.steps.map((u)=>Tt(u,{operation:ct(u,i),dependsOn:o[u.index].map((y)=>lt(y+1)),level:l[u.index],waits:u.gates.filter((y)=>r(y,u)).map(Ft),inputHint:It(t,e.steps,u,i)}));return{schemaVersion:"1",outcome:e.outcome,levelCount:d.length===0?0:Math.max(...l)+1,cards:[$t(n,N(a.goalFacts),Pt(t,n)),...d,At(e)]}}function Gt(t){return t.map((a,e)=>{let i=new Set;for(let n of a.requires){let o=Nt(t,e,z(n));if(o!==void 0)i.add(o)}for(let n=0;n<e;n++){let o=t[n];if(st(o.removes,[...a.requires,...a.produces])||st(a.removes,[...o.requires,...o.produces]))i.add(n)}return[...i].sort((n,o)=>n-o)})}function xt(t){let a=[];return t.forEach((e,i)=>{a[i]=e.length?Math.max(...e.map((n)=>a[n]))+1:0}),a}function It(t,a,e,i){let n=ct(e,i);if(!n)return;let o=zt(n),l=new Map;for(let d of a.slice(0,e.index))if(d.target.kind==="operation")l.set(d.target.id,d.index+1);let r=t.edges.filter((d)=>d.type==="operation-link"&&d.planningEligible&&d.to===n.id&&l.has(d.from)).map((d)=>({edgeIdentity:`edge:${d.id}`,fromStep:l.get(d.from),...d.label?{label:d.label}:{}})).sort((d,u)=>d.fromStep-u.fromStep||d.edgeIdentity.localeCompare(u.edgeIdentity));if(o.length===0&&r.length===0)return;return{status:r.length?"may-be-linked":"needs-input",inputs:o,links:r}}function zt(t){let a=new Map;for(let e of t.inputs){if(!e.required)continue;if(e.location!=="body"){a.set(`${e.location}:${e.name}`,{name:e.name,location:e.location});continue}let i=St(t,e.schema?.required);for(let n of i.length?i:["body"])a.set(`body:${n}`,{name:n,location:"body"})}return[...a.entries()].sort(([e],[i])=>e.localeCompare(i)).map(([,e])=>e)}function St(t,a){if(a?.length)return[...a];return[...new Set(t.bodyVariants.filter((e)=>e.required).flatMap((e)=>e.schema.required??[]))]}function kt(t){if(t.satisfiedGates&&t.principalSupplied!==void 0){let e=new Set(t.satisfiedGates),i=t.principalSupplied;return(n,o)=>!nt(n,o.transitionId,e,i)}let a=new Set(t.result.unsatisfiedGates.map((e)=>`${e.kind}:${e.code}`));return(e)=>a.has(`${e.kind}:${e.code}`)}function Ft(t){return{kind:t.kind,code:t.code,...t.detail?{detail:t.detail}:{}}}function Tt(t,a){let e=lt(t.index+1),i=a.operation?.purpose||t.target.id,n=N(t.requires),o=N(t.produces),l=N(t.removes);return{identity:e,domId:x(e),kind:"action",label:i,step:t.index+1,level:a.level,dependsOn:a.dependsOn,transitionId:t.transitionId,target:{...t.target},...a.operation?{effectMode:a.operation.effects.mode,purpose:a.operation.purpose}:{},requires:n,produces:o,removes:l,waits:a.waits,...t.outcomes?.length?{otherwise:t.outcomes.map((r)=>({status:r.status,produces:N(r.produces),removes:N(r.removes)}))}:{},...a.inputHint?{inputHint:a.inputHint}:{},searchText:P([i,t.transitionId,t.target.id,...[...n,...o,...l].map((r)=>r.predicate)])}}function Pt(t,a){let e=new Set(a.map(z));return(t.triggers??[]).filter((i)=>i.produces.some((n)=>e.has(z(n)))).map((i)=>i.id).sort((i,n)=>i.localeCompare(n))}function $t(t,a,e){return{identity:ot,domId:x(ot),kind:"start",label:"Start when the goal is requested",dependsOn:[],requires:[],produces:[],removes:[],waits:[],initialFacts:t,goalFacts:a,...e.length?{triggerIds:[...e]}:{},searchText:P(["start",...e,...[...t,...a].map((i)=>i.predicate)])}}function At(t){let a=[...new Set(t.diagnostics.map((e)=>e.code))].sort((e,i)=>e.localeCompare(i));return{identity:rt,domId:x(rt),kind:"outcome",label:`Outcome: ${t.outcome}`,dependsOn:[],requires:[],produces:[],removes:[],waits:[],outcome:t.outcome,diagnosticCodes:a,searchText:P(["outcome",t.outcome,...a])}}function ct(t,a){return t.target.kind==="operation"?a.get(t.target.id):void 0}function Nt(t,a,e){for(let i=a-1;i>=0;i--)if(t[i].produces.some((n)=>z(n)===e))return i;return}function st(t,a){let e=new Set(a.map(z));return t.some((i)=>e.has(z(i)))}function N(t){return[...new Map(t.map((a)=>[z(a),S(a)]))].sort(([a],[e])=>a.localeCompare(e)).map(([,a])=>a)}function pt(t,a=[]){let e=t.planning?.transitions??[],i=new Map,n=new Map,o=new Map,l=(s,g,c)=>{if(B(g))return;let h=z(g);i.set(h,g),s.set(h,(s.get(h)??new Set).add(c))},r=new Map;for(let s of e){for(let g of s.requires)l(n,g,s.target.id);for(let g of s.produces)l(o,g,s.target.id);for(let g of s.outcomes??[])for(let c of g.produces)l(r,c,`${s.target.id} ${g.status}`)}let d=new Map;for(let s of t.triggers??[])for(let g of s.produces)l(d,g,s.id);let u=Ot(t,a),y=new Set(u.keys()),V=(s,g)=>({fact:S(i.get(s)),label:Dt(i.get(s)),operations:[...g.get(s)].sort((c,h)=>c.localeCompare(h))}),b=j(n),p=new Set(e.map((s)=>s.target.id));return{schemaVersion:"1",orphanRequirements:b.filter((s)=>!o.has(s)&&!r.has(s)&&!d.has(s)&&!y.has(s)).map((s)=>V(s,n)),clientVerifiedFacts:b.filter((s)=>y.has(s)).map((s)=>({...V(s,n),origins:[...u.get(s)].sort()})),outcomes:j(o).filter((s)=>!n.has(s)).map((s)=>V(s,o)),responseFacts:j(r).map((s)=>V(s,r)),eventFacts:j(d).map((s)=>V(s,d)),discoveryOnlyOperations:t.operations.map((s)=>s.id).filter((s)=>!p.has(s)).sort((s,g)=>s.localeCompare(g))}}function Ot(t,a=[]){let e=new Map,i=(n,o)=>e.set(z(n),(e.get(z(n))??new Set).add(o));for(let n of t.clientFacts??[])i(n.fact,"contract");for(let n of a)i(n,"option");return e}function Ge(t,a=[]){let e=new Map;for(let i of t.clientFacts??[])e.set(z(i.fact),i.fact);for(let i of a)e.set(z(i),i);return[...e.entries()].sort(([i],[n])=>i.localeCompare(n)).map(([,i])=>S(i))}function Dt(t){return t.value===void 0?t.predicate:`${t.predicate}=${JSON.stringify(t.value)}`}function j(t){return[...t.keys()].sort((a,e)=>a.localeCompare(e))}var J=Object.freeze({maxInputBytes:16777216,maxNodes:5000,maxEdges:20000,maxPlanningTransitions:1e4,maxPlanningFacts:1e4,maxStateRelations:50000,maxPlanTraceSteps:1000,maxDiagnostics:2000,maxOutputBytes:33554432}),Y=Object.freeze(["topology","business-states","planning","plan-trace","flow-cards"]);class A extends Error{code;details;constructor(t,a,e){super(a);this.code=t;this.details=e;this.name="CapabilityGraphVisualizationError"}}function E(t){return t.value===void 0?t.predicate:`${t.predicate}=${Et(t.value)}`}function Et(t){return JSON.stringify(t)}var q=340,F=54,mt={capability:48,operation:580},W=22,M=56;function qt(t,a={}){let e=K(a.limits);ut(t,e);let i=Mt(t,e);if(a.planTrace)ut(a.planTrace,e),Ut(i,a.planTrace,e);let n=_(i.capabilities.map((f)=>f.id),"capability"),o=_(i.operations.map((f)=>f.id),"operation");for(let f of n)if(o.has(f))m("duplicate-node-id","graph.nodes");Jt(i,n,o);let l=[...i.capabilities].sort(H),r=[...i.operations].sort(H),d=[...l.map((f,G)=>Yt(f,G,i.operations)),...r.map((f,G)=>Zt(f,G,i.capabilities))],u=new Map(d.map((f)=>[f.graphId,f])),y=[...i.edges].sort(H).map((f)=>Xt(f,u)),V=i.planning?.transitions?[...i.planning.transitions].sort(H).map(Qt):void 0,b=V?te(V,e):void 0,p=a.planTrace?ie(i,a.planTrace,e):void 0,s=a.planTrace?dt(i,a.planTrace):void 0;if(s)T("maxPlanTraceSteps",s.cards.length-2,e.maxPlanTraceSteps);let g=Lt(a.initialView);a.clientVerifiedFacts?.forEach((f,G)=>D(f,`options.clientVerifiedFacts[${G}]`));let c=i.planning?pt(i,a.clientVerifiedFacts):void 0,h=[...i.diagnostics].sort((f,G)=>`${f.severity}:${f.code}:${f.operationId??""}:${f.pointer??""}`.localeCompare(`${G.severity}:${G.code}:${G.operationId??""}:${G.pointer??""}`)).map((f,G)=>ne(f,G)),k=Math.max(l.length,r.length,1);return{schemaVersion:"1",graphSchemaVersion:"1",graphFingerprint:i.fingerprint,source:re(i.source),counts:{capabilities:l.length,operations:r.length,edges:y.length,planningTransitions:V?.length??0,planningFacts:b?.counts.facts??0,businessFacts:b?.counts.businessFacts??0,technicalFacts:b?.counts.technicalFacts??0,stateRelations:b?.counts.relations??0,diagnostics:h.length},layout:{width:970,height:M*2+k*(F+W),nodeWidth:q,nodeHeight:F},nodes:d,edges:y,...V?{planning:{schemaVersion:"1",transitions:V}}:{},...b?{businessStates:b}:{},...p?{planTrace:p}:{},...s?{flowCards:s}:{},...c?{factAudit:c}:{},...i.triggers?.length?{triggers:i.triggers.map(Rt)}:{},...g?{initialView:g}:{},diagnostics:h,filters:oe(d,y,h)}}function Rt(t){return{id:t.id,kind:t.kind,name:t.name,method:t.method,...t.expression?{expression:t.expression}:{},...t.operationId?{operationId:t.operationId}:{},purpose:t.purpose,produces:t.produces.map(S)}}function Lt(t){if(t===void 0)return;if(!Y.includes(t))m("unknown-initial-view","options.initialView");return t}function K(t={}){return Object.fromEntries(Object.entries(J).map(([a,e])=>{let i=t[a];return[a,typeof i==="number"&&Number.isFinite(i)&&i>0?Math.min(Math.floor(i),e):e]}))}function ut(t,a){let e;try{e=JSON.stringify(t)}catch{m("non-json-input","graph")}let i=new TextEncoder().encode(e).byteLength;T("maxInputBytes",i,a.maxInputBytes),X(t,"graph",new WeakSet)}function X(t,a,e){if(t===null||typeof t==="string"||typeof t==="boolean")return;if(typeof t==="number"){if(!Number.isFinite(t))m("non-json-number",a);return}if(!t||typeof t!=="object")m("non-json-value",a);if(e.has(t))m("cyclic-input",a);if(e.add(t),Array.isArray(t))t.forEach((i,n)=>X(i,`${a}[${n}]`,e));else for(let[i,n]of Object.entries(t)){if(n===void 0)continue;X(n,`${a}.${i}`,e)}e.delete(t)}function Mt(t,a){let e=w(t,"graph");if(e.schemaVersion!=="1")throw new A("unsupported-graph-version","Visualization supports CapabilityGraphV1 schemaVersion '1' only",{path:"graph.schemaVersion"});if(typeof e.fingerprint!=="string"||!/^[a-f0-9]{64}$/.test(e.fingerprint))m("invalid-fingerprint","graph.fingerprint");let i=w(e.source,"graph.source");C(i.kind,"graph.source.kind"),C(i.identifier,"graph.source.identifier");let n=v(e.capabilities,"graph.capabilities"),o=v(e.operations,"graph.operations"),l=v(e.edges,"graph.edges"),r=v(e.diagnostics,"graph.diagnostics"),d=e.triggers===void 0?[]:v(e.triggers,"graph.triggers");if(T("maxNodes",n.length+o.length+d.length,a.maxNodes),d.forEach((u,y)=>Kt(u,y)),T("maxEdges",l.length,a.maxEdges),T("maxDiagnostics",r.length,a.maxDiagnostics),n.forEach((u,y)=>Bt(u,y)),o.forEach((u,y)=>jt(u,y)),l.forEach((u,y)=>Ht(u,y)),r.forEach((u,y)=>_t(u,y)),e.planning!==void 0){let u=w(e.planning,"graph.planning");if(u.schemaVersion!=="1")m("invalid-planning-version","graph.planning.schemaVersion");let y=v(u.transitions,"graph.planning.transitions");T("maxPlanningTransitions",y.length,a.maxPlanningTransitions),y.forEach((V,b)=>Wt(V,b))}return e}function Bt(t,a){let e=`graph.capabilities[${a}]`,i=w(t,e);C(i.id,`${e}.id`),C(i.label,`${e}.label`),L(i.path,`${e}.path`),ft(i.provenance,`${e}.provenance`)}function jt(t,a){let e=`graph.operations[${a}]`,i=w(t,e);C(i.id,`${e}.id`),L(i.capabilityIds,`${e}.capabilityIds`),C(i.purpose,`${e}.purpose`),L(i.useWhen,`${e}.useWhen`),L(i.avoidWhen,`${e}.avoidWhen`);let n=w(i.transport,`${e}.transport`);C(n.kind,`${e}.transport.kind`),v(i.inputs,`${e}.inputs`),v(i.bodyVariants,`${e}.bodyVariants`),v(i.outputs,`${e}.outputs`),w(i.effects,`${e}.effects`),v(i.authorization,`${e}.authorization`),L(i.prerequisites,`${e}.prerequisites`),w(i.provenance,`${e}.provenance`)}function Ht(t,a){let e=`graph.edges[${a}]`,i=w(t,e);if(C(i.id,`${e}.id`),i.type!=="capability-operation"&&i.type!=="operation-link")m("invalid-edge-type",`${e}.type`);if(C(i.from,`${e}.from`),C(i.to,`${e}.to`),typeof i.planningEligible!=="boolean")m("invalid-edge",`${e}.planningEligible`);ft(i.provenance,`${e}.provenance`)}function _t(t,a){let e=`graph.diagnostics[${a}]`,i=w(t,e);if(C(i.code,`${e}.code`),i.severity!=="warning"&&i.severity!=="error")m("invalid-diagnostic-severity",`${e}.severity`);C(i.message,`${e}.message`)}function Wt(t,a){let e=`graph.planning.transitions[${a}]`,i=w(t,e);C(i.id,`${e}.id`);let n=w(i.target,`${e}.target`);if(n.kind!=="operation"&&n.kind!=="workflow")m("invalid-target-kind",`${e}.target.kind`);C(n.id,`${e}.target.id`);for(let o of["requires","produces","removes"])v(i[o],`${e}.${o}`).forEach((l,r)=>D(l,`${e}.${o}[${r}]`));if(typeof i.cost!=="number"||!Number.isFinite(i.cost)||i.cost<0)m("invalid-transition-cost",`${e}.cost`);v(i.gates,`${e}.gates`),v(i.sources,`${e}.sources`)}function Kt(t,a){let e=`graph.triggers[${a}]`,i=w(t,e);for(let n of["id","name","method","purpose"])C(i[n],`${e}.${n}`);if(i.kind!=="webhook"&&i.kind!=="callback")m("invalid-trigger-kind",`${e}.kind`);v(i.produces,`${e}.produces`).forEach((n,o)=>D(n,`${e}.produces[${o}]`))}function Ut(t,a,e){a.initialFacts.forEach((l,r)=>D(l,`options.planTrace.initialFacts[${r}]`)),a.goalFacts.forEach((l,r)=>D(l,`options.planTrace.goalFacts[${r}]`));let i=w(a.result,"options.planTrace.result");if(i.schemaVersion!=="1")m("invalid-plan-trace-version","options.planTrace.result.schemaVersion");if(C(i.graphFingerprint,"options.planTrace.result.graphFingerprint"),!new Set(["planned","clarification-required","complete","unplannable"]).has(String(i.outcome)))m("invalid-plan-trace-outcome","options.planTrace.result.outcome");if(typeof i.totalCost!=="number"||!Number.isFinite(i.totalCost)||i.totalCost<0)m("invalid-plan-trace-cost","options.planTrace.result.totalCost");let n=v(i.steps,"options.planTrace.result.steps");T("maxPlanTraceSteps",n.length,e.maxPlanTraceSteps);let o=new Set((t.planning?.transitions??[]).map((l)=>l.id));n.forEach((l,r)=>{let d=w(l,`options.planTrace.result.steps[${r}]`);if(d.index!==r)m("invalid-plan-trace-index",`options.planTrace.result.steps[${r}].index`);let u=C(d.transitionId,`options.planTrace.result.steps[${r}].transitionId`);if(!o.has(u))m("unknown-plan-trace-transition",`options.planTrace.result.steps[${r}].transitionId`);for(let y of["requires","produces","removes"])v(d[y],`options.planTrace.result.steps[${r}].${y}`).forEach((V,b)=>D(V,`options.planTrace.result.steps[${r}].${y}[${b}]`));if(d.outcomes!==void 0)v(d.outcomes,`options.planTrace.result.steps[${r}].outcomes`).forEach((y,V)=>{let b=`options.planTrace.result.steps[${r}].outcomes[${V}]`,p=w(y,b);C(p.status,`${b}.status`);for(let s of["produces","removes"])v(p[s],`${b}.${s}`).forEach((g,c)=>D(g,`${b}.${s}[${c}]`))})}),v(i.unsatisfiedGates,"options.planTrace.result.unsatisfiedGates"),v(i.diagnostics,"options.planTrace.result.diagnostics")}function D(t,a){let e=w(t,a);C(e.predicate,`${a}.predicate`)}function ft(t,a){let e=w(t,a);if(!new Set(["extension","document","inferred"]).has(String(e.kind)))m("invalid-provenance",`${a}.kind`)}function Jt(t,a,e){let i=new Set([...a,...e]);for(let o of t.operations)for(let l of o.capabilityIds)if(!a.has(l))m("unknown-capability-reference","graph.operations.capabilityIds");_(t.edges.map((o)=>o.id),"edge");for(let o of t.edges){if(!i.has(o.from)||!i.has(o.to))m("unknown-edge-reference","graph.edges");if(o.type==="capability-operation"&&(!a.has(o.from)||!e.has(o.to)))m("invalid-membership-edge","graph.edges");if(o.type==="operation-link"&&(!e.has(o.from)||!e.has(o.to)))m("invalid-operation-link","graph.edges")}let n=t.planning?.transitions??[];_(n.map((o)=>o.id),"planning-transition");for(let o of n)if(o.target.kind==="operation"&&!e.has(o.target.id))m("unknown-transition-target","graph.planning.transitions");for(let o of t.diagnostics)if(o.operationId&&!e.has(o.operationId))m("unknown-diagnostic-operation","graph.diagnostics")}function Yt(t,a,e){let i=`capability:${t.id}`,n=e.filter((o)=>o.capabilityIds.includes(t.id)).map((o)=>`operation:${o.id}`).sort();return{identity:i,graphId:t.id,domId:x(i),kind:"capability",label:t.label,...t.description?{description:t.description}:{},taxonomy:[...t.path],provenance:R(t.provenance),relatedIdentities:n,position:{x:mt.capability,y:M+a*(F+W)},searchText:P([t.id,t.label,t.description,...t.path])}}function Zt(t,a,e){let i=`operation:${t.id}`,n=e.filter((l)=>t.capabilityIds.includes(l.id)).flatMap((l)=>l.path).filter(ce).sort(),o=t.authorization.flatMap((l)=>l.schemes.flatMap((r)=>[r.scheme,...r.scopes]));return{identity:i,graphId:t.id,domId:x(i),kind:"operation",label:t.sourceOperationId??t.id,purpose:t.purpose,taxonomy:n,...t.transport.method?{method:t.transport.method}:{},...t.transport.path?{path:t.transport.path}:{},useWhen:[...t.useWhen],avoidWhen:[...t.avoidWhen],inputs:t.inputs.map(se),bodyVariants:t.bodyVariants.map(le),outputs:t.outputs.map(de),effects:{...t.effects},authorization:t.authorization.map((l)=>({schemes:l.schemes.map((r)=>({scheme:r.scheme,scopes:[...r.scopes]}))})),prerequisites:[...t.prerequisites],fieldProvenance:Object.fromEntries(Object.entries(t.provenance).filter((l)=>Boolean(l[1])).map(([l,r])=>[l,R(r)])),provenance:R(t.provenance.identity??{kind:"inferred"}),relatedIdentities:t.capabilityIds.map((l)=>`capability:${l}`).sort(),position:{x:mt.operation,y:M+a*(F+W)},searchText:P([t.id,t.sourceOperationId,t.purpose,t.transport.method,t.transport.path,t.effects.mode,...n,...t.useWhen,...t.avoidWhen,...t.prerequisites,...o])}}function Xt(t,a){let e=a.get(t.from),i=a.get(t.to),n=`edge:${t.id}`;return{identity:n,graphId:t.id,domId:x(n),type:t.type,sourceIdentity:e.identity,targetIdentity:i.identity,path:`M ${e.position.x+q} ${e.position.y+F/2} L ${i.position.x} ${i.position.y+F/2}`,...t.label?{label:t.label}:{},planningEligible:t.planningEligible,provenance:R(t.provenance)}}function Qt(t){let a=`transition:${t.id}`;return{identity:a,graphId:t.id,domId:x(a),target:{...t.target},requires:t.requires.map(S),produces:t.produces.map(S),removes:t.removes.map(S),cost:t.cost,gates:t.gates.map((e)=>({kind:e.kind,status:e.status,code:e.code,...e.detail?{detail:e.detail}:{}})),sources:t.sources.map((e)=>({kind:e.kind,provenance:R(e.provenance)})),searchText:P([t.id,t.target.kind,t.target.id,...t.requires.map(E),...t.produces.map(E),...t.removes.map(E),...t.gates.flatMap((e)=>[e.kind,e.status,e.code,e.detail]),...t.sources.map((e)=>e.kind)])}}function te(t,a){let e=new Map,i=[];for(let p of t)for(let s of["requires","produces","removes"])for(let g of p[s]){let c=I(g);e.set(c,S(g)),i.push({kind:s,factKey:c,transition:p})}T("maxPlanningFacts",e.size,a.maxPlanningFacts),T("maxStateRelations",i.length,a.maxStateRelations);let n=[...e.keys()].sort(),o=t.map((p)=>p.identity),l=ee(n,o,i),r=n.map((p)=>{let s=e.get(p),g=Q(s),c=i.filter((h)=>h.factKey===p);return{identity:g,domId:x(g),fact:s,label:E(s),technical:B(s),position:l.get(g),producerIdentities:Z(c,"produces"),consumerIdentities:Z(c,"requires"),removerIdentities:Z(c,"removes"),searchText:P([s.predicate,E(s)])}}),d=t.map((p)=>({identity:p.identity,domId:x(`state-${p.identity}`),transitionIdentity:p.identity,label:p.target.id,position:l.get(p.identity),searchText:p.searchText})),u=i.map((p)=>ae(p,l)).sort((p,s)=>p.identity.localeCompare(s.identity)),y=Math.max(0,...[...l.values()].map((p)=>p.x)),V=Math.max(0,...[...l.values()].map((p)=>p.y)),b=r.filter((p)=>p.technical).length;return{schemaVersion:"1",facts:r,transitions:d,relations:u,layout:{width:Math.max(970,y+q+48),height:Math.max(240,V+F+M),nodeWidth:q,nodeHeight:F},counts:{facts:r.length,businessFacts:r.length-b,technicalFacts:b,relations:u.length}}}function ee(t,a,e){let i=new Map(t.map((c)=>[c,Q(JSON.parse(c))])),n=[...i.values(),...a].sort(),o=new Map(n.map((c)=>[c,[]])),l=new Map(n.map((c)=>[c,0]));for(let c of e){let h=i.get(c.factKey),k=c.transition.identity,[f,G]=c.kind==="requires"?[h,k]:[k,h];o.get(f).push(G),l.set(G,(l.get(G)??0)+1)}for(let c of o.values())c.sort();let r=new Map(n.map((c)=>[c,0])),d=n.filter((c)=>l.get(c)===0).sort(),u=new Set;while(d.length){let c=d.shift();u.add(c);for(let h of o.get(c)??[])if(r.set(h,Math.max(r.get(h)??0,(r.get(c)??0)+1)),l.set(h,(l.get(h)??0)-1),l.get(h)===0)d.push(h),d.sort()}let y=Math.max(0,...[...u].map((c)=>r.get(c)??0)),V=n.filter((c)=>!u.has(c)),b=V.filter((c)=>c.startsWith("fact:")),p=V.filter((c)=>c.startsWith("transition:"));for(let c of b)r.set(c,y+1);for(let c of p)r.set(c,y+2);let s=new Map;for(let c of n){let h=r.get(c)??0,k=s.get(h)??[];k.push(c),s.set(h,k)}let g=new Map;for(let[c,h]of[...s].sort(([k],[f])=>k-f))h.sort(),h.forEach((k,f)=>g.set(k,{x:48+c*390,y:M+f*(F+W)}));return g}function ae(t,a){let e=Q(JSON.parse(t.factKey)),i=t.transition.identity,[n,o]=t.kind==="requires"?[e,i]:[i,e],l=a.get(n),r=a.get(o),d=`state-relation:${t.kind}:${i}:${t.factKey}`;return{identity:d,domId:x(d),kind:t.kind,factIdentity:e,transitionIdentity:i,sourceIdentity:n,targetIdentity:o,path:`M ${l.x+q/2} ${l.y+F/2} L ${r.x+q/2} ${r.y+F/2}`,sources:t.transition.sources.map((u)=>({kind:u.kind,provenance:R(u.provenance)}))}}function Z(t,a){return O(t.filter((e)=>e.kind===a).map((e)=>e.transition.identity))}function Q(t){return`fact:${I(t)}`}function ie(t,a,e){if(a.result.graphFingerprint!==t.fingerprint)m("plan-trace-fingerprint-mismatch","options.planTrace.result.graphFingerprint");T("maxPlanTraceSteps",a.result.steps.length,e.maxPlanTraceSteps);let i=yt(a.initialFacts),n=yt(a.goalFacts),o=i,l=[{identity:"plan-state:0",domId:x("plan-state:0"),index:0,label:"Initial state",facts:o,added:o,removed:[]}];for(let r of a.result.steps){let d=new Map(o.map((p)=>[I(p),p])),u=new Map(d);for(let p of r.removes)u.delete(I(p));for(let p of r.produces)u.set(I(p),S(p));o=[...u.entries()].sort(([p],[s])=>p.localeCompare(s)).map(([,p])=>p);let y=o.filter((p)=>!d.has(I(p))),V=[...d.entries()].filter(([p])=>!u.has(p)).sort(([p],[s])=>p.localeCompare(s)).map(([,p])=>p),b=`plan-state:${r.index+1}`;l.push({identity:b,domId:x(b),index:r.index+1,label:`After ${r.transitionId}`,facts:o,added:y,removed:V,transitionId:r.transitionId,target:{...r.target}})}return{schemaVersion:"1",outcome:a.result.outcome,graphFingerprint:a.result.graphFingerprint,initialFacts:i,goalFacts:n,totalCost:a.result.totalCost,states:l,unsatisfiedGates:a.result.unsatisfiedGates.map((r)=>({...r})),diagnostics:a.result.diagnostics.map((r)=>({code:r.code,severity:r.severity,message:r.message,...r.pointer?{pointer:r.pointer}:{},...r.operationId?{operationId:r.operationId}:{}}))}}function yt(t){return[...new Map(t.map((a)=>[I(a),S(a)])).entries()].sort(([a],[e])=>a.localeCompare(e)).map(([,a])=>a)}function ne(t,a){let e=`diagnostic:${a}:${t.code}`;return{identity:e,domId:x(e),code:t.code,severity:t.severity,message:t.message,...t.pointer?{pointer:t.pointer}:{},...t.operationId?{operationIdentity:`operation:${t.operationId}`}:{}}}function oe(t,a,e){return{taxonomy:O(t.flatMap((i)=>i.taxonomy)),methods:O(t.flatMap((i)=>i.method?[i.method.toUpperCase()]:[])),effects:O(t.flatMap((i)=>i.effects?[i.effects.mode]:[])),provenanceKinds:O(t.map((i)=>i.provenance.kind)),diagnosticSeverities:O(e.map((i)=>i.severity)),edgeTypes:O(a.map((i)=>i.type))}}function re(t){return{kind:t.kind,identifier:gt(t.identifier),...t.canonicalUri?{canonicalUri:gt(t.canonicalUri)}:{},...t.documentVersion?{documentVersion:t.documentVersion}:{},...t.title?{title:t.title}:{},...t.version?{version:t.version}:{}}}function gt(t){if(/^file:/i.test(t)||t.startsWith("/")||/^[A-Za-z]:[\\/]/.test(t))return t.split(/[\\/]/).filter(Boolean).at(-1)??"local-source";return t}function se(t){return{name:t.name,location:t.location,required:t.required,...t.description?{description:t.description}:{},...t.schema?{schema:tt(t.schema)}:{}}}function le(t){return{id:t.id,mediaType:t.mediaType,required:t.required,...t.title?{title:t.title}:{},schemaHash:t.schemaHash,schema:tt(t.schema)}}function de(t){return{status:t.status,description:t.description,mediaTypes:[...t.mediaTypes],fields:[...t.fields]}}function tt(t){return{...t.ref?{ref:t.ref}:{},...t.type?{type:t.type}:{},...t.format?{format:t.format}:{},...t.title?{title:t.title}:{},...t.description?{description:t.description}:{},...t.enum?{enum:[...t.enum]}:{},...t.required?{required:[...t.required]}:{},...t.properties?{properties:[...t.properties]}:{},...t.items?{items:tt(t.items)}:{}}}function R(t){return{kind:t.kind,...t.pointer?{pointer:t.pointer}:{},...t.detail?{detail:t.detail}:{}}}function O(t){return[...new Set(t)].sort((a,e)=>a.localeCompare(e))}function ce(t,a,e){return e.indexOf(t)===a}function _(t,a){let e=new Set;for(let i of t){if(e.has(i))m(`duplicate-${a}-id`,`graph.${a}`);e.add(i)}return e}function H(t,a){return t.id.localeCompare(a.id)}function T(t,a,e){if(a<=e)return;throw new A("visualization-limit-exceeded",`Visualization ${t} exceeded: ${a} > ${e}`,{limit:t,count:a,maximum:e})}function m(t,a){throw new A(t,`Capability graph is invalid for visualization at ${a}`,{path:a})}function w(t,a){if(!t||typeof t!=="object"||Array.isArray(t))m("expected-object",a);return t}function v(t,a){if(!Array.isArray(t))m("expected-array",a);return t}function C(t,a){if(typeof t!=="string"||t.length===0)m("expected-string",a);return t}function L(t,a){return v(t,a).map((e,i)=>C(e,`${a}[${i}]`))}var et=String.raw`
|
|
4
|
+
:root{color-scheme:light dark;font-family:Inter,ui-sans-serif,system-ui,-apple-system,BlinkMacSystemFont,"Segoe UI",sans-serif;background:#07111f;color:#e5edf8;--panel:#101d2d;--panel2:#17263a;--line:#4d6a8a;--accent:#55d6be;--accent2:#f3b95f;--danger:#ff7b89;--muted:#9db0c7;--focus:#fff36b}*{box-sizing:border-box}body{margin:0;min-width:320px;background:radial-gradient(circle at top left,#17304b 0,#07111f 42rem);color:#e5edf8}button,input,select{font:inherit}button,select,input{border:1px solid #496783;border-radius:.45rem;background:#102238;color:inherit;padding:.55rem .7rem}button{cursor:pointer}button:hover{border-color:var(--accent)}:focus-visible{outline:3px solid var(--focus);outline-offset:2px}header{padding:1.2rem 1.4rem;border-bottom:1px solid #29415c;background:#091625ee;position:sticky;top:0;z-index:5}h1{font-size:1.35rem;margin:0 0 .35rem}.notice{color:var(--accent);font-weight:700}.meta{color:var(--muted);font-size:.9rem;overflow-wrap:anywhere}.shell{display:grid;grid-template-columns:minmax(15rem,20rem) minmax(0,1fr);min-height:calc(100vh - 7rem)}aside{padding:1rem;border-right:1px solid #29415c;background:#091625}.filters{display:grid;gap:.75rem}.filters label{display:grid;gap:.3rem;font-size:.85rem;color:var(--muted)}.filter-actions{display:flex;gap:.5rem}.content{min-width:0;padding:1rem}.tabs{display:flex;gap:.5rem;margin-bottom:1rem}.tabs button[aria-selected=true]{background:var(--accent);border-color:var(--accent);color:#06131f;font-weight:800}.view[hidden]{display:none}.topology-grid{display:grid;grid-template-columns:minmax(0,2fr) minmax(17rem,1fr);gap:1rem}.panel{background:var(--panel);border:1px solid #29415c;border-radius:.7rem;padding:1rem;min-width:0}.canvas{overflow:auto;max-height:68vh}.graph-svg{min-width:60rem;background:#0a1726;border-radius:.5rem}.edge{fill:none;stroke:var(--line);stroke-width:2}.edge.operation-link{stroke-dasharray:8 5}.edge.eligible{stroke:var(--accent2);stroke-width:3}.node rect{fill:var(--panel2);stroke:#52708e;stroke-width:2;rx:8}.node.capability rect{stroke:var(--accent)}.node.operation rect{stroke:var(--accent2)}.node:focus rect,.node.selected rect{stroke:var(--focus);stroke-width:4}.node text{fill:currentColor;font-size:13px;pointer-events:none}.item-list,.planning-list,.diagnostic-list{list-style:none;padding:0;margin:.5rem 0;display:grid;gap:.35rem}.item-list button,.planning-list button,.diagnostic-list button{width:100%;text-align:left}.item-list button[aria-current=true],.planning-list button[aria-current=true],.diagnostic-list button[aria-current=true]{border-color:var(--focus);background:#27374b}.badge{display:inline-block;border:1px solid #54708c;border-radius:999px;padding:.1rem .45rem;margin:.1rem .2rem .1rem 0;font-size:.75rem;color:var(--muted)}.badge.warning{border-color:var(--accent2);color:var(--accent2)}.badge.error{border-color:var(--danger);color:var(--danger)}.details{overflow-wrap:anywhere}.details dl{display:grid;grid-template-columns:minmax(7rem,auto) 1fr;gap:.45rem .75rem}.details dt{color:var(--muted);font-weight:700}.details dd{margin:0;white-space:pre-wrap}.empty{color:var(--muted);font-style:italic}.status{min-height:1.5rem;color:var(--muted)}.counts{display:flex;flex-wrap:wrap;gap:.5rem;margin:.7rem 0}.count{background:#13243a;border-radius:.4rem;padding:.35rem .55rem}.sr-only{position:absolute!important;width:1px!important;height:1px!important;padding:0!important;margin:-1px!important;overflow:hidden!important;clip:rect(0,0,0,0)!important;white-space:nowrap!important;border:0!important}@media(max-width:900px){.shell{grid-template-columns:1fr}aside{border-right:0;border-bottom:1px solid #29415c}.topology-grid{grid-template-columns:1fr}.canvas{max-height:50vh}}@media(prefers-reduced-motion:reduce){*,*::before,*::after{scroll-behavior:auto!important;transition:none!important;animation:none!important}}@media(forced-colors:active){.edge,.edge.eligible{stroke:CanvasText}.node rect,.node.capability rect,.node.operation rect{fill:Canvas;stroke:CanvasText}.node:focus rect,.node.selected rect{stroke:Highlight}.notice{color:CanvasText}}
|
|
5
|
+
.technical-toggle{display:flex;align-items:center;gap:.5rem;margin:.5rem 0 1rem;color:var(--muted)}.technical-toggle input{width:auto}.state-relation{fill:none;stroke-width:2}.state-relation.requires{stroke:#7fb5ff}.state-relation.produces{stroke:var(--accent);marker-end:url(#state-arrow)}.state-relation.removes{stroke:var(--danger);stroke-dasharray:7 5;marker-end:url(#state-remove-arrow)}.state-node.fact rect{stroke:#7fb5ff}.state-node.transition rect{stroke:var(--accent2);stroke-width:3}.state-node.technical rect{stroke-dasharray:6 4}.state-node text{fill:currentColor;font-size:13px;pointer-events:none}.state-node:focus rect,.state-node.selected rect{stroke:var(--focus);stroke-width:4}.legend{display:flex;flex-wrap:wrap;gap:1rem;color:var(--muted)}.trace-state{border-left:4px solid var(--accent);padding:.7rem;margin:.5rem 0;background:var(--panel2)}.trace-state h3{margin:.1rem 0 .45rem}.outcome{display:inline-block;text-transform:uppercase;font-weight:800;border:1px solid var(--accent);border-radius:999px;padding:.15rem .5rem}.outcome.unplannable{border-color:var(--danger);color:var(--danger)}.outcome.clarification-required{border-color:var(--accent2);color:var(--accent2)}
|
|
6
|
+
.flow-cards{display:grid;gap:.4rem;justify-items:center;padding:1rem;border:1px solid #29415c;border-radius:.6rem;background:#0b1828}.flow-level{display:flex;flex-wrap:wrap;justify-content:center;gap:.9rem;width:100%}.flow-level-label{color:var(--muted);font-size:.75rem;text-transform:uppercase;letter-spacing:.06em}.flow-then{color:var(--accent);font-size:.8rem}.flow-card{width:min(100%,19rem);border:1px solid var(--line);border-radius:.55rem;background:var(--panel);text-align:left;cursor:pointer}.flow-card.selected{outline:3px solid var(--focus)}.flow-card.dim{opacity:.45}.flow-card header{position:static;display:flex;gap:.5rem;align-items:center;padding:.5rem .75rem;border-bottom:1px solid var(--line);background:var(--panel2);font-weight:700;font-size:.85rem}.flow-card .flow-body{display:grid;gap:.35rem;padding:.6rem .75rem;font-size:.85rem}.flow-card.flow-start header,.flow-card.flow-outcome header{color:var(--accent)}.flow-card .wait{color:var(--accent2);font-weight:700}.flow-card .inputs{color:var(--muted)}.flow-card .trigger{color:var(--accent);font-weight:700}.flow-card .otherwise{color:var(--danger);border-left:3px dashed var(--danger);padding-left:.4rem}.flow-card .facts{display:flex;flex-wrap:wrap;gap:.25rem}.flow-card .fact{font-family:ui-monospace,monospace;font-size:.72rem;padding:.12rem .35rem;border-radius:.25rem;background:#1d3048}.flow-card .op{font-family:ui-monospace,monospace;font-size:.75rem;color:var(--muted);overflow-wrap:anywhere}.flow-gaps{display:grid;gap:.6rem;margin-top:1rem}.flow-gap{border:1px dashed var(--danger);border-radius:.5rem;padding:.6rem .8rem}.flow-gap h3{margin:.1rem 0 .4rem;font-size:.9rem;color:var(--danger)}.flow-gap.info{border-color:var(--line)}.flow-gap.info h3{color:var(--muted)}@media (prefers-reduced-motion:reduce){*{transition:none!important;animation:none!important}}
|
|
7
|
+
`,at=String.raw`
|
|
8
|
+
"use strict";
|
|
9
|
+
(()=>{
|
|
10
|
+
const byId=id=>document.getElementById(id);
|
|
11
|
+
const text=(tag,value,className)=>{const node=document.createElement(tag);if(className)node.className=className;node.textContent=String(value);return node};
|
|
12
|
+
const svg=(tag,attrs={})=>{const node=document.createElementNS("http://www.w3.org/2000/svg",tag);for(const [key,value] of Object.entries(attrs))node.setAttribute(key,String(value));return node};
|
|
13
|
+
const decodeData=()=>{const encoded=byId("visualization-data").textContent.trim();const binary=atob(encoded);const bytes=Uint8Array.from(binary,char=>char.charCodeAt(0));return JSON.parse(new TextDecoder().decode(bytes))};
|
|
14
|
+
const data=decodeData();
|
|
15
|
+
const nodesByIdentity=new Map(data.nodes.map(node=>[node.identity,node]));
|
|
16
|
+
const transitionsByIdentity=new Map((data.planning?.transitions??[]).map(item=>[item.identity,item]));
|
|
17
|
+
const factsByIdentity=new Map((data.businessStates?.facts??[]).map(item=>[item.identity,item]));
|
|
18
|
+
const planStatesByIdentity=new Map((data.planTrace?.states??[]).map(item=>[item.identity,item]));
|
|
19
|
+
const diagnosticsByIdentity=new Map(data.diagnostics.map(item=>[item.identity,item]));
|
|
20
|
+
const triggersById=new Map((data.triggers??[]).map(item=>[item.id,item]));
|
|
21
|
+
const triggerText=trigger=>trigger.kind+" "+trigger.name+" ("+trigger.method.toUpperCase()+")";
|
|
22
|
+
const flowCardsByIdentity=new Map((data.flowCards?.cards??[]).map(item=>[item.identity,item]));
|
|
23
|
+
const factText=fact=>fact.value===undefined?fact.predicate:fact.predicate+"="+JSON.stringify(fact.value);
|
|
24
|
+
const state={selected:null,view:"topology"};
|
|
25
|
+
const controls={query:byId("query"),kind:byId("node-kind"),taxonomy:byId("taxonomy"),method:byId("method"),effect:byId("effect"),authorization:byId("authorization"),provenance:byId("provenance"),severity:byId("severity"),edgeType:byId("edge-type"),eligibility:byId("planning-eligibility")};
|
|
26
|
+
const normalize=value=>String(value??"").normalize("NFKC").toLocaleLowerCase("en-US");
|
|
27
|
+
const addOptions=(select,values)=>{for(const value of values){const option=text("option",value);option.value=value;select.append(option)}};
|
|
28
|
+
addOptions(controls.taxonomy,data.filters.taxonomy);addOptions(controls.method,data.filters.methods);addOptions(controls.effect,data.filters.effects);addOptions(controls.provenance,data.filters.provenanceKinds);addOptions(controls.severity,data.filters.diagnosticSeverities);addOptions(controls.edgeType,data.filters.edgeTypes);
|
|
29
|
+
byId("graph-meta").textContent="Graph V"+data.graphSchemaVersion+" \u00B7 "+data.graphFingerprint+" \u00B7 "+data.source.identifier;
|
|
30
|
+
const counts=byId("counts");for(const [name,value] of Object.entries(data.counts))counts.append(text("span",name+": "+value,"count"));
|
|
31
|
+
const nodeMatches=node=>{const tokens=normalize(controls.query.value).split(/\s+/).filter(Boolean);return tokens.every(token=>node.searchText.includes(token))&&(!controls.kind.value||node.kind===controls.kind.value)&&(!controls.taxonomy.value||node.taxonomy.includes(controls.taxonomy.value))&&(!controls.method.value||normalize(node.method)===normalize(controls.method.value))&&(!controls.effect.value||node.effects?.mode===controls.effect.value)&&(!controls.authorization.value||(controls.authorization.value==="required")===(node.authorization?.length>0))&&(!controls.provenance.value||node.provenance.kind===controls.provenance.value)};
|
|
32
|
+
const queryMatches=item=>normalize(item.searchText).includes(normalize(controls.query.value));
|
|
33
|
+
const edgeMatches=edge=>(!controls.edgeType.value||edge.type===controls.edgeType.value)&&(!controls.eligibility.value||(controls.eligibility.value==="eligible")===edge.planningEligible);
|
|
34
|
+
const diagnosticMatches=item=>!controls.severity.value||item.severity===controls.severity.value;
|
|
35
|
+
const itemButton=(item,label)=>{const button=text("button",label);button.type="button";button.dataset.identity=item.identity;button.setAttribute("aria-current",String(state.selected===item.identity));button.addEventListener("click",()=>selectIdentity(item.identity));return button};
|
|
36
|
+
const addDetail=(list,label,value)=>{if(value===undefined||value===null||value===""||(Array.isArray(value)&&value.length===0))return;list.append(text("dt",label),text("dd",Array.isArray(value)?value.map(entry=>typeof entry==="object"?JSON.stringify(entry):String(entry)).join("\n"):typeof value==="object"?JSON.stringify(value,null,2):value))};
|
|
37
|
+
const selectIdentity=(identity,updateHash=true)=>{state.selected=identity;for(const button of document.querySelectorAll("[data-identity]"))button.setAttribute("aria-current",String(button.dataset.identity===identity));for(const node of document.querySelectorAll(".node,.state-node,.flow-card"))node.classList.toggle("selected",node.dataset.identity===identity);renderDetails(identity);if(updateHash)history.replaceState(null,"","#item="+encodeURIComponent(identity))};
|
|
38
|
+
const renderDetails=identity=>{const target=byId("details");target.replaceChildren();const node=nodesByIdentity.get(identity),transition=transitionsByIdentity.get(identity),fact=factsByIdentity.get(identity),planState=planStatesByIdentity.get(identity),card=flowCardsByIdentity.get(identity),diagnostic=diagnosticsByIdentity.get(identity);const item=node??transition??fact??planState??card??diagnostic;if(!item){target.append(text("p",identity?"Selection is unavailable in this graph.":"Select an item to inspect its safe graph metadata.","empty"));byId("status").textContent=identity?"Requested selection is unavailable.":"";return}const title=node?(node.label||node.graphId):transition?transition.graphId:fact?fact.label:planState?planState.label:card?card.label:diagnostic.code;target.append(text("h2",title));const list=document.createElement("dl");addDetail(list,"Identity",item.identity);if(node){addDetail(list,"Kind",node.kind);addDetail(list,"Purpose",node.purpose);addDetail(list,"Description",node.description);addDetail(list,"Taxonomy",node.taxonomy);addDetail(list,"Transport",[node.method,node.path].filter(Boolean).join(" "));addDetail(list,"Use when",node.useWhen);addDetail(list,"Avoid when",node.avoidWhen);addDetail(list,"Inputs",node.inputs);addDetail(list,"Body variants",node.bodyVariants);addDetail(list,"Outputs",node.outputs);addDetail(list,"Effects",node.effects);addDetail(list,"Authorization",node.authorization);addDetail(list,"Prerequisites",node.prerequisites);addDetail(list,"Related",node.relatedIdentities);addDetail(list,"Provenance",node.provenance);addDetail(list,"Field provenance",node.fieldProvenance)}else if(transition){addDetail(list,"Target",transition.target);addDetail(list,"Requires",transition.requires);addDetail(list,"Produces",transition.produces);addDetail(list,"Removes",transition.removes);addDetail(list,"Cost",transition.cost);addDetail(list,"Gates",transition.gates);addDetail(list,"Sources",transition.sources)}else if(fact){addDetail(list,"Predicate",fact.fact.predicate);addDetail(list,"Value",fact.fact.value);addDetail(list,"Technical",fact.technical);addDetail(list,"Produced by",fact.producerIdentities);addDetail(list,"Required by",fact.consumerIdentities);addDetail(list,"Removed by",fact.removerIdentities);const provenance=(data.businessStates?.relations??[]).filter(relation=>relation.factIdentity===fact.identity).map(relation=>({relationship:relation.kind,transition:relation.transitionIdentity,sources:relation.sources}));addDetail(list,"Relationship provenance",provenance)}else if(planState){addDetail(list,"Step",planState.index);addDetail(list,"Transition",planState.transitionId);addDetail(list,"Target",planState.target);addDetail(list,"Facts",planState.facts);addDetail(list,"Added",planState.added);addDetail(list,"Removed",planState.removed)}else if(card){addDetail(list,"Card kind",card.kind);addDetail(list,"Planner step",card.step);addDetail(list,"Dependency level",card.level);addDetail(list,"Depends on",card.dependsOn);addDetail(list,"Transition",card.transitionId);addDetail(list,"Target",card.target);addDetail(list,"Effect",card.effectMode);addDetail(list,"Requires",card.requires.map(factText));addDetail(list,"Produces",card.produces.map(factText));addDetail(list,"Removes",card.removes.map(factText));addDetail(list,"Waits",card.waits.map(wait=>wait.kind+": "+wait.code));addDetail(list,"Otherwise",(card.otherwise??[]).map(branch=>branch.status+": +"+branch.produces.map(factText).join(",")+" \u2212"+branch.removes.map(factText).join(",")));addDetail(list,"Input hint",card.inputHint);addDetail(list,"Initial facts",(card.initialFacts??[]).map(factText));addDetail(list,"Start triggers",card.triggerIds);addDetail(list,"Goal facts",(card.goalFacts??[]).map(factText));addDetail(list,"Outcome",card.outcome);addDetail(list,"Diagnostics",card.diagnosticCodes)}else{addDetail(list,"Severity",diagnostic.severity);addDetail(list,"Message",diagnostic.message);addDetail(list,"Pointer",diagnostic.pointer);addDetail(list,"Operation",diagnostic.operationIdentity)}target.append(list);byId("status").textContent="Selected "+item.identity};
|
|
39
|
+
const selectableSvgNode=(item,className,label,layout)=>{const group=svg("g",{id:item.domId,class:className,role:"button",tabindex:"0","data-identity":item.identity,"aria-label":label});const title=svg("title");title.textContent=label;const rect=svg("rect",{x:item.position.x,y:item.position.y,width:layout.nodeWidth,height:layout.nodeHeight,rx:8});const caption=svg("text",{x:item.position.x+14,y:item.position.y+32});caption.textContent=label.length>42?label.slice(0,39)+"\u2026":label;group.append(title,rect,caption);group.addEventListener("click",()=>selectIdentity(item.identity));group.addEventListener("keydown",event=>{if(event.key==="Enter"||event.key===" "){event.preventDefault();selectIdentity(item.identity)}});return group};
|
|
40
|
+
const renderTopology=()=>{const visible=data.nodes.filter(nodeMatches);const visibleIds=new Set(visible.map(node=>node.identity));const edges=data.edges.filter(edge=>visibleIds.has(edge.sourceIdentity)&&visibleIds.has(edge.targetIdentity)&&edgeMatches(edge));const canvas=byId("graph");canvas.replaceChildren();canvas.setAttribute("viewBox","0 0 "+data.layout.width+" "+data.layout.height);for(const edge of edges)canvas.append(svg("path",{d:edge.path,class:"edge "+edge.type+" "+(edge.planningEligible?"eligible":"descriptive"),"aria-hidden":"true"}));for(const node of visible)canvas.append(selectableSvgNode(node,"node "+node.kind,node.kind+": "+node.label,data.layout));const list=byId("item-list");list.replaceChildren();for(const node of visible){const item=document.createElement("li");item.append(itemButton(node,node.kind+": "+node.label+" \u00B7 related "+node.relatedIdentities.length));list.append(item)}byId("topology-summary").textContent=visible.length+" nodes and "+edges.length+" edges visible. Inspection results do not imply authorization or execution eligibility."};
|
|
41
|
+
const renderBusinessStates=()=>{const model=data.businessStates,list=byId("state-item-list"),canvas=byId("state-graph");list.replaceChildren();canvas.replaceChildren();if(!model){list.append(text("li","This graph has no planning section.","empty"));byId("business-states-summary").textContent="No validated business-state transitions are present.";return}const showTechnical=byId("show-technical-facts").checked;const facts=model.facts.filter(fact=>(showTechnical||!fact.technical)&&queryMatches(fact));const factIds=new Set(facts.map(fact=>fact.identity));const transitions=model.transitions.filter(queryMatches);const transitionIds=new Set(transitions.map(item=>item.identity));const relations=model.relations.filter(relation=>factIds.has(relation.factIdentity)&&transitionIds.has(relation.transitionIdentity));canvas.setAttribute("viewBox","0 0 "+model.layout.width+" "+model.layout.height);const defs=svg("defs"),arrow=svg("marker",{id:"state-arrow",markerWidth:8,markerHeight:8,refX:7,refY:3,orient:"auto"}),arrowPath=svg("path",{d:"M0,0 L0,6 L7,3 z",fill:"currentColor"}),removeArrow=svg("marker",{id:"state-remove-arrow",markerWidth:9,markerHeight:9,refX:8,refY:4,orient:"auto"}),removePath=svg("path",{d:"M1,1 L7,7 M7,1 L1,7",stroke:"currentColor","stroke-width":2});arrow.append(arrowPath);removeArrow.append(removePath);defs.append(arrow,removeArrow);canvas.append(defs);for(const relation of relations)canvas.append(svg("path",{d:relation.path,class:"state-relation "+relation.kind,"aria-label":relation.kind+" relationship"}));for(const fact of facts)canvas.append(selectableSvgNode(fact,"state-node fact "+(fact.technical?"technical":"business"),"fact: "+fact.label,model.layout));for(const transition of transitions)canvas.append(selectableSvgNode(transition,"state-node transition","transition: "+transition.label,model.layout));for(const fact of facts){const item=document.createElement("li");item.append(itemButton(fact,(fact.technical?"technical fact: ":"fact: ")+fact.label));list.append(item)}for(const transition of transitions){const item=document.createElement("li");item.append(itemButton(transition,"transition: "+transition.label));list.append(item)}byId("business-states-summary").textContent=facts.length+" of "+model.counts.facts+" facts and "+relations.length+" typed relations visible; "+model.counts.technicalFacts+" technical facts "+(showTechnical?"shown.":"hidden.")};
|
|
42
|
+
const renderPlanning=()=>{const list=byId("planning-list");list.replaceChildren();const transitions=(data.planning?.transitions??[]).filter(queryMatches);if(!data.planning){list.append(text("li","This graph has no planning section.","empty"))}else if(!transitions.length){list.append(text("li","No planning transitions match the current text query.","empty"))}else for(const transition of transitions){const item=document.createElement("li");item.append(itemButton(transition,transition.graphId+" \u2192 "+transition.target.kind+":"+transition.target.id+" \u00B7 cost "+transition.cost));list.append(item)}byId("planning-summary").textContent=data.planning?transitions.length+" validated transitions shown separately from descriptive topology. Display does not imply authorization, confirmation, or execution.":"No validated planning transitions are present."};
|
|
43
|
+
const renderPlanTrace=()=>{const list=byId("plan-trace-list"),trace=data.planTrace;list.replaceChildren();if(!trace){list.append(text("li","No plan trace was requested when this artifact was generated.","empty"));byId("plan-trace-summary").textContent="Generate with --goal-fact and optional simulation inputs to embed an exact trace.";return}const summary=byId("plan-trace-summary");summary.replaceChildren();summary.append(text("span",trace.outcome,"outcome "+trace.outcome),text("span"," \u00B7 cost "+trace.totalCost+" \u00B7 "+trace.states.length+" state snapshots"));for(const planState of trace.states){const item=document.createElement("li");item.className="trace-state";item.append(itemButton(planState,planState.label+" \u00B7 "+planState.facts.length+" facts"));const changes=text("p","Added: "+(planState.added.map(fact=>fact.predicate).join(", ")||"-")+" \u00B7 Removed: "+(planState.removed.map(fact=>fact.predicate).join(", ")||"-"),"status");item.append(changes);list.append(item)}if(trace.unsatisfiedGates.length)list.append(text("li","Unsatisfied gates: "+trace.unsatisfiedGates.map(gate=>gate.code).join(", "),"empty"));if(trace.diagnostics.length)list.append(text("li","Diagnostics: "+trace.diagnostics.map(entry=>entry.code).join(", "),"empty"))};
|
|
44
|
+
const isTechnicalFact=fact=>/^operation\..+\.completed$/.test(fact.predicate);
|
|
45
|
+
const factChips=(label,allFacts)=>{const facts=allFacts.filter(fact=>!isTechnicalFact(fact));if(!facts.length)return null;const row=text("div","","facts");row.append(text("span",label));for(const fact of facts)row.append(text("span",factText(fact),"fact"));return row};
|
|
46
|
+
const inputHintText=hint=>{const names=hint.inputs.map(input=>input.name+" ("+input.location+")").join(", ");if(hint.status==="needs-input")return"Needs input: "+names;const sources=hint.links.map(link=>(link.label||link.edgeIdentity)+" from step "+link.fromStep).join("; ");return"May be supplied by link "+sources+(names?": "+names:"")};
|
|
47
|
+
const flowCardNode=card=>{const node=document.createElement("article");node.id=card.domId;node.className="flow-card flow-"+card.kind;node.tabIndex=0;node.dataset.identity=card.identity;node.setAttribute("role","button");const heading=card.kind==="start"?"Start when":card.kind==="outcome"?"Outcome":(card.waits.length?"Wait, then do this":"Do this");const header=document.createElement("header");header.append(text("span",card.kind==="action"?"Step "+card.step+" \u00B7 "+heading:heading));node.setAttribute("aria-label",(card.kind==="action"?"Step "+card.step+": ":"")+card.label);const body=text("div","","flow-body");body.append(text("span",card.label));if(card.kind==="start"){for(const id of card.triggerIds??[]){const trigger=triggersById.get(id);if(trigger)body.append(text("span","Can start when declared "+triggerText(trigger)+" is received by the client","trigger"))}for(const row of [factChips("Goal",card.goalFacts),factChips("Known",card.initialFacts)])if(row)body.append(row)}else if(card.kind==="outcome"){body.append(text("span",card.outcome==="planned"||card.outcome==="complete"?"The goal is reachable with this plan.":"The goal is not reached: "+card.outcome+".","status"));if(card.diagnosticCodes.length)body.append(text("span","Diagnostics: "+card.diagnosticCodes.join(", "),"op"))}else{body.append(text("span",card.target.kind+":"+card.target.id+(card.effectMode?" \u00B7 "+card.effectMode:""),"op"));for(const wait of card.waits)body.append(text("span","Wait for "+wait.kind+": "+wait.code,"wait"));if(card.inputHint)body.append(text("span",inputHintText(card.inputHint),"inputs"));for(const branch of card.otherwise??[]){const parts=[branch.produces.length?"adds "+branch.produces.map(factText).join(", "):"",branch.removes.length?"removes "+branch.removes.map(factText).join(", "):""].filter(Boolean).join("; ");body.append(text("span","Otherwise ("+branch.status+"): "+parts+". The client re-plans.","otherwise"))}for(const row of [factChips("Needs",card.requires),factChips("Adds",card.produces),factChips("Removes",card.removes)])if(row)body.append(row)}node.append(header,body);node.addEventListener("click",()=>selectIdentity(card.identity));node.addEventListener("keydown",event=>{if(event.key==="Enter"||event.key===" "){event.preventDefault();selectIdentity(card.identity)}});return node};
|
|
48
|
+
const candidateGoals=()=>(data.businessStates?.facts??[]).filter(fact=>!fact.technical&&fact.producerIdentities.length&&!fact.consumerIdentities.length).map(fact=>fact.label);
|
|
49
|
+
const renderFlowGaps=()=>{const target=byId("flow-gaps");target.replaceChildren();const audit=data.factAudit;if(!audit)return;const section=(title,entries,describe,className)=>{if(!entries.length)return;const box=text("section","","flow-gap "+className);box.append(text("h3",title));const list=document.createElement("ul");for(const entry of entries)list.append(text("li",describe(entry)));box.append(list);target.append(box)};section("Required but never produced",audit.orphanRequirements,entry=>entry.label+" \u00B7 required by "+entry.operations.join(", "),"orphan");section("Client-verified facts",audit.clientVerifiedFacts,entry=>entry.label+" \u00B7 required by "+entry.operations.join(", ")+(entry.origins?.length?" \u00B7 declared by "+entry.origins.join(" and "):""),"info");section("Candidate goals",audit.outcomes,entry=>entry.label+" \u00B7 produced by "+entry.operations.join(", "),"info");section("Response outcome facts",audit.responseFacts??[],entry=>entry.label+" \u00B7 from "+entry.operations.join(", "),"info");section("Event facts",audit.eventFacts??[],entry=>entry.label+" \u00B7 signalled by "+entry.operations.join(", "),"info");section("Discovery-only operations",audit.discoveryOnlyOperations,entry=>entry,"info");section("Declared event triggers (descriptive; HAPI never receives them)",data.triggers??[],trigger=>triggerText(trigger)+": "+trigger.purpose+(trigger.expression?" \u00B7 "+trigger.expression:"")+(trigger.produces.length?" \u00B7 signals "+trigger.produces.map(factText).join(", "):""),"info")};
|
|
50
|
+
const renderFlowCards=()=>{const canvas=byId("flow-cards"),list=byId("flow-card-list"),summary=byId("flow-cards-summary"),model=data.flowCards;canvas.replaceChildren();list.replaceChildren();renderFlowGaps();if(!model){canvas.hidden=true;const goals=candidateGoals();summary.textContent="No plan trace was requested. Generate with --goal-fact to create cards."+(goals.length?" Candidate goal facts: "+goals.join(", ")+".":"");return}canvas.hidden=false;const query=normalize(controls.query.value);const matches=card=>!query||card.searchText.includes(query);const actions=model.cards.filter(card=>card.kind==="action");const start=model.cards.find(card=>card.kind==="start"),outcome=model.cards.find(card=>card.kind==="outcome");const then=()=>text("span","\u2193 then","flow-then");const row=cards=>{const level=text("div","","flow-level");for(const card of cards){const node=flowCardNode(card);node.classList.toggle("dim",!matches(card));node.classList.toggle("selected",state.selected===card.identity);level.append(node)}return level};canvas.append(row([start]));for(let level=0;level<model.levelCount;level++){const cards=actions.filter(card=>card.level===level);canvas.append(then(),text("span","Level "+level+(cards.length>1?" \u00B7 independent by declared facts":""),"flow-level-label"),row(cards))}canvas.append(then(),row([outcome]));for(const card of model.cards){if(!matches(card))continue;const item=document.createElement("li");item.append(itemButton(card,(card.kind==="action"?"Step "+card.step+" \u00B7 level "+card.level+" \u00B7 ":"")+card.label+(card.waits.length?" \u00B7 waits for "+card.waits.map(wait=>wait.code).join(", "):"")));list.append(item)}summary.textContent=model.outcome+" \u00B7 "+actions.length+" steps across "+model.levelCount+" dependency levels."};
|
|
51
|
+
const renderDiagnostics=()=>{const list=byId("diagnostic-list");list.replaceChildren();const entries=data.diagnostics.filter(diagnosticMatches);if(!entries.length)list.append(text("li","No diagnostics match the current filter.","empty"));for(const diagnostic of entries){const item=document.createElement("li");const button=itemButton(diagnostic,diagnostic.severity.toUpperCase()+" \u00B7 "+diagnostic.code+" \u00B7 "+diagnostic.message);button.classList.add(diagnostic.severity);item.append(button);list.append(item)}};
|
|
52
|
+
const render=()=>{renderTopology();renderBusinessStates();renderPlanning();renderPlanTrace();renderFlowCards();renderDiagnostics();if(state.selected)selectIdentity(state.selected,false)};
|
|
53
|
+
for(const control of Object.values(controls))control.addEventListener(control.tagName==="INPUT"?"input":"change",render);
|
|
54
|
+
byId("show-technical-facts").addEventListener("change",render);
|
|
55
|
+
byId("reset").addEventListener("click",()=>{for(const control of Object.values(controls))control.value="";byId("show-technical-facts").checked=false;render();controls.query.focus()});
|
|
56
|
+
const activateView=(name,focus)=>{const button=document.querySelector('[data-view="'+name+'"]');if(!button)return;state.view=name;for(const candidate of document.querySelectorAll("[data-view]"))candidate.setAttribute("aria-selected",String(candidate===button));for(const view of document.querySelectorAll(".view"))view.hidden=view.id!==name+"-view";if(focus)button.focus()};
|
|
57
|
+
for(const button of document.querySelectorAll("[data-view]"))button.addEventListener("click",()=>activateView(button.dataset.view,true));
|
|
58
|
+
window.addEventListener("hashchange",()=>applyFragment());
|
|
59
|
+
const applyFragment=()=>{const identity=new URLSearchParams(location.hash.slice(1)).get("item");if(identity)selectIdentity(identity,false)};
|
|
60
|
+
render();if(data.initialView)activateView(data.initialView,false);applyFragment();document.body.dataset.ready="true";
|
|
61
|
+
})()
|
|
62
|
+
`;async function pe(t,a={}){let e=K(a.limits),i=ue(I(t)),[n,o]=await Promise.all([ht(et),ht(at)]),r=`<!doctype html>
|
|
63
|
+
<html lang="en">
|
|
64
|
+
<head>
|
|
65
|
+
<meta charset="utf-8">
|
|
66
|
+
<meta name="viewport" content="width=device-width,initial-scale=1">
|
|
67
|
+
<meta http-equiv="Content-Security-Policy" content="${["default-src 'none'","base-uri 'none'","connect-src 'none'","font-src 'none'","form-action 'none'","frame-src 'none'","child-src 'none'","img-src 'none'","media-src 'none'","object-src 'none'",`script-src 'sha256-${o}'`,`style-src 'sha256-${n}'`,"worker-src 'none'"].join("; ")}">
|
|
68
|
+
<title>HAPI Capability Graph Visualization</title>
|
|
69
|
+
<style>${et}</style>
|
|
70
|
+
</head>
|
|
71
|
+
<body>
|
|
72
|
+
<header>
|
|
73
|
+
<h1>HAPI Capability Graph Visualization</h1>
|
|
74
|
+
<div class="notice">Read-only inspection \u2014 visibility does not imply authorization or execution eligibility.</div>
|
|
75
|
+
<div id="graph-meta" class="meta"></div>
|
|
76
|
+
<div id="counts" class="counts" aria-label="Graph counts"></div>
|
|
77
|
+
</header>
|
|
78
|
+
<main class="shell">
|
|
79
|
+
<aside aria-label="Visualization filters">
|
|
80
|
+
<h2>Filters</h2>
|
|
81
|
+
<div class="filters">
|
|
82
|
+
<label>Text search<input id="query" type="search" autocomplete="off" placeholder="Identity, purpose, taxonomy\u2026"></label>
|
|
83
|
+
<label>Node kind<select id="node-kind"><option value="">All node kinds</option><option value="capability">Capability</option><option value="operation">Operation</option></select></label>
|
|
84
|
+
<label>Taxonomy<select id="taxonomy"><option value="">All taxonomy</option></select></label>
|
|
85
|
+
<label>HTTP method<select id="method"><option value="">All methods</option></select></label>
|
|
86
|
+
<label>Effect<select id="effect"><option value="">All effects</option></select></label>
|
|
87
|
+
<label>Authorization<select id="authorization"><option value="">Any authorization</option><option value="required">Required</option><option value="none">None</option></select></label>
|
|
88
|
+
<label>Provenance<select id="provenance"><option value="">All provenance</option></select></label>
|
|
89
|
+
<label>Diagnostic severity<select id="severity"><option value="">All severities</option></select></label>
|
|
90
|
+
<label>Edge type<select id="edge-type"><option value="">All edge types</option></select></label>
|
|
91
|
+
<label>Planning eligibility<select id="planning-eligibility"><option value="">Any edge eligibility</option><option value="eligible">Planning eligible</option><option value="descriptive">Descriptive only</option></select></label>
|
|
92
|
+
<div class="filter-actions"><button id="reset" type="button">Reset filters</button></div>
|
|
93
|
+
</div>
|
|
94
|
+
<p id="status" class="status" role="status" aria-live="polite"></p>
|
|
95
|
+
</aside>
|
|
96
|
+
<section class="content">
|
|
97
|
+
<div class="tabs" role="tablist" aria-label="Visualization views">
|
|
98
|
+
<button type="button" role="tab" data-view="topology" aria-selected="true" aria-controls="topology-view">Topology</button>
|
|
99
|
+
<button type="button" role="tab" data-view="business-states" aria-selected="false" aria-controls="business-states-view">Business states</button>
|
|
100
|
+
<button type="button" role="tab" data-view="planning" aria-selected="false" aria-controls="planning-view">Planning transitions</button>
|
|
101
|
+
<button type="button" role="tab" data-view="plan-trace" aria-selected="false" aria-controls="plan-trace-view">Plan trace</button>
|
|
102
|
+
<button type="button" role="tab" data-view="flow-cards" aria-selected="false" aria-controls="flow-cards-view">Flow cards</button>
|
|
103
|
+
</div>
|
|
104
|
+
<section id="topology-view" class="view" role="tabpanel">
|
|
105
|
+
<p id="topology-summary" class="status"></p>
|
|
106
|
+
<div class="topology-grid">
|
|
107
|
+
<section class="panel canvas" aria-label="Graph topology">
|
|
108
|
+
<svg id="graph" class="graph-svg" role="img" aria-labelledby="graph-title graph-description">
|
|
109
|
+
<title id="graph-title">Capability graph topology</title>
|
|
110
|
+
<desc id="graph-description">Capabilities and operations connected by typed relationships. Use the synchronized item list for a text representation.</desc>
|
|
111
|
+
</svg>
|
|
112
|
+
</section>
|
|
113
|
+
<section class="panel" aria-label="Graph items and diagnostics">
|
|
114
|
+
<h2>Graph items</h2><ul id="item-list" class="item-list"></ul>
|
|
115
|
+
<h2>Diagnostics</h2><ul id="diagnostic-list" class="diagnostic-list"></ul>
|
|
116
|
+
</section>
|
|
117
|
+
</div>
|
|
118
|
+
</section>
|
|
119
|
+
<section id="business-states-view" class="view" role="tabpanel" hidden>
|
|
120
|
+
<h2>Business State Flow</h2>
|
|
121
|
+
<p class="status">Facts are conditions; a planner state is the complete set of facts that are true together. This is not a formal UML state machine.</p>
|
|
122
|
+
<label class="technical-toggle"><input id="show-technical-facts" type="checkbox"> Show technical operation-completion facts</label>
|
|
123
|
+
<p id="business-states-summary" class="status"></p>
|
|
124
|
+
<div class="topology-grid">
|
|
125
|
+
<section class="panel canvas" aria-label="Business state flow">
|
|
126
|
+
<svg id="state-graph" class="graph-svg" role="img" aria-labelledby="state-graph-title state-graph-description">
|
|
127
|
+
<title id="state-graph-title">Business State Flow</title>
|
|
128
|
+
<desc id="state-graph-description">Facts connect to operation or workflow transitions through requires, produces, and removes relationships. Use the synchronized list for a text representation.</desc>
|
|
129
|
+
</svg>
|
|
130
|
+
</section>
|
|
131
|
+
<section class="panel" aria-label="Business facts and transitions">
|
|
132
|
+
<h2>Facts and transitions</h2><ul id="state-item-list" class="item-list"></ul>
|
|
133
|
+
<p class="legend"><span>\u2192 requires / produces</span><span>\u21E2 removes</span></p>
|
|
134
|
+
</section>
|
|
135
|
+
</div>
|
|
136
|
+
</section>
|
|
137
|
+
<section id="planning-view" class="view panel" role="tabpanel" hidden>
|
|
138
|
+
<h2>Validated planning transitions</h2>
|
|
139
|
+
<p id="planning-summary" class="status"></p>
|
|
140
|
+
<ul id="planning-list" class="planning-list"></ul>
|
|
141
|
+
</section>
|
|
142
|
+
<section id="plan-trace-view" class="view panel" role="tabpanel" hidden>
|
|
143
|
+
<h2>Exact Plan Trace</h2>
|
|
144
|
+
<p id="plan-trace-summary" class="status"></p>
|
|
145
|
+
<ol id="plan-trace-list" class="planning-list"></ol>
|
|
146
|
+
</section>
|
|
147
|
+
<section id="flow-cards-view" class="view panel" role="tabpanel" hidden>
|
|
148
|
+
<h2>Flow cards</h2>
|
|
149
|
+
<p class="status">Cards present the exact plan trace. Steps on the same row are independent by declared facts; that is not a promise of parallel execution. Nothing here invokes an API, grants authorization, or confirms a step.</p>
|
|
150
|
+
<p id="flow-cards-summary" class="status"></p>
|
|
151
|
+
<div id="flow-cards" class="flow-cards" aria-label="Flow cards grouped by dependency level"></div>
|
|
152
|
+
<h3>Plan order</h3>
|
|
153
|
+
<ol id="flow-card-list" class="planning-list"></ol>
|
|
154
|
+
<div id="flow-gaps" class="flow-gaps"></div>
|
|
155
|
+
</section>
|
|
156
|
+
<section id="details" class="panel details" aria-label="Selected item details"><p class="empty">Select an item to inspect its safe graph metadata.</p></section>
|
|
157
|
+
</section>
|
|
158
|
+
</main>
|
|
159
|
+
<script id="visualization-data" type="application/octet-stream">${i}</script>
|
|
160
|
+
<script>${at}</script>
|
|
161
|
+
</body>
|
|
162
|
+
</html>
|
|
163
|
+
`,d=new TextEncoder().encode(r).byteLength;if(d>e.maxOutputBytes)throw new A("visualization-limit-exceeded",`Visualization maxOutputBytes exceeded: ${d} > ${e.maxOutputBytes}`,{limit:"maxOutputBytes",count:d,maximum:e.maxOutputBytes});return r}async function ht(t){let a=await crypto.subtle.digest("SHA-256",new TextEncoder().encode(t));return bt(new Uint8Array(a))}function ue(t){return bt(new TextEncoder().encode(t))}function bt(t){let a="",e=32768;for(let i=0;i<t.length;i+=e)a+=String.fromCharCode(...t.subarray(i,i+e));return btoa(a)}export{J as CAPABILITY_GRAPH_VISUALIZATION_LIMITS,Y as CAPABILITY_GRAPH_VISUALIZATION_VIEWS,A as CapabilityGraphVisualizationError,K as effectiveVisualizationLimits,qt as projectCapabilityGraphVisualization,pe as renderCapabilityGraphVisualizationHtml};
|