mindsystem-cc 4.0.3 → 4.0.4
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 +9 -0
- package/bin/install.js +29 -8
- package/commands/ms/doctor.md +3 -3
- package/package.json +1 -1
- package/scripts/ms-tools.py +56 -8
package/README.md
CHANGED
|
@@ -250,6 +250,15 @@ Requirements you want but haven't shipped yet are tracked in `PROJECT.md` with o
|
|
|
250
250
|
|
|
251
251
|
---
|
|
252
252
|
|
|
253
|
+
## Prerequisites
|
|
254
|
+
|
|
255
|
+
- [Claude Code](https://docs.anthropic.com/en/docs/claude-code)
|
|
256
|
+
- [Node.js](https://nodejs.org/) (for `npx`)
|
|
257
|
+
- [uv](https://docs.astral.sh/uv/) — Python package runner used by CLI scripts (`curl -LsSf https://astral.sh/uv/install.sh | sh`)
|
|
258
|
+
- Python 3.10+ (used by uv for scripts)
|
|
259
|
+
|
|
260
|
+
---
|
|
261
|
+
|
|
253
262
|
## Quick start
|
|
254
263
|
|
|
255
264
|
### New project
|
package/bin/install.js
CHANGED
|
@@ -420,9 +420,9 @@ function generateWrappers(claudeDir) {
|
|
|
420
420
|
fs.mkdirSync(binDir, { recursive: true });
|
|
421
421
|
|
|
422
422
|
const wrappers = {
|
|
423
|
-
'ms-tools': '#!/usr/bin/env bash\nexec uv run "$(dirname "$0")/../mindsystem/scripts/ms-tools.py" "$@"\n',
|
|
423
|
+
'ms-tools': '#!/usr/bin/env bash\n[ -f "$HOME/.local/bin/env" ] && . "$HOME/.local/bin/env"\nexec uv run "$(dirname "$0")/../mindsystem/scripts/ms-tools.py" "$@"\n',
|
|
424
424
|
'ms-lookup': '#!/usr/bin/env bash\nexec "$(dirname "$0")/../mindsystem/scripts/ms-lookup-wrapper.sh" "$@"\n',
|
|
425
|
-
'ms-compare-mockups': '#!/usr/bin/env bash\nexec uv run "$(dirname "$0")/../mindsystem/scripts/compare_mockups.py" "$@"\n',
|
|
425
|
+
'ms-compare-mockups': '#!/usr/bin/env bash\n[ -f "$HOME/.local/bin/env" ] && . "$HOME/.local/bin/env"\nexec uv run "$(dirname "$0")/../mindsystem/scripts/compare_mockups.py" "$@"\n',
|
|
426
426
|
};
|
|
427
427
|
|
|
428
428
|
for (const [name, content] of Object.entries(wrappers)) {
|
|
@@ -444,11 +444,6 @@ function ensurePathHook(claudeDir, isGlobal, configDir) {
|
|
|
444
444
|
if (!Array.isArray(settings.hooks.SessionStart))
|
|
445
445
|
settings.hooks.SessionStart = [];
|
|
446
446
|
|
|
447
|
-
// Idempotent — skip if already present
|
|
448
|
-
const marker = 'mindsystem/bin';
|
|
449
|
-
if (settings.hooks.SessionStart.some(e => JSON.stringify(e).includes(marker)))
|
|
450
|
-
return;
|
|
451
|
-
|
|
452
447
|
// Build PATH expression
|
|
453
448
|
let binExpr;
|
|
454
449
|
if (isGlobal) {
|
|
@@ -459,6 +454,14 @@ function ensurePathHook(claudeDir, isGlobal, configDir) {
|
|
|
459
454
|
binExpr = '$CLAUDE_PROJECT_DIR/.claude/bin';
|
|
460
455
|
}
|
|
461
456
|
|
|
457
|
+
// Self-healing: remove all existing Mindsystem PATH hooks, then add exactly one.
|
|
458
|
+
// This deduplicates any prior entries AND prevents future duplicates.
|
|
459
|
+
const before = settings.hooks.SessionStart.length;
|
|
460
|
+
settings.hooks.SessionStart = settings.hooks.SessionStart.filter(
|
|
461
|
+
e => !JSON.stringify(e).includes('CLAUDE_ENV_FILE')
|
|
462
|
+
);
|
|
463
|
+
const removed = before - settings.hooks.SessionStart.length;
|
|
464
|
+
|
|
462
465
|
settings.hooks.SessionStart.push({
|
|
463
466
|
matcher: '',
|
|
464
467
|
hooks: [{
|
|
@@ -468,7 +471,11 @@ function ensurePathHook(claudeDir, isGlobal, configDir) {
|
|
|
468
471
|
});
|
|
469
472
|
|
|
470
473
|
fs.writeFileSync(settingsPath, JSON.stringify(settings, null, 2));
|
|
471
|
-
|
|
474
|
+
if (removed > 0) {
|
|
475
|
+
console.log(` ${green}✓${reset} Configured PATH hook (cleaned ${removed} duplicate(s))`);
|
|
476
|
+
} else {
|
|
477
|
+
console.log(` ${green}✓${reset} Configured PATH hook`);
|
|
478
|
+
}
|
|
472
479
|
}
|
|
473
480
|
|
|
474
481
|
/**
|
|
@@ -654,6 +661,20 @@ async function install(isGlobal) {
|
|
|
654
661
|
}
|
|
655
662
|
}
|
|
656
663
|
|
|
664
|
+
// Phase 8b: Check uv
|
|
665
|
+
try {
|
|
666
|
+
const { execSync } = require('child_process');
|
|
667
|
+
const uvVersion = execSync('uv --version 2>&1', { encoding: 'utf8' }).trim();
|
|
668
|
+
console.log(` ${green}✓${reset} Found ${uvVersion}`);
|
|
669
|
+
} catch (e) {
|
|
670
|
+
const isWin = process.platform === 'win32';
|
|
671
|
+
const installCmd = isWin
|
|
672
|
+
? 'powershell -ExecutionPolicy ByPass -c "irm https://astral.sh/uv/install.ps1 | iex"'
|
|
673
|
+
: 'curl -LsSf https://astral.sh/uv/install.sh | sh';
|
|
674
|
+
console.log(` ${yellow}⚠${reset} uv not found — CLI wrappers (ms-tools, ms-compare-mockups) require it`);
|
|
675
|
+
console.log(` Install: ${cyan}${installCmd}${reset}`);
|
|
676
|
+
}
|
|
677
|
+
|
|
657
678
|
// Phase 9: Cleanup orphaned files
|
|
658
679
|
if (orphans.length > 0) {
|
|
659
680
|
console.log('');
|
package/commands/ms/doctor.md
CHANGED
|
@@ -13,7 +13,7 @@ allowed-tools:
|
|
|
13
13
|
---
|
|
14
14
|
|
|
15
15
|
<objective>
|
|
16
|
-
Run health checks on project configuration. Detect and fix structural drift across 10 categories: subsystem vocabulary, milestone directory structure, milestone naming convention, phase archival, knowledge files, phase summaries, PLAN cleanup, CLI wrappers, research API keys, and Mindsystem version.
|
|
16
|
+
Run health checks on project configuration. Detect and fix structural drift across 10 categories: subsystem vocabulary, milestone directory structure, milestone naming convention, phase archival, knowledge files, phase summaries, PLAN cleanup, CLI wrappers and environment diagnostics, research API keys, and Mindsystem version.
|
|
17
17
|
|
|
18
18
|
Idempotent.
|
|
19
19
|
</objective>
|
|
@@ -117,7 +117,7 @@ Display results as a markdown table:
|
|
|
117
117
|
| Knowledge files | FAIL | Directory missing |
|
|
118
118
|
| Phase summaries | FAIL | 2 milestones missing summaries |
|
|
119
119
|
| PLAN cleanup | FAIL | 9 leftover PLAN.md files |
|
|
120
|
-
| CLI wrappers | FAIL |
|
|
120
|
+
| CLI wrappers | FAIL | Not resolvable; bin dir not in PATH |
|
|
121
121
|
| Research API Keys | WARN | PERPLEXITY_API_KEY not set |
|
|
122
122
|
| Mindsystem version | WARN | v3.21.0 → v3.22.1 available |
|
|
123
123
|
```
|
|
@@ -143,7 +143,7 @@ If "Review each" → use AskUserQuestion for each failed check with its details
|
|
|
143
143
|
|
|
144
144
|
Apply fixes in dependency order: fix_subsystems → fix_milestone_dirs → fix_milestone_naming → fix_phase_archival → fix_plan_cleanup → fix_knowledge. Skip any fix whose check passed or was skipped by user.
|
|
145
145
|
|
|
146
|
-
Phase summaries are resolved by fix_phase_archival. CLI
|
|
146
|
+
Phase summaries are resolved by fix_phase_archival. CLI wrapper failures have specific fixes: bin dir not in PATH → restart Claude Code session; missing wrappers or bin dir → re-run `npx mindsystem-cc`; uv not found → `curl -LsSf https://astral.sh/uv/install.sh | sh`. WARN checks (Research API Keys, missing uv) are informational — no automated fix, only displayed in the report.
|
|
147
147
|
</step>
|
|
148
148
|
|
|
149
149
|
<step name="apply_fixes">
|
package/package.json
CHANGED
package/scripts/ms-tools.py
CHANGED
|
@@ -761,19 +761,67 @@ def cmd_doctor_scan(args: argparse.Namespace) -> None:
|
|
|
761
761
|
record("PASS", "PLAN Cleanup")
|
|
762
762
|
print()
|
|
763
763
|
|
|
764
|
-
# ---- CHECK 7: CLI Wrappers ----
|
|
764
|
+
# ---- CHECK 7: CLI Wrappers & Environment ----
|
|
765
765
|
print("=== CLI Wrappers ===")
|
|
766
766
|
wrapper_names = ["ms-tools", "ms-lookup", "ms-compare-mockups"]
|
|
767
|
-
|
|
768
|
-
|
|
767
|
+
|
|
768
|
+
# 7a: Check bin directory exists
|
|
769
|
+
global_bin = Path.home() / ".claude" / "bin"
|
|
770
|
+
local_bin = Path(".claude") / "bin"
|
|
771
|
+
bin_dir = global_bin if global_bin.is_dir() else (local_bin if local_bin.is_dir() else None)
|
|
772
|
+
|
|
773
|
+
if bin_dir is None:
|
|
769
774
|
print("Status: FAIL")
|
|
770
|
-
print(
|
|
771
|
-
print("Fix: re-run `npx mindsystem-cc` to
|
|
775
|
+
print("Bin directory not found (~/.claude/bin/ or .claude/bin/)")
|
|
776
|
+
print("Fix: re-run `npx mindsystem-cc` to generate wrappers")
|
|
772
777
|
record("FAIL", "CLI Wrappers")
|
|
773
778
|
else:
|
|
774
|
-
|
|
775
|
-
|
|
776
|
-
|
|
779
|
+
# 7b: Check wrapper files present
|
|
780
|
+
missing_files = [w for w in wrapper_names if not (bin_dir / w).exists()]
|
|
781
|
+
if missing_files:
|
|
782
|
+
print("Status: FAIL")
|
|
783
|
+
print(f"Wrapper files missing from {bin_dir}: {', '.join(missing_files)}")
|
|
784
|
+
print("Fix: re-run `npx mindsystem-cc` to regenerate wrappers")
|
|
785
|
+
record("FAIL", "CLI Wrappers")
|
|
786
|
+
else:
|
|
787
|
+
# 7c: Check bin dir in PATH
|
|
788
|
+
path_dirs = os.environ.get("PATH", "").split(os.pathsep)
|
|
789
|
+
bin_in_path = str(bin_dir.resolve()) in [os.path.realpath(p) for p in path_dirs]
|
|
790
|
+
|
|
791
|
+
# 7d: Check wrappers resolvable
|
|
792
|
+
missing_wrappers = [w for w in wrapper_names if shutil.which(w) is None]
|
|
793
|
+
|
|
794
|
+
if missing_wrappers:
|
|
795
|
+
print("Status: FAIL")
|
|
796
|
+
print(f"Not resolvable: {', '.join(missing_wrappers)}")
|
|
797
|
+
if not bin_in_path:
|
|
798
|
+
print(f"Cause: {bin_dir} not in PATH")
|
|
799
|
+
print("Fix: restart Claude Code session (PATH hook fires on SessionStart)")
|
|
800
|
+
else:
|
|
801
|
+
print("Fix: re-run `npx mindsystem-cc` to regenerate wrappers and PATH hook")
|
|
802
|
+
record("FAIL", "CLI Wrappers")
|
|
803
|
+
else:
|
|
804
|
+
print(f"All {len(wrapper_names)} CLI wrappers found on PATH")
|
|
805
|
+
|
|
806
|
+
# 7e: Check uv available
|
|
807
|
+
uv_ok = shutil.which("uv") is not None
|
|
808
|
+
# 7f: Check Python available
|
|
809
|
+
py_ok = shutil.which("python3") is not None or shutil.which("python") is not None
|
|
810
|
+
|
|
811
|
+
issues = []
|
|
812
|
+
if not uv_ok:
|
|
813
|
+
issues.append("uv not found — install: `curl -LsSf https://astral.sh/uv/install.sh | sh`")
|
|
814
|
+
if not py_ok:
|
|
815
|
+
issues.append("Python not found — install Python 3.10+")
|
|
816
|
+
|
|
817
|
+
if issues:
|
|
818
|
+
print("Status: WARN")
|
|
819
|
+
for issue in issues:
|
|
820
|
+
print(f" {issue}")
|
|
821
|
+
record("WARN", "CLI Wrappers")
|
|
822
|
+
else:
|
|
823
|
+
print("Status: PASS")
|
|
824
|
+
record("PASS", "CLI Wrappers")
|
|
777
825
|
print()
|
|
778
826
|
|
|
779
827
|
# ---- CHECK 8: Milestone Naming Convention ----
|