Merge upstream/master into dev (13 commits — includes #5922, #5938, blocked inbox, recovery actions)
This commit is contained in:
@@ -420,6 +420,12 @@ export interface ManagedRoutineMissingRef {
|
||||
resourceKey: string;
|
||||
}
|
||||
|
||||
export interface ManagedRoutineDefaultDrift {
|
||||
changedFields: string[];
|
||||
defaultTitle?: string | null;
|
||||
defaultDescription?: string | null;
|
||||
}
|
||||
|
||||
export interface ManagedRoutinesListItem {
|
||||
key: string;
|
||||
title: string;
|
||||
@@ -434,6 +440,7 @@ export interface ManagedRoutinesListItem {
|
||||
lastRunStatus?: string | null;
|
||||
managedByPluginDisplayName?: string | null;
|
||||
missingRefs?: ManagedRoutineMissingRef[];
|
||||
defaultDrift?: ManagedRoutineDefaultDrift | null;
|
||||
}
|
||||
|
||||
export interface ManagedRoutinesListProps {
|
||||
|
||||
@@ -34,6 +34,7 @@
|
||||
* @see PLUGIN_SPEC.md §14 — SDK Surface
|
||||
*/
|
||||
|
||||
import fs from "node:fs";
|
||||
import path from "node:path";
|
||||
import { createInterface, type Interface as ReadlineInterface } from "node:readline";
|
||||
import { fileURLToPath } from "node:url";
|
||||
@@ -175,6 +176,21 @@ interface EventRegistration {
|
||||
/** Default timeout for worker→host RPC calls. */
|
||||
const DEFAULT_RPC_TIMEOUT_MS = 30_000;
|
||||
|
||||
function realpathOrResolvedPath(filePath: string): string {
|
||||
const resolvedPath = path.resolve(filePath);
|
||||
try {
|
||||
return fs.realpathSync.native(resolvedPath);
|
||||
} catch {
|
||||
return resolvedPath;
|
||||
}
|
||||
}
|
||||
|
||||
export function isWorkerEntrypoint(entry: string, moduleUrl: string): boolean {
|
||||
const thisFile = realpathOrResolvedPath(fileURLToPath(moduleUrl));
|
||||
const entryPath = realpathOrResolvedPath(entry);
|
||||
return thisFile === entryPath;
|
||||
}
|
||||
|
||||
// ---------------------------------------------------------------------------
|
||||
// startWorkerRpcHost
|
||||
// ---------------------------------------------------------------------------
|
||||
@@ -223,9 +239,7 @@ export function runWorker(
|
||||
}
|
||||
const entry = process.argv[1];
|
||||
if (typeof entry !== "string") return;
|
||||
const thisFile = path.resolve(fileURLToPath(moduleUrl));
|
||||
const entryPath = path.resolve(entry);
|
||||
if (thisFile === entryPath) {
|
||||
if (isWorkerEntrypoint(entry, moduleUrl)) {
|
||||
startWorkerRpcHost({ plugin });
|
||||
}
|
||||
}
|
||||
|
||||
@@ -0,0 +1,57 @@
|
||||
import fs from "node:fs";
|
||||
import os from "node:os";
|
||||
import path from "node:path";
|
||||
import { pathToFileURL } from "node:url";
|
||||
|
||||
import { afterEach, describe, expect, it } from "vitest";
|
||||
|
||||
import { isWorkerEntrypoint } from "../src/worker-rpc-host.js";
|
||||
|
||||
describe("isWorkerEntrypoint", () => {
|
||||
const tempRoots: string[] = [];
|
||||
|
||||
afterEach(() => {
|
||||
for (const tempRoot of tempRoots.splice(0)) {
|
||||
fs.rmSync(tempRoot, { recursive: true, force: true });
|
||||
}
|
||||
});
|
||||
|
||||
function createTempRoot(): string {
|
||||
const tempRoot = fs.mkdtempSync(path.join(os.tmpdir(), "paperclip-sdk-worker-"));
|
||||
tempRoots.push(tempRoot);
|
||||
return tempRoot;
|
||||
}
|
||||
|
||||
it("matches an entrypoint reached through a symlinked directory", () => {
|
||||
const tempRoot = createTempRoot();
|
||||
const realDir = path.join(tempRoot, "real");
|
||||
const linkDir = path.join(tempRoot, "link");
|
||||
fs.mkdirSync(realDir);
|
||||
fs.symlinkSync(realDir, linkDir, "dir");
|
||||
|
||||
const workerPath = path.join(realDir, "worker.js");
|
||||
fs.writeFileSync(workerPath, "");
|
||||
|
||||
expect(
|
||||
isWorkerEntrypoint(
|
||||
path.join(linkDir, "worker.js"),
|
||||
pathToFileURL(workerPath).toString(),
|
||||
),
|
||||
).toBe(true);
|
||||
});
|
||||
|
||||
it("does not match a different entrypoint", () => {
|
||||
const tempRoot = createTempRoot();
|
||||
const workerPath = path.join(tempRoot, "worker.js");
|
||||
const otherPath = path.join(tempRoot, "other.js");
|
||||
fs.writeFileSync(workerPath, "");
|
||||
fs.writeFileSync(otherPath, "");
|
||||
|
||||
expect(
|
||||
isWorkerEntrypoint(
|
||||
otherPath,
|
||||
pathToFileURL(workerPath).toString(),
|
||||
),
|
||||
).toBe(false);
|
||||
});
|
||||
});
|
||||
@@ -0,0 +1,8 @@
|
||||
import { defineConfig } from "vitest/config";
|
||||
|
||||
export default defineConfig({
|
||||
test: {
|
||||
environment: "node",
|
||||
include: ["tests/**/*.test.ts"],
|
||||
},
|
||||
});
|
||||
Reference in New Issue
Block a user