chainlesschain 0.45.2 → 0.45.4

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "chainlesschain",
3
- "version": "0.45.2",
3
+ "version": "0.45.4",
4
4
  "description": "CLI for ChainlessChain - install, configure, and manage your personal AI management system",
5
5
  "type": "module",
6
6
  "bin": {
@@ -15,6 +15,7 @@ import { WSSessionManager } from "../lib/ws-session-manager.js";
15
15
  import { createWebUIServer } from "../lib/web-ui-server.js";
16
16
  import { bootstrap } from "../runtime/bootstrap.js";
17
17
  import { findProjectRoot, loadProjectConfig } from "../lib/project-detector.js";
18
+ import { loadConfig } from "../lib/config-manager.js";
18
19
 
19
20
  /**
20
21
  * Open a URL in the system default browser (cross-platform).
@@ -82,9 +83,11 @@ export function registerUiCommand(program) {
82
83
  }
83
84
 
84
85
  // ── Start WebSocket server ────────────────────────────────────────────
86
+ const appConfig = loadConfig();
85
87
  const sessionManager = new WSSessionManager({
86
88
  db,
87
89
  defaultProjectRoot: projectRoot || process.cwd(),
90
+ config: appConfig,
88
91
  });
89
92
 
90
93
  const wsServer = new ChainlessChainWSServer({
@@ -55,8 +55,8 @@ function buildHtml({
55
55
  <title>${escapeHtml(title)}</title>
56
56
  <script>window.__CC_CONFIG__ = ${cfg};</script>
57
57
  <link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/highlight.js/11.9.0/styles/github-dark.min.css">
58
- <script src="https://cdnjs.cloudflare.com/ajax/libs/marked/12.0.0/marked.min.js"></script>
59
- <script src="https://cdnjs.cloudflare.com/ajax/libs/highlight.js/11.9.0/highlight.min.js"></script>
58
+ <script src="https://cdnjs.cloudflare.com/ajax/libs/marked/9.1.6/marked.min.js" defer></script>
59
+ <script src="https://cdnjs.cloudflare.com/ajax/libs/highlight.js/11.9.0/highlight.min.js" defer></script>
60
60
  <style>
61
61
  *, *::before, *::after { box-sizing: border-box; margin: 0; padding: 0; }
62
62
 
@@ -460,7 +460,7 @@ function buildHtml({
460
460
  <div id="conn-dot"></div>
461
461
  <span id="conn-label">未连接</span>
462
462
  </div>
463
- <span id="version-label">v5.0.2.3</span>
463
+ <span id="version-label">v5.0.2.5</span>
464
464
  </div>
465
465
  </nav>
466
466
 
@@ -523,6 +523,7 @@ function buildHtml({
523
523
  let selectedSessionType = 'agent';
524
524
  let pendingQuestionResolve = null;
525
525
  let _msgId = 0;
526
+ let _pendingMsgs = []; // buffered while session pending
526
527
  const sessions = new Map(); // id → { id, title, type, createdAt }
527
528
 
528
529
  // ── DOM refs ─────────────────────────────────────────────────────────────
@@ -560,18 +561,24 @@ function buildHtml({
560
561
  emptyDesc.textContent = '全局模式:未绑定项目,可直接对话或管理项目。';
561
562
  }
562
563
 
563
- // ── marked.js config ────────────────────────────────────────────────────
564
- if (window.marked) {
565
- marked.setOptions({
566
- highlight: (code, lang) => {
567
- if (window.hljs && lang && hljs.getLanguage(lang)) {
568
- return hljs.highlight(code, { language: lang }).value;
569
- }
570
- return window.hljs ? hljs.highlightAuto(code).value : code;
571
- },
572
- breaks: true,
573
- gfm: true,
574
- });
564
+ // ── marked.js config (deferred — called after defer scripts load) ────────
565
+ function initMarked() {
566
+ if (window.marked) {
567
+ try {
568
+ marked.setOptions({
569
+ highlight: (code, lang) => {
570
+ if (window.hljs && lang && hljs.getLanguage(lang)) {
571
+ return hljs.highlight(code, { language: lang }).value;
572
+ }
573
+ return window.hljs ? hljs.highlightAuto(code).value : code;
574
+ },
575
+ breaks: true,
576
+ gfm: true,
577
+ });
578
+ } catch (_) {
579
+ // marked v10+ removed highlight option — ignore, fallback renderer handles it
580
+ }
581
+ }
575
582
  }
576
583
 
577
584
  // ── WebSocket ────────────────────────────────────────────────────────────
@@ -785,6 +792,11 @@ function buildHtml({
785
792
  }
786
793
  renderSessionList();
787
794
  ws.onmessage = origHandler;
795
+ // Flush buffered messages sent while session was pending
796
+ for (const pending of _pendingMsgs) {
797
+ send({ type: 'session-message', sessionId: realId, content: pending });
798
+ }
799
+ _pendingMsgs = [];
788
800
  return;
789
801
  }
790
802
  // Pass through all other messages
@@ -888,7 +900,7 @@ function buildHtml({
888
900
  el.className = 'message user';
889
901
  el.innerHTML =
890
902
  '<div class="msg-avatar">U</div>' +
891
- '<div class="msg-bubble">' + esc(text).replace(/\n/g, '<br>') + '</div>';
903
+ '<div class="msg-bubble">' + esc(text).split('\\n').join('<br>') + '</div>';
892
904
  messages.appendChild(el);
893
905
  scrollToBottom();
894
906
  }
@@ -978,6 +990,13 @@ function buildHtml({
978
990
  showMessagesArea();
979
991
  showTyping();
980
992
 
993
+ // If session is still pending (not yet confirmed by server), buffer
994
+ if (currentSessionId && currentSessionId.startsWith('pending-')) {
995
+ _pendingMsgs.push(text);
996
+ setTimeout(() => { btnSend.disabled = false; }, 500);
997
+ return;
998
+ }
999
+
981
1000
  send({
982
1001
  type: 'session-message',
983
1002
  sessionId: currentSessionId,
@@ -1077,11 +1096,14 @@ function buildHtml({
1077
1096
  if (window.marked) {
1078
1097
  try { return marked.parse(text); } catch (_) { /* fall through */ }
