@artil-ai/pi 0.1.1 → 0.1.2

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
@@ -14,15 +14,17 @@ Interactive and RPC sessions run `artil internal pi-channel`, so `artil` must be
14
14
  on the PATH and signed in as the agent. See [Pi](https://docs.artil.dev/pi) in
15
15
  the docs.
16
16
 
17
- | Entry point | What it does |
18
- | ------------------------ | ----------------------------------------------------------------------- |
19
- | `extensions/messages.ts` | Hands each new message to the session as a follow-up that starts a turn |
20
- | `skills/artil/SKILL.md` | The `artil` skill; the CLI installs the same text for its other clients |
17
+ | Entry point | What it does |
18
+ | ----------------------- | ----------------------------------------------------------------------- |
19
+ | `index.ts` | Hands each new message to the session as a follow-up that starts a turn |
20
+ | `skills/artil/SKILL.md` | The `artil` skill, copied from the repository's `skills` when packed |
21
21
 
22
22
  ## Development
23
23
 
24
- Try the package without installing it, from the repository root:
24
+ `bun run build` bundles `dist/index.js` and copies the skill. Try the package
25
+ without installing it, from the repository root:
25
26
 
26
27
  ```sh
27
- pi -e ./pi
28
+ bun run build
29
+ pi -e ./plugins/pi
28
30
  ```
package/dist/index.js ADDED
@@ -0,0 +1,53 @@
1
+ // ../../packages/channel/listen.ts
2
+ import { spawn } from "node:child_process";
3
+ import { createInterface } from "node:readline";
4
+ function listen({ channel, restart, deliver, stopped }) {
5
+ const artil = spawn("artil", ["internal", channel]);
6
+ let problem = "";
7
+ let stopping = false;
8
+ artil.on("error", (error) => {
9
+ problem = error.code === "ENOENT" ? `The artil command is not on the PATH. Install it with curl -fsSL https://artil.dev/install.sh | bash, or add ~/.local/bin to the PATH, then ${restart}.` : error.message;
10
+ });
11
+ artil.stderr.on("data", (chunk) => {
12
+ problem += chunk.toString();
13
+ });
14
+ artil.on("close", () => {
15
+ if (!stopping)
16
+ stopped(problem.trim());
17
+ });
18
+ createInterface({ input: artil.stdout }).on("line", (line) => {
19
+ deliver(JSON.parse(line));
20
+ });
21
+ return function stop() {
22
+ stopping = true;
23
+ artil.stdin.end();
24
+ setTimeout(() => artil.kill(), 5000).unref();
25
+ };
26
+ }
27
+
28
+ // index.ts
29
+ function hearNewMessages(pi) {
30
+ let listening;
31
+ pi.on("session_start", (_event, ctx) => {
32
+ if (!ctx.hasUI)
33
+ return;
34
+ const stop = listen({
35
+ channel: "pi-channel",
36
+ restart: "run /reload",
37
+ deliver: ({ content, meta = {} }) => {
38
+ if (listening !== stop)
39
+ return;
40
+ pi.sendMessage({ customType: "artil-messages", content, display: true, details: meta }, { deliverAs: "followUp", triggerTurn: true });
41
+ },
42
+ stopped: (problem) => ctx.ui.notify(`Pi no longer hears about new messages. ${problem}`, "error")
43
+ });
44
+ listening = stop;
45
+ });
46
+ pi.on("session_shutdown", () => {
47
+ listening?.();
48
+ listening = undefined;
49
+ });
50
+ }
51
+ export {
52
+ hearNewMessages as default
53
+ };
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@artil-ai/pi",
3
- "version": "0.1.1",
3
+ "version": "0.1.2",
4
4
  "description": "Hear about your Artil agent's new messages in Pi, and answer them with the artil CLI.",
5
5
  "keywords": [
6
6
  "artil",
@@ -11,17 +11,22 @@
11
11
  "repository": {
12
12
  "type": "git",
13
13
  "url": "git+https://github.com/artilai/plugins.git",
14
- "directory": "pi"
14
+ "directory": "plugins/pi"
15
15
  },
16
16
  "files": [
17
- "extensions/messages.ts",
17
+ "dist",
18
18
  "skills"
19
19
  ],
20
20
  "type": "module",
21
21
  "publishConfig": {
22
22
  "access": "public"
23
23
  },
24
+ "scripts": {
25
+ "build": "bun build index.ts --outdir dist --target node --external @earendil-works/pi-coding-agent && rm -rf skills && cp -R ../../skills skills",
26
+ "prepack": "bun run build"
27
+ },
24
28
  "devDependencies": {
29
+ "@artil-ai/channel": "workspace:*",
25
30
  "@earendil-works/pi-coding-agent": "1.0.4"
26
31
  },
27
32
  "peerDependencies": {
@@ -34,7 +39,7 @@
34
39
  },
35
40
  "pi": {
36
41
  "extensions": [
37
- "./extensions/messages.ts"
42
+ "./dist/index.js"
38
43
  ],
39
44
  "skills": [
40
45
  "./skills"
@@ -1,66 +0,0 @@
1
- import { spawn } from "node:child_process";
2
- import { createInterface } from "node:readline";
3
-
4
- import type { ExtensionAPI } from "@earendil-works/pi-coding-agent";
5
-
6
- type Notice = { readonly content: string; readonly meta?: Readonly<Record<string, string>> };
7
-
8
- type ListenForMessagesOptions = {
9
- readonly artil: string;
10
- readonly deliver: (notice: Notice) => void;
11
- readonly stopped: (problem: string) => void;
12
- };
13
-
14
- const missing =
15
- "The artil command is not on the PATH. Install it with curl -fsSL https://artil.dev/install.sh | bash, or add ~/.local/bin to the PATH, then run /reload.";
16
-
17
- export function listenForMessages({ artil, deliver, stopped }: ListenForMessagesOptions) {
18
- const listening = spawn(artil, ["internal", "pi-channel"]);
19
- let problem = "";
20
- let stopping = false;
21
-
22
- listening.on("error", (error: NodeJS.ErrnoException) => {
23
- problem = error.code === "ENOENT" ? missing : error.message;
24
- });
25
- listening.stderr.on("data", (chunk: Buffer) => {
26
- problem += chunk.toString();
27
- });
28
- listening.on("close", () => {
29
- if (!stopping) stopped(problem.trim());
30
- });
31
- createInterface({ input: listening.stdout }).on("line", (line) => {
32
- if (stopping) return;
33
-
34
- // SAFETY: artil internal pi-channel prints each notice as one JSON object per line.
35
- deliver(JSON.parse(line) as Notice);
36
- });
37
-
38
- return function stop() {
39
- stopping = true;
40
- listening.kill();
41
- };
42
- }
43
-
44
- export default function hearNewMessages(pi: ExtensionAPI) {
45
- let stop: (() => void) | undefined;
46
-
47
- pi.on("session_start", (_event, ctx) => {
48
- if (!ctx.hasUI) return;
49
-
50
- stop = listenForMessages({
51
- artil: "artil",
52
- deliver: ({ content, meta = {} }) =>
53
- pi.sendMessage(
54
- { customType: "artil-messages", content, display: true, details: meta },
55
- { deliverAs: "followUp", triggerTurn: true },
56
- ),
57
- stopped: (problem) =>
58
- ctx.ui.notify(`Pi no longer hears about new messages. ${problem}`, "error"),
59
- });
60
- });
61
-
62
- pi.on("session_shutdown", () => {
63
- stop?.();
64
- stop = undefined;
65
- });
66
- }