aiblueprint-cli 1.4.30 → 1.4.32

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/cli.js +114 -0
  2. package/package.json +1 -1
package/dist/cli.js CHANGED
@@ -33100,6 +33100,7 @@ function getPlaySoundCommand(soundPath) {
33100
33100
  var KNOWN_CLAUDE_PATHS = [
33101
33101
  /\/Users\/[^/]+\/\.claude\//,
33102
33102
  /\/home\/[^/]+\/\.claude\//,
33103
+ /\/root\/\.claude\//,
33103
33104
  /C:\\Users\\[^\\]+\\\.claude\\/i
33104
33105
  ];
33105
33106
  function transformHookCommand(command, claudeDir) {
@@ -33108,6 +33109,13 @@ function transformHookCommand(command, claudeDir) {
33108
33109
  transformed = transformed.replace(pattern, `${claudeDir}/`);
33109
33110
  }
33110
33111
  transformed = transformed.replace(/\\/g, "/");
33112
+ const isAudioCommand = /^(afplay|paplay|aplay|mpv|ffplay|powershell)\s/.test(transformed);
33113
+ if (isAudioCommand) {
33114
+ const newCommand = transformAudioCommand(transformed, claudeDir);
33115
+ if (newCommand) {
33116
+ return newCommand;
33117
+ }
33118
+ }
33111
33119
  return transformed;
33112
33120
  }
33113
33121
  function transformHook(hook, claudeDir) {
@@ -33151,12 +33159,39 @@ function isTextFile(filePath) {
33151
33159
  const ext = filePath.toLowerCase().slice(filePath.lastIndexOf("."));
33152
33160
  return TEXT_FILE_EXTENSIONS.has(ext);
33153
33161
  }
33162
+ function transformAudioCommand(command, claudeDir) {
33163
+ const soundFileMatch = command.match(/(?:finish\.mp3|need-human\.mp3|[^'"\s]+\.(?:mp3|wav))/);
33164
+ if (!soundFileMatch)
33165
+ return null;
33166
+ const soundFile = soundFileMatch[0];
33167
+ let soundPath;
33168
+ if (soundFile.includes("/")) {
33169
+ soundPath = soundFile;
33170
+ } else {
33171
+ soundPath = `${claudeDir}/song/${soundFile}`;
33172
+ }
33173
+ return getPlaySoundCommand(soundPath);
33174
+ }
33154
33175
  function transformFileContent(content, claudeDir) {
33155
33176
  let transformed = content;
33156
33177
  for (const pattern of KNOWN_CLAUDE_PATHS) {
33157
33178
  transformed = transformed.replace(new RegExp(pattern.source, "g"), `${claudeDir}/`);
33158
33179
  }
33159
33180
  transformed = transformed.replace(/\\/g, "/");
33181
+ const audioPatterns = [
33182
+ /afplay\s+-v\s+[\d.]+\s+'[^']+'/g,
33183
+ /afplay\s+'[^']+'/g,
33184
+ /paplay\s+'[^']+'/g,
33185
+ /aplay\s+'[^']+'/g,
33186
+ /mpv\s+--no-video[^']*'[^']+'/g,
33187
+ /ffplay\s+-nodisp[^']*'[^']+'/g
33188
+ ];
33189
+ for (const pattern of audioPatterns) {
33190
+ transformed = transformed.replace(pattern, (match) => {
33191
+ const newCommand = transformAudioCommand(match, claudeDir);
33192
+ return newCommand || match;
33193
+ });
33194
+ }
33160
33195
  return transformed;
33161
33196
  }
33162
33197
 
@@ -36156,6 +36191,40 @@ function getOpenclawTokenInfo() {
36156
36191
  var import_fs_extra14 = __toESM(require_lib4(), 1);
36157
36192
  var API_URL2 = "https://codeline.app/api/products";
36158
36193
  var OPENCLAW_PRODUCT_ID = "prd_t2GRwX3aH1";
36194
+ var CLAUDE_CODE_TOOLS_INSTRUCTIONS = `
36195
+ ## Claude Code (CLI)
36196
+
36197
+ Claude Code requires a TTY for interactive mode. When running in Docker or via exec without a PTY, use the \`script\` wrapper to simulate a TTY.
36198
+
36199
+ ### Usage Pattern
36200
+
36201
+ \`\`\`bash
36202
+ # ALWAYS use this pattern to run Claude Code:
36203
+ script -q -c "claude -p 'your prompt here' --output-format json" /dev/null
36204
+
36205
+ # Examples:
36206
+ script -q -c "claude -p 'What is 4+4?' --output-format json" /dev/null
36207
+ script -q -c "claude -p 'Explain this error: connection refused' --output-format json" /dev/null
36208
+ \`\`\`
36209
+
36210
+ ### Why?
36211
+
36212
+ Claude Code uses Ink (React for terminal) which requires \`stdin.setRawMode()\`. Without a TTY, this fails silently. The \`script\` command allocates a pseudo-TTY.
36213
+
36214
+ ### Wrapper Script
36215
+
36216
+ A wrapper is available at \`/usr/local/bin/claude-run\`:
36217
+
36218
+ \`\`\`bash
36219
+ claude-run "your prompt here"
36220
+ \`\`\`
36221
+
36222
+ ### Important
36223
+
36224
+ - NEVER run \`claude -p "..."\` directly - it will hang or fail silently
36225
+ - ALWAYS use the \`script\` wrapper or \`claude-run\`
36226
+ - Use \`--output-format json\` for structured output
36227
+ `.trim();
36159
36228
  async function openclawProActivateCommand(userToken) {
36160
36229
  Ie(source_default.blue(`\uD83D\uDD11 Activate OpenClaw Pro ${source_default.gray(`v${getVersion()}`)}`));
36161
36230
  try {
@@ -36274,10 +36343,55 @@ async function openclawProSetupCommand(options = {}) {
36274
36343
  }));
36275
36344
  skillCount = dirs.filter(Boolean).length;
36276
36345
  }
36346
+ spinner.start("Setting up workspace TOOLS.md...");
36347
+ const workspaceDir = path18.join(openclawDir, "workspace");
36348
+ const toolsPath = path18.join(workspaceDir, "TOOLS.md");
36349
+ await import_fs_extra14.default.ensureDir(workspaceDir);
36350
+ if (await import_fs_extra14.default.pathExists(toolsPath)) {
36351
+ const existingContent = await import_fs_extra14.default.readFile(toolsPath, "utf-8");
36352
+ if (!existingContent.includes("Claude Code (CLI)")) {
36353
+ await import_fs_extra14.default.appendFile(toolsPath, `
36354
+
36355
+ ` + CLAUDE_CODE_TOOLS_INSTRUCTIONS);
36356
+ spinner.stop("TOOLS.md updated with Claude Code instructions");
36357
+ } else {
36358
+ spinner.stop("TOOLS.md already has Claude Code instructions");
36359
+ }
36360
+ } else {
36361
+ const defaultToolsMd = `# TOOLS.md - Local Notes
36362
+
36363
+ Skills define _how_ tools work. This file is for _your_ specifics — the stuff that's unique to your setup.
36364
+
36365
+ ${CLAUDE_CODE_TOOLS_INSTRUCTIONS}
36366
+ `;
36367
+ await import_fs_extra14.default.writeFile(toolsPath, defaultToolsMd);
36368
+ spinner.stop("TOOLS.md created with Claude Code instructions");
36369
+ }
36370
+ spinner.start("Creating claude-run wrapper...");
36371
+ const claudeRunWrapper = `#!/bin/bash
36372
+ # Claude Code wrapper that handles TTY requirement
36373
+ # Usage: claude-run "your prompt here"
36374
+
36375
+ if [ -z "$1" ]; then
36376
+ echo "Usage: claude-run 'your prompt'"
36377
+ exit 1
36378
+ fi
36379
+
36380
+ script -q -c "claude -p '$1' --output-format json" /dev/null
36381
+ `;
36382
+ const binDir = "/usr/local/bin";
36383
+ const wrapperPath = path18.join(binDir, "claude-run");
36384
+ try {
36385
+ await import_fs_extra14.default.writeFile(wrapperPath, claudeRunWrapper, { mode: 493 });
36386
+ spinner.stop("claude-run wrapper created");
36387
+ } catch {
36388
+ spinner.stop("claude-run wrapper skipped (no write access to /usr/local/bin)");
36389
+ }
36277
36390
  M2.success("✅ Setup complete!");
36278
36391
  M2.info("Installed:");
36279
36392
  M2.info(` • Skills (${skillCount})`);
36280
36393
  M2.info(` • IDENTITY.md`);
36394
+ M2.info(` • TOOLS.md (Claude Code instructions)`);
36281
36395
  M2.info(source_default.cyan(`
36282
36396
  \uD83D\uDCA1 Skills installed to: ` + skillsDir));
36283
36397
  Se(source_default.green("\uD83D\uDE80 OpenClaw Pro ready!"));
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "aiblueprint-cli",
3
- "version": "1.4.30",
3
+ "version": "1.4.32",
4
4
  "description": "AIBlueprint CLI for setting up Claude Code configurations",
5
5
  "author": "AIBlueprint",
6
6
  "license": "MIT",