codexmate 0.0.18 → 0.0.19

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.
@@ -1,11 +1,98 @@
1
- export function createSkillsMethods({ api }) {
1
+ function createUnsupportedSkillsTargetAppError(app) {
2
+ return new Error(`Unsupported skills target app: ${String(app)}`);
3
+ }
4
+
5
+ function showUnsupportedSkillsTargetMessage(vm, app) {
6
+ vm.showMessage(`不支持的 Skills 安装目标:${String(app)}`, 'error');
7
+ }
8
+
9
+ export function createSkillsMethods({ api }) {
2
10
  return {
3
- async openSkillsManager() {
11
+ normalizeSkillsTargetApp(app) {
12
+ if (app == null) {
13
+ return 'codex';
14
+ }
15
+ if (app === 'codex' || app === 'claude') {
16
+ return app;
17
+ }
18
+ throw createUnsupportedSkillsTargetAppError(app);
19
+ },
20
+
21
+ resetSkillsTargetState() {
4
22
  this.skillsSelectedNames = [];
5
23
  this.skillsKeyword = '';
6
24
  this.skillsStatusFilter = 'all';
25
+ this.skillsRootPath = '';
26
+ this.skillsList = [];
7
27
  this.skillsImportList = [];
8
28
  this.skillsImportSelectedKeys = [];
29
+ this.skillsMarketLocalLoadedOnce = false;
30
+ this.skillsMarketImportLoadedOnce = false;
31
+ },
32
+
33
+ async setSkillsTargetApp(app, options = {}) {
34
+ if (
35
+ this.skillsLoading
36
+ || this.skillsDeleting
37
+ || this.skillsScanningImports
38
+ || this.skillsImporting
39
+ || this.skillsZipImporting
40
+ || this.skillsExporting
41
+ || this.skillsMarketLoading
42
+ ) {
43
+ return false;
44
+ }
45
+ let nextTarget;
46
+ try {
47
+ nextTarget = this.normalizeSkillsTargetApp(app);
48
+ } catch (error) {
49
+ showUnsupportedSkillsTargetMessage(this, app);
50
+ return false;
51
+ }
52
+ const refresh = !(options && options.refresh === false);
53
+ const silent = !!(options && options.silent);
54
+ if (nextTarget !== this.skillsTargetApp) {
55
+ this.skillsTargetApp = nextTarget;
56
+ this.resetSkillsTargetState();
57
+ }
58
+ if (!refresh) {
59
+ return true;
60
+ }
61
+ return await this.loadSkillsMarketOverview({
62
+ forceRefresh: true,
63
+ silent
64
+ });
65
+ },
66
+
67
+ async openSkillsManager(options = {}) {
68
+ if (
69
+ this.skillsLoading
70
+ || this.skillsDeleting
71
+ || this.skillsScanningImports
72
+ || this.skillsImporting
73
+ || this.skillsZipImporting
74
+ || this.skillsExporting
75
+ || this.skillsMarketLoading
76
+ ) {
77
+ return false;
78
+ }
79
+ let targetApp;
80
+ try {
81
+ targetApp = this.normalizeSkillsTargetApp(options && options.targetApp ? options.targetApp : this.skillsTargetApp);
82
+ } catch (error) {
83
+ showUnsupportedSkillsTargetMessage(this, options && options.targetApp);
84
+ return false;
85
+ }
86
+ const targetChanged = targetApp !== this.skillsTargetApp;
87
+ if (targetChanged) {
88
+ this.skillsTargetApp = targetApp;
89
+ this.resetSkillsTargetState();
90
+ } else {
91
+ this.skillsSelectedNames = [];
92
+ this.skillsKeyword = '';
93
+ this.skillsStatusFilter = 'all';
94
+ this.skillsImportSelectedKeys = [];
95
+ }
9
96
  this.showSkillsModal = true;
10
97
  await this.refreshSkillsList({ silent: false });
11
98
  },
@@ -28,23 +115,25 @@
28
115
  async refreshSkillsList(options = {}) {
29
116
  this.skillsLoading = true;
30
117
  try {
31
- const res = await api('list-codex-skills');
118
+ const res = await api('list-skills', {
119
+ targetApp: this.skillsTargetApp
120
+ });
32
121
  if (res.error) {
33
122
  this.skillsRootPath = '';
34
123
  this.skillsList = [];
35
124
  this.skillsSelectedNames = [];
36
125
  this.showMessage(res.error, 'error');
37
- return;
126
+ return false;
38
127
  }
39
128
  const exists = res.exists !== false;
40
129
  if (!exists) {
41
- this.skillsRootPath = '';
130
+ this.skillsRootPath = res.root || '';
42
131
  this.skillsList = [];
43
132
  this.skillsSelectedNames = [];
44
133
  if (!options.silent) {
45
- this.showMessage('skills 目录不存在,已按空列表显示', 'info');
134
+ this.showMessage(`${this.skillsTargetLabel} skills 目录不存在,已按空列表显示`, 'info');
46
135
  }
47
- return;
136
+ return true;
48
137
  }
49
138
  this.skillsRootPath = res.root || '';
50
139
  this.skillsList = Array.isArray(res.items) ? res.items : [];
@@ -53,16 +142,40 @@
53
142
  .filter(Boolean));
54
143
  this.skillsSelectedNames = (Array.isArray(this.skillsSelectedNames) ? this.skillsSelectedNames : [])
55
144
  .filter((name) => currentNames.has(name));
145
+ return true;
56
146
  } catch (e) {
57
147
  this.skillsRootPath = '';
58
148
  this.skillsList = [];
59
149
  this.skillsSelectedNames = [];
60
150
  this.showMessage('加载 skills 失败', 'error');
151
+ return false;
61
152
  } finally {
62
153
  this.skillsLoading = false;
63
154
  }
64
155
  },
65
156
 
157
+ async loadSkillsMarketOverview(options = {}) {
158
+ if (this.skillsMarketLoading) return false;
159
+ const silent = !!(options && options.silent);
160
+ const forceRefresh = !!(options && options.forceRefresh);
161
+ this.skillsMarketLoading = true;
162
+ let localLoaded = this.skillsMarketLocalLoadedOnce === true;
163
+ let importLoaded = this.skillsMarketImportLoadedOnce === true;
164
+ try {
165
+ if (forceRefresh || !localLoaded) {
166
+ localLoaded = await this.refreshSkillsList({ silent });
167
+ this.skillsMarketLocalLoadedOnce = localLoaded;
168
+ }
169
+ if (forceRefresh || !importLoaded) {
170
+ importLoaded = await this.scanImportableSkills({ silent });
171
+ this.skillsMarketImportLoadedOnce = importLoaded;
172
+ }
173
+ return !!(localLoaded && importLoaded);
174
+ } finally {
175
+ this.skillsMarketLoading = false;
176
+ }
177
+ },
178
+
66
179
  resetSkillsFilters() {
67
180
  this.skillsKeyword = '';
68
181
  this.skillsStatusFilter = 'all';
@@ -99,18 +212,20 @@
99
212
  },
100
213
 
101
214
  async scanImportableSkills(options = {}) {
102
- if (this.skillsScanningImports || this.skillsImporting || this.skillsZipImporting || this.skillsExporting) return;
215
+ if (this.skillsDeleting || this.skillsScanningImports || this.skillsImporting || this.skillsZipImporting || this.skillsExporting) return false;
103
216
  const silent = !!(options && options.silent);
104
217
  this.skillsScanningImports = true;
105
218
  try {
106
- const res = await api('scan-unmanaged-codex-skills');
219
+ const res = await api('scan-unmanaged-skills', {
220
+ targetApp: this.skillsTargetApp
221
+ });
107
222
  if (res.error) {
108
223
  this.skillsImportList = [];
109
224
  this.skillsImportSelectedKeys = [];
110
225
  if (!silent) {
111
226
  this.showMessage(res.error, 'error');
112
227
  }
113
- return;
228
+ return false;
114
229
  }
115
230
  this.skillsImportList = Array.isArray(res.items) ? res.items : [];
116
231
  const availableKeys = new Set(this.skillsImportSelectableKeys);
@@ -121,19 +236,21 @@
121
236
  } else if (!silent) {
122
237
  this.showMessage(`扫描到 ${this.skillsImportList.length} 个可导入 skill`, 'success');
123
238
  }
239
+ return true;
124
240
  } catch (e) {
125
241
  this.skillsImportList = [];
126
242
  this.skillsImportSelectedKeys = [];
127
243
  if (!silent) {
128
244
  this.showMessage('扫描可导入 skill 失败', 'error');
129
245
  }
246
+ return false;
130
247
  } finally {
131
248
  this.skillsScanningImports = false;
132
249
  }
133
250
  },
134
251
 
135
252
  async importSelectedSkills() {
136
- if (this.skillsImporting || this.skillsZipImporting || this.skillsExporting) return;
253
+ if (this.skillsDeleting || this.skillsScanningImports || this.skillsImporting || this.skillsZipImporting || this.skillsExporting) return;
137
254
  const selectedSet = new Set(Array.isArray(this.skillsImportSelectedKeys) ? this.skillsImportSelectedKeys : []);
138
255
  const selectedItems = (Array.isArray(this.skillsImportList) ? this.skillsImportList : [])
139
256
  .filter((item) => selectedSet.has(this.buildSkillImportKey(item)))
@@ -148,7 +265,10 @@
148
265
 
149
266
  this.skillsImporting = true;
150
267
  try {
151
- const res = await api('import-codex-skills', { items: selectedItems });
268
+ const res = await api('import-skills', {
269
+ targetApp: this.skillsTargetApp,
270
+ items: selectedItems
271
+ });
152
272
  if (res.error) {
153
273
  this.showMessage(res.error, 'error');
154
274
  return;
@@ -161,7 +281,7 @@
161
281
  const first = res.failed[0] && res.failed[0].error ? res.failed[0].error : '导入失败';
162
282
  this.showMessage(first, 'error');
163
283
  } else {
164
- this.showMessage(`已导入 ${importedCount} 个 skill`, 'success');
284
+ this.showMessage(`已导入 ${importedCount} 个 skill 到 ${this.skillsTargetLabel}`, 'success');
165
285
  }
166
286
  await this.refreshSkillsList({ silent: true });
167
287
  } catch (e) {
@@ -197,8 +317,8 @@
197
317
  async uploadSkillsZipStream(file) {
198
318
  const fileName = (file && typeof file.name === 'string' && file.name.trim())
199
319
  ? file.name.trim()
200
- : 'codex-skills.zip';
201
- const response = await fetch('/api/import-codex-skills-zip', {
320
+ : `${this.skillsTargetApp}-skills.zip`;
321
+ const response = await fetch(`/api/import-skills-zip?targetApp=${encodeURIComponent(this.skillsTargetApp)}`, {
202
322
  method: 'POST',
203
323
  headers: {
204
324
  'x-codexmate-file-name': encodeURIComponent(fileName)
@@ -222,7 +342,7 @@
222
342
  },
223
343
 
224
344
  async importSkillsFromZipFile(file) {
225
- if (this.skillsZipImporting || this.skillsImporting || this.skillsExporting) return;
345
+ if (this.skillsDeleting || this.skillsScanningImports || this.skillsZipImporting || this.skillsImporting || this.skillsExporting) return;
226
346
  const maxSize = 20 * 1024 * 1024;
227
347
  if (file.size > maxSize) {
228
348
  this.showMessage('ZIP 文件过大,限制 20MB', 'error');
@@ -244,7 +364,7 @@
244
364
  const first = res.failed[0] && res.failed[0].error ? res.failed[0].error : '导入失败';
245
365
  this.showMessage(first, 'error');
246
366
  } else {
247
- this.showMessage(`已导入 ${importedCount} 个 skill`, 'success');
367
+ this.showMessage(`已导入 ${importedCount} 个 skill 到 ${this.skillsTargetLabel}`, 'success');
248
368
  }
249
369
  await this.refreshSkillsList({ silent: true });
250
370
  } catch (e) {
@@ -257,7 +377,7 @@
257
377
  },
258
378
 
259
379
  async exportSelectedSkills() {
260
- if (this.skillsExporting || this.skillsZipImporting || this.skillsImporting) return;
380
+ if (this.skillsDeleting || this.skillsExporting || this.skillsZipImporting || this.skillsImporting) return;
261
381
  const selected = Array.isArray(this.skillsSelectedNames)
262
382
  ? Array.from(new Set(this.skillsSelectedNames.map((item) => String(item || '').trim()).filter(Boolean)))
263
383
  : [];
@@ -267,7 +387,10 @@
267
387
  }
268
388
  this.skillsExporting = true;
269
389
  try {
270
- const res = await api('export-codex-skills', { names: selected });
390
+ const res = await api('export-skills', {
391
+ targetApp: this.skillsTargetApp,
392
+ names: selected
393
+ });
271
394
  if (res && res.error) {
272
395
  this.showMessage(res.error, 'error');
273
396
  return;
@@ -290,7 +413,7 @@
290
413
  if (failedCount > 0) {
291
414
  this.showMessage(`已导出 ${exportedCount} 个,失败 ${failedCount} 个`, 'error');
292
415
  } else {
293
- this.showMessage(`已导出 ${exportedCount} 个 skill`, 'success');
416
+ this.showMessage(`已从 ${this.skillsTargetLabel} 导出 ${exportedCount} 个 skill`, 'success');
294
417
  }
295
418
  } catch (e) {
296
419
  this.showMessage('导出 skill 失败', 'error');
@@ -301,6 +424,10 @@
301
424
 
302
425
  async deleteSelectedSkills() {
303
426
  if (this.skillsDeleting || this.skillsZipImporting || this.skillsExporting || this.skillsImporting) return;
427
+ if (this.skillsScanningImports) {
428
+ this.showMessage('正在扫描导入源,请稍后再试', 'error');
429
+ return;
430
+ }
304
431
  const selected = Array.isArray(this.skillsSelectedNames)
305
432
  ? Array.from(new Set(this.skillsSelectedNames.map((item) => String(item || '').trim()).filter(Boolean)))
306
433
  : [];
@@ -310,9 +437,10 @@
310
437
  }
311
438
  const confirmed = await this.requestConfirmDialog({
312
439
  title: '删除 Skills',
313
- message: `确认删除 ${selected.length} 个 skill 吗?此操作不可撤销。`,
440
+ message: `确认从 ${this.skillsTargetLabel} 删除 ${selected.length} 个 skill 吗?此操作不可撤销。`,
314
441
  confirmText: '删除',
315
442
  cancelText: '取消',
443
+ confirmDisabled: () => this.skillsDeleting || this.skillsScanningImports,
316
444
  danger: true
317
445
  });
318
446
  if (!confirmed) {
@@ -321,7 +449,10 @@
321
449
 
322
450
  this.skillsDeleting = true;
323
451
  try {
324
- const res = await api('delete-codex-skills', { names: selected });
452
+ const res = await api('delete-skills', {
453
+ targetApp: this.skillsTargetApp,
454
+ names: selected
455
+ });
325
456
  if (res.error) {
326
457
  this.showMessage(res.error, 'error');
327
458
  return;
@@ -336,7 +467,7 @@
336
467
  const first = failedList[0] && failedList[0].error ? failedList[0].error : '删除失败';
337
468
  this.showMessage(first, 'error');
338
469
  } else {
339
- this.showMessage(`已删除 ${deletedCount} 个 skill`, 'success');
470
+ this.showMessage(`已从 ${this.skillsTargetLabel} 删除 ${deletedCount} 个 skill`, 'success');
340
471
  }
341
472
  await this.refreshSkillsList({ silent: true });
342
473
  } catch (e) {
@@ -61,6 +61,18 @@ export function switchMainTab(tab) {
61
61
  this.sessionTrashLoadedOnce = false;
62
62
  this.loadSessionTrashCount({ silent: true });
63
63
  }
64
+ const shouldLoadSkillsMarketOnEnter = nextTab === 'market'
65
+ && previousTab !== 'market'
66
+ && typeof this.loadSkillsMarketOverview === 'function';
67
+ if (shouldLoadSkillsMarketOnEnter) {
68
+ let marketOverviewLoad = null;
69
+ try {
70
+ marketOverviewLoad = this.loadSkillsMarketOverview({ silent: true });
71
+ } catch (_) {
72
+ marketOverviewLoad = null;
73
+ }
74
+ void Promise.resolve(marketOverviewLoad).catch(() => {});
75
+ }
64
76
  if (nextTab === 'config' && this.configMode === 'claude') {
65
77
  const expectedTab = nextTab;
66
78
  const expectedConfigMode = this.configMode;
package/web-ui/styles.css CHANGED
@@ -37,11 +37,13 @@
37
37
 
38
38
  --font-size-display: 52px;
39
39
  --font-size-title: 18px;
40
+ --font-size-large: 20px;
40
41
  --font-size-body: 15px;
41
42
  --font-size-secondary: 13px;
42
43
  --font-size-caption: 11px;
43
44
 
44
45
  --font-weight-display: 600;
46
+ --font-weight-primary: 600;
45
47
  --font-weight-title: 600;
46
48
  --font-weight-body: 400;
47
49
  --font-weight-secondary: 500;
@@ -59,6 +61,7 @@
59
61
 
60
62
  /* 圆角系统 */
61
63
  --radius-sm: 8px;
64
+ --radius-md: 10px;
62
65
  --radius-lg: 12px;
63
66
  --radius-xl: 18px;
64
67
  --radius-full: 50px;
@@ -1326,9 +1329,9 @@ body::after {
1326
1329
  grid-auto-columns: max-content;
1327
1330
  column-gap: var(--spacing-xs);
1328
1331
  row-gap: 6px;
1329
- align-items: start;
1332
+ align-items: center;
1330
1333
  justify-content: end;
1331
- align-self: flex-start;
1334
+ align-self: center;
1332
1335
  }
1333
1336
 
1334
1337
  .card-trailing .card-actions {
@@ -3668,6 +3671,160 @@ body::after {
3668
3671
  line-height: 1.45;
3669
3672
  }
3670
3673
 
3674
+ .market-overview-section {
3675
+ margin-bottom: var(--spacing-sm);
3676
+ }
3677
+
3678
+ .market-overview-header {
3679
+ gap: var(--spacing-sm);
3680
+ align-items: flex-start;
3681
+ }
3682
+
3683
+ .market-header-actions {
3684
+ flex-wrap: wrap;
3685
+ }
3686
+
3687
+ .market-target-switch {
3688
+ display: flex;
3689
+ flex-wrap: wrap;
3690
+ gap: 8px;
3691
+ margin-bottom: var(--spacing-sm);
3692
+ }
3693
+
3694
+ .market-target-switch-compact {
3695
+ justify-content: flex-end;
3696
+ margin-bottom: 0;
3697
+ }
3698
+
3699
+ .market-target-chip {
3700
+ border: 1px solid rgba(160, 145, 130, 0.28);
3701
+ border-radius: 999px;
3702
+ background: rgba(255, 255, 255, 0.92);
3703
+ color: var(--color-text-secondary);
3704
+ padding: 8px 14px;
3705
+ font-size: var(--font-size-caption);
3706
+ font-weight: var(--font-weight-secondary);
3707
+ cursor: pointer;
3708
+ transition: border-color var(--transition-fast) var(--ease-smooth), background var(--transition-fast) var(--ease-smooth), color var(--transition-fast) var(--ease-smooth), box-shadow var(--transition-fast) var(--ease-smooth);
3709
+ }
3710
+
3711
+ .market-target-chip:disabled,
3712
+ .market-target-chip[disabled] {
3713
+ cursor: not-allowed;
3714
+ opacity: 0.64;
3715
+ pointer-events: none;
3716
+ box-shadow: none;
3717
+ }
3718
+
3719
+ .market-target-chip.active {
3720
+ border-color: rgba(208, 88, 58, 0.4);
3721
+ background: linear-gradient(to bottom, rgba(255, 243, 236, 0.98) 0%, rgba(255, 232, 220, 0.86) 100%);
3722
+ color: #8c3a1f;
3723
+ box-shadow: var(--shadow-subtle);
3724
+ }
3725
+
3726
+ .market-root-box {
3727
+ margin-bottom: var(--spacing-sm);
3728
+ }
3729
+
3730
+ .market-grid {
3731
+ display: grid;
3732
+ grid-template-columns: repeat(2, minmax(0, 1fr));
3733
+ gap: var(--spacing-sm);
3734
+ }
3735
+
3736
+ .market-panel {
3737
+ margin-bottom: 0;
3738
+ min-width: 0;
3739
+ }
3740
+
3741
+ .market-actions-panel {
3742
+ grid-column: 1 / -1;
3743
+ }
3744
+
3745
+ .market-panel-wide {
3746
+ grid-column: 1 / -1;
3747
+ }
3748
+
3749
+ .market-preview-list {
3750
+ display: grid;
3751
+ gap: 10px;
3752
+ }
3753
+
3754
+ .market-preview-item {
3755
+ display: flex;
3756
+ align-items: flex-start;
3757
+ justify-content: space-between;
3758
+ gap: var(--spacing-xs);
3759
+ padding: 10px 12px;
3760
+ border: 1px solid rgba(160, 145, 130, 0.18);
3761
+ border-radius: var(--radius-sm);
3762
+ background: rgba(255, 255, 255, 0.64);
3763
+ }
3764
+
3765
+ .market-preview-main {
3766
+ min-width: 0;
3767
+ display: flex;
3768
+ flex-direction: column;
3769
+ gap: 4px;
3770
+ }
3771
+
3772
+ .market-preview-title {
3773
+ font-size: var(--font-size-body);
3774
+ font-weight: var(--font-weight-secondary);
3775
+ color: var(--color-text-secondary);
3776
+ overflow-wrap: anywhere;
3777
+ }
3778
+
3779
+ .market-preview-meta {
3780
+ font-size: var(--font-size-caption);
3781
+ color: var(--color-text-tertiary);
3782
+ line-height: 1.45;
3783
+ overflow-wrap: anywhere;
3784
+ }
3785
+
3786
+ .market-action-grid {
3787
+ display: grid;
3788
+ grid-template-columns: repeat(3, minmax(0, 1fr));
3789
+ gap: var(--spacing-xs);
3790
+ }
3791
+
3792
+ .market-action-card {
3793
+ border: 1px solid rgba(160, 145, 130, 0.24);
3794
+ border-radius: var(--radius-sm);
3795
+ background: linear-gradient(to bottom, rgba(255, 255, 255, 0.96) 0%, rgba(255, 248, 242, 0.84) 100%);
3796
+ color: var(--color-text-secondary);
3797
+ text-align: left;
3798
+ padding: 14px;
3799
+ display: flex;
3800
+ flex-direction: column;
3801
+ gap: 6px;
3802
+ cursor: pointer;
3803
+ transition: transform var(--transition-fast) var(--ease-smooth), box-shadow var(--transition-fast) var(--ease-smooth), border-color var(--transition-fast) var(--ease-smooth);
3804
+ }
3805
+
3806
+ .market-action-card:hover:not(:disabled) {
3807
+ transform: translateY(-1px);
3808
+ border-color: rgba(208, 88, 58, 0.34);
3809
+ box-shadow: var(--shadow-subtle);
3810
+ }
3811
+
3812
+ .market-action-card:disabled {
3813
+ cursor: not-allowed;
3814
+ opacity: 0.64;
3815
+ }
3816
+
3817
+ .market-action-title {
3818
+ font-size: var(--font-size-body);
3819
+ font-weight: var(--font-weight-secondary);
3820
+ }
3821
+
3822
+ .market-action-copy {
3823
+ font-size: var(--font-size-caption);
3824
+ color: var(--color-text-tertiary);
3825
+ line-height: 1.45;
3826
+ }
3827
+
3671
3828
  .skills-filter-row {
3672
3829
  display: flex;
3673
3830
  gap: var(--spacing-xs);
@@ -4176,6 +4333,10 @@ textarea:focus-visible {
4176
4333
  .skills-modal-actions {
4177
4334
  align-items: flex-start;
4178
4335
  }
4336
+
4337
+ .market-target-switch-compact {
4338
+ justify-content: flex-start;
4339
+ }
4179
4340
  }
4180
4341
 
4181
4342
  @media (max-width: 720px) {
@@ -4202,6 +4363,14 @@ textarea:focus-visible {
4202
4363
  flex-wrap: wrap;
4203
4364
  }
4204
4365
 
4366
+ .market-grid {
4367
+ grid-template-columns: 1fr;
4368
+ }
4369
+
4370
+ .market-action-grid {
4371
+ grid-template-columns: 1fr;
4372
+ }
4373
+
4205
4374
  .status-chip {
4206
4375
  flex: 1 1 100%;
4207
4376
  }
package/doc/CHANGELOG.md DELETED
@@ -1,32 +0,0 @@
1
- # Changelog
2
-
3
- ## 0.0.15
4
-
5
- - Release: bump package version to 0.0.15
6
- - Docs: sync README / README.en with current release marker
7
-
8
- ## 0.0.14
9
-
10
- - Skills Manager: polish modal layout with overview counters and clearer section structure
11
- - Skills Manager: unify status select style and refine list scrollbar density
12
- - Docs: sync README / README.en release notes for 0.0.14
13
-
14
- ## 0.0.13
15
-
16
- - Web UI: switch to IDE-style three-column layout with a fixed status inspector panel
17
- - AGENTS editor: add "Export" action to download current content as `agent-<timestamp>.txt`
18
- - Release: bump package version to 0.0.13 and sync release docs/examples
19
-
20
- ## 0.0.5
21
-
22
- - Sessions: enable keyword search for Codex-only view
23
- - Sessions: increase keyword scan limit to reduce misses
24
- - Utilities: add JS fallback for zip/unzip when 7-Zip is missing
25
- - UI: shorten base_url/key/model check hint
26
-
27
- ## 0.0.4
28
-
29
- - Added OpenClaw config mode with JSON5 profiles and one-click apply
30
- - Added OpenClaw workspace AGENTS.md management
31
- - Added JSON5 parsing dependency
32
-
@@ -1,34 +0,0 @@
1
- # 更新日志
2
-
3
- ## 0.0.15
4
-
5
- - 发版:版本提升至 0.0.15
6
- - 文档:同步 README / README.en 当前版本标记
7
-
8
-
9
-
10
- ## 0.0.14
11
-
12
- - Skills 管理:打磨弹窗信息层级,新增统计概览与分区结构
13
- - Skills 管理:统一状态下拉样式,并优化列表滚动条密度
14
- - 文档:同步 README / README.en 的 0.0.14 发版说明
15
-
16
- ## 0.0.13
17
-
18
- - Web UI:调整为 IDE 风格三栏布局,并新增固定可见的状态检查器
19
- - AGENTS 编辑器:新增“导出”按钮,可下载当前内容为 `agent-<timestamp>.txt`
20
- - 发版:版本提升至 0.0.13,并同步 README 发版示例版本号
21
-
22
- ## 0.0.5
23
-
24
- - 会话浏览:仅 Codex 支持关键词检索
25
- - 会话浏览:关键词扫描上限提升,降低漏检
26
- - 附属功能:7-Zip 缺失时回退内置 JS 压缩/解压
27
- - 文案:精简检测提示
28
-
29
- ## 0.0.4
30
-
31
- - 新增 OpenClaw 配置模式(JSON5 多配置管理 + 一键应用)
32
- - 新增 OpenClaw Workspace 的 AGENTS.md 管理
33
- - 增加 JSON5 解析依赖
34
-