@undeemed/get-shit-done-codex 1.20.3 → 1.20.8
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/README.md +13 -3
- package/agents/gsd-codebase-mapper.md +3 -0
- package/agents/gsd-debugger.md +3 -0
- package/agents/gsd-executor.md +52 -2
- package/agents/gsd-integration-checker.md +20 -0
- package/agents/gsd-phase-researcher.md +96 -4
- package/agents/gsd-plan-checker.md +125 -3
- package/agents/gsd-planner.md +38 -3
- package/agents/gsd-project-researcher.md +3 -0
- package/agents/gsd-research-synthesizer.md +3 -0
- package/agents/gsd-roadmapper.md +3 -0
- package/agents/gsd-verifier.md +25 -8
- package/commands/gsd/add-phase.md +6 -2
- package/commands/gsd/add-todo.md +6 -1
- package/commands/gsd/audit-milestone.md +1 -7
- package/commands/gsd/check-todos.md +6 -2
- package/commands/gsd/debug.md +3 -1
- package/commands/gsd/discuss-phase.md +1 -5
- package/commands/gsd/execute-phase.md +1 -2
- package/commands/gsd/insert-phase.md +1 -2
- package/commands/gsd/list-phase-assumptions.md +1 -5
- package/commands/gsd/new-milestone.md +1 -8
- package/commands/gsd/pause-work.md +4 -1
- package/commands/gsd/plan-milestone-gaps.md +1 -7
- package/commands/gsd/quick.md +2 -1
- package/commands/gsd/remove-phase.md +1 -2
- package/commands/gsd/research-phase.md +17 -15
- package/commands/gsd/verify-work.md +1 -2
- package/get-shit-done/bin/gsd-tools.cjs +168 -4858
- package/get-shit-done/bin/lib/commands.cjs +556 -0
- package/get-shit-done/bin/lib/config.cjs +162 -0
- package/get-shit-done/bin/lib/core.cjs +398 -0
- package/get-shit-done/bin/lib/frontmatter.cjs +299 -0
- package/get-shit-done/bin/lib/init.cjs +694 -0
- package/get-shit-done/bin/lib/milestone.cjs +215 -0
- package/get-shit-done/bin/lib/phase.cjs +873 -0
- package/get-shit-done/bin/lib/roadmap.cjs +298 -0
- package/get-shit-done/bin/lib/state.cjs +490 -0
- package/get-shit-done/bin/lib/template.cjs +222 -0
- package/get-shit-done/bin/lib/verify.cjs +772 -0
- package/get-shit-done/references/checkpoints.md +1 -0
- package/get-shit-done/templates/VALIDATION.md +104 -0
- package/get-shit-done/templates/config.json +2 -1
- package/get-shit-done/templates/phase-prompt.md +2 -0
- package/get-shit-done/templates/roadmap.md +1 -1
- package/get-shit-done/templates/summary.md +2 -0
- package/get-shit-done/workflows/audit-milestone.md +63 -8
- package/get-shit-done/workflows/complete-milestone.md +26 -0
- package/get-shit-done/workflows/diagnose-issues.md +1 -1
- package/get-shit-done/workflows/discuss-phase.md +68 -13
- package/get-shit-done/workflows/execute-phase.md +54 -9
- package/get-shit-done/workflows/execute-plan.md +17 -13
- package/get-shit-done/workflows/map-codebase.md +32 -44
- package/get-shit-done/workflows/new-milestone.md +16 -7
- package/get-shit-done/workflows/new-project.md +34 -31
- package/get-shit-done/workflows/plan-milestone-gaps.md +23 -5
- package/get-shit-done/workflows/plan-phase.md +106 -76
- package/get-shit-done/workflows/progress.md +14 -26
- package/get-shit-done/workflows/quick.md +24 -15
- package/get-shit-done/workflows/research-phase.md +10 -11
- package/get-shit-done/workflows/settings.md +16 -3
- package/get-shit-done/workflows/transition.md +5 -0
- package/get-shit-done/workflows/verify-work.md +11 -12
- package/hooks/dist/gsd-context-monitor.js +122 -0
- package/hooks/dist/gsd-statusline.js +17 -0
- package/package.json +18 -2
- package/scripts/build-hooks.js +1 -0
- package/get-shit-done/bin/gsd-tools.test.cjs +0 -2273
|
@@ -9,23 +9,13 @@ Read all files referenced by the invoking prompt's execution_context before star
|
|
|
9
9
|
<process>
|
|
10
10
|
|
|
11
11
|
<step name="init_context">
|
|
12
|
-
**Load progress context (
|
|
12
|
+
**Load progress context (paths only):**
|
|
13
13
|
|
|
14
14
|
```bash
|
|
15
|
-
|
|
16
|
-
# Large payloads are written to a tmpfile — output starts with @file:/path
|
|
17
|
-
if [[ "$INIT_RAW" == @file:* ]]; then
|
|
18
|
-
INIT_FILE="${INIT_RAW#@file:}"
|
|
19
|
-
INIT=$(cat "$INIT_FILE")
|
|
20
|
-
rm -f "$INIT_FILE"
|
|
21
|
-
else
|
|
22
|
-
INIT="$INIT_RAW"
|
|
23
|
-
fi
|
|
15
|
+
INIT=$(node ~/.codex/get-shit-done/bin/gsd-tools.cjs init progress)
|
|
24
16
|
```
|
|
25
17
|
|
|
26
|
-
Extract from init JSON: `project_exists`, `roadmap_exists`, `state_exists`, `phases`, `current_phase`, `next_phase`, `milestone_version`, `completed_count`, `phase_count`, `paused_at`.
|
|
27
|
-
|
|
28
|
-
**File contents (from --include):** `state_content`, `roadmap_content`, `project_content`, `config_content`. These are null if files don't exist.
|
|
18
|
+
Extract from init JSON: `project_exists`, `roadmap_exists`, `state_exists`, `phases`, `current_phase`, `next_phase`, `milestone_version`, `completed_count`, `phase_count`, `paused_at`, `state_path`, `roadmap_path`, `project_path`, `config_path`.
|
|
29
19
|
|
|
30
20
|
If `project_exists` is false (no `.planning/` directory):
|
|
31
21
|
|
|
@@ -47,15 +37,13 @@ If missing both ROADMAP.md and PROJECT.md: suggest `/gsd:new-project`.
|
|
|
47
37
|
</step>
|
|
48
38
|
|
|
49
39
|
<step name="load">
|
|
50
|
-
**Use
|
|
40
|
+
**Use structured extraction from gsd-tools:**
|
|
51
41
|
|
|
52
|
-
|
|
53
|
-
- `
|
|
54
|
-
- `
|
|
55
|
-
- `project_content` — current state (What This Is, Core Value, Requirements)
|
|
56
|
-
- `config_content` — settings (model_profile, workflow toggles)
|
|
42
|
+
Instead of reading full files, use targeted tools to get only the data needed for the report:
|
|
43
|
+
- `ROADMAP=$(node ~/.codex/get-shit-done/bin/gsd-tools.cjs roadmap analyze)`
|
|
44
|
+
- `STATE=$(node ~/.codex/get-shit-done/bin/gsd-tools.cjs state-snapshot)`
|
|
57
45
|
|
|
58
|
-
|
|
46
|
+
This minimizes orchestrator context usage.
|
|
59
47
|
</step>
|
|
60
48
|
|
|
61
49
|
<step name="analyze_roadmap">
|
|
@@ -89,9 +77,8 @@ Use this instead of manually reading/parsing ROADMAP.md.
|
|
|
89
77
|
<step name="position">
|
|
90
78
|
**Parse current position from init context and roadmap analysis:**
|
|
91
79
|
|
|
92
|
-
- Use `current_phase` and `next_phase` from
|
|
93
|
-
-
|
|
94
|
-
- Note `paused_at` if work was paused (from init context)
|
|
80
|
+
- Use `current_phase` and `next_phase` from `$ROADMAP`
|
|
81
|
+
- Note `paused_at` if work was paused (from `$STATE`)
|
|
95
82
|
- Count pending todos: use `init todos` or `list-todos`
|
|
96
83
|
- Check for active debug sessions: `ls .planning/debug/*.md 2>/dev/null | grep -v resolved | wc -l`
|
|
97
84
|
</step>
|
|
@@ -122,11 +109,12 @@ Plan [M] of [phase-total]: [status]
|
|
|
122
109
|
CONTEXT: [✓ if has_context | - if not]
|
|
123
110
|
|
|
124
111
|
## Key Decisions Made
|
|
125
|
-
- [
|
|
126
|
-
- [decision
|
|
112
|
+
- [extract from $STATE.decisions[]]
|
|
113
|
+
- [e.g. jq -r '.decisions[].decision' from state-snapshot]
|
|
127
114
|
|
|
128
115
|
## Blockers/Concerns
|
|
129
|
-
- [
|
|
116
|
+
- [extract from $STATE.blockers[]]
|
|
117
|
+
- [e.g. jq -r '.blockers[].text' from state-snapshot]
|
|
130
118
|
|
|
131
119
|
## Pending Todos
|
|
132
120
|
- [count] pending — /gsd:check-todos to review
|
|
@@ -96,8 +96,12 @@ Task(
|
|
|
96
96
|
**Directory:** ${QUICK_DIR}
|
|
97
97
|
**Description:** ${DESCRIPTION}
|
|
98
98
|
|
|
99
|
-
|
|
100
|
-
|
|
99
|
+
<files_to_read>
|
|
100
|
+
- .planning/STATE.md (Project State)
|
|
101
|
+
- ./CODEX.md (if exists — follow project-specific guidelines)
|
|
102
|
+
</files_to_read>
|
|
103
|
+
|
|
104
|
+
**Project skills:** Check .agents/skills/ directory (if exists) — read SKILL.md files, plans should account for project skill rules
|
|
101
105
|
|
|
102
106
|
</planning_context>
|
|
103
107
|
|
|
@@ -143,10 +147,6 @@ Display banner:
|
|
|
143
147
|
◆ Spawning plan checker...
|
|
144
148
|
```
|
|
145
149
|
|
|
146
|
-
```bash
|
|
147
|
-
PLAN_CONTENT=$(cat "${QUICK_DIR}/${next_num}-PLAN.md" 2>/dev/null)
|
|
148
|
-
```
|
|
149
|
-
|
|
150
150
|
Checker prompt:
|
|
151
151
|
|
|
152
152
|
```markdown
|
|
@@ -154,7 +154,9 @@ Checker prompt:
|
|
|
154
154
|
**Mode:** quick-full
|
|
155
155
|
**Task Description:** ${DESCRIPTION}
|
|
156
156
|
|
|
157
|
-
|
|
157
|
+
<files_to_read>
|
|
158
|
+
- ${QUICK_DIR}/${next_num}-PLAN.md (Plan to verify)
|
|
159
|
+
</files_to_read>
|
|
158
160
|
|
|
159
161
|
**Scope:** This is a quick task, not a full phase. Skip checks that require a ROADMAP phase goal.
|
|
160
162
|
</verification_context>
|
|
@@ -197,17 +199,16 @@ Track `iteration_count` (starts at 1 after initial plan + check).
|
|
|
197
199
|
|
|
198
200
|
Display: `Sending back to planner for revision... (iteration ${N}/2)`
|
|
199
201
|
|
|
200
|
-
```bash
|
|
201
|
-
PLAN_CONTENT=$(cat "${QUICK_DIR}/${next_num}-PLAN.md" 2>/dev/null)
|
|
202
|
-
```
|
|
203
|
-
|
|
204
202
|
Revision prompt:
|
|
205
203
|
|
|
206
204
|
```markdown
|
|
207
205
|
<revision_context>
|
|
208
206
|
**Mode:** quick-full (revision)
|
|
209
207
|
|
|
210
|
-
|
|
208
|
+
<files_to_read>
|
|
209
|
+
- ${QUICK_DIR}/${next_num}-PLAN.md (Existing plan)
|
|
210
|
+
</files_to_read>
|
|
211
|
+
|
|
211
212
|
**Checker issues:** ${structured_issues_from_checker}
|
|
212
213
|
|
|
213
214
|
</revision_context>
|
|
@@ -247,8 +248,12 @@ Task(
|
|
|
247
248
|
prompt="
|
|
248
249
|
Execute quick task ${next_num}.
|
|
249
250
|
|
|
250
|
-
|
|
251
|
-
|
|
251
|
+
<files_to_read>
|
|
252
|
+
- ${QUICK_DIR}/${next_num}-PLAN.md (Plan)
|
|
253
|
+
- .planning/STATE.md (Project state)
|
|
254
|
+
- ./CODEX.md (Project instructions, if exists)
|
|
255
|
+
- .agents/skills/ (Project skills, if exists — list skills, read SKILL.md for each, follow relevant rules during implementation)
|
|
256
|
+
</files_to_read>
|
|
252
257
|
|
|
253
258
|
<constraints>
|
|
254
259
|
- Execute all tasks in the plan
|
|
@@ -294,7 +299,11 @@ Task(
|
|
|
294
299
|
prompt="Verify quick task goal achievement.
|
|
295
300
|
Task directory: ${QUICK_DIR}
|
|
296
301
|
Task goal: ${DESCRIPTION}
|
|
297
|
-
|
|
302
|
+
|
|
303
|
+
<files_to_read>
|
|
304
|
+
- ${QUICK_DIR}/${next_num}-PLAN.md (Plan)
|
|
305
|
+
</files_to_read>
|
|
306
|
+
|
|
298
307
|
Check must_haves against actual codebase. Create VERIFICATION.md at ${QUICK_DIR}/${next_num}-VERIFICATION.md.",
|
|
299
308
|
subagent_type="gsd-verifier",
|
|
300
309
|
model="{verifier_model}",
|
|
@@ -34,12 +34,8 @@ If exists: Offer update/view/skip options.
|
|
|
34
34
|
## Step 3: Gather Phase Context
|
|
35
35
|
|
|
36
36
|
```bash
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
cat .planning/REQUIREMENTS.md 2>/dev/null
|
|
40
|
-
cat .planning/phases/${PHASE}-*/*-CONTEXT.md 2>/dev/null
|
|
41
|
-
# Decisions from state-snapshot (structured JSON)
|
|
42
|
-
node ~/.codex/get-shit-done/bin/gsd-tools.cjs state-snapshot | jq '.decisions'
|
|
37
|
+
INIT=$(node ~/.codex/get-shit-done/bin/gsd-tools.cjs init phase-op "${PHASE}")
|
|
38
|
+
# Extract: phase_dir, padded_phase, phase_number, state_path, requirements_path, context_path
|
|
43
39
|
```
|
|
44
40
|
|
|
45
41
|
## Step 4: Spawn Researcher
|
|
@@ -50,12 +46,15 @@ Task(
|
|
|
50
46
|
Research implementation approach for Phase {phase}: {name}
|
|
51
47
|
</objective>
|
|
52
48
|
|
|
53
|
-
<
|
|
49
|
+
<files_to_read>
|
|
50
|
+
- {context_path} (USER DECISIONS from /gsd:discuss-phase)
|
|
51
|
+
- {requirements_path} (Project requirements)
|
|
52
|
+
- {state_path} (Project decisions and history)
|
|
53
|
+
</files_to_read>
|
|
54
|
+
|
|
55
|
+
<additional_context>
|
|
54
56
|
Phase description: {description}
|
|
55
|
-
|
|
56
|
-
Prior decisions: {decisions}
|
|
57
|
-
Phase context: {context_md}
|
|
58
|
-
</context>
|
|
57
|
+
</additional_context>
|
|
59
58
|
|
|
60
59
|
<output>
|
|
61
60
|
Write to: .planning/phases/${PHASE}-{slug}/${PHASE}-RESEARCH.md
|
|
@@ -28,6 +28,7 @@ Parse current values (default to `true` if not present):
|
|
|
28
28
|
- `workflow.research` — spawn researcher during plan-phase
|
|
29
29
|
- `workflow.plan_check` — spawn plan checker during plan-phase
|
|
30
30
|
- `workflow.verifier` — spawn verifier during execute-phase
|
|
31
|
+
- `workflow.nyquist_validation` — validation architecture research during plan-phase
|
|
31
32
|
- `model_profile` — which model each agent uses (default: `balanced`)
|
|
32
33
|
- `git.branching_strategy` — branching approach (default: `"none"`)
|
|
33
34
|
</step>
|
|
@@ -83,6 +84,15 @@ AskUserQuestion([
|
|
|
83
84
|
{ label: "Yes", description: "Chain stages via Task() subagents (same isolation)" }
|
|
84
85
|
]
|
|
85
86
|
},
|
|
87
|
+
{
|
|
88
|
+
question: "Enable Nyquist Validation? (researches test coverage during planning)",
|
|
89
|
+
header: "Nyquist",
|
|
90
|
+
multiSelect: false,
|
|
91
|
+
options: [
|
|
92
|
+
{ label: "Yes (Recommended)", description: "Research automated test coverage during plan-phase. Adds validation requirements to plans. Blocks approval if tasks lack automated verify." },
|
|
93
|
+
{ label: "No", description: "Skip validation research. Good for rapid prototyping or no-test phases." }
|
|
94
|
+
]
|
|
95
|
+
},
|
|
86
96
|
{
|
|
87
97
|
question: "Git branching strategy?",
|
|
88
98
|
header: "Branching",
|
|
@@ -108,7 +118,8 @@ Merge new settings into existing config.json:
|
|
|
108
118
|
"research": true/false,
|
|
109
119
|
"plan_check": true/false,
|
|
110
120
|
"verifier": true/false,
|
|
111
|
-
"auto_advance": true/false
|
|
121
|
+
"auto_advance": true/false,
|
|
122
|
+
"nyquist_validation": true/false
|
|
112
123
|
},
|
|
113
124
|
"git": {
|
|
114
125
|
"branching_strategy": "none" | "phase" | "milestone"
|
|
@@ -155,7 +166,8 @@ Write `~/.gsd/defaults.json` with:
|
|
|
155
166
|
"research": <current>,
|
|
156
167
|
"plan_check": <current>,
|
|
157
168
|
"verifier": <current>,
|
|
158
|
-
"auto_advance": <current
|
|
169
|
+
"auto_advance": <current>,
|
|
170
|
+
"nyquist_validation": <current>
|
|
159
171
|
}
|
|
160
172
|
}
|
|
161
173
|
```
|
|
@@ -176,6 +188,7 @@ Display:
|
|
|
176
188
|
| Plan Checker | {On/Off} |
|
|
177
189
|
| Execution Verifier | {On/Off} |
|
|
178
190
|
| Auto-Advance | {On/Off} |
|
|
191
|
+
| Nyquist Validation | {On/Off} |
|
|
179
192
|
| Git Branching | {None/Per Phase/Per Milestone} |
|
|
180
193
|
| Saved as Defaults | {Yes/No} |
|
|
181
194
|
|
|
@@ -193,7 +206,7 @@ Quick commands:
|
|
|
193
206
|
|
|
194
207
|
<success_criteria>
|
|
195
208
|
- [ ] Current config read
|
|
196
|
-
- [ ] User presented with
|
|
209
|
+
- [ ] User presented with 7 settings (profile + 5 workflow toggles + git branching)
|
|
197
210
|
- [ ] Config updated with model_profile, workflow, and git sections
|
|
198
211
|
- [ ] User offered to save as global defaults (~/.gsd/defaults.json)
|
|
199
212
|
- [ ] Changes confirmed to user
|
|
@@ -451,6 +451,11 @@ Exit skill and invoke SlashCommand("/gsd:discuss-phase [X+1] --auto")
|
|
|
451
451
|
|
|
452
452
|
**Route B: Milestone complete (all phases done)**
|
|
453
453
|
|
|
454
|
+
**Clear auto-advance** — milestone boundary is the natural stopping point:
|
|
455
|
+
```bash
|
|
456
|
+
node ~/.codex/get-shit-done/bin/gsd-tools.cjs config-set workflow.auto_advance false
|
|
457
|
+
```
|
|
458
|
+
|
|
454
459
|
<if mode="yolo">
|
|
455
460
|
|
|
456
461
|
```
|
|
@@ -365,14 +365,11 @@ Task(
|
|
|
365
365
|
**Phase:** {phase_number}
|
|
366
366
|
**Mode:** gap_closure
|
|
367
367
|
|
|
368
|
-
|
|
369
|
-
|
|
370
|
-
|
|
371
|
-
|
|
372
|
-
|
|
373
|
-
|
|
374
|
-
**Roadmap:**
|
|
375
|
-
@.planning/ROADMAP.md
|
|
368
|
+
<files_to_read>
|
|
369
|
+
- {phase_dir}/{phase_num}-UAT.md (UAT with diagnoses)
|
|
370
|
+
- .planning/STATE.md (Project State)
|
|
371
|
+
- .planning/ROADMAP.md (Roadmap)
|
|
372
|
+
</files_to_read>
|
|
376
373
|
|
|
377
374
|
</planning_context>
|
|
378
375
|
|
|
@@ -416,8 +413,9 @@ Task(
|
|
|
416
413
|
**Phase:** {phase_number}
|
|
417
414
|
**Phase Goal:** Close diagnosed gaps from UAT
|
|
418
415
|
|
|
419
|
-
|
|
420
|
-
|
|
416
|
+
<files_to_read>
|
|
417
|
+
- {phase_dir}/*-PLAN.md (Plans to verify)
|
|
418
|
+
</files_to_read>
|
|
421
419
|
|
|
422
420
|
</verification_context>
|
|
423
421
|
|
|
@@ -455,8 +453,9 @@ Task(
|
|
|
455
453
|
**Phase:** {phase_number}
|
|
456
454
|
**Mode:** revision
|
|
457
455
|
|
|
458
|
-
|
|
459
|
-
|
|
456
|
+
<files_to_read>
|
|
457
|
+
- {phase_dir}/*-PLAN.md (Existing plans)
|
|
458
|
+
</files_to_read>
|
|
460
459
|
|
|
461
460
|
**Checker issues:**
|
|
462
461
|
{structured_issues_from_checker}
|
|
@@ -0,0 +1,122 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
// Context Monitor - PostToolUse hook
|
|
3
|
+
// Reads context metrics from the statusline bridge file and injects
|
|
4
|
+
// warnings when context usage is high. This makes the AGENT aware of
|
|
5
|
+
// context limits (the statusline only shows the user).
|
|
6
|
+
//
|
|
7
|
+
// How it works:
|
|
8
|
+
// 1. The statusline hook writes metrics to /tmp/codex-ctx-{session_id}.json
|
|
9
|
+
// 2. This hook reads those metrics after each tool use
|
|
10
|
+
// 3. When remaining context drops below thresholds, it injects a warning
|
|
11
|
+
// as additionalContext, which the agent sees in its conversation
|
|
12
|
+
//
|
|
13
|
+
// Thresholds:
|
|
14
|
+
// WARNING (remaining <= 35%): Agent should wrap up current task
|
|
15
|
+
// CRITICAL (remaining <= 25%): Agent should stop immediately and save state
|
|
16
|
+
//
|
|
17
|
+
// Debounce: 5 tool uses between warnings to avoid spam
|
|
18
|
+
// Severity escalation bypasses debounce (WARNING -> CRITICAL fires immediately)
|
|
19
|
+
|
|
20
|
+
const fs = require('fs');
|
|
21
|
+
const os = require('os');
|
|
22
|
+
const path = require('path');
|
|
23
|
+
|
|
24
|
+
const WARNING_THRESHOLD = 35; // remaining_percentage <= 35%
|
|
25
|
+
const CRITICAL_THRESHOLD = 25; // remaining_percentage <= 25%
|
|
26
|
+
const STALE_SECONDS = 60; // ignore metrics older than 60s
|
|
27
|
+
const DEBOUNCE_CALLS = 5; // min tool uses between warnings
|
|
28
|
+
|
|
29
|
+
let input = '';
|
|
30
|
+
process.stdin.setEncoding('utf8');
|
|
31
|
+
process.stdin.on('data', chunk => input += chunk);
|
|
32
|
+
process.stdin.on('end', () => {
|
|
33
|
+
try {
|
|
34
|
+
const data = JSON.parse(input);
|
|
35
|
+
const sessionId = data.session_id;
|
|
36
|
+
|
|
37
|
+
if (!sessionId) {
|
|
38
|
+
process.exit(0);
|
|
39
|
+
}
|
|
40
|
+
|
|
41
|
+
const tmpDir = os.tmpdir();
|
|
42
|
+
const metricsPath = path.join(tmpDir, `codex-ctx-${sessionId}.json`);
|
|
43
|
+
|
|
44
|
+
// If no metrics file, this is a subagent or fresh session -- exit silently
|
|
45
|
+
if (!fs.existsSync(metricsPath)) {
|
|
46
|
+
process.exit(0);
|
|
47
|
+
}
|
|
48
|
+
|
|
49
|
+
const metrics = JSON.parse(fs.readFileSync(metricsPath, 'utf8'));
|
|
50
|
+
const now = Math.floor(Date.now() / 1000);
|
|
51
|
+
|
|
52
|
+
// Ignore stale metrics
|
|
53
|
+
if (metrics.timestamp && (now - metrics.timestamp) > STALE_SECONDS) {
|
|
54
|
+
process.exit(0);
|
|
55
|
+
}
|
|
56
|
+
|
|
57
|
+
const remaining = metrics.remaining_percentage;
|
|
58
|
+
const usedPct = metrics.used_pct;
|
|
59
|
+
|
|
60
|
+
// No warning needed
|
|
61
|
+
if (remaining > WARNING_THRESHOLD) {
|
|
62
|
+
process.exit(0);
|
|
63
|
+
}
|
|
64
|
+
|
|
65
|
+
// Debounce: check if we warned recently
|
|
66
|
+
const warnPath = path.join(tmpDir, `codex-ctx-${sessionId}-warned.json`);
|
|
67
|
+
let warnData = { callsSinceWarn: 0, lastLevel: null };
|
|
68
|
+
let firstWarn = true;
|
|
69
|
+
|
|
70
|
+
if (fs.existsSync(warnPath)) {
|
|
71
|
+
try {
|
|
72
|
+
warnData = JSON.parse(fs.readFileSync(warnPath, 'utf8'));
|
|
73
|
+
firstWarn = false;
|
|
74
|
+
} catch (e) {
|
|
75
|
+
// Corrupted file, reset
|
|
76
|
+
}
|
|
77
|
+
}
|
|
78
|
+
|
|
79
|
+
warnData.callsSinceWarn = (warnData.callsSinceWarn || 0) + 1;
|
|
80
|
+
|
|
81
|
+
const isCritical = remaining <= CRITICAL_THRESHOLD;
|
|
82
|
+
const currentLevel = isCritical ? 'critical' : 'warning';
|
|
83
|
+
|
|
84
|
+
// Emit immediately on first warning, then debounce subsequent ones
|
|
85
|
+
// Severity escalation (WARNING -> CRITICAL) bypasses debounce
|
|
86
|
+
const severityEscalated = currentLevel === 'critical' && warnData.lastLevel === 'warning';
|
|
87
|
+
if (!firstWarn && warnData.callsSinceWarn < DEBOUNCE_CALLS && !severityEscalated) {
|
|
88
|
+
// Update counter and exit without warning
|
|
89
|
+
fs.writeFileSync(warnPath, JSON.stringify(warnData));
|
|
90
|
+
process.exit(0);
|
|
91
|
+
}
|
|
92
|
+
|
|
93
|
+
// Reset debounce counter
|
|
94
|
+
warnData.callsSinceWarn = 0;
|
|
95
|
+
warnData.lastLevel = currentLevel;
|
|
96
|
+
fs.writeFileSync(warnPath, JSON.stringify(warnData));
|
|
97
|
+
|
|
98
|
+
// Build warning message
|
|
99
|
+
let message;
|
|
100
|
+
if (isCritical) {
|
|
101
|
+
message = `CONTEXT MONITOR CRITICAL: Usage at ${usedPct}%. Remaining: ${remaining}%. ` +
|
|
102
|
+
'STOP new work immediately. Save state NOW and inform the user that context is nearly exhausted. ' +
|
|
103
|
+
'If using GSD, run /gsd:pause-work to save execution state.';
|
|
104
|
+
} else {
|
|
105
|
+
message = `CONTEXT MONITOR WARNING: Usage at ${usedPct}%. Remaining: ${remaining}%. ` +
|
|
106
|
+
'Begin wrapping up current task. Do not start new complex work. ' +
|
|
107
|
+
'If using GSD, consider /gsd:pause-work to save state.';
|
|
108
|
+
}
|
|
109
|
+
|
|
110
|
+
const output = {
|
|
111
|
+
hookSpecificOutput: {
|
|
112
|
+
hookEventName: "PostToolUse",
|
|
113
|
+
additionalContext: message
|
|
114
|
+
}
|
|
115
|
+
};
|
|
116
|
+
|
|
117
|
+
process.stdout.write(JSON.stringify(output));
|
|
118
|
+
} catch (e) {
|
|
119
|
+
// Silent fail -- never block tool execution
|
|
120
|
+
process.exit(0);
|
|
121
|
+
}
|
|
122
|
+
});
|
|
@@ -27,6 +27,23 @@ process.stdin.on('end', () => {
|
|
|
27
27
|
// Scale: 80% real usage = 100% displayed
|
|
28
28
|
const used = Math.min(100, Math.round((rawUsed / 80) * 100));
|
|
29
29
|
|
|
30
|
+
// Write context metrics to bridge file for the context-monitor PostToolUse hook.
|
|
31
|
+
// The monitor reads this file to inject agent-facing warnings when context is low.
|
|
32
|
+
if (session) {
|
|
33
|
+
try {
|
|
34
|
+
const bridgePath = path.join(os.tmpdir(), `codex-ctx-${session}.json`);
|
|
35
|
+
const bridgeData = JSON.stringify({
|
|
36
|
+
session_id: session,
|
|
37
|
+
remaining_percentage: remaining,
|
|
38
|
+
used_pct: used,
|
|
39
|
+
timestamp: Math.floor(Date.now() / 1000)
|
|
40
|
+
});
|
|
41
|
+
fs.writeFileSync(bridgePath, bridgeData);
|
|
42
|
+
} catch (e) {
|
|
43
|
+
// Silent fail -- bridge is best-effort, don't break statusline
|
|
44
|
+
}
|
|
45
|
+
}
|
|
46
|
+
|
|
30
47
|
// Build progress bar (10 segments)
|
|
31
48
|
const filled = Math.floor(used / 10);
|
|
32
49
|
const bar = '█'.repeat(filled) + '░'.repeat(10 - filled);
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@undeemed/get-shit-done-codex",
|
|
3
|
-
"version": "1.20.
|
|
3
|
+
"version": "1.20.8",
|
|
4
4
|
"description": "A meta-prompting, context engineering and spec-driven development system for OpenAI Codex (CLI and Desktop). Fork of get-shit-done by TÂCHES, adapted for Codex by undeemed.",
|
|
5
5
|
"bin": {
|
|
6
6
|
"get-shit-done-codex": "bin/install.js"
|
|
@@ -18,13 +18,29 @@
|
|
|
18
18
|
"AGENTS.md"
|
|
19
19
|
],
|
|
20
20
|
"keywords": [
|
|
21
|
+
"get-shit-done",
|
|
22
|
+
"gsd",
|
|
21
23
|
"openai",
|
|
22
24
|
"codex",
|
|
23
25
|
"codex-cli",
|
|
26
|
+
"codex-desktop",
|
|
27
|
+
"codex-app",
|
|
28
|
+
"openai-codex",
|
|
24
29
|
"ai",
|
|
30
|
+
"ai-coding",
|
|
31
|
+
"ai-agents",
|
|
25
32
|
"meta-prompting",
|
|
26
33
|
"context-engineering",
|
|
34
|
+
"context-rot",
|
|
27
35
|
"spec-driven-development",
|
|
36
|
+
"prompt-engineering",
|
|
37
|
+
"multi-agent",
|
|
38
|
+
"subagent",
|
|
39
|
+
"ai-workflow",
|
|
40
|
+
"developer-tools",
|
|
41
|
+
"dev-tools",
|
|
42
|
+
"productivity",
|
|
43
|
+
"code-generation",
|
|
28
44
|
"agents"
|
|
29
45
|
],
|
|
30
46
|
"author": "undeemed <jerry.x0930@gmail.com>",
|
|
@@ -50,6 +66,6 @@
|
|
|
50
66
|
"scripts": {
|
|
51
67
|
"build:hooks": "node scripts/build-hooks.js",
|
|
52
68
|
"prepublishOnly": "npm run build:hooks",
|
|
53
|
-
"test": "node --test
|
|
69
|
+
"test": "node --test tests/*.test.cjs"
|
|
54
70
|
}
|
|
55
71
|
}
|