speclock 5.2.6 → 5.3.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.
package/src/cli/index.js CHANGED
@@ -62,6 +62,8 @@ import {
62
62
  getSSOConfig,
63
63
  saveSSOConfig,
64
64
  } from "../core/sso.js";
65
+ import { syncRules, getSyncFormats } from "../core/rules-sync.js";
66
+ import { getReplay, listSessions, formatReplay } from "../core/replay.js";
65
67
 
66
68
  // --- Argument parsing ---
67
69
 
@@ -117,7 +119,7 @@ function refreshContext(root) {
117
119
 
118
120
  function printHelp() {
119
121
  console.log(`
120
- SpecLock v5.2.6 — AI Constraint Engine (Spec Compiler + Code Graph + Typed Constraints + Python SDK + ROS2 + REST API v2 + Gemini LLM + Policy-as-Code + Auth + RBAC + Encryption)
122
+ SpecLock v5.3.0 — AI Constraint Engine (Universal Rules Sync + Spec Compiler + Code Graph + Typed Constraints + Python SDK + ROS2 + REST API v2 + Gemini LLM + Policy-as-Code + Auth + RBAC + Encryption)
121
123
  Developed by Sandeep Roy (github.com/sgroy10)
122
124
 
123
125
  Usage: speclock <command> [options]
@@ -149,7 +151,13 @@ Commands:
149
151
  license Show license tier and usage info
150
152
  context Generate and print context pack
151
153
  facts deploy [--provider X] Set deployment facts
152
- watch Start file watcher (auto-track changes)
154
+ sync [--format <name>] Sync constraints to AI tool rules files
155
+ sync --all Sync to ALL formats at once
156
+ sync --list List available sync formats
157
+ sync --preview <format> Preview without writing files
158
+ replay [--session <id>] Replay session activity — what AI tried & what was caught
159
+ replay --list List available sessions for replay
160
+ watch Start file watcher (live dashboard)
153
161
  serve [--project <path>] Start MCP stdio server
154
162
  status Show project brain summary
155
163
 
@@ -163,7 +171,10 @@ Options:
163
171
  --format <soc2|hipaa|csv> Compliance export format
164
172
  --project <path> Project root (for serve)
165
173
 
166
- Templates: nextjs, react, express, supabase, stripe, security-hardened
174
+ Templates: nextjs, react, express, supabase, stripe, security-hardened,
175
+ safe-defaults, hipaa, api-stability, solo-founder
176
+
177
+ Sync Formats: cursor, claude, agents, windsurf, copilot, gemini, codex, aider
167
178
 
168
179
  Policy-as-Code (v3.5):
169
180
  policy list List all policy rules
@@ -310,11 +321,17 @@ Files created/updated:
310
321
  Next steps:
311
322
  To add constraints: npx speclock lock "Never touch auth files"
312
323
  To check conflicts: npx speclock check "Modifying auth page"
313
- To log changes: npx speclock log-change "Built landing page"
324
+ To sync to AI tools: npx speclock sync --all
325
+ To replay sessions: npx speclock replay
314
326
  To see status: npx speclock status
315
-
316
- Tip: When starting a new chat, tell the AI:
317
- "Check speclock status and read the project constraints before doing anything"
327
+ ${!flags.template ? `
328
+ Quick start templates:
329
+ npx speclock template apply safe-defaults — Prevent the 5 most common AI disasters
330
+ npx speclock template apply solo-founder — Essential protection for indie builders
331
+ npx speclock template apply hipaa — HIPAA healthcare compliance (8 locks)
332
+ npx speclock template apply api-stability — Protect your public API contracts
333
+ ` : ""}
334
+ Tip: Run "speclock sync --all" to push constraints to Cursor, Claude, Copilot, Windsurf, and more.
318
335
  `);
319
336
  return;
320
337
  }
@@ -1096,6 +1113,119 @@ Tip: When starting a new chat, tell the AI:
1096
1113
  process.exit(1);
1097
1114
  }
1098
1115
 
