@ixo/editor 6.31.4 → 6.32.1
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/dist/action-manifest-v2.schema.json +214 -0
- package/dist/action-manifest.json +79 -58
- package/dist/{chunk-2HFSD5YP.js → chunk-5JF23UP3.js} +2 -2
- package/dist/{chunk-PSZOCS5V.js → chunk-A4CWC4AG.js} +2 -2
- package/dist/{chunk-6OMM32CE.js → chunk-NEOPTPDF.js} +436 -44
- package/dist/chunk-NEOPTPDF.js.map +1 -0
- package/dist/{connections-B24zj0RI.d.ts → connections-1NtNQrsY.d.ts} +1 -1
- package/dist/core/index.cjs +443 -43
- package/dist/core/index.cjs.map +1 -1
- package/dist/core/index.d.ts +299 -5
- package/dist/core/index.js +14 -2
- package/dist/core/index.js.map +1 -1
- package/dist/{graphql-client-BICFLCX8.d.ts → graphql-client-Bn0tN049.d.ts} +1 -1
- package/dist/index.d.ts +3 -3
- package/dist/index.js +3 -3
- package/dist/mantine/index.d.ts +3 -3
- package/dist/mantine/index.js +2 -2
- package/dist/{runtime-DFPayq89.d.ts → runtime-BFwvCQDF.d.ts} +15 -0
- package/package.json +2 -1
- package/dist/chunk-6OMM32CE.js.map +0 -1
- /package/dist/{chunk-2HFSD5YP.js.map → chunk-5JF23UP3.js.map} +0 -0
- /package/dist/{chunk-PSZOCS5V.js.map → chunk-A4CWC4AG.js.map} +0 -0
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { a6 as FlowNodeAuthzExtension, a7 as FlowNode, a8 as EvaluationStatus, F as FlowRuntimeStateManager, G as UcanService, g as InvocationStore, a9 as IxoEditorType, aa as PendingInvocation, ab as ActionServices, ac as ActionHandlers, ad as RunEventAppender, ae as TopicExecutionContext, af as TopicActionBridge, ag as ActionResult, ah as TopicActionWriteBackResult, U as UcanCapability, ai as FlowNodeRuntimeState, z as UcanDelegationStore, v as StoredDelegation, aj as ActionDefinition } from './runtime-
|
|
1
|
+
import { a6 as FlowNodeAuthzExtension, a7 as FlowNode, a8 as EvaluationStatus, F as FlowRuntimeStateManager, G as UcanService, g as InvocationStore, a9 as IxoEditorType, aa as PendingInvocation, ab as ActionServices, ac as ActionHandlers, ad as RunEventAppender, ae as TopicExecutionContext, af as TopicActionBridge, ag as ActionResult, ah as TopicActionWriteBackResult, U as UcanCapability, ai as FlowNodeRuntimeState, z as UcanDelegationStore, v as StoredDelegation, aj as ActionDefinition } from './runtime-BFwvCQDF.js';
|
|
2
2
|
import * as Y from 'yjs';
|
|
3
3
|
import { Doc, Map } from 'yjs';
|
|
4
4
|
import { MatrixClient } from 'matrix-js-sdk';
|
package/dist/core/index.cjs
CHANGED
|
@@ -74,8 +74,10 @@ var init_cid = __esm({
|
|
|
74
74
|
// src/core/index.ts
|
|
75
75
|
var core_exports = {};
|
|
76
76
|
__export(core_exports, {
|
|
77
|
+
ACTION_MANIFEST_V2_SCHEMA: () => ACTION_MANIFEST_V2_SCHEMA,
|
|
77
78
|
ACTION_MANIFEST_VERSION: () => ACTION_MANIFEST_VERSION,
|
|
78
79
|
ACTION_REGISTRY_VERSION: () => ACTION_REGISTRY_VERSION,
|
|
80
|
+
ActionManifestV2VerificationError: () => ActionManifestV2VerificationError,
|
|
79
81
|
ExplicitRunRequiredError: () => ExplicitRunRequiredError,
|
|
80
82
|
FLOW_CONNECTIONS_MAP_KEY: () => FLOW_CONNECTIONS_MAP_KEY,
|
|
81
83
|
FLOW_CONNECTION_BINDINGS_MAP_KEY: () => FLOW_CONNECTION_BINDINGS_MAP_KEY,
|
|
@@ -141,6 +143,7 @@ __export(core_exports, {
|
|
|
141
143
|
canToActionType: () => canToActionType,
|
|
142
144
|
canToType: () => canToType,
|
|
143
145
|
cancelRun: () => cancelRun,
|
|
146
|
+
canonicalizeManifestV2Payload: () => canonicalizeManifestV2Payload,
|
|
144
147
|
capabilityPatternCoversCan: () => capabilityPatternCoversCan,
|
|
145
148
|
classifyBlockerCause: () => classifyBlockerCause,
|
|
146
149
|
classifyNodeState: () => classifyNodeState,
|
|
@@ -150,6 +153,7 @@ __export(core_exports, {
|
|
|
150
153
|
closeRun: () => closeRun,
|
|
151
154
|
collectPhantomLegacyRun: () => collectPhantomLegacyRun,
|
|
152
155
|
compileBaseUcanFlow: () => compileBaseUcanFlow,
|
|
156
|
+
computeActionManifestV2Digest: () => computeActionManifestV2Digest,
|
|
153
157
|
computeAgentCommandId: () => computeAgentCommandId,
|
|
154
158
|
computeCID: () => computeCID,
|
|
155
159
|
computeJsonCID: () => computeJsonCID,
|
|
@@ -326,6 +330,7 @@ __export(core_exports, {
|
|
|
326
330
|
setTempUcanEnforcementDisabled: () => setTempUcanEnforcementDisabled,
|
|
327
331
|
setupFlowFromBaseUcan: () => setupFlowFromBaseUcan,
|
|
328
332
|
sha256Digest: () => sha256Digest,
|
|
333
|
+
signActionManifestV2: () => signActionManifestV2,
|
|
329
334
|
snapshotInputRefs: () => snapshotInputRefs,
|
|
330
335
|
snapshotNode: () => snapshotNode,
|
|
331
336
|
startRun: () => startRun,
|
|
@@ -355,6 +360,7 @@ __export(core_exports, {
|
|
|
355
360
|
validateFlowAgentLease: () => validateFlowAgentLease,
|
|
356
361
|
validateTopicSemanticRecord: () => validateTopicSemanticRecord,
|
|
357
362
|
validateTopicSemanticRecordBatch: () => validateTopicSemanticRecordBatch,
|
|
363
|
+
verifyActionManifestV2: () => verifyActionManifestV2,
|
|
358
364
|
verifyCompletion: () => verifyCompletion,
|
|
359
365
|
writeActionState: () => writeActionState,
|
|
360
366
|
writeCompiledBlocksToFragment: () => writeCompiledBlocksToFragment,
|
|
@@ -2677,12 +2683,11 @@ var PRESENTATION = {
|
|
|
2677
2683
|
"qi/topic.action.receipt.record": { displayName: "Record Action Receipt", description: "Record a signed Action receipt against its Topic request" },
|
|
2678
2684
|
"qi/topic.action.request": { displayName: "Request Topic Action", description: "Request an Action against the current Topic revision" },
|
|
2679
2685
|
"qi/topic.context.link": { displayName: "Link Topic Context", description: "Link a referenced resource or service to the Topic" },
|
|
2680
|
-
"qi/topic.contract.
|
|
2686
|
+
"qi/topic.contract.confirm-setup": { displayName: "Confirm Topic Setup", description: "Confirm the exact proposed Topic setup revision" },
|
|
2681
2687
|
"qi/topic.decision.record": { displayName: "Record Topic Decision", description: "Record an authorised decision and its rationale" },
|
|
2682
2688
|
"qi/topic.file.attach-reference": { displayName: "Attach File Reference", description: "Attach a pinned VFS file reference to the Topic" },
|
|
2683
2689
|
"qi/topic.flow.bind": { displayName: "Bind Flow to Topic", description: "Bind a governed Flow revision to the Topic" },
|
|
2684
2690
|
"qi/topic.flow.unbind": { displayName: "Unbind Flow from Topic", description: "Remove an existing Flow binding from the Topic" },
|
|
2685
|
-
"qi/topic.outcome.confirm": { displayName: "Confirm Topic Outcome", description: "Confirm a proposed outcome using the stated authority" },
|
|
2686
2691
|
"qi/topic.outcome.propose": { displayName: "Propose Topic Outcome", description: "Propose an evidence-backed outcome for review" },
|
|
2687
2692
|
"qi/topic.status.transition": { displayName: "Change Topic Status", description: "Move the Topic between permitted lifecycle statuses" },
|
|
2688
2693
|
"qi/wallet.fund": { displayName: "Fund Wallet", description: "Fund a wallet with an on-chain transfer" },
|
|
@@ -2763,7 +2768,11 @@ var ACTION_TYPE_ALIASES = {
|
|
|
2763
2768
|
// qi/ixo.calendar.event.* instead.
|
|
2764
2769
|
"qi/calendar.event.create": "qi/googlecalendar.event.create-self",
|
|
2765
2770
|
"qi/calendar.event.update": "qi/googlecalendar.event.update-self",
|
|
2766
|
-
"qi/calendar.event.list": "qi/googlecalendar.event.list-self"
|
|
2771
|
+
"qi/calendar.event.list": "qi/googlecalendar.event.list-self",
|
|
2772
|
+
// Topic v3 called setup confirmation "accept contract". Persisted Flow
|
|
2773
|
+
// documents keep that action key, so resolve it to the v4 confirmation
|
|
2774
|
+
// contract while new documents use the canonical name.
|
|
2775
|
+
"qi/topic.contract.accept": "qi/topic.contract.confirm-setup"
|
|
2767
2776
|
};
|
|
2768
2777
|
var aliases = new Map(Object.entries(ACTION_TYPE_ALIASES));
|
|
2769
2778
|
function resolveActionType(type) {
|
|
@@ -3028,6 +3037,347 @@ function actionManifestIssues(manifest = generateActionManifest()) {
|
|
|
3028
3037
|
return issues;
|
|
3029
3038
|
}
|
|
3030
3039
|
|
|
3040
|
+
// src/core/lib/actionRegistry/manifestV2.ts
|
|
3041
|
+
var import__2 = __toESM(require("ajv/dist/2020.js"), 1);
|
|
3042
|
+
|
|
3043
|
+
// src/core/lib/actionRegistry/manifestV2.schema.ts
|
|
3044
|
+
var ACTION_MANIFEST_V2_SCHEMA = {
|
|
3045
|
+
$schema: "https://json-schema.org/draft/2020-12/schema",
|
|
3046
|
+
$id: "https://ixo.world/schemas/qi/action-manifest-v2.schema.json",
|
|
3047
|
+
type: "object",
|
|
3048
|
+
additionalProperties: false,
|
|
3049
|
+
required: ["manifestVersion", "manifestId", "generatedAt", "package", "issuer", "compatibility", "actions", "primitives", "integrity"],
|
|
3050
|
+
properties: {
|
|
3051
|
+
manifestVersion: { const: "2.0" },
|
|
3052
|
+
manifestId: { type: "string", minLength: 1 },
|
|
3053
|
+
generatedAt: {
|
|
3054
|
+
type: "string",
|
|
3055
|
+
pattern: "^\\d{4}-\\d{2}-\\d{2}T\\d{2}:\\d{2}:\\d{2}(?:\\.\\d+)?(?:Z|[+-]\\d{2}:\\d{2})$"
|
|
3056
|
+
},
|
|
3057
|
+
package: {
|
|
3058
|
+
type: "object",
|
|
3059
|
+
additionalProperties: false,
|
|
3060
|
+
required: ["name", "version", "sourceCommit"],
|
|
3061
|
+
properties: {
|
|
3062
|
+
name: { type: "string", minLength: 1 },
|
|
3063
|
+
version: { type: "string", minLength: 1 },
|
|
3064
|
+
sourceCommit: { type: "string", minLength: 1 },
|
|
3065
|
+
buildId: { type: "string", minLength: 1 },
|
|
3066
|
+
distributionUrl: { type: "string", pattern: "^[a-zA-Z][a-zA-Z0-9+.-]*:" }
|
|
3067
|
+
}
|
|
3068
|
+
},
|
|
3069
|
+
issuer: {
|
|
3070
|
+
type: "object",
|
|
3071
|
+
additionalProperties: false,
|
|
3072
|
+
required: ["did", "verificationMethod"],
|
|
3073
|
+
properties: {
|
|
3074
|
+
did: { type: "string", pattern: "^did:[a-z0-9]+:.+" },
|
|
3075
|
+
verificationMethod: { type: "string", pattern: "^did:[a-z0-9]+:.+#.+" }
|
|
3076
|
+
}
|
|
3077
|
+
},
|
|
3078
|
+
compatibility: {
|
|
3079
|
+
type: "object",
|
|
3080
|
+
additionalProperties: false,
|
|
3081
|
+
required: ["engine", "flowSchemaVersions", "features"],
|
|
3082
|
+
properties: {
|
|
3083
|
+
engine: {
|
|
3084
|
+
type: "object",
|
|
3085
|
+
additionalProperties: false,
|
|
3086
|
+
required: ["versionRange"],
|
|
3087
|
+
properties: {
|
|
3088
|
+
versionRange: { type: "string", minLength: 1 }
|
|
3089
|
+
}
|
|
3090
|
+
},
|
|
3091
|
+
flowSchemaVersions: {
|
|
3092
|
+
type: "array",
|
|
3093
|
+
minItems: 1,
|
|
3094
|
+
uniqueItems: true,
|
|
3095
|
+
items: { type: "string", minLength: 1 }
|
|
3096
|
+
},
|
|
3097
|
+
features: {
|
|
3098
|
+
type: "array",
|
|
3099
|
+
minItems: 1,
|
|
3100
|
+
uniqueItems: true,
|
|
3101
|
+
items: { type: "string", minLength: 1 }
|
|
3102
|
+
}
|
|
3103
|
+
}
|
|
3104
|
+
},
|
|
3105
|
+
actions: {
|
|
3106
|
+
type: "array",
|
|
3107
|
+
items: { $ref: "#/$defs/contract" }
|
|
3108
|
+
},
|
|
3109
|
+
primitives: {
|
|
3110
|
+
type: "array",
|
|
3111
|
+
items: { $ref: "#/$defs/contract" }
|
|
3112
|
+
},
|
|
3113
|
+
integrity: {
|
|
3114
|
+
type: "object",
|
|
3115
|
+
additionalProperties: false,
|
|
3116
|
+
required: ["canonicalization", "digest", "signature"],
|
|
3117
|
+
properties: {
|
|
3118
|
+
canonicalization: { const: "RFC8785" },
|
|
3119
|
+
digest: {
|
|
3120
|
+
type: "object",
|
|
3121
|
+
additionalProperties: false,
|
|
3122
|
+
required: ["algorithm", "value"],
|
|
3123
|
+
properties: {
|
|
3124
|
+
algorithm: { const: "SHA-256" },
|
|
3125
|
+
value: { type: "string", pattern: "^sha256:[0-9a-f]{64}$" }
|
|
3126
|
+
}
|
|
3127
|
+
},
|
|
3128
|
+
signature: {
|
|
3129
|
+
type: "object",
|
|
3130
|
+
additionalProperties: false,
|
|
3131
|
+
required: ["algorithm", "verificationMethod", "value"],
|
|
3132
|
+
properties: {
|
|
3133
|
+
algorithm: { type: "string", minLength: 1 },
|
|
3134
|
+
verificationMethod: { type: "string", pattern: "^did:[a-z0-9]+:.+#.+" },
|
|
3135
|
+
value: { type: "string", minLength: 1 }
|
|
3136
|
+
}
|
|
3137
|
+
}
|
|
3138
|
+
}
|
|
3139
|
+
}
|
|
3140
|
+
},
|
|
3141
|
+
$defs: {
|
|
3142
|
+
contract: {
|
|
3143
|
+
type: "object",
|
|
3144
|
+
required: ["type", "contractVersion"],
|
|
3145
|
+
properties: {
|
|
3146
|
+
type: { type: "string", minLength: 1 },
|
|
3147
|
+
contractVersion: { type: "string", minLength: 1 },
|
|
3148
|
+
aliases: {
|
|
3149
|
+
type: "array",
|
|
3150
|
+
uniqueItems: true,
|
|
3151
|
+
items: { type: "string", minLength: 1 }
|
|
3152
|
+
}
|
|
3153
|
+
}
|
|
3154
|
+
}
|
|
3155
|
+
}
|
|
3156
|
+
};
|
|
3157
|
+
|
|
3158
|
+
// src/core/lib/actionRegistry/manifestV2.ts
|
|
3159
|
+
var ActionManifestV2VerificationError = class extends Error {
|
|
3160
|
+
constructor(code, message) {
|
|
3161
|
+
super(message);
|
|
3162
|
+
this.name = "ActionManifestV2VerificationError";
|
|
3163
|
+
this.code = code;
|
|
3164
|
+
}
|
|
3165
|
+
};
|
|
3166
|
+
var validateSignedManifest = new import__2.default({ allErrors: true, strict: false }).compile(ACTION_MANIFEST_V2_SCHEMA);
|
|
3167
|
+
var SIGNATURE_DOMAIN = "qi.action-manifest.v2\0";
|
|
3168
|
+
function isPlainObject(value) {
|
|
3169
|
+
const prototype = Object.getPrototypeOf(value);
|
|
3170
|
+
return prototype === Object.prototype || prototype === null;
|
|
3171
|
+
}
|
|
3172
|
+
function assertValidUnicode(value) {
|
|
3173
|
+
for (let index = 0; index < value.length; index += 1) {
|
|
3174
|
+
const codeUnit = value.charCodeAt(index);
|
|
3175
|
+
if (codeUnit >= 55296 && codeUnit <= 56319) {
|
|
3176
|
+
const next = value.charCodeAt(index + 1);
|
|
3177
|
+
if (!(next >= 56320 && next <= 57343)) {
|
|
3178
|
+
throw new TypeError("Manifest v2 contains an unpaired Unicode surrogate");
|
|
3179
|
+
}
|
|
3180
|
+
index += 1;
|
|
3181
|
+
} else if (codeUnit >= 56320 && codeUnit <= 57343) {
|
|
3182
|
+
throw new TypeError("Manifest v2 contains an unpaired Unicode surrogate");
|
|
3183
|
+
}
|
|
3184
|
+
}
|
|
3185
|
+
}
|
|
3186
|
+
function canonicalizeManifestV2Payload(payload) {
|
|
3187
|
+
const ancestors = /* @__PURE__ */ new Set();
|
|
3188
|
+
const serialize = (value) => {
|
|
3189
|
+
if (value === null || typeof value === "boolean") {
|
|
3190
|
+
return JSON.stringify(value);
|
|
3191
|
+
}
|
|
3192
|
+
if (typeof value === "string") {
|
|
3193
|
+
assertValidUnicode(value);
|
|
3194
|
+
return JSON.stringify(value);
|
|
3195
|
+
}
|
|
3196
|
+
if (typeof value === "number") {
|
|
3197
|
+
if (!Number.isFinite(value)) {
|
|
3198
|
+
throw new TypeError("Manifest v2 contains a non-finite number");
|
|
3199
|
+
}
|
|
3200
|
+
return JSON.stringify(value);
|
|
3201
|
+
}
|
|
3202
|
+
if (typeof value !== "object") {
|
|
3203
|
+
throw new TypeError(`Manifest v2 contains a non-JSON value: ${typeof value}`);
|
|
3204
|
+
}
|
|
3205
|
+
if (ancestors.has(value)) {
|
|
3206
|
+
throw new TypeError("Manifest v2 contains a circular reference");
|
|
3207
|
+
}
|
|
3208
|
+
ancestors.add(value);
|
|
3209
|
+
try {
|
|
3210
|
+
if (Array.isArray(value)) {
|
|
3211
|
+
return `[${value.map((entry) => serialize(entry)).join(",")}]`;
|
|
3212
|
+
}
|
|
3213
|
+
if (!isPlainObject(value)) {
|
|
3214
|
+
throw new TypeError("Manifest v2 contains a non-plain object");
|
|
3215
|
+
}
|
|
3216
|
+
return `{${Object.keys(value).sort().map((key) => {
|
|
3217
|
+
assertValidUnicode(key);
|
|
3218
|
+
return `${JSON.stringify(key)}:${serialize(value[key])}`;
|
|
3219
|
+
}).join(",")}}`;
|
|
3220
|
+
} finally {
|
|
3221
|
+
ancestors.delete(value);
|
|
3222
|
+
}
|
|
3223
|
+
};
|
|
3224
|
+
return serialize(payload);
|
|
3225
|
+
}
|
|
3226
|
+
async function computeActionManifestV2Digest(payload) {
|
|
3227
|
+
if (!globalThis.crypto?.subtle) {
|
|
3228
|
+
throw new Error("Web Crypto is required to digest an Action Manifest v2 contract");
|
|
3229
|
+
}
|
|
3230
|
+
const canonicalPayload = canonicalizeManifestV2Payload(payload);
|
|
3231
|
+
const digest2 = await globalThis.crypto.subtle.digest("SHA-256", new TextEncoder().encode(canonicalPayload));
|
|
3232
|
+
const hex = Array.from(new Uint8Array(digest2), (byte) => byte.toString(16).padStart(2, "0")).join("");
|
|
3233
|
+
return `sha256:${hex}`;
|
|
3234
|
+
}
|
|
3235
|
+
function signatureInput(digest2) {
|
|
3236
|
+
return new TextEncoder().encode(`${SIGNATURE_DOMAIN}${digest2}`);
|
|
3237
|
+
}
|
|
3238
|
+
function schemaFailure() {
|
|
3239
|
+
const details = (validateSignedManifest.errors || []).map((error) => `${error.instancePath || "/"} ${error.message || "is invalid"}`).join("; ");
|
|
3240
|
+
return new ActionManifestV2VerificationError("INVALID_MANIFEST", details ? `Action Manifest v2 is invalid: ${details}` : "Action Manifest v2 is invalid");
|
|
3241
|
+
}
|
|
3242
|
+
function payloadFromSignedManifest(manifest) {
|
|
3243
|
+
const { integrity: _integrity, ...payload } = manifest;
|
|
3244
|
+
return payload;
|
|
3245
|
+
}
|
|
3246
|
+
function assertContractIdentities(payload) {
|
|
3247
|
+
const contracts = [...payload.actions, ...payload.primitives];
|
|
3248
|
+
const canonicalTypes = /* @__PURE__ */ new Set();
|
|
3249
|
+
for (const contract of contracts) {
|
|
3250
|
+
if (canonicalTypes.has(contract.type)) {
|
|
3251
|
+
throw new ActionManifestV2VerificationError("DUPLICATE_CONTRACT_TYPE", `Manifest contains duplicate canonical contract type: ${contract.type}`);
|
|
3252
|
+
}
|
|
3253
|
+
canonicalTypes.add(contract.type);
|
|
3254
|
+
}
|
|
3255
|
+
for (const [groupName, group] of [
|
|
3256
|
+
["actions", payload.actions],
|
|
3257
|
+
["primitives", payload.primitives]
|
|
3258
|
+
]) {
|
|
3259
|
+
for (let index = 1; index < group.length; index += 1) {
|
|
3260
|
+
if (group[index - 1].type > group[index].type) {
|
|
3261
|
+
throw new ActionManifestV2VerificationError("UNSORTED_CONTRACTS", `Manifest ${groupName} must be sorted by canonical type`);
|
|
3262
|
+
}
|
|
3263
|
+
}
|
|
3264
|
+
}
|
|
3265
|
+
const claimedNames = new Map(Array.from(canonicalTypes, (type) => [type, type]));
|
|
3266
|
+
for (const contract of contracts) {
|
|
3267
|
+
const aliases2 = contract.aliases;
|
|
3268
|
+
if (!Array.isArray(aliases2)) continue;
|
|
3269
|
+
for (const alias of aliases2) {
|
|
3270
|
+
const existingOwner = claimedNames.get(alias);
|
|
3271
|
+
if (existingOwner) {
|
|
3272
|
+
throw new ActionManifestV2VerificationError("AMBIGUOUS_ALIAS", `Manifest alias ${alias} conflicts with contract ${existingOwner}`);
|
|
3273
|
+
}
|
|
3274
|
+
claimedNames.set(alias, contract.type);
|
|
3275
|
+
}
|
|
3276
|
+
}
|
|
3277
|
+
}
|
|
3278
|
+
function deepFreeze(value) {
|
|
3279
|
+
for (const child of Object.values(value)) {
|
|
3280
|
+
if (typeof child === "object" && child !== null && !Object.isFrozen(child)) {
|
|
3281
|
+
deepFreeze(child);
|
|
3282
|
+
}
|
|
3283
|
+
}
|
|
3284
|
+
return Object.freeze(value);
|
|
3285
|
+
}
|
|
3286
|
+
async function signActionManifestV2(payload, signer) {
|
|
3287
|
+
if (signer.issuerDid !== payload.issuer.did || signer.verificationMethod !== payload.issuer.verificationMethod) {
|
|
3288
|
+
throw new ActionManifestV2VerificationError("SIGNER_MISMATCH", "The Manifest v2 signer does not match the declared issuer verification method");
|
|
3289
|
+
}
|
|
3290
|
+
assertContractIdentities(payload);
|
|
3291
|
+
let digest2;
|
|
3292
|
+
try {
|
|
3293
|
+
digest2 = await computeActionManifestV2Digest(payload);
|
|
3294
|
+
} catch (error) {
|
|
3295
|
+
throw new ActionManifestV2VerificationError(
|
|
3296
|
+
"INVALID_MANIFEST",
|
|
3297
|
+
error instanceof Error ? `Action Manifest v2 cannot be canonicalized: ${error.message}` : "Action Manifest v2 cannot be canonicalized"
|
|
3298
|
+
);
|
|
3299
|
+
}
|
|
3300
|
+
const signature = await signer.sign(signatureInput(digest2));
|
|
3301
|
+
if (!signature) {
|
|
3302
|
+
throw new ActionManifestV2VerificationError("INVALID_SIGNATURE", "The Manifest v2 signer returned an empty signature");
|
|
3303
|
+
}
|
|
3304
|
+
const signed = {
|
|
3305
|
+
...payload,
|
|
3306
|
+
integrity: {
|
|
3307
|
+
canonicalization: "RFC8785",
|
|
3308
|
+
digest: {
|
|
3309
|
+
algorithm: "SHA-256",
|
|
3310
|
+
value: digest2
|
|
3311
|
+
},
|
|
3312
|
+
signature: {
|
|
3313
|
+
algorithm: signer.algorithm,
|
|
3314
|
+
verificationMethod: signer.verificationMethod,
|
|
3315
|
+
value: signature
|
|
3316
|
+
}
|
|
3317
|
+
}
|
|
3318
|
+
};
|
|
3319
|
+
if (!validateSignedManifest(signed)) {
|
|
3320
|
+
throw schemaFailure();
|
|
3321
|
+
}
|
|
3322
|
+
assertContractIdentities(payload);
|
|
3323
|
+
return signed;
|
|
3324
|
+
}
|
|
3325
|
+
async function verifyActionManifestV2(candidate, trustPolicy) {
|
|
3326
|
+
if (typeof candidate !== "object" || candidate === null || !("manifestVersion" in candidate) || candidate.manifestVersion !== "2.0") {
|
|
3327
|
+
throw new ActionManifestV2VerificationError("UNSUPPORTED_MANIFEST_VERSION", "Only Action Manifest version 2.0 can cross this execution boundary");
|
|
3328
|
+
}
|
|
3329
|
+
if (!("integrity" in candidate) || typeof candidate.integrity !== "object") {
|
|
3330
|
+
throw new ActionManifestV2VerificationError("UNSIGNED_MANIFEST", "A signature and digest are required to load Action Manifest v2 for execution");
|
|
3331
|
+
}
|
|
3332
|
+
if (!validateSignedManifest(candidate)) {
|
|
3333
|
+
throw schemaFailure();
|
|
3334
|
+
}
|
|
3335
|
+
const manifest = candidate;
|
|
3336
|
+
const { issuer, integrity } = manifest;
|
|
3337
|
+
assertContractIdentities(manifest);
|
|
3338
|
+
if (!trustPolicy.trustedIssuerDids.includes(issuer.did)) {
|
|
3339
|
+
throw new ActionManifestV2VerificationError("UNTRUSTED_ISSUER", `Manifest issuer is not trusted: ${issuer.did}`);
|
|
3340
|
+
}
|
|
3341
|
+
if (trustPolicy.revokedIssuerDids?.includes(issuer.did)) {
|
|
3342
|
+
throw new ActionManifestV2VerificationError("REVOKED_ISSUER", `Manifest issuer is revoked: ${issuer.did}`);
|
|
3343
|
+
}
|
|
3344
|
+
if (integrity.signature.verificationMethod !== issuer.verificationMethod || !integrity.signature.verificationMethod.startsWith(`${issuer.did}#`)) {
|
|
3345
|
+
throw new ActionManifestV2VerificationError("VERIFICATION_METHOD_MISMATCH", "The signature verification method does not belong to the declared manifest issuer");
|
|
3346
|
+
}
|
|
3347
|
+
if (!trustPolicy.allowedSignatureAlgorithms.includes(integrity.signature.algorithm)) {
|
|
3348
|
+
throw new ActionManifestV2VerificationError("DISALLOWED_SIGNATURE_ALGORITHM", `Manifest signature algorithm is not allowed: ${integrity.signature.algorithm}`);
|
|
3349
|
+
}
|
|
3350
|
+
let digest2;
|
|
3351
|
+
try {
|
|
3352
|
+
digest2 = await computeActionManifestV2Digest(payloadFromSignedManifest(manifest));
|
|
3353
|
+
} catch (error) {
|
|
3354
|
+
throw new ActionManifestV2VerificationError(
|
|
3355
|
+
"INVALID_MANIFEST",
|
|
3356
|
+
error instanceof Error ? `Action Manifest v2 cannot be canonicalized: ${error.message}` : "Action Manifest v2 cannot be canonicalized"
|
|
3357
|
+
);
|
|
3358
|
+
}
|
|
3359
|
+
if (digest2 !== integrity.digest.value) {
|
|
3360
|
+
throw new ActionManifestV2VerificationError("DIGEST_MISMATCH", "Manifest payload does not match its signed digest");
|
|
3361
|
+
}
|
|
3362
|
+
let validSignature = false;
|
|
3363
|
+
try {
|
|
3364
|
+
validSignature = await trustPolicy.verifySignature({
|
|
3365
|
+
issuerDid: issuer.did,
|
|
3366
|
+
verificationMethod: integrity.signature.verificationMethod,
|
|
3367
|
+
algorithm: integrity.signature.algorithm,
|
|
3368
|
+
data: signatureInput(digest2),
|
|
3369
|
+
signature: integrity.signature.value
|
|
3370
|
+
});
|
|
3371
|
+
} catch {
|
|
3372
|
+
validSignature = false;
|
|
3373
|
+
}
|
|
3374
|
+
if (!validSignature) {
|
|
3375
|
+
throw new ActionManifestV2VerificationError("INVALID_SIGNATURE", "Manifest signature verification failed");
|
|
3376
|
+
}
|
|
3377
|
+
const trustedSnapshot = JSON.parse(JSON.stringify(manifest));
|
|
3378
|
+
return deepFreeze(trustedSnapshot);
|
|
3379
|
+
}
|
|
3380
|
+
|
|
3031
3381
|
// src/core/lib/actionRegistry/inputRequirements.ts
|
|
3032
3382
|
function isBlankInputValue(value) {
|
|
3033
3383
|
if (value == null) return true;
|
|
@@ -10717,7 +11067,7 @@ function stripHtml(s) {
|
|
|
10717
11067
|
}
|
|
10718
11068
|
|
|
10719
11069
|
// src/core/lib/actionRegistry/actions/evalRubric/schemaGate.ts
|
|
10720
|
-
var
|
|
11070
|
+
var import__3 = __toESM(require("ajv/dist/2020.js"), 1);
|
|
10721
11071
|
|
|
10722
11072
|
// src/core/lib/actionRegistry/actions/evalRubric/types.ts
|
|
10723
11073
|
var RUBRIC_CTX_TOKENS = [
|
|
@@ -10790,7 +11140,7 @@ async function getValidator(fetchSchema, evalEngineUrl) {
|
|
|
10790
11140
|
if (compiledValidator) return compiledValidator;
|
|
10791
11141
|
const schema = await fetchSchema(evalEngineUrl);
|
|
10792
11142
|
if (!schema || typeof schema !== "object") throw new Error("the rules service returned no schema");
|
|
10793
|
-
const validate = new
|
|
11143
|
+
const validate = new import__3.default({ allErrors: true, strict: false }).compile(schema);
|
|
10794
11144
|
compiledValidator = validate;
|
|
10795
11145
|
return validate;
|
|
10796
11146
|
}
|
|
@@ -12955,6 +13305,7 @@ registerTopicOperation({
|
|
|
12955
13305
|
executorPreference: { type: "string", enum: ["qi-flow", "qiforge", "mcp"] },
|
|
12956
13306
|
bindingId: { type: "string" },
|
|
12957
13307
|
confirmationPolicy: { type: "string", enum: ["inherit", "required"] },
|
|
13308
|
+
transitionCode: { type: "string" },
|
|
12958
13309
|
idempotencyKey: { type: "string" }
|
|
12959
13310
|
}
|
|
12960
13311
|
},
|
|
@@ -12973,6 +13324,7 @@ registerTopicOperation({
|
|
|
12973
13324
|
const inputDigest = requiredString(inputs.inputDigest, "inputDigest");
|
|
12974
13325
|
const derived = (purpose) => sha256Digest({ purpose, parentRequestId: topic.requestId, topicId: topic.topicId, actionType: target.type, inputDigest });
|
|
12975
13326
|
return {
|
|
13327
|
+
...inputs.transitionCode ? { transitionCode: String(inputs.transitionCode) } : {},
|
|
12976
13328
|
request: {
|
|
12977
13329
|
version: 1,
|
|
12978
13330
|
requestId: String(inputs.requestId || derived("topic-action-request")),
|
|
@@ -13038,9 +13390,15 @@ registerTopicOperation({
|
|
|
13038
13390
|
ability: "topic/change-status",
|
|
13039
13391
|
inputSchema: {
|
|
13040
13392
|
type: "object",
|
|
13041
|
-
required: ["from", "to", "reason"],
|
|
13393
|
+
required: ["from", "to", "transitionCode", "reason"],
|
|
13042
13394
|
additionalProperties: false,
|
|
13043
|
-
properties: {
|
|
13395
|
+
properties: {
|
|
13396
|
+
from: { type: "string" },
|
|
13397
|
+
to: { type: "string" },
|
|
13398
|
+
transitionCode: { type: "string" },
|
|
13399
|
+
reason: { type: "string" },
|
|
13400
|
+
idempotencyKey: { type: "string" }
|
|
13401
|
+
}
|
|
13044
13402
|
},
|
|
13045
13403
|
buildPayload: async (inputs, ctx) => {
|
|
13046
13404
|
const from = requiredString(inputs.from, "from");
|
|
@@ -13053,16 +13411,21 @@ registerTopicOperation({
|
|
|
13053
13411
|
const outcome = projection.outcome;
|
|
13054
13412
|
if (completion?.requiresOutcomeRecord === true && !outcome?.outcomeRecordId) throw new Error("Topic policy requires an accepted outcome record before resolution");
|
|
13055
13413
|
}
|
|
13056
|
-
return {
|
|
13414
|
+
return {
|
|
13415
|
+
from,
|
|
13416
|
+
to,
|
|
13417
|
+
transitionCode: requiredString(inputs.transitionCode, "transitionCode"),
|
|
13418
|
+
reason: requiredString(inputs.reason, "reason")
|
|
13419
|
+
};
|
|
13057
13420
|
}
|
|
13058
13421
|
});
|
|
13059
13422
|
registerTopicOperation({
|
|
13060
|
-
type: "qi/topic.contract.
|
|
13061
|
-
can: "topic/contract.
|
|
13062
|
-
operationType: "
|
|
13423
|
+
type: "qi/topic.contract.confirm-setup",
|
|
13424
|
+
can: "topic/contract.confirm-setup",
|
|
13425
|
+
operationType: "confirm-setup",
|
|
13063
13426
|
confirmation: true,
|
|
13064
13427
|
owner: "human",
|
|
13065
|
-
ability: "topic/
|
|
13428
|
+
ability: "topic/confirm-setup",
|
|
13066
13429
|
inputSchema: {
|
|
13067
13430
|
type: "object",
|
|
13068
13431
|
required: ["contractRevision", "contractDigest", "confirmationReference"],
|
|
@@ -13071,6 +13434,7 @@ registerTopicOperation({
|
|
|
13071
13434
|
contractRevision: { type: "string" },
|
|
13072
13435
|
contractDigest: { type: "string", pattern: "^sha256:" },
|
|
13073
13436
|
confirmationReference: { type: "string" },
|
|
13437
|
+
transitionCode: { type: "string" },
|
|
13074
13438
|
idempotencyKey: { type: "string" }
|
|
13075
13439
|
}
|
|
13076
13440
|
},
|
|
@@ -13078,8 +13442,13 @@ registerTopicOperation({
|
|
|
13078
13442
|
const revision = requiredString(inputs.contractRevision, "contractRevision");
|
|
13079
13443
|
const digest2 = requiredString(inputs.contractDigest, "contractDigest");
|
|
13080
13444
|
if (revision !== topicContext(ctx).contract.revision || digest2 !== topicContext(ctx).contract.digest)
|
|
13081
|
-
throw new Error("
|
|
13082
|
-
return {
|
|
13445
|
+
throw new Error("Setup confirmation must target the exact proposed contract revision and digest");
|
|
13446
|
+
return {
|
|
13447
|
+
contractRevision: revision,
|
|
13448
|
+
contractDigest: digest2,
|
|
13449
|
+
confirmationReference: requiredString(inputs.confirmationReference, "confirmationReference"),
|
|
13450
|
+
...inputs.transitionCode ? { transitionCode: String(inputs.transitionCode) } : {}
|
|
13451
|
+
};
|
|
13083
13452
|
}
|
|
13084
13453
|
});
|
|
13085
13454
|
registerTopicOperation({
|
|
@@ -13103,35 +13472,6 @@ registerTopicOperation({
|
|
|
13103
13472
|
}
|
|
13104
13473
|
})
|
|
13105
13474
|
});
|
|
13106
|
-
registerTopicOperation({
|
|
13107
|
-
type: "qi/topic.outcome.confirm",
|
|
13108
|
-
can: "topic/outcome.confirm",
|
|
13109
|
-
operationType: "update-contract",
|
|
13110
|
-
confirmation: true,
|
|
13111
|
-
owner: "human",
|
|
13112
|
-
ability: "topic/update-contract",
|
|
13113
|
-
inputSchema: {
|
|
13114
|
-
type: "object",
|
|
13115
|
-
required: ["proposedOutcomeRecordId", "confirmationAuthorityDid", "confirmationReference"],
|
|
13116
|
-
additionalProperties: false,
|
|
13117
|
-
properties: {
|
|
13118
|
-
proposedOutcomeRecordId: { type: "string" },
|
|
13119
|
-
confirmationAuthorityDid: { type: "string", pattern: "^did:" },
|
|
13120
|
-
confirmationReference: { type: "string" },
|
|
13121
|
-
idempotencyKey: { type: "string" }
|
|
13122
|
-
}
|
|
13123
|
-
},
|
|
13124
|
-
buildPayload: (inputs) => ({
|
|
13125
|
-
patch: {
|
|
13126
|
-
outcome: {
|
|
13127
|
-
status: "achieved",
|
|
13128
|
-
outcomeRecordId: requiredString(inputs.proposedOutcomeRecordId, "proposedOutcomeRecordId"),
|
|
13129
|
-
confirmedBy: requiredString(inputs.confirmationAuthorityDid, "confirmationAuthorityDid"),
|
|
13130
|
-
confirmationReference: requiredString(inputs.confirmationReference, "confirmationReference")
|
|
13131
|
-
}
|
|
13132
|
-
}
|
|
13133
|
-
})
|
|
13134
|
-
});
|
|
13135
13475
|
registerTopicOperation({
|
|
13136
13476
|
type: "qi/topic.decision.record",
|
|
13137
13477
|
can: "topic/decision.record",
|
|
@@ -13540,6 +13880,60 @@ registerSemanticAction({
|
|
|
13540
13880
|
occurredAt: String(inputs.occurredAt || (/* @__PURE__ */ new Date()).toISOString())
|
|
13541
13881
|
})
|
|
13542
13882
|
});
|
|
13883
|
+
registerAction({
|
|
13884
|
+
type: "qi/topic.remind",
|
|
13885
|
+
can: "topic/reminder.deliver",
|
|
13886
|
+
displayName: "Send a Topic reminder",
|
|
13887
|
+
description: "Posts a reminder into the Topic thread and notifies the people responsible for it.",
|
|
13888
|
+
sideEffect: true,
|
|
13889
|
+
proof: { fields: ["deliveredAt"] },
|
|
13890
|
+
done: doneWhenCompleted,
|
|
13891
|
+
defaultRequiresConfirmation: false,
|
|
13892
|
+
executionOwner: "agent",
|
|
13893
|
+
riskTier: "low",
|
|
13894
|
+
requiredServices: ["topic"],
|
|
13895
|
+
eligibleForTimeTrigger: true,
|
|
13896
|
+
scheduling: {
|
|
13897
|
+
riskTier: "R0",
|
|
13898
|
+
misfirePolicies: ["run_once_immediately", "skip"],
|
|
13899
|
+
// Reminders never queue: two firings of the same reminder are the same
|
|
13900
|
+
// reminder, and delivering it twice is the failure mode, not the goal.
|
|
13901
|
+
overlapPolicies: ["skip"],
|
|
13902
|
+
approvalRequirement: "none",
|
|
13903
|
+
idempotencyStrategy: "idempotency_key",
|
|
13904
|
+
inputModes: ["resolve_at_fire"],
|
|
13905
|
+
runModes: ["new_run_per_occurrence"]
|
|
13906
|
+
},
|
|
13907
|
+
topic: topicMetadata(ALL_KINDS2, [], ["topic/manage-reminder"], "contextual"),
|
|
13908
|
+
inputSchema: {
|
|
13909
|
+
type: "object",
|
|
13910
|
+
required: ["recipients"],
|
|
13911
|
+
additionalProperties: false,
|
|
13912
|
+
properties: {
|
|
13913
|
+
recipients: { type: "array", items: { type: "string" } },
|
|
13914
|
+
message: { type: "string" },
|
|
13915
|
+
idempotencyKey: { type: "string" }
|
|
13916
|
+
}
|
|
13917
|
+
},
|
|
13918
|
+
outputSchema: [
|
|
13919
|
+
{ path: "deliveredAt", displayName: "Delivered at", type: "string" },
|
|
13920
|
+
{ path: "recipients", displayName: "Reminded", type: "string" }
|
|
13921
|
+
],
|
|
13922
|
+
run: async (inputs, ctx) => {
|
|
13923
|
+
const service = topicService(ctx);
|
|
13924
|
+
if (!service.deliverReminder) throw new Error("The host did not grant a Topic reminder delivery service");
|
|
13925
|
+
const recipients = requiredArray(inputs.recipients, "recipients");
|
|
13926
|
+
if (recipients.length === 0) throw new Error("A reminder needs at least one recipient");
|
|
13927
|
+
return {
|
|
13928
|
+
output: await service.deliverReminder({
|
|
13929
|
+
context: topicContext(ctx),
|
|
13930
|
+
recipients,
|
|
13931
|
+
message: String(inputs.message || ""),
|
|
13932
|
+
idempotencyKey: idempotencyKey("qi/topic.remind", inputs, ctx)
|
|
13933
|
+
})
|
|
13934
|
+
};
|
|
13935
|
+
}
|
|
13936
|
+
});
|
|
13543
13937
|
|
|
13544
13938
|
// src/core/lib/actionRegistry/actions/calendar/eventCreate.types.ts
|
|
13545
13939
|
function parseAttendeesField(raw) {
|
|
@@ -22616,8 +23010,10 @@ function createOracleInitFlowTemplate() {
|
|
|
22616
23010
|
}
|
|
22617
23011
|
// Annotate the CommonJS export names for ESM import in node:
|
|
22618
23012
|
0 && (module.exports = {
|
|
23013
|
+
ACTION_MANIFEST_V2_SCHEMA,
|
|
22619
23014
|
ACTION_MANIFEST_VERSION,
|
|
22620
23015
|
ACTION_REGISTRY_VERSION,
|
|
23016
|
+
ActionManifestV2VerificationError,
|
|
22621
23017
|
ExplicitRunRequiredError,
|
|
22622
23018
|
FLOW_CONNECTIONS_MAP_KEY,
|
|
22623
23019
|
FLOW_CONNECTION_BINDINGS_MAP_KEY,
|
|
@@ -22683,6 +23079,7 @@ function createOracleInitFlowTemplate() {
|
|
|
22683
23079
|
canToActionType,
|
|
22684
23080
|
canToType,
|
|
22685
23081
|
cancelRun,
|
|
23082
|
+
canonicalizeManifestV2Payload,
|
|
22686
23083
|
capabilityPatternCoversCan,
|
|
22687
23084
|
classifyBlockerCause,
|
|
22688
23085
|
classifyNodeState,
|
|
@@ -22692,6 +23089,7 @@ function createOracleInitFlowTemplate() {
|
|
|
22692
23089
|
closeRun,
|
|
22693
23090
|
collectPhantomLegacyRun,
|
|
22694
23091
|
compileBaseUcanFlow,
|
|
23092
|
+
computeActionManifestV2Digest,
|
|
22695
23093
|
computeAgentCommandId,
|
|
22696
23094
|
computeCID,
|
|
22697
23095
|
computeJsonCID,
|
|
@@ -22868,6 +23266,7 @@ function createOracleInitFlowTemplate() {
|
|
|
22868
23266
|
setTempUcanEnforcementDisabled,
|
|
22869
23267
|
setupFlowFromBaseUcan,
|
|
22870
23268
|
sha256Digest,
|
|
23269
|
+
signActionManifestV2,
|
|
22871
23270
|
snapshotInputRefs,
|
|
22872
23271
|
snapshotNode,
|
|
22873
23272
|
startRun,
|
|
@@ -22897,6 +23296,7 @@ function createOracleInitFlowTemplate() {
|
|
|
22897
23296
|
validateFlowAgentLease,
|
|
22898
23297
|
validateTopicSemanticRecord,
|
|
22899
23298
|
validateTopicSemanticRecordBatch,
|
|
23299
|
+
verifyActionManifestV2,
|
|
22900
23300
|
verifyCompletion,
|
|
22901
23301
|
writeActionState,
|
|
22902
23302
|
writeCompiledBlocksToFragment,
|