@phnx-labs/agents-cli 1.16.0 → 1.17.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +65 -0
- package/dist/commands/browser.js +248 -9
- package/dist/commands/cloud.js +8 -0
- package/dist/commands/exec.js +70 -1
- package/dist/commands/plugins.js +179 -5
- package/dist/commands/prune.js +6 -0
- package/dist/commands/secrets.js +117 -19
- package/dist/commands/view.js +21 -8
- package/dist/commands/workflows.d.ts +10 -0
- package/dist/commands/workflows.js +457 -0
- package/dist/index.js +31 -16
- package/dist/lib/browser/cdp.js +7 -4
- package/dist/lib/browser/chrome.d.ts +10 -0
- package/dist/lib/browser/chrome.js +37 -2
- package/dist/lib/browser/drivers/local.js +13 -2
- package/dist/lib/browser/input.d.ts +1 -0
- package/dist/lib/browser/input.js +3 -0
- package/dist/lib/browser/ipc.js +14 -0
- package/dist/lib/browser/profiles.d.ts +5 -0
- package/dist/lib/browser/profiles.js +45 -0
- package/dist/lib/browser/service.d.ts +10 -0
- package/dist/lib/browser/service.js +29 -1
- package/dist/lib/browser/types.d.ts +11 -1
- package/dist/lib/cloud/rush.d.ts +28 -1
- package/dist/lib/cloud/rush.js +68 -13
- package/dist/lib/commands.d.ts +0 -15
- package/dist/lib/commands.js +5 -5
- package/dist/lib/hooks.js +24 -11
- package/dist/lib/migrate.js +59 -1
- package/dist/lib/permissions.d.ts +0 -58
- package/dist/lib/permissions.js +10 -10
- package/dist/lib/plugins.d.ts +75 -34
- package/dist/lib/plugins.js +640 -133
- package/dist/lib/resource-patterns.d.ts +41 -0
- package/dist/lib/resource-patterns.js +82 -0
- package/dist/lib/resources/index.d.ts +17 -0
- package/dist/lib/resources/index.js +7 -0
- package/dist/lib/resources/types.d.ts +1 -1
- package/dist/lib/resources/workflows.d.ts +24 -0
- package/dist/lib/resources/workflows.js +110 -0
- package/dist/lib/resources.d.ts +6 -1
- package/dist/lib/resources.js +12 -2
- package/dist/lib/session/db.d.ts +18 -0
- package/dist/lib/session/db.js +106 -7
- package/dist/lib/session/discover.d.ts +6 -0
- package/dist/lib/session/discover.js +28 -17
- package/dist/lib/shims.d.ts +3 -51
- package/dist/lib/shims.js +18 -10
- package/dist/lib/sqlite.js +10 -4
- package/dist/lib/state.d.ts +15 -2
- package/dist/lib/state.js +29 -8
- package/dist/lib/types.d.ts +43 -14
- package/dist/lib/versions.d.ts +3 -0
- package/dist/lib/versions.js +139 -27
- package/dist/lib/workflows.d.ts +79 -0
- package/dist/lib/workflows.js +233 -0
- package/package.json +1 -5
- package/scripts/postinstall.js +59 -58
- package/dist/commands/fork.d.ts +0 -10
- package/dist/commands/fork.js +0 -146
|
@@ -13,23 +13,22 @@ import * as crypto from 'crypto';
|
|
|
13
13
|
import * as readline from 'readline';
|
|
14
14
|
import { execFile } from 'child_process';
|
|
15
15
|
import { promisify } from 'util';
|
|
16
|
-
import { getAgentsDir,
|
|
16
|
+
import { getAgentsDir, getHistoryDir } from '../state.js';
|
|
17
17
|
const execFileAsync = promisify(execFile);
|
|
18
18
|
import { AGENTS, getCliVersion } from '../agents.js';
|
|
19
19
|
import { walkForFiles } from '../fs-walk.js';
|
|
20
20
|
import { getConfigSymlinkVersion } from '../shims.js';
|
|
21
21
|
import { SESSION_AGENTS } from './types.js';
|
|
22
22
|
import { extractSessionTopic } from './prompt.js';
|
|
23
|
-
import { getDB, getScanStampByPath, getScanStampsForPaths, recordScans, syncLabels, upsertSessionsBatch, querySessions, countSessions, ftsSearch, } from './db.js';
|
|
23
|
+
import { getDB, getScanStampByPath, getScanStampsForPaths, recordScans, syncLabels, upsertSessionsBatch, querySessions, countSessions, ftsSearch, tryClaimScan, releaseScan, } from './db.js';
|
|
24
24
|
const HOME = os.homedir();
|
|
25
25
|
// Versions can live under either repo: the user repo (current canonical
|
|
26
|
-
// location, ~/.agents/versions/) or the system repo (legacy / npm-shipped,
|
|
26
|
+
// location, ~/.agents/.history/versions/) or the system repo (legacy / npm-shipped,
|
|
27
27
|
// ~/.agents-system/versions/). Both must be scanned — sessions written by
|
|
28
28
|
// any installed version end up in that version's projects/ dir, and the user
|
|
29
29
|
// can be running one repo's version while another repo holds older versions
|
|
30
30
|
// whose JSONLs the user still wants to search.
|
|
31
|
-
const VERSIONS_ROOTS = [
|
|
32
|
-
const AGENTS_DIR = getAgentsDir();
|
|
31
|
+
const VERSIONS_ROOTS = [getHistoryDir(), getAgentsDir()];
|
|
33
32
|
const RUSH_SESSIONS_DIR = path.join(HOME, '.rush', 'sessions');
|
|
34
33
|
const HERMES_SESSIONS_DIR = path.join(HOME, '.hermes', 'sessions');
|
|
35
34
|
/** How long OpenClaw channel/cron snapshots stay valid before we re-shell-out. */
|
|
@@ -39,24 +38,36 @@ const cachedAgentVersions = new Map();
|
|
|
39
38
|
/**
|
|
40
39
|
* Discover sessions. Scans only files whose (mtime, size) have changed since
|
|
41
40
|
* the last run; everything else is served from the SQLite cache.
|
|
41
|
+
*
|
|
42
|
+
* Only one process runs the incremental scan at a time. When many agents boot
|
|
43
|
+
* simultaneously (e.g. after a restart), the first to claim the scan slot does
|
|
44
|
+
* the work; the rest skip parsing entirely and serve from the DB. The claim is
|
|
45
|
+
* stored in the `meta` table — crash-safe via dead-PID detection and a 2-min
|
|
46
|
+
* TTL, no external lock files needed.
|
|
42
47
|
*/
|
|
43
48
|
export async function discoverSessions(options) {
|
|
44
49
|
// Touch the DB so the schema is ready and connection is cached for this run.
|
|
45
50
|
getDB();
|
|
46
51
|
const agents = options?.agent ? [options.agent] : SESSION_AGENTS;
|
|
47
52
|
const onProgress = options?.onProgress;
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
53
|
+
if (tryClaimScan(process.pid)) {
|
|
54
|
+
try {
|
|
55
|
+
await Promise.all(agents.map(agent => {
|
|
56
|
+
switch (agent) {
|
|
57
|
+
case 'claude': return scanClaudeIncremental(onProgress);
|
|
58
|
+
case 'codex': return scanCodexIncremental(onProgress);
|
|
59
|
+
case 'gemini': return scanGeminiIncremental(onProgress);
|
|
60
|
+
case 'opencode': return scanOpenCodeIncremental();
|
|
61
|
+
case 'openclaw': return scanOpenClawIncremental();
|
|
62
|
+
case 'rush': return scanRushIncremental(onProgress);
|
|
63
|
+
case 'hermes': return scanHermesIncremental(onProgress);
|
|
64
|
+
}
|
|
65
|
+
}));
|
|
58
66
|
}
|
|
59
|
-
|
|
67
|
+
finally {
|
|
68
|
+
releaseScan(process.pid);
|
|
69
|
+
}
|
|
70
|
+
}
|
|
60
71
|
const sessions = querySessions(buildQueryOptions(options, agents, { includeLimit: true }));
|
|
61
72
|
return sessions;
|
|
62
73
|
}
|
|
@@ -202,7 +213,7 @@ export function getAgentSessionDirs(agent, subdir) {
|
|
|
202
213
|
}
|
|
203
214
|
catch { /* dir unreadable */ }
|
|
204
215
|
}
|
|
205
|
-
const backupsBase = path.join(
|
|
216
|
+
const backupsBase = path.join(getHistoryDir(), 'backups', agent);
|
|
206
217
|
if (fs.existsSync(backupsBase)) {
|
|
207
218
|
try {
|
|
208
219
|
for (const ts of fs.readdirSync(backupsBase)) {
|
package/dist/lib/shims.d.ts
CHANGED
|
@@ -13,15 +13,6 @@ export interface ConflictInfo {
|
|
|
13
13
|
version: string;
|
|
14
14
|
conflicts: string[];
|
|
15
15
|
}
|
|
16
|
-
/**
|
|
17
|
-
* Detect conflicting files between source and destination directories.
|
|
18
|
-
* Returns list of filenames that exist in both locations (excluding symlinks in dest).
|
|
19
|
-
*/
|
|
20
|
-
export declare function detectConflicts(src: string, dest: string, prefix?: string): string[];
|
|
21
|
-
/**
|
|
22
|
-
* Prompt user for conflict resolution strategy.
|
|
23
|
-
*/
|
|
24
|
-
export declare function promptConflictStrategy(conflictInfos: ConflictInfo[]): Promise<ConflictStrategy | null>;
|
|
25
16
|
/**
|
|
26
17
|
* Generate the shim script content for an agent.
|
|
27
18
|
*
|
|
@@ -57,8 +48,10 @@ export declare function promptConflictStrategy(conflictInfos: ConflictInfo[]): P
|
|
|
57
48
|
* and capability flag `memoryImports` → `rulesImports`.
|
|
58
49
|
* v8 — versions moved from ~/.agents-system/versions to ~/.agents/versions
|
|
59
50
|
* (two-repo split: system = shipped defaults, user = operational state).
|
|
51
|
+
* v9 — claude shim exports CLAUDE_CODE_OAUTH_TOKEN from per-version
|
|
52
|
+
* .oauth_token file on Linux (keychain-less sandbox fallback).
|
|
60
53
|
*/
|
|
61
|
-
export declare const SHIM_SCHEMA_VERSION =
|
|
54
|
+
export declare const SHIM_SCHEMA_VERSION = 10;
|
|
62
55
|
/**
|
|
63
56
|
* Generate the full bash shim script for the given agent. The returned string
|
|
64
57
|
* is written to ~/.agents/shims/{cliCommand} and made executable.
|
|
@@ -128,14 +121,6 @@ export declare function removeVersionedAlias(agent: AgentId, version: string): b
|
|
|
128
121
|
* Check if a versioned alias exists.
|
|
129
122
|
*/
|
|
130
123
|
export declare function versionedAliasExists(agent: AgentId, version: string): boolean;
|
|
131
|
-
/**
|
|
132
|
-
* Detect conflicts that would occur when switching config symlink for an agent/version.
|
|
133
|
-
* This allows collecting conflicts upfront before prompting for a strategy.
|
|
134
|
-
*
|
|
135
|
-
* Returns null if no migration is needed (already symlink or doesn't exist),
|
|
136
|
-
* or ConflictInfo with the list of conflicting files.
|
|
137
|
-
*/
|
|
138
|
-
export declare function detectMigrationConflicts(agent: AgentId, version: string): ConflictInfo | null;
|
|
139
124
|
/**
|
|
140
125
|
* Switch the agent's config symlink to point to a specific version.
|
|
141
126
|
* e.g., ~/.claude -> ~/.agents/versions/claude/2.0.65/home/.claude/
|
|
@@ -185,14 +170,6 @@ export declare function switchHomeFileSymlinks(agent: AgentId, version: string):
|
|
|
185
170
|
* - Symlink points elsewhere: replace it.
|
|
186
171
|
*/
|
|
187
172
|
export declare function ensureClaudeInsideSymlink(version: string): void;
|
|
188
|
-
/**
|
|
189
|
-
* Apply `ensureClaudeInsideSymlink` to every installed Claude version.
|
|
190
|
-
* Safe to call repeatedly; per-version calls are idempotent.
|
|
191
|
-
*/
|
|
192
|
-
export declare function ensureAllClaudeInsideSymlinks(): {
|
|
193
|
-
migrated: string[];
|
|
194
|
-
errors: string[];
|
|
195
|
-
};
|
|
196
173
|
/**
|
|
197
174
|
* Get the current config symlink target version, if any.
|
|
198
175
|
*/
|
|
@@ -201,17 +178,6 @@ export declare function getConfigSymlinkVersion(agent: AgentId): string | null;
|
|
|
201
178
|
* Check if shim exists for an agent.
|
|
202
179
|
*/
|
|
203
180
|
export declare function shimExists(agent: AgentId): boolean;
|
|
204
|
-
/**
|
|
205
|
-
* Read the schema version embedded in an existing on-disk shim. Returns
|
|
206
|
-
* `null` if the shim doesn't exist or has no version marker (pre-v2 shim).
|
|
207
|
-
*/
|
|
208
|
-
export declare function readShimSchemaVersion(agent: AgentId): number | null;
|
|
209
|
-
/**
|
|
210
|
-
* True if the on-disk shim's schema version matches `SHIM_SCHEMA_VERSION`.
|
|
211
|
-
* False means either the shim is missing, is pre-v2 (no marker), or is an
|
|
212
|
-
* older version that needs regeneration.
|
|
213
|
-
*/
|
|
214
|
-
export declare function isShimCurrent(agent: AgentId): boolean;
|
|
215
181
|
/**
|
|
216
182
|
* Regenerate the shim if it's missing or outdated. Returns a status describing
|
|
217
183
|
* what happened — callers can surface a one-line notice to the user ("Updated
|
|
@@ -276,10 +242,6 @@ export declare function addShimsToPath(overrides?: {
|
|
|
276
242
|
error?: string;
|
|
277
243
|
};
|
|
278
244
|
export declare function listAgentsWithInstalledVersions(): AgentId[];
|
|
279
|
-
/**
|
|
280
|
-
* Create shims for all installed agents.
|
|
281
|
-
*/
|
|
282
|
-
export declare function ensureAllShims(): void;
|
|
283
245
|
/**
|
|
284
246
|
* Resource diff between two versions. Each field lists resources present in
|
|
285
247
|
* the current version but missing from the target.
|
|
@@ -295,17 +257,7 @@ export interface ResourceDiff {
|
|
|
295
257
|
}[];
|
|
296
258
|
mcp: string[];
|
|
297
259
|
}
|
|
298
|
-
/**
|
|
299
|
-
* Compare resources between two versions.
|
|
300
|
-
* Returns resources that exist in currentVersion but not in targetVersion.
|
|
301
|
-
*/
|
|
302
|
-
export declare function compareVersionResources(agent: AgentId, currentVersion: string, targetVersion: string): ResourceDiff;
|
|
303
260
|
/**
|
|
304
261
|
* Check if a ResourceDiff has any differences.
|
|
305
262
|
*/
|
|
306
263
|
export declare function hasResourceDiff(diff: ResourceDiff): boolean;
|
|
307
|
-
/**
|
|
308
|
-
* Copy resources from one version to another.
|
|
309
|
-
* Only copies resources listed in the diff (i.e., ones missing in target).
|
|
310
|
-
*/
|
|
311
|
-
export declare function copyResourcesToVersion(agent: AgentId, fromVersion: string, toVersion: string, diff: ResourceDiff): void;
|
package/dist/lib/shims.js
CHANGED
|
@@ -44,7 +44,7 @@ function shouldIgnore(name) {
|
|
|
44
44
|
* Detect conflicting files between source and destination directories.
|
|
45
45
|
* Returns list of filenames that exist in both locations (excluding symlinks in dest).
|
|
46
46
|
*/
|
|
47
|
-
|
|
47
|
+
function detectConflicts(src, dest, prefix = '') {
|
|
48
48
|
const conflicts = [];
|
|
49
49
|
if (!fs.existsSync(src) || !fs.existsSync(dest)) {
|
|
50
50
|
return conflicts;
|
|
@@ -93,7 +93,7 @@ export function detectConflicts(src, dest, prefix = '') {
|
|
|
93
93
|
/**
|
|
94
94
|
* Prompt user for conflict resolution strategy.
|
|
95
95
|
*/
|
|
96
|
-
|
|
96
|
+
async function promptConflictStrategy(conflictInfos) {
|
|
97
97
|
const totalConflicts = conflictInfos.reduce((sum, info) => sum + info.conflicts.length, 0);
|
|
98
98
|
if (totalConflicts === 0) {
|
|
99
99
|
return null; // No conflicts, no prompt needed
|
|
@@ -171,8 +171,10 @@ export async function promptConflictStrategy(conflictInfos) {
|
|
|
171
171
|
* and capability flag `memoryImports` → `rulesImports`.
|
|
172
172
|
* v8 — versions moved from ~/.agents-system/versions to ~/.agents/versions
|
|
173
173
|
* (two-repo split: system = shipped defaults, user = operational state).
|
|
174
|
+
* v9 — claude shim exports CLAUDE_CODE_OAUTH_TOKEN from per-version
|
|
175
|
+
* .oauth_token file on Linux (keychain-less sandbox fallback).
|
|
174
176
|
*/
|
|
175
|
-
export const SHIM_SCHEMA_VERSION =
|
|
177
|
+
export const SHIM_SCHEMA_VERSION = 10;
|
|
176
178
|
/** Internal marker string used to embed the schema version in shim scripts. */
|
|
177
179
|
const SHIM_VERSION_MARKER = 'agents-shim-version:';
|
|
178
180
|
/**
|
|
@@ -189,6 +191,12 @@ export function generateShimScript(agent) {
|
|
|
189
191
|
# selected version's config directory so switching versions also switches the
|
|
190
192
|
# live Claude account.
|
|
191
193
|
export CLAUDE_CONFIG_DIR="$VERSION_DIR/home/${configDirName}"
|
|
194
|
+
# On Linux sandboxes (no keychain), fall back to a per-version token file.
|
|
195
|
+
# The env var always wins if already set; no-op on macOS.
|
|
196
|
+
if [ "\$(uname -s)" = "Linux" ] && [ -z "\${CLAUDE_CODE_OAUTH_TOKEN:-}" ] && [ -f "\$CLAUDE_CONFIG_DIR/.oauth_token" ]; then
|
|
197
|
+
CLAUDE_CODE_OAUTH_TOKEN=\$(cat "\$CLAUDE_CONFIG_DIR/.oauth_token")
|
|
198
|
+
export CLAUDE_CODE_OAUTH_TOKEN
|
|
199
|
+
fi
|
|
192
200
|
`
|
|
193
201
|
: agent === 'codex'
|
|
194
202
|
? `
|
|
@@ -543,7 +551,7 @@ function getVersionConfigPath(agent, version) {
|
|
|
543
551
|
* Returns null if no migration is needed (already symlink or doesn't exist),
|
|
544
552
|
* or ConflictInfo with the list of conflicting files.
|
|
545
553
|
*/
|
|
546
|
-
|
|
554
|
+
function detectMigrationConflicts(agent, version) {
|
|
547
555
|
const configPath = getAgentConfigPath(agent);
|
|
548
556
|
const versionConfigPath = getVersionConfigPath(agent, version);
|
|
549
557
|
try {
|
|
@@ -837,7 +845,7 @@ export function ensureClaudeInsideSymlink(version) {
|
|
|
837
845
|
* Apply `ensureClaudeInsideSymlink` to every installed Claude version.
|
|
838
846
|
* Safe to call repeatedly; per-version calls are idempotent.
|
|
839
847
|
*/
|
|
840
|
-
|
|
848
|
+
function ensureAllClaudeInsideSymlinks() {
|
|
841
849
|
const versionsDir = getVersionsDir();
|
|
842
850
|
const claudeVersionsDir = path.join(versionsDir, 'claude');
|
|
843
851
|
const migrated = [];
|
|
@@ -975,7 +983,7 @@ export function shimExists(agent) {
|
|
|
975
983
|
* Read the schema version embedded in an existing on-disk shim. Returns
|
|
976
984
|
* `null` if the shim doesn't exist or has no version marker (pre-v2 shim).
|
|
977
985
|
*/
|
|
978
|
-
|
|
986
|
+
function readShimSchemaVersion(agent) {
|
|
979
987
|
if (!shimExists(agent))
|
|
980
988
|
return null;
|
|
981
989
|
try {
|
|
@@ -996,7 +1004,7 @@ export function readShimSchemaVersion(agent) {
|
|
|
996
1004
|
* False means either the shim is missing, is pre-v2 (no marker), or is an
|
|
997
1005
|
* older version that needs regeneration.
|
|
998
1006
|
*/
|
|
999
|
-
|
|
1007
|
+
function isShimCurrent(agent) {
|
|
1000
1008
|
const version = readShimSchemaVersion(agent);
|
|
1001
1009
|
return version === SHIM_SCHEMA_VERSION;
|
|
1002
1010
|
}
|
|
@@ -1309,7 +1317,7 @@ export function listAgentsWithInstalledVersions() {
|
|
|
1309
1317
|
/**
|
|
1310
1318
|
* Create shims for all installed agents.
|
|
1311
1319
|
*/
|
|
1312
|
-
|
|
1320
|
+
function ensureAllShims() {
|
|
1313
1321
|
const versionsDir = getVersionsDir();
|
|
1314
1322
|
if (!fs.existsSync(versionsDir)) {
|
|
1315
1323
|
return;
|
|
@@ -1331,7 +1339,7 @@ export function ensureAllShims() {
|
|
|
1331
1339
|
* Compare resources between two versions.
|
|
1332
1340
|
* Returns resources that exist in currentVersion but not in targetVersion.
|
|
1333
1341
|
*/
|
|
1334
|
-
|
|
1342
|
+
function compareVersionResources(agent, currentVersion, targetVersion) {
|
|
1335
1343
|
const agentConfig = AGENTS[agent];
|
|
1336
1344
|
const currentPath = getVersionConfigPath(agent, currentVersion);
|
|
1337
1345
|
const targetPath = getVersionConfigPath(agent, targetVersion);
|
|
@@ -1420,7 +1428,7 @@ export function hasResourceDiff(diff) {
|
|
|
1420
1428
|
* Copy resources from one version to another.
|
|
1421
1429
|
* Only copies resources listed in the diff (i.e., ones missing in target).
|
|
1422
1430
|
*/
|
|
1423
|
-
|
|
1431
|
+
function copyResourcesToVersion(agent, fromVersion, toVersion, diff) {
|
|
1424
1432
|
const agentConfig = AGENTS[agent];
|
|
1425
1433
|
const fromPath = getVersionConfigPath(agent, fromVersion);
|
|
1426
1434
|
const toPath = getVersionConfigPath(agent, toVersion);
|
package/dist/lib/sqlite.js
CHANGED
|
@@ -66,12 +66,18 @@ class Database {
|
|
|
66
66
|
pragma(stmt) {
|
|
67
67
|
this.inner.exec(`PRAGMA ${stmt}`);
|
|
68
68
|
}
|
|
69
|
-
// Wrap fn in BEGIN/COMMIT, ROLLBACK on throw. Manual on both
|
|
70
|
-
// because node:sqlite has no `db.transaction(fn)
|
|
71
|
-
//
|
|
69
|
+
// Wrap fn in BEGIN IMMEDIATE/COMMIT, ROLLBACK on throw. Manual on both
|
|
70
|
+
// runtimes because node:sqlite has no `db.transaction(fn)`.
|
|
71
|
+
//
|
|
72
|
+
// BEGIN IMMEDIATE (not BEGIN DEFERRED) is required for write transactions in
|
|
73
|
+
// WAL mode. BEGIN DEFERRED upgrades the lock lazily on the first write; if
|
|
74
|
+
// another writer already committed since the transaction started, SQLite
|
|
75
|
+
// returns SQLITE_BUSY_SNAPSHOT (a sub-code of SQLITE_BUSY that the busy
|
|
76
|
+
// handler does NOT retry). BEGIN IMMEDIATE claims the write lock upfront so
|
|
77
|
+
// the busy handler fires correctly and respects busy_timeout.
|
|
72
78
|
transaction(fn) {
|
|
73
79
|
return (...args) => {
|
|
74
|
-
this.inner.exec('BEGIN');
|
|
80
|
+
this.inner.exec('BEGIN IMMEDIATE');
|
|
75
81
|
try {
|
|
76
82
|
const result = fn(...args);
|
|
77
83
|
this.inner.exec('COMMIT');
|
package/dist/lib/state.d.ts
CHANGED
|
@@ -89,6 +89,8 @@ export declare function getUserRulesDir(): string;
|
|
|
89
89
|
export declare function getUserMcpDir(): string;
|
|
90
90
|
export declare function getUserPermissionsDir(): string;
|
|
91
91
|
export declare function getUserSubagentsDir(): string;
|
|
92
|
+
export declare function getSystemWorkflowsDir(): string;
|
|
93
|
+
export declare function getUserWorkflowsDir(): string;
|
|
92
94
|
export declare function getUserSecretsDir(): string;
|
|
93
95
|
export declare function getUserPromptcutsPath(): string;
|
|
94
96
|
/** Bucket root for durable runtime data (~/.agents/.history/). */
|
|
@@ -163,6 +165,7 @@ export declare function getTrashHooksDir(): string;
|
|
|
163
165
|
export declare function getTrashPluginsDir(): string;
|
|
164
166
|
/** Path to soft-deleted subagents (~/.agents/trash/subagents/). */
|
|
165
167
|
export declare function getTrashSubagentsDir(): string;
|
|
168
|
+
export declare function getTrashWorkflowsDir(): string;
|
|
166
169
|
/**
|
|
167
170
|
* Path to a single user-level extra DotAgent repo clone (~/.agents-<alias>/).
|
|
168
171
|
*
|
|
@@ -194,8 +197,18 @@ export declare function writeMeta(meta: Meta): void;
|
|
|
194
197
|
export declare function updateMeta(updates: Partial<Meta>): Meta;
|
|
195
198
|
/** Derive a filesystem-safe local clone path for a package source URL. */
|
|
196
199
|
export declare function getPackageLocalPath(source: string): string;
|
|
197
|
-
import type { AgentId, ResourceType, VersionResources } from './types.js';
|
|
198
|
-
|
|
200
|
+
import type { AgentId, ResourceType, VersionResources, ResourcePattern } from './types.js';
|
|
201
|
+
/**
|
|
202
|
+
* @deprecated No-op. Use ensureVersionResourcePatterns instead.
|
|
203
|
+
* Kept for backward compat with command files that still call it.
|
|
204
|
+
*/
|
|
205
|
+
export declare function recordVersionResources(_agent: AgentId, _version: string, _resourceType: ResourceType, _resources: string[]): void;
|
|
206
|
+
/**
|
|
207
|
+
* Write default resource selection patterns for an agent@version.
|
|
208
|
+
* Only writes each field when it is not already set, preserving user customization.
|
|
209
|
+
* Pass all resource types you want to initialize in one call to batch the write.
|
|
210
|
+
*/
|
|
211
|
+
export declare function ensureVersionResourcePatterns(agent: AgentId, version: string, updates: Partial<Record<Exclude<keyof VersionResources, 'rulesPreset'>, ResourcePattern[]>>): void;
|
|
199
212
|
export declare function getVersionResources(agent: AgentId, version: string): VersionResources | null;
|
|
200
213
|
export declare function clearVersionResources(agent: AgentId, version: string): void;
|
|
201
214
|
/** Active rules preset for an agent@version. Defaults to "default" when unset. */
|
package/dist/lib/state.js
CHANGED
|
@@ -23,7 +23,7 @@ import * as path from 'path';
|
|
|
23
23
|
import * as os from 'os';
|
|
24
24
|
import * as yaml from 'yaml';
|
|
25
25
|
import { SEEDED_REGISTRIES } from './types.js';
|
|
26
|
-
const HOME = os.homedir();
|
|
26
|
+
const HOME = process.env.HOME ?? os.homedir();
|
|
27
27
|
// ─── Root directories ─────────────────────────────────────────────────────────
|
|
28
28
|
/** System repo — npm-shipped, read-only from user commands. */
|
|
29
29
|
const SYSTEM_AGENTS_DIR = path.join(HOME, '.agents-system');
|
|
@@ -41,6 +41,7 @@ const SYSTEM_RULES_DIR = path.join(SYSTEM_AGENTS_DIR, 'rules');
|
|
|
41
41
|
const SYSTEM_MCP_DIR = path.join(SYSTEM_AGENTS_DIR, 'mcp');
|
|
42
42
|
const SYSTEM_PERMISSIONS_DIR = path.join(SYSTEM_AGENTS_DIR, 'permissions');
|
|
43
43
|
const SYSTEM_SUBAGENTS_DIR = path.join(SYSTEM_AGENTS_DIR, 'subagents');
|
|
44
|
+
const SYSTEM_WORKFLOWS_DIR = path.join(SYSTEM_AGENTS_DIR, 'workflows');
|
|
44
45
|
const SYSTEM_PROMPTCUTS_FILE = path.join(SYSTEM_AGENTS_DIR, 'hooks', 'promptcuts.yaml');
|
|
45
46
|
const SYSTEM_MCP_CONFIG_FILE = path.join(SYSTEM_AGENTS_DIR, 'mcp.json');
|
|
46
47
|
const SYSTEM_INSTRUCTIONS_FILE = path.join(SYSTEM_AGENTS_DIR, 'instructions.md');
|
|
@@ -88,6 +89,7 @@ const USER_RULES_DIR = path.join(USER_AGENTS_DIR, 'rules');
|
|
|
88
89
|
const USER_MCP_DIR = path.join(USER_AGENTS_DIR, 'mcp');
|
|
89
90
|
const USER_PERMISSIONS_DIR = path.join(USER_AGENTS_DIR, 'permissions');
|
|
90
91
|
const USER_SUBAGENTS_DIR = path.join(USER_AGENTS_DIR, 'subagents');
|
|
92
|
+
const USER_WORKFLOWS_DIR = path.join(USER_AGENTS_DIR, 'workflows');
|
|
91
93
|
const USER_SECRETS_DIR = path.join(USER_AGENTS_DIR, 'secrets');
|
|
92
94
|
const USER_PROMPTCUTS_FILE = path.join(USER_AGENTS_DIR, 'hooks', 'promptcuts.yaml');
|
|
93
95
|
const META_HEADER = `# agents-cli metadata
|
|
@@ -238,6 +240,8 @@ export function getUserRulesDir() { return USER_RULES_DIR; }
|
|
|
238
240
|
export function getUserMcpDir() { return USER_MCP_DIR; }
|
|
239
241
|
export function getUserPermissionsDir() { return USER_PERMISSIONS_DIR; }
|
|
240
242
|
export function getUserSubagentsDir() { return USER_SUBAGENTS_DIR; }
|
|
243
|
+
export function getSystemWorkflowsDir() { return SYSTEM_WORKFLOWS_DIR; }
|
|
244
|
+
export function getUserWorkflowsDir() { return USER_WORKFLOWS_DIR; }
|
|
241
245
|
export function getUserSecretsDir() { return USER_SECRETS_DIR; }
|
|
242
246
|
export function getUserPromptcutsPath() { return USER_PROMPTCUTS_FILE; }
|
|
243
247
|
// ─── User operational path getters ────────────────────────────────────────────
|
|
@@ -316,6 +320,7 @@ export function getTrashHooksDir() { return path.join(TRASH_DIR, 'hooks'); }
|
|
|
316
320
|
export function getTrashPluginsDir() { return path.join(TRASH_DIR, 'plugins'); }
|
|
317
321
|
/** Path to soft-deleted subagents (~/.agents/trash/subagents/). */
|
|
318
322
|
export function getTrashSubagentsDir() { return path.join(TRASH_DIR, 'subagents'); }
|
|
323
|
+
export function getTrashWorkflowsDir() { return path.join(TRASH_DIR, 'workflows'); }
|
|
319
324
|
/**
|
|
320
325
|
* Path to a single user-level extra DotAgent repo clone (~/.agents-<alias>/).
|
|
321
326
|
*
|
|
@@ -552,9 +557,19 @@ export function getPackageLocalPath(source) {
|
|
|
552
557
|
.replace(/\//g, '-');
|
|
553
558
|
return path.join(PACKAGES_DIR, sanitized);
|
|
554
559
|
}
|
|
555
|
-
|
|
556
|
-
|
|
557
|
-
|
|
560
|
+
/**
|
|
561
|
+
* @deprecated No-op. Use ensureVersionResourcePatterns instead.
|
|
562
|
+
* Kept for backward compat with command files that still call it.
|
|
563
|
+
*/
|
|
564
|
+
export function recordVersionResources(_agent, _version, _resourceType, _resources) {
|
|
565
|
+
// intentional no-op — tracking moved to pattern-based ensureVersionResourcePatterns
|
|
566
|
+
}
|
|
567
|
+
/**
|
|
568
|
+
* Write default resource selection patterns for an agent@version.
|
|
569
|
+
* Only writes each field when it is not already set, preserving user customization.
|
|
570
|
+
* Pass all resource types you want to initialize in one call to batch the write.
|
|
571
|
+
*/
|
|
572
|
+
export function ensureVersionResourcePatterns(agent, version, updates) {
|
|
558
573
|
const meta = readMeta();
|
|
559
574
|
if (!meta.versions)
|
|
560
575
|
meta.versions = {};
|
|
@@ -562,10 +577,16 @@ export function recordVersionResources(agent, version, resourceType, resources)
|
|
|
562
577
|
meta.versions[agent] = {};
|
|
563
578
|
if (!meta.versions[agent][version])
|
|
564
579
|
meta.versions[agent][version] = {};
|
|
565
|
-
const
|
|
566
|
-
|
|
567
|
-
|
|
568
|
-
|
|
580
|
+
const vr = meta.versions[agent][version];
|
|
581
|
+
let changed = false;
|
|
582
|
+
for (const [type, patterns] of Object.entries(updates)) {
|
|
583
|
+
if (!vr[type] || vr[type].length === 0) {
|
|
584
|
+
vr[type] = patterns;
|
|
585
|
+
changed = true;
|
|
586
|
+
}
|
|
587
|
+
}
|
|
588
|
+
if (changed)
|
|
589
|
+
writeMeta(meta);
|
|
569
590
|
}
|
|
570
591
|
export function getVersionResources(agent, version) {
|
|
571
592
|
const meta = readMeta();
|
package/dist/lib/types.d.ts
CHANGED
|
@@ -288,30 +288,49 @@ export interface ResolvedPackage {
|
|
|
288
288
|
skillEntry?: SkillEntry;
|
|
289
289
|
}
|
|
290
290
|
/** Categories of resources that can be synced into an agent version home. */
|
|
291
|
-
export type ResourceType = 'commands' | 'skills' | 'hooks' | 'memory' | 'mcp' | 'permissions' | 'subagents' | 'plugins';
|
|
292
|
-
/**
|
|
291
|
+
export type ResourceType = 'commands' | 'skills' | 'hooks' | 'memory' | 'mcp' | 'permissions' | 'subagents' | 'plugins' | 'workflows';
|
|
292
|
+
/**
|
|
293
|
+
* A resource selection pattern stored in agents.yaml versions:
|
|
294
|
+
* "system:*" — all resources from ~/.agents-system/
|
|
295
|
+
* "user:*" — all resources from ~/.agents/
|
|
296
|
+
* "rush:*" — all resources from ~/.agents-rush/ (extra repo alias)
|
|
297
|
+
* "project:*" — all resources from .agents/ in the project root
|
|
298
|
+
* "user:foo" — specifically "foo" from ~/.agents/
|
|
299
|
+
* "!user:temp" — exclude "temp" from the user repo
|
|
300
|
+
*/
|
|
301
|
+
export type ResourcePattern = string;
|
|
302
|
+
/** Sync specification for a specific agent@version, keyed by resource type. */
|
|
293
303
|
export interface VersionResources {
|
|
294
|
-
commands?: string[];
|
|
295
|
-
skills?: string[];
|
|
296
|
-
hooks?: string[];
|
|
297
|
-
memory?: string[];
|
|
298
|
-
mcp?: string[];
|
|
299
|
-
permissions?: string[];
|
|
300
|
-
subagents?: string[];
|
|
301
|
-
plugins?: string[];
|
|
302
304
|
/**
|
|
303
|
-
* Active rule preset
|
|
304
|
-
* `rules.yaml` files and emits this preset's subrules as the agent's
|
|
305
|
-
* single instruction file. Absent/null means the literal "default" preset.
|
|
305
|
+
* Active rule preset. Absent/null means "default".
|
|
306
306
|
*/
|
|
307
307
|
rulesPreset?: string;
|
|
308
|
+
skills?: ResourcePattern[];
|
|
309
|
+
commands?: ResourcePattern[];
|
|
310
|
+
hooks?: ResourcePattern[];
|
|
311
|
+
subagents?: ResourcePattern[];
|
|
312
|
+
plugins?: ResourcePattern[];
|
|
313
|
+
workflows?: ResourcePattern[];
|
|
314
|
+
permissions?: ResourcePattern[];
|
|
315
|
+
mcp?: ResourcePattern[];
|
|
316
|
+
}
|
|
317
|
+
/** A userConfig field declared in a plugin manifest. */
|
|
318
|
+
export interface PluginUserConfigField {
|
|
319
|
+
key: string;
|
|
320
|
+
description: string;
|
|
321
|
+
required?: boolean;
|
|
322
|
+
default?: string;
|
|
308
323
|
}
|
|
309
|
-
/** Manifest file (plugin.
|
|
324
|
+
/** Manifest file (plugin.json) at the root of a plugin bundle. */
|
|
310
325
|
export interface PluginManifest {
|
|
311
326
|
name: string;
|
|
312
327
|
description: string;
|
|
313
328
|
version: string;
|
|
314
329
|
agents?: AgentId[];
|
|
330
|
+
/** Interactive config fields prompted at install time. Values stored in .user-config.json. */
|
|
331
|
+
userConfig?: PluginUserConfigField[];
|
|
332
|
+
/** Other plugin names this plugin depends on. Missing deps produce a warning. */
|
|
333
|
+
dependencies?: string[];
|
|
315
334
|
}
|
|
316
335
|
/** A plugin found on disk with its parsed manifest and resource inventory. */
|
|
317
336
|
export interface DiscoveredPlugin {
|
|
@@ -321,6 +340,16 @@ export interface DiscoveredPlugin {
|
|
|
321
340
|
skills: string[];
|
|
322
341
|
hooks: string[];
|
|
323
342
|
scripts: string[];
|
|
343
|
+
/** Slash-command .md files in the plugin's commands/ directory (names without extension). */
|
|
344
|
+
commands: string[];
|
|
345
|
+
/** Subagent .md files in the plugin's agents/ directory (names without extension). */
|
|
346
|
+
agentDefs: string[];
|
|
347
|
+
/** Executable files in the plugin's bin/ directory. */
|
|
348
|
+
bin: string[];
|
|
349
|
+
/** Whether the plugin root contains a .mcp.json file. */
|
|
350
|
+
hasMcp: boolean;
|
|
351
|
+
/** Whether the plugin root contains a settings.json with non-permission keys to merge. */
|
|
352
|
+
hasSettings: boolean;
|
|
324
353
|
}
|
|
325
354
|
/** Frontmatter fields parsed from a subagent's agent.md file. */
|
|
326
355
|
export interface SubagentFrontmatter {
|
package/dist/lib/versions.d.ts
CHANGED
|
@@ -15,6 +15,7 @@ export interface ResourceSelection {
|
|
|
15
15
|
permissions?: string[] | 'all';
|
|
16
16
|
subagents?: string[] | 'all';
|
|
17
17
|
plugins?: string[] | 'all';
|
|
18
|
+
workflows?: string[] | 'all';
|
|
18
19
|
}
|
|
19
20
|
/**
|
|
20
21
|
* Available resources in ~/.agents/ for syncing.
|
|
@@ -33,6 +34,7 @@ export interface AvailableResources {
|
|
|
33
34
|
permissions: string[];
|
|
34
35
|
subagents: string[];
|
|
35
36
|
plugins: string[];
|
|
37
|
+
workflows: string[];
|
|
36
38
|
promptcuts: boolean;
|
|
37
39
|
}
|
|
38
40
|
/**
|
|
@@ -215,6 +217,7 @@ export interface SyncResult {
|
|
|
215
217
|
mcp: string[];
|
|
216
218
|
subagents: string[];
|
|
217
219
|
plugins: string[];
|
|
220
|
+
workflows: string[];
|
|
218
221
|
}
|
|
219
222
|
/** Diff between central ~/.agents/ resources and what is synced to a version home. */
|
|
220
223
|
export interface ResourceDiff {
|