@chipschat/opencode 1.0.10 → 1.0.12

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
@@ -197,8 +197,7 @@ npm test
197
197
 
198
198
  They run the bridge against Chips's conformance fake and a scripted OpenCode server
199
199
  (`test/fake-opencode.ts`), on OpenCode's own routes and event shapes. That includes Chips's golden
200
- scenario. The SDK and the kit are in `vendor/`, packed from a Chips checkout with
201
- `pnpm release:sdk <this repo>/vendor`.
200
+ scenario. The SDK and the kit come from npm, at the version `package.json` pins.
202
201
 
203
202
  ```
204
203
  npm run e2e
@@ -1,9 +1,9 @@
1
1
  # Third-party notices
2
2
 
3
- `dist/main.js` in @chipschat/opencode 1.0.10 carries these packages, bundled in. Each one's
3
+ `dist/main.js` in @chipschat/opencode 1.0.12 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
@@ -20354,7 +20354,14 @@ var HARNESS_CAPABILITIES = {
20354
20354
  * and `context_window.change`, does them in its own way, and answers with its copy. What makes
20355
20355
  * an agent's Context window group worth drawing.
20356
20356
  */
20357
- contextWindows: "context_windows"
20357
+ contextWindows: "context_windows",
20358
+ /**
20359
+ * The harness sends Chips a copy of the jobs it runs on its own, outside any space, and posts
20360
+ * each run with what it cost, and takes a person's switch (ADR 0252): a socket of it says `jobs`
20361
+ * in its `hello`, hears `job.change`, switches the job in its own way, and answers with its
20362
+ * copy. What makes the harness page's "Its own jobs" group worth drawing.
20363
+ */
20364
+ jobs: "jobs"
20358
20365
  };
20359
20366
  var FORK_WAIT_MS = 6e4;
20360
20367
 
@@ -22531,6 +22538,115 @@ var AGENT_FIRST_NAMES = [
22531
22538
  "Zaid Zane Zeke Zeno Zev Ziggy"
22532
22539
  ].flatMap((line) => line.split(" "));
22533
22540
 
22541
+ // node_modules/@chipschat/protocol/dist/src/harness-jobs.js
22542
+ var HARNESS_JOBS_MAX = 24;
22543
+ var JOB_CHOICES_MAX = 12;
22544
+ var JOB_EVERY_MAX = 525600;
22545
+ var JOB_RUNS_POST_MAX = 200;
22546
+ var JOB_KINDS = ["heartbeat", "memory", "skills", "other"];
22547
+ var jobKind = external_exports.enum(JOB_KINDS);
22548
+ var JOB_RUN_OUTCOMES = ["done", "failed", "stopped"];
22549
+ var jobRunOutcome = external_exports.enum(JOB_RUN_OUTCOMES);
22550
+ 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 `-`.");
22551
+ var minutes2 = external_exports.int().min(1).max(JOB_EVERY_MAX);
22552
+ var ascending3 = (choices) => choices.every((each, at) => at === 0 || each > (choices[at - 1] ?? 0));
22553
+ var jobFields = {
22554
+ job_id: jobId,
22555
+ name: external_exports.string().min(1).max(40).describe('What the harness calls it: "Dreaming".'),
22556
+ about: external_exports.string().min(1).max(240).describe("What it does, in a sentence, for its page."),
22557
+ kind: jobKind.describe("What it does, for its mark: `other` for anything else."),
22558
+ every: minutes2.optional().describe("How often it runs, in minutes. Chips says it in words, with `next_at` for the time of day."),
22559
+ 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."),
22560
+ next_at: isoTimestamp.optional().describe("When it runs next, while it is on."),
22561
+ 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."),
22562
+ on: external_exports.boolean().describe("Whether it runs now."),
22563
+ editable: external_exports.boolean().describe("Whether a person may switch it from Chips."),
22564
+ 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`."),
22565
+ 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.")
22566
+ };
22567
+ var harnessJob = external_exports.object(jobFields).refine((job) => job.every !== void 0 || job.when !== void 0, {
22568
+ path: ["every"],
22569
+ message: "Say how often it runs: `every` in minutes, or `when` in words."
22570
+ }).refine((job) => job.choices === void 0 || job.choices.includes(job.every ?? -1), {
22571
+ path: ["choices"],
22572
+ message: "`every` is one of `choices`."
22573
+ }).refine((job) => job.why_read_only === void 0 || !job.editable, {
22574
+ path: ["why_read_only"],
22575
+ message: "Say why only for a job that can't be switched."
22576
+ });
22577
+ var uniqueJobs = (jobs) => new Set(jobs.map((job) => job.job_id)).size === jobs.length;
22578
+ var harnessJobsPut = external_exports.object({
22579
+ 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."),
22580
+ answers: id("change").optional().describe("The change this copy answers: made, and these are the jobs as they are now."),
22581
+ refuses: external_exports.object({
22582
+ change_id: id("change"),
22583
+ message: external_exports.string().min(1).max(300).optional().describe("Why not, for the person.")
22584
+ }).optional().describe("A change not made. The copy beside it is the jobs as they are now.")
22585
+ }).describe("`PUT /v1/harnesses/:id/jobs`: a harness's copy of the jobs it runs on its own.");
22586
+ var jobRun = external_exports.object({
22587
+ job_id: jobId,
22588
+ run_id: external_exports.string().min(1).max(160).describe("The harness's own id for the run."),
22589
+ started_at: isoTimestamp,
22590
+ ended_at: isoTimestamp,
22591
+ outcome: jobRunOutcome.describe("`done`, `failed`, or `stopped` when something else ended it, such as a restart."),
22592
+ quiet: external_exports.boolean().optional().describe("It did its work and had nothing to say: a heartbeat with nothing for anyone."),
22593
+ waited: external_exports.boolean().optional().describe("It waited for an approval that nobody gave."),
22594
+ 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."),
22595
+ agent_id: id("agent").optional().describe("The agent it ran for, when it runs for some."),
22596
+ 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."),
22597
+ tokens: external_exports.int().min(0).optional().describe("Its tokens, in and out."),
22598
+ model: external_exports.string().min(1).max(80).optional().describe("The model it ran on, in its words.")
22599
+ }).refine((run2) => Date.parse(run2.ended_at) >= Date.parse(run2.started_at), {
22600
+ path: ["ended_at"],
22601
+ message: "A run ends after it starts."
22602
+ }).describe("One run of a job, once it ended.");
22603
+ 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.");
22604
+ var jobChangeAsk = external_exports.object({
22605
+ on: external_exports.boolean(),
22606
+ every: minutes2.optional().describe("One of the job's choices; its own when left out.")
22607
+ }).describe("`POST /v1/harnesses/:id/jobs/:job/changes`: on or off, and how often.");
22608
+ var JOB_CHANGE_STATES = ["waiting", "saved", "failed", "missed"];
22609
+ var jobChangeState = external_exports.enum(JOB_CHANGE_STATES);
22610
+ var jobChangeView = external_exports.object({
22611
+ change_id: id("change"),
22612
+ state: jobChangeState.describe("`missed` once `JOB_CHANGE_WAIT_MS` has passed with no answer; read, never stored."),
22613
+ on: external_exports.boolean(),
22614
+ every: minutes2.optional(),
22615
+ asked_at: isoTimestamp,
22616
+ answered_at: isoTimestamp.optional(),
22617
+ message: external_exports.string().max(300).optional().describe("The harness's words, for a refusal.")
22618
+ }).describe("The last change a person asked of a job, and what became of it (ADR 0252).");
22619
+ var harnessJobView = external_exports.object({
22620
+ ...jobFields,
22621
+ 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."),
22622
+ week_runs: external_exports.int().min(0).describe("How many runs it made in the last seven days."),
22623
+ runs_total: external_exports.int().min(0).describe("How many of its runs Chips holds."),
22624
+ last_run: jobRun.optional(),
22625
+ change: jobChangeView.optional()
22626
+ }).describe("One job as a person reads it: the harness's copy, what Chips counted, its change.");
22627
+ var harnessJobsView = external_exports.object({
22628
+ harness_id: id("harness"),
22629
+ jobs: external_exports.array(harnessJobView),
22630
+ read_at: isoTimestamp.describe("When the harness last sent its copy."),
22631
+ away: external_exports.boolean().describe("No socket of the harness hears changes now: read, not switched.")
22632
+ }).describe("`GET /v1/harnesses/:id/jobs`, for the harness's owner or an admin.");
22633
+ var jobRunsView = external_exports.object({
22634
+ harness_id: id("harness"),
22635
+ job_id: jobId,
22636
+ runs: external_exports.array(jobRun).describe("Newest first."),
22637
+ more: external_exports.boolean().describe("Whether older runs are left, for `before` the last one's start.")
22638
+ }).describe("`GET /v1/harnesses/:id/jobs/:job/runs?since=&before=&limit=`.");
22639
+ var jobChangeFrame = external_exports.object({
22640
+ frame: external_exports.literal("job.change"),
22641
+ change_id: id("change"),
22642
+ harness_id: id("harness"),
22643
+ job_id: jobId,
22644
+ on: external_exports.boolean(),
22645
+ every: minutes2.optional().describe("For a job with choices: one of them, the copy's own when the person named none."),
22646
+ asked_by: id("person"),
22647
+ asked_at: isoTimestamp
22648
+ }).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`.");
22649
+
22534
22650
  // node_modules/@chipschat/protocol/dist/src/frames.js
22535
22651
  var clientHelloFrame = external_exports.object({
22536
22652
  frame: external_exports.literal("hello"),
@@ -22547,7 +22663,7 @@ var clientHelloFrame = external_exports.object({
22547
22663
  autonomy: autonomyLevel.optional().describe("The level the harness believes it has.")
22548
22664
  })).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."),
22549
22665
  since: external_exports.int().nonnegative().optional().describe("Not read by Chips: a stream resumes from `subscribe`'s `since`."),
22550
- 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."),
22666
+ 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."),
22551
22667
  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.")
22552
22668
  }).describe("The first frame a client sends.");
22553
22669
  var subscribeFrame = external_exports.object({
@@ -22678,6 +22794,7 @@ var serverFrame = external_exports.discriminatedUnion("frame", [
22678
22794
  heartbeatChangeFrame,
22679
22795
  windowCompactFrame,
22680
22796
  windowChangeFrame,
22797
+ jobChangeFrame,
22681
22798
  pingFrame,
22682
22799
  pongFrame,
22683
22800
  errorFrame
@@ -23805,6 +23922,14 @@ var Run = class {
23805
23922
  ...cost2(input2.costUsd)
23806
23923
  });
23807
23924
  }
23925
+ /**
23926
+ * That this turn heard a message said in the room while it worked (ADR 0106): one that
23927
+ * `message.overheard` named this run for in `working_turns`, handed to the turn at a step. The
23928
+ * room shows its agent heard it while working. Say it once the turn has the words, never before.
23929
+ */
23930
+ heard(messageId) {
23931
+ return this.wire.send("message.heard", { message_id: messageId });
23932
+ }
23808
23933
  checkpoint(label2, next, compacted) {
23809
23934
  return this.wire.send("checkpoint", {
23810
23935
  label: label2,
@@ -23854,7 +23979,8 @@ function acceptsFor(handlers) {
23854
23979
  ...handlers.context === void 0 ? [] : ["context"],
23855
23980
  ...handlers.models === void 0 ? [] : ["models"],
23856
23981
  ...handlers.heartbeats === void 0 ? [] : ["heartbeats"],
23857
- ...handlers.contextWindows === void 0 ? [] : ["context_windows"]
23982
+ ...handlers.contextWindows === void 0 ? [] : ["context_windows"],
23983
+ ...handlers.jobs === void 0 ? [] : ["jobs"]
23858
23984
  ];
23859
23985
  }
23860
23986
  var PATHS = {
@@ -23862,28 +23988,32 @@ var PATHS = {
23862
23988
  "harness-context": (id2) => `/v1/harnesses/${encodeURIComponent(id2)}/context`,
23863
23989
  model: (id2) => `/v1/agents/${encodeURIComponent(id2)}/model`,
23864
23990
  heartbeat: (id2) => `/v1/agents/${encodeURIComponent(id2)}/heartbeat`,
23865
- "context-window": (id2) => `/v1/agents/${encodeURIComponent(id2)}/context-window`
23991
+ "context-window": (id2) => `/v1/agents/${encodeURIComponent(id2)}/context-window`,
23992
+ jobs: (id2) => `/v1/harnesses/${encodeURIComponent(id2)}/jobs`
23866
23993
  };
23867
23994
  var FRAMES = {
23868
23995
  "context.edit": contextEditFrame,
23869
23996
  "model.change": modelChangeFrame,
23870
23997
  "heartbeat.change": heartbeatChangeFrame,
23871
23998
  "context_window.compact": windowCompactFrame,
23872
- "context_window.change": windowChangeFrame
23999
+ "context_window.change": windowChangeFrame,
24000
+ "job.change": jobChangeFrame
23873
24001
  };
23874
24002
  var Settings = class {
23875
24003
  put;
23876
24004
  harnessId;
23877
24005
  handlers;
24006
+ post;
23878
24007
  /** The copy last given for each `kind:id`, for a refusal to carry. */
23879
24008
  sent = /* @__PURE__ */ new Map();
23880
24009
  /** The copy Chips last took for each `kind:id`, as JSON. */
23881
24010
  landed = /* @__PURE__ */ new Map();
23882
24011
  chains = /* @__PURE__ */ new Map();
23883
- constructor(put, harnessId, handlers) {
24012
+ constructor(put, harnessId, handlers, post) {
23884
24013
  this.put = put;
23885
24014
  this.harnessId = harnessId;
23886
24015
  this.handlers = handlers;
24016
+ this.post = post;
23887
24017
  }
23888
24018
  /** An agent's context files (`context_files`). */
23889
24019
  context(agentId2, copy) {
@@ -23905,6 +24035,24 @@ var Settings = class {
23905
24035
  contextWindow(agentId2, copy) {
23906
24036
  return this.send("context-window", agentId2, copy, {});
23907
24037
  }
24038
+ /** The jobs the harness runs on its own, all of them (`jobs`). */
24039
+ jobs(copy) {
24040
+ return this.send("jobs", this.harnessId(), copy, {});
24041
+ }
24042
+ /**
24043
+ * Runs of its jobs the harness finished (`jobs`), two hundred to a post. A run sent again says
24044
+ * what it says over the one before, and what it leaves out stays, so send it once more when its
24045
+ * cost is known, and again without one does no harm. Send the copy first:
24046
+ * Chips refuses runs of a job its copy doesn't list.
24047
+ */
24048
+ async jobRuns(runs) {
24049
+ if (this.post === void 0)
24050
+ throw new Error("This connection can't post a job's runs.");
24051
+ const path = `${PATHS.jobs(this.harnessId())}/runs`;
24052
+ for (let at = 0; at < runs.length; at += JOB_RUNS_POST_MAX) {
24053
+ await this.post(path, { runs: runs.slice(at, at + JOB_RUNS_POST_MAX) });
24054
+ }
24055
+ }
23908
24056
  /** An agent deleted: nothing is remembered of it, so a copy for an agent made again is sent. */
23909
24057
  forget(agentId2) {
23910
24058
  for (const kind of Object.keys(PATHS)) {
@@ -23952,6 +24100,8 @@ var Settings = class {
23952
24100
  return this.answer("model", frame.agent_id, frame.change_id, "change_id", () => handlers?.models?.(frame));
23953
24101
  case "heartbeat.change":
23954
24102
  return this.answer("heartbeat", frame.agent_id, frame.change_id, "change_id", () => handlers?.heartbeats?.(frame));
24103
+ case "job.change":
24104
+ return this.answer("jobs", this.harnessId(), frame.change_id, "change_id", () => handlers?.jobs?.(frame));
23955
24105
  case "context_window.compact":
23956
24106
  return this.answer("context-window", frame.agent_id, frame.change_id, "change_id", () => handlers?.contextWindows?.compact(frame));
23957
24107
  default:
@@ -24067,7 +24217,7 @@ var Chips = class _Chips {
24067
24217
  this.outbox.add(String(event["idempotency_key"]), event).catch(() => void 0);
24068
24218
  }
24069
24219
  this.orphans = [...kept?.runs ?? []];
24070
- this.settings = new Settings((path, body) => this.request("PUT", path, body), () => this.harnessId, options.settings);
24220
+ this.settings = new Settings((path, body) => this.request("PUT", path, body), () => this.harnessId, options.settings, (path, body) => this.request("POST", path, body));
24071
24221
  }
24072
24222
  /**
24073
24223
  * The harness's copies of what a person changes from an agent's page (ADRs 0134, 0140, 0143,
@@ -27709,7 +27859,7 @@ ${command}
27709
27859
  const patch = files.map((file3) => text(file3["patch"]) ?? "").filter((each) => each !== "").join("\n");
27710
27860
  return {
27711
27861
  action: { kind: "file.edit", input: { files: resources } },
27712
- question: one === void 0 ? "Change these files?" : `Change ${baseName(one)}?`,
27862
+ question: one === void 0 ? "Change these files?" : `Change ${cut(baseName(one), QUESTION_MAX - 8)}?`,
27713
27863
  risk: [],
27714
27864
  ...patch === "" ? {} : { preview: { format: "diff", title: one ?? "Changes", body: patch.slice(0, 2e5) } },
27715
27865
  ...effect
@@ -27727,7 +27877,7 @@ ${command}
27727
27877
  const what = resources.filter((each) => each !== "*").join(", ");
27728
27878
  return {
27729
27879
  action: { kind: `opencode.${action2.toLowerCase().replace(/[^a-z0-9_]+/g, "_") || "act"}`, input: { resources } },
27730
- question: `${verb}${what === "" ? "" : ` ${what}`}?`.slice(0, 300),
27880
+ question: `${verb}${what === "" ? "" : ` ${cut(what, QUESTION_MAX - verb.length - 2)}`}?`,
27731
27881
  risk: action2 === "webfetch" || action2 === "websearch" ? ["external"] : [],
27732
27882
  ...effect
27733
27883
  };
@@ -27803,6 +27953,7 @@ function secondLook(who, reply, note) {
27803
27953
  const first = note?.split("\n").find((line) => line.trim() !== "")?.trim();
27804
27954
  return { text: text2, goal: first === void 0 ? "Looking again at its reply" : cut(`Looking again: ${first}`, 120) };
27805
27955
  }
27956
+ var QUESTION_MAX = 200;
27806
27957
  function cut(words4, most) {
27807
27958
  return words4.length <= most ? words4 : `${words4.slice(0, most - 1)}\u2026`;
27808
27959
  }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@chipschat/opencode",
3
- "version": "1.0.10",
3
+ "version": "1.0.12",
4
4
  "description": "OpenCode as a Chips harness, on its V2 server (opencode serve): each OpenCode agent a Chips agent, each room an OpenCode 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",