speclock 5.2.1 → 5.2.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.
- package/package.json +1 -1
- package/src/cli/index.js +130 -1
- package/src/core/compliance.js +1 -1
- package/src/dashboard/index.html +2 -2
- package/src/mcp/http-server.js +1 -1
- package/src/mcp/server.js +1 -1
package/package.json
CHANGED
|
@@ -2,7 +2,7 @@
|
|
|
2
2
|
|
|
3
3
|
"name": "speclock",
|
|
4
4
|
|
|
5
|
-
"version": "5.2.
|
|
5
|
+
"version": "5.2.2",
|
|
6
6
|
|
|
7
7
|
"description": "AI Constraint Engine — AI Patch Firewall. Diff-native review (interface breaks, protected symbols, dependency drift, schema changes, API impact), Patch Gateway (ALLOW/WARN/BLOCK verdicts), Spec Compiler (NL→constraints), Code Graph (blast radius, lock-to-file mapping), Typed constraints, REST API v2, Python SDK, ROS2 integration. 42 MCP tools, Gemini LLM hybrid, HMAC audit chain, RBAC, encryption, SOC 2/HIPAA compliance.",
|
|
8
8
|
|
package/src/cli/index.js
CHANGED
|
@@ -117,7 +117,7 @@ function refreshContext(root) {
|
|
|
117
117
|
|
|
118
118
|
function printHelp() {
|
|
119
119
|
console.log(`
|
|
120
|
-
SpecLock v5.2.
|
|
120
|
+
SpecLock v5.2.2 — AI Constraint Engine (Spec Compiler + Code Graph + Typed Constraints + Python SDK + ROS2 + REST API v2 + Gemini LLM + Policy-as-Code + Auth + RBAC + Encryption)
|
|
121
121
|
Developed by Sandeep Roy (github.com/sgroy10)
|
|
122
122
|
|
|
123
123
|
Usage: speclock <command> [options]
|
|
@@ -1102,6 +1102,135 @@ Tip: When starting a new chat, tell the AI:
|
|
|
1102
1102
|
return;
|
|
1103
1103
|
}
|
|
1104
1104
|
|
|
1105
|
+
// --- RELEASE: Automated version bump + publish + deploy ---
|
|
1106
|
+
if (cmd === "release") {
|
|
1107
|
+
const bump = args[0]; // "patch", "minor", or "major"
|
|
1108
|
+
if (!bump || !["patch", "minor", "major"].includes(bump)) {
|
|
1109
|
+
console.log("Usage: speclock release <patch|minor|major>");
|
|
1110
|
+
console.log(" Bumps version in ALL files, commits, pushes, npm publishes, deploys.");
|
|
1111
|
+
process.exit(1);
|
|
1112
|
+
}
|
|
1113
|
+
|
|
1114
|
+
const { execSync } = await import("child_process");
|
|
1115
|
+
const fs = await import("fs");
|
|
1116
|
+
|
|
1117
|
+
// Read current version
|
|
1118
|
+
const pkgPath = path.join(root, "package.json");
|
|
1119
|
+
const pkg = JSON.parse(fs.readFileSync(pkgPath, "utf8"));
|
|
1120
|
+
const [major, minor, patch] = pkg.version.split(".").map(Number);
|
|
1121
|
+
let newVersion;
|
|
1122
|
+
if (bump === "patch") newVersion = `${major}.${minor}.${patch + 1}`;
|
|
1123
|
+
else if (bump === "minor") newVersion = `${major}.${minor + 1}.0`;
|
|
1124
|
+
else newVersion = `${major + 1}.0.0`;
|
|
1125
|
+
|
|
1126
|
+
console.log(`\n Releasing v${newVersion} (was ${pkg.version})\n`);
|
|
1127
|
+
|
|
1128
|
+
// Step 1: Version bump in all 7 files
|
|
1129
|
+
const VERSION_FILES = [
|
|
1130
|
+
{ file: "package.json", pattern: `"version": "${pkg.version}"`, replacement: `"version": "${newVersion}"` },
|
|
1131
|
+
{ file: "src/mcp/http-server.js", pattern: `const VERSION = "${pkg.version}"`, replacement: `const VERSION = "${newVersion}"` },
|
|
1132
|
+
{ file: "src/mcp/server.js", pattern: `const VERSION = "${pkg.version}"`, replacement: `const VERSION = "${newVersion}"` },
|
|
1133
|
+
{ file: "src/core/compliance.js", pattern: `const VERSION = "${pkg.version}"`, replacement: `const VERSION = "${newVersion}"` },
|
|
1134
|
+
{ file: "src/cli/index.js", pattern: `SpecLock v${pkg.version}`, replacement: `SpecLock v${newVersion}` },
|
|
1135
|
+
{ file: "src/dashboard/index.html", pattern: `v${pkg.version}`, replacement: `v${newVersion}` },
|
|
1136
|
+
];
|
|
1137
|
+
|
|
1138
|
+
let filesUpdated = 0;
|
|
1139
|
+
for (const { file, pattern, replacement } of VERSION_FILES) {
|
|
1140
|
+
const filePath = path.join(root, file);
|
|
1141
|
+
if (!fs.existsSync(filePath)) {
|
|
1142
|
+
console.log(` SKIP ${file} (not found)`);
|
|
1143
|
+
continue;
|
|
1144
|
+
}
|
|
1145
|
+
const content = fs.readFileSync(filePath, "utf8");
|
|
1146
|
+
const updated = content.replaceAll(pattern, replacement);
|
|
1147
|
+
if (updated !== content) {
|
|
1148
|
+
fs.writeFileSync(filePath, updated);
|
|
1149
|
+
const count = (content.split(pattern).length - 1);
|
|
1150
|
+
console.log(` DONE ${file} (${count} replacement${count > 1 ? "s" : ""})`);
|
|
1151
|
+
filesUpdated++;
|
|
1152
|
+
} else {
|
|
1153
|
+
console.log(` SKIP ${file} (pattern not found)`);
|
|
1154
|
+
}
|
|
1155
|
+
}
|
|
1156
|
+
console.log(`\n ${filesUpdated} files updated to v${newVersion}\n`);
|
|
1157
|
+
|
|
1158
|
+
// Step 2: Git commit + push
|
|
1159
|
+
console.log(" Committing...");
|
|
1160
|
+
try {
|
|
1161
|
+
execSync(`git add -A`, { cwd: root, stdio: "pipe" });
|
|
1162
|
+
execSync(`git commit -m "v${newVersion}"`, { cwd: root, stdio: "pipe" });
|
|
1163
|
+
console.log(" DONE git commit");
|
|
1164
|
+
} catch (e) {
|
|
1165
|
+
console.error(" FAIL git commit:", e.message);
|
|
1166
|
+
process.exit(1);
|
|
1167
|
+
}
|
|
1168
|
+
|
|
1169
|
+
console.log(" Pushing...");
|
|
1170
|
+
try {
|
|
1171
|
+
execSync(`git push origin main`, { cwd: root, stdio: "pipe" });
|
|
1172
|
+
console.log(" DONE git push");
|
|
1173
|
+
} catch (e) {
|
|
1174
|
+
console.error(" FAIL git push:", e.message);
|
|
1175
|
+
}
|
|
1176
|
+
|
|
1177
|
+
// Step 3: npm publish
|
|
1178
|
+
console.log(" Publishing to npm...");
|
|
1179
|
+
try {
|
|
1180
|
+
execSync(`npm publish`, { cwd: root, stdio: "pipe" });
|
|
1181
|
+
console.log(" DONE npm publish speclock@" + newVersion);
|
|
1182
|
+
} catch (e) {
|
|
1183
|
+
console.error(" FAIL npm publish:", e.message);
|
|
1184
|
+
}
|
|
1185
|
+
|
|
1186
|
+
// Step 4: Git tag
|
|
1187
|
+
console.log(" Tagging...");
|
|
1188
|
+
try {
|
|
1189
|
+
execSync(`git tag v${newVersion}`, { cwd: root, stdio: "pipe" });
|
|
1190
|
+
execSync(`git push origin v${newVersion}`, { cwd: root, stdio: "pipe" });
|
|
1191
|
+
console.log(` DONE git tag v${newVersion}`);
|
|
1192
|
+
} catch (e) {
|
|
1193
|
+
console.error(" FAIL git tag:", e.message);
|
|
1194
|
+
}
|
|
1195
|
+
|
|
1196
|
+
// Step 5: Railway deploy
|
|
1197
|
+
console.log(" Deploying to Railway...");
|
|
1198
|
+
try {
|
|
1199
|
+
execSync(`railway up`, { cwd: root, stdio: "pipe", timeout: 120000 });
|
|
1200
|
+
console.log(" DONE railway up");
|
|
1201
|
+
} catch (e) {
|
|
1202
|
+
console.log(" WARN railway up (may need manual deploy):", e.message?.slice(0, 100));
|
|
1203
|
+
}
|
|
1204
|
+
|
|
1205
|
+
// Step 6: Verify
|
|
1206
|
+
console.log("\n Verifying...");
|
|
1207
|
+
try {
|
|
1208
|
+
const health = execSync(`curl -s https://speclock-mcp-production.up.railway.app/health`, { timeout: 15000 }).toString();
|
|
1209
|
+
const parsed = JSON.parse(health);
|
|
1210
|
+
if (parsed.version === newVersion) {
|
|
1211
|
+
console.log(` DONE Railway health: v${parsed.version} (${parsed.tools} tools)`);
|
|
1212
|
+
} else {
|
|
1213
|
+
console.log(` WARN Railway shows v${parsed.version}, expected v${newVersion} (may need a moment)`);
|
|
1214
|
+
}
|
|
1215
|
+
} catch (e) {
|
|
1216
|
+
console.log(" WARN Health check failed (Railway may still be deploying)");
|
|
1217
|
+
}
|
|
1218
|
+
|
|
1219
|
+
try {
|
|
1220
|
+
const npmVer = execSync(`npm view speclock version`, { timeout: 10000 }).toString().trim();
|
|
1221
|
+
if (npmVer === newVersion) {
|
|
1222
|
+
console.log(` DONE npm: speclock@${npmVer}`);
|
|
1223
|
+
} else {
|
|
1224
|
+
console.log(` WARN npm shows ${npmVer}, expected ${newVersion} (cache delay)`);
|
|
1225
|
+
}
|
|
1226
|
+
} catch (e) {
|
|
1227
|
+
console.log(" WARN npm check failed");
|
|
1228
|
+
}
|
|
1229
|
+
|
|
1230
|
+
console.log(`\n Release v${newVersion} complete.\n`);
|
|
1231
|
+
return;
|
|
1232
|
+
}
|
|
1233
|
+
|
|
1105
1234
|
console.error(`Unknown command: ${cmd}`);
|
|
1106
1235
|
console.error("Run 'speclock --help' for usage.");
|
|
1107
1236
|
process.exit(1);
|
package/src/core/compliance.js
CHANGED
package/src/dashboard/index.html
CHANGED
|
@@ -89,7 +89,7 @@
|
|
|
89
89
|
<div class="header">
|
|
90
90
|
<div>
|
|
91
91
|
<h1><span>SpecLock</span> Dashboard</h1>
|
|
92
|
-
<div class="meta">v5.2.
|
|
92
|
+
<div class="meta">v5.2.2 — AI Constraint Engine</div>
|
|
93
93
|
</div>
|
|
94
94
|
<div style="display:flex;align-items:center;gap:12px;">
|
|
95
95
|
<span id="health-badge" class="status-badge healthy">Loading...</span>
|
|
@@ -182,7 +182,7 @@
|
|
|
182
182
|
</div>
|
|
183
183
|
|
|
184
184
|
<div style="text-align:center;padding:24px;color:var(--muted);font-size:12px;">
|
|
185
|
-
SpecLock v5.2.
|
|
185
|
+
SpecLock v5.2.2 — Developed by Sandeep Roy — <a href="https://github.com/sgroy10/speclock" style="color:var(--accent)">GitHub</a>
|
|
186
186
|
</div>
|
|
187
187
|
|
|
188
188
|
<script>
|
package/src/mcp/http-server.js
CHANGED
|
@@ -113,7 +113,7 @@ import { fileURLToPath } from "url";
|
|
|
113
113
|
import _path from "path";
|
|
114
114
|
|
|
115
115
|
const PROJECT_ROOT = process.env.SPECLOCK_PROJECT_ROOT || process.cwd();
|
|
116
|
-
const VERSION = "5.2.
|
|
116
|
+
const VERSION = "5.2.2";
|
|
117
117
|
const AUTHOR = "Sandeep Roy";
|
|
118
118
|
const START_TIME = Date.now();
|
|
119
119
|
|
package/src/mcp/server.js
CHANGED
|
@@ -120,7 +120,7 @@ const PROJECT_ROOT =
|
|
|
120
120
|
args.project || process.env.SPECLOCK_PROJECT_ROOT || process.cwd();
|
|
121
121
|
|
|
122
122
|
// --- MCP Server ---
|
|
123
|
-
const VERSION = "5.2.
|
|
123
|
+
const VERSION = "5.2.2";
|
|
124
124
|
const AUTHOR = "Sandeep Roy";
|
|
125
125
|
|
|
126
126
|
const server = new McpServer(
|