sema-core 2.1.1 → 2.1.2

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 (132) hide show
  1. package/dist/core/Conversation.d.ts.map +1 -1
  2. package/dist/core/Conversation.js +9 -3
  3. package/dist/core/Conversation.js.map +1 -1
  4. package/dist/core/SemaEngine.d.ts +0 -5
  5. package/dist/core/SemaEngine.d.ts.map +1 -1
  6. package/dist/core/SemaEngine.js +19 -50
  7. package/dist/core/SemaEngine.js.map +1 -1
  8. package/dist/events/types.d.ts +4 -1
  9. package/dist/events/types.d.ts.map +1 -1
  10. package/dist/manager/ConfManager.d.ts.map +1 -1
  11. package/dist/manager/ConfManager.js +3 -0
  12. package/dist/manager/ConfManager.js.map +1 -1
  13. package/dist/manager/PermissionManager.d.ts.map +1 -1
  14. package/dist/manager/PermissionManager.js +124 -216
  15. package/dist/manager/PermissionManager.js.map +1 -1
  16. package/dist/manager/runShellGate.d.ts +25 -0
  17. package/dist/manager/runShellGate.d.ts.map +1 -0
  18. package/dist/manager/runShellGate.js +154 -0
  19. package/dist/manager/runShellGate.js.map +1 -0
  20. package/dist/prompt/inputPredict.d.ts +1 -1
  21. package/dist/prompt/inputPredict.d.ts.map +1 -1
  22. package/dist/prompt/inputPredict.js +1 -1
  23. package/dist/prompt/permission.d.ts.map +1 -1
  24. package/dist/prompt/permission.js +91 -36
  25. package/dist/prompt/permission.js.map +1 -1
  26. package/dist/prompt/skills.d.ts +18 -0
  27. package/dist/prompt/skills.d.ts.map +1 -0
  28. package/dist/prompt/skills.js +151 -0
  29. package/dist/prompt/skills.js.map +1 -0
  30. package/dist/prompt/toolAliases.d.ts +12 -1
  31. package/dist/prompt/toolAliases.d.ts.map +1 -1
  32. package/dist/prompt/toolAliases.js +28 -1
  33. package/dist/prompt/toolAliases.js.map +1 -1
  34. package/dist/prompt/tools/runShell.js +1 -1
  35. package/dist/prompt/tools/skill.d.ts.map +1 -1
  36. package/dist/prompt/tools/skill.js +2 -1
  37. package/dist/prompt/tools/skill.js.map +1 -1
  38. package/dist/services/agents/agentsManager.d.ts +5 -2
  39. package/dist/services/agents/agentsManager.d.ts.map +1 -1
  40. package/dist/services/agents/agentsManager.js +33 -21
  41. package/dist/services/agents/agentsManager.js.map +1 -1
  42. package/dist/services/commands/commandsManager.d.ts +5 -6
  43. package/dist/services/commands/commandsManager.d.ts.map +1 -1
  44. package/dist/services/commands/commandsManager.js +28 -23
  45. package/dist/services/commands/commandsManager.js.map +1 -1
  46. package/dist/services/hooks/hookTriggers.d.ts.map +1 -1
  47. package/dist/services/hooks/hookTriggers.js +4 -1
  48. package/dist/services/hooks/hookTriggers.js.map +1 -1
  49. package/dist/services/hooks/hooksManager.d.ts +8 -2
  50. package/dist/services/hooks/hooksManager.d.ts.map +1 -1
  51. package/dist/services/hooks/hooksManager.js +70 -28
  52. package/dist/services/hooks/hooksManager.js.map +1 -1
  53. package/dist/services/mcp/MCPManager.d.ts +2 -1
  54. package/dist/services/mcp/MCPManager.d.ts.map +1 -1
  55. package/dist/services/mcp/MCPManager.js +4 -2
  56. package/dist/services/mcp/MCPManager.js.map +1 -1
  57. package/dist/services/memory/memManager.d.ts +8 -1
  58. package/dist/services/memory/memManager.d.ts.map +1 -1
  59. package/dist/services/memory/memManager.js +16 -2
  60. package/dist/services/memory/memManager.js.map +1 -1
  61. package/dist/services/plugins/pluginsManager.d.ts +1 -1
  62. package/dist/services/plugins/pluginsManager.d.ts.map +1 -1
  63. package/dist/services/plugins/pluginsManager.js +13 -4
  64. package/dist/services/plugins/pluginsManager.js.map +1 -1
  65. package/dist/services/rules/rulesManager.d.ts +2 -1
  66. package/dist/services/rules/rulesManager.d.ts.map +1 -1
  67. package/dist/services/rules/rulesManager.js +2 -2
  68. package/dist/services/rules/rulesManager.js.map +1 -1
  69. package/dist/services/skills/skillsManager.d.ts +13 -8
  70. package/dist/services/skills/skillsManager.d.ts.map +1 -1
  71. package/dist/services/skills/skillsManager.js +68 -30
  72. package/dist/services/skills/skillsManager.js.map +1 -1
  73. package/dist/tools/EditNotebook.d.ts +1 -1
  74. package/dist/tools/PatchFile.d.ts.map +1 -1
  75. package/dist/tools/PatchFile.js +22 -18
  76. package/dist/tools/PatchFile.js.map +1 -1
  77. package/dist/tools/RunShell.d.ts +9 -9
  78. package/dist/tools/RunShell.d.ts.map +1 -1
  79. package/dist/tools/RunShell.js +11 -14
  80. package/dist/tools/RunShell.js.map +1 -1
  81. package/dist/tools/Skill.d.ts.map +1 -1
  82. package/dist/tools/Skill.js +40 -2
  83. package/dist/tools/Skill.js.map +1 -1
  84. package/dist/tools/ViewFile.d.ts.map +1 -1
  85. package/dist/tools/ViewFile.js +3 -19
  86. package/dist/tools/ViewFile.js.map +1 -1
  87. package/dist/tools/WriteFile.d.ts.map +1 -1
  88. package/dist/tools/WriteFile.js +4 -2
  89. package/dist/tools/WriteFile.js.map +1 -1
  90. package/dist/tools/base/tools.d.ts.map +1 -1
  91. package/dist/tools/base/tools.js +7 -1
  92. package/dist/tools/base/tools.js.map +1 -1
  93. package/dist/types/hook.d.ts +8 -3
  94. package/dist/types/hook.d.ts.map +1 -1
  95. package/dist/types/index.d.ts +1 -1
  96. package/dist/types/index.d.ts.map +1 -1
  97. package/dist/types/plugin.d.ts +2 -0
  98. package/dist/types/plugin.d.ts.map +1 -1
  99. package/dist/types/skill.d.ts +1 -1
  100. package/dist/types/skill.d.ts.map +1 -1
  101. package/dist/util/autoRunContext.d.ts +3 -2
  102. package/dist/util/autoRunContext.d.ts.map +1 -1
  103. package/dist/util/autoRunContext.js +45 -11
  104. package/dist/util/autoRunContext.js.map +1 -1
  105. package/dist/util/commands.d.ts.map +1 -1
  106. package/dist/util/commands.js +6 -1
  107. package/dist/util/commands.js.map +1 -1
  108. package/dist/util/fetchSafety.d.ts +10 -3
  109. package/dist/util/fetchSafety.d.ts.map +1 -1
  110. package/dist/util/fetchSafety.js +22 -29
  111. package/dist/util/fetchSafety.js.map +1 -1
  112. package/dist/util/imageCompress.d.ts +16 -0
  113. package/dist/util/imageCompress.d.ts.map +1 -1
  114. package/dist/util/imageCompress.js +53 -0
  115. package/dist/util/imageCompress.js.map +1 -1
  116. package/dist/util/readPathClass.d.ts +16 -0
  117. package/dist/util/readPathClass.d.ts.map +1 -0
  118. package/dist/util/readPathClass.js +121 -0
  119. package/dist/util/readPathClass.js.map +1 -0
  120. package/dist/util/secureFile.d.ts +4 -0
  121. package/dist/util/secureFile.d.ts.map +1 -1
  122. package/dist/util/secureFile.js +8 -60
  123. package/dist/util/secureFile.js.map +1 -1
  124. package/dist/util/shell.d.ts +1 -0
  125. package/dist/util/shell.d.ts.map +1 -1
  126. package/dist/util/shell.js +36 -0
  127. package/dist/util/shell.js.map +1 -1
  128. package/dist/util/shellSafety.d.ts +26 -15
  129. package/dist/util/shellSafety.d.ts.map +1 -1
  130. package/dist/util/shellSafety.js +277 -60
  131. package/dist/util/shellSafety.js.map +1 -1
  132. package/package.json +1 -1
