@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.
- package/.claude-plugin/plugin.json +1 -1
- package/CHANGELOG.md +75 -0
- package/LICENSE +0 -0
- package/README.md +0 -0
- package/bin/persistent-planning.js +57 -232
- package/commands/policy.md +16 -0
- package/commands/relink.md +6 -0
- package/{.claude/commands → commands}/start-planning.md +0 -0
- package/commands/status.md +6 -0
- package/commands/update.md +6 -0
- package/docs/examples.md +0 -0
- package/docs/reference.md +0 -0
- package/hooks/hooks.json +15 -0
- package/hooks/session-start.js +13 -0
- package/package.json +16 -13
- package/scripts/link-skills.js +23 -0
- package/skills/{SKILL.md → persistent-planning/SKILL.md} +0 -0
- package/.claude/settings.local.json +0 -13
- package/postinstall.js +0 -34
- package/scripts/init-planning.sh +0 -233
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "persistent-planning",
|
|
3
|
-
"version": "
|
|
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
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
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
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
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
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
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
|
-
|
|
115
|
-
|
|
116
|
-
|
|
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
|
-
|
|
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.
|
|
File without changes
|
|
@@ -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
|
package/hooks/hooks.json
ADDED
|
@@ -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": "
|
|
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": "
|
|
5
|
+
"type": "module",
|
|
6
6
|
"bin": {
|
|
7
|
-
"persistent-planning": "
|
|
7
|
+
"persistent-planning": "bin/persistent-planning.js"
|
|
8
8
|
},
|
|
9
9
|
"scripts": {
|
|
10
|
-
"postinstall": "node
|
|
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": ">=
|
|
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
|
+
}
|
|
File without changes
|
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
|
-
`);
|
package/scripts/init-planning.sh
DELETED
|
@@ -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 ""
|