its-magic 0.1.2-13 → 0.1.2-15

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
@@ -69,17 +69,48 @@ its-magic --target . --mode overwrite --backup
69
69
  2. Run `/intake` with your idea
70
70
  3. Follow the workflow
71
71
 
72
+ ### CLI quick commands
73
+
74
+ ```bash
75
+ # Show banner + help
76
+ its-magic
77
+
78
+ # Show version only
79
+ its-magic --version
80
+
81
+ # Install workflow files into current repo
82
+ its-magic --target . --mode missing
83
+
84
+ # Clean previously installed workflow artifacts
85
+ its-magic --clean-repo --target .
86
+ ```
87
+
72
88
  ### Installer options
73
89
 
90
+ **Install options**
91
+
92
+ | Flag | Description |
93
+ |------|-------------|
94
+ | `--target <path>` | Path to the repository where workflow files are installed. If omitted you are prompted interactively. |
95
+ | `--mode missing` | **Default.** Only copy files that do not exist yet. Safe for repos that already have some workflow files. |
96
+ | `--mode overwrite` | Replace every file, even if it already exists. Combine with `--backup` to keep a snapshot first. |
97
+ | `--mode interactive` | Ask per file whether to overwrite or skip. Useful when you want to cherry-pick updates. |
98
+ | `--backup` | Before overwriting, save existing files to `backups/<timestamp>/`. Ignored in `missing` mode (nothing gets replaced). |
99
+ | `--create` | Create the target directory if it does not exist. |
100
+
101
+ **Clean options**
102
+
103
+ | Flag | Description |
104
+ |------|-------------|
105
+ | `--clean-repo` | Remove all its-magic workflow artifacts from the target repo (`.cursor`, `docs/product`, `docs/engineering`, `sprints`, `handoffs`, `decisions`). Your own source code is never touched. |
106
+ | `--yes` | Skip the confirmation prompt when cleaning. |
107
+
108
+ **Info**
109
+
74
110
  | Flag | Description |
75
111
  |------|-------------|
76
- | `--target <path>` | Target repo path |
77
- | `--mode missing` | Copy only missing files |
78
- | `--mode overwrite` | Replace existing files |
79
- | `--mode interactive` | Prompt per file |
80
- | `--backup` | Save replaced files into `backups/<timestamp>/` |
81
- | `--create` | Create target directory |
82
- | `--help` | Show usage |
112
+ | `--help`, `-h` | Show banner, version, repo URL, and full usage reference. |
113
+ | `--version`, `-v` | Print the installed its-magic version and exit. |
83
114
 
84
115
  ## How-to
85
116
 
package/bin/its-magic.js CHANGED
@@ -1,9 +1,52 @@
1
1
  #!/usr/bin/env node
2
2
  const path = require("path");
3
3
  const { spawnSync } = require("child_process");
4
+ const packageJson = require("../package.json");
5
+
6
+ const REPO_URL = "https://github.com/fl0wm0ti0n/its-magic";
7
+
8
+ function printBanner() {
9
+ const M = "\x1b[1;35m";
10
+ const C = "\x1b[1;36m";
11
+ const Y = "\x1b[1;33m";
12
+ const R = "\x1b[0m";
13
+ console.log("");
14
+ console.log(`${M} ██╗████████╗███████╗ ███╗ ███╗ █████╗ ██████╗ ██╗ ██████╗${R}`);
15
+ console.log(`${M} ██║╚══██╔══╝██╔════╝ ████╗ ████║██╔══██╗██╔════╝ ██║██╔════╝${R}`);
16
+ console.log(`${M} ██║ ██║ ███████╗█████╗██╔████╔██║███████║██║ ███╗██║██║ ${R}`);
17
+ console.log(`${C} ██║ ██║ ╚════██║╚════╝██║╚██╔╝██║██╔══██║██║ ██║██║██║ ${R}`);
18
+ console.log(`${C} ██║ ██║ ███████║ ██║ ╚═╝ ██║██║ ██║╚██████╔╝██║╚██████╗${R}`);
19
+ console.log(`${C} ╚═╝ ╚═╝ ╚══════╝ ╚═╝ ╚═╝╚═╝ ╚═╝ ╚═════╝ ╚═╝ ╚═════╝${R}`);
20
+ console.log("");
21
+ console.log(`${Y} AI dev team${R}`);
22
+ console.log("");
23
+ }
4
24
 
