@mcoda/integrations 0.1.8 → 0.1.10

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,59 @@
1
+ export interface DocdexCheckResult {
2
+ status?: string;
3
+ success?: boolean;
4
+ checks?: Array<{
5
+ name?: string;
6
+ status?: string;
7
+ message?: string;
8
+ details?: Record<string, unknown>;
9
+ }>;
10
+ }
11
+ export interface DocdexHealthSummary {
12
+ ok: boolean;
13
+ message?: string;
14
+ failedChecks?: Array<{
15
+ name?: string;
16
+ status?: string;
17
+ message?: string;
18
+ }>;
19
+ }
20
+ export interface DocdexChromiumDetails {
21
+ path?: string;
22
+ manifestPath?: string;
23
+ installedAt?: string;
24
+ version?: string;
25
+ platform?: string;
26
+ downloadUrl?: string;
27
+ }
28
+ export interface DocdexBrowserInfo {
29
+ ok: boolean;
30
+ message?: string;
31
+ installHint?: string;
32
+ autoInstallEnabled?: boolean;
33
+ configuredKind?: string;
34
+ chromium?: DocdexChromiumDetails;
35
+ }
36
+ export declare const resolveDocdexBinary: () => string | undefined;
37
+ export declare const runDocdex: (args: string[], options?: {
38
+ cwd?: string;
39
+ env?: NodeJS.ProcessEnv;
40
+ }) => Promise<{
41
+ stdout: string;
42
+ stderr: string;
43
+ }>;
44
+ export declare const parseDocdexCheckOutput: (output: string) => DocdexCheckResult;
45
+ export declare const readDocdexCheck: (options?: {
46
+ cwd?: string;
47
+ env?: NodeJS.ProcessEnv;
48
+ }) => Promise<DocdexCheckResult>;
49
+ export declare const summarizeDocdexCheck: (check: DocdexCheckResult) => DocdexHealthSummary;
50
+ export declare const resolveDocdexBaseUrl: (options?: {
51
+ cwd?: string;
52
+ env?: NodeJS.ProcessEnv;
53
+ }) => Promise<string | undefined>;
54
+ export declare const parseDocdexBrowserCheck: (check: DocdexCheckResult) => DocdexBrowserInfo;
55
+ export declare const resolveDocdexBrowserInfo: (options?: {
56
+ cwd?: string;
57
+ env?: NodeJS.ProcessEnv;
58
+ }) => Promise<DocdexBrowserInfo>;
59
+ //# sourceMappingURL=DocdexRuntime.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"DocdexRuntime.d.ts","sourceRoot":"","sources":["../../src/docdex/DocdexRuntime.ts"],"names":[],"mappings":"AAQA,MAAM,WAAW,iBAAiB;IAChC,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,OAAO,CAAC,EAAE,OAAO,CAAC;IAClB,MAAM,CAAC,EAAE,KAAK,CAAC;QACb,IAAI,CAAC,EAAE,MAAM,CAAC;QACd,MAAM,CAAC,EAAE,MAAM,CAAC;QAChB,OAAO,CAAC,EAAE,MAAM,CAAC;QACjB,OAAO,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;KACnC,CAAC,CAAC;CACJ;AAED,MAAM,WAAW,mBAAmB;IAClC,EAAE,EAAE,OAAO,CAAC;IACZ,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,YAAY,CAAC,EAAE,KAAK,CAAC;QAAE,IAAI,CAAC,EAAE,MAAM,CAAC;QAAC,MAAM,CAAC,EAAE,MAAM,CAAC;QAAC,OAAO,CAAC,EAAE,MAAM,CAAA;KAAE,CAAC,CAAC;CAC5E;AAED,MAAM,WAAW,qBAAqB;IACpC,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,YAAY,CAAC,EAAE,MAAM,CAAC;IACtB,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,WAAW,CAAC,EAAE,MAAM,CAAC;CACtB;AAED,MAAM,WAAW,iBAAiB;IAChC,EAAE,EAAE,OAAO,CAAC;IACZ,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,kBAAkB,CAAC,EAAE,OAAO,CAAC;IAC7B,cAAc,CAAC,EAAE,MAAM,CAAC;IACxB,QAAQ,CAAC,EAAE,qBAAqB,CAAC;CAClC;AAuBD,eAAO,MAAM,mBAAmB,QAAO,MAAM,GAAG,SAI/C,CAAC;AAEF,eAAO,MAAM,SAAS,GACpB,MAAM,MAAM,EAAE,EACd,UAAS;IAAE,GAAG,CAAC,EAAE,MAAM,CAAC;IAAC,GAAG,CAAC,EAAE,MAAM,CAAC,UAAU,CAAA;CAAO,KACtD,OAAO,CAAC;IAAE,MAAM,EAAE,MAAM,CAAC;IAAC,MAAM,EAAE,MAAM,CAAA;CAAE,CAU5C,CAAC;AAUF,eAAO,MAAM,sBAAsB,GAAI,QAAQ,MAAM,KAAG,iBAiCvD,CAAC;AAEF,eAAO,MAAM,eAAe,GAAU,UAAS;IAAE,GAAG,CAAC,EAAE,MAAM,CAAC;IAAC,GAAG,CAAC,EAAE,MAAM,CAAC,UAAU,CAAA;CAAO,KAAG,OAAO,CAAC,iBAAiB,CAexH,CAAC;AAEF,eAAO,MAAM,oBAAoB,GAAI,OAAO,iBAAiB,KAAG,mBAsB/D,CAAC;AAEF,eAAO,MAAM,oBAAoB,GAAU,UAAS;IAAE,GAAG,CAAC,EAAE,MAAM,CAAC;IAAC,GAAG,CAAC,EAAE,MAAM,CAAC,UAAU,CAAA;CAAO,KAAG,OAAO,CAAC,MAAM,GAAG,SAAS,CAsB9H,CAAC;AA0BF,eAAO,MAAM,uBAAuB,GAAI,OAAO,iBAAiB,KAAG,iBAoClE,CAAC;AAEF,eAAO,MAAM,wBAAwB,GACnC,UAAS;IAAE,GAAG,CAAC,EAAE,MAAM,CAAC;IAAC,GAAG,CAAC,EAAE,MAAM,CAAC,UAAU,CAAA;CAAO,KACtD,OAAO,CAAC,iBAAiB,CAW3B,CAAC"}
@@ -0,0 +1,219 @@
1
+ import path from "node:path";
2
+ import os from "node:os";
3
+ import { createRequire } from "node:module";
4
+ import { execFile as execFileCb } from "node:child_process";
5
+ import { promisify } from "node:util";
6
+ const execFile = promisify(execFileCb);
7
+ const DOCDEX_ENV_URLS = ["MCODA_DOCDEX_URL", "DOCDEX_URL"];
8
+ const DEFAULT_DOCDEX_STATE_DIR = path.join(os.homedir(), ".docdex", "state");
9
+ const buildDocdexEnv = (env) => {
10
+ const merged = { ...process.env, ...(env ?? {}) };
11
+ if (!merged.DOCDEX_STATE_DIR) {
12
+ merged.DOCDEX_STATE_DIR = DEFAULT_DOCDEX_STATE_DIR;
13
+ }
14
+ return merged;
15
+ };
16
+ const resolveDocdexPackageRoot = () => {
17
+ try {
18
+ const require = createRequire(import.meta.url);
19
+ const pkgPath = require.resolve("docdex/package.json");
20
+ return path.dirname(pkgPath);
21
+ }
22
+ catch {
23
+ return undefined;
24
+ }
25
+ };
26
+ export const resolveDocdexBinary = () => {
27
+ const root = resolveDocdexPackageRoot();
28
+ if (!root)
29
+ return undefined;
30
+ return path.join(root, "bin", "docdex.js");
31
+ };
32
+ export const runDocdex = async (args, options = {}) => {
33
+ const binary = resolveDocdexBinary();
34
+ if (!binary) {
35
+ throw new Error("Docdex npm package not found. Install docdex and retry.");
36
+ }
37
+ const { stdout, stderr } = await execFile(process.execPath, [binary, ...args], {
38
+ cwd: options.cwd,
39
+ env: buildDocdexEnv(options.env),
40
+ });
41
+ return { stdout: stdout ?? "", stderr: stderr ?? "" };
42
+ };
43
+ const MAX_DOCDEX_SNIPPET = 240;
44
+ const formatDocdexSnippet = (value) => {
45
+ const trimmed = value.trim().replace(/\s+/g, " ");
46
+ if (trimmed.length <= MAX_DOCDEX_SNIPPET)
47
+ return trimmed;
48
+ return `${trimmed.slice(0, MAX_DOCDEX_SNIPPET)}...`;
49
+ };
50
+ export const parseDocdexCheckOutput = (output) => {
51
+ const trimmed = output.trim();
52
+ if (!trimmed) {
53
+ throw new Error("Docdex check returned empty output");
54
+ }
55
+ const attempts = [{ label: "full", candidate: trimmed }];
56
+ const braceStart = trimmed.indexOf("{");
57
+ const braceEnd = trimmed.lastIndexOf("}");
58
+ if (braceStart !== -1 && braceEnd > braceStart) {
59
+ attempts.push({ label: "brace-slice", candidate: trimmed.slice(braceStart, braceEnd + 1) });
60
+ }
61
+ const lines = trimmed.split(/\r?\n/);
62
+ for (let i = 0; i < lines.length; i += 1) {
63
+ const line = lines[i].trim();
64
+ if (!line.startsWith("{"))
65
+ continue;
66
+ const joined = lines.slice(i).join("\n").trim();
67
+ attempts.push({ label: "line-join", candidate: joined });
68
+ break;
69
+ }
70
+ let lastError;
71
+ for (const attempt of attempts) {
72
+ try {
73
+ return JSON.parse(attempt.candidate);
74
+ }
75
+ catch (error) {
76
+ lastError = error;
77
+ }
78
+ }
79
+ const snippet = formatDocdexSnippet(trimmed);
80
+ const message = lastError?.message ? `${lastError.message}. ` : "";
81
+ throw new Error(`Docdex check returned invalid JSON: ${message}Output: "${snippet}"`);
82
+ };
83
+ export const readDocdexCheck = async (options = {}) => {
84
+ let stdout = "";
85
+ let stderr = "";
86
+ try {
87
+ ({ stdout, stderr } = await runDocdex(["check"], options));
88
+ }
89
+ catch (error) {
90
+ const execError = error;
91
+ stdout = typeof execError.stdout === "string" ? execError.stdout : execError.stdout?.toString() ?? "";
92
+ stderr = typeof execError.stderr === "string" ? execError.stderr : execError.stderr?.toString() ?? "";
93
+ if (!stdout && !stderr) {
94
+ throw error;
95
+ }
96
+ }
97
+ const trimmed = stdout.trim() || stderr.trim();
98
+ return parseDocdexCheckOutput(trimmed);
99
+ };
100
+ export const summarizeDocdexCheck = (check) => {
101
+ const failures = check.checks?.filter((item) => item?.status && item.status !== "ok")?.map((item) => ({
102
+ name: item.name,
103
+ status: item.status,
104
+ message: item.message,
105
+ })) ?? [];
106
+ if (check.success === false || failures.length > 0) {
107
+ const details = failures
108
+ .map((item) => {
109
+ const head = item.name ? `${item.name}=${item.status ?? "error"}` : item.status ?? "error";
110
+ const tail = item.message ? ` (${item.message})` : "";
111
+ return `${head}${tail}`;
112
+ })
113
+ .join("; ");
114
+ return {
115
+ ok: false,
116
+ message: details || "Docdex check failed.",
117
+ failedChecks: failures,
118
+ };
119
+ }
120
+ return { ok: true };
121
+ };
122
+ export const resolveDocdexBaseUrl = async (options = {}) => {
123
+ for (const key of DOCDEX_ENV_URLS) {
124
+ const envValue = process.env[key];
125
+ if (envValue)
126
+ return envValue;
127
+ }
128
+ if (process.env.MCODA_SKIP_DOCDEX_CHECKS === "1" ||
129
+ process.env.MCODA_SKIP_DOCDEX_RUNTIME_CHECKS === "1" ||
130
+ (process.platform === "win32" && process.env.CI)) {
131
+ return undefined;
132
+ }
133
+ try {
134
+ const check = await readDocdexCheck(options);
135
+ const bind = check.checks?.find((c) => c.name === "bind")?.details;
136
+ const bindAddr = bind?.bind_addr;
137
+ if (!bindAddr)
138
+ return undefined;
139
+ if (bindAddr.startsWith("http://") || bindAddr.startsWith("https://"))
140
+ return bindAddr;
141
+ return `http://${bindAddr}`;
142
+ }
143
+ catch {
144
+ return undefined;
145
+ }
146
+ };
147
+ const coerceString = (value) => {
148
+ if (typeof value !== "string")
149
+ return undefined;
150
+ const trimmed = value.trim();
151
+ return trimmed ? trimmed : undefined;
152
+ };
153
+ const coerceChromiumDetails = (value) => {
154
+ if (!value || typeof value !== "object")
155
+ return undefined;
156
+ const details = value;
157
+ return {
158
+ path: coerceString(details.path),
159
+ manifestPath: coerceString(details.manifest_path ?? details.manifestPath),
160
+ installedAt: coerceString(details.installed_at ?? details.installedAt),
161
+ version: coerceString(details.version),
162
+ platform: coerceString(details.platform),
163
+ downloadUrl: coerceString(details.download_url ?? details.downloadUrl),
164
+ };
165
+ };
166
+ const buildBrowserSetupHint = (installHint) => {
167
+ const hint = installHint ?? "docdexd browser install";
168
+ return `Run \`${hint}\` to install the headless Chromium browser.`;
169
+ };
170
+ export const parseDocdexBrowserCheck = (check) => {
171
+ const browserCheck = check.checks?.find((c) => c.name === "browser");
172
+ const details = browserCheck?.details;
173
+ const chromium = coerceChromiumDetails(details?.chromium);
174
+ const installHint = coerceString(details?.install_hint);
175
+ const autoInstallEnabled = typeof details?.auto_install_enabled === "boolean" ? details.auto_install_enabled : undefined;
176
+ const configuredKind = coerceString(details?.configured_kind);
177
+ if (!browserCheck) {
178
+ const setupHint = buildBrowserSetupHint(installHint);
179
+ return {
180
+ ok: false,
181
+ message: `Docdex browser check unavailable. ${setupHint}`,
182
+ chromium,
183
+ installHint,
184
+ autoInstallEnabled,
185
+ configuredKind,
186
+ };
187
+ }
188
+ if (browserCheck.status !== "ok") {
189
+ const setupHint = buildBrowserSetupHint(installHint);
190
+ return {
191
+ ok: false,
192
+ message: `${browserCheck.message ?? "Docdex browser check failed."} ${setupHint}`,
193
+ chromium,
194
+ installHint,
195
+ autoInstallEnabled,
196
+ configuredKind,
197
+ };
198
+ }
199
+ return {
200
+ ok: true,
201
+ chromium,
202
+ installHint,
203
+ autoInstallEnabled,
204
+ configuredKind,
205
+ };
206
+ };
207
+ export const resolveDocdexBrowserInfo = async (options = {}) => {
208
+ try {
209
+ const check = await readDocdexCheck(options);
210
+ return parseDocdexBrowserCheck(check);
211
+ }
212
+ catch (error) {
213
+ const setupHint = buildBrowserSetupHint();
214
+ return {
215
+ ok: false,
216
+ message: `Docdex check failed: ${error.message}. ${setupHint}`,
217
+ };
218
+ }
219
+ };
package/dist/index.d.ts CHANGED
@@ -1,4 +1,5 @@
1
1
  export * from "./docdex/DocdexClient.js";
