pakhale 0.1.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/LICENSE +21 -0
- package/README.md +72 -0
- package/assets/instructions/AGENTS.md +29 -0
- package/assets/statusline/claude-code.sh +100 -0
- package/dist/cli.js +2037 -0
- package/package.json +50 -0
- package/skills/architecture/SKILL.md +14 -0
- package/skills/consistency-check/DIMENSIONS.md +91 -0
- package/skills/consistency-check/SKILL.md +74 -0
- package/skills/consistency-check/scripts/consistency-workflow.js +158 -0
- package/skills/deslop/SKILL.md +153 -0
- package/skills/deslop/references/python.md +65 -0
- package/skills/deslop/references/react.md +71 -0
- package/skills/deslop/references/typescript.md +62 -0
- package/skills/sitedrop/SKILL.md +40 -0
- package/skills/stackup/SKILL.md +96 -0
- package/skills/stackup/references/hooks-ci.md +132 -0
- package/skills/stackup/references/python.md +81 -0
- package/skills/stackup/references/react.md +79 -0
- package/skills/stackup/references/typescript.md +114 -0
package/LICENSE
ADDED
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
MIT License
|
|
2
|
+
|
|
3
|
+
Copyright (c) 2026 Pratik Pakhale
|
|
4
|
+
|
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
6
|
+
of this software and associated documentation files (the "Software"), to deal
|
|
7
|
+
in the Software without restriction, including without limitation the rights
|
|
8
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
9
|
+
copies of the Software, and to permit persons to whom the Software is
|
|
10
|
+
furnished to do so, subject to the following conditions:
|
|
11
|
+
|
|
12
|
+
The above copyright notice and this permission notice shall be included in all
|
|
13
|
+
copies or substantial portions of the Software.
|
|
14
|
+
|
|
15
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
16
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
17
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
18
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
19
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
20
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
21
|
+
SOFTWARE.
|
package/README.md
ADDED
|
@@ -0,0 +1,72 @@
|
|
|
1
|
+
# pakhale
|
|
2
|
+
|
|
3
|
+
My personal CLI. It keeps my coding agents — [Claude Code](https://claude.com/claude-code) and
|
|
4
|
+
[opencode](https://opencode.ai) — set up the same way on every machine, from one file.
|
|
5
|
+
|
|
6
|
+
```bash
|
|
7
|
+
npx pakhale setup agents # set up this machine
|
|
8
|
+
npx pakhale setup agents plan # dry run — show every change, write nothing
|
|
9
|
+
```
|
|
10
|
+
|
|
11
|
+
Running `plan` first is always safe: it reads the machine and prints exactly what would change.
|
|
12
|
+
|
|
13
|
+
## What it sets up
|
|
14
|
+
|
|
15
|
+
[`config.ts`](config.ts) is the whole source of truth. It lists the agents I use and the
|
|
16
|
+
capabilities I want them to have — plugins, skills, MCP servers — plus my shared instructions
|
|
17
|
+
and settings. Applying it installs whatever is missing and leaves everything else alone.
|
|
18
|
+
|
|
19
|
+
Agents package things differently, so each capability says how it reaches each agent:
|
|
20
|
+
|
|
21
|
+
```ts
|
|
22
|
+
{
|
|
23
|
+
name: 'plannotator',
|
|
24
|
+
deliver: {
|
|
25
|
+
'claude-code': { via: 'claude-plugin', marketplace: 'plannotator', plugin: 'plannotator' },
|
|
26
|
+
opencode: { via: 'opencode-plugin', package: '@plannotator/opencode@latest' },
|
|
27
|
+
},
|
|
28
|
+
}
|
|
29
|
+
```
|
|
30
|
+
|
|
31
|
+
| `via` | Reaches |
|
|
32
|
+
| --- | --- |
|
|
33
|
+
| `skills` | any agent that reads `SKILL.md` |
|
|
34
|
+
| `mcp` | any agent |
|
|
35
|
+
| `claude-plugin` | Claude Code |
|
|
36
|
+
| `opencode-plugin` | opencode |
|
|
37
|
+
|
|
38
|
+
Leaving an agent undeclared is an error rather than a silent skip, so adding a new agent tells
|
|
39
|
+
me about every gap at once.
|
|
40
|
+
|
|
41
|
+
## Options
|
|
42
|
+
|
|
43
|
+
- `plan` or `-n, --dry-run` — show every change, write nothing
|
|
44
|
+
- `-a, --agent <id>` — set up one agent (repeatable)
|
|
45
|
+
- `--all` — every configured agent, no prompt
|
|
46
|
+
- `--home <dir>` — apply against a different home directory
|
|
47
|
+
- `-h, --help` — full usage
|
|
48
|
+
|
|
49
|
+
With a terminal and no `--agent`, it asks which agents to set up — space to toggle, `a` for all.
|
|
50
|
+
Piped or scripted, it applies to every configured agent without asking.
|
|
51
|
+
|
|
52
|
+
## Safe by default
|
|
53
|
+
|
|
54
|
+
- **Re-running changes nothing.** Every artifact is checked before it is written, installers
|
|
55
|
+
included.
|
|
56
|
+
- **Settings you added yourself survive.** Keys `config.ts` does not name are preserved.
|
|
57
|
+
- **A config file it cannot parse is left alone** rather than flattened.
|
|
58
|
+
- **Agents you do not have installed are skipped,** never created.
|
|
59
|
+
- **Anything it displaces is backed up** to `.setup-backups/<timestamp>/`.
|
|
60
|
+
|
|
61
|
+
## Development
|
|
62
|
+
|
|
63
|
+
```bash
|
|
64
|
+
bun install
|
|
65
|
+
bun src/cli.ts setup agents plan # run from source
|
|
66
|
+
bun run test # ~5s, no network, never touches your real ~
|
|
67
|
+
bun run typecheck
|
|
68
|
+
bun run build # dist/cli.js (Node >=20)
|
|
69
|
+
```
|
|
70
|
+
|
|
71
|
+
[ARCHITECTURE.md](ARCHITECTURE.md) covers how it works inside — the config vocabulary, the
|
|
72
|
+
plan/diff/commit split, and how to add another agent.
|
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
## DO's :
|
|
2
|
+
|
|
3
|
+
1. Prefer established, well-maintained libraries when they reduce overall
|
|
4
|
+
complexity or improve reliability. Do not reimplement common
|
|
5
|
+
functionality without a clear reason.
|
|
6
|
+
|
|
7
|
+
2. Lean on the dependencies already in the project before writing your own
|
|
8
|
+
implementation or adding packages. Do not assume a library lacks a
|
|
9
|
+
capability without checking its documentation and types.
|
|
10
|
+
|
|
11
|
+
3. Make architectural decisions for the long term. Do not accept a stopgap
|
|
12
|
+
that only works for now and is meant to be replaced later.
|
|
13
|
+
|
|
14
|
+
---
|
|
15
|
+
|
|
16
|
+
## DONT's :
|
|
17
|
+
|
|
18
|
+
1. DO NOT COMMIT OR AUTO CREATE PR UNLESS EXPLICITLY ASKED YOU TO DO SO.
|
|
19
|
+
AND IN ANY CASE NEVER EVER ADD YOURSELF AS COAUTHOR TO THE COMMITS!!
|
|
20
|
+
|
|
21
|
+
Use conventional commit messages (https://www.conventionalcommits.org/):
|
|
22
|
+
- Format: `type(scope): description` (scope is optional)
|
|
23
|
+
- Types: feat, fix, refactor, style, docs, test, chore, perf, ci, build
|
|
24
|
+
- Keep subject line under 72 chars, imperative mood, lowercase
|
|
25
|
+
- Use body for details when needed, separated by blank line
|
|
26
|
+
|
|
27
|
+
2. Dont use any kind of browser agent unless explicitly told you to do so. Even to test something, do not try to operate a browser.
|
|
28
|
+
|
|
29
|
+
3. NEVER push changes to outward-facing/shared surfaces directly — ALWAYS show me the drafted change and wait for my explicit confirmation first. This covers PR titles/descriptions/comments, issue titles/descriptions/comments, commit messages, and anything written to GitHub, Linear, Slack, or any external service. "Update the PR description" (or similar) is a request to DRAFT it, not to apply it live. Prepare the change locally, show it to me, then apply only after I say go.
|
|
@@ -0,0 +1,100 @@
|
|
|
1
|
+
#!/bin/bash
|
|
2
|
+
# Claude Code Status Line — minimal + info-dense
|
|
3
|
+
input=$(cat)
|
|
4
|
+
|
|
5
|
+
# Format integer with thousands separators (commas)
|
|
6
|
+
commafy() { echo "$1" | sed -e :a -e 's/\(.*[0-9]\)\([0-9]\{3\}\)/\1,\2/;ta'; }
|
|
7
|
+
|
|
8
|
+
# --- Extract fields ---
|
|
9
|
+
model_full=$(echo "$input" | jq -r '.model.display_name // empty')
|
|
10
|
+
# Extract only the model family (lowercase); fall back to first word of display name
|
|
11
|
+
model=$(echo "$model_full" | grep -oiE 'opus|sonnet|haiku|fable|mythos' | head -1 | tr '[:upper:]' '[:lower:]')
|
|
12
|
+
[ -z "$model" ] && model=$(echo "$model_full" | tr '[:upper:]' '[:lower:]' | awk '{print $1}')
|
|
13
|
+
thinking=$(echo "$input" | jq -r '.thinking.enabled // false')
|
|
14
|
+
effort=$(echo "$input" | jq -r '.effort.level // empty')
|
|
15
|
+
cwd=$(echo "$input" | jq -r '.workspace.current_dir // .cwd // empty')
|
|
16
|
+
project=$([ -n "$cwd" ] && basename "$cwd" || echo "")
|
|
17
|
+
pct=$(echo "$input" | jq -r '.context_window.used_percentage // 0' | cut -d. -f1)
|
|
18
|
+
ctx_size=$(echo "$input" | jq -r '.context_window.context_window_size // 0')
|
|
19
|
+
tokens_k=$(echo "$input" | jq -r --argjson s "$ctx_size" --argjson p "$pct" '($s * $p / 100 / 1000) | floor')
|
|
20
|
+
five_h=$(echo "$input" | jq -r '.rate_limits.five_hour.used_percentage // empty')
|
|
21
|
+
seven_d=$(echo "$input" | jq -r '.rate_limits.seven_day.used_percentage // empty')
|
|
22
|
+
|
|
23
|
+
|
|
24
|
+
# Git branch + diff stats
|
|
25
|
+
branch=""
|
|
26
|
+
diff_added=""
|
|
27
|
+
diff_removed=""
|
|
28
|
+
diff_files=""
|
|
29
|
+
if [ -n "$cwd" ] && git -C "$cwd" rev-parse --git-dir >/dev/null 2>&1; then
|
|
30
|
+
branch=$(git -C "$cwd" symbolic-ref --short HEAD 2>/dev/null || git -C "$cwd" rev-parse --short HEAD 2>/dev/null)
|
|
31
|
+
|
|
32
|
+
# Detect base branch (run only when we have a branch name)
|
|
33
|
+
if [ -n "$branch" ]; then
|
|
34
|
+
base_ref=$(git -C "$cwd" symbolic-ref refs/remotes/origin/HEAD 2>/dev/null | sed 's|refs/remotes/||')
|
|
35
|
+
if [ -z "$base_ref" ]; then
|
|
36
|
+
for candidate in origin/release origin/main origin/master; do
|
|
37
|
+
if git -C "$cwd" rev-parse --verify "$candidate" >/dev/null 2>&1; then
|
|
38
|
+
base_ref="$candidate"
|
|
39
|
+
break
|
|
40
|
+
fi
|
|
41
|
+
done
|
|
42
|
+
fi
|
|
43
|
+
|
|
44
|
+
# Compute diff stats only when we are NOT on the base branch itself
|
|
45
|
+
if [ -n "$base_ref" ]; then
|
|
46
|
+
base_short="${base_ref#origin/}"
|
|
47
|
+
if [ "$branch" != "$base_short" ]; then
|
|
48
|
+
shortstat=$(git -C "$cwd" diff --shortstat "${base_ref}...HEAD" 2>/dev/null)
|
|
49
|
+
if [ -n "$shortstat" ]; then
|
|
50
|
+
diff_files=$(echo "$shortstat" | grep -oE '[0-9]+ file' | grep -oE '[0-9]+')
|
|
51
|
+
diff_added=$(echo "$shortstat" | grep -oE '[0-9]+ insertion' | grep -oE '[0-9]+')
|
|
52
|
+
diff_removed=$(echo "$shortstat" | grep -oE '[0-9]+ deletion' | grep -oE '[0-9]+')
|
|
53
|
+
[ -n "$diff_files" ] && diff_files=$(commafy "$diff_files")
|
|
54
|
+
[ -n "$diff_added" ] && diff_added=$(commafy "$diff_added")
|
|
55
|
+
[ -n "$diff_removed" ] && diff_removed=$(commafy "$diff_removed")
|
|
56
|
+
fi
|
|
57
|
+
fi
|
|
58
|
+
fi
|
|
59
|
+
fi
|
|
60
|
+
fi
|
|
61
|
+
|
|
62
|
+
# --- Colors ---
|
|
63
|
+
RST="\033[0m"
|
|
64
|
+
DIM="\033[2m"
|
|
65
|
+
CYAN="\033[36m"
|
|
66
|
+
BLUE="\033[34m"
|
|
67
|
+
MAG="\033[35m"
|
|
68
|
+
YEL="\033[33m"
|
|
69
|
+
RED="\033[31m"
|
|
70
|
+
GRN="\033[32m"
|
|
71
|
+
|
|
72
|
+
# Percentage text color
|
|
73
|
+
if [ "$pct" -lt 50 ]; then PCT_COLOR=$RST
|
|
74
|
+
elif [ "$pct" -lt 85 ]; then PCT_COLOR=$YEL
|
|
75
|
+
else PCT_COLOR=$RED; fi
|
|
76
|
+
|
|
77
|
+
# --- Single line ---
|
|
78
|
+
sep=" ${DIM}/${RST} "
|
|
79
|
+
model_label="${model}"
|
|
80
|
+
if [ "$thinking" = "true" ] || [ -n "$effort" ]; then
|
|
81
|
+
think_tag="think"
|
|
82
|
+
[ -n "$effort" ] && think_tag="${effort}"
|
|
83
|
+
model_label="${model} ${DIM}${think_tag}${RST}"
|
|
84
|
+
fi
|
|
85
|
+
out="${CYAN}${model_label}${RST}"
|
|
86
|
+
[ -n "$project" ] && out="${out}${sep}${BLUE}${project}${RST}"
|
|
87
|
+
[ -n "$branch" ] && out="${out}${sep}${MAG}⎇ ${branch}${RST}"
|
|
88
|
+
if [ -n "$diff_added" ] || [ -n "$diff_removed" ] || [ -n "$diff_files" ]; then
|
|
89
|
+
diff_seg=""
|
|
90
|
+
[ -n "$diff_added" ] && diff_seg="${GRN}+${diff_added}${RST}"
|
|
91
|
+
[ -n "$diff_removed" ] && diff_seg="${diff_seg:+${diff_seg} }${RED}-${diff_removed}${RST}"
|
|
92
|
+
[ -n "$diff_files" ] && diff_seg="${diff_seg:+${diff_seg} }${DIM}~${diff_files}f${RST}"
|
|
93
|
+
[ -n "$diff_seg" ] && out="${out} ${diff_seg}"
|
|
94
|
+
fi
|
|
95
|
+
out="${out}${sep}${PCT_COLOR}${pct}%${RST} ${DIM}($(commafy "$tokens_k")k)${RST}"
|
|
96
|
+
[ -n "$five_h" ] && out="${out}${sep}${DIM}5h:${RST}$(printf '%.0f' "$five_h")%"
|
|
97
|
+
[ -n "$seven_d" ] && out="${out} ${DIM}7d:${RST}$(printf '%.0f' "$seven_d")%"
|
|
98
|
+
|
|
99
|
+
|
|
100
|
+
printf "%b\n" "$out"
|