





















@@ -1,4 +1,5 @@
11import fs from "node:fs";
2+import os from "node:os";
23import path from "node:path";
34import { withTempHome } from "openclaw/plugin-sdk/test-env";
45import { afterEach, beforeEach, describe, expect, it } from "vitest";
@@ -16,6 +17,7 @@ import {
1617failTaskRunByRunId,
1718} from "../../tasks/task-executor.js";
1819import { resetTaskRegistryForTests } from "../../tasks/task-registry.js";
20+import { withEnvAsync } from "../../test-utils/env.js";
1921import { buildStatusReply, buildStatusText } from "./commands-status.js";
2022import {
2123baseCommandTestConfig,
@@ -521,6 +523,83 @@ describe("buildStatusReply subagent summary", () => {
521523expect(normalized).not.toContain("Fast · codex");
522524});
523525526+it("uses workspace-scoped auth evidence in /status auth labels", async () => {
527+const tempRoot = fs.mkdtempSync(path.join(os.tmpdir(), "openclaw-status-auth-label-"));
528+const workspaceDir = path.join(tempRoot, "workspace");
529+const pluginDir = path.join(workspaceDir, ".openclaw", "extensions", "workspace-auth-label");
530+const bundledDir = path.join(tempRoot, "bundled");
531+const stateDir = path.join(tempRoot, "state");
532+const credentialPath = path.join(tempRoot, "credentials.json");
533+fs.mkdirSync(pluginDir, { recursive: true });
534+fs.mkdirSync(bundledDir, { recursive: true });
535+fs.mkdirSync(stateDir, { recursive: true });
536+fs.writeFileSync(path.join(pluginDir, "index.ts"), "export default {}\n", "utf8");
537+fs.writeFileSync(credentialPath, "{}", "utf8");
538+fs.writeFileSync(
539+path.join(pluginDir, "openclaw.plugin.json"),
540+JSON.stringify({
541+id: "workspace-auth-label",
542+configSchema: { type: "object" },
543+setup: {
544+providers: [
545+{
546+id: "anthropic",
547+authEvidence: [
548+{
549+type: "local-file-with-env",
550+fileEnvVar: "WORKSPACE_STATUS_CREDENTIALS",
551+credentialMarker: "workspace-status-local-credentials",
552+source: "workspace status credentials",
553+},
554+],
555+},
556+],
557+},
558+}),
559+"utf8",
560+);
561+562+try {
563+await withEnvAsync(
564+{
565+OPENCLAW_BUNDLED_PLUGINS_DIR: bundledDir,
566+OPENCLAW_STATE_DIR: stateDir,
567+WORKSPACE_STATUS_CREDENTIALS: credentialPath,
568+},
569+async () => {
570+const text = await buildStatusText({
571+cfg: {
572+ ...baseCfg,
573+plugins: { allow: ["workspace-auth-label"] },
574+},
575+sessionEntry: {
576+sessionId: "sess-status-workspace-auth",
577+updatedAt: 0,
578+},
579+sessionKey: "agent:main:main",
580+parentSessionKey: "agent:main:main",
581+sessionScope: "per-sender",
582+statusChannel: "mobilechat",
583+ workspaceDir,
584+provider: "anthropic",
585+model: "claude-opus-4-5",
586+contextTokens: 32_000,
587+resolvedFastMode: false,
588+resolvedVerboseLevel: "off",
589+resolvedReasoningLevel: "off",
590+resolveDefaultThinkingLevel: async () => undefined,
591+isGroup: false,
592+defaultGroupActivation: () => "mention",
593+});
594+595+expect(normalizeTestText(text)).toContain("workspace status credentials");
596+},
597+);
598+} finally {
599+fs.rmSync(tempRoot, { recursive: true, force: true });
600+}
601+});
602+524603it("keeps /status on a session-pinned PI harness after config changes", async () => {
525604registerStatusCodexHarness();
526605此内容由惯性聚合(RSS阅读器)自动聚合整理,仅供阅读参考。 原文来自 — 版权归原作者所有。