5
25
  function parseArgs(argv) {
6
- const args = { target: process.cwd(), mode: "missing", backup: false, create: false };
26
+ const args = {
27
+ target: process.cwd(),
28
+ mode: "missing",
29
+ backup: false,
30
+ create: false,
31
+ cleanRepo: false,
32
+ yes: false,
33
+ help: false,
34
+ version: false,
35
+ };
36
+
37
+ if (argv.length === 0) {
38
+ args.help = true;
39
+ return args;
40
+ }
41
+
42
+ const first = argv[0];
43
+ if (first === "help") return { ...args, help: true };
44
+ if (first === "version") return { ...args, version: true };
45
+ if (first === "clean") {
46
+ args.cleanRepo = true;
47
+ argv = argv.slice(1);
48
+ }
49
+
7
50
  for (let i = 0; i < argv.length; i += 1) {
8
51
  const a = argv[i];
9
52
  if (a === "--target" && argv[i + 1]) {
@@ -24,24 +67,66 @@ function parseArgs(argv) {
24
67
  args.create = true;
25
68
  continue;
26
69
  }
70
+ if (a === "--clean-repo") {
71
+ args.cleanRepo = true;
72
+ continue;
73
+ }
74
+ if (a === "--yes") {
75
+ args.yes = true;
76
+ continue;
77
+ }
27
78
  if (a === "--help" || a === "-h") {
28
- return { help: true };
79
+ args.help = true;
80
+ continue;
81
+ }
82
+ if (a === "--version" || a === "-v") {
83
+ args.version = true;
84
+ continue;
29
85
  }
30
86
  }
31
87
  return args;
32
88
  }
33
89
 
34
90
  function printHelp() {
35
- console.log(`its-magic
91
+ printBanner();
92
+ console.log(`its-magic v${packageJson.version}
93
+ Repository: ${REPO_URL}
94
+
95
+ Install AI dev team workflow files into any Cursor repository.
36
96
 
37
97
  Usage:
38
- npx its-magic --target <path> --mode missing [--backup] [--create]
98
+ its-magic --target <path> [--mode <mode>] [--backup] [--create]
99
+ its-magic --clean-repo [--target <path>] [--yes]
100
+ its-magic --help | --version
39
101
 
40
- Options:
41
- --target Target repository path (default: current directory)
42
- --mode missing | overwrite | interactive (default: missing)
43
- --backup Backup files before overwrite
44
- --create Create target directory if missing
102
+ Install options:
103
+ --target <path> Path to the repository where workflow files are installed.
104
+ If omitted you will be prompted interactively.
105
+ --mode <mode> How to handle files that already exist in the target:
106
+ missing Only copy files that do not exist yet (default).
107
+ Safe for repos that already have some workflow files.
108
+ overwrite Replace every file, even if it already exists.
109
+ Combine with --backup to keep a snapshot first.
110
+ interactive Ask per file whether to overwrite or skip.
111
+ --backup Before overwriting, save existing files to backups/<timestamp>/.
112
+ Ignored when mode is "missing" (nothing gets replaced).
113
+ --create Create the target directory if it does not exist.
114
+
115
+ Clean options:
116
+ --clean-repo Remove all its-magic workflow artifacts from the target repo
117
+ (.cursor, docs/product, docs/engineering, sprints, handoffs,
118
+ decisions). Your own source code is never touched.
119
+ --target <path> Repo to clean (default: current directory).
120
+ --yes Skip the confirmation prompt.
121
+
122
+ Info:
123
+ --help, -h Show this help and exit.
124
+ --version, -v Print the installed version and exit.
125
+
126
+ Examples:
127
+ its-magic --target . --mode missing Safe first-time setup
128
+ its-magic --target . --mode overwrite --backup Update all files, keep backup
129
+ its-magic --clean-repo --target . --yes Remove workflow artifacts silently
45
130
  `);
46
131
  }
47
132
 
@@ -50,6 +135,10 @@ if (args.help) {
50
135
  printHelp();
51
136
  process.exit(0);
52
137
  }
138
+ if (args.version) {
139
+ console.log(`its-magic v${packageJson.version}`);
140
+ process.exit(0);
141
+ }
53
142
 
54
143
  const root = path.resolve(__dirname, "..");
55
144
  const isWin = process.platform === "win32";
@@ -68,6 +157,8 @@ if (isWin) {
68
157
  ];
69
158
  if (args.backup) psArgs.push("-Backup");
70
159
  if (args.create) psArgs.push("-Create");
160
+ if (args.cleanRepo) psArgs.push("-CleanRepo");
161
+ if (args.yes) psArgs.push("-Yes");
71
162
  const res = spawnSync("powershell", psArgs, { stdio: "inherit" });
72
163
  process.exit(res.status || 0);
73
164
  } else {
@@ -81,6 +172,8 @@ if (isWin) {
81
172
  ];
82
173
  if (args.backup) shArgs.push("--backup");
83
174
  if (args.create) shArgs.push("--create");
175
+ if (args.cleanRepo) shArgs.push("--clean-repo");
176
+ if (args.yes) shArgs.push("--yes");
84
177
  const res = spawnSync("sh", shArgs, { stdio: "inherit" });
85
178
  process.exit(res.status || 0);
86
179
  }
package/installer.ps1 CHANGED
@@ -3,7 +3,11 @@ Param(
3
3
  [ValidateSet("missing","overwrite","interactive")]
4
4
  [string]$Mode,
5
5
  [switch]$Backup,
6
- [switch]$Create
6
+ [switch]$Create,
7
+ [switch]$CleanRepo,
8
+ [switch]$Yes,
9
+ [switch]$Help,
10
+ [switch]$Version
7
11
  )
8
12
 
9
13
  $ErrorActionPreference = "Stop"
@@ -69,7 +73,128 @@ function Prompt-YesNo($Label, $Default = $false) {
69
73
  return @("y","yes") -contains $value
70
74
  }
71
75
 
76
+ function Get-AppVersion($SourceRoot) {
77
+ try {
78
+ $pkgPath = Join-Path $SourceRoot "package.json"
79
+ if (Test-Path $pkgPath -PathType Leaf) {
80
+ $pkg = Get-Content -Path $pkgPath -Raw | ConvertFrom-Json
81
+ if ($pkg.version) { return [string]$pkg.version }
82
+ }
83
+ } catch {}
84
+ return "unknown"
85
+ }
86
+
87
+ function Show-ItsMagicBanner([switch]$IncludeInstallMessage) {
88
+ $prev = [Console]::OutputEncoding
89
+ [Console]::OutputEncoding = [System.Text.Encoding]::UTF8
90
+ $b64 = 'ICDilojilojilZfilojilojilojilojilojilojilojilojilZfilojilojilojilojilojilojilojilZcgICAgICDilojilojilojilZcgICDilojilojilojilZcg4paI4paI4paI4paI4paI4pWXICDilojilojilojilojilojilojilZcg4paI4paI4pWXIOKWiOKWiOKWiOKWiOKWiOKWiOKVlwogIOKWiOKWiOKVkeKVmuKVkOKVkOKWiOKWiOKVlOKVkOKVkOKVneKWiOKWiOKVlOKVkOKVkOKVkOKVkOKVnSAgICAgIOKWiOKWiOKWiOKWiOKVlyDilojilojilojilojilZHilojilojilZTilZDilZDilojilojilZfilojilojilZTilZDilZDilZDilZDilZ0g4paI4paI4pWR4paI4paI4pWU4pWQ4pWQ4pWQ4pWQ4pWdCiAg4paI4paI4pWRICAg4paI4paI4pWRICAg4paI4paI4paI4paI4paI4paI4paI4pWX4paI4paI4paI4paI4paI4pWX4paI4paI4pWU4paI4paI4paI4paI4pWU4paI4paI4pWR4paI4paI4paI4paI4paI4paI4paI4pWR4paI4paI4pWRICDilojilojilojilZfilojilojilZHilojilojilZEgICAgIAogIOKWiOKWiOKVkSAgIOKWiOKWiOKVkSAgIOKVmuKVkOKVkOKVkOKVkOKWiOKWiOKVkeKVmuKVkOKVkOKVkOKVkOKVneKWiOKWiOKVkeKVmuKWiOKWiOKVlOKVneKWiOKWiOKVkeKWiOKWiOKVlOKVkOKVkOKWiOKWiOKVkeKWiOKWiOKVkSAgIOKWiOKWiOKVkeKWiOKWiOKVkeKWiOKWiOKVkSAgICAgCiAg4paI4paI4pWRICAg4paI4paI4pWRICAg4paI4paI4paI4paI4paI4paI4paI4pWRICAgICAg4paI4paI4pWRIOKVmuKVkOKVnSDilojilojilZHilojilojilZEgIOKWiOKWiOKVkeKVmuKWiOKWiOKWiOKWiOKWiOKWiOKVlOKVneKWiOKWiOKVkeKVmuKWiOKWiOKWiOKWiOKWiOKWiOKVlwogIOKVmuKVkOKVnSAgIOKVmuKVkOKVnSAgIOKVmuKVkOKVkOKVkOKVkOKVkOKVkOKVnSAgICAgIOKVmuKVkOKVnSAgICAg4pWa4pWQ4pWd4pWa4pWQ4pWdICDilZrilZDilZ0g4pWa4pWQ4pWQ4pWQ4pWQ4pWQ4pWdIOKVmuKVkOKVnSDilZrilZDilZDilZDilZDilZDilZ0='
91
+ $art = [System.Text.Encoding]::UTF8.GetString([Convert]::FromBase64String($b64))
92
+ $lines = $art -split "`n"
93
+ $colors = @('Magenta','Magenta','Magenta','Cyan','Cyan','Cyan')
94
+ Write-Host ""
95
+ for ($i = 0; $i -lt $lines.Count; $i++) {
96
+ Write-Host $lines[$i] -ForegroundColor $colors[$i]
97
+ }
98
+ Write-Host ""
99
+ Write-Host " AI dev team" -ForegroundColor Yellow
100
+ if ($IncludeInstallMessage) {
101
+ Write-Host " Installation complete!" -ForegroundColor Green
102
+ }
103
+ Write-Host ""
104
+ [Console]::OutputEncoding = $prev
105
+ }
106
+
107
+ function Show-ItsMagicHelp($VersionString, $RepoUrl) {
108
+ Show-ItsMagicBanner
109
+ Write-Host "its-magic v$VersionString"
110
+ Write-Host "Repository: $RepoUrl"
111
+ Write-Host ""
112
+ Write-Host "Install AI dev team workflow files into any Cursor repository."
113
+ Write-Host ""
114
+ Write-Host "Usage:"
115
+ Write-Host " its-magic --target <path> [--mode <mode>] [--backup] [--create]"
116
+ Write-Host " its-magic --clean-repo [--target <path>] [--yes]"
117
+ Write-Host " its-magic --help | --version"
118
+ Write-Host ""
119
+ Write-Host "Install options:"
120
+ Write-Host " --target <path> Path to the repository where workflow files are installed."
121
+ Write-Host " If omitted you will be prompted interactively."
122
+ Write-Host " --mode <mode> How to handle files that already exist in the target:"
123
+ Write-Host " missing Only copy files that do not exist yet (default)."
124
+ Write-Host " Safe for repos that already have some workflow files."
125
+ Write-Host " overwrite Replace every file, even if it already exists."
126
+ Write-Host " Combine with --backup to keep a snapshot first."
127
+ Write-Host " interactive Ask per file whether to overwrite or skip."
128
+ Write-Host " --backup Before overwriting, save existing files to backups/<timestamp>/."
129
+ Write-Host " Ignored when mode is 'missing' (nothing gets replaced)."
130
+ Write-Host " --create Create the target directory if it does not exist."
131
+ Write-Host ""
132
+ Write-Host "Clean options:"
133
+ Write-Host " --clean-repo Remove all its-magic workflow artifacts from the target repo"
134
+ Write-Host " (.cursor, docs/product, docs/engineering, sprints, handoffs,"
135
+ Write-Host " decisions). Your own source code is never touched."
136
+ Write-Host " --target <path> Repo to clean (default: current directory)."
137
+ Write-Host " --yes Skip the confirmation prompt."
138
+ Write-Host ""
139
+ Write-Host "Info:"
140
+ Write-Host " --help Show this help and exit."
141
+ Write-Host " --version Print the installed version and exit."
142
+ Write-Host ""
143
+ Write-Host "Examples:"
144
+ Write-Host " its-magic --target . --mode missing Safe first-time setup"
145
+ Write-Host " its-magic --target . --mode overwrite --backup Update all files, keep backup"
146
+ Write-Host " its-magic --clean-repo --target . --yes Remove workflow artifacts silently"
147
+ Write-Host ""
148
+ }
149
+
72
150
  $sourceRoot = Normalize-PathSafe (Split-Path -Parent $MyInvocation.MyCommand.Path)
151
+ $repoUrl = "https://github.com/fl0wm0ti0n/its-magic"
152
+ $appVersion = Get-AppVersion $sourceRoot
153
+ $noArgs = $PSBoundParameters.Count -eq 0
154
+
155
+ if ($Version) {
156
+ Write-Host "its-magic v$appVersion"
157
+ exit 0
158
+ }
159
+
160
+ if ($Help -or $noArgs) {
161
+ Show-ItsMagicHelp -VersionString $appVersion -RepoUrl $repoUrl
162
+ exit 0
163
+ }
164
+
165
+ if ($CleanRepo) {
166
+ if (-not $Target) { $Target = "." }
167
+ $targetRoot = Normalize-PathSafe $Target
168
+ if (-not (Test-Path $targetRoot -PathType Container)) {
169
+ Write-Host "Target directory does not exist."
170
+ exit 1
171
+ }
172
+ if (-not $Yes) {
173
+ $proceed = Prompt-YesNo "Clean its-magic workflow artifacts in $targetRoot?" $false
174
+ if (-not $proceed) {
175
+ Write-Host "Aborted."
176
+ exit 1
177
+ }
178
+ }
179
+ $cleanPaths = @(
180
+ ".cursor",
181
+ "docs\product",
182
+ "docs\engineering",
183
+ "sprints",
184
+ "handoffs",
185
+ "decisions"
186
+ )
187
+ foreach ($rel in $cleanPaths) {
188
+ $fullPath = Join-Path $targetRoot $rel
189
+ if (Test-Path $fullPath) {
190
+ Remove-Item -Path $fullPath -Recurse -Force
191
+ Write-Host "Removed: $rel"
192
+ }
193
+ }
194
+ Write-Host "Clean completed."
195
+ exit 0
196
+ }
197
+
73
198
  if (-not $Target) {
74
199
  $Target = Read-Host "Target repository path"
75
200
  }
@@ -165,24 +290,9 @@ foreach ($rel in $files) {
165
290
  }
166
291
  }
167
292
 
168
- function Show-ItsMagicBanner {
169
- $prev = [Console]::OutputEncoding
170
- [Console]::OutputEncoding = [System.Text.Encoding]::UTF8
171
- $b64 = 'ICDilojilojilZfilojilojilojilojilojilojilojilojilZfilojilojilojilojilojilojilojilZcgICAgICDilojilojilojilZcgICDilojilojilojilZcg4paI4paI4paI4paI4paI4pWXICDilojilojilojilojilojilojilZcg4paI4paI4pWXIOKWiOKWiOKWiOKWiOKWiOKWiOKVlwogIOKWiOKWiOKVkeKVmuKVkOKVkOKWiOKWiOKVlOKVkOKVkOKVneKWiOKWiOKVlOKVkOKVkOKVkOKVkOKVnSAgICAgIOKWiOKWiOKWiOKWiOKVlyDilojilojilojilojilZHilojilojilZTilZDilZDilojilojilZfilojilojilZTilZDilZDilZDilZDilZ0g4paI4paI4pWR4paI4paI4pWU4pWQ4pWQ4pWQ4pWQ4pWdCiAg4paI4paI4pWRICAg4paI4paI4pWRICAg4paI4paI4paI4paI4paI4paI4paI4pWX4paI4paI4paI4paI4paI4pWX4paI4paI4pWU4paI4paI4paI4paI4pWU4paI4paI4pWR4paI4paI4paI4paI4paI4paI4paI4pWR4paI4paI4pWRICDilojilojilojilZfilojilojilZHilojilojilZEgICAgIAogIOKWiOKWiOKVkSAgIOKWiOKWiOKVkSAgIOKVmuKVkOKVkOKVkOKVkOKWiOKWiOKVkeKVmuKVkOKVkOKVkOKVkOKVneKWiOKWiOKVkeKVmuKWiOKWiOKVlOKVneKWiOKWiOKVkeKWiOKWiOKVlOKVkOKVkOKWiOKWiOKVkeKWiOKWiOKVkSAgIOKWiOKWiOKVkeKWiOKWiOKVkeKWiOKWiOKVkSAgICAgCiAg4paI4paI4pWRICAg4paI4paI4pWRICAg4paI4paI4paI4paI4paI4paI4paI4pWRICAgICAg4paI4paI4pWRIOKVmuKVkOKVnSDilojilojilZHilojilojilZEgIOKWiOKWiOKVkeKVmuKWiOKWiOKWiOKWiOKWiOKWiOKVlOKVneKWiOKWiOKVkeKVmuKWiOKWiOKWiOKWiOKWiOKWiOKVlwogIOKVmuKVkOKVnSAgIOKVmuKVkOKVnSAgIOKVmuKVkOKVkOKVkOKVkOKVkOKVkOKVnSAgICAgIOKVmuKVkOKVnSAgICAg4pWa4pWQ4pWd4pWa4pWQ4pWdICDilZrilZDilZ0g4pWa4pWQ4pWQ4pWQ4pWQ4pWQ4pWdIOKVmuKVkOKVnSDilZrilZDilZDilZDilZDilZDilZ0='
172
- $art = [System.Text.Encoding]::UTF8.GetString([Convert]::FromBase64String($b64))
173
- $lines = $art -split "`n"
174
- $colors = @('Magenta','Magenta','Magenta','Cyan','Cyan','Cyan')
175
- Write-Host ""
176
- for ($i = 0; $i -lt $lines.Count; $i++) {
177
- Write-Host $lines[$i] -ForegroundColor $colors[$i]
178
- }
179
- Write-Host ""
180
- Write-Host " AI dev team" -ForegroundColor Yellow
181
- Write-Host " Installation complete!" -ForegroundColor Green
182
- Write-Host ""
183
- [Console]::OutputEncoding = $prev
184
- }
185
-
186
- Show-ItsMagicBanner
293
+ Show-ItsMagicBanner -IncludeInstallMessage
294
+ Write-Host "its-magic v$appVersion"
295
+ Write-Host "Repository: $repoUrl"
296
+ Write-Host ""
187
297
  exit 0
188
298
 
package/installer.py CHANGED
@@ -1,14 +1,26 @@
1
1
  import argparse
2
+ import json
2
3
  import os
3
4
  import shutil
4
5
  import sys
5
6
  from datetime import datetime
6
7
 
8
+ REPO_URL = "https://github.com/fl0wm0ti0n/its-magic"
9
+
7
10
 
8
11
  def normalize(path):
9
12
  return os.path.normpath(os.path.abspath(path))
10
13
 
11
14
 
15
+ def read_version(source_root):
16
+ package_path = os.path.join(source_root, "package.json")
17
+ try:
18
+ with open(package_path, "r", encoding="utf-8") as f:
19
+ return json.load(f).get("version", "unknown")
20
+ except Exception:
21
+ return "unknown"
22
+
23
+
12
24
  def list_source_files(source_root, include_paths):
13
25
  files = []
14
26
  for rel in include_paths:
@@ -63,29 +75,130 @@ def prompt_yes_no(label, default=False):
63
75
  return value in ("y", "yes")
64
76
 
65
77
 
78
+ def show_banner(include_install_message=False):
79
+ try:
80
+ sys.stdout.reconfigure(encoding="utf-8")
81
+ except Exception:
82
+ pass
83
+ m = "\033[1;35m"
84
+ c = "\033[1;36m"
85
+ y = "\033[1;33m"
86
+ g = "\033[1;32m"
87
+ r = "\033[0m"
88
+ print()
89
+ print(f"{m} ██╗████████╗███████╗ ███╗ ███╗ █████╗ ██████╗ ██╗ ██████╗{r}")
90
+ print(f"{m} ██║╚══██╔══╝██╔════╝ ████╗ ████║██╔══██╗██╔════╝ ██║██╔════╝{r}")
91
+ print(f"{m} ██║ ██║ ███████╗█████╗██╔████╔██║███████║██║ ███╗██║██║ {r}")
92
+ print(f"{c} ██║ ██║ ╚════██║╚════╝██║╚██╔╝██║██╔══██║██║ ██║██║██║ {r}")
93
+ print(f"{c} ██║ ██║ ███████║ ██║ ╚═╝ ██║██║ ██║╚██████╔╝██║╚██████╗{r}")
94
+ print(f"{c} ╚═╝ ╚═╝ ╚══════╝ ╚═╝ ╚═╝╚═╝ ╚═╝ ╚═════╝ ╚═╝ ╚═════╝{r}")
95
+ print()
96
+ print(f"{y} AI dev team{r}")
97
+ if include_install_message:
98
+ print(f"{g} Installation complete!{r}")
99
+ print()
100
+
101
+
102
+ def show_help(version):
103
+ show_banner(include_install_message=False)
104
+ print(f"its-magic v{version}")
105
+ print(f"Repository: {REPO_URL}")
106
+ print()
107
+ print("Install AI dev team workflow files into any Cursor repository.")
108
+ print()
109
+ print("Usage:")
110
+ print(" its-magic --target <path> [--mode <mode>] [--backup] [--create]")
111
+ print(" its-magic --clean-repo [--target <path>] [--yes]")
112
+ print(" its-magic --help | --version")
113
+ print()
114
+ print("Install options:")
115
+ print(" --target <path> Path to the repository where workflow files are installed.")
116
+ print(" If omitted you will be prompted interactively.")
117
+ print(" --mode <mode> How to handle files that already exist in the target:")
118
+ print(" missing Only copy files that do not exist yet (default).")
119
+ print(" Safe for repos that already have some workflow files.")
120
+ print(" overwrite Replace every file, even if it already exists.")
121
+ print(" Combine with --backup to keep a snapshot first.")
122
+ print(" interactive Ask per file whether to overwrite or skip.")
123
+ print(" --backup Before overwriting, save existing files to backups/<timestamp>/.")
124
+ print(" Ignored when mode is 'missing' (nothing gets replaced).")
125
+ print(" --create Create the target directory if it does not exist.")
126
+ print()
127
+ print("Clean options:")
128
+ print(" --clean-repo Remove all its-magic workflow artifacts from the target repo")
129
+ print(" (.cursor, docs/product, docs/engineering, sprints, handoffs,")
130
+ print(" decisions). Your own source code is never touched.")
131
+ print(" --target <path> Repo to clean (default: current directory).")
132
+ print(" --yes Skip the confirmation prompt.")
133
+ print()
134
+ print("Info:")
135
+ print(" --help, -h Show this help and exit.")
136
+ print(" --version, -v Print the installed version and exit.")
137
+ print()
138
+ print("Examples:")
139
+ print(" its-magic --target . --mode missing Safe first-time setup")
140
+ print(" its-magic --target . --mode overwrite --backup Update all files, keep backup")
141
+ print(" its-magic --clean-repo --target . --yes Remove workflow artifacts silently")
142
+ print()
143
+
144
+
145
+ def clean_repo(target_root):
146
+ clean_paths = [
147
+ ".cursor",
148
+ os.path.join("docs", "product"),
149
+ os.path.join("docs", "engineering"),
150
+ "sprints",
151
+ "handoffs",
152
+ "decisions",
153
+ ]
154
+ for rel in clean_paths:
155
+ full = os.path.join(target_root, rel)
156
+ if os.path.exists(full):
157
+ shutil.rmtree(full)
158
+ print(f"Removed: {rel}")
159
+ print("Clean completed.")
160
+
161
+
66
162
  def main():
67
- parser = argparse.ArgumentParser(description="Install its-magic into a repo")
68
- parser.add_argument("--target", help="Target repository path")
69
- parser.add_argument(
70
- "--mode",
71
- choices=["missing", "overwrite", "interactive"],
72
- help="Install mode",
73
- )
74
- parser.add_argument(
75
- "--backup",
76
- action="store_true",
77
- help="Backup files before overwriting",
78
- )
79
- parser.add_argument(
80
- "--create",
81
- action="store_true",
82
- help="Create target directory if missing",
163
+ source_root = normalize(os.path.dirname(__file__))
164
+ version = read_version(source_root)
165
+
166
+ parser = argparse.ArgumentParser(
167
+ description="Install its-magic into a repo",
168
+ add_help=False,
83
169
  )
170
+ parser.add_argument("--target", help="Target repository path")
171
+ parser.add_argument("--mode", choices=["missing", "overwrite", "interactive"], help="Install mode")
172
+ parser.add_argument("--backup", action="store_true", help="Backup files before overwriting")
173
+ parser.add_argument("--create", action="store_true", help="Create target directory if missing")
174
+ parser.add_argument("--clean-repo", action="store_true", help="Remove installed workflow artifacts")
175
+ parser.add_argument("--yes", action="store_true", help="Skip clean confirmation prompt")
176
+ parser.add_argument("--help", "-h", action="store_true", help="Show help")
177
+ parser.add_argument("--version", "-v", action="store_true", help="Show version")
84
178
  args = parser.parse_args()
85
179
 
86
- source_root = normalize(os.path.dirname(__file__))
180
+ if len(sys.argv) == 1 or args.help:
181
+ show_help(version)
182
+ return 0
183
+
184
+ if args.version:
185
+ print(f"its-magic v{version}")
186
+ return 0
187
+
87
188
  target_root = normalize(args.target) if args.target else None
88
189
 
190
+ if args.clean_repo:
191
+ if not target_root:
192
+ target_root = normalize(".")
193
+ if not os.path.isdir(target_root):
194
+ print("Target directory does not exist.")
195
+ return 1
196
+ if not args.yes and not prompt_yes_no(f"Clean its-magic workflow artifacts in {target_root}?", default=False):
197
+ print("Aborted.")
198
+ return 1
199
+ clean_repo(target_root)
200
+ return 0
201
+
89
202
  if not target_root:
90
203
  target_root = normalize(input("Target repository path: ").strip())
91
204
 
@@ -164,30 +277,12 @@ def main():
164
277
  print(f"Backed up: {rel} -> {backup_root}")
165
278
  ensure_parent(dst)
166
279
  shutil.copy2(src, dst)
167
- else:
168
- continue
169
-
170
- show_banner()
171
- return 0
172
-
173
280
 
174
- def show_banner():
175
- M = "\033[1;35m"
176
- C = "\033[1;36m"
177
- Y = "\033[1;33m"
178
- G = "\033[1;32m"
179
- R = "\033[0m"
180
- print()
181
- print(f"{M} ██╗████████╗███████╗ ███╗ ███╗ █████╗ ██████╗ ██╗ ██████╗{R}")
182
- print(f"{M} ██║╚══██╔══╝██╔════╝ ████╗ ████║██╔══██╗██╔════╝ ██║██╔════╝{R}")
183
- print(f"{M} ██║ ██║ ███████╗█████╗██╔████╔██║███████║██║ ███╗██║██║ {R}")
184
- print(f"{C} ██║ ██║ ╚════██║╚════╝██║╚██╔╝██║██╔══██║██║ ██║██║██║ {R}")
185
- print(f"{C} ██║ ██║ ███████║ ██║ ╚═╝ ██║██║ ██║╚██████╔╝██║╚██████╗{R}")
186
- print(f"{C} ╚═╝ ╚═╝ ╚══════╝ ╚═╝ ╚═╝╚═╝ ╚═╝ ╚═════╝ ╚═╝ ╚═════╝{R}")
187
- print()
188
- print(f"{Y} AI dev team{R}")
189
- print(f"{G} Installation complete!{R}")
281
+ show_banner(include_install_message=True)
282
+ print(f"its-magic v{version}")
283
+ print(f"Repository: {REPO_URL}")
190
284
  print()
285
+ return 0
191
286
 
192
287
 
193
288
  if __name__ == "__main__":
package/installer.sh CHANGED
@@ -1,6 +1,59 @@
1
1
  #!/usr/bin/env sh
2
2
  set -e
3
3
 
4
+ SOURCE_ROOT=$(cd "$(dirname "$0")" && pwd)
5
+ REPO_URL="https://github.com/fl0wm0ti0n/its-magic"
6
+ APP_VERSION=$(sed -n 's/.*"version"[[:space:]]*:[[:space:]]*"\([^"]*\)".*/\1/p' "$SOURCE_ROOT/package.json" | head -n 1)
7
+ [ -z "$APP_VERSION" ] && APP_VERSION="unknown"
8
+
9
+ show_banner() {
10
+ printf "\n"
11
+ printf "\033[1;35m ██╗████████╗███████╗ ███╗ ███╗ █████╗ ██████╗ ██╗ ██████╗\033[0m\n"
12
+ printf "\033[1;35m ██║╚══██╔══╝██╔════╝ ████╗ ████║██╔══██╗██╔════╝ ██║██╔════╝\033[0m\n"
13
+ printf "\033[1;35m ██║ ██║ ███████╗█████╗██╔████╔██║███████║██║ ███╗██║██║ \033[0m\n"
14
+ printf "\033[1;36m ██║ ██║ ╚════██║╚════╝██║╚██╔╝██║██╔══██║██║ ██║██║██║ \033[0m\n"
15
+ printf "\033[1;36m ██║ ██║ ███████║ ██║ ╚═╝ ██║██║ ██║╚██████╔╝██║╚██████╗\033[0m\n"
16
+ printf "\033[1;36m ╚═╝ ╚═╝ ╚══════╝ ╚═╝ ╚═╝╚═╝ ╚═╝ ╚═════╝ ╚═╝ ╚═════╝\033[0m\n"
17
+ printf "\n"
18
+ printf "\033[1;33m AI dev team\033[0m\n"
19
+ printf "\n"
20
+ }
21
+
22
+ show_help() {
23
+ show_banner
24
+ printf "its-magic v%s\n" "$APP_VERSION"
25
+ printf "Repository: %s\n\n" "$REPO_URL"
26
+ printf "Install AI dev team workflow files into any Cursor repository.\n\n"
27
+ printf "Usage:\n"
28
+ printf " its-magic --target <path> [--mode <mode>] [--backup] [--create]\n"
29
+ printf " its-magic --clean-repo [--target <path>] [--yes]\n"
30
+ printf " its-magic --help | --version\n\n"
31
+ printf "Install options:\n"
32
+ printf " --target <path> Path to the repository where workflow files are installed.\n"
33
+ printf " If omitted you will be prompted interactively.\n"
34
+ printf " --mode <mode> How to handle files that already exist in the target:\n"
35
+ printf " missing Only copy files that do not exist yet (default).\n"
36
+ printf " Safe for repos that already have some workflow files.\n"
37
+ printf " overwrite Replace every file, even if it already exists.\n"
38
+ printf " Combine with --backup to keep a snapshot first.\n"
39
+ printf " interactive Ask per file whether to overwrite or skip.\n"
40
+ printf " --backup Before overwriting, save existing files to backups/<timestamp>/.\n"
41
+ printf " Ignored when mode is 'missing' (nothing gets replaced).\n"
42
+ printf " --create Create the target directory if it does not exist.\n\n"
43
+ printf "Clean options:\n"
44
+ printf " --clean-repo Remove all its-magic workflow artifacts from the target repo\n"
45
+ printf " (.cursor, docs/product, docs/engineering, sprints, handoffs,\n"
46
+ printf " decisions). Your own source code is never touched.\n"
47
+ printf " --target <path> Repo to clean (default: current directory).\n"
48
+ printf " --yes Skip the confirmation prompt.\n\n"
49
+ printf "Info:\n"
50
+ printf " --help, -h Show this help and exit.\n"
51
+ printf " --version, -v Print the installed version and exit.\n\n"
52
+ printf "Examples:\n"
53
+ printf " its-magic --target . --mode missing Safe first-time setup\n"
54
+ printf " its-magic --target . --mode overwrite --backup Update all files, keep backup\n"
55
+ printf " its-magic --clean-repo --target . --yes Remove workflow artifacts silently\n\n"
56
+ }
4
57
 
5
58
  ensure_parent() {
6
59
  dir=$(dirname "$1")
@@ -68,6 +121,14 @@ TARGET=""
68
121
  MODE=""
69
122
  BACKUP="false"
70
123
  CREATE="false"
124
+ CLEAN_REPO="false"
125
+ ASSUME_YES="false"
126
+ SHOW_HELP="false"
127
+ SHOW_VERSION="false"
128
+
129
+ if [ $# -eq 0 ]; then
130
+ SHOW_HELP="true"
131
+ fi
71
132
 
72
133
  while [ $# -gt 0 ]; do
73
134
  case "$1" in
@@ -75,11 +136,57 @@ while [ $# -gt 0 ]; do
75
136
  --mode) MODE="$2"; shift 2 ;;
76
137
  --backup) BACKUP="true"; shift 1 ;;
77
138
  --create) CREATE="true"; shift 1 ;;
139
+ --clean-repo) CLEAN_REPO="true"; shift 1 ;;
140
+ --yes) ASSUME_YES="true"; shift 1 ;;
141
+ --help|-h) SHOW_HELP="true"; shift 1 ;;
142
+ --version|-v) SHOW_VERSION="true"; shift 1 ;;
78
143
  *) shift 1 ;;
