@phnx-labs/agents-cli 1.22.42 → 1.22.43
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 +72 -0
- package/README.md +1 -1
- package/dist/bin/agents +0 -0
- package/dist/bootstrap.js +25 -7
- package/dist/cli/command-registry.d.ts +0 -3
- package/dist/cli/command-registry.js +0 -8
- package/dist/commands/alias.d.ts +7 -4
- package/dist/commands/alias.js +33 -8
- package/dist/commands/auth.js +7 -3
- package/dist/commands/computer.js +20 -6
- package/dist/commands/daemon.js +1 -1
- package/dist/commands/doctor.d.ts +4 -2
- package/dist/commands/doctor.js +20 -5
- package/dist/commands/exec.js +3 -2
- package/dist/commands/feed.js +1 -30
- package/dist/commands/harness.js +3 -3
- package/dist/commands/monitors.js +1 -1
- package/dist/commands/org.js +9 -8
- package/dist/commands/profiles.js +2 -2
- package/dist/commands/routines.js +43 -25
- package/dist/commands/sessions-picker.js +124 -122
- package/dist/commands/setup.js +5 -1
- package/dist/commands/snapshot.d.ts +1 -1
- package/dist/commands/snapshot.js +4 -4
- package/dist/commands/status.d.ts +4 -2
- package/dist/commands/status.js +10 -7
- package/dist/commands/sync.d.ts +1 -0
- package/dist/commands/sync.js +29 -2
- package/dist/commands/view.js +6 -0
- package/dist/commands/webhook.js +1 -1
- package/dist/lib/accounting/rotate.d.ts +5 -3
- package/dist/lib/accounting/rotate.js +36 -7
- package/dist/lib/accounting/usage.d.ts +18 -4
- package/dist/lib/accounting/usage.js +138 -27
- package/dist/lib/agent-spec/agents.d.ts +7 -7
- package/dist/lib/agent-spec/agents.js +15 -15
- package/dist/lib/cloud/rush.d.ts +0 -15
- package/dist/lib/cloud/rush.js +0 -35
- package/dist/lib/crabbox/runtimes.d.ts +6 -2
- package/dist/lib/crabbox/runtimes.js +21 -5
- package/dist/lib/daemon/daemon.js +86 -58
- package/dist/lib/daemon/runner.d.ts +18 -1
- package/dist/lib/daemon/runner.js +105 -11
- package/dist/lib/devices/doctor-findings.js +1 -1
- package/dist/lib/devices/health-report.js +1 -1
- package/dist/lib/drift-sync.d.ts +1 -1
- package/dist/lib/drift-sync.js +2 -2
- package/dist/lib/drift.d.ts +1 -1
- package/dist/lib/exec.js +13 -3
- package/dist/lib/format.d.ts +9 -0
- package/dist/lib/format.js +16 -0
- package/dist/lib/github/pr-mergeable.d.ts +49 -0
- package/dist/lib/github/pr-mergeable.js +157 -0
- package/dist/lib/github/pr-verdict.d.ts +67 -0
- package/dist/lib/github/pr-verdict.js +72 -0
- package/dist/lib/harness/adapter.d.ts +6 -5
- package/dist/lib/hosts/passthrough.d.ts +10 -0
- package/dist/lib/hosts/passthrough.js +28 -6
- package/dist/lib/hosts/session-index.js +1 -1
- package/dist/lib/installations/shims.js +1 -1
- package/dist/lib/installations/versions.d.ts +40 -0
- package/dist/lib/installations/versions.js +57 -2
- package/dist/lib/menubar/MenubarHelper.app/Contents/CodeResources +0 -0
- package/dist/lib/menubar/MenubarHelper.app/Contents/MacOS/MenubarHelper +0 -0
- package/dist/lib/menubar/install-menubar.js +19 -8
- package/dist/lib/monitors/config.d.ts +2 -2
- package/dist/lib/monitors/config.js +3 -2
- package/dist/lib/origin-machine.d.ts +18 -0
- package/dist/lib/origin-machine.js +34 -0
- package/dist/lib/perf/db.js +1 -1
- package/dist/lib/perf/spool.js +1 -1
- package/dist/lib/profiles.d.ts +7 -0
- package/dist/lib/profiles.js +26 -1
- package/dist/lib/sandbox.d.ts +24 -0
- package/dist/lib/sandbox.js +101 -0
- package/dist/lib/scheduling/routines.d.ts +18 -9
- package/dist/lib/scheduling/routines.js +16 -8
- 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/agent.js +9 -1
- package/dist/lib/secrets/index.js +1 -1
- package/dist/lib/secrets/list-filter.js +1 -1
- package/dist/lib/service-manifest.d.ts +20 -0
- package/dist/lib/service-manifest.js +34 -0
- package/dist/lib/session/cloud.js +1 -1
- package/dist/lib/session/db.js +1 -1
- package/dist/lib/session/fork.js +1 -1
- package/dist/lib/session/live-metadata.js +1 -1
- package/dist/lib/session/origin-machine.d.ts +1 -18
- package/dist/lib/session/origin-machine.js +4 -34
- package/dist/lib/session/relative-time.d.ts +1 -44
- package/dist/lib/session/relative-time.js +4 -120
- package/dist/lib/session/remote-list.js +1 -1
- package/dist/lib/session/remote.js +2 -2
- package/dist/lib/session/short-id.d.ts +1 -17
- package/dist/lib/session/short-id.js +4 -20
- package/dist/lib/session/width.d.ts +1 -29
- package/dist/lib/session/width.js +4 -101
- package/dist/lib/snapshot.d.ts +2 -2
- package/dist/lib/snapshot.js +1 -1
- package/dist/lib/startup/command-registry.d.ts +4 -1
- package/dist/lib/startup/command-registry.js +11 -4
- package/dist/lib/teams/placement-probe.js +1 -1
- package/dist/lib/teams/scheduler.js +1 -1
- package/dist/lib/text/relative-time.d.ts +44 -0
- package/dist/lib/text/relative-time.js +120 -0
- package/dist/lib/text/short-id.d.ts +17 -0
- package/dist/lib/text/short-id.js +20 -0
- package/dist/lib/text/width.d.ts +29 -0
- package/dist/lib/text/width.js +101 -0
- package/dist/lib/triggers/handlers.d.ts +7 -0
- package/dist/lib/triggers/handlers.js +8 -0
- package/dist/lib/triggers/webhook.d.ts +1 -0
- package/dist/lib/triggers/webhook.js +2 -1
- package/dist/lib/view-types.d.ts +4 -0
- package/package.json +1 -1
- package/dist/commands/tickets.d.ts +0 -2
- package/dist/commands/tickets.js +0 -43
- package/dist/lib/observe-aliases.d.ts +0 -30
- package/dist/lib/observe-aliases.js +0 -38
- package/dist/lib/tickets/list.d.ts +0 -53
- package/dist/lib/tickets/list.js +0 -153
|
@@ -21,7 +21,7 @@ import { parseCommaSeparatedList } from '../format.js';
|
|
|
21
21
|
// From the leaf module, NOT discover.js — the latter imports `../sqlite.js`, so
|
|
22
22
|
// reaching through it for one parser would pull node:sqlite into every `agents
|
|
23
23
|
// secrets` invocation and print Node's SQLite ExperimentalWarning on stderr.
|
|
24
|
-
import { parseTimeFilter } from '../
|
|
24
|
+
import { parseTimeFilter } from '../text/relative-time.js';
|
|
25
25
|
import { describeBundle, bundlePolicy, SECRET_TYPES, } from './bundles.js';
|
|
26
26
|
/** Ref kinds a var's value can have, from `describeBundle`. */
|
|
27
27
|
export const REF_KINDS = ['literal', 'keychain', 'env', 'file', 'exec'];
|
|
@@ -27,3 +27,23 @@ export declare function serviceManifestHomeEnv(): {
|
|
|
27
27
|
HOME: string;
|
|
28
28
|
AGENTS_REAL_HOME: string;
|
|
29
29
|
};
|
|
30
|
+
/**
|
|
31
|
+
* Whether this process may safely register (or tear down) a service with the
|
|
32
|
+
* user's real service manager.
|
|
33
|
+
*
|
|
34
|
+
* `launchctl` and `systemctl --user` are per-user-session and HOME-independent:
|
|
35
|
+
* a process running under a redirected HOME still talks to the SAME launchd or
|
|
36
|
+
* systemd instance as a normal login session. service-manifest.ts namespaces the
|
|
37
|
+
* job label under a redirected HOME, but that only changes the identifier — the
|
|
38
|
+
* registration still lands in the real service manager. A hermetic test fork (or
|
|
39
|
+
* any CLI running under a sandbox HOME) must therefore never touch launchd/
|
|
40
|
+
* systemd unless it has explicitly opted in.
|
|
41
|
+
*
|
|
42
|
+
* `AGENTS_SERVICE_MANAGER_ALLOW_REDIRECTED_HOME=1` is the test seam for the
|
|
43
|
+
* shim/PATH-based tests that intentionally exercise the registration code path
|
|
44
|
+
* under a redirected HOME. Production code must never set it.
|
|
45
|
+
*/
|
|
46
|
+
export declare function serviceManagerRegistrationAllowed(): {
|
|
47
|
+
allowed: boolean;
|
|
48
|
+
reason: string;
|
|
49
|
+
};
|
|
@@ -78,3 +78,37 @@ export function serviceManifestHomeEnv() {
|
|
|
78
78
|
const home = process.env.HOME || os.homedir();
|
|
79
79
|
return { HOME: home, AGENTS_REAL_HOME: process.env.AGENTS_REAL_HOME || home };
|
|
80
80
|
}
|
|
81
|
+
/**
|
|
82
|
+
* Whether this process may safely register (or tear down) a service with the
|
|
83
|
+
* user's real service manager.
|
|
84
|
+
*
|
|
85
|
+
* `launchctl` and `systemctl --user` are per-user-session and HOME-independent:
|
|
86
|
+
* a process running under a redirected HOME still talks to the SAME launchd or
|
|
87
|
+
* systemd instance as a normal login session. service-manifest.ts namespaces the
|
|
88
|
+
* job label under a redirected HOME, but that only changes the identifier — the
|
|
89
|
+
* registration still lands in the real service manager. A hermetic test fork (or
|
|
90
|
+
* any CLI running under a sandbox HOME) must therefore never touch launchd/
|
|
91
|
+
* systemd unless it has explicitly opted in.
|
|
92
|
+
*
|
|
93
|
+
* `AGENTS_SERVICE_MANAGER_ALLOW_REDIRECTED_HOME=1` is the test seam for the
|
|
94
|
+
* shim/PATH-based tests that intentionally exercise the registration code path
|
|
95
|
+
* under a redirected HOME. Production code must never set it.
|
|
96
|
+
*/
|
|
97
|
+
export function serviceManagerRegistrationAllowed() {
|
|
98
|
+
const suffix = isolatedHomeSuffix();
|
|
99
|
+
if (!suffix) {
|
|
100
|
+
return { allowed: true, reason: 'production HOME: service-manager registration allowed' };
|
|
101
|
+
}
|
|
102
|
+
if (process.env.AGENTS_SERVICE_MANAGER_ALLOW_REDIRECTED_HOME === '1') {
|
|
103
|
+
return {
|
|
104
|
+
allowed: true,
|
|
105
|
+
reason: `test seam AGENTS_SERVICE_MANAGER_ALLOW_REDIRECTED_HOME allows registration under sandbox-${suffix}`,
|
|
106
|
+
};
|
|
107
|
+
}
|
|
108
|
+
return {
|
|
109
|
+
allowed: false,
|
|
110
|
+
reason: `refusing service-manager registration under redirected HOME (sandbox-${suffix}): ` +
|
|
111
|
+
`launchctl/systemd are per-user-session and HOME-independent, so a sandboxed process ` +
|
|
112
|
+
`would register in the real service manager (RUSH-2968)`,
|
|
113
|
+
};
|
|
114
|
+
}
|
|
@@ -13,7 +13,7 @@ import * as fs from 'fs';
|
|
|
13
13
|
import * as path from 'path';
|
|
14
14
|
import * as os from 'os';
|
|
15
15
|
import * as yaml from 'yaml';
|
|
16
|
-
import { deriveShortId } from '
|
|
16
|
+
import { deriveShortId } from '../text/short-id.js';
|
|
17
17
|
import { getCacheDir } from '../state.js';
|
|
18
18
|
const PROXY_BASE = process.env.RUSH_PROXY_BASE ?? 'https://api.prix.dev';
|
|
19
19
|
const USER_YAML = path.join(os.homedir(), '.rush', 'user.yaml');
|
package/dist/lib/session/db.js
CHANGED
|
@@ -13,7 +13,7 @@ import { parseSession, sessionFilePathContainer } from './parse.js';
|
|
|
13
13
|
import { extractRecentDirectoriesTouched, extractTodoProgressFromEvents } from './state.js';
|
|
14
14
|
import { getSessionsDir, getSessionsDbPath } from '../state.js';
|
|
15
15
|
import { query as queryEvents, queryToolUsageForSessions } from '../feed/events.js';
|
|
16
|
-
import { machineForSessionFile } from '
|
|
16
|
+
import { machineForSessionFile } from '../origin-machine.js';
|
|
17
17
|
import { loadSessionActorIndex, readSessionActorRecord } from './actor-sidecar.js';
|
|
18
18
|
import { toolCallsFromEvents } from './tool-calls.js';
|
|
19
19
|
import { persistToolCalls, toolEvidenceSourcePath } from './tool-store.js';
|
package/dist/lib/session/fork.js
CHANGED
|
@@ -19,7 +19,7 @@ import * as fs from 'fs';
|
|
|
19
19
|
import * as path from 'path';
|
|
20
20
|
import { upsertSession } from './db.js';
|
|
21
21
|
import { recordRunName } from './run-names.js';
|
|
22
|
-
import { deriveShortId } from '
|
|
22
|
+
import { deriveShortId } from '../text/short-id.js';
|
|
23
23
|
/** Agents that `fork` can branch today (see the module doc for why). */
|
|
24
24
|
export const FORKABLE_AGENTS = ['claude'];
|
|
25
25
|
/** Whether a session's agent can be forked by {@link forkSession}. */
|
|
@@ -16,7 +16,7 @@
|
|
|
16
16
|
// state the live registry already computed. When the transcript IS on disk, the
|
|
17
17
|
// synthesized row carries its path, so the downstream `buildPreview` renders the
|
|
18
18
|
// real digest; otherwise it renders the header + a "not indexed here" note.
|
|
19
|
-
import { deriveShortId } from '
|
|
19
|
+
import { deriveShortId } from '../text/short-id.js';
|
|
20
20
|
import { isSessionTrackedAgent } from './types.js';
|
|
21
21
|
/**
|
|
22
22
|
* Reshape one live `ActiveSession` into a `SessionMeta` candidate for the id
|
|
@@ -1,18 +1 @@
|
|
|
1
|
-
|
|
2
|
-
* Resolve which machine a session transcript originated on.
|
|
3
|
-
*
|
|
4
|
-
* Cross-machine sync mirrors a remote transcript to
|
|
5
|
-
* `backups/<agent>/<machine>/<subdir>/…`. Every other transcript is a live-home
|
|
6
|
-
* file on this box, so the origin is the local machine id.
|
|
7
|
-
*
|
|
8
|
-
* Kept in a leaf module (no session/db imports) so both discovery and the
|
|
9
|
-
* sessions DB upsert path can stamp `machine` without circular deps.
|
|
10
|
-
*/
|
|
11
|
-
/** Local machine id, cached for the process lifetime. */
|
|
12
|
-
export declare function localMachineId(): string;
|
|
13
|
-
/**
|
|
14
|
-
* The machine a discovered session originated on.
|
|
15
|
-
* When the path sits under the agent's backups root, the first segment below it
|
|
16
|
-
* is the origin machine id; otherwise it's the local machine.
|
|
17
|
-
*/
|
|
18
|
-
export declare function machineForSessionFile(filePath: string, agent: string): string;
|
|
1
|
+
export * from '../origin-machine.js';
|
|
@@ -1,34 +1,4 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
*
|
|
5
|
-
* `backups/<agent>/<machine>/<subdir>/…`. Every other transcript is a live-home
|
|
6
|
-
* file on this box, so the origin is the local machine id.
|
|
7
|
-
*
|
|
8
|
-
* Kept in a leaf module (no session/db imports) so both discovery and the
|
|
9
|
-
* sessions DB upsert path can stamp `machine` without circular deps.
|
|
10
|
-
*/
|
|
11
|
-
import * as path from 'path';
|
|
12
|
-
import { getHistoryDir } from '../state.js';
|
|
13
|
-
import { machineId } from '../machine-id.js';
|
|
14
|
-
let _localMachineId;
|
|
15
|
-
/** Local machine id, cached for the process lifetime. */
|
|
16
|
-
export function localMachineId() {
|
|
17
|
-
return (_localMachineId ??= machineId());
|
|
18
|
-
}
|
|
19
|
-
/**
|
|
20
|
-
* The machine a discovered session originated on.
|
|
21
|
-
* When the path sits under the agent's backups root, the first segment below it
|
|
22
|
-
* is the origin machine id; otherwise it's the local machine.
|
|
23
|
-
*/
|
|
24
|
-
export function machineForSessionFile(filePath, agent) {
|
|
25
|
-
if (!filePath)
|
|
26
|
-
return localMachineId();
|
|
27
|
-
const base = path.join(getHistoryDir(), 'backups', agent) + path.sep;
|
|
28
|
-
if (filePath.startsWith(base)) {
|
|
29
|
-
const seg = filePath.slice(base.length).split(path.sep)[0];
|
|
30
|
-
if (seg)
|
|
31
|
-
return seg;
|
|
32
|
-
}
|
|
33
|
-
return localMachineId();
|
|
34
|
-
}
|
|
1
|
+
// Moved to ../origin-machine.ts (move 1 of the core-module refactor — see
|
|
2
|
+
// .agents/artifacts/2026-08-20/plan-*.md). Kept as a re-export shim so
|
|
3
|
+
// existing importers don't break.
|
|
4
|
+
export * from '../origin-machine.js';
|
|
@@ -1,44 +1 @@
|
|
|
1
|
-
|
|
2
|
-
* Human-readable "time since" formatting for session timestamps. Lives here (not
|
|
3
|
-
* inline in `sessions.ts`) so both the session list renderer and the remote
|
|
4
|
-
* offline-cache banner (`remote.ts`) share one formatter — `sessions.ts` imports
|
|
5
|
-
* `remote.ts`, so a back-import would cycle.
|
|
6
|
-
*/
|
|
7
|
-
export declare function formatRelativeTime(isoTimestamp: string): string;
|
|
8
|
-
/**
|
|
9
|
-
* Compact age — `now`, `45m`, `3h`, `2d`, then the calendar date. This is the
|
|
10
|
-
* *creation* half of a session's time cell: it renders right next to the long
|
|
11
|
-
* last-activity label, and one row can afford one long form, not two.
|
|
12
|
-
*/
|
|
13
|
-
export declare function formatCompactAge(isoTimestamp: string): string;
|
|
14
|
-
/** The two time fields a session listing shows for one row. */
|
|
15
|
-
export interface SessionAgeParts {
|
|
16
|
-
/**
|
|
17
|
-
* Compact age of the session's creation, set only when the session ran long
|
|
18
|
-
* enough (>= a minute) for it to say something `last` does not.
|
|
19
|
-
*/
|
|
20
|
-
created?: string;
|
|
21
|
-
/** Last-activity label — the long relative form the listing sorts by. */
|
|
22
|
-
last: string;
|
|
23
|
-
}
|
|
24
|
-
/**
|
|
25
|
-
* Split a session's timestamps into the two fields a listing renders: when it
|
|
26
|
-
* was created and when it was last active. One last-activity label answers
|
|
27
|
-
* neither "is this the old session I'm looking for" nor "how long did it run" —
|
|
28
|
-
* a session touched an hour ago may have started last week.
|
|
29
|
-
*/
|
|
30
|
-
export declare function sessionAgeParts(createdIso: string, lastActivityIso?: string): SessionAgeParts;
|
|
31
|
-
/**
|
|
32
|
-
* Parse a time filter string (relative like '7d' or an ISO timestamp) into epoch
|
|
33
|
-
* milliseconds. Backs `--since` on `sessions`, `cost`, `teams`, and `output`, and
|
|
34
|
-
* `--unused` on `secrets list`.
|
|
35
|
-
*
|
|
36
|
-
* It lives here, in a module with no imports, rather than in `discover.ts` where
|
|
37
|
-
* it started: `discover.ts` loads `../sqlite.js`, so importing this one function
|
|
38
|
-
* from there pulls `node:sqlite` into the caller's module graph and Node prints
|
|
39
|
-
* `ExperimentalWarning: SQLite …` on stderr. That is invisible in a command that
|
|
40
|
-
* already touches the session DB, and a broken contract in one that doesn't —
|
|
41
|
-
* `monitors --json` asserts a clean stderr. `discover.ts` re-exports it, so
|
|
42
|
-
* existing importers are unaffected.
|
|
43
|
-
*/
|
|
44
|
-
export declare function parseTimeFilter(input: string): number;
|
|
1
|
+
export * from '../text/relative-time.js';
|
|
@@ -1,120 +1,4 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
*
|
|
5
|
-
* `remote.ts`, so a back-import would cycle.
|
|
6
|
-
*/
|
|
7
|
-
const MONTHS = ['Jan', 'Feb', 'Mar', 'Apr', 'May', 'Jun', 'Jul', 'Aug', 'Sep', 'Oct', 'Nov', 'Dec'];
|
|
8
|
-
/**
|
|
9
|
-
* Calendar label for a timestamp older than the relative window. A 2-digit year
|
|
10
|
-
* is appended outside the current year so "Jun 28" is never ambiguous across
|
|
11
|
-
* years (e.g. "Jun 28 '25").
|
|
12
|
-
*/
|
|
13
|
-
function calendarLabel(thenMs, nowMs) {
|
|
14
|
-
const d = new Date(thenMs);
|
|
15
|
-
const label = `${MONTHS[d.getMonth()]} ${d.getDate()}`;
|
|
16
|
-
return d.getFullYear() === new Date(nowMs).getFullYear()
|
|
17
|
-
? label
|
|
18
|
-
: `${label} '${String(d.getFullYear()).slice(-2)}`;
|
|
19
|
-
}
|
|
20
|
-
export function formatRelativeTime(isoTimestamp) {
|
|
21
|
-
const now = Date.now();
|
|
22
|
-
const then = new Date(isoTimestamp).getTime();
|
|
23
|
-
if (isNaN(then))
|
|
24
|
-
return isoTimestamp;
|
|
25
|
-
const diffMs = now - then;
|
|
26
|
-
const diffMin = Math.floor(diffMs / 60_000);
|
|
27
|
-
const diffHrs = Math.floor(diffMs / 3_600_000);
|
|
28
|
-
const diffDays = Math.floor(diffMs / 86_400_000);
|
|
29
|
-
if (diffMin < 1)
|
|
30
|
-
return 'just now';
|
|
31
|
-
if (diffMin < 60)
|
|
32
|
-
return `${diffMin} min ago`;
|
|
33
|
-
if (diffHrs < 24)
|
|
34
|
-
return `${diffHrs} hour${diffHrs === 1 ? '' : 's'} ago`;
|
|
35
|
-
if (diffDays < 7)
|
|
36
|
-
return `${diffDays} day${diffDays === 1 ? '' : 's'} ago`;
|
|
37
|
-
// Older: show the date.
|
|
38
|
-
return calendarLabel(then, now);
|
|
39
|
-
}
|
|
40
|
-
/**
|
|
41
|
-
* Compact age — `now`, `45m`, `3h`, `2d`, then the calendar date. This is the
|
|
42
|
-
* *creation* half of a session's time cell: it renders right next to the long
|
|
43
|
-
* last-activity label, and one row can afford one long form, not two.
|
|
44
|
-
*/
|
|
45
|
-
export function formatCompactAge(isoTimestamp) {
|
|
46
|
-
const now = Date.now();
|
|
47
|
-
const then = new Date(isoTimestamp).getTime();
|
|
48
|
-
if (isNaN(then))
|
|
49
|
-
return isoTimestamp;
|
|
50
|
-
const diffMs = now - then;
|
|
51
|
-
const diffMin = Math.floor(diffMs / 60_000);
|
|
52
|
-
const diffHrs = Math.floor(diffMs / 3_600_000);
|
|
53
|
-
const diffDays = Math.floor(diffMs / 86_400_000);
|
|
54
|
-
if (diffMin < 1)
|
|
55
|
-
return 'now';
|
|
56
|
-
if (diffMin < 60)
|
|
57
|
-
return `${diffMin}m`;
|
|
58
|
-
if (diffHrs < 24)
|
|
59
|
-
return `${diffHrs}h`;
|
|
60
|
-
if (diffDays < 7)
|
|
61
|
-
return `${diffDays}d`;
|
|
62
|
-
return calendarLabel(then, now);
|
|
63
|
-
}
|
|
64
|
-
/**
|
|
65
|
-
* Shortest creation→last-activity gap worth rendering as two fields. Below it
|
|
66
|
-
* both halves name the same minute, so the row would carry a duplicate instead
|
|
67
|
-
* of information.
|
|
68
|
-
*/
|
|
69
|
-
const SPAN_MIN_MS = 60_000;
|
|
70
|
-
/**
|
|
71
|
-
* Split a session's timestamps into the two fields a listing renders: when it
|
|
72
|
-
* was created and when it was last active. One last-activity label answers
|
|
73
|
-
* neither "is this the old session I'm looking for" nor "how long did it run" —
|
|
74
|
-
* a session touched an hour ago may have started last week.
|
|
75
|
-
*/
|
|
76
|
-
export function sessionAgeParts(createdIso, lastActivityIso) {
|
|
77
|
-
const lastIso = lastActivityIso ?? createdIso;
|
|
78
|
-
const last = formatRelativeTime(lastIso);
|
|
79
|
-
const createdMs = new Date(createdIso).getTime();
|
|
80
|
-
const lastMs = new Date(lastIso).getTime();
|
|
81
|
-
if (isNaN(createdMs) || isNaN(lastMs) || lastMs - createdMs < SPAN_MIN_MS)
|
|
82
|
-
return { last };
|
|
83
|
-
return { created: formatCompactAge(createdIso), last };
|
|
84
|
-
}
|
|
85
|
-
/**
|
|
86
|
-
* Parse a time filter string (relative like '7d' or an ISO timestamp) into epoch
|
|
87
|
-
* milliseconds. Backs `--since` on `sessions`, `cost`, `teams`, and `output`, and
|
|
88
|
-
* `--unused` on `secrets list`.
|
|
89
|
-
*
|
|
90
|
-
* It lives here, in a module with no imports, rather than in `discover.ts` where
|
|
91
|
-
* it started: `discover.ts` loads `../sqlite.js`, so importing this one function
|
|
92
|
-
* from there pulls `node:sqlite` into the caller's module graph and Node prints
|
|
93
|
-
* `ExperimentalWarning: SQLite …` on stderr. That is invisible in a command that
|
|
94
|
-
* already touches the session DB, and a broken contract in one that doesn't —
|
|
95
|
-
* `monitors --json` asserts a clean stderr. `discover.ts` re-exports it, so
|
|
96
|
-
* existing importers are unaffected.
|
|
97
|
-
*/
|
|
98
|
-
export function parseTimeFilter(input) {
|
|
99
|
-
// Units: m=minute, h=hour, d=day, w=week, mo=month(30d), y=year(365d). `mo`
|
|
100
|
-
// must precede the single-letter alternatives so "1mo" isn't read as "1m"+"o".
|
|
101
|
-
const relativeMatch = input.match(/^(\d+)(mo|[mhdwy])$/i);
|
|
102
|
-
if (relativeMatch) {
|
|
103
|
-
const value = parseInt(relativeMatch[1], 10);
|
|
104
|
-
const unit = relativeMatch[2].toLowerCase();
|
|
105
|
-
if (unit === 'm')
|
|
106
|
-
return Date.now() - value * 60_000;
|
|
107
|
-
if (unit === 'h')
|
|
108
|
-
return Date.now() - value * 3_600_000;
|
|
109
|
-
if (unit === 'd')
|
|
110
|
-
return Date.now() - value * 86_400_000;
|
|
111
|
-
if (unit === 'w')
|
|
112
|
-
return Date.now() - value * 7 * 86_400_000;
|
|
113
|
-
if (unit === 'mo')
|
|
114
|
-
return Date.now() - value * 30 * 86_400_000;
|
|
115
|
-
if (unit === 'y')
|
|
116
|
-
return Date.now() - value * 365 * 86_400_000;
|
|
117
|
-
}
|
|
118
|
-
const ts = new Date(input).getTime();
|
|
119
|
-
return Number.isNaN(ts) ? 0 : ts;
|
|
120
|
-
}
|
|
1
|
+
// Moved to ../text/relative-time.ts (move 1 of the core-module refactor — see
|
|
2
|
+
// .agents/artifacts/2026-08-20/plan-*.md). Kept as a re-export shim so
|
|
3
|
+
// existing importers don't break.
|
|
4
|
+
export * from '../text/relative-time.js';
|
|
@@ -23,7 +23,7 @@ import { remoteShellFor, buildWindowsAgentsCommand, stripClixml } from '../hosts
|
|
|
23
23
|
import { gatherRemoteAgentsJson } from '../remote-agents-json.js';
|
|
24
24
|
import { machineId, normalizeHost } from './sync/config.js';
|
|
25
25
|
import { NO_FANOUT_ENV } from './remote-active.js';
|
|
26
|
-
import { terminalWidth } from '
|
|
26
|
+
import { terminalWidth } from '../text/width.js';
|
|
27
27
|
import { sanitizeForTerminal } from '../redact.js';
|
|
28
28
|
import { mapBounded } from '../concurrency.js';
|
|
29
29
|
import { TOOL_QUERY_MAX_CLAUSE_BYTES, TOOL_QUERY_MAX_CALL_ROWS, TOOL_QUERY_MAX_CLAUSES, TOOL_QUERY_MAX_RESULT_SESSIONS, TOOL_QUERY_MAX_SERIALIZED_BYTES, serializedToolSearchEnvelopeBytes, } from './tool-index.js';
|
|
@@ -32,8 +32,8 @@ import { SSH_OPTS, controlOpts, assertValidSshTarget } from '../ssh-exec.js';
|
|
|
32
32
|
import { remoteShellFor, buildWindowsAgentsCommand } from '../hosts/remote-cmd.js';
|
|
33
33
|
import { resolveRemoteOsSync } from '../hosts/remote-os.js';
|
|
34
34
|
import { NO_FANOUT_ENV } from './remote-active.js';
|
|
35
|
-
import { formatRelativeTime } from '
|
|
36
|
-
import { terminalWidth } from '
|
|
35
|
+
import { formatRelativeTime } from '../text/relative-time.js';
|
|
36
|
+
import { terminalWidth } from '../text/width.js';
|
|
37
37
|
/**
|
|
38
38
|
* POSIX single-quote a string for safe interpolation into a remote shell command.
|
|
39
39
|
* Always wraps (unlike the bare-passthrough variant in `ssh-exec.ts`) — the
|
|
@@ -1,17 +1 @@
|
|
|
1
|
-
|
|
2
|
-
* Canonical derivation of a session's 8-char `shortId`.
|
|
3
|
-
*
|
|
4
|
-
* Every session parser used to inline `id.slice(0, 8)` — some with a
|
|
5
|
-
* `.replace(prefix, '')` strip first (`session_`, `api-`, `ses_`). That strip is
|
|
6
|
-
* the bug: an id that is *only* its prefix (a bare `session_` directory, an id of
|
|
7
|
-
* exactly `api-`) strips to `''`, and `''.slice(0, 8)` is still `''`. An empty
|
|
8
|
-
* shortId then passes the `short_id TEXT NOT NULL` constraint (empty string is not
|
|
9
|
-
* NULL) yet matches nothing in the `short_id LIKE ?` picker lookups — a silently
|
|
10
|
-
* corrupt index row.
|
|
11
|
-
*
|
|
12
|
-
* This helper is the single source of truth: it strips the optional prefix, takes
|
|
13
|
-
* the first 8 chars, and — the whole point — guarantees a NON-EMPTY result by
|
|
14
|
-
* falling back to the unstripped id when the strip empties it, so a row always
|
|
15
|
-
* stays addressable by its shortId.
|
|
16
|
-
*/
|
|
17
|
-
export declare function deriveShortId(id: string, stripPrefix?: RegExp): string;
|
|
1
|
+
export * from '../text/short-id.js';
|
|
@@ -1,20 +1,4 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
*
|
|
5
|
-
* `.replace(prefix, '')` strip first (`session_`, `api-`, `ses_`). That strip is
|
|
6
|
-
* the bug: an id that is *only* its prefix (a bare `session_` directory, an id of
|
|
7
|
-
* exactly `api-`) strips to `''`, and `''.slice(0, 8)` is still `''`. An empty
|
|
8
|
-
* shortId then passes the `short_id TEXT NOT NULL` constraint (empty string is not
|
|
9
|
-
* NULL) yet matches nothing in the `short_id LIKE ?` picker lookups — a silently
|
|
10
|
-
* corrupt index row.
|
|
11
|
-
*
|
|
12
|
-
* This helper is the single source of truth: it strips the optional prefix, takes
|
|
13
|
-
* the first 8 chars, and — the whole point — guarantees a NON-EMPTY result by
|
|
14
|
-
* falling back to the unstripped id when the strip empties it, so a row always
|
|
15
|
-
* stays addressable by its shortId.
|
|
16
|
-
*/
|
|
17
|
-
export function deriveShortId(id, stripPrefix) {
|
|
18
|
-
const stripped = stripPrefix ? id.replace(stripPrefix, '') : id;
|
|
19
|
-
return stripped.slice(0, 8) || id.slice(0, 8) || id;
|
|
20
|
-
}
|
|
1
|
+
// Moved to ../text/short-id.ts (move 1 of the core-module refactor — see
|
|
2
|
+
// .agents/artifacts/2026-08-20/plan-*.md). Kept as a re-export shim so
|
|
3
|
+
// existing importers don't break.
|
|
4
|
+
export * from '../text/short-id.js';
|
|
@@ -1,29 +1 @@
|
|
|
1
|
-
|
|
2
|
-
* Terminal display-width helpers.
|
|
3
|
-
*
|
|
4
|
-
* `String.length` is the wrong ruler for a terminal: it over-counts ANSI colour
|
|
5
|
-
* escapes (chalk output) and under-counts wide glyphs (CJK, emoji) which occupy
|
|
6
|
-
* two cells. The result is the drifting, wrapping session-table line users see
|
|
7
|
-
* under tmux and over `--device` SSH. Every renderer that sizes a session-table
|
|
8
|
-
* cell measures and truncates through this module so alignment is computed once,
|
|
9
|
-
* correctly, from the same source of truth.
|
|
10
|
-
*/
|
|
11
|
-
/** Strip SGR colour + OSC-8 hyperlink escapes so width is measured on visible characters only. */
|
|
12
|
-
export declare function stripAnsi(s: string): string;
|
|
13
|
-
/** Visible display width of a string, ANSI-aware and wide-char-aware. */
|
|
14
|
-
export declare function stringWidth(s: string): number;
|
|
15
|
-
/**
|
|
16
|
-
* Truncate to a target display width, appending '…' when shortened. Operates on
|
|
17
|
-
* the visible (ANSI-stripped) string; callers colour the result afterwards so
|
|
18
|
-
* the ellipsis is never inserted mid-escape.
|
|
19
|
-
*/
|
|
20
|
-
export declare function truncateToWidth(s: string, max: number): string;
|
|
21
|
-
/** Right-pad with spaces to a target display width. Never truncates. */
|
|
22
|
-
export declare function padToWidth(s: string, width: number): string;
|
|
23
|
-
/**
|
|
24
|
-
* Effective terminal width. Reads `$COLUMNS` first so it survives tmux and
|
|
25
|
-
* `--device` SSH (where `process.stdout.columns` is unset or wrong), falls back to
|
|
26
|
-
* the TTY's reported width, then to `fallback`. Clamped to a sane band so a
|
|
27
|
-
* bogus value can't produce a 0-wide or absurdly long table.
|
|
28
|
-
*/
|
|
29
|
-
export declare function terminalWidth(fallback?: number): number;
|
|
1
|
+
export * from '../text/width.js';
|
|
@@ -1,101 +1,4 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
*
|
|
5
|
-
* escapes (chalk output) and under-counts wide glyphs (CJK, emoji) which occupy
|
|
6
|
-
* two cells. The result is the drifting, wrapping session-table line users see
|
|
7
|
-
* under tmux and over `--device` SSH. Every renderer that sizes a session-table
|
|
8
|
-
* cell measures and truncates through this module so alignment is computed once,
|
|
9
|
-
* correctly, from the same source of truth.
|
|
10
|
-
*/
|
|
11
|
-
/** SGR colour sequences emitted by chalk (e.g. `\x1b[32m`). */
|
|
12
|
-
const SGR_REGEX = /\x1b\[[0-9;]*m/g;
|
|
13
|
-
/**
|
|
14
|
-
* OSC-8 hyperlink sequences (`\x1b]8;;<url>\x1b\\` … `\x1b]8;;\x1b\\`, or with a
|
|
15
|
-
* BEL `\x07` terminator) emitted by `osc8()` in render.ts for clickable
|
|
16
|
-
* ticket/PR/path badges. These carry the URL, which is NOT visible — leaving it
|
|
17
|
-
* in over-counts width and, worse, lets a truncation land *inside* the escape and
|
|
18
|
-
* corrupt it. Stripping both the opener and closer leaves only the visible label
|
|
19
|
-
* between them, so width is measured on what the user sees and `truncateToWidth`
|
|
20
|
-
* can never cut a hyperlink in half.
|
|
21
|
-
*/
|
|
22
|
-
const OSC8_REGEX = /\x1b\]8;[^;]*;.*?(?:\x1b\\|\x07)/g;
|
|
23
|
-
/** Strip SGR colour + OSC-8 hyperlink escapes so width is measured on visible characters only. */
|
|
24
|
-
export function stripAnsi(s) {
|
|
25
|
-
return s.replace(OSC8_REGEX, '').replace(SGR_REGEX, '');
|
|
26
|
-
}
|
|
27
|
-
/**
|
|
28
|
-
* Display cells for one code point: 0 for zero-width combining/ZWJ/variation
|
|
29
|
-
* selectors, 2 for East-Asian-wide and emoji ranges, 1 otherwise. Compact and
|
|
30
|
-
* dependency-free — covers the glyphs that actually show up in prompts/titles.
|
|
31
|
-
*/
|
|
32
|
-
function charWidth(cp) {
|
|
33
|
-
if (cp === 0)
|
|
34
|
-
return 0;
|
|
35
|
-
// Zero-width: combining marks, zero-width joiner, variation selectors.
|
|
36
|
-
if ((cp >= 0x0300 && cp <= 0x036f) ||
|
|
37
|
-
cp === 0x200b || cp === 0x200d ||
|
|
38
|
-
(cp >= 0xfe00 && cp <= 0xfe0f))
|
|
39
|
-
return 0;
|
|
40
|
-
// Wide (2 cells): CJK, Hangul, fullwidth forms, emoji & pictographs.
|
|
41
|
-
if ((cp >= 0x1100 && cp <= 0x115f) || // Hangul Jamo
|
|
42
|
-
(cp >= 0x2e80 && cp <= 0xa4cf) || // CJK radicals … Yi
|
|
43
|
-
(cp >= 0xac00 && cp <= 0xd7a3) || // Hangul syllables
|
|
44
|
-
(cp >= 0xf900 && cp <= 0xfaff) || // CJK compatibility ideographs
|
|
45
|
-
(cp >= 0xfe30 && cp <= 0xfe4f) || // CJK compatibility forms
|
|
46
|
-
(cp >= 0xff00 && cp <= 0xff60) || // Fullwidth forms
|
|
47
|
-
(cp >= 0xffe0 && cp <= 0xffe6) || // Fullwidth signs
|
|
48
|
-
(cp >= 0x1f300 && cp <= 0x1faff) || // emoji & symbols
|
|
49
|
-
(cp >= 0x20000 && cp <= 0x3fffd) // CJK Ext-B and beyond
|
|
50
|
-
)
|
|
51
|
-
return 2;
|
|
52
|
-
return 1;
|
|
53
|
-
}
|
|
54
|
-
/** Visible display width of a string, ANSI-aware and wide-char-aware. */
|
|
55
|
-
export function stringWidth(s) {
|
|
56
|
-
const plain = stripAnsi(s);
|
|
57
|
-
let w = 0;
|
|
58
|
-
for (const ch of plain)
|
|
59
|
-
w += charWidth(ch.codePointAt(0));
|
|
60
|
-
return w;
|
|
61
|
-
}
|
|
62
|
-
/**
|
|
63
|
-
* Truncate to a target display width, appending '…' when shortened. Operates on
|
|
64
|
-
* the visible (ANSI-stripped) string; callers colour the result afterwards so
|
|
65
|
-
* the ellipsis is never inserted mid-escape.
|
|
66
|
-
*/
|
|
67
|
-
export function truncateToWidth(s, max) {
|
|
68
|
-
if (max <= 0)
|
|
69
|
-
return '';
|
|
70
|
-
const plain = stripAnsi(s);
|
|
71
|
-
if (stringWidth(plain) <= max)
|
|
72
|
-
return plain;
|
|
73
|
-
let w = 0;
|
|
74
|
-
let out = '';
|
|
75
|
-
for (const ch of plain) {
|
|
76
|
-
const cw = charWidth(ch.codePointAt(0));
|
|
77
|
-
if (w + cw > max - 1)
|
|
78
|
-
break; // reserve one cell for the ellipsis
|
|
79
|
-
out += ch;
|
|
80
|
-
w += cw;
|
|
81
|
-
}
|
|
82
|
-
return out + '…';
|
|
83
|
-
}
|
|
84
|
-
/** Right-pad with spaces to a target display width. Never truncates. */
|
|
85
|
-
export function padToWidth(s, width) {
|
|
86
|
-
const pad = width - stringWidth(s);
|
|
87
|
-
return pad > 0 ? s + ' '.repeat(pad) : s;
|
|
88
|
-
}
|
|
89
|
-
/**
|
|
90
|
-
* Effective terminal width. Reads `$COLUMNS` first so it survives tmux and
|
|
91
|
-
* `--device` SSH (where `process.stdout.columns` is unset or wrong), falls back to
|
|
92
|
-
* the TTY's reported width, then to `fallback`. Clamped to a sane band so a
|
|
93
|
-
* bogus value can't produce a 0-wide or absurdly long table.
|
|
94
|
-
*/
|
|
95
|
-
export function terminalWidth(fallback = 100) {
|
|
96
|
-
const env = Number.parseInt(process.env.COLUMNS ?? '', 10);
|
|
97
|
-
const raw = Number.isFinite(env) && env > 0
|
|
98
|
-
? env
|
|
99
|
-
: (process.stdout.columns || fallback);
|
|
100
|
-
return Math.max(60, Math.min(200, raw));
|
|
101
|
-
}
|
|
1
|
+
// Moved to ../text/width.ts (move 1 of the core-module refactor — see
|
|
2
|
+
// .agents/artifacts/2026-08-20/plan-*.md). Kept as a re-export shim so
|
|
3
|
+
// existing importers don't break.
|
|
4
|
+
export * from '../text/width.js';
|
package/dist/lib/snapshot.d.ts
CHANGED
|
@@ -8,7 +8,7 @@
|
|
|
8
8
|
*
|
|
9
9
|
* That is N+2 process starts per poll tick. This module gathers the same
|
|
10
10
|
* shapes in one invocation so poll count drops to 1 without redefining
|
|
11
|
-
* `agents status` (which stays the UnifiedSyncStatus sync contract).
|
|
11
|
+
* `agents sync status` (which stays the UnifiedSyncStatus sync contract).
|
|
12
12
|
*
|
|
13
13
|
* Stores are not merged — inventory still comes from view, active rows from
|
|
14
14
|
* sessions, blocks from feed. Only the reader is consolidated.
|
|
@@ -63,7 +63,7 @@ export interface FleetSnapshot {
|
|
|
63
63
|
agents: FleetAgentCounts;
|
|
64
64
|
/** Present when --with-feed. */
|
|
65
65
|
feed?: SnapshotFeedSummary;
|
|
66
|
-
/** Present when --with-sync (UnifiedSyncStatus; does not replace `agents status`). */
|
|
66
|
+
/** Present when --with-sync (UnifiedSyncStatus; does not replace `agents sync status`). */
|
|
67
67
|
sync?: UnifiedSyncStatus;
|
|
68
68
|
}
|
|
69
69
|
export interface ComputeSnapshotOptions {
|
package/dist/lib/snapshot.js
CHANGED
|
@@ -8,7 +8,7 @@
|
|
|
8
8
|
*
|
|
9
9
|
* That is N+2 process starts per poll tick. This module gathers the same
|
|
10
10
|
* shapes in one invocation so poll count drops to 1 without redefining
|
|
11
|
-
* `agents status` (which stays the UnifiedSyncStatus sync contract).
|
|
11
|
+
* `agents sync status` (which stays the UnifiedSyncStatus sync contract).
|
|
12
12
|
*
|
|
13
13
|
* Stores are not merged — inventory still comes from view, active rows from
|
|
14
14
|
* sessions, blocks from feed. Only the reader is consolidated.
|
|
@@ -21,7 +21,10 @@ export declare const KNOWN_TOP_LEVEL_COMMANDS: ReadonlySet<string>;
|
|
|
21
21
|
* under `agents artifacts share` (RUSH-2580). login/logout/budget/bench/mine/
|
|
22
22
|
* cost/output/profiles/snapshot/cp/resume/roster moved under nested homes
|
|
23
23
|
* (cli-surface-consolidate). `timeline` was removed as a duplicated surface —
|
|
24
|
-
* use `agents feed --filter updates` (RUSH-2692).
|
|
24
|
+
* use `agents feed --filter updates` (RUSH-2692). `status` moved under
|
|
25
|
+
* `agents sync status` (RUSH-2864). `tickets` was removed — use `linear`
|
|
26
|
+
* (linear-cli) (RUSH-2932). `alias` moved under `agents setup alias` (RUSH-2965).
|
|
27
|
+
* `inbox` was a pure alias of `agents feed` (RUSH-2984).
|
|
25
28
|
*/
|
|
26
29
|
export declare const RETIRED_TOP_LEVEL_COMMANDS: ReadonlySet<string>;
|
|
27
30
|
export declare function isKnownTopLevelCommand(name: string): boolean;
|
|
@@ -3,12 +3,12 @@ const LOADED_COMMAND_NAMES = [
|
|
|
3
3
|
'permissions', 'mcp', 'clis', 'subagents', 'plugins', 'workflows', 'add', 'use', 'list',
|
|
4
4
|
'remove', 'rm', 'purge', 'update', 'prune', 'import', 'registry', 'search', 'install',
|
|
5
5
|
'routines', 'monitors', 'projects', 'run', 'open', 'reconnect', 'fork', 'config',
|
|
6
|
-
'models', 'modes', 'trash', 'restore', 'doctor', 'apply',
|
|
6
|
+
'models', 'modes', 'trash', 'restore', 'doctor', 'apply',
|
|
7
7
|
'route', 'harness', 'harnesses', 'secrets', 'menubar', 'beta', 'sync',
|
|
8
8
|
'refresh-rules', 'factory', 'usage', 'insights', 'perf', 'trends',
|
|
9
|
-
'
|
|
9
|
+
'pty', 'tmux', 'watchdog', 'browser', 'computer', 'logs', 'events',
|
|
10
10
|
'ssh', 'devices', 'fleet', 'repos', 'repo', 'setup', 'uninstall', 'upgrade', 'sessions',
|
|
11
|
-
'teams', '
|
|
11
|
+
'teams', 'cloud', 'message', 'send', 'notify', 'feed',
|
|
12
12
|
'mailboxes', 'mailbox', 'serve', 'artifacts', 'unshare', 'audit', 'webhooks',
|
|
13
13
|
'humans', 'daemon',
|
|
14
14
|
];
|
|
@@ -41,7 +41,10 @@ export const KNOWN_TOP_LEVEL_COMMANDS = new Set([
|
|
|
41
41
|
* under `agents artifacts share` (RUSH-2580). login/logout/budget/bench/mine/
|
|
42
42
|
* cost/output/profiles/snapshot/cp/resume/roster moved under nested homes
|
|
43
43
|
* (cli-surface-consolidate). `timeline` was removed as a duplicated surface —
|
|
44
|
-
* use `agents feed --filter updates` (RUSH-2692).
|
|
44
|
+
* use `agents feed --filter updates` (RUSH-2692). `status` moved under
|
|
45
|
+
* `agents sync status` (RUSH-2864). `tickets` was removed — use `linear`
|
|
46
|
+
* (linear-cli) (RUSH-2932). `alias` moved under `agents setup alias` (RUSH-2965).
|
|
47
|
+
* `inbox` was a pure alias of `agents feed` (RUSH-2984).
|
|
45
48
|
*/
|
|
46
49
|
export const RETIRED_TOP_LEVEL_COMMANDS = new Set([
|
|
47
50
|
'webhook',
|
|
@@ -60,6 +63,10 @@ export const RETIRED_TOP_LEVEL_COMMANDS = new Set([
|
|
|
60
63
|
'set',
|
|
61
64
|
'share',
|
|
62
65
|
'timeline',
|
|
66
|
+
'status',
|
|
67
|
+
'tickets',
|
|
68
|
+
'alias',
|
|
69
|
+
'inbox',
|
|
63
70
|
]);
|
|
64
71
|
export function isKnownTopLevelCommand(name) {
|
|
65
72
|
return KNOWN_TOP_LEVEL_COMMANDS.has(name);
|
|
@@ -26,7 +26,7 @@ import { probeFleetStats, headroom } from '../devices/health.js';
|
|
|
26
26
|
import { loadDevicesSync } from '../devices/registry.js';
|
|
27
27
|
import { buildSshInvocation, writeAskpassShim } from '../devices/connect.js';
|
|
28
28
|
import { buildReadyProbeCommand, parseReadyProbe, viewAgentSignedIn, viewHasAgent, } from '../hosts/ready.js';
|
|
29
|
-
import { localMachineId } from '../
|
|
29
|
+
import { localMachineId } from '../origin-machine.js';
|
|
30
30
|
import { normalizeHost } from '../machine-id.js';
|
|
31
31
|
import { checkCliAvailable, checkCliSignedIn } from './agents.js';
|
|
32
32
|
/** Per-remote readiness probe budget — matches the health probe's short window
|