flavor-code 1.2.3 → 1.2.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.
Files changed (36) hide show
  1. package/README.md +208 -931
  2. package/dist/{app-SCHNJSXI.js → app-N3655H2E.js} +6 -7
  3. package/dist/{chunk-MVIMQEQT.js → chunk-HFR2WS6T.js} +0 -1
  4. package/dist/{chunk-DM64TM4Z.js → chunk-KKIBYDJI.js} +0 -1
  5. package/dist/{chunk-AHUOGT4I.js → chunk-L5A2NDMT.js} +1 -2
  6. package/dist/{chunk-XGCFBGBB.js → chunk-MRISY6KK.js} +10 -10
  7. package/dist/{chunk-VOCZVFP7.js → chunk-N2S7USST.js} +0 -1
  8. package/dist/{chunk-XS2JU6S3.js → chunk-NVLYFU6P.js} +3 -4
  9. package/dist/{chunk-JZ322RCJ.js → chunk-S32JRDZK.js} +0 -1
  10. package/dist/{claude-ink-ZL4UZMFY.js → claude-ink-WPWPEL5A.js} +3 -4
  11. package/dist/cli.js +9 -10
  12. package/dist/desktop/main.js +8 -8
  13. package/dist/desktop/preload.cjs +0 -1
  14. package/dist/desktop-renderer/assets/index-C66pDvHs.js +1 -2
  15. package/dist/desktop-renderer/index.html +14 -14
  16. package/dist/{devtools-SXJBSV2N.js → devtools-4QTPKBKK.js} +0 -1
  17. package/dist/{load-WQGNTCHC.js → load-XC5JYYBQ.js} +2 -3
  18. package/dist/sdk/index.js +5 -6
  19. package/package.json +6 -1
  20. package//346/212/200/346/234/257/346/226/271/346/241/210/346/212/245/345/221/212.md +1 -1
  21. package/dist/app-SCHNJSXI.js.map +0 -1
  22. package/dist/chunk-AHUOGT4I.js.map +0 -1
  23. package/dist/chunk-DM64TM4Z.js.map +0 -1
  24. package/dist/chunk-JZ322RCJ.js.map +0 -1
  25. package/dist/chunk-MVIMQEQT.js.map +0 -1
  26. package/dist/chunk-VOCZVFP7.js.map +0 -1
  27. package/dist/chunk-XGCFBGBB.js.map +0 -1
  28. package/dist/chunk-XS2JU6S3.js.map +0 -1
  29. package/dist/claude-ink-ZL4UZMFY.js.map +0 -1
  30. package/dist/cli.js.map +0 -1
  31. package/dist/desktop/main.js.map +0 -1
  32. package/dist/desktop/preload.cjs.map +0 -1
  33. package/dist/desktop-renderer/assets/index-C66pDvHs.js.map +0 -1
  34. package/dist/devtools-SXJBSV2N.js.map +0 -1
  35. package/dist/load-WQGNTCHC.js.map +0 -1
  36. package/dist/sdk/index.js.map +0 -1
@@ -2,7 +2,7 @@
2
2
  import { createRequire } from "node:module"; const require = createRequire(import.meta.url);
3
3
  import {
4
4
  statusPresentation
5
- } from "./chunk-DM64TM4Z.js";
5
+ } from "./chunk-KKIBYDJI.js";
6
6
  import {
7
7
  COMMAND_DESCRIPTIONS,
8
8
  MVP_COMMANDS,
@@ -14,8 +14,8 @@ import {
14
14
  modelContentTranscriptText,
15
15
  redactErrorText,
16
16
  transcriptReducer
17
- } from "./chunk-XGCFBGBB.js";
18
- import "./chunk-MVIMQEQT.js";
17
+ } from "./chunk-MRISY6KK.js";
18
+ import "./chunk-HFR2WS6T.js";
19
19
  import {
20
20
  Box_default,
21
21
  ClockContext,
@@ -32,11 +32,11 @@ import {
32
32
  useStdout,
33
33
  use_app_default,
34
34
  use_input_default
35
- } from "./chunk-XS2JU6S3.js";
35
+ } from "./chunk-NVLYFU6P.js";
36
36
  import {
37
37
  execFileNoThrow
38
- } from "./chunk-VOCZVFP7.js";
39
- import "./chunk-JZ322RCJ.js";
38
+ } from "./chunk-N2S7USST.js";
39
+ import "./chunk-S32JRDZK.js";
40
40
 
41
41
  // src/ui/app.tsx
42
42
  import { basename as basename3 } from "path";
@@ -3182,4 +3182,3 @@ export {
3182
3182
  submitSafely,
3183
3183
  taskPanelViewportRows
3184
3184
  };
3185
- //# sourceMappingURL=app-SCHNJSXI.js.map
@@ -689,4 +689,3 @@ export {
689
689
  setProjectProviderConfig,
690
690
  redactConfig
691
691
  };
692
- //# sourceMappingURL=chunk-MVIMQEQT.js.map
@@ -121,4 +121,3 @@ export {
121
121
  staticTaskLines,
122
122
  statusPresentation
123
123
  };
124
- //# sourceMappingURL=chunk-DM64TM4Z.js.map
@@ -4,7 +4,7 @@ import {
4
4
  message,
5
5
  redactErrorText,
6
6
  redactSecrets
7
- } from "./chunk-XGCFBGBB.js";
7
+ } from "./chunk-MRISY6KK.js";
8
8
 
9
9
  // src/rpc/server.ts
10
10
  import { createInterface } from "readline";
@@ -243,4 +243,3 @@ export {
243
243
  TraceRecordSchema,
244
244
  TraceRecorder
245
245
  };
246
- //# sourceMappingURL=chunk-AHUOGT4I.js.map
@@ -12,7 +12,7 @@ import {
12
12
  redactConfig,
13
13
  setProjectMcpServerDisabled,
14
14
  updateProtectedFile
15
- } from "./chunk-MVIMQEQT.js";
15
+ } from "./chunk-HFR2WS6T.js";
16
16
  import {
17
17
  AuditLogger,
18
18
  appendUsageLog,
@@ -23,7 +23,7 @@ import {
23
23
  resolveLanguage,
24
24
  setUsageSession,
25
25
  usageLogPath
26
- } from "./chunk-VOCZVFP7.js";
26
+ } from "./chunk-N2S7USST.js";
27
27
 
28
28
  // src/models/types.ts
