ultra-builder-pro-cli 0.26.2 → 3.0.2

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.
Files changed (67) hide show
  1. package/.ultra-template/contexts/TEMPLATE.md +64 -29
  2. package/.ultra-template/north-star.md +35 -18
  3. package/.ultra-template/tasks.json +1 -0
  4. package/.ultra-template/test-report.json +17 -1
  5. package/CHANGELOG.md +163 -1
  6. package/README.md +108 -38
  7. package/adapters/_shared/host-profile.cjs +68 -12
  8. package/adapters/_shared/plugin-core.cjs +4 -5
  9. package/adapters/_shared/runtime-assets.cjs +11 -2
  10. package/adapters/zcode.js +375 -0
  11. package/bin/delegate-worker.cjs +20 -0
  12. package/bin/delegate.cjs +94 -25
  13. package/bin/install.js +11 -6
  14. package/docs/ARCHITECTURE.md +84 -23
  15. package/docs/ARTIFACT-AUTHORITY.md +167 -22
  16. package/docs/DECISIONS.md +131 -17
  17. package/docs/PHILOSOPHY.md +58 -7
  18. package/docs/PLUGIN-ISOLATION-CONTRACT.md +6 -0
  19. package/docs/RUNTIME-COMPAT-MATRIX.md +106 -13
  20. package/docs/SKILL-AUTHORING.md +4 -3
  21. package/docs/WORKFLOW-LIFECYCLE.md +126 -28
  22. package/docs/evals/adversarial-review-2026-08-14.md +84 -0
  23. package/docs/evals/zcode-automation-2026-08-14.md +103 -0
  24. package/hooks/README.md +27 -4
  25. package/hooks/_common.py +1678 -61
  26. package/hooks/adapters/zcode.py +227 -0
  27. package/hooks/compact_context.py +176 -17
  28. package/hooks/mid_workflow_recall.py +27 -5
  29. package/hooks/post_edit_guard.py +133 -23
  30. package/hooks/session_context.py +707 -22
  31. package/package.json +6 -3
  32. package/skills/ultra-change/SKILL.md +40 -9
  33. package/skills/ultra-change/references/change-contract.md +93 -27
  34. package/skills/ultra-change/references/execution-grant.md +109 -0
  35. package/skills/ultra-change/references/primary-transfer.md +273 -0
  36. package/skills/ultra-change/scripts/validate_primary_transfer.cjs +1928 -0
  37. package/skills/ultra-delegate/SKILL.md +24 -2
  38. package/skills/ultra-delegate/references/delegation-contract.md +21 -1
  39. package/skills/ultra-deliver/SKILL.md +85 -11
  40. package/skills/ultra-dev/SKILL.md +171 -41
  41. package/skills/ultra-grilling/SKILL.md +10 -7
  42. package/skills/ultra-grilling/references/reframing.md +7 -3
  43. package/skills/ultra-init/SKILL.md +44 -7
  44. package/skills/ultra-init/scripts/init_project.cjs +968 -21
  45. package/skills/ultra-plan/SKILL.md +70 -44
  46. package/skills/ultra-plan/references/task-evidence-v2.md +300 -0
  47. package/skills/ultra-plan/scripts/validate_task_evidence.cjs +859 -0
  48. package/skills/ultra-research/SKILL.md +38 -10
  49. package/skills/ultra-research/references/04-product-strategy.md +11 -2
  50. package/skills/ultra-research/references/21-features-scope.md +8 -0
  51. package/skills/ultra-research/references/22-success-metrics.md +4 -3
  52. package/skills/ultra-research/references/99-synthesis.md +19 -2
  53. package/skills/ultra-research/references/north-star-v2.md +168 -0
  54. package/skills/ultra-research/references/wayfinding.md +8 -0
  55. package/skills/ultra-research/scripts/validate_north_star.cjs +1174 -0
  56. package/skills/ultra-review/SKILL.md +201 -27
  57. package/skills/ultra-review/references/adversarial-evaluation.md +31 -0
  58. package/skills/ultra-review/references/spec.md +5 -0
  59. package/skills/ultra-review/references/unified-schema.md +146 -11
  60. package/skills/ultra-review/references/worker-packet.md +151 -8
  61. package/skills/ultra-review/scripts/review_wait.py +2653 -63
  62. package/skills/ultra-status/SKILL.md +95 -11
  63. package/skills/ultra-tdd/SKILL.md +11 -4
  64. package/skills/ultra-tdd/references/test-execution.md +6 -1
  65. package/skills/ultra-test/SKILL.md +145 -17
  66. package/skills/ultra-test/scripts/validate_review_transport.cjs +549 -0
  67. package/skills/ultra-test/scripts/worktree_digest.cjs +518 -30
