@appchy/jarvis 0.1.96 → 0.1.97

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.
@@ -11,14 +11,72 @@ import {
11
11
  } from "./chunk-YWSWQEJN.mjs";
12
12
 
13
13
  // ../../packages/data/src/backends/graphify.ts
14
+ import { execFile as execFile2 } from "child_process";
15
+ import { access, readFile as readFile3, rename, rm, stat, utimes, writeFile as writeFile2 } from "fs/promises";
16
+ import { dirname as dirname2, resolve as resolve3 } from "path";
17
+ import { promisify as promisify2 } from "util";
18
+
19
+ // ../../packages/data/src/backends/changes.ts
14
20
  import { execFile } from "child_process";
15
- import { access, readFile as readFile2, rename, rm, stat, utimes, writeFile } from "fs/promises";
16
- import { dirname, resolve as resolve2 } from "path";
21
+ import { readFile, writeFile } from "fs/promises";
22
+ import { dirname, resolve } from "path";
17
23
  import { promisify } from "util";
24
+ var run = promisify(execFile);
25
+ var STAMP = "extracted-at";
26
+ async function git(root, argv) {
27
+ try {
28
+ const { stdout } = await run("git", argv, {
29
+ cwd: root,
30
+ timeout: 5e3,
31
+ env: { ...process.env, GIT_TERMINAL_PROMPT: "0" }
32
+ });
33
+ return stdout.trim();
34
+ } catch {
35
+ return void 0;
36
+ }
37
+ }
38
+ function stampPath(graphPath) {
39
+ return resolve(dirname(graphPath), STAMP);
40
+ }
41
+ async function saveExtractedCommit(root, graphPath) {
42
+ const head = await git(root, ["rev-parse", "HEAD"]);
43
+ if (!head) return;
44
+ try {
45
+ await writeFile(stampPath(graphPath), `${head}
46
+ `, "utf8");
47
+ } catch {
48
+ }
49
+ }
50
+ async function loadExtractedCommit(graphPath) {
51
+ try {
52
+ const sha = (await readFile(stampPath(graphPath), "utf8")).trim();
53
+ return /^[0-9a-f]{40}$/.test(sha) ? sha : void 0;
54
+ } catch {
55
+ return void 0;
56
+ }
57
+ }
58
+ async function changedSince(root, since) {
59
+ const committed = await git(root, ["diff", "--name-only", since, "HEAD"]);
60
+ if (committed === void 0) return void 0;
61
+ const working = await git(root, ["status", "--porcelain"]);
62
+ if (working === void 0) return void 0;
63
+ const staged = working.split("\n").filter((line) => line.trim().length > 0).flatMap((line) => line.slice(3).split(" -> "));
64
+ return [...committed.split("\n"), ...staged].map((path) => path.trim()).filter(Boolean);
65
+ }
66
+ async function indexedCodeChanged(root, graphPath, globs) {
67
+ if (!globs.include || globs.include.length === 0) return true;
68
+ const since = await loadExtractedCommit(graphPath);
69
+ if (!since) return true;
70
+ const changed = await changedSince(root, since);
71
+ if (changed === void 0) return true;
72
+ const included = matcher(globs.include);
73
+ const ignored = globs.ignore && globs.ignore.length > 0 ? matcher(globs.ignore) : () => false;
74
+ return changed.some((path) => included(path) && !ignored(path));
75
+ }
18
76
 
19
77
  // ../../packages/data/src/backends/imports.ts
20
- import { readFile } from "fs/promises";
21
- import { posix, resolve } from "path";
78
+ import { readFile as readFile2 } from "fs/promises";
79
+ import { posix, resolve as resolve2 } from "path";
22
80
  var IMPORT_RELATION_SET = new Set(IMPORT_RELATIONS);
23
81
  var asStr = (v) => typeof v === "string" ? v : void 0;
24
82
  var toPosix = (p) => p.replace(/\\/g, "/");
@@ -50,7 +108,7 @@ async function packageNameOf(cache, root, file) {
50
108
  return hit === NO_PACKAGE ? void 0 : hit;
51
109
  }
52
110
  pending.push(dir);