29
29
  function modelContentText(content) {
@@ -10664,19 +10664,20 @@ function createReadTool(workspace, options = {}) {
10664
10664
  if (startLine !== void 0 && endLine !== void 0 && endLine < startLine) {
10665
10665
  throw new Error(`endLine (${endLine}) must not be below startLine (${startLine})`);
10666
10666
  }
10667
- const contents = await readBounded2(path, maxBytes, signal, openFile2);
10667
+ const rangeRequested = startLine !== void 0 || endLine !== void 0;
10668
+ const windowBytes = rangeRequested ? Math.max(maxBytes, Math.min(info.size, MAX_READ_BYTES)) : maxBytes;
10669
+ const contents = await readBounded2(path, windowBytes, signal, openFile2);
10668
10670
  if (isBinary(contents)) throw new Error("Cannot read binary file as text");
10669
- const textEnd = utf8SafeEnd(contents, maxBytes);
10670
- const truncated = contents.length > maxBytes;
10671
+ const textEnd = utf8SafeEnd(contents, windowBytes);
10672
+ const truncated = contents.length > windowBytes;
10671
10673
  const text = contents.subarray(0, textEnd).toString("utf8").replaceAll("\r\n", "\n");
10672
10674
  const lines = text.split("\n");
10673
10675
  if (lines.at(-1) === "") lines.pop();
10674
10676
  const availableLines = lines.length;
10675
- const rangeRequested = startLine !== void 0 || endLine !== void 0;
10676
10677
  const start = startLine ?? 1;
10677
10678
  const end = Math.min(endLine ?? availableLines, availableLines);
10678
10679
  if (rangeRequested && start > availableLines) {
10679
- throw new Error(`startLine (${start}) is beyond the ${availableLines} line${availableLines === 1 ? "" : "s"} available${truncated ? ` in this read (truncated at ${maxBytes} bytes)` : " in this file"}`);
10680
+ throw new Error(`startLine (${start}) is beyond the ${availableLines} line${availableLines === 1 ? "" : "s"} available${truncated ? ` in this read (truncated at ${windowBytes} bytes)` : " in this file"}`);
10680
10681
  }
10681
10682
  if (rangeRequested && end < start) {
10682
10683
  throw new Error(`endLine (${endLine}) must not be below startLine (${start})`);
@@ -10692,13 +10693,13 @@ function createReadTool(workspace, options = {}) {
10692
10693
  record.ranges = mergeRange(record.ranges, start, end);
10693
10694
  }
10694
10695
  if (rangeRequested) {
10695
- const header = `[Lines ${start}-${end} of ${availableLines}${truncated ? ` visible in this read (truncated at ${maxBytes} bytes)` : ""}]`;
10696
+ const header = `[Lines ${start}-${end} of ${availableLines}${truncated ? ` visible in this read (truncated at ${windowBytes} bytes)` : ""}]`;
10696
10697
  return `${header}
10697
10698
 
10698
10699
  ${lines.slice(start - 1, end).join("\n")}`;
10699
10700
  }
10700
10701
  if (truncated) {
10701
- return `[Truncated to ${maxBytes} bytes. File is ${info.size} bytes total. Request a higher maxBytes or read a specific range with startLine/endLine.]
10702
+ return `[Truncated to ${windowBytes} bytes. File is ${info.size} bytes total. Request a higher maxBytes or read a specific range with startLine/endLine.]
10702
10703
 
10703
10704
  ${text}`;
10704
10705
  }
@@ -15783,4 +15784,3 @@ export {
15783
15784
  createExecutionEnvironment,
15784
15785
  createProductionRuntime
15785
15786
  };
15786
- //# sourceMappingURL=chunk-XGCFBGBB.js.map
@@ -150,4 +150,3 @@ export {
150
150
  resolveLanguage,
151
151
  languageInstruction
152
152
  };
153
- //# sourceMappingURL=chunk-VOCZVFP7.js.map
@@ -5,12 +5,12 @@ import {
5
5
  getGraphemeSegmenter,
6
6
  isEnvTruthy,
7
7
  logError
8
- } from "./chunk-VOCZVFP7.js";
8
+ } from "./chunk-N2S7USST.js";
9
9
  import {
10
10
  __commonJS,
11
11
  __require,
12
12
  __toESM
13
- } from "./chunk-JZ322RCJ.js";
13
+ } from "./chunk-S32JRDZK.js";
14
14
 
15
15
  // node_modules/scheduler/cjs/scheduler.production.js
16
16
  var require_scheduler_production = __commonJS({
@@ -28001,7 +28001,7 @@ var styles_default = styles2;
28001
28001
  // src/claude-ink/reconciler.ts
28002
28002
  if (process.env.NODE_ENV === "development") {
28003
28003
  try {
28004
- void import("./devtools-SXJBSV2N.js");
28004
+ void import("./devtools-4QTPKBKK.js");
28005
28005
  } catch (error) {
28006
28006
  if (error.code === "ERR_MODULE_NOT_FOUND") {
28007
28007
  console.warn(
@@ -35554,4 +35554,3 @@ react-reconciler/cjs/react-reconciler-constants.development.js:
35554
35554
  * LICENSE file in the root directory of this source tree.
35555
35555
  *)
35556
35556
  */
35557
- //# sourceMappingURL=chunk-XS2JU6S3.js.map
@@ -37,4 +37,3 @@ export {
37
37
  __commonJS,
38
38
  __toESM
39
39
  };
40
- //# sourceMappingURL=chunk-JZ322RCJ.js.map
@@ -10,9 +10,9 @@ import {
10
10
  useStdout,
11
11
  use_app_default,
12
12
  use_input_default
13
- } from "./chunk-XS2JU6S3.js";
14
- import "./chunk-VOCZVFP7.js";
15
- import "./chunk-JZ322RCJ.js";
13
+ } from "./chunk-NVLYFU6P.js";
14
+ import "./chunk-N2S7USST.js";
15
+ import "./chunk-S32JRDZK.js";
16
16
  export {
17
17
  AlternateScreen,
18
18
  Box_default as Box,
@@ -24,4 +24,3 @@ export {
24
24
  use_input_default as useInput,
25
25
  useStdout
26
26
  };
27
- //# sourceMappingURL=claude-ink-ZL4UZMFY.js.map
package/dist/cli.js CHANGED
@@ -3,10 +3,10 @@ import { createRequire } from "node:module"; const require = createRequire(impor
3
3
  import {
4
4
  FlavorRpcServer,
5
5
  TraceRecorder
6
- } from "./chunk-AHUOGT4I.js";
6
+ } from "./chunk-L5A2NDMT.js";
7
7
  import {
8
8
  staticTaskLines
9
- } from "./chunk-DM64TM4Z.js";
9
+ } from "./chunk-KKIBYDJI.js";
10
10
  import {
11
11
  DEFAULT_MAX_OUTPUT_BYTES,
12
12
  MEMORY_TYPES,
@@ -20,7 +20,7 @@ import {
20
20
  message,
21
21
  packageVersion,
22
22
  redactErrorText
23
- } from "./chunk-XGCFBGBB.js";
23
+ } from "./chunk-MRISY6KK.js";
24
24
  import {
25
25
  McpServerConfigSchema,
26
26
  McpServerNameSchema,
@@ -29,9 +29,9 @@ import {
29
29
  readRecoverableFile,
30
30
  setProjectSkillDisabled,
31
31
  updateProtectedFile
32
- } from "./chunk-MVIMQEQT.js";
33
- import "./chunk-VOCZVFP7.js";
34
- import "./chunk-JZ322RCJ.js";
32
+ } from "./chunk-HFR2WS6T.js";
33
+ import "./chunk-N2S7USST.js";
34
+ import "./chunk-S32JRDZK.js";
35
35
 
36
36
  // src/cli.tsx
37
37
  import { realpathSync } from "fs";
@@ -669,7 +669,7 @@ async function runEvaluationFile(path, outputPath) {
669
669
  })),
670
670
  ...parsed.maxTokens === void 0 ? {} : { maxTokens: parsed.maxTokens }
671
671
  };
672
- const configured = await import("./load-WQGNTCHC.js").then(({ loadConfig: loadConfig2 }) => loadConfig2({ cwd: workspace, home: process.env.USERPROFILE ?? process.env.HOME ?? workspace }));
672
+ const configured = await import("./load-XC5JYYBQ.js").then(({ loadConfig: loadConfig2 }) => loadConfig2({ cwd: workspace, home: process.env.USERPROFILE ?? process.env.HOME ?? workspace }));
673
673
  const environment = createExecutionEnvironment(workspace, configured.config.execution) ?? new LocalExecutionEnvironment();
674
674
  let report;
675
675
  try {
@@ -769,9 +769,9 @@ function createProgram() {
769
769
  }
770
770
  setInteractiveProcessTitle();
771
771
  const [{ render, AlternateScreen }, { createElement }, { App }] = await Promise.all([
772
- import("./claude-ink-ZL4UZMFY.js"),
772
+ import("./claude-ink-WPWPEL5A.js"),
773
773
  import("react"),
774
- import("./app-SCHNJSXI.js")
774
+ import("./app-N3655H2E.js")
775
775
  ]);
776
776
  const instance = await render(createElement(
777
777
  AlternateScreen,
@@ -912,4 +912,3 @@ export {
912
912
  runRpcMode,
913
913
  setInteractiveProcessTitle
914
914
  };
915
- //# sourceMappingURL=cli.js.map
@@ -10430,19 +10430,20 @@ function createReadTool(workspace, options = {}) {
10430
10430
  if (startLine !== void 0 && endLine !== void 0 && endLine < startLine) {
10431
10431
  throw new Error(`endLine (${endLine}) must not be below startLine (${startLine})`);
10432
10432
  }
10433
- const contents = await readBounded2(path, maxBytes, signal, openFile2);
10433
+ const rangeRequested = startLine !== void 0 || endLine !== void 0;
10434
+ const windowBytes = rangeRequested ? Math.max(maxBytes, Math.min(info.size, MAX_READ_BYTES)) : maxBytes;
10435
+ const contents = await readBounded2(path, windowBytes, signal, openFile2);
10434
10436
  if (isBinary(contents)) throw new Error("Cannot read binary file as text");
10435
- const textEnd = utf8SafeEnd(contents, maxBytes);
10436
- const truncated = contents.length > maxBytes;
10437
+ const textEnd = utf8SafeEnd(contents, windowBytes);
10438
+ const truncated = contents.length > windowBytes;
10437
10439
  const text = contents.subarray(0, textEnd).toString("utf8").replaceAll("\r\n", "\n");
10438
10440
  const lines = text.split("\n");
10439
10441
  if (lines.at(-1) === "") lines.pop();
10440
10442
  const availableLines = lines.length;
10441
- const rangeRequested = startLine !== void 0 || endLine !== void 0;
10442
10443
  const start = startLine ?? 1;
10443
10444
  const end = Math.min(endLine ?? availableLines, availableLines);
10444
10445
  if (rangeRequested && start > availableLines) {
10445
- throw new Error(`startLine (${start}) is beyond the ${availableLines} line${availableLines === 1 ? "" : "s"} available${truncated ? ` in this read (truncated at ${maxBytes} bytes)` : " in this file"}`);
10446
+ throw new Error(`startLine (${start}) is beyond the ${availableLines} line${availableLines === 1 ? "" : "s"} available${truncated ? ` in this read (truncated at ${windowBytes} bytes)` : " in this file"}`);
10446
10447
  }
10447
10448
  if (rangeRequested && end < start) {
10448
10449
  throw new Error(`endLine (${endLine}) must not be below startLine (${start})`);
@@ -10458,13 +10459,13 @@ function createReadTool(workspace, options = {}) {
10458
10459
  record.ranges = mergeRange(record.ranges, start, end);
10459
10460
  }
10460
10461
  if (rangeRequested) {
10461
- const header = `[Lines ${start}-${end} of ${availableLines}${truncated ? ` visible in this read (truncated at ${maxBytes} bytes)` : ""}]`;
10462
+ const header = `[Lines ${start}-${end} of ${availableLines}${truncated ? ` visible in this read (truncated at ${windowBytes} bytes)` : ""}]`;
10462
10463
  return `${header}
10463
10464
 
10464
10465
  ${lines.slice(start - 1, end).join("\n")}`;
10465
10466
  }
10466
10467
  if (truncated) {
10467
- return `[Truncated to ${maxBytes} bytes. File is ${info.size} bytes total. Request a higher maxBytes or read a specific range with startLine/endLine.]
10468
+ return `[Truncated to ${windowBytes} bytes. File is ${info.size} bytes total. Request a higher maxBytes or read a specific range with startLine/endLine.]
10468
10469
 
10469
10470
  ${text}`;
10470
10471
  }
@@ -17790,4 +17791,3 @@ app.on("before-quit", () => {
17790
17791
  app.on("window-all-closed", () => {
17791
17792
  if (process.platform !== "darwin") app.quit();
17792
17793
  });
17793
- //# sourceMappingURL=main.js.map
@@ -87,4 +87,3 @@ var api = {
87
87
  }
88
88
  };
89
89
  import_electron.contextBridge.exposeInMainWorld("flavorDesktop", api);
90
- //# sourceMappingURL=preload.cjs.map
@@ -140,5 +140,4 @@ Describe when and how the agent should use this skill.`,disableModelInvocation:!
140
140
  `)}function _l(e){return`command`in e?[e.command,...e.args].join(` `):``}function vl(e){return`url`in e?e.url:``}function yl(e){return e instanceof Error?e.message:String(e)}var bl={sessions:[],diagnostics:[],models:[]},xl=[`default`,`acceptEdits`,`plan`,`bypassPermissions`,`auto`,`bubble`],Sl=nl.map(e=>({name:e,description:rl[e]})),Cl=5,wl=5*1024*1024,Tl=20*1024*1024,El=new Set([`image/png`,`image/jpeg`,`image/webp`]);function Dl(e,t){return[e.trim(),...t.map((e,t)=>`[Image #${t+1}]`)].filter(Boolean).join(`
141
141
  `)}function Ol({attachments:e,onRemove:t}){return(0,N.jsx)(`div`,{className:`image-attachment-strip`,"aria-label":`待发送图片`,children:e.map((e,n)=>(0,N.jsxs)(`figure`,{className:`image-attachment-chip`,children:[(0,N.jsx)(`img`,{src:e.previewUrl,alt:e.name}),(0,N.jsxs)(`figcaption`,{children:[(0,N.jsxs)(`strong`,{children:[`[Image #`,n+1,`]`]}),(0,N.jsx)(`span`,{children:e.name})]}),(0,N.jsx)(`button`,{type:`button`,onClick:()=>t(e.id),"aria-label":`移除 ${e.name}`,title:`移除图片`,children:`×`})]},e.id))})}function kl(){let[e,t]=(0,_.useState)(bl),[n,r]=(0,_.useState)(x),[i,a]=(0,_.useState)(``),[o,s]=(0,_.useState)([]),[c,l]=(0,_.useState)(!0),[u,d]=(0,_.useState)(),[f,p]=(0,_.useState)(!1),[m,h]=(0,_.useState)(!1),[g,v]=(0,_.useState)(),[y,b]=(0,_.useState)(),[C,w]=(0,_.useState)(!1),[ee,T]=(0,_.useState)(0),[te,E]=(0,_.useState)(),[ne,re]=(0,_.useState)([]),[ie,ae]=(0,_.useState)([]),[oe,se]=(0,_.useState)(0),[ce,D]=(0,_.useState)(),[O,le]=(0,_.useState)(),[ue,de]=(0,_.useState)(0),[k,A]=(0,_.useState)(`conversation`),he=(0,_.useRef)(null),ge=(0,_.useRef)(null),_e=(0,_.useRef)(void 0),ve=(0,_.useRef)(new Set),ye=(0,_.useRef)(!1),be=(0,_.useCallback)(e=>{a(e),E(void 0),D(void 0)},[]);(0,_.useEffect)(()=>()=>{for(let e of ve.current)URL.revokeObjectURL(e);ve.current.clear()},[]);let j=(0,_.useCallback)(e=>{s(t=>{let n=t.find(t=>t.id===e);return n!==void 0&&(URL.revokeObjectURL(n.previewUrl),ve.current.delete(n.previewUrl)),t.filter(t=>t.id!==e)})},[]),xe=(0,_.useCallback)(()=>{s(e=>{for(let t of e)URL.revokeObjectURL(t.previewUrl),ve.current.delete(t.previewUrl);return[]})},[]),Se=(0,_.useCallback)(async e=>{if(e.length===0)return;let t=Cl-o.length;if(t<=0||e.length>t){d(`每条消息最多添加 ${Cl} 张图片。`);return}if(o.reduce((e,t)=>e+Math.floor(t.dataBase64.length*3/4),0)+e.reduce((e,t)=>e+t.size,0)>Tl){d(`单条消息的图片总大小不能超过 20 MiB。`);return}try{let t=await Promise.all(e.map(q));for(let e of t)ve.current.add(e.previewUrl);s(e=>[...e,...t].slice(0,Cl)),d(void 0)}catch(e){d(Xl(e))}},[o]);(0,_.useEffect)(()=>{let e=he.current;if(!e)return;let t=e=>{e.deltaY<0?ye.current=!0:requestAnimationFrame(()=>{let e=he.current;e&&e.scrollHeight-e.scrollTop-e.clientHeight<8&&(ye.current=!1)})};return e.addEventListener(`wheel`,t,{passive:!0}),()=>e.removeEventListener(`wheel`,t)},[]),(0,_.useEffect)(()=>{let e=window.flavorDesktop.onEvent(e=>{jl(e,_e,t,r,d)});return window.flavorDesktop.bootstrap().then(e=>{_e.current=e.activeSession?.sessionId,t(e)}).catch(e=>d(Xl(e))).finally(()=>l(!1)),e},[]),(0,_.useEffect)(()=>{ye.current||he.current?.scrollTo({top:he.current.scrollHeight,behavior:`smooth`})},[n]),(0,_.useEffect)(()=>{let e=!1;return window.flavorDesktop.listFiles().then(t=>{e||ae(ln(t))}).catch(()=>{}),()=>{e=!0}},[e.workspace]),(0,_.useEffect)(()=>{let t=!1;return e.workspace===void 0?(re([]),()=>{t=!0}):(window.flavorDesktop.listSkills().then(e=>{t||re(e)}).catch(()=>{t||re([])}),()=>{t=!0})},[e.workspace,k]);let Ce=e.activeSession?.busy??!1,we=(0,_.useMemo)(()=>fe(e.sessions),[e.sessions]),Te=(0,_.useMemo)(()=>Jt(Sl,[],ne.filter(e=>e.enabled)),[ne]),Ee=(0,_.useMemo)(()=>Ce||e.approval!==void 0||e.questions!==void 0||te===i?null:Xt(i,ue,Te,ee),[i,ue,ee,te,Ce,e.approval,e.questions,Te]),De=(0,_.useMemo)(()=>Ce||e.approval!==void 0||e.questions!==void 0||ce===i||Ee!==null?null:un(i,ue,ie,oe),[i,ue,oe,ce,Ce,e.approval,e.questions,ie,Ee]),Oe=Ee===null?Yt(i,Te,!1):0,ke=(0,_.useCallback)(e=>{let t=Qt(i,ue,e);a(t.text),E(t.text),T(0),de(t.cursor),setTimeout(()=>{let e=ge.current;e!==null&&(e.focus(),e.setSelectionRange(e.value.length,e.value.length))},0)},[i,ue]),Ae=(0,_.useCallback)(()=>{E(i)},[i]),je=(0,_.useCallback)(e=>{T(t=>Zt(t,e,Ee?.items.length??0))},[Ee]),Me=(0,_.useCallback)(e=>{let t=fn(i,ue,e);a(t.text),D(t.text),se(0),le(t.span),de(t.cursor),setTimeout(()=>{let e=ge.current;e!==null&&(e.focus(),e.setSelectionRange(e.value.length,e.value.length))},0)},[i,ue]),Ne=(0,_.useCallback)(()=>{D(i)},[i]),Pe=(0,_.useCallback)(e=>{se(t=>dn(t,e,De?.items.length??0))},[De]),Fe=async()=>{d(void 0);try{let e=await window.flavorDesktop.chooseWorkspace();e!==void 0&&(xe(),t(e),r(x()),p(!1),A(`conversation`))}catch(e){d(Xl(e))}},Ie=async e=>{d(void 0);try{let n=await window.flavorDesktop.startSession(e?.sessionId);xe(),t(n.snapshot),r(S(x(),{type:`restore`,state:n.restoredTranscript})),p(!1),A(`conversation`),setTimeout(()=>ge.current?.focus(),0)}catch(e){d(Xl(e))}},Le=async(n,s)=>{let c=(n??i).trim(),l=n===void 0?o:[];if(!(!c&&l.length===0)){d(void 0);try{let i=e;if(i.activeSession===void 0){let e=await window.flavorDesktop.startSession();i=e.snapshot,t(i),r(S(x(),{type:`restore`,state:e.restoredTranscript}))}let o=s??(Ce?`steer`:`prompt`);if(l.length>0&&o!==`prompt`)throw Error(`图片只能随新消息发送,不能作为运行中的引导或后续消息。`);o===`prompt`&&r(e=>S(e,{type:`submit`,prompt:Dl(c,l)})),n===void 0&&a(``),await window.flavorDesktop.submit(c,o,l.map(({name:e,mediaType:t,dataBase64:n})=>({name:e,mediaType:t,dataBase64:n}))),l.length>0&&xe()}catch(e){let t=Xl(e);d(t),r(e=>S(e,{type:`submit-error`,message:t}))}}},Re=e=>void Le(`/permissions ${e}`),ze=async e=>{d(void 0);try{t(await window.flavorDesktop.switchModel(e))}catch(e){d(Xl(e))}},Be=async()=>{if(!(Ce||e.activeSession===void 0)){d(void 0);try{await window.flavorDesktop.finishTask()}catch(e){d(Xl(e))}}},Ve=async e=>{d(void 0);try{let n=await window.flavorDesktop.addModel(e);t(n.snapshot)}catch(e){throw d(Xl(e)),e}},He=(e,t)=>{let n=t.currentTarget.getBoundingClientRect();window.flavorDesktop.showAppMenu(e,Math.round(n.left),Math.round(n.bottom))},Ue=async()=>{if(!(y===void 0||C)){w(!0),d(void 0);try{let n=y.sessionId===e.activeSession?.sessionId,i=await window.flavorDesktop.deleteSession(y.sessionId);t(i),n&&r(x()),b(void 0),v(void 0)}catch(e){d(Xl(e))}finally{w(!1)}}};return(0,N.jsxs)(`div`,{className:`app-frame`,children:[(0,N.jsx)(Al,{railCollapsed:m,onToggleRail:()=>h(e=>!e),onMenu:He}),(0,N.jsxs)(`div`,{className:`desktop-shell`,"data-rail-collapsed":m,children:[(0,N.jsx)(`button`,{className:`rail-scrim`,"data-open":f,onClick:()=>p(!1),"aria-label":`关闭项目栏`}),(0,N.jsxs)(`aside`,{className:`project-rail`,"data-open":f,children:[(0,N.jsxs)(`div`,{className:`brand-row`,children:[(0,N.jsx)(Yl,{}),(0,N.jsx)(`strong`,{children:`Flavor Code`}),(0,N.jsx)(`span`,{className:`brand-chevron`,children:`⌄`})]}),(0,N.jsxs)(`nav`,{className:`primary-actions`,"aria-label":`主要操作`,children:[(0,N.jsxs)(`button`,{className:`rail-action rail-action-primary`,disabled:e.workspace===void 0,onClick:()=>void Ie(),children:[(0,N.jsx)(`span`,{className:`action-icon`,children:`+`}),(0,N.jsx)(`span`,{children:`新建任务`}),(0,N.jsx)(`kbd`,{children:`Ctrl N`})]}),(0,N.jsxs)(`button`,{className:`rail-action`,onClick:()=>void Fe(),children:[(0,N.jsx)(`span`,{className:`action-icon`,children:`⌂`}),(0,N.jsx)(`span`,{children:`打开项目`})]}),(0,N.jsxs)(`button`,{className:`rail-action`,"data-active":k===`skills`,onClick:()=>{A(`skills`),p(!1)},disabled:e.workspace===void 0,children:[(0,N.jsx)(`span`,{className:`action-icon`,children:`◇`}),(0,N.jsx)(`span`,{children:`技能`})]}),(0,N.jsxs)(`button`,{className:`rail-action`,"data-active":k===`memory`,onClick:()=>{A(`memory`),p(!1)},disabled:e.workspace===void 0,children:[(0,N.jsx)(`span`,{className:`action-icon`,children:`⌁`}),(0,N.jsx)(`span`,{children:`长期记忆`})]}),(0,N.jsxs)(`button`,{className:`rail-action`,"data-active":k===`mcp`,onClick:()=>{A(`mcp`),p(!1)},disabled:e.workspace===void 0,children:[(0,N.jsx)(`span`,{className:`action-icon`,children:`◎`}),(0,N.jsx)(`span`,{children:`MCP 服务`})]})]}),(0,N.jsxs)(`div`,{className:`sessions-scroll`,children:[(0,N.jsx)(`div`,{className:`rail-section-title`,children:`项目`}),e.workspace===void 0?(0,N.jsx)(`button`,{className:`empty-project`,onClick:()=>void Fe(),children:`选择一个本地文件夹开始`}):(0,N.jsxs)(N.Fragment,{children:[(0,N.jsxs)(`div`,{className:`project-heading`,children:[(0,N.jsx)(`span`,{className:`folder-icon`,children:`▱`}),(0,N.jsx)(`span`,{children:me(e.workspace)})]}),we.length===0&&(0,N.jsx)(`p`,{className:`no-sessions`,children:`还没有任务`}),we.map(t=>(0,N.jsxs)(`section`,{className:`session-group`,children:[(0,N.jsx)(`h2`,{children:t.label}),t.sessions.map(t=>(0,N.jsxs)(`div`,{className:`session-item-shell`,onBlur:e=>{e.currentTarget.contains(e.relatedTarget)||v(void 0)},children:[(0,N.jsxs)(`button`,{className:`session-item`,"data-active":t.sessionId===e.activeSession?.sessionId,onClick:()=>void Ie(t),children:[(0,N.jsx)(`span`,{children:pe(t)}),(0,N.jsx)(`time`,{children:$l(t.updatedAt)})]}),(0,N.jsx)(`button`,{className:`session-more`,"aria-label":`管理会话:${pe(t)}`,"aria-expanded":g===t.sessionId,onClick:()=>v(e=>e===t.sessionId?void 0:t.sessionId),children:`•••`}),g===t.sessionId&&(0,N.jsx)(`div`,{className:`session-menu`,role:`menu`,children:(0,N.jsx)(`button`,{role:`menuitem`,className:`danger-item`,disabled:Ce&&t.sessionId===e.activeSession?.sessionId,onClick:()=>{b(t),v(void 0)},children:`删除会话`})})]},t.sessionId))]},t.label))]})]}),(0,N.jsxs)(`div`,{className:`rail-footer`,children:[(0,N.jsx)(`span`,{className:`avatar`,children:`F`}),(0,N.jsx)(`span`,{children:`本地工作区`}),(0,N.jsx)(`button`,{title:`帮助`,children:`?`})]})]}),(0,N.jsxs)(`main`,{className:`workspace-panel`,children:[k===`skills`&&e.workspace!==void 0?(0,N.jsx)(al,{onClose:()=>A(`conversation`),onError:d}):k===`memory`&&e.workspace!==void 0?(0,N.jsx)(ll,{onClose:()=>A(`conversation`),onError:d}):k===`mcp`&&e.workspace!==void 0?(0,N.jsx)(dl,{onClose:()=>A(`conversation`),onError:d}):(0,N.jsxs)(N.Fragment,{children:[(0,N.jsxs)(`header`,{className:`workspace-header`,children:[(0,N.jsx)(`button`,{className:`mobile-rail-toggle`,onClick:()=>p(!0),"aria-label":`打开项目栏`,children:`☰`}),(0,N.jsx)(`div`,{className:`workspace-breadcrumb`,children:(0,N.jsx)(`span`,{children:me(e.workspace)})}),(0,N.jsxs)(`div`,{className:`header-actions`,children:[(0,N.jsx)(`button`,{className:`finish-task-button`,onClick:()=>void Be(),disabled:Ce||e.activeSession===void 0,title:`评估并完成当前任务`,children:`完成任务`}),(0,N.jsx)(`button`,{title:`更多选项`,children:`•••`})]})]}),(0,N.jsx)(`div`,{className:`conversation-scroll`,ref:he,children:c?(0,N.jsx)(Gl,{}):e.workspace===void 0?(0,N.jsx)(Wl,{onOpen:Fe}):n.completed.length===0&&n.active===void 0?(0,N.jsx)(Ul,{project:me(e.workspace),onStart:e=>void Le(e)}):(0,N.jsxs)(`div`,{className:`conversation-column`,children:[n.completed.map(e=>(0,N.jsx)(Ml,{turn:e},e.id)),n.active!==void 0&&(0,N.jsx)(Ml,{turn:n.active,active:!0})]})}),e.diagnostics.length>0&&(0,N.jsxs)(`details`,{className:`diagnostics`,children:[(0,N.jsxs)(`summary`,{children:[e.diagnostics.length,` 条启动提示`]}),(0,N.jsx)(`pre`,{children:e.diagnostics.join(`
142
142
  `)})]}),(0,N.jsx)(Ll,{input:i,setInput:be,onSend:e=>void Le(void 0,e),busy:Ce,onInterrupt:()=>void window.flavorDesktop.interrupt(),inputRef:ge,snapshot:e,attachments:o,onAddImages:e=>void Se(e),onRemoveImage:j,setModel:ze,addModel:Ve,setPermission:Re,slashCompletion:Ee,onSlashSelect:ke,onSlashDismiss:Ae,onSlashMove:je,mentionCompletion:De,onMentionSelect:Me,onMentionDismiss:Ne,onMentionMove:Pe,mentionSpan:O,setMentionSpan:le,completedTokenLen:Oe,cursorPos:ue,setCursorPos:de})]}),u!==void 0&&(0,N.jsxs)(`div`,{className:`error-toast`,role:`alert`,children:[(0,N.jsx)(`span`,{children:`!`}),(0,N.jsx)(`p`,{children:u}),(0,N.jsx)(`button`,{onClick:()=>d(void 0),children:`×`})]})]})]}),e.approval!==void 0&&(0,N.jsx)(zl,{approval:e.approval,onResolve:e=>void window.flavorDesktop.resolveApproval(e)}),e.questions!==void 0&&(0,N.jsx)(Bl,{questions:e.questions,onAnswer:e=>void window.flavorDesktop.answerQuestions(e)}),e.memoryReviews!==void 0&&e.memoryReviews.length>0&&(0,N.jsx)(Vl,{reviews:e.memoryReviews,autoDismissSeconds:e.memoryAutoDismissSeconds??0,onResolve:(e,t)=>{window.flavorDesktop.resolveMemoryReview(e,t).catch(e=>d(Xl(e)))}}),y!==void 0&&(0,N.jsx)(Y,{session:y,deleting:C,onCancel:()=>b(void 0),onDelete:()=>void Ue()})]})}function Al({railCollapsed:e,onToggleRail:t,onMenu:n}){return(0,N.jsxs)(`header`,{className:`window-titlebar`,children:[(0,N.jsx)(`button`,{className:`titlebar-icon sidebar-toggle`,"data-collapsed":e,onClick:t,"aria-label":e?`显示项目栏`:`隐藏项目栏`,title:e?`显示项目栏`:`隐藏项目栏`,children:(0,N.jsxs)(`svg`,{viewBox:`0 0 16 16`,"aria-hidden":`true`,children:[(0,N.jsx)(`rect`,{x:`2.5`,y:`2.5`,width:`11`,height:`11`,rx:`2`}),(0,N.jsx)(`path`,{d:`M6 3v10`})]})}),(0,N.jsx)(`button`,{className:`titlebar-icon nav-button`,disabled:!0,"aria-label":`后退`,children:(0,N.jsx)(`span`,{children:`‹`})}),(0,N.jsx)(`button`,{className:`titlebar-icon nav-button`,disabled:!0,"aria-label":`前进`,children:(0,N.jsx)(`span`,{children:`›`})}),(0,N.jsxs)(`nav`,{className:`titlebar-menus`,"aria-label":`应用菜单`,children:[(0,N.jsx)(`button`,{onClick:e=>n(`file`,e),children:`文件`}),(0,N.jsx)(`button`,{onClick:e=>n(`edit`,e),children:`编辑`}),(0,N.jsx)(`button`,{onClick:e=>n(`view`,e),children:`视图`}),(0,N.jsx)(`button`,{onClick:e=>n(`help`,e),children:`帮助`})]})]})}function jl(e,t,n,r,i){e.type===`snapshot`?(t.current=e.snapshot.activeSession?.sessionId,n(e.snapshot)):e.type===`session-started`?(t.current=e.payload.sessionId,n(e.payload.snapshot),r(S(x(),{type:`restore`,state:e.payload.restoredTranscript}))):e.type===`session-output`?r(n=>ge(n,t.current,e)):e.type===`runtime-error`&&(e.sessionId===void 0||e.sessionId===t.current)&&i(e.message)}function Ml({turn:e,active:t=!1}){let n=t?e.blocks:e.blocks.filter(e=>e.kind!==`status`||e.task===void 0);return(0,N.jsxs)(`article`,{className:`turn`,"data-active":t,"data-kind":e.kind??`conversation`,children:[(0,N.jsx)(`div`,{className:`user-message`,children:(0,N.jsx)(`span`,{children:e.prompt})}),(0,N.jsxs)(`div`,{className:`assistant-message`,children:[(0,N.jsx)(`div`,{className:`assistant-avatar`,children:(0,N.jsx)(Yl,{})}),(0,N.jsxs)(`div`,{className:`turn-content`,children:[n.map((e,t)=>(0,N.jsx)(Nl,{block:e},e.kind===`status`?e.id:`text-${t}`)),t&&n.length===0&&(0,N.jsxs)(`div`,{className:`thinking-line`,children:[(0,N.jsx)(`i`,{}),(0,N.jsx)(`span`,{children:`正在理解任务…`})]})]})]})]})}function Nl({block:e}){if(e.kind===`text`)return(0,N.jsx)(`div`,{className:`assistant-copy`,children:(0,N.jsx)(Wt,{text:e.text})});let t=e.state===`completed`?`✓`:e.state===`failed`?`×`:e.state===`cancelled`?`–`:e.state===`running`?``:`·`;return(0,N.jsxs)(`div`,{className:`activity-card`,"data-state":e.state,"data-tone":e.tone,children:[(0,N.jsx)(`span`,{className:`activity-node`,children:t}),(0,N.jsxs)(`div`,{className:`activity-body`,children:[(0,N.jsxs)(`div`,{className:`activity-title`,children:[(0,N.jsx)(`span`,{children:e.text.replace(/^[·✓×]\s*/,``)}),e.hint&&(0,N.jsx)(`code`,{children:e.hint})]}),e.progress!==void 0&&(0,N.jsx)(`div`,{className:`progress-track`,children:(0,N.jsx)(`i`,{style:{width:`${e.progress}%`}})}),e.presentation&&(0,N.jsx)(Fl,{presentation:e.presentation}),e.tool&&(0,N.jsxs)(`details`,{className:`tool-details`,children:[(0,N.jsx)(`summary`,{children:`调用详情`}),(0,N.jsx)(`label`,{children:`Input`}),(0,N.jsx)(`pre`,{children:Pl(e.tool.input)}),e.tool.result===void 0?null:(0,N.jsxs)(N.Fragment,{children:[(0,N.jsx)(`label`,{children:`Result`}),(0,N.jsx)(`pre`,{children:Pl(e.tool.result)})]})]}),e.details&&(0,N.jsxs)(`details`,{className:`timeline-details`,children:[(0,N.jsx)(`summary`,{children:`压缩摘要`}),(0,N.jsx)(Wt,{text:e.details})]})]})]})}function Pl(e,t=1e4){let n;try{n=JSON.stringify(e,null,2)??`undefined`}catch{n=String(e)}return n.length<=t?n:`${n.slice(0,t)}…`}function Fl({presentation:e}){let t=e.operation===`delete`,n=e.operation===`create`?`新建`:e.operation===`delete`?`删除`:`修改`,r=e.path.replace(/^.*[/\\]/,``),i=t?1:Math.max(1,...e.lines.map(e=>Math.max(e.oldLine??0,e.newLine??0))).toString().length;return(0,N.jsxs)(`details`,{className:`diff-preview`,children:[(0,N.jsxs)(`summary`,{children:[(0,N.jsx)(`span`,{className:`diff-marker ${t?`diff-delete`:`diff-add`}`,children:`●`}),(0,N.jsx)(`span`,{className:`diff-label`,children:n}),(0,N.jsx)(`span`,{className:`diff-path`,children:r}),(0,N.jsxs)(`span`,{className:`diff-counts`,children:[!t&&(0,N.jsxs)(`span`,{className:`diff-added-count`,children:[`+`,e.added]}),!t&&e.removed>0&&(0,N.jsxs)(`span`,{className:`diff-removed-count`,children:[` −`,e.removed]}),t&&(0,N.jsxs)(`span`,{className:`diff-removed-count`,children:[`−`,e.removed]})]})]}),t?null:(0,N.jsx)(`div`,{className:`diff-body`,children:e.lines.map((e,t)=>(0,N.jsx)(Il,{line:e,lineWidth:i},t))})]})}function Il({line:e,lineWidth:t}){let n=e.kind===`removed`||e.kind===`context`?e.oldLine:e.newLine,r=e.kind===`removed`?`-`:e.kind===`added`?`+`:e.kind===`omitted`?`…`:` `;return(0,N.jsxs)(`div`,{className:`diff-row ${e.kind===`added`?`diff-row-added`:e.kind===`removed`?`diff-row-removed`:e.kind===`omitted`?`diff-row-omitted`:`diff-row-context`}`,children:[(0,N.jsx)(`span`,{className:`diff-line-number`,children:String(n??``).padStart(t)}),(0,N.jsx)(`span`,{className:`diff-line-marker`,children:r}),(0,N.jsx)(`span`,{className:`diff-line-text`,children:e.text})]})}function Ll(e){let t=e.snapshot.workspace===void 0,[n,r]=(0,_.useState)(!1),i=(0,_.useRef)(null),a=e.slashCompletion!==null,o=e.mentionCompletion!==null,s=a||o,c=e.completedTokenLen>0,l=c?e.input.slice(0,e.completedTokenLen):void 0,u=l?.startsWith(`/`)?l.slice(1).trim():l?.trim(),d=c?void 0:e.mentionSpan,f=d!==void 0&&d.start>=0&&d.end>d.start&&d.start<e.input.length&&d.end<=e.input.length&&e.input.slice(d.start,d.end)===e.input.slice(d.start,d.end),p=f?e.input.slice(0,d.start):``,m=f?e.input.slice(d.start,d.end):``,h=f?e.input.slice(d.end):``,g=m.startsWith(`@`)?m.slice(1).trim():m,v=c?e.input.slice(e.completedTokenLen):f?h:e.input,y=c?l.length:f?d.start+m.length:0,b=e=>y+e,x=t=>{if(a){if(t.key===`ArrowDown`){t.preventDefault(),e.onSlashMove(1);return}if(t.key===`ArrowUp`){t.preventDefault(),e.onSlashMove(-1);return}if(t.key===`Tab`||t.key===`Enter`){t.preventDefault();let n=e.slashCompletion?.items[e.slashCompletion?.selectedIndex??0];n!==void 0&&e.onSlashSelect(n.name);return}if(t.key===`Escape`){t.preventDefault(),e.onSlashDismiss();return}}if(o){if(t.key===`ArrowDown`){t.preventDefault(),e.onMentionMove(1);return}if(t.key===`ArrowUp`){t.preventDefault(),e.onMentionMove(-1);return}if(t.key===`Tab`||t.key===`Enter`){t.preventDefault();let n=e.mentionCompletion?.items[e.mentionCompletion?.selectedIndex??0];n!==void 0&&e.onMentionSelect(n);return}if(t.key===`Escape`){t.preventDefault(),e.onMentionDismiss();return}}let n=t.target,r=n.selectionStart,i=n.selectionEnd;if(t.key===`Backspace`&&r===i&&!s){if(c){let n=$t(e.input,e.completedTokenLen,b(r));if(n!==null){t.preventDefault(),e.setInput(n.text),e.setCursorPos(n.cursor);return}}if(f&&r===0){t.preventDefault();let n=p+h;e.setInput(n),e.setMentionSpan(void 0),e.setCursorPos(p.length);return}}t.key===`Enter`&&!t.shiftKey&&(t.preventDefault(),e.onSend(t.altKey?`followUp`:e.busy?`steer`:void 0))},S=(t,n)=>{let r;if(r=c?l+t:f?p+m+t:t,f){let t=p+m;r.startsWith(t)||e.setMentionSpan(void 0)}e.setInput(r),e.setCursorPos(b(n))},C=t=>{e.setCursorPos(b(t))},w=(0,N.jsx)(`textarea`,{ref:e.inputRef,className:`composer-textarea`,value:v,onChange:e=>S(e.target.value,e.target.selectionStart),onSelect:e=>C(e.target.selectionStart),onKeyDown:x,onPaste:t=>{let n=Rl(t.clipboardData.files);n.length!==0&&(t.preventDefault(),e.onAddImages(n))},onClick:e=>C(e.target.selectionStart),placeholder:t?`先打开一个项目`:c||f?``:`给 Flavor 一个任务,或输入 / 查看命令`,disabled:t,rows:1}),ee=c?(0,N.jsxs)(`div`,{className:`composer-input-row`,children:[(0,N.jsx)(`span`,{className:`slash-tag`,children:u}),w]}):f?(0,N.jsxs)(`div`,{className:`composer-input-row`,children:[p.length>0&&(0,N.jsx)(`span`,{className:`composer-plain-text`,children:p}),(0,N.jsx)(`span`,{className:`mention-tag`,children:g}),w]}):w;return(0,N.jsxs)(`div`,{className:`composer-wrap`,onDragEnter:e=>{K(e.dataTransfer)&&(e.preventDefault(),r(!0))},onDragOver:e=>{K(e.dataTransfer)&&e.preventDefault()},onDragLeave:e=>{e.currentTarget.contains(e.relatedTarget)||r(!1)},onDrop:t=>{let n=Rl(t.dataTransfer.files);n.length!==0&&(t.preventDefault(),r(!1),e.onAddImages(n))},children:[a&&(0,N.jsx)(rn,{completion:e.slashCompletion,onSelect:e.onSlashSelect,onDismiss:e.onSlashDismiss}),o&&(0,N.jsx)(sn,{completion:e.mentionCompletion,onSelect:e.onMentionSelect,onDismiss:e.onMentionDismiss}),(0,N.jsxs)(`div`,{className:`composer${c||f?` has-tag`:``}`,"data-busy":e.busy,"data-image-drag":n,children:[e.attachments.length>0&&(0,N.jsx)(Ol,{attachments:e.attachments,onRemove:e.onRemoveImage}),ee,(0,N.jsxs)(`div`,{className:`composer-tools`,children:[(0,N.jsx)(`input`,{ref:i,className:`image-file-input`,type:`file`,accept:`image/png,image/jpeg,image/webp`,multiple:!0,onChange:t=>{e.onAddImages(Rl(t.target.files)),t.target.value=``}}),(0,N.jsx)(`button`,{type:`button`,className:`attach-button image-attach-button`,title:`添加图片(也可粘贴或拖入)`,"aria-label":`添加图片`,onClick:()=>i.current?.click(),disabled:t||e.busy||e.attachments.length>=Cl,children:`▧`}),(0,N.jsx)(`button`,{className:`attach-button`,title:`在提示中输入 @ 引用项目文件`,onClick:()=>{e.setInput(`${e.input}${e.input?` `:``}@`),setTimeout(()=>{let t=e.inputRef.current;t!==null&&(t.focus(),t.setSelectionRange(t.value.length,t.value.length))},0)},disabled:t,children:`+`}),(0,N.jsxs)(`div`,{className:`composer-context`,children:[(0,N.jsxs)(`span`,{className:`context-item`,children:[`▱ `,me(e.snapshot.workspace)]}),(0,N.jsx)(`span`,{className:`context-item`,children:`▣ 本地`})]}),(0,N.jsxs)(`div`,{className:`composer-controls`,children:[(0,N.jsx)(Ql,{models:e.snapshot.models,activeModel:e.snapshot.activeSession?.mainModel,busy:e.busy,onSelect:e.setModel,onAdd:e.addModel}),(0,N.jsx)(`select`,{"aria-label":`权限模式`,value:e.snapshot.activeSession?.permissionMode??`default`,disabled:e.busy||e.snapshot.activeSession===void 0,onChange:t=>e.setPermission(t.target.value),children:xl.map(e=>(0,N.jsx)(`option`,{value:e,children:A(e)},e))}),e.busy&&(0,N.jsxs)(`span`,{className:`queue-count`,title:`引导 + 后续消息`,children:[e.snapshot.activeSession?.queue.steering.length??0,`+`,e.snapshot.activeSession?.queue.followUp.length??0]}),(0,N.jsx)(`button`,{className:`send-button`,onClick:()=>e.onSend(e.busy?`steer`:void 0),disabled:t||!e.input.trim()&&e.attachments.length===0,title:e.busy?`发送引导消息`:`发送`,children:(0,N.jsx)(`span`,{children:`↑`})}),e.busy&&(0,N.jsx)(`button`,{className:`send-button stop-button`,onClick:e.onInterrupt,title:`停止任务`,children:(0,N.jsx)(`span`,{})})]})]})]}),(0,N.jsx)(`p`,{className:`composer-hint`,children:`Enter 发送 · Shift Enter 换行 · 粘贴/拖入图片 · @ 引用文件 · / 调用命令`})]})}function Rl(e){return e===null?[]:Array.from(e).filter(e=>e.type.startsWith(`image/`))}function K(e){return Array.from(e.items).some(e=>e.kind===`file`&&e.type.startsWith(`image/`))}async function q(e){if(!El.has(e.type))throw Error(`不支持 ${e.type||`未知格式`};请选择 PNG、JPEG 或 WebP 图片。`);if(e.size<=0)throw Error(`${e.name} 是空文件。`);if(e.size>wl)throw Error(`${e.name} 超过单图 5 MiB 限制。`);let t=J(new Uint8Array(await e.arrayBuffer())),n=URL.createObjectURL(e);return{id:globalThis.crypto?.randomUUID?.()??`${Date.now()}-${Math.random()}`,name:e.name,mediaType:e.type,dataBase64:t,previewUrl:n}}function J(e){let t=``,n=32768;for(let r=0;r<e.length;r+=n)t+=String.fromCharCode(...e.subarray(r,r+n));return btoa(t)}function Y({session:e,deleting:t,onCancel:n,onDelete:r}){return(0,N.jsx)(`div`,{className:`modal-layer`,children:(0,N.jsxs)(`section`,{className:`decision-sheet delete-session-sheet`,role:`dialog`,"aria-modal":`true`,"aria-labelledby":`delete-session-title`,children:[(0,N.jsx)(`div`,{className:`sheet-icon danger`,children:`×`}),(0,N.jsxs)(`div`,{children:[(0,N.jsx)(`p`,{className:`sheet-kicker`,children:`删除历史会话`}),(0,N.jsxs)(`h2`,{id:`delete-session-title`,children:[`删除“`,pe(e),`”?`]}),(0,N.jsx)(`p`,{children:`此会话的消息和任务记录将从当前项目中永久删除,此操作无法撤销。`}),(0,N.jsxs)(`div`,{className:`sheet-actions`,children:[(0,N.jsx)(`button`,{disabled:t,onClick:n,children:`取消`}),(0,N.jsx)(`button`,{className:`danger`,disabled:t,onClick:r,children:t?`正在删除…`:`删除会话`})]})]})]})})}var X=new Set([`Delete`,`Move`]);function zl({approval:e,onResolve:t}){let n=X.has(e.tool);return(0,N.jsx)(`div`,{className:`modal-layer`,children:(0,N.jsxs)(`section`,{className:`decision-sheet`,role:`dialog`,"aria-modal":`true`,"aria-labelledby":`approval-title`,children:[(0,N.jsx)(`div`,{className:`sheet-icon warning`,children:`!`}),(0,N.jsxs)(`div`,{children:[(0,N.jsxs)(`p`,{className:`sheet-kicker`,children:[`权限确认 · `,e.agent===`main`?`主 Agent`:`子 Agent`]}),(0,N.jsxs)(`h2`,{id:`approval-title`,children:[`允许执行 `,e.tool,`?`]}),(0,N.jsx)(`p`,{children:e.reason??`这项操作需要你的确认。`}),(e.command||e.paths?.length)&&(0,N.jsxs)(`pre`,{children:[e.command??e.paths?.join(`
143
- `),e.args?.length?` ${e.args.join(` `)}`:``]}),(0,N.jsxs)(`div`,{className:`sheet-actions`,children:[(0,N.jsx)(`button`,{onClick:()=>t(`deny`),children:`拒绝`}),!n&&(0,N.jsx)(`button`,{onClick:()=>t(`always`),children:`始终允许同类操作`}),(0,N.jsx)(`button`,{className:`primary`,onClick:()=>t(`allow`),children:`允许一次`})]})]})]})})}function Bl({questions:e,onAnswer:t}){let[n,r]=(0,_.useState)({}),[i,a]=(0,_.useState)({}),o=e.every((e,t)=>!!n[t]?.trim());return(0,N.jsx)(`div`,{className:`modal-layer`,children:(0,N.jsxs)(`section`,{className:`question-sheet`,role:`dialog`,"aria-modal":`true`,children:[(0,N.jsx)(`p`,{className:`sheet-kicker`,children:`Flavor 需要确认`}),e.map((e,t)=>(0,N.jsxs)(`fieldset`,{children:[(0,N.jsx)(`legend`,{children:e.header}),(0,N.jsx)(`p`,{children:e.question}),(0,N.jsxs)(`div`,{className:`question-options`,children:[e.options.map(e=>(0,N.jsxs)(`button`,{"data-selected":!i[t]&&n[t]===e.label,onClick:()=>{a(e=>({...e,[t]:!1})),r(n=>({...n,[t]:e.label}))},children:[(0,N.jsx)(`strong`,{children:e.label}),(0,N.jsx)(`span`,{children:e.description})]},e.label)),(0,N.jsxs)(`button`,{"data-selected":i[t]===!0,onClick:()=>{a(e=>({...e,[t]:!0})),r(e=>({...e,[t]:``}))},children:[(0,N.jsx)(`strong`,{children:`其他(自定义输入)`}),(0,N.jsx)(`span`,{children:`键入你自己的回答`})]}),i[t]===!0&&(0,N.jsx)(`input`,{className:`question-custom-input`,autoFocus:!0,value:n[t]??``,onChange:e=>r(n=>({...n,[t]:e.target.value})),placeholder:`请输入回答`,"aria-label":`${e.header} 自定义回答`})]})]},`${e.header}-${t}`)),(0,N.jsx)(`div`,{className:`sheet-actions`,children:(0,N.jsx)(`button`,{className:`primary`,disabled:!o,onClick:()=>t(n),children:`继续`})})]})})}function Vl({reviews:e,autoDismissSeconds:t,onResolve:n}){return(0,N.jsxs)(`aside`,{className:`memory-review-rail`,"aria-label":`长期记忆写入确认`,children:[(0,N.jsxs)(`header`,{children:[(0,N.jsxs)(`div`,{children:[(0,N.jsx)(`p`,{children:`待确认`}),(0,N.jsx)(`h2`,{children:`长期记忆候选`})]}),(0,N.jsx)(`span`,{children:e.length})]}),(0,N.jsx)(`p`,{className:`memory-review-warning`,children:`以下内容由模型生成,确认前不会写入长期记忆,也不会影响后续会话。`}),(0,N.jsx)(`div`,{className:`memory-review-list`,children:e.map(e=>(0,N.jsxs)(`article`,{children:[(0,N.jsx)(`small`,{children:e.type}),(0,N.jsx)(`p`,{children:e.content}),(0,N.jsx)(Hl,{seconds:t}),(0,N.jsxs)(`div`,{children:[(0,N.jsx)(`button`,{onClick:()=>n(e.id,`dismiss`),children:`忽略`}),(0,N.jsx)(`button`,{className:`primary`,onClick:()=>n(e.id,`accept`),children:`保存`})]})]},e.id))})]})}function Hl({seconds:e}){let[t,n]=(0,_.useState)(e);return(0,_.useEffect)(()=>{if(e<=0)return;n(e);let t=setInterval(()=>n(e=>Math.max(0,e-1)),1e3);return()=>clearInterval(t)},[e]),e<=0?null:(0,N.jsxs)(`small`,{className:`memory-review-countdown`,children:[`未操作将在 `,t,`s 后自动忽略`]})}function Ul({project:e,onStart:t}){return(0,N.jsxs)(`section`,{className:`welcome-state`,children:[(0,N.jsx)(`div`,{className:`welcome-mark`,children:(0,N.jsx)(Yl,{})}),(0,N.jsx)(`p`,{children:`已连接本地项目`}),(0,N.jsxs)(`h1`,{children:[`我们应该在 `,(0,N.jsx)(`u`,{children:e}),` 中构建什么?`]}),(0,N.jsx)(`div`,{className:`starter-grid`,children:de.map(e=>(0,N.jsx)(`button`,{onClick:()=>t(e),children:e},e))})]})}function Wl({onOpen:e}){return(0,N.jsxs)(`section`,{className:`open-state`,children:[(0,N.jsx)(`div`,{className:`welcome-mark`,children:(0,N.jsx)(Yl,{})}),(0,N.jsx)(`h1`,{children:`从一个本地项目开始`}),(0,N.jsx)(`p`,{children:`Flavor 会在你选择的文件夹范围内阅读、修改和运行代码。`}),(0,N.jsx)(`button`,{onClick:e,children:`打开项目`})]})}function Gl(){return(0,N.jsxs)(`div`,{className:`loading-state`,children:[(0,N.jsx)(Yl,{}),(0,N.jsx)(`span`,{children:`正在准备桌面工作区…`})]})}var Kl;function ql(){return Kl??=window.flavorDesktop.appIcon().catch(()=>void 0),Kl}function Jl(){let[e,t]=(0,_.useState)(void 0);return(0,_.useEffect)(()=>{let e=!1;return ql().then(n=>{e||t(n)}),()=>{e=!0}},[]),e}function Yl(){let e=Jl();return e===void 0?(0,N.jsxs)(`svg`,{className:`flavor-mark`,viewBox:`0 0 36 36`,"aria-hidden":`true`,children:[(0,N.jsx)(`path`,{d:`M8 17.5C8 11.7 12.5 7 18 7s10 4.7 10 10.5c0 2.7-1 5.1-2.7 7l1 3.8-4-1.2A9.5 9.5 0 0 1 18 28c-5.5 0-10-4.7-10-10.5Z`}),(0,N.jsx)(`path`,{d:`M16 15l-2 2l2 2`,fill:`none`,stroke:`#1979c9`,strokeWidth:`1.5`,strokeLinecap:`round`,strokeLinejoin:`round`}),(0,N.jsx)(`path`,{d:`M20 15l2 2l-2 2`,fill:`none`,stroke:`#1979c9`,strokeWidth:`1.5`,strokeLinecap:`round`,strokeLinejoin:`round`}),(0,N.jsx)(`path`,{className:`mark-smile`,d:`M14 23c2.5 1.5 5.5 1.5 8 0`}),(0,N.jsx)(`ellipse`,{cx:`22`,cy:`24`,rx:`1.2`,ry:`0.9`,fill:`#f472b6`,stroke:`#ec4899`,strokeWidth:`0.3`,transform:`rotate(15 22 24)`})]}):(0,N.jsx)(`img`,{className:`flavor-mark`,src:e,alt:``,"aria-hidden":`true`})}function Xl(e){return e instanceof Error?e.message:String(e)}function Zl(e){return e?e.split(`:`).at(-1)??e:`选择模型`}function Ql({models:e,activeModel:t,busy:n,onSelect:r,onAdd:i}){let[a,o]=(0,_.useState)(!1),[s,c]=(0,_.useState)(!1),[l,u]=(0,_.useState)(),[d,f]=(0,_.useState)({provider:``,model:``,baseURL:``,apiKey:``,protocol:`openai-compatible`}),p=(e,t)=>{f(n=>({...n,[e]:t})),u(void 0)},m=async e=>{if(e.preventDefault(),s)return;let t=e.currentTarget;c(!0),u(void 0);try{await i(d),o(!1),f({provider:``,model:``,baseURL:``,apiKey:``,protocol:`openai-compatible`}),t.closest(`details`)?.removeAttribute(`open`)}catch(e){u(Xl(e))}finally{c(!1)}};return(0,N.jsxs)(`details`,{className:`model-menu`,children:[(0,N.jsxs)(`summary`,{children:[Zl(t),`⌄`]}),(0,N.jsxs)(`div`,{className:`popover model-popover`,children:[(0,N.jsxs)(`div`,{className:`model-popover-heading`,children:[(0,N.jsxs)(`div`,{children:[(0,N.jsx)(`strong`,{children:a?`添加厂商模型`:`切换主模型`}),(0,N.jsx)(`span`,{children:a?`连接 OpenAI 兼容或 Anthropic 服务`:`DeepSeek 默认可用,也可接入其他厂商`})]}),!a&&(0,N.jsx)(`button`,{type:`button`,onClick:()=>o(!0),disabled:n,children:`+ 新增`})]}),a?(0,N.jsxs)(`form`,{className:`model-provider-form`,onSubmit:e=>void m(e),children:[(0,N.jsxs)(`div`,{className:`model-form-grid`,children:[(0,N.jsxs)(`label`,{children:[(0,N.jsx)(`span`,{children:`厂商名称 / ID`}),(0,N.jsx)(`input`,{required:!0,maxLength:64,placeholder:`例如 siliconflow`,value:d.provider,onChange:e=>p(`provider`,e.target.value),pattern:`[A-Za-z0-9][A-Za-z0-9_-]*`})]}),(0,N.jsxs)(`label`,{children:[(0,N.jsx)(`span`,{children:`模型名称`}),(0,N.jsx)(`input`,{required:!0,maxLength:256,placeholder:`例如 qwen3-coder`,value:d.model,onChange:e=>p(`model`,e.target.value)})]})]}),(0,N.jsxs)(`label`,{children:[(0,N.jsx)(`span`,{children:`接口协议`}),(0,N.jsxs)(`select`,{value:d.protocol,onChange:e=>p(`protocol`,e.target.value),children:[(0,N.jsx)(`option`,{value:`openai-compatible`,children:`OpenAI 兼容 API`}),(0,N.jsx)(`option`,{value:`anthropic`,children:`Anthropic API`})]})]}),(0,N.jsxs)(`label`,{children:[(0,N.jsx)(`span`,{children:`Base URL`}),(0,N.jsx)(`input`,{required:!0,type:`url`,maxLength:2048,placeholder:`https://api.example.com/v1`,value:d.baseURL,onChange:e=>p(`baseURL`,e.target.value)})]}),(0,N.jsxs)(`label`,{children:[(0,N.jsx)(`span`,{children:`API Key`}),(0,N.jsx)(`input`,{required:!0,type:`password`,autoComplete:`off`,maxLength:16384,placeholder:`输入服务密钥`,value:d.apiKey,onChange:e=>p(`apiKey`,e.target.value)})]}),(0,N.jsxs)(`p`,{className:`model-security-note`,children:[(0,N.jsx)(`span`,{children:`◆`}),` 配置同步到当前项目,密钥只加密保存在本机。保存后会新建会话。`]}),l!==void 0&&(0,N.jsx)(`p`,{className:`model-form-error`,role:`alert`,children:l}),(0,N.jsxs)(`div`,{className:`model-form-actions`,children:[(0,N.jsx)(`button`,{type:`button`,onClick:()=>{o(!1),u(void 0)},disabled:s,children:`取消`}),(0,N.jsx)(`button`,{type:`submit`,className:`primary`,disabled:s||n,children:s?`正在连接…`:`保存并切换`})]})]}):(0,N.jsx)(`div`,{className:`model-options`,role:`listbox`,"aria-label":`主模型`,children:e.map(e=>{let i=t===e.id;return(0,N.jsxs)(`button`,{type:`button`,role:`option`,"aria-selected":i,className:`model-option`,disabled:n||i,onClick:t=>{r(e.id),t.currentTarget.closest(`details`)?.removeAttribute(`open`)},children:[(0,N.jsxs)(`span`,{className:`model-option-copy`,children:[(0,N.jsx)(`strong`,{children:e.label}),(0,N.jsx)(`small`,{children:e.description})]}),e.source===`custom`&&(0,N.jsx)(`span`,{className:`model-option-badge`,children:`自定义`}),(0,N.jsx)(`span`,{className:`model-option-state`,"aria-hidden":`true`,children:i?`✓`:`→`})]},e.id)})})]})]})}function $l(e){let t=new Date(e);return Number.isNaN(t.getTime())?``:t.toLocaleTimeString(`zh-CN`,{hour:`2-digit`,minute:`2-digit`})}var eu=document.getElementById(`root`);if(eu===null)throw Error(`Desktop root element was not found`);(0,v.createRoot)(eu).render((0,N.jsx)(_.StrictMode,{children:(0,N.jsx)(kl,{})}));
144
- //# sourceMappingURL=index-C66pDvHs.js.map
143
+ `),e.args?.length?` ${e.args.join(` `)}`:``]}),(0,N.jsxs)(`div`,{className:`sheet-actions`,children:[(0,N.jsx)(`button`,{onClick:()=>t(`deny`),children:`拒绝`}),!n&&(0,N.jsx)(`button`,{onClick:()=>t(`always`),children:`始终允许同类操作`}),(0,N.jsx)(`button`,{className:`primary`,onClick:()=>t(`allow`),children:`允许一次`})]})]})]})})}function Bl({questions:e,onAnswer:t}){let[n,r]=(0,_.useState)({}),[i,a]=(0,_.useState)({}),o=e.every((e,t)=>!!n[t]?.trim());return(0,N.jsx)(`div`,{className:`modal-layer`,children:(0,N.jsxs)(`section`,{className:`question-sheet`,role:`dialog`,"aria-modal":`true`,children:[(0,N.jsx)(`p`,{className:`sheet-kicker`,children:`Flavor 需要确认`}),e.map((e,t)=>(0,N.jsxs)(`fieldset`,{children:[(0,N.jsx)(`legend`,{children:e.header}),(0,N.jsx)(`p`,{children:e.question}),(0,N.jsxs)(`div`,{className:`question-options`,children:[e.options.map(e=>(0,N.jsxs)(`button`,{"data-selected":!i[t]&&n[t]===e.label,onClick:()=>{a(e=>({...e,[t]:!1})),r(n=>({...n,[t]:e.label}))},children:[(0,N.jsx)(`strong`,{children:e.label}),(0,N.jsx)(`span`,{children:e.description})]},e.label)),(0,N.jsxs)(`button`,{"data-selected":i[t]===!0,onClick:()=>{a(e=>({...e,[t]:!0})),r(e=>({...e,[t]:``}))},children:[(0,N.jsx)(`strong`,{children:`其他(自定义输入)`}),(0,N.jsx)(`span`,{children:`键入你自己的回答`})]}),i[t]===!0&&(0,N.jsx)(`input`,{className:`question-custom-input`,autoFocus:!0,value:n[t]??``,onChange:e=>r(n=>({...n,[t]:e.target.value})),placeholder:`请输入回答`,"aria-label":`${e.header} 自定义回答`})]})]},`${e.header}-${t}`)),(0,N.jsx)(`div`,{className:`sheet-actions`,children:(0,N.jsx)(`button`,{className:`primary`,disabled:!o,onClick:()=>t(n),children:`继续`})})]})})}function Vl({reviews:e,autoDismissSeconds:t,onResolve:n}){return(0,N.jsxs)(`aside`,{className:`memory-review-rail`,"aria-label":`长期记忆写入确认`,children:[(0,N.jsxs)(`header`,{children:[(0,N.jsxs)(`div`,{children:[(0,N.jsx)(`p`,{children:`待确认`}),(0,N.jsx)(`h2`,{children:`长期记忆候选`})]}),(0,N.jsx)(`span`,{children:e.length})]}),(0,N.jsx)(`p`,{className:`memory-review-warning`,children:`以下内容由模型生成,确认前不会写入长期记忆,也不会影响后续会话。`}),(0,N.jsx)(`div`,{className:`memory-review-list`,children:e.map(e=>(0,N.jsxs)(`article`,{children:[(0,N.jsx)(`small`,{children:e.type}),(0,N.jsx)(`p`,{children:e.content}),(0,N.jsx)(Hl,{seconds:t}),(0,N.jsxs)(`div`,{children:[(0,N.jsx)(`button`,{onClick:()=>n(e.id,`dismiss`),children:`忽略`}),(0,N.jsx)(`button`,{className:`primary`,onClick:()=>n(e.id,`accept`),children:`保存`})]})]},e.id))})]})}function Hl({seconds:e}){let[t,n]=(0,_.useState)(e);return(0,_.useEffect)(()=>{if(e<=0)return;n(e);let t=setInterval(()=>n(e=>Math.max(0,e-1)),1e3);return()=>clearInterval(t)},[e]),e<=0?null:(0,N.jsxs)(`small`,{className:`memory-review-countdown`,children:[`未操作将在 `,t,`s 后自动忽略`]})}function Ul({project:e,onStart:t}){return(0,N.jsxs)(`section`,{className:`welcome-state`,children:[(0,N.jsx)(`div`,{className:`welcome-mark`,children:(0,N.jsx)(Yl,{})}),(0,N.jsx)(`p`,{children:`已连接本地项目`}),(0,N.jsxs)(`h1`,{children:[`我们应该在 `,(0,N.jsx)(`u`,{children:e}),` 中构建什么?`]}),(0,N.jsx)(`div`,{className:`starter-grid`,children:de.map(e=>(0,N.jsx)(`button`,{onClick:()=>t(e),children:e},e))})]})}function Wl({onOpen:e}){return(0,N.jsxs)(`section`,{className:`open-state`,children:[(0,N.jsx)(`div`,{className:`welcome-mark`,children:(0,N.jsx)(Yl,{})}),(0,N.jsx)(`h1`,{children:`从一个本地项目开始`}),(0,N.jsx)(`p`,{children:`Flavor 会在你选择的文件夹范围内阅读、修改和运行代码。`}),(0,N.jsx)(`button`,{onClick:e,children:`打开项目`})]})}function Gl(){return(0,N.jsxs)(`div`,{className:`loading-state`,children:[(0,N.jsx)(Yl,{}),(0,N.jsx)(`span`,{children:`正在准备桌面工作区…`})]})}var Kl;function ql(){return Kl??=window.flavorDesktop.appIcon().catch(()=>void 0),Kl}function Jl(){let[e,t]=(0,_.useState)(void 0);return(0,_.useEffect)(()=>{let e=!1;return ql().then(n=>{e||t(n)}),()=>{e=!0}},[]),e}function Yl(){let e=Jl();return e===void 0?(0,N.jsxs)(`svg`,{className:`flavor-mark`,viewBox:`0 0 36 36`,"aria-hidden":`true`,children:[(0,N.jsx)(`path`,{d:`M8 17.5C8 11.7 12.5 7 18 7s10 4.7 10 10.5c0 2.7-1 5.1-2.7 7l1 3.8-4-1.2A9.5 9.5 0 0 1 18 28c-5.5 0-10-4.7-10-10.5Z`}),(0,N.jsx)(`path`,{d:`M16 15l-2 2l2 2`,fill:`none`,stroke:`#1979c9`,strokeWidth:`1.5`,strokeLinecap:`round`,strokeLinejoin:`round`}),(0,N.jsx)(`path`,{d:`M20 15l2 2l-2 2`,fill:`none`,stroke:`#1979c9`,strokeWidth:`1.5`,strokeLinecap:`round`,strokeLinejoin:`round`}),(0,N.jsx)(`path`,{className:`mark-smile`,d:`M14 23c2.5 1.5 5.5 1.5 8 0`}),(0,N.jsx)(`ellipse`,{cx:`22`,cy:`24`,rx:`1.2`,ry:`0.9`,fill:`#f472b6`,stroke:`#ec4899`,strokeWidth:`0.3`,transform:`rotate(15 22 24)`})]}):(0,N.jsx)(`img`,{className:`flavor-mark`,src:e,alt:``,"aria-hidden":`true`})}function Xl(e){return e instanceof Error?e.message:String(e)}function Zl(e){return e?e.split(`:`).at(-1)??e:`选择模型`}function Ql({models:e,activeModel:t,busy:n,onSelect:r,onAdd:i}){let[a,o]=(0,_.useState)(!1),[s,c]=(0,_.useState)(!1),[l,u]=(0,_.useState)(),[d,f]=(0,_.useState)({provider:``,model:``,baseURL:``,apiKey:``,protocol:`openai-compatible`}),p=(e,t)=>{f(n=>({...n,[e]:t})),u(void 0)},m=async e=>{if(e.preventDefault(),s)return;let t=e.currentTarget;c(!0),u(void 0);try{await i(d),o(!1),f({provider:``,model:``,baseURL:``,apiKey:``,protocol:`openai-compatible`}),t.closest(`details`)?.removeAttribute(`open`)}catch(e){u(Xl(e))}finally{c(!1)}};return(0,N.jsxs)(`details`,{className:`model-menu`,children:[(0,N.jsxs)(`summary`,{children:[Zl(t),`⌄`]}),(0,N.jsxs)(`div`,{className:`popover model-popover`,children:[(0,N.jsxs)(`div`,{className:`model-popover-heading`,children:[(0,N.jsxs)(`div`,{children:[(0,N.jsx)(`strong`,{children:a?`添加厂商模型`:`切换主模型`}),(0,N.jsx)(`span`,{children:a?`连接 OpenAI 兼容或 Anthropic 服务`:`DeepSeek 默认可用,也可接入其他厂商`})]}),!a&&(0,N.jsx)(`button`,{type:`button`,onClick:()=>o(!0),disabled:n,children:`+ 新增`})]}),a?(0,N.jsxs)(`form`,{className:`model-provider-form`,onSubmit:e=>void m(e),children:[(0,N.jsxs)(`div`,{className:`model-form-grid`,children:[(0,N.jsxs)(`label`,{children:[(0,N.jsx)(`span`,{children:`厂商名称 / ID`}),(0,N.jsx)(`input`,{required:!0,maxLength:64,placeholder:`例如 siliconflow`,value:d.provider,onChange:e=>p(`provider`,e.target.value),pattern:`[A-Za-z0-9][A-Za-z0-9_-]*`})]}),(0,N.jsxs)(`label`,{children:[(0,N.jsx)(`span`,{children:`模型名称`}),(0,N.jsx)(`input`,{required:!0,maxLength:256,placeholder:`例如 qwen3-coder`,value:d.model,onChange:e=>p(`model`,e.target.value)})]})]}),(0,N.jsxs)(`label`,{children:[(0,N.jsx)(`span`,{children:`接口协议`}),(0,N.jsxs)(`select`,{value:d.protocol,onChange:e=>p(`protocol`,e.target.value),children:[(0,N.jsx)(`option`,{value:`openai-compatible`,children:`OpenAI 兼容 API`}),(0,N.jsx)(`option`,{value:`anthropic`,children:`Anthropic API`})]})]}),(0,N.jsxs)(`label`,{children:[(0,N.jsx)(`span`,{children:`Base URL`}),(0,N.jsx)(`input`,{required:!0,type:`url`,maxLength:2048,placeholder:`https://api.example.com/v1`,value:d.baseURL,onChange:e=>p(`baseURL`,e.target.value)})]}),(0,N.jsxs)(`label`,{children:[(0,N.jsx)(`span`,{children:`API Key`}),(0,N.jsx)(`input`,{required:!0,type:`password`,autoComplete:`off`,maxLength:16384,placeholder:`输入服务密钥`,value:d.apiKey,onChange:e=>p(`apiKey`,e.target.value)})]}),(0,N.jsxs)(`p`,{className:`model-security-note`,children:[(0,N.jsx)(`span`,{children:`◆`}),` 配置同步到当前项目,密钥只加密保存在本机。保存后会新建会话。`]}),l!==void 0&&(0,N.jsx)(`p`,{className:`model-form-error`,role:`alert`,children:l}),(0,N.jsxs)(`div`,{className:`model-form-actions`,children:[(0,N.jsx)(`button`,{type:`button`,onClick:()=>{o(!1),u(void 0)},disabled:s,children:`取消`}),(0,N.jsx)(`button`,{type:`submit`,className:`primary`,disabled:s||n,children:s?`正在连接…`:`保存并切换`})]})]}):(0,N.jsx)(`div`,{className:`model-options`,role:`listbox`,"aria-label":`主模型`,children:e.map(e=>{let i=t===e.id;return(0,N.jsxs)(`button`,{type:`button`,role:`option`,"aria-selected":i,className:`model-option`,disabled:n||i,onClick:t=>{r(e.id),t.currentTarget.closest(`details`)?.removeAttribute(`open`)},children:[(0,N.jsxs)(`span`,{className:`model-option-copy`,children:[(0,N.jsx)(`strong`,{children:e.label}),(0,N.jsx)(`small`,{children:e.description})]}),e.source===`custom`&&(0,N.jsx)(`span`,{className:`model-option-badge`,children:`自定义`}),(0,N.jsx)(`span`,{className:`model-option-state`,"aria-hidden":`true`,children:i?`✓`:`→`})]},e.id)})})]})]})}function $l(e){let t=new Date(e);return Number.isNaN(t.getTime())?``:t.toLocaleTimeString(`zh-CN`,{hour:`2-digit`,minute:`2-digit`})}var eu=document.getElementById(`root`);if(eu===null)throw Error(`Desktop root element was not found`);(0,v.createRoot)(eu).render((0,N.jsx)(_.StrictMode,{children:(0,N.jsx)(kl,{})}));
@@ -1,16 +1,16 @@
1
- <!doctype html>
2
- <html lang="zh-CN">
3
- <head>
4
- <meta charset="UTF-8" />
5
- <meta name="viewport" content="width=device-width, initial-scale=1.0" />
6
- <meta name="color-scheme" content="light" />
7
- <meta http-equiv="Content-Security-Policy" content="default-src 'self'; script-src 'self'; style-src 'self' 'unsafe-inline'; img-src 'self' data:; connect-src 'self' http://127.0.0.1:* ws://127.0.0.1:*" />
8
- <title>Flavor Code</title>
1
+ <!doctype html>
2
+ <html lang="zh-CN">
3
+ <head>
4
+ <meta charset="UTF-8" />
5
+ <meta name="viewport" content="width=device-width, initial-scale=1.0" />
6
+ <meta name="color-scheme" content="light" />
7
+ <meta http-equiv="Content-Security-Policy" content="default-src 'self'; script-src 'self'; style-src 'self' 'unsafe-inline'; img-src 'self' data:; connect-src 'self' http://127.0.0.1:* ws://127.0.0.1:*" />
8
+ <title>Flavor Code</title>
9
9
  <script type="module" crossorigin src="./assets/index-C66pDvHs.js"></script>
10
10
  <link rel="stylesheet" crossorigin href="./assets/index-Cm_ktmXm.css">
11
- </head>
12
- <body>
13
- <div id="root"></div>
14
- </body>
15
- </html>
16
-
11
+ </head>
12
+ <body>
13
+ <div id="root"></div>
14
+ </body>
15
+ </html>
16
+
@@ -1,3 +1,2 @@
1
1
  #!/usr/bin/env node
2
2
  import { createRequire } from "node:module"; const require = createRequire(import.meta.url);
3
- //# sourceMappingURL=devtools-SXJBSV2N.js.map
@@ -7,8 +7,8 @@ import {
7
7
  setProjectMcpServerDisabled,
8
8
  setProjectProviderConfig,
9
9
  setProjectSkillDisabled
10
- } from "./chunk-MVIMQEQT.js";
11
- import "./chunk-JZ322RCJ.js";
10
+ } from "./chunk-HFR2WS6T.js";
11
+ import "./chunk-S32JRDZK.js";
12
12
  export {
13
13
  loadConfig,
14
14
  redactConfig,
@@ -17,4 +17,3 @@ export {
17
17
  setProjectProviderConfig,
18
18
  setProjectSkillDisabled
19
19
  };
20
- //# sourceMappingURL=load-WQGNTCHC.js.map
package/dist/sdk/index.js CHANGED
@@ -4,7 +4,7 @@ import {
4
4
  FlavorRpcServer,
5
5
  TraceRecordSchema,
6
6
  TraceRecorder
7
- } from "../chunk-AHUOGT4I.js";
7
+ } from "../chunk-L5A2NDMT.js";
8
8
  import {
9
9
  AgentMessageQueue,
10
10
  DockerExecutionEnvironment,
@@ -13,10 +13,10 @@ import {
13
13
  WorkspaceCheckpointStore,
14
14
  buildDockerInvocation,
15
15
  createProductionRuntime
16
- } from "../chunk-XGCFBGBB.js";
17
- import "../chunk-MVIMQEQT.js";
18
- import "../chunk-VOCZVFP7.js";
19
- import "../chunk-JZ322RCJ.js";
16
+ } from "../chunk-MRISY6KK.js";
17
+ import "../chunk-HFR2WS6T.js";
18
+ import "../chunk-N2S7USST.js";
19
+ import "../chunk-S32JRDZK.js";
20
20
 
21
21
  // src/trace/replay.ts
22
22
  import { readFile } from "fs/promises";
@@ -50,4 +50,3 @@ export {
50
50
  replayOutputEvents,
51
51
  replayTrace
52
52
  };
53
- //# sourceMappingURL=index.js.map
package/package.json CHANGED
@@ -1,8 +1,11 @@
1
1
  {
2
2
  "name": "flavor-code",
3
- "version": "1.2.3",
3
+ "version": "1.2.4",
4
4
  "author": "YachuanWzh",
5
5
  "type": "module",
6
+ "publishConfig": {
7
+ "registry": "https://registry.npmjs.org"
8
+ },
6
9
  "main": "dist/desktop/main.js",
7
10
  "bin": {
8
11
  "flavor": "dist/cli.js"
@@ -16,6 +19,7 @@
16
19
  },
17
20
  "files": [
18
21
  "dist/",
22
+ "!dist/**/*.map",
19
23
  "README.md",
20
24
  "技术方案报告.md",
21
25
  "LICENSE"
@@ -55,6 +59,7 @@
55
59
  },
56
60
  "files": [
57
61
  "dist/**/*",
62
+ "!dist/**/*.map",
58
63
  "assets/icon.png",
59
64
  "package.json",
60
65
  "README.md",
@@ -1,6 +1,6 @@
1
1
  # flavor-code 技术方案报告
2
2
 
3
- > 版本:1.2.3 | 语言:TypeScript | 运行时:Node.js ≥20 | 包管理器:npm
3
+ > 版本:1.2.4 | 语言:TypeScript | 运行时:Node.js ≥20 | 包管理器:npm
4
4
 
5
5
  ---
6
6