@oomol-lab/open-flow 0.1.0-beta.63 → 0.1.0-beta.65

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.
@@ -0,0 +1,19 @@
1
+ import { z } from 'zod';
2
+ export declare const canvasMinZoom = 0.1;
3
+ export declare const canvasMaxZoom = 3;
4
+ /** Transient operations on each connected canvas's own viewport. */
5
+ export declare const canvasCommandSchema: z.ZodDiscriminatedUnion<[z.ZodObject<{
6
+ type: z.ZodLiteral<"focus">;
7
+ nodeId: z.ZodString;
8
+ }, z.core.$strict>, z.ZodObject<{
9
+ type: z.ZodLiteral<"zoom">;
10
+ zoom: z.ZodNumber;
11
+ }, z.core.$strict>, z.ZodObject<{
12
+ type: z.ZodLiteral<"pan">;
13
+ dx: z.ZodNumber;
14
+ dy: z.ZodNumber;
15
+ }, z.core.$strict>, z.ZodObject<{
16
+ type: z.ZodLiteral<"fit">;
17
+ }, z.core.$strict>], "type">;
18
+ export type CanvasCommand = z.infer<typeof canvasCommandSchema>;
19
+ export type CanvasCommandSubscriber = (execute: (command: CanvasCommand) => void) => () => void;
@@ -1,4 +1,5 @@
1
- import type { ConnectorAccess, ConnectorAccessSnapshot, ConnectorAccessCandidates, ConnectorAccessCandidatesBatch, ConnectorAction, ConnectorActionMetadata, ConnectorConnection, ConnectorProvider } from './control-api.js';
1
+ import type { ConnectorAccess, ConnectorAccessSnapshot, ConnectorAccessCandidates, ConnectorAccessCandidatesBatch, ConnectorAction, ConnectorActionMetadata, ConnectorConnection, ConnectorProvider, LeinaBot } from './control-api.js';
2
+ export declare function leinaBots(value: unknown): readonly LeinaBot[];
2
3
  export declare function connectorAccess(value: unknown): ConnectorAccess;
3
4
  export declare function connectorAccessSnapshot(value: unknown): ConnectorAccessSnapshot;
4
5
  export declare function connectorAccessCandidates(value: unknown, providerId: string): ConnectorAccessCandidates;
@@ -10065,6 +10065,22 @@ function parseProviderAccessSource(value) {
10065
10065
  }
10066
10066
  //#endregion
10067
10067
  //#region src/control/common/connectorDecoders.ts
10068
+ function leinaBots(value) {
10069
+ const source = record$1(value);
10070
+ if (!Array.isArray(source.bots)) return invalidResponse("Leina bots: expected an array.");
10071
+ const bots = source.bots.map((entry) => {
10072
+ const bot = record$1(entry);
10073
+ if (!Array.isArray(bot.platforms)) return invalidResponse("Leina platforms: expected an array.");
10074
+ return {
10075
+ leinaId: string(bot.leinaId),
10076
+ name: string(bot.name),
10077
+ status: string(bot.status),
10078
+ platforms: bot.platforms.map(string)
10079
+ };
10080
+ });
10081
+ if (new Set(bots.map((bot) => bot.leinaId)).size != bots.length) return invalidResponse("Leina bots: duplicate identifiers.");
10082
+ return bots;
10083
+ }
10068
10084
  function accessPermissions(value) {
10069
10085
  const source = record$1(value);
10070
10086
  exact(source, [
@@ -11468,6 +11484,26 @@ var ControlClient = class {
11468
11484
  method: "POST"
11469
11485
  }));
11470
11486
  }
