@minicor/mcp-server 3.6.0 → 3.9.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.
Files changed (100) hide show
  1. package/README.md +66 -1
  2. package/dist/__tests__/builder-discovery.test.d.ts +2 -0
  3. package/dist/__tests__/builder-discovery.test.d.ts.map +1 -0
  4. package/dist/__tests__/builder-discovery.test.js +120 -0
  5. package/dist/__tests__/builder-discovery.test.js.map +1 -0
  6. package/dist/__tests__/codemode.test.js +35 -0
  7. package/dist/__tests__/codemode.test.js.map +1 -1
  8. package/dist/__tests__/config-stores.test.d.ts +2 -0
  9. package/dist/__tests__/config-stores.test.d.ts.map +1 -0
  10. package/dist/__tests__/config-stores.test.js +88 -0
  11. package/dist/__tests__/config-stores.test.js.map +1 -0
  12. package/dist/__tests__/dev-mode-draft.test.d.ts +2 -0
  13. package/dist/__tests__/dev-mode-draft.test.d.ts.map +1 -0
  14. package/dist/__tests__/dev-mode-draft.test.js +260 -0
  15. package/dist/__tests__/dev-mode-draft.test.js.map +1 -0
  16. package/dist/__tests__/disk-token-store.test.d.ts +2 -0
  17. package/dist/__tests__/disk-token-store.test.d.ts.map +1 -0
  18. package/dist/__tests__/disk-token-store.test.js +231 -0
  19. package/dist/__tests__/disk-token-store.test.js.map +1 -0
  20. package/dist/__tests__/laminar-client.test.js +154 -0
  21. package/dist/__tests__/laminar-client.test.js.map +1 -1
  22. package/dist/__tests__/lib-dev-mode.test.d.ts +2 -0
  23. package/dist/__tests__/lib-dev-mode.test.d.ts.map +1 -0
  24. package/dist/__tests__/lib-dev-mode.test.js +48 -0
  25. package/dist/__tests__/lib-dev-mode.test.js.map +1 -0
  26. package/dist/__tests__/paths.test.d.ts +2 -0
  27. package/dist/__tests__/paths.test.d.ts.map +1 -0
  28. package/dist/__tests__/paths.test.js +55 -0
  29. package/dist/__tests__/paths.test.js.map +1 -0
  30. package/dist/__tests__/recording-frames.test.d.ts +2 -0
  31. package/dist/__tests__/recording-frames.test.d.ts.map +1 -0
  32. package/dist/__tests__/recording-frames.test.js +46 -0
  33. package/dist/__tests__/recording-frames.test.js.map +1 -0
  34. package/dist/__tests__/server-profile.test.d.ts +2 -0
  35. package/dist/__tests__/server-profile.test.d.ts.map +1 -0
  36. package/dist/__tests__/server-profile.test.js +311 -0
  37. package/dist/__tests__/server-profile.test.js.map +1 -0
  38. package/dist/builder-index.d.ts +3 -0
  39. package/dist/builder-index.d.ts.map +1 -0
  40. package/dist/builder-index.js +5 -0
  41. package/dist/builder-index.js.map +1 -0
  42. package/dist/cli.js +4 -3
  43. package/dist/cli.js.map +1 -1
  44. package/dist/codemode.d.ts +3 -1
  45. package/dist/codemode.d.ts.map +1 -1
  46. package/dist/codemode.js +20 -6
  47. package/dist/codemode.js.map +1 -1
  48. package/dist/disk-token-store.d.ts +101 -0
  49. package/dist/disk-token-store.d.ts.map +1 -0
  50. package/dist/disk-token-store.js +398 -0
  51. package/dist/disk-token-store.js.map +1 -0
  52. package/dist/index.d.ts.map +1 -1
  53. package/dist/index.js +98 -111
  54. package/dist/index.js.map +1 -1
  55. package/dist/laminar-client.d.ts +111 -0
  56. package/dist/laminar-client.d.ts.map +1 -1
  57. package/dist/laminar-client.js +47 -1
  58. package/dist/laminar-client.js.map +1 -1
  59. package/dist/lib.d.ts +4 -0
  60. package/dist/lib.d.ts.map +1 -1
  61. package/dist/lib.js +53 -58
  62. package/dist/lib.js.map +1 -1
  63. package/dist/paths.d.ts +4 -0
  64. package/dist/paths.d.ts.map +1 -1
  65. package/dist/paths.js +33 -0
  66. package/dist/paths.js.map +1 -1
  67. package/dist/prompts/debug-execution.d.ts.map +1 -1
  68. package/dist/prompts/debug-execution.js +3 -2
  69. package/dist/prompts/debug-execution.js.map +1 -1
  70. package/dist/recording-frames.d.ts +58 -0
  71. package/dist/recording-frames.d.ts.map +1 -0
  72. package/dist/recording-frames.js +244 -0
  73. package/dist/recording-frames.js.map +1 -0
  74. package/dist/seed-skills.js +3 -2
  75. package/dist/seed-skills.js.map +1 -1
  76. package/dist/server-profile.d.ts +11 -0
  77. package/dist/server-profile.d.ts.map +1 -0
  78. package/dist/server-profile.js +104 -0
  79. package/dist/server-profile.js.map +1 -0
  80. package/dist/setup.d.ts +1 -0
  81. package/dist/setup.d.ts.map +1 -1
  82. package/dist/setup.js +81 -71
  83. package/dist/setup.js.map +1 -1
  84. package/dist/tools/builder-discovery.d.ts +17 -0
  85. package/dist/tools/builder-discovery.d.ts.map +1 -0
  86. package/dist/tools/builder-discovery.js +131 -0
  87. package/dist/tools/builder-discovery.js.map +1 -0
  88. package/dist/tools/core.d.ts.map +1 -1
  89. package/dist/tools/core.js +117 -43
  90. package/dist/tools/core.js.map +1 -1
  91. package/dist/tools/dev-mode-draft.d.ts +3 -0
  92. package/dist/tools/dev-mode-draft.d.ts.map +1 -0
  93. package/dist/tools/dev-mode-draft.js +279 -0
  94. package/dist/tools/dev-mode-draft.js.map +1 -0
  95. package/dist/tools/vm.d.ts.map +1 -1
  96. package/dist/tools/vm.js +3 -35
  97. package/dist/tools/vm.js.map +1 -1
  98. package/dist/types.d.ts +9 -0
  99. package/dist/types.d.ts.map +1 -1
  100. package/package.json +2 -1
package/dist/lib.d.ts CHANGED
@@ -15,6 +15,7 @@
15
15
  import { McpServer } from "@modelcontextprotocol/sdk/server/mcp.js";
16
16
  import type { Transport } from "@modelcontextprotocol/sdk/shared/transport.js";
17
17
  import { type Region } from "./paths.js";