53
- const name = await readFile(resolve(root, dir, "package.json"), "utf8").then((text) => asStr(JSON.parse(text).name)).catch(() => void 0);
111
+ const name = await readFile2(resolve2(root, dir, "package.json"), "utf8").then((text) => asStr(JSON.parse(text).name)).catch(() => void 0);
54
112
  if (name !== void 0) {
55
113
  for (const d of pending) cache.set(d, name);
56
114
  return name;
@@ -65,7 +123,7 @@ async function packageNameOf(cache, root, file) {
65
123
  async function readLines(cache, absPath) {
66
124
  const hit = cache.get(absPath);
67
125
  if (hit !== void 0) return hit;
68
- const lines = await readFile(absPath, "utf8").then((text) => text.split(/\r?\n/)).catch(() => null);
126
+ const lines = await readFile2(absPath, "utf8").then((text) => text.split(/\r?\n/)).catch(() => null);
69
127
  cache.set(absPath, lines);
70
128
  return lines;
71
129
  }
@@ -83,7 +141,7 @@ async function resolveImportCollisions(raw, root) {
83
141
  const specsInFile = async (file) => {
84
142
  const hit = fileSpecCache.get(file);
85
143
  if (hit !== void 0 || fileSpecCache.has(file)) return hit;
86
- const lines = await readLines(lineCache, resolve(root, file));
144
+ const lines = await readLines(lineCache, resolve2(root, file));
87
145
  const specs = lines?.flatMap((l) => specifiersOf(l));
88
146
  fileSpecCache.set(file, specs);
89
147
  return specs;
@@ -125,7 +183,7 @@ async function resolveImportCollisions(raw, root) {
125
183
  const importer = toPosix(asStr(links[0]?.source_file) ?? "");
126
184
  const lineNo = lineNumberOf(asStr(links[0]?.source_location));
127
185
  if (!importer || lineNo === void 0) continue;
128
- const lines = await readLines(lineCache, resolve(root, importer));
186
+ const lines = await readLines(lineCache, resolve2(root, importer));
129
187
  const line = lines?.[lineNo - 1];
130
188
  if (!line) continue;
131
189
  const allSpecs = specifiersOf(line);
@@ -185,7 +243,7 @@ function communityLabelPrompt(communities) {
185
243
  }
186
244
 
187
245
  // ../../packages/data/src/backends/graphify.ts
188
- var run = promisify(execFile);
246
+ var run2 = promisify2(execFile2);
189
247
  var LABEL_TOP_K = 8;
190
248
  var LABEL_MAX_LEN = 80;
191
249
  var PLACEHOLDER_COMMUNITY = /^Community \d+$/;
@@ -200,8 +258,8 @@ function graphify(options = {}) {
200
258
  // saying so at the moment it is produced.
201
259
  ...options.staleness ? { staleness: options.staleness } : {},
202
260
  load: async (ctx) => {
203
- const root = resolve2(ctx.config.repoRoot, options.root ?? ".");
204
- const graphPath = resolve2(ctx.config.repoRoot, graphRel);
261
+ const root = resolve3(ctx.config.repoRoot, options.root ?? ".");
262
+ const graphPath = resolve3(ctx.config.repoRoot, graphRel);
205
263
  const bin = options.bin ?? "graphify";
206
264
  const forceExtract = process.env.JARVIS_DATA_REBUILD === "1";
207
265
  const refresh = process.env.JARVIS_DATA_REFRESH === "1" && options.extract !== false;
@@ -209,15 +267,27 @@ function graphify(options = {}) {
209
267
  const mode = forceExtract ? true : options.extract ?? "auto";
210
268
  const present = await exists(graphPath);
211
269
  const missing = options.missing !== void 0 ? { missing: options.missing } : {};
212
- const extracted = forceExtract && present ? await rebuildFresh(graphPath, () => extract(bin, root, ctx, graphRel, { ...missing })) : refresh ? await extract(bin, root, ctx, graphRel, { force: true, ...missing }) : mode === true || mode === "auto" && !present ? await extract(bin, root, ctx, graphRel, { ...missing }) : false;
213
- if (extracted) await stampFresh(graphPath);
270
+ const unmoved = refresh && present && !await indexedCodeChanged(root, graphPath, {
271
+ ...options.include ? { include: options.include } : {},
272
+ ...options.ignore ? { ignore: options.ignore } : {}
273
+ });
274
+ const extracted = forceExtract && present ? await rebuildFresh(graphPath, () => extract(bin, root, ctx, graphRel, { ...missing })) : unmoved ? false : refresh ? await extract(bin, root, ctx, graphRel, { force: true, ...missing }) : mode === true || mode === "auto" && !present ? await extract(bin, root, ctx, graphRel, { ...missing }) : false;
275
+ if (extracted) {
276
+ await stampFresh(graphPath);
277
+ await saveExtractedCommit(root, graphPath);
278
+ } else if (unmoved) {
279
+ ctx.logger.info(
280
+ "graphify: nothing it indexes changed \u2014 keeping the graph, skipping extract"
281
+ );
282
+ await stampFresh(graphPath);
283
+ }
214
284
  if (!await exists(graphPath)) {
215
285
  ctx.panic(
216
286
  `graphify graph not found at ${graphRel}. Run \`jarvis build graph\`, or set { extract: true } in the backend options.`
217
287
  );
218
288
  }
219
289
  if (options.staleness) await reportIfStale(ctx, graphPath, graphRel, options.staleness);
220
- const raw = JSON.parse(await readFile2(graphPath, "utf8"));
290
+ const raw = JSON.parse(await readFile3(graphPath, "utf8"));
221
291
  if (options.labeler && (forceLabel || extracted && !refresh)) {
222
292
  await labelCommunities(ctx, options.labeler, raw, graphPath, extracted);
223
293
  }
@@ -231,7 +301,7 @@ async function loadCommunityLabels(graphPath) {
231
301
  const labels = /* @__PURE__ */ new Map();
232
302
  const labelPath = communityLabelsPath(graphPath);
233
303
  try {
234
- const raw = JSON.parse(await readFile2(labelPath, "utf8"));
304
+ const raw = JSON.parse(await readFile3(labelPath, "utf8"));
235
305
  if (!raw || typeof raw !== "object") return labels;
236
306
  for (const [rawId, rawName] of Object.entries(raw)) {
237
307
  const name = asString(rawName);
@@ -289,7 +359,7 @@ function communityOf(n, labels) {
289
359
  return key ? `Community ${key}` : void 0;
290
360
  }
291
361
  function graphifyOptions(ctx, graphRel) {
292
- return { cwd: ctx.config.repoRoot, env: { ...process.env, GRAPHIFY_OUT: dirname(graphRel) } };
362
+ return { cwd: ctx.config.repoRoot, env: { ...process.env, GRAPHIFY_OUT: dirname2(graphRel) } };
293
363
  }
294
364
  async function extract(bin, root, ctx, graphRel, options = {}) {
295
365
  try {
@@ -297,7 +367,7 @@ async function extract(bin, root, ctx, graphRel, options = {}) {
297
367
  `graphify: extracting ${root}${options.force ? " (incremental \u2014 prune deletions)" : ""}`
298
368
  );
299
369
  const args = options.force ? ["update", "--force", root] : ["update", root];
300
- await run(bin, args, graphifyOptions(ctx, graphRel));
370
+ await run2(bin, args, graphifyOptions(ctx, graphRel));
301
371
  return true;
302
372
  } catch (err) {
303
373
  const code = err.code;
@@ -337,7 +407,7 @@ async function rebuildFresh(graphPath, extract2) {
337
407
  }
338
408
  async function parseable(path) {
339
409
  try {
340
- JSON.parse(await readFile2(path, "utf8"));
410
+ JSON.parse(await readFile3(path, "utf8"));
341
411
  return true;
342
412
  } catch {
343
413
  return false;
@@ -411,12 +481,12 @@ function sampleCommunities(raw) {
411
481
  return communities;
412
482
  }
413
483
  function communityLabelsPath(graphPath) {
414
- return resolve2(dirname(graphPath), "community-labels.json");
484
+ return resolve3(dirname2(graphPath), "community-labels.json");
415
485
  }
416
486
  async function readCommunityLabels(graphPath) {
417
487
  const out = /* @__PURE__ */ new Map();
418
488
  try {
419
- const existing = JSON.parse(await readFile2(communityLabelsPath(graphPath), "utf8"));
489
+ const existing = JSON.parse(await readFile3(communityLabelsPath(graphPath), "utf8"));
420
490
  for (const [id, value] of Object.entries(existing)) {
421
491
  const name = asString(value);
422
492
  if (name && !PLACEHOLDER_COMMUNITY.test(name)) out.set(id, name);
@@ -429,7 +499,7 @@ async function writeCommunityLabels(graphPath, named) {
429
499
  const merged = {};
430
500
  for (const [id, name] of await readCommunityLabels(graphPath)) merged[id] = name;
431
501
  for (const [id, name] of named) merged[id] = name;
432
- await writeFile(communityLabelsPath(graphPath), `${JSON.stringify(merged, null, 2)}
502
+ await writeFile2(communityLabelsPath(graphPath), `${JSON.stringify(merged, null, 2)}
433
503
  `, "utf8");
434
504
  }
435
505
  async function reportIfStale(ctx, graphPath, graphRel, severity) {
@@ -441,7 +511,7 @@ async function reportIfStale(ctx, graphPath, graphRel, severity) {
441
511
  }
442
512
  let headMs;
443
513
  try {
444
- const { stdout } = await run("git", ["show", "-s", "--format=%ct", "HEAD"], {
514
+ const { stdout } = await run2("git", ["show", "-s", "--format=%ct", "HEAD"], {
445
515
  cwd: ctx.config.repoRoot
446
516
  });
447
517
  const seconds = Number(stdout.trim());
package/dist/data/mcp.mjs CHANGED
@@ -215,6 +215,14 @@ async function freshness(ctx) {
215
215
  const builtMs = Date.parse(ctx.builtAt);
216
216
  let behindHead;
217
217
  if (head && mtimeMs) behindHead = mtimeMs < head.committedMs;
218
+ let behindHeadBy;
219
+ let behindHeadForMs;
220
+ if (behindHead && head && mtimeMs) {
221
+ behindHeadForMs = head.committedMs - mtimeMs;
222
+ const since = new Date(mtimeMs).toISOString();
223
+ const count = Number(await git(root, ["rev-list", "--count", `--since=${since}`, "HEAD"]));
224
+ if (Number.isFinite(count)) behindHeadBy = count;
225
+ }
218
226
  const replacedMs = Math.max(mtimeMs ?? 0, await snapshotMtimeMs(ctx) ?? 0);
219
227
  const rebuiltOnDisk = Boolean(
220
228
  replacedMs && Number.isFinite(builtMs) && replacedMs > builtMs + 1e3
@@ -223,27 +231,47 @@ async function freshness(ctx) {
223
231
  const behindOrigin = Boolean(origin?.reachable && (origin.behindBy ?? 0) > 0);
224
232
  const originUnknown = Boolean(origin && !origin.reachable);
225
233
  let reason;
226
- if (behindOrigin)
234
+ let verdict;
235
+ if (behindOrigin) {
236
+ verdict = "stale";
227
237
  reason = `this checkout is ${origin?.behindBy} commit(s) behind ${origin?.ref} \u2014 the map and the board both describe an older world than the origin's. Pull, then \`jarvis build graph\`.`;
228
- else if (originUnknown)
229
- reason = `cannot reach ${origin?.ref}, so I cannot tell whether this is current${origin?.lastSyncedIso ? ` \u2014 last synced at ${origin.lastSyncedIso}` : " and this clone has never fetched"}.`;
230
- else if (behindHead)
231
- reason = `${graphRel} is older than HEAD \u2014 the code graph is stale; run \`jarvis build graph\` (the incremental update \u2014 it re-extracts in place), then traces and impact are trustworthy again. \`--rebuild\` re-extracts from scratch and relabels; it is for a graph still wrong after a plain build, not for ordinary drift.`;
232
- else if (rebuiltOnDisk)
238
+ } else if (originUnknown) {
239
+ verdict = "unknown";
240
+ reason = `cannot reach ${origin?.ref}, so whether this is current is UNKNOWN rather than bad \u2014 rebuilding cannot answer it${origin?.lastSyncedIso ? `. Last heard from a remote at ${origin.lastSyncedIso}` : ", and this clone has never fetched"}.`;
241
+ } else if (behindHead) {
242
+ verdict = "stale";
243
+ reason = `${graphRel} is ${describeBehind(behindHeadBy, behindHeadForMs)} \u2014 run \`jarvis build graph\` (the incremental update \u2014 it re-extracts in place), then traces and impact are trustworthy again. \`--rebuild\` re-extracts from scratch and relabels; it is for a graph still wrong after a plain build, not for ordinary drift.`;
244
+ } else if (rebuiltOnDisk) {
245
+ verdict = "stale";
233
246
  reason = `${graphRel} was rebuilt after this MCP server loaded it \u2014 reloading automatically.`;
247
+ }
234
248
  return {
235
249
  graphPath: graphRel,
236
250
  ...mtimeIso ? { mtimeIso } : {},
237
251
  ...head ? { head: { commit: head.commit, dirty: head.dirty } } : {},
238
252
  ...behindHead !== void 0 ? { behindHead } : {},
253
+ ...behindHeadBy !== void 0 ? { behindHeadBy } : {},
254
+ ...behindHeadForMs !== void 0 ? { behindHeadForMs } : {},
239
255
  ...rebuiltOnDisk ? { rebuiltOnDisk } : {},
240
256
  ...origin ? { origin } : {},
241
257
  ...behindOrigin ? { behindOrigin } : {},
242
258
  ...originUnknown ? { originUnknown } : {},
243
259
  stale: Boolean(behindHead) || rebuiltOnDisk || behindOrigin || originUnknown,
260
+ ...verdict ? { verdict } : {},
244
261
  ...reason ? { reason } : {}
245
262
  };
246
263
  }
264
+ function describeBehind(commits, forMs) {
265
+ const age = forMs !== void 0 && forMs >= 60 * 60 * 1e3 ? describeAge(forMs) : void 0;
266
+ if (commits === void 0) return `older than HEAD${age ? ` by ${age}` : ""}`;
267
+ const plural = commits === 1 ? "commit" : "commits";
268
+ return `${commits} ${plural} behind HEAD${age ? `, built ${age} ago` : ""}`;
269
+ }
270
+ function describeAge(ms) {
271
+ const hours = Math.round(ms / (60 * 60 * 1e3));
272
+ if (hours < 48) return `${hours} hour(s)`;
273
+ return `${Math.round(hours / 24)} day(s)`;
274
+ }
247
275
  async function snapshotMtimeMs(ctx) {
248
276
  const path = ctx.config.persistence?.locate?.({ repoRoot: ctx.config.repoRoot }, "snapshot");
249
277
  if (!path) return void 0;
@@ -874,11 +902,13 @@ async function brief(ctx, req) {
874
902
  const areas = [...communityCounts.entries()].map(([name, size]) => ({ name, size })).sort((a, b) => b.size - a.size).slice(0, listCap);
875
903
  const inProgressCount = byCategory["in-progress"] ?? 0;
876
904
  return {
877
- summary: `${leaves.length} work item(s) \u2014 ${inProgressCount} in flight, ${byCategory["open"] ?? 0} open, ${byCategory["done"] ?? 0} done. ${artifacts} knowledge artifact(s); health: ${health.counts.error} error(s), ${health.counts.warn} warning(s)${f.stale ? " \u2014 GRAPH IS STALE, run `jarvis build graph` (incremental) before trusting details" : ""}${staleOrigins.length ? ` \u2014 ${staleOrigins.map((o) => o.origin).join(", ")} behind their own HEAD (re-run \`jarvis build graph\` there, then re-merge)` : ""}.`,
905
+ summary: `${leaves.length} work item(s) \u2014 ${inProgressCount} in flight, ${byCategory["open"] ?? 0} open, ${byCategory["done"] ?? 0} done. ${artifacts} knowledge artifact(s); health: ${health.counts.error} error(s), ${health.counts.warn} warning(s)${f.stale ? ` \u2014 ${describeFreshness(f)}` : ""}${staleOrigins.length ? ` \u2014 ${staleOrigins.map((o) => o.origin).join(", ")} behind their own HEAD (re-run \`jarvis build graph\` there, then re-merge)` : ""}.`,
878
906
  freshness: {
879
907
  builtAt: ctx.builtAt,
880
908
  ...f.head ? { head: { commit: f.head.commit, dirty: f.head.dirty } } : {},
881
909
  ...f.stale !== void 0 ? { stale: f.stale } : {},
910
+ ...f.verdict ? { verdict: f.verdict } : {},
911
+ ...f.behindHeadBy !== void 0 ? { behindHeadBy: f.behindHeadBy } : {},
882
912
  ...originsFresh.length ? { federated: originsFresh } : {}
883
913
  },
884
914
  graph: { nodes: ctx.graph.nodes().length, artifacts, edges: ctx.graph.edges().length },
@@ -920,6 +950,15 @@ function renderWorkItem(ctx, item, home) {
920
950
  ...home !== void 0 ? { belongsTo: home } : {}
921
951
  };
922
952
  }
953
+ function describeFreshness(f) {
954
+ if (f.verdict === "unknown")
955
+ return "FRESHNESS UNKNOWN \u2014 cannot reach the origin, so nothing below is confirmed current; rebuilding cannot answer it";
956
+ if (f.behindOrigin)
957
+ return `THIS CHECKOUT IS BEHIND ITS ORIGIN by ${f.origin?.behindBy} commit(s) \u2014 pull, then run \`jarvis build graph\``;
958
+ if (f.behindHead)
959
+ return `GRAPH IS STALE by ${f.behindHeadBy ?? "an unknown number of"} commit(s), run \`jarvis build graph\` (incremental) before trusting details`;
960
+ return "GRAPH IS STALE, run `jarvis build graph` (incremental) before trusting details";
961
+ }
923
962
 
924
963
  // ../../packages/data/src/resolve.ts
925
964
  function resolveTarget(ctx, input) {
@@ -2562,15 +2601,11 @@ function createServer(ctx, hosted = [], prompts = []) {
2562
2601
  );
2563
2602
  }
2564
2603
  for (const p of prompts) {
2565
- server.registerPrompt(
2566
- p.name,
2567
- { title: p.title, description: p.description },
2568
- async () => ({
2569
- messages: [
2570
- { role: "user", content: { type: "text", text: await p.read() } }
2571
- ]
2572
- })
2573
- );
2604
+ server.registerPrompt(p.name, { title: p.title, description: p.description }, async () => ({
2605
+ messages: [
2606
+ { role: "user", content: { type: "text", text: await p.read() } }
2607
+ ]
2608
+ }));
2574
2609
  }
2575
2610
  return server;
2576
2611
  }
@@ -2601,14 +2636,23 @@ function buildInstructions(req = {}) {
2601
2636
  }
2602
2637
  async function result(ctx, structured) {
2603
2638
  const f = await freshness(ctx);
2604
- const summary = f.stale && !/stale/i.test(structured.summary) ? `${STALE_PREFIX}${structured.summary}` : structured.summary;
2639
+ const summary = f.stale && !/stale/i.test(structured.summary) ? `${f.verdict === "unknown" ? UNKNOWN_PREFIX : STALE_PREFIX}${structured.summary}` : structured.summary;
2605
2640
  return {
2606
2641
  content: [{ type: "text", text: summary }],
2607
2642
  structuredContent: { ...structured, summary },
2608
- ...f.stale ? { _meta: { data: { stale: true, ...f.reason ? { reason: f.reason } : {} } } } : {}
2643
+ ...f.stale ? {
2644
+ _meta: {
2645
+ data: {
2646
+ stale: true,
2647
+ ...f.verdict ? { verdict: f.verdict } : {},
2648
+ ...f.reason ? { reason: f.reason } : {}
2649
+ }
2650
+ }
2651
+ } : {}
2609
2652
  };
2610
2653
  }
2611
2654
  var STALE_PREFIX = "\u26A0 STALE GRAPH \u2014 results may be wrong; run `jarvis build graph` (the incremental update \u2014 not --rebuild). ";
2655
+ var UNKNOWN_PREFIX = "\u26A0 FRESHNESS UNKNOWN \u2014 this clone cannot reach its origin, so it cannot tell whether these results are current. ";
2612
2656
 
2613
2657
  // ../../packages/data/src/mcp/snapshot.ts
2614
2658
  async function loadSnapshot(config) {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@appchy/jarvis",
3
- "version": "0.1.96",
3
+ "version": "0.1.97",
4
4
  "description": "Jarvis — local AI coding assistant CLI",
5
5
  "private": false,
6
6
  "type": "module",
@@ -56,15 +56,15 @@
56
56
  "tsup": "^8.5.1",
57
57
  "typescript": "^5.7.0",
58
58
  "vitest": "^2.1.0",
59
- "@jarvis/agents": "1.0.0",
60
59
  "@jarvis/anthropic": "1.0.0",
61
- "@jarvis/errors": "1.0.0",
62
60
  "@jarvis/board": "0.1.0",
61
+ "@jarvis/agents": "1.0.0",
62
+ "@jarvis/data": "0.1.0",
63
63
  "@jarvis/logger": "1.0.0",
64
+ "@jarvis/errors": "1.0.0",
64
65
  "@jarvis/rpc": "1.0.0",
65
66
  "@jarvis/types": "1.0.0",
66
67
  "@jarvis/typescript-config": "1.0.0",
67
- "@jarvis/data": "0.1.0",
68
68
  "@jarvis/ui": "0.1.0",
69
69
  "@jarvis/vitest-config": "1.0.0"
70
70
  },