abelworkflow 1.1.3 → 1.2.0
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/LICENSE +21 -0
- package/README.md +30 -29
- package/extensions/gpt-responses-compat.ts +213 -0
- package/extensions/k2think-compat.ts +40 -0
- package/lib/cli/args.mjs +5 -19
- package/lib/cli/main.mjs +105 -72
- package/lib/cli/prompts.mjs +9 -2
- package/lib/config/dotenv.mjs +1 -1
- package/lib/config/jsonc.mjs +1 -1
- package/lib/config/store.mjs +197 -45
- package/lib/config/toml.mjs +147 -453
- package/lib/installer/assets.mjs +67 -45
- package/lib/installer/install.mjs +202 -45
- package/lib/installer/links.mjs +124 -101
- package/lib/installer/lock.mjs +82 -0
- package/lib/installer/state.mjs +14 -21
- package/lib/paths.mjs +9 -9
- package/lib/providers/claude.mjs +58 -114
- package/lib/providers/codex.mjs +101 -198
- package/lib/providers/pi.mjs +331 -497
- package/lib/providers/skills.mjs +88 -68
- package/lib/providers/url.mjs +35 -0
- package/lib/templates/workflow/commands/abel-design.md +23 -161
- package/lib/templates/workflow/commands/abel-diagnose.md +30 -56
- package/lib/templates/workflow/commands/abel-implement.md +30 -150
- package/lib/templates/workflow/commands/abel-init.md +1 -1
- package/lib/tools/cli-installer.mjs +29 -190
- package/package.json +7 -9
- package/skills/context7-auto-research/context7-api.cjs +75 -17
- package/skills/dev-browser/SKILL.md +15 -1
- package/skills/dev-browser/dist/scripts/start.d.ts +0 -1
- package/skills/dev-browser/dist/scripts/start.js +8 -36
- package/skills/dev-browser/dist/src/client.d.ts +3 -4
- package/skills/dev-browser/dist/src/client.js +117 -117
- package/skills/dev-browser/dist/src/entrypoint.d.ts +1 -1
- package/skills/dev-browser/dist/src/entrypoint.js +38 -31
- package/skills/dev-browser/dist/src/index.d.ts +0 -1
- package/skills/dev-browser/dist/src/index.js +0 -1
- package/skills/dev-browser/dist/src/page-api.d.ts +0 -1
- package/skills/dev-browser/dist/src/page-api.js +0 -1
- package/skills/dev-browser/dist/src/relay.d.ts +0 -1
- package/skills/dev-browser/dist/src/relay.js +53 -7
- package/skills/dev-browser/dist/src/runtime.d.ts +3 -14
- package/skills/dev-browser/dist/src/runtime.js +5 -15
- package/skills/dev-browser/dist/src/snapshot/browser-script.d.ts +0 -1
- package/skills/dev-browser/dist/src/snapshot/browser-script.js +0 -1
- package/skills/dev-browser/dist/src/snapshot/index.d.ts +0 -1
- package/skills/dev-browser/dist/src/snapshot/index.js +0 -1
- package/skills/dev-browser/dist/src/snapshot/inject.d.ts +0 -1
- package/skills/dev-browser/dist/src/snapshot/inject.js +0 -1
- package/skills/dev-browser/dist/src/standalone.d.ts +0 -1
- package/skills/dev-browser/dist/src/standalone.js +2 -3
- package/skills/dev-browser/dist/src/startup.d.ts +3 -12
- package/skills/dev-browser/dist/src/startup.js +6 -10
- package/skills/dev-browser/dist/src/target-registry.d.ts +0 -1
- package/skills/dev-browser/dist/src/target-registry.js +0 -1
- package/skills/dev-browser/dist/src/types.d.ts +0 -1
- package/skills/dev-browser/dist/src/types.js +0 -1
- package/skills/dev-browser/package-lock.json +1 -1
- package/skills/dev-browser/package.json +2 -2
- package/skills/grok-search/.env.example +1 -1
- package/skills/grok-search/SKILL.md +13 -16
- package/skills/grok-search/scripts/_dotenv.py +1 -1
- package/skills/grok-search/scripts/groksearch_cli.py +271 -195
- package/skills/time/SKILL.md +5 -2
- package/skills/time/scripts/time_cli.py +61 -22
- package/extensions/pi-gpt-responses-compat/index.ts +0 -25
- package/lib/templates/codex/config-base.toml +0 -103
- package/skills/dev-browser/dist/scripts/start.d.ts.map +0 -1
- package/skills/dev-browser/dist/scripts/start.js.map +0 -1
- package/skills/dev-browser/dist/src/client.d.ts.map +0 -1
- package/skills/dev-browser/dist/src/client.js.map +0 -1
- package/skills/dev-browser/dist/src/entrypoint.d.ts.map +0 -1
- package/skills/dev-browser/dist/src/entrypoint.js.map +0 -1
- package/skills/dev-browser/dist/src/index.d.ts.map +0 -1
- package/skills/dev-browser/dist/src/index.js.map +0 -1
- package/skills/dev-browser/dist/src/page-api.d.ts.map +0 -1
- package/skills/dev-browser/dist/src/page-api.js.map +0 -1
- package/skills/dev-browser/dist/src/relay.d.ts.map +0 -1
- package/skills/dev-browser/dist/src/relay.js.map +0 -1
- package/skills/dev-browser/dist/src/runtime.d.ts.map +0 -1
- package/skills/dev-browser/dist/src/runtime.js.map +0 -1
- package/skills/dev-browser/dist/src/snapshot/browser-script.d.ts.map +0 -1
- package/skills/dev-browser/dist/src/snapshot/browser-script.js.map +0 -1
- package/skills/dev-browser/dist/src/snapshot/index.d.ts.map +0 -1
- package/skills/dev-browser/dist/src/snapshot/index.js.map +0 -1
- package/skills/dev-browser/dist/src/snapshot/inject.d.ts.map +0 -1
- package/skills/dev-browser/dist/src/snapshot/inject.js.map +0 -1
- package/skills/dev-browser/dist/src/standalone.d.ts.map +0 -1
- package/skills/dev-browser/dist/src/standalone.js.map +0 -1
- package/skills/dev-browser/dist/src/startup.d.ts.map +0 -1
- package/skills/dev-browser/dist/src/startup.js.map +0 -1
- package/skills/dev-browser/dist/src/target-registry.d.ts.map +0 -1
- package/skills/dev-browser/dist/src/target-registry.js.map +0 -1
- package/skills/dev-browser/dist/src/types.d.ts.map +0 -1
- package/skills/dev-browser/dist/src/types.js.map +0 -1
- package/skills/grok-search/gitignore.template +0 -4
- package/skills/grok-search/scripts/groksearch_entry.py +0 -131
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
import { isIP } from "node:net";
|
|
1
2
|
export const DEFAULT_HOST = "localhost";
|
|
2
3
|
const DEFAULT_PORT = 9222;
|
|
3
4
|
const DEFAULT_CDP_PORT = 9223;
|
|
@@ -12,18 +13,24 @@ export function formatWsUrl(host, port, path = "") {
|
|
|
12
13
|
return `ws://${formatHostForUrl(host)}:${port}${path}`;
|
|
13
14
|
}
|
|
14
15
|
export function resolveHostForProbe(host) {
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
if (
|
|
20
|
-
return
|
|
21
|
-
|
|
22
|
-
|
|
16
|
+
return normalizeLoopbackHost(host);
|
|
17
|
+
}
|
|
18
|
+
export function normalizeLoopbackHost(host) {
|
|
19
|
+
const normalized = host === "[::1]" ? "::1" : host.toLowerCase();
|
|
20
|
+
if (normalized === "localhost" || normalized === "::1")
|
|
21
|
+
return normalized;
|
|
22
|
+
if (isIP(normalized) === 4 && normalized.split(".")[0] === "127")
|
|
23
|
+
return normalized;
|
|
24
|
+
throw new Error(`Invalid host: ${host}. Only loopback hosts are allowed`);
|
|
23
25
|
}
|
|
24
26
|
export function parseEntrypointArgs(argv, env = process.env) {
|
|
25
27
|
let index = 0;
|
|
26
28
|
let mode = "standalone";
|
|
29
|
+
let host = env.HOST ?? DEFAULT_HOST;
|
|
30
|
+
let port = env.PORT ?? String(DEFAULT_PORT);
|
|
31
|
+
let portLabel = env.PORT === undefined ? "port" : "PORT";
|
|
32
|
+
let cdpPort = String(DEFAULT_CDP_PORT);
|
|
33
|
+
let headless = env.HEADLESS?.trim().toLowerCase() === "true";
|
|
27
34
|
const first = argv[0];
|
|
28
35
|
if (first && !first.startsWith("--")) {
|
|
29
36
|
if (first !== "standalone" && first !== "extension") {
|
|
@@ -32,36 +39,42 @@ export function parseEntrypointArgs(argv, env = process.env) {
|
|
|
32
39
|
mode = first;
|
|
33
40
|
index = 1;
|
|
34
41
|
}
|
|
35
|
-
const args = {
|
|
36
|
-
mode,
|
|
37
|
-
host: env.HOST?.trim() || DEFAULT_HOST,
|
|
38
|
-
port: readEnvPort(env.PORT, "PORT") ?? DEFAULT_PORT,
|
|
39
|
-
cdpPort: DEFAULT_CDP_PORT,
|
|
40
|
-
headless: env.HEADLESS?.trim().toLowerCase() === "true",
|
|
41
|
-
};
|
|
42
42
|
while (index < argv.length) {
|
|
43
43
|
const token = argv[index++];
|
|
44
44
|
switch (token) {
|
|
45
45
|
case "--headless":
|
|
46
|
-
|
|
46
|
+
if (mode === "extension") {
|
|
47
|
+
throw new Error("--headless is only valid in standalone mode");
|
|
48
|
+
}
|
|
49
|
+
headless = true;
|
|
47
50
|
break;
|
|
48
51
|
case "--host":
|
|
49
|
-
|
|
52
|
+
host = readValue(argv, index - 1);
|
|
50
53
|
index += 1;
|
|
51
54
|
break;
|
|
52
55
|
case "--port":
|
|
53
|
-
|
|
56
|
+
port = readValue(argv, index - 1);
|
|
57
|
+
portLabel = "port";
|
|
54
58
|
index += 1;
|
|
55
59
|
break;
|
|
56
60
|
case "--cdp-port":
|
|
57
|
-
|
|
61
|
+
if (mode === "extension") {
|
|
62
|
+
throw new Error("--cdp-port is only valid in standalone mode");
|
|
63
|
+
}
|
|
64
|
+
cdpPort = readValue(argv, index - 1);
|
|
58
65
|
index += 1;
|
|
59
66
|
break;
|
|
60
67
|
default:
|
|
61
68
|
throw new Error(`Unknown argument: ${token}`);
|
|
62
69
|
}
|
|
63
70
|
}
|
|
64
|
-
return
|
|
71
|
+
return {
|
|
72
|
+
mode,
|
|
73
|
+
host: normalizeLoopbackHost(host),
|
|
74
|
+
port: parsePort(port, portLabel),
|
|
75
|
+
cdpPort: parsePort(cdpPort, "cdpPort"),
|
|
76
|
+
headless,
|
|
77
|
+
};
|
|
65
78
|
}
|
|
66
79
|
export function formatReadinessLines(info) {
|
|
67
80
|
if (info.mode === "standalone") {
|
|
@@ -84,23 +97,17 @@ export function formatReadinessLines(info) {
|
|
|
84
97
|
}
|
|
85
98
|
function readValue(argv, optionIndex) {
|
|
86
99
|
const value = argv[optionIndex + 1];
|
|
87
|
-
if (
|
|
100
|
+
if (value === undefined || value.startsWith("--")) {
|
|
88
101
|
throw new Error(`Missing value for ${argv[optionIndex]}`);
|
|
89
102
|
}
|
|
90
103
|
return value;
|
|
91
104
|
}
|
|
92
105
|
function parsePort(value, label) {
|
|
93
|
-
|
|
94
|
-
|
|
106
|
+
if (!/^\d+$/.test(value))
|
|
107
|
+
throw new Error(`Invalid ${label}: ${value}`);
|
|
108
|
+
const port = Number(value);
|
|
109
|
+
if (port < 1 || port > 65535) {
|
|
95
110
|
throw new Error(`Invalid ${label}: ${value}`);
|
|
96
111
|
}
|
|
97
112
|
return port;
|
|
98
113
|
}
|
|
99
|
-
function readEnvPort(value, label) {
|
|
100
|
-
const normalized = value?.trim();
|
|
101
|
-
if (!normalized) {
|
|
102
|
-
return undefined;
|
|
103
|
-
}
|
|
104
|
-
return parsePort(normalized, label);
|
|
105
|
-
}
|
|
106
|
-
//# sourceMappingURL=entrypoint.js.map
|
|
@@ -1,4 +1,3 @@
|
|
|
1
1
|
export { createStandaloneApp, createStandalonePageBackend, serve } from "./standalone.js";
|
|
2
2
|
export type { DevBrowserServer } from "./standalone.js";
|
|
3
3
|
export type { GetPageResponse, ListPagesResponse, ServeOptions, ServerInfoResponse, } from "./types.js";
|
|
4
|
-
//# sourceMappingURL=index.d.ts.map
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import { serve } from "@hono/node-server";
|
|
2
2
|
import { createNodeWebSocket } from "@hono/node-ws";
|
|
3
3
|
import { Hono } from "hono";
|
|
4
|
-
import { formatHttpUrl, formatWsUrl } from "./entrypoint.js";
|
|
4
|
+
import { formatHttpUrl, formatWsUrl, normalizeLoopbackHost } from "./entrypoint.js";
|
|
5
5
|
import { PageBackendError, createPageApi, } from "./page-api.js";
|
|
6
6
|
import { createTargetRegistry, } from "./target-registry.js";
|
|
7
7
|
export const WEBSOCKET_POLICY_VIOLATION_CODE = 1008;
|
|
@@ -39,6 +39,37 @@ function isCdpCommand(value) {
|
|
|
39
39
|
&& (value.params === undefined || isRecord(value.params))
|
|
40
40
|
&& (value.sessionId === undefined || typeof value.sessionId === "string");
|
|
41
41
|
}
|
|
42
|
+
function isTargetInfo(value) {
|
|
43
|
+
return isRecord(value)
|
|
44
|
+
&& typeof value.targetId === "string"
|
|
45
|
+
&& typeof value.type === "string"
|
|
46
|
+
&& typeof value.title === "string"
|
|
47
|
+
&& typeof value.url === "string"
|
|
48
|
+
&& typeof value.attached === "boolean";
|
|
49
|
+
}
|
|
50
|
+
function isExtensionEvent(value) {
|
|
51
|
+
if (!isRecord(value) || value.method !== "forwardCDPEvent" || !isRecord(value.params)) {
|
|
52
|
+
return false;
|
|
53
|
+
}
|
|
54
|
+
const event = value.params;
|
|
55
|
+
if (typeof event.method !== "string"
|
|
56
|
+
|| (event.params !== undefined && !isRecord(event.params))
|
|
57
|
+
|| (event.sessionId !== undefined && typeof event.sessionId !== "string")) {
|
|
58
|
+
return false;
|
|
59
|
+
}
|
|
60
|
+
if (event.method === "Target.attachedToTarget") {
|
|
61
|
+
return isRecord(event.params)
|
|
62
|
+
&& typeof event.params.sessionId === "string"
|
|
63
|
+
&& isTargetInfo(event.params.targetInfo);
|
|
64
|
+
}
|
|
65
|
+
if (event.method === "Target.detachedFromTarget") {
|
|
66
|
+
return isRecord(event.params) && typeof event.params.sessionId === "string";
|
|
67
|
+
}
|
|
68
|
+
if (event.method === "Target.targetInfoChanged") {
|
|
69
|
+
return isRecord(event.params) && isTargetInfo(event.params.targetInfo);
|
|
70
|
+
}
|
|
71
|
+
return true;
|
|
72
|
+
}
|
|
42
73
|
export function createExtensionPageBackend({ registry, isConnected, sendCommand, timeoutMs, }) {
|
|
43
74
|
const pending = new Map();
|
|
44
75
|
async function create(name) {
|
|
@@ -72,7 +103,10 @@ export function createExtensionPageBackend({ registry, isConnected, sendCommand,
|
|
|
72
103
|
async list() {
|
|
73
104
|
return registry.list();
|
|
74
105
|
},
|
|
75
|
-
async getOrCreate(name) {
|
|
106
|
+
async getOrCreate(name, viewport) {
|
|
107
|
+
if (viewport) {
|
|
108
|
+
throw new PageBackendError(400, "viewport is not supported in extension mode");
|
|
109
|
+
}
|
|
76
110
|
const existing = registry.getByName(name);
|
|
77
111
|
if (existing)
|
|
78
112
|
return { name, targetId: existing.targetId };
|
|
@@ -118,7 +152,10 @@ export function createExtensionPageBackend({ registry, isConnected, sendCommand,
|
|
|
118
152
|
}
|
|
119
153
|
export async function serveRelay(options = {}) {
|
|
120
154
|
const requestedPort = options.port ?? 9222;
|
|
121
|
-
const host = options.host ?? "127.0.0.1";
|
|
155
|
+
const host = normalizeLoopbackHost(options.host ?? "127.0.0.1");
|
|
156
|
+
if (!Number.isInteger(requestedPort) || requestedPort < 1 || requestedPort > 65535) {
|
|
157
|
+
throw new Error(`Invalid port: ${requestedPort}. Must be between 1 and 65535`);
|
|
158
|
+
}
|
|
122
159
|
const targetTimeoutMs = options.targetTimeoutMs ?? 5000;
|
|
123
160
|
const wsEndpoint = formatWsUrl(host, requestedPort, "/cdp");
|
|
124
161
|
const registry = createTargetRegistry();
|
|
@@ -219,6 +256,12 @@ export async function serveRelay(options = {}) {
|
|
|
219
256
|
extensionWs = null;
|
|
220
257
|
closePlaywrightClients(error.message);
|
|
221
258
|
}
|
|
259
|
+
function closeInvalidExtension(ws, code, reason) {
|
|
260
|
+
if (extensionWs === ws) {
|
|
261
|
+
disconnectExtension(new PageBackendError(502, reason));
|
|
262
|
+
}
|
|
263
|
+
ws.close(code, reason);
|
|
264
|
+
}
|
|
222
265
|
async function sendToExtension(method, params, timeoutMs = 30_000) {
|
|
223
266
|
const ws = extensionWs;
|
|
224
267
|
if (!ws)
|
|
@@ -427,11 +470,11 @@ export async function serveRelay(options = {}) {
|
|
|
427
470
|
parsed = JSON.parse(event.data.toString());
|
|
428
471
|
}
|
|
429
472
|
catch {
|
|
430
|
-
ws
|
|
473
|
+
closeInvalidExtension(ws, 1000, "Invalid JSON");
|
|
431
474
|
return;
|
|
432
475
|
}
|
|
433
476
|
if (!isRecord(parsed)) {
|
|
434
|
-
ws
|
|
477
|
+
closeInvalidExtension(ws, 1003, "Invalid extension message");
|
|
435
478
|
return;
|
|
436
479
|
}
|
|
437
480
|
const message = parsed;
|
|
@@ -450,7 +493,11 @@ export async function serveRelay(options = {}) {
|
|
|
450
493
|
}
|
|
451
494
|
if (message.method !== "forwardCDPEvent")
|
|
452
495
|
return;
|
|
453
|
-
|
|
496
|
+
if (!isExtensionEvent(parsed)) {
|
|
497
|
+
closeInvalidExtension(ws, 1003, "Invalid extension message");
|
|
498
|
+
return;
|
|
499
|
+
}
|
|
500
|
+
const { method, params, sessionId } = parsed.params;
|
|
454
501
|
if (method === "Target.attachedToTarget") {
|
|
455
502
|
const attached = params;
|
|
456
503
|
const target = {
|
|
@@ -518,4 +565,3 @@ function waitForListening(server) {
|
|
|
518
565
|
function errorMessage(error) {
|
|
519
566
|
return error instanceof Error ? error.message : String(error);
|
|
520
567
|
}
|
|
521
|
-
//# sourceMappingURL=relay.js.map
|
|
@@ -1,7 +1,3 @@
|
|
|
1
|
-
export interface RuntimeCommand {
|
|
2
|
-
command: string;
|
|
3
|
-
args: string[];
|
|
4
|
-
}
|
|
5
1
|
export interface TcpPortProbe {
|
|
6
2
|
once(event: "error" | "listening", listener: () => void): this;
|
|
7
3
|
listen(port: number, host: string): unknown;
|
|
@@ -27,19 +23,12 @@ export interface InvalidRuntimeDependenciesOptions {
|
|
|
27
23
|
lockedDependencies: Record<string, string>;
|
|
28
24
|
readPackageVersion: (packageJsonPath: string) => string | undefined;
|
|
29
25
|
}
|
|
30
|
-
export declare function
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
nodeExecutable?: string;
|
|
34
|
-
}): RuntimeCommand;
|
|
26
|
+
export declare function assertRuntimeDependenciesAvailable({ invalidDependencies, }: {
|
|
27
|
+
invalidDependencies: string[];
|
|
28
|
+
}): void;
|
|
35
29
|
export declare function isTcpPortInUse(port: number, host?: string, createProbe?: TcpPortProbeFactory): Promise<boolean>;
|
|
36
30
|
export declare function isPlaywrightChromiumInstalled({ headless, findExecutable, exists, }: ChromiumInstallCheckOptions): boolean;
|
|
37
31
|
export declare function getLockedRuntimeDependencies(lockfile: RuntimePackageLock): Record<string, string>;
|
|
38
32
|
export declare function getInvalidRuntimeDependencies({ skillDir, lockedDependencies, readPackageVersion, }: InvalidRuntimeDependenciesOptions): string[];
|
|
39
|
-
export declare function resolveRuntimePaths(skillDir: string): {
|
|
40
|
-
skillDir: string;
|
|
41
|
-
};
|
|
42
33
|
export declare function resolveImportMetaDir(moduleUrl: string): string;
|
|
43
34
|
export declare function resolveSkillDirFromEntrypoint(moduleUrl: string): string;
|
|
44
|
-
export declare function shouldUseShellForPackageCommands(platform: NodeJS.Platform): boolean;
|
|
45
|
-
//# sourceMappingURL=runtime.d.ts.map
|
|
@@ -1,14 +1,11 @@
|
|
|
1
1
|
import { createServer } from "node:net";
|
|
2
2
|
import { basename, dirname, join } from "node:path";
|
|
3
3
|
import { fileURLToPath } from "node:url";
|
|
4
|
-
export function
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
command: nodeExecutable,
|
|
10
|
-
args: [join(skillDir, "node_modules", "playwright", "cli.js"), "install", "chromium"],
|
|
11
|
-
};
|
|
4
|
+
export function assertRuntimeDependenciesAvailable({ invalidDependencies, }) {
|
|
5
|
+
if (invalidDependencies.length === 0)
|
|
6
|
+
return;
|
|
7
|
+
throw new Error(`Runtime dependencies missing or out of date: ${invalidDependencies.join(", ")}. ` +
|
|
8
|
+
"From the dev-browser skill directory, run: npm ci --omit=dev");
|
|
12
9
|
}
|
|
13
10
|
export async function isTcpPortInUse(port, host = "127.0.0.1", createProbe = createServer) {
|
|
14
11
|
return await new Promise((resolve) => {
|
|
@@ -38,9 +35,6 @@ export function getInvalidRuntimeDependencies({ skillDir, lockedDependencies, re
|
|
|
38
35
|
? []
|
|
39
36
|
: [name]);
|
|
40
37
|
}
|
|
41
|
-
export function resolveRuntimePaths(skillDir) {
|
|
42
|
-
return { skillDir };
|
|
43
|
-
}
|
|
44
38
|
export function resolveImportMetaDir(moduleUrl) {
|
|
45
39
|
return dirname(fileURLToPath(moduleUrl));
|
|
46
40
|
}
|
|
@@ -48,7 +42,3 @@ export function resolveSkillDirFromEntrypoint(moduleUrl) {
|
|
|
48
42
|
const parentDir = dirname(resolveImportMetaDir(moduleUrl));
|
|
49
43
|
return basename(parentDir) === "dist" ? dirname(parentDir) : parentDir;
|
|
50
44
|
}
|
|
51
|
-
export function shouldUseShellForPackageCommands(platform) {
|
|
52
|
-
return platform === "win32";
|
|
53
|
-
}
|
|
54
|
-
//# sourceMappingURL=runtime.js.map
|
|
@@ -29,4 +29,3 @@ export declare function createStandaloneApp({ backend, wsEndpoint, }: {
|
|
|
29
29
|
}): Hono<import("hono/types").BlankEnv, import("hono/types").BlankSchema, "/">;
|
|
30
30
|
export declare function serve(options?: ServeOptions): Promise<DevBrowserServer>;
|
|
31
31
|
export type { ServeOptions } from "./types.js";
|
|
32
|
-
//# sourceMappingURL=standalone.d.ts.map
|
|
@@ -2,7 +2,7 @@ import { once } from "node:events";
|
|
|
2
2
|
import { serve as serveNode } from "@hono/node-server";
|
|
3
3
|
import { Hono } from "hono";
|
|
4
4
|
import { chromium } from "playwright";
|
|
5
|
-
import { formatHttpUrl } from "./entrypoint.js";
|
|
5
|
+
import { formatHttpUrl, normalizeLoopbackHost } from "./entrypoint.js";
|
|
6
6
|
import { createPageApi, } from "./page-api.js";
|
|
7
7
|
export function createStandalonePageBackend(context) {
|
|
8
8
|
const pages = new Map();
|
|
@@ -81,7 +81,7 @@ export function createStandaloneApp({ backend, wsEndpoint, }) {
|
|
|
81
81
|
}
|
|
82
82
|
export async function serve(options = {}) {
|
|
83
83
|
const port = options.port ?? 9222;
|
|
84
|
-
const host = options.host ?? "localhost";
|
|
84
|
+
const host = normalizeLoopbackHost(options.host ?? "localhost");
|
|
85
85
|
const cdpPort = options.cdpPort ?? 9223;
|
|
86
86
|
validatePorts(port, cdpPort);
|
|
87
87
|
const context = await chromium.launchPersistentContext("", {
|
|
@@ -171,4 +171,3 @@ function closeServer(server) {
|
|
|
171
171
|
server.close((error) => (error ? reject(error) : resolve()));
|
|
172
172
|
});
|
|
173
173
|
}
|
|
174
|
-
//# sourceMappingURL=standalone.js.map
|
|
@@ -1,8 +1,4 @@
|
|
|
1
1
|
import { type EntrypointArgs } from "./entrypoint.js";
|
|
2
|
-
import type { RuntimeCommand } from "./runtime.js";
|
|
3
|
-
export interface RuntimePaths {
|
|
4
|
-
skillDir: string;
|
|
5
|
-
}
|
|
6
2
|
interface StandaloneServer {
|
|
7
3
|
port: number;
|
|
8
4
|
wsEndpoint: string;
|
|
@@ -14,7 +10,6 @@ interface ExtensionServer {
|
|
|
14
10
|
stop: () => Promise<void>;
|
|
15
11
|
}
|
|
16
12
|
export interface RunEntrypointDeps {
|
|
17
|
-
runtimePaths: RuntimePaths;
|
|
18
13
|
serveStandalone: (options: {
|
|
19
14
|
port: number;
|
|
20
15
|
host: string;
|
|
@@ -31,11 +26,8 @@ export interface RunEntrypointDeps {
|
|
|
31
26
|
ensureBrowser?: () => Promise<void>;
|
|
32
27
|
preflightStandalone?: () => Promise<boolean>;
|
|
33
28
|
}
|
|
34
|
-
export interface
|
|
29
|
+
export interface PlaywrightChromiumPreflightDeps {
|
|
35
30
|
isInstalled: () => boolean;
|
|
36
|
-
installCommand: RuntimeCommand;
|
|
37
|
-
runCommand: (command: string, args: string[]) => Promise<void>;
|
|
38
|
-
log: (line: string) => void;
|
|
39
31
|
}
|
|
40
32
|
export interface PreflightStandaloneStartupDeps {
|
|
41
33
|
checkServer: (host: string, port: number) => Promise<{
|
|
@@ -45,11 +37,10 @@ export interface PreflightStandaloneStartupDeps {
|
|
|
45
37
|
wsEndpoint?: unknown;
|
|
46
38
|
};
|
|
47
39
|
}>;
|
|
48
|
-
isPortInUse: (port: number) => Promise<boolean>;
|
|
40
|
+
isPortInUse: (port: number, host: string) => Promise<boolean>;
|
|
49
41
|
log: (line: string) => void;
|
|
50
42
|
}
|
|
51
43
|
export declare function preflightStandaloneStartup(args: EntrypointArgs, deps: PreflightStandaloneStartupDeps): Promise<boolean>;
|
|
52
|
-
export declare function
|
|
44
|
+
export declare function assertPlaywrightChromiumAvailable(deps: PlaywrightChromiumPreflightDeps): void;
|
|
53
45
|
export declare function runEntrypoint(args: EntrypointArgs, deps: RunEntrypointDeps): Promise<void>;
|
|
54
46
|
export {};
|
|
55
|
-
//# sourceMappingURL=startup.d.ts.map
|
|
@@ -8,22 +8,19 @@ export async function preflightStandaloneStartup(args, deps) {
|
|
|
8
8
|
deps.log(`Server already running on port ${args.port}`);
|
|
9
9
|
return false;
|
|
10
10
|
}
|
|
11
|
-
if (await deps.isPortInUse(args.port)) {
|
|
11
|
+
if (await deps.isPortInUse(args.port, args.host)) {
|
|
12
12
|
throw new Error(`HTTP port ${args.port} is already in use. Stop the existing service or use --port.`);
|
|
13
13
|
}
|
|
14
|
-
if (await deps.isPortInUse(args.cdpPort)) {
|
|
14
|
+
if (await deps.isPortInUse(args.cdpPort, "127.0.0.1")) {
|
|
15
15
|
throw new Error(`CDP port ${args.cdpPort} is already in use. Close the existing browser or use --cdp-port.`);
|
|
16
16
|
}
|
|
17
17
|
return true;
|
|
18
18
|
}
|
|
19
|
-
export
|
|
20
|
-
if (deps.isInstalled())
|
|
21
|
-
deps.log("Playwright Chromium already installed.");
|
|
19
|
+
export function assertPlaywrightChromiumAvailable(deps) {
|
|
20
|
+
if (deps.isInstalled())
|
|
22
21
|
return;
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
await deps.runCommand(deps.installCommand.command, deps.installCommand.args);
|
|
26
|
-
deps.log("Chromium installed successfully.");
|
|
22
|
+
throw new Error("Playwright Chromium is missing. From the dev-browser skill directory, run: " +
|
|
23
|
+
"node node_modules/playwright/cli.js install chromium");
|
|
27
24
|
}
|
|
28
25
|
export async function runEntrypoint(args, deps) {
|
|
29
26
|
if (args.mode === "extension") {
|
|
@@ -78,4 +75,3 @@ export async function runEntrypoint(args, deps) {
|
|
|
78
75
|
throw error;
|
|
79
76
|
}
|
|
80
77
|
}
|
|
81
|
-
//# sourceMappingURL=startup.js.map
|
|
@@ -13,7 +13,7 @@
|
|
|
13
13
|
}
|
|
14
14
|
},
|
|
15
15
|
"scripts": {
|
|
16
|
-
"build": "tsc -p tsconfig.json",
|
|
16
|
+
"build": "node -e \"require('node:fs').rmSync('dist',{recursive:true,force:true})\" && tsc -p tsconfig.json",
|
|
17
17
|
"typecheck": "tsc -p tsconfig.json --noEmit",
|
|
18
18
|
"start": "node dist/scripts/start.js standalone",
|
|
19
19
|
"start-server": "node dist/scripts/start.js standalone",
|
|
@@ -25,7 +25,7 @@
|
|
|
25
25
|
"@hono/node-server": "^1.19.13",
|
|
26
26
|
"@hono/node-ws": "^1.3.1",
|
|
27
27
|
"hono": "^4.12.30",
|
|
28
|
-
"playwright": "^1.
|
|
28
|
+
"playwright": "^1.56.0"
|
|
29
29
|
},
|
|
30
30
|
"devDependencies": {
|
|
31
31
|
"@types/node": "^22.0.0",
|
|
@@ -11,28 +11,26 @@ Use this skill for web search, webpage retrieval, and current-information lookup
|
|
|
11
11
|
|
|
12
12
|
## Rules
|
|
13
13
|
|
|
14
|
-
-
|
|
15
|
-
-
|
|
16
|
-
-
|
|
14
|
+
- Install dependencies in an environment you choose before first use: `python -m pip install -r "<SKILL_DIR>/requirements.txt"`.
|
|
15
|
+
- Always call `python "<SKILL_DIR>/scripts/groksearch_cli.py" ...` from that environment.
|
|
16
|
+
- Provide credentials through external environment variables. AbelWorkflow installations may use the restricted installed config at `<SKILL_DIR>/.env`; do not create a source-tree `.env`.
|
|
17
17
|
- Required env: `GROK_API_URL`, `GROK_API_KEY`.
|
|
18
|
-
- Optional env: `GROK_MODEL`, `GROK_DEBUG`, `GROK_RETRY_*`, `TAVILY_API_KEY`, `TAVILY_API_URL`, `TAVILY_ENABLED
|
|
18
|
+
- Optional env: `GROK_MODEL`, `GROK_DEBUG`, `GROK_RETRY_*`, `TAVILY_API_KEY`, `TAVILY_API_URL`, `TAVILY_ENABLED`.
|
|
19
19
|
- For time-sensitive answers, include source URLs and the relevant date.
|
|
20
20
|
- Start with `web_search`; use `web_fetch` for page content; use `web_map` for site structure.
|
|
21
21
|
|
|
22
22
|
## Commands
|
|
23
23
|
|
|
24
24
|
```bash
|
|
25
|
-
|
|
25
|
+
python -m pip install -r "<SKILL_DIR>/requirements.txt"
|
|
26
26
|
|
|
27
|
-
python "<SKILL_DIR>/scripts/
|
|
27
|
+
python "<SKILL_DIR>/scripts/groksearch_cli.py" web_search --query "search terms" [--platform "GitHub"] [--min-results 3] [--max-results 10] [--model "grok-4.20-non-reasoning"] [--extra-sources 3]
|
|
28
28
|
|
|
29
|
-
python "<SKILL_DIR>/scripts/
|
|
29
|
+
python "<SKILL_DIR>/scripts/groksearch_cli.py" web_fetch --url "https://..." [--out file.md] [--fallback-grok]
|
|
30
30
|
|
|
31
|
-
python "<SKILL_DIR>/scripts/
|
|
31
|
+
python "<SKILL_DIR>/scripts/groksearch_cli.py" web_map --url "https://..." [--instructions "focus area"] [--max-depth 2] [--limit 80]
|
|
32
32
|
|
|
33
|
-
python "<SKILL_DIR>/scripts/
|
|
34
|
-
|
|
35
|
-
python "<SKILL_DIR>/scripts/groksearch_entry.py" toggle_builtin_tools --action on|off|status [--root /path/to/project]
|
|
33
|
+
python "<SKILL_DIR>/scripts/groksearch_cli.py" get_config_info [--no-test]
|
|
36
34
|
```
|
|
37
35
|
|
|
38
36
|
## Tool Routing Policy
|
|
@@ -40,8 +38,8 @@ python "<SKILL_DIR>/scripts/groksearch_entry.py" toggle_builtin_tools --action o
|
|
|
40
38
|
|
|
41
39
|
| Scenario | Disabled | Use Instead |
|
|
42
40
|
|----------|----------|-------------|
|
|
43
|
-
| Web Search | `WebSearch` | CLI `web_search` via `
|
|
44
|
-
| Web Fetch | `WebFetch` | CLI `web_fetch` via `
|
|
41
|
+
| Web Search | `WebSearch` | CLI `web_search` via `groksearch_cli.py` |
|
|
42
|
+
| Web Fetch | `WebFetch` | CLI `web_fetch` via `groksearch_cli.py` |
|
|
45
43
|
|
|
46
44
|
### Tool Capability Matrix
|
|
47
45
|
|
|
@@ -51,7 +49,6 @@ python "<SKILL_DIR>/scripts/groksearch_entry.py" toggle_builtin_tools --action o
|
|
|
51
49
|
| `web_fetch` | `url`(required), `out`/`fallback_grok`(optional) | Structured Markdown |
|
|
52
50
|
| `web_map` | `url`(required), `instructions`/`max_depth`/`max_breadth`/`limit`/`timeout`(optional) | JSON string |
|
|
53
51
|
| `get_config_info` | `no_test`(optional) | `{api_url,status,connection_test}` |
|
|
54
|
-
| `toggle_builtin_tools` | `action`(on/off/status), `root`(optional) | `{blocked,deny_list}` |
|
|
55
52
|
|
|
56
53
|
## Search Workflow
|
|
57
54
|
|
|
@@ -84,6 +81,6 @@ python "<SKILL_DIR>/scripts/groksearch_entry.py" toggle_builtin_tools --action o
|
|
|
84
81
|
| Prohibited | Correct |
|
|
85
82
|
|------------|---------|
|
|
86
83
|
| No source citation | Include `Source [1](URL)` |
|
|
87
|
-
| Assume current repo has `skills/grok-search` | Check global skill directories under `$HOME` first, then project-level `.claude/.codex/.agents`, then call `<SKILL_DIR>/scripts/
|
|
88
|
-
|
|
|
84
|
+
| Assume current repo has `skills/grok-search` | Check global skill directories under `$HOME` first, then project-level `.claude/.codex/.agents`, then call `<SKILL_DIR>/scripts/groksearch_cli.py` |
|
|
85
|
+
| Expect automatic environment setup | Choose an environment and install `requirements.txt` explicitly |
|
|
89
86
|
| Use built-in WebSearch/WebFetch | Use GrokSearch CLI |
|