@agentsky/sky 2.24.1 → 2.25.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.
@@ -38,7 +38,7 @@ function currentUniverse() {
38
38
  }
39
39
 
40
40
  // src/version.ts
41
- var CLI_VERSION = "2.24.1";
41
+ var CLI_VERSION = "2.25.0";
42
42
  var USER_AGENT = `sky-cli/${CLI_VERSION} (${process.platform}; node/${process.versions.node})`;
43
43
 
44
44
  export {
@@ -3,7 +3,7 @@ import {
3
3
  apiBase,
4
4
  apiToken,
5
5
  currentUniverse
6
- } from "./chunk-S4YG3TXA.js";
6
+ } from "./chunk-LPUGEMCV.js";
7
7
 
8
8
  // src/api.ts
9
9
  import { createWriteStream, writeFileSync } from "fs";
@@ -97,6 +97,9 @@ async function downloadFileTo(fileId, outPath) {
97
97
  headers: { "user-agent": USER_AGENT, ...authHeaders() }
98
98
  });
99
99
  if (!res.ok) await parseError(res);
100
+ return writeResponseFile(res, outPath);
101
+ }
102
+ async function writeResponseFile(res, outPath) {
100
103
  if (!res.body) {
101
104
  writeFileSync(outPath, new Uint8Array(0));
102
105
  return 0;
@@ -189,6 +192,7 @@ export {
189
192
  uploadFile,
190
193
  apiForm,
191
194
  downloadFileTo,
195
+ writeResponseFile,
192
196
  apiBytes,
193
197
  resolveSessionRef,
194
198
  streamEvents,
package/dist/index.js CHANGED
@@ -9,8 +9,9 @@ import {
9
9
  postEvents,
10
10
  resolveSessionRef,
11
11
  streamEvents,
12
- uploadFile
13
- } from "./chunk-KWLEADJQ.js";
12
+ uploadFile,
13
+ writeResponseFile
14
+ } from "./chunk-QROAAJN2.js";
14
15
  import {
15
16
  CLI_VERSION,
16
17
  USER_AGENT,
@@ -21,7 +22,7 @@ import {
21
22
  currentUniverse,
22
23
  loadConfig,
23
24
  saveConfig
24
- } from "./chunk-S4YG3TXA.js";
25
+ } from "./chunk-LPUGEMCV.js";
25
26
  import {
26
27
  AGENT_TYPES,
27
28
  MODEL_SUBSCRIPTION_PLAN_PHRASE,
@@ -47,7 +48,7 @@ import {
47
48
  import "./chunk-MLKGABMK.js";
48
49
 
49
50
  // src/index.ts
50
- import { existsSync as existsSync13, readFileSync as readFileSync19, writeFileSync as writeFileSync11 } from "fs";
51
+ import { existsSync as existsSync13, readFileSync as readFileSync20, writeFileSync as writeFileSync10 } from "fs";
51
52
  import { basename as basename9, resolve as resolve9 } from "path";
52
53
  import { createInterface as createInterface6 } from "readline";
53
54
  import { Command } from "commander";
@@ -2643,6 +2644,35 @@ it, and name its path in the brief.
2643
2644
  6. Tell the person what was done, which agent did which part, and what it cost
2644
2645
  (\`get_task\` reports the task's cost).
2645
2646
 
2647
+ ## Share an existing Library document
2648
+
2649
+ Use \`read_library_file_links\` with the document's exact \`ref\` to read its
2650
+ current revision, supported access and real available members. The reference
2651
+ can name a Drive file (including an uploaded meeting note), task file, memory
2652
+ note, skill file, agent user instructions (\`{kind:"agent_prompt",agentId}\`), saved artifact or platform artifact. Only the user-authored AGENTS.md is shared; system instructions and credentials are never included. \`workspace\` names the
2653
+ audience workspace, never a storage move or the connection's default.
2654
+ \`share_library_file\` changes only the requested workspace/member grants;
2655
+ \`publish_library_file\` enables or disables a public view-only link while
2656
+ preserving other grants. Both read first and merge against the current
2657
+ revision. \`revoke_library_file_links\` needs the explicit revision you reviewed.
2658
+ A conflict is an error: read the current state before intentionally retrying.
2659
+ These tools send no messages and start no sessions. CLI equivalents are
2660
+ \`sky library links show\`, \`share\`, \`publish\` and \`revoke\`; their help
2661
+ shows every reference shape. Existing artifact links and version pins keep
2662
+ using their existing controls and \`share_artifact\`.
2663
+
2664
+ When you receive a Library shared/public URL, \`read_shared_library_file\`
2665
+ accepts the 43-character token at its end; \`public: true\` chooses the public
2666
+ view-only reader. A recipient with a live edit grant can use
2667
+ \`save_shared_library_file\` with the opaque source revision from that read
2668
+ and exactly one native text/HTML/Office/restore field. Public links have no
2669
+ writer. The CLI equivalents are \`sky library links read --token \u2026\`
2670
+ (\`--output\` streams original bytes) and \`sky library links save --token \u2026
2671
+ --revision \u2026 --file \u2026\`; \`--data\` accepts the other native save fields.
2672
+ A 403 is not a saved result; a 409 requires reading current state before an
2673
+ intentional retry. This source revision is distinct from the integer revision
2674
+ of the sharing settings.
2675
+
2646
2676
  ## Build an agent that the person's own application runs
2647
2677
 
2648
2678
  When the person wants an agent their product starts for its customers, built
@@ -5261,6 +5291,83 @@ function renderThreadSummary(t) {
5261
5291
  return `${t.id.slice(0, 12)} ${flag}${t.title.slice(0, 40).padEnd(44)} [${agents}] ${status}`;
5262
5292
  }
5263
5293
 
5294
+ // src/library.ts
5295
+ import { readFileSync as readFileSync17 } from "fs";
5296
+
5297
+ // src/api-command.ts
5298
+ import { readFileSync as readFileSync16 } from "fs";
5299
+ var API_METHODS = ["GET", "POST", "PUT", "PATCH", "DELETE"];
5300
+ function readData(data, stdin = () => readFileSync16(0, "utf8")) {
5301
+ if (data === void 0) return void 0;
5302
+ const raw = data === "-" ? stdin() : data.startsWith("@") ? readFileSync16(data.slice(1), "utf8") : data;
5303
+ try {
5304
+ JSON.parse(raw);
5305
+ } catch {
5306
+ throw new Error("--data must be JSON (inline, @file or - for stdin)");
5307
+ }
5308
+ return raw;
5309
+ }
5310
+ function requestPath(path, query = []) {
5311
+ if (!path.startsWith("/") || path.startsWith("//")) throw new Error("path must start with /, e.g. /threads");
5312
+ const clean = path.replace(/^\/v1(?=\/)/, "");
5313
+ const params = new URLSearchParams();
5314
+ for (const pair of query) {
5315
+ const at = pair.indexOf("=");
5316
+ if (at <= 0) throw new Error(`--query needs key=value, got "${pair}"`);
5317
+ params.append(pair.slice(0, at), pair.slice(at + 1));
5318
+ }
5319
+ const sep4 = clean.includes("?") ? "&" : "?";
5320
+ const encoded = params.toString();
5321
+ return encoded ? `${clean}${sep4}${encoded}` : clean;
5322
+ }
5323
+ function matchOperations(doc, words) {
5324
+ const needles = words.map((w) => w.toLowerCase());
5325
+ const out = [];
5326
+ for (const [path, item] of Object.entries(doc.paths ?? {})) {
5327
+ for (const [method, op] of Object.entries(item)) {
5328
+ if (!API_METHODS.includes(method.toUpperCase())) continue;
5329
+ const hay = `${method} ${path} ${op.summary ?? ""} ${op.operationId ?? ""}`.toLowerCase();
5330
+ if (needles.every((n) => hay.includes(n))) out.push({ method: method.toUpperCase(), path, summary: op.summary, operationId: op.operationId });
5331
+ }
5332
+ }
5333
+ return out.sort((a, b) => a.path.localeCompare(b.path) || a.method.localeCompare(b.method));
5334
+ }
5335
+ async function searchApi(words) {
5336
+ const res = await apiRaw("GET", "/openapi.json", { auth: false });
5337
+ if (!res.ok) throw new Error(`could not read the API reference (${res.status})`);
5338
+ const ops = matchOperations(await res.json(), words);
5339
+ if (!ops.length) {
5340
+ console.log("no operations match");
5341
+ return;
5342
+ }
5343
+ for (const op of ops) console.log(`${op.method.padEnd(6)} ${op.path}${op.summary ? ` \u2014 ${op.summary}` : ""}`);
5344
+ }
5345
+ async function callApi(method, path, opts) {
5346
+ const verb = method.toUpperCase();
5347
+ if (!API_METHODS.includes(verb)) throw new Error(`method must be one of ${API_METHODS.join(", ")} or "search"`);
5348
+ const body = readData(opts.data);
5349
+ if (body !== void 0 && verb === "GET") throw new Error("a GET takes no --data; use --query");
5350
+ const res = await apiRaw(verb, requestPath(path, opts.query), { body, idempotencyKey: opts.idempotencyKey, universe: opts.workspace });
5351
+ const type = res.headers.get("content-type") ?? "";
5352
+ if (opts.output) {
5353
+ await writeResponseFile(res, opts.output);
5354
+ console.error(`${res.status} \u2192 ${opts.output}`);
5355
+ } else if (/json/.test(type)) {
5356
+ const text = await res.text();
5357
+ let printed = text;
5358
+ try {
5359
+ printed = JSON.stringify(JSON.parse(text), null, 2);
5360
+ } catch {
5361
+ }
5362
+ (res.ok ? console.log : console.error)(printed);
5363
+ } else if (/^text\/|xml|csv|markdown/.test(type) || !type) {
5364
+ (res.ok ? console.log : console.error)(await res.text());
5365
+ } else {
5366
+ console.error(`${res.status}: ${type} body (${res.headers.get("content-length") ?? "?"} bytes); pass --output <file> to save it`);
5367
+ }
5368
+ if (!res.ok && res.status !== 304) process.exitCode = 1;
5369
+ }
5370
+
5264
5371
  // src/library.ts
5265
5372
  var artifactPath = (id) => `/library/artifacts/${encodeURIComponent(id)}`;
5266
5373
  async function listLibrary(query = {}) {
@@ -5295,9 +5402,139 @@ function renderLibraryArtifact(artifact2) {
5295
5402
  const version = artifact2.currentVersion ? `v${artifact2.currentVersion}` : "";
5296
5403
  return `${artifact2.id} ${artifact2.name} ${version}${artifact2.shared ? " shared" : ""}`;
5297
5404
  }
5405
+ var libraryFileRefSchema = external_exports.discriminatedUnion("kind", [
5406
+ external_exports.object({ kind: external_exports.literal("agent_prompt"), agentId: external_exports.string().min(1).max(200).regex(/^[a-zA-Z0-9_-]+$/) }).strict(),
5407
+ external_exports.object({ kind: external_exports.literal("file"), fileId: external_exports.string().min(1), sessionId: external_exports.string().min(1).optional() }).strict(),
5408
+ external_exports.object({ kind: external_exports.literal("task_file"), taskId: external_exports.string().min(1), path: external_exports.string().min(1) }).strict(),
5409
+ external_exports.object({ kind: external_exports.literal("memory_note"), storeId: external_exports.string().min(1), memoryId: external_exports.string().min(1) }).strict(),
5410
+ external_exports.object({ kind: external_exports.literal("skill_file"), skillId: external_exports.string().min(1), path: external_exports.string().min(1) }).strict(),
5411
+ external_exports.object({ kind: external_exports.literal("artifact"), artifactId: external_exports.string().min(1) }).strict(),
5412
+ external_exports.object({ kind: external_exports.literal("platform_artifact"), artifactId: external_exports.string().min(1), path: external_exports.string().min(1).optional() }).strict()
5413
+ ]);
5414
+ var linkAccessSchema = external_exports.enum(["none", "view", "edit"]);
5415
+ var linkMemberSchema = external_exports.object({ userId: external_exports.string().min(1), access: external_exports.enum(["view", "edit"]) });
5416
+ var linkRevisionSchema = external_exports.number().int().nonnegative();
5417
+ var libraryLinksSchema = external_exports.object({
5418
+ link: external_exports.object({
5419
+ id: external_exports.string().nullable(),
5420
+ ref: libraryFileRefSchema,
5421
+ workspace: external_exports.string().nullable(),
5422
+ revision: linkRevisionSchema,
5423
+ editable: external_exports.boolean(),
5424
+ workspaceAccess: linkAccessSchema,
5425
+ members: external_exports.array(linkMemberSchema),
5426
+ publicEnabled: external_exports.boolean(),
5427
+ sharedUrl: external_exports.string().nullable(),
5428
+ publicUrl: external_exports.string().nullable()
5429
+ }),
5430
+ availableMembers: external_exports.array(external_exports.object({ userId: external_exports.string(), name: external_exports.string().nullable(), email: external_exports.string().nullable() }))
5431
+ });
5432
+ function parseLibraryFileRef(value) {
5433
+ return libraryFileRefSchema.parse(JSON.parse(value));
5434
+ }
5435
+ async function getLibraryLinks(ref, workspace2) {
5436
+ const params = new URLSearchParams({ ref: JSON.stringify(libraryFileRefSchema.parse(ref)), ...workspace2 ? { workspace: workspace2 } : {} });
5437
+ const result = libraryLinksSchema.parse(await api("GET", `/library/links?${params}`));
5438
+ if (JSON.stringify(result.link.ref) !== JSON.stringify(libraryFileRefSchema.parse(ref)) || workspace2 !== void 0 && result.link.workspace !== workspace2) throw new Error("The API returned sharing for a different source. No access was changed.");
5439
+ return result;
5440
+ }
5441
+ async function updateLibraryLinks(ref, change) {
5442
+ const current = await getLibraryLinks(ref, change.workspace);
5443
+ if (change.revision !== void 0 && linkRevisionSchema.parse(change.revision) !== current.link.revision) throw new Error("Sharing changed since that revision. Read the current links and retry.");
5444
+ const members = new Map(current.link.members.map((member) => [member.userId, member]));
5445
+ for (const member of change.memberChanges ?? []) {
5446
+ const userId = external_exports.string().min(1).parse(member.userId);
5447
+ const access = linkAccessSchema.parse(member.access);
5448
+ if (access === "none") members.delete(userId);
5449
+ else members.set(userId, { userId, access });
5450
+ }
5451
+ return libraryLinksSchema.parse(await api("PUT", "/library/links", {
5452
+ ref,
5453
+ workspace: current.link.workspace,
5454
+ revision: current.link.revision,
5455
+ workspaceAccess: change.workspaceAccess === void 0 ? current.link.workspaceAccess : linkAccessSchema.parse(change.workspaceAccess),
5456
+ members: [...members.values()],
5457
+ publicEnabled: change.publicEnabled === void 0 ? current.link.publicEnabled : external_exports.boolean().parse(change.publicEnabled)
5458
+ }));
5459
+ }
5460
+ async function revokeLibraryLinks(ref, revision, workspace2) {
5461
+ return libraryLinksSchema.parse(await api("DELETE", "/library/links", {
5462
+ ref: libraryFileRefSchema.parse(ref),
5463
+ revision: linkRevisionSchema.parse(revision),
5464
+ ...workspace2 ? { workspace: workspace2 } : {}
5465
+ }));
5466
+ }
5467
+ var sharedLibraryToken = external_exports.string().length(43).regex(/^[A-Za-z0-9_-]{43}$/, "use the 43-character token from the Library shared or public URL");
5468
+ var sharedLibrarySource = external_exports.object({
5469
+ name: external_exports.string(),
5470
+ format: external_exports.enum(["file", "site"]),
5471
+ mediaType: external_exports.string(),
5472
+ revision: external_exports.string(),
5473
+ editable: external_exports.boolean(),
5474
+ url: external_exports.string(),
5475
+ maxBytes: external_exports.number(),
5476
+ history: external_exports.array(external_exports.record(external_exports.string(), external_exports.unknown()))
5477
+ }).passthrough();
5478
+ var sharedLibrarySaved = external_exports.object({ url: external_exports.string(), revision: external_exports.string().min(1), publishedAt: external_exports.string().datetime({ offset: true }), text: external_exports.string().nullable().optional(), historyRevision: external_exports.string().optional() });
5479
+ var sharedLibrarySaveSchema = external_exports.object({
5480
+ revision: external_exports.string().min(1),
5481
+ text: external_exports.string().optional(),
5482
+ html: external_exports.string().optional(),
5483
+ office: external_exports.string().optional(),
5484
+ docx: external_exports.string().optional(),
5485
+ restoreRevision: external_exports.string().min(1).optional(),
5486
+ requestId: external_exports.string().uuid().optional()
5487
+ }).strict().refine((body) => [body.text, body.html, body.office, body.docx, body.restoreRevision].filter((field) => field !== void 0).length === 1, "provide exactly one of text, html, office, docx or restoreRevision");
5488
+ async function readSharedLibraryFile(token, options = {}) {
5489
+ const path = `/library/${options.public ? "public" : "shared"}/${sharedLibraryToken.parse(token)}`;
5490
+ if (!options.output) return sharedLibrarySource.parse(await api("GET", path, void 0, { auth: options.public !== true }));
5491
+ const response = await apiRaw("GET", `${path}?raw=1`, { auth: options.public !== true });
5492
+ if (!response.ok) {
5493
+ const body = await response.json().catch(() => null);
5494
+ throw new ApiError(response.status, body?.error?.code ?? "http_error", body?.error?.message ?? `Download failed (${response.status}).`);
5495
+ }
5496
+ return { output: options.output, bytes: await writeResponseFile(response, options.output) };
5497
+ }
5498
+ async function saveSharedLibraryFile(token, body) {
5499
+ return sharedLibrarySaved.parse(await api("PUT", `/library/shared/${sharedLibraryToken.parse(token)}`, sharedLibrarySaveSchema.parse(body)));
5500
+ }
5501
+ function registerLibraryLinkCommands(library2) {
5502
+ const libraryLinks = library2.command("links").description("share or publish any Library file; --workspace selects the sharing audience without moving the file");
5503
+ libraryLinks.command("read").description("read a shared native document snapshot; --public reads a public view-only link").requiredOption("--token <token>", "43-character token from a Library shared or public URL").option("--public", "use the public reader without sending your API key").option("--output <file>", "stream the original bytes to this file instead of printing the JSON snapshot").action(async (opts) => {
5504
+ console.log(JSON.stringify(await readSharedLibraryFile(opts.token, opts), null, 2));
5505
+ });
5506
+ libraryLinks.command("save").description("save through a live recipient edit grant; --revision is the opaque source revision from links read").requiredOption("--token <token>", "43-character token from the authenticated shared URL (public URLs have no writer)").requiredOption("--revision <revision>", "native source revision from links read; stale revisions fail without retry").option("--file <path>", "UTF-8 text file to save").option("--data <json>", "instead of --file, JSON/ @file / - containing exactly one text/html/office/docx/restoreRevision and optional requestId").action(async (opts) => {
5507
+ if (opts.file !== void 0 === (opts.data !== void 0)) throw new Error("Choose exactly one of --file or --data.");
5508
+ const body = opts.file !== void 0 ? { text: new TextDecoder("utf-8", { fatal: true }).decode(readFileSync17(opts.file)) } : JSON.parse(readData(opts.data));
5509
+ if (!body || typeof body !== "object" || Array.isArray(body)) throw new Error("--data must be a JSON object with one native save field.");
5510
+ if ("revision" in body && body.revision !== opts.revision) throw new Error("--data revision must match --revision.");
5511
+ console.log(JSON.stringify(await saveSharedLibraryFile(opts.token, sharedLibrarySaveSchema.parse({ ...body, revision: opts.revision })), null, 2));
5512
+ });
5513
+ const linkRefOption = (command) => command.requiredOption("--ref <json>", 'file reference JSON, e.g. {"kind":"file","fileId":"file_\u2026"}').option("--workspace <slug>", "the team audience for this link (omit for private/public-only sharing)");
5514
+ const linkRevision = (value) => value === void 0 ? void 0 : linkRevisionSchema.parse(Number(external_exports.string().regex(/^\d+$/, "revision must be a nonnegative integer").parse(value)));
5515
+ const printLibraryLinks = (value) => console.log(JSON.stringify(value, null, 2));
5516
+ linkRefOption(libraryLinks.command("show").description("read sharing, real workspace members and the current revision without creating a link")).action(async (opts) => printLibraryLinks(await getLibraryLinks(parseLibraryFileRef(opts.ref), opts.workspace)));
5517
+ linkRefOption(libraryLinks.command("share").description("change workspace or specific members' access while preserving every unmentioned grant")).option("--workspace-access <access>", "none, view or edit (edit requires an editable source)").option("--member <user:access>", "grant a member view or edit; repeat to update several members", (value, previous) => [...previous, value], []).option("--remove-member <user>", "clear a member override; workspace access still applies", (value, previous) => [...previous, value], []).option("--revision <n>", "refuse if sharing changed since this reviewed revision").action(async (opts) => {
5518
+ if (opts.workspaceAccess === void 0 && !opts.member?.length && !opts.removeMember?.length) throw new Error("Choose --workspace-access, --member or --remove-member; links show reads without changing access.");
5519
+ const memberChanges = (opts.member ?? []).map((value) => {
5520
+ const colon = value.lastIndexOf(":");
5521
+ if (colon < 1) throw new Error("--member must be a user id followed by :view or :edit");
5522
+ return { userId: value.slice(0, colon), access: external_exports.enum(["view", "edit"]).parse(value.slice(colon + 1)) };
5523
+ });
5524
+ memberChanges.push(...(opts.removeMember ?? []).map((userId) => ({ userId, access: "none" })));
5525
+ printLibraryLinks(await updateLibraryLinks(parseLibraryFileRef(opts.ref), {
5526
+ workspace: opts.workspace,
5527
+ revision: linkRevision(opts.revision),
5528
+ memberChanges,
5529
+ workspaceAccess: opts.workspaceAccess === void 0 ? void 0 : external_exports.enum(["none", "view", "edit"]).parse(opts.workspaceAccess)
5530
+ }));
5531
+ });
5532
+ linkRefOption(libraryLinks.command("publish").description("create a public view-only link; --disable revokes only public access and keeps other grants")).option("--disable", "turn off public viewing").option("--revision <n>", "refuse if sharing changed since this reviewed revision").action(async (opts) => printLibraryLinks(await updateLibraryLinks(parseLibraryFileRef(opts.ref), { workspace: opts.workspace, revision: linkRevision(opts.revision), publicEnabled: !opts.disable })));
5533
+ linkRefOption(libraryLinks.command("revoke").description("stop all sharing at an explicitly reviewed revision")).requiredOption("--revision <n>", "current revision from links show; stale revisions fail without retry").action(async (opts) => printLibraryLinks(await revokeLibraryLinks(parseLibraryFileRef(opts.ref), linkRevision(opts.revision), opts.workspace)));
5534
+ }
5298
5535
 
5299
5536
  // src/design-systems.ts
5300
- import { readdirSync as readdirSync8, readFileSync as readFileSync16, statSync as statSync9 } from "fs";
5537
+ import { readdirSync as readdirSync8, readFileSync as readFileSync18, statSync as statSync9 } from "fs";
5301
5538
  import { join as join18, relative as relative5, sep as sep3 } from "path";
5302
5539
  var TEXT2 = /\.(mdx?|markdown|txt|json|m?js|cjs|jsx|tsx?|css|html?|svg|xml|csv|ya?ml|toml)$/i;
5303
5540
  var MEDIA = {
@@ -5341,7 +5578,7 @@ function fileTableFrom(dir) {
5341
5578
  continue;
5342
5579
  }
5343
5580
  const key = relative5(dir, path).split(sep3).join("/");
5344
- const bytes = readFileSync16(path);
5581
+ const bytes = readFileSync18(path);
5345
5582
  files2[key] = TEXT2.test(name) ? bytes.toString("utf8") : `data:${MEDIA[name.split(".").pop()?.toLowerCase() ?? ""] ?? "application/octet-stream"};base64,${bytes.toString("base64")}`;
5346
5583
  }
5347
5584
  };
@@ -5364,80 +5601,6 @@ async function designComments(id, input) {
5364
5601
  return api(input ? "POST" : "GET", `/artifacts/${encodeURIComponent(id)}/design-system/comments`, input);
5365
5602
  }
5366
5603
 
5367
- // src/api-command.ts
5368
- import { readFileSync as readFileSync17, writeFileSync as writeFileSync9 } from "fs";
5369
- var API_METHODS = ["GET", "POST", "PUT", "PATCH", "DELETE"];
5370
- function readData(data, stdin = () => readFileSync17(0, "utf8")) {
5371
- if (data === void 0) return void 0;
5372
- const raw = data === "-" ? stdin() : data.startsWith("@") ? readFileSync17(data.slice(1), "utf8") : data;
5373
- try {
5374
- JSON.parse(raw);
5375
- } catch {
5376
- throw new Error("--data must be JSON (inline, @file or - for stdin)");
5377
- }
5378
- return raw;
5379
- }
5380
- function requestPath(path, query = []) {
5381
- if (!path.startsWith("/") || path.startsWith("//")) throw new Error("path must start with /, e.g. /threads");
5382
- const clean = path.replace(/^\/v1(?=\/)/, "");
5383
- const params = new URLSearchParams();
5384
- for (const pair of query) {
5385
- const at = pair.indexOf("=");
5386
- if (at <= 0) throw new Error(`--query needs key=value, got "${pair}"`);
5387
- params.append(pair.slice(0, at), pair.slice(at + 1));
5388
- }
5389
- const sep4 = clean.includes("?") ? "&" : "?";
5390
- const encoded = params.toString();
5391
- return encoded ? `${clean}${sep4}${encoded}` : clean;
5392
- }
5393
- function matchOperations(doc, words) {
5394
- const needles = words.map((w) => w.toLowerCase());
5395
- const out = [];
5396
- for (const [path, item] of Object.entries(doc.paths ?? {})) {
5397
- for (const [method, op] of Object.entries(item)) {
5398
- if (!API_METHODS.includes(method.toUpperCase())) continue;
5399
- const hay = `${method} ${path} ${op.summary ?? ""} ${op.operationId ?? ""}`.toLowerCase();
5400
- if (needles.every((n) => hay.includes(n))) out.push({ method: method.toUpperCase(), path, summary: op.summary, operationId: op.operationId });
5401
- }
5402
- }
5403
- return out.sort((a, b) => a.path.localeCompare(b.path) || a.method.localeCompare(b.method));
5404
- }
5405
- async function searchApi(words) {
5406
- const res = await apiRaw("GET", "/openapi.json", { auth: false });
5407
- if (!res.ok) throw new Error(`could not read the API reference (${res.status})`);
5408
- const ops = matchOperations(await res.json(), words);
5409
- if (!ops.length) {
5410
- console.log("no operations match");
5411
- return;
5412
- }
5413
- for (const op of ops) console.log(`${op.method.padEnd(6)} ${op.path}${op.summary ? ` \u2014 ${op.summary}` : ""}`);
5414
- }
5415
- async function callApi(method, path, opts) {
5416
- const verb = method.toUpperCase();
5417
- if (!API_METHODS.includes(verb)) throw new Error(`method must be one of ${API_METHODS.join(", ")} or "search"`);
5418
- const body = readData(opts.data);
5419
- if (body !== void 0 && verb === "GET") throw new Error("a GET takes no --data; use --query");
5420
- const res = await apiRaw(verb, requestPath(path, opts.query), { body, idempotencyKey: opts.idempotencyKey, universe: opts.workspace });
5421
- const type = res.headers.get("content-type") ?? "";
5422
- if (opts.output) {
5423
- writeFileSync9(opts.output, new Uint8Array(await res.arrayBuffer()));
5424
- console.error(`${res.status} \u2192 ${opts.output}`);
5425
- } else if (/json/.test(type)) {
5426
- const text = await res.text();
5427
- let printed = text;
5428
- try {
5429
- printed = JSON.stringify(JSON.parse(text), null, 2);
5430
- } catch {
5431
- }
5432
- (res.ok ? console.log : console.error)(printed);
5433
- } else if (/^text\/|xml|csv|markdown/.test(type) || !type) {
5434
- (res.ok ? console.log : console.error)(await res.text());
5435
- } else {
5436
- console.error(`${res.status}: ${type} body (${res.headers.get("content-length") ?? "?"} bytes); pass --output <file> to save it`);
5437
- }
5438
- if (!res.ok && res.status !== 304) process.exitCode = 1;
5439
- }
5440
-
5441
5604
  // src/billing-plans.ts
5442
5605
  var readCodingPlan = () => api("GET", "/billing/coding-plan");
5443
5606
  function joinCodingPlan(dollars2, requestId) {
@@ -5524,7 +5687,7 @@ function workspaceFlagIsCommands(argv, commandPath) {
5524
5687
  }
5525
5688
 
5526
5689
  // src/harness.ts
5527
- import { existsSync as existsSync12, mkdirSync as mkdirSync6, readFileSync as readFileSync18, writeFileSync as writeFileSync10 } from "fs";
5690
+ import { existsSync as existsSync12, mkdirSync as mkdirSync6, readFileSync as readFileSync19, writeFileSync as writeFileSync9 } from "fs";
5528
5691
  import { dirname as dirname9, join as join19, resolve as resolve8 } from "path";
5529
5692
  var HARNESS_FILE = "harness.json";
5530
5693
  function harnessFilePath(dir) {
@@ -5536,7 +5699,7 @@ function readHarnessFile(dir) {
5536
5699
  throw new Error(`no ${HARNESS_FILE} found in ${resolve8(dir)} \u2014 run \`sky harness init\` first`);
5537
5700
  }
5538
5701
  try {
5539
- return JSON.parse(readFileSync18(path, "utf8"));
5702
+ return JSON.parse(readFileSync19(path, "utf8"));
5540
5703
  } catch (err) {
5541
5704
  throw new Error(`could not parse ${path}: ${err instanceof Error ? err.message : String(err)}`);
5542
5705
  }
@@ -5567,7 +5730,7 @@ function harnessInit(dir) {
5567
5730
  throw new Error(`${path} already exists \u2014 delete it to re-init`);
5568
5731
  }
5569
5732
  mkdirSync6(dirname9(path), { recursive: true });
5570
- writeFileSync10(path, `${JSON.stringify(INIT_SKELETON, null, 2)}
5733
+ writeFileSync9(path, `${JSON.stringify(INIT_SKELETON, null, 2)}
5571
5734
  `);
5572
5735
  console.log(`Created ${path}`);
5573
5736
  console.log(INIT_COMMENT);
@@ -6306,7 +6469,7 @@ sessionWorkspace.command("cat <ref> <path>").description("print a file (up to 1
6306
6469
  run(async (ref, path, opts) => {
6307
6470
  const bytes = await readFile(await resolveSessionRef(ref), path);
6308
6471
  if (opts.out) {
6309
- writeFileSync11(opts.out, bytes);
6472
+ writeFileSync10(opts.out, bytes);
6310
6473
  console.error(`saved ${bytes.length} bytes to ${opts.out}`);
6311
6474
  } else process.stdout.write(bytes);
6312
6475
  })
@@ -6323,7 +6486,7 @@ sessionWorkspace.command("patch <ref> [repo]").description("the work in a reposi
6323
6486
  console.error(`${meta.repo}: ${meta.commits.length} commit${meta.commits.length === 1 ? "" : "s"} since ${meta.base_branch || "the imported copy"} (${meta.base_commit.slice(0, 12)})`);
6324
6487
  if (!patch.length) console.error("nothing changed");
6325
6488
  else if (opts.out) {
6326
- writeFileSync11(opts.out, patch);
6489
+ writeFileSync10(opts.out, patch);
6327
6490
  console.error(`wrote ${opts.out} \u2014 apply with: git apply ${opts.out}`);
6328
6491
  } else process.stdout.write(patch);
6329
6492
  })
@@ -6828,14 +6991,14 @@ task.command("get <task> <path>").description("read one task file; prints it, or
6828
6991
  run(async (taskId, path, opts) => {
6829
6992
  const bytes = await readTaskFile(taskId, path);
6830
6993
  if (opts.out) {
6831
- writeFileSync11(opts.out, bytes);
6994
+ writeFileSync10(opts.out, bytes);
6832
6995
  console.log(`Wrote ${bytes.length} bytes to ${opts.out}`);
6833
6996
  } else process.stdout.write(bytes);
6834
6997
  })
6835
6998
  );
6836
6999
  task.command("put <task> <path> <local>").description("write a local file to <path> in the task's files (every session of the task sees it)").action(
6837
7000
  run(async (taskId, path, local) => {
6838
- const { file, conflict } = await writeTaskFile(taskId, path, readFileSync19(local), mediaTypeFor(local));
7001
+ const { file, conflict } = await writeTaskFile(taskId, path, readFileSync20(local), mediaTypeFor(local));
6839
7002
  console.log(`${renderTaskFile(file)}${conflict ? " (replaced a version you had not seen)" : ""}`);
6840
7003
  })
6841
7004
  );
@@ -6908,6 +7071,34 @@ task.command("verdict <task> <did-the-job>").description("record whether the tas
6908
7071
  console.log(`Recorded verdict on task ${updated.id}: did_the_job=${value === "yes"}`);
6909
7072
  })
6910
7073
  );
7074
+ var plugins = program.command("plugins").description("Claude Code plugins in the workspace: install from GitHub, list, remove");
7075
+ plugins.command("list").description("the workspace's installed plugins and the skills each one installed").option("--json", "print the list as JSON").action(
7076
+ run(async (opts) => {
7077
+ const { plugins: list } = await api("GET", "/plugins");
7078
+ if (opts.json) return void console.log(JSON.stringify(list));
7079
+ if (list.length === 0) return void console.log("No plugins. `sky plugins install github:owner/repo[/path][@ref]`");
7080
+ for (const p of list) console.log(`${p.name} ${p.skills.length} skill${p.skills.length === 1 ? "" : "s"}: ${p.skills.map((s) => s.displayName.split("/").pop()).join(", ")}`);
7081
+ })
7082
+ );
7083
+ plugins.command("install <source>").description("install or update a plugin: github:owner/repo[/path][@ref] or a github.com URL").option("--json", "print the result as JSON").action(
7084
+ run(async (source, opts) => {
7085
+ const result = await api("POST", "/plugins", { source });
7086
+ if (opts.json) return void console.log(JSON.stringify(result));
7087
+ console.log(`Installed ${result.plugin.name}${result.plugin.version ? ` ${result.plugin.version}` : ""} from ${result.plugin.source}: ${result.skills.length} skill(s), on for every new session.`);
7088
+ for (const c of result.connectors) {
7089
+ const state = c.app === null ? "no AgentSky connector for it yet" : c.connected ? `uses your ${c.app} connection` : `connect ${c.app}: ${c.connect_url}`;
7090
+ console.log(` connector ${c.server}: ${state}`);
7091
+ }
7092
+ for (const s of result.skipped) console.log(` skipped ${s.part}: ${s.reason}`);
7093
+ for (const r of result.removed) console.log(` ${r.part}: ${r.result.replace("_", " ")} (no longer in the plugin)`);
7094
+ })
7095
+ );
7096
+ plugins.command("rm <name>").description("remove a plugin's skills (a skill a session still holds is switched off)").action(
7097
+ run(async (name) => {
7098
+ const result = await api("DELETE", `/plugins/${encodeURIComponent(name)}`);
7099
+ console.log(`Removed ${result.name}: ${result.parts.map((p) => `${p.part} ${p.result.replace("_", " ")}`).join(", ")}`);
7100
+ })
7101
+ );
6911
7102
  var skills = program.command("skills").description("the workspace's skill store: upload a skill, then attach it to an agent (sky skills attach, or [[skills]] in agent.toml)");
6912
7103
  skills.command("upload <dir>").description("upload a skill directory (SKILL.md at its root) as a new skill").option("--name <name>", "display name (default: the directory's name)").option("--json", "print the stored skill as JSON").action(
6913
7104
  run(async (dir, opts) => {
@@ -6999,7 +7190,7 @@ library.command("list").description("your Library, newest first").option("--sear
6999
7190
  );
7000
7191
  library.command("upload <path>").description("save a file from this computer to your Library").option("--workspace <key>", "place it in this workspace").action(
7001
7192
  run(async (path, opts) => {
7002
- const bytes = readFileSync19(path);
7193
+ const bytes = readFileSync20(path);
7003
7194
  const { artifact: artifact2 } = await uploadToLibrary({ bytes, name: basename9(path), mediaType: "application/octet-stream" }, `sky-upload-${crypto.randomUUID()}`, opts.workspace);
7004
7195
  console.log(renderLibraryArtifact(artifact2));
7005
7196
  })
@@ -7030,10 +7221,11 @@ library.command("place <id> <workspace>").description('place your artifact in a
7030
7221
  library.command("download <id> <out>").description("save one version's bytes to a file").option("--version <n>", "a saved version (the current one when omitted)").action(
7031
7222
  run(async (id, out, opts) => {
7032
7223
  const { bytes } = await downloadLibraryArtifact(id, opts.version ? Number(opts.version) : void 0);
7033
- writeFileSync11(out, bytes);
7224
+ writeFileSync10(out, bytes);
7034
7225
  console.log(`wrote ${bytes.length} bytes to ${out}`);
7035
7226
  })
7036
7227
  );
7228
+ registerLibraryLinkCommands(library);
7037
7229
  var artifact = program.command("artifact").description("artifacts: publish a task's files as a named, shareable result");
7038
7230
  artifact.command("list").description("the workspace's artifacts, or one task's with --task").option("--task <task>", "only this task's artifacts").action(
7039
7231
  run(async (opts) => {
@@ -7051,7 +7243,7 @@ artifact.command("get <id> <path>").description("read one file of an artifact; p
7051
7243
  run(async (id, path, opts) => {
7052
7244
  const bytes = await readArtifactFile(id, path);
7053
7245
  if (opts.out) {
7054
- writeFileSync11(opts.out, bytes);
7246
+ writeFileSync10(opts.out, bytes);
7055
7247
  console.log(`Wrote ${bytes.length} bytes to ${opts.out}`);
7056
7248
  } else process.stdout.write(bytes);
7057
7249
  })
@@ -7089,7 +7281,7 @@ designSystem.command("import <task> <folder>").description("import a local desig
7089
7281
  );
7090
7282
  designSystem.command("tokens <id> <file>").description("save a tokens.json file as the system's next version; --base is the version you edited").requiredOption("--base <version>", "the version the file was edited from", (value) => Number(value)).option("--note <note>", "one line saying what changed").action(
7091
7283
  run(async (id, file, opts) => {
7092
- const tokens = JSON.parse(readFileSync19(resolve9(file), "utf8"));
7284
+ const tokens = JSON.parse(readFileSync20(resolve9(file), "utf8"));
7093
7285
  console.log(renderArtifact(await saveDesignTokens(id, opts.base, tokens, opts.note)));
7094
7286
  })
7095
7287
  );
@@ -7402,7 +7594,7 @@ usageOptions(
7402
7594
  run(async (opts) => {
7403
7595
  const { bytes } = await apiBytes("GET", `/billing/usage/export${usageQuery(opts)}`);
7404
7596
  if (opts.out) {
7405
- writeFileSync11(opts.out, bytes);
7597
+ writeFileSync10(opts.out, bytes);
7406
7598
  console.log(`Wrote ${bytes.length} bytes to ${opts.out}`);
7407
7599
  } else {
7408
7600
  process.stdout.write(bytes);
@@ -8014,7 +8206,7 @@ notes.command("read <storeId> <noteId>").description("print one note").action(
8014
8206
  notes.command("save <storeId> <file>").description("write a note from a local file: --path creates one, --note saves a new version of one").option("--path <path>", "path of a new note, e.g. /projects/launch.md").option("--note <noteId>", "the note to update").action(
8015
8207
  run(async (storeId, file, opts) => {
8016
8208
  if (!opts.path === !opts.note) throw new Error("pass exactly one of --path (new note) or --note (update)");
8017
- const content = readFileSync19(file, "utf8");
8209
+ const content = readFileSync20(file, "utf8");
8018
8210
  const target = `/memory_stores/${encodeURIComponent(storeId)}/memories${opts.note ? `/${encodeURIComponent(opts.note)}` : ""}`;
8019
8211
  const { memory: memory2 } = await api("POST", target, { content, ...opts.path ? { path: opts.path } : {} });
8020
8212
  console.log(`Saved ${memory2.path} (${memory2.id})`);
@@ -8114,7 +8306,7 @@ harness.command("connect").description("run an ACP agent (the command after --)
8114
8306
  }));
8115
8307
  var traceCmd = program.command("trace").description("correlate this machine's agent work with the cloud sessions it starts (metadata only unless you choose content)");
8116
8308
  traceCmd.command("start").description("start a trace: a grant for this machine, a root span, and the spool the hooks write to").option("--name <name>", "a name for the task").option("--source <source>", "how this machine reports itself", "claude-code").option("--hooks [settings]", "also install the Claude Code hooks (default: ./.claude/settings.local.json)").option("--capture <scopes>", "also send content, redacted on this machine first: any of prompts,tool_output,files").option("--file <path>", "a file the files scope may send (repeatable)", collect).option("--dir <path>", "a folder whose files the files scope may send when a file tool touches them (repeatable)", collect).action(run(async (opts) => {
8117
- const { readState, writeState, record, installClaudeHooks, parseContentScopes, chosenPaths, fileEvent } = await import("./trace-WLTD4C22.js");
8309
+ const { readState, writeState, record, installClaudeHooks, parseContentScopes, chosenPaths, fileEvent } = await import("./trace-HV4E2BPX.js");
8118
8310
  if (readState()) throw new Error("a trace is already running here \u2014 `sky trace stop` it first");
8119
8311
  const scopes = parseContentScopes(opts.capture);
8120
8312
  const chosen = chosenPaths(opts.file ?? [], opts.dir ?? []);
@@ -8149,7 +8341,7 @@ traceCmd.command("start").description("start a trace: a grant for this machine,
8149
8341
  }));
8150
8342
  traceCmd.command("hook").description("record one Claude Code hook event read from stdin (run by the installed hooks; never fails, prints nothing)").action(async () => {
8151
8343
  try {
8152
- const { readState, record, flush, grantSender, eventsForClaudeHook, contentForClaudeHook, clearState } = await import("./trace-WLTD4C22.js");
8344
+ const { readState, record, flush, grantSender, eventsForClaudeHook, contentForClaudeHook, clearState } = await import("./trace-HV4E2BPX.js");
8153
8345
  const chunks = [];
8154
8346
  for await (const chunk of process.stdin) chunks.push(chunk);
8155
8347
  const input = JSON.parse(Buffer.concat(chunks).toString("utf8") || "{}");
@@ -8162,14 +8354,14 @@ traceCmd.command("hook").description("record one Claude Code hook event read fro
8162
8354
  }
8163
8355
  });
8164
8356
  traceCmd.command("flush").description("send what the spool holds, retrying with backoff").action(run(async () => {
8165
- const { readState, flush, grantSender } = await import("./trace-WLTD4C22.js");
8357
+ const { readState, flush, grantSender } = await import("./trace-HV4E2BPX.js");
8166
8358
  const state = readState();
8167
8359
  if (!state) throw new Error("no trace is running here");
8168
8360
  const outcome = await flush(grantSender(state), { attempts: 4 });
8169
8361
  console.log(`sent ${outcome.sent}, refused ${outcome.refused}, given up ${outcome.expired}, still pending ${outcome.pending}${outcome.stopped ? ` (stopped: ${outcome.stopped})` : ""}`);
8170
8362
  }));
8171
8363
  traceCmd.command("status").description("the running trace and its spool").action(run(async () => {
8172
- const { readState, spoolStatus } = await import("./trace-WLTD4C22.js");
8364
+ const { readState, spoolStatus } = await import("./trace-HV4E2BPX.js");
8173
8365
  const state = readState();
8174
8366
  if (!state) {
8175
8367
  console.log("No trace is running here.");
@@ -8179,7 +8371,7 @@ traceCmd.command("status").description("the running trace and its spool").action
8179
8371
  console.log(`${state.trace_id} as ${state.source}: ${spool.pending} pending, ${spool.dropped_full} dropped (spool full), ${spool.dropped_expired} given up, ${spool.refused} refused`);
8180
8372
  }));
8181
8373
  traceCmd.command("show [id]").description("the trace bundle: spans, the sessions they reach, cost counted once per session").option("--json", "print the bundle as JSON").action(run(async (id, opts) => {
8182
- const { readState } = await import("./trace-WLTD4C22.js");
8374
+ const { readState } = await import("./trace-HV4E2BPX.js");
8183
8375
  const ref = id ?? readState()?.trace_id;
8184
8376
  if (!ref) throw new Error("name a trace, or start one here");
8185
8377
  const bundle = await api("GET", `/traces/${ref}`);
@@ -8206,7 +8398,7 @@ traceCmd.command("show [id]").description("the trace bundle: spans, the sessions
8206
8398
  for (const gap of bundle.gaps) console.log(` gap: ${gap.span_id} ${gap.reason}`);
8207
8399
  }));
8208
8400
  traceCmd.command("stop").description("end the root span, send what is left, and revoke this machine's grant").action(run(async () => {
8209
- const { readState, record, flush, grantSender, clearState } = await import("./trace-WLTD4C22.js");
8401
+ const { readState, record, flush, grantSender, clearState } = await import("./trace-HV4E2BPX.js");
8210
8402
  const state = readState();
8211
8403
  if (!state) throw new Error("no trace is running here");
8212
8404
  if (state.root_span) record(() => [{ span_id: state.root_span, kind: "end", outcome: "completed" }]);
@@ -8216,7 +8408,7 @@ traceCmd.command("stop").description("end the root span, send what is left, and
8216
8408
  console.log(`Stopped ${state.trace_id}${outcome.pending ? ` (${outcome.pending} events could not be sent)` : ""}`);
8217
8409
  }));
8218
8410
  traceCmd.command("sync [payload]").description("upload this machine's agent sessions (Claude Code, Codex, Cursor, Gemini CLI and every other agent `--agents` lists) to the matching workspace's trace library, redacted here first").option("--enable", "turn sync on for this machine").option("--disable", "turn sync off; nothing more is uploaded").option("--route <match=workspace>", "send sessions whose folder path contains <match> to <workspace> (repeatable; replaces the saved rules)", collect).option("--default <workspace>", "where a session no rule matches goes").option("--keep-local", "keep sessions no rule matches on this machine (the default)").option("--session <ref>", "only this session: its id or transcript path (repeatable)", collect).option("--import <export>", "add a downloaded cloud export (claude.ai, ChatGPT, Gemini, Grok, DeepSeek \u2026: its .zip, folder or file) so sync uploads it (repeatable)", collect).option("--agents", "list the agents sync reads and which are on this machine").option("--full", "re-read every session, not only files that changed").option("--limit <n>", "at most this many changed sessions this run", (v) => Number.parseInt(v, 10)).option("--dry-run", "show what would be uploaded without uploading").option("--hook", "run from a Claude Code SessionEnd hook or Codex notify: upload that session in the background and return at once").option("--install-schedule", "also sweep every 15 minutes (macOS launchd)").option("--status", "what sync has done on this machine").option("--quiet", "print only failures").action(async (payload, opts) => {
8219
- const lib = await import("./trace-library-YMAVLH4Y.js");
8411
+ const lib = await import("./trace-library-HJWI7KM7.js");
8220
8412
  if (opts.hook) {
8221
8413
  try {
8222
8414
  let raw = payload ?? "";
@@ -8288,11 +8480,11 @@ traceCmd.command("sync [payload]").description("upload this machine's agent sess
8288
8480
  console.log(`Sweeping every 15 minutes (${plist}); a full re-read runs weekly. Log: ${log}`);
8289
8481
  }
8290
8482
  if (opts.status) {
8291
- const { readFileSync: readFileSync20 } = await import("fs");
8483
+ const { readFileSync: readFileSync21 } = await import("fs");
8292
8484
  const { join: join20 } = await import("path");
8293
8485
  let state = { sessions: {} };
8294
8486
  try {
8295
- state = JSON.parse(readFileSync20(join20(lib.syncConfigPath(), "..", "trace-sync-state.json"), "utf8"));
8487
+ state = JSON.parse(readFileSync21(join20(lib.syncConfigPath(), "..", "trace-sync-state.json"), "utf8"));
8296
8488
  } catch {
8297
8489
  }
8298
8490
  const counts = /* @__PURE__ */ new Map();
@@ -8331,7 +8523,7 @@ traceCmd.command("search <query...>").description("search every session in a wor
8331
8523
  console.log(opts.json ? JSON.stringify(page, null, 2) : renderContextPage(page));
8332
8524
  }));
8333
8525
  traceCmd.command("library").description("list the sessions in a workspace's trace library, most recently updated first").option("--workspace <slug>", "the workspace (default: the current one)").option("--limit <n>", "how many", (v) => Number.parseInt(v, 10), 20).option("--json", "print the page as JSON").action(run(async (opts) => {
8334
- const { libraryRequest } = await import("./trace-library-YMAVLH4Y.js");
8526
+ const { libraryRequest } = await import("./trace-library-HJWI7KM7.js");
8335
8527
  const workspace2 = opts.workspace ?? currentUniverse();
8336
8528
  if (!workspace2) throw new Error("name a workspace with --workspace");
8337
8529
  const page = await libraryRequest("GET", `/trace-library?limit=${opts.limit}`, workspace2);
@@ -1,7 +1,7 @@
1
1
  import {
2
2
  USER_AGENT,
3
3
  configPath
4
- } from "./chunk-S4YG3TXA.js";
4
+ } from "./chunk-LPUGEMCV.js";
5
5
  import {
6
6
  TRACE_CONTENT_SCOPES,
7
7
  redactTraceText
@@ -1,11 +1,11 @@
1
1
  import {
2
2
  ApiError
3
- } from "./chunk-KWLEADJQ.js";
3
+ } from "./chunk-QROAAJN2.js";
4
4
  import {
5
5
  USER_AGENT,
6
6
  apiBase,
7
7
  apiToken
8
- } from "./chunk-S4YG3TXA.js";
8
+ } from "./chunk-LPUGEMCV.js";
9
9
  import {
10
10
  SessionSourceCollector,
11
11
  publicRemote,
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@agentsky/sky",
3
- "version": "2.24.1",
3
+ "version": "2.25.0",
4
4
  "description": "sky \u2014 the AgentSky developer CLI: launch and talk to long-lived agents from your terminal.",
5
5
  "license": "MIT",
6
6
  "type": "module",