@only1btayy/g2w 1.0.32 → 1.0.33

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 CHANGED
@@ -4,18 +4,6 @@
4
4
 
5
5
  </div>
6
6
 
7
- # G2W
8
-
9
- The best relationships are built on trust. Trust comes from honesty, and honesty breeds clarity and understanding.
10
-
11
- I got tired of going in circles with Claude and others because the systems I was using were not set up in a way that builds trust between the user and the model. Some of the top CEOs and big business people who use AI are not concerned with the question — "can it build?" Instead they are focused on — "can we trust what it builds and can we ship it?"
12
-
13
- This is not just a workflow system. Not just a task runner. This is a protocol for building trust between you and your AI so what gets built is actually what you envisioned. No more back and forth and all the other bullshit that gets in the way.
14
-
15
- **G2W is a relationship protocol.**
16
-
17
- ---
18
-
19
7
  [![npm version](https://img.shields.io/npm/v/%40only1btayy%2Fg2w?style=for-the-badge&logo=npm&logoColor=white&color=CB3837&label=npm)](https://www.npmjs.com/package/@only1btayy/g2w)
20
8
  [![license](https://img.shields.io/badge/license-MIT-6e7681?style=for-the-badge)](LICENSE)
21
9
  [![platform](https://img.shields.io/badge/platform-Claude%20Code-8957e5?style=for-the-badge)](https://claude.ai/code)
@@ -31,13 +19,27 @@ npm install -g @only1btayy/g2w && g2w
31
19
 
32
20
  ---
33
21
 
34
- [The Name](#the-name) · [The Problem](#the-problem) · [How It Works](#how-it-works) · [The Commands](#the-commands) · [How 2 Install](#how-2-install) · [Who It's For](#who-its-for) · [Philosophy](#the-philosophy)
22
+ [The Name](#the-name) · [The Problem](#the-problem) · [How It Works](#how-it-works) · [Resource Limits](#resource-limits) · [The Commands](#the-commands) · [How 2 Install](#how-2-install)
23
+
24
+ ---
25
+
26
+ # G2W
27
+
28
+ The best relationships are built on trust. Trust comes from honesty, and honesty breeds clarity and understanding.
29
+
30
+ I got tired of going in circles with Claude because the systems I was using weren't set up to build genuine trust between the user and the model. The top CEOs and business leaders using AI aren't asking "can it build?" They're asking "can we trust what it builds, and can we ship it?"
31
+
32
+ This is not just a workflow system. Not just a task runner. This is a protocol for building trust between you and your AI so what gets built is actually what you envisioned. No more back and forth, no more bullshit getting in the way.
33
+
34
+ **G2W is a relationship protocol.**
35
+
36
+ If you've ever felt like your AI was working against you instead of with you, G2W is for you.
35
37
 
36
38
  ---
37
39
 
38
40
  ## The Name
39
41
 
40
- I named G2W after my motto in life "It's going to work or it's going to work." This is a perspective shift I had that allows me to view even the apparent losses in life as wins because the gems are in the data. Every loss, every mistake, every doubt and fear we have is data that is filled with gems. We just have to choose to look at it that way. The people who change the world are often considered crazy and delusional until they actually change it. Then the "crazy" becomes genius and the "delusional" becomes relentless. I want you to dare to be relentless in your approach to the challenges in life and remember it's going to work or it's going to work — ain't no other options.
42
+ I named G2W after my motto in life: "It's going to work or it's going to work." This is a perspective shift I had that allows me to view even the apparent losses in life as wins because the gems are in the data. Every loss, every mistake, every doubt and fear we have is data that is filled with gems. We just have to choose to look at it that way. The people who change the world are often considered crazy and delusional until they actually change it. Then the "crazy" becomes genius and the "delusional" becomes relentless. I want you to dare to be relentless in your approach to the challenges in life and remember, it's going to work or it's going to work. Ain't no other options.
41
43
 
42
44
  No in-between. No failure as an option. Two paths and both lead to success.
43
45
 
@@ -45,11 +47,28 @@ No in-between. No failure as an option. Two paths and both lead to success.
45
47
 
46
48
  ## The Problem
47
49
 
48
- You've worked with AI before. You know how it goes.
50
+ I want to preface this by saying I'm a vibe-coder. I have the utmost respect for actual devs and feel genuinely grateful to live in a time where tools like Claude and Codex let people like me get ideas out without needing to know how to code or have a big budget. I felt like I finally found my thing.
51
+
52
+ As many of you may have noticed, Claude seemed to take a noticeable dip in performance quality around February 2026. Some people swear it's just a matter of not knowing how to use it properly, and hey, great for you, but if you experienced the dip, you know exactly what I'm talking about.
53
+
54
+ He simply became unable to handle even simple tasks or edits. He'd go completely off the rails, then turn around and say "yeah you're right" over and over which drove me near insanity. I followed every recommended protocol, watched and read tutorial after tutorial, and even used the exact claude.md template that Boris Cherny shared on his X account. So you can miss me with the "oh you're just not using it right" talk. Claude worked great until he didn't. A lot of you can relate.
55
+
56
+ I'd say "make this button this size" and get back "I've already decided the current size is optimal." WTF.
57
+
58
+ Sound familiar?
59
+
60
+ - Spending an hour in a planning session, then having to repeat everything when it's time to execute
61
+ - Watching it make changes that break three other things it never bothered to check, then admit it after the fact
62
+ - Seeing it commit code you never approved
63
+ - Having it guess instead of just asking
49
64
 
50
- You say "make this button this size" and it does something else and explains why it was right. You spend an hour in a discussion session and then have to repeat everything again when it's time to plan. It makes a change that breaks three other things it never bothered to check. It commits code you didn't approve. It guesses instead of asking.
65
+ I did try other systems along the way, like GSD 1 & 2 (Get Shit Done) by TACHES. It's great if you want AI to build everything out while you step away, but I wanted more control and involvement. I wanted to learn as I went, steer the ship, and understand how what I was building actually worked. GSD felt clunky and slow to me at times. No shade to what TACHES built though, it's wildly popular for a reason and he deserves every bit of the success he's seeing. It just wasn't the fit for me.
51
66
 
52
- G2W fixes all of that. Not by adding more rules but by building a system that genuinely earns trust.
67
+ Deep down I knew there had to be something I could do to get Claude back on track. Even 80% of what he was when I started, I could live with that. Just not the full-blown-idiot-Claude days.
68
+
69
+ After collecting data from Reddit and Facebook posts, the lightbulb went off. That was the birth of G2W.
70
+
71
+ G2W was created for those of us who just want the AI to do what we ask. Simple. Nothing more, nothing less. Not by piling on more rules but by building a system that genuinely earns trust.
53
72
 
54
73
  The problem was never intelligence. The problem was process.
55
74
 
@@ -61,27 +80,47 @@ The problem was never intelligence. The problem was process.
61
80
 
62
81
  ### The Modular Doc System
63
82
 
64
- Every project gets a full set of living documents `ARCHITECTURE.md`, `CONVENTIONS.md`, `ERRORS.md`, `CHANGELOG.md`, and more. The rule is simple: when you change code that any doc describes, update that doc in the same session. No separate documentation pass. No stale docs. The knowledge base stays current automatically.
83
+ Every project gets a full set of living documents auto-generated by `/g2w:bring2life`. The rule is simple: when you change code that any doc describes, update that doc in the same session. No separate documentation pass. No stale docs. The knowledge base stays current automatically.
84
+
85
+ All docs live in `~/.g2w/projects/[your-project]/`, zero footprint inside your actual repo.
86
+
87
+ | Document | What It Does |
88
+ |---|---|
89
+ | `ARCHITECTURE.md` | System design, modules, data flow, how components connect |
90
+ | `CONVENTIONS.md` | Code style, naming patterns, project idioms, and a Context Budget that tells the AI which files to read selectively vs. fully |
91
+ | `FEATURES.md` | Complete list of what the project does and feature status |
92
+ | `ERRORS.md` | Bugs, dead code, anti-patterns, and security issues found during automatic code audit |
93
+ | `TESTING.md` | How to test, coverage gaps, and Golden Cases: critical scenarios that must never break regardless of what task is running |
94
+ | `TRAPS.md` | Project-specific pitfalls, things that look right but break things in this codebase |
95
+ | `SECURITY.md` | Auth, data protection, threat analysis |
96
+ | `SCALING.md` | Performance limits, bottlenecks, growth paths |
97
+ | `CHANGELOG.md` | Version history and significant changes |
98
+ | `CURRENT.md` | Active session state: what's in progress, what's next, declared scope |
99
+ | `PLAN.md` | The locked task plan, populated by The Visionary, approved by The Challenger |
100
+ | `CLAUDE.md` | Project-specific instructions that load into every Claude session automatically |
101
+ | `RESEARCH.md` | Background research on frameworks, libraries, and best practices (optional, generated during planning) |
102
+
103
+ Every doc is a draft seeded from your actual code. Gaps are marked with `❓ [UNKNOWN]` so you know exactly what needs filling in.
65
104
 
66
105
  ---
67
106
 
68
107
  ### Talk Once. Plan Once. Build.
69
108
 
70
- You start a conversation. You describe your vision. G2W listens, asks smart questions, and runs research silently in the background tech stack, existing solutions, the ecosystem. By the time you're done talking, the plan is already written and locked.
109
+ You start a conversation. You describe your vision. G2W listens, asks smart questions, and runs research silently in the background: tech stack, existing solutions, the ecosystem. By the time you're done talking, the plan is already written and locked.
71
110
 
72
111
  No separate phases. No repeating yourself. Just a conversation that ends with something ready to build.
73
112
 
74
- Research isn't just a web search. G2W uses Context7 for live library docs, Exa for semantic search across similar projects, Firecrawl to crawl repos and docs sites, and Repomix to pack reference codebases so The Visionary can read how a production-quality version of what you're building actually works. Everything saves to `RESEARCH.md` and persists future sessions don't re-run research from scratch.
113
+ Research isn't just a web search. G2W uses Context7 for live library docs, Exa for semantic search across similar projects, Firecrawl to crawl repos and docs sites, and Repomix to pack reference codebases so The Visionary can read how a production-quality version of what you're building actually works. Everything saves to `RESEARCH.md` and persists, so future sessions don't re-run research from scratch.
75
114
 
76
115
  ---
77
116
 
78
117
  ### What Ships With G2W
79
118
 
80
- These install automatically no setup, no API keys, no extra steps:
119
+ These install automatically, no setup, no API keys, no extra steps:
81
120
 
82
121
  | Tool | What It Does |
83
122
  |---|---|
84
- | [Context7](https://context7.com) | Live library docs in every research and planning phase no stale training data |
123
+ | [Context7](https://context7.com) | Live library docs in every research and planning phase, no stale training data |
85
124
  | [Shadcn/UI MCP](https://www.shadcn.io/mcp) | Real React component implementations with TypeScript props |
86
125
  | [Tailwind CSS MCP](https://github.com/CarbonoDev/tailwindcss-mcp-server) | Utility classes, color palettes, CSS-to-Tailwind conversion |
87
126
  | [A11y MCP](https://github.com/priyankark/a11y-mcp) | Accessibility audits and WCAG compliance checks |
@@ -95,28 +134,19 @@ Claude reaches for these automatically when they're relevant. You don't have to
95
134
  Optional tools that make G2W stronger. Run `g2w power-ups` to set these up anytime.
96
135
 
97
136
  **Free (just needs a key):**
98
-
99
- | Tool | What It Adds | Get Your Key |
100
- |---|---|---|
101
- | [21st.dev](https://21st.dev) | AI-powered UI component generation like v0 in your IDE | [21st.dev/magic/console](https://21st.dev/magic/console) |
102
- | [Motion](https://motion.dev) | Production-grade animations with AI Kit | [plus.motion.dev/personal-token](https://plus.motion.dev/personal-token) |
103
- | [Figma MCP](https://help.figma.com/hc/en-us/articles/32132100833559) | Design-to-code from Figma frames (free during beta) | [figma.com](https://figma.com) |
104
- | [Marketing Skills](https://github.com/coreyhaines31/marketingskills) | 40+ skills for copywriting, SEO, conversion, growth | No key needed |
137
+ - [21st.dev](https://21st.dev), AI-powered UI component generation
138
+ - [Motion](https://motion.dev), Production-grade animations with AI Kit
139
+ - [Figma MCP](https://help.figma.com/hc/en-us/articles/32132100833559), Design-to-code from Figma frames (free during beta)
140
+ - [Marketing Skills](https://github.com/coreyhaines31/marketingskills), 40+ skills for copywriting, SEO, conversion, growth (no key needed)
105
141
 
106
142
  **Research (paid):**
107
-
108
- | Tool | What It Adds |
109
- |---|---|
110
- | [Exa](https://exa.ai) | Semantic search for similar projects and best practices |
111
- | [Firecrawl](https://firecrawl.dev) | Deep crawling of repos and docs sites during research |
143
+ - [Exa](https://exa.ai), Semantic search for similar projects and best practices
144
+ - [Firecrawl](https://firecrawl.dev), Deep crawling of repos and docs sites during research
112
145
 
113
146
  **Workflow:**
114
-
115
- | Tool | What It Adds |
116
- |---|---|
117
- | [Repomix](https://github.com/yamadashy/repomix) | Packs entire codebases into one AI-optimized file — `bring2life` uses this |
118
- | [MemPalace](https://github.com/milla-jovovich/mempalace) | Persistent memory across sessions — decisions survive context clears |
119
- | [Superpowers](https://github.com/supermemoryai/superpowers-claude) | Enhanced planning and review capabilities for Claude users |
147
+ - [Repomix](https://github.com/yamadashy/repomix), Packs entire codebases into one AI-optimized file
148
+ - [MemPalace](https://github.com/milla-jovovich/mempalace), Persistent memory across sessions
149
+ - [Superpowers](https://github.com/supermemoryai/superpowers-claude), Enhanced planning and review capabilities
120
150
 
121
151
  G2W uses what's available and falls back gracefully when something isn't there.
122
152
 
@@ -129,7 +159,7 @@ Once the plan locks, The Foundation takes over. Five roles. One mission. Get it
129
159
  | Agent | Role |
130
160
  |---|---|
131
161
  | The Visionary | Writes a complete plan with real decisions and no placeholders |
132
- | The Challenger | Adversarial review finds every way the plan could fail before coding starts |
162
+ | The Challenger | Adversarial review, finds every way the plan could fail before coding starts |
133
163
  | The Builder | Builds exactly what the locked plan says, nothing extra |
134
164
  | The Inspector | Verifies everything against the plan and loops until it's clean |
135
165
  | The Leader | Manages the team and keeps everything on track |
@@ -140,15 +170,15 @@ The plan is the contract. By the time The Builder touches a single line of code,
140
170
 
141
171
  ### Optional Methods
142
172
 
143
- Each Foundation agent is also a direct slash command. The normal flow runs through `/g2w:build2gether` and `/g2w:get2work` but if you know what you're doing, you can jump straight into any stage of the pipeline.
173
+ Each Foundation agent is also a direct slash command. The normal flow runs through `/g2w:build2gether` and `/g2w:get2work`, but if you know what you're doing, you can jump straight into any stage of the pipeline.
144
174
 
145
175
  | Command | When to use it directly |
146
176
  |---|---|
147
- | `/g2w:the-visionary` | You have a half-written plan and just want it finished skip the full build2gether flow |
177
+ | `/g2w:the-visionary` | You have a half-written plan and just want it finished, skip the full build2gether flow |
148
178
  | `/g2w:the-challenger` | You wrote your own plan outside G2W and want it stress-tested before building |
149
- | `/g2w:the-builder` | Plan is already locked skip straight to building |
150
- | `/g2w:the-inspector` | Code is already written just verify it against a plan |
151
- | `/g2w:the-leader` | Kick off the full pipeline includes automatic code audit before Challenger reviews |
179
+ | `/g2w:the-builder` | Plan is already locked, skip straight to building |
180
+ | `/g2w:the-inspector` | Code is already written, just verify it against a plan |
181
+ | `/g2w:the-leader` | Kick off the full pipeline, includes automatic code audit before Challenger reviews |
152
182
 
153
183
  These are escape hatches for engineers who don't need the ceremony. G2W has no ceiling.
154
184
 
@@ -159,10 +189,10 @@ These are escape hatches for engineers who don't need the ceremony. G2W has no c
159
189
  Delivered via CLAUDE.md so it loads into every session automatically as project instructions.
160
190
 
161
191
  - Your explicit instruction is a direct order. No agent may override it, rationalize it away, or route around it.
162
- - The AI answers your question first and then asks to proceed never just acts.
192
+ - The AI answers your question first and then asks to proceed, never just acts.
163
193
  - No edits outside the declared scope.
164
194
  - No commits without your approval.
165
- - "I don't know" instead of guessing always.
195
+ - "I don't know" instead of guessing, always.
166
196
  - Uncertainty is labeled, not hidden. `[Inference]` and `[Unverified]` are used so you always know what's confirmed and what isn't.
167
197
  - If scope creeps, it stops and flags it before touching anything.
168
198
 
@@ -181,9 +211,27 @@ Only after working through those questions does execution begin. Taking more tim
181
211
 
182
212
  ---
183
213
 
184
- ### Git Without The Friction
214
+ ### Resource Limits
215
+
216
+ AI agents don't slow down on their own. They keep running, keep calling models, and keep charging your account until you step in and control it. G2W has a built-in safety layer that tracks usage per session and stops runaway behavior before it burns through your budget.
217
+
218
+ **What it tracks:**
185
219
 
186
- Safe git operations add, commit, push, status, log — run without approval prompts. One command handles the whole thing. Add, commit, push. Done. No multi-step back and forth, no unnecessary interruptions. You stay in flow.
220
+ | Metric | Default Limit | What Happens |
221
+ |---|---|---|
222
+ | Total tool calls per session | 200 | Hard stop, wrap up and hand off |
223
+ | PLAN.md revisions | 5 | Hard stop, Visionary/Challenger loop is stuck, escalate to user |
224
+ | Unique files touched | 25 | Hard stop, scope creep detected |
225
+ | Edits to the same file | 8 | Warning, possible fix loop |
226
+ | Tool call usage at 80% | N/A | Warning, start wrapping up |
227
+
228
+ **Session logging:** Every completed session gets logged to `~/.g2w/session-log.jsonl`: project name, tool call breakdown, duration. You can see exactly which tasks are driving spend.
229
+
230
+ **Configurable:** All limits live in `~/.g2w/resource-limits.json`. Edit any number. Per-project overrides go in `~/.g2w/projects/[project]/resource-limits.json`.
231
+
232
+ **Kill switch:** Set `"enabled": false` in the config to bypass all limits. Delete `~/.g2w/session-limits.json` to reset counters mid-session.
233
+
234
+ The resource limits hook runs first in the chain, before scope guard, before A-Game, before anything else. If the session is over limit, nothing else fires.
187
235
 
188
236
  ---
189
237
 
@@ -191,15 +239,15 @@ Safe git operations — add, commit, push, status, log — run without approval
191
239
 
192
240
  | Command | What It Does |
193
241
  |---|---|
194
- | `/g2w:bring2life` | Onboard an existing codebase scans it, generates your doc files, flags gaps |
195
- | `/g2w:build2gether` | Start a new project brainstorm, research, and locked plan in one conversation |
242
+ | `/g2w:bring2life` | Onboard an existing codebase, scans it, generates your doc files, flags gaps |
243
+ | `/g2w:build2gether` | Start a new project, brainstorm, research, and locked plan in one conversation |
196
244
  | `/g2w:back2it` | Pick up right where you left off |
197
245
  | `/g2w:get2work` | Execute the current task |
198
- | `/g2w:cut2it` | Fast mode small tasks, no ceremony |
246
+ | `/g2w:cut2it` | Fast mode, small tasks, no ceremony |
199
247
  | `/g2w:back2basics` | Strip context and start clean |
200
248
  | `/g2w:true2plan` | Verify that what was built actually matches the plan |
201
249
  | `/g2w:true2dagame` | Full system health check |
202
- | `/g2w:ready2save` | Wrap up the session update CURRENT.md, capture key decisions and the reasoning behind them, hand off cleanly |
250
+ | `/g2w:ready2save` | Wrap up the session, update CURRENT.md, capture key decisions and the reasoning behind them, hand off cleanly |
203
251
 
204
252
  ---
205
253
 
@@ -209,7 +257,7 @@ Safe git operations — add, commit, push, status, log — run without approval
209
257
  npm install -g @only1btayy/g2w && g2w
210
258
  ```
211
259
 
212
- That's it. G2W installs globally into `~/.claude/` automatically skills, hooks, and design tools ready in every project, everywhere.
260
+ That's it. G2W installs globally into `~/.claude/` automatically, skills, hooks, and design tools ready in every project, everywhere.
213
261
 
214
262
  To update:
215
263
 
@@ -235,32 +283,30 @@ Skills, hooks, and MCP servers are removed from `~/.claude/` automatically.
235
283
 
236
284
  ---
237
285
 
238
- ## Who It's For
239
-
240
- Everyone tired of the bullshit. Vibe coders who just want to ship. Senior engineers who want control. Solo builders with no team and no co-founder.
286
+ ## Contributing
241
287
 
242
- If you've ever felt like your AI was working against you instead of with you, G2W is for you.
288
+ G2W is open source and contributions are welcome.
243
289
 
244
- G2W works in other models — the Modular Doc System and commands are model-agnostic. But Claude Code is where it's fully alive. The Trust Layer lives in CLAUDE.md so it loads as project instructions every session. The A-Game Hook and context warnings are hook-delivered, running automatically without relying on the AI to remember. Other models get the workflow. Claude Code gets the guarantees.
245
-
246
- ---
247
-
248
- ## The Philosophy
249
-
250
- Speed comes from simplicity. Control comes from clarity. If you need a system to manage your system, it's already broken. G2W is not a factory. It's a studio.
251
-
252
- ---
290
+ **How to get started:**
291
+ 1. Fork the repo
292
+ 2. Clone it and run `npm install`
293
+ 3. Make your changes in a feature branch
294
+ 4. Run `node test/hooks-and-skills.test.js` to make sure nothing breaks
295
+ 5. Open a PR with a clear description of what you changed and why
253
296
 
254
- ## Status
297
+ **Where help is needed:**
298
+ - Mac and Linux testing, G2W was built on Windows and needs cross-platform validation
299
+ - New hook ideas, if you've hit a pattern where AI goes off the rails, it might be a hook
300
+ - Bug reports, if something doesn't work, open an issue
255
301
 
256
- Under active development. First real-world test case is Blackhole VST running through `/g2w:bring2life`.
302
+ No contribution is too small. If you found a typo, fix it. If you have an idea, open an issue and let's talk about it.
257
303
 
258
304
  ---
259
305
 
260
306
  ## Acknowledgements
261
307
 
262
- - **[johnkf5-ops/the-dev-squad](https://github.com/johnkf5-ops/the-dev-squad)** inspired The Foundation's multi-agent pipeline
263
- - **John Knopf** modular doc system approach. His words: *"Take it, run with it, use it, modify it, make it better. That's the whole point."*
308
+ - **[johnkf5-ops/the-dev-squad](https://github.com/johnkf5-ops/the-dev-squad)**, inspired The Foundation's multi-agent pipeline
309
+ - **John Knopf**, modular doc system approach. His words: *"Take it, run with it, use it, modify it, make it better. That's the whole point."*
264
310
 
265
311
  ---
266
312
 
@@ -0,0 +1,239 @@
1
+ #!/usr/bin/env node
2
+ // G2W Resource Limits — PreToolUse hook
3
+ // Tracks tool calls, plan revisions, and file edits per session.
4
+ // Warns at thresholds, hard blocks at limits. Logs session summaries.
5
+ // Config: ~/.g2w/resource-limits.json | State: ~/.g2w/session-limits.json
6
+
7
+ const fs = require('fs');
8
+ const path = require('path');
9
+ const os = require('os');
10
+
11
+ const G2W_DIR = path.join(os.homedir(), '.g2w');
12
+ const CONFIG_FILE = path.join(G2W_DIR, 'resource-limits.json');
13
+ const STATE_FILE = path.join(G2W_DIR, 'session-limits.json');
14
+ const LOG_FILE = path.join(G2W_DIR, 'session-log.jsonl');
15
+ const CURRENT_MD = path.join(G2W_DIR, 'CURRENT.md');
16
+
17
+ const DEFAULTS = {
18
+ enabled: true,
19
+ maxToolCalls: 200,
20
+ warnAtToolCallPercent: 80,
21
+ maxPlanRevisions: 5,
22
+ maxFileEdits: 8,
23
+ maxUniqueFiles: 25,
24
+ sessionTimeoutHours: 4
25
+ };
26
+
27
+ function loadJSON(filePath, fallback) {
28
+ try {
29
+ return JSON.parse(fs.readFileSync(filePath, 'utf8'));
30
+ } catch {
31
+ return fallback;
32
+ }
33
+ }
34
+
35
+ function saveJSON(filePath, data) {
36
+ try {
37
+ fs.mkdirSync(path.dirname(filePath), { recursive: true });
38
+ fs.writeFileSync(filePath, JSON.stringify(data, null, 2));
39
+ } catch {}
40
+ }
41
+
42
+ function appendLog(line) {
43
+ try {
44
+ fs.mkdirSync(path.dirname(LOG_FILE), { recursive: true });
45
+ fs.appendFileSync(LOG_FILE, JSON.stringify(line) + '\n');
46
+ } catch {}
47
+ }
48
+
49
+ function getActiveProject() {
50
+ try {
51
+ const content = fs.readFileSync(CURRENT_MD, 'utf8');
52
+ const match = content.match(/^active:\s*(.+)/m);
53
+ return match ? match[1].trim() : null;
54
+ } catch {
55
+ return null;
56
+ }
57
+ }
58
+
59
+ function loadConfig() {
60
+ const global = loadJSON(CONFIG_FILE, {});
61
+ const project = getActiveProject();
62
+ let projectConfig = {};
63
+ if (project) {
64
+ const projectConfigPath = path.join(G2W_DIR, 'projects', project, 'resource-limits.json');
65
+ projectConfig = loadJSON(projectConfigPath, {});
66
+ }
67
+ return { ...DEFAULTS, ...global, ...projectConfig };
68
+ }
69
+
70
+ function freshState(project) {
71
+ return {
72
+ startedAt: new Date().toISOString(),
73
+ project: project || 'unknown',
74
+ counters: {
75
+ totalToolCalls: 0,
76
+ writes: 0,
77
+ edits: 0,
78
+ bashCalls: 0,
79
+ uniqueFilesTouched: [],
80
+ planRevisions: 0,
81
+ fileEditCounts: {}
82
+ },
83
+ warnings: {
84
+ toolCallWarningFired: false,
85
+ planLoopWarningFired: false
86
+ }
87
+ };
88
+ }
89
+
90
+ function logSession(state) {
91
+ if (!state || state.counters.totalToolCalls === 0) return;
92
+ const start = new Date(state.startedAt);
93
+ const now = new Date();
94
+ const durationMinutes = Math.round((now - start) / 60000);
95
+ appendLog({
96
+ project: state.project,
97
+ startedAt: state.startedAt,
98
+ endedAt: now.toISOString(),
99
+ totalToolCalls: state.counters.totalToolCalls,
100
+ writes: state.counters.writes,
101
+ edits: state.counters.edits,
102
+ bashCalls: state.counters.bashCalls,
103
+ uniqueFiles: state.counters.uniqueFilesTouched.length,
104
+ planRevisions: state.counters.planRevisions,
105
+ durationMinutes
106
+ });
107
+ }
108
+
109
+ function isSessionExpired(state, timeoutHours) {
110
+ if (!state || !state.startedAt) return true;
111
+ const elapsed = (Date.now() - new Date(state.startedAt).getTime()) / 3600000;
112
+ return elapsed > timeoutHours;
113
+ }
114
+
115
+ function output(message) {
116
+ process.stdout.write(JSON.stringify({
117
+ hookSpecificOutput: {
118
+ hookEventName: 'PreToolUse',
119
+ additionalContext: message
120
+ }
121
+ }));
122
+ }
123
+
124
+ let input = '';
125
+ const stdinTimeout = setTimeout(() => process.exit(0), 3000);
126
+ process.stdin.setEncoding('utf8');
127
+ process.stdin.on('data', chunk => (input += chunk));
128
+ process.stdin.on('end', () => {
129
+ clearTimeout(stdinTimeout);
130
+ try {
131
+ const data = JSON.parse(input);
132
+ const toolName = data.tool_name;
133
+
134
+ // Only track Write, Edit, Bash
135
+ if (toolName !== 'Write' && toolName !== 'Edit' && toolName !== 'Bash') {
136
+ process.exit(0);
137
+ }
138
+
139
+ const config = loadConfig();
140
+
141
+ // Kill switch
142
+ if (!config.enabled) {
143
+ process.exit(0);
144
+ }
145
+
146
+ const project = getActiveProject();
147
+ let state = loadJSON(STATE_FILE, null);
148
+
149
+ // Reset if expired or missing
150
+ if (!state || isSessionExpired(state, config.sessionTimeoutHours)) {
151
+ logSession(state);
152
+ state = freshState(project);
153
+ }
154
+
155
+ const c = state.counters;
156
+ const filePath = data.tool_input?.file_path || '';
157
+ const normalizedPath = filePath ? path.normalize(filePath) : '';
158
+
159
+ // Increment counters
160
+ c.totalToolCalls++;
161
+ if (toolName === 'Write') c.writes++;
162
+ if (toolName === 'Edit') c.edits++;
163
+ if (toolName === 'Bash') c.bashCalls++;
164
+
165
+ // Track unique files and per-file edits (Write/Edit only)
166
+ if ((toolName === 'Write' || toolName === 'Edit') && normalizedPath) {
167
+ if (!c.uniqueFilesTouched.includes(normalizedPath)) {
168
+ c.uniqueFilesTouched.push(normalizedPath);
169
+ }
170
+ c.fileEditCounts[normalizedPath] = (c.fileEditCounts[normalizedPath] || 0) + 1;
171
+
172
+ // Track PLAN.md revisions
173
+ if (path.basename(filePath).toUpperCase() === 'PLAN.MD') {
174
+ c.planRevisions++;
175
+ }
176
+ }
177
+
178
+ // Save state before checking limits (so counters persist even on block)
179
+ saveJSON(STATE_FILE, state);
180
+
181
+ // --- Check limits (severity order: hard blocks first, then warnings) ---
182
+
183
+ // Hard block: total tool calls
184
+ if (c.totalToolCalls >= config.maxToolCalls) {
185
+ output(
186
+ `🛑 G2W RESOURCE LIMIT: Session hit ${c.totalToolCalls} tool calls (limit: ${config.maxToolCalls}). ` +
187
+ 'Stop and wrap up. Run /g2w:ready2save to hand off cleanly. ' +
188
+ 'To reset: delete ~/.g2w/session-limits.json'
189
+ );
190
+ process.exit(1);
191
+ }
192
+
193
+ // Hard block: plan revision loop
194
+ if (c.planRevisions >= config.maxPlanRevisions) {
195
+ output(
196
+ `🛑 G2W LOOP DETECTED: PLAN.md has been revised ${c.planRevisions} times (limit: ${config.maxPlanRevisions}). ` +
197
+ 'The Visionary/Challenger loop is stuck. Stop iterating and escalate to the user. ' +
198
+ 'Ask: "The plan has been revised ' + c.planRevisions + ' times. Should we lock it as-is, break the task smaller, or take a different approach?"'
199
+ );
200
+ process.exit(1);
201
+ }
202
+
203
+ // Hard block: too many unique files (scope creep)
204
+ if (c.uniqueFilesTouched.length >= config.maxUniqueFiles) {
205
+ output(
206
+ `🛑 G2W SCOPE CREEP: ${c.uniqueFilesTouched.length} unique files touched (limit: ${config.maxUniqueFiles}). ` +
207
+ 'This session is touching too many files. Stop and re-scope with the user.'
208
+ );
209
+ process.exit(1);
210
+ }
211
+
212
+ // Warning: file edit loop (specific file edited too many times)
213
+ if (normalizedPath && c.fileEditCounts[normalizedPath] >= config.maxFileEdits && !state.warnings[`fileLoop_${normalizedPath}`]) {
214
+ state.warnings[`fileLoop_${normalizedPath}`] = true;
215
+ saveJSON(STATE_FILE, state);
216
+ output(
217
+ `⚠️ G2W FIX LOOP WARNING: "${path.basename(filePath)}" has been edited ${c.fileEditCounts[normalizedPath]} times this session. ` +
218
+ 'Possible Inspector/Builder fix loop. Consider whether the approach needs to change.'
219
+ );
220
+ process.exit(0);
221
+ }
222
+
223
+ // Warning: approaching tool call limit
224
+ const warnThreshold = Math.floor(config.maxToolCalls * config.warnAtToolCallPercent / 100);
225
+ if (c.totalToolCalls >= warnThreshold && !state.warnings.toolCallWarningFired) {
226
+ state.warnings.toolCallWarningFired = true;
227
+ saveJSON(STATE_FILE, state);
228
+ output(
229
+ `⚠️ G2W RESOURCE WARNING: ${c.totalToolCalls}/${config.maxToolCalls} tool calls used (${config.warnAtToolCallPercent}%). ` +
230
+ 'Start wrapping up. Consider running /g2w:ready2save soon.'
231
+ );
232
+ process.exit(0);
233
+ }
234
+
235
+ process.exit(0);
236
+ } catch {
237
+ process.exit(0); // never block on error
238
+ }
239
+ });
package/lib/install.js CHANGED
@@ -21,6 +21,16 @@ const HOOKS_SRC = path.join(__dirname, '../hooks');
21
21
 
22
22
  const G2W_HOOKS = {
23
23
  PreToolUse: [
24
+ {
25
+ matcher: 'Write|Edit|Bash',
26
+ hooks: [
27
+ {
28
+ type: 'command',
29
+ command: 'node "{{HOOKS_DIR}}/g2w-resource-limits.js"',
30
+ timeout: 5
31
+ }
32
+ ]
33
+ },
24
34
  {
25
35
  matcher: 'Write|Edit',
26
36
  hooks: [
@@ -115,9 +125,10 @@ function mergeMcpServers(targetBase) {
115
125
 
116
126
  // Unique identifiers for each G2W hook — used for merge and removal
117
127
  const HOOK_SIGNATURES = {
118
- scopeGuard: h => h.hooks?.some(hh => hh.command?.includes('g2w-scope-guard')),
119
- aGame: h => h.hooks?.some(hh => hh.command?.includes('g2w-agame')),
120
- commitGuard: h => h.hooks?.some(hh => hh.command?.includes('g2w-commit-guard')),
128
+ resourceLimits: h => h.hooks?.some(hh => hh.command?.includes('g2w-resource-limits')),
129
+ scopeGuard: h => h.hooks?.some(hh => hh.command?.includes('g2w-scope-guard')),
130
+ aGame: h => h.hooks?.some(hh => hh.command?.includes('g2w-agame')),
131
+ commitGuard: h => h.hooks?.some(hh => hh.command?.includes('g2w-commit-guard')),
121
132
  };
122
133
 
123
134
  function mergeHooks(targetBase) {
@@ -168,10 +179,12 @@ function mergeHooks(targetBase) {
168
179
 
169
180
  if (!existing.hooks.PreToolUse) existing.hooks.PreToolUse = [];
170
181
  for (const hook of resolvedHooks.PreToolUse) {
182
+ const isResourceLimits = HOOK_SIGNATURES.resourceLimits(hook);
171
183
  const isScopeGuard = HOOK_SIGNATURES.scopeGuard(hook);
172
184
  const isAGame = HOOK_SIGNATURES.aGame(hook);
173
185
  const isCommitGuard = HOOK_SIGNATURES.commitGuard(hook);
174
186
  const alreadyExists = existing.hooks.PreToolUse.some(h =>
187
+ (isResourceLimits && HOOK_SIGNATURES.resourceLimits(h)) ||
175
188
  (isScopeGuard && HOOK_SIGNATURES.scopeGuard(h)) ||
176
189
  (isAGame && HOOK_SIGNATURES.aGame(h)) ||
177
190
  (isCommitGuard && HOOK_SIGNATURES.commitGuard(h))
@@ -212,7 +225,7 @@ function removeHooks(targetBase) {
212
225
  const hooksDir = path.join(targetBase, '.claude', 'hooks');
213
226
 
214
227
  // Remove hook scripts
215
- ['g2w-scope-guard.js', 'g2w-agame.js', 'g2w-commit-guard.js'].forEach(file => {
228
+ ['g2w-resource-limits.js', 'g2w-scope-guard.js', 'g2w-agame.js', 'g2w-commit-guard.js'].forEach(file => {
216
229
  const p = path.join(hooksDir, file);
217
230
  if (fs.existsSync(p)) fs.rmSync(p);
218
231
  });
@@ -225,6 +238,7 @@ function removeHooks(targetBase) {
225
238
  // Remove all G2W PreToolUse hooks (scope-guard, a-game, commit-guard, old Trust Layer prompt)
226
239
  if (existing.hooks.PreToolUse) {
227
240
  existing.hooks.PreToolUse = existing.hooks.PreToolUse.filter(h =>
241
+ !HOOK_SIGNATURES.resourceLimits(h) &&
228
242
  !HOOK_SIGNATURES.scopeGuard(h) &&
229
243
  !HOOK_SIGNATURES.aGame(h) &&
230
244
  !HOOK_SIGNATURES.commitGuard(h) &&
@@ -257,12 +271,29 @@ function getTarget() {
257
271
  return { base: os.homedir(), label: '~/.claude/' };
258
272
  }
259
273
 
274
+ function createDefaultResourceLimits() {
275
+ const configPath = path.join(os.homedir(), '.g2w', 'resource-limits.json');
276
+ if (fs.existsSync(configPath)) return; // don't overwrite user config
277
+ const defaults = {
278
+ enabled: true,
279
+ maxToolCalls: 200,
280
+ warnAtToolCallPercent: 80,
281
+ maxPlanRevisions: 5,
282
+ maxFileEdits: 8,
283
+ maxUniqueFiles: 25,
284
+ sessionTimeoutHours: 4
285
+ };
286
+ fs.mkdirSync(path.dirname(configPath), { recursive: true });
287
+ fs.writeFileSync(configPath, JSON.stringify(defaults, null, 2));
288
+ }
289
+
260
290
  async function run() {
261
291
  const { base, label } = getTarget();
262
292
  const { dest, count } = copySkills(base);
263
293
  copyHooks(base);
264
294
  const settingsPath = mergeHooks(base);
265
295
  const mcpAdded = mergeMcpServers(base);
296
+ createDefaultResourceLimits();
266
297
 
267
298
  writeTTY(`${LOGO}
268
299
  \x1b[32m✅ G2W installed at ${label}\x1b[0m
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@only1btayy/g2w",
3
- "version": "1.0.32",
3
+ "version": "1.0.33",
4
4
  "publishConfig": {
5
5
  "access": "public"
6
6
  },