@hyperdrive.bot/gut 0.1.14-alpha.0 → 0.1.15-alpha.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/README.md CHANGED
@@ -18,7 +18,7 @@ $ npm install -g @hyperdrive.bot/gut
18
18
  $ gut COMMAND
19
19
  running command...
20
20
  $ gut (--version)
21
- @hyperdrive.bot/gut/0.1.14-alpha.0 linux-x64 node-v22.22.2
21
+ @hyperdrive.bot/gut/0.1.15-alpha.0 linux-x64 node-v22.22.2
22
22
  $ gut --help [COMMAND]
23
23
  USAGE
24
24
  $ gut COMMAND
@@ -72,6 +72,11 @@ USAGE
72
72
  * [`gut used-by [ENTITY]`](#gut-used-by-entity)
73
73
  * [`gut workspace ACTION`](#gut-workspace-action)
74
74
  * [`gut worktree create NAME`](#gut-worktree-create-name)
75
+ * [`gut worktree gc`](#gut-worktree-gc)
76
+ * [`gut worktree list`](#gut-worktree-list)
77
+ * [`gut worktree prune`](#gut-worktree-prune)
78
+ * [`gut worktree remove NAME`](#gut-worktree-remove-name)
79
+ * [`gut worktree status [NAME]`](#gut-worktree-status-name)
75
80
 
76
81
  ## `gut add [PATH]`
77
82
 
@@ -1215,4 +1220,101 @@ EXAMPLES
1215
1220
 
1216
1221
  GUT_WORKTREE_DIR=/tmp/gut-worktrees gut worktree create feature/ci-run
1217
1222
  ```
1223
+
1224
+ ## `gut worktree gc`
1225
+
1226
+ Remove worktrees older than a given duration (garbage collection)
1227
+
1228
+ ```
1229
+ USAGE
1230
+ $ gut worktree gc -o <value> [-n] [-f]
1231
+
1232
+ FLAGS
1233
+ -f, --force Remove even worktrees with uncommitted changes
1234
+ -n, --dry-run List candidates without removing anything
1235
+ -o, --older-than=<value> (required) Duration threshold (e.g. '7d', '24h', '30m', '90s')
1236
+
1237
+ DESCRIPTION
1238
+ Remove worktrees older than a given duration (garbage collection)
1239
+
1240
+ EXAMPLES
1241
+ $ gut worktree gc --older-than 7d
1242
+
1243
+ $ gut worktree gc --older-than 14d --force
1244
+
1245
+ $ gut worktree gc --older-than 7d --dry-run
1246
+ ```
1247
+
1248
+ ## `gut worktree list`
1249
+
1250
+ List all active worktrees with metadata and staleness detection
1251
+
1252
+ ```
1253
+ USAGE
1254
+ $ gut worktree list
1255
+
1256
+ DESCRIPTION
1257
+ List all active worktrees with metadata and staleness detection
1258
+
1259
+ EXAMPLES
1260
+ $ gut worktree list
1261
+ ```
1262
+
1263
+ ## `gut worktree prune`
1264
+
1265
+ Remove worktree records whose paths no longer exist on disk
1266
+
1267
+ ```
1268
+ USAGE
1269
+ $ gut worktree prune
1270
+
1271
+ DESCRIPTION
1272
+ Remove worktree records whose paths no longer exist on disk
1273
+
1274
+ EXAMPLES
1275
+ $ gut worktree prune
1276
+ ```
1277
+
1278
+ ## `gut worktree remove NAME`
1279
+
1280
+ Remove a worktree and all entity worktrees
1281
+
1282
+ ```
1283
+ USAGE
1284
+ $ gut worktree remove NAME [-f]
1285
+
1286
+ ARGUMENTS
1287
+ NAME Worktree name to remove
1288
+
1289
+ FLAGS
1290
+ -f, --force Remove even with uncommitted changes
1291
+
1292
+ DESCRIPTION
1293
+ Remove a worktree and all entity worktrees
1294
+
1295
+ EXAMPLES
1296
+ $ gut worktree remove workflow/batch
1297
+
1298
+ $ gut worktree remove workflow/batch --force
1299
+ ```
1300
+
1301
+ ## `gut worktree status [NAME]`
1302
+
1303
+ Show per-entity git status for worktrees
1304
+
1305
+ ```
1306
+ USAGE
1307
+ $ gut worktree status [NAME]
1308
+
1309
+ ARGUMENTS
1310
+ NAME Worktree name (shows all if omitted)
1311
+
1312
+ DESCRIPTION
1313
+ Show per-entity git status for worktrees
1314
+
1315
+ EXAMPLES
1316
+ $ gut worktree status
1317
+
1318
+ $ gut worktree status workflow/deploy-batch
1319
+ ```
1218
1320
  <!-- commandsstop -->
@@ -0,0 +1,11 @@
1
+ import { BaseCommand } from '../../base-command.js';
2
+ export default class ClaudeInit extends BaseCommand {
3
+ static description: string;
4
+ static examples: string[];
5
+ static flags: {
6
+ 'dry-run': import("@oclif/core/interfaces").BooleanFlag<boolean>;
7
+ force: import("@oclif/core/interfaces").BooleanFlag<boolean>;
8
+ };
9
+ protected get requiresInit(): boolean;
10
+ run(): Promise<void>;
11
+ }
@@ -0,0 +1,120 @@
1
+ import { Flags } from '@oclif/core';
2
+ import { copyFileSync, existsSync, mkdirSync, readFileSync, writeFileSync } from 'node:fs';
3
+ import { dirname, join } from 'node:path';
4
+ import { fileURLToPath } from 'node:url';
5
+ import chalk from 'chalk';
6
+ import { BaseCommand } from '../../base-command.js';
7
+ const GUT_START = '<!-- gut:start -->';
8
+ const GUT_END = '<!-- gut:end -->';
9
+ const __filename = fileURLToPath(import.meta.url);
10
+ const __dirname = dirname(__filename);
11
+ const templateDir = join(__dirname, '..', '..', '..', 'templates', 'claude-init');
12
+ export default class ClaudeInit extends BaseCommand {
13
+ static description = 'Scaffold Claude Code configuration for gut';
14
+ static examples = [
15
+ '<%= config.bin %> claude init',
16
+ '<%= config.bin %> claude init --dry-run',
17
+ '<%= config.bin %> claude init --force',
18
+ ];
19
+ static flags = {
20
+ 'dry-run': Flags.boolean({ description: 'Preview changes without writing files' }),
21
+ force: Flags.boolean({ char: 'f', description: 'Overwrite existing gut section and command files' }),
22
+ };
23
+ get requiresInit() {
24
+ return false;
25
+ }
26
+ async run() {
27
+ const { flags } = await this.parse(ClaudeInit);
28
+ const dryRun = flags['dry-run'];
29
+ const force = flags.force;
30
+ // Validate template directory
31
+ if (!existsSync(templateDir)) {
32
+ this.error('Template directory not found at: ' + templateDir);
33
+ }
34
+ const results = [];
35
+ // --- CLAUDE.md handler ---
36
+ const claudeMdPath = join(process.cwd(), 'CLAUDE.md');
37
+ const templateContent = readFileSync(join(templateDir, 'claude-md-section.md'), 'utf-8');
38
+ if (!existsSync(claudeMdPath)) {
39
+ // No CLAUDE.md — create new file
40
+ if (dryRun) {
41
+ results.push({ action: 'created', file: 'CLAUDE.md' });
42
+ }
43
+ else {
44
+ writeFileSync(claudeMdPath, templateContent);
45
+ results.push({ action: 'created', file: 'CLAUDE.md' });
46
+ }
47
+ }
48
+ else {
49
+ const existing = readFileSync(claudeMdPath, 'utf-8');
50
+ if (existing.includes(GUT_START)) {
51
+ if (force) {
52
+ // Remove existing gut section and re-append
53
+ const cleaned = existing.replace(new RegExp(GUT_START + '[\\s\\S]*?' + GUT_END, 'g'), '').trimEnd();
54
+ if (!dryRun) {
55
+ writeFileSync(claudeMdPath, cleaned + '\n\n' + templateContent);
56
+ }
57
+ results.push({ action: 'modified', file: 'CLAUDE.md' });
58
+ }
59
+ else {
60
+ this.log('gut section already exists (use --force to overwrite)');
61
+ results.push({ action: 'skipped', file: 'CLAUDE.md' });
62
+ }
63
+ }
64
+ else {
65
+ // Append gut section
66
+ if (!dryRun) {
67
+ writeFileSync(claudeMdPath, existing + '\n\n' + templateContent);
68
+ }
69
+ results.push({ action: 'modified', file: 'CLAUDE.md' });
70
+ }
71
+ }
72
+ // --- .claude/commands/ handler ---
73
+ const commandsDir = join(process.cwd(), '.claude', 'commands');
74
+ const commandFiles = ['gut-status.md', 'gut-affected.md'];
75
+ if (!existsSync(commandsDir)) {
76
+ if (dryRun) {
77
+ this.log('.claude/commands/ → create directory');
78
+ }
79
+ else {
80
+ mkdirSync(commandsDir, { recursive: true });
81
+ }
82
+ }
83
+ for (const filename of commandFiles) {
84
+ const source = join(templateDir, 'commands', filename);
85
+ const target = join(commandsDir, filename);
86
+ if (existsSync(target) && !force) {
87
+ this.log(`${filename} → already exists (use --force to overwrite)`);
88
+ results.push({ action: 'skipped', file: `.claude/commands/${filename}` });
89
+ }
90
+ else {
91
+ if (!dryRun) {
92
+ // Ensure directory exists (in case only some files existed)
93
+ mkdirSync(commandsDir, { recursive: true });
94
+ copyFileSync(source, target);
95
+ }
96
+ results.push({ action: 'created', file: `.claude/commands/${filename}` });
97
+ }
98
+ }
99
+ // --- Summary ---
100
+ const heading = dryRun ? 'gut claude init (dry run)' : 'gut claude init';
101
+ this.log('');
102
+ this.log(chalk.bold(heading));
103
+ this.log('');
104
+ for (const { action, file } of results) {
105
+ const label = action === 'created'
106
+ ? chalk.green(action)
107
+ : action === 'modified'
108
+ ? chalk.yellow(action)
109
+ : chalk.dim(action);
110
+ this.log(` ${file} → ${label}`);
111
+ }
112
+ this.log('');
113
+ if (dryRun) {
114
+ this.log('No files were modified. Remove --dry-run to apply.');
115
+ }
116
+ else {
117
+ this.log('Run /gut-status in Claude Code to verify');
118
+ }
119
+ }
120
+ }
@@ -1418,6 +1418,45 @@
1418
1418
  "status.js"
1419
1419
  ]
1420
1420
  },
1421
+ "claude:init": {
1422
+ "aliases": [],
1423
+ "args": {},
1424
+ "description": "Scaffold Claude Code configuration for gut",
1425
+ "examples": [
1426
+ "<%= config.bin %> claude init",
1427
+ "<%= config.bin %> claude init --dry-run",
1428
+ "<%= config.bin %> claude init --force"
1429
+ ],
1430
+ "flags": {
1431
+ "dry-run": {
1432
+ "description": "Preview changes without writing files",
1433
+ "name": "dry-run",
1434
+ "allowNo": false,
1435
+ "type": "boolean"
1436
+ },
1437
+ "force": {
1438
+ "char": "f",
1439
+ "description": "Overwrite existing gut section and command files",
1440
+ "name": "force",
1441
+ "allowNo": false,
1442
+ "type": "boolean"
1443
+ }
1444
+ },
1445
+ "hasDynamicHelp": false,
1446
+ "hiddenAliases": [],
1447
+ "id": "claude:init",
1448
+ "pluginAlias": "@hyperdrive.bot/gut",
1449
+ "pluginName": "@hyperdrive.bot/gut",
1450
+ "pluginType": "core",
1451
+ "strict": true,
1452
+ "isESM": true,
1453
+ "relativePath": [
1454
+ "dist",
1455
+ "commands",
1456
+ "claude",
1457
+ "init.js"
1458
+ ]
1459
+ },
1421
1460
  "entity:add": {
1422
1461
  "aliases": [],
1423
1462
  "args": {
@@ -2414,5 +2453,5 @@
2414
2453
  ]
2415
2454
  }
2416
2455
  },
2417
- "version": "0.1.14-alpha.0"
2456
+ "version": "0.1.15-alpha.0"
2418
2457
  }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@hyperdrive.bot/gut",
3
- "version": "0.1.14-alpha.0",
3
+ "version": "0.1.15-alpha.0",
4
4
  "description": "Git Unified Tooling - Enhanced git with workspace intelligence for entity-based organization",
5
5
  "main": "dist/index.js",
6
6
  "types": "dist/index.d.ts",
@@ -0,0 +1,179 @@
1
+ <!-- gut:start -->
2
+ # Gut — Workspace Intelligence
3
+
4
+ ## What is Gut
5
+
6
+ Gut is an entity-aware workspace manager for multi-repo and monorepo setups. It wraps git with workspace intelligence — focus-driven commands that scope operations to the entities you care about, dependency analysis across repos, and atomic multi-repo worktree isolation. The CLI is `gut` (npm: `@hyperdrive.bot/gut`).
7
+
8
+ ## Mental Model
9
+
10
+ ### Entities
11
+
12
+ Entities are the building blocks of your workspace. Each entity has a type, name, and path:
13
+
14
+ | Type | Purpose |
15
+ |------|---------|
16
+ | `client` | Client projects |
17
+ | `company` | Company-level repositories |
18
+ | `delivery` | Delivery/app projects |
19
+ | `initiative` | Internal initiatives |
20
+ | `module` | Packages and libraries |
21
+ | `prospect` | Prospect/sales projects |
22
+ | `service` | Backend services |
23
+ | `system` | System-level infrastructure |
24
+ | `tool` | Developer tools |
25
+
26
+ Entities are stored in `.gut/config.json` and auto-discovered from directory patterns (`apps/` → delivery, `packages/` → module, `libs/` → module, `services/` → service, `tools/` → tool).
27
+
28
+ ### Focus System
29
+
30
+ Focus scopes all gut commands to selected entities. When you focus on an entity, commands like `gut status`, `gut commit`, and `gut push` operate only on that entity's repository.
31
+
32
+ | Mode | Purpose |
33
+ |------|---------|
34
+ | `audit` | Reviewing code quality and compliance |
35
+ | `debug` | Investigating and fixing issues |
36
+ | `delivery` | Building and shipping features |
37
+ | `proposal` | Preparing proposals and estimates |
38
+ | `research` | Exploring and prototyping |
39
+ | `strategy` | Planning and architecture |
40
+
41
+ Focus state is stored in `.gut/focus.json` with history in `.gut/history.json` (max 10 entries).
42
+
43
+ ### Worktrees
44
+
45
+ Gut provides atomic multi-repo isolation via `gut worktree create`. This creates a super-repo worktree plus per-entity worktrees on a new branch, allowing isolated pipeline runs without affecting your working tree. Default location: `~/.local/share/gut/worktrees/<slug>`.
46
+
47
+ ## Command Reference
48
+
49
+ ### Setup
50
+
51
+ | Command | Description |
52
+ |---------|-------------|
53
+ | `gut init` | Initialize a gut workspace |
54
+ | `gut quick-setup` | Quick workspace setup wizard |
55
+
56
+ ### Entity
57
+
58
+ | Command | Description |
59
+ |---------|-------------|
60
+ | `gut entity add` | Add entity to workspace |
61
+ | `gut entity clone` | Clone entity repository |
62
+ | `gut entity clone-all` | Clone all entities |
63
+ | `gut entity list` | List entities |
64
+ | `gut entity remove` | Remove entity |
65
+
66
+ ### Focus
67
+
68
+ | Command | Description |
69
+ |---------|-------------|
70
+ | `gut focus` | Set focus on entities |
71
+ | `gut unfocus` | Clear focus |
72
+ | `gut back` | Return to previous focus/branch |
73
+ | `gut context` | Show current focus context |
74
+ | `gut contexts` | List saved focus contexts |
75
+
76
+ ### Git
77
+
78
+ | Command | Description |
79
+ |---------|-------------|
80
+ | `gut status` | Show git status for focused entities |
81
+ | `gut commit` | Commit changes across focused entities |
82
+ | `gut push` | Push changes to remotes |
83
+ | `gut pull` | Pull changes from remotes |
84
+ | `gut checkout` | Checkout branches across entities |
85
+ | `gut sync` | Sync across entities |
86
+
87
+ ### Worktree
88
+
89
+ | Command | Description |
90
+ |---------|-------------|
91
+ | `gut worktree create` | Create mirrored worktrees for super-repo + focused entities |
92
+ | `gut worktree list` | List worktrees |
93
+ | `gut worktree remove` | Remove worktree |
94
+ | `gut worktree status` | Show worktree status |
95
+
96
+ ### Analysis
97
+
98
+ | Command | Description |
99
+ |---------|-------------|
100
+ | `gut affected` | Detect entities potentially affected by changes |
101
+ | `gut deps` | Analyze dependencies |
102
+ | `gut graph` | Visualize dependency graph |
103
+ | `gut related` | Find related entities |
104
+ | `gut used-by` | Show what uses an entity |
105
+ | `gut stack` | Show dependency stack |
106
+ | `gut patterns` | Analyze patterns across codebase |
107
+ | `gut insights` | Show insights about entities |
108
+ | `gut audit` | Run audits across entities |
109
+
110
+ ### Tickets
111
+
112
+ | Command | Description |
113
+ |---------|-------------|
114
+ | `gut ticket focus` | Focus on a ticket |
115
+ | `gut ticket get` | Get ticket details |
116
+ | `gut ticket list` | List tickets |
117
+ | `gut ticket sync` | Sync tickets |
118
+ | `gut ticket update` | Update ticket |
119
+ | `gut ticket config` | Configure ticket system |
120
+
121
+ ### Auth
122
+
123
+ | Command | Description |
124
+ |---------|-------------|
125
+ | `gut auth login` | Authenticate |
126
+ | `gut auth logout` | Logout |
127
+ | `gut auth status` | Show auth status |
128
+
129
+ ### Other
130
+
131
+ | Command | Description |
132
+ |---------|-------------|
133
+ | `gut repos` | List repositories |
134
+ | `gut recent` | Show recent activity |
135
+ | `gut add` | Add a git submodule or dependency |
136
+ | `gut extract` | Extract code/modules |
137
+ | `gut workspace` | Workspace management |
138
+
139
+ ## Common Workflows
140
+
141
+ 1. **Start a client project:**
142
+ ```
143
+ gut init
144
+ gut entity add my-client client ./path
145
+ gut focus client my-client --mode delivery
146
+ gut context
147
+ ```
148
+
149
+ 2. **Check blast radius before changes:**
150
+ ```
151
+ gut affected --verbose
152
+ ```
153
+ Review confidence levels (high/medium/low) and dependency reasons before making cross-entity changes.
154
+
155
+ 3. **Create isolated worktree for pipeline run:**
156
+ ```
157
+ gut focus client my-client
158
+ gut worktree create feature-x --install
159
+ cd ~/.local/share/gut/worktrees/feature-x
160
+ ```
161
+
162
+ 4. **Explore workspace:**
163
+ ```
164
+ gut entity list
165
+ gut focus <entity>
166
+ gut context
167
+ gut status --all --verbose
168
+ ```
169
+
170
+ ## Rules for Claude
171
+
172
+ - Prefer `gut` commands over raw `git` when inside a gut workspace (`.gut/` directory exists)
173
+ - Always check current focus with `gut context` before suggesting git operations
174
+ - Use `gut affected --verbose` to understand blast radius before making cross-entity changes
175
+ - Never modify `.gut/` directory contents directly — use gut commands
176
+ - Use `gut status --all --verbose` for full workspace status, not `git status`
177
+ - When a gut command fails, check if the workspace is initialized (`gut init`) and if entities are focused (`gut context`)
178
+ - Use `gut worktree create` for isolated pipeline/workflow runs — never create git worktrees manually in a gut workspace
179
+ <!-- gut:end -->
@@ -0,0 +1,40 @@
1
+ Analyze which entities are potentially affected by recent changes in the current focus.
2
+
3
+ ## Steps
4
+
5
+ 1. Run `gut affected --verbose` to detect entities affected by changes since the last commit
6
+
7
+ ## Fallback — no entities focused
8
+
9
+ If the command fails or returns no results because no entities are currently focused:
10
+
11
+ 1. Tell the user: "No entities are focused. You need to focus on an entity first."
12
+ 2. Suggest: Run `gut focus <entity-name>` to set focus on the entity you're working on
13
+ 3. Then retry `/gut-affected`
14
+
15
+ ## Interpreting the output
16
+
17
+ ### Confidence levels
18
+ Results are grouped by how likely an entity is to be affected:
19
+ - **High** — direct dependency or shared code path changed
20
+ - **Medium** — related configuration or schema change detected
21
+ - **Low** — indirect or transitive dependency change
22
+
23
+ ### Change types
24
+ Each affected entity shows what kind of change triggered the detection:
25
+ - **API** — API contract or endpoint changes
26
+ - **Config** — configuration file changes (serverless.yml, package.json, etc.)
27
+ - **Schema** — database schema or type definition changes
28
+ - **Dependency** — shared dependency or package version changes
29
+
30
+ ### Verbose output
31
+ With `--verbose`, each affected entity includes a file-level breakdown showing exactly which changed files triggered the detection.
32
+
33
+ ## Suggested actions
34
+
35
+ Based on the affected entities list, suggest which entities the user should:
36
+ - **Review** — entities with high-confidence API or schema changes
37
+ - **Test** — entities with config or dependency changes that may break at runtime
38
+ - **Deploy** — entities that depend on the changed code and need redeployment
39
+
40
+ Prioritize high-confidence results first. For low-confidence results, mention them but note they may not require immediate action.
@@ -0,0 +1,33 @@
1
+ Show the current gut context and git status across all entities in the super-repo.
2
+
3
+ ## Steps
4
+
5
+ 1. Run `gut context` to show the current focus context (which entities are focused, their types, and paths)
6
+ 2. Run `gut status --all --verbose` to show git status across all entities with file-level detail
7
+
8
+ ## Interpreting the output
9
+
10
+ ### Entity type emojis
11
+ - 🏢 = client
12
+ - 🚀 = initiative
13
+ - 🏗️ = company
14
+ - 📦 = package
15
+ - 🌐 = web-app
16
+
17
+ ### Status indicators
18
+ - ✓ = clean (no uncommitted changes)
19
+ - ● = has changes (staged, unstaged, or untracked files)
20
+
21
+ ### Verbose output
22
+ When `--verbose` is used, each entity with changes shows file-level details:
23
+ - **Staged** — files added to the index, ready to commit
24
+ - **Unstaged** — modified files not yet staged
25
+ - **Untracked** — new files not tracked by git
26
+
27
+ ## Summary
28
+
29
+ After running both commands, present a concise summary of:
30
+ - Which entities have uncommitted changes
31
+ - What kind of changes each has (staged, unstaged, untracked)
32
+ - How many files are affected per entity
33
+ - Any entities that are currently focused