79
144
  esac
80
145
  done
81
146
 
82
- SOURCE_ROOT=$(cd "$(dirname "$0")" && pwd)
147
+ if [ "$SHOW_VERSION" = "true" ]; then
148
+ printf "its-magic v%s\n" "$APP_VERSION"
149
+ exit 0
150
+ fi
151
+
152
+ if [ "$SHOW_HELP" = "true" ]; then
153
+ show_help
154
+ exit 0
155
+ fi
156
+
157
+ if [ "$CLEAN_REPO" = "true" ]; then
158
+ if [ -z "$TARGET" ]; then
159
+ TARGET="."
160
+ fi
161
+ if [ ! -d "$TARGET" ]; then
162
+ printf "%s\n" "Target directory does not exist."
163
+ exit 1
164
+ fi
165
+ TARGET_ROOT=$(cd "$TARGET" && pwd)
166
+ if [ "$ASSUME_YES" != "true" ]; then
167
+ if ! prompt_yes_no "Clean its-magic workflow artifacts in $TARGET_ROOT?" "false"; then
168
+ printf "%s\n" "Aborted."
169
+ exit 1
170
+ fi
171
+ fi
172
+ CLEAN_PATHS="
173
+ .cursor
174
+ docs/product
175
+ docs/engineering
176
+ sprints
177
+ handoffs
178
+ decisions
179
+ "
180
+ for rel in $CLEAN_PATHS; do
181
+ path="$TARGET_ROOT/$rel"
182
+ if [ -e "$path" ]; then
183
+ rm -rf "$path"
184
+ printf "%s\n" "Removed: $rel"
185
+ fi
186
+ done
187
+ printf "%s\n" "Clean completed."
188
+ exit 0
189
+ fi
83
190
 
