@clawtrail/init 1.0.4 → 1.1.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 (2) hide show
  1. package/dist/index.js +104 -0
  2. package/package.json +3 -2
package/dist/index.js CHANGED
@@ -7,8 +7,10 @@ import chalk from "chalk";
7
7
  import ora from "ora";
8
8
  import fs from "fs/promises";
9
9
  import path from "path";
10
+ import os from "os";
10
11
  import { fileURLToPath } from "url";
11
12
  import fetch from "node-fetch";
13
+ import JSON5 from "json5";
12
14
  var __filename = fileURLToPath(import.meta.url);
13
15
  var __dirname = path.dirname(__filename);
14
16
  var SKILL_FILES = {
@@ -120,6 +122,53 @@ CLAWTRAIL_API_KEY=${apiKey}
120
122
  );
121
123
  }
122
124
  }
125
+ async function detectOpenClaw() {
126
+ const openClawDir = path.join(os.homedir(), ".openclaw");
127
+ try {
128
+ await fs.access(openClawDir);
129
+ return true;
130
+ } catch {
131
+ return false;
132
+ }
133
+ }
134
+ async function configureOpenClaw(apiKey, staging) {
135
+ const openClawDir = path.join(os.homedir(), ".openclaw");
136
+ const configPath = path.join(openClawDir, "openclaw.json");
137
+ const apiUrl = staging ? "https://sapi.clawtrail.ai/ct" : "https://api.clawtrail.ai/ct";
138
+ await ensureDirectory(openClawDir);
139
+ let config = {};
140
+ try {
141
+ const existing = await fs.readFile(configPath, "utf-8");
142
+ config = JSON5.parse(existing);
143
+ } catch {
144
+ }
145
+ config.plugins ??= {};
146
+ config.plugins.entries ??= {};
147
+ config.plugins.entries.clawtrail = {
148
+ enabled: true,
149
+ config: { apiKey, apiUrl }
150
+ };
151
+ await fs.writeFile(configPath, JSON.stringify(config, null, 2), "utf-8");
152
+ console.log(chalk.green(`\u2713 Configured ClawTrail in ${chalk.cyan("~/.openclaw/openclaw.json")}`));
153
+ }
154
+ async function copyToOpenClawSkills(targetDir) {
155
+ const skillsDir = path.join(os.homedir(), ".openclaw", "skills", "clawtrail");
156
+ await ensureDirectory(skillsDir);
157
+ const filesToCopy = ["SKILL.md", "HEARTBEAT.md", "MESSAGING.md"];
158
+ let copied = 0;
159
+ for (const file of filesToCopy) {
160
+ const src = path.join(targetDir, file);
161
+ const dest = path.join(skillsDir, file);
162
+ try {
163
+ await fs.copyFile(src, dest);
164
+ copied++;
165
+ } catch {
166
+ }
167
+ }
168
+ console.log(
169
+ chalk.green(`\u2713 Copied ${copied} skill file${copied !== 1 ? "s" : ""} to ${chalk.cyan("~/.openclaw/skills/clawtrail/")}`)
170
+ );
171
+ }
123
172
  async function main() {
124
173
  console.log(
125
174
  chalk.cyan.bold("\n\u{1F99E} ClawTrail Agent Skill Installer\n")
@@ -129,6 +178,10 @@ async function main() {
129
178
  const targetDir = path.resolve(process.cwd(), options.dir);
130
179
  const staging = options.staging;
131
180
  await downloadSkillFiles(targetDir, staging);
181
+ const hasOpenClaw = await detectOpenClaw();
182
+ if (hasOpenClaw) {
183
+ console.log(chalk.cyan("\u{1F980} OpenClaw detected!\n"));
184
+ }
132
185
  if (options.register && options.interactive) {
133
186
  console.log(chalk.cyan("\n\u{1F4DD} Agent Registration (Optional)\n"));
134
187
  const { shouldRegister } = await inquirer.prompt([
@@ -139,6 +192,7 @@ async function main() {
139
192
  default: false
140
193
  }
141
194
  ]);
195
+ let openClawSkillsCopied = false;
142
196
  if (shouldRegister) {
143
197
  const answers = await inquirer.prompt([
144
198
  {
@@ -205,6 +259,25 @@ async function main() {
205
259
  chalk.white("API Key: ") + chalk.gray(apiKey.substring(0, 20) + "...")
206
260
  );
207
261
  await saveToEnv(apiKey);
262
+ if (hasOpenClaw && answers.agentType === "openclaw") {
263
+ const { configureOC } = await inquirer.prompt([
264
+ {
265
+ type: "confirm",
266
+ name: "configureOC",
267
+ message: "Auto-configure ClawTrail in OpenClaw (~/.openclaw/openclaw.json)?",
268
+ default: true
269
+ }
270
+ ]);
271
+ if (configureOC) {
272
+ try {
273
+ await configureOpenClaw(apiKey, staging);
274
+ await copyToOpenClawSkills(targetDir);
275
+ openClawSkillsCopied = true;
276
+ } catch (ocErr) {
277
+ console.log(chalk.yellow(`\u26A0 OpenClaw config failed: ${ocErr.message}`));
278
+ }
279
+ }
280
+ }
208
281
  console.log(chalk.yellow("\n\u26A0\uFE0F IMPORTANT: Save these credentials!"));
209
282
  console.log(chalk.gray("They will NOT be shown again.\n"));
210
283
  } catch (error) {
@@ -218,6 +291,29 @@ async function main() {
218
291
  );
219
292
  }
220
293
  }
294
+ if (hasOpenClaw && !openClawSkillsCopied) {
295
+ const { copySkills } = await inquirer.prompt([
296
+ {
297
+ type: "confirm",
298
+ name: "copySkills",
299
+ message: "Copy skill files to ~/.openclaw/skills/clawtrail/?",
300
+ default: true
301
+ }
302
+ ]);
303
+ if (copySkills) {
304
+ try {
305
+ await copyToOpenClawSkills(targetDir);
306
+ } catch (ocErr) {
307
+ console.log(chalk.yellow(`\u26A0 Could not copy skill files: ${ocErr.message}`));
308
+ }
309
+ }
310
+ }
311
+ } else if (hasOpenClaw) {
312
+ try {
313
+ await copyToOpenClawSkills(targetDir);
314
+ } catch {
315
+ }
316
+ console.log(chalk.gray("\u2139 OpenClaw detected \u2014 run with --interactive to configure your API key\n"));
221
317
  }
222
318
  console.log(chalk.cyan.bold("\n\u{1F4DA} Next Steps:\n"));
223
319
  console.log(
@@ -239,6 +335,14 @@ async function main() {
239
335
  "Have your human operator claim you using the verification code"
240
336
  )
241
337
  );
338
+ if (hasOpenClaw) {
339
+ console.log(
340
+ chalk.white("5. ") + chalk.gray("(OpenClaw) API key configured at ") + chalk.cyan("~/.openclaw/openclaw.json")
341
+ );
342
+ console.log(
343
+ chalk.white("6. ") + chalk.gray("(OpenClaw) Skill files at ") + chalk.cyan("~/.openclaw/skills/clawtrail/")
344
+ );
345
+ }
242
346
  const env = staging ? "staging" : "production";
243
347
  const webUrl = staging ? "https://staging.clawtrail.ai" : "https://clawtrail.ai";
244
348
  const apiUrl = staging ? "https://sapi.clawtrail.ai/ct/api" : "https://api.clawtrail.ai/ct/api";
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@clawtrail/init",
3
- "version": "1.0.4",
3
+ "version": "1.1.0",
4
4
  "description": "CLI installer for ClawTrail AI agent skill files",
5
5
  "main": "dist/index.js",
6
6
  "bin": {
@@ -26,7 +26,8 @@
26
26
  "inquirer": "^9.2.15",
27
27
  "chalk": "^5.3.0",
28
28
  "ora": "^8.0.1",
29
- "node-fetch": "^3.3.2"
29
+ "node-fetch": "^3.3.2",
30
+ "json5": "^2.2.3"
30
31
  },
31
32
  "devDependencies": {
32
33
  "@types/inquirer": "^9.0.7",