@chatcode/chatcode-cli 3.0.4-rc.4 → 3.0.4-rc.7

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 (54) hide show
  1. package/README.i18n.yaml +4 -4
  2. package/README.md +4 -2
  3. package/README.zh.md +4 -2
  4. package/lib/bin.js +3 -3
  5. package/lib/{command-errors-BJ_ZWzUU.js → command-errors-Ca64Lgba.js} +12 -12
  6. package/lib/{command-trees-C9b7-bci.js → command-trees-CVc4Xu_z.js} +2 -2
  7. package/lib/{component-identity-Jb1DYjke.js → component-identity-6aEut5Yt.js} +3 -3
  8. package/lib/dump-config-CDixiJNt.js +2 -0
  9. package/lib/{dump-config-BcH-VYuv.js → dump-config-ZzrfvtnX.js} +10 -6
  10. package/lib/{dump-config-schema-DM0fb6Ns.js → dump-config-schema-BlO-eZ-J.js} +2 -2
  11. package/lib/{extension-events-DKX4LXOd.js → extension-events-C7MUpqVE.js} +20 -20
  12. package/lib/headless-compat.js +31 -31
  13. package/lib/{host-access-CMg6rsWt.js → host-access-CLbyAGT5.js} +1 -1
  14. package/lib/{keymap-CrC4pSNH.js → keymap-82JwLLHe.js} +2 -2
  15. package/lib/{plugin-eJjD6r12.js → plugin-BZdazFXS.js} +1 -1
  16. package/lib/{plugin-CmyMCGfb.js → plugin-BlQlWIR5.js} +425 -451
  17. package/lib/{profile-boot-BNQry1NM.js → profile-boot-B0aEEQIR.js} +40 -11
  18. package/lib/profile-boot.js +2 -2
  19. package/lib/{scenes-Cil9RnwU.js → scenes-BNS0ZFyQ.js} +3 -3
  20. package/lib/{settings-sections-jVCqXwdH.js → settings-sections-CXH24cu5.js} +3 -3
  21. package/lib/{statusBarSettings-DNoBH3Cq.js → statusBarSettings-BAMzn8fX.js} +6 -6
  22. package/lib/{themes-BdgeY3It.js → themes-DXUIvP7m.js} +12 -12
  23. package/lib/tui-compat-command-trees.js +1 -1
  24. package/lib/tui-compat-extensions.js +3 -3
  25. package/lib/tui-compat-plugin-host.js +5 -5
  26. package/lib/tui-compat-scenes.js +1 -1
  27. package/lib/tui-compat-settings-sections.js +1 -1
  28. package/lib/tui-compat-working-activity.js +17 -17
  29. package/lib/tui-compat-workspaces.js +1 -1
  30. package/lib/tui-compat.js +39 -39
  31. package/lib/types/dump-config.d.ts +3 -3
  32. package/lib/types/profile-boot.d.ts +13 -3
  33. package/lib/{workspaces-DOatJRYr.js → workspaces-CUJXNU5W.js} +2 -2
  34. package/package.json +25 -25
  35. package/runtime/manifest.json +1 -1
  36. package/runtime/node_modules/@deepseek-ai/cordis-plugin-loader/lib/index.js +1 -1
  37. package/runtime/node_modules/@deepseek-ai/cordis-plugin-loader/src/config/entry.ts +1 -1
  38. package/runtime/node_modules/@deepseek-ai/dsh-app-boot/lib/index.js +5 -1
  39. package/runtime/node_modules/@deepseek-ai/dsh-app-boot/lib/types/profile-context.d.ts +2 -0
  40. package/runtime/node_modules/@deepseek-ai/dsh-client-ui-settings-account/lib/client.js +2 -2
  41. package/runtime/node_modules/@deepseek-ai/dsh-client-ui-settings-general/lib/client.js +1 -1
  42. package/runtime/node_modules/@deepseek-ai/dsh-client-ui-sidebar/lib/client.js +3 -1
  43. package/runtime/node_modules/@deepseek-ai/dsh-client-ui-workspace/lib/client.js +17 -159
  44. package/runtime/node_modules/@deepseek-ai/dsh-client-ui-workspace/lib/types/client/ArchivedSessions.d.ts +1 -2
  45. package/runtime/node_modules/@deepseek-ai/dsh-config-editor/lib/index.js +5 -1
  46. package/runtime/node_modules/@deepseek-ai/dsh-subagent/lib/types/control.d.ts +1 -1
  47. package/runtime/node_modules/@deepseek-ai/dsh-web-frontend/dist/assets/{index-Dz_cDcce.js → index-D-8yUukj.js} +24 -24
  48. package/runtime/node_modules/@deepseek-ai/dsh-web-frontend/dist/assets/{index-Dz_cDcce.js.map → index-D-8yUukj.js.map} +1 -1
  49. package/runtime/node_modules/@deepseek-ai/dsh-web-frontend/dist/index.html +1 -1
  50. package/runtime/node_modules/@deepseek-ai/dsh-web-frontend/dist/preview.html +1 -1
  51. package/runtime/node_modules/@deepseek-ai/dsh-workspace/lib/index.js +40 -29
  52. package/runtime/node_modules/@deepseek-ai/dsh-workspace/lib/types/index.d.ts +2 -2
  53. package/runtime/node_modules/@deepseek-ai/dsh-workspace/lib/types/index.js +53 -28
  54. package/lib/dump-config-CyopmD85.js +0 -2