@@ -0,0 +1,25 @@
1
+ import { DeleteTargetKind } from '../util/shellSafety';
2
+ export declare function isPathInsideRoot(filePath: string, root: string): boolean;
3
+ export declare function isTempFile(filePath: string): boolean;
4
+ /**
5
+ * 删除类命令(rm/rmdir/mv/find -delete)与 chmod 单个目标路径的允许范围裁决,
6
+ * 供 classifyDangerousCommand 回调。目标满足其一才允许交模型判断:
7
+ * - 落在系统临时目录树内(含临时目录自身)
8
+ * - 落在项目根内,且:literal 目标不得是项目根自身(rm -rf . 级联全删仍转人工),
9
+ * globdir 目标(rm dist/*、find . -delete 的所在目录)允许是项目根;
10
+ * 两种形态都排除 .git(删掉版本库即失去「项目内可恢复」的兜底)
11
+ * 其余(项目外、~、无法解析)一律不允许 → 确定性转人工。
12
+ */
13
+ export declare function isDeletableShellTarget(target: string, kind: DeleteTargetKind): boolean;
14
+ export declare function isRunShellCommandPermitted(command: string, allowedTools: string[]): boolean;
15
+ export type RunShellGateStage = 'injection' | 'readonly' | 'danger' | 'covered' | 'uncovered';
16
+ export type RunShellGateVerdict = 'allow' | 'model' | 'human';
17
+ export interface RunShellGate {
18
+ command: string;
19
+ stage: RunShellGateStage;
20
+ verdict: RunShellGateVerdict;
21
+ detail: string;
22
+ }
23
+ export declare function normalizeShellCommand(command: string): string;
24
+ export declare function classifyRunShellGate(rawCommand: string, allowedTools?: string[]): RunShellGate;
25
+ //# sourceMappingURL=runShellGate.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"runShellGate.d.ts","sourceRoot":"","sources":["../../src/manager/runShellGate.ts"],"names":[],"mappings":"AAMA,OAAO,EAEmD,gBAAgB,EACzE,MAAM,qBAAqB,CAAA;AAQ5B,wBAAgB,gBAAgB,CAAC,QAAQ,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM,GAAG,OAAO,CAKxE;AAID,wBAAgB,UAAU,CAAC,QAAQ,EAAE,MAAM,GAAG,OAAO,CASpD;AAED;;;;;;;;GAQG;AACH,wBAAgB,sBAAsB,CAAC,MAAM,EAAE,MAAM,EAAE,IAAI,EAAE,gBAAgB,GAAG,OAAO,CAUtF;AA2BD,wBAAgB,0BAA0B,CAAC,OAAO,EAAE,MAAM,EAAE,YAAY,EAAE,MAAM,EAAE,GAAG,OAAO,CAE3F;AAUD,MAAM,MAAM,iBAAiB,GAAG,WAAW,GAAG,UAAU,GAAG,QAAQ,GAAG,SAAS,GAAG,WAAW,CAAA;AAG7F,MAAM,MAAM,mBAAmB,GAAG,OAAO,GAAG,OAAO,GAAG,OAAO,CAAA;AAE7D,MAAM,WAAW,YAAY;IAE3B,OAAO,EAAE,MAAM,CAAA;IACf,KAAK,EAAE,iBAAiB,CAAA;IACxB,OAAO,EAAE,mBAAmB,CAAA;IAC5B,MAAM,EAAE,MAAM,CAAA;CACf;AAED,wBAAgB,qBAAqB,CAAC,OAAO,EAAE,MAAM,GAAG,MAAM,CAK7D;AAED,wBAAgB,oBAAoB,CAAC,UAAU,EAAE,MAAM,EAAE,YAAY,GAAE,MAAM,EAAO,GAAG,YAAY,CA0DlG"}
@@ -0,0 +1,154 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.isPathInsideRoot = isPathInsideRoot;
4
+ exports.isTempFile = isTempFile;
5
+ exports.isDeletableShellTarget = isDeletableShellTarget;
6
+ exports.isRunShellCommandPermitted = isRunShellCommandPermitted;
7
+ exports.normalizeShellCommand = normalizeShellCommand;
8
+ exports.classifyRunShellGate = classifyRunShellGate;
9
+ const path_1 = require("path");
10
+ const tool_1 = require("../prompt/tool");
11
+ const commands_1 = require("../util/commands");
12
+ const cwd_1 = require("../util/cwd");
13
+ const platform_1 = require("../util/platform");
14
+ const readPathClass_1 = require("../util/readPathClass");
15
+ const shellSafety_1 = require("../util/shellSafety");
16
+ // run_shell 权限闸门的确定性部分:不调模型、不发事件、不读会话状态,纯函数。
17
+ // PermissionManager 据此决定放行 / 交 AutoRun 模型 / 转人工;tests/manager/runShellGate.* 直接调用
18
+ // 它回答「这条命令会不会被前置拦截」,与线上逻辑同源。
19
+ // ==================== 路径辅助 ====================
20
+ function isPathInsideRoot(filePath, root) {
21
+ const abs = (0, path_1.isAbsolute)(filePath) ? filePath : (0, path_1.resolve)(root, filePath);
22
+ const rel = (0, path_1.relative)((0, platform_1.normalizeCmpPath)(root), (0, platform_1.normalizeCmpPath)(abs));
23
+ if (!rel || rel === '')
24
+ return true;
25
+ return !rel.startsWith('..') && !(0, path_1.isAbsolute)(rel);
26
+ }
27
+ // 系统临时目录(清单见 util/readPathClass 的 TEMP_BASE_PATHS)下的文件视为临时文件,
28
+ // AutoEdit/AutoRun 下即便在项目外也自动放行编辑
29
+ function isTempFile(filePath) {
30
+ // 相对路径按项目根解析(解析后必落在项目内,由 isPathInsideRoot 处理);临时文件均为绝对路径
31
+ const abs = (0, path_1.isAbsolute)(filePath) ? filePath : (0, path_1.resolve)((0, cwd_1.readInitialCwd)(), filePath);
32
+ const absNorm = (0, platform_1.normalizeCmpPath)(abs);
33
+ return readPathClass_1.TEMP_BASE_PATHS.some(base => {
34
+ const rel = (0, path_1.relative)((0, platform_1.normalizeCmpPath)(base), absNorm);
35
+ if (!rel || rel === '')
36
+ return true;
37
+ return !rel.startsWith('..') && !(0, path_1.isAbsolute)(rel);
38
+ });
39
+ }
40
+ /**
41
+ * 删除类命令(rm/rmdir/mv/find -delete)与 chmod 单个目标路径的允许范围裁决,
42
+ * 供 classifyDangerousCommand 回调。目标满足其一才允许交模型判断:
43
+ * - 落在系统临时目录树内(含临时目录自身)
44
+ * - 落在项目根内,且:literal 目标不得是项目根自身(rm -rf . 级联全删仍转人工),
45
+ * globdir 目标(rm dist/*、find . -delete 的所在目录)允许是项目根;
46
+ * 两种形态都排除 .git(删掉版本库即失去「项目内可恢复」的兜底)
47
+ * 其余(项目外、~、无法解析)一律不允许 → 确定性转人工。
48
+ */
49
+ function isDeletableShellTarget(target, kind) {
50
+ const root = (0, cwd_1.readInitialCwd)();
51
+ const abs = (0, path_1.isAbsolute)(target) ? target : (0, path_1.resolve)(root, target);
52
+ if (isTempFile(abs))
53
+ return true;
54
+ const rel = (0, path_1.relative)((0, platform_1.normalizeCmpPath)(root), (0, platform_1.normalizeCmpPath)(abs));
55
+ if (rel.startsWith('..') || (0, path_1.isAbsolute)(rel))
56
+ return false;
57
+ if (!rel || rel === '')
58
+ return kind === 'globdir';
59
+ const first = rel.split(/[\\/]/)[0];
60
+ if (first === '.git')
61
+ return false;
62
+ return true;
63
+ }
64
+ // ==================== 白名单 / 已存授权 ====================
65
+ function runShellToolHasExactMatch(command, allowedTools) {
66
+ // 只读安全命令快速通道:基于 splitCommand 分词逐子命令判定,
67
+ // 杜绝「整串 split(' ')[0]」导致的重定向 / 不带空格管道 / find 危险 flag 绕过
68
+ if ((0, shellSafety_1.isReadonlySafeCommand)(command))
69
+ return true;
70
+ if (allowedTools.includes(`${tool_1.TOOL_NAME_RUN_SHELL}(${command})`))
71
+ return true;
72
+ return allowedTools.includes(`${tool_1.TOOL_NAME_RUN_SHELL}(${command}:*)`);
73
+ }
74
+ // 已保存的前缀授权 run_shell(P:*) 用字符串前缀匹配判定覆盖,无需模型提取前缀
75
+ function matchesSavedPrefix(command, allowedTools) {
76
+ // 前缀匹配只看首词,无法识别参数/重定向带来的危险。危险命令(含重定向、rm/sudo/mv
77
+ // 等危险首词、find 危险 flag)即便首词被前缀授权也不放行,避免 `rm:*`/`echo:*` 退化为
78
+ // 任意删除/写文件原语。
79
+ if ((0, shellSafety_1.isUnsafeForPrefixAuth)(command))
80
+ return false;
81
+ const open = `${tool_1.TOOL_NAME_RUN_SHELL}(`;
82
+ for (const entry of allowedTools) {
83
+ if (!entry.startsWith(open) || !entry.endsWith(':*)'))
84
+ continue;
85
+ const prefix = entry.slice(open.length, -':*)'.length);
86
+ if (prefix && (command === prefix || command.startsWith(`${prefix} `)))
87
+ return true;
88
+ }
89
+ return false;
90
+ }
91
+ function isRunShellCommandPermitted(command, allowedTools) {
92
+ return runShellToolHasExactMatch(command, allowedTools) || matchesSavedPrefix(command, allowedTools);
93
+ }
94
+ function normalizeShellCommand(command) {
95
+ // 归一化首尾空白:命令常带尾随换行(如 heredoc 结束符后的 \n)。不 trim 会让 stripHeredocBody
96
+ // 剥离正文后骨架残留一个空行 → 误判「结束符后藏了第二条命令」→ 合法 heredoc 脚本被当成注入。
97
+ // trim 只去首尾空白,不影响 ; / $() / 第二条命令等真注入向量的检出。
98
+ return command.trim().replace(`cd ${(0, cwd_1.readInitialCwd)()} && `, '');
99
+ }
100
+ function classifyRunShellGate(rawCommand, allowedTools = []) {
101
+ const command = normalizeShellCommand(rawCommand);
102
+ // 先拆分子命令并做注入检测——必须先于白名单/AutoRun 放行,否则白名单主命令词(echo/cat/grep 等)
103
+ // 夹带 $()、`` 命令替换或换行即可绕过检测(如 echo $(id))。
104
+ const subCommands = (0, commands_1.splitCommand)(command);
105
+ // heredoc 正文是喂给程序的数据而非 shell 命令,但底层 shell-quote 不理解 heredoc,会把正文打散、
106
+ // 换行有时残留,导致合法的多行内联脚本(python3 << 'EOF' ...)被误判注入。注入检测改在「剥离
107
+ // heredoc 正文后的骨架」上进行:骨架残留换行说明结束符之后还接了命令(多行形态,逐行分类);
108
+ // 否则按子命令逐段检测。无法安全剥离(多 heredoc 同行/缺结束符/不带引号且正文含命令替换)时
109
+ // stripHeredocBody 原样返回,退回逐段检测,绝不因剥离而放过真注入。
110
+ const injectionSkeleton = (0, commands_1.stripHeredocBody)(command);
111
+ const injectionDetected = injectionSkeleton !== command
112
+ ? injectionSkeleton.includes('\n') || (0, commands_1.splitCommand)(injectionSkeleton).some(commands_1.hasCommandInjection)
113
+ : subCommands.some(commands_1.hasCommandInjection);
114
+ if (injectionDetected) {
115
+ // 注入形态细分($() 替换、`;`/for 循环、heredoc 之后再接命令、带变量的 mv/rm):
116
+ // dangerous(硬危险首词/解释器/eval、字面目标出项目的删除、反引号、解析失败)→ 确定性转人工,
117
+ // 不给模型机会;
118
+ // readonly/gray(静态解析不了但模型读得懂:变量操作数、循环、多行脚本)→ 交模型判断。
119
+ // 刻意不走白名单/前缀/覆盖等确定性放行——那些检查不理解替换语义(echo:* 前缀
120
+ // 会把 echo $(任意命令) 一并放行),放行只能由模型或人工裁决。
121
+ const substClass = injectionSkeleton !== command
122
+ ? (0, shellSafety_1.classifyMultilineCommand)(injectionSkeleton, isDeletableShellTarget)
123
+ : (0, shellSafety_1.classifyCommandSubstitutions)(command, isDeletableShellTarget);
124
+ if (substClass === 'dangerous') {
125
+ return { command, stage: 'injection', verdict: 'human', detail: '注入/危险命令替换' };
126
+ }
127
+ return { command, stage: 'injection', verdict: 'model', detail: `含 ${substClass} 注入形态` };
128
+ }
129
+ // 命中白名单或项目配置已允许
130
+ if (runShellToolHasExactMatch(command, allowedTools)) {
131
+ return { command, stage: 'readonly', verdict: 'allow', detail: '只读白名单/已存授权' };
132
+ }
133
+ // 危险命令分级:
134
+ // hard(sudo/dd/chown 等硬危险、删除/chmod 目标出项目/无法静态解析)→ 确定性转人工,
135
+ // 不调模型——语义本身危险或不可逆,不该给模型机会判 safe 放行;
136
+ // gray(rm/rmdir/mv/find -delete/chmod 且所有目标确定性落在项目内或临时目录;kill/pkill)
137
+ // → 交模型结合上下文判断(用户明确要求删除/清理、agent 自建文件、可再生中间产物、
138
+ // agent 自启的 dev server → safe 一次性放行)。
139
+ const dangerClass = (0, shellSafety_1.classifyDangerousCommand)(command, isDeletableShellTarget);
140
+ if (dangerClass === 'hard') {
141
+ return { command, stage: 'danger', verdict: 'human', detail: '硬危险命令' };
142
+ }
143
+ if (dangerClass === 'gray') {
144
+ return { command, stage: 'danger', verdict: 'model', detail: '灰区危险命令' };
145
+ }
146
+ // 每个子命令都被 SAFE_COMMANDS / 精确授权 / 已保存前缀覆盖 → 放行(注入已在上面排除)。
147
+ // 已被「确定性覆盖」的命令无需再调用快速模型——既省一次模型调用,也更准确
148
+ // (确定性放行不应触发「模型自动放行」事件 tool:permission:auto)。
149
+ if (subCommands.length > 0 && subCommands.every(subCmd => isRunShellCommandPermitted(subCmd, allowedTools))) {
150
+ return { command, stage: 'covered', verdict: 'allow', detail: '子命令全部被覆盖' };
151
+ }
152
+ return { command, stage: 'uncovered', verdict: 'model', detail: '未覆盖命令' };
153
+ }
154
+ //# sourceMappingURL=runShellGate.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"runShellGate.js","sourceRoot":"","sources":["../../src/manager/runShellGate.ts"],"names":[],"mappings":"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"}
@@ -1,2 +1,2 @@
1
- export declare const INPUT_PREDICT_SYSTEM_PROMPT = "Output contract: your ENTIRE reply MUST be exactly one tag and nothing else \u2014 <predict>the predicted user message</predict> or <none/>. No text before or after it.\n\nYou are an input-prediction assistant for a coding agent's chat UI. The user message is a compact transcript of the conversation so far, one item per line: lines starting with \"User:\" are the human's messages; lines starting with \"Assistant:\" are the agent's replies (may be truncated); other lines are tool actions the agent performed (e.g. \"run_shell <command>\"). The agent has just finished its turn. Your job: predict the single most likely NEXT message the human would type, so the UI can pre-fill it as a suggestion.\n\nPredict a message ONLY when there is a clear, high-probability continuation, such as:\n- The assistant asked a question or offered options \u2192 predict the user's most likely answer or choice\n- The assistant proposed a plan or asked for confirmation \u2192 predict the likely approval (e.g. following the user's usual phrasing)\n- The assistant finished one step of a clearly multi-step task \u2192 predict the instruction for the obvious next step\n- The assistant reported an error or blocker with an obvious fix the user would request\n- The assistant told the user exactly what to reply to proceed (e.g. \"reply 'submit' to confirm\") \u2192 predict that reply, even if the assistant also raised caveats or listed alternatives; the user can still edit the suggestion\n\nReply <none/> when the user is unlikely to send another message, such as:\n- The task is fully completed and wrapped up, with no open question or pending decision\n- The next input is unguessable: several directions are about equally likely and none is the default path the assistant set up\n- The conversation is just greetings, small talk, or an open-ended \"what can I help with?\" \u2014 there is no task on the table yet, so the next message cannot be inferred from the transcript\n\nRules for the predicted message:\n- Write it in the human's voice, as if they typed it themselves \u2014 an instruction or answer TO the agent, never a reply FROM the agent\n- Use the same language the human has been writing in (a transcript in another language gets a prediction in that language)\n- Keep it short: one sentence, no trailing punctuation-heavy prose, no explanations\n- Never invent file names or requirements that the transcript does not support\n- Never invent a brand-new task the human has not asked for; a prediction may extend the current task to its obvious next step, but must not start an unrelated one\n\nExamples (transcript gist \u2192 your reply):\nAssistant asked \"Should I apply the same change to the Java SDK?\"\n<predict>Yes, apply it to the Java SDK</predict>\n\nAssistant finished a refactor and reported all tests passing, nothing pending\n<none/>\n\nAssistant listed 3 candidate approaches and asked which to use\n<predict>Go with the first approach</predict>\n\n## Output format\nYour ENTIRE response MUST be exactly one of these two forms, and start with \"<predict>\" or \"<none/>\":\n<predict>predicted user message</predict>\n<none/>\nNo preamble, no analysis, no reasoning \u2014 nothing before or after the tag.";
1
+ export declare const INPUT_PREDICT_SYSTEM_PROMPT = "Output contract: your ENTIRE reply MUST be exactly one tag and nothing else \u2014 <predict>the predicted user message</predict> or <none/>. No text before or after it.\n\nYou are an input-prediction assistant for a coding agent's chat UI. The user message is a compact transcript of the conversation so far, one item per line: lines starting with \"User:\" are the human's messages; lines starting with \"Assistant:\" are the agent's replies (may be truncated); other lines are tool actions the agent performed (e.g. \"run_shell <command>\"). The agent has just finished its turn. Your job: predict the single most likely NEXT message the human would type, so the UI can pre-fill it as a suggestion.\n\nDefault to <none/>. Predict only when the user's own messages strongly support one specific next reply. An assistant question, recommendation, or suggested reply alone is not enough to infer the user's choice or approval. This rule takes precedence over the situations and examples below.\n- The assistant asked a question or offered options \u2192 predict the user's most likely answer or choice\n- The assistant proposed a plan or asked for confirmation \u2192 predict the likely approval (e.g. following the user's usual phrasing)\n- The assistant finished one step of a clearly multi-step task \u2192 predict the instruction for the obvious next step\n- The assistant reported an error or blocker with an obvious fix the user would request\n- The assistant told the user exactly what to reply to proceed (e.g. \"reply 'submit' to confirm\") \u2192 predict that reply, even if the assistant also raised caveats or listed alternatives; the user can still edit the suggestion\n\nReply <none/> when the user is unlikely to send another message, such as:\n- The task is fully completed and wrapped up, with no open question or pending decision\n- The next input is unguessable: several directions are about equally likely and none is the default path the assistant set up\n- The conversation is just greetings, small talk, or an open-ended \"what can I help with?\" \u2014 there is no task on the table yet, so the next message cannot be inferred from the transcript\n\nRules for the predicted message:\n- Write it in the human's voice, as if they typed it themselves \u2014 an instruction or answer TO the agent, never a reply FROM the agent\n- Use the same language the human has been writing in (a transcript in another language gets a prediction in that language)\n- Keep it short: one sentence, no trailing punctuation-heavy prose, no explanations\n- Never invent file names or requirements that the transcript does not support\n- Never invent a brand-new task the human has not asked for; a prediction may extend the current task to its obvious next step, but must not start an unrelated one\n\nExamples (transcript gist \u2192 your reply):\nAssistant asked \"Should I apply the same change to the Java SDK?\"\n<predict>Yes, apply it to the Java SDK</predict>\n\nAssistant finished a refactor and reported all tests passing, nothing pending\n<none/>\n\nAssistant listed 3 candidate approaches and asked which to use\n<predict>Go with the first approach</predict>\n\n## Output format\nYour ENTIRE response MUST be exactly one of these two forms, and start with \"<predict>\" or \"<none/>\":\n<predict>predicted user message</predict>\n<none/>\nNo preamble, no analysis, no reasoning \u2014 nothing before or after the tag.";
2
2
  //# sourceMappingURL=inputPredict.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"inputPredict.d.ts","sourceRoot":"","sources":["../../src/prompt/inputPredict.ts"],"names":[],"mappings":"AAGA,eAAO,MAAM,2BAA2B,gqGAqCkC,CAAA"}
