@mcsherrylabs/pi-meerkat 0.5.0 → 0.7.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.
Files changed (51) hide show
  1. package/README.md +182 -48
  2. package/dist/announce.d.ts +2 -1
  3. package/dist/announce.d.ts.map +1 -1
  4. package/dist/announce.js +25 -2
  5. package/dist/announce.js.map +1 -1
  6. package/dist/config.d.ts +34 -0
  7. package/dist/config.d.ts.map +1 -0
  8. package/dist/config.js +97 -0
  9. package/dist/config.js.map +1 -0
  10. package/dist/mcp-announce.d.ts +42 -0
  11. package/dist/mcp-announce.d.ts.map +1 -0
  12. package/dist/mcp-announce.js +231 -0
  13. package/dist/mcp-announce.js.map +1 -0
  14. package/dist/mcp-cli.d.ts +3 -0
  15. package/dist/mcp-cli.d.ts.map +1 -0
  16. package/dist/mcp-cli.js +111 -0
  17. package/dist/mcp-cli.js.map +1 -0
  18. package/dist/mcp-config.d.ts +28 -0
  19. package/dist/mcp-config.d.ts.map +1 -0
  20. package/dist/mcp-config.js +104 -0
  21. package/dist/mcp-config.js.map +1 -0
  22. package/dist/mcp-facade.d.ts +20 -0
  23. package/dist/mcp-facade.d.ts.map +1 -0
  24. package/dist/mcp-facade.js +200 -0
  25. package/dist/mcp-facade.js.map +1 -0
  26. package/dist/mcp-upstream.d.ts +42 -0
  27. package/dist/mcp-upstream.d.ts.map +1 -0
  28. package/dist/mcp-upstream.js +151 -0
  29. package/dist/mcp-upstream.js.map +1 -0
  30. package/dist/registry.d.ts +2 -2
  31. package/dist/registry.d.ts.map +1 -1
  32. package/dist/registry.js +4 -2
  33. package/dist/registry.js.map +1 -1
  34. package/dist/target.d.ts +25 -0
  35. package/dist/target.d.ts.map +1 -0
  36. package/dist/target.js +84 -0
  37. package/dist/target.js.map +1 -0
  38. package/dist/tools.d.ts +7 -3
  39. package/dist/tools.d.ts.map +1 -1
  40. package/dist/tools.js +124 -120
  41. package/dist/tools.js.map +1 -1
  42. package/extensions/meerkat.ts +7 -5
  43. package/package.json +15 -7
  44. package/dist/subscription-infra.d.ts +0 -15
  45. package/dist/subscription-infra.d.ts.map +0 -1
  46. package/dist/subscription-infra.js +0 -74
  47. package/dist/subscription-infra.js.map +0 -1
  48. package/dist/subscription-tools.d.ts +0 -29
  49. package/dist/subscription-tools.d.ts.map +0 -1
  50. package/dist/subscription-tools.js +0 -77
  51. package/dist/subscription-tools.js.map +0 -1
package/README.md CHANGED
@@ -1,69 +1,203 @@
1
1
  # @mcsherrylabs/pi-meerkat
2
2
 
3
- Pi agent tools for the meerkat announcements registry: **announce a channel you control**, and
4
- search what others have announced.
3
+ Meerkat registry tools and a **stdio MCP facade**. One client registration exposes the seven
4
+ Meerkat tools plus every tool dynamically discovered from the private
5
+ `@mcsherrylabs/evolver-mcp@0.15.0` child. The released upstream baseline is 65 tools, so healthy
6
+ discovery currently returns 72. The count is a comparison baseline, not a routing allowlist.
5
7
 
