@chipschat/hermes 1.0.15 → 1.0.16

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.
@@ -1,9 +1,9 @@
1
1
  # Third-party notices
2
2
 
3
- `dist/main.js` in @chipschat/hermes 1.0.15 carries these packages, bundled in. Each one's
3
+ `dist/main.js` in @chipschat/hermes 1.0.16 carries these packages, bundled in. Each one's
4
4
  licence follows.
5
5
 
6
- ## @chipschat/harness 1.0.1 (Apache-2.0)
6
+ ## @chipschat/harness 1.0.2 (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 1.0.1 (Apache-2.0)
210
+ ## @chipschat/protocol 1.0.2 (Apache-2.0)
211
211
 
212
212
  Apache License
213
213
  Version 2.0, January 2004
package/dist/main.js CHANGED
@@ -20529,7 +20529,7 @@ var contextLine = external_exports.object({
20529
20529
  }).describe("One line of a room: something said, or something that happened to who is in it.");
20530
20530
  var roomContext = external_exports.object({
20531
20531
  lines: external_exports.array(contextLine).max(CONTEXT_CEILING.lines).describe("Oldest first, the newest that fit the budget."),
20532
- since_seq: external_exports.int().nonnegative().describe("Where they start: after this `seq`. With a message, where the turn that said the harness's own last message in the room began (ADR 0105), else its joining; from the pull route, 0."),
20532
+ since_seq: external_exports.int().nonnegative().describe("Where they start: after this `seq`. With a message, where the harness's own last turn in the room began, one that said something or passed with NO_REPLY (ADR 0105), else its joining; from the pull route, 0."),
20533
20533
  truncated: external_exports.boolean().describe("Whether older lines after `since_seq` were left out to fit the budget."),
20534
20534
  before: external_exports.int().positive().describe("A cursor: `GET /v1/spaces/:id/context?before=` this reads what came before these lines."),
20535
20535
  files: roomFiles.max(ROOM_FILES_IN_CONTEXT).optional().describe("The room's files at their current version, newest first, the 20 newest (ADR 0099): with a message, as of it, its own files included; from the pull route, as of now. Each with a URL for this harness. Absent from a Chips before files, and when the room has none."),
@@ -21677,6 +21677,7 @@ var pairingPayload = external_exports.object({
21677
21677
  var JOIN_POLL_SECONDS = 3;
21678
21678
  var joinKind = external_exports.enum(["harness", "device", "invite", "pairing"]).describe("A harness asking for a key; a device asking to be paired; a person joining by an invite, or a device pairing by a code, that waits for whoever handed it out (ADR 0232).");
21679
21679
  var keyCode = external_exports.string().regex(/^[0-9]{6}$/, "six digits");
21680
+ var joinNonce = external_exports.string().regex(/^[A-Za-z0-9_-]{43}$/, "32 bytes, base64url");
21680
21681
  var requestCode = external_exports.union([pairingCode, keyCode]);
21681
21682
  var joinState = external_exports.enum(["waiting", "allowed", "denied", "expired", "redeemed"]).describe("`waiting` for a person; `allowed`, and not yet collected; `denied` by a person, or withdrawn; `expired` before it was collected; `redeemed`, which spends it.");
21682
21683
  var joinStartedBy = external_exports.enum(["requester", "person"]).describe("Who started it: the requester, with a code to compare, or a person, with a link that is allowed already.");
@@ -21712,12 +21713,15 @@ var joinAsk = external_exports.object({
21712
21713
  software: words2(120).optional(),
21713
21714
  machine: words2(120).optional(),
21714
21715
  wants: capabilities.optional().describe("For a harness: what it asks to be allowed."),
21715
- public_key: external_exports.string().regex(/^[A-Za-z0-9+/]{40,64}={0,2}$/).optional().describe("For a device: the public half of its Ed25519 key, SPKI DER, base64.")
21716
+ public_key: external_exports.string().regex(/^[A-Za-z0-9+/]{40,64}={0,2}$/).optional().describe("For a device: the public half of its Ed25519 key, SPKI DER, base64."),
21717
+ commit: joinNonce.optional().describe("For a device (S-1, ADR 0278): the SHA-256 of `joinCommitText` of a nonce it keeps, base64url. It sends the nonce with its first poll, once it holds the server's, and both ends work the code out.")
21716
21718
  }).describe("A request to join.");
21717
21719
  var joinAsked = external_exports.object({
21718
21720
  request_id: id("join"),
21719
21721
  secret: external_exports.string().min(16).max(200).describe("The requester's alone: it polls with it."),
21720
- code: requestCode,
21722
+ code: requestCode.optional().describe("The code to show. Absent for a device that sent `commit`: it works its own out."),
21723
+ server_key: external_exports.string().min(1).max(128).optional().describe("For a device that sent `commit`: the server's tunnel key, which the code is worked out from and the device pins once it is allowed (ADR 0191, 0278)."),
21724
+ nonce: joinNonce.optional().describe("For a device that sent `commit`: the server's nonce, for the code (ADR 0278)."),
21721
21725
  expires_in: external_exports.int().positive().describe("Seconds until it expires."),
21722
21726
  interval: external_exports.int().positive().describe("Seconds between polls.")
21723
21727
  });
@@ -22649,6 +22653,17 @@ var jobChangeFrame = external_exports.object({
22649
22653
  asked_at: isoTimestamp
22650
22654
  }).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
22655
 
22656
+ // node_modules/@chipschat/protocol/dist/src/read-marks.js
22657
+ var READ_MARKS_MAX = 1e3;
22658
+ var readMarks = external_exports.record(id("space"), external_exports.int().nonnegative().describe("The `seq` the room is read up to.")).refine((marks) => Object.keys(marks).length <= READ_MARKS_MAX, {
22659
+ message: `at most ${READ_MARKS_MAX} rooms`
22660
+ }).describe("How far each room is read, by room id.");
22661
+ var readMarksBody = external_exports.object({ spaces: readMarks });
22662
+ var readFrame = external_exports.object({
22663
+ frame: external_exports.literal("read"),
22664
+ spaces: readMarks.describe("The rooms whose marks moved, and where to.")
22665
+ }).describe("A person read further in some rooms, on one of their devices (ADR 0262). Sent to that person's sockets that said `reads` in their `hello`, never to anyone else's, now or never: `GET /v1/me/read` reads them again.");
22666
+
22652
22667
  // node_modules/@chipschat/protocol/dist/src/frames.js
22653
22668
  var clientHelloFrame = external_exports.object({
22654
22669
  frame: external_exports.literal("hello"),
@@ -22665,7 +22680,7 @@ var clientHelloFrame = external_exports.object({
22665
22680
  autonomy: autonomyLevel.optional().describe("The level the harness believes it has.")
22666
22681
  })).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."),
22667
22682
  since: external_exports.int().nonnegative().optional().describe("Not read by Chips: a stream resumes from `subscribe`'s `since`."),
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."),
22683
+ 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); a person's that says `reads` is sent `read` when they read further on another of their devices (ADR 0262); one that says nothing is sent what it was always sent, since an unknown frame is dropped in silence."),
22669
22684
  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.")
22670
22685
  }).describe("The first frame a client sends.");
22671
22686
  var subscribeFrame = external_exports.object({
@@ -22791,6 +22806,7 @@ var serverFrame = external_exports.discriminatedUnion("frame", [
22791
22806
  folderOpenFrame,
22792
22807
  folderRunFrame,
22793
22808
  folderRunStateFrame,
22809
+ readFrame,
22794
22810
  contextEditFrame,
22795
22811
  modelChangeFrame,
22796
22812
  heartbeatChangeFrame,
@@ -22842,9 +22858,37 @@ var HTML_POLICY = "default-src 'none'; img-src data: blob:; font-src data:; medi
22842
22858
  var PAGE_SANDBOX = "allow-scripts allow-popups allow-popups-to-escape-sandbox";
22843
22859
  var PAGE_HEADER_POLICY = `${HTML_POLICY}; sandbox ${PAGE_SANDBOX}`;
22844
22860
 
22845
- // node_modules/@chipschat/harness/dist/connect.js
22846
- import { readFile as readFile2 } from "node:fs/promises";
22847
- import { basename } from "node:path";
22861
+ // node_modules/@chipschat/protocol/dist/src/push.js
22862
+ var PUSH_WORDS = {
22863
+ /** An ask of an agent's that waits on a person (ADR 0045). */
22864
+ decision: {
22865
+ title: "A decision is waiting",
22866
+ body: "Approve or deny from here.",
22867
+ categoryId: "decision"
22868
+ },
22869
+ /** A message that @s the person, or was sent to them (ADR 0158). */
22870
+ messageForYou: { title: "A message for you", body: "Open Chips to read it." },
22871
+ /** A message in a room they hear (ADR 0158). */
22872
+ message: { title: "A new message", body: "Open Chips to read it." },
22873
+ /** A join request for its maker or an owner (ADR 0122). */
22874
+ join: { title: "Something asks to join", body: "Check its code, then allow it or not." },
22875
+ /** The referee paused agents talking among themselves (ADR 0097). */
22876
+ held: { title: "Chips paused the agents", body: "Open the space to let them carry on." },
22877
+ warning: { title: "The agents need a look", body: "They have been talking among themselves." },
22878
+ /** A guest's ask to go direct, and its answers (ADR 0211). */
22879
+ directAsked: {
22880
+ title: "A guest wants to connect directly",
22881
+ body: "Share your server with them in Tailscale."
22882
+ },
22883
+ directShared: { title: "Your server is shared with you", body: "Open Chips to go direct." },
22884
+ directDone: {
22885
+ title: "Connected directly",
22886
+ body: "A guest you shared your server with is direct now."
22887
+ },
22888
+ /** An owner is turning the relay off (ADR 0211, Phase 4). */
22889
+ relayOff: { title: "The relay is going off", body: "Go direct to keep reaching the server." }
22890
+ };
22891
+ var KNOWN = new Set(Object.values(PUSH_WORDS).map((words4) => JSON.stringify([words4.title, words4.body, "categoryId" in words4 ? words4.categoryId : null])));
22848
22892
 
22849
22893
  // node_modules/@chipschat/harness/dist/asks.js
22850
22894
  var Asks = class {
@@ -22879,10 +22923,7 @@ var Asks = class {
22879
22923
  const from = event["from"];
22880
22924
  if (!this.listener.listening() || from?.kind !== "person")
22881
22925
  return false;
22882
- this.hand(spaceId, room, {
22883
- messageId: String(event["message_id"]),
22884
- text: String(event["text"] ?? "")
22885
- });
22926
+ this.hand(spaceId, room, { messageId: String(event["message_id"]), text: String(event["text"] ?? "") }, event);
22886
22927
  return true;
22887
22928
  }
22888
22929
  /**
@@ -22918,11 +22959,42 @@ var Asks = class {
22918
22959
  this.rooms.set(spaceId, room);
22919
22960
  return room;
22920
22961
  }
22921
- hand(spaceId, room, first) {
22962
+ hand(spaceId, room, first, message) {
22922
22963
  room.first = first.messageId;
22923
- this.listener.hand({ spaceId, askedBy: room.askedBy, firstMessage: first });
22964
+ this.listener.hand({
22965
+ spaceId,
22966
+ askedBy: room.askedBy,
22967
+ firstMessage: first,
22968
+ ...message === void 0 ? {} : { message }
22969
+ });
22924
22970
  }
22925
22971
  };
22972
+ function firstTurnOf(asked, agentId2) {
22973
+ const { message } = asked;
22974
+ if (message === void 0)
22975
+ return void 0;
22976
+ const room = message.room;
22977
+ const notes = room?.notes ?? {};
22978
+ const [place, ...more] = Object.keys(notes);
22979
+ if (room === void 0 || place === void 0 || more.length > 0) {
22980
+ return { ...message, for: [agentId2] };
22981
+ }
22982
+ const placed = (each) => each.participant_id === place ? { ...each, participant_id: agentId2 } : each;
22983
+ const note = notes[place];
22984
+ const rules = room.rules?.[place];
22985
+ return {
22986
+ ...message,
22987
+ for: [agentId2],
22988
+ room: {
22989
+ ...room,
22990
+ members: room.members.map(placed),
22991
+ notes: note === void 0 ? {} : { [agentId2]: note },
22992
+ ...room.rules === void 0 ? {} : { rules: rules === void 0 ? {} : { [agentId2]: rules } },
22993
+ ...room.working === void 0 ? {} : { working: room.working.map(placed) },
22994
+ ...room.idle === void 0 ? {} : { idle: room.idle.map(placed) }
22995
+ }
22996
+ };
22997
+ }
22926
22998
  function firstWords(history) {
22927
22999
  for (const event of history) {
22928
23000
  const actor2 = event["actor"];
@@ -22933,6 +23005,10 @@ function firstWords(history) {
22933
23005
  return void 0;
22934
23006
  }
22935
23007
 
23008
+ // node_modules/@chipschat/harness/dist/connect.js
23009
+ import { readFile as readFile2 } from "node:fs/promises";
23010
+ import { basename } from "node:path";
23011
+
22936
23012
  // node_modules/@chipschat/harness/dist/events.js
22937
23013
  var Emitter = class {
22938
23014
  handlers = /* @__PURE__ */ new Map();
@@ -28054,7 +28130,7 @@ ${hook.lines}`);
28054
28130
  await this.ownProfile(agent.agentId, agent.name);
28055
28131
  this.ours.add(agent.agentId);
28056
28132
  void this.agentsMoved();
28057
- const message = {
28133
+ const message = firstTurnOf(asked, agent.agentId) ?? {
28058
28134
  type: "message.new",
28059
28135
  space_id: spaceId,
28060
28136
  message_id: firstMessage.messageId,
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@chipschat/hermes",
3
- "version": "1.0.15",
3
+ "version": "1.0.16",
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": "1.0.1",
37
- "@chipschat/harness": "1.0.1",
38
- "@chipschat/protocol": "1.0.1",
36
+ "@chipschat/conformance": "1.0.2",
37
+ "@chipschat/harness": "1.0.2",
38
+ "@chipschat/protocol": "1.0.2",
39
39
  "@types/node": "22.19.0",
40
40
  "esbuild": "0.27.7",
41
41
  "tsx": "4.21.0",