@researai/deepscientist 1.5.11 → 1.5.13

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 (107) hide show
  1. package/README.md +8 -8
  2. package/bin/ds.js +375 -61
  3. package/docs/en/00_QUICK_START.md +55 -4
  4. package/docs/en/01_SETTINGS_REFERENCE.md +15 -0
  5. package/docs/en/02_START_RESEARCH_GUIDE.md +68 -4
  6. package/docs/en/09_DOCTOR.md +48 -4
  7. package/docs/en/12_GUIDED_WORKFLOW_TOUR.md +21 -2
  8. package/docs/en/15_CODEX_PROVIDER_SETUP.md +382 -0
  9. package/docs/en/README.md +4 -0
  10. package/docs/zh/00_QUICK_START.md +54 -3
  11. package/docs/zh/01_SETTINGS_REFERENCE.md +15 -0
  12. package/docs/zh/02_START_RESEARCH_GUIDE.md +69 -3
  13. package/docs/zh/09_DOCTOR.md +48 -2
  14. package/docs/zh/12_GUIDED_WORKFLOW_TOUR.md +21 -2
  15. package/docs/zh/15_CODEX_PROVIDER_SETUP.md +383 -0
  16. package/docs/zh/README.md +4 -1
  17. package/package.json +2 -1
  18. package/pyproject.toml +1 -1
  19. package/src/deepscientist/__init__.py +1 -1
  20. package/src/deepscientist/bash_exec/monitor.py +7 -5
  21. package/src/deepscientist/bash_exec/service.py +84 -21
  22. package/src/deepscientist/channels/local.py +3 -3
  23. package/src/deepscientist/channels/qq.py +7 -7
  24. package/src/deepscientist/channels/relay.py +7 -7
  25. package/src/deepscientist/channels/weixin_ilink.py +90 -19
  26. package/src/deepscientist/cli.py +3 -0
  27. package/src/deepscientist/codex_cli_compat.py +117 -0
  28. package/src/deepscientist/config/models.py +1 -0
  29. package/src/deepscientist/config/service.py +173 -25
  30. package/src/deepscientist/daemon/app.py +314 -6
  31. package/src/deepscientist/doctor.py +1 -5
  32. package/src/deepscientist/mcp/server.py +124 -3
  33. package/src/deepscientist/prompts/builder.py +113 -11
  34. package/src/deepscientist/quest/service.py +247 -31
  35. package/src/deepscientist/runners/codex.py +132 -24
  36. package/src/deepscientist/runners/runtime_overrides.py +9 -0
  37. package/src/deepscientist/shared.py +33 -14
  38. package/src/prompts/connectors/qq.md +2 -1
  39. package/src/prompts/connectors/weixin.md +2 -1
  40. package/src/prompts/contracts/shared_interaction.md +4 -1
  41. package/src/prompts/system.md +59 -9
  42. package/src/skills/analysis-campaign/SKILL.md +46 -6
  43. package/src/skills/analysis-campaign/references/campaign-plan-template.md +21 -8
  44. package/src/skills/baseline/SKILL.md +1 -1
  45. package/src/skills/baseline/references/artifact-payload-examples.md +39 -0
  46. package/src/skills/decision/SKILL.md +1 -1
  47. package/src/skills/experiment/SKILL.md +1 -1
  48. package/src/skills/finalize/SKILL.md +1 -1
  49. package/src/skills/idea/SKILL.md +1 -1
  50. package/src/skills/intake-audit/SKILL.md +1 -1
  51. package/src/skills/rebuttal/SKILL.md +74 -1
  52. package/src/skills/rebuttal/references/response-letter-template.md +55 -11
  53. package/src/skills/review/SKILL.md +118 -1
  54. package/src/skills/review/references/experiment-todo-template.md +23 -0
  55. package/src/skills/review/references/review-report-template.md +16 -0
  56. package/src/skills/review/references/revision-log-template.md +4 -0
  57. package/src/skills/scout/SKILL.md +1 -1
  58. package/src/skills/write/SKILL.md +168 -7
  59. package/src/skills/write/references/paper-experiment-matrix-template.md +131 -0
  60. package/src/tui/dist/lib/connectorConfig.js +90 -0
  61. package/src/tui/dist/lib/qr.js +21 -0
  62. package/src/tui/package.json +2 -1
  63. package/src/ui/dist/assets/{AiManusChatView-D0mTXG4-.js → AiManusChatView-CnJcXynW.js} +12 -12
  64. package/src/ui/dist/assets/{AnalysisPlugin-Db0cTXxm.js → AnalysisPlugin-DeyzPEhV.js} +1 -1
  65. package/src/ui/dist/assets/{CliPlugin-DrV8je02.js → CliPlugin-CB1YODQn.js} +9 -9
  66. package/src/ui/dist/assets/{CodeEditorPlugin-QXMSCH71.js → CodeEditorPlugin-B-xicq1e.js} +8 -8
  67. package/src/ui/dist/assets/{CodeViewerPlugin-7hhtWj_E.js → CodeViewerPlugin-DT54ysXa.js} +5 -5
  68. package/src/ui/dist/assets/{DocViewerPlugin-BWMSnRJe.js → DocViewerPlugin-DQtKT-VD.js} +3 -3
  69. package/src/ui/dist/assets/{GitDiffViewerPlugin-7J9h9Vy_.js → GitDiffViewerPlugin-hqHbCfnv.js} +20 -20
  70. package/src/ui/dist/assets/{ImageViewerPlugin-CHJl_0lr.js → ImageViewerPlugin-OcVo33jV.js} +5 -5
  71. package/src/ui/dist/assets/{LabCopilotPanel-1qSow1es.js → LabCopilotPanel-DdGwhEUV.js} +11 -11
  72. package/src/ui/dist/assets/{LabPlugin-eQpPPCEp.js → LabPlugin-Ciz1gDaX.js} +2 -2
  73. package/src/ui/dist/assets/{LatexPlugin-BwRfi89Z.js → LatexPlugin-BhmjNQRC.js} +37 -11
  74. package/src/ui/dist/assets/{MarkdownViewerPlugin-836PVQWV.js → MarkdownViewerPlugin-BzdVH9Bx.js} +4 -4
  75. package/src/ui/dist/assets/{MarketplacePlugin-C2y_556i.js → MarketplacePlugin-DmyHspXt.js} +3 -3
  76. package/src/ui/dist/assets/{NotebookEditor-DIX7Mlzu.js → NotebookEditor-BMXKrDRk.js} +1 -1
  77. package/src/ui/dist/assets/{NotebookEditor-BRzJbGsn.js → NotebookEditor-BTVYRGkm.js} +11 -11
  78. package/src/ui/dist/assets/{PdfLoader-DzRaTAlq.js → PdfLoader-CvcjJHXv.js} +1 -1
  79. package/src/ui/dist/assets/{PdfMarkdownPlugin-DZUfIUnp.js → PdfMarkdownPlugin-DW2ej8Vk.js} +2 -2
  80. package/src/ui/dist/assets/{PdfViewerPlugin-BwtICzue.js → PdfViewerPlugin-CmlDxbhU.js} +10 -10
  81. package/src/ui/dist/assets/{SearchPlugin-DHeIAMsx.js → SearchPlugin-DAjQZPSv.js} +1 -1
  82. package/src/ui/dist/assets/{TextViewerPlugin-C3tCmFox.js → TextViewerPlugin-C-nVAZb_.js} +5 -5
  83. package/src/ui/dist/assets/{VNCViewer-CQsKVm3t.js → VNCViewer-D7-dIYon.js} +10 -10
  84. package/src/ui/dist/assets/{bot-BEA2vWuK.js → bot-C_G4WtNI.js} +1 -1
  85. package/src/ui/dist/assets/{code-XfbSR8K2.js → code-Cd7WfiWq.js} +1 -1
  86. package/src/ui/dist/assets/{file-content-BjxNaIfy.js → file-content-B57zsL9y.js} +1 -1
  87. package/src/ui/dist/assets/{file-diff-panel-D_lLVQk0.js → file-diff-panel-DVoheLFq.js} +1 -1
  88. package/src/ui/dist/assets/{file-socket-D9x_5vlY.js → file-socket-B5kXFxZP.js} +1 -1
  89. package/src/ui/dist/assets/{image-BhWT33W1.js → image-LLOjkMHF.js} +1 -1
  90. package/src/ui/dist/assets/{index-Dqj-Mjb4.css → index-BQG-1s2o.css} +40 -2
  91. package/src/ui/dist/assets/{index--c4iXtuy.js → index-C3r2iGrp.js} +12 -12
  92. package/src/ui/dist/assets/{index-DZTZ8mWP.js → index-CLQauncb.js} +911 -120
  93. package/src/ui/dist/assets/{index-PJbSbPTy.js → index-Dxa2eYMY.js} +1 -1
  94. package/src/ui/dist/assets/{index-BDxipwrC.js → index-hOUOWbW2.js} +2 -2
  95. package/src/ui/dist/assets/{monaco-K8izTGgo.js → monaco-BGGAEii3.js} +1 -1
  96. package/src/ui/dist/assets/{pdf-effect-queue-DfBors6y.js → pdf-effect-queue-DlEr1_y5.js} +1 -1
  97. package/src/ui/dist/assets/{popover-yFK1J4fL.js → popover-CWJbJuYY.js} +1 -1
  98. package/src/ui/dist/assets/{project-sync-PENr2zcz.js → project-sync-CRJiucYO.js} +18 -4
  99. package/src/ui/dist/assets/{select-CAbJDfYv.js → select-CoHB7pvH.js} +2 -2
  100. package/src/ui/dist/assets/{sigma-DEuYJqTl.js → sigma-D5aJWR8J.js} +1 -1
  101. package/src/ui/dist/assets/{square-check-big-omoSUmcd.js → square-check-big-DUK_mnkS.js} +1 -1
  102. package/src/ui/dist/assets/{trash--F119N47.js → trash-ChU3SEE3.js} +1 -1
  103. package/src/ui/dist/assets/{useCliAccess-D31UR23I.js → useCliAccess-BrJBV3tY.js} +1 -1
  104. package/src/ui/dist/assets/{useFileDiffOverlay-BH6KcMzq.js → useFileDiffOverlay-C2OQaVWc.js} +1 -1
  105. package/src/ui/dist/assets/{wrap-text-CZ613PM5.js → wrap-text-C7Qqh-om.js} +1 -1
  106. package/src/ui/dist/assets/{zoom-out-BgDLAv3z.js → zoom-out-rtX0FKya.js} +1 -1
  107. package/src/ui/dist/index.html +2 -2