6
- ```
7
- pi-meerkat ──▶ @mcsherrylabs/pi-evolver ──▶ @mcsherrylabs/evolver-client
8
- the service's verbs chain + content, generic the wire
8
+ **Version 0.7.0 introduces this facade.** Version 0.6.0 is the previous Pi/local-signing package
9
+ and does **not** contain it. Use the explicit version below, not an unversioned `npx` command or
10
+ an assumption about npm `latest`. Source/packed acceptance, publication, and verification of an
11
+ installed published release are separate milestones.
12
+
13
+ ## Install from npm
14
+
15
+ Run this in the same environment where Claude Code (or another MCP client) runs. Node 22 is
16
+ the verified runtime. Installation downloads the package and its exact released dependency;
17
+ it does not provision or start a node:
18
+
19
+ ```bash
20
+ npm install --prefix "$HOME/.local/share/meerkat-mcp/0.7.0" \
21
+ --no-audit --no-fund @mcsherrylabs/pi-meerkat@0.7.0
22
+ export PATH="$HOME/.local/share/meerkat-mcp/0.7.0/node_modules/.bin:$PATH"
9
23
  ```
10
24
 
11
- ## Why this is a separate package
25
+ The installed facade resolves and launches its actual dependency's `evolver-mcp` bin
26
+ (`dist/cli.js`). It does not use a sibling source checkout, global executable, or unversioned
27
+ runtime download. Installation under the home directory persists across rig recreation.
12
28
 
13
- `pi-evolver` forbids a tool from naming a channel, a ledger or a service, and fails its build
14
- for it — a draft of its content tool was rejected for the word "announcement". That rule is what
15
- keeps it chain-generic, and it is also what says where a service's own verbs belong: **here**, in
16
- the service's own repository, installed by whoever wants them. A new service becomes usable by an
17
- agent with nothing central edited.
29
+ ## Configure an existing node once
18
30
 
19
- ## Tools
31
+ Setup records **references**, not key bytes. Select an existing node endpoint, separate content
32
+ endpoint, identity, existing key file, registry read origin, explicit genesis/chain ID and node ID,
33
+ registry channel, and TLS policy. This command does not provision a node, claim an identity,
34
+ create/copy a key, initialize a registry database, or change a client registration automatically.
20
35
 
21
- | tool | what it answers |
22
- |---|---|
23
- | `meerkat_summary` | start here — counts, kinds, keywords, misses, and **which channel** this registry indexes |
24
- | `meerkat_services` | search by keyword or free text |
25
- | `meerkat_service` | one entry in full, with its `provenance` |
26
- | `meerkat_detail` | the announced document, digest-verified by the registry |
27
- | `meerkat_rejections` | why an announcement was refused |
28
- | `meerkat_announce` | describe a channel you control, optionally with a document |
29
- | `meerkat_inbox` | what arrived on a channel this node subscribes to and no handler claimed — the event inbox |
36
+ Set the following shell inputs to values you already operate. Do not copy a guessed identity,
37
+ chain ID, key, or endpoint from a model or from registry content. `MEERKAT_TLS_INSECURE=false`
38
+ keeps certificate verification enabled; an explicitly chosen private CA may be supplied with
39
+ `--ca-file /absolute/operator-ca.pem`.
30
40
 
31
- ## Three things that are deliberate
41
+ <!-- meerkat-setup:start -->
42
+ ```bash
43
+ meerkat-mcp setup \
44
+ --config "${MEERKAT_CONFIG:?Choose an absolute operator-owned config path}" \
45
+ --node-url "${MEERKAT_NODE_URL:?Select the existing node origin}" \
46
+ --content-url "${MEERKAT_CONTENT_URL:?Select its separate content origin}" \
47
+ --identity "${MEERKAT_IDENTITY:?Select the existing signing identity}" \
48
+ --key-path "${MEERKAT_KEY_PATH:?Select the existing absolute key reference}" \
49
+ --key-type "${MEERKAT_KEY_TYPE:?Select ed25519 or bls}" \
50
+ --tls-insecure "${MEERKAT_TLS_INSECURE:?Explicitly choose true or false}" \
51
+ --meerkat-url "${MEERKAT_READ_URL:?Select the registry processor read origin}" \
52
+ --chain-id "${MEERKAT_CHAIN_ID:?Supply the existing 64-hex chain ID}" \
53
+ --node-id "${MEERKAT_NODE_ID:?Supply the existing inbox-binding node ID}" \
54
+ --channel "${MEERKAT_CHANNEL:?Select the registry announcement channel}"
55
+ ```
56
+ <!-- meerkat-setup:end -->
32
57
 
33
- **The document is published before the announcement, inside the tool.** An announcement names its
34
- document by key and digest. Announce first and the entry refers to bytes that exist nowhere —
35
- permanently `unfetchable`, indistinguishable from a document that is merely slow, and *every*
36
- detail document on this estate was in that state until it was found. Two composable tools would
37
- put that ordering in a model's hands. `meerkat_announce` takes the text.
58
+ Create the config's parent directory beforehand. Setup exclusively creates an operator-owned
59
+ mode-0600 file and refuses to overwrite an existing one. Treat that file and all parent paths as
60
+ trusted launch configuration; do not let a project or another user replace them. Setup checks
61
+ that the key reference exists but **only the child reads signing-key bytes**. Key bytes do not
62
+ enter the setup output, facade, or registration.
38
63
 
39
- **The document is published OPEN.** Anyone who obtains the key may read it. That is right for a
40
- public index, and with the announcements channel no longer carrying a DA group there is no group
41
- left to grant to. Do not announce anything whose disclosure depends on a key staying private.
64
+ Setup emits one JSON `mcpServers` entry, with the installed facade's absolute command and
65
+ `--config` pointing to the saved file. Add **that one Meerkat entry** to your MCP client's
66
+ configuration. No manual environment ceremony, separate Evolver registration, HTTP MCP service,
67
+ Pi adapter, or separately managed child is required. Direct launch uses the same entrypoint:
42
68
 
43
- **The channel is configuration, not a parameter.** `REGISTRY_CHANNEL` — the same variable the
44
- registry reads, so the two cannot disagree. A model with a free-text channel field will
45
- eventually fill it from something it read, and an announcement is charged and permanent.
69
+ ```bash
70
+ meerkat-mcp --config "$MEERKAT_CONFIG"
71
+ ```
46
72
 
47
- ## Configuration
73
+ ### Register in Claude Code
48
74
 
49
- | variable | what |
50
- |---|---|
51
- | `MEERKAT_URL` | the event processor's read server — the registry's routes and the inbox — e.g. `http://registry:8090`. `REGISTRY_URL`, its name before 0.3.0, is refused: every read answers `misconfigured` until it is renamed |
52
- | `REGISTRY_CHANNEL` | the channel to announce onto and read (default `ce.meerkat.announcements`) |
53
- | `EVOLVER_URL`, `EVOLVER_IDENTITY`, `EVOLVER_KEY_PATH` | from pi-evolver — who signs |
54
- | `EVOLVER_CONTENT_URL` | from pi-evolver — required only to announce a document |
75
+ From the environment where Claude Code runs, register the installed facade with the same
76
+ absolute config path used for setup:
77
+
78
+ ```bash
79
+ claude mcp add --scope user --transport stdio meerkat -- \
80
+ "$(command -v node)" \
81
+ "$HOME/.local/share/meerkat-mcp/0.7.0/node_modules/@mcsherrylabs/pi-meerkat/dist/mcp-cli.js" \
82
+ --config "$MEERKAT_CONFIG"
83
+ ```
55
84
 
