sentinel-agentos 0.1.3 → 0.2.0

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 CHANGED
@@ -793,6 +793,36 @@ const entries = api.auditQuery({ minScore: 3.0 }); // 高风险操作 · High-ri
793
793
  ```
794
794
  </details>
795
795
 
796
+ <details>
797
+ <summary><b>Q: Sentinel AgentOS 需要 API Key 吗? · Does it need an API Key?</b></summary>
798
+
799
+ 不需要。Sentinel AgentOS 的 Guard / Memory / Evaluator 层都是纯确定性代码,不调用任何外部 AI API。唯一的鉴权是 HTTP API 模式下可选的 `--token` 参数。
800
+ *No. All Guard/Memory/Evaluator layers are pure deterministic code with zero external API calls. The only authentication is the optional `--token` for HTTP API mode.*
801
+ </details>
802
+
803
+ <details>
804
+ <summary><b>Q: HTTP API Token 怎么设置? · How to set HTTP API token?</b></summary>
805
+
806
+ 三种方式:
807
+ 1. 命令行参数:`npx sentinel-agentos server --port 3300 --token my-secret`
808
+ 2. 代码中配置:`createServer({ port: 3300, apiToken: 'my-secret' })`
809
+ 3. 环境变量:`AGENTOS_TOKEN=*** npx sentinel-agentos server`
810
+
811
+ 不设置 Token 则不加鉴权(仅适合本地开发环境)。
812
+ *Three ways: CLI flag, code config, or AGENTOS_TOKEN env var. No token = no auth (local dev only).*
813
+ </details>
814
+
815
+ <details>
816
+ <summary><b>Q: Token 泄漏了怎么办? · What if token leaks?</b></summary>
817
+
818
+ 重启服务,换一个新 Token 即可:
819
+ 1. 生成新 Token:`openssl rand -hex 32`
820
+ 2. 重启 sentinel-agentos server 使用新 Token
821
+ 3. 更新所有客户端调用
822
+ Sentinel AgentOS 的 Token 是服务端本地验证的,无需到任何平台撤销。
823
+ *Restart server with a new token. No external platform involved — tokens are validated locally.*
824
+ </details>
825
+
796
826
  ---
797
827
 
798
828
  ## 🗺️ 路线图 · Roadmap
@@ -809,6 +839,643 @@ const entries = api.auditQuery({ minScore: 3.0 }); // 高风险操作 · High-ri
809
839
 
810
840
  ---
811
841
 
842
+ ## 🔑 Token 与鉴权说明
843
+
844
+ Sentinel AgentOS 本身**不依赖外部 AI API**,所有 Guard / Memory / Evaluator 都是纯确定性代码。唯一的鉴权需求来自 **HTTP API 模式**下的 `server` 命令。
845
+
846
+ ### HTTP API Token 鉴权
847
+
848
+ 启动 HTTP 服务后,除 `/health` 外所有端点都需要 Bearer Token 鉴权。
849
+
850
+ #### 启动时设置 Token
851
+
852
+ ```bash
853
+ # 方式一:命令行参数
854
+ npx sentinel-agentos server --port 3300 --token my-secret-token-123
855
+
856
+ # 方式二:代码中配置
857
+ import { createServer } from 'sentinel-agentos';
858
+ const server = createServer({ port: 3300, apiToken: 'my-secret-token-123' });
859
+ await server.start();
860
+ ```
861
+
862
+ #### 客户端调用
863
+
864
+ ```bash
865
+ # 所有 API(/health 除外)都需要 Authorization header
866
+ curl -H "Authorization: Bearer my-secret-token-123" \
867
+ http://localhost:3300/pipeline/profile
868
+
869
+ # Token 不匹配 → 401 Unauthorized
870
+ curl http://localhost:3300/pipeline/profile
871
+ # → {"error":"Unauthorized: invalid or missing API token"}
872
+ ```
873
+
874
+ #### Token 未设置时
875
+
876
+ 如果不传 `--token` 或 `apiToken`,服务**不加鉴权**,所有端点可自由访问。适用于本地开发环境,生产环境**强烈建议设置 Token**。
877
+
878
+ ```bash
879
+ # 无鉴权模式(仅限本地开发)
880
+ npx sentinel-agentos server --port 3300
881
+ # 所有端点无需 Authorization header
882
+ ```
883
+
884
+ #### Token 最佳实践
885
+
886
+ | 环境 | Token 策略 | 示例 |
887
+ |------|----------|------|
888
+ | 本地开发 | 可不用 Token | `npx sentinel-agentos server --port 3300` |
889
+ | 本机测试 | 简短 Token | `--token dev-123` |
890
+ | 生产环境 | 强随机 Token | `--token $(openssl rand -hex 32)` |
891
+ | Docker / CI | 环境变量注入 | `--token $AGENTOS_API_TOKEN` |
892
+ | 跨语言调用 | HTTP header | `Authorization: Bearer <token>` |
893
+
894
+ ### 环境变量配置
895
+
896
+ 除 Token 外,Sentinel AgentOS 没有其他必填环境变量。可选的环境变量:
897
+
898
+ | 环境变量 | 说明 | 默认值 |
899
+ |---------|------|--------|
900
+ | `HOME` / `USERPROFILE` | 持久化存储根目录 | 系统默认 |
901
+ | `AGENTOS_WORKSPACE` | workspace 根目录 | `process.cwd()` |
902
+ | `AGENTOS_TOKEN` | API Token(备选方式) | — |
903
+
904
+ ---
905
+
906
+ ## 📋 完整接口使用说明
907
+
908
+ > 本章汇总 Sentinel AgentOS 所有接口——CLI、SDK、HTTP API、中间件、沙箱——作为完整参考。
909
+
910
+ ### 命令一览
911
+
912
+ | 分类 | 接口/命令 | 说明 |
913
+ |------|---------|------|
914
+ | CLI | `validate` | 参数格式校验(Schema Gate) |
915
+ | CLI | `risk` | 风险评分(Risk Gate) |
916
+ | CLI | `audit` | 查询审计日志 |
917
+ | CLI | `stats` | 审计统计(JSON) |
918
+ | CLI | `profile` | Agent 质量画像(JSON) |
919
+ | CLI | `status` | 质量状态报告(人类可读) |
920
+ | CLI | `server` | 启动 HTTP API 服务 |
921
+ | CLI | `memory` | 查看注入上下文 |
922
+ | CLI | `help` | 帮助信息 |
923
+ | SDK | `AgentOS` | 主类,完整流水线 |
924
+ | SDK | `AgentOSAPI` | SDK 协议层(25+ 方法) |
925
+ | SDK | `SchemaGate` / `RiskGate` 等 | 独立组件 |
926
+ | SDK | `wrapAgent` | 一行接入中间件 |
927
+ | SDK | `sentinelPlugin` | OpenClaw 插件 |
928
+ | SDK | `SandboxExecutor` | 沙箱执行器 |
929
+ | HTTP | `POST /pipeline/pre` | 执行前校验 |
930
+ | HTTP | `POST /pipeline/post` | 执行后验证 |
931
+ | HTTP | `GET /pipeline/report` | 状态报告 |
932
+ | HTTP | `GET /pipeline/profile` | 质量画像 |
933
+ | HTTP | `POST /guard/schema` | 注册 Schema 规则 |
934
+ | HTTP | `GET /guard/schema` | 查看 Schema 规则 |
935
+ | HTTP | `POST /memory/preference` | 设置偏好 |
936
+ | HTTP | `POST /memory/fact` | 添加事实 |
937
+ | HTTP | `POST /memory/rule` | 学习规则 |
938
+ | HTTP | `GET /memory/context` | 获取注入上下文 |
939
+ | HTTP | `GET /audit` | 查询审计日志 |
940
+ | HTTP | `POST /feedback` | 记录反馈 |
941
+ | HTTP | `POST /session/end` | 结束 session |
942
+ | HTTP | `GET /health` | 健康检查(免 Token) |
943
+
944
+ ---
945
+
946
+ ### CLI 接口
947
+
948
+ ```
949
+ sentinel-agentos <command> [args...]
950
+ ```
951
+
952
+ #### `validate` — 参数格式校验
953
+
954
+ ```bash
955
+ # 新语法(推荐)
956
+ sentinel-agentos validate <tool> [key=value...]
957
+
958
+ # 校验 exec 命令
959
+ sentinel-agentos validate exec command="rm -rf /"
960
+ # → {"pass":true,"errors":[]}
961
+
962
+ # 校验 write_file(会被 pathDeny 拦截)
963
+ sentinel-agentos validate write_file path=.env content=hello
964
+ # → {"pass":false,"errors":[{"field":"path","message":"path matches deny pattern"}]}
965
+
966
+ # 旧语法(--tool + --params JSON)
967
+ sentinel-agentos validate --tool exec --params '{"command":"npm test"}'
968
+ ```
969
+
970
+ | 参数 | 说明 |
971
+ |------|------|
972
+ | `<tool>` | 工具名称(如 `exec`, `write_file`, `delete_file`) |
973
+ | `key=value` | 参数键值对,支持 `key="带空格的值"`,自动检测类型 |
974
+
975
+ #### `risk` — 风险评分
976
+
977
+ ```bash
978
+ sentinel-agentos risk exec command="sudo reboot"
979
+ # → {"score":8.5,"action":"deny","dimensions":{"impact":3,"reversibility":0.2,...}}
980
+
981
+ sentinel-agentos risk exec command="npm test"
982
+ # → {"score":0.19,"action":"auto",...}
983
+ ```
984
+
985
+ | 风险等级 | 分数 | 动作 |
986
+ |---------|------|------|
987
+ | 🟢 Auto | ≤ 0.5 | 自动放行 |
988
+ | 🔵 Notify | ≤ 1.0 | 执行后通知 |
989
+ | 🟡 Confirm | ≤ 3.0 | 暂停等待确认 |
990
+ | 🔴 Deny | > 8.0 | 直接拒绝 |
991
+
992
+ #### `audit` — 查询审计日志
993
+
994
+ ```bash
995
+ sentinel-agentos audit --limit 10
996
+ # → [{id, sessionId, toolName, verifyStatus, riskScore, ...}, ...]
997
+
998
+ sentinel-agentos audit --limit 5
999
+ ```
1000
+
1001
+ #### `stats` / `profile` / `status` — 统计与画像
1002
+
1003
+ ```bash
1004
+ # 审计统计(JSON)
1005
+ sentinel-agentos stats
1006
+ # → {"totalOperations":156,"verifyFailures":2,"highRiskOps":3,...}
1007
+
1008
+ # Agent 质量画像(JSON)
1009
+ sentinel-agentos profile
1010
+ # → {"overallScore":85,"breakdown":{...},"trends":{...},"warnings":[...]}
1011
+
1012
+ # 质量状态报告(人类可读)
1013
+ sentinel-agentos status
1014
+ # → 文本报告
1015
+ ```
1016
+
1017
+ #### `server` — 启动 HTTP API 服务
1018
+
1019
+ ```bash
1020
+ sentinel-agentos server --port 3300 --token ***
1021
+ # → 🛡️ Sentinel AgentOS HTTP server → http://127.0.0.1:3300
1022
+
1023
+ # 可选项
1024
+ sentinel-agentos server --port 8080 --host 0.0.0.0 --token ***
1025
+ ```
1026
+
1027
+ | 参数 | 默认值 | 说明 |
1028
+ |------|--------|------|
1029
+ | `--port <N>` | `3300` | 服务端口 |
1030
+ | `--host <IP>` | `127.0.0.1` | 绑定地址 |
1031
+ | `--token <str>` | — | API 鉴权 Token(不设则无鉴权) |
1032
+
1033
+ #### `memory` — 查看记忆上下文
1034
+
1035
+ ```bash
1036
+ sentinel-agentos memory
1037
+ # → 当前 semantic + episodic 注入的上下文文本
1038
+ ```
1039
+
1040
+ ---
1041
+
1042
+ ### SDK 接口
1043
+
1044
+ #### `AgentOS` — 主类
1045
+
1046
+ ```typescript
1047
+ import { AgentOS } from 'sentinel-agentos';
1048
+
1049
+ const aos = new AgentOS({
1050
+ workspaceRoot: process.cwd(), // 工作区根目录
1051
+ maxWorkingTokens: 50000, // 工作记忆 token 上限
1052
+ maxEpisodicSizeKb: 500, // 情景记忆大小上限 (KB)
1053
+ guardConfig: { // Guard 配置
1054
+ riskGate: {
1055
+ autoApprove: 0.5,
1056
+ notify: 1.0,
1057
+ confirm: 3.0,
1058
+ deny: 8.0,
1059
+ },
1060
+ },
1061
+ });
1062
+ ```
1063
+
1064
+ **构造函数参数 `AgentOSConfig`**:
1065
+
1066
+ | 字段 | 类型 | 默认值 | 说明 |
1067
+ |------|------|--------|------|
1068
+ | `workspaceRoot` | string | `process.cwd()` | 工作区根目录,持久化存储位置 |
1069
+ | `maxWorkingTokens` | number | `50000` | 工作记忆最大 token 数 |
1070
+ | `maxEpisodicSizeKb` | number | `500` | 情景记忆最大大小 (KB) |
1071
+ | `guardConfig.riskGate` | object | 见上 | 风险评分阈值覆盖 |
1072
+ | `evaluatorConfig.implicitFeedbackEnabled` | boolean | — | 隐性反馈开关 |
1073
+
1074
+ **核心方法**:
1075
+
1076
+ | 方法 | 返回 | 说明 |
1077
+ |------|------|------|
1078
+ | `executePipeline({...})` | `{preExec, snapshot, profile}` | 执行前校验流水线(Schema + Risk + Snapshot) |
1079
+ | `completeExecution({...})` | `{runtime, postExec, auditEntry, profile}` | 执行后验证流水线(Verify + Audit) |
1080
+ | `recordFeedback(signal, sessionId)` | `void` | 记录隐性用户反馈 |
1081
+ | `injectContext()` | `string` | 注入记忆上下文(session 启动时调用) |
1082
+ | `endSession(sessionId)` | `void` | 结束 session(清空 Working Memory) |
1083
+ | `getProfile(sessionId?)` | `AgentProfile` | 获取 Agent 质量画像 |
1084
+ | `getAuditStats()` | 审计统计 | 获取审计统计 |
1085
+ | `statusReport()` | `string` | 获取人类可读的状态报告 |
1086
+
1087
+ **访问子组件**:
1088
+
1089
+ ```typescript
1090
+ // Guard 层
1091
+ aos.guard.schema // SchemaGate — 注册/查询校验规则
1092
+ aos.guard.risk // RiskGate — 风险评分引擎
1093
+ aos.guard.snapshot // SnapshotGate — 执行前快照
1094
+ aos.guard.verify // VerifyGate — 执行后验证
1095
+ aos.guard.audit // AuditLog — 审计日志
1096
+
1097
+ // Memory 层
1098
+ aos.memory.working // WorkingMemory — 当前会话工作记忆
1099
+ aos.memory.episodic // EpisodicMemory — 跨会话事件时间线
1100
+ aos.memory.semantic // SemanticMemoryStore — 永久知识
1101
+
1102
+ // Evaluator 层
1103
+ aos.evaluator.preExec // PreExecEvaluator — 执行前评估
1104
+ aos.evaluator.runtime // RuntimeEvaluator — 执行中评估
1105
+ aos.evaluator.postExec // PostExecEvaluator — 执行后评估
1106
+ aos.evaluator.feedback // ImplicitFeedbackEngine — 隐性反馈
1107
+ aos.evaluator.profiler // AgentProfiler — 质量画像
1108
+ ```
1109
+
1110
+ #### `AgentOSAPI` — SDK 协议层
1111
+
1112
+ ```typescript
1113
+ import { AgentOS, AgentOSAPI } from 'sentinel-agentos';
1114
+
1115
+ const api = new AgentOSAPI(new AgentOS());
1116
+
1117
+ // Guard
1118
+ api.guardRegisterRule({ tool: 'exec', required: ['command'] });
1119
+ api.guardRegisterRules([...]);
1120
+ api.guardEvaluateRisk('exec', { command: 'rm -rf /' });
1121
+ api.guardSetRiskThresholds({ autoApprove: 0.5, deny: 6.0 });
1122
+
1123
+ // Pipeline
1124
+ const result = await api.pipelineExecute({
1125
+ sessionId: 's1', agentId: 'a1',
1126
+ toolName: 'write_file',
1127
+ toolParameters: { path: 'src/main.ts', content: 'hello' },
1128
+ });
1129
+ const complete = api.pipelineComplete({...});
1130
+
1131
+ // Memory
1132
+ api.memorySetPreference('language', 'zh-CN');
1133
+ api.memoryGetPreference('language'); // → 'zh-CN'
1134
+ api.memoryLearnRule('提交前 npm test', 'session_1');
1135
+ api.memoryDefineTerm('PEP', 'Python Enhancement Proposal');
1136
+ api.memorySetProjectContext('my-app', { description: '...', techStack: ['React', 'Node'] });
1137
+ api.memoryInjectContext(); // → 启动注入文本
1138
+ api.memoryAddMessage('user', 'Hello');
1139
+ api.memoryRecordEvent('decision', 'Chose approach A', ['architecture'], []);
1140
+
1141
+ // Audit
1142
+ api.auditQuery({ toolName: 'exec', limit: 10 });
1143
+ api.auditQuery({ minScore: 3.0 }); // 高风险操作
1144
+ api.auditStats();
1145
+
1146
+ // Feedback
1147
+ api.recordFeedback('user_explicit_approval', 's1');
1148
+ api.getSatisfaction(); // → 82 (0-100)
1149
+ api.getSatisfaction('s1', 24); // 最近 24 小时
1150
+ api.feedbackStats();
1151
+
1152
+ // Profile
1153
+ api.getProfile();
1154
+ api.getProfile('s1');
1155
+ api.getStatusReport();
1156
+ api.getSessionOverview();
1157
+
1158
+ // Session
1159
+ api.endSession('s1');
1160
+ ```
1161
+
1162
+ **AgentOSAPI 完整方法清单(25 个)**:
1163
+
1164
+ | 方法 | 说明 |
1165
+ |------|------|
1166
+ | `guardRegisterRule(rule)` | 注册单条 Schema 规则 |
1167
+ | `guardRegisterRules(rules)` | 批量注册 Schema 规则 |
1168
+ | `guardHasRule(toolName)` | 检查工具是否有规则 |
1169
+ | `guardGetRules()` | 获取所有已注册规则 |
1170
+ | `guardEvaluateRisk(tool, params)` | 评估风险评分 |
1171
+ | `guardSetRiskThresholds(thresholds)` | 设置风险阈值 |
1172
+ | `pipelineExecute(params)` | 执行前校验流水线 |
1173
+ | `pipelineComplete(params)` | 执行后验证流水线 |
1174
+ | `memoryInjectContext()` | 注入记忆上下文 |
1175
+ | `memoryAddMessage(role, content)` | 添加工作记忆消息 |
1176
+ | `memorySetTask(task)` | 设置当前任务 |
1177
+ | `memoryCacheResult(tool, result)` | 缓存工具结果 |
1178
+ | `memoryRecordEvent(type, content, tags, entities)` | 记录情景事件 |
1179
+ | `memorySetPreference(key, value)` | 设置用户偏好 |
1180
+ | `memoryGetPreference(key)` | 获取用户偏好 |
1181
+ | `memoryLearnRule(rule, source)` | 学习规则 |
1182
+ | `memoryDefineTerm(term, meaning)` | 定义术语 |
1183
+ | `memorySetProjectContext(name, context)` | 设置项目上下文 |
1184
+ | `auditQuery(filter)` | 查询审计日志 |
1185
+ | `auditStats()` | 审计统计 |
1186
+ | `recordFeedback(signal, sessionId)` | 记录反馈 |
1187
+ | `getSatisfaction(sessionId?, hours?)` | 获取满意度 |
1188
+ | `feedbackStats()` | 反馈统计 |
1189
+ | `getProfile(sessionId?)` | 获取质量画像 |
1190
+ | `getStatusReport()` | 获取状态报告 |
1191
+ | `getSessionOverview()` | 获取 session 概况 |
1192
+ | `endSession(sessionId)` | 结束 session |
1193
+
1194
+ ---
1195
+
1196
+ ### HTTP API 接口
1197
+
1198
+ 基础 URL:`http://localhost:3300`(默认)
1199
+
1200
+ #### Request/Response 通用格式
1201
+
1202
+ - **Content-Type**:`application/json`
1203
+ - **鉴权**:除 `/health` 外,`Authorization: Bearer <token>`
1204
+ - **成功**:`200 OK`,JSON body
1205
+ - **鉴权失败**:`401 Unauthorized`
1206
+ - **参数错误**:`400 Bad Request`,`{"error":"..."}`
1207
+ - **服务错误**:`500 Internal Server Error`
1208
+
1209
+ #### 端点详情
1210
+
1211
+ ##### `GET /health` — 健康检查(免 Token)
1212
+
1213
+ ```bash
1214
+ curl http://localhost:3300/health
1215
+ # → {"ok":true,"uptime":12.3}
1216
+ ```
1217
+
1218
+ ##### `POST /pipeline/pre` — 执行前校验
1219
+
1220
+ ```bash
1221
+ curl -X POST http://localhost:3300/pipeline/pre \
1222
+ -H "Authorization: Bearer ***" \
1223
+ -H "Content-Type: application/json" \
1224
+ -d '{
1225
+ "sessionId": "s1",
1226
+ "agentId": "main",
1227
+ "toolName": "exec",
1228
+ "parameters": {"command": "npm test"},
1229
+ "affectedFiles": []
1230
+ }'
1231
+ ```
1232
+
1233
+ | 字段 | 类型 | 必填 | 说明 |
1234
+ |------|------|------|------|
1235
+ | `toolName` | string | ✅ | 工具名 |
1236
+ | `sessionId` | string | ❌ | 默认 `"http_session"` |
1237
+ | `agentId` | string | ❌ | 默认 `"http_agent"` |
1238
+ | `parameters` | object | ❌ | 工具参数,默认 `{}` |
1239
+ | `affectedFiles` | string[] | ❌ | 受影响的文件列表 |
1240
+
1241
+ **返回**:
1242
+
1243
+ ```json
1244
+ {
1245
+ "preExec": {
1246
+ "schemaCheck": { "pass": true, "errors": [] },
1247
+ "riskScore": { "score": 0.19, "action": "auto", "dimensions": {...} },
1248
+ "paramQuality": { "score": 85, "observations": [] },
1249
+ "contextUtilization": { "score": 70, "patterns": [] }
1250
+ },
1251
+ "snapshot": { "id": "...", "fileHashes": {...}, "gitHead": "...", "gitDirty": false },
1252
+ "profile": { "overallScore": 85, ... }
1253
+ }
1254
+ ```
1255
+
1256
+ ##### `POST /pipeline/post` — 执行后验证
1257
+
1258
+ ```bash
1259
+ curl -X POST http://localhost:3300/pipeline/post \
1260
+ -H "Authorization: Bearer ***" \
1261
+ -H "Content-Type: application/json" \
1262
+ -d '{
1263
+ "toolName": "exec",
1264
+ "toolParameters": {"command": "npm test"},
1265
+ "toolResult": "all passed",
1266
+ "snapshot": {...},
1267
+ "startTime": 1718123456000,
1268
+ "endTime": 1718123457000,
1269
+ "retryCount": 0,
1270
+ "wasSelfCorrected": false,
1271
+ "hadTimeout": false,
1272
+ "userAccepted": true,
1273
+ "userProvidedEdit": false,
1274
+ "resultWasUsed": true
1275
+ }'
1276
+ ```
1277
+
1278
+ | 字段 | 类型 | 必填 | 说明 |
1279
+ |------|------|------|------|
1280
+ | `toolName` | string | ✅ | 工具名 |
1281
+ | `sessionId` | string | ❌ | session 标识 |
1282
+ | `agentId` | string | ❌ | agent 标识 |
1283
+ | `toolParameters` | object | ❌ | 执行时的参数 |
1284
+ | `toolResult` | any | ❌ | 工具返回结果 |
1285
+ | `snapshot` | object | ❌ | 从 `/pipeline/pre` 获取的 snapshot |
1286
+ | `startTime` | number | ❌ | 执行开始时间戳 ms |
1287
+ | `endTime` | number | ❌ | 执行结束时间戳 ms |
1288
+ | `retryCount` | number | ❌ | 重试次数,默认 0 |
1289
+ | `wasSelfCorrected` | boolean | ❌ | Agent 是否自我纠正 |
1290
+ | `hadTimeout` | boolean | ❌ | 是否超时 |
1291
+ | `userAccepted` | boolean | ❌ | 用户是否接受了结果 |
1292
+ | `userProvidedEdit` | boolean | ❌ | 用户是否修改了结果 |
1293
+ | `resultWasUsed` | boolean | ❌ | 用户是否使用了结果 |
1294
+
1295
+ ##### `GET /pipeline/report` / `GET /pipeline/profile`
1296
+
1297
+ ```bash
1298
+ curl -H "Authorization: Bearer ***" http://localhost:3300/pipeline/report
1299
+ # → {"report":"=== AgentOS Status Report ===\n..."}
1300
+
1301
+ curl -H "Authorization: Bearer ***" http://localhost:3300/pipeline/profile
1302
+ curl -H "Authorization: Bearer ***" "http://localhost:3300/pipeline/profile?sessionId=s1"
1303
+ ```
1304
+
1305
+ ##### `POST /guard/schema` / `GET /guard/schema`
1306
+
1307
+ ```bash
1308
+ # 注册规则
1309
+ curl -X POST http://localhost:3300/guard/schema \
1310
+ -H "Authorization: Bearer ***" \
1311
+ -H "Content-Type: application/json" \
1312
+ -d '{"tool":"delete_file","required":["path"],"forbidden":[]}'
1313
+ # → {"ok":true,"tool":"delete_file"}
1314
+
1315
+ # 查看规则
1316
+ curl -H "Authorization: Bearer ***" "http://localhost:3300/guard/schema?tool=delete_file"
1317
+ ```
1318
+
1319
+ ##### Memory 端点(4 个)
1320
+
1321
+ ```bash
1322
+ # 设置偏好
1323
+ curl -X POST http://localhost:3300/memory/preference \
1324
+ -H "Authorization: Bearer ***" -H "Content-Type: application/json" \
1325
+ -d '{"key":"language","value":"zh-CN"}'
1326
+
1327
+ # 添加事实
1328
+ curl -X POST http://localhost:3300/memory/fact \
1329
+ -H "Authorization: Bearer ***" -H "Content-Type: application/json" \
1330
+ -d '{"fact":"用户在北京"}'
1331
+
1332
+ # 学习规则
1333
+ curl -X POST http://localhost:3300/memory/rule \
1334
+ -H "Authorization: Bearer ***" -H "Content-Type: application/json" \
1335
+ -d '{"rule":"提交前运行 npm test","source":"session_1"}'
1336
+
1337
+ # 获取注入上下文
1338
+ curl -H "Authorization: Bearer ***" http://localhost:3300/memory/context
1339
+ ```
1340
+
1341
+ ##### `GET /audit` — 审计查询
1342
+
1343
+ ```bash
1344
+ curl -H "Authorization: Bearer ***" "http://localhost:3300/audit?limit=10"
1345
+ curl -H "Authorization: Bearer ***" "http://localhost:3300/audit?toolName=exec&status=FAIL"
1346
+ ```
1347
+
1348
+ | 查询参数 | 说明 |
1349
+ |---------|------|
1350
+ | `limit` | 返回条数(默认 20) |
1351
+ | `toolName` | 按工具名过滤 |
1352
+ | `status` | 按校验状态过滤:`PASS` / `WARN` / `FAIL` |
1353
+
1354
+ ##### `POST /feedback` — 记录隐性反馈
1355
+
1356
+ ```bash
1357
+ curl -X POST http://localhost:3300/feedback \
1358
+ -H "Authorization: Bearer ***" -H "Content-Type: application/json" \
1359
+ -d '{"signal":"user_explicit_approval","sessionId":"s1"}'
1360
+ ```
1361
+
1362
+ **支持的 signal 值**:
1363
+
1364
+ | Signal | 强度 | 说明 |
1365
+ |--------|------|------|
1366
+ | `user_explicit_approval` | +0.6 | 用户明确说"做得好" |
1367
+ | `user_immediate_continue` | +0.3 | 用户立即继续对话 |
1368
+ | `user_used_result` | +0.7 | 用户使用了 Agent 的结果 |
1369
+ | `user_shared_output` | +0.8 | 用户分享了 Agent 输出 |
1370
+ | `user_modified_output` | -0.5 | 用户修改了 Agent 输出 |
1371
+ | `user_deleted_code` | -0.8 | 用户删除了 Agent 创建的代码 |
1372
+ | `user_interrupted` | -0.6 | 用户打断了 Agent |
1373
+ | `user_repeated_instruction` | -0.3 | 用户重复了相同指令 |
1374
+
1375
+ ##### `POST /session/end` — 结束 Session
1376
+
1377
+ ```bash
1378
+ curl -X POST http://localhost:3300/session/end \
1379
+ -H "Authorization: Bearer ***" -H "Content-Type: application/json" \
1380
+ -d '{"sessionId":"s1"}'
1381
+ # → {"ok":true}
1382
+ ```
1383
+
1384
+ ---
1385
+
1386
+ ### 中间件 / 插件接口
1387
+
1388
+ #### `wrapAgent` — 一行接入中间件
1389
+
1390
+ ```typescript
1391
+ import { wrapAgent } from 'sentinel-agentos';
1392
+
1393
+ const sentinel = wrapAgent({ workspaceRoot: process.cwd() });
1394
+
1395
+ // 每个工具调用前后调用
1396
+ const { allowed, reason } = sentinel.preCheck('exec', { command: 'rm -rf /' });
1397
+ // → { allowed: false, reason: 'Risk 9.18 → DENY' }
1398
+
1399
+ const { allowed } = sentinel.preCheck('exec', { command: 'npm test' });
1400
+ // → { allowed: true }
1401
+
1402
+ // 执行后验证
1403
+ sentinel.postCheck('exec', { command: 'npm test' }, 'all passed');
1404
+ ```
1405
+
1406
+ **`wrapAgent` 参数**:
1407
+
1408
+ | 参数 | 类型 | 默认值 | 说明 |
1409
+ |------|------|--------|------|
1410
+ | `workspaceRoot` | string | `process.cwd()` | 工作区根目录 |
1411
+ | `maxWorkingTokens` | number | `50000` | 工作记忆 token 上限 |
1412
+ | `preRegisteredRules` | boolean | `false` | 是否使用内置默认规则 |
1413
+
1414
+ #### `sentinelPlugin` — OpenClaw 插件
1415
+
1416
+ ```typescript
1417
+ import { sentinelPlugin } from 'sentinel-agentos';
1418
+
1419
+ const plugin = sentinelPlugin({
1420
+ workspaceRoot: process.cwd(),
1421
+ preRegisteredRules: true,
1422
+ });
1423
+ // → onBeforeTool → Schema + Risk 校验
1424
+ // → onAfterTool → Verify + Audit 记录
1425
+ ```
1426
+
1427
+ ---
1428
+
1429
+ ### Sandbox 沙箱接口
1430
+
1431
+ ```typescript
1432
+ import { SandboxExecutor } from 'sentinel-agentos';
1433
+
1434
+ const sandbox = new SandboxExecutor({
1435
+ mode: 'sandbox', // 'direct' | 'sandbox' | 'dry-run'
1436
+ workspaceRoot: process.cwd(),
1437
+ timeoutMs: 30000, // 命令超时 30s
1438
+ networkAccess: 'whitelist', // 'none' | 'localhost' | 'whitelist'
1439
+ networkWhitelist: ['api.github.com', 'registry.npmjs.org'],
1440
+ writablePaths: ['src/', 'tests/', 'dist/'],
1441
+ readonlyPaths: ['node_modules/', '.git/'],
1442
+ allowedTools: ['read_file', 'write_file', 'edit', 'exec'],
1443
+ forbiddenTools: ['rm', 'unlink', 'delete_file'],
1444
+ });
1445
+
1446
+ // 预检
1447
+ const check = sandbox.validate('exec', { command: 'curl evil.com' });
1448
+ // → { success: false, sandboxRejectReason: 'Network not in whitelist' }
1449
+
1450
+ // 执行
1451
+ const result = await sandbox.execute('exec', { command: 'npm test' });
1452
+ // → { success: true, result: {...} }
1453
+ ```
1454
+
1455
+ **`SandboxExecutor` 构造参数**:
1456
+
1457
+ | 参数 | 类型 | 默认值 | 说明 |
1458
+ |------|------|--------|------|
1459
+ | `mode` | `'direct' | 'sandbox' | 'dry-run'` | `'sandbox'` | 执行模式 |
1460
+ | `workspaceRoot` | string | `process.cwd()` | 工作区根目录 |
1461
+ | `timeoutMs` | number | `30000` | 命令超时毫秒 |
1462
+ | `networkAccess` | `'none' | 'localhost' | 'whitelist'` | `'localhost'` | 网络策略 |
1463
+ | `networkWhitelist` | string[] | `[]` | 网络白名单域名 |
1464
+ | `writablePaths` | string[] | `[]` | 可写路径 |
1465
+ | `readonlyPaths` | string[] | `[]` | 只读路径 |
1466
+ | `allowedTools` | string[] | `[]` | 允许的工具 |
1467
+ | `forbiddenTools` | string[] | `[]` | 禁止的工具 |
1468
+
1469
+ **执行模式说明**:
1470
+
1471
+ | 模式 | 说明 |
1472
+ |------|------|
1473
+ | `direct` | 直接执行,无限制 |
1474
+ | `sandbox` | 沙箱模式,受限的文件系统和网络访问 |
1475
+ | `dry-run` | 试运行,不实际执行,只校验权限 |
1476
+
1477
+ ---
1478
+
812
1479
  ## 📂 源码结构 · Source Layout
