@only1btayy/g2w 1.0.26 → 1.0.28

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
@@ -209,7 +209,19 @@ Safe git operations — add, commit, push, status, log — run without approval
209
209
  npm install -g @only1btayy/g2w && g2w
210
210
  ```
211
211
 
212
- That's it. G2W installs globally into `~/.claude/` automatically — skills and hooks ready in every project, everywhere.
212
+ That's it. G2W installs globally into `~/.claude/` automatically — skills, hooks, and design tools ready in every project, everywhere.
213
+
214
+ To update:
215
+
216
+ ```bash
217
+ g2w update
218
+ ```
219
+
220
+ To see optional Power-Ups:
221
+
222
+ ```bash
223
+ g2w power-ups
224
+ ```
213
225
 
214
226
  To uninstall:
215
227
 
@@ -217,7 +229,7 @@ To uninstall:
217
229
  npm uninstall -g @only1btayy/g2w
218
230
  ```
219
231
 
220
- Skills and hooks are removed from `~/.claude/` automatically.
232
+ Skills, hooks, and MCP servers are removed from `~/.claude/` automatically.
221
233
 
222
234
  > **Tip:** The logo renders in **bright green** in any terminal. On Windows Terminal or iTerm2, enable Retro/Bloom effects for the full glow.
223
235
 
