@phnx-labs/agents-cli 1.20.72 → 1.20.74
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/CHANGELOG.md +395 -0
- package/README.md +40 -4
- package/dist/bin/agents +0 -0
- package/dist/commands/activity.d.ts +12 -0
- package/dist/commands/activity.js +68 -0
- package/dist/commands/apply.d.ts +13 -0
- package/dist/commands/apply.js +28 -3
- package/dist/commands/browser.js +1 -1
- package/dist/commands/cloud.js +21 -11
- package/dist/commands/doctor.js +21 -5
- package/dist/commands/events.d.ts +11 -10
- package/dist/commands/events.js +30 -21
- package/dist/commands/exec.d.ts +34 -0
- package/dist/commands/exec.js +337 -39
- package/dist/commands/export.d.ts +11 -0
- package/dist/commands/export.js +215 -0
- package/dist/commands/feed.d.ts +13 -0
- package/dist/commands/feed.js +130 -29
- package/dist/commands/hq.d.ts +2 -0
- package/dist/commands/hq.js +58 -0
- package/dist/commands/import.js +51 -3
- package/dist/commands/lease.d.ts +19 -0
- package/dist/commands/lease.js +138 -11
- package/dist/commands/login.d.ts +2 -0
- package/dist/commands/login.js +123 -0
- package/dist/commands/logs.js +1 -1
- package/dist/commands/mine.d.ts +27 -0
- package/dist/commands/mine.js +207 -0
- package/dist/commands/monitors.js +79 -49
- package/dist/commands/plugins.js +1 -0
- package/dist/commands/profiles.js +158 -0
- package/dist/commands/repo.js +2 -60
- package/dist/commands/resources.d.ts +5 -0
- package/dist/commands/resources.js +95 -0
- package/dist/commands/routines.d.ts +2 -0
- package/dist/commands/routines.js +139 -37
- package/dist/commands/secrets.js +234 -47
- package/dist/commands/send.d.ts +15 -0
- package/dist/commands/send.js +62 -0
- package/dist/commands/sessions-tail.d.ts +1 -0
- package/dist/commands/sessions-tail.js +20 -9
- package/dist/commands/sessions.js +18 -3
- package/dist/commands/setup-mine.d.ts +18 -0
- package/dist/commands/setup-mine.js +106 -0
- package/dist/commands/setup-share.js +2 -2
- package/dist/commands/setup.js +9 -2
- package/dist/commands/share.d.ts +8 -1
- package/dist/commands/share.js +122 -37
- package/dist/commands/ssh.d.ts +9 -0
- package/dist/commands/ssh.js +196 -26
- package/dist/commands/sync.js +1 -1
- package/dist/commands/teams.js +11 -2
- package/dist/commands/versions.js +36 -5
- package/dist/commands/view.js +75 -27
- package/dist/index.js +80 -10
- package/dist/lib/activity.d.ts +124 -0
- package/dist/lib/activity.js +542 -0
- package/dist/lib/agents.d.ts +35 -0
- package/dist/lib/agents.js +79 -6
- package/dist/lib/artifact-actions.d.ts +1 -1
- package/dist/lib/artifact-actions.js +1 -1
- package/dist/lib/ask-classifier.d.ts +2 -1
- package/dist/lib/ask-classifier.js +3 -3
- package/dist/lib/auth-health.d.ts +32 -4
- package/dist/lib/auth-health.js +40 -1
- package/dist/lib/auto-pull.js +8 -1
- package/dist/lib/brand.d.ts +40 -0
- package/dist/lib/brand.js +122 -0
- package/dist/lib/browser/drivers/ssh.js +4 -7
- package/dist/lib/browser/service.js +6 -8
- package/dist/lib/channels/providers/index.d.ts +2 -0
- package/dist/lib/channels/providers/index.js +20 -0
- package/dist/lib/channels/providers/mailbox.d.ts +2 -0
- package/dist/lib/channels/providers/mailbox.js +26 -0
- package/dist/lib/channels/providers/openclaw-telegram.d.ts +2 -0
- package/dist/lib/channels/providers/openclaw-telegram.js +34 -0
- package/dist/lib/channels/providers/rush.d.ts +6 -0
- package/dist/lib/channels/providers/rush.js +55 -0
- package/dist/lib/channels/registry.d.ts +42 -0
- package/dist/lib/channels/registry.js +20 -0
- package/dist/lib/channels/resolve.d.ts +11 -0
- package/dist/lib/channels/resolve.js +12 -0
- package/dist/lib/cli-resources.d.ts +18 -0
- package/dist/lib/cli-resources.js +53 -4
- package/dist/lib/cloud/codex.js +6 -3
- package/dist/lib/cloud/factory.d.ts +1 -0
- package/dist/lib/cloud/factory.js +10 -4
- package/dist/lib/cloud/rush.d.ts +3 -1
- package/dist/lib/cloud/rush.js +6 -1
- package/dist/lib/cloud/types.d.ts +2 -0
- package/dist/lib/codex-home.d.ts +35 -0
- package/dist/lib/codex-home.js +136 -0
- package/dist/lib/config-transfer.d.ts +16 -0
- package/dist/lib/config-transfer.js +56 -0
- package/dist/lib/crabbox/cli.d.ts +44 -0
- package/dist/lib/crabbox/cli.js +120 -20
- package/dist/lib/crabbox/lease.d.ts +52 -1
- package/dist/lib/crabbox/lease.js +117 -16
- package/dist/lib/crabbox/progress.d.ts +31 -0
- package/dist/lib/crabbox/progress.js +76 -0
- package/dist/lib/crabbox/runtimes.d.ts +4 -0
- package/dist/lib/crabbox/runtimes.js +33 -8
- package/dist/lib/crabbox/setup-copy.d.ts +87 -0
- package/dist/lib/crabbox/setup-copy.js +127 -0
- package/dist/lib/daemon.d.ts +5 -5
- package/dist/lib/daemon.js +9 -9
- package/dist/lib/drive-sync.js +6 -3
- package/dist/lib/event-stream.d.ts +36 -0
- package/dist/lib/event-stream.js +68 -0
- package/dist/lib/events.d.ts +1 -1
- package/dist/lib/exec.d.ts +11 -0
- package/dist/lib/exec.js +23 -2
- package/dist/lib/export.d.ts +72 -0
- package/dist/lib/export.js +269 -0
- package/dist/lib/feed-policy.d.ts +1 -1
- package/dist/lib/feed-policy.js +14 -9
- package/dist/lib/feed-ranking.d.ts +32 -0
- package/dist/lib/feed-ranking.js +224 -0
- package/dist/lib/feed.d.ts +35 -2
- package/dist/lib/feed.js +66 -3
- package/dist/lib/fleet/auth-sync.d.ts +53 -0
- package/dist/lib/fleet/auth-sync.js +92 -0
- package/dist/lib/fleet/remote-login.d.ts +187 -0
- package/dist/lib/fleet/remote-login.js +556 -0
- package/dist/lib/format.d.ts +30 -3
- package/dist/lib/format.js +34 -5
- package/dist/lib/fs-atomic.d.ts +7 -2
- package/dist/lib/fs-atomic.js +8 -12
- package/dist/lib/git.d.ts +16 -0
- package/dist/lib/git.js +79 -2
- package/dist/lib/heal.js +11 -3
- package/dist/lib/hosts/progress.d.ts +28 -10
- package/dist/lib/hosts/progress.js +79 -22
- package/dist/lib/hosts/remote-cmd.js +4 -0
- package/dist/lib/hq/floor.d.ts +87 -0
- package/dist/lib/hq/floor.js +226 -0
- package/dist/lib/import.d.ts +23 -0
- package/dist/lib/import.js +74 -2
- package/dist/lib/isolation-boundary-report.d.ts +10 -0
- package/dist/lib/isolation-boundary-report.js +35 -0
- package/dist/lib/menubar/install-menubar.js +14 -20
- package/dist/lib/notify.d.ts +1 -0
- package/dist/lib/notify.js +3 -3
- package/dist/lib/open-url.d.ts +2 -0
- package/dist/lib/open-url.js +19 -0
- package/dist/lib/openclaw-keychain.d.ts +56 -0
- package/dist/lib/openclaw-keychain.js +236 -0
- package/dist/lib/overdue.js +10 -0
- package/dist/lib/permissions.d.ts +44 -1
- package/dist/lib/permissions.js +284 -7
- package/dist/lib/project-launch.d.ts +6 -12
- package/dist/lib/project-launch.js +13 -228
- package/dist/lib/project-resources.d.ts +7 -0
- package/dist/lib/project-resources.js +306 -0
- package/dist/lib/pty-client.d.ts +27 -0
- package/dist/lib/pty-client.js +136 -10
- package/dist/lib/refresh.js +14 -10
- package/dist/lib/resource-profiles.d.ts +26 -0
- package/dist/lib/resource-profiles.js +157 -0
- package/dist/lib/resources/permissions.js +7 -1
- package/dist/lib/resources/types.d.ts +1 -1
- package/dist/lib/resources.d.ts +1 -1
- package/dist/lib/resources.js +32 -3
- package/dist/lib/routines.d.ts +11 -0
- package/dist/lib/routines.js +56 -15
- package/dist/lib/runner.d.ts +1 -0
- package/dist/lib/runner.js +66 -5
- package/dist/lib/secrets/bundles.d.ts +16 -3
- package/dist/lib/secrets/bundles.js +206 -37
- package/dist/lib/secrets/icloud-import.d.ts +2 -2
- package/dist/lib/secrets/icloud-import.js +9 -6
- package/dist/lib/secrets/mcp.js +1 -1
- package/dist/lib/secrets/vault-age-helper.d.ts +1 -0
- package/dist/lib/secrets/vault-age-helper.js +34 -0
- package/dist/lib/secrets/vault.d.ts +49 -0
- package/dist/lib/secrets/vault.js +397 -0
- package/dist/lib/self-heal/checks/path.js +3 -1
- package/dist/lib/self-heal/checks/shadowing.js +10 -2
- package/dist/lib/self-heal/checks/shims.js +19 -11
- package/dist/lib/session/cloud.d.ts +2 -2
- package/dist/lib/session/cloud.js +2 -2
- package/dist/lib/session/db.d.ts +4 -0
- package/dist/lib/session/db.js +44 -7
- package/dist/lib/session/discover.d.ts +2 -0
- package/dist/lib/session/discover.js +114 -3
- package/dist/lib/session/stream-render.d.ts +3 -0
- package/dist/lib/session/stream-render.js +130 -0
- package/dist/lib/session/types.d.ts +6 -0
- package/dist/lib/share/analytics.d.ts +13 -0
- package/dist/lib/share/analytics.js +45 -0
- package/dist/lib/share/config.d.ts +19 -5
- package/dist/lib/share/config.js +44 -8
- package/dist/lib/share/provision.d.ts +58 -6
- package/dist/lib/share/provision.js +97 -22
- package/dist/lib/share/publish.d.ts +36 -13
- package/dist/lib/share/publish.js +55 -8
- package/dist/lib/share/worker-template.js +83 -17
- package/dist/lib/shims.d.ts +35 -0
- package/dist/lib/shims.js +159 -13
- package/dist/lib/ssh-exec.d.ts +14 -0
- package/dist/lib/ssh-exec.js +57 -0
- package/dist/lib/staleness/detectors/hooks.js +25 -1
- package/dist/lib/staleness/detectors/permissions.js +66 -0
- package/dist/lib/staleness/detectors/workflows.js +20 -0
- package/dist/lib/staleness/writers/hooks.js +58 -4
- package/dist/lib/staleness/writers/permissions.js +2 -2
- package/dist/lib/staleness/writers/skills.js +1 -1
- package/dist/lib/staleness/writers/sources.d.ts +10 -1
- package/dist/lib/staleness/writers/sources.js +68 -1
- package/dist/lib/star-nudge.d.ts +45 -0
- package/dist/lib/star-nudge.js +91 -0
- package/dist/lib/startup/command-registry.d.ts +7 -1
- package/dist/lib/startup/command-registry.js +19 -3
- package/dist/lib/state.d.ts +2 -0
- package/dist/lib/state.js +17 -4
- package/dist/lib/subagents-registry.d.ts +2 -0
- package/dist/lib/subagents-registry.js +3 -0
- package/dist/lib/teams/parsers.js +214 -6
- package/dist/lib/teams/supervisor.d.ts +7 -0
- package/dist/lib/teams/supervisor.js +2 -1
- package/dist/lib/template.d.ts +1 -1
- package/dist/lib/template.js +1 -1
- package/dist/lib/triggers/webhook.js +36 -3
- package/dist/lib/types.d.ts +84 -0
- package/dist/lib/uninstall.js +1 -45
- package/dist/lib/version.d.ts +40 -0
- package/dist/lib/version.js +94 -16
- package/dist/lib/versions.d.ts +24 -0
- package/dist/lib/versions.js +269 -78
- package/dist/lib/workflows.d.ts +2 -0
- package/dist/lib/workflows.js +88 -0
- package/package.json +2 -1
- package/dist/commands/daemon.d.ts +0 -10
- package/dist/commands/daemon.js +0 -121
|
@@ -14,7 +14,7 @@ import * as readline from 'readline';
|
|
|
14
14
|
import { execFile } from 'child_process';
|
|
15
15
|
import { promisify } from 'util';
|
|
16
16
|
import Database from '../sqlite.js';
|
|
17
|
-
import { getAgentsDir, getHistoryDir } from '../state.js';
|
|
17
|
+
import { getAgentsDir, getHistoryDir, getRunsDir } from '../state.js';
|
|
18
18
|
const execFileAsync = promisify(execFile);
|
|
19
19
|
import { AGENTS, agentConfigDirName, getCliVersion } from '../agents.js';
|
|
20
20
|
import { walkForFiles } from '../fs-walk.js';
|
|
@@ -65,6 +65,7 @@ export async function discoverSessions(options) {
|
|
|
65
65
|
// reads to behavioral EDR (CrowdStrike Falcon) as a ransomware-style bulk
|
|
66
66
|
// file-enumeration sweep. Same dirs, same results — just not all at once.
|
|
67
67
|
await scanAgentsBounded(agents, agent => dispatchAgentScan(agent, onProgress));
|
|
68
|
+
await scanAgentsBounded(agents, agent => scanRoutineArchivesIncremental(agent, onProgress));
|
|
68
69
|
// Seed labels from `agents run --name` handles onto the freshly-scanned
|
|
69
70
|
// rows by id. Runs AFTER the per-agent scans (which applied agent-generated
|
|
70
71
|
// titles via syncLabels), so a real title always wins and the seed only
|
|
@@ -163,6 +164,7 @@ function buildQueryOptions(options, agents, opts) {
|
|
|
163
164
|
limit: opts.includeLimit ? (options?.limit ?? 50) : undefined,
|
|
164
165
|
excludeTeamOrigin: options?.excludeTeamOrigin,
|
|
165
166
|
onlyTeamOrigin: options?.onlyTeamOrigin,
|
|
167
|
+
origin: options?.origin,
|
|
166
168
|
sortBy: options?.sortBy,
|
|
167
169
|
};
|
|
168
170
|
}
|
|
@@ -180,10 +182,14 @@ function normalizeCwd(cwd) {
|
|
|
180
182
|
*/
|
|
181
183
|
export function resolveSessionById(sessions, idQuery) {
|
|
182
184
|
const query = idQuery.toLowerCase();
|
|
183
|
-
const exact = sessions.filter(s => s.id.toLowerCase() === query ||
|
|
185
|
+
const exact = sessions.filter(s => s.id.toLowerCase() === query ||
|
|
186
|
+
s.shortId.toLowerCase() === query ||
|
|
187
|
+
s.routineRunId?.toLowerCase() === query);
|
|
184
188
|
if (exact.length > 0)
|
|
185
189
|
return exact;
|
|
186
|
-
return sessions.filter(s => s.id.toLowerCase().startsWith(query) ||
|
|
190
|
+
return sessions.filter(s => s.id.toLowerCase().startsWith(query) ||
|
|
191
|
+
s.shortId.toLowerCase().startsWith(query) ||
|
|
192
|
+
s.routineRunId?.toLowerCase().startsWith(query));
|
|
187
193
|
}
|
|
188
194
|
// ---------------------------------------------------------------------------
|
|
189
195
|
// Content-index search (FTS5-backed)
|
|
@@ -319,6 +325,9 @@ const SESSION_ROOT_SPECS = [
|
|
|
319
325
|
{ agent: 'droid', subdir: 'sessions' },
|
|
320
326
|
{ agent: 'kimi', subdir: 'sessions' },
|
|
321
327
|
];
|
|
328
|
+
function sessionRootSubdir(agent) {
|
|
329
|
+
return SESSION_ROOT_SPECS.find((spec) => spec.agent === agent)?.subdir ?? null;
|
|
330
|
+
}
|
|
322
331
|
/**
|
|
323
332
|
* The directories `agents sessions` scans for each on-disk session agent,
|
|
324
333
|
* resolved to what exists on this machine. Emitted by `agents sessions --roots
|
|
@@ -329,11 +338,113 @@ export function getSessionRoots() {
|
|
|
329
338
|
const out = [];
|
|
330
339
|
for (const { agent, subdir } of SESSION_ROOT_SPECS) {
|
|
331
340
|
const dirs = getAgentSessionDirs(agent, subdir);
|
|
341
|
+
dirs.push(...getRoutineArchiveSessionDirs(agent, subdir));
|
|
332
342
|
if (dirs.length > 0)
|
|
333
343
|
out.push({ agent, dirs });
|
|
334
344
|
}
|
|
335
345
|
return out;
|
|
336
346
|
}
|
|
347
|
+
function getRoutineArchiveSessionDirs(agent, subdir) {
|
|
348
|
+
const runsDir = getRunsDir();
|
|
349
|
+
if (!fs.existsSync(runsDir))
|
|
350
|
+
return [];
|
|
351
|
+
const dirs = [];
|
|
352
|
+
let jobDirs;
|
|
353
|
+
try {
|
|
354
|
+
jobDirs = fs.readdirSync(runsDir, { withFileTypes: true });
|
|
355
|
+
}
|
|
356
|
+
catch {
|
|
357
|
+
return dirs;
|
|
358
|
+
}
|
|
359
|
+
for (const jobDir of jobDirs) {
|
|
360
|
+
if (!jobDir.isDirectory())
|
|
361
|
+
continue;
|
|
362
|
+
const jobRunsDir = path.join(runsDir, jobDir.name);
|
|
363
|
+
let runDirs;
|
|
364
|
+
try {
|
|
365
|
+
runDirs = fs.readdirSync(jobRunsDir, { withFileTypes: true });
|
|
366
|
+
}
|
|
367
|
+
catch {
|
|
368
|
+
continue;
|
|
369
|
+
}
|
|
370
|
+
for (const runDir of runDirs) {
|
|
371
|
+
if (!runDir.isDirectory())
|
|
372
|
+
continue;
|
|
373
|
+
const dir = path.join(jobRunsDir, runDir.name, 'sessions', agent, subdir);
|
|
374
|
+
if (fs.existsSync(dir))
|
|
375
|
+
dirs.push(dir);
|
|
376
|
+
}
|
|
377
|
+
}
|
|
378
|
+
return dirs;
|
|
379
|
+
}
|
|
380
|
+
function routineArchiveInfo(filePath) {
|
|
381
|
+
const rel = path.relative(getRunsDir(), filePath);
|
|
382
|
+
if (rel.startsWith('..') || path.isAbsolute(rel))
|
|
383
|
+
return null;
|
|
384
|
+
const parts = rel.split(path.sep);
|
|
385
|
+
if (parts.length < 6 || parts[2] !== 'sessions')
|
|
386
|
+
return null;
|
|
387
|
+
return { jobName: parts[0], runId: parts[1] };
|
|
388
|
+
}
|
|
389
|
+
function decorateRoutineSession(meta, info) {
|
|
390
|
+
return {
|
|
391
|
+
...meta,
|
|
392
|
+
origin: 'routine',
|
|
393
|
+
routineName: info.jobName,
|
|
394
|
+
routineRunId: info.runId,
|
|
395
|
+
project: info.jobName,
|
|
396
|
+
label: info.jobName,
|
|
397
|
+
};
|
|
398
|
+
}
|
|
399
|
+
async function readRoutineArchiveMeta(agent, filePath) {
|
|
400
|
+
const info = routineArchiveInfo(filePath);
|
|
401
|
+
if (!info)
|
|
402
|
+
return null;
|
|
403
|
+
if (agent === 'claude') {
|
|
404
|
+
const sessionId = path.basename(filePath).replace(/\.jsonl$/, '');
|
|
405
|
+
const result = await readClaudeMeta(filePath, sessionId);
|
|
406
|
+
return result ? { ...result, meta: decorateRoutineSession(result.meta, info) } : null;
|
|
407
|
+
}
|
|
408
|
+
if (agent === 'codex') {
|
|
409
|
+
const result = await readCodexMeta(filePath);
|
|
410
|
+
return result ? { ...result, meta: decorateRoutineSession(result.meta, info) } : null;
|
|
411
|
+
}
|
|
412
|
+
return null;
|
|
413
|
+
}
|
|
414
|
+
async function scanRoutineArchivesIncremental(agent, onProgress) {
|
|
415
|
+
const subdir = sessionRootSubdir(agent);
|
|
416
|
+
if (!subdir)
|
|
417
|
+
return;
|
|
418
|
+
const ext = agent === 'gemini' ? '.json' : '.jsonl';
|
|
419
|
+
const filePaths = [];
|
|
420
|
+
for (const sessionsDir of getRoutineArchiveSessionDirs(agent, subdir)) {
|
|
421
|
+
for (const fp of walkForFiles(sessionsDir, ext, 100_000))
|
|
422
|
+
filePaths.push(fp);
|
|
423
|
+
}
|
|
424
|
+
const changed = filterChangedFiles(filePaths);
|
|
425
|
+
if (changed.length === 0)
|
|
426
|
+
return;
|
|
427
|
+
onProgress?.({ agent, parsed: 0, total: changed.length });
|
|
428
|
+
const entries = [];
|
|
429
|
+
const touched = [];
|
|
430
|
+
let parsed = 0;
|
|
431
|
+
for (const { filePath, scan } of changed) {
|
|
432
|
+
try {
|
|
433
|
+
const result = await readRoutineArchiveMeta(agent, filePath);
|
|
434
|
+
if (result)
|
|
435
|
+
entries.push({ meta: result.meta, content: result.content, scan });
|
|
436
|
+
else
|
|
437
|
+
touched.push({ filePath, scan });
|
|
438
|
+
}
|
|
439
|
+
catch {
|
|
440
|
+
touched.push({ filePath, scan });
|
|
441
|
+
}
|
|
442
|
+
parsed++;
|
|
443
|
+
onProgress?.({ agent, parsed, total: changed.length });
|
|
444
|
+
}
|
|
445
|
+
upsertSessionsBatch(entries);
|
|
446
|
+
recordScans(touched);
|
|
447
|
+
}
|
|
337
448
|
// ---------------------------------------------------------------------------
|
|
338
449
|
// Claude account info
|
|
339
450
|
// ---------------------------------------------------------------------------
|
|
@@ -0,0 +1,130 @@
|
|
|
1
|
+
import chalk from 'chalk';
|
|
2
|
+
import { truncate } from '../format.js';
|
|
3
|
+
import { parseClaudeContent, parseCodexContent, sanitizeEvents, summarizeToolUse } from './parse.js';
|
|
4
|
+
import { linkPath, relativeToCwd } from './render.js';
|
|
5
|
+
const LINE_MAX = 120;
|
|
6
|
+
function timeOf(event) {
|
|
7
|
+
const d = new Date(event.timestamp);
|
|
8
|
+
if (Number.isNaN(d.getTime()))
|
|
9
|
+
return '00:00:00';
|
|
10
|
+
return d.toTimeString().slice(0, 8);
|
|
11
|
+
}
|
|
12
|
+
function paintTool(tool) {
|
|
13
|
+
const label = tool.padEnd(10);
|
|
14
|
+
if (tool === 'Bash' || tool === 'exec_command')
|
|
15
|
+
return chalk.yellow(label);
|
|
16
|
+
if (tool === 'Edit' || tool === 'Write' || tool === 'Read')
|
|
17
|
+
return chalk.cyan(label);
|
|
18
|
+
if (tool === 'Agent')
|
|
19
|
+
return chalk.magenta(label);
|
|
20
|
+
return chalk.cyan(label);
|
|
21
|
+
}
|
|
22
|
+
function formatPath(absPath, cwd) {
|
|
23
|
+
const label = relativeToCwd(absPath, cwd);
|
|
24
|
+
return absPath.startsWith('/') ? linkPath(absPath, label) : label;
|
|
25
|
+
}
|
|
26
|
+
function splitToolSummary(tool, summary, event, cwd) {
|
|
27
|
+
if (event.path)
|
|
28
|
+
return formatPath(event.path, cwd);
|
|
29
|
+
const prefix = `${tool}: `;
|
|
30
|
+
if (summary.startsWith(prefix))
|
|
31
|
+
return summary.slice(prefix.length);
|
|
32
|
+
const spacedPrefix = `${tool} `;
|
|
33
|
+
if (summary.startsWith(spacedPrefix))
|
|
34
|
+
return summary.slice(spacedPrefix.length);
|
|
35
|
+
return summary === tool ? '' : summary;
|
|
36
|
+
}
|
|
37
|
+
function lineCount(text) {
|
|
38
|
+
if (!text)
|
|
39
|
+
return 0;
|
|
40
|
+
return text.split(/\r?\n/).length;
|
|
41
|
+
}
|
|
42
|
+
function plural(n, word) {
|
|
43
|
+
return `${n} ${word}${n === 1 ? '' : 's'}`;
|
|
44
|
+
}
|
|
45
|
+
function claudeToolResultLines(raw) {
|
|
46
|
+
if (raw?.type !== 'user' || !Array.isArray(raw?.message?.content))
|
|
47
|
+
return undefined;
|
|
48
|
+
const block = raw.message.content.find((b) => b?.type === 'tool_result');
|
|
49
|
+
if (!block)
|
|
50
|
+
return undefined;
|
|
51
|
+
if (typeof block.content === 'string')
|
|
52
|
+
return lineCount(block.content);
|
|
53
|
+
if (Array.isArray(block.content)) {
|
|
54
|
+
const text = block.content
|
|
55
|
+
.filter((c) => c?.type === 'text')
|
|
56
|
+
.map((c) => c.text || '')
|
|
57
|
+
.join('\n');
|
|
58
|
+
return lineCount(text);
|
|
59
|
+
}
|
|
60
|
+
return 0;
|
|
61
|
+
}
|
|
62
|
+
function codexToolResultLines(raw) {
|
|
63
|
+
if (raw?.type !== 'response_item')
|
|
64
|
+
return undefined;
|
|
65
|
+
const ptype = raw?.payload?.type;
|
|
66
|
+
if (ptype !== 'function_call_output' && ptype !== 'custom_tool_call_output')
|
|
67
|
+
return undefined;
|
|
68
|
+
return lineCount(String(raw.payload.output || ''));
|
|
69
|
+
}
|
|
70
|
+
function rawToolResultLines(line, agent) {
|
|
71
|
+
try {
|
|
72
|
+
const raw = JSON.parse(line);
|
|
73
|
+
return agent === 'codex' ? codexToolResultLines(raw) : claudeToolResultLines(raw);
|
|
74
|
+
}
|
|
75
|
+
catch {
|
|
76
|
+
return undefined;
|
|
77
|
+
}
|
|
78
|
+
}
|
|
79
|
+
function renderEvent(event, cwd, lastTool, resultLines) {
|
|
80
|
+
const prefix = chalk.dim(`${timeOf(event)} `);
|
|
81
|
+
switch (event.type) {
|
|
82
|
+
case 'message': {
|
|
83
|
+
const marker = event.role === 'user' ? chalk.blue('» you ') : chalk.green(`· ${event.agent.padEnd(9)}`);
|
|
84
|
+
return prefix + marker + truncate((event.content || '').replace(/\s+/g, ' ').trim(), LINE_MAX);
|
|
85
|
+
}
|
|
86
|
+
case 'tool_use': {
|
|
87
|
+
const tool = event.tool || 'unknown';
|
|
88
|
+
const summary = summarizeToolUse(tool, event.args);
|
|
89
|
+
const detail = splitToolSummary(tool, summary, event, cwd);
|
|
90
|
+
return prefix + chalk.yellow('→ ') + paintTool(tool) + chalk.gray(truncate(detail.replace(/\s+/g, ' ').trim(), LINE_MAX));
|
|
91
|
+
}
|
|
92
|
+
case 'tool_result': {
|
|
93
|
+
const tool = event.tool || lastTool || 'tool';
|
|
94
|
+
const count = resultLines ?? lineCount(event.output || '');
|
|
95
|
+
const status = event.success === false ? chalk.red('✗ ') : chalk.green('✓ ');
|
|
96
|
+
return prefix + status + paintTool(tool) + chalk.dim(`(result elided — ${plural(count, 'line')})`);
|
|
97
|
+
}
|
|
98
|
+
case 'error': {
|
|
99
|
+
const label = event.tool ? `${event.tool}: ` : '';
|
|
100
|
+
return prefix + chalk.red('✗ Error ') + chalk.gray(truncate((label + (event.content || '')).replace(/\s+/g, ' ').trim(), LINE_MAX));
|
|
101
|
+
}
|
|
102
|
+
case 'thinking':
|
|
103
|
+
case 'usage':
|
|
104
|
+
case 'init':
|
|
105
|
+
case 'result':
|
|
106
|
+
return null;
|
|
107
|
+
default:
|
|
108
|
+
return null;
|
|
109
|
+
}
|
|
110
|
+
}
|
|
111
|
+
export function makeStreamRenderer(agent, cwd) {
|
|
112
|
+
const parse = agent === 'codex' ? parseCodexContent : parseClaudeContent;
|
|
113
|
+
let lastTool;
|
|
114
|
+
return (line) => {
|
|
115
|
+
const events = parse(line);
|
|
116
|
+
sanitizeEvents(events);
|
|
117
|
+
if (events.length === 0)
|
|
118
|
+
return null;
|
|
119
|
+
const resultLines = rawToolResultLines(line, agent);
|
|
120
|
+
const rendered = [];
|
|
121
|
+
for (const event of events) {
|
|
122
|
+
const out = renderEvent(event, cwd, lastTool, resultLines);
|
|
123
|
+
if (event.type === 'tool_use' && event.tool)
|
|
124
|
+
lastTool = event.tool;
|
|
125
|
+
if (out)
|
|
126
|
+
rendered.push(out);
|
|
127
|
+
}
|
|
128
|
+
return rendered.length ? rendered.join('\n') : null;
|
|
129
|
+
};
|
|
130
|
+
}
|
|
@@ -76,6 +76,12 @@ export interface SessionMeta {
|
|
|
76
76
|
id: string;
|
|
77
77
|
shortId: string;
|
|
78
78
|
agent: SessionAgentId;
|
|
79
|
+
/** Where the indexed transcript came from. Routine rows are archived from a run directory. */
|
|
80
|
+
origin?: 'cli' | 'routine';
|
|
81
|
+
/** Routine name for transcripts archived from ~/.agents/.history/runs/<name>/<runId>/. */
|
|
82
|
+
routineName?: string;
|
|
83
|
+
/** Routine run id for transcripts archived from ~/.agents/.history/runs/<name>/<runId>/. */
|
|
84
|
+
routineRunId?: string;
|
|
79
85
|
timestamp: string;
|
|
80
86
|
/**
|
|
81
87
|
* Last-activity time (ISO): the last message timestamp when a parser computed
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
/** Cloudflare Web Analytics snippet for a given zone token. */
|
|
2
|
+
export declare function renderBeacon(token: string): string;
|
|
3
|
+
/**
|
|
4
|
+
* Inject the CF Web Analytics beacon into an HTML page. Idempotent: any existing
|
|
5
|
+
* agents-share analytics block is removed first. The snippet is appended before
|
|
6
|
+
* `</body>` when present, otherwise before `</head>`, otherwise prepended to the
|
|
7
|
+
* document so it still loads.
|
|
8
|
+
*/
|
|
9
|
+
export declare function injectAnalyticsBeacon(html: string, token: string): string;
|
|
10
|
+
/** True if the share config has a non-empty analytics token. */
|
|
11
|
+
export declare function analyticsEnabled(cfg: {
|
|
12
|
+
analyticsToken?: string;
|
|
13
|
+
} | undefined | null): boolean;
|
|
@@ -0,0 +1,45 @@
|
|
|
1
|
+
// Cloudflare Web Analytics injection for `agents share`.
|
|
2
|
+
//
|
|
3
|
+
// The beacon is cookieless and privacy-first, which matters because a lot of shared
|
|
4
|
+
// content (games, kid-facing pages) should avoid GA4-style tracking. The token is
|
|
5
|
+
// stored in the synced share config and injected into every published HTML page at
|
|
6
|
+
// publish time, so analytics work with zero user effort once setup is complete.
|
|
7
|
+
const BEACON_OPEN = '<!-- agents-share:analytics -->';
|
|
8
|
+
const BEACON_CLOSE = '<!-- /agents-share:analytics -->';
|
|
9
|
+
/** Cloudflare Web Analytics snippet for a given zone token. */
|
|
10
|
+
export function renderBeacon(token) {
|
|
11
|
+
const payload = JSON.stringify({ token });
|
|
12
|
+
return (`${BEACON_OPEN}\n` +
|
|
13
|
+
'<script defer ' +
|
|
14
|
+
'src="https://static.cloudflareinsights.com/beacon.min.js" ' +
|
|
15
|
+
`data-cf-beacon='${payload}'></script>\n` +
|
|
16
|
+
`${BEACON_CLOSE}\n`);
|
|
17
|
+
}
|
|
18
|
+
/** Strip a previously-injected analytics block so re-publishing doesn't duplicate it. */
|
|
19
|
+
function stripPrevious(html) {
|
|
20
|
+
const re = new RegExp(`${BEACON_OPEN}[\\s\\S]*?${BEACON_CLOSE}\\n?`, 'g');
|
|
21
|
+
return html.replace(re, '');
|
|
22
|
+
}
|
|
23
|
+
/**
|
|
24
|
+
* Inject the CF Web Analytics beacon into an HTML page. Idempotent: any existing
|
|
25
|
+
* agents-share analytics block is removed first. The snippet is appended before
|
|
26
|
+
* `</body>` when present, otherwise before `</head>`, otherwise prepended to the
|
|
27
|
+
* document so it still loads.
|
|
28
|
+
*/
|
|
29
|
+
export function injectAnalyticsBeacon(html, token) {
|
|
30
|
+
if (!token)
|
|
31
|
+
return html;
|
|
32
|
+
const cleaned = stripPrevious(html);
|
|
33
|
+
const block = renderBeacon(token);
|
|
34
|
+
const bodyClose = cleaned.search(/<\/body>/i);
|
|
35
|
+
if (bodyClose !== -1)
|
|
36
|
+
return cleaned.slice(0, bodyClose) + block + cleaned.slice(bodyClose);
|
|
37
|
+
const headClose = cleaned.search(/<\/head>/i);
|
|
38
|
+
if (headClose !== -1)
|
|
39
|
+
return cleaned.slice(0, headClose) + block + cleaned.slice(headClose);
|
|
40
|
+
return block + cleaned;
|
|
41
|
+
}
|
|
42
|
+
/** True if the share config has a non-empty analytics token. */
|
|
43
|
+
export function analyticsEnabled(cfg) {
|
|
44
|
+
return Boolean(cfg?.analyticsToken && cfg.analyticsToken.trim().length > 0);
|
|
45
|
+
}
|
|
@@ -6,12 +6,18 @@ export interface ShareConfig {
|
|
|
6
6
|
bucketName: string;
|
|
7
7
|
/** Custom domain when mapped (e.g. `share.agents-cli.sh`). */
|
|
8
8
|
domain?: string;
|
|
9
|
+
/** Cloudflare Web Analytics token injected into published HTML pages. */
|
|
10
|
+
analyticsToken?: string;
|
|
9
11
|
}
|
|
10
12
|
export declare const SHARE_BUNDLE = "share";
|
|
11
|
-
export declare const SHARE_TOKEN_KEY = "
|
|
12
|
-
export declare const
|
|
13
|
+
export declare const SHARE_TOKEN_KEY = "WRITE_TOKEN";
|
|
14
|
+
export declare const SHARE_TOKEN_ENV_KEY = "SHARE_WRITE_TOKEN";
|
|
15
|
+
export declare const DEFAULT_CF_BUNDLE = "cloudflare";
|
|
13
16
|
export declare const DEFAULT_WORKER_NAME = "agents-share";
|
|
14
17
|
export declare const DEFAULT_BUCKET_NAME = "agents-share";
|
|
18
|
+
export declare const DEFAULT_SHARE_DOMAIN = "share.agents-cli.sh";
|
|
19
|
+
/** The write token may be injected ephemerally into fleet/cloud agents. */
|
|
20
|
+
export declare function readWriteTokenEnv(env?: NodeJS.ProcessEnv): string | null;
|
|
15
21
|
/** Read the persisted endpoint config, or null if `agents share setup`/`join` never ran. */
|
|
16
22
|
export declare function readShareConfig(): ShareConfig | null;
|
|
17
23
|
/** Persist the endpoint config to `agents.yaml` (syncs across the fleet). */
|
|
@@ -21,10 +27,18 @@ export declare function generateWriteToken(): string;
|
|
|
21
27
|
/** Persist the raw write token into the `share` secrets bundle (keychain-backed,
|
|
22
28
|
* fleet-injectable). Mirrors the add-key sequence in `commands/secrets.ts`. */
|
|
23
29
|
export declare function storeWriteToken(token: string): void;
|
|
24
|
-
/** Read the raw write token from the `share` secrets bundle.
|
|
25
|
-
|
|
30
|
+
/** Read the raw write token from the `share` secrets bundle. */
|
|
31
|
+
export declare function readWriteTokenFromBundle(): string;
|
|
32
|
+
/** Read the raw write token from injected env first, then the local bundle.
|
|
33
|
+
* Throws with an actionable message if absent (run setup/join first). */
|
|
26
34
|
export declare function readWriteToken(): string;
|
|
27
|
-
/**
|
|
35
|
+
/** Best-effort runtime env for spawned agents. Never throws: a missing/locked
|
|
36
|
+
* bundle should not block unrelated agent runs, but an already-unlocked bundle
|
|
37
|
+
* or injected token lets ephemeral agents publish with no local setup. */
|
|
38
|
+
export declare function shareRuntimeEnv(opts?: {
|
|
39
|
+
agentOnly?: boolean;
|
|
40
|
+
}): Record<string, string> | undefined;
|
|
41
|
+
/** Cloudflare API credentials for provisioning, read from `cloudflare` (or a
|
|
28
42
|
* user-named bundle). Fuzzy-matches key names so it works across bundle layouts. */
|
|
29
43
|
export declare function readCloudflareCreds(bundle?: string, override?: {
|
|
30
44
|
apiToken?: string;
|
package/dist/lib/share/config.js
CHANGED
|
@@ -6,16 +6,23 @@
|
|
|
6
6
|
// - The raw write token lives in the `share` secrets bundle (keychain-backed,
|
|
7
7
|
// fleet-injectable) — never on disk in plaintext.
|
|
8
8
|
// - The Cloudflare API token (for provisioning) is read from the user's existing
|
|
9
|
-
// `cloudflare
|
|
9
|
+
// `cloudflare` bundle.
|
|
10
10
|
import { randomBytes } from 'node:crypto';
|
|
11
11
|
import { readMeta, updateMeta } from '../state.js';
|
|
12
|
-
import { bundleItemStore, bundlePolicy, isHeadlessSecretsContext, keychainRef, readAndResolveBundleEnv, readBundle, writeBundle, } from '../secrets/bundles.js';
|
|
12
|
+
import { bundleExists, bundleItemStore, bundlePolicy, isHeadlessSecretsContext, keychainRef, readAndResolveBundleEnv, readBundle, writeBundle, } from '../secrets/bundles.js';
|
|
13
13
|
import { secretsKeychainItem } from '../secrets/index.js';
|
|
14
14
|
export const SHARE_BUNDLE = 'share';
|
|
15
|
-
export const SHARE_TOKEN_KEY = '
|
|
16
|
-
export const
|
|
15
|
+
export const SHARE_TOKEN_KEY = 'WRITE_TOKEN';
|
|
16
|
+
export const SHARE_TOKEN_ENV_KEY = 'SHARE_WRITE_TOKEN';
|
|
17
|
+
export const DEFAULT_CF_BUNDLE = 'cloudflare';
|
|
17
18
|
export const DEFAULT_WORKER_NAME = 'agents-share';
|
|
18
19
|
export const DEFAULT_BUCKET_NAME = 'agents-share';
|
|
20
|
+
export const DEFAULT_SHARE_DOMAIN = 'share.agents-cli.sh';
|
|
21
|
+
/** The write token may be injected ephemerally into fleet/cloud agents. */
|
|
22
|
+
export function readWriteTokenEnv(env = process.env) {
|
|
23
|
+
const token = env[SHARE_TOKEN_ENV_KEY]?.trim();
|
|
24
|
+
return token ? token : null;
|
|
25
|
+
}
|
|
19
26
|
/** Read the persisted endpoint config, or null if `agents share setup`/`join` never ran. */
|
|
20
27
|
export function readShareConfig() {
|
|
21
28
|
const s = readMeta().share;
|
|
@@ -27,6 +34,7 @@ export function readShareConfig() {
|
|
|
27
34
|
workerName: s.workerName,
|
|
28
35
|
bucketName: s.bucketName,
|
|
29
36
|
domain: s.domain,
|
|
37
|
+
analyticsToken: s.analyticsToken,
|
|
30
38
|
};
|
|
31
39
|
}
|
|
32
40
|
/** Persist the endpoint config to `agents.yaml` (syncs across the fleet). */
|
|
@@ -56,9 +64,8 @@ export function storeWriteToken(token) {
|
|
|
56
64
|
bundle.vars[SHARE_TOKEN_KEY] = keychainRef(SHARE_TOKEN_KEY);
|
|
57
65
|
writeBundle(bundle);
|
|
58
66
|
}
|
|
59
|
-
/** Read the raw write token from the `share` secrets bundle.
|
|
60
|
-
|
|
61
|
-
export function readWriteToken() {
|
|
67
|
+
/** Read the raw write token from the `share` secrets bundle. */
|
|
68
|
+
export function readWriteTokenFromBundle() {
|
|
62
69
|
const { env } = readAndResolveBundleEnv(SHARE_BUNDLE, {
|
|
63
70
|
caller: 'share',
|
|
64
71
|
agentOnly: isHeadlessSecretsContext(),
|
|
@@ -70,7 +77,36 @@ export function readWriteToken() {
|
|
|
70
77
|
}
|
|
71
78
|
return token;
|
|
72
79
|
}
|
|
73
|
-
/**
|
|
80
|
+
/** Read the raw write token from injected env first, then the local bundle.
|
|
81
|
+
* Throws with an actionable message if absent (run setup/join first). */
|
|
82
|
+
export function readWriteToken() {
|
|
83
|
+
return readWriteTokenEnv() ?? readWriteTokenFromBundle();
|
|
84
|
+
}
|
|
85
|
+
/** Best-effort runtime env for spawned agents. Never throws: a missing/locked
|
|
86
|
+
* bundle should not block unrelated agent runs, but an already-unlocked bundle
|
|
87
|
+
* or injected token lets ephemeral agents publish with no local setup. */
|
|
88
|
+
export function shareRuntimeEnv(opts = {}) {
|
|
89
|
+
if (!readShareConfig())
|
|
90
|
+
return undefined;
|
|
91
|
+
const fromEnv = readWriteTokenEnv();
|
|
92
|
+
if (fromEnv)
|
|
93
|
+
return { [SHARE_TOKEN_ENV_KEY]: fromEnv };
|
|
94
|
+
try {
|
|
95
|
+
if (!bundleExists(SHARE_BUNDLE))
|
|
96
|
+
return undefined;
|
|
97
|
+
const { env } = readAndResolveBundleEnv(SHARE_BUNDLE, {
|
|
98
|
+
caller: 'share',
|
|
99
|
+
keys: [SHARE_TOKEN_KEY],
|
|
100
|
+
agentOnly: opts.agentOnly,
|
|
101
|
+
});
|
|
102
|
+
const token = env[SHARE_TOKEN_KEY];
|
|
103
|
+
return token ? { [SHARE_TOKEN_ENV_KEY]: token } : undefined;
|
|
104
|
+
}
|
|
105
|
+
catch {
|
|
106
|
+
return undefined;
|
|
107
|
+
}
|
|
108
|
+
}
|
|
109
|
+
/** Cloudflare API credentials for provisioning, read from `cloudflare` (or a
|
|
74
110
|
* user-named bundle). Fuzzy-matches key names so it works across bundle layouts. */
|
|
75
111
|
export function readCloudflareCreds(bundle = DEFAULT_CF_BUNDLE, override) {
|
|
76
112
|
// Explicit --token/--account bypass the bundle entirely (robust escape hatch).
|
|
@@ -1,10 +1,62 @@
|
|
|
1
|
+
export declare const SHARE_LIFECYCLE_RULE_ID = "agents-share-expire-objects";
|
|
2
|
+
export declare const SHARE_LIFECYCLE_RETENTION_DAYS = 366;
|
|
3
|
+
interface R2LifecycleRule {
|
|
4
|
+
id: string;
|
|
5
|
+
enabled: boolean;
|
|
6
|
+
conditions: {
|
|
7
|
+
prefix: string;
|
|
8
|
+
};
|
|
9
|
+
deleteObjectsTransition?: {
|
|
10
|
+
condition: {
|
|
11
|
+
type: 'Age';
|
|
12
|
+
maxAge: number;
|
|
13
|
+
} | {
|
|
14
|
+
type: 'Date';
|
|
15
|
+
date: string;
|
|
16
|
+
};
|
|
17
|
+
};
|
|
18
|
+
abortMultipartUploadsTransition?: {
|
|
19
|
+
condition?: {
|
|
20
|
+
type: 'Age';
|
|
21
|
+
maxAge: number;
|
|
22
|
+
};
|
|
23
|
+
};
|
|
24
|
+
storageClassTransitions?: Array<{
|
|
25
|
+
condition: {
|
|
26
|
+
type: 'Age';
|
|
27
|
+
maxAge: number;
|
|
28
|
+
} | {
|
|
29
|
+
type: 'Date';
|
|
30
|
+
date: string;
|
|
31
|
+
};
|
|
32
|
+
storageClass: 'InfrequentAccess';
|
|
33
|
+
}>;
|
|
34
|
+
}
|
|
35
|
+
export interface CloudflareRequest {
|
|
36
|
+
apiToken: string;
|
|
37
|
+
method: string;
|
|
38
|
+
pathname: string;
|
|
39
|
+
body?: unknown;
|
|
40
|
+
form?: FormData;
|
|
41
|
+
}
|
|
42
|
+
export type CloudflareRequester = <T = unknown>(request: CloudflareRequest) => Promise<T>;
|
|
43
|
+
interface ProvisionOptions {
|
|
44
|
+
request?: CloudflareRequester;
|
|
45
|
+
}
|
|
1
46
|
/** Create the R2 bucket (idempotent). */
|
|
2
|
-
export declare function createBucket(apiToken: string, accountId: string, name: string): Promise<void>;
|
|
3
|
-
|
|
4
|
-
export declare function
|
|
47
|
+
export declare function createBucket(apiToken: string, accountId: string, name: string, opts?: ProvisionOptions): Promise<void>;
|
|
48
|
+
export declare function buildShareLifecycleRule(days?: number): R2LifecycleRule;
|
|
49
|
+
export declare function mergeShareLifecycleRule(existing?: R2LifecycleRule[], rule?: R2LifecycleRule): R2LifecycleRule[];
|
|
50
|
+
/** Ensure the share bucket self-cleans old objects. Exact per-link expiry is enforced by the Worker. */
|
|
51
|
+
export declare function configureBucketLifecycle(apiToken: string, accountId: string, bucketName: string, opts?: ProvisionOptions): Promise<void>;
|
|
52
|
+
/** Upload the module Worker with an R2 binding (`BUCKET`). Secrets are set via the Workers Secrets API. */
|
|
53
|
+
export declare function deployWorker(apiToken: string, accountId: string, workerName: string, script: string, bucketName: string, opts?: ProvisionOptions): Promise<void>;
|
|
54
|
+
/** Add/update the WRITE_TOKEN binding using Cloudflare's Workers Secrets API. */
|
|
55
|
+
export declare function setWorkerSecret(apiToken: string, accountId: string, workerName: string, writeToken: string, opts?: ProvisionOptions): Promise<void>;
|
|
5
56
|
/** Enable the free `*.workers.dev` route for the script, and return the account subdomain. */
|
|
6
|
-
export declare function enableWorkersDev(apiToken: string, accountId: string, workerName: string): Promise<string>;
|
|
57
|
+
export declare function enableWorkersDev(apiToken: string, accountId: string, workerName: string, opts?: ProvisionOptions): Promise<string>;
|
|
7
58
|
/** Resolve a zone id for a domain the token can see, or null if not owned/visible. */
|
|
8
|
-
export declare function findZoneId(apiToken: string, domain: string): Promise<string | null>;
|
|
59
|
+
export declare function findZoneId(apiToken: string, domain: string, opts?: ProvisionOptions): Promise<string | null>;
|
|
9
60
|
/** Map a custom hostname (e.g. `share.agents-cli.sh`) to the Worker via Workers Custom Domains. */
|
|
10
|
-
export declare function addCustomDomain(apiToken: string, accountId: string, workerName: string, zoneId: string, hostname: string): Promise<void>;
|
|
61
|
+
export declare function addCustomDomain(apiToken: string, accountId: string, workerName: string, zoneId: string, hostname: string, opts?: ProvisionOptions): Promise<void>;
|
|
62
|
+
export {};
|