dodo-mcp 1.4.0 → 1.4.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.
Files changed (36) hide show
  1. package/README.md +10 -1
  2. package/dist/auth/interactions.js +8 -0
  3. package/dist/auth/interactions.js.map +1 -1
  4. package/dist/auth/verifier.js +4 -0
  5. package/dist/auth/verifier.js.map +1 -1
  6. package/dist/server/bootstrap.js +12 -3
  7. package/dist/server/bootstrap.js.map +1 -1
  8. package/dist/server/configUi/app.js +13 -1
  9. package/dist/server/configUi/index.html +4 -4
  10. package/dist/server/configUi/ui/recovery.js +32 -46
  11. package/dist/server/configUi/workbench.css +3 -0
  12. package/dist/server/configUi/workbench.js +75 -4
  13. package/dist/server/installationRuntime.js +6 -1
  14. package/dist/server/installationRuntime.js.map +1 -1
  15. package/dist/services/ai/contracts.js +1 -1
  16. package/dist/services/ai/contracts.js.map +1 -1
  17. package/dist/services/recovery/contracts.js +2 -0
  18. package/dist/services/recovery/contracts.js.map +1 -1
  19. package/dist/services/recovery/drift.js +48 -27
  20. package/dist/services/recovery/drift.js.map +1 -1
  21. package/dist/services/recovery/history.js +48 -23
  22. package/dist/services/recovery/history.js.map +1 -1
  23. package/dist/services/recovery/recoveryService.js +136 -62
  24. package/dist/services/recovery/recoveryService.js.map +1 -1
  25. package/dist/services/recovery/storage.js +21 -7
  26. package/dist/services/recovery/storage.js.map +1 -1
  27. package/dist/store/db.js +75 -0
  28. package/dist/store/db.js.map +1 -1
  29. package/dist/tools/directTools.js +1 -1
  30. package/dist/tools/directTools.js.map +1 -1
  31. package/docs/RECOVERY.md +57 -18
  32. package/docs/RELEASE_1.4.1.md +14 -0
  33. package/docs/RELEASE_1.4.2.md +66 -0
  34. package/docs/RELEASE_NOTES.md +23 -0
  35. package/docs/TEST_REPORT.md +45 -0
  36. package/package.json +3 -1
package/README.md CHANGED
@@ -619,6 +619,11 @@ npm pack
619
619
  ### Recovery — สำรองและกู้คืนงาน
620
620
 
621
621
  โปรเจกต์ที่ลงทะเบียนเปิด source backup เป็นค่าเริ่มต้น ก่อนแก้ไฟล์หรือรันคำสั่ง
622
+ ตั้งแต่ **1.4.2** การสำรองอัตโนมัติเป็น best effort: หากสำรองไม่ได้ งานปกติยังทำต่อได้
623
+ แม้รีสตาร์ตหรือมีค่า strict/Git requirement เดิม ระบบแสดงคำเตือนและ `blockedPath`
624
+ พร้อม `skippedSecretFiles` และ `operationsBlocked:false` ใน `project_overview`
625
+ ค่าเลือกข้ามไฟล์ที่มีเนื้อหาคล้าย Secret เก็บถาวรต่อโปรเจกต์ ส่วน checkpoint ที่สั่งเอง
626
+ และการกู้คืนตามแผนยังต้องผ่านการตรวจสำเนาและ integrity จริง
622
627
  หน้า **Projects → Recovery** ใช้ตรวจประวัติ เปรียบเทียบ และยืนยันแผนกู้คืนได้จริง
623
628
  หรือใช้ `dodo recovery --help` ผ่าน terminal สำเนาอยู่ใน private state แยกจาก Git
624
629
  ของโปรเจกต์ และไม่ push ขึ้น GitHub อัตโนมัติ
@@ -632,7 +637,11 @@ npm pack
632
637
  **Source restore ไม่ย้อนฐานข้อมูล, secrets, volumes หรือระบบภายนอก** การสำรอง config
633
638
  ใช้กุญแจจาก OS credential store และไม่ส่งเนื้อหาให้ AI; ไม่มี generic database rollback
634
639
  หรือการ restart service อัตโนมัติ ดู [คู่มือ Recovery](docs/RECOVERY.md),
635
- [การเปลี่ยนแปลง 1.3.0](docs/RELEASE_1.3.0.md) และ [ผลตรวจรับจริง](docs/TEST_REPORT.md)
640
+ [การเปลี่ยนแปลง 1.4.2](docs/RELEASE_1.4.2.md) และ [ผลตรวจรับจริง](docs/TEST_REPORT.md)
641
+
642
+ อัปเดตด้วย `npm install -g dodo-mcp@1.4.2` แล้ว restart process ของ DODO ที่ใช้งานจริง
643
+ และเรียก `project_overview` ใหม่เพื่อรับ workspace epoch ปัจจุบัน การติดตั้งแพ็กเกจ
644
+ อย่างเดียวไม่เปลี่ยนโค้ดที่ process เดิมโหลดค้างอยู่
636
645
 
637
646
  ### จัดการพื้นที่สำรอง Recovery
638
647
 
@@ -132,6 +132,14 @@ export function interactionRouter(opts) {
132
132
  scopes: summary.scopes,
133
133
  });
134
134
  store.setMeta(`identity-grant:${grantId}`, '2');
135
+ if (!requestedScopes.some((s) => ALL_SCOPES.includes(s))) {
136
+ const storedInteraction = store.oauthFind('Interaction', details.uid);
137
+ if (storedInteraction && storedInteraction['params'] && typeof storedInteraction['params'] === 'object') {
138
+ const nextParams = { ...storedInteraction['params'] };
139
+ nextParams['scope'] = [...new Set([...requestedScopes.filter(Boolean), ...summary.scopes])].join(' ');
140
+ store.oauthUpsert('Interaction', details.uid, { ...storedInteraction, params: nextParams });
141
+ }
142
+ }
135
143
  const returnTo = await provider.interactionResult(req, res, { login: { accountId: OWNER_ACCOUNT_ID }, consent: { grantId } }, { mergeWithLastSubmission: false });
136
144
  res.setHeader('Cache-Control', 'no-store').json({ returnTo });
137
145
  }
