@researai/deepscientist 1.5.14 → 1.5.15
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 +8 -0
- package/assets/branding/logo-raster.png +0 -0
- package/bin/ds.js +134 -49
- package/docs/en/00_QUICK_START.md +2 -2
- package/docs/en/01_SETTINGS_REFERENCE.md +20 -4
- package/docs/en/03_QQ_CONNECTOR_GUIDE.md +19 -0
- package/docs/en/10_WEIXIN_CONNECTOR_GUIDE.md +20 -0
- package/docs/en/14_PROMPT_SKILLS_AND_MCP_GUIDE.md +2 -0
- 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/README.md +6 -0
- package/docs/zh/00_QUICK_START.md +2 -2
- package/docs/zh/01_SETTINGS_REFERENCE.md +20 -4
- package/docs/zh/03_QQ_CONNECTOR_GUIDE.md +19 -0
- package/docs/zh/10_WEIXIN_CONNECTOR_GUIDE.md +20 -0
- package/docs/zh/14_PROMPT_SKILLS_AND_MCP_GUIDE.md +2 -0
- 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/README.md +6 -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/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 +3534 -191
- 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 +79 -64
- package/src/deepscientist/bash_exec/shells.py +87 -0
- package/src/deepscientist/bridges/connectors.py +51 -2
- package/src/deepscientist/config/models.py +6 -3
- package/src/deepscientist/config/service.py +7 -2
- package/src/deepscientist/connector/weixin_support.py +122 -1
- package/src/deepscientist/daemon/api/handlers.py +75 -4
- package/src/deepscientist/daemon/api/router.py +1 -0
- package/src/deepscientist/daemon/app.py +758 -206
- package/src/deepscientist/doctor.py +51 -0
- package/src/deepscientist/file_lock.py +48 -0
- package/src/deepscientist/gitops/diff.py +167 -1
- package/src/deepscientist/mcp/server.py +173 -5
- package/src/deepscientist/process_control.py +161 -0
- package/src/deepscientist/prompts/builder.py +267 -442
- package/src/deepscientist/quest/service.py +2255 -163
- package/src/deepscientist/quest/stage_views.py +171 -0
- package/src/deepscientist/runners/base.py +2 -0
- package/src/deepscientist/runners/codex.py +88 -5
- package/src/deepscientist/runners/runtime_overrides.py +17 -1
- package/src/prompts/contracts/shared_interaction.md +13 -4
- package/src/prompts/system.md +916 -72
- package/src/skills/analysis-campaign/SKILL.md +31 -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 +2 -0
- package/src/skills/decision/SKILL.md +19 -2
- package/src/skills/experiment/SKILL.md +8 -2
- package/src/skills/finalize/SKILL.md +18 -0
- package/src/skills/idea/SKILL.md +78 -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 +1 -1
- package/src/skills/optimize/SKILL.md +1644 -0
- package/src/skills/rebuttal/SKILL.md +2 -1
- package/src/skills/review/SKILL.md +2 -1
- package/src/skills/write/SKILL.md +80 -12
- package/src/skills/write/references/outline-evidence-contract-example.md +107 -0
- package/src/tui/dist/app/AppContainer.js +3 -0
- package/src/tui/package.json +1 -1
- package/src/ui/dist/assets/{AiManusChatView-DaF9Nge_.js → AiManusChatView-DDjbFnbt.js} +12 -12
- package/src/ui/dist/assets/{AnalysisPlugin-BSVx6dXE.js → AnalysisPlugin-Yb5IdmaU.js} +1 -1
- package/src/ui/dist/assets/CliPlugin-e64sreyu.js +31037 -0
- package/src/ui/dist/assets/{CodeEditorPlugin-DU9G0Tox.js → CodeEditorPlugin-C4D2TIkU.js} +8 -8
- package/src/ui/dist/assets/{CodeViewerPlugin-DoX_fI9l.js → CodeViewerPlugin-BVoNZIvC.js} +5 -5
- package/src/ui/dist/assets/{DocViewerPlugin-C4FWIXuU.js → DocViewerPlugin-CLChbllo.js} +3 -3
- package/src/ui/dist/assets/{GitDiffViewerPlugin-BgfFMgtf.js → GitDiffViewerPlugin-C4xeFyFQ.js} +20 -20
- package/src/ui/dist/assets/{ImageViewerPlugin-tcPkfY_x.js → ImageViewerPlugin-OiMUAcLi.js} +5 -5
- package/src/ui/dist/assets/{LabCopilotPanel-_dKV60Bf.js → LabCopilotPanel-BjD2ThQF.js} +11 -11
- package/src/ui/dist/assets/{LabPlugin-Bje0ayoC.js → LabPlugin-DQPg-NrB.js} +2 -2
- package/src/ui/dist/assets/{LatexPlugin-CVsBzAln.js → LatexPlugin-CI05XAV9.js} +7 -7
- package/src/ui/dist/assets/{MarkdownViewerPlugin-xjmrqv_8.js → MarkdownViewerPlugin-DpeBLYZf.js} +4 -4
- package/src/ui/dist/assets/{MarketplacePlugin-mMM2A8wP.js → MarketplacePlugin-DolE58Q2.js} +3 -3
- package/src/ui/dist/assets/{NotebookEditor-3kVDSOBo.js → NotebookEditor-7Qm2rSWD.js} +11 -11
- package/src/ui/dist/assets/{NotebookEditor-SoJ8X-MO.js → NotebookEditor-C1kWaxKi.js} +1 -1
- package/src/ui/dist/assets/{PdfLoader-DElVuHl9.js → PdfLoader-BfOHw8Zw.js} +1 -1
- package/src/ui/dist/assets/{PdfMarkdownPlugin-Bq88XT4G.js → PdfMarkdownPlugin-BulDREv1.js} +2 -2
- package/src/ui/dist/assets/{PdfViewerPlugin-CsCXMo9S.js → PdfViewerPlugin-C-daaOaL.js} +10 -10
- package/src/ui/dist/assets/{SearchPlugin-oUPvy19k.js → SearchPlugin-CjpaiJ3A.js} +1 -1
- package/src/ui/dist/assets/{TextViewerPlugin-CRkT9yNy.js → TextViewerPlugin-BxIyqPQC.js} +5 -5
- package/src/ui/dist/assets/{VNCViewer-BgbuvWhR.js → VNCViewer-HAg9mF7M.js} +10 -10
- package/src/ui/dist/assets/{bot-v_RASACv.js → bot-0DYntytV.js} +1 -1
- package/src/ui/dist/assets/{code-5hC9d0VH.js → code-B20Slj_w.js} +1 -1
- package/src/ui/dist/assets/{file-content-D1PxfOrp.js → file-content-DT24KFma.js} +1 -1
- package/src/ui/dist/assets/{file-diff-panel-DG1oT_Hj.js → file-diff-panel-DK13YPql.js} +1 -1
- package/src/ui/dist/assets/{file-socket-BmdFYQlk.js → file-socket-B4T2o4nR.js} +1 -1
- package/src/ui/dist/assets/{image-Dqe2X2tW.js → image-DSeR_sDS.js} +1 -1
- package/src/ui/dist/assets/{index-RDlNXXx1.js → index-BrFje2Uk.js} +2 -2
- package/src/ui/dist/assets/{index-DVsMKK_y.js → index-BwRJaoTl.js} +1 -1
- package/src/ui/dist/assets/{index-Nt9hS4ck.js → index-D_E4281X.js} +5007 -28514
- package/src/ui/dist/assets/{index-Duvz8Ip0.js → index-DnYB3xb1.js} +12 -12
- package/src/ui/dist/assets/{index-BQG-1s2o.css → index-G7AcWcMu.css} +43 -2
- package/src/ui/dist/assets/{monaco-DIXge1CP.js → monaco-LExaAN3Y.js} +1 -1
- package/src/ui/dist/assets/{pdf-effect-queue-BBTTQaO-.js → pdf-effect-queue-BJk5okWJ.js} +1 -1
- package/src/ui/dist/assets/{popover-BWlolyxo.js → popover-D3Gg_FoV.js} +1 -1
- package/src/ui/dist/assets/{project-sync-BM5PkFH4.js → project-sync-C_ygLlVU.js} +1 -1
- package/src/ui/dist/assets/{select-D4dAtrA8.js → select-CpAK6uWm.js} +2 -2
- package/src/ui/dist/assets/{sigma-CKbE5jJT.js → sigma-DEccaSgk.js} +1 -1
- package/src/ui/dist/assets/{square-check-big-CZNGMgiB.js → square-check-big-uUfyVsbD.js} +1 -1
- package/src/ui/dist/assets/{trash-DaB37xAz.js → trash-CXvwwSe8.js} +1 -1
- package/src/ui/dist/assets/{useCliAccess-C2OmAcWe.js → useCliAccess-Bnop4mgR.js} +1 -1
- package/src/ui/dist/assets/{useFileDiffOverlay-Dowd1Ij4.js → useFileDiffOverlay-B8eUAX0I.js} +1 -1
- package/src/ui/dist/assets/{wrap-text-BGjAhAUq.js → wrap-text-9vbOBpkW.js} +1 -1
- package/src/ui/dist/assets/{zoom-out-dMZQMXzc.js → zoom-out-BgVMmOW4.js} +1 -1
- package/src/ui/dist/index.html +2 -2
- package/src/ui/dist/assets/CliPlugin-C9gzJX41.js +0 -5905
|
@@ -0,0 +1,161 @@
|
|
|
1
|
+
from __future__ import annotations
|
|
2
|
+
|
|
3
|
+
import os
|
|
4
|
+
from pathlib import Path
|
|
5
|
+
import signal
|
|
6
|
+
import subprocess
|
|
7
|
+
import time
|
|
8
|
+
from typing import Any
|
|
9
|
+
|
|
10
|
+
|
|
11
|
+
def process_session_popen_kwargs(
|
|
12
|
+
*,
|
|
13
|
+
hide_window: bool = False,
|
|
14
|
+
new_process_group: bool = True,
|
|
15
|
+
) -> dict[str, Any]:
|
|
16
|
+
if os.name == "nt": # pragma: no cover - exercised on Windows
|
|
17
|
+
creationflags = 0
|
|
18
|
+
if new_process_group and hasattr(subprocess, "CREATE_NEW_PROCESS_GROUP"):
|
|
19
|
+
creationflags |= getattr(subprocess, "CREATE_NEW_PROCESS_GROUP")
|
|
20
|
+
if hide_window and hasattr(subprocess, "CREATE_NO_WINDOW"):
|
|
21
|
+
creationflags |= getattr(subprocess, "CREATE_NO_WINDOW")
|
|
22
|
+
payload: dict[str, Any] = {}
|
|
23
|
+
if creationflags:
|
|
24
|
+
payload["creationflags"] = creationflags
|
|
25
|
+
if hide_window and hasattr(subprocess, "STARTUPINFO") and hasattr(subprocess, "STARTF_USESHOWWINDOW"):
|
|
26
|
+
startupinfo = subprocess.STARTUPINFO()
|
|
27
|
+
startupinfo.dwFlags |= getattr(subprocess, "STARTF_USESHOWWINDOW")
|
|
28
|
+
startupinfo.wShowWindow = getattr(subprocess, "SW_HIDE", 0)
|
|
29
|
+
payload["startupinfo"] = startupinfo
|
|
30
|
+
return payload
|
|
31
|
+
if new_process_group:
|
|
32
|
+
return {
|
|
33
|
+
"start_new_session": True,
|
|
34
|
+
}
|
|
35
|
+
return {}
|
|
36
|
+
|
|
37
|
+
|
|
38
|
+
def is_process_alive(pid: object) -> bool:
|
|
39
|
+
if not isinstance(pid, int) or pid <= 0:
|
|
40
|
+
return False
|
|
41
|
+
if os.name != "nt":
|
|
42
|
+
proc_stat_path = Path("/proc") / str(pid) / "stat"
|
|
43
|
+
if proc_stat_path.exists():
|
|
44
|
+
try:
|
|
45
|
+
parts = proc_stat_path.read_text(encoding="utf-8").split()
|
|
46
|
+
except OSError:
|
|
47
|
+
parts = []
|
|
48
|
+
if len(parts) >= 3 and parts[2] == "Z":
|
|
49
|
+
return False
|
|
50
|
+
try:
|
|
51
|
+
os.kill(pid, 0)
|
|
52
|
+
except ProcessLookupError:
|
|
53
|
+
return False
|
|
54
|
+
except PermissionError:
|
|
55
|
+
return True
|
|
56
|
+
except OSError:
|
|
57
|
+
return False
|
|
58
|
+
return True
|
|
59
|
+
|
|
60
|
+
|
|
61
|
+
def terminate_process_ids(
|
|
62
|
+
*,
|
|
63
|
+
process_pid: int | None,
|
|
64
|
+
process_group_id: int | None,
|
|
65
|
+
force: bool = False,
|
|
66
|
+
) -> None:
|
|
67
|
+
if os.name == "nt": # pragma: no cover - exercised on Windows
|
|
68
|
+
if isinstance(process_pid, int) and process_pid > 0:
|
|
69
|
+
taskkill_args = ["taskkill", "/PID", str(process_pid), "/T"]
|
|
70
|
+
if force:
|
|
71
|
+
taskkill_args.append("/F")
|
|
72
|
+
subprocess.run(taskkill_args, check=False, capture_output=True, text=True)
|
|
73
|
+
if not force and is_process_alive(process_pid):
|
|
74
|
+
try:
|
|
75
|
+
os.kill(process_pid, signal.SIGTERM)
|
|
76
|
+
except OSError:
|
|
77
|
+
pass
|
|
78
|
+
return
|
|
79
|
+
if isinstance(process_group_id, int) and process_group_id > 0:
|
|
80
|
+
try:
|
|
81
|
+
os.killpg(process_group_id, signal.SIGKILL if force else signal.SIGTERM)
|
|
82
|
+
except ProcessLookupError:
|
|
83
|
+
return
|
|
84
|
+
return
|
|
85
|
+
if isinstance(process_pid, int) and process_pid > 0:
|
|
86
|
+
try:
|
|
87
|
+
os.kill(process_pid, signal.SIGKILL if force else signal.SIGTERM)
|
|
88
|
+
except ProcessLookupError:
|
|
89
|
+
return
|
|
90
|
+
|
|
91
|
+
|
|
92
|
+
def terminate_subprocess(
|
|
93
|
+
process: subprocess.Popen[Any],
|
|
94
|
+
*,
|
|
95
|
+
process_group_id: int | None = None,
|
|
96
|
+
force: bool = False,
|
|
97
|
+
prefer_ctrl_break: bool = False,
|
|
98
|
+
grace_seconds: float = 5.0,
|
|
99
|
+
) -> None:
|
|
100
|
+
if process.poll() is not None:
|
|
101
|
+
return
|
|
102
|
+
|
|
103
|
+
if os.name == "nt": # pragma: no cover - exercised on Windows
|
|
104
|
+
if not force and prefer_ctrl_break and hasattr(signal, "CTRL_BREAK_EVENT"):
|
|
105
|
+
try:
|
|
106
|
+
process.send_signal(signal.CTRL_BREAK_EVENT) # type: ignore[attr-defined]
|
|
107
|
+
except (AttributeError, OSError, ValueError):
|
|
108
|
+
try:
|
|
109
|
+
process.terminate()
|
|
110
|
+
except OSError:
|
|
111
|
+
return
|
|
112
|
+
elif not force:
|
|
113
|
+
try:
|
|
114
|
+
process.terminate()
|
|
115
|
+
except OSError:
|
|
116
|
+
return
|
|
117
|
+
else:
|
|
118
|
+
try:
|
|
119
|
+
process.kill()
|
|
120
|
+
except OSError:
|
|
121
|
+
return
|
|
122
|
+
if force:
|
|
123
|
+
return
|
|
124
|
+
deadline = time.monotonic() + max(grace_seconds, 0.1)
|
|
125
|
+
while time.monotonic() < deadline:
|
|
126
|
+
if process.poll() is not None:
|
|
127
|
+
return
|
|
128
|
+
time.sleep(0.05)
|
|
129
|
+
try:
|
|
130
|
+
process.kill()
|
|
131
|
+
except OSError:
|
|
132
|
+
return
|
|
133
|
+
return
|
|
134
|
+
|
|
135
|
+
if isinstance(process_group_id, int) and process_group_id > 0:
|
|
136
|
+
try:
|
|
137
|
+
os.killpg(process_group_id, signal.SIGKILL if force else signal.SIGTERM)
|
|
138
|
+
except ProcessLookupError:
|
|
139
|
+
return
|
|
140
|
+
else:
|
|
141
|
+
try:
|
|
142
|
+
process.kill() if force else process.terminate()
|
|
143
|
+
except OSError:
|
|
144
|
+
return
|
|
145
|
+
if force:
|
|
146
|
+
return
|
|
147
|
+
deadline = time.monotonic() + max(grace_seconds, 0.1)
|
|
148
|
+
while time.monotonic() < deadline:
|
|
149
|
+
if process.poll() is not None:
|
|
150
|
+
return
|
|
151
|
+
time.sleep(0.05)
|
|
152
|
+
if isinstance(process_group_id, int) and process_group_id > 0:
|
|
153
|
+
try:
|
|
154
|
+
os.killpg(process_group_id, signal.SIGKILL)
|
|
155
|
+
except ProcessLookupError:
|
|
156
|
+
return
|
|
157
|
+
elif process.poll() is None:
|
|
158
|
+
try:
|
|
159
|
+
process.kill()
|
|
160
|
+
except OSError:
|
|
161
|
+
return
|