56
- The read tools need no chain at all: an agent with no signing key can still search the index.
85
+ `--scope user` makes this operator registration available across your projects. Use
86
+ `--scope local` instead to restrict the initial test to the current project. Start a fresh
87
+ Claude Code session and run `/mcp` to inspect the connection and its tools. Do not register the
88
+ private Evolver child separately. Begin with `meerkat_summary`, a small `meerkat_services`
89
+ query, `meerkat_inbox`, and the upstream read-only `evolver_chain_height`; do not approve
90
+ announcement/sign/submit calls until you deliberately choose to exercise a write.
91
+
92
+ The stdio connection uses stdout exclusively for MCP messages. Diagnostics go to stderr. The
93
+ operator-selected node/content/trust/identity/key/channel inputs are captured at facade startup;
94
+ model arguments and project configuration cannot select signing authority. Within one client,
95
+ forwarded Evolver tools and `meerkat_announce` deliberately share the owned upstream session and
96
+ signing history. Independent clients each get a distinct child/session/store. There are **two
97
+ server OS processes**, privately owned by the single registration. Close the client connection
98
+ or stop the facade to await its child and transport cleanup.
99
+
100
+ ## Degraded discovery and independent reads
101
+
102
+ Initialization and local reads do not require a signing key or a working upstream child.
103
+ Without `--config`, registry read inputs retain `MEERKAT_URL`, `EVOLVER_CHAIN_ID` and
104
+ `APP_NODE_ID`; these are the only inputs needed for bound inbox reads. With `--config`, the
105
+ saved operator values bind those reads. `REGISTRY_URL` remains a refused obsolete name.
106
+
107
+ A bounded failed upstream discovery returns the **seven local definitions** with explicit
108
+ upstream-unavailable/degraded metadata and a stderr diagnostic. All six read tools remain
109
+ usable, including both inbox summary and paginated page routes. Announce and upstream-dependent
110
+ calls refuse clearly. Failed refresh invalidates stale upstream routing; a later successful
111
+ catalog discovery can restore healthy routing but never resumes or replays an interrupted write.
112
+ There is no hidden-name workaround or eighth status tool.
57
113
 
58
- ## The contract lives here
114
+ ## Tools
59
115
 
60
- `src/contract.ts` is the announcement wire format — bounds, types and the body builder. It is in
61
- this package rather than in the app so a client can announce without depending on the whole
62
- registry, and so there is one encoding rather than two. Pure: no chain, no clock, no I/O.
116
+ | Tool | Purpose |
117
+ |---|---|
118
+ | `meerkat_summary` | Start here: counts, kinds, keywords, misses, indexed channel and progress |
119
+ | `meerkat_services` | Search announced services by keyword or free text |
120
+ | `meerkat_service` | Read one service, including provenance |
121
+ | `meerkat_detail` | Read the document already digest-verified by the registry |
122
+ | `meerkat_rejections` | Learn why an ordered announcement was not indexed |
123
+ | `meerkat_inbox` | Read the inbox summary, or a bounded page with `round:index` continuation |
124
+ | `meerkat_announce` | Describe a channel you control, optionally with an open document |
125
+
126
+ The original seven names, descriptions and input schemas are preserved against published 0.6.0.
127
+ Upstream descriptions/schemas/results are forwarded unchanged. A newly discovered tool routes
128
+ without an adapter. Colliding names and unknown/undiscovered calls refuse rather than shadowing.
129
+ This is a tools facade, not a generic prompts/resources proxy. Supported cancellation is passed
130
+ through; cancellation is not rollback. Supported upstream tool-list changes refresh the catalog.
131
+
132
+ Registry strings are **untrusted data**, never instructions or signing configuration. Read errors
133
+ are not empty answers: not-found, unreachable, unavailable and truncated remain distinct. Inbox
134
+ binding validates the configured chain and node; previews remain at most 256 decoded bytes per
135
+ entry, with at most 50 entries and 12,800 preview bytes per page. Carry the returned `next` as
136
+ `after` yourself; the facade does not advance a processor cursor.
137
+
138
+ ## Announcement semantics
139
+
140
+ The registry channel is **trusted configuration**, not a tool parameter. The facade uses the
141
+ existing unsigned `announcementBody` encoder, with its field order, bounds, UTF-8 bytes and
142
+ 4,096-byte body cap. Sequence is epoch seconds; lease expiry uses a read-only chain-round
143
+ preflight in the same session, defaulting to 20,000 rounds, never wall-clock as chain height.
144
+
145
+ The owned sequence is:
146
+
147
+ 1. `evolver_chain_height` (read-only preflight).
148
+ 2. If nonempty detail text is supplied, await `evolver_content_put` with `access=open`; validate
149
+ the real acknowledgement and original UTF-8 size/SHA-256 before embedding its reference.
150
+ 3. `evolver_sign_channel_write` for the configured channel and exact announcement `bodyHex`.
151
+ 4. Ordinary `evolver_submit` with **only the original returned txId**.
152
+
153
+ No DA conversion/collection, auto-claim, extra mutating setup, caller-selected identity/key/TTL,
154
+ local signer, local key read or direct node submit is added. The document is published **OPEN**:
155
+ anyone with its key may read it. Upload occurs before signing; a successful upload may remain
156
+ stored after a later failure.
157
+
158
+ Only this owned orchestration decodes upstream's actual warning-suffixed JSON and submit prose;
159
+ transparent forwarded results are never reworded. Protocol success or `isError:false` does not
160
+ establish a committed announcement. Committed, fined, refused, unknown and local
161
+ already-submitted remain distinct. A fined write can charge and deliver a body; committed is
162
+ **not registry acceptance**—read the entry/rejections afterward.
163
+
164
+ Definitive local child/session loss before submit prevents that send. Once submit may have left
165
+ the transport, a lost, timed-out or unreadable reply means **UNKNOWN**, retaining the original
166
+ txId and reconciliation guidance. Read/reconcile that transaction; never automatically reconnect,
167
+ resume, re-sign, retry or replay the write. Already-submitted says this call sent nothing, not
168
+ that a previous attempt failed.
169
+
170
+ ## Existing Pi package and registry application
171
+
172
+ The retained Pi extension and useful `channel-subscription` / `service-discovery` skills are
173
+ still shipped. The legacy extension's `EVOLVER_URL`, `EVOLVER_IDENTITY`, `EVOLVER_KEY_PATH`,
174
+ `EVOLVER_CONTENT_URL` and two-file Pi config are **not** the MCP facade's authority interface.
175
+ No additional Pi host adapter is required. The root registry application, database/schema,
176
+ processor cursor and supported SDK Docker helper are unchanged. Root `npm start` starts the
177
+ registry application and does not demonstrate facade acceptance.
178
+
179
+ The announcement wire contract remains in this package (`src/contract.ts`, export `./contract`),
180
+ so clients and the registry use one encoder rather than divergent copies. MCP runtime
181
+ capability comes from the exact installed child; remaining SDK usage in the facade is unsigned
182
+ encoding/types or the existing bound `ProcessorClient` inbox reads, not local signing.
183
+
184
+ ## Verification lanes
63
185
 