1116
+ // --- REPLAY (new: incident replay) ---
1117
+ if (cmd === "replay") {
1118
+ const flags = parseFlags(args);
1119
+
1120
+ if (flags.list) {
1121
+ const result = listSessions(root, 10);
1122
+ console.log(`\nSession History (${result.total} total)`);
1123
+ console.log("=".repeat(60));
1124
+ if (result.sessions.length === 0) {
1125
+ console.log(" No sessions recorded yet.");
1126
+ } else {
1127
+ for (const s of result.sessions) {
1128
+ const current = s.isCurrent ? " [ACTIVE]" : "";
1129
+ console.log(` ${s.id} ${s.tool.padEnd(12)} ${s.startedAt.substring(0, 16)} ${s.events} events${current}`);
1130
+ if (s.summary && s.summary !== "(no summary)") {
1131
+ console.log(` ${"".padEnd(16)} ${s.summary.substring(0, 60)}`);
1132
+ }
1133
+ }
1134
+ }
1135
+ console.log(`\nReplay a session: speclock replay --session <id>`);
1136
+ return;
1137
+ }
1138
+
1139
+ const replay = getReplay(root, {
1140
+ sessionId: flags.session || null,
1141
+ limit: flags.limit ? parseInt(flags.limit, 10) : 50,
1142
+ });
1143
+
1144
+ if (!replay.found) {
1145
+ console.error(replay.error);
1146
+ process.exit(1);
1147
+ }
1148
+
1149
+ console.log(`\nSpecLock Incident Replay`);
1150
+ console.log("=".repeat(60));
1151
+ console.log(formatReplay(replay));
1152
+ return;
1153
+ }
1154
+
1155
+ // --- SYNC (new: universal rules sync) ---
1156
+ if (cmd === "sync") {
1157
+ const flags = parseFlags(args);
1158
+
1159
+ // List available formats
1160
+ if (flags.list) {
1161
+ const formats = getSyncFormats();
1162
+ console.log("\nAvailable Sync Formats:");
1163
+ console.log("=".repeat(55));
1164
+ for (const f of formats) {
1165
+ console.log(` ${f.key.padEnd(12)} ${f.name.padEnd(18)} → ${f.file}`);
1166
+ console.log(` ${"".padEnd(12)} ${f.description}`);
1167
+ console.log("");
1168
+ }
1169
+ console.log("Usage:");
1170
+ console.log(" speclock sync --format cursor Sync to Cursor only");
1171
+ console.log(" speclock sync --all Sync to ALL formats");
1172
+ console.log(" speclock sync --preview claude Preview without writing");
1173
+ return;
1174
+ }
1175
+
1176
+ // Preview mode
1177
+ if (flags.preview) {
1178
+ const result = syncRules(root, { format: flags.preview, dryRun: true });
1179
+ if (result.errors.length > 0) {
1180
+ for (const err of result.errors) console.error(err);
1181
+ process.exit(1);
1182
+ }
1183
+ for (const s of result.synced) {
1184
+ console.log(`\n${"=".repeat(55)}`);
1185
+ console.log(`Preview: ${s.name} → ${s.file} (${s.size} bytes)`);
1186
+ console.log("=".repeat(55));
1187
+ console.log(s.content);
1188
+ }
1189
+ return;
1190
+ }
1191
+
1192
+ // Determine format
1193
+ const format = flags.format || (flags.all ? undefined : flags._[0]);
1194
+ if (!format && !flags.all) {
1195
+ console.error("Usage: speclock sync --format <cursor|claude|agents|windsurf|copilot|gemini|aider>");
1196
+ console.error(" speclock sync --all Sync to all formats");
1197
+ console.error(" speclock sync --list List formats");
1198
+ console.error(" speclock sync --preview <fmt> Preview output");
1199
+ process.exit(1);
1200
+ }
1201
+
1202
+ const options = {};
1203
+ if (format) options.format = format;
1204
+ if (flags.append) options.append = true;
1205
+
1206
+ const result = syncRules(root, options);
1207
+
1208
+ if (result.errors.length > 0) {
1209
+ for (const err of result.errors) console.error(`Error: ${err}`);
1210
+ if (result.synced.length === 0) process.exit(1);
1211
+ }
1212
+
1213
+ if (result.synced.length > 0) {
1214
+ console.log(`\nSpecLock Sync Complete`);
1215
+ console.log("=".repeat(55));
1216
+ console.log(`Constraints: ${result.lockCount} lock(s), ${result.decisionCount} decision(s)`);
1217
+ console.log("");
1218
+ for (const s of result.synced) {
1219
+ console.log(` ✓ ${s.name.padEnd(18)} → ${s.file} (${s.size} bytes)`);
1220
+ }
1221
+ console.log(`\n${result.synced.length} file(s) synced. Your AI tools will now see SpecLock constraints.`);
1222
+ if (!format) {
1223
+ console.log("\nTip: Add these files to git so your AI tools read them automatically.");
1224
+ }
1225
+ }
1226
+ return;
1227
+ }
1228
+
1099
1229
  // --- STATUS ---
1100
1230
  if (cmd === "status") {
1101
1231
  showStatus(root);