18
+ import { type MinicorServerProfile } from "./server-profile.js";
18
19
  export interface TokenCredentials {
19
20
  access_token: string;
20
21
  refresh_token: string;
@@ -33,6 +34,8 @@ export interface MinicorServerOptions {
33
34
  vmServiceBaseUrl?: string;
34
35
  /** Expose the experimental single code-mode tool instead of the default one-tool-per-operation surface. Defaults to false (opt in via EXPERIMENTAL_USE_CODE_MODE=1). */
35
36
  codeMode?: boolean;
37
+ /** Tool and instruction profile. Defaults to the backwards-compatible full server. */
38
+ profile?: MinicorServerProfile;
36
39
  }
37
40
  /**
38
41
  * Create and connect a Minicor MCP server on the given transport.
@@ -43,5 +46,6 @@ export declare function createMinicorServer(transport: Transport, opts?: Minicor
43
46
  close: () => Promise<void>;
44
47
  }>;
45
48
  export type { LaminarAuth } from "./laminar-client.js";
49
+ export type { MinicorServerProfile } from "./server-profile.js";
46
50
  export type { ToolDeps } from "./types.js";
47
51
  //# sourceMappingURL=lib.d.ts.map
package/dist/lib.d.ts.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"file":"lib.d.ts","sourceRoot":"","sources":["../src/lib.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;GAaG;AAEH,OAAO,EAAE,SAAS,EAAE,MAAM,yCAAyC,CAAC;AACpE,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,+CAA+C,CAAC;AAE/E,OAAO,EAAmB,KAAK,MAAM,EAAE,MAAM,YAAY,CAAC;AA8B1D,MAAM,WAAW,gBAAgB;IAC/B,YAAY,EAAE,MAAM,CAAC;IACrB,aAAa,EAAE,MAAM,CAAC;IACtB,UAAU,EAAE,MAAM,CAAC;CACpB;AAED,MAAM,WAAW,oBAAoB;IACnC,+CAA+C;IAC/C,WAAW,CAAC,EAAE,gBAAgB,CAAC;IAC/B,2CAA2C;IAC3C,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,6DAA6D;IAC7D,iBAAiB,CAAC,EAAE,OAAO,CAAC,MAAM,CAAC,MAAM,EAAE,gBAAgB,GAAG;QAAE,OAAO,CAAC,EAAE,MAAM,CAAA;KAAE,CAAC,CAAC,CAAC;IACrF,uEAAuE;IACvE,gBAAgB,CAAC,EAAE,MAAM,CAAC;IAC1B,wKAAwK;IACxK,QAAQ,CAAC,EAAE,OAAO,CAAC;CACpB;AAoFD;;;GAGG;AACH,wBAAsB,mBAAmB,CACvC,SAAS,EAAE,SAAS,EACpB,IAAI,GAAE,oBAAyB,GAC9B,OAAO,CAAC;IAAE,MAAM,EAAE,SAAS,CAAC;IAAC,KAAK,EAAE,MAAM,OAAO,CAAC,IAAI,CAAC,CAAA;CAAE,CAAC,CAkG5D;AAED,YAAY,EAAE,WAAW,EAAE,MAAM,qBAAqB,CAAC;AACvD,YAAY,EAAE,QAAQ,EAAE,MAAM,YAAY,CAAC"}
1
+ {"version":3,"file":"lib.d.ts","sourceRoot":"","sources":["../src/lib.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;GAaG;AAEH,OAAO,EAAE,SAAS,EAAE,MAAM,yCAAyC,CAAC;AACpE,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,+CAA+C,CAAC;AAE/E,OAAO,EAIL,KAAK,MAAM,EACZ,MAAM,YAAY,CAAC;AASpB,OAAO,EAKL,KAAK,oBAAoB,EAC1B,MAAM,qBAAqB,CAAC;AAK7B,MAAM,WAAW,gBAAgB;IAC/B,YAAY,EAAE,MAAM,CAAC;IACrB,aAAa,EAAE,MAAM,CAAC;IACtB,UAAU,EAAE,MAAM,CAAC;CACpB;AAED,MAAM,WAAW,oBAAoB;IACnC,+CAA+C;IAC/C,WAAW,CAAC,EAAE,gBAAgB,CAAC;IAC/B,2CAA2C;IAC3C,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,6DAA6D;IAC7D,iBAAiB,CAAC,EAAE,OAAO,CAAC,MAAM,CAAC,MAAM,EAAE,gBAAgB,GAAG;QAAE,OAAO,CAAC,EAAE,MAAM,CAAA;KAAE,CAAC,CAAC,CAAC;IACrF,uEAAuE;IACvE,gBAAgB,CAAC,EAAE,MAAM,CAAC;IAC1B,wKAAwK;IACxK,QAAQ,CAAC,EAAE,OAAO,CAAC;IACnB,sFAAsF;IACtF,OAAO,CAAC,EAAE,oBAAoB,CAAC;CAChC;AAkDD;;;GAGG;AACH,wBAAsB,mBAAmB,CACvC,SAAS,EAAE,SAAS,EACpB,IAAI,GAAE,oBAAyB,GAC9B,OAAO,CAAC;IAAE,MAAM,EAAE,SAAS,CAAC;IAAC,KAAK,EAAE,MAAM,OAAO,CAAC,IAAI,CAAC,CAAA;CAAE,CAAC,CAiJ5D;AAED,YAAY,EAAE,WAAW,EAAE,MAAM,qBAAqB,CAAC;AACvD,YAAY,EAAE,oBAAoB,EAAE,MAAM,qBAAqB,CAAC;AAChE,YAAY,EAAE,QAAQ,EAAE,MAAM,YAAY,CAAC"}
package/dist/lib.js CHANGED
@@ -14,56 +14,12 @@
14
14
  */
15
15
  import { McpServer } from "@modelcontextprotocol/sdk/server/mcp.js";
16
16
  import { LaminarClient } from "./laminar-client.js";
17
- import { regionToApiBase } from "./paths.js";
17
+ import { apiBaseToRegion, resolveApiBase, validateApiBaseUrl, } from "./paths.js";
18
18
  import { TokenProvider } from "./token-provider.js";
19
19
  import { CodeModeToolRegistry, asMcpServer, buildCodeModeInstructions, shouldUseCodeMode, } from "./codemode.js";
20
- import { register as registerCore } from "./tools/core.js";
21
- import { register as registerWorkflowOps } from "./tools/workflow-ops.js";
22
- import { register as registerConfigStores } from "./tools/config-stores.js";
23
- import { register as registerSyncTools } from "./tools/sync-tools.js";
24
- import { register as registerVm } from "./tools/vm.js";
25
- import { register as registerVmRpa } from "./tools/vm-rpa.js";
26
- import { register as registerTfa } from "./tools/tfa.js";
27
- import { register as registerIssues } from "./tools/issues.js";
28
- import { register as registerAgents } from "./tools/agents.js";
29
- import { register as registerSkills } from "./tools/skills.js";
30
- import { register as registerSession, autoCheckpoint } from "./tools/session.js";
31
- import { register as registerWorkflowGuide } from "./prompts/workflow-guide.js";
32
- import { register as registerDebugExecution } from "./prompts/debug-execution.js";
33
- import { register as registerBuildRpa } from "./prompts/build-rpa.js";
34
- import { register as registerTfaGuide } from "./prompts/tfa-guide.js";
35
- import { register as registerWorkspaceSession } from "./prompts/workspace-session.js";
20
+ import { instructionsForProfile, profileUsesSessions, registerProfile, serverNameForProfile, } from "./server-profile.js";
21
+ import { autoCheckpoint } from "./tools/session.js";
36
22
  const DEFAULT_VM_SERVICE_URL = "https://lam-vm-service-ernfuwetfa-uc.a.run.app";
37
- function registerAllTools(deps) {
38
- registerCore(deps);
39
- registerWorkflowOps(deps);
40
- registerConfigStores(deps);
41
- registerSyncTools(deps);
42
- registerVm(deps);
43
- registerVmRpa(deps);
44
- registerTfa(deps);
45
- registerIssues(deps);
46
- registerAgents(deps);
47
- registerSkills(deps);
48
- registerSession(deps);
49
- registerWorkflowGuide(deps);
50
- registerDebugExecution(deps);
51
- registerBuildRpa(deps);
52
- registerTfaGuide(deps);
53
- registerWorkspaceSession(deps);
54
- }
55
- const DEFAULT_BASE_URL = "https://api.laminar.run";
56
- const MINICOR_INSTRUCTIONS = `You are connected to the Minicor MCP server for RPA workflow automation.
57
-
58
- CRITICAL: If the current directory contains a minicor.json file, you are in a workspace clone.
59
- You MUST call session_start(directory) as your FIRST action. It returns the workspace rules
60
- (AGENTS.md), prior session state for resuming, and all context you need. Follow the phase loop
61
- it describes.
62
-
63
- Before ending your session, call session_end() to persist your progress. Other agents (on other
64
- machines, scheduled, or human-triggered) depend on this to resume where you left off.
65
-
66
- If you are NOT in a workspace clone, use the tools freely — list_workspaces, clone_workspace, etc.`;
67
23
  async function refreshViaApi(apiBase, refreshToken) {
68
24
  try {
69
25
  const res = await fetch(`${apiBase}/auth/refresh`, {
@@ -101,36 +57,48 @@ function buildProvider(creds, apiBase, onUpdate) {
101
57
  * Returns a handle with a `close()` method for cleanup.
102
58
  */
103
59
  export async function createMinicorServer(transport, opts = {}) {
60
+ const profile = opts.profile ?? "full";
104
61
  const codeModeEnabled = opts.codeMode ?? shouldUseCodeMode();
105
- const server = new McpServer({ name: "minicor", version: "3.0.0" }, {
62
+ const profileInstructions = instructionsForProfile(profile);
63
+ const server = new McpServer({ name: serverNameForProfile(profile), version: "3.8.0" }, {
106
64
  instructions: codeModeEnabled
107
- ? buildCodeModeInstructions(MINICOR_INSTRUCTIONS)
108
- : MINICOR_INSTRUCTIONS,
65
+ ? buildCodeModeInstructions(profileInstructions, {
66
+ sessionLifecycle: profileUsesSessions(profile),
67
+ })
68
+ : profileInstructions,
109
69
  });
110
70
  const clients = new Map();
111
71
  const tokens = new Map();
112
72
  const baseUrls = new Map();
73
+ const apiBaseOverrides = new Map();
74
+ const tokenProviders = new Map();
75
+ function rebuildRegionClient(region, baseUrl) {
76
+ clients.set(region, new LaminarClient({ type: "bearer", token: tokens.get(region) ?? "" }, baseUrl, tokenProviders.get(region)));
77
+ baseUrls.set(region, baseUrl);
78
+ }
113
79
  if (opts.regionCredentials) {
114
80
  for (const [r, creds] of Object.entries(opts.regionCredentials)) {
115
81
  if (!creds)
116
82
  continue;
117
- const base = creds.baseUrl || regionToApiBase(r);
83
+ const base = creds.baseUrl || resolveApiBase(r);
118
84
  const provider = buildProvider(creds, base, (t) => tokens.set(r, t));
119
85
  clients.set(r, new LaminarClient({ type: "bearer", token: creds.access_token }, base, provider));
120
86
  tokens.set(r, creds.access_token);
87
+ tokenProviders.set(r, provider);
121
88
  baseUrls.set(r, base);
122
89
  }
123
90
  }
124
91
  if (clients.size === 0 && opts.credentials) {
125
- const baseUrl = opts.baseUrl || DEFAULT_BASE_URL;
126
- const region = baseUrl.includes("ca.api") ? "ca" : "us";
92
+ const baseUrl = opts.baseUrl || resolveApiBase("us");
93
+ const region = apiBaseToRegion(baseUrl);
127
94
  const provider = buildProvider(opts.credentials, baseUrl, (t) => tokens.set(region, t));
128
95
  clients.set(region, new LaminarClient({ type: "bearer", token: opts.credentials.access_token }, baseUrl, provider));
129
96
  tokens.set(region, opts.credentials.access_token);
97
+ tokenProviders.set(region, provider);
130
98
  baseUrls.set(region, baseUrl);
131
99
  }
132
100
  if (clients.size === 0) {
133
- const baseUrl = opts.baseUrl || DEFAULT_BASE_URL;
101
+ const baseUrl = opts.baseUrl || resolveApiBase("us");
134
102
  clients.set("us", new LaminarClient({ type: "bearer", token: "" }, baseUrl));
135
103
  tokens.set("us", "");
136
104
  baseUrls.set("us", baseUrl);
@@ -161,24 +129,51 @@ export async function createMinicorServer(transport, opts = {}) {
161
129
  },
162
130
  getApiBase: (region) => {
163
131
  const r = region ?? getDefaultRegion();
164
- return baseUrls.get(r) ?? regionToApiBase(r);
132
+ return baseUrls.get(r) ?? resolveApiBase(r);
133
+ },
134
+ getStoredApiBase: (region) => {
135
+ const r = region ?? getDefaultRegion();
136
+ return apiBaseOverrides.get(r);
137
+ },
138
+ setApiBase: async (region, baseUrl) => {
139
+ if (!clients.has(region)) {
140
+ throw new Error(`No client configured for ${region.toUpperCase()} region.`);
141
+ }
142
+ const storedApiBase = validateApiBaseUrl(baseUrl);
143
+ apiBaseOverrides.set(region, storedApiBase);
144
+ const effectiveApiBase = resolveApiBase(region, storedApiBase);
145
+ rebuildRegionClient(region, effectiveApiBase);
146
+ return { storedApiBase, effectiveApiBase };
147
+ },
148
+ unsetApiBase: async (region) => {
149
+ if (!clients.has(region)) {
150
+ throw new Error(`No client configured for ${region.toUpperCase()} region.`);
151
+ }
152
+ apiBaseOverrides.delete(region);
153
+ const effectiveApiBase = resolveApiBase(region);
154
+ rebuildRegionClient(region, effectiveApiBase);
155
+ return { storedApiBase: undefined, effectiveApiBase };
165
156
  },
166
157
  getVmServiceBase: () => vmServiceBase,
167
158
  getAuthToken: (region) => tokens.get(region ?? getDefaultRegion()) ?? "",
168
159
  availableRegions: () => [...clients.keys()],
169
160
  };
170
- registerAllTools(deps);
161
+ registerProfile(deps, profile);
171
162
  if (codeModeRegistry) {
172
163
  codeModeRegistry.registerCodeModeTool();
173
164
  }
174
165
  await server.connect(transport);
175
166
  transport.onclose = async () => {
176
- await autoCheckpoint(deps);
167
+ if (profileUsesSessions(profile)) {
168
+ await autoCheckpoint(deps);
169
+ }
177
170
  };
178
171
  return {
179
172
  server,
180
173
  close: async () => {
181
- await autoCheckpoint(deps);
174
+ if (profileUsesSessions(profile)) {
175
+ await autoCheckpoint(deps);
176
+ }
182
177
  try {
183
178
  await server.close();
184
179
  }
package/dist/lib.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"file":"lib.js","sourceRoot":"","sources":["../src/lib.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"lib.js","sourceRoot":"","sources":["../src/lib.ts"],"names":[],"mappings":"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"}
package/dist/paths.d.ts CHANGED
@@ -13,5 +13,9 @@ export declare function getConfigPath(): string;
13
13
  export declare function getWriteConfigPath(): string;
14
14
  export type Region = "us" | "ca";
15
15
  export declare function regionToApiBase(region: Region): string;
16
+ export declare function normalizeBaseUrl(baseUrl: string): string;
17
+ export declare function validateApiBaseUrl(baseUrl: string): string;
18
+ export declare function resolveDefaultApiBase(region: Region): string;
19
+ export declare function resolveApiBase(region: Region, storedApiBase?: string | null): string;
16
20
  export declare function apiBaseToRegion(apiBase: string): Region;
17
21
  //# sourceMappingURL=paths.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"paths.d.ts","sourceRoot":"","sources":["../src/paths.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;AAMH,QAAA,MAAM,WAAW,QAAsC,CAAC;AAGxD,OAAO,EAAE,WAAW,EAAE,CAAC;AAEvB,wBAAgB,YAAY,IAAI,MAAM,CAMrC;AAED,wBAAgB,iBAAiB,IAAI,MAAM,CAE1C;AAED,wBAAgB,aAAa,IAAI,MAAM,CAMtC;AAED,wBAAgB,kBAAkB,IAAI,MAAM,CAE3C;AAED,MAAM,MAAM,MAAM,GAAG,IAAI,GAAG,IAAI,CAAC;AAEjC,wBAAgB,eAAe,CAAC,MAAM,EAAE,MAAM,GAAG,MAAM,CAItD;AAED,wBAAgB,eAAe,CAAC,OAAO,EAAE,MAAM,GAAG,MAAM,CAEvD"}
1
+ {"version":3,"file":"paths.d.ts","sourceRoot":"","sources":["../src/paths.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;AAMH,QAAA,MAAM,WAAW,QAAsC,CAAC;AAGxD,OAAO,EAAE,WAAW,EAAE,CAAC;AAEvB,wBAAgB,YAAY,IAAI,MAAM,CAMrC;AAED,wBAAgB,iBAAiB,IAAI,MAAM,CAE1C;AAED,wBAAgB,aAAa,IAAI,MAAM,CAMtC;AAED,wBAAgB,kBAAkB,IAAI,MAAM,CAE3C;AAED,MAAM,MAAM,MAAM,GAAG,IAAI,GAAG,IAAI,CAAC;AAEjC,wBAAgB,eAAe,CAAC,MAAM,EAAE,MAAM,GAAG,MAAM,CAItD;AAED,wBAAgB,gBAAgB,CAAC,OAAO,EAAE,MAAM,GAAG,MAAM,CAExD;AAED,wBAAgB,kBAAkB,CAAC,OAAO,EAAE,MAAM,GAAG,MAAM,CAe1D;AAWD,wBAAgB,qBAAqB,CAAC,MAAM,EAAE,MAAM,GAAG,MAAM,CAE5D;AAED,wBAAgB,cAAc,CAC5B,MAAM,EAAE,MAAM,EACd,aAAa,CAAC,EAAE,MAAM,GAAG,IAAI,GAC5B,MAAM,CAMR;AAED,wBAAgB,eAAe,CAAC,OAAO,EAAE,MAAM,GAAG,MAAM,CAEvD"}
package/dist/paths.js CHANGED
@@ -40,6 +40,39 @@ export function regionToApiBase(region) {
40
40
  ? "https://ca.api.laminar.run"
41
41
  : "https://api.laminar.run";
42
42
  }
43
+ export function normalizeBaseUrl(baseUrl) {
44
+ return baseUrl.trim().replace(/\/+$/, "");
45
+ }
46
+ export function validateApiBaseUrl(baseUrl) {
47
+ const normalized = normalizeBaseUrl(baseUrl);
48
+ let parsed;
49
+ try {
50
+ parsed = new URL(normalized);
51
+ }
52
+ catch {
53
+ throw new Error("Backend API URL must be a valid URL.");
54
+ }
55
+ if (parsed.protocol !== "http:" && parsed.protocol !== "https:") {
56
+ throw new Error("Backend API URL must start with http:// or https://.");
57
+ }
58
+ return normalized;
59
+ }
60
+ function envApiBase(region) {
61
+ const regional = region === "ca"
62
+ ? process.env.MINICOR_API_BASE_URL_CA
63
+ : process.env.MINICOR_API_BASE_URL_US;
64
+ const base = regional ?? process.env.MINICOR_API_BASE_URL;
65
+ return base && base.trim() !== "" ? normalizeBaseUrl(base) : undefined;
66
+ }
67
+ export function resolveDefaultApiBase(region) {
68
+ return envApiBase(region) ?? regionToApiBase(region);
69
+ }
70
+ export function resolveApiBase(region, storedApiBase) {
71
+ const stored = storedApiBase && storedApiBase.trim() !== ""
72
+ ? normalizeBaseUrl(storedApiBase)
73
+ : undefined;
74
+ return envApiBase(region) ?? stored ?? regionToApiBase(region);
75
+ }
43
76
  export function apiBaseToRegion(apiBase) {
44
77
  return apiBase.includes("ca.api") ? "ca" : "us";
45
78
  }
package/dist/paths.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"file":"paths.js","sourceRoot":"","sources":["../src/paths.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;AAEH,OAAO,EAAE,MAAM,SAAS,CAAC;AACzB,OAAO,EAAE,MAAM,SAAS,CAAC;AACzB,OAAO,IAAI,MAAM,WAAW,CAAC;AAE7B,MAAM,WAAW,GAAG,IAAI,CAAC,IAAI,CAAC,EAAE,CAAC,OAAO,EAAE,EAAE,UAAU,CAAC,CAAC;AACxD,MAAM,UAAU,GAAG,IAAI,CAAC,IAAI,CAAC,EAAE,CAAC,OAAO,EAAE,EAAE,UAAU,CAAC,CAAC;AAEvD,OAAO,EAAE,WAAW,EAAE,CAAC;AAEvB,MAAM,UAAU,YAAY;IAC1B,MAAM,WAAW,GAAG,IAAI,CAAC,IAAI,CAAC,WAAW,EAAE,aAAa,CAAC,CAAC;IAC1D,IAAI,EAAE,CAAC,UAAU,CAAC,WAAW,CAAC;QAAE,OAAO,WAAW,CAAC;IACnD,MAAM,UAAU,GAAG,IAAI,CAAC,IAAI,CAAC,UAAU,EAAE,aAAa,CAAC,CAAC;IACxD,IAAI,EAAE,CAAC,UAAU,CAAC,UAAU,CAAC;QAAE,OAAO,UAAU,CAAC;IACjD,OAAO,WAAW,CAAC;AACrB,CAAC;AAED,MAAM,UAAU,iBAAiB;IAC/B,OAAO,IAAI,CAAC,IAAI,CAAC,WAAW,EAAE,aAAa,CAAC,CAAC;AAC/C,CAAC;AAED,MAAM,UAAU,aAAa;IAC3B,MAAM,WAAW,GAAG,IAAI,CAAC,IAAI,CAAC,WAAW,EAAE,aAAa,CAAC,CAAC;IAC1D,IAAI,EAAE,CAAC,UAAU,CAAC,WAAW,CAAC;QAAE,OAAO,WAAW,CAAC;IACnD,MAAM,UAAU,GAAG,IAAI,CAAC,IAAI,CAAC,UAAU,EAAE,aAAa,CAAC,CAAC;IACxD,IAAI,EAAE,CAAC,UAAU,CAAC,UAAU,CAAC;QAAE,OAAO,UAAU,CAAC;IACjD,OAAO,WAAW,CAAC;AACrB,CAAC;AAED,MAAM,UAAU,kBAAkB;IAChC,OAAO,IAAI,CAAC,IAAI,CAAC,WAAW,EAAE,aAAa,CAAC,CAAC;AAC/C,CAAC;AAID,MAAM,UAAU,eAAe,CAAC,MAAc;IAC5C,OAAO,MAAM,KAAK,IAAI;QACpB,CAAC,CAAC,4BAA4B;QAC9B,CAAC,CAAC,yBAAyB,CAAC;AAChC,CAAC;AAED,MAAM,UAAU,eAAe,CAAC,OAAe;IAC7C,OAAO,OAAO,CAAC,QAAQ,CAAC,QAAQ,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,IAAI,CAAC;AAClD,CAAC"}
1
+ {"version":3,"file":"paths.js","sourceRoot":"","sources":["../src/paths.ts"],"names":[],"mappings":"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"}
@@ -1 +1 @@
1
- {"version":3,"file":"debug-execution.d.ts","sourceRoot":"","sources":["../../src/prompts/debug-execution.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,QAAQ,EAAE,MAAM,aAAa,CAAC;AAI5C,wBAAgB,QAAQ,CAAC,EAAE,MAAM,EAAE,MAAM,EAAE,EAAE,QAAQ,QA2EpD"}
1
+ {"version":3,"file":"debug-execution.d.ts","sourceRoot":"","sources":["../../src/prompts/debug-execution.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,QAAQ,EAAE,MAAM,aAAa,CAAC;AAI5C,wBAAgB,QAAQ,CAAC,EAAE,MAAM,EAAE,MAAM,EAAE,EAAE,QAAQ,QA4EpD"}
@@ -52,8 +52,9 @@ Analyze the execution, identify failures, explain root causes, and suggest speci
52
52
  - Look at preceding successful steps for context
53
53
 
54
54
  ### 2. Check for video recordings
55
- - RPA step executions include \`recording.blobName\` in their response data (e.g. \`rpa_1_step-name.mp4\`)
56
- - These MP4 recordings can be viewed in the Minicor platform for visual debugging
55
+ - To visually inspect what happened, use \`get_recording_frames\` it samples full-resolution still frames (as images) from the execution recording, or from a single step when you pass its flow run ID. Great for confirming the on-screen state at the point of failure
56
+ - To hand a full video to a human (or embed it), use \`get_execution_recording\` for a 24h signed URL to the full recording, or \`get_flow_run_recording\` for a single step's recording
57
+ - RPA step executions also include \`recording.blobName\` in their response data (e.g. \`rpa_1_step-name.mp4\`)
57
58
 
58
59
  ### 3. If a VM is connected — reproduce on the live VM
59
60
  - Use \`replay_execution_step\` with the failed flow run ID to re-run the exact script with before/after screenshots
@@ -1 +1 @@
1
- {"version":3,"file":"debug-execution.js","sourceRoot":"","sources":["../../src/prompts/debug-execution.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;AAGxB,OAAO,EAAE,IAAI,EAAE,MAAM,eAAe,CAAC;AAErC,MAAM,UAAU,QAAQ,CAAC,EAAE,MAAM,EAAE,MAAM,EAAY;IACnD,MAAM,CAAC,MAAM,CACX,0BAA0B,EAC1B,uDAAuD,EACvD;QACE,UAAU,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,QAAQ,CAAC,sBAAsB,CAAC;QACvD,WAAW,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,QAAQ,CAAC,qBAAqB,CAAC;QACvD,MAAM,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,QAAQ,EAAE,CAAC,QAAQ,CAAC,mBAAmB,CAAC;KAC5D,EACD,KAAK,EAAE,EAAE,UAAU,EAAE,WAAW,EAAE,MAAM,EAAE,EAAE,EAAE;QAC5C,MAAM,GAAG,GAAG,QAAQ,CAAC,UAAU,CAAC,CAAC;QACjC,MAAM,GAAG,GAAG,QAAQ,CAAC,WAAW,CAAC,CAAC;QAClC,MAAM,CAAC,GAAG,MAA4B,CAAC;QACvC,IAAI,aAAkB,CAAC;QACvB,IAAI,SAAc,CAAC;QAEnB,IAAI,CAAC;YACH,aAAa,GAAG,MAAM,MAAM,CAAC,CAAC,CAAC,CAAC,YAAY,CAAC,GAAG,EAAE,GAAG,CAAC,CAAC;YACvD,SAAS,GAAG,MAAM,MAAM,CAAC,CAAC,CAAC,CAAC,gBAAgB,CAAC,GAAG,CAAC,CAAC;QACpD,CAAC;QAAC,OAAO,CAAM,EAAE,CAAC;YAChB,OAAO;gBACL,QAAQ,EAAE;oBACR;wBACE,IAAI,EAAE,MAAe;wBACrB,OAAO,EAAE;4BACP,IAAI,EAAE,MAAe;4BACrB,IAAI,EAAE,mCAAmC,CAAC,CAAC,OAAO,EAAE;yBACrD;qBACF;iBACF;aACF,CAAC;QACJ,CAAC;QAED,OAAO;YACL,QAAQ,EAAE;gBACR;oBACE,IAAI,EAAE,MAAe;oBACrB,OAAO,EAAE;wBACP,IAAI,EAAE,MAAe;wBACrB,IAAI,EAAE;;;EAGlB,IAAI,CAAC,SAAS,CAAC;;;EAGf,IAAI,CAAC,aAAa,CAAC;;;;;;;;;;;;;;;;;;;;;;;wEAuBmD;qBAC3D;iBACF;aACF;SACF,CAAC;IACJ,CAAC,CACF,CAAC;AACJ,CAAC"}
1
+ {"version":3,"file":"debug-execution.js","sourceRoot":"","sources":["../../src/prompts/debug-execution.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;AAGxB,OAAO,EAAE,IAAI,EAAE,MAAM,eAAe,CAAC;AAErC,MAAM,UAAU,QAAQ,CAAC,EAAE,MAAM,EAAE,MAAM,EAAY;IACnD,MAAM,CAAC,MAAM,CACX,0BAA0B,EAC1B,uDAAuD,EACvD;QACE,UAAU,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,QAAQ,CAAC,sBAAsB,CAAC;QACvD,WAAW,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,QAAQ,CAAC,qBAAqB,CAAC;QACvD,MAAM,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,QAAQ,EAAE,CAAC,QAAQ,CAAC,mBAAmB,CAAC;KAC5D,EACD,KAAK,EAAE,EAAE,UAAU,EAAE,WAAW,EAAE,MAAM,EAAE,EAAE,EAAE;QAC5C,MAAM,GAAG,GAAG,QAAQ,CAAC,UAAU,CAAC,CAAC;QACjC,MAAM,GAAG,GAAG,QAAQ,CAAC,WAAW,CAAC,CAAC;QAClC,MAAM,CAAC,GAAG,MAA4B,CAAC;QACvC,IAAI,aAAkB,CAAC;QACvB,IAAI,SAAc,CAAC;QAEnB,IAAI,CAAC;YACH,aAAa,GAAG,MAAM,MAAM,CAAC,CAAC,CAAC,CAAC,YAAY,CAAC,GAAG,EAAE,GAAG,CAAC,CAAC;YACvD,SAAS,GAAG,MAAM,MAAM,CAAC,CAAC,CAAC,CAAC,gBAAgB,CAAC,GAAG,CAAC,CAAC;QACpD,CAAC;QAAC,OAAO,CAAM,EAAE,CAAC;YAChB,OAAO;gBACL,QAAQ,EAAE;oBACR;wBACE,IAAI,EAAE,MAAe;wBACrB,OAAO,EAAE;4BACP,IAAI,EAAE,MAAe;4BACrB,IAAI,EAAE,mCAAmC,CAAC,CAAC,OAAO,EAAE;yBACrD;qBACF;iBACF;aACF,CAAC;QACJ,CAAC;QAED,OAAO;YACL,QAAQ,EAAE;gBACR;oBACE,IAAI,EAAE,MAAe;oBACrB,OAAO,EAAE;wBACP,IAAI,EAAE,MAAe;wBACrB,IAAI,EAAE;;;EAGlB,IAAI,CAAC,SAAS,CAAC;;;EAGf,IAAI,CAAC,aAAa,CAAC;;;;;;;;;;;;;;;;;;;;;;;;wEAwBmD;qBAC3D;iBACF;aACF;SACF,CAAC;IACJ,CAAC,CACF,CAAC;AACJ,CAAC"}
@@ -0,0 +1,58 @@
1
+ /**
2
+ * Extracts sampled still frames from a recording (MP4) so that a vision-capable
3
+ * model can visually verify or debug an execution.
4
+ *
5
+ * The recording endpoints return a signed URL to an MP4. A model cannot "watch"
6
+ * a video URL, so this module downloads the video and uses ffmpeg to sample a
7
+ * handful of frames, returned as base64 JPEGs. ffmpeg (and ideally ffprobe) must
8
+ * be available on the MCP host; when they are missing we throw a clear error so
9
+ * the caller can fall back to handing the raw URL to a human.
10
+ */
11
+ export interface ExtractedFrame {
12
+ /** Human-readable label, e.g. "t=12.3s" or "frame 2". */
13
+ label: string;
14
+ /** Frame position in seconds when known, otherwise null. */
15
+ timestampSeconds: number | null;
16
+ /** Base64-encoded JPEG (no data: prefix). */
17
+ base64: string;
18
+ }
19
+ export interface ExtractFramesOptions {
20
+ /** Number of evenly-spaced frames to sample. Default 4. */
21
+ count?: number;
22
+ /**
23
+ * Optional max output width in px. When omitted (the default) frames keep the
24
+ * recording's ORIGINAL resolution — important for reading fine on-screen detail.
25
+ * Only set this if you explicitly want to trade resolution for smaller frames.
26
+ */
27
+ maxWidth?: number;
28
+ /** Max bytes to download before aborting. Default 200 MB. */
29
+ maxBytes?: number;
30
+ /** Overall download timeout in ms. Default 60s. */
31
+ downloadTimeoutMs?: number;
32
+ /** Per-ffmpeg/ffprobe command timeout in ms. Default 30s. */
33
+ commandTimeoutMs?: number;
34
+ ffmpegPath?: string;
35
+ ffprobePath?: string;
36
+ }
37
+ /**
38
+ * Computes evenly-spaced sample timestamps centered within the duration, so we
39
+ * avoid black/blank frames at the very start and end.
40
+ */
41
+ export declare function computeSampleTimestamps(durationSeconds: number, count: number): number[];
42
+ /**
43
+ * Builds an ffmpeg scale filter that caps width while preserving aspect ratio.
44
+ * Returns null when no cap is requested, so frames keep their original resolution.
45
+ */
46
+ export declare function buildScaleFilter(maxWidth?: number): string | null;
47
+ export interface CommandResult {
48
+ code: number | null;
49
+ stdout: string;
50
+ stderr: string;
51
+ }
52
+ export declare function runCommand(command: string, args: string[], timeoutMs: number): Promise<CommandResult>;
53
+ /**
54
+ * Downloads the recording at `url` and returns sampled JPEG frames.
55
+ * Throws with a clear message when ffmpeg is unavailable.
56
+ */
57
+ export declare function extractFramesFromUrl(url: string, options?: ExtractFramesOptions): Promise<ExtractedFrame[]>;
58
+ //# sourceMappingURL=recording-frames.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"recording-frames.d.ts","sourceRoot":"","sources":["../src/recording-frames.ts"],"names":[],"mappings":"AAAA;;;;;;;;;GASG;AAOH,MAAM,WAAW,cAAc;IAC7B,yDAAyD;IACzD,KAAK,EAAE,MAAM,CAAC;IACd,4DAA4D;IAC5D,gBAAgB,EAAE,MAAM,GAAG,IAAI,CAAC;IAChC,6CAA6C;IAC7C,MAAM,EAAE,MAAM,CAAC;CAChB;AAED,MAAM,WAAW,oBAAoB;IACnC,2DAA2D;IAC3D,KAAK,CAAC,EAAE,MAAM,CAAC;IACf;;;;OAIG;IACH,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,6DAA6D;IAC7D,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,mDAAmD;IACnD,iBAAiB,CAAC,EAAE,MAAM,CAAC;IAC3B,6DAA6D;IAC7D,gBAAgB,CAAC,EAAE,MAAM,CAAC;IAC1B,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,WAAW,CAAC,EAAE,MAAM,CAAC;CACtB;AAWD;;;GAGG;AACH,wBAAgB,uBAAuB,CAAC,eAAe,EAAE,MAAM,EAAE,KAAK,EAAE,MAAM,GAAG,MAAM,EAAE,CASxF;AAED;;;GAGG;AACH,wBAAgB,gBAAgB,CAAC,QAAQ,CAAC,EAAE,MAAM,GAAG,MAAM,GAAG,IAAI,CAKjE;AAID,MAAM,WAAW,aAAa;IAC5B,IAAI,EAAE,MAAM,GAAG,IAAI,CAAC;IACpB,MAAM,EAAE,MAAM,CAAC;IACf,MAAM,EAAE,MAAM,CAAC;CAChB;AAED,wBAAgB,UAAU,CACxB,OAAO,EAAE,MAAM,EACf,IAAI,EAAE,MAAM,EAAE,EACd,SAAS,EAAE,MAAM,GAChB,OAAO,CAAC,aAAa,CAAC,CA4CxB;AAqHD;;;GAGG;AACH,wBAAsB,oBAAoB,CACxC,GAAG,EAAE,MAAM,EACX,OAAO,GAAE,oBAAyB,GACjC,OAAO,CAAC,cAAc,EAAE,CAAC,CAuF3B"}
@@ -0,0 +1,244 @@
1
+ /**
2
+ * Extracts sampled still frames from a recording (MP4) so that a vision-capable
3
+ * model can visually verify or debug an execution.
4
+ *
5
+ * The recording endpoints return a signed URL to an MP4. A model cannot "watch"
6
+ * a video URL, so this module downloads the video and uses ffmpeg to sample a
7
+ * handful of frames, returned as base64 JPEGs. ffmpeg (and ideally ffprobe) must
8
+ * be available on the MCP host; when they are missing we throw a clear error so
9
+ * the caller can fall back to handing the raw URL to a human.
10
+ */
11
+ import { spawn } from "node:child_process";
12
+ import { mkdtemp, open, readFile, readdir, rm } from "node:fs/promises";
13
+ import { tmpdir } from "node:os";
14
+ import path from "node:path";
15
+ const DEFAULTS = {
16
+ count: 4,
17
+ maxBytes: 200 * 1024 * 1024,
18
+ downloadTimeoutMs: 60_000,
19
+ commandTimeoutMs: 30_000,
20
+ ffmpegPath: "ffmpeg",
21
+ ffprobePath: "ffprobe",
22
+ };
23
+ /**
24
+ * Computes evenly-spaced sample timestamps centered within the duration, so we
25
+ * avoid black/blank frames at the very start and end.
26
+ */
27
+ export function computeSampleTimestamps(durationSeconds, count) {
28
+ if (!Number.isFinite(durationSeconds) || durationSeconds <= 0 || count <= 0) {
29
+ return [];
30
+ }
31
+ const n = Math.min(count, Math.max(1, Math.floor(count)));
32
+ return Array.from({ length: n }, (_, i) => {
33
+ const fraction = (i + 0.5) / n;
34
+ return Number((durationSeconds * fraction).toFixed(3));
35
+ });
36
+ }
37
+ /**
38
+ * Builds an ffmpeg scale filter that caps width while preserving aspect ratio.
39
+ * Returns null when no cap is requested, so frames keep their original resolution.
40
+ */
41
+ export function buildScaleFilter(maxWidth) {
42
+ if (maxWidth == null || !Number.isFinite(maxWidth) || maxWidth <= 0) {
43
+ return null;
44
+ }
45
+ return `scale='min(${maxWidth},iw)':-2`;
46
+ }
47
+ class CommandNotFoundError extends Error {
48
+ }
49
+ export function runCommand(command, args, timeoutMs) {
50
+ return new Promise((resolve, reject) => {
51
+ const child = spawn(command, args, { stdio: ["ignore", "pipe", "pipe"] });
52
+ let stdout = "";
53
+ let stderr = "";
54
+ let settled = false;
55
+ const timer = setTimeout(() => {
56
+ if (settled)
57
+ return;
58
+ settled = true;
59
+ child.kill("SIGKILL");
60
+ reject(new Error(`${command} timed out after ${timeoutMs}ms`));
61
+ }, timeoutMs);
62
+ child.stdout?.on("data", (d) => (stdout += d.toString()));
63
+ child.stderr?.on("data", (d) => (stderr += d.toString()));
64
+ child.on("error", (err) => {
65
+ if (settled)
66
+ return;
67
+ settled = true;
68
+ clearTimeout(timer);
69
+ if (err.code === "ENOENT") {
70
+ reject(new CommandNotFoundError(`'${command}' not found on the MCP host`));
71
+ }
72
+ else {
73
+ reject(err);
74
+ }
75
+ });
76
+ child.on("close", (code) => {
77
+ if (settled)
78
+ return;
79
+ settled = true;
80
+ clearTimeout(timer);
81
+ if (code !== 0) {
82
+ const detail = stderr.trim().split("\n").slice(-3).join("; ");
83
+ reject(new Error(`${command} exited with code ${code}${detail ? `: ${detail}` : ""}`));
84
+ return;
85
+ }
86
+ resolve({ code, stdout, stderr });
87
+ });
88
+ });
89
+ }
90
+ async function downloadToFile(url, dest, maxBytes, timeoutMs) {
91
+ const controller = new AbortController();
92
+ const timer = setTimeout(() => controller.abort(), timeoutMs);
93
+ try {
94
+ const res = await fetch(url, { signal: controller.signal });
95
+ if (!res.ok) {
96
+ throw new Error(`failed to download recording (${res.status})`);
97
+ }
98
+ const contentLength = Number(res.headers.get("content-length") ?? "0");
99
+ if (contentLength && contentLength > maxBytes) {
100
+ throw new Error(`recording too large (${contentLength} bytes > ${maxBytes} limit)`);
101
+ }
102
+ if (!res.body) {
103
+ throw new Error("recording download returned an empty body");
104
+ }
105
+ const handle = await open(dest, "w");
106
+ try {
107
+ let total = 0;
108
+ for await (const chunk of res.body) {
109
+ total += chunk.length;
110
+ if (total > maxBytes) {
111
+ throw new Error(`recording exceeded max size (${maxBytes} bytes)`);
112
+ }
113
+ await handle.write(chunk);
114
+ }
115
+ }
116
+ finally {
117
+ await handle.close();
118
+ }
119
+ }
120
+ finally {
121
+ clearTimeout(timer);
122
+ }
123
+ }
124
+ async function probeDurationSeconds(file, ffprobePath, timeoutMs) {
125
+ try {
126
+ const { stdout } = await runCommand(ffprobePath, ["-v", "error", "-show_entries", "format=duration", "-of", "default=nw=1:nk=1", file], timeoutMs);
127
+ const duration = parseFloat(stdout.trim());
128
+ return Number.isFinite(duration) && duration > 0 ? duration : null;
129
+ }
130
+ catch (e) {
131
+ if (e instanceof CommandNotFoundError) {
132
+ return null; // ffprobe missing; caller falls back to thumbnail sampling
133
+ }
134
+ return null;
135
+ }
136
+ }
137
+ async function extractFrameAt(file, timestampSeconds, outPath, scaleFilter, ffmpegPath, timeoutMs) {
138
+ const args = ["-ss", String(timestampSeconds), "-i", file, "-frames:v", "1"];
139
+ if (scaleFilter) {
140
+ args.push("-vf", scaleFilter);
141
+ }
142
+ // -q:v 2 = highest-quality JPEG, so the original resolution is preserved with minimal artifacts.
143
+ args.push("-q:v", "2", "-y", outPath);
144
+ await runCommand(ffmpegPath, args, timeoutMs);
145
+ }
146
+ async function extractThumbnails(file, count, outPattern, scaleFilter, ffmpegPath, timeoutMs) {
147
+ const vf = scaleFilter ? `thumbnail,${scaleFilter}` : "thumbnail";
148
+ await runCommand(ffmpegPath, [
149
+ "-i",
150
+ file,
151
+ "-vf",
152
+ vf,
153
+ "-frames:v",
154
+ String(count),
155
+ "-vsync",
156
+ "vfr",
157
+ "-q:v",
158
+ "2",
159
+ "-y",
160
+ outPattern,
161
+ ], timeoutMs);
162
+ }
163
+ async function readJpegBase64(file) {
164
+ try {
165
+ const buf = await readFile(file);
166
+ return buf.length > 0 ? buf.toString("base64") : null;
167
+ }
168
+ catch {
169
+ return null;
170
+ }
171
+ }
172
+ /**
173
+ * Downloads the recording at `url` and returns sampled JPEG frames.
174
+ * Throws with a clear message when ffmpeg is unavailable.
175
+ */
176
+ export async function extractFramesFromUrl(url, options = {}) {
177
+ const opts = { ...DEFAULTS, ...options };
178
+ const scaleFilter = buildScaleFilter(opts.maxWidth);
179
+ const workDir = await mkdtemp(path.join(tmpdir(), "laminar-frames-"));
180
+ const videoPath = path.join(workDir, "recording.mp4");
181
+ try {
182
+ await downloadToFile(url, videoPath, opts.maxBytes, opts.downloadTimeoutMs);
183
+ const duration = await probeDurationSeconds(videoPath, opts.ffprobePath, opts.commandTimeoutMs);
184
+ const frames = [];
185
+ try {
186
+ if (duration != null) {
187
+ const timestamps = computeSampleTimestamps(duration, opts.count);
188
+ let lastError = null;
189
+ for (let i = 0; i < timestamps.length; i++) {
190
+ const outPath = path.join(workDir, `frame-${i}.jpg`);
191
+ try {
192
+ await extractFrameAt(videoPath, timestamps[i], outPath, scaleFilter, opts.ffmpegPath, opts.commandTimeoutMs);
193
+ }
194
+ catch (e) {
195
+ // ffmpeg missing is fatal; a single bad frame (e.g. a seek that lands
196
+ // past the end) should not abort the whole sample — record it and move on.
197
+ if (e instanceof CommandNotFoundError)
198
+ throw e;
199
+ lastError = e;
200
+ continue;
201
+ }
202
+ const base64 = await readJpegBase64(outPath);
203
+ if (base64) {
204
+ frames.push({
205
+ label: `t=${timestamps[i].toFixed(1)}s`,
206
+ timestampSeconds: timestamps[i],
207
+ base64,
208
+ });
209
+ }
210
+ }
211
+ // Surface a genuine failure instead of pretending nothing was recorded.
212
+ if (frames.length === 0 && lastError) {
213
+ throw lastError;
214
+ }
215
+ }
216
+ else {
217
+ // No duration (ffprobe missing) — fall back to thumbnail sampling.
218
+ const outPattern = path.join(workDir, "thumb-%03d.jpg");
219
+ await extractThumbnails(videoPath, opts.count, outPattern, scaleFilter, opts.ffmpegPath, opts.commandTimeoutMs);
220
+ const files = (await readdir(workDir))
221
+ .filter((f) => f.startsWith("thumb-") && f.endsWith(".jpg"))
222
+ .sort();
223
+ for (let i = 0; i < files.length; i++) {
224
+ const base64 = await readJpegBase64(path.join(workDir, files[i]));
225
+ if (base64) {
226
+ frames.push({ label: `frame ${i + 1}`, timestampSeconds: null, base64 });
227
+ }
228
+ }
229
+ }
230
+ }
231
+ catch (e) {
232
+ if (e instanceof CommandNotFoundError) {
233
+ throw new Error("ffmpeg is not installed on the MCP host, so frames cannot be extracted. " +
234
+ "Install ffmpeg, or use get_execution_recording / get_flow_run_recording to get the raw video URL.");
235
+ }
236
+ throw e;
237
+ }
238
+ return frames;
239
+ }
240
+ finally {
241
+ await rm(workDir, { recursive: true, force: true }).catch(() => { });
242
+ }
243
+ }
244
+ //# sourceMappingURL=recording-frames.js.map