813
1480
 
814
1481
  ```
package/dist/cli.js CHANGED
@@ -60,9 +60,14 @@ Usage:
60
60
  sentinel-agentos profile
61
61
  sentinel-agentos status
62
62
  sentinel-agentos server [--port N] [--token ***
63
+ sentinel-agentos init (一键安装 Guard Skill 到 OpenClaw workspace)
63
64
  sentinel-agentos memory
64
65
  sentinel-agentos help
65
66
 
67
+ Quick start:
68
+ sentinel-agentos init # 安装 Sentinel Guard Skill → 自动启用全部功能
69
+ sentinel-agentos status # 查看质量报告
70
+
66
71
  Examples:
67
72
  sentinel-agentos validate exec command="rm -rf /"
68
73
  sentinel-agentos validate write_file path=src/main.ts content="console.log(1)"
@@ -234,6 +239,103 @@ async function main() {
234
239
  console.log(context || '(no memory context yet)');
235
240
  break;
236
241
  }
242
+ case 'init': {
243
+ const fs = await Promise.resolve().then(() => __importStar(require('fs')));
244
+ const path = await Promise.resolve().then(() => __importStar(require('path')));
245
+ // Find OpenClaw workspace (from env or common locations)
246
+ const home = process.env.USERPROFILE || process.env.HOME || '~';
247
+ const workspaceDir = process.env.OPENCLAW_WORKSPACE || path.join(home, '.openclaw', 'workspace');
248
+ if (!fs.existsSync(workspaceDir)) {
249
+ fatal(`Workspace not found: ${workspaceDir}. Set OPENCLAW_WORKSPACE or run from workspace root.`);
250
+ }
251
+ const skillDir = path.join(workspaceDir, 'skills', 'sentinel-guard');
252
+ const scriptsDir = path.join(skillDir, 'scripts');
253
+ if (fs.existsSync(skillDir)) {
254
+ console.log('⚠ Sentinel Guard skill already installed at:');
255
+ console.log(' ' + skillDir);
256
+ console.log('\nRun sentinel-agentos status to check current state.');
257
+ return;
258
+ }
259
+ // Create skill directory
260
+ fs.mkdirSync(skillDir, { recursive: true });
261
+ fs.mkdirSync(scriptsDir, { recursive: true });
262
+ // Source light guard from dist/scripts
263
+ const guardSrc = path.join(__dirname, '..', 'scripts', 'sentinel-light.js');
264
+ let guardContent;
265
+ if (fs.existsSync(guardSrc)) {
266
+ guardContent = fs.readFileSync(guardSrc, 'utf-8');
267
+ }
268
+ else {
269
+ // Fallback: use the one from src (dev mode)
270
+ const fallback = path.join(__dirname, '..', '..', 'scripts', 'sentinel-light.js');
271
+ if (fs.existsSync(fallback)) {
272
+ guardContent = fs.readFileSync(fallback, 'utf-8');
273
+ }
274
+ else {
275
+ fatal('Guard script not found. Reinstall sentinel-agentos.');
276
+ }
277
+ }
278
+ // Write guard script
279
+ fs.writeFileSync(path.join(skillDir, 'sentinel-guard.js'), guardContent);
280
+ // Write SKILL.md
281
+ const skillMd = `---
282
+ name: sentinel-guard
283
+ description: "Sentinel AgentOS Guard — 确定性代码审查守卫,拦截危险命令和敏感文件操作。"
284
+ ---
285
+
286
+ # Sentinel AgentOS Guard
287
+
288
+ 拦截危险操作和敏感文件修改,基于确定性规则而非 LLM。
289
+
290
+ ## 使用
291
+
292
+ \`\`\`javascript
293
+ const guard = require('./sentinel-guard');
294
+ const check = guard.preCheck('exec', { command: 'rm -rf /' });
295
+ if (!check.passed) return { blocked: true, reason: check.reason };
296
+ \`\`\`
297
+
298
+ ## 三层防护
299
+
300
+ - 🛡️ 命令黑名单:rm -rf /、sudo rm、mkfs、fork bomb 等
301
+ - 🔒 Schema Gate:拦截 .env、*.key、*.pem 等敏感文件
302
+ - ⚠️ Risk Gate:git push --force、npm publish 需确认
303
+
304
+ ## 快速测试
305
+
306
+ \`\`\`bash
307
+ node scripts/test-suite.js
308
+ \`\`\`
309
+ `;
310
+ fs.writeFileSync(path.join(skillDir, 'SKILL.md'), skillMd);
311
+ // Write test suite
312
+ const testContent = `#!/usr/bin/env node
313
+ const guard = require('../sentinel-guard');
314
+ ['exec rm -rf /', 'write .env', 'exec npm test'].forEach(t => {
315
+ const s = t.split(' ');
316
+ const r = guard.preCheck(s[0], s[0] === 'exec' ? {command: s.slice(1).join(' ')} : {path: s[1], content:'x'});
317
+ console.log(r.block ? '🚫 ' + r.reason : '✅ ' + t);
318
+ });
319
+ `;
320
+ fs.writeFileSync(path.join(scriptsDir, 'test-suite.js'), testContent);
321
+ // Add .sentinel-audit to .gitignore if exists
322
+ const gitignore = path.join(workspaceDir, '.gitignore');
323
+ if (fs.existsSync(gitignore)) {
324
+ const giContent = fs.readFileSync(gitignore, 'utf-8');
325
+ if (!giContent.includes('.sentinel-audit')) {
326
+ fs.appendFileSync(gitignore, '\n# Sentinel AgentOS audit logs\n.sentinel-audit/\n');
327
+ }
328
+ }
329
+ console.log('✅ Sentinel AgentOS Guard 安装完成!\n');
330
+ console.log('📂 Skill: ' + skillDir);
331
+ console.log('🛡️ Guard: ' + path.join(skillDir, 'sentinel-guard.js'));
332
+ console.log('');
333
+ console.log('下一步:');
334
+ console.log(' 1. Agent 重启后自动加载 Guard');
335
+ console.log(' 2. 运行 sentinel-agentos status 查看状态');
336
+ console.log(' 3. 或在代码中 require: const guard = require("./sentinel-guard")');
337
+ break;
338
+ }
237
339
  default:
