@r1z4x/tezgah 1.11.0 → 1.14.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 (109) hide show
  1. package/CHANGELOG.md +507 -1
  2. package/MANIFEST +40 -0
  3. package/NOTICE +152 -0
  4. package/README.de.md +41 -20
  5. package/README.es.md +39 -19
  6. package/README.fr.md +41 -20
  7. package/README.md +18 -10
  8. package/README.tr.md +39 -21
  9. package/bin/codegen +9 -2
  10. package/bin/consult +6 -0
  11. package/bin/tezgah-adhd +3 -0
  12. package/bin/tezgah-agents +3 -0
  13. package/bin/tezgah-capture +3 -0
  14. package/bin/tezgah-design +329 -54
  15. package/bin/tezgah-docs +158 -42
  16. package/bin/tezgah-dsh +1 -1
  17. package/bin/tezgah-gate +7 -2
  18. package/bin/tezgah-import-ai-research +16 -4
  19. package/bin/tezgah-index +3 -0
  20. package/bin/tezgah-lessons +13 -4
  21. package/bin/tezgah-mcp +4 -0
  22. package/bin/tezgah-migrate +3 -0
  23. package/bin/tezgah-ocr-review +2 -1
  24. package/bin/tezgah-optimize +4 -1
  25. package/bin/tezgah-pony +3 -0
  26. package/bin/tezgah-research +51 -10
  27. package/bin/tezgah-rollback +3 -0
  28. package/bin/tezgah-route +1 -1
  29. package/bin/tezgah-setup +1741 -95
  30. package/bin/tezgah-status +11 -1
  31. package/bin/tezgah-task +58 -17
  32. package/bin/tezgah.js +10 -3
  33. package/commands/adhd.md +1 -1
  34. package/docs/README.md +19 -8
  35. package/docs/architecture.md +2 -2
  36. package/docs/citations-baseline.json +11 -17
  37. package/docs/clarity-baseline.json +12 -6
  38. package/docs/contract.md +83 -34
  39. package/docs/environment.md +59 -24
  40. package/docs/evidence.md +128 -25
  41. package/docs/gate.md +77 -23
  42. package/docs/glossary.md +1 -1
  43. package/docs/hosts.md +343 -48
  44. package/docs/layers.md +2 -2
  45. package/docs/models.md +6 -0
  46. package/docs/operations.md +83 -29
  47. package/docs/research.md +37 -11
  48. package/docs/skills.md +31 -8
  49. package/docs/status-line.md +39 -23
  50. package/docs/testing.md +50 -17
  51. package/docs/vision.md +6 -2
  52. package/hooks/hooks.json +1 -1
  53. package/hooks/lang/en.json +16 -2
  54. package/hooks/lang/tr.json +14 -2
  55. package/hooks/projects-posttooluse.py +11 -3
  56. package/hooks/projects-stop.py +3 -2
  57. package/hooks/tezgah_agents.py +27 -3
  58. package/hooks/tezgah_attest.py +79 -10
  59. package/hooks/tezgah_context.py +61 -31
  60. package/hooks/tezgah_gate.py +480 -126
  61. package/hooks/tezgah_integrity.py +577 -133
  62. package/hooks/tezgah_lessons.py +5 -2
  63. package/hooks/tezgah_paths.py +60 -8
  64. package/hooks/tezgah_policy.py +48 -18
  65. package/hooks/tezgah_replay.py +8 -2
  66. package/hooks/tezgah_research.py +167 -24
  67. package/hooks/tezgah_skill_pick.py +1 -1
  68. package/hooks/tezgah_snapshot.py +6 -3
  69. package/hooks/tezgah_stack.py +236 -1
  70. package/hooks/tezgah_stopspec.py +2 -1
  71. package/hooks/tezgah_task.py +2 -1
  72. package/hosts/amp/hook.py +217 -0
  73. package/hosts/amp/tezgah-plugin.ts.in +396 -0
  74. package/hosts/antigravity/hook.py +255 -0
  75. package/hosts/codex/hook.py +3 -2
  76. package/hosts/commandcode/hook.py +239 -0
  77. package/hosts/copilot/hook.py +284 -0
  78. package/hosts/cursor/hook.py +4 -2
  79. package/hosts/droid/hook.py +259 -0
  80. package/hosts/dsh/hooks.json +1 -1
  81. package/hosts/gemini/hook.py +213 -0
  82. package/hosts/goose/hook.py +145 -0
  83. package/hosts/omp/hook.py +5 -2
  84. package/hosts/omp/tezgah-hook.ts.in +157 -42
  85. package/hosts/opencode/plugins/tezgah.js +209 -63
  86. package/hosts/qwen/hook.py +206 -0
  87. package/output-styles/tezgah.md +11 -6
  88. package/package.json +6 -3
  89. package/packaging/build.sh +4 -4
  90. package/packaging/install.sh +11 -0
  91. package/packaging/upgrade.sh +3 -0
  92. package/skills/ai-research/LICENSE +21 -0
  93. package/skills/design-contract/SKILL.md +27 -6
  94. package/skills/design-library/LICENSE +21 -0
  95. package/skills/harness/SKILL.md +2 -0
  96. package/skills/i-have-adhd/SKILL.md +10 -1
  97. package/skills/plan-add/SKILL.md +5 -1
  98. package/skills/plan-add/render_table.py +7 -0
  99. package/skills/pm-frameworks/LICENSE +21 -0
  100. package/skills/research/SKILL.md +22 -9
  101. package/skills/rl-env/LICENSE +201 -0
  102. package/skills/tezgah-contract/SKILL.md +21 -8
  103. package/statusline.py +20 -9
  104. package/third_party/open-code-review/LICENSE +201 -0
  105. package/third_party/open-code-review/README.md +15 -0
  106. package/third_party/open-code-review/prompts/main_task_system.md +26 -0
  107. package/third_party/open-code-review/prompts/review_filter_task_system.md +13 -0
  108. package/workflows/graph-map.js +14 -5
  109. package/workflows/graph-review.js +14 -2
