@artil-ai/openclaw 0.1.13 → 0.2.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
@@ -1,36 +1,10 @@
1
- # @artil-ai/openclaw
1
+ # Artil for OpenClaw
2
2
 
3
- The Artil plugin for [OpenClaw](https://openclaw.ai). The gateway hears about
4
- each new message to the agent account, including ones its team sends to its
5
- Message URL, from where it left off, and starts a turn in the agent's `artil`
6
- session for each one. The
7
- agent answers with the `artil` CLI, as the `artil` skill teaches; nothing it
8
- writes in that session is sent anywhere.
9
-
10
- ## Usage
3
+ Install the plugin, which brings the Artil CLI, then sign in as your agent:
11
4
 
12
5
  ```sh
13
- openclaw plugins install clawhub:@artil-ai/openclaw --accept-capabilities
6
+ openclaw plugins install npm:@artil-ai/openclaw
7
+ openclaw artil auth login
14
8
  ```
15
9
 
16
- `artil plugin install openclaw` installs the same plugin from npm instead, with
17
- `openclaw plugins install npm:@artil-ai/openclaw@latest --force --accept-capabilities`.
18
-
19
- The gateway runs `artil internal openclaw-channel`, so `artil` must be on its
20
- PATH, which includes `~/.local/bin`, and signed in as the agent. See
21
- [OpenClaw](https://docs.artil.ai/openclaw) in the docs.
22
-
23
- | Entry point | What it does |
24
- | ----------------------- | -------------------------------------------------------------------------------------- |
25
- | `index.ts` | Starts a turn in the `agent:<id>:artil` session for each notice, delivering no replies |
26
- | `skills/artil/SKILL.md` | The `artil` skill, copied from the repository's `skills` when packed |
27
-
28
- ## Development
29
-
30
- `bun run build` bundles `dist/index.js` and copies the skill, and `npm pack`
31
- runs it. Install the packed archive into a gateway to try it:
32
-
33
- ```sh
34
- npm pack
35
- openclaw plugins install npm-pack:./artil-ai-openclaw-*.tgz --force --accept-capabilities
36
- ```
10
+ Read more in the [Artil docs](https://docs.artil.ai/openclaw).
package/dist/index.js CHANGED
@@ -1,3 +1,6 @@
1
+ // index.ts
2
+ import { spawn as spawn2 } from "node:child_process";
3
+
1
4
  // ../../packages/channel/listen.ts
2
5
  import { spawn } from "node:child_process";
3
6
  import { createInterface } from "node:readline";
@@ -25,6 +28,23 @@ function listen({ channel, restart, deliver, stopped }) {
25
28
  };
26
29
  }
27
30
 
31
+ // ../../packages/channel/bundled-artil.ts
32
+ import { createRequire } from "node:module";
33
+ import { delimiter, dirname } from "node:path";
34
+ function bundledArtil(pluginUrl) {
35
+ try {
36
+ return dirname(createRequire(pluginUrl).resolve("artil-ai/package.json"));
37
+ } catch {
38
+ return;
39
+ }
40
+ }
41
+ function addBundledArtil(pluginUrl) {
42
+ const artil = bundledArtil(pluginUrl);
43
+ const path = process.env.PATH?.split(delimiter) ?? [];
44
+ if (artil && !path.includes(artil))
45
+ process.env.PATH = [...path, artil].join(delimiter);
46
+ }
47
+
28
48
  // index.ts
29
49
  import { resolveDefaultAgentId } from "openclaw/plugin-sdk/agent-scope-runtime";
30
50
  import { definePluginEntry } from "openclaw/plugin-sdk/plugin-entry";
@@ -34,36 +54,76 @@ var hint = [
34
54
  "Answer only through artil, never with OpenClaw's own Telegram or other channels, which are other accounts.",
35
55
  "Nobody outside reads what you write in this session."
36
56
  ].join(" ");
57
+ var retryAfter = 30000;
58
+ var artilCommand = {
59
+ name: "artil",
60
+ description: "Run the artil command the Artil plugin brings, like: openclaw artil auth login",
61
+ hasSubcommands: false
62
+ };
63
+ function runArtil(args) {
64
+ const { promise, resolve } = Promise.withResolvers();
65
+ addBundledArtil(import.meta.url);
66
+ const artil = spawn2("artil", args, { stdio: "inherit" });
67
+ artil.on("error", (error) => {
68
+ console.error(error.message);
69
+ process.exitCode = 1;
70
+ resolve();
71
+ });
72
+ artil.on("close", (code) => {
73
+ process.exitCode = code ?? 1;
74
+ resolve();
75
+ });
76
+ return promise;
77
+ }
37
78
  var openclaw_default = definePluginEntry({
38
79
  id: "artil",
39
80
  name: "Artil",
40
81
  description: "Email, SMS and Telegram for OpenClaw. Your agent gets its own Artil inbox and phone number to read and answer messages.",
41
82
  register(api) {
83
+ if (["cli-metadata", "discovery", "full"].includes(api.registrationMode)) {
84
+ api.registerCli(({ program }) => {
85
+ program.command(artilCommand.name).description(artilCommand.description).argument("[args...]").allowUnknownOption().helpOption(false).action(runArtil);
86
+ }, { descriptors: [artilCommand] });
87
+ }
42
88
  if (api.registrationMode !== "full")
43
89
  return;
44
90
  let listening;
91
+ let retrying;
92
+ function stopListening() {
93
+ clearTimeout(retrying);
94
+ listening?.();
95
+ listening = undefined;
96
+ }
97
+ addBundledArtil(import.meta.url);
45
98
  api.registerService({
46
99
  id: "artil-messages",
47
100
  start({ config, logger }) {
48
101
  const sessionKey = `agent:${resolveDefaultAgentId(config)}:artil`;
49
- listening?.();
50
- listening = listen({
51
- channel: "openclaw-channel",
52
- restart: "restart the gateway",
53
- deliver: ({ content, meta }) => void api.runtime.subagent.run({
54
- sessionKey,
55
- message: content,
56
- extraSystemPrompt: hint,
57
- deliver: false,
58
- ...meta && { idempotencyKey: meta.message_id }
59
- }).catch((error) => logger.error(`Could not hand OpenClaw a notice: ${error}`)),
60
- stopped: (problem) => logger.error(`OpenClaw no longer hears about new messages. ${problem}`)
61
- });
102
+ let reported = "";
103
+ function hear() {
104
+ listening = listen({
105
+ channel: "openclaw-channel",
106
+ restart: "restart the gateway",
107
+ deliver: ({ content, meta }) => void api.runtime.subagent.run({
108
+ sessionKey,
109
+ message: content,
110
+ extraSystemPrompt: hint,
111
+ deliver: false,
112
+ ...meta && { idempotencyKey: meta.message_id }
113
+ }).catch((error) => logger.error(`Could not hand OpenClaw a notice: ${error}`)),
114
+ stopped: (problem) => {
115
+ if (problem !== reported) {
116
+ logger.error(`OpenClaw does not hear about new messages and tries again every 30 seconds. ${problem}`);
117
+ }
118
+ reported = problem;
119
+ retrying = setTimeout(hear, retryAfter);
120
+ }
121
+ });
122
+ }
123
+ stopListening();
124
+ hear();
62
125
  },
63
- stop() {
64
- listening?.();
65
- listening = undefined;
66
- }
126
+ stop: stopListening
67
127
  });
68
128
  }
69
129
  });
@@ -5,5 +5,12 @@
5
5
  "categories": ["channels"],
6
6
  "activation": { "onStartup": true },
7
7
  "skills": ["./skills"],
8
- "configSchema": { "type": "object", "additionalProperties": false, "properties": {} }
8
+ "configSchema": { "type": "object", "additionalProperties": false, "properties": {} },
9
+ "cliCommands": [
10
+ {
11
+ "name": "artil",
12
+ "description": "Run the artil command the Artil plugin brings, like: openclaw artil auth login",
13
+ "hasSubcommands": false
14
+ }
15
+ ]
9
16
  }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@artil-ai/openclaw",
3
- "version": "0.1.13",
3
+ "version": "0.2.0",
4
4
  "description": "Email, SMS and Telegram for OpenClaw. Your agent gets its own Artil inbox and phone number to read and answer messages.",
5
5
  "keywords": [
6
6
  "ai-agents",
@@ -35,6 +35,9 @@
35
35
  "build": "bun build index.ts --outdir dist --target node --external openclaw && rm -rf skills && cp -R ../../skills skills",
36
36
  "prepack": "bun run build"
37
37
  },
38
+ "dependencies": {
39
+ "artil-ai": "0.23.1"
40
+ },
38
41
  "devDependencies": {
39
42
  "@artil-ai/channel": "workspace:*",
40
43
  "openclaw": "2026.9.8"