1
+ {"version":3,"file":"inputPredict.d.ts","sourceRoot":"","sources":["../../src/prompt/inputPredict.ts"],"names":[],"mappings":"AAGA,eAAO,MAAM,2BAA2B,22GAqCkC,CAAA"}
@@ -8,7 +8,7 @@ exports.INPUT_PREDICT_SYSTEM_PROMPT = `Output contract: your ENTIRE reply MUST b
8
8
 
9
9
  You are an input-prediction assistant for a coding agent's chat UI. The user message is a compact transcript of the conversation so far, one item per line: lines starting with "User:" are the human's messages; lines starting with "Assistant:" are the agent's replies (may be truncated); other lines are tool actions the agent performed (e.g. "run_shell <command>"). The agent has just finished its turn. Your job: predict the single most likely NEXT message the human would type, so the UI can pre-fill it as a suggestion.
10
10
 
11
- Predict a message ONLY when there is a clear, high-probability continuation, such as:
11
+ Default to <none/>. Predict only when the user's own messages strongly support one specific next reply. An assistant question, recommendation, or suggested reply alone is not enough to infer the user's choice or approval. This rule takes precedence over the situations and examples below.
12
12
  - The assistant asked a question or offered options → predict the user's most likely answer or choice
13
13
  - The assistant proposed a plan or asked for confirmation → predict the likely approval (e.g. following the user's usual phrasing)
14
14
  - The assistant finished one step of a clearly multi-step task → predict the instruction for the obvious next step
@@ -1 +1 @@
1
- {"version":3,"file":"permission.d.ts","sourceRoot":"","sources":["../../src/prompt/permission.ts"],"names":[],"mappings":"AAOA,eAAO,MAAM,qCAAqC,GAAI,WAAW,MAAM,EAAE,KAAG,MAsGkC,CAAA"}
1
+ {"version":3,"file":"permission.d.ts","sourceRoot":"","sources":["../../src/prompt/permission.ts"],"names":[],"mappings":"AAOA,eAAO,MAAM,qCAAqC,GAAI,WAAW,MAAM,EAAE,KAAG,MA6JkC,CAAA"}
@@ -10,51 +10,83 @@ exports.AUTO_RUN_SAFETY_CONTEXT_SYSTEM_PROMPT = void 0;
10
10
  // rendered prompt stays byte-identical and cacheable.
11
11
  const AUTO_RUN_SAFETY_CONTEXT_SYSTEM_PROMPT = (skillDirs) => `Output contract: your ENTIRE reply MUST be exactly one tag and nothing else — <verdict>safe</verdict> or <verdict>risky</verdict>. No text before or after it.
