visionclaw 0.1.195-beta.1 → 0.1.195-dev.feat-e2e-test-system.2

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.
Files changed (107) hide show
  1. package/dist/agent/command-handlers.d.ts.map +1 -1
  2. package/dist/agent/command-handlers.js +17 -0
  3. package/dist/agent/command-handlers.js.map +1 -1
  4. package/dist/builtin-skills/catalog/equity-research/SKILL.md +256 -0
  5. package/dist/builtin-skills/catalog/financial-modeling/SKILL.md +186 -0
  6. package/dist/builtin-skills/catalog/investment-banking/SKILL.md +213 -0
  7. package/dist/builtin-skills/catalog/private-equity/SKILL.md +282 -0
  8. package/dist/builtin-skills/catalog/wealth-management/SKILL.md +252 -0
  9. package/dist/channels/interface.d.ts +9 -0
  10. package/dist/channels/interface.d.ts.map +1 -1
  11. package/dist/channels/manager.d.ts.map +1 -1
  12. package/dist/channels/manager.js +3 -0
  13. package/dist/channels/manager.js.map +1 -1
  14. package/dist/channels/telegram.d.ts.map +1 -1
  15. package/dist/channels/telegram.js +7 -1
  16. package/dist/channels/telegram.js.map +1 -1
  17. package/dist/config/types.d.ts +6 -0
  18. package/dist/config/types.d.ts.map +1 -1
  19. package/dist/config/types.js +10 -0
  20. package/dist/config/types.js.map +1 -1
  21. package/dist/e2e/artifacts.d.ts +8 -0
  22. package/dist/e2e/artifacts.d.ts.map +1 -0
  23. package/dist/e2e/artifacts.js +35 -0
  24. package/dist/e2e/artifacts.js.map +1 -0
  25. package/dist/e2e/cleanup.d.ts +8 -0
  26. package/dist/e2e/cleanup.d.ts.map +1 -0
  27. package/dist/e2e/cleanup.js +108 -0
  28. package/dist/e2e/cleanup.js.map +1 -0
  29. package/dist/e2e/cli.d.ts +4 -0
  30. package/dist/e2e/cli.d.ts.map +1 -0
  31. package/dist/e2e/cli.js +16 -0
  32. package/dist/e2e/cli.js.map +1 -0
  33. package/dist/e2e/index.d.ts +5 -0
  34. package/dist/e2e/index.d.ts.map +1 -0
  35. package/dist/e2e/index.js +4 -0
  36. package/dist/e2e/index.js.map +1 -0
  37. package/dist/e2e/local-test-server.d.ts +7 -0
  38. package/dist/e2e/local-test-server.d.ts.map +1 -0
  39. package/dist/e2e/local-test-server.js +75 -0
  40. package/dist/e2e/local-test-server.js.map +1 -0
  41. package/dist/e2e/oauth-setup-store.d.ts +28 -0
  42. package/dist/e2e/oauth-setup-store.d.ts.map +1 -0
  43. package/dist/e2e/oauth-setup-store.js +56 -0
  44. package/dist/e2e/oauth-setup-store.js.map +1 -0
  45. package/dist/e2e/parser.d.ts +4 -0
  46. package/dist/e2e/parser.d.ts.map +1 -0
  47. package/dist/e2e/parser.js +52 -0
  48. package/dist/e2e/parser.js.map +1 -0
  49. package/dist/e2e/registry.d.ts +3 -0
  50. package/dist/e2e/registry.d.ts.map +1 -0
  51. package/dist/e2e/registry.js +44 -0
  52. package/dist/e2e/registry.js.map +1 -0
  53. package/dist/e2e/reporter.d.ts +6 -0
  54. package/dist/e2e/reporter.d.ts.map +1 -0
  55. package/dist/e2e/reporter.js +56 -0
  56. package/dist/e2e/reporter.js.map +1 -0
  57. package/dist/e2e/runner.d.ts +4 -0
  58. package/dist/e2e/runner.d.ts.map +1 -0
  59. package/dist/e2e/runner.js +116 -0
  60. package/dist/e2e/runner.js.map +1 -0
  61. package/dist/e2e/setup-google-guest.d.ts +19 -0
  62. package/dist/e2e/setup-google-guest.d.ts.map +1 -0
  63. package/dist/e2e/setup-google-guest.js +205 -0
  64. package/dist/e2e/setup-google-guest.js.map +1 -0
  65. package/dist/e2e/suite-utils.d.ts +19 -0
  66. package/dist/e2e/suite-utils.d.ts.map +1 -0
  67. package/dist/e2e/suite-utils.js +60 -0
  68. package/dist/e2e/suite-utils.js.map +1 -0
  69. package/dist/e2e/suites/agent.d.ts +3 -0
  70. package/dist/e2e/suites/agent.d.ts.map +1 -0
  71. package/dist/e2e/suites/agent.js +33 -0
  72. package/dist/e2e/suites/agent.js.map +1 -0
  73. package/dist/e2e/suites/browser.d.ts +3 -0
  74. package/dist/e2e/suites/browser.d.ts.map +1 -0
  75. package/dist/e2e/suites/browser.js +68 -0
  76. package/dist/e2e/suites/browser.js.map +1 -0
  77. package/dist/e2e/suites/cua.d.ts +3 -0
  78. package/dist/e2e/suites/cua.d.ts.map +1 -0
  79. package/dist/e2e/suites/cua.js +78 -0
  80. package/dist/e2e/suites/cua.js.map +1 -0
  81. package/dist/e2e/suites/google.d.ts +3 -0
  82. package/dist/e2e/suites/google.d.ts.map +1 -0
  83. package/dist/e2e/suites/google.js +145 -0
  84. package/dist/e2e/suites/google.js.map +1 -0
  85. package/dist/e2e/suites/memory.d.ts +3 -0
  86. package/dist/e2e/suites/memory.d.ts.map +1 -0
  87. package/dist/e2e/suites/memory.js +50 -0
  88. package/dist/e2e/suites/memory.js.map +1 -0
  89. package/dist/e2e/suites/obs.d.ts +3 -0
  90. package/dist/e2e/suites/obs.d.ts.map +1 -0
  91. package/dist/e2e/suites/obs.js +29 -0
  92. package/dist/e2e/suites/obs.js.map +1 -0
  93. package/dist/e2e/suites/self.d.ts +3 -0
  94. package/dist/e2e/suites/self.d.ts.map +1 -0
  95. package/dist/e2e/suites/self.js +65 -0
  96. package/dist/e2e/suites/self.js.map +1 -0
  97. package/dist/e2e/suites/upgrade.d.ts +3 -0
  98. package/dist/e2e/suites/upgrade.d.ts.map +1 -0
  99. package/dist/e2e/suites/upgrade.js +31 -0
  100. package/dist/e2e/suites/upgrade.js.map +1 -0
  101. package/dist/e2e/types.d.ts +91 -0
  102. package/dist/e2e/types.d.ts.map +1 -0
  103. package/dist/e2e/types.js +2 -0
  104. package/dist/e2e/types.js.map +1 -0
  105. package/dist/index.js.map +1 -1
  106. package/dist-agent/bundle.cjs +31839 -30032
  107. package/package.json +1 -1
