dev3000 0.0.174 → 0.0.175
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/README.md +0 -4
- package/dist/cdp-monitor.d.ts +3 -0
- package/dist/cdp-monitor.d.ts.map +1 -1
- package/dist/cdp-monitor.js +225 -38
- package/dist/cdp-monitor.js.map +1 -1
- package/dist/cli.js +172 -217
- package/dist/cli.js.map +1 -1
- package/dist/commands/crawl.d.ts.map +1 -1
- package/dist/commands/crawl.js +4 -43
- package/dist/commands/crawl.js.map +1 -1
- package/dist/commands/errors.d.ts.map +1 -1
- package/dist/commands/errors.js +4 -53
- package/dist/commands/errors.js.map +1 -1
- package/dist/commands/fix.d.ts.map +1 -1
- package/dist/commands/fix.js +5 -74
- package/dist/commands/fix.js.map +1 -1
- package/dist/commands/logs.d.ts.map +1 -1
- package/dist/commands/logs.js +4 -53
- package/dist/commands/logs.js.map +1 -1
- package/dist/commands/skill-runner.d.ts +14 -0
- package/dist/commands/skill-runner.d.ts.map +1 -0
- package/dist/commands/skill-runner.js +494 -0
- package/dist/commands/skill-runner.js.map +1 -0
- package/dist/dev-environment.d.ts +4 -3
- package/dist/dev-environment.d.ts.map +1 -1
- package/dist/dev-environment.js +111 -95
- package/dist/dev-environment.js.map +1 -1
- package/dist/skills/d3k/internal-skill.md +145 -0
- package/dist/skills/index.test.ts +28 -1
- package/dist/skills/index.ts +58 -7
- package/dist/utils/agent-browser.d.ts.map +1 -1
- package/dist/utils/agent-browser.js +6 -3
- package/dist/utils/agent-browser.js.map +1 -1
- package/dist/utils/agent-detection.d.ts +1 -0
- package/dist/utils/agent-detection.d.ts.map +1 -1
- package/dist/utils/agent-detection.js +11 -0
- package/dist/utils/agent-detection.js.map +1 -1
- package/dist/utils/agent-selection.js +3 -3
- package/dist/utils/agent-selection.js.map +1 -1
- package/dist/utils/browser-command-argv.d.ts +1 -1
- package/dist/utils/browser-command-argv.d.ts.map +1 -1
- package/dist/utils/browser-command-argv.js +1 -1
- package/dist/utils/browser-command-argv.js.map +1 -1
- package/dist/utils/project-name.d.ts +2 -0
- package/dist/utils/project-name.d.ts.map +1 -1
- package/dist/utils/project-name.js +6 -0
- package/dist/utils/project-name.js.map +1 -1
- package/dist/utils/session.d.ts +14 -0
- package/dist/utils/session.d.ts.map +1 -0
- package/dist/utils/session.js +65 -0
- package/dist/utils/session.js.map +1 -0
- package/dist/utils/version-check.js +2 -2
- package/dist/utils/version-check.js.map +1 -1
- package/package.json +8 -18
- package/dist/commands/cloud-check-pr.d.ts +0 -9
- package/dist/commands/cloud-check-pr.d.ts.map +0 -1
- package/dist/commands/cloud-check-pr.js +0 -243
- package/dist/commands/cloud-check-pr.js.map +0 -1
- package/dist/commands/cloud-fix.d.ts +0 -13
- package/dist/commands/cloud-fix.d.ts.map +0 -1
- package/dist/commands/cloud-fix.js +0 -79
- package/dist/commands/cloud-fix.js.map +0 -1
- package/dist/commands/find-component.d.ts +0 -8
- package/dist/commands/find-component.d.ts.map +0 -1
- package/dist/commands/find-component.js +0 -182
- package/dist/commands/find-component.js.map +0 -1
- package/dist/skills/d3k/SKILL.md +0 -126
- package/dist/skills/index.d.ts +0 -46
- package/dist/skills/index.d.ts.map +0 -1
- package/dist/skills/index.js +0 -174
- package/dist/skills/index.js.map +0 -1
package/dist/cli.js
CHANGED
|
@@ -63,108 +63,59 @@ function findAgentBrowser() {
|
|
|
63
63
|
}
|
|
64
64
|
return "agent-browser";
|
|
65
65
|
}
|
|
66
|
-
function
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
}
|
|
72
|
-
}
|
|
73
|
-
const cwd = process.cwd();
|
|
74
|
-
const home = homedir();
|
|
75
|
-
const searchPaths = [
|
|
76
|
-
join(home, ".bun", "install", "global", "node_modules", "dev3000", "node_modules", "@vercel", "next-browser", "dist", "cli.js"),
|
|
77
|
-
join(home, ".bun", "install", "global", "node_modules", "@vercel", "next-browser", "dist", "cli.js"),
|
|
78
|
-
join(cwd, "node_modules", "@vercel", "next-browser", "dist", "cli.js"),
|
|
79
|
-
join(cwd, "..", "node_modules", "@vercel", "next-browser", "dist", "cli.js")
|
|
80
|
-
];
|
|
81
|
-
const globalNodeModules = [
|
|
82
|
-
join("/usr", "local", "lib", "node_modules"),
|
|
83
|
-
join("/opt", "homebrew", "lib", "node_modules")
|
|
84
|
-
];
|
|
85
|
-
for (const root of globalNodeModules) {
|
|
86
|
-
searchPaths.push(join(root, "dev3000", "node_modules", "@vercel", "next-browser", "dist", "cli.js"));
|
|
87
|
-
searchPaths.push(join(root, "@vercel", "next-browser", "dist", "cli.js"));
|
|
88
|
-
}
|
|
89
|
-
for (const searchPath of searchPaths) {
|
|
90
|
-
if (existsSync(searchPath)) {
|
|
91
|
-
return searchPath;
|
|
92
|
-
}
|
|
66
|
+
function getSessionCdpPort() {
|
|
67
|
+
const session = findCurrentSession();
|
|
68
|
+
const cdpUrl = session?.cdpUrl;
|
|
69
|
+
if (!cdpUrl) {
|
|
70
|
+
return null;
|
|
93
71
|
}
|
|
94
|
-
return null;
|
|
95
|
-
}
|
|
96
|
-
function getProjectBrowserToolPreference() {
|
|
97
72
|
try {
|
|
98
|
-
const
|
|
99
|
-
if (
|
|
100
|
-
return
|
|
73
|
+
const parsed = new URL(cdpUrl);
|
|
74
|
+
if (/^\d+$/.test(parsed.port)) {
|
|
75
|
+
return parsed.port;
|
|
101
76
|
}
|
|
102
|
-
const sessionInfo = JSON.parse(readFileSync(sessionFile, "utf8"));
|
|
103
|
-
return sessionInfo.preferredBrowserTool === "next-browser" ? "next-browser" : "agent-browser";
|
|
104
77
|
}
|
|
105
78
|
catch {
|
|
106
|
-
|
|
79
|
+
const match = cdpUrl.match(/:(\d+)/);
|
|
80
|
+
if (match) {
|
|
81
|
+
return match[1];
|
|
82
|
+
}
|
|
107
83
|
}
|
|
84
|
+
return null;
|
|
108
85
|
}
|
|
109
|
-
function runLocalBrowserTool(
|
|
86
|
+
function runLocalBrowserTool(args) {
|
|
110
87
|
const env = { ...process.env };
|
|
111
88
|
ensureCommandPath(env);
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
if (
|
|
134
|
-
|
|
135
|
-
}
|
|
136
|
-
if (result.stderr?.length > 0) {
|
|
137
|
-
process.stderr.write(result.stderr);
|
|
138
|
-
}
|
|
139
|
-
if (result.error) {
|
|
140
|
-
console.error(`\nError spawning agent-browser: ${result.error.message}`);
|
|
141
|
-
console.error(`Binary path: ${binaryPath}`);
|
|
142
|
-
process.exit(1);
|
|
89
|
+
const subcommandIndex = args.findIndex((arg) => !arg.startsWith("-") && !arg.startsWith("@") && arg !== "9222");
|
|
90
|
+
const subcommand = subcommandIndex >= 0 ? args[subcommandIndex] : null;
|
|
91
|
+
if (subcommand === "errors") {
|
|
92
|
+
console.log("\x1b[33m💡 Tip: Using `d3k errors` instead (shows browser + server errors)\x1b[0m\n");
|
|
93
|
+
const d3kBin = process.argv[1];
|
|
94
|
+
const result = spawnSync(d3kBin, ["errors"], { stdio: "inherit", shell: false });
|
|
95
|
+
process.exit(result.status ?? 0);
|
|
96
|
+
}
|
|
97
|
+
if (subcommand === "console") {
|
|
98
|
+
console.log("\x1b[33m💡 Tip: Using `d3k logs` instead (shows browser + server logs)\x1b[0m\n");
|
|
99
|
+
const d3kBin = process.argv[1];
|
|
100
|
+
const result = spawnSync(d3kBin, ["logs", "--type", "browser"], { stdio: "inherit", shell: false });
|
|
101
|
+
process.exit(result.status ?? 0);
|
|
102
|
+
}
|
|
103
|
+
const binaryPath = findAgentBrowser();
|
|
104
|
+
if (subcommand !== "connect" &&
|
|
105
|
+
subcommand !== "close" &&
|
|
106
|
+
!args.includes("--cdp") &&
|
|
107
|
+
!args.includes("--profile") &&
|
|
108
|
+
!args.includes("--profile-dir")) {
|
|
109
|
+
const cdpPort = getSessionCdpPort();
|
|
110
|
+
if (cdpPort) {
|
|
111
|
+
spawnSync(binaryPath, ["connect", cdpPort], { stdio: "pipe", env, shell: false });
|
|
143
112
|
}
|
|
144
|
-
process.exit(result.status ?? 1);
|
|
145
113
|
}
|
|
146
|
-
const
|
|
147
|
-
|
|
114
|
+
const result = spawnSync(binaryPath, args, {
|
|
115
|
+
stdio: "pipe",
|
|
148
116
|
env,
|
|
149
117
|
shell: false
|
|
150
118
|
});
|
|
151
|
-
const nodeVersion = nodeVersionCheck.stdout?.trim();
|
|
152
|
-
const nodeMajor = nodeVersion ? Number.parseInt(nodeVersion.split(".")[0] || "0", 10) : 0;
|
|
153
|
-
if (nodeVersionCheck.status !== 0 || Number.isNaN(nodeMajor) || nodeMajor < 20) {
|
|
154
|
-
console.error("\nnext-browser requires a system Node.js runtime >= 20.");
|
|
155
|
-
console.error("Install Node 20+ or keep using agent-browser for local d3k sessions.");
|
|
156
|
-
process.exit(1);
|
|
157
|
-
}
|
|
158
|
-
const cliPath = findNextBrowserCli();
|
|
159
|
-
const nextBrowserHome = join(getProjectDir(), "next-browser-home");
|
|
160
|
-
mkdirSync(nextBrowserHome, { recursive: true });
|
|
161
|
-
env.HOME = nextBrowserHome;
|
|
162
|
-
env.USERPROFILE = nextBrowserHome;
|
|
163
|
-
const result = spawnSync(cliPath ? "node" : "next-browser", cliPath ? [cliPath, ...args] : args, {
|
|
164
|
-
stdio: "pipe",
|
|
165
|
-
shell: false,
|
|
166
|
-
env
|
|
167
|
-
});
|
|
168
119
|
if (result.stdout?.length > 0) {
|
|
169
120
|
process.stdout.write(result.stdout);
|
|
170
121
|
}
|
|
@@ -172,10 +123,8 @@ function runLocalBrowserTool(browserTool, args) {
|
|
|
172
123
|
process.stderr.write(result.stderr);
|
|
173
124
|
}
|
|
174
125
|
if (result.error) {
|
|
175
|
-
console.error(`\nError spawning
|
|
176
|
-
|
|
177
|
-
console.error(`CLI path: ${cliPath}`);
|
|
178
|
-
}
|
|
126
|
+
console.error(`\nError spawning agent-browser: ${result.error.message}`);
|
|
127
|
+
console.error(`Binary path: ${binaryPath}`);
|
|
179
128
|
process.exit(1);
|
|
180
129
|
}
|
|
181
130
|
process.exit(result.status ?? 1);
|
|
@@ -183,13 +132,7 @@ function runLocalBrowserTool(browserTool, args) {
|
|
|
183
132
|
import { getBrowserCommandInvocation } from "./utils/browser-command-argv.js";
|
|
184
133
|
const browserCommandInvocation = getBrowserCommandInvocation(process.argv.slice(2));
|
|
185
134
|
if (browserCommandInvocation && (process.argv[1]?.includes("d3k") || process.argv[1]?.includes("dev3000"))) {
|
|
186
|
-
|
|
187
|
-
const browserTool = browserCommand === "browser"
|
|
188
|
-
? getProjectBrowserToolPreference()
|
|
189
|
-
: browserCommand === "next-browser"
|
|
190
|
-
? "next-browser"
|
|
191
|
-
: "agent-browser";
|
|
192
|
-
runLocalBrowserTool(browserTool, args);
|
|
135
|
+
runLocalBrowserTool(browserCommandInvocation.args);
|
|
193
136
|
}
|
|
194
137
|
import chalk from "chalk";
|
|
195
138
|
import { execSync, spawnSync } from "child_process";
|
|
@@ -197,17 +140,17 @@ import { Command } from "commander";
|
|
|
197
140
|
import { accessSync, appendFileSync, chmodSync, constants, copyFileSync, existsSync, mkdirSync, readFileSync } from "fs";
|
|
198
141
|
import { homedir } from "os";
|
|
199
142
|
import { detect } from "package-manager-detector";
|
|
200
|
-
import { dirname, join } from "path";
|
|
143
|
+
import { dirname, join, resolve } from "path";
|
|
201
144
|
import { fileURLToPath } from "url";
|
|
202
|
-
import {
|
|
203
|
-
import { cloudFix } from "./commands/cloud-fix.js";
|
|
145
|
+
import { runRemoteSkillCommand, shouldUseRemoteSkillRunner } from "./commands/skill-runner.js";
|
|
204
146
|
import { createPersistentLogFile, findAvailablePort, startDevEnvironment } from "./dev-environment.js";
|
|
205
|
-
import {
|
|
147
|
+
import { getBundledD3kSkillPath, getSkill, getSkillsInfo, listAvailableSkills } from "./skills/index.js";
|
|
206
148
|
import { detectAIAgent } from "./utils/agent-detection.js";
|
|
207
149
|
import { getAvailableAgents, getSkillsAgentId } from "./utils/agent-selection.js";
|
|
208
150
|
import { ensureD3kHomeDir } from "./utils/d3k-dir.js";
|
|
209
151
|
import { readProjectAgentName } from "./utils/project-metadata.js";
|
|
210
152
|
import { getProjectDir, getProjectDisplayName } from "./utils/project-name.js";
|
|
153
|
+
import { findCurrentSession } from "./utils/session.js";
|
|
211
154
|
import { checkForSkillUpdates, getApplicablePackages, getSkillsPathForLocation, installSkillPackage, isPackageInstalled, updateSkills } from "./utils/skill-installer.js";
|
|
212
155
|
import { DEFAULT_TMUX_CONFIG, generateSessionName, generateTmuxCommands, getTmuxInstallInstructions, isTmuxInstalled } from "./utils/tmux-helpers.js";
|
|
213
156
|
import { loadUserConfig, saveUserConfig } from "./utils/user-config.js";
|
|
@@ -269,49 +212,81 @@ process.on("unhandledRejection", (reason) => {
|
|
|
269
212
|
process.exit(1);
|
|
270
213
|
}
|
|
271
214
|
});
|
|
215
|
+
function shellQuote(value) {
|
|
216
|
+
return `'${value.replace(/'/g, `'\\''`)}'`;
|
|
217
|
+
}
|
|
218
|
+
function validatePortOption(port) {
|
|
219
|
+
if (!/^\d+$/.test(port)) {
|
|
220
|
+
throw new Error("--port must be a numeric port number.");
|
|
221
|
+
}
|
|
222
|
+
const parsed = Number.parseInt(port, 10);
|
|
223
|
+
if (!Number.isInteger(parsed) || parsed < 1 || parsed > 65535) {
|
|
224
|
+
throw new Error("--port must be between 1 and 65535.");
|
|
225
|
+
}
|
|
226
|
+
return String(parsed);
|
|
227
|
+
}
|
|
228
|
+
function validatePositiveIntegerOption(name, value) {
|
|
229
|
+
if (!/^\d+$/.test(value)) {
|
|
230
|
+
throw new Error(`${name} must be a positive integer.`);
|
|
231
|
+
}
|
|
232
|
+
const parsed = Number.parseInt(value, 10);
|
|
233
|
+
if (!Number.isInteger(parsed) || parsed <= 0) {
|
|
234
|
+
throw new Error(`${name} must be a positive integer.`);
|
|
235
|
+
}
|
|
236
|
+
return String(parsed);
|
|
237
|
+
}
|
|
238
|
+
function validateScriptOption(script) {
|
|
239
|
+
if (!/^[A-Za-z0-9._:/-]+$/.test(script)) {
|
|
240
|
+
throw new Error("--script may only contain letters, numbers, dots, slashes, colons, underscores, and hyphens.");
|
|
241
|
+
}
|
|
242
|
+
return script;
|
|
243
|
+
}
|
|
244
|
+
function validateDateTimeOption(value) {
|
|
245
|
+
if (value !== "local" && value !== "utc") {
|
|
246
|
+
throw new Error("--date-time must be either 'local' or 'utc'.");
|
|
247
|
+
}
|
|
248
|
+
return value;
|
|
249
|
+
}
|
|
272
250
|
/**
|
|
273
251
|
* Build the d3k command string with forwarded options.
|
|
274
252
|
*/
|
|
275
253
|
function buildD3kCommandWithOptions(options) {
|
|
276
254
|
const d3kBase = process.argv[1].endsWith("d3k") ? "d3k" : "dev3000";
|
|
277
|
-
const args = [d3kBase];
|
|
255
|
+
const args = [shellQuote(d3kBase)];
|
|
278
256
|
// Forward options that were explicitly set
|
|
279
257
|
if (options.port)
|
|
280
|
-
args.push(
|
|
258
|
+
args.push("--port", shellQuote(options.port));
|
|
281
259
|
if (options.script)
|
|
282
|
-
args.push(
|
|
260
|
+
args.push("--script", shellQuote(options.script));
|
|
283
261
|
if (options.command)
|
|
284
|
-
args.push(
|
|
262
|
+
args.push("--command", shellQuote(options.command));
|
|
285
263
|
if (options.startupTimeout)
|
|
286
|
-
args.push(
|
|
264
|
+
args.push("--startup-timeout", shellQuote(options.startupTimeout));
|
|
287
265
|
if (options.browserNavigationTimeout) {
|
|
288
|
-
args.push(
|
|
266
|
+
args.push("--browser-navigation-timeout", shellQuote(options.browserNavigationTimeout));
|
|
289
267
|
}
|
|
290
268
|
if (options.profileDir)
|
|
291
|
-
args.push(
|
|
269
|
+
args.push("--profile-dir", shellQuote(options.profileDir));
|
|
292
270
|
if (options.browserTool)
|
|
293
|
-
args.push(
|
|
271
|
+
args.push("--browser-tool", shellQuote(options.browserTool));
|
|
294
272
|
if (options.browser)
|
|
295
|
-
args.push(
|
|
273
|
+
args.push("--browser", shellQuote(options.browser));
|
|
296
274
|
if (options.serversOnly)
|
|
297
275
|
args.push("--servers-only");
|
|
298
276
|
if (options.headless)
|
|
299
277
|
args.push("--headless");
|
|
300
278
|
if (options.dateTime)
|
|
301
|
-
args.push(
|
|
279
|
+
args.push("--date-time", shellQuote(options.dateTime));
|
|
302
280
|
if (options.pluginReactScan)
|
|
303
281
|
args.push("--plugin-react-scan");
|
|
304
282
|
if (options.agentName)
|
|
305
|
-
args.push(
|
|
283
|
+
args.push("--agent-name", shellQuote(options.agentName));
|
|
306
284
|
return args.join(" ");
|
|
307
285
|
}
|
|
308
286
|
function ensureClaudeD3kSkill() {
|
|
309
287
|
try {
|
|
310
|
-
const
|
|
311
|
-
if (!
|
|
312
|
-
return;
|
|
313
|
-
const bundledSkillPath = join(bundledSkillsDir, "d3k", "SKILL.md");
|
|
314
|
-
if (!existsSync(bundledSkillPath))
|
|
288
|
+
const bundledSkillPath = getBundledD3kSkillPath();
|
|
289
|
+
if (!bundledSkillPath)
|
|
315
290
|
return;
|
|
316
291
|
const skillsRoot = join(process.cwd(), ".claude", "skills");
|
|
317
292
|
const skillDir = join(skillsRoot, "d3k");
|
|
@@ -778,7 +753,10 @@ program
|
|
|
778
753
|
.option("--startup-timeout <seconds>", "Seconds to wait for your app server to become reachable", "30")
|
|
779
754
|
.option("--browser-navigation-timeout <seconds>", "Seconds to wait for browser-initiated page navigation commands", "60")
|
|
780
755
|
.option("--profile-dir <dir>", "Chrome profile directory")
|
|
781
|
-
.option("--
|
|
756
|
+
.option("--data-dir <dir>", "Override the per-project data directory (default: ~/.d3k/<project>/). Holds session.json, logs, screenshots, and the Chrome profile.")
|
|
757
|
+
.option("--log-file <path>", "Override the consolidated log file path (default: <data-dir>/logs/<timestamp>.log)")
|
|
758
|
+
.option("--screenshots-dir <dir>", "Override the screenshots directory (default: <data-dir>/screenshots)")
|
|
759
|
+
.option("--browser-tool <tool>", "Preferred local browser CLI: 'agent-browser'", "agent-browser")
|
|
782
760
|
.option("--browser <path>", "Full path to browser executable (e.g. for Arc: '/Applications/Arc.app/Contents/MacOS/Arc')")
|
|
783
761
|
.option("--servers-only", "Run servers only, skip browser launch")
|
|
784
762
|
.option("--debug", "Enable debug logging to console (automatically disables TUI)")
|
|
@@ -794,10 +772,34 @@ program
|
|
|
794
772
|
.option("--agent-name <name>", "Selected agent name (internal)")
|
|
795
773
|
.option("--no-agent", "Skip agent selection prompt and run d3k standalone")
|
|
796
774
|
.action(async (options) => {
|
|
775
|
+
if (options.dataDir) {
|
|
776
|
+
process.env.D3K_DATA_DIR = resolve(options.dataDir);
|
|
777
|
+
}
|
|
797
778
|
const projectName = getProjectDisplayName();
|
|
798
779
|
setTerminalTitle(projectName);
|
|
780
|
+
try {
|
|
781
|
+
if (options.port) {
|
|
782
|
+
options.port = validatePortOption(options.port);
|
|
783
|
+
}
|
|
784
|
+
if (options.script) {
|
|
785
|
+
options.script = validateScriptOption(options.script);
|
|
786
|
+
}
|
|
787
|
+
options.startupTimeout = validatePositiveIntegerOption("--startup-timeout", options.startupTimeout);
|
|
788
|
+
options.browserNavigationTimeout = validatePositiveIntegerOption("--browser-navigation-timeout", options.browserNavigationTimeout);
|
|
789
|
+
if (options.browserTool && options.browserTool !== "agent-browser") {
|
|
790
|
+
throw new Error("--browser-tool must be 'agent-browser'.");
|
|
791
|
+
}
|
|
792
|
+
options.browserTool = "agent-browser";
|
|
793
|
+
options.dateTime = validateDateTimeOption(options.dateTime || "local");
|
|
794
|
+
}
|
|
795
|
+
catch (error) {
|
|
796
|
+
const message = error instanceof Error ? error.message : String(error);
|
|
797
|
+
console.error(chalk.red(`\n❌ ${message}\n`));
|
|
798
|
+
process.exit(1);
|
|
799
|
+
}
|
|
799
800
|
// Load user config early so it can be used for --with-agent and agent selection flows
|
|
800
801
|
const userConfig = loadUserConfig();
|
|
802
|
+
const agentDetection = detectAIAgent();
|
|
801
803
|
// Apply browser default from user config if not explicitly provided via CLI
|
|
802
804
|
const browserOption = options.browser || userConfig.browser;
|
|
803
805
|
// Handle --with-agent by spawning tmux with split panes
|
|
@@ -824,7 +826,23 @@ program
|
|
|
824
826
|
const insideTmux = !!process.env.TMUX;
|
|
825
827
|
let selectedAgent = null;
|
|
826
828
|
let didPromptAgentSelection = false;
|
|
827
|
-
let skillsAgentId = options.agentName
|
|
829
|
+
let skillsAgentId = options.agentName
|
|
830
|
+
? getSkillsAgentId(options.agentName)
|
|
831
|
+
: agentDetection.agentId || null;
|
|
832
|
+
if (agentDetection.isAgent) {
|
|
833
|
+
if (options.tui !== false) {
|
|
834
|
+
if (options.debug) {
|
|
835
|
+
console.log(`[DEBUG] AI agent detected: ${agentDetection.agentName} (${agentDetection.reason}), auto-disabling TUI`);
|
|
836
|
+
}
|
|
837
|
+
options.tui = false;
|
|
838
|
+
}
|
|
839
|
+
if (agentDetection.agentId && options.skills !== false && !options.autoSkills) {
|
|
840
|
+
if (options.debug) {
|
|
841
|
+
console.log(`[DEBUG] AI agent detected: ${agentDetection.agentName} (${agentDetection.reason}), auto-enabling project skill installs`);
|
|
842
|
+
}
|
|
843
|
+
options.autoSkills = true;
|
|
844
|
+
}
|
|
845
|
+
}
|
|
828
846
|
if (process.stdin.isTTY && options.agent !== false && options.tui !== false && !options.debug && !insideTmux) {
|
|
829
847
|
// Clear the terminal so d3k UI starts at the top of the screen
|
|
830
848
|
process.stdout.write("\x1B[2J\x1B[0f");
|
|
@@ -968,6 +986,7 @@ program
|
|
|
968
986
|
script: options.script,
|
|
969
987
|
command: options.command,
|
|
970
988
|
startupTimeout: options.startupTimeout,
|
|
989
|
+
browserNavigationTimeout: options.browserNavigationTimeout,
|
|
971
990
|
profileDir: options.profileDir,
|
|
972
991
|
browserTool: options.browserTool,
|
|
973
992
|
browser: browserOption,
|
|
@@ -981,7 +1000,7 @@ program
|
|
|
981
1000
|
}
|
|
982
1001
|
}
|
|
983
1002
|
if (options.autoSkills && options.skills !== false && !skillsAgentId) {
|
|
984
|
-
skillsAgentId = "codex";
|
|
1003
|
+
skillsAgentId = agentDetection.agentId || "codex";
|
|
985
1004
|
}
|
|
986
1005
|
// Detect project type and configuration
|
|
987
1006
|
const projectConfig = await detectProjectType(options.debug);
|
|
@@ -999,22 +1018,13 @@ program
|
|
|
999
1018
|
console.error(chalk.yellow(` d3k --command "node server.js" -p 3000\n`));
|
|
1000
1019
|
process.exit(1);
|
|
1001
1020
|
}
|
|
1002
|
-
// Detect if running under an AI agent and auto-disable TUI
|
|
1003
|
-
const agentDetection = detectAIAgent();
|
|
1004
|
-
if (agentDetection.isAgent && options.tui !== false) {
|
|
1005
|
-
if (options.debug) {
|
|
1006
|
-
console.log(`[DEBUG] AI agent detected: ${agentDetection.agentName} (${agentDetection.reason}), auto-disabling TUI`);
|
|
1007
|
-
}
|
|
1008
|
-
// Override TUI setting to false when agent is detected
|
|
1009
|
-
options.tui = false;
|
|
1010
|
-
}
|
|
1011
1021
|
// Use defaults from project detection if not explicitly provided
|
|
1012
1022
|
const port = options.port || projectConfig.defaultPort;
|
|
1013
1023
|
const script = options.script || projectConfig.defaultScript;
|
|
1014
1024
|
const userSetPort = options.port !== undefined;
|
|
1015
1025
|
const startupTimeoutSeconds = Number.parseInt(options.startupTimeout, 10);
|
|
1016
1026
|
const browserNavigationTimeoutSeconds = Number.parseInt(options.browserNavigationTimeout, 10);
|
|
1017
|
-
const browserTool =
|
|
1027
|
+
const browserTool = "agent-browser";
|
|
1018
1028
|
if (Number.isNaN(startupTimeoutSeconds) || startupTimeoutSeconds <= 0) {
|
|
1019
1029
|
console.error(chalk.red("\n❌ --startup-timeout must be a positive integer (seconds).\n"));
|
|
1020
1030
|
process.exit(1);
|
|
@@ -1094,7 +1104,7 @@ program
|
|
|
1094
1104
|
const commandName = executablePath.endsWith("/d3k") || executablePath.includes("/d3k") ? "d3k" : "dev3000";
|
|
1095
1105
|
try {
|
|
1096
1106
|
// Create persistent log file
|
|
1097
|
-
const logFile = createPersistentLogFile();
|
|
1107
|
+
const logFile = createPersistentLogFile(options.logFile);
|
|
1098
1108
|
// Use a per-project Chrome profile by default so concurrent d3k sessions
|
|
1099
1109
|
// don't fight over the same browser state. Honor explicit overrides.
|
|
1100
1110
|
const profileDir = options.profileDir || join(getProjectDir(), "chrome-profile");
|
|
@@ -1126,7 +1136,8 @@ program
|
|
|
1126
1136
|
agentName: options.agentName || undefined,
|
|
1127
1137
|
skillsAgentId: skillsAgentId || undefined,
|
|
1128
1138
|
autoSkills: options.skills !== false ? options.autoSkills || false : false,
|
|
1129
|
-
installSkills: options.skills !== false
|
|
1139
|
+
installSkills: options.skills !== false,
|
|
1140
|
+
screenshotsDir: options.screenshotsDir
|
|
1130
1141
|
});
|
|
1131
1142
|
}
|
|
1132
1143
|
catch (error) {
|
|
@@ -1134,41 +1145,6 @@ program
|
|
|
1134
1145
|
process.exit(1);
|
|
1135
1146
|
}
|
|
1136
1147
|
});
|
|
1137
|
-
// Cloud commands
|
|
1138
|
-
const cloud = program.command("cloud").description("Cloud-based tools using Vercel Sandbox");
|
|
1139
|
-
// Cloud fix command
|
|
1140
|
-
cloud
|
|
1141
|
-
.command("fix")
|
|
1142
|
-
.description("Start a cloud fix workflow for the current project")
|
|
1143
|
-
.option("--repo <url>", "Repository URL (e.g. https://github.com/user/repo)")
|
|
1144
|
-
.option("--branch <name>", "Git branch to test")
|
|
1145
|
-
.option("--project-dir <dir>", "Project directory within repo (e.g. 'www')")
|
|
1146
|
-
.option("--debug", "Enable debug logging")
|
|
1147
|
-
.action(async (options) => {
|
|
1148
|
-
try {
|
|
1149
|
-
await cloudFix(options);
|
|
1150
|
-
}
|
|
1151
|
-
catch (error) {
|
|
1152
|
-
console.error(chalk.red("❌ Cloud fix failed:"), error);
|
|
1153
|
-
process.exit(1);
|
|
1154
|
-
}
|
|
1155
|
-
});
|
|
1156
|
-
// Cloud check-pr command
|
|
1157
|
-
cloud
|
|
1158
|
-
.command("check-pr [pr-number]")
|
|
1159
|
-
.description("Verify a PR's changes work as expected using Vercel preview deployment")
|
|
1160
|
-
.option("--repo <url>", "Repository URL (optional, auto-detected from git)")
|
|
1161
|
-
.option("--url <preview-url>", "Preview deployment URL (optional, auto-detected from Vercel)")
|
|
1162
|
-
.option("--debug", "Enable debug logging")
|
|
1163
|
-
.action(async (prNumber, options) => {
|
|
1164
|
-
try {
|
|
1165
|
-
await cloudCheckPR({ ...options, prNumber });
|
|
1166
|
-
}
|
|
1167
|
-
catch (error) {
|
|
1168
|
-
console.error(chalk.red("❌ Cloud check-pr failed:"), error);
|
|
1169
|
-
process.exit(1);
|
|
1170
|
-
}
|
|
1171
|
-
});
|
|
1172
1148
|
// Upgrade command
|
|
1173
1149
|
program
|
|
1174
1150
|
.command("upgrade")
|
|
@@ -1214,21 +1190,37 @@ program
|
|
|
1214
1190
|
.command("agent-browser [args...]")
|
|
1215
1191
|
.description("Run the bundled agent-browser CLI (e.g., d3k agent-browser screenshot /tmp/foo.png)")
|
|
1216
1192
|
.allowUnknownOption(true);
|
|
1217
|
-
program
|
|
1218
|
-
.command("next-browser [args...]")
|
|
1219
|
-
.description("Run the bundled next-browser CLI (e.g., d3k next-browser open http://localhost:3000)")
|
|
1220
|
-
.allowUnknownOption(true);
|
|
1221
|
-
program
|
|
1222
|
-
.command("browser [args...]")
|
|
1223
|
-
.description("Run the preferred local browser CLI for this session")
|
|
1224
|
-
.allowUnknownOption(true);
|
|
1225
1193
|
// Skill command - get skill content for use in prompts/workflows
|
|
1226
1194
|
program
|
|
1227
1195
|
.command("skill [name]")
|
|
1228
1196
|
.description("Get skill content or list available skills")
|
|
1229
1197
|
.option("-l, --list", "List all available skills")
|
|
1230
1198
|
.option("-v, --verbose", "Show detailed skill information")
|
|
1231
|
-
.
|
|
1199
|
+
.option("--team <team>", "Override the inferred Vercel team slug or ID for a hosted skill run")
|
|
1200
|
+
.option("--project <project>", "Override the inferred Vercel project name or ID for a hosted skill run")
|
|
1201
|
+
.option("--branch <branch>", "Git branch or ref to scan")
|
|
1202
|
+
.option("--project-dir <dir>", "Project root directory inside the repository")
|
|
1203
|
+
.option("--base-url <url>", "dev3000 base URL")
|
|
1204
|
+
.option("--wait", "Wait for the run to finish")
|
|
1205
|
+
.option("--json", "Print machine-readable JSON")
|
|
1206
|
+
.option("--no-install", "Do not install or repair the team skill runner project before starting")
|
|
1207
|
+
.action(async (name, options) => {
|
|
1208
|
+
if (shouldUseRemoteSkillRunner(name, options)) {
|
|
1209
|
+
try {
|
|
1210
|
+
await runRemoteSkillCommand(name, options);
|
|
1211
|
+
}
|
|
1212
|
+
catch (error) {
|
|
1213
|
+
const message = error instanceof Error ? error.message : String(error);
|
|
1214
|
+
if (options.json) {
|
|
1215
|
+
console.log(JSON.stringify({ success: false, error: message }, null, 2));
|
|
1216
|
+
}
|
|
1217
|
+
else {
|
|
1218
|
+
console.error(chalk.red(`Error: ${message}`));
|
|
1219
|
+
}
|
|
1220
|
+
process.exit(1);
|
|
1221
|
+
}
|
|
1222
|
+
return;
|
|
1223
|
+
}
|
|
1232
1224
|
// List skills if --list flag or no name provided
|
|
1233
1225
|
if (options.list || !name) {
|
|
1234
1226
|
if (options.verbose) {
|
|
@@ -1321,14 +1313,6 @@ program
|
|
|
1321
1313
|
const { crawlApp } = await import("./commands/crawl.js");
|
|
1322
1314
|
await crawlApp(options);
|
|
1323
1315
|
});
|
|
1324
|
-
// Find-component command - map DOM to React source
|
|
1325
|
-
program
|
|
1326
|
-
.command("find-component <selector>")
|
|
1327
|
-
.description("Find React component source for a DOM selector")
|
|
1328
|
-
.action(async (selector) => {
|
|
1329
|
-
const { findComponent } = await import("./commands/find-component.js");
|
|
1330
|
-
await findComponent(selector);
|
|
1331
|
-
});
|
|
1332
1316
|
program
|
|
1333
1317
|
.command("resume")
|
|
1334
1318
|
.description("Resume the last supported AI agent session for this project")
|
|
@@ -1340,37 +1324,8 @@ program
|
|
|
1340
1324
|
program
|
|
1341
1325
|
.command("cdp-port")
|
|
1342
1326
|
.description("Output the CDP port for the current d3k session (for use in scripts)")
|
|
1343
|
-
.action(
|
|
1344
|
-
|
|
1345
|
-
const projectDir = getProjectDir();
|
|
1346
|
-
const projectName = projectDir.split("/").pop() || "unknown";
|
|
1347
|
-
// Try to find session.json in ~/.d3k/{project-name}/
|
|
1348
|
-
const entries = existsSync(sessionDir)
|
|
1349
|
-
? await import("fs").then((fs) => fs.readdirSync(sessionDir, { withFileTypes: true }))
|
|
1350
|
-
: [];
|
|
1351
|
-
for (const entry of entries) {
|
|
1352
|
-
if (entry.isDirectory() && entry.name.startsWith(projectName.substring(0, 20))) {
|
|
1353
|
-
const sessionFile = join(sessionDir, entry.name, "session.json");
|
|
1354
|
-
if (existsSync(sessionFile)) {
|
|
1355
|
-
try {
|
|
1356
|
-
const content = JSON.parse(readFileSync(sessionFile, "utf-8"));
|
|
1357
|
-
if (content.cdpUrl) {
|
|
1358
|
-
// Extract port from URL like "ws://localhost:9223/devtools/browser/..."
|
|
1359
|
-
const match = content.cdpUrl.match(/:(\d+)/);
|
|
1360
|
-
if (match) {
|
|
1361
|
-
console.log(match[1]);
|
|
1362
|
-
process.exit(0);
|
|
1363
|
-
}
|
|
1364
|
-
}
|
|
1365
|
-
}
|
|
1366
|
-
catch {
|
|
1367
|
-
// Continue searching
|
|
1368
|
-
}
|
|
1369
|
-
}
|
|
1370
|
-
}
|
|
1371
|
-
}
|
|
1372
|
-
// Default to 9222 if no session found
|
|
1373
|
-
console.log("9222");
|
|
1327
|
+
.action(() => {
|
|
1328
|
+
console.log(getSessionCdpPort() || "9222");
|
|
1374
1329
|
});
|
|
1375
1330
|
program.parse();
|
|
1376
1331
|
//# sourceMappingURL=cli.js.map
|