@@ -11,7 +11,7 @@
11
11
  <link rel="icon" type="image/svg+xml" href="./favicon-dark.svg?v=unicom-1" media="(prefers-color-scheme: dark)" />
12
12
  <link rel="icon" type="image/svg+xml" href="./favicon.svg?v=unicom-1" media="(prefers-color-scheme: light)" />
13
13
  <title>ChatCode CLI Local Build</title>
14
- <script type="module" crossorigin src="./assets/index-Dz_cDcce.js"></script>
14
+ <script type="module" crossorigin src="./assets/index-D-8yUukj.js"></script>
15
15
  <link rel="modulepreload" crossorigin href="./assets/vendor-CCJJTK99.js">
16
16
  <link rel="stylesheet" crossorigin href="./assets/vendor-BNsW4eBh.css">
17
17
  <link rel="stylesheet" crossorigin href="./assets/index-D5kpKf--.css">
@@ -11,7 +11,7 @@
11
11
  <link rel="icon" type="image/svg+xml" href="./favicon-dark.svg?v=unicom-1" media="(prefers-color-scheme: dark)" />
12
12
  <link rel="icon" type="image/svg+xml" href="./favicon.svg?v=unicom-1" media="(prefers-color-scheme: light)" />
13
13
  <title>ChatCode CLI Local Build</title>
14
- <script type="module" crossorigin src="./preview/bootstrap-DlVeEFeU.js"></script><script type="module" crossorigin src="./assets/index-Dz_cDcce.js"></script>
14
+ <script type="module" crossorigin src="./preview/bootstrap-DlVeEFeU.js"></script><script type="module" crossorigin src="./assets/index-D-8yUukj.js"></script>
15
15
  <link rel="modulepreload" crossorigin href="./assets/vendor-CCJJTK99.js">
16
16
  <link rel="stylesheet" crossorigin href="./assets/vendor-BNsW4eBh.css">
17
17
  <link rel="stylesheet" crossorigin href="./assets/index-D5kpKf--.css">
