@clawtrail/init 1.4.2 → 2.0.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 +156 -316
  2. package/package.json +1 -3
package/dist/index.js CHANGED
@@ -2,7 +2,6 @@
2
2
 
3
3
  // src/index.ts
4
4
  import { Command } from "commander";
5
- import inquirer from "inquirer";
6
5
  import chalk from "chalk";
7
6
  import ora from "ora";
8
7
  import fs from "fs/promises";
@@ -66,107 +65,36 @@ async function downloadSkillFiles(targetDir, staging = false) {
66
65
  }
67
66
  if (failed.length > 0) {
68
67
  spinner.warn(
69
- chalk.yellow(`Downloaded ${succeeded}/${downloads.length} skill files to ${chalk.cyan(targetDir)} (${env}) \u2014 ${failed.join(", ")} unavailable`)
68
+ chalk.yellow(`Downloaded ${succeeded}/${downloads.length} files (${env}) \u2014 ${failed.join(", ")} unavailable`)
70
69
  );
71
70
  } else {
72
71
  spinner.succeed(
73
- chalk.green(`Downloaded ${succeeded} skill files to ${chalk.cyan(targetDir)} (${env})`)
72
+ chalk.green(`Downloaded ${succeeded} skill files (${env})`)
74
73
  );
75
74
  }
75
+ return { succeeded, failed };
76
76
  }
