@phnx-labs/agents-cli 1.20.73 → 1.20.76
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 +989 -0
- package/README.md +36 -10
- package/dist/bin/agents +0 -0
- package/dist/commands/apply.js +21 -3
- package/dist/commands/attach.d.ts +10 -0
- package/dist/commands/attach.js +41 -0
- package/dist/commands/computer.js +3 -3
- package/dist/commands/detach-core.d.ts +46 -0
- package/dist/commands/detach-core.js +61 -0
- package/dist/commands/detach.d.ts +5 -0
- package/dist/commands/detach.js +171 -0
- package/dist/commands/doctor.js +31 -1
- package/dist/commands/exec.js +31 -3
- package/dist/commands/export.d.ts +11 -0
- package/dist/commands/export.js +215 -0
- package/dist/commands/feed.d.ts +7 -1
- package/dist/commands/feed.js +47 -4
- package/dist/commands/go.d.ts +9 -2
- package/dist/commands/go.js +16 -6
- package/dist/commands/harness.d.ts +14 -0
- package/dist/commands/harness.js +145 -0
- package/dist/commands/import.js +87 -9
- package/dist/commands/inspect.js +5 -2
- package/dist/commands/profiles.d.ts +20 -0
- package/dist/commands/profiles.js +68 -21
- package/dist/commands/repo.js +14 -0
- package/dist/commands/routines.js +15 -2
- package/dist/commands/secrets.js +44 -21
- package/dist/commands/sessions-browser.js +1 -1
- package/dist/commands/sessions-export.js +19 -5
- package/dist/commands/sessions-migrate.d.ts +29 -0
- package/dist/commands/sessions-migrate.js +596 -0
- package/dist/commands/sessions-picker.js +16 -1
- package/dist/commands/sessions.d.ts +36 -13
- package/dist/commands/sessions.js +210 -40
- package/dist/commands/setup-computer.js +2 -2
- package/dist/commands/setup.js +6 -1
- package/dist/commands/ssh.js +71 -35
- package/dist/commands/status.js +10 -2
- package/dist/commands/versions.js +51 -11
- package/dist/commands/view.d.ts +5 -0
- package/dist/commands/view.js +99 -31
- package/dist/commands/watchdog.d.ts +7 -2
- package/dist/commands/watchdog.js +73 -57
- package/dist/index.js +59 -7
- package/dist/lib/activity.d.ts +14 -4
- package/dist/lib/activity.js +17 -5
- package/dist/lib/actor.d.ts +50 -0
- package/dist/lib/actor.js +166 -0
- package/dist/lib/agent-spec/provider.js +2 -1
- package/dist/lib/agent-spec/resolve.js +19 -5
- package/dist/lib/agent-spec/types.d.ts +9 -1
- package/dist/lib/agents.d.ts +56 -0
- package/dist/lib/agents.js +133 -7
- package/dist/lib/cloud/codex.d.ts +2 -0
- package/dist/lib/cloud/codex.js +14 -3
- package/dist/lib/cloud/session-index.d.ts +32 -0
- package/dist/lib/cloud/session-index.js +58 -0
- package/dist/lib/cloud/store.d.ts +7 -0
- package/dist/lib/cloud/store.js +25 -0
- package/dist/lib/config-transfer.d.ts +16 -0
- package/dist/lib/config-transfer.js +60 -0
- package/dist/lib/daemon.js +18 -2
- package/dist/lib/devices/connect.d.ts +15 -1
- package/dist/lib/devices/connect.js +15 -1
- package/dist/lib/devices/fleet.d.ts +21 -0
- package/dist/lib/devices/fleet.js +26 -0
- package/dist/lib/devices/health-report.d.ts +38 -0
- package/dist/lib/devices/health-report.js +214 -0
- package/dist/lib/devices/health.js +4 -1
- package/dist/lib/devices/reachability.d.ts +31 -0
- package/dist/lib/devices/reachability.js +40 -0
- package/dist/lib/devices/registry.d.ts +33 -0
- package/dist/lib/devices/registry.js +37 -0
- package/dist/lib/devices/resolve-target.d.ts +15 -27
- package/dist/lib/devices/resolve-target.js +63 -102
- package/dist/lib/devices/sync.d.ts +18 -0
- package/dist/lib/devices/sync.js +23 -1
- package/dist/lib/devices/tailscale.d.ts +3 -0
- package/dist/lib/devices/tailscale.js +1 -0
- package/dist/lib/events.d.ts +1 -1
- package/dist/lib/exec.d.ts +66 -0
- package/dist/lib/exec.js +195 -6
- package/dist/lib/export.d.ts +72 -0
- package/dist/lib/export.js +269 -0
- package/dist/lib/feed-post.d.ts +63 -0
- package/dist/lib/feed-post.js +204 -0
- package/dist/lib/fleet/apply.d.ts +32 -2
- package/dist/lib/fleet/apply.js +97 -10
- package/dist/lib/fleet/types.d.ts +11 -0
- package/dist/lib/fs-walk.d.ts +13 -0
- package/dist/lib/fs-walk.js +16 -7
- package/dist/lib/hooks.d.ts +1 -0
- package/dist/lib/hooks.js +156 -0
- package/dist/lib/hosts/dispatch.d.ts +7 -0
- package/dist/lib/hosts/dispatch.js +2 -0
- package/dist/lib/hosts/passthrough.js +2 -0
- package/dist/lib/hosts/reconnect.d.ts +78 -0
- package/dist/lib/hosts/reconnect.js +127 -0
- package/dist/lib/hosts/registry.d.ts +75 -14
- package/dist/lib/hosts/registry.js +205 -30
- package/dist/lib/hosts/remote-cmd.js +1 -0
- package/dist/lib/hosts/run-target.d.ts +13 -5
- package/dist/lib/hosts/run-target.js +26 -10
- package/dist/lib/hosts/session-index.d.ts +18 -1
- package/dist/lib/hosts/session-index.js +37 -2
- package/dist/lib/hosts/session-marker.d.ts +33 -0
- package/dist/lib/hosts/session-marker.js +51 -0
- package/dist/lib/hosts/tasks.d.ts +8 -4
- package/dist/lib/import.d.ts +25 -0
- package/dist/lib/import.js +107 -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.d.ts +20 -0
- package/dist/lib/menubar/install-menubar.js +45 -1
- package/dist/lib/migrate.d.ts +16 -0
- package/dist/lib/migrate.js +36 -0
- package/dist/lib/models.d.ts +27 -0
- package/dist/lib/models.js +54 -1
- package/dist/lib/overdue.d.ts +7 -2
- package/dist/lib/overdue.js +18 -11
- package/dist/lib/picker.js +4 -1
- package/dist/lib/platform/process.d.ts +17 -0
- package/dist/lib/platform/process.js +70 -0
- package/dist/lib/profiles-presets.js +9 -7
- package/dist/lib/profiles.d.ts +31 -0
- package/dist/lib/profiles.js +70 -0
- package/dist/lib/project-resources.js +20 -5
- package/dist/lib/pty-server.d.ts +2 -10
- package/dist/lib/pty-server.js +4 -38
- package/dist/lib/registry.d.ts +1 -1
- package/dist/lib/registry.js +48 -8
- package/dist/lib/rotate.d.ts +18 -0
- package/dist/lib/rotate.js +28 -0
- package/dist/lib/routines.d.ts +26 -0
- package/dist/lib/routines.js +19 -2
- package/dist/lib/runner.js +104 -7
- package/dist/lib/secrets/agent.d.ts +66 -1
- package/dist/lib/secrets/agent.js +154 -90
- package/dist/lib/secrets/bundles.d.ts +34 -0
- package/dist/lib/secrets/bundles.js +179 -19
- package/dist/lib/secrets/index.d.ts +15 -1
- package/dist/lib/secrets/index.js +21 -3
- package/dist/lib/secrets/rc-hygiene.d.ts +55 -0
- package/dist/lib/secrets/rc-hygiene.js +154 -0
- package/dist/lib/secrets/remote.d.ts +7 -4
- package/dist/lib/secrets/remote.js +7 -4
- package/dist/lib/secrets/sync-commands.d.ts +21 -0
- package/dist/lib/secrets/sync-commands.js +21 -0
- package/dist/lib/self-update.d.ts +23 -2
- package/dist/lib/self-update.js +86 -5
- package/dist/lib/session/active.d.ts +114 -7
- package/dist/lib/session/active.js +323 -52
- package/dist/lib/session/cloud.js +2 -1
- package/dist/lib/session/db.d.ts +48 -0
- package/dist/lib/session/db.js +238 -14
- package/dist/lib/session/detached.d.ts +30 -0
- package/dist/lib/session/detached.js +92 -0
- package/dist/lib/session/discover.d.ts +465 -2
- package/dist/lib/session/discover.js +1648 -468
- package/dist/lib/session/fork.js +2 -1
- package/dist/lib/session/hook-sessions.d.ts +43 -0
- package/dist/lib/session/hook-sessions.js +135 -0
- package/dist/lib/session/linear.d.ts +6 -0
- package/dist/lib/session/linear.js +55 -0
- package/dist/lib/session/migrate-targets.d.ts +65 -0
- package/dist/lib/session/migrate-targets.js +94 -0
- package/dist/lib/session/migrations.d.ts +37 -0
- package/dist/lib/session/migrations.js +60 -0
- package/dist/lib/session/parse.d.ts +18 -0
- package/dist/lib/session/parse.js +130 -30
- package/dist/lib/session/pid-registry.d.ts +34 -2
- package/dist/lib/session/pid-registry.js +49 -2
- package/dist/lib/session/render.d.ts +7 -2
- package/dist/lib/session/render.js +22 -10
- package/dist/lib/session/short-id.d.ts +17 -0
- package/dist/lib/session/short-id.js +20 -0
- package/dist/lib/session/state.js +6 -2
- package/dist/lib/shims.d.ts +27 -1
- package/dist/lib/shims.js +88 -6
- package/dist/lib/sqlite.d.ts +3 -2
- package/dist/lib/sqlite.js +27 -4
- package/dist/lib/staleness/detectors/commands.js +1 -1
- package/dist/lib/staleness/detectors/workflows.js +13 -2
- package/dist/lib/staleness/writers/commands.js +7 -7
- package/dist/lib/staleness/writers/workflows.d.ts +4 -2
- package/dist/lib/startup/command-registry.d.ts +2 -0
- package/dist/lib/startup/command-registry.js +5 -0
- package/dist/lib/state.d.ts +1 -1
- package/dist/lib/state.js +15 -36
- package/dist/lib/teams/agents.d.ts +19 -10
- package/dist/lib/teams/agents.js +40 -39
- package/dist/lib/types.d.ts +48 -2
- package/dist/lib/uninstall.js +1 -45
- package/dist/lib/usage.d.ts +33 -1
- package/dist/lib/usage.js +172 -12
- package/dist/lib/versions.d.ts +22 -2
- package/dist/lib/versions.js +98 -10
- package/dist/lib/watchdog/log.d.ts +43 -0
- package/dist/lib/watchdog/log.js +69 -0
- package/dist/lib/watchdog/routine.d.ts +44 -0
- package/dist/lib/watchdog/routine.js +69 -0
- package/dist/lib/watchdog/runner.d.ts +51 -7
- package/dist/lib/watchdog/runner.js +239 -64
- package/dist/lib/watchdog/watchdog.d.ts +1 -1
- package/dist/lib/watchdog/watchdog.js +31 -16
- package/dist/lib/workflows.d.ts +16 -0
- package/dist/lib/workflows.js +110 -1
- package/package.json +1 -1
|
@@ -64,23 +64,32 @@ export function classifyTerminal(input) {
|
|
|
64
64
|
}
|
|
65
65
|
return { kind: 'stalled', stalledForMs: age };
|
|
66
66
|
}
|
|
67
|
-
export const WATCHDOG_SYSTEM_PROMPT = `You are
|
|
68
|
-
|
|
67
|
+
export const WATCHDOG_SYSTEM_PROMPT = `You are the watchdog for AI coding agents running in terminals. These agents are
|
|
68
|
+
expected to DRIVE TO COMPLETION end-to-end. They too often stop to ask a needless
|
|
69
|
+
question or pause with the task unfinished. For each stalled terminal below, decide
|
|
70
|
+
NUDGE (send a message that unsticks it and pushes it to finish) or SKIP (it genuinely
|
|
71
|
+
needs the human).
|
|
69
72
|
|
|
70
|
-
|
|
71
|
-
-
|
|
72
|
-
|
|
73
|
-
-
|
|
73
|
+
NUDGE when the agent could have continued on its own:
|
|
74
|
+
- It asked permission for an obvious or already-authorized next step
|
|
75
|
+
("should I proceed?", "want me to continue?", "shall I run the tests?").
|
|
76
|
+
- It asked a question it could answer itself from the available context or a
|
|
77
|
+
reasonable default.
|
|
78
|
+
- It announced an action ("I'll run X", "let me write Y") but no tool call followed.
|
|
79
|
+
- It paused with the task incomplete and no real blocker.
|
|
80
|
+
The nudge text MUST: restate the goal, tell it to use best judgment and finish
|
|
81
|
+
end-to-end WITHOUT asking again, and give ONE concrete hint — the specific next
|
|
82
|
+
step, a tool it forgot, or the sensible default to take. Imperative, 1-2 sentences,
|
|
83
|
+
no emojis, under 200 characters.
|
|
74
84
|
|
|
75
|
-
|
|
76
|
-
-
|
|
77
|
-
-
|
|
85
|
+
SKIP when the agent genuinely needs the human:
|
|
86
|
+
- Credentials, auth, login, 2FA, or biometric.
|
|
87
|
+
- An irreversible or outward-facing action that needs sign-off (force-push, delete
|
|
88
|
+
prod data, publish/release, spend money, send an external message).
|
|
89
|
+
- A real product or intent decision with genuine ambiguity (not a trivial default).
|
|
90
|
+
- The task is actually complete.
|
|
78
91
|
- You cannot tell what the agent is doing.
|
|
79
92
|
|
|
80
|
-
Nudge text must be:
|
|
81
|
-
- One sentence, imperative ("Show me the file.", "Run the tests.").
|
|
82
|
-
- No emojis. No apologies. Under 120 characters.
|
|
83
|
-
|
|
84
93
|
Respond with ONLY a JSON array (no prose, no code fence):
|
|
85
94
|
[{"terminalId":"<id>","action":"nudge"|"skip","text":"<message or empty>","reason":"<brief>"}]`;
|
|
86
95
|
// User-editable playbook appended below the built-in prompt. The user maintains
|
|
@@ -137,15 +146,21 @@ export function parseWatchdogResponse(stdout) {
|
|
|
137
146
|
return decisions;
|
|
138
147
|
}
|
|
139
148
|
export function isLikelyTrulyBlocked(candidate) {
|
|
140
|
-
|
|
141
|
-
return true;
|
|
149
|
+
// With no tail to reason over, only a very long stall counts as blocked.
|
|
142
150
|
if (candidate.tailLines.length === 0)
|
|
143
|
-
return
|
|
151
|
+
return candidate.stalledForMs >= FORCE_REVIEW_STALL_MS;
|
|
144
152
|
const lowerTail = candidate.tailLines.join('\n').toLowerCase();
|
|
153
|
+
// Waiting-on-user and completion hints are checked BEFORE the 15m force-review
|
|
154
|
+
// short-circuit — a long-idle OPEN QUESTION must defer (not be blindly
|
|
155
|
+
// force-nudged) and a finished task is done. The old order tested stall age
|
|
156
|
+
// first, so a 15m-60m idle session whose tail said "waiting on user" / "done"
|
|
157
|
+
// was force-nudged anyway. Precedence fixed here (watchdog-brain-v2).
|
|
145
158
|
if (WAITING_HINTS.some((hint) => lowerTail.includes(hint)))
|
|
146
159
|
return false;
|
|
147
160
|
if (COMPLETION_HINTS.some((hint) => lowerTail.includes(hint)))
|
|
148
161
|
return false;
|
|
162
|
+
if (candidate.stalledForMs >= FORCE_REVIEW_STALL_MS)
|
|
163
|
+
return true;
|
|
149
164
|
if (BLOCKED_HINTS.some((hint) => lowerTail.includes(hint)))
|
|
150
165
|
return true;
|
|
151
166
|
let sawToolAfter = false;
|
package/dist/lib/workflows.d.ts
CHANGED
|
@@ -296,6 +296,22 @@ export declare function transformWorkflowForKimi(workflowPath: string, name: str
|
|
|
296
296
|
export declare function transformWorkflowForAntigravity(workflowPath: string, name: string): string;
|
|
297
297
|
/** Convert a canonical agents-cli workflow bundle into an OpenClaw Lobster file. */
|
|
298
298
|
export declare function transformWorkflowForOpenClaw(workflowPath: string, name: string): string;
|
|
299
|
+
/** Marker comment prefix written into agents-cli-managed Grok `.rhai` files. */
|
|
300
|
+
export declare const GROK_WORKFLOW_MARKER = "agents_workflow";
|
|
301
|
+
/**
|
|
302
|
+
* Convert a canonical agents-cli workflow bundle into a Grok native Rhai
|
|
303
|
+
* workflow script. Grok discovers saved workflows as
|
|
304
|
+
* `~/.grok/workflows/<name>.rhai` (and project `.grok/workflows/`) and exposes
|
|
305
|
+
* each as a `/<name>` slash command (enabled by default since v0.2.111).
|
|
306
|
+
*
|
|
307
|
+
* The projection is a single-agent orchestrator that feeds the WORKFLOW.md
|
|
308
|
+
* body as the agent prompt plus the caller's `args.prompt` (or string args).
|
|
309
|
+
* Multi-phase fan-out is left to hand-authored Rhai — agents-cli's job is to
|
|
310
|
+
* land the orchestrator instructions in the native path.
|
|
311
|
+
*/
|
|
312
|
+
export declare function transformWorkflowForGrok(workflowPath: string, name: string): string;
|
|
313
|
+
/** Read the agents_workflow marker from a Grok `.rhai` file, if present. */
|
|
314
|
+
export declare function grokWorkflowMarker(filePath: string): string | null;
|
|
299
315
|
/**
|
|
300
316
|
* Resolve an `agents run <workflow>` reference.
|
|
301
317
|
*
|
package/dist/lib/workflows.js
CHANGED
|
@@ -9,7 +9,7 @@ import * as fs from 'fs';
|
|
|
9
9
|
import * as os from 'os';
|
|
10
10
|
import * as path from 'path';
|
|
11
11
|
import * as yaml from 'yaml';
|
|
12
|
-
import { capableAgents } from './capabilities.js';
|
|
12
|
+
import { capableAgents, supports } from './capabilities.js';
|
|
13
13
|
import { getProjectAgentsDir, getSystemWorkflowsDir, getUserWorkflowsDir, getTrashWorkflowsDir, getEnabledExtraRepos, } from './state.js';
|
|
14
14
|
import { listInstalledVersions, getVersionHomePath } from './versions.js';
|
|
15
15
|
/**
|
|
@@ -444,6 +444,67 @@ export function transformWorkflowForOpenClaw(workflowPath, name) {
|
|
|
444
444
|
],
|
|
445
445
|
});
|
|
446
446
|
}
|
|
447
|
+
/** Marker comment prefix written into agents-cli-managed Grok `.rhai` files. */
|
|
448
|
+
export const GROK_WORKFLOW_MARKER = 'agents_workflow';
|
|
449
|
+
/** Escape a string for embedding inside a Rhai double-quoted literal. */
|
|
450
|
+
function escapeRhaiString(s) {
|
|
451
|
+
return s
|
|
452
|
+
.replace(/\\/g, '\\\\')
|
|
453
|
+
.replace(/"/g, '\\"')
|
|
454
|
+
.replace(/\r\n/g, '\\n')
|
|
455
|
+
.replace(/\n/g, '\\n')
|
|
456
|
+
.replace(/\r/g, '\\n');
|
|
457
|
+
}
|
|
458
|
+
/**
|
|
459
|
+
* Convert a canonical agents-cli workflow bundle into a Grok native Rhai
|
|
460
|
+
* workflow script. Grok discovers saved workflows as
|
|
461
|
+
* `~/.grok/workflows/<name>.rhai` (and project `.grok/workflows/`) and exposes
|
|
462
|
+
* each as a `/<name>` slash command (enabled by default since v0.2.111).
|
|
463
|
+
*
|
|
464
|
+
* The projection is a single-agent orchestrator that feeds the WORKFLOW.md
|
|
465
|
+
* body as the agent prompt plus the caller's `args.prompt` (or string args).
|
|
466
|
+
* Multi-phase fan-out is left to hand-authored Rhai — agents-cli's job is to
|
|
467
|
+
* land the orchestrator instructions in the native path.
|
|
468
|
+
*/
|
|
469
|
+
export function transformWorkflowForGrok(workflowPath, name) {
|
|
470
|
+
const fm = parseWorkflowFrontmatter(workflowPath);
|
|
471
|
+
if (!fm)
|
|
472
|
+
throw new Error(`Invalid WORKFLOW.md in ${workflowPath}`);
|
|
473
|
+
const body = getWorkflowBody(workflowPath);
|
|
474
|
+
const description = (fm.description || name).trim();
|
|
475
|
+
const instructions = (body || description).trim();
|
|
476
|
+
return [
|
|
477
|
+
`// ${GROK_WORKFLOW_MARKER}: ${name}`,
|
|
478
|
+
`// Managed by agents-cli — re-sync from ~/.agents/workflows/${name}/; do not edit by hand.`,
|
|
479
|
+
`let meta = #{`,
|
|
480
|
+
` name: "${escapeRhaiString(name)}",`,
|
|
481
|
+
` description: "${escapeRhaiString(description)}",`,
|
|
482
|
+
` phases: [ #{ title: "Run", detail: "orchestrator" } ],`,
|
|
483
|
+
`};`,
|
|
484
|
+
``,
|
|
485
|
+
`let user_prompt = if args == () { () } else if type_of(args) == "string" { args } else { args.prompt };`,
|
|
486
|
+
`if user_prompt == () { pause("verification", "Pass a prompt as args.prompt or a string arg."); }`,
|
|
487
|
+
``,
|
|
488
|
+
`phase("Run");`,
|
|
489
|
+
`let instructions = "${escapeRhaiString(instructions)}";`,
|
|
490
|
+
`let prompt = instructions + "\\n\\n---\\n\\nUser request:\\n" + user_prompt;`,
|
|
491
|
+
`let r = agent(prompt, #{ label: "orchestrator", capability_mode: "all" });`,
|
|
492
|
+
`if r != () && r.success { complete(r.output); }`,
|
|
493
|
+
`complete(#{ summary: "workflow failed", error: if r == () { "no result" } else { "agent failed" } });`,
|
|
494
|
+
``,
|
|
495
|
+
].join('\n');
|
|
496
|
+
}
|
|
497
|
+
/** Read the agents_workflow marker from a Grok `.rhai` file, if present. */
|
|
498
|
+
export function grokWorkflowMarker(filePath) {
|
|
499
|
+
try {
|
|
500
|
+
const content = fs.readFileSync(filePath, 'utf-8');
|
|
501
|
+
const match = content.match(new RegExp(`^//\\s*${GROK_WORKFLOW_MARKER}:\\s*(\\S+)`, 'm'));
|
|
502
|
+
return match?.[1] ?? null;
|
|
503
|
+
}
|
|
504
|
+
catch {
|
|
505
|
+
return null;
|
|
506
|
+
}
|
|
507
|
+
}
|
|
447
508
|
function expandWorkflowPath(ref) {
|
|
448
509
|
if (ref === '~')
|
|
449
510
|
return process.env.HOME ?? ref;
|
|
@@ -622,6 +683,8 @@ function workflowTargetRoot(agent, versionHome) {
|
|
|
622
683
|
return antigravityWorkflowsDir();
|
|
623
684
|
if (agent === 'openclaw')
|
|
624
685
|
return path.join(versionHome, '.openclaw', 'workflows');
|
|
686
|
+
if (agent === 'grok')
|
|
687
|
+
return path.join(versionHome, '.grok', 'workflows');
|
|
625
688
|
return path.join(versionHome, 'workflows');
|
|
626
689
|
}
|
|
627
690
|
/** List workflow names synced into a specific agent version home. */
|
|
@@ -676,6 +739,20 @@ export function listWorkflowsForAgent(agent, versionHome) {
|
|
|
676
739
|
return [];
|
|
677
740
|
}
|
|
678
741
|
}
|
|
742
|
+
if (agent === 'grok') {
|
|
743
|
+
const dir = workflowTargetRoot(agent, versionHome);
|
|
744
|
+
if (!fs.existsSync(dir))
|
|
745
|
+
return [];
|
|
746
|
+
try {
|
|
747
|
+
return fs.readdirSync(dir, { withFileTypes: true })
|
|
748
|
+
.filter(d => d.isFile() && d.name.endsWith('.rhai') && !d.name.startsWith('.'))
|
|
749
|
+
.map(d => d.name.slice(0, -'.rhai'.length))
|
|
750
|
+
.filter(base => grokWorkflowMarker(path.join(dir, `${base}.rhai`)) === base);
|
|
751
|
+
}
|
|
752
|
+
catch {
|
|
753
|
+
return [];
|
|
754
|
+
}
|
|
755
|
+
}
|
|
679
756
|
const workflowsDir = workflowTargetRoot(agent, versionHome);
|
|
680
757
|
if (!fs.existsSync(workflowsDir))
|
|
681
758
|
return [];
|
|
@@ -823,6 +900,19 @@ export function syncWorkflowToVersion(workflowPath, name, agent, versionHome) {
|
|
|
823
900
|
fs.writeFileSync(targetFile, transformWorkflowForOpenClaw(workflowPath, name), 'utf-8');
|
|
824
901
|
return { success: true };
|
|
825
902
|
}
|
|
903
|
+
if (agent === 'grok') {
|
|
904
|
+
const targetDir = workflowTargetRoot(agent, versionHome);
|
|
905
|
+
const targetFile = path.join(targetDir, `${name}.rhai`);
|
|
906
|
+
if (fs.existsSync(targetFile)) {
|
|
907
|
+
const marker = grokWorkflowMarker(targetFile);
|
|
908
|
+
if (marker !== name) {
|
|
909
|
+
return { success: false, error: `Grok workflow '${name}' already exists and is not managed by agents-cli` };
|
|
910
|
+
}
|
|
911
|
+
}
|
|
912
|
+
fs.mkdirSync(targetDir, { recursive: true });
|
|
913
|
+
fs.writeFileSync(targetFile, transformWorkflowForGrok(workflowPath, name), 'utf-8');
|
|
914
|
+
return { success: true };
|
|
915
|
+
}
|
|
826
916
|
const targetDir = path.join(workflowTargetRoot(agent, versionHome), name);
|
|
827
917
|
fs.mkdirSync(workflowTargetRoot(agent, versionHome), { recursive: true });
|
|
828
918
|
if (fs.existsSync(targetDir)) {
|
|
@@ -887,6 +977,22 @@ export function removeWorkflowFromVersion(agent, version, name) {
|
|
|
887
977
|
return { success: false, error: err.message };
|
|
888
978
|
}
|
|
889
979
|
}
|
|
980
|
+
if (agent === 'grok') {
|
|
981
|
+
const targetFile = path.join(workflowTargetRoot(agent, versionHome), `${name}.rhai`);
|
|
982
|
+
if (!fs.existsSync(targetFile)) {
|
|
983
|
+
return { success: false, error: `Workflow '${name}' not synced to ${agent}@${version}` };
|
|
984
|
+
}
|
|
985
|
+
if (grokWorkflowMarker(targetFile) !== name) {
|
|
986
|
+
return { success: false, error: `Grok workflow '${name}' is not managed by agents-cli` };
|
|
987
|
+
}
|
|
988
|
+
try {
|
|
989
|
+
fs.rmSync(targetFile, { force: true });
|
|
990
|
+
return { success: true };
|
|
991
|
+
}
|
|
992
|
+
catch (err) {
|
|
993
|
+
return { success: false, error: err.message };
|
|
994
|
+
}
|
|
995
|
+
}
|
|
890
996
|
const targetPath = path.join(workflowTargetRoot(agent, versionHome), name);
|
|
891
997
|
if (!fs.existsSync(targetPath)) {
|
|
892
998
|
return { success: false, error: `Workflow '${name}' not synced to ${agent}@${version}` };
|
|
@@ -958,6 +1064,9 @@ export function iterWorkflowsCapableVersions(filter) {
|
|
|
958
1064
|
for (const version of versions) {
|
|
959
1065
|
if (filter?.version && filter.version !== version)
|
|
960
1066
|
continue;
|
|
1067
|
+
// Honour version floors (e.g. grok workflows since 0.2.111).
|
|
1068
|
+
if (!supports(agentId, 'workflows', version).ok)
|
|
1069
|
+
continue;
|
|
961
1070
|
result.push({ agent: agentId, version });
|
|
962
1071
|
}
|
|
963
1072
|
}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@phnx-labs/agents-cli",
|
|
3
|
-
"version": "1.20.
|
|
3
|
+
"version": "1.20.76",
|
|
4
4
|
"description": "One CLI for all your AI coding agents - versions, config, cloud dispatch, sessions, and teams (now with first-class Grok Build CLI support)",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"main": "dist/index.js",
|