@chipschat/hermes 1.0.13 → 1.0.15

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/README.md CHANGED
@@ -202,8 +202,8 @@ npm test
202
202
  They run the bridge against Chips's conformance fake and a scripted Hermes API server
203
203
  (`test/fake-hermes.ts`), on Hermes's own routes and event names, and its webhook's signed
204
204
  readings. That includes Chips's golden scenario. Hermes's own files are in temporary homes: no
205
- test reads or writes `~/.hermes`. The SDK and the kit are in `vendor/`, packed from a Chips checkout with
206
- `pnpm release:sdk <this repo>/vendor`.
205
+ test reads or writes `~/.hermes`. The SDK and the kit come from npm, at the version `package.json`
206
+ pins.
207
207
 
208
208
  ```
209
209
  npm run e2e
@@ -1,9 +1,9 @@
1
1
  # Third-party notices
2
2
 
3
- `dist/main.js` in @chipschat/hermes 1.0.13 carries these packages, bundled in. Each one's
3
+ `dist/main.js` in @chipschat/hermes 1.0.15 carries these packages, bundled in. Each one's
4
4
  licence follows.
5
5
 
6
- ## @chipschat/harness 0.0.0 (Apache-2.0)
6
+ ## @chipschat/harness 1.0.1 (Apache-2.0)
7
7
 
8
8
  Apache License
9
9
  Version 2.0, January 2004
@@ -207,7 +207,7 @@ Apache License
207
207
  See the License for the specific language governing permissions and
208
208
  limitations under the License.
209
209
 
210
- ## @chipschat/protocol 0.0.0 (Apache-2.0)
210
+ ## @chipschat/protocol 1.0.1 (Apache-2.0)
211
211
 
212
212
  Apache License
213
213
  Version 2.0, January 2004
package/dist/main.js CHANGED
@@ -20356,7 +20356,14 @@ var HARNESS_CAPABILITIES = {
20356
20356
  * and `context_window.change`, does them in its own way, and answers with its copy. What makes
20357
20357
  * an agent's Context window group worth drawing.
20358
20358
  */
20359
- contextWindows: "context_windows"
20359
+ contextWindows: "context_windows",
20360
+ /**
20361
+ * The harness sends Chips a copy of the jobs it runs on its own, outside any space, and posts
20362
+ * each run with what it cost, and takes a person's switch (ADR 0252): a socket of it says `jobs`
20363
+ * in its `hello`, hears `job.change`, switches the job in its own way, and answers with its
20364
+ * copy. What makes the harness page's "Its own jobs" group worth drawing.
20365
+ */
20366
+ jobs: "jobs"
20360
20367
  };
20361
20368
  var FORK_WAIT_MS = 6e4;
20362
20369
 
@@ -22533,6 +22540,115 @@ var AGENT_FIRST_NAMES = [
22533
22540
  "Zaid Zane Zeke Zeno Zev Ziggy"
22534
22541
  ].flatMap((line2) => line2.split(" "));
22535
22542
 
22543
+ // node_modules/@chipschat/protocol/dist/src/harness-jobs.js
22544
+ var HARNESS_JOBS_MAX = 24;
22545
+ var JOB_CHOICES_MAX = 12;
22546
+ var JOB_EVERY_MAX = 525600;
22547
+ var JOB_RUNS_POST_MAX = 200;
22548
+ var JOB_KINDS = ["heartbeat", "memory", "skills", "other"];
22549
+ var jobKind = external_exports.enum(JOB_KINDS);
22550
+ var JOB_RUN_OUTCOMES = ["done", "failed", "stopped"];
22551
+ var jobRunOutcome = external_exports.enum(JOB_RUN_OUTCOMES);
22552
+ var jobId = external_exports.string().regex(/^[A-Za-z0-9][A-Za-z0-9._:-]{0,79}$/, "expected a job id").describe("The harness's own id for a job: stable, up to 80 letters, digits, `.`, `_`, `:` or `-`.");
22553
+ var minutes2 = external_exports.int().min(1).max(JOB_EVERY_MAX);
22554
+ var ascending3 = (choices) => choices.every((each, at) => at === 0 || each > (choices[at - 1] ?? 0));
22555
+ var jobFields = {
22556
+ job_id: jobId,
22557
+ name: external_exports.string().min(1).max(40).describe('What the harness calls it: "Dreaming".'),
22558
+ about: external_exports.string().min(1).max(240).describe("What it does, in a sentence, for its page."),
22559
+ kind: jobKind.describe("What it does, for its mark: `other` for anything else."),
22560
+ every: minutes2.optional().describe("How often it runs, in minutes. Chips says it in words, with `next_at` for the time of day."),
22561
+ when: external_exports.string().min(1).max(60).optional().describe("How often, in the harness's words, for a schedule that is not an interval."),
22562
+ next_at: isoTimestamp.optional().describe("When it runs next, while it is on."),
22563
+ for_agents: external_exports.array(id("agent")).max(200).optional().describe("The harness's agents it runs for, if it runs for some rather than the harness."),
22564
+ on: external_exports.boolean().describe("Whether it runs now."),
22565
+ editable: external_exports.boolean().describe("Whether a person may switch it from Chips."),
22566
+ why_read_only: external_exports.string().min(1).max(120).optional().describe("Why not, in the harness's words, only when it is not `editable`."),
22567
+ choices: external_exports.array(minutes2).min(1).max(JOB_CHOICES_MAX).refine(ascending3, { message: "The intervals go up, each named once." }).optional().describe("The intervals a person may pick, in minutes, shortest first, `every` among them.")
22568
+ };
22569
+ var harnessJob = external_exports.object(jobFields).refine((job) => job.every !== void 0 || job.when !== void 0, {
22570
+ path: ["every"],
22571
+ message: "Say how often it runs: `every` in minutes, or `when` in words."
22572
+ }).refine((job) => job.choices === void 0 || job.choices.includes(job.every ?? -1), {
22573
+ path: ["choices"],
22574
+ message: "`every` is one of `choices`."
22575
+ }).refine((job) => job.why_read_only === void 0 || !job.editable, {
22576
+ path: ["why_read_only"],
22577
+ message: "Say why only for a job that can't be switched."
22578
+ });
22579
+ var uniqueJobs = (jobs) => new Set(jobs.map((job) => job.job_id)).size === jobs.length;
22580
+ var harnessJobsPut = external_exports.object({
22581
+ jobs: external_exports.array(harnessJob).max(HARNESS_JOBS_MAX).refine(uniqueJobs, { message: "Each job is named once." }).describe("Every job the harness runs on its own, whole: one left out is gone, runs and all."),
22582
+ answers: id("change").optional().describe("The change this copy answers: made, and these are the jobs as they are now."),
22583
+ refuses: external_exports.object({
22584
+ change_id: id("change"),
22585
+ message: external_exports.string().min(1).max(300).optional().describe("Why not, for the person.")
22586
+ }).optional().describe("A change not made. The copy beside it is the jobs as they are now.")
22587
+ }).describe("`PUT /v1/harnesses/:id/jobs`: a harness's copy of the jobs it runs on its own.");
22588
+ var jobRun = external_exports.object({
22589
+ job_id: jobId,
22590
+ run_id: external_exports.string().min(1).max(160).describe("The harness's own id for the run."),
22591
+ started_at: isoTimestamp,
22592
+ ended_at: isoTimestamp,
22593
+ outcome: jobRunOutcome.describe("`done`, `failed`, or `stopped` when something else ended it, such as a restart."),
22594
+ quiet: external_exports.boolean().optional().describe("It did its work and had nothing to say: a heartbeat with nothing for anyone."),
22595
+ waited: external_exports.boolean().optional().describe("It waited for an approval that nobody gave."),
22596
+ error: external_exports.string().min(1).max(200).optional().describe("What went wrong, in the harness's words, for a run that failed or was stopped."),
22597
+ agent_id: id("agent").optional().describe("The agent it ran for, when it runs for some."),
22598
+ cost_usd: external_exports.number().min(0).max(1e4).optional().describe("What it cost, as the harness priced it: absent when the harness doesn't know."),
22599
+ tokens: external_exports.int().min(0).optional().describe("Its tokens, in and out."),
22600
+ model: external_exports.string().min(1).max(80).optional().describe("The model it ran on, in its words.")
22601
+ }).refine((run2) => Date.parse(run2.ended_at) >= Date.parse(run2.started_at), {
22602
+ path: ["ended_at"],
22603
+ message: "A run ends after it starts."
22604
+ }).describe("One run of a job, once it ended.");
22605
+ var jobRunsPost = external_exports.object({ runs: external_exports.array(jobRun).min(1).max(JOB_RUNS_POST_MAX) }).describe("`POST /v1/harnesses/:id/jobs/runs`: runs the harness finished. A run posted again says what it says over what was posted before, and what it leaves out stays: so a run may be posted once more with its cost, and never loses one.");
22606
+ var jobChangeAsk = external_exports.object({
22607
+ on: external_exports.boolean(),
22608
+ every: minutes2.optional().describe("One of the job's choices; its own when left out.")
22609
+ }).describe("`POST /v1/harnesses/:id/jobs/:job/changes`: on or off, and how often.");
22610
+ var JOB_CHANGE_STATES = ["waiting", "saved", "failed", "missed"];
22611
+ var jobChangeState = external_exports.enum(JOB_CHANGE_STATES);
22612
+ var jobChangeView = external_exports.object({
22613
+ change_id: id("change"),
22614
+ state: jobChangeState.describe("`missed` once `JOB_CHANGE_WAIT_MS` has passed with no answer; read, never stored."),
22615
+ on: external_exports.boolean(),
22616
+ every: minutes2.optional(),
22617
+ asked_at: isoTimestamp,
22618
+ answered_at: isoTimestamp.optional(),
22619
+ message: external_exports.string().max(300).optional().describe("The harness's words, for a refusal.")
22620
+ }).describe("The last change a person asked of a job, and what became of it (ADR 0252).");
22621
+ var harnessJobView = external_exports.object({
22622
+ ...jobFields,
22623
+ week_usd: external_exports.number().min(0).optional().describe("What its runs of the last seven days cost: absent when none of them had a cost."),
22624
+ week_runs: external_exports.int().min(0).describe("How many runs it made in the last seven days."),
22625
+ runs_total: external_exports.int().min(0).describe("How many of its runs Chips holds."),
22626
+ last_run: jobRun.optional(),
22627
+ change: jobChangeView.optional()
22628
+ }).describe("One job as a person reads it: the harness's copy, what Chips counted, its change.");
22629
+ var harnessJobsView = external_exports.object({
22630
+ harness_id: id("harness"),
22631
+ jobs: external_exports.array(harnessJobView),
22632
+ read_at: isoTimestamp.describe("When the harness last sent its copy."),
22633
+ away: external_exports.boolean().describe("No socket of the harness hears changes now: read, not switched.")
22634
+ }).describe("`GET /v1/harnesses/:id/jobs`, for the harness's owner or an admin.");
22635
+ var jobRunsView = external_exports.object({
22636
+ harness_id: id("harness"),
22637
+ job_id: jobId,
22638
+ runs: external_exports.array(jobRun).describe("Newest first."),
22639
+ more: external_exports.boolean().describe("Whether older runs are left, for `before` the last one's start.")
22640
+ }).describe("`GET /v1/harnesses/:id/jobs/:job/runs?since=&before=&limit=`.");
22641
+ var jobChangeFrame = external_exports.object({
22642
+ frame: external_exports.literal("job.change"),
22643
+ change_id: id("change"),
22644
+ harness_id: id("harness"),
22645
+ job_id: jobId,
22646
+ on: external_exports.boolean(),
22647
+ every: minutes2.optional().describe("For a job with choices: one of them, the copy's own when the person named none."),
22648
+ asked_by: id("person"),
22649
+ asked_at: isoTimestamp
22650
+ }).describe("A person switched one of a harness's own jobs, or changed how often it runs (ADR 0252). Sent to a harness's socket that said `jobs` in its `hello`, now or never: it is not in the log. The harness answers with its copy of all its jobs, `answers` or `refuses` naming `change_id`.");
22651
+
22536
22652
  // node_modules/@chipschat/protocol/dist/src/frames.js
22537
22653
  var clientHelloFrame = external_exports.object({
22538
22654
  frame: external_exports.literal("hello"),
@@ -22549,7 +22665,7 @@ var clientHelloFrame = external_exports.object({
22549
22665
  autonomy: autonomyLevel.optional().describe("The level the harness believes it has.")
22550
22666
  })).max(64).optional().describe("Not read by Chips: a connection is its token's, and the server's `hello` names the token's harness and its agents (ADR 0087). Absent for a person's client."),
22551
22667
  since: external_exports.int().nonnegative().optional().describe("Not read by Chips: a stream resumes from `subscribe`'s `since`."),
22552
- accepts: external_exports.array(external_exports.string().min(1).max(40)).max(32).optional().describe("Server frames beyond the base set this client understands, by the names in `SERVER_EXTENSIONS`. A name the server does not know is ignored rather than refused, so a client may name a frame a newer server sends and still be answered by an older one (ADR 0211, Phase 3). A client that says `events` is sent its replay in pages rather than one frame per event; one that says `presence` is sent an agent's state as it changes (ADR 0083); a harness's socket that says `restart` is sent `restart` when a person asks it to restart (ADR 0094); an owner's or admin's that says `join` is sent each join request as it changes (ADR 0122); a harness's that says `context` is sent `context.edit` when a person changes one of its context files (ADR 0134); a harness's that says `models` is sent `model.change` when a person changes an agent's model or effort (ADR 0140); a harness's that says `heartbeats` is sent `heartbeat.change` when a person switches an agent's heartbeat or changes how often it beats (ADR 0143); a harness's that says `context_windows` is sent `context_window.compact` and `context_window.change` when a person asks an agent to compact now or changes the limit it compacts itself at (ADR 0146); a person's that says `folders` is sent `folder.open` when they ask, from another of their devices, for a room's folder to be opened in Finder (ADR 0225), and `folder.run` when they ask for its project to be run or stopped there (ADR 0226); a person's that says `folder_runs` is sent `folder.run_state` when their Mac says how a run of theirs stands (ADR 0226); one that says nothing is sent what it was always sent, since an unknown frame is dropped in silence."),
22668
+ accepts: external_exports.array(external_exports.string().min(1).max(40)).max(32).optional().describe("Server frames beyond the base set this client understands, by the names in `SERVER_EXTENSIONS`. A name the server does not know is ignored rather than refused, so a client may name a frame a newer server sends and still be answered by an older one (ADR 0211, Phase 3). A client that says `events` is sent its replay in pages rather than one frame per event; one that says `presence` is sent an agent's state as it changes (ADR 0083); a harness's socket that says `restart` is sent `restart` when a person asks it to restart (ADR 0094); an owner's or admin's that says `join` is sent each join request as it changes (ADR 0122); a harness's that says `context` is sent `context.edit` when a person changes one of its context files (ADR 0134); a harness's that says `models` is sent `model.change` when a person changes an agent's model or effort (ADR 0140); a harness's that says `heartbeats` is sent `heartbeat.change` when a person switches an agent's heartbeat or changes how often it beats (ADR 0143); a harness's that says `context_windows` is sent `context_window.compact` and `context_window.change` when a person asks an agent to compact now or changes the limit it compacts itself at (ADR 0146); a harness's that says `jobs` is sent `job.change` when a person switches one of the jobs it runs on its own (ADR 0252); a person's that says `folders` is sent `folder.open` when they ask, from another of their devices, for a room's folder to be opened in Finder (ADR 0225), and `folder.run` when they ask for its project to be run or stopped there (ADR 0226); a person's that says `folder_runs` is sent `folder.run_state` when their Mac says how a run of theirs stands (ADR 0226); one that says nothing is sent what it was always sent, since an unknown frame is dropped in silence."),
22553
22669
  context: contextBudget.optional().describe("How much of a room a harness is handed with each message for it (ADR 0088): 40 lines and 16,000 characters when absent, 200 and 32,000 at most. For this connection. A person's client is handed none.")
22554
22670
  }).describe("The first frame a client sends.");
22555
22671
  var subscribeFrame = external_exports.object({
@@ -22680,6 +22796,7 @@ var serverFrame = external_exports.discriminatedUnion("frame", [
22680
22796
  heartbeatChangeFrame,
22681
22797
  windowCompactFrame,
22682
22798
  windowChangeFrame,
22799
+ jobChangeFrame,
22683
22800
  pingFrame,
22684
22801
  pongFrame,
22685
22802
  errorFrame
@@ -23864,7 +23981,8 @@ function acceptsFor(handlers) {
23864
23981
  ...handlers.context === void 0 ? [] : ["context"],
23865
23982
  ...handlers.models === void 0 ? [] : ["models"],
23866
23983
  ...handlers.heartbeats === void 0 ? [] : ["heartbeats"],
23867
- ...handlers.contextWindows === void 0 ? [] : ["context_windows"]
23984
+ ...handlers.contextWindows === void 0 ? [] : ["context_windows"],
23985
+ ...handlers.jobs === void 0 ? [] : ["jobs"]
23868
23986
  ];
23869
23987
  }
23870
23988
  var PATHS = {
@@ -23872,28 +23990,32 @@ var PATHS = {
23872
23990
  "harness-context": (id2) => `/v1/harnesses/${encodeURIComponent(id2)}/context`,
23873
23991
  model: (id2) => `/v1/agents/${encodeURIComponent(id2)}/model`,
23874
23992
  heartbeat: (id2) => `/v1/agents/${encodeURIComponent(id2)}/heartbeat`,
23875
- "context-window": (id2) => `/v1/agents/${encodeURIComponent(id2)}/context-window`
23993
+ "context-window": (id2) => `/v1/agents/${encodeURIComponent(id2)}/context-window`,
23994
+ jobs: (id2) => `/v1/harnesses/${encodeURIComponent(id2)}/jobs`
23876
23995
  };
23877
23996
  var FRAMES = {
23878
23997
  "context.edit": contextEditFrame,
23879
23998
  "model.change": modelChangeFrame,
23880
23999
  "heartbeat.change": heartbeatChangeFrame,
23881
24000
  "context_window.compact": windowCompactFrame,
23882
- "context_window.change": windowChangeFrame
24001
+ "context_window.change": windowChangeFrame,
24002
+ "job.change": jobChangeFrame
23883
24003
  };
23884
24004
  var Settings = class {
23885
24005
  put;
23886
24006
  harnessId;
23887
24007
  handlers;
24008
+ post;
23888
24009
  /** The copy last given for each `kind:id`, for a refusal to carry. */
23889
24010
  sent = /* @__PURE__ */ new Map();
23890
24011
  /** The copy Chips last took for each `kind:id`, as JSON. */
23891
24012
  landed = /* @__PURE__ */ new Map();
23892
24013
  chains = /* @__PURE__ */ new Map();
23893
- constructor(put, harnessId, handlers) {
24014
+ constructor(put, harnessId, handlers, post) {
23894
24015
  this.put = put;
23895
24016
  this.harnessId = harnessId;
23896
24017
  this.handlers = handlers;
24018
+ this.post = post;
23897
24019
  }
23898
24020
  /** An agent's context files (`context_files`). */
23899
24021
  context(agentId2, copy) {
@@ -23915,6 +24037,24 @@ var Settings = class {
23915
24037
  contextWindow(agentId2, copy) {
23916
24038
  return this.send("context-window", agentId2, copy, {});
23917
24039
  }
24040
+ /** The jobs the harness runs on its own, all of them (`jobs`). */
24041
+ jobs(copy) {
24042
+ return this.send("jobs", this.harnessId(), copy, {});
24043
+ }
24044
+ /**
24045
+ * Runs of its jobs the harness finished (`jobs`), two hundred to a post. A run sent again says
24046
+ * what it says over the one before, and what it leaves out stays, so send it once more when its
24047
+ * cost is known, and again without one does no harm. Send the copy first:
24048
+ * Chips refuses runs of a job its copy doesn't list.
24049
+ */
24050
+ async jobRuns(runs) {
24051
+ if (this.post === void 0)
24052
+ throw new Error("This connection can't post a job's runs.");
24053
+ const path = `${PATHS.jobs(this.harnessId())}/runs`;
24054
+ for (let at = 0; at < runs.length; at += JOB_RUNS_POST_MAX) {
24055
+ await this.post(path, { runs: runs.slice(at, at + JOB_RUNS_POST_MAX) });
24056
+ }
24057
+ }
23918
24058
  /** An agent deleted: nothing is remembered of it, so a copy for an agent made again is sent. */
23919
24059
  forget(agentId2) {
23920
24060
  for (const kind of Object.keys(PATHS)) {
@@ -23962,6 +24102,8 @@ var Settings = class {
23962
24102
  return this.answer("model", frame.agent_id, frame.change_id, "change_id", () => handlers?.models?.(frame));
23963
24103
  case "heartbeat.change":
23964
24104
  return this.answer("heartbeat", frame.agent_id, frame.change_id, "change_id", () => handlers?.heartbeats?.(frame));
24105
+ case "job.change":
24106
+ return this.answer("jobs", this.harnessId(), frame.change_id, "change_id", () => handlers?.jobs?.(frame));
23965
24107
  case "context_window.compact":
23966
24108
  return this.answer("context-window", frame.agent_id, frame.change_id, "change_id", () => handlers?.contextWindows?.compact(frame));
23967
24109
  default:
@@ -24077,7 +24219,7 @@ var Chips = class _Chips {
24077
24219
  this.outbox.add(String(event["idempotency_key"]), event).catch(() => void 0);
24078
24220
  }
24079
24221
  this.orphans = [...kept?.runs ?? []];
24080
- this.settings = new Settings((path, body) => this.request("PUT", path, body), () => this.harnessId, options.settings);
24222
+ this.settings = new Settings((path, body) => this.request("PUT", path, body), () => this.harnessId, options.settings, (path, body) => this.request("POST", path, body));
24081
24223
  }
24082
24224
  /**
24083
24225
  * The harness's copies of what a person changes from an agent's page (ADRs 0134, 0140, 0143,
@@ -27533,6 +27675,8 @@ var Bridge = class {
27533
27675
  toldModels = false;
27534
27676
  /** While Hermes's gateway restarts (Chips ADR 0094), the health watch says nothing: the restart says how it went. */
27535
27677
  held = false;
27678
+ /** Restarts begun, so a health check asked before one, and answered after, is let go. */
27679
+ holds = 0;
27536
27680
  /** What went wrong in the last restart, said in place of the watch's own words while Hermes doesn't answer. */
27537
27681
  why;
27538
27682
  /** Register the agents, start hearing what is said to them, and say how their gateways are. */
@@ -27573,6 +27717,7 @@ var Bridge = class {
27573
27717
  }
27574
27718
  /** Hold the health watch's words while Hermes's gateway restarts, and let them go after. */
27575
27719
  hold(held) {
27720
+ if (held && !this.held) this.holds += 1;
27576
27721
  this.held = held;
27577
27722
  }
27578
27723
  /**
@@ -28037,11 +28182,18 @@ ${hook.lines}`);
28037
28182
  return note === void 0 ? {} : { note };