2
+ export * from "./docdex/DocdexRuntime.js";
2
3
  export * from "./telemetry/TelemetryClient.js";
3
4
  export * from "./vcs/VcsClient.js";
4
5
  export * from "./qa/index.js";
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,cAAc,0BAA0B,CAAC;AACzC,cAAc,gCAAgC,CAAC;AAC/C,cAAc,oBAAoB,CAAC;AACnC,cAAc,eAAe,CAAC;AAC9B,cAAc,0BAA0B,CAAC"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,cAAc,0BAA0B,CAAC;AACzC,cAAc,2BAA2B,CAAC;AAC1C,cAAc,gCAAgC,CAAC;AAC/C,cAAc,oBAAoB,CAAC;AACnC,cAAc,eAAe,CAAC;AAC9B,cAAc,0BAA0B,CAAC"}
package/dist/index.js CHANGED
@@ -1,4 +1,5 @@
1
1
  export * from "./docdex/DocdexClient.js";
2
+ export * from "./docdex/DocdexRuntime.js";
2
3
  export * from "./telemetry/TelemetryClient.js";
3
4
  export * from "./vcs/VcsClient.js";
4
5
  export * from "./qa/index.js";
@@ -1,10 +1,68 @@
1
1
  import { QaProfile } from '@mcoda/shared/qa/QaProfile.js';