84
191
  if [ -z "$TARGET" ]; then
85
192
  printf "%s" "Target repository path: "
@@ -180,20 +287,9 @@ for rel in $FILES; do
180
287
  fi
181
288
  done
182
289
 
183
- show_banner() {
184
- printf "\n"
185
- printf "\033[1;35m ██╗████████╗███████╗ ███╗ ███╗ █████╗ ██████╗ ██╗ ██████╗\033[0m\n"
186
- printf "\033[1;35m ██║╚══██╔══╝██╔════╝ ████╗ ████║██╔══██╗██╔════╝ ██║██╔════╝\033[0m\n"
187
- printf "\033[1;35m ██║ ██║ ███████╗█████╗██╔████╔██║███████║██║ ███╗██║██║ \033[0m\n"
188
- printf "\033[1;36m ██║ ██║ ╚════██║╚════╝██║╚██╔╝██║██╔══██║██║ ██║██║██║ \033[0m\n"
189
- printf "\033[1;36m ██║ ██║ ███████║ ██║ ╚═╝ ██║██║ ██║╚██████╔╝██║╚██████╗\033[0m\n"
190
- printf "\033[1;36m ╚═╝ ╚═╝ ╚══════╝ ╚═╝ ╚═╝╚═╝ ╚═╝ ╚═════╝ ╚═╝ ╚═════╝\033[0m\n"
191
- printf "\n"
192
- printf "\033[1;33m AI dev team\033[0m\n"
193
- printf "\033[1;32m Installation complete!\033[0m\n"
194
- printf "\n"
195
- }
196
-
197
290
  show_banner
291
+ printf "its-magic v%s\n" "$APP_VERSION"
292
+ printf "Repository: %s\n\n" "$REPO_URL"
293
+ printf "\033[1;32m Installation complete!\033[0m\n\n"
198
294
  exit 0
199
295
 
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "its-magic",
3
- "version": "0.1.2-13",
3
+ "version": "0.1.2-15",
4
4
  "description": "its-magic - AI dev team workflow for Cursor.",
5
5
  "license": "MIT",
6
6
  "bin": {