scream-code 0.3.4 → 0.3.6
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/dist/main.mjs +57 -4
- package/package.json +2 -1
- package/scripts/postinstall/shortcut.mjs +61 -0
- package/scripts/postinstall.mjs +7 -0
package/dist/main.mjs
CHANGED
|
@@ -71217,6 +71217,31 @@ function renderBashDescription(shellName) {
|
|
|
71217
71217
|
function withoutBackgroundDescription(description) {
|
|
71218
71218
|
return description.replace(/\n\nIf `run_in_background=true`,[\s\S]*?point them to the `\/tasks` command, which opens an interactive panel; it has no subcommands\./, "\n\nBackground execution is disabled for this agent. Do not set `run_in_background=true`.").replace(` For possibly long-running foreground commands, set the \`timeout\` argument in seconds. Foreground commands default to ${String(DEFAULT_TIMEOUT_S)}s and allow up to ${String(MAX_TIMEOUT_S)}s.`, ` For possibly long-running commands, set the \`timeout\` argument in seconds. The default is ${String(DEFAULT_TIMEOUT_S)}s; foreground commands allow up to ${String(MAX_TIMEOUT_S)}s.`).replace(/\n- Prefer `run_in_background=true`[\s\S]*?conversation to continue before the command finishes\./, "\n- Do not set `run_in_background=true`; background task management tools are not available.");
|
|
71219
71219
|
}
|
|
71220
|
+
function rejectDangerousCommand(pattern, hint) {
|
|
71221
|
+
return {
|
|
71222
|
+
isError: true,
|
|
71223
|
+
output: `Scream Code self-protection blocked this command.\n\nThe command matches a dangerous pattern (${pattern}) that could kill Scream Code's own process.\n\nInstead: ${hint}`
|
|
71224
|
+
};
|
|
71225
|
+
}
|
|
71226
|
+
function validateCommand(command, isWindows) {
|
|
71227
|
+
const cmd = command;
|
|
71228
|
+
if (/\bkill\s+-9\s+-1\b/.test(cmd) || /\bkill\s+-KILL\s+-1\b/.test(cmd)) return rejectDangerousCommand("kill -9 -1", "Use 'kill <pid>' with a specific PID to terminate the target process.");
|
|
71229
|
+
if (/\b(killall|pkill)\b.*\b(node|scream)/i.test(cmd)) return rejectDangerousCommand("killall/pkill node", "Use 'kill <pid>' with a specific PID, or use the server's own stop command.");
|
|
71230
|
+
if (isWindows) {
|
|
71231
|
+
if (/\btasklist\b/.test(cmd) && /\bgrep\b.*\b(node|scream)/i.test(cmd) && /\b(taskkill|tskill)\b/.test(cmd)) return rejectDangerousCommand("tasklist | grep node | taskkill pipeline", "Use 'taskkill /PID <pid>' with the specific preview server PID. First run 'tasklist | grep -i node' to find the exact PID, then kill only that one.");
|
|
71232
|
+
if (/\btaskkill\b.*\/IM\s+node/i.test(cmd)) return rejectDangerousCommand("taskkill /IM node.exe", "Use 'taskkill /PID <pid>' with a specific PID instead of killing by image name.");
|
|
71233
|
+
if (/\bwmic\s+process\s+.*where\s+.*name.*=.*node/i.test(cmd) && /\bdelete\b/i.test(cmd)) return rejectDangerousCommand("wmic process delete", "Use 'taskkill /PID <pid>' with a specific PID instead.");
|
|
71234
|
+
if (/\bstop-process\b.*-Name\s+node/i.test(cmd)) return rejectDangerousCommand("Stop-Process -Name node", "Use 'Stop-Process -Id <pid>' with a specific PID instead.");
|
|
71235
|
+
} else {
|
|
71236
|
+
if (/\bps\b/.test(cmd) && /\bgrep\b.*\b(node|scream)/i.test(cmd) && /\bxargs\s+kill\b/.test(cmd)) return rejectDangerousCommand("ps | grep node | xargs kill pipeline", "Use 'kill <pid>' with a specific PID instead.");
|
|
71237
|
+
if (/\bpgrep\b.*\b(node|scream)/i.test(cmd) && /\bxargs\s+kill\b/.test(cmd)) return rejectDangerousCommand("pgrep node | xargs kill", "Use 'kill <pid>' with a specific PID instead.");
|
|
71238
|
+
}
|
|
71239
|
+
return null;
|
|
71240
|
+
}
|
|
71241
|
+
function buildSelfProtectionPreamble(isWindows) {
|
|
71242
|
+
if (isWindows) return "_SCREAM_CHECK(){ for _a in \"$@\";do [ \"$_a\" = \"$SCREAM_PID\" ]&&{ echo \"Scream Code self-protection: refusing to kill itself (pid $SCREAM_PID). Use a specific non-Scream PID.\">&2;return 1;};done;return 0;};kill(){ _SCREAM_CHECK \"$@\"||return 1;command kill \"$@\";};pkill(){ echo \"Scream Code self-protection: pkill blocked. Use kill <pid>.\">&2;return 1;};taskkill(){ _SCREAM_CHECK \"$@\"||return 1;command taskkill \"$@\";};tskill(){ _SCREAM_CHECK \"$@\"||return 1;command tskill \"$@\";};";
|
|
71243
|
+
return "_SCREAM_CHECK(){ for _a in \"$@\";do [ \"$_a\" = \"$SCREAM_PID\" ]||[ \"$_a\" = \"-$SCREAM_PID\" ]&&{ echo \"Scream Code self-protection: refusing to kill itself (pid $SCREAM_PID). Use a specific non-Scream PID.\">&2;return 1;};done;return 0;};kill(){ _SCREAM_CHECK \"$@\"||return 1;command kill \"$@\";};pkill(){ echo \"Scream Code self-protection: pkill blocked. Use kill <pid>.\">&2;return 1;};killall(){ echo \"Scream Code self-protection: killall blocked. Use kill <pid>.\">&2;return 1;};";
|
|
71244
|
+
}
|
|
71220
71245
|
var BashTool = class {
|
|
71221
71246
|
jian;
|
|
71222
71247
|
cwd;
|
|
@@ -71253,16 +71278,18 @@ var BashTool = class {
|
|
|
71253
71278
|
}
|
|
71254
71279
|
spawn(effectiveCwd, command) {
|
|
71255
71280
|
const shellCwd = this.isWindowsBash ? windowsPathToPosixPath(effectiveCwd) : effectiveCwd;
|
|
71281
|
+
const preamble = buildSelfProtectionPreamble(this.isWindowsBash);
|
|
71256
71282
|
const shellArgs = [
|
|
71257
71283
|
this.jian.osEnv.shellPath,
|
|
71258
71284
|
"-c",
|
|
71259
|
-
`cd ${shellQuote$1(shellCwd)} && ${command}`
|
|
71285
|
+
`cd ${shellQuote$1(shellCwd)} && ${preamble}; ${command}`
|
|
71260
71286
|
];
|
|
71261
71287
|
const noninteractiveEnv = {
|
|
71262
71288
|
NO_COLOR: "1",
|
|
71263
71289
|
TERM: "dumb",
|
|
71264
71290
|
GIT_TERMINAL_PROMPT: process.env["GIT_TERMINAL_PROMPT"] ?? "0",
|
|
71265
|
-
SHELL: this.jian.osEnv.shellPath
|
|
71291
|
+
SHELL: this.jian.osEnv.shellPath,
|
|
71292
|
+
SCREAM_PID: String(process.pid)
|
|
71266
71293
|
};
|
|
71267
71294
|
const mergedEnv = {
|
|
71268
71295
|
...process.env,
|
|
@@ -71279,6 +71306,8 @@ var BashTool = class {
|
|
|
71279
71306
|
isError: true,
|
|
71280
71307
|
output: "Command cannot be empty."
|
|
71281
71308
|
};
|
|
71309
|
+
const validationError = validateCommand(args.command, this.isWindowsBash);
|
|
71310
|
+
if (validationError !== null) return validationError;
|
|
71282
71311
|
if (args.run_in_background) {
|
|
71283
71312
|
if (!this.allowBackground) return {
|
|
71284
71313
|
isError: true,
|
|
@@ -124475,6 +124504,30 @@ const BUILTIN_REGISTRY = [
|
|
|
124475
124504
|
displayName: "Academic Research 学术研究",
|
|
124476
124505
|
description: "完整学术研究管线:深度研究(13 Agent 团队 × 7 种模式)+ 学术写作(12 Agent 管线)+ 同行评审(7 Agent 多视角审稿),全流程覆盖",
|
|
124477
124506
|
source: "https://github.com/Imbad0202/academic-research-skills"
|
|
124507
|
+
},
|
|
124508
|
+
{
|
|
124509
|
+
id: "taste-skill",
|
|
124510
|
+
displayName: "Taste Skill 品味提升",
|
|
124511
|
+
description: "让 AI 拥有好品味,不再生成无聊、千篇一律的平庸内容",
|
|
124512
|
+
source: "https://github.com/Leonxlnx/taste-skill"
|
|
124513
|
+
},
|
|
124514
|
+
{
|
|
124515
|
+
id: "headroom",
|
|
124516
|
+
displayName: "Headroom 压缩优化",
|
|
124517
|
+
description: "在内容送达 LLM 前压缩工具输出、日志、文件和 RAG 块,节省 60-95% Token,答案质量不变",
|
|
124518
|
+
source: "https://github.com/chopratejas/headroom"
|
|
124519
|
+
},
|
|
124520
|
+
{
|
|
124521
|
+
id: "composio",
|
|
124522
|
+
displayName: "Composio 工具集成",
|
|
124523
|
+
description: "1000+ 工具集、工具搜索、上下文管理、认证和沙盒工作台,帮助构建能把意图转化为行动的 AI Agent",
|
|
124524
|
+
source: "https://github.com/ComposioHQ/composio"
|
|
124525
|
+
},
|
|
124526
|
+
{
|
|
124527
|
+
id: "remotion",
|
|
124528
|
+
displayName: "Remotion 视频编程",
|
|
124529
|
+
description: "用 React 程序化生成视频,代码驱动动画、剪辑和渲染",
|
|
124530
|
+
source: "https://github.com/remotion-dev/remotion"
|
|
124478
124531
|
}
|
|
124479
124532
|
];
|
|
124480
124533
|
async function handlePluginCommand(host, _args) {
|
|
@@ -124534,8 +124587,8 @@ async function uninstallAndReport(host, id) {
|
|
|
124534
124587
|
}
|
|
124535
124588
|
}
|
|
124536
124589
|
async function openPluginPanel(host) {
|
|
124537
|
-
|
|
124538
|
-
const installed = await loadInstalled(host);
|
|
124590
|
+
host.showStatus("正在加载插件中心…", "cyan");
|
|
124591
|
+
const [marketplace, installed] = await Promise.all([loadSafe(host), loadInstalled(host)]);
|
|
124539
124592
|
const options = buildOptions(marketplace, installed);
|
|
124540
124593
|
if (options.length === 0) {
|
|
124541
124594
|
host.showNotice("ScreamCode 插件中心", "暂无可用插件。请检查网络或稍后重试。");
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "scream-code",
|
|
3
|
-
"version": "0.3.
|
|
3
|
+
"version": "0.3.6",
|
|
4
4
|
"description": "The Starting Point for Next-Gen Agents",
|
|
5
5
|
"license": "MIT",
|
|
6
6
|
"author": "ScreamCli",
|
|
@@ -51,6 +51,7 @@
|
|
|
51
51
|
"test": "pnpm -w run build:packages && vitest run",
|
|
52
52
|
"e2e": "pnpm -w run build:packages && SCREAM_E2E=1 vitest run test/e2e",
|
|
53
53
|
"e2e:real": "pnpm -w run build:packages && SCREAM_E2E_REAL=1 vitest run test/e2e/real-llm-smoke.e2e.test.ts",
|
|
54
|
+
"preinstall": "node -e \"console.log('\\n📦 正在安装 scream-code,请稍候...\\n')\"",
|
|
54
55
|
"postinstall": "node scripts/postinstall.mjs",
|
|
55
56
|
"smoke": "node dist/main.mjs --version"
|
|
56
57
|
},
|
|
@@ -0,0 +1,61 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Create a desktop shortcut for Scream Code on Windows.
|
|
3
|
+
*
|
|
4
|
+
* Only runs on Win32 and for global installs. Never fails the install —
|
|
5
|
+
* errors are caught and swallowed.
|
|
6
|
+
*/
|
|
7
|
+
|
|
8
|
+
import { execFileSync } from 'node:child_process';
|
|
9
|
+
|
|
10
|
+
export function createDesktopShortcut() {
|
|
11
|
+
if (process.platform !== 'win32') return;
|
|
12
|
+
|
|
13
|
+
try {
|
|
14
|
+
execFileSync(
|
|
15
|
+
'powershell.exe',
|
|
16
|
+
[
|
|
17
|
+
'-NoProfile',
|
|
18
|
+
'-ExecutionPolicy', 'Bypass',
|
|
19
|
+
'-Command',
|
|
20
|
+
shortcutPowerShellScript,
|
|
21
|
+
],
|
|
22
|
+
{ stdio: 'ignore', timeout: 10_000 },
|
|
23
|
+
);
|
|
24
|
+
} catch {
|
|
25
|
+
// Never fail the install over a shortcut.
|
|
26
|
+
}
|
|
27
|
+
}
|
|
28
|
+
|
|
29
|
+
const shortcutPowerShellScript = `
|
|
30
|
+
$ErrorActionPreference = 'Stop'
|
|
31
|
+
|
|
32
|
+
$DesktopPath = [Environment]::GetFolderPath('Desktop')
|
|
33
|
+
$ShortcutPath = "$DesktopPath\\Scream Code.lnk"
|
|
34
|
+
$WshShell = New-Object -ComObject WScript.Shell
|
|
35
|
+
$Shortcut = $WshShell.CreateShortcut($ShortcutPath)
|
|
36
|
+
|
|
37
|
+
$wt = Get-Command wt.exe -ErrorAction SilentlyContinue
|
|
38
|
+
$pwsh7 = Get-Command pwsh.exe -ErrorAction SilentlyContinue
|
|
39
|
+
$ps5 = Get-Command powershell.exe -ErrorAction SilentlyContinue
|
|
40
|
+
|
|
41
|
+
if ($wt) {
|
|
42
|
+
$Shortcut.TargetPath = $wt.Source
|
|
43
|
+
$Shortcut.Arguments = '--title "Scream Code" cmd /k "chcp 65001 > nul && scream"'
|
|
44
|
+
}
|
|
45
|
+
elseif ($pwsh7) {
|
|
46
|
+
$Shortcut.TargetPath = $pwsh7.Source
|
|
47
|
+
$Shortcut.Arguments = '-NoExit -Command "chcp 65001 > $null; scream"'
|
|
48
|
+
}
|
|
49
|
+
elseif ($ps5) {
|
|
50
|
+
$Shortcut.TargetPath = $ps5.Source
|
|
51
|
+
$Shortcut.Arguments = '-NoExit -Command "chcp 65001 > $null; [Console]::OutputEncoding = [Console]::InputEncoding = [Text.Encoding]::UTF8; $Host.UI.RawUI.WindowTitle = ''Scream Code''; scream"'
|
|
52
|
+
}
|
|
53
|
+
else {
|
|
54
|
+
$Shortcut.TargetPath = 'powershell.exe'
|
|
55
|
+
$Shortcut.Arguments = '-NoExit -Command "chcp 65001 > $null; [Console]::OutputEncoding = [Console]::InputEncoding = [Text.Encoding]::UTF8; $Host.UI.RawUI.WindowTitle = ''Scream Code''; scream"'
|
|
56
|
+
}
|
|
57
|
+
|
|
58
|
+
$Shortcut.WorkingDirectory = $env:USERPROFILE
|
|
59
|
+
$Shortcut.Description = 'Scream Code - AI 命令行助手'
|
|
60
|
+
$Shortcut.Save()
|
|
61
|
+
`.trim();
|
package/scripts/postinstall.mjs
CHANGED
|
@@ -113,6 +113,7 @@ import {
|
|
|
113
113
|
detectLegacyShims,
|
|
114
114
|
renameInPlace,
|
|
115
115
|
} from './postinstall/migrate.mjs';
|
|
116
|
+
import { createDesktopShortcut } from './postinstall/shortcut.mjs';
|
|
116
117
|
import {
|
|
117
118
|
logForeignScreamInTheWay,
|
|
118
119
|
logMigrationBlocked,
|
|
@@ -263,6 +264,12 @@ async function main() {
|
|
|
263
264
|
);
|
|
264
265
|
}
|
|
265
266
|
|
|
267
|
+
try {
|
|
268
|
+
createDesktopShortcut();
|
|
269
|
+
} catch {
|
|
270
|
+
// Never fail the install over a shortcut.
|
|
271
|
+
}
|
|
272
|
+
|
|
266
273
|
main().catch((err) => {
|
|
267
274
|
const message = err instanceof Error ? err.message : String(err);
|
|
268
275
|
notify(`[scream-code] postinstall warning: ${message}`);
|