@playdrop/playdrop-cli 0.10.5 → 0.10.7
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 +1 -1
- package/config/client-meta.json +1 -1
- package/dist/commands/agents.js +15 -0
- package/dist/commands/upgrade.d.ts +10 -1
- package/dist/commands/upgrade.js +99 -9
- package/dist/commands/worker.d.ts +64 -0
- package/dist/commands/worker.js +873 -10
- package/dist/index.js +41 -1
- package/node_modules/@playdrop/api-client/dist/client.d.ts +3 -2
- package/node_modules/@playdrop/api-client/dist/client.d.ts.map +1 -1
- package/node_modules/@playdrop/api-client/dist/domains/agent-tasks.d.ts +3 -2
- package/node_modules/@playdrop/api-client/dist/domains/agent-tasks.d.ts.map +1 -1
- package/node_modules/@playdrop/api-client/dist/domains/agent-tasks.js +23 -12
- package/node_modules/@playdrop/api-client/dist/index.d.ts +3 -2
- package/node_modules/@playdrop/api-client/dist/index.d.ts.map +1 -1
- package/node_modules/@playdrop/api-client/dist/index.js +10 -5
- package/node_modules/@playdrop/config/client-meta.json +1 -1
- package/node_modules/@playdrop/types/dist/api.d.ts +108 -9
- package/node_modules/@playdrop/types/dist/api.d.ts.map +1 -1
- package/node_modules/@playdrop/types/dist/api.js +54 -3
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -88,7 +88,7 @@ playdrop workspaces init
|
|
|
88
88
|
|
|
89
89
|
`playdrop agents install-plugin claude` adds the PlayDrop marketplace, installs the PlayDrop plugin through the Claude Code CLI, and tells you to reload plugins.
|
|
90
90
|
|
|
91
|
-
`playdrop agents install-plugin codex` configures the PlayDrop plugin marketplace and uses Codex's plugin
|
|
91
|
+
`playdrop agents install-plugin codex` configures the PlayDrop plugin marketplace and uses Codex's `plugin add` command when the local Codex CLI exposes it. If the installed Codex CLI only supports marketplace management, finish activation from Codex with `/plugins`.
|
|
92
92
|
|
|
93
93
|
Cursor does not currently expose documented plugin installation through its CLI. `playdrop agents install-plugin cursor` prints the manual steps instead: open Cursor and use `/add-plugin` or the Cursor Marketplace for PlayDrop.
|
|
94
94
|
|
package/config/client-meta.json
CHANGED
package/dist/commands/agents.js
CHANGED
|
@@ -296,6 +296,21 @@ function runCodexPluginAction(action, runCommand) {
|
|
|
296
296
|
}
|
|
297
297
|
const help = runCommand('codex', ['plugin', '--help']);
|
|
298
298
|
const helpText = commandOutput(help);
|
|
299
|
+
if (commandHelpIncludes(helpText, 'add')) {
|
|
300
|
+
const add = runCommand('codex', ['plugin', 'add', PLAYDROP_PLUGIN_SPEC]);
|
|
301
|
+
if (add.status !== 0) {
|
|
302
|
+
console.error(`Codex PlayDrop plugin ${action === 'install-plugin' ? 'install' : 'update'} failed.`);
|
|
303
|
+
process.exitCode = 1;
|
|
304
|
+
return;
|
|
305
|
+
}
|
|
306
|
+
if (commandHelpIncludes(helpText, 'list') && !readInstalledPlayDropPlugin('codex', runCommand)) {
|
|
307
|
+
console.error(`Codex PlayDrop plugin ${action === 'install-plugin' ? 'install' : 'update'} could not be verified from codex plugin list --json.`);
|
|
308
|
+
process.exitCode = 1;
|
|
309
|
+
return;
|
|
310
|
+
}
|
|
311
|
+
console.log(`${action === 'install-plugin' ? 'Installed' : 'Updated'} the PlayDrop plugin for Codex.`);
|
|
312
|
+
return;
|
|
313
|
+
}
|
|
299
314
|
if (action === 'install-plugin' && commandHelpIncludes(helpText, 'install')) {
|
|
300
315
|
const install = runCommand('codex', ['plugin', 'install', PLAYDROP_PLUGIN_SPEC]);
|
|
301
316
|
if (install.status !== 0) {
|
|
@@ -1 +1,10 @@
|
|
|
1
|
-
|
|
1
|
+
type UpgradeOptions = {
|
|
2
|
+
dryRun?: boolean;
|
|
3
|
+
targetVersion?: string;
|
|
4
|
+
worker?: boolean;
|
|
5
|
+
env?: string;
|
|
6
|
+
workerKey?: string;
|
|
7
|
+
updatePlugins?: boolean;
|
|
8
|
+
};
|
|
9
|
+
export declare function upgrade(options?: UpgradeOptions): Promise<void>;
|
|
10
|
+
export {};
|
package/dist/commands/upgrade.js
CHANGED
|
@@ -2,16 +2,33 @@
|
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
3
|
exports.upgrade = upgrade;
|
|
4
4
|
const node_child_process_1 = require("node:child_process");
|
|
5
|
-
const
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
5
|
+
const commandContext_1 = require("../commandContext");
|
|
6
|
+
const config_1 = require("../config");
|
|
7
|
+
const worker_1 = require("./worker");
|
|
8
|
+
const WORKER_UPDATE_POLL_DEFAULT_MS = 3000;
|
|
9
|
+
const WORKER_UPDATE_TIMEOUT_DEFAULT_MS = 15 * 60000;
|
|
10
|
+
function readPositiveIntegerEnv(name, fallback) {
|
|
11
|
+
const raw = process.env[name]?.trim() || '';
|
|
12
|
+
const value = Number(raw);
|
|
13
|
+
return Number.isInteger(value) && value > 0 ? value : fallback;
|
|
14
|
+
}
|
|
15
|
+
function sleep(ms) {
|
|
16
|
+
return new Promise((resolve) => {
|
|
17
|
+
setTimeout(resolve, ms);
|
|
18
|
+
});
|
|
19
|
+
}
|
|
20
|
+
function validateTargetVersion(value) {
|
|
21
|
+
const version = value?.trim() || process.env.PLAYDROP_CLI_TARGET_VERSION?.trim() || '';
|
|
22
|
+
if (!/^\d+\.\d+\.\d+(?:[-+][0-9A-Za-z.-]+)?$/.test(version)) {
|
|
23
|
+
throw new Error('playdrop_update_target_version_required: pass --target-version <version> or set PLAYDROP_CLI_TARGET_VERSION. Managed workers should use playdrop update --worker.');
|
|
11
24
|
}
|
|
25
|
+
return version;
|
|
26
|
+
}
|
|
27
|
+
function runCommand(command, args) {
|
|
28
|
+
const commandString = `${command} ${args.join(' ')}`;
|
|
12
29
|
console.log('Running:', commandString);
|
|
13
|
-
|
|
14
|
-
const child = (0, node_child_process_1.spawn)(
|
|
30
|
+
return new Promise((resolve, reject) => {
|
|
31
|
+
const child = (0, node_child_process_1.spawn)(command, args, {
|
|
15
32
|
stdio: 'inherit',
|
|
16
33
|
shell: process.platform === 'win32'
|
|
17
34
|
});
|
|
@@ -20,9 +37,82 @@ async function upgrade(dryRun = false) {
|
|
|
20
37
|
resolve();
|
|
21
38
|
}
|
|
22
39
|
else {
|
|
23
|
-
reject(new Error(
|
|
40
|
+
reject(new Error(`${command} exited with code ${code}`));
|
|
24
41
|
}
|
|
25
42
|
});
|
|
26
43
|
child.on('error', (error) => reject(error));
|
|
27
44
|
});
|
|
28
45
|
}
|
|
46
|
+
function formatWorkerUpdateState(worker) {
|
|
47
|
+
return [
|
|
48
|
+
`lifecycle=${worker.lifecycleState ?? 'unknown'}`,
|
|
49
|
+
`update=${worker.updateState ?? 'unknown'}`,
|
|
50
|
+
`ready=${worker.ready === true ? 'true' : worker.ready === false ? 'false' : 'unknown'}`,
|
|
51
|
+
`cli=${worker.cliVersion ?? 'unknown'}`,
|
|
52
|
+
`plugin=${worker.pluginVersion ?? 'unknown'}`,
|
|
53
|
+
].join(' ');
|
|
54
|
+
}
|
|
55
|
+
async function observeManagedWorkerUpdate(input) {
|
|
56
|
+
const pollMs = readPositiveIntegerEnv('PLAYDROP_WORKER_UPDATE_POLL_MS', WORKER_UPDATE_POLL_DEFAULT_MS);
|
|
57
|
+
const timeoutMs = readPositiveIntegerEnv('PLAYDROP_WORKER_UPDATE_TIMEOUT_MS', WORKER_UPDATE_TIMEOUT_DEFAULT_MS);
|
|
58
|
+
const deadline = Date.now() + timeoutMs;
|
|
59
|
+
let lastState = '';
|
|
60
|
+
while (Date.now() <= deadline) {
|
|
61
|
+
const workers = await input.client.listMyAgentWorkers();
|
|
62
|
+
const worker = workers.workers.find((candidate) => candidate.workerKey === input.workerKey);
|
|
63
|
+
if (!worker) {
|
|
64
|
+
throw new Error(`playdrop_update_worker_missing: worker ${input.workerKey} is no longer registered. Run "playdrop worker status --json" on the worker host.`);
|
|
65
|
+
}
|
|
66
|
+
const state = formatWorkerUpdateState(worker);
|
|
67
|
+
if (state !== lastState) {
|
|
68
|
+
console.log(`Worker update progress: ${state}`);
|
|
69
|
+
lastState = state;
|
|
70
|
+
}
|
|
71
|
+
if (worker.updateState === 'UPDATE_BLOCKED' || worker.lifecycleState === 'DEGRADED' || worker.ready === false) {
|
|
72
|
+
throw new Error(`playdrop_update_worker_failed: ${state}. Next action: run "playdrop worker status --json" on the worker host and inspect the wrapper failure marker under ~/.playdrop/worker.`);
|
|
73
|
+
}
|
|
74
|
+
if (worker.activeUpdateIntentId !== input.intentId
|
|
75
|
+
&& worker.lifecycleState === 'READY'
|
|
76
|
+
&& worker.updateState === 'CURRENT'
|
|
77
|
+
&& worker.ready === true) {
|
|
78
|
+
console.log('Managed worker update completed.');
|
|
79
|
+
return;
|
|
80
|
+
}
|
|
81
|
+
await sleep(pollMs);
|
|
82
|
+
}
|
|
83
|
+
throw new Error(`playdrop_update_worker_timeout: worker ${input.workerKey} did not complete update intent ${input.intentId} within ${timeoutMs}ms. Next action: check Slack worker alerts, launchctl status, and the wrapper failure marker on the worker host.`);
|
|
84
|
+
}
|
|
85
|
+
async function upgrade(options = {}) {
|
|
86
|
+
if (options.worker) {
|
|
87
|
+
const ctx = await (0, commandContext_1.resolveAuthenticatedEnvironmentContext)('update', 'Requesting a managed worker update', { env: options.env });
|
|
88
|
+
if (!ctx) {
|
|
89
|
+
return;
|
|
90
|
+
}
|
|
91
|
+
const workerKey = options.workerKey?.trim() || (0, config_1.getOrCreateWorkerKey)();
|
|
92
|
+
const intent = await ctx.client.workerCreateUpdateIntent({
|
|
93
|
+
workerKey,
|
|
94
|
+
environment: ctx.env,
|
|
95
|
+
reason: 'manual_update',
|
|
96
|
+
});
|
|
97
|
+
console.log(`Managed worker update intent ${intent.intent.id} created for worker ${workerKey}.`);
|
|
98
|
+
console.log(`Worker state: ${intent.worker.lifecycleState ?? 'unknown'} / ${intent.worker.updateState ?? 'unknown'}`);
|
|
99
|
+
await observeManagedWorkerUpdate({
|
|
100
|
+
client: ctx.client,
|
|
101
|
+
workerKey,
|
|
102
|
+
intentId: intent.intent.id,
|
|
103
|
+
});
|
|
104
|
+
return;
|
|
105
|
+
}
|
|
106
|
+
const activePersonalWorker = (0, worker_1.readActivePersonalWorkerRuntimeState)();
|
|
107
|
+
if (activePersonalWorker) {
|
|
108
|
+
throw new Error(`playdrop_update_active_personal_worker: stop the My Agent worker first, then rerun playdrop update. pid=${activePersonalWorker.pid} worker=${activePersonalWorker.workerName}`);
|
|
109
|
+
}
|
|
110
|
+
const targetVersion = validateTargetVersion(options.targetVersion);
|
|
111
|
+
const upgradeCommand = ['install', '-g', '--no-audit', '--no-fund', `@playdrop/playdrop-cli@${targetVersion}`];
|
|
112
|
+
const commandString = `npm ${upgradeCommand.join(' ')}`;
|
|
113
|
+
if (options.dryRun) {
|
|
114
|
+
console.log(commandString);
|
|
115
|
+
return;
|
|
116
|
+
}
|
|
117
|
+
await runCommand('npm', upgradeCommand);
|
|
118
|
+
}
|
|
@@ -10,6 +10,47 @@ type WorkerStartOptions = {
|
|
|
10
10
|
env?: string;
|
|
11
11
|
once?: boolean;
|
|
12
12
|
name?: string;
|
|
13
|
+
superviseStdin?: boolean;
|
|
14
|
+
};
|
|
15
|
+
type WorkerStatusOptions = {
|
|
16
|
+
env?: string;
|
|
17
|
+
json?: boolean;
|
|
18
|
+
};
|
|
19
|
+
type WorkerSetupOptions = {
|
|
20
|
+
env?: string;
|
|
21
|
+
name?: string;
|
|
22
|
+
start?: boolean;
|
|
23
|
+
restart?: boolean;
|
|
24
|
+
};
|
|
25
|
+
type WorkerLocalStatus = {
|
|
26
|
+
ready: boolean;
|
|
27
|
+
degradedReasons: string[];
|
|
28
|
+
cliVersion: string;
|
|
29
|
+
nodeVersion: string;
|
|
30
|
+
npmVersion: string | null;
|
|
31
|
+
playwright: {
|
|
32
|
+
version?: string;
|
|
33
|
+
chromiumInstalled?: boolean;
|
|
34
|
+
} | null;
|
|
35
|
+
plugin: {
|
|
36
|
+
ready: boolean;
|
|
37
|
+
root: string | null;
|
|
38
|
+
version: string | null;
|
|
39
|
+
error: string | null;
|
|
40
|
+
};
|
|
41
|
+
agents: AgentWorkerCapabilities['agents'];
|
|
42
|
+
capabilities: AgentWorkerCapabilities | null;
|
|
43
|
+
};
|
|
44
|
+
type WorkerStatusPayload = {
|
|
45
|
+
schemaVersion: 1;
|
|
46
|
+
generatedAt: string;
|
|
47
|
+
local: WorkerLocalStatus;
|
|
48
|
+
server: {
|
|
49
|
+
reachable: boolean;
|
|
50
|
+
authenticated: boolean;
|
|
51
|
+
worker: import('@playdrop/types').AgentWorkerResponse | null;
|
|
52
|
+
error?: string;
|
|
53
|
+
};
|
|
13
54
|
};
|
|
14
55
|
type TaskReportOptions = {
|
|
15
56
|
env?: string;
|
|
@@ -111,6 +152,8 @@ export declare function buildWorkerCapabilities(input: string | {
|
|
|
111
152
|
codexAuthenticated?: boolean | null;
|
|
112
153
|
claudeVersion?: string | null;
|
|
113
154
|
claudeAuthenticated?: boolean | null;
|
|
155
|
+
cursorVersion?: string | null;
|
|
156
|
+
cursorAuthenticated?: boolean | null;
|
|
114
157
|
npmVersion?: string | null;
|
|
115
158
|
playwright?: {
|
|
116
159
|
version?: string;
|
|
@@ -150,6 +193,27 @@ export declare function createLocalPlaydropShim(input: {
|
|
|
150
193
|
attempt: number;
|
|
151
194
|
devPort: number;
|
|
152
195
|
}): Promise<string>;
|
|
196
|
+
type WorkerRuntimeState = {
|
|
197
|
+
schemaVersion: 1;
|
|
198
|
+
pid: number;
|
|
199
|
+
env: string;
|
|
200
|
+
workerKey: string;
|
|
201
|
+
workerName: string;
|
|
202
|
+
target: AgentExecutionTarget;
|
|
203
|
+
startedAt: string;
|
|
204
|
+
};
|
|
205
|
+
export declare function readActivePersonalWorkerRuntimeState(): WorkerRuntimeState | null;
|
|
206
|
+
export declare function parseLaunchAgentProgramArguments(plist: string): string[];
|
|
207
|
+
export declare function assertLaunchAgentPlistCompatible(input: {
|
|
208
|
+
plistPath: string;
|
|
209
|
+
plist: string;
|
|
210
|
+
env: string;
|
|
211
|
+
workerName: string;
|
|
212
|
+
wrapperPath: string;
|
|
213
|
+
canonicalPlistPath: string;
|
|
214
|
+
}): void;
|
|
215
|
+
export declare function showWorkerStatus(options?: WorkerStatusOptions): Promise<WorkerStatusPayload>;
|
|
216
|
+
export declare function setupWorker(options?: WorkerSetupOptions): Promise<void>;
|
|
153
217
|
export declare function startWorker(options?: WorkerStartOptions): Promise<void>;
|
|
154
218
|
export declare function reportTask(options: TaskReportOptions): Promise<void>;
|
|
155
219
|
export declare function reportCatalogueTask(options: TaskCatalogueReportOptions): Promise<void>;
|