prjct-cli 2.65.0 → 2.67.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/CHANGELOG.md +10 -0
- package/README.md +2 -5
- package/assets/statusline/components/limits.sh +66 -0
- package/assets/statusline/default-config.json +5 -1
- package/assets/statusline/lib/cache.sh +48 -2
- package/assets/statusline/lib/config.sh +10 -4
- package/assets/statusline/statusline.sh +1 -1
- package/dist/bin/prjct-core.mjs +394 -388
- package/dist/daemon/entry.mjs +314 -308
- package/dist/mcp/server.mjs +185 -179
- package/dist/templates.json +1 -1
- package/package.json +1 -1
- package/scripts/install.sh +3 -3
- package/templates/antigravity/SKILL.md +2 -2
- package/templates/crew/agents/implementer.md +1 -1
- package/templates/cursor/router.mdc +1 -1
- package/templates/global/ANTIGRAVITY.md +1 -1
- package/templates/global/CURSOR.mdc +1 -1
- package/templates/global/GEMINI.md +1 -1
- package/templates/global/STORAGE-SPEC.md +4 -5
- package/templates/global/WINDSURF.md +1 -1
- package/templates/mcp-config.json +2 -2
- package/templates/windsurf/router.md +1 -1
- package/templates/agentic/checklist-routing.md +0 -98
- package/templates/agentic/orchestrator.md +0 -68
- package/templates/agentic/task-fragmentation.md +0 -89
- package/templates/agents/AGENTS.md +0 -67
- package/templates/checklists/architecture.md +0 -28
- package/templates/checklists/code-quality.md +0 -28
- package/templates/checklists/data.md +0 -33
- package/templates/checklists/documentation.md +0 -33
- package/templates/checklists/infrastructure.md +0 -33
- package/templates/checklists/performance.md +0 -33
- package/templates/checklists/security.md +0 -33
- package/templates/checklists/testing.md +0 -33
- package/templates/checklists/ux-ui.md +0 -37
- package/templates/config/skill-mappings.json +0 -82
- package/templates/context/dashboard.md +0 -251
- package/templates/context/roadmap.md +0 -221
- package/templates/cursor/commands/ship.md +0 -6
- package/templates/cursor/commands/task.md +0 -6
- package/templates/cursor/p.md +0 -6
- package/templates/permissions/default.jsonc +0 -60
- package/templates/permissions/permissive.jsonc +0 -49
- package/templates/permissions/strict.jsonc +0 -58
- package/templates/skills/code-review.md +0 -47
- package/templates/skills/debug.md +0 -61
- package/templates/skills/refactor.md +0 -47
- package/templates/tools/bash.txt +0 -22
- package/templates/tools/edit.txt +0 -18
- package/templates/tools/glob.txt +0 -19
- package/templates/tools/grep.txt +0 -21
- package/templates/tools/read.txt +0 -14
- package/templates/tools/task.txt +0 -20
- package/templates/tools/webfetch.txt +0 -16
- package/templates/tools/websearch.txt +0 -18
- package/templates/tools/write.txt +0 -17
- package/templates/windsurf/workflows/ship.md +0 -6
- package/templates/windsurf/workflows/task.md +0 -6
package/CHANGELOG.md
CHANGED
package/README.md
CHANGED
|
@@ -260,7 +260,7 @@ p. status done # close the active task
|
|
|
260
260
|
p. ship # commit, push, open PR
|
|
261
261
|
```
|
|
262
262
|
|
|
263
|
-
Cursor
|
|
263
|
+
Cursor and Windsurf use their installed prjct router files; otherwise run `prjct <command> --md` and follow the output.
|
|
264
264
|
|
|
265
265
|
### Core verbs
|
|
266
266
|
|
|
@@ -277,7 +277,6 @@ Cursor / Windsurf use the same commands with a `/` prefix: `/capture`, `/task`,
|
|
|
277
277
|
| `prjct ship [name]` | Run the project's ship workflow (commit, push, PR, persist). |
|
|
278
278
|
| `prjct sync` | Re-index files, git co-change, imports; refresh project analysis. |
|
|
279
279
|
| `prjct regen` | Full rebuild of the Obsidian vault snapshot from SQLite. |
|
|
280
|
-
| `prjct suggest` | Smart recommendations based on current project state. |
|
|
281
280
|
| `prjct value` | Show whether prjct is paying for itself in this project. |
|
|
282
281
|
| `prjct memory-doctor` | Audit memory quality before noisy context spreads to every agent. |
|
|
283
282
|
| `prjct report [days]` | Generate a human report from shipped work and project memory. |
|
|
@@ -531,9 +530,7 @@ $ prjct status done # close it when finished
|
|
|
531
530
|
$ prjct ship # bump version, commit, PR
|
|
532
531
|
```
|
|
533
532
|
|
|
534
|
-
Inside an agent you
|
|
535
|
-
refresh"` in Claude Code, `/task "…"` in Cursor/Windsurf. `prjct task` with no
|
|
536
|
-
argument prints the currently active task.
|
|
533
|
+
Inside an agent you can say it: `p. task "add OAuth refresh"` in Claude Code, or run `prjct task "…" --md` from any wired agent. `prjct task` with no argument prints the currently active task.
|
|
537
534
|
|
|
538
535
|
**How do I get AI assistance for a coding problem?**
|
|
539
536
|
Inside Claude Code (or any wired agent) describe the problem in natural
|
|
@@ -0,0 +1,66 @@
|
|
|
1
|
+
#!/bin/bash
|
|
2
|
+
# prjct statusline - Usage limits component
|
|
3
|
+
# Displays Claude.ai 5-hour and weekly limit usage when Claude provides it.
|
|
4
|
+
|
|
5
|
+
limit_circle() {
|
|
6
|
+
local pct="$1"
|
|
7
|
+
if [[ ! "$pct" =~ ^[0-9]+$ ]]; then
|
|
8
|
+
echo ""
|
|
9
|
+
elif [[ "$pct" -ge 90 ]]; then
|
|
10
|
+
echo "●"
|
|
11
|
+
elif [[ "$pct" -ge 75 ]]; then
|
|
12
|
+
echo "◕"
|
|
13
|
+
elif [[ "$pct" -ge 50 ]]; then
|
|
14
|
+
echo "◑"
|
|
15
|
+
elif [[ "$pct" -ge 25 ]]; then
|
|
16
|
+
echo "◔"
|
|
17
|
+
else
|
|
18
|
+
echo "○"
|
|
19
|
+
fi
|
|
20
|
+
}
|
|
21
|
+
|
|
22
|
+
limit_color() {
|
|
23
|
+
local pct="$1"
|
|
24
|
+
if [[ ! "$pct" =~ ^[0-9]+$ ]]; then
|
|
25
|
+
echo "$MUTED"
|
|
26
|
+
elif [[ "$pct" -ge 90 ]]; then
|
|
27
|
+
echo "$ERROR"
|
|
28
|
+
elif [[ "$pct" -ge 75 ]]; then
|
|
29
|
+
echo "$WARNING"
|
|
30
|
+
else
|
|
31
|
+
echo "$MUTED"
|
|
32
|
+
fi
|
|
33
|
+
}
|
|
34
|
+
|
|
35
|
+
format_limit() {
|
|
36
|
+
local label="$1"
|
|
37
|
+
local pct="$2"
|
|
38
|
+
|
|
39
|
+
[[ -z "$pct" || "$pct" == "null" || ! "$pct" =~ ^[0-9]+$ ]] && return
|
|
40
|
+
|
|
41
|
+
local circle color
|
|
42
|
+
circle=$(limit_circle "$pct")
|
|
43
|
+
color=$(limit_color "$pct")
|
|
44
|
+
|
|
45
|
+
echo -e "${color}${circle} ${label} ${pct}%${NC}"
|
|
46
|
+
}
|
|
47
|
+
|
|
48
|
+
component_limits() {
|
|
49
|
+
component_enabled "limits" || return
|
|
50
|
+
|
|
51
|
+
local parts=()
|
|
52
|
+
local five_hour weekly
|
|
53
|
+
|
|
54
|
+
five_hour=$(format_limit "5h" "$RATE_LIMIT_5H_PERCENT")
|
|
55
|
+
weekly=$(format_limit "7d" "$RATE_LIMIT_WEEKLY_PERCENT")
|
|
56
|
+
|
|
57
|
+
[[ -n "$five_hour" ]] && parts+=("$five_hour")
|
|
58
|
+
[[ -n "$weekly" ]] && parts+=("$weekly")
|
|
59
|
+
|
|
60
|
+
[[ ${#parts[@]} -eq 0 ]] && return
|
|
61
|
+
|
|
62
|
+
local old_ifs="$IFS"
|
|
63
|
+
IFS=" "
|
|
64
|
+
echo -e "${parts[*]}"
|
|
65
|
+
IFS="$old_ifs"
|
|
66
|
+
}
|
|
@@ -64,6 +64,43 @@ parse_stdin() {
|
|
|
64
64
|
# Single jq call to extract all values
|
|
65
65
|
local parsed
|
|
66
66
|
parsed=$(echo "$input" | jq -r '
|
|
67
|
+
def pct:
|
|
68
|
+
(.used_percentage // .usedPercent // .used_percent // .percent // empty);
|
|
69
|
+
def reset:
|
|
70
|
+
(.resets_at // .resetsAt // .reset_at // .resetAt // empty);
|
|
71
|
+
def key:
|
|
72
|
+
(.id // .name // .limit_name // .limitName // .window // .type // .label // "" | tostring | ascii_downcase);
|
|
73
|
+
def normpct:
|
|
74
|
+
if . == null or . == "" then "" else (tonumber | floor | tostring) end;
|
|
75
|
+
def five_hour_from($rl):
|
|
76
|
+
if ($rl | type) == "array" then
|
|
77
|
+
(($rl[]? | select((key | test("5|five|hour")) and ((key | test("week|7|day")) | not)) | pct) // "")
|
|
78
|
+
elif ($rl | type) == "object" then
|
|
79
|
+
(($rl.five_hour | pct) // ($rl.fiveHour | pct) // ($rl["5h"] | pct) // ($rl.primary | pct) //
|
|
80
|
+
($rl | to_entries[]? | select(((.key | ascii_downcase) | test("5|five|hour")) or ((.value | key) | test("5|five|hour"))) | .value | pct) // "")
|
|
81
|
+
else "" end;
|
|
82
|
+
def weekly_from($rl):
|
|
83
|
+
if ($rl | type) == "array" then
|
|
84
|
+
(($rl[]? | select(key | test("week|weekly|7|day")) | pct) // "")
|
|
85
|
+
elif ($rl | type) == "object" then
|
|
86
|
+
(($rl.weekly | pct) // ($rl.week | pct) // ($rl.seven_day | pct) // ($rl.sevenDay | pct) // ($rl["7d"] | pct) // ($rl.secondary | pct) //
|
|
87
|
+
($rl | to_entries[]? | select(((.key | ascii_downcase) | test("week|weekly|7|day")) or ((.value | key) | test("week|weekly|7|day"))) | .value | pct) // "")
|
|
88
|
+
else "" end;
|
|
89
|
+
def five_hour_reset_from($rl):
|
|
90
|
+
if ($rl | type) == "array" then
|
|
91
|
+
(($rl[]? | select((key | test("5|five|hour")) and ((key | test("week|7|day")) | not)) | reset) // "")
|
|
92
|
+
elif ($rl | type) == "object" then
|
|
93
|
+
(($rl.five_hour | reset) // ($rl.fiveHour | reset) // ($rl["5h"] | reset) // ($rl.primary | reset) //
|
|
94
|
+
($rl | to_entries[]? | select(((.key | ascii_downcase) | test("5|five|hour")) or ((.value | key) | test("5|five|hour"))) | .value | reset) // "")
|
|
95
|
+
else "" end;
|
|
96
|
+
def weekly_reset_from($rl):
|
|
97
|
+
if ($rl | type) == "array" then
|
|
98
|
+
(($rl[]? | select(key | test("week|weekly|7|day")) | reset) // "")
|
|
99
|
+
elif ($rl | type) == "object" then
|
|
100
|
+
(($rl.weekly | reset) // ($rl.week | reset) // ($rl.seven_day | reset) // ($rl.sevenDay | reset) // ($rl["7d"] | reset) // ($rl.secondary | reset) //
|
|
101
|
+
($rl | to_entries[]? | select(((.key | ascii_downcase) | test("week|weekly|7|day")) or ((.value | key) | test("week|weekly|7|day"))) | .value | reset) // "")
|
|
102
|
+
else "" end;
|
|
103
|
+
.rate_limits as $rl |
|
|
67
104
|
[
|
|
68
105
|
(.model.display_name // "Claude"),
|
|
69
106
|
(.workspace.current_dir // "~"),
|
|
@@ -72,13 +109,17 @@ parse_stdin() {
|
|
|
72
109
|
(.context_window.context_window_size // 200000),
|
|
73
110
|
(.context_window.current_usage.input_tokens // 0),
|
|
74
111
|
(.context_window.current_usage.cache_creation_input_tokens // 0),
|
|
75
|
-
(.context_window.current_usage.cache_read_input_tokens // 0)
|
|
112
|
+
(.context_window.current_usage.cache_read_input_tokens // 0),
|
|
113
|
+
(five_hour_from($rl) | normpct),
|
|
114
|
+
(five_hour_reset_from($rl) // ""),
|
|
115
|
+
(weekly_from($rl) | normpct),
|
|
116
|
+
(weekly_reset_from($rl) // "")
|
|
76
117
|
] | @tsv
|
|
77
118
|
' 2>/dev/null)
|
|
78
119
|
|
|
79
120
|
# Parse tab-separated values (save/restore IFS to avoid breaking associative arrays)
|
|
80
121
|
local old_ifs="$IFS"
|
|
81
|
-
IFS=$'\t' read -r MODEL CWD ADDED REMOVED CTX_SIZE INPUT_TOKENS CACHE_CREATE CACHE_READ <<< "$parsed"
|
|
122
|
+
IFS=$'\t' read -r MODEL CWD ADDED REMOVED CTX_SIZE INPUT_TOKENS CACHE_CREATE CACHE_READ RATE_LIMIT_5H_PERCENT RATE_LIMIT_5H_RESET RATE_LIMIT_WEEKLY_PERCENT RATE_LIMIT_WEEKLY_RESET <<< "$parsed"
|
|
82
123
|
IFS="$old_ifs"
|
|
83
124
|
|
|
84
125
|
# Set defaults if parsing failed
|
|
@@ -90,6 +131,10 @@ parse_stdin() {
|
|
|
90
131
|
INPUT_TOKENS="${INPUT_TOKENS:-0}"
|
|
91
132
|
CACHE_CREATE="${CACHE_CREATE:-0}"
|
|
92
133
|
CACHE_READ="${CACHE_READ:-0}"
|
|
134
|
+
RATE_LIMIT_5H_PERCENT="${RATE_LIMIT_5H_PERCENT:-}"
|
|
135
|
+
RATE_LIMIT_5H_RESET="${RATE_LIMIT_5H_RESET:-}"
|
|
136
|
+
RATE_LIMIT_WEEKLY_PERCENT="${RATE_LIMIT_WEEKLY_PERCENT:-}"
|
|
137
|
+
RATE_LIMIT_WEEKLY_RESET="${RATE_LIMIT_WEEKLY_RESET:-}"
|
|
93
138
|
|
|
94
139
|
# Calculate context percentage
|
|
95
140
|
TOTAL_USED=$((INPUT_TOKENS + CACHE_CREATE + CACHE_READ))
|
|
@@ -119,3 +164,4 @@ get_global_path() {
|
|
|
119
164
|
[[ -z "$project_id" ]] && return
|
|
120
165
|
echo "${HOME}/.prjct-cli/projects/${project_id}"
|
|
121
166
|
}
|
|
167
|
+
|
|
@@ -46,6 +46,7 @@ load_config() {
|
|
|
46
46
|
COMPONENT_ENABLED["git"]="true"
|
|
47
47
|
COMPONENT_ENABLED["changes"]="true"
|
|
48
48
|
COMPONENT_ENABLED["context"]="true"
|
|
49
|
+
COMPONENT_ENABLED["limits"]="true"
|
|
49
50
|
COMPONENT_ENABLED["model"]="true"
|
|
50
51
|
|
|
51
52
|
COMPONENT_POSITION["prjct_icon"]=0
|
|
@@ -56,7 +57,8 @@ load_config() {
|
|
|
56
57
|
COMPONENT_POSITION["git"]=4
|
|
57
58
|
COMPONENT_POSITION["changes"]=5
|
|
58
59
|
COMPONENT_POSITION["context"]=6
|
|
59
|
-
COMPONENT_POSITION["
|
|
60
|
+
COMPONENT_POSITION["limits"]=7
|
|
61
|
+
COMPONENT_POSITION["model"]=8
|
|
60
62
|
|
|
61
63
|
# Load config file if exists
|
|
62
64
|
[[ ! -f "$CONFIG_FILE" ]] && return
|
|
@@ -84,6 +86,7 @@ load_config() {
|
|
|
84
86
|
(if .components.git.enabled == null then true else .components.git.enabled end),
|
|
85
87
|
(if .components.changes.enabled == null then true else .components.changes.enabled end),
|
|
86
88
|
(if .components.context.enabled == null then true else .components.context.enabled end),
|
|
89
|
+
(if .components.limits.enabled == null then true else .components.limits.enabled end),
|
|
87
90
|
(if .components.model.enabled == null then false else .components.model.enabled end),
|
|
88
91
|
(if .components.enrichment.enabled == null then true else .components.enrichment.enabled end),
|
|
89
92
|
(.components.prjct_icon.position // 0),
|
|
@@ -94,7 +97,8 @@ load_config() {
|
|
|
94
97
|
(.components.git.position // 4),
|
|
95
98
|
(.components.changes.position // 5),
|
|
96
99
|
(.components.context.position // 6),
|
|
97
|
-
(.components.
|
|
100
|
+
(.components.limits.position // 7),
|
|
101
|
+
(.components.model.position // 8)
|
|
98
102
|
] | @tsv
|
|
99
103
|
' "$CONFIG_FILE" 2>/dev/null)
|
|
100
104
|
|
|
@@ -107,8 +111,8 @@ load_config() {
|
|
|
107
111
|
CONFIG_CACHE_TTL_PRJCT CONFIG_CACHE_TTL_GIT CONFIG_CACHE_TTL_LINEAR CONFIG_CACHE_TTL_JIRA \
|
|
108
112
|
CONFIG_TASK_MAX_LENGTH CONFIG_CONTEXT_MIN_PERCENT \
|
|
109
113
|
CONFIG_LINEAR_SHOW_PRIORITY CONFIG_JIRA_SHOW_PRIORITY CONFIG_JIRA_SHOW_STATUS \
|
|
110
|
-
E_PRJCT_ICON E_TASK E_LINEAR E_JIRA E_DIR E_GIT E_CHANGES E_CONTEXT E_MODEL E_ENRICHMENT \
|
|
111
|
-
P_PRJCT_ICON P_TASK P_LINEAR P_JIRA P_DIR P_GIT P_CHANGES P_CONTEXT P_MODEL \
|
|
114
|
+
E_PRJCT_ICON E_TASK E_LINEAR E_JIRA E_DIR E_GIT E_CHANGES E_CONTEXT E_LIMITS E_MODEL E_ENRICHMENT \
|
|
115
|
+
P_PRJCT_ICON P_TASK P_LINEAR P_JIRA P_DIR P_GIT P_CHANGES P_CONTEXT P_LIMITS P_MODEL \
|
|
112
116
|
<<< "$config_data"
|
|
113
117
|
IFS="$old_ifs"
|
|
114
118
|
|
|
@@ -121,6 +125,7 @@ load_config() {
|
|
|
121
125
|
COMPONENT_ENABLED["git"]="$E_GIT"
|
|
122
126
|
COMPONENT_ENABLED["changes"]="$E_CHANGES"
|
|
123
127
|
COMPONENT_ENABLED["context"]="$E_CONTEXT"
|
|
128
|
+
COMPONENT_ENABLED["limits"]="$E_LIMITS"
|
|
124
129
|
COMPONENT_ENABLED["model"]="$E_MODEL"
|
|
125
130
|
|
|
126
131
|
# Set component positions
|
|
@@ -132,6 +137,7 @@ load_config() {
|
|
|
132
137
|
COMPONENT_POSITION["git"]="$P_GIT"
|
|
133
138
|
COMPONENT_POSITION["changes"]="$P_CHANGES"
|
|
134
139
|
COMPONENT_POSITION["context"]="$P_CONTEXT"
|
|
140
|
+
COMPONENT_POSITION["limits"]="$P_LIMITS"
|
|
135
141
|
COMPONENT_POSITION["model"]="$P_MODEL"
|
|
136
142
|
|
|
137
143
|
# Update linear/jira enabled based on component config
|
|
@@ -25,7 +25,7 @@ STATUSLINE_DIR="${HOME}/.prjct-cli/statusline"
|
|
|
25
25
|
SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
|
|
26
26
|
|
|
27
27
|
# Use installed location or script location for libs/components
|
|
28
|
-
if [[ -
|
|
28
|
+
if [[ -f "${STATUSLINE_DIR}/lib/cache.sh" && -f "${STATUSLINE_DIR}/lib/theme.sh" && -f "${STATUSLINE_DIR}/lib/config.sh" ]]; then
|
|
29
29
|
LIB_DIR="${STATUSLINE_DIR}/lib"
|
|
30
30
|
COMPONENTS_DIR="${STATUSLINE_DIR}/components"
|
|
31
31
|
else
|