@powerhousedao/reactor-workflow 6.2.3-dev.11

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -0,0 +1 @@
1
+ {"version":3,"file":"redact-C7LWgAyD.js","names":[],"sources":["../src/pieces/activepieces/types.ts","../src/pieces/activepieces/context/stubs.ts","../src/pieces/activepieces/worker/protocol.ts","../src/pieces/activepieces/worker/json-safe.ts","../src/pieces/activepieces/context/store-scope.ts","../src/pieces/activepieces/context/action.ts","../src/pieces/activepieces/context/limits.ts","../src/pieces/activepieces/context/files.ts","../src/pieces/activepieces/context/trigger.ts","../src/pieces/activepieces/worker/egress.ts","../src/pieces/activepieces/worker/redact.ts"],"sourcesContent":["// Structural types for published Activepieces bundles (Path B). Bundles inline\n// their framework, so all typing is duck-typed — see ../../10-spike-notes-s6a.md.\nimport type {\n ActionBase,\n BasePropertySchema,\n DropdownOption,\n DropdownProperty,\n DropdownState,\n PieceBase,\n TriggerBase,\n WebhookHandshakeConfiguration,\n} from \"@powerhousedao/pieces-framework\";\n\nexport { DEDUPE_KEY_PROPERTY } from \"@powerhousedao/pieces-framework\";\n\n// Widened from the framework's PropertyType: a bundle inlines its own copy of\n// the enum, so a value read off one is compared as a string, never by identity.\nexport type ApPropertyType = string;\n\nexport type ApDropdownOption = Pick<DropdownOption<unknown>, \"label\" | \"value\">;\n\n// STATIC_DROPDOWN options are plain data; DROPDOWN options is a resolver function.\nexport type ApStaticDropdownState = Pick<\n DropdownState<unknown>,\n \"disabled\" | \"placeholder\"\n> & { options: ApDropdownOption[] };\n\n// Every field optional: an unknown bundle version may omit any of them, and a\n// missing field must read as absent rather than fail the descriptor.\nexport type ApProperty = Partial<\n Pick<BasePropertySchema, \"displayName\" | \"description\" | \"placeholder\">\n> &\n Partial<Pick<DropdownProperty<unknown, boolean>, \"refreshers\">> & {\n type?: ApPropertyType;\n required?: boolean;\n defaultValue?: unknown;\n options?: ApStaticDropdownState | ((...args: unknown[]) => unknown);\n // Resolver function on DYNAMIC properties.\n props?: (...args: unknown[]) => unknown;\n // ARRAY: schema of each item's fields; absent for plain value arrays.\n properties?: Record<string, ApProperty>;\n };\n\n// requireAuth is UI metadata only — pieces run without auth despite it (spike finding).\nexport type ApAction = Partial<\n Pick<ActionBase, \"name\" | \"displayName\" | \"description\" | \"requireAuth\">\n> & {\n props?: Record<string, ApProperty>;\n run: (ctx: unknown) => Promise<unknown>;\n};\n\n// Widened from TriggerStrategy for the same reason as ApPropertyType:\n// WEBHOOK | POLLING | MANUAL | APP_WEBHOOK, read off a foreign bundle's enum.\nexport type ApTriggerStrategy = string;\n\n// strategy widened from WebhookHandshakeStrategy: NONE | HEADER_PRESENT |\n// QUERY_PRESENT | BODY_PARAM_PRESENT | HEAD_REQUEST.\nexport type ApHandshakeConfiguration = Partial<\n Omit<WebhookHandshakeConfiguration, \"strategy\">\n> & { strategy?: string };\n\nexport type ApTrigger = Partial<\n Pick<\n TriggerBase,\n \"name\" | \"displayName\" | \"description\" | \"requireAuth\" | \"sampleData\"\n >\n> & {\n type?: ApTriggerStrategy;\n // Widened from TriggerTestStrategy: SIMULATION | TEST_FUNCTION.\n testStrategy?: string;\n props?: Record<string, ApProperty>;\n handshakeConfiguration?: ApHandshakeConfiguration;\n onEnable?: (ctx: unknown) => Promise<void>;\n onDisable?: (ctx: unknown) => Promise<void>;\n onStart?: (ctx: unknown) => Promise<unknown>;\n run?: (ctx: unknown) => Promise<unknown[]>;\n test?: (ctx: unknown) => Promise<unknown[]>;\n onHandshake?: (ctx: unknown) => Promise<unknown>;\n onRenew?: (ctx: unknown) => Promise<void>;\n};\n\n// `categories` is widened from PieceCategory[] for the cross-bundle reason\n// above; `auth` is the raw property, not the framework's PieceAuthProperty.\nexport type ApPiece = Pick<PieceBase, \"displayName\"> &\n Partial<\n Pick<\n PieceBase,\n | \"description\"\n | \"logoUrl\"\n | \"authors\"\n | \"minimumSupportedRelease\"\n | \"maximumSupportedRelease\"\n >\n > & {\n categories?: string[];\n auth?: ApProperty;\n // A bundle exposes these as the built record or as a zero-arg method; the\n // framework's own Piece class only ever has the method.\n actions?: Record<string, ApAction> | (() => Record<string, ApAction>);\n triggers?: Record<string, ApTrigger> | (() => Record<string, ApTrigger>);\n getAction?: (name: string) => ApAction | undefined;\n getTrigger?: (name: string) => ApTrigger | undefined;\n metadata?: () => Record<string, unknown>;\n };\n\n// Normalizes the record-vs-method variants of `piece.actions`.\nexport function getActions(piece: ApPiece): Record<string, ApAction> {\n const actions =\n typeof piece.actions === \"function\" ? piece.actions() : piece.actions;\n return actions ?? {};\n}\n\n// Normalizes the record-vs-method variants of `piece.triggers`.\nexport function getTriggers(piece: ApPiece): Record<string, ApTrigger> {\n const triggers =\n typeof piece.triggers === \"function\" ? piece.triggers() : piece.triggers;\n return triggers ?? {};\n}\n","export class UnsupportedContextMemberError extends Error {\n readonly member: string;\n\n constructor(member: string) {\n super(\n `Piece used unimplemented context member \"${member}\". ` +\n `Implement it in the adapter or reject the piece at conformance time.`,\n );\n this.name = \"UnsupportedContextMemberError\";\n this.member = member;\n }\n}\n\n// Traps calls and member reads so both `ctx.files.write(...)` and\n// `ctx.server.apiUrl` throw with the full member path.\nexport function throwingStub(memberPath: string): unknown {\n return new Proxy(function stub() {}, {\n get(_target, prop) {\n // `then` and symbols stay inert so `await`/inspection don't false-trip.\n if (typeof prop !== \"string\" || prop === \"then\") return undefined;\n throw new UnsupportedContextMemberError(`${memberPath}.${prop}`);\n },\n apply() {\n throw new UnsupportedContextMemberError(memberPath);\n },\n });\n}\n\n// Wraps a context object so every top-level read is recorded; reads of\n// members outside the documented surface are flagged as UNDOCUMENTED.\nexport function withTouchTracking<T extends object>(\n base: T,\n touched: Set<string>,\n onTouch?: (member: string) => void,\n): T {\n return new Proxy(base, {\n get(target, prop, receiver) {\n if (typeof prop === \"string\" && prop !== \"then\") {\n const member = prop in target ? prop : `UNDOCUMENTED:${prop}`;\n touched.add(member);\n onTouch?.(member);\n }\n return Reflect.get(target, prop, receiver) as unknown;\n },\n });\n}\n","import type { ActionContextIdentity } from \"../context/action.js\";\nimport type { StagedFile } from \"../context/files.js\";\nimport type {\n ExecutionType,\n ServerContext,\n} from \"@powerhousedao/pieces-framework\";\nimport type { RecordedListener, RecordedSchedule } from \"../context/trigger.js\";\n\n// One FILE-prop value the host resolved to a path before the run, so the\n// bytes reach the worker through the shared filesystem instead of JSON IPC.\nexport interface StagedInput {\n ref: string;\n path: string;\n fileName?: string;\n contentType?: string;\n}\n\n// Where a piece may connect to while this request runs. Enforced in the child\n// at socket-connect time; absent means unrestricted, which is the old behaviour.\nexport interface EgressPolicy {\n // Hostnames (or literal IPs) the piece may reach; a leading \"*.\" matches\n // subdomains. Omitted or empty allows any host the address rules permit.\n allowHosts?: string[];\n // Addresses or CIDRs reachable even though they are private — a service on\n // the operator's own network, say.\n allowAddresses?: string[];\n // Lifts the private-address block, for an operator whose isolation lives\n // elsewhere. Local sockets, UDP and listening stay refused under any policy.\n allowPrivateAddresses?: boolean;\n // TCP ports the piece may reach; omitted or empty allows any.\n allowPorts?: number[];\n}\n\n// The child is forked with an empty env, so policy can only arrive on the wire:\n// every request carries the one in force for the work it asks for.\nexport interface EgressScopedRequest {\n egress?: EgressPolicy;\n}\n\n// Where the worker finds the piece module: a bundle directory in npm shape, as\n// a registry fetch extracts it, or the module file of an installed package.\n\n// Exactly one is set; a request carrying neither is refused before any load.\nexport interface PieceModuleRef {\n bundleDir?: string;\n entryPath?: string;\n}\n\nexport interface RunActionRequest extends EgressScopedRequest, PieceModuleRef {\n actionName: string;\n propsValue: Record<string, unknown>;\n auth?: unknown;\n // Where ctx.files.write() puts bytes for the host to ingest. Without it the\n // action gets the data-URI service instead.\n stagingDir?: string;\n // Attachment refs in propsValue, already materialized by the host.\n stagedInputs?: StagedInput[];\n // Resolved connection values served to ctx.connections.get(key).\n connections?: Record<string, unknown>;\n // Store partition; runs sharing a scope share state for the worker's lifetime.\n storeScope?: string;\n // Serve `ctx.store` from the host over the call channel instead of the\n // in-memory partition above, so a write survives this worker.\n durableStore?: boolean;\n // Forward the piece's console output to the host as it is written. Off by\n // default: a chatty piece would otherwise pay IPC for logs nobody reads.\n captureLogs?: boolean;\n // Implement `ctx.output.update`, which reports progress mid-step. Without\n // it the member keeps throwing, so a piece that needs it fails loudly.\n liveOutput?: boolean;\n executionType?: `${ExecutionType}`;\n identity?: ActionContextIdentity;\n // Concrete secret values resolved for this step, so the child can strip them\n // from an error before it crosses back; they already travel inside `auth`.\n redactValues?: string[];\n // Serve `ctx.reactor` over the call channel. Set only for a piece the host\n // loaded from an installed reactor package; a fetched bundle never gets it.\n reactorAccess?: boolean;\n}\n\nexport interface RunMessage {\n id: number;\n type: \"run\";\n request: RunActionRequest;\n}\n\n// Design-time resolution of a DROPDOWN options() / DYNAMIC props() resolver.\nexport interface ResolveOptionsRequest\n extends EgressScopedRequest, PieceModuleRef {\n // Action or trigger name, per kind (default \"action\").\n actionName: string;\n kind?: \"action\" | \"trigger\";\n propName: string;\n refresherValues?: Record<string, unknown>;\n auth?: unknown;\n searchValue?: string;\n // As on a run: an options() resolver of a package piece may read the reactor\n // it is offering choices from.\n reactorAccess?: boolean;\n}\n\nexport interface ResolveOptionsMessage {\n id: number;\n type: \"resolve-options\";\n request: ResolveOptionsRequest;\n}\n\n// One trigger lifecycle hook. With `durableStore` its `ctx.store` is the same\n// host-served store an action gets, so a write lands as the hook makes it.\n\n// Without one it runs statelessly: `storeState` seeds an in-memory store and\n// the whole snapshot comes back in the response for the caller to persist.\nexport interface TriggerHookRequest\n extends EgressScopedRequest, PieceModuleRef {\n triggerName: string;\n hook: \"onEnable\" | \"onDisable\" | \"run\" | \"test\" | \"onHandshake\";\n propsValue: Record<string, unknown>;\n auth?: unknown;\n storeState?: Record<string, unknown>;\n // Serve `ctx.store` from the host over the call channel, exactly as\n // RunActionRequest does, instead of seeding and returning the snapshot above.\n durableStore?: boolean;\n identity?: ActionContextIdentity;\n // onEnable of an unchanged trigger; pollingHelper keeps its cursor.\n isRepublish?: boolean;\n // WEBHOOK payloads; also handed to test runs.\n payload?: unknown;\n webhookUrl?: string;\n server?: ServerContext;\n // As on a run request: secrets stripped from errors before they cross back.\n redactValues?: string[];\n}\n\nexport interface TriggerHookMessage {\n id: number;\n type: \"trigger-hook\";\n request: TriggerHookRequest;\n}\n\n// A connection credential check. Auth crosses into the worker and stays\n// there: the piece code that reads it never runs in the host process.\nexport interface CheckConnectionRequest\n extends EgressScopedRequest, PieceModuleRef {\n auth?: unknown;\n}\n\nexport interface CheckConnectionMessage {\n id: number;\n type: \"check-connection\";\n request: CheckConnectionRequest;\n}\n\n// `output` of a check-connection result.\nexport interface CheckConnectionOutcome {\n // False when the piece declares no app.checkConnection.\n declared: boolean;\n // Its return value: void | boolean | { name | username | email | sub }.\n result?: unknown;\n}\n\n// Design-time descriptor of a piece: its actions, triggers and auth shape.\n// Building one requires the piece module, whose top-level code runs on load,\n// so it is built in the worker and only the plain descriptor crosses back.\nexport interface DescribePieceRequest\n extends EgressScopedRequest, PieceModuleRef {\n // Carried through into the descriptor's `source` and its resolver ids.\n packageName: string;\n version: string;\n}\n\nexport interface DescribePieceMessage {\n id: number;\n type: \"describe\";\n request: DescribePieceRequest;\n}\n\nexport type WorkerRequestMessage =\n | RunMessage\n | ResolveOptionsMessage\n | TriggerHookMessage\n | CheckConnectionMessage\n | DescribePieceMessage;\n\n// Piece errors cross the IPC boundary as data; classify on these fields.\nexport interface SerializedPieceError {\n name: string;\n message: string;\n // The error's own enumerable properties, plus the HTTP status, request and\n // response the framework's error formatter recovered from it.\n properties: Record<string, unknown>;\n // Set when the piece hit an unimplemented context member.\n unsupportedMember?: string;\n}\n\nexport interface ResultResponse {\n id: number;\n type: \"result\";\n output: unknown;\n touched: string[];\n // True when the piece set NODE_TLS_REJECT_UNAUTHORIZED=0 (contained to the worker).\n tlsPoisoned: boolean;\n // Files the piece wrote through ctx.files during this request. The host\n // ingests each one, then rewrites its provisional token in `output`.\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\nexport interface ErrorResponse {\n id: number;\n type: \"error\";\n error: SerializedPieceError;\n tlsPoisoned: boolean;\n}\n\nexport type WorkerResponse = ResultResponse | ErrorResponse;\n\n// A request the child makes of its host while a step is running: the reverse\n// direction of everything above, and the only way a piece reaches durable state.\n\n// Ids are the child's own counter, a separate space from the host's, which is\n// why every handler dispatches on `type` before comparing an id.\nexport interface HostCallMessage {\n id: number;\n type: \"host-call\";\n method: string;\n payload: unknown;\n}\n\n// `error` carries the failure as data: a rejected promise cannot cross IPC,\n// so the reply always arrives and the child rethrows.\nexport interface HostCallResponse {\n id: number;\n type: \"host-result\";\n value?: unknown;\n error?: string;\n}\n\n// What the host will answer for the request in flight. Registered per request,\n// so a call arriving after the step returned finds nothing and is refused.\nexport type HostCallHandlers = Record<\n string,\n (payload: unknown) => Promise<unknown>\n>;\n\n// The one-way half of the channel: a report the host may act on, with no\n// answer to wait for. Their engine splits the same way (rpc vs rpc-notify).\n\n// A tap must never stall the step, so these carry no id and no reply. Node's\n// IPC preserves order, which is what drains them before the result lands.\nexport interface HostNotifyMessage {\n type: \"host-notify\";\n method: string;\n payload: unknown;\n}\n\n// Handlers registered per request, like HostCallHandlers. A throw here is\n// swallowed: a failed tap must not fail the step it was reporting on.\nexport type HostNotifyHandlers = Record<string, (payload: unknown) => void>;\n\n// One console call the piece made, already flattened to a string in the child.\nexport interface PieceLogEntry {\n level: \"log\" | \"info\" | \"warn\" | \"error\" | \"debug\";\n message: string;\n at: number;\n}\n\nexport const LOG_WRITE = \"log.write\";\nexport const OUTPUT_UPDATE = \"output.update\";\n\n// A store call carries `{ key, value?, scope }`. The scope is a name the host\n// partitions on, never a prefix the child bakes into the key.\nexport const STORE_GET = \"store.get\";\nexport const STORE_PUT = \"store.put\";\nexport const STORE_DELETE = \"store.delete\";\n\n// A reactor call carries the operation's own input object; the host answers\n// with documents already projected to summaries (see context/reactor.ts).\nexport const REACTOR_MODELS = \"reactor.models\";\nexport const REACTOR_MODEL = \"reactor.model\";\nexport const REACTOR_GET = \"reactor.get\";\nexport const REACTOR_FIND = \"reactor.find\";\nexport const REACTOR_CREATE = \"reactor.create\";\nexport const REACTOR_EXECUTE = \"reactor.execute\";\n","// Everything the child sends crosses a structured-clone boundary. A piece's\n// own objects routinely do not survive it, so they are flattened first.\nexport function jsonSafe(value: unknown): unknown {\n try {\n return JSON.parse(JSON.stringify(value)) as unknown;\n } catch {\n return String(value);\n }\n}\n","// Their StoreScope, as a name the host can partition on.\nimport { StoreScope } from \"@powerhousedao/pieces-framework\";\n\n// The enum's PROJECT member carries the legacy value \"COLLECTION\", and an\n// omitted scope means FLOW, so both are folded to one name here.\nexport type StoreScopeName = keyof typeof StoreScope;\n\n// Compared by value, never by enum identity: a piece bundle inlines its own\n// copy of StoreScope, and some pass the member name instead of its value.\nexport function normalizeStoreScope(scope?: unknown): StoreScopeName {\n return scope === StoreScope.PROJECT || scope === \"PROJECT\"\n ? \"PROJECT\"\n : \"FLOW\";\n}\n","// Our ActionContext → their ActionContext (doc 06 §2.8). Implements the top usage\n// tier (propsValue, auth, store, connections); the rest throws loudly, named.\nimport { throwingStub, withTouchTracking } from \"./stubs.js\";\nimport { jsonSafe } from \"../worker/json-safe.js\";\nimport { normalizeStoreScope, type StoreScopeName } from \"./store-scope.js\";\nimport type { ApFilesService } from \"./files.js\";\nimport type { ConnectionsProvider } from \"./props.js\";\nimport type {\n BaseContext,\n ConnectionsManager,\n ExecutionType,\n FilesService,\n FlowsContext,\n InputPropertyMap,\n OutputContext,\n ReactorService,\n RunContext,\n ServerContext,\n StepContext,\n Store,\n TagsManager,\n} from \"@powerhousedao/pieces-framework\";\n\nexport { UnsupportedContextMemberError } from \"./stubs.js\";\n\n// The scope travels beside the key rather than inside it: which partition a\n// key belongs to is the host's decision, not a naming convention.\n\n// The host's half of the framework's Store, with its generics dropped: a\n// durable store round-trips through JSON, so nothing comes back as the T put in.\nexport interface KeyValueStore {\n put(key: string, value: unknown, scope?: StoreScopeName): Promise<unknown>;\n get(key: string, scope?: StoreScopeName): Promise<unknown>;\n delete(key: string, scope?: StoreScopeName): Promise<void>;\n}\n\n// In-memory connection registry: key → resolved connection value.\nexport class InMemoryConnectionsProvider implements ConnectionsProvider {\n private readonly values: Map<string, unknown>;\n\n constructor(values: Record<string, unknown> = {}) {\n this.values = new Map(Object.entries(values));\n }\n\n set(key: string, value: unknown): void {\n this.values.set(key, value);\n }\n\n get(key: string): Promise<unknown> {\n return Promise.resolve(this.values.get(key) ?? null);\n }\n}\n\nexport class InMemoryKeyValueStore implements KeyValueStore {\n private readonly entries: Map<string, unknown>;\n\n constructor(seed: Record<string, unknown> = {}) {\n this.entries = new Map(Object.entries(seed));\n }\n\n snapshot(): Record<string, unknown> {\n return Object.fromEntries(this.entries);\n }\n\n // Flattened like the durable store, so the heap fallback is not the one\n // place a Date survives a put.\n put(key: string, value: unknown, scope?: StoreScopeName): Promise<unknown> {\n const stored = jsonSafe(value);\n this.entries.set(this.scoped(key, scope), stored);\n return Promise.resolve(stored);\n }\n\n get(key: string, scope?: StoreScopeName): Promise<unknown> {\n return Promise.resolve(this.entries.get(this.scoped(key, scope)) ?? null);\n }\n\n delete(key: string, scope?: StoreScopeName): Promise<void> {\n this.entries.delete(this.scoped(key, scope));\n return Promise.resolve();\n }\n\n // One heap, so the scopes share it and are kept apart by name.\n private scoped(key: string, scope?: StoreScopeName): string {\n return scope === \"PROJECT\" ? `PROJECT:${key}` : key;\n }\n}\n\nexport interface ActionContextIdentity {\n runId?: string;\n projectId?: string;\n flowId?: string;\n flowVersionId?: string;\n stepName?: string;\n}\n\nexport interface ActionContextOptions {\n propsValue: Record<string, unknown>;\n auth?: unknown;\n store?: KeyValueStore;\n // ctx.files for actions. Mirrors the option triggers already accept; when\n // omitted the member keeps throwing, so a piece that needs files fails\n // loudly rather than silently dropping them.\n files?: ApFilesService;\n connections?: ConnectionsProvider;\n // ctx.output.update, the piece's own progress report. Omitted, the member\n // throws, so a piece that depends on it fails by name rather than silently.\n output?: { update(output: unknown): Promise<void> };\n // ctx.reactor. Served only to a piece the host loaded from an installed\n // reactor package; for every other piece the member throws by name.\n reactor?: ReactorService;\n executionType?: `${ExecutionType}`;\n identity?: ActionContextIdentity;\n onTouch?: (member: string) => void;\n}\n\n// Shape of the context we hand to `action.run()`: the framework's ActionContext\n// member for member. Those beyond the implemented tier throw, named.\nexport interface BuiltApActionContext {\n executionType: `${ExecutionType}`;\n auth: unknown;\n propsValue: Record<string, unknown>;\n store: Store;\n connections: ConnectionsManager;\n tags: TagsManager;\n server: ServerContext;\n files: FilesService;\n output: OutputContext;\n reactor: ReactorService;\n // Carried by the framework's own test double but absent from its types.\n agent: { tools: unknown[] };\n run: RunContext;\n project: BaseContext<undefined, InputPropertyMap>[\"project\"];\n flows: FlowsContext;\n step: StepContext;\n generateResumeUrl(params: {\n queryParams: Record<string, string>;\n sync?: boolean;\n }): string;\n}\n\nexport interface ActionContextHandle {\n context: BuiltApActionContext;\n // Top-level members the piece read; `UNDOCUMENTED:<name>` marks unknown reads.\n touched: ReadonlySet<string>;\n}\n\nexport function buildActionContext(\n options: ActionContextOptions,\n): ActionContextHandle {\n const { identity = {} } = options;\n const store = options.store ?? new InMemoryKeyValueStore();\n const touched = new Set<string>();\n\n const base: Record<string, unknown> = {\n executionType: options.executionType ?? \"BEGIN\",\n auth: options.auth,\n propsValue: options.propsValue,\n store: {\n put: (key: string, value: unknown, scope?: unknown) =>\n store.put(key, value, normalizeStoreScope(scope)),\n get: (key: string, scope?: unknown) =>\n store.get(key, normalizeStoreScope(scope)),\n delete: (key: string, scope?: unknown) =>\n store.delete(key, normalizeStoreScope(scope)),\n },\n connections: options.connections ?? throwingStub(\"connections\"),\n tags: throwingStub(\"tags\"),\n server: throwingStub(\"server\"),\n files: options.files ?? throwingStub(\"files\"),\n output: options.output ?? throwingStub(\"output\"),\n reactor: options.reactor ?? throwingStub(\"reactor\"),\n agent: throwingStub(\"agent\"),\n run: {\n id: identity.runId ?? \"run\",\n stop: throwingStub(\"run.stop\"),\n pause: throwingStub(\"run.pause\"),\n respond: throwingStub(\"run.respond\"),\n createWaitpoint: throwingStub(\"run.createWaitpoint\"),\n waitForWaitpoint: throwingStub(\"run.waitForWaitpoint\"),\n },\n project: {\n id: identity.projectId ?? \"project\",\n externalId: () => Promise.resolve(identity.projectId ?? \"project\"),\n },\n flows: {\n list: throwingStub(\"flows.list\"),\n current: {\n id: identity.flowId ?? \"flow\",\n version: { id: identity.flowVersionId ?? \"flow-version\" },\n },\n },\n step: { name: identity.stepName ?? \"step\" },\n generateResumeUrl: throwingStub(\"generateResumeUrl\"),\n };\n\n const context = withTouchTracking(base, touched, options.onTouch);\n return { context: context as unknown as BuiltApActionContext, touched };\n}\n","// One file-size ceiling for both directions. Inbound hydration (a FILE prop\n// that arrives as a URL, a data URI or an attachment ref) and outbound\n// ctx.files.write share it, because a piece that can emit a file the next step\n// cannot ingest is worse than a piece that refuses both.\nexport const DEFAULT_MAX_FILE_BYTES = 8 * 1024 * 1024;\n\n// Read per call rather than at import: a host may set the override after this\n// module is loaded, and tests need to move it.\nexport function maxFileBytes(): number {\n const raw = process.env.PH_PIECE_MAX_FILE_BYTES;\n if (raw === undefined) return DEFAULT_MAX_FILE_BYTES;\n const parsed = Number(raw);\n return Number.isFinite(parsed) && parsed > 0\n ? Math.floor(parsed)\n : DEFAULT_MAX_FILE_BYTES;\n}\n\nexport class FileTooLargeError extends Error {\n readonly size: number;\n readonly limit: number;\n\n constructor(size: number, limit: number = maxFileBytes()) {\n super(\n `File of ${size} bytes exceeds the ${limit} byte limit ` +\n `(raise PH_PIECE_MAX_FILE_BYTES to allow more)`,\n );\n this.name = \"FileTooLargeError\";\n this.size = size;\n this.limit = limit;\n }\n}\n\nexport function assertWithinLimit(size: number): void {\n const limit = maxFileBytes();\n if (size > limit) throw new FileTooLargeError(size, limit);\n}\n","// Two FilesService implementations plus the staged-file contract that carries\n// bytes back to the host.\n//\n// `ctx.files.write()` is called *during* action.run(), inside the forked\n// worker, and the worker protocol has no worker-to-host request channel. So\n// this follows the pattern storeState already establishes — push in, return\n// whole — using the one thing a fork shares with its parent: the filesystem.\n// The worker writes bytes to a staging directory and returns a provisional\n// `apfile://<token>`; the host ingests each staged file after the step returns\n// and rewrites the tokens in the output before journalling it.\nimport { randomUUID } from \"node:crypto\";\nimport { mkdir, writeFile } from \"node:fs/promises\";\nimport path from \"node:path\";\nimport {\n assertWithinLimit,\n FileTooLargeError,\n maxFileBytes,\n} from \"./limits.js\";\n\nexport { FileTooLargeError, maxFileBytes };\n\nexport const APFILE_SCHEME = \"apfile://\";\n\n// One file the piece wrote, as it crosses back on ResultResponse.files.\nexport interface StagedFile {\n // The provisional ref handed to the piece; the host rewrites it in place.\n token: string;\n path: string;\n fileName: string;\n size: number;\n contentType?: string;\n}\n\n// The framework's FilesService for both actions and triggers, narrowed to a\n// Buffer (the staging path cannot stream) with fileName optional.\nexport interface ApFilesService {\n write(file: { fileName?: string; data: Buffer }): Promise<string>;\n}\n\n// Default for both actions and triggers when the host injects nothing: inline\n// the bytes as a data URI so the payload stays self-contained. Bounded by the\n// shared cap, since a data URI lands in the run journal.\nexport class DataUriFilesService implements ApFilesService {\n write(file: { fileName?: string; data: Buffer }): Promise<string> {\n const data = Buffer.isBuffer(file.data)\n ? file.data\n : Buffer.from(file.data);\n if (data.byteLength > maxFileBytes()) {\n return Promise.reject(new FileTooLargeError(data.byteLength));\n }\n return Promise.resolve(\n `data:application/octet-stream;base64,${data.toString(\"base64\")}`,\n );\n }\n}\n\nconst EXTENSION_TYPES: Record<string, string> = {\n pdf: \"application/pdf\",\n png: \"image/png\",\n jpg: \"image/jpeg\",\n jpeg: \"image/jpeg\",\n webp: \"image/webp\",\n tif: \"image/tiff\",\n tiff: \"image/tiff\",\n txt: \"text/plain\",\n json: \"application/json\",\n csv: \"text/csv\",\n};\n\nfunction contentTypeFor(fileName: string): string | undefined {\n const extension = fileName.split(\".\").pop()?.toLowerCase();\n return extension ? EXTENSION_TYPES[extension] : undefined;\n}\n\n// Worker-side service: writes into `<stagingDir>/<uuid>` and remembers what it\n// wrote so the worker can report it on the response.\nexport class StagedFilesService implements ApFilesService {\n private readonly files: StagedFile[] = [];\n\n constructor(private readonly stagingDir: string) {}\n\n staged(): StagedFile[] {\n return [...this.files];\n }\n\n async write(file: { fileName?: string; data: Buffer }): Promise<string> {\n const data = Buffer.isBuffer(file.data)\n ? file.data\n : Buffer.from(file.data);\n // Checked before the write: a piece must not be able to fill the disk by\n // handing over a file the host would refuse anyway.\n assertWithinLimit(data.byteLength);\n const token = randomUUID();\n const fileName =\n file.fileName && file.fileName !== \"\" ? file.fileName : token;\n const target = path.join(this.stagingDir, token);\n await mkdir(this.stagingDir, { recursive: true });\n await writeFile(target, data);\n this.files.push({\n token: `${APFILE_SCHEME}${token}`,\n path: target,\n fileName,\n size: data.byteLength,\n contentType: contentTypeFor(fileName),\n });\n return `${APFILE_SCHEME}${token}`;\n }\n}\n\n// Replaces every provisional token in a step output with the real ref the host\n// got back from its attachment store. Walks the whole value: a piece may nest\n// the ref anywhere, and a plain string replace over the serialized JSON would\n// corrupt any base64 that happens to contain the token.\nexport function rewriteFileRefs(\n value: unknown,\n refs: Map<string, string>,\n): unknown {\n if (refs.size === 0) return value;\n if (typeof value === \"string\") return refs.get(value) ?? value;\n if (Array.isArray(value)) {\n return value.map((entry) => rewriteFileRefs(entry, refs));\n }\n if (typeof value === \"object\" && value !== null) {\n const out: Record<string, unknown> = {};\n for (const [key, entry] of Object.entries(value)) {\n out[key] = rewriteFileRefs(entry, refs);\n }\n return out;\n }\n return value;\n}\n","// Our TriggerHookContext → theirs (doc 06 §2.8): one builder covering the\n// strategy variants; identity/payload as data, capabilities injected or stubbed.\nimport { Cron } from \"croner\";\nimport { DEDUPE_KEY_PROPERTY, type ApTrigger } from \"../types.js\";\nimport {\n InMemoryKeyValueStore,\n type ActionContextIdentity,\n type KeyValueStore,\n} from \"./action.js\";\nimport type { ConnectionsProvider, FlowsProvider } from \"./props.js\";\nimport { normalizeStoreScope, type StoreScopeName } from \"./store-scope.js\";\nimport { throwingStub, withTouchTracking } from \"./stubs.js\";\nimport type { ApFilesService } from \"./files.js\";\nimport type {\n TriggerStrategy,\n InputPropertyMap,\n ServerContext,\n SetScheduleRequest,\n TestOrRunHookContext,\n} from \"@powerhousedao/pieces-framework\";\n\n// Both branches of the framework's SetScheduleRequest, as the piece asked.\nexport type RecordedSchedule = SetScheduleRequest;\n\ntype HookContextFor<S extends TriggerStrategy> = TestOrRunHookContext<\n undefined,\n InputPropertyMap,\n S\n>;\n\nexport type RecordedListener = Parameters<\n HookContextFor<TriggerStrategy.APP_WEBHOOK>[\"app\"][\"createListeners\"]\n>[0];\n\n// Upstream's floor for an interval schedule; a cron is validated the way its\n// engine does, by handing the expression to a parser.\nexport const MIN_SCHEDULE_INTERVAL_MS = 60_000;\n\nexport class InvalidCronExpressionError extends Error {\n constructor(cronExpression: string) {\n super(`Invalid cron expression \"${cronExpression}\"`);\n this.name = \"InvalidCronExpressionError\";\n }\n}\n\nexport class InvalidScheduleIntervalError extends Error {\n constructor(intervalMs: unknown) {\n super(\n `Invalid schedule interval ${String(intervalMs)}: expected a whole number of milliseconds, at least ${MIN_SCHEDULE_INTERVAL_MS}`,\n );\n this.name = \"InvalidScheduleIntervalError\";\n }\n}\n\n// setSchedule's own validation, as the engine's trigger helper performs it: an\n// interval is a whole number at or above the floor, a cron has to parse.\nexport function validateSchedule(request: RecordedSchedule): RecordedSchedule {\n if (\"intervalMs\" in request) {\n const { intervalMs } = request;\n if (\n !Number.isInteger(intervalMs) ||\n intervalMs < MIN_SCHEDULE_INTERVAL_MS\n ) {\n throw new InvalidScheduleIntervalError(intervalMs);\n }\n return { intervalMs };\n }\n const timezone = request.timezone ?? \"UTC\";\n let parsed: Cron;\n try {\n parsed = new Cron(request.cronExpression, { timezone, legacyMode: false });\n } catch {\n throw new InvalidCronExpressionError(request.cronExpression);\n }\n if (!parsed.nextRun()) {\n throw new InvalidCronExpressionError(request.cronExpression);\n }\n return { cronExpression: request.cronExpression, timezone };\n}\n\nexport interface TriggerContextOptions {\n propsValue: Record<string, unknown>;\n auth?: unknown;\n store?: KeyValueStore;\n // \"test\" for test hooks so they never touch the live cursor; \"\" otherwise.\n // Ignored when hostPartitionedStore is set — the host separates them there.\n storePrefix?: string;\n // The store partitions on (scope, key) itself, so the key reaches it\n // verbatim instead of carrying the scope as a name prefix. See scopedKey.\n hostPartitionedStore?: boolean;\n identity?: ActionContextIdentity;\n // onEnable: an unchanged trigger re-enabling; pollingHelper keeps its cursor.\n isRepublish?: boolean;\n // WEBHOOK / APP_WEBHOOK: the incoming request; also handed to test runs.\n payload?: unknown;\n webhookUrl?: string;\n flows?: FlowsProvider;\n connections?: ConnectionsProvider;\n server?: ServerContext;\n // run/test hooks only per the AP contract; omitted members throw, named.\n files?: ApFilesService;\n onTouch?: (member: string) => void;\n}\n\n// One shape for every strategy: the framework splits TriggerHookContext by\n// TriggerStrategy, but a bundle's declared strategy is not known at build time.\nexport type BuiltApTriggerContext = HookContextFor<TriggerStrategy.POLLING> &\n HookContextFor<TriggerStrategy.WEBHOOK> &\n HookContextFor<TriggerStrategy.APP_WEBHOOK>;\n\nexport interface TriggerContextHandle {\n context: BuiltApTriggerContext;\n touched: ReadonlySet<string>;\n // setSchedule / app.createListeners calls, for the supervisor to arm.\n schedules: RecordedSchedule[];\n listeners: RecordedListener[];\n}\n\nexport function buildTriggerContext(\n options: TriggerContextOptions,\n): TriggerContextHandle {\n const { identity = {} } = options;\n const store = options.store ?? new InMemoryKeyValueStore();\n const touched = new Set<string>();\n const schedules: RecordedSchedule[] = [];\n const listeners: RecordedListener[] = [];\n\n // AP's engine store layout, for a store that is one flat map: FLOW scope\n // (the default) nests under the flow id; PROJECT scope uses the bare key.\n\n // Matching the enum's \"COLLECTION\" value alone missed a piece that passes\n // the name instead, which then silently got flow scope.\n const prefix = options.storePrefix ?? \"\";\n const flowId = identity.flowId ?? \"flow\";\n const scopedKey = (key: string, scope?: unknown) =>\n normalizeStoreScope(scope) === \"PROJECT\"\n ? `${prefix}${key}`\n : `${prefix}flow_${flowId}/${key}`;\n\n // A host-partitioned store owns the layout, so the scope travels beside the\n // key rather than inside it, exactly as buildActionContext passes it.\n\n // No \"test\" prefix on that path: a prefix aliases, so a live key named\n // \"testMode\" is a sample's \"Mode\" once both share one flat partition.\n\n // Separating a sample is then the host's job, by partition — which a prefix\n // could not do anyway, since nothing can enumerate a sample's keys to drop.\n const address = (\n key: string,\n scope?: unknown,\n ): [string, StoreScopeName | undefined] =>\n options.hostPartitionedStore\n ? [key, normalizeStoreScope(scope)]\n : [scopedKey(key, scope), undefined];\n\n const base: Record<string, unknown> = {\n auth: options.auth,\n propsValue: options.propsValue,\n isRepublish: options.isRepublish ?? false,\n store: {\n put: (key: string, value: unknown, scope?: unknown) => {\n const [at, partition] = address(key, scope);\n return store.put(at, value, partition);\n },\n get: (key: string, scope?: unknown) => store.get(...address(key, scope)),\n delete: (key: string, scope?: unknown) =>\n store.delete(...address(key, scope)),\n },\n flows: {\n list:\n options.flows?.list.bind(options.flows) ?? throwingStub(\"flows.list\"),\n current: {\n id: identity.flowId ?? \"flow\",\n version: { id: identity.flowVersionId ?? \"flow-version\" },\n },\n },\n step: { name: identity.stepName ?? \"trigger\" },\n project: {\n id: identity.projectId ?? \"project\",\n externalId: () => Promise.resolve(identity.projectId ?? \"project\"),\n },\n connections: options.connections ?? {\n get: throwingStub(\"connections.get\"),\n },\n server: options.server ?? throwingStub(\"server\"),\n webhookUrl: options.webhookUrl ?? \"http://localhost:0/webhook\",\n payload: options.payload,\n setSchedule: (schedule: RecordedSchedule) => {\n schedules.push(validateSchedule(schedule));\n },\n app: {\n createListeners: (listener: RecordedListener) => {\n listeners.push(listener);\n },\n },\n files: options.files ?? throwingStub(\"files\"),\n };\n\n const context = withTouchTracking(base, touched, options.onTouch);\n return {\n context: context as unknown as BuiltApTriggerContext,\n touched,\n schedules,\n listeners,\n };\n}\n\n// Dedup key per doc 08 §4.4: the payload's own _dedupe_key wins; the caller\n// falls back to its own synthesis when absent.\nexport function extractDedupeKey(payload: unknown): string | undefined {\n if (typeof payload !== \"object\" || payload === null) return undefined;\n const value = (payload as Record<string, unknown>)[DEDUPE_KEY_PROPERTY];\n return typeof value === \"string\" ? value : undefined;\n}\n\nexport class TriggerHookNotImplementedError extends Error {\n constructor(triggerName: string, hook: string) {\n super(`Trigger \"${triggerName}\" does not implement ${hook}()`);\n this.name = \"TriggerHookNotImplementedError\";\n }\n}\n\nexport type TriggerLifecycleHook =\n | \"onEnable\"\n | \"onDisable\"\n | \"run\"\n | \"test\"\n | \"onHandshake\"\n | \"onRenew\";\n\n// Invokes one lifecycle hook with the built context; result is returned untouched.\nexport async function runTriggerHook(\n trigger: ApTrigger,\n hook: TriggerLifecycleHook,\n handle: TriggerContextHandle,\n): Promise<unknown> {\n const fn = trigger[hook];\n if (typeof fn !== \"function\") {\n throw new TriggerHookNotImplementedError(trigger.name ?? \"unknown\", hook);\n }\n return await fn.call(trigger, handle.context);\n}\n","// Network egress policy, enforced inside the worker child. Pieces bundle their\n// own HTTP clients, so hooking one of them — or `fetch` — is bypassable.\n\n// Every TCP connection in Node ends at `net.Socket.prototype.connect`, whatever\n// the client, so that is the choke point installed here.\n\n// This hardens SSRF inside a cooperative process; it is not a boundary against\n// hostile code — see installEgressGuard.\nimport dgram from \"node:dgram\";\nimport dns from \"node:dns\";\nimport net, { isIP } from \"node:net\";\nimport { AsyncLocalStorage } from \"node:async_hooks\";\nimport { ssrfIpClassifier } from \"@powerhousedao/pieces-framework/host\";\nimport type { EgressPolicy } from \"./protocol.js\";\n\nexport const EGRESS_DENIED_CODE = \"EGRESS_DENIED\";\n\n// What a host applies when it expresses no preference: every public host is\n// reachable, private space and the metadata endpoint are not.\nexport const DEFAULT_EGRESS_POLICY: EgressPolicy = {};\n\n// Raised at connect time and delivered to the piece the way Node delivers a\n// failed DNS lookup — an error on the socket — so any client surfaces it.\nexport class EgressDeniedError extends Error {\n readonly code = EGRESS_DENIED_CODE;\n readonly host: string;\n readonly port: number | undefined;\n readonly address: string | undefined;\n\n constructor(\n reason: string,\n where: { host: string; port?: number; address?: string },\n ) {\n super(`Egress denied: ${reason}`);\n this.name = \"EgressDeniedError\";\n this.host = where.host;\n this.port = where.port;\n this.address = where.address;\n }\n}\n\n// The SSRF surface (loopback, RFC1918, link-local incl. the metadata endpoint,\n// multicast, and the IPv6 equivalents) is the framework's classifier table.\n\n// ipaddr.js reads a deprecated IPv4-compatible address (::a.b.c.d) as unicast,\n// so ::169.254.169.254 would walk past it; the whole block is refused here.\nconst IPV4_COMPATIBLE = new net.BlockList();\nIPV4_COMPATIBLE.addSubnet(\"::\", 96, \"ipv6\");\n\nfunction familyOf(address: string): \"ipv4\" | \"ipv6\" {\n return isIP(address) === 6 ? \"ipv6\" : \"ipv4\";\n}\n\n// The address without its zone, or undefined when it is not one at all.\nexport function parseAddress(value: string): string | undefined {\n const bare = value.split(\"%\")[0];\n return isIP(bare) === 0 ? undefined : bare;\n}\n\n// Compiled eagerly so a malformed entry fails the request rather than\n// degrading it to no enforcement.\nfunction addAllowedAddress(list: net.BlockList, spec: string): void {\n const slash = spec.indexOf(\"/\");\n const mask = slash === -1 ? \"\" : spec.slice(slash + 1);\n const address = parseAddress(slash === -1 ? spec : spec.slice(0, slash));\n if (!address) {\n throw new Error(`Egress policy entry \"${spec}\" is not an IP address`);\n }\n const family = familyOf(address);\n const width = family === \"ipv6\" ? 128 : 32;\n const prefix = mask === \"\" ? width : Number(mask);\n if (!Number.isInteger(prefix) || prefix < 1 || prefix > width) {\n throw new Error(`Egress policy entry \"${spec}\" has an invalid prefix`);\n }\n list.addSubnet(address, prefix, family);\n}\n\ntype NativeLookup = (\n hostname: string,\n options: dns.LookupOneOptions,\n callback: (error: Error | null, address: unknown, family?: number) => void,\n) => void;\n\n// getaddrinfo, taken before anything is patched: the guard resolves through\n// this so its own lookups never meet the refusal it installs below.\nconst nativeLookup = originalOf<NativeLookup>(dns, \"lookup\");\n\n// c-ares, which owns its sockets and never passes through dgram or connect.\n\n// A query is a channel out on its own — the data rides in the name — so the\n// answer is irrelevant and the whole surface is refused under a policy.\nconst RESOLVER_METHODS = [\n \"resolve\",\n \"resolve4\",\n \"resolve6\",\n \"resolveAny\",\n \"resolveCaa\",\n \"resolveCname\",\n \"resolveMx\",\n \"resolveNaptr\",\n \"resolveNs\",\n \"resolvePtr\",\n \"resolveSoa\",\n \"resolveSrv\",\n \"resolveTxt\",\n \"reverse\",\n];\n\nexport function isPrivateAddress(value: string): boolean {\n const address = parseAddress(value);\n // An address we cannot classify counts as private: fail closed.\n if (!address) return true;\n if (IPV4_COMPATIBLE.check(address, familyOf(address))) return true;\n return ssrfIpClassifier.isBlockedIp({ ip: address, allowList: [] });\n}\n\ninterface CompiledPolicy {\n hosts: string[] | undefined;\n addresses: net.BlockList | undefined;\n ports: number[] | undefined;\n allowPrivate: boolean;\n}\n\nfunction compile(policy: EgressPolicy): CompiledPolicy {\n const hosts = policy.allowHosts?.map((host) => host.trim().toLowerCase());\n const ports = policy.allowPorts?.map((port) => {\n if (!Number.isInteger(port) || port < 0 || port > 65535) {\n throw new Error(`Egress policy port ${String(port)} is out of range`);\n }\n return port;\n });\n const specs = policy.allowAddresses ?? [];\n const addresses = new net.BlockList();\n for (const spec of specs) addAllowedAddress(addresses, spec);\n return {\n hosts: hosts && hosts.length > 0 ? hosts : undefined,\n addresses: specs.length > 0 ? addresses : undefined,\n ports: ports && ports.length > 0 ? ports : undefined,\n allowPrivate: policy.allowPrivateAddresses === true,\n };\n}\n\nfunction hostAllowed(policy: CompiledPolicy, host: string): boolean {\n if (!policy.hosts) return true;\n const name = host.toLowerCase();\n return policy.hosts.some((entry) =>\n entry.startsWith(\"*.\")\n ? name.length > entry.length - 1 && name.endsWith(entry.slice(1))\n : entry === name,\n );\n}\n\nfunction addressAllowed(policy: CompiledPolicy, address: string): boolean {\n const ip = parseAddress(address);\n if (!ip) return false;\n if (policy.addresses?.check(ip, familyOf(ip))) return true;\n return policy.allowPrivate || !isPrivateAddress(ip);\n}\n\n// The policy of the request in flight, and the one the work started under: both\n// apply, so a pooled client's callback chain cannot borrow a laxer context.\n\n// A piece's leftover timer keeps the policy it was created with rather than\n// whatever the next request brings.\nlet inFlight: CompiledPolicy | undefined;\nconst started = new AsyncLocalStorage<CompiledPolicy | undefined>();\n\nfunction policiesInForce(): CompiledPolicy[] {\n const inherited = started.getStore();\n const policies: CompiledPolicy[] = [];\n if (inFlight) policies.push(inFlight);\n if (inherited && inherited !== inFlight) policies.push(inherited);\n return policies;\n}\n\n// Runs one request under its policy. Compiling first means a malformed policy\n// fails the request rather than degrading it to no enforcement.\nexport async function runWithEgressPolicy<T>(\n policy: EgressPolicy | undefined,\n work: () => Promise<T>,\n): Promise<T> {\n const compiled = policy ? compile(policy) : undefined;\n installEgressGuard();\n inFlight = compiled;\n try {\n return await started.run(compiled, work);\n } finally {\n // The request is over; what it left running keeps the policy it inherited,\n // so it can never become less restricted than it started.\n if (inFlight === compiled) inFlight = undefined;\n }\n}\n\ninterface ConnectOptions {\n path?: string;\n port?: number | string;\n host?: string;\n lookup?: unknown;\n [key: string]: unknown;\n}\n\n// Node's own connect-argument shapes: (options) | (port[, host]) | (path), plus\n// the pre-normalized [options, callback] array net.createConnection hands over.\nfunction normalizeConnectArgs(args: unknown[]): {\n options: ConnectOptions;\n callback: unknown;\n} {\n if (Array.isArray(args[0])) {\n const [options, callback] = args[0] as [ConnectOptions, unknown];\n return { options: { ...options }, callback };\n }\n const first = args[0];\n let options: ConnectOptions = {};\n if (typeof first === \"object\" && first !== null) {\n options = { ...(first as ConnectOptions) };\n } else if (typeof first === \"string\" && Number.isNaN(Number(first))) {\n options.path = first;\n } else {\n options.port = first as number;\n if (typeof args[1] === \"string\") options.host = args[1];\n }\n const last = args[args.length - 1];\n return { options, callback: typeof last === \"function\" ? last : undefined };\n}\n\ntype LookupResult = { address: string; family: number }[];\n\ntype LookupCallback = (\n error: Error | null,\n address?: string | LookupResult,\n family?: number,\n) => void;\n\n// Classifies the address the socket is about to use, not the name the piece\n// asked for: a name check alone loses to DNS rebinding.\nfunction guardedLookup(\n policies: CompiledPolicy[],\n host: string,\n port: number | undefined,\n): (hostname: string, options: unknown, callback: LookupCallback) => void {\n return (hostname, options, callback) => {\n const asked = options as { all?: boolean };\n nativeLookup(\n hostname,\n options as dns.LookupOneOptions,\n (error: Error | null, result: unknown, family?: number) => {\n if (error) {\n callback(error);\n return;\n }\n try {\n const entries: LookupResult = asked.all\n ? (result as LookupResult)\n : [{ address: result as string, family: family ?? 0 }];\n const permitted = entries.filter((entry) =>\n policies.every((policy) => addressAllowed(policy, entry.address)),\n );\n if (permitted.length === 0) {\n const seen = entries.map((entry) => entry.address).join(\", \");\n callback(\n new EgressDeniedError(\n `host \"${host}\" resolves to ${seen || \"nothing\"}, which the policy does not permit`,\n { host, port, address: entries[0]?.address },\n ),\n );\n return;\n }\n if (asked.all) callback(null, permitted);\n else callback(null, permitted[0].address, permitted[0].family);\n } catch (failure) {\n // A defect in the guard denies the connection, never opens it.\n callback(\n failure instanceof Error ? failure : new Error(String(failure)),\n );\n }\n },\n );\n };\n}\n\nfunction denyReason(\n policies: CompiledPolicy[],\n options: ConnectOptions,\n): EgressDeniedError | undefined {\n if (typeof options.path === \"string\") {\n return new EgressDeniedError(\n `connections to local socket \"${options.path}\" are not permitted`,\n { host: options.path },\n );\n }\n const host = typeof options.host === \"string\" ? options.host : \"\";\n const port = options.port === undefined ? undefined : Number(options.port);\n for (const policy of policies) {\n if (policy.ports && (port === undefined || !policy.ports.includes(port))) {\n return new EgressDeniedError(\n `port ${String(port)} on host \"${host}\" is not permitted`,\n { host, port },\n );\n }\n if (!hostAllowed(policy, host)) {\n return new EgressDeniedError(`host \"${host}\" is not on the allowlist`, {\n host,\n port,\n });\n }\n if (isIP(host) && !addressAllowed(policy, host)) {\n return new EgressDeniedError(`address ${host} is not permitted`, {\n host,\n port,\n address: host,\n });\n }\n }\n return undefined;\n}\n\n// Reports a denial the way Node reports an asynchronous socket failure, so a\n// piece catches it from its client rather than from a synchronous throw.\nfunction failLater(\n emitter: { emit: (event: string, error: Error) => boolean },\n error: EgressDeniedError,\n callback: unknown,\n): void {\n process.nextTick(() => {\n if (typeof callback === \"function\") (callback as (e: Error) => void)(error);\n else emitter.emit(\"error\", error);\n });\n}\n\n// Takes a method off its descriptor rather than as a method reference: what is\n// wanted is the original implementation, re-applied with an explicit `this`.\nfunction originalOf<T>(target: object, name: string): T {\n return Object.getOwnPropertyDescriptor(target, name)?.value as T;\n}\n\nfunction resolverDenial(method: string, args: unknown[]): EgressDeniedError {\n const host = typeof args[0] === \"string\" ? args[0] : \"\";\n return new EgressDeniedError(\n `DNS ${method}(\"${host}\") is not permitted; use a hostname in a request instead`,\n { host },\n );\n}\n\n// Refuses every c-ares entry point on one object, in the shape its callers\n// expect: a rejected promise here, a callback error there.\nfunction refuseResolvers(target: object, promised: boolean): void {\n for (const method of RESOLVER_METHODS) {\n const original = originalOf<(this: unknown, ...args: unknown[]) => unknown>(\n target,\n method,\n );\n if (typeof original !== \"function\") continue;\n function refused(this: unknown, ...args: unknown[]): unknown {\n if (policiesInForce().length === 0) return original.apply(this, args);\n const denied = resolverDenial(method, args);\n if (promised) return Promise.reject(denied);\n const callback = args[args.length - 1];\n // No callback is a programming error Node would throw on anyway.\n if (typeof callback !== \"function\") throw denied;\n process.nextTick(() => (callback as (error: Error) => void)(denied));\n return undefined;\n }\n seal(target, method, refused);\n }\n}\n\n// Sealed so a piece holding the pristine implementation cannot put it back, and\n// so a later assignment cannot quietly unhook the guard.\nfunction seal(target: object, name: string, value: unknown): void {\n Object.defineProperty(target, name, {\n value,\n writable: false,\n configurable: false,\n enumerable: false,\n });\n}\n\nlet installed = false;\n\n// Installed when the worker child starts, before any piece code can run, and a\n// no-op while no policy is in force.\n\n// Not a boundary against hostile code: a child process or a worker thread gets\n// its own copy of these modules. Isolation is a network namespace, not this.\nexport function installEgressGuard(): void {\n if (installed) return;\n installed = true;\n\n const connect = originalOf<\n (this: net.Socket, ...args: unknown[]) => net.Socket\n >(net.Socket.prototype, \"connect\");\n\n function patchedConnect(this: net.Socket, ...args: unknown[]): net.Socket {\n const policies = policiesInForce();\n if (policies.length === 0) return connect.apply(this, args);\n const { options, callback } = normalizeConnectArgs(args);\n // Node defaults a missing host to localhost; write it back so the checks\n // and the guarded lookup below both see what will be dialled.\n if (typeof options.path !== \"string\" && !options.host) {\n options.host = \"localhost\";\n }\n const denied = denyReason(policies, options);\n if (denied) {\n process.nextTick(() => this.destroy(denied));\n return this;\n }\n if (typeof options.host === \"string\" && !isIP(options.host)) {\n options.lookup = guardedLookup(\n policies,\n options.host,\n options.port === undefined ? undefined : Number(options.port),\n );\n }\n return connect.call(this, options, callback);\n }\n seal(net.Socket.prototype, \"connect\", patchedConnect);\n\n // The dgram surface carries no destination a policy can usefully allow — a\n // piece's work is HTTP — so it is refused whole, as is c-ares further down.\n const send = originalOf<(this: dgram.Socket, ...args: unknown[]) => void>(\n dgram.Socket.prototype,\n \"send\",\n );\n function patchedSend(this: dgram.Socket, ...args: unknown[]): void {\n if (policiesInForce().length === 0) {\n send.apply(this, args);\n return;\n }\n const host = args.find(\n (arg, index) => index > 0 && typeof arg === \"string\",\n ) as string | undefined;\n const last = args[args.length - 1];\n failLater(\n this,\n new EgressDeniedError(\n `UDP to \"${host ?? \"the requested address\"}\" is not permitted`,\n { host: host ?? \"\" },\n ),\n typeof last === \"function\" ? last : undefined,\n );\n }\n seal(dgram.Socket.prototype, \"send\", patchedSend);\n\n // Inbound is refused for the same reason: a delivery reaches a workflow\n // through the host's webhook endpoint, never a port the piece opened.\n const bind = originalOf<\n (this: dgram.Socket, ...args: unknown[]) => dgram.Socket\n >(dgram.Socket.prototype, \"bind\");\n function patchedBind(this: dgram.Socket, ...args: unknown[]): dgram.Socket {\n if (policiesInForce().length === 0) return bind.apply(this, args);\n failLater(\n this,\n new EgressDeniedError(\"binding a UDP socket is not permitted\", {\n host: \"\",\n }),\n undefined,\n );\n return this;\n }\n seal(dgram.Socket.prototype, \"bind\", patchedBind);\n\n const listen = originalOf<\n (this: net.Server, ...args: unknown[]) => net.Server\n >(net.Server.prototype, \"listen\");\n function patchedListen(this: net.Server, ...args: unknown[]): net.Server {\n if (policiesInForce().length === 0) return listen.apply(this, args);\n failLater(\n this,\n new EgressDeniedError(\"listening for connections is not permitted\", {\n host: \"\",\n }),\n undefined,\n );\n return this;\n }\n seal(net.Server.prototype, \"listen\", patchedListen);\n\n // The four objects a piece can reach c-ares through; dns.lookup is\n // getaddrinfo and stays open, guarded per connect instead.\n refuseResolvers(dns, false);\n refuseResolvers(dns.Resolver.prototype, false);\n refuseResolvers(dns.promises, true);\n refuseResolvers(dns.promises.Resolver.prototype, true);\n}\n\n// True for a denial raised in the child, including one a piece's client\n// re-wrapped: axios copies `code`, undici keeps the original as `cause`.\nexport function isEgressDenied(error: unknown): boolean {\n const seen = new Set<unknown>();\n let candidate: unknown = error;\n // Wrappers nest, and some of them produce a cycle; the walk is bounded by\n // the seen set and by a depth no honest chain reaches.\n for (let depth = 0; depth < 16; depth++) {\n if (candidate instanceof EgressDeniedError) return true;\n if (typeof candidate !== \"object\" || candidate === null) return false;\n if (seen.has(candidate)) return false;\n seen.add(candidate);\n const fields = candidate as {\n name?: unknown;\n code?: unknown;\n message?: unknown;\n cause?: unknown;\n properties?: { code?: unknown };\n serialized?: { name?: unknown; properties?: { code?: unknown } };\n };\n const codes = [\n fields.code,\n fields.properties?.code,\n fields.serialized?.properties?.code,\n ];\n if (codes.includes(EGRESS_DENIED_CODE)) return true;\n if (fields.name === \"EgressDeniedError\") return true;\n if (fields.serialized?.name === \"EgressDeniedError\") return true;\n if (\n typeof fields.message === \"string\" &&\n fields.message.includes(\"Egress denied:\")\n ) {\n return true;\n }\n candidate = fields.cause;\n }\n return false;\n}\n","// Credential redaction for anything that gets journaled or shown to a user.\n// Two independent passes, because each catches what the other misses.\n\n// Key-based catches a credential the run never knew about: a piece's own\n// hardcoded key, a token it fetched mid-step.\n\n// Value-based catches a secret the run did resolve, wherever a piece spliced\n// it — into a message, a URL, a header it composed itself.\n\nexport const REDACTED_PREFIX = \"[redacted:\";\nexport const SECRET_MARKER = \"[redacted:secret]\";\nexport const CIRCULAR_MARKER = \"[circular]\";\nexport const TRUNCATED_MARKER = \"[truncated]\";\n\n// Bounds for the hostile-error path only. Ordinary step output is data a user\n// asked for, so it is redacted whole rather than truncated.\nconst ERROR_MAX_DEPTH = 8;\nconst ERROR_MAX_NODES = 1000;\n\n// Deep enough never to be reached by real data, shallow enough that the\n// recursive walk cannot overflow the stack on a self-nesting object.\nconst STACK_GUARD_DEPTH = 200;\n\n// Exact names, matched after stripping separators and case: \"X-Api-Key\",\n// \"x_api_key\" and \"apiKey\" are one name.\nconst SENSITIVE_NAMES = new Set([\n \"auth\",\n \"authorization\",\n \"proxyauthorization\",\n \"wwwauthenticate\",\n \"authtoken\",\n \"xauthtoken\",\n \"apikey\",\n \"xapikey\",\n \"apisecret\",\n \"bearer\",\n \"cookie\",\n \"setcookie\",\n \"credential\",\n \"credentials\",\n \"password\",\n \"passwd\",\n \"passphrase\",\n \"pwd\",\n \"privatekey\",\n \"secret\",\n \"secrettext\",\n \"sessionid\",\n \"signature\",\n \"token\",\n]);\n\n// A name ending in one of these is sensitive whatever prefixes it, which is\n// what catches githubToken, client_secret and the rest of the long tail.\nconst SENSITIVE_SUFFIXES = [\n \"apikey\",\n \"credentials\",\n \"password\",\n \"privatekey\",\n \"secret\",\n \"token\",\n];\n\n// Header and field names worth redacting inside a free-form string, where\n// there is no key to walk.\n\n// Deliberately a fixed list: a loose pattern over prose eats more of the\n// message than it saves.\n\n// Signature is the one alternative that carries its own affixes, because a\n// webhook MAC header wraps the word: x-hub-signature-256.\nconst TEXT_FIELD = new RegExp(\n String.raw`\\b(authorization|proxy-authorization|api[-_]?key|x-api-key|access[-_]?token|refresh[-_]?token|client[-_]?secret|set-cookie|cookie|password|secret|token|(?:[a-z0-9]+[-_])*signature(?:[-_][a-z0-9]+)*)\\b([\"']?)(\\s*[:=]\\s*)([\"']?)((?:(?:Bearer|Basic|Token)\\s+)?[^\\s\",;&)}]+)\\4`,\n \"gi\",\n);\n\nconst AUTH_SCHEME = /\\b(Bearer|Basic|Token)\\s+([A-Za-z0-9._~+/=-]{8,})/g;\n\nconst QUERY_PARAM = /([?&])([A-Za-z0-9_.%[\\]-]+)=([^&\\s\"'<>]+)/g;\n\n// The password half of a URL's userinfo, which no header or query pattern\n// reaches: https://user:s3cret@host/api.\nconst URL_USERINFO = /([a-z][a-z0-9+.-]*:\\/\\/)([^/\\s:@]+):([^/\\s@]+)@/gi;\n\nexport function normalizeName(name: string): string {\n return name.toLowerCase().replace(/[^a-z0-9]/g, \"\");\n}\n\nexport function isSensitiveName(name: string): boolean {\n const normalized = normalizeName(name);\n if (!normalized) return false;\n if (SENSITIVE_NAMES.has(normalized)) return true;\n // Anywhere in the name, because a webhook MAC header carries its algorithm\n // after it: x-hub-signature-256.\n if (normalized.includes(\"signature\")) return true;\n return SENSITIVE_SUFFIXES.some(\n (suffix) =>\n normalized.length > suffix.length && normalized.endsWith(suffix),\n );\n}\n\nfunction marker(name: string): string {\n return `[redacted:${name.toLowerCase()}]`;\n}\n\nfunction shannonEntropy(text: string): number {\n const counts = new Map<string, number>();\n for (const char of text) counts.set(char, (counts.get(char) ?? 0) + 1);\n let entropy = 0;\n for (const count of counts.values()) {\n const p = count / text.length;\n entropy -= p * Math.log2(p);\n }\n return entropy;\n}\n\n// The bar a *guessed* secret must clear before its value is matched anywhere.\n\n// A short or repetitive guess (\"admin\", \"8080\", \"aaaaaaaa\") would hit unrelated\n// text and leave an error nobody can read; the key-based pass still covers it.\nconst MIN_VALUE_LENGTH = 8;\nconst MIN_DISTINCT_CHARS = 5;\nconst MIN_ENTROPY_BITS = 2;\n\n// A value the host hands over is a declaration, not a guess, so \"hunter2\" is\n// redacted. Only a value too short to be a credential is refused.\nconst MIN_DECLARED_LENGTH = 4;\n\nexport function isRedactableValue(value: unknown): value is string {\n if (typeof value !== \"string\") return false;\n if (value.length < MIN_VALUE_LENGTH) return false;\n if (new Set(value).size < MIN_DISTINCT_CHARS) return false;\n return shannonEntropy(value) >= MIN_ENTROPY_BITS;\n}\n\nexport function isDeclaredValue(value: unknown): value is string {\n return typeof value === \"string\" && value.length >= MIN_DECLARED_LENGTH;\n}\n\n// The AppConnectionValue discriminator, and anything shaped like an endpoint.\n\n// Both are configuration rather than credentials, and a URL is usually the\n// most useful thing left in a failed request's error.\nconst STRUCTURAL_NAMES = new Set([\"type\", \"authtype\"]);\nconst URL_LIKE = /^[a-z][a-z0-9+.-]*:\\/\\//i;\n\n// Every credential-shaped string leaf of a resolved connection. The fallback\n// for a host resolver that cannot say which of its values are secret.\nexport function collectSecretValues(\n value: unknown,\n into: Set<string> = new Set(),\n depth = 0,\n): Set<string> {\n if (depth > ERROR_MAX_DEPTH) return into;\n if (isRedactableValue(value)) {\n if (!URL_LIKE.test(value)) into.add(value);\n return into;\n }\n if (Array.isArray(value)) {\n for (const entry of value) collectSecretValues(entry, into, depth + 1);\n return into;\n }\n if (typeof value === \"object\" && value !== null) {\n for (const [key, entry] of Object.entries(value)) {\n if (STRUCTURAL_NAMES.has(normalizeName(key))) continue;\n collectSecretValues(entry, into, depth + 1);\n }\n }\n return into;\n}\n\nexport interface RedactOptions {\n // Concrete secret values resolved for this step; each occurrence is replaced.\n values?: Iterable<string>;\n maxDepth?: number;\n maxNodes?: number;\n}\n\n// A host-side handle from a thrown error to the secrets its step ran with, so\n// a catch far from the connection can still redact by value.\nconst thrownSecrets = new WeakMap<object, string[]>();\n\nexport function rememberSecrets<T>(error: T, values: string[]): T {\n if (typeof error === \"object\" && error !== null && values.length > 0) {\n thrownSecrets.set(error, values);\n }\n return error;\n}\n\nexport function secretsFor(error: unknown): string[] {\n if (typeof error !== \"object\" || error === null) return [];\n return thrownSecrets.get(error) ?? [];\n}\n\ninterface Pass {\n values: string[];\n maxDepth: number;\n maxNodes: number;\n nodes: number;\n}\n\n// Longest first, so a secret that contains another is replaced whole rather\n// than leaving its tail behind.\nfunction preparePass(options: RedactOptions | undefined): Pass {\n const values = [...(options?.values ?? [])]\n .filter(isDeclaredValue)\n .sort((a, b) => b.length - a.length);\n return {\n values,\n maxDepth: options?.maxDepth ?? STACK_GUARD_DEPTH,\n maxNodes: options?.maxNodes ?? Number.POSITIVE_INFINITY,\n nodes: 0,\n };\n}\n\nfunction safeDecode(name: string): string {\n try {\n return decodeURIComponent(name);\n } catch {\n return name;\n }\n}\n\nfunction replaceValues(text: string, values: string[]): string {\n let result = text;\n for (const value of values) {\n if (result.includes(value)) {\n result = result.split(value).join(SECRET_MARKER);\n }\n const encoded = encodeURIComponent(value);\n if (encoded !== value && result.includes(encoded)) {\n result = result.split(encoded).join(SECRET_MARKER);\n }\n }\n return result;\n}\n\nfunction redactText(text: string, pass: Pass): string {\n let result = replaceValues(text, pass.values);\n result = result.replace(\n URL_USERINFO,\n (_match, scheme: string, user: string) =>\n `${scheme}${user}:${marker(\"password\")}@`,\n );\n result = result.replace(QUERY_PARAM, (match, sep: string, name: string) =>\n isSensitiveName(safeDecode(name)) ? `${sep}${name}=${marker(name)}` : match,\n );\n result = result.replace(\n AUTH_SCHEME,\n (_match, scheme: string) => `${scheme} ${marker(scheme)}`,\n );\n\n // Skipping a value that is already a marker keeps this pass from re-matching\n // what the query pass just wrote and swallowing the rest of the string.\n return result.replace(\n TEXT_FIELD,\n (\n match,\n name: string,\n nameQuote: string,\n sep: string,\n quote: string,\n value: string,\n ) =>\n value.startsWith(REDACTED_PREFIX)\n ? match\n : `${name}${nameQuote}${sep}${quote}${marker(name)}${quote}`,\n );\n}\n\nfunction walk(\n value: unknown,\n pass: Pass,\n depth: number,\n seen: Set<object>,\n): unknown {\n if (typeof value === \"string\") return redactText(value, pass);\n if (typeof value !== \"object\" || value === null) return value;\n if (seen.has(value)) return CIRCULAR_MARKER;\n if (depth >= pass.maxDepth) return TRUNCATED_MARKER;\n if (pass.nodes >= pass.maxNodes) return TRUNCATED_MARKER;\n pass.nodes += 1;\n\n // Tracked per path, not globally: the same object appearing twice in a tree\n // is not a cycle, and calling it one would drop data a user needs.\n seen.add(value);\n try {\n if (Array.isArray(value)) {\n return value.map((entry) => walk(entry, pass, depth + 1, seen));\n }\n const result: Record<string, unknown> = {};\n for (const [key, entry] of Object.entries(value)) {\n result[key] = isSensitiveName(key)\n ? marker(key)\n : walk(entry, pass, depth + 1, seen);\n }\n return result;\n } finally {\n seen.delete(value);\n }\n}\n\n// Redacts credentials from an arbitrary value: sensitive keys by name, known\n// secret values wherever they appear, sensitive URL query parameters.\n\n// Cycles are collapsed; nothing else is dropped, because this also runs over\n// step output a user asked to see.\nexport function redact(value: unknown, options?: RedactOptions): unknown {\n return walk(value, preparePass(options), 0, new Set());\n}\n\n// The same pass for an error object, which is attacker-shaped: depth and node\n// count are capped so a hostile error cannot make redaction expensive.\nexport function redactError(value: unknown, options?: RedactOptions): unknown {\n return redact(value, {\n maxDepth: ERROR_MAX_DEPTH,\n maxNodes: ERROR_MAX_NODES,\n ...options,\n });\n}\n\n// True when a value carries a marker this module wrote. Rerun uses it to\n// refuse a journaled output it cannot faithfully replay.\nexport function containsRedactedMarker(value: unknown, depth = 0): boolean {\n if (typeof value === \"string\") return value.includes(REDACTED_PREFIX);\n if (typeof value !== \"object\" || value === null) return false;\n if (depth >= STACK_GUARD_DEPTH) return false;\n return Object.values(value).some((entry) =>\n containsRedactedMarker(entry, depth + 1),\n );\n}\n\n// The string-only form, for a message that is already flat text.\nexport function redactMessage(text: string, options?: RedactOptions): string {\n return redactText(text, preparePass(options));\n}\n"],"mappings":"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"}
@@ -0,0 +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";
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 };
@@ -0,0 +1,4 @@
1
+ import { f as extractDedupeKey } from "./redact-C7LWgAyD.js";
2
+ import { S as localFirstResolver, T as fetchPieceBundle, a as CompositeBlockExecutor, i as ActivepiecesBlockExecutor, p as InMemorySecretProvider, r as runWorkflow, t as PieceRegistry, u as StaticConnectionResolver, v as PieceWorkerPool, w as ensurePieceBundle, y as PieceWorker } from "./piece-registry-BWWihLyp.js";
3
+ import { i as loadPieceFromDir, t as buildDescriptor } from "./descriptor-DXbWuxhE.js";
4
+ export { ActivepiecesBlockExecutor, CompositeBlockExecutor, InMemorySecretProvider, PieceRegistry, PieceWorker, PieceWorkerPool, StaticConnectionResolver, buildDescriptor, ensurePieceBundle, extractDedupeKey, fetchPieceBundle, loadPieceFromDir, localFirstResolver, runWorkflow };
@@ -0,0 +1 @@
1
+ export { };