@@ -3,17 +3,21 @@
3
3
 
4
4
  from __future__ import annotations
5
5
 
6
- import json
7
6
  import re
8
7
  from datetime import datetime, timezone
9
8
  from pathlib import Path
10
9
 
11
10
  from _common import (
12
- current_task,
11
+ current_task_selection,
13
12
  emit_context,
14
- project_file,
13
+ normalized_task_id,
14
+ project_relative_path,
15
15
  project_root,
16
+ read_derived_json,
16
17
  read_payload,
18
+ read_stable_project_file_snapshot,
19
+ render_task_diagnostics,
20
+ task_sections,
17
21
  write_json_atomic,
18
22
  )
19
23
 
@@ -26,25 +30,59 @@ DIMENSIONS = (
26
30
  "vertical_slice",
27
31
  "spec_trace",
28
32
  )
33
+ PROGRESS_SNAPSHOT_MAX_BYTES = 1024 * 1024
34
+ TRACE_SOURCE_SNAPSHOT_MAX_BYTES = 8 * 1024 * 1024
29
35
 
30
36
 
31
37
  def slug(value: str) -> str:
32
38
  return re.sub(r"[^a-z0-9]+", "-", value.lower()).strip("-")
33
39
 
34
40
 
35
- def trace_observation(root: Path, task: dict) -> str:
41
+ def trace_observation(root: Path, task: dict):
36
42
  trace = task.get("trace_to")
37
43
  if not isinstance(trace, str) or "#" not in trace:
38
- return "missing"
44
+ return "missing", None
39
45
  name, anchor = trace.rsplit("#", 1)
40
- file = project_file(root, name, ultra_default=True)
41
- if file is None:
42
- return "missing"
46
+ relative = project_relative_path(name, ultra_default=True)
47
+ if relative is None:
48
+ return "missing", None
49
+ snapshot, failure = read_stable_project_file_snapshot(
50
+ root,
51
+ relative,
52
+ max_bytes=TRACE_SOURCE_SNAPSHOT_MAX_BYTES,
53
+ code_prefix="trace_source_snapshot",
54
+ label="Task trace source",
55
+ )
56
+ if snapshot is None or failure is not None:
57
+ diagnostic = dict(failure) if failure is not None else {
58
+ "code": "trace_source_snapshot_read_error",
59
+ "message": "Task trace source could not be observed.",
60
+ "path": str(root / relative),
61
+ }
62
+ diagnostic["repair"] = (
63
+ "Restore the trace source as one stable readable regular UTF-8 file and retry "
64
+ "PostToolUse; spec_trace remains missing until it is observed."
65
+ )
66
+ return "missing", diagnostic
43
67
  try:
44
- headings = re.findall(r"^#{1,6}\s+(.+?)\s*$", file.read_text(encoding="utf-8"), re.MULTILINE)
45
- except OSError:
46
- return "missing"
47
- return "observed" if slug(anchor) in {slug(heading) for heading in headings} else "missing"
68
+ text = snapshot["bytes"].decode("utf-8")
69
+ except UnicodeDecodeError:
70
+ return "missing", {
71
+ "code": "trace_source_snapshot_invalid_utf8",
72
+ "message": "Task trace source must be valid UTF-8 before it can be observed.",
73
+ "path": snapshot["path"],
74
+ "repair": (
75
+ "Restore the trace source as valid UTF-8 and retry PostToolUse; spec_trace "
76
+ "remains missing until it is observed."
77
+ ),
78
+ }
79
+ headings = re.findall(r"^#{1,6}\s+(.+?)\s*$", text, re.MULTILINE)
80
+ observation = (
81
+ "observed"
82
+ if slug(anchor) in {slug(heading) for heading in headings}
83
+ else "missing"
84
+ )
85
+ return observation, None
48
86
 
49
87
 
50
88
  def main() -> int:
@@ -52,8 +90,31 @@ def main() -> int:
52
90
  root = project_root(payload) # Idle guard: no `.ultra/` means silent exit.
53
91
  if root is None:
54
92
  return 0
55
- task = current_task(root)
93
+ selection = current_task_selection(root)
94
+ task = selection["task"]
56
95
  if not task:
96
+ diagnostics = render_task_diagnostics(selection["diagnostics"])
97
+ if diagnostics:
98
+ emit_context(
99
+ "PostToolUse",
100
+ "Ultra task selection diagnostic:\n" + diagnostics,
101
+ )
102
+ return 0
103
+ sections = task_sections(root, task)
104
+ if not sections["context_available"]:
105
+ context_diagnostics = [
106
+ diagnostic
107
+ for diagnostic in sections["diagnostics"]
108
+ if str(diagnostic.get("code") or "").startswith("task_context_")
109
+ ]
110
+ emit_context(
111
+ "PostToolUse",
112
+ "Ultra task context diagnostic:\n"
113
+ + render_task_diagnostics(context_diagnostics),
114
+ )
115
+ return 0
116
+ task_id = normalized_task_id(task.get("id"))
117
+ if task_id is None:
57
118
  return 0