2
+ import type { QaBrowserAction } from '@mcoda/shared/qa/QaPlan.js';
2
3
  import { QaAdapter } from './QaAdapter.js';
3
4
  import { QaContext, QaEnsureResult, QaRunResult } from './QaTypes.js';
5
+ type BrowserFetchResult = {
6
+ html: string;
7
+ innerText?: string;
8
+ textContent?: string;
9
+ status?: number;
10
+ finalUrl?: string;
11
+ };
12
+ type BrowserActionResult = {
13
+ index: number;
14
+ type: QaBrowserAction['type'];
15
+ ok: boolean;
16
+ message?: string;
17
+ url?: string;
18
+ durationMs?: number;
19
+ };
20
+ type BrowserActionSnapshot = {
21
+ index: number;
22
+ name: string;
23
+ html: string;
24
+ innerText?: string;
25
+ textContent?: string;
26
+ url?: string;
27
+ };
28
+ export declare const resolveChromiumBinary: () => Promise<string | undefined>;
29
+ declare class NetworkIdleTracker {
30
+ inflight: number;
31
+ lastActivity: number;
32
+ sawLoad: boolean;
33
+ documentStatus?: number;
34
+ documentUrl?: string;
35
+ handle(method: string, params?: any): void;
36
+ }
37
+ declare class CdpClient {
38
+ private ws;
39
+ private queue;
40
+ private nextId;
41
+ private closed;
42
+ static connect(wsUrl: string): Promise<CdpClient>;
43
+ private constructor();
44
+ call(method: string, params: Record<string, unknown>, tracker?: NetworkIdleTracker, timeoutMs?: number): Promise<any>;
45
+ waitForNetworkIdle(tracker: NetworkIdleTracker, timeoutMs: number): Promise<boolean>;
46
+ close(): void;
47
+ }
4
48
  export declare class ChromiumQaAdapter implements QaAdapter {
5
- private resolveCwd;
6
49
  ensureInstalled(profile: QaProfile, ctx: QaContext): Promise<QaEnsureResult>;
7
50
  private persistLogs;
51
+ private persistBrowserArtifacts;
8
52
  invoke(profile: QaProfile, ctx: QaContext): Promise<QaRunResult>;
53
+ private runBrowserActions;
54
+ private runBrowser;
9
55
  }
