@extension.dev/mcp 10.10.8 → 10.10.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.
- package/.claude-plugin/marketplace.json +1 -1
- package/.claude-plugin/plugin.json +1 -1
- package/CHANGELOG.md +133 -1
- package/README.md +12 -10
- package/claude/ARCHITECTURE.md +13 -13
- package/claude/CLAUDE.md +11 -10
- package/claude/README.md +4 -4
- package/claude/commands/extension-debug.md +1 -1
- package/claude/commands/extension-publish.md +1 -1
- package/claude/commands/extension.md +1 -1
- package/claude/rules/cross-browser.md +4 -3
- package/claude/rules/mcp-tools.md +446 -1009
- package/dist/module.js +7735 -3934
- package/dist/src/index.d.ts +1 -0
- package/dist/src/lib/allowance.d.ts +1 -1
- package/dist/src/lib/boot-verdict.d.ts +5 -0
- package/dist/src/lib/bridge-tabs.d.ts +3 -1
- package/dist/src/lib/browser-family.d.ts +1 -0
- package/dist/src/lib/carrier-registry.d.ts +4 -0
- package/dist/src/lib/carrier.d.ts +10 -1
- package/dist/src/lib/cdp-connection.d.ts +2 -1
- package/dist/src/lib/cdp-devtools.d.ts +1 -0
- package/dist/src/lib/cdp-extension-page.d.ts +14 -2
- package/dist/src/lib/cdp-page-scripts.d.ts +2 -2
- package/dist/src/lib/cdp-port.d.ts +1 -1
- package/dist/src/lib/cdp.d.ts +13 -1
- package/dist/src/lib/create-answer.d.ts +20 -0
- package/dist/src/lib/credential-source.d.ts +25 -0
- package/dist/src/lib/credentials.d.ts +24 -0
- package/dist/src/lib/device-flow.d.ts +4 -0
- package/dist/src/lib/docs-tools.d.ts +9 -0
- package/dist/src/lib/engine-manifest-view.d.ts +1 -0
- package/dist/src/lib/envelope.d.ts +1 -1
- package/dist/src/lib/exec.d.ts +2 -0
- package/dist/src/lib/extension-identity.d.ts +7 -0
- package/dist/src/lib/first-build.d.ts +15 -0
- package/dist/src/lib/guest-load-oracle.d.ts +2 -1
- package/dist/src/lib/launch-flags.d.ts +2 -2
- package/dist/src/lib/login-flow.d.ts +7 -0
- package/dist/src/lib/match-patterns.d.ts +1 -1
- package/dist/src/lib/node-engine.d.ts +11 -0
- package/dist/src/lib/platform-hold.d.ts +1 -0
- package/dist/src/lib/process-identity.d.ts +5 -0
- package/dist/src/lib/process-manager.d.ts +4 -0
- package/dist/src/lib/project-batch.d.ts +28 -0
- package/dist/src/lib/project-create-batch.d.ts +42 -0
- package/dist/src/lib/project-create-body.d.ts +14 -0
- package/dist/src/lib/project-manifest.d.ts +1 -0
- package/dist/src/lib/promote-outcome.d.ts +29 -0
- package/dist/src/lib/publish.d.ts +2 -0
- package/dist/src/lib/registry-access.d.ts +1 -0
- package/dist/src/lib/registry.d.ts +4 -1
- package/dist/src/lib/safari-automation.d.ts +2 -0
- package/dist/src/lib/session-browser.d.ts +5 -0
- package/dist/src/lib/session-paths.d.ts +1 -0
- package/dist/src/lib/store-review.d.ts +14 -2
- package/dist/src/lib/submit-outcome.d.ts +14 -0
- package/dist/src/lib/templates-cache.d.ts +13 -0
- package/dist/src/lib/types.d.ts +2 -1
- package/dist/src/lib/vendor/chrome-theme/chrome-theme-resolve.d.ts +1 -0
- package/dist/src/tools/assert.d.ts +3 -0
- package/dist/src/tools/auth.d.ts +8 -0
- package/dist/src/tools/create.d.ts +1 -0
- package/dist/src/tools/dev.d.ts +2 -2
- package/dist/src/tools/inspect-gecko.d.ts +1 -1
- package/dist/src/tools/login.d.ts +5 -0
- package/dist/src/tools/logs-filter.d.ts +5 -2
- package/dist/src/tools/open.d.ts +3 -0
- package/dist/src/tools/project-create.d.ts +11 -2
- package/dist/src/tools/start.d.ts +2 -2
- package/dist/src/tools/stop.d.ts +9 -0
- package/dist/src/tools/storage.d.ts +0 -5
- package/dist/src/tools/store-status.d.ts +4 -0
- package/extensions/live-preview/chromium/action/index.css +1 -1
- package/extensions/live-preview/chromium/action/index.js +1 -1
- package/extensions/live-preview/chromium/background/service_worker.js +98 -4
- package/extensions/live-preview/chromium/manifest.json +1 -1
- package/package.json +3 -2
- package/server.json +3 -3
package/dist/src/index.d.ts
CHANGED
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
import { Server } from "@modelcontextprotocol/sdk/server/index.js";
|
|
2
2
|
import { version } from "../package.json";
|
|
3
3
|
export { version };
|
|
4
|
+
export { renderToolsDoc } from "./lib/docs-tools";
|
|
4
5
|
import { type ServerOptions } from "./lib/tool-policy";
|
|
5
6
|
export interface ToolModule {
|
|
6
7
|
schema: {
|
|
@@ -15,6 +15,10 @@ export type BootVerdict = {
|
|
|
15
15
|
kind: "compile-failed";
|
|
16
16
|
message?: string;
|
|
17
17
|
compileErrors: string[];
|
|
18
|
+
} | {
|
|
19
|
+
kind: "boot-failed";
|
|
20
|
+
code?: string;
|
|
21
|
+
message?: string;
|
|
18
22
|
} | {
|
|
19
23
|
kind: "browser-exited";
|
|
20
24
|
stamp: {
|
|
@@ -43,4 +47,5 @@ export interface PollOptions {
|
|
|
43
47
|
intervalMs?: number;
|
|
44
48
|
}
|
|
45
49
|
export declare function speaksMachineContract(contract: unknown): boolean;
|
|
50
|
+
export declare function bootFailureHint(code: string | undefined): string;
|
|
46
51
|
export declare function pollBootVerdict(projectPath: string, browser: string, options: PollOptions): Promise<BootReading>;
|
|
@@ -9,7 +9,9 @@ export declare function listBridgeTabs(projectPath: string, browser: string, tim
|
|
|
9
9
|
error: string;
|
|
10
10
|
}>;
|
|
11
11
|
export declare function matchTabsByUrl(tabs: BridgeTab[], needle: string): BridgeTab[];
|
|
12
|
-
export declare function pollForBridgeTab(projectPath: string, browser: string, url: string, budgetMs: number): Promise<BridgeTab | null
|
|
12
|
+
export declare function pollForBridgeTab(projectPath: string, browser: string, url: string, budgetMs: number): Promise<BridgeTab | null | {
|
|
13
|
+
unreadable: string;
|
|
14
|
+
}>;
|
|
13
15
|
export interface NavigateTarget {
|
|
14
16
|
tab?: number;
|
|
15
17
|
newTab?: boolean;
|
|
@@ -3,3 +3,4 @@ export declare const GECKO_FAMILY: ReadonlySet<string>;
|
|
|
3
3
|
export declare const WEBKIT_FAMILY: ReadonlySet<string>;
|
|
4
4
|
export declare function isChromiumFamily(browser: string): boolean;
|
|
5
5
|
export declare function isGeckoFamily(browser: string): boolean;
|
|
6
|
+
export declare function engineBrowserName(browser: string): string;
|
|
@@ -1,4 +1,8 @@
|
|
|
1
1
|
export declare function rememberCarrier(projectPath: string): void;
|
|
2
2
|
export declare function forgetCarrier(projectPath: string): void;
|
|
3
3
|
export declare function carriersPlacedHere(): string[];
|
|
4
|
+
export declare function readRememberedCarriers(): {
|
|
5
|
+
carriers: string[];
|
|
6
|
+
unreadable: string | null;
|
|
7
|
+
};
|
|
4
8
|
export declare function rememberedCarriers(): string[];
|
|
@@ -1,5 +1,10 @@
|
|
|
1
1
|
export declare const CARRIER_DIR_NAME = "extension-dev-live-preview";
|
|
2
2
|
export declare const CARRIER_EXTENSION_ID = "ibppeifnekhjjjmpjfiobccjlicbmgcb";
|
|
3
|
+
export declare const CARRIER_TRUSTED_ORIGINS: readonly ["https://preview.extension.dev", "https://code.extension.dev", "https://themes.extension.dev"];
|
|
4
|
+
export declare const CARRIER_TRUSTED_LOCAL_HOSTS: readonly ["localhost", "127.0.0.1"];
|
|
5
|
+
export declare const CARRIER_TRUSTED_LOCAL_PORTS: readonly ["3103", "3104", "3110", "3111"];
|
|
6
|
+
export declare const CARRIER_REFUSAL_SENTENCE = "This page is not one the Live Preview carrier answers.";
|
|
7
|
+
export declare const CARRIER_ALLOWED_ORIGINS_SENTENCE: string;
|
|
3
8
|
export declare function carrierPath(projectPath: string): string;
|
|
4
9
|
export declare function isManagedCarrier(projectPath: string): boolean;
|
|
5
10
|
export type CarrierClaim = {
|
|
@@ -16,12 +21,16 @@ export type CarrierRemoval = {
|
|
|
16
21
|
note?: string;
|
|
17
22
|
};
|
|
18
23
|
export declare function removeCarrier(projectPath: string): CarrierRemoval;
|
|
19
|
-
export declare function ensureCarrierIgnored(projectPath: string):
|
|
24
|
+
export declare function ensureCarrierIgnored(projectPath: string): {
|
|
25
|
+
entry: string | null;
|
|
26
|
+
state: "added" | "already-ignored" | "not-a-repo" | "failed";
|
|
27
|
+
};
|
|
20
28
|
export type CarrierMaterialization = {
|
|
21
29
|
loaded: boolean;
|
|
22
30
|
path?: string;
|
|
23
31
|
note: string;
|
|
24
32
|
gitignored?: string;
|
|
33
|
+
gitignoreNote?: string;
|
|
25
34
|
limitations?: string[];
|
|
26
35
|
graduation?: string;
|
|
27
36
|
bridgeProtocol?: {
|
|
@@ -8,7 +8,7 @@ export declare class CDPConnection {
|
|
|
8
8
|
disconnect(): void;
|
|
9
9
|
private handleMessage;
|
|
10
10
|
private rejectAllPending;
|
|
11
|
-
sendCommand(method: string, params?: Record<string, unknown>, sessionId?: string): Promise<unknown>;
|
|
11
|
+
sendCommand(method: string, params?: Record<string, unknown>, sessionId?: string, timeoutMs?: number): Promise<unknown>;
|
|
12
12
|
getConsoleMessages(): Array<{
|
|
13
13
|
level: string;
|
|
14
14
|
text: string;
|
|
@@ -16,5 +16,6 @@ export declare class CDPConnection {
|
|
|
16
16
|
timestamp: number;
|
|
17
17
|
}>;
|
|
18
18
|
getConsoleSummary(): Record<string, unknown>;
|
|
19
|
+
resetConsole(): void;
|
|
19
20
|
protected onEvent(handler: (msg: Record<string, unknown>) => void): () => void;
|
|
20
21
|
}
|
|
@@ -6,9 +6,20 @@ export type ExtensionPageEval = {
|
|
|
6
6
|
ok: false;
|
|
7
7
|
message: string;
|
|
8
8
|
thrown: boolean;
|
|
9
|
+
timedOut?: boolean;
|
|
9
10
|
};
|
|
10
11
|
export declare function matchExtensionPageTargets(targets: PageTarget[], wantedUrl: string): PageTarget[];
|
|
11
12
|
export declare const WORKER_TARGET_TYPES: Set<string>;
|
|
13
|
+
export type TargetsRead<T> = {
|
|
14
|
+
targets: T[];
|
|
15
|
+
} | {
|
|
16
|
+
unreadable: string;
|
|
17
|
+
};
|
|
18
|
+
export declare function readExtensionWorkerTargets(port: number, extensionId: string): Promise<TargetsRead<{
|
|
19
|
+
targetId: string;
|
|
20
|
+
type: string;
|
|
21
|
+
url: string;
|
|
22
|
+
}>>;
|
|
12
23
|
export declare function findExtensionWorkerTargets(port: number, extensionId: string): Promise<Array<{
|
|
13
24
|
targetId: string;
|
|
14
25
|
type: string;
|
|
@@ -26,8 +37,9 @@ export type WorkerWake = {
|
|
|
26
37
|
reason: string;
|
|
27
38
|
};
|
|
28
39
|
export declare function wakeExtensionWorker(port: number, extensionId: string): Promise<WorkerWake>;
|
|
40
|
+
export declare function readExtensionPageTargets(port: number, wantedUrl: string): Promise<TargetsRead<PageTarget>>;
|
|
29
41
|
export declare function findExtensionPageTargets(port: number, wantedUrl: string): Promise<PageTarget[]>;
|
|
30
|
-
export declare function evaluateOnExtensionPage(port: number, targetId: string, expression: string): Promise<ExtensionPageEval>;
|
|
42
|
+
export declare function evaluateOnExtensionPage(port: number, targetId: string, expression: string, timeoutMs?: number): Promise<ExtensionPageEval>;
|
|
31
43
|
export type SidePanelGestureOutcome = {
|
|
32
44
|
opened: true;
|
|
33
45
|
targetId: string;
|
|
@@ -36,4 +48,4 @@ export type SidePanelGestureOutcome = {
|
|
|
36
48
|
opened: false;
|
|
37
49
|
reason: string;
|
|
38
50
|
};
|
|
39
|
-
export declare function openSidePanelWithSyntheticGesture(port: number, hostUrl: string): Promise<SidePanelGestureOutcome>;
|
|
51
|
+
export declare function openSidePanelWithSyntheticGesture(port: number, hostUrl: string, excludeTargetIds?: ReadonlySet<string>): Promise<SidePanelGestureOutcome>;
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
export declare const PAGE_HTML_SCRIPT = "(() => {\n try {\n const doctype = document.doctype;\n const dt = doctype\n ? '<!DOCTYPE ' + doctype.name\n + (doctype.publicId ? ' PUBLIC \"' + doctype.publicId + '\"' : '')\n + (doctype.systemId ? ' \"' + doctype.systemId + '\"' : '')\n + '>'\n : '';\n // Include shadow DOM content from extension roots\n const roots = Array.from(document.querySelectorAll(\n '#extension-root,[data-extension-root]:not([data-extension-root=\"extension-js-devtools\"])'\n ));\n if (roots.length) {\n const clone = document.documentElement.cloneNode(true);\n const clonedRoots = Array.from(clone.querySelectorAll(\n '#extension-root,[data-extension-root]:not([data-extension-root=\"extension-js-devtools\"])'\n ));\n const s = new XMLSerializer();\n for (let i = 0; i < Math.min(roots.length, clonedRoots.length); i++) {\n const sr = roots[i].shadowRoot;\n if (!sr) continue;\n try {\n const shadow = Array.from(sr.childNodes).map(n => {\n try { return s.serializeToString(n); } catch { return ''; }\n }).join('');\n if (shadow) clonedRoots[i].innerHTML = shadow;\n } catch {}\n }\n return dt + '\\n' + clone.outerHTML;\n }\n return dt + '\\n' + document.documentElement.outerHTML;\n } catch (e) { return ''; }\n })()";
|
|
2
2
|
export declare const PAGE_META_SCRIPT = "(() => {\n try {\n return {\n title: document.title,\n url: location.href,\n readyState: document.readyState,\n viewport: {\n width: window.innerWidth,\n height: window.innerHeight,\n devicePixelRatio: window.devicePixelRatio\n },\n frameCount: window.frames.length,\n scriptCount: document.querySelectorAll('script').length,\n styleCount: document.querySelectorAll('style,link[rel=\"stylesheet\"]').length\n };\n } catch { return {}; }\n })()";
|
|
3
|
-
export declare const EXTENSION_ROOT_META_SCRIPT = "(() => {\n try {\n const readGeneration = (node) => {\n const raw = node.getAttribute && node.getAttribute('data-extjs-reinject-generation');\n const parsed = Number(raw);\n return Number.isFinite(parsed) ? parsed : undefined;\n };\n const normalize = (node) => ({\n tag: node.tagName ? String(node.tagName).toLowerCase() : 'unknown',\n id: node.id || undefined,\n key: node.getAttribute ? node.getAttribute('data-extjs-reinject-key') || undefined : undefined,\n generation: readGeneration(node),\n status: node.getAttribute ? node.getAttribute('data-extjs-reinject-status') || undefined : undefined\n });\n const
|
|
4
|
-
export declare const RENDER_EVIDENCE_SCRIPT = "(() => {\n try {\n const body = document.body;\n const roots = document.querySelectorAll(\n '#extension-root,[data-extension-root]:not([data-extension-root=\"extension-js-devtools\"])'\n );\n const text = body ? (body.innerText || body.textContent || '') : '';\n return {\n readyState: document.readyState,\n title: document.title,\n bodyChildCount: body ? body.children.length : 0,\n bodyElementCount: body ? body.querySelectorAll('*').length : 0,\n textLength: text.trim().length,\n extensionRootCount: roots.length\n };\n } catch { return null; }\n })()";
|
|
3
|
+
export declare const EXTENSION_ROOT_META_SCRIPT = "(() => {\n try {\n const readGeneration = (node) => {\n const raw = node.getAttribute && node.getAttribute('data-extjs-reinject-generation');\n const parsed = Number(raw);\n return Number.isFinite(parsed) ? parsed : undefined;\n };\n const normalize = (node) => ({\n tag: node.tagName ? String(node.tagName).toLowerCase() : 'unknown',\n id: node.id || undefined,\n key: node.getAttribute ? node.getAttribute('data-extjs-reinject-key') || undefined : undefined,\n generation: readGeneration(node),\n status: node.getAttribute ? node.getAttribute('data-extjs-reinject-status') || undefined : undefined\n });\n const allRoots = Array.from(\n document.querySelectorAll('#extension-root,[data-extension-root]:not([data-extension-root=\"extension-js-devtools\"])')\n );\n const allMarkers = Array.from(\n document.querySelectorAll('[data-extjs-reinject-marker=\"true\"]')\n );\n const roots = allRoots.slice(0, 10).map(normalize);\n const markers = allMarkers.slice(0, 10).map(normalize);\n if (!roots.length && !markers.length) return null;\n const generations = [...roots, ...markers]\n .map(e => e.generation)\n .filter(g => typeof g === 'number');\n return {\n rootCount: allRoots.length,\n markerCount: allMarkers.length,\n listed: { roots: roots.length, markers: markers.length },\n truncated: allRoots.length > roots.length || allMarkers.length > markers.length,\n latestGeneration: generations.length ? Math.max(...generations) : 0,\n roots,\n markers\n };\n } catch { return null; }\n })()";
|
|
4
|
+
export declare const RENDER_EVIDENCE_SCRIPT = "(() => {\n try {\n const body = document.body;\n const roots = document.querySelectorAll(\n '#extension-root,[data-extension-root]:not([data-extension-root=\"extension-js-devtools\"])'\n );\n const text = body ? (body.innerText || body.textContent || '') : '';\n const INERT = new Set(['SCRIPT', 'STYLE', 'NOSCRIPT', 'TEMPLATE', 'LINK', 'META']);\n const VISUAL = new Set(['CANVAS', 'IMG', 'SVG', 'VIDEO', 'IFRAME', 'INPUT', 'TEXTAREA', 'SELECT', 'BUTTON']);\n let rendered = 0;\n let visual = 0;\n if (body) {\n for (const el of body.querySelectorAll('*')) {\n const tag = el.tagName.toUpperCase();\n if (INERT.has(tag) || el.closest('noscript, template')) continue;\n rendered += 1;\n if (VISUAL.has(tag)) visual += 1;\n }\n }\n const renderedText = body && typeof body.innerText === 'string' ? body.innerText : '';\n return {\n readyState: document.readyState,\n title: document.title,\n bodyChildCount: body ? body.children.length : 0,\n bodyElementCount: body ? body.querySelectorAll('*').length : 0,\n textLength: text.trim().length,\n renderedElementCount: rendered,\n visualElementCount: visual,\n renderedTextLength: renderedText.trim().length,\n extensionRootCount: roots.length\n };\n } catch { return null; }\n })()";
|
|
5
5
|
export declare function probeSelectorsScript(selectors: string[]): string;
|
|
6
6
|
export declare function domSnapshotScript(maxNodes: number): string;
|
|
@@ -3,7 +3,7 @@ export declare function resolveCdpPort(projectPath: string, browser: string, opt
|
|
|
3
3
|
graceMs?: number;
|
|
4
4
|
}): Promise<{
|
|
5
5
|
port: number;
|
|
6
|
-
source: "contract"
|
|
6
|
+
source: "contract";
|
|
7
7
|
} | null>;
|
|
8
8
|
export declare function resolveRdpPort(projectPath: string, browser: string, options?: {
|
|
9
9
|
waitMs?: number;
|
package/dist/src/lib/cdp.d.ts
CHANGED
|
@@ -5,8 +5,19 @@ export interface RenderEvidence {
|
|
|
5
5
|
bodyChildCount?: number;
|
|
6
6
|
bodyElementCount?: number;
|
|
7
7
|
textLength?: number;
|
|
8
|
+
renderedElementCount?: number;
|
|
9
|
+
visualElementCount?: number;
|
|
10
|
+
renderedTextLength?: number;
|
|
8
11
|
extensionRootCount?: number;
|
|
9
12
|
}
|
|
13
|
+
export interface DomSnapshot {
|
|
14
|
+
nodes: Array<Record<string, unknown>>;
|
|
15
|
+
totalElements: number;
|
|
16
|
+
truncated: boolean;
|
|
17
|
+
maxNodes: number;
|
|
18
|
+
maxDepth: number;
|
|
19
|
+
}
|
|
20
|
+
export declare function normalizeDomSnapshot(result: unknown, maxNodes: number): DomSnapshot;
|
|
10
21
|
export declare class CDPClient extends CDPConnection {
|
|
11
22
|
static discoverBrowserWsUrl(port: number, host?: string): Promise<string>;
|
|
12
23
|
static discoverBrowserVersion(port: number, host?: string): Promise<string | null>;
|
|
@@ -35,8 +46,9 @@ export declare class CDPClient extends CDPConnection {
|
|
|
35
46
|
selector: string;
|
|
36
47
|
count: number;
|
|
37
48
|
samples: Array<Record<string, unknown>>;
|
|
49
|
+
error?: string;
|
|
38
50
|
}>>;
|
|
39
|
-
getDomSnapshot(sessionId: string, maxNodes?: number): Promise<
|
|
51
|
+
getDomSnapshot(sessionId: string, maxNodes?: number): Promise<DomSnapshot>;
|
|
40
52
|
getRenderEvidence(sessionId: string): Promise<RenderEvidence | null>;
|
|
41
53
|
getExtensionRootMeta(sessionId: string): Promise<Record<string, unknown> | null>;
|
|
42
54
|
}
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
export type CreatedProject = {
|
|
2
|
+
ok: true;
|
|
3
|
+
projectId: string;
|
|
4
|
+
workspaceSlug: string;
|
|
5
|
+
projectSlug: string;
|
|
6
|
+
} | {
|
|
7
|
+
ok: false;
|
|
8
|
+
why: string;
|
|
9
|
+
};
|
|
10
|
+
export declare function readCreatedProject(body: unknown): CreatedProject;
|
|
11
|
+
export type CreatedWorkspace = {
|
|
12
|
+
ok: true;
|
|
13
|
+
id: string;
|
|
14
|
+
slug: string;
|
|
15
|
+
} | {
|
|
16
|
+
ok: false;
|
|
17
|
+
why: string;
|
|
18
|
+
};
|
|
19
|
+
export declare function readCreatedWorkspace(body: unknown): CreatedWorkspace;
|
|
20
|
+
export declare function answerIsUnknownOutcome(status: number, body: unknown): boolean;
|
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
export interface CredentialRef {
|
|
2
|
+
workspace: string;
|
|
3
|
+
project: string;
|
|
4
|
+
}
|
|
5
|
+
export interface TokenClaims extends CredentialRef {
|
|
6
|
+
expiresAt: number | null;
|
|
7
|
+
}
|
|
8
|
+
export declare function readTokenClaims(token: string): TokenClaims | null;
|
|
9
|
+
export declare function splitRef(name: string): CredentialRef | null;
|
|
10
|
+
export interface ResolvedCredential {
|
|
11
|
+
token: string;
|
|
12
|
+
source: "stored" | "env" | "none";
|
|
13
|
+
ref: CredentialRef | null;
|
|
14
|
+
refSource: "stored" | "named" | "env-claims" | "none";
|
|
15
|
+
mismatch: {
|
|
16
|
+
env: CredentialRef;
|
|
17
|
+
stored: CredentialRef;
|
|
18
|
+
} | null;
|
|
19
|
+
note: string | null;
|
|
20
|
+
}
|
|
21
|
+
export declare function resolveCredential(options?: {
|
|
22
|
+
project?: string;
|
|
23
|
+
}): ResolvedCredential;
|
|
24
|
+
export declare function credentialProjectRef(selector?: string): CredentialRef | null;
|
|
25
|
+
export declare function laneClosedByServer(err: unknown, code: string): boolean;
|
|
@@ -17,7 +17,29 @@ export interface CredentialSelector {
|
|
|
17
17
|
project?: string;
|
|
18
18
|
}
|
|
19
19
|
export declare function credentialKey(workspaceSlug: string, projectSlug: string): string;
|
|
20
|
+
export type CredentialStoreRead = {
|
|
21
|
+
state: "absent";
|
|
22
|
+
} | {
|
|
23
|
+
state: "ok";
|
|
24
|
+
store: CredentialStore;
|
|
25
|
+
} | {
|
|
26
|
+
state: "unreadable";
|
|
27
|
+
path: string;
|
|
28
|
+
reason: string;
|
|
29
|
+
};
|
|
30
|
+
export declare class CredentialStoreUnreadableError extends Error {
|
|
31
|
+
readonly path: string;
|
|
32
|
+
readonly reason: string;
|
|
33
|
+
constructor(file: string, reason: string);
|
|
34
|
+
}
|
|
35
|
+
export declare function inspectCredentialStore(): CredentialStoreRead;
|
|
20
36
|
export declare function readCredentialStore(): CredentialStore | null;
|
|
37
|
+
export declare function credentialStoreProblem(): {
|
|
38
|
+
path: string;
|
|
39
|
+
reason: string;
|
|
40
|
+
} | null;
|
|
41
|
+
export declare const TOKEN_TTL_SECONDS: number;
|
|
42
|
+
export declare function tokenExpiry(value: unknown): number;
|
|
21
43
|
export declare const PROJECT_PIN_ENV = "EXTENSION_DEV_PROJECT";
|
|
22
44
|
export declare function pinnedProject(): string;
|
|
23
45
|
export declare function isProjectRef(value: string): boolean;
|
|
@@ -28,11 +50,13 @@ export declare function listCredentials(): Array<StoredCredentials & {
|
|
|
28
50
|
active: boolean;
|
|
29
51
|
}>;
|
|
30
52
|
export declare function writeCredentials(creds: StoredCredentials): string;
|
|
53
|
+
export declare function writeCredentialBatch(batch: StoredCredentials[]): string | null;
|
|
31
54
|
export declare function clearCredentials(selector?: CredentialSelector): {
|
|
32
55
|
cleared: boolean;
|
|
33
56
|
path: string;
|
|
34
57
|
removed: string[];
|
|
35
58
|
remaining: string[];
|
|
59
|
+
failure?: string;
|
|
36
60
|
};
|
|
37
61
|
export declare function readValidCredentials(nowSeconds?: number, selector?: CredentialSelector): StoredCredentials | null;
|
|
38
62
|
export declare const PROJECT_TOKEN_INPUT: {
|
|
@@ -13,6 +13,7 @@ export declare function requestDeviceCode(args: {
|
|
|
13
13
|
apiBase: string;
|
|
14
14
|
path: string;
|
|
15
15
|
project?: string;
|
|
16
|
+
projects?: string[];
|
|
16
17
|
workspace?: string;
|
|
17
18
|
clientName?: string;
|
|
18
19
|
intent?: DeviceIntent;
|
|
@@ -33,11 +34,14 @@ export type DeviceGrantPollResult = {
|
|
|
33
34
|
ok: false;
|
|
34
35
|
reason: "pending" | "denied" | "expired" | "error";
|
|
35
36
|
message?: string;
|
|
37
|
+
code?: string;
|
|
38
|
+
body?: Record<string, unknown>;
|
|
36
39
|
};
|
|
37
40
|
export declare function pollDeviceGrant(args: {
|
|
38
41
|
apiBase: string;
|
|
39
42
|
path: string;
|
|
40
43
|
project?: string;
|
|
44
|
+
projects?: string[];
|
|
41
45
|
workspace?: string;
|
|
42
46
|
deviceCode: string;
|
|
43
47
|
interval: number;
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export declare function engineManifestView(manifest: Record<string, unknown>, browser: string): Record<string, unknown>;
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
export declare const ENVELOPE_SCHEMA: 1;
|
|
2
2
|
export declare const DECISION_D6 = "The MCP tool name owns the envelope `command` key; forking the key to `tool` would fork the schema the checksum test pins.";
|
|
3
|
-
export type ErrorCode = "E_AMBIGUOUS_TARGET" | "E_APPROVAL_PENDING" | "E_APPROVAL_REJECTED" | "E_APPROVAL_REQUIRED" | "E_AUTH_DENIED" | "E_AUTH_EXPIRED" | "E_AUTH_FAILED" | "E_AUTH_REQUIRED" | "E_BAD_HOST_URL" | "E_BAD_MANIFEST" | "E_BAD_REQUEST" | "E_BRIDGE" | "E_BROWSER_EXITED" | "E_BROWSER_INSTALL" | "E_BROWSER_UNINSTALL" | "E_BUILD_FAILED" | "E_CARRIER_IN_DIST" | "E_CDP" | "E_CLI" | "E_COMPILE" | "E_CONFIG" | "E_CONTRACT_ERROR" | "E_CONTROL_CHANNEL" | "E_CONTROL_ENVELOPE" | "E_ENGINE_TOO_OLD" | "E_ENTRYPOINT_MISSING" | "E_FIRST_COMPILE" | "E_INPUT_VALIDATION" | "E_INTERNAL" | "E_INVALID_BUNDLE_ID" | "E_LOGS_MISSING" | "E_MANIFEST_BLOCKING" | "E_MANIFEST_NOT_FOUND" | "E_NAVIGATE_ERROR" | "E_NAVIGATE_FAILED" | "E_NETWORK" | "E_NO_CONTROL_CHANNEL" | "E_NO_DIST" | "E_NO_EXTENSION_ID" | "E_NO_MATCHING_TARGET" | "E_NO_REFERENCE_TEMPLATE" | "E_NO_SESSION" | "E_NO_SURFACE_DOCUMENT" | "E_NO_TARGET" | "E_NOT_ATTACHED" | "E_PARSE" | "E_PLATFORM" | "E_PREVIEW_HOST_UNREACHABLE" | "E_PROFILE_LOCKED" | "E_RDP" | "E_SAFARI_ONLY_OPTION" | "E_EVAL" | "E_SCAFFOLD_FAILED" | "E_SCAFFOLD_INCOMPLETE" | "E_SESSION_EXISTS" | "E_SESSION_EXITED" | "E_STALE_CONTRACT" | "E_SURFACE_DID_NOT_OPEN" | "E_TEMPLATE_FETCH" | "E_TEMPLATE_NOT_FOUND" | "E_TOOL_DISABLED" | "E_UNKNOWN_COMMAND" | "E_UNKNOWN_TOOL" | "E_UNSUPPORTED_BROWSER" | "E_WAIT_TIMEOUT";
|
|
3
|
+
export type ErrorCode = "E_AMBIGUOUS_TARGET" | "E_APPROVAL_PENDING" | "E_APPROVAL_REJECTED" | "E_APPROVAL_REQUIRED" | "E_AUTH_DENIED" | "E_AUTH_EXPIRED" | "E_AUTH_FAILED" | "E_AUTH_REQUIRED" | "E_BAD_HOST_URL" | "E_BAD_MANIFEST" | "E_BAD_REQUEST" | "E_BRIDGE" | "E_BROWSER_EXITED" | "E_BROWSER_INSTALL" | "E_BROWSER_UNINSTALL" | "E_BUILD_FAILED" | "E_BUILD_NOT_FOUND" | "E_BUILD_TIMEOUT" | "E_CARRIER_IN_DIST" | "E_CDP" | "E_CLI" | "E_COMPILE" | "E_CONFIG" | "E_CONTRACT_ERROR" | "E_CONTROL_CHANNEL" | "E_CONTROL_ENVELOPE" | "E_ENGINE_TOO_OLD" | "E_ENTRYPOINT_MISSING" | "E_FIRST_COMPILE" | "E_INPUT_VALIDATION" | "E_INTERNAL" | "E_INVALID_BUNDLE_ID" | "E_LOGS_MISSING" | "E_MANIFEST_BLOCKING" | "E_MANIFEST_NOT_FOUND" | "E_NAVIGATE_ERROR" | "E_NAVIGATE_FAILED" | "E_NETWORK" | "E_NO_CONTROL_CHANNEL" | "E_NO_DIST" | "E_NO_THEME" | "E_NO_EXTENSION_ID" | "E_NO_MATCHING_TARGET" | "E_NO_REFERENCE_TEMPLATE" | "E_NO_SESSION" | "E_NO_SURFACE_DOCUMENT" | "E_NO_TARGET" | "E_NOT_ATTACHED" | "E_PARSE" | "E_PLATFORM" | "E_PREVIEW_HOST_UNREACHABLE" | "E_PROFILE_LOCKED" | "E_RDP" | "E_SAFARI_ONLY_OPTION" | "E_EVAL" | "E_EVAL_DISABLED" | "E_SCAFFOLD_FAILED" | "E_SCAFFOLD_INCOMPLETE" | "E_SESSION_EXISTS" | "E_SESSION_EXITED" | "E_STALE_CONTRACT" | "E_SURFACE_DID_NOT_OPEN" | "E_TEMPLATE_FETCH" | "E_TEMPLATE_NOT_FOUND" | "E_TOOL_DISABLED" | "E_UNKNOWN_COMMAND" | "E_UNKNOWN_TOOL" | "E_UNSUPPORTED_BROWSER" | "E_WAIT_TIMEOUT";
|
|
4
4
|
export declare const ERROR_CODES: ErrorCode[];
|
|
5
5
|
export interface EnvelopeError {
|
|
6
6
|
code: ErrorCode | string;
|
package/dist/src/lib/exec.d.ts
CHANGED
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
export declare function unpackedExtensionId(distPath: string): string;
|
|
2
|
+
export interface GuestIdentity {
|
|
3
|
+
expectedIds: string[];
|
|
4
|
+
companionIds: Set<string>;
|
|
5
|
+
source: "contract" | "dist-path" | "none";
|
|
6
|
+
}
|
|
7
|
+
export declare function sessionGuestIdentity(projectPath: string, browser: string): GuestIdentity;
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
export type FirstBuild = {
|
|
2
|
+
state: "dispatched";
|
|
3
|
+
} | {
|
|
4
|
+
state: "withheld";
|
|
5
|
+
reason: string;
|
|
6
|
+
} | {
|
|
7
|
+
state: "unsaid";
|
|
8
|
+
};
|
|
9
|
+
export declare function readFirstBuild(body: unknown): FirstBuild;
|
|
10
|
+
export declare function withheldBecause(reason: string): string;
|
|
11
|
+
export declare function firstBuildValue(build: FirstBuild): {
|
|
12
|
+
dispatched: boolean | null;
|
|
13
|
+
reason?: string;
|
|
14
|
+
};
|
|
15
|
+
export declare function firstBuildSentence(build: FirstBuild, buildsPageUrl: string): string;
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
export declare function isEngineCompanionUrl(url: string): boolean;
|
|
1
|
+
export declare function isEngineCompanionUrl(url: string, projectPath?: string, browser?: string): boolean;
|
|
2
2
|
export type GuestTarget = {
|
|
3
3
|
id: string;
|
|
4
4
|
type: string;
|
|
@@ -9,6 +9,7 @@ export type GuestLoadCheck = {
|
|
|
9
9
|
loaded: boolean;
|
|
10
10
|
guestTargets: GuestTarget[];
|
|
11
11
|
guestIds: string[];
|
|
12
|
+
otherExtensionIds?: string[];
|
|
12
13
|
cdpPort?: number;
|
|
13
14
|
reason: string;
|
|
14
15
|
};
|
|
@@ -9,11 +9,11 @@ export declare const LAUNCH_FLAG_SCHEMA: {
|
|
|
9
9
|
};
|
|
10
10
|
readonly chromiumBinary: {
|
|
11
11
|
readonly type: "string";
|
|
12
|
-
readonly description: "Custom Chromium-based binary (
|
|
12
|
+
readonly description: "Custom Chromium-based binary to launch; `browser` still names the target family the engine builds for (chromium-based when none is given).";
|
|
13
13
|
};
|
|
14
14
|
readonly geckoBinary: {
|
|
15
15
|
readonly type: "string";
|
|
16
|
-
readonly description: "Custom Gecko/Firefox binary (
|
|
16
|
+
readonly description: "Custom Gecko/Firefox binary to launch; `browser` still names the target family the engine builds for (gecko-based when none is given).";
|
|
17
17
|
};
|
|
18
18
|
readonly host: {
|
|
19
19
|
readonly type: "string";
|
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
import { type StoredCredentials } from "./credentials";
|
|
2
|
+
import { type BatchCapability } from "./project-batch";
|
|
2
3
|
export declare function tokenTtlNote(workspaceSlug?: string, projectSlug?: string): string;
|
|
3
4
|
type FetchImpl = typeof fetch;
|
|
4
5
|
export declare function resolveApiBase(api?: string): string;
|
|
@@ -13,6 +14,7 @@ export interface LoginConfig {
|
|
|
13
14
|
deviceCodeUrl: string;
|
|
14
15
|
deviceTokenUrl: string;
|
|
15
16
|
verificationUri: string;
|
|
17
|
+
batch: BatchCapability | null;
|
|
16
18
|
}
|
|
17
19
|
export declare function fetchLoginConfig(apiBase: string, fetchImpl?: FetchImpl): Promise<LoginConfig>;
|
|
18
20
|
export declare function persistTokenResponse(args: {
|
|
@@ -20,4 +22,9 @@ export declare function persistTokenResponse(args: {
|
|
|
20
22
|
project: string;
|
|
21
23
|
data: Record<string, unknown>;
|
|
22
24
|
}): StoredCredentials;
|
|
25
|
+
export declare function persistBatchTokenResponse(args: {
|
|
26
|
+
apiBase: string;
|
|
27
|
+
projects: string[];
|
|
28
|
+
data: Record<string, unknown>;
|
|
29
|
+
}): StoredCredentials[];
|
|
23
30
|
export {};
|
|
@@ -1,3 +1,3 @@
|
|
|
1
1
|
export declare function matchPatternCovers(pattern: string, url: string): boolean;
|
|
2
2
|
export declare function coveringMatches(patterns: string[], url: string): string[];
|
|
3
|
-
export declare function contentScriptsForbidden(url: string): string | null;
|
|
3
|
+
export declare function contentScriptsForbidden(url: string, browser?: string): string | null;
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
export declare function engineNodeRange(): {
|
|
2
|
+
range: string;
|
|
3
|
+
engine: string;
|
|
4
|
+
} | null;
|
|
5
|
+
export declare function meetsNodeRange(version: string, range: string): boolean | null;
|
|
6
|
+
export declare function nodeCheck(version: string): {
|
|
7
|
+
check: "node";
|
|
8
|
+
status: "pass" | "warn" | "fail";
|
|
9
|
+
detail: string;
|
|
10
|
+
remediation?: string;
|
|
11
|
+
};
|
|
@@ -2,6 +2,7 @@ export declare const PLATFORM_HOLD_CODE = "PLATFORM_NOT_OPEN";
|
|
|
2
2
|
export declare const PLATFORM_HOLD_HEADER = "x-extensiondev-hold";
|
|
3
3
|
export declare const PLATFORM_HOLD_STATUS = "platform-held";
|
|
4
4
|
export declare const PLATFORM_HOLD_RELAYS_THE_PLATFORM_DATE: boolean;
|
|
5
|
+
export declare const HOLD_STILL_WORKS_SENTENCE = "This does not stop you building. Creating, developing and packaging an extension run on your own machine, need no account and nothing from the platform, and work right now: extension_create scaffolds a project, extension_dev runs it in a real browser with live reload, extension_build produces the store-ready package for every browser you target, and extension_manifest_validate with extension_doctor check it before you ship. What is closed is the part that runs on extension.dev's machines: publishing, promoting a release, submitting to a store, hosting a preview share, requesting an approval, and creating a platform project or workspace.";
|
|
5
6
|
export declare const PLATFORM_HOLD_STILL_WORKS: string[];
|
|
6
7
|
export declare function templatesOrigin(apiHint?: string): string;
|
|
7
8
|
export declare function readPlatformCode(body: unknown): string;
|
|
@@ -0,0 +1,5 @@
|
|
|
1
|
+
export type PidState = "alive" | "dead" | "foreign";
|
|
2
|
+
export declare const PLAUSIBLE_SESSION_BINARY: RegExp;
|
|
3
|
+
export declare function processCommand(pid: number): string;
|
|
4
|
+
export declare function pidState(pid: number): PidState;
|
|
5
|
+
export declare function describeForeignPid(pid: number): string;
|
|
@@ -1,6 +1,10 @@
|
|
|
1
1
|
import type { ProcessInfo } from "./types";
|
|
2
2
|
export declare function sessionStateDir(): string;
|
|
3
3
|
export declare function removeSessionMarker(projectPath: string, browser: string, pid?: number): void;
|
|
4
|
+
export declare function readSessionMarkers(): {
|
|
5
|
+
markers: ProcessInfo[];
|
|
6
|
+
unreadable: string | null;
|
|
7
|
+
};
|
|
4
8
|
export declare function listSessionMarkers(): ProcessInfo[];
|
|
5
9
|
export declare function registerSession(info: ProcessInfo): void;
|
|
6
10
|
export declare function sessionSinceMs(projectPath: string, browser: string): number | null;
|
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
export declare const MAX_BATCH_PROJECTS = 20;
|
|
2
|
+
export declare const MAX_PROJECT_SLUG_LENGTH = 48;
|
|
3
|
+
export declare const MAX_WORKSPACE_SLUG_LENGTH = 64;
|
|
4
|
+
export declare const PLATFORM_CREATES_PER_HOUR = 10;
|
|
5
|
+
export declare const DEFAULT_CREATE_PROJECTS_PER_APPROVAL = 10;
|
|
6
|
+
export interface BatchCapability {
|
|
7
|
+
createProjectsPerApproval: number;
|
|
8
|
+
loginProjectsPerApproval: number;
|
|
9
|
+
}
|
|
10
|
+
export declare function readBatchCapability(config: unknown): BatchCapability | null;
|
|
11
|
+
export declare const BATCH_UNSUPPORTED_MESSAGE = "This platform does not advertise batch onboarding, so a list of projects was not sent and no device code was spent.";
|
|
12
|
+
export declare function isExactProjectSlug(slug: string): boolean;
|
|
13
|
+
export interface ProjectBatch {
|
|
14
|
+
workspace: string;
|
|
15
|
+
slugs: string[];
|
|
16
|
+
refs: string[];
|
|
17
|
+
}
|
|
18
|
+
export type ProjectBatchParse = {
|
|
19
|
+
ok: true;
|
|
20
|
+
batch: ProjectBatch;
|
|
21
|
+
} | {
|
|
22
|
+
ok: false;
|
|
23
|
+
message: string;
|
|
24
|
+
};
|
|
25
|
+
export declare function parseProjectBatch(input: unknown): ProjectBatchParse;
|
|
26
|
+
export declare function sameProjectSet(a: string[], b: string[]): boolean;
|
|
27
|
+
export declare function createRateLimitNote(): string;
|
|
28
|
+
export declare function createCapNote(cap: number): string;
|
|
@@ -0,0 +1,42 @@
|
|
|
1
|
+
export interface BatchCreateArgs {
|
|
2
|
+
projects?: unknown;
|
|
3
|
+
project?: unknown;
|
|
4
|
+
repo?: unknown;
|
|
5
|
+
installationId?: string;
|
|
6
|
+
displayName?: unknown;
|
|
7
|
+
description?: unknown;
|
|
8
|
+
installCommand?: string;
|
|
9
|
+
buildCommand?: string;
|
|
10
|
+
outputDirectory?: string;
|
|
11
|
+
browsers?: string[];
|
|
12
|
+
outputDirectories?: Record<string, unknown>;
|
|
13
|
+
deviceCode?: string;
|
|
14
|
+
api?: string;
|
|
15
|
+
}
|
|
16
|
+
interface BatchEntry {
|
|
17
|
+
ref: string;
|
|
18
|
+
workspace: string;
|
|
19
|
+
slug: string;
|
|
20
|
+
repo: string;
|
|
21
|
+
owner: string;
|
|
22
|
+
repoName: string;
|
|
23
|
+
displayName?: string;
|
|
24
|
+
description?: string;
|
|
25
|
+
installCommand?: string;
|
|
26
|
+
buildCommand?: string;
|
|
27
|
+
outputDirectory?: string;
|
|
28
|
+
browsers?: string[];
|
|
29
|
+
outputDirectories?: Record<string, unknown>;
|
|
30
|
+
}
|
|
31
|
+
export declare function resetBatchCreateSessions(): void;
|
|
32
|
+
export declare function parseBatchCreateArgs(args: BatchCreateArgs): {
|
|
33
|
+
ok: true;
|
|
34
|
+
workspace: string;
|
|
35
|
+
entries: BatchEntry[];
|
|
36
|
+
} | {
|
|
37
|
+
ok: false;
|
|
38
|
+
message: string;
|
|
39
|
+
hint?: string;
|
|
40
|
+
};
|
|
41
|
+
export declare function createProjectBatch(args: BatchCreateArgs): Promise<string>;
|
|
42
|
+
export {};
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
export declare function buildCreateBody(args: {
|
|
2
|
+
workspace: string;
|
|
3
|
+
projectSlug: string;
|
|
4
|
+
owner: string;
|
|
5
|
+
repoName: string;
|
|
6
|
+
installationId?: string;
|
|
7
|
+
displayName?: string;
|
|
8
|
+
description?: string;
|
|
9
|
+
installCommand?: string;
|
|
10
|
+
buildCommand?: string;
|
|
11
|
+
outputDirectory?: string;
|
|
12
|
+
browsers?: string[];
|
|
13
|
+
outputDirectories?: Record<string, unknown>;
|
|
14
|
+
}): Record<string, unknown>;
|
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
export interface PromoteNotarization {
|
|
2
|
+
pending: string[];
|
|
3
|
+
refused: {
|
|
4
|
+
browsers: string[];
|
|
5
|
+
reason: string;
|
|
6
|
+
upgradeUrl: string;
|
|
7
|
+
} | null;
|
|
8
|
+
}
|
|
9
|
+
export type PromoteOutcome = {
|
|
10
|
+
state: "promoted";
|
|
11
|
+
queuedBrowsers: string[];
|
|
12
|
+
notarization: PromoteNotarization;
|
|
13
|
+
} | {
|
|
14
|
+
state: "partial";
|
|
15
|
+
queuedBrowsers: string[];
|
|
16
|
+
failedBrowsers: string[];
|
|
17
|
+
pendingMirrors: string[];
|
|
18
|
+
githubReleaseFailed: boolean;
|
|
19
|
+
githubReleaseAssetErrors: string[];
|
|
20
|
+
notarization: PromoteNotarization;
|
|
21
|
+
} | {
|
|
22
|
+
state: "unconfirmed";
|
|
23
|
+
why: string;
|
|
24
|
+
};
|
|
25
|
+
export declare function readPromoteOutcome(body: unknown): PromoteOutcome;
|
|
26
|
+
export declare function notarizationNotes(notarization: PromoteNotarization): string[];
|
|
27
|
+
export declare function partialPromoteWarnings(outcome: Extract<PromoteOutcome, {
|
|
28
|
+
state: "partial";
|
|
29
|
+
}>, channel: string): string[];
|