238
340
  fatal(`Unknown command: ${cmd}. Run 'sentinel-agentos help' for usage.`);
239
341
  }
package/dist/cli.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"file":"cli.js","sourceRoot":"","sources":["../src/cli.ts"],"names":[],"mappings":";;AAEA;;;;;;;;;;;;GAYG;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AAEH,iCAAiC;AAEjC,SAAS,SAAS;IAChB,OAAO,CAAC,GAAG,CAAC;;;;;;;;;;;;;;;;;;;;;CAqBb,CAAC,CAAC;AACH,CAAC;AAED,SAAS,KAAK,CAAC,GAAW;IACxB,OAAO,CAAC,KAAK,CAAC,KAAK,GAAG,EAAE,CAAC,CAAC;IAC1B,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;AAClB,CAAC;AAED;;;GAGG;AACH,SAAS,WAAW,CAAC,IAAc;IACjC,MAAM,MAAM,GAA4B,EAAE,CAAC;IAE3C,KAAK,MAAM,GAAG,IAAI,IAAI,EAAE,CAAC;QACvB,MAAM,KAAK,GAAG,GAAG,CAAC,OAAO,CAAC,GAAG,CAAC,CAAC;QAC/B,IAAI,KAAK,KAAK,CAAC,CAAC;YAAE,SAAS;QAE3B,MAAM,GAAG,GAAG,GAAG,CAAC,KAAK,CAAC,CAAC,EAAE,KAAK,CAAC,CAAC;QAChC,IAAI,GAAG,GAAG,GAAG,CAAC,KAAK,CAAC,KAAK,GAAG,CAAC,CAAC,CAAC;QAE/B,0BAA0B;QAC1B,IAAI,CAAC,GAAG,CAAC,UAAU,CAAC,GAAG,CAAC,IAAI,GAAG,CAAC,QAAQ,CAAC,GAAG,CAAC,CAAC;YAC1C,CAAC,GAAG,CAAC,UAAU,CAAC,GAAG,CAAC,IAAI,GAAG,CAAC,QAAQ,CAAC,GAAG,CAAC,CAAC,EAAE,CAAC;YAC/C,GAAG,GAAG,GAAG,CAAC,KAAK,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC;QACzB,CAAC;QAED,mBAAmB;QACnB,IAAI,GAAG,KAAK,MAAM;YAAE,MAAM,CAAC,GAAG,CAAC,GAAG,IAAI,CAAC;aAClC,IAAI,GAAG,KAAK,OAAO;YAAE,MAAM,CAAC,GAAG,CAAC,GAAG,KAAK,CAAC;aACzC,IAAI,GAAG,KAAK,MAAM;YAAE,MAAM,CAAC,GAAG,CAAC,GAAG,IAAI,CAAC;aACvC,IAAI,OAAO,CAAC,IAAI,CAAC,GAAG,CAAC;YAAE,MAAM,CAAC,GAAG,CAAC,GAAG,QAAQ,CAAC,GAAG,EAAE,EAAE,CAAC,CAAC;aACvD,IAAI,YAAY,CAAC,IAAI,CAAC,GAAG,CAAC;YAAE,MAAM,CAAC,GAAG,CAAC,GAAG,UAAU,CAAC,GAAG,CAAC,CAAC;;YAC1D,MAAM,CAAC,GAAG,CAAC,GAAG,GAAG,CAAC;IACzB,CAAC;IAED,OAAO,MAAM,CAAC;AAChB,CAAC;AAED;;;GAGG;AACH,SAAS,UAAU,CAAC,IAAc;IAChC,MAAM,MAAM,GAA2B,EAAE,CAAC;IAC1C,KAAK,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,IAAI,CAAC,MAAM,EAAE,CAAC,EAAE,EAAE,CAAC;QACrC,MAAM,GAAG,GAAG,IAAI,CAAC,CAAC,CAAC,CAAC;QACpB,IAAI,GAAG,IAAI,GAAG,CAAC,UAAU,CAAC,IAAI,CAAC,EAAE,CAAC;YAChC,MAAM,GAAG,GAAG,GAAG,CAAC,OAAO,CAAC,KAAK,EAAE,EAAE,CAAC,CAAC;YACnC,MAAM,IAAI,GAAG,IAAI,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC;YACzB,+CAA+C;YAC/C,IAAI,IAAI,IAAI,CAAC,IAAI,CAAC,UAAU,CAAC,IAAI,CAAC,IAAI,CAAC,IAAI,CAAC,QAAQ,CAAC,GAAG,CAAC,EAAE,CAAC;gBAC1D,MAAM,CAAC,GAAG,CAAC,GAAG,IAAI,CAAC;gBACnB,CAAC,EAAE,CAAC;YACN,CAAC;iBAAM,CAAC;gBACN,MAAM,CAAC,GAAG,CAAC,GAAG,MAAM,CAAC;YACvB,CAAC;QACH,CAAC;IACH,CAAC;IACD,OAAO,MAAM,CAAC;AAChB,CAAC;AAED,KAAK,UAAU,IAAI;IACjB,MAAM,OAAO,GAAG,OAAO,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC;IACtC,MAAM,GAAG,GAAG,OAAO,CAAC,CAAC,CAAC,IAAI,EAAE,CAAC;IAE7B,IAAI,CAAC,GAAG,IAAI,GAAG,KAAK,MAAM,EAAE,CAAC;QAC3B,SAAS,EAAE,CAAC;QACZ,OAAO;IACT,CAAC;IAED,MAAM,GAAG,GAAG,IAAI,cAAO,EAAE,CAAC;IAE1B,QAAQ,GAAG,EAAE,CAAC;QACZ,KAAK,UAAU,CAAC;QAChB,KAAK,MAAM,CAAC,CAAC,CAAC;YACZ,8DAA8D;YAC9D,0DAA0D;YAC1D,MAAM,KAAK,GAAG,UAAU,CAAC,OAAO,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,CAAC;YAC3C,IAAI,IAAY,CAAC;YACjB,IAAI,MAA+B,CAAC;YAEpC,wBAAwB;YACxB,MAAM,UAAU,GAAG,OAAO,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,UAAU,CAAC,IAAI,CAAC,CAAC,CAAC;YACrE,MAAM,QAAQ,GAAG,UAAU,CAAC,CAAC,CAAC,CAAC;YAC/B,MAAM,WAAW,GAAG,UAAU,CAAC,MAAM,GAAG,CAAC,IAAI,QAAQ,KAAK,SAAS,IAAI,CAAC,QAAQ,CAAC,QAAQ,CAAC,GAAG,CAAC,CAAC;YAE/F,IAAI,WAAW,IAAI,UAAU,CAAC,CAAC,CAAC,EAAE,CAAC;gBACjC,IAAI,GAAG,UAAU,CAAC,CAAC,CAAC,CAAC;gBACrB,MAAM,GAAG,WAAW,CAAC,UAAU,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,CAAC;YAC5C,CAAC;iBAAM,IAAI,WAAW,EAAE,CAAC;gBACvB,KAAK,CAAC,2BAA2B,GAAG,wBAAwB,CAAC,CAAC;YAChE,CAAC;iBAAM,CAAC;gBACN,+BAA+B;gBAC/B,MAAM,QAAQ,GAAG,KAAK,CAAC,IAAI,IAAI,OAAO,CAAC,CAAC,CAAC,CAAC;gBAC1C,IAAI,GAAG,QAAQ,IAAI,EAAE,CAAC;gBACtB,IAAI,CAAC,IAAI;oBAAE,KAAK,CAAC,2BAA2B,GAAG,wBAAwB,CAAC,CAAC;gBACzE,MAAM,UAAU,GAAG,KAAK,CAAC,MAAM,IAAI,IAAI,CAAC;gBACxC,IAAI,CAAC;oBAAC,MAAM,GAAG,IAAI,CAAC,KAAK,CAAC,UAAU,CAAC,CAAC;gBAAC,CAAC;gBAAC,MAAM,CAAC;oBAAC,MAAM,GAAG,WAAW,CAAC,OAAO,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,CAAC;gBAAC,CAAC;YAC5F,CAAC;YAED,MAAM,MAAM,GAAG,GAAG,CAAC,eAAe,CAAC;gBACjC,SAAS,EAAE,KAAK;gBAChB,OAAO,EAAE,KAAK;gBACd,QAAQ,EAAE,IAAI;gBACd,UAAU,EAAE,MAAM;aACnB,CAAC,CAAC;YAEH,IAAI,GAAG,KAAK,UAAU,EAAE,CAAC;gBACvB,OAAO,CAAC,GAAG,CAAC,IAAI,CAAC,SAAS,CAAC,MAAM,CAAC,OAAO,CAAC,WAAW,EAAE,IAAI,EAAE,CAAC,CAAC,CAAC,CAAC;YACnE,CAAC;iBAAM,CAAC;gBACN,OAAO,CAAC,GAAG,CAAC,IAAI,CAAC,SAAS,CAAC,MAAM,CAAC,OAAO,CAAC,SAAS,EAAE,IAAI,EAAE,CAAC,CAAC,CAAC,CAAC;YACjE,CAAC;YACD,MAAM;QACR,CAAC;QAED,KAAK,OAAO,CAAC,CAAC,CAAC;YACb,MAAM,KAAK,GAAG,UAAU,CAAC,OAAO,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,CAAC;YAC3C,MAAM,KAAK,GAAG,QAAQ,CAAC,KAAK,CAAC,KAAK,IAAI,IAAI,EAAE,EAAE,CAAC,CAAC;YAChD,MAAM,OAAO,GAAG,GAAG,CAAC,KAAK,CAAC,KAAK,CAAC,KAAK,CAAC,EAAE,KAAK,EAAE,CAAC,CAAC;YACjD,OAAO,CAAC,GAAG,CAAC,IAAI,CAAC,SAAS,CAAC,OAAO,EAAE,IAAI,EAAE,CAAC,CAAC,CAAC,CAAC;YAC9C,MAAM;QACR,CAAC;QAED,KAAK,OAAO,CAAC,CAAC,CAAC;YACb,MAAM,KAAK,GAAG,GAAG,CAAC,aAAa,EAAE,CAAC;YAClC,OAAO,CAAC,GAAG,CAAC,IAAI,CAAC,SAAS,CAAC,KAAK,EAAE,IAAI,EAAE,CAAC,CAAC,CAAC,CAAC;YAC5C,MAAM;QACR,CAAC;QAED,KAAK,SAAS,CAAC,CAAC,CAAC;YACf,MAAM,OAAO,GAAG,GAAG,CAAC,UAAU,EAAE,CAAC;YACjC,OAAO,CAAC,GAAG,CAAC,IAAI,CAAC,SAAS,CAAC,OAAO,EAAE,IAAI,EAAE,CAAC,CAAC,CAAC,CAAC;YAC9C,MAAM;QACR,CAAC;QAED,KAAK,QAAQ,CAAC,CAAC,CAAC;YACd,OAAO,CAAC,GAAG,CAAC,GAAG,CAAC,YAAY,EAAE,CAAC,CAAC;YAChC,MAAM;QACR,CAAC;QAED,KAAK,QAAQ,CAAC,CAAC,CAAC;YACd,MAAM,KAAK,GAAG,UAAU,CAAC,OAAO,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,CAAC;YAC3C,MAAM,IAAI,GAAG,QAAQ,CAAC,KAAK,CAAC,IAAI,IAAI,MAAM,EAAE,EAAE,CAAC,CAAC;YAChD,MAAM,IAAI,GAAG,KAAK,CAAC,IAAI,IAAI,WAAW,CAAC;YACvC,MAAM,KAAK,GAAG,KAAK,CAAC,KAAK,CAAC;YAE1B,IAAI,CAAC;gBACH,MAAM,EAAE,YAAY,EAAE,GAAG,wDAAa,UAAU,GAAC,CAAC;gBAClD,MAAM,MAAM,GAAG,YAAY,CAAC,EAAE,IAAI,EAAE,IAAI,EAAE,QAAQ,EAAE,KAAK,EAAE,CAAC,CAAC;gBAC7D,MAAM,MAAM,CAAC,KAAK,EAAE,CAAC;gBACrB,OAAO,CAAC,GAAG,CAAC,sBAAsB,CAAC,CAAC;gBAEpC,OAAO,CAAC,EAAE,CAAC,QAAQ,EAAE,KAAK,IAAI,EAAE;oBAC9B,OAAO,CAAC,GAAG,CAAC,oBAAoB,CAAC,CAAC;oBAClC,MAAM,MAAM,CAAC,IAAI,EAAE,CAAC;oBACpB,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;gBAClB,CAAC,CAAC,CAAC;YACL,CAAC;YAAC,OAAO,GAAQ,EAAE,CAAC;gBAClB,KAAK,CAAC,2BAA2B,GAAG,CAAC,OAAO,EAAE,CAAC,CAAC;YAClD,CAAC;YACD,MAAM;QACR,CAAC;QAED,KAAK,QAAQ,CAAC,CAAC,CAAC;YACd,MAAM,OAAO,GAAG,GAAG,CAAC,aAAa,EAAE,CAAC;YACpC,OAAO,CAAC,GAAG,CAAC,OAAO,IAAI,yBAAyB,CAAC,CAAC;YAClD,MAAM;QACR,CAAC;QAED;YACE,KAAK,CAAC,oBAAoB,GAAG,0CAA0C,CAAC,CAAC;IAC7E,CAAC;AACH,CAAC;AAED,IAAI,EAAE,CAAC,KAAK,CAAC,CAAC,GAAG,EAAE,EAAE;IACnB,OAAO,CAAC,KAAK,CAAC,GAAG,EAAE,GAAG,CAAC,OAAO,CAAC,CAAC;IAChC,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;AAClB,CAAC,CAAC,CAAC"}
1
+ {"version":3,"file":"cli.js","sourceRoot":"","sources":["../src/cli.ts"],"names":[],"mappings":"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"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "sentinel-agentos",
3
- "version": "0.1.3",
3
+ "version": "0.2.0",
4
4
  "description": "Sentinel AgentOS — 确定性 Guard 层 + 分层记忆 + 自动评估,让任何 Agent 变得可靠、可审计、可改进",
5
5
  "keywords": [
6
6
  "agent",
@@ -25,6 +25,7 @@
25
25
  },
26
26
  "files": [
27
27
  "dist/",
28
+ "scripts/sentinel-light.js",
28
29
  "README.md",
29
30
  "LICENSE"
30
31
  ],
@@ -49,16 +50,20 @@
49
50
  "@typescript-eslint/parser": "^7.0.0",
50
51
  "eslint": "^8.0.0",
51
52
  "eslint-config-prettier": "^9.0.0",
53
+ "fluent-ffmpeg": "^2.1.3",
52
54
  "jest": "^29.0.0",
53
55
  "prettier": "^3.0.0",
54
56
  "ts-jest": "^29.0.0",
55
- "typescript": "^5.4.0"
57
+ "typescript": "^5.4.0",
58
+ "videoshow": "^0.1.12"
56
59
  },
