flyspace-cli 0.1.12 → 0.1.13

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.
Files changed (2) hide show
  1. package/dist/cli.js +94 -22
  2. package/package.json +1 -1
package/dist/cli.js CHANGED
@@ -1540,7 +1540,7 @@ async function runAuthCmd(args) {
1540
1540
  }
1541
1541
 
1542
1542
  // src/version.ts
1543
- var CLI_VERSION = true ? "0.1.12" : null;
1543
+ var CLI_VERSION = true ? "0.1.13" : null;
1544
1544
  function isOlderVersion(a, b) {
1545
1545
  const parse2 = (v) => v.replace(/^v/, "").split("-")[0].split(".").map(Number);
1546
1546
  const [pa, pb] = [parse2(a), parse2(b)];
@@ -2032,7 +2032,7 @@ function npmEnv() {
2032
2032
  return home ? { ...process.env, PATH: `${join9(home, "node", "bin")}:${process.env.PATH ?? ""}` } : process.env;
2033
2033
  }
2034
2034
  async function runUpgrade() {
2035
- const current = "0.1.12";
2035
+ const current = "0.1.13";
2036
2036
  console.log(`Current version: ${current}`);
2037
2037
  console.log("Checking for updates...\n");
2038
2038
  try {
@@ -4203,7 +4203,7 @@ async function deliverPasswordResetLink(email, redirectTo) {
4203
4203
  import { existsSync as existsSync25 } from "fs";
4204
4204
  import { createServer } from "net";
4205
4205
  import { join as join23 } from "path";
4206
- import { Hono as Hono33 } from "hono";
4206
+ import { Hono as Hono34 } from "hono";
4207
4207
  import { serve } from "@hono/node-server";
4208
4208
  import { serveStatic } from "@hono/node-server/serve-static";
4209
4209
 
@@ -4403,7 +4403,7 @@ var requireDocsAccess = async (c, next) => {
4403
4403
  };
4404
4404
 
4405
4405
  // src/dashboard/api.ts
4406
- import { Hono as Hono30 } from "hono";
4406
+ import { Hono as Hono31 } from "hono";
4407
4407
 
4408
4408
  // src/dashboard/public-share-routes.ts
4409
4409
  import { existsSync as existsSync11, readFileSync as readFileSync9, statSync as statSync3 } from "fs";
@@ -10767,10 +10767,10 @@ function deleteDocEntry(root, path) {
10767
10767
  type: isDir2 ? "dir" : "file"
10768
10768
  };
10769
10769
  }
10770
- function createDocsRouter() {
10770
+ function createDocsRouter({ gate = requireDocsAccess } = {}) {
10771
10771
  const app = new Hono10();
10772
- app.use("/:id/docs", requireDocsAccess);
10773
- app.use("/:id/docs/*", requireDocsAccess);
10772
+ app.use("/:id/docs", gate);
10773
+ app.use("/:id/docs/*", gate);
10774
10774
  app.get("/:id/docs", (c) => {
10775
10775
  const { cwd } = resolveChannelConfig(c.req.param("id"));
10776
10776
  const dir = c.req.query("path") ?? "";
@@ -15524,10 +15524,76 @@ function registerDataRoutes(api, agent = {}) {
15524
15524
  // src/dashboard/device-auth-routes.ts
15525
15525
  import { verify } from "crypto";
15526
15526
  import { getConnInfo } from "@hono/node-server/conninfo";
15527
- import { Hono as Hono29 } from "hono";
15527
+ import { Hono as Hono30 } from "hono";
15528
15528
 
15529
15529
  // src/dashboard/agent-bridge.ts
15530
15530
  import { randomBytes as randomBytes8, randomUUID as randomUUID4, sign as signRaw, timingSafeEqual as timingSafeEqual2, verify as verifyRaw } from "crypto";
15531
+
15532
+ // src/dashboard/docs-relay.ts
15533
+ import { Hono as Hono29 } from "hono";
15534
+ import { streamSSE as streamSSE2 } from "hono/streaming";
15535
+ var FORWARDED_HEADERS = ["content-type", "host", "accept-language"];
15536
+ var RETURNED_HEADERS = ["content-type", "content-disposition", "content-security-policy", "cache-control"];
15537
+ async function handleDocsRequest(req) {
15538
+ const app = new Hono29();
15539
+ app.use("*", async (c, next) => {
15540
+ c.set("auth", req.auth);
15541
+ await next();
15542
+ });
15543
+ app.route("/channels", createDocsRouter({ gate: async (_c, next) => next() }));
15544
+ const res = await app.request(req.path, {
15545
+ method: req.method,
15546
+ headers: req.headers,
15547
+ ...req.body !== void 0 && { body: Buffer.from(req.body, "base64") }
15548
+ });
15549
+ const headers = {};
15550
+ for (const name of RETURNED_HEADERS) {
15551
+ const value = res.headers.get(name);
15552
+ if (value) headers[name] = value;
15553
+ }
15554
+ return { status: res.status, headers, body: Buffer.from(await res.arrayBuffer()).toString("base64") };
15555
+ }
15556
+ function registerRelayedDocsRoutes(api, agent) {
15557
+ api.get(
15558
+ "/channels/:id/docs/watch",
15559
+ requireDocsAccess,
15560
+ (c) => streamSSE2(c, async (stream) => {
15561
+ await stream.writeSSE({ event: "unavailable", data: "{}" });
15562
+ })
15563
+ );
15564
+ api.all("/channels/:id/docs", requireDocsAccess, relay2(agent));
15565
+ api.all("/channels/:id/docs/*", requireDocsAccess, relay2(agent));
15566
+ }
15567
+ function relay2(agent) {
15568
+ return async (c) => {
15569
+ const url = new URL(c.req.url);
15570
+ const path = url.pathname.slice(url.pathname.indexOf("/channels/")) + url.search;
15571
+ const headers = {};
15572
+ for (const name of FORWARDED_HEADERS) {
15573
+ const value = c.req.header(name);
15574
+ if (value) headers[name] = value;
15575
+ }
15576
+ const hasBody = c.req.method !== "GET" && c.req.method !== "HEAD";
15577
+ const body = hasBody ? Buffer.from(await c.req.arrayBuffer()).toString("base64") : void 0;
15578
+ const result = await agent.docsRequest?.({
15579
+ method: c.req.method,
15580
+ path,
15581
+ headers,
15582
+ body,
15583
+ auth: c.get("auth")
15584
+ });
15585
+ if (!result) {
15586
+ return c.json({ error: "Docs need the Host machine, which is not connected right now." }, 503);
15587
+ }
15588
+ const empty = c.req.method === "HEAD" || result.status === 204 || result.status === 304;
15589
+ return new Response(empty ? null : Buffer.from(result.body, "base64"), {
15590
+ status: result.status,
15591
+ headers: result.headers
15592
+ });
15593
+ };
15594
+ }
15595
+
15596
+ // src/dashboard/agent-bridge.ts
15531
15597
  import { existsSync as existsSync24, readFileSync as readFileSync17 } from "fs";
15532
15598
  import dotenv from "dotenv";
15533
15599
  import { WebSocket, WebSocketServer } from "ws";
@@ -16247,7 +16313,7 @@ var METHODS = {
16247
16313
  channel_docs_access: ["GET", "HEAD"]
16248
16314
  };
16249
16315
  var CHANNEL_SCOPED = /* @__PURE__ */ new Set(["channel_members", "channel_docs_access"]);
16250
- var FORWARDED_HEADERS = ["accept", "content-type", "prefer", "range"];
16316
+ var FORWARDED_HEADERS2 = ["accept", "content-type", "prefer", "range"];
16251
16317
  var deny = (message, status = 403) => ({
16252
16318
  status,
16253
16319
  headers: { "content-type": "application/json" },
@@ -16383,7 +16449,7 @@ async function proxyHostDb(workspaces, req, forward, assigned = workspaces ?? []
16383
16449
  }
16384
16450
  }
16385
16451
  const headers = {};
16386
- for (const name of FORWARDED_HEADERS) {
16452
+ for (const name of FORWARDED_HEADERS2) {
16387
16453
  const value = req.headers[name];
16388
16454
  if (value !== void 0) headers[name] = value;
16389
16455
  }
@@ -16553,6 +16619,7 @@ function localAgentCallbacks(chatAgent) {
16553
16619
  saveLocalDashboardSettings: (patch) => saveDashboardSettings(patch),
16554
16620
  writeSkill: (ref, write) => writeSkillAndSync(ref, write),
16555
16621
  outputStylesRequest: (req) => handleOutputStylesRequest(req),
16622
+ docsRequest: (req) => handleDocsRequest(req),
16556
16623
  listSessions: () => listLocalSessions(),
16557
16624
  scanOnboarding: () => scanOnboarding(),
16558
16625
  linkProjectFolders: (slug, items) => linkProjectFolders(slug, items),
@@ -16576,6 +16643,7 @@ function startLocalProfileConfigHydration() {
16576
16643
  return () => clearInterval(timer2);
16577
16644
  }
16578
16645
  var CALL_TIMEOUT_MS = 15e3;
16646
+ var DOCS_CALL_TIMEOUT_MS = 12e4;
16579
16647
  var AUTH_TIMEOUT_MS = 5e3;
16580
16648
  var HEARTBEAT_INTERVAL_MS = 15e3;
16581
16649
  var HEARTBEAT_TIMEOUT_MS = HEARTBEAT_INTERVAL_MS * 2.5;
@@ -16765,7 +16833,7 @@ function attachHostSocket(server) {
16765
16833
  });
16766
16834
  return wss;
16767
16835
  }
16768
- function callHost(method, args) {
16836
+ function callHost(method, args, timeoutMs = CALL_TIMEOUT_MS) {
16769
16837
  const profile = getProfile();
16770
16838
  const ws = hostFor(profile);
16771
16839
  if (!ws) {
@@ -16780,7 +16848,7 @@ function callHost(method, args) {
16780
16848
  pending2.delete(id);
16781
16849
  console.error(`[host-socket] ${method} -> timed out`);
16782
16850
  resolve7(null);
16783
- }, CALL_TIMEOUT_MS);
16851
+ }, timeoutMs);
16784
16852
  pending2.set(id, {
16785
16853
  resolve: (value) => {
16786
16854
  clearTimeout(timer2);
@@ -16835,6 +16903,9 @@ function remoteAgentCallbacks() {
16835
16903
  writeSkill: (ref, write) => callHost("writeSkill", [ref, write]),
16836
16904
  // Same posture as writeSkill: `null` becomes a 503.
16837
16905
  outputStylesRequest: (req) => callHost("outputStylesRequest", [req]),
16906
+ // Same posture again. Longer timeout: a first translation of a doc runs a
16907
+ // model call on the Host before it answers.
16908
+ docsRequest: (req) => callHost("docsRequest", [req], DOCS_CALL_TIMEOUT_MS),
16838
16909
  // `null` (no Host connected) is passed through rather than defaulting to
16839
16910
  // `[]` — see listSessions's doc comment on AgentCallbacks.
16840
16911
  listSessions: () => callHost("listSessions", []),
@@ -16972,7 +17043,7 @@ var RELAYED_METHODS = [
16972
17043
  "listAgentRuns"
16973
17044
  ];
16974
17045
  function relayedAgentCallbacks(local) {
16975
- const relay2 = (method) => async (...args) => {
17046
+ const relay3 = (method) => async (...args) => {
16976
17047
  const endpoint = readHostEndpoint();
16977
17048
  if (endpoint) {
16978
17049
  try {
@@ -16992,7 +17063,7 @@ function relayedAgentCallbacks(local) {
16992
17063
  };
16993
17064
  return {
16994
17065
  ...local,
16995
- ...Object.fromEntries(RELAYED_METHODS.map((method) => [method, relay2(method)]))
17066
+ ...Object.fromEntries(RELAYED_METHODS.map((method) => [method, relay3(method)]))
16996
17067
  };
16997
17068
  }
16998
17069
  async function handleLocalRelay(req, callbacks, token) {
@@ -17095,7 +17166,7 @@ async function boundWorkspaceIds(publicKey, userId) {
17095
17166
  return new Set(existing ? (await listDeviceWorkspaces(existing)).map((w) => w.id) : []);
17096
17167
  }
17097
17168
  function createDeviceAuthRouter() {
17098
- const app = new Hono29();
17169
+ const app = new Hono30();
17099
17170
  app.post("/code", async (c) => {
17100
17171
  const body = await readBody(c);
17101
17172
  const publicKey = typeof body["public_key"] === "string" ? body["public_key"] : "";
@@ -17259,7 +17330,7 @@ function createDeviceAuthRouter() {
17259
17330
 
17260
17331
  // src/dashboard/api.ts
17261
17332
  function createApiRouter(agent = {}, mode = "all") {
17262
- const api = new Hono30();
17333
+ const api = new Hono31();
17263
17334
  api.use("*", async (c, next) => {
17264
17335
  const known = await listKnownWorkspaces();
17265
17336
  const fromHost = profileFromHost(trustedHost(c), known);
@@ -17322,6 +17393,7 @@ function createApiRouter(agent = {}, mode = "all") {
17322
17393
  const entries2 = await agent.listFlatDocs?.({ cwd, query, sort, showHidden }) ?? [];
17323
17394
  return c.json({ root: cwd, query, entries: entries2 });
17324
17395
  });
17396
+ registerRelayedDocsRoutes(api, agent);
17325
17397
  api.get("/settings", async (c) => {
17326
17398
  const [branding, local] = await Promise.all([
17327
17399
  loadWorkspaceBranding(),
@@ -17370,7 +17442,7 @@ function createApiRouter(agent = {}, mode = "all") {
17370
17442
  }
17371
17443
 
17372
17444
  // src/dashboard/app-icon-routes.ts
17373
- import { Hono as Hono31 } from "hono";
17445
+ import { Hono as Hono32 } from "hono";
17374
17446
  var NEUTRAL_MANIFEST = {
17375
17447
  id: "/",
17376
17448
  name: "Flyspace",
@@ -17408,7 +17480,7 @@ async function withResolvedProfile2(c, next) {
17408
17480
  return profile ? runWithProfile(profile, () => next()) : next();
17409
17481
  }
17410
17482
  function createAppIconRouter() {
17411
- const app = new Hono31();
17483
+ const app = new Hono32();
17412
17484
  app.get("/manifest.json", withResolvedProfile2, async (c) => {
17413
17485
  if (!await resolvedProfileHost(c)) return c.json(NEUTRAL_MANIFEST);
17414
17486
  const profile = getProfile();
@@ -17448,7 +17520,7 @@ function pngResponse(c, png) {
17448
17520
  }
17449
17521
 
17450
17522
  // src/dashboard/stripe-routes.ts
17451
- import { Hono as Hono32 } from "hono";
17523
+ import { Hono as Hono33 } from "hono";
17452
17524
  function planStatusFor(status) {
17453
17525
  const known = ["trialing", "active", "paused", "canceled"];
17454
17526
  return known.includes(status) ? status : null;
@@ -17491,7 +17563,7 @@ async function handleCardAdded(session) {
17491
17563
  }
17492
17564
  }
17493
17565
  function createStripeWebhookRouter() {
17494
- const stripeRouter = new Hono32();
17566
+ const stripeRouter = new Hono33();
17495
17567
  stripeRouter.post("/webhook", async (c) => {
17496
17568
  const secret = process.env["STRIPE_WEBHOOK_SECRET"];
17497
17569
  const signature = c.req.header("stripe-signature");
@@ -17651,7 +17723,7 @@ async function startDashboardServer(preferredPort = DEFAULT_DASHBOARD_PORT, host
17651
17723
  const mirrorsSkills = mode === "host" || process.env["FLYSPACE_SKILL_SYNC"] === "1";
17652
17724
  const stopSkillSync = mirrorsSkills ? installSkillSync(listProfiles()) : () => {
17653
17725
  };
17654
- const app = new Hono33();
17726
+ const app = new Hono34();
17655
17727
  app.use("*", async (c, next) => {
17656
17728
  await next();
17657
17729
  if (c.req.path.startsWith("/assets/")) {
@@ -19659,7 +19731,7 @@ async function main() {
19659
19731
  break;
19660
19732
  case "-v":
19661
19733
  case "--version":
19662
- printRaw("0.1.12");
19734
+ printRaw("0.1.13");
19663
19735
  break;
19664
19736
  case "-h":
19665
19737
  case "--help":
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "flyspace-cli",
3
- "version": "0.1.12",
3
+ "version": "0.1.13",
4
4
  "description": "AI-native headless community OS",
5
5
  "license": "SEE LICENSE IN LICENSE",
6
6
  "private": false,