codexmate 0.0.55 → 0.0.57

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 (49) hide show
  1. package/README.md +2 -0
  2. package/README.vi.md +2 -0
  3. package/README.zh.md +2 -0
  4. package/cli/local-bridge.js +221 -22
  5. package/cli.js +797 -134
  6. package/lib/task-orchestrator.js +90 -21
  7. package/lib/task-workspace-chat.js +292 -0
  8. package/package.json +2 -2
  9. package/web-ui/app.js +57 -129
  10. package/web-ui/modules/app.computed.main-tabs.mjs +304 -7
  11. package/web-ui/modules/app.computed.session.mjs +210 -0
  12. package/web-ui/modules/app.methods.agents.mjs +3 -0
  13. package/web-ui/modules/app.methods.claude-config.mjs +178 -22
  14. package/web-ui/modules/app.methods.codex-config.mjs +294 -65
  15. package/web-ui/modules/app.methods.navigation.mjs +71 -84
  16. package/web-ui/modules/app.methods.openclaw-editing.mjs +3 -6
  17. package/web-ui/modules/app.methods.providers.mjs +15 -1
  18. package/web-ui/modules/app.methods.runtime.mjs +7 -2
  19. package/web-ui/modules/app.methods.session-actions.mjs +25 -12
  20. package/web-ui/modules/app.methods.session-browser.mjs +23 -54
  21. package/web-ui/modules/app.methods.session-trash.mjs +0 -1
  22. package/web-ui/modules/app.methods.startup-claude.mjs +35 -17
  23. package/web-ui/modules/app.methods.task-orchestration.mjs +347 -8
  24. package/web-ui/modules/app.methods.tool-config-permissions.mjs +0 -3
  25. package/web-ui/modules/app.methods.web-ui-preferences.mjs +415 -68
  26. package/web-ui/modules/config-template-confirm-pref.mjs +2 -3
  27. package/web-ui/modules/i18n/locales/en.mjs +187 -28
  28. package/web-ui/modules/i18n/locales/ja.mjs +184 -25
  29. package/web-ui/modules/i18n/locales/vi.mjs +186 -33
  30. package/web-ui/modules/i18n/locales/zh-tw.mjs +187 -28
  31. package/web-ui/modules/i18n/locales/zh.mjs +189 -30
  32. package/web-ui/modules/i18n.mjs +5 -12
  33. package/web-ui/modules/provider-default-names.mjs +25 -0
  34. package/web-ui/modules/sessions-filters-url.mjs +1 -2
  35. package/web-ui/partials/index/layout-header.html +37 -14
  36. package/web-ui/partials/index/modal-health-check.html +69 -5
  37. package/web-ui/partials/index/panel-config-codex.html +2 -2
  38. package/web-ui/partials/index/panel-orchestration.html +489 -282
  39. package/web-ui/partials/index/panel-sessions.html +97 -17
  40. package/web-ui/res/web-ui-render.precompiled.js +1423 -732
  41. package/web-ui/session-helpers.mjs +4 -1
  42. package/web-ui/styles/layout-shell.css +157 -1
  43. package/web-ui/styles/navigation-panels.css +11 -0
  44. package/web-ui/styles/responsive.css +98 -0
  45. package/web-ui/styles/sessions-preview.css +212 -2
  46. package/web-ui/styles/sessions-toolbar-trash.css +61 -18
  47. package/web-ui/styles/skills-list.css +122 -0
  48. package/web-ui/styles/task-orchestration.css +2161 -4
  49. package/web-ui/styles/titles-cards.css +52 -0
package/web-ui/app.js CHANGED
@@ -6,7 +6,6 @@ import {
6
6
  } from './modules/app.constants.mjs';
7
7
  import { createAppComputed } from './modules/app.computed.index.mjs';
8
8
  import { createAppMethods } from './modules/app.methods.index.mjs';
9
- import { loadConfigTemplateDiffConfirmEnabledFromStorage } from './modules/config-template-confirm-pref.mjs';
10
9
  import { installWebUiUrlCanonicalization } from './modules/sessions-filters-url.mjs';
11
10
 