64
186
  ```bash
65
- npm run check:contract # the encoding and every bound, with nothing running
66
- npm run check:surface # the tool table's properties
187
+ npm run check:pi # root: ordinary package tests, including K01–K07
188
+ npm run check:plan-two:client --workspace @mcsherrylabs/pi-meerkat
67
189
  ```
68
190
 
69
- Version 0.4.2 pins pi-evolver 0.9.0 and evolver-client 0.19.0 to share the corrected identity-key lookup. Configure the agent API endpoint to evolver-node **v0.24.1+** before using that lookup. The announcement and inbox contracts are unchanged.
191
+ Run networked gates in a disposable isolated network namespace/container, with physical
192
+ `K_REGISTRY_TEST_TMP` and temporary outputs outside the source tree. K uses a real downstream
193
+ MCP client, built and freshly packed-installed facade, real released child, fixed fixture keys,
194
+ HTTP boundary stand-ins, explicit counters/barriers, and awaited exact-owned cleanup. It makes
195
+ no live model, faucet/devnet, production database or estate changes. `PLAN_TWO_REPORT` selects
196
+ the acceptance report path; source CI retains this report and runs the normal package chain.
197
+
198
+ An npm pack is **not publication**. Publication needs an unused version, synchronized locks,
199
+ an immutable `pi-meerkat-vX.Y.Z` tag at the accepted revision and successful exact-SHA required
200
+ CI/publish jobs. Published-release verification additionally retrieves anonymous metadata and
201
+ tarballs/integrity and exercises the installed published facade/dependency with independent
202
+ clients in isolation. Served/downloaded instruction hashes and transcripts belong to that
203
+ post-publication lane. Pending publication or delivery gates must not be represented as passes.
@@ -1,5 +1,6 @@
1
1
  import type { SubmitResult } from "@mcsherrylabs/evolver-client";
2
- import type { ChainTarget, ToolResult } from "@mcsherrylabs/pi-evolver";
2
+ import type { ToolResult } from "@mcsherrylabs/evolver-core";
3
+ import type { ChainTarget } from "./target.js";
3
4
  import type { DetailRef } from "./contract.js";
