@devflow-tools/mcp-server 0.15.0 → 0.16.1
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 +1 -1
- package/dist/command-registry.json +34 -36
- package/dist/enforcer/constitutional.d.ts +2 -2
- package/dist/enforcer/constitutional.d.ts.map +1 -1
- package/dist/enforcer/constitutional.js +3 -26
- package/dist/enforcer/constitutional.js.map +1 -1
- package/dist/enforcer/index.d.ts +4 -1
- package/dist/enforcer/index.d.ts.map +1 -1
- package/dist/enforcer/index.js +77 -1
- package/dist/enforcer/index.js.map +1 -1
- package/dist/enforcer/rule-engine.d.ts +1 -1
- package/dist/enforcer/rule-engine.d.ts.map +1 -1
- package/dist/enforcer/rule-engine.js +66 -13
- package/dist/enforcer/rule-engine.js.map +1 -1
- package/dist/enforcer/types.d.ts +1 -1
- package/dist/enforcer/types.d.ts.map +1 -1
- package/dist/plugin-guards.d.ts +8 -0
- package/dist/plugin-guards.d.ts.map +1 -0
- package/dist/plugin-guards.js +35 -0
- package/dist/plugin-guards.js.map +1 -0
- package/dist/prompts.d.ts +1 -0
- package/dist/prompts.d.ts.map +1 -1
- package/dist/prompts.js +23 -1
- package/dist/prompts.js.map +1 -1
- package/dist/report-store.d.ts +0 -1
- package/dist/report-store.d.ts.map +1 -1
- package/dist/report-store.js +0 -3
- package/dist/report-store.js.map +1 -1
- package/dist/resources.d.ts +1 -1
- package/dist/resources.d.ts.map +1 -1
- package/dist/resources.js +3 -3
- package/dist/resources.js.map +1 -1
- package/dist/server.d.ts +38 -1
- package/dist/server.d.ts.map +1 -1
- package/dist/server.js +263 -112
- package/dist/server.js.map +1 -1
- package/dist/surface-telemetry.d.ts +3 -0
- package/dist/surface-telemetry.d.ts.map +1 -0
- package/dist/surface-telemetry.js +35 -0
- package/dist/surface-telemetry.js.map +1 -0
- package/dist/tools.d.ts +6 -9
- package/dist/tools.d.ts.map +1 -1
- package/dist/tools.js +225 -99
- package/dist/tools.js.map +1 -1
- package/package.json +9 -8
- package/dist/sampling-client.d.ts +0 -10
- package/dist/sampling-client.d.ts.map +0 -1
- package/dist/sampling-client.js +0 -51
- package/dist/sampling-client.js.map +0 -1
package/README.md
CHANGED
|
@@ -53,7 +53,7 @@ npx @devflow-tools/mcp-server
|
|
|
53
53
|
|------|--------|------|
|
|
54
54
|
| `DEVFLOW_SERVER_URL` | `http://127.0.0.1:13337` | DevFlow 服务端地址 |
|
|
55
55
|
| `DEVFLOW_PROJECT_ROOT` | `cwd` | 项目根目录 |
|
|
56
|
-
| `DEVFLOW_API_KEY` |
|
|
56
|
+
| `DEVFLOW_API_KEY` | 读取生成的本地密钥 | API 认证密钥;未设置时使用 `~/.devflow/keys/local.key` |
|
|
57
57
|
|
|
58
58
|
## Transport
|
|
59
59
|
|
|
@@ -61,14 +61,9 @@
|
|
|
61
61
|
],
|
|
62
62
|
"blockedNative": []
|
|
63
63
|
},
|
|
64
|
-
"devflow:
|
|
64
|
+
"devflow:animation": {
|
|
65
65
|
"mcpTools": [
|
|
66
|
-
"
|
|
67
|
-
"react_new_feature",
|
|
68
|
-
"react_audit_performance",
|
|
69
|
-
"react_review_hooks",
|
|
70
|
-
"react_refactor_component",
|
|
71
|
-
"react_new_component"
|
|
66
|
+
"animation_suggest"
|
|
72
67
|
],
|
|
73
68
|
"blockedNative": [
|
|
74
69
|
"grep",
|
|
@@ -82,11 +77,9 @@
|
|
|
82
77
|
"WebFetch"
|
|
83
78
|
]
|
|
84
79
|
},
|
|
85
|
-
"devflow:
|
|
80
|
+
"devflow:css": {
|
|
86
81
|
"mcpTools": [
|
|
87
|
-
"
|
|
88
|
-
"vue_new_component",
|
|
89
|
-
"vue_debug_reactivity"
|
|
82
|
+
"css_audit_selectors"
|
|
90
83
|
],
|
|
91
84
|
"blockedNative": [
|
|
92
85
|
"grep",
|
|
@@ -100,10 +93,9 @@
|
|
|
100
93
|
"WebFetch"
|
|
101
94
|
]
|
|
102
95
|
},
|
|
103
|
-
"devflow:
|
|
96
|
+
"devflow:docker": {
|
|
104
97
|
"mcpTools": [
|
|
105
|
-
"
|
|
106
|
-
"nest_diagnose_bug"
|
|
98
|
+
"docker_dockerize_project"
|
|
107
99
|
],
|
|
108
100
|
"blockedNative": [
|
|
109
101
|
"grep",
|
|
@@ -117,10 +109,9 @@
|
|
|
117
109
|
"WebFetch"
|
|
118
110
|
]
|
|
119
111
|
},
|
|
120
|
-
"devflow:
|
|
112
|
+
"devflow:electron": {
|
|
121
113
|
"mcpTools": [
|
|
122
|
-
"
|
|
123
|
-
"nextjs_diagnose_bug"
|
|
114
|
+
"electron_diagnose_bug"
|
|
124
115
|
],
|
|
125
116
|
"blockedNative": [
|
|
126
117
|
"grep",
|
|
@@ -134,10 +125,9 @@
|
|
|
134
125
|
"WebFetch"
|
|
135
126
|
]
|
|
136
127
|
},
|
|
137
|
-
"devflow:
|
|
128
|
+
"devflow:git": {
|
|
138
129
|
"mcpTools": [
|
|
139
|
-
"
|
|
140
|
-
"graphql_diagnose_bug"
|
|
130
|
+
"git_analyze_repo"
|
|
141
131
|
],
|
|
142
132
|
"blockedNative": [
|
|
143
133
|
"grep",
|
|
@@ -151,9 +141,9 @@
|
|
|
151
141
|
"WebFetch"
|
|
152
142
|
]
|
|
153
143
|
},
|
|
154
|
-
"devflow:
|
|
144
|
+
"devflow:graphql": {
|
|
155
145
|
"mcpTools": [
|
|
156
|
-
"
|
|
146
|
+
"graphql_diagnose_bug"
|
|
157
147
|
],
|
|
158
148
|
"blockedNative": [
|
|
159
149
|
"grep",
|
|
@@ -167,9 +157,10 @@
|
|
|
167
157
|
"WebFetch"
|
|
168
158
|
]
|
|
169
159
|
},
|
|
170
|
-
"devflow:
|
|
160
|
+
"devflow:nest": {
|
|
171
161
|
"mcpTools": [
|
|
172
|
-
"
|
|
162
|
+
"nest_diagnose_bug",
|
|
163
|
+
"nest_new_module"
|
|
173
164
|
],
|
|
174
165
|
"blockedNative": [
|
|
175
166
|
"grep",
|
|
@@ -183,9 +174,10 @@
|
|
|
183
174
|
"WebFetch"
|
|
184
175
|
]
|
|
185
176
|
},
|
|
186
|
-
"devflow:
|
|
177
|
+
"devflow:nextjs": {
|
|
187
178
|
"mcpTools": [
|
|
188
|
-
"
|
|
179
|
+
"nextjs_diagnose_bug",
|
|
180
|
+
"nextjs_new_page"
|
|
189
181
|
],
|
|
190
182
|
"blockedNative": [
|
|
191
183
|
"grep",
|
|
@@ -215,9 +207,13 @@
|
|
|
215
207
|
"WebFetch"
|
|
216
208
|
]
|
|
217
209
|
},
|
|
218
|
-
"devflow:
|
|
210
|
+
"devflow:react": {
|
|
219
211
|
"mcpTools": [
|
|
220
|
-
"
|
|
212
|
+
"react_review_hooks",
|
|
213
|
+
"react_audit_performance",
|
|
214
|
+
"react_refactor_component",
|
|
215
|
+
"react_diagnose_bug",
|
|
216
|
+
"react_new_component"
|
|
221
217
|
],
|
|
222
218
|
"blockedNative": [
|
|
223
219
|
"grep",
|
|
@@ -231,9 +227,10 @@
|
|
|
231
227
|
"WebFetch"
|
|
232
228
|
]
|
|
233
229
|
},
|
|
234
|
-
"devflow:
|
|
230
|
+
"devflow:tailwind": {
|
|
235
231
|
"mcpTools": [
|
|
236
|
-
"
|
|
232
|
+
"tailwind_new_component",
|
|
233
|
+
"tailwind_optimize_classes"
|
|
237
234
|
],
|
|
238
235
|
"blockedNative": [
|
|
239
236
|
"grep",
|
|
@@ -247,9 +244,9 @@
|
|
|
247
244
|
"WebFetch"
|
|
248
245
|
]
|
|
249
246
|
},
|
|
250
|
-
"devflow:
|
|
247
|
+
"devflow:taro": {
|
|
251
248
|
"mcpTools": [
|
|
252
|
-
"
|
|
249
|
+
"taro_new_page"
|
|
253
250
|
],
|
|
254
251
|
"blockedNative": [
|
|
255
252
|
"grep",
|
|
@@ -263,9 +260,9 @@
|
|
|
263
260
|
"WebFetch"
|
|
264
261
|
]
|
|
265
262
|
},
|
|
266
|
-
"devflow:
|
|
263
|
+
"devflow:ui-layout": {
|
|
267
264
|
"mcpTools": [
|
|
268
|
-
"
|
|
265
|
+
"ui_layout_generate"
|
|
269
266
|
],
|
|
270
267
|
"blockedNative": [
|
|
271
268
|
"grep",
|
|
@@ -279,9 +276,10 @@
|
|
|
279
276
|
"WebFetch"
|
|
280
277
|
]
|
|
281
278
|
},
|
|
282
|
-
"devflow:
|
|
279
|
+
"devflow:vue": {
|
|
283
280
|
"mcpTools": [
|
|
284
|
-
"
|
|
281
|
+
"vue_diagnose_bug",
|
|
282
|
+
"vue_debug_reactivity"
|
|
285
283
|
],
|
|
286
284
|
"blockedNative": [
|
|
287
285
|
"grep",
|
|
@@ -1,3 +1,3 @@
|
|
|
1
|
-
|
|
2
|
-
export declare const CONSTITUTIONAL_RULES: Rule[];
|
|
1
|
+
/** @deprecated Defaults are seeded into SQLite; runtime evaluation reads the database only. */
|
|
2
|
+
export declare const CONSTITUTIONAL_RULES: import("@devflow-tools/sdk").Rule[];
|
|
3
3
|
//# sourceMappingURL=constitutional.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"constitutional.d.ts","sourceRoot":"","sources":["../../src/enforcer/constitutional.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"constitutional.d.ts","sourceRoot":"","sources":["../../src/enforcer/constitutional.ts"],"names":[],"mappings":"AAEA,+FAA+F;AAC/F,eAAO,MAAM,oBAAoB,qCAA2D,CAAC"}
|
|
@@ -1,27 +1,4 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
name: "Session Token 缺失(本地模式降级)",
|
|
5
|
-
level: "constitutional",
|
|
6
|
-
condition: { requireFields: ["_devflow_token"] },
|
|
7
|
-
action: "warn",
|
|
8
|
-
message: "缺少 Session Token。运行在降级模式,部分功能可能受限。",
|
|
9
|
-
},
|
|
10
|
-
{
|
|
11
|
-
id: "C002",
|
|
12
|
-
name: "Token 过期(自动续期)",
|
|
13
|
-
level: "constitutional",
|
|
14
|
-
condition: {},
|
|
15
|
-
action: "warn",
|
|
16
|
-
message: "Session Token 已过期,已自动续期。",
|
|
17
|
-
},
|
|
18
|
-
{
|
|
19
|
-
id: "C003",
|
|
20
|
-
name: "速率限制",
|
|
21
|
-
level: "constitutional",
|
|
22
|
-
condition: { maxCallsPerMinute: 60 },
|
|
23
|
-
action: "warn",
|
|
24
|
-
message: "调用频率过高,请稍后重试。",
|
|
25
|
-
},
|
|
26
|
-
];
|
|
1
|
+
import { DEFAULT_ENFORCER_RULES } from "@devflow-tools/sdk";
|
|
2
|
+
/** @deprecated Defaults are seeded into SQLite; runtime evaluation reads the database only. */
|
|
3
|
+
export const CONSTITUTIONAL_RULES = DEFAULT_ENFORCER_RULES.filter((rule) => rule.gate === 1);
|
|
27
4
|
//# sourceMappingURL=constitutional.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"constitutional.js","sourceRoot":"","sources":["../../src/enforcer/constitutional.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"constitutional.js","sourceRoot":"","sources":["../../src/enforcer/constitutional.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,sBAAsB,EAAE,MAAM,oBAAoB,CAAC;AAE5D,+FAA+F;AAC/F,MAAM,CAAC,MAAM,oBAAoB,GAAG,sBAAsB,CAAC,MAAM,CAAC,CAAC,IAAI,EAAE,EAAE,CAAC,IAAI,CAAC,IAAI,KAAK,CAAC,CAAC,CAAC"}
|
package/dist/enforcer/index.d.ts
CHANGED
|
@@ -1,11 +1,14 @@
|
|
|
1
1
|
import type { MCPContext, EnforceResult } from "./types.js";
|
|
2
|
-
import type
|
|
2
|
+
import { type IDataProvider } from "@devflow-tools/sdk";
|
|
3
3
|
import { issueReceipt } from "./receipt.js";
|
|
4
4
|
export declare function parseJwtPayload(token: string): Record<string, unknown> | null;
|
|
5
5
|
export type { MCPContext, EnforceResult };
|
|
6
6
|
export { verifyAuditChain, rebuildAuditChain, hashArgs } from "./audit-chain.js";
|
|
7
7
|
export { issueReceipt, verifyReceipt, isReceiptExpired } from "./receipt.js";
|
|
8
8
|
export { CONSTITUTIONAL_RULES } from "./constitutional.js";
|
|
9
|
+
export declare function recordEnforcementOutcome(toolName: string, args: Record<string, unknown>, result: unknown): void;
|
|
10
|
+
export declare function recordEnforcementFailure(toolName: string, args: Record<string, unknown>, error: unknown): void;
|
|
11
|
+
export declare function resetEnforcementSession(sessionId?: string): void;
|
|
9
12
|
export declare function enforce(toolName: string, args: Record<string, unknown>, provider: IDataProvider): Promise<{
|
|
10
13
|
result: EnforceResult;
|
|
11
14
|
receipt?: ReturnType<typeof issueReceipt>;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/enforcer/index.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,UAAU,EAAE,aAAa,EAAE,MAAM,YAAY,CAAC;AAC5D,OAAO,KAAK,
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/enforcer/index.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,UAAU,EAAE,aAAa,EAAE,MAAM,YAAY,CAAC;AAC5D,OAAO,EAAsB,KAAK,aAAa,EAAE,MAAM,oBAAoB,CAAC;AAG5E,OAAO,EAAE,YAAY,EAAE,MAAM,cAAc,CAAC;AAE5C,wBAAgB,eAAe,CAAC,KAAK,EAAE,MAAM,GAAG,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,GAAG,IAAI,CAU7E;AAED,YAAY,EAAE,UAAU,EAAE,aAAa,EAAE,CAAC;AAE1C,OAAO,EAAE,gBAAgB,EAAE,iBAAiB,EAAE,QAAQ,EAAE,MAAM,kBAAkB,CAAC;AACjF,OAAO,EAAE,YAAY,EAAE,aAAa,EAAE,gBAAgB,EAAE,MAAM,cAAc,CAAC;AAC7E,OAAO,EAAE,oBAAoB,EAAE,MAAM,qBAAqB,CAAC;AAqD3D,wBAAgB,wBAAwB,CACtC,QAAQ,EAAE,MAAM,EAChB,IAAI,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,EAC7B,MAAM,EAAE,OAAO,GACd,IAAI,CAaN;AAED,wBAAgB,wBAAwB,CACtC,QAAQ,EAAE,MAAM,EAChB,IAAI,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,EAC7B,KAAK,EAAE,OAAO,GACb,IAAI,CAON;AAED,wBAAgB,uBAAuB,CAAC,SAAS,CAAC,EAAE,MAAM,GAAG,IAAI,CAGhE;AAED,wBAAsB,OAAO,CAC3B,QAAQ,EAAE,MAAM,EAChB,IAAI,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,EAC7B,QAAQ,EAAE,aAAa,GACtB,OAAO,CAAC;IAAE,MAAM,EAAE,aAAa,CAAC;IAAC,OAAO,CAAC,EAAE,UAAU,CAAC,OAAO,YAAY,CAAC,CAAA;CAAE,CAAC,CAqE/E"}
|
package/dist/enforcer/index.js
CHANGED
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
import { getLocalHmacSecret } from "@devflow-tools/sdk";
|
|
1
2
|
import { loadRules, evaluateAll } from "./rule-engine.js";
|
|
2
3
|
import { hashArgs, appendAuditEntry } from "./audit-chain.js";
|
|
3
4
|
import { issueReceipt } from "./receipt.js";
|
|
@@ -17,6 +18,77 @@ export function parseJwtPayload(token) {
|
|
|
17
18
|
export { verifyAuditChain, rebuildAuditChain, hashArgs } from "./audit-chain.js";
|
|
18
19
|
export { issueReceipt, verifyReceipt, isReceiptExpired } from "./receipt.js";
|
|
19
20
|
export { CONSTITUTIONAL_RULES } from "./constitutional.js";
|
|
21
|
+
const sessionStates = new Map();
|
|
22
|
+
function getSessionId(args) {
|
|
23
|
+
const token = args._devflow_token;
|
|
24
|
+
if (typeof token?.sub === "string")
|
|
25
|
+
return token.sub;
|
|
26
|
+
const envToken = process.env.DEVFLOW_SESSION_TOKEN;
|
|
27
|
+
const payload = envToken ? parseJwtPayload(envToken) : null;
|
|
28
|
+
return typeof payload?.sub === "string" ? payload.sub : "anon";
|
|
29
|
+
}
|
|
30
|
+
function getSessionState(sessionId) {
|
|
31
|
+
let state = sessionStates.get(sessionId);
|
|
32
|
+
if (!state) {
|
|
33
|
+
state = { priorTools: new Set() };
|
|
34
|
+
sessionStates.set(sessionId, state);
|
|
35
|
+
}
|
|
36
|
+
return state;
|
|
37
|
+
}
|
|
38
|
+
function findContextQuality(value, depth = 0) {
|
|
39
|
+
if (!value || typeof value !== "object" || depth > 6)
|
|
40
|
+
return { warnings: [] };
|
|
41
|
+
if (Array.isArray(value)) {
|
|
42
|
+
const warnings = [];
|
|
43
|
+
let confidence;
|
|
44
|
+
for (const item of value) {
|
|
45
|
+
const nested = findContextQuality(item, depth + 1);
|
|
46
|
+
warnings.push(...nested.warnings);
|
|
47
|
+
if (nested.confidence !== undefined)
|
|
48
|
+
confidence = Math.min(confidence ?? 1, nested.confidence);
|
|
49
|
+
}
|
|
50
|
+
return { warnings, confidence };
|
|
51
|
+
}
|
|
52
|
+
const record = value;
|
|
53
|
+
const warnings = Array.isArray(record.warnings)
|
|
54
|
+
? record.warnings.filter((item) => typeof item === "string")
|
|
55
|
+
: [];
|
|
56
|
+
let confidence = typeof record.confidence === "number" ? record.confidence : undefined;
|
|
57
|
+
for (const nestedValue of Object.values(record)) {
|
|
58
|
+
const nested = findContextQuality(nestedValue, depth + 1);
|
|
59
|
+
warnings.push(...nested.warnings);
|
|
60
|
+
if (nested.confidence !== undefined)
|
|
61
|
+
confidence = Math.min(confidence ?? 1, nested.confidence);
|
|
62
|
+
}
|
|
63
|
+
return { warnings: [...new Set(warnings)], confidence };
|
|
64
|
+
}
|
|
65
|
+
export function recordEnforcementOutcome(toolName, args, result) {
|
|
66
|
+
const state = getSessionState(getSessionId(args));
|
|
67
|
+
state.priorTools.add(toolName);
|
|
68
|
+
if (toolName === "get_project_context") {
|
|
69
|
+
const quality = findContextQuality(result);
|
|
70
|
+
state.contextWarning = quality.warnings[0]
|
|
71
|
+
?? (quality.confidence !== undefined && quality.confidence < 0.5
|
|
72
|
+
? `context-confidence-${quality.confidence}`
|
|
73
|
+
: undefined);
|
|
74
|
+
}
|
|
75
|
+
if (state.previousFailure)
|
|
76
|
+
delete state.previousFailure;
|
|
77
|
+
}
|
|
78
|
+
export function recordEnforcementFailure(toolName, args, error) {
|
|
79
|
+
const state = getSessionState(getSessionId(args));
|
|
80
|
+
state.previousFailure = {
|
|
81
|
+
toolName,
|
|
82
|
+
message: error instanceof Error ? error.message : String(error),
|
|
83
|
+
timestamp: Date.now(),
|
|
84
|
+
};
|
|
85
|
+
}
|
|
86
|
+
export function resetEnforcementSession(sessionId) {
|
|
87
|
+
if (sessionId)
|
|
88
|
+
sessionStates.delete(sessionId);
|
|
89
|
+
else
|
|
90
|
+
sessionStates.clear();
|
|
91
|
+
}
|
|
20
92
|
export async function enforce(toolName, args, provider) {
|
|
21
93
|
// Dual-path token injection: args first, env fallback
|
|
22
94
|
if (!args._devflow_token) {
|
|
@@ -29,11 +101,15 @@ export async function enforce(toolName, args, provider) {
|
|
|
29
101
|
}
|
|
30
102
|
}
|
|
31
103
|
const sessionId = args._devflow_token?.sub ?? "anon";
|
|
104
|
+
const state = getSessionState(sessionId);
|
|
32
105
|
const ctx = {
|
|
33
106
|
toolName,
|
|
34
107
|
args,
|
|
35
108
|
sessionId,
|
|
36
109
|
tokenPayload: args._devflow_token,
|
|
110
|
+
priorTools: [...state.priorTools],
|
|
111
|
+
contextWarning: state.contextWarning,
|
|
112
|
+
previousFailure: state.previousFailure,
|
|
37
113
|
};
|
|
38
114
|
// C002: Check token expiry — auto-refresh instead of deny
|
|
39
115
|
if (ctx.tokenPayload) {
|
|
@@ -49,7 +125,7 @@ export async function enforce(toolName, args, provider) {
|
|
|
49
125
|
scope: ctx.tokenPayload.scope || ["context", "knowledge", "memory", "workflow", "graph"],
|
|
50
126
|
};
|
|
51
127
|
const payloadB64 = Buffer.from(JSON.stringify(newPayload)).toString("base64url");
|
|
52
|
-
const signature = crypto.createHmac("sha256",
|
|
128
|
+
const signature = crypto.createHmac("sha256", getLocalHmacSecret())
|
|
53
129
|
.update(`${hdr}.${payloadB64}`)
|
|
54
130
|
.digest("base64url");
|
|
55
131
|
process.env.DEVFLOW_SESSION_TOKEN = `${hdr}.${payloadB64}.${signature}`;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/enforcer/index.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/enforcer/index.ts"],"names":[],"mappings":"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"}
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import type { Rule, Decision, MCPContext } from "./types.js";
|
|
2
|
-
import type
|
|
2
|
+
import { type IDataProvider } from "@devflow-tools/sdk";
|
|
3
3
|
export declare function loadRules(provider: IDataProvider): Promise<Rule[]>;
|
|
4
4
|
export declare function evaluateRule(rule: Rule, ctx: MCPContext): Decision;
|
|
5
5
|
export declare function evaluateAll(rules: Rule[], ctx: MCPContext): {
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"rule-engine.d.ts","sourceRoot":"","sources":["../../src/enforcer/rule-engine.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,IAAI,EAAiB,QAAQ,EAAE,UAAU,EAAE,MAAM,YAAY,CAAC;AAC5E,OAAO,KAAK,
|
|
1
|
+
{"version":3,"file":"rule-engine.d.ts","sourceRoot":"","sources":["../../src/enforcer/rule-engine.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,IAAI,EAAiB,QAAQ,EAAE,UAAU,EAAE,MAAM,YAAY,CAAC;AAC5E,OAAO,EAA4B,KAAK,aAAa,EAAE,MAAM,oBAAoB,CAAC;AAIlF,wBAAsB,SAAS,CAAC,QAAQ,EAAE,aAAa,GAAG,OAAO,CAAC,IAAI,EAAE,CAAC,CAGxE;AA8BD,wBAAgB,YAAY,CAAC,IAAI,EAAE,IAAI,EAAE,GAAG,EAAE,UAAU,GAAG,QAAQ,CAuElE;AAED,wBAAgB,WAAW,CAAC,KAAK,EAAE,IAAI,EAAE,EAAE,GAAG,EAAE,UAAU,GAAG;IAAE,QAAQ,EAAE,QAAQ,CAAC;IAAC,IAAI,CAAC,EAAE,IAAI,CAAA;CAAE,CAa/F"}
|
|
@@ -1,27 +1,59 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import { seedDefaultEnforcerRules } from "@devflow-tools/sdk";
|
|
2
2
|
const rateCounters = new Map();
|
|
3
3
|
export async function loadRules(provider) {
|
|
4
|
-
|
|
5
|
-
return
|
|
4
|
+
await seedDefaultEnforcerRules(provider);
|
|
5
|
+
return provider.ruleGetAll();
|
|
6
|
+
}
|
|
7
|
+
function getPath(value, path) {
|
|
8
|
+
return path.split(".").reduce((current, key) => {
|
|
9
|
+
if (!current || typeof current !== "object")
|
|
10
|
+
return undefined;
|
|
11
|
+
return current[key];
|
|
12
|
+
}, value);
|
|
13
|
+
}
|
|
14
|
+
function collectScalarValues(value, result = [], depth = 0) {
|
|
15
|
+
if (depth > 8)
|
|
16
|
+
return result;
|
|
17
|
+
if (Array.isArray(value)) {
|
|
18
|
+
for (const entry of value)
|
|
19
|
+
collectScalarValues(entry, result, depth + 1);
|
|
20
|
+
}
|
|
21
|
+
else if (value && typeof value === "object") {
|
|
22
|
+
for (const entry of Object.values(value)) {
|
|
23
|
+
collectScalarValues(entry, result, depth + 1);
|
|
24
|
+
}
|
|
25
|
+
}
|
|
26
|
+
else {
|
|
27
|
+
result.push(value);
|
|
28
|
+
}
|
|
29
|
+
return result;
|
|
30
|
+
}
|
|
31
|
+
function matchesTool(rule, toolName) {
|
|
32
|
+
const { tools, toolPatterns } = rule.condition;
|
|
33
|
+
if (tools && !tools.includes("*") && !tools.includes(toolName))
|
|
34
|
+
return false;
|
|
35
|
+
if (toolPatterns && !toolPatterns.some((pattern) => new RegExp(pattern, "i").test(toolName)))
|
|
36
|
+
return false;
|
|
37
|
+
return true;
|
|
6
38
|
}
|
|
7
39
|
export function evaluateRule(rule, ctx) {
|
|
8
40
|
const cond = rule.condition;
|
|
41
|
+
const hasActivationCondition = Object.keys(cond).some((key) => key !== "tools" && key !== "toolPatterns");
|
|
9
42
|
// Tool filter
|
|
10
|
-
if (
|
|
43
|
+
if (!rule.enabled || !matchesTool(rule, ctx.toolName))
|
|
11
44
|
return "allow";
|
|
12
|
-
}
|
|
13
45
|
// Required fields check
|
|
14
46
|
if (cond.requireFields) {
|
|
15
47
|
for (const field of cond.requireFields) {
|
|
16
|
-
if (
|
|
48
|
+
if (getPath(ctx.args, field) === undefined)
|
|
17
49
|
return rule.action;
|
|
18
50
|
}
|
|
19
51
|
}
|
|
20
52
|
// Forbidden patterns check
|
|
21
53
|
if (cond.forbidPatterns) {
|
|
22
54
|
for (const pattern of cond.forbidPatterns) {
|
|
23
|
-
for (const val of
|
|
24
|
-
if (typeof val === "string" && new RegExp(pattern).test(val)) {
|
|
55
|
+
for (const val of collectScalarValues(ctx.args)) {
|
|
56
|
+
if (typeof val === "string" && new RegExp(pattern, "i").test(val)) {
|
|
25
57
|
return rule.action;
|
|
26
58
|
}
|
|
27
59
|
}
|
|
@@ -30,11 +62,33 @@ export function evaluateRule(rule, ctx) {
|
|
|
30
62
|
// Param pattern check
|
|
31
63
|
if (cond.paramPatterns) {
|
|
32
64
|
for (const [key, pattern] of Object.entries(cond.paramPatterns)) {
|
|
33
|
-
const val = String(ctx.args
|
|
34
|
-
if (new RegExp(pattern).test(val))
|
|
65
|
+
const val = String(getPath(ctx.args, key) ?? "");
|
|
66
|
+
if (new RegExp(pattern, "i").test(val))
|
|
35
67
|
return rule.action;
|
|
36
68
|
}
|
|
37
69
|
}
|
|
70
|
+
if (cond.maxNumericFields) {
|
|
71
|
+
for (const [key, maximum] of Object.entries(cond.maxNumericFields)) {
|
|
72
|
+
const value = Number(getPath(ctx.args, key));
|
|
73
|
+
if (Number.isFinite(value) && value > maximum)
|
|
74
|
+
return rule.action;
|
|
75
|
+
}
|
|
76
|
+
}
|
|
77
|
+
if (cond.requirePriorTools) {
|
|
78
|
+
const prior = new Set(ctx.priorTools ?? []);
|
|
79
|
+
if (cond.requirePriorTools.some((tool) => !prior.has(tool)))
|
|
80
|
+
return rule.action;
|
|
81
|
+
}
|
|
82
|
+
if (cond.requiresContextWarning) {
|
|
83
|
+
if (ctx.contextWarning)
|
|
84
|
+
return rule.action;
|
|
85
|
+
return "allow";
|
|
86
|
+
}
|
|
87
|
+
if (cond.requiresPreviousFailure) {
|
|
88
|
+
if (ctx.previousFailure)
|
|
89
|
+
return rule.action;
|
|
90
|
+
return "allow";
|
|
91
|
+
}
|
|
38
92
|
// Rate limit check
|
|
39
93
|
if (cond.maxCallsPerMinute) {
|
|
40
94
|
const key = `${ctx.toolName}:${ctx.sessionId ?? "anon"}`;
|
|
@@ -48,13 +102,12 @@ export function evaluateRule(rule, ctx) {
|
|
|
48
102
|
if (entry.count > cond.maxCallsPerMinute)
|
|
49
103
|
return rule.action;
|
|
50
104
|
}
|
|
51
|
-
return "allow";
|
|
105
|
+
return hasActivationCondition ? "allow" : rule.action;
|
|
52
106
|
}
|
|
53
107
|
export function evaluateAll(rules, ctx) {
|
|
54
|
-
// Constitutional rules first (sorted by level priority)
|
|
55
108
|
const sorted = [...rules].sort((a, b) => {
|
|
56
109
|
const order = { constitutional: 0, project: 1, session: 2 };
|
|
57
|
-
return order[a.level] - order[b.level];
|
|
110
|
+
return a.gate - b.gate || order[a.level] - order[b.level] || a.id.localeCompare(b.id);
|
|
58
111
|
});
|
|
59
112
|
for (const rule of sorted) {
|
|
60
113
|
const decision = evaluateRule(rule, ctx);
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"rule-engine.js","sourceRoot":"","sources":["../../src/enforcer/rule-engine.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"rule-engine.js","sourceRoot":"","sources":["../../src/enforcer/rule-engine.ts"],"names":[],"mappings":"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"}
|
package/dist/enforcer/types.d.ts
CHANGED
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
export type { Rule, RuleCondition, Decision, EnforceResult, MCPContext,
|
|
1
|
+
export type { Rule, RuleCondition, Decision, EnforceResult, MCPContext, Receipt, } from "@devflow-tools/sdk";
|
|
2
2
|
//# sourceMappingURL=types.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../../src/enforcer/types.ts"],"names":[],"mappings":"AAAA,YAAY,EACV,IAAI,EACJ,aAAa,EACb,QAAQ,EACR,aAAa,EACb,UAAU,EACV,
|
|
1
|
+
{"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../../src/enforcer/types.ts"],"names":[],"mappings":"AAAA,YAAY,EACV,IAAI,EACJ,aAAa,EACb,QAAQ,EACR,aAAa,EACb,UAAU,EACV,OAAO,GACR,MAAM,oBAAoB,CAAC"}
|
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
export declare function canonicalizeProjectRoot(projectRoot: string): string;
|
|
2
|
+
export declare function requireProjectRoot<T extends Record<string, unknown>>(args: T, boundProjectRoot?: string): asserts args is T & {
|
|
3
|
+
projectRoot: string;
|
|
4
|
+
};
|
|
5
|
+
export declare function wrapHandlerRequireRoot<A extends Record<string, unknown>, R>(handler: (args: A & {
|
|
6
|
+
projectRoot: string;
|
|
7
|
+
}) => Promise<R>, boundProjectRoot: string): (args: A) => Promise<R>;
|
|
8
|
+
//# sourceMappingURL=plugin-guards.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"plugin-guards.d.ts","sourceRoot":"","sources":["../src/plugin-guards.ts"],"names":[],"mappings":"AAGA,wBAAgB,uBAAuB,CAAC,WAAW,EAAE,MAAM,GAAG,MAAM,CAOnE;AAED,wBAAgB,kBAAkB,CAAC,CAAC,SAAS,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,EAClE,IAAI,EAAE,CAAC,EACP,gBAAgB,CAAC,EAAE,MAAM,GACxB,OAAO,CAAC,IAAI,IAAI,CAAC,GAAG;IAAE,WAAW,EAAE,MAAM,CAAA;CAAE,CAe7C;AAED,wBAAgB,sBAAsB,CAAC,CAAC,SAAS,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,EAAE,CAAC,EACzE,OAAO,EAAE,CAAC,IAAI,EAAE,CAAC,GAAG;IAAE,WAAW,EAAE,MAAM,CAAA;CAAE,KAAK,OAAO,CAAC,CAAC,CAAC,EAC1D,gBAAgB,EAAE,MAAM,GACvB,CAAC,IAAI,EAAE,CAAC,KAAK,OAAO,CAAC,CAAC,CAAC,CAWzB"}
|
|
@@ -0,0 +1,35 @@
|
|
|
1
|
+
import { realpathSync } from "node:fs";
|
|
2
|
+
import { resolve } from "node:path";
|
|
3
|
+
export function canonicalizeProjectRoot(projectRoot) {
|
|
4
|
+
const absoluteRoot = resolve(projectRoot);
|
|
5
|
+
try {
|
|
6
|
+
return realpathSync.native(absoluteRoot);
|
|
7
|
+
}
|
|
8
|
+
catch {
|
|
9
|
+
return absoluteRoot;
|
|
10
|
+
}
|
|
11
|
+
}
|
|
12
|
+
export function requireProjectRoot(args, boundProjectRoot) {
|
|
13
|
+
if (typeof args.projectRoot !== "string" || args.projectRoot.trim().length === 0) {
|
|
14
|
+
throw new Error("projectRoot is required; refusing to fall back to cwd. " +
|
|
15
|
+
"Pass CLAUDE_PROJECT_DIR as projectRoot.");
|
|
16
|
+
}
|
|
17
|
+
const canonicalRoot = canonicalizeProjectRoot(args.projectRoot);
|
|
18
|
+
if (boundProjectRoot !== undefined && canonicalRoot !== boundProjectRoot) {
|
|
19
|
+
throw new Error(`projectRoot ${canonicalRoot} does not match this MCP server's projectRoot ${boundProjectRoot}.`);
|
|
20
|
+
}
|
|
21
|
+
args.projectRoot = boundProjectRoot ?? canonicalRoot;
|
|
22
|
+
}
|
|
23
|
+
export function wrapHandlerRequireRoot(handler, boundProjectRoot) {
|
|
24
|
+
const canonicalBoundRoot = typeof boundProjectRoot === "string"
|
|
25
|
+
? canonicalizeProjectRoot(boundProjectRoot)
|
|
26
|
+
: undefined;
|
|
27
|
+
return async (args) => {
|
|
28
|
+
if (canonicalBoundRoot === undefined) {
|
|
29
|
+
throw new Error("bound projectRoot is required for guarded tool handlers.");
|
|
30
|
+
}
|
|
31
|
+
requireProjectRoot(args, canonicalBoundRoot);
|
|
32
|
+
return handler(args);
|
|
33
|
+
};
|
|
34
|
+
}
|
|
35
|
+
//# sourceMappingURL=plugin-guards.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"plugin-guards.js","sourceRoot":"","sources":["../src/plugin-guards.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,YAAY,EAAE,MAAM,SAAS,CAAC;AACvC,OAAO,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AAEpC,MAAM,UAAU,uBAAuB,CAAC,WAAmB;IACzD,MAAM,YAAY,GAAG,OAAO,CAAC,WAAW,CAAC,CAAC;IAC1C,IAAI,CAAC;QACH,OAAO,YAAY,CAAC,MAAM,CAAC,YAAY,CAAC,CAAC;IAC3C,CAAC;IAAC,MAAM,CAAC;QACP,OAAO,YAAY,CAAC;IACtB,CAAC;AACH,CAAC;AAED,MAAM,UAAU,kBAAkB,CAChC,IAAO,EACP,gBAAyB;IAEzB,IAAI,OAAO,IAAI,CAAC,WAAW,KAAK,QAAQ,IAAI,IAAI,CAAC,WAAW,CAAC,IAAI,EAAE,CAAC,MAAM,KAAK,CAAC,EAAE,CAAC;QACjF,MAAM,IAAI,KAAK,CACb,yDAAyD;YACzD,yCAAyC,CAC1C,CAAC;IACJ,CAAC;IAED,MAAM,aAAa,GAAG,uBAAuB,CAAC,IAAI,CAAC,WAAW,CAAC,CAAC;IAChE,IAAI,gBAAgB,KAAK,SAAS,IAAI,aAAa,KAAK,gBAAgB,EAAE,CAAC;QACzE,MAAM,IAAI,KAAK,CACb,eAAe,aAAa,iDAAiD,gBAAgB,GAAG,CACjG,CAAC;IACJ,CAAC;IACA,IAAoC,CAAC,WAAW,GAAG,gBAAgB,IAAI,aAAa,CAAC;AACxF,CAAC;AAED,MAAM,UAAU,sBAAsB,CACpC,OAA0D,EAC1D,gBAAwB;IAExB,MAAM,kBAAkB,GAAG,OAAO,gBAAgB,KAAK,QAAQ;QAC7D,CAAC,CAAC,uBAAuB,CAAC,gBAAgB,CAAC;QAC3C,CAAC,CAAC,SAAS,CAAC;IACd,OAAO,KAAK,EAAE,IAAO,EAAE,EAAE;QACvB,IAAI,kBAAkB,KAAK,SAAS,EAAE,CAAC;YACrC,MAAM,IAAI,KAAK,CAAC,0DAA0D,CAAC,CAAC;QAC9E,CAAC;QACD,kBAAkB,CAAC,IAAI,EAAE,kBAAkB,CAAC,CAAC;QAC7C,OAAO,OAAO,CAAC,IAAI,CAAC,CAAC;IACvB,CAAC,CAAC;AACJ,CAAC"}
|
package/dist/prompts.d.ts
CHANGED
package/dist/prompts.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"prompts.d.ts","sourceRoot":"","sources":["../src/prompts.ts"],"names":[],"mappings":"AAAA,eAAO,MAAM,gBAAgB,EAAE,MAAM,CAAC,MAAM,EAAE;IAC5C,IAAI,EAAE,MAAM,CAAC;IACb,WAAW,EAAE,MAAM,CAAC;IACpB,SAAS,EAAE,KAAK,CAAC;QAAE,IAAI,EAAE,MAAM,CAAC;QAAC,WAAW,EAAE,MAAM,CAAC;QAAC,QAAQ,EAAE,OAAO,CAAA;KAAE,CAAC,CAAC;
|
|
1
|
+
{"version":3,"file":"prompts.d.ts","sourceRoot":"","sources":["../src/prompts.ts"],"names":[],"mappings":"AAAA,eAAO,MAAM,gBAAgB,EAAE,MAAM,CAAC,MAAM,EAAE;IAC5C,IAAI,EAAE,MAAM,CAAC;IACb,WAAW,EAAE,MAAM,CAAC;IACpB,SAAS,EAAE,KAAK,CAAC;QAAE,IAAI,EAAE,MAAM,CAAC;QAAC,WAAW,EAAE,MAAM,CAAC;QAAC,QAAQ,EAAE,OAAO,CAAA;KAAE,CAAC,CAAC;IAC3E,MAAM,EAAE,CAAC,IAAI,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,KAAK,MAAM,CAAC;CACnD,CAqCA,CAAC;AAEF,wBAAsB,WAAW;;;;;kBAzCN,MAAM;yBAAe,MAAM;sBAAY,OAAO;;;GAiDxE;AAED,wBAAsB,SAAS,CAAC,IAAI,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC;;;;;;;;GAe1E"}
|