77
- var REGISTRATION_ERROR_HINTS = {
78
- "unable to register another agent": "IP rate limit: only 1 agent registration per IP per 24 hours. Try again tomorrow or use a different network.",
79
- "agent name already exists": "An agent with this name is already registered. Choose a different name.",
80
- "name already taken": "An agent with this name is already registered. Choose a different name.",
81
- "wallet already registered": "This wallet address is already associated with an agent."
82
- };
83
- function getRegistrationErrorHint(message) {
84
- const lower = message.toLowerCase();
85
- for (const [pattern, hint] of Object.entries(REGISTRATION_ERROR_HINTS)) {
86
- if (lower.includes(pattern)) return hint;
87
- }
88
- return void 0;
89
- }
90
- async function registerAgent(data, staging = false) {
91
- const apiUrl = staging ? "https://sapi.clawtrail.ai/ct/api" : "https://api.clawtrail.ai/ct/api";
92
- const spinner = ora("Registering agent with ClawTrail...").start();
93
- try {
94
- const response = await fetch(`${apiUrl}/agents/register`, {
95
- method: "POST",
96
- headers: {
97
- "Content-Type": "application/json"
98
- },
99
- body: JSON.stringify(data)
100
- });
101
- if (!response.ok) {
102
- const error = await response.json();
103
- const rawMessage = error.error || "Registration failed";
104
- const hint = getRegistrationErrorHint(rawMessage);
105
- throw new Error(hint || rawMessage);
106
- }
107
- const result = await response.json();
108
- spinner.succeed(chalk.green("Agent registered successfully!"));
109
- return {
110
- agentId: result.agentId,
111
- apiKey: result.apiKey,
112
- verificationCode: result.verificationCode,
113
- statusUrl: result.statusUrl
114
- };
115
- } catch (error) {
116
- spinner.fail(chalk.red(`Registration failed: ${error.message}`));
117
- throw error;
118
- }
119
- }
120
- async function checkExistingApiKey() {
77
+ async function copyToOpenClawDirs(targetDir, staging) {
78
+ const skillFolder = staging ? "clawtrail-staging" : "clawtrail";
79
+ const openclawDir = path.join(os.homedir(), ".openclaw");
80
+ const placed = [];
81
+ const workspaceDir = path.join(openclawDir, "workspace");
82
+ await ensureDirectory(workspaceDir);
121
83
  try {
122
- const envPath = path.join(process.cwd(), ".env");
123
- const content = await fs.readFile(envPath, "utf-8");
124
- return content.includes("CLAWTRAIL_API_KEY=");
84
+ await fs.copyFile(path.join(targetDir, "HEARTBEAT.md"), path.join(workspaceDir, "HEARTBEAT.md"));
85
+ placed.push("~/.openclaw/workspace/HEARTBEAT.md");
125
86
  } catch {
126
- return false;
127
87
  }
128
- }
129
- async function saveToEnv(apiKey) {
130
- const envPath = path.join(process.cwd(), ".env");
131
- const envContent = `
132
- # ClawTrail API Key
133
- CLAWTRAIL_API_KEY=${apiKey}
134
- `;
135
- try {
136
- let existingContent = "";
137
- try {
138
- existingContent = await fs.readFile(envPath, "utf-8");
139
- } catch {
140
- }
141
- if (existingContent.includes("CLAWTRAIL_API_KEY")) {
142
- console.log(
143
- chalk.yellow(
144
- " .env already contains CLAWTRAIL_API_KEY, not overwriting"
145
- )
146
- );
147
- return;
148
- }
149
- await fs.appendFile(envPath, envContent);
150
- console.log(chalk.green(` Saved API key to ${chalk.cyan(".env")}`));
151
- } catch (error) {
152
- console.log(
153
- chalk.yellow(` Could not save to .env: ${error.message}`)
154
- );
155
- console.log(
156
- chalk.gray(" You can manually add it: CLAWTRAIL_API_KEY=<your-key>")
157
- );
158
- }
159
- }
160
- async function detectOpenClaw() {
161
- const openClawDir = path.join(os.homedir(), ".openclaw");
88
+ const skillsDir = path.join(openclawDir, "skills", skillFolder);
89
+ await ensureDirectory(skillsDir);
162
90
  try {
163
- await fs.access(openClawDir);
164
- return true;
91
+ await fs.copyFile(path.join(targetDir, "SKILL.md"), path.join(skillsDir, "SKILL.md"));
92
+ placed.push(`~/.openclaw/skills/${skillFolder}/SKILL.md`);
165
93
  } catch {
166
- return false;
167
94
  }
95
+ return placed;
168
96
  }
169
- async function configureOpenClaw(apiKey, staging) {
97
+ async function configureOpenClaw(staging, apiKey) {
170
98
  const openClawDir = path.join(os.homedir(), ".openclaw");
171
99
  const configPath = path.join(openClawDir, "openclaw.json");
172
100
  const apiUrl = staging ? "https://sapi.clawtrail.ai/ct" : "https://api.clawtrail.ai/ct";
@@ -176,269 +104,181 @@ async function configureOpenClaw(apiKey, staging) {
176
104
  const existing = await fs.readFile(configPath, "utf-8");
177
105
  config = JSON5.parse(existing);
178
106
  } catch (err) {
179
- if (err.code === "ENOENT") {
180
- } else {
181
- console.log(
182
- chalk.yellow(` Could not parse existing openclaw.json \u2014 backing up and starting fresh`)
183
- );
107
+ if (err.code !== "ENOENT") {
184
108
  try {
185
109
  await fs.copyFile(configPath, configPath + ".bak");
186
- console.log(chalk.gray(` Backup saved to ${configPath}.bak`));
187
110
  } catch {
188
111
  }
189
112
  }
190
113
  }
191
- config.plugins ??= {};
192
- config.plugins.entries ??= {};
193
- config.plugins.entries.clawtrail = {
194
- enabled: true,
195
- config: {
196
- apiKey,
197
- apiUrl
198
- }
114
+ config.agents ??= {};
115
+ config.agents.defaults ??= {};
116
+ config.agents.defaults.heartbeat = {
117
+ every: "30s",
118
+ target: "last"
199
119
  };
120
+ config.skills ??= {};
121
+ config.skills.entries ??= {};
122
+ config.skills.entries.clawtrail ??= {};
123
+ config.skills.entries.clawtrail.enabled = true;
124
+ config.skills.entries.clawtrail.env ??= {};
125
+ config.skills.entries.clawtrail.env.CLAWTRAIL_API_URL = apiUrl;
126
+ if (apiKey) {
127
+ config.skills.entries.clawtrail.env.CLAWTRAIL_API_KEY = apiKey;
128
+ }
200
129
  await fs.writeFile(configPath, JSON.stringify(config, null, 2), "utf-8");
201
- console.log(chalk.green(` Configured ClawTrail in ${chalk.cyan("~/.openclaw/openclaw.json")}`));
130
+ return {
131
+ configPath: "~/.openclaw/openclaw.json",
132
+ heartbeat: "every 30s",
133
+ hasApiKey: !!apiKey
134
+ };
202
135
  }
203
- async function copyToOpenClawSkills(targetDir, staging) {
204
- const skillFolder = staging ? "clawtrail-staging" : "clawtrail";
205
- const openclawDir = path.join(os.homedir(), ".openclaw");
206
- const workspaceDir = path.join(openclawDir, "workspace");
207
- await ensureDirectory(workspaceDir);
136
+ async function registerAgent(name, description, staging, opts = {}) {
137
+ const apiUrl = staging ? "https://sapi.clawtrail.ai/ct/api" : "https://api.clawtrail.ai/ct/api";
138
+ const spinner = ora("Registering agent...").start();
208
139
  try {
209
- await fs.copyFile(path.join(targetDir, "HEARTBEAT.md"), path.join(workspaceDir, "HEARTBEAT.md"));
210
- console.log(chalk.green(" HEARTBEAT.md -> ") + chalk.cyan("~/.openclaw/workspace/HEARTBEAT.md"));
211
- } catch {
140
+ const response = await fetch(`${apiUrl}/agents/register`, {
141
+ method: "POST",
142
+ headers: { "Content-Type": "application/json" },
143
+ body: JSON.stringify({
144
+ name,
145
+ description,
146
+ bio: opts.bio || void 0,
147
+ agentType: opts.agentType || "openclaw",
148
+ framework: opts.framework || void 0,
149
+ skills: opts.skills?.length ? opts.skills : void 0,
150
+ capabilities: opts.capabilities?.length ? opts.capabilities : ["general"]
151
+ })
152
+ });
153
+ if (!response.ok) {
154
+ const error = await response.json();
155
+ throw new Error(error.error || "Registration failed");
156
+ }
157
+ const result = await response.json();
158
+ spinner.succeed(chalk.green("Agent registered"));
159
+ return {
160
+ agentId: result.agentId,
161
+ apiKey: result.apiKey,
162
+ verificationCode: result.verificationCode,
163
+ statusUrl: result.statusUrl
164
+ };
165
+ } catch (error) {
166
+ spinner.fail(chalk.red(`Registration failed: ${error.message}`));
167
+ throw error;
212
168
  }
213
- const skillsDir = path.join(openclawDir, "skills", skillFolder);
214
- await ensureDirectory(skillsDir);
169
+ }
170
+ async function detectOpenClaw() {
215
171
  try {
216
- await fs.copyFile(path.join(targetDir, "SKILL.md"), path.join(skillsDir, "SKILL.md"));
217
- console.log(chalk.green(" SKILL.md -> ") + chalk.cyan(`~/.openclaw/skills/${skillFolder}/SKILL.md`));
172
+ await fs.access(path.join(os.homedir(), ".openclaw"));
173
+ return true;
218
174
  } catch {
175
+ return false;
219
176
  }
220
177
  }
221
178
  async function main() {
222
- console.log(
223
- chalk.cyan.bold("\n ClawTrail Agent Skill Installer\n")
224
- );
179
+ console.log(chalk.cyan.bold("\n ClawTrail Agent Installer\n"));
225
180
  const program = new Command();
226
- program.name("clawtrail-init").description("Initialize ClawTrail skill files for AI agents").version("1.4.2").option("-d, --dir <path>", "Target directory", "./clawtrail-skills").option("-s, --staging", "Use staging environment", false).option("--no-register", "Skip agent registration").option("--no-interactive", "Skip interactive prompts").action(async (options) => {
181
+ program.name("clawtrail-init").description("Install ClawTrail skill files, configure heartbeat, and optionally register an agent").version("2.0.0").option("-d, --dir <path>", "Download directory for skill files", "./clawtrail-skills").option("-s, --staging", "Use staging environment", false).option("--name <name>", "Register agent with this name").option("--description <desc>", "Agent description (required with --name)").option("--bio <bio>", "Agent bio").option("--agent-type <type>", "Agent type (openclaw, custom, mcp-server, a2a-agent)", "openclaw").option("--framework <fw>", "Agent framework (e.g., langchain, autogen)").option("--skills <skills>", "Comma-separated skills (e.g., coding,research,dkg)").option("--capabilities <caps>", "Comma-separated capabilities (e.g., research,analysis)").option("--api-key <key>", "Existing API key (skip registration, just configure)").action(async (options) => {
227
182
  const targetDir = path.resolve(process.cwd(), options.dir);
228
183
  const staging = options.staging;
184
+ const env = staging ? "staging" : "production";
229
185
  await downloadSkillFiles(targetDir, staging);
230
186
  const hasOpenClaw = await detectOpenClaw();
187
+ let placedFiles = [];
231
188
  if (hasOpenClaw) {
232
- console.log(chalk.cyan(" OpenClaw detected!\n"));
189
+ const spinner = ora("Placing files in OpenClaw directories...").start();
233
190
  try {
234
- await copyToOpenClawSkills(targetDir, staging);
235
- } catch (copyErr) {
236
- console.log(chalk.yellow(` Could not copy to OpenClaw workspace: ${copyErr.message}`));
191
+ placedFiles = await copyToOpenClawDirs(targetDir, staging);
192
+ spinner.succeed(chalk.green(`Placed ${placedFiles.length} files in OpenClaw`));
193
+ } catch (err) {
194
+ spinner.warn(chalk.yellow(`Could not place files: ${err.message}`));
237
195
  }
238
196
  }
239
- if (options.register && options.interactive) {
240
- const hasExistingKey = await checkExistingApiKey();
241
- if (hasExistingKey) {
242
- console.log(
243
- chalk.yellow("\n An existing CLAWTRAIL_API_KEY was found in .env")
244
- );
245
- const { registerAnyway } = await inquirer.prompt([
197
+ let apiKey = options.apiKey || void 0;
198
+ let agentId;
199
+ let verificationCode;
200
+ if (options.name) {
201
+ if (!options.description) {
202
+ console.log(chalk.red("\n --description is required when using --name\n"));
203
+ process.exit(1);
204
+ }
205
+ try {
206
+ const result = await registerAgent(
207
+ options.name.trim(),
208
+ options.description.trim(),
209
+ staging,
246
210
  {
247
- type: "confirm",
248
- name: "registerAnyway",
249
- message: "Register a new agent anyway? (existing key will not be overwritten)",
250
- default: false
211
+ bio: options.bio?.trim(),
212
+ agentType: options.agentType,
213
+ framework: options.framework?.trim(),
214
+ skills: options.skills?.split(",").map((s) => s.trim()).filter(Boolean),
215
+ capabilities: options.capabilities?.split(",").map((s) => s.trim()).filter(Boolean)
251
216
  }
252
- ]);
253
- if (!registerAnyway) {
254
- console.log(chalk.gray(" Skipping registration \u2014 using existing credentials.\n"));
255
- options.register = false;
256
- }
217
+ );
218
+ apiKey = result.apiKey;
219
+ agentId = result.agentId;
220
+ verificationCode = result.verificationCode;
221
+ } catch {
257
222
  }
258
223
  }
259
- if (options.register && options.interactive) {
260
- console.log(chalk.cyan("\n Agent Registration (Optional)\n"));
261
- const { registrationChoice } = await inquirer.prompt([
262
- {
263
- type: "list",
264
- name: "registrationChoice",
265
- message: "How would you like to register your agent?",
266
- choices: [
267
- { name: "Let my bot register itself (recommended for OpenClaw)", value: "bot" },
268
- { name: "Enter agent info manually now", value: "manual" },
269
- { name: "Skip registration", value: "skip" }
270
- ],
271
- default: hasOpenClaw ? "bot" : "manual"
272
- }
273
- ]);
274
- if (registrationChoice === "bot") {
275
- console.log(chalk.green("\n Got it! Your bot will register itself.\n"));
276
- console.log(chalk.gray(" Your bot can register using the SKILL.md instructions."));
277
- console.log(chalk.gray(" It will call POST /api/agents/register with its own info."));
278
- if (hasOpenClaw) {
279
- console.log(chalk.gray(" The ClawTrail skill file has been placed in your OpenClaw workspace."));
280
- console.log(chalk.gray(" Just start your bot \u2014 it will read the skill and register automatically.\n"));
281
- } else {
282
- console.log(chalk.gray(" Point your agent at the SKILL.md file to get started.\n"));
283
- }
284
- } else if (registrationChoice === "manual") {
285
- const answers = await inquirer.prompt([
286
- {
287
- type: "input",
288
- name: "name",
289
- message: "Agent name:",
290
- validate: (input) => {
291
- if (!input.trim()) return "Name is required";
292
- if (input.trim().length < 2) return "Name must be at least 2 characters";
293
- if (input.trim().length > 100) return "Name must be under 100 characters";
294
- return true;
295
- }
296
- },
297
- {
298
- type: "input",
299
- name: "description",
300
- message: "Agent description:",
301
- validate: (input) => {
302
- if (!input.trim()) return "Description is required";
303
- if (input.trim().length < 10) return "Description must be at least 10 characters";
304
- return true;
305
- }
306
- },
307
- {
308
- type: "input",
309
- name: "bio",
310
- message: "Short bio (optional):"
311
- },
312
- {
313
- type: "list",
314
- name: "agentType",
315
- message: "Agent type:",
316
- choices: [
317
- { name: "OpenClaw Agent", value: "openclaw" },
318
- { name: "Custom Agent", value: "custom" },
319
- { name: "MCP Server", value: "mcp-server" },
320
- { name: "A2A Agent", value: "a2a-agent" },
321
- { name: "ERC-8004 Agent", value: "erc8004" }
322
- ],
323
- default: hasOpenClaw ? "openclaw" : "custom"
324
- },
325
- {
326
- type: "input",
327
- name: "framework",
328
- message: "Framework (optional, e.g., langchain, autogen):"
329
- },
330
- {
331
- type: "input",
332
- name: "skills",
333
- message: "Skills (optional, comma-separated, e.g., coding,research,dkg):"
334
- },
335
- {
336
- type: "input",
337
- name: "capabilities",
338
- message: "Capabilities (optional, comma-separated, e.g., research,analysis,automation):"
339
- }
340
- ]);
224
+ let ocConfig;
225
+ if (hasOpenClaw) {
226
+ const spinner = ora("Configuring OpenClaw heartbeat...").start();
227
+ try {
228
+ ocConfig = await configureOpenClaw(staging, apiKey);
229
+ spinner.succeed(chalk.green(`Heartbeat configured: ${chalk.cyan("every 30s")}`));
230
+ } catch (err) {
231
+ spinner.warn(chalk.yellow(`Config failed: ${err.message}`));
232
+ }
233
+ }
234
+ if (apiKey) {
235
+ const envPath = path.join(process.cwd(), ".env");
236
+ try {
237
+ let existing = "";
341
238
  try {
342
- const { agentId, apiKey, verificationCode, statusUrl } = await registerAgent(
343
- {
344
- name: answers.name.trim(),
345
- description: answers.description.trim(),
346
- bio: answers.bio?.trim() || void 0,
347
- agentType: answers.agentType,
348
- framework: answers.framework?.trim() || void 0,
349
- skills: answers.skills ? answers.skills.split(",").map((s) => s.trim()).filter(Boolean) : [],
350
- capabilities: answers.capabilities ? answers.capabilities.split(",").map((s) => s.trim()).filter(Boolean) : ["general"]
351
- },
352
- staging
353
- );
354
- console.log(chalk.green("\n Registration Complete!\n"));
355
- console.log(chalk.white("Agent ID: ") + chalk.cyan(agentId));
356
- console.log(
357
- chalk.white("Verification Code: ") + chalk.yellow(verificationCode)
358
- );
359
- console.log(
360
- chalk.white("DKG Status: ") + chalk.yellow("pending \u2014 minting queued (~30s)")
361
- );
362
- console.log(
363
- chalk.white("Status URL: ") + chalk.blue.underline(statusUrl)
364
- );
365
- await saveToEnv(apiKey);
366
- console.log(chalk.yellow("\n IMPORTANT: Your API key has been saved to .env"));
367
- console.log(chalk.yellow(" The verification code above will NOT be shown again.\n"));
368
- if (hasOpenClaw && answers.agentType === "openclaw") {
369
- const { configureOC } = await inquirer.prompt([
370
- {
371
- type: "confirm",
372
- name: "configureOC",
373
- message: "Auto-configure ClawTrail in OpenClaw (~/.openclaw/openclaw.json)?",
374
- default: true
375
- }
376
- ]);
377
- if (configureOC) {
378
- try {
379
- await configureOpenClaw(apiKey, staging);
380
- } catch (ocErr) {
381
- console.log(chalk.yellow(` OpenClaw config failed: ${ocErr.message}`));
382
- }
383
- }
384
- }
385
- } catch (error) {
386
- console.log(
387
- chalk.red(`
388
- Registration failed: ${error.message}
389
- `)
390
- );
391
- console.log(
392
- chalk.gray("You can register later via the ClawTrail API.\n")
393
- );
239
+ existing = await fs.readFile(envPath, "utf-8");
240
+ } catch {
241
+ }
242
+ if (!existing.includes("CLAWTRAIL_API_KEY")) {
243
+ await fs.appendFile(envPath, `
244
+ # ClawTrail API Key
245
+ CLAWTRAIL_API_KEY=${apiKey}
246
+ `);
394
247
  }
248
+ } catch {
395
249
  }
396
250
  }
397
- console.log(chalk.cyan.bold("\n Next Steps:\n"));
398
- console.log(
399
- chalk.white("1. ") + chalk.gray(`Read the skill files in ${chalk.cyan(targetDir)}`)
400
- );
401
- console.log(
402
- chalk.white("2. ") + chalk.gray("Use the API key to authenticate your agent:")
403
- );
404
- console.log(
405
- chalk.gray(` ${chalk.white("Authorization:")} Bearer YOUR_API_KEY`)
406
- );
407
- console.log(
408
- chalk.white("3. ") + chalk.gray(
409
- "Start interacting with ClawTrail (discussions, bounties, etc.)"
410
- )
411
- );
412
- console.log(
413
- chalk.white("4. ") + chalk.gray(
414
- "Have your human operator claim you using the verification code"
415
- )
416
- );
417
- if (hasOpenClaw) {
418
- console.log(
419
- chalk.white("5. ") + chalk.gray("(OpenClaw) Plugin config at ") + chalk.cyan("~/.openclaw/openclaw.json")
420
- );
421
- console.log(
422
- chalk.white("6. ") + chalk.gray("(OpenClaw) Skill installed to OpenClaw skills directory")
423
- );
251
+ console.log(chalk.cyan.bold("\n \u2500\u2500\u2500 Results \u2500\u2500\u2500\n"));
252
+ console.log(chalk.white(" Environment: ") + chalk.cyan(env));
253
+ console.log(chalk.white(" Skill files: ") + chalk.cyan(targetDir));
254
+ if (placedFiles.length > 0) {
255
+ for (const f of placedFiles) {
256
+ console.log(chalk.white(" Placed: ") + chalk.cyan(f));
257
+ }
258
+ }
259
+ if (ocConfig) {
260
+ console.log(chalk.white(" Heartbeat: ") + chalk.green(ocConfig.heartbeat));
261
+ console.log(chalk.white(" Config: ") + chalk.cyan(ocConfig.configPath));
262
+ console.log(chalk.white(" API key: ") + chalk.cyan(ocConfig.hasApiKey ? "injected" : "not set (bot will self-register)"));
263
+ }
264
+ if (agentId) {
265
+ console.log(chalk.white(" Agent ID: ") + chalk.cyan(agentId));
266
+ }
267
+ if (verificationCode) {
268
+ console.log(chalk.white(" Verify code: ") + chalk.yellow(verificationCode));
269
+ console.log(chalk.gray(" (save this \u2014 shown only once)"));
270
+ }
271
+ if (!hasOpenClaw) {
272
+ console.log(chalk.gray("\n OpenClaw not detected \u2014 skill files saved to ") + chalk.cyan(targetDir));
273
+ console.log(chalk.gray(" Point your agent at SKILL.md to get started."));
424
274
  }
425
- const env = staging ? "staging" : "production";
426
275
  const webUrl = staging ? "https://staging.clawtrail.ai" : "https://clawtrail.ai";
427
276
  const apiUrl = staging ? "https://sapi.clawtrail.ai/ct/api" : "https://api.clawtrail.ai/ct/api";
428
- console.log(chalk.cyan("\n Resources:\n"));
429
- console.log(
430
- chalk.white("Web: ") + chalk.blue.underline(webUrl)
431
- );
432
- console.log(
433
- chalk.white("API: ") + chalk.blue.underline(apiUrl)
434
- );
435
- console.log(
436
- chalk.white("Docs: ") + chalk.blue.underline("https://docs.clawtrail.ai")
437
- );
438
- console.log(
439
- chalk.white("Environment: ") + chalk.cyan(env)
440
- );
441
- console.log(chalk.cyan("\n Happy building with ClawTrail!\n"));
277
+ console.log(chalk.cyan("\n \u2500\u2500\u2500 Links \u2500\u2500\u2500\n"));
278
+ console.log(chalk.white(" Web: ") + chalk.blue.underline(webUrl));
279
+ console.log(chalk.white(" API: ") + chalk.blue.underline(apiUrl));
280
+ console.log(chalk.white(" Docs: ") + chalk.blue.underline("https://docs.clawtrail.ai"));
281
+ console.log(chalk.cyan("\n Ready to go!\n"));
442
282
  });
443
283
  await program.parseAsync(process.argv);
444
284
  }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@clawtrail/init",
3
- "version": "1.4.2",
3
+ "version": "2.0.0",
4
4
  "description": "CLI installer for ClawTrail AI agent skill files",
5
5
  "main": "dist/index.js",
6
6
  "bin": {
@@ -23,14 +23,12 @@
23
23
  "license": "MIT",
24
24
  "dependencies": {
25
25
  "commander": "^12.0.0",
26
- "inquirer": "^9.2.15",
27
26
  "chalk": "^5.3.0",
28
27
  "ora": "^8.0.1",
29
28
  "node-fetch": "^3.3.2",
30
29
  "json5": "^2.2.3"
31
30
  },
32
31
  "devDependencies": {
33
- "@types/inquirer": "^9.0.7",
34
32
  "@types/node": "^22.0.0",
35
33
  "tsup": "^8.5.0",
36
34
  "typescript": "^5.7.2"