@researai/deepscientist 1.5.14 → 1.5.16
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +336 -90
- package/assets/branding/logo-raster.png +0 -0
- package/bin/ds.js +816 -131
- package/docs/en/00_QUICK_START.md +36 -15
- package/docs/en/01_SETTINGS_REFERENCE.md +53 -4
- package/docs/en/02_START_RESEARCH_GUIDE.md +7 -0
- package/docs/en/03_QQ_CONNECTOR_GUIDE.md +19 -0
- package/docs/en/05_TUI_GUIDE.md +6 -0
- package/docs/en/06_RUNTIME_AND_CANVAS.md +4 -3
- package/docs/en/09_DOCTOR.md +11 -5
- package/docs/en/10_WEIXIN_CONNECTOR_GUIDE.md +20 -0
- package/docs/en/14_PROMPT_SKILLS_AND_MCP_GUIDE.md +65 -13
- package/docs/en/15_CODEX_PROVIDER_SETUP.md +25 -8
- package/docs/en/16_TELEGRAM_CONNECTOR_GUIDE.md +134 -0
- package/docs/en/17_WHATSAPP_CONNECTOR_GUIDE.md +126 -0
- package/docs/en/18_FEISHU_CONNECTOR_GUIDE.md +136 -0
- package/docs/en/19_EXTERNAL_CONTROLLER_GUIDE.md +226 -0
- package/docs/en/19_LOCAL_BROWSER_AUTH.md +70 -0
- package/docs/en/20_WORKSPACE_MODES_GUIDE.md +250 -0
- package/docs/en/README.md +24 -0
- package/docs/zh/00_QUICK_START.md +36 -15
- package/docs/zh/01_SETTINGS_REFERENCE.md +53 -4
- package/docs/zh/02_START_RESEARCH_GUIDE.md +7 -0
- package/docs/zh/03_QQ_CONNECTOR_GUIDE.md +19 -0
- package/docs/zh/05_TUI_GUIDE.md +6 -0
- package/docs/zh/09_DOCTOR.md +11 -5
- package/docs/zh/10_WEIXIN_CONNECTOR_GUIDE.md +20 -0
- package/docs/zh/14_PROMPT_SKILLS_AND_MCP_GUIDE.md +65 -13
- package/docs/zh/15_CODEX_PROVIDER_SETUP.md +25 -8
- package/docs/zh/16_TELEGRAM_CONNECTOR_GUIDE.md +134 -0
- package/docs/zh/17_WHATSAPP_CONNECTOR_GUIDE.md +126 -0
- package/docs/zh/18_FEISHU_CONNECTOR_GUIDE.md +136 -0
- package/docs/zh/19_EXTERNAL_CONTROLLER_GUIDE.md +226 -0
- package/docs/zh/19_LOCAL_BROWSER_AUTH.md +68 -0
- package/docs/zh/20_WORKSPACE_MODES_GUIDE.md +251 -0
- package/docs/zh/README.md +24 -0
- package/install.sh +2 -0
- package/package.json +1 -1
- package/pyproject.toml +1 -1
- package/src/deepscientist/__init__.py +1 -1
- package/src/deepscientist/acp/envelope.py +6 -0
- package/src/deepscientist/artifact/charts.py +567 -0
- package/src/deepscientist/artifact/guidance.py +50 -10
- package/src/deepscientist/artifact/metrics.py +228 -5
- package/src/deepscientist/artifact/schemas.py +3 -0
- package/src/deepscientist/artifact/service.py +4276 -308
- package/src/deepscientist/bash_exec/models.py +23 -0
- package/src/deepscientist/bash_exec/monitor.py +147 -67
- package/src/deepscientist/bash_exec/runtime.py +218 -156
- package/src/deepscientist/bash_exec/service.py +309 -69
- package/src/deepscientist/bash_exec/shells.py +87 -0
- package/src/deepscientist/bridges/connectors.py +51 -2
- package/src/deepscientist/cli.py +115 -19
- package/src/deepscientist/codex_cli_compat.py +232 -0
- package/src/deepscientist/config/models.py +8 -4
- package/src/deepscientist/config/service.py +38 -11
- package/src/deepscientist/connector/weixin_support.py +122 -1
- package/src/deepscientist/daemon/api/handlers.py +199 -9
- package/src/deepscientist/daemon/api/router.py +5 -0
- package/src/deepscientist/daemon/app.py +1458 -289
- package/src/deepscientist/doctor.py +51 -0
- package/src/deepscientist/file_lock.py +48 -0
- package/src/deepscientist/gitops/__init__.py +10 -1
- package/src/deepscientist/gitops/diff.py +296 -1
- package/src/deepscientist/gitops/service.py +4 -1
- package/src/deepscientist/mcp/server.py +212 -5
- package/src/deepscientist/process_control.py +161 -0
- package/src/deepscientist/prompts/builder.py +501 -453
- package/src/deepscientist/quest/layout.py +15 -2
- package/src/deepscientist/quest/service.py +2539 -195
- package/src/deepscientist/quest/stage_views.py +177 -1
- package/src/deepscientist/runners/base.py +2 -0
- package/src/deepscientist/runners/codex.py +169 -31
- package/src/deepscientist/runners/runtime_overrides.py +17 -1
- package/src/deepscientist/skills/__init__.py +2 -2
- package/src/deepscientist/skills/installer.py +196 -5
- package/src/deepscientist/skills/registry.py +66 -0
- package/src/prompts/connectors/qq.md +18 -8
- package/src/prompts/connectors/weixin.md +16 -6
- package/src/prompts/contracts/shared_interaction.md +24 -4
- package/src/prompts/system.md +921 -72
- package/src/prompts/system_copilot.md +43 -0
- package/src/skills/analysis-campaign/SKILL.md +32 -2
- package/src/skills/analysis-campaign/references/artifact-orchestration.md +1 -1
- package/src/skills/analysis-campaign/references/writing-facing-slice-examples.md +65 -0
- package/src/skills/baseline/SKILL.md +10 -0
- package/src/skills/decision/SKILL.md +27 -2
- package/src/skills/experiment/SKILL.md +16 -2
- package/src/skills/figure-polish/SKILL.md +1 -0
- package/src/skills/finalize/SKILL.md +19 -0
- package/src/skills/idea/SKILL.md +79 -0
- package/src/skills/idea/references/idea-generation-playbook.md +100 -0
- package/src/skills/idea/references/outline-seeding-example.md +60 -0
- package/src/skills/intake-audit/SKILL.md +9 -1
- package/src/skills/mentor/SKILL.md +217 -0
- package/src/skills/mentor/references/correction-rules.md +210 -0
- package/src/skills/mentor/references/knowledge-profile.md +91 -0
- package/src/skills/mentor/references/persona-profile.md +138 -0
- package/src/skills/mentor/references/taste-profile.md +128 -0
- package/src/skills/mentor/references/thought-style-profile.md +138 -0
- package/src/skills/mentor/references/work-profile.md +289 -0
- package/src/skills/mentor/references/workflow-profile.md +240 -0
- package/src/skills/optimize/SKILL.md +1645 -0
- package/src/skills/rebuttal/SKILL.md +3 -1
- package/src/skills/review/SKILL.md +3 -1
- package/src/skills/scout/SKILL.md +8 -0
- package/src/skills/write/SKILL.md +81 -12
- package/src/skills/write/references/outline-evidence-contract-example.md +107 -0
- package/src/tui/dist/app/AppContainer.js +22 -11
- package/src/tui/dist/index.js +4 -1
- package/src/tui/dist/lib/api.js +33 -3
- package/src/tui/package.json +1 -1
- package/src/ui/dist/assets/AiManusChatView-COFACy7V.js +204 -0
- package/src/ui/dist/assets/AnalysisPlugin-DnSm0GZn.js +1 -0
- package/src/ui/dist/assets/CliPlugin-CvwCmDQ5.js +109 -0
- package/src/ui/dist/assets/CodeEditorPlugin-cOqSa0xq.js +2 -0
- package/src/ui/dist/assets/CodeViewerPlugin-itb0tltR.js +270 -0
- package/src/ui/dist/assets/DocViewerPlugin-DqKkiCI6.js +7 -0
- package/src/ui/dist/assets/GitCommitViewerPlugin-DVgNHBCS.js +1 -0
- package/src/ui/dist/assets/GitDiffViewerPlugin-DxL2ezFG.js +6 -0
- package/src/ui/dist/assets/GitSnapshotViewer-B_RQm1YZ.js +30 -0
- package/src/ui/dist/assets/ImageViewerPlugin-tHqlXY3n.js +26 -0
- package/src/ui/dist/assets/LabCopilotPanel-ClMbq5Yu.js +14 -0
- package/src/ui/dist/assets/LabPlugin-L_SuE8ow.js +22 -0
- package/src/ui/dist/assets/LatexPlugin-B495DTXC.js +25 -0
- package/src/ui/dist/assets/MarkdownViewerPlugin-DG28-61B.js +128 -0
- package/src/ui/dist/assets/MarketplacePlugin-BiOGT-Kj.js +13 -0
- package/src/ui/dist/assets/{NotebookEditor-CccQYZjX.css → NotebookEditor-BHH8rdGj.css} +1 -1
- package/src/ui/dist/assets/NotebookEditor-BOr3x3Ej.css +1 -0
- package/src/ui/dist/assets/NotebookEditor-C-4Kt1p9.js +81 -0
- package/src/ui/dist/assets/NotebookEditor-CVsj8h_T.js +361 -0
- package/src/ui/dist/assets/PdfLoader-CASDQmxJ.js +16 -0
- package/src/ui/dist/assets/PdfLoader-Cy5jtWrr.css +1 -0
- package/src/ui/dist/assets/PdfMarkdownPlugin-BFhwoKsY.js +1 -0
- package/src/ui/dist/assets/PdfViewerPlugin-DcOzU9vd.js +17 -0
- package/src/ui/dist/assets/PdfViewerPlugin-nwwE-fjJ.css +1 -0
- package/src/ui/dist/assets/SearchPlugin-CHj7M58O.js +16 -0
- package/src/ui/dist/assets/SearchPlugin-DA4en4hK.css +1 -0
- package/src/ui/dist/assets/TextViewerPlugin-CB4DYfWO.js +54 -0
- package/src/ui/dist/assets/VNCViewer-CjlbyCB3.js +11 -0
- package/src/ui/dist/assets/bot-CFkZY-JP.js +6 -0
- package/src/ui/dist/assets/browser-CTB2jwNe.js +8 -0
- package/src/ui/dist/assets/chevron-up-Dq5ofbht.js +6 -0
- package/src/ui/dist/assets/code-DLC6G24T.js +6 -0
- package/src/ui/dist/assets/file-content-Dv4LoZec.js +1 -0
- package/src/ui/dist/assets/file-diff-panel-Denq-lC3.js +1 -0
- package/src/ui/dist/assets/file-jump-queue-DA-SdG__.js +1 -0
- package/src/ui/dist/assets/file-socket-Cu4Qln7Y.js +1 -0
- package/src/ui/dist/assets/git-commit-horizontal-BUh6G52n.js +6 -0
- package/src/ui/dist/assets/image-B9HUUddG.js +6 -0
- package/src/ui/dist/assets/index-B2B1sg-M.js +1 -0
- package/src/ui/dist/assets/index-Cgla8biy.css +33 -0
- package/src/ui/dist/assets/index-DRyx7vAc.js +1 -0
- package/src/ui/dist/assets/index-Gbl53BNp.js +2496 -0
- package/src/ui/dist/assets/index-wQ7RIIRd.js +11 -0
- package/src/ui/dist/assets/monaco-CiHMMNH_.js +1 -0
- package/src/ui/dist/assets/pdf-effect-queue-ZtnHFCAi.js +6 -0
- package/src/ui/dist/assets/plugin-monaco-C8UgLomw.js +19 -0
- package/src/ui/dist/assets/plugin-notebook-HbW2K-1c.js +169 -0
- package/src/ui/dist/assets/plugin-pdf-CR8hgQBV.js +357 -0
- package/src/ui/dist/assets/plugin-terminal-MXFIPun8.js +227 -0
- package/src/ui/dist/assets/popover-DL6h35vr.js +1 -0
- package/src/ui/dist/assets/project-sync-CsX08Qno.js +1 -0
- package/src/ui/dist/assets/select-DvmXt1yY.js +11 -0
- package/src/ui/dist/assets/sigma-7jpXazui.js +6 -0
- package/src/ui/dist/assets/trash-xA7kFt8i.js +11 -0
- package/src/ui/dist/assets/useCliAccess-DsMwDjOp.js +1 -0
- package/src/ui/dist/assets/useFileDiffOverlay-FuhcnKiw.js +1 -0
- package/src/ui/dist/assets/wrap-text-CwMn-iqb.js +11 -0
- package/src/ui/dist/assets/zoom-out-R-GWEhzS.js +11 -0
- package/src/ui/dist/index.html +5 -2
- package/src/ui/dist/assets/AiManusChatView-DaF9Nge_.js +0 -26597
- package/src/ui/dist/assets/AnalysisPlugin-BSVx6dXE.js +0 -123
- package/src/ui/dist/assets/CliPlugin-C9gzJX41.js +0 -5905
- package/src/ui/dist/assets/CodeEditorPlugin-DU9G0Tox.js +0 -427
- package/src/ui/dist/assets/CodeViewerPlugin-DoX_fI9l.js +0 -905
- package/src/ui/dist/assets/DocViewerPlugin-C4FWIXuU.js +0 -278
- package/src/ui/dist/assets/GitDiffViewerPlugin-BgfFMgtf.js +0 -2661
- package/src/ui/dist/assets/ImageViewerPlugin-tcPkfY_x.js +0 -500
- package/src/ui/dist/assets/LabCopilotPanel-_dKV60Bf.js +0 -4104
- package/src/ui/dist/assets/LabPlugin-Bje0ayoC.js +0 -2677
- package/src/ui/dist/assets/LatexPlugin-CVsBzAln.js +0 -1792
- package/src/ui/dist/assets/MarkdownViewerPlugin-xjmrqv_8.js +0 -308
- package/src/ui/dist/assets/MarketplacePlugin-mMM2A8wP.js +0 -413
- package/src/ui/dist/assets/NotebookEditor-3kVDSOBo.js +0 -4214
- package/src/ui/dist/assets/NotebookEditor-C3VQ7ylN.css +0 -1405
- package/src/ui/dist/assets/NotebookEditor-SoJ8X-MO.js +0 -84873
- package/src/ui/dist/assets/PdfLoader-C-Y707R3.css +0 -49
- package/src/ui/dist/assets/PdfLoader-DElVuHl9.js +0 -25468
- package/src/ui/dist/assets/PdfMarkdownPlugin-Bq88XT4G.js +0 -409
- package/src/ui/dist/assets/PdfViewerPlugin-CsCXMo9S.js +0 -3095
- package/src/ui/dist/assets/PdfViewerPlugin-DQ11QcSf.css +0 -3627
- package/src/ui/dist/assets/SearchPlugin-DDMrGDkh.css +0 -379
- package/src/ui/dist/assets/SearchPlugin-oUPvy19k.js +0 -741
- package/src/ui/dist/assets/TextViewerPlugin-CRkT9yNy.js +0 -472
- package/src/ui/dist/assets/VNCViewer-BgbuvWhR.js +0 -18821
- package/src/ui/dist/assets/awareness-C0NPR2Dj.js +0 -292
- package/src/ui/dist/assets/bot-v_RASACv.js +0 -21
- package/src/ui/dist/assets/browser-BAcuE0Xj.js +0 -2895
- package/src/ui/dist/assets/code-5hC9d0VH.js +0 -17
- package/src/ui/dist/assets/file-content-D1PxfOrp.js +0 -377
- package/src/ui/dist/assets/file-diff-panel-DG1oT_Hj.js +0 -92
- package/src/ui/dist/assets/file-jump-queue-r5XKgJEV.js +0 -16
- package/src/ui/dist/assets/file-socket-BmdFYQlk.js +0 -58
- package/src/ui/dist/assets/function-B5QZkkHC.js +0 -1895
- package/src/ui/dist/assets/image-Dqe2X2tW.js +0 -18
- package/src/ui/dist/assets/index-BQG-1s2o.css +0 -12553
- package/src/ui/dist/assets/index-DVsMKK_y.js +0 -25
- package/src/ui/dist/assets/index-Duvz8Ip0.js +0 -159
- package/src/ui/dist/assets/index-Nt9hS4ck.js +0 -244829
- package/src/ui/dist/assets/index-RDlNXXx1.js +0 -120
- package/src/ui/dist/assets/monaco-DIXge1CP.js +0 -623
- package/src/ui/dist/assets/pdf-effect-queue-BBTTQaO-.js +0 -47
- package/src/ui/dist/assets/pdf_viewer-e0g1is2C.js +0 -8206
- package/src/ui/dist/assets/popover-BWlolyxo.js +0 -476
- package/src/ui/dist/assets/project-sync-BM5PkFH4.js +0 -297
- package/src/ui/dist/assets/select-D4dAtrA8.js +0 -1690
- package/src/ui/dist/assets/sigma-CKbE5jJT.js +0 -22
- package/src/ui/dist/assets/square-check-big-CZNGMgiB.js +0 -17
- package/src/ui/dist/assets/trash-DaB37xAz.js +0 -32
- package/src/ui/dist/assets/useCliAccess-C2OmAcWe.js +0 -957
- package/src/ui/dist/assets/useFileDiffOverlay-Dowd1Ij4.js +0 -53
- package/src/ui/dist/assets/wrap-text-BGjAhAUq.js +0 -35
- package/src/ui/dist/assets/yjs-DncrqiZ8.js +0 -11243
- package/src/ui/dist/assets/zoom-out-dMZQMXzc.js +0 -34
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
---
|
|
2
2
|
name: rebuttal
|
|
3
3
|
description: Use when a quest already has a paper, draft, or review package and the task is to map reviewer feedback into experiments, manuscript deltas, and a durable rebuttal / revision response.
|
|
4
|
+
skill_role: companion
|
|
4
5
|
---
|
|
5
6
|
|
|
6
7
|
# Rebuttal
|
|
@@ -18,6 +19,7 @@ The task is “respond to concrete reviewer pressure with the smallest honest se
|
|
|
18
19
|
- Message templates are references only. Adapt to the actual context and vary wording so updates feel natural and non-robotic.
|
|
19
20
|
- If a threaded user reply arrives, interpret it relative to the latest rebuttal progress update before assuming the task changed completely.
|
|
20
21
|
- When the rebuttal plan, the main supplementary-evidence package, or the final response bundle becomes durable, send one richer `artifact.interact(kind='milestone', reply_mode='threaded', ...)` update that says what reviewer concerns are now addressed, what still remains open, and what happens next.
|
|
22
|
+
- Hard execution rule: if this stage needs terminal work such as manuscript builds, scripted checks, Git inspection, or reviewer-linked experiment launches, every such command must go through `bash_exec`.
|
|
21
23
|
|
|
22
24
|
## Purpose
|
|
23
25
|
|
|
@@ -423,7 +425,7 @@ Open additional skills only when the rebuttal workflow requires them:
|
|
|
423
425
|
|
|
424
426
|
Use these tools deliberately:
|
|
425
427
|
|
|
426
|
-
- `artifact.record(
|
|
428
|
+
- `artifact.record(payload={'kind': 'decision', ...})`
|
|
427
429
|
- route choice, claim downgrade, literature-audit launch, baseline-recovery launch, supplementary-experiment launch, rebuttal completion recommendation
|
|
428
430
|
- `artifact.create_analysis_campaign(...)`
|
|
429
431
|
- multi-slice reviewer-driven supplementary work
|
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
---
|
|
2
2
|
name: review
|
|
3
3
|
description: Use when a draft, paper, or paper-like report is substantial enough for an independent skeptical audit before finalization, rebuttal, or revision routing.
|
|
4
|
+
skill_role: companion
|
|
4
5
|
---
|
|
5
6
|
|
|
6
7
|
# Review
|
|
@@ -19,6 +20,7 @@ It is also not the same as `rebuttal`.
|
|
|
19
20
|
- Follow the shared interaction contract injected by the system prompt.
|
|
20
21
|
- For ordinary active work, prefer a concise progress update once work has crossed roughly 6 tool calls with a human-meaningful delta, and do not drift beyond roughly 12 tool calls or about 8 minutes without a user-visible update.
|
|
21
22
|
- When the review report, revision plan, or follow-up experiment TODO list becomes durable, send a richer `artifact.interact(kind='milestone', reply_mode='threaded', ...)` update that says what the main risks are, what should be fixed next, and whether the next route is writing, experiment, or claim downgrade.
|
|
23
|
+
- Hard execution rule: if this stage needs terminal work such as document builds, scripted checks, Git inspection, or file inspection, every such command must go through `bash_exec`.
|
|
22
24
|
|
|
23
25
|
## Purpose
|
|
24
26
|
|
|
@@ -356,7 +358,7 @@ Open additional skills only when the review workflow requires them:
|
|
|
356
358
|
|
|
357
359
|
Use these tools deliberately:
|
|
358
360
|
|
|
359
|
-
- `artifact.record(
|
|
361
|
+
- `artifact.record(payload={'kind': 'decision', ...})`
|
|
360
362
|
- review conclusion, claim downgrade recommendation, route choice, stop/go recommendation
|
|
361
363
|
- `artifact.create_analysis_campaign(...)`
|
|
362
364
|
- when the experiment TODO list should become concrete follow-up slices
|
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
---
|
|
2
2
|
name: scout
|
|
3
3
|
description: Use when a quest needs problem framing, literature scouting, dataset or metric clarification, or baseline discovery before deeper work.
|
|
4
|
+
skill_role: stage
|
|
4
5
|
---
|
|
5
6
|
|
|
6
7
|
# Scout
|
|
@@ -15,6 +16,13 @@ Use this skill when the quest does not yet have a stable research frame.
|
|
|
15
16
|
- If a threaded user reply arrives, interpret it relative to the latest scout progress update before assuming the task changed completely.
|
|
16
17
|
- When scouting actually resolves the framing ambiguity, locks the evaluation contract, or makes the next anchor obvious, send one richer `artifact.interact(kind='milestone', reply_mode='threaded', ...)` update that says what is now clear, why it matters, and which stage should come next.
|
|
17
18
|
|
|
19
|
+
## Tool discipline
|
|
20
|
+
|
|
21
|
+
- **Do not use native `shell_command` / `command_execution` in this skill.**
|
|
22
|
+
- **Any shell, CLI, Python, bash, node, git, npm, uv, or repo-inspection execution must go through `bash_exec(...)`.**
|
|
23
|
+
- **For git inspection inside the current quest repository or worktree, prefer `artifact.git(...)` before raw shell git commands.**
|
|
24
|
+
- **If scouting only needs durable quest context, prefer `artifact.read_quest_documents(...)`, `artifact.get_quest_state(...)`, and `memory.*` instead of shelling out.**
|
|
25
|
+
|
|
18
26
|
## Stage purpose
|
|
19
27
|
|
|
20
28
|
The scout stage exists to answer the smallest set of framing questions required to make the rest of the quest efficient:
|
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
---
|
|
2
2
|
name: write
|
|
3
3
|
description: Use when a quest has enough evidence to draft or refine a paper, report, or research summary without inventing missing support.
|
|
4
|
+
skill_role: stage
|
|
4
5
|
---
|
|
5
6
|
|
|
6
7
|
# Write
|
|
@@ -21,6 +22,7 @@ This skill intentionally absorbs the strongest old DeepScientist writing discipl
|
|
|
21
22
|
|
|
22
23
|
- Follow the shared interaction contract injected by the system prompt.
|
|
23
24
|
- For ordinary active work, prefer a concise progress update once work has crossed roughly 6 tool calls with a human-meaningful delta, and do not drift beyond roughly 12 tool calls or about 8 minutes without a user-visible update.
|
|
25
|
+
- Hard execution rule: every terminal command in this stage must go through `bash_exec`; do not use any other terminal path for LaTeX builds, figure generation, scripted export, Git, Python, package-manager, or file-inspection commands.
|
|
24
26
|
- Prefer `bash_exec` for durable document-build commands such as LaTeX compilation, figure regeneration, and scripted export steps so logs remain quest-local and reviewable.
|
|
25
27
|
- Keep ordinary subtask completions concise. When a paper/draft milestone is actually completed, upgrade to a richer `artifact.interact(kind='milestone', reply_mode='threaded', ...)` report instead of another short progress update.
|
|
26
28
|
- That richer writing-stage milestone report should normally cover: which draft, section, or outline milestone finished, what is now supportable, what is still missing, and the exact recommended next revision or route decision.
|
|
@@ -63,6 +65,7 @@ It exists to test whether the current evidence can support a stable narrative.
|
|
|
63
65
|
Writing should happen on a dedicated `paper/*` branch/worktree derived from the source main-experiment `run/*` branch.
|
|
64
66
|
Treat that paper branch as the writing surface, and treat the parent run branch as the evidence source that writing must faithfully reflect.
|
|
65
67
|
Do not run new main experiments from the paper branch; if writing exposes a missing evidence requirement, route back through `decision`, `activate_branch`, `experiment`, or `analysis-campaign`.
|
|
68
|
+
Once an outline is selected, treat that branch/worktree as an active paper line with its own contract, not just as a late draft folder.
|
|
66
69
|
|
|
67
70
|
If the evidence is incomplete, contradictory, or too weak, the correct output is:
|
|
68
71
|
|
|
@@ -85,6 +88,17 @@ The approved outline should be a real structured object, typically containing:
|
|
|
85
88
|
- `experimental_designs`
|
|
86
89
|
- `contributions`
|
|
87
90
|
|
|
91
|
+
Treat the approved outline as the paper contract, not just a narrative sketch.
|
|
92
|
+
It should decide:
|
|
93
|
+
|
|
94
|
+
- which sections exist
|
|
95
|
+
- which experiments or analysis items each section depends on
|
|
96
|
+
- which evidence belongs in main text, appendix, or reference-only support
|
|
97
|
+
|
|
98
|
+
If the selected outline is missing those links, repair the outline and matrix before further drafting.
|
|
99
|
+
Prefer an author-facing outline folder under `paper/outline/` with section-level files, and treat `paper/selected_outline.json` as the compiled compatibility view of that contract.
|
|
100
|
+
`paper/evidence_ledger.json` remains the runtime truth of what evidence actually exists and where it maps.
|
|
101
|
+
|
|
88
102
|
## Writing mental guardrails
|
|
89
103
|
|
|
90
104
|
- Writing starts when the claim and evidence structure are stable enough, not when prose feels easy.
|
|
@@ -120,8 +134,27 @@ Before writing seriously, confirm:
|
|
|
120
134
|
- the claims you intend to write are backed by durable artifacts
|
|
121
135
|
- the code/diff path is available for method fidelity checks
|
|
122
136
|
- the evaluation contract is explicit
|
|
137
|
+
- the active paper line is known
|
|
138
|
+
- the selected outline is present and reflects the current evidence line
|
|
139
|
+
- `paper/outline/manifest.json` and any relevant section files are present when the outline folder flow is enabled
|
|
140
|
+
- `paper/evidence_ledger.json` or `paper/evidence_ledger.md` reflects the current mapped paper evidence set
|
|
141
|
+
- `paper/paper_experiment_matrix.md` reflects the current paper-facing experiment and analysis frontier when that planning surface is in use
|
|
142
|
+
- completed relevant analysis results under `experiments/analysis-results/` are mapped into the selected outline or matrix rather than floating only as standalone reports
|
|
123
143
|
|
|
124
144
|
If major claims lack evidence, surface the gap first.
|
|
145
|
+
If the selected outline, outline folder, evidence ledger, or matrix feels underspecified, read `references/outline-evidence-contract-example.md` before drafting further.
|
|
146
|
+
For paper-facing work, use this hard order instead of drifting between surfaces:
|
|
147
|
+
|
|
148
|
+
1. refresh the active outline folder section files first when they exist
|
|
149
|
+
2. sync the compiled `paper/selected_outline.json`
|
|
150
|
+
3. confirm `paper/evidence_ledger.json` reflects the same mapped evidence set
|
|
151
|
+
4. only then draft, revise, review, or bundle prose
|
|
152
|
+
|
|
153
|
+
Do not draft first and promise to repair the paper contract later.
|
|
154
|
+
If the current blocker set is not obvious from files, call `artifact.get_paper_contract_health(detail='full')` before deciding whether to keep writing or to return to contract repair / supplementary work.
|
|
155
|
+
If the active quest status, current workspace, recent durable runs, or pending interaction state is unclear after a restart, call `artifact.get_quest_state(detail='summary')` first.
|
|
156
|
+
If the exact current brief/plan/status/summary wording matters for the current drafting decision, call `artifact.read_quest_documents(...)` instead of relying on prompt-injected excerpts.
|
|
157
|
+
If you need earlier user/assistant continuity to interpret the current writing request, call `artifact.get_conversation_context(...)` before changing the route.
|
|
125
158
|
|
|
126
159
|
## Truth sources
|
|
127
160
|
|
|
@@ -139,12 +172,19 @@ Use these as the canonical evidence base:
|
|
|
139
172
|
|
|
140
173
|
Do not rely on memory alone for numbers.
|
|
141
174
|
Always prefer direct artifact paths for claims.
|
|
175
|
+
Do not keep drafting from remembered storyline summaries if the active paper line already has a stricter durable contract in its outline folder, selected outline, evidence ledger, experiment matrix, or paper-facing analysis mirrors.
|
|
142
176
|
|
|
143
177
|
## Required durable outputs
|
|
144
178
|
|
|
145
179
|
The write stage should usually produce most of the following:
|
|
146
180
|
|
|
147
|
-
- `paper/outline.
|
|
181
|
+
- `paper/outline/manifest.json`
|
|
182
|
+
- `paper/outline/sections/<section_id>/section.md`
|
|
183
|
+
- `paper/outline/sections/<section_id>/result_table.json`
|
|
184
|
+
- `paper/outline/sections/<section_id>/experiment_setup.md`
|
|
185
|
+
- `paper/outline/sections/<section_id>/findings.md`
|
|
186
|
+
- `paper/outline/sections/<section_id>/impact.md`
|
|
187
|
+
- `paper/outline.md` or equivalent outline view
|
|
148
188
|
- `paper/selected_outline.json`
|
|
149
189
|
- `paper/paper_experiment_matrix.md`
|
|
150
190
|
- `paper/paper_experiment_matrix.json`
|
|
@@ -172,7 +212,8 @@ The write stage should usually produce most of the following:
|
|
|
172
212
|
|
|
173
213
|
The exact paths may vary, but the structure and meaning should remain clear.
|
|
174
214
|
|
|
175
|
-
Treat the
|
|
215
|
+
Treat the author-facing outline folder and compiled selected outline together as the authoritative blueprint for the draft.
|
|
216
|
+
If both exist, update the outline folder first and then keep `paper/selected_outline.json` synchronized as the compiled compatibility output.
|
|
176
217
|
Treat `paper/draft.md` or the equivalent working note as the running evidence ledger where useful findings, citation notes, and writing decisions are accumulated as work proceeds.
|
|
177
218
|
After every significant search, plot, paragraph, revision pass, or claim downgrade, update the working note and writing plan immediately so important writing state is not trapped in transient chat output.
|
|
178
219
|
For any substantial paper-writing line, keep `paper/writing_plan.md` or an equivalent durable plan detailed enough that another agent could resume from it without reconstructing the full logic from chat alone.
|
|
@@ -212,8 +253,10 @@ For any paper-like writing line that has more than a trivial single-result story
|
|
|
212
253
|
- `paper/paper_experiment_matrix.json`
|
|
213
254
|
|
|
214
255
|
Use `references/paper-experiment-matrix-template.md` when helpful.
|
|
256
|
+
Use `references/outline-evidence-contract-example.md` when the paper line needs a concrete example of section binding, `required_items`, and `result_table` updates.
|
|
215
257
|
|
|
216
|
-
The paper experiment matrix is the
|
|
258
|
+
The paper experiment matrix is the planning and reporting surface for the paper line.
|
|
259
|
+
It is not the master truth when it disagrees with the selected outline contract or `paper/evidence_ledger.json`.
|
|
217
260
|
It exists to prevent two common failures:
|
|
218
261
|
|
|
219
262
|
- an outline that overweights post-hoc analysis and under-specifies paper-typical experiments
|
|
@@ -231,6 +274,18 @@ It should cover the full paper-facing experiment program beyond the already-fini
|
|
|
231
274
|
- failure-boundary or limitation-surface analyses
|
|
232
275
|
- case study or trace walkthrough rows as optional supporting material rather than mandatory core evidence
|
|
233
276
|
|
|
277
|
+
The matrix should also act as the ingestion gate for completed follow-up analysis:
|
|
278
|
+
|
|
279
|
+
- if a completed analysis campaign or slice is relevant to a paper claim, it must appear in the matrix as `main_required`, `appendix`, `reference_only`, or be excluded with a written reason
|
|
280
|
+
- do not allow completed analysis results to remain paper-invisible
|
|
281
|
+
|
|
282
|
+
The outline should be revised in lockstep with that matrix:
|
|
283
|
+
|
|
284
|
+
- before analysis begins, seed the section structure and expected evidence items
|
|
285
|
+
- after each completed slice, update the matching section's `result_table`
|
|
286
|
+
- if the outline folder exists, update the section's `experiment_setup.md`, `findings.md`, and `impact.md` instead of leaving those changes only in prose notes
|
|
287
|
+
- if a result weakens the claim, downgrade the section contract before polishing prose
|
|
288
|
+
|
|
234
289
|
Case study is usually optional.
|
|
235
290
|
Do not let it displace stronger quantitative evidence.
|
|
236
291
|
Efficiency or cost experiments are not mandatory in every paper, but they should be added whenever:
|
|
@@ -342,6 +397,15 @@ After every meaningful experiment outcome, even a null result or exclusion:
|
|
|
342
397
|
Do not decide the next supplementary experiment from memory alone when the matrix exists.
|
|
343
398
|
The matrix should be the authoritative experiment-routing surface for the paper line, and the selected outline's `experimental_designs` should stay consistent with that matrix rather than drifting away from it.
|
|
344
399
|
|
|
400
|
+
Before drafting any section, verify all of the following:
|
|
401
|
+
|
|
402
|
+
- the section exists in the selected outline
|
|
403
|
+
- the section's required experiment or analysis items are present in `paper/paper_experiment_matrix.*`
|
|
404
|
+
- every main-text-required item for that section is already completed or honestly blocked
|
|
405
|
+
- no completed relevant analysis slice remains unmapped
|
|
406
|
+
|
|
407
|
+
If any of those checks fails, stop drafting and repair the paper contract first.
|
|
408
|
+
|
|
345
409
|
## Venue template selection
|
|
346
410
|
|
|
347
411
|
For paper-like writing, use a real venue template rather than improvising a blank LaTeX tree.
|
|
@@ -385,14 +449,18 @@ For paper-like deliverables, the safest default order is:
|
|
|
385
449
|
2. activate or create the dedicated `paper/*` branch/worktree derived from the source run branch before durable outline selection or drafting
|
|
386
450
|
3. choose the venue template from `templates/`, copy it into `paper/latex/`, and default general ML work to `templates/iclr2026/` unless a stronger venue target exists
|
|
387
451
|
4. if the line benefits from an explicit outline contract, record one or more outline candidates with `artifact.submit_paper_outline(mode='candidate', ...)`
|
|
388
|
-
5. if one outline should become the durable paper contract, select or revise it with `artifact.submit_paper_outline(mode='select'|'revise', ...)
|
|
389
|
-
6. create or refresh `paper/
|
|
390
|
-
7.
|
|
391
|
-
8.
|
|
392
|
-
9.
|
|
393
|
-
10.
|
|
394
|
-
11.
|
|
395
|
-
12.
|
|
452
|
+
5. if one outline should become the durable paper contract, select or revise it with `artifact.submit_paper_outline(mode='select'|'revise', ...)`; that selection should be treated as opening or refreshing the active paper line
|
|
453
|
+
6. if the outline folder flow is enabled, create or refresh `paper/outline/manifest.json` and the relevant section files before stabilizing the experiments section
|
|
454
|
+
7. create or refresh `paper/paper_experiment_matrix.md` and `paper/paper_experiment_matrix.json` before stabilizing the experiments section
|
|
455
|
+
8. if the selected outline or matrix still exposes evidence gaps, launch an outline-bound and matrix-bound `artifact.create_analysis_campaign(...)` before drafting the experiments section as if it were settled
|
|
456
|
+
9. after every completed follow-up slice, reopen the selected outline and confirm the corresponding `result_table` row now reflects the real result rather than a placeholder
|
|
457
|
+
10. if the outline folder exists, immediately sync the affected section files so experiment setup, findings, and impact stay current on the paper line
|
|
458
|
+
11. after that sync, confirm `paper/evidence_ledger.json` and the paper line summary still agree before continuing prose work
|
|
459
|
+
12. plan and generate decisive figures or tables
|
|
460
|
+
13. draft sections directly from the evidence and the current working outline; do not force extra outline rounds when direct drafting is clearer and safer
|
|
461
|
+
14. run harsh review and revision cycles
|
|
462
|
+
15. proof, package, submit `artifact.submit_paper_bundle(...)` when the bundle is ready, and then pass to `finalize`
|
|
463
|
+
16. if the final paper PDF exists and QQ milestone media is enabled in config, the bundle-ready milestone may attach that PDF once
|
|
396
464
|
|
|
397
465
|
Before real drafting, force one explicit planning pass that stabilizes at least:
|
|
398
466
|
|
|
@@ -1202,6 +1270,7 @@ Preferred artifact choices:
|
|
|
1202
1270
|
- draft readiness when a user-facing checkpoint helps
|
|
1203
1271
|
- use `approval` when the user explicitly confirms a submission-critical choice
|
|
1204
1272
|
- use `artifact.submit_paper_outline(mode='candidate'|'select'|'revise', ...)` for the real outline lifecycle instead of leaving outline choice only in prose
|
|
1273
|
+
- when `mode='select'`, treat the selected outline as the activation point of the active paper line and keep its folder/json contract synchronized
|
|
1205
1274
|
- use `artifact.submit_paper_bundle(...)` before leaving the writing stage when the draft, plan, references, and packaging evidence are durable enough
|
|
1206
1275
|
- continue writing on the dedicated `paper/*` branch/worktree after analysis slices finish; treat the parent run or idea branch as the evidence source, not the drafting surface
|
|
1207
1276
|
|
|
@@ -1239,7 +1308,7 @@ Use these references when the deliverable is paper-like and you need a denser op
|
|
|
1239
1308
|
|
|
1240
1309
|
Exit the write stage only when one of the following is durably true:
|
|
1241
1310
|
|
|
1242
|
-
- the current draft is evidence-complete enough for `finalize`, including a selected outline and a durable paper bundle manifest when the deliverable is paper-like
|
|
1311
|
+
- the current draft is evidence-complete enough for `finalize`, including an active paper line, a selected outline, synchronized outline contract files, and a durable paper bundle manifest when the deliverable is paper-like
|
|
1243
1312
|
- a clear evidence gap has been recorded and the quest is routed backward
|
|
1244
1313
|
- a packaging or proofing blocker has been recorded and the next action is explicit
|
|
1245
1314
|
|
|
@@ -0,0 +1,107 @@
|
|
|
1
|
+
# Outline-Centered Paper Contract Example
|
|
2
|
+
|
|
3
|
+
Use this reference when the paper line needs a concrete example of:
|
|
4
|
+
|
|
5
|
+
- what a selected outline should look like before follow-up analysis
|
|
6
|
+
- how completed evidence should be written back into the outline
|
|
7
|
+
- what should block further drafting
|
|
8
|
+
|
|
9
|
+
## Minimal selected outline shape
|
|
10
|
+
|
|
11
|
+
```json
|
|
12
|
+
{
|
|
13
|
+
"outline_id": "outline-002",
|
|
14
|
+
"title": "Truth-Preserving Collaboration under Mixed Signals",
|
|
15
|
+
"story": "Motivation -> bottleneck -> remedy -> evidence -> boundary",
|
|
16
|
+
"detailed_outline": {
|
|
17
|
+
"research_questions": [
|
|
18
|
+
"RQ1: Does the method improve the main benchmark under the accepted protocol?",
|
|
19
|
+
"RQ2: Which component actually causes the gain?",
|
|
20
|
+
"RQ3: Where does the method fail or regress?"
|
|
21
|
+
],
|
|
22
|
+
"experimental_designs": [
|
|
23
|
+
"Main benchmark comparison",
|
|
24
|
+
"Component ablation",
|
|
25
|
+
"Boundary / failure analysis"
|
|
26
|
+
],
|
|
27
|
+
"contributions": [
|
|
28
|
+
"A new route for source-aware collaboration",
|
|
29
|
+
"A controlled decomposition of the gain",
|
|
30
|
+
"A clearer limitation boundary"
|
|
31
|
+
]
|
|
32
|
+
},
|
|
33
|
+
"evidence_contract": {
|
|
34
|
+
"main_text_items_must_be_ready": true,
|
|
35
|
+
"appendix_items_may_be_ready_or_reference_only": true,
|
|
36
|
+
"record_results_back_into_outline": true,
|
|
37
|
+
"result_table_required": true
|
|
38
|
+
},
|
|
39
|
+
"sections": [
|
|
40
|
+
{
|
|
41
|
+
"section_id": "results-main",
|
|
42
|
+
"title": "Main Results",
|
|
43
|
+
"paper_role": "main_text",
|
|
44
|
+
"claims": ["C1"],
|
|
45
|
+
"required_items": ["run-main-001"],
|
|
46
|
+
"optional_items": [],
|
|
47
|
+
"status": "pending",
|
|
48
|
+
"result_table": []
|
|
49
|
+
},
|
|
50
|
+
{
|
|
51
|
+
"section_id": "analysis-mechanism",
|
|
52
|
+
"title": "Mechanism Analysis",
|
|
53
|
+
"paper_role": "main_text",
|
|
54
|
+
"claims": ["C2"],
|
|
55
|
+
"required_items": ["AN-ABL-001"],
|
|
56
|
+
"optional_items": [],
|
|
57
|
+
"status": "pending",
|
|
58
|
+
"result_table": []
|
|
59
|
+
},
|
|
60
|
+
{
|
|
61
|
+
"section_id": "analysis-boundary",
|
|
62
|
+
"title": "Boundary and Failure Analysis",
|
|
63
|
+
"paper_role": "appendix",
|
|
64
|
+
"claims": ["C3"],
|
|
65
|
+
"required_items": [],
|
|
66
|
+
"optional_items": ["AN-BND-001"],
|
|
67
|
+
"status": "planned",
|
|
68
|
+
"result_table": []
|
|
69
|
+
}
|
|
70
|
+
]
|
|
71
|
+
}
|
|
72
|
+
```
|
|
73
|
+
|
|
74
|
+
## After one completed analysis slice
|
|
75
|
+
|
|
76
|
+
Write the result back into the matching `section.result_table`.
|
|
77
|
+
|
|
78
|
+
```json
|
|
79
|
+
{
|
|
80
|
+
"item_id": "AN-ABL-001",
|
|
81
|
+
"title": "Remove corroboration module",
|
|
82
|
+
"kind": "analysis_slice",
|
|
83
|
+
"paper_role": "main_text",
|
|
84
|
+
"status": "completed",
|
|
85
|
+
"claim_links": ["C2"],
|
|
86
|
+
"metric_summary": "acc=0.811; delta=-0.046",
|
|
87
|
+
"result_summary": "Removing the corroboration module eliminates most of the measured gain.",
|
|
88
|
+
"source_paths": [
|
|
89
|
+
"experiments/analysis/analysis-1234/ablation/RESULT.md",
|
|
90
|
+
"experiments/analysis-results/analysis-1234/ablation.md"
|
|
91
|
+
],
|
|
92
|
+
"updated_at": "2026-03-28T00:00:00Z"
|
|
93
|
+
}
|
|
94
|
+
```
|
|
95
|
+
|
|
96
|
+
The matching section should then move from `pending` to:
|
|
97
|
+
|
|
98
|
+
- `ready` if every required item is ready
|
|
99
|
+
- `partial` if some required items are ready
|
|
100
|
+
- `pending` if the row exists but the result is not ready
|
|
101
|
+
|
|
102
|
+
## Drafting rules by case
|
|
103
|
+
|
|
104
|
+
- If a section has missing required items, stop prose expansion and repair the evidence contract first.
|
|
105
|
+
- If an analysis slice is completed but has no `section_id` or `item_id`, do not summarize it in the paper yet; map it first.
|
|
106
|
+
- If a result is only useful as support, keep it in `appendix` or `reference_only` instead of inflating the main text.
|
|
107
|
+
- If the result weakens the claim, record that downgrade in the outline before rewriting the section prose.
|
|
@@ -93,16 +93,18 @@ const buildQuestConfigItems = (questId, questRoot) => {
|
|
|
93
93
|
documentId: 'path::quest.yaml',
|
|
94
94
|
},
|
|
95
95
|
];
|
|
96
|
-
const
|
|
97
|
-
|
|
96
|
+
const codexCandidates = [`${questRoot}/.ds/codex-home/config.toml`, `${questRoot}/.codex/config.toml`];
|
|
97
|
+
const codexPath = codexCandidates.find((candidate) => fs.existsSync(candidate));
|
|
98
|
+
if (codexPath) {
|
|
99
|
+
const relativeCodexPath = codexPath.replace(`${questRoot}/`, '');
|
|
98
100
|
items.push({
|
|
99
|
-
id: `quest:${questId}
|
|
101
|
+
id: `quest:${questId}:${relativeCodexPath}`,
|
|
100
102
|
scope: 'quest',
|
|
101
|
-
name:
|
|
102
|
-
title:
|
|
103
|
+
name: relativeCodexPath,
|
|
104
|
+
title: relativeCodexPath,
|
|
103
105
|
path: codexPath,
|
|
104
106
|
writable: true,
|
|
105
|
-
documentId:
|
|
107
|
+
documentId: `path::${relativeCodexPath}`,
|
|
106
108
|
});
|
|
107
109
|
}
|
|
108
110
|
return items;
|
|
@@ -480,18 +482,21 @@ function openBrowser(url) {
|
|
|
480
482
|
}
|
|
481
483
|
spawn('xdg-open', [url], { detached: true, stdio: 'ignore' }).unref();
|
|
482
484
|
}
|
|
483
|
-
function buildProjectsUrl(baseUrl) {
|
|
485
|
+
function buildProjectsUrl(baseUrl, authToken) {
|
|
484
486
|
const target = new URL(baseUrl);
|
|
485
487
|
if (target.hostname === '0.0.0.0') {
|
|
486
488
|
target.hostname = '127.0.0.1';
|
|
487
489
|
}
|
|
488
490
|
target.pathname = '/projects';
|
|
489
491
|
target.search = '';
|
|
492
|
+
if (authToken) {
|
|
493
|
+
target.searchParams.set('token', authToken);
|
|
494
|
+
}
|
|
490
495
|
return target.toString();
|
|
491
496
|
}
|
|
492
|
-
function buildProjectUrl(baseUrl, questId) {
|
|
497
|
+
function buildProjectUrl(baseUrl, questId, authToken) {
|
|
493
498
|
if (!questId) {
|
|
494
|
-
return buildProjectsUrl(baseUrl);
|
|
499
|
+
return buildProjectsUrl(baseUrl, authToken);
|
|
495
500
|
}
|
|
496
501
|
const target = new URL(baseUrl);
|
|
497
502
|
if (target.hostname === '0.0.0.0') {
|
|
@@ -499,9 +504,12 @@ function buildProjectUrl(baseUrl, questId) {
|
|
|
499
504
|
}
|
|
500
505
|
target.pathname = `/projects/${questId}`;
|
|
501
506
|
target.search = '';
|
|
507
|
+
if (authToken) {
|
|
508
|
+
target.searchParams.set('token', authToken);
|
|
509
|
+
}
|
|
502
510
|
return target.toString();
|
|
503
511
|
}
|
|
504
|
-
export const AppContainer = ({ baseUrl, initialQuestId = null, }) => {
|
|
512
|
+
export const AppContainer = ({ baseUrl, initialQuestId = null, authToken = null, }) => {
|
|
505
513
|
const { exit } = useApp();
|
|
506
514
|
const [quests, setQuests] = useState([]);
|
|
507
515
|
const [connectors, setConnectors] = useState([]);
|
|
@@ -1604,6 +1612,9 @@ export const AppContainer = ({ baseUrl, initialQuestId = null, }) => {
|
|
|
1604
1612
|
setInput('');
|
|
1605
1613
|
setStatusLine(nextStatus);
|
|
1606
1614
|
}, []);
|
|
1615
|
+
const openConfigBrowser = useCallback((nextStatus) => {
|
|
1616
|
+
openConfigRoot(nextStatus);
|
|
1617
|
+
}, [openConfigRoot]);
|
|
1607
1618
|
const openConnectorBrowser = useCallback(async (targetConnector) => {
|
|
1608
1619
|
try {
|
|
1609
1620
|
const document = await loadConnectorsDocument();
|
|
@@ -2537,7 +2548,7 @@ export const AppContainer = ({ baseUrl, initialQuestId = null, }) => {
|
|
|
2537
2548
|
return;
|
|
2538
2549
|
}
|
|
2539
2550
|
if (key.ctrl && value.toLowerCase() === 'o') {
|
|
2540
|
-
openBrowser(buildProjectUrl(baseUrl, activeQuestId || browseQuestId));
|
|
2551
|
+
openBrowser(buildProjectUrl(baseUrl, activeQuestId || browseQuestId, authToken));
|
|
2541
2552
|
return;
|
|
2542
2553
|
}
|
|
2543
2554
|
if (key.ctrl && value.toLowerCase() === 'g') {
|
package/src/tui/dist/index.js
CHANGED
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
import React from 'react';
|
|
2
2
|
import { render } from 'ink';
|
|
3
3
|
import { AppContainer } from './app/AppContainer.js';
|
|
4
|
+
import { setDaemonAuthToken } from './lib/api.js';
|
|
4
5
|
import { isAlternateBufferEnabled, isIncrementalRenderingEnabled } from './utils/terminal.js';
|
|
5
6
|
const CLEAR_TO_END = '\x1b[0K';
|
|
6
7
|
const BRACKETED_PASTE_ENABLE = '\x1b[?2004h';
|
|
@@ -31,6 +32,8 @@ function parseArg(name) {
|
|
|
31
32
|
}
|
|
32
33
|
const baseUrl = parseArg('--base-url') ?? 'http://0.0.0.0:20999';
|
|
33
34
|
const questId = parseArg('--quest-id');
|
|
35
|
+
const authToken = parseArg('--auth-token');
|
|
36
|
+
setDaemonAuthToken(authToken);
|
|
34
37
|
const useAlternateBuffer = isAlternateBufferEnabled();
|
|
35
38
|
const useIncrementalRendering = isIncrementalRenderingEnabled();
|
|
36
39
|
const setBracketedPasteMode = (enabled) => {
|
|
@@ -54,7 +57,7 @@ const closeBracketedPasteMode = () => {
|
|
|
54
57
|
};
|
|
55
58
|
setBracketedPasteMode(true);
|
|
56
59
|
process.once('exit', closeBracketedPasteMode);
|
|
57
|
-
const instance = render(React.createElement(AppContainer, { baseUrl: baseUrl, initialQuestId: questId }), {
|
|
60
|
+
const instance = render(React.createElement(AppContainer, { baseUrl: baseUrl, initialQuestId: questId, authToken: authToken }), {
|
|
58
61
|
stdout: withLineClearing(process.stdout),
|
|
59
62
|
stderr: process.stderr,
|
|
60
63
|
stdin: process.stdin,
|
package/src/tui/dist/lib/api.js
CHANGED
|
@@ -1,3 +1,29 @@
|
|
|
1
|
+
let daemonAuthToken = null;
|
|
2
|
+
function toHeaderRecord(headers) {
|
|
3
|
+
if (!headers)
|
|
4
|
+
return {};
|
|
5
|
+
if (headers instanceof Headers) {
|
|
6
|
+
return Object.fromEntries(headers.entries());
|
|
7
|
+
}
|
|
8
|
+
if (Array.isArray(headers)) {
|
|
9
|
+
return Object.fromEntries(headers);
|
|
10
|
+
}
|
|
11
|
+
return { ...headers };
|
|
12
|
+
}
|
|
13
|
+
function authHeaders(headers) {
|
|
14
|
+
const normalizedToken = typeof daemonAuthToken === 'string' ? daemonAuthToken.trim() : '';
|
|
15
|
+
if (!normalizedToken) {
|
|
16
|
+
return toHeaderRecord(headers);
|
|
17
|
+
}
|
|
18
|
+
return {
|
|
19
|
+
...toHeaderRecord(headers),
|
|
20
|
+
Authorization: `Bearer ${normalizedToken}`,
|
|
21
|
+
};
|
|
22
|
+
}
|
|
23
|
+
export function setDaemonAuthToken(value) {
|
|
24
|
+
const normalized = typeof value === 'string' ? value.trim() : '';
|
|
25
|
+
daemonAuthToken = normalized || null;
|
|
26
|
+
}
|
|
1
27
|
async function parseResponse(response) {
|
|
2
28
|
if (!response.ok) {
|
|
3
29
|
throw new Error(await response.text());
|
|
@@ -6,10 +32,11 @@ async function parseResponse(response) {
|
|
|
6
32
|
}
|
|
7
33
|
export async function api(baseUrl, path, init) {
|
|
8
34
|
const response = await fetch(`${baseUrl}${path}`, {
|
|
35
|
+
...init,
|
|
9
36
|
headers: {
|
|
10
37
|
'Content-Type': 'application/json',
|
|
38
|
+
...authHeaders(init?.headers),
|
|
11
39
|
},
|
|
12
|
-
...init,
|
|
13
40
|
});
|
|
14
41
|
return parseResponse(response);
|
|
15
42
|
}
|
|
@@ -68,6 +95,7 @@ export const client = {
|
|
|
68
95
|
const response = await fetch(client.eventsStreamUrl(baseUrl, questId, cursor), {
|
|
69
96
|
headers: {
|
|
70
97
|
Accept: 'text/event-stream',
|
|
98
|
+
...authHeaders(),
|
|
71
99
|
},
|
|
72
100
|
signal: callbacks.signal,
|
|
73
101
|
});
|
|
@@ -128,7 +156,9 @@ export const client = {
|
|
|
128
156
|
search.set('order', params.order);
|
|
129
157
|
}
|
|
130
158
|
const suffix = search.toString() ? `?${search.toString()}` : '';
|
|
131
|
-
const response = await fetch(`${baseUrl}/api/quests/${questId}/bash/sessions/${bashId}/logs${suffix}
|
|
159
|
+
const response = await fetch(`${baseUrl}/api/quests/${questId}/bash/sessions/${bashId}/logs${suffix}`, {
|
|
160
|
+
headers: authHeaders(),
|
|
161
|
+
});
|
|
132
162
|
if (!response.ok) {
|
|
133
163
|
throw new Error(await response.text());
|
|
134
164
|
}
|
|
@@ -151,7 +181,7 @@ export const client = {
|
|
|
151
181
|
}
|
|
152
182
|
const response = await fetch(`${baseUrl}/api/quests/${questId}/bash/sessions/${bashId}/stream`, {
|
|
153
183
|
method: 'GET',
|
|
154
|
-
headers,
|
|
184
|
+
headers: authHeaders(headers),
|
|
155
185
|
signal: callbacks.signal,
|
|
156
186
|
});
|
|
157
187
|
if (!response.ok || !response.body) {
|