geet-geet 0.1.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.
@@ -0,0 +1,519 @@
1
+ # Developer Guide
2
+
3
+ This guide explains the internal architecture and developer workflow for geet.
4
+
5
+ ## Table of Contents
6
+
7
+ - [Script Setup & Entrypoint](#script-setup--entrypoint)
8
+ - [Prework & Initialization](#prework--initialization)
9
+ - [Logging System](#logging-system)
10
+ - [Available Variables & Functions](#available-variables--functions)
11
+ - [Writing New Commands](#writing-new-commands)
12
+
13
+ ## Script Setup & Entrypoint
14
+
15
+ ### Entry Point: `bin/geet.sh`
16
+
17
+ All geet commands flow through `bin/geet.sh`, which serves as the main dispatcher:
18
+
19
+ ```bash
20
+ #!/usr/bin/env bash
21
+ set -euo pipefail
22
+
23
+ # 1. Locate the geet library
24
+ NODE_BIN="$(cd -- "$(dirname -- "${BASH_SOURCE[0]}")" && pwd)"
25
+ GEET_LIB="$(cd -- "$NODE_BIN/../lib/node_modules/geet-geet/lib" && pwd)"
26
+
27
+ # 2. Run the prework (digest-and-locate.sh)
28
+ source "$GEET_LIB/digest-and-locate.sh" "$@"
29
+
30
+ # 3. Dispatch to the appropriate command handler
31
+ cmd="${1:-help}"
32
+ shift || true
33
+
34
+ case "$cmd" in
35
+ help|-h|--help)
36
+ source "$GEET_LIB/help.sh"
37
+ help
38
+ ;;
39
+ sync)
40
+ source "$GEET_LIB/sync.sh"
41
+ sync "${GEET_ARGS[@]:1}"
42
+ ;;
43
+ # ... more commands
44
+ *)
45
+ # Default: treat as git subcommand
46
+ source "$GEET_LIB/git.sh"
47
+ call_cmd "${GEET_ARGS[@]}"
48
+ ;;
49
+ esac
50
+ ```
51
+
52
+ ### Command Flow
53
+
54
+ 1. **Entry** → `bin/geet.sh`
55
+ 2. **Prework** → Sources `lib/digest-and-locate.sh` (sets up environment)
56
+ 3. **Dispatch** → Routes to appropriate command handler in `lib/*.sh`
57
+ 4. **Execute** → Command-specific logic runs
58
+
59
+ ## Prework & Initialization
60
+
61
+ ### `digest-and-locate.sh` - The Setup Script
62
+
63
+ Before any geet command runs, `digest-and-locate.sh` is sourced. This script:
64
+
65
+ 1. **Sources logger.sh** - Sets up the logging system
66
+ 2. **Loads global config** - Sources `config.env` from package root for user preferences
67
+ 3. **Parses flags** - Extracts `--geet-dir`, `--verbose`, `--filter`, `--brave`, etc.
68
+ 4. **Auto-detects template directory** - Finds `.geethier` in parent directories (with caching)
69
+ 5. **Loads template config** - Sources `template-config.env`
70
+ 6. **Sets up environment** - Exports all variables and functions needed by commands
71
+
72
+ ### What Gets Set Up
73
+
74
+ After sourcing `digest-and-locate.sh`, you have access to:
75
+
76
+ - **Paths**: `$GEET_LIB`, `$GEET_CMD`, `$APP_DIR`, `$TEMPLATE_DIR`, etc.
77
+ - **Config values**: `$TEMPLATE_NAME`, `$GEET_ALIAS`, `$TEMPLATE_GH_URL`, etc.
78
+ - **Logging functions**: `debug`, `info`, `log`, `warn`, `critical`, `die`
79
+ - **Helper functions**: `read_config`, `geet_git`, `brave_guard`, etc.
80
+
81
+ See the comments at the top of `lib/digest-and-locate.sh` for the complete list.
82
+
83
+ ### Configuration System
84
+
85
+ Geet uses a multi-file `.env` configuration system for fast loading and clear separation of concerns:
86
+
87
+ #### Global User Preferences: `config.env`
88
+
89
+ Located at the package root (`$GEET_LIB/../config.env`), this file contains user preferences that apply to all geet operations:
90
+
91
+ ```bash
92
+ # Global user preferences
93
+ SHOW_LEVEL=true # Show log level in output
94
+ COLOR_MODE=light # Color scheme: light, dark, or none
95
+ COLOR_SCOPE=line # Color scope: line or level
96
+ ```
97
+
98
+ This file is:
99
+ - Created automatically on first `geet template` run
100
+ - Tracked by git (part of the npm package)
101
+ - User-editable for customization
102
+ - Loaded before any template configs
103
+
104
+ #### Template Configuration: `template-config.env`
105
+
106
+ Located in the template directory (e.g., `.mytemplate/template-config.env`), this file contains template identity and settings:
107
+
108
+ ```bash
109
+ # Template configuration
110
+ TEMPLATE_NAME=mytemplate
111
+ TEMPLATE_DESC="Description of the template"
112
+
113
+ TEMPLATE_GH_USER=username
114
+ TEMPLATE_GH_NAME=reponame
115
+ TEMPLATE_GH_URL=https://github.com/user/repo
116
+ TEMPLATE_GH_SSH=git@github.com:user/repo.git
117
+ TEMPLATE_GH_HTTPS=https://github.com/user/repo.git
118
+
119
+ GEET_ALIAS=geet
120
+ DD_APP_NAME=MyApp
121
+ DD_TEMPLATE_NAME=mytemplate
122
+ ```
123
+
124
+ This file is:
125
+ - Created by `geet template`
126
+ - Tracked by git (committed to template repo)
127
+ - Defines the template's core identity
128
+
129
+
130
+ #### Local System Cache: `untracked-template-config.env`
131
+
132
+ Located in the template directory (e.g., `.mytemplate/untracked-template-config.env`), this file contains system-specific paths:
133
+
134
+ ```bash
135
+ # Auto-generated system-specific paths
136
+ GEET_LIB=/absolute/path/to/lib
137
+ GEET_CMD=/absolute/path/to/bin/geet.sh
138
+ TEMPLATE_DIR=/absolute/path/to/.mytemplate
139
+ APP_DIR=/absolute/path/to/app
140
+ ```
141
+
142
+ This file is:
143
+ - Auto-generated on first run in a directory
144
+ - **NOT tracked** (in `.gitignore`)
145
+ - Caches TEMPLATE_DIR detection (50-200ms savings per run)
146
+ - System-specific, regenerated per installation
147
+
148
+ #### Load Order & Precedence
149
+
150
+ Configuration is loaded in this order (later overrides earlier):
151
+
152
+ 1. **Global config** (`config.env`) - User preferences
153
+ 2. **Template config** (`template-config.env`) - Template identity
154
+ 4. **Local cache** (`untracked-template-config.env`) - System paths
155
+ 5. **Command-line flags** - Highest precedence
156
+
157
+ #### Performance Impact
158
+
159
+ The .env system provides massive performance improvements:
160
+
161
+ - **Before**: 300-900ms prework time
162
+ - 10 jq calls: 100-200ms
163
+ - gh API call: 200-500ms
164
+ - Directory walking: 50-200ms
165
+ - **After**: 6-10ms prework time
166
+ - Load 3-4 .env files: 4-8ms
167
+ - String operations: ~1ms
168
+ - **35-90x faster!**
169
+
170
+ ### Template Detection
171
+
172
+ `digest-and-locate.sh` uses a **fast path / slow path** strategy to find your template directory:
173
+
174
+ #### Fast Path (Cached)
175
+
176
+ 1. Check for `untracked-template-config.env` in current directory and parent directories
177
+ 2. If found, load `TEMPLATE_DIR` from cache (4-8ms)
178
+ 3. Verify cached path is still valid (`.geethier` exists)
179
+
180
+ #### Slow Path (Directory Walking)
181
+
182
+ Only runs on cache miss:
183
+
184
+ 1. Starting from `$PWD`
185
+ 2. Looking for hidden directories containing `.geethier`
186
+ 3. Choosing the directory with the most lines in `.geethier` (indicates hierarchy depth)
187
+ 4. Walking up parent directories until finding a candidate or hitting a `.git` directory
188
+ 5. Creating `untracked-template-config.env` cache for future runs
189
+
190
+ **Result**: First run in a directory is ~50-200ms, subsequent runs are ~4-8ms.
191
+
192
+ You can override auto-detection with `--geet-dir /path/to/template`.
193
+
194
+ ## Logging System
195
+
196
+ ### Overview
197
+
198
+ The logging system lives in `lib/logger.sh` and provides structured, filterable logging with color support.
199
+
200
+ ### Log Levels
201
+
202
+ From least to most severe:
203
+
204
+ - `DEBUG` - Verbose diagnostic information
205
+ - `INFO` - General informational messages
206
+ - `WARN` - Warning messages
207
+ - `ERROR` - Error messages
208
+ - `CRITICAL` - Critical errors (used by `die`)
209
+ - `NEVER` - Suppresses all output
210
+
211
+ ### Logging Functions
212
+
213
+ ```bash
214
+ debug "Checking for template at $dir" # Only shown with --verbose
215
+ info "Syncing template changes..." # Default level
216
+ log "Same as info" # Alias
217
+ warn "Config file not found, using defaults"
218
+ critical "Failed to initialize repository"
219
+ die "Fatal error: cannot proceed" # Logs and exits with code 1
220
+ ```
221
+
222
+ ### Controlling Log Output
223
+
224
+ #### By Level
225
+
226
+ ```bash
227
+ # Show everything including debug messages
228
+ geet sync --verbose
229
+
230
+ # Show only warnings and errors
231
+ geet sync --quiet
232
+
233
+ # Show only errors
234
+ geet sync --min-level ERROR
235
+
236
+ # Suppress all output
237
+ geet sync --silent
238
+ ```
239
+
240
+ #### By Filter Pattern
241
+
242
+ Use `--filter` to show only messages containing a specific string:
243
+
244
+ ```bash
245
+ # Only show messages containing "template"
246
+ geet sync --filter template
247
+
248
+ # Only show messages containing "LOCATE"
249
+ geet tree --verbose --filter LOCATE
250
+ ```
251
+
252
+ #### Inverting Filters with `~`
253
+
254
+ Prefix your filter with `~` to **exclude** messages matching the pattern:
255
+
256
+ ```bash
257
+ # Show all messages EXCEPT those containing "DEBUG"
258
+ geet sync --verbose --filter '~DEBUG'
259
+
260
+ # Show all messages EXCEPT those containing "git"
261
+ geet doctor --filter '~git'
262
+ ```
263
+
264
+ The `~` acts as a "NOT" operator, inverting the filter logic.
265
+
266
+ ### Filter Implementation
267
+
268
+ From `lib/logger.sh:125-136`:
269
+
270
+ ```bash
271
+ if [[ -n "${LOG_FILTER:-}" ]]; then
272
+ if [[ "$LOG_FILTER" == \~* ]]; then
273
+ # exclude mode: pattern starts with ~
274
+ local pat="${LOG_FILTER:1}"
275
+ [[ "$plain" == *"$pat"* ]] && return 0 # Skip if matches
276
+ else
277
+ # include mode: normal pattern
278
+ [[ "$plain" != *"$LOG_FILTER"* ]] && return 0 # Skip if doesn't match
279
+ fi
280
+ fi
281
+ ```
282
+
283
+ ### Color Configuration
284
+
285
+ Colors are controlled by environment variables in `digest-and-locate.sh`:
286
+
287
+ ```bash
288
+ COLOR_MODE="light" # Options: light, dark, none
289
+ COLOR_SCOPE="line" # Options: line, level
290
+ ```
291
+
292
+ - `COLOR_MODE` - Color scheme for terminal output
293
+ - `light` - Colors optimized for light backgrounds
294
+ - `dark` - Colors optimized for dark backgrounds
295
+ - `none` - No colors
296
+ - `COLOR_SCOPE` - What gets colored
297
+ - `line` - Color the entire log line
298
+ - `level` - Color only the level prefix (e.g., `[DEBUG]`)
299
+
300
+ ## Available Variables & Functions
301
+
302
+ After sourcing `digest-and-locate.sh`, these are available in your command scripts:
303
+
304
+ ### Key Paths
305
+
306
+ ```bash
307
+ $GEET_LIB # Path to lib/ directory
308
+ $GEET_CMD # Path to bin/geet.sh
309
+ $APP_DIR # Your app's root directory (parent of template dir)
310
+ $APP_NAME # Name of your app
311
+ $TEMPLATE_DIR # The template directory (e.g., .mytemplate)
312
+ $DOTGIT # The template's git directory (TEMPLATE_DIR/dot-git)
313
+ $GEET_GIT # Path to geet-git.sh wrapper
314
+ ```
315
+
316
+ ### Config Values
317
+
318
+ ```bash
319
+ $TEMPLATE_NAME # Template name from config
320
+ $TEMPLATE_DESC # Template description
321
+ $GEET_ALIAS # Command alias (usually "geet")
322
+ $TEMPLATE_GH_USER # GitHub username
323
+ $TEMPLATE_GH_NAME # GitHub repo name
324
+ $TEMPLATE_GH_URL # GitHub URL
325
+ $TEMPLATE_GH_SSH # SSH remote URL
326
+ $TEMPLATE_GH_HTTPS # HTTPS remote URL
327
+ ```
328
+
329
+ ### Flags
330
+
331
+ ```bash
332
+ $BRAVE # Set if --brave flag present
333
+ $VERBOSE # Set if --verbose flag present
334
+ $QUIET # Set if --quiet flag present
335
+ $SILENT # Set if --silent flag present
336
+ $MIN_LOG_LEVEL # Current minimum log level
337
+ $LOG_FILTER # Active log filter pattern
338
+ ```
339
+
340
+ ### Helper Functions
341
+
342
+ ```bash
343
+ read_config KEY [DEFAULT] # Get config value by key name
344
+ geet_git [args...] # Run git in template context
345
+ detect_template_dir_from_cwd # Auto-find template directory
346
+ brave_guard CMD [REASON] # Require --brave flag or exit
347
+ log_if_brave MESSAGE # Log only if --brave is set
348
+ ```
349
+
350
+ ## Writing New Commands
351
+
352
+ ### Basic Template
353
+
354
+ Create a new file in `lib/your-command.sh`:
355
+
356
+ ```bash
357
+ #!/usr/bin/env bash
358
+ # lib/my-command.sh
359
+
360
+ # This function assumes digest-and-locate.sh has already been sourced
361
+ # So you have access to all the variables and functions listed above
362
+
363
+ my_command() {
364
+ debug "Starting my-command with args: $*"
365
+
366
+ # Check if we're in a template directory
367
+ if [[ -z "$TEMPLATE_DIR" ]]; then
368
+ die "Not in a geet template directory. Run this from your app directory."
369
+ fi
370
+
371
+ # Use logging functions
372
+ log "Running my command..."
373
+
374
+ # Read from config
375
+ local template_name
376
+ template_name="$(read_config name "unknown")"
377
+ info "Template name: $template_name"
378
+
379
+ # Run git commands
380
+ geet_git status
381
+
382
+ # Guard dangerous operations
383
+ brave_guard "my dangerous operation" "This will modify important files."
384
+
385
+ log "Done!"
386
+ }
387
+ ```
388
+
389
+ ### Add to Dispatcher
390
+
391
+ Edit `bin/geet.sh` to add your command:
392
+
393
+ ```bash
394
+ case "$cmd" in
395
+ # ... existing commands ...
396
+
397
+ my-command)
398
+ source "$GEET_LIB/my-command.sh"
399
+ my_command "${GEET_ARGS[@]:1}"
400
+ ;;
401
+
402
+ # ... rest of commands ...
403
+ esac
404
+ ```
405
+
406
+ ### Testing Your Command
407
+
408
+ ```bash
409
+ # Run with verbose logging
410
+ geet my-command --verbose
411
+
412
+ # Run with filtering
413
+ geet my-command --verbose --filter "my-command"
414
+
415
+ # Run with brave mode
416
+ geet my-command --brave
417
+ ```
418
+
419
+ ## Debugging Tips
420
+
421
+ ### Use Verbose Mode
422
+
423
+ Always develop with `--verbose` to see debug messages:
424
+
425
+ ```bash
426
+ geet your-command --verbose
427
+ ```
428
+
429
+ ### Filter Noise
430
+
431
+ If there's too much output, filter it:
432
+
433
+ ```bash
434
+ # Only show messages from your command
435
+ geet your-command --verbose --filter "my-command"
436
+
437
+ # Exclude git-related messages
438
+ geet your-command --verbose --filter '~git'
439
+ ```
440
+
441
+ ### Check What's Loaded
442
+
443
+ Add debug messages to see what's set:
444
+
445
+ ```bash
446
+ debug "TEMPLATE_DIR=$TEMPLATE_DIR"
447
+ debug "TEMPLATE_NAME=$TEMPLATE_NAME"
448
+ debug "BRAVE=$BRAVE"
449
+ ```
450
+
451
+ ### Trace Execution
452
+
453
+ Enable bash tracing for maximum detail:
454
+
455
+ ```bash
456
+ bash -x "$(which geet)" your-command
457
+ ```
458
+
459
+ ## Common Patterns
460
+
461
+ ### Reading Config Values
462
+
463
+ All config values are available as environment variables after prework. Access them directly:
464
+
465
+ ```bash
466
+ # Direct access (preferred)
467
+ log "Template name: $TEMPLATE_NAME"
468
+ log "GitHub URL: $TEMPLATE_GH_URL"
469
+
470
+ # Using read_config helper (maps legacy keys to env vars)
471
+ timeout="$(read_config timeout 30)"
472
+
473
+ # Check if required value is set
474
+ [[ -z "$TEMPLATE_NAME" ]] && die "TEMPLATE_NAME not set"
475
+ ```
476
+
477
+ ### Guarding Destructive Operations
478
+
479
+ ```bash
480
+ dangerous_operation() {
481
+ brave_guard "deleting files" "This will permanently remove files."
482
+
483
+ # This only runs if --brave was passed
484
+ rm -rf "$SOME_DIR"
485
+ }
486
+ ```
487
+
488
+ ### Conditional Logging
489
+
490
+ ```bash
491
+ # Only log if --brave
492
+ log_if_brave "About to do something risky..."
493
+
494
+ # Custom conditions
495
+ if [[ "$VERBOSE" ]]; then
496
+ log "Detailed diagnostic info..."
497
+ fi
498
+ ```
499
+
500
+ ### Working with Git
501
+
502
+ ```bash
503
+ # Use geet_git wrapper (respects template context)
504
+ geet_git fetch origin
505
+
506
+ # Get git output
507
+ current_branch="$(geet_git rev-parse --abbrev-ref HEAD)"
508
+ ```
509
+
510
+ ## Summary
511
+
512
+ 1. **All commands start** via `bin/geet.sh`
513
+ 2. **Prework runs first** (`digest-and-locate.sh` sets up environment)
514
+ 3. **Logging is centralized** (use `debug`, `info`, `warn`, `critical`, `die`)
515
+ 4. **Filter with `--filter`** (use `~` prefix to invert)
516
+ 5. **Guard dangerous ops** with `brave_guard`
517
+ 6. **Everything is documented** in `digest-and-locate.sh` comments
518
+
519
+ For more examples, browse the existing command files in `lib/`.
package/docs/FAQ.md ADDED
@@ -0,0 +1,128 @@
1
+ ## FAQ
2
+
3
+ ### What is geet?
4
+
5
+ **Geet lets you maintain a reusable template as a real Git repo over the same working tree as your app, without copying files, moving paths, or running generators.**
6
+
7
+ In practice: two or more Git repos, one folder.
8
+
9
+ ---
10
+
11
+ ### How is this different from a normal template?
12
+
13
+ Normal templates:
14
+
15
+ * copy files once
16
+ * drift immediately as the template owner makes updates and changes
17
+ * require regeneration or manual syncing
18
+
19
+ Geet:
20
+
21
+ * shares *real files at real paths*
22
+ * updates via `git pull`
23
+ * never copies or regenerates code
24
+
25
+ ---
26
+
27
+ ### How is this different from Git submodules?
28
+
29
+ Submodules:
30
+
31
+ * live in a subdirectory
32
+ * can’t interleave files with the app
33
+ * break path-sensitive systems (Expo, routing, config)
34
+
35
+ Geet:
36
+
37
+ * works **at the project root**
38
+ * files stay exactly where the app expects them
39
+ * no nested repos in your source tree
40
+
41
+ **NOTE**: If you have the ability to fully and cleanly separate your template into a separate folder, consider using submodules instead. Geet is made for cases where that is not feasible.
42
+
43
+ ---
44
+
45
+ ### How is this different from Git subtrees?
46
+
47
+ Subtrees:
48
+
49
+ * still copy files into the repo
50
+ * still requires a separate folder for the template, does not support interleaving
51
+ * updates are noisy and opaque
52
+ * merges become painful over time
53
+
54
+ Geet:
55
+
56
+ * no copying
57
+ * no sync step
58
+ * updates are normal Git merges
59
+
60
+ ---
61
+
62
+ ### Why not monorepos?
63
+
64
+ Monorepos:
65
+
66
+ * assume clear ownership boundaries
67
+ * don’t work well when *most* files overlap
68
+ * still require indirection or abstraction
69
+
70
+ Geet is for cases where:
71
+
72
+ * 50–90% of files are shared
73
+ * file locations are non-negotiable
74
+ * you want minimal abstraction
75
+
76
+ ---
77
+
78
+ ### Is this safe?
79
+
80
+ Yes, if used as intended.
81
+
82
+ * The app repo remains totally standard.
83
+ * The template repo is sandboxed via a whitelist.
84
+ * Destructive Git commands are blocked by default.
85
+ * You can detach at any time by deleting the layer folder.
86
+
87
+ ---
88
+
89
+ ### Is this a Git hack?
90
+
91
+ Yes — deliberately.
92
+
93
+ Git already supports:
94
+
95
+ * separate `GIT_DIR`
96
+ * shared working trees
97
+ * repo-local ignore rules
98
+
99
+ Geet just assembles those primitives into a usable tool.
100
+
101
+ ---
102
+
103
+ ### Who is geet for?
104
+
105
+ * Teams maintaining multiple similar apps
106
+ * Path-sensitive frameworks (Expo, RN, Next, native builds)
107
+ * Developers who want **Git-native updates**, not generators
108
+ * Anyone burned by templates that drift
109
+
110
+ ---
111
+
112
+ ### When should I *not* use geet?
113
+
114
+ Don’t use geet if:
115
+
116
+ * your template can live in a subdirectory
117
+ * copying files is acceptable
118
+ * your shared code is small or purely library-based
119
+
120
+ Geet is for the “everything overlaps” case.
121
+
122
+ ---
123
+
124
+ If you want, next we can:
125
+
126
+ * tighten this FAQ even more
127
+ * add a “When geet is the wrong tool” section
128
+ * or turn this into a README-ready block