@@ -1,4 +1,4 @@
1
- const __vite__mapDeps=(i,m=__vite__mapDeps,d=(m.f||(m.f=["assets/CodeViewerPlugin-7hhtWj_E.js","assets/file-jump-queue-r5XKgJEV.js","assets/code-XfbSR8K2.js","assets/wrap-text-CZ613PM5.js","assets/CodeEditorPlugin-QXMSCH71.js","assets/file-content-BjxNaIfy.js","assets/file-socket-D9x_5vlY.js","assets/monaco-K8izTGgo.js","assets/useFileDiffOverlay-BH6KcMzq.js","assets/file-diff-panel-D_lLVQk0.js","assets/TextViewerPlugin-C3tCmFox.js","assets/index-PJbSbPTy.js","assets/MarkdownViewerPlugin-836PVQWV.js","assets/ImageViewerPlugin-CHJl_0lr.js","assets/image-BhWT33W1.js","assets/zoom-out-BgDLAv3z.js","assets/PdfViewerPlugin-BwtICzue.js","assets/pdf-effect-queue-DfBors6y.js","assets/PdfLoader-DzRaTAlq.js","assets/PdfLoader-C-Y707R3.css","assets/square-check-big-omoSUmcd.js","assets/PdfViewerPlugin-DQ11QcSf.css","assets/PdfMarkdownPlugin-DZUfIUnp.js","assets/NotebookEditor-DIX7Mlzu.js","assets/NotebookEditor-C3VQ7ylN.css","assets/CliPlugin-DrV8je02.js","assets/select-CAbJDfYv.js","assets/useCliAccess-D31UR23I.js","assets/LabPlugin-eQpPPCEp.js","assets/bot-BEA2vWuK.js","assets/index--c4iXtuy.js","assets/NotebookEditor-BRzJbGsn.js","assets/function-B5QZkkHC.js","assets/yjs-DncrqiZ8.js","assets/project-sync-PENr2zcz.js","assets/popover-yFK1J4fL.js","assets/trash--F119N47.js","assets/sigma-DEuYJqTl.js","assets/NotebookEditor-CccQYZjX.css","assets/LatexPlugin-BwRfi89Z.js","assets/GitDiffViewerPlugin-7J9h9Vy_.js","assets/SearchPlugin-DHeIAMsx.js","assets/SearchPlugin-DDMrGDkh.css","assets/MarketplacePlugin-C2y_556i.js","assets/AiManusChatView-D0mTXG4-.js","assets/LabCopilotPanel-1qSow1es.js"])))=>i.map(i=>d[i]);
1
+ const __vite__mapDeps=(i,m=__vite__mapDeps,d=(m.f||(m.f=["assets/CodeViewerPlugin-DT54ysXa.js","assets/file-jump-queue-r5XKgJEV.js","assets/code-Cd7WfiWq.js","assets/wrap-text-C7Qqh-om.js","assets/CodeEditorPlugin-B-xicq1e.js","assets/file-content-B57zsL9y.js","assets/file-socket-B5kXFxZP.js","assets/monaco-BGGAEii3.js","assets/useFileDiffOverlay-C2OQaVWc.js","assets/file-diff-panel-DVoheLFq.js","assets/TextViewerPlugin-C-nVAZb_.js","assets/index-Dxa2eYMY.js","assets/MarkdownViewerPlugin-BzdVH9Bx.js","assets/ImageViewerPlugin-OcVo33jV.js","assets/image-LLOjkMHF.js","assets/zoom-out-rtX0FKya.js","assets/PdfViewerPlugin-CmlDxbhU.js","assets/pdf-effect-queue-DlEr1_y5.js","assets/PdfLoader-CvcjJHXv.js","assets/PdfLoader-C-Y707R3.css","assets/square-check-big-DUK_mnkS.js","assets/PdfViewerPlugin-DQ11QcSf.css","assets/PdfMarkdownPlugin-DW2ej8Vk.js","assets/NotebookEditor-BMXKrDRk.js","assets/NotebookEditor-C3VQ7ylN.css","assets/CliPlugin-CB1YODQn.js","assets/select-CoHB7pvH.js","assets/useCliAccess-BrJBV3tY.js","assets/LabPlugin-Ciz1gDaX.js","assets/bot-C_G4WtNI.js","assets/index-C3r2iGrp.js","assets/NotebookEditor-BTVYRGkm.js","assets/function-B5QZkkHC.js","assets/yjs-DncrqiZ8.js","assets/project-sync-CRJiucYO.js","assets/popover-CWJbJuYY.js","assets/trash-ChU3SEE3.js","assets/sigma-D5aJWR8J.js","assets/NotebookEditor-CccQYZjX.css","assets/LatexPlugin-BhmjNQRC.js","assets/GitDiffViewerPlugin-hqHbCfnv.js","assets/SearchPlugin-DAjQZPSv.js","assets/SearchPlugin-DDMrGDkh.css","assets/MarketplacePlugin-DmyHspXt.js","assets/AiManusChatView-CnJcXynW.js","assets/LabCopilotPanel-DdGwhEUV.js"])))=>i.map(i=>d[i]);
2
2
  function _mergeNamespaces(n, m) {
3
3
  for (var i = 0; i < m.length; i++) {
4
4
  const e = m[i];
@@ -76685,7 +76685,7 @@ const DialogDescription = reactExports.forwardRef(({ className, ...props }, ref)
76685
76685
  ));
76686
76686
  DialogDescription.displayName = Description.displayName;
76687
76687
 
76688
- const COPY$1 = {
76688
+ const COPY$2 = {
76689
76689
  zh: {
76690
76690
  title: "发现新版本",
76691
76691
  body: "DeepScientist 检测到新的 npm 版本。请在终端运行下面这条命令完成更新。",
@@ -76717,7 +76717,7 @@ function SystemUpdateDialog({
76717
76717
  dismissing = false
76718
76718
  }) {
76719
76719
  const { locale } = useI18n$1();
76720
- const t = COPY$1[locale];
76720
+ const t = COPY$2[locale];
76721
76721
  const showResult = Boolean(status && !status.busy && status.last_update_result);
76722
76722
  const message = status?.last_update_result?.message || null;
76723
76723
  const command = status?.manual_update_command || "npm install -g @researai/deepscientist@latest";
@@ -111076,7 +111076,7 @@ const useOnboardingStore = create$3((set, get) => ({
111076
111076
  }
111077
111077
  }));
111078
111078
 
111079
- const COPY = {
111079
+ const COPY$1 = {
111080
111080
  en: {
111081
111081
  chooserTitle: "Choose your first tutorial",
111082
111082
  chooserBody: "DeepScientist can walk you through the first run step by step. Choose the guide language, skip for now, or turn the reminder off.",
@@ -111667,7 +111667,6 @@ function OnboardingOverlay() {
111667
111667
  language,
111668
111668
  startedFrom,
111669
111669
  hydrate,
111670
- maybeOpenFirstRunChooser,
111671
111670
  startTutorial,
111672
111671
  nextStep,
111673
111672
  previousStep,
@@ -111682,7 +111681,6 @@ function OnboardingOverlay() {
111682
111681
  language: state.language,
111683
111682
  startedFrom: state.startedFrom,
111684
111683
  hydrate: state.hydrate,
111685
- maybeOpenFirstRunChooser: state.maybeOpenFirstRunChooser,
111686
111684
  startTutorial: state.startTutorial,
111687
111685
  nextStep: state.nextStep,
111688
111686
  previousStep: state.previousStep,
@@ -111701,7 +111699,7 @@ function OnboardingOverlay() {
111701
111699
  const cardRef = reactExports.useRef(null);
111702
111700
  const step = status === "running" ? ONBOARDING_STEPS[stepIndex] ?? null : null;
111703
111701
  const activeLanguage = language === "zh" || language === "en" ? language : "en";
111704
- const copy = COPY[activeLanguage];
111702
+ const copy = COPY$1[activeLanguage];
111705
111703
  const isGuidedProjectRoute = /^\/projects\/demo-/.test(location.pathname);
111706
111704
  const exitTutorial = reactExports.useCallback(
111707
111705
  (mode) => {
@@ -111752,11 +111750,6 @@ function OnboardingOverlay() {
111752
111750
  close();
111753
111751
  }
111754
111752
  }, [close, isMobileViewport, status]);
111755
- reactExports.useEffect(() => {
111756
- if (!hydrated) return;
111757
- if (isMobileViewport) return;
111758
- maybeOpenFirstRunChooser(location.pathname);
111759
- }, [hydrated, isMobileViewport, location.pathname, maybeOpenFirstRunChooser]);
111760
111753
  reactExports.useEffect(() => {
111761
111754
  if (status !== "running" || !step) {
111762
111755
  setTargetRect(null);
@@ -114827,6 +114820,9 @@ const settingsCatalogZh = {
114827
114820
  "Config directory": "配置目录",
114828
114821
  "Global runner home used for auth and global configuration.": "用于认证和全局配置的 runner 主目录。",
114829
114822
  "Point this to the runner home directory that stores auth and global config files.": "指向存放认证信息和全局配置文件的 runner 主目录。",
114823
+ "Codex profile": "Codex 配置档",
114824
+ "Optional Codex profile passed through as `codex --profile <name>`.": "可选的 Codex 配置档,会直接透传为 `codex --profile <name>`。",
114825
+ "Use this for provider-specific Codex setups such as MiniMax or other custom profiles. Leave it empty for the default login-based Codex path.": "当你使用 MiniMax 或其他自定义 provider 的 Codex 配置时填写这里;如果走默认的登录式 Codex 路径,就保持为空。",
114830
114826
  "Default model": "默认模型",
114831
114827
  "Default model used when the project or request does not override it.": "当项目或请求未覆盖时所使用的默认模型。",
114832
114828
  "Use the model id accepted by the selected runner.": "填写当前 runner 支持的模型 ID。",
@@ -119370,6 +119366,14 @@ const runnerFields = [
119370
119366
  description: "Global runner home used for auth and global configuration.",
119371
119367
  whereToGet: "Point this to the runner home directory that stores auth and global config files."
119372
119368
  },
119369
+ {
119370
+ key: "profile",
119371
+ label: "Codex profile",
119372
+ kind: "text",
119373
+ placeholder: "m27",
119374
+ description: "Optional Codex profile passed through as `codex --profile <name>`.",
119375
+ whereToGet: "Use this for provider-specific Codex setups such as MiniMax or other custom profiles. Leave it empty for the default login-based Codex path."
119376
+ },
119373
119377
  {
119374
119378
  key: "model",
119375
119379
  label: "Default model",
@@ -132225,8 +132229,12 @@ function defaultStartResearchTemplate(language) {
132225
132229
  decision_policy: "autonomous",
132226
132230
  launch_mode: "standard",
132227
132231
  custom_profile: "freeform",
132232
+ review_followup_policy: "audit_only",
132233
+ baseline_execution_policy: "auto",
132234
+ manuscript_edit_mode: "none",
132228
132235
  entry_state_summary: "",
132229
132236
  review_summary: "",
132237
+ review_materials: "",
132230
132238
  custom_brief: "",
132231
132239
  user_language: language
132232
132240
  };
@@ -132316,8 +132324,12 @@ function listReferenceStartResearchTemplates() {
132316
132324
  decision_policy: "autonomous",
132317
132325
  launch_mode: "standard",
132318
132326
  custom_profile: "freeform",
132327
+ review_followup_policy: "audit_only",
132328
+ baseline_execution_policy: "auto",
132329
+ manuscript_edit_mode: "none",
132319
132330
  entry_state_summary: "",
132320
132331
  review_summary: "",
132332
+ review_materials: "",
132321
132333
  custom_brief: "",
132322
132334
  user_language: "zh"
132323
132335
  };
@@ -132359,8 +132371,12 @@ function listReferenceStartResearchTemplates() {
132359
132371
  decision_policy: "autonomous",
132360
132372
  launch_mode: "standard",
132361
132373
  custom_profile: "freeform",
132374
+ review_followup_policy: "audit_only",
132375
+ baseline_execution_policy: "auto",
132376
+ manuscript_edit_mode: "none",
132362
132377
  entry_state_summary: "",
132363
132378
  review_summary: "",
132379
+ review_materials: "",
132364
132380
  custom_brief: "",
132365
132381
  user_language: "en"
132366
132382
  };
@@ -132414,11 +132430,32 @@ function sanitizeLaunchMode(value) {
132414
132430
  }
132415
132431
  function sanitizeCustomProfile(value) {
132416
132432
  const normalized = String(value || "").trim().toLowerCase();
132417
- if (normalized === "continue_existing_state" || normalized === "revision_rebuttal" || normalized === "freeform") {
132433
+ if (normalized === "continue_existing_state" || normalized === "review_audit" || normalized === "revision_rebuttal" || normalized === "freeform") {
132418
132434
  return normalized;
132419
132435
  }
132420
132436
  return "freeform";
132421
132437
  }
132438
+ function sanitizeBaselineExecutionPolicy(value) {
132439
+ const normalized = String(value || "").trim().toLowerCase();
132440
+ if (normalized === "auto" || normalized === "must_reproduce_or_verify" || normalized === "reuse_existing_only" || normalized === "skip_unless_blocking") {
132441
+ return normalized;
132442
+ }
132443
+ return "auto";
132444
+ }
132445
+ function sanitizeReviewFollowupPolicy(value) {
132446
+ const normalized = String(value || "").trim().toLowerCase();
132447
+ if (normalized === "audit_only" || normalized === "auto_execute_followups" || normalized === "user_gated_followups") {
132448
+ return normalized;
132449
+ }
132450
+ return "audit_only";
132451
+ }
132452
+ function sanitizeManuscriptEditMode(value) {
132453
+ const normalized = String(value || "").trim().toLowerCase();
132454
+ if (normalized === "none" || normalized === "copy_ready_text" || normalized === "latex_required") {
132455
+ return normalized;
132456
+ }
132457
+ return "none";
132458
+ }
132422
132459
  function sanitizeLines$1(text) {
132423
132460
  return text.split("\n").map((item) => item.trim()).filter(Boolean);
132424
132461
  }
@@ -132449,8 +132486,12 @@ function sanitizeTemplate(input) {
132449
132486
  decision_policy: sanitizeDecisionPolicy(input.decision_policy),
132450
132487
  launch_mode: sanitizeLaunchMode(input.launch_mode),
132451
132488
  custom_profile: sanitizeCustomProfile(input.custom_profile),
132489
+ review_followup_policy: sanitizeReviewFollowupPolicy(input.review_followup_policy),
132490
+ baseline_execution_policy: sanitizeBaselineExecutionPolicy(input.baseline_execution_policy),
132491
+ manuscript_edit_mode: sanitizeManuscriptEditMode(input.manuscript_edit_mode),
132452
132492
  entry_state_summary: String(input.entry_state_summary || "").trim(),
132453
132493
  review_summary: String(input.review_summary || "").trim(),
132494
+ review_materials: String(input.review_materials || "").trim(),
132454
132495
  custom_brief: String(input.custom_brief || "").trim(),
132455
132496
  user_language: input.user_language === "en" ? "en" : "zh"
132456
132497
  };
@@ -132499,10 +132540,44 @@ function labelCustomProfile(value) {
132499
132540
  switch (value) {
132500
132541
  case "continue_existing_state":
132501
132542
  return "Continue existing state: audit and normalize an existing baseline, result, draft, or mixed project state before deciding the next anchor.";
132543
+ case "review_audit":
132544
+ return "Review / audit: treat the current draft or paper package as the active contract and run an independent skeptical review before more writing or finalization.";
132502
132545
  case "revision_rebuttal":
132503
132546
  return "Revision / rebuttal: treat the current paper and reviewer package as the active contract, then route supplementary experiments and manuscript edits from that state.";
132504
132547
  default:
132505
- return "Freeform: follow the user-defined custom brief and open only the skills actually needed.";
132548
+ return "Other / freeform: follow the user-defined custom brief and open only the skills actually needed.";
132549
+ }
132550
+ }
132551
+ function labelBaselineExecutionPolicy(value) {
132552
+ switch (value) {
132553
+ case "must_reproduce_or_verify":
132554
+ return "Reproduce or verify first: explicitly recover or verify the rebuttal-critical baseline/comparator before reviewer-linked follow-up work.";
132555
+ case "reuse_existing_only":
132556
+ return "Reuse existing only: start from the trusted current baseline and do not rerun it unless the stored evidence is inconsistent or unusable.";
132557
+ case "skip_unless_blocking":
132558
+ return "Skip unless blocking: do not spend time rerunning baselines by default; only do it if a reviewer-linked item truly depends on a missing comparator.";
132559
+ default:
132560
+ return "Automatic: let the startup contract and current evidence decide whether rebuttal work should verify, reuse, or skip baseline reruns.";
132561
+ }
132562
+ }
132563
+ function labelReviewFollowupPolicy(value) {
132564
+ switch (value) {
132565
+ case "auto_execute_followups":
132566
+ return "Auto-execute follow-ups: after the audit artifacts are durable, continue automatically into the required experiments, manuscript deltas, and closure work.";
132567
+ case "user_gated_followups":
132568
+ return "User-gated follow-ups: finish the audit first, then turn the next major experiment/revision package into a structured decision if continuation depends on user approval.";
132569
+ default:
132570
+ return "Audit only: stop after the review artifacts and route recommendation are durable.";
132571
+ }
132572
+ }
132573
+ function labelManuscriptEditMode(value) {
132574
+ switch (value) {
132575
+ case "copy_ready_text":
132576
+ return "Copy-ready text: produce manuscript-facing revision text and section-level deltas, but do not require LaTeX-specific delivery.";
132577
+ case "latex_required":
132578
+ return "LaTeX required: when manuscript revision is needed, prefer the provided LaTeX tree as the writing surface and produce LaTeX-ready replacement text; if LaTeX source is unavailable, make that blocker explicit.";
132579
+ default:
132580
+ return "No manuscript edit package is required by default beyond the review/rebuttal planning artifacts.";
132506
132581
  }
132507
132582
  }
132508
132583
  function labelScope(value) {
@@ -132599,18 +132674,40 @@ function customLaunchLines(input) {
132599
132674
  if (normalized.entry_state_summary) {
132600
132675
  lines.push("- Existing state summary:", normalized.entry_state_summary);
132601
132676
  }
132602
- if (normalized.review_summary) {
132677
+ if ((normalized.custom_profile === "review_audit" || normalized.custom_profile === "revision_rebuttal") && normalized.review_summary) {
132603
132678
  lines.push("- Review / revision summary:", normalized.review_summary);
132604
132679
  }
132680
+ if ((normalized.custom_profile === "review_audit" || normalized.custom_profile === "revision_rebuttal") && normalized.review_materials) {
132681
+ lines.push("- Review materials (URLs or local paths/directories):");
132682
+ lines.push(...sanitizeLines$1(normalized.review_materials).map((item) => ` - ${item}`));
132683
+ }
132605
132684
  if (normalized.custom_brief) {
132606
132685
  lines.push("- Custom brief:", normalized.custom_brief);
132607
132686
  }
132687
+ if (normalized.custom_profile === "review_audit") {
132688
+ lines.push(`- Review follow-up policy: ${labelReviewFollowupPolicy(normalized.review_followup_policy)}`);
132689
+ }
132690
+ lines.push(`- Baseline execution policy: ${labelBaselineExecutionPolicy(normalized.baseline_execution_policy)}`);
132691
+ if (normalized.custom_profile === "review_audit" || normalized.custom_profile === "revision_rebuttal") {
132692
+ lines.push(`- Manuscript edit mode: ${labelManuscriptEditMode(normalized.manuscript_edit_mode)}`);
132693
+ }
132608
132694
  if (normalized.custom_profile === "continue_existing_state") {
132609
132695
  lines.push("- First action: audit and trust-rank existing baselines, results, drafts, or review assets before rerunning expensive work.");
132610
132696
  lines.push("- Prefer `intake-audit` first if the starting state is not already normalized.");
132697
+ } else if (normalized.custom_profile === "review_audit") {
132698
+ lines.push("- First action: inspect the current manuscript and run an independent skeptical audit before further drafting or finalization.");
132699
+ lines.push("- Prefer `review` first, and only route to extra experiments when the audit shows the current evidence is genuinely insufficient.");
132700
+ if (normalized.review_followup_policy === "auto_execute_followups") {
132701
+ lines.push("- After the audit artifacts are durable, continue automatically into the required experiments, manuscript deltas, and review-closure work.");
132702
+ } else if (normalized.review_followup_policy === "user_gated_followups") {
132703
+ lines.push("- After the audit artifacts are durable, turn the next expensive follow-up package into a structured decision before continuing.");
132704
+ } else {
132705
+ lines.push("- Stop after the durable audit artifacts unless the user later asks for execution follow-up.");
132706
+ }
132611
132707
  } else if (normalized.custom_profile === "revision_rebuttal") {
132612
132708
  lines.push("- First action: interpret reviewer comments and current paper state before ordinary writing or fresh ideation.");
132613
132709
  lines.push("- Prefer `rebuttal` first, and route supplementary runs only when a reviewer issue genuinely requires them.");
132710
+ lines.push("- If a manuscript PDF, reviewer packet, or local review directory is already known, inspect and normalize those inputs before planning reviewer-linked experiments.");
132614
132711
  } else {
132615
132712
  lines.push("- First action: follow the custom brief and open only the minimum necessary skills.");
132616
132713
  }
@@ -132640,7 +132737,7 @@ function compileStartResearchPrompt(input) {
132640
132737
  "Baseline Context",
132641
132738
  baselineContext,
132642
132739
  "",
132643
- "Reference Papers / Repositories",
132740
+ "Reference Papers / Repositories / Local Paths",
132644
132741
  paperUrls.length > 0 ? paperUrls.map((url) => `- ${url}`).join("\n") : "- None provided",
132645
132742
  "",
132646
132743
  "Operational Constraints",
@@ -132662,6 +132759,9 @@ function compileStartResearchPrompt(input) {
132662
132759
  `- Research paper required: ${normalized.need_research_paper ? "Yes" : "No; optimize for the strongest justified algorithmic result."}`,
132663
132760
  `- Scope: ${labelScope(derivedContract.scope)}`,
132664
132761
  `- Baseline policy: ${labelBaselineMode(derivedContract.baseline_mode)}`,
132762
+ `- Review follow-up policy: ${normalized.custom_profile === "review_audit" ? labelReviewFollowupPolicy(normalized.review_followup_policy) : "Not applicable outside the Review custom task type."}`,
132763
+ `- Baseline execution policy: ${normalized.launch_mode === "custom" ? labelBaselineExecutionPolicy(normalized.baseline_execution_policy) : "Standard baseline handling from the ordinary research loop."}`,
132764
+ `- Manuscript edit mode: ${normalized.custom_profile === "review_audit" || normalized.custom_profile === "revision_rebuttal" ? labelManuscriptEditMode(normalized.manuscript_edit_mode) : "No manuscript-facing custom edit contract requested."}`,
132665
132765
  `- Resource policy: ${labelResourcePolicy(derivedContract.resource_policy)}`,
132666
132766
  `- Git strategy: ${labelGitStrategy(derivedContract.git_strategy)}`,
132667
132767
  `- Time budget per research round: ${derivedContract.time_budget_hours} hour(s)`,
@@ -132673,6 +132773,7 @@ function compileStartResearchPrompt(input) {
132673
132773
  "- Emit explicit milestone updates after each meaningful step.",
132674
132774
  "- Every decision must include reasons, evidence, and the next recommended action.",
132675
132775
  "- If the startup contract already fixes the delivery mode and baseline policy, follow it without asking the user again unless cost, safety, or scope changes materially.",
132776
+ normalized.manuscript_edit_mode === "latex_required" ? "- If manuscript edits are required, prefer the provided LaTeX tree as the writing surface; if LaTeX source is unavailable, produce LaTeX-ready replacement text and state the blocker explicitly." : "- If manuscript edits are required, make the section-level deltas explicit and keep the replacement wording copy-ready.",
132676
132777
  normalized.decision_policy === "autonomous" ? "- Autonomous mode is the default contract here: decide the route yourself and continue unless you are requesting explicit completion approval." : "- User-gated mode is enabled here: if local evidence is insufficient for a safe route decision, ask the user with one blocking decision request."
132677
132778
  ].join("\n");
132678
132779
  }
@@ -132830,19 +132931,31 @@ const copy$2 = {
132830
132931
  basics: "Core research brief",
132831
132932
  references: "Baseline & references",
132832
132933
  policy: "Research contract",
132833
- launchModeLabel: "Launch mode",
132834
- launchModeHelp: "Standard starts from the ordinary research loop. Custom is for continuing existing state, rebuttal / revision, or a user-defined brief.",
132835
- customProfileLabel: "Custom profile",
132836
- customProfileHelp: "Only shown in custom mode. Use it to tell the agent whether this project should first audit existing state, handle rebuttal work, or follow a freeform brief.",
132934
+ launchModeLabel: "Launch path",
132935
+ launchModeHelp: "First choose whether this project should follow the ordinary research workflow or enter through a custom task type.",
132936
+ standardProfileLabel: "Entry type",
132937
+ standardProfileHelp: "In Standard mode, this stays on the canonical research workflow.",
132938
+ customProfileLabel: "Entry type",
132939
+ customProfileHelp: "In Custom mode, choose what kind of entry this is: continue existing state, run a review audit, handle rebuttal / revision, or follow a freeform brief.",
132940
+ reviewFollowupPolicyLabel: "Review follow-up",
132941
+ reviewFollowupPolicyHelp: "Only meaningful for the Review task type. Use this to decide whether the system should stop after the audit, continue automatically into experiments and manuscript updates, or pause for approval after the audit.",
132942
+ baselineExecutionPolicyLabel: "Baseline handling",
132943
+ baselineExecutionPolicyHelp: "Only shown in custom mode. Use this to tell the agent whether it should verify/reproduce a baseline first, reuse current evidence only, or skip baseline reruns unless a reviewer-linked issue truly blocks on them.",
132944
+ manuscriptEditModeLabel: "Manuscript update mode",
132945
+ manuscriptEditModeHelp: "Use this to control whether the system should only give review/rebuttal planning artifacts, produce copy-ready revision text, or require LaTeX-ready revision text and edits.",
132837
132946
  entryStateSummaryLabel: "Existing state summary",
132838
132947
  entryStateSummaryHelp: "Briefly describe what already exists, such as a trusted baseline, finished main runs, analysis results, or a paper draft.",
132839
132948
  entryStateSummaryPlaceholder: "Example: baseline is already trusted; one main experiment has finished; draft introduction and method sections already exist.",
132840
132949
  reviewSummaryLabel: "Review / revision summary",
132841
132950
  reviewSummaryHelp: "Use this when the project is driven by reviewer comments, a revision request, or a meta-review.",
132842
132951
  reviewSummaryPlaceholder: "Example: reviewers asked for stronger ablations, one extra baseline, and a clearer limitation discussion.",
132952
+ reviewMaterialsLabel: "Reviewer / revision materials",
132953
+ reviewMaterialsHelp: "Use one URL or one absolute local file/folder path per line for reviewer comments, a decision letter, meta-review notes, or a revision packet.",
132954
+ reviewMaterialsPlaceholder: "Example: /data/rebuttal/review_comments.md or https://openreview.net/forum?id=demo",
132843
132955
  customBriefLabel: "Custom brief",
132844
132956
  customBriefHelp: "Any extra task-specific instruction that should override the standard full-research launch behavior.",
132845
132957
  customBriefPlaceholder: "Example: do not rerun the baseline; first normalize existing results, then decide whether supplementary analysis is still needed.",
132958
+ manuscriptEditModeNote: "If `LaTeX required` is selected, provide the LaTeX source tree or a local LaTeX folder path in the manuscript/reference inputs when possible.",
132846
132959
  researchIntensityLabel: "Research intensity",
132847
132960
  researchIntensityHelp: "Choose how much the first autonomous research round should attempt before reporting back.",
132848
132961
  decisionPolicyLabel: "Decision mode",
@@ -132869,12 +132982,12 @@ const copy$2 = {
132869
132982
  baselineRootHelp: "Pick a previously confirmed reusable baseline entry from the global registry. Runtime will attach and confirm it before the new project starts.",
132870
132983
  baselineVariant: "Baseline variant",
132871
132984
  baselineVariantHelp: "Optional: choose a specific baseline variant when the entry contains multiple variants.",
132872
- baselineUrls: "Baseline links",
132873
- baselineUrlsPlaceholder: "One repository or artifact URL per line",
132874
- baselineUrlsHelp: "Provide source repositories or artifacts that help recover the baseline quickly.",
132875
- paperUrls: "Reference papers / repos",
132876
- paperUrlsPlaceholder: "Relevant papers, code, benchmarks, or leaderboards",
132877
- paperUrlsHelp: "These references help the agent scope the problem and compare against prior work.",
132985
+ baselineUrls: "Baseline links / local paths",
132986
+ baselineUrlsPlaceholder: "One URL or one absolute local file/folder path per line",
132987
+ baselineUrlsHelp: "Provide repositories, artifacts, or local file/folder paths that help recover the baseline quickly.",
132988
+ paperUrls: "Paper / reference sources",
132989
+ paperUrlsPlaceholder: "Papers, repos, or absolute local file/folder paths",
132990
+ paperUrlsHelp: "These references can be web links or local file/folder paths. Use them for manuscripts, code, benchmarks, or leaderboards.",
132878
132991
  runtimeConstraintsLabel: "Runtime constraints",
132879
132992
  runtimeConstraintsPlaceholder: "Budget, hardware, privacy, storage, data access, or deadline constraints",
132880
132993
  runtimeConstraintsHelp: "Anything here becomes a hard operating rule for the first research round.",
@@ -132946,13 +133059,97 @@ const copy$2 = {
132946
133059
  manual_integration_only: "Manual integration only — avoid automatic integration and require explicit merge decisions."
132947
133060
  },
132948
133061
  launchModeOptions: {
132949
- standard: "Standard — start from the ordinary research graph.",
132950
- custom: "Custom — continue existing state, rebuttal/revision, or a user-defined brief."
133062
+ standard: "Standard workflow follow the ordinary research graph.",
133063
+ custom: "Custom entry — continue existing state, review, rebuttal/revision, or a user-defined brief."
133064
+ },
133065
+ standardProfileChoiceOption: {
133066
+ title: "Canonical research workflow",
133067
+ meta: "Standard path",
133068
+ body: "Stay on the normal full-research route: baseline, idea, experiment, analysis, and then paper work when justified."
132951
133069
  },
132952
133070
  customProfileOptions: {
132953
133071
  continue_existing_state: "Continue existing state — first audit baselines, results, drafts, and current project assets.",
133072
+ review_audit: "Review — run an independent skeptical audit on the current draft or paper package.",
132954
133073
  revision_rebuttal: "Revision / rebuttal — first interpret reviews, then route extra experiments and writing updates.",
132955
- freeform: "Freeform — follow the custom brief and use only the skills actually needed."
133074
+ freeform: "Other / freeform — follow the custom brief and use only the skills actually needed."
133075
+ },
133076
+ customProfileChoiceOptions: {
133077
+ continue_existing_state: {
133078
+ title: "Continue existing state",
133079
+ meta: "Reuse-first",
133080
+ body: "Audit existing baselines, results, drafts, and mixed project assets before deciding whether anything expensive must be rerun."
133081
+ },
133082
+ review_audit: {
133083
+ title: "Review",
133084
+ meta: "Skeptical audit",
133085
+ body: "Use the current draft or paper package as the active contract and run an independent skeptical review before more writing or finalization."
133086
+ },
133087
+ revision_rebuttal: {
133088
+ title: "Rebuttal / revision",
133089
+ meta: "Reviewer-driven",
133090
+ body: "Treat reviewer comments, a revision packet, or a decision letter as the active contract. First map comments to actions, then run only the necessary supplementary work."
133091
+ },
133092
+ freeform: {
133093
+ title: "Other / freeform",
133094
+ meta: "User-defined",
133095
+ body: "Follow the custom brief and open only the skills actually needed. Use this when the task does not match the standard custom entry types."
133096
+ }
133097
+ },
133098
+ baselineExecutionPolicyOptions: {
133099
+ auto: {
133100
+ title: "Automatic",
133101
+ meta: "Recommended",
133102
+ body: "Let the startup contract and current evidence decide whether rebuttal work should verify, reuse, or skip baseline reruns."
133103
+ },
133104
+ must_reproduce_or_verify: {
133105
+ title: "Verify / reproduce first",
133106
+ meta: "Baseline-first",
133107
+ body: "Before reviewer-linked follow-up work, recover or verify the baseline/comparator that the rebuttal depends on."
133108
+ },
133109
+ reuse_existing_only: {
133110
+ title: "Reuse existing only",
133111
+ meta: "No fresh rerun",
133112
+ body: "Trust the current baseline evidence and do not rerun it unless stored results look inconsistent or unusable."
133113
+ },
133114
+ skip_unless_blocking: {
133115
+ title: "Skip unless blocking",
133116
+ meta: "Rebuttal-first",
133117
+ body: "Do not spend time rerunning baselines by default. Only do it if a named reviewer-linked issue truly requires a missing comparator."
133118
+ }
133119
+ },
133120
+ reviewFollowupPolicyOptions: {
133121
+ audit_only: {
133122
+ title: "Audit only",
133123
+ meta: "Stop after review",
133124
+ body: "Finish the skeptical audit artifacts and stop with a route recommendation instead of running follow-up experiments or manuscript edits automatically."
133125
+ },
133126
+ auto_execute_followups: {
133127
+ title: "Auto execute",
133128
+ meta: "Run and revise",
133129
+ body: "After the audit artifacts are durable, continue automatically into the necessary experiments, manuscript deltas, and review-closure work."
133130
+ },
133131
+ user_gated_followups: {
133132
+ title: "Ask after audit",
133133
+ meta: "Approval gate",
133134
+ body: "Finish the audit first, then raise a structured decision before expensive experiments or manuscript revisions continue."
133135
+ }
133136
+ },
133137
+ manuscriptEditModeOptions: {
133138
+ none: {
133139
+ title: "No manuscript edits",
133140
+ meta: "Planning only",
133141
+ body: "Limit output to audit / rebuttal planning artifacts and route recommendations."
133142
+ },
133143
+ copy_ready_text: {
133144
+ title: "Copy-ready text",
133145
+ meta: "Section deltas",
133146
+ body: "Produce manuscript-facing revision text and section-level replacement wording, without requiring LaTeX-specific delivery."
133147
+ },
133148
+ latex_required: {
133149
+ title: "LaTeX required",
133150
+ meta: "LaTeX-ready",
133151
+ body: "When manuscript revision is needed, prefer the provided LaTeX tree as the writing surface and produce LaTeX-ready replacement text; if LaTeX source is missing, make that blocker explicit."
133152
+ }
132956
133153
  }
132957
133154
  },
132958
133155
  zh: {
@@ -133007,19 +133204,31 @@ const copy$2 = {
133007
133204
  basics: "核心研究简述",
133008
133205
  references: "Baseline 与参考",
133009
133206
  policy: "研究合同",
133010
- launchModeLabel: "启动模式",
133011
- launchModeHelp: "Standard 表示按普通科研主线启动;Custom 用于继续已有状态、处理 rebuttal / revision,或执行自定义研究任务。",
133012
- customProfileLabel: "自定义档位",
133013
- customProfileHelp: "仅在 Custom 模式下显示。用来告诉 agent 这是继续已有状态、处理审稿回复,还是一个自由定制任务。",
133207
+ launchModeLabel: "启动路径",
133208
+ launchModeHelp: "先选择这次项目是走普通科研工作流,还是通过自定义任务入口启动。",
133209
+ standardProfileLabel: "入口类型",
133210
+ standardProfileHelp: " Standard 模式下,这里固定为普通科研工作流。",
133211
+ customProfileLabel: "入口类型",
133212
+ customProfileHelp: "在 Custom 模式下,选择这次启动属于哪一种入口:继续已有状态、Review、Rebuttal / Revision,还是自由任务。",
133213
+ reviewFollowupPolicyLabel: "Review 后续动作",
133214
+ reviewFollowupPolicyHelp: "仅对 Review 任务类型有意义。用来决定系统是在审计后停止,还是自动继续补实验和改稿,还是先审计再等待你的批准。",
133215
+ baselineExecutionPolicyLabel: "Baseline 处理方式",
133216
+ baselineExecutionPolicyHelp: "仅在 Custom 模式下显示。用来明确告诉 agent:是先验证/复现 baseline,还是只复用现有证据,还是除非 reviewer-linked 问题卡住否则先跳过 baseline 重跑。",
133217
+ manuscriptEditModeLabel: "论文修改模式",
133218
+ manuscriptEditModeHelp: "用来控制系统是只输出 review/rebuttal 规划产物,还是给出可直接使用的修改文本,还是要求 LaTeX-ready 的修改文本和编辑结果。",
133014
133219
  entryStateSummaryLabel: "已有状态摘要",
133015
133220
  entryStateSummaryHelp: "简要写清当前已经有什么,例如可信 baseline、主实验结果、分析结果、论文草稿等。",
133016
133221
  entryStateSummaryPlaceholder: "例如:baseline 已可信;一个主实验已完成;引言和方法草稿已存在。",
133017
133222
  reviewSummaryLabel: "审稿 / 修改摘要",
133018
133223
  reviewSummaryHelp: "当项目由 reviewer comments、revision request 或 meta-review 驱动时,在这里概括主要要求。",
133019
133224
  reviewSummaryPlaceholder: "例如:reviewer 要求补更强的 ablation、增加一个 baseline、并澄清 limitation。",
133225
+ reviewMaterialsLabel: "审稿 / 修改材料",
133226
+ reviewMaterialsHelp: "每行填写一个 URL,或一个绝对本地文件/文件夹路径,用于 reviewer comments、decision letter、meta-review 或 revision packet。",
133227
+ reviewMaterialsPlaceholder: "例如:/data/rebuttal/review_comments.md 或 https://openreview.net/forum?id=demo",
133020
133228
  customBriefLabel: "自定义说明",
133021
133229
  customBriefHelp: "任何需要覆盖标准 full research 启动方式的额外任务说明,都可以写在这里。",
133022
133230
  customBriefPlaceholder: "例如:不要重新跑 baseline;先整理现有结果,再决定是否需要额外分析实验。",
133231
+ manuscriptEditModeNote: "如果选择了 `LaTeX required`,尽量在论文/参考输入里提供 LaTeX 源目录或本地 LaTeX 文件夹路径。",
133023
133232
  researchIntensityLabel: "研究投入强度",
133024
133233
  researchIntensityHelp: "只需决定第一轮自治研究准备投入到什么程度,其余执行策略会自动推导。",
133025
133234
  decisionPolicyLabel: "决策模式",
@@ -133046,12 +133255,12 @@ const copy$2 = {
133046
133255
  baselineRootHelp: "选择全局 registry 中已经确认可复用的 baseline。运行时会在新项目创建前自动 attach 并 confirm;留空则从零开始建立 baseline。",
133047
133256
  baselineVariant: "Baseline variant",
133048
133257
  baselineVariantHelp: "可选:当 baseline entry 里包含多个 variant 时,可以在这里指定。",
133049
- baselineUrls: "Baseline 链接",
133050
- baselineUrlsPlaceholder: "每行一个仓库或 artifact 链接",
133051
- baselineUrlsHelp: "这些链接用于帮助系统更快恢复或修复 baseline。",
133052
- paperUrls: "参考论文 / 仓库",
133053
- paperUrlsPlaceholder: "相关论文、代码、benchmark 或 leaderboard",
133054
- paperUrlsHelp: "这些参考资料会帮助 agent 更好地界定问题和比较工作。",
133258
+ baselineUrls: "Baseline 链接 / 本地路径",
133259
+ baselineUrlsPlaceholder: "每行一个 URL,或一个绝对本地文件/文件夹路径",
133260
+ baselineUrlsHelp: "这些来源既可以是仓库、artifact,也可以是本地文件或文件夹路径,用于帮助系统更快恢复或修复 baseline。",
133261
+ paperUrls: "论文 / 参考来源",
133262
+ paperUrlsPlaceholder: "论文、仓库,或绝对本地文件/文件夹路径",
133263
+ paperUrlsHelp: "这些参考来源既可以是网络链接,也可以是本地文件或文件夹路径,可用于论文、代码、benchmark leaderboard。",
133055
133264
  runtimeConstraintsLabel: "运行约束",
133056
133265
  runtimeConstraintsPlaceholder: "预算、硬件、隐私、存储、数据访问、截止时间等限制",
133057
133266
  runtimeConstraintsHelp: "写在这里的内容会被视为第一轮研究中的硬性运行约束。",
@@ -133123,13 +133332,97 @@ const copy$2 = {
133123
133332
  manual_integration_only: "仅手动集成 —— 避免自动集成,所有合并都需要显式决策。"
133124
133333
  },
133125
133334
  launchModeOptions: {
133126
- standard: "Standard —— 按普通科研图谱启动。",
133127
- custom: "Custom —— 继续已有状态、处理 rebuttal/revision,或执行用户自定义任务。"
133335
+ standard: "标准工作流 —— 按普通科研图谱推进。",
133336
+ custom: "自定义入口 —— 继续已有状态、做 Review、处理 rebuttal/revision,或执行自定义任务。"
133337
+ },
133338
+ standardProfileChoiceOption: {
133339
+ title: "普通科研工作流",
133340
+ meta: "标准主线",
133341
+ body: "沿用常规 full research 路线:baseline、方向选择、主实验、补充分析,以及在证据足够后进入论文工作。"
133128
133342
  },
133129
133343
  customProfileOptions: {
133130
133344
  continue_existing_state: "继续已有状态 —— 先审计 baseline、结果、草稿和现有项目资产。",
133345
+ review_audit: "Review —— 先对当前 draft / paper package 做一次独立、skeptical 的审计。",
133131
133346
  revision_rebuttal: "审稿修改 / rebuttal —— 先解析 review,再决定补实验和改文。",
133132
- freeform: "自由模式 —— 以自定义 brief 为主,只打开真正需要的 skills。"
133347
+ freeform: "其它 / 自由模式 —— 以自定义 brief 为主,只打开真正需要的 skills。"
133348
+ },
133349
+ customProfileChoiceOptions: {
133350
+ continue_existing_state: {
133351
+ title: "继续已有状态",
133352
+ meta: "先复用",
133353
+ body: "先审计现有 baseline、结果、草稿和混合资产,再决定是否真的需要重跑任何昂贵步骤。"
133354
+ },
133355
+ review_audit: {
133356
+ title: "Review",
133357
+ meta: "独立审计",
133358
+ body: "把当前 draft / paper package 当作主动合同,先做一次独立、skeptical 的审阅,再决定是否继续写作或收尾。"
133359
+ },
133360
+ revision_rebuttal: {
133361
+ title: "Rebuttal / Revision",
133362
+ meta: "审稿驱动",
133363
+ body: "把 reviewer comments、revision packet 或 decision letter 当作主动合同。先拆评论,再只补真正必要的实验和改文。"
133364
+ },
133365
+ freeform: {
133366
+ title: "其它 / 自定义",
133367
+ meta: "用户自定义",
133368
+ body: "以 custom brief 为主,只打开真正需要的 skills。适合不完全属于标准 custom 入口类型的任务。"
133369
+ }
133370
+ },
133371
+ baselineExecutionPolicyOptions: {
133372
+ auto: {
133373
+ title: "自动",
133374
+ meta: "推荐",
133375
+ body: "让启动合同和当前证据自己决定 rebuttal 阶段应该验证、复用还是跳过 baseline 重跑。"
133376
+ },
133377
+ must_reproduce_or_verify: {
133378
+ title: "先验证 / 复现",
133379
+ meta: "Baseline 优先",
133380
+ body: "在 reviewer-linked 的后续工作之前,先恢复或验证 rebuttal 真正依赖的 baseline / comparator。"
133381
+ },
133382
+ reuse_existing_only: {
133383
+ title: "只复用现有",
133384
+ meta: "不新跑",
133385
+ body: "默认信任当前已有 baseline 证据;除非现有结果不一致或不可用,否则不重新跑。"
133386
+ },
133387
+ skip_unless_blocking: {
133388
+ title: "除非卡住否则跳过",
133389
+ meta: "Rebuttal 优先",
133390
+ body: "默认先不花时间重跑 baseline;只有当某个 reviewer-linked 问题明确依赖缺失 comparator 时才补跑。"
133391
+ }
133392
+ },
133393
+ reviewFollowupPolicyOptions: {
133394
+ audit_only: {
133395
+ title: "只做审计",
133396
+ meta: "审后停止",
133397
+ body: "完成 skeptical 审计产物后就停止,只给出路由建议,不自动补实验或改稿。"
133398
+ },
133399
+ auto_execute_followups: {
133400
+ title: "自动继续执行",
133401
+ meta: "补实验并改稿",
133402
+ body: "当审计产物落盘后,自动继续进入必要的实验、论文修改和 review closure 工作。"
133403
+ },
133404
+ user_gated_followups: {
133405
+ title: "审后再问我",
133406
+ meta: "批准门",
133407
+ body: "先完成审计,再把昂贵实验或改稿动作整理成结构化决策,等待你的批准后继续。"
133408
+ }
133409
+ },
133410
+ manuscriptEditModeOptions: {
133411
+ none: {
133412
+ title: "不改论文",
133413
+ meta: "只做规划",
133414
+ body: "只输出审计 / rebuttal 规划产物和路由建议,不要求进一步生成可直接替换的论文文本。"
133415
+ },
133416
+ copy_ready_text: {
133417
+ title: "可直接改写文本",
133418
+ meta: "段落替换",
133419
+ body: "输出面向论文的修改文本和 section-level 替换建议,但不强制要求 LaTeX 格式。"
133420
+ },
133421
+ latex_required: {
133422
+ title: "LaTeX required",
133423
+ meta: "LaTeX-ready",
133424
+ body: "当需要修改论文时,优先把提供的 LaTeX 树当作写作表面,并输出 LaTeX-ready 的替换文本;如果缺少 LaTeX 源,要明确说明阻塞。"
133425
+ }
133133
133426
  }
133134
133427
  }
133135
133428
  };
@@ -133475,8 +133768,12 @@ function buildTutorialStartResearchExample(language) {
133475
133768
  decision_policy: "autonomous",
133476
133769
  launch_mode: "standard",
133477
133770
  custom_profile: "freeform",
133771
+ review_followup_policy: "audit_only",
133772
+ baseline_execution_policy: "auto",
133773
+ manuscript_edit_mode: "none",
133478
133774
  entry_state_summary: "",
133479
133775
  review_summary: "",
133776
+ review_materials: "",
133480
133777
  custom_brief: "",
133481
133778
  user_language: "zh"
133482
133779
  };
@@ -133507,8 +133804,12 @@ function buildTutorialStartResearchExample(language) {
133507
133804
  decision_policy: "autonomous",
133508
133805
  launch_mode: "standard",
133509
133806
  custom_profile: "freeform",
133807
+ review_followup_policy: "audit_only",
133808
+ baseline_execution_policy: "auto",
133809
+ manuscript_edit_mode: "none",
133510
133810
  entry_state_summary: "",
133511
133811
  review_summary: "",
133812
+ review_materials: "",
133512
133813
  custom_brief: "",
133513
133814
  user_language: "en"
133514
133815
  };
@@ -133611,6 +133912,65 @@ function CreateProjectDialog({
133611
133912
  })),
133612
133913
  [t]
133613
133914
  );
133915
+ const customProfileItems = reactExports.useMemo(
133916
+ () => ["continue_existing_state", "review_audit", "revision_rebuttal", "freeform"].map((value) => ({
133917
+ value,
133918
+ title: t.customProfileChoiceOptions[value].title,
133919
+ meta: t.customProfileChoiceOptions[value].meta,
133920
+ description: t.customProfileChoiceOptions[value].body
133921
+ })),
133922
+ [t]
133923
+ );
133924
+ const launchModeItems = reactExports.useMemo(
133925
+ () => ["standard", "custom"].map((value) => {
133926
+ const copy2 = splitOptionCopy(t.launchModeOptions[value]);
133927
+ return {
133928
+ value,
133929
+ title: copy2.title,
133930
+ meta: value === "standard" ? locale === "zh" ? "默认" : "Default" : "Custom",
133931
+ description: copy2.description
133932
+ };
133933
+ }),
133934
+ [locale, t]
133935
+ );
133936
+ const standardProfileItems = reactExports.useMemo(
133937
+ () => [
133938
+ {
133939
+ value: "canonical_research_graph",
133940
+ title: t.standardProfileChoiceOption.title,
133941
+ meta: t.standardProfileChoiceOption.meta,
133942
+ description: t.standardProfileChoiceOption.body
133943
+ }
133944
+ ],
133945
+ [t]
133946
+ );
133947
+ const reviewFollowupPolicyItems = reactExports.useMemo(
133948
+ () => ["audit_only", "auto_execute_followups", "user_gated_followups"].map((value) => ({
133949
+ value,
133950
+ title: t.reviewFollowupPolicyOptions[value].title,
133951
+ meta: t.reviewFollowupPolicyOptions[value].meta,
133952
+ description: t.reviewFollowupPolicyOptions[value].body
133953
+ })),
133954
+ [t]
133955
+ );
133956
+ const baselineExecutionPolicyItems = reactExports.useMemo(
133957
+ () => ["auto", "must_reproduce_or_verify", "reuse_existing_only", "skip_unless_blocking"].map((value) => ({
133958
+ value,
133959
+ title: t.baselineExecutionPolicyOptions[value].title,
133960
+ meta: t.baselineExecutionPolicyOptions[value].meta,
133961
+ description: t.baselineExecutionPolicyOptions[value].body
133962
+ })),
133963
+ [t]
133964
+ );
133965
+ const manuscriptEditModeItems = reactExports.useMemo(
133966
+ () => ["none", "copy_ready_text", "latex_required"].map((value) => ({
133967
+ value,
133968
+ title: t.manuscriptEditModeOptions[value].title,
133969
+ meta: t.manuscriptEditModeOptions[value].meta,
133970
+ description: t.manuscriptEditModeOptions[value].body
133971
+ })),
133972
+ [t]
133973
+ );
133614
133974
  const derivedContract = reactExports.useMemo(
133615
133975
  () => resolveStartResearchContractFields(form),
133616
133976
  [form.baseline_id, form.research_intensity]
@@ -133669,20 +134029,6 @@ function CreateProjectDialog({
133669
134029
  return next;
133670
134030
  });
133671
134031
  };
133672
- const handleApplyTutorialExample = reactExports.useCallback(() => {
133673
- const example = buildTutorialStartResearchExample(locale);
133674
- setManualOverride(false);
133675
- setQuestIdManualOverride(false);
133676
- setForm((current) => {
133677
- const next = {
133678
- ...current,
133679
- ...example,
133680
- quest_id: current.quest_id
133681
- };
133682
- saveStartResearchDraft(next);
133683
- return next;
133684
- });
133685
- }, [locale]);
133686
134032
  reactExports.useEffect(() => {
133687
134033
  if (!open) return;
133688
134034
  let active = true;
@@ -133939,8 +134285,12 @@ function CreateProjectDialog({
133939
134285
  decision_policy: next.decision_policy,
133940
134286
  launch_mode: next.launch_mode,
133941
134287
  custom_profile: next.custom_profile,
134288
+ review_followup_policy: next.review_followup_policy,
134289
+ baseline_execution_policy: next.baseline_execution_policy,
134290
+ manuscript_edit_mode: next.manuscript_edit_mode,
133942
134291
  entry_state_summary: next.entry_state_summary,
133943
134292
  review_summary: next.review_summary,
134293
+ review_materials: next.review_materials,
133944
134294
  custom_brief: next.custom_brief,
133945
134295
  user_language: next.user_language
133946
134296
  });
@@ -133987,6 +134337,10 @@ function CreateProjectDialog({
133987
134337
  variant_id: baselineVariantId || null
133988
134338
  } : null;
133989
134339
  const derivedFields = resolveStartResearchContractFields(saved);
134340
+ const effectiveReviewFollowupPolicy = saved.custom_profile === "review_audit" ? saved.review_followup_policy : "audit_only";
134341
+ const effectiveManuscriptEditMode = saved.custom_profile === "review_audit" || saved.custom_profile === "revision_rebuttal" ? saved.manuscript_edit_mode : "none";
134342
+ const effectiveReviewSummary = saved.custom_profile === "review_audit" || saved.custom_profile === "revision_rebuttal" ? saved.review_summary : "";
134343
+ const effectiveReviewMaterials = saved.custom_profile === "review_audit" || saved.custom_profile === "revision_rebuttal" ? sanitizeLines(saved.review_materials) : [];
133990
134344
  const timeBudget = Number(derivedFields.time_budget_hours);
133991
134345
  const requestedConnectorBindings = connectorChoices.map((item) => ({
133992
134346
  connector: item.name,
@@ -134000,6 +134354,9 @@ function CreateProjectDialog({
134000
134354
  decision_policy: saved.decision_policy,
134001
134355
  launch_mode: saved.launch_mode,
134002
134356
  custom_profile: saved.custom_profile,
134357
+ review_followup_policy: effectiveReviewFollowupPolicy,
134358
+ baseline_execution_policy: saved.baseline_execution_policy,
134359
+ manuscript_edit_mode: effectiveManuscriptEditMode,
134003
134360
  scope: derivedFields.scope,
134004
134361
  baseline_mode: derivedFields.baseline_mode,
134005
134362
  resource_policy: derivedFields.resource_policy,
@@ -134010,7 +134367,8 @@ function CreateProjectDialog({
134010
134367
  baseline_urls: sanitizeLines(saved.baseline_urls),
134011
134368
  paper_urls: sanitizeLines(saved.paper_urls),
134012
134369
  entry_state_summary: saved.entry_state_summary,
134013
- review_summary: saved.review_summary,
134370
+ review_summary: effectiveReviewSummary,
134371
+ review_materials: effectiveReviewMaterials,
134014
134372
  custom_brief: saved.custom_brief
134015
134373
  };
134016
134374
  await onCreate({
@@ -134135,19 +134493,6 @@ function CreateProjectDialog({
134135
134493
  disabled: manualOverride
134136
134494
  }
134137
134495
  ) }),
134138
- onboardingStatus !== "running" ? /* @__PURE__ */ jsxRuntimeExports.jsx("div", { className: "flex justify-end", children: /* @__PURE__ */ jsxRuntimeExports.jsx(
134139
- Button,
134140
- {
134141
- type: "button",
134142
- variant: "secondary",
134143
- size: "sm",
134144
- className: "rounded-full",
134145
- onClick: handleApplyTutorialExample,
134146
- disabled: manualOverride,
134147
- title: t.tutorialExampleHelp,
134148
- children: t.tutorialExample
134149
- }
134150
- ) }) : null,
134151
134496
  /* @__PURE__ */ jsxRuntimeExports.jsx(InlineField, { label: t.goalLabel, help: t.goalHelp, dataOnboardingId: "start-research-goal", children: /* @__PURE__ */ jsxRuntimeExports.jsx(
134152
134497
  Textarea,
134153
134498
  {
@@ -134261,34 +134606,70 @@ function CreateProjectDialog({
134261
134606
  ) })
134262
134607
  ] }),
134263
134608
  /* @__PURE__ */ jsxRuntimeExports.jsxs(SectionCard, { title: t.policy, dataOnboardingId: "start-research-contract", children: [
134264
- /* @__PURE__ */ jsxRuntimeExports.jsx(InlineField, { label: t.launchModeLabel, help: t.launchModeHelp, hint: t.launchModeHelp, children: /* @__PURE__ */ jsxRuntimeExports.jsxs(
134265
- "select",
134609
+ /* @__PURE__ */ jsxRuntimeExports.jsx(
134610
+ ChoiceField,
134266
134611
  {
134612
+ label: t.launchModeLabel,
134613
+ help: t.launchModeHelp,
134614
+ hint: t.launchModeHelp,
134267
134615
  value: form.launch_mode,
134268
- onChange: (event) => setField("launch_mode", event.target.value),
134269
- className: selectClassName,
134270
- disabled: manualOverride,
134271
- children: [
134272
- /* @__PURE__ */ jsxRuntimeExports.jsx("option", { value: "standard", children: t.launchModeOptions.standard }),
134273
- /* @__PURE__ */ jsxRuntimeExports.jsx("option", { value: "custom", children: t.launchModeOptions.custom })
134274
- ]
134616
+ items: launchModeItems,
134617
+ onChange: (value) => setField("launch_mode", value),
134618
+ disabled: manualOverride
134275
134619
  }
134276
- ) }),
134620
+ ),
134277
134621
  form.launch_mode === "custom" ? /* @__PURE__ */ jsxRuntimeExports.jsxs(jsxRuntimeExports.Fragment, { children: [
134278
- /* @__PURE__ */ jsxRuntimeExports.jsx(InlineField, { label: t.customProfileLabel, help: t.customProfileHelp, hint: t.customProfileHelp, children: /* @__PURE__ */ jsxRuntimeExports.jsxs(
134279
- "select",
134622
+ /* @__PURE__ */ jsxRuntimeExports.jsx(
134623
+ ChoiceField,
134280
134624
  {
134625
+ label: t.customProfileLabel,
134626
+ help: t.customProfileHelp,
134627
+ hint: t.customProfileHelp,
134281
134628
  value: form.custom_profile,
134282
- onChange: (event) => setField("custom_profile", event.target.value),
134283
- className: selectClassName,
134284
- disabled: manualOverride,
134285
- children: [
134286
- /* @__PURE__ */ jsxRuntimeExports.jsx("option", { value: "continue_existing_state", children: t.customProfileOptions.continue_existing_state }),
134287
- /* @__PURE__ */ jsxRuntimeExports.jsx("option", { value: "revision_rebuttal", children: t.customProfileOptions.revision_rebuttal }),
134288
- /* @__PURE__ */ jsxRuntimeExports.jsx("option", { value: "freeform", children: t.customProfileOptions.freeform })
134289
- ]
134629
+ items: customProfileItems,
134630
+ onChange: (value) => setField("custom_profile", value),
134631
+ disabled: manualOverride
134290
134632
  }
134291
- ) }),
134633
+ ),
134634
+ /* @__PURE__ */ jsxRuntimeExports.jsx(
134635
+ ChoiceField,
134636
+ {
134637
+ label: t.baselineExecutionPolicyLabel,
134638
+ help: t.baselineExecutionPolicyHelp,
134639
+ hint: t.baselineExecutionPolicyHelp,
134640
+ value: form.baseline_execution_policy,
134641
+ items: baselineExecutionPolicyItems,
134642
+ onChange: (value) => setField("baseline_execution_policy", value),
134643
+ disabled: manualOverride
134644
+ }
134645
+ ),
134646
+ form.custom_profile === "review_audit" ? /* @__PURE__ */ jsxRuntimeExports.jsx(
134647
+ ChoiceField,
134648
+ {
134649
+ label: t.reviewFollowupPolicyLabel,
134650
+ help: t.reviewFollowupPolicyHelp,
134651
+ hint: t.reviewFollowupPolicyHelp,
134652
+ value: form.review_followup_policy,
134653
+ items: reviewFollowupPolicyItems,
134654
+ onChange: (value) => setField("review_followup_policy", value),
134655
+ disabled: manualOverride
134656
+ }
134657
+ ) : null,
134658
+ form.custom_profile === "revision_rebuttal" || form.custom_profile === "review_audit" && form.review_followup_policy !== "audit_only" ? /* @__PURE__ */ jsxRuntimeExports.jsxs(jsxRuntimeExports.Fragment, { children: [
134659
+ /* @__PURE__ */ jsxRuntimeExports.jsx(
134660
+ ChoiceField,
134661
+ {
134662
+ label: t.manuscriptEditModeLabel,
134663
+ help: t.manuscriptEditModeHelp,
134664
+ hint: t.manuscriptEditModeHelp,
134665
+ value: form.manuscript_edit_mode,
134666
+ items: manuscriptEditModeItems,
134667
+ onChange: (value) => setField("manuscript_edit_mode", value),
134668
+ disabled: manualOverride
134669
+ }
134670
+ ),
134671
+ form.manuscript_edit_mode === "latex_required" ? /* @__PURE__ */ jsxRuntimeExports.jsx("div", { className: "rounded-lg border border-[rgba(126,77,42,0.22)] bg-[rgba(126,77,42,0.06)] px-3 py-2 text-[11px] leading-5 text-[rgba(86,82,77,0.88)] dark:border-[rgba(126,77,42,0.22)] dark:bg-[rgba(126,77,42,0.08)] dark:text-[rgba(86,82,77,0.88)]", children: t.manuscriptEditModeNote }) : null
134672
+ ] }) : null,
134292
134673
  /* @__PURE__ */ jsxRuntimeExports.jsx(InlineField, { label: t.entryStateSummaryLabel, help: t.entryStateSummaryHelp, children: /* @__PURE__ */ jsxRuntimeExports.jsx(
134293
134674
  Textarea,
134294
134675
  {
@@ -134299,7 +134680,7 @@ function CreateProjectDialog({
134299
134680
  disabled: manualOverride
134300
134681
  }
134301
134682
  ) }),
134302
- form.custom_profile === "revision_rebuttal" ? /* @__PURE__ */ jsxRuntimeExports.jsx(InlineField, { label: t.reviewSummaryLabel, help: t.reviewSummaryHelp, children: /* @__PURE__ */ jsxRuntimeExports.jsx(
134683
+ form.custom_profile === "review_audit" || form.custom_profile === "revision_rebuttal" ? /* @__PURE__ */ jsxRuntimeExports.jsx(InlineField, { label: t.reviewSummaryLabel, help: t.reviewSummaryHelp, children: /* @__PURE__ */ jsxRuntimeExports.jsx(
134303
134684
  Textarea,
134304
134685
  {
134305
134686
  value: form.review_summary,
@@ -134309,6 +134690,16 @@ function CreateProjectDialog({
134309
134690
  disabled: manualOverride
134310
134691
  }
134311
134692
  ) }) : null,
134693
+ form.custom_profile === "review_audit" || form.custom_profile === "revision_rebuttal" ? /* @__PURE__ */ jsxRuntimeExports.jsx(InlineField, { label: t.reviewMaterialsLabel, help: t.reviewMaterialsHelp, children: /* @__PURE__ */ jsxRuntimeExports.jsx(
134694
+ Textarea,
134695
+ {
134696
+ value: form.review_materials,
134697
+ onChange: (event) => setField("review_materials", event.target.value),
134698
+ placeholder: t.reviewMaterialsPlaceholder,
134699
+ className: "min-h-[92px] rounded-[10px] border-[rgba(45,42,38,0.09)] bg-white/75 text-xs leading-5 dark:border-[rgba(45,42,38,0.09)] dark:bg-white/78",
134700
+ disabled: manualOverride
134701
+ }
134702
+ ) }) : null,
134312
134703
  /* @__PURE__ */ jsxRuntimeExports.jsx(InlineField, { label: t.customBriefLabel, help: t.customBriefHelp, children: /* @__PURE__ */ jsxRuntimeExports.jsx(
134313
134704
  Textarea,
134314
134705
  {
@@ -134319,7 +134710,19 @@ function CreateProjectDialog({
134319
134710
  disabled: manualOverride
134320
134711
  }
134321
134712
  ) })
134322
- ] }) : null,
134713
+ ] }) : /* @__PURE__ */ jsxRuntimeExports.jsx(
134714
+ ChoiceField,
134715
+ {
134716
+ label: t.standardProfileLabel,
134717
+ help: t.standardProfileHelp,
134718
+ hint: t.standardProfileHelp,
134719
+ value: "canonical_research_graph",
134720
+ items: standardProfileItems,
134721
+ onChange: () => {
134722
+ },
134723
+ disabled: manualOverride
134724
+ }
134725
+ ),
134323
134726
  /* @__PURE__ */ jsxRuntimeExports.jsx(
134324
134727
  ChoiceField,
134325
134728
  {
@@ -135142,6 +135545,270 @@ const HERO_COPY = {
135142
135545
  }
135143
135546
  ];
135144
135547
 
135548
+ const COPY = {
135549
+ en: {
135550
+ title: "Before you start",
135551
+ subtitle: "Set up an external connector for milestone delivery, or jump into the guided demo first.",
135552
+ connector: {
135553
+ eyebrow: "STEP 1",
135554
+ title: "Bind a connector first",
135555
+ body: {
135556
+ no_enabled: "No external connector is enabled yet. It is recommended to configure one first so milestones, replies, and progress can reach you outside the web workspace.",
135557
+ no_target: "A connector is enabled, but there is no selectable delivery target yet. Open connector settings first, or send one message from the target connector and then come back here.",
135558
+ recommended: "It is recommended to confirm one default connector target before starting. Then Start Research and later project progress can be delivered to your normal external conversation."
135559
+ },
135560
+ cta: {
135561
+ no_enabled: "Open Connector Settings",
135562
+ no_target: "Check Connector Settings",
135563
+ recommended: "Bind Connector"
135564
+ },
135565
+ note: "This reminder appears on entry while no external connector is bound, so you can set delivery up before the first real run."
135566
+ },
135567
+ tutorial: {
135568
+ eyebrow: "STEP 2",
135569
+ title: "Play the guided demo",
135570
+ body: "If you want a safe first pass through the interface, launch the guided demo. It walks through Start Research, Explorer, Canvas, Memory, and Copilot with a staged project.",
135571
+ zh: "Chinese Demo",
135572
+ en: "English Demo",
135573
+ skip: "Skip demo for now",
135574
+ never: "Do not remind again"
135575
+ },
135576
+ close: "Close"
135577
+ },
135578
+ zh: {
135579
+ title: "开始之前",
135580
+ subtitle: "先配置一个外部 Connector,或先播放一次 guided demo。",
135581
+ connector: {
135582
+ eyebrow: "STEP 1",
135583
+ title: "先绑定一个 Connector",
135584
+ body: {
135585
+ no_enabled: "你现在还没有启用任何外部 Connector。建议先配置一个,这样研究过程中的里程碑、回复和进展可以直接发送到网页之外。",
135586
+ no_target: "你已经启用了 Connector,但还没有可选择的投递目标。建议先进入 Connector 设置页检查配置,或者先在对应 Connector 中发一条消息,再回来继续。",
135587
+ recommended: "建议先确认一个默认 Connector 目标。这样之后 Start Research 和项目运行中的进展都可以直接同步出去。"
135588
+ },
135589
+ cta: {
135590
+ no_enabled: "前往 Connector 设置",
135591
+ no_target: "检查 Connector 设置",
135592
+ recommended: "绑定 Connector"
135593
+ },
135594
+ note: "只要还没有绑定外部 Connector,这个提醒在进入首页时就会继续出现,方便你在第一次真实运行前先完成投递配置。"
135595
+ },
135596
+ tutorial: {
135597
+ eyebrow: "STEP 2",
135598
+ title: "播放首次 Demo",
135599
+ body: "如果你想先安全地熟悉界面和工作流,可以先进入教程 demo。它会一步步带你理解 Start Research、Explorer、Canvas、Memory 和 Copilot。",
135600
+ zh: "中文 Demo",
135601
+ en: "English Demo",
135602
+ skip: "暂时跳过 Demo",
135603
+ never: "不再提醒"
135604
+ },
135605
+ close: "关闭"
135606
+ }
135607
+ };
135608
+ function stepLabel(label, fallback, showBoth) {
135609
+ if (showBoth) return label;
135610
+ return fallback;
135611
+ }
135612
+ function BilingualBlock({
135613
+ zh,
135614
+ en,
135615
+ className,
135616
+ zhClassName,
135617
+ enClassName
135618
+ }) {
135619
+ return /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: cn$1("space-y-1.5", className), children: [
135620
+ /* @__PURE__ */ jsxRuntimeExports.jsx("div", { className: cn$1("leading-7", zhClassName), children: zh }),
135621
+ /* @__PURE__ */ jsxRuntimeExports.jsx("div", { className: cn$1("leading-7 opacity-88", enClassName), children: en })
135622
+ ] });
135623
+ }
135624
+ function EntryCoachDialog({
135625
+ open,
135626
+ locale,
135627
+ connectorMode,
135628
+ showConnectorStep,
135629
+ showTutorialStep,
135630
+ onClose,
135631
+ onOpenConnectorSettings,
135632
+ onSetLanguage,
135633
+ onStartTutorial,
135634
+ onSkipTutorial,
135635
+ onNeverShowTutorial
135636
+ }) {
135637
+ if (!open) {
135638
+ return null;
135639
+ }
135640
+ const t = COPY[locale];
135641
+ const zh = COPY.zh;
135642
+ const en = COPY.en;
135643
+ const showBoth = showConnectorStep && showTutorialStep;
135644
+ return /* @__PURE__ */ jsxRuntimeExports.jsx(
135645
+ "div",
135646
+ {
135647
+ className: "fixed inset-0 z-[10010] flex items-center justify-center bg-[rgba(12,14,18,0.48)] p-4 backdrop-blur-md",
135648
+ onClick: onClose,
135649
+ children: /* @__PURE__ */ jsxRuntimeExports.jsxs(
135650
+ "div",
135651
+ {
135652
+ className: "relative w-full max-w-[980px] overflow-hidden rounded-[32px] border border-white/10 bg-[rgba(252,248,242,0.98)] shadow-[0_40px_120px_-52px_rgba(15,23,42,0.62)]",
135653
+ onClick: (event) => event.stopPropagation(),
135654
+ children: [
135655
+ /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "flex items-start justify-between gap-4 border-b border-black/[0.06] px-6 py-5", children: [
135656
+ /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "min-w-0", children: [
135657
+ /* @__PURE__ */ jsxRuntimeExports.jsx("div", { className: "text-[11px] font-semibold uppercase tracking-[0.2em] text-[rgba(126,108,82,0.72)]", children: "Quick Start / 快速开始" }),
135658
+ /* @__PURE__ */ jsxRuntimeExports.jsxs("h2", { className: "mt-2 text-2xl font-semibold tracking-tight text-[rgba(38,36,33,0.96)]", children: [
135659
+ zh.title,
135660
+ " / ",
135661
+ en.title
135662
+ ] }),
135663
+ /* @__PURE__ */ jsxRuntimeExports.jsx("div", { className: "mt-2 max-w-2xl text-sm text-[rgba(86,82,77,0.86)]", children: /* @__PURE__ */ jsxRuntimeExports.jsx(BilingualBlock, { zh: zh.subtitle, en: en.subtitle }) })
135664
+ ] }),
135665
+ /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "flex items-center gap-2", children: [
135666
+ /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "inline-flex rounded-full border border-[rgba(126,108,82,0.14)] bg-[rgba(244,239,233,0.84)] p-1", children: [
135667
+ /* @__PURE__ */ jsxRuntimeExports.jsx(
135668
+ "button",
135669
+ {
135670
+ type: "button",
135671
+ onClick: () => onSetLanguage("zh"),
135672
+ className: cn$1(
135673
+ "rounded-full px-3 py-1.5 text-xs font-semibold transition",
135674
+ locale === "zh" ? "bg-[#2D2A26] text-white" : "text-[rgba(86,82,77,0.82)] hover:bg-white"
135675
+ ),
135676
+ children: "中文"
135677
+ }
135678
+ ),
135679
+ /* @__PURE__ */ jsxRuntimeExports.jsx(
135680
+ "button",
135681
+ {
135682
+ type: "button",
135683
+ onClick: () => onSetLanguage("en"),
135684
+ className: cn$1(
135685
+ "rounded-full px-3 py-1.5 text-xs font-semibold transition",
135686
+ locale === "en" ? "bg-[#2D2A26] text-white" : "text-[rgba(86,82,77,0.82)] hover:bg-white"
135687
+ ),
135688
+ children: "English"
135689
+ }
135690
+ )
135691
+ ] }),
135692
+ /* @__PURE__ */ jsxRuntimeExports.jsx(
135693
+ "button",
135694
+ {
135695
+ type: "button",
135696
+ onClick: onClose,
135697
+ className: "inline-flex h-10 w-10 items-center justify-center rounded-full text-[rgba(107,103,97,0.82)] transition hover:bg-black/[0.04] hover:text-[rgba(38,36,33,0.96)]",
135698
+ "aria-label": t.close,
135699
+ children: /* @__PURE__ */ jsxRuntimeExports.jsx(X$1, { className: "h-4 w-4" })
135700
+ }
135701
+ )
135702
+ ] })
135703
+ ] }),
135704
+ /* @__PURE__ */ jsxRuntimeExports.jsxs(
135705
+ "div",
135706
+ {
135707
+ className: cn$1(
135708
+ "grid gap-0",
135709
+ showBoth ? "lg:grid-cols-[1.05fr_0.95fr]" : "grid-cols-1"
135710
+ ),
135711
+ children: [
135712
+ showConnectorStep ? /* @__PURE__ */ jsxRuntimeExports.jsxs("section", { className: "relative overflow-hidden bg-[#23262D] px-6 py-6 text-white lg:px-7 lg:py-7", children: [
135713
+ /* @__PURE__ */ jsxRuntimeExports.jsx("div", { className: "absolute inset-0 bg-[radial-gradient(circle_at_top_left,rgba(199,173,150,0.16),transparent_48%),radial-gradient(circle_at_bottom_right,rgba(95,117,138,0.18),transparent_44%)]" }),
135714
+ /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "relative", children: [
135715
+ /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "inline-flex items-center gap-2 rounded-full border border-white/12 bg-white/6 px-3 py-1 text-[11px] font-semibold uppercase tracking-[0.18em] text-white/74", children: [
135716
+ /* @__PURE__ */ jsxRuntimeExports.jsx(Settings2, { className: "h-3.5 w-3.5" }),
135717
+ stepLabel(t.connector.eyebrow, "STEP 1", showBoth)
135718
+ ] }),
135719
+ /* @__PURE__ */ jsxRuntimeExports.jsxs("h3", { className: "mt-4 text-2xl font-semibold tracking-tight", children: [
135720
+ zh.connector.title,
135721
+ " / ",
135722
+ en.connector.title
135723
+ ] }),
135724
+ /* @__PURE__ */ jsxRuntimeExports.jsx("div", { className: "mt-3 text-sm text-white/82", children: /* @__PURE__ */ jsxRuntimeExports.jsx(
135725
+ BilingualBlock,
135726
+ {
135727
+ zh: zh.connector.body[connectorMode],
135728
+ en: en.connector.body[connectorMode],
135729
+ enClassName: "text-white/72"
135730
+ }
135731
+ ) }),
135732
+ /* @__PURE__ */ jsxRuntimeExports.jsxs(
135733
+ Button,
135734
+ {
135735
+ type: "button",
135736
+ onClick: onOpenConnectorSettings,
135737
+ className: "mt-6 h-12 rounded-full bg-[#121419] px-6 text-sm font-semibold text-white shadow-[0_20px_40px_-24px_rgba(0,0,0,0.6)] transition hover:bg-black",
135738
+ children: [
135739
+ t.connector.cta[connectorMode],
135740
+ /* @__PURE__ */ jsxRuntimeExports.jsx(ArrowRight, { className: "ml-2 h-4 w-4" })
135741
+ ]
135742
+ }
135743
+ ),
135744
+ /* @__PURE__ */ jsxRuntimeExports.jsx("div", { className: "mt-4 text-[12px] text-white/60", children: /* @__PURE__ */ jsxRuntimeExports.jsx(
135745
+ BilingualBlock,
135746
+ {
135747
+ zh: zh.connector.note,
135748
+ en: en.connector.note,
135749
+ enClassName: "text-white/56"
135750
+ }
135751
+ ) })
135752
+ ] })
135753
+ ] }) : null,
135754
+ showTutorialStep ? /* @__PURE__ */ jsxRuntimeExports.jsxs("section", { className: "px-6 py-6 lg:px-7 lg:py-7", children: [
135755
+ /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "inline-flex items-center gap-2 rounded-full border border-[rgba(126,108,82,0.14)] bg-[rgba(244,239,233,0.72)] px-3 py-1 text-[11px] font-semibold uppercase tracking-[0.18em] text-[rgba(126,108,82,0.78)]", children: [
135756
+ /* @__PURE__ */ jsxRuntimeExports.jsx(GraduationCap, { className: "h-3.5 w-3.5" }),
135757
+ stepLabel(t.tutorial.eyebrow, "STEP 1", showBoth)
135758
+ ] }),
135759
+ /* @__PURE__ */ jsxRuntimeExports.jsxs("h3", { className: "mt-4 text-2xl font-semibold tracking-tight text-[rgba(38,36,33,0.96)]", children: [
135760
+ zh.tutorial.title,
135761
+ " / ",
135762
+ en.tutorial.title
135763
+ ] }),
135764
+ /* @__PURE__ */ jsxRuntimeExports.jsx("div", { className: "mt-3 text-sm text-[rgba(86,82,77,0.86)]", children: /* @__PURE__ */ jsxRuntimeExports.jsx(BilingualBlock, { zh: zh.tutorial.body, en: en.tutorial.body }) }),
135765
+ /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "mt-6 grid gap-3 sm:grid-cols-2", children: [
135766
+ /* @__PURE__ */ jsxRuntimeExports.jsxs(
135767
+ "button",
135768
+ {
135769
+ type: "button",
135770
+ onClick: () => onStartTutorial("zh"),
135771
+ className: "rounded-[20px] border border-[rgba(126,77,42,0.16)] bg-[rgba(244,239,233,0.76)] px-4 py-4 text-left transition hover:border-[rgba(126,77,42,0.28)] hover:bg-white",
135772
+ children: [
135773
+ /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "flex items-center gap-2 text-sm font-semibold text-[rgba(38,36,33,0.95)]", children: [
135774
+ /* @__PURE__ */ jsxRuntimeExports.jsx(BookOpen, { className: "h-4 w-4" }),
135775
+ t.tutorial.zh
135776
+ ] }),
135777
+ /* @__PURE__ */ jsxRuntimeExports.jsx("div", { className: "mt-1 text-[12px] leading-6 text-[rgba(86,82,77,0.82)]", children: locale === "zh" ? "一步步熟悉首页、Start Research 和项目工作区。" : "Walk through the landing page, Start Research, and workspace basics." })
135778
+ ]
135779
+ }
135780
+ ),
135781
+ /* @__PURE__ */ jsxRuntimeExports.jsxs(
135782
+ "button",
135783
+ {
135784
+ type: "button",
135785
+ onClick: () => onStartTutorial("en"),
135786
+ className: "rounded-[20px] border border-[rgba(126,77,42,0.16)] bg-[rgba(244,239,233,0.76)] px-4 py-4 text-left transition hover:border-[rgba(126,77,42,0.28)] hover:bg-white",
135787
+ children: [
135788
+ /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "flex items-center gap-2 text-sm font-semibold text-[rgba(38,36,33,0.95)]", children: [
135789
+ /* @__PURE__ */ jsxRuntimeExports.jsx(GraduationCap, { className: "h-4 w-4" }),
135790
+ t.tutorial.en
135791
+ ] }),
135792
+ /* @__PURE__ */ jsxRuntimeExports.jsx("div", { className: "mt-1 text-[12px] leading-6 text-[rgba(86,82,77,0.82)]", children: locale === "zh" ? "使用英文引导完成同一套首次 demo。" : "Use the same guided flow in English." })
135793
+ ]
135794
+ }
135795
+ )
135796
+ ] }),
135797
+ /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "mt-5 flex flex-col gap-2 sm:flex-row sm:justify-end", children: [
135798
+ /* @__PURE__ */ jsxRuntimeExports.jsx(Button, { variant: "ghost", onClick: onSkipTutorial, children: t.tutorial.skip }),
135799
+ /* @__PURE__ */ jsxRuntimeExports.jsx(Button, { variant: "secondary", onClick: onNeverShowTutorial, children: t.tutorial.never })
135800
+ ] })
135801
+ ] }) : null
135802
+ ]
135803
+ }
135804
+ )
135805
+ ]
135806
+ }
135807
+ )
135808
+ }
135809
+ );
135810
+ }
135811
+
135145
135812
  const Link = reactExports.forwardRef(function Link2({ href, children, ...rest }, ref) {
135146
135813
  const isExternal = /^https?:\/\//.test(href);
135147
135814
  if (isExternal) {
@@ -135766,6 +136433,22 @@ function sortQuests(items) {
135766
136433
  }
135767
136434
  function Hero() {
135768
136435
  const navigate = useNavigate();
136436
+ const { locale } = useI18n$1();
136437
+ const {
136438
+ hydrated: onboardingHydrated,
136439
+ firstRunHandled,
136440
+ neverRemind,
136441
+ startTutorial,
136442
+ skipFirstRun,
136443
+ neverShowAgain
136444
+ } = useOnboardingStore((state) => ({
136445
+ hydrated: state.hydrated,
136446
+ firstRunHandled: state.firstRunHandled,
136447
+ neverRemind: state.neverRemind,
136448
+ startTutorial: state.startTutorial,
136449
+ skipFirstRun: state.skipFirstRun,
136450
+ neverShowAgain: state.neverShowAgain
136451
+ }));
135769
136452
  const heroRef = reactExports.useRef(null);
135770
136453
  const prefersReducedMotion = useReducedMotion();
135771
136454
  const reducedMotion = prefersReducedMotion ?? false;
@@ -135790,11 +136473,34 @@ function Hero() {
135790
136473
  const [createDialogOpen, setCreateDialogOpen] = reactExports.useState(false);
135791
136474
  const [creating, setCreating] = reactExports.useState(false);
135792
136475
  const [createError, setCreateError] = reactExports.useState(null);
136476
+ const [connectorAvailability, setConnectorAvailability] = reactExports.useState(null);
136477
+ const [connectorAvailabilityResolved, setConnectorAvailabilityResolved] = reactExports.useState(false);
136478
+ const [entryCoachDismissed, setEntryCoachDismissed] = reactExports.useState(false);
135793
136479
  const currentVersion = reactExports.useMemo(() => runtimeVersion(), []);
135794
136480
  reactExports.useEffect(() => {
135795
136481
  document.body.classList.add("font-project");
135796
136482
  return () => document.body.classList.remove("font-project");
135797
136483
  }, []);
136484
+ reactExports.useEffect(() => {
136485
+ if (!onboardingHydrated) {
136486
+ return;
136487
+ }
136488
+ let active = true;
136489
+ void client.connectorsAvailability().then((payload) => {
136490
+ if (!active) return;
136491
+ setConnectorAvailability(payload);
136492
+ }).catch(() => {
136493
+ if (!active) return;
136494
+ setConnectorAvailability(null);
136495
+ }).finally(() => {
136496
+ if (active) {
136497
+ setConnectorAvailabilityResolved(true);
136498
+ }
136499
+ });
136500
+ return () => {
136501
+ active = false;
136502
+ };
136503
+ }, [onboardingHydrated]);
135798
136504
  reactExports.useEffect(() => {
135799
136505
  const updateSize = () => {
135800
136506
  setIsMobile(window.innerWidth < 1024);
@@ -136015,6 +136721,24 @@ function Hero() {
136015
136721
  }, [progress]);
136016
136722
  const sceneStageIndex = scrollStage;
136017
136723
  const barProgress = progress;
136724
+ const connectorCoachMode = reactExports.useMemo(() => {
136725
+ if (!connectorAvailability?.should_recommend_binding) {
136726
+ return null;
136727
+ }
136728
+ if (!connectorAvailability.has_enabled_external_connector) {
136729
+ return "no_enabled";
136730
+ }
136731
+ const hasDeliveryTarget = connectorAvailability.available_connectors.some(
136732
+ (item) => item.enabled && item.has_delivery_target
136733
+ );
136734
+ if (!hasDeliveryTarget) {
136735
+ return "no_target";
136736
+ }
136737
+ return "recommended";
136738
+ }, [connectorAvailability]);
136739
+ const shouldShowConnectorCoach = connectorAvailabilityResolved && connectorCoachMode !== null;
136740
+ const shouldShowTutorialCoach = onboardingHydrated && !firstRunHandled && !neverRemind;
136741
+ const entryCoachOpen = !entryCoachDismissed && !createDialogOpen && !questDialogOpen && (shouldShowConnectorCoach || shouldShowTutorialCoach);
136018
136742
  return /* @__PURE__ */ jsxRuntimeExports.jsxs(jsxRuntimeExports.Fragment, { children: [
136019
136743
  /* @__PURE__ */ jsxRuntimeExports.jsxs(
136020
136744
  "div",
@@ -136144,7 +136868,32 @@ function Hero() {
136144
136868
  deletingQuestId
136145
136869
  }
136146
136870
  ),
136147
- /* @__PURE__ */ jsxRuntimeExports.jsx(UpdateReminderDialog, {})
136871
+ /* @__PURE__ */ jsxRuntimeExports.jsx(UpdateReminderDialog, {}),
136872
+ /* @__PURE__ */ jsxRuntimeExports.jsx(
136873
+ EntryCoachDialog,
136874
+ {
136875
+ open: entryCoachOpen,
136876
+ locale,
136877
+ connectorMode: connectorCoachMode || "recommended",
136878
+ showConnectorStep: shouldShowConnectorCoach,
136879
+ showTutorialStep: shouldShowTutorialCoach,
136880
+ onClose: () => setEntryCoachDismissed(true),
136881
+ onOpenConnectorSettings: () => {
136882
+ setEntryCoachDismissed(true);
136883
+ navigate("/settings/connector", { state: { configName: "connectors" } });
136884
+ },
136885
+ onStartTutorial: (language) => {
136886
+ setEntryCoachDismissed(true);
136887
+ startTutorial(language, "/", "auto");
136888
+ },
136889
+ onSkipTutorial: () => {
136890
+ skipFirstRun();
136891
+ },
136892
+ onNeverShowTutorial: () => {
136893
+ neverShowAgain();
136894
+ }
136895
+ }
136896
+ )
136148
136897
  ] });
136149
136898
  }
136150
136899
 
@@ -155270,71 +156019,71 @@ const BUILTIN_PLUGIN_IMPORTS = {
155270
156019
  // Implemented Plugins
155271
156020
  // ============================================================
155272
156021
  // Code Viewer Plugin
155273
- "@ds/plugin-code-viewer": () => __vitePreload(() => import('./CodeViewerPlugin-7hhtWj_E.js'),true?__vite__mapDeps([0,1,2,3]):void 0).then((m) => ({
156022
+ "@ds/plugin-code-viewer": () => __vitePreload(() => import('./CodeViewerPlugin-DT54ysXa.js'),true?__vite__mapDeps([0,1,2,3]):void 0).then((m) => ({
155274
156023
  default: m.default
155275
156024
  })),
155276
156025
  // Code Editor Plugin (Monaco)
155277
- "@ds/plugin-code-editor": () => __vitePreload(() => import('./CodeEditorPlugin-QXMSCH71.js'),true?__vite__mapDeps([4,5,6,7,8,9]):void 0).then((m) => ({
156026
+ "@ds/plugin-code-editor": () => __vitePreload(() => import('./CodeEditorPlugin-B-xicq1e.js'),true?__vite__mapDeps([4,5,6,7,8,9]):void 0).then((m) => ({
155278
156027
  default: m.default
155279
156028
  })),
155280
156029
  // Text Viewer Plugin
155281
- "@ds/plugin-text-viewer": () => __vitePreload(() => import('./TextViewerPlugin-C3tCmFox.js'),true?__vite__mapDeps([10,1,3,11]):void 0).then((m) => ({
156030
+ "@ds/plugin-text-viewer": () => __vitePreload(() => import('./TextViewerPlugin-C-nVAZb_.js'),true?__vite__mapDeps([10,1,3,11]):void 0).then((m) => ({
155282
156031
  default: m.default
155283
156032
  })),
155284
156033
  // Markdown Viewer Plugin
155285
- "@ds/plugin-markdown-viewer": () => __vitePreload(() => import('./MarkdownViewerPlugin-836PVQWV.js'),true?__vite__mapDeps([12,2]):void 0).then((m) => ({
156034
+ "@ds/plugin-markdown-viewer": () => __vitePreload(() => import('./MarkdownViewerPlugin-BzdVH9Bx.js'),true?__vite__mapDeps([12,2]):void 0).then((m) => ({
155286
156035
  default: m.default
155287
156036
  })),
155288
156037
  // Image Viewer Plugin
155289
- "@ds/plugin-image-viewer": () => __vitePreload(() => import('./ImageViewerPlugin-CHJl_0lr.js'),true?__vite__mapDeps([13,14,15]):void 0).then((m) => ({
156038
+ "@ds/plugin-image-viewer": () => __vitePreload(() => import('./ImageViewerPlugin-OcVo33jV.js'),true?__vite__mapDeps([13,14,15]):void 0).then((m) => ({
155290
156039
  default: m.default
155291
156040
  })),
155292
156041
  // Document Viewer Plugin (Office documents)
155293
- "@ds/plugin-doc-viewer": () => __vitePreload(() => import('./DocViewerPlugin-BWMSnRJe.js'),true?[]:void 0).then((m) => ({
156042
+ "@ds/plugin-doc-viewer": () => __vitePreload(() => import('./DocViewerPlugin-DQtKT-VD.js'),true?[]:void 0).then((m) => ({
155294
156043
  default: m.default
155295
156044
  })),
155296
156045
  // PDF Viewer Plugin (Stage 06)
155297
- "@ds/plugin-pdf-viewer": () => __vitePreload(() => import('./PdfViewerPlugin-BwtICzue.js'),true?__vite__mapDeps([16,6,17,18,19,15,11,20,21]):void 0).then((m) => ({
156046
+ "@ds/plugin-pdf-viewer": () => __vitePreload(() => import('./PdfViewerPlugin-CmlDxbhU.js'),true?__vite__mapDeps([16,6,17,18,19,15,11,20,21]):void 0).then((m) => ({
155298
156047
  default: m.default
155299
156048
  })),
155300
156049
  // PDF Markdown Plugin (MinerU)
155301
- "@ds/plugin-pdf-markdown": () => __vitePreload(() => import('./PdfMarkdownPlugin-DZUfIUnp.js'),true?__vite__mapDeps([22,23,24]):void 0).then((m) => ({
156050
+ "@ds/plugin-pdf-markdown": () => __vitePreload(() => import('./PdfMarkdownPlugin-DW2ej8Vk.js'),true?__vite__mapDeps([22,23,24]):void 0).then((m) => ({
155302
156051
  default: m.default
155303
156052
  })),
155304
156053
  // CLI Plugin
155305
- "@ds/plugin-cli": () => __vitePreload(() => import('./CliPlugin-DrV8je02.js'),true?__vite__mapDeps([25,26,11,20,27]):void 0).then((m) => ({
156054
+ "@ds/plugin-cli": () => __vitePreload(() => import('./CliPlugin-CB1YODQn.js'),true?__vite__mapDeps([25,26,11,20,27]):void 0).then((m) => ({
155306
156055
  default: m.default
155307
156056
  })),
155308
156057
  // Lab Plugin (Home)
155309
- "@ds/plugin-lab": () => __vitePreload(() => import('./LabPlugin-eQpPPCEp.js'),true?__vite__mapDeps([28,29]):void 0).then((m) => ({
156058
+ "@ds/plugin-lab": () => __vitePreload(() => import('./LabPlugin-Ciz1gDaX.js'),true?__vite__mapDeps([28,29]):void 0).then((m) => ({
155310
156059
  default: m.default
155311
156060
  })),
155312
156061
  // ============================================================
155313
156062
  // Notebook Plugin (Novel Integration)
155314
156063
  // ============================================================
155315
156064
  // Notebook plugin with Novel editor
155316
- "@ds/plugin-notebook": () => __vitePreload(() => import('./index--c4iXtuy.js'),true?__vite__mapDeps([30,31,23,24,32,33,34,20,2,14,35,36,37,8,9,38]):void 0).then((m) => ({
156065
+ "@ds/plugin-notebook": () => __vitePreload(() => import('./index-C3r2iGrp.js'),true?__vite__mapDeps([30,31,23,24,32,33,34,20,2,14,35,36,37,8,9,38]):void 0).then((m) => ({
155317
156066
  default: m.default
155318
156067
  })),
155319
156068
  // ============================================================
155320
156069
  // LaTeX Plugin (Stage 11)
155321
156070
  // ============================================================
155322
- "@ds/plugin-latex": () => __vitePreload(() => import('./LatexPlugin-BwRfi89Z.js'),true?__vite__mapDeps([39,34,7,18,19,15]):void 0).then((m) => ({
156071
+ "@ds/plugin-latex": () => __vitePreload(() => import('./LatexPlugin-BhmjNQRC.js'),true?__vite__mapDeps([39,34,7,18,19,15]):void 0).then((m) => ({
155323
156072
  default: m.default
155324
156073
  })),
155325
- "@ds/plugin-git-diff-viewer": () => __vitePreload(() => import('./GitDiffViewerPlugin-7J9h9Vy_.js'),true?__vite__mapDeps([40,13,14,15,12,2,31,23,24,32,33,34,20,35,36,37,8,9,38,16,6,17,18,19,11,21]):void 0).then((m) => ({
156074
+ "@ds/plugin-git-diff-viewer": () => __vitePreload(() => import('./GitDiffViewerPlugin-hqHbCfnv.js'),true?__vite__mapDeps([40,13,14,15,12,2,31,23,24,32,33,34,20,35,36,37,8,9,38,16,6,17,18,19,11,21]):void 0).then((m) => ({
155326
156075
  default: m.default
155327
156076
  })),
155328
156077
  // ============================================================
155329
156078
  // Placeholder Plugins - to be implemented
155330
156079
  // ============================================================
155331
- "@ds/plugin-search": () => __vitePreload(() => import('./SearchPlugin-DHeIAMsx.js'),true?__vite__mapDeps([41,42]):void 0).then((m) => ({
156080
+ "@ds/plugin-search": () => __vitePreload(() => import('./SearchPlugin-DAjQZPSv.js'),true?__vite__mapDeps([41,42]):void 0).then((m) => ({
155332
156081
  default: m.default
155333
156082
  })),
155334
- "@ds/plugin-analysis": () => __vitePreload(() => import('./AnalysisPlugin-Db0cTXxm.js'),true?[]:void 0).then((m) => ({
156083
+ "@ds/plugin-analysis": () => __vitePreload(() => import('./AnalysisPlugin-DeyzPEhV.js'),true?[]:void 0).then((m) => ({
155335
156084
  default: m.default
155336
156085
  })),
155337
- "@ds/plugin-marketplace": () => __vitePreload(() => import('./MarketplacePlugin-C2y_556i.js'),true?__vite__mapDeps([43,37,14]):void 0).then((m) => ({
156086
+ "@ds/plugin-marketplace": () => __vitePreload(() => import('./MarketplacePlugin-DmyHspXt.js'),true?__vite__mapDeps([43,37,14]):void 0).then((m) => ({
155338
156087
  default: m.default
155339
156088
  }))
155340
156089
  };
@@ -172858,7 +173607,7 @@ const CopilotDockHeaderPortalContext = reactExports.createContext(null);
172858
173607
  const useCopilotDockHeaderPortal = () => reactExports.useContext(CopilotDockHeaderPortalContext);
172859
173608
  const CopilotDockCallbacksContext = reactExports.createContext(null);
172860
173609
  const useCopilotDockCallbacks = () => reactExports.useContext(CopilotDockCallbacksContext);
172861
- const AiManusChatView$1 = dynamic(() => __vitePreload(() => import('./AiManusChatView-D0mTXG4-.js').then(n => n.c),true?__vite__mapDeps([44,5,26,11,1,17,9,29,23,24,36]):void 0), {
173610
+ const AiManusChatView$1 = dynamic(() => __vitePreload(() => import('./AiManusChatView-CnJcXynW.js').then(n => n.c),true?__vite__mapDeps([44,5,26,11,1,17,9,29,23,24,36]):void 0), {
172862
173611
  loading: () => /* @__PURE__ */ jsxRuntimeExports.jsx(CopilotDockLoading, {})
172863
173612
  });
172864
173613
  const SPRING = {
@@ -174450,7 +175199,7 @@ function WorkspaceTooltipLayer({ rootId = "workspace-root" }) {
174450
175199
  );
174451
175200
  }
174452
175201
 
174453
- const AiManusChatView = dynamic(() => __vitePreload(() => import('./AiManusChatView-D0mTXG4-.js').then(n => n.c),true?__vite__mapDeps([44,5,26,11,1,17,9,29,23,24,36]):void 0), {
175202
+ const AiManusChatView = dynamic(() => __vitePreload(() => import('./AiManusChatView-CnJcXynW.js').then(n => n.c),true?__vite__mapDeps([44,5,26,11,1,17,9,29,23,24,36]):void 0), {
174454
175203
  loading: () => /* @__PURE__ */ jsxRuntimeExports.jsx("div", { className: "flex h-full items-center justify-center text-xs text-muted-foreground", children: "Loading Copilot…" })
174455
175204
  });
174456
175205
  function WelcomeCopilotView({
@@ -225142,6 +225891,8 @@ const QuestGraphNode = ({ data }) => {
225142
225891
  nodeData.isRoot && "is-root",
225143
225892
  nodeData.isHead && "is-head",
225144
225893
  nodeData.isSelected && "is-selected",
225894
+ nodeData.isCurrentPath && "is-current-path",
225895
+ nodeData.isCurrentWorkspace && "is-current-workspace",
225145
225896
  nodeData.isEvent && "is-event",
225146
225897
  nodeData.isPlaceholder && "is-placeholder",
225147
225898
  nodeData.baselineGate === "waived" && "is-waived",
@@ -225155,6 +225906,7 @@ const QuestGraphNode = ({ data }) => {
225155
225906
  /* @__PURE__ */ jsxRuntimeExports.jsx(Handle, { type: "source", position: Position.Right, className: "lab-flow-handle" }),
225156
225907
  /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "lab-quest-graph-node__eyebrow", children: [
225157
225908
  /* @__PURE__ */ jsxRuntimeExports.jsx("span", { className: "lab-quest-graph-node__kind", children: semanticLabel }),
225909
+ nodeData.isCurrentWorkspace ? /* @__PURE__ */ jsxRuntimeExports.jsx("span", { className: "lab-quest-graph-node__location is-current", children: t("quest_current_workspace_badge", void 0, "CURRENT") }) : null,
225158
225910
  nodeData.verdict ? /* @__PURE__ */ jsxRuntimeExports.jsx("span", { className: cn$1("lab-quest-graph-node__verdict", `is-${nodeData.verdict}`), children: nodeData.verdict }) : null
225159
225911
  ] }),
225160
225912
  /* @__PURE__ */ jsxRuntimeExports.jsx("div", { className: "lab-quest-graph-node__title", children: nodeData.label }),
@@ -226254,9 +227006,17 @@ function LabQuestGraphCanvasInner({
226254
227006
  const visibleBranchLineage = reactExports.useMemo(() => {
226255
227007
  if (pathFilterMode === "all") return /* @__PURE__ */ new Set();
226256
227008
  const fallbackBranch = branchNodesBase.find((node) => node.node_kind !== "baseline_root" && node.node_kind !== "placeholder")?.branch_name || null;
226257
- const targetBranch = pathFilterMode === "selected" ? activeBranch || headBranch || fallbackBranch : headBranch || activeBranch || fallbackBranch;
227009
+ const targetBranch = pathFilterMode === "selected" ? activeBranch || headBranch || fallbackBranch : activeBranch || headBranch || fallbackBranch;
226258
227010
  return buildBranchLineageSet(branchNodesBase, targetBranch);
226259
227011
  }, [activeBranch, branchNodesBase, headBranch, pathFilterMode]);
227012
+ const currentWorkspaceBranch = reactExports.useMemo(() => {
227013
+ const fallbackBranch = branchNodesBase.find((node) => node.node_kind !== "baseline_root" && node.node_kind !== "placeholder")?.branch_name || null;
227014
+ return activeBranch || headBranch || fallbackBranch || null;
227015
+ }, [activeBranch, branchNodesBase, headBranch]);
227016
+ const currentWorkspaceLineage = reactExports.useMemo(
227017
+ () => buildBranchLineageSet(branchNodesBase, currentWorkspaceBranch),
227018
+ [branchNodesBase, currentWorkspaceBranch]
227019
+ );
226260
227020
  const branchNodes = reactExports.useMemo(() => {
226261
227021
  if (pathFilterMode === "all") return branchNodesBase;
226262
227022
  return filterNodesByBranchLineage(branchNodesBase, visibleBranchLineage);
@@ -226581,6 +227341,12 @@ function LabQuestGraphCanvasInner({
226581
227341
  }
226582
227342
  return ids;
226583
227343
  }, [highlightBranch, highlightNodeId, viewMode, viewNodes]);
227344
+ const currentPathNodeIds = reactExports.useMemo(() => {
227345
+ if (viewMode !== "branch" || !currentWorkspaceLineage.size) return /* @__PURE__ */ new Set();
227346
+ return new Set(
227347
+ viewNodes.filter((node) => node.branch_name && currentWorkspaceLineage.has(node.branch_name)).map((node) => node.node_id)
227348
+ );
227349
+ }, [currentWorkspaceLineage, viewMode, viewNodes]);
226584
227350
  reactExports.useEffect(() => {
226585
227351
  if (viewMode !== "event") return;
226586
227352
  if (eventTraceMode !== "compact") return;
@@ -226627,7 +227393,9 @@ function LabQuestGraphCanvasInner({
226627
227393
  const label = isStage ? node.stage_title || node.stage_key || node.branch_name || "stage" : viewMode === "event" ? isDecision ? `DECISION: ${decisionValue || "recorded"}` : node.target_label || node.stage_title || node.status || node.branch_name || "event" : node.target_label || node.branch_name;
226628
227394
  const subtitle = isStage ? typeof node.event_count === "number" ? `${node.event_count} event${node.event_count === 1 ? "" : "s"}` : null : viewMode === "event" ? isDecision ? decisionPayload?.reason ? clampCanvasText(String(decisionPayload.reason), 80) : decisionPayload?.justification ? clampCanvasText(String(decisionPayload.justification), 80) : node.branch_name : node.stage_title || node.branch_name : isBaselineRoot ? node.status || null : isPlaceholder ? t("quest_graph_next_step_placeholder", void 0, "Next step") : node.idea_title || branchInsight?.stageLabel || node.idea_id || "Idea";
226629
227395
  const nodeStatus = viewMode === "branch" ? isPlaceholder ? t("quest_process_status_pending", void 0, "Pending") : branchInsight?.updatedAt ? `Updated ${formatRelativeTime$3(branchInsight.updatedAt)}` : node.status : node.status;
226630
- const isSelected = highlightIds.size > 0 ? highlightIds.has(node.node_id) : viewMode === "branch" ? node.branch_name === activeBranch : false;
227396
+ const isSelected = highlightIds.size > 0 ? highlightIds.has(node.node_id) : viewMode === "branch" ? Boolean(currentWorkspaceBranch && node.branch_name === currentWorkspaceBranch) : false;
227397
+ const isCurrentWorkspace = viewMode === "branch" && Boolean(currentWorkspaceBranch && node.branch_name === currentWorkspaceBranch);
227398
+ const isCurrentPath = viewMode === "branch" && Boolean(node.branch_name && currentWorkspaceLineage.has(node.branch_name));
226631
227399
  return {
226632
227400
  id: node.node_id,
226633
227401
  type: "questNode",
@@ -226661,6 +227429,8 @@ function LabQuestGraphCanvasInner({
226661
227429
  isRoot: viewMode === "branch" && isBaselineRoot,
226662
227430
  isPlaceholder: viewMode === "branch" && isPlaceholder,
226663
227431
  isSelected,
227432
+ isCurrentWorkspace,
227433
+ isCurrentPath,
226664
227434
  isEvent: viewMode === "event",
226665
227435
  branchName: node.branch_name,
226666
227436
  decisionType: decisionValue ? decisionValue.toLowerCase() : null,
@@ -226699,11 +227469,12 @@ function LabQuestGraphCanvasInner({
226699
227469
  };
226700
227470
  }),
226701
227471
  [
226702
- activeBranch,
226703
227472
  baselineMetricSnapshot,
226704
227473
  branchInsights,
226705
227474
  curveMetric,
226706
227475
  curveMode,
227476
+ currentWorkspaceBranch,
227477
+ currentWorkspaceLineage,
226707
227478
  headBranch,
226708
227479
  highlightIds,
226709
227480
  interactionLocked,
@@ -226734,10 +227505,15 @@ function LabQuestGraphCanvasInner({
226734
227505
  const questEdges = viewEdges.map((edge, index) => {
226735
227506
  const baseStyle = resolveEdgeStyle(edge.edge_type, edgePalette);
226736
227507
  const isHighlighted = highlightIds.has(edge.source) && highlightIds.has(edge.target);
227508
+ const isCurrentPathEdge = viewMode === "branch" && currentPathNodeIds.has(edge.source) && currentPathNodeIds.has(edge.target);
226737
227509
  const style = isHighlighted ? {
226738
227510
  ...baseStyle,
226739
227511
  stroke: "#53b0ae",
226740
227512
  strokeWidth: typeof baseStyle.strokeWidth === "number" ? Math.max(baseStyle.strokeWidth + 0.6, 2) : 2
227513
+ } : isCurrentPathEdge ? {
227514
+ ...baseStyle,
227515
+ stroke: "rgba(83, 176, 174, 0.82)",
227516
+ strokeWidth: typeof baseStyle.strokeWidth === "number" ? Math.max(baseStyle.strokeWidth + 0.3, 1.8) : 1.8
226741
227517
  } : baseStyle;
226742
227518
  const color = String(style.stroke || "var(--lab-border-strong)");
226743
227519
  return {
@@ -226759,7 +227535,7 @@ function LabQuestGraphCanvasInner({
226759
227535
  };
226760
227536
  });
226761
227537
  return [...questEdges, ...agentGraph.edges, ...overlayGraph.edges];
226762
- }, [agentGraph.edges, edgePalette, highlightIds, overlayGraph.edges, viewEdges]);
227538
+ }, [agentGraph.edges, currentPathNodeIds, edgePalette, highlightIds, overlayGraph.edges, viewEdges, viewMode]);
226763
227539
  reactExports.useEffect(() => {
226764
227540
  const forceLayout = viewModeRef.current !== viewMode;
226765
227541
  setNodes((prev) => {
@@ -230781,7 +231557,8 @@ function QuestCanvasSurface({
230781
231557
  questId,
230782
231558
  error,
230783
231559
  onRefresh,
230784
- onOpenStageSelection
231560
+ onOpenStageSelection,
231561
+ snapshot
230785
231562
  }) {
230786
231563
  const queryClient = useQueryClient();
230787
231564
  const clearGraphSelection = useLabGraphSelectionStore((state) => state.clear);
@@ -230811,6 +231588,16 @@ function QuestCanvasSurface({
230811
231588
  className: "relative h-full min-h-0 overflow-hidden bg-[var(--lab-surface-muted)]",
230812
231589
  "data-onboarding-id": "quest-canvas-surface",
230813
231590
  children: [
231591
+ /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "absolute left-4 top-4 z-20 flex max-w-[32rem] flex-wrap items-center gap-2", children: [
231592
+ snapshot?.branch ? /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "rounded-full border border-black/[0.08] bg-white/[0.88] px-3 py-1.5 text-[11px] font-medium text-foreground shadow-sm backdrop-blur dark:border-white/[0.10] dark:bg-[rgba(18,18,18,0.78)]", children: [
231593
+ "Current path: ",
231594
+ /* @__PURE__ */ jsxRuntimeExports.jsx("span", { className: "font-semibold", children: snapshot.branch })
231595
+ ] }) : null,
231596
+ snapshot?.active_anchor ? /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "rounded-full border border-black/[0.08] bg-white/[0.82] px-3 py-1.5 text-[11px] text-muted-foreground shadow-sm backdrop-blur dark:border-white/[0.10] dark:bg-[rgba(18,18,18,0.72)]", children: [
231597
+ "Stage: ",
231598
+ /* @__PURE__ */ jsxRuntimeExports.jsx("span", { className: "font-medium text-foreground", children: snapshot.active_anchor })
231599
+ ] }) : null
231600
+ ] }),
230814
231601
  /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "absolute right-4 top-4 z-20 flex max-w-[28rem] flex-col items-end gap-2", children: [
230815
231602
  error ? /* @__PURE__ */ jsxRuntimeExports.jsx("div", { className: "max-w-full rounded-full border border-black/[0.08] bg-white/[0.86] px-3 py-1.5 text-xs text-muted-foreground shadow-sm backdrop-blur dark:border-white/[0.10] dark:bg-[rgba(18,18,18,0.76)]", children: /* @__PURE__ */ jsxRuntimeExports.jsx("span", { className: "break-words", children: error }) }) : null,
230816
231603
  canOpenStageOverview && selection ? /* @__PURE__ */ jsxRuntimeExports.jsx(
@@ -230834,6 +231621,8 @@ function QuestCanvasSurface({
230834
231621
  questId,
230835
231622
  readOnly: true,
230836
231623
  preferredViewMode: "branch",
231624
+ activeBranch: snapshot?.branch || null,
231625
+ highlightBranch: selection?.branch_name || null,
230837
231626
  showFloatingPanels: false,
230838
231627
  onStageOpen: onOpenStageSelection
230839
231628
  }
@@ -232560,7 +233349,8 @@ function QuestWorkspaceSurfaceInner({
232560
233349
  questId,
232561
233350
  error,
232562
233351
  onRefresh: refreshWorkspace,
232563
- onOpenStageSelection
233352
+ onOpenStageSelection,
233353
+ snapshot
232564
233354
  }
232565
233355
  ) : view === "memory" ? /* @__PURE__ */ jsxRuntimeExports.jsx(
232566
233356
  QuestMemorySurface,
@@ -237458,6 +238248,7 @@ function createNoopNotebookSocket() {
237458
238248
  connect: () => socket,
237459
238249
  disconnect: () => socket,
237460
238250
  on: () => socket,
238251
+ once: () => socket,
237461
238252
  off: () => socket,
237462
238253
  emit: () => true,
237463
238254
  emitWithAck: async () => ({ data: void 0 })
@@ -239848,11 +240639,11 @@ function MobileQuestWorkspaceShell({
239848
240639
 
239849
240640
  const EXPLORER_REFRESH_EVENT = "ds:explorer:refresh";
239850
240641
 
239851
- const LabCopilotPanel = dynamic(() => __vitePreload(() => import('./LabCopilotPanel-1qSow1es.js'),true?__vite__mapDeps([45,35,26,11,44,5,1,17,9,29,23,24,36]):void 0), {
240642
+ const LabCopilotPanel = dynamic(() => __vitePreload(() => import('./LabCopilotPanel-DdGwhEUV.js'),true?__vite__mapDeps([45,35,26,11,44,5,1,17,9,29,23,24,36]):void 0), {
239852
240643
  loading: () => null
239853
240644
  });
239854
240645
  const LabCopilotHeader = dynamic(
239855
- () => __vitePreload(() => import('./LabCopilotPanel-1qSow1es.js'),true?__vite__mapDeps([45,35,26,11,44,5,1,17,9,29,23,24,36]):void 0).then((mod) => mod.LabCopilotHeader),
240646
+ () => __vitePreload(() => import('./LabCopilotPanel-DdGwhEUV.js'),true?__vite__mapDeps([45,35,26,11,44,5,1,17,9,29,23,24,36]):void 0).then((mod) => mod.LabCopilotHeader),
239856
240647
  { loading: () => null }
239857
240648
  );
239858
240649
  const getLabContextSessionId = (tab, projectId) => {