57
60
  "engines": {
58
61
  "node": ">=18"
59
62
  },
60
63
  "dependencies": {
61
64
  "cors": "^2.8.6",
62
- "express": "^5.2.1"
65
+ "express": "^5.2.1",
66
+ "puppeteer": "^25.1.0",
67
+ "ws": "^8.21.0"
63
68
  }
64
69
  }
@@ -0,0 +1,233 @@
1
+ /**
2
+ * Sentinel AgentOS Full Guard — 全功能版
3
+ *
4
+ * preCheck: 轻量拦截(4.4μs)
5
+ * postCheck: 完整审计 + 三层记忆 + 三阶段评估 + 隐性反馈
6
+ *
7
+ * 模块初始化时自动注入语义记忆上下文到 session。
8
+ */
9
+
10
+ const { AgentOS } = require('sentinel-agentos');
11
+ const fs = require('fs');
12
+ const path = require('path');
13
+
14
+ const AUDIT_DIR = path.join(__dirname, '..', '.sentinel-audit');
15
+
16
+ // 全局单例
17
+ if (!global.__sentinel_aos) {
18
+ const aos = new AgentOS({
19
+ workspaceRoot: process.cwd(),
20
+ maxWorkingTokens: 50000,
21
+ maxEpisodicSizeKb: 500,
22
+ });
23
+
24
+ // 注册全套 Schema 规则
25
+ aos.guard.schema.registerRules([
26
+ { tool: 'exec', required: ['command'] },
27
+ {
28
+ tool: 'write', required: ['path', 'content'],
29
+ pathDeny: { path: ['.env', '*.key', '*.pem', '.git/**', '**/credentials/**'] },
30
+ maxSize: { content: 1048576 }, secrets: ['content'],
31
+ },
32
+ { tool: 'read', required: ['path'], pathDeny: { path: ['.env', '*.key'] } },
33
+ { tool: 'edit', required: ['path'], pathDeny: { path: ['.env', '*.key', '.git/**'] } },
34
+ {
35
+ tool: 'delete', required: ['path'],
36
+ pathDeny: { path: ['.env', '*.key', '*.pem', '.git/**', 'node_modules/**', 'package.json'] },
37
+ },
38
+ ]);
39
+
40
+ // 从磁盘恢复审计
41
+ const auditFile = path.join(AUDIT_DIR, 'audit.jsonl');
42
+ if (fs.existsSync(auditFile)) {
43
+ try {
44
+ fs.readFileSync(auditFile, 'utf-8').trim().split('\n').filter(Boolean).forEach(line => {
45
+ aos.guard.audit.entries.push(JSON.parse(line));
46
+ });
47
+ } catch {}
48
+ }
49
+
50
+ // 注入默认语义记忆
51
+ aos.memory.semantic.setPreference('user-name', '老板');
52
+ aos.memory.semantic.setPreference('language', 'zh-CN');
53
+ aos.memory.semantic.setPreference('direct-communication', true);
54
+ aos.memory.semantic.addFact('老板是中国用户,偏好直接、不说废话');
55
+ aos.memory.semantic.addFact('项目 coderev 是 AI 代码审查 CLI 工具');
56
+ aos.memory.semantic.addFact('项目 sentinel-agentos 是 AI Agent 操作系统');
57
+ aos.memory.semantic.learnRule('高风险操作前必须 preCheck', 'sentinel_init');
58
+ aos.memory.semantic.learnRule('操作完成后必须 postCheck 审计', 'sentinel_init');
59
+ aos.memory.semantic.learnRule('npm publish 前必须确认版本号', 'sentinel_init');
60
+
61
+ // 记录首次启动事件
62
+ aos.memory.episodic.record('milestone',
63
+ 'Sentinel AgentOS 全功能启用:Guard + Memory + Evaluator',
64
+ ['init', 'milestone'], ['sentinel-agentos']);
65
+
66
+ global.__sentinel_aos = aos;
67
+ global.__sentinel_session_id = 1;
68
+ }
69
+
70
+ const aos = global.__sentinel_aos;
71
+ let opCounter = 0;
72
+
73
+ // ── 确定性规则(零 LLM)──
74
+ const DANGEROUS = [
75
+ [/rm\s+-rf\s+\//, 'rm -rf / — 删除整个系统'],
76
+ [/rm\s+-rf\s+~/, 'rm -rf ~ — 删除用户目录'],
77
+ [/sudo\s+rm/, 'sudo rm — 超级用户删除'],
78
+ [/mkfs\./, 'mkfs — 格式化磁盘'],
79
+ [/dd\s+if=/, 'dd — 可能覆盖分区'],
80
+ [/fork\s*bomb|:\(\)/, 'fork bomb — 系统崩溃'],
81
+ [/chmod\s+777\s+-R\s*\//, 'chmod 777 -R / — 权限全开'],
82
+ [/del\s+\/F\s+\/S\s+[A-Z]:\\/, 'del /F /S — 全盘删除'],
83
+ [/>\s*\/dev\/sd[a-z]/, '写入磁盘设备'],
84
+ ];
85
+ const WARNING = [
86
+ [/git\s+push\s+--force/, 'git push --force — 强制覆盖'],
87
+ [/git\s+reset\s+--hard/, 'git reset --hard — 不可逆'],
88
+ [/npm\s+publish\b/, 'npm publish — 发布公共包'],
89
+ [/npm\s+unpublish\b/, 'npm unpublish — 从 npm 删除'],
90
+ [/DROP\s+(TABLE|DATABASE)/i, 'DROP — 删除数据库'],
91
+ [/TRUNCATE\s+(TABLE\s+)?/i, 'TRUNCATE — 清空表'],
92
+ ];
93
+ const SENSITIVE = [
94
+ '.env', '.env.*', '*.key', '*.pem', '*.p12', '*.pfx', '*.jks', '*.keystore',
95
+ '.git/**', '**/credentials/**', '**/secrets/**', '**/SECRETS/**',
96
+ 'package.json', 'package-lock.json', 'yarn.lock', 'pnpm-lock.yaml', 'Cargo.lock',
97
+ ];
98
+ const PROTECTED = [
99
+ 'package.json', 'package-lock.json', 'yarn.lock', 'pnpm-lock.yaml',
100
+ '.gitignore', '.gitattributes', 'Cargo.toml', 'Cargo.lock', 'tsconfig.json',
101
+ 'AGENTS.md', 'SOUL.md', 'MEMORY.md', 'USER.md',
102
+ ];
103
+
104
+ function globMatch(pattern, p) {
105
+ p = (p || '').replace(/\\/g, '/');
106
+ if (!pattern.includes('*')) return p === pattern || p.endsWith('/' + pattern);
107
+ const re = '^' + pattern.replace(/[.+^${}()|[\]\\]/g, '\\$&').replace(/\*\*\//g, '(.*/)?').replace(/\*/g, '[^/]*') + '$';
108
+ return new RegExp(re).test(p);
109
+ }
110
+
111
+ module.exports = {
112
+ // ── 执行前拦截 ──
113
+ preCheck(toolName, params) {
114
+ if (toolName === 'exec' && params.command) {
115
+ const cmd = String(params.command);
116
+ for (const [re, desc] of DANGEROUS) {
117
+ if (re.test(cmd)) return { passed: false, block: true, risk: 'DENY', reason: `🚫 危险命令: ${desc}` };
118
+ }
119
+ for (const [re, desc] of WARNING) {
120
+ if (re.test(cmd)) return { passed: false, block: true, risk: 'CONFIRM', reason: `⚠️ 需要确认: ${desc}`, needsConfirmation: true };
121
+ }
122
+ }
123
+ const p = params.path || params.file;
124
+ if (p && ['write', 'edit', 'delete', 'read'].includes(toolName)) {
125
+ for (const ptn of SENSITIVE) {
126
+ if (globMatch(ptn, p)) return { passed: false, block: true, risk: 'DENY', reason: `🚫 敏感文件: "${p}" → "${ptn}"` };
127
+ }
128
+ }
129
+ if (toolName === 'delete' && p) {
130
+ for (const pf of PROTECTED) {
131
+ if (String(p) === pf || String(p).endsWith('/' + pf) || String(p).endsWith('\\' + pf))
132
+ return { passed: false, block: true, risk: 'DENY', reason: `🚫 保护文件: "${pf}"` };
133
+ }
134
+ }
135
+ return { passed: true, risk: 'auto' };
136
+ },
137
+
138
+ // ── 执行后完整审计 ──
139
+ postCheck(toolName, params, result) {
140
+ const sid = `s${global.__sentinel_session_id}_op${++opCounter}`;
141
+
142
+ // 记录到 Working Memory
143
+ aos.memory.working.addMessage('tool', `${toolName}: ${JSON.stringify(params || {}).slice(0, 200)}`);
144
+
145
+ // AgentOS 完整流水线
146
+ const { preExec, snapshot } = aos.executePipeline({
147
+ sessionId: sid, agentId: 'openclaw', toolName, parameters: params || {},
148
+ });
149
+
150
+ const t = Date.now();
151
+ try {
152
+ const ret = aos.completeExecution({
153
+ sessionId: sid, agentId: 'openclaw', toolName,
154
+ toolParameters: params || {}, toolResult: result ?? null,
155
+ snapshot, startTime: t - 500, endTime: t,
156
+ retryCount: 0, wasSelfCorrected: false, hadTimeout: false,
157
+ userAccepted: true, userProvidedEdit: false, resultWasUsed: true,
158
+ });
159
+
160
+ // 记录情景记忆
161
+ if (toolName === 'exec' && params.command) {
162
+ aos.memory.episodic.record('tool_call', params.command, ['exec'], []);
163
+ }
164
+
165
+ // 持久化审计
166
+ try {
167
+ if (!fs.existsSync(AUDIT_DIR)) fs.mkdirSync(AUDIT_DIR, { recursive: true });
168
+ fs.appendFileSync(path.join(AUDIT_DIR, 'audit.jsonl'),
169
+ JSON.stringify(ret.auditEntry) + '\n');
170
+ } catch {}
171
+
172
+ return {
173
+ auditId: ret.auditEntry.id,
174
+ verify: ret.postExec.verifyPassed ? 'PASS' : 'FAIL',
175
+ risk: ret.runtime.adaptiveScore,
176
+ profile: ret.profile.overallScore,
177
+ };
178
+ } catch (err) {
179
+ // Audit 降级:即使 AgentOS 抛错,也记录轻量审计
180
+ try {
181
+ if (!fs.existsSync(AUDIT_DIR)) fs.mkdirSync(AUDIT_DIR, { recursive: true });
182
+ fs.appendFileSync(path.join(AUDIT_DIR, 'audit.jsonl'),
183
+ JSON.stringify({ ts: new Date().toISOString(), tool: toolName, error: err.message }) + '\n');
184
+ } catch {}
185
+ return { auditId: null, verify: 'ERROR', error: err.message };
186
+ }
187
+ },
188
+
189
+ // ── 查看审计 ──
190
+ audit(limit = 10) {
191
+ return aos.guard.audit.query({ limit });
192
+ },
193
+
194
+ // ── 完整状态报告 ──
195
+ status() {
196
+ return aos.statusReport();
197
+ },
198
+
199
+ // ── 注入 Memory 上下文(session 启动时调用)─
200
+ injectContext() {
201
+ return aos.injectContext();
202
+ },
203
+
204
+ // ── 记录反馈 ──
205
+ feedback(signal) {
206
+ aos.recordFeedback(signal, `s${global.__sentinel_session_id}`);
207
+ },
208
+
209
+ // ── 结束 Session ──
210
+ endSession() {
211
+ const sid = `s${global.__sentinel_session_id}`;
212
+ aos.endSession(sid);
213
+ global.__sentinel_session_id++;
214
+ },
215
+
216
+ // ── 获取完整状态快照 ──
217
+ fullStatus() {
218
+ return {
219
+ sessionId: `s${global.__sentinel_session_id}`,
220
+ opCount: opCounter,
221
+ audit: aos.guard.audit.stats(),
222
+ profile: aos.getProfile(),
223
+ satisfaction: aos.evaluator.feedback.getSatisfactionScore(),
224
+ workingMemory: {
225
+ messages: aos.memory.working.recentMessages.length,
226
+ budget: aos.memory.working.budget,
227
+ },
228
+ episodicEvents: aos.memory.episodic.count,
229
+ semanticRules: aos.memory.semantic.getAllRules().length,
230
+ preferences: aos.memory.semantic.getPreference('language'),
231
+ };
232
+ },
233
+ };