aiblueprint-cli 1.2.3 → 1.3.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.
|
@@ -29,11 +29,16 @@ Add to `~/.claude/settings.json`:
|
|
|
29
29
|
|
|
30
30
|
### Authentication
|
|
31
31
|
|
|
32
|
-
OAuth token
|
|
32
|
+
OAuth token storage (platform-specific):
|
|
33
|
+
|
|
34
|
+
**macOS**: Stored in Keychain
|
|
33
35
|
- **Service**: `Claude Code-credentials`
|
|
36
|
+
- **Access**: `security find-generic-password -s "Claude Code-credentials" -w`
|
|
37
|
+
|
|
38
|
+
**Windows & Linux**: Stored in file system
|
|
39
|
+
- **Location**: `~/.claude/.credentials.json`
|
|
34
40
|
- **Format**: JSON with `claudeAiOauth.accessToken`
|
|
35
41
|
- **Token type**: `sk-ant-oat01-...` (OAuth token, not API key)
|
|
36
|
-
- **Access**: `security find-generic-password -s "Claude Code-credentials" -w`
|
|
37
42
|
|
|
38
43
|
## Architecture
|
|
39
44
|
|
|
@@ -172,7 +177,7 @@ This ensures statusline never crashes Claude Code.
|
|
|
172
177
|
|
|
173
178
|
## Known Limitations
|
|
174
179
|
|
|
175
|
-
- macOS only (uses Keychain)
|
|
176
180
|
- Requires `git` CLI for git status
|
|
177
181
|
- Requires Claude Code OAuth (not API key)
|
|
178
182
|
- Transcript must be accessible (permissions)
|
|
183
|
+
- Cross-platform support: macOS (Keychain), Windows & Linux (file-based credentials)
|
package/dist/cli.js
CHANGED
|
@@ -32490,7 +32490,7 @@ var lib_default = inquirer;
|
|
|
32490
32490
|
// src/commands/setup.ts
|
|
32491
32491
|
var import_fs_extra5 = __toESM(require_lib4(), 1);
|
|
32492
32492
|
import path7 from "path";
|
|
32493
|
-
import
|
|
32493
|
+
import os7 from "os";
|
|
32494
32494
|
|
|
32495
32495
|
// node_modules/chalk/source/vendor/ansi-styles/index.js
|
|
32496
32496
|
var ANSI_BACKGROUND_OFFSET = 10;
|
|
@@ -32994,8 +32994,14 @@ async function setupShellShortcuts() {
|
|
|
32994
32994
|
try {
|
|
32995
32995
|
const platform = os3.platform();
|
|
32996
32996
|
let shellConfigFile;
|
|
32997
|
+
let aliases;
|
|
32997
32998
|
if (platform === "darwin") {
|
|
32998
32999
|
shellConfigFile = path2.join(os3.homedir(), ".zshenv");
|
|
33000
|
+
aliases = `
|
|
33001
|
+
# AIBlueprint Claude Code aliases
|
|
33002
|
+
alias cc="claude --dangerously-skip-permissions"
|
|
33003
|
+
alias ccc="claude --dangerously-skip-permissions -c"
|
|
33004
|
+
`;
|
|
32999
33005
|
} else if (platform === "linux") {
|
|
33000
33006
|
const shell = process.env.SHELL || "";
|
|
33001
33007
|
if (shell.includes("zsh")) {
|
|
@@ -33003,17 +33009,35 @@ async function setupShellShortcuts() {
|
|
|
33003
33009
|
} else {
|
|
33004
33010
|
shellConfigFile = path2.join(os3.homedir(), ".bashrc");
|
|
33005
33011
|
}
|
|
33006
|
-
|
|
33007
|
-
console.log(source_default.yellow("Shell shortcuts are only supported on macOS and Linux"));
|
|
33008
|
-
return;
|
|
33009
|
-
}
|
|
33010
|
-
const aliases = `
|
|
33012
|
+
aliases = `
|
|
33011
33013
|
# AIBlueprint Claude Code aliases
|
|
33012
33014
|
alias cc="claude --dangerously-skip-permissions"
|
|
33013
33015
|
alias ccc="claude --dangerously-skip-permissions -c"
|
|
33014
33016
|
`;
|
|
33017
|
+
} else if (platform === "win32") {
|
|
33018
|
+
const pwshProfileDir = path2.join(os3.homedir(), "Documents", "PowerShell");
|
|
33019
|
+
const windowsPwshProfileDir = path2.join(os3.homedir(), "Documents", "WindowsPowerShell");
|
|
33020
|
+
let profileDir;
|
|
33021
|
+
if (await import_fs_extra.default.pathExists(pwshProfileDir)) {
|
|
33022
|
+
profileDir = pwshProfileDir;
|
|
33023
|
+
} else if (await import_fs_extra.default.pathExists(windowsPwshProfileDir)) {
|
|
33024
|
+
profileDir = windowsPwshProfileDir;
|
|
33025
|
+
} else {
|
|
33026
|
+
profileDir = pwshProfileDir;
|
|
33027
|
+
await import_fs_extra.default.ensureDir(profileDir);
|
|
33028
|
+
}
|
|
33029
|
+
shellConfigFile = path2.join(profileDir, "Profile.ps1");
|
|
33030
|
+
aliases = `
|
|
33031
|
+
# AIBlueprint Claude Code shortcuts
|
|
33032
|
+
function cc { claude --dangerously-skip-permissions $args }
|
|
33033
|
+
function ccc { claude --dangerously-skip-permissions -c $args }
|
|
33034
|
+
`;
|
|
33035
|
+
} else {
|
|
33036
|
+
console.log(source_default.yellow(`Shell shortcuts are not supported on platform: ${platform}`));
|
|
33037
|
+
return;
|
|
33038
|
+
}
|
|
33015
33039
|
const existingContent = await import_fs_extra.default.readFile(shellConfigFile, "utf-8").catch(() => "");
|
|
33016
|
-
if (!existingContent.includes("AIBlueprint Claude Code
|
|
33040
|
+
if (!existingContent.includes("AIBlueprint Claude Code")) {
|
|
33017
33041
|
await import_fs_extra.default.appendFile(shellConfigFile, aliases);
|
|
33018
33042
|
}
|
|
33019
33043
|
} catch (error) {
|
|
@@ -33078,7 +33102,12 @@ async function createSymlink(sourcePath, targetPath, options = {}) {
|
|
|
33078
33102
|
return false;
|
|
33079
33103
|
}
|
|
33080
33104
|
}
|
|
33081
|
-
|
|
33105
|
+
const isWindows = os4.platform() === "win32";
|
|
33106
|
+
if (isWindows) {
|
|
33107
|
+
await import_fs_extra2.default.symlink(sourcePath, targetPath, "junction");
|
|
33108
|
+
} else {
|
|
33109
|
+
await import_fs_extra2.default.symlink(sourcePath, targetPath);
|
|
33110
|
+
}
|
|
33082
33111
|
return true;
|
|
33083
33112
|
} catch (error) {
|
|
33084
33113
|
console.error(source_default.red(options.errorPrefix || "Error creating symlink:"), error);
|
|
@@ -33131,10 +33160,13 @@ async function setupOpenCodeSymlink(claudeDir, customOpenCodeFolder, customClaud
|
|
|
33131
33160
|
// src/commands/setup/dependencies.ts
|
|
33132
33161
|
import { execSync } from "child_process";
|
|
33133
33162
|
import path4 from "path";
|
|
33163
|
+
import os5 from "os";
|
|
33134
33164
|
async function checkAndInstallDependencies() {
|
|
33165
|
+
const isWindows = os5.platform() === "win32";
|
|
33135
33166
|
const checkCommand = (cmd) => {
|
|
33136
33167
|
try {
|
|
33137
|
-
|
|
33168
|
+
const whichCmd = isWindows ? `where ${cmd}` : `which ${cmd}`;
|
|
33169
|
+
execSync(whichCmd, { stdio: "ignore" });
|
|
33138
33170
|
return true;
|
|
33139
33171
|
} catch {
|
|
33140
33172
|
return false;
|
|
@@ -33177,6 +33209,27 @@ async function installStatuslineDependencies(claudeDir) {
|
|
|
33177
33209
|
// src/commands/setup/settings.ts
|
|
33178
33210
|
var import_fs_extra3 = __toESM(require_lib4(), 1);
|
|
33179
33211
|
import path5 from "path";
|
|
33212
|
+
import os6 from "os";
|
|
33213
|
+
function getPlaySoundCommand(soundPath) {
|
|
33214
|
+
const platform = os6.platform();
|
|
33215
|
+
if (platform === "darwin") {
|
|
33216
|
+
return `afplay -v 0.1 "${soundPath}"`;
|
|
33217
|
+
} else if (platform === "win32") {
|
|
33218
|
+
return `powershell -c "(New-Object Media.SoundPlayer '${soundPath}').PlaySync()"`;
|
|
33219
|
+
} else {
|
|
33220
|
+
return `paplay "${soundPath}" 2>/dev/null || aplay "${soundPath}" 2>/dev/null || true`;
|
|
33221
|
+
}
|
|
33222
|
+
}
|
|
33223
|
+
async function hasExistingStatusLine(claudeDir) {
|
|
33224
|
+
const settingsPath = path5.join(claudeDir, "settings.json");
|
|
33225
|
+
try {
|
|
33226
|
+
const existingSettings = await import_fs_extra3.default.readFile(settingsPath, "utf-8");
|
|
33227
|
+
const settings = JSON.parse(existingSettings);
|
|
33228
|
+
return !!settings.statusLine;
|
|
33229
|
+
} catch {
|
|
33230
|
+
return false;
|
|
33231
|
+
}
|
|
33232
|
+
}
|
|
33180
33233
|
async function updateSettings(options, claudeDir) {
|
|
33181
33234
|
const settingsPath = path5.join(claudeDir, "settings.json");
|
|
33182
33235
|
let settings = {};
|
|
@@ -33186,24 +33239,8 @@ async function updateSettings(options, claudeDir) {
|
|
|
33186
33239
|
} catch {
|
|
33187
33240
|
}
|
|
33188
33241
|
if (options.customStatusline) {
|
|
33189
|
-
|
|
33190
|
-
|
|
33191
|
-
{
|
|
33192
|
-
type: "confirm",
|
|
33193
|
-
name: "replace",
|
|
33194
|
-
message: "You already have a statusLine configuration. Replace it?"
|
|
33195
|
-
}
|
|
33196
|
-
]);
|
|
33197
|
-
if (!confirmAnswer.replace) {
|
|
33198
|
-
console.log(source_default.yellow(" Keeping existing statusLine configuration"));
|
|
33199
|
-
} else {
|
|
33200
|
-
settings.statusLine = {
|
|
33201
|
-
type: "command",
|
|
33202
|
-
command: `bun ${path5.join(claudeDir, "scripts/statusline/src/index.ts")}`,
|
|
33203
|
-
padding: 0
|
|
33204
|
-
};
|
|
33205
|
-
}
|
|
33206
|
-
} else {
|
|
33242
|
+
const shouldReplace = options.replaceStatusline !== false;
|
|
33243
|
+
if (shouldReplace) {
|
|
33207
33244
|
settings.statusLine = {
|
|
33208
33245
|
type: "command",
|
|
33209
33246
|
command: `bun ${path5.join(claudeDir, "scripts/statusline/src/index.ts")}`,
|
|
@@ -33236,12 +33273,13 @@ async function updateSettings(options, claudeDir) {
|
|
|
33236
33273
|
if (!settings.hooks.Stop) {
|
|
33237
33274
|
settings.hooks.Stop = [];
|
|
33238
33275
|
}
|
|
33276
|
+
const finishSoundPath = path5.join(claudeDir, "song/finish.mp3");
|
|
33239
33277
|
const stopHook = {
|
|
33240
33278
|
matcher: "",
|
|
33241
33279
|
hooks: [
|
|
33242
33280
|
{
|
|
33243
33281
|
type: "command",
|
|
33244
|
-
command:
|
|
33282
|
+
command: getPlaySoundCommand(finishSoundPath)
|
|
33245
33283
|
}
|
|
33246
33284
|
]
|
|
33247
33285
|
};
|
|
@@ -33252,12 +33290,13 @@ async function updateSettings(options, claudeDir) {
|
|
|
33252
33290
|
if (!settings.hooks.Notification) {
|
|
33253
33291
|
settings.hooks.Notification = [];
|
|
33254
33292
|
}
|
|
33293
|
+
const needHumanSoundPath = path5.join(claudeDir, "song/need-human.mp3");
|
|
33255
33294
|
const notificationHook = {
|
|
33256
33295
|
matcher: "",
|
|
33257
33296
|
hooks: [
|
|
33258
33297
|
{
|
|
33259
33298
|
type: "command",
|
|
33260
|
-
command:
|
|
33299
|
+
command: getPlaySoundCommand(needHumanSoundPath)
|
|
33261
33300
|
}
|
|
33262
33301
|
]
|
|
33263
33302
|
};
|
|
@@ -33322,24 +33361,35 @@ async function downloadDirectoryFromGitHub(dirPath, targetDir) {
|
|
|
33322
33361
|
const apiUrl = `https://api.github.com/repos/Melvynx/aiblueprint-cli/contents/claude-code-config/${dirPath}`;
|
|
33323
33362
|
const response = await fetch(apiUrl);
|
|
33324
33363
|
if (!response.ok) {
|
|
33364
|
+
console.error(source_default.yellow(` Warning: Failed to fetch directory from GitHub: ${dirPath} (HTTP ${response.status})`));
|
|
33325
33365
|
return false;
|
|
33326
33366
|
}
|
|
33327
33367
|
const files = await response.json();
|
|
33328
33368
|
if (!Array.isArray(files)) {
|
|
33369
|
+
console.error(source_default.yellow(` Warning: Invalid response from GitHub API for: ${dirPath}`));
|
|
33329
33370
|
return false;
|
|
33330
33371
|
}
|
|
33331
33372
|
await import_fs_extra4.default.ensureDir(targetDir);
|
|
33373
|
+
let allSuccess = true;
|
|
33332
33374
|
for (const file of files) {
|
|
33333
33375
|
const relativePath = `${dirPath}/${file.name}`;
|
|
33334
33376
|
const targetPath = path6.join(targetDir, file.name);
|
|
33335
33377
|
if (file.type === "file") {
|
|
33336
|
-
await downloadFromGitHub(relativePath, targetPath);
|
|
33378
|
+
const success = await downloadFromGitHub(relativePath, targetPath);
|
|
33379
|
+
if (!success) {
|
|
33380
|
+
console.error(source_default.yellow(` Warning: Failed to download file: ${relativePath}`));
|
|
33381
|
+
allSuccess = false;
|
|
33382
|
+
}
|
|
33337
33383
|
} else if (file.type === "dir") {
|
|
33338
|
-
await downloadDirectoryFromGitHub(relativePath, targetPath);
|
|
33384
|
+
const success = await downloadDirectoryFromGitHub(relativePath, targetPath);
|
|
33385
|
+
if (!success) {
|
|
33386
|
+
allSuccess = false;
|
|
33387
|
+
}
|
|
33339
33388
|
}
|
|
33340
33389
|
}
|
|
33341
|
-
return
|
|
33390
|
+
return allSuccess;
|
|
33342
33391
|
} catch (error) {
|
|
33392
|
+
console.error(source_default.yellow(` Warning: Error downloading directory ${dirPath}: ${error instanceof Error ? error.message : String(error)}`));
|
|
33343
33393
|
return false;
|
|
33344
33394
|
}
|
|
33345
33395
|
}
|
|
@@ -33443,10 +33493,11 @@ async function setupCommand(params = {}) {
|
|
|
33443
33493
|
notificationSounds: features.includes("notificationSounds"),
|
|
33444
33494
|
postEditTypeScript: features.includes("postEditTypeScript"),
|
|
33445
33495
|
codexSymlink: features.includes("codexSymlink"),
|
|
33446
|
-
openCodeSymlink: features.includes("openCodeSymlink")
|
|
33496
|
+
openCodeSymlink: features.includes("openCodeSymlink"),
|
|
33497
|
+
skipInteractive
|
|
33447
33498
|
};
|
|
33448
33499
|
const s = new SimpleSpinner;
|
|
33449
|
-
const claudeDir = customClaudeCodeFolder ? path7.resolve(customClaudeCodeFolder) : path7.join(
|
|
33500
|
+
const claudeDir = customClaudeCodeFolder ? path7.resolve(customClaudeCodeFolder) : path7.join(os7.homedir(), ".claude");
|
|
33450
33501
|
console.log(source_default.gray(`Installing to: ${claudeDir}`));
|
|
33451
33502
|
await import_fs_extra5.default.ensureDir(claudeDir);
|
|
33452
33503
|
let useGitHub = true;
|
|
@@ -33577,6 +33628,23 @@ async function setupCommand(params = {}) {
|
|
|
33577
33628
|
await installStatuslineDependencies(claudeDir);
|
|
33578
33629
|
s.stop("Statusline dependencies installed");
|
|
33579
33630
|
}
|
|
33631
|
+
if (options.customStatusline && !skipInteractive) {
|
|
33632
|
+
const existingStatusLine = await hasExistingStatusLine(claudeDir);
|
|
33633
|
+
if (existingStatusLine) {
|
|
33634
|
+
const confirmAnswer = await lib_default.prompt([
|
|
33635
|
+
{
|
|
33636
|
+
type: "confirm",
|
|
33637
|
+
name: "replace",
|
|
33638
|
+
message: "You already have a statusLine configuration. Replace it?",
|
|
33639
|
+
default: true
|
|
33640
|
+
}
|
|
33641
|
+
]);
|
|
33642
|
+
options.replaceStatusline = confirmAnswer.replace;
|
|
33643
|
+
if (!confirmAnswer.replace) {
|
|
33644
|
+
console.log(source_default.yellow(" Keeping existing statusLine configuration"));
|
|
33645
|
+
}
|
|
33646
|
+
}
|
|
33647
|
+
}
|
|
33580
33648
|
s.start("Updating settings.json");
|
|
33581
33649
|
await updateSettings(options, claudeDir);
|
|
33582
33650
|
s.stop("Settings updated");
|
|
@@ -33584,7 +33652,12 @@ async function setupCommand(params = {}) {
|
|
|
33584
33652
|
console.log(source_default.gray(`
|
|
33585
33653
|
Next steps:`));
|
|
33586
33654
|
if (options.shellShortcuts) {
|
|
33587
|
-
|
|
33655
|
+
const platform = os7.platform();
|
|
33656
|
+
if (platform === "win32") {
|
|
33657
|
+
console.log(source_default.gray(" • Restart PowerShell to load the new functions"));
|
|
33658
|
+
} else {
|
|
33659
|
+
console.log(source_default.gray(" • Restart your terminal or run: source ~/.zshenv (macOS) or source ~/.bashrc (Linux)"));
|
|
33660
|
+
}
|
|
33588
33661
|
console.log(source_default.gray(' • Use "cc" for Claude Code with permissions skipped'));
|
|
33589
33662
|
console.log(source_default.gray(' • Use "ccc" for Claude Code with permissions skipped and continue mode'));
|
|
33590
33663
|
}
|
|
@@ -34708,7 +34781,7 @@ var de = () => {
|
|
|
34708
34781
|
|
|
34709
34782
|
// src/lib/pro-installer.ts
|
|
34710
34783
|
var import_fs_extra12 = __toESM(require_lib4(), 1);
|
|
34711
|
-
import
|
|
34784
|
+
import os8 from "os";
|
|
34712
34785
|
import path14 from "path";
|
|
34713
34786
|
var PREMIUM_REPO = "Melvynx/aiblueprint-cli-premium";
|
|
34714
34787
|
var PREMIUM_BRANCH = "main";
|
|
@@ -34770,8 +34843,8 @@ async function downloadDirectoryFromPrivateGitHub(repo, branch, dirPath, targetD
|
|
|
34770
34843
|
}
|
|
34771
34844
|
async function installProConfigs(options) {
|
|
34772
34845
|
const { githubToken, claudeCodeFolder } = options;
|
|
34773
|
-
const claudeFolder = claudeCodeFolder || path14.join(
|
|
34774
|
-
const tempDir = path14.join(
|
|
34846
|
+
const claudeFolder = claudeCodeFolder || path14.join(os8.homedir(), ".claude");
|
|
34847
|
+
const tempDir = path14.join(os8.tmpdir(), `aiblueprint-premium-${Date.now()}`);
|
|
34775
34848
|
try {
|
|
34776
34849
|
const success = await downloadDirectoryFromPrivateGitHub(PREMIUM_REPO, PREMIUM_BRANCH, "claude-code-config", tempDir, githubToken);
|
|
34777
34850
|
if (!success) {
|
|
@@ -34795,9 +34868,9 @@ async function installProConfigs(options) {
|
|
|
34795
34868
|
// src/lib/setup-helper.ts
|
|
34796
34869
|
var import_fs_extra13 = __toESM(require_lib4(), 1);
|
|
34797
34870
|
import path15 from "path";
|
|
34798
|
-
import
|
|
34871
|
+
import os9 from "os";
|
|
34799
34872
|
async function installBasicConfigs(options = {}, skipStatusline = false) {
|
|
34800
|
-
const claudeDir = options.claudeCodeFolder || path15.join(
|
|
34873
|
+
const claudeDir = options.claudeCodeFolder || path15.join(os9.homedir(), ".claude");
|
|
34801
34874
|
await import_fs_extra13.default.ensureDir(claudeDir);
|
|
34802
34875
|
console.log(source_default.gray("\uD83D\uDCE6 Installing free configurations..."));
|
|
34803
34876
|
console.log(source_default.gray(" • Commands..."));
|
|
@@ -34814,15 +34887,15 @@ async function installBasicConfigs(options = {}, skipStatusline = false) {
|
|
|
34814
34887
|
|
|
34815
34888
|
// src/lib/token-storage.ts
|
|
34816
34889
|
var import_fs_extra14 = __toESM(require_lib4(), 1);
|
|
34817
|
-
import
|
|
34890
|
+
import os10 from "os";
|
|
34818
34891
|
import path16 from "path";
|
|
34819
34892
|
function getConfigDir() {
|
|
34820
|
-
const platform =
|
|
34893
|
+
const platform = os10.platform();
|
|
34821
34894
|
if (platform === "win32") {
|
|
34822
|
-
const appData = process.env.APPDATA || path16.join(
|
|
34895
|
+
const appData = process.env.APPDATA || path16.join(os10.homedir(), "AppData", "Roaming");
|
|
34823
34896
|
return path16.join(appData, "aiblueprint");
|
|
34824
34897
|
} else {
|
|
34825
|
-
const configHome = process.env.XDG_CONFIG_HOME || path16.join(
|
|
34898
|
+
const configHome = process.env.XDG_CONFIG_HOME || path16.join(os10.homedir(), ".config");
|
|
34826
34899
|
return path16.join(configHome, "aiblueprint");
|
|
34827
34900
|
}
|
|
34828
34901
|
}
|
|
@@ -34849,7 +34922,7 @@ async function getToken() {
|
|
|
34849
34922
|
function getTokenInfo() {
|
|
34850
34923
|
return {
|
|
34851
34924
|
path: getTokenFilePath(),
|
|
34852
|
-
platform:
|
|
34925
|
+
platform: os10.platform()
|
|
34853
34926
|
};
|
|
34854
34927
|
}
|
|
34855
34928
|
|