@@ -1 +1 @@
1
- {"version":3,"file":"interactions.js","sourceRoot":"","sources":["../../src/auth/interactions.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"interactions.js","sourceRoot":"","sources":["../../src/auth/interactions.ts"],"names":[],"mappings":"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"}
@@ -1,6 +1,7 @@
1
1
  import { createLocalJWKSet, jwtVerify } from 'jose';
2
2
  import { OAuthError, OAuthErrorCode } from '@modelcontextprotocol/server';
3
3
  import { publicJwks } from './keys.js';
4
+ import { ALL_SCOPES } from '../security/policy.js';
4
5
  export function buildTokenVerifier(opts) {
5
6
  const jwkSet = createLocalJWKSet(publicJwks(opts.jwks));
6
7
  const active = () => {
@@ -47,6 +48,9 @@ export function buildTokenVerifier(opts) {
47
48
  throw new OAuthError(OAuthErrorCode.InvalidToken, 'token is not valid for this workspace');
48
49
  }
49
50
  let scopes = typeof payload['scope'] === 'string' ? payload['scope'].split(' ').filter(Boolean) : [];
51
+ if (!scopes.some((s) => ALL_SCOPES.includes(s))) {
52
+ scopes = [...grant.scopes];
53
+ }
50
54
  const tokenScopes = [...scopes];
51
55
  {
52
56
  const access = store.clientAccess(workspaceId, clientId);
@@ -1 +1 @@
1
- {"version":3,"file":"verifier.js","sourceRoot":"","sources":["../../src/auth/verifier.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"verifier.js","sourceRoot":"","sources":["../../src/auth/verifier.ts"],"names":[],"mappings":"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"}
@@ -133,10 +133,18 @@ export function bootstrapWorkspace(opts) {
133
133
  applier.beforeMutation = async (opts, files) => {
134
134
  await services.recovery.checkpoint('before-write', opts.principal, files.flatMap(f => [f.path, ...(f.destPath ? [f.destPath] : [])]));
135
135
  };
136
- applier.onCommitted = files => services.recovery.drift.committed(files);
137
- applier.onChangeset = id => services.recovery.history.record('changeset', id);
136
+ const recordRecovery = (record) => {
137
+ try {
138
+ record();
139
+ }
140
+ catch (error) {
141
+ services.recovery.reportBookkeepingFailure(error);
142
+ }
143
+ };
144
+ applier.onCommitted = files => recordRecovery(() => services.recovery.drift.committed(files));
145
+ applier.onChangeset = id => recordRecovery(() => services.recovery.history.record('changeset', id));
138
146
  jobs.withRecovery = (actor, fn) => services.recovery.history.around(actor, undefined, fn);
139
- jobs.onRecorded = id => services.recovery.history.record('job', id);
147
+ jobs.onRecorded = id => recordRecovery(() => services.recovery.history.record('job', id));
140
148
  jobs.afterFinished = () => services.recovery.observeJob();
141
149
  jobs.beforeStart = async (req) => { await services.recovery.checkpoint('before-exec', req.principal); };
142
150
  jobs.requiresPreparation = () => Boolean(store.db.prepare('SELECT 1 FROM project_registry WHERE workspace_id=? AND removed_at IS NULL').get(workspaceId));
@@ -153,6 +161,7 @@ export function bootstrapWorkspace(opts) {
153
161
  configDir,
154
162
  configDirSource,
155
163
  ...(configDirEnvVar ? { configDirEnvVar } : {}),
164
+ ...(opts.runMode ? { runMode: opts.runMode } : {}),
156
165
  paths,
157
166
  config,
158
167
  db,
@@ -1 +1 @@
1
- {"version":3,"file":"bootstrap.js","sourceRoot":"","sources":["../../src/server/bootstrap.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,eAAe,EAAE,MAAM,yCAAyC,CAAC;AAC1E,OAAO,EAAE,mBAAmB,EAAE,MAAM,mBAAmB,CAAC;AACxD,OAAO,EAAE,aAAa,EAAE,MAAM,8BAA8B,CAAC;AAC7D,OAAO,EAAE,cAAc,EAAE,aAAa,EAAE,MAAM,2BAA2B,CAAC;AAC1E,OAAO,EAAE,iBAAiB,EAAE,MAAM,6CAA6C,CAAC;AAChF,OAAO,EAAE,eAAe,EAAE,MAAM,0CAA0C,CAAC;AAC3E,OAAO,EAAE,mBAAmB,EAAE,MAAM,mCAAmC,CAAC;AACxE,OAAO,EAAE,oBAAoB,EAAE,MAAM,sCAAsC,CAAC;AAC5E,OAAO,EAAE,aAAa,EAAE,MAAM,qCAAqC,CAAC;AACpE,OAAO,EAAE,cAAc,EAAE,MAAM,uCAAuC,CAAC;AACvE,OAAO,EAAE,mBAAmB,EAAE,MAAM,mCAAmC,CAAC;AACxE,OAAO,EAAE,eAAe,EAAE,MAAM,0CAA0C,CAAC;AAC3E,OAAO,EAAE,cAAc,EAAE,MAAM,uCAAuC,CAAC;AACvE,OAAO,EAAE,oBAAoB,EAAE,MAAM,sCAAsC,CAAC;AAC5E,OAAO,EAAE,cAAc,EAAE,MAAM,uCAAuC,CAAC;AACvE,OAAO,EAAE,gBAAgB,EAAE,MAAM,mCAAmC,CAAC;AAErE,OAAO,EAAE,gBAAgB,EAAE,eAAe,EAAE,UAAU,EAA6C,MAAM,oBAAoB,CAAC;AAC9H,OAAO,EAAE,gBAAgB,EAAqB,MAAM,2BAA2B,CAAC;AAChF,OAAO,EAAE,iBAAiB,EAA4B,MAAM,4BAA4B,CAAC;AACzF,OAAO,EAAE,oBAAoB,EAAiB,MAAM,sBAAsB,CAAC;AAC3E,OAAO,EAAE,eAAe,EAAE,SAAS,EAAE,MAAM,0BAA0B,CAAC;AACtE,OAAO,EAAE,YAAY,EAAE,MAAM,yBAAyB,CAAC;AACvD,OAAO,EAAE,WAAW,EAAE,MAAM,oBAAoB,CAAC;AACjD,OAAO,EAAE,YAAY,EAAE,MAAM,gBAAgB,CAAC;AAC9C,OAAO,EAAE,KAAK,EAAE,MAAM,mBAAmB,CAAC;AAC1C,OAAO,EAAE,WAAW,EAAE,WAAW,EAAE,MAAM,kCAAkC,CAAC;AAC5E,OAAO,EAAE,aAAa,EAAE,MAAM,qCAAqC,CAAC;AACpE,OAAO,EAAE,OAAO,EAAE,MAAM,gCAAgC,CAAC;AACzD,OAAO,EAAE,OAAO,EAAE,MAAM,gCAAgC,CAAC;AACzD,OAAO,EAAE,UAAU,EAAE,MAAM,gCAAgC,CAAC;AAC5D,OAAO,EAAE,UAAU,EAAE,MAAM,+BAA+B,CAAC;AAC3D,OAAO,EAAE,YAAY,EAAE,MAAM,0CAA0C,CAAC;AACxE,OAAO,EAAE,eAAe,EAAE,MAAM,yBAAyB,CAAC;AAC1D,OAAO,EAAE,wBAAwB,EAAE,MAAM,mCAAmC,CAAC;AAE7E,OAAO,EAAE,YAAY,EAAE,MAAM,cAAc,CAAC;AAC5C,OAAO,EAAE,iBAAiB,EAAE,MAAM,2BAA2B,CAAC;AAuC9D,OAAO,EAAE,oBAAoB,EAAE,MAAM,0BAA0B,CAAC;AAEhE,MAAM,UAAU,kBAAkB,CAAC,IAAsB;IACvD,MAAM,EAAE,GAAG,EAAE,GAAG,IAAI,CAAC;IACrB,MAAM,gBAAgB,GAAG,IAAI,CAAC,SAAS,IAAI,gBAAgB,CAAC,OAAO,CAAC,GAAG,CAAC,CAAC;IACzE,MAAM,EAAE,GAAG,EAAE,SAAS,EAAE,MAAM,EAAE,eAAe,EAAE,MAAM,EAAE,eAAe,EAAE,GAAG,gBAAgB,CAAC;IAC9F,eAAe,CAAC,SAAS,CAAC,CAAC;IAC3B,MAAM,KAAK,GAAG,UAAU,CAAC,SAAS,CAAC,CAAC;IACpC,MAAM,MAAM,GAAG,gBAAgB,CAAC,KAAK,CAAC,UAAU,CAAC,CAAC;IAClD,IAAI,IAAI,CAAC,OAAO;QAAE,MAAM,CAAC,aAAa,GAAG,IAAI,CAAC;IAC9C,IAAI,IAAI,CAAC,OAAO,KAAK,QAAQ;QAAE,MAAM,CAAC,cAAc,GAAG,KAAK,CAAC;IAC7D,MAAM,MAAM,GAAG,MAAM,CAAC,MAAM,CAAC;IAE7B,MAAM,QAAQ,GAAG,oBAAoB,CAAC,IAAI,CAAC,YAAY,IAAI,IAAI,CAAC,UAAU,EAAE,EAAE,WAAW,EAAE,IAAI,CAAC,eAAe,IAAI,KAAK,EAAE,CAAC,CAAC;IAC5H,MAAM,YAAY,GAAG,mBAAmB,CAAC,SAAS,EAAE,QAAQ,CAAC,IAAI,CAAC,CAAC;IACnE,IAAI,QAAuC,CAAC;IAC5C,IAAI,CAAC;QACL,oBAAoB,CAAC,SAAS,EAAE,QAAQ,CAAC,IAAI,CAAC,CAAC;QAC/C,MAAM,EAAE,GAAG,YAAY,CAAC,KAAK,CAAC,MAAM,CAAC,CAAC;QAAC,QAAQ,GAAG,EAAE,CAAC;QACrD,MAAM,KAAK,GAAG,IAAI,KAAK,CAAC,EAAE,CAAC,CAAC;QAC5B,0EAA0E;QAC1E,0EAA0E;QAC1E,qEAAqE;QACrE,aAAa,CAAC,KAAK,EAAE,MAAM,CAAC,UAAU,CAAC,CAAC;QACxC,MAAM,aAAa,GAAG,KAAK,CAAC,aAAa,EAAE,CAAC;QAC5C,MAAM,WAAW,GAAG,eAAe,CAAC,aAAa,EAAE,QAAQ,CAAC,IAAI,CAAC,CAAC;QAClE,MAAM,KAAK,GAAG,SAAS,EAAE,CAAC;QAC1B,MAAM,UAAU,GAAG,KAAK,CAAC,YAAY,CAAC,WAAW,CAAC,CAAC;QACnD,IAAI,UAAU,IAAI,CAAC,UAAU,CAAC,GAAG,KAAK,QAAQ,CAAC,GAAG,IAAI,UAAU,CAAC,GAAG,KAAK,QAAQ,CAAC,GAAG,CAAC,EAAE,CAAC;YACvF,yEAAyE;YACzE,4DAA4D;YAC5D,KAAK,CAAC,EAAE,CAAC,OAAO,CAAC,oDAAoD,CAAC,CAAC,GAAG,CAAC,WAAW,CAAC,CAAC;YACxF,KAAK,CAAC,YAAY,CAAC,WAAW,EAAE,SAAS,CAAC,CAAC;YAC3C,GAAG,CAAC,kFAAkF,CAAC,CAAC;QAC1F,CAAC;QACD,KAAK,CAAC,eAAe,CAAC,EAAE,EAAE,EAAE,WAAW,EAAE,IAAI,EAAE,QAAQ,CAAC,IAAI,EAAE,GAAG,EAAE,QAAQ,CAAC,GAAG,EAAE,GAAG,EAAE,QAAQ,CAAC,GAAG,EAAE,KAAK,EAAE,CAAC,CAAC;QAC7G,MAAM,WAAW,GAAG,KAAK,CAAC,mBAAmB,CAAC,KAAK,EAAE,WAAW,CAAC,CAAC;QAClE,IAAI,WAAW,GAAG,CAAC;YAAE,GAAG,CAAC,UAAU,WAAW,2DAA2D,CAAC,CAAC;QAE3G,MAAM,aAAa,GAAG,iBAAiB,CAAC,QAAQ,CAAC,IAAI,CAAC,CAAC;QACvD,MAAM,OAAO,GAAG,IAAI,YAAY,CAAC;YAC/B,IAAI,EAAE,QAAQ,CAAC,IAAI;YACnB,gBAAgB,EAAE,MAAM,CAAC,gBAAgB;YACzC,mBAAmB,EAAE,MAAM,CAAC,UAAU;YACtC,WAAW,EAAE,MAAM,CAAC,WAAW;YAC/B,eAAe,EAAE,aAAa,CAAC,MAAM,CAAC,OAAO;SAC9C,CAAC,CAAC;QACH,MAAM,GAAG,GAAG,IAAI,WAAW,CAAC,QAAQ,CAAC,IAAI,EAAE,OAAO,CAAC,CAAC;QAEpD,MAAM,OAAO,GAAG,IAAI,OAAO,CAAC,GAAG,EAAE,MAAM,EAAE,KAAK,EAAE,KAAK,CAAC,UAAU,EAAE,WAAW,CAAC,CAAC;QAC/E,MAAM,KAAK,GAAG,OAAO,CAAC,eAAe,EAAE,CAAC;QACxC,IAAI,KAAK,CAAC,gBAAgB,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC;YACtC,GAAG,CAAC,mBAAmB,KAAK,CAAC,gBAAgB,CAAC,MAAM,yFAAyF,CAAC,CAAC;QACjJ,CAAC;QAED,MAAM,GAAG,GAAG,IAAI,UAAU,CAAC,GAAG,EAAE,MAAM,CAAC,CAAC;QACxC,MAAM,WAAW,GAAG,IAAI,WAAW,CAAC,GAAG,EAAE,MAAM,CAAC,CAAC;QACjD,MAAM,IAAI,GAAG,IAAI,UAAU,CAAC,GAAG,EAAE,MAAM,EAAE,KAAK,EAAE,KAAK,CAAC,OAAO,EAAE,MAAM,CAAC,YAAY,EAAE,wBAAwB,CAAC,MAAM,EAAE,QAAQ,CAAC,IAAI,EAAE,SAAS,CAAC,CAAC,CAAC;QAChJ,MAAM,KAAK,GAAG,IAAI,YAAY,CAC5B;YACE,IAAI,EAAE,QAAQ,CAAC,IAAI;YACnB,mBAAmB,EAAE,MAAM,CAAC,UAAU;YACtC,eAAe,EAAE,aAAa,CAAC,MAAM,CAAC,OAAO;YAC7C,gBAAgB,EAAE,MAAM,CAAC,gBAAgB;YACzC,gBAAgB,EAAE,IAAI,CAAC,GAAG,CAAC,MAAM,CAAC,aAAa,EAAE,GAAG,GAAG,IAAI,CAAC;SAC7D,EACD,MAAM,CACP,CAAC;QACF,MAAM,SAAS,GAAG,IAAI,aAAa,EAAE,CAAC;QACtC,IAAI,CAAC,SAAS,GAAG,SAAS,CAAC;QAC3B,MAAM,QAAQ,GAAgB;YAC5B,SAAS;YACT,UAAU,EAAE,IAAI,iBAAiB,CAAC,KAAK,EAAE,MAAM,EAAE,MAAM,CAAC;YACxD,SAAS,EAAE,IAAI,eAAe,CAAC,EAAC,KAAK,EAAC,WAAW,EAAC,KAAK,EAAC,GAAG,EAAC,IAAI,EAAC,MAAM,EAAC,MAAM,EAAC,CAAC;YAChF,OAAO,EAAE,YAAY;YACrB,MAAM;YACN,MAAM;YACN,KAAK;YACL,GAAG;YACH,WAAW,EAAE,IAAI,WAAW,CAAC,GAAG,EAAE,MAAM,CAAC;YACzC,WAAW;YACX,MAAM,EAAE,IAAI,aAAa,CAAC,GAAG,EAAE,MAAM,EAAE,MAAM,CAAC,aAAa,CAAC;YAC5D,OAAO,EAAE,IAAI,OAAO,CAAC,GAAG,EAAE,MAAM,EAAE,KAAK,EAAE,GAAG,EAAE,CAAC,MAAM,CAAC,iBAAiB,CAAC;YACxE,OAAO;YACP,IAAI;YACJ,GAAG;YACH,KAAK;YACL,QAAQ,EAAE,IAAI,eAAe,CAAC,GAAG,EAAE,MAAM,EAAE,WAAW,EAAE,GAAG,CAAC;YAC5D,OAAO,EAAE,IAAI,cAAc,CAAC,KAAK,EAAE,WAAW,EAAE,KAAK,EAAE,IAAI,oBAAoB,CAAC,SAAS,CAAC,CAAC;YAC3F,OAAO,EAAE,IAAI,cAAc,CAAC,KAAK,EAAE,GAAG,EAAE,WAAW,EAAE,KAAK,EAAE,IAAI,gBAAgB,CAAC,QAAQ,CAAC,IAAI,CAAC,EAAE,SAAS,CAAC;YAC3G,aAAa;YACb,WAAW;YACX,KAAK;YACL,yEAAyE;YACzE,2EAA2E;YAC3E,uEAAuE;YACvE,4DAA4D;YAC5D,SAAS,EAAE,GAAG,EAAE,CAAC,CAAC,IAAI,CAAC,OAAO,IAAI,cAAc,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,CAAC,SAAS,CAAC,CAAC,CAAC,KAAK,CAAC,SAAS,CAAC,WAAW,CAAC;SACpG,CAAC;QAEF,QAAQ,CAAC,QAAQ,GAAG,IAAI,eAAe,CAAC,QAAQ,EAAE,SAAS,CAAC,CAAC;QAC7D,OAAO,CAAC,cAAc,GAAG,KAAK,EAAE,IAAI,EAAE,KAAK,EAAE,EAAE;YAC7C,MAAM,QAAQ,CAAC,QAAS,CAAC,UAAU,CAAC,cAAc,EAAE,IAAI,CAAC,SAAS,EAAE,KAAK,CAAC,OAAO,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,IAAI,EAAE,GAAG,CAAC,CAAC,CAAC,QAAQ,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,QAAQ,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC;QACzI,CAAC,CAAC;QACF,OAAO,CAAC,WAAW,GAAG,KAAK,CAAC,EAAE,CAAC,QAAQ,CAAC,QAAS,CAAC,KAAK,CAAC,SAAS,CAAC,KAAK,CAAC,CAAC;QACzE,OAAO,CAAC,WAAW,GAAG,EAAE,CAAC,EAAE,CAAC,QAAQ,CAAC,QAAS,CAAC,OAAO,CAAC,MAAM,CAAC,WAAW,EAAC,EAAE,CAAC,CAAC;QAC9E,IAAI,CAAC,YAAY,GAAG,CAAC,KAAK,EAAC,EAAE,EAAE,EAAE,CAAC,QAAQ,CAAC,QAAS,CAAC,OAAO,CAAC,MAAM,CAAC,KAAK,EAAC,SAAS,EAAC,EAAE,CAAC,CAAC;QACxF,IAAI,CAAC,UAAU,GAAG,EAAE,CAAC,EAAE,CAAC,QAAQ,CAAC,QAAS,CAAC,OAAO,CAAC,MAAM,CAAC,KAAK,EAAC,EAAE,CAAC,CAAC;QACpE,IAAI,CAAC,aAAa,GAAG,GAAG,EAAE,CAAC,QAAQ,CAAC,QAAS,CAAC,UAAU,EAAE,CAAC;QAC3D,IAAI,CAAC,WAAW,GAAG,KAAK,EAAC,GAAG,EAAC,EAAE,GAAG,MAAM,QAAQ,CAAC,QAAS,CAAC,UAAU,CAAC,aAAa,EAAE,GAAG,CAAC,SAAS,CAAC,CAAC,CAAC,CAAC,CAAC;QACvG,IAAI,CAAC,mBAAmB,GAAG,GAAG,EAAE,CAAC,OAAO,CAAC,KAAK,CAAC,EAAE,CAAC,OAAO,CAAC,4EAA4E,CAAC,CAAC,GAAG,CAAC,WAAW,CAAC,CAAC,CAAC;QAC1J,QAAQ,CAAC,QAAQ,CAAC,QAAQ,EAAE,CAAC;QAE7B,QAAQ,CAAC,UAAU,GAAG,IAAI,iBAAiB,CAAC,QAAQ,EAAE,SAAS,CAAC,CAAC;QACjE,QAAQ,CAAC,SAAS,GAAG,IAAI,eAAe,CAAC,QAAQ,EAAE,SAAS,EAAE,KAAK,CAAC,gBAAgB,EAAE,KAAK,CAAC,kBAAkB,EAAE,aAAa,CAAC,CAAC;QAC/H,QAAQ,CAAC,KAAK,GAAG,IAAI,mBAAmB,CAAC,QAAQ,EAAE,aAAa,CAAC,CAAC;QAClE,QAAQ,CAAC,OAAO,GAAG,IAAI,cAAc,CAAC,QAAQ,CAAC,CAAC;QAChD,QAAQ,CAAC,YAAY,GAAG,IAAI,mBAAmB,CAAC,QAAQ,CAAC,CAAC;QAC1D,QAAQ,CAAC,aAAa,GAAG,IAAI,oBAAoB,CAAC,QAAQ,EAAE,aAAa,CAAC,CAAC;QAC3E,QAAQ,CAAC,MAAM,GAAG,IAAI,aAAa,CAAC,QAAQ,EAAE,aAAa,CAAC,CAAC;QAE7D,IAAI,MAAM,GAAG,KAAK,CAAC;QACnB,OAAO;YACL,SAAS;YACT,eAAe;YACf,GAAG,CAAC,eAAe,CAAC,CAAC,CAAC,EAAE,eAAe,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC;YAC/C,KAAK;YACL,MAAM;YACN,EAAE;YACF,KAAK;YACL,QAAQ;YACR,WAAW;YACX,KAAK;YACL,aAAa;YACb,QAAQ;YACR,KAAK,CAAC,gBAAgB;gBACpB,IAAI,MAAM;oBAAE,OAAO;gBACnB,MAAM,GAAG,IAAI,CAAC;gBACd,QAAQ,CAAC,SAAS,CAAC,IAAI,EAAE,CAAC;gBAC1B,MAAM,QAAQ,CAAC,QAAQ,EAAE,KAAK,EAAE,CAAC;gBACjC,QAAQ,CAAC,MAAM,EAAE,KAAK,EAAE,CAAC;gBACzB,QAAQ,CAAC,aAAa,EAAE,KAAK,EAAE,CAAC;gBAChC,QAAQ,CAAC,YAAY,EAAE,KAAK,EAAE,CAAC;gBAC/B,QAAQ,CAAC,OAAO,EAAE,KAAK,EAAE,CAAC;gBAC1B,MAAM,QAAQ,CAAC,KAAK,EAAE,KAAK,EAAE,CAAC;gBAC9B,MAAM,QAAQ,CAAC,UAAU,EAAE,KAAK,EAAE,CAAC;gBACnC,QAAQ,CAAC,SAAS,EAAE,KAAK,EAAE,CAAC;gBAC5B,MAAM,QAAQ,CAAC,OAAO,CAAC,KAAK,EAAE,CAAC;gBAC/B,MAAM,QAAQ,CAAC,OAAO,CAAC,KAAK,EAAE,CAAC;gBAC/B,IAAI,CAAC;oBACH,MAAM,QAAQ,CAAC,IAAI,CAAC,QAAQ,CAAC,IAAI,CAAC,CAAC;oBACnC,MAAM,QAAQ,CAAC,KAAK,CAAC,QAAQ,EAAE,CAAC;oBAChC,MAAM,QAAQ,CAAC,GAAG,EAAE,QAAQ,EAAE,CAAC;gBACjC,CAAC;gBAAC,MAAM,CAAC;oBACP,iBAAiB;gBACnB,CAAC;gBACD,IAAI,CAAC;oBACH,EAAE,CAAC,KAAK,EAAE,CAAC;oBACX,YAAY,EAAE,CAAC;gBACjB,CAAC;gBAAC,MAAM,CAAC;oBACP,oBAAoB;gBACtB,CAAC;YACH,CAAC;SACF,CAAC;IACF,CAAC;IAAC,OAAO,KAAK,EAAE,CAAC;QAAC,IAAI,CAAC;YAAC,QAAQ,EAAE,KAAK,EAAE,CAAC;QAAC,CAAC;gBAAS,CAAC;YAAC,YAAY,EAAE,CAAC;QAAC,CAAC;QAAC,MAAM,KAAK,CAAC;IAAC,CAAC;AACzF,CAAC"}
1
+ {"version":3,"file":"bootstrap.js","sourceRoot":"","sources":["../../src/server/bootstrap.ts"],"names":[],"mappings":"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"}
@@ -541,7 +541,19 @@
541
541
  await loadProjects(true);
542
542
  } catch (error) { notify('error', `นำโปรเจกต์ออกไม่สำเร็จ: ${error.message}`); }
543
543
  }));
544
- actions.append(switchButton, removeButton);
544
+ const wbButton = document.createElement('button'); wbButton.type = 'button'; wbButton.className = 'btn small'; wbButton.textContent = 'ตั้งค่า Recovery / สิทธิ์ไฟล์';
545
+ wbButton.disabled = !project.available;
546
+ wbButton.addEventListener('click', () => {
547
+ const picker = $('wb-project');
548
+ const selectBtn = $('wb-select');
549
+ if (picker && selectBtn) {
550
+ picker.value = project.projectId;
551
+ selectBtn.click();
552
+ const wbEl = $('workbench');
553
+ if (wbEl && typeof wbEl.scrollIntoView === 'function') wbEl.scrollIntoView({ behavior: 'smooth', block: 'start' });
554
+ }
555
+ });
556
+ actions.append(switchButton, wbButton, removeButton);
545
557
  article.append(head, root, accessRow, description, details, actions);
546
558
  list.append(article);
547
559
  }
@@ -134,8 +134,8 @@
134
134
  <div class="input-row">
135
135
  <select id="project-add-access" name="access">
136
136
  <option value="read">อ่านอย่างเดียว — อ่าน ค้นหา วิเคราะห์</option>
137
- <option value="edit" selected>แก้ไข — อ่านและแก้ไฟล์</option>
138
- <option value="full">ทำงานเต็มรูปแบบ — อ่าน แก้ไฟล์ และรันคำสั่ง/ทดสอบ</option>
137
+ <option value="edit">แก้ไข — อ่านและแก้ไฟล์</option>
138
+ <option value="full" selected>ทำงานเต็มรูปแบบ — อ่าน แก้ไฟล์ และรันคำสั่ง/ทดสอบ</option>
139
139
  </select>
140
140
  <button type="submit" class="btn primary" id="project-add">เพิ่มโปรเจกต์</button>
141
141
  </div>
@@ -211,8 +211,8 @@
211
211
  <fieldset class="checks">
212
212
  <legend>สิทธิ์ในโฟลเดอร์นี้</legend>
213
213
  <label class="check"><input type="checkbox" name="scope" value="dodo:read" checked><span>อ่านและค้นหา</span></label>
214
- <label class="check"><input type="checkbox" name="scope" value="dodo:write"><span>แก้ไฟล์</span></label>
215
- <label class="check"><input type="checkbox" name="scope" value="dodo:exec"><span>รันคำสั่งตาม trust mode</span></label>
214
+ <label class="check"><input type="checkbox" name="scope" value="dodo:write" checked><span>แก้ไฟล์</span></label>
215
+ <label class="check"><input type="checkbox" name="scope" value="dodo:exec" checked><span>รันคำสั่งตาม trust mode</span></label>
216
216
  </fieldset>
217
217
  <button type="submit" class="btn primary" id="client-add-save">เพิ่มและบันทึกสิทธิ์</button>
218
218
  </form>
@@ -171,13 +171,13 @@ window.DodoRecovery=({el,section,button,check,field,choice,notice,confirmDanger,
171
171
  const box=section('การเปลี่ยนไฟล์นอก journal','เปรียบเทียบ hash จริง ไม่ระบุว่าใครแก้จากเวลาไฟล์ การยอมรับสถานะไม่ใช่ผลทดสอบและไม่เพิ่มสิทธิ์');parent.append(box);
172
172
  const view=el('div');box.append(view);
173
173
  function render(d){
174
- view.replaceChildren(el('p',d.state==='external_changes'?`พบ ${d.changedCount} รายการ · ไม่ทราบผู้แก้${d.critical?' · ต้องตรวจทานก่อนรันคำสั่ง':''}`:d.state==='unchanged'?'ไม่พบการเปลี่ยนจากสถานะที่บันทึก':d.state==='unavailable'?`ตรวจไม่สำเร็จ: ${d.errorCode}`:'ยังไม่ได้สแกน'));
174
+ view.replaceChildren(el('p',d.state==='external_changes'?`พบ ${d.changedCount} รายการ · ไม่ทราบผู้แก้${d.critical?' · แนะนำให้ตรวจทานก่อนรันคำสั่ง':''}`:d.state==='unchanged'?'ไม่พบการเปลี่ยนจากสถานะที่บันทึก':d.state==='unavailable'?`ตรวจไม่สำเร็จ: ${d.errorCode} · ไม่บล็อกงานปกติ`:'ยังไม่ได้สแกน'));
175
175
  if(d.changedCount){
176
176
  const list=el('ul');for(const c of d.changes)list.append(el('li',`${c.change} · ${c.path} · ${c.beforeHash?.slice(0,12)||'ไม่มี'} → ${c.observedHash?.slice(0,12)||'ไม่มี'}`));view.append(list);
177
177
  if(d.truncated){view.append(el('p','ยังมีรายการถัดไป การยืนยันใช้กับการเปลี่ยนแปลงทั้งหมดที่ระบุ'));view.append(button('ดูรายการเปลี่ยนแปลงถัดไป',async()=>render(await act('recovery.drift.scan',{cursor:d.nextCursor}))));}
178
178
  view.append(el('p','สำเนาที่ตรวจพบแยกจาก baseline เดิม ไม่รับรองว่ามี bytes ก่อนถูกเขียนทับ หากยังไม่เคยสำรอง'));
179
179
  view.append(button('ยอมรับสถานะที่ตรวจนี้',async()=>{
180
- if(!await confirmDanger('ยอมรับไฟล์ที่เปลี่ยน?',`มี ${d.changedCount} รายการ การยืนยันอนุญาตให้ทำงานต่อจากสถานะนี้ ไม่ได้กู้ไฟล์กลับ`,'ยอมรับสถานะ'))return;
180
+ if(!await confirmDanger('ยอมรับไฟล์ที่เปลี่ยน?',`มี ${d.changedCount} รายการ การยืนยันบันทึกสถานะที่ตรวจแล้วเป็น baseline ใหม่ ไม่ได้กู้ไฟล์กลับ`,'ยอมรับสถานะ'))return;
181
181
  const result=await act('recovery.drift.acknowledge',{digest:d.digest,workspaceId:selected.workspaceId,workspaceEpoch:selected.workspaceEpoch,confirm:true});render(result);notice('บันทึกสถานะที่เจ้าของตรวจแล้ว');
182
182
  }));
183
183
  }
@@ -191,26 +191,31 @@ window.DodoRecovery=({el,section,button,check,field,choice,notice,confirmDanger,
191
191
  const status=el('p','กำลังตรวจสอบจุดกู้คืน…','wb-status');status.setAttribute('role','status');card.append(status);
192
192
  const selected={...getSelected()};
193
193
  const act=(operation,args={})=>api('admin/action',{projectId:selected.projectId,operation,args},true);
194
+ const retryBackup=async()=>{
195
+ const result=await act('recovery.reset');
196
+ notice(result.state==='BLOCKED'?`ตรวจสำเนาใหม่แล้ว ยังสำรองไม่ได้ (${result.errorCode||'UNKNOWN'}) · งานปกติยังทำต่อได้`:'ตรวจสถานะสำเนาใหม่แล้ว');
197
+ await refresh();
198
+ };
194
199
  try {
195
200
  const data=await act('recovery.status');
196
201
  const effectiveMode=data.effectiveMode||(data.hasGitRepo?'git':'snapshot');
197
202
  const labels={
198
203
  INITIALIZING:'กำลังเตรียมสำเนา — พร้อมใช้งานโดยไม่บล็อกการทำงาน',
199
204
  READY:effectiveMode==='git'?'SAVED · พร้อมใช้งาน (โหมด Git Recovery)':'SAVED · มีสำเนาที่ตรวจ integrity แล้ว (โหมด Snapshot)',
200
- BLOCKED:'สำรองไม่ได้ — หยุดการเปลี่ยน source (สามารถกดล้างสถานะบล็อกหรือปิด Strict Mode ด้านล่าง)',
205
+ BLOCKED:'สำรองไม่พร้อม — ยังแก้ไฟล์และรันคำสั่งได้ตามสิทธิ์เดิม',
201
206
  DISABLED_BY_OWNER:'เจ้าของปิดการสำรองอัตโนมัติ',
202
207
  };
203
208
  status.textContent=labels[data.state]||data.state;
204
- if(data.awaitingActivation&&data.enabled)status.textContent='เปิดการป้องกันไว้ — รอสร้างจุดกู้คืนแรก';
209
+ if(data.awaitingActivation&&data.enabled&&data.state==='INITIALIZING')status.textContent='เปิดการสำรองไว้ — รอสร้างจุดกู้คืนแรก';
205
210
 
206
211
  const headerBar=el('div',undefined,'rec-header');
207
212
  const headerCopy=el('div',undefined,'rec-header-copy');
208
213
  headerCopy.append(
209
214
  el('strong',data.hasGitRepo?'ตรวจพบ Git Repository ในโปรเจกต์นี้ (.git)':'โปรเจกต์ทั่วไป (ยังไม่ได้เชื่อม Git)'),
210
- el('span',data.policy.strictEnforcement?'โหมดเข้มงวด (Strict Blocking เปิดอยู่)':'โหมดไม่บังคับบล็อก (แก้ไฟล์และรันคำสั่งได้ตลอดเวลา ไม่ติด RECOVERY_REQUIRED)','muted')
215
+ el('span','สำรองอัตโนมัติแบบ best effort: ปัญหาการสำรองไม่บล็อกการแก้ไฟล์หรือรันคำสั่ง','muted')
211
216
  );
212
217
  const badge=el('span',
213
- data.state==='BLOCKED'?`ติดบล็อก · ${data.errorCode||'BLOCKED'}`:
218
+ data.state==='BLOCKED'?`สำรองไม่พร้อม · ${data.errorCode||'BLOCKED'}`:
214
219
  data.state==='DISABLED_BY_OWNER'?'ปิดการใช้งาน':
215
220
  effectiveMode==='git'?'พร้อมใช้งาน · Git Recovery':'พร้อมใช้งาน · DODO Snapshot',
216
221
  'rec-badge'
@@ -224,7 +229,7 @@ window.DodoRecovery=({el,section,button,check,field,choice,notice,confirmDanger,
224
229
  statCard(
225
230
  'โหมดที่ใช้งานจริง',
226
231
  effectiveMode==='git'?'Git Recovery':effectiveMode==='off'?'ปิดการใช้งาน':'DODO Snapshot',
227
- `ตั้งค่า: ${(data.policy.mode||'auto').toUpperCase()} · ${data.policy.strictEnforcement?'บล็อกเมื่อพบปัญหา':'ไม่บล็อกงาน'}`
232
+ `ตั้งค่า: ${(data.policy.mode||'auto').toUpperCase()} · ปัญหาการสำรองไม่บล็อกงานปกติ`
228
233
  ),
229
234
  statCard(
230
235
  'การตรวจสอบล่าสุด',
@@ -256,49 +261,35 @@ window.DodoRecovery=({el,section,button,check,field,choice,notice,confirmDanger,
256
261
  alertBox.append(
257
262
  el('p',
258
263
  data.state==='BLOCKED'
259
- ?`พบปัญหาที่ทำให้ Recovery ติดสถานะ BLOCKED (${data.errorCode||'UNKNOWN'})`
264
+ ?`Recovery ยังสำรองไม่สำเร็จ (${data.errorCode||'UNKNOWN'}) · ไม่บล็อกการแก้ไฟล์หรือรันคำสั่ง`
260
265
  :`คำเตือนจากระบบ Recovery (ไม่บล็อกการแก้ไฟล์หรือรันคำสั่ง)`,
261
266
  'rec-alert-title'
262
267
  )
263
268
  );
264
- if(data.errorDetail||data.lastWarning){
265
- alertBox.append(el('p',data.errorDetail||data.lastWarning,'muted'));
266
- }
269
+ if(data.errorDetail)alertBox.append(el('p',data.errorDetail,'muted'));
270
+ if(data.lastWarning&&data.lastWarning!==data.errorDetail)alertBox.append(el('p',data.lastWarning,'muted'));
267
271
  if(problemPaths.length){
268
- alertBox.append(el('p','ไฟล์ที่เป็นต้นเหตุ (เช่น มีข้อความคล้าย API key / Private key หรือขนาดเกินขีดจำกัด):'));
272
+ alertBox.append(el('p','พาธภายในโปรเจกต์ที่สำรองไม่ได้หรือถูกข้าม (relative path; เช่น เนื้อหาคล้ายคีย์หรือไฟล์เกินขีดจำกัด):'));
269
273
  const ul=el('ul',undefined,'rec-path-list');
270
274
  for(const p of problemPaths)ul.append(el('li',p,'rec-path-pill'));
271
275
  alertBox.append(ul);
272
276
  }else if(data.errorCode==='SECRET_PATH_DENIED'){
273
- alertBox.append(el('p','คำแนะนำ: มักเกิดจากไฟล์ตัวอย่างที่มีรูปแบบคีย์ เช่น env.example, scripts/setup-env.sh หรือ src/lib/env.ts คุณสามารถกดปุ่มด้านล่างเพื่อล้างสถานะบล็อก หรือเพิ่มไฟล์เข้า Exclude ได้ทันที','muted'));
277
+ alertBox.append(el('p','ตรวจไฟล์ตัวอย่างที่อาจมีข้อความคล้ายคีย์ เช่น env.example, scripts/setup-env.sh หรือ src/lib/env.ts แล้วลองสำรองใหม่หรือเลือกข้ามไฟล์นั้น การแก้ไฟล์และรันคำสั่งยังใช้สิทธิ์เดิม','muted'));
274
278
  }
275
279
  const quickActions=el('div',undefined,'rec-action-bar');
276
280
  if(problemPaths.length){
277
281
  quickActions.append(button('เพิ่มไฟล์ต้นเหตุเข้า Exclude ทันที',async()=>{
278
282
  const merged=[...new Set([...(data.policy.excludePaths||[]),...problemPaths])];
279
- await act('recovery.configure',{confirm:true,policy:{...data.policy,strictEnforcement:false,skipSecretContentFiles:true,excludePaths:merged}});
283
+ await act('recovery.configure',{confirm:true,policy:{...data.policy,strictEnforcement:false,excludePaths:merged}});
280
284
  await act('recovery.reset');
281
- notice(`เพิ่ม ${problemPaths.join(', ')} เข้า Exclude และปลดบล็อกเรียบร้อยแล้ว`);
285
+ notice(`เพิ่ม ${problemPaths.join(', ')} เข้า Exclude แล้ว · ตรวจสถานะสำเนาใหม่ด้านบน`);
282
286
  await refresh();
283
287
  },'btn primary'));
284
- quickActions.append(button('อนุญาตไฟล์ต้นเหตุในสิทธิ์ไฟล์ (Secret Allow)',async()=>{
285
- const cfg=await api('admin/config');
286
- const nextAllow=[...new Set([...(cfg.secretAllow||[]),...problemPaths])];
287
- await api('admin/config',{secretAllow:nextAllow});
288
- await act('recovery.configure',{confirm:true,policy:{...data.policy,strictEnforcement:false,skipSecretContentFiles:true}});
289
- await act('recovery.reset');
290
- notice(`อนุญาต ${problemPaths.join(', ')} ในสิทธิ์ไฟล์และปลดบล็อกเรียบร้อยแล้ว`);
291
- await refresh();
292
- },'btn'));
293
288
  }
294
- if(data.errorCode==='SECRET_PATH_DENIED'||problemPaths.length){
295
- quickActions.append(button('อนุญาตทุกไฟล์ (ปิดการบล็อก SECRET_PATH_DENIED)',async()=>{
296
- if(!await confirmDanger('ยืนยันอนุญาตให้เข้าถึงทุกไฟล์?','ระบบจะเปิดโหมดอนุญาตทุกไฟล์ (Allow All) และปิดการบล็อก SECRET_PATH_DENIED ทั้งชื่อไฟล์และเนื้อหา เพื่อให้คุณและ AI แก้ไขได้ทุกไฟล์','ยืนยันอนุญาตทุกไฟล์'))return;
297
- await api('admin/config',{secretPolicyMode:'off'});
298
- await act('recovery.configure',{confirm:true,policy:{...data.policy,strictEnforcement:false,scanContentSecrets:false,skipSecretContentFiles:true}});
299
- await act('recovery.reset');
300
- notice('เปิดโหมดอนุญาตทุกไฟล์และปลดบล็อกเรียบร้อยแล้ว');
301
- await refresh();
289
+ if(data.errorCode==='SECRET_PATH_DENIED'||(Array.isArray(data.skippedSecretFiles)&&data.skippedSecretFiles.length)){
290
+ quickActions.append(button('ข้ามไฟล์ที่มีเนื้อหาคล้าย Secret ในการสำรอง',async()=>{
291
+ await act('recovery.configure',{confirm:true,policy:{...data.policy,strictEnforcement:false,skipSecretContentFiles:true}});
292
+ await retryBackup();
302
293
  },'btn'));
303
294
  }
304
295
  if(data.hasGitRepo&&data.policy.mode!=='git'){
@@ -309,11 +300,7 @@ window.DodoRecovery=({el,section,button,check,field,choice,notice,confirmDanger,
309
300
  await refresh();
310
301
  },'btn'));
311
302
  }
312
- quickActions.append(button('ล้างสถานะบล็อก / สแกนใหม่ทันที',async()=>{
313
- await act('recovery.reset');
314
- notice('ล้างสถานะบล็อกและสแกนใหม่เรียบร้อยแล้ว');
315
- await refresh();
316
- },'btn'));
303
+ quickActions.append(button('ลองสำรองใหม่ทันที',retryBackup,'btn'));
317
304
  alertBox.append(quickActions);
318
305
  card.append(alertBox);
319
306
  }
@@ -327,8 +314,8 @@ window.DodoRecovery=({el,section,button,check,field,choice,notice,confirmDanger,
327
314
  const settingsGrid=el('div',undefined,'rec-settings-grid');
328
315
  card.append(settingsGrid);
329
316
 
330
- // Group 1: Mode & Blocking Behavior
331
- const g1=groupCard(1,'โหมดการทำงานและการบล็อกงาน','กำหนดว่าจะใช้ Git หรือ Snapshot และป้องกันไม่ให้ระบบบล็อกการแก้ไฟล์/รันคำสั่ง');
317
+ // Group 1: Backup mode and automatic best-effort behavior.
318
+ const g1=groupCard(1,'โหมดการสำรอง','เลือก Git หรือ Snapshot โดยปัญหาการสำรองอัตโนมัติไม่บล็อกงานปกติ');
332
319
  const modeSelect=choice(g1,'โหมดการสำรองและกู้คืน (Recovery Mode)','recoveryMode',[
333
320
  ['auto','Auto (แนะนำ — ใช้ Git อัตโนมัติถ้าโปรเจกต์มี .git)'],
334
321
  ['git','Git เท่านั้น (ใช้ Git ล้วน ไม่สแกนไฟล์ CAS ของ DODO)'],
@@ -336,16 +323,14 @@ window.DodoRecovery=({el,section,button,check,field,choice,notice,confirmDanger,
336
323
  ['off','ปิดการใช้งาน Recovery'],
337
324
  ],data.policy.mode||'auto');
338
325
  const enabled=check(g1,'เปิดการสำรองอัตโนมัติ','recoveryEnabled',data.enabled);enabled.setAttribute('role','switch');
339
- const strictEnforcement=check(g1,'บังคับบล็อกการแก้ไฟล์/รันคำสั่งเมื่อสำรองไม่สำเร็จ (Strict Mode — แนะนำให้ปิด)','recoveryStrict',Boolean(data.policy.strictEnforcement));
340
- strictEnforcement.setAttribute('role','switch');
341
- g1.append(el('p','เมื่อปิด Strict Mode: ต่อให้ไฟล์ติด SECRET_PATH_DENIED หรือเกิดข้อผิดพลาดระหว่างสำรอง คุณยังสามารถแก้ไฟล์และรันคำสั่งได้ตามปกติ','muted'));
326
+ g1.append(el('p','สำรองอัตโนมัติแบบ best effort: หากไฟล์ถูกข้าม คลังสำรองไม่พร้อม หรือสแกนไม่สำเร็จ จะแสดงคำเตือนและให้งานปกติทำต่อได้ การสร้างจุดกู้คืนที่ร้องขอและการกู้คืนตามแผนยังต้องตรวจสำเนาสำเร็จ','muted'));
342
327
  settingsGrid.append(g1);
343
328
 
344
329
  // Group 2: Secret Content Screening & Drift Policy
345
330
  const g2=groupCard(2,'การตรวจไฟล์ความลับและไฟล์เปลี่ยนภายนอก','จัดการการตรวจจับคีย์ตัวอย่างในโค้ด (เช่น env.example) และการแก้ไฟล์จากภายนอก');
346
331
  const scanContentSecrets=check(g2,'สแกนหาคีย์ความลับในเนื้อหาไฟล์ระหว่างสำรอง Snapshot','recoveryScanSecrets',data.policy.scanContentSecrets!==false);
347
332
  scanContentSecrets.setAttribute('role','switch');
348
- const skipSecretContentFiles=check(g2,'ข้ามไฟล์ที่พบเนื้อหาคล้าย Secret อัตโนมัติ (ไม่ให้ติดบล็อก SECRET_PATH_DENIED)','recoverySkipSecrets',data.policy.skipSecretContentFiles!==false);
333
+ const skipSecretContentFiles=check(g2,'ข้ามไฟล์ที่พบเนื้อหาคล้าย Secret อัตโนมัติ และแสดงพาธที่ข้าม','recoverySkipSecrets',data.policy.skipSecretContentFiles!==false);
349
334
  skipSecretContentFiles.setAttribute('role','switch');
350
335
  const checkDrift=check(g2,'ตรวจจับการแก้ไฟล์จากภายนอก DODO (Drift Detection)','recoveryCheckDrift',data.policy.checkDrift!==false);
351
336
  checkDrift.setAttribute('role','switch');
@@ -391,9 +376,10 @@ window.DodoRecovery=({el,section,button,check,field,choice,notice,confirmDanger,
391
376
  g4.append(quotaCols);
392
377
 
393
378
  const advanced=el('details',undefined,'details');advanced.append(el('summary','ขอบเขตและพื้นที่สำรอง (Git Copy แยกโฟลเดอร์ขั้นสูง)'));
394
- const gitRequired=check(advanced,'ต้องมี Git recovery copy ก่อนทำงาน','recoveryGitRequired',data.policy.gitRequired);
379
+ const gitRequired=check(advanced,'กำหนดให้จุดกู้คืนที่ร้องขอมี Git recovery copy','recoveryGitRequired',data.policy.gitRequired);
395
380
  const gitDirectory=field(advanced,'ที่เก็บ Git สำรอง (absolute path; เว้นว่างใช้ private state)','recoveryGitDirectory',data.policy.gitDirectory||'');
396
381
  advanced.append(el('p','โฟลเดอร์สำรองต้องมีอยู่แล้ว เป็น private ของเจ้าของ และอยู่นอกโปรเจกต์','muted'));
382
+ advanced.append(el('p','เมื่อ Git copy หรือโฟลเดอร์สำรองไม่พร้อม งานแก้ไฟล์และคำสั่งปกติยังทำต่อได้ พร้อมคำเตือนเรื่องสำเนาที่ขาดไป','muted'));
397
383
  g4.append(advanced);
398
384
  settingsGrid.append(g4);
399
385
 
@@ -415,7 +401,7 @@ window.DodoRecovery=({el,section,button,check,field,choice,notice,confirmDanger,
415
401
  ...data.policy,
416
402
  enabled:isEnabled,
417
403
  mode:isEnabled?(modeSelect.value==='off'?'auto':modeSelect.value):'off',
418
- strictEnforcement:strictEnforcement.checked,
404
+ strictEnforcement:false,
419
405
  scanContentSecrets:scanContentSecrets.checked,
420
406
  skipSecretContentFiles:skipSecretContentFiles.checked,
421
407
  checkDrift:checkDrift.checked,
@@ -438,7 +424,7 @@ window.DodoRecovery=({el,section,button,check,field,choice,notice,confirmDanger,
438
424
  await refresh();
439
425
  },'btn primary'),
440
426
  button('สร้างจุดกู้คืนตอนนี้',async()=>{await act('recovery.checkpoint');notice('สร้างจุดกู้คืนเรียบร้อยแล้ว');await refresh();}),
441
- button('ล้างสถานะบล็อก / สแกนใหม่',async()=>{await act('recovery.reset');notice('ล้างสถานะบล็อกและสแกนใหม่แล้ว');await refresh();}),
427
+ button('ลองสำรองใหม่',retryBackup),
442
428
  button('ตรวจสถานะใหม่',async()=>refresh())
443
429
  );
444
430
  card.append(mainActions);
@@ -133,6 +133,9 @@
133
133
  .wb-subtab-btn { font:inherit;font-size:.86rem;font-weight:600;padding:7px 14px;border-radius:999px;border:1px solid var(--border-strong);background:var(--panel);color:var(--muted);cursor:pointer;transition:all .15s ease; }
134
134
  .wb-subtab-btn:hover { color:var(--text);border-color:var(--accent); }
135
135
  .wb-subtab-btn.active,.wb-subtab-btn[aria-selected="true"] { background:var(--accent);color:var(--accent-fg,#fff);border-color:var(--accent); }
136
+ .wb-project-grid { display:grid;grid-template-columns:repeat(auto-fit,minmax(min(240px,100%),1fr));gap:10px;min-width:0; }
137
+ .wb-project-item { border:1px solid var(--border);border-radius:var(--radius-sm);padding:12px 14px;background:var(--panel);display:flex;flex-direction:column;gap:8px;min-width:0; }
138
+ .wb-project-item[data-active="true"] { border-color:var(--accent);background:color-mix(in srgb,var(--accent) 6%,var(--panel)); }
136
139
 
137
140
  @media(max-width:860px) { .rec-settings-grid,.rec-git-columns { grid-template-columns:1fr; } }
138
141
  @media(max-width:640px) { .wb-form,.rec-two-col,.rec-three-col { grid-template-columns:1fr; } .wb-section { padding:12px; } .workbench-nav { padding:10px 12px; } .wb-toolbar { align-items:stretch; } .wb-tool-controls { grid-template-columns:1fr; } .wb-tool-row { grid-template-columns:1fr; } .wb-tool-row-state { max-width:none;text-align:left;padding-left:52px; } .wb-tool-group > summary { align-items:flex-start; } }
@@ -96,7 +96,7 @@
96
96
  try {
97
97
  if(!await reload(generation))return;
98
98
  if(view==='overview')overview(body);
99
- if(view==='projects')await projects(body);
99
+ if(view==='projects')await projects(body,generation);
100
100
  if(view==='providers'){providers(body);profiles(body);}
101
101
  if(view==='chat')chat(body);
102
102
  if(view==='runs')runs(body);
@@ -301,12 +301,83 @@
301
301
  return card;
302
302
  }
303
303
 
304
- async function projects(body) {
304
+ async function projects(body,generation) {
305
305
  const personal=state.accessMode==='personal';
306
306
  const s=section('โปรเจกต์พร้อมกัน',personal?'เพิ่ม path แล้วใช้ได้ทันที ไม่ต้องอนุญาต client หรือ profile ซ้ำ งานต่างโปรเจกต์ทำพร้อมกันได้':'เปิด runtime แยกโปรเจกต์และกำหนด ACL/trust ของแต่ละโปรเจกต์เอง');body.append(s);
307
307
  const name=field(s,'ชื่อโปรเจกต์','projectName'),root=field(s,'Absolute path ในเครื่อง','projectRoot');
308
- s.append(button(personal?'เพิ่มและพร้อมใช้':'เพิ่ม path',async()=>{await api('projects/add',{path:root.value,...(name.value?{displayName:name.value}:{})});notice(personal?'เพิ่มโปรเจกต์แล้ว พร้อมใช้งานทันที':'เพิ่มในทะเบียนแล้ว ตั้งค่าสิทธิ์ก่อนใช้งาน');await show('projects');}));
309
- if(!selected){s.append(el('p',personal?'เพิ่มหรือเลือกโปรเจกต์จากรายการด้านบน':'เลือกโปรเจกต์จากรายการด้านบนเพื่อจัดการสิทธิ์','wb-empty'));return;}
308
+ s.append(button(personal?'เพิ่มและพร้อมใช้':'เพิ่ม path',async()=>{
309
+ const added=await api('projects/add',{path:root.value,access:'full',...(name.value?{displayName:name.value}:{})});
310
+ if(added?.project?.projectId){try{selected=await api('ai/project',{projectId:added.project.projectId});}catch{}}
311
+ notice(personal?'เพิ่มโปรเจกต์แล้ว พร้อมใช้งานทันที':'เพิ่มในทะเบียนแล้ว ตั้งค่าสิทธิ์ก่อนใช้งาน');
312
+ await show('projects');
313
+ }));
314
+
315
+ if(!selected){
316
+ const autoTarget=state.projects.find(p=>p.workspaceId===state.controlContext?.workspaceId&&p.available)||state.projects.find(p=>p.available);
317
+ if(autoTarget){
318
+ try{
319
+ const fetched=await api('ai/project',{projectId:autoTarget.projectId});
320
+ if((generation===undefined||generation===renderGeneration)&&!selected){
321
+ selected=fetched;
322
+ $('wb-root').textContent=personal?`${selected.root} · พร้อมใช้ทันทีในโหมดส่วนตัว`:`${selected.root} · บันทึก ${selected.savedTrust} / มีผล ${selected.effectiveTrust}`;
323
+ }
324
+ }catch{}
325
+ }
326
+ }
327
+
328
+ if(state.projects.length>0){
329
+ const multiCard=el('div',undefined,'rec-setting-group');
330
+ multiCard.append(
331
+ el('h4',`โปรเจกต์ทั้งหมดในเครื่อง (${state.projects.length} โปรเจกต์ · รันหลายโปรเจกต์พร้อมกันได้)`),
332
+ el('p','เลือกโปรเจกต์ที่ต้องการตั้งค่า Recovery / การอนุญาตไฟล์ หรือปรับระดับการเข้าถึงของแต่ละโปรเจกต์ได้ทันทีโดยไม่รบกวนโปรเจกต์อื่นที่กำลังทำงานอยู่','muted')
333
+ );
334
+ const listGrid=el('div',undefined,'wb-project-grid');
335
+ const runtimeSet=new Set((state.runtimes||[]).map(r=>r.projectId));
336
+ for(const proj of state.projects){
337
+ const isCurrent=selected?.projectId===proj.projectId;
338
+ const isRunning=runtimeSet.has(proj.projectId)||proj.workspaceId===state.controlContext?.workspaceId;
339
+ const item=el('div',undefined,'wb-project-item');
340
+ if(isCurrent)item.dataset.active='true';
341
+ const itemHead=el('div',undefined,'rec-item-head');
342
+ const titleBox=el('div');
343
+ titleBox.append(el('b',proj.displayName),el('span',` (${proj.projectId})`,'muted'));
344
+ const statusBadge=el('span',isCurrent?'● กำลังตั้งค่าอยู่':isRunning?'● เปิด Runtime พร้อมใช้งาน':proj.available?'พร้อมใช้งาน':'ไม่พร้อม','rec-badge');
345
+ statusBadge.dataset.tone=isCurrent?'ok':isRunning?'info':proj.available?'ok':'warn';
346
+ itemHead.append(titleBox,statusBadge);
347
+ const pathLine=el('code',proj.root,'rec-path-pill');
348
+ const actionsRow=el('div',undefined,'rec-item-actions');
349
+ const selectBtn=button(isCurrent?'กำลังแสดงการตั้งค่าโปรเจกต์นี้':'จัดการตั้งค่าโปรเจกต์นี้',async()=>{
350
+ $('wb-project').value=proj.projectId;
351
+ await selectProject();
352
+ await show('projects');
353
+ },isCurrent?'btn small':'btn primary small');
354
+ selectBtn.disabled=isCurrent||!proj.available;
355
+ const accessSelect=el('select');
356
+ accessSelect.style.width='auto';
357
+ accessSelect.style.maxWidth='100%';
358
+ for(const [val,lbl] of [['full','ทำงานเต็มรูปแบบ (อ่าน/แก้ไฟล์/รันคำสั่ง)'],['edit','แก้ไขไฟล์ (อ่าน/แก้ไฟล์)'],['read','อ่านอย่างเดียว']]){
359
+ const opt=el('option',lbl);opt.value=val;accessSelect.append(opt);
360
+ }
361
+ accessSelect.value=proj.accessLevel||'full';
362
+ accessSelect.onchange=()=>busy(selectBtn,async()=>{
363
+ await api('projects/access',{projectId:proj.projectId,access:accessSelect.value});
364
+ notice(`เปลี่ยนสิทธิ์ของ ${proj.displayName} เป็น ${accessSelect.value} แล้ว`);
365
+ await show('projects');
366
+ });
367
+ actionsRow.append(selectBtn,accessSelect);
368
+ item.append(itemHead,pathLine,actionsRow);
369
+ listGrid.append(item);
370
+ }
371
+ multiCard.append(listGrid);
372
+ s.append(multiCard);
373
+ }
374
+
375
+ if(!selected){
376
+ const config=await api('admin/config');
377
+ renderFileAccessPolicyCard(s,config,()=>show('projects'));
378
+ s.append(el('p',personal?'เพิ่มหรือเลือกโปรเจกต์จากรายการด้านบนเพื่อตั้งค่า Recovery รายโปรเจกต์':'เลือกโปรเจกต์จากรายการด้านบนเพื่อจัดการสิทธิ์และตั้งค่า Recovery','wb-empty'));
379
+ return;
380
+ }
310
381
 
311
382
  const [config,stuckChangesets]=await Promise.all([
312
383
  api('admin/config'),
@@ -103,7 +103,12 @@ export class InstallationRuntime {
103
103
  } };
104
104
  }
105
105
  async open(id, root) {
106
- const ws = bootstrapWorkspace({ invokedCwd: root, configDir: { dir: this.initial.configDir, source: this.initial.configDirSource }, log: this.log });
106
+ const ws = bootstrapWorkspace({
107
+ invokedCwd: root,
108
+ configDir: { dir: this.initial.configDir, source: this.initial.configDirSource },
109
+ log: this.log,
110
+ ...(this.initial.runMode ? { runMode: this.initial.runMode } : {}),
111
+ });
107
112
  try {
108
113
  attachOptionalServices(ws, this.log);
109
114
  this.attach(ws);