pinomad 0.3.0 → 0.5.0

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.
@@ -3,105 +3,19 @@ import {
3
3
  INVALID_FRAME_CLOSE_CODE,
4
4
  PROTOCOL,
5
5
  UNAUTHORIZED_CLOSE_CODE,
6
+ checkoutOf,
6
7
  conversationStream,
7
8
  docStream,
9
+ homeOf,
8
10
  hostStreams,
9
11
  hostSupportsCall,
10
- hostSupportsFeature
11
- } from "./chunk-c155p0t0.js";
12
+ hostSupportsFeature,
13
+ organize
14
+ } from "./chunk-hsp12cjt.js";
12
15
 
13
16
  // packages/protocol/src/remote-durable.ts
14
17
  import { applyImmutable } from "@earendil-works/chord/delta";
15
18
 
16
- // packages/protocol/src/organization.ts
17
- function organize(index, summaries) {
18
- const summaryById = new Map(summaries.map((summary) => [summary.id, summary]));
19
- const nodes = new Map;
20
- const topLevel = new Map;
21
- for (const entry of index.conversations) {
22
- if (entry.archived === true)
23
- continue;
24
- const home = entry.home;
25
- if (home.kind === "project" && !index.projects.some((project) => project.path === home.path))
26
- continue;
27
- const summary = summaryById.get(entry.id);
28
- if (summary === undefined)
29
- continue;
30
- topLevel.set(entry.id, entry);
31
- nodes.set(entry.id, { summary, children: [] });
32
- }
33
- for (const summary of summaries) {
34
- const chain = [summary];
35
- let current = summary;
36
- while (!topLevel.has(current.id)) {
37
- const parent = current.parent === undefined ? undefined : summaryById.get(current.parent);
38
- if (parent === undefined || chain.includes(parent))
39
- break;
40
- chain.push(parent);
41
- current = parent;
42
- }
43
- if (!topLevel.has(current.id))
44
- continue;
45
- for (let i = chain.length - 1;i >= 0; i--) {
46
- const member = chain[i];
47
- if (!nodes.has(member.id))
48
- nodes.set(member.id, { summary: member, children: [] });
49
- if (i < chain.length - 1) {
50
- const parent = nodes.get(chain[i + 1].id);
51
- const child = nodes.get(member.id);
52
- if (!parent.children.includes(child))
53
- parent.children.push(child);
54
- }
55
- }
56
- }
57
- const byIdAscending = (a, b) => a.summary.id - b.summary.id;
58
- const nodeList = (entry) => sortChildren(nodes.get(entry.id));
59
- const sortChildren = (node) => ({
60
- summary: node.summary,
61
- children: [...node.children].sort(byIdAscending).map(sortChildren)
62
- });
63
- const entries = [...topLevel.values()].sort((a, b) => b.createdAt - a.createdAt);
64
- return {
65
- chats: entries.filter((entry) => entry.home.kind === "chat").map(nodeList),
66
- projects: [...index.projects].sort((a, b) => b.addedAt - a.addedAt).map((project) => ({
67
- project,
68
- conversations: entries.filter((entry) => entry.home.kind === "project" && entry.home.path === project.path).map(nodeList)
69
- }))
70
- };
71
- }
72
- function checkoutOf(index, summaries, id) {
73
- const record = index.checkouts?.find((checkout) => checkout.conversationId === id);
74
- if (record !== undefined)
75
- return record;
76
- const summaryById = new Map(summaries.map((summary) => [summary.id, summary]));
77
- const seen = new Set;
78
- let current = summaryById.get(id);
79
- while (current !== undefined && !seen.has(current.id)) {
80
- seen.add(current.id);
81
- const ancestor = index.checkouts?.find((checkout) => checkout.conversationId === current.id);
82
- if (ancestor !== undefined)
83
- return ancestor;
84
- current = current.parent === undefined ? undefined : summaryById.get(current.parent);
85
- }
86
- return;
87
- }
88
- function homeOf(index, summaries, id) {
89
- const entry = index.conversations.find((candidate) => candidate.id === id);
90
- if (entry !== undefined)
91
- return entry.home;
92
- const summaryById = new Map(summaries.map((summary) => [summary.id, summary]));
93
- const seen = new Set;
94
- let current = summaryById.get(id);
95
- while (current !== undefined && !seen.has(current.id)) {
96
- seen.add(current.id);
97
- const ancestor = index.conversations.find((candidate) => candidate.id === current.id);
98
- if (ancestor !== undefined)
99
- return ancestor.home;
100
- current = current.parent === undefined ? undefined : summaryById.get(current.parent);
101
- }
102
- return;
103
- }
104
-
105
19
  // packages/protocol/src/transport.ts
