@powerhousedao/reactor-workflow 6.2.3-dev.13 → 6.2.3-dev.14

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.
@@ -55,8 +55,6 @@ interface FetchPieceBundleOptions {
55
55
  interface FetchedBundle {
56
56
  dir: string;
57
57
  source: "cdn" | "npm" | "cache";
58
- dependencies: Record<string, string>;
59
- installed: boolean;
60
58
  }
61
59
  declare function fetchPieceBundle(options: FetchPieceBundleOptions): Promise<FetchedBundle>;
62
60
  declare function ensurePieceBundle(options: FetchPieceBundleOptions): Promise<FetchedBundle>;
@@ -585,16 +583,14 @@ declare function runWorkflow(options: RunWorkflowOptions): Promise<WorkflowRunRe
585
583
  //#region src/reactor/piece-registry.d.ts
586
584
  declare class PieceRegistry {
587
585
  private byName;
588
- private loading;
589
- load(projectRoot?: string): Promise<void>;
590
- private discover;
591
- ready(projectRoot?: string): Promise<void>;
586
+ setPieces(pieces: readonly LocalPiece[]): void;
592
587
  lookup: (name: string) => LocalPiece | undefined;
593
588
  entries(): LocalPiece[];
594
589
  versions(): Record<string, string>;
590
+ /** Test seam: a suite that filled the registry starts the next from nothing. */
595
591
  reset(): void;
596
592
  }
597
593
  declare const packagePieces: PieceRegistry;
598
594
  //#endregion
599
595
  export { fetchPieceBundle as A, EgressPolicy as C, buildDescriptor as D, PieceDescriptor as E, loadPieceFromDir as O, localFirstResolver as S, extractDedupeKey as T, PieceWorker as _, AttachmentPort as a, PackagePiece as b, ConnectionRequest as c, SecretStore as d, BlockExecution as f, IPieceWorker as g, PieceWorkerPool as h, ActivepiecesBlockExecutor as i, ensurePieceBundle as k, StaticConnectionResolver as l, WorkflowRunResult as m, packagePieces as n, CompositeBlockExecutor as o, StepExecutionRecord as p, runWorkflow as r, ReactorPort as s, PieceRegistry as t, InMemorySecretProvider as u, PieceWorkerResult as v, RecordedSchedule as w, PieceResolver as x, LocalPiece as y };
600
- //# sourceMappingURL=piece-registry-CE0UFmDA.d.ts.map
596
+ //# sourceMappingURL=piece-registry-DxYByELl.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"piece-registry-DxYByELl.d.ts","names":[],"sources":["../src/pieces/activepieces/types.ts","../src/pieces/activepieces/fetch.ts","../src/pieces/activepieces/loader.ts","../src/pieces/activepieces/descriptor.ts","../src/pieces/activepieces/context/store-scope.ts","../src/pieces/activepieces/context/files.ts","../src/pieces/activepieces/context/action.ts","../src/pieces/activepieces/context/trigger.ts","../src/pieces/activepieces/worker/protocol.ts","../src/pieces/activepieces/resolver.ts","../src/pieces/activepieces/worker/transport.ts","../src/pieces/activepieces/worker/host.ts","../src/pieces/activepieces/worker/pool.ts","../src/pieces/engine/types.ts","../src/pieces/engine/secrets.ts","../src/pieces/engine/connections.ts","../src/pieces/engine/blocks.ts","../src/pieces/engine/coordinator.ts","../src/reactor/piece-registry.ts"],"mappings":"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"}
@@ -1,14 +1,13 @@
1
1
  import { A as REACTOR_MODEL, C as jsonSafe, D as REACTOR_EXECUTE, E as REACTOR_CREATE, M as STORE_DELETE, N as STORE_GET, O as REACTOR_FIND, P as STORE_PUT, T as OUTPUT_UPDATE, a as redactMessage, c as DEFAULT_EGRESS_POLICY, g as rewriteFileRefs, i as redactError, j as REACTOR_MODELS, k as REACTOR_GET, n as containsRedactedMarker, o as rememberSecrets, r as redact, s as secretsFor, t as collectSecretValues, w as LOG_WRITE } from "./redact-C7LWgAyD.js";
2
- import { createRequire } from "node:module";
3
2
  import { AppConnectionType } from "@powerhousedao/pieces-framework";
4
- import { execFile, fork } from "node:child_process";
5
- import { existsSync, readFileSync } from "node:fs";
3
+ import { existsSync } from "node:fs";
6
4
  import { mkdir, readFile, rename, rm, writeFile } from "node:fs/promises";
7
- import path, { dirname, isAbsolute, join } from "node:path";
5
+ import path from "node:path";
8
6
  import { promisify } from "node:util";
9
7
  import { gunzip } from "node:zlib";
10
- import { fileURLToPath, pathToFileURL } from "node:url";
8
+ import { fileURLToPath } from "node:url";
11
9
  import { randomUUID } from "node:crypto";
10
+ import { fork } from "node:child_process";
12
11
  import { childLogger } from "document-model";
13
12
  //#region src/pieces/activepieces/fetch.ts
14
13
  const gunzip$1 = promisify(gunzip);
@@ -110,12 +109,13 @@ async function fetchPieceBundle(options) {
110
109
  assertValidPackageCoordinate(name, version);
111
110
  const dir = path.join(cacheDir, `${name.replace("/", "-")}-${version}`);
112
111
  assertWithinCacheDir(dir, cacheDir);
113
- if (existsSync(path.join(dir, "package.json"))) return {
114
- dir,
115
- source: "cache",
116
- dependencies: await readDependencies(dir),
117
- installed: false
118
- };
112
+ if (existsSync(path.join(dir, "package.json"))) {
113
+ await assertSelfContained(dir, name, version);
114
+ return {
115
+ dir,
116
+ source: "cache"
117
+ };
118
+ }
119
119
  const { tgz, source } = await downloadTarball(name, version, timeoutMs);
120
120
  const staging = `${dir}.tmp-${process.pid}`;
121
121
  await rm(staging, {
@@ -136,45 +136,10 @@ async function fetchPieceBundle(options) {
136
136
  });
137
137
  if (!existsSync(path.join(dir, "package.json"))) throw error;
138
138
  }
139
+ await assertSelfContained(dir, name, version);
139
140
  return {
140
141
  dir,
141
- source,
142
- dependencies: await readDependencies(dir),
143
- installed: false
144
- };
145
- }
146
- async function installPieceBundle(options) {
147
- const { name, version, cacheDir, timeoutMs = 12e4 } = options;
148
- assertValidPackageCoordinate(name, version);
149
- const workspace = path.join(cacheDir, `${name.replace("/", "-")}-${version}.install`);
150
- assertWithinCacheDir(workspace, cacheDir);
151
- const dir = path.join(workspace, "node_modules", name);
152
- if (existsSync(path.join(workspace, "ready")) && existsSync(path.join(dir, "package.json"))) return {
153
- dir,
154
- source: "cache",
155
- dependencies: await readDependencies(dir),
156
- installed: true
157
- };
158
- const { tgz, source } = await downloadTarball(name, version, timeoutMs);
159
- await rm(workspace, {
160
- recursive: true,
161
- force: true
162
- });
163
- await mkdir(workspace, { recursive: true });
164
- await writeFile(path.join(workspace, "bundle.tgz"), tgz);
165
- await writeFile(path.join(workspace, "package.json"), JSON.stringify({
166
- name: "piece-workspace",
167
- version: "1.0.0",
168
- private: true,
169
- dependencies: { [name]: "file:./bundle.tgz" }
170
- }));
171
- await runNpmInstall(workspace, timeoutMs);
172
- await writeFile(path.join(workspace, "ready"), "true");
173
- return {
174
- dir,
175
- source,
176
- dependencies: await readDependencies(dir),
177
- installed: true
142
+ source
178
143
  };
179
144
  }
180
145
  const inFlight = /* @__PURE__ */ new Map();
@@ -182,33 +147,21 @@ async function ensurePieceBundle(options) {
182
147
  const key = `${options.cacheDir}\u0000${options.name}@${options.version}`;
183
148
  const pending = inFlight.get(key);
184
149
  if (pending) return pending;
185
- const started = resolveBundle(options).finally(() => inFlight.delete(key));
150
+ const started = fetchPieceBundle(options).finally(() => inFlight.delete(key));
186
151
  inFlight.set(key, started);
187
152
  return started;
188
153
  }
189
- async function resolveBundle(options) {
190
- const fetched = await fetchPieceBundle(options);
191
- if (Object.keys(fetched.dependencies).length === 0) return fetched;
192
- return installPieceBundle(options);
193
- }
194
- async function runNpmInstall(cwd, timeoutMs) {
195
- const windows = process.platform === "win32";
196
- await new Promise((resolve, reject) => {
197
- execFile(windows ? "npm.cmd" : "npm", [
198
- "install",
199
- "--ignore-scripts",
200
- "--no-audit",
201
- "--no-fund",
202
- "--loglevel=error"
203
- ], {
204
- cwd,
205
- timeout: timeoutMs,
206
- shell: windows
207
- }, (error, _stdout, stderr) => {
208
- if (error) reject(/* @__PURE__ */ new Error(`npm install failed in ${cwd}: ${stderr || error.message}`));
209
- else resolve();
210
- });
211
- });
154
+ const AP_SELF_CONTAINED_SINCE = "0.86.0";
155
+ const MAX_LISTED_DEPENDENCIES = 5;
156
+ async function assertSelfContained(dir, name, version) {
157
+ const dependencies = await readDependencies(dir);
158
+ const declared = Object.keys(dependencies);
159
+ if (declared.length === 0) return;
160
+ const listed = declared.slice(0, MAX_LISTED_DEPENDENCIES).map((dep) => `${dep}@${dependencies[dep]}`);
161
+ const rest = declared.length - listed.length;
162
+ const count = declared.length === 1 ? "a dependency" : `${declared.length} dependencies`;
163
+ const since = name.startsWith("@activepieces/") ? ` Activepieces bundles have been self-contained since ${AP_SELF_CONTAINED_SINCE}.` : "";
164
+ throw new Error(`Piece bundle ${name}@${version} is not self-contained: it declares ${count} (${listed.join(", ")}${rest > 0 ? `, and ${rest} more` : ""}). The reactor no longer installs a bundle's dependencies. Pin ${name} at or above its first self-contained release.${since}`);
212
165
  }
213
166
  async function readDependencies(dir) {
214
167
  const raw = await readFile(path.join(dir, "package.json"), "utf8");
@@ -1300,105 +1253,15 @@ async function runWorkflow(options) {
1300
1253
  //#endregion
1301
1254
  //#region src/reactor/piece-registry.ts
1302
1255
  const logger = childLogger(["workflow", "piece-registry"]);
1303
- const MANIFEST_CANDIDATES = ["dist/node/pieces/index.mjs", "pieces/index.ts"];
1304
- const require = createRequire(import.meta.url);
1305
- function packageRoot(packageName) {
1306
- try {
1307
- return dirname(require.resolve(`${packageName}/package.json`));
1308
- } catch {}
1309
- try {
1310
- let dir = dirname(require.resolve(packageName));
1311
- while (!existsSync(join(dir, "package.json"))) {
1312
- const parent = dirname(dir);
1313
- if (parent === dir) return void 0;
1314
- dir = parent;
1315
- }
1316
- return dir;
1317
- } catch {
1318
- return;
1319
- }
1320
- }
1321
- function configuredPackages(projectRoot) {
1322
- const file = join(projectRoot, "powerhouse.config.json");
1323
- try {
1324
- return (JSON.parse(readFileSync(file, "utf8")).packages ?? []).map((entry) => entry.packageName).filter((name) => typeof name === "string" && name !== "");
1325
- } catch {
1326
- return [];
1327
- }
1328
- }
1329
- async function readManifest(root) {
1330
- for (const candidate of MANIFEST_CANDIDATES) {
1331
- const file = join(root, candidate);
1332
- if (!existsSync(file)) continue;
1333
- const module = await import(
1334
- /* @vite-ignore */
1335
- pathToFileURL(file).href
1336
- );
1337
- const declared = module.pieces ?? module.default;
1338
- if (Array.isArray(declared)) return declared;
1339
- logger.warn(`${file} exports no "pieces" array; ignoring it`);
1340
- return [];
1341
- }
1342
- return [];
1343
- }
1344
- function locate(declared, root, source) {
1345
- const where = declared.entry ?? declared.bundle;
1346
- if (!where) {
1347
- logger.warn(`Piece "${declared.name}" from ${source} declares no bundle or entry`);
1348
- return;
1349
- }
1350
- const path = isAbsolute(where) ? where : join(root, where);
1351
- if (!(declared.entry ? existsSync(path) : existsSync(join(path, "package.json")))) {
1352
- logger.warn(`Piece "${declared.name}" from ${source} is declared but not built at ${path}`);
1353
- return;
1354
- }
1355
- return {
1356
- name: declared.name,
1357
- version: declared.version,
1358
- ...declared.entry ? { entryPath: path } : { bundleDir: path }
1359
- };
1360
- }
1361
1256
  var PieceRegistry = class {
1362
1257
  byName = /* @__PURE__ */ new Map();
1363
- loading;
1364
- load(projectRoot = process.cwd()) {
1365
- return this.loading = this.discover(projectRoot);
1366
- }
1367
- async discover(projectRoot) {
1258
+ setPieces(pieces) {
1368
1259
  const found = /* @__PURE__ */ new Map();
1369
- const sources = [{
1370
- source: "this project",
1371
- root: projectRoot
1372
- }, ...configuredPackages(projectRoot).flatMap((name) => {
1373
- const root = packageRoot(name);
1374
- if (!root) {
1375
- logger.warn(`Package "${name}" is configured but not resolvable`);
1376
- return [];
1377
- }
1378
- return [{
1379
- source: name,
1380
- root
1381
- }];
1382
- })];
1383
- for (const { source, root } of sources) {
1384
- let declared;
1385
- try {
1386
- declared = await readManifest(root);
1387
- } catch (error) {
1388
- logger.warn(`Could not read the pieces of ${source}: ${String(error)}`);
1389
- continue;
1390
- }
1391
- for (const entry of declared) {
1392
- if (found.has(entry.name)) continue;
1393
- const piece = locate(entry, root, source);
1394
- if (piece) found.set(entry.name, piece);
1395
- }
1396
- }
1260
+ for (const piece of pieces) if (!found.has(piece.name)) found.set(piece.name, piece);
1397
1261
  this.byName = found;
1398
- if (found.size > 0) logger.info(`Loaded ${found.size} package piece(s): ${[...found.keys()].join(", ")}`);
1399
- }
1400
- ready(projectRoot = process.cwd()) {
1401
- return this.loading ??= this.discover(projectRoot);
1262
+ const names = [...found.keys()].join(", ");
1263
+ if (found.size > 0) logger.info(`Holding ${found.size} package piece(s): @names`, names);
1264
+ else logger.debug("Holding no package pieces");
1402
1265
  }
1403
1266
  lookup = (name) => this.byName.get(name);
1404
1267
  entries() {
@@ -1407,13 +1270,13 @@ var PieceRegistry = class {
1407
1270
  versions() {
1408
1271
  return Object.fromEntries([...this.byName.values()].map((piece) => [piece.name, piece.version]));
1409
1272
  }
1273
+ /** Test seam: a suite that filled the registry starts the next from nothing. */
1410
1274
  reset() {
1411
1275
  this.byName = /* @__PURE__ */ new Map();
1412
- this.loading = void 0;
1413
1276
  }
1414
1277
  };
1415
1278
  const packagePieces = new PieceRegistry();
1416
1279
  //#endregion
1417
1280
  export { pieceModuleRef as C, localFirstResolver as S, fetchPieceBundle as T, secretRefFromId as _, CompositeBlockExecutor as a, PieceWorkerError as b, storeHandlers as c, declaredConnectionIds as d, shapeConnection as f, parseSecretRef as g, SecretNotFoundError as h, ActivepiecesBlockExecutor as i, BoundConnectionResolver as l, SecretDeletedError as m, packagePieces as n, parseBlockType as o, InMemorySecretProvider as p, runWorkflow as r, reactorHandlers as s, PieceRegistry as t, StaticConnectionResolver as u, PieceWorkerPool as v, ensurePieceBundle as w, PieceWorkerTimeoutError as x, PieceWorker as y };
1418
1281
 
1419
- //# sourceMappingURL=piece-registry-BWWihLyp.js.map
1282
+ //# sourceMappingURL=piece-registry-fpNdxNLr.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"piece-registry-fpNdxNLr.js","names":["gunzip","gunzipCb"],"sources":["../src/pieces/activepieces/fetch.ts","../src/pieces/activepieces/resolver.ts","../src/pieces/activepieces/worker/transport.ts","../src/pieces/activepieces/worker/host.ts","../src/pieces/activepieces/worker/pool.ts","../src/pieces/engine/secrets.ts","../src/pieces/engine/expressions.ts","../src/pieces/engine/connections.ts","../src/pieces/engine/blocks.ts","../src/pieces/engine/coordinator.ts","../src/reactor/piece-registry.ts"],"sourcesContent":["import { existsSync } from \"node:fs\";\nimport { mkdir, readFile, rename, rm, writeFile } from \"node:fs/promises\";\nimport path from \"node:path\";\nimport { promisify } from \"node:util\";\nimport { gunzip as gunzipCb } from \"node:zlib\";\n\nconst gunzip = promisify(gunzipCb);\n\n// Mirrors their pieceBundle.resolve(): CDN bundle when served, else the npm\n// tarball. Tarballs are immutable per (name, version), so the cache never expires.\nconst CDN_PIECES_URL = \"https://cdn.activepieces.com/pieces/bundled/\";\nconst NPM_REGISTRY_URL = \"https://registry.npmjs.org\";\n\nexport function cdnTarballUrl(name: string, version: string): string {\n return `${CDN_PIECES_URL}${name.replace(\"/\", \"-\")}-${version}.tgz`;\n}\n\nexport function npmTarballUrl(name: string, version: string): string {\n const unscoped = name.startsWith(\"@\") ? name.split(\"/\")[1] : name;\n return `${NPM_REGISTRY_URL}/${name}/-/${unscoped}-${version}.tgz`;\n}\n\n// name/version come from a workflow step's blockType, an unconstrained string.\nconst NPM_NAME_RE = /^(@[a-z0-9][a-z0-9-_.]*\\/)?[a-z0-9][a-z0-9-_.]*$/;\nconst NPM_VERSION_RE = /^[A-Za-z0-9][A-Za-z0-9.+-]*$/;\n\nfunction assertValidPackageCoordinate(name: string, version: string): void {\n if (!NPM_NAME_RE.test(name)) {\n throw new Error(`Invalid piece package name: ${name}`);\n }\n if (!NPM_VERSION_RE.test(version)) {\n throw new Error(`Invalid piece package version: ${version}`);\n }\n}\n\n// Belt-and-suspenders: the path we're about to rm/rename must land under cacheDir.\nfunction assertWithinCacheDir(dir: string, cacheDir: string): void {\n const root = path.resolve(cacheDir);\n const resolved = path.resolve(dir);\n if (resolved !== root && !resolved.startsWith(root + path.sep)) {\n throw new Error(`Resolved piece cache path escapes cacheDir: ${dir}`);\n }\n}\n\nfunction readString(header: Buffer, offset: number, length: number): string {\n const slice = header.subarray(offset, offset + length);\n const nul = slice.indexOf(0);\n return slice.subarray(0, nul === -1 ? length : nul).toString(\"utf8\");\n}\n\n// Published piece bundles run a few hundred KB extracted; the cap is well clear\n// of that and bounds what a hostile or corrupt tarball can inflate to.\nconst MAX_EXTRACTED_BYTES = 64 * 1024 * 1024;\n\n// Caps the compressed transfer itself, before gunzip ever runs — the decompressed\n// cap above does nothing for a huge (not necessarily bomb-like) response body.\nconst MAX_COMPRESSED_BYTES = 64 * 1024 * 1024;\n\n// Minimal ustar extraction: regular files only, \"package/\" root stripped.\nasync function extractTarball(tgz: Buffer, dest: string): Promise<void> {\n // Async gunzip: the sync one blocks the reactor's event loop for every\n // request, not just this one, and inflation is unbounded without maxOutputLength.\n const tar = await gunzip(tgz, { maxOutputLength: MAX_EXTRACTED_BYTES }).catch(\n (error: unknown) => {\n throw new Error(`Failed to decompress piece bundle: ${String(error)}`);\n },\n );\n let offset = 0;\n while (offset + 512 <= tar.length) {\n const header = tar.subarray(offset, offset + 512);\n if (header.every((byte) => byte === 0)) break;\n const name = readString(header, 0, 100);\n const prefix = readString(header, 345, 155);\n const size = parseInt(readString(header, 124, 12).trim() || \"0\", 8);\n const type = String.fromCharCode(header[156]);\n offset += 512;\n const isFile = type === \"0\" || type === \"\\0\" || type === \"\";\n if (isFile && size >= 0) {\n const full = prefix ? `${prefix}/${name}` : name;\n const rel = full.replace(/^[^/]+\\//, \"\");\n const target = path.resolve(dest, rel);\n // Guard against path traversal from a hostile tarball.\n if (rel && target.startsWith(path.resolve(dest) + path.sep)) {\n await mkdir(path.dirname(target), { recursive: true });\n await writeFile(target, tar.subarray(offset, offset + size));\n }\n }\n offset += Math.ceil(size / 512) * 512;\n }\n}\n\nexport interface FetchPieceBundleOptions {\n name: string;\n version: string;\n cacheDir: string;\n timeoutMs?: number;\n}\n\nexport interface FetchedBundle {\n dir: string;\n source: \"cdn\" | \"npm\" | \"cache\";\n}\n\n// Bounds the transfer before gunzip: rejects an over-limit Content-Length up\n// front, else tracks a running total as the body streams in.\nasync function readBoundedBody(\n response: Response,\n url: string,\n): Promise<Buffer> {\n const declared = response.headers.get(\"content-length\");\n if (declared && Number(declared) > MAX_COMPRESSED_BYTES) {\n throw new Error(\n `${url} exceeds the ${MAX_COMPRESSED_BYTES}-byte compressed size cap (Content-Length: ${declared})`,\n );\n }\n if (!response.body) return Buffer.from(await response.arrayBuffer());\n const reader = response.body.getReader();\n const chunks: Uint8Array[] = [];\n let total = 0;\n for (;;) {\n const { done, value } = await reader.read();\n if (done) break;\n total += value.byteLength;\n if (total > MAX_COMPRESSED_BYTES) {\n await reader.cancel();\n throw new Error(\n `${url} exceeds the ${MAX_COMPRESSED_BYTES}-byte compressed size cap`,\n );\n }\n chunks.push(value);\n }\n return Buffer.concat(chunks);\n}\n\nasync function downloadTarball(\n name: string,\n version: string,\n timeoutMs: number,\n): Promise<{ tgz: Buffer; source: \"cdn\" | \"npm\" }> {\n const sources: { source: \"cdn\" | \"npm\"; url: string }[] = [\n { source: \"cdn\", url: cdnTarballUrl(name, version) },\n { source: \"npm\", url: npmTarballUrl(name, version) },\n ];\n let lastError: unknown;\n for (const { source, url } of sources) {\n try {\n const response = await fetch(url, {\n signal: AbortSignal.timeout(timeoutMs),\n });\n if (!response.ok) {\n lastError = new Error(`${url} responded ${response.status}`);\n continue;\n }\n return { tgz: await readBoundedBody(response, url), source };\n } catch (error) {\n lastError = error;\n }\n }\n throw new Error(\n `Failed to fetch piece bundle ${name}@${version}: ${String(lastError)}`,\n );\n}\n\n// Downloads and extracts a published piece bundle, returning the directory to\n// hand to loadPieceFromDir(). A cached extraction is reused, and re-checked.\nexport async function fetchPieceBundle(\n options: FetchPieceBundleOptions,\n): Promise<FetchedBundle> {\n const { name, version, cacheDir, timeoutMs = 30_000 } = options;\n assertValidPackageCoordinate(name, version);\n const dir = path.join(cacheDir, `${name.replace(\"/\", \"-\")}-${version}`);\n assertWithinCacheDir(dir, cacheDir);\n if (existsSync(path.join(dir, \"package.json\"))) {\n await assertSelfContained(dir, name, version);\n return { dir, source: \"cache\" };\n }\n\n const { tgz, source } = await downloadTarball(name, version, timeoutMs);\n const staging = `${dir}.tmp-${process.pid}`;\n await rm(staging, { recursive: true, force: true });\n await extractTarball(tgz, staging);\n await rm(dir, { recursive: true, force: true });\n try {\n await rename(staging, dir);\n } catch (error) {\n // Concurrent fetcher won the rename; its extraction is identical.\n await rm(staging, { recursive: true, force: true });\n if (!existsSync(path.join(dir, \"package.json\"))) throw error;\n }\n // Checked here rather than before the rename so a bundle an older build\n // already extracted is refused on its cache hit too, not only a fresh one.\n await assertSelfContained(dir, name, version);\n return { dir, source };\n}\n\n// Concurrent callers for the same bundle share one download+extract rather\n// than racing each other through it.\nconst inFlight = new Map<string, Promise<FetchedBundle>>();\n\n// The way in: a bundle arrives extracted, cached and checked, and callers that\n// ask for the same one at the same time wait on a single fetch.\nexport async function ensurePieceBundle(\n options: FetchPieceBundleOptions,\n): Promise<FetchedBundle> {\n const key = `${options.cacheDir}\\u0000${options.name}@${options.version}`;\n const pending = inFlight.get(key);\n if (pending) return pending;\n // Dropped once settled, refusals included, so a later caller re-checks the\n // bundle rather than inheriting this call's answer forever.\n const started = fetchPieceBundle(options).finally(() => inFlight.delete(key));\n inFlight.set(key, started);\n return started;\n}\n\n// The Activepieces release that began inlining a piece's dependencies into its\n// bundle. They still publish pieces to npm, which is why npm stays a source.\nconst AP_SELF_CONTAINED_SINCE = \"0.86.0\";\n\n// Enough to recognise what the bundle wants without turning the refusal into\n// a wall of text.\nconst MAX_LISTED_DEPENDENCIES = 5;\n\n// A bundle has to carry its own code: the worker imports it straight out of the\n// cache directory, where there is no node_modules and nothing to install one.\nasync function assertSelfContained(\n dir: string,\n name: string,\n version: string,\n): Promise<void> {\n const dependencies = await readDependencies(dir);\n const declared = Object.keys(dependencies);\n if (declared.length === 0) return;\n const listed = declared\n .slice(0, MAX_LISTED_DEPENDENCIES)\n .map((dep) => `${dep}@${dependencies[dep]}`);\n const rest = declared.length - listed.length;\n const count =\n declared.length === 1 ? \"a dependency\" : `${declared.length} dependencies`;\n // Only an Activepieces piece gets their release number: a bundle from\n // anywhere else would be sent chasing a version that means nothing to it.\n const since = name.startsWith(\"@activepieces/\")\n ? ` Activepieces bundles have been self-contained since ${AP_SELF_CONTAINED_SINCE}.`\n : \"\";\n throw new Error(\n `Piece bundle ${name}@${version} is not self-contained: it declares ${count} ` +\n `(${listed.join(\", \")}${rest > 0 ? `, and ${rest} more` : \"\"}). ` +\n `The reactor no longer installs a bundle's dependencies. Pin ${name} at or above ` +\n `its first self-contained release.${since}`,\n );\n}\n\nasync function readDependencies(dir: string): Promise<Record<string, string>> {\n const raw = await readFile(path.join(dir, \"package.json\"), \"utf8\");\n const pkg = JSON.parse(raw) as { dependencies?: Record<string, string> };\n return pkg.dependencies ?? {};\n}\n","// Where a piece's code comes from. Two sources, one seam.\n\n// A published piece is a bundle fetched from a registry and cached on disk; a\n// first-party piece ships inside an installed reactor package and is already\n// on disk, with no version to fetch and no cache to warm.\nimport { ensurePieceBundle } from \"./fetch.js\";\nimport type { PieceModuleRef } from \"./worker/protocol.js\";\n\nexport interface ResolvedPiece extends PieceModuleRef {\n name: string;\n version: string;\n // True when the piece is code the operator installed rather than a bundle\n // fetched from a registry. Only these are offered host capabilities.\n local: boolean;\n}\n\nexport interface PieceResolver {\n resolve(name: string, version: string): Promise<ResolvedPiece>;\n}\n\n// A piece found in an installed reactor package: a module file, or a directory\n// in npm-bundle shape when the package ships one already bundled.\nexport interface LocalPiece {\n name: string;\n version: string;\n entryPath?: string;\n bundleDir?: string;\n}\n\n// May answer asynchronously: a host whose registry loads on first use waits\n// here rather than racing every caller to have loaded it first.\nexport type LocalPieceLookup = (\n name: string,\n) => LocalPiece | undefined | Promise<LocalPiece | undefined>;\n\n// One entry of a reactor package's `pieces` export: which piece it ships and\n// where the built bundle sits, relative to the package root.\nexport type { PackagePiece } from \"@powerhousedao/pieces-framework\";\n\n// The published path: fetch (or reuse) the bundle for an exact version.\nexport function bundleResolver(options: {\n cacheDir: string;\n timeoutMs?: number;\n}): PieceResolver {\n return {\n async resolve(name: string, version: string): Promise<ResolvedPiece> {\n const bundle = await ensurePieceBundle({\n name,\n version,\n cacheDir: options.cacheDir,\n ...(options.timeoutMs ? { timeoutMs: options.timeoutMs } : {}),\n });\n return { name, version, bundleDir: bundle.dir, local: false };\n },\n };\n}\n\n// An installed package wins over the registry for its own name, whatever\n// version the block type asked for: the installed copy is the one this reactor\n// runs, and a fetched bundle of the same name would shadow it silently.\nexport function localFirstResolver(\n lookup: LocalPieceLookup,\n fallback: PieceResolver,\n): PieceResolver {\n return {\n async resolve(name: string, version: string): Promise<ResolvedPiece> {\n const local = await lookup(name);\n if (!local) return fallback.resolve(name, version);\n return {\n name,\n version: local.version,\n ...(local.entryPath ? { entryPath: local.entryPath } : {}),\n ...(local.bundleDir ? { bundleDir: local.bundleDir } : {}),\n local: true,\n };\n },\n };\n}\n\n// What a request hands the worker, from whichever source answered.\nexport function pieceModuleRef(piece: ResolvedPiece): PieceModuleRef {\n return piece.entryPath\n ? { entryPath: piece.entryPath }\n : { bundleDir: piece.bundleDir };\n}\n","// What PieceWorker needs from a connection to a worker, and nothing else.\n\n// Written against this rather than a ChildProcess so a later transport — a\n// pooled fork, a socket to another machine — slots in underneath unchanged.\nimport { fork, type ChildProcess } from \"node:child_process\";\nimport { existsSync } from \"node:fs\";\nimport path from \"node:path\";\nimport { fileURLToPath } from \"node:url\";\n\nexport interface TransportExit {\n code: number | null;\n signal: NodeJS.Signals | null;\n}\n\nexport type TransportEventMap = {\n message: unknown;\n exit: TransportExit;\n};\n\nexport type TransportEvent = keyof TransportEventMap;\n\nexport type TransportListener<E extends TransportEvent> = (\n payload: TransportEventMap[E],\n) => void;\n\n// One worker's connection. An implementation must deliver `message` payloads\n// faithfully enough for the protocol above, and emit `exit` exactly once.\n\n// \"Faithfully enough\" means JSON-shaped, deliberately: the fork's structured\n// clone would carry a Date or a Map, but nothing may depend on that, because\n// no other carrier could honour it.\n\n// PieceWorker flattens what it sends and the child flattens what it answers,\n// so this is a contract a socket could meet too — a transport is not required\n// to preserve anything JSON would lose.\nexport interface IPieceWorkerTransport {\n send(message: unknown): void;\n on<E extends TransportEvent>(event: E, listener: TransportListener<E>): void;\n off<E extends TransportEvent>(event: E, listener: TransportListener<E>): void;\n // Ends the worker now; it takes any pending host calls with it.\n kill(): void;\n // False once the worker cannot receive: a send after this is dropped.\n readonly connected: boolean;\n}\n\n// Builds a fresh connection. Called on first use and again after a worker is\n// killed, so a factory must be able to produce more than one.\nexport type PieceWorkerTransportFactory = () => IPieceWorkerTransport;\n\nexport function defaultEntryPath(): string {\n let dir = path.dirname(fileURLToPath(import.meta.url));\n while (!existsSync(path.join(dir, \"package.json\"))) {\n const parent = path.dirname(dir);\n if (parent === dir) throw new Error(\"Could not locate package root\");\n dir = parent;\n }\n const entry = path.join(dir, \"dist\", \"worker-entry.js\");\n if (!existsSync(entry)) {\n throw new Error(`Worker entry not built at ${entry} — run pnpm build`);\n }\n return entry;\n}\n\n// A forked node child on this machine, over its IPC channel.\nexport function createForkTransport(entryPath: string): IPieceWorkerTransport {\n const child: ChildProcess = fork(entryPath, [], {\n // Empty env: the child gets no host secrets and no inherited TLS overrides.\n env: {},\n execArgv: [],\n // Structured clone rather than JSON, so a Buffer in a payload survives.\n serialization: \"advanced\",\n // Piece stdout/stderr are dropped for now; log capture arrives with journaling.\n stdio: [\"ignore\", \"ignore\", \"ignore\", \"ipc\"],\n });\n\n // Node reports exit as two positional arguments; the interface carries one\n // payload, so the adaptation lives here rather than in every listener.\n const exitListeners = new Map<\n TransportListener<\"exit\">,\n (code: number | null, signal: NodeJS.Signals | null) => void\n >();\n\n return {\n get connected() {\n return child.connected;\n },\n send(message) {\n child.send(message as never);\n },\n on(event, listener) {\n if (event === \"exit\") {\n const adapted = (code: number | null, signal: NodeJS.Signals | null) =>\n (listener as TransportListener<\"exit\">)({ code, signal });\n exitListeners.set(listener as TransportListener<\"exit\">, adapted);\n child.on(\"exit\", adapted);\n return;\n }\n child.on(\"message\", listener as (value: unknown) => void);\n },\n off(event, listener) {\n if (event === \"exit\") {\n const adapted = exitListeners.get(\n listener as TransportListener<\"exit\">,\n );\n if (adapted) {\n child.off(\"exit\", adapted);\n exitListeners.delete(listener as TransportListener<\"exit\">);\n }\n return;\n }\n child.off(\"message\", listener as (value: unknown) => void);\n },\n kill() {\n child.kill(\"SIGKILL\");\n },\n };\n}\n","import type { StagedFile } from \"../context/files.js\";\nimport type { RecordedListener, RecordedSchedule } from \"../context/trigger.js\";\nimport { jsonSafe } from \"./json-safe.js\";\nimport {\n createForkTransport,\n defaultEntryPath,\n type IPieceWorkerTransport,\n type PieceWorkerTransportFactory,\n type TransportExit,\n} from \"./transport.js\";\nimport type {\n CheckConnectionRequest,\n DescribePieceRequest,\n HostCallHandlers,\n HostCallMessage,\n HostCallResponse,\n HostNotifyHandlers,\n HostNotifyMessage,\n ResolveOptionsRequest,\n RunActionRequest,\n SerializedPieceError,\n TriggerHookRequest,\n WorkerResponse,\n} from \"./protocol.js\";\n\ntype WorkerRequestType =\n | \"run\"\n | \"resolve-options\"\n | \"trigger-hook\"\n | \"check-connection\"\n | \"describe\";\n\ntype WorkerRequest =\n | RunActionRequest\n | ResolveOptionsRequest\n | TriggerHookRequest\n | CheckConnectionRequest\n | DescribePieceRequest;\n\nexport class PieceWorkerError extends Error {\n readonly serialized: SerializedPieceError;\n\n constructor(serialized: SerializedPieceError) {\n super(`${serialized.name}: ${serialized.message}`);\n this.name = \"PieceWorkerError\";\n this.serialized = serialized;\n }\n}\n\nexport class PieceWorkerTimeoutError extends Error {\n constructor(timeoutMs: number) {\n super(`Piece action timed out after ${timeoutMs}ms; worker was replaced`);\n this.name = \"PieceWorkerTimeoutError\";\n }\n}\n\nexport class PieceWorkerExitError extends Error {\n constructor(code: number | null, signal: string | null) {\n super(`Piece worker exited unexpectedly (code=${code}, signal=${signal})`);\n this.name = \"PieceWorkerExitError\";\n }\n}\n\nexport interface PieceWorkerResult {\n output: unknown;\n touched: string[];\n tlsPoisoned: boolean;\n // run only: files the piece wrote through ctx.files, staged on disk for the\n // host to ingest before the output is journalled.\n files?: StagedFile[];\n // trigger-hook only: final store contents plus captured context calls.\n storeState?: Record<string, unknown>;\n schedules?: RecordedSchedule[];\n listeners?: RecordedListener[];\n}\n\n// Handlers the host offers for the duration of one request: calls it answers,\n// and one-way reports it receives.\nexport interface RequestTaps {\n hostCalls?: HostCallHandlers;\n notifications?: HostNotifyHandlers;\n}\n\n// Every request that can serve a piece takes the same shape: a deadline plus\n// the taps the host offers while it runs.\nexport interface RequestOptions extends RequestTaps {\n timeoutMs?: number;\n}\n\n/** @deprecated Named for the one request that had it; every request takes it\n * now. Kept because the old name is on main, in this package's public types. */\nexport type RunActionOptions = RequestOptions;\n\ntype ChildMessage = WorkerResponse | HostCallMessage | HostNotifyMessage;\n\n// A tap reports on the step; it never decides its outcome. Node delivers these\n// before the result, so no draining step is needed at teardown.\nfunction serveNotify(\n message: HostNotifyMessage,\n handlers: HostNotifyHandlers | undefined,\n): void {\n const handler = handlers?.[message.method];\n if (!handler) return;\n try {\n // Declared void, but TypeScript admits an async function here, and its\n // rejection would take the host down rather than the tap.\n void Promise.resolve(handler(message.payload)).catch(() => undefined);\n } catch {\n // A broken tap is not the step's problem.\n }\n}\n\nexport interface PieceWorkerOptions {\n // Absolute path to the compiled worker entry; defaults to dist/worker-entry.js.\n entryPath?: string;\n defaultTimeoutMs?: number;\n // How to reach a worker. Defaults to a forked child on this machine; a\n // remote transport replaces it without touching the protocol above.\n transport?: PieceWorkerTransportFactory;\n}\n\n// The five requests a worker serves, plus teardown. Callers hold this rather\n// than PieceWorker itself, so a child that outlives every request and a child\n// that lives for one run are interchangeable to them.\nexport interface IPieceWorker {\n runAction(\n request: RunActionRequest,\n options?: RequestOptions,\n ): Promise<PieceWorkerResult>;\n resolveOptions(\n request: ResolveOptionsRequest,\n options?: RequestOptions,\n ): Promise<PieceWorkerResult>;\n checkConnection(\n request: CheckConnectionRequest,\n options?: { timeoutMs?: number },\n ): Promise<PieceWorkerResult>;\n describePiece(\n request: DescribePieceRequest,\n options?: { timeoutMs?: number },\n ): Promise<PieceWorkerResult>;\n runTriggerHook(\n request: TriggerHookRequest,\n options?: RequestOptions,\n ): Promise<PieceWorkerResult>;\n // Ends the worker. A caller that was handed one it does not own must not\n // call this; PieceWorkerPool disposes the workers it hands out.\n dispose(): void;\n}\n\n// Executes piece actions in a child process. Side-effects (TLS env poisoning,\n// crashes) stay in the child; a timed-out or crashed worker is replaced.\nexport class PieceWorker implements IPieceWorker {\n private readonly connect: PieceWorkerTransportFactory;\n private readonly defaultTimeoutMs: number;\n private worker: IPieceWorkerTransport | undefined;\n private queue: Promise<unknown> = Promise.resolve();\n private nextId = 1;\n\n constructor(options: PieceWorkerOptions = {}) {\n const entryPath = options.entryPath;\n this.connect =\n options.transport ??\n (() => createForkTransport(entryPath ?? defaultEntryPath()));\n this.defaultTimeoutMs = options.defaultTimeoutMs ?? 30_000;\n }\n\n // Requests are serialized per worker; concurrency comes from holding more\n // than one, which is what PieceWorkerPool does.\n runAction(\n request: RunActionRequest,\n options: RequestOptions = {},\n ): Promise<PieceWorkerResult> {\n return this.enqueue(\"run\", request, options.timeoutMs, options);\n }\n\n // Design-time DROPDOWN options() / DYNAMIC props() resolution. It takes the\n // same taps a run does: a package piece's resolver may read the reactor.\n resolveOptions(\n request: ResolveOptionsRequest,\n options: RequestOptions = {},\n ): Promise<PieceWorkerResult> {\n return this.enqueue(\"resolve-options\", request, options.timeoutMs, options);\n }\n\n // A piece's app.checkConnection over resolved credentials; the output is a\n // CheckConnectionOutcome.\n checkConnection(\n request: CheckConnectionRequest,\n options: { timeoutMs?: number } = {},\n ): Promise<PieceWorkerResult> {\n return this.enqueue(\"check-connection\", request, options.timeoutMs);\n }\n\n // The piece's design-time descriptor; the output is a PieceDescriptor.\n describePiece(\n request: DescribePieceRequest,\n options: { timeoutMs?: number } = {},\n ): Promise<PieceWorkerResult> {\n return this.enqueue(\"describe\", request, options.timeoutMs);\n }\n\n // One trigger lifecycle hook. It takes the same taps a run does, so a\n // `durableStore` hook reaches the host's store while it is still running.\n runTriggerHook(\n request: TriggerHookRequest,\n options: RequestOptions = {},\n ): Promise<PieceWorkerResult> {\n return this.enqueue(\"trigger-hook\", request, options.timeoutMs, options);\n }\n\n private enqueue(\n type: WorkerRequestType,\n request: WorkerRequest,\n timeoutMs?: number,\n taps: RequestTaps = {},\n ): Promise<PieceWorkerResult> {\n const run = this.queue.then(() =>\n this.execute(type, request, timeoutMs ?? this.defaultTimeoutMs, taps),\n );\n this.queue = run.catch(() => undefined);\n return run;\n }\n\n dispose(): void {\n this.worker?.kill();\n this.worker = undefined;\n }\n\n private spawn(): IPieceWorkerTransport {\n if (this.worker) return this.worker;\n const worker = this.connect();\n const forget = () => {\n if (this.worker === worker) this.worker = undefined;\n worker.off(\"exit\", forget);\n };\n worker.on(\"exit\", forget);\n this.worker = worker;\n return worker;\n }\n\n private execute(\n type: WorkerRequestType,\n request: WorkerRequest,\n timeoutMs: number,\n taps: RequestTaps,\n ): Promise<PieceWorkerResult> {\n const worker = this.spawn();\n const id = this.nextId++;\n\n return new Promise<PieceWorkerResult>((resolve, reject) => {\n const timer = setTimeout(() => {\n cleanup();\n worker.kill();\n this.worker = undefined;\n reject(new PieceWorkerTimeoutError(timeoutMs));\n }, timeoutMs);\n\n const onMessage = (value: unknown) => {\n const response = value as ChildMessage;\n // Ids come from two counters; dispatch on type before comparing them.\n if (response.type === \"host-call\" || response.type === \"host-notify\") {\n return;\n }\n if (response.id !== id) return;\n cleanup();\n if (response.type === \"result\") {\n resolve({\n output: response.output,\n touched: response.touched,\n tlsPoisoned: response.tlsPoisoned,\n files: response.files,\n storeState: response.storeState,\n schedules: response.schedules,\n listeners: response.listeners,\n });\n } else {\n reject(new PieceWorkerError(response.error));\n }\n };\n\n const onExit = ({ code, signal }: TransportExit) => {\n cleanup();\n reject(new PieceWorkerExitError(code, signal));\n };\n\n // Served outside the request queue: the queue is held by this very\n // request, so routing a call through it would deadlock the step.\n const onHostCall = (value: unknown) => {\n const message = value as ChildMessage;\n if (message.type === \"host-call\") {\n void this.serveHostCall(worker, message, taps.hostCalls);\n return;\n }\n if (message.type === \"host-notify\") {\n serveNotify(message, taps.notifications);\n }\n };\n\n const cleanup = () => {\n clearTimeout(timer);\n worker.off(\"message\", onMessage);\n worker.off(\"message\", onHostCall);\n worker.off(\"exit\", onExit);\n };\n\n worker.on(\"message\", onMessage);\n worker.on(\"message\", onHostCall);\n worker.on(\"exit\", onExit);\n // Flattened here rather than per caller: config, auth and connection\n // values are piece-authored, and the contract is JSON-shaped both ways.\n worker.send(jsonSafe({ id, type, request }));\n });\n }\n\n // Answers one call from the child. The handler set belongs to the request in\n // flight, so a call arriving after the step returned is refused, not served.\n private async serveHostCall(\n worker: IPieceWorkerTransport,\n message: HostCallMessage,\n handlers: HostCallHandlers | undefined,\n ): Promise<void> {\n let response: HostCallResponse;\n try {\n const handler = handlers?.[message.method];\n if (!handler) {\n throw new Error(`No host handler for \"${message.method}\"`);\n }\n response = {\n id: message.id,\n type: \"host-result\",\n value: await handler(message.payload),\n };\n } catch (error) {\n response = {\n id: message.id,\n type: \"host-result\",\n error: error instanceof Error ? error.message : String(error),\n };\n }\n // A worker killed on timeout takes its pending calls with it.\n if (worker.connected) worker.send(response);\n }\n}\n","// A bounded set of piece workers, handed out one per run (doc 08 §7, doc 03 §5).\n\n// PieceWorker serializes its requests, so one shared worker makes every\n// connector step on the server wait for every other.\n\n// The pool answers both halves of that: N sessions run at once, and each holds\n// a child of its own, killed when the session closes.\n\n// So a run starts on a clean heap, waits only on itself, and takes nothing\n// with it when it ends.\nimport {\n PieceWorker,\n type IPieceWorker,\n type PieceWorkerOptions,\n type PieceWorkerResult,\n type RequestOptions,\n} from \"./host.js\";\nimport type {\n CheckConnectionRequest,\n DescribePieceRequest,\n ResolveOptionsRequest,\n RunActionRequest,\n TriggerHookRequest,\n} from \"./protocol.js\";\n\n// Thrown when a session asks for a slot the pool will not queue.\n\n// The pool queues without limit unless an operator caps it, so this only\n// appears where someone chose failing fast over waiting.\nexport class PieceWorkerPoolBusyError extends Error {\n constructor(size: number, waiting: number) {\n super(\n `All ${size} piece workers are busy and ${waiting} runs are already waiting`,\n );\n this.name = \"PieceWorkerPoolBusyError\";\n }\n}\n\nexport class PieceWorkerSessionClosedError extends Error {\n constructor() {\n super(\"This piece worker session is closed\");\n this.name = \"PieceWorkerSessionClosedError\";\n }\n}\n\nexport interface PieceWorkerPoolOptions extends PieceWorkerOptions {\n // How many sessions may hold a worker at once. Each one is a child process,\n // so this is the server's real connector concurrency.\n size?: number;\n // How many sessions may wait for a slot. 0 is unbounded, which is what the\n // single shared worker effectively did: latency rather than failure.\n maxQueueDepth?: number;\n // Builds one worker. Defaults to a forked child; a test or a remote\n // deployment substitutes its own.\n createWorker?: (options: PieceWorkerOptions) => IPieceWorker;\n}\n\nconst DEFAULT_SIZE = 4;\n\ninterface Waiter {\n session: PieceWorkerSession;\n resolve: () => void;\n reject: (error: unknown) => void;\n}\n\n// One run's claim on a worker. Lazy on purpose: a run whose steps are all\n// document or core blocks never takes a slot and never forks a child.\nexport class PieceWorkerSession implements IPieceWorker {\n private worker: IPieceWorker | undefined;\n private taking: Promise<IPieceWorker> | undefined;\n private held = false;\n private closed = false;\n\n constructor(private readonly pool: PieceWorkerPool) {}\n\n runAction(\n request: RunActionRequest,\n options?: RequestOptions,\n ): Promise<PieceWorkerResult> {\n return this.request((worker) => worker.runAction(request, options));\n }\n\n resolveOptions(\n request: ResolveOptionsRequest,\n options?: { timeoutMs?: number },\n ): Promise<PieceWorkerResult> {\n return this.request((worker) => worker.resolveOptions(request, options));\n }\n\n checkConnection(\n request: CheckConnectionRequest,\n options?: { timeoutMs?: number },\n ): Promise<PieceWorkerResult> {\n return this.request((worker) => worker.checkConnection(request, options));\n }\n\n describePiece(\n request: DescribePieceRequest,\n options?: { timeoutMs?: number },\n ): Promise<PieceWorkerResult> {\n return this.request((worker) => worker.describePiece(request, options));\n }\n\n runTriggerHook(\n request: TriggerHookRequest,\n options?: RequestOptions,\n ): Promise<PieceWorkerResult> {\n return this.request((worker) => worker.runTriggerHook(request, options));\n }\n\n // Kills this session's child and frees its slot for whoever is waiting.\n\n // Idempotent: a caller closing in a `finally` must not have to care whether\n // the run failed before it ever reached a piece step.\n close(): void {\n if (this.closed) return;\n this.closed = true;\n // Still queueing: the request fails now rather than when a slot happens\n // to free, which for a saturated pool may be never.\n this.pool.cancel(this);\n this.worker?.dispose();\n this.worker = undefined;\n this.pool.forget(this);\n this.giveBack();\n }\n\n // IPieceWorker's teardown is this session's close: a caller holding one\n // through the interface ends the run's child, not the pool.\n dispose(): void {\n this.close();\n }\n\n private async request<T>(fn: (worker: IPieceWorker) => Promise<T>) {\n const worker = await this.take();\n // Closed while this was waiting — a shutdown landing mid-run.\n\n // Its worker is already killed, and PieceWorker forks a replacement on the\n // next request, so dispatching now would leak a child the pool never sees.\n if (this.closed) throw new PieceWorkerSessionClosedError();\n return fn(worker);\n }\n\n private take(): Promise<IPieceWorker> {\n if (this.closed) {\n return Promise.reject(new PieceWorkerSessionClosedError());\n }\n if (this.worker) return Promise.resolve(this.worker);\n // Memoized: two steps entering at once must not take two slots, even\n // though the coordinator runs a run's steps one after another.\n this.taking ??= this.acquire();\n return this.taking;\n }\n\n private async acquire(): Promise<IPieceWorker> {\n await this.pool.acquire(this);\n this.held = true;\n // Closed while queueing: hand the slot straight back rather than fork a\n // child for a run that is already over.\n if (this.closed) {\n this.giveBack();\n throw new PieceWorkerSessionClosedError();\n }\n this.worker = this.pool.build();\n return this.worker;\n }\n\n private giveBack(): void {\n if (!this.held) return;\n this.held = false;\n this.pool.release();\n }\n}\n\n// Sized once at construction. Sessions queue for a slot in the order they ask\n// for one, so a burst of runs is served first-come rather than at random.\nexport class PieceWorkerPool {\n readonly size: number;\n private readonly maxQueueDepth: number;\n private readonly createWorker: (options: PieceWorkerOptions) => IPieceWorker;\n private readonly workerOptions: PieceWorkerOptions;\n private readonly sessions = new Set<PieceWorkerSession>();\n private readonly waiters: Waiter[] = [];\n private inUse = 0;\n private disposed = false;\n\n constructor(options: PieceWorkerPoolOptions = {}) {\n const { size, maxQueueDepth, createWorker, ...workerOptions } = options;\n this.size = Math.max(1, Math.trunc(size ?? DEFAULT_SIZE));\n this.maxQueueDepth = Math.max(0, Math.trunc(maxQueueDepth ?? 0));\n this.createWorker = createWorker ?? ((o) => new PieceWorker(o));\n this.workerOptions = workerOptions;\n }\n\n // A run's claim on a worker, for the length of the run. Free until its\n // first piece step, so opening one per run costs nothing.\n session(): PieceWorkerSession {\n if (this.disposed) throw new Error(\"Piece worker pool is disposed\");\n const session = new PieceWorkerSession(this);\n this.sessions.add(session);\n return session;\n }\n\n // Sessions holding a worker, and sessions waiting for one. The wait is what\n // a queue-depth alarm watches: it is invisible in a run's own timings.\n stats(): { size: number; active: number; waiting: number } {\n return {\n size: this.size,\n active: this.inUse,\n waiting: this.waiters.length,\n };\n }\n\n // Closes every session — killing the children mid-run — and refuses the ones\n // still queueing. For shutdown; a live run does not survive it.\n dispose(): void {\n this.disposed = true;\n // Queued sessions hear why before the closing below turns their wait into\n // the more ordinary \"your session closed\".\n for (const waiter of this.waiters.splice(0)) {\n waiter.reject(new Error(\"Piece worker pool is disposed\"));\n }\n for (const session of [...this.sessions]) session.close();\n this.sessions.clear();\n }\n\n /** @internal — a session taking its slot. */\n acquire(session: PieceWorkerSession): Promise<void> {\n if (this.disposed) {\n return Promise.reject(new Error(\"Piece worker pool is disposed\"));\n }\n if (this.inUse < this.size) {\n this.inUse++;\n return Promise.resolve();\n }\n if (this.maxQueueDepth > 0 && this.waiters.length >= this.maxQueueDepth) {\n return Promise.reject(\n new PieceWorkerPoolBusyError(this.size, this.waiters.length),\n );\n }\n return new Promise<void>((resolve, reject) => {\n this.waiters.push({ session, resolve, reject });\n });\n }\n\n /** @internal — a session that closed while queueing. */\n cancel(session: PieceWorkerSession): void {\n const index = this.waiters.findIndex((w) => w.session === session);\n if (index < 0) return;\n const [waiter] = this.waiters.splice(index, 1);\n waiter.reject(new PieceWorkerSessionClosedError());\n }\n\n /** @internal — a session giving its slot back. */\n release(): void {\n const next = this.waiters.shift();\n // Handed straight on rather than counted down and up again, so a slot\n // freed with someone waiting cannot be taken by a later arrival.\n if (next) {\n next.resolve();\n return;\n }\n this.inUse = Math.max(0, this.inUse - 1);\n }\n\n /** @internal — one child for one session. */\n build(): IPieceWorker {\n return this.createWorker(this.workerOptions);\n }\n\n /** @internal — a session that closed itself. */\n forget(session: PieceWorkerSession): void {\n this.sessions.delete(session);\n }\n}\n","// Secret references and the provider/store seams. Refs are server-minted\n// random ids — stable handles over mutable values, never content hashes.\n\nexport const SECRET_REF_PREFIX = \"secret://v1:\";\n\nconst SECRET_ID_PATTERN = /^[0-9a-f]{32}$/;\n\n// Read seam consumed by the engine (connection resolution).\nexport interface SecretProvider {\n get(ref: string): Promise<string>;\n}\n\nexport interface SecretStat {\n ref: string;\n label: string | null;\n version: number;\n status: \"ACTIVE\" | \"DELETED\";\n createdAt: string;\n updatedAt: string;\n}\n\n// Full lifecycle, implemented by managed backends. `get` is execution-context\n// only and must never be exposed over a transport.\nexport interface SecretStore extends SecretProvider {\n create(input: { value: string; label?: string }): Promise<SecretStat>;\n rotate(ref: string, value: string): Promise<SecretStat>;\n stat(ref: string): Promise<SecretStat>;\n list(): Promise<SecretStat[]>;\n delete(ref: string): Promise<void>;\n}\n\nexport class SecretNotFoundError extends Error {\n constructor(ref: string) {\n super(`No secret found for ref \"${ref}\"`);\n this.name = \"SecretNotFoundError\";\n }\n}\n\nexport class SecretDeletedError extends Error {\n constructor(ref: string) {\n super(`Secret \"${ref}\" has been deleted`);\n this.name = \"SecretDeletedError\";\n }\n}\n\nexport class InvalidSecretRefError extends Error {\n constructor(ref: string) {\n super(\n `Invalid secret ref \"${ref}\"; expected ${SECRET_REF_PREFIX}<32 hex chars>`,\n );\n this.name = \"InvalidSecretRefError\";\n }\n}\n\nexport function isSecretRef(ref: string): boolean {\n return (\n ref.startsWith(SECRET_REF_PREFIX) &&\n SECRET_ID_PATTERN.test(ref.slice(SECRET_REF_PREFIX.length))\n );\n}\n\n// Returns the 32-hex id; throws on anything else.\nexport function parseSecretRef(ref: string): string {\n if (!isSecretRef(ref)) throw new InvalidSecretRefError(ref);\n return ref.slice(SECRET_REF_PREFIX.length);\n}\n\nexport function secretRefFromId(id: string): string {\n if (!SECRET_ID_PATTERN.test(id)) throw new InvalidSecretRefError(id);\n return `${SECRET_REF_PREFIX}${id}`;\n}\n\nexport class InMemorySecretProvider implements SecretProvider {\n private readonly secrets: Map<string, string>;\n\n constructor(secrets: Record<string, string>) {\n this.secrets = new Map(Object.entries(secrets));\n }\n\n get(ref: string): Promise<string> {\n const value = this.secrets.get(ref);\n if (value === undefined)\n return Promise.reject(new SecretNotFoundError(ref));\n return Promise.resolve(value);\n }\n}\n","// Minimal {{path}} expression resolution over the run scope (doc 08 §4.6).\n// A whole-string expression yields the raw value; embedded ones interpolate.\n\nexport interface ExpressionScope {\n trigger?: unknown;\n steps: Record<string, { output: unknown }>;\n variables: Record<string, unknown>;\n}\n\nconst WHOLE_EXPRESSION = /^\\{\\{\\s*([^{}]+?)\\s*\\}\\}$/;\nconst EMBEDDED_EXPRESSION = /\\{\\{\\s*([^{}]+?)\\s*\\}\\}/g;\n\nexport function lookupPath(scope: ExpressionScope, path: string): unknown {\n let current: unknown = scope;\n for (const segment of path.split(\".\")) {\n if (current === null || typeof current !== \"object\") return undefined;\n current = (current as Record<string, unknown>)[segment];\n }\n return current;\n}\n\nconst STRING_LITERAL = /^(['\"])(.*)\\1$/;\n\n// \"a.b || c.d || 'default'\": first term that isn't undefined/null/\"\" wins.\nexport function resolveExpression(\n scope: ExpressionScope,\n expression: string,\n): unknown {\n for (const term of expression.split(\"||\")) {\n const trimmed = term.trim();\n if (!trimmed) continue;\n const literal = STRING_LITERAL.exec(trimmed);\n const value = literal ? literal[2] : lookupPath(scope, trimmed);\n if (value !== undefined && value !== null && value !== \"\") return value;\n }\n return undefined;\n}\n\nfunction interpolate(value: unknown): string {\n if (value === undefined || value === null) return \"\";\n if (typeof value === \"object\") return JSON.stringify(value);\n return String(value as string | number | boolean);\n}\n\nexport function resolveExpressions(\n value: unknown,\n scope: ExpressionScope,\n): unknown {\n if (typeof value === \"string\") {\n const whole = WHOLE_EXPRESSION.exec(value);\n if (whole) return resolveExpression(scope, whole[1]);\n return value.replaceAll(EMBEDDED_EXPRESSION, (_, path: string) =>\n interpolate(resolveExpression(scope, path)),\n );\n }\n if (Array.isArray(value)) {\n return value.map((item) => resolveExpressions(item, scope));\n }\n if (value !== null && typeof value === \"object\") {\n return Object.fromEntries(\n Object.entries(value as Record<string, unknown>).map(([key, entry]) => [\n key,\n resolveExpressions(entry, scope),\n ]),\n );\n }\n return value;\n}\n\n// Truthiness of a resolved condition; the strings \"false\" and \"0\" are falsy.\nexport function evaluateCondition(\n condition: string,\n scope: ExpressionScope,\n): boolean {\n const resolved = resolveExpressions(condition, scope);\n if (resolved === \"false\" || resolved === \"0\") return false;\n return Boolean(resolved);\n}\n","// Resolves connection references into the auth value a piece reads from\n// ctx.auth, shaped per Activepieces auth kind (powerhouse/connection state).\n\nimport type { SecretProvider } from \"./secrets.js\";\nimport type { WorkflowDefinition } from \"./types.js\";\nimport {\n AppConnectionType,\n type AppConnectionValue,\n type BasicAuthConnectionValue,\n} from \"@powerhousedao/pieces-framework\";\n\n// The powerhouse/connection document model's own enum: the framework's\n// AppConnectionType, minus its OAuth2 variants, with NO_AUTH persisted as NONE.\nexport type ConnectionAuthType =\n | `${AppConnectionType.SECRET_TEXT}`\n | `${AppConnectionType.BASIC_AUTH}`\n | `${AppConnectionType.CUSTOM_AUTH}`\n | `${AppConnectionType.OAUTH2}`\n | `${AppConnectionType.OIDC}`\n | \"NONE\";\n\n// Mirrors the powerhouse/connection document state the resolver consumes.\nexport interface ConnectionSource {\n authType: ConnectionAuthType;\n config?: Record<string, unknown>;\n secretRefs?: { name: string; ref: string }[];\n}\n\n// Which step is asking. A resolver needs it to check the request against the\n// run's binding rather than trust the id it was handed.\n\n// piecePackage is the package the caller already resolved the block type to,\n// so a resolver never re-parses a block type to learn which piece is asking.\nexport interface ConnectionRequest {\n blockType: string;\n piecePackage?: string;\n stepId?: string;\n stepKey?: string;\n}\n\n// The auth a piece reads, plus the concrete secret strings behind it. The\n// second half is what value-based journal redaction matches on.\nexport interface ResolvedConnection {\n auth: unknown;\n secretValues: string[];\n}\n\nexport interface EngineConnectionResolver {\n resolve(connectionId: string, request?: ConnectionRequest): Promise<unknown>;\n // Optional: hosts that predate redaction keep working without it. It takes\n // the same request, so authorization is not skipped to get the secrets.\n resolveWithSecrets?(\n connectionId: string,\n request?: ConnectionRequest,\n ): Promise<ResolvedConnection>;\n}\n\nexport class ConnectionNotFoundError extends Error {\n constructor(connectionId: string) {\n super(`No connection registered for id \"${connectionId}\"`);\n this.name = \"ConnectionNotFoundError\";\n }\n}\n\n// A step reached for a connection its workflow definition never declared.\n// Raised before any lookup, so it cannot say whether the id exists.\nexport class ConnectionNotBoundError extends Error {\n constructor(connectionId: string) {\n super(`Connection \"${connectionId}\" is not bound to this workflow`);\n this.name = \"ConnectionNotBoundError\";\n }\n}\n\nexport class UnsupportedAuthTypeError extends Error {\n constructor(authType: string) {\n super(`Auth type \"${authType}\" is not supported yet`);\n this.name = \"UnsupportedAuthTypeError\";\n }\n}\n\nasync function resolveSecrets(\n source: ConnectionSource,\n secrets: SecretProvider,\n): Promise<Record<string, string>> {\n const entries = await Promise.all(\n (source.secretRefs ?? []).map(\n async ({ name, ref }) => [name, await secrets.get(ref)] as const,\n ),\n );\n return Object.fromEntries(entries);\n}\n\n// Values are AppConnectionValue-shaped: pieces read auth.secret_text,\n// auth.username/password or auth.props.* depending on their auth kind.\nexport async function shapeAuthValue(\n source: ConnectionSource,\n secrets: SecretProvider,\n): Promise<unknown> {\n return (await shapeConnection(source, secrets)).auth;\n}\n\n// Only the values behind `secretRefs` are reported as secret: config fields\n// (a base URL, a username) are not, and redacting them would cost debuggability.\nexport async function shapeConnection(\n source: ConnectionSource,\n secrets: SecretProvider,\n): Promise<ResolvedConnection> {\n const resolved = await resolveSecrets(source, secrets);\n return {\n auth: shapeAuth(source, resolved),\n secretValues: Object.values(resolved),\n };\n}\n\n// NONE is the persisted value; the framework's NO_AUTH case carries no value a\n// piece reads, so ctx.auth stays undefined rather than becoming that shape.\nfunction shapeAuth(\n source: ConnectionSource,\n resolved: Record<string, string>,\n): AppConnectionValue | undefined {\n switch (source.authType) {\n case \"NONE\":\n return undefined;\n case \"SECRET_TEXT\": {\n const values = Object.values(resolved);\n if (values.length !== 1) {\n throw new Error(\n `SECRET_TEXT connection must have exactly one secret ref, got ${values.length}`,\n );\n }\n return { type: AppConnectionType.SECRET_TEXT, secret_text: values[0] };\n }\n case \"BASIC_AUTH\": {\n const props = { ...source.config, ...resolved };\n return {\n type: AppConnectionType.BASIC_AUTH,\n username: props.username,\n password: props.password,\n } as BasicAuthConnectionValue;\n }\n case \"CUSTOM_AUTH\": {\n return {\n type: AppConnectionType.CUSTOM_AUTH,\n props: { ...source.config, ...resolved },\n };\n }\n default:\n throw new UnsupportedAuthTypeError(source.authType);\n }\n}\n\nexport class StaticConnectionResolver implements EngineConnectionResolver {\n private readonly connections: Map<string, ConnectionSource>;\n\n constructor(\n connections: Record<string, ConnectionSource>,\n private readonly secrets: SecretProvider,\n ) {\n this.connections = new Map(Object.entries(connections));\n }\n\n resolve(connectionId: string): Promise<unknown> {\n return this.resolveWithSecrets(connectionId).then(\n (resolved) => resolved.auth,\n );\n }\n\n resolveWithSecrets(connectionId: string): Promise<ResolvedConnection> {\n const source = this.connections.get(connectionId);\n if (!source) {\n return Promise.reject(new ConnectionNotFoundError(connectionId));\n }\n return shapeConnection(source, this.secrets);\n }\n}\n\n// Every connection a definition declares: the trigger's and each step's.\n\n// A templated id is left out — connectionId is never expression-resolved, so\n// it names no connection and a step cannot pick credentials at run time.\nexport function declaredConnectionIds(\n definition: WorkflowDefinition,\n): ReadonlySet<string> {\n const declared = new Set<string>();\n const declare = (connectionId: string | null | undefined) => {\n if (connectionId && !connectionId.includes(\"{{\"))\n declared.add(connectionId);\n };\n declare(definition.trigger?.connectionId);\n for (const step of definition.steps) declare(step.connectionId);\n return declared;\n}\n\n// The binding in force for the caller, or undefined when there is none. Read\n// per call because one executor serves every concurrent run.\nexport type ConnectionBindingLookup = () => ReadonlySet<string> | undefined;\n\n// Server-side connection binding (doc 08 §10): a step resolves only what the\n// definition its run pinned declared.\n\n// Without a binding nothing resolves, so a path that fails to establish one\n// fails closed.\nexport class BoundConnectionResolver implements EngineConnectionResolver {\n // Present only when the inner resolver has it, because its absence is what\n // tells a caller to fall back to guessing the secrets from the auth value.\n readonly resolveWithSecrets?: (\n connectionId: string,\n request?: ConnectionRequest,\n ) => Promise<ResolvedConnection>;\n\n constructor(\n private readonly inner: EngineConnectionResolver,\n private readonly binding: ConnectionBindingLookup,\n private readonly onRefused?: (\n connectionId: string,\n request?: ConnectionRequest,\n ) => void,\n ) {\n const withSecrets = inner.resolveWithSecrets?.bind(inner);\n if (!withSecrets) return;\n this.resolveWithSecrets = (connectionId, request) =>\n this.bound(connectionId, request)\n ? withSecrets(connectionId, request)\n : Promise.reject(new ConnectionNotBoundError(connectionId));\n }\n\n resolve(connectionId: string, request?: ConnectionRequest): Promise<unknown> {\n if (!this.bound(connectionId, request)) {\n return Promise.reject(new ConnectionNotBoundError(connectionId));\n }\n return this.inner.resolve(connectionId, request);\n }\n\n // Both paths ask the same question, so neither is a way around it.\n private bound(connectionId: string, request?: ConnectionRequest): boolean {\n if (this.binding()?.has(connectionId)) return true;\n this.onRefused?.(connectionId, request);\n return false;\n }\n}\n","import { randomUUID } from \"node:crypto\";\nimport { mkdir, rm } from \"node:fs/promises\";\nimport path from \"node:path\";\nimport {\n bundleResolver,\n pieceModuleRef,\n type PieceResolver,\n} from \"../activepieces/resolver.js\";\nimport type { ReactorService } from \"../activepieces/context/reactor.js\";\nimport {\n rewriteFileRefs,\n type StagedFile,\n} from \"../activepieces/context/files.js\";\nimport { PieceWorker, type IPieceWorker } from \"../activepieces/worker/host.js\";\nimport { DEFAULT_EGRESS_POLICY } from \"../activepieces/worker/egress.js\";\nimport {\n LOG_WRITE,\n OUTPUT_UPDATE,\n REACTOR_CREATE,\n REACTOR_EXECUTE,\n REACTOR_FIND,\n REACTOR_GET,\n REACTOR_MODEL,\n REACTOR_MODELS,\n STORE_DELETE,\n STORE_GET,\n STORE_PUT,\n type EgressPolicy,\n type HostCallHandlers,\n type HostNotifyHandlers,\n type PieceLogEntry,\n type StagedInput,\n} from \"../activepieces/worker/protocol.js\";\nimport type { StoreScopeName } from \"../activepieces/context/store-scope.js\";\nimport {\n collectSecretValues,\n redactError,\n redactMessage,\n rememberSecrets,\n} from \"../activepieces/worker/redact.js\";\nimport type {\n ConnectionRequest,\n EngineConnectionResolver,\n ResolvedConnection,\n} from \"./connections.js\";\nimport type { BlockExecution, BlockExecutor, BlockResult } from \"./types.js\";\n\nexport class UnknownBlockTypeError extends Error {\n constructor(blockType: string) {\n super(`No executor registered for block type \"${blockType}\"`);\n this.name = \"UnknownBlockTypeError\";\n }\n}\n\nexport class TriggerBlockAsStepError extends Error {\n constructor(blockType: string) {\n super(`Trigger block type \"${blockType}\" cannot run as a workflow step`);\n this.name = \"TriggerBlockAsStepError\";\n }\n}\n\n// Core blocks. core#branch routes on its (already resolved) condition: equal\n// to `equals` when that is set, otherwise truthiness. core#assert fails the\n// run on blank or rejected values.\nexport class CoreBlockExecutor implements BlockExecutor {\n static handles(blockType: string): boolean {\n return blockType.startsWith(\"core#\");\n }\n\n execute(execution: BlockExecution): Promise<BlockResult> {\n if (execution.blockType === \"core#branch\") {\n const { condition, equals } = execution.config as {\n condition?: unknown;\n equals?: unknown;\n };\n // Trimmed and case-insensitive: the condition is often model output.\n const normalize = (value: unknown) =>\n (typeof value === \"string\"\n ? value\n : value === undefined || value === null\n ? \"\"\n : JSON.stringify(value)\n )\n .trim()\n .toLowerCase();\n const taken =\n typeof equals === \"string\"\n ? normalize(condition) === normalize(equals)\n : Boolean(condition) && condition !== \"false\" && condition !== \"0\";\n return Promise.resolve({\n output: { condition: condition ?? null },\n port: taken ? \"true\" : \"false\",\n });\n }\n if (execution.blockType === \"core#assert\") {\n return this.assert(execution);\n }\n return Promise.reject(new UnknownBlockTypeError(execution.blockType));\n }\n\n // core#assert fails the step when its value is blank or is one of the\n // rejected values. Model output is the motivating case: an empty\n // completion, or a classifier answering the wrong question, must not flow\n // on to a step with a side effect.\n private assert(execution: BlockExecution): Promise<BlockResult> {\n const { value, rejectValues, allowValues, allowEmpty, message } =\n execution.config as {\n value?: unknown;\n rejectValues?: unknown;\n allowValues?: unknown;\n allowEmpty?: unknown;\n message?: unknown;\n };\n const text =\n typeof value === \"string\"\n ? value\n : value === undefined || value === null\n ? \"\"\n : JSON.stringify(value);\n const trimmed = text.trim();\n const fail = (reason: string) =>\n Promise.reject(\n new Error(\n typeof message === \"string\" && message\n ? message\n : `core#assert: ${reason}`,\n ),\n );\n\n if (!trimmed && allowEmpty !== true) {\n return fail(\"value is empty\");\n }\n const normalizeList = (entries: unknown) =>\n (typeof entries === \"string\"\n ? [entries]\n : Array.isArray(entries)\n ? entries\n : []\n )\n .map((entry) => String(entry).trim().toLowerCase())\n .filter(Boolean);\n\n if (normalizeList(rejectValues).includes(trimmed.toLowerCase())) {\n return fail(`value is a rejected value (\"${trimmed}\")`);\n }\n // An allow-list is the safer gate for model output: anything unforeseen\n // fails here rather than reaching a step that writes.\n const allowed = normalizeList(allowValues);\n if (allowed.length > 0 && !allowed.includes(trimmed.toLowerCase())) {\n return fail(\n `value \"${trimmed}\" is not one of the allowed values (${allowed.join(\", \")})`,\n );\n }\n return Promise.resolve({ output: { value }, port: \"next\" });\n }\n}\n\n// The host's attachment store, as the engine needs it: materialize a\n// reference to a path the worker can read, and ingest a path the worker wrote.\n// Both directions go through the filesystem, so bytes never enter IPC.\nexport interface AttachmentPort {\n read(\n ref: string,\n destPath: string,\n ): Promise<{ fileName?: string; contentType?: string }>;\n write(file: {\n path: string;\n fileName: string;\n size: number;\n contentType?: string;\n }): Promise<string>;\n}\n\nconst ATTACHMENT_REF = /^attachment:\\/\\//i;\n\n// Collects every attachment reference appearing as a string in a step config.\n// Deliberately type-agnostic: the worker decides which of them to hydrate\n// (only FILE props go through toApFile), so staging a reference no one reads\n// costs one file, while missing one would fail the step.\nfunction collectRefs(value: unknown, found: Set<string>): void {\n if (typeof value === \"string\") {\n if (ATTACHMENT_REF.test(value)) found.add(value);\n return;\n }\n if (Array.isArray(value)) {\n for (const entry of value) collectRefs(entry, found);\n return;\n }\n if (typeof value === \"object\" && value !== null) {\n for (const entry of Object.values(value)) collectRefs(entry, found);\n }\n}\n\n// The durable `ctx.store`, as the engine needs it: one call per operation, so\n// a piece that checkpoints mid-loop keeps what it wrote if the step then dies.\n\n// Which scope a step's keys belong to is the host's business; the executor is\n// shared across runs and must not decide it.\nexport interface PieceStorePort {\n get(key: string, scope: StoreScopeName): Promise<unknown>;\n put(key: string, value: unknown, scope: StoreScopeName): Promise<void>;\n delete(key: string, scope: StoreScopeName): Promise<void>;\n}\n\n// One key operation as it arrives from the worker.\ninterface StoreCallPayload {\n key?: unknown;\n value?: unknown;\n scope?: unknown;\n}\n\n// An unrecognised scope is treated as FLOW, the narrower partition: a bad\n// name must never widen what a step can reach.\nfunction storeScopeOf(payload: unknown): StoreScopeName {\n const scope = (payload as StoreCallPayload | undefined)?.scope;\n return scope === \"PROJECT\" ? \"PROJECT\" : \"FLOW\";\n}\n\nfunction storeKeyOf(payload: unknown): string {\n const key = (payload as StoreCallPayload | undefined)?.key;\n if (typeof key !== \"string\" || key === \"\") {\n throw new Error(\"Store call carried no key\");\n }\n return key;\n}\n\n// The host's half of `ctx.reactor`: the same operations the piece calls, run\n// against the reactor this host serves. See activepieces/context/reactor.ts.\n\n// Registered per step and only for a piece the host resolved locally, so a\n// fetched bundle forging these calls finds no handler and is refused.\nexport type ReactorPort = ReactorService;\n\n// Payloads arrive from the child, which runs piece code: a call is checked\n// here rather than trusted to have come from our own proxy.\nfunction reactorInput(payload: unknown): Record<string, unknown> {\n if (\n typeof payload !== \"object\" ||\n payload === null ||\n Array.isArray(payload)\n ) {\n throw new Error(\"Reactor call carried no input object\");\n }\n return payload as Record<string, unknown>;\n}\n\nfunction requiredString(\n payload: Record<string, unknown>,\n field: string,\n): string {\n const value = payload[field];\n if (typeof value !== \"string\" || value === \"\") {\n throw new Error(`Reactor call carried no \"${field}\"`);\n }\n return value;\n}\n\nfunction optionalString(\n payload: Record<string, unknown>,\n field: string,\n): string | undefined {\n const value = payload[field];\n return typeof value === \"string\" && value !== \"\" ? value : undefined;\n}\n\nfunction reactorActions(payload: Record<string, unknown>) {\n const actions = payload.actions;\n if (!Array.isArray(actions) || actions.length === 0) {\n throw new Error(\"Reactor call carried no actions\");\n }\n return actions.map((entry, index) => {\n const action = entry as Record<string, unknown> | null;\n if (!action || typeof action.type !== \"string\") {\n throw new Error(`Reactor call: actions[${index}] needs a string \"type\"`);\n }\n return {\n type: action.type,\n input: action.input,\n ...(typeof action.scope === \"string\" ? { scope: action.scope } : {}),\n };\n });\n}\n\n// A page size the host will serve. The value arrives from piece code, so it\n// is clamped here rather than trusted; a host may cap it further.\nconst MAX_FIND_LIMIT = 100;\n\nfunction findLimit(value: unknown): number | undefined {\n if (typeof value !== \"number\" || !Number.isFinite(value)) return undefined;\n return Math.min(Math.max(Math.floor(value), 1), MAX_FIND_LIMIT);\n}\n\n// The state match, as the host will accept it. Both halves must be strings and\n// the path must name something: a match with an empty path would silently pass\n// every document, which is the opposite of what a step asking to match wants.\nfunction findMatch(\n value: unknown,\n): { path: string; value: string } | undefined {\n if (typeof value !== \"object\" || value === null) return undefined;\n const record = value as Record<string, unknown>;\n const path = record.path;\n const wanted = record.value;\n if (typeof path !== \"string\" || path.trim() === \"\") return undefined;\n if (typeof wanted !== \"string\") return undefined;\n return { path: path.trim(), value: wanted };\n}\n\nexport function reactorHandlers(port: ReactorPort): HostCallHandlers {\n return {\n [REACTOR_MODELS]: () => port.models(),\n [REACTOR_MODEL]: (payload) =>\n port.model(requiredString(reactorInput(payload), \"documentType\")),\n [REACTOR_GET]: (payload) => {\n const input = reactorInput(payload);\n return port.get({\n documentId: requiredString(input, \"documentId\"),\n ...(optionalString(input, \"branch\")\n ? { branch: optionalString(input, \"branch\") }\n : {}),\n });\n },\n [REACTOR_FIND]: (payload) => {\n const input = reactorInput(payload);\n return port.find({\n ...(optionalString(input, \"documentType\")\n ? { documentType: optionalString(input, \"documentType\") }\n : {}),\n ...(optionalString(input, \"parentId\")\n ? { parentId: optionalString(input, \"parentId\") }\n : {}),\n ...(findLimit(input.limit) !== undefined\n ? { limit: findLimit(input.limit) }\n : {}),\n ...(findMatch(input.match) ? { match: findMatch(input.match) } : {}),\n ...(input.withState === true ? { withState: true } : {}),\n });\n },\n [REACTOR_CREATE]: (payload) => {\n const input = reactorInput(payload);\n return port.create({\n documentType: requiredString(input, \"documentType\"),\n ...(optionalString(input, \"name\")\n ? { name: optionalString(input, \"name\") }\n : {}),\n ...(optionalString(input, \"parentId\")\n ? { parentId: optionalString(input, \"parentId\") }\n : {}),\n });\n },\n [REACTOR_EXECUTE]: (payload) => {\n const input = reactorInput(payload);\n return port.execute({\n documentId: requiredString(input, \"documentId\"),\n ...(optionalString(input, \"branch\")\n ? { branch: optionalString(input, \"branch\") }\n : {}),\n actions: reactorActions(input),\n });\n },\n };\n}\n\n// The handlers served to a running step or trigger hook. A rejection becomes\n// the error the piece sees, which is what an over-limit write should do.\nexport function storeHandlers(port: PieceStorePort): HostCallHandlers {\n return {\n [STORE_GET]: (payload) =>\n port.get(storeKeyOf(payload), storeScopeOf(payload)),\n [STORE_PUT]: async (payload) => {\n await port.put(\n storeKeyOf(payload),\n (payload as StoreCallPayload).value,\n storeScopeOf(payload),\n );\n return null;\n },\n [STORE_DELETE]: async (payload) => {\n await port.delete(storeKeyOf(payload), storeScopeOf(payload));\n return null;\n },\n };\n}\n\nexport interface ActivepiecesBlockExecutorOptions {\n cacheDir: string;\n // Piece package name -> pinned version; the connector registry for this run.\n // A blockType may instead pin inline: \"@scope/pkg@1.2.3#action\".\n\n // A function is awaited per step, so a host whose registry loads lazily —\n // package pieces are pinned by what is installed, not by the block type —\n // answers with what it has by the time a step actually runs.\n packages?:\n | Record<string, string>\n | (() => Record<string, string> | Promise<Record<string, string>>);\n connections?: EngineConnectionResolver;\n // The worker piece steps go to. A function is asked once per step, so a\n // host handing each run its own child answers with that run's.\n worker?: IPieceWorker | (() => IPieceWorker | undefined);\n defaultTimeoutMs?: number;\n // Both are needed for ctx.files to work: a directory the host and the forked\n // worker share, and somewhere to put what the piece wrote. Without them a\n // piece calling ctx.files falls back to inline data URIs.\n stagingRoot?: string;\n attachments?: AttachmentPort;\n // Without it `ctx.store` falls back to the worker's heap, which a step\n // timeout discards.\n pieceStore?: PieceStorePort;\n // Where a block type's piece comes from. Defaults to fetching the pinned\n // version into `cacheDir`, which is what a published piece needs.\n resolver?: PieceResolver;\n // Serves `ctx.reactor`, and only to a piece the resolver answered locally.\n // Without it even a package piece finds the member throwing.\n reactor?: ReactorPort;\n // Where a step's piece may connect to. Left unset it is the default policy,\n // which refuses private address space; `null` runs the piece unrestricted.\n egress?: EgressPolicy | null;\n // Taps on a running step. Each is opt-in because it costs the worker an IPC\n // message per event, and neither is asked for unless someone reads it.\n onPieceLog?: (entry: PieceLogEntry, execution: BlockExecution) => void;\n onPartialOutput?: (output: unknown, execution: BlockExecution) => void;\n}\n\n// The notify handlers served to one step. Unlike a store call, nothing here\n// answers the piece: these are reports, and the step never waits on them.\nfunction stepTaps(\n options: ActivepiecesBlockExecutorOptions,\n execution: BlockExecution,\n values: string[],\n): HostNotifyHandlers | undefined {\n const { onPieceLog, onPartialOutput } = options;\n if (!onPieceLog && !onPartialOutput) return undefined;\n const handlers: HostNotifyHandlers = {};\n if (onPieceLog) {\n // A piece logging its own outgoing request is a common idiom, so this is\n // one of the likeliest places for a credential to reach the host log.\n handlers[LOG_WRITE] = (payload) => {\n const entry = payload as PieceLogEntry;\n // Returned, not discarded: a sink that rejects is the host's to catch.\n return onPieceLog(\n { ...entry, message: redactMessage(entry.message, { values }) },\n execution,\n );\n };\n }\n if (onPartialOutput) {\n handlers[OUTPUT_UPDATE] = (payload) => onPartialOutput(payload, execution);\n }\n return handlers;\n}\n\n// Mutated in place rather than rewrapped: callers classify on the error's\n// class, and a new one would lose that.\n\n// `stack` embeds the message as it was at construction, so a caller logging\n// the error object rather than `.message` would otherwise still print it.\nfunction redactThrown(error: unknown, values: string[]): unknown {\n if (error instanceof Error) {\n error.message = redactMessage(error.message, { values });\n if (error.stack) error.stack = redactMessage(error.stack, { values });\n return rememberSecrets(error, values);\n }\n return rememberSecrets(redactError(error, { values }), values);\n}\n\nexport type BlockKind = \"action\" | \"trigger\";\n\nexport interface ParsedBlockType {\n packageName: string;\n version: string;\n kind: BlockKind;\n // Action or trigger name within the piece.\n name: string;\n}\n\nconst TRIGGER_FRAGMENT = \"trigger:\";\n\n// \"<pkg>[@<version>]#<action>\" or \"<pkg>[@<version>]#trigger:<trigger>\" —\n// the version after the scope-less \"@\" wins over the registry.\nexport function parseBlockType(\n blockType: string,\n packages: Record<string, string> = {},\n): ParsedBlockType | undefined {\n const separator = blockType.lastIndexOf(\"#\");\n if (separator <= 0) return undefined;\n const packageSpec = blockType.slice(0, separator);\n const fragment = blockType.slice(separator + 1);\n const isTrigger = fragment.startsWith(TRIGGER_FRAGMENT);\n const name = isTrigger ? fragment.slice(TRIGGER_FRAGMENT.length) : fragment;\n if (!name) return undefined;\n const kind: BlockKind = isTrigger ? \"trigger\" : \"action\";\n const versionAt = packageSpec.indexOf(\"@\", 1);\n if (versionAt > 0) {\n return {\n packageName: packageSpec.slice(0, versionAt),\n version: packageSpec.slice(versionAt + 1),\n kind,\n name,\n };\n }\n const version = packages[packageSpec] as string | undefined;\n if (!version) return undefined;\n return { packageName: packageSpec, version, kind, name };\n}\n\n// Executes \"<packageName>#<actionName>\" block types through the piece worker.\nexport class ActivepiecesBlockExecutor implements BlockExecutor {\n // Only set when nothing was supplied: the fallback this executor owns and\n // must dispose. A supplied worker belongs to whoever supplied it.\n private own: PieceWorker | undefined;\n\n private readonly resolver: PieceResolver;\n\n constructor(private readonly options: ActivepiecesBlockExecutorOptions) {\n this.resolver =\n options.resolver ?? bundleResolver({ cacheDir: options.cacheDir });\n }\n\n private worker(): IPieceWorker {\n const supplied = this.options.worker;\n if (typeof supplied === \"function\") {\n const worker = supplied();\n if (worker) return worker;\n } else if (supplied) {\n return supplied;\n }\n return (this.own ??= new PieceWorker());\n }\n\n private packages(): Promise<Record<string, string>> {\n const supplied = this.options.packages;\n return Promise.resolve(\n typeof supplied === \"function\" ? supplied() : (supplied ?? {}),\n );\n }\n\n async execute(execution: BlockExecution): Promise<BlockResult> {\n const parsed = parseBlockType(execution.blockType, await this.packages());\n if (!parsed) {\n throw new UnknownBlockTypeError(execution.blockType);\n }\n if (parsed.kind !== \"action\") {\n throw new TriggerBlockAsStepError(execution.blockType);\n }\n\n // One staging directory per execution, removed in the finally below. A\n // host crash can still leave one behind, which is why it lives under a\n // root the host can sweep at startup.\n const stagingDir = this.options.stagingRoot\n ? path.join(this.options.stagingRoot, randomUUID())\n : undefined;\n\n // Bundle fetch and connection resolution belong inside the catch: a secret\n // provider or a resolver can fail with the credential in its own message.\n let redactValues: string[] = [];\n try {\n const piece = await this.resolver.resolve(\n parsed.packageName,\n parsed.version,\n );\n const connection = await this.resolveConnection(execution.connectionId, {\n blockType: execution.blockType,\n piecePackage: parsed.packageName,\n stepId: execution.step.id,\n stepKey: execution.step.key,\n });\n const auth = connection?.auth;\n redactValues = connection?.secretValues ?? [];\n\n const timeoutMs = execution.step.timeoutSeconds\n ? execution.step.timeoutSeconds * 1000\n : this.options.defaultTimeoutMs;\n const stagedInputs = await this.stageInputs(execution.config, stagingDir);\n const pieceStore = this.options.pieceStore;\n const notifications = stepTaps(this.options, execution, redactValues);\n const egress =\n this.options.egress === undefined\n ? DEFAULT_EGRESS_POLICY\n : this.options.egress;\n // A fetched bundle never reaches the reactor: the handlers below are the\n // only way in, and they are registered for a local piece alone.\n const reactor = piece.local ? this.options.reactor : undefined;\n const result = await this.worker().runAction(\n {\n ...pieceModuleRef(piece),\n actionName: parsed.name,\n propsValue: execution.config as Record<string, unknown>,\n auth,\n ...(redactValues.length > 0 ? { redactValues } : {}),\n ...(stagingDir ? { stagingDir } : {}),\n ...(stagedInputs ? { stagedInputs } : {}),\n ...(pieceStore ? { durableStore: true } : {}),\n ...(reactor ? { reactorAccess: true } : {}),\n ...(this.options.onPieceLog ? { captureLogs: true } : {}),\n ...(this.options.onPartialOutput ? { liveOutput: true } : {}),\n ...(egress ? { egress } : {}),\n },\n {\n ...(timeoutMs ? { timeoutMs } : {}),\n ...(pieceStore || reactor\n ? {\n hostCalls: {\n ...(pieceStore ? storeHandlers(pieceStore) : {}),\n ...(reactor ? reactorHandlers(reactor) : {}),\n },\n }\n : {}),\n ...(notifications ? { notifications } : {}),\n },\n );\n return {\n output: await this.ingestFiles(result.output, result.files),\n redactValues,\n };\n } catch (error) {\n // The child already stripped what it threw; this covers what the host\n // itself raises (bundle fetch, connection resolution, file ingest).\n throw redactThrown(error, redactValues);\n } finally {\n if (stagingDir) await rm(stagingDir, { recursive: true, force: true });\n }\n }\n\n private async resolveConnection(\n connectionId: string | null | undefined,\n request: ConnectionRequest,\n ): Promise<ResolvedConnection | undefined> {\n const connections = this.options.connections;\n if (!connectionId || !connections) return undefined;\n // The request travels with both, so taking the secret-bearing path never\n // means skipping the check on who is asking.\n if (connections.resolveWithSecrets) {\n return connections.resolveWithSecrets(connectionId, request);\n }\n const auth = await connections.resolve(connectionId, request);\n return { auth, secretValues: [...collectSecretValues(auth)] };\n }\n\n private async stageInputs(\n config: unknown,\n stagingDir: string | undefined,\n ): Promise<StagedInput[] | undefined> {\n const port = this.options.attachments;\n if (!stagingDir || !port) return undefined;\n const refs = new Set<string>();\n collectRefs(config, refs);\n if (refs.size === 0) return undefined;\n await mkdir(stagingDir, { recursive: true });\n const staged: StagedInput[] = [];\n let index = 0;\n for (const ref of refs) {\n const destPath = path.join(stagingDir, `in-${index++}`);\n const meta = await port.read(ref, destPath);\n staged.push({ ref, path: destPath, ...meta });\n }\n return staged;\n }\n\n // A provisional apfile:// token only becomes a real reference once the step\n // has returned, so a piece that writes a file and then reads it back by URL\n // within the same run would not work. No action needs that today; the fix is\n // a bidirectional worker channel, which is its own design.\n private async ingestFiles(\n output: unknown,\n files: StagedFile[] | undefined,\n ): Promise<unknown> {\n if (!files || files.length === 0) return output;\n const port = this.options.attachments;\n if (!port) {\n throw new Error(\n `The action wrote ${files.length} file(s) through ctx.files, but no attachment store is configured for this reactor`,\n );\n }\n const refs = new Map<string, string>();\n for (const file of files) {\n refs.set(\n file.token,\n await port.write({\n path: file.path,\n fileName: file.fileName,\n size: file.size,\n contentType: file.contentType,\n }),\n );\n }\n return rewriteFileRefs(output, refs);\n }\n\n dispose(): void {\n this.own?.dispose();\n this.own = undefined;\n }\n}\n\n// Routes explicit handlers first, then core#*, then the piece executor.\n// Handlers let a host add block types of its own, served in its process.\nexport class CompositeBlockExecutor implements BlockExecutor {\n private readonly core = new CoreBlockExecutor();\n\n constructor(\n private readonly pieces: BlockExecutor,\n private readonly handlers: Record<string, BlockExecutor> = {},\n ) {}\n\n execute(execution: BlockExecution): Promise<BlockResult> {\n const handler = this.handlers[execution.blockType] as\n | BlockExecutor\n | undefined;\n if (handler) return handler.execute(execution);\n if (CoreBlockExecutor.handles(execution.blockType)) {\n return this.core.execute(execution);\n }\n return this.pieces.execute(execution);\n }\n}\n","import {\n containsRedactedMarker,\n redact,\n redactMessage,\n secretsFor,\n} from \"../activepieces/worker/redact.js\";\nimport {\n evaluateCondition,\n resolveExpressions,\n type ExpressionScope,\n} from \"./expressions.js\";\nimport type {\n BlockExecutor,\n StepExecutionRecord,\n WorkflowDefinition,\n WorkflowRunResult,\n WorkflowStepDef,\n} from \"./types.js\";\n\nexport interface RunWorkflowOptions {\n definition: WorkflowDefinition;\n executor: BlockExecutor;\n // Exposed to expressions as {{trigger.payload...}}.\n triggerPayload?: unknown;\n // Journaled outputs from a prior run, keyed by step id; matching steps\n // replay (output injected, port re-taken) instead of executing.\n completedSteps?: Map<string, { output?: unknown; port?: string | null }>;\n // Called as each step reaches a terminal state, so a run that dies\n // mid-flight leaves the steps it finished behind. Ordinal is execution\n // order; skips are excluded, being knowable only once the run completes.\n onStep?: (\n record: StepExecutionRecord,\n ordinal: number,\n ) => void | Promise<void>;\n}\n\nfunction errorMessage(error: unknown): string {\n if (error instanceof Error) return error.message;\n return String(error);\n}\n\n// A record is journal material, read back by the editor and kept in the\n// database, so it never carries the live value a downstream step reads.\nfunction journaled(value: unknown, values: string[] | undefined): unknown {\n return value === undefined ? undefined : redact(value, { values });\n}\n\n// Sequential v1 of the RunCoordinator (doc 08 §7.3): walks the steps+edges\n// graph, resolving each step's config against prior outputs before executing.\nexport async function runWorkflow(\n options: RunWorkflowOptions,\n): Promise<WorkflowRunResult> {\n const { definition, executor } = options;\n const scope: ExpressionScope = {\n trigger: { payload: options.triggerPayload },\n steps: {},\n variables: Object.fromEntries(\n (definition.variables ?? []).map((v) => [v.key, v.value ?? null]),\n ),\n };\n\n const records = new Map<string, StepExecutionRecord>();\n // edgeId -> taken; an edge is decided once its source ran or was skipped.\n const edgeDecisions = new Map<string, boolean>();\n let runFailed: string | undefined;\n let executedCount = 0;\n\n // A failing journal write must not cost us the step's completed work: the\n // run carries on, and finishRun's final sweep repairs the missing row.\n const journal = async (record: StepExecutionRecord) => {\n if (!options.onStep) return;\n const ordinal = executedCount++;\n try {\n await options.onStep(record, ordinal);\n } catch {\n // Durability is the bonus here; run correctness is not at stake.\n }\n };\n\n const decideOutgoing = (sourceId: string, port: string | undefined) => {\n for (const edge of definition.edges) {\n if (edge.from !== sourceId) continue;\n const portMatches = port !== undefined && edge.port === port;\n const taken =\n portMatches &&\n (!edge.condition || evaluateCondition(edge.condition, scope));\n edgeDecisions.set(edge.id, taken);\n }\n };\n\n // Trigger edges fire on the trigger's implicit \"next\" port.\n if (definition.trigger) {\n decideOutgoing(definition.trigger.id, \"next\");\n }\n\n const inboundEdges = (step: WorkflowStepDef) =>\n definition.edges.filter((edge) => edge.to === step.id);\n\n const isEntryStep = (step: WorkflowStepDef) =>\n !definition.trigger && inboundEdges(step).length === 0;\n\n const skipStep = (step: WorkflowStepDef) => {\n records.set(step.id, {\n stepId: step.id,\n key: step.key,\n blockType: step.blockType,\n status: \"SKIPPED\",\n });\n decideOutgoing(step.id, undefined);\n };\n\n // The journal keeps a redacted copy, so a replay would hand the marker to\n // the next step. Refusing is loud; replaying it would be silently wrong.\n const refuseReplay = (step: WorkflowStepDef) => {\n const error =\n `Journaled output of step \"${step.key}\" was redacted and cannot be ` +\n \"replayed; fire the workflow again instead of rerunning it\";\n records.set(step.id, {\n stepId: step.id,\n key: step.key,\n blockType: step.blockType,\n status: \"FAILED\",\n error,\n });\n runFailed = error;\n };\n\n const executeStep = async (step: WorkflowStepDef) => {\n const replay = options.completedSteps?.get(step.id);\n if (replay) {\n if (containsRedactedMarker(replay.output)) {\n refuseReplay(step);\n return;\n }\n const port = replay.port ?? \"next\";\n const record: StepExecutionRecord = {\n stepId: step.id,\n key: step.key,\n blockType: step.blockType,\n status: \"REPLAYED\",\n output: replay.output,\n port,\n };\n records.set(step.id, record);\n await journal(record);\n scope.steps[step.key] = { output: replay.output };\n decideOutgoing(step.id, port);\n return;\n }\n const input = resolveExpressions(step.config, scope);\n try {\n const result = await executor.execute({\n blockType: step.blockType,\n config: input,\n connectionId: step.connectionId,\n step,\n });\n const port = result.port ?? \"next\";\n const record: StepExecutionRecord = {\n stepId: step.id,\n key: step.key,\n blockType: step.blockType,\n status: \"SUCCEEDED\",\n input: journaled(input, result.redactValues),\n output: journaled(result.output, result.redactValues),\n port,\n };\n records.set(step.id, record);\n await journal(record);\n scope.steps[step.key] = { output: result.output };\n decideOutgoing(step.id, port);\n } catch (error) {\n // A failed step is exactly where an input gets inspected, so it is\n // redacted with the same secrets the successful path uses.\n const values = secretsFor(error);\n const detail = redactMessage(errorMessage(error), { values });\n const record: StepExecutionRecord = {\n stepId: step.id,\n key: step.key,\n blockType: step.blockType,\n status: \"FAILED\",\n input: journaled(input, values),\n error: detail,\n };\n records.set(step.id, record);\n await journal(record);\n decideOutgoing(step.id, \"error\");\n const errorHandled = definition.edges.some(\n (edge) => edge.from === step.id && edgeDecisions.get(edge.id),\n );\n if (!errorHandled) {\n runFailed = `Step \"${step.key}\" failed: ${detail}`;\n }\n }\n };\n\n let progressed = true;\n while (progressed && !runFailed) {\n progressed = false;\n for (const step of definition.steps) {\n if (records.has(step.id)) continue;\n const inbound = inboundEdges(step);\n if (isEntryStep(step)) {\n await executeStep(step);\n progressed = true;\n // Independent roots are otherwise free to run their side effects\n // before the outer loop notices the run is already over.\n if (runFailed) break;\n continue;\n }\n if (inbound.length === 0) continue;\n const decided = inbound.every((edge) => edgeDecisions.has(edge.id));\n if (!decided) continue;\n const reachable = inbound.some((edge) => edgeDecisions.get(edge.id));\n if (reachable) {\n await executeStep(step);\n } else {\n skipStep(step);\n }\n progressed = true;\n if (runFailed) break;\n }\n }\n\n // Steps never reached (dangling, cyclic, or after a terminal failure).\n for (const step of definition.steps) {\n if (!records.has(step.id)) skipStep(step);\n }\n\n // A FAILED record with a taken error edge is a handled failure; only\n // unhandled ones set runFailed above.\n const steps = definition.steps.map((step) => records.get(step.id)!);\n return runFailed\n ? { status: \"FAILED\", steps, error: runFailed }\n : { status: \"SUCCEEDED\", steps };\n}\n","// The pieces this reactor holds locally, by piece name.\n\n// A holder, not a finder: resolving a package is the host's package manager's\n// job, and this runtime must not depend on reactor-api to have it done.\nimport { childLogger } from \"document-model\";\nimport type { LocalPiece } from \"../pieces/index.js\";\n\nconst logger = childLogger([\"workflow\", \"piece-registry\"]);\n\nexport class PieceRegistry {\n private byName = new Map<string, LocalPiece>();\n\n // Replaces the whole set: what the host reports is everything it holds, so\n // a piece missing from it is a piece the reactor no longer has.\n setPieces(pieces: readonly LocalPiece[]): void {\n const found = new Map<string, LocalPiece>();\n for (const piece of pieces) {\n // The first to claim a name keeps it, so a project can override a piece\n // one of its dependencies ships.\n if (!found.has(piece.name)) found.set(piece.name, piece);\n }\n this.byName = found;\n const names = [...found.keys()].join(\", \");\n // Names go through the logger's values: it substitutes `@`-prefixed\n // tokens, and a scoped package name printed inline comes out as null/pack.\n if (found.size > 0) {\n logger.info(`Holding ${found.size} package piece(s): @names`, names);\n } else {\n logger.debug(\"Holding no package pieces\");\n }\n }\n\n lookup = (name: string): LocalPiece | undefined => this.byName.get(name);\n\n entries(): LocalPiece[] {\n return [...this.byName.values()];\n }\n\n // Name -> installed version, the registry parseBlockType resolves an\n // unversioned block type against.\n versions(): Record<string, string> {\n return Object.fromEntries(\n [...this.byName.values()].map((piece) => [piece.name, piece.version]),\n );\n }\n\n /** Test seam: a suite that filled the registry starts the next from nothing. */\n reset(): void {\n this.byName = new Map();\n }\n}\n\n// One registry for the runtime, the way the bundle cache is one directory.\nexport const packagePieces = new PieceRegistry();\n"],"mappings":"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"}
package/dist/testing.d.ts CHANGED
@@ -1,2 +1,2 @@
1
- import { A as fetchPieceBundle, D as buildDescriptor, E as PieceDescriptor, O as loadPieceFromDir, S as localFirstResolver, T as extractDedupeKey, _ as PieceWorker, a as AttachmentPort, b as PackagePiece, f as BlockExecution, g as IPieceWorker, h as PieceWorkerPool, i as ActivepiecesBlockExecutor, k as ensurePieceBundle, l as StaticConnectionResolver, m as WorkflowRunResult, o as CompositeBlockExecutor, r as runWorkflow, s as ReactorPort, t as PieceRegistry, u as InMemorySecretProvider, w as RecordedSchedule, x as PieceResolver, y as LocalPiece } from "./piece-registry-CE0UFmDA.js";
1
+ import { A as fetchPieceBundle, D as buildDescriptor, E as PieceDescriptor, O as loadPieceFromDir, S as localFirstResolver, T as extractDedupeKey, _ as PieceWorker, a as AttachmentPort, b as PackagePiece, f as BlockExecution, g as IPieceWorker, h as PieceWorkerPool, i as ActivepiecesBlockExecutor, k as ensurePieceBundle, l as StaticConnectionResolver, m as WorkflowRunResult, o as CompositeBlockExecutor, r as runWorkflow, s as ReactorPort, t as PieceRegistry, u as InMemorySecretProvider, w as RecordedSchedule, x as PieceResolver, y as LocalPiece } from "./piece-registry-DxYByELl.js";
2
2
  export { ActivepiecesBlockExecutor, type AttachmentPort, type BlockExecution, CompositeBlockExecutor, type IPieceWorker, InMemorySecretProvider, type LocalPiece, type PackagePiece, type PieceDescriptor, PieceRegistry, type PieceResolver, PieceWorker, PieceWorkerPool, type ReactorPort, type RecordedSchedule, StaticConnectionResolver, type WorkflowRunResult, buildDescriptor, ensurePieceBundle, extractDedupeKey, fetchPieceBundle, loadPieceFromDir, localFirstResolver, runWorkflow };