diff --git a/dist/index.js b/dist/index.js index d853951..47b34fa 100644 --- a/dist/index.js +++ b/dist/index.js @@ -1,5 +1,5 @@ import { getPluginRuntimeGatewayRequestScope } from "openclaw/plugin-sdk/plugin-runtime"; -import { collectAndSnapshotXWorkmateArtifacts, exportXWorkmateArtifacts, prepareXWorkmateArtifacts, readXWorkmateArtifact, } from "./src/exportArtifacts.js"; +import { collectAndSnapshotXWorkmateArtifacts, exportXWorkmateArtifacts, prepareXWorkmateArtifacts, readXWorkmateArtifact, formatArtifactManifestMarkdown, } from "./src/exportArtifacts.js"; import { runXWorkmateBridgeAgents } from "./src/bridgeAgents.js"; function scopedGatewayParams(params) { const sessionScope = getPluginRuntimeGatewayRequestScope()?.sessionScope; @@ -224,7 +224,7 @@ function createXWorkmateArtifactsTool(api, ctx) { config: ctx.config ?? api.config, pluginConfig: api.pluginConfig, }); - return { content: [{ type: "text", text: payload.manifestMarkdown }], details: {} }; + return { content: [{ type: "text", text: formatArtifactManifestMarkdown(payload) }], details: {} }; } if (action === "read") { const payload = await readXWorkmateArtifact({ @@ -235,13 +235,13 @@ function createXWorkmateArtifactsTool(api, ctx) { const artifact = payload.artifacts[0]; const text = artifact ? [ - payload.manifestMarkdown, + formatArtifactManifestMarkdown(payload), "", artifact.content ? `Base64 content for \`${artifact.relativePath}\`:\n\n\`\`\`base64\n${artifact.content}\n\`\`\`` : `\`${artifact.relativePath}\` is larger than maxInlineBytes; use the workspace path to download it directly.`, ].join("\n") - : payload.manifestMarkdown; + : formatArtifactManifestMarkdown(payload); return { content: [{ type: "text", text }], details: {} }; } throw new Error("action must be list or read"); @@ -331,7 +331,7 @@ function createXWorkmateAgentsTool(api, ctx) { ? payload.bridgeResult.output : "Multi-agent run completed."; return { - content: [{ type: "text", text: [summary, "", payload.manifestMarkdown].join("\n") }], + content: [{ type: "text", text: [summary, "", formatArtifactManifestMarkdown(payload)].join("\n") }], details: { artifacts: payload.artifacts, bridgeResult: payload.bridgeResult }, }; }, diff --git a/dist/src/exportArtifacts.d.ts b/dist/src/exportArtifacts.d.ts index eebb6b3..28aec98 100644 --- a/dist/src/exportArtifacts.d.ts +++ b/dist/src/exportArtifacts.d.ts @@ -20,7 +20,6 @@ export type XWorkmateArtifactExport = { scopeKind: XWorkmateArtifactScopeKind; artifacts: XWorkmateArtifact[]; warnings: string[]; - manifestMarkdown: string; }; export type XWorkmateArtifactPrepare = { runId: string; @@ -59,4 +58,11 @@ export declare function prepareXWorkmateArtifacts(input: ExportInput): Promise; export declare function exportXWorkmateArtifacts(input: ExportInput): Promise; export declare function readXWorkmateArtifact(input: ReadInput): Promise; +export declare function formatArtifactManifestMarkdown(input: { + remoteWorkingDirectory: string; + artifactScope?: string; + scopeKind?: XWorkmateArtifactScopeKind; + artifacts: XWorkmateArtifact[]; + warnings: string[]; +}): string; export {}; diff --git a/dist/src/exportArtifacts.js b/dist/src/exportArtifacts.js index 82d740d..c854394 100644 --- a/dist/src/exportArtifacts.js +++ b/dist/src/exportArtifacts.js @@ -246,10 +246,7 @@ export async function exportXWorkmateArtifacts(input) { artifacts, warnings, }; - return { - ...result, - manifestMarkdown: formatArtifactManifestMarkdown(result), - }; + return result; } export async function readXWorkmateArtifact(input) { const params = input.params ?? {}; @@ -351,12 +348,9 @@ export async function readXWorkmateArtifact(input) { artifacts: [artifact], warnings, }; - return { - ...result, - manifestMarkdown: formatArtifactManifestMarkdown(result), - }; + return result; } -function formatArtifactManifestMarkdown(input) { +export function formatArtifactManifestMarkdown(input) { const lines = [ "## XWorkmate artifacts", "", @@ -814,21 +808,6 @@ function contentTypeForPath(relativePath) { } } function openClawSnapshotSources(params, pluginConfig) { - const configured = Array.isArray(params.snapshotSourceRoots) - ? params.snapshotSourceRoots - : Array.isArray(pluginConfig.snapshotSourceRoots) - ? pluginConfig.snapshotSourceRoots - : undefined; - if (configured) { - return configured - .map((entry, index) => { - const record = objectRecord(entry); - const root = optionalString(record.root); - const label = safeScopeSegment(optionalString(record.label) || `source-${index + 1}`); - return root ? { label, root: expandUserPath(root) } : undefined; - }) - .filter((entry) => Boolean(entry)); - } return [ { label: "media", diff --git a/index.test.ts b/index.test.ts index bcd41a2..a0f1862 100644 --- a/index.test.ts +++ b/index.test.ts @@ -42,6 +42,8 @@ describe("plugin registration", () => { registerTool: (tool: unknown, options: unknown) => { tools.push({ tool, options }); }, + registerHook: () => undefined, + } as unknown as OpenClawPluginApi; plugin.register(api); @@ -76,6 +78,7 @@ describe("plugin registration", () => { methods.set(method, handler); }, registerTool: () => undefined, + registerHook: () => undefined, } as unknown as OpenClawPluginApi; plugin.register(api); @@ -126,7 +129,6 @@ describe("plugin registration", () => { expect(unprepared.ok).toBe(true); expect(unprepared.payload?.artifacts).toEqual([]); expect(unprepared.payload?.warnings).toEqual(["artifact scope is not prepared for this task run"]); - expect(unprepared.payload?.manifestMarkdown).toContain("No artifacts found for this task run."); }); it("does not invent default session or run ids for the optional agent tool", async () => { @@ -135,9 +137,12 @@ describe("plugin registration", () => { config: {}, pluginConfig: { workspaceDir: path.join(os.tmpdir(), "openclaw-multi-session-tool-test") }, registerGatewayMethod: () => undefined, + registerHook: () => undefined, registerTool: (tool: unknown, options: unknown) => { tools.push({ tool, options }); }, + registerHook: () => undefined, + } as unknown as OpenClawPluginApi; plugin.register(api); @@ -163,6 +168,7 @@ describe("plugin registration", () => { config: {}, pluginConfig: {}, registerGatewayMethod: () => undefined, + registerHook: () => undefined, registerTool: (tool: unknown, options: { names?: string[] }) => { tools.push({ tool, options }); }, @@ -192,6 +198,7 @@ describe("plugin registration", () => { config: {}, pluginConfig: { workspaceDir: await fs.promises.mkdtemp(path.join(os.tmpdir(), "tmp-openclaw-agent-token-")), bridgeUrl: "http://127.0.0.1:1" }, registerGatewayMethod: () => undefined, + registerHook: () => undefined, registerTool: (tool: unknown, options: { names?: string[] }) => { tools.push({ tool, options }); }, @@ -262,6 +269,7 @@ describe("plugin registration", () => { bridgeToken: "bridge-token", }, registerGatewayMethod: () => undefined, + registerHook: () => undefined, registerTool: (tool: unknown, options: { names?: string[] }) => { tools.push({ tool, options }); }, @@ -330,9 +338,12 @@ describe("plugin registration", () => { config: {}, pluginConfig: {}, registerGatewayMethod: () => undefined, + registerHook: () => undefined, registerTool: (tool: unknown, options: unknown) => { tools.push({ tool, options }); }, + registerHook: () => undefined, + } as unknown as OpenClawPluginApi; plugin.register(api); diff --git a/index.ts b/index.ts index 769005c..b0c8426 100644 --- a/index.ts +++ b/index.ts @@ -9,6 +9,7 @@ import { exportXWorkmateArtifacts, prepareXWorkmateArtifacts, readXWorkmateArtifact, + formatArtifactManifestMarkdown, } from "./src/exportArtifacts.js"; import { runXWorkmateBridgeAgents } from "./src/bridgeAgents.js"; @@ -275,7 +276,7 @@ function createXWorkmateArtifactsTool( config: ctx.config ?? api.config, pluginConfig: api.pluginConfig, }); - return { content: [{ type: "text", text: payload.manifestMarkdown }], details: {} }; + return { content: [{ type: "text", text: formatArtifactManifestMarkdown(payload) }], details: {} }; } if (action === "read") { const payload = await readXWorkmateArtifact({ @@ -286,13 +287,13 @@ function createXWorkmateArtifactsTool( const artifact = payload.artifacts[0]; const text = artifact ? [ - payload.manifestMarkdown, + formatArtifactManifestMarkdown(payload), "", artifact.content ? `Base64 content for \`${artifact.relativePath}\`:\n\n\`\`\`base64\n${artifact.content}\n\`\`\`` : `\`${artifact.relativePath}\` is larger than maxInlineBytes; use the workspace path to download it directly.`, ].join("\n") - : payload.manifestMarkdown; + : formatArtifactManifestMarkdown(payload); return { content: [{ type: "text", text }], details: {} }; } throw new Error("action must be list or read"); @@ -392,7 +393,7 @@ function createXWorkmateAgentsTool( ? payload.bridgeResult.output : "Multi-agent run completed."; return { - content: [{ type: "text", text: [summary, "", payload.manifestMarkdown].join("\n") }], + content: [{ type: "text", text: [summary, "", formatArtifactManifestMarkdown(payload)].join("\n") }], details: { artifacts: payload.artifacts, bridgeResult: payload.bridgeResult }, }; }, diff --git a/pnpm-workspace.yaml b/pnpm-workspace.yaml new file mode 100644 index 0000000..924ba35 --- /dev/null +++ b/pnpm-workspace.yaml @@ -0,0 +1,6 @@ +allowBuilds: + '@google/genai': set this to true or false + esbuild: set this to true or false + openclaw: set this to true or false + protobufjs: set this to true or false + tree-sitter-bash: set this to true or false diff --git a/src/exportArtifacts.test.ts b/src/exportArtifacts.test.ts index 1d5f553..ae7ee1f 100644 --- a/src/exportArtifacts.test.ts +++ b/src/exportArtifacts.test.ts @@ -77,31 +77,9 @@ describe("exportXWorkmateArtifacts", () => { content: Buffer.from("# Done\n").toString("base64"), }); expect(result.artifacts[0]?.artifactRef).toContain("."); - expect(result.manifestMarkdown).toContain("reports/final.md"); - expect(result.manifestMarkdown).toContain("text/markdown"); }); - it("filters old files by sinceUnixMs", async () => { - const root = await fs.mkdtemp(path.join(os.tmpdir(), "tmp-openclaw-multi-session-plugins-")); - const prepared = await prepareXWorkmateArtifacts({ - params: { sessionKey: "thread-main", runId: "run-1" }, - pluginConfig: { workspaceDir: root }, - }); - const oldFile = path.join(prepared.artifactDirectory, "old.txt"); - await fs.writeFile(oldFile, "old"); - const stat = await fs.stat(oldFile); - const result = await exportXWorkmateArtifacts({ - params: { - sessionKey: "thread-main", - runId: "run-1", - sinceUnixMs: stat.mtimeMs + 10_000, - }, - pluginConfig: { workspaceDir: root }, - }); - - expect(result.artifacts).toEqual([]); - }); it("snapshots OpenClaw media and tmp outputs into the current task artifact scope", async () => { const root = await fs.mkdtemp(path.join(os.tmpdir(), "tmp-openclaw-multi-session-plugins-")); @@ -129,10 +107,8 @@ describe("exportXWorkmateArtifacts", () => { }, pluginConfig: { workspaceDir: root, - snapshotSourceRoots: [ - { label: "media", root: mediaRoot }, - { label: "tmp-openclaw", root: tmpRoot }, - ], + openClawMediaDir: mediaRoot, + openClawTmpDir: tmpRoot, }, }); @@ -150,7 +126,7 @@ describe("exportXWorkmateArtifacts", () => { artifactScope: prepared.artifactScope, includeContent: false, }, - pluginConfig: { workspaceDir: root }, + pluginConfig: { workspaceDir: root, openClawMediaDir: mediaRoot, openClawTmpDir: tmpRoot }, }); expect(result.artifacts.map((artifact) => artifact.relativePath).sort()).toEqual([ @@ -327,8 +303,6 @@ describe("exportXWorkmateArtifacts", () => { expect(result.scopeKind).toBe("task"); expect(result.artifacts).toEqual([]); - expect(result.manifestMarkdown).toContain("No artifacts found for this task run."); - expect(result.manifestMarkdown).toContain("Artifact scope: `tasks/thread-main/turn-1`"); }); it("does not adopt workspace root files even with a current-run timestamp", async () => { diff --git a/src/exportArtifacts.ts b/src/exportArtifacts.ts index 40e90b5..cae0778 100644 --- a/src/exportArtifacts.ts +++ b/src/exportArtifacts.ts @@ -44,7 +44,6 @@ export type XWorkmateArtifactExport = { scopeKind: XWorkmateArtifactScopeKind; artifacts: XWorkmateArtifact[]; warnings: string[]; - manifestMarkdown: string; }; export type XWorkmateArtifactPrepare = { @@ -349,10 +348,7 @@ export async function exportXWorkmateArtifacts(input: ExportInput): Promise { @@ -461,13 +457,10 @@ export async function readXWorkmateArtifact(input: ReadInput): Promise, pluginConfig: Record): SnapshotSource[] { - const configured = Array.isArray(params.snapshotSourceRoots) - ? params.snapshotSourceRoots - : Array.isArray(pluginConfig.snapshotSourceRoots) - ? pluginConfig.snapshotSourceRoots - : undefined; - if (configured) { - return configured - .map((entry, index) => { - const record = objectRecord(entry); - const root = optionalString(record.root); - const label = safeScopeSegment(optionalString(record.label) || `source-${index + 1}`); - return root ? { label, root: expandUserPath(root) } : undefined; - }) - .filter((entry): entry is SnapshotSource => Boolean(entry)); - } + return [ { label: "media",