58
119
  tool_input = payload.get("tool_input")
59
120
  tool_input = tool_input if isinstance(tool_input, dict) else {}
@@ -62,19 +123,39 @@ def main() -> int:
62
123
  if changed:
63
124
  try:
64
125
  relative = str(Path(changed).resolve().relative_to(root))
65
- except ValueError:
126
+ except (OSError, RuntimeError, ValueError):
66
127
  relative = ""
67
128
 
68
- file = root / ".ultra" / "progress" / f"{task.get('id')}.json"
69
- try:
70
- progress = json.loads(file.read_text(encoding="utf-8"))
71
- except (OSError, json.JSONDecodeError):
129
+ progress_relative = Path(".ultra") / "progress" / f"{task_id}.json"
130
+ progress, read_failure = read_derived_json(
131
+ root,
132
+ progress_relative,
133
+ max_bytes=PROGRESS_SNAPSHOT_MAX_BYTES,
134
+ code_prefix="progress_snapshot",
135
+ label="Task progress observation",
136
+ )
137
+ diagnostics = []
138
+ if read_failure is not None:
139
+ code = read_failure.get("code", "")
140
+ if code.endswith("_missing"):
141
+ progress = {}
142
+ elif code.endswith(("_invalid_utf8", "_invalid_json", "_invalid_root")):
143
+ diagnostics.append(read_failure)
144
+ progress = {}
145
+ else:
146
+ emit_context(
147
+ "PostToolUse",
148
+ "Ultra progress diagnostic:\n"
149
+ + render_task_diagnostics([read_failure]),
150
+ )
151
+ return 0
152
+ if progress is None:
72
153
  progress = {}
73
154
  if not isinstance(progress, dict):
74
155
  progress = {}
75
156
  existing_evidence = progress.get("evidence")
76
157
  existing_evidence = existing_evidence if isinstance(existing_evidence, dict) else {}
77
- progress["task_id"] = str(task.get("id"))
158
+ progress["task_id"] = task_id
78
159
  progress["evidence"] = {
79
160
  name: existing_evidence.get(name, "unknown")
80
161
  if isinstance(existing_evidence.get(name, "unknown"), str)
@@ -89,14 +170,43 @@ def main() -> int:
89
170
  progress["touched_files"].append(relative)
90
171
  if re.search(r"(?:^|/)(?:test|tests|__tests__)/|(?:\.test|\.spec)\.", relative, re.IGNORECASE):
91
172
  progress["evidence"]["tests_written"] = "observed"
92
- progress["evidence"]["spec_trace"] = trace_observation(root, task)
173
+ trace_value, trace_failure = trace_observation(root, task)
174
+ progress["evidence"]["spec_trace"] = trace_value
175
+ if trace_failure is not None:
176
+ diagnostics.append(trace_failure)
93
177
  progress["updated_at"] = datetime.now(timezone.utc).isoformat()
94
- write_json_atomic(file, progress)
178
+ write_failure = write_json_atomic(
179
+ root,
180
+ progress_relative,
181
+ progress,
182
+ max_bytes=PROGRESS_SNAPSHOT_MAX_BYTES,
183
+ code_prefix="progress_write",
184
+ label="Task progress observation",
185
+ )
186
+ if write_failure is not None:
187
+ diagnostics.append(write_failure)
188
+ emit_context(
189
+ "PostToolUse",
190
+ "Ultra progress diagnostic:\n"
191
+ + render_task_diagnostics(diagnostics),
192
+ )
193
+ return 0
95
194
 
96
- unknown = [name for name, value in progress["evidence"].items() if value == "unknown"]
195
+ non_observed = [
196
+ name
197
+ for name, value in progress["evidence"].items()
198
+ if value != "observed"
199
+ ]
200
+ parts = []
201
+ if diagnostics:
202
+ parts.append("Ultra progress diagnostic:\n" + render_task_diagnostics(diagnostics))
203
+ parts.append(
204
+ f"Ultra evidence sensor updated task {task_id}. Still non-observed: "
205
+ f"{', '.join(non_observed) or 'none'}."
206
+ )
97
207
  emit_context(
98
208
  "PostToolUse",
99
- f"Ultra evidence sensor updated task {task.get('id')}. Still unobserved: {', '.join(unknown) or 'none'}.",
209
+ "\n\n".join(parts),
100
210
  )
101
211
  return 0
102
212