@microsoft/agent-governance-antigravity-cli 4.0.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 +99 -0
- package/assets/extensions/agt-global-policy/ANTIGRAVITY.md +9 -0
- package/assets/extensions/agt-global-policy/antigravity-extension.json +30 -0
- package/assets/extensions/agt-global-policy/commands/agt/check.toml +15 -0
- package/assets/extensions/agt-global-policy/commands/agt/status.toml +13 -0
- package/assets/extensions/agt-global-policy/config/default-policy.json +245 -0
- package/assets/extensions/agt-global-policy/config/profiles/advisory.json +246 -0
- package/assets/extensions/agt-global-policy/config/profiles/balanced.json +246 -0
- package/assets/extensions/agt-global-policy/config/profiles/strict.json +246 -0
- package/assets/extensions/agt-global-policy/hooks/after-tool.mjs +43 -0
- package/assets/extensions/agt-global-policy/hooks/before-agent.mjs +39 -0
- package/assets/extensions/agt-global-policy/hooks/before-tool.mjs +41 -0
- package/assets/extensions/agt-global-policy/hooks/hooks.json +60 -0
- package/assets/extensions/agt-global-policy/hooks/session-start.mjs +18 -0
- package/assets/extensions/agt-global-policy/lib/hook-runtime.mjs +62 -0
- package/assets/extensions/agt-global-policy/lib/poisoning.mjs +61 -0
- package/assets/extensions/agt-global-policy/lib/policy.mjs +1388 -0
- package/assets/extensions/agt-global-policy/lib/sdk-loader.mjs +46 -0
- package/assets/extensions/agt-global-policy/mcp/server.mjs +224 -0
- package/assets/extensions/agt-global-policy/package.json +4 -0
- package/bin/agt-antigravity.mjs +8 -0
- package/lib/cli.mjs +941 -0
- package/package.json +42 -0
|
@@ -0,0 +1,46 @@
|
|
|
1
|
+
// Copyright (c) Microsoft Corporation.
|
|
2
|
+
// Licensed under the MIT License.
|
|
3
|
+
|
|
4
|
+
import { existsSync, realpathSync } from "node:fs";
|
|
5
|
+
import { join, resolve } from "node:path";
|
|
6
|
+
import { pathToFileURL } from "node:url";
|
|
7
|
+
|
|
8
|
+
const VENDORED_SDK_RELATIVE_PATH =
|
|
9
|
+
"./vendor/agent-governance-sdk/node_modules/@microsoft/agent-governance-sdk/dist/index.js";
|
|
10
|
+
|
|
11
|
+
export async function loadAgentGovernanceSdk({
|
|
12
|
+
env = process.env,
|
|
13
|
+
extensionRoot = import.meta.dirname,
|
|
14
|
+
} = {}) {
|
|
15
|
+
const extensionRootPath = realpathSync(resolve(extensionRoot));
|
|
16
|
+
const vendoredSdkPath = resolve(extensionRootPath, VENDORED_SDK_RELATIVE_PATH);
|
|
17
|
+
const candidates = [
|
|
18
|
+
{
|
|
19
|
+
path: vendoredSdkPath,
|
|
20
|
+
source: "vendored",
|
|
21
|
+
},
|
|
22
|
+
];
|
|
23
|
+
|
|
24
|
+
const attempted = [];
|
|
25
|
+
for (const candidate of candidates) {
|
|
26
|
+
attempted.push(candidate.path);
|
|
27
|
+
if (!existsSync(candidate.path)) {
|
|
28
|
+
continue;
|
|
29
|
+
}
|
|
30
|
+
|
|
31
|
+
const canonicalCandidatePath = realpathSync(candidate.path);
|
|
32
|
+
const loaded = await import(pathToFileURL(canonicalCandidatePath).href);
|
|
33
|
+
return {
|
|
34
|
+
path: canonicalCandidatePath,
|
|
35
|
+
sdk: loaded.default ?? loaded,
|
|
36
|
+
source: candidate.source,
|
|
37
|
+
};
|
|
38
|
+
}
|
|
39
|
+
|
|
40
|
+
throw new Error(
|
|
41
|
+
[
|
|
42
|
+
"Unable to locate the vendored Agent Governance TypeScript SDK.",
|
|
43
|
+
`Checked paths: ${attempted.join("; ")}`,
|
|
44
|
+
].join(" "),
|
|
45
|
+
);
|
|
46
|
+
}
|
|
@@ -0,0 +1,224 @@
|
|
|
1
|
+
// Copyright (c) Microsoft Corporation.
|
|
2
|
+
// Licensed under the MIT License.
|
|
3
|
+
|
|
4
|
+
import { fileURLToPath } from "node:url";
|
|
5
|
+
|
|
6
|
+
import { checkArbitraryText, formatPolicySummary, getPolicyStatus, loadPolicy } from "../lib/policy.mjs";
|
|
7
|
+
|
|
8
|
+
const SERVER_INFO = {
|
|
9
|
+
name: "agt-global-policy",
|
|
10
|
+
version: "3.3.0",
|
|
11
|
+
};
|
|
12
|
+
const PROTOCOL_VERSION = "2024-11-05";
|
|
13
|
+
const JSONRPC_VERSION = "2.0";
|
|
14
|
+
const HEADER_SEPARATOR = Buffer.from("\r\n\r\n", "utf8");
|
|
15
|
+
const extensionRoot = fileURLToPath(new URL("..", import.meta.url));
|
|
16
|
+
|
|
17
|
+
const tools = [
|
|
18
|
+
{
|
|
19
|
+
name: "agt_policy_status",
|
|
20
|
+
description: "Return the active AGT Antigravity policy runtime status and summary.",
|
|
21
|
+
inputSchema: {
|
|
22
|
+
type: "object",
|
|
23
|
+
properties: {},
|
|
24
|
+
additionalProperties: false,
|
|
25
|
+
},
|
|
26
|
+
},
|
|
27
|
+
{
|
|
28
|
+
name: "agt_policy_check_text",
|
|
29
|
+
description: "Run AGT poisoning, MCP, and prompt-defense checks against arbitrary text.",
|
|
30
|
+
inputSchema: {
|
|
31
|
+
type: "object",
|
|
32
|
+
properties: {
|
|
33
|
+
text: {
|
|
34
|
+
type: "string",
|
|
35
|
+
description: "The text to inspect.",
|
|
36
|
+
},
|
|
37
|
+
},
|
|
38
|
+
required: ["text"],
|
|
39
|
+
additionalProperties: false,
|
|
40
|
+
},
|
|
41
|
+
},
|
|
42
|
+
];
|
|
43
|
+
|
|
44
|
+
let inputBuffer = Buffer.alloc(0);
|
|
45
|
+
|
|
46
|
+
process.stdin.on("data", (chunk) => {
|
|
47
|
+
inputBuffer = Buffer.concat([inputBuffer, chunk]);
|
|
48
|
+
void drainInputBuffer();
|
|
49
|
+
});
|
|
50
|
+
|
|
51
|
+
async function drainInputBuffer() {
|
|
52
|
+
while (true) {
|
|
53
|
+
const headerEnd = inputBuffer.indexOf(HEADER_SEPARATOR);
|
|
54
|
+
if (headerEnd === -1) {
|
|
55
|
+
return;
|
|
56
|
+
}
|
|
57
|
+
|
|
58
|
+
const headerText = inputBuffer.subarray(0, headerEnd).toString("utf8");
|
|
59
|
+
const contentLength = getContentLength(headerText);
|
|
60
|
+
if (contentLength === null) {
|
|
61
|
+
inputBuffer = Buffer.alloc(0);
|
|
62
|
+
writeError(null, -32700, "Missing or invalid Content-Length header.");
|
|
63
|
+
return;
|
|
64
|
+
}
|
|
65
|
+
|
|
66
|
+
const messageStart = headerEnd + HEADER_SEPARATOR.length;
|
|
67
|
+
const messageEnd = messageStart + contentLength;
|
|
68
|
+
if (inputBuffer.length < messageEnd) {
|
|
69
|
+
return;
|
|
70
|
+
}
|
|
71
|
+
|
|
72
|
+
const payload = inputBuffer.subarray(messageStart, messageEnd).toString("utf8");
|
|
73
|
+
inputBuffer = inputBuffer.subarray(messageEnd);
|
|
74
|
+
|
|
75
|
+
let message;
|
|
76
|
+
try {
|
|
77
|
+
message = JSON.parse(payload);
|
|
78
|
+
} catch {
|
|
79
|
+
writeError(null, -32700, "Invalid JSON payload.");
|
|
80
|
+
continue;
|
|
81
|
+
}
|
|
82
|
+
|
|
83
|
+
await handleMessage(message);
|
|
84
|
+
}
|
|
85
|
+
}
|
|
86
|
+
|
|
87
|
+
function getContentLength(headerText) {
|
|
88
|
+
for (const line of headerText.split("\r\n")) {
|
|
89
|
+
const [name, ...valueParts] = line.split(":");
|
|
90
|
+
if (name?.toLowerCase() !== "content-length") {
|
|
91
|
+
continue;
|
|
92
|
+
}
|
|
93
|
+
const parsed = Number.parseInt(valueParts.join(":").trim(), 10);
|
|
94
|
+
return Number.isFinite(parsed) ? parsed : null;
|
|
95
|
+
}
|
|
96
|
+
return null;
|
|
97
|
+
}
|
|
98
|
+
|
|
99
|
+
async function handleMessage(message) {
|
|
100
|
+
if (message?.jsonrpc !== JSONRPC_VERSION || typeof message?.method !== "string") {
|
|
101
|
+
writeError(message?.id ?? null, -32600, "Invalid JSON-RPC request.");
|
|
102
|
+
return;
|
|
103
|
+
}
|
|
104
|
+
|
|
105
|
+
if (message.method === "notifications/initialized") {
|
|
106
|
+
return;
|
|
107
|
+
}
|
|
108
|
+
|
|
109
|
+
try {
|
|
110
|
+
if (message.method === "initialize") {
|
|
111
|
+
writeResult(message.id, {
|
|
112
|
+
protocolVersion: PROTOCOL_VERSION,
|
|
113
|
+
capabilities: {
|
|
114
|
+
tools: {},
|
|
115
|
+
},
|
|
116
|
+
serverInfo: SERVER_INFO,
|
|
117
|
+
});
|
|
118
|
+
return;
|
|
119
|
+
}
|
|
120
|
+
|
|
121
|
+
if (message.method === "ping") {
|
|
122
|
+
writeResult(message.id, {});
|
|
123
|
+
return;
|
|
124
|
+
}
|
|
125
|
+
|
|
126
|
+
if (message.method === "tools/list") {
|
|
127
|
+
writeResult(message.id, { tools });
|
|
128
|
+
return;
|
|
129
|
+
}
|
|
130
|
+
|
|
131
|
+
if (message.method === "tools/call") {
|
|
132
|
+
writeResult(message.id, await callTool(message.params ?? {}));
|
|
133
|
+
return;
|
|
134
|
+
}
|
|
135
|
+
|
|
136
|
+
writeError(message.id ?? null, -32601, `Unknown method: ${message.method}`);
|
|
137
|
+
} catch (error) {
|
|
138
|
+
writeError(message.id ?? null, -32603, error instanceof Error ? error.message : String(error));
|
|
139
|
+
}
|
|
140
|
+
}
|
|
141
|
+
|
|
142
|
+
async function callTool(params) {
|
|
143
|
+
const state = await loadPolicy({ extensionRoot });
|
|
144
|
+
const args = params.arguments ?? {};
|
|
145
|
+
|
|
146
|
+
if (params.name === "agt_policy_status") {
|
|
147
|
+
return {
|
|
148
|
+
content: [
|
|
149
|
+
{
|
|
150
|
+
type: "text",
|
|
151
|
+
text: JSON.stringify(
|
|
152
|
+
{
|
|
153
|
+
summary: formatPolicySummary(state),
|
|
154
|
+
status: getPolicyStatus(state),
|
|
155
|
+
},
|
|
156
|
+
null,
|
|
157
|
+
2,
|
|
158
|
+
),
|
|
159
|
+
},
|
|
160
|
+
],
|
|
161
|
+
};
|
|
162
|
+
}
|
|
163
|
+
|
|
164
|
+
if (params.name === "agt_policy_check_text") {
|
|
165
|
+
const text = String(args.text ?? "").trim();
|
|
166
|
+
if (!text) {
|
|
167
|
+
return {
|
|
168
|
+
content: [
|
|
169
|
+
{
|
|
170
|
+
type: "text",
|
|
171
|
+
text: "The `text` argument is required.",
|
|
172
|
+
},
|
|
173
|
+
],
|
|
174
|
+
isError: true,
|
|
175
|
+
};
|
|
176
|
+
}
|
|
177
|
+
|
|
178
|
+
return {
|
|
179
|
+
content: [
|
|
180
|
+
{
|
|
181
|
+
type: "text",
|
|
182
|
+
text: JSON.stringify(checkArbitraryText(state, text), null, 2),
|
|
183
|
+
},
|
|
184
|
+
],
|
|
185
|
+
};
|
|
186
|
+
}
|
|
187
|
+
|
|
188
|
+
return {
|
|
189
|
+
content: [
|
|
190
|
+
{
|
|
191
|
+
type: "text",
|
|
192
|
+
text: `Unknown tool: ${params.name}`,
|
|
193
|
+
},
|
|
194
|
+
],
|
|
195
|
+
isError: true,
|
|
196
|
+
};
|
|
197
|
+
}
|
|
198
|
+
|
|
199
|
+
function writeResult(id, result) {
|
|
200
|
+
if (id === undefined || id === null) {
|
|
201
|
+
return;
|
|
202
|
+
}
|
|
203
|
+
writeMessage({
|
|
204
|
+
jsonrpc: JSONRPC_VERSION,
|
|
205
|
+
id,
|
|
206
|
+
result,
|
|
207
|
+
});
|
|
208
|
+
}
|
|
209
|
+
|
|
210
|
+
function writeError(id, code, message) {
|
|
211
|
+
writeMessage({
|
|
212
|
+
jsonrpc: JSONRPC_VERSION,
|
|
213
|
+
id,
|
|
214
|
+
error: {
|
|
215
|
+
code,
|
|
216
|
+
message,
|
|
217
|
+
},
|
|
218
|
+
});
|
|
219
|
+
}
|
|
220
|
+
|
|
221
|
+
function writeMessage(payload) {
|
|
222
|
+
const body = JSON.stringify(payload);
|
|
223
|
+
process.stdout.write(`Content-Length: ${Buffer.byteLength(body, "utf8")}\r\n\r\n${body}`);
|
|
224
|
+
}
|