56
+ export declare const __testing: {
57
+ resolveActionUrl: (actionUrl: string | undefined, baseUrl: string | undefined) => string | undefined;
58
+ resolveActionTimeoutMs: (action: QaBrowserAction, fallbackMs: number) => number;
59
+ runBrowserActionsWithClient: (client: CdpClient, actions: QaBrowserAction[], baseUrl: string | undefined, timeoutMs: number) => Promise<{
60
+ outcome: "pass" | "fail";
61
+ errorMessage?: string;
62
+ results: BrowserActionResult[];
63
+ snapshots: BrowserActionSnapshot[];
64
+ finalDom?: BrowserFetchResult;
65
+ }>;
66
+ };
67
+ export {};
10
68
  //# sourceMappingURL=ChromiumQaAdapter.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"ChromiumQaAdapter.d.ts","sourceRoot":"","sources":["../../src/qa/ChromiumQaAdapter.ts"],"names":[],"mappings":"AAGA,OAAO,EAAE,SAAS,EAAE,MAAM,+BAA+B,CAAC;AAC1D,OAAO,EAAE,SAAS,EAAE,MAAM,gBAAgB,CAAC;AAC3C,OAAO,EAAE,SAAS,EAAE,cAAc,EAAE,WAAW,EAAE,MAAM,cAAc,CAAC;AAOtE,qBAAa,iBAAkB,YAAW,SAAS;IACjD,OAAO,CAAC,UAAU;IASZ,eAAe,CAAC,OAAO,EAAE,SAAS,EAAE,GAAG,EAAE,SAAS,GAAG,OAAO,CAAC,cAAc,CAAC;YAiBpE,WAAW;IAYnB,MAAM,CAAC,OAAO,EAAE,SAAS,EAAE,GAAG,EAAE,SAAS,GAAG,OAAO,CAAC,WAAW,CAAC;CAqCvE"}
1
+ {"version":3,"file":"ChromiumQaAdapter.d.ts","sourceRoot":"","sources":["../../src/qa/ChromiumQaAdapter.ts"],"names":[],"mappings":"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"}