@shardflux/cli 0.17.0 → 0.18.0-next.5
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 +9 -4
- package/README.md +4 -3
- package/dist/agent-target-commands.js +3 -7
- package/dist/agent-targets.d.ts +15 -5
- package/dist/agent-targets.js +18 -8
- package/dist/args.js +2 -2
- package/dist/desktop-linux.d.ts +40 -0
- package/dist/desktop-linux.js +186 -0
- package/dist/device-approvals.js +5 -3
- package/dist/git-remote-bin.js +0 -0
- package/dist/main.js +2 -1
- package/dist/menubar.js +44 -4
- package/dist/onboarding.js +7 -5
- package/dist/t3-asar.d.ts +10 -0
- package/dist/t3-asar.js +91 -0
- package/dist/t3-launch.js +1 -1
- package/dist/t3-linux.d.ts +68 -0
- package/dist/t3-linux.js +343 -0
- package/dist/t3-mode.d.ts +16 -8
- package/dist/t3-mode.js +49 -27
- package/dist/t3-provider.d.ts +5 -3
- package/dist/t3-provider.js +12 -49
- package/dist/update.js +16 -0
- package/package.json +7 -19
package/dist/t3-mode.js
CHANGED
|
@@ -3,11 +3,12 @@
|
|
|
3
3
|
* thread, so the thread is made through T3's own server API, with a short-lived admin session that T3's own CLI
|
|
4
4
|
* issues and revokes, and T3 is brought to the front.
|
|
5
5
|
*
|
|
6
|
-
* - **ACP mode** (a T3 build with ACP providers, 0.0.46+): T3's server runs on this
|
|
7
|
-
* providers (`shard acp`, registered by every `shard` run). The thread is launched on the
|
|
8
|
-
* (`server-runtime.json`) over its WebSocket RPC (`orchestration.launchThread`) with the
|
|
9
|
-
* then gives the thread its own cloud VM. The session is issued by the T3 server the app
|
|
10
|
-
* (`ELECTRON_RUN_AS_NODE=1 <app>/Contents/MacOS/<exe> <app.asar>/apps/server/dist/bin.mjs auth session
|
|
6
|
+
* - **ACP mode** (a T3 build with ACP providers, 0.0.46+): T3's server runs on this computer (macOS or Linux) and
|
|
7
|
+
* Shardflux is one of its providers (`shard acp`, registered by every `shard` run). The thread is launched on the
|
|
8
|
+
* running desktop server (`server-runtime.json`) over its WebSocket RPC (`orchestration.launchThread`) with the
|
|
9
|
+
* Shardflux provider, which then gives the thread its own cloud VM. The session is issued by the T3 server the app
|
|
10
|
+
* bundles (`ELECTRON_RUN_AS_NODE=1 <app>/Contents/MacOS/<exe> <app.asar>/apps/server/dist/bin.mjs auth session
|
|
11
|
+
* issue`; on Linux the app's `t3code` with its `resources/app.asar`, or T3's own `~/.t3/bin/t3` for an AppImage).
|
|
11
12
|
* - **SSH mode** (stable 0.0.45): T3's server runs in the project VM. `T3_THREAD_SCRIPT` runs there and dispatches
|
|
12
13
|
* `thread.create` and `thread.turn.start` over loopback (POST /api/orchestration/dispatch).
|
|
13
14
|
*
|
|
@@ -19,13 +20,13 @@ import { spawn, spawnSync } from 'node:child_process';
|
|
|
19
20
|
import { randomUUID } from 'node:crypto';
|
|
20
21
|
import { readFileSync, realpathSync } from 'node:fs';
|
|
21
22
|
import { writePrivateFile } from "./credentials.js";
|
|
22
|
-
import { homedir } from 'node:os';
|
|
23
23
|
import { basename, join } from 'node:path';
|
|
24
24
|
import { setTimeout as delay } from 'node:timers/promises';
|
|
25
25
|
import { CodedError, UsageError, describeError } from "./errors.js";
|
|
26
26
|
import { AgentStateStore } from "./agent-state.js";
|
|
27
27
|
import { applicationDirs, desktopAppPath, t3Apps } from "./agent-targets.js";
|
|
28
|
-
import { configureT3Provider, t3BundleSupportsAcp } from "./t3-provider.js";
|
|
28
|
+
import { configureT3Provider, t3BundleSupportsAcp, t3HomeDir } from "./t3-provider.js";
|
|
29
|
+
import { linuxLastUsed, linuxServerCli, linuxSupportsAcp, openLinuxT3 } from "./t3-linux.js";
|
|
29
30
|
import { acpSignedIn } from "./acp-login.js";
|
|
30
31
|
import { AcpModelCache } from "./acp-models.js";
|
|
31
32
|
import { nativeModelOptions } from "./acp-catalog.js";
|
|
@@ -36,6 +37,7 @@ import { uploadInitialImages } from "./initial-prompt.js";
|
|
|
36
37
|
export const T3_BUNDLE_ID = 'com.t3tools.t3code';
|
|
37
38
|
/** Where each app's new conversations can open: Claude in a terminal, Claude Desktop, claude.ai or T3; Codex in the Codex app or T3. */
|
|
38
39
|
export const OPEN_IN_TARGETS = { claude: ['terminal', 'claude-desktop', 'web', 't3'], codex: ['codex-app', 't3'] };
|
|
40
|
+
export const openInTargets = (app, platform = process.platform) => platform === 'linux' && app === 'codex' ? ['terminal', 't3'] : OPEN_IN_TARGETS[app];
|
|
39
41
|
/** T3 0.0.45's built-in defaults (DEFAULT_MODEL_BY_PROVIDER), used only when T3 in the VM has not described its models yet. */
|
|
40
42
|
const T3_DEFAULT_MODEL = { claude: 'claude-fable-5-1', codex: 'gpt-6-astra' };
|
|
41
43
|
const T3_START_WAIT_MS = 30_000;
|
|
@@ -46,11 +48,16 @@ const isoDate = (raw) => {
|
|
|
46
48
|
const parsed = SPOTLIGHT_DATE.test(raw) ? new Date(raw.replace(' ', 'T').replace(' ', '')) : null;
|
|
47
49
|
return parsed && !Number.isNaN(parsed.getTime()) ? parsed.toISOString() : null;
|
|
48
50
|
};
|
|
49
|
-
/**
|
|
51
|
+
/**
|
|
52
|
+
* Native lookups that tests replace: Spotlight's last-used dates of app bundles, one `mdls` for all of them (macOS), or
|
|
53
|
+
* when each program last started, from its access time (Linux, t3-linux.ts).
|
|
54
|
+
*/
|
|
50
55
|
export const t3Native = {
|
|
51
|
-
lastUsedMany(paths, env) {
|
|
56
|
+
lastUsedMany(paths, env, platform = process.platform) {
|
|
52
57
|
if (!paths.length)
|
|
53
58
|
return {};
|
|
59
|
+
if (platform !== 'darwin')
|
|
60
|
+
return Object.fromEntries(paths.map(path => [path, linuxLastUsed(path)]));
|
|
54
61
|
const r = spawnSync('mdls', ['-name', 'kMDItemLastUsedDate', '-raw', ...paths], { env, encoding: 'utf8', input: '', timeout: 3000 });
|
|
55
62
|
// -raw separates the values with NUL; a bundle Spotlight has no date for prints "(null)".
|
|
56
63
|
const values = r.status === 0 ? r.stdout.split('\0').map(v => v.trim()) : [];
|
|
@@ -76,16 +83,16 @@ export function lastUsedDates(ctx, paths, now = Date.now()) {
|
|
|
76
83
|
catch { /* a cache only */ }
|
|
77
84
|
return dates;
|
|
78
85
|
}
|
|
86
|
+
/** Whether an installed T3 runs the Shardflux provider: its server has the ACP Registry driver (t3-asar.ts, t3-linux.ts). */
|
|
87
|
+
const supportsAcp = (app) => app.linux ? linuxSupportsAcp({ ...app, linux: app.linux }) : t3BundleSupportsAcp(app.path);
|
|
79
88
|
/** The installed T3 Code, preferring a build with ACP providers when several channels are installed. */
|
|
80
|
-
export function t3Install(env, platform = process.platform) {
|
|
81
|
-
const apps = t3Apps(
|
|
82
|
-
const acp = apps.find(
|
|
89
|
+
export function t3Install(env, platform = process.platform, dirs = applicationDirs(env, platform)) {
|
|
90
|
+
const apps = t3Apps(dirs, platform, env);
|
|
91
|
+
const acp = apps.find(supportsAcp);
|
|
83
92
|
const app = acp ?? apps[0];
|
|
84
|
-
return app ? { path: app.path, version: app.version, mode: acp ? 'acp' : 'ssh' } : undefined;
|
|
85
|
-
}
|
|
86
|
-
export function t3HomeDir(env) {
|
|
87
|
-
return env.T3CODE_HOME || join(env.HOME || homedir(), '.t3');
|
|
93
|
+
return app ? { path: app.path, version: app.version, mode: acp ? 'acp' : 'ssh', ...(app.linux ? { linux: app.linux } : {}) } : undefined;
|
|
88
94
|
}
|
|
95
|
+
export { t3HomeDir };
|
|
89
96
|
/** The Shardflux provider instance in T3's server settings (read only; every `shard` run writes it, see t3-provider.ts). */
|
|
90
97
|
export function t3ProviderRegistered(env) {
|
|
91
98
|
try {
|
|
@@ -137,7 +144,7 @@ export function openInFor(ctx, project, known = {}) {
|
|
|
137
144
|
const claudeDesktop = () => known.clients ? known.clients.includes('claude-desktop') : desktopAppPath(dirs, 'Claude.app', 'com.anthropic.claudefordesktop') !== undefined;
|
|
138
145
|
const valid = (app) => {
|
|
139
146
|
const value = saved[app];
|
|
140
|
-
if (typeof value !== 'string' || !
|
|
147
|
+
if (typeof value !== 'string' || !openInTargets(app).includes(value))
|
|
141
148
|
return undefined;
|
|
142
149
|
return value === 't3' ? (t3() ? value : undefined) : value === 'claude-desktop' ? (claudeDesktop() ? value : undefined) : value;
|
|
143
150
|
};
|
|
@@ -171,8 +178,8 @@ export function saveOpenIn(ctx, spec, status, clients) {
|
|
|
171
178
|
const [app, target, extra] = part.split('=').map(s => s.trim());
|
|
172
179
|
if (app !== 'claude' && app !== 'codex' || !target || extra !== undefined)
|
|
173
180
|
throw new UsageError('--open-in takes app=target pairs, e.g. claude=t3,codex=t3.');
|
|
174
|
-
if (!
|
|
175
|
-
throw new UsageError(`--open-in: ${app} opens in ${
|
|
181
|
+
if (!openInTargets(app).includes(target))
|
|
182
|
+
throw new UsageError(`--open-in: ${app} opens in ${openInTargets(app).join(', ')}.`);
|
|
176
183
|
if (target === 't3' && !status.installed)
|
|
177
184
|
throw t3NotInstalled();
|
|
178
185
|
if (!available(target, status, clients))
|
|
@@ -203,11 +210,16 @@ export function t3ThreadTitle(prompt) {
|
|
|
203
210
|
return line.length > 80 ? `${line.slice(0, 79).trimEnd()}…` : line;
|
|
204
211
|
}
|
|
205
212
|
/**
|
|
206
|
-
* Opens T3 Code (or brings it to the front): the install `shard` chose
|
|
207
|
-
* bundle id, so `open -b` could start another installed channel
|
|
213
|
+
* Opens T3 Code (or brings it to the front): the install `shard` chose. On macOS `open -a <path>` (every T3 channel
|
|
214
|
+
* shares one bundle id, so `open -b` could start another installed channel); on Linux its desktop entry with
|
|
215
|
+
* `gtk-launch`, else its program (t3-linux.ts).
|
|
208
216
|
*/
|
|
209
|
-
export async function openT3(env,
|
|
210
|
-
|
|
217
|
+
export async function openT3(env, install) {
|
|
218
|
+
if (!install)
|
|
219
|
+
throw t3NotInstalled();
|
|
220
|
+
if (install.linux)
|
|
221
|
+
return openLinuxT3(env, { path: install.path, version: install.version, linux: install.linux });
|
|
222
|
+
const child = spawn('open', ['-a', install.path], { env, stdio: 'ignore' });
|
|
211
223
|
await new Promise((resolve, reject) => {
|
|
212
224
|
const timer = setTimeout(() => { child.kill('SIGKILL'); reject(new Error('T3 Code did not open in time')); }, 10_000);
|
|
213
225
|
child.once('error', e => { clearTimeout(timer); reject(e); });
|
|
@@ -307,7 +319,7 @@ export async function localT3Server(ctx, install, waitMs = T3_START_WAIT_MS) {
|
|
|
307
319
|
const found = await runningServer(base, ctx.signal);
|
|
308
320
|
if (found)
|
|
309
321
|
return found;
|
|
310
|
-
await openT3(ctx.io.env, install
|
|
322
|
+
await openT3(ctx.io.env, install);
|
|
311
323
|
const deadline = Date.now() + waitMs;
|
|
312
324
|
while (Date.now() < deadline) {
|
|
313
325
|
await delay(500, undefined, { signal: ctx.signal });
|
|
@@ -317,7 +329,17 @@ export async function localT3Server(ctx, install, waitMs = T3_START_WAIT_MS) {
|
|
|
317
329
|
}
|
|
318
330
|
throw t3Unreachable(`T3 Code’s server did not answer within ${Math.round(waitMs / 1000)} s.`);
|
|
319
331
|
}
|
|
320
|
-
|
|
332
|
+
/**
|
|
333
|
+
* The server CLI the app bundles: on macOS the bundle's executable with `<app.asar>/apps/server/dist/bin.mjs`; on Linux
|
|
334
|
+
* the app's own executable the same way, or for an AppImage T3's own launcher (linuxServerCli).
|
|
335
|
+
*/
|
|
336
|
+
function serverCli(install, env) {
|
|
337
|
+
if (install.linux) {
|
|
338
|
+
const cli = linuxServerCli({ path: install.path, version: install.version, linux: install.linux }, t3HomeDir(env));
|
|
339
|
+
if (!cli)
|
|
340
|
+
throw t3Unreachable(`T3 Code has not written its command line launcher (${join(t3HomeDir(env), 'bin', 't3')}) yet.`, 'Open T3 Code once, then run this again.');
|
|
341
|
+
return cli;
|
|
342
|
+
}
|
|
321
343
|
const r = spawnSync('/usr/libexec/PlistBuddy', ['-c', 'Print :CFBundleExecutable', join(install.path, 'Contents', 'Info.plist')], { encoding: 'utf8', input: '', timeout: 2000 });
|
|
322
344
|
const exe = r.status === 0 ? r.stdout.trim() : '';
|
|
323
345
|
if (!exe || exe.includes('/'))
|
|
@@ -326,7 +348,7 @@ function serverCli(install) {
|
|
|
326
348
|
}
|
|
327
349
|
/** Runs the T3 server CLI the app bundles (Electron as Node), the same code the desktop runs as its backend. */
|
|
328
350
|
function t3Cli(ctx, install, args) {
|
|
329
|
-
const cli = serverCli(install);
|
|
351
|
+
const cli = serverCli(install, ctx.io.env);
|
|
330
352
|
return new Promise((resolve, reject) => {
|
|
331
353
|
const child = spawn(cli.command, [...cli.args, ...args], { env: { ...ctx.io.env, ELECTRON_RUN_AS_NODE: '1' }, stdio: ['ignore', 'pipe', 'pipe'], signal: ctx.signal });
|
|
332
354
|
let stdout = '', stderr = '';
|
|
@@ -601,7 +623,7 @@ export async function startAcpThread(ctx, install, folder, request, waitMs = CON
|
|
|
601
623
|
const id = objectValue(launched).threadId;
|
|
602
624
|
const t3ThreadId = typeof id === 'string' ? id : threadId;
|
|
603
625
|
// The thread exists from here on: T3 comes to the front first, and a failure after this names the thread.
|
|
604
|
-
const opened = await openT3(ctx.io.env, install
|
|
626
|
+
const opened = await openT3(ctx.io.env, install).then(() => undefined, (error) => error);
|
|
605
627
|
let conversation = null;
|
|
606
628
|
try {
|
|
607
629
|
conversation = await threadConversation(ctx, server, session, t3ThreadId, realpathSync(folder), known, waitMs);
|
package/dist/t3-provider.d.ts
CHANGED
|
@@ -1,6 +1,8 @@
|
|
|
1
|
-
/** Every shard invocation registers the one installed T3 provider without adding terminal noise. */
|
|
2
|
-
export declare function registerInstalledT3(env: Record<string, string | undefined>, dir: string, signal?: AbortSignal): Promise<void>;
|
|
3
|
-
/**
|
|
1
|
+
/** Every shard invocation registers the one installed T3 provider without adding terminal noise (macOS and Linux). */
|
|
2
|
+
export declare function registerInstalledT3(env: Record<string, string | undefined>, dir: string, signal?: AbortSignal, platform?: NodeJS.Platform): Promise<void>;
|
|
3
|
+
/** Whether a macOS T3 bundle's server has the ACP Registry driver (its Contents/Resources/app.asar; see t3-asar.ts). */
|
|
4
4
|
export declare function t3BundleSupportsAcp(app: string): boolean;
|
|
5
|
+
/** T3's home, as the desktop resolves it on macOS and Linux: T3CODE_HOME (trimmed), else ~/.t3. */
|
|
6
|
+
export declare function t3HomeDir(env: Record<string, string | undefined>): string;
|
|
5
7
|
/** Desktop 0.0.45 watches this server settings file, including symlink targets. No encrypted stores. */
|
|
6
8
|
export declare function configureT3Provider(env: Record<string, string | undefined>, dir: string, remove?: boolean, signal?: AbortSignal): Promise<boolean>;
|
package/dist/t3-provider.js
CHANGED
|
@@ -1,70 +1,33 @@
|
|
|
1
|
-
import { readFileSync, realpathSync
|
|
1
|
+
import { readFileSync, realpathSync } from 'node:fs';
|
|
2
2
|
import { homedir } from 'node:os';
|
|
3
3
|
import { dirname, join } from 'node:path';
|
|
4
4
|
import { writePrivateFile } from "./credentials.js";
|
|
5
5
|
import { withTargetLock } from "./target-lock.js";
|
|
6
6
|
import { installedTargets } from "./agent-targets.js";
|
|
7
|
+
import { t3ArchiveSupportsAcp } from "./t3-asar.js";
|
|
7
8
|
const ID = 'shardflux';
|
|
8
9
|
const provider = { driver: 'acpRegistry', displayName: 'Shardflux', enabled: true, config: { source: 'local', commandPath: 'shard', commandArgs: ['acp'] } };
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
if (process.platform !== 'darwin')
|
|
13
|
-
return;
|
|
14
|
-
if (!installedTargets(env).targets.includes('t3'))
|
|
10
|
+
/** Every shard invocation registers the one installed T3 provider without adding terminal noise (macOS and Linux). */
|
|
11
|
+
export async function registerInstalledT3(env, dir, signal, platform = process.platform) {
|
|
12
|
+
if (!installedTargets(env, platform).targets.includes('t3'))
|
|
15
13
|
return;
|
|
16
14
|
try {
|
|
17
15
|
await configureT3Provider(env, dir, false, signal);
|
|
18
16
|
}
|
|
19
17
|
catch { /* User-owned malformed or conflicting settings stay intact. */ }
|
|
20
18
|
}
|
|
21
|
-
/**
|
|
19
|
+
/** Whether a macOS T3 bundle's server has the ACP Registry driver (its Contents/Resources/app.asar; see t3-asar.ts). */
|
|
22
20
|
export function t3BundleSupportsAcp(app) {
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
return support.get(archive).capable;
|
|
29
|
-
fd = openSync(archive, 'r');
|
|
30
|
-
const sizes = Buffer.alloc(16);
|
|
31
|
-
if (readSync(fd, sizes, 0, 16, 0) !== 16)
|
|
32
|
-
return false;
|
|
33
|
-
const headerSize = sizes.readUInt32LE(12);
|
|
34
|
-
if (headerSize < 1 || headerSize > 16 << 20)
|
|
35
|
-
return false;
|
|
36
|
-
const header = Buffer.alloc(headerSize);
|
|
37
|
-
if (readSync(fd, header, 0, headerSize, 16) !== headerSize)
|
|
38
|
-
return false;
|
|
39
|
-
let entry = JSON.parse(header.toString());
|
|
40
|
-
for (const part of ['apps', 'server', 'dist', 'bin.mjs']) {
|
|
41
|
-
const child = entry.files?.[part];
|
|
42
|
-
if (!child)
|
|
43
|
-
return false;
|
|
44
|
-
entry = child;
|
|
45
|
-
}
|
|
46
|
-
const size = entry.size, offset = Number(entry.offset) + 8 + sizes.readUInt32LE(4);
|
|
47
|
-
if (!Number.isSafeInteger(size) || !size || size < 1 || size > 64 << 20 || !Number.isSafeInteger(offset) || offset < 16 || offset + size > stat.size)
|
|
48
|
-
return false;
|
|
49
|
-
const bytes = entry.unpacked ? readFileSync(join(`${archive}.unpacked`, 'apps/server/dist/bin.mjs')) : Buffer.alloc(size);
|
|
50
|
-
if (!entry.unpacked && readSync(fd, bytes, 0, size, offset) !== size)
|
|
51
|
-
return false;
|
|
52
|
-
const capable = /ProviderDriverKind\.make\(["']acpRegistry["']\)/.test(bytes.toString());
|
|
53
|
-
support.set(archive, { stamp, capable });
|
|
54
|
-
return capable;
|
|
55
|
-
}
|
|
56
|
-
catch {
|
|
57
|
-
return false;
|
|
58
|
-
}
|
|
59
|
-
finally {
|
|
60
|
-
if (fd !== undefined)
|
|
61
|
-
closeSync(fd);
|
|
62
|
-
}
|
|
21
|
+
return t3ArchiveSupportsAcp(join(app, 'Contents/Resources/app.asar'));
|
|
22
|
+
}
|
|
23
|
+
/** T3's home, as the desktop resolves it on macOS and Linux: T3CODE_HOME (trimmed), else ~/.t3. */
|
|
24
|
+
export function t3HomeDir(env) {
|
|
25
|
+
return env.T3CODE_HOME?.trim() || join(env.HOME || homedir(), '.t3');
|
|
63
26
|
}
|
|
64
27
|
/** Desktop 0.0.45 watches this server settings file, including symlink targets. No encrypted stores. */
|
|
65
28
|
export async function configureT3Provider(env, dir, remove = false, signal) {
|
|
66
29
|
return withTargetLock(dir, () => {
|
|
67
|
-
let file = join(
|
|
30
|
+
let file = join(t3HomeDir(env), 'userdata', 'settings.json');
|
|
68
31
|
let raw = '{}';
|
|
69
32
|
try {
|
|
70
33
|
file = realpathSync(file);
|
package/dist/update.js
CHANGED
|
@@ -264,6 +264,22 @@ export async function update(ctx, values, deps = {}) {
|
|
|
264
264
|
* runs the code from before the update).
|
|
265
265
|
*/
|
|
266
266
|
async function refreshMenubar(ctx, menubar, runtime, run, env) {
|
|
267
|
+
if (menubar.platform === 'linux') {
|
|
268
|
+
const { LinuxDesktopManager } = await import("./desktop-linux.js");
|
|
269
|
+
const desktop = new LinuxDesktopManager({ home: ctx.io.env.HOME, env: ctx.io.env });
|
|
270
|
+
const before = await desktop.status(ctx.store.dir);
|
|
271
|
+
if (!before.installed || new AgentStateStore(ctx.store.dir).read().menubar_stopped === true)
|
|
272
|
+
return { status: 'off' };
|
|
273
|
+
if (runtime && run && env) {
|
|
274
|
+
const result = await run([runtime.node, runtime.script, '--api-url', ctx.apiUrl, 'menubar', 'start', '--json'], { ...env, SHARDFLUX_CONFIG_DIR: ctx.store.dir, SHARDFLUX_NO_UPDATE_CHECK: '1' }, ctx.signal);
|
|
275
|
+
if (result.code !== 0)
|
|
276
|
+
return { status: 'failed' };
|
|
277
|
+
}
|
|
278
|
+
else
|
|
279
|
+
await desktop.start(ctx.store.dir, ctx.apiUrl);
|
|
280
|
+
const after = await desktop.status(ctx.store.dir);
|
|
281
|
+
return after.version !== before.version ? { status: 'restarted', version: after.version } : { status: 'current' };
|
|
282
|
+
}
|
|
267
283
|
if (menubar.platform !== 'darwin')
|
|
268
284
|
return { status: 'off' };
|
|
269
285
|
if (new AgentStateStore(ctx.store.dir).read().menubar_stopped === true)
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@shardflux/cli",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.18.0-next.5",
|
|
4
4
|
"type": "module",
|
|
5
5
|
"description": "shard: the Shardflux command line. Create an account, sign in, set up keys and billing, then open, run commands in, move files to, suspend, resume and fork serverless agent workspaces.",
|
|
6
6
|
"license": "Apache-2.0",
|
|
@@ -43,29 +43,17 @@
|
|
|
43
43
|
"access": "public"
|
|
44
44
|
},
|
|
45
45
|
"dependencies": {
|
|
46
|
+
"@shardflux/sdk": "0.24.0-next.5",
|
|
46
47
|
"classic-level": "3.0.0",
|
|
47
48
|
"smol-toml": "1.9.0",
|
|
48
49
|
"snappyjs": "0.7.0",
|
|
49
|
-
"yaml": "2.9.1"
|
|
50
|
-
"@shardflux/sdk": "^0.23.0"
|
|
51
|
-
},
|
|
52
|
-
"devDependencies": {
|
|
53
|
-
"@eslint/js": "10.0.1",
|
|
54
|
-
"@types/node": "24.13.6",
|
|
55
|
-
"eslint": "10.11.0",
|
|
56
|
-
"playwright": "1.62.1",
|
|
57
|
-
"typescript": "5.9.3",
|
|
58
|
-
"typescript-eslint": "8.70.1"
|
|
50
|
+
"yaml": "2.9.1"
|
|
59
51
|
},
|
|
60
52
|
"optionalDependencies": {
|
|
61
|
-
"@shardflux/menubar-darwin": "^0.5.0"
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
"build": "node scripts/build.mjs",
|
|
65
|
-
"typecheck": "tsc -p tsconfig.json --noEmit",
|
|
66
|
-
"lint": "eslint .",
|
|
67
|
-
"test": "node --test test/*.test.ts"
|
|
53
|
+
"@shardflux/menubar-darwin": "^0.5.0",
|
|
54
|
+
"@shardflux/desktop-linux-x64": "0.1.0-next.5",
|
|
55
|
+
"@shardflux/desktop-linux-arm64": "0.1.0-next.5"
|
|
68
56
|
},
|
|
69
57
|
"main": "./dist/index.js",
|
|
70
58
|
"types": "./dist/index.d.ts"
|
|
71
|
-
}
|
|
59
|
+
}
|