flyspace-cli 0.1.29 → 0.1.30
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/dist/cli.js +80 -40
- package/package.json +7 -2
package/dist/cli.js
CHANGED
|
@@ -1835,7 +1835,7 @@ async function runAuthCmd(args) {
|
|
|
1835
1835
|
}
|
|
1836
1836
|
|
|
1837
1837
|
// ../api/src/version.ts
|
|
1838
|
-
var CLI_VERSION = true ? "0.1.
|
|
1838
|
+
var CLI_VERSION = true ? "0.1.30" : null;
|
|
1839
1839
|
function isOlderVersion(a, b) {
|
|
1840
1840
|
const parse = (v) => v.replace(/^v/, "").split("-")[0].split(".").map(Number);
|
|
1841
1841
|
const [pa, pb] = [parse(a), parse(b)];
|
|
@@ -2108,11 +2108,11 @@ async function serverReachable() {
|
|
|
2108
2108
|
return err.cause ? String(err.cause) : err.message;
|
|
2109
2109
|
}
|
|
2110
2110
|
}
|
|
2111
|
-
function checkService(name, installed, file,
|
|
2111
|
+
function checkService(name, installed, file, running2, fix) {
|
|
2112
2112
|
if (!installed) bad2(`${name} not installed`, `run: ${fix}`);
|
|
2113
2113
|
else if (serviceBinaryMissing(file))
|
|
2114
2114
|
bad2(`${name} points at a CLI that no longer exists`, `run: ${fix}`);
|
|
2115
|
-
else if (!
|
|
2115
|
+
else if (!running2) bad2(`${name} not running`, `logs: ${tilde3(paths.LOG_DIR)}`);
|
|
2116
2116
|
else ok2(`${name} running`);
|
|
2117
2117
|
}
|
|
2118
2118
|
async function runDoctor(args) {
|
|
@@ -2418,7 +2418,7 @@ function npmEnv() {
|
|
|
2418
2418
|
return home2 ? { ...process.env, PATH: `${join11(home2, "node", "bin")}:${process.env.PATH ?? ""}` } : process.env;
|
|
2419
2419
|
}
|
|
2420
2420
|
async function runUpgrade() {
|
|
2421
|
-
const current = "0.1.
|
|
2421
|
+
const current = "0.1.30";
|
|
2422
2422
|
console.log(`Current version: ${current}`);
|
|
2423
2423
|
console.log("Checking for updates...\n");
|
|
2424
2424
|
try {
|
|
@@ -6348,10 +6348,10 @@ async function runMcpCmd(args) {
|
|
|
6348
6348
|
}
|
|
6349
6349
|
|
|
6350
6350
|
// src/commands/dashboard.ts
|
|
6351
|
-
import { spawn as
|
|
6351
|
+
import { spawn as spawn8, spawnSync } from "child_process";
|
|
6352
6352
|
import { existsSync as existsSync32 } from "fs";
|
|
6353
6353
|
import { platform as platform7 } from "os";
|
|
6354
|
-
import { join as
|
|
6354
|
+
import { join as join29 } from "path";
|
|
6355
6355
|
|
|
6356
6356
|
// src/reconcile.ts
|
|
6357
6357
|
import { existsSync as existsSync14, mkdirSync as mkdirSync8, writeFileSync as writeFileSync8 } from "fs";
|
|
@@ -7398,8 +7398,8 @@ var inFlight = /* @__PURE__ */ new Map();
|
|
|
7398
7398
|
async function readOrCreateTranslation(input2) {
|
|
7399
7399
|
const contentHash = translationHash(input2.title, input2.content);
|
|
7400
7400
|
const key = `${input2.shareId}:${contentHash}:${input2.lang}`;
|
|
7401
|
-
const
|
|
7402
|
-
if (
|
|
7401
|
+
const running2 = inFlight.get(key);
|
|
7402
|
+
if (running2) return running2;
|
|
7403
7403
|
const job = (async () => {
|
|
7404
7404
|
const cached = await getDocShareTranslation(input2.shareId, input2.lang, contentHash);
|
|
7405
7405
|
if (cached) return cached;
|
|
@@ -8805,6 +8805,9 @@ async function verifyTurnstileToken(token) {
|
|
|
8805
8805
|
return data.action === void 0 || data.action === "login";
|
|
8806
8806
|
}
|
|
8807
8807
|
|
|
8808
|
+
// ../api/src/dashboard/onboarding-routes.ts
|
|
8809
|
+
import { Hono as Hono7 } from "hono";
|
|
8810
|
+
|
|
8808
8811
|
// ../api/src/store/device-store.ts
|
|
8809
8812
|
import { createHash as createHash7, createPublicKey as createPublicKey2, randomBytes as randomBytes4, randomInt } from "crypto";
|
|
8810
8813
|
var DEVICE_CODE_TTL_MS = 10 * 6e4;
|
|
@@ -9031,9 +9034,6 @@ async function userEmail(userId) {
|
|
|
9031
9034
|
return data.user?.email ?? null;
|
|
9032
9035
|
}
|
|
9033
9036
|
|
|
9034
|
-
// ../api/src/dashboard/onboarding-routes.ts
|
|
9035
|
-
import { Hono as Hono7 } from "hono";
|
|
9036
|
-
|
|
9037
9037
|
// ../api/src/dashboard/agent-bridge-data.ts
|
|
9038
9038
|
import { randomBytes as randomBytes5, randomUUID as randomUUID2, verify as verifyRaw } from "crypto";
|
|
9039
9039
|
import { WebSocket, WebSocketServer } from "ws";
|
|
@@ -9207,6 +9207,11 @@ var CHANNEL_NAME_RE = /^[a-z0-9][a-z0-9-]*$/;
|
|
|
9207
9207
|
function isWorkspaceOwner(ctx) {
|
|
9208
9208
|
return ctx?.role === "admin" && !ctx.isSupport;
|
|
9209
9209
|
}
|
|
9210
|
+
async function isHostOwner(ctx) {
|
|
9211
|
+
if (ctx.role !== "admin") return false;
|
|
9212
|
+
if (ctx.isSupport) return true;
|
|
9213
|
+
return (await listWorkspaceDevices(ctx.workspaceId)).some((d) => d.userId === ctx.userId);
|
|
9214
|
+
}
|
|
9210
9215
|
function hostUnavailable(c, agent, method) {
|
|
9211
9216
|
return c.json({ error: "host offline", reason: agent.getHostCallFailure?.(method) ?? "offline" }, 503);
|
|
9212
9217
|
}
|
|
@@ -9389,7 +9394,7 @@ function createAuthRouter() {
|
|
|
9389
9394
|
owner: isWorkspaceOwner(ctx),
|
|
9390
9395
|
// Only the Host's owner can run `flyspace upgrade` on it, so other
|
|
9391
9396
|
// admins never see the upgrade banner. Support staff can tell them to.
|
|
9392
|
-
hostOwner:
|
|
9397
|
+
hostOwner: await isHostOwner(ctx)
|
|
9393
9398
|
});
|
|
9394
9399
|
});
|
|
9395
9400
|
auth.patch("/handle", async (c) => {
|
|
@@ -10057,8 +10062,8 @@ async function translateThread(threadId, lang, messages) {
|
|
|
10057
10062
|
if (messages.length === 0) return [];
|
|
10058
10063
|
const shape = createHash8("sha256").update(messages.map((m) => translationHash2(m.author, m.body)).join("\n")).digest("hex");
|
|
10059
10064
|
const key = `${threadId}:${lang}:${shape}`;
|
|
10060
|
-
const
|
|
10061
|
-
if (
|
|
10065
|
+
const running2 = inFlight4.get(key);
|
|
10066
|
+
if (running2) return running2;
|
|
10062
10067
|
const job = (async () => {
|
|
10063
10068
|
const hashes = messages.map((m) => ({
|
|
10064
10069
|
replyId: m.id,
|
|
@@ -13701,6 +13706,7 @@ async function resolveThreadLinks(sessions2) {
|
|
|
13701
13706
|
}
|
|
13702
13707
|
|
|
13703
13708
|
// ../api/src/dashboard/data-api.ts
|
|
13709
|
+
var SELF_UPGRADE_MIN_VERSION = "0.1.30";
|
|
13704
13710
|
function registerDataRoutes(api, agent = {}) {
|
|
13705
13711
|
api.get("/profile", (c) => c.json({ profile: getProfile() }));
|
|
13706
13712
|
api.get("/host/status", async (c) => {
|
|
@@ -13714,7 +13720,20 @@ function registerDataRoutes(api, agent = {}) {
|
|
|
13714
13720
|
const cliVersion = agent.getHostCliVersion?.(getProfile()) ?? null;
|
|
13715
13721
|
const latest2 = cliVersion ? await latestCliVersion() : null;
|
|
13716
13722
|
const outdated = !!(cliVersion && latest2 && isOlderVersion(cliVersion, latest2));
|
|
13717
|
-
|
|
13723
|
+
const selfUpgrade = !!cliVersion && !isOlderVersion(cliVersion, SELF_UPGRADE_MIN_VERSION);
|
|
13724
|
+
return c.json({
|
|
13725
|
+
online: !paused,
|
|
13726
|
+
cliVersion,
|
|
13727
|
+
selfUpgrade,
|
|
13728
|
+
...outdated ? { latestCliVersion: latest2 } : {}
|
|
13729
|
+
});
|
|
13730
|
+
});
|
|
13731
|
+
api.post("/host/upgrade", async (c) => {
|
|
13732
|
+
const auth = c.get("auth");
|
|
13733
|
+
if (!await isHostOwner(auth)) return c.json({ error: "only the Host owner can upgrade it" }, 403);
|
|
13734
|
+
const res = await agent.upgradeHost?.();
|
|
13735
|
+
if (!res) return c.json({ error: "Host is offline" }, 503);
|
|
13736
|
+
return c.json(res, 202);
|
|
13718
13737
|
});
|
|
13719
13738
|
api.get("/channels", async (c) => {
|
|
13720
13739
|
const auth = c.get("auth");
|
|
@@ -13902,9 +13921,9 @@ function registerDataRoutes(api, agent = {}) {
|
|
|
13902
13921
|
void broadcastHostStatusChange();
|
|
13903
13922
|
let cancelled = 0;
|
|
13904
13923
|
if (body.paused) {
|
|
13905
|
-
const
|
|
13906
|
-
if (
|
|
13907
|
-
const { data } = await getSupabaseClient().from("threads").select("id, channel_id").in("id",
|
|
13924
|
+
const running2 = await agent.listAgentRuns?.() ?? [];
|
|
13925
|
+
if (running2.length > 0) {
|
|
13926
|
+
const { data } = await getSupabaseClient().from("threads").select("id, channel_id").in("id", running2);
|
|
13908
13927
|
const profile = getProfile();
|
|
13909
13928
|
for (const t of data ?? []) {
|
|
13910
13929
|
if (findOwningProfile(t.channel_id) !== profile) continue;
|
|
@@ -13922,7 +13941,7 @@ function registerDataRoutes(api, agent = {}) {
|
|
|
13922
13941
|
const host = trustedHost(c);
|
|
13923
13942
|
const known = await listKnownWorkspaces();
|
|
13924
13943
|
const hostProfile = profileFromHost(host, known);
|
|
13925
|
-
const
|
|
13944
|
+
const running2 = new Set(await agent.listRunningProfiles?.() ?? []);
|
|
13926
13945
|
const auth = c.get("auth");
|
|
13927
13946
|
const [{ data: memberships }, workspaces] = await Promise.all([
|
|
13928
13947
|
getSupabaseClient().from("memberships").select("workspace_id").eq("user_id", auth.userId),
|
|
@@ -13939,7 +13958,7 @@ function registerDataRoutes(api, agent = {}) {
|
|
|
13939
13958
|
return {
|
|
13940
13959
|
name,
|
|
13941
13960
|
active: name === active,
|
|
13942
|
-
running:
|
|
13961
|
+
running: running2.has(name),
|
|
13943
13962
|
displayName: branding.displayName,
|
|
13944
13963
|
logo: branding.logo,
|
|
13945
13964
|
hostname: (hostProfile ? workspaceHostname(host, name) : null) ?? void 0
|
|
@@ -14313,16 +14332,16 @@ function installSkillSync(profiles, options = {}) {
|
|
|
14313
14332
|
if (!databaseReachable()) return () => {
|
|
14314
14333
|
};
|
|
14315
14334
|
const { intervalMs = SYNC_INTERVAL_MS, onError = (e) => console.error("[skill-sync]", e) } = options;
|
|
14316
|
-
let
|
|
14335
|
+
let running2 = false;
|
|
14317
14336
|
const tick = async () => {
|
|
14318
|
-
if (
|
|
14319
|
-
|
|
14337
|
+
if (running2) return;
|
|
14338
|
+
running2 = true;
|
|
14320
14339
|
try {
|
|
14321
14340
|
for (const profile of profiles) {
|
|
14322
14341
|
await runWithProfile(profile, () => pushSkillScopes()).catch(onError);
|
|
14323
14342
|
}
|
|
14324
14343
|
} finally {
|
|
14325
|
-
|
|
14344
|
+
running2 = false;
|
|
14326
14345
|
}
|
|
14327
14346
|
};
|
|
14328
14347
|
void tick();
|
|
@@ -14874,8 +14893,8 @@ var inFlight5 = /* @__PURE__ */ new Map();
|
|
|
14874
14893
|
async function readOrCreateDocTranslation(input2) {
|
|
14875
14894
|
const contentHash = translationHash(input2.title, input2.content);
|
|
14876
14895
|
const key = `${input2.channelId}:${input2.sourcePath}:${contentHash}:${input2.lang}`;
|
|
14877
|
-
const
|
|
14878
|
-
if (
|
|
14896
|
+
const running2 = inFlight5.get(key);
|
|
14897
|
+
if (running2) return running2;
|
|
14879
14898
|
const job = (async () => {
|
|
14880
14899
|
const cached = await getDocTranslation(input2.channelId, input2.sourcePath, input2.lang, contentHash);
|
|
14881
14900
|
if (cached) return cached;
|
|
@@ -18832,6 +18851,26 @@ function readDocShareBundle({ cwd, sourcePath }) {
|
|
|
18832
18851
|
return { status: "ok", kind, title, content: content + renderAttachments(attachments), assets };
|
|
18833
18852
|
}
|
|
18834
18853
|
|
|
18854
|
+
// src/dashboard/host-upgrade.ts
|
|
18855
|
+
import { spawn as spawn7 } from "child_process";
|
|
18856
|
+
import { mkdirSync as mkdirSync13, openSync as openSync3 } from "fs";
|
|
18857
|
+
import { join as join27 } from "path";
|
|
18858
|
+
var running = false;
|
|
18859
|
+
function startHostUpgrade() {
|
|
18860
|
+
if (running) return { started: false };
|
|
18861
|
+
mkdirSync13(paths.LOG_DIR, { recursive: true });
|
|
18862
|
+
const log5 = openSync3(join27(paths.LOG_DIR, "host-upgrade.log"), "a");
|
|
18863
|
+
const child = spawn7(process.execPath, [process.argv[1] ?? "", "upgrade"], {
|
|
18864
|
+
detached: true,
|
|
18865
|
+
stdio: ["ignore", log5, log5]
|
|
18866
|
+
});
|
|
18867
|
+
running = true;
|
|
18868
|
+
child.on("exit", () => running = false);
|
|
18869
|
+
child.on("error", () => running = false);
|
|
18870
|
+
child.unref();
|
|
18871
|
+
return { started: true };
|
|
18872
|
+
}
|
|
18873
|
+
|
|
18835
18874
|
// src/dashboard/agent-bridge-host.ts
|
|
18836
18875
|
var HOSTED_DATA_SOCKET_ORIGIN = "wss://flyspace-api.fly.dev";
|
|
18837
18876
|
function dataSocketUrl() {
|
|
@@ -18872,6 +18911,7 @@ function localAgentCallbacks(chatAgent) {
|
|
|
18872
18911
|
docsRequest: (req) => handleDocsRequest(req),
|
|
18873
18912
|
hostRequest: (req) => handleHostRequest(req),
|
|
18874
18913
|
listSessions: () => listLocalSessions(),
|
|
18914
|
+
upgradeHost: () => startHostUpgrade(),
|
|
18875
18915
|
scanOnboarding: (slug) => scanOnboarding(slug),
|
|
18876
18916
|
linkProjectFolders: (slug, items) => linkProjectFolders(slug, items),
|
|
18877
18917
|
isHostOnline: () => true
|
|
@@ -19129,7 +19169,7 @@ function startPushWatcher() {
|
|
|
19129
19169
|
|
|
19130
19170
|
// src/dashboard/machine-server.ts
|
|
19131
19171
|
import { existsSync as existsSync31 } from "fs";
|
|
19132
|
-
import { join as
|
|
19172
|
+
import { join as join28 } from "path";
|
|
19133
19173
|
import { serveStatic } from "@hono/node-server/serve-static";
|
|
19134
19174
|
|
|
19135
19175
|
// src/dashboard/app-icon-routes.ts
|
|
@@ -19211,7 +19251,7 @@ function pngResponse(c, png) {
|
|
|
19211
19251
|
}
|
|
19212
19252
|
|
|
19213
19253
|
// src/dashboard/machine-server.ts
|
|
19214
|
-
var WEB_DIST =
|
|
19254
|
+
var WEB_DIST = join28(paths.WEB_ROOT, "dist");
|
|
19215
19255
|
async function bootMachine() {
|
|
19216
19256
|
await reconcileAll().catch(
|
|
19217
19257
|
(err) => console.error("[dashboard] reconcileAll failed:", err.message)
|
|
@@ -19231,14 +19271,14 @@ async function bootMachine() {
|
|
|
19231
19271
|
function mountSpa(app) {
|
|
19232
19272
|
app.route("/share", createPublicShareAssetRouter(WEB_DIST));
|
|
19233
19273
|
app.route("/", createAppIconRouter());
|
|
19234
|
-
if (existsSync31(WEB_DIST) || existsSync31(
|
|
19274
|
+
if (existsSync31(WEB_DIST) || existsSync31(join28(paths.WEB_ROOT, "package.json"))) {
|
|
19235
19275
|
app.use("/*", serveStatic({ root: WEB_DIST }));
|
|
19236
19276
|
}
|
|
19237
19277
|
app.get("/assets/*", (c) => c.text("stale asset \u2014 reload for the current build", 404));
|
|
19238
|
-
const spaFallback = serveStatic({ path:
|
|
19278
|
+
const spaFallback = serveStatic({ path: join28(WEB_DIST, "index.html") });
|
|
19239
19279
|
app.get("*", async (c, next) => {
|
|
19240
|
-
if (!existsSync31(
|
|
19241
|
-
const isCheckout = existsSync31(
|
|
19280
|
+
if (!existsSync31(join28(WEB_DIST, "index.html"))) {
|
|
19281
|
+
const isCheckout = existsSync31(join28(paths.WEB_ROOT, "package.json"));
|
|
19242
19282
|
return c.text(
|
|
19243
19283
|
isCheckout ? `Workspace UI build missing (${WEB_DIST}).
|
|
19244
19284
|
Run \`pnpm build:web\` from the repo root.
|
|
@@ -19367,13 +19407,13 @@ function flagValue(args, name) {
|
|
|
19367
19407
|
function openBrowser2(url) {
|
|
19368
19408
|
const cmd = platform7() === "darwin" ? "open" : platform7() === "win32" ? "start" : "xdg-open";
|
|
19369
19409
|
try {
|
|
19370
|
-
|
|
19410
|
+
spawn8(cmd, [url], { stdio: "ignore", detached: true }).unref();
|
|
19371
19411
|
} catch {
|
|
19372
19412
|
}
|
|
19373
19413
|
}
|
|
19374
19414
|
function ensureWebBuild() {
|
|
19375
|
-
if (existsSync32(
|
|
19376
|
-
if (!existsSync32(
|
|
19415
|
+
if (existsSync32(join29(paths.WEB_ROOT, "dist", "index.html"))) return;
|
|
19416
|
+
if (!existsSync32(join29(paths.WEB_ROOT, "package.json"))) return;
|
|
19377
19417
|
console.log(" packages/ui/dist missing, building the dashboard UI...");
|
|
19378
19418
|
const result = spawnSync("pnpm", ["build"], {
|
|
19379
19419
|
cwd: paths.WEB_ROOT,
|
|
@@ -19423,7 +19463,7 @@ async function runDashboard(args) {
|
|
|
19423
19463
|
}
|
|
19424
19464
|
|
|
19425
19465
|
// src/commands/workspace.ts
|
|
19426
|
-
import { existsSync as existsSync33, mkdirSync as
|
|
19466
|
+
import { existsSync as existsSync33, mkdirSync as mkdirSync14, writeFileSync as writeFileSync13 } from "fs";
|
|
19427
19467
|
var USAGE7 = `
|
|
19428
19468
|
Usage: flyspace workspace <subcommand> [options]
|
|
19429
19469
|
|
|
@@ -19527,7 +19567,7 @@ async function provisionChannels(specs) {
|
|
|
19527
19567
|
}
|
|
19528
19568
|
const cwd = expandPath(spec.cwd);
|
|
19529
19569
|
if (!existsSync33(cwd)) {
|
|
19530
|
-
|
|
19570
|
+
mkdirSync14(cwd, { recursive: true });
|
|
19531
19571
|
console.log(` created cwd ${cwd}`);
|
|
19532
19572
|
}
|
|
19533
19573
|
await createChannel({ name: spec.name, cwd, position: index });
|
|
@@ -19604,10 +19644,10 @@ async function runReconcileCmd(args) {
|
|
|
19604
19644
|
}
|
|
19605
19645
|
|
|
19606
19646
|
// src/cli.ts
|
|
19607
|
-
import { join as
|
|
19647
|
+
import { join as join30 } from "path";
|
|
19608
19648
|
var home = flyspaceHome();
|
|
19609
19649
|
if (home) {
|
|
19610
|
-
const bin =
|
|
19650
|
+
const bin = join30(home, "bin");
|
|
19611
19651
|
const path = process.env.PATH ?? "";
|
|
19612
19652
|
if (!path.split(":").includes(bin)) process.env.PATH = path ? `${bin}:${path}` : bin;
|
|
19613
19653
|
}
|
|
@@ -19745,7 +19785,7 @@ async function main() {
|
|
|
19745
19785
|
break;
|
|
19746
19786
|
case "-v":
|
|
19747
19787
|
case "--version":
|
|
19748
|
-
printRaw("0.1.
|
|
19788
|
+
printRaw("0.1.30");
|
|
19749
19789
|
break;
|
|
19750
19790
|
case "-h":
|
|
19751
19791
|
case "--help":
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "flyspace-cli",
|
|
3
|
-
"version": "0.1.
|
|
3
|
+
"version": "0.1.30",
|
|
4
4
|
"description": "AI-native headless community OS",
|
|
5
5
|
"license": "SEE LICENSE IN LICENSE",
|
|
6
6
|
"private": false,
|
|
@@ -29,7 +29,7 @@
|
|
|
29
29
|
"build:cli": "FLYSPACE_PUBLIC_BUILD=1 tsup",
|
|
30
30
|
"start": "node dist/cli.js start",
|
|
31
31
|
"prepublishOnly": "pnpm run build:cli",
|
|
32
|
-
"release": "pnpm version patch &&
|
|
32
|
+
"release": "pnpm version patch && git push --follow-tags"
|
|
33
33
|
},
|
|
34
34
|
"dependencies": {
|
|
35
35
|
"@anthropic-ai/sandbox-runtime": "0.0.77",
|
|
@@ -71,5 +71,10 @@
|
|
|
71
71
|
"@types/web-push": "^3.6.4",
|
|
72
72
|
"@types/ws": "^8.18.1",
|
|
73
73
|
"playwright": "^1.58.2"
|
|
74
|
+
},
|
|
75
|
+
"repository": {
|
|
76
|
+
"type": "git",
|
|
77
|
+
"url": "git+https://github.com/flycoder-io/flyspace.git",
|
|
78
|
+
"directory": "packages/host"
|
|
74
79
|
}
|
|
75
80
|
}
|