4
5
  /** How many rounds an entry stays live unless re-announced. Rounds, never wall-clock: devnet
5
6
  * commits on a ~600 ms floor when busy and a 300-second idle heartbeat when quiescent, so the
@@ -1 +1 @@
1
- {"version":3,"file":"announce.d.ts","sourceRoot":"","sources":["../src/announce.ts"],"names":[],"mappings":"AAWA,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,8BAA8B,CAAC;AAEjE,OAAO,KAAK,EAAE,WAAW,EAAE,UAAU,EAAE,MAAM,0BAA0B,CAAC;AAExE,OAAO,KAAK,EAAiB,SAAS,EAAE,MAAM,eAAe,CAAC;AAE9D;;iFAEiF;AACjF,eAAO,MAAM,oBAAoB,QAAS,CAAC;AAE3C,MAAM,WAAW,eAAe;IAC9B,QAAQ,CAAC,OAAO,EAAE,MAAM,CAAC;IACzB,QAAQ,CAAC,QAAQ,EAAE,MAAM,CAAC;IAC1B,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAC;IACtB,QAAQ,CAAC,KAAK,EAAE,MAAM,CAAC;IACvB,QAAQ,CAAC,OAAO,EAAE,MAAM,CAAC;IACzB,QAAQ,CAAC,QAAQ,EAAE,SAAS,MAAM,EAAE,CAAC;IACrC,2FAA2F;IAC3F,QAAQ,CAAC,UAAU,CAAC,EAAE,MAAM,CAAC;IAC7B,QAAQ,CAAC,WAAW,CAAC,EAAE,MAAM,CAAC;CAC/B;AAED,MAAM,WAAW,SAAS;IACxB,QAAQ,CAAC,OAAO,EAAE,MAAM,CAAC;IACzB,QAAQ,CAAC,QAAQ,EAAE,MAAM,CAAC;IAC1B,QAAQ,CAAC,GAAG,EAAE,MAAM,CAAC;IACrB,QAAQ,CAAC,cAAc,EAAE,MAAM,CAAC;IAChC,QAAQ,CAAC,MAAM,EAAE,SAAS,GAAG,IAAI,CAAC;IAClC,QAAQ,CAAC,MAAM,EAAE,YAAY,CAAC;CAC/B;AAED;;;;;;;;;;;;;;;GAeG;AACH,wBAAsB,QAAQ,CAC5B,MAAM,EAAE,WAAW,EACnB,GAAG,EAAE,eAAe,GACnB,OAAO,CAAC,UAAU,CAAC,SAAS,CAAC,CAAC,CAgEhC"}
1
+ {"version":3,"file":"announce.d.ts","sourceRoot":"","sources":["../src/announce.ts"],"names":[],"mappings":"AAWA,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,8BAA8B,CAAC;AAGjE,OAAO,KAAK,EAAe,UAAU,EAAE,MAAM,4BAA4B,CAAC;AAC1E,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,aAAa,CAAC;AAE/C,OAAO,KAAK,EAAiB,SAAS,EAAE,MAAM,eAAe,CAAC;AAE9D;;iFAEiF;AACjF,eAAO,MAAM,oBAAoB,QAAS,CAAC;AAuB3C,MAAM,WAAW,eAAe;IAC9B,QAAQ,CAAC,OAAO,EAAE,MAAM,CAAC;IACzB,QAAQ,CAAC,QAAQ,EAAE,MAAM,CAAC;IAC1B,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAC;IACtB,QAAQ,CAAC,KAAK,EAAE,MAAM,CAAC;IACvB,QAAQ,CAAC,OAAO,EAAE,MAAM,CAAC;IACzB,QAAQ,CAAC,QAAQ,EAAE,SAAS,MAAM,EAAE,CAAC;IACrC,2FAA2F;IAC3F,QAAQ,CAAC,UAAU,CAAC,EAAE,MAAM,CAAC;IAC7B,QAAQ,CAAC,WAAW,CAAC,EAAE,MAAM,CAAC;CAC/B;AAED,MAAM,WAAW,SAAS;IACxB,QAAQ,CAAC,OAAO,EAAE,MAAM,CAAC;IACzB,QAAQ,CAAC,QAAQ,EAAE,MAAM,CAAC;IAC1B,QAAQ,CAAC,GAAG,EAAE,MAAM,CAAC;IACrB,QAAQ,CAAC,cAAc,EAAE,MAAM,CAAC;IAChC,QAAQ,CAAC,MAAM,EAAE,SAAS,GAAG,IAAI,CAAC;IAClC,QAAQ,CAAC,MAAM,EAAE,YAAY,CAAC;CAC/B;AAED;;;;;;;;;;;;;;;GAeG;AACH,wBAAsB,QAAQ,CAC5B,MAAM,EAAE,WAAW,EACnB,GAAG,EAAE,eAAe,GACnB,OAAO,CAAC,UAAU,CAAC,SAAS,CAAC,CAAC,CAkEhC"}
package/dist/announce.js CHANGED
@@ -8,12 +8,32 @@
8
8
  // gets it wrong produces a plausible-looking entry that can never be repaired except by
9
9
  // announcing again. So the sequence is not offered as a choice.
10
10
  import { buildSignedTx, channelBody } from "@mcsherrylabs/evolver-client";
11
- import { publishBytes } from "@mcsherrylabs/pi-evolver";
11
+ import { NodeClient } from "@mcsherrylabs/evolver-client";
12
+ import { misconfigured, publishBytes } from "@mcsherrylabs/evolver-core";
12
13
  import { announcementBody, announcementProblems } from "./contract.js";
13
14
  /** How many rounds an entry stays live unless re-announced. Rounds, never wall-clock: devnet
14
15
  * commits on a ~600 ms floor when busy and a 300-second idle heartbeat when quiescent, so the
15
16
  * same number of rounds is a wildly different amount of time in each regime. */
16
17
  export const DEFAULT_LEASE_ROUNDS = 20_000;
