@cotal-ai/pi 0.11.1

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.
@@ -0,0 +1 @@
1
+ {"version":3,"file":"standalone.js","sourceRoot":"","sources":["../src/standalone.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,OAAO,EAAE,MAAM,gBAAgB,CAAC"}
@@ -0,0 +1,5 @@
1
+ import { type MeshAgent, type AgentConfig } from "@cotal-ai/connector-core";
2
+ import type { ExtensionAPI } from "@earendil-works/pi-coding-agent";
3
+ /** Register the full cotal_* tool set on a pi session, wired to one mesh agent. */
4
+ export declare function registerCotalTools(pi: ExtensionAPI, mesh: MeshAgent, config: AgentConfig): void;
5
+ //# sourceMappingURL=tools.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"tools.d.ts","sourceRoot":"","sources":["../src/tools.ts"],"names":[],"mappings":"AAgBA,OAAO,EAAkB,KAAK,SAAS,EAAE,KAAK,WAAW,EAAE,MAAM,0BAA0B,CAAC;AAC5F,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,iCAAiC,CAAC;AAoEpE,mFAAmF;AACnF,wBAAgB,kBAAkB,CAAC,EAAE,EAAE,YAAY,EAAE,IAAI,EAAE,SAAS,EAAE,MAAM,EAAE,WAAW,GAAG,IAAI,CA+B/F"}
package/dist/tools.js ADDED
@@ -0,0 +1,113 @@
1
+ /**
2
+ * The Cotal tool surface for pi, rendered from the **shared** {@link cotalToolSpecs} (the
3
+ * same source the Claude Code MCP and OpenCode connectors render) via `pi.registerTool`.
4
+ * One source of truth → the cotal_* surface can't drift across adapters: a pi peer gets
5
+ * the same tools (send/dm/anycast, roster, channels, status, spawn where capable).
6
+ *
7
+ * The one pi-specific tool is `cotal_inbox`: this connector DRIVES delivery (the loop
8
+ * surfaces each batch into a turn and acks on completion), so the agent's inbox tool is
9
+ * READ-ONLY — it peeks (never drains), or it would race the loop's ack.
10
+ *
11
+ * Schemas: the shared spec carries a Zod raw shape; pi's `registerTool` takes a TypeBox
12
+ * TSchema. TypeBox schemas are plain JSON Schema, so we render Zod → JSON Schema (Zod 4's
13
+ * `toJSONSchema`, the same path the Hermes connector uses) and brand it with `Type.Unsafe`.
14
+ */
15
+ import { z } from "zod";
16
+ import { isConcreteChannel } from "@cotal-ai/core";
17
+ import { cotalToolSpecs } from "@cotal-ai/connector-core";
18
+ import { Type } from "typebox";
19
+ const READONLY_INBOX_DESCRIPTION = "Show the peer messages currently waiting for you (incl. focus-mode recall). You don't normally " +
20
+ "need this — the connector delivers peer messages into your turns automatically; use it to " +
21
+ "re-check what's pending mid-task. Read-only: it never consumes them.";
22
+ /** Mesh etiquette, appended to the system prompt while the send tools are active. The first
23
+ * line is load-bearing: with loop-owned delivery removed, plain chat output goes nowhere —
24
+ * a reply EXISTS only if the model sends it through a tool. */
25
+ const SEND_GUIDELINES = [
26
+ "Peer messages from the Cotal mesh arrive as user messages tagged 📨. Your chat output is NOT " +
27
+ "delivered to peers — when a reply is warranted, send it with cotal_dm (back to that peer), " +
28
+ "cotal_send (to a channel), or cotal_anycast (to a role).",
29
+ "Reply only when a reply is actually needed — a silent acknowledgement is correct; " +
30
+ '"agreed/thanks/good point" messages are noise. And @-mention a peer only when you need THAT ' +
31
+ "specific peer to act: a mention wakes them, so mentioning in acknowledgements or sign-offs " +
32
+ "makes peers ping-pong wake-ups in an endless loop.",
33
+ ];
34
+ function toParameters(schema) {
35
+ if (!schema)
36
+ return Type.Object({});
37
+ // io:"input" — the default (output) io emits `additionalProperties: false`, and pi validates
38
+ // args strictly against the schema, so a harmless stray key would fail a call that the same
39
+ // Zod shape accepts (strip mode) on the Claude Code / OpenCode paths. Input io matches those.
40
+ return Type.Unsafe(z.toJSONSchema(z.object(schema), { io: "input" }));
41
+ }
42
+ /** `<label> → <target>: <text>` for a send-tool call, so the operator SEES what the model is
43
+ * sending from inside the session (pi's default extension-tool rendering shows only the label). */
44
+ function sendCallLine(name, config, args) {
45
+ // While the call's args are still streaming in, fields may be absent — render "…" rather
46
+ // than a bogus concrete target; the settled frame paints the real one.
47
+ const text = String(args.text ?? "");
48
+ if (name === "cotal_dm")
49
+ return `cotal_dm → ${args.to ? `"${String(args.to)}"` : "…"}: ${text}`;
50
+ if (name === "cotal_anycast")
51
+ return `cotal_anycast → @${String(args.role ?? "…")}: ${text}`;
52
+ // Same default the tool itself applies (first CONCRETE channel) — subscribe[0] may be a
53
+ // wildcard like `team.>`, which the message can never actually go to. Strip a display `#`
54
+ // the model may have echoed back, as the tool's own channel normalization does.
55
+ const channel = String(args.channel ?? config.subscribe.find(isConcreteChannel) ?? "general").replace(/^#+/, "");
56
+ return `cotal_send → #${channel}: ${text}`;
57
+ }
58
+ /** Word-wrap a line to the viewport, satisfying pi-tui's structural `Component` contract
59
+ * ({ render(width): string[]; invalidate(): void }) without importing pi-tui — the published
60
+ * extension must add no runtime dependency on the host. Static text: invalidate is a no-op. */
61
+ function wrapped(line) {
62
+ return {
63
+ invalidate() { },
64
+ render(width) {
65
+ const w = Math.max(16, width);
66
+ const out = [];
67
+ let rest = line.replace(/\s+/g, " ");
68
+ while (rest.length > w) {
69
+ const cut = rest.lastIndexOf(" ", w);
70
+ const at = cut > w / 2 ? cut : w;
71
+ out.push(rest.slice(0, at));
72
+ rest = rest.slice(at).trimStart();
73
+ }
74
+ out.push(rest);
75
+ return out;
76
+ },
77
+ };
78
+ }
79
+ const SEND_TOOLS = new Set(["cotal_send", "cotal_dm", "cotal_anycast"]);
80
+ /** Register the full cotal_* tool set on a pi session, wired to one mesh agent. */
81
+ export function registerCotalTools(pi, mesh, config) {
82
+ for (const spec of cotalToolSpecs(config, "pi")) {
83
+ const readonlyInbox = spec.name === "cotal_inbox";
84
+ pi.registerTool({
85
+ name: spec.name,
86
+ label: spec.title,
87
+ description: readonlyInbox ? READONLY_INBOX_DESCRIPTION : spec.description,
88
+ parameters: readonlyInbox ? Type.Object({}) : toParameters(spec.schema),
89
+ promptGuidelines: spec.name === "cotal_send" ? SEND_GUIDELINES : undefined,
90
+ renderCall: SEND_TOOLS.has(spec.name)
91
+ ? (args) => wrapped(sendCallLine(spec.name, config, (args ?? {})))
92
+ : undefined,
93
+ async execute(_id, params) {
94
+ const args = readonlyInbox
95
+ ? { peek: true }
96
+ : { ...(params ?? {}) };
97
+ if (spec.name === "cotal_send" && typeof args.channel === "string") {
98
+ const channel = args.channel.replace(/^#+/, "");
99
+ if (!isConcreteChannel(channel)) {
100
+ return {
101
+ content: [{ type: "text", text: `⚠ ${JSON.stringify(args.channel)} is not a concrete channel` }],
102
+ details: undefined,
103
+ };
104
+ }
105
+ args.channel = channel;
106
+ }
107
+ const r = await spec.run(mesh, config, args);
108
+ return { content: [{ type: "text", text: r.isError ? `⚠ ${r.text}` : r.text }], details: undefined };
109
+ },
110
+ });
111
+ }
112
+ }
113
+ //# sourceMappingURL=tools.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"tools.js","sourceRoot":"","sources":["../src/tools.ts"],"names":[],"mappings":"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"}
package/package.json ADDED
@@ -0,0 +1,46 @@
1
+ {
2
+ "name": "@cotal-ai/pi",
3
+ "version": "0.11.1",
4
+ "license": "Apache-2.0",
5
+ "type": "module",
6
+ "main": "./dist/index.js",
7
+ "types": "./dist/index.d.ts",
8
+ "exports": {
9
+ ".": {
10
+ "types": "./dist/index.d.ts",
11
+ "import": "./dist/index.js"
12
+ },
13
+ "./extension": {
14
+ "types": "./dist/extension.d.ts",
15
+ "import": "./dist/standalone.js"
16
+ }
17
+ },
18
+ "engines": {
19
+ "node": ">=20"
20
+ },
21
+ "dependencies": {
22
+ "typebox": "^1.1.0",
23
+ "zod": "^4.4.3",
24
+ "@cotal-ai/connector-core": "0.11.2"
25
+ },
26
+ "peerDependencies": {
27
+ "@cotal-ai/core": "0.11.2"
28
+ },
29
+ "devDependencies": {
30
+ "@earendil-works/pi-ai": "0.79.10",
31
+ "@earendil-works/pi-coding-agent": "0.79.10",
32
+ "esbuild": "^0.28.0",
33
+ "@cotal-ai/core": "0.11.2"
34
+ },
35
+ "files": [
36
+ "dist"
37
+ ],
38
+ "publishConfig": {
39
+ "access": "public"
40
+ },
41
+ "scripts": {
42
+ "typecheck": "tsc -p tsconfig.json --noEmit",
43
+ "build": "tsc -p tsconfig.json && esbuild src/standalone.ts --bundle --platform=node --format=esm --target=node20 --outfile=dist/standalone.js --external:@earendil-works/pi-coding-agent --external:@earendil-works/pi-tui --banner:js=\"import { createRequire as __cotalCreateRequire } from 'node:module'; const require = __cotalCreateRequire(import.meta.url);\"",
44
+ "test": "pnpm run build && tsx pi.smoke.ts && tsx pi-sdk.smoke.ts && node --input-type=module -e \"await import('./dist/standalone.js'); console.log('pi standalone smoke: import passed')\""
45
+ }
46
+ }