@@ -449,7 +449,6 @@ var WorkspaceRegistry = class extends Service {
449
449
  invalidSessionPaths = /* @__PURE__ */ new Map();
450
450
  operationTail = Promise.resolve();
451
451
  stopping = false;
452
- refreshedState = "";
453
452
  host = {
454
453
  table: () => this.requireTable(),
455
454
  enqueue: (operation) => this.enqueueOperation(operation),
@@ -492,7 +491,6 @@ var WorkspaceRegistry = class extends Service {
492
491
  this.validateStoredState(this.requireState());
493
492
  this.rebuildEntities();
494
493
  this.reportFilteredCandidates();
495
- this.refreshedState = this.snapshotIdentity();
496
494
  });
497
495
  const poll = async () => {
498
496
  try {
@@ -1121,26 +1119,30 @@ var WorkspaceRegistry = class extends Service {
1121
1119
  await this.indexHeaders(headers);
1122
1120
  }
1123
1121
  async indexHeaders(headers) {
1124
- for (const header of headers) await this.indexHeader(header);
1122
+ const directories = /* @__PURE__ */ new Map();
1123
+ for (const header of headers) await this.indexHeader(header, directories);
1125
1124
  }
1126
- async indexHeader(header) {
1125
+ async indexHeader(header, directories) {
1127
1126
  this.headers.set(header.id, header);
1128
1127
  this.sessionPaths.delete(header.id);
1129
1128
  if (header.cwd === void 0) {
1130
1129
  this.invalidSessionPaths.set(header.id, "header has no cwd");
1131
1130
  return;
1132
1131
  }
1133
- try {
1134
- const path = await realpathNormalize(header.cwd);
1135
- if (!(await stat(path)).isDirectory()) {
1136
- this.invalidSessionPaths.set(header.id, `cwd '${header.cwd}' is not a directory`);
1137
- return;
1132
+ let directory = directories.get(header.cwd);
1133
+ if (directory === void 0) {
1134
+ try {
1135
+ const path = await realpathNormalize(header.cwd);
1136
+ directory = (await stat(path)).isDirectory() ? { path } : { reason: `cwd '${header.cwd}' is not a directory` };
1137
+ } catch (error) {
1138
+ directory = { reason: `cwd '${header.cwd}' does not resolve` };
1138
1139
  }
1139
- this.sessionPaths.set(header.id, path);
1140
- this.invalidSessionPaths.delete(header.id);
1141
- } catch {
1142
- this.invalidSessionPaths.set(header.id, `cwd '${header.cwd}' does not resolve`);
1140
+ directories.set(header.cwd, directory);
1143
1141
  }
1142
+ if ("path" in directory) {
1143
+ this.sessionPaths.set(header.id, directory.path);
1144
+ this.invalidSessionPaths.delete(header.id);
1145
+ } else this.invalidSessionPaths.set(header.id, directory.reason);
1144
1146
  }
1145
1147
  /** Every stored session's header, projected from the persistence snapshot listing. */
1146
1148
  async listStoredHeaders() {
@@ -1151,7 +1153,19 @@ var WorkspaceRegistry = class extends Service {
1151
1153
  async indexLiveSessions() {
1152
1154
  const sessions = this.ctx.get("sessions");
1153
1155
  if (sessions === void 0) return;
1154
- await this.indexHeaders(sessions.list().filter((session) => !this.deletedSessionIds.includes(session.id)).map((session) => session.header));
1156
+ const deleted = new Set(this.deletedSessionIds);
1157
+ await this.indexHeaders(sessions.list().filter((session) => !deleted.has(session.id)).map((session) => session.header));
1158
+ }
1159
+ /** Retry unresolved membership using known headers or individual persistence lookups. */
1160
+ async refreshUnresolvedMembers() {
1161
+ const sessions = this.ctx.get("sessions");
1162
+ const unresolved = [];
1163
+ for (const [, record] of this.requireTable().entries()) for (const id of record.sessionIds) {
1164
+ if (this.sessionPaths.has(id)) continue;
1165
+ const header = sessions?.get(id)?.header ?? this.headers.get(id) ?? (await this.ctx.sessionPersistence.stat(id))?.header;
1166
+ if (header !== void 0) unresolved.push(header);
1167
+ }
1168
+ await this.indexHeaders(unresolved);
1155
1169
  }
1156
1170
  reportFilteredCandidates() {
1157
1171
  for (const entity of this.entities.values()) {
@@ -1172,10 +1186,9 @@ var WorkspaceRegistry = class extends Service {
1172
1186
  }
1173
1187
  const cached = this.headers.get(id);
1174
1188
  if (cached !== void 0) return cached;
1175
- const headers = await this.listStoredHeaders();
1176
- await this.indexHeaders(headers);
1177
- const header = this.headers.get(id);
1189
+ const header = (await this.ctx.sessionPersistence.stat(id))?.header;
1178
1190
  if (header === void 0) throw new Error(`cannot validate session '${id}': session persistence holds no such session`);
1191
+ this.headers.set(id, header);
1179
1192
  return header;
1180
1193
  }
1181
1194
  requireTable() {
@@ -1198,12 +1211,16 @@ var WorkspaceRegistry = class extends Service {
1198
1211
  return await domain.exclusive(async () => {
1199
1212
  const before = JSON.stringify([...this.entities.values()].map((entity) => [entity.id, entity.sessionIds]));
1200
1213
  const previousDeleted = new Set(this.deletedSessionIds);
1201
- await domain.refresh();
1202
- const changed = this.snapshotIdentity() !== this.refreshedState;
1214
+ const changed = await domain.refresh();
1203
1215
  this.state = domain.global.get();
1204
- const missingHeaders = [...this.requireTable().entries()].some(([, record]) => record.sessionIds.some((id) => !this.sessionPaths.has(id)));
1205
- if (changed || missingHeaders) {
1206
- await this.replaceHeaderIndex(await this.listStoredHeaders());
1216
+ for (const id of this.deletedSessionIds) {
1217
+ if (previousDeleted.has(id)) continue;
1218
+ this.headers.delete(id);
1219
+ this.sessionPaths.delete(id);
1220
+ this.invalidSessionPaths.delete(id);
1221
+ }
1222
+ await this.refreshUnresolvedMembers();
1223
+ if (changed) {
1207
1224
  await this.indexLiveSessions();
1208
1225
  this.rebuildEntities();
1209
1226
  }
@@ -1218,18 +1235,12 @@ var WorkspaceRegistry = class extends Service {
1218
1235
  } catch (error) {
1219
1236
  this.ctx.logger.warn(`workspace: refresh listener failed: ${String(error)}`);
1220
1237
  }
1221
- this.refreshedState = this.snapshotIdentity();
1222
- const result = await operation();
1223
- this.refreshedState = this.snapshotIdentity();
1224
- return result;
1238
+ return await operation();
1225
1239
  });
1226
1240
  });
1227
1241
  this.operationTail = result.then(() => {}, () => {});
1228
1242
  return result;
1229
1243
  }
1230
- snapshotIdentity() {
1231
- return JSON.stringify([this.domain?.global.get(), [...this.requireTable().entries()]]);
1232
- }
1233
1244
  };
1234
1245
  const sameSessionIds = (left, right) => left.length === right.length && left.every((id, index) => id === right[index]);
1235
1246
  //#endregion
@@ -143,7 +143,6 @@ export declare class WorkspaceRegistry extends Service {
143
143
  private readonly invalidSessionPaths;
144
144
  private operationTail;
145
145
  private stopping;
146
- private refreshedState;
147
146
  private readonly host;
148
147
  constructor(ctx: Context);
149
148
  /** Open the domain, finish bootstrap when required, and rebuild the ordered cache. */
@@ -319,13 +318,14 @@ export declare class WorkspaceRegistry extends Service {
319
318
  /** Every stored session's header, projected from the persistence snapshot listing. */
320
319
  private listStoredHeaders;
321
320
  private indexLiveSessions;
321
+ /** Retry unresolved membership using known headers or individual persistence lookups. */
322
+ private refreshUnresolvedMembers;
322
323
  private reportFilteredCandidates;
323
324
  private readSessionHeader;
324
325
  private requireTable;
325
326
  private requireState;
326
327
  private setState;
327
328
  private enqueueOperation;
328
- private snapshotIdentity;
329
329
  }
330
330
  export default WorkspaceRegistry;
331
331
  //# sourceMappingURL=index.d.ts.map
@@ -170,7 +170,6 @@ export class WorkspaceRegistry extends Service {
170
170
  invalidSessionPaths = new Map();
171
171
  operationTail = Promise.resolve();
172
172
  stopping = false;
173
- refreshedState = '';
174
173
  host = {
175
174
  table: () => this.requireTable(),
176
175
  enqueue: operation => this.enqueueOperation(operation),
@@ -216,7 +215,6 @@ export class WorkspaceRegistry extends Service {
216
215
  this.validateStoredState(this.requireState());
217
216
  this.rebuildEntities();
218
217
  this.reportFilteredCandidates();
219
- this.refreshedState = this.snapshotIdentity();
220
218
  });
221
219
  const poll = async () => {
222
220
  try {
@@ -951,27 +949,37 @@ export class WorkspaceRegistry extends Service {
951
949
  await this.indexHeaders(headers);
952
950
  }
953
951
  async indexHeaders(headers) {
952
+ const directories = new Map();
954
953
  for (const header of headers)
955
- await this.indexHeader(header);
954
+ await this.indexHeader(header, directories);
956
955
  }
957
- async indexHeader(header) {
956
+ async indexHeader(header, directories) {
958
957
  this.headers.set(header.id, header);
959
958
  this.sessionPaths.delete(header.id);
960
959
  if (header.cwd === undefined) {
961
960
  this.invalidSessionPaths.set(header.id, 'header has no cwd');
962
961
  return;
963
962
  }
964
- try {
965
- const path = await realpathNormalize(header.cwd);
966
- if (!(await stat(path)).isDirectory()) {
967
- this.invalidSessionPaths.set(header.id, `cwd '${header.cwd}' is not a directory`);
968
- return;
963
+ let directory = directories.get(header.cwd);
964
+ if (directory === undefined) {
965
+ try {
966
+ const path = await realpathNormalize(header.cwd);
967
+ directory = (await stat(path)).isDirectory()
968
+ ? { path } : { reason: `cwd '${header.cwd}' is not a directory` };
969
+ }
970
+ catch (error) {
971
+ // An unavailable directory remains unprojected, not removed from durable membership.
972
+ void error;
973
+ directory = { reason: `cwd '${header.cwd}' does not resolve` };
969
974
  }
970
- this.sessionPaths.set(header.id, path);
975
+ directories.set(header.cwd, directory);
976
+ }
977
+ if ('path' in directory) {
978
+ this.sessionPaths.set(header.id, directory.path);
971
979
  this.invalidSessionPaths.delete(header.id);
972
980
  }
973
- catch {
974
- this.invalidSessionPaths.set(header.id, `cwd '${header.cwd}' does not resolve`);
981
+ else {
982
+ this.invalidSessionPaths.set(header.id, directory.reason);
975
983
  }
976
984
  }
977
985
  /** Every stored session's header, projected from the persistence snapshot listing. */
@@ -984,7 +992,24 @@ export class WorkspaceRegistry extends Service {
984
992
  const sessions = this.ctx.get('sessions');
985
993
  if (sessions === undefined)
986
994
  return;
987
- await this.indexHeaders(sessions.list().filter(session => !this.deletedSessionIds.includes(session.id)).map(session => session.header));
995
+ const deleted = new Set(this.deletedSessionIds);
996
+ await this.indexHeaders(sessions.list().filter(session => !deleted.has(session.id)).map(session => session.header));
997
+ }
998
+ /** Retry unresolved membership using known headers or individual persistence lookups. */
999
+ async refreshUnresolvedMembers() {
1000
+ const sessions = this.ctx.get('sessions');
1001
+ const unresolved = [];
1002
+ for (const [, record] of this.requireTable().entries()) {
1003
+ for (const id of record.sessionIds) {
1004
+ if (this.sessionPaths.has(id))
1005
+ continue;
1006
+ const header = sessions?.get(id)?.header ?? this.headers.get(id)
1007
+ ?? (await this.ctx.sessionPersistence.stat(id))?.header;
1008
+ if (header !== undefined)
1009
+ unresolved.push(header);
1010
+ }
1011
+ }
1012
+ await this.indexHeaders(unresolved);
988
1013
  }
989
1014
  reportFilteredCandidates() {
990
1015
  for (const entity of this.entities.values()) {
@@ -1010,12 +1035,11 @@ export class WorkspaceRegistry extends Service {
1010
1035
  const cached = this.headers.get(id);
1011
1036
  if (cached !== undefined)
1012
1037
  return cached;
1013
- const headers = await this.listStoredHeaders();
1014
- await this.indexHeaders(headers);
1015
- const header = this.headers.get(id);
1038
+ const header = (await this.ctx.sessionPersistence.stat(id))?.header;
1016
1039
  if (header === undefined) {
1017
1040
  throw new Error(`cannot validate session '${id}': session persistence holds no such session`);
1018
1041
  }
1042
+ this.headers.set(id, header);
1019
1043
  return header;
1020
1044
  }
1021
1045
  requireTable() {
@@ -1042,12 +1066,19 @@ export class WorkspaceRegistry extends Service {
1042
1066
  return await domain.exclusive(async () => {
1043
1067
  const before = JSON.stringify([...this.entities.values()].map(entity => [entity.id, entity.sessionIds]));
1044
1068
  const previousDeleted = new Set(this.deletedSessionIds);
1045
- await domain.refresh();
1046
- const changed = this.snapshotIdentity() !== this.refreshedState;
1069
+ const changed = await domain.refresh();
1047
1070
  this.state = domain.global.get();
1048
- const missingHeaders = [...this.requireTable().entries()].some(([, record]) => record.sessionIds.some(id => !this.sessionPaths.has(id)));
1049
- if (changed || missingHeaders) {
1050
- await this.replaceHeaderIndex(await this.listStoredHeaders());
1071
+ for (const id of this.deletedSessionIds) {
1072
+ if (previousDeleted.has(id))
1073
+ continue;
1074
+ this.headers.delete(id);
1075
+ this.sessionPaths.delete(id);
1076
+ this.invalidSessionPaths.delete(id);
1077
+ }
1078
+ // Header cwd and workspace paths are immutable. Changed titles, pins,
1079
+ // ordering, or one new member do not invalidate every historical header.
1080
+ await this.refreshUnresolvedMembers();
1081
+ if (changed) {
1051
1082
  await this.indexLiveSessions();
1052
1083
  this.rebuildEntities();
1053
1084
  }
@@ -1066,18 +1097,12 @@ export class WorkspaceRegistry extends Service {
1066
1097
  this.ctx.logger.warn(`workspace: refresh listener failed: ${String(error)}`);
1067
1098
  }
1068
1099
  }
1069
- this.refreshedState = this.snapshotIdentity();
1070
- const result = await operation();
1071
- this.refreshedState = this.snapshotIdentity();
1072
- return result;
1100
+ return await operation();
1073
1101
  });
1074
1102
  });
1075
1103
  this.operationTail = result.then(() => { }, () => { });
1076
1104
  return result;
1077
1105
  }
1078
- snapshotIdentity() {
1079
- return JSON.stringify([this.domain?.global.get(), [...this.requireTable().entries()]]);
1080
- }
1081
1106
  }
1082
1107
  const sameSessionIds = (left, right) => left.length === right.length && left.every((id, index) => id === right[index]);
1083
1108
  export default WorkspaceRegistry;
@@ -1,2 +0,0 @@
1
- import { n as runDumpConfig } from "./dump-config-BcH-VYuv.js";
2
- export { runDumpConfig };