@shardflux/cli 0.20.0 → 0.22.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +214 -1
- package/README.md +215 -75
- package/dist/account-args.js +7 -2
- package/dist/account-commands.js +56 -106
- package/dist/account-pool.d.ts +19 -15
- package/dist/account-pool.js +47 -96
- package/dist/account-scope.d.ts +65 -0
- package/dist/account-scope.js +246 -0
- package/dist/acp-login.d.ts +4 -3
- package/dist/acp-login.js +7 -5
- package/dist/acp-models.js +20 -15
- package/dist/acp.js +66 -13
- package/dist/agent-commands.d.ts +4 -1
- package/dist/agent-commands.js +86 -32
- package/dist/agent-config-return.d.ts +46 -2
- package/dist/agent-config-return.js +110 -4
- package/dist/agent-credentials.js +7 -3
- package/dist/agent-repository.d.ts +16 -3
- package/dist/agent-repository.js +149 -74
- package/dist/agent-setup.d.ts +14 -3
- package/dist/agent-setup.js +78 -36
- package/dist/agent-target-commands.js +24 -13
- package/dist/args.d.ts +1 -1
- package/dist/args.js +94 -54
- package/dist/bin.js +5 -1
- package/dist/browser.d.ts +13 -2
- package/dist/browser.js +30 -14
- package/dist/claude-cloud-login.d.ts +24 -2
- package/dist/claude-cloud-login.js +151 -11
- package/dist/cli-proxy-forward.d.ts +2 -0
- package/dist/cli-proxy-forward.js +9 -2
- package/dist/cli-proxy-hub.d.ts +69 -25
- package/dist/cli-proxy-hub.js +231 -54
- package/dist/cli-proxy.d.ts +70 -1
- package/dist/cli-proxy.js +298 -32
- package/dist/client-settings.d.ts +39 -0
- package/dist/client-settings.js +91 -0
- package/dist/codex-cloud.d.ts +5 -0
- package/dist/codex-cloud.js +88 -17
- package/dist/command-center-actions.js +5 -1
- package/dist/commands.js +171 -22
- package/dist/conversation-commands.d.ts +5 -0
- package/dist/conversation-commands.js +8 -5
- package/dist/conversation-terminal.d.ts +10 -2
- package/dist/conversation-terminal.js +77 -13
- package/dist/conversations.d.ts +73 -1
- package/dist/conversations.js +257 -23
- package/dist/device-bridge.d.ts +1 -1
- package/dist/device-bridge.js +6 -4
- package/dist/device-helper.js +43 -22
- package/dist/errors.d.ts +27 -1
- package/dist/errors.js +45 -5
- package/dist/filesystem-commands.d.ts +16 -9
- package/dist/filesystem-commands.js +108 -54
- package/dist/format.d.ts +2 -1
- package/dist/format.js +10 -1
- package/dist/handlers.js +3 -1
- package/dist/initial-prompt.d.ts +8 -0
- package/dist/initial-prompt.js +43 -1
- package/dist/large-media.d.ts +14 -0
- package/dist/large-media.js +100 -0
- package/dist/linux-terminal.d.ts +5 -3
- package/dist/linux-terminal.js +6 -20
- package/dist/local-sessions.d.ts +26 -2
- package/dist/local-sessions.js +113 -24
- package/dist/machine-setup.d.ts +11 -1
- package/dist/machine-setup.js +69 -22
- package/dist/machine-status.d.ts +67 -0
- package/dist/machine-status.js +140 -0
- package/dist/main.js +11 -13
- package/dist/move-worktrees-restore.py +144 -0
- package/dist/move-worktrees.d.ts +63 -0
- package/dist/move-worktrees.js +201 -0
- package/dist/move.d.ts +10 -1
- package/dist/move.js +116 -16
- package/dist/onboarding.d.ts +11 -7
- package/dist/onboarding.js +59 -27
- package/dist/prepared-repository.d.ts +202 -0
- package/dist/prepared-repository.js +860 -0
- package/dist/prepared-repository.py +1306 -0
- package/dist/project-preparation.d.ts +48 -0
- package/dist/project-preparation.js +304 -0
- package/dist/project-sync-manifest.d.ts +4 -0
- package/dist/project-sync-manifest.js +5 -1
- package/dist/project-sync-transfer.js +1 -1
- package/dist/project-sync.d.ts +19 -4
- package/dist/project-sync.js +31 -8
- package/dist/project-template-setup.d.ts +33 -1
- package/dist/project-template-setup.js +59 -2
- package/dist/secret-ask.d.ts +72 -0
- package/dist/secret-ask.js +351 -0
- package/dist/seed-phases.d.ts +8 -1
- package/dist/seed-phases.js +17 -2
- package/dist/setup-cache.d.ts +7 -0
- package/dist/setup-cache.js +32 -0
- package/dist/t3-launch.js +1 -4
- package/dist/t3-mode.d.ts +8 -2
- package/dist/t3-mode.js +19 -4
- package/dist/t3-phone.d.ts +4 -2
- package/dist/t3-phone.js +12 -4
- package/dist/terminal-apps.d.ts +157 -0
- package/dist/terminal-apps.js +561 -0
- package/dist/terminal-onboarding.js +6 -1
- package/dist/this-computer.d.ts +11 -0
- package/dist/this-computer.js +36 -0
- package/dist/thread-on-computer.js +4 -1
- package/dist/update.js +11 -3
- package/dist/worktree-twin.d.ts +10 -2
- package/dist/worktree-twin.js +27 -9
- package/package.json +5 -5
|
@@ -20,6 +20,7 @@ import { promptWithImages, readInitialImages, readInitialPrompt, uploadInitialIm
|
|
|
20
20
|
import { recordSeedSnapshot } from "./files-mirror.js";
|
|
21
21
|
import { ensureCodexCloud, printCloudThread, submitCloudInitialPrompt } from "./codex-cloud.js";
|
|
22
22
|
import { modelChoice } from "./agent-models.js";
|
|
23
|
+
import { storedTitlePrefix } from "./client-settings.js";
|
|
23
24
|
const UUID = /^[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}$/i;
|
|
24
25
|
const SHA = /^[0-9a-f]{40}(?:[0-9a-f]{24})?$/;
|
|
25
26
|
/** A conversation still bound to its computer: not ended, archived or discarded (a settled `done` turn still is). */
|
|
@@ -168,9 +169,11 @@ export async function startThreadOn(ctx, values, path, explicitApp) {
|
|
|
168
169
|
const commit = await targetHead(ws, target, ctx.signal);
|
|
169
170
|
const baseBranch = target.base_branch ?? undefined;
|
|
170
171
|
await uploadInitialImages(ws.cell(), images, ctx.signal);
|
|
172
|
+
// This computer's title marker (0.20.1+); without one the thread keeps its computer's conversation's.
|
|
173
|
+
const titlePrefix = storedTitlePrefix(ctx.store.dir);
|
|
171
174
|
const response = await conversationClient(ctx).conversations.create({ projectId: target.project_id, repoRemote: target.repo_remote ?? ws.labels.repo_remote ?? '',
|
|
172
175
|
harness: app, route: app === 'codex' && !nativeCodex ? 'codex-cloud' : 'terminal', mode: 'join', parentId: target.id, ...(review ? { joinMode: 'reviewer' } : {}),
|
|
173
|
-
base: { commit, ...(baseBranch ? { branch: baseBranch } : {}) }, ...(name ? { name } : {}), ...choice }, { idempotencyKey: randomUUID(), signal: ctx.signal });
|
|
176
|
+
base: { commit, ...(baseBranch ? { branch: baseBranch } : {}) }, ...(name ? { name } : {}), ...choice, ...(titlePrefix !== undefined ? { titlePrefix } : {}) }, { idempotencyKey: randomUUID(), signal: ctx.signal });
|
|
174
177
|
let c = validateConversation({ ...response.conversation, restore: response.restore });
|
|
175
178
|
rememberConversation(ctx, c, project.folder, false, baseBranch);
|
|
176
179
|
store.save(projectKey, app);
|
package/dist/update.js
CHANGED
|
@@ -95,9 +95,11 @@ export function displayCommand(install, specs) {
|
|
|
95
95
|
case 'bun': return `bun add -g ${specs.join(' ')}`;
|
|
96
96
|
case 'volta': return `volta install ${specs.join(' ')}`;
|
|
97
97
|
case 'npx': return `npx ${specs[0]}`;
|
|
98
|
-
default: return `npm install -g ${specs.join(' ')}`;
|
|
98
|
+
default: return `npm install -g${install.manager === 'npm' && install.prefix ? ` --prefix ${shellQuote(install.prefix)}` : ''} ${specs.join(' ')}`;
|
|
99
99
|
}
|
|
100
100
|
}
|
|
101
|
+
/** Prefixes can contain spaces, quotes or shell substitutions. The actual install still uses argv. */
|
|
102
|
+
const shellQuote = (value) => `'${value.replaceAll("'", "'\\''")}'`;
|
|
101
103
|
const LABELS = { shardflux: 'shardflux', '@shardflux/cli': 'shard', '@shardflux/sdk': 'SDK', [MENUBAR]: 'menu bar', [MCP]: 'MCP server' };
|
|
102
104
|
/** Every local piece and its status against the catalog. */
|
|
103
105
|
export async function components(ctx, install, catalog, menubar = menubarManager(ctx)) {
|
|
@@ -225,12 +227,18 @@ export async function update(ctx, values, deps = {}) {
|
|
|
225
227
|
const result = await run(argv, env, ctx.signal);
|
|
226
228
|
if (result.code !== 0) {
|
|
227
229
|
const denied = /\bEACCES\b|\bEPERM\b/.test(result.output);
|
|
228
|
-
const
|
|
230
|
+
const home = ctx.io.env.HOME || homedir();
|
|
231
|
+
const userPrefix = join(home, '.local');
|
|
232
|
+
const recoverNpm = denied && install.manager === 'npm';
|
|
233
|
+
const fix = recoverNpm ? displayCommand({ ...install, prefix: userPrefix }, specs) : command;
|
|
229
234
|
const message = denied
|
|
230
235
|
? `${install.manager} cannot write to ${install.prefix ?? install.root}.`
|
|
231
236
|
: `${install.manager} failed: ${result.output.trim().split('\n').slice(-3).join(' ').slice(0, 400)}`;
|
|
232
237
|
writeLastUpdate(ctx.store.dir, { status: 'failed', changes: [], message, command: fix });
|
|
233
|
-
|
|
238
|
+
const hint = recoverNpm
|
|
239
|
+
? `run: ${fix}; then use ${shellQuote(join(userPrefix, 'bin', 'shard'))} instead of the old global shard. This leaves npm config and PATH unchanged.`
|
|
240
|
+
: `run: ${fix}`;
|
|
241
|
+
throw new CodedError(denied ? 'update_permission_denied' : 'update_failed', message, hint);
|
|
234
242
|
}
|
|
235
243
|
// The new shard reports what is installed now.
|
|
236
244
|
const after = await run([runtime.node, runtime.script, 'version', '--json'], { ...env, SHARDFLUX_NO_UPDATE_CHECK: '1' }, ctx.signal);
|
package/dist/worktree-twin.d.ts
CHANGED
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
import type { CellClient } from '@shardflux/sdk';
|
|
2
2
|
import { AgentStateStore } from './agent-state.js';
|
|
3
|
+
import type { OutsideFile } from './large-media.js';
|
|
3
4
|
/** A file the landing rewrites must be untouched this long first. */
|
|
4
5
|
export declare const QUIET_MS = 2000;
|
|
5
6
|
export declare const HUB_PATH = "/shardflux/project/git/hub.git";
|
|
@@ -49,10 +50,12 @@ export interface Snapshot {
|
|
|
49
50
|
root: string;
|
|
50
51
|
id: string;
|
|
51
52
|
headTree: string;
|
|
53
|
+
/** Large untracked media left out of the tree (large-media.ts): a start carries them as files beside it (0.22.0+). */
|
|
54
|
+
outside: OutsideFile[];
|
|
52
55
|
}
|
|
53
56
|
/**
|
|
54
|
-
* One snapshot commit of the worktree's working state (what `git add -A` sees, any file size; `.shard/`
|
|
55
|
-
* first parent HEAD. Kept as refs/shard/twin/<worktree id>; an unchanged state reuses it.
|
|
57
|
+
* One snapshot commit of the worktree's working state (what `git add -A` sees, any file size; `.shard/` and large
|
|
58
|
+
* untracked media left out), first parent HEAD. Kept as refs/shard/twin/<worktree id>; an unchanged state reuses it.
|
|
56
59
|
*/
|
|
57
60
|
export declare function snapshotWorktree(info: WorktreeInfo, options: {
|
|
58
61
|
device: string;
|
|
@@ -247,6 +250,8 @@ export interface TwinConversationState {
|
|
|
247
250
|
seed?: string;
|
|
248
251
|
seed_snapshot?: boolean;
|
|
249
252
|
folder?: string;
|
|
253
|
+
/** Large untracked media the seed snapshot left out (large-media.ts): the copy seed's VM repository ignores them. */
|
|
254
|
+
outside?: string[];
|
|
250
255
|
upto?: string;
|
|
251
256
|
tip?: string;
|
|
252
257
|
landed_revision?: string;
|
|
@@ -282,6 +287,7 @@ export declare function deviceId(stateDir: string): string;
|
|
|
282
287
|
export interface TwinSeed {
|
|
283
288
|
commit: string;
|
|
284
289
|
snapshot: boolean;
|
|
290
|
+
outside?: OutsideFile[];
|
|
285
291
|
}
|
|
286
292
|
/**
|
|
287
293
|
* The commit a new conversation starts from: HEAD when the worktree is clean (or landing is off, or the user's Git
|
|
@@ -306,4 +312,6 @@ export declare function twinCheckoutArgv(stateDir: string, conversation: {
|
|
|
306
312
|
base_commit: string;
|
|
307
313
|
worktree_path: string;
|
|
308
314
|
}): string[];
|
|
315
|
+
/** A gitignore line matching exactly this path from the worktree root (prepared-repository.py exclude_pattern). */
|
|
316
|
+
export declare function excludePattern(path: string): string;
|
|
309
317
|
export {};
|
package/dist/worktree-twin.js
CHANGED
|
@@ -18,6 +18,7 @@ import { basename, dirname, join, relative, resolve, sep } from 'node:path';
|
|
|
18
18
|
import { setTimeout as delay } from 'node:timers/promises';
|
|
19
19
|
import { AgentStateStore } from "./agent-state.js";
|
|
20
20
|
import { readSyncFileTo, writeSyncFileFrom } from "./project-sync-transfer.js";
|
|
21
|
+
import { largeUntrackedMedia, outsideSpecs } from "./large-media.js";
|
|
21
22
|
/** A file the landing rewrites must be untouched this long first. */
|
|
22
23
|
export const QUIET_MS = 2000;
|
|
23
24
|
export const HUB_PATH = '/shardflux/project/git/hub.git';
|
|
@@ -108,8 +109,8 @@ export const hubTwinRef = (device, id) => `refs/shard/twin/${device}/${id}`;
|
|
|
108
109
|
const identity = (now) => ({ GIT_AUTHOR_NAME: 'Shardflux', GIT_AUTHOR_EMAIL: 'twin@shardflux.dev', GIT_COMMITTER_NAME: 'Shardflux', GIT_COMMITTER_EMAIL: 'twin@shardflux.dev',
|
|
109
110
|
GIT_AUTHOR_DATE: `@${Math.floor(now.getTime() / 1000)} +0000`, GIT_COMMITTER_DATE: `@${Math.floor(now.getTime() / 1000)} +0000` });
|
|
110
111
|
/**
|
|
111
|
-
* One snapshot commit of the worktree's working state (what `git add -A` sees, any file size; `.shard/`
|
|
112
|
-
* first parent HEAD. Kept as refs/shard/twin/<worktree id>; an unchanged state reuses it.
|
|
112
|
+
* One snapshot commit of the worktree's working state (what `git add -A` sees, any file size; `.shard/` and large
|
|
113
|
+
* untracked media left out), first parent HEAD. Kept as refs/shard/twin/<worktree id>; an unchanged state reuses it.
|
|
113
114
|
*/
|
|
114
115
|
export async function snapshotWorktree(info, options) {
|
|
115
116
|
if (!info.head)
|
|
@@ -130,8 +131,10 @@ export async function snapshotWorktree(info, options) {
|
|
|
130
131
|
}
|
|
131
132
|
else
|
|
132
133
|
await git(info.root, ['read-tree', info.head], { env, signal });
|
|
133
|
-
// Every file, whatever its size
|
|
134
|
-
|
|
134
|
+
// Every file, whatever its size (Git stores large files as streamed loose objects), except untracked media: hashing
|
|
135
|
+
// and storing those cost seconds per snapshot (617 MB of media: 13.4 s), and they are not the user's code.
|
|
136
|
+
const outside = await largeUntrackedMedia(info.root, options.stateDir, id, signal);
|
|
137
|
+
const specs = ['.', ':(exclude).shard', ':(exclude,glob)**/.shard/**', ':(exclude,glob)**/*.shard-tmp-*', ...outsideSpecs(outside)];
|
|
135
138
|
await git(info.root, ['add', '-A', '--ignore-errors', '--pathspec-from-file=-', '--pathspec-file-nul'], { env, input: specs.join('\0') + '\0', signal });
|
|
136
139
|
const tree = await gitText(info.root, ['write-tree'], { env, signal });
|
|
137
140
|
const headTree = await gitText(info.root, ['rev-parse', `${info.head}^{tree}`], { signal });
|
|
@@ -147,7 +150,7 @@ export async function snapshotWorktree(info, options) {
|
|
|
147
150
|
commit = await gitText(info.root, ['commit-tree', tree, '-p', info.head, '-F', '-'], { env: identity(options.now ?? new Date()), input: message, signal });
|
|
148
151
|
await git(info.root, ['update-ref', twinRef(id), commit], { signal });
|
|
149
152
|
}
|
|
150
|
-
return { commit, tree, base: info.head, branch: info.branch, root: info.root, id, headTree };
|
|
153
|
+
return { commit, tree, base: info.head, branch: info.branch, root: info.root, id, headTree, outside };
|
|
151
154
|
}
|
|
152
155
|
finally {
|
|
153
156
|
rmSync(index, { force: true });
|
|
@@ -162,7 +165,7 @@ export async function refTwin(repo, branch, device, now = new Date()) {
|
|
|
162
165
|
const id = createHash('sha256').update(`${realpathSync(repo)}\0${branch}`).digest('hex').slice(0, 16);
|
|
163
166
|
const commit = await gitText(repo, ['commit-tree', tree, '-p', base, '-F', '-'], { env: identity(now), input: `Shardflux twin of ${branch}\n\n${SNAPSHOT_TRAILER}: ${device}/${id}\nShardflux-Branch: ${branch}\n` });
|
|
164
167
|
await git(repo, ['update-ref', twinRef(id), commit]);
|
|
165
|
-
return { commit, tree, base, branch, root: realpathSync(repo), id, headTree: tree };
|
|
168
|
+
return { commit, tree, base, branch, root: realpathSync(repo), id, headTree: tree, outside: [] };
|
|
166
169
|
}
|
|
167
170
|
async function rawDiff(cwd, a, b) {
|
|
168
171
|
const parts = (await git(cwd, ['diff-tree', '-r', '-z', '--raw', '--no-renames', '--no-abbrev', a, b])).stdout.toString('utf8').split('\0');
|
|
@@ -771,10 +774,11 @@ export async function twinSeed(stateDir, folder, head, project) {
|
|
|
771
774
|
if (info.head !== head || pauseReason(info))
|
|
772
775
|
return { commit: head, snapshot: false };
|
|
773
776
|
const snap = await snapshotWorktree(info, { device: deviceId(stateDir), stateDir });
|
|
774
|
-
return snap.tree === snap.headTree ? { commit: head, snapshot: false } : { commit: snap.commit, snapshot: true };
|
|
777
|
+
return snap.tree === snap.headTree ? { commit: head, snapshot: false, outside: snap.outside } : { commit: snap.commit, snapshot: true, outside: snap.outside };
|
|
775
778
|
}
|
|
776
779
|
export function rememberTwinSeed(stateDir, conversation, folder, seed, branch) {
|
|
777
|
-
new TwinLedger(stateDir).patch(conversation, { seed: seed.commit, seed_snapshot: seed.snapshot, folder, ...(branch ? { base_branch: branch } : {})
|
|
780
|
+
new TwinLedger(stateDir).patch(conversation, { seed: seed.commit, seed_snapshot: seed.snapshot, folder, ...(branch ? { base_branch: branch } : {}),
|
|
781
|
+
...(seed.outside?.length ? { outside: seed.outside.map(f => f.path) } : {}) });
|
|
778
782
|
}
|
|
779
783
|
/** Carries a snapshot seed into the conversation's VM repository (one small bundle: the snapshot over HEAD). */
|
|
780
784
|
export async function sendTwinSeed(stateDir, cell, conversation, folder, signal) {
|
|
@@ -804,5 +808,19 @@ export function twinCheckoutArgv(stateDir, conversation) {
|
|
|
804
808
|
const state = new TwinLedger(stateDir).conversation(conversation.id);
|
|
805
809
|
if (!state.seed_snapshot || state.seed !== conversation.base_commit)
|
|
806
810
|
return ['git', '-C', conversation.worktree_path, 'checkout', '-B', conversation.branch, conversation.base_commit];
|
|
807
|
-
|
|
811
|
+
// The copy seed copied the large media the snapshot left out: its Git ignores them too, as the user's sees them
|
|
812
|
+
// (untracked), so an agent never commits them and landing never meets them (0.22.0+).
|
|
813
|
+
const ignore = state.outside?.length ? `${EXCLUDE_BEGIN}\n${state.outside.map(excludePattern).join('\n')}\n${EXCLUDE_END}\n` : '';
|
|
814
|
+
return ['sh', '-c', 'set -e; git -C "$1" checkout -q -B "$2" HEAD; git -C "$1" reset -q --mixed "$3"; if [ -n "$4" ]; then printf %s "$4" >> "$1/.git/info/exclude"; fi',
|
|
815
|
+
'shard-seed', conversation.worktree_path, conversation.branch, conversation.base_commit, ignore];
|
|
816
|
+
}
|
|
817
|
+
/** The block prepared-repository.py writes for the same files (EXCLUDE_BEGIN/END, exclude_pattern). */
|
|
818
|
+
const EXCLUDE_BEGIN = '# shardflux: large files outside the snapshot (begin)', EXCLUDE_END = '# shardflux: (end)';
|
|
819
|
+
/** A gitignore line matching exactly this path from the worktree root (prepared-repository.py exclude_pattern). */
|
|
820
|
+
export function excludePattern(path) {
|
|
821
|
+
let s = [...path].map(c => '\\*?['.includes(c) ? `\\${c}` : c).join('');
|
|
822
|
+
if (s.startsWith('!') || s.startsWith('#'))
|
|
823
|
+
s = `\\${s}`;
|
|
824
|
+
const stripped = s.replace(/ +$/, '');
|
|
825
|
+
return `/${stripped}${'\\ '.repeat(s.length - stripped.length)}`;
|
|
808
826
|
}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@shardflux/cli",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.22.0",
|
|
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",
|
|
@@ -47,7 +47,7 @@
|
|
|
47
47
|
"smol-toml": "1.9.0",
|
|
48
48
|
"snappyjs": "0.7.0",
|
|
49
49
|
"yaml": "2.9.1",
|
|
50
|
-
"@shardflux/sdk": "^0.
|
|
50
|
+
"@shardflux/sdk": "^0.26.0"
|
|
51
51
|
},
|
|
52
52
|
"devDependencies": {
|
|
53
53
|
"@eslint/js": "10.0.1",
|
|
@@ -58,9 +58,9 @@
|
|
|
58
58
|
"typescript-eslint": "8.70.1"
|
|
59
59
|
},
|
|
60
60
|
"optionalDependencies": {
|
|
61
|
-
"@shardflux/desktop-linux-x64": "0.1.
|
|
62
|
-
"@shardflux/desktop-linux-arm64": "0.1.
|
|
63
|
-
"@shardflux/menubar-darwin": "^0.8.
|
|
61
|
+
"@shardflux/desktop-linux-x64": "0.1.8",
|
|
62
|
+
"@shardflux/desktop-linux-arm64": "0.1.8",
|
|
63
|
+
"@shardflux/menubar-darwin": "^0.8.3"
|
|
64
64
|
},
|
|
65
65
|
"scripts": {
|
|
66
66
|
"build": "node scripts/build.mjs",
|