prizmkit 1.1.113 → 1.1.115
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/bundled/VERSION.json +3 -3
- package/bundled/dev-pipeline/.env.example +0 -1
- package/bundled/dev-pipeline/README.md +4 -6
- package/bundled/dev-pipeline/SCHEMA_ANALYSIS.md +40 -518
- package/bundled/dev-pipeline/assets/prizm-dev-team-integration.md +27 -99
- package/bundled/dev-pipeline/prizmkit_runtime/checkpoint_state.py +283 -0
- package/bundled/dev-pipeline/prizmkit_runtime/daemon.py +3 -13
- package/bundled/dev-pipeline/prizmkit_runtime/heartbeat.py +0 -1
- package/bundled/dev-pipeline/prizmkit_runtime/runner_classification.py +25 -31
- package/bundled/dev-pipeline/prizmkit_runtime/runner_models.py +0 -8
- package/bundled/dev-pipeline/prizmkit_runtime/runner_prompts.py +0 -3
- package/bundled/dev-pipeline/prizmkit_runtime/runners.py +13 -7
- package/bundled/dev-pipeline/prizmkit_runtime/sessions.py +13 -1
- package/bundled/dev-pipeline/scripts/continuation.py +8 -40
- package/bundled/dev-pipeline/scripts/generate-bootstrap-prompt.py +76 -261
- package/bundled/dev-pipeline/scripts/generate-bugfix-prompt.py +16 -35
- package/bundled/dev-pipeline/scripts/generate-refactor-prompt.py +15 -34
- package/bundled/dev-pipeline/scripts/init-bugfix-pipeline.py +6 -0
- package/bundled/dev-pipeline/scripts/init-pipeline.py +6 -0
- package/bundled/dev-pipeline/scripts/init-refactor-pipeline.py +6 -0
- package/bundled/dev-pipeline/scripts/parse-stream-progress.py +1 -1
- package/bundled/dev-pipeline/scripts/prompt_framework.py +114 -63
- package/bundled/dev-pipeline/scripts/update-bug-status.py +3 -7
- package/bundled/dev-pipeline/scripts/update-checkpoint.py +54 -22
- package/bundled/dev-pipeline/scripts/update-feature-status.py +3 -7
- package/bundled/dev-pipeline/scripts/update-refactor-status.py +3 -7
- package/bundled/dev-pipeline/scripts/utils.py +14 -40
- package/bundled/dev-pipeline/templates/bootstrap-prompt.md +1 -1
- package/bundled/dev-pipeline/templates/bootstrap-tier1.md +1 -1
- package/bundled/dev-pipeline/templates/bootstrap-tier2.md +9 -91
- package/bundled/dev-pipeline/templates/bootstrap-tier3.md +9 -66
- package/bundled/dev-pipeline/templates/bug-fix-list-schema.json +10 -16
- package/bundled/dev-pipeline/templates/feature-list-schema.json +32 -17
- package/bundled/dev-pipeline/templates/refactor-bootstrap-prompt.md +0 -16
- package/bundled/dev-pipeline/templates/refactor-list-schema.json +10 -16
- package/bundled/dev-pipeline/templates/sections/bugfix-session-context.md +1 -1
- package/bundled/dev-pipeline/templates/sections/context-budget-rules.md +1 -1
- package/bundled/dev-pipeline/templates/sections/critical-paths-agent.md +0 -1
- package/bundled/dev-pipeline/templates/sections/critical-paths-full.md +0 -1
- package/bundled/dev-pipeline/templates/sections/phase-implement-agent.md +1 -1
- package/bundled/dev-pipeline/templates/sections/phase-implement-full.md +1 -1
- package/bundled/dev-pipeline/templates/sections/refactor-session-context.md +1 -1
- package/bundled/dev-pipeline/tests/conftest.py +1 -0
- package/bundled/dev-pipeline/tests/test_checkpoint_state.py +164 -0
- package/bundled/dev-pipeline/tests/test_generate_bootstrap_prompt.py +48 -76
- package/bundled/dev-pipeline/tests/test_generate_bugfix_prompt.py +25 -3
- package/bundled/dev-pipeline/tests/test_generate_refactor_prompt.py +25 -5
- package/bundled/dev-pipeline/tests/test_python_runner_parity.py +128 -10
- package/bundled/dev-pipeline/tests/test_runtime_helper.py +23 -0
- package/bundled/dev-pipeline/tests/test_unified_cli.py +40 -9
- package/bundled/skills/_metadata.json +1 -1
- package/bundled/skills/app-planner/SKILL.md +18 -2
- package/bundled/skills/app-planner/references/generated-plan-review.md +67 -0
- package/bundled/skills/bug-planner/SKILL.md +24 -28
- package/bundled/skills/bug-planner/references/generated-plan-review.md +63 -0
- package/bundled/skills/bug-planner/references/verification.md +29 -0
- package/bundled/skills/bug-planner/scripts/validate-bug-list.py +8 -0
- package/bundled/skills/bugfix-pipeline-launcher/SKILL.md +2 -2
- package/bundled/skills/bugfix-pipeline-launcher/references/configuration.md +1 -6
- package/bundled/skills/feature-pipeline-launcher/SKILL.md +6 -12
- package/bundled/skills/feature-pipeline-launcher/references/configuration.md +0 -1
- package/bundled/skills/feature-planner/SKILL.md +30 -34
- package/bundled/skills/feature-planner/assets/planning-guide.md +2 -2
- package/bundled/skills/feature-planner/references/generated-plan-review.md +63 -0
- package/bundled/skills/feature-planner/scripts/validate-and-generate.py +8 -11
- package/bundled/skills/prizmkit-init/SKILL.md +2 -2
- package/bundled/skills/prizmkit-plan/SKILL.md +15 -1
- package/bundled/skills/prizmkit-plan/references/review-plan-spec-loop.md +101 -0
- package/bundled/skills/prizmkit-prizm-docs/references/op-init.md +1 -1
- package/bundled/skills/refactor-pipeline-launcher/SKILL.md +5 -5
- package/bundled/skills/refactor-pipeline-launcher/references/configuration.md +2 -7
- package/bundled/skills/refactor-planner/SKILL.md +30 -34
- package/bundled/skills/refactor-planner/references/fast-path.md +2 -2
- package/bundled/skills/refactor-planner/references/generated-plan-review.md +63 -0
- package/bundled/skills/refactor-planner/scripts/validate-and-generate-refactor.py +9 -0
- package/bundled/team/prizm-dev-team.json +2 -9
- package/package.json +1 -1
- package/src/clean.js +60 -7
- package/src/config.js +61 -20
- package/src/gitignore-template.js +6 -3
- package/src/manifest.js +6 -2
- package/src/platforms.js +14 -0
- package/src/scaffold.js +198 -34
- package/src/upgrade.js +5 -2
- package/bundled/agents/prizm-dev-team-critic.md +0 -179
- package/bundled/dev-pipeline/templates/agent-prompts/critic-plan-challenge.md +0 -8
- package/bundled/dev-pipeline/templates/sections/bugfix-phase-critic.md +0 -22
- package/bundled/dev-pipeline/templates/sections/phase-critic-plan-full.md +0 -61
- package/bundled/dev-pipeline/templates/sections/phase-critic-plan.md +0 -38
- package/bundled/dev-pipeline/templates/sections/refactor-phase-critic.md +0 -22
- package/bundled/skills/bug-planner/references/critic-and-verification.md +0 -44
|
@@ -0,0 +1,63 @@
|
|
|
1
|
+
# Generated Plan Review — Refactor Planner
|
|
2
|
+
|
|
3
|
+
Use this local review loop after `.prizmkit/plans/refactor-list.json` has been generated and validated. This is a planner-output review, not an implementation/code-diff review.
|
|
4
|
+
|
|
5
|
+
## Trigger
|
|
6
|
+
|
|
7
|
+
Run only when the current `refactor-planner` session generated, appended, or rewrote final refactor planning content. For validate-only, summary-only, or draft-save flows with no new final planning content, report: `Local generated-plan review: not applicable — no new final planning content written.`
|
|
8
|
+
|
|
9
|
+
## Direct Artifact Reads
|
|
10
|
+
|
|
11
|
+
Planning artifacts may be gitignored, untracked, or absent from staged and unstaged diffs. Read the actual files directly:
|
|
12
|
+
|
|
13
|
+
- Final list: `.prizmkit/plans/refactor-list.json`
|
|
14
|
+
- Draft/source list when present: `.prizmkit/plans/refactor-list.draft.json`
|
|
15
|
+
- Pre-session final list snapshot if captured in memory before edits
|
|
16
|
+
- In-memory draft object if the session has not written a draft file yet
|
|
17
|
+
|
|
18
|
+
Do not rely on `git status`, `git diff`, or `git diff --cached` to decide whether planner output exists or changed. Do not invoke `/prizmkit-code-review` for this planner-output gate; `/prizmkit-code-review` remains the implementation/code-diff review gate after `/prizmkit-implement`.
|
|
19
|
+
|
|
20
|
+
## Review Scope
|
|
21
|
+
|
|
22
|
+
1. If a pre-session final list exists, compare by stable refactor IDs (`R-*`).
|
|
23
|
+
2. Treat refactors as changed only when item fields changed. Ignore root generator metadata and formatting-only differences such as `$schema`, `created_at`, and `created_by`.
|
|
24
|
+
3. Review newly added refactor IDs and changed refactor IDs.
|
|
25
|
+
4. Preserve unchanged historical refactors. Read unchanged entries only when needed to verify dependency references or behavior-preservation interactions with reviewed refactors.
|
|
26
|
+
5. If no snapshot exists, review all refactor entries produced by the current generation flow.
|
|
27
|
+
|
|
28
|
+
## Review Checklist
|
|
29
|
+
|
|
30
|
+
For every reviewed refactor entry, check:
|
|
31
|
+
|
|
32
|
+
- Schema compatibility with `dev-pipeline-refactor-list-v1` and `.prizmkit/dev-pipeline/templates/refactor-list-schema.json`
|
|
33
|
+
- Dependency/DAG soundness, including safe behavior-preserving order
|
|
34
|
+
- Description completeness, target scope clarity, and headless execution readiness
|
|
35
|
+
- Acceptance criteria specificity and measurable behavior-preservation verification
|
|
36
|
+
- `behavior_preservation` strategy quality and consistency with target scope and existing tests
|
|
37
|
+
- User-provided wording preservation in `description`, `acceptance_criteria`, and `user_context`
|
|
38
|
+
- Task-scoped `user_context` isolation: no unrelated sibling refactor goals, target files, constraints, desired end states, or supplementary materials; shared context appears on multiple items only when explicitly global
|
|
39
|
+
- Priority/complexity calibration: every reviewed refactor has short priority and complexity rationales, medium/low assignments are allowed when criteria fit, and high/high is not used merely because the work is cleanup, framework-related, multi-file, or user-requested
|
|
40
|
+
|
|
41
|
+
## Fix Loop
|
|
42
|
+
|
|
43
|
+
1. Present findings with IDs, severity, evidence, and suggested draft/source changes.
|
|
44
|
+
2. Accept only findings that improve planner correctness, completeness, or downstream behavior-preserving execution readiness.
|
|
45
|
+
3. Apply accepted fixes to `.prizmkit/plans/refactor-list.draft.json` or the in-memory draft object first.
|
|
46
|
+
4. Regenerate the final list through the existing generator:
|
|
47
|
+
|
|
48
|
+
```bash
|
|
49
|
+
python3 ${SKILL_DIR}/scripts/validate-and-generate-refactor.py generate --input .prizmkit/plans/refactor-list.draft.json --output .prizmkit/plans/refactor-list.json
|
|
50
|
+
```
|
|
51
|
+
|
|
52
|
+
5. Re-run validation/generation until valid. Do not hand-patch `.prizmkit/plans/refactor-list.json` as the source of truth.
|
|
53
|
+
6. Repeat the local review only for entries changed by accepted fixes.
|
|
54
|
+
|
|
55
|
+
## Report Format
|
|
56
|
+
|
|
57
|
+
Report in the final handoff summary:
|
|
58
|
+
|
|
59
|
+
- `Local generated-plan review: PASS` or `NEEDS_FIXES`
|
|
60
|
+
- Reviewed refactor IDs
|
|
61
|
+
- Accepted fixes, or `none`
|
|
62
|
+
- Final validation result
|
|
63
|
+
- Note when review was not applicable because no new final planning content was written
|
|
@@ -246,6 +246,15 @@ def validate_refactor_list(data):
|
|
|
246
246
|
)
|
|
247
247
|
)
|
|
248
248
|
|
|
249
|
+
# -- Retired fields --
|
|
250
|
+
for retired_field in ("critic", "critic_count"):
|
|
251
|
+
if retired_field in refactor:
|
|
252
|
+
errors.append(
|
|
253
|
+
"{}: '{}' field is retired; remove it from refactor-list data".format(
|
|
254
|
+
label, retired_field
|
|
255
|
+
)
|
|
256
|
+
)
|
|
257
|
+
|
|
249
258
|
# -- Scope --
|
|
250
259
|
scope = refactor.get("scope")
|
|
251
260
|
if isinstance(scope, dict):
|
|
@@ -1,12 +1,12 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "prizm-dev-team",
|
|
3
3
|
"team_name": "prizm-dev-team",
|
|
4
|
-
"description": "PrizmKit-integrated
|
|
4
|
+
"description": "PrizmKit-integrated software development team with Dev and Reviewer agents following the PrizmKit spec-driven workflow.",
|
|
5
5
|
"lead": "orchestrator",
|
|
6
6
|
"communication": {
|
|
7
7
|
"protocol": "SendMessage",
|
|
8
8
|
"routing": "mesh",
|
|
9
|
-
"note": "Teammates communicate directly via SendMessage; key messages must also be sent to Orchestrator (the main AI session).
|
|
9
|
+
"note": "Teammates communicate directly via SendMessage; key messages must also be sent to Orchestrator (the main AI session)."
|
|
10
10
|
},
|
|
11
11
|
"members": [
|
|
12
12
|
{
|
|
@@ -22,13 +22,6 @@
|
|
|
22
22
|
"agentDefinition": "prizm-dev-team-reviewer",
|
|
23
23
|
"prompt": "You are the Reviewer Agent of the prizm-dev-team. Your complete behavior rules are in your agent definition. Run /prizmkit-code-review for diagnosis + fix strategy formulation. You do NOT run tests — the Orchestrator handles testing.",
|
|
24
24
|
"subscriptions": ["*"]
|
|
25
|
-
},
|
|
26
|
-
{
|
|
27
|
-
"name": "critic",
|
|
28
|
-
"role": "critic",
|
|
29
|
-
"agentDefinition": "prizm-dev-team-critic",
|
|
30
|
-
"prompt": "You are the Critic Agent of the prizm-dev-team. Your complete behavior rules are in your agent definition. Challenge plans and implementations for project fitness, style consistency, robustness, and integration quality. Supports parallel 3-critic voting mode. Do NOT verify correctness — that is the Reviewer's job.",
|
|
31
|
-
"subscriptions": ["*"]
|
|
32
25
|
}
|
|
33
26
|
]
|
|
34
27
|
}
|
package/package.json
CHANGED
package/src/clean.js
CHANGED
|
@@ -3,6 +3,19 @@ import path from 'path';
|
|
|
3
3
|
import fs from 'fs-extra';
|
|
4
4
|
import { loadMetadata, loadRulesMetadata } from './metadata.js';
|
|
5
5
|
import { readManifest } from './manifest.js';
|
|
6
|
+
import { privateProjectMemoryFile, projectMemoryFile } from './platforms.js';
|
|
7
|
+
|
|
8
|
+
const PRIZMKIT_GITIGNORE_HEADERS = new Set([
|
|
9
|
+
'# PrizmKit',
|
|
10
|
+
'# PrizmKit 运行时全部产物(state/、prizm-docs/、.env、logs 等)',
|
|
11
|
+
]);
|
|
12
|
+
const PRIZMKIT_GITIGNORE_ENTRIES = new Set([
|
|
13
|
+
'.prizmkit/',
|
|
14
|
+
'.prizmkit/*',
|
|
15
|
+
'CLAUDE.private.md',
|
|
16
|
+
'AGENTS.private.md',
|
|
17
|
+
'CODEBUDDY.private.md',
|
|
18
|
+
]);
|
|
6
19
|
|
|
7
20
|
async function removePath(targetPath, dryRun) {
|
|
8
21
|
if (!await fs.pathExists(targetPath)) {
|
|
@@ -54,11 +67,14 @@ async function cleanGitignore(projectRoot, dryRun) {
|
|
|
54
67
|
}
|
|
55
68
|
|
|
56
69
|
const content = await fs.readFile(gitignorePath, 'utf8');
|
|
57
|
-
const
|
|
58
|
-
.
|
|
59
|
-
.
|
|
60
|
-
|
|
61
|
-
|
|
70
|
+
const nextLines = content.split(/\r?\n/).filter(line => {
|
|
71
|
+
const trimmed = line.trim();
|
|
72
|
+
return !PRIZMKIT_GITIGNORE_HEADERS.has(trimmed)
|
|
73
|
+
&& !PRIZMKIT_GITIGNORE_ENTRIES.has(trimmed);
|
|
74
|
+
});
|
|
75
|
+
const next = nextLines.join('\n').replace(/\n{3,}/g, '\n\n').trimEnd();
|
|
76
|
+
|
|
77
|
+
if (`${next}\n` === content || next === content.trimEnd()) {
|
|
62
78
|
return { updated: false, reason: 'no_prizmkit_section' };
|
|
63
79
|
}
|
|
64
80
|
|
|
@@ -66,7 +82,7 @@ async function cleanGitignore(projectRoot, dryRun) {
|
|
|
66
82
|
return { updated: true, reason: 'dry_run' };
|
|
67
83
|
}
|
|
68
84
|
|
|
69
|
-
await fs.writeFile(gitignorePath, next
|
|
85
|
+
await fs.writeFile(gitignorePath, next ? `${next}\n` : '');
|
|
70
86
|
return { updated: true };
|
|
71
87
|
}
|
|
72
88
|
|
|
@@ -100,6 +116,38 @@ async function cleanMarkedProjectMemory(projectRoot, fileName, dryRun) {
|
|
|
100
116
|
return { path: filePath, removed: true, note: '(PrizmKit section)' };
|
|
101
117
|
}
|
|
102
118
|
|
|
119
|
+
async function cleanProjectMemoryImport(projectRoot, fileName, privateFileName, dryRun) {
|
|
120
|
+
const filePath = path.join(projectRoot, fileName);
|
|
121
|
+
if (!await fs.pathExists(filePath)) {
|
|
122
|
+
return { path: filePath, removed: false, reason: 'not_found' };
|
|
123
|
+
}
|
|
124
|
+
|
|
125
|
+
const importPointer = `@./${privateFileName}`;
|
|
126
|
+
const content = await fs.readFile(filePath, 'utf8');
|
|
127
|
+
const next = content
|
|
128
|
+
.split(/\r?\n/)
|
|
129
|
+
.filter(line => line.trim() !== importPointer)
|
|
130
|
+
.join('\n')
|
|
131
|
+
.replace(/\n{3,}/g, '\n\n')
|
|
132
|
+
.trimEnd();
|
|
133
|
+
|
|
134
|
+
if (next === content.trimEnd()) {
|
|
135
|
+
return { path: filePath, removed: false, reason: 'no_prizmkit_import' };
|
|
136
|
+
}
|
|
137
|
+
|
|
138
|
+
if (dryRun) {
|
|
139
|
+
return { path: filePath, removed: false, reason: 'dry_run' };
|
|
140
|
+
}
|
|
141
|
+
|
|
142
|
+
if (!next) {
|
|
143
|
+
await fs.remove(filePath);
|
|
144
|
+
return { path: filePath, removed: true, note: '(PrizmKit import only)' };
|
|
145
|
+
}
|
|
146
|
+
|
|
147
|
+
await fs.writeFile(filePath, `${next}\n`);
|
|
148
|
+
return { path: filePath, removed: true, note: '(PrizmKit import)' };
|
|
149
|
+
}
|
|
150
|
+
|
|
103
151
|
async function removeGeneratedCodexConfig(projectRoot, dryRun) {
|
|
104
152
|
const configPath = path.join(projectRoot, '.codex', 'config.toml');
|
|
105
153
|
if (!await fs.pathExists(configPath)) {
|
|
@@ -228,7 +276,12 @@ export async function runClean(directory, options = {}) {
|
|
|
228
276
|
const legacyCodexRulesDir = path.join(projectRoot, '.codex', 'rules');
|
|
229
277
|
results.push(...await removeKnownEntries(legacyCodexRulesDir, ruleFileNames.map(n => `${n}.md`), dryRun));
|
|
230
278
|
|
|
231
|
-
for (const
|
|
279
|
+
for (const platform of ['codebuddy', 'claude', 'codex']) {
|
|
280
|
+
const memoryFile = projectMemoryFile(platform);
|
|
281
|
+
const privateMemoryFile = privateProjectMemoryFile(platform);
|
|
282
|
+
if (!memoryFile || !privateMemoryFile) continue;
|
|
283
|
+
results.push(await cleanProjectMemoryImport(projectRoot, memoryFile, privateMemoryFile, dryRun));
|
|
284
|
+
results.push(await cleanMarkedProjectMemory(projectRoot, privateMemoryFile, dryRun));
|
|
232
285
|
results.push(await cleanMarkedProjectMemory(projectRoot, memoryFile, dryRun));
|
|
233
286
|
}
|
|
234
287
|
|
package/src/config.js
CHANGED
|
@@ -38,6 +38,7 @@ import {
|
|
|
38
38
|
resolveRuleNamesForRuntime,
|
|
39
39
|
findStaleManagedPipelineFiles,
|
|
40
40
|
removeStaleManagedPipelineFiles,
|
|
41
|
+
normalizeMainProjectMemoryContent,
|
|
41
42
|
} from './scaffold.js';
|
|
42
43
|
import {
|
|
43
44
|
removeSkillFiles,
|
|
@@ -54,7 +55,7 @@ import {
|
|
|
54
55
|
confirmTeamMode,
|
|
55
56
|
confirmPipeline,
|
|
56
57
|
} from './prompts.js';
|
|
57
|
-
import { isKnownPlatform, platformLabel, projectMemoryFile, resolvePayloadPlatforms } from './platforms.js';
|
|
58
|
+
import { isKnownPlatform, platformLabel, privateProjectMemoryFile, privateProjectMemoryFiles, projectMemoryFile, resolvePayloadPlatforms } from './platforms.js';
|
|
58
59
|
import { normalizeRuntime, runtimeLabel } from './runtimes.js';
|
|
59
60
|
import { applyAiCliLaunchToConfig, resolveAiCliLaunchSelection, storedAiCliLaunch } from './ai-cli-launch.js';
|
|
60
61
|
|
|
@@ -114,6 +115,50 @@ function getProjectMemoryFile(platform) {
|
|
|
114
115
|
return projectMemoryFile(platform);
|
|
115
116
|
}
|
|
116
117
|
|
|
118
|
+
function logManagedMemoryWarnings(mainFile, warnings) {
|
|
119
|
+
for (const warning of warnings) {
|
|
120
|
+
console.log(chalk.yellow(` ⚠ ${mainFile}: ${warning}; preserving unmatched marker content`));
|
|
121
|
+
}
|
|
122
|
+
}
|
|
123
|
+
|
|
124
|
+
async function removeProjectMemoryArtifacts(platform, projectRoot, dryRun) {
|
|
125
|
+
const mainFile = projectMemoryFile(platform);
|
|
126
|
+
const privateFile = privateProjectMemoryFile(platform);
|
|
127
|
+
if (!mainFile || !privateFile) return;
|
|
128
|
+
|
|
129
|
+
const privatePath = path.join(projectRoot, privateFile);
|
|
130
|
+
if (await fs.pathExists(privatePath)) {
|
|
131
|
+
if (dryRun) {
|
|
132
|
+
console.log(chalk.gray(` [dry-run] remove ${privateFile}`));
|
|
133
|
+
} else {
|
|
134
|
+
await fs.remove(privatePath);
|
|
135
|
+
console.log(chalk.red(` ✗ removed ${privateFile}`));
|
|
136
|
+
}
|
|
137
|
+
}
|
|
138
|
+
|
|
139
|
+
const mainPath = path.join(projectRoot, mainFile);
|
|
140
|
+
if (!await fs.pathExists(mainPath)) return;
|
|
141
|
+
|
|
142
|
+
const current = await fs.readFile(mainPath, 'utf-8');
|
|
143
|
+
const normalized = normalizeMainProjectMemoryContent(current, privateFile);
|
|
144
|
+
logManagedMemoryWarnings(mainFile, normalized.warnings);
|
|
145
|
+
const next = normalized.content.trim();
|
|
146
|
+
if (next === current.trim()) return;
|
|
147
|
+
|
|
148
|
+
if (dryRun) {
|
|
149
|
+
console.log(chalk.gray(` [dry-run] update ${mainFile} (remove PrizmKit import)`));
|
|
150
|
+
return;
|
|
151
|
+
}
|
|
152
|
+
|
|
153
|
+
if (!next) {
|
|
154
|
+
await fs.remove(mainPath);
|
|
155
|
+
console.log(chalk.red(` ✗ removed ${mainFile} (empty after PrizmKit import removal)`));
|
|
156
|
+
} else {
|
|
157
|
+
await fs.writeFile(mainPath, `${next}\n`, 'utf-8');
|
|
158
|
+
console.log(chalk.green(` ✓ updated ${mainFile} (removed PrizmKit import)`));
|
|
159
|
+
}
|
|
160
|
+
}
|
|
161
|
+
|
|
117
162
|
async function migrateProjectMemoryOnPlatformDrop(droppedPlatform, newPlatforms, projectRoot, dryRun) {
|
|
118
163
|
const sourceFile = getProjectMemoryFile(droppedPlatform);
|
|
119
164
|
if (!sourceFile) return;
|
|
@@ -135,8 +180,13 @@ async function migrateProjectMemoryOnPlatformDrop(droppedPlatform, newPlatforms,
|
|
|
135
180
|
return;
|
|
136
181
|
}
|
|
137
182
|
|
|
138
|
-
const
|
|
139
|
-
|
|
183
|
+
const normalized = normalizeMainProjectMemoryContent(
|
|
184
|
+
await fs.readFile(sourcePath, 'utf-8'),
|
|
185
|
+
privateProjectMemoryFile(droppedPlatform),
|
|
186
|
+
);
|
|
187
|
+
logManagedMemoryWarnings(sourceFile, normalized.warnings);
|
|
188
|
+
const sourceContent = normalized.content.trim();
|
|
189
|
+
if (!sourceContent) return;
|
|
140
190
|
|
|
141
191
|
if (!await fs.pathExists(targetPath)) {
|
|
142
192
|
const normalized = sourceContent.endsWith('\n') ? sourceContent : `${sourceContent}\n`;
|
|
@@ -244,18 +294,8 @@ async function removePlatformFiles(platform, projectRoot, manifest, dryRun) {
|
|
|
244
294
|
}
|
|
245
295
|
}
|
|
246
296
|
|
|
247
|
-
// Project memory file
|
|
248
|
-
|
|
249
|
-
if (!memoryFile) return;
|
|
250
|
-
const memoryPath = path.join(projectRoot, memoryFile);
|
|
251
|
-
if (await fs.pathExists(memoryPath)) {
|
|
252
|
-
if (dryRun) {
|
|
253
|
-
console.log(chalk.gray(` [dry-run] remove ${memoryFile}`));
|
|
254
|
-
} else {
|
|
255
|
-
await fs.remove(memoryPath);
|
|
256
|
-
console.log(chalk.red(` ✗ removed ${memoryFile}`));
|
|
257
|
-
}
|
|
258
|
-
}
|
|
297
|
+
// Project memory artifacts: remove only managed private file/imports, not user-owned main content.
|
|
298
|
+
await removeProjectMemoryArtifacts(platform, projectRoot, dryRun);
|
|
259
299
|
|
|
260
300
|
// Command assets (Claude only)
|
|
261
301
|
if (platform === 'claude') {
|
|
@@ -611,10 +651,8 @@ export async function runConfig(directory, options = {}) {
|
|
|
611
651
|
console.log(chalk.blue('\n Settings & Rules:'));
|
|
612
652
|
await installSettings(p, projectRoot, { pipeline: newConfig.pipeline, rules: newConfig.rules }, false, newConfig.runtime);
|
|
613
653
|
|
|
614
|
-
|
|
615
|
-
|
|
616
|
-
await installProjectMemory(p, projectRoot, false);
|
|
617
|
-
}
|
|
654
|
+
console.log(chalk.blue('\n Project Memory:'));
|
|
655
|
+
await installProjectMemory(p, projectRoot, false);
|
|
618
656
|
|
|
619
657
|
if (newConfig.team) {
|
|
620
658
|
console.log(chalk.blue('\n Team Config:'));
|
|
@@ -648,7 +686,10 @@ export async function runConfig(directory, options = {}) {
|
|
|
648
686
|
|
|
649
687
|
// 5f. Update .gitignore
|
|
650
688
|
console.log(chalk.blue('\n Gitignore:'));
|
|
651
|
-
await installGitignore(projectRoot, {
|
|
689
|
+
await installGitignore(projectRoot, {
|
|
690
|
+
pipeline: newConfig.pipeline,
|
|
691
|
+
privateMemoryFiles: privateProjectMemoryFiles(newPlatforms),
|
|
692
|
+
}, false);
|
|
652
693
|
|
|
653
694
|
// 5g. Runtime-aware git hook and PrizmKit helper scripts
|
|
654
695
|
if (newConfig.runtime !== currentConfig.runtime || runtimeManifestNeedsNormalization || runtimeOptionNeedsNormalization) {
|
|
@@ -9,11 +9,14 @@
|
|
|
9
9
|
* @returns {string}
|
|
10
10
|
*/
|
|
11
11
|
export function generateGitignore(options = {}) {
|
|
12
|
-
|
|
12
|
+
const privateMemoryFiles = Array.isArray(options.privateMemoryFiles)
|
|
13
|
+
? options.privateMemoryFiles.filter(Boolean)
|
|
14
|
+
: [];
|
|
13
15
|
const lines = [
|
|
14
|
-
'# PrizmKit
|
|
16
|
+
'# PrizmKit',
|
|
15
17
|
'.prizmkit/*',
|
|
18
|
+
...privateMemoryFiles,
|
|
16
19
|
];
|
|
17
20
|
|
|
18
|
-
return lines.join('\n');
|
|
21
|
+
return [...new Set(lines)].join('\n');
|
|
19
22
|
}
|
package/src/manifest.js
CHANGED
|
@@ -9,7 +9,7 @@
|
|
|
9
9
|
|
|
10
10
|
import fs from 'fs-extra';
|
|
11
11
|
import path from 'path';
|
|
12
|
-
import { projectMemoryFile, resolvePayloadPlatforms } from './platforms.js';
|
|
12
|
+
import { privateProjectMemoryFile, projectMemoryFile, resolvePayloadPlatforms } from './platforms.js';
|
|
13
13
|
import { normalizeRuntime } from './runtimes.js';
|
|
14
14
|
|
|
15
15
|
const MANIFEST_FILE = 'manifest.json';
|
|
@@ -100,7 +100,11 @@ export function buildManifest({
|
|
|
100
100
|
pipeline: pipeline ? [...pipeline] : [],
|
|
101
101
|
extras: extras ? [...extras] : [],
|
|
102
102
|
payloadPlatforms: installedPayloadPlatforms,
|
|
103
|
-
|
|
103
|
+
memory: {
|
|
104
|
+
main: [...new Set(installedPayloadPlatforms.map(projectMemoryFile).filter(Boolean))],
|
|
105
|
+
private: [...new Set(installedPayloadPlatforms.map(privateProjectMemoryFile).filter(Boolean))],
|
|
106
|
+
},
|
|
107
|
+
other: [...new Set(installedPayloadPlatforms.map(privateProjectMemoryFile).filter(Boolean))],
|
|
104
108
|
},
|
|
105
109
|
};
|
|
106
110
|
}
|
package/src/platforms.js
CHANGED
|
@@ -62,6 +62,20 @@ export function projectMemoryFile(platform) {
|
|
|
62
62
|
return null;
|
|
63
63
|
}
|
|
64
64
|
|
|
65
|
+
export function privateProjectMemoryFile(platform) {
|
|
66
|
+
const mainFile = projectMemoryFile(platform);
|
|
67
|
+
if (!mainFile) return null;
|
|
68
|
+
return mainFile.replace(/\.md$/i, '.private.md');
|
|
69
|
+
}
|
|
70
|
+
|
|
71
|
+
export function projectMemoryFiles(platform) {
|
|
72
|
+
return [projectMemoryFile(platform), privateProjectMemoryFile(platform)].filter(Boolean);
|
|
73
|
+
}
|
|
74
|
+
|
|
75
|
+
export function privateProjectMemoryFiles(platforms) {
|
|
76
|
+
return [...new Set((platforms || []).map(privateProjectMemoryFile).filter(Boolean))];
|
|
77
|
+
}
|
|
78
|
+
|
|
65
79
|
export function defaultCliForPlatform(platform) {
|
|
66
80
|
if (platform === 'claude') return 'claude';
|
|
67
81
|
if (platform === 'codebuddy') return 'cbc';
|