@planu/cli 0.63.1 → 0.63.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/dist/engine/dashboard/server.d.ts.map +1 -1
- package/dist/engine/dashboard/server.js +3 -2
- package/dist/engine/dashboard/server.js.map +1 -1
- package/dist/storage/hash-snapshot-store.d.ts.map +1 -1
- package/dist/storage/hash-snapshot-store.js +11 -4
- package/dist/storage/hash-snapshot-store.js.map +1 -1
- package/dist/storage/knowledge-store/knowledge.d.ts.map +1 -1
- package/dist/storage/knowledge-store/knowledge.js +27 -20
- package/dist/storage/knowledge-store/knowledge.js.map +1 -1
- package/dist/storage/metrics-store.d.ts.map +1 -1
- package/dist/storage/metrics-store.js +23 -14
- package/dist/storage/metrics-store.js.map +1 -1
- package/dist/storage/pattern-store.d.ts.map +1 -1
- package/dist/storage/pattern-store.js +65 -43
- package/dist/storage/pattern-store.js.map +1 -1
- package/dist/storage/sync-log-store.d.ts.map +1 -1
- package/dist/storage/sync-log-store.js +27 -18
- package/dist/storage/sync-log-store.js.map +1 -1
- package/dist/tools/git/hook-ops.d.ts.map +1 -1
- package/dist/tools/git/hook-ops.js +6 -7
- package/dist/tools/git/hook-ops.js.map +1 -1
- package/package.json +1 -1
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"server.d.ts","sourceRoot":"","sources":["../../../src/engine/dashboard/server.ts"],"names":[],"mappings":"AAKA,OAAO,KAAK,EAAE,oBAAoB,EAAE,MAAM,sBAAsB,CAAC;AAYjE,iDAAiD;AACjD,wBAAgB,iBAAiB,IAAI,oBAAoB,CAExD;AAED;;kEAEkE;AAClE,wBAAsB,oBAAoB,CAAC,IAAI,SAAO,GAAG,OAAO,CAAC,MAAM,CAAC,CAmCvE;AAED;;qCAEqC;AACrC,wBAAsB,mBAAmB,IAAI,OAAO,CAAC,MAAM,CAAC,CAsB3D;AAKD;kCACkC;AAClC,wBAAsB,0BAA0B,CAAC,QAAQ,SAAO,GAAG,OAAO,CAAC,MAAM,CAAC,CAsBjF;AAED,kFAAkF;AAClF,wBAAgB,WAAW,CAAC,GAAG,EAAE,MAAM,GAAG,OAAO,
|
|
1
|
+
{"version":3,"file":"server.d.ts","sourceRoot":"","sources":["../../../src/engine/dashboard/server.ts"],"names":[],"mappings":"AAKA,OAAO,KAAK,EAAE,oBAAoB,EAAE,MAAM,sBAAsB,CAAC;AAYjE,iDAAiD;AACjD,wBAAgB,iBAAiB,IAAI,oBAAoB,CAExD;AAED;;kEAEkE;AAClE,wBAAsB,oBAAoB,CAAC,IAAI,SAAO,GAAG,OAAO,CAAC,MAAM,CAAC,CAmCvE;AAED;;qCAEqC;AACrC,wBAAsB,mBAAmB,IAAI,OAAO,CAAC,MAAM,CAAC,CAsB3D;AAKD;kCACkC;AAClC,wBAAsB,0BAA0B,CAAC,QAAQ,SAAO,GAAG,OAAO,CAAC,MAAM,CAAC,CAsBjF;AAED,kFAAkF;AAClF,wBAAgB,WAAW,CAAC,GAAG,EAAE,MAAM,GAAG,OAAO,CAoBhD;AAED,2EAA2E;AAC3E,wBAAgB,uBAAuB,IAAI,IAAI,CAY9C"}
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
// engine/dashboard/server.ts — Singleton HTTP server for the Planu dashboard.
|
|
2
2
|
// Binds to 127.0.0.1 (localhost-only). Runs in the same process as the MCP server.
|
|
3
3
|
import { createServer } from 'node:http';
|
|
4
|
-
import {
|
|
4
|
+
import { execFile } from 'node:child_process';
|
|
5
5
|
import { handleRequest } from './routes.js';
|
|
6
6
|
/** Singleton state — lives as long as the process */
|
|
7
7
|
const state = {
|
|
@@ -112,7 +112,8 @@ export function openBrowser(url) {
|
|
|
112
112
|
cmd = 'xdg-open';
|
|
113
113
|
}
|
|
114
114
|
try {
|
|
115
|
-
const
|
|
115
|
+
const args = platform === 'win32' ? ['', url] : [url];
|
|
116
|
+
const child = execFile(cmd, args);
|
|
116
117
|
child.unref();
|
|
117
118
|
return true;
|
|
118
119
|
}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"server.js","sourceRoot":"","sources":["../../../src/engine/dashboard/server.ts"],"names":[],"mappings":"AAAA,8EAA8E;AAC9E,mFAAmF;AAEnF,OAAO,EAAE,YAAY,EAAe,MAAM,WAAW,CAAC;AACtD,OAAO,EAAE,
|
|
1
|
+
{"version":3,"file":"server.js","sourceRoot":"","sources":["../../../src/engine/dashboard/server.ts"],"names":[],"mappings":"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"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"hash-snapshot-store.d.ts","sourceRoot":"","sources":["../../src/storage/hash-snapshot-store.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"hash-snapshot-store.d.ts","sourceRoot":"","sources":["../../src/storage/hash-snapshot-store.ts"],"names":[],"mappings":"AAMA,OAAO,KAAK,EAAE,gBAAgB,EAAE,iBAAiB,EAAE,MAAM,mBAAmB,CAAC;AAgB7E;;GAEG;AACH,wBAAsB,WAAW,CAC/B,SAAS,EAAE,MAAM,EACjB,MAAM,EAAE,MAAM,GACb,OAAO,CAAC,gBAAgB,GAAG,IAAI,CAAC,CAElC;AAED;;GAEG;AACH,wBAAsB,YAAY,CAChC,SAAS,EAAE,MAAM,EACjB,MAAM,EAAE,MAAM,EACd,QAAQ,EAAE,gBAAgB,GACzB,OAAO,CAAC,IAAI,CAAC,CAKf;AAED;;GAEG;AACH,wBAAsB,eAAe,CACnC,SAAS,EAAE,MAAM,EACjB,MAAM,EAAE,MAAM,GACb,OAAO,CAAC,iBAAiB,EAAE,CAAC,CAE9B;AAED;;GAEG;AACH,wBAAsB,kBAAkB,CACtC,SAAS,EAAE,MAAM,EACjB,MAAM,EAAE,MAAM,EACd,OAAO,EAAE,iBAAiB,EAAE,GAC3B,OAAO,CAAC,IAAI,CAAC,CAOf"}
|
|
@@ -2,6 +2,7 @@
|
|
|
2
2
|
// Stores snapshots in data/projects/{hash}/spec-hashes/{specId}.json
|
|
3
3
|
// Append-only: old snapshots are archived, not deleted.
|
|
4
4
|
import { projectDataDir, readJson, writeJson } from './base-store.js';
|
|
5
|
+
import { withFileLock } from './file-mutex.js';
|
|
5
6
|
/**
|
|
6
7
|
* Get the file path for a spec's hash snapshot.
|
|
7
8
|
*/
|
|
@@ -24,7 +25,10 @@ export async function getSnapshot(projectId, specId) {
|
|
|
24
25
|
* Save a spec's hash snapshot.
|
|
25
26
|
*/
|
|
26
27
|
export async function saveSnapshot(projectId, specId, snapshot) {
|
|
27
|
-
|
|
28
|
+
const path = snapshotPath(projectId, specId);
|
|
29
|
+
await withFileLock(path, async () => {
|
|
30
|
+
await writeJson(path, snapshot);
|
|
31
|
+
});
|
|
28
32
|
}
|
|
29
33
|
/**
|
|
30
34
|
* Load reconcile log entries for a spec.
|
|
@@ -36,8 +40,11 @@ export async function getReconcileLog(projectId, specId) {
|
|
|
36
40
|
* Append entries to the reconcile log for a spec.
|
|
37
41
|
*/
|
|
38
42
|
export async function appendReconcileLog(projectId, specId, entries) {
|
|
39
|
-
const
|
|
40
|
-
|
|
41
|
-
|
|
43
|
+
const path = reconcileLogPath(projectId, specId);
|
|
44
|
+
await withFileLock(path, async () => {
|
|
45
|
+
const existing = await readJson(path, []);
|
|
46
|
+
existing.push(...entries);
|
|
47
|
+
await writeJson(path, existing);
|
|
48
|
+
});
|
|
42
49
|
}
|
|
43
50
|
//# sourceMappingURL=hash-snapshot-store.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"hash-snapshot-store.js","sourceRoot":"","sources":["../../src/storage/hash-snapshot-store.ts"],"names":[],"mappings":"AAAA,uEAAuE;AACvE,qEAAqE;AACrE,wDAAwD;AAExD,OAAO,EAAE,cAAc,EAAE,QAAQ,EAAE,SAAS,EAAE,MAAM,iBAAiB,CAAC;
|
|
1
|
+
{"version":3,"file":"hash-snapshot-store.js","sourceRoot":"","sources":["../../src/storage/hash-snapshot-store.ts"],"names":[],"mappings":"AAAA,uEAAuE;AACvE,qEAAqE;AACrE,wDAAwD;AAExD,OAAO,EAAE,cAAc,EAAE,QAAQ,EAAE,SAAS,EAAE,MAAM,iBAAiB,CAAC;AACtE,OAAO,EAAE,YAAY,EAAE,MAAM,iBAAiB,CAAC;AAG/C;;GAEG;AACH,SAAS,YAAY,CAAC,SAAiB,EAAE,MAAc;IACrD,OAAO,GAAG,cAAc,CAAC,SAAS,CAAC,gBAAgB,MAAM,OAAO,CAAC;AACnE,CAAC;AAED;;GAEG;AACH,SAAS,gBAAgB,CAAC,SAAiB,EAAE,MAAc;IACzD,OAAO,GAAG,cAAc,CAAC,SAAS,CAAC,gBAAgB,MAAM,qBAAqB,CAAC;AACjF,CAAC;AAED;;GAEG;AACH,MAAM,CAAC,KAAK,UAAU,WAAW,CAC/B,SAAiB,EACjB,MAAc;IAEd,OAAO,QAAQ,CAA0B,YAAY,CAAC,SAAS,EAAE,MAAM,CAAC,EAAE,IAAI,CAAC,CAAC;AAClF,CAAC;AAED;;GAEG;AACH,MAAM,CAAC,KAAK,UAAU,YAAY,CAChC,SAAiB,EACjB,MAAc,EACd,QAA0B;IAE1B,MAAM,IAAI,GAAG,YAAY,CAAC,SAAS,EAAE,MAAM,CAAC,CAAC;IAC7C,MAAM,YAAY,CAAC,IAAI,EAAE,KAAK,IAAI,EAAE;QAClC,MAAM,SAAS,CAAC,IAAI,EAAE,QAAQ,CAAC,CAAC;IAClC,CAAC,CAAC,CAAC;AACL,CAAC;AAED;;GAEG;AACH,MAAM,CAAC,KAAK,UAAU,eAAe,CACnC,SAAiB,EACjB,MAAc;IAEd,OAAO,QAAQ,CAAsB,gBAAgB,CAAC,SAAS,EAAE,MAAM,CAAC,EAAE,EAAE,CAAC,CAAC;AAChF,CAAC;AAED;;GAEG;AACH,MAAM,CAAC,KAAK,UAAU,kBAAkB,CACtC,SAAiB,EACjB,MAAc,EACd,OAA4B;IAE5B,MAAM,IAAI,GAAG,gBAAgB,CAAC,SAAS,EAAE,MAAM,CAAC,CAAC;IACjD,MAAM,YAAY,CAAC,IAAI,EAAE,KAAK,IAAI,EAAE;QAClC,MAAM,QAAQ,GAAG,MAAM,QAAQ,CAAsB,IAAI,EAAE,EAAE,CAAC,CAAC;QAC/D,QAAQ,CAAC,IAAI,CAAC,GAAG,OAAO,CAAC,CAAC;QAC1B,MAAM,SAAS,CAAC,IAAI,EAAE,QAAQ,CAAC,CAAC;IAClC,CAAC,CAAC,CAAC;AACL,CAAC"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"knowledge.d.ts","sourceRoot":"","sources":["../../../src/storage/knowledge-store/knowledge.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,gBAAgB,EAAE,MAAM,sBAAsB,CAAC;
|
|
1
|
+
{"version":3,"file":"knowledge.d.ts","sourceRoot":"","sources":["../../../src/storage/knowledge-store/knowledge.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,gBAAgB,EAAE,MAAM,sBAAsB,CAAC;AAI7D,iBAAS,aAAa,CAAC,SAAS,EAAE,MAAM,GAAG,MAAM,CAEhD;AAED;;GAEG;AACH,wBAAsB,YAAY,CAAC,SAAS,EAAE,MAAM,GAAG,OAAO,CAAC,gBAAgB,GAAG,IAAI,CAAC,CAEtF;AAED;;GAEG;AACH,wBAAsB,aAAa,CAAC,SAAS,EAAE,MAAM,EAAE,SAAS,EAAE,gBAAgB,GAAG,OAAO,CAAC,IAAI,CAAC,CAIjG;AAED;;GAEG;AACH,wBAAsB,eAAe,CACnC,SAAS,EAAE,MAAM,EACjB,OAAO,EAAE,OAAO,CAAC,gBAAgB,CAAC,GACjC,OAAO,CAAC,gBAAgB,CAAC,CAe3B;AAED;;GAEG;AACH,wBAAsB,eAAe,CAAC,SAAS,EAAE,MAAM,GAAG,OAAO,CAAC,OAAO,CAAC,CAUzE;AAED,OAAO,EAAE,aAAa,EAAE,CAAC"}
|
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
import { readJson, writeJson, projectDataDir } from '../base-store.js';
|
|
2
|
+
import { withFileLock } from '../file-mutex.js';
|
|
2
3
|
function knowledgeFile(projectId) {
|
|
3
4
|
return `${projectDataDir(projectId)}/knowledge.json`;
|
|
4
5
|
}
|
|
@@ -12,36 +13,42 @@ export async function getKnowledge(projectId) {
|
|
|
12
13
|
* Save or overwrite the full project knowledge object.
|
|
13
14
|
*/
|
|
14
15
|
export async function saveKnowledge(projectId, knowledge) {
|
|
15
|
-
await
|
|
16
|
+
await withFileLock(knowledgeFile(projectId), async () => {
|
|
17
|
+
await writeJson(knowledgeFile(projectId), knowledge);
|
|
18
|
+
});
|
|
16
19
|
}
|
|
17
20
|
/**
|
|
18
21
|
* Partially update project knowledge, merging with the existing object.
|
|
19
22
|
*/
|
|
20
23
|
export async function updateKnowledge(projectId, updates) {
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
24
|
+
return withFileLock(knowledgeFile(projectId), async () => {
|
|
25
|
+
const existing = await readJson(knowledgeFile(projectId), null);
|
|
26
|
+
if (!existing) {
|
|
27
|
+
throw new Error(`No knowledge found for project "${projectId}". Use saveKnowledge first.`);
|
|
28
|
+
}
|
|
29
|
+
const updated = {
|
|
30
|
+
...existing,
|
|
31
|
+
...updates,
|
|
32
|
+
projectId, // never allow override
|
|
33
|
+
lastAnalyzed: new Date().toISOString(),
|
|
34
|
+
};
|
|
35
|
+
await writeJson(knowledgeFile(projectId), updated);
|
|
36
|
+
return updated;
|
|
37
|
+
});
|
|
33
38
|
}
|
|
34
39
|
/**
|
|
35
40
|
* Delete all knowledge for a project. Returns `true` if it existed.
|
|
36
41
|
*/
|
|
37
42
|
export async function deleteKnowledge(projectId) {
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
43
|
+
return withFileLock(knowledgeFile(projectId), async () => {
|
|
44
|
+
const existing = await readJson(knowledgeFile(projectId), null);
|
|
45
|
+
if (!existing) {
|
|
46
|
+
return false;
|
|
47
|
+
}
|
|
48
|
+
// Overwrite with null sentinel so readJson returns null on next read
|
|
49
|
+
await writeJson(knowledgeFile(projectId), null);
|
|
50
|
+
return true;
|
|
51
|
+
});
|
|
45
52
|
}
|
|
46
53
|
export { knowledgeFile };
|
|
47
54
|
//# sourceMappingURL=knowledge.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"knowledge.js","sourceRoot":"","sources":["../../../src/storage/knowledge-store/knowledge.ts"],"names":[],"mappings":"AAEA,OAAO,EAAE,QAAQ,EAAE,SAAS,EAAE,cAAc,EAAE,MAAM,kBAAkB,CAAC;
|
|
1
|
+
{"version":3,"file":"knowledge.js","sourceRoot":"","sources":["../../../src/storage/knowledge-store/knowledge.ts"],"names":[],"mappings":"AAEA,OAAO,EAAE,QAAQ,EAAE,SAAS,EAAE,cAAc,EAAE,MAAM,kBAAkB,CAAC;AACvE,OAAO,EAAE,YAAY,EAAE,MAAM,kBAAkB,CAAC;AAEhD,SAAS,aAAa,CAAC,SAAiB;IACtC,OAAO,GAAG,cAAc,CAAC,SAAS,CAAC,iBAAiB,CAAC;AACvD,CAAC;AAED;;GAEG;AACH,MAAM,CAAC,KAAK,UAAU,YAAY,CAAC,SAAiB;IAClD,OAAO,QAAQ,CAA0B,aAAa,CAAC,SAAS,CAAC,EAAE,IAAI,CAAC,CAAC;AAC3E,CAAC;AAED;;GAEG;AACH,MAAM,CAAC,KAAK,UAAU,aAAa,CAAC,SAAiB,EAAE,SAA2B;IAChF,MAAM,YAAY,CAAC,aAAa,CAAC,SAAS,CAAC,EAAE,KAAK,IAAI,EAAE;QACtD,MAAM,SAAS,CAAC,aAAa,CAAC,SAAS,CAAC,EAAE,SAAS,CAAC,CAAC;IACvD,CAAC,CAAC,CAAC;AACL,CAAC;AAED;;GAEG;AACH,MAAM,CAAC,KAAK,UAAU,eAAe,CACnC,SAAiB,EACjB,OAAkC;IAElC,OAAO,YAAY,CAAC,aAAa,CAAC,SAAS,CAAC,EAAE,KAAK,IAAI,EAAE;QACvD,MAAM,QAAQ,GAAG,MAAM,QAAQ,CAA0B,aAAa,CAAC,SAAS,CAAC,EAAE,IAAI,CAAC,CAAC;QACzF,IAAI,CAAC,QAAQ,EAAE,CAAC;YACd,MAAM,IAAI,KAAK,CAAC,mCAAmC,SAAS,6BAA6B,CAAC,CAAC;QAC7F,CAAC;QACD,MAAM,OAAO,GAAqB;YAChC,GAAG,QAAQ;YACX,GAAG,OAAO;YACV,SAAS,EAAE,uBAAuB;YAClC,YAAY,EAAE,IAAI,IAAI,EAAE,CAAC,WAAW,EAAE;SACvC,CAAC;QACF,MAAM,SAAS,CAAC,aAAa,CAAC,SAAS,CAAC,EAAE,OAAO,CAAC,CAAC;QACnD,OAAO,OAAO,CAAC;IACjB,CAAC,CAAC,CAAC;AACL,CAAC;AAED;;GAEG;AACH,MAAM,CAAC,KAAK,UAAU,eAAe,CAAC,SAAiB;IACrD,OAAO,YAAY,CAAC,aAAa,CAAC,SAAS,CAAC,EAAE,KAAK,IAAI,EAAE;QACvD,MAAM,QAAQ,GAAG,MAAM,QAAQ,CAA0B,aAAa,CAAC,SAAS,CAAC,EAAE,IAAI,CAAC,CAAC;QACzF,IAAI,CAAC,QAAQ,EAAE,CAAC;YACd,OAAO,KAAK,CAAC;QACf,CAAC;QACD,qEAAqE;QACrE,MAAM,SAAS,CAAC,aAAa,CAAC,SAAS,CAAC,EAAE,IAAI,CAAC,CAAC;QAChD,OAAO,IAAI,CAAC;IACd,CAAC,CAAC,CAAC;AACL,CAAC;AAED,OAAO,EAAE,aAAa,EAAE,CAAC"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"metrics-store.d.ts","sourceRoot":"","sources":["../../src/storage/metrics-store.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAE,cAAc,EAAE,WAAW,EAAE,UAAU,EAAE,WAAW,EAAE,MAAM,mBAAmB,CAAC;
|
|
1
|
+
{"version":3,"file":"metrics-store.d.ts","sourceRoot":"","sources":["../../src/storage/metrics-store.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAE,cAAc,EAAE,WAAW,EAAE,UAAU,EAAE,WAAW,EAAE,MAAM,mBAAmB,CAAC;AA4B9F;;GAEG;AACH,wBAAsB,iBAAiB,CAAC,SAAS,EAAE,MAAM,GAAG,OAAO,CAAC,cAAc,CAAC,CAElF;AAED;;GAEG;AACH,wBAAsB,cAAc,CAClC,SAAS,EAAE,MAAM,EACjB,KAAK,EAAE,WAAW,GACjB,OAAO,CAAC,cAAc,CAAC,CAOzB;AAED;;GAEG;AACH,wBAAsB,sBAAsB,CAC1C,SAAS,EAAE,MAAM,EACjB,UAAU,EAAE,UAAU,GACrB,OAAO,CAAC,WAAW,EAAE,CAAC,CAGxB;AAED;;GAEG;AACH,wBAAsB,iBAAiB,CAAC,SAAS,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,GAAG,OAAO,CAAC,WAAW,EAAE,CAAC,CAGjG;AAED;;;GAGG;AACH,wBAAsB,kBAAkB,CAAC,SAAS,EAAE,MAAM,GAAG,OAAO,CAAC,MAAM,CAAC,CAO3E;AAED;;;GAGG;AACH,wBAAsB,oBAAoB,CAAC,SAAS,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,GAAG,OAAO,CAAC,MAAM,CAAC,CAW7F;AAED;;GAEG;AACH,wBAAsB,YAAY,CAAC,SAAS,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC,CAInE;AAYD;;GAEG;AACH,wBAAsB,cAAc,CAAC,SAAS,EAAE,MAAM,GAAG,OAAO,CAAC,WAAW,CAAC,CAE5E;AAED;;GAEG;AACH,wBAAsB,eAAe,CAAC,SAAS,EAAE,MAAM,EAAE,MAAM,EAAE,WAAW,GAAG,OAAO,CAAC,IAAI,CAAC,CAI3F"}
|
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
import { readJson, writeJson, projectDataDir } from './base-store.js';
|
|
2
|
+
import { withFileLock } from './file-mutex.js';
|
|
2
3
|
// --- internal helpers ---
|
|
3
4
|
function metricsFile(projectId) {
|
|
4
5
|
return `${projectDataDir(projectId)}/metrics.json`;
|
|
@@ -26,10 +27,12 @@ export async function getMetricsHistory(projectId) {
|
|
|
26
27
|
* Add a completed-spec metric entry.
|
|
27
28
|
*/
|
|
28
29
|
export async function addMetricEntry(projectId, entry) {
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
30
|
+
return withFileLock(metricsFile(projectId), async () => {
|
|
31
|
+
const history = await loadHistory(projectId);
|
|
32
|
+
history.entries.push(entry);
|
|
33
|
+
await saveHistory(projectId, history);
|
|
34
|
+
return history;
|
|
35
|
+
});
|
|
33
36
|
}
|
|
34
37
|
/**
|
|
35
38
|
* Get metric entries filtered by difficulty level.
|
|
@@ -62,20 +65,24 @@ export async function getAverageAccuracy(projectId) {
|
|
|
62
65
|
* Returns the number of entries removed.
|
|
63
66
|
*/
|
|
64
67
|
export async function deleteMetricsForSpec(projectId, specId) {
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
68
|
+
return withFileLock(metricsFile(projectId), async () => {
|
|
69
|
+
const history = await loadHistory(projectId);
|
|
70
|
+
const before = history.entries.length;
|
|
71
|
+
history.entries = history.entries.filter((e) => e.specId !== specId);
|
|
72
|
+
const removed = before - history.entries.length;
|
|
73
|
+
if (removed > 0) {
|
|
74
|
+
await saveHistory(projectId, history);
|
|
75
|
+
}
|
|
76
|
+
return removed;
|
|
77
|
+
});
|
|
73
78
|
}
|
|
74
79
|
/**
|
|
75
80
|
* Clear all metrics for a project.
|
|
76
81
|
*/
|
|
77
82
|
export async function clearMetrics(projectId) {
|
|
78
|
-
await
|
|
83
|
+
await withFileLock(metricsFile(projectId), async () => {
|
|
84
|
+
await saveHistory(projectId, emptyHistory(projectId));
|
|
85
|
+
});
|
|
79
86
|
}
|
|
80
87
|
// --- Token Budget ---
|
|
81
88
|
const DEFAULT_BUDGET = {
|
|
@@ -95,6 +102,8 @@ export async function getTokenBudget(projectId) {
|
|
|
95
102
|
* Save / update the token budget for a project.
|
|
96
103
|
*/
|
|
97
104
|
export async function saveTokenBudget(projectId, budget) {
|
|
98
|
-
await
|
|
105
|
+
await withFileLock(budgetFile(projectId), async () => {
|
|
106
|
+
await writeJson(budgetFile(projectId), budget);
|
|
107
|
+
});
|
|
99
108
|
}
|
|
100
109
|
//# sourceMappingURL=metrics-store.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"metrics-store.js","sourceRoot":"","sources":["../../src/storage/metrics-store.ts"],"names":[],"mappings":"AAGA,OAAO,EAAE,QAAQ,EAAE,SAAS,EAAE,cAAc,EAAE,MAAM,iBAAiB,CAAC;
|
|
1
|
+
{"version":3,"file":"metrics-store.js","sourceRoot":"","sources":["../../src/storage/metrics-store.ts"],"names":[],"mappings":"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"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"pattern-store.d.ts","sourceRoot":"","sources":["../../src/storage/pattern-store.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,mBAAmB,CAAC;
|
|
1
|
+
{"version":3,"file":"pattern-store.d.ts","sourceRoot":"","sources":["../../src/storage/pattern-store.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,mBAAmB,CAAC;AAoBxD;;GAEG;AACH,wBAAsB,YAAY,CAAC,SAAS,EAAE,MAAM,GAAG,OAAO,CAAC,cAAc,EAAE,CAAC,CAE/E;AAED;;GAEG;AACH,wBAAsB,UAAU,CAC9B,SAAS,EAAE,MAAM,EACjB,SAAS,EAAE,MAAM,GAChB,OAAO,CAAC,cAAc,GAAG,IAAI,CAAC,CAGhC;AAED;;GAEG;AACH,wBAAsB,UAAU,CAC9B,SAAS,EAAE,MAAM,EACjB,OAAO,EAAE,cAAc,GACtB,OAAO,CAAC,cAAc,CAAC,CAazB;AAED;;GAEG;AACH,wBAAsB,aAAa,CACjC,SAAS,EAAE,MAAM,EACjB,SAAS,EAAE,MAAM,EACjB,OAAO,EAAE,OAAO,CAAC,cAAc,CAAC,GAC/B,OAAO,CAAC,cAAc,CAAC,CAwBzB;AAED;;GAEG;AACH,wBAAsB,qBAAqB,CACzC,SAAS,EAAE,MAAM,EACjB,SAAS,EAAE,MAAM,GAChB,OAAO,CAAC,cAAc,CAAC,CAoBzB;AAED;;GAEG;AACH,wBAAsB,aAAa,CAAC,SAAS,EAAE,MAAM,EAAE,SAAS,EAAE,MAAM,GAAG,OAAO,CAAC,OAAO,CAAC,CAa1F;AAED;;GAEG;AACH,wBAAsB,kBAAkB,CACtC,SAAS,EAAE,MAAM,EACjB,IAAI,EAAE,cAAc,CAAC,MAAM,CAAC,GAC3B,OAAO,CAAC,cAAc,EAAE,CAAC,CAG3B;AAED;;GAEG;AACH,wBAAsB,YAAY,CAChC,SAAS,EAAE,MAAM,EACjB,SAAS,EAAE,CAAC,OAAO,EAAE,cAAc,KAAK,OAAO,GAC9C,OAAO,CAAC,cAAc,EAAE,CAAC,CAG3B;AAED;;GAEG;AACH,wBAAsB,aAAa,CAAC,SAAS,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC,CAIpE"}
|
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
import { readJson, writeJson, projectDataDir } from './base-store.js';
|
|
2
|
+
import { withFileLock } from './file-mutex.js';
|
|
2
3
|
// --- internal helpers ---
|
|
3
4
|
function patternsFile(projectId) {
|
|
4
5
|
return `${projectDataDir(projectId)}/patterns.json`;
|
|
@@ -27,69 +28,88 @@ export async function getPattern(projectId, patternId) {
|
|
|
27
28
|
* Add a new learned pattern.
|
|
28
29
|
*/
|
|
29
30
|
export async function addPattern(projectId, pattern) {
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
31
|
+
await withFileLock(patternsFile(projectId), async () => {
|
|
32
|
+
const patterns = await loadAll(projectId);
|
|
33
|
+
// If a pattern with the same ID already exists, update it instead
|
|
34
|
+
const idx = patterns.findIndex((p) => p.id === pattern.id);
|
|
35
|
+
if (idx !== -1) {
|
|
36
|
+
patterns[idx] = pattern;
|
|
37
|
+
}
|
|
38
|
+
else {
|
|
39
|
+
patterns.push(pattern);
|
|
40
|
+
}
|
|
41
|
+
await saveAll(projectId, patterns);
|
|
42
|
+
});
|
|
40
43
|
return pattern;
|
|
41
44
|
}
|
|
42
45
|
/**
|
|
43
46
|
* Update an existing pattern. Throws if not found.
|
|
44
47
|
*/
|
|
45
48
|
export async function updatePattern(projectId, patternId, updates) {
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
49
|
+
let updated;
|
|
50
|
+
await withFileLock(patternsFile(projectId), async () => {
|
|
51
|
+
const patterns = await loadAll(projectId);
|
|
52
|
+
const idx = patterns.findIndex((p) => p.id === patternId);
|
|
53
|
+
if (idx === -1) {
|
|
54
|
+
throw new Error(`Pattern "${patternId}" not found in project "${projectId}"`);
|
|
55
|
+
}
|
|
56
|
+
const existing = patterns[idx];
|
|
57
|
+
if (!existing) {
|
|
58
|
+
throw new Error(`Pattern "${patternId}" not found in project "${projectId}"`);
|
|
59
|
+
}
|
|
60
|
+
updated = {
|
|
61
|
+
...existing,
|
|
62
|
+
...updates,
|
|
63
|
+
id: patternId, // never allow id override
|
|
64
|
+
};
|
|
65
|
+
patterns[idx] = updated;
|
|
66
|
+
await saveAll(projectId, patterns);
|
|
67
|
+
});
|
|
68
|
+
if (!updated) {
|
|
53
69
|
throw new Error(`Pattern "${patternId}" not found in project "${projectId}"`);
|
|
54
70
|
}
|
|
55
|
-
const updated = {
|
|
56
|
-
...existing,
|
|
57
|
-
...updates,
|
|
58
|
-
id: patternId, // never allow id override
|
|
59
|
-
};
|
|
60
|
-
patterns[idx] = updated;
|
|
61
|
-
await saveAll(projectId, patterns);
|
|
62
71
|
return updated;
|
|
63
72
|
}
|
|
64
73
|
/**
|
|
65
74
|
* Increment the usage count of a pattern.
|
|
66
75
|
*/
|
|
67
76
|
export async function incrementPatternUsage(projectId, patternId) {
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
77
|
+
let result;
|
|
78
|
+
await withFileLock(patternsFile(projectId), async () => {
|
|
79
|
+
const patterns = await loadAll(projectId);
|
|
80
|
+
const idx = patterns.findIndex((p) => p.id === patternId);
|
|
81
|
+
if (idx === -1) {
|
|
82
|
+
throw new Error(`Pattern "${patternId}" not found in project "${projectId}"`);
|
|
83
|
+
}
|
|
84
|
+
const pattern = patterns[idx];
|
|
85
|
+
if (!pattern) {
|
|
86
|
+
throw new Error(`Pattern "${patternId}" not found in project "${projectId}"`);
|
|
87
|
+
}
|
|
88
|
+
pattern.usageCount += 1;
|
|
89
|
+
result = pattern;
|
|
90
|
+
await saveAll(projectId, patterns);
|
|
91
|
+
});
|
|
92
|
+
if (!result) {
|
|
75
93
|
throw new Error(`Pattern "${patternId}" not found in project "${projectId}"`);
|
|
76
94
|
}
|
|
77
|
-
|
|
78
|
-
await saveAll(projectId, patterns);
|
|
79
|
-
return pattern;
|
|
95
|
+
return result;
|
|
80
96
|
}
|
|
81
97
|
/**
|
|
82
98
|
* Delete a pattern by ID. Returns `true` if removed, `false` if not found.
|
|
83
99
|
*/
|
|
84
100
|
export async function deletePattern(projectId, patternId) {
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
101
|
+
let removed = false;
|
|
102
|
+
await withFileLock(patternsFile(projectId), async () => {
|
|
103
|
+
const patterns = await loadAll(projectId);
|
|
104
|
+
const idx = patterns.findIndex((p) => p.id === patternId);
|
|
105
|
+
if (idx === -1) {
|
|
106
|
+
return;
|
|
107
|
+
}
|
|
108
|
+
patterns.splice(idx, 1);
|
|
109
|
+
await saveAll(projectId, patterns);
|
|
110
|
+
removed = true;
|
|
111
|
+
});
|
|
112
|
+
return removed;
|
|
93
113
|
}
|
|
94
114
|
/**
|
|
95
115
|
* Find patterns by type.
|
|
@@ -109,6 +129,8 @@ export async function findPatterns(projectId, predicate) {
|
|
|
109
129
|
* Clear all patterns for a project.
|
|
110
130
|
*/
|
|
111
131
|
export async function clearPatterns(projectId) {
|
|
112
|
-
await
|
|
132
|
+
await withFileLock(patternsFile(projectId), async () => {
|
|
133
|
+
await saveAll(projectId, []);
|
|
134
|
+
});
|
|
113
135
|
}
|
|
114
136
|
//# sourceMappingURL=pattern-store.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"pattern-store.js","sourceRoot":"","sources":["../../src/storage/pattern-store.ts"],"names":[],"mappings":"AAGA,OAAO,EAAE,QAAQ,EAAE,SAAS,EAAE,cAAc,EAAE,MAAM,iBAAiB,CAAC;
|
|
1
|
+
{"version":3,"file":"pattern-store.js","sourceRoot":"","sources":["../../src/storage/pattern-store.ts"],"names":[],"mappings":"AAGA,OAAO,EAAE,QAAQ,EAAE,SAAS,EAAE,cAAc,EAAE,MAAM,iBAAiB,CAAC;AACtE,OAAO,EAAE,YAAY,EAAE,MAAM,iBAAiB,CAAC;AAE/C,2BAA2B;AAE3B,SAAS,YAAY,CAAC,SAAiB;IACrC,OAAO,GAAG,cAAc,CAAC,SAAS,CAAC,gBAAgB,CAAC;AACtD,CAAC;AAED,KAAK,UAAU,OAAO,CAAC,SAAiB;IACtC,OAAO,QAAQ,CAAmB,YAAY,CAAC,SAAS,CAAC,EAAE,EAAE,CAAC,CAAC;AACjE,CAAC;AAED,KAAK,UAAU,OAAO,CAAC,SAAiB,EAAE,QAA0B;IAClE,MAAM,SAAS,CAAC,YAAY,CAAC,SAAS,CAAC,EAAE,QAAQ,CAAC,CAAC;AACrD,CAAC;AAED,qBAAqB;AAErB;;GAEG;AACH,MAAM,CAAC,KAAK,UAAU,YAAY,CAAC,SAAiB;IAClD,OAAO,OAAO,CAAC,SAAS,CAAC,CAAC;AAC5B,CAAC;AAED;;GAEG;AACH,MAAM,CAAC,KAAK,UAAU,UAAU,CAC9B,SAAiB,EACjB,SAAiB;IAEjB,MAAM,QAAQ,GAAG,MAAM,OAAO,CAAC,SAAS,CAAC,CAAC;IAC1C,OAAO,QAAQ,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,EAAE,KAAK,SAAS,CAAC,IAAI,IAAI,CAAC;AAC1D,CAAC;AAED;;GAEG;AACH,MAAM,CAAC,KAAK,UAAU,UAAU,CAC9B,SAAiB,EACjB,OAAuB;IAEvB,MAAM,YAAY,CAAC,YAAY,CAAC,SAAS,CAAC,EAAE,KAAK,IAAI,EAAE;QACrD,MAAM,QAAQ,GAAG,MAAM,OAAO,CAAC,SAAS,CAAC,CAAC;QAC1C,kEAAkE;QAClE,MAAM,GAAG,GAAG,QAAQ,CAAC,SAAS,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,EAAE,KAAK,OAAO,CAAC,EAAE,CAAC,CAAC;QAC3D,IAAI,GAAG,KAAK,CAAC,CAAC,EAAE,CAAC;YACf,QAAQ,CAAC,GAAG,CAAC,GAAG,OAAO,CAAC;QAC1B,CAAC;aAAM,CAAC;YACN,QAAQ,CAAC,IAAI,CAAC,OAAO,CAAC,CAAC;QACzB,CAAC;QACD,MAAM,OAAO,CAAC,SAAS,EAAE,QAAQ,CAAC,CAAC;IACrC,CAAC,CAAC,CAAC;IACH,OAAO,OAAO,CAAC;AACjB,CAAC;AAED;;GAEG;AACH,MAAM,CAAC,KAAK,UAAU,aAAa,CACjC,SAAiB,EACjB,SAAiB,EACjB,OAAgC;IAEhC,IAAI,OAAmC,CAAC;IACxC,MAAM,YAAY,CAAC,YAAY,CAAC,SAAS,CAAC,EAAE,KAAK,IAAI,EAAE;QACrD,MAAM,QAAQ,GAAG,MAAM,OAAO,CAAC,SAAS,CAAC,CAAC;QAC1C,MAAM,GAAG,GAAG,QAAQ,CAAC,SAAS,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,EAAE,KAAK,SAAS,CAAC,CAAC;QAC1D,IAAI,GAAG,KAAK,CAAC,CAAC,EAAE,CAAC;YACf,MAAM,IAAI,KAAK,CAAC,YAAY,SAAS,2BAA2B,SAAS,GAAG,CAAC,CAAC;QAChF,CAAC;QACD,MAAM,QAAQ,GAAG,QAAQ,CAAC,GAAG,CAAC,CAAC;QAC/B,IAAI,CAAC,QAAQ,EAAE,CAAC;YACd,MAAM,IAAI,KAAK,CAAC,YAAY,SAAS,2BAA2B,SAAS,GAAG,CAAC,CAAC;QAChF,CAAC;QACD,OAAO,GAAG;YACR,GAAG,QAAQ;YACX,GAAG,OAAO;YACV,EAAE,EAAE,SAAS,EAAE,0BAA0B;SAC1C,CAAC;QACF,QAAQ,CAAC,GAAG,CAAC,GAAG,OAAO,CAAC;QACxB,MAAM,OAAO,CAAC,SAAS,EAAE,QAAQ,CAAC,CAAC;IACrC,CAAC,CAAC,CAAC;IACH,IAAI,CAAC,OAAO,EAAE,CAAC;QACb,MAAM,IAAI,KAAK,CAAC,YAAY,SAAS,2BAA2B,SAAS,GAAG,CAAC,CAAC;IAChF,CAAC;IACD,OAAO,OAAO,CAAC;AACjB,CAAC;AAED;;GAEG;AACH,MAAM,CAAC,KAAK,UAAU,qBAAqB,CACzC,SAAiB,EACjB,SAAiB;IAEjB,IAAI,MAAkC,CAAC;IACvC,MAAM,YAAY,CAAC,YAAY,CAAC,SAAS,CAAC,EAAE,KAAK,IAAI,EAAE;QACrD,MAAM,QAAQ,GAAG,MAAM,OAAO,CAAC,SAAS,CAAC,CAAC;QAC1C,MAAM,GAAG,GAAG,QAAQ,CAAC,SAAS,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,EAAE,KAAK,SAAS,CAAC,CAAC;QAC1D,IAAI,GAAG,KAAK,CAAC,CAAC,EAAE,CAAC;YACf,MAAM,IAAI,KAAK,CAAC,YAAY,SAAS,2BAA2B,SAAS,GAAG,CAAC,CAAC;QAChF,CAAC;QACD,MAAM,OAAO,GAAG,QAAQ,CAAC,GAAG,CAAC,CAAC;QAC9B,IAAI,CAAC,OAAO,EAAE,CAAC;YACb,MAAM,IAAI,KAAK,CAAC,YAAY,SAAS,2BAA2B,SAAS,GAAG,CAAC,CAAC;QAChF,CAAC;QACD,OAAO,CAAC,UAAU,IAAI,CAAC,CAAC;QACxB,MAAM,GAAG,OAAO,CAAC;QACjB,MAAM,OAAO,CAAC,SAAS,EAAE,QAAQ,CAAC,CAAC;IACrC,CAAC,CAAC,CAAC;IACH,IAAI,CAAC,MAAM,EAAE,CAAC;QACZ,MAAM,IAAI,KAAK,CAAC,YAAY,SAAS,2BAA2B,SAAS,GAAG,CAAC,CAAC;IAChF,CAAC;IACD,OAAO,MAAM,CAAC;AAChB,CAAC;AAED;;GAEG;AACH,MAAM,CAAC,KAAK,UAAU,aAAa,CAAC,SAAiB,EAAE,SAAiB;IACtE,IAAI,OAAO,GAAG,KAAK,CAAC;IACpB,MAAM,YAAY,CAAC,YAAY,CAAC,SAAS,CAAC,EAAE,KAAK,IAAI,EAAE;QACrD,MAAM,QAAQ,GAAG,MAAM,OAAO,CAAC,SAAS,CAAC,CAAC;QAC1C,MAAM,GAAG,GAAG,QAAQ,CAAC,SAAS,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,EAAE,KAAK,SAAS,CAAC,CAAC;QAC1D,IAAI,GAAG,KAAK,CAAC,CAAC,EAAE,CAAC;YACf,OAAO;QACT,CAAC;QACD,QAAQ,CAAC,MAAM,CAAC,GAAG,EAAE,CAAC,CAAC,CAAC;QACxB,MAAM,OAAO,CAAC,SAAS,EAAE,QAAQ,CAAC,CAAC;QACnC,OAAO,GAAG,IAAI,CAAC;IACjB,CAAC,CAAC,CAAC;IACH,OAAO,OAAO,CAAC;AACjB,CAAC;AAED;;GAEG;AACH,MAAM,CAAC,KAAK,UAAU,kBAAkB,CACtC,SAAiB,EACjB,IAA4B;IAE5B,MAAM,QAAQ,GAAG,MAAM,OAAO,CAAC,SAAS,CAAC,CAAC;IAC1C,OAAO,QAAQ,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,IAAI,KAAK,IAAI,CAAC,CAAC;AACjD,CAAC;AAED;;GAEG;AACH,MAAM,CAAC,KAAK,UAAU,YAAY,CAChC,SAAiB,EACjB,SAA+C;IAE/C,MAAM,QAAQ,GAAG,MAAM,OAAO,CAAC,SAAS,CAAC,CAAC;IAC1C,OAAO,QAAQ,CAAC,MAAM,CAAC,SAAS,CAAC,CAAC;AACpC,CAAC;AAED;;GAEG;AACH,MAAM,CAAC,KAAK,UAAU,aAAa,CAAC,SAAiB;IACnD,MAAM,YAAY,CAAC,YAAY,CAAC,SAAS,CAAC,EAAE,KAAK,IAAI,EAAE;QACrD,MAAM,OAAO,CAAC,SAAS,EAAE,EAAE,CAAC,CAAC;IAC/B,CAAC,CAAC,CAAC;AACL,CAAC"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"sync-log-store.d.ts","sourceRoot":"","sources":["../../src/storage/sync-log-store.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"sync-log-store.d.ts","sourceRoot":"","sources":["../../src/storage/sync-log-store.ts"],"names":[],"mappings":"AAKA,OAAO,KAAK,EAAE,YAAY,EAAE,YAAY,EAAE,MAAM,mBAAmB,CAAC;AAUpE;;GAEG;AACH,wBAAsB,UAAU,CAAC,SAAS,EAAE,MAAM,GAAG,OAAO,CAAC,YAAY,EAAE,CAAC,CAE3E;AAED;;GAEG;AACH,wBAAsB,aAAa,CAAC,SAAS,EAAE,MAAM,EAAE,OAAO,EAAE,YAAY,EAAE,GAAG,OAAO,CAAC,IAAI,CAAC,CAQ7F;AAED;;GAEG;AACH,wBAAsB,YAAY,CAAC,SAAS,EAAE,MAAM,GAAG,OAAO,CAAC,YAAY,EAAE,CAAC,CAE7E;AAED;;GAEG;AACH,wBAAsB,aAAa,CAAC,SAAS,EAAE,MAAM,EAAE,SAAS,EAAE,YAAY,EAAE,GAAG,OAAO,CAAC,IAAI,CAAC,CAI/F;AAED;;GAEG;AACH,wBAAsB,YAAY,CAAC,SAAS,EAAE,MAAM,EAAE,YAAY,EAAE,YAAY,EAAE,GAAG,OAAO,CAAC,IAAI,CAAC,CAMjG;AAED;;GAEG;AACH,wBAAsB,eAAe,CACnC,SAAS,EAAE,MAAM,EACjB,UAAU,EAAE,MAAM,EAClB,UAAU,EAAE,MAAM,GACjB,OAAO,CAAC,YAAY,GAAG,IAAI,CAAC,CAa9B"}
|
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
// storage/sync-log-store.ts — Sync log and conflicts persistence
|
|
2
2
|
// Stores sync logs in data/projects/{hash}/spec-sync-log/
|
|
3
3
|
import { projectDataDir, readJson, writeJson } from './base-store.js';
|
|
4
|
+
import { withFileLock } from './file-mutex.js';
|
|
4
5
|
function syncLogPath(projectId) {
|
|
5
6
|
return `${projectDataDir(projectId)}/spec-sync-log/sync-log.json`;
|
|
6
7
|
}
|
|
@@ -17,11 +18,13 @@ export async function getSyncLog(projectId) {
|
|
|
17
18
|
* Append entries to the sync log.
|
|
18
19
|
*/
|
|
19
20
|
export async function appendSyncLog(projectId, entries) {
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
21
|
+
await withFileLock(syncLogPath(projectId), async () => {
|
|
22
|
+
const existing = await readJson(syncLogPath(projectId), []);
|
|
23
|
+
existing.push(...entries);
|
|
24
|
+
// Keep last 500 entries to prevent unbounded growth
|
|
25
|
+
const trimmed = existing.length > 500 ? existing.slice(existing.length - 500) : existing;
|
|
26
|
+
await writeJson(syncLogPath(projectId), trimmed);
|
|
27
|
+
});
|
|
25
28
|
}
|
|
26
29
|
/**
|
|
27
30
|
* Load active (unresolved) conflicts.
|
|
@@ -33,28 +36,34 @@ export async function getConflicts(projectId) {
|
|
|
33
36
|
* Save conflicts list.
|
|
34
37
|
*/
|
|
35
38
|
export async function saveConflicts(projectId, conflicts) {
|
|
36
|
-
await
|
|
39
|
+
await withFileLock(conflictsPath(projectId), async () => {
|
|
40
|
+
await writeJson(conflictsPath(projectId), conflicts);
|
|
41
|
+
});
|
|
37
42
|
}
|
|
38
43
|
/**
|
|
39
44
|
* Add new conflicts (merges with existing unresolved).
|
|
40
45
|
*/
|
|
41
46
|
export async function addConflicts(projectId, newConflicts) {
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
47
|
+
await withFileLock(conflictsPath(projectId), async () => {
|
|
48
|
+
const existing = await readJson(conflictsPath(projectId), []);
|
|
49
|
+
const merged = [...existing, ...newConflicts];
|
|
50
|
+
await writeJson(conflictsPath(projectId), merged);
|
|
51
|
+
});
|
|
45
52
|
}
|
|
46
53
|
/**
|
|
47
54
|
* Resolve a conflict by ID.
|
|
48
55
|
*/
|
|
49
56
|
export async function resolveConflict(projectId, conflictId, resolution) {
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
57
|
+
return withFileLock(conflictsPath(projectId), async () => {
|
|
58
|
+
const conflicts = await readJson(conflictsPath(projectId), []);
|
|
59
|
+
const conflict = conflicts.find((c) => c.id === conflictId);
|
|
60
|
+
if (!conflict) {
|
|
61
|
+
return null;
|
|
62
|
+
}
|
|
63
|
+
conflict.resolved = true;
|
|
64
|
+
conflict.resolution = resolution;
|
|
65
|
+
await writeJson(conflictsPath(projectId), conflicts);
|
|
66
|
+
return conflict;
|
|
67
|
+
});
|
|
59
68
|
}
|
|
60
69
|
//# sourceMappingURL=sync-log-store.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"sync-log-store.js","sourceRoot":"","sources":["../../src/storage/sync-log-store.ts"],"names":[],"mappings":"AAAA,iEAAiE;AACjE,0DAA0D;AAE1D,OAAO,EAAE,cAAc,EAAE,QAAQ,EAAE,SAAS,EAAE,MAAM,iBAAiB,CAAC;
|
|
1
|
+
{"version":3,"file":"sync-log-store.js","sourceRoot":"","sources":["../../src/storage/sync-log-store.ts"],"names":[],"mappings":"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"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"hook-ops.d.ts","sourceRoot":"","sources":["../../../src/tools/git/hook-ops.ts"],"names":[],"mappings":"AAGA,OAAO,KAAK,EAAE,UAAU,EAAE,SAAS,EAAe,MAAM,sBAAsB,CAAC;
|
|
1
|
+
{"version":3,"file":"hook-ops.d.ts","sourceRoot":"","sources":["../../../src/tools/git/hook-ops.ts"],"names":[],"mappings":"AAGA,OAAO,KAAK,EAAE,UAAU,EAAE,SAAS,EAAe,MAAM,sBAAsB,CAAC;AAkL/E,wBAAsB,gBAAgB,CAAC,SAAS,EAAE,MAAM,EAAE,MAAM,CAAC,EAAE,SAAS,GAAG,OAAO,CAAC,UAAU,CAAC,CAyCjG"}
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
// tools/git/hook-ops.ts — Hook operations: setup-hooks with manager detection
|
|
2
|
-
import { writeFile, mkdir, access } from 'node:fs/promises';
|
|
2
|
+
import { writeFile, mkdir, access, readFile } from 'node:fs/promises';
|
|
3
3
|
import { join } from 'node:path';
|
|
4
|
-
import { git, resolveProjectPath, mergeConfig, DEFAULT_PROTECTED_BRANCHES
|
|
4
|
+
import { git, resolveProjectPath, mergeConfig, DEFAULT_PROTECTED_BRANCHES } from './git-helpers.js';
|
|
5
5
|
async function detectHookManager(projectPath) {
|
|
6
6
|
// Check for husky
|
|
7
7
|
try {
|
|
@@ -28,11 +28,10 @@ async function detectHookManager(projectPath) {
|
|
|
28
28
|
}
|
|
29
29
|
// Check for simple-git-hooks in package.json
|
|
30
30
|
try {
|
|
31
|
-
const
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
if (stdout.trim() && stdout.trim() !== '[]') {
|
|
31
|
+
const pkgRaw = await readFile(join(projectPath, 'package.json'), 'utf-8');
|
|
32
|
+
const pkg = JSON.parse(pkgRaw);
|
|
33
|
+
const sgh = pkg['simple-git-hooks'];
|
|
34
|
+
if (sgh && typeof sgh === 'object' && Object.keys(sgh).length > 0) {
|
|
36
35
|
return 'simple-git-hooks';
|
|
37
36
|
}
|
|
38
37
|
}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"hook-ops.js","sourceRoot":"","sources":["../../../src/tools/git/hook-ops.ts"],"names":[],"mappings":"AAAA,8EAA8E;AAC9E,OAAO,EAAE,SAAS,EAAE,KAAK,EAAE,MAAM,EAAE,MAAM,kBAAkB,CAAC;
|
|
1
|
+
{"version":3,"file":"hook-ops.js","sourceRoot":"","sources":["../../../src/tools/git/hook-ops.ts"],"names":[],"mappings":"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"}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@planu/cli",
|
|
3
|
-
"version": "0.63.
|
|
3
|
+
"version": "0.63.2",
|
|
4
4
|
"description": "Planu — MCP Server for Spec Driven Development. Manages specs, estimations, reverse engineering, and auto-learning across any language/framework.",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"main": "dist/index.js",
|