@programinglive/dev-workflow-mcp-server 1.13.7 → 1.13.9
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/workflow-state.js +43 -6
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@programinglive/dev-workflow-mcp-server",
|
|
3
|
-
"version": "1.13.
|
|
3
|
+
"version": "1.13.9",
|
|
4
4
|
"description": "MCP server to enforce development workflow discipline",
|
|
5
5
|
"homepage": "https://devworkflow.programinglive.com/",
|
|
6
6
|
"mcpName": "io.github.programinglive/dev-workflow-mcp-server",
|
package/workflow-state.js
CHANGED
|
@@ -223,18 +223,55 @@ function getUserScopedDir(baseDir) {
|
|
|
223
223
|
return path.join(baseDir, "users", userId);
|
|
224
224
|
}
|
|
225
225
|
|
|
226
|
-
|
|
226
|
+
/**
|
|
227
|
+
* Identitas user untuk baris database milik state ini.
|
|
228
|
+
*
|
|
229
|
+
* MENGAPA TIDAK MEMBACA CACHE MODUL
|
|
230
|
+
* ---------------------------------
|
|
231
|
+
* Versi sebelumnya hanya memakai `cachedUserId`, yang terisi lewat
|
|
232
|
+
* `resolveUserId()` - dan itu hanya dipanggil dari `resolveStateFile()`.
|
|
233
|
+
* Pemanggil yang membuat `WorkflowState` dengan path EKSPLISIT (skrip
|
|
234
|
+
* perbaikan, CLI, tes) tidak pernah memicunya, sehingga `syncToDatabase()`
|
|
235
|
+
* diam-diam menulis baris dengan `user_id = "default"`.
|
|
236
|
+
*
|
|
237
|
+
* Akibat nyata 30 Oktober 2026: satu proyek punya riwayat di dua identitas
|
|
238
|
+
* (`user-…` dan `default`) dalam database yang sama, dan 150 baris duplikat
|
|
239
|
+
* harus dibersihkan manual.
|
|
240
|
+
*
|
|
241
|
+
* Membaca langsung dari direktori `.state` milik state ini membuat hasilnya
|
|
242
|
+
* tidak bergantung pada direktori kerja proses, tidak bergantung pada urutan
|
|
243
|
+
* pemanggilan, dan tidak bocor antar proyek dalam satu proses.
|
|
244
|
+
*/
|
|
245
|
+
function getCurrentUserId(stateFile = null) {
|
|
227
246
|
const envUserId = (process.env.DEV_WORKFLOW_USER_ID || "").trim();
|
|
228
247
|
if (envUserId) {
|
|
229
248
|
return envUserId;
|
|
230
249
|
}
|
|
231
250
|
|
|
232
|
-
if (
|
|
233
|
-
|
|
251
|
+
if (stateFile) {
|
|
252
|
+
const stateDir = path.dirname(path.resolve(stateFile));
|
|
253
|
+
const userIdFile = path.join(stateDir, USER_ID_FILENAME);
|
|
254
|
+
|
|
255
|
+
try {
|
|
256
|
+
const stored = readFileSync(userIdFile, "utf-8").trim();
|
|
257
|
+
if (stored) {
|
|
258
|
+
return stored;
|
|
259
|
+
}
|
|
260
|
+
} catch {
|
|
261
|
+
// Berkas belum ada: jatuh ke pencarian di bawah.
|
|
262
|
+
}
|
|
263
|
+
|
|
264
|
+
// .state langsung (bukan .state/users/<id>): pakai resolveUserId, yang
|
|
265
|
+
// menangani migrasi id lama maupun pembuatan id baru.
|
|
266
|
+
try {
|
|
267
|
+
return resolveUserId(stateDir);
|
|
268
|
+
} catch {
|
|
269
|
+
// Biarkan jatuh ke nilai cadangan di bawah.
|
|
270
|
+
}
|
|
234
271
|
}
|
|
235
272
|
|
|
236
|
-
if (
|
|
237
|
-
return
|
|
273
|
+
if (cachedUserId) {
|
|
274
|
+
return cachedUserId;
|
|
238
275
|
}
|
|
239
276
|
|
|
240
277
|
return "default";
|
|
@@ -1014,7 +1051,7 @@ export class WorkflowState {
|
|
|
1014
1051
|
async syncToDatabase(options = {}) {
|
|
1015
1052
|
assertSafeKnowledge(this.state);
|
|
1016
1053
|
const db = options.db ?? (await import("./db/index.js"));
|
|
1017
|
-
const userId = getCurrentUserId();
|
|
1054
|
+
const userId = getCurrentUserId(this.stateFile);
|
|
1018
1055
|
// projectRoot dipakai sebagai identitas proyek di database. Ditentukan
|
|
1019
1056
|
// lewat resolveProjectRootForState, bukan dengan menghitung `dirname`
|
|
1020
1057
|
// berkali-kali: jumlah itu hanya benar untuk satu kedalaman tertentu.
|