@crustdev/armordesk 0.0.0-stage → 1.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/LICENSE +21 -0
- package/README.md +164 -2
- package/bin/cli.js +6 -0
- package/dist/chunk-TVWUJ3XJ.mjs +297 -0
- package/dist/cli.d.ts +2 -0
- package/dist/cli.d.ts.map +1 -0
- package/dist/cli.js +607 -0
- package/dist/cli.mjs +300 -0
- package/dist/client.d.ts +81 -0
- package/dist/client.d.ts.map +1 -0
- package/dist/crypto.d.ts +31 -0
- package/dist/crypto.d.ts.map +1 -0
- package/dist/index.d.ts +5 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +331 -0
- package/dist/index.mjs +22 -0
- package/dist/mcp.d.ts +21 -0
- package/dist/mcp.d.ts.map +1 -0
- package/dist/types.d.ts +237 -0
- package/dist/types.d.ts.map +1 -0
- package/package.json +54 -4
package/dist/index.js
ADDED
|
@@ -0,0 +1,331 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __defProp = Object.defineProperty;
|
|
3
|
+
var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
|
|
4
|
+
var __getOwnPropNames = Object.getOwnPropertyNames;
|
|
5
|
+
var __hasOwnProp = Object.prototype.hasOwnProperty;
|
|
6
|
+
var __export = (target, all) => {
|
|
7
|
+
for (var name in all)
|
|
8
|
+
__defProp(target, name, { get: all[name], enumerable: true });
|
|
9
|
+
};
|
|
10
|
+
var __copyProps = (to, from, except, desc) => {
|
|
11
|
+
if (from && typeof from === "object" || typeof from === "function") {
|
|
12
|
+
for (let key of __getOwnPropNames(from))
|
|
13
|
+
if (!__hasOwnProp.call(to, key) && key !== except)
|
|
14
|
+
__defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
|
|
15
|
+
}
|
|
16
|
+
return to;
|
|
17
|
+
};
|
|
18
|
+
var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
|
|
19
|
+
|
|
20
|
+
// src/index.ts
|
|
21
|
+
var index_exports = {};
|
|
22
|
+
__export(index_exports, {
|
|
23
|
+
ArmorDeskClient: () => ArmorDeskClient,
|
|
24
|
+
buildMerkleTree: () => buildMerkleTree,
|
|
25
|
+
canonicalJson: () => canonicalJson,
|
|
26
|
+
generateClaudeDesktopConfig: () => generateClaudeDesktopConfig,
|
|
27
|
+
generateCursorConfig: () => generateCursorConfig,
|
|
28
|
+
generatePlanHash: () => generatePlanHash,
|
|
29
|
+
hashSha256: () => hashSha256,
|
|
30
|
+
verifyMerkleRoot: () => verifyMerkleRoot,
|
|
31
|
+
verifyProof: () => verifyProof
|
|
32
|
+
});
|
|
33
|
+
module.exports = __toCommonJS(index_exports);
|
|
34
|
+
|
|
35
|
+
// src/crypto.ts
|
|
36
|
+
var import_node_crypto = require("crypto");
|
|
37
|
+
function canonicalJson(data) {
|
|
38
|
+
if (data === null || data === void 0) {
|
|
39
|
+
return "null";
|
|
40
|
+
}
|
|
41
|
+
if (typeof data === "number" || typeof data === "boolean") {
|
|
42
|
+
return JSON.stringify(data);
|
|
43
|
+
}
|
|
44
|
+
if (typeof data === "string") {
|
|
45
|
+
return JSON.stringify(data);
|
|
46
|
+
}
|
|
47
|
+
if (Array.isArray(data)) {
|
|
48
|
+
return "[" + data.map((item) => canonicalJson(item)).join(",") + "]";
|
|
49
|
+
}
|
|
50
|
+
if (typeof data === "object") {
|
|
51
|
+
const keys = Object.keys(data).sort();
|
|
52
|
+
const entries = keys.map((k) => JSON.stringify(k) + ":" + canonicalJson(data[k]));
|
|
53
|
+
return "{" + entries.join(",") + "}";
|
|
54
|
+
}
|
|
55
|
+
return JSON.stringify(data);
|
|
56
|
+
}
|
|
57
|
+
function hashSha256(data) {
|
|
58
|
+
return (0, import_node_crypto.createHash)("sha256").update(data, "utf8").digest("hex");
|
|
59
|
+
}
|
|
60
|
+
function generatePlanHash(planDict) {
|
|
61
|
+
const canonical = canonicalJson(planDict);
|
|
62
|
+
return hashSha256(canonical);
|
|
63
|
+
}
|
|
64
|
+
function buildMerkleTree(leafItems) {
|
|
65
|
+
const leafHashes = leafItems.length === 0 ? [hashSha256("empty_tree_node")] : leafItems.map((item) => hashSha256(item));
|
|
66
|
+
let currentLevel = [...leafHashes];
|
|
67
|
+
while (currentLevel.length > 1) {
|
|
68
|
+
const nextLevel = [];
|
|
69
|
+
for (let i = 0; i < currentLevel.length; i += 2) {
|
|
70
|
+
const left = currentLevel[i];
|
|
71
|
+
const right = i + 1 < currentLevel.length ? currentLevel[i + 1] : left;
|
|
72
|
+
const combined = hashSha256(left + right);
|
|
73
|
+
nextLevel.push(combined);
|
|
74
|
+
}
|
|
75
|
+
currentLevel = nextLevel;
|
|
76
|
+
}
|
|
77
|
+
return {
|
|
78
|
+
root: currentLevel[0],
|
|
79
|
+
leafHashes
|
|
80
|
+
};
|
|
81
|
+
}
|
|
82
|
+
function verifyMerkleRoot(leafItems, expectedRoot) {
|
|
83
|
+
const { root } = buildMerkleTree(leafItems);
|
|
84
|
+
return root.toLowerCase() === expectedRoot.toLowerCase();
|
|
85
|
+
}
|
|
86
|
+
function verifyProof(request) {
|
|
87
|
+
const computedPlanHash = generatePlanHash(request.allowed_spec);
|
|
88
|
+
const matchesHash = computedPlanHash.toLowerCase() === request.plan_hash.toLowerCase();
|
|
89
|
+
const executionItems = Object.entries(request.actual_execution).sort(([a], [b]) => a.localeCompare(b)).map(([k, v]) => `${k}:${canonicalJson(v)}`);
|
|
90
|
+
const { root: computedMerkleRoot } = buildMerkleTree(executionItems);
|
|
91
|
+
const matchesMerkle = computedMerkleRoot.toLowerCase() === request.merkle_root.toLowerCase();
|
|
92
|
+
const valid = matchesHash && matchesMerkle;
|
|
93
|
+
return {
|
|
94
|
+
valid,
|
|
95
|
+
computed_plan_hash: computedPlanHash,
|
|
96
|
+
computed_merkle_root: computedMerkleRoot,
|
|
97
|
+
matches_hash: matchesHash,
|
|
98
|
+
matches_merkle: matchesMerkle,
|
|
99
|
+
status: valid ? "CRYPTOGRAPHICALLY_VERIFIED" : "VERIFICATION_FAILED",
|
|
100
|
+
details: valid ? "Plan hash matches allowed specification and Merkle root confirms un-tampered execution proof." : `Discrepancy detected: hashMatch=${matchesHash}, merkleMatch=${matchesMerkle}`
|
|
101
|
+
};
|
|
102
|
+
}
|
|
103
|
+
|
|
104
|
+
// src/client.ts
|
|
105
|
+
var ArmorDeskClient = class {
|
|
106
|
+
baseUrl;
|
|
107
|
+
apiKey;
|
|
108
|
+
tenantId;
|
|
109
|
+
userName;
|
|
110
|
+
userRole;
|
|
111
|
+
_fetch;
|
|
112
|
+
crypto = {
|
|
113
|
+
canonicalJson,
|
|
114
|
+
generatePlanHash,
|
|
115
|
+
buildMerkleTree,
|
|
116
|
+
verifyMerkleRoot,
|
|
117
|
+
verifyProof
|
|
118
|
+
};
|
|
119
|
+
constructor(options = {}) {
|
|
120
|
+
this.baseUrl = (options.baseUrl || typeof process !== "undefined" && process.env?.ARMORDESK_URL || "https://armordesk.crusts.dev").replace(/\/$/, "");
|
|
121
|
+
this.apiKey = options.apiKey || (typeof process !== "undefined" ? process.env?.ARMORIQ_API_KEY || process.env?.ARMORIQ_PRO_API_KEY : void 0);
|
|
122
|
+
this.tenantId = options.tenantId || "acme-corp";
|
|
123
|
+
this.userName = options.userName || "Sarah Chen";
|
|
124
|
+
this.userRole = options.userRole || "manager";
|
|
125
|
+
this._fetch = options.fetch || globalThis.fetch.bind(globalThis);
|
|
126
|
+
}
|
|
127
|
+
async request(endpoint, options = {}) {
|
|
128
|
+
const url = `${this.baseUrl}${endpoint.startsWith("/") ? endpoint : "/" + endpoint}`;
|
|
129
|
+
const headers = {
|
|
130
|
+
"Content-Type": "application/json",
|
|
131
|
+
"X-ArmorIQ-Tenant": this.tenantId,
|
|
132
|
+
...options.headers
|
|
133
|
+
};
|
|
134
|
+
if (this.apiKey) {
|
|
135
|
+
headers["Authorization"] = `Bearer ${this.apiKey}`;
|
|
136
|
+
headers["X-ArmorIQ-API-Key"] = this.apiKey;
|
|
137
|
+
}
|
|
138
|
+
const res = await this._fetch(url, {
|
|
139
|
+
...options,
|
|
140
|
+
headers
|
|
141
|
+
});
|
|
142
|
+
if (!res.ok) {
|
|
143
|
+
let errorBody = "";
|
|
144
|
+
try {
|
|
145
|
+
errorBody = await res.text();
|
|
146
|
+
} catch {
|
|
147
|
+
}
|
|
148
|
+
throw new Error(
|
|
149
|
+
`ArmorDesk API error [${res.status} ${res.statusText}] at ${endpoint}: ${errorBody || "Unknown error"}`
|
|
150
|
+
);
|
|
151
|
+
}
|
|
152
|
+
return res.json();
|
|
153
|
+
}
|
|
154
|
+
/**
|
|
155
|
+
* Health and runtime operational telemetry
|
|
156
|
+
*/
|
|
157
|
+
async status() {
|
|
158
|
+
return this.request("/api/status");
|
|
159
|
+
}
|
|
160
|
+
/**
|
|
161
|
+
* List managed corporate tenants
|
|
162
|
+
*/
|
|
163
|
+
async getTenants() {
|
|
164
|
+
return this.request("/api/tenants");
|
|
165
|
+
}
|
|
166
|
+
/**
|
|
167
|
+
* Fetch immutable security and policy enforcement traces
|
|
168
|
+
*/
|
|
169
|
+
async getTraces(tenantId) {
|
|
170
|
+
const tid = tenantId || this.tenantId;
|
|
171
|
+
return this.request(`/api/traces?tenant_id=${encodeURIComponent(tid)}`);
|
|
172
|
+
}
|
|
173
|
+
/**
|
|
174
|
+
* Fetch approval queue items held by human-in-the-loop policies
|
|
175
|
+
*/
|
|
176
|
+
async getApprovals(tenantId) {
|
|
177
|
+
const tid = tenantId || this.tenantId;
|
|
178
|
+
return this.request(`/api/approvals?tenant_id=${encodeURIComponent(tid)}`);
|
|
179
|
+
}
|
|
180
|
+
/**
|
|
181
|
+
* Authorize or reject a held action in escrow
|
|
182
|
+
*/
|
|
183
|
+
async resolveApproval(delegationId, action, notes) {
|
|
184
|
+
const payload = {
|
|
185
|
+
action,
|
|
186
|
+
user_role: this.userRole,
|
|
187
|
+
user_name: this.userName,
|
|
188
|
+
notes
|
|
189
|
+
};
|
|
190
|
+
return this.request(`/api/approvals/${encodeURIComponent(delegationId)}/action`, {
|
|
191
|
+
method: "POST",
|
|
192
|
+
body: JSON.stringify(payload)
|
|
193
|
+
});
|
|
194
|
+
}
|
|
195
|
+
/**
|
|
196
|
+
* List digital verification receipts with cryptographic proofs
|
|
197
|
+
*/
|
|
198
|
+
async getReceipts(tenantId) {
|
|
199
|
+
const tid = tenantId || this.tenantId;
|
|
200
|
+
return this.request(`/api/receipts?tenant_id=${encodeURIComponent(tid)}`);
|
|
201
|
+
}
|
|
202
|
+
/**
|
|
203
|
+
* Retrieve a specific receipt by ID
|
|
204
|
+
*/
|
|
205
|
+
async getReceipt(receiptId) {
|
|
206
|
+
return this.request(`/api/receipts/${encodeURIComponent(receiptId)}`);
|
|
207
|
+
}
|
|
208
|
+
/**
|
|
209
|
+
* Cryptographically verify a digital proof
|
|
210
|
+
*/
|
|
211
|
+
async verifyProof(proof) {
|
|
212
|
+
return this.request("/api/receipts/verify", {
|
|
213
|
+
method: "POST",
|
|
214
|
+
body: JSON.stringify(proof)
|
|
215
|
+
});
|
|
216
|
+
}
|
|
217
|
+
/**
|
|
218
|
+
* Get MCP Gateway configuration and sample connection specs
|
|
219
|
+
*/
|
|
220
|
+
async getMCPConfig(tenantId) {
|
|
221
|
+
const tid = tenantId || this.tenantId;
|
|
222
|
+
return this.request(`/api/mcp/config?tenant_id=${encodeURIComponent(tid)}`);
|
|
223
|
+
}
|
|
224
|
+
/**
|
|
225
|
+
* Invoke a tool through the Governed MCP Gateway
|
|
226
|
+
*/
|
|
227
|
+
async callMCPTool(toolName, args, options = {}) {
|
|
228
|
+
const rpcPayload = {
|
|
229
|
+
jsonrpc: "2.0",
|
|
230
|
+
id: Date.now(),
|
|
231
|
+
method: "tools/call",
|
|
232
|
+
params: {
|
|
233
|
+
name: toolName,
|
|
234
|
+
arguments: args,
|
|
235
|
+
context: {
|
|
236
|
+
user_role: options.userRole || this.userRole,
|
|
237
|
+
user_name: options.userName || this.userName,
|
|
238
|
+
delegation_id: options.delegationId
|
|
239
|
+
}
|
|
240
|
+
}
|
|
241
|
+
};
|
|
242
|
+
return this.request("/api/mcp/gateway", {
|
|
243
|
+
method: "POST",
|
|
244
|
+
body: JSON.stringify(rpcPayload)
|
|
245
|
+
});
|
|
246
|
+
}
|
|
247
|
+
/**
|
|
248
|
+
* Execute an adversarial FinOps scenario simulation (1 to 5)
|
|
249
|
+
*/
|
|
250
|
+
async runScenario(scenarioId, tenantId) {
|
|
251
|
+
return this.request("/api/scenarios/run", {
|
|
252
|
+
method: "POST",
|
|
253
|
+
body: JSON.stringify({
|
|
254
|
+
scenario_id: scenarioId,
|
|
255
|
+
tenant_id: tenantId || this.tenantId
|
|
256
|
+
})
|
|
257
|
+
});
|
|
258
|
+
}
|
|
259
|
+
/**
|
|
260
|
+
* Test prompt injection attacks against ArmorDesk CTF Gauntlet
|
|
261
|
+
*/
|
|
262
|
+
async submitCTF(prompt, attackerName, tenantId) {
|
|
263
|
+
return this.request("/api/ctf/submit", {
|
|
264
|
+
method: "POST",
|
|
265
|
+
body: JSON.stringify({
|
|
266
|
+
prompt,
|
|
267
|
+
attacker_name: attackerName || "PenTester",
|
|
268
|
+
tenant_id: tenantId || this.tenantId
|
|
269
|
+
})
|
|
270
|
+
});
|
|
271
|
+
}
|
|
272
|
+
/**
|
|
273
|
+
* Generate an executive voice briefing via ElevenLabs
|
|
274
|
+
*/
|
|
275
|
+
async getVoiceBriefing(briefingType = "executive", tenantId) {
|
|
276
|
+
return this.request("/api/voice/briefing", {
|
|
277
|
+
method: "POST",
|
|
278
|
+
body: JSON.stringify({
|
|
279
|
+
briefing_type: briefingType,
|
|
280
|
+
tenant_id: tenantId || this.tenantId
|
|
281
|
+
})
|
|
282
|
+
});
|
|
283
|
+
}
|
|
284
|
+
};
|
|
285
|
+
|
|
286
|
+
// src/mcp.ts
|
|
287
|
+
function generateClaudeDesktopConfig(options = {}) {
|
|
288
|
+
const url = options.gatewayUrl || "https://armordesk.crusts.dev/api/mcp/gateway";
|
|
289
|
+
const tenant = options.tenantId || "acme-corp";
|
|
290
|
+
const apiKey = options.apiKey || "ak_live_acme_corp";
|
|
291
|
+
return {
|
|
292
|
+
mcpServers: {
|
|
293
|
+
armordesk_gateway: {
|
|
294
|
+
command: "npx",
|
|
295
|
+
args: ["-y", "@modelcontextprotocol/server-fetch", url],
|
|
296
|
+
env: {
|
|
297
|
+
ARMORIQ_TENANT: tenant,
|
|
298
|
+
ARMORIQ_API_KEY: apiKey
|
|
299
|
+
}
|
|
300
|
+
}
|
|
301
|
+
}
|
|
302
|
+
};
|
|
303
|
+
}
|
|
304
|
+
function generateCursorConfig(options = {}) {
|
|
305
|
+
const url = options.gatewayUrl || "https://armordesk.crusts.dev/api/mcp/gateway";
|
|
306
|
+
const tenant = options.tenantId || "acme-corp";
|
|
307
|
+
const apiKey = options.apiKey || "ak_live_acme_corp";
|
|
308
|
+
return {
|
|
309
|
+
mcpServers: {
|
|
310
|
+
armordesk: {
|
|
311
|
+
url,
|
|
312
|
+
headers: {
|
|
313
|
+
"X-ArmorIQ-Tenant": tenant,
|
|
314
|
+
Authorization: `Bearer ${apiKey}`
|
|
315
|
+
}
|
|
316
|
+
}
|
|
317
|
+
}
|
|
318
|
+
};
|
|
319
|
+
}
|
|
320
|
+
// Annotate the CommonJS export names for ESM import in node:
|
|
321
|
+
0 && (module.exports = {
|
|
322
|
+
ArmorDeskClient,
|
|
323
|
+
buildMerkleTree,
|
|
324
|
+
canonicalJson,
|
|
325
|
+
generateClaudeDesktopConfig,
|
|
326
|
+
generateCursorConfig,
|
|
327
|
+
generatePlanHash,
|
|
328
|
+
hashSha256,
|
|
329
|
+
verifyMerkleRoot,
|
|
330
|
+
verifyProof
|
|
331
|
+
});
|
package/dist/index.mjs
ADDED
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
import {
|
|
2
|
+
ArmorDeskClient,
|
|
3
|
+
buildMerkleTree,
|
|
4
|
+
canonicalJson,
|
|
5
|
+
generateClaudeDesktopConfig,
|
|
6
|
+
generateCursorConfig,
|
|
7
|
+
generatePlanHash,
|
|
8
|
+
hashSha256,
|
|
9
|
+
verifyMerkleRoot,
|
|
10
|
+
verifyProof
|
|
11
|
+
} from "./chunk-TVWUJ3XJ.mjs";
|
|
12
|
+
export {
|
|
13
|
+
ArmorDeskClient,
|
|
14
|
+
buildMerkleTree,
|
|
15
|
+
canonicalJson,
|
|
16
|
+
generateClaudeDesktopConfig,
|
|
17
|
+
generateCursorConfig,
|
|
18
|
+
generatePlanHash,
|
|
19
|
+
hashSha256,
|
|
20
|
+
verifyMerkleRoot,
|
|
21
|
+
verifyProof
|
|
22
|
+
};
|
package/dist/mcp.d.ts
ADDED
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Generates ready-to-paste Claude Desktop configuration object
|
|
3
|
+
*/
|
|
4
|
+
export declare function generateClaudeDesktopConfig(options?: {
|
|
5
|
+
gatewayUrl?: string;
|
|
6
|
+
tenantId?: string;
|
|
7
|
+
apiKey?: string;
|
|
8
|
+
}): {
|
|
9
|
+
mcpServers: Record<string, any>;
|
|
10
|
+
};
|
|
11
|
+
/**
|
|
12
|
+
* Generates ready-to-paste Cursor IDE MCP configuration object
|
|
13
|
+
*/
|
|
14
|
+
export declare function generateCursorConfig(options?: {
|
|
15
|
+
gatewayUrl?: string;
|
|
16
|
+
tenantId?: string;
|
|
17
|
+
apiKey?: string;
|
|
18
|
+
}): {
|
|
19
|
+
mcpServers: Record<string, any>;
|
|
20
|
+
};
|
|
21
|
+
//# sourceMappingURL=mcp.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"mcp.d.ts","sourceRoot":"","sources":["../src/mcp.ts"],"names":[],"mappings":"AAEA;;GAEG;AACH,wBAAgB,2BAA2B,CAAC,OAAO,GAAE;IACnD,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,MAAM,CAAC,EAAE,MAAM,CAAC;CACZ,GAAG;IAAE,UAAU,EAAE,MAAM,CAAC,MAAM,EAAE,GAAG,CAAC,CAAA;CAAE,CAiB3C;AAED;;GAEG;AACH,wBAAgB,oBAAoB,CAAC,OAAO,GAAE;IAC5C,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,MAAM,CAAC,EAAE,MAAM,CAAC;CACZ,GAAG;IAAE,UAAU,EAAE,MAAM,CAAC,MAAM,EAAE,GAAG,CAAC,CAAA;CAAE,CAgB3C"}
|
package/dist/types.d.ts
ADDED
|
@@ -0,0 +1,237 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* TypeScript Type Definitions for ArmorDesk SDK
|
|
3
|
+
*/
|
|
4
|
+
export interface ArmorDeskClientOptions {
|
|
5
|
+
/**
|
|
6
|
+
* Base URL of ArmorDesk Control Plane instance
|
|
7
|
+
* Default: "https://armordesk.crusts.dev"
|
|
8
|
+
*/
|
|
9
|
+
baseUrl?: string;
|
|
10
|
+
/**
|
|
11
|
+
* ArmorIQ API Key or Pro Key (ak_live_..., ak_test_...)
|
|
12
|
+
*/
|
|
13
|
+
apiKey?: string;
|
|
14
|
+
/**
|
|
15
|
+
* Tenant identifier for multi-tenant isolation
|
|
16
|
+
* Default: "acme-corp"
|
|
17
|
+
*/
|
|
18
|
+
tenantId?: string;
|
|
19
|
+
/**
|
|
20
|
+
* Default requesting user name
|
|
21
|
+
*/
|
|
22
|
+
userName?: string;
|
|
23
|
+
/**
|
|
24
|
+
* Default requesting user role ('manager' | 'intern' | 'auditor')
|
|
25
|
+
*/
|
|
26
|
+
userRole?: string;
|
|
27
|
+
/**
|
|
28
|
+
* Optional custom fetch implementation
|
|
29
|
+
*/
|
|
30
|
+
fetch?: typeof fetch;
|
|
31
|
+
}
|
|
32
|
+
export interface ArmorDeskStatus {
|
|
33
|
+
status: string;
|
|
34
|
+
service: string;
|
|
35
|
+
version: string;
|
|
36
|
+
armoriq_pro_active: boolean;
|
|
37
|
+
mode: string;
|
|
38
|
+
slack_configured: boolean;
|
|
39
|
+
active_tenants: number;
|
|
40
|
+
timestamp: string;
|
|
41
|
+
}
|
|
42
|
+
export interface TenantInfo {
|
|
43
|
+
id: string;
|
|
44
|
+
name: string;
|
|
45
|
+
spend_limit: number;
|
|
46
|
+
policy_rules: Record<string, any>;
|
|
47
|
+
balance: number;
|
|
48
|
+
currency: string;
|
|
49
|
+
}
|
|
50
|
+
export interface TraceItem {
|
|
51
|
+
id: string;
|
|
52
|
+
tenant_id: string;
|
|
53
|
+
user_role: string;
|
|
54
|
+
user_name: string;
|
|
55
|
+
agent_name: string;
|
|
56
|
+
prompt: string;
|
|
57
|
+
action: string;
|
|
58
|
+
status: "ALLOWED" | "HELD_FOR_APPROVAL" | "BLOCKED" | string;
|
|
59
|
+
reason: string;
|
|
60
|
+
plan_hash: string;
|
|
61
|
+
merkle_root: string;
|
|
62
|
+
metadata: Record<string, any>;
|
|
63
|
+
created_at: string;
|
|
64
|
+
}
|
|
65
|
+
export interface ApprovalItem {
|
|
66
|
+
delegation_id: string;
|
|
67
|
+
tenant_id: string;
|
|
68
|
+
requested_by: string;
|
|
69
|
+
role: string;
|
|
70
|
+
amount: number;
|
|
71
|
+
recipient: string;
|
|
72
|
+
description: string;
|
|
73
|
+
action_type: string;
|
|
74
|
+
status: "HELD_FOR_APPROVAL" | "APPROVED" | "REJECTED";
|
|
75
|
+
plan_hash: string;
|
|
76
|
+
payload: Record<string, any>;
|
|
77
|
+
created_at: string;
|
|
78
|
+
resolved_at?: string;
|
|
79
|
+
resolved_by?: string;
|
|
80
|
+
}
|
|
81
|
+
export interface ApprovalActionRequest {
|
|
82
|
+
action: "APPROVE" | "REJECT";
|
|
83
|
+
user_role?: string;
|
|
84
|
+
user_name?: string;
|
|
85
|
+
notes?: string;
|
|
86
|
+
}
|
|
87
|
+
export interface ReceiptItem {
|
|
88
|
+
id: string;
|
|
89
|
+
tenant_id: string;
|
|
90
|
+
delegation_id?: string;
|
|
91
|
+
action_type: string;
|
|
92
|
+
amount: number;
|
|
93
|
+
recipient: string;
|
|
94
|
+
status: string;
|
|
95
|
+
plan_hash: string;
|
|
96
|
+
merkle_root: string;
|
|
97
|
+
allowed_spec: Record<string, any>;
|
|
98
|
+
actual_execution: Record<string, any>;
|
|
99
|
+
signature: string;
|
|
100
|
+
verified: boolean;
|
|
101
|
+
created_at: string;
|
|
102
|
+
}
|
|
103
|
+
export interface VerifyProofRequest {
|
|
104
|
+
plan_hash: string;
|
|
105
|
+
merkle_root: string;
|
|
106
|
+
signature: string;
|
|
107
|
+
allowed_spec: Record<string, any>;
|
|
108
|
+
actual_execution: Record<string, any>;
|
|
109
|
+
}
|
|
110
|
+
export interface VerifyProofResponse {
|
|
111
|
+
valid: boolean;
|
|
112
|
+
computed_plan_hash: string;
|
|
113
|
+
computed_merkle_root: string;
|
|
114
|
+
matches_hash: boolean;
|
|
115
|
+
matches_merkle: boolean;
|
|
116
|
+
status: string;
|
|
117
|
+
details: string;
|
|
118
|
+
}
|
|
119
|
+
export interface MCPToolDef {
|
|
120
|
+
name: string;
|
|
121
|
+
description: string;
|
|
122
|
+
input_schema: Record<string, any>;
|
|
123
|
+
governing_agent: string;
|
|
124
|
+
tier: "READ_ONLY" | "FINANCIAL" | "WRITE";
|
|
125
|
+
}
|
|
126
|
+
export interface ConnectedAgentItem {
|
|
127
|
+
agent_id: string;
|
|
128
|
+
name: string;
|
|
129
|
+
transport: string;
|
|
130
|
+
status: string;
|
|
131
|
+
capabilities: string[];
|
|
132
|
+
assigned_sandbox: string;
|
|
133
|
+
enforced_policy: string;
|
|
134
|
+
last_heartbeat: string;
|
|
135
|
+
}
|
|
136
|
+
export interface MCPGatewayConfig {
|
|
137
|
+
gateway_url: string;
|
|
138
|
+
sse_url: string;
|
|
139
|
+
protocol_version: string;
|
|
140
|
+
tenant_id: string;
|
|
141
|
+
api_key_masked: string;
|
|
142
|
+
governed_tools: MCPToolDef[];
|
|
143
|
+
connected_agents: ConnectedAgentItem[];
|
|
144
|
+
sample_configs: {
|
|
145
|
+
claude_desktop: string;
|
|
146
|
+
cursor: string;
|
|
147
|
+
python_sdk: string;
|
|
148
|
+
curl: string;
|
|
149
|
+
};
|
|
150
|
+
}
|
|
151
|
+
export interface MCPCallRequest {
|
|
152
|
+
jsonrpc: "2.0";
|
|
153
|
+
id: string | number;
|
|
154
|
+
method: "tools/call" | "tools/list";
|
|
155
|
+
params: {
|
|
156
|
+
name?: string;
|
|
157
|
+
arguments?: Record<string, any>;
|
|
158
|
+
context?: {
|
|
159
|
+
user_role?: string;
|
|
160
|
+
user_name?: string;
|
|
161
|
+
delegation_id?: string;
|
|
162
|
+
};
|
|
163
|
+
};
|
|
164
|
+
}
|
|
165
|
+
export interface MCPCallResponse {
|
|
166
|
+
jsonrpc: "2.0";
|
|
167
|
+
id: string | number;
|
|
168
|
+
result?: {
|
|
169
|
+
content: Array<{
|
|
170
|
+
type: "text";
|
|
171
|
+
text: string;
|
|
172
|
+
}>;
|
|
173
|
+
isError?: boolean;
|
|
174
|
+
governance?: {
|
|
175
|
+
status: "ALLOWED" | "HELD_FOR_APPROVAL" | "BLOCKED";
|
|
176
|
+
reason: string;
|
|
177
|
+
plan_hash: string;
|
|
178
|
+
merkle_root: string;
|
|
179
|
+
delegation_id?: string;
|
|
180
|
+
};
|
|
181
|
+
};
|
|
182
|
+
error?: {
|
|
183
|
+
code: number;
|
|
184
|
+
message: string;
|
|
185
|
+
data?: any;
|
|
186
|
+
};
|
|
187
|
+
}
|
|
188
|
+
export interface ScenarioRunRequest {
|
|
189
|
+
scenario_id: number;
|
|
190
|
+
tenant_id?: string;
|
|
191
|
+
}
|
|
192
|
+
export interface ScenarioStep {
|
|
193
|
+
step: number;
|
|
194
|
+
agent: string;
|
|
195
|
+
tool: string;
|
|
196
|
+
status: string;
|
|
197
|
+
detail: string;
|
|
198
|
+
plan_hash?: string;
|
|
199
|
+
}
|
|
200
|
+
export interface ScenarioRunResponse {
|
|
201
|
+
scenario_id: number;
|
|
202
|
+
scenario_name: string;
|
|
203
|
+
overall_status: string;
|
|
204
|
+
summary: string;
|
|
205
|
+
steps: ScenarioStep[];
|
|
206
|
+
trace_id?: string;
|
|
207
|
+
delegation_id?: string;
|
|
208
|
+
receipt_id?: string;
|
|
209
|
+
}
|
|
210
|
+
export interface CTFSubmitRequest {
|
|
211
|
+
tenant_id?: string;
|
|
212
|
+
attacker_name?: string;
|
|
213
|
+
prompt: string;
|
|
214
|
+
}
|
|
215
|
+
export interface CTFSubmitResponse {
|
|
216
|
+
id: string;
|
|
217
|
+
attacker_name: string;
|
|
218
|
+
prompt: string;
|
|
219
|
+
detected_threat: string;
|
|
220
|
+
blocked: boolean;
|
|
221
|
+
score: number;
|
|
222
|
+
reason: string;
|
|
223
|
+
sub_agent_action: string;
|
|
224
|
+
created_at: string;
|
|
225
|
+
}
|
|
226
|
+
export interface VoiceBriefingResponse {
|
|
227
|
+
success: boolean;
|
|
228
|
+
audio_base64: string;
|
|
229
|
+
fallback_browser_tts: boolean;
|
|
230
|
+
text: string;
|
|
231
|
+
voice_type: string;
|
|
232
|
+
voice_id: string;
|
|
233
|
+
content_type: string;
|
|
234
|
+
script: string;
|
|
235
|
+
pending_count: number;
|
|
236
|
+
}
|
|
237
|
+
//# sourceMappingURL=types.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../src/types.ts"],"names":[],"mappings":"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"}
|
package/package.json
CHANGED
|
@@ -1,6 +1,56 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@crustdev/armordesk",
|
|
3
|
-
"version": "
|
|
4
|
-
"
|
|
5
|
-
"
|
|
6
|
-
|
|
3
|
+
"version": "1.0.0",
|
|
4
|
+
"description": "Official TypeScript SDK and CLI for ArmorDesk: Enterprise AI Agent Control Plane, Governed MCP Gateway, and Cryptographic Trust Center.",
|
|
5
|
+
"main": "./dist/index.js",
|
|
6
|
+
"module": "./dist/index.mjs",
|
|
7
|
+
"types": "./dist/index.d.ts",
|
|
8
|
+
"bin": {
|
|
9
|
+
"armordesk": "./bin/cli.js"
|
|
10
|
+
},
|
|
11
|
+
"exports": {
|
|
12
|
+
".": {
|
|
13
|
+
"types": "./dist/index.d.ts",
|
|
14
|
+
"import": "./dist/index.mjs",
|
|
15
|
+
"require": "./dist/index.js"
|
|
16
|
+
}
|
|
17
|
+
},
|
|
18
|
+
"files": [
|
|
19
|
+
"dist",
|
|
20
|
+
"bin",
|
|
21
|
+
"README.md",
|
|
22
|
+
"LICENSE"
|
|
23
|
+
],
|
|
24
|
+
"scripts": {
|
|
25
|
+
"build": "tsup src/index.ts src/cli.ts --clean --format cjs,esm && tsc --emitDeclarationOnly",
|
|
26
|
+
"prepublishOnly": "npm run build"
|
|
27
|
+
},
|
|
28
|
+
"publishConfig": {
|
|
29
|
+
"access": "public"
|
|
30
|
+
},
|
|
31
|
+
"keywords": [
|
|
32
|
+
"armordesk",
|
|
33
|
+
"armoriq",
|
|
34
|
+
"mcp",
|
|
35
|
+
"model-context-protocol",
|
|
36
|
+
"ai-agent-governance",
|
|
37
|
+
"security",
|
|
38
|
+
"control-plane",
|
|
39
|
+
"cryptographic-proof",
|
|
40
|
+
"merkle-tree",
|
|
41
|
+
"finops",
|
|
42
|
+
"crustdev"
|
|
43
|
+
],
|
|
44
|
+
"author": "Jumarr <rustaman@crusts.dev>",
|
|
45
|
+
"license": "MIT",
|
|
46
|
+
"homepage": "https://armordesk.crusts.dev",
|
|
47
|
+
"repository": {
|
|
48
|
+
"type": "git",
|
|
49
|
+
"url": "https://github.com/Rustaman1280/ArmorDesk"
|
|
50
|
+
},
|
|
51
|
+
"devDependencies": {
|
|
52
|
+
"@types/node": "^22.10.0",
|
|
53
|
+
"tsup": "^8.5.1",
|
|
54
|
+
"typescript": "^5.7.0"
|
|
55
|
+
}
|
|
56
|
+
}
|