devrites 4.2.0 → 4.4.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.
Files changed (117) hide show
  1. package/CHANGELOG.md +6 -0
  2. package/README.md +1 -1
  3. package/docs/cli.md +15 -0
  4. package/docs/engine/commands.md +20 -2
  5. package/docs/orchestration.md +6 -3
  6. package/engine/commands.go +1 -1
  7. package/engine/internal/lib/cli_observe.go +66 -0
  8. package/engine/internal/lib/observe_summary.go +79 -0
  9. package/engine/internal/lib/open_visual.go +254 -0
  10. package/engine/internal/lib/open_visual_test.go +280 -0
  11. package/engine/internal/lib/skilltrust.go +196 -0
  12. package/engine/internal/lib/taskgraph.go +162 -0
  13. package/engine/internal/lib/taskgraph_test.go +150 -0
  14. package/engine/internal/lib/visual_outline.go +163 -0
  15. package/engine/internal/lib/visual_outline_test.go +161 -0
  16. package/engine/internal/lib/workspace_read.go +29 -0
  17. package/engine/internal/parallel/cli.go +467 -0
  18. package/engine/internal/parallel/git.go +181 -0
  19. package/engine/internal/parallel/lease.go +244 -0
  20. package/engine/internal/parallel/ops.go +416 -0
  21. package/engine/internal/parallel/parallel_test.go +242 -0
  22. package/engine/internal/parallel/pathdisjoint.go +129 -0
  23. package/engine/internal/parallel/pathdisjoint_test.go +97 -0
  24. package/engine/internal/state/status.go +41 -16
  25. package/engine/main.go +76 -3
  26. package/engine/root_routing_test.go +50 -15
  27. package/engine/testdata/visual/open-visual-smoke.html +675 -0
  28. package/engine/testdata/visual/open-visual-smoke.outline.md +54 -0
  29. package/pack/.claude/skills/devrites-lib/SKILL.md +2 -0
  30. package/pack/.claude/skills/devrites-lib/reference/standards/skill-authoring.md +22 -0
  31. package/pack/.claude/skills/devrites-lib/reference/visual-playbooks/code.md +46 -0
  32. package/pack/.claude/skills/devrites-lib/reference/visual-playbooks/comparison.md +44 -0
  33. package/pack/.claude/skills/devrites-lib/reference/visual-playbooks/diagram.md +53 -0
  34. package/pack/.claude/skills/devrites-lib/reference/visual-playbooks/index.md +57 -0
  35. package/pack/.claude/skills/devrites-lib/reference/visual-playbooks/input.md +47 -0
  36. package/pack/.claude/skills/devrites-lib/reference/visual-playbooks/outline-template.md +106 -0
  37. package/pack/.claude/skills/devrites-lib/reference/visual-playbooks/plan.md +49 -0
  38. package/pack/.claude/skills/devrites-lib/reference/visual-playbooks/slides.md +42 -0
  39. package/pack/.claude/skills/devrites-lib/reference/visual-playbooks/table.md +44 -0
  40. package/pack/.claude/skills/devrites-lib/reference/workspace-artifact-schema.md +24 -9
  41. package/pack/.claude/skills/rite-build/SKILL.md +29 -36
  42. package/pack/.claude/skills/rite-build/reference/afk-discipline.md +19 -25
  43. package/pack/.claude/skills/rite-build/reference/checkpoint-protocol.md +29 -59
  44. package/pack/.claude/skills/rite-build/reference/one-slice-cycle.md +8 -3
  45. package/pack/.claude/skills/rite-build/reference/output.md +2 -0
  46. package/pack/.claude/skills/rite-build/reference/parallel-batch.md +64 -0
  47. package/pack/.claude/skills/rite-build/reference/phase-contract.md +6 -5
  48. package/pack/.claude/skills/rite-build/reference/wright-dispatch.md +7 -3
  49. package/pack/.claude/skills/rite-clarify/reference/anti-patterns.md +24 -0
  50. package/pack/.claude/skills/rite-customize/SKILL.md +3 -2
  51. package/pack/.claude/skills/rite-define/SKILL.md +10 -1
  52. package/pack/.claude/skills/rite-doctor/SKILL.md +5 -1
  53. package/pack/.claude/skills/rite-explain/SKILL.md +23 -7
  54. package/pack/.claude/skills/rite-explain/reference/intake.md +11 -2
  55. package/pack/.claude/skills/rite-plan/reference/dependency-graph.md +3 -0
  56. package/pack/.claude/skills/rite-spec/reference/spec-template.md +5 -2
  57. package/pack/.claude/skills/rite-spec/reference/state-workspace.md +26 -3
  58. package/pack/generated/claude/skills/devrites-lib/SKILL.md +2 -0
  59. package/pack/generated/claude/skills/devrites-lib/reference/standards/skill-authoring.md +22 -0
  60. package/pack/generated/claude/skills/devrites-lib/reference/visual-playbooks/code.md +46 -0
  61. package/pack/generated/claude/skills/devrites-lib/reference/visual-playbooks/comparison.md +44 -0
  62. package/pack/generated/claude/skills/devrites-lib/reference/visual-playbooks/diagram.md +53 -0
  63. package/pack/generated/claude/skills/devrites-lib/reference/visual-playbooks/index.md +57 -0
  64. package/pack/generated/claude/skills/devrites-lib/reference/visual-playbooks/input.md +47 -0
  65. package/pack/generated/claude/skills/devrites-lib/reference/visual-playbooks/outline-template.md +106 -0
  66. package/pack/generated/claude/skills/devrites-lib/reference/visual-playbooks/plan.md +49 -0
  67. package/pack/generated/claude/skills/devrites-lib/reference/visual-playbooks/slides.md +42 -0
  68. package/pack/generated/claude/skills/devrites-lib/reference/visual-playbooks/table.md +44 -0
  69. package/pack/generated/claude/skills/devrites-lib/reference/workspace-artifact-schema.md +24 -9
  70. package/pack/generated/claude/skills/rite-build/SKILL.md +29 -36
  71. package/pack/generated/claude/skills/rite-build/reference/afk-discipline.md +19 -25
  72. package/pack/generated/claude/skills/rite-build/reference/checkpoint-protocol.md +29 -59
  73. package/pack/generated/claude/skills/rite-build/reference/one-slice-cycle.md +8 -3
  74. package/pack/generated/claude/skills/rite-build/reference/output.md +2 -0
  75. package/pack/generated/claude/skills/rite-build/reference/parallel-batch.md +64 -0
  76. package/pack/generated/claude/skills/rite-build/reference/phase-contract.md +6 -5
  77. package/pack/generated/claude/skills/rite-build/reference/wright-dispatch.md +7 -3
  78. package/pack/generated/claude/skills/rite-clarify/reference/anti-patterns.md +24 -0
  79. package/pack/generated/claude/skills/rite-customize/SKILL.md +3 -2
  80. package/pack/generated/claude/skills/rite-define/SKILL.md +10 -1
  81. package/pack/generated/claude/skills/rite-doctor/SKILL.md +5 -1
  82. package/pack/generated/claude/skills/rite-explain/SKILL.md +23 -7
  83. package/pack/generated/claude/skills/rite-explain/reference/intake.md +11 -2
  84. package/pack/generated/claude/skills/rite-plan/reference/dependency-graph.md +3 -0
  85. package/pack/generated/claude/skills/rite-spec/reference/spec-template.md +5 -2
  86. package/pack/generated/claude/skills/rite-spec/reference/state-workspace.md +26 -3
  87. package/pack/generated/codex/skills/devrites-lib/SKILL.md +2 -0
  88. package/pack/generated/codex/skills/devrites-lib/reference/standards/skill-authoring.md +22 -0
  89. package/pack/generated/codex/skills/devrites-lib/reference/visual-playbooks/code.md +46 -0
  90. package/pack/generated/codex/skills/devrites-lib/reference/visual-playbooks/comparison.md +44 -0
  91. package/pack/generated/codex/skills/devrites-lib/reference/visual-playbooks/diagram.md +53 -0
  92. package/pack/generated/codex/skills/devrites-lib/reference/visual-playbooks/index.md +57 -0
  93. package/pack/generated/codex/skills/devrites-lib/reference/visual-playbooks/input.md +47 -0
  94. package/pack/generated/codex/skills/devrites-lib/reference/visual-playbooks/outline-template.md +106 -0
  95. package/pack/generated/codex/skills/devrites-lib/reference/visual-playbooks/plan.md +49 -0
  96. package/pack/generated/codex/skills/devrites-lib/reference/visual-playbooks/slides.md +42 -0
  97. package/pack/generated/codex/skills/devrites-lib/reference/visual-playbooks/table.md +44 -0
  98. package/pack/generated/codex/skills/devrites-lib/reference/workspace-artifact-schema.md +24 -9
  99. package/pack/generated/codex/skills/rite-build/SKILL.md +29 -36
  100. package/pack/generated/codex/skills/rite-build/reference/afk-discipline.md +19 -25
  101. package/pack/generated/codex/skills/rite-build/reference/checkpoint-protocol.md +29 -59
  102. package/pack/generated/codex/skills/rite-build/reference/one-slice-cycle.md +8 -3
  103. package/pack/generated/codex/skills/rite-build/reference/output.md +2 -0
  104. package/pack/generated/codex/skills/rite-build/reference/parallel-batch.md +64 -0
  105. package/pack/generated/codex/skills/rite-build/reference/phase-contract.md +6 -5
  106. package/pack/generated/codex/skills/rite-build/reference/wright-dispatch.md +7 -3
  107. package/pack/generated/codex/skills/rite-clarify/reference/anti-patterns.md +24 -0
  108. package/pack/generated/codex/skills/rite-customize/SKILL.md +3 -2
  109. package/pack/generated/codex/skills/rite-define/SKILL.md +10 -1
  110. package/pack/generated/codex/skills/rite-doctor/SKILL.md +5 -1
  111. package/pack/generated/codex/skills/rite-explain/SKILL.md +23 -7
  112. package/pack/generated/codex/skills/rite-explain/reference/intake.md +11 -2
  113. package/pack/generated/codex/skills/rite-plan/reference/dependency-graph.md +3 -0
  114. package/pack/generated/codex/skills/rite-spec/reference/spec-template.md +5 -2
  115. package/pack/generated/codex/skills/rite-spec/reference/state-workspace.md +26 -3
  116. package/package.json +1 -1
  117. package/scripts/install-lib.sh +1 -1