18
+ const CONTENT_MISSING_FIX = "Set EVOLVER_CONTENT_URL to the node's own content listener (`ce.evolver.content.http-port`, " +
19
+ "e.g. http://node:8450 inside a compose network), or put `contentUrl` in the home-level " +
20
+ ".pi/agent/evolver.json. It is deliberately NOT derived from the chain URL — content is a " +
21
+ "separate listener on a separate port — and a project-level file may not set it.";
22
+ /** The content deps for a target, or a refusal naming what to set. Core's `publishBytes` takes
23
+ * `ContentDeps` (client + contentUrl) rather than the whole target, and builds the client against
24
+ * the SEPARATE content listener; that wiring is pi-meerkat's to provide here. */
25
+ function contentDeps(target) {
26
+ const contentUrl = target.config.contentUrl;
27
+ if (!contentUrl)
28
+ return { ok: false, error: CONTENT_MISSING_FIX };
29
+ return {
30
+ ok: true,
31
+ deps: {
32
+ contentUrl,
33
+ client: new NodeClient({ baseUrl: contentUrl, contentBaseUrl: contentUrl }),
34
+ },
35
+ };
36
+ }
17
37
  /**
18
38
  * Announce one channel onto the registry's channel, as this agent's identity.
19
39
  *
@@ -35,7 +55,10 @@ export async function announce(target, req) {
35
55
  // recoverable direction: an announcement referring to nothing is not.
36
56
  let detail;
37
57
  if (req.detailText !== undefined && req.detailText.length > 0) {
38
- const published = await publishBytes(target, new TextEncoder().encode(req.detailText));
58
+ const d = contentDeps(target);
59
+ if (!d.ok)
60
+ return misconfigured("a content endpoint for publishing the document", d.error);
61
+ const published = await publishBytes(d.deps, { access: "open", text: req.detailText });
39
62
  if (published.kind !== "ok")
40
63
  return published;
41
64
  detail = { key: published.value.key, sha256: published.value.sha256, bytes: published.value.size };
@@ -1 +1 @@
1
- {"version":3,"file":"announce.js","sourceRoot":"","sources":["../src/announce.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"announce.js","sourceRoot":"","sources":["../src/announce.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,34 @@
1
+ import { DEFAULT_URL, isLocal } from "@mcsherrylabs/evolver-core";
2
+ import type { TlsOptions } from "@mcsherrylabs/evolver-core";
3
+ export { DEFAULT_URL, isLocal };
4
+ export type { TlsOptions };
5
+ /** Where the signing key is, and which key an identity signs with. A faucet-claimed identity
6
+ * holds more than one, so this is not inferable. */
7
+ export interface KeyLocation {
8
+ readonly path: string;
9
+ readonly keyType: "ed25519" | "bls";
10
+ }
11
+ export interface EvolverConfig {
12
+ readonly url: string;
13
+ /** The node's LOOPBACK CONTENT listener — `POST /content`, `GET /content/<key>`. A separate port,
14
+ * not derivable from `url`, and NOT project-overridable (publishing is bytes the agent chose). */
15
+ readonly contentUrl?: string;
16
+ readonly identity: string;
17
+ readonly keyLocation: KeyLocation;
18
+ readonly tls?: TlsOptions;
19
+ }
20
+ export type ConfigResult = {
21
+ readonly ok: true;
22
+ readonly config: EvolverConfig;
23
+ } | {
24
+ readonly ok: false;
25
+ readonly error: string;
26
+ };
27
+ /**
28
+ * Combine a project-level and a home-level configuration under the asymmetric precedence rule.
29
+ * Pure: no filesystem, no environment. `loadConfig` does the reading and calls this.
30
+ */
31
+ export declare function mergeConfig(project: unknown, home: unknown, env?: Record<string, unknown>): ConfigResult;
32
+ /** Read both files and apply the rule. The only part that touches a filesystem. */
33
+ export declare function loadConfig(cwd?: string, env?: NodeJS.ProcessEnv): ConfigResult;
34
+ //# sourceMappingURL=config.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"config.d.ts","sourceRoot":"","sources":["../src/config.ts"],"names":[],"mappings":"AAoBA,OAAO,EAAE,WAAW,EAAE,OAAO,EAAE,MAAM,4BAA4B,CAAC;AAClE,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,4BAA4B,CAAC;AAE7D,OAAO,EAAE,WAAW,EAAE,OAAO,EAAE,CAAC;AAChC,YAAY,EAAE,UAAU,EAAE,CAAC;AAE3B;qDACqD;AACrD,MAAM,WAAW,WAAW;IAC1B,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAC;IACtB,QAAQ,CAAC,OAAO,EAAE,SAAS,GAAG,KAAK,CAAC;CACrC;AAED,MAAM,WAAW,aAAa;IAC5B,QAAQ,CAAC,GAAG,EAAE,MAAM,CAAC;IACrB;uGACmG;IACnG,QAAQ,CAAC,UAAU,CAAC,EAAE,MAAM,CAAC;IAC7B,QAAQ,CAAC,QAAQ,EAAE,MAAM,CAAC;IAC1B,QAAQ,CAAC,WAAW,EAAE,WAAW,CAAC;IAClC,QAAQ,CAAC,GAAG,CAAC,EAAE,UAAU,CAAC;CAC3B;AAED,MAAM,MAAM,YAAY,GACpB;IAAE,QAAQ,CAAC,EAAE,EAAE,IAAI,CAAC;IAAC,QAAQ,CAAC,MAAM,EAAE,aAAa,CAAA;CAAE,GACrD;IAAE,QAAQ,CAAC,EAAE,EAAE,KAAK,CAAC;IAAC,QAAQ,CAAC,KAAK,EAAE,MAAM,CAAA;CAAE,CAAC;AASnD;;;GAGG;AACH,wBAAgB,WAAW,CAAC,OAAO,EAAE,OAAO,EAAE,IAAI,EAAE,OAAO,EAAE,GAAG,GAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAM,GAAG,YAAY,CAqC5G;AAsBD,mFAAmF;AACnF,wBAAgB,UAAU,CAAC,GAAG,GAAE,MAAsB,EAAE,GAAG,GAAE,MAAM,CAAC,UAAwB,GAAG,YAAY,CAM1G"}
package/dist/config.js ADDED
@@ -0,0 +1,97 @@
1
+ // Configuration: the two-file project/home precedence that governs who signs, and where content
2
+ // goes.
3
+ //
4
+ // ⚠️ THIS IS pi-meerkat'S OWN RULE, NOT core's. `@mcsherrylabs/evolver-core`'s config.ts is a
5
+ // different rule on purpose: it serves a spawned-per-session stdio server, so it reads ONE explicit
6
+ // file, forbids `keyLocation`/`contentUrl` outright (FORBIDDEN_KEYS), and loads the signing key
7
+ // from the ENVIRONMENT only. pi-meerkat is a long-lived extension that must honour a project-level
8
+ // `.pi/agent/evolver.json` next to a home-level one, and whose keyLocation and contentUrl legitimately
9
+ // live in the home file. Core's `resolveConfig` would REJECT exactly the record this package needs,
10
+ // so the precedence is kept here as a local wrapper; the shared compile-time pieces (`DEFAULT_URL`,
11
+ // `isLocal`, the `TlsOptions` shape) are imported from core so they cannot drift.
12
+ //
13
+ // The precedence is NOT uniform, and that is the point. A project file may override the chain URL
14
+ // and NOTHING ELSE. The identity, the key and how the endpoint is trusted come from home or the
15
+ // environment only — a repository you open ships its own file, and if that file could name an
16
+ // identity or a key path, opening a repository would change which key signs.
17
+ import { homedir } from "node:os";
18
+ import { existsSync, readFileSync } from "node:fs";
19
+ import { join } from "node:path";
20
+ import { DEFAULT_URL, isLocal } from "@mcsherrylabs/evolver-core";
21
+ export { DEFAULT_URL, isLocal };
22
+ /** The ONLY field a project-level file may contribute. A list, not a spread, so adding a field
23
+ * to `EvolverConfig` does not silently widen what a project can set. */
24
+ const PROJECT_OVERRIDABLE = ["url"];
25
+ const asRecord = (v) => typeof v === "object" && v !== null ? v : undefined;
26
+ /**
27
+ * Combine a project-level and a home-level configuration under the asymmetric precedence rule.
28
+ * Pure: no filesystem, no environment. `loadConfig` does the reading and calls this.
29
+ */
30
+ export function mergeConfig(project, home, env = {}) {
31
+ const p = asRecord(project);
32
+ const h = { ...(asRecord(home) ?? {}), ...env }; // the environment outranks the home FILE
33
+ const hasHome = asRecord(home) !== undefined || Object.keys(env).length > 0;
34
+ if (!hasHome && !p)
35
+ return { ok: false, error: "no evolver configuration found (looked for a project .pi/agent/evolver.json, a home-level one, and EVOLVER_* in the environment)" };
36
+ const merged = { ...h };
37
+ if (p)
38
+ for (const field of PROJECT_OVERRIDABLE) {
39
+ if (p[field] !== undefined)
40
+ merged[field] = p[field];
41
+ }
42
+ const identity = merged["identity"];
43
+ if (typeof identity !== "string" || identity.length === 0)
44
+ return { ok: false, error: "configuration has no `identity` — nothing could sign with it (a project file cannot supply one)" };
45
+ const keyLocation = asRecord(merged["keyLocation"]);
46
+ if (!keyLocation || typeof keyLocation["path"] !== "string")
47
+ return { ok: false, error: "configuration has no `keyLocation` — nothing could sign with it (a project file cannot supply one)" };
48
+ const keyType = keyLocation["keyType"];
49
+ if (keyType !== "ed25519" && keyType !== "bls")
50
+ return { ok: false, error: "`keyLocation.keyType` must be \"ed25519\" or \"bls\" — an identity holds more than one key, so this is not inferable" };
51
+ const url = typeof merged["url"] === "string" && merged["url"].length > 0 ? merged["url"] : DEFAULT_URL;
52
+ const contentUrl = typeof merged["contentUrl"] === "string" && merged["contentUrl"].length > 0
53
+ ? merged["contentUrl"] : undefined;
54
+ return {
55
+ ok: true,
56
+ config: {
57
+ url,
58
+ ...(contentUrl ? { contentUrl } : {}),
59
+ identity,
60
+ keyLocation: { path: keyLocation["path"], keyType },
61
+ tls: asRecord(merged["tls"]),
62
+ },
63
+ };
64
+ }
65
+ /** Environment overrides for the fields a project file may NOT set. */
66
+ function fromEnv(env) {
67
+ const out = {};
68
+ if (env["EVOLVER_URL"])
69
+ out["url"] = env["EVOLVER_URL"];
70
+ if (env["EVOLVER_CONTENT_URL"])
71
+ out["contentUrl"] = env["EVOLVER_CONTENT_URL"];
72
+ if (env["EVOLVER_IDENTITY"])
73
+ out["identity"] = env["EVOLVER_IDENTITY"];
74
+ if (env["EVOLVER_KEY_PATH"])
75
+ out["keyLocation"] = {
76
+ path: env["EVOLVER_KEY_PATH"],
77
+ keyType: env["EVOLVER_KEY_TYPE"] === "bls" ? "bls" : "ed25519",
78
+ };
79
+ if (env["EVOLVER_TLS_INSECURE"] === "1")
80
+ out["tls"] = { insecure: true };
81
+ return out;
82
+ }
83
+ const readJson = (file) => {
84
+ if (!existsSync(file))
85
+ return undefined;
86
+ try {
87
+ return JSON.parse(readFileSync(file, "utf8"));
88
+ }
89
+ catch {
90
+ return undefined;
91
+ }
92
+ };
93
+ /** Read both files and apply the rule. The only part that touches a filesystem. */
94
+ export function loadConfig(cwd = process.cwd(), env = process.env) {
95
+ return mergeConfig(readJson(join(cwd, ".pi", "agent", "evolver.json")), readJson(join(homedir(), ".pi", "agent", "evolver.json")), fromEnv(env));
96
+ }
97
+ //# sourceMappingURL=config.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"config.js","sourceRoot":"","sources":["../src/config.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,42 @@
1
+ import type { CallToolResult } from "@modelcontextprotocol/sdk/types.js";
2
+ import type { AnnounceRequest } from "./announce.js";
3
+ import type { DetailRef } from "./contract.js";
4
+ export interface McpAnnounceSession {
5
+ callTool(name: string, args: Record<string, unknown>, signal?: AbortSignal): Promise<CallToolResult>;
6
+ /** Definitive local session/child liveness; false must not trigger reconnect-and-resume. */
7
+ isOpen(): boolean;
8
+ }
9
+ export interface McpAnnounceOptions {
10
+ /** Trusted facade startup configuration, NOT request.channel or a model argument. */
11
+ readonly channel: string;
12
+ readonly signal?: AbortSignal;
13
+ /** Whole orchestration budget, including an optional awaited dependency hook. */
14
+ readonly timeoutMs?: number;
15
+ /** Dependency injection for an awaited pre-send barrier; never wired to environment/model data. */
16
+ readonly afterSign?: (txId: string) => Promise<void>;
17
+ }
18
+ export type McpAnnounceStage = "validation" | "preflight" | "publish" | "sign" | "before_submit" | "submit";
19
+ interface AnnouncementState {
20
+ readonly channel: string;
21
+ readonly ledgerId: string;
22
+ readonly seq?: number;
23
+ readonly expiresAtRound?: string;
24
+ readonly detail: DetailRef | null;
25
+ /** An unread/invalid publication acknowledgement does not prove storage was rolled back. */
26
+ readonly upload: "not_attempted" | "acknowledged" | "unknown";
27
+ readonly stage: McpAnnounceStage;
28
+ readonly message: string;
29
+ readonly reason?: string;
30
+ readonly commitIntervalMs?: number;
31
+ }
32
+ export type McpAnnouncementResult = AnnouncementState & ({
33
+ readonly kind: "committed" | "fined" | "unknown" | "already_submitted";
34
+ readonly txId: string;
35
+ } | {
36
+ readonly kind: "error" | "refused";
37
+ readonly txId?: string;
38
+ });
39
+ /** One same owned session; zero local signing/key/node access; one ordinary submit of its original id. */
40
+ export declare function announceViaMcp(session: McpAnnounceSession, request: AnnounceRequest, options: McpAnnounceOptions): Promise<McpAnnouncementResult>;
41
+ export {};
42
+ //# sourceMappingURL=mcp-announce.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"mcp-announce.d.ts","sourceRoot":"","sources":["../src/mcp-announce.ts"],"names":[],"mappings":"AAGA,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,oCAAoC,CAAC;AACzE,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,eAAe,CAAC;AAErD,OAAO,KAAK,EAAiB,SAAS,EAAE,MAAM,eAAe,CAAC;AAE9D,MAAM,WAAW,kBAAkB;IACjC,QAAQ,CAAC,IAAI,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,EAAE,MAAM,CAAC,EAAE,WAAW,GAAG,OAAO,CAAC,cAAc,CAAC,CAAC;IACrG,4FAA4F;IAC5F,MAAM,IAAI,OAAO,CAAC;CACnB;AACD,MAAM,WAAW,kBAAkB;IACjC,qFAAqF;IACrF,QAAQ,CAAC,OAAO,EAAE,MAAM,CAAC;IACzB,QAAQ,CAAC,MAAM,CAAC,EAAE,WAAW,CAAC;IAC9B,iFAAiF;IACjF,QAAQ,CAAC,SAAS,CAAC,EAAE,MAAM,CAAC;IAC5B,mGAAmG;IACnG,QAAQ,CAAC,SAAS,CAAC,EAAE,CAAC,IAAI,EAAE,MAAM,KAAK,OAAO,CAAC,IAAI,CAAC,CAAC;CACtD;AACD,MAAM,MAAM,gBAAgB,GAAG,YAAY,GAAG,WAAW,GAAG,SAAS,GAAG,MAAM,GAAG,eAAe,GAAG,QAAQ,CAAC;AAC5G,UAAU,iBAAiB;IACzB,QAAQ,CAAC,OAAO,EAAE,MAAM,CAAC;IACzB,QAAQ,CAAC,QAAQ,EAAE,MAAM,CAAC;IAC1B,QAAQ,CAAC,GAAG,CAAC,EAAE,MAAM,CAAC;IACtB,QAAQ,CAAC,cAAc,CAAC,EAAE,MAAM,CAAC;IACjC,QAAQ,CAAC,MAAM,EAAE,SAAS,GAAG,IAAI,CAAC;IAClC,4FAA4F;IAC5F,QAAQ,CAAC,MAAM,EAAE,eAAe,GAAG,cAAc,GAAG,SAAS,CAAC;IAC9D,QAAQ,CAAC,KAAK,EAAE,gBAAgB,CAAC;IACjC,QAAQ,CAAC,OAAO,EAAE,MAAM,CAAC;IACzB,QAAQ,CAAC,MAAM,CAAC,EAAE,MAAM,CAAC;IACzB,QAAQ,CAAC,gBAAgB,CAAC,EAAE,MAAM,CAAC;CACpC;AACD,MAAM,MAAM,qBAAqB,GAAG,iBAAiB,GAAG,CACpD;IAAE,QAAQ,CAAC,IAAI,EAAE,WAAW,GAAG,OAAO,GAAG,SAAS,GAAG,mBAAmB,CAAC;IAAC,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAA;CAAE,GACjG;IAAE,QAAQ,CAAC,IAAI,EAAE,OAAO,GAAG,SAAS,CAAC;IAAC,QAAQ,CAAC,IAAI,CAAC,EAAE,MAAM,CAAA;CAAE,CACjE,CAAC;AAkHF,0GAA0G;AAC1G,wBAAsB,cAAc,CAClC,OAAO,EAAE,kBAAkB,EAC3B,OAAO,EAAE,eAAe,EACxB,OAAO,EAAE,kBAAkB,GAC1B,OAAO,CAAC,qBAAqB,CAAC,CA6FhC"}