@i4ctime/q-ring 0.10.1 → 0.11.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 +17 -3
- package/dist/{chunk-LLMO64FE.js → chunk-A4RZVP3P.js} +363 -223
- package/dist/chunk-A4RZVP3P.js.map +1 -0
- package/dist/{chunk-E46HG5NM.js → chunk-MQM4DLPI.js} +388 -242
- package/dist/chunk-MQM4DLPI.js.map +1 -0
- package/dist/dashboard-FSCJDLJX.js +1313 -0
- package/dist/dashboard-FSCJDLJX.js.map +1 -0
- package/dist/dashboard-OXUD62RV.js +1313 -0
- package/dist/dashboard-OXUD62RV.js.map +1 -0
- package/dist/index.js +26 -154
- package/dist/index.js.map +1 -1
- package/dist/mcp.js +16 -144
- package/dist/mcp.js.map +1 -1
- package/package.json +1 -1
- package/dist/chunk-E46HG5NM.js.map +0 -1
- package/dist/chunk-LLMO64FE.js.map +0 -1
- package/dist/dashboard-73QYM5FU.js +0 -557
- package/dist/dashboard-73QYM5FU.js.map +0 -1
- package/dist/dashboard-CMXRH4AQ.js +0 -557
- package/dist/dashboard-CMXRH4AQ.js.map +0 -1
package/dist/mcp.js
CHANGED
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
#!/usr/bin/env node
|
|
2
2
|
import {
|
|
3
|
+
PACKAGE_VERSION,
|
|
3
4
|
checkDecay,
|
|
4
5
|
checkExecPolicy,
|
|
5
6
|
checkKeyReadPolicy,
|
|
@@ -13,6 +14,7 @@ import {
|
|
|
13
14
|
exportAudit,
|
|
14
15
|
exportSecrets,
|
|
15
16
|
fireHooks,
|
|
17
|
+
forget,
|
|
16
18
|
getEnvelope,
|
|
17
19
|
getExecMaxRuntime,
|
|
18
20
|
getPolicySummary,
|
|
@@ -20,12 +22,15 @@ import {
|
|
|
20
22
|
hasSecret,
|
|
21
23
|
httpRequest,
|
|
22
24
|
listHooks,
|
|
25
|
+
listMemory,
|
|
23
26
|
listSecrets,
|
|
24
27
|
logAudit,
|
|
25
28
|
queryAudit,
|
|
26
29
|
readProjectConfig,
|
|
30
|
+
recall,
|
|
27
31
|
registerHook,
|
|
28
32
|
registry,
|
|
33
|
+
remember,
|
|
29
34
|
removeHook,
|
|
30
35
|
setSecret,
|
|
31
36
|
tunnelCreate,
|
|
@@ -33,7 +38,7 @@ import {
|
|
|
33
38
|
tunnelList,
|
|
34
39
|
tunnelRead,
|
|
35
40
|
verifyAuditChain
|
|
36
|
-
} from "./chunk-
|
|
41
|
+
} from "./chunk-MQM4DLPI.js";
|
|
37
42
|
|
|
38
43
|
// src/mcp.ts
|
|
39
44
|
import { StdioServerTransport } from "@modelcontextprotocol/sdk/server/stdio.js";
|
|
@@ -41,23 +46,6 @@ import { StdioServerTransport } from "@modelcontextprotocol/sdk/server/stdio.js"
|
|
|
41
46
|
// src/mcp/server.ts
|
|
42
47
|
import { McpServer } from "@modelcontextprotocol/sdk/server/mcp.js";
|
|
43
48
|
|
|
44
|
-
// src/version.ts
|
|
45
|
-
import { readFileSync } from "fs";
|
|
46
|
-
import { dirname, join } from "path";
|
|
47
|
-
import { fileURLToPath } from "url";
|
|
48
|
-
function readPackageVersion() {
|
|
49
|
-
try {
|
|
50
|
-
const here = dirname(fileURLToPath(import.meta.url));
|
|
51
|
-
const pkgPath = join(here, "..", "package.json");
|
|
52
|
-
const raw = readFileSync(pkgPath, "utf8");
|
|
53
|
-
const pkg = JSON.parse(raw);
|
|
54
|
-
return typeof pkg.version === "string" ? pkg.version : "0.0.0";
|
|
55
|
-
} catch {
|
|
56
|
-
return "0.0.0";
|
|
57
|
-
}
|
|
58
|
-
}
|
|
59
|
-
var PACKAGE_VERSION = readPackageVersion();
|
|
60
|
-
|
|
61
49
|
// src/mcp/tools/secrets.ts
|
|
62
50
|
import { z as z2 } from "zod";
|
|
63
51
|
|
|
@@ -163,7 +151,7 @@ function estimateEntropy(secret) {
|
|
|
163
151
|
}
|
|
164
152
|
|
|
165
153
|
// src/core/import.ts
|
|
166
|
-
import { readFileSync
|
|
154
|
+
import { readFileSync } from "fs";
|
|
167
155
|
function parseDotenv(content) {
|
|
168
156
|
const result = /* @__PURE__ */ new Map();
|
|
169
157
|
const lines = content.split(/\r?\n/);
|
|
@@ -195,7 +183,7 @@ function parseDotenv(content) {
|
|
|
195
183
|
function importDotenv(filePathOrContent, options = {}) {
|
|
196
184
|
let content;
|
|
197
185
|
try {
|
|
198
|
-
content =
|
|
186
|
+
content = readFileSync(filePathOrContent, "utf8");
|
|
199
187
|
} catch {
|
|
200
188
|
content = filePathOrContent;
|
|
201
189
|
}
|
|
@@ -1983,8 +1971,8 @@ async function execCommand(opts2) {
|
|
|
1983
1971
|
}
|
|
1984
1972
|
|
|
1985
1973
|
// src/core/scan.ts
|
|
1986
|
-
import { readFileSync as
|
|
1987
|
-
import { join
|
|
1974
|
+
import { readFileSync as readFileSync2, readdirSync, statSync } from "fs";
|
|
1975
|
+
import { join } from "path";
|
|
1988
1976
|
|
|
1989
1977
|
// src/core/secrets-detect.ts
|
|
1990
1978
|
var SECRET_ASSIGNMENT_PATTERN = /((?:api_?key|secret|token|password|auth|credential|access_?key)[a-z0-9_]*)\s*[:=]\s*(['"])([^'"]+)\2/gi;
|
|
@@ -2078,7 +2066,7 @@ function scanCodebase(dir) {
|
|
|
2078
2066
|
}
|
|
2079
2067
|
for (const entry of entries) {
|
|
2080
2068
|
if (IGNORE_DIRS.has(entry)) continue;
|
|
2081
|
-
const fullPath =
|
|
2069
|
+
const fullPath = join(currentDir, entry);
|
|
2082
2070
|
let stat;
|
|
2083
2071
|
try {
|
|
2084
2072
|
stat = statSync(fullPath);
|
|
@@ -2092,7 +2080,7 @@ function scanCodebase(dir) {
|
|
|
2092
2080
|
if (IGNORE_EXTS.has(ext) || entry.endsWith(".lock")) continue;
|
|
2093
2081
|
let content;
|
|
2094
2082
|
try {
|
|
2095
|
-
content =
|
|
2083
|
+
content = readFileSync2(fullPath, "utf8");
|
|
2096
2084
|
} catch {
|
|
2097
2085
|
continue;
|
|
2098
2086
|
}
|
|
@@ -2122,7 +2110,7 @@ function scanCodebase(dir) {
|
|
|
2122
2110
|
}
|
|
2123
2111
|
|
|
2124
2112
|
// src/core/linter.ts
|
|
2125
|
-
import { readFileSync as
|
|
2113
|
+
import { readFileSync as readFileSync3, writeFileSync, existsSync } from "fs";
|
|
2126
2114
|
import { basename, extname } from "path";
|
|
2127
2115
|
var ENV_REF_BY_EXT = {
|
|
2128
2116
|
".ts": (k) => `process.env.${k}`,
|
|
@@ -2153,7 +2141,7 @@ function lintFiles(files, opts2 = {}) {
|
|
|
2153
2141
|
if (!existsSync(file)) continue;
|
|
2154
2142
|
let content;
|
|
2155
2143
|
try {
|
|
2156
|
-
content =
|
|
2144
|
+
content = readFileSync3(file, "utf8");
|
|
2157
2145
|
} catch {
|
|
2158
2146
|
continue;
|
|
2159
2147
|
}
|
|
@@ -2351,7 +2339,7 @@ ${result.stderr}`);
|
|
|
2351
2339
|
let dashboardInstance = null;
|
|
2352
2340
|
server2.tool(
|
|
2353
2341
|
"status_dashboard",
|
|
2354
|
-
"[dashboard] Launch the quantum status dashboard \u2014 a local web page showing live health,
|
|
2342
|
+
"[dashboard] Launch the quantum status dashboard \u2014 a local SSE-driven web page showing live KPIs (secrets, env, protected, approvals, hooks, 24h reads, anomalies), health summary, environment, .q-ring.json manifest gaps, governance policy summary, sortable searchable secrets table, decay/superposition/entanglement/tunnel cards, active approvals & hooks, agent memory, anomaly alerts, and a filterable 24h audit feed. Returns the URL to open in a browser. Never exposes secret values.",
|
|
2355
2343
|
{
|
|
2356
2344
|
port: z9.number().optional().default(9876).describe("Port to serve on")
|
|
2357
2345
|
},
|
|
@@ -2363,7 +2351,7 @@ ${result.stderr}`);
|
|
|
2363
2351
|
`Dashboard already running at http://127.0.0.1:${dashboardInstance.port}`
|
|
2364
2352
|
);
|
|
2365
2353
|
}
|
|
2366
|
-
const { startDashboardServer } = await import("./dashboard-
|
|
2354
|
+
const { startDashboardServer } = await import("./dashboard-FSCJDLJX.js");
|
|
2367
2355
|
dashboardInstance = startDashboardServer({ port: params.port });
|
|
2368
2356
|
return text(
|
|
2369
2357
|
`Dashboard started at http://127.0.0.1:${dashboardInstance.port}
|
|
@@ -2392,122 +2380,6 @@ Open this URL in a browser to see live quantum status.`
|
|
|
2392
2380
|
|
|
2393
2381
|
// src/mcp/tools/agent.ts
|
|
2394
2382
|
import { z as z10 } from "zod";
|
|
2395
|
-
|
|
2396
|
-
// src/core/memory.ts
|
|
2397
|
-
import { existsSync as existsSync2, readFileSync as readFileSync5, writeFileSync as writeFileSync2, mkdirSync } from "fs";
|
|
2398
|
-
import { join as join3 } from "path";
|
|
2399
|
-
import { homedir, hostname, userInfo } from "os";
|
|
2400
|
-
import { createCipheriv as createCipheriv2, createDecipheriv as createDecipheriv2, createHash, randomBytes as randomBytes3 } from "crypto";
|
|
2401
|
-
import { Entry } from "@napi-rs/keyring";
|
|
2402
|
-
var MEMORY_FILE = "agent-memory.enc";
|
|
2403
|
-
var KEYRING_SERVICE = "qring-memory-key";
|
|
2404
|
-
var KEYRING_ACCOUNT = "encryption-key";
|
|
2405
|
-
function getMemoryDir() {
|
|
2406
|
-
const dir = join3(homedir(), ".config", "q-ring");
|
|
2407
|
-
if (!existsSync2(dir)) {
|
|
2408
|
-
mkdirSync(dir, { recursive: true });
|
|
2409
|
-
}
|
|
2410
|
-
return dir;
|
|
2411
|
-
}
|
|
2412
|
-
function getMemoryPath() {
|
|
2413
|
-
return join3(getMemoryDir(), MEMORY_FILE);
|
|
2414
|
-
}
|
|
2415
|
-
function deriveLegacyKey() {
|
|
2416
|
-
const fingerprint = `qring-memory:${hostname()}:${userInfo().username}`;
|
|
2417
|
-
return createHash("sha256").update(fingerprint).digest();
|
|
2418
|
-
}
|
|
2419
|
-
function getOrCreateKey() {
|
|
2420
|
-
try {
|
|
2421
|
-
const entry = new Entry(KEYRING_SERVICE, KEYRING_ACCOUNT);
|
|
2422
|
-
const stored = entry.getPassword();
|
|
2423
|
-
if (stored) return Buffer.from(stored, "base64");
|
|
2424
|
-
const key = randomBytes3(32);
|
|
2425
|
-
entry.setPassword(key.toString("base64"));
|
|
2426
|
-
return key;
|
|
2427
|
-
} catch {
|
|
2428
|
-
console.warn("[q-ring] OS keyring unavailable for memory key \u2014 falling back to machine-derived key");
|
|
2429
|
-
return deriveLegacyKey();
|
|
2430
|
-
}
|
|
2431
|
-
}
|
|
2432
|
-
function encryptWith(data, key) {
|
|
2433
|
-
const iv = randomBytes3(12);
|
|
2434
|
-
const cipher = createCipheriv2("aes-256-gcm", key, iv);
|
|
2435
|
-
const encrypted = Buffer.concat([cipher.update(data, "utf8"), cipher.final()]);
|
|
2436
|
-
const tag = cipher.getAuthTag();
|
|
2437
|
-
return `${iv.toString("base64")}:${tag.toString("base64")}:${encrypted.toString("base64")}`;
|
|
2438
|
-
}
|
|
2439
|
-
function decryptWith(blob, key) {
|
|
2440
|
-
const parts = blob.split(":");
|
|
2441
|
-
if (parts.length !== 3) throw new Error("Invalid encrypted format");
|
|
2442
|
-
const iv = Buffer.from(parts[0], "base64");
|
|
2443
|
-
const tag = Buffer.from(parts[1], "base64");
|
|
2444
|
-
const encrypted = Buffer.from(parts[2], "base64");
|
|
2445
|
-
const decipher = createDecipheriv2("aes-256-gcm", key, iv);
|
|
2446
|
-
decipher.setAuthTag(tag);
|
|
2447
|
-
return decipher.update(encrypted) + decipher.final("utf8");
|
|
2448
|
-
}
|
|
2449
|
-
function encrypt(data) {
|
|
2450
|
-
return encryptWith(data, getOrCreateKey());
|
|
2451
|
-
}
|
|
2452
|
-
function decrypt(blob) {
|
|
2453
|
-
const key = getOrCreateKey();
|
|
2454
|
-
try {
|
|
2455
|
-
return decryptWith(blob, key);
|
|
2456
|
-
} catch {
|
|
2457
|
-
const legacy = deriveLegacyKey();
|
|
2458
|
-
const plain = decryptWith(blob, legacy);
|
|
2459
|
-
writeFileSync2(getMemoryPath(), encryptWith(plain, key), "utf8");
|
|
2460
|
-
return plain;
|
|
2461
|
-
}
|
|
2462
|
-
}
|
|
2463
|
-
function loadStore() {
|
|
2464
|
-
const path = getMemoryPath();
|
|
2465
|
-
if (!existsSync2(path)) {
|
|
2466
|
-
return { entries: {} };
|
|
2467
|
-
}
|
|
2468
|
-
try {
|
|
2469
|
-
const raw = readFileSync5(path, "utf8");
|
|
2470
|
-
const decrypted = decrypt(raw);
|
|
2471
|
-
return JSON.parse(decrypted);
|
|
2472
|
-
} catch {
|
|
2473
|
-
return { entries: {} };
|
|
2474
|
-
}
|
|
2475
|
-
}
|
|
2476
|
-
function saveStore(store) {
|
|
2477
|
-
const json = JSON.stringify(store);
|
|
2478
|
-
const encrypted = encrypt(json);
|
|
2479
|
-
writeFileSync2(getMemoryPath(), encrypted, "utf8");
|
|
2480
|
-
}
|
|
2481
|
-
function remember(key, value) {
|
|
2482
|
-
const store = loadStore();
|
|
2483
|
-
store.entries[key] = {
|
|
2484
|
-
value,
|
|
2485
|
-
updatedAt: (/* @__PURE__ */ new Date()).toISOString()
|
|
2486
|
-
};
|
|
2487
|
-
saveStore(store);
|
|
2488
|
-
}
|
|
2489
|
-
function recall(key) {
|
|
2490
|
-
const store = loadStore();
|
|
2491
|
-
return store.entries[key]?.value ?? null;
|
|
2492
|
-
}
|
|
2493
|
-
function listMemory() {
|
|
2494
|
-
const store = loadStore();
|
|
2495
|
-
return Object.entries(store.entries).map(([key, entry]) => ({
|
|
2496
|
-
key,
|
|
2497
|
-
updatedAt: entry.updatedAt
|
|
2498
|
-
}));
|
|
2499
|
-
}
|
|
2500
|
-
function forget(key) {
|
|
2501
|
-
const store = loadStore();
|
|
2502
|
-
if (key in store.entries) {
|
|
2503
|
-
delete store.entries[key];
|
|
2504
|
-
saveStore(store);
|
|
2505
|
-
return true;
|
|
2506
|
-
}
|
|
2507
|
-
return false;
|
|
2508
|
-
}
|
|
2509
|
-
|
|
2510
|
-
// src/mcp/tools/agent.ts
|
|
2511
2383
|
function registerAgentTools(server2) {
|
|
2512
2384
|
server2.tool(
|
|
2513
2385
|
"agent_remember",
|