11487
+ async broadcastCanvas(flowId, command) {
11488
+ const source = record$1(await this.request(`/v1/flows/${segment(flowId)}/canvas`, {
11489
+ method: "POST",
11490
+ body: JSON.stringify({
11491
+ version: 1,
11492
+ command
11493
+ })
11494
+ }));
11495
+ exact(source, [
11496
+ "version",
11497
+ "flowId",
11498
+ "broadcast"
11499
+ ]);
11500
+ if (source.version != 1 || source.broadcast !== true || source.flowId !== flowId) return invalidResponse();
11501
+ return {
11502
+ version: 1,
11503
+ flowId: string(source.flowId),
11504
+ broadcast: true
11505
+ };
11506
+ }
11471
11507
  async getFlow(flowId) {
11472
11508
  return flow(await this.request(`/v1/flows/${segment(flowId)}`));
11473
11509
  }
@@ -11648,6 +11684,9 @@ var ControlClient = class {
11648
11684
  const query = connectorProvidersQuery(flowId, locale);
11649
11685
  return this.connectorRequest(query.path, "providers", signal, query.decode);
11650
11686
  }
11687
+ async listLeinaBots(flowId, signal) {
11688
+ return leinaBots(await this.request(`/v1/connector/leina/bots?flowId=${segment(flowId)}`, { signal }));
11689
+ }
11651
11690
  async removeConnectionUsage(flowId, connectionId, expectedRevisionId, expectedAccessRevision, idempotencyKey) {
11652
11691
  return draftChange(await this.request(`/v1/flows/${segment(flowId)}/connection-usage/remove`, {
11653
11692
  method: "POST",
@@ -1,3 +1,5 @@
1
+ import type { CanvasCommand } from './canvas-commands.js';
2
+ export type { CanvasCommand, CanvasCommandSubscriber } from './canvas-commands.js';
1
3
  import type { LiveDetails } from './liveDetails.js';
2
4
  export { liveEntries } from './liveDetails.js';
3
5
  export type { LiveDetails, LiveEntry } from './liveDetails.js';
@@ -30,6 +32,11 @@ export type { JsonValue, TriggerKeySnapshot, WaitAction } from '../browser/flow-
30
32
  export type { RunStatus } from './run-lifecycle.js';
31
33
  export { ApiError, controlErrorCode, controlErrorMetadata, type ControlErrorCode } from './control-api-errors.js';
32
34
  export type { FlowCatalogEvent, FlowChangeEvent } from './flow-notifications.js';
35
+ export interface CanvasBroadcast {
36
+ readonly version: 1;
37
+ readonly flowId: string;
38
+ readonly broadcast: true;
39
+ }
33
40
  export type ControlRequest = (path: string, init?: RequestInit) => Promise<Response>;
34
41
  export interface ErrorListener {
35
42
  readonly flowId: string;
@@ -194,6 +201,12 @@ export interface ConnectorProvider extends ProviderIconAppearance {
194
201
  readonly serviceName: string;
195
202
  }
196
203
  export type ConnectorAccessMode = 'implicit' | 'selectable';
204
+ export interface LeinaBot {
205
+ readonly leinaId: string;
206
+ readonly name: string;
207
+ readonly status: string;
208
+ readonly platforms: readonly string[];
209
+ }
197
210
  export type ProviderAccessBindingStatus = 'active' | 'forbidden' | 'invalid' | 'missing';
198
211
  export type ProviderAccessBinding = ((ProviderAccessIdentity & {
199
212
  readonly status: ProviderAccessBindingStatus;
@@ -791,6 +804,7 @@ export declare class ControlClient {
791
804
  readonly idempotencyKey?: string;
792
805
  }): Promise<Flow>;
793
806
  createFlow(name: string, idempotencyKey?: string, teamId?: string): Promise<Flow>;
807
+ broadcastCanvas(flowId: string, command: CanvasCommand): Promise<CanvasBroadcast>;
794
808
  getFlow(flowId: string): Promise<Flow>;
795
809
  getErrorListeners(flowId: string, signal?: AbortSignal): Promise<readonly ErrorListener[]>;
796
810
  renameFlow(flowId: string, name: string): Promise<Flow>;
@@ -833,6 +847,7 @@ export declare class ControlClient {
833
847
  version: 1;
834
848
  }>;
835
849
  listConnectorProviders(signal?: AbortSignal, flowId?: string, locale?: string): Promise<readonly ConnectorProvider[]>;
850
+ listLeinaBots(flowId: string, signal?: AbortSignal): Promise<readonly LeinaBot[]>;
836
851
  removeConnectionUsage(flowId: string, connectionId: string, expectedRevisionId: string, expectedAccessRevision: number, idempotencyKey: string): Promise<DraftChange>;
837
852
  getConnectorAccess(flowId: string, signal?: AbortSignal): Promise<ConnectorAccess>;
838
853
  getPublishedConnectorAccess(flowId: string, publicationId: string, signal?: AbortSignal): Promise<ConnectorAccessSnapshot>;
@@ -10220,6 +10220,22 @@ async function providerAccessBindingId(teamId, identity) {
10220
10220
  }
10221
10221
  //#endregion
10222
10222
  //#region src/control/common/connectorDecoders.ts
10223
+ function leinaBots(value) {
10224
+ const source = record(value);
10225
+ if (!Array.isArray(source.bots)) return invalidResponse("Leina bots: expected an array.");
10226
+ const bots = source.bots.map((entry) => {
10227
+ const bot = record(entry);
10228
+ if (!Array.isArray(bot.platforms)) return invalidResponse("Leina platforms: expected an array.");
10229
+ return {
10230
+ leinaId: string(bot.leinaId),
10231
+ name: string(bot.name),
10232
+ status: string(bot.status),
10233
+ platforms: bot.platforms.map(string)
10234
+ };
10235
+ });
10236
+ if (new Set(bots.map((bot) => bot.leinaId)).size != bots.length) return invalidResponse("Leina bots: duplicate identifiers.");
10237
+ return bots;
10238
+ }
10223
10239
  function accessPermissions(value) {
10224
10240
  const source = record(value);
10225
10241
  exact(source, [
@@ -10736,6 +10752,12 @@ function resolutionOutputPorts(node) {
10736
10752
  pending: objectPort({
10737
10753
  inputs,
10738
10754
  prompt: { type: "string" },
10755
+ pageUrl: { type: "string" },
10756
+ message: {
10757
+ type: "string",
10758
+ minLength: 1,
10759
+ pattern: "\\S"
10760
+ },
10739
10761
  ...Object.fromEntries(actions.map((action) => [`${action}Url`, { type: "string" }])),
10740
10762
  expiresAt: { type: "string" }
10741
10763
  }),
@@ -12124,6 +12146,26 @@ var ControlClient = class {
12124
12146
  method: "POST"
12125
12147
  }));
12126
12148
  }
12149
+ async broadcastCanvas(flowId, command) {
12150
+ const source = record(await this.request(`/v1/flows/${segment(flowId)}/canvas`, {
12151
+ method: "POST",
12152
+ body: JSON.stringify({
12153
+ version: 1,
12154
+ command
12155
+ })
12156
+ }));
12157
+ exact(source, [
12158
+ "version",
12159
+ "flowId",
12160
+ "broadcast"
12161
+ ]);
12162
+ if (source.version != 1 || source.broadcast !== true || source.flowId !== flowId) return invalidResponse();
12163
+ return {
12164
+ version: 1,
12165
+ flowId: string(source.flowId),
12166
+ broadcast: true
12167
+ };
12168
+ }
12127
12169
  async getFlow(flowId) {
12128
12170
  return flow(await this.request(`/v1/flows/${segment(flowId)}`));
12129
12171
  }
@@ -12304,6 +12346,9 @@ var ControlClient = class {
12304
12346
  const query = connectorProvidersQuery(flowId, locale);
12305
12347
  return this.connectorRequest(query.path, "providers", signal, query.decode);
12306
12348
  }
12349
+ async listLeinaBots(flowId, signal) {
12350
+ return leinaBots(await this.request(`/v1/connector/leina/bots?flowId=${segment(flowId)}`, { signal }));
12351
+ }
12307
12352
  async removeConnectionUsage(flowId, connectionId, expectedRevisionId, expectedAccessRevision, idempotencyKey) {
12308
12353
  return draftChange(await this.request(`/v1/flows/${segment(flowId)}/connection-usage/remove`, {
12309
12354
  method: "POST",
@@ -1,3 +1,4 @@
1
+ export { canvasCommandSchema } from './canvas-commands.js';
1
2
  export * from './authoring.js';
2
3
  import type { JsonValue } from '../browser/flow-change.js';
3
4
  import type { DraftOperation } from './draftOperations.js';
@@ -9,6 +10,22 @@ export declare const waitActionBodySchema: {
9
10
  };
10
11
  };
11
12
  export declare const controlRequests: {
13
+ canvas: (value: unknown) => {
14
+ command: {
15
+ type: "focus";
16
+ nodeId: string;
17
+ } | {
18
+ type: "zoom";
19
+ zoom: number;
20
+ } | {
21
+ type: "pan";
22
+ dx: number;
23
+ dy: number;
24
+ } | {
25
+ type: "fit";
26
+ };
27
+ version: 1;
28
+ };
12
29
  authoringCheck: (value: unknown) => {
13
30
  revisionId: string;
14
31
  };
@@ -5852,6 +5852,23 @@ function preprocess(fn, schema) {
5852
5852
  out: schema
5853
5853
  });
5854
5854
  }
5855
+ /** Transient operations on each connected canvas's own viewport. */
5856
+ var canvasCommandSchema = discriminatedUnion("type", [
5857
+ strictObject({
5858
+ type: literal("focus"),
5859
+ nodeId: string().min(1)
5860
+ }),
5861
+ strictObject({
5862
+ type: literal("zoom"),
5863
+ zoom: number().min(.1).max(3)
5864
+ }),
5865
+ strictObject({
5866
+ type: literal("pan"),
5867
+ dx: number(),
5868
+ dy: number()
5869
+ }),
5870
+ strictObject({ type: literal("fit") })
5871
+ ]);
5855
5872
  //#endregion
5856
5873
  //#region ../../node_modules/.bun/dequal@2.0.3/node_modules/dequal/lite/index.mjs
5857
5874
  var has = Object.prototype.hasOwnProperty;
@@ -12027,6 +12044,41 @@ function connectorOutputMode(schema) {
12027
12044
  return properties != null && Object.keys(properties).length > 0 || root?.type == "object" && root.additionalProperties === false ? "fields" : "value";
12028
12045
  }
12029
12046
  //#endregion
12047
+ //#region src/flow/common/edgeChanges.ts
12048
+ function connect(content, edge) {
12049
+ const selected = content.document.graph;
12050
+ if (selected?.edges.some((candidate) => dequal(candidate, edge))) return [];
12051
+ const changes = [{
12052
+ edge,
12053
+ kind: "graph.edge.connect"
12054
+ }];
12055
+ const source = selected.nodes[edge.source];
12056
+ const target = selected.nodes[edge.target];
12057
+ if (edge.sourceHandle == "pending" && (source?.kind == "approval" || source?.kind == "wait") && target?.kind == "task" && "executor" in target.task && target.task.executor.kind == "connector" && target.task.executor.action == "leina.send_notification" && (target.inputs.message == null || target.inputs.message.kind == "unset")) changes.push({
12058
+ kind: "graph.node.input.set",
12059
+ nodeId: edge.target,
12060
+ handle: "message",
12061
+ before: target.inputs.message,
12062
+ value: {
12063
+ kind: "sources",
12064
+ sources: [{
12065
+ kind: "node",
12066
+ nodeId: edge.source,
12067
+ output: "pending",
12068
+ field: "message"
12069
+ }]
12070
+ }
12071
+ });
12072
+ return changes;
12073
+ }
12074
+ function disconnect(content, edge) {
12075
+ if (!content.document.graph?.edges.some((candidate) => dequal(candidate, edge))) return [];
12076
+ return [{
12077
+ edge,
12078
+ kind: "graph.edge.disconnect"
12079
+ }];
12080
+ }
12081
+ //#endregion
12030
12082
  //#region src/trigger/common/contract.ts
12031
12083
  var errorOutputs = [
12032
12084
  {
@@ -12190,6 +12242,12 @@ function resolutionOutputPorts(node) {
12190
12242
  pending: objectPort({
12191
12243
  inputs,
12192
12244
  prompt: { type: "string" },
12245
+ pageUrl: { type: "string" },
12246
+ message: {
12247
+ type: "string",
12248
+ minLength: 1,
12249
+ pattern: "\\S"
12250
+ },
12193
12251
  ...Object.fromEntries(actions.map((action) => [`${action}Url`, { type: "string" }])),
12194
12252
  expiresAt: { type: "string" }
12195
12253
  }),
@@ -13113,6 +13171,7 @@ async function compileAuthoring(base, request, host) {
13113
13171
  let content = base, index = 0, sequence = 0;
13114
13172
  const operations = [], aliases = {};
13115
13173
  const touchedModules = /* @__PURE__ */ new Set();
13174
+ const explicitMessages = /* @__PURE__ */ new Set();
13116
13175
  function fresh(label) {
13117
13176
  return host.id(`${index}:${label}:${sequence++}`);
13118
13177
  }
@@ -13422,6 +13481,7 @@ async function compileAuthoring(base, request, host) {
13422
13481
  });
13423
13482
  }
13424
13483
  async function setInput(ref, input, value) {
13484
+ if (input == "message") explicitMessages.add(ref);
13425
13485
  const node = nodeAt(content, ref);
13426
13486
  if (node.kind == "condition") fail("input.unsupported", "Edit the branch condition operands through config.branches.", {
13427
13487
  node: ref,
@@ -13598,11 +13658,8 @@ async function compileAuthoring(base, request, host) {
13598
13658
  target: to,
13599
13659
  ...edit.branch == null ? {} : { sourceHandle: edit.branch }
13600
13660
  };
13601
- const exists = content.document.graph.edges.some((e) => dequal(e, edge));
13602
- if (edit.op == "edge.connect" != exists) apply([{
13603
- kind: edit.op == "edge.connect" ? "graph.edge.connect" : "graph.edge.disconnect",
13604
- edge
13605
- }]);
13661
+ const changes = edit.op == "edge.connect" ? connect(content, edge) : disconnect(content, edge);
13662
+ apply(explicitMessages.has(to) ? changes.filter((change) => change.kind != "graph.node.input.set") : changes);
13606
13663
  break;
13607
13664
  }
13608
13665
  case "text.set":
@@ -14012,6 +14069,10 @@ var trigger = strictObject({
14012
14069
  outputs: record$3(string(), json)
14013
14070
  });
14014
14071
  var schemas = {
14072
+ canvas: strictObject({
14073
+ command: canvasCommandSchema,
14074
+ version
14075
+ }),
14015
14076
  authoringCheck: authoringCheckSchema,
14016
14077
  authoringEdit: authoringRequestSchema,
14017
14078
  authoringRead: authoringReadSchema,
@@ -14123,6 +14184,7 @@ function decoder(schema) {
14123
14184
  return (value) => schema.parse(value);
14124
14185
  }
14125
14186
  var controlRequests = {
14187
+ canvas: decoder(schemas.canvas),
14126
14188
  authoringCheck: decoder(schemas.authoringCheck),
14127
14189
  authoringEdit: decoder(schemas.authoringEdit),
14128
14190
  authoringRead: decoder(schemas.authoringRead),
@@ -14171,4 +14233,4 @@ function controlRequestSchema(name) {
14171
14233
  return schema;
14172
14234
  }
14173
14235
  //#endregion
14174
- export { AuthoringError, authoringCheckResponse, authoringCheckSchema, authoringConfigurations, authoringDiagnosticSchema, authoringDiagnostics, authoringEditResponse, authoringEditSchema, authoringExample, authoringExamples, authoringNode, authoringReadResponse, authoringReadSchema, authoringRequestContract, authoringRequestSchema, authoringSchema, authoringSchemaQuery, authoringSearchResponse, authoringSearchSchema, authoringSourceSchema, authoringTypes, compileAuthoring, controlRequestSchema, controlRequests, decodeDraftOperations, draftOperationsSchema, readAuthoring, resolveDraftOperations, searchAuthoring, waitActionBodySchema };
14236
+ export { AuthoringError, authoringCheckResponse, authoringCheckSchema, authoringConfigurations, authoringDiagnosticSchema, authoringDiagnostics, authoringEditResponse, authoringEditSchema, authoringExample, authoringExamples, authoringNode, authoringReadResponse, authoringReadSchema, authoringRequestContract, authoringRequestSchema, authoringSchema, authoringSchemaQuery, authoringSearchResponse, authoringSearchSchema, authoringSourceSchema, authoringTypes, canvasCommandSchema, compileAuthoring, controlRequestSchema, controlRequests, decodeDraftOperations, draftOperationsSchema, readAuthoring, resolveDraftOperations, searchAuthoring, waitActionBodySchema };
@@ -1,3 +1,4 @@
1
+ import type { CanvasCommand } from '../common/canvas-commands.js';
1
2
  export type FlowCatalogEvent = {
2
3
  readonly kind: 'flows.changed';
3
4
  readonly version: 1;
@@ -7,6 +8,11 @@ export type FlowCatalogEvent = {
7
8
  readonly version: 1;
8
9
  };
9
10
  export type FlowChangeEvent = {
11
+ readonly kind: 'canvas.command';
12
+ readonly flowId: string;
13
+ readonly command: CanvasCommand;
14
+ readonly version: 1;
15
+ } | {
10
16
  readonly accessRevision: number;
11
17
  readonly flowId: string;
12
18
  readonly kind: 'access.changed';
@@ -12045,6 +12045,12 @@ function resolutionOutputPorts(node) {
12045
12045
  pending: objectPort({
12046
12046
  inputs,
12047
12047
  prompt: { type: "string" },
12048
+ pageUrl: { type: "string" },
12049
+ message: {
12050
+ type: "string",
12051
+ minLength: 1,
12052
+ pattern: "\\S"
12053
+ },
12048
12054
  ...Object.fromEntries(actions.map((action) => [`${action}Url`, { type: "string" }])),
12049
12055
  expiresAt: { type: "string" }
12050
12056
  }),
@@ -3,6 +3,48 @@ import { z } from 'zod';
3
3
  export declare const mcpProtocolVersion = "2026-07-28";
4
4
  export declare const mcpInstructions: string;
5
5
  export declare const mcpTools: {
6
+ flow_canvas: {
7
+ description: string;
8
+ annotations: {
9
+ readOnlyHint: boolean;
10
+ destructiveHint: boolean;
11
+ idempotentHint: boolean;
12
+ openWorldHint: boolean;
13
+ };
14
+ inputSchema: {
15
+ '~standard': {
16
+ version: 1;
17
+ vendor: string;
18
+ jsonSchema: {
19
+ input: () => Record<string, unknown>;
20
+ output: () => Record<string, unknown>;
21
+ };
22
+ validate(value: unknown): {
23
+ value: {
24
+ flowId: string;
25
+ command: {
26
+ type: "focus";
27
+ nodeId: string;
28
+ } | {
29
+ type: "zoom";
30
+ zoom: number;
31
+ } | {
32
+ type: "pan";
33
+ dx: number;
34
+ dy: number;
35
+ } | {
36
+ type: "fit";
37
+ };
38
+ };
39
+ } | {
40
+ issues: {
41
+ message: string;
42
+ path: string[];
43
+ }[];
44
+ };
45
+ };
46
+ };
47
+ };
6
48
  flow_live: {
7
49
  description: string;
8
50
  annotations: {