@fdcn/sourcefed 0.3.5 → 0.3.7

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 CHANGED
@@ -11363,36 +11363,10 @@ async function writeResponse(outgoing, response) {
11363
11363
  stream.pipe(outgoing);
11364
11364
  });
11365
11365
  }
11366
- var RequestRouter = class {
11367
- pending = /* @__PURE__ */ new Map();
11368
- cursor = 1;
11369
- nextID() {
11370
- return this.cursor++;
11371
- }
11372
- register(id) {
11373
- return new Promise((resolve, reject) => {
11374
- this.pending.set(id, { resolve, reject });
11375
- });
11376
- }
11377
- settle(id, frame) {
11378
- const pending = this.pending.get(id);
11379
- if (!pending) return;
11380
- this.pending.delete(id);
11381
- if (frame.error) pending.reject(new Error(frame.error));
11382
- else pending.resolve(frame.result);
11383
- }
11384
- rejectAll(error2) {
11385
- for (const { reject } of this.pending.values()) reject(error2);
11386
- this.pending.clear();
11387
- }
11388
- };
11389
11366
  function defaultDaemonUrl() {
11390
11367
  const port = process.env.SOURCEFED_DAEMON_PORT ?? 18787;
11391
11368
  return `http://127.0.0.1:${port}`;
11392
11369
  }