@@ -0,0 +1,44 @@
1
+ import { selfSuite } from "./suites/self.js";
2
+ import { browserSuite } from "./suites/browser.js";
3
+ import { cuaSuite } from "./suites/cua.js";
4
+ import { googleSuite } from "./suites/google.js";
5
+ import { memorySuite } from "./suites/memory.js";
6
+ import { agentSuite } from "./suites/agent.js";
7
+ import { obsSuite } from "./suites/obs.js";
8
+ import { upgradeSuite } from "./suites/upgrade.js";
9
+ const ALL_SUITES = [
10
+ selfSuite,
11
+ memorySuite,
12
+ browserSuite,
13
+ cuaSuite,
14
+ googleSuite,
15
+ agentSuite,
16
+ obsSuite,
17
+ upgradeSuite,
18
+ ];
19
+ export function getSuitesForMode(mode, options) {
20
+ switch (mode) {
21
+ case "self":
22
+ return [selfSuite];
23
+ case "browser":
24
+ return [selfSuite, browserSuite];
25
+ case "cua":
26
+ return [selfSuite, cuaSuite];
27
+ case "google":
28
+ return [selfSuite, googleSuite];
29
+ case "smoke":
30
+ return [
31
+ selfSuite,
32
+ memorySuite,
33
+ browserSuite,
34
+ cuaSuite,
35
+ googleSuite,
36
+ ...(options.includeAgent ? [agentSuite] : []),
37
+ ];
38
+ case "full":
39
+ return ALL_SUITES;
40
+ default:
41
+ return [selfSuite];
42
+ }
43
+ }
44
+ //# sourceMappingURL=registry.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"registry.js","sourceRoot":"","sources":["../../src/e2e/registry.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,SAAS,EAAE,MAAM,kBAAkB,CAAC;AAC7C,OAAO,EAAE,YAAY,EAAE,MAAM,qBAAqB,CAAC;AACnD,OAAO,EAAE,QAAQ,EAAE,MAAM,iBAAiB,CAAC;AAC3C,OAAO,EAAE,WAAW,EAAE,MAAM,oBAAoB,CAAC;AACjD,OAAO,EAAE,WAAW,EAAE,MAAM,oBAAoB,CAAC;AACjD,OAAO,EAAE,UAAU,EAAE,MAAM,mBAAmB,CAAC;AAC/C,OAAO,EAAE,QAAQ,EAAE,MAAM,iBAAiB,CAAC;AAC3C,OAAO,EAAE,YAAY,EAAE,MAAM,qBAAqB,CAAC;AAEnD,MAAM,UAAU,GAAe;IAC7B,SAAS;IACT,WAAW;IACX,YAAY;IACZ,QAAQ;IACR,WAAW;IACX,UAAU;IACV,QAAQ;IACR,YAAY;CACb,CAAC;AAEF,MAAM,UAAU,gBAAgB,CAAC,IAAa,EAAE,OAA0B;IACxE,QAAQ,IAAI,EAAE,CAAC;QACb,KAAK,MAAM;YACT,OAAO,CAAC,SAAS,CAAC,CAAC;QACrB,KAAK,SAAS;YACZ,OAAO,CAAC,SAAS,EAAE,YAAY,CAAC,CAAC;QACnC,KAAK,KAAK;YACR,OAAO,CAAC,SAAS,EAAE,QAAQ,CAAC,CAAC;QAC/B,KAAK,QAAQ;YACX,OAAO,CAAC,SAAS,EAAE,WAAW,CAAC,CAAC;QAClC,KAAK,OAAO;YACV,OAAO;gBACL,SAAS;gBACT,WAAW;gBACX,YAAY;gBACZ,QAAQ;gBACR,WAAW;gBACX,GAAG,CAAC,OAAO,CAAC,YAAY,CAAC,CAAC,CAAC,CAAC,UAAU,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC;aAC9C,CAAC;QACJ,KAAK,MAAM;YACT,OAAO,UAAU,CAAC;QACpB;YACE,OAAO,CAAC,SAAS,CAAC,CAAC;IACvB,CAAC;AACH,CAAC"}
@@ -0,0 +1,6 @@
1
+ import type { E2ERunResult, E2EStatus } from "./types.js";
2
+ export declare function aggregateStatus(statuses: E2EStatus[]): E2EStatus;
3
+ export declare function formatE2EStartMessage(runId: string, mode: string): string;
4
+ export declare function formatE2ESummary(result: E2ERunResult): string;
5
+ export declare function writeReports(result: E2ERunResult): void;
6
+ //# sourceMappingURL=reporter.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"reporter.d.ts","sourceRoot":"","sources":["../../src/e2e/reporter.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAE,YAAY,EAAkB,SAAS,EAAE,MAAM,YAAY,CAAC;AAE1E,wBAAgB,eAAe,CAAC,QAAQ,EAAE,SAAS,EAAE,GAAG,SAAS,CAKhE;AAED,wBAAgB,qBAAqB,CAAC,KAAK,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM,GAAG,MAAM,CAEzE;AAED,wBAAgB,gBAAgB,CAAC,MAAM,EAAE,YAAY,GAAG,MAAM,CA8B7D;AAED,wBAAgB,YAAY,CAAC,MAAM,EAAE,YAAY,GAAG,IAAI,CAIvD"}
@@ -0,0 +1,56 @@
1
+ import fs from "node:fs";
2
+ import path from "node:path";
3
+ export function aggregateStatus(statuses) {
4
+ if (statuses.includes("failed"))
5
+ return "failed";
6
+ if (statuses.includes("warning"))
7
+ return "warning";
8
+ if (statuses.length > 0 && statuses.every((status) => status === "skipped"))
9
+ return "skipped";
10
+ return "passed";
11
+ }
12
+ export function formatE2EStartMessage(runId, mode) {
13
+ return `VisionClaw E2E started\n\nRun ID: ${runId}\nMode: ${mode}`;
14
+ }
15
+ export function formatE2ESummary(result) {
16
+ const counts = countStatuses(result.suites);
17
+ const lines = [
18
+ `VisionClaw E2E ${result.mode} completed: ${result.status}`,
19
+ "",
20
+ `Run ID: ${result.runId}`,
21
+ `Duration: ${(result.durationMs / 1000).toFixed(1)}s`,
22
+ "",
23
+ "Suites:",
24
+ ...result.suites.map((suite) => `- ${suite.name}: ${suite.status} (${suite.tests.length} tests)`),
25
+ "",
26
+ `Totals: passed=${counts.passed}, warning=${counts.warning}, failed=${counts.failed}, skipped=${counts.skipped}`,
27
+ `Artifacts: ${result.artifactsDir}`,
28
+ "",
29
+ `Cleanup: /e2e cleanup ${result.runId}`,
30
+ ];
31
+ if (result.cleanup.status === "failed" || result.cleanup.status === "warning") {
32
+ lines.push("", `Cleanup needs attention. Run: /e2e cleanup ${result.runId}`);
33
+ }
34
+ const failures = result.suites.flatMap((suite) => suite.tests.filter((test) => test.status === "failed"));
35
+ if (failures.length > 0) {
36
+ lines.push("", "Failed tests:");
37
+ for (const failure of failures.slice(0, 5)) {
38
+ lines.push(`- ${failure.id}: ${failure.error?.message ?? failure.message ?? "failed"}`);
39
+ }
40
+ }
41
+ return lines.join("\n");
42
+ }
43
+ export function writeReports(result) {
44
+ fs.mkdirSync(result.artifactsDir, { recursive: true });
45
+ fs.writeFileSync(path.join(result.artifactsDir, "report.json"), `${JSON.stringify(result, null, 2)}\n`, "utf-8");
46
+ fs.writeFileSync(path.join(result.artifactsDir, "summary.md"), `${formatE2ESummary(result)}\n`, "utf-8");
47
+ }
48
+ function countStatuses(suites) {
49
+ const counts = { passed: 0, failed: 0, skipped: 0, warning: 0 };
50
+ for (const suite of suites) {
51
+ for (const test of suite.tests)
52
+ counts[test.status]++;
53
+ }
54
+ return counts;
55
+ }
56
+ //# sourceMappingURL=reporter.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"reporter.js","sourceRoot":"","sources":["../../src/e2e/reporter.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,4 @@
1
+ import type { E2ERequestOptions, E2ERunResult } from "./types.js";
2
+ export declare function runE2E(options: E2ERequestOptions): Promise<E2ERunResult | string>;
3
+ export declare function formatE2EResult(result: E2ERunResult, json?: boolean): string;
4
+ //# sourceMappingURL=runner.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"runner.d.ts","sourceRoot":"","sources":["../../src/e2e/runner.ts"],"names":[],"mappings":"AAGA,OAAO,KAAK,EAAkB,iBAAiB,EAAE,YAAY,EAAE,MAAM,YAAY,CAAC;AAelF,wBAAsB,MAAM,CAAC,OAAO,EAAE,iBAAiB,GAAG,OAAO,CAAC,YAAY,GAAG,MAAM,CAAC,CA0DvF;AAqDD,wBAAgB,eAAe,CAAC,MAAM,EAAE,YAAY,EAAE,IAAI,UAAQ,GAAG,MAAM,CAG1E"}
@@ -0,0 +1,116 @@
1
+ import { randomUUID } from "node:crypto";
2
+ import { loadConfig } from "../config/index.js";
3
+ import { logger } from "../logger.js";
4
+ import { ensureE2ERunDir, listRecentRunIds } from "./artifacts.js";
5
+ import { getSuitesForMode } from "./registry.js";
6
+ import { aggregateStatus, formatE2EStartMessage, formatE2ESummary, writeReports } from "./reporter.js";
7
+ import { formatCleanupList, hasFailedCleanupItems, loadCleanupItems, runCleanupForRun, saveCleanupItems } from "./cleanup.js";
8
+ import { completeGoogleGuestSetupFromCallback, startGoogleGuestSetup, } from "./setup-google-guest.js";
9
+ function makeRunId() {
10
+ const stamp = new Date().toISOString().replace(/[-:TZ.]/g, "").slice(0, 14);
11
+ return `e2e_${stamp}_${randomUUID().slice(0, 4)}`;
12
+ }
13
+ export async function runE2E(options) {
14
+ const config = loadConfig();
15
+ if (options.mode === "cleanup") {
16
+ return handleCleanup(config, options);
17
+ }
18
+ if (options.mode === "setup") {
19
+ return handleSetup(config, options);
20
+ }
21
+ const runId = makeRunId();
22
+ const artifactsDir = ensureE2ERunDir(runId);
23
+ const startedAt = new Date().toISOString();
24
+ const cleanupItems = [];
25
+ logger.system(formatE2EStartMessage(runId, options.mode));
26
+ const context = {
27
+ runId,
28
+ mode: options.mode,
29
+ config,
30
+ options,
31
+ artifactsDir,
32
+ addCleanupItem: (item) => {
33
+ cleanupItems.push({
34
+ ...item,
35
+ createdAt: new Date().toISOString(),
36
+ cleanupStatus: "pending",
37
+ });
38
+ },
39
+ };
40
+ const suites = [];
41
+ for (const suite of getSuitesForMode(options.mode, options)) {
42
+ suites.push(await suite.run(context));
43
+ }
44
+ saveCleanupItems(runId, cleanupItems);
45
+ const cleanup = options.keepArtifacts
46
+ ? { status: "skipped", items: cleanupItems, message: "Cleanup skipped due to --keep-artifacts" }
47
+ : await runCleanupForRun(config, runId);
48
+ const finishedAt = new Date().toISOString();
49
+ const result = {
50
+ runId,
51
+ mode: options.mode,
52
+ startedAt,
53
+ finishedAt,
54
+ status: aggregateStatus([...suites.map((suite) => suite.status), cleanup.status]),
55
+ durationMs: Date.parse(finishedAt) - Date.parse(startedAt),
56
+ suites,
57
+ artifactsDir,
58
+ cleanup,
59
+ };
60
+ writeReports(result);
61
+ return result;
62
+ }
63
+ async function handleCleanup(config, options) {
64
+ const target = options.cleanupTarget;
65
+ if (!target)
66
+ return formatCleanupList();
67
+ let runId = target;
68
+ if (target === "latest") {
69
+ runId = listRecentRunIds(1)[0] ?? "";
70
+ if (!runId)
71
+ return "No recent E2E runs found.";
72
+ }
73
+ if (target === "--all-stale" || target === "--failed") {
74
+ const recentRunIds = listRecentRunIds(20);
75
+ const runIds = target === "--failed" ? recentRunIds.filter((id) => hasFailedCleanupItems(id)) : recentRunIds;
76
+ const lines = [`Running cleanup for ${runIds.length} run(s)...`];
77
+ for (const id of runIds) {
78
+ const result = await runCleanupForRun(config, id);
79
+ lines.push(`- ${id}: ${result.status}`);
80
+ }
81
+ return lines.join("\n");
82
+ }
83
+ const items = loadCleanupItems(runId);
84
+ if (items.length === 0)
85
+ return `No cleanup registry found for run ${runId}.`;
86
+ const result = await runCleanupForRun(config, runId);
87
+ return `Cleanup for ${runId}: ${result.status}${result.message ? `\n${result.message}` : ""}`;
88
+ }
89
+ async function handleSetup(config, options) {
90
+ if (options.setupKind === "google-guest-code") {
91
+ const setupId = options.args[2];
92
+ const callbackUrl = options.args.slice(3).join(" ");
93
+ if (!setupId || !callbackUrl) {
94
+ throw new Error("Usage: e2e setup google-guest-code <setupId> <callbackUrl>");
95
+ }
96
+ const result = await completeGoogleGuestSetupFromCallback(config, setupId, callbackUrl);
97
+ return result.message;
98
+ }
99
+ if (options.setupKind === "google-guest") {
100
+ const email = options.args.at(2) ?? config.e2e?.google?.meetGuestEmail ?? process.env.E2E_GOOGLE_MEET_GUEST_EMAIL;
101
+ if (!email)
102
+ throw new Error("Guest email is required");
103
+ const result = await startGoogleGuestSetup(config, email, {
104
+ remote: options.flags.has("--remote"),
105
+ requestSource: "cli",
106
+ });
107
+ return result.message;
108
+ }
109
+ throw new Error("Unknown e2e setup command");
110
+ }
111
+ export function formatE2EResult(result, json = false) {
112
+ if (json)
113
+ return JSON.stringify(result, null, 2);
114
+ return formatE2ESummary(result);
115
+ }
116
+ //# sourceMappingURL=runner.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"runner.js","sourceRoot":"","sources":["../../src/e2e/runner.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,19 @@
1
+ import { google } from "googleapis";
2
+ import { type GoogleTokens, type VisionClawConfig } from "../config/types.js";
3
+ export declare const E2E_GUEST_SCOPES: string[];
4
+ export interface GoogleGuestSetupResult {
5
+ message: string;
6
+ setupId?: string;
7
+ authUrl?: string;
8
+ }
9
+ export declare function loadE2EGuestTokens(): GoogleTokens | null;
10
+ export declare function saveE2EGuestTokens(tokens: GoogleTokens): void;
11
+ export declare function startGoogleGuestSetup(config: VisionClawConfig, email: string, options: {
12
+ remote?: boolean;
13
+ requestSource?: "cli" | "chat";
14
+ channel?: string;
15
+ sender?: string;
16
+ }): Promise<GoogleGuestSetupResult>;
17
+ export declare function completeGoogleGuestSetupFromCallback(config: VisionClawConfig, setupId: string, callbackUrl: string): Promise<GoogleGuestSetupResult>;
18
+ export declare function createGuestCalendarClient(config: VisionClawConfig): ReturnType<typeof google.calendar> | null;
19
+ //# sourceMappingURL=setup-google-guest.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"setup-google-guest.d.ts","sourceRoot":"","sources":["../../src/e2e/setup-google-guest.ts"],"names":[],"mappings":"AAIA,OAAO,EAAE,MAAM,EAAE,MAAM,YAAY,CAAC;AACpC,OAAO,EAAsB,KAAK,YAAY,EAAE,KAAK,gBAAgB,EAAE,MAAM,oBAAoB,CAAC;AAUlG,eAAO,MAAM,gBAAgB,UAAwD,CAAC;AAEtF,MAAM,WAAW,sBAAsB;IACrC,OAAO,EAAE,MAAM,CAAC;IAChB,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,OAAO,CAAC,EAAE,MAAM,CAAC;CAClB;AAED,wBAAgB,kBAAkB,IAAI,YAAY,GAAG,IAAI,CAQxD;AAED,wBAAgB,kBAAkB,CAAC,MAAM,EAAE,YAAY,GAAG,IAAI,CAI7D;AAED,wBAAsB,qBAAqB,CACzC,MAAM,EAAE,gBAAgB,EACxB,KAAK,EAAE,MAAM,EACb,OAAO,EAAE;IAAE,MAAM,CAAC,EAAE,OAAO,CAAC;IAAC,aAAa,CAAC,EAAE,KAAK,GAAG,MAAM,CAAC;IAAC,OAAO,CAAC,EAAE,MAAM,CAAC;IAAC,MAAM,CAAC,EAAE,MAAM,CAAA;CAAE,GAC/F,OAAO,CAAC,sBAAsB,CAAC,CAKjC;AA2HD,wBAAsB,oCAAoC,CACxD,MAAM,EAAE,gBAAgB,EACxB,OAAO,EAAE,MAAM,EACf,WAAW,EAAE,MAAM,GAClB,OAAO,CAAC,sBAAsB,CAAC,CA4BjC;AAuBD,wBAAgB,yBAAyB,CAAC,MAAM,EAAE,gBAAgB,GAAG,UAAU,CAAC,OAAO,MAAM,CAAC,QAAQ,CAAC,GAAG,IAAI,CAgB7G"}
@@ -0,0 +1,205 @@
1
+ import fs from "node:fs";
2
+ import http from "node:http";
3
+ import path from "node:path";
4
+ import open from "open";
5
+ import { google } from "googleapis";
6
+ import { GoogleTokensSchema } from "../config/types.js";
7
+ import { resolveGoogleOAuthCredentials } from "../google/oauth-credentials.js";
8
+ import { getE2EGuestTokensFile } from "./artifacts.js";
9
+ import { createOAuthSetupSession, deleteOAuthSetupSession, loadOAuthSetupSession, parseCallbackUrl, } from "./oauth-setup-store.js";
10
+ export const E2E_GUEST_SCOPES = ["https://www.googleapis.com/auth/calendar.readonly"];
11
+ export function loadE2EGuestTokens() {
12
+ const file = getE2EGuestTokensFile();
13
+ if (!fs.existsSync(file))
14
+ return null;
15
+ try {
16
+ return GoogleTokensSchema.parse(JSON.parse(fs.readFileSync(file, "utf-8")));
17
+ }
18
+ catch {
19
+ return null;
20
+ }
21
+ }
22
+ export function saveE2EGuestTokens(tokens) {
23
+ const file = getE2EGuestTokensFile();
24
+ fs.mkdirSync(path.dirname(file), { recursive: true });
25
+ fs.writeFileSync(file, `${JSON.stringify(tokens, null, 2)}\n`, "utf-8");
26
+ }
27
+ export async function startGoogleGuestSetup(config, email, options) {
28
+ if (options.remote) {
29
+ return startRemoteGoogleGuestSetup(config, email, options);
30
+ }
31
+ return startLocalGoogleGuestSetup(config, email);
32
+ }
33
+ function startRemoteGoogleGuestSetup(config, email, options) {
34
+ const { clientId, clientSecret } = resolveGoogleOAuthCredentials(config);
35
+ const session = createOAuthSetupSession({
36
+ expectedEmail: email,
37
+ scopes: E2E_GUEST_SCOPES,
38
+ redirectUri: "http://127.0.0.1:49321/callback",
39
+ requestSource: options.requestSource ?? "cli",
40
+ channel: options.channel,
41
+ sender: options.sender,
42
+ });
43
+ const oauth2Client = new google.auth.OAuth2(clientId, clientSecret, session.redirectUri);
44
+ const authUrl = oauth2Client.generateAuthUrl({
45
+ access_type: "offline",
46
+ scope: E2E_GUEST_SCOPES,
47
+ prompt: "consent",
48
+ state: session.state,
49
+ });
50
+ return {
51
+ setupId: session.setupId,
52
+ authUrl,
53
+ message: [
54
+ "E2E Google guest setup started (remote mode).",
55
+ "",
56
+ `Expected guest: ${email}`,
57
+ `Setup ID: ${session.setupId}`,
58
+ "",
59
+ "Open this URL on any machine:",
60
+ authUrl,
61
+ "",
62
+ "After authorization, copy the full callback URL and run:",
63
+ `visionclaw e2e setup google-guest-code ${session.setupId} <callbackUrl>`,
64
+ ].join("\n"),
65
+ };
66
+ }
67
+ async function startLocalGoogleGuestSetup(config, email) {
68
+ const { clientId, clientSecret } = resolveGoogleOAuthCredentials(config);
69
+ return new Promise((resolve, reject) => {
70
+ const server = http.createServer();
71
+ server.listen(0, "127.0.0.1", () => {
72
+ const addr = server.address();
73
+ if (!addr || typeof addr === "string") {
74
+ reject(new Error("Failed to start local OAuth server"));
75
+ return;
76
+ }
77
+ const redirectUri = `http://127.0.0.1:${addr.port}/callback`;
78
+ const oauth2Client = new google.auth.OAuth2(clientId, clientSecret, redirectUri);
79
+ const authUrl = oauth2Client.generateAuthUrl({
80
+ access_type: "offline",
81
+ scope: E2E_GUEST_SCOPES,
82
+ prompt: "consent",
83
+ });
84
+ void open(authUrl).catch(() => { });
85
+ let settled = false;
86
+ const timeout = setTimeout(() => {
87
+ if (settled)
88
+ return;
89
+ settled = true;
90
+ server.close();
91
+ reject(new Error("OAuth setup timed out after 10 minutes"));
92
+ }, 10 * 60 * 1000);
93
+ const finish = (fn) => {
94
+ if (settled)
95
+ return;
96
+ settled = true;
97
+ clearTimeout(timeout);
98
+ server.close();
99
+ fn();
100
+ };
101
+ server.on("request", (req, res) => {
102
+ void (async () => {
103
+ try {
104
+ const url = new URL(req.url ?? "/", redirectUri);
105
+ const code = url.searchParams.get("code");
106
+ const error = url.searchParams.get("error");
107
+ if (error)
108
+ throw new Error(`Google OAuth error: ${error}`);
109
+ if (!code) {
110
+ res.writeHead(400);
111
+ res.end("Missing code");
112
+ return;
113
+ }
114
+ const { tokens } = await oauth2Client.getToken(code);
115
+ if (!tokens.refresh_token)
116
+ throw new Error("No refresh token received");
117
+ const googleTokens = {
118
+ access_token: tokens.access_token ?? "",
119
+ refresh_token: tokens.refresh_token,
120
+ token_type: tokens.token_type ?? "Bearer",
121
+ expiry_date: tokens.expiry_date ?? 0,
122
+ scope: tokens.scope ?? E2E_GUEST_SCOPES.join(" "),
123
+ };
124
+ await verifyGuestEmail(config, googleTokens, email);
125
+ saveE2EGuestTokens(googleTokens);
126
+ res.writeHead(200, { "Content-Type": "text/html" });
127
+ res.end("<h1>E2E guest authorization complete</h1>");
128
+ finish(() => resolve({
129
+ authUrl,
130
+ message: `E2E Google guest setup completed for ${email}.`,
131
+ }));
132
+ }
133
+ catch (err) {
134
+ res.writeHead(500);
135
+ res.end("Authorization failed");
136
+ finish(() => reject(err instanceof Error ? err : new Error(String(err))));
137
+ }
138
+ })();
139
+ });
140
+ });
141
+ });
142
+ }
143
+ export async function completeGoogleGuestSetupFromCallback(config, setupId, callbackUrl) {
144
+ const session = loadOAuthSetupSession(setupId);
145
+ if (!session)
146
+ throw new Error("OAuth setup session not found or expired");
147
+ const { code, state } = parseCallbackUrl(callbackUrl);
148
+ if (!state || state !== session.state)
149
+ throw new Error("OAuth state mismatch");
150
+ const { clientId, clientSecret } = resolveGoogleOAuthCredentials(config);
151
+ const oauth2Client = new google.auth.OAuth2(clientId, clientSecret, session.redirectUri);
152
+ const { tokens } = await oauth2Client.getToken(code);
153
+ if (!tokens.refresh_token)
154
+ throw new Error("No refresh token received");
155
+ const googleTokens = {
156
+ access_token: tokens.access_token ?? "",
157
+ refresh_token: tokens.refresh_token,
158
+ token_type: tokens.token_type ?? "Bearer",
159
+ expiry_date: tokens.expiry_date ?? 0,
160
+ scope: tokens.scope ?? session.scopes.join(" "),
161
+ };
162
+ await verifyGuestEmail(config, googleTokens, session.expectedEmail);
163
+ saveE2EGuestTokens(googleTokens);
164
+ deleteOAuthSetupSession(setupId);
165
+ return {
166
+ message: `E2E Google guest setup completed for ${session.expectedEmail}.`,
167
+ setupId,
168
+ };
169
+ }
170
+ async function verifyGuestEmail(config, tokens, expectedEmail) {
171
+ const { clientId, clientSecret } = resolveGoogleOAuthCredentials(config);
172
+ const oauth2Client = new google.auth.OAuth2(clientId, clientSecret);
173
+ oauth2Client.setCredentials({
174
+ access_token: tokens.access_token,
175
+ refresh_token: tokens.refresh_token,
176
+ token_type: tokens.token_type,
177
+ expiry_date: tokens.expiry_date,
178
+ });
179
+ const oauth2 = google.oauth2({ version: "v2", auth: oauth2Client });
180
+ const profile = await oauth2.userinfo.get();
181
+ const email = profile.data.email?.toLowerCase();
182
+ if (!email || email !== expectedEmail.toLowerCase()) {
183
+ throw new Error(`Authorized account ${email ?? "unknown"} does not match expected ${expectedEmail}`);
184
+ }
185
+ }
186
+ export function createGuestCalendarClient(config) {
187
+ const tokens = loadE2EGuestTokens();
188
+ if (!tokens)
189
+ return null;
190
+ try {
191
+ const { clientId, clientSecret } = resolveGoogleOAuthCredentials(config);
192
+ const oauth2Client = new google.auth.OAuth2(clientId, clientSecret);
193
+ oauth2Client.setCredentials({
194
+ access_token: tokens.access_token,
195
+ refresh_token: tokens.refresh_token,
196
+ token_type: tokens.token_type,
197
+ expiry_date: tokens.expiry_date,
198
+ });
199
+ return google.calendar({ version: "v3", auth: oauth2Client });
200
+ }
201
+ catch {
202
+ return null;
203
+ }
204
+ }
205
+ //# sourceMappingURL=setup-google-guest.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"setup-google-guest.js","sourceRoot":"","sources":["../../src/e2e/setup-google-guest.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,19 @@
1
+ import type { E2EStatus, E2ESuiteResult, E2ETestResult } from "./types.js";
2
+ export declare function runTest(suite: string, id: string, name: string, fn: () => Promise<Omit<E2ETestResult, "id" | "name" | "suite" | "durationMs">>): Promise<E2ETestResult>;
3
+ export declare function buildSuiteResult(id: string, name: string, started: number, tests: E2ETestResult[]): E2ESuiteResult;
4
+ export declare function ok(message?: string, details?: Record<string, unknown>): {
5
+ status: E2EStatus;
6
+ message?: string;
7
+ details?: Record<string, unknown>;
8
+ };
9
+ export declare function skipped(message: string, details?: Record<string, unknown>): {
10
+ status: E2EStatus;
11
+ message: string;
12
+ details?: Record<string, unknown>;
13
+ };
14
+ export declare function warning(message: string, details?: Record<string, unknown>): {
15
+ status: E2EStatus;
16
+ message: string;
17
+ details?: Record<string, unknown>;
18
+ };
19
+ //# sourceMappingURL=suite-utils.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"suite-utils.d.ts","sourceRoot":"","sources":["../../src/e2e/suite-utils.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,SAAS,EAAE,cAAc,EAAE,aAAa,EAA0B,MAAM,YAAY,CAAC;AAGnG,wBAAsB,OAAO,CAC3B,KAAK,EAAE,MAAM,EACb,EAAE,EAAE,MAAM,EACV,IAAI,EAAE,MAAM,EACZ,EAAE,EAAE,MAAM,OAAO,CAAC,IAAI,CAAC,aAAa,EAAE,IAAI,GAAG,MAAM,GAAG,OAAO,GAAG,YAAY,CAAC,CAAC,GAC7E,OAAO,CAAC,aAAa,CAAC,CA0BxB;AAED,wBAAgB,gBAAgB,CAAC,EAAE,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM,EAAE,OAAO,EAAE,MAAM,EAAE,KAAK,EAAE,aAAa,EAAE,GAAG,cAAc,CAQlH;AAED,wBAAgB,EAAE,CAAC,OAAO,CAAC,EAAE,MAAM,EAAE,OAAO,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,GAAG;IAAE,MAAM,EAAE,SAAS,CAAC;IAAC,OAAO,CAAC,EAAE,MAAM,CAAC;IAAC,OAAO,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAA;CAAE,CAElJ;AAED,wBAAgB,OAAO,CAAC,OAAO,EAAE,MAAM,EAAE,OAAO,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,GAAG;IAAE,MAAM,EAAE,SAAS,CAAC;IAAC,OAAO,EAAE,MAAM,CAAC;IAAC,OAAO,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAA;CAAE,CAErJ;AAED,wBAAgB,OAAO,CAAC,OAAO,EAAE,MAAM,EAAE,OAAO,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,GAAG;IAAE,MAAM,EAAE,SAAS,CAAC;IAAC,OAAO,EAAE,MAAM,CAAC;IAAC,OAAO,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAA;CAAE,CAErJ"}
@@ -0,0 +1,60 @@
1
+ import { aggregateStatus } from "./reporter.js";
2
+ export async function runTest(suite, id, name, fn) {
3
+ const started = Date.now();
4
+ try {
5
+ const result = await fn();
6
+ return {
7
+ id,
8
+ name,
9
+ suite,
10
+ durationMs: Date.now() - started,
11
+ ...result,
12
+ };
13
+ }
14
+ catch (err) {
15
+ return {
16
+ id,
17
+ name,
18
+ suite,
19
+ status: "failed",
20
+ durationMs: Date.now() - started,
21
+ error: {
22
+ name: err instanceof Error ? err.name : undefined,
23
+ message: err instanceof Error ? err.message : String(err),
24
+ stack: err instanceof Error ? err.stack : undefined,
25
+ classification: classifyError(err),
26
+ },
27
+ };
28
+ }
29
+ }
30
+ export function buildSuiteResult(id, name, started, tests) {
31
+ return {
32
+ id,
33
+ name,
34
+ status: aggregateStatus(tests.map((test) => test.status)),
35
+ durationMs: Date.now() - started,
36
+ tests,
37
+ };
38
+ }
39
+ export function ok(message, details) {
40
+ return { status: "passed", message, details };
41
+ }
42
+ export function skipped(message, details) {
43
+ return { status: "skipped", message, details };
44
+ }
45
+ export function warning(message, details) {
46
+ return { status: "warning", message, details };
47
+ }
48
+ function classifyError(err) {
49
+ const message = err instanceof Error ? err.message : String(err);
50
+ if (/not configured|not found|missing/i.test(message))
51
+ return "missing_config";
52
+ if (/scope|insufficient/i.test(message))
53
+ return "missing_scope";
54
+ if (/permission|accessibility|screen recording|denied/i.test(message))
55
+ return "permission_denied";
56
+ if (/network|timeout|fetch/i.test(message))
57
+ return "network_error";
58
+ return "unknown";
59
+ }
60
+ //# sourceMappingURL=suite-utils.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"suite-utils.js","sourceRoot":"","sources":["../../src/e2e/suite-utils.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,eAAe,EAAE,MAAM,eAAe,CAAC;AAEhD,MAAM,CAAC,KAAK,UAAU,OAAO,CAC3B,KAAa,EACb,EAAU,EACV,IAAY,EACZ,EAA8E;IAE9E,MAAM,OAAO,GAAG,IAAI,CAAC,GAAG,EAAE,CAAC;IAC3B,IAAI,CAAC;QACH,MAAM,MAAM,GAAG,MAAM,EAAE,EAAE,CAAC;QAC1B,OAAO;YACL,EAAE;YACF,IAAI;YACJ,KAAK;YACL,UAAU,EAAE,IAAI,CAAC,GAAG,EAAE,GAAG,OAAO;YAChC,GAAG,MAAM;SACV,CAAC;IACJ,CAAC;IAAC,OAAO,GAAG,EAAE,CAAC;QACb,OAAO;YACL,EAAE;YACF,IAAI;YACJ,KAAK;YACL,MAAM,EAAE,QAAQ;YAChB,UAAU,EAAE,IAAI,CAAC,GAAG,EAAE,GAAG,OAAO;YAChC,KAAK,EAAE;gBACL,IAAI,EAAE,GAAG,YAAY,KAAK,CAAC,CAAC,CAAC,GAAG,CAAC,IAAI,CAAC,CAAC,CAAC,SAAS;gBACjD,OAAO,EAAE,GAAG,YAAY,KAAK,CAAC,CAAC,CAAC,GAAG,CAAC,OAAO,CAAC,CAAC,CAAC,MAAM,CAAC,GAAG,CAAC;gBACzD,KAAK,EAAE,GAAG,YAAY,KAAK,CAAC,CAAC,CAAC,GAAG,CAAC,KAAK,CAAC,CAAC,CAAC,SAAS;gBACnD,cAAc,EAAE,aAAa,CAAC,GAAG,CAAC;aACnC;SACF,CAAC;IACJ,CAAC;AACH,CAAC;AAED,MAAM,UAAU,gBAAgB,CAAC,EAAU,EAAE,IAAY,EAAE,OAAe,EAAE,KAAsB;IAChG,OAAO;QACL,EAAE;QACF,IAAI;QACJ,MAAM,EAAE,eAAe,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC,IAAI,EAAE,EAAE,CAAC,IAAI,CAAC,MAAM,CAAC,CAAC;QACzD,UAAU,EAAE,IAAI,CAAC,GAAG,EAAE,GAAG,OAAO;QAChC,KAAK;KACN,CAAC;AACJ,CAAC;AAED,MAAM,UAAU,EAAE,CAAC,OAAgB,EAAE,OAAiC;IACpE,OAAO,EAAE,MAAM,EAAE,QAAQ,EAAE,OAAO,EAAE,OAAO,EAAE,CAAC;AAChD,CAAC;AAED,MAAM,UAAU,OAAO,CAAC,OAAe,EAAE,OAAiC;IACxE,OAAO,EAAE,MAAM,EAAE,SAAS,EAAE,OAAO,EAAE,OAAO,EAAE,CAAC;AACjD,CAAC;AAED,MAAM,UAAU,OAAO,CAAC,OAAe,EAAE,OAAiC;IACxE,OAAO,EAAE,MAAM,EAAE,SAAS,EAAE,OAAO,EAAE,OAAO,EAAE,CAAC;AACjD,CAAC;AAED,SAAS,aAAa,CAAC,GAAY;IACjC,MAAM,OAAO,GAAG,GAAG,YAAY,KAAK,CAAC,CAAC,CAAC,GAAG,CAAC,OAAO,CAAC,CAAC,CAAC,MAAM,CAAC,GAAG,CAAC,CAAC;IACjE,IAAI,mCAAmC,CAAC,IAAI,CAAC,OAAO,CAAC;QAAE,OAAO,gBAAgB,CAAC;IAC/E,IAAI,qBAAqB,CAAC,IAAI,CAAC,OAAO,CAAC;QAAE,OAAO,eAAe,CAAC;IAChE,IAAI,mDAAmD,CAAC,IAAI,CAAC,OAAO,CAAC;QAAE,OAAO,mBAAmB,CAAC;IAClG,IAAI,wBAAwB,CAAC,IAAI,CAAC,OAAO,CAAC;QAAE,OAAO,eAAe,CAAC;IACnE,OAAO,SAAS,CAAC;AACnB,CAAC"}
@@ -0,0 +1,3 @@
1
+ import type { E2ESuite } from "../types.js";
2
+ export declare const agentSuite: E2ESuite;
3
+ //# sourceMappingURL=agent.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"agent.d.ts","sourceRoot":"","sources":["../../../src/e2e/suites/agent.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,QAAQ,EAAE,MAAM,aAAa,CAAC;AAG5C,eAAO,MAAM,UAAU,EAAE,QA6BxB,CAAC"}
@@ -0,0 +1,33 @@
1
+ import { createToolServer } from "../../tools/index.js";
2
+ import { buildSuiteResult, ok, runTest, skipped } from "../suite-utils.js";
3
+ export const agentSuite = {
4
+ id: "agent",
5
+ name: "Agent",
6
+ run: async (context) => {
7
+ const started = Date.now();
8
+ const tests = [
9
+ await runTest("agent", "agent.provider_config", "Provider config", () => {
10
+ const provider = context.config.provider;
11
+ const hasCreds = (provider === "anthropic" && !!context.config.anthropicApiKey) ||
12
+ (provider === "bedrock" && !!context.config.awsRegion) ||
13
+ (provider === "openai" && !!context.config.openaiApiKey) ||
14
+ (provider === "azure-openai" && !!context.config.azureOpenAIApiKey);
15
+ if (!hasCreds)
16
+ return Promise.resolve(skipped(`Provider credentials not present for ${provider}`));
17
+ return Promise.resolve(ok(`Provider ${provider} configured`));
18
+ }),
19
+ await runTest("agent", "agent.tool_server", "Tool server registry", () => {
20
+ createToolServer();
21
+ return Promise.resolve(ok("Tool server registry available"));
22
+ }),
23
+ await runTest("agent", "agent.minimal_turn", "Minimal agent turn", () => {
24
+ if (!context.options.includeAgent && context.mode !== "full") {
25
+ return Promise.resolve(skipped("Agent LLM turn skipped; pass --include-agent to enable"));
26
+ }
27
+ return Promise.resolve(skipped("Full agent LLM turn is not executed in automated e2e v1"));
28
+ }),
29
+ ];
30
+ return buildSuiteResult("agent", "Agent", started, tests);
31
+ },
32
+ };
33
+ //# sourceMappingURL=agent.js.map