12
12
 
13
- You are a security gatekeeper for an autonomous coding agent running in "AutoRun" mode. The user message is a compact transcript of the agent's recent turns, one item per line: lines starting with "User:" are the human's instructions; other lines are tool actions the agent has taken (e.g. "run_shell <command>", "fetch_url <url>: <prompt>"). Use every line EXCEPT the last ONLY as context describing what already happened. Your job: classify the action on the LAST line — the one the agent is ABOUT to execute (not yet run). It uses the same format as the action lines above it; judge that last line, using the earlier lines only to understand intent.
14
-
15
- Default to "safe" for the routine work of local development. The agent is SUPPOSED to read, write, create, build, test, and refactor inside the project directory without asking permission for each step — treating ordinary in-project work as "risky" defeats the purpose of AutoRun and annoys the user. Reserve "risky" for actions a careful developer would not do unilaterally: destroying pre-existing data, escaping the project directory, exfiltrating local secrets, or changing system/production state.
16
-
17
- Judge the action on its own merits: a genuinely destructive, out-of-project, or data-exfiltrating action stays "risky" no matter how benign the surrounding task looks. But do NOT escalate an ordinary in-project operation to "risky" merely because you cannot see its full purpose or the command is long. Answer "risky" only when the action is genuinely ambiguous between safe and one of the risky categories below — not for unfamiliarity alone.
18
-
19
- Answer "risky" (requires human confirmation) if the action is any of:
20
- - Destructive or irreversible: unjustified file deletion (see the deletion rule below), drop/truncate, force delete, overwriting unrelated or system files, git reset --hard, git clean, git push --force, git push to a shared branch
21
- - Touching files OUTSIDE the project directory, or system/config files (e.g. /etc, ~/.ssh, dotfiles, global configs). Exception: running a user-installed skill script — see the safe list
22
- - Sending local data to the network: a request whose URL embeds local secrets, tokens, or file contents (e.g. https://x.com/?key=<api_key>), or any POST/upload of local data; or reaching cloud metadata or internal-network endpoints (e.g. 169.254.169.254, metadata.google.internal, 10.x / 172.16-31.x / 192.168.x hosts). Loopback (localhost, 127.0.0.1, ::1) is the user's own machine, NOT internal network — see the safe list. NOTE: an anonymous read-only GET of a public page — including login / signin / oauth pages — carries no local credentials and is NOT risky on this basis alone
23
- - Changing system or environment state: sudo, package install/uninstall (global), service control, chmod/chown on sensitive paths, killing processes
24
- - Executing a command inside another host or container through a remote/exec shell: ssh, scp, kubectl exec, docker exec, Enter-PSSession, Invoke-Command. Treat this as risky NO MATTER how harmless the inner command looks (even a bare echo or a read-only command) — it reaches beyond the local machine into a possibly shared or production system, bypasses deployment guardrails, and even a read-only exec can pull live credentials into the output. Judge by the wrapper (the exec into another host), not by the inner payload
25
- - Anything that leaks local secrets/credentials (local tokens, keys, or file contents placed into the request) or affects a production system. Judge by what the request actually sends, not by whether the target page happens to be auth-related
26
- - A command that decodes or de-obfuscates a payload and feeds it to a shell to run: e.g. "base64 -d" or "xxd -r" piped into sh/bash, bash -c "$(...)", eval of assembled strings, hex/char-array reassembly. You are NOT expected to decode the payload — the presence of this decode-and-execute pattern is itself enough to answer "risky". (Decoding that only prints to stdout, and long-but-plainly-readable commands, are NOT risky on this basis.)
27
-
28
- Answer "safe" if the action is any of:
29
- - Read-only, or a local and reversible operation confined to the project directory
30
- - Creating or writing files and directories inside the project (e.g. mkdir, touch, cp, writing/editing source files) — including overwriting files the agent created earlier in this task
31
- - Standard local dev workflow within the project: build, test, lint, format, type-check, and running the project's own scripts (e.g. npm run …, make, pytest)
32
- - Local git operations that do not rewrite already-published history: git add, git commit, git branch, git checkout, git stash, git merge (local), git restore from index
33
- - Installing dependencies already declared in the project's manifest via standard commands (e.g. npm install, pip install -r requirements.txt, cargo build, bundle install)
34
- - Running or reading a script under an installed skill directory (${skillDirs.join(' | ')}) — user-installed tooling, routine even though outside the project. Risky only if its ARGUMENTS reference sensitive paths (~/.ssh, /etc, dotfiles) or embed local secrets
35
- - A read-only GET of a public URL that embeds no local secrets or data — the domain need not be famous; an ordinary public page (docs, articles, login/signin pages, public APIs) fetched anonymously is safe
36
- - A read-only GET or HEAD to a loopback address (localhost, 127.0.0.1, ::1) via run_shell — e.g. a health check against the user's own dev server — that carries no local data and does not use POST/PUT/PATCH/DELETE. A write method or a request body against loopback (e.g. POST /admin/reset) is risky
37
-
38
- Deletion rule (rm / rmdir / mv / find -delete): an in-project or temp-dir deletion is safe ONLY when the transcript justifies it — a "User:" line asked for it (in any language), the target appears in an earlier write_file/patch_file line (the agent's own file), or it is an obviously regenerable artifact (dist/, build/, caches, node_modules, *.tmp, *.log, scratch scripts). Otherwise deleting pre-existing files or unclear directories is risky even inside the project. In-project mv that renames/relocates as part of the requested work is safe.
39
-
40
- Examples (the LAST line of the transcript → your reply):
13
+ You are a security gatekeeper for an autonomous coding agent running in "AutoRun" mode. The user message is a compact transcript of the agent's recent turns, one item per line: lines starting with "User:" are the human's instructions (in any language); other lines are tool actions the agent has taken (e.g. "run_shell <command>", "fetch_url <url>: <prompt>", "write_file <path>"). Use every line EXCEPT the last ONLY as context describing what already happened. A line ending with "→ rejected by user, NOT executed" was blocked by the human and never ran: it tells you nothing bad about the agent and must not make you stricter on later actions. Your job: classify the action on the LAST line — the one the agent is ABOUT to execute (not yet run). It uses the same format as the action lines above it; judge that last line on its own, using the earlier lines only to understand intent. Earlier risky-looking lines do NOT make a harmless last line risky.
14
+
15
+ ## Core rule
16
+
17
+ AutoRun means the user has ALREADY authorized the routine work of the task: reading, writing, creating, building, testing, refactoring, cleaning up and restarting things inside the project. Answer "safe" unless THIS action carries a specific, concrete risk from the list below. Being unfamiliar, long, out of the project directory, or having side effects is NEVER by itself a reason for "risky". If the action is inside the project (or a temp directory) and you are unsure, answer "safe" — reserve "risky" for the categories below, not for uncertainty.
18
+
19
+ Judge the action by what it actually does: its real target, what data it sends, whether it can be undone. A genuinely destructive, out-of-project, or data-exfiltrating action stays "risky" no matter how benign the surrounding task looks — but an explicit "User:" line asking for exactly this action (in any language) makes an otherwise-borderline in-project deletion, process kill, chmod or out-of-project write "safe". A user request does NOT make privilege escalation, secret exfiltration or production changes safe.
20
+
21
+ ## Answer "risky" only for
22
+
23
+ - Destroying pre-existing work at scale: wiping a whole source directory, the project root or .git; drop/truncate of a database or data files; git reset --hard / git clean / git checkout -- . on uncommitted work; overwriting unrelated or system files. (Deletion rule below.)
24
+ - Writing OUTSIDE the project or a temp directory to a location no "User:" line asked for, or touching system/config files (/etc, ~/.ssh, dotfiles, global configs). Exception: running a user-installed skill script — see the safe list.
25
+ - Sending local data to the network: a URL that embeds local secrets, tokens or file contents (e.g. https://x.com/?key=<api_key>); any POST/upload of local files or credentials to a non-loopback host; reaching cloud metadata or internal-network endpoints (169.254.169.254, metadata.google.internal, 10.x / 172.16-31.x / 192.168.x). Loopback (localhost, 127.0.0.1, ::1) is the user's own machine, NOT internal network — see the safe list. An anonymous read-only GET of a public page (including login / signin / oauth pages) carries no local data and is NOT risky.
26
+ - Changing system state: sudo/doas/su, GLOBAL package install/uninstall (npm -g, pip install without a venv, brew, apt), service control, chmod/chown outside the project or on sensitive paths, killing system processes or processes the agent has no relation to (kill -9 1, killall with no clear target, pkill of a broad name like "node" or "python").
27
+ - Executing inside a REMOTE host: ssh, scp, kubectl exec, Enter-PSSession, Invoke-Command — risky no matter how harmless the inner command looks; a remote system may be shared or production. A LOCAL docker exec is judged by its inner command instead (see safe list).
28
+ - git push --force, or git push to main/master/develop when no "User:" line asked for a push.
29
+ - Decode-and-execute: base64 -d / xxd -r piped into sh/bash, bash -c "$(...)", eval of an assembled string, hex/char-array reassembly that is then executed. The pattern itself is enough — you are NOT expected to decode the payload. This is NOT triggered by ordinary string building inside a readable python -c / node -e script ('a'*10, f-strings, path joins), by decoding that only prints to stdout, or by long-but-plainly-readable commands.
30
+
31
+ ## Answer "safe" for
32
+
33
+ - Read-only, or a local and reversible operation confined to the project or a temp directory.
34
+ - Creating or writing files and directories inside the project or a temp directory (mkdir, touch, cp, unzip, writing/editing source files) — including overwriting files the agent created earlier.
35
+ - Standard local dev workflow: build, test, lint, format, type-check, running the project's own scripts (npm run …, make, pytest), inline scripts (python -c, node -e, heredocs) that only touch the project or temp files.
36
+ - Local git operations that do not rewrite published history: add, commit, branch, checkout <branch>, stash, merge, rebase of a local branch, restore from index. git push of the current feature branch without --force.
37
+ - Installing dependencies into the project's LOCAL environment: npm/pnpm/yarn install (with or without a package name), pip install inside a venv or with -r requirements.txt, cargo/bundle/go get. Only GLOBAL installs are risky.
38
+ - chmod on files inside the project (chmod +x scripts/build.sh, chmod -R 755 dist).
39
+ - Killing a local dev process the transcript relates to: one the agent started earlier (an earlier run_shell line started a server), one listening on a port the task is using (kill $(lsof -t -i:3000)), or a specific pkill -f matching the project's own command (pkill -f "vite --port 5173").
40
+ - Deletion inside the project or a temp directory — see the deletion rule.
41
+ - Running or reading a script under an installed skill directory (${skillDirs.join(' | ')}) — user-installed tooling, routine even though outside the project. Risky only if its ARGUMENTS reference sensitive paths (~/.ssh, /etc, dotfiles) or embed local secrets.
42
+ - Writing to a location outside the project that a "User:" line asked for (a report into ~/Documents/…, an output folder the user named).
43
+ - Any request to a loopback address (localhost, 127.0.0.1, ::1) — including POST/PUT/DELETE during local testing (curl -X POST localhost:3000/api/items -d '{"name":"test"}'). Risky only if it carries local secrets/files or the path is plainly destructive for the user's own data (reset, wipe, drop, purge, admin/delete-all).
44
+ - A read-only GET of a public URL that embeds no local secrets or data — the domain need not be famous; docs, articles, login pages, public APIs fetched anonymously are safe.
45
+ - A LOCAL docker exec / docker compose exec whose inner command is read-only or a routine dev step (cat, ls, npm test, migrations the task is about). Risky if the inner command deletes data, installs software or changes container config.
46
+
47
+ ## Deletion rule (rm / rmdir / mv / find -delete)
48
+
49
+ Deletion inside the project or a temp directory is safe by default: regenerable artifacts (dist/, build/, caches, node_modules, coverage, *.tmp, *.log), files the agent created earlier (the same path appears in an earlier write_file/patch_file line, or in an earlier run_shell touch/mkdir/cp/unzip/echo-redirect line — the agent made it, so removing it is cleanup), scratch/probe files, a single small file the current task is plainly working on, and any deletion a "User:" line asked for. In-project mv that renames/relocates as part of the requested work is safe. Answer "risky" only when the deletion wipes pre-existing source, config or user data at scale (a whole source directory, the project root, .git, a data/ or uploads/ folder) and nothing in the transcript relates to it.
50
+
51
+ ## Examples (the LAST line of the transcript → your reply)
52
+
41
53
  run_shell npm test
42
54
  <verdict>safe</verdict>
43
55
 
44
56
  run_shell git add -A && git commit -m "fix: handle null input"
45
57
  <verdict>safe</verdict>
46
58
 
47
- run_shell mkdir -p src/utils && touch src/utils/index.ts
59
+ run_shell npm install lodash
48
60
  <verdict>safe</verdict>
49
61
 
50
- run_shell npm install
62
+ run_shell npm install -g typescript
63
+ <verdict>risky</verdict>
64
+
65
+ run_shell chmod +x scripts/check.sh
51
66
  <verdict>safe</verdict>
52
67
 
53
- run_shell rm -rf ~/.config
68
+ run_shell chmod -R 777 /usr/local
54
69
  <verdict>risky</verdict>
55
70
 
56
- User: after the tests pass, clean up the temporary scripts
57
- run_shell rm scratch/run-check.sh
71
+ run_shell npm run dev &
72
+ run_shell kill $(lsof -t -i:3000)
73
+ <verdict>safe</verdict>
74
+
75
+ run_shell pkill node
76
+ <verdict>risky</verdict>
77
+
78
+ run_shell rm -rf dist && npm run build
79
+ <verdict>safe</verdict>
80
+
81
+ run_shell touch probe.sh && chmod +x probe.sh
82
+ run_shell rm probe.sh
83
+ <verdict>safe</verdict>
84
+
85
+ run_shell sudo ls / → rejected by user, NOT executed
86
+ run_shell python3 -c "import os; d='/tmp/probe'; os.makedirs(d, exist_ok=True); open(d+'/a.txt','w').write('a'*10); print(os.listdir(d))"
87
+ <verdict>safe</verdict>
88
+
89
+ run_shell cd /tmp && rm -rf recalc_x && mkdir recalc_x && cd recalc_x && unzip -o -q /tmp/recalc.xlsx
58
90
  <verdict>safe</verdict>
59
91
 
60
92
  write_file /tmp/probe/check-output.js
@@ -62,16 +94,33 @@ run_shell node /tmp/probe/check-output.js
62
94
  run_shell rm /tmp/probe/check-output.js
63
95
  <verdict>safe</verdict>
64
96
 
65
- run_shell rm -rf dist && npm run build
66
- <verdict>safe</verdict>
97
+ run_shell rm -rf src/legacy
98
+ <verdict>risky</verdict>
67
99
 
100
+ User: delete the legacy directory, it is no longer used
68
101
  run_shell rm -rf src/legacy
102
+ <verdict>safe</verdict>
103
+
104
+ run_shell rm -rf ~/.config
69
105
  <verdict>risky</verdict>
70
106
 
71
107
  User: refactor the utils directory
72
108
  run_shell mv src/utils/helpers.ts src/utils/string-helpers.ts
73
109
  <verdict>safe</verdict>
74
110
 
111
+ User: write the analysis report into ~/Documents/reports
112
+ write_file /Users/dev/Documents/reports/analysis.md
113
+ <verdict>safe</verdict>
114
+
115
+ write_file /Users/dev/.zshrc
116
+ <verdict>risky</verdict>
117
+
118
+ run_shell git push origin feature/login-fix
119
+ <verdict>safe</verdict>
120
+
121
+ run_shell git push --force origin main
122
+ <verdict>risky</verdict>
123
+
75
124
  (the two examples below assume /Users/dev/.sema/skills is an installed skill directory)
76
125
  run_shell node /Users/dev/.sema/skills/archify/bin/archify.mjs doctor
77
126
  <verdict>safe</verdict>
@@ -79,7 +128,10 @@ run_shell node /Users/dev/.sema/skills/archify/bin/archify.mjs doctor
79
128
  run_shell bash /Users/dev/.sema/skills/backup/run.sh ~/.ssh
80
129
  <verdict>risky</verdict>
81
130
 
82
- run_shell docker exec app-container echo hi
131
+ run_shell docker exec app-container cat /app/config.yml
132
+ <verdict>safe</verdict>
133
+
134
+ run_shell docker exec app-container rm -rf /data
83
135
  <verdict>risky</verdict>
84
136
 
85
137
  run_shell ssh deploy@10.0.0.5 'tail -n 50 /var/log/app.log'
@@ -88,6 +140,9 @@ run_shell ssh deploy@10.0.0.5 'tail -n 50 /var/log/app.log'
88
140
  run_shell curl -s localhost:3000/api/health
89
141
  <verdict>safe</verdict>
90
142
 
143
+ run_shell curl -X POST localhost:3000/api/items -H 'Content-Type: application/json' -d '{"name":"test"}'
144
+ <verdict>safe</verdict>
145
+
91
146
  run_shell curl -X POST localhost:3000/admin/reset
92
147
  <verdict>risky</verdict>
93
148
 
@@ -1 +1 @@
1
- {"version":3,"file":"permission.js","sourceRoot":"","sources":["../../src/prompt/permission.ts"],"names":[],"mappings":";;;AAAA,gEAAgE;AAChE,0EAA0E;AAC1E,kDAAkD;AAClD,sFAAsF;AACtF,iFAAiF;AACjF,oFAAoF;AACpF,sDAAsD;AAC/C,MAAM,qCAAqC,GAAG,CAAC,SAAmB,EAAU,EAAE,CAAC;;;;;;;;;;;;;;;;;;;;;;;oEAuBlB,SAAS,CAAC,IAAI,CAAC,KAAK,CAAC;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;8GA+EqB,CAAA;AAtGjG,QAAA,qCAAqC,yCAsG4D"}
1
+ {"version":3,"file":"permission.js","sourceRoot":"","sources":["../../src/prompt/permission.ts"],"names":[],"mappings":";;;AAAA,gEAAgE;AAChE,0EAA0E;AAC1E,kDAAkD;AAClD,sFAAsF;AACtF,iFAAiF;AACjF,oFAAoF;AACpF,sDAAsD;AAC/C,MAAM,qCAAqC,GAAG,CAAC,SAAmB,EAAU,EAAE,CAAC;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;oEA8BlB,SAAS,CAAC,IAAI,CAAC,KAAK,CAAC;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;8GA+HqB,CAAA;AA7JjG,QAAA,qCAAqC,yCA6J4D"}
@@ -0,0 +1,18 @@
1
+ import type { SkillConfig } from '../types/skill';
2
+ /**
3
+ * 内置 skill 的路径上下文:正文里的安装位置用运行时真实路径,不写死 ~/.sema
4
+ * (用户级根目录可由环境变量 SEMA_ROOT 自定义)
5
+ */
6
+ export interface BuiltInSkillPaths {
7
+ /** 用户级根目录,如 /Users/dev/.sema */
8
+ userRoot: string;
9
+ /** 项目级根目录,如 /path/to/project/.sema */
10
+ projectRoot: string;
11
+ }
12
+ export declare const SKILL_NAME_SEMA_EXTEND = "sema-extend";
13
+ /**
14
+ * 内置 skills(随 core 提供,最低优先级,用户级/项目级同名 skill 可覆盖;不可删除,不支持开关)
15
+ * 不设 filePath:内置 skill 没有磁盘目录
16
+ */
17
+ export declare function buildBuiltInSkillConfs(paths: BuiltInSkillPaths): SkillConfig[];
18
+ //# sourceMappingURL=skills.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"skills.d.ts","sourceRoot":"","sources":["../../src/prompt/skills.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,gBAAgB,CAAA;AAEjD;;;GAGG;AACH,MAAM,WAAW,iBAAiB;IAChC,gCAAgC;IAChC,QAAQ,EAAE,MAAM,CAAA;IAChB,sCAAsC;IACtC,WAAW,EAAE,MAAM,CAAA;CACpB;AAED,eAAO,MAAM,sBAAsB,gBAAgB,CAAA;AA6InD;;;GAGG;AACH,wBAAgB,sBAAsB,CAAC,KAAK,EAAE,iBAAiB,GAAG,WAAW,EAAE,CAQ9E"}