106
20
  function webSocketTransport(url, token) {
107
21
  return {
@@ -338,7 +252,7 @@ class RemoteClient {
338
252
  Promise.all(hostStreams(hostMinor).map((stream) => this.#snapshot(stream))).then(() => {
339
253
  this.#state = {
340
254
  session: hello.session,
341
- organized: { chats: [], projects: [] },
255
+ organized: { chats: [], projects: [], archived: [] },
342
256
  models: this.#host("models") ?? hello.models,
343
257
  defaults: this.#effectiveDefaults(hello.defaults ?? {}),
344
258
  notices: [],
@@ -526,6 +440,9 @@ class RemoteClient {
526
440
  if (images.length > 0 && !hostSupportsFeature(this.#hostMinor, "images")) {
527
441
  throw new Error("The host is too old for images (needs protocol 5.5); run `pinomad upgrade` on the host");
528
442
  }
443
+ if (options?.agent !== undefined && !hostSupportsFeature(this.#hostMinor, "agentConversations")) {
444
+ throw new Error("The host is too old for named agents (needs protocol 5.10); run `pinomad upgrade` on the host");
445
+ }
529
446
  const { conversationId: conversationId2 } = await this.#call("createConversation", {
530
447
  home,
531
448
  text,
@@ -533,6 +450,7 @@ class RemoteClient {
533
450
  ...options?.checkout === undefined ? {} : { checkout: options.checkout },
534
451
  ...options?.model === undefined ? {} : { model: options.model },
535
452
  ...options?.thinkingLevel === undefined ? {} : { thinkingLevel: options.thinkingLevel },
453
+ ...options?.agent === undefined ? {} : { agent: options.agent },
536
454
  ...images.length === 0 ? {} : { images }
537
455
  });
538
456
  await this.#switch(conversationId2);
@@ -596,6 +514,12 @@ class RemoteClient {
596
514
  }),
597
515
  answer: (kind, requestId, answers, target) => this.#command(() => this.#call("answer", { conversationId: target ?? conversationId(), kind, requestId, answers })),
598
516
  changes: () => this.#request(() => this.#call("changes", { conversationId: conversationId() })),
517
+ listFiles: (scope, query) => {
518
+ if (!hostSupportsCall(this.#hostMinor, "listFiles")) {
519
+ return Promise.reject(new Error("The host is too old for this (needs protocol 5.10); run `pinomad upgrade` on the host"));
520
+ }
521
+ return this.#call("listFiles", { scope, query });
522
+ },
599
523
  createPairing: () => this.#request(() => this.#call("createPairing", {})),
600
524
  revokeDevice: (publicKey) => this.#command(() => this.#call("revokeDevice", { publicKey })),
601
525
  logout: (providerId) => this.#command(() => {
@@ -608,6 +532,9 @@ class RemoteClient {
608
532
  if (!hostSupportsCall(this.#hostMinor, "updateSettings")) {
609
533
  throw new Error("The host is too old for this (needs protocol 5.2); run `pinomad upgrade` on the host");
610
534
  }
535
+ if (patch.acceptAccountDevices !== undefined && !hostSupportsFeature(this.#hostMinor, "acceptAccountDevices")) {
536
+ throw new Error("The host is too old for this (needs protocol 5.8); run `pinomad upgrade` on the host");
537
+ }
611
538
  return this.#call("updateSettings", { patch });
612
539
  }),
613
540
  createAgent: (role) => this.#request(async () => {
@@ -627,6 +554,15 @@ class RemoteClient {
627
554
  throw new Error("The host is too old for this (needs protocol 5.6); run `pinomad upgrade` on the host");
628
555
  }
629
556
  await this.#call("deleteAgent", { name });
557
+ }),
558
+ setPushToken: (token) => this.#request(async () => {
559
+ if (!hostSupportsCall(this.#hostMinor, "setPushToken")) {
560
+ throw new Error("The host is too old for this (needs protocol 5.7); run `pinomad upgrade` on the host");
561
+ }
562
+ if (token !== null && typeof token !== "string" && !hostSupportsFeature(this.#hostMinor, "apnsPush")) {
563
+ throw new Error("The host is too old for this (needs protocol 5.9); run `pinomad upgrade` on the host");
564
+ }
565
+ await this.#call("setPushToken", { token });
630
566
  })
631
567
  };
632
568
  }
@@ -1,7 +1,7 @@
1
1
  import {
2
2
  connectRemoteDurable
3
- } from "./chunk-bggesvnj.js";
4
- import"./chunk-c155p0t0.js";
3
+ } from "./chunk-m4q9wafw.js";
4
+ import"./chunk-hsp12cjt.js";
5
5
  import {
6
6
  hostAddress
7
7
  } from "./chunk-cjfmfyjb.js";
package/dist/pinomad.js CHANGED
@@ -1,32 +1,37 @@
1
1
  #!/usr/bin/env node
2
2
  import {
3
3
  packagedVersion
4
- } from "./chunk-3tf23vjq.js";
4
+ } from "./chunk-1d9sppj0.js";
5
5
  import {
6
6
  __require
7
7
  } from "./chunk-df32avw6.js";
8
8
 
9
9
  // apps/cli/src/pinomad.ts
10
10
  var COMMANDS = {
11
- host: () => import("./chunk-tfqc1djy.js"),
12
- relay: () => import("./chunk-4dj2vb8t.js"),
13
- service: () => import("./chunk-kxws8b83.js"),
14
- upgrade: () => import("./chunk-n60kkf1m.js"),
15
- link: () => import("./chunk-3qn8gbjb.js"),
16
- pair: () => import("./chunk-syf0z68f.js"),
17
- "relay-id": () => import("./chunk-7fqn69ys.js")
11
+ host: () => import("./chunk-d4wdt5qs.js"),
12
+ server: () => import("./chunk-4by4x5c4.js"),
13
+ relay: () => import("./chunk-4by4x5c4.js"),
14
+ service: () => import("./chunk-5ng86fmy.js"),
15
+ upgrade: () => import("./chunk-crv3dqzp.js"),
16
+ link: () => import("./chunk-gqr7ahv4.js"),
17
+ pair: () => import("./chunk-zttf1hvh.js"),
18
+ join: () => import("./chunk-9d59jjmt.js"),
19
+ leave: () => import("./chunk-f0v3sht0.js")
18
20
  };
19
- var USAGE = `pinomad — PiNomad host, relay, and utilities
21
+ var USAGE = `pinomad — PiNomad host, server, and utilities
20
22
 
21
23
  usage: pinomad <command> [args…]
22
24
 
23
25
  host [host args…] run the host in the foreground
24
- relay --public-origin O --allow-host H… run the relay
26
+ server --public-origin O [--data-dir D] [--trust-proxy] run the server
27
+ server passwd [--data-dir D] [--user U] change the account password (stdin)
28
+ relay … old name of server
25
29
  service install|uninstall|status|restart|logs user-level host service
26
30
  upgrade [--force] [address flags] upgrade the package and restart the service
27
31
  link [--data-dir D|--url U …] print the browser link
28
32
  pair [--data-dir D|--url U …] print a pairing QR
29
- relay-id [--data-dir D] print this host's relay id (for --allow-host)
33
+ join <origin> <token> [--data-dir D] join this host to a server account
34
+ leave [--data-dir D] leave the server account
30
35
  --version, -v print the version
31
36
  `;
32
37
  async function main(argv) {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "pinomad",
3
- "version": "0.3.0",
3
+ "version": "0.5.0",
4
4
  "description": "PiNomad — self-hosted coding agent: host, relay, and web client in one package",
5
5
  "license": "Apache-2.0",
6
6
  "type": "module",
Binary file