its-magic 0.1.2-37 → 0.1.2-39
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/installer.ps1 +20 -0
- package/installer.py +66 -2
- package/installer.sh +22 -0
- package/package.json +2 -1
- package/scripts/check_intake_template_parity.py +1 -0
- package/scripts/intake_evidence_lib.py +413 -10
- package/scripts/intake_evidence_validate.py +2 -2
- package/scripts/materialize_codebase_map.py +184 -0
- package/template/.cursor/agents/po.mdc +19 -0
- package/template/.cursor/commands/architecture.md +12 -0
- package/template/.cursor/commands/ask.md +11 -0
- package/template/.cursor/commands/auto.md +20 -2
- package/template/.cursor/commands/intake.md +64 -9
- package/template/.cursor/commands/map-codebase.md +18 -1
- package/template/.cursor/commands/refresh-context.md +7 -0
- package/template/.cursor/rules/core.mdc +5 -0
- package/template/docs/engineering/artifact-ownership-policy.md +1 -1
- package/template/docs/engineering/context/installer-owned-paths.manifest +17 -0
- package/template/docs/engineering/runbook.md +76 -2
- package/template/scripts/check_intake_template_parity.py +1 -0
- package/template/scripts/enforce-triad-hot-surface.py +626 -0
- package/template/scripts/intake_bug_resume_brief_refresh.py +303 -0
- package/template/scripts/intake_evidence_lib.py +413 -10
- package/template/scripts/intake_evidence_validate.py +2 -2
- package/template/scripts/materialize_codebase_map.py +184 -0
package/installer.ps1
CHANGED
|
@@ -405,6 +405,24 @@ function Invoke-ScratchpadPostinstall {
|
|
|
405
405
|
if ($LASTEXITCODE -ne 0) { exit $LASTEXITCODE }
|
|
406
406
|
}
|
|
407
407
|
|
|
408
|
+
function Invoke-InstallCompletenessValidation {
|
|
409
|
+
param(
|
|
410
|
+
[string]$TargetRoot
|
|
411
|
+
)
|
|
412
|
+
$installerPy = Join-Path $scriptDir "installer.py"
|
|
413
|
+
if (-not (Test-Path $installerPy -PathType Leaf)) {
|
|
414
|
+
Write-Host "[INSTALL_COMPLETENESS_FAILED] installer.py missing next to installer.ps1."
|
|
415
|
+
exit 1
|
|
416
|
+
}
|
|
417
|
+
$py = Get-Command python -ErrorAction SilentlyContinue
|
|
418
|
+
if (-not $py) {
|
|
419
|
+
Write-Host "[INSTALL_COMPLETENESS_FAILED] PYTHON_NOT_FOUND: Python is required for deterministic installer completeness validation."
|
|
420
|
+
exit 1
|
|
421
|
+
}
|
|
422
|
+
& python $installerPy --validate-install-completeness --target $TargetRoot
|
|
423
|
+
if ($LASTEXITCODE -ne 0) { exit $LASTEXITCODE }
|
|
424
|
+
}
|
|
425
|
+
|
|
408
426
|
function Show-ItsMagicBanner([switch]$IncludeInstallMessage) {
|
|
409
427
|
$prev = [Console]::OutputEncoding
|
|
410
428
|
[Console]::OutputEncoding = [System.Text.Encoding]::UTF8
|
|
@@ -643,6 +661,7 @@ if ($mode -eq "upgrade") {
|
|
|
643
661
|
}
|
|
644
662
|
|
|
645
663
|
Invoke-ScratchpadPostinstall -TargetRoot $targetRoot -Mode "upgrade"
|
|
664
|
+
Invoke-InstallCompletenessValidation -TargetRoot $targetRoot
|
|
646
665
|
|
|
647
666
|
Write-InstalledVersion $targetRoot $appVersion
|
|
648
667
|
Sync-RootReadmeToItsMagic $targetRoot | Out-Null
|
|
@@ -724,6 +743,7 @@ foreach ($rel in $files) {
|
|
|
724
743
|
}
|
|
725
744
|
|
|
726
745
|
Invoke-ScratchpadPostinstall -TargetRoot $targetRoot -Mode $mode
|
|
746
|
+
Invoke-InstallCompletenessValidation -TargetRoot $targetRoot
|
|
727
747
|
|
|
728
748
|
Write-InstalledVersion $targetRoot $appVersion
|
|
729
749
|
Sync-RootReadmeToItsMagic $targetRoot | Out-Null
|
package/installer.py
CHANGED
|
@@ -11,6 +11,7 @@ from datetime import datetime
|
|
|
11
11
|
|
|
12
12
|
REPO_URL = "https://github.com/fl0wm0ti0n/its-magic"
|
|
13
13
|
MANIFEST_RELATIVE_PATH = os.path.join("docs", "engineering", "context", "installer-owned-paths.manifest")
|
|
14
|
+
MANIFEST_REQUIRED_SCRIPTS_SECTION = "required_install_script_paths"
|
|
14
15
|
|
|
15
16
|
|
|
16
17
|
def normalize(path):
|
|
@@ -67,12 +68,42 @@ def load_ownership_manifest(source_root, script_dir):
|
|
|
67
68
|
continue
|
|
68
69
|
install_paths = read_manifest_paths(path, "install_include_paths")
|
|
69
70
|
clean_paths = read_manifest_paths(path, "clean_paths")
|
|
71
|
+
required_script_paths = read_manifest_paths(path, MANIFEST_REQUIRED_SCRIPTS_SECTION)
|
|
70
72
|
if not install_paths or not clean_paths:
|
|
71
73
|
raise RuntimeError(f"[INSTALL_MANIFEST_ERROR] {path} is missing required sections or entries.")
|
|
72
|
-
|
|
74
|
+
if not required_script_paths:
|
|
75
|
+
raise RuntimeError(
|
|
76
|
+
f"[INSTALL_MANIFEST_ERROR] {path} is missing [{MANIFEST_REQUIRED_SCRIPTS_SECTION}] entries."
|
|
77
|
+
)
|
|
78
|
+
return install_paths, clean_paths, required_script_paths, path
|
|
73
79
|
raise RuntimeError("[INSTALL_SOURCE_ERROR] installer-owned-paths.manifest not found. Reinstall its-magic package.")
|
|
74
80
|
|
|
75
81
|
|
|
82
|
+
def validate_install_completeness(target_root, source_root, required_script_paths, manifest_path):
|
|
83
|
+
missing_paths = []
|
|
84
|
+
for rel in sorted(set(required_script_paths)):
|
|
85
|
+
src = os.path.join(source_root, rel)
|
|
86
|
+
dst = os.path.join(target_root, rel)
|
|
87
|
+
if not os.path.isfile(src) or not os.path.isfile(dst):
|
|
88
|
+
missing_paths.append(rel.replace("\\", "/"))
|
|
89
|
+
if not missing_paths:
|
|
90
|
+
return True
|
|
91
|
+
print(
|
|
92
|
+
"[INSTALL_COMPLETENESS_FAILED] Required installer scripts are missing after "
|
|
93
|
+
"copy/classification invariant check."
|
|
94
|
+
)
|
|
95
|
+
for rel in missing_paths:
|
|
96
|
+
print(f"[INSTALL_REQUIRED_SCRIPT_MISSING:{rel}]")
|
|
97
|
+
print(
|
|
98
|
+
"Fix: update manifest parity and required-script inventory at "
|
|
99
|
+
f"{MANIFEST_RELATIVE_PATH} (section [{MANIFEST_REQUIRED_SCRIPTS_SECTION}]), "
|
|
100
|
+
"ensure each listed script exists in template/scripts and clean-path ownership, "
|
|
101
|
+
"then rerun installer missing/upgrade."
|
|
102
|
+
)
|
|
103
|
+
print(f"Manifest source: {manifest_path}")
|
|
104
|
+
return False
|
|
105
|
+
|
|
106
|
+
|
|
76
107
|
def ensure_parent(path):
|
|
77
108
|
parent = os.path.dirname(path)
|
|
78
109
|
if parent and not os.path.isdir(parent):
|
|
@@ -684,6 +715,12 @@ def main():
|
|
|
684
715
|
action="store_true",
|
|
685
716
|
help=argparse.SUPPRESS,
|
|
686
717
|
)
|
|
718
|
+
parser.add_argument("--source-root", help=argparse.SUPPRESS)
|
|
719
|
+
parser.add_argument(
|
|
720
|
+
"--validate-install-completeness",
|
|
721
|
+
action="store_true",
|
|
722
|
+
help=argparse.SUPPRESS,
|
|
723
|
+
)
|
|
687
724
|
args = parser.parse_args()
|
|
688
725
|
|
|
689
726
|
if len(sys.argv) == 1 or args.help:
|
|
@@ -694,6 +731,9 @@ def main():
|
|
|
694
731
|
print(f"its-magic v{version}")
|
|
695
732
|
return 0
|
|
696
733
|
|
|
734
|
+
if args.source_root:
|
|
735
|
+
source_root = normalize(args.source_root)
|
|
736
|
+
|
|
697
737
|
if args.scratchpad_postinstall:
|
|
698
738
|
target_root = normalize(args.target) if args.target else normalize(".")
|
|
699
739
|
mode = args.mode or "missing"
|
|
@@ -712,11 +752,31 @@ def main():
|
|
|
712
752
|
ok = run_scratchpad_postinstall(target_root, source_root, mode, print_ok=True)
|
|
713
753
|
return 0 if ok else 1
|
|
714
754
|
|
|
755
|
+
if args.validate_install_completeness:
|
|
756
|
+
target_root = normalize(args.target) if args.target else normalize(".")
|
|
757
|
+
if not os.path.isdir(target_root):
|
|
758
|
+
print(f"[INSTALL_COMPLETENESS_FAILED] target directory missing: {target_root}")
|
|
759
|
+
return 1
|
|
760
|
+
if not os.path.isdir(source_root):
|
|
761
|
+
print("[INSTALL_SOURCE_ERROR] template directory is missing. Reinstall its-magic package.")
|
|
762
|
+
return 1
|
|
763
|
+
try:
|
|
764
|
+
_install_paths, _clean_paths, required_script_paths, manifest_path = load_ownership_manifest(
|
|
765
|
+
source_root, script_dir
|
|
766
|
+
)
|
|
767
|
+
except RuntimeError as exc:
|
|
768
|
+
print(str(exc))
|
|
769
|
+
return 1
|
|
770
|
+
ok = validate_install_completeness(target_root, source_root, required_script_paths, manifest_path)
|
|
771
|
+
return 0 if ok else 1
|
|
772
|
+
|
|
715
773
|
if not os.path.isdir(source_root):
|
|
716
774
|
print("[INSTALL_SOURCE_ERROR] template directory is missing. Reinstall its-magic package.")
|
|
717
775
|
return 1
|
|
718
776
|
try:
|
|
719
|
-
include_paths, clean_paths = load_ownership_manifest(
|
|
777
|
+
include_paths, clean_paths, required_script_paths, manifest_path = load_ownership_manifest(
|
|
778
|
+
source_root, script_dir
|
|
779
|
+
)
|
|
720
780
|
except RuntimeError as exc:
|
|
721
781
|
print(str(exc))
|
|
722
782
|
return 1
|
|
@@ -818,6 +878,8 @@ def main():
|
|
|
818
878
|
|
|
819
879
|
if not run_scratchpad_postinstall(target_root, source_root, "upgrade", print_ok=True):
|
|
820
880
|
return 1
|
|
881
|
+
if not validate_install_completeness(target_root, source_root, required_script_paths, manifest_path):
|
|
882
|
+
return 1
|
|
821
883
|
|
|
822
884
|
write_installed_version(target_root, version)
|
|
823
885
|
sync_root_readme_to_its_magic(target_root)
|
|
@@ -896,6 +958,8 @@ def main():
|
|
|
896
958
|
|
|
897
959
|
if not run_scratchpad_postinstall(target_root, source_root, mode, print_ok=True):
|
|
898
960
|
return 1
|
|
961
|
+
if not validate_install_completeness(target_root, source_root, required_script_paths, manifest_path):
|
|
962
|
+
return 1
|
|
899
963
|
|
|
900
964
|
write_installed_version(target_root, version)
|
|
901
965
|
sync_root_readme_to_its_magic(target_root)
|
package/installer.sh
CHANGED
|
@@ -1,6 +1,9 @@
|
|
|
1
1
|
#!/usr/bin/env sh
|
|
2
2
|
set -e
|
|
3
3
|
|
|
4
|
+
# BUG-0004: keep startup shell options POSIX-safe for /bin/sh execution.
|
|
5
|
+
# Do not use bash-only "set" flags in this unconditional startup path.
|
|
6
|
+
|
|
4
7
|
SCRIPT_DIR=$(cd "$(dirname "$0")" && pwd)
|
|
5
8
|
SOURCE_ROOT="$SCRIPT_DIR/template"
|
|
6
9
|
MANIFEST_NAME="docs/engineering/context/installer-owned-paths.manifest"
|
|
@@ -151,6 +154,23 @@ scratchpad_postinstall() {
|
|
|
151
154
|
fi
|
|
152
155
|
}
|
|
153
156
|
|
|
157
|
+
validate_install_completeness() {
|
|
158
|
+
target_root="$1"
|
|
159
|
+
installer_py="$SCRIPT_DIR/installer.py"
|
|
160
|
+
if [ ! -f "$installer_py" ]; then
|
|
161
|
+
printf "%s\n" "[INSTALL_COMPLETENESS_FAILED] installer.py missing next to installer.sh."
|
|
162
|
+
exit 1
|
|
163
|
+
fi
|
|
164
|
+
if command -v python3 >/dev/null 2>&1; then
|
|
165
|
+
python3 "$installer_py" --validate-install-completeness --target "$target_root" || exit $?
|
|
166
|
+
elif command -v python >/dev/null 2>&1; then
|
|
167
|
+
python "$installer_py" --validate-install-completeness --target "$target_root" || exit $?
|
|
168
|
+
else
|
|
169
|
+
printf "%s\n" "[INSTALL_COMPLETENESS_FAILED] PYTHON_NOT_FOUND: Python is required for deterministic installer completeness validation."
|
|
170
|
+
exit 1
|
|
171
|
+
fi
|
|
172
|
+
}
|
|
173
|
+
|
|
154
174
|
classify_file() {
|
|
155
175
|
rel="$1"
|
|
156
176
|
case "$rel" in
|
|
@@ -535,6 +555,7 @@ if [ "$MODE" = "upgrade" ]; then
|
|
|
535
555
|
done
|
|
536
556
|
|
|
537
557
|
scratchpad_postinstall "$TARGET_ROOT" "upgrade"
|
|
558
|
+
validate_install_completeness "$TARGET_ROOT"
|
|
538
559
|
|
|
539
560
|
write_installed_version "$TARGET_ROOT" "$APP_VERSION"
|
|
540
561
|
sync_root_readme_to_its_magic "$TARGET_ROOT" || true
|
|
@@ -606,6 +627,7 @@ for rel in $FILES; do
|
|
|
606
627
|
done
|
|
607
628
|
|
|
608
629
|
scratchpad_postinstall "$TARGET_ROOT" "$MODE"
|
|
630
|
+
validate_install_completeness "$TARGET_ROOT"
|
|
609
631
|
|
|
610
632
|
write_installed_version "$TARGET_ROOT" "$APP_VERSION"
|
|
611
633
|
sync_root_readme_to_its_magic "$TARGET_ROOT" || true
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "its-magic",
|
|
3
|
-
"version": "0.1.2-
|
|
3
|
+
"version": "0.1.2-39",
|
|
4
4
|
"description": "its-magic - AI dev team workflow for Cursor.",
|
|
5
5
|
"license": "MIT",
|
|
6
6
|
"bin": {
|
|
@@ -16,6 +16,7 @@
|
|
|
16
16
|
"scripts/intake_evidence_lib.py",
|
|
17
17
|
"scripts/intake_bug_routing_guard.py",
|
|
18
18
|
"scripts/check_intake_template_parity.py",
|
|
19
|
+
"scripts/materialize_codebase_map.py",
|
|
19
20
|
"bin/its-magic.js",
|
|
20
21
|
"bin/postinstall.js"
|
|
21
22
|
],
|
|
@@ -12,6 +12,7 @@ INTAKE_TEMPLATE_PAIRS: tuple[tuple[str, str], ...] = (
|
|
|
12
12
|
("scripts/intake_evidence_validate.py", "template/scripts/intake_evidence_validate.py"),
|
|
13
13
|
("scripts/intake_evidence_lib.py", "template/scripts/intake_evidence_lib.py"),
|
|
14
14
|
("scripts/intake_bug_routing_guard.py", "template/scripts/intake_bug_routing_guard.py"),
|
|
15
|
+
("scripts/intake_bug_resume_brief_refresh.py", "template/scripts/intake_bug_resume_brief_refresh.py"),
|
|
15
16
|
("scripts/check_intake_template_parity.py", "template/scripts/check_intake_template_parity.py"),
|
|
16
17
|
)
|
|
17
18
|
|