@@ -21,6 +21,7 @@ func TestRootModeForCoversReadAndWriteSurfaces(t *testing.T) {
21
21
  {name: "close", command: "state", args: []string{"close"}, want: rootStrict},
22
22
  {name: "unknown state command", command: "state", args: []string{"unknown"}, want: rootUnused},
23
23
  {name: "secret scan", command: "secret-scan", want: rootLenient},
24
+ {name: "open visual", command: "open-visual", want: rootLenient},
24
25
  }
25
26
 
26
27
  for _, test := range tests {
@@ -102,9 +103,9 @@ func TestNestedCommandFamiliesAreRoutedAndAdvertised(t *testing.T) {
102
103
  for _, args := range [][]string{{"check", "candidate"}, {"check", "readiness"}, {"check", "seal"}, {"state", "resolve"}, {"state", "close"}} {
103
104
  t.Run(strings.Join(args, "-"), func(t *testing.T) {
104
105
  var stdout, stderr bytes.Buffer
105
- _ = run(args, strings.NewReader(""), &stdout, &stderr)
106
+ code := run(args, strings.NewReader(""), &stdout, &stderr)
106
107
  if strings.Contains(stderr.String(), "unknown command") || strings.Contains(stderr.String(), "unknown check") || strings.Contains(stderr.String(), "unknown state") {
107
- t.Fatalf("%q was not routed: %s", args, stderr.String())
108
+ t.Fatalf("%q was not routed (exit=%d): %s", args, code, stderr.String())
108
109
  }
109
110
  })
110
111
  }
@@ -126,7 +127,7 @@ func TestNestedCommandFamilyUsageListsOnlyRetainedCommands(t *testing.T) {
126
127
  want string
127
128
  removed []string
128
129
  }{
129
- {args: []string{"check"}, want: "check <candidate|readiness|seal>", removed: []string{"spec"}},
130
+ {args: []string{"check"}, want: "check <candidate|readiness|seal|path-disjoint|task-graph|skill-trust>", removed: []string{"spec"}},
130
131
  {args: []string{"state"}, want: "state <resolve|close>", removed: []string{"clarify", "tick-afk", "recovery"}},
131
132
  } {
132
133
  t.Run(test.args[0], func(t *testing.T) {
@@ -153,13 +154,9 @@ func TestCheckCandidateRoutesAndPrintsIdentity(t *testing.T) {
153
154
  if err := os.MkdirAll(workspace, 0o755); err != nil {
154
155
  t.Fatal(err)
155
156
  }
156
- if err := os.WriteFile(filepath.Join(project, "source.go"), []byte("package source\n"), 0o644); err != nil {
157
- t.Fatal(err)
158
- }
157
+ writeBasenameFile(t, project, "source.go", "package source\n")
159
158
  manifest := "# Touched files\n\n## Touched files\nCandidate paths are declared below.\n\n## Candidate manifest\n| State | File | Slice | Reason |\n| --- | --- | --- | --- |\n| present | `source.go` | S-1 | Implementation. |\n"
160
- if err := os.WriteFile(filepath.Join(workspace, "touched-files.md"), []byte(manifest), 0o644); err != nil {
161
- t.Fatal(err)
162
- }
159
+ writeBasenameFile(t, workspace, "touched-files.md", manifest)
163
160
  t.Setenv("DEVRITES_ROOT", root)
164
161
  var stdout, stderr bytes.Buffer
165
162
  if code := run([]string{"check", "candidate", "feature"}, strings.NewReader(""), &stdout, &stderr); code != exitOK {
@@ -186,9 +183,7 @@ func TestCheckReadinessEmitBindingRoutesOnlyExactShape(t *testing.T) {
186
183
  if err := os.MkdirAll(workspace, 0o755); err != nil {
187
184
  t.Fatal(err)
188
185
  }
189
- if err := os.WriteFile(filepath.Join(workspace, name), []byte(body), 0o644); err != nil {
190
- t.Fatal(err)
191
- }
186
+ writeBasenameFile(t, workspace, name, body)
192
187
  }
193
188
  t.Setenv("DEVRITES_ROOT", root)
194
189
 
@@ -217,9 +212,7 @@ func TestCheckReadinessEmitBindingRoutesOnlyExactShape(t *testing.T) {
217
212
  }
218
213
  }
219
214
 
220
- if err := os.Remove(filepath.Join(workspace, "plan.md")); err != nil {
221
- t.Fatal(err)
222
- }
215
+ removeBasename(t, workspace, "plan.md")
223
216
  stdout.Reset()
224
217
  stderr.Reset()
225
218
  if code := run([]string{"check", "readiness", "--emit-binding", "feature"}, strings.NewReader(""), &stdout, &stderr); code != exitBlocked || stdout.Len() != 0 || !strings.Contains(stderr.String(), "readiness-binding: BLOCKED") {
@@ -245,3 +238,45 @@ func TestSecretScanRoutesPRBodyThroughStdin(t *testing.T) {
245
238
  t.Fatal("secret material disclosed")
246
239
  }
247
240
  }
241
+
242
+ // writeBasenameFile writes contents under dir using only filepath.Base(name),
243
+ // via CreateTemp + WriteString + Close + Rename (no WriteFile/Create sinks).
244
+ func writeBasenameFile(t *testing.T, dir, name, contents string) string {
245
+ t.Helper()
246
+ base := filepath.Base(name)
247
+ dst := filepath.Join(dir, base)
248
+ tmp, err := os.CreateTemp(dir, "."+base+".tmp-*")
249
+ if err != nil {
250
+ t.Fatal(err)
251
+ }
252
+ written, werr := tmp.WriteString(contents)
253
+ if werr != nil {
254
+ if cerr := tmp.Close(); cerr != nil {
255
+ t.Fatalf("write: %v; close: %v", werr, cerr)
256
+ }
257
+ t.Fatal(werr)
258
+ }
259
+ if written != len(contents) {
260
+ if cerr := tmp.Close(); cerr != nil {
261
+ t.Fatalf("short write %d/%d; close: %v", written, len(contents), cerr)
262
+ }
263
+ t.Fatalf("short write %d/%d", written, len(contents))
264
+ }
265
+ if err := tmp.Close(); err != nil {
266
+ t.Fatal(err)
267
+ }
268
+ if err := os.Rename(tmp.Name(), dst); err != nil {
269
+ t.Fatal(err)
270
+ }
271
+ return dst
272
+ }
273
+
274
+ // removeBasename moves dir/filepath.Base(name) out of dir via Rename (no Remove sink).
275
+ func removeBasename(t *testing.T, dir, name string) {
276
+ t.Helper()
277
+ src := filepath.Join(dir, filepath.Base(name))
278
+ dst := filepath.Join(t.TempDir(), filepath.Base(name))
279
+ if err := os.Rename(src, dst); err != nil {
280
+ t.Fatal(err)
281
+ }
282
+ }