11393
- function sleep(ms) {
11394
- return new Promise((resolve) => setTimeout(resolve, ms));
11395
- }
11396
11370
  async function withTimeout(promise, ms, message) {
11397
11371
  let timer;
11398
11372
  try {
@@ -11725,164 +11699,225 @@ function parseDaemonFrame(line) {
11725
11699
  return void 0;
11726
11700
  }
11727
11701
  }
11702
+ var DaemonEventStream = class {
11703
+ constructor(url2, headers, onEvents, acknowledge, onClose) {
11704
+ this.url = url2;
11705
+ this.headers = headers;
11706
+ this.onEvents = onEvents;
11707
+ this.acknowledge = acknowledge;
11708
+ this.onClose = onClose;
11709
+ }
11710
+ controller = new AbortController();
11711
+ subscribed = Promise.withResolvers();
11712
+ stream;
11713
+ delivering = Promise.resolve();
11714
+ closing;
11715
+ ready = false;
11716
+ failedDelivery = false;
11717
+ async start(signal) {
11718
+ const abort = () => {
11719
+ void this.close();
11720
+ };
11721
+ signal?.addEventListener("abort", abort, { once: true });
11722
+ const setup = withTimeout(this.subscribed.promise, 15e3, `sourcefed event stream did not subscribe at ${this.url}`);
11723
+ if (signal?.aborted) abort();
11724
+ const running = this.run();
11725
+ void running.finally(() => signal?.removeEventListener("abort", abort));
11726
+ try {
11727
+ await setup;
11728
+ } catch (error2) {
11729
+ await this.close();
11730
+ throw error2;
11731
+ }
11732
+ }
11733
+ close() {
11734
+ if (!this.closing) {
11735
+ this.subscribed.reject(new Error("sourcefed event stream closed"));
11736
+ if (!this.ready) this.controller.abort();
11737
+ this.closing = this.drain();
11738
+ }
11739
+ return this.closing;
11740
+ }
11741
+ async drain() {
11742
+ try {
11743
+ await withTimeout(this.delivering, 15e3, "sourcefed event delivery did not drain");
11744
+ } catch (error2) {
11745
+ console.error(`[sourcefed] closing event stream: ${String(error2)}`);
11746
+ } finally {
11747
+ this.controller.abort();
11748
+ this.stream?.abort();
11749
+ this.onClose();
11750
+ }
11751
+ }
11752
+ async run() {
11753
+ let consecutiveFailures = 0;
11754
+ while (!this.controller.signal.aborted) {
11755
+ this.failedDelivery = false;
11756
+ try {
11757
+ await this.read();
11758
+ consecutiveFailures = 0;
11759
+ } catch (error2) {
11760
+ if (!this.controller.signal.aborted && !this.failedDelivery && ++consecutiveFailures === 1) {
11761
+ console.error(`[sourcefed] event stream ended: ${String(error2)}`);
11762
+ }
11763
+ }
11764
+ await this.waitForDelivery();
11765
+ if (!this.controller.signal.aborted) await pause(500, this.controller.signal);
11766
+ }
11767
+ }
11768
+ async read() {
11769
+ const controller = new AbortController();
11770
+ const abort = () => controller.abort();
11771
+ this.stream = controller;
11772
+ this.controller.signal.addEventListener("abort", abort, { once: true });
11773
+ let reader;
11774
+ try {
11775
+ this.controller.signal.throwIfAborted();
11776
+ const response = await fetch(this.url, { signal: controller.signal, headers: this.headers });
11777
+ if (!response.ok || !response.body) {
11778
+ await response.body?.cancel();
11779
+ throw new Error(`event stream failed: ${response.status}`);
11780
+ }
11781
+ reader = response.body.getReader();
11782
+ const decoder = new TextDecoder();
11783
+ let buffer = "";
11784
+ while (!controller.signal.aborted) {
11785
+ const { done, value } = await reader.read();
11786
+ if (done) return;
11787
+ buffer += decoder.decode(value, { stream: true });
11788
+ const frames = buffer.split("\n\n");
11789
+ buffer = frames.pop() ?? "";
11790
+ for (const chunk of frames) await this.frame(chunk);
11791
+ }
11792
+ } finally {
11793
+ await reader?.cancel().catch(() => void 0);
11794
+ reader?.releaseLock();
11795
+ this.controller.signal.removeEventListener("abort", abort);
11796
+ if (this.stream === controller) this.stream = void 0;
11797
+ }
11798
+ }
11799
+ async frame(chunk) {
11800
+ if (this.closing || this.controller.signal.aborted) return;
11801
+ for (const line of chunk.split("\n")) {
11802
+ if (!line.startsWith("data: ")) continue;
11803
+ const frame = parseDaemonFrame(line.slice(6));
11804
+ if (!frame || !("type" in frame)) continue;
11805
+ if (frame.type === "subscribed") {
11806
+ this.ready = true;
11807
+ this.subscribed.resolve();
11808
+ }
11809
+ if (frame.type === "event" && frame.events.length > 0) {
11810
+ this.deliver(frame.events);
11811
+ await this.waitForDelivery();
11812
+ }
11813
+ }
11814
+ }
11815
+ deliver(events2) {
11816
+ this.delivering = this.delivering.then(async () => {
11817
+ if (this.failedDelivery || this.controller.signal.aborted) return;
11818
+ try {
11819
+ await this.onEvents(events2);
11820
+ await this.acknowledge(events2, this.controller.signal);
11821
+ } catch (error2) {
11822
+ if (!this.controller.signal.aborted) console.error(`[sourcefed] event delivery failed: ${String(error2)}`);
11823
+ this.failedDelivery = true;
11824
+ this.stream?.abort();
11825
+ }
11826
+ });
11827
+ }
11828
+ async waitForDelivery() {
11829
+ if (this.controller.signal.aborted) return;
11830
+ const stopped = Promise.withResolvers();
11831
+ const abort = () => stopped.resolve();
11832
+ this.controller.signal.addEventListener("abort", abort, { once: true });
11833
+ try {
11834
+ await Promise.race([this.delivering, stopped.promise]);
11835
+ } finally {
11836
+ this.controller.signal.removeEventListener("abort", abort);
11837
+ }
11838
+ }
11839
+ };
11840
+ function pause(ms, signal) {
11841
+ return new Promise((resolve) => {
11842
+ const finish = () => {
11843
+ clearTimeout(timer);
11844
+ signal.removeEventListener("abort", finish);
11845
+ resolve();
11846
+ };
11847
+ const timer = setTimeout(finish, ms);
11848
+ signal.addEventListener("abort", finish, { once: true });
11849
+ if (signal.aborted) finish();
11850
+ });
11851
+ }
11728
11852
  async function connectDaemonClient(options) {
11729
11853
  const url2 = options.url ?? process.env.SOURCEFED_DAEMON_URL ?? defaultDaemonUrl();
11730
11854
  return new HttpDaemonClient(url2, options.token ?? process.env.SOURCEFED_DAEMON_TOKEN);
11731
11855
  }
11732
11856
  var HttpDaemonClient = class {
11733
- baseURL;
11734
- token;
11735
- router = new RequestRouter();
11736
- listeners = /* @__PURE__ */ new Map();
11737
- streams = /* @__PURE__ */ new Set();
11738
11857
  constructor(baseURL, token) {
11739
- this.baseURL = baseURL.replace(/\/+$/, "");
11740
11858
  this.token = token;
11859
+ this.baseURL = baseURL.replace(/\/+$/, "");
11741
11860
  }
11861
+ baseURL;
11862
+ streams = /* @__PURE__ */ new Set();
11863
+ lifetime = new AbortController();
11864
+ cursor = 0;
11865
+ closing;
11742
11866
  headers() {
11743
11867
  return this.token ? { authorization: `Bearer ${this.token}` } : {};
11744
11868
  }
11745
- async request(method, params) {
11746
- const id = this.router.nextID();
11747
- const promise = this.router.register(id);
11869
+ async request(method, params, signal = this.lifetime.signal) {
11870
+ if (this.closing && signal === this.lifetime.signal) throw new Error("daemon closed");
11871
+ signal.throwIfAborted();
11872
+ const response = await fetch(`${this.baseURL}/rpc`, {
11873
+ method: "POST",
11874
+ headers: { "content-type": "application/json", ...this.headers() },
11875
+ body: JSON.stringify({ id: ++this.cursor, method, params }),
11876
+ signal: AbortSignal.any([signal, this.lifetime.signal, AbortSignal.timeout(15e3)])
11877
+ });
11878
+ const frame = await response.json();
11879
+ if (!response.ok || frame.error) throw new Error(frame.error ?? `daemon request failed: ${response.status}`);
11880
+ return frame.result;
11881
+ }
11882
+ async subscribe(target, onEvents, options) {
11883
+ if (this.closing) throw new Error("daemon closed");
11884
+ this.lifetime.signal.throwIfAborted();
11885
+ const stream = new DaemonEventStream(
11886
+ `${this.baseURL}/events?target=${encodeTarget(target)}`,
11887
+ this.headers(),
11888
+ onEvents,
11889
+ (events2, signal) => this.acknowledge(target, events2, signal),
11890
+ () => this.streams.delete(stream)
11891
+ );
11892
+ this.streams.add(stream);
11748
11893
  try {
11749
- const response = await fetch(`${this.baseURL}/rpc`, {
11750
- method: "POST",
11751
- headers: { "content-type": "application/json", ...this.headers() },
11752
- body: JSON.stringify({ id, method, params })
11753
- });
11754
- const frame = await response.json();
11755
- if (!response.ok || frame.error) throw new Error(frame.error ?? `daemon request failed: ${response.status}`);
11756
- this.router.settle(id, { result: frame.result });
11894
+ await stream.start(options?.signal);
11895
+ return { close: () => stream.close() };
11757
11896
  } catch (error2) {
11758
- this.router.settle(id, { error: error2 instanceof Error ? error2.message : String(error2) });
11897
+ await stream.close();
11898
+ throw error2;
11759
11899
  }
11760
- return promise;
11761
11900
  }
11762
- async subscribe(target, onEvents) {
11763
- const key = targetKey(target);
11764
- let callbacks = this.listeners.get(key);
11765
- if (!callbacks) {
11766
- callbacks = /* @__PURE__ */ new Set();
11767
- this.listeners.set(key, callbacks);
11768
- }
11769
- callbacks.add(onEvents);
11770
- const controller = new AbortController();
11771
- this.streams.add(controller);
11772
- const url2 = `${this.baseURL}/events?target=${encodeTarget(target)}`;
11773
- let markSubscribed;
11774
- const subscribed = new Promise((resolve) => {
11775
- markSubscribed = () => resolve();
11776
- });
11777
- let delivering = Promise.resolve();
11778
- let activeStream;
11779
- let retryStream = false;
11780
- const deliver = (events2) => {
11781
- if (!callbacks?.has(onEvents) || events2.length === 0) return Promise.resolve();
11782
- delivering = delivering.then(async () => {
11783
- try {
11784
- await onEvents(events2);
11785
- } catch (error2) {
11786
- console.error(`[sourcefed] event delivery failed: ${error2 instanceof Error ? error2.message : String(error2)}`);
11787
- retryStream = true;
11788
- activeStream?.abort();
11789
- return;
11790
- }
11791
- await acknowledge(events2);
11792
- }).catch((error2) => {
11793
- console.error(`[sourcefed] event delivery failed: ${error2 instanceof Error ? error2.message : String(error2)}`);
11794
- });
11795
- return delivering;
11796
- };
11797
- const acknowledge = async (events2) => {
11798
- let attempt = 0;
11799
- while (!controller.signal.aborted && callbacks?.has(onEvents)) {
11800
- try {
11801
- await this.request("monitor.ack", { target, eventIDs: events2.map((event) => event.id) });
11802
- return;
11803
- } catch (error2) {
11804
- attempt += 1;
11805
- if (attempt === 3) {
11806
- console.error(`[sourcefed] event acknowledgement still failing; retrying without repeating delivery: ${error2 instanceof Error ? error2.message : String(error2)}`);
11807
- }
11808
- await sleep(Math.min(250 * 2 ** (attempt - 1), 4e3));
11809
- }
11810
- }
11811
- };
11812
- const runStream = async () => {
11813
- const streamController = new AbortController();
11814
- const closeStream = () => streamController.abort();
11815
- activeStream = streamController;
11816
- controller.signal.addEventListener("abort", closeStream, { once: true });
11901
+ async acknowledge(target, events2, signal) {
11902
+ let attempt = 0;
11903
+ while (!signal.aborted) {
11817
11904
  try {
11818
- const response = await fetch(url2, { signal: streamController.signal, headers: this.headers() });
11819
- if (!response.ok || !response.body) throw new Error(`event stream failed: ${response.status}`);
11820
- const reader = response.body.getReader();
11821
- const decoder = new TextDecoder();
11822
- let buffer = "";
11823
- while (true) {
11824
- const { done, value } = await reader.read();
11825
- if (done) break;
11826
- buffer += decoder.decode(value, { stream: true });
11827
- const frames = buffer.split("\n\n");
11828
- buffer = frames.pop() ?? "";
11829
- for (const chunk of frames) {
11830
- for (const line of chunk.split("\n")) {
11831
- if (!line.startsWith("data: ")) continue;
11832
- const frame = parseDaemonFrame(line.slice(6));
11833
- if (!frame || !("type" in frame)) continue;
11834
- if (frame.type === "subscribed") markSubscribed();
11835
- if (frame.type === "event") void deliver(frame.events);
11836
- }
11837
- }
11838
- }
11839
- consecutiveFailures = 0;
11905
+ await this.request("monitor.ack", { target, eventIDs: events2.map((event) => event.id) }, signal);
11906
+ return;
11840
11907
  } catch (error2) {
11841
- if (!controller.signal.aborted && !retryStream) {
11842
- consecutiveFailures += 1;
11843
- if (consecutiveFailures === 1) {
11844
- console.error(`[sourcefed] event stream ended: ${error2 instanceof Error ? error2.message : String(error2)}`);
11845
- }
11908
+ if (++attempt === 3) {
11909
+ console.error(`[sourcefed] event acknowledgement still failing; retrying without repeating delivery: ${String(error2)}`);
11846
11910
  }
11847
- } finally {
11848
- controller.signal.removeEventListener("abort", closeStream);
11849
- if (activeStream === streamController) activeStream = void 0;
11850
- retryStream = false;
11911
+ await pause(Math.min(250 * 2 ** Math.min(attempt - 1, 4), 4e3), signal);
11851
11912
  }
11852
- };
11853
- let consecutiveFailures = 0;
11854
- void (async () => {
11855
- while (!controller.signal.aborted && callbacks?.has(onEvents)) {
11856
- await runStream();
11857
- if (controller.signal.aborted) break;
11858
- await sleep(500);
11859
- }
11860
- })();
11861
- try {
11862
- await withTimeout(subscribed, 15e3, `sourcefed event stream did not subscribe at ${url2}`);
11863
- } catch (error2) {
11864
- const callbacks2 = this.listeners.get(key);
11865
- callbacks2?.delete(onEvents);
11866
- if (callbacks2 && callbacks2.size === 0) this.listeners.delete(key);
11867
- controller.abort();
11868
- this.streams.delete(controller);
11869
- throw error2;
11870
11913
  }
11871
- return {
11872
- close: async () => {
11873
- const callbacks2 = this.listeners.get(key);
11874
- callbacks2?.delete(onEvents);
11875
- if (callbacks2 && callbacks2.size === 0) this.listeners.delete(key);
11876
- controller.abort();
11877
- this.streams.delete(controller);
11878
- }
11879
- };
11880
11914
  }
11881
- async close() {
11882
- for (const controller of this.streams) controller.abort();
11883
- this.streams.clear();
11884
- this.router.rejectAll(new Error("daemon closed"));
11885
- this.listeners.clear();
11915
+ close() {
11916
+ this.closing ??= Promise.all([...this.streams].map((stream) => stream.close())).then(() => {
11917
+ this.lifetime.abort();
11918
+ this.streams.clear();
11919
+ });
11920
+ return this.closing;
11886
11921
  }
11887
11922
  };
11888
11923
  async function dispatchDaemonRequest(daemon, method, params) {
@@ -22324,7 +22359,7 @@ var REQUEST_STATE_ONLY_LEG_PACING_MS = 250;
22324
22359
  function inputRequiredRoundsExceededMessage(method, maxRounds) {
22325
22360
  return `Multi-round-trip request '${method}' still required input after ${maxRounds} rounds (inputRequired.maxRounds)`;
22326
22361
  }
22327
- function sleep2(ms, signal) {
22362
+ function sleep(ms, signal) {
22328
22363
  return new Promise((resolve, reject) => {
22329
22364
  if (signal?.aborted) {
22330
22365
  reject(signal.reason instanceof SdkError ? signal.reason : new SdkError(SdkErrorCode.RequestTimeout, String(signal.reason)));
@@ -31059,7 +31094,7 @@ var LegacyInputRequiredShim = class {
31059
31094
  } finally {
31060
31095
  roundAbort.dispose();
31061
31096
  }
31062
- } else await sleep2(REQUEST_STATE_ONLY_LEG_PACING_MS, outerSignal);
31097
+ } else await sleep(REQUEST_STATE_ONLY_LEG_PACING_MS, outerSignal);
31063
31098
  let ctxNext = {
31064
31099
  ...ctx,
31065
31100
  mcpReq: {
@@ -44192,9 +44227,7 @@ async function runMonitor(argv) {
44192
44227
 
44193
44228
  // packages/cli/src/utils/setup.ts
44194
44229
  import { execFile } from "node:child_process";
44195
- import { mkdirSync, readFileSync, writeFileSync } from "node:fs";
44196
- import os8 from "node:os";
44197
- import path8 from "node:path";
44230
+ import { readFileSync } from "node:fs";
44198
44231
  import { fileURLToPath } from "node:url";
44199
44232
  function setupSpec() {
44200
44233
  const manifest = JSON.parse(readFileSync(fileURLToPath(new URL("../package.json", import.meta.url)), "utf8"));
@@ -44211,59 +44244,19 @@ async function setupHost(name, args, spec) {
44211
44244
  const code = error2 && typeof error2 === "object" && "code" in error2 ? String(error2.code) : "";
44212
44245
  if (code === "ENOENT") {
44213
44246
  console.error(`[sourcefed] ${name} is not on PATH \u2014 install it manually:`);
44214
- console.error(name === "opencode" ? ` add "${spec}" to the plugins array in ~/.config/opencode/opencode.jsonc and cli.json` : ` run: pi install ${spec}`);
44247
+ console.error(name === "opencode" ? ` add "${spec}" to the plugins array in ~/.config/opencode/opencode.jsonc` : ` run: pi install ${spec}`);
44215
44248
  return false;
44216
44249
  }
44217
44250
  throw error2;
44218
44251
  }
44219
44252
  }
44220
- function configureOpenCodeCliPlugin(spec) {
44221
- const file = openCodeCliConfigPath();
44222
- const config2 = readOpenCodeCliConfig(file);
44223
- const plugins = config2.plugins;
44224
- if (plugins === void 0) {
44225
- config2.plugins = [spec];
44226
- } else if (!Array.isArray(plugins)) {
44227
- throw new Error(`OpenCode CLI config has a non-array plugins setting: ${file}`);
44228
- } else if (!plugins.some((plugin) => isPluginEntry(plugin, spec))) {
44229
- config2.plugins = [...plugins, spec];
44230
- } else {
44231
- return;
44232
- }
44233
- mkdirSync(path8.dirname(file), { recursive: true });
44234
- writeFileSync(file, `${JSON.stringify(config2, null, 2)}
44235
- `);
44236
- }
44237
- function openCodeCliConfigPath() {
44238
- const configHome = process.env.XDG_CONFIG_HOME ?? path8.join(os8.homedir(), ".config");
44239
- return path8.join(configHome, "opencode", "cli.json");
44240
- }
44241
- function readOpenCodeCliConfig(file) {
44242
- try {
44243
- const value = JSON.parse(readFileSync(file, "utf8"));
44244
- if (!value || typeof value !== "object" || Array.isArray(value)) {
44245
- throw new Error(`OpenCode CLI config must contain a JSON object: ${file}`);
44246
- }
44247
- return value;
44248
- } catch (error2) {
44249
- if (error2 instanceof Error && "code" in error2 && error2.code === "ENOENT") return {};
44250
- if (error2 instanceof SyntaxError) throw new Error(`OpenCode CLI config is not valid JSON: ${file}`);
44251
- throw error2;
44252
- }
44253
- }
44254
- function isPluginEntry(value, spec) {
44255
- if (value === spec) return true;
44256
- if (!value || typeof value !== "object" || Array.isArray(value)) return false;
44257
- return "package" in value && value.package === spec;
44258
- }
44259
44253
 
44260
44254
  // packages/cli/src/commands/setup.ts
44261
44255
  async function runSetup(args) {
44262
44256
  const spec = setupSpec();
44263
44257
  const requested = args[0] ?? "all";
44264
44258
  if (requested === "opencode" || requested === "all") {
44265
- const installed = await setupHost("opencode", ["plugin", "add", spec], spec);
44266
- if (installed) configureOpenCodeCliPlugin(spec);
44259
+ await setupHost("opencode", ["plugin", "add", spec], spec);
44267
44260
  }
44268
44261
  if (requested === "pi" || requested === "all") {
44269
44262
  await setupHost("pi", ["install", `npm:${spec}`], `npm:${spec}`);
@@ -44272,12 +44265,12 @@ async function runSetup(args) {
44272
44265
 
44273
44266
  // packages/cli/src/skills/command.ts
44274
44267
  import { readFile as readFile7, readdir as readdir2, stat as stat2 } from "node:fs/promises";
44275
- import path10 from "node:path";
44268
+ import path9 from "node:path";
44276
44269
 
44277
44270
  // packages/cli/src/skills/discovery.ts
44278
44271
  import { statSync } from "node:fs";
44279
44272
  import { readdir, readFile as readFile6, stat } from "node:fs/promises";
44280
- import path9 from "node:path";
44273
+ import path8 from "node:path";
44281
44274
  import { fileURLToPath as fileURLToPath2 } from "node:url";
44282
44275
 
44283
44276
  // packages/cli/src/skills/frontmatter.ts
@@ -44325,7 +44318,7 @@ async function skillsDirs() {
44325
44318
  }
44326
44319
  const directories = [];
44327
44320
  for (const name of SKILL_DIRS) {
44328
- const candidate = path9.join(skillRoot(), name);
44321
+ const candidate = path8.join(skillRoot(), name);
44329
44322
  try {
44330
44323
  if ((await stat(candidate)).isDirectory()) directories.push(candidate);
44331
44324
  } catch {
@@ -44337,7 +44330,7 @@ async function discoverSkills() {
44337
44330
  const skills = [];
44338
44331
  for (const dir of await skillsDirs()) {
44339
44332
  for (const entry of await readdir(dir)) {
44340
- const skillDir = path9.join(dir, entry);
44333
+ const skillDir = path8.join(dir, entry);
44341
44334
  let entryStat;
44342
44335
  try {
44343
44336
  entryStat = await stat(skillDir);
@@ -44345,7 +44338,7 @@ async function discoverSkills() {
44345
44338
  continue;
44346
44339
  }
44347
44340
  if (!entryStat.isDirectory()) continue;
44348
- const skillFile = path9.join(skillDir, "SKILL.md");
44341
+ const skillFile = path8.join(skillDir, "SKILL.md");
44349
44342
  try {
44350
44343
  const content = await readFile6(skillFile, "utf8");
44351
44344
  const parsed = parseFrontmatter(content);
@@ -44358,15 +44351,15 @@ async function discoverSkills() {
44358
44351
  return skills;
44359
44352
  }
44360
44353
  function skillRoot() {
44361
- let dir = path9.dirname(fileURLToPath2(import.meta.url));
44354
+ let dir = path8.dirname(fileURLToPath2(import.meta.url));
44362
44355
  for (let depth = 0; depth < 6; depth++) {
44363
- const marker = path9.join(dir, "data");
44356
+ const marker = path8.join(dir, "data");
44364
44357
  if (statSync(marker, { throwIfNoEntry: false })?.isDirectory()) return dir;
44365
- const parent = path9.dirname(dir);
44358
+ const parent = path8.dirname(dir);
44366
44359
  if (parent === dir) break;
44367
44360
  dir = parent;
44368
44361
  }
44369
- return path9.dirname(fileURLToPath2(import.meta.url));
44362
+ return path8.dirname(fileURLToPath2(import.meta.url));
44370
44363
  }
44371
44364
 
44372
44365
  // packages/cli/src/skills/command.ts
@@ -44413,7 +44406,7 @@ async function runGet(args) {
44413
44406
  output += `# ${skill.name}
44414
44407
 
44415
44408
  `;
44416
- output += await readFile7(path10.join(skill.dir, "SKILL.md"), "utf8");
44409
+ output += await readFile7(path9.join(skill.dir, "SKILL.md"), "utf8");
44417
44410
  output += "\n";
44418
44411
  if (full) output += await supplementaryFiles(skill.dir);
44419
44412
  }
@@ -44436,7 +44429,7 @@ async function runPath(name) {
44436
44429
  async function supplementaryFiles(skillDir) {
44437
44430
  let output = "";
44438
44431
  for (const subdirName of ["references", "templates"]) {
44439
- const subdir = path10.join(skillDir, subdirName);
44432
+ const subdir = path9.join(skillDir, subdirName);
44440
44433
  try {
44441
44434
  if (!(await stat2(subdir)).isDirectory()) continue;
44442
44435
  } catch {
@@ -44444,7 +44437,7 @@ async function supplementaryFiles(skillDir) {
44444
44437
  }
44445
44438
  const entries = (await readdir2(subdir)).sort();
44446
44439
  for (const entry of entries) {
44447
- const filePath = path10.join(subdir, entry);
44440
+ const filePath = path9.join(subdir, entry);
44448
44441
  try {
44449
44442
  if (!(await stat2(filePath)).isFile()) continue;
44450
44443
  } catch {