@decantr/cli 2.3.1 → 2.4.1
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/README.md +31 -4
- package/dist/bin.js +2 -2
- package/dist/{chunk-2JWVKBNB.js → chunk-6BRD6DTB.js} +915 -327
- package/dist/chunk-AUQXYJ7T.js +316 -0
- package/dist/{chunk-3H3HWDJA.js → chunk-OD46PCR6.js} +354 -17
- package/dist/{chunk-WDA4SHIQ.js → chunk-P4NUDLWB.js} +109 -9
- package/dist/{health-EENY3BFS.js → health-ZXOPGNBZ.js} +5 -1
- package/dist/index.js +2 -2
- package/dist/{studio-TBJPZZHA.js → studio-LHQXHBE7.js} +63 -1
- package/dist/{upgrade-PL755AF7.js → upgrade-HSPWYROM.js} +1 -1
- package/dist/workspace-MOLAGT2B.js +21 -0
- package/package.json +22 -5
- package/src/templates/decantr-health.workflow.yml.template +2 -2
package/dist/index.js
CHANGED
|
@@ -1,3 +1,3 @@
|
|
|
1
|
-
import "./chunk-
|
|
2
|
-
import "./chunk-
|
|
1
|
+
import "./chunk-6BRD6DTB.js";
|
|
2
|
+
import "./chunk-P4NUDLWB.js";
|
|
3
3
|
import "./chunk-IEW2QFYI.js";
|
|
@@ -1,6 +1,9 @@
|
|
|
1
|
+
import {
|
|
2
|
+
createWorkspaceHealthReport
|
|
3
|
+
} from "./chunk-AUQXYJ7T.js";
|
|
1
4
|
import {
|
|
2
5
|
createProjectHealthReport
|
|
3
|
-
} from "./chunk-
|
|
6
|
+
} from "./chunk-OD46PCR6.js";
|
|
4
7
|
import "./chunk-NBJCO4G5.js";
|
|
5
8
|
import {
|
|
6
9
|
sendStudioHealthRefreshedTelemetry,
|
|
@@ -1104,16 +1107,70 @@ function studioHtml(reportMode = false) {
|
|
|
1104
1107
|
</body>
|
|
1105
1108
|
</html>`;
|
|
1106
1109
|
}
|
|
1110
|
+
function workspaceStudioHtml() {
|
|
1111
|
+
return `<!doctype html>
|
|
1112
|
+
<html lang="en">
|
|
1113
|
+
<head>
|
|
1114
|
+
<meta charset="utf-8">
|
|
1115
|
+
<meta name="viewport" content="width=device-width, initial-scale=1">
|
|
1116
|
+
<title>Decantr Workspace Health</title>
|
|
1117
|
+
<style>
|
|
1118
|
+
body { margin: 0; background: #101014; color: #f5f2eb; font-family: Inter, ui-sans-serif, system-ui, sans-serif; }
|
|
1119
|
+
header { padding: 1rem; border-bottom: 1px solid rgba(245,242,235,.12); display: flex; justify-content: space-between; gap: 1rem; align-items: center; }
|
|
1120
|
+
h1 { margin: 0; font-size: 1rem; }
|
|
1121
|
+
main { padding: 1rem; display: grid; gap: .75rem; }
|
|
1122
|
+
button { border: 1px solid rgba(245,242,235,.14); border-radius: 8px; background: rgba(245,242,235,.06); color: inherit; padding: .55rem .8rem; cursor: pointer; }
|
|
1123
|
+
.grid { display: grid; grid-template-columns: repeat(5, minmax(0, 1fr)); border: 1px solid rgba(245,242,235,.1); border-radius: 8px; overflow: hidden; }
|
|
1124
|
+
.cell { padding: .7rem; border-bottom: 1px solid rgba(245,242,235,.08); }
|
|
1125
|
+
.head { color: #ada7bd; font-size: .75rem; text-transform: uppercase; }
|
|
1126
|
+
.healthy { color: #5ee2a0; } .warning { color: #f2bd61; } .error, .failed { color: #ff6f7d; }
|
|
1127
|
+
.card { border: 1px solid rgba(245,242,235,.1); border-radius: 8px; padding: 1rem; background: rgba(245,242,235,.025); }
|
|
1128
|
+
</style>
|
|
1129
|
+
</head>
|
|
1130
|
+
<body>
|
|
1131
|
+
<header><h1>Decantr Workspace Health</h1><button id="refresh">Refresh</button></header>
|
|
1132
|
+
<main id="root"><div class="card">Loading workspace health...</div></main>
|
|
1133
|
+
<script>
|
|
1134
|
+
const esc = (v) => String(v ?? '').replace(/[&<>"]/g, (ch) => ({'&':'&','<':'<','>':'>','"':'"'}[ch]));
|
|
1135
|
+
async function load(refresh = false) {
|
|
1136
|
+
const res = await fetch(refresh ? '/api/workspace/refresh' : '/api/workspace', { method: refresh ? 'POST' : 'GET' });
|
|
1137
|
+
const report = await res.json();
|
|
1138
|
+
if (!res.ok) throw new Error(report.message || report.error || 'failed');
|
|
1139
|
+
const summary = report.summary || {};
|
|
1140
|
+
const rows = (report.projects || []).map((p) => '<div class="cell"><strong>' + esc(p.path) + '</strong></div><div class="cell ' + esc(p.status) + '">' + esc(p.status) + '</div><div class="cell">' + esc(p.score) + '</div><div class="cell">' + esc(p.findingCount) + '</div><div class="cell">' + esc(p.source) + '</div>').join('');
|
|
1141
|
+
document.getElementById('root').innerHTML =
|
|
1142
|
+
'<div class="card">Projects checked: <strong>' + esc(summary.checkedCount) + '/' + esc(summary.projectCount) + '</strong> \xB7 Healthy ' + esc(summary.healthyCount) + ' \xB7 Warnings ' + esc(summary.warningCount) + ' \xB7 Errors ' + esc(summary.errorCount) + ' \xB7 Failed ' + esc(summary.failedCount) + '</div>' +
|
|
1143
|
+
'<div class="grid"><div class="cell head">Project</div><div class="cell head">Status</div><div class="cell head">Score</div><div class="cell head">Findings</div><div class="cell head">Source</div>' + rows + '</div>';
|
|
1144
|
+
}
|
|
1145
|
+
document.getElementById('refresh').addEventListener('click', () => load(true).catch((e) => alert(e.message)));
|
|
1146
|
+
load().catch((e) => document.getElementById('root').innerHTML = '<div class="card error">' + esc(e.message) + '</div>');
|
|
1147
|
+
</script>
|
|
1148
|
+
</body>
|
|
1149
|
+
</html>`;
|
|
1150
|
+
}
|
|
1107
1151
|
function createStudioRequestHandler(projectRoot, options = {}) {
|
|
1108
1152
|
const reportPath = resolveReportPath(projectRoot, options.report);
|
|
1109
1153
|
const loadReport = () => reportPath ? readProjectHealthReport(reportPath) : createProjectHealthReport(projectRoot);
|
|
1154
|
+
const loadWorkspaceReport = () => createWorkspaceHealthReport(projectRoot);
|
|
1110
1155
|
return async function handleStudioRequest(req, res) {
|
|
1111
1156
|
const url = new URL(req.url ?? "/", "http://localhost");
|
|
1112
1157
|
try {
|
|
1113
1158
|
if (req.method === "GET" && url.pathname === "/") {
|
|
1159
|
+
if (options.workspace) {
|
|
1160
|
+
sendHtml(res, workspaceStudioHtml());
|
|
1161
|
+
return;
|
|
1162
|
+
}
|
|
1114
1163
|
sendHtml(res, studioHtml(Boolean(reportPath)));
|
|
1115
1164
|
return;
|
|
1116
1165
|
}
|
|
1166
|
+
if (options.workspace && req.method === "GET" && url.pathname === "/api/workspace") {
|
|
1167
|
+
sendJson(res, 200, await loadWorkspaceReport());
|
|
1168
|
+
return;
|
|
1169
|
+
}
|
|
1170
|
+
if (options.workspace && req.method === "POST" && url.pathname === "/api/workspace/refresh") {
|
|
1171
|
+
sendJson(res, 200, await loadWorkspaceReport());
|
|
1172
|
+
return;
|
|
1173
|
+
}
|
|
1117
1174
|
if (req.method === "GET" && url.pathname === "/api/health") {
|
|
1118
1175
|
sendJson(res, 200, await loadReport());
|
|
1119
1176
|
return;
|
|
@@ -1164,6 +1221,9 @@ async function cmdStudio(projectRoot = process.cwd(), options = {}) {
|
|
|
1164
1221
|
if (options.report) {
|
|
1165
1222
|
console.log("Report mode enabled. Refresh re-reads the local Project Health JSON file.");
|
|
1166
1223
|
}
|
|
1224
|
+
if (options.workspace) {
|
|
1225
|
+
console.log("Workspace mode enabled. Studio aggregates Decantr project health locally.");
|
|
1226
|
+
}
|
|
1167
1227
|
console.log("Press Ctrl+C to stop.");
|
|
1168
1228
|
}
|
|
1169
1229
|
function parseStudioArgs(args) {
|
|
@@ -1187,6 +1247,8 @@ function parseStudioArgs(args) {
|
|
|
1187
1247
|
const value = arg.slice("--report=".length);
|
|
1188
1248
|
if (!value) throw new Error("Missing --report value.");
|
|
1189
1249
|
options.report = value;
|
|
1250
|
+
} else if (arg === "--workspace") {
|
|
1251
|
+
options.workspace = true;
|
|
1190
1252
|
}
|
|
1191
1253
|
}
|
|
1192
1254
|
if (options.port !== void 0 && (!Number.isInteger(options.port) || options.port < 0)) {
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
import {
|
|
2
|
+
cmdWorkspace,
|
|
3
|
+
createWorkspaceHealthReport,
|
|
4
|
+
formatWorkspaceHealthMarkdown,
|
|
5
|
+
formatWorkspaceHealthText,
|
|
6
|
+
listWorkspaceProjects,
|
|
7
|
+
parseWorkspaceArgs,
|
|
8
|
+
shouldFailWorkspaceHealth
|
|
9
|
+
} from "./chunk-AUQXYJ7T.js";
|
|
10
|
+
import "./chunk-OD46PCR6.js";
|
|
11
|
+
import "./chunk-NBJCO4G5.js";
|
|
12
|
+
import "./chunk-IEW2QFYI.js";
|
|
13
|
+
export {
|
|
14
|
+
cmdWorkspace,
|
|
15
|
+
createWorkspaceHealthReport,
|
|
16
|
+
formatWorkspaceHealthMarkdown,
|
|
17
|
+
formatWorkspaceHealthText,
|
|
18
|
+
listWorkspaceProjects,
|
|
19
|
+
parseWorkspaceArgs,
|
|
20
|
+
shouldFailWorkspaceHealth
|
|
21
|
+
};
|
package/package.json
CHANGED
|
@@ -1,7 +1,24 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@decantr/cli",
|
|
3
|
-
"version": "2.
|
|
3
|
+
"version": "2.4.1",
|
|
4
4
|
"description": "Decantr CLI - scaffold, audit, inspect Project Health, and maintain Decantr projects from the terminal",
|
|
5
|
+
"keywords": [
|
|
6
|
+
"decantr",
|
|
7
|
+
"decantr-ai",
|
|
8
|
+
"ai-coding",
|
|
9
|
+
"ai-generated-ui",
|
|
10
|
+
"cli",
|
|
11
|
+
"project-health",
|
|
12
|
+
"design-intelligence",
|
|
13
|
+
"design-governance",
|
|
14
|
+
"ui-verification",
|
|
15
|
+
"drift-detection",
|
|
16
|
+
"scaffolding",
|
|
17
|
+
"brownfield",
|
|
18
|
+
"cursor",
|
|
19
|
+
"claude-code",
|
|
20
|
+
"windsurf"
|
|
21
|
+
],
|
|
5
22
|
"author": "Decantr AI",
|
|
6
23
|
"license": "MIT",
|
|
7
24
|
"bugs": {
|
|
@@ -31,11 +48,11 @@
|
|
|
31
48
|
},
|
|
32
49
|
"dependencies": {
|
|
33
50
|
"ajv": "^8.20.0",
|
|
34
|
-
"@decantr/core": "2.
|
|
35
|
-
"@decantr/
|
|
51
|
+
"@decantr/core": "2.1.0",
|
|
52
|
+
"@decantr/registry": "2.0.0",
|
|
36
53
|
"@decantr/essence-spec": "2.0.1",
|
|
37
|
-
"@decantr/
|
|
38
|
-
"@decantr/
|
|
54
|
+
"@decantr/telemetry": "2.2.1",
|
|
55
|
+
"@decantr/verifier": "2.1.0"
|
|
39
56
|
},
|
|
40
57
|
"scripts": {
|
|
41
58
|
"build": "tsup",
|
|
@@ -38,10 +38,10 @@ jobs:
|
|
|
38
38
|
fi
|
|
39
39
|
|
|
40
40
|
- name: Generate Decantr health JSON
|
|
41
|
-
{{PROJECT_WORKING_DIRECTORY}} run: npx --yes {{CLI_PACKAGE}}
|
|
41
|
+
{{PROJECT_WORKING_DIRECTORY}} run: npx --yes {{CLI_PACKAGE}} {{HEALTH_COMMAND}} --json --output {{JSON_PATH}}
|
|
42
42
|
|
|
43
43
|
- name: Audit Decantr health
|
|
44
|
-
{{PROJECT_WORKING_DIRECTORY}} run: npx --yes {{CLI_PACKAGE}}
|
|
44
|
+
{{PROJECT_WORKING_DIRECTORY}} run: npx --yes {{CLI_PACKAGE}} {{HEALTH_COMMAND}} --ci --fail-on {{FAIL_ON}} --markdown --output {{REPORT_PATH}}
|
|
45
45
|
|
|
46
46
|
- name: Publish health summary
|
|
47
47
|
if: always()
|