@phnx-labs/agents-cli 1.22.9 → 1.22.11
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 +37 -4
- package/dist/bin/agents +0 -0
- package/dist/commands/beta.js +21 -9
- package/dist/commands/browser.js +2 -2
- package/dist/commands/events.d.ts +1 -1
- package/dist/commands/events.js +1 -1
- package/dist/commands/projects.d.ts +1 -2
- package/dist/commands/projects.js +39 -47
- package/dist/commands/secrets.js +38 -39
- package/dist/commands/ssh.js +4 -5
- package/dist/commands/workflows.js +1 -1
- package/dist/index.js +1 -1
- package/dist/lib/beta.d.ts +1 -1
- package/dist/lib/beta.js +1 -1
- package/dist/lib/event-stream.d.ts +1 -1
- package/dist/lib/event-stream.js +1 -1
- package/dist/lib/events.d.ts +1 -1
- package/dist/lib/events.js +3 -3
- package/dist/lib/feed-broadcast.d.ts +19 -5
- package/dist/lib/feed-broadcast.js +41 -8
- package/dist/lib/menubar/MenubarHelper.app/Contents/CodeResources +0 -0
- package/dist/lib/menubar/MenubarHelper.app/Contents/MacOS/MenubarHelper +0 -0
- package/dist/lib/migrate.js +61 -0
- package/dist/lib/plugins.d.ts +14 -5
- package/dist/lib/plugins.js +29 -5
- package/dist/lib/project-probe.d.ts +1 -1
- package/dist/lib/project-probe.js +1 -1
- package/dist/lib/projects.d.ts +1 -1
- package/dist/lib/resources/types.d.ts +2 -1
- package/dist/lib/resources/workflows.d.ts +1 -1
- package/dist/lib/resources/workflows.js +22 -20
- package/dist/lib/secrets/Agents CLI.app/Contents/CodeResources +0 -0
- package/dist/lib/secrets/Agents CLI.app/Contents/MacOS/Agents CLI +0 -0
- package/dist/lib/secrets/audit.js +1 -1
- package/dist/lib/secrets/bundles.d.ts +9 -0
- package/dist/lib/secrets/bundles.js +9 -23
- package/dist/lib/secrets/headless.d.ts +3 -15
- package/dist/lib/secrets/headless.js +5 -33
- package/dist/lib/secrets/index.d.ts +8 -0
- package/dist/lib/secrets/index.js +16 -36
- package/dist/lib/share/config.js +5 -7
- package/dist/lib/state.d.ts +1 -1
- package/dist/lib/state.js +1 -1
- package/dist/lib/types.d.ts +7 -1
- package/dist/lib/workflows.d.ts +19 -4
- package/dist/lib/workflows.js +81 -7
- package/package.json +1 -1
package/CHANGELOG.md
CHANGED
|
@@ -1,5 +1,40 @@
|
|
|
1
1
|
# Changelog
|
|
2
2
|
|
|
3
|
+
## 1.22.11
|
|
4
|
+
|
|
5
|
+
- **`--blocked` iMessage notifications are now phone-actionable.** The forwarded message dropped the block's `--option`s, `--default`, and timeout and instead showed `agents focus <id>` — a CLI command that is useless on a phone. It now shows the choices (`Options: publish / wait`) and the safe-default fallback (`Default in 15 min: wait`) and omits the `agents focus` line, so a `--blocked` post that carries a `--default` self-resolves when the owner can't reply. Source: `apps/cli/src/lib/feed-broadcast.ts`.
|
|
6
|
+
|
|
7
|
+
- Move operational event logs from the git-backed `~/.agents/` root into `~/.agents/.history/events/`, including existing numbered gzip archives.
|
|
8
|
+
|
|
9
|
+
- **`agents projects` is out of beta — no `agents beta enable projects` needed.**
|
|
10
|
+
The command tree (list / add / import / status / link / …) is always registered
|
|
11
|
+
now; `projects` is dropped from the beta registry (`ALL_BETA_FEATURES`,
|
|
12
|
+
`BetaFeatureName`) and the `preAction` beta gate is removed. Any lingering
|
|
13
|
+
`beta.enabled: [projects]` entry is harmlessly ignored, and `agents beta
|
|
14
|
+
enable/disable projects` prints a friendly "graduated out of beta" note and
|
|
15
|
+
no-ops instead of erroring (so old scripts survive). Source:
|
|
16
|
+
`apps/cli/src/lib/beta.ts`, `apps/cli/src/lib/types.ts`,
|
|
17
|
+
`apps/cli/src/commands/beta.ts`, `apps/cli/src/commands/projects.ts`.
|
|
18
|
+
|
|
19
|
+
- **`agents projects status` shows every project across the whole fleet by default;
|
|
20
|
+
scope it with `--device`/`--devices`.** The old `--fleet` flag is gone — status
|
|
21
|
+
now dials every registered device's workspace (presence, branch, drift) in one
|
|
22
|
+
parallel SSH round without being asked. `--device <name...>` (repeatable) or
|
|
23
|
+
`--devices a,b,c` narrows the fan-out to a subset; with no filter the whole fleet
|
|
24
|
+
is dialled. Reuses the shared `--host`/`--device` target resolution. Source:
|
|
25
|
+
`apps/cli/src/commands/projects.ts`.
|
|
26
|
+
|
|
27
|
+
- **`scripts/release.sh` home-base hop: pass a single remote argv to `agents ssh`.** Multi-arg forms (`bash -lc '…'`) are joined without re-quoting by `wrapRemoteCommand`, so the remote `cd` never ran and publish failed with `fatal: not a git repository`. One shell string keeps the command intact. Source: `apps/cli/scripts/release.sh`.
|
|
28
|
+
|
|
29
|
+
## 1.22.10
|
|
30
|
+
|
|
31
|
+
- **Plugins package workflows (Phase 5 packaging slice).** A plugin’s `workflows/<name>/WORKFLOW.md` is discovered and resolved by `agents run <name>` with precedence project > user > plugin > extra > system — no separate install into `~/.agents/workflows/` required. Plugin inventory / resource groups list `workflows`. Source: `apps/cli/src/lib/workflows.ts`, `apps/cli/src/lib/plugins.ts`, `apps/cli/src/lib/resources/workflows.ts`.
|
|
32
|
+
|
|
33
|
+
- **`scripts/release.sh` routes the home-base publish hop via `agents ssh`.** Plain `ssh mac-mini` fails host-key checks on headless Linux workers; `agents ssh` uses the devices registry and brokered credentials. Falls back to plain ssh only when `agents` is not on PATH. Source: `apps/cli/scripts/release.sh`.
|
|
34
|
+
|
|
35
|
+
- **Touch ID is now raised in exactly one place — `agents secrets unlock`.** `agents secrets list`, `agents run <agent>`, `secrets get`/`export`/`view`, and every background read resolve from the secrets broker / durable session / no-ACL layer and never raise a biometric sheet; a locked keychain bundle fails with an actionable "run `agents secrets unlock <bundle>`" hint instead of prompting. The `AGENTS_SECRETS_NO_PROMPT` environment override and the "a human at a TTY, so prompting is fine" heuristic are deleted — the prompt decision is structural, not an ambient env var. The macOS keychain `list`/`list-synced` enumeration queries now pass `kSecUseAuthenticationUISkip` (enumeration itself was evaluating the biometry ACL, so `agents secrets list` prompted and silently dropped keychain bundles when the sheet was cancelled), and the one-time hash-rekey + metadata-ACL heal run only inside the single `unlock` sheet so nothing on the run/list path can storm. Source: `apps/cli/src/lib/secrets/keychain-helper.swift`, `apps/cli/src/lib/secrets/index.ts`, `apps/cli/src/lib/secrets/bundles.ts`, `apps/cli/src/lib/secrets/headless.ts`, `apps/cli/src/commands/secrets.ts`.
|
|
36
|
+
- **The Factory VS Code extension (`swarm-ext`) no longer decrypts secrets or shells raw `ssh`.** Device health, reachability, and sync route every remote command through `agents ssh <host>` (broker-owned credentials, no prompt); the extension's own secret-resolution path (`resolveSecret`/`discoverSecretsReadCmd`/`extractCredentials`) is removed, so rendering the devices list never raises Touch ID. Source: `apps/factory/src/vscode/deviceHealth.vscode.ts`, `apps/factory/src/vscode/settings.vscode.ts`, `apps/factory/src/vscode/extension.ts`.
|
|
37
|
+
|
|
3
38
|
## 1.22.9
|
|
4
39
|
|
|
5
40
|
- **`agents ssh auto` and `agents teams add --device auto` no longer reject with "Unknown device 'auto'" (RUSH-2185).** The `auto` affinity sentinel was a `run`-only preprocessing step (`applyDeviceAutoToOptions` in `smart-launch.ts`, wired only from `agents run`'s exec path) — every other `--host`/`--device` caller went straight to the shared resolver, which had no idea what `auto` meant and reported it as an unregistered device. `matchHost` (the one core every `--host`/`--device` caller shares) now resolves `auto` directly via the same `resolveDeviceAffinity` engine `run` uses, so `agents ssh`, `agents teams add`, and anything else routed through `matchHost`/`resolveHost` (including the generic `--host`/`--device` passthrough) pick a device the same way. `agents teams add --device auto` landing on the local machine now just runs the teammate locally, matching `run`'s "null pick = local" outcome; `agents ssh auto` refuses a local pick with a clear message instead of self-SSHing, since `agents ssh` exists to dial OUT to a remote box. Source: `apps/cli/src/lib/hosts/registry.ts`, `apps/cli/src/lib/devices/resolve-target.ts`, `apps/cli/src/commands/ssh.ts`, `apps/cli/src/commands/teams.ts`, `apps/cli/docs/00-concepts.md`, `apps/cli/docs/hosts.md`, `apps/cli/docs/teams.md`.
|
|
@@ -2908,10 +2943,8 @@
|
|
|
2908
2943
|
`agentOnly` guard; and `isHeadlessSecretsContext` recognized the `headless` and
|
|
2909
2944
|
`teams` runtimes but not `terminal`, which is what an interactive run sets. Agent
|
|
2910
2945
|
launches now resolve broker-only and a locked bundle fails fast naming
|
|
2911
|
-
`agents secrets unlock <bundle
|
|
2912
|
-
|
|
2913
|
-
prompts — it carries no `AGENTS_RUNTIME`, so the guard does not apply. Run beneath
|
|
2914
|
-
an agent it refuses, because there the agent is the caller. This narrows the
|
|
2946
|
+
`agents secrets unlock <bundle>`. Direct read commands use the same broker-only
|
|
2947
|
+
path even from a plain shell; only an explicit unlock may authenticate. This narrows the
|
|
2915
2948
|
agent-triggered approval added in RUSH-2032, which is unreleased.
|
|
2916
2949
|
|
|
2917
2950
|
- **`release.sh` now borrows the npm token from a primary device when the local box
|
package/dist/bin/agents
CHANGED
|
Binary file
|
package/dist/commands/beta.js
CHANGED
|
@@ -2,17 +2,23 @@ import chalk from 'chalk';
|
|
|
2
2
|
import { ALL_BETA_FEATURES, getBetaConfigLocation, getEnabledBetaFeatures, setBetaEnabled, } from '../lib/beta.js';
|
|
3
3
|
const BETA_DESCRIPTIONS = {
|
|
4
4
|
factory: 'Cloud-based agent dispatch via Rush Factory',
|
|
5
|
-
projects: 'Named multi-repo projects with a progress rollup (agents projects)',
|
|
6
5
|
};
|
|
6
|
+
// Features that used to be beta and are now always-on. `beta enable/disable` on
|
|
7
|
+
// one of these is a friendly no-op, not an "Unknown beta feature" error — so
|
|
8
|
+
// muscle memory and old bootstrap scripts survive the graduation.
|
|
9
|
+
const GRADUATED_FEATURES = new Set(['projects']);
|
|
7
10
|
function parseFeatures(values) {
|
|
8
11
|
const valid = new Set(ALL_BETA_FEATURES);
|
|
9
|
-
const
|
|
10
|
-
|
|
11
|
-
|
|
12
|
+
for (const g of values.filter((v) => GRADUATED_FEATURES.has(v))) {
|
|
13
|
+
console.error(chalk.gray(`'${g}' has graduated out of beta — it is on by default; no action needed.`));
|
|
14
|
+
}
|
|
15
|
+
const unknown = values.filter((v) => !valid.has(v) && !GRADUATED_FEATURES.has(v));
|
|
16
|
+
if (unknown.length > 0) {
|
|
17
|
+
console.error(chalk.red(`Unknown beta feature: ${unknown.join(', ')}`));
|
|
12
18
|
console.error(chalk.gray(`Valid features: ${ALL_BETA_FEATURES.join(', ')}`));
|
|
13
19
|
process.exit(1);
|
|
14
20
|
}
|
|
15
|
-
return values;
|
|
21
|
+
return values.filter((v) => valid.has(v));
|
|
16
22
|
}
|
|
17
23
|
export function registerBetaCommands(program) {
|
|
18
24
|
const beta = program
|
|
@@ -43,16 +49,22 @@ Examples:
|
|
|
43
49
|
.command('enable <features...>')
|
|
44
50
|
.description('Enable one or more beta features.')
|
|
45
51
|
.action((features) => {
|
|
46
|
-
const
|
|
47
|
-
|
|
52
|
+
const parsed = parseFeatures(features);
|
|
53
|
+
if (parsed.length === 0)
|
|
54
|
+
return; // only graduated/no-op names
|
|
55
|
+
const result = setBetaEnabled(parsed, true);
|
|
56
|
+
console.log(chalk.green(`Enabled: ${parsed.join(', ')}`));
|
|
48
57
|
console.log(chalk.gray(`Saved to ${result.path}`));
|
|
49
58
|
});
|
|
50
59
|
beta
|
|
51
60
|
.command('disable <features...>')
|
|
52
61
|
.description('Disable one or more beta features.')
|
|
53
62
|
.action((features) => {
|
|
54
|
-
const
|
|
55
|
-
|
|
63
|
+
const parsed = parseFeatures(features);
|
|
64
|
+
if (parsed.length === 0)
|
|
65
|
+
return; // only graduated/no-op names
|
|
66
|
+
const result = setBetaEnabled(parsed, false);
|
|
67
|
+
console.log(chalk.green(`Disabled: ${parsed.join(', ')}`));
|
|
56
68
|
console.log(chalk.gray(`Saved to ${result.path}`));
|
|
57
69
|
});
|
|
58
70
|
}
|
package/dist/commands/browser.js
CHANGED
|
@@ -5,7 +5,7 @@ import { updateMeta } from '../lib/state.js';
|
|
|
5
5
|
import { resolveActor } from '../lib/actor.js';
|
|
6
6
|
import { loginsForProfile, profilesLoggedInto, serviceForUrl, loginsWithAccountsForProfile, accountsForProfile, credKeysForService, AUTH_SIGNATURES, } from '../lib/browser/login-detection.js';
|
|
7
7
|
import { parseSecretRef } from '../lib/browser/secret-ref.js';
|
|
8
|
-
import { readAndResolveBundleEnv,
|
|
8
|
+
import { readAndResolveBundleEnv, bundleExists, readBundle, describeBundle } from '../lib/secrets/bundles.js';
|
|
9
9
|
import { findBrowserPath, getPortOccupant, isLauncherScript } from '../lib/browser/chrome.js';
|
|
10
10
|
import { listProfileCacheDirs, removeProfileCache, listAllProfileSnapshots, } from '../lib/browser/runtime-state.js';
|
|
11
11
|
import { DEFAULT_VIEWPORT } from '../lib/browser/devices.js';
|
|
@@ -1481,7 +1481,7 @@ function registerTaskCommands(browser) {
|
|
|
1481
1481
|
process.exit(1);
|
|
1482
1482
|
}
|
|
1483
1483
|
try {
|
|
1484
|
-
const { env } = readAndResolveBundleEnv(parsed.bundle, { caller: 'browser type', keys: [parsed.key], keyMode: 'storage', agentOnly:
|
|
1484
|
+
const { env } = readAndResolveBundleEnv(parsed.bundle, { caller: 'browser type', keys: [parsed.key], keyMode: 'storage', agentOnly: true });
|
|
1485
1485
|
if (!(parsed.key in env)) {
|
|
1486
1486
|
console.error(`Key "${parsed.key}" not in bundle "${parsed.bundle}".`);
|
|
1487
1487
|
process.exit(1);
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
/**
|
|
2
2
|
* `agents events` — read the unified event stream.
|
|
3
3
|
*
|
|
4
|
-
* One stream over BOTH operational events (`~/.agents/events.jsonl`: every
|
|
4
|
+
* One stream over BOTH operational events (`~/.agents/.history/events/events.jsonl`: every
|
|
5
5
|
* `agents <module> <cmd>` invocation plus typed events like secrets access,
|
|
6
6
|
* version installs) AND agent-semantic events (the per-session activity logs:
|
|
7
7
|
* plans, PRs, worktrees, sub-agents, artifacts). Each is stamped with who ran
|
package/dist/commands/events.js
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
/**
|
|
2
2
|
* `agents events` — read the unified event stream.
|
|
3
3
|
*
|
|
4
|
-
* One stream over BOTH operational events (`~/.agents/events.jsonl`: every
|
|
4
|
+
* One stream over BOTH operational events (`~/.agents/.history/events/events.jsonl`: every
|
|
5
5
|
* `agents <module> <cmd>` invocation plus typed events like secrets access,
|
|
6
6
|
* version installs) AND agent-semantic events (the per-session activity logs:
|
|
7
7
|
* plans, PRs, worktrees, sub-agents, artifacts). Each is stamped with who ran
|
|
@@ -1,8 +1,7 @@
|
|
|
1
1
|
/**
|
|
2
2
|
* `agents projects` — named, multi-repo projects and the progress
|
|
3
3
|
* rollup. Definitions live in `~/.agents/projects/<name>.yaml` (see
|
|
4
|
-
* `lib/projects.ts`); this registers the command tree over them.
|
|
5
|
-
* `isBetaEnabled('projects')`, mirroring `agents factory`.
|
|
4
|
+
* `lib/projects.ts`); this registers the command tree over them.
|
|
6
5
|
*
|
|
7
6
|
* The headline is `status`: instead of the vague per-agent activity line, it
|
|
8
7
|
* rolls every session up by project (matched on cwd) into one card — agents by
|
|
@@ -1,8 +1,7 @@
|
|
|
1
1
|
/**
|
|
2
2
|
* `agents projects` — named, multi-repo projects and the progress
|
|
3
3
|
* rollup. Definitions live in `~/.agents/projects/<name>.yaml` (see
|
|
4
|
-
* `lib/projects.ts`); this registers the command tree over them.
|
|
5
|
-
* `isBetaEnabled('projects')`, mirroring `agents factory`.
|
|
4
|
+
* `lib/projects.ts`); this registers the command tree over them.
|
|
6
5
|
*
|
|
7
6
|
* The headline is `status`: instead of the vague per-agent activity line, it
|
|
8
7
|
* rolls every session up by project (matched on cwd) into one card — agents by
|
|
@@ -12,7 +11,6 @@ import chalk from 'chalk';
|
|
|
12
11
|
import * as fs from 'fs';
|
|
13
12
|
import * as path from 'path';
|
|
14
13
|
import { execFileSync, spawnSync } from 'child_process';
|
|
15
|
-
import { betaEnableHint, isBetaEnabled } from '../lib/beta.js';
|
|
16
14
|
import { setHelpSections } from '../lib/help.js';
|
|
17
15
|
import { getMainRepoRoot } from '../lib/git.js';
|
|
18
16
|
import { parseOwnerRepoFromRemote } from '../lib/registry.js';
|
|
@@ -437,25 +435,24 @@ warnWorkspaces = []) {
|
|
|
437
435
|
console.log('');
|
|
438
436
|
}
|
|
439
437
|
export function registerProjectsCommands(program) {
|
|
440
|
-
const enabled = isBetaEnabled('projects');
|
|
441
438
|
const projects = program
|
|
442
|
-
.command('projects'
|
|
439
|
+
.command('projects')
|
|
443
440
|
.description('Named multi-repo projects with a progress rollup.');
|
|
444
441
|
setHelpSections(projects, {
|
|
445
442
|
examples: `
|
|
446
443
|
agents projects import --from-linear # the projects you actually track
|
|
447
444
|
agents projects add rush --repo phnx-labs/rush --path apps/web
|
|
448
445
|
agents projects list
|
|
449
|
-
agents projects status #
|
|
446
|
+
agents projects status # every project, across the whole fleet
|
|
450
447
|
agents projects status rush # one project (same body as view/show)
|
|
451
448
|
agents projects view rush # alias of status <name>
|
|
452
|
-
agents projects status --
|
|
449
|
+
agents projects status --device s0 # scope to one device (or --devices a,b,c)
|
|
453
450
|
agents projects link rush --linear # bind the Linear project (auto-suggest)
|
|
454
451
|
agents run --project rush # land an agent in the project
|
|
455
452
|
`,
|
|
456
453
|
notes: `
|
|
457
454
|
Definitions are hand-editable YAML in ~/.agents/projects/ and sync across
|
|
458
|
-
machines with 'agents push/pull'.
|
|
455
|
+
machines with 'agents push/pull'.
|
|
459
456
|
|
|
460
457
|
'import --from-factory' reads Factory's auto-detected registry, which
|
|
461
458
|
guesses from checkouts on disk — it imports only 'high' confidence rows by
|
|
@@ -463,18 +460,6 @@ export function registerProjectsCommands(program) {
|
|
|
463
460
|
with 'agents projects rm <name>'.
|
|
464
461
|
`,
|
|
465
462
|
});
|
|
466
|
-
projects.hook('preAction', (_thisCommand, actionCommand) => {
|
|
467
|
-
if (enabled)
|
|
468
|
-
return;
|
|
469
|
-
// `probe` is the peer half of `status --fleet`: it must answer whenever the
|
|
470
|
-
// binary carries it, even where the beta flag is off — a gated peer would
|
|
471
|
-
// look unreachable to every fleet member on a newer CLI.
|
|
472
|
-
if (actionCommand.name() === 'probe')
|
|
473
|
-
return;
|
|
474
|
-
console.error(chalk.red('agents projects is in beta.'));
|
|
475
|
-
console.error(chalk.gray(betaEnableHint('projects')));
|
|
476
|
-
process.exit(1);
|
|
477
|
-
});
|
|
478
463
|
// ---- list ----
|
|
479
464
|
projects
|
|
480
465
|
.command('list')
|
|
@@ -553,6 +538,15 @@ export function registerProjectsCommands(program) {
|
|
|
553
538
|
console.log(chalk.gray(` ${target}`));
|
|
554
539
|
console.log(chalk.gray(` root ${def.root}${def.repo ? ` · repo ${def.repo}` : ''}`));
|
|
555
540
|
});
|
|
541
|
+
/** Merge `--device a b` (variadic) and `--devices a,b,c` (comma list) into one
|
|
542
|
+
* deduped device filter; undefined when neither was given (= whole fleet). */
|
|
543
|
+
function resolveDeviceFilter(device, devices) {
|
|
544
|
+
const merged = [
|
|
545
|
+
...(device ?? []),
|
|
546
|
+
...(devices ? devices.split(',').map((s) => s.trim()).filter(Boolean) : []),
|
|
547
|
+
];
|
|
548
|
+
return merged.length ? [...new Set(merged)] : undefined;
|
|
549
|
+
}
|
|
556
550
|
/** Print the YAML-side fields that sit under the shared card in `view` mode. */
|
|
557
551
|
function printProjectDefinition(def, name) {
|
|
558
552
|
console.log();
|
|
@@ -598,16 +592,16 @@ export function registerProjectsCommands(program) {
|
|
|
598
592
|
}
|
|
599
593
|
const windowDays = Math.max(1, Number.parseInt(opts.window ?? '7', 10) || 7);
|
|
600
594
|
const nowMs = Date.now();
|
|
601
|
-
//
|
|
602
|
-
// locally
|
|
603
|
-
// live-session rollup to the
|
|
604
|
-
//
|
|
605
|
-
//
|
|
606
|
-
const fleetTargets =
|
|
595
|
+
// Fleet is the default: probe each shown def's workspace paths (root +
|
|
596
|
+
// repos[].path) locally AND on every peer in one parallel SSH round, and
|
|
597
|
+
// widen the live-session rollup to the fleet via the sessions fan-out.
|
|
598
|
+
// `--device`/`--devices` scopes the remote fan-out to a subset; with no
|
|
599
|
+
// filter every registered device is dialled.
|
|
600
|
+
const fleetTargets = [...new Set(defs.flatMap(workspaceTargetsForDef))];
|
|
607
601
|
let fleetWs = [];
|
|
608
602
|
let fleetSkipped = [];
|
|
609
603
|
let fleetSessions = [];
|
|
610
|
-
|
|
604
|
+
{
|
|
611
605
|
const self = machineId();
|
|
612
606
|
fleetWs.push(...probeProjectWorkspaces(fleetTargets).map((s) => ({ ...s, host: self })));
|
|
613
607
|
const [probeRes, activeRes] = await Promise.all([
|
|
@@ -615,11 +609,12 @@ export function registerProjectsCommands(program) {
|
|
|
615
609
|
? gatherRemoteAgentsJson({
|
|
616
610
|
args: ['projects', 'probe', '--json', ...fleetTargets],
|
|
617
611
|
noFanoutEnv: PROJECTS_NO_FANOUT_ENV,
|
|
612
|
+
hosts: opts.deviceFilter,
|
|
618
613
|
parse: parseRemoteProbe,
|
|
619
614
|
quiet: true,
|
|
620
615
|
})
|
|
621
616
|
: Promise.resolve({ items: [], deviceCount: 0, skipped: [] }),
|
|
622
|
-
gatherRemoteActive(
|
|
617
|
+
gatherRemoteActive(opts.deviceFilter, { quiet: true }),
|
|
623
618
|
]);
|
|
624
619
|
fleetWs.push(...probeRes.items);
|
|
625
620
|
fleetSkipped = probeRes.skipped;
|
|
@@ -636,17 +631,6 @@ export function registerProjectsCommands(program) {
|
|
|
636
631
|
const targets = new Set(workspaceTargetsForDef(d));
|
|
637
632
|
return fleetWs.filter((s) => targets.has(s.path));
|
|
638
633
|
};
|
|
639
|
-
/** Local-only workspace probe for the warnings footer when --fleet is off. */
|
|
640
|
-
const localWsCache = new Map();
|
|
641
|
-
const localWsFor = (d) => {
|
|
642
|
-
const cached = localWsCache.get(d.name);
|
|
643
|
-
if (cached)
|
|
644
|
-
return cached;
|
|
645
|
-
const self = machineId();
|
|
646
|
-
const rows = probeProjectWorkspaces(workspaceTargetsForDef(d)).map((s) => ({ ...s, host: self }));
|
|
647
|
-
localWsCache.set(d.name, rows);
|
|
648
|
-
return rows;
|
|
649
|
-
};
|
|
650
634
|
if (opts.json) {
|
|
651
635
|
if (fleetSkipped.length > 0)
|
|
652
636
|
process.stderr.write(formatFleetSkippedNote(fleetSkipped));
|
|
@@ -677,7 +661,7 @@ export function registerProjectsCommands(program) {
|
|
|
677
661
|
lastArtifact: rem?.lastArtifact ?? null,
|
|
678
662
|
windowDays,
|
|
679
663
|
repos: [d.repo, ...(d.repos ?? []).map((r2) => r2.slug)].filter(Boolean),
|
|
680
|
-
|
|
664
|
+
workspaces: fleetFor(d),
|
|
681
665
|
};
|
|
682
666
|
}), null, 2));
|
|
683
667
|
return;
|
|
@@ -685,10 +669,10 @@ export function registerProjectsCommands(program) {
|
|
|
685
669
|
// Compact rollup shows the next milestone; `view` shows every declared one.
|
|
686
670
|
const milestoneLimit = detail ? Number.POSITIVE_INFINITY : 1;
|
|
687
671
|
for (const d of defs) {
|
|
688
|
-
renderCard(d, roll.get(d.name), remote.get(d.name),
|
|
689
|
-
// Always feed workspace rows into the warnings footer
|
|
690
|
-
//
|
|
691
|
-
|
|
672
|
+
renderCard(d, roll.get(d.name), remote.get(d.name), fleetFor(d), linear.get(d.name), nowMs, milestoneLimit, focus.get(d.name) ?? [], detail,
|
|
673
|
+
// Always feed workspace rows into the warnings footer so behind/dirty
|
|
674
|
+
// is never silent.
|
|
675
|
+
fleetFor(d));
|
|
692
676
|
if (detail)
|
|
693
677
|
printProjectDefinition(d, d.name);
|
|
694
678
|
}
|
|
@@ -699,15 +683,23 @@ export function registerProjectsCommands(program) {
|
|
|
699
683
|
.command('status [name]')
|
|
700
684
|
.alias('view')
|
|
701
685
|
.alias('show')
|
|
702
|
-
.description('Progress card for every project, or one named project (aliases: view, show). Named form also prints every milestone and the stored definition.')
|
|
686
|
+
.description('Progress card for every project across the whole fleet, or one named project (aliases: view, show). Named form also prints every milestone and the stored definition.')
|
|
703
687
|
.option('--json', 'Machine-readable output')
|
|
704
688
|
.option('--window <days>', 'Window for merged PRs, artifacts, and focus areas', '7')
|
|
705
689
|
.option('--no-remote', 'Skip the GitHub and Linear lookups; faster, offline')
|
|
706
|
-
.option('--
|
|
707
|
-
.
|
|
690
|
+
.option('--device <name...>', 'Scope fleet status to one or more devices (repeatable)')
|
|
691
|
+
.option('--devices <names>', 'Scope fleet status to a comma-separated list of devices')
|
|
692
|
+
.action(async (name, rawOpts) => {
|
|
708
693
|
// Named invocation = `view` depth (all milestones + definition). Unnamed
|
|
709
694
|
// stays the scannable multi-project rollup. `view`/`show` are commander
|
|
710
695
|
// aliases of this same command, so there is only one implementation.
|
|
696
|
+
// Fleet is dialled by default; --device/--devices narrows it to a subset.
|
|
697
|
+
const opts = {
|
|
698
|
+
json: rawOpts.json,
|
|
699
|
+
window: rawOpts.window,
|
|
700
|
+
remote: rawOpts.remote,
|
|
701
|
+
deviceFilter: resolveDeviceFilter(rawOpts.device, rawOpts.devices),
|
|
702
|
+
};
|
|
711
703
|
const mode = name ? 'view' : 'status';
|
|
712
704
|
await runProjectCard(name, opts, mode);
|
|
713
705
|
});
|
package/dist/commands/secrets.js
CHANGED
|
@@ -18,10 +18,10 @@ import { ensureDaemonStarted, isDaemonRunning } from '../lib/daemon.js';
|
|
|
18
18
|
import { parseHostsOption, remoteResolveEnv, remoteSecretsRaw, remoteSecretsStream, resolveHostSshTarget, verifyRemoteKeychainPush, keychainWriteFailureMessage, } from '../lib/secrets/remote.js';
|
|
19
19
|
import { remoteShellFor, buildWindowsStdinImportCommand } from '../lib/hosts/remote-cmd.js';
|
|
20
20
|
import { resolveRemoteOsSync } from '../lib/hosts/remote-os.js';
|
|
21
|
-
import { bundleBackend, bundleExists, bundleItemStore, bundlePolicy, deleteBundle, describeBundle, keychainItemsForBundle, keychainRef, listBundles, migrateLegacyBundles, parseDotenv, readAndResolveBundleEnv,
|
|
21
|
+
import { bundleBackend, bundleExists, bundleItemStore, bundlePolicy, deleteBundle, describeBundle, keychainItemsForBundle, keychainRef, listBundles, healKeychainBundleMetadataAclOnce, migrateLegacyBundles, parseDotenv, readAndResolveBundleEnv, readBundle, readBundleIfDecryptable, reAclBundleItems, renameBundle, rotateBundleSecret, sanitizeProcessEnv, validateBundleName, validateEnvKey, validateExpiresFutureDated, validateSecretType, writeBundle, writeBundleWithItems, SECRET_TYPES, } from '../lib/secrets/bundles.js';
|
|
22
22
|
import { parseListFilters, bundleMatchesFilter, bundleExpiry, filterIsActive, describeFilter, parseSortField, sortBundles, SORT_FIELDS, REF_KINDS, DEFAULT_EXPIRING_DAYS, } from '../lib/secrets/list-filter.js';
|
|
23
23
|
import { encryptForFallback, decryptForFallback } from '../lib/secrets/filestore.js';
|
|
24
|
-
import { getKeychainToken,
|
|
24
|
+
import { getKeychainToken, hasKeychainToken, secretsKeychainItem, setKeychainToken, maybeAutoRekey, } from '../lib/secrets/index.js';
|
|
25
25
|
import { assertOpAvailable, createPasswordItem, deleteItemByTitle, extractSecrets, itemExistsByTitle, listItems, listVaults, } from '../lib/onepassword.js';
|
|
26
26
|
import { GLOBAL_HARNESS } from '../lib/secrets/scope.js';
|
|
27
27
|
import { secretsHoldMs, secretsAgentDurable, agentLoad, agentLock, agentPing, agentStatus, ensureAgentRunning, runAgentLoadFromStdin, runSecretsAgent, uninstallSecretsAgentService, } from '../lib/secrets/agent.js';
|
|
@@ -1251,15 +1251,15 @@ export function registerSecretsCommands(program) {
|
|
|
1251
1251
|
}
|
|
1252
1252
|
const revealed = new Map();
|
|
1253
1253
|
if (reveal) {
|
|
1254
|
-
const
|
|
1255
|
-
|
|
1256
|
-
|
|
1257
|
-
|
|
1258
|
-
|
|
1259
|
-
|
|
1260
|
-
|
|
1261
|
-
|
|
1262
|
-
|
|
1254
|
+
const { env } = readAndResolveBundleEnv(bundle.name, {
|
|
1255
|
+
caller: 'view --reveal --json',
|
|
1256
|
+
keyMode: 'storage',
|
|
1257
|
+
agentOnly: true,
|
|
1258
|
+
});
|
|
1259
|
+
for (const entry of entries) {
|
|
1260
|
+
if (entry.kind === 'keychain' && env[entry.key] !== undefined) {
|
|
1261
|
+
revealed.set(secretsKeychainItem(bundle.name, entry.detail), env[entry.key]);
|
|
1262
|
+
}
|
|
1263
1263
|
}
|
|
1264
1264
|
const exposed = revealed.size + entries.filter((e) => e.kind === 'literal').length;
|
|
1265
1265
|
if (exposed > 0) {
|
|
@@ -1369,23 +1369,20 @@ export function registerSecretsCommands(program) {
|
|
|
1369
1369
|
console.error(chalk.red('--reveal in a non-TTY requires --plaintext.'));
|
|
1370
1370
|
process.exit(1);
|
|
1371
1371
|
}
|
|
1372
|
-
//
|
|
1373
|
-
//
|
|
1374
|
-
//
|
|
1372
|
+
// Resolve through the broker / durable-session path. A locked keychain
|
|
1373
|
+
// bundle errors with the explicit unlock hint; viewing never raises a
|
|
1374
|
+
// Touch ID sheet itself.
|
|
1375
1375
|
const revealedValues = new Map();
|
|
1376
1376
|
if (reveal) {
|
|
1377
|
-
const
|
|
1378
|
-
|
|
1379
|
-
|
|
1380
|
-
|
|
1381
|
-
|
|
1382
|
-
|
|
1383
|
-
|
|
1384
|
-
|
|
1385
|
-
|
|
1386
|
-
}
|
|
1387
|
-
catch {
|
|
1388
|
-
// Fall through to masked output on cancellation / batch failure.
|
|
1377
|
+
const { env } = readAndResolveBundleEnv(bundle.name, {
|
|
1378
|
+
caller: 'view --reveal',
|
|
1379
|
+
keyMode: 'storage',
|
|
1380
|
+
agentOnly: true,
|
|
1381
|
+
});
|
|
1382
|
+
for (const entry of entries) {
|
|
1383
|
+
if (entry.kind === 'keychain' && env[entry.key] !== undefined) {
|
|
1384
|
+
revealedValues.set(secretsKeychainItem(bundle.name, entry.detail), env[entry.key]);
|
|
1385
|
+
}
|
|
1389
1386
|
}
|
|
1390
1387
|
// Revealing plaintext bypasses readAndResolveBundleEnv (the usual
|
|
1391
1388
|
// audit chokepoint), so emit here — a `--reveal` exposes real values
|
|
@@ -1475,10 +1472,9 @@ export function registerSecretsCommands(program) {
|
|
|
1475
1472
|
process.exit(1);
|
|
1476
1473
|
}
|
|
1477
1474
|
// `secrets get` is the scriptable automation primitive ($(agents secrets
|
|
1478
|
-
// get bundle KEY))
|
|
1479
|
-
//
|
|
1480
|
-
|
|
1481
|
-
const { env } = readAndResolveBundleEnv(item, { caller: 'secrets get', keys: [key], keyMode: 'storage', agentOnly: isHeadlessSecretsContext() });
|
|
1475
|
+
// get bundle KEY)). Every read is broker-only; a locked bundle points at
|
|
1476
|
+
// the explicit unlock command instead of raising Touch ID.
|
|
1477
|
+
const { env } = readAndResolveBundleEnv(item, { caller: 'secrets get', keys: [key], keyMode: 'storage', agentOnly: true });
|
|
1482
1478
|
if (!(key in env)) {
|
|
1483
1479
|
console.error(chalk.red(`Key '${key}' not in bundle '${item}'.`));
|
|
1484
1480
|
process.exit(1);
|
|
@@ -2083,7 +2079,7 @@ Examples:
|
|
|
2083
2079
|
throw new Error('--to-file needs AGENTS_SECRETS_PASSPHRASE set to encrypt the bundle. ' +
|
|
2084
2080
|
'Set it for this command, then supply the same value when importing.');
|
|
2085
2081
|
}
|
|
2086
|
-
const { env } = readAndResolveBundleEnv(resolvedBundleName, { caller: 'export --to-file', keyMode: 'storage', agentOnly:
|
|
2082
|
+
const { env } = readAndResolveBundleEnv(resolvedBundleName, { caller: 'export --to-file', keyMode: 'storage', agentOnly: true });
|
|
2087
2083
|
exportBundleToFile(env, opts.toFile, passphrase);
|
|
2088
2084
|
emitSecretAudit({ event: 'secrets.export', bundle: resolvedBundleName, operation: 'export --to-file', source: 'file', status: 'success', keyCount: Object.keys(env).length });
|
|
2089
2085
|
console.log(chalk.green(`Exported ${Object.keys(env).length} key(s) to ${opts.toFile}`));
|
|
@@ -2111,7 +2107,7 @@ Examples:
|
|
|
2111
2107
|
'bundle at rest on the remote. Set it for this command, then unlock it the same way per run.');
|
|
2112
2108
|
}
|
|
2113
2109
|
}
|
|
2114
|
-
const { env } = readAndResolveBundleEnv(resolvedBundleName, { caller: `ssh export`, keyMode: 'storage', agentOnly:
|
|
2110
|
+
const { env } = readAndResolveBundleEnv(resolvedBundleName, { caller: `ssh export`, keyMode: 'storage', agentOnly: true });
|
|
2115
2111
|
const dotenv = bundleEnvToDotenv(env);
|
|
2116
2112
|
const keyCount = Object.keys(env).length;
|
|
2117
2113
|
// Drive the remote's own `agents secrets import --from -` so the values
|
|
@@ -2200,7 +2196,7 @@ Examples:
|
|
|
2200
2196
|
if (opts.to1password) {
|
|
2201
2197
|
assertOpAvailable();
|
|
2202
2198
|
const vault = await resolveVault(opts.vault);
|
|
2203
|
-
const { env } = readAndResolveBundleEnv(resolvedBundleName, { caller: `1Password vault ${vault}`, keyMode: 'storage', agentOnly:
|
|
2199
|
+
const { env } = readAndResolveBundleEnv(resolvedBundleName, { caller: `1Password vault ${vault}`, keyMode: 'storage', agentOnly: true });
|
|
2204
2200
|
let created = 0;
|
|
2205
2201
|
let overwritten = 0;
|
|
2206
2202
|
let skipped = 0;
|
|
@@ -2240,14 +2236,12 @@ Examples:
|
|
|
2240
2236
|
process.exit(1);
|
|
2241
2237
|
}
|
|
2242
2238
|
// `agents secrets export --plaintext` is what release/CI scripts eval.
|
|
2243
|
-
//
|
|
2244
|
-
//
|
|
2245
|
-
// ID sheet on the interactive user's screen. An `eval "$(...)"` typed in a
|
|
2246
|
-
// plain shell carries no AGENTS_RUNTIME, so it is not headless and still prompts.
|
|
2239
|
+
// Every caller is broker-only, including a plain shell, so export never
|
|
2240
|
+
// raises Touch ID on the interactive user's screen.
|
|
2247
2241
|
const { env } = readAndResolveBundleEnv(resolvedBundleName, {
|
|
2248
2242
|
caller: `export to shell`,
|
|
2249
2243
|
keyMode: 'process',
|
|
2250
|
-
agentOnly:
|
|
2244
|
+
agentOnly: true,
|
|
2251
2245
|
});
|
|
2252
2246
|
if (opts.format === 'json') {
|
|
2253
2247
|
// Machine-readable form consumed by `remoteResolveEnv` over SSH.
|
|
@@ -2309,7 +2303,7 @@ Examples:
|
|
|
2309
2303
|
caller: `command ${cmd}`,
|
|
2310
2304
|
keys: keysSubset,
|
|
2311
2305
|
allowExpired: execOpts.allowExpired,
|
|
2312
|
-
agentOnly:
|
|
2306
|
+
agentOnly: true,
|
|
2313
2307
|
}).env;
|
|
2314
2308
|
}
|
|
2315
2309
|
const { spawn } = await import('child_process');
|
|
@@ -2575,6 +2569,11 @@ Examples:
|
|
|
2575
2569
|
duration: humanRemaining(Date.now() + ttlMs),
|
|
2576
2570
|
keyMode: 'storage',
|
|
2577
2571
|
});
|
|
2572
|
+
// Migrations are authorized only by this explicit unlock. The bundle
|
|
2573
|
+
// metadata was included in the successful authenticated batch, so the
|
|
2574
|
+
// ACL heal can rewrite that already-read value without another read.
|
|
2575
|
+
maybeAutoRekey();
|
|
2576
|
+
healKeychainBundleMetadataAclOnce(new Map([[bundle.name, JSON.stringify(bundle)]]));
|
|
2578
2577
|
if (await agentLoad(name, bundle, env, ttlMs, harness)) {
|
|
2579
2578
|
loaded++;
|
|
2580
2579
|
// Persist a durable session snapshot so the unlock survives a daemon
|
package/dist/commands/ssh.js
CHANGED
|
@@ -16,7 +16,7 @@ import * as path from 'path';
|
|
|
16
16
|
import chalk from 'chalk';
|
|
17
17
|
import ora from 'ora';
|
|
18
18
|
import { getCliVersion } from '../lib/version.js';
|
|
19
|
-
import { readAndResolveBundleEnv
|
|
19
|
+
import { readAndResolveBundleEnv } from '../lib/secrets/bundles.js';
|
|
20
20
|
import { machineId } from '../lib/session/sync/config.js';
|
|
21
21
|
import { isDeviceAuto, resolveDeviceAffinity } from '../lib/smart-launch.js';
|
|
22
22
|
import { registerFleetCaptureCommand } from './fleet-capture.js';
|
|
@@ -31,7 +31,7 @@ import { resolveDeviceTarget, splitUserHost } from '../lib/devices/resolve-targe
|
|
|
31
31
|
import { clearPendingSentinel } from '../lib/devices/pending.js';
|
|
32
32
|
import { isInteractiveTerminal, isPromptCancelled } from './utils.js';
|
|
33
33
|
import { hostNameFor, renderSshConfig } from '../lib/devices/ssh-config.js';
|
|
34
|
-
import { ASKPASS_BUNDLE_ENV, ASKPASS_KEY_ENV,
|
|
34
|
+
import { ASKPASS_BUNDLE_ENV, ASKPASS_KEY_ENV, buildSshInvocation, fleetDialTarget, writeAskpassShim, } from '../lib/devices/connect.js';
|
|
35
35
|
import { ensureManagedKnownHostsDir, isHostPinned } from '../lib/devices/known-hosts.js';
|
|
36
36
|
import { shouldSyncTerminfo, syncTerminfoToDevice, terminfoHostKey } from '../lib/devices/terminfo.js';
|
|
37
37
|
import { fanOutDevices, fleetHealthSkip, planFleetTargets, remoteFleetTargets, runFleet, skipLabel, upgradeCommand, } from '../lib/devices/fleet.js';
|
|
@@ -1514,9 +1514,8 @@ async function runAskpass() {
|
|
|
1514
1514
|
}
|
|
1515
1515
|
// A read-only stats probe sets ASKPASS_AGENT_ONLY_ENV to force a broker-only
|
|
1516
1516
|
// resolve even under a TTY — so `agents devices` never pops Touch ID just to
|
|
1517
|
-
// render load/mem for an uncached password-auth device (RUSH-1970).
|
|
1518
|
-
|
|
1519
|
-
const agentOnly = process.env[ASKPASS_AGENT_ONLY_ENV] === '1' || isHeadlessSecretsContext();
|
|
1517
|
+
// render load/mem for an uncached password-auth device (RUSH-1970).
|
|
1518
|
+
const agentOnly = true;
|
|
1520
1519
|
try {
|
|
1521
1520
|
const { env } = readAndResolveBundleEnv(bundle, { caller: 'agents ssh', keys: [key], keyMode: 'storage', agentOnly });
|
|
1522
1521
|
const value = env[key];
|
|
@@ -29,7 +29,7 @@ Structure:
|
|
|
29
29
|
skills/ optional: knowledge packs scoped to this workflow
|
|
30
30
|
plugins/ optional: plugin bundles scoped to this workflow
|
|
31
31
|
|
|
32
|
-
Resolution: project
|
|
32
|
+
Resolution: project > user > plugin (plugins/*/workflows/) > extra > system.
|
|
33
33
|
|
|
34
34
|
Note: agents run defaults to --mode plan (read-only). For workflows that
|
|
35
35
|
write files, post comments, or otherwise mutate state, pass --mode edit or
|
package/dist/index.js
CHANGED
|
@@ -1177,7 +1177,7 @@ if (process.env.AGENTS_SKIP_MIGRATION !== '1') {
|
|
|
1177
1177
|
// Bumping the suffix re-runs migrations for every user; binary releases that
|
|
1178
1178
|
// don't change the schema must NOT re-run (they would destroy user content
|
|
1179
1179
|
// when migration steps overlap with user-authored paths). See issue #20.
|
|
1180
|
-
const sentinelValue = '
|
|
1180
|
+
const sentinelValue = 'v14';
|
|
1181
1181
|
let needRun = true;
|
|
1182
1182
|
try {
|
|
1183
1183
|
if (fs.existsSync(sentinel) && fs.readFileSync(sentinel, 'utf-8').trim() === sentinelValue) {
|
package/dist/lib/beta.d.ts
CHANGED
|
@@ -8,7 +8,7 @@
|
|
|
8
8
|
* checks.
|
|
9
9
|
*/
|
|
10
10
|
import type { BetaFeatureName } from './types.js';
|
|
11
|
-
export declare const ALL_BETA_FEATURES: readonly ["factory"
|
|
11
|
+
export declare const ALL_BETA_FEATURES: readonly ["factory"];
|
|
12
12
|
export declare function getEnabledBetaFeatures(): BetaFeatureName[];
|
|
13
13
|
export declare function isBetaEnabled(feature: BetaFeatureName): boolean;
|
|
14
14
|
export declare function getBetaConfigLocation(): {
|
package/dist/lib/beta.js
CHANGED
|
@@ -10,7 +10,7 @@
|
|
|
10
10
|
import * as path from 'path';
|
|
11
11
|
import { getAgentsDir, getOptionalUserAgentsDir, readMeta, writeMeta } from './state.js';
|
|
12
12
|
import { readManifest, writeManifest } from './manifest.js';
|
|
13
|
-
export const ALL_BETA_FEATURES = ['factory'
|
|
13
|
+
export const ALL_BETA_FEATURES = ['factory'];
|
|
14
14
|
function isBetaFeatureName(value) {
|
|
15
15
|
return typeof value === 'string' && ALL_BETA_FEATURES.includes(value);
|
|
16
16
|
}
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
/**
|
|
2
2
|
* The unified event reader -- one stream over BOTH operational events
|
|
3
|
-
* (`~/.agents/events.jsonl` via events.ts: secrets, commands, teams, ...) and
|
|
3
|
+
* (`~/.agents/.history/events/events.jsonl` via events.ts: secrets, commands, teams, ...) and
|
|
4
4
|
* agent-semantic events (the per-session activity logs via activity.ts: plans,
|
|
5
5
|
* PRs, worktrees, sub-agents, artifacts). They share one {@link EventType}
|
|
6
6
|
* vocabulary and one {@link EventRecord} shape, so `agents events` and any
|
package/dist/lib/event-stream.js
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
/**
|
|
2
2
|
* The unified event reader -- one stream over BOTH operational events
|
|
3
|
-
* (`~/.agents/events.jsonl` via events.ts: secrets, commands, teams, ...) and
|
|
3
|
+
* (`~/.agents/.history/events/events.jsonl` via events.ts: secrets, commands, teams, ...) and
|
|
4
4
|
* agent-semantic events (the per-session activity logs via activity.ts: plans,
|
|
5
5
|
* PRs, worktrees, sub-agents, artifacts). They share one {@link EventType}
|
|
6
6
|
* vocabulary and one {@link EventRecord} shape, so `agents events` and any
|
package/dist/lib/events.d.ts
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
/**
|
|
2
2
|
* Centralized event logging for agents-cli.
|
|
3
3
|
*
|
|
4
|
-
* Structured JSONL audit log at ~/.agents/events.jsonl with lossless numbered
|
|
4
|
+
* Structured JSONL audit log at ~/.agents/.history/events/events.jsonl with lossless numbered
|
|
5
5
|
* gzip rotation at 10 MB and rich metadata for debugging/auditing.
|
|
6
6
|
*
|
|
7
7
|
* Features:
|