28038
28183
  }
28039
28184
  }
28040
- /** Trouble while a profile's gateway doesn't answer, and fine once all do (ADR 0083); nothing while a restart runs. */
28185
+ /**
28186
+ * Trouble while a profile's gateway doesn't answer, and fine once all do (ADR 0083); nothing while
28187
+ * a restart runs, nor answers to a check asked before one began, even one over by now: they are of
28188
+ * the gateways before, and a failed restart's words would go.
28189
+ */
28041
28190
  async sayHowItIs() {
28042
28191
  if (this.held) return;
28043
- for (const agent of this.agents) agent.up = await agent.client.healthy();
28044
- if (this.held) return;
28192
+ const holds2 = this.holds;
28193
+ const answers2 = /* @__PURE__ */ new Map();
28194
+ for (const agent of this.agents) answers2.set(agent, await agent.client.healthy());
28195
+ if (this.holds !== holds2) return;
28196
+ for (const [agent, up] of answers2) agent.up = up;
28045
28197
  const down = this.agents.filter((agent) => !agent.up);
28046
28198
  if (down.length === 0) this.why = void 0;
28047
28199
  const chips2 = this.options.chips;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@chipschat/hermes",
3
- "version": "1.0.13",
3
+ "version": "1.0.15",
4
4
  "description": "Hermes Agent as a Chips harness, on its Runs API: each profile a Chips agent, each room a Hermes session.",
5
5
  "license": "Apache-2.0",
6
6
  "repository": {
@@ -33,9 +33,9 @@
33
33
  "release": "npm run build && npm test && npm pack"
34
34
  },
35
35
  "devDependencies": {
36
- "@chipschat/conformance": "file:vendor/chipschat-conformance-0.0.0.tgz",
37
- "@chipschat/harness": "file:vendor/chipschat-harness-0.0.0.tgz",
38
- "@chipschat/protocol": "file:vendor/chipschat-protocol-0.0.0.tgz",
36
+ "@chipschat/conformance": "1.0.1",
37
+ "@chipschat/harness": "1.0.1",
38
+ "@chipschat/protocol": "1.0.1",
39
39
  "@types/node": "22.19.0",
40
40
  "esbuild": "0.27.7",
41
41
  "tsx": "4.21.0",