@@ -77,7 +77,8 @@ focus, ranked, with the real directory path for each. Do not read file bodies -
77
77
  { label: 'survey', schema: SURVEY, effort: 'medium' },
78
78
  )
79
79
 
80
- if (!survey || !survey.modules || !survey.modules.length) {
80
+ if (!survey) return { error: 'the survey agent failed - nothing was mapped; unknown, not clean', unknown: ['survey'] }
81
+ if (!survey.modules || !survey.modules.length) {
81
82
  return { error: 'survey returned no modules - is the repo indexed? run `codegraph init` in it first' }
82
83
  }
83
84
 
@@ -88,7 +89,7 @@ if (ranked.length > picked.length) {
88
89
  }
89
90
 
90
91
  phase('Read')
91
- const readings = (await parallel(picked.map(m => () => agent(
92
+ const read = await parallel(picked.map(m => () => agent(
92
93
  `Read module "${m.name}" at ${m.path}. It matters because: ${m.why}. Overall focus: ${focus}.
93
94
  ${GRAPH}
94
95
  Answer: what it is responsible for, its key symbols with file and line, which other modules call it or
@@ -96,7 +97,10 @@ it calls (use \`codegraph callers\` and \`codegraph callees\` both directions),
96
97
  and any graph-evidenced risk (dead code, a symbol with many inbound callers, missing test coverage).
97
98
  Cite file:line for every claim.`,
98
99
  { label: `read:${m.name}`, phase: 'Read', schema: READING },
99
- )))).filter(Boolean)
100
+ )))
101
+ // a failed reader is unknown, never silence: its module is unread, not empty
102
+ const unknown = picked.filter((m, i) => !read[i]).map(m => `read:${m.name}`)
103
+ const readings = read.filter(Boolean)
100
104
 
101
105
  log(`${readings.length}/${picked.length} modules read`)
102
106
 
@@ -119,7 +123,8 @@ document headings up as code.`,
119
123
  if (!map) {
120
124
  return { focus, modules_read: readings.map(r => r.module),
121
125
  modules_dropped: ranked.slice(MAX_MODULES).map(m => m.name),
122
- map: null, gaps: [], error: 'the synthesize agent returned nothing' }
126
+ map: null, gaps: 'unknown - the gap check never ran', unknown: unknown.concat(['synthesize']),
127
+ error: 'the synthesize agent returned nothing' }
123
128
  }
124
129
 
125
130
  phase('Gap check')
@@ -148,11 +153,15 @@ list; empty list if genuinely clean.`,
148
153
  }, effort: 'high' },
149
154
  )
150
155
 
156
+ if (!gaps) unknown.push('gap-check')
157
+ if (unknown.length) log(`failed, reported as unknown: ${unknown.join(', ')}`)
158
+
151
159
  return {
152
160
  focus,
153
161
  modules_read: readings.map(r => r.module),
154
162
  modules_dropped: ranked.slice(MAX_MODULES).map(m => m.name),
155
163
  map,
156
- gaps: (gaps && gaps.gaps) || [],
164
+ gaps: gaps ? (gaps.gaps || []) : 'unknown - the gap-check agent failed',
157
165
  coverage_note: gaps && gaps.coverage_note,
166
+ unknown,
158
167
  }
@@ -114,7 +114,18 @@ const unknown = DIMENSIONS.filter((d, i) => !reviewed[i]).map(d => `review:${d.k
114
114
  const reviews = reviewed.filter(Boolean)
115
115
 
116
116
  const rank = { high: 0, medium: 1, low: 2 }
117
- const all = reviews.flatMap(r => r.findings || []).sort((a, b) => rank[a.severity] - rank[b.severity])
117
+ // two lenses often raise one defect: merge on (file, line, lowercased title), keep the higher severity
118
+ const byKey = new Map()
119
+ let raised = 0
120
+ reviewed.forEach((r, i) => ((r && r.findings) || []).forEach(f => {
121
+ raised++
122
+ const key = `${f.file}\u0000${f.line || ''}\u0000${String(f.title).trim().toLowerCase()}`
123
+ const prev = byKey.get(key)
124
+ const keep = prev && rank[prev.severity] <= rank[f.severity] ? prev : f
125
+ byKey.set(key, { ...keep, dimensions: [...new Set([...((prev && prev.dimensions) || []), DIMENSIONS[i].key])] })
126
+ }))
127
+ const all = [...byKey.values()].sort((a, b) => rank[a.severity] - rank[b.severity])
128
+ const caps = { max_verified: MAX_VERIFIED, raised, deduplicated: raised - all.length }
118
129
  if (!all.length) {
119
130
  const note = !unknown.length ? 'all four dimensions came back clean'
120
131
  : !reviews.length ? 'every dimension failed - nothing was reviewed; unknown, not clean'
@@ -124,7 +135,7 @@ if (!all.length) {
124
135
 
125
136
  const toVerify = all.slice(0, MAX_VERIFIED)
126
137
  if (all.length > toVerify.length) {
127
- log(`${all.length} findings raised; verifying the ${toVerify.length} most severe. NOT verified (reported as unverified): ${all.slice(MAX_VERIFIED).map(f => f.title).join('; ')}`)
138
+ log(`${all.length} distinct findings (${caps.deduplicated} duplicates merged); verifying the ${toVerify.length} most severe. NOT verified (reported as unverified): ${all.slice(MAX_VERIFIED).map(f => f.title).join('; ')}`)
128
139
  }
129
140
 
130
141
  phase('Verify')
@@ -167,4 +178,5 @@ return {
167
178
  unverified: unsettled.map(v => ({ ...v.finding, verdict: 'UNVERIFIED - every refuter failed' }))
168
179
  .concat(all.slice(MAX_VERIFIED).map(f => ({ ...f, verdict: 'UNVERIFIED - budget cap' }))),
169
180
  unknown,
181
+ caps,
170
182
  }