pinomad 0.7.0 → 0.8.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.
package/README.md CHANGED
@@ -20,74 +20,21 @@ The host needs Node 25+ on macOS or Linux.
20
20
 
21
21
  ```sh
22
22
  npm i -g pinomad
23
- pinomad host # uses the models and credentials you set up in pi (~/.pi/agent)
23
+ pinomad host # data and credentials live in ~/.pinomad
24
24
  pinomad link # in another terminal: prints a browser link to the web client
25
25
  ```
26
26
 
27
- Haven't set up pi yet? `pinomad host --faux "hi"` runs a scripted fake model so you can click around.
28
-
29
- ## Connect your other devices
30
-
31
- Open a port for paired devices, then pair each device with its own QR code:
32
-
33
- ```sh
34
- pinomad host --remote-port 7422
35
- pinomad pair # one-time QR code and link, expires after 5 minutes
36
- ```
37
-
38
- Scan the code with the iPhone app, or paste the link into the Mac app. The remote port accepts paired devices only; revoke them under Settings → Devices.
39
-
40
- The pairing link uses the LAN address the host detects. On a tailnet or behind a tunnel, add `--public-url http://<tailnet-ip>:7422` so the link points there. To reach a host at home from anywhere, run the relay on a VPS: see [Remote access](docs/remote-access.md).
41
-
42
- ## Keep it running
43
-
44
- Install the host as a user service (LaunchAgent on macOS, systemd user unit on Linux) so it starts at boot and restarts on crash:
45
-
46
- ```sh
47
- pinomad service install --remote-port 7422
48
- pinomad service status
49
- pinomad upgrade # install pinomad@latest, wait for running tasks, restart
50
- ```
51
-
52
- Service flags, logs, and platform caveats: [Running as a service](docs/service.md).
53
-
54
- ## Clients
55
-
56
- | Client | How to get it |
57
- |---|---|
58
- | Web | Served by the host itself (`pinomad link`) and by the relay; any modern browser |
59
- | macOS (Apple silicon) | Signed DMG from [GitHub Releases](https://github.com/bubbleptr/pinomad/releases); updates itself |
60
- | iOS | Internal TestFlight only for now |
61
- | Linux, Windows | Use the web client |
62
-
63
- ## What the agent can do
64
-
65
- The agent has pi's four tools (read, bash, edit, write) plus:
66
-
67
- | Feature | What it does |
68
- |---|---|
69
- | Projects and worktrees | Register a directory as a project. In a Git repo each conversation works in its own worktree and branch, so your checkout stays untouched |
70
- | Forks | Branch off from a message and keep both lines going |
71
- | Subagents | Hand self-contained tasks to subagents that run in parallel |
72
- | Named agents | Reusable roles in `<data dir>/agents/<name>.md` — a `subagent` call or an `@name` mention delegates to one, optionally pinning its model and thinking level |
73
- | Questions, not approvals | Tools run without approval prompts; when the direction is unclear, the agent asks 1–4 multiple-choice questions |
74
- | codemode | The model writes JavaScript that calls other tools in a QuickJS sandbox; only the script's output enters the context |
75
- | MCP | Servers configured in `~/.agents/mcp.json`, in the usual `mcpServers` format |
76
- | Images | Paste, drop, or pick up to 4 images per message in the Web/desktop composer — resized to JPEG before sending |
77
- | AGENTS.md and skills | Reads `AGENTS.md` / `CLAUDE.md` and skills from `~/.agents` and the project, on every request; a `$name` mention sends that skill's full text with the message |
78
-
79
- Details and the MCP config reference: [Usage](docs/usage.md).
27
+ Sign in to a model provider under Settings → Providers: a subscription you already pay for (Claude, ChatGPT, Copilot, …), an API key, or your own OpenAI- or Anthropic-compatible endpoint. To click around without one, `pinomad host --faux "hi"` runs a scripted fake model.
80
28
 
81
29
  ## Documentation
82
30
 
83
- These docs are written in Chinese.
31
+ User docs live on **[pinomad.si/docs](https://pinomad.si/docs/)**: [getting started](https://pinomad.si/docs/) (connecting your other devices, keeping the host running, clients) and [what the agent can do](https://pinomad.si/docs/features/). Usage, remote access, and the service reference are in Chinese for now: [中文文档](https://pinomad.si/zh/docs/).
32
+
33
+ For contributors (in Chinese):
84
34
 
85
35
  | Doc | Covers |
86
36
  |---|---|
87
- | [Usage](docs/usage.md) | Projects, worktrees, tools, MCP configuration |
88
- | [Remote access](docs/remote-access.md) | Pairing, tunnels, self-hosted relay (VPS or container platforms) |
89
- | [Running as a service](docs/service.md) | `service` and `upgrade` commands, platform notes |
90
- | [Website](docs/website.md) | The pinomad.si landing page and the hosted app.pinomad.si instance |
37
+ | [Website](docs/website.md) | The pinomad.si site and the hosted app.pinomad.si instance |
91
38
  | [Architecture overview](docs/architecture.md) | How the parts and languages fit together, with send/receive diagrams |
92
39
  | [Architecture decisions](docs/adr/README.md) | Why things are the way they are |
93
40
  | [Roadmap](docs/roadmap.md) | Direction and order; items live in GitHub Issues |
@@ -9,14 +9,14 @@ import {
9
9
  relayWsBase,
10
10
  verifyRelayChallenge,
11
11
  verifyRelayChallengeV2
12
- } from "./chunk-7qb9tq54.js";
12
+ } from "./chunk-khcpv54k.js";
13
13
  import {
14
14
  commandHint,
15
15
  webRoot
16
- } from "./chunk-rtwxjb90.js";
16
+ } from "./chunk-p56xf1r8.js";
17
17
  import {
18
18
  normalizeHostName
19
- } from "./chunk-znhn8af7.js";
19
+ } from "./chunk-sygeb9qb.js";
20
20
  import"./chunk-df32avw6.js";