package/bin/g2w.js CHANGED
@@ -7,12 +7,27 @@ if (command === 'install') {
7
7
  require('../lib/install').run();
8
8
  } else if (command === 'update') {
9
9
  require('../lib/install').update();
10
+ } else if (command === 'power-ups' || command === 'powerups') {
11
+ require('../lib/install').powerups();
10
12
  } else if (command === 'uninstall') {
11
13
  require('../lib/install').uninstall();
14
+ } else if (command === 'setup') {
15
+ const readline = require('readline');
16
+ const { getName, setName } = require('../lib/personality');
17
+ const rl = readline.createInterface({ input: process.stdin, output: process.stdout });
18
+ const current = getName();
19
+ rl.question(` What should G2W call you? [${current}]: `, (answer) => {
20
+ const name = answer.trim() || current;
21
+ setName(name);
22
+ console.log(`\n Got it, ${name}. Let's build.\n`);
23
+ rl.close();
24
+ });
12
25
  } else {
13
26
  process.stdout.write(`${LOGO}
14
27
  Usage:
15
- g2w update update skills to latest version
28
+ g2w setup set your name
29
+ g2w update — update skills, hooks, and tools to latest
30
+ g2w power-ups — show optional tools and setup links
16
31
  g2w uninstall — remove G2W
17
32
 
18
33
  `);
package/lib/install.js CHANGED
@@ -2,6 +2,7 @@ const fs = require('fs');
2
2
  const path = require('path');
3
3
  const os = require('os');
4
4
  const { LOGO } = require('./logo');
5
+ const { getGreeting } = require('./personality');
5
6
 
6
7
  function writeTTY(text) {
7
8
  // Plain stderr first — npm shows this reliably
@@ -256,14 +257,49 @@ Open any project with Claude Code and type:
256
257
  /g2w:back2it — resume a session
257
258
  /g2w:build2gether — start something new
258
259
 
260
+ ${getGreeting()}
259
261
  `);
260
262
  }
261
263
 
262
264
  async function update() {
263
265
  const { base, label } = getTarget();
264
- copySkills(base);
266
+ const { count } = copySkills(base);
265
267
  copyHooks(base);
266
- console.log(`\n✅ G2W skills and hooks updated at ${label}\n`);
268
+ mergeHooks(base);
269
+ const mcpAdded = mergeMcpServers(base);
270
+
271
+ writeTTY(`
272
+ \x1b[32m✅ G2W updated at ${label}\x1b[0m
273
+
274
+ ${count} skills synced
275
+ Hooks synced
276
+ ${mcpAdded > 0 ? mcpAdded + ' new MCP servers added' : 'MCP servers up to date'}
277
+
278
+ `);
279
+ }
280
+
281
+ async function powerups() {
282
+ writeTTY(`
283
+ \x1b[36mG2W Power-Ups\x1b[0m
284
+
285
+ \x1b[33mFree (just needs a key):\x1b[0m
286
+ → 21st.dev — AI component generation https://21st.dev/magic/console
287
+ → Motion — production animations https://plus.motion.dev/personal-token
288
+ → Figma MCP — design-to-code from Figma https://figma.com
289
+ → Marketing — 40+ SEO, copy, growth skills https://github.com/coreyhaines31/marketingskills
290
+
291
+ \x1b[33mResearch (paid):\x1b[0m
292
+ → Exa — semantic search https://exa.ai
293
+ → Firecrawl — deep doc crawling https://firecrawl.dev
294
+
295
+ \x1b[33mWorkflow:\x1b[0m
296
+ → Repomix — pack codebases for AI https://github.com/yamadashy/repomix
297
+ → MemPalace — persistent memory https://github.com/milla-jovovich/mempalace
298
+ → Superpowers — enhanced planning + review https://github.com/supermemoryai/superpowers-claude
299
+
300
+ Visit the links above to get your keys, then configure them in ~/.claude/settings.json
301
+
302
+ `);
267
303
  }
268
304
 
269
305
  async function uninstall() {
@@ -279,4 +315,4 @@ async function uninstall() {
279
315
  }
280
316
  }
281
317
 
282
- module.exports = { run, update, uninstall };
318
+ module.exports = { run, update, uninstall, powerups };
@@ -0,0 +1,150 @@
1
+ const { execSync } = require('child_process');
2
+ const fs = require('fs');
3
+ const path = require('path');
4
+ const os = require('os');
5
+
6
+ // --- Name resolution ---
7
+
8
+ const PROFILE_FILE = path.join(os.homedir(), '.g2w', 'profile.json');
9
+
10
+ function loadProfile() {
11
+ try {
12
+ return JSON.parse(fs.readFileSync(PROFILE_FILE, 'utf8'));
13
+ } catch {
14
+ return {};
15
+ }
16
+ }
17
+
18
+ function saveProfile(data) {
19
+ fs.mkdirSync(path.dirname(PROFILE_FILE), { recursive: true });
20
+ fs.writeFileSync(PROFILE_FILE, JSON.stringify(data, null, 2));
21
+ }
22
+
23
+ function getName() {
24
+ const profile = loadProfile();
25
+ if (profile.name) return profile.name;
26
+
27
+ // Try git config (skip if it looks like a handle — no spaces, all caps, etc.)
28
+ try {
29
+ const gitName = execSync('git config user.name', { encoding: 'utf8', stdio: ['pipe', 'pipe', 'pipe'] }).trim();
30
+ if (gitName && gitName.includes(' ')) return gitName.split(' ')[0];
31
+ } catch {}
32
+
33
+ return os.userInfo().username;
34
+ }
35
+
36
+ function setName(name) {
37
+ const profile = loadProfile();
38
+ profile.name = name;
39
+ saveProfile(profile);
40
+ }
41
+
42
+ // --- Quote bank ---
43
+
44
+ const QUOTES = [
45
+ // With "Remember, {name}..." prefix
46
+ { text: "If you don't decide who you are, someone else will do it for you.", author: "Ocean Veau", prefixed: true },
47
+ { text: "Life is not only about ourselves, it's about the impact we have on others.", prefixed: true },
48
+ { text: "As a man thinketh in his heart, so is he. So whatever you believe you are — you're right.", prefixed: true },
49
+ { text: "Great things are done by a series of small things brought together. One brick at a time my friend. You got this.", prefixed: true },
50
+ { text: "What other people think of you is none of your business. Besides, it's not like they got anything better to talk about. :)", prefixed: true },
51
+ { text: "Next time you look up into the stars, remember that you're looking at a mirror.", author: "Ocean Veau", prefixed: true },
52
+ { text: "Money only has purpose & meaning when a human touches it so... who really has the power?", prefixed: true },
53
+ { text: "It's going to work or it's going to work. Ain't no other options my friend.", prefixed: true },
54
+
55
+ // Standalone
56
+ { text: "A man grows by the greatness of his task.", prefixed: false },
57
+ { text: "If you do what's easy, your life will be hard. But if you do what's hard, your life will be easy.", prefixed: false },
58
+ { text: "Sometimes good things fall apart so better things can fall together.", prefixed: false },
59
+ { text: "Ego says: \"Once everything falls into place, I'll feel peace.\" Spirit says: \"Find peace and everything will fall into place.\"", prefixed: false },
60
+ { text: "Be kind, not nice. Nice is a mask that even your worst enemy can wear.", author: "Ocean Veau", prefixed: false },
61
+ { text: "Rules were made to be broken, but principle will get you where you need to go.", author: "Ocean Veau", prefixed: false },
62
+ { text: "The best time to plant a tree was 20 years ago. The second best time is right now.", author: "Chinese Proverb", prefixed: false },
63
+ { text: "Don't be afraid to give up the good to go for the great.", author: "John D. Rockefeller", prefixed: false },
64
+ { text: "The man who moves a mountain begins by carrying away small stones.", author: "Confucius", prefixed: false },
65
+ { text: "He who has a why to live can bear almost any how.", author: "Nietzsche", prefixed: false },
66
+ { text: "You don't rise to the level of your goals. You fall to the level of your systems.", author: "James Clear", prefixed: false },
67
+ { text: "The cave you fear to enter holds the treasure you seek.", author: "Joseph Campbell", prefixed: false },
68
+ { text: "You can't build a reputation on what you're going to do.", author: "Henry Ford", prefixed: false },
69
+ { text: "Everybody wants to be a beast until it's time to do what beasts do.", prefixed: false },
70
+ { text: "A society grows great when old men plant trees in whose shade they shall never sit.", author: "Greek Proverb", prefixed: false },
71
+ { text: "They tried to bury us. They didn't know we were seeds.", author: "Mexican Proverb", prefixed: false },
72
+ { text: "What you leave behind is not what is engraved in stone monuments, but what is woven into the lives of others.", author: "Pericles", prefixed: false },
73
+ ];
74
+
75
+ function getCloseQuote() {
76
+ const name = getName();
77
+ const quote = QUOTES[Math.floor(Math.random() * QUOTES.length)];
78
+ const attribution = quote.author ? ` — ${quote.author}` : '';
79
+
80
+ if (quote.prefixed) {
81
+ return `\x1b[2m Remember, ${name}... ${quote.text}${attribution}\x1b[0m`;
82
+ }
83
+ return `\x1b[2m "${quote.text}"${attribution}\x1b[0m`;
84
+ }
85
+
86
+ // --- Greeting ---
87
+
88
+ function getGreeting() {
89
+ const name = getName();
90
+ return `\x1b[1m Hey ${name}, let's make an impact and make some money while we're doing it.\x1b[0m
91
+ \x1b[2m What are we building today?\x1b[0m`;
92
+ }
93
+
94
+ // --- Streak tracking ---
95
+
96
+ const STREAK_DIR = path.join(os.homedir(), '.g2w');
97
+ const STREAK_FILE = path.join(STREAK_DIR, 'streak.json');
98
+
99
+ function loadStreak() {
100
+ try {
101
+ return JSON.parse(fs.readFileSync(STREAK_FILE, 'utf8'));
102
+ } catch {
103
+ return { lastDate: null, count: 0 };
104
+ }
105
+ }
106
+
107
+ function saveStreak(data) {
108
+ fs.mkdirSync(STREAK_DIR, { recursive: true });
109
+ fs.writeFileSync(STREAK_FILE, JSON.stringify(data, null, 2));
110
+ }
111
+
112
+ function recordSession() {
113
+ const today = new Date().toISOString().split('T')[0];
114
+ const streak = loadStreak();
115
+
116
+ if (streak.lastDate === today) {
117
+ return streak; // Already counted today
118
+ }
119
+
120
+ const yesterday = new Date(Date.now() - 86400000).toISOString().split('T')[0];
121
+
122
+ if (streak.lastDate === yesterday) {
123
+ streak.count++;
124
+ } else {
125
+ streak.count = 1;
126
+ }
127
+
128
+ streak.lastDate = today;
129
+ saveStreak(streak);
130
+ return streak;
131
+ }
132
+
133
+ function getStreakMessage() {
134
+ const streak = recordSession();
135
+ if (streak.count < 2) return null; // No message for day 1
136
+
137
+ const name = getName();
138
+ if (streak.count <= 3) {
139
+ return `\x1b[2m ${streak.count} days in a row, ${name}. Consistency compounds.\x1b[0m`;
140
+ }
141
+ if (streak.count <= 7) {
142
+ return `\x1b[2m ${streak.count}-day streak. This is how things get built, ${name}.\x1b[0m`;
143
+ }
144
+ if (streak.count <= 14) {
145
+ return `\x1b[2m ${streak.count} days straight. Most people quit by now. You didn't.\x1b[0m`;
146
+ }
147
+ return `\x1b[2m ${streak.count}-day streak. At this point, it's not discipline — it's who you are.\x1b[0m`;
148
+ }
149
+
150
+ module.exports = { getName, setName, getGreeting, getCloseQuote, getStreakMessage, recordSession };
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@only1btayy/g2w",
3
- "version": "1.0.26",
3
+ "version": "1.0.28",
4
4
  "description": "G2W — a relationship protocol for building trust with AI",
5
5
  "bin": {
6
6
  "g2w": "bin/g2w.js"
package/skills/back2it.md CHANGED
@@ -35,7 +35,19 @@ You are resuming a G2W session. Get back up to speed fast. No fluff.
35
35
  Blockers: [any known issues, or "none"]
36
36
  ```
37
37
 
38
- 6. Ask: "Ready to pick up where we left off?"
38
+ 6. **Streak check:** Read `~/.g2w/streak.json` (Windows: `C:/Users/[username]/.g2w/streak.json`). If it exists, check the `lastDate` and `count` fields:
39
+ - If `lastDate` was yesterday, increment `count` by 1 and update `lastDate` to today. Write the file back.
40
+ - If `lastDate` is today, don't change anything.
41
+ - If `lastDate` is older than yesterday, reset `count` to 1 and set `lastDate` to today. Write the file back.
42
+ - If the file doesn't exist, create it with `{ "lastDate": "[today]", "count": 1 }`.
43
+
44
+ Display the streak only if count >= 2, using this tone (calm, professional, encouraging):
45
+ - 2-3 days: "{count} days in a row, {first name}. Consistency compounds."
46
+ - 4-7 days: "{count}-day streak. This is how things get built, {first name}."
47
+ - 8-14 days: "{count} days straight. Most people quit by now. You didn't."
48
+ - 15+ days: "{count}-day streak. At this point, it's not discipline — it's who you are."
49
+
50
+ 7. Ask: "Ready to pick up where we left off?"
39
51
 
40
52
  ## Rules
41
53
 
@@ -58,8 +58,42 @@ You are closing out this session. Leave the project in a state where any future
58
58
 
59
59
  Present the commit message to the user. Wait for approval before running.
60
60
 
61
- 6. **Announce:**
62
- > "Saved. Context is clean. Next session, type `/g2w:back2it` to pick up right where we left off."
61
+ 6. **Announce with personality:**
62
+ End the session with a closing quote. Pick ONE at random from this list:
63
+
64
+ **Prefixed quotes** — format as: "Remember, {user's first name}... {quote}"
65
+ - "If you don't decide who you are, someone else will do it for you." — Ocean Veau
66
+ - "Life is not only about ourselves, it's about the impact we have on others."
67
+ - "As a man thinketh in his heart, so is he. So whatever you believe you are — you're right."
68
+ - "Great things are done by a series of small things brought together. One brick at a time my friend. You got this."
69
+ - "What other people think of you is none of your business. Besides, it's not like they got anything better to talk about. :)"
70
+ - "Next time you look up into the stars, remember that you're looking at a mirror." — Ocean Veau
71
+ - "Money only has purpose & meaning when a human touches it so... who really has the power?"
72
+ - "It's going to work or it's going to work. Ain't no other options my friend."
73
+
74
+ **Standalone quotes** — format as: "{quote}" — {author}
75
+ - "A man grows by the greatness of his task."
76
+ - "If you do what's easy, your life will be hard. But if you do what's hard, your life will be easy."
77
+ - "Sometimes good things fall apart so better things can fall together."
78
+ - "Ego says: 'Once everything falls into place, I'll feel peace.' Spirit says: 'Find peace and everything will fall into place.'"
79
+ - "Be kind, not nice. Nice is a mask that even your worst enemy can wear." — Ocean Veau
80
+ - "Rules were made to be broken, but principle will get you where you need to go." — Ocean Veau
81
+ - "The best time to plant a tree was 20 years ago. The second best time is right now." — Chinese Proverb
82
+ - "Don't be afraid to give up the good to go for the great." — John D. Rockefeller
83
+ - "The man who moves a mountain begins by carrying away small stones." — Confucius
84
+ - "He who has a why to live can bear almost any how." — Nietzsche
85
+ - "You don't rise to the level of your goals. You fall to the level of your systems." — James Clear
86
+ - "The cave you fear to enter holds the treasure you seek." — Joseph Campbell
87
+ - "You can't build a reputation on what you're going to do." — Henry Ford
88
+ - "Everybody wants to be a beast until it's time to do what beasts do."
89
+ - "A society grows great when old men plant trees in whose shade they shall never sit." — Greek Proverb
90
+ - "They tried to bury us. They didn't know we were seeds." — Mexican Proverb
91
+ - "What you leave behind is not what is engraved in stone monuments, but what is woven into the lives of others." — Pericles
92
+
93
+ Format the full closing as:
94
+ > Saved. Context is clean. Next session, type `/g2w:back2it` to pick up right where we left off.
95
+ >
96
+ > {closing quote}
63
97
 
64
98
  ## Rules
65
99