@theglitchking/persistent-planning 1.0.0 → 2.0.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.
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "persistent-planning",
3
- "version": "1.0.0",
3
+ "version": "2.0.0",
4
4
  "description": "Persistent markdown-based planning with task directories, progress tracking, and context engineering for multi-step Claude Code workflows",
5
5
  "author": {
6
6
  "name": "TheGlitchKing"
package/CHANGELOG.md CHANGED
@@ -2,6 +2,81 @@
2
2
 
3
3
  All notable changes to this project will be documented in this file.
4
4
 
5
+ ## [2.0.0] - 2026-04-18
6
+
7
+ ### ⚠️ Breaking changes
8
+
9
+ v2.0.0 removes the hand-rolled `persistent-planning install|uninstall`
10
+ flow in favor of standard Claude Code plugin distribution and npm install
11
+ paths. Plugin skill and command files are now delivered **automatically**
12
+ — no manual copy step.
13
+
14
+ **If you're an existing v1 user**, here's what to expect and how to
15
+ upgrade:
16
+
17
+ - `persistent-planning install --scope user` is gone. Install instead via
18
+ the plugin marketplace:
19
+
20
+ ```
21
+ /plugin marketplace add TheGlitchKing/persistent-planning
22
+ /plugin install persistent-planning@persistent-planning-marketplace
23
+ ```
24
+
25
+ Or, for a project-local install that's visible to teammates and CI:
26
+
27
+ ```
28
+ npm install --save-dev @theglitchking/persistent-planning
29
+ ```
30
+
31
+ - `persistent-planning uninstall` is gone. Use `/plugin uninstall` or
32
+ `npm uninstall @theglitchking/persistent-planning` depending on how you
33
+ installed it.
34
+
35
+ - **Old skill/command files in `~/.claude/` or `./.claude/`** placed by
36
+ v1's installer will keep working until you remove them — but the
37
+ marketplace plugin and the npm postinstall both place their own copies,
38
+ so to avoid duplication you should delete the manually-installed
39
+ copies once you've adopted v2:
40
+
41
+ ```
42
+ # If you installed with --scope user:
43
+ rm -rf ~/.claude/skills/persistent-planning
44
+ rm ~/.claude/commands/start-planning.md
45
+
46
+ # If you installed with --scope project:
47
+ rm -rf .claude/skills/persistent-planning
48
+ rm .claude/commands/start-planning.md
49
+ ```
50
+
51
+ - The old `install`/`uninstall` subcommands still exist as deprecation
52
+ shims — running them prints a migration pointer and exits cleanly
53
+ instead of failing.
54
+
55
+ ### Added
56
+ - Adopts `@theglitchking/claude-plugin-runtime` for postinstall skill
57
+ symlinking, SessionStart update nudge/auto-apply, and standardized
58
+ `update`/`policy`/`status`/`relink` CLI subcommands.
59
+ - Default `updatePolicy: "nudge"` — on session start, the plugin checks
60
+ npm for a newer version and prints a one-liner when one exists. Opt
61
+ into `auto` for background auto-update, or `off` to silence entirely.
62
+ - Four new slash commands: `/persistent-planning:update`,
63
+ `/persistent-planning:policy`, `/persistent-planning:status`,
64
+ `/persistent-planning:relink`.
65
+
66
+ ### Changed
67
+ - **Skill layout**: `skills/SKILL.md` moved to
68
+ `skills/persistent-planning/SKILL.md` so the runtime can symlink it
69
+ into consuming projects' `.claude/skills/persistent-planning/`.
70
+ - **Slash command location**: `.claude/commands/start-planning.md` moved
71
+ to `commands/start-planning.md` (top-level, matching the marketplace
72
+ plugin convention).
73
+ - Node >= 20 required (was >= 16).
74
+
75
+ ### Removed
76
+ - `install.sh`, `uninstall.sh`, and the `postinstall.js` banner script.
77
+ - The root-level `plugin.json` — manifest is now only at
78
+ `.claude-plugin/plugin.json`.
79
+
5
80
  ## [1.0.0] - 2026-02-12
6
81
 
7
82
  ### Added
package/LICENSE CHANGED
File without changes
package/README.md CHANGED
File without changes
@@ -1,241 +1,66 @@
1
1
  #!/usr/bin/env node
2
2
 
3
- const fs = require('fs');
4
- const path = require('path');
5
-
6
- const PLUGIN_ROOT = path.join(__dirname, '..');
7
-
8
- const colors = {
9
- reset: '\x1b[0m',
10
- green: '\x1b[32m',
11
- blue: '\x1b[34m',
12
- yellow: '\x1b[33m',
13
- red: '\x1b[31m',
14
- cyan: '\x1b[36m'
15
- };
16
-
17
- function showHelp() {
18
- console.log(`
19
- ${colors.blue}persistent-planning CLI${colors.reset}
20
-
21
- ${colors.green}Usage:${colors.reset}
22
- persistent-planning install [--scope user|project]
23
- persistent-planning uninstall [--scope user|project]
24
- persistent-planning status
25
- persistent-planning help
26
-
27
- ${colors.green}Commands:${colors.reset}
28
- install Install persistent-planning skill and /start-planning command
29
- uninstall Remove persistent-planning from Claude Code
30
- status Show installation status
31
- help Show this help message
32
-
33
- ${colors.green}Install Options:${colors.reset}
34
- --scope {user|project} Install scope (default: user)
35
- user - Install globally (~/.claude/)
36
- project - Install in current project (.claude/)
37
-
38
- ${colors.green}Examples:${colors.reset}
39
- persistent-planning install --scope user
40
- persistent-planning install --scope project
41
- persistent-planning uninstall --scope user
42
- persistent-planning status
43
-
44
- ${colors.green}After Installation:${colors.reset}
45
- Run this command in Claude Code:
46
- /start-planning "Your task name"
47
- `);
48
- }
49
-
50
- function copyRecursive(src, dest) {
51
- const stats = fs.statSync(src);
52
- if (stats.isDirectory()) {
53
- if (!fs.existsSync(dest)) {
54
- fs.mkdirSync(dest, { recursive: true });
55
- }
56
- fs.readdirSync(src).forEach(file => {
57
- copyRecursive(path.join(src, file), path.join(dest, file));
58
- });
59
- } else {
60
- fs.copyFileSync(src, dest);
3
+ import { program } from "commander";
4
+ import { registerUpdateCommands } from "@theglitchking/claude-plugin-runtime";
5
+ import { createRequire } from "node:module";
6
+ import { spawnSync } from "node:child_process";
7
+ import { existsSync } from "node:fs";
8
+ import { join, resolve } from "node:path";
9
+
10
+ const require_ = createRequire(import.meta.url);
11
+ const { version } = require_("../package.json");
12
+
13
+ const PKG = "@theglitchking/persistent-planning";
14
+
15
+ function runRelink(cwd) {
16
+ const linker = join(cwd, "node_modules", "@theglitchking", "persistent-planning", "scripts", "link-skills.js");
17
+ const script = existsSync(linker) ? linker : resolve(process.cwd(), "scripts", "link-skills.js");
18
+ if (!existsSync(script)) {
19
+ console.error("link-skills.js not found — is the package installed?");
20
+ return;
61
21
  }
22
+ spawnSync(process.execPath, [script], {
23
+ cwd,
24
+ env: { ...process.env, INIT_CWD: cwd },
25
+ stdio: "inherit",
26
+ });
62
27
  }
63
28
 
64
- function getInstallDir(scope) {
65
- return scope === 'user'
66
- ? path.join(process.env.HOME || process.env.USERPROFILE, '.claude')
67
- : '.claude';
29
+ program
30
+ .name("persistent-planning")
31
+ .description("Persistent markdown-based planning for Claude Code.")
32
+ .version(version);
33
+
34
+ registerUpdateCommands(program, {
35
+ packageName: PKG,
36
+ pluginName: "persistent-planning",
37
+ configFile: "persistent-planning.json",
38
+ onAfterUpdate: (cwd) => runRelink(cwd),
39
+ });
40
+
41
+ // Deprecated subcommands from v1. Accept them so existing automation
42
+ // doesn't silently break — print a migration pointer and exit 0.
43
+ function deprecationNotice(name) {
44
+ console.error(`\n⚠️ 'persistent-planning ${name}' was removed in v2.0.0.\n`);
45
+ console.error(`The plugin now installs via the Claude Code plugin marketplace:`);
46
+ console.error(` /plugin marketplace add TheGlitchKing/persistent-planning`);
47
+ console.error(` /plugin install persistent-planning@persistent-planning-marketplace\n`);
48
+ console.error(`Or, at the project level, via npm:`);
49
+ console.error(` npm install --save-dev @theglitchking/persistent-planning\n`);
50
+ console.error(`See the v2.0.0 CHANGELOG for migration details:`);
51
+ console.error(` https://github.com/TheGlitchKing/persistent-planning/blob/main/CHANGELOG.md\n`);
68
52
  }
69
53
 
70
- function checkInstallation(scope) {
71
- const installDir = getInstallDir(scope);
72
- const skillPath = path.join(installDir, 'skills', 'persistent-planning', 'SKILL.md');
73
- const commandPath = path.join(installDir, 'commands', 'start-planning.md');
74
- return {
75
- skill: fs.existsSync(skillPath),
76
- command: fs.existsSync(commandPath)
77
- };
78
- }
79
-
80
- function showStatus() {
81
- console.log(`\n${colors.blue}persistent-planning Installation Status${colors.reset}\n`);
82
-
83
- const userInstall = checkInstallation('user');
84
- const projectInstall = checkInstallation('project');
85
-
86
- console.log(`User Scope (~/.claude/):`);
87
- console.log(` Skill: ${userInstall.skill ? colors.green + 'Installed' : colors.yellow + 'Not installed'}${colors.reset}`);
88
- console.log(` Command: ${userInstall.command ? colors.green + 'Installed' : colors.yellow + 'Not installed'}${colors.reset}`);
89
-
90
- console.log(`\nProject Scope (./.claude/):`);
91
- console.log(` Skill: ${projectInstall.skill ? colors.green + 'Installed' : colors.yellow + 'Not installed'}${colors.reset}`);
92
- console.log(` Command: ${projectInstall.command ? colors.green + 'Installed' : colors.yellow + 'Not installed'}${colors.reset}`);
93
-
94
- if (!userInstall.skill && !projectInstall.skill) {
95
- console.log(`\n${colors.yellow}Run: persistent-planning install${colors.reset}`);
96
- }
97
- console.log();
98
- }
99
-
100
- function runInstall(args) {
101
- const scope = args.includes('--scope') ? args[args.indexOf('--scope') + 1] : 'user';
102
- const installDir = getInstallDir(scope);
103
-
104
- console.log(`${colors.blue}Installing persistent-planning...${colors.reset}`);
105
- console.log(` Scope: ${scope} (${installDir})\n`);
106
-
107
- try {
108
- // Create directories
109
- const skillDir = path.join(installDir, 'skills', 'persistent-planning');
110
- const scriptsDir = path.join(skillDir, 'scripts');
111
- const docsDir = path.join(skillDir, 'docs');
112
- const commandsDir = path.join(installDir, 'commands');
54
+ program
55
+ .command("install")
56
+ .description("[removed in v2.0.0] use the Claude Code plugin marketplace or npm")
57
+ .option("--scope <scope>")
58
+ .action(() => { deprecationNotice("install"); process.exit(0); });
113
59
 
114
- fs.mkdirSync(scriptsDir, { recursive: true });
115
- fs.mkdirSync(docsDir, { recursive: true });
116
- fs.mkdirSync(commandsDir, { recursive: true });
60
+ program
61
+ .command("uninstall")
62
+ .description("[removed in v2.0.0] use /plugin uninstall or npm uninstall")
63
+ .option("--scope <scope>")
64
+ .action(() => { deprecationNotice("uninstall"); process.exit(0); });
117
65
 
118
- // Copy skill
119
- fs.copyFileSync(
120
- path.join(PLUGIN_ROOT, 'skills', 'SKILL.md'),
121
- path.join(skillDir, 'SKILL.md')
122
- );
123
- console.log(`${colors.green}+${colors.reset} Installed SKILL.md`);
124
-
125
- // Copy init script
126
- const initScript = path.join(scriptsDir, 'init-planning.sh');
127
- fs.copyFileSync(
128
- path.join(PLUGIN_ROOT, 'scripts', 'init-planning.sh'),
129
- initScript
130
- );
131
- fs.chmodSync(initScript, 0o755);
132
- console.log(`${colors.green}+${colors.reset} Installed init-planning.sh`);
133
-
134
- // Copy docs
135
- fs.copyFileSync(
136
- path.join(PLUGIN_ROOT, 'docs', 'reference.md'),
137
- path.join(docsDir, 'reference.md')
138
- );
139
- fs.copyFileSync(
140
- path.join(PLUGIN_ROOT, 'docs', 'examples.md'),
141
- path.join(docsDir, 'examples.md')
142
- );
143
- console.log(`${colors.green}+${colors.reset} Installed reference docs`);
144
-
145
- // Copy command
146
- fs.copyFileSync(
147
- path.join(PLUGIN_ROOT, '.claude', 'commands', 'start-planning.md'),
148
- path.join(commandsDir, 'start-planning.md')
149
- );
150
- console.log(`${colors.green}+${colors.reset} Installed /start-planning command`);
151
-
152
- // Update .gitignore if project scope
153
- if (scope === 'project') {
154
- const gitignorePath = '.gitignore';
155
- if (fs.existsSync(gitignorePath)) {
156
- const content = fs.readFileSync(gitignorePath, 'utf8');
157
- if (!content.includes('.claude/')) {
158
- fs.appendFileSync(gitignorePath, '\n.claude/\n');
159
- console.log(`${colors.green}+${colors.reset} Updated .gitignore`);
160
- }
161
- } else {
162
- fs.writeFileSync(gitignorePath, '.claude/\n');
163
- console.log(`${colors.green}+${colors.reset} Created .gitignore`);
164
- }
165
- }
166
-
167
- console.log(`\n${colors.green}Installation Complete!${colors.reset}\n`);
168
- console.log(`${colors.yellow}Usage:${colors.reset}`);
169
- console.log(` In Claude Code, run: ${colors.cyan}/start-planning "Your task name"${colors.reset}\n`);
170
- console.log(`${colors.yellow}Uninstall:${colors.reset}`);
171
- console.log(` ${colors.cyan}persistent-planning uninstall --scope ${scope}${colors.reset}\n`);
172
-
173
- } catch (error) {
174
- console.error(`${colors.red}Installation failed: ${error.message}${colors.reset}`);
175
- process.exit(1);
176
- }
177
- }
178
-
179
- function runUninstall(args) {
180
- const scope = args.includes('--scope') ? args[args.indexOf('--scope') + 1] : 'user';
181
- const installDir = getInstallDir(scope);
182
-
183
- console.log(`${colors.blue}Uninstalling persistent-planning...${colors.reset}`);
184
- console.log(` Scope: ${scope} (${installDir})\n`);
185
-
186
- let removed = 0;
187
-
188
- try {
189
- const skillDir = path.join(installDir, 'skills', 'persistent-planning');
190
- if (fs.existsSync(skillDir)) {
191
- fs.rmSync(skillDir, { recursive: true, force: true });
192
- console.log(`${colors.green}+${colors.reset} Removed skill`);
193
- removed++;
194
- }
195
-
196
- const commandFile = path.join(installDir, 'commands', 'start-planning.md');
197
- if (fs.existsSync(commandFile)) {
198
- fs.unlinkSync(commandFile);
199
- console.log(`${colors.green}+${colors.reset} Removed /start-planning command`);
200
- removed++;
201
- }
202
-
203
- if (removed === 0) {
204
- console.log(`${colors.yellow}Nothing to remove. persistent-planning not found in ${installDir}/${colors.reset}`);
205
- } else {
206
- console.log(`\n${colors.green}Uninstall complete.${colors.reset}`);
207
- console.log(`\nNote: .planning/ directories in your projects are not removed.`);
208
- console.log(`To clean those up: rm -rf .planning/\n`);
209
- }
210
-
211
- } catch (error) {
212
- console.error(`${colors.red}Uninstallation failed: ${error.message}${colors.reset}`);
213
- process.exit(1);
214
- }
215
- }
216
-
217
- // Main
218
- const args = process.argv.slice(2);
219
- const command = args[0];
220
-
221
- switch (command) {
222
- case 'install':
223
- runInstall(args.slice(1));
224
- break;
225
- case 'uninstall':
226
- runUninstall(args.slice(1));
227
- break;
228
- case 'status':
229
- showStatus();
230
- break;
231
- case 'help':
232
- case '--help':
233
- case '-h':
234
- case undefined:
235
- showHelp();
236
- break;
237
- default:
238
- console.error(`${colors.red}Unknown command: ${command}${colors.reset}`);
239
- console.log(`Run 'persistent-planning help' for usage information`);
240
- process.exit(1);
241
- }
66
+ program.parse();
@@ -0,0 +1,16 @@
1
+ ---
2
+ description: Get or set the persistent-planning update policy (auto | nudge | off)
3
+ allowed-tools: Bash(npx:*)
4
+ argument-hint: "[auto|nudge|off]"
5
+ ---
6
+
7
+ Arguments: $ARGUMENTS
8
+
9
+ - If `$ARGUMENTS` is empty, run `npx --no @theglitchking/persistent-planning policy` and report the current policy and config path.
10
+ - If `$ARGUMENTS` is one of `auto`, `nudge`, `off`, run `npx --no @theglitchking/persistent-planning policy $ARGUMENTS` and confirm the new setting to the user.
11
+ - If `$ARGUMENTS` is anything else, tell the user the valid values are `auto`, `nudge`, `off`.
12
+
13
+ Policies:
14
+ - `auto` — auto-run `npm update @theglitchking/persistent-planning` at session start when a newer version is available.
15
+ - `nudge` — print a one-liner when a newer version is available (default).
16
+ - `off` — do not check for updates.
@@ -0,0 +1,6 @@
1
+ ---
2
+ description: Re-run the skill linker — refresh symlinks from node_modules into .claude/skills/
3
+ allowed-tools: Bash(npx:*)
4
+ ---
5
+
6
+ Run `npx --no @theglitchking/persistent-planning relink` and report the result.
File without changes
@@ -0,0 +1,6 @@
1
+ ---
2
+ description: Show installed version, latest available version, current update policy, and hook registration state
3
+ allowed-tools: Bash(npx:*)
4
+ ---
5
+
6
+ Run `npx --no @theglitchking/persistent-planning status` and relay the output to the user verbatim.
@@ -0,0 +1,6 @@
1
+ ---
2
+ description: Update persistent-planning to the latest version (runs npm update + re-links skills)
3
+ allowed-tools: Bash(npx:*)
4
+ ---
5
+
6
+ Run `npx --no @theglitchking/persistent-planning update` and report the before/after versions to the user. If the project doesn't have a local install, fall back to `npx -y @theglitchking/persistent-planning update` and note that in your summary.
package/docs/examples.md CHANGED
File without changes
package/docs/reference.md CHANGED
File without changes
@@ -0,0 +1,15 @@
1
+ {
2
+ "description": "persistent-planning SessionStart hook — nudges/auto-updates per policy.",
3
+ "hooks": {
4
+ "SessionStart": [
5
+ {
6
+ "hooks": [
7
+ {
8
+ "type": "command",
9
+ "command": "node \"${CLAUDE_PLUGIN_ROOT}/hooks/session-start.js\""
10
+ }
11
+ ]
12
+ }
13
+ ]
14
+ }
15
+ }
@@ -0,0 +1,13 @@
1
+ #!/usr/bin/env node
2
+ // persistent-planning SessionStart hook.
3
+ // Delegates entirely to @theglitchking/claude-plugin-runtime — this plugin
4
+ // has no mcp.json wiring or project-side reconcile, so only the update
5
+ // check runs.
6
+
7
+ import { runSessionStart } from "@theglitchking/claude-plugin-runtime";
8
+
9
+ await runSessionStart({
10
+ packageName: "@theglitchking/persistent-planning",
11
+ pluginName: "persistent-planning",
12
+ configFile: "persistent-planning.json",
13
+ });
package/package.json CHANGED
@@ -1,43 +1,42 @@
1
1
  {
2
2
  "name": "@theglitchking/persistent-planning",
3
- "version": "1.0.0",
3
+ "version": "2.0.0",
4
4
  "description": "Persistent markdown-based planning with task directories, progress tracking, and context engineering for multi-step Claude Code workflows",
5
- "type": "commonjs",
5
+ "type": "module",
6
6
  "bin": {
7
- "persistent-planning": "./bin/persistent-planning.js"
7
+ "persistent-planning": "bin/persistent-planning.js"
8
8
  },
9
9
  "scripts": {
10
- "postinstall": "node postinstall.js"
10
+ "postinstall": "node scripts/link-skills.js"
11
11
  },
12
12
  "files": [
13
13
  "bin/",
14
+ "commands/",
15
+ "hooks/",
16
+ "scripts/link-skills.js",
14
17
  "skills/",
15
- "scripts/",
16
18
  "docs/",
17
- ".claude/",
18
19
  ".claude-plugin/",
19
- "postinstall.js",
20
20
  "README.md",
21
21
  "LICENSE",
22
22
  "CHANGELOG.md"
23
23
  ],
24
24
  "engines": {
25
- "node": ">=16.0.0"
25
+ "node": ">=20.0.0"
26
26
  },
27
27
  "publishConfig": {
28
28
  "access": "public"
29
29
  },
30
30
  "keywords": [
31
31
  "claude-code",
32
+ "plugin",
32
33
  "planning",
33
34
  "persistent",
34
35
  "markdown",
35
36
  "context-engineering",
36
37
  "task-tracking",
37
38
  "working-memory",
38
- "goal-tracking",
39
- "manus",
40
- "plugin"
39
+ "goal-tracking"
41
40
  ],
42
41
  "author": {
43
42
  "name": "TheGlitchKing",
@@ -46,10 +45,14 @@
46
45
  "license": "MIT",
47
46
  "repository": {
48
47
  "type": "git",
49
- "url": "https://github.com/TheGlitchKing/persistent-planning.git"
48
+ "url": "git+https://github.com/TheGlitchKing/persistent-planning.git"
50
49
  },
51
50
  "bugs": {
52
51
  "url": "https://github.com/TheGlitchKing/persistent-planning/issues"
53
52
  },
54
- "homepage": "https://github.com/TheGlitchKing/persistent-planning#readme"
53
+ "homepage": "https://github.com/TheGlitchKing/persistent-planning#readme",
54
+ "dependencies": {
55
+ "@theglitchking/claude-plugin-runtime": "^0.1.0",
56
+ "commander": "^14.0.0"
57
+ }
55
58
  }
@@ -0,0 +1,23 @@
1
+ #!/usr/bin/env node
2
+ // Postinstall — delegates to @theglitchking/claude-plugin-runtime.
3
+ // See https://github.com/TheGlitchKing/claude-plugin-runtime/blob/main/docs/PLUGIN_AUTHORING_SCAFFOLD.md
4
+
5
+ import { runPostinstall } from "@theglitchking/claude-plugin-runtime";
6
+ import { dirname, resolve } from "node:path";
7
+ import { fileURLToPath } from "node:url";
8
+
9
+ const packageRoot = resolve(dirname(fileURLToPath(import.meta.url)), "..");
10
+
11
+ try {
12
+ runPostinstall({
13
+ packageName: "@theglitchking/persistent-planning",
14
+ pluginName: "persistent-planning",
15
+ configFile: "persistent-planning.json",
16
+ skillsDir: "skills",
17
+ packageRoot,
18
+ hookCommand:
19
+ "node ./node_modules/@theglitchking/persistent-planning/hooks/session-start.js",
20
+ });
21
+ } catch (err) {
22
+ console.warn(`[persistent-planning] postinstall failed: ${err?.message || err}`);
23
+ }
@@ -1,13 +0,0 @@
1
- {
2
- "permissions": {
3
- "allow": [
4
- "Bash(bash:*)",
5
- "Bash(echo:*)",
6
- "Bash(./install.sh:*)",
7
- "Bash(/mnt/e/docker-containers/persistent-planning/uninstall.sh:*)",
8
- "Bash(chmod:*)",
9
- "Bash(node:*)",
10
- "Bash(python3:*)"
11
- ]
12
- }
13
- }
package/postinstall.js DELETED
@@ -1,34 +0,0 @@
1
- #!/usr/bin/env node
2
-
3
- const colors = {
4
- reset: '\x1b[0m',
5
- green: '\x1b[32m',
6
- blue: '\x1b[34m',
7
- yellow: '\x1b[33m',
8
- cyan: '\x1b[36m'
9
- };
10
-
11
- console.log(`
12
- ${colors.cyan}persistent-planning installed successfully!${colors.reset}
13
-
14
- ${colors.green}+${colors.reset} Package installed: ${colors.blue}@theglitchking/persistent-planning${colors.reset}
15
-
16
- ${colors.yellow}Next Steps:${colors.reset}
17
-
18
- 1. Run the installer to set up the plugin:
19
- ${colors.cyan}persistent-planning install --scope user${colors.reset}
20
-
21
- ${colors.blue}Scopes:${colors.reset}
22
- user - Install globally (~/.claude/) for all projects
23
- project - Install locally (./.claude/) for this project only
24
-
25
- 2. Check installation status:
26
- ${colors.cyan}persistent-planning status${colors.reset}
27
-
28
- 3. After installation, use this Claude Code command:
29
- ${colors.cyan}/start-planning "Your task name"${colors.reset}
30
-
31
- ${colors.yellow}Documentation:${colors.reset}
32
- ${colors.blue}https://github.com/TheGlitchKing/persistent-planning${colors.reset}
33
-
34
- `);
@@ -1,233 +0,0 @@
1
- #!/bin/bash
2
-
3
- ###############################################################################
4
- # init-planning.sh - Persistent Planning Directory Setup
5
- #
6
- # Part of the persistent-planning plugin by TheGlitchKing
7
- # https://github.com/TheGlitchKing/persistent-planning
8
- #
9
- # Usage:
10
- # bash scripts/init-planning.sh [task-name]
11
- # bash scripts/init-planning.sh "Refactor database layer"
12
- #
13
- # What it does:
14
- # 1. Creates .planning/[task-slug]/ directory (separate per task)
15
- # 2. Creates task_plan.md with templates
16
- # 3. Creates notes.md with templates
17
- # 4. Adds .planning/ to .gitignore (optional)
18
- # 5. Confirms creation and provides next steps
19
- #
20
- # Multiple tasks example:
21
- # /start-planning "Refactor auth" -> .planning/refactor-auth/
22
- # /start-planning "Debug memory leak" -> .planning/debug-memory-leak/
23
- # Both plans coexist without conflicts!
24
- ###############################################################################
25
-
26
- set -e
27
-
28
- # Validate that task name was provided
29
- if [ -z "$1" ]; then
30
- echo "Error: Task name required"
31
- echo ""
32
- echo "Usage: bash scripts/init-planning.sh \"Your Task Name\""
33
- echo ""
34
- echo "Examples:"
35
- echo " bash scripts/init-planning.sh \"Refactor authentication\""
36
- echo " bash scripts/init-planning.sh \"Debug API performance\""
37
- exit 1
38
- fi
39
-
40
- TASK_NAME="$1"
41
-
42
- # Convert task name to slug
43
- # "Refactor Authentication" -> "refactor-authentication"
44
- task_name_to_slug() {
45
- local name="$1"
46
- name=$(echo "$name" | tr '[:upper:]' '[:lower:]')
47
- name=$(echo "$name" | sed 's/[[:space:]_]\+/-/g')
48
- name=$(echo "$name" | sed 's/[^a-z0-9-]//g')
49
- name=$(echo "$name" | sed 's/^-\+\|-\+$//g')
50
- name=$(echo "$name" | sed 's/-\+/-/g')
51
- echo "$name"
52
- }
53
-
54
- TASK_SLUG=$(task_name_to_slug "$TASK_NAME")
55
-
56
- # Validate slug
57
- if [ -z "$TASK_SLUG" ]; then
58
- echo "Error: Task name must contain at least one alphanumeric character"
59
- echo "Provided: $TASK_NAME"
60
- exit 1
61
- fi
62
-
63
- # Determine project root
64
- PROJECT_ROOT="${CLAUDE_PROJECT_DIR:-$(pwd)}"
65
- PLANNING_DIR="${PROJECT_ROOT}/.planning"
66
- TASK_DIR="${PLANNING_DIR}/${TASK_SLUG}"
67
-
68
- # Color codes
69
- GREEN='\033[0;32m'
70
- BLUE='\033[0;34m'
71
- YELLOW='\033[1;33m'
72
- CYAN='\033[0;36m'
73
- NC='\033[0m'
74
-
75
- echo -e "${BLUE}Initializing Planning Structure${NC}"
76
- echo ""
77
-
78
- # Step 1: Create .planning directory
79
- if [ ! -d "$PLANNING_DIR" ]; then
80
- mkdir -p "$PLANNING_DIR"
81
- echo -e "${GREEN}+${NC} Created .planning/ directory"
82
- else
83
- echo -e "${YELLOW}*${NC} .planning/ directory exists"
84
- fi
85
-
86
- # Step 2: Create task directory
87
- if [ ! -d "$TASK_DIR" ]; then
88
- mkdir -p "$TASK_DIR"
89
- echo -e "${GREEN}+${NC} Created task directory: ${CYAN}.planning/${TASK_SLUG}/${NC}"
90
- else
91
- echo -e "${YELLOW}*${NC} Task directory already exists: ${CYAN}.planning/${TASK_SLUG}/${NC}"
92
- fi
93
-
94
- # Step 3: Create task_plan.md
95
- TASK_PLAN_FILE="${TASK_DIR}/task_plan.md"
96
- if [ ! -f "$TASK_PLAN_FILE" ]; then
97
- cat > "$TASK_PLAN_FILE" << 'EOF'
98
- # Task Plan: TASK_NAME_PLACEHOLDER
99
-
100
- ## Goal
101
- [One sentence describing the end state]
102
-
103
- ## Phases
104
- - [ ] Phase 1: Plan and setup
105
- - [ ] Phase 2: Research/gather information
106
- - [ ] Phase 3: Execute/build
107
- - [ ] Phase 4: Review and deliver
108
-
109
- ## Key Questions
110
- 1. [Question to answer]
111
- 2. [Question to answer]
112
-
113
- ## Decisions Made
114
- - [Decision]: [Rationale]
115
-
116
- ## Errors Encountered
117
- - [Error]: [Resolution]
118
-
119
- ## Status
120
- **Currently in Phase 1** - Setting up planning structure
121
-
122
- ---
123
-
124
- ## Notes
125
- - This file persists across sessions
126
- - Update status after each phase
127
- - Mark completed phases with [x]
128
- - Save research to notes.md instead of stuffing context
129
- EOF
130
-
131
- sed -i "s/TASK_NAME_PLACEHOLDER/${TASK_NAME}/g" "$TASK_PLAN_FILE"
132
- echo -e "${GREEN}+${NC} Created task_plan.md"
133
- else
134
- echo -e "${YELLOW}*${NC} task_plan.md already exists (not overwritten)"
135
- fi
136
-
137
- # Step 4: Create notes.md
138
- NOTES_FILE="${TASK_DIR}/notes.md"
139
- if [ ! -f "$NOTES_FILE" ]; then
140
- cat > "$NOTES_FILE" << 'EOF'
141
- # Notes: TASK_NAME_PLACEHOLDER
142
-
143
- ## Key Findings
144
- - [Finding 1]
145
- - [Finding 2]
146
-
147
- ## Research Sources
148
- - [Source 1]: [URL or reference]
149
- - [Source 2]: [URL or reference]
150
-
151
- ## Synthesized Findings
152
-
153
- ### [Category/Topic 1]
154
- - [Finding]
155
- - [Finding]
156
-
157
- ### [Category/Topic 2]
158
- - [Finding]
159
- - [Finding]
160
-
161
- ## Decisions Made
162
- - [Decision]: [Rationale]
163
- - [Decision]: [Rationale]
164
-
165
- ## Errors & Solutions
166
- - [Error]: [Resolution]
167
- - [Error]: [Resolution]
168
-
169
- ---
170
-
171
- ## Append-Only Log
172
- Store findings here as you discover them. This builds a searchable history.
173
-
174
- ### [Date/Time]
175
- - [What I found/did]
176
- EOF
177
-
178
- sed -i "s/TASK_NAME_PLACEHOLDER/${TASK_NAME}/g" "$NOTES_FILE"
179
- echo -e "${GREEN}+${NC} Created notes.md"
180
- else
181
- echo -e "${YELLOW}*${NC} notes.md already exists (not overwritten)"
182
- fi
183
-
184
- # Step 5: Update .gitignore
185
- if [ -f "${PROJECT_ROOT}/.gitignore" ]; then
186
- if ! grep -q "^\.planning/" "${PROJECT_ROOT}/.gitignore"; then
187
- echo ".planning/" >> "${PROJECT_ROOT}/.gitignore"
188
- echo -e "${GREEN}+${NC} Added .planning/ to .gitignore"
189
- else
190
- echo -e "${YELLOW}*${NC} .planning/ already in .gitignore"
191
- fi
192
- else
193
- echo -e "${YELLOW}*${NC} No .gitignore found (not added)"
194
- fi
195
-
196
- # Step 6: List other active tasks
197
- OTHER_TASKS=$(find "$PLANNING_DIR" -maxdepth 1 -type d -not -name ".planning" -not -path "$TASK_DIR" 2>/dev/null | wc -l)
198
- if [ "$OTHER_TASKS" -gt 0 ]; then
199
- echo ""
200
- echo -e "${CYAN}Other active tasks:${NC}"
201
- find "$PLANNING_DIR" -maxdepth 1 -type d -not -name ".planning" -not -path "$TASK_DIR" | sort | while read dir; do
202
- task_slug=$(basename "$dir")
203
- echo " .planning/${task_slug}/"
204
- done
205
- fi
206
-
207
- # Step 7: Confirmation
208
- echo ""
209
- echo -e "${GREEN}=====================================${NC}"
210
- echo -e "${GREEN}Task Plan Ready${NC}"
211
- echo -e "${GREEN}=====================================${NC}"
212
- echo ""
213
-
214
- echo -e "${BLUE}Task:${NC} ${TASK_NAME}"
215
- echo -e "${BLUE}Location:${NC} .planning/${TASK_SLUG}/"
216
- echo ""
217
-
218
- echo -e "${BLUE}Files:${NC}"
219
- echo " task_plan.md (your task plan)"
220
- echo " notes.md (research & findings)"
221
- echo ""
222
-
223
- echo -e "${BLUE}Next steps:${NC}"
224
- echo " 1. Edit .planning/${TASK_SLUG}/task_plan.md to define your phases"
225
- echo " 2. As you work, update the Status section"
226
- echo " 3. Save findings to .planning/${TASK_SLUG}/notes.md"
227
- echo " 4. Re-read task_plan.md before major decisions"
228
- echo ""
229
-
230
- echo -e "${BLUE}Cleanup:${NC}"
231
- echo " rm -rf .planning/${TASK_SLUG}/ # Remove this task"
232
- echo " rm -rf .planning/ # Remove all tasks"
233
- echo ""