@weave_protocol/adapter-msaf 0.1.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 +277 -0
- package/SKILL.md +102 -0
- package/dist/cli.d.ts +16 -0
- package/dist/cli.d.ts.map +1 -0
- package/dist/cli.js +260 -0
- package/dist/cli.js.map +1 -0
- package/dist/index.d.ts +12 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +10 -0
- package/dist/index.js.map +1 -0
- package/dist/middleware.d.ts +96 -0
- package/dist/middleware.d.ts.map +1 -0
- package/dist/middleware.js +164 -0
- package/dist/middleware.js.map +1 -0
- package/dist/policy.d.ts +25 -0
- package/dist/policy.d.ts.map +1 -0
- package/dist/policy.js +154 -0
- package/dist/policy.js.map +1 -0
- package/dist/types.d.ts +96 -0
- package/dist/types.d.ts.map +1 -0
- package/dist/types.js +58 -0
- package/dist/types.js.map +1 -0
- package/package.json +56 -0
package/README.md
ADDED
|
@@ -0,0 +1,277 @@
|
|
|
1
|
+
# 🛡️ @weave_protocol/adapter-msaf
|
|
2
|
+
|
|
3
|
+
[](https://www.npmjs.com/package/@weave_protocol/adapter-msaf)
|
|
4
|
+
[](https://www.npmjs.com/package/@weave_protocol/adapter-msaf)
|
|
5
|
+
[](https://opensource.org/licenses/Apache-2.0)
|
|
6
|
+
|
|
7
|
+
**WARD.md enforcement for [Microsoft Agent Framework](https://devblogs.microsoft.com/agent-framework/) (MSAF) via the middleware pipeline.**
|
|
8
|
+
|
|
9
|
+
> *AGENTS.md tells your agent what to do. SKILL.md tells your agent how to do it. **WARD.md tells your agent what it can't.** This package makes Microsoft Agent Framework listen.*
|
|
10
|
+
|
|
11
|
+
Part of the [Weave Protocol](https://github.com/Tyox-all/Weave_Protocol) security suite. Third cross-platform harness adapter (after [adapter-claudecode](../adapter-claudecode) and [adapter-antigravity](../adapter-antigravity)).
|
|
12
|
+
|
|
13
|
+
---
|
|
14
|
+
|
|
15
|
+
## What it does
|
|
16
|
+
|
|
17
|
+
When a Microsoft Agent Framework agent is about to invoke a tool (shell command, file edit, HTTP request, etc.), the WARD middleware fires in the function-middleware layer, reads your project's `WARD.md`, and **throws a `WardDeniedError`** if the call violates the declared policy. MSAF's middleware pipeline short-circuits, the tool never runs.
|
|
18
|
+
|
|
19
|
+
Because MSAF middleware is registered programmatically (not via a config file), there's no global hook to install — you wire it into your agent setup in one line.
|
|
20
|
+
|
|
21
|
+
```typescript
|
|
22
|
+
import { WardMiddleware } from '@weave_protocol/adapter-msaf';
|
|
23
|
+
|
|
24
|
+
const ward = new WardMiddleware(); // auto-loads ./WARD.md
|
|
25
|
+
agent.useFunctionMiddleware(ward.functionMiddleware());
|
|
26
|
+
```
|
|
27
|
+
|
|
28
|
+
That's it. Every tool call your MSAF agent makes is now gated by your WARD.md.
|
|
29
|
+
|
|
30
|
+
---
|
|
31
|
+
|
|
32
|
+
## Why this is shaped differently from the other adapters
|
|
33
|
+
|
|
34
|
+
| | adapter-claudecode | adapter-antigravity | **adapter-msaf** |
|
|
35
|
+
|---|---|---|---|
|
|
36
|
+
| Install pattern | `init` writes to `~/.claude/settings.json` | `init` writes to `~/.gemini/antigravity-cli/settings.json` | **You import a class and pass it to your agent** |
|
|
37
|
+
| Invocation | CLI subprocess (stdin/stdout) | CLI subprocess (stdin/stdout) | **In-process middleware function** |
|
|
38
|
+
| Scope | Global (all Claude Code sessions) | Global (all Antigravity surfaces) | **Per-agent (whichever agents you wire it into)** |
|
|
39
|
+
|
|
40
|
+
MSAF doesn't have a global config file for hooks — middleware lives in your agent code. That's a deliberate design choice in MSAF (it wants explicit, code-level policy registration). So instead of `init` writing config, it prints the integration snippet for you to paste.
|
|
41
|
+
|
|
42
|
+
---
|
|
43
|
+
|
|
44
|
+
## Quick start
|
|
45
|
+
|
|
46
|
+
```bash
|
|
47
|
+
# Install
|
|
48
|
+
npm install @weave_protocol/adapter-msaf
|
|
49
|
+
```
|
|
50
|
+
|
|
51
|
+
Then in your MSAF agent setup:
|
|
52
|
+
|
|
53
|
+
```typescript
|
|
54
|
+
import { WardMiddleware } from '@weave_protocol/adapter-msaf';
|
|
55
|
+
|
|
56
|
+
// Construct — auto-loads WARD.md from cwd, .weave/, or .msaf/
|
|
57
|
+
const ward = new WardMiddleware();
|
|
58
|
+
|
|
59
|
+
// Or explicit path:
|
|
60
|
+
// const ward = new WardMiddleware({ wardPath: './policies/strict.WARD.md' });
|
|
61
|
+
|
|
62
|
+
// Or inline source (useful for tests):
|
|
63
|
+
// const ward = new WardMiddleware({ wardSource: someMdContent });
|
|
64
|
+
|
|
65
|
+
// Register
|
|
66
|
+
agent.useFunctionMiddleware(ward.functionMiddleware());
|
|
67
|
+
```
|
|
68
|
+
|
|
69
|
+
Drop a `WARD.md` in your project root (`npx @weave_protocol/ward init`) and you're done.
|
|
70
|
+
|
|
71
|
+
Verify with:
|
|
72
|
+
|
|
73
|
+
```bash
|
|
74
|
+
npx weave-msaf status
|
|
75
|
+
```
|
|
76
|
+
|
|
77
|
+
---
|
|
78
|
+
|
|
79
|
+
## How WARD.md is resolved
|
|
80
|
+
|
|
81
|
+
When the middleware is constructed (or `weave-msaf status` runs), it looks in this order:
|
|
82
|
+
|
|
83
|
+
1. Explicit `wardPath` constructor option
|
|
84
|
+
2. Explicit `wardSource` constructor option (raw markdown)
|
|
85
|
+
3. `$WEAVE_WARD_PATH` env var
|
|
86
|
+
4. `<cwd>/WARD.md`
|
|
87
|
+
5. `<cwd>/.weave/WARD.md`
|
|
88
|
+
6. `<cwd>/.msaf/WARD.md`
|
|
89
|
+
|
|
90
|
+
First match wins. If nothing is found:
|
|
91
|
+
- Default (fail-open): every call is allowed; a warning is logged once
|
|
92
|
+
- `failMode: 'closed'`: constructor throws
|
|
93
|
+
|
|
94
|
+
---
|
|
95
|
+
|
|
96
|
+
## Tool mapping
|
|
97
|
+
|
|
98
|
+
MSAF tool names are user-defined, but several common conventions emerge from the local agent runtime and the Copilot/Claude Code SDK harness integrations. Built-in mappings cover them:
|
|
99
|
+
|
|
100
|
+
| MSAF tool | WARD capability | Path arg | fs op |
|
|
101
|
+
|---|---|---|---|
|
|
102
|
+
| `ShellExec` / `Bash` / `RunCommand` | `shell_exec` | (command heuristic) | varies |
|
|
103
|
+
| `FileWrite` / `FileEdit` / `EditFile` / `Edit` / `Write` | `file_write` | `path` or `file_path` | `write` |
|
|
104
|
+
| `FileRead` / `ReadFile` / `Read` | `file_read` | `path` or `file_path` | `read` |
|
|
105
|
+
| `FileDelete` | `file_delete` | `path` | `delete` |
|
|
106
|
+
| `ListDirectory` | `file_list` | `path` | `list` |
|
|
107
|
+
| `HttpRequest` / `WebFetch` | `http_request` | `url` | — |
|
|
108
|
+
| `SendEmail` | `send_email` | — | — |
|
|
109
|
+
| `PostMessage` | `send_message` | — | — |
|
|
110
|
+
| `CreateIssue` | `create_issue` | — | — |
|
|
111
|
+
| `Subagent` | `subagent` | — | — |
|
|
112
|
+
|
|
113
|
+
Your WARD.md can use either the MSAF tool name or the generic capability. Explicit allow/deny/approval rules beat default decisions.
|
|
114
|
+
|
|
115
|
+
**Custom mappings:**
|
|
116
|
+
|
|
117
|
+
```typescript
|
|
118
|
+
const ward = new WardMiddleware({
|
|
119
|
+
toolMappings: {
|
|
120
|
+
MyCorpAPI: { capability: 'http_request', urlField: 'endpoint' },
|
|
121
|
+
AzureCLI: { capability: 'shell_exec', commandField: 'cmd' },
|
|
122
|
+
}
|
|
123
|
+
});
|
|
124
|
+
```
|
|
125
|
+
|
|
126
|
+
The Bash command heuristic also catches Azure CLI credential paths (`~/.azure/`) on top of SSH/AWS/GCP — relevant for MSAF users.
|
|
127
|
+
|
|
128
|
+
---
|
|
129
|
+
|
|
130
|
+
## Callbacks for logging and attestation
|
|
131
|
+
|
|
132
|
+
```typescript
|
|
133
|
+
const ward = new WardMiddleware({
|
|
134
|
+
onAllow: (call, result) => {
|
|
135
|
+
log.info('ward.allow', { tool: call.toolName });
|
|
136
|
+
},
|
|
137
|
+
onDeny: async (call, result) => {
|
|
138
|
+
log.warn('ward.deny', { tool: call.toolName, reasons: result.reasons });
|
|
139
|
+
// (Optional) return true to override the deny — emergency escape valve
|
|
140
|
+
// return false; // (default) — let WARD deny stand
|
|
141
|
+
},
|
|
142
|
+
});
|
|
143
|
+
```
|
|
144
|
+
|
|
145
|
+
`onDeny` returning `true` lets you override a WARD decision at runtime (for human-in-the-loop approval, for instance). Logged but allowed. Use sparingly.
|
|
146
|
+
|
|
147
|
+
---
|
|
148
|
+
|
|
149
|
+
## CLI
|
|
150
|
+
|
|
151
|
+
```bash
|
|
152
|
+
weave-msaf init [--language=ts|csharp|python]
|
|
153
|
+
Print the integration snippet you paste into your agent code
|
|
154
|
+
|
|
155
|
+
weave-msaf status
|
|
156
|
+
Show the active WARD policy (resolved from cwd) and built-in mappings
|
|
157
|
+
|
|
158
|
+
weave-msaf test <tool> [--input=JSON]
|
|
159
|
+
Dry-run a tool call against your WARD.md without invoking MSAF
|
|
160
|
+
|
|
161
|
+
weave-msaf help
|
|
162
|
+
```
|
|
163
|
+
|
|
164
|
+
### Examples
|
|
165
|
+
|
|
166
|
+
```bash
|
|
167
|
+
# What would happen if my agent tried to exfil Azure creds?
|
|
168
|
+
weave-msaf test ShellExec --input='{"command":"cat ~/.azure/credentials"}'
|
|
169
|
+
|
|
170
|
+
# What about a forbidden HTTP endpoint?
|
|
171
|
+
weave-msaf test HttpRequest --input='{"url":"https://evil.example.com"}'
|
|
172
|
+
|
|
173
|
+
# Get the integration snippet
|
|
174
|
+
weave-msaf init --language=ts
|
|
175
|
+
```
|
|
176
|
+
|
|
177
|
+
---
|
|
178
|
+
|
|
179
|
+
## Catching denials
|
|
180
|
+
|
|
181
|
+
The middleware throws `WardDeniedError` (a named class) so callers can handle WARD failures distinctly:
|
|
182
|
+
|
|
183
|
+
```typescript
|
|
184
|
+
import { WardDeniedError } from '@weave_protocol/adapter-msaf';
|
|
185
|
+
|
|
186
|
+
try {
|
|
187
|
+
await agent.run(userPrompt);
|
|
188
|
+
} catch (err) {
|
|
189
|
+
if (err instanceof WardDeniedError) {
|
|
190
|
+
console.warn(`Agent action blocked by WARD: ${err.reasons.join(', ')}`);
|
|
191
|
+
// Optionally surface to user, route to human-in-the-loop, etc.
|
|
192
|
+
} else {
|
|
193
|
+
throw err;
|
|
194
|
+
}
|
|
195
|
+
}
|
|
196
|
+
```
|
|
197
|
+
|
|
198
|
+
---
|
|
199
|
+
|
|
200
|
+
## A sample WARD.md for an MSAF agent
|
|
201
|
+
|
|
202
|
+
```markdown
|
|
203
|
+
---
|
|
204
|
+
ward: "1.0"
|
|
205
|
+
agent: msaf-coding-agent
|
|
206
|
+
---
|
|
207
|
+
|
|
208
|
+
# WARD.md
|
|
209
|
+
|
|
210
|
+
## Filesystem
|
|
211
|
+
|
|
212
|
+
allow:
|
|
213
|
+
- read: /Users/me/projects/**
|
|
214
|
+
- write: /Users/me/projects/**
|
|
215
|
+
deny:
|
|
216
|
+
- read: ~/.ssh/**
|
|
217
|
+
- read: ~/.azure/**
|
|
218
|
+
- read: ~/.aws/**
|
|
219
|
+
- write: /etc/**
|
|
220
|
+
default: deny
|
|
221
|
+
|
|
222
|
+
## Network
|
|
223
|
+
|
|
224
|
+
allow:
|
|
225
|
+
- url: "https://api.github.com/**"
|
|
226
|
+
- url: "https://management.azure.com/**"
|
|
227
|
+
- url: "https://*.openai.azure.com/**"
|
|
228
|
+
default: deny
|
|
229
|
+
|
|
230
|
+
## Capabilities
|
|
231
|
+
|
|
232
|
+
allow:
|
|
233
|
+
- file_read
|
|
234
|
+
- file_write
|
|
235
|
+
- file_list
|
|
236
|
+
requireApproval:
|
|
237
|
+
- shell_exec
|
|
238
|
+
- http_request
|
|
239
|
+
- subagent
|
|
240
|
+
deny:
|
|
241
|
+
- file_delete
|
|
242
|
+
default: deny
|
|
243
|
+
|
|
244
|
+
## Behavioral Limits
|
|
245
|
+
|
|
246
|
+
maxIterations: 50
|
|
247
|
+
maxCostUSD: 5.00
|
|
248
|
+
maxRuntimeSeconds: 600
|
|
249
|
+
```
|
|
250
|
+
|
|
251
|
+
With this, the MSAF agent can work inside your projects directory but can't read SSH/AWS/Azure credentials, requires approval for shell or HTTP, and is hard-blocked from spawning subagents or deleting files.
|
|
252
|
+
|
|
253
|
+
---
|
|
254
|
+
|
|
255
|
+
## Roadmap
|
|
256
|
+
|
|
257
|
+
v0.1 (this release):
|
|
258
|
+
- ✅ TypeScript middleware library + CLI
|
|
259
|
+
- ✅ Function middleware (per-tool gating)
|
|
260
|
+
- ✅ Agent middleware (turn-level hook, pass-through scaffold)
|
|
261
|
+
- ✅ 20-tool built-in mappings (MSAF local runtime + Copilot SDK + Claude Code SDK patterns)
|
|
262
|
+
- ✅ Bash command heuristic includes Azure credential paths
|
|
263
|
+
- ✅ Allow/deny callbacks for logging and override
|
|
264
|
+
- ✅ `WardDeniedError` typed exception
|
|
265
|
+
|
|
266
|
+
v0.2 planned:
|
|
267
|
+
- [ ] Native .NET package (NuGet) for first-class C# integration
|
|
268
|
+
- [ ] Native Python package (PyPI) — for MSAF Python users
|
|
269
|
+
- [ ] Behavioral-limit enforcement in agent middleware (iteration / cost caps)
|
|
270
|
+
- [ ] Domere attestation integration in `onAllow`/`onDeny`
|
|
271
|
+
- [ ] Chat middleware variant (gate at the model-call layer)
|
|
272
|
+
|
|
273
|
+
---
|
|
274
|
+
|
|
275
|
+
## License
|
|
276
|
+
|
|
277
|
+
Apache 2.0 — see [LICENSE](../LICENSE).
|
package/SKILL.md
ADDED
|
@@ -0,0 +1,102 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: adapter-msaf
|
|
3
|
+
description: Use this skill when the user wants to enforce a WARD.md security policy inside Microsoft Agent Framework (MSAF) via its middleware pipeline. Triggers on requests to "secure my Agent Framework agent", "block MSAF from doing X", "add WARD middleware to my agent", "lock down my Copilot SDK agent", or any work involving the `weave-msaf` command or programmatic WARD enforcement in a Microsoft agent setup. Also useful when reviewing a user's MSAF agent code for missing security middleware, or when a user wants to know how to express their WARD.md as runtime enforcement in C#/TypeScript/Python.
|
|
4
|
+
---
|
|
5
|
+
|
|
6
|
+
# Microsoft Agent Framework adapter for Weave Protocol
|
|
7
|
+
|
|
8
|
+
The `@weave_protocol/adapter-msaf` package enforces [WARD.md](https://www.npmjs.com/package/@weave_protocol/ward) policies inside Microsoft Agent Framework (MSAF) via its middleware pipeline. Unlike the Claude Code and Antigravity adapters which use config-file hooks, this adapter is a **library** that the user registers programmatically in their agent setup.
|
|
9
|
+
|
|
10
|
+
## When to use
|
|
11
|
+
|
|
12
|
+
- User is building an MSAF agent and wants policy enforcement at the tool-call layer
|
|
13
|
+
- User wants the same WARD.md they use elsewhere (Claude Code, Antigravity, MCP) to apply to their MSAF agent
|
|
14
|
+
- User wants typed exceptions (`WardDeniedError`) to catch and handle WARD denials in their code
|
|
15
|
+
- User wants per-agent enforcement (not global, since one process may run multiple agents with different policies)
|
|
16
|
+
|
|
17
|
+
## Architecture difference from claudecode / antigravity adapters
|
|
18
|
+
|
|
19
|
+
MSAF middleware is **registered programmatically**, not via a config file. So:
|
|
20
|
+
- No `init` writes to disk; instead it prints the integration snippet
|
|
21
|
+
- Middleware is per-agent, not global
|
|
22
|
+
- Runs in-process (no subprocess invocation overhead)
|
|
23
|
+
|
|
24
|
+
The user must paste a small code snippet into their MSAF agent setup. The CLI helps with `init` (snippet generator), `status` (verify policy resolution), and `test` (dry-run a call).
|
|
25
|
+
|
|
26
|
+
## Primary API
|
|
27
|
+
|
|
28
|
+
```typescript
|
|
29
|
+
import { WardMiddleware } from '@weave_protocol/adapter-msaf';
|
|
30
|
+
|
|
31
|
+
const ward = new WardMiddleware({
|
|
32
|
+
// wardPath: './WARD.md' // or auto-resolve from cwd
|
|
33
|
+
// failMode: 'closed' // or 'open' (default)
|
|
34
|
+
// toolMappings: { ... } // custom tool name → capability
|
|
35
|
+
// onAllow: (call, result) => { ... }
|
|
36
|
+
// onDeny: (call, result) => { ... }
|
|
37
|
+
});
|
|
38
|
+
|
|
39
|
+
agent.useFunctionMiddleware(ward.functionMiddleware());
|
|
40
|
+
```
|
|
41
|
+
|
|
42
|
+
## WARD resolution order
|
|
43
|
+
|
|
44
|
+
1. `wardPath` option (explicit)
|
|
45
|
+
2. `wardSource` option (raw markdown)
|
|
46
|
+
3. `$WEAVE_WARD_PATH`
|
|
47
|
+
4. `<cwd>/WARD.md`
|
|
48
|
+
5. `<cwd>/.weave/WARD.md`
|
|
49
|
+
6. `<cwd>/.msaf/WARD.md`
|
|
50
|
+
|
|
51
|
+
## CLI
|
|
52
|
+
|
|
53
|
+
```bash
|
|
54
|
+
weave-msaf init [--language=ts|csharp|python] # print integration snippet
|
|
55
|
+
weave-msaf status # show active WARD + mappings
|
|
56
|
+
weave-msaf test <tool> [--input=JSON] # dry-run a tool call
|
|
57
|
+
```
|
|
58
|
+
|
|
59
|
+
## Tool mapping
|
|
60
|
+
|
|
61
|
+
Covers MSAF's local agent runtime tools, Copilot SDK patterns, and Claude Code SDK integration (since MSAF can use them as a sub-harness):
|
|
62
|
+
|
|
63
|
+
- `ShellExec`/`Bash`/`RunCommand` → `shell_exec` (with command heuristic)
|
|
64
|
+
- `FileWrite`/`FileEdit`/`Edit`/`Write` → `file_write`
|
|
65
|
+
- `FileRead`/`Read` → `file_read`
|
|
66
|
+
- `FileDelete` → `file_delete`
|
|
67
|
+
- `ListDirectory` → `file_list`
|
|
68
|
+
- `HttpRequest`/`WebFetch` → `http_request`
|
|
69
|
+
- `SendEmail` → `send_email`
|
|
70
|
+
- `PostMessage` → `send_message`
|
|
71
|
+
- `CreateIssue` → `create_issue`
|
|
72
|
+
- `Subagent` → `subagent`
|
|
73
|
+
|
|
74
|
+
WARD.md can use either MSAF tool names or generic capabilities. Custom mappings via `toolMappings` option.
|
|
75
|
+
|
|
76
|
+
Bash command heuristic includes **Azure credential paths** (`~/.azure/`) — the realistic threat vector for MSAF users.
|
|
77
|
+
|
|
78
|
+
## Decision rules
|
|
79
|
+
|
|
80
|
+
| Situation | Action |
|
|
81
|
+
|---|---|
|
|
82
|
+
| User asks how to enforce WARD in their MSAF agent | Show `init` snippet + `WardMiddleware` construction |
|
|
83
|
+
| User wants to test policy without running the agent | `weave-msaf test <tool>` |
|
|
84
|
+
| User reports a tool call was blocked | Suggest catching `WardDeniedError` |
|
|
85
|
+
| User wants emergency override capability | Use `onDeny` callback returning `true` |
|
|
86
|
+
| User wants stricter failure mode | `failMode: 'closed'` |
|
|
87
|
+
| User uses non-standard tool names | `toolMappings: { MyTool: { capability: '...' } }` |
|
|
88
|
+
|
|
89
|
+
## Pairs with
|
|
90
|
+
|
|
91
|
+
- `@weave_protocol/ward` — the policy format being enforced
|
|
92
|
+
- `@weave_protocol/adapter-claudecode` — same WARD.md, enforced in Claude Code
|
|
93
|
+
- `@weave_protocol/adapter-antigravity` — same WARD.md, enforced in Antigravity
|
|
94
|
+
- `@weave_protocol/hundredmen` — enforces the same WARD.md on MCP servers
|
|
95
|
+
- `@weave_protocol/cli` — `weave init` scaffolds projects with a WARD.md
|
|
96
|
+
|
|
97
|
+
## Anti-patterns
|
|
98
|
+
|
|
99
|
+
- **Don't try to globally install this adapter via a config file.** MSAF doesn't work that way. Each agent registration is explicit.
|
|
100
|
+
- **Don't catch `WardDeniedError` and silently swallow it** — if a WARD says no, that's the policy. If you need to override, use the `onDeny` callback explicitly so the decision is logged.
|
|
101
|
+
- **Don't ship to production with `failMode: 'open'` and no WARD.md.** That's silent no-enforcement. Either ship a WARD.md or use `failMode: 'closed'` so a missing policy is loud.
|
|
102
|
+
- **Don't use this for MDASH** — MDASH is Microsoft's internal vulnerability-scanning research platform, not the Microsoft Agent Framework. This adapter targets MSAF (the public developer-facing framework).
|
package/dist/cli.d.ts
ADDED
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
/**
|
|
3
|
+
* weave-msaf CLI
|
|
4
|
+
*
|
|
5
|
+
* weave-msaf init [--language=ts|csharp|python] Print integration snippet
|
|
6
|
+
* weave-msaf status Show active WARD policy
|
|
7
|
+
* weave-msaf test <tool> [--input=JSON] Dry-run a tool call
|
|
8
|
+
* weave-msaf help
|
|
9
|
+
*
|
|
10
|
+
* Note: Unlike the Claude Code / Antigravity adapters, MSAF middleware is
|
|
11
|
+
* programmatic — registered in the user's agent code, not via a config file.
|
|
12
|
+
* So `init` here prints the integration snippet for the user to paste rather
|
|
13
|
+
* than writing to a settings.json.
|
|
14
|
+
*/
|
|
15
|
+
export {};
|
|
16
|
+
//# sourceMappingURL=cli.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"cli.d.ts","sourceRoot":"","sources":["../src/cli.ts"],"names":[],"mappings":";AACA;;;;;;;;;;;;GAYG"}
|
package/dist/cli.js
ADDED
|
@@ -0,0 +1,260 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
/**
|
|
3
|
+
* weave-msaf CLI
|
|
4
|
+
*
|
|
5
|
+
* weave-msaf init [--language=ts|csharp|python] Print integration snippet
|
|
6
|
+
* weave-msaf status Show active WARD policy
|
|
7
|
+
* weave-msaf test <tool> [--input=JSON] Dry-run a tool call
|
|
8
|
+
* weave-msaf help
|
|
9
|
+
*
|
|
10
|
+
* Note: Unlike the Claude Code / Antigravity adapters, MSAF middleware is
|
|
11
|
+
* programmatic — registered in the user's agent code, not via a config file.
|
|
12
|
+
* So `init` here prints the integration snippet for the user to paste rather
|
|
13
|
+
* than writing to a settings.json.
|
|
14
|
+
*/
|
|
15
|
+
import { resolve } from 'node:path';
|
|
16
|
+
import { resolveWardForCwd, evaluateCall } from './policy.js';
|
|
17
|
+
import { TOOL_MAPPINGS } from './types.js';
|
|
18
|
+
// ─── ANSI colors ───────────────────────────────────────────────
|
|
19
|
+
const tty = process.stdout.isTTY && !process.env.NO_COLOR;
|
|
20
|
+
const c = {
|
|
21
|
+
reset: tty ? '\x1b[0m' : '',
|
|
22
|
+
bold: tty ? '\x1b[1m' : '',
|
|
23
|
+
dim: tty ? '\x1b[2m' : '',
|
|
24
|
+
red: tty ? '\x1b[31m' : '',
|
|
25
|
+
green: tty ? '\x1b[32m' : '',
|
|
26
|
+
yellow: tty ? '\x1b[33m' : '',
|
|
27
|
+
blue: tty ? '\x1b[34m' : '',
|
|
28
|
+
cyan: tty ? '\x1b[36m' : '',
|
|
29
|
+
gray: tty ? '\x1b[90m' : '',
|
|
30
|
+
};
|
|
31
|
+
function banner() {
|
|
32
|
+
console.error(`
|
|
33
|
+
${c.cyan}${c.bold}🛡️ weave-msaf${c.reset}
|
|
34
|
+
${c.gray}WARD.md enforcement for Microsoft Agent Framework via middleware${c.reset}
|
|
35
|
+
`);
|
|
36
|
+
}
|
|
37
|
+
// ─── help ──────────────────────────────────────────────────────
|
|
38
|
+
function help() {
|
|
39
|
+
banner();
|
|
40
|
+
console.error(`${c.bold}Usage:${c.reset} weave-msaf <command> [options]\n`);
|
|
41
|
+
console.error(`${c.bold}Commands:${c.reset}`);
|
|
42
|
+
console.error(` ${c.cyan}init${c.reset} ${c.gray}[--language=ts|csharp|python]${c.reset} Print integration snippet for your code`);
|
|
43
|
+
console.error(` ${c.cyan}status${c.reset} Show active WARD policy`);
|
|
44
|
+
console.error(` ${c.cyan}test${c.reset} ${c.gray}<tool> [--input=JSON]${c.reset} Dry-run a tool call against your WARD.md`);
|
|
45
|
+
console.error(` ${c.cyan}help${c.reset} Show this message\n`);
|
|
46
|
+
console.error(`${c.bold}Examples:${c.reset}`);
|
|
47
|
+
console.error(` ${c.gray}$${c.reset} weave-msaf init --language=ts`);
|
|
48
|
+
console.error(` ${c.gray}$${c.reset} weave-msaf status`);
|
|
49
|
+
console.error(` ${c.gray}$${c.reset} weave-msaf test ShellExec --input='{"command":"rm -rf ~/.azure"}'\n`);
|
|
50
|
+
console.error(`${c.gray}Docs: https://github.com/Tyox-all/Weave_Protocol/tree/main/adapter-msaf${c.reset}\n`);
|
|
51
|
+
}
|
|
52
|
+
// ─── arg helpers ───────────────────────────────────────────────
|
|
53
|
+
function parseFlag(args, name) {
|
|
54
|
+
for (const a of args) {
|
|
55
|
+
if (a === `--${name}`)
|
|
56
|
+
return '';
|
|
57
|
+
if (a.startsWith(`--${name}=`))
|
|
58
|
+
return a.slice(`--${name}=`.length);
|
|
59
|
+
}
|
|
60
|
+
return undefined;
|
|
61
|
+
}
|
|
62
|
+
// ─── init ──────────────────────────────────────────────────────
|
|
63
|
+
function runInit(args) {
|
|
64
|
+
banner();
|
|
65
|
+
const language = parseFlag(args, 'language') || 'ts';
|
|
66
|
+
console.error(`${c.bold}Integration snippet for ${c.cyan}${language}${c.reset}${c.bold}${c.reset}\n`);
|
|
67
|
+
if (language === 'csharp' || language === 'cs' || language === '.net') {
|
|
68
|
+
console.log(`// In your MSAF agent setup:
|
|
69
|
+
// (.NET / C#)
|
|
70
|
+
|
|
71
|
+
using Microsoft.AgentFramework;
|
|
72
|
+
|
|
73
|
+
// 1. Install: dotnet add package Weave.Protocol.AdapterMsaf
|
|
74
|
+
// (.NET wrapper coming in v0.2 — for now use the Node bridge or call
|
|
75
|
+
// the WARD CLI as a subprocess from your MSAF middleware.)
|
|
76
|
+
|
|
77
|
+
// 2. Until v0.2, recommended approach: install @weave_protocol/adapter-msaf
|
|
78
|
+
// via Node and call \`weave-msaf test\` from a custom .NET function
|
|
79
|
+
// middleware to evaluate calls. See README for full pattern.
|
|
80
|
+
`);
|
|
81
|
+
}
|
|
82
|
+
else if (language === 'python' || language === 'py') {
|
|
83
|
+
console.log(`# In your MSAF agent setup (Python):
|
|
84
|
+
|
|
85
|
+
# 1. Install:
|
|
86
|
+
# pip install weave-protocol-msaf # coming in v0.2 (Python package)
|
|
87
|
+
#
|
|
88
|
+
# For now, the npm package can be invoked from Python as a subprocess
|
|
89
|
+
# for testing. The Python middleware shape is:
|
|
90
|
+
|
|
91
|
+
class WardFunctionMiddleware:
|
|
92
|
+
def __init__(self, ward_path="WARD.md"):
|
|
93
|
+
# load policy
|
|
94
|
+
...
|
|
95
|
+
|
|
96
|
+
async def pre_invoke(self, ctx):
|
|
97
|
+
# evaluate ctx.tool_name and ctx.arguments against WARD
|
|
98
|
+
# call ctx.cancel() if denied
|
|
99
|
+
...
|
|
100
|
+
|
|
101
|
+
# Track issue #N for native Python support timeline.
|
|
102
|
+
`);
|
|
103
|
+
}
|
|
104
|
+
else {
|
|
105
|
+
// TypeScript (default)
|
|
106
|
+
console.log(`// In your MSAF agent setup (TypeScript):
|
|
107
|
+
|
|
108
|
+
import { WardMiddleware } from '@weave_protocol/adapter-msaf';
|
|
109
|
+
|
|
110
|
+
// 1. Construct with auto-resolved WARD.md
|
|
111
|
+
const ward = new WardMiddleware();
|
|
112
|
+
// Or with explicit path:
|
|
113
|
+
// const ward = new WardMiddleware({ wardPath: './policies/strict.WARD.md' });
|
|
114
|
+
|
|
115
|
+
// 2. Register as function middleware on your MSAF agent.
|
|
116
|
+
// The exact API depends on your MSAF Node binding; the middleware function
|
|
117
|
+
// follows the documented pre_invoke shape:
|
|
118
|
+
//
|
|
119
|
+
// async (call, next) => { ... }
|
|
120
|
+
//
|
|
121
|
+
agent.useFunctionMiddleware(ward.functionMiddleware());
|
|
122
|
+
|
|
123
|
+
// 3. (Optional) Custom tool mappings if you have non-standard tool names:
|
|
124
|
+
// const ward = new WardMiddleware({
|
|
125
|
+
// toolMappings: {
|
|
126
|
+
// MyCustomTool: { capability: 'custom_capability' }
|
|
127
|
+
// }
|
|
128
|
+
// });
|
|
129
|
+
|
|
130
|
+
// 4. (Optional) Allow/deny callbacks for logging/attestation:
|
|
131
|
+
// const ward = new WardMiddleware({
|
|
132
|
+
// onAllow: (call, result) => log('allowed', call.toolName),
|
|
133
|
+
// onDeny: (call, result) => log('denied', call.toolName, result.reasons),
|
|
134
|
+
// });
|
|
135
|
+
`);
|
|
136
|
+
}
|
|
137
|
+
console.error('');
|
|
138
|
+
console.error(`${c.gray}─${c.reset}`.repeat(60));
|
|
139
|
+
console.error(`${c.bold}Next:${c.reset}`);
|
|
140
|
+
console.error(` ${c.gray}1.${c.reset} Drop a ${c.cyan}WARD.md${c.reset} in your project root (or pass wardPath explicitly)`);
|
|
141
|
+
console.error(` ${c.gray}2.${c.reset} Paste the snippet above into your agent setup code`);
|
|
142
|
+
console.error(` ${c.gray}3.${c.reset} Run ${c.cyan}weave-msaf status${c.reset} to verify policy is found`);
|
|
143
|
+
console.error('');
|
|
144
|
+
return 0;
|
|
145
|
+
}
|
|
146
|
+
// ─── status ────────────────────────────────────────────────────
|
|
147
|
+
function runStatus() {
|
|
148
|
+
banner();
|
|
149
|
+
console.error(`${c.bold}Active WARD policy${c.reset}`);
|
|
150
|
+
console.error(`${c.gray}─${c.reset}`.repeat(60));
|
|
151
|
+
try {
|
|
152
|
+
const resolved = resolveWardForCwd(process.cwd());
|
|
153
|
+
if (!resolved) {
|
|
154
|
+
console.error(` ${c.yellow}No WARD.md found${c.reset}`);
|
|
155
|
+
console.error(` ${c.gray}Looked at:${c.reset}`);
|
|
156
|
+
if (process.env.WEAVE_WARD_PATH)
|
|
157
|
+
console.error(` ${c.gray}•${c.reset} ${process.env.WEAVE_WARD_PATH} ${c.gray}(WEAVE_WARD_PATH)${c.reset}`);
|
|
158
|
+
console.error(` ${c.gray}•${c.reset} ${resolve(process.cwd(), 'WARD.md')}`);
|
|
159
|
+
console.error(` ${c.gray}•${c.reset} ${resolve(process.cwd(), '.weave', 'WARD.md')}`);
|
|
160
|
+
console.error(` ${c.gray}•${c.reset} ${resolve(process.cwd(), '.msaf', 'WARD.md')}`);
|
|
161
|
+
}
|
|
162
|
+
else {
|
|
163
|
+
console.error(` ${c.gray}Source:${c.reset} ${c.cyan}${resolved.source}${c.reset}`);
|
|
164
|
+
console.error(` ${c.gray}Name:${c.reset} ${resolved.policy.name || c.gray + '(unnamed)' + c.reset}`);
|
|
165
|
+
console.error(` ${c.gray}Agent:${c.reset} ${resolved.policy.agent || c.gray + '(none)' + c.reset}`);
|
|
166
|
+
console.error(` ${c.gray}WARD version:${c.reset} ${resolved.policy.version}`);
|
|
167
|
+
}
|
|
168
|
+
}
|
|
169
|
+
catch (err) {
|
|
170
|
+
console.error(` ${c.red}Error loading WARD.md:${c.reset} ${err instanceof Error ? err.message : String(err)}`);
|
|
171
|
+
return 1;
|
|
172
|
+
}
|
|
173
|
+
console.error('');
|
|
174
|
+
console.error(`${c.bold}Built-in tool mappings${c.reset}`);
|
|
175
|
+
console.error(`${c.gray}─${c.reset}`.repeat(60));
|
|
176
|
+
const mappingNames = Object.keys(TOOL_MAPPINGS).slice(0, 12);
|
|
177
|
+
console.error(` ${c.gray}${mappingNames.join(', ')}${mappingNames.length < Object.keys(TOOL_MAPPINGS).length ? ', ...' : ''}${c.reset}`);
|
|
178
|
+
console.error(` ${c.gray}(${Object.keys(TOOL_MAPPINGS).length} total — see README for full list)${c.reset}`);
|
|
179
|
+
console.error('');
|
|
180
|
+
return 0;
|
|
181
|
+
}
|
|
182
|
+
// ─── test ──────────────────────────────────────────────────────
|
|
183
|
+
function runTest(args) {
|
|
184
|
+
const tool = args[0];
|
|
185
|
+
if (!tool) {
|
|
186
|
+
console.error(`${c.red}✗${c.reset} Usage: weave-msaf test <tool> [--input='{"path":"..."}']`);
|
|
187
|
+
return 2;
|
|
188
|
+
}
|
|
189
|
+
banner();
|
|
190
|
+
const inputArg = parseFlag(args, 'input');
|
|
191
|
+
let toolInput = {};
|
|
192
|
+
if (inputArg) {
|
|
193
|
+
try {
|
|
194
|
+
toolInput = JSON.parse(inputArg);
|
|
195
|
+
}
|
|
196
|
+
catch {
|
|
197
|
+
console.error(`${c.red}✗${c.reset} --input must be valid JSON`);
|
|
198
|
+
return 2;
|
|
199
|
+
}
|
|
200
|
+
}
|
|
201
|
+
const resolved = resolveWardForCwd(process.cwd());
|
|
202
|
+
if (!resolved) {
|
|
203
|
+
console.error(`${c.yellow}⚠${c.reset} No WARD.md found — call would be allowed by default.`);
|
|
204
|
+
return 0;
|
|
205
|
+
}
|
|
206
|
+
console.error(`Testing ${c.bold}${tool}${c.reset}${inputArg ? ' with ' + c.cyan + JSON.stringify(toolInput) + c.reset : ''}`);
|
|
207
|
+
console.error(`Policy: ${c.cyan}${resolved.source}${c.reset}\n`);
|
|
208
|
+
const result = evaluateCall(resolved.policy, { toolName: tool, args: toolInput });
|
|
209
|
+
const colorMap = {
|
|
210
|
+
allow: c.green,
|
|
211
|
+
deny: c.red,
|
|
212
|
+
require_approval: c.yellow,
|
|
213
|
+
};
|
|
214
|
+
const iconMap = { allow: '✓', deny: '✗', require_approval: '⚠' };
|
|
215
|
+
console.error(`Decision: ${colorMap[result.decision]}${iconMap[result.decision]} ${result.decision.toUpperCase()}${c.reset}`);
|
|
216
|
+
if (result.reasons.length > 0) {
|
|
217
|
+
console.error(`\nReasons:`);
|
|
218
|
+
for (const r of result.reasons)
|
|
219
|
+
console.error(` ${c.gray}•${c.reset} ${r}`);
|
|
220
|
+
}
|
|
221
|
+
console.error('');
|
|
222
|
+
return result.decision === 'deny' ? 1 : 0;
|
|
223
|
+
}
|
|
224
|
+
// ─── router ────────────────────────────────────────────────────
|
|
225
|
+
async function main() {
|
|
226
|
+
const [, , cmd, ...rest] = process.argv;
|
|
227
|
+
let code = 0;
|
|
228
|
+
try {
|
|
229
|
+
switch (cmd) {
|
|
230
|
+
case 'init':
|
|
231
|
+
code = runInit(rest);
|
|
232
|
+
break;
|
|
233
|
+
case 'status':
|
|
234
|
+
code = runStatus();
|
|
235
|
+
break;
|
|
236
|
+
case 'test':
|
|
237
|
+
code = runTest(rest);
|
|
238
|
+
break;
|
|
239
|
+
case 'help':
|
|
240
|
+
case '--help':
|
|
241
|
+
case '-h':
|
|
242
|
+
case undefined:
|
|
243
|
+
help();
|
|
244
|
+
break;
|
|
245
|
+
default:
|
|
246
|
+
console.error(`${c.red}Unknown command: ${cmd}${c.reset}\n`);
|
|
247
|
+
help();
|
|
248
|
+
code = 2;
|
|
249
|
+
}
|
|
250
|
+
}
|
|
251
|
+
catch (err) {
|
|
252
|
+
console.error(`${c.red}Error:${c.reset} ${err instanceof Error ? err.message : String(err)}`);
|
|
253
|
+
if (process.env.DEBUG)
|
|
254
|
+
console.error(err);
|
|
255
|
+
code = 2;
|
|
256
|
+
}
|
|
257
|
+
process.exit(code);
|
|
258
|
+
}
|
|
259
|
+
main();
|
|
260
|
+
//# sourceMappingURL=cli.js.map
|
package/dist/cli.js.map
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"cli.js","sourceRoot":"","sources":["../src/cli.ts"],"names":[],"mappings":"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"}
|