@garyr/pt-cli 1.1.1 → 1.3.1
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/CHANGELOG.md +47 -0
- package/README.md +26 -27
- package/dist/commands/completionCommand.js +49 -12
- package/dist/commands/initCommand.js +476 -181
- package/dist/index.js +22 -4
- package/dist/substitute.js +45 -19
- package/doc/configuration.md +7 -5
- package/doc/usage.md +22 -5
- package/package.json +1 -1
- package/skills/agency-pt-operator/SKILL.md +5 -4
- package/src/commands/completionCommand.ts +49 -12
- package/src/commands/initCommand.ts +495 -194
- package/src/index.ts +20 -4
- package/src/substitute.ts +48 -21
- package/tests/modularity.test.ts +605 -0
package/CHANGELOG.md
CHANGED
|
@@ -7,6 +7,53 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
|
|
|
7
7
|
|
|
8
8
|
---
|
|
9
9
|
|
|
10
|
+
## [1.3.0] - 2026-09-08
|
|
11
|
+
|
|
12
|
+
### Added
|
|
13
|
+
|
|
14
|
+
- **Multi-template task deduplication**: `pt init` now deduplicates post-config tasks across templates by command+description, executing each unique task only once
|
|
15
|
+
- **ID-based task selection**: Internal `_id` fields prevent key collisions when identical commands exist in multiple templates
|
|
16
|
+
|
|
17
|
+
### Changed
|
|
18
|
+
|
|
19
|
+
- **Aggregated security warnings**: Single security prompt for all templates (was per-template), preventing early abort when one template has dangerous commands
|
|
20
|
+
- **Template attribution in UI**: Deduplicated tasks show all contributing templates (e.g., `[base-template, addon-template]`)
|
|
21
|
+
|
|
22
|
+
### Fixed
|
|
23
|
+
|
|
24
|
+
- Duplicate `git init` execution when multiple templates include the same post-config task
|
|
25
|
+
- Security warning loop that cancelled all templates when user declined one template's post-config
|
|
26
|
+
|
|
27
|
+
---
|
|
28
|
+
|
|
29
|
+
## [1.2.0] - 2026-09-04
|
|
30
|
+
|
|
31
|
+
### Added
|
|
32
|
+
|
|
33
|
+
- **Modular multi-template initialization**: `pt init <template1> <template2> <target>` combines folders, files, variables, and post-config from multiple templates
|
|
34
|
+
- **Collision handling**: Detects and reports conflicting folder names, file destinations, and variable definitions across templates
|
|
35
|
+
- **Readme renaming**: Auto-renames `README.md` from each template to `README_<template>.md` to prevent overwrites
|
|
36
|
+
|
|
37
|
+
### Changed
|
|
38
|
+
|
|
39
|
+
- **Init command accepts multiple templates**: Space-separated template names before target directory
|
|
40
|
+
- **Variable merging**: Template variables merged with collision detection and clear error messages
|
|
41
|
+
|
|
42
|
+
---
|
|
43
|
+
|
|
44
|
+
## [1.1.0] - 2026-09-03
|
|
45
|
+
|
|
46
|
+
### Added
|
|
47
|
+
|
|
48
|
+
- **Shell completions**: `pt completion <bash|zsh|fish>` generates shell completion scripts
|
|
49
|
+
- **Completion install guidance**: Printed instructions for adding to shell rc files
|
|
50
|
+
|
|
51
|
+
### Fixed
|
|
52
|
+
|
|
53
|
+
- **Shell completions interfere with PT-GUI**: Removed auto-install behavior that broke GUI integration; completions now opt-in only
|
|
54
|
+
|
|
55
|
+
---
|
|
56
|
+
|
|
10
57
|
## [1.0.0] - 2026-07-31
|
|
11
58
|
|
|
12
59
|
### 🎉 First Stable Release
|
package/README.md
CHANGED
|
@@ -26,33 +26,32 @@ graph LR
|
|
|
26
26
|
RSA -. Update .-> Engine
|
|
27
27
|
|
|
28
28
|
style Engine fill:#f9f,stroke:#333,stroke-width:2px,color:#000
|
|
29
|
-
|
|
30
29
|
```
|
|
31
30
|
|
|
32
31
|
<!-- TOC -->
|
|
33
32
|
|
|
34
33
|
- [pt - Project Template CLI](#pt---project-template-cli)
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
34
|
+
- [Why pt-cli?](#why-pt-cli)
|
|
35
|
+
- [Core Benefits & Uses](#core-benefits--uses)
|
|
36
|
+
- [🚀 Low-Friction Templating](#-low-friction-templating)
|
|
37
|
+
- [🧠 Reduces Cognitive Load](#-reduces-cognitive-load)
|
|
38
|
+
- [📦 Sharing is Caring](#-sharing-is-caring)
|
|
39
|
+
- [🤖 Agentic and API Friendly](#-agentic-and-api-friendly)
|
|
40
|
+
- [Features at a Glance](#features-at-a-glance)
|
|
41
|
+
- [Quick Start](#quick-start)
|
|
42
|
+
- [Installation](#installation)
|
|
43
|
+
- [Basic Commands](#basic-commands)
|
|
44
|
+
- [Shell Completions](#shell-completions)
|
|
45
|
+
- [Agent Integration](#agent-integration)
|
|
46
|
+
- [Documentation](#documentation)
|
|
47
|
+
- [Development](#development)
|
|
48
|
+
- [Where are the Templates?](#where-are-the-templates)
|
|
49
|
+
- [Release & API Stability](#release--api-stability)
|
|
50
|
+
- [🔒 Stability Guarantee 1.x series](#-stability-guarantee-1x-series)
|
|
51
|
+
- [📦 Versioning Policy](#-versioning-policy)
|
|
52
|
+
- [📋 What's Locked in 1.0](#-whats-locked-in-10)
|
|
53
|
+
- [📖 Migration from 0.x to 1.0](#-migration-from-0x-to-10)
|
|
54
|
+
- [Documentation](#documentation)
|
|
56
55
|
|
|
57
56
|
<!-- /TOC -->
|
|
58
57
|
|
|
@@ -60,7 +59,7 @@ graph LR
|
|
|
60
59
|
|
|
61
60
|
Traditional project templating often tightly couples logic and configuration, meaning every new template requires code changes. `pt-cli` breaks that ceiling by separating project definitions from the underlying logic.
|
|
62
61
|
|
|
63
|
-
Instead of writing complex, hard-coded configuration files to scaffold new work, `pt-cli` allows you to **
|
|
62
|
+
Instead of writing complex, hard-coded configuration files to scaffold new work, `pt-cli` allows you to **learn** from your existing project directories and turn them into templates. It doesn't enforce a specific folder structure; it supports *your* existing patterns.
|
|
64
63
|
|
|
65
64
|
## Core Benefits & Uses
|
|
66
65
|
|
|
@@ -114,8 +113,8 @@ pt learn /path/to/PROJECT
|
|
|
114
113
|
# Learn a template from a remote repository (e.g. GitHub, Gitea, or path to tarball)
|
|
115
114
|
pt learn https://github.com/garyritchie/pt_godot
|
|
116
115
|
|
|
117
|
-
# Scaffold a new project from
|
|
118
|
-
pt init <template_name> /path/to/NEW_PROJECT
|
|
116
|
+
# Scaffold a new project from one or more learned templates
|
|
117
|
+
pt init <template_name> [template_name2...] /path/to/NEW_PROJECT
|
|
119
118
|
|
|
120
119
|
# List available templates and configurations
|
|
121
120
|
pt config
|
|
@@ -128,7 +127,6 @@ pt add my-new-template --file my-new-template.json
|
|
|
128
127
|
|
|
129
128
|
# Scaffold directly from a JSON file (no config registration required)
|
|
130
129
|
pt init ./new-project --file my-template.json --yes
|
|
131
|
-
|
|
132
130
|
```
|
|
133
131
|
|
|
134
132
|
### Shell Completions
|
|
@@ -143,6 +141,7 @@ pt completion bash > /etc/bash_completion.d/pt
|
|
|
143
141
|
# Zsh
|
|
144
142
|
pt completion zsh > ~/.zsh/completions/_pt
|
|
145
143
|
# Add to ~/.zshrc: fpath=(~/.zsh/completions $fpath)
|
|
144
|
+
# autoload -U compinit && compinit
|
|
146
145
|
|
|
147
146
|
# Fish
|
|
148
147
|
pt completion fish > ~/.config/fish/completions/pt.fish
|
|
@@ -281,4 +280,4 @@ If you skipped intermediate 0.x versions, the auto-migration handles everything.
|
|
|
281
280
|
* **[Security Guide](doc/security.md)** - Command validation, trusted sources, audit logging.
|
|
282
281
|
* **[Testing Guide](doc/testing.md)** - Test suite structure and running tests.
|
|
283
282
|
* **[Exclusions Reference](doc/exclusions.md)** - Default ignored files and custom patterns.
|
|
284
|
-
* **[Variable Substitution Example](doc/variable_substitution_example.md)** - Practical examples.
|
|
283
|
+
* **[Variable Substitution Example](doc/variable_substitution_example.md)** - Practical examples.
|
|
@@ -65,11 +65,30 @@ _pt_completions() {
|
|
|
65
65
|
;;
|
|
66
66
|
init)
|
|
67
67
|
if [[ "$cur" == -* ]]; then
|
|
68
|
-
COMPREPLY=( $(compgen -W "-f --file --skip-post-config --dry-run -y --yes --vars -h --help" -- "$cur") )
|
|
69
|
-
elif [[ $cword -
|
|
68
|
+
COMPREPLY=( $(compgen -W "-f --file --skip-post-config --dry-run -y --yes --vars --collision --json -h --help" -- "$cur") )
|
|
69
|
+
elif [[ $cword -ge 2 ]]; then
|
|
70
|
+
# Try template name completion first
|
|
70
71
|
local templates
|
|
71
72
|
templates=$(pt completion --templates 2>/dev/null)
|
|
72
|
-
|
|
73
|
+
local template_matches
|
|
74
|
+
template_matches=$(compgen -W "$templates" -- "$cur")
|
|
75
|
+
|
|
76
|
+
# If we're at a position where destination could be (cword >= 2 for first arg after init,
|
|
77
|
+
# or cword >= 3 with templates already specified),
|
|
78
|
+
# also try directory completion. This handles cases like "pt init Base SPA PARK<TAB>"
|
|
79
|
+
local dir_matches
|
|
80
|
+
if [[ $cword -ge 2 ]]; then
|
|
81
|
+
dir_matches=$(compgen -d -- "$cur")
|
|
82
|
+
fi
|
|
83
|
+
|
|
84
|
+
# Combine matches - template matches first, then directory matches
|
|
85
|
+
COMPREPLY=()
|
|
86
|
+
if [[ -n "$template_matches" ]]; then
|
|
87
|
+
COMPREPLY=( $template_matches )
|
|
88
|
+
fi
|
|
89
|
+
if [[ -n "$dir_matches" ]]; then
|
|
90
|
+
COMPREPLY+=( $dir_matches )
|
|
91
|
+
fi
|
|
73
92
|
fi
|
|
74
93
|
;;
|
|
75
94
|
config)
|
|
@@ -192,15 +211,16 @@ _pt() {
|
|
|
192
211
|
'2:sourcePath:_files -/'
|
|
193
212
|
;;
|
|
194
213
|
init)
|
|
195
|
-
_arguments
|
|
196
|
-
'(-f --file)'{-f,--file}'[Initialize directly from a JSON template file]:file:_files'
|
|
197
|
-
'--skip-post-config[Skip running post-config tasks]'
|
|
198
|
-
'--dry-run[Show what would be created without making changes]'
|
|
199
|
-
'(-y --yes)'{-y,--yes}'[Automatically answer yes to prompts]'
|
|
200
|
-
'--vars=[Comma-separated key=value variables]:variables:'
|
|
201
|
-
'
|
|
202
|
-
'
|
|
203
|
-
'
|
|
214
|
+
_arguments \
|
|
215
|
+
'(-f --file)'{-f,--file}'[Initialize directly from a JSON template file]:file:_files' \
|
|
216
|
+
'--skip-post-config[Skip running post-config tasks]' \
|
|
217
|
+
'--dry-run[Show what would be created without making changes]' \
|
|
218
|
+
'(-y --yes)'{-y,--yes}'[Automatically answer yes to prompts]' \
|
|
219
|
+
'--vars=[Comma-separated key=value variables]:variables:' \
|
|
220
|
+
'--collision=[File collision resolution strategy]:mode:(overwrite newest)' \
|
|
221
|
+
'--json[Output result as JSON]' \
|
|
222
|
+
'(-h --help)'{-h,--help}'[display help for command]' \
|
|
223
|
+
'*: :(_pt_templates _directories)'
|
|
204
224
|
;;
|
|
205
225
|
config)
|
|
206
226
|
_arguments \\
|
|
@@ -321,11 +341,28 @@ complete -c pt -n '__fish_pt_using_command update' -l no-diff -d 'Disable additi
|
|
|
321
341
|
|
|
322
342
|
# init
|
|
323
343
|
complete -c pt -n '__fish_pt_using_command init' -a '(__fish_pt_templates)' -d 'Template name'
|
|
344
|
+
complete -c pt -n '__fish_pt_using_command init' -F -d 'Target directory' --wraps=pt --condition=__fish_pt_init_dir
|
|
324
345
|
complete -c pt -n '__fish_pt_using_command init' -s f -l file -d 'Initialize directly from a JSON template file without adding it to local config'
|
|
325
346
|
complete -c pt -n '__fish_pt_using_command init' -l skip-post-config -d 'Skip running post-config tasks'
|
|
326
347
|
complete -c pt -n '__fish_pt_using_command init' -l dry-run -d 'Show what would be created without making changes'
|
|
327
348
|
complete -c pt -n '__fish_pt_using_command init' -s y -l yes -d 'Automatically answer yes to prompts'
|
|
328
349
|
complete -c pt -n '__fish_pt_using_command init' -l vars -d 'Comma-separated key=value variables'
|
|
350
|
+
complete -c pt -n '__fish_pt_using_command init' -l collision -a 'overwrite newest' -d 'File collision resolution strategy'
|
|
351
|
+
complete -c pt -n '__fish_pt_using_command init' -l json -d 'Output result as JSON'
|
|
352
|
+
|
|
353
|
+
# Helper function for init directory completion (only when last positional arg looks like a path)
|
|
354
|
+
function __fish_pt_init_dir
|
|
355
|
+
set -l cmd (commandline -opc)
|
|
356
|
+
# Count non-flag positional arguments after 'init'
|
|
357
|
+
set -l args (string match -r '(^[^ ]+ )?init( .+)?' <<< "$cmd")
|
|
358
|
+
# Simple approach: if the current token contains / or starts with ~ or ., complete as directory
|
|
359
|
+
set -l cur (commandline -ct)
|
|
360
|
+
if string match -q '*/' "$cur"; or string match -q '~*' "$cur"; or string match -q '.*' "$cur"
|
|
361
|
+
return 0
|
|
362
|
+
else
|
|
363
|
+
return 1
|
|
364
|
+
end
|
|
365
|
+
end
|
|
329
366
|
|
|
330
367
|
# config
|
|
331
368
|
complete -c pt -n '__fish_pt_using_command config' -a '(__fish_pt_templates)' -d 'Template name'
|