codeforge-dev 1.4.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/.devcontainer/.env +22 -0
- package/.devcontainer/CHANGELOG.md +197 -0
- package/.devcontainer/CLAUDE.md +117 -0
- package/.devcontainer/README.md +222 -0
- package/.devcontainer/config/main-system-prompt.md +502 -0
- package/.devcontainer/config/settings.json +47 -0
- package/.devcontainer/devcontainer.json +94 -0
- package/.devcontainer/features/README.md +113 -0
- package/.devcontainer/features/agent-browser/README.md +65 -0
- package/.devcontainer/features/agent-browser/devcontainer-feature.json +23 -0
- package/.devcontainer/features/agent-browser/install.sh +79 -0
- package/.devcontainer/features/ast-grep/README.md +24 -0
- package/.devcontainer/features/ast-grep/devcontainer-feature.json +24 -0
- package/.devcontainer/features/ast-grep/install.sh +51 -0
- package/.devcontainer/features/ccstatusline/README.md +296 -0
- package/.devcontainer/features/ccstatusline/devcontainer-feature.json +19 -0
- package/.devcontainer/features/ccstatusline/install.sh +290 -0
- package/.devcontainer/features/ccusage/README.md +205 -0
- package/.devcontainer/features/ccusage/devcontainer-feature.json +38 -0
- package/.devcontainer/features/ccusage/install.sh +132 -0
- package/.devcontainer/features/claude-code/README.md +498 -0
- package/.devcontainer/features/claude-code/config/settings.json +36 -0
- package/.devcontainer/features/claude-code/config/system-prompt.md +118 -0
- package/.devcontainer/features/claude-code/config/world-building-sp.md +1432 -0
- package/.devcontainer/features/claude-code/devcontainer-feature.json +42 -0
- package/.devcontainer/features/claude-code/install.sh +466 -0
- package/.devcontainer/features/claude-monitor/README.md +74 -0
- package/.devcontainer/features/claude-monitor/devcontainer-feature.json +38 -0
- package/.devcontainer/features/claude-monitor/install.sh +99 -0
- package/.devcontainer/features/lsp-servers/README.md +85 -0
- package/.devcontainer/features/lsp-servers/devcontainer-feature.json +40 -0
- package/.devcontainer/features/lsp-servers/install.sh +116 -0
- package/.devcontainer/features/mcp-qdrant/CHANGES.md +399 -0
- package/.devcontainer/features/mcp-qdrant/README.md +474 -0
- package/.devcontainer/features/mcp-qdrant/devcontainer-feature.json +57 -0
- package/.devcontainer/features/mcp-qdrant/install.sh +295 -0
- package/.devcontainer/features/mcp-qdrant/poststart-hook.sh +129 -0
- package/.devcontainer/features/mcp-reasoner/README.md +177 -0
- package/.devcontainer/features/mcp-reasoner/devcontainer-feature.json +20 -0
- package/.devcontainer/features/mcp-reasoner/install.sh +177 -0
- package/.devcontainer/features/mcp-reasoner/poststart-hook.sh +67 -0
- package/.devcontainer/features/notify-hook/README.md +86 -0
- package/.devcontainer/features/notify-hook/devcontainer-feature.json +23 -0
- package/.devcontainer/features/notify-hook/install.sh +38 -0
- package/.devcontainer/features/splitrail/README.md +140 -0
- package/.devcontainer/features/splitrail/devcontainer-feature.json +34 -0
- package/.devcontainer/features/splitrail/install.sh +129 -0
- package/.devcontainer/features/tree-sitter/README.md +138 -0
- package/.devcontainer/features/tree-sitter/devcontainer-feature.json +52 -0
- package/.devcontainer/features/tree-sitter/install.sh +173 -0
- package/.devcontainer/plugins/devs-marketplace/.claude-plugin/marketplace.json +106 -0
- package/.devcontainer/plugins/devs-marketplace/plugins/auto-formatter/.claude-plugin/plugin.json +7 -0
- package/.devcontainer/plugins/devs-marketplace/plugins/auto-formatter/hooks/hooks.json +17 -0
- package/.devcontainer/plugins/devs-marketplace/plugins/auto-formatter/scripts/format-file.py +101 -0
- package/.devcontainer/plugins/devs-marketplace/plugins/auto-linter/.claude-plugin/plugin.json +7 -0
- package/.devcontainer/plugins/devs-marketplace/plugins/auto-linter/hooks/hooks.json +17 -0
- package/.devcontainer/plugins/devs-marketplace/plugins/auto-linter/scripts/lint-file.py +137 -0
- package/.devcontainer/plugins/devs-marketplace/plugins/codedirective-skills/.claude-plugin/plugin.json +8 -0
- package/.devcontainer/plugins/devs-marketplace/plugins/codedirective-skills/skills/claude-code-headless/SKILL.md +387 -0
- package/.devcontainer/plugins/devs-marketplace/plugins/codedirective-skills/skills/claude-code-headless/references/cli-flags-and-output.md +312 -0
- package/.devcontainer/plugins/devs-marketplace/plugins/codedirective-skills/skills/claude-code-headless/references/sdk-and-mcp.md +569 -0
- package/.devcontainer/plugins/devs-marketplace/plugins/codedirective-skills/skills/docker/SKILL.md +309 -0
- package/.devcontainer/plugins/devs-marketplace/plugins/codedirective-skills/skills/docker/references/compose-services.md +438 -0
- package/.devcontainer/plugins/devs-marketplace/plugins/codedirective-skills/skills/docker/references/dockerfile-patterns.md +340 -0
- package/.devcontainer/plugins/devs-marketplace/plugins/codedirective-skills/skills/docker-py/SKILL.md +412 -0
- package/.devcontainer/plugins/devs-marketplace/plugins/codedirective-skills/skills/docker-py/references/container-lifecycle.md +388 -0
- package/.devcontainer/plugins/devs-marketplace/plugins/codedirective-skills/skills/docker-py/references/resources-and-security.md +444 -0
- package/.devcontainer/plugins/devs-marketplace/plugins/codedirective-skills/skills/fastapi/SKILL.md +344 -0
- package/.devcontainer/plugins/devs-marketplace/plugins/codedirective-skills/skills/fastapi/references/middleware-and-lifespan.md +254 -0
- package/.devcontainer/plugins/devs-marketplace/plugins/codedirective-skills/skills/fastapi/references/pydantic-models.md +245 -0
- package/.devcontainer/plugins/devs-marketplace/plugins/codedirective-skills/skills/fastapi/references/routing-and-dependencies.md +255 -0
- package/.devcontainer/plugins/devs-marketplace/plugins/codedirective-skills/skills/fastapi/references/sse-and-streaming.md +318 -0
- package/.devcontainer/plugins/devs-marketplace/plugins/codedirective-skills/skills/pydantic-ai/SKILL.md +345 -0
- package/.devcontainer/plugins/devs-marketplace/plugins/codedirective-skills/skills/pydantic-ai/references/agents-and-tools.md +271 -0
- package/.devcontainer/plugins/devs-marketplace/plugins/codedirective-skills/skills/pydantic-ai/references/models-and-streaming.md +422 -0
- package/.devcontainer/plugins/devs-marketplace/plugins/codedirective-skills/skills/skill-building/SKILL.md +220 -0
- package/.devcontainer/plugins/devs-marketplace/plugins/codedirective-skills/skills/skill-building/references/cross-vendor-principles.md +139 -0
- package/.devcontainer/plugins/devs-marketplace/plugins/codedirective-skills/skills/skill-building/references/patterns-and-antipatterns.md +376 -0
- package/.devcontainer/plugins/devs-marketplace/plugins/codedirective-skills/skills/skill-building/references/skill-authoring-patterns.md +356 -0
- package/.devcontainer/plugins/devs-marketplace/plugins/codedirective-skills/skills/sqlite/SKILL.md +329 -0
- package/.devcontainer/plugins/devs-marketplace/plugins/codedirective-skills/skills/sqlite/references/advanced-queries.md +314 -0
- package/.devcontainer/plugins/devs-marketplace/plugins/codedirective-skills/skills/sqlite/references/javascript-patterns.md +323 -0
- package/.devcontainer/plugins/devs-marketplace/plugins/codedirective-skills/skills/sqlite/references/python-patterns.md +354 -0
- package/.devcontainer/plugins/devs-marketplace/plugins/codedirective-skills/skills/sqlite/references/schema-and-pragmas.md +326 -0
- package/.devcontainer/plugins/devs-marketplace/plugins/codedirective-skills/skills/svelte5/SKILL.md +356 -0
- package/.devcontainer/plugins/devs-marketplace/plugins/codedirective-skills/skills/svelte5/references/ai-sdk-svelte.md +128 -0
- package/.devcontainer/plugins/devs-marketplace/plugins/codedirective-skills/skills/svelte5/references/component-patterns.md +332 -0
- package/.devcontainer/plugins/devs-marketplace/plugins/codedirective-skills/skills/svelte5/references/layercake.md +203 -0
- package/.devcontainer/plugins/devs-marketplace/plugins/codedirective-skills/skills/svelte5/references/migration-guide.md +350 -0
- package/.devcontainer/plugins/devs-marketplace/plugins/codedirective-skills/skills/svelte5/references/runes-and-reactivity.md +328 -0
- package/.devcontainer/plugins/devs-marketplace/plugins/codedirective-skills/skills/svelte5/references/spa-and-routing.md +262 -0
- package/.devcontainer/plugins/devs-marketplace/plugins/codedirective-skills/skills/svelte5/references/svelte-dnd-action.md +181 -0
- package/.devcontainer/plugins/devs-marketplace/plugins/codedirective-skills/skills/testing/SKILL.md +414 -0
- package/.devcontainer/plugins/devs-marketplace/plugins/codedirective-skills/skills/testing/references/fastapi-testing.md +411 -0
- package/.devcontainer/plugins/devs-marketplace/plugins/codedirective-skills/skills/testing/references/svelte-testing.md +538 -0
- package/.devcontainer/plugins/devs-marketplace/plugins/codeforge-lsp/.claude-plugin/plugin.json +7 -0
- package/.devcontainer/plugins/devs-marketplace/plugins/dangerous-command-blocker/.claude-plugin/plugin.json +7 -0
- package/.devcontainer/plugins/devs-marketplace/plugins/dangerous-command-blocker/hooks/hooks.json +17 -0
- package/.devcontainer/plugins/devs-marketplace/plugins/dangerous-command-blocker/scripts/block-dangerous.py +110 -0
- package/.devcontainer/plugins/devs-marketplace/plugins/notify-hook/.claude-plugin/plugin.json +7 -0
- package/.devcontainer/plugins/devs-marketplace/plugins/notify-hook/hooks/hooks.json +17 -0
- package/.devcontainer/plugins/devs-marketplace/plugins/planning-reminder/.claude-plugin/plugin.json +7 -0
- package/.devcontainer/plugins/devs-marketplace/plugins/planning-reminder/hooks/hooks.json +17 -0
- package/.devcontainer/plugins/devs-marketplace/plugins/protected-files-guard/.claude-plugin/plugin.json +7 -0
- package/.devcontainer/plugins/devs-marketplace/plugins/protected-files-guard/hooks/hooks.json +17 -0
- package/.devcontainer/plugins/devs-marketplace/plugins/protected-files-guard/scripts/guard-protected.py +108 -0
- package/.devcontainer/plugins/devs-marketplace/plugins/ticket-workflow/.claude-plugin/commands/ticket/357/200/272create-pr.md +337 -0
- package/.devcontainer/plugins/devs-marketplace/plugins/ticket-workflow/.claude-plugin/commands/ticket/357/200/272new.md +166 -0
- package/.devcontainer/plugins/devs-marketplace/plugins/ticket-workflow/.claude-plugin/commands/ticket/357/200/272review-commit.md +290 -0
- package/.devcontainer/plugins/devs-marketplace/plugins/ticket-workflow/.claude-plugin/commands/ticket/357/200/272work.md +257 -0
- package/.devcontainer/plugins/devs-marketplace/plugins/ticket-workflow/.claude-plugin/plugin.json +8 -0
- package/.devcontainer/plugins/devs-marketplace/plugins/ticket-workflow/.claude-plugin/system-prompt.md +184 -0
- package/.devcontainer/plugins/devs-marketplace/plugins/workflow-enhancer/.claude-plugin/plugin.json +6 -0
- package/.devcontainer/plugins/devs-marketplace/plugins/workflow-enhancer/config/planning-instructions.md +14 -0
- package/.devcontainer/plugins/devs-marketplace/plugins/workflow-enhancer/functional-conjuring-map.md +989 -0
- package/.devcontainer/plugins/devs-marketplace/plugins/workflow-enhancer/hooks/hooks.json +33 -0
- package/.devcontainer/plugins/devs-marketplace/plugins/workflow-enhancer/scripts/__pycache__/post-enhance-task.cpython-314.pyc +0 -0
- package/.devcontainer/plugins/devs-marketplace/plugins/workflow-enhancer/scripts/enhance-planning.py +71 -0
- package/.devcontainer/plugins/devs-marketplace/plugins/workflow-enhancer/scripts/enhancers/enhance-plan.sh +68 -0
- package/.devcontainer/plugins/devs-marketplace/plugins/workflow-enhancer/scripts/enhancers/enhance-task.sh +120 -0
- package/.devcontainer/plugins/devs-marketplace/plugins/workflow-enhancer/scripts/post-enhance-plan.py +133 -0
- package/.devcontainer/plugins/devs-marketplace/plugins/workflow-enhancer/scripts/post-enhance-task.py +253 -0
- package/.devcontainer/scripts/setup-aliases.sh +80 -0
- package/.devcontainer/scripts/setup-config.sh +28 -0
- package/.devcontainer/scripts/setup-irie-claude.sh +32 -0
- package/.devcontainer/scripts/setup-plugins.sh +80 -0
- package/.devcontainer/scripts/setup.sh +58 -0
- package/LICENSE.txt +674 -0
- package/README.md +267 -0
- package/package.json +44 -0
- package/setup.js +83 -0
|
@@ -0,0 +1,290 @@
|
|
|
1
|
+
#!/bin/bash
|
|
2
|
+
set -euo pipefail
|
|
3
|
+
|
|
4
|
+
# Cleanup on exit
|
|
5
|
+
cleanup() {
|
|
6
|
+
rm -f /tmp/ccstatusline-*.json 2>/dev/null || true
|
|
7
|
+
}
|
|
8
|
+
trap cleanup EXIT
|
|
9
|
+
|
|
10
|
+
# Import options from devcontainer-feature.json
|
|
11
|
+
# NOTE: DevContainer converts camelCase options to UPPERCASE without underscores
|
|
12
|
+
USERNAME="${USERNAME:-automatic}"
|
|
13
|
+
|
|
14
|
+
echo "[ccstatusline] Starting installation..."
|
|
15
|
+
|
|
16
|
+
# Source NVM (Node is installed via NVM by the node feature)
|
|
17
|
+
if [ -f /usr/local/share/nvm/nvm.sh ]; then
|
|
18
|
+
source /usr/local/share/nvm/nvm.sh
|
|
19
|
+
fi
|
|
20
|
+
|
|
21
|
+
# Validate jq is available (required for JSON generation)
|
|
22
|
+
if ! command -v jq &>/dev/null; then
|
|
23
|
+
echo "[ccstatusline] ERROR: jq is not available"
|
|
24
|
+
echo " Install common-utils feature first"
|
|
25
|
+
exit 1
|
|
26
|
+
fi
|
|
27
|
+
|
|
28
|
+
# Validate npm/npx is available
|
|
29
|
+
if ! command -v npm &>/dev/null && ! command -v npx &>/dev/null; then
|
|
30
|
+
echo "[ccstatusline] ERROR: npm/npx is not available"
|
|
31
|
+
echo " Install node feature first"
|
|
32
|
+
echo " NVM path: /usr/local/share/nvm/nvm.sh"
|
|
33
|
+
exit 1
|
|
34
|
+
fi
|
|
35
|
+
|
|
36
|
+
# Determine the user
|
|
37
|
+
if [ "${USERNAME}" = "auto" ] || [ "${USERNAME}" = "automatic" ]; then
|
|
38
|
+
USERNAME=""
|
|
39
|
+
for CURRENT_USER in vscode node codespace; do
|
|
40
|
+
if id -u "${CURRENT_USER}" >/dev/null 2>&1; then
|
|
41
|
+
USERNAME=${CURRENT_USER}
|
|
42
|
+
break
|
|
43
|
+
fi
|
|
44
|
+
done
|
|
45
|
+
[ -z "${USERNAME}" ] && USERNAME=root
|
|
46
|
+
elif [ "${USERNAME}" = "none" ] || ! id -u "${USERNAME}" >/dev/null 2>&1; then
|
|
47
|
+
USERNAME=root
|
|
48
|
+
fi
|
|
49
|
+
|
|
50
|
+
echo "[ccstatusline] Installing for user: ${USERNAME}"
|
|
51
|
+
|
|
52
|
+
# Get user's home directory
|
|
53
|
+
USER_HOME=$(eval echo ~${USERNAME})
|
|
54
|
+
|
|
55
|
+
# Check if ccstatusline is available
|
|
56
|
+
if sudo -u "${USERNAME}" bash -c 'npx -y ccstatusline@latest --version' &>/dev/null 2>&1; then
|
|
57
|
+
echo "[ccstatusline] ccstatusline already available via npx"
|
|
58
|
+
else
|
|
59
|
+
echo "[ccstatusline] ccstatusline will be cached on first use via npx"
|
|
60
|
+
fi
|
|
61
|
+
|
|
62
|
+
echo "[ccstatusline] Generating powerline configuration..."
|
|
63
|
+
|
|
64
|
+
# Generate powerline configuration using jq (ANSI colors - same as module)
|
|
65
|
+
CONFIG_JSON=$(jq -n '{
|
|
66
|
+
version: 3,
|
|
67
|
+
lines: [
|
|
68
|
+
[
|
|
69
|
+
{id: "1", type: "context-length", color: "cyan"},
|
|
70
|
+
{id: "3", type: "git-branch", color: "brightBlack"},
|
|
71
|
+
{id: "5", type: "tokens-input", color: "magenta"},
|
|
72
|
+
{id: "7", type: "session-clock", color: "yellow"},
|
|
73
|
+
{id: "1eafc42e-f222-4090-a463-46de6ba81849", type: "output-style", backgroundColor: "bgBrightBlack"}
|
|
74
|
+
],
|
|
75
|
+
[
|
|
76
|
+
{id: "db519d5a-80a7-4b44-8a9c-2c7d8c0a7176", type: "context-percentage-usable", backgroundColor: "bgRed"},
|
|
77
|
+
{id: "a529e50e-b9f3-4150-a812-937ab81545e8", type: "git-changes", backgroundColor: "bgBrightBlue"},
|
|
78
|
+
{id: "ac094d46-3673-4d41-84e3-dc8c5bcf639f", type: "tokens-output", backgroundColor: "bgMagenta"},
|
|
79
|
+
{id: "90aae111-3d3f-4bb0-8336-230f322cc2e8", type: "block-timer", backgroundColor: "bgYellow"},
|
|
80
|
+
{id: "d904cca6-ade8-41c1-a4f5-ddea30607a5e", type: "model", backgroundColor: "bgMagenta"}
|
|
81
|
+
],
|
|
82
|
+
[
|
|
83
|
+
{id: "9bacbdb4-2e01-45de-a0c0-ee6ec30fa3c2", type: "tokens-total", backgroundColor: "bgGreen"},
|
|
84
|
+
{id: "a9eaae3f-7f91-459c-833a-fbc9f01a09ae", type: "git-worktree", backgroundColor: "bgBrightBlue"},
|
|
85
|
+
{id: "2ad12147-05fd-45fb-8336-53ba2e7df56c", type: "tokens-cached", backgroundColor: "bgBrightRed"},
|
|
86
|
+
{id: "a4fe7f75-2f6c-49c7-88f6-ac7381142c2c", type: "session-cost", backgroundColor: "bgBrightWhite"},
|
|
87
|
+
{id: "2cdff909-8297-44a1-83f9-ad4bf024391e", type: "version", backgroundColor: "bgRed"}
|
|
88
|
+
]
|
|
89
|
+
],
|
|
90
|
+
flexMode: "full-minus-40",
|
|
91
|
+
compactThreshold: 60,
|
|
92
|
+
colorLevel: 2,
|
|
93
|
+
inheritSeparatorColors: false,
|
|
94
|
+
globalBold: false,
|
|
95
|
+
powerline: {
|
|
96
|
+
enabled: true,
|
|
97
|
+
separators: [""],
|
|
98
|
+
separatorInvertBackground: [true],
|
|
99
|
+
startCaps: [""],
|
|
100
|
+
endCaps: [""],
|
|
101
|
+
autoAlign: false,
|
|
102
|
+
theme: "monokai"
|
|
103
|
+
},
|
|
104
|
+
defaultPadding: " "
|
|
105
|
+
}')
|
|
106
|
+
|
|
107
|
+
# Validate generated config
|
|
108
|
+
if ! echo "${CONFIG_JSON}" | jq empty 2>/dev/null; then
|
|
109
|
+
echo "[ccstatusline] ERROR: Generated configuration is invalid JSON"
|
|
110
|
+
exit 1
|
|
111
|
+
fi
|
|
112
|
+
|
|
113
|
+
echo "[ccstatusline] Writing configuration..."
|
|
114
|
+
|
|
115
|
+
CONFIG_DIR="${USER_HOME}/.config/ccstatusline"
|
|
116
|
+
CONFIG_FILE="${CONFIG_DIR}/settings.json"
|
|
117
|
+
|
|
118
|
+
# Create directory
|
|
119
|
+
mkdir -p "${CONFIG_DIR}"
|
|
120
|
+
|
|
121
|
+
# Write config using secure temp file
|
|
122
|
+
TEMP_CONFIG=$(mktemp)
|
|
123
|
+
chmod 644 "${TEMP_CONFIG}"
|
|
124
|
+
echo "${CONFIG_JSON}" | jq . > "${TEMP_CONFIG}"
|
|
125
|
+
|
|
126
|
+
# Move to final location
|
|
127
|
+
mv "${TEMP_CONFIG}" "${CONFIG_FILE}"
|
|
128
|
+
|
|
129
|
+
# Set ownership
|
|
130
|
+
if ! chown "${USERNAME}:${USERNAME}" "${CONFIG_FILE}" 2>/dev/null; then
|
|
131
|
+
echo "[ccstatusline] WARNING: Could not set ownership on ${CONFIG_FILE}"
|
|
132
|
+
echo " Fix: sudo chown ${USERNAME}:${USERNAME} ${CONFIG_FILE}"
|
|
133
|
+
fi
|
|
134
|
+
|
|
135
|
+
if ! chown "${USERNAME}:${USERNAME}" "${CONFIG_DIR}" 2>/dev/null; then
|
|
136
|
+
echo "[ccstatusline] WARNING: Could not set ownership on ${CONFIG_DIR}"
|
|
137
|
+
fi
|
|
138
|
+
|
|
139
|
+
echo "[ccstatusline] ✓ Configuration written to ${CONFIG_FILE}"
|
|
140
|
+
|
|
141
|
+
# Create template directory and save config template
|
|
142
|
+
echo "[ccstatusline] Creating configuration template..."
|
|
143
|
+
mkdir -p /usr/local/share/ccstatusline
|
|
144
|
+
TEMPLATE_FILE=/usr/local/share/ccstatusline/settings.template.json
|
|
145
|
+
echo "${CONFIG_JSON}" | jq . > "${TEMPLATE_FILE}"
|
|
146
|
+
chmod 644 "${TEMPLATE_FILE}"
|
|
147
|
+
echo "[ccstatusline] ✓ Template saved to ${TEMPLATE_FILE}"
|
|
148
|
+
|
|
149
|
+
# Create wrapper script to protect configuration
|
|
150
|
+
echo "[ccstatusline] Creating wrapper script..."
|
|
151
|
+
cat > /usr/local/bin/ccstatusline-wrapper <<'WRAPPER_EOF'
|
|
152
|
+
#!/bin/bash
|
|
153
|
+
# ccstatusline wrapper script
|
|
154
|
+
# Ensures custom powerline configuration is valid before running ccstatusline
|
|
155
|
+
|
|
156
|
+
set -euo pipefail
|
|
157
|
+
|
|
158
|
+
CONFIG_FILE="$HOME/.config/ccstatusline/settings.json"
|
|
159
|
+
TEMPLATE_FILE="/usr/local/share/ccstatusline/settings.template.json"
|
|
160
|
+
|
|
161
|
+
# Ensure config directory exists
|
|
162
|
+
mkdir -p "$HOME/.config/ccstatusline"
|
|
163
|
+
|
|
164
|
+
# Function to check if config is valid
|
|
165
|
+
is_config_valid() {
|
|
166
|
+
if [[ ! -f "$CONFIG_FILE" ]]; then
|
|
167
|
+
return 1
|
|
168
|
+
fi
|
|
169
|
+
|
|
170
|
+
# Check if powerline is enabled (key indicator of custom config)
|
|
171
|
+
if ! grep -q '"enabled"[[:space:]]*:[[:space:]]*true' "$CONFIG_FILE" 2>/dev/null; then
|
|
172
|
+
return 1
|
|
173
|
+
fi
|
|
174
|
+
|
|
175
|
+
# Check if ANSI colors are present (backgroundColor with bg prefix)
|
|
176
|
+
if ! grep -q 'bgRed\|bgMagenta\|bgGreen\|bgBrightBlue' "$CONFIG_FILE" 2>/dev/null; then
|
|
177
|
+
return 1
|
|
178
|
+
fi
|
|
179
|
+
|
|
180
|
+
# Validate JSON syntax
|
|
181
|
+
if ! jq empty "$CONFIG_FILE" 2>/dev/null; then
|
|
182
|
+
return 1
|
|
183
|
+
fi
|
|
184
|
+
|
|
185
|
+
return 0
|
|
186
|
+
}
|
|
187
|
+
|
|
188
|
+
# Restore config from template if missing or invalid
|
|
189
|
+
if ! is_config_valid; then
|
|
190
|
+
if [[ -f "$TEMPLATE_FILE" ]]; then
|
|
191
|
+
cp "$TEMPLATE_FILE" "$CONFIG_FILE"
|
|
192
|
+
chmod 644 "$CONFIG_FILE"
|
|
193
|
+
else
|
|
194
|
+
echo "[ccstatusline-wrapper] ERROR: Template file not found at $TEMPLATE_FILE" >&2
|
|
195
|
+
exit 1
|
|
196
|
+
fi
|
|
197
|
+
fi
|
|
198
|
+
|
|
199
|
+
# Run ccstatusline with all passed arguments
|
|
200
|
+
exec npx -y ccstatusline@latest "$@"
|
|
201
|
+
WRAPPER_EOF
|
|
202
|
+
|
|
203
|
+
chmod +x /usr/local/bin/ccstatusline-wrapper
|
|
204
|
+
echo "[ccstatusline] ✓ Wrapper installed at /usr/local/bin/ccstatusline-wrapper"
|
|
205
|
+
|
|
206
|
+
# Create post-start hook directory (standard pattern for DevContainer features)
|
|
207
|
+
mkdir -p /usr/local/devcontainer-poststart.d
|
|
208
|
+
|
|
209
|
+
# Create post-start hook script for Claude Code integration
|
|
210
|
+
# Runs on EVERY container start to ensure statusLine is always configured
|
|
211
|
+
# This handles cached images, config deletion, and corruption scenarios
|
|
212
|
+
# Note: Uses prefix 40 to run before MCP servers (50-51) to ensure settings.json exists first
|
|
213
|
+
cat > /usr/local/devcontainer-poststart.d/40-ccstatusline.sh <<'AUTOEOF'
|
|
214
|
+
#!/bin/bash
|
|
215
|
+
set -euo pipefail
|
|
216
|
+
|
|
217
|
+
echo "[ccstatusline] Auto-configuring Claude Code integration..."
|
|
218
|
+
|
|
219
|
+
# Validate prerequisites
|
|
220
|
+
if ! command -v jq &>/dev/null; then
|
|
221
|
+
echo "[ccstatusline] ERROR: jq is not available"
|
|
222
|
+
echo " Ensure common-utils feature is installed"
|
|
223
|
+
exit 1
|
|
224
|
+
fi
|
|
225
|
+
|
|
226
|
+
SETTINGS_FILE="${WORKSPACE_ROOT:-/workspaces}/.claude/settings.json"
|
|
227
|
+
# Use SUDO_USER since _REMOTE_USER isn't set in post-start hooks
|
|
228
|
+
USERNAME="${SUDO_USER:-vscode}"
|
|
229
|
+
|
|
230
|
+
# Ensure directory exists
|
|
231
|
+
mkdir -p "$(dirname "${SETTINGS_FILE}")"
|
|
232
|
+
|
|
233
|
+
# Initialize settings.json if missing
|
|
234
|
+
if [ ! -f "${SETTINGS_FILE}" ]; then
|
|
235
|
+
echo '{}' > "${SETTINGS_FILE}"
|
|
236
|
+
fi
|
|
237
|
+
|
|
238
|
+
# Add statusLine configuration (atomic) - use wrapper to protect config
|
|
239
|
+
jq '.statusLine //= {}' "${SETTINGS_FILE}" | \
|
|
240
|
+
jq '.statusLine = {
|
|
241
|
+
type: "command",
|
|
242
|
+
command: "/usr/local/bin/ccstatusline-wrapper"
|
|
243
|
+
}' > "${SETTINGS_FILE}.tmp"
|
|
244
|
+
|
|
245
|
+
# Atomic move (only if jq succeeded)
|
|
246
|
+
if [ $? -eq 0 ]; then
|
|
247
|
+
mv "${SETTINGS_FILE}.tmp" "${SETTINGS_FILE}"
|
|
248
|
+
if ! chown "${USERNAME}:${USERNAME}" "${SETTINGS_FILE}" 2>/dev/null; then
|
|
249
|
+
echo "[ccstatusline] WARNING: Could not set ownership on ${SETTINGS_FILE}"
|
|
250
|
+
fi
|
|
251
|
+
echo "[ccstatusline] ✓ Configured in ${SETTINGS_FILE}"
|
|
252
|
+
echo "[ccstatusline] Verify: cat ${SETTINGS_FILE} | jq '.statusLine'"
|
|
253
|
+
else
|
|
254
|
+
rm -f "${SETTINGS_FILE}.tmp"
|
|
255
|
+
echo "[ccstatusline] ERROR: Configuration failed"
|
|
256
|
+
exit 1
|
|
257
|
+
fi
|
|
258
|
+
AUTOEOF
|
|
259
|
+
|
|
260
|
+
chmod +x /usr/local/devcontainer-poststart.d/40-ccstatusline.sh
|
|
261
|
+
echo "[ccstatusline] ✓ Post-start hook created at /usr/local/devcontainer-poststart.d/40-ccstatusline.sh"
|
|
262
|
+
echo ""
|
|
263
|
+
echo "━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━"
|
|
264
|
+
echo " ccstatusline Installation Complete"
|
|
265
|
+
echo "━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━"
|
|
266
|
+
echo ""
|
|
267
|
+
echo "Configuration:"
|
|
268
|
+
echo " • Config file: ${CONFIG_FILE}"
|
|
269
|
+
echo " • User: ${USERNAME}"
|
|
270
|
+
echo " • Theme: Powerline (3 lines, 13 widgets, ANSI colors)"
|
|
271
|
+
echo " • Protected by: /usr/local/bin/ccstatusline-wrapper"
|
|
272
|
+
echo ""
|
|
273
|
+
echo "Display:"
|
|
274
|
+
echo " Line 1: Context | Git Branch | Tokens In | Clock | Output Style"
|
|
275
|
+
echo " Line 2: Context % | Git Changes | Tokens Out | Block Timer | Model"
|
|
276
|
+
echo " Line 3: Tokens Total | Git Worktree | Cached | Cost | Version"
|
|
277
|
+
echo ""
|
|
278
|
+
echo "━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━"
|
|
279
|
+
echo " Next Steps"
|
|
280
|
+
echo "━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━"
|
|
281
|
+
echo ""
|
|
282
|
+
echo "1. Configuration will be applied automatically on container creation"
|
|
283
|
+
echo ""
|
|
284
|
+
echo "2. Test manually:"
|
|
285
|
+
echo " echo '{\"model\":{\"display_name\":\"Test\"}}' | npx -y ccstatusline@latest"
|
|
286
|
+
echo ""
|
|
287
|
+
echo "3. View configuration:"
|
|
288
|
+
echo " cat ${CONFIG_FILE} | jq ."
|
|
289
|
+
echo ""
|
|
290
|
+
echo "━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━"
|
|
@@ -0,0 +1,205 @@
|
|
|
1
|
+
# ccusage - Claude Code Usage Analyzer
|
|
2
|
+
|
|
3
|
+
A DevContainer feature that installs the ccusage CLI tool for analyzing Claude Code and Codex token usage from local JSONL files.
|
|
4
|
+
|
|
5
|
+
## Overview
|
|
6
|
+
|
|
7
|
+
ccusage tracks token usage and costs across daily, monthly, and session-based reports with live monitoring capabilities. This feature configures shell aliases for easy access to the tool via `npx`.
|
|
8
|
+
|
|
9
|
+
## Installation
|
|
10
|
+
|
|
11
|
+
Add this feature to your `.devcontainer/devcontainer.json`:
|
|
12
|
+
|
|
13
|
+
```json
|
|
14
|
+
{
|
|
15
|
+
"features": {
|
|
16
|
+
"ghcr.io/devcontainers/features/node:1": {},
|
|
17
|
+
"./features/ccusage": {}
|
|
18
|
+
}
|
|
19
|
+
}
|
|
20
|
+
```
|
|
21
|
+
|
|
22
|
+
### With Custom Options
|
|
23
|
+
|
|
24
|
+
```json
|
|
25
|
+
{
|
|
26
|
+
"features": {
|
|
27
|
+
"ghcr.io/devcontainers/features/node:1": {},
|
|
28
|
+
"./features/ccusage": {
|
|
29
|
+
"version": "latest",
|
|
30
|
+
"shells": "both",
|
|
31
|
+
"username": "automatic"
|
|
32
|
+
}
|
|
33
|
+
}
|
|
34
|
+
}
|
|
35
|
+
```
|
|
36
|
+
|
|
37
|
+
## Options
|
|
38
|
+
|
|
39
|
+
| Option | Type | Default | Description |
|
|
40
|
+
|--------|------|---------|-------------|
|
|
41
|
+
| `version` | string | `latest` | ccusage version to use (e.g., 'latest', '1.0.0') |
|
|
42
|
+
| `shells` | string | `both` | Which shells to configure: `bash`, `zsh`, or `both` |
|
|
43
|
+
| `username` | string | `automatic` | Container user to install for (auto-detects vscode/node/codespace) |
|
|
44
|
+
|
|
45
|
+
## Usage
|
|
46
|
+
|
|
47
|
+
Once installed, use the `ccusage` command from any shell:
|
|
48
|
+
|
|
49
|
+
### Daily Usage Report
|
|
50
|
+
```bash
|
|
51
|
+
ccusage --daily
|
|
52
|
+
```
|
|
53
|
+
Shows token usage and costs for today.
|
|
54
|
+
|
|
55
|
+
### Monthly Report
|
|
56
|
+
```bash
|
|
57
|
+
ccusage --monthly
|
|
58
|
+
```
|
|
59
|
+
Displays monthly token consumption and costs.
|
|
60
|
+
|
|
61
|
+
### Live Monitoring
|
|
62
|
+
```bash
|
|
63
|
+
ccusage --live
|
|
64
|
+
```
|
|
65
|
+
Real-time monitoring of your Claude Code usage.
|
|
66
|
+
|
|
67
|
+
### JSON Output
|
|
68
|
+
```bash
|
|
69
|
+
ccusage --json
|
|
70
|
+
```
|
|
71
|
+
Output data in JSON format for scripting/integration.
|
|
72
|
+
|
|
73
|
+
### Compact Display
|
|
74
|
+
```bash
|
|
75
|
+
ccusage --compact
|
|
76
|
+
```
|
|
77
|
+
Minimal output for quick checks.
|
|
78
|
+
|
|
79
|
+
## Features
|
|
80
|
+
|
|
81
|
+
- **Beautiful Tables**: Formatted output with clear cost breakdown
|
|
82
|
+
- **Multiple Models**: Supports Claude Opus, Sonnet, and other models
|
|
83
|
+
- **Timezone Support**: Customize timezone and locale settings
|
|
84
|
+
- **Session Tracking**: View usage by individual sessions
|
|
85
|
+
- **Cost Tracking**: Accurate pricing for different models
|
|
86
|
+
|
|
87
|
+
## How It Works
|
|
88
|
+
|
|
89
|
+
This feature creates a shell alias that points to `npx -y ccusage@<version>`, which automatically downloads and runs the latest version of ccusage without requiring a global installation.
|
|
90
|
+
|
|
91
|
+
ccusage automatically reads from Claude Code's JSONL usage logs located in:
|
|
92
|
+
- `~/.claude/` (default)
|
|
93
|
+
- `$CLAUDE_CONFIG_DIR` (if customized)
|
|
94
|
+
|
|
95
|
+
## Advanced Options
|
|
96
|
+
|
|
97
|
+
For full list of ccusage command options:
|
|
98
|
+
```bash
|
|
99
|
+
ccusage --help
|
|
100
|
+
```
|
|
101
|
+
|
|
102
|
+
## Example Configurations
|
|
103
|
+
|
|
104
|
+
### Install for Specific User (zsh only)
|
|
105
|
+
```json
|
|
106
|
+
{
|
|
107
|
+
"features": {
|
|
108
|
+
"./features/ccusage": {
|
|
109
|
+
"username": "vscode",
|
|
110
|
+
"shells": "zsh"
|
|
111
|
+
}
|
|
112
|
+
}
|
|
113
|
+
}
|
|
114
|
+
```
|
|
115
|
+
|
|
116
|
+
### Pin to Specific Version
|
|
117
|
+
```json
|
|
118
|
+
{
|
|
119
|
+
"features": {
|
|
120
|
+
"./features/ccusage": {
|
|
121
|
+
"version": "1.0.0"
|
|
122
|
+
}
|
|
123
|
+
}
|
|
124
|
+
}
|
|
125
|
+
```
|
|
126
|
+
|
|
127
|
+
### Bash Only Installation
|
|
128
|
+
```json
|
|
129
|
+
{
|
|
130
|
+
"features": {
|
|
131
|
+
"./features/ccusage": {
|
|
132
|
+
"shells": "bash"
|
|
133
|
+
}
|
|
134
|
+
}
|
|
135
|
+
}
|
|
136
|
+
```
|
|
137
|
+
|
|
138
|
+
## Troubleshooting
|
|
139
|
+
|
|
140
|
+
### Command Not Found
|
|
141
|
+
|
|
142
|
+
If `ccusage` is not found after installation:
|
|
143
|
+
|
|
144
|
+
1. **Reload your shell**:
|
|
145
|
+
```bash
|
|
146
|
+
source ~/.bashrc # for bash
|
|
147
|
+
source ~/.zshrc # for zsh
|
|
148
|
+
```
|
|
149
|
+
|
|
150
|
+
2. **Check if alias is configured**:
|
|
151
|
+
```bash
|
|
152
|
+
grep ccusage ~/.bashrc # for bash
|
|
153
|
+
grep ccusage ~/.zshrc # for zsh
|
|
154
|
+
```
|
|
155
|
+
|
|
156
|
+
3. **Verify npx is available**:
|
|
157
|
+
```bash
|
|
158
|
+
npx --version
|
|
159
|
+
```
|
|
160
|
+
|
|
161
|
+
### Permission Errors
|
|
162
|
+
|
|
163
|
+
If you see permission errors:
|
|
164
|
+
```bash
|
|
165
|
+
sudo chown -R $(whoami):$(whoami) ~/.bashrc
|
|
166
|
+
sudo chown -R $(whoami):$(whoami) ~/.zshrc
|
|
167
|
+
```
|
|
168
|
+
|
|
169
|
+
### Network Issues
|
|
170
|
+
|
|
171
|
+
If ccusage fails to download:
|
|
172
|
+
- Check your internet connection
|
|
173
|
+
- The tool will be cached after first successful download
|
|
174
|
+
- Try running manually: `npx -y ccusage@latest --version`
|
|
175
|
+
|
|
176
|
+
## Dependencies
|
|
177
|
+
|
|
178
|
+
This feature requires:
|
|
179
|
+
- **Node.js**: Install the `node` feature first
|
|
180
|
+
- The feature automatically declares this dependency via `installsAfter`
|
|
181
|
+
|
|
182
|
+
## Integration with Other Tools
|
|
183
|
+
|
|
184
|
+
This tool complements:
|
|
185
|
+
- **splitrail**: Real-time monitoring during active sessions
|
|
186
|
+
- **ccstatusline**: Visual status display in terminal
|
|
187
|
+
|
|
188
|
+
## Links
|
|
189
|
+
|
|
190
|
+
- **GitHub**: https://github.com/ryoppippi/ccusage
|
|
191
|
+
- **NPM**: https://www.npmjs.com/package/ccusage
|
|
192
|
+
- **DevContainer Features**: https://containers.dev/features
|
|
193
|
+
|
|
194
|
+
## Version History
|
|
195
|
+
|
|
196
|
+
### 1.0.0
|
|
197
|
+
- Initial release as DevContainer feature
|
|
198
|
+
- Automatic user detection
|
|
199
|
+
- Configurable shell support (bash/zsh/both)
|
|
200
|
+
- Version pinning support
|
|
201
|
+
- Idempotent installation
|
|
202
|
+
|
|
203
|
+
## License
|
|
204
|
+
|
|
205
|
+
This feature wrapper follows the same license as the underlying ccusage tool.
|
|
@@ -0,0 +1,38 @@
|
|
|
1
|
+
{
|
|
2
|
+
"id": "ccusage",
|
|
3
|
+
"version": "1.0.0",
|
|
4
|
+
"name": "ccusage - Claude Code Usage Analyzer",
|
|
5
|
+
"description": "Installs ccusage CLI tool for analyzing Claude Code token usage",
|
|
6
|
+
"maintainer": "AnExiledDev",
|
|
7
|
+
"documentationURL": "https://github.com/ryoppippi/ccusage",
|
|
8
|
+
"options": {
|
|
9
|
+
"version": {
|
|
10
|
+
"type": "string",
|
|
11
|
+
"description": "ccusage version to use (e.g., 'latest', '1.0.0')",
|
|
12
|
+
"default": "latest"
|
|
13
|
+
},
|
|
14
|
+
"shells": {
|
|
15
|
+
"type": "string",
|
|
16
|
+
"description": "Which shells to configure (bash, zsh, or both)",
|
|
17
|
+
"default": "both",
|
|
18
|
+
"enum": [
|
|
19
|
+
"bash",
|
|
20
|
+
"zsh",
|
|
21
|
+
"both"
|
|
22
|
+
],
|
|
23
|
+
"proposals": [
|
|
24
|
+
"bash",
|
|
25
|
+
"zsh",
|
|
26
|
+
"both"
|
|
27
|
+
]
|
|
28
|
+
},
|
|
29
|
+
"username": {
|
|
30
|
+
"type": "string",
|
|
31
|
+
"description": "Container user to install for",
|
|
32
|
+
"default": "automatic"
|
|
33
|
+
}
|
|
34
|
+
},
|
|
35
|
+
"installsAfter": [
|
|
36
|
+
"ghcr.io/devcontainers/features/node:1"
|
|
37
|
+
]
|
|
38
|
+
}
|
|
@@ -0,0 +1,132 @@
|
|
|
1
|
+
#!/bin/bash
|
|
2
|
+
set -euo pipefail
|
|
3
|
+
|
|
4
|
+
# === SETUP ===
|
|
5
|
+
cleanup() {
|
|
6
|
+
# No temp files needed for this simple feature
|
|
7
|
+
:
|
|
8
|
+
}
|
|
9
|
+
trap cleanup EXIT
|
|
10
|
+
|
|
11
|
+
# === IMPORT OPTIONS ===
|
|
12
|
+
# NOTE: DevContainer converts camelCase options to UPPERCASE without underscores
|
|
13
|
+
# "version" → VERSION, "shells" → SHELLS, "username" → USERNAME
|
|
14
|
+
CCUSAGE_VERSION="${VERSION:-latest}"
|
|
15
|
+
SHELLS="${SHELLS:-both}"
|
|
16
|
+
USERNAME="${USERNAME:-automatic}"
|
|
17
|
+
|
|
18
|
+
echo "[ccusage] Starting ccusage installation..."
|
|
19
|
+
|
|
20
|
+
# === SOURCE NVM ===
|
|
21
|
+
# Node is installed via NVM by the node feature
|
|
22
|
+
if [ -f /usr/local/share/nvm/nvm.sh ]; then
|
|
23
|
+
source /usr/local/share/nvm/nvm.sh
|
|
24
|
+
fi
|
|
25
|
+
|
|
26
|
+
# === VALIDATE DEPENDENCIES ===
|
|
27
|
+
if ! command -v npx &>/dev/null; then
|
|
28
|
+
echo "[ccusage] ERROR: npx is not available"
|
|
29
|
+
echo " Ensure node feature is installed first"
|
|
30
|
+
echo " NVM path: /usr/local/share/nvm/nvm.sh"
|
|
31
|
+
exit 1
|
|
32
|
+
fi
|
|
33
|
+
|
|
34
|
+
# === VALIDATE INPUT ===
|
|
35
|
+
# Validate shells parameter
|
|
36
|
+
if [[ ! "${SHELLS}" =~ ^(bash|zsh|both)$ ]]; then
|
|
37
|
+
echo "[ccusage] ERROR: shells must be 'bash', 'zsh', or 'both'"
|
|
38
|
+
echo " Provided: ${SHELLS}"
|
|
39
|
+
exit 1
|
|
40
|
+
fi
|
|
41
|
+
|
|
42
|
+
# Validate version format (basic check)
|
|
43
|
+
if [[ ! "${CCUSAGE_VERSION}" =~ ^[a-zA-Z0-9.-]+$ ]]; then
|
|
44
|
+
echo "[ccusage] ERROR: version contains invalid characters"
|
|
45
|
+
echo " Provided: ${CCUSAGE_VERSION}"
|
|
46
|
+
exit 1
|
|
47
|
+
fi
|
|
48
|
+
|
|
49
|
+
# === DETECT USER ===
|
|
50
|
+
if [ "${USERNAME}" = "auto" ] || [ "${USERNAME}" = "automatic" ]; then
|
|
51
|
+
USERNAME=""
|
|
52
|
+
for CURRENT_USER in vscode node codespace; do
|
|
53
|
+
if id -u "${CURRENT_USER}" >/dev/null 2>&1; then
|
|
54
|
+
USERNAME=${CURRENT_USER}
|
|
55
|
+
break
|
|
56
|
+
fi
|
|
57
|
+
done
|
|
58
|
+
[ -z "${USERNAME}" ] && USERNAME=root
|
|
59
|
+
elif [ "${USERNAME}" = "none" ] || ! id -u "${USERNAME}" >/dev/null 2>&1; then
|
|
60
|
+
USERNAME=root
|
|
61
|
+
fi
|
|
62
|
+
|
|
63
|
+
echo "[ccusage] Installing for user: ${USERNAME}"
|
|
64
|
+
|
|
65
|
+
# === GET USER HOME ===
|
|
66
|
+
USER_HOME=$(eval echo "~${USERNAME}")
|
|
67
|
+
if [ ! -d "${USER_HOME}" ]; then
|
|
68
|
+
echo "[ccusage] ERROR: Home directory not found for user ${USERNAME}"
|
|
69
|
+
exit 1
|
|
70
|
+
fi
|
|
71
|
+
|
|
72
|
+
# === INSTALL (CREATE ALIASES) ===
|
|
73
|
+
ALIAS_CMD="alias ccusage=\"npx -y ccusage@${CCUSAGE_VERSION}\""
|
|
74
|
+
|
|
75
|
+
configure_shell() {
|
|
76
|
+
local shell_rc="$1"
|
|
77
|
+
local shell_name="$2"
|
|
78
|
+
|
|
79
|
+
if [ ! -f "${shell_rc}" ]; then
|
|
80
|
+
echo "[ccusage] Creating ${shell_name} config file: ${shell_rc}"
|
|
81
|
+
sudo -u "${USERNAME}" touch "${shell_rc}"
|
|
82
|
+
fi
|
|
83
|
+
|
|
84
|
+
if grep -q "alias ccusage=" "${shell_rc}"; then
|
|
85
|
+
echo "[ccusage] ${shell_name} alias already configured. Skipping..."
|
|
86
|
+
else
|
|
87
|
+
echo "[ccusage] Adding ccusage alias to ${shell_name}"
|
|
88
|
+
echo "${ALIAS_CMD}" >> "${shell_rc}"
|
|
89
|
+
if ! chown "${USERNAME}:${USERNAME}" "${shell_rc}" 2>/dev/null; then
|
|
90
|
+
echo "[ccusage] WARNING: Could not set ownership on ${shell_rc}"
|
|
91
|
+
echo " Fix: sudo chown ${USERNAME}:${USERNAME} ${shell_rc}"
|
|
92
|
+
fi
|
|
93
|
+
fi
|
|
94
|
+
}
|
|
95
|
+
|
|
96
|
+
# Configure requested shells
|
|
97
|
+
if [ "${SHELLS}" = "bash" ] || [ "${SHELLS}" = "both" ]; then
|
|
98
|
+
configure_shell "${USER_HOME}/.bashrc" "bash"
|
|
99
|
+
fi
|
|
100
|
+
|
|
101
|
+
if [ "${SHELLS}" = "zsh" ] || [ "${SHELLS}" = "both" ]; then
|
|
102
|
+
configure_shell "${USER_HOME}/.zshrc" "zsh"
|
|
103
|
+
fi
|
|
104
|
+
|
|
105
|
+
# === VERIFICATION ===
|
|
106
|
+
echo "[ccusage] Verifying npx can access ccusage..."
|
|
107
|
+
if sudo -u "${USERNAME}" bash -c "npx -y ccusage@${CCUSAGE_VERSION} --version" &>/dev/null; then
|
|
108
|
+
echo "[ccusage] ✓ ccusage is accessible"
|
|
109
|
+
else
|
|
110
|
+
echo "[ccusage] WARNING: Could not verify ccusage installation"
|
|
111
|
+
echo " This may be due to network connectivity"
|
|
112
|
+
echo " The alias will still work once ccusage is available"
|
|
113
|
+
fi
|
|
114
|
+
|
|
115
|
+
# === SUMMARY ===
|
|
116
|
+
echo ""
|
|
117
|
+
echo "━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━"
|
|
118
|
+
echo " ccusage Installation Complete"
|
|
119
|
+
echo "━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━"
|
|
120
|
+
echo ""
|
|
121
|
+
echo "Configuration:"
|
|
122
|
+
echo " • User: ${USERNAME}"
|
|
123
|
+
echo " • Version: ${CCUSAGE_VERSION}"
|
|
124
|
+
echo " • Shells: ${SHELLS}"
|
|
125
|
+
echo ""
|
|
126
|
+
echo "Usage:"
|
|
127
|
+
echo " ccusage --daily # Daily usage report"
|
|
128
|
+
echo " ccusage --monthly # Monthly report"
|
|
129
|
+
echo " ccusage --live # Live monitoring"
|
|
130
|
+
echo " ccusage --help # Full options"
|
|
131
|
+
echo ""
|
|
132
|
+
echo "━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━"
|