@agentsky/sky 2.14.0 → 2.15.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.14.0";
41
+ var CLI_VERSION = "2.15.0";
42
42
  var USER_AGENT = `sky-cli/${CLI_VERSION} (${process.platform}; node/${process.versions.node})`;
43
43
 
44
44
  export {
@@ -19737,6 +19737,7 @@ var SessionSourceCollector = class {
19737
19737
  summed = { input_tokens: 0, output_tokens: 0, cache_read_tokens: 0, cache_write_tokens: 0, reasoning_tokens: 0 };
19738
19738
  cumulative = null;
19739
19739
  meta = {};
19740
+ summaryTitle = "";
19740
19741
  push(raw) {
19741
19742
  const record2 = obj(raw);
19742
19743
  if (!record2) return;
@@ -19757,6 +19758,15 @@ var SessionSourceCollector = class {
19757
19758
  this.model(str(info?.model) || str(payload.model));
19758
19759
  return;
19759
19760
  }
19761
+ if (type === "custom-title") {
19762
+ const title = str(record2.customTitle).slice(0, 120);
19763
+ if (title) this.meta.title = title;
19764
+ return;
19765
+ }
19766
+ if (type === "summary") {
19767
+ this.summaryTitle = str(record2.summary).slice(0, 120) || this.summaryTitle;
19768
+ return;
19769
+ }
19760
19770
  if (type === "response_item") return this.time(str(record2.timestamp));
19761
19771
  if (type === "user" || type === "assistant") return this.claudeLine(record2, type);
19762
19772
  }
@@ -19765,6 +19775,7 @@ var SessionSourceCollector = class {
19765
19775
  const usage = Object.fromEntries(Object.entries(this.cumulative ?? this.summed).filter(([, value]) => num(value) > 0));
19766
19776
  return {
19767
19777
  ...this.meta,
19778
+ ...!this.meta.title && this.summaryTitle ? { title: this.summaryTitle } : {},
19768
19779
  ...models.length ? { models } : {},
19769
19780
  ...this.efforts.size ? { effort: [...this.efforts].join(", ") } : {},
19770
19781
  ...Object.keys(usage).length ? { usage } : {}
@@ -3,7 +3,7 @@ import {
3
3
  apiBase,
4
4
  apiToken,
5
5
  currentUniverse
6
- } from "./chunk-VJEE2ALN.js";
6
+ } from "./chunk-R5FKQQMG.js";
7
7
 
8
8
  // src/api.ts
9
9
  var ApiError = class extends Error {
@@ -132,7 +132,7 @@ async function resolveSessionRef(ref) {
132
132
  return agent.defaultSessionId;
133
133
  }
134
134
  async function* streamEvents(sessionId, signal) {
135
- const { parseSseStream } = await import("./src-EJU5U2GO.js");
135
+ const { parseSseStream } = await import("./src-KLP774OA.js");
136
136
  const res = await fetch(
137
137
  `${apiBase()}/sessions/${encodeURIComponent(sessionId)}/stream`,
138
138
  {
package/dist/index.js CHANGED
@@ -9,7 +9,7 @@ import {
9
9
  resolveSessionRef,
10
10
  streamEvents,
11
11
  uploadFile
12
- } from "./chunk-FOJP33RS.js";
12
+ } from "./chunk-Y3NTKJLA.js";
13
13
  import {
14
14
  CLI_VERSION,
15
15
  USER_AGENT,
@@ -20,7 +20,7 @@ import {
20
20
  currentUniverse,
21
21
  loadConfig,
22
22
  saveConfig
23
- } from "./chunk-VJEE2ALN.js";
23
+ } from "./chunk-R5FKQQMG.js";
24
24
  import {
25
25
  AGENT_TYPES,
26
26
  MODEL_SUBSCRIPTION_PLAN_PHRASE,
@@ -40,13 +40,13 @@ import {
40
40
  skillRefSchema,
41
41
  splitMcpServers,
42
42
  supersededBy
43
- } from "./chunk-7OM2B5SE.js";
43
+ } from "./chunk-RHRREQMF.js";
44
44
  import "./chunk-MLKGABMK.js";
45
45
 
46
46
  // src/index.ts
47
47
  import { existsSync as existsSync10, readFileSync as readFileSync13, writeFileSync as writeFileSync6 } from "fs";
48
48
  import { basename as basename6, resolve as resolve7 } from "path";
49
- import { createInterface as createInterface4 } from "readline";
49
+ import { createInterface as createInterface5 } from "readline";
50
50
  import { Command } from "commander";
51
51
 
52
52
  // src/files.ts
@@ -1007,7 +1007,7 @@ function mcpServers(harness2, cwd, home = homedir2()) {
1007
1007
  function remoteWithoutCredentials(remote) {
1008
1008
  return remote.trim().replace(/\/\/[^@/]+@/, "//").replace(/^[^@/]+@([^:]+):/, "$1:");
1009
1009
  }
1010
- function workspaceState(cwd, harness2, skills2, home = homedir2()) {
1010
+ function workspaceState(cwd, harness2, skills2, home = homedir2(), title = null) {
1011
1011
  const present = !!cwd && isDir(cwd);
1012
1012
  const root = present ? git(cwd, "rev-parse", "--show-toplevel")?.trim() || null : null;
1013
1013
  let gitState = null;
@@ -1033,6 +1033,7 @@ function workspaceState(cwd, harness2, skills2, home = homedir2()) {
1033
1033
  format: "agentsky.import-workspace",
1034
1034
  format_version: 1,
1035
1035
  harness: harness2,
1036
+ title: title?.trim().slice(0, 120) || null,
1036
1037
  cwd: cwd ? cwd.replace(home, "~") : null,
1037
1038
  project: cwd ? basename3(root ?? cwd) : null,
1038
1039
  git: gitState,
@@ -1064,6 +1065,21 @@ function skillFiles(skill) {
1064
1065
  if (existsSync3(skill.dir)) walk(skill.dir, 0);
1065
1066
  return out;
1066
1067
  }
1068
+ function codexThreadName(sessionId, home = homedir2()) {
1069
+ let name = null;
1070
+ try {
1071
+ for (const line of readFileSync4(join2(process.env.CODEX_HOME ?? join2(home, ".codex"), "session_index.jsonl"), "utf8").split("\n")) {
1072
+ if (!line.includes(sessionId)) continue;
1073
+ try {
1074
+ const entry2 = JSON.parse(line);
1075
+ if (entry2.id === sessionId && typeof entry2.thread_name === "string" && entry2.thread_name.trim()) name = entry2.thread_name.trim();
1076
+ } catch {
1077
+ }
1078
+ }
1079
+ } catch {
1080
+ }
1081
+ return name;
1082
+ }
1067
1083
 
1068
1084
  // src/import-files.ts
1069
1085
  var MAX_ATTACHED_FILE_BYTES = 10 * 1024 * 1024;
@@ -1248,8 +1264,8 @@ function collectSessionFiles(records, opts) {
1248
1264
  const lines = [];
1249
1265
  const attached = [];
1250
1266
  let bytes = 0;
1251
- const state = workspaceState(opts.cwd, opts.harness, skills2, home);
1252
- const described = !!opts.cwd || state.manifest.skills.length > 0 || state.manifest.mcp_servers.length > 0;
1267
+ const state = workspaceState(opts.cwd, opts.harness, skills2, home, opts.title ?? null);
1268
+ const described = !!opts.cwd || !!state.manifest.title || state.manifest.skills.length > 0 || state.manifest.mcp_servers.length > 0;
1253
1269
  const generated = [
1254
1270
  ...described ? [{ name: "agentsky/workspace.json", mediaType: "application/json", data: Buffer.from(JSON.stringify(state.manifest, null, 2)) }] : [],
1255
1271
  ...state.patch ? [{ name: "agentsky/uncommitted.patch", mediaType: "text/x-diff", data: Buffer.from(state.patch) }] : []
@@ -1613,7 +1629,13 @@ function prepareImport(session2, summaryPath, options = {}) {
1613
1629
  const sourceId = nativeId ?? session2.sessionId;
1614
1630
  if (!/^[A-Za-z0-9_-]{1,200}$/.test(sourceId) || redactLine2(JSON.stringify(sourceId)) !== JSON.stringify(sourceId)) throw new Error("The source conversation has an invalid identifier.");
1615
1631
  const meta = source.result();
1616
- const files2 = options.files === false ? { lines: [], bytes: 0, attached: [], leftOut: [], setup: { skills: [], missingSkills: [], mcpServers: [], git: false } } : collectSessionFiles(records, { harness: session2.harness, cwd: meta.cwd ?? (session2.harness === "claude_code" ? session2.workspace : ""), budget: MAX_IMPORT_BYTES - outputBytes - SUMMARY_RESERVE_BYTES, exclude: session2.files });
1632
+ const files2 = options.files === false ? { lines: [], bytes: 0, attached: [], leftOut: [], setup: { skills: [], missingSkills: [], mcpServers: [], git: false } } : collectSessionFiles(records, {
1633
+ harness: session2.harness,
1634
+ cwd: meta.cwd ?? (session2.harness === "claude_code" ? session2.workspace : ""),
1635
+ budget: MAX_IMPORT_BYTES - outputBytes - SUMMARY_RESERVE_BYTES,
1636
+ exclude: session2.files,
1637
+ title: meta.title ?? (session2.harness === "codex" ? codexThreadName(session2.sessionId) : null)
1638
+ });
1617
1639
  const attachedNote = files2.attached.length ? ` The ${files2.attached.length} local ${files2.attached.length === 1 ? "file" : "files"} it read, wrote or ran under, the skills it loaded and its workspace description (repository state and tool servers, agentsky/workspace.json) are attached as well (listed in artifacts).` : "";
1618
1640
  let summaryJson;
1619
1641
  if (summaryPath) {
@@ -3192,6 +3214,7 @@ function renderRequest(request) {
3192
3214
  }
3193
3215
 
3194
3216
  // src/workspace.ts
3217
+ import { createInterface as createInterface4 } from "readline";
3195
3218
  var KINDS = ["TOOL_CALL", "SPEND_CAP", "CALL_COUNT", "CAPABILITY"];
3196
3219
  async function workspaceSlug(explicit) {
3197
3220
  if (explicit) return explicit;
@@ -3284,6 +3307,51 @@ function renderPolicy(rule) {
3284
3307
  const state = rule.enabled ? "on " : "off";
3285
3308
  return `${state} ${rule.layer.padEnd(9)} ${rule.kind.padEnd(10)} ${rule.name} ${JSON.stringify(rule.config)} ${rule.id}`;
3286
3309
  }
3310
+ var REMOVED_KINDS = [
3311
+ ["sessions", "sessions and their transcripts"],
3312
+ ["agents", "agents"],
3313
+ ["artifacts", "artifacts"],
3314
+ ["files", "task files"],
3315
+ ["memory_stores", "memory stores"],
3316
+ ["routines", "routines"],
3317
+ ["channels", "channel connections"],
3318
+ ["webhooks", "webhooks"],
3319
+ ["api_keys", "API keys"],
3320
+ ["vaults", "vaults"],
3321
+ ["skills", "skills"],
3322
+ ["environments", "environments"],
3323
+ ["connections", "connected apps"],
3324
+ ["traces", "uploaded traces"],
3325
+ ["members", "other members"],
3326
+ ["invites", "pending invitations"]
3327
+ ];
3328
+ async function deletionPreview(slug) {
3329
+ return api("GET", `/universes/${encodeURIComponent(slug)}/deletion`);
3330
+ }
3331
+ function renderDeletionPreview(preview) {
3332
+ if (!preview.can_delete) return [`${preview.workspace.slug} cannot be deleted:`, ...preview.blockers.map((b) => ` ${b.message}`)];
3333
+ const lines = [`Deleting ${preview.workspace.slug} (${preview.workspace.name}) permanently removes:`];
3334
+ const removed = REMOVED_KINDS.filter(([key]) => (preview.removes[key] ?? 0) > 0);
3335
+ for (const [key, label] of removed) lines.push(` ${preview.removes[key]} ${label}`);
3336
+ if (!removed.length) lines.push(" nothing: the workspace is empty");
3337
+ const running = preview.removes.running_sessions ?? 0;
3338
+ if (running) lines.push(`${running} running session${running === 1 ? " is" : "s are"} stopped first.`);
3339
+ if (preview.wallet) lines.push(`$${(preview.wallet.balance_micros / 1e6).toFixed(2)} in its wallet goes back to ${preview.wallet.returns_to ?? "you"}.`);
3340
+ lines.push("This cannot be undone.");
3341
+ return lines;
3342
+ }
3343
+ async function deleteWorkspace(slug) {
3344
+ return (await api("DELETE", `/universes/${encodeURIComponent(slug)}`)).deleted;
3345
+ }
3346
+ function typedConfirmation(slug) {
3347
+ return new Promise((done) => {
3348
+ const rl = createInterface4({ input: process.stdin, output: process.stdout });
3349
+ rl.question(`Type ${slug} to delete it: `, (answer) => {
3350
+ rl.close();
3351
+ done(answer.trim() === slug);
3352
+ });
3353
+ });
3354
+ }
3287
3355
 
3288
3356
  // src/harness.ts
3289
3357
  import { existsSync as existsSync9, mkdirSync as mkdirSync3, readFileSync as readFileSync12, writeFileSync as writeFileSync5 } from "fs";
@@ -3565,6 +3633,19 @@ universe.command("remove <member>").description("remove a member (user id or ema
3565
3633
  console.log(`Removed ${member.email ?? member.user_id}`);
3566
3634
  })
3567
3635
  );
3636
+ async function deleteWorkspaceCommand(slug, opts) {
3637
+ const preview = await deletionPreview(slug);
3638
+ for (const line of renderDeletionPreview(preview)) console.log(line);
3639
+ if (!preview.can_delete) process.exit(1);
3640
+ if (!opts.yes && !await typedConfirmation(slug)) {
3641
+ console.log("Aborted.");
3642
+ return;
3643
+ }
3644
+ const deleted = await deleteWorkspace(slug);
3645
+ if (currentUniverse() === slug) saveConfig({ ...loadConfig(), currentUniverse: void 0 });
3646
+ console.log(`Deleted ${deleted.slug}${deleted.sessions_stopped ? ` \xB7 stopped ${deleted.sessions_stopped} running session${deleted.sessions_stopped === 1 ? "" : "s"}` : ""}`);
3647
+ }
3648
+ universe.command("delete <slug>").description("permanently delete a workspace you own and everything in it (asks you to type the slug)").option("-y, --yes", "skip typing the slug").action(run(deleteWorkspaceCommand));
3568
3649
  universe.command("join <token>").description("accept an invitation sent to your verified email").action(
3569
3650
  run(async (token) => {
3570
3651
  const workspace2 = await joinWorkspace(token);
@@ -3582,6 +3663,7 @@ workspace.command("list").action(
3582
3663
  }
3583
3664
  })
3584
3665
  );
3666
+ workspace.command("delete <slug>").description("permanently delete a workspace you own and everything in it (asks you to type the slug)").option("-y, --yes", "skip typing the slug").action(run(deleteWorkspaceCommand));
3585
3667
  var policy = program.command("policy").description("policy rules: tool calls, spend caps, call counts, capabilities");
3586
3668
  async function policyScope(opts) {
3587
3669
  return opts.session ? { session: await resolveSessionRef(opts.session) } : { slug: await workspaceSlug(opts.universe) };
@@ -3985,7 +4067,7 @@ async function sendAndFollow(sessionId, text, opts) {
3985
4067
  async function chatLoop(sessionId, opts = {}) {
3986
4068
  console.log(`Chatting with ${sessionId} \u2014 Ctrl-C to leave.`);
3987
4069
  const controller = new AbortController();
3988
- const rl = createInterface4({ input: process.stdin, output: process.stdout, prompt: "> " });
4070
+ const rl = createInterface5({ input: process.stdin, output: process.stdout, prompt: "> " });
3989
4071
  let system = opts.system;
3990
4072
  void (async () => {
3991
4073
  try {
@@ -4233,7 +4315,7 @@ program.command("import").description("import a local Claude Code or Codex sessi
4233
4315
  console.log(` ${ws}`);
4234
4316
  });
4235
4317
  console.log();
4236
- const rl = createInterface4({ input: process.stdin, output: process.stdout });
4318
+ const rl = createInterface5({ input: process.stdin, output: process.stdout });
4237
4319
  const answer = await new Promise(
4238
4320
  (resolve8) => rl.question(
4239
4321
  `Import which session? [1-${candidates.length}, or comma-separated, or "all"]: `,
@@ -4261,7 +4343,7 @@ program.command("import").description("import a local Claude Code or Codex sessi
4261
4343
  }
4262
4344
  if (!autoConfirm) {
4263
4345
  if (nonInteractive) throw new Error("Use --yes to confirm this transfer in a non-interactive terminal.");
4264
- const prompt = createInterface4({ input: process.stdin, output: process.stdout });
4346
+ const prompt = createInterface5({ input: process.stdin, output: process.stdout });
4265
4347
  const answer = await new Promise((resolve8) => prompt.question("Upload these selected conversations? [y/N] ", (value) => {
4266
4348
  prompt.close();
4267
4349
  resolve8(value);
@@ -4809,7 +4891,7 @@ harness.command("connect").description("run an ACP agent (the command after --)
4809
4891
  }));
4810
4892
  var traceCmd = program.command("trace").description("correlate this machine's agent work with the cloud sessions it starts (metadata only unless you choose content)");
4811
4893
  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) => {
4812
- const { readState, writeState, record, installClaudeHooks, parseContentScopes, chosenPaths, fileEvent } = await import("./trace-YKEGRVJN.js");
4894
+ const { readState, writeState, record, installClaudeHooks, parseContentScopes, chosenPaths, fileEvent } = await import("./trace-PMUETYJS.js");
4813
4895
  if (readState()) throw new Error("a trace is already running here \u2014 `sky trace stop` it first");
4814
4896
  const scopes = parseContentScopes(opts.capture);
4815
4897
  const chosen = chosenPaths(opts.file ?? [], opts.dir ?? []);
@@ -4844,7 +4926,7 @@ traceCmd.command("start").description("start a trace: a grant for this machine,
4844
4926
  }));
4845
4927
  traceCmd.command("hook").description("record one Claude Code hook event read from stdin (run by the installed hooks; never fails, prints nothing)").action(async () => {
4846
4928
  try {
4847
- const { readState, record, flush, grantSender, eventsForClaudeHook, contentForClaudeHook, clearState } = await import("./trace-YKEGRVJN.js");
4929
+ const { readState, record, flush, grantSender, eventsForClaudeHook, contentForClaudeHook, clearState } = await import("./trace-PMUETYJS.js");
4848
4930
  const chunks = [];
4849
4931
  for await (const chunk of process.stdin) chunks.push(chunk);
4850
4932
  const input = JSON.parse(Buffer.concat(chunks).toString("utf8") || "{}");
@@ -4857,14 +4939,14 @@ traceCmd.command("hook").description("record one Claude Code hook event read fro
4857
4939
  }
4858
4940
  });
4859
4941
  traceCmd.command("flush").description("send what the spool holds, retrying with backoff").action(run(async () => {
4860
- const { readState, flush, grantSender } = await import("./trace-YKEGRVJN.js");
4942
+ const { readState, flush, grantSender } = await import("./trace-PMUETYJS.js");
4861
4943
  const state = readState();
4862
4944
  if (!state) throw new Error("no trace is running here");
4863
4945
  const outcome = await flush(grantSender(state), { attempts: 4 });
4864
4946
  console.log(`sent ${outcome.sent}, refused ${outcome.refused}, given up ${outcome.expired}, still pending ${outcome.pending}${outcome.stopped ? ` (stopped: ${outcome.stopped})` : ""}`);
4865
4947
  }));
4866
4948
  traceCmd.command("status").description("the running trace and its spool").action(run(async () => {
4867
- const { readState, spoolStatus } = await import("./trace-YKEGRVJN.js");
4949
+ const { readState, spoolStatus } = await import("./trace-PMUETYJS.js");
4868
4950
  const state = readState();
4869
4951
  if (!state) {
4870
4952
  console.log("No trace is running here.");
@@ -4874,7 +4956,7 @@ traceCmd.command("status").description("the running trace and its spool").action
4874
4956
  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`);
4875
4957
  }));
4876
4958
  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) => {
4877
- const { readState } = await import("./trace-YKEGRVJN.js");
4959
+ const { readState } = await import("./trace-PMUETYJS.js");
4878
4960
  const ref = id ?? readState()?.trace_id;
4879
4961
  if (!ref) throw new Error("name a trace, or start one here");
4880
4962
  const bundle = await api("GET", `/traces/${ref}`);
@@ -4901,7 +4983,7 @@ traceCmd.command("show [id]").description("the trace bundle: spans, the sessions
4901
4983
  for (const gap of bundle.gaps) console.log(` gap: ${gap.span_id} ${gap.reason}`);
4902
4984
  }));
4903
4985
  traceCmd.command("stop").description("end the root span, send what is left, and revoke this machine's grant").action(run(async () => {
4904
- const { readState, record, flush, grantSender, clearState } = await import("./trace-YKEGRVJN.js");
4986
+ const { readState, record, flush, grantSender, clearState } = await import("./trace-PMUETYJS.js");
4905
4987
  const state = readState();
4906
4988
  if (!state) throw new Error("no trace is running here");
4907
4989
  if (state.root_span) record(() => [{ span_id: state.root_span, kind: "end", outcome: "completed" }]);
@@ -4911,7 +4993,7 @@ traceCmd.command("stop").description("end the root span, send what is left, and
4911
4993
  console.log(`Stopped ${state.trace_id}${outcome.pending ? ` (${outcome.pending} events could not be sent)` : ""}`);
4912
4994
  }));
4913
4995
  traceCmd.command("sync [payload]").description("upload this machine's Claude Code and Codex sessions 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("--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) => {
4914
- const lib = await import("./trace-library-6BK5GJVD.js");
4996
+ const lib = await import("./trace-library-FIMBRED6.js");
4915
4997
  if (opts.hook) {
4916
4998
  try {
4917
4999
  let raw = payload ?? "";
@@ -5009,7 +5091,7 @@ traceCmd.command("sync [payload]").description("upload this machine's Claude Cod
5009
5091
  })();
5010
5092
  });
5011
5093
  traceCmd.command("search <query...>").description("search every session in a workspace's trace library (literal substring)").option("--workspace <slug>", "the workspace to search (default: the current one)").option("--limit <n>", "hits per page", (v) => Number.parseInt(v, 10), 20).option("--cursor <cursor>", "the next page of an earlier search").option("--json", "print the page as JSON").action(run(async (words, opts) => {
5012
- const { libraryRequest } = await import("./trace-library-6BK5GJVD.js");
5094
+ const { libraryRequest } = await import("./trace-library-FIMBRED6.js");
5013
5095
  const workspace2 = opts.workspace ?? currentUniverse();
5014
5096
  if (!workspace2) throw new Error("name a workspace with --workspace");
5015
5097
  const params = new URLSearchParams({ q: words.join(" "), scope: "traces", limit: String(opts.limit), ...opts.cursor ? { cursor: opts.cursor } : {} });
@@ -5026,7 +5108,7 @@ traceCmd.command("search <query...>").description("search every session in a wor
5026
5108
  if (page.nextCursor) console.log(`More: sky trace search ${JSON.stringify(words.join(" "))} --workspace ${workspace2} --cursor ${page.nextCursor}`);
5027
5109
  }));
5028
5110
  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) => {
5029
- const { libraryRequest } = await import("./trace-library-6BK5GJVD.js");
5111
+ const { libraryRequest } = await import("./trace-library-FIMBRED6.js");
5030
5112
  const workspace2 = opts.workspace ?? currentUniverse();
5031
5113
  if (!workspace2) throw new Error("name a workspace with --workspace");
5032
5114
  const page = await libraryRequest("GET", `/trace-library?limit=${opts.limit}`, workspace2);
package/dist/products.js CHANGED
@@ -8,7 +8,7 @@ import {
8
8
  skillsArraySchema,
9
9
  systemMessageEventSchema,
10
10
  userMessageEventSchema
11
- } from "./chunk-7OM2B5SE.js";
11
+ } from "./chunk-RHRREQMF.js";
12
12
  import "./chunk-MLKGABMK.js";
13
13
 
14
14
  // ../../packages/spec/src/compatibility.ts
@@ -1,7 +1,7 @@
1
1
  import {
2
2
  external_exports,
3
3
  messagePartSchema
4
- } from "./chunk-7OM2B5SE.js";
4
+ } from "./chunk-RHRREQMF.js";
5
5
  import "./chunk-MLKGABMK.js";
6
6
 
7
7
  // ../../packages/chat/src/stream.ts
@@ -1,11 +1,11 @@
1
1
  import {
2
2
  USER_AGENT,
3
3
  configPath
4
- } from "./chunk-VJEE2ALN.js";
4
+ } from "./chunk-R5FKQQMG.js";
5
5
  import {
6
6
  TRACE_CONTENT_SCOPES,
7
7
  redactTraceText
8
- } from "./chunk-7OM2B5SE.js";
8
+ } from "./chunk-RHRREQMF.js";
9
9
  import "./chunk-MLKGABMK.js";
10
10
 
11
11
  // src/trace.ts
@@ -1,16 +1,16 @@
1
1
  import {
2
2
  ApiError
3
- } from "./chunk-FOJP33RS.js";
3
+ } from "./chunk-Y3NTKJLA.js";
4
4
  import {
5
5
  USER_AGENT,
6
6
  apiBase,
7
7
  apiToken
8
- } from "./chunk-VJEE2ALN.js";
8
+ } from "./chunk-R5FKQQMG.js";
9
9
  import {
10
10
  SessionSourceCollector,
11
11
  publicRemote,
12
12
  redactTraceText
13
- } from "./chunk-7OM2B5SE.js";
13
+ } from "./chunk-RHRREQMF.js";
14
14
  import "./chunk-MLKGABMK.js";
15
15
 
16
16
  // src/trace-library.ts
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@agentsky/sky",
3
- "version": "2.14.0",
3
+ "version": "2.15.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",