speclock 1.4.1 → 1.5.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/README.md +2 -2
- package/package.json +1 -1
- package/src/cli/index.js +14 -5
- package/src/core/engine.js +46 -1
package/README.md
CHANGED
|
@@ -76,7 +76,7 @@ Or run it yourself:
|
|
|
76
76
|
npx speclock setup --goal "Build my app"
|
|
77
77
|
```
|
|
78
78
|
|
|
79
|
-
**That's it.**
|
|
79
|
+
**That's it.** SpecLock creates `SPECLOCK.md`, injects a marker into `package.json`, and generates `.speclock/context/latest.md`. The AI reads these automatically and follows the rules. When the AI returns in a new session, it sees the SpecLock marker in `package.json` and knows to check the rules before making changes.
|
|
80
80
|
|
|
81
81
|
### Lovable (MCP Remote — No Install)
|
|
82
82
|
|
|
@@ -287,4 +287,4 @@ MIT License - see [LICENSE](LICENSE) file.
|
|
|
287
287
|
|
|
288
288
|
---
|
|
289
289
|
|
|
290
|
-
*SpecLock v1.
|
|
290
|
+
*SpecLock v1.5.0 — Because remembering isn't enough. AI needs to respect boundaries.*
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "speclock",
|
|
3
|
-
"version": "1.
|
|
3
|
+
"version": "1.5.0",
|
|
4
4
|
"description": "AI constraint engine — MCP server + CLI with active enforcement. Memory + guardrails for AI coding tools. Works with Bolt.new, Claude Code, Cursor, Lovable.",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"main": "src/mcp/server.js",
|
package/src/cli/index.js
CHANGED
|
@@ -13,6 +13,7 @@ import {
|
|
|
13
13
|
createSpecLockMd,
|
|
14
14
|
guardFile,
|
|
15
15
|
unguardFile,
|
|
16
|
+
injectPackageJsonMarker,
|
|
16
17
|
} from "../core/engine.js";
|
|
17
18
|
import { generateContext } from "../core/context.js";
|
|
18
19
|
import { readBrain } from "../core/storage.js";
|
|
@@ -71,7 +72,7 @@ function refreshContext(root) {
|
|
|
71
72
|
|
|
72
73
|
function printHelp() {
|
|
73
74
|
console.log(`
|
|
74
|
-
SpecLock v1.
|
|
75
|
+
SpecLock v1.5.0 — AI Constraint Engine
|
|
75
76
|
Developed by Sandeep Roy (github.com/sgroy10)
|
|
76
77
|
|
|
77
78
|
Usage: speclock <command> [options]
|
|
@@ -181,18 +182,25 @@ async function main() {
|
|
|
181
182
|
const mdPath = createSpecLockMd(root);
|
|
182
183
|
console.log(`Created SPECLOCK.md (AI instructions file).`);
|
|
183
184
|
|
|
184
|
-
// 4.
|
|
185
|
+
// 4. Inject marker into package.json (so AI tools auto-discover SpecLock)
|
|
186
|
+
const pkgResult = injectPackageJsonMarker(root);
|
|
187
|
+
if (pkgResult.success) {
|
|
188
|
+
console.log("Injected SpecLock marker into package.json.");
|
|
189
|
+
}
|
|
190
|
+
|
|
191
|
+
// 5. Generate context
|
|
185
192
|
generateContext(root);
|
|
186
193
|
console.log("Generated .speclock/context/latest.md");
|
|
187
194
|
|
|
188
|
-
//
|
|
195
|
+
// 6. Print summary
|
|
189
196
|
console.log(`
|
|
190
197
|
SpecLock is ready!
|
|
191
198
|
|
|
192
|
-
Files created:
|
|
199
|
+
Files created/updated:
|
|
193
200
|
.speclock/brain.json — Project memory
|
|
194
201
|
.speclock/context/latest.md — Context for AI (read this)
|
|
195
202
|
SPECLOCK.md — AI rules (read this)
|
|
203
|
+
package.json — SpecLock marker added (AI auto-discovery)
|
|
196
204
|
|
|
197
205
|
Next steps:
|
|
198
206
|
The AI should read SPECLOCK.md for rules and
|
|
@@ -210,8 +218,9 @@ Next steps:
|
|
|
210
218
|
if (cmd === "init") {
|
|
211
219
|
ensureInit(root);
|
|
212
220
|
createSpecLockMd(root);
|
|
221
|
+
injectPackageJsonMarker(root);
|
|
213
222
|
generateContext(root);
|
|
214
|
-
console.log("SpecLock initialized. Created SPECLOCK.md and context file.");
|
|
223
|
+
console.log("SpecLock initialized. Created SPECLOCK.md, updated package.json, and generated context file.");
|
|
215
224
|
return;
|
|
216
225
|
}
|
|
217
226
|
|
package/src/core/engine.js
CHANGED
|
@@ -704,8 +704,24 @@ export function createSpecLockMd(root) {
|
|
|
704
704
|
|
|
705
705
|
## STOP — Read this before doing ANYTHING.
|
|
706
706
|
|
|
707
|
+
This project has SpecLock installed. It tracks project memory, goals, constraints (locks), and decisions.
|
|
708
|
+
|
|
709
|
+
**Step 1:** Read \`.speclock/context/latest.md\` — this contains the full project memory.
|
|
710
|
+
**Step 2:** Follow ALL rules below on every message.
|
|
711
|
+
|
|
707
712
|
**If a file contains "SPECLOCK-GUARD" at the top → DO NOT EDIT IT. Period.**
|
|
708
713
|
|
|
714
|
+
## Returning to This Project? (New Chat Session)
|
|
715
|
+
|
|
716
|
+
If you are starting a new chat on this project:
|
|
717
|
+
1. SpecLock is ALREADY installed — do NOT reinstall it
|
|
718
|
+
2. The \`.speclock/\` directory contains all project memory
|
|
719
|
+
3. Run \`npx speclock status\` to see the current state
|
|
720
|
+
4. Read \`.speclock/context/latest.md\` for full context (goals, locks, decisions, history)
|
|
721
|
+
5. Respect ALL existing locks and constraints before making any changes
|
|
722
|
+
|
|
723
|
+
**DO NOT say "SpecLock is not installed" — if you can read this file, it IS installed.**
|
|
724
|
+
|
|
709
725
|
## Your Job (Do This Automatically — The User Will NOT Ask)
|
|
710
726
|
|
|
711
727
|
### On EVERY message:
|
|
@@ -748,6 +764,7 @@ User might say "actually, let me change auth" or "ok modify the database."
|
|
|
748
764
|
## Commands
|
|
749
765
|
|
|
750
766
|
\`\`\`bash
|
|
767
|
+
npx speclock status # CHECK IF ALREADY SET UP
|
|
751
768
|
npx speclock check "what you plan to do" # ALWAYS RUN BEFORE CHANGES
|
|
752
769
|
npx speclock lock "constraint" # Lock a constraint
|
|
753
770
|
npx speclock guard <file> --lock "constraint" # Protect a specific file
|
|
@@ -756,7 +773,6 @@ npx speclock lock remove <lockId> # Unlock a constraint
|
|
|
756
773
|
npx speclock log-change "what changed" # Log changes
|
|
757
774
|
npx speclock decide "decision" # Record a decision
|
|
758
775
|
npx speclock context # Refresh context file
|
|
759
|
-
npx speclock status # See project summary
|
|
760
776
|
\`\`\`
|
|
761
777
|
|
|
762
778
|
## Key Rule
|
|
@@ -764,6 +780,7 @@ npx speclock status # See project summary
|
|
|
764
780
|
**The user will NEVER tell you to run these commands. You run them automatically.**
|
|
765
781
|
**The user will NEVER say "lock this." You detect the intent and lock it yourself.**
|
|
766
782
|
**The user will NEVER say "check constraints." You check before EVERY code change.**
|
|
783
|
+
**If this file exists, SpecLock is installed. Do NOT reinstall. Just read the context and follow the rules.**
|
|
767
784
|
`;
|
|
768
785
|
const filePath = path.join(root, "SPECLOCK.md");
|
|
769
786
|
fs.writeFileSync(filePath, mdContent);
|
|
@@ -824,6 +841,34 @@ export function guardFile(root, relativeFilePath, lockText) {
|
|
|
824
841
|
return { success: true };
|
|
825
842
|
}
|
|
826
843
|
|
|
844
|
+
// --- Package.json marker injection (makes Bolt.new auto-discover SpecLock) ---
|
|
845
|
+
|
|
846
|
+
export function injectPackageJsonMarker(root) {
|
|
847
|
+
const pkgPath = path.join(root, "package.json");
|
|
848
|
+
if (!fs.existsSync(pkgPath)) {
|
|
849
|
+
return { success: false, error: "No package.json found in project root." };
|
|
850
|
+
}
|
|
851
|
+
|
|
852
|
+
try {
|
|
853
|
+
const raw = fs.readFileSync(pkgPath, "utf-8");
|
|
854
|
+
const pkg = JSON.parse(raw);
|
|
855
|
+
|
|
856
|
+
// Add speclock marker
|
|
857
|
+
pkg.speclock = {
|
|
858
|
+
active: true,
|
|
859
|
+
rules: "IMPORTANT: Read SPECLOCK.md before making ANY changes to this project. Read .speclock/context/latest.md for project memory, goals, locks, and decisions. Run 'npx speclock check' before modifying locked files.",
|
|
860
|
+
};
|
|
861
|
+
|
|
862
|
+
// Write back with same formatting
|
|
863
|
+
const indent = raw.match(/^(\s+)/m)?.[1] || " ";
|
|
864
|
+
fs.writeFileSync(pkgPath, JSON.stringify(pkg, null, indent) + "\n");
|
|
865
|
+
|
|
866
|
+
return { success: true };
|
|
867
|
+
} catch (err) {
|
|
868
|
+
return { success: false, error: `Failed to modify package.json: ${err.message}` };
|
|
869
|
+
}
|
|
870
|
+
}
|
|
871
|
+
|
|
827
872
|
export function unguardFile(root, relativeFilePath) {
|
|
828
873
|
const fullPath = path.join(root, relativeFilePath);
|
|
829
874
|
if (!fs.existsSync(fullPath)) {
|