aiblueprint-cli 1.1.8 → 1.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/claude-code-config/scripts/command-validator/README.md +147 -0
- package/claude-code-config/scripts/command-validator/biome.json +29 -0
- package/claude-code-config/scripts/command-validator/bun.lockb +0 -0
- package/claude-code-config/scripts/command-validator/dist/cli.js +544 -0
- package/claude-code-config/scripts/command-validator/package.json +27 -0
- package/claude-code-config/scripts/command-validator/src/__tests__/validator.test.ts +148 -0
- package/claude-code-config/scripts/command-validator/src/cli.ts +118 -0
- package/claude-code-config/scripts/command-validator/src/lib/security-rules.ts +172 -0
- package/claude-code-config/scripts/command-validator/src/lib/types.ts +33 -0
- package/claude-code-config/scripts/command-validator/src/lib/validator.ts +360 -0
- package/claude-code-config/scripts/command-validator/vitest.config.ts +7 -0
- package/claude-code-config/scripts/statusline/package.json +1 -3
- package/claude-code-config/scripts/statusline/src/index.ts +5 -107
- package/claude-code-config/scripts/statusline/src/lib/context.ts +66 -87
- package/claude-code-config/scripts/statusline/src/lib/formatters.ts +16 -186
- package/claude-code-config/scripts/statusline/statusline.config.ts +4 -101
- package/dist/cli.js +938 -12
- package/package.json +1 -1
- package/claude-code-config/agents/fix-grammar.md +0 -49
- package/claude-code-config/agents/snipper.md +0 -36
- package/claude-code-config/commands/claude-memory.md +0 -190
- package/claude-code-config/commands/cleanup-context.md +0 -82
- package/claude-code-config/commands/debug.md +0 -91
- package/claude-code-config/commands/deep-code-analysis.md +0 -87
- package/claude-code-config/commands/epct/code.md +0 -171
- package/claude-code-config/commands/epct/deploy.md +0 -116
- package/claude-code-config/commands/epct/explore.md +0 -97
- package/claude-code-config/commands/epct/plan.md +0 -132
- package/claude-code-config/commands/epct/tasks.md +0 -206
- package/claude-code-config/commands/explain-architecture.md +0 -113
- package/claude-code-config/commands/melvynx-plugin.md +0 -1
- package/claude-code-config/commands/prompt-agent.md +0 -126
- package/claude-code-config/commands/prompt-command.md +0 -225
- package/claude-code-config/scripts/statusline/data/.gitignore +0 -5
- package/claude-code-config/scripts/statusline/src/commands/CLAUDE.md +0 -3
- package/claude-code-config/scripts/statusline/src/commands/spend-month.ts +0 -60
- package/claude-code-config/scripts/statusline/src/commands/spend-today.ts +0 -42
- package/claude-code-config/scripts/statusline/src/lib/git.ts +0 -100
- package/claude-code-config/scripts/statusline/src/lib/spend.ts +0 -119
- package/claude-code-config/scripts/statusline/src/lib/usage-limits.ts +0 -147
|
@@ -1,218 +1,48 @@
|
|
|
1
|
-
import type {
|
|
2
|
-
import type { GitStatus } from "./git";
|
|
1
|
+
import type { StatuslineConfig } from "../../statusline.config";
|
|
3
2
|
|
|
4
3
|
export const colors = {
|
|
5
|
-
GREEN: "\x1b[0;32m",
|
|
6
|
-
RED: "\x1b[0;31m",
|
|
7
|
-
PURPLE: "\x1b[0;35m",
|
|
8
|
-
YELLOW: "\x1b[0;33m",
|
|
9
|
-
ORANGE: "\x1b[38;5;208m",
|
|
10
4
|
GRAY: "\x1b[0;90m",
|
|
11
5
|
LIGHT_GRAY: "\x1b[0;37m",
|
|
12
6
|
RESET: "\x1b[0m",
|
|
13
7
|
} as const;
|
|
14
8
|
|
|
15
|
-
export function
|
|
16
|
-
git: GitStatus,
|
|
17
|
-
gitConfig: StatuslineConfig["git"],
|
|
18
|
-
): string {
|
|
19
|
-
let result = "";
|
|
20
|
-
|
|
21
|
-
if (gitConfig.showBranch) {
|
|
22
|
-
result = git.branch;
|
|
23
|
-
}
|
|
24
|
-
|
|
25
|
-
if (git.hasChanges) {
|
|
26
|
-
const changes: string[] = [];
|
|
27
|
-
|
|
28
|
-
if (gitConfig.showDirtyIndicator) {
|
|
29
|
-
result += `${colors.PURPLE}*${colors.RESET}`;
|
|
30
|
-
}
|
|
31
|
-
|
|
32
|
-
if (gitConfig.showChanges) {
|
|
33
|
-
const totalAdded = git.staged.added + git.unstaged.added;
|
|
34
|
-
const totalDeleted = git.staged.deleted + git.unstaged.deleted;
|
|
35
|
-
|
|
36
|
-
if (totalAdded > 0) {
|
|
37
|
-
changes.push(`${colors.GREEN}+${totalAdded}${colors.RESET}`);
|
|
38
|
-
}
|
|
39
|
-
if (totalDeleted > 0) {
|
|
40
|
-
changes.push(`${colors.RED}-${totalDeleted}${colors.RESET}`);
|
|
41
|
-
}
|
|
42
|
-
}
|
|
43
|
-
|
|
44
|
-
if (gitConfig.showStaged && git.staged.files > 0) {
|
|
45
|
-
changes.push(`${colors.GRAY}~${git.staged.files}${colors.RESET}`);
|
|
46
|
-
}
|
|
47
|
-
|
|
48
|
-
if (gitConfig.showUnstaged && git.unstaged.files > 0) {
|
|
49
|
-
changes.push(`${colors.YELLOW}~${git.unstaged.files}${colors.RESET}`);
|
|
50
|
-
}
|
|
51
|
-
|
|
52
|
-
if (changes.length > 0) {
|
|
53
|
-
result += ` ${changes.join(" ")}`;
|
|
54
|
-
}
|
|
55
|
-
}
|
|
56
|
-
|
|
57
|
-
return result;
|
|
58
|
-
}
|
|
59
|
-
|
|
60
|
-
export function formatPath(
|
|
61
|
-
path: string,
|
|
62
|
-
mode: "full" | "truncated" | "basename" = "truncated",
|
|
63
|
-
): string {
|
|
9
|
+
export function formatPath(path: string, _mode: "full"): string {
|
|
64
10
|
const home = process.env.HOME || "";
|
|
65
|
-
let formattedPath = path;
|
|
66
|
-
|
|
67
11
|
if (home && path.startsWith(home)) {
|
|
68
|
-
|
|
12
|
+
return `~${path.slice(home.length)}`;
|
|
69
13
|
}
|
|
70
|
-
|
|
71
|
-
if (mode === "basename") {
|
|
72
|
-
const segments = path.split("/").filter((s) => s.length > 0);
|
|
73
|
-
return segments[segments.length - 1] || path;
|
|
74
|
-
}
|
|
75
|
-
|
|
76
|
-
if (mode === "truncated") {
|
|
77
|
-
const segments = formattedPath.split("/").filter((s) => s.length > 0);
|
|
78
|
-
if (segments.length > 2) {
|
|
79
|
-
return `/${segments.slice(-2).join("/")}`;
|
|
80
|
-
}
|
|
81
|
-
}
|
|
82
|
-
|
|
83
|
-
return formattedPath;
|
|
84
|
-
}
|
|
85
|
-
|
|
86
|
-
export function formatCost(cost: number): string {
|
|
87
|
-
return cost.toFixed(2);
|
|
14
|
+
return path;
|
|
88
15
|
}
|
|
89
16
|
|
|
90
|
-
|
|
17
|
+
function formatTokens(tokens: number): string {
|
|
91
18
|
if (tokens >= 1000000) {
|
|
92
|
-
const value = tokens / 1000000;
|
|
93
|
-
|
|
94
|
-
? value.toFixed(1)
|
|
95
|
-
: Math.round(value).toString();
|
|
96
|
-
return `${number}${colors.GRAY}m${colors.LIGHT_GRAY}`;
|
|
19
|
+
const value = Math.round(tokens / 1000000);
|
|
20
|
+
return `${value}${colors.GRAY}m${colors.LIGHT_GRAY}`;
|
|
97
21
|
}
|
|
98
22
|
if (tokens >= 1000) {
|
|
99
|
-
const value = tokens / 1000;
|
|
100
|
-
|
|
101
|
-
? value.toFixed(1)
|
|
102
|
-
: Math.round(value).toString();
|
|
103
|
-
return `${number}${colors.GRAY}k${colors.LIGHT_GRAY}`;
|
|
23
|
+
const value = Math.round(tokens / 1000);
|
|
24
|
+
return `${value}${colors.GRAY}k${colors.LIGHT_GRAY}`;
|
|
104
25
|
}
|
|
105
26
|
return tokens.toString();
|
|
106
27
|
}
|
|
107
28
|
|
|
108
|
-
export function formatDuration(ms: number): string {
|
|
109
|
-
const minutes = Math.floor(ms / 60000);
|
|
110
|
-
const hours = Math.floor(minutes / 60);
|
|
111
|
-
const mins = minutes % 60;
|
|
112
|
-
|
|
113
|
-
if (hours > 0) {
|
|
114
|
-
return `${hours}h ${mins}m`;
|
|
115
|
-
}
|
|
116
|
-
return `${mins}m`;
|
|
117
|
-
}
|
|
118
|
-
|
|
119
|
-
export function formatResetTime(resetsAt: string): string {
|
|
120
|
-
try {
|
|
121
|
-
const resetDate = new Date(resetsAt);
|
|
122
|
-
const now = new Date();
|
|
123
|
-
const diffMs = resetDate.getTime() - now.getTime();
|
|
124
|
-
|
|
125
|
-
if (diffMs <= 0) {
|
|
126
|
-
return "now";
|
|
127
|
-
}
|
|
128
|
-
|
|
129
|
-
const hours = Math.floor(diffMs / 3600000);
|
|
130
|
-
const minutes = Math.floor((diffMs % 3600000) / 60000);
|
|
131
|
-
|
|
132
|
-
if (hours > 0) {
|
|
133
|
-
return `${hours}h${minutes}m`;
|
|
134
|
-
}
|
|
135
|
-
return `${minutes}m`;
|
|
136
|
-
} catch {
|
|
137
|
-
return "N/A";
|
|
138
|
-
}
|
|
139
|
-
}
|
|
140
|
-
|
|
141
|
-
export function formatProgressBar(
|
|
142
|
-
percentage: number,
|
|
143
|
-
length: number,
|
|
144
|
-
colorMode: "progressive" | "green" | "yellow" | "red",
|
|
145
|
-
): string {
|
|
146
|
-
const filled = Math.round((percentage / 100) * length);
|
|
147
|
-
const empty = length - filled;
|
|
148
|
-
|
|
149
|
-
const filledBar = "█".repeat(filled);
|
|
150
|
-
const emptyBar = "░".repeat(empty);
|
|
151
|
-
|
|
152
|
-
let barColor: string;
|
|
153
|
-
if (colorMode === "progressive") {
|
|
154
|
-
if (percentage < 50) {
|
|
155
|
-
barColor = colors.GRAY;
|
|
156
|
-
} else if (percentage < 70) {
|
|
157
|
-
barColor = colors.YELLOW;
|
|
158
|
-
} else if (percentage < 90) {
|
|
159
|
-
barColor = colors.ORANGE;
|
|
160
|
-
} else {
|
|
161
|
-
barColor = colors.RED;
|
|
162
|
-
}
|
|
163
|
-
} else if (colorMode === "green") {
|
|
164
|
-
barColor = colors.GREEN;
|
|
165
|
-
} else if (colorMode === "yellow") {
|
|
166
|
-
barColor = colors.YELLOW;
|
|
167
|
-
} else {
|
|
168
|
-
barColor = colors.RED;
|
|
169
|
-
}
|
|
170
|
-
|
|
171
|
-
return `${barColor}${filledBar}${colors.GRAY}${emptyBar}${colors.RESET}`;
|
|
172
|
-
}
|
|
173
|
-
|
|
174
|
-
export interface SessionConfig {
|
|
175
|
-
infoSeparator: Separator | null;
|
|
176
|
-
showCost: boolean;
|
|
177
|
-
showTokens: boolean;
|
|
178
|
-
showMaxTokens: boolean;
|
|
179
|
-
showTokenDecimals: boolean;
|
|
180
|
-
showPercentage: boolean;
|
|
181
|
-
}
|
|
182
|
-
|
|
183
29
|
export function formatSession(
|
|
184
|
-
|
|
185
|
-
tokensUsed: number,
|
|
186
|
-
tokensMax: number,
|
|
30
|
+
tokens: number,
|
|
187
31
|
percentage: number,
|
|
188
|
-
config:
|
|
32
|
+
config: StatuslineConfig["session"],
|
|
189
33
|
): string {
|
|
190
|
-
const
|
|
34
|
+
const items: string[] = [];
|
|
191
35
|
|
|
192
|
-
if (config.showCost) {
|
|
193
|
-
sessionItems.push(`$${cost}`);
|
|
194
|
-
}
|
|
195
36
|
if (config.showTokens) {
|
|
196
|
-
|
|
197
|
-
if (config.showMaxTokens) {
|
|
198
|
-
const formattedMax = formatTokens(tokensMax, config.showTokenDecimals);
|
|
199
|
-
sessionItems.push(
|
|
200
|
-
`${formattedUsed}${colors.GRAY}/${formattedMax}${colors.LIGHT_GRAY}`,
|
|
201
|
-
);
|
|
202
|
-
} else {
|
|
203
|
-
sessionItems.push(formattedUsed);
|
|
204
|
-
}
|
|
37
|
+
items.push(formatTokens(tokens));
|
|
205
38
|
}
|
|
206
39
|
if (config.showPercentage) {
|
|
207
|
-
|
|
40
|
+
items.push(`${percentage}${colors.GRAY}%${colors.LIGHT_GRAY}`);
|
|
208
41
|
}
|
|
209
42
|
|
|
210
|
-
if (
|
|
43
|
+
if (items.length === 0) {
|
|
211
44
|
return "";
|
|
212
45
|
}
|
|
213
46
|
|
|
214
|
-
|
|
215
|
-
? ` ${colors.GRAY}${config.infoSeparator}${colors.LIGHT_GRAY} `
|
|
216
|
-
: " ";
|
|
217
|
-
return `${colors.GRAY}S:${colors.LIGHT_GRAY} ${sessionItems.join(infoSep)}`;
|
|
47
|
+
return `${colors.LIGHT_GRAY}${items.join(" ")}`;
|
|
218
48
|
}
|
|
@@ -1,122 +1,25 @@
|
|
|
1
|
-
export type Separator =
|
|
2
|
-
| "|"
|
|
3
|
-
| "•"
|
|
4
|
-
| "·"
|
|
5
|
-
| "⋅"
|
|
6
|
-
| "●"
|
|
7
|
-
| "◆"
|
|
8
|
-
| "▪"
|
|
9
|
-
| "▸"
|
|
10
|
-
| "›"
|
|
11
|
-
| "→";
|
|
12
|
-
|
|
13
1
|
export interface StatuslineConfig {
|
|
14
|
-
// Display everything on one line (separated by separator) or two lines
|
|
15
2
|
oneLine: boolean;
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
showSonnetModel: boolean;
|
|
19
|
-
|
|
20
|
-
// Path display mode:
|
|
21
|
-
// - "full": Show complete path with ~ substitution
|
|
22
|
-
// - "truncated": Show only last 2 segments
|
|
23
|
-
// - "basename": Show only the directory name
|
|
24
|
-
pathDisplayMode: "full" | "truncated" | "basename";
|
|
25
|
-
|
|
26
|
-
// Git display configuration
|
|
27
|
-
git: {
|
|
28
|
-
// Show current branch name
|
|
29
|
-
showBranch: boolean;
|
|
30
|
-
// Show * indicator when branch has changes
|
|
31
|
-
showDirtyIndicator: boolean;
|
|
32
|
-
// Show added/deleted lines count
|
|
33
|
-
showChanges: boolean;
|
|
34
|
-
// Show staged files count (gray color)
|
|
35
|
-
showStaged: boolean;
|
|
36
|
-
// Show unstaged files count (yellow color)
|
|
37
|
-
showUnstaged: boolean;
|
|
38
|
-
};
|
|
39
|
-
|
|
40
|
-
// Separator character between sections
|
|
41
|
-
// Options: "|", "•", "·", "⋅", "●", "◆", "▪", "▸", "›", "→"
|
|
42
|
-
separator: Separator;
|
|
43
|
-
|
|
44
|
-
// Session display configuration
|
|
3
|
+
pathDisplayMode: "full";
|
|
4
|
+
separator: "•";
|
|
45
5
|
session: {
|
|
46
|
-
// Separator character between session info (cost, tokens, percentage)
|
|
47
|
-
// Options: "|", "•", "·", "⋅", "●", "◆", "▪", "▸", "›", "→"
|
|
48
|
-
// Use null for single space separator
|
|
49
|
-
infoSeparator: Separator | null;
|
|
50
|
-
// Show session cost in USD
|
|
51
|
-
showCost: boolean;
|
|
52
|
-
// Show token count
|
|
53
6
|
showTokens: boolean;
|
|
54
|
-
// Show max tokens (e.g., "192k/200k" vs "192k")
|
|
55
|
-
showMaxTokens: boolean;
|
|
56
|
-
// Show decimals in token count (e.g., "192.1k" vs "192k")
|
|
57
|
-
showTokenDecimals: boolean;
|
|
58
|
-
// Show context percentage
|
|
59
7
|
showPercentage: boolean;
|
|
60
8
|
};
|
|
61
|
-
|
|
62
|
-
// Context display configuration
|
|
63
9
|
context: {
|
|
64
|
-
|
|
65
|
-
maxContextTokens: number;
|
|
66
|
-
// Autocompact buffer size (reserved for safety)
|
|
67
|
-
autocompactBufferTokens: number;
|
|
68
|
-
// Use only usable context (includes autocompact buffer in display) vs just transcript
|
|
69
|
-
useUsableContextOnly: boolean;
|
|
70
|
-
// Approximate tokens overhead for system (prompts, tools, memory files)
|
|
71
|
-
// Default ~20k includes: system prompts (~3k) + tools (~12k) + memory (~5k)
|
|
72
|
-
// Set to 0 to show only transcript tokens
|
|
73
|
-
overheadTokens: number;
|
|
74
|
-
};
|
|
75
|
-
|
|
76
|
-
// Limits display configuration
|
|
77
|
-
limits: {
|
|
78
|
-
// Show progress bar instead of just percentage
|
|
79
|
-
showProgressBar: boolean;
|
|
80
|
-
// Progress bar length (number of characters)
|
|
81
|
-
progressBarLength: 5 | 10;
|
|
82
|
-
// Progress bar color mode:
|
|
83
|
-
// - "progressive": Changes color based on usage (gray < 50%, yellow < 70%, orange < 90%, red >= 90%)
|
|
84
|
-
// - "green": Always green
|
|
85
|
-
// - "yellow": Always yellow
|
|
86
|
-
// - "red": Always red
|
|
87
|
-
color: "progressive" | "green" | "yellow" | "red";
|
|
10
|
+
maxContextTokens: 200000;
|
|
88
11
|
};
|
|
89
12
|
}
|
|
90
13
|
|
|
91
14
|
export const defaultConfig: StatuslineConfig = {
|
|
92
15
|
oneLine: true,
|
|
93
|
-
|
|
94
|
-
pathDisplayMode: "truncated",
|
|
95
|
-
git: {
|
|
96
|
-
showBranch: true,
|
|
97
|
-
showDirtyIndicator: true,
|
|
98
|
-
showChanges: false,
|
|
99
|
-
showStaged: true,
|
|
100
|
-
showUnstaged: true,
|
|
101
|
-
},
|
|
16
|
+
pathDisplayMode: "full",
|
|
102
17
|
separator: "•",
|
|
103
18
|
session: {
|
|
104
|
-
infoSeparator: null,
|
|
105
|
-
showCost: false,
|
|
106
19
|
showTokens: true,
|
|
107
|
-
showMaxTokens: false,
|
|
108
|
-
showTokenDecimals: false,
|
|
109
20
|
showPercentage: true,
|
|
110
21
|
},
|
|
111
22
|
context: {
|
|
112
23
|
maxContextTokens: 200000,
|
|
113
|
-
autocompactBufferTokens: 45000,
|
|
114
|
-
useUsableContextOnly: true,
|
|
115
|
-
overheadTokens: 0,
|
|
116
|
-
},
|
|
117
|
-
limits: {
|
|
118
|
-
showProgressBar: true,
|
|
119
|
-
progressBarLength: 5,
|
|
120
|
-
color: "progressive",
|
|
121
24
|
},
|
|
122
25
|
};
|