1079
1098
  }
1080
- return esc(text).replace(/\n/g, '<br>');
1099
+ return esc(text).split('\\n').join('<br>');
1081
1100
  }
1082
1101
 
1083
1102
  // ── Start ────────────────────────────────────────────────────────────────
1103
+ // Connect immediately — do NOT wait for defer scripts (marked/hljs)
1084
1104
  connect();
1105
+ // Init marked after defer scripts finish loading
1106
+ window.addEventListener('load', initMarked);
1085
1107
  })();
1086
1108
  </script>
1087
1109
  </body>
@@ -84,10 +84,15 @@ export class WSSessionManager {
84
84
  const sessionId = this._generateId();
85
85
  const type = options.type || "agent";
86
86
  const projectRoot = options.projectRoot || this.defaultProjectRoot;
87
- const provider = options.provider || "ollama";
87
+ const cfgLlm = this.config?.llm || {};
88
+ const provider = options.provider || cfgLlm.provider || "ollama";
88
89
  const model =
89
- options.model || (provider === "ollama" ? "qwen2.5:7b" : null);
90
- const baseUrl = options.baseUrl || "http://localhost:11434";
90
+ options.model ||
91
+ cfgLlm.model ||
92
+ (provider === "ollama" ? "qwen2.5:7b" : null);
93
+ const baseUrl =
94
+ options.baseUrl || cfgLlm.baseUrl || "http://localhost:11434";
95
+ const apiKey = options.apiKey || cfgLlm.apiKey || null;
91
96
 
92
97
  // Project context (rules.md, persona) is now loaded by buildSystemPrompt()
93
98
 
@@ -144,7 +149,7 @@ export class WSSessionManager {
144
149
  messages,
145
150
  provider,
146
151
  model,
147
- apiKey: options.apiKey || null,
152
+ apiKey,
148
153
  baseUrl,
149
154
  projectRoot,
150
155
  rulesContent: null,