21
21
 
22
22
  // apps/server/src/main.ts
@@ -810,7 +810,8 @@ async function handleApiRequest(request, response, ctx) {
810
810
  url: `${relayWsBase(ctx.publicOrigin)}/c/${row.hostId}`,
811
811
  hostKey: row.noisePublicKey,
812
812
  secret: result.secret,
813
- expiresAt: result.expiresAt
813
+ expiresAt: result.expiresAt,
814
+ ...result.endpointSet === undefined ? {} : { endpointSet: result.endpointSet }
814
815
  });
815
816
  return;
816
817
  case "refused":
@@ -1073,7 +1074,12 @@ async function startRelay(options) {
1073
1074
  const request = pairingRequests.get(answer.requestId);
1074
1075
  if (request === undefined || request.control !== socket)
1075
1076
  return;
1076
- request.settle(answer.t === "pairing" ? { status: "ok", secret: answer.secret, expiresAt: answer.expiresAt } : { status: "refused", reason: answer.reason });
1077
+ request.settle(answer.t === "pairing" ? {
1078
+ status: "ok",
1079
+ secret: answer.secret,
1080
+ expiresAt: answer.expiresAt,
1081
+ ...answer.endpointSet === undefined ? {} : { endpointSet: answer.endpointSet }
1082
+ } : { status: "refused", reason: answer.reason });
1077
1083
  return;
1078
1084
  }
1079
1085
  socket.close(1008, "unexpected frame");
@@ -5,9 +5,11 @@ import {
5
5
  relayHostId,
6
6
  relayWsBase,
7
7
  signRelayChallenge,
8
- signRelayChallengeV2,
8
+ signRelayChallengeV2
9
+ } from "./chunk-khcpv54k.js";
10
+ import {
9
11
  toBase64Url
10
- } from "./chunk-7qb9tq54.js";
12
+ } from "./chunk-sygeb9qb.js";
11
13
 
12
14
  // apps/host/src/cli/server-ops.ts
13
15
  import { WebSocket } from "ws";
@@ -5,11 +5,11 @@ import {
5
5
  commandHint,
6
6
  hostEntry,
7
7
  packagedVersion
8
- } from "./chunk-rtwxjb90.js";
8
+ } from "./chunk-p56xf1r8.js";
9
9
  import {
10
10
  ProtocolMismatchError,
11
11
  connectRemoteDurable
12
- } from "./chunk-sj7rnvh4.js";
12
+ } from "./chunk-a4b61tx5.js";
13
13
  import {
14
14
  DEFAULT_DATA_DIR,
15
15
  hostAddress