12
11
  document.addEventListener('DOMContentLoaded', () => {
@@ -174,7 +173,7 @@ document.addEventListener('DOMContentLoaded', () => {
174
173
  ticket: 0
175
174
  },
176
175
  sessionsViewMode: 'browser',
177
- sessionsUsageTimeRange: (function () { try { const saved = localStorage.getItem('sessionsUsageTimeRange'); if (saved === '7d' || saved === '30d' || saved === 'all') return saved; } catch (_) {} return '7d'; })(),
176
+ sessionsUsageTimeRange: '7d',
178
177
  sessionsUsageList: [],
179
178
  sessionsUsageCompareEnabled: false,
180
179
  sessionsUsageSelectedDayKey: '',
@@ -272,6 +271,8 @@ document.addEventListener('DOMContentLoaded', () => {
272
271
  healthCheckBatchTotal: 0,
273
272
  healthCheckBatchDone: 0,
274
273
  healthCheckBatchFailed: 0,
274
+ healthCheckFailedProviderSelections: {},
275
+ healthCheckFailedProviderDeleting: false,
275
276
  installPackageManager: 'npm',
276
277
  installCommandAction: 'install',
277
278
  installRegistryPreset: 'npmmirror',
@@ -389,22 +390,7 @@ document.addEventListener('DOMContentLoaded', () => {
389
390
  providerCacheError: '',
390
391
  providerCacheRequestSeq: 0,
391
392
  settingsTab: 'general',
392
- toolConfigPermissions: (function() {
393
- try {
394
- const cached = localStorage.getItem('toolConfigPermissions');
395
- if (cached) {
396
- const parsed = JSON.parse(cached);
397
- if (parsed && typeof parsed === 'object' && !Array.isArray(parsed)) {
398
- return {
399
- codex: parsed.codex === true,
400
- claude: parsed.claude === true,
401
- opencode: parsed.opencode === true
402
- };
403
- }
404
- }
405
- } catch (_) {}
406
- return { codex: false, claude: false, opencode: false };
407
- })(),
393
+ toolConfigPermissions: { codex: false, claude: false, opencode: false },
408
394
  toolConfigPermissionSaving: { codex: false, claude: false, opencode: false },
409
395
  sessionTrashEnabled: true,
410
396
  sessionTrashItems: [],
@@ -449,6 +435,9 @@ document.addEventListener('DOMContentLoaded', () => {
449
435
  opencodeMaxTokens: '',
450
436
  opencodeReasoningEffort: '',
451
437
  forceCompactLayout: false,
438
+ sidebarCollapsed: false,
439
+ sessionLoadNativeDialog: false,
440
+ starPrompted: false,
452
441
  taskOrchestrationTabEnabled: true,
453
442
  taskOrchestration: {
454
443
  loading: false,
@@ -458,11 +447,14 @@ document.addEventListener('DOMContentLoaded', () => {
458
447
  queueStarting: false,
459
448
  retrying: false,
460
449
  target: '',
450
+ chatDraft: '',
461
451
  title: '',
462
452
  notes: '',
453
+ workspacePath: '',
454
+ threadId: '',
463
455
  followUpsText: '',
464
456
  workflowIdsText: '',
465
- selectedEngine: 'codex',
457
+ selectedEngine: 'openai-chat',
466
458
  runMode: 'write',
467
459
  concurrency: 2,
468
460
  autoFixRounds: 1,
@@ -480,6 +472,7 @@ document.addEventListener('DOMContentLoaded', () => {
480
472
  selectedRunLoading: false,
481
473
  selectedRunError: '',
482
474
  detailRequestToken: 0,
475
+ settingsOpen: false,
483
476
  lastLoadedAt: '',
484
477
  lastError: ''
485
478
  },
@@ -499,9 +492,8 @@ document.addEventListener('DOMContentLoaded', () => {
499
492
  if (pathname === '/web-ui' || pathname === '/web-ui/' || pathname === '/web-ui/index.html') {
500
493
  const url = new URL(window.location.href);
501
494
  url.pathname = '/';
502
- // 移除查询参数和 hash,保持 URL 纯净
503
- url.search = '';
504
- url.hash = '';
495
+ // Preserve startup query/hash flags while normalizing the legacy web-ui path.
496
+ // Feature gates such as ?taskOrchestration=1 are consumed below after redirect.
505
497
  window.location.replace(url.toString());
506
498
  return;
507
499
  }
@@ -534,25 +526,15 @@ document.addEventListener('DOMContentLoaded', () => {
534
526
  this.agentsModalTitle = this.t('modal.agents.title');
535
527
  this.agentsModalHint = this.t('modal.agents.hint');
536
528
  }
529
+ try {
530
+ const url = new URL(window.location.href);
531
+ const requestedTaskOrchestration = String(url.searchParams.get('taskOrchestration') || '').trim().toLowerCase();
532
+ if (requestedTaskOrchestration === '1' || requestedTaskOrchestration === 'true') {
533
+ this.taskOrchestrationTabEnabled = true;
534
+ }
535
+ } catch (_) {}
537
536
  {
538
- const NAV_STATE_STORAGE_KEY = 'codexmateNavState.v1';
539
537
  const mainTabSet = new Set(['dashboard', 'config', 'sessions', 'usage', 'orchestration', 'market', 'plugins', 'docs', 'settings', 'trash', 'prompts']);
540
- let restored = null;
541
- try {
542
- const raw = localStorage.getItem(NAV_STATE_STORAGE_KEY) || '';
543
- restored = raw ? JSON.parse(raw) : null;
544
- } catch (_) {
545
- restored = null;
546
- }
547
- const nextMainTab = restored && typeof restored.mainTab === 'string'
548
- ? restored.mainTab.trim().toLowerCase()
549
- : '';
550
- const nextConfigMode = restored && typeof restored.configMode === 'string'
551
- ? restored.configMode.trim().toLowerCase()
552
- : '';
553
- const nextSettingsTab = restored && typeof restored.settingsTab === 'string'
554
- ? restored.settingsTab.trim().toLowerCase()
555
- : '';
556
538
  let urlMainTab = '';
557
539
  try {
558
540
  const url = new URL(window.location.href);
@@ -562,25 +544,13 @@ document.addEventListener('DOMContentLoaded', () => {
562
544
  } catch (_) {
563
545
  urlMainTab = '';
564
546
  }
565
- const resolvedMainTab = urlMainTab && mainTabSet.has(urlMainTab)
566
- ? urlMainTab
567
- : nextMainTab;
568
- if (nextSettingsTab && (nextSettingsTab === 'general' || nextSettingsTab === 'data')) {
569
- this.settingsTab = nextSettingsTab;
547
+ let resolvedMainTab = urlMainTab && mainTabSet.has(urlMainTab) ? urlMainTab : '';
548
+ if (typeof this.isMainTabDisabled === 'function' && this.isMainTabDisabled(resolvedMainTab)) {
549
+ resolvedMainTab = typeof this.getFirstSelectableMainTab === 'function'
550
+ ? this.getFirstSelectableMainTab()
551
+ : 'dashboard';
570
552
  }
571
- if (nextConfigMode && typeof this.switchConfigMode === 'function') {
572
- this.__navStateRestoring = true;
573
- try {
574
- if (nextConfigMode === 'codex' || nextConfigMode === 'claude' || nextConfigMode === 'openclaw' || nextConfigMode === 'opencode') {
575
- this.configMode = nextConfigMode;
576
- }
577
- if (resolvedMainTab && mainTabSet.has(resolvedMainTab) && resolvedMainTab !== this.mainTab) {
578
- this.switchMainTab(resolvedMainTab);
579
- }
580
- } finally {
581
- this.__navStateRestoring = false;
582
- }
583
- } else if (resolvedMainTab && mainTabSet.has(resolvedMainTab) && resolvedMainTab !== this.mainTab) {
553
+ if (resolvedMainTab && mainTabSet.has(resolvedMainTab) && resolvedMainTab !== this.mainTab) {
584
554
  this.__navStateRestoring = true;
585
555
  try {
586
556
  this.switchMainTab(resolvedMainTab);
@@ -591,61 +561,26 @@ document.addEventListener('DOMContentLoaded', () => {
591
561
  }
592
562
  this.initSessionStandalone();
593
563
  this.updateCompactLayoutMode();
594
- if (!this.taskOrchestrationTabEnabled && this.mainTab === 'orchestration') {
595
- this.mainTab = 'config';
564
+ if (typeof this.isMainTabDisabled === 'function' && this.isMainTabDisabled(this.mainTab)) {
565
+ const fallbackTab = typeof this.getFirstSelectableMainTab === 'function'
566
+ ? this.getFirstSelectableMainTab()
567
+ : 'dashboard';
568
+ this.switchMainTab(fallbackTab);
569
+ } else if (!this.taskOrchestrationTabEnabled && this.mainTab === 'orchestration') {
570
+ this.switchMainTab('dashboard');
596
571
  }
597
572
  this.restoreSessionFilterCache();
598
573
  this.restoreSessionPinnedMap();
599
- this.shareCommandPrefix = this.normalizeShareCommandPrefix(localStorage.getItem('codexmateShareCommandPrefix'));
600
- this.sessionTrashEnabled = this.normalizeSessionTrashEnabled(localStorage.getItem('codexmateSessionTrashEnabled'));
601
- this.sessionTrashRetentionDays = this.normalizeSessionTrashRetentionDays(localStorage.getItem('codexmateSessionTrashRetentionDays'));
602
- try {
603
- var savedTimelineStyle = localStorage.getItem('codexmateSessionTimelineStyle');
604
- this.sessionTimelineStyle = savedTimelineStyle === 'bar' ? 'bar' : 'dots';
605
- } catch (_) {}
606
- this.configTemplateDiffConfirmEnabled = loadConfigTemplateDiffConfirmEnabledFromStorage(localStorage);
607
- try {
608
- var savedProjectPath = localStorage.getItem('codexmate_project_claude_md_path');
609
- if (savedProjectPath) {
610
- this.projectClaudeMdPath = savedProjectPath;
611
- }
612
- } catch (_) {}
613
- try {
614
- var savedSubTab = localStorage.getItem('codexmate_prompts_sub_tab');
615
- if (savedSubTab === 'codex' || savedSubTab === 'claude-project') {
616
- this.promptsSubTab = savedSubTab;
617
- }
618
- } catch (_) {}
619
574
  window.addEventListener('resize', this.onWindowResize);
620
575
  window.addEventListener('keydown', this.handleGlobalKeydown);
621
576
  window.addEventListener('beforeunload', this.handleBeforeUnload);
622
- const savedConfigs = localStorage.getItem('claudeConfigs');
623
- if (savedConfigs) {
624
- try {
625
- this.claudeConfigs = JSON.parse(savedConfigs);
626
- for (const [name, config] of Object.entries(this.claudeConfigs)) {
627
- if (config.apiKey && config.apiKey.includes('****')) {
628
- config.apiKey = '';
629
- config.hasKey = false;
630
- }
631
- const targetApiRaw = typeof config.targetApi === 'string' ? config.targetApi.trim().toLowerCase() : '';
632
- if (targetApiRaw === 'chat_completions' || targetApiRaw === 'chat-completions' || targetApiRaw === 'chat/completions') {
633
- config.targetApi = 'chat_completions';
634
- } else if (targetApiRaw === 'ollama') {
635
- config.targetApi = 'ollama';
636
- } else {
637
- config.targetApi = 'responses';
638
- }
639
- }
640
- localStorage.setItem('claudeConfigs', JSON.stringify(this.claudeConfigs));
641
- } catch (e) {
642
- console.error('加载 Claude 配置失败:', e);
643
- }
644
- }
645
- {
646
- const savedCurrentClaudeConfig = localStorage.getItem('currentClaudeConfig');
647
- if (savedCurrentClaudeConfig && this.claudeConfigs[savedCurrentClaudeConfig]) {
648
- this.currentClaudeConfig = savedCurrentClaudeConfig;
577
+ if (typeof this.normalizeStoredClaudeConfigs === 'function') {
578
+ const claudeConfigsChanged = this.normalizeStoredClaudeConfigs();
579
+ if (claudeConfigsChanged && typeof this.persistWebUiPreferences === 'function') {
580
+ this.persistWebUiPreferences({
581
+ claudeConfigs: this.claudeConfigs,
582
+ currentClaudeConfig: this.currentClaudeConfig || ''
583
+ });
649
584
  }
650
585
  }
651
586
  if (!this.currentClaudeConfig) {
@@ -679,17 +614,7 @@ document.addEventListener('DOMContentLoaded', () => {
679
614
  }
680
615
  return normalized;
681
616
  };
682
- const savedOpenclawConfigs = localStorage.getItem('openclawConfigs');
683
- if (savedOpenclawConfigs) {
684
- try {
685
- this.openclawConfigs = normalizeOpenclawConfigs(JSON.parse(savedOpenclawConfigs));
686
- } catch (e) {
687
- console.error('加载 OpenClaw 配置失败:', e);
688
- this.openclawConfigs = normalizeOpenclawConfigs(this.openclawConfigs);
689
- }
690
- } else {
691
- this.openclawConfigs = normalizeOpenclawConfigs(this.openclawConfigs);
692
- }
617
+ this.openclawConfigs = normalizeOpenclawConfigs(this.openclawConfigs);
693
618
  const configNames = Object.keys(this.openclawConfigs);
694
619
  if (configNames.length > 0) {
695
620
  this.currentOpenclawConfig = this.openclawConfigs['默认配置'] ? '默认配置' : configNames[0];
@@ -772,8 +697,12 @@ document.addEventListener('DOMContentLoaded', () => {
772
697
  this._initialLoadTimer = 0;
773
698
  }
774
699
  if (this.__webUiPreferencesPersistTimer) {
775
- clearTimeout(this.__webUiPreferencesPersistTimer);
776
- this.__webUiPreferencesPersistTimer = 0;
700
+ if (typeof this.flushWebUiPreferences === 'function') {
701
+ this.flushWebUiPreferences();
702
+ } else {
703
+ clearTimeout(this.__webUiPreferencesPersistTimer);
704
+ this.__webUiPreferencesPersistTimer = 0;
705
+ }
777
706
  }
778
707
  window.removeEventListener('resize', this.onWindowResize);
779
708
  window.removeEventListener('keydown', this.handleGlobalKeydown);
@@ -788,6 +717,15 @@ document.addEventListener('DOMContentLoaded', () => {
788
717
 
789
718
  watch: {
790
719
  mainTab(newTab) {
720
+ if (typeof this.isMainTabDisabled === 'function' && this.isMainTabDisabled(newTab)) {
721
+ const fallbackTab = typeof this.getFirstSelectableMainTab === 'function'
722
+ ? this.getFirstSelectableMainTab()
723
+ : 'dashboard';
724
+ if (fallbackTab && fallbackTab !== newTab && typeof this.switchMainTab === 'function') {
725
+ this.switchMainTab(fallbackTab);
726
+ }
727
+ return;
728
+ }
791
729
  if (newTab === 'prompts' && typeof this.loadPromptsContent === 'function') {
792
730
  if (this.promptsSubTab === 'claude-project' && !this.projectPathOptions.length && !this.projectPathOptionsLoading && typeof this.loadProjectPathOptions === 'function') {
793
731
  this.loadProjectPathOptions();
@@ -796,9 +734,6 @@ document.addEventListener('DOMContentLoaded', () => {
796
734
  }
797
735
  },
798
736
  promptsSubTab(newVal) {
799
- try {
800
- localStorage.setItem('codexmate_prompts_sub_tab', newVal);
801
- } catch (_) {}
802
737
  if (typeof this.persistWebUiPreferences === 'function') {
803
738
  this.persistWebUiPreferences({ promptsSubTab: newVal });
804
739
  }
@@ -807,13 +742,6 @@ document.addEventListener('DOMContentLoaded', () => {
807
742
  }
808
743
  },
809
744
  projectClaudeMdPath(newPath) {
810
- try {
811
- if (newPath) {
812
- localStorage.setItem('codexmate_project_claude_md_path', newPath);
813
- } else {
814
- localStorage.removeItem('codexmate_project_claude_md_path');
815
- }
816
- } catch (_) {}
817
745
  if (typeof this.persistWebUiPreferences === 'function') {
818
746
  this.persistWebUiPreferences({ projectClaudeMdPath: newPath || '' });
819
747
  }