delimit-cli 4.7.2 → 4.7.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/CHANGELOG.md +15 -0
- package/README.md +37 -2
- package/bin/delimit-cli.js +152 -1
- package/bin/delimit-setup.js +88 -6
- package/bin/delimit.js +10 -25
- package/gateway/ai/backends/governance_bridge.py +52 -0
- package/gateway/ai/backends/repo_bridge.py +12 -0
- package/gateway/ai/backends/tools_infra.py +43 -1
- package/gateway/ai/cli_contract.py +12 -0
- package/gateway/ai/custom_gemini_repl.py +80 -0
- package/gateway/ai/delimit_daemon.py +8 -0
- package/gateway/ai/gemini_vertex_shim.py +38 -0
- package/gateway/ai/license_core.cpython-310-x86_64-linux-gnu.so +0 -0
- package/gateway/ai/release_sync.py +43 -8
- package/gateway/ai/route_daemon.py +98 -0
- package/gateway/ai/server.py +71 -1
- package/gateway/ai/session_phoenix.py +101 -136
- package/gateway/ai/supabase_sync.py +58 -0
- package/gateway/ai/swarm.py +2 -0
- package/gateway/ai/tui.py +81 -0
- package/gateway/core/ci_formatter.py +89 -61
- package/gateway/core/diff_engine_v2.py +208 -627
- package/gateway/core/explainer.py +67 -34
- package/lib/ai-sbom-engine.js +1 -0
- package/lib/auth-setup.js +10 -1
- package/lib/chat-repl.js +244 -0
- package/lib/cross-model-hooks.js +111 -0
- package/lib/timeline-engine.js +60 -0
- package/lib/wrap-engine.js +67 -11
- package/package.json +1 -1
- package/server.json +2 -2
|
@@ -100,89 +100,117 @@ class CIFormatter:
|
|
|
100
100
|
decision = result.get("decision", "unknown")
|
|
101
101
|
violations = result.get("violations", [])
|
|
102
102
|
summary = result.get("summary", {})
|
|
103
|
-
semver = result.get("semver")
|
|
103
|
+
semver = result.get("semver")
|
|
104
|
+
all_changes = result.get("all_changes", [])
|
|
105
|
+
migration = result.get("migration")
|
|
104
106
|
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
bump = semver.get("bump", "unknown")
|
|
109
|
-
bump_badge = {"major": " `MAJOR`", "minor": " `MINOR`", "patch": " `PATCH`", "none": ""}.get(bump, "")
|
|
107
|
+
bc = summary.get("breaking_changes", 0)
|
|
108
|
+
total = summary.get("total_changes", 0)
|
|
109
|
+
additive = total - bc
|
|
110
110
|
|
|
111
|
-
if
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
111
|
+
errors = [v for v in violations if v.get("severity") == "error"]
|
|
112
|
+
warnings = [v for v in violations if v.get("severity") == "warning"]
|
|
113
|
+
|
|
114
|
+
if bc == 0:
|
|
115
|
+
# ── GREEN PATH ──
|
|
116
|
+
bump_label = "NONE"
|
|
117
|
+
if semver:
|
|
118
|
+
bump_label = semver.get("bump", "none").upper()
|
|
119
|
+
lines.append("\U0001f6e1\ufe0f **Governance Passed**\n")
|
|
120
|
+
if total > 0:
|
|
121
|
+
lines.append(
|
|
122
|
+
f"> **No breaking API changes detected.** "
|
|
123
|
+
f"{additive} additive change{'s' if additive != 1 else ''} "
|
|
124
|
+
f"found \u2014 Semver: **{bump_label}**\n"
|
|
125
|
+
)
|
|
126
|
+
else:
|
|
127
|
+
lines.append("> **No breaking API changes detected.**\n")
|
|
128
|
+
|
|
129
|
+
# Additive changes
|
|
130
|
+
safe_changes = [c for c in all_changes if not c.get("is_breaking")]
|
|
131
|
+
if safe_changes and len(safe_changes) <= 15:
|
|
132
|
+
lines.append("<details>")
|
|
133
|
+
lines.append(f"<summary>\u2705 New additions ({len(safe_changes)})</summary>\n")
|
|
134
|
+
for c in safe_changes:
|
|
135
|
+
lines.append(f"- `{c.get('path', '')}` \u2014 {c.get('message', '')}")
|
|
136
|
+
lines.append("</details>\n")
|
|
115
137
|
else:
|
|
116
|
-
|
|
138
|
+
# ── RED PATH ──
|
|
139
|
+
lines.append("\U0001f6e1\ufe0f **Breaking API Changes Detected**\n")
|
|
117
140
|
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
lines.append(f"| Total changes | {summary.get('total_changes', 0)} |")
|
|
126
|
-
lines.append(f"| Breaking | {summary.get('breaking_changes', 0)} |")
|
|
127
|
-
if summary.get("violations", 0) > 0:
|
|
128
|
-
lines.append(f"| Policy violations | {summary['violations']} |")
|
|
129
|
-
lines.append("")
|
|
141
|
+
# Summary card
|
|
142
|
+
parts = [f"\U0001f534 **{bc} breaking change{'s' if bc != 1 else ''}**"]
|
|
143
|
+
parts.append("Semver: **MAJOR**")
|
|
144
|
+
if semver and semver.get("next_version"):
|
|
145
|
+
parts.append(f"Next: `{semver['next_version']}`")
|
|
146
|
+
separator = " \u00b7 "
|
|
147
|
+
lines.append(f"> {separator.join(parts)}\n")
|
|
130
148
|
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
|
|
149
|
+
# Stats table
|
|
150
|
+
lines.append("| | Count |")
|
|
151
|
+
lines.append("|---|---|")
|
|
152
|
+
lines.append(f"| Total changes | {total} |")
|
|
153
|
+
lines.append(f"| Breaking | {bc} |")
|
|
154
|
+
lines.append(f"| Additive | {additive} |")
|
|
155
|
+
if len(warnings) > 0:
|
|
156
|
+
lines.append(f"| Warnings | {len(warnings)} |")
|
|
157
|
+
if summary.get("violations", 0) > 0:
|
|
158
|
+
lines.append(f"| Policy violations | {summary['violations']} |")
|
|
159
|
+
lines.append("")
|
|
135
160
|
|
|
161
|
+
# Violations table
|
|
136
162
|
if errors or warnings:
|
|
137
|
-
lines.append("###
|
|
138
|
-
lines.append("| Severity |
|
|
139
|
-
lines.append("
|
|
163
|
+
lines.append("### Breaking Changes\n")
|
|
164
|
+
lines.append("| Severity | Change | Location |")
|
|
165
|
+
lines.append("|----------|--------|----------|")
|
|
140
166
|
|
|
141
167
|
for v in errors:
|
|
142
|
-
rule = v.get("name", v.get("rule", "Unknown"))
|
|
143
168
|
desc = v.get("message", "Unknown violation")
|
|
144
169
|
location = v.get("path", "-")
|
|
145
|
-
lines.append(f"|
|
|
170
|
+
lines.append(f"| \U0001f534 Critical | {desc} | `{location}` |")
|
|
146
171
|
|
|
147
172
|
for v in warnings:
|
|
148
|
-
rule = v.get("name", v.get("rule", "Unknown"))
|
|
149
173
|
desc = v.get("message", "Unknown warning")
|
|
150
174
|
location = v.get("path", "-")
|
|
151
|
-
lines.append(f"|
|
|
175
|
+
lines.append(f"| \U0001f7e1 Warning | {desc} | `{location}` |")
|
|
152
176
|
|
|
153
177
|
lines.append("")
|
|
154
178
|
|
|
155
|
-
|
|
156
|
-
|
|
157
|
-
|
|
158
|
-
|
|
159
|
-
|
|
160
|
-
|
|
161
|
-
|
|
162
|
-
|
|
163
|
-
lines.append(
|
|
164
|
-
|
|
165
|
-
|
|
179
|
+
# Migration guidance
|
|
180
|
+
if migration and decision == "fail":
|
|
181
|
+
lines.append("<details>")
|
|
182
|
+
lines.append("<summary>\U0001f4cb Migration guide</summary>\n")
|
|
183
|
+
lines.append(migration)
|
|
184
|
+
lines.append("\n</details>\n")
|
|
185
|
+
elif errors and decision == "fail":
|
|
186
|
+
lines.append("<details>")
|
|
187
|
+
lines.append("<summary>\U0001f4cb Migration guide</summary>\n")
|
|
188
|
+
lines.append("1. **Restore removed endpoints** \u2014 deprecate before removing")
|
|
189
|
+
lines.append("2. **Make parameters optional** \u2014 don't add required params")
|
|
190
|
+
lines.append("3. **Use versioning** \u2014 create `/v2/` for breaking changes")
|
|
191
|
+
lines.append("4. **Gradual migration** \u2014 provide guides and time")
|
|
192
|
+
lines.append("\n</details>\n")
|
|
166
193
|
|
|
167
|
-
|
|
168
|
-
|
|
169
|
-
|
|
170
|
-
|
|
171
|
-
|
|
172
|
-
|
|
173
|
-
|
|
194
|
+
# Additive changes
|
|
195
|
+
safe_changes = [c for c in all_changes if not c.get("is_breaking")]
|
|
196
|
+
if safe_changes and len(safe_changes) <= 15:
|
|
197
|
+
lines.append("<details>")
|
|
198
|
+
lines.append(f"<summary>\u2705 New additions ({len(safe_changes)})</summary>\n")
|
|
199
|
+
for c in safe_changes:
|
|
200
|
+
lines.append(f"- `{c.get('path', '')}` \u2014 {c.get('message', '')}")
|
|
201
|
+
lines.append("</details>\n")
|
|
174
202
|
|
|
175
|
-
|
|
176
|
-
if violations and decision == "fail" and not migration:
|
|
177
|
-
lines.append("### 💡 How to Fix\n")
|
|
178
|
-
lines.append("1. **Restore removed endpoints** — deprecate before removing")
|
|
179
|
-
lines.append("2. **Make parameters optional** — don't add required params")
|
|
180
|
-
lines.append("3. **Use versioning** — create `/v2/` for breaking changes")
|
|
181
|
-
lines.append("4. **Gradual migration** — provide guides and time")
|
|
182
|
-
lines.append("")
|
|
203
|
+
lines.append("> **Fix locally:** `npx delimit-cli lint`\n")
|
|
183
204
|
|
|
184
205
|
lines.append("---")
|
|
185
|
-
lines.append(
|
|
206
|
+
lines.append(
|
|
207
|
+
"Powered by [Delimit](https://delimit.ai) \u00b7 "
|
|
208
|
+
"[Docs](https://delimit.ai/docs) \u00b7 "
|
|
209
|
+
"[Install](https://github.com/marketplace/actions/delimit-api-governance)"
|
|
210
|
+
)
|
|
211
|
+
|
|
212
|
+
if bc == 0:
|
|
213
|
+
lines.append("\nKeep Building.")
|
|
186
214
|
|
|
187
215
|
return "\n".join(lines)
|
|
188
216
|
|