knosky 0.6.3 → 0.7.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/CHANGELOG.md +149 -93
- package/CREDITS.md +14 -14
- package/LICENSE.md +76 -76
- package/LIMITATIONS.md +33 -23
- package/PRIVACY.md +30 -30
- package/README.md +170 -117
- package/SECURITY.md +78 -46
- package/action/post-comment.mjs +94 -89
- package/action.yml +62 -62
- package/bin/knosky.mjs +279 -105
- package/core/CONTRACT.md +70 -70
- package/core/append-only-checkpoint.mjs +215 -0
- package/core/audit-writer.mjs +317 -0
- package/core/benchmark-results.mjs +225 -225
- package/core/bundle.mjs +178 -178
- package/core/churn.mjs +23 -23
- package/core/ci.mjs +268 -268
- package/core/comparison.mjs +189 -189
- package/core/config.mjs +189 -189
- package/core/constants.mjs +13 -13
- package/core/contract.mjs +123 -123
- package/core/cross-repo.mjs +111 -111
- package/core/decision-codes.mjs +92 -0
- package/core/destination.mjs +161 -161
- package/core/district-classification.mjs +111 -0
- package/core/doctor-scorecard.mjs +369 -0
- package/core/domain-store.mjs +347 -0
- package/core/edges.mjs +43 -43
- package/core/escalate.mjs +68 -68
- package/core/freshness.mjs +198 -194
- package/core/fs-indexer.mjs +218 -218
- package/core/key-store.mjs +348 -348
- package/core/layout.mjs +46 -46
- package/core/ledger.mjs +176 -141
- package/core/local-ipc-identity.mjs +500 -0
- package/core/lod.mjs +155 -155
- package/core/mode-b.mjs +410 -0
- package/core/multi-model-benchmark.mjs +405 -405
- package/core/net-lockdown.mjs +421 -0
- package/core/onboarding.mjs +223 -223
- package/core/operator-auth.mjs +317 -0
- package/core/overlays.mjs +45 -45
- package/core/policy-lattice.mjs +142 -0
- package/core/pr-comment.mjs +198 -198
- package/core/protocol-spec.mjs +460 -460
- package/core/provenance.mjs +320 -0
- package/core/retrieve.mjs +63 -63
- package/core/route.mjs +304 -304
- package/core/schema.mjs +275 -275
- package/core/signing-tiers.mjs +1265 -0
- package/core/swarm-bench.mjs +106 -0
- package/core/swarm-coordinator.mjs +867 -0
- package/core/trust-root-rekey.mjs +410 -0
- package/mcp/server.mjs +264 -108
- package/package.json +56 -46
- package/renderer/art/kenney/buildingTiles_sheet.xml +130 -130
- package/renderer/art/kenney/cityDetails_sheet.xml +12 -12
- package/renderer/art/kenney/landscapeTiles_sheet.xml +129 -129
- package/renderer/art/kenney/sheet_allCars.xml +545 -545
- package/renderer/build-rich.mjs +43 -43
- package/renderer/city.template.html +808 -808
- package/ssot/decision-codes.json +133 -0
- package/ssot/ladder-l0-l3.md +232 -0
- package/ssot/tool-menu.json +130 -0
package/mcp/server.mjs
CHANGED
|
@@ -1,108 +1,264 @@
|
|
|
1
|
-
// Knowledge City — local stdio MCP server (
|
|
2
|
-
// Read-
|
|
3
|
-
import { McpServer } from "@modelcontextprotocol/sdk/server/mcp.js";
|
|
4
|
-
import { StdioServerTransport } from "@modelcontextprotocol/sdk/server/stdio.js";
|
|
5
|
-
import { z } from "zod";
|
|
6
|
-
import { load, search, getNode, listCategories, getProvenance, getRelated } from "../core/retrieve.mjs";
|
|
7
|
-
import {
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
})
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
});
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
}
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
return
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
}
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
}
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
});
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
1
|
+
// Knowledge City — local stdio MCP server (Mode B + DEC-108 menu freeze).
|
|
2
|
+
// Read-mostly local index. No network; data never leaves the machine by default.
|
|
3
|
+
import { McpServer } from "@modelcontextprotocol/sdk/server/mcp.js";
|
|
4
|
+
import { StdioServerTransport } from "@modelcontextprotocol/sdk/server/stdio.js";
|
|
5
|
+
import { z } from "zod";
|
|
6
|
+
import { load, search, getNode, listCategories, getProvenance, getRelated } from "../core/retrieve.mjs";
|
|
7
|
+
import { createModeBDoor } from "../core/mode-b.mjs";
|
|
8
|
+
import { queryAudit, verifyAuditChain } from "../core/audit-writer.mjs";
|
|
9
|
+
import { closedSet } from "../core/decision-codes.mjs";
|
|
10
|
+
import { readFileSync } from "node:fs";
|
|
11
|
+
import { dirname, join } from "node:path";
|
|
12
|
+
import { fileURLToPath } from "node:url";
|
|
13
|
+
|
|
14
|
+
const CITY = process.env.KC_CITY || process.argv[2];
|
|
15
|
+
if (!CITY) {
|
|
16
|
+
console.error("Knowledge City MCP: set KC_CITY (or pass a path) to a city-data.v2.json");
|
|
17
|
+
process.exit(1);
|
|
18
|
+
}
|
|
19
|
+
|
|
20
|
+
const PROFILE = (process.env.KC_PROFILE || "coding").toLowerCase(); // coding | security | advisory
|
|
21
|
+
const DOMAIN = process.env.KC_DOMAIN || undefined;
|
|
22
|
+
|
|
23
|
+
let ctx;
|
|
24
|
+
try {
|
|
25
|
+
ctx = load(CITY);
|
|
26
|
+
} catch (err) {
|
|
27
|
+
console.error("Knowledge City MCP: failed to load city:", err && err.message ? err.message : err);
|
|
28
|
+
process.exit(1);
|
|
29
|
+
}
|
|
30
|
+
|
|
31
|
+
const door = createModeBDoor({
|
|
32
|
+
cityCtx: ctx,
|
|
33
|
+
cityPath: CITY,
|
|
34
|
+
domainRoot: DOMAIN,
|
|
35
|
+
profile: PROFILE,
|
|
36
|
+
});
|
|
37
|
+
|
|
38
|
+
const HERE = dirname(fileURLToPath(import.meta.url));
|
|
39
|
+
const SSOT_MENU = join(HERE, "..", "ssot", "tool-menu.json");
|
|
40
|
+
let menuVersion = "1.0.0";
|
|
41
|
+
try {
|
|
42
|
+
menuVersion = JSON.parse(readFileSync(SSOT_MENU, "utf8")).version || menuVersion;
|
|
43
|
+
} catch {
|
|
44
|
+
/* optional */
|
|
45
|
+
}
|
|
46
|
+
|
|
47
|
+
const server = new McpServer({ name: "knosky", version: "0.7.0-modeb" });
|
|
48
|
+
|
|
49
|
+
function textResult(obj) {
|
|
50
|
+
const text = typeof obj === "string" ? obj : JSON.stringify(obj, null, 2);
|
|
51
|
+
return { content: [{ type: "text", text }], structuredContent: typeof obj === "object" ? obj : { text } };
|
|
52
|
+
}
|
|
53
|
+
|
|
54
|
+
function modeALabel() {
|
|
55
|
+
return PROFILE === "advisory"
|
|
56
|
+
? " [Mode A advisory — non-authorizing]"
|
|
57
|
+
: " [Tier 0 map — non-authorizing unless combined with Mode B tools]";
|
|
58
|
+
}
|
|
59
|
+
|
|
60
|
+
// --- Tier 0 map tools (non-authorizing) ---
|
|
61
|
+
|
|
62
|
+
server.registerTool("kc_search", {
|
|
63
|
+
title: "Search the Knowledge City",
|
|
64
|
+
description:
|
|
65
|
+
"Search the indexed knowledge base by keywords. Returns ranked items with provenance citations." +
|
|
66
|
+
modeALabel() +
|
|
67
|
+
" Navigation, not full-text code search. Not a Mode B authorization.",
|
|
68
|
+
inputSchema: {
|
|
69
|
+
query: z.string().max(500).describe("keywords"),
|
|
70
|
+
limit: z.number().int().min(1).max(50).optional().describe("max results (default 10, max 50)"),
|
|
71
|
+
category: z.string().max(200).optional().describe("restrict to one category id"),
|
|
72
|
+
},
|
|
73
|
+
annotations: { readOnlyHint: true, openWorldHint: false },
|
|
74
|
+
}, async ({ query, limit, category }) => {
|
|
75
|
+
const hits = search(ctx, String(query).slice(0, 500), {
|
|
76
|
+
limit: Math.min(Math.max(1, limit || 10), 50),
|
|
77
|
+
category: category ? String(category).slice(0, 200) : null,
|
|
78
|
+
});
|
|
79
|
+
const text = hits.length
|
|
80
|
+
? hits
|
|
81
|
+
.map(
|
|
82
|
+
(h) =>
|
|
83
|
+
`- [${h.category}] ${h.title} — ${h.summary || ""}\n source: ${h.provenance.ref} @ ${h.provenance.source_rev} (id: ${h.id})`,
|
|
84
|
+
)
|
|
85
|
+
.join("\n")
|
|
86
|
+
: "No matches.";
|
|
87
|
+
return {
|
|
88
|
+
content: [{ type: "text", text: text + "\n\n(decision_code hint: ADVISORY_UNAUTH / non-authorizing map)" }],
|
|
89
|
+
structuredContent: { results: hits, decision_code: "ADVISORY_UNAUTH", mode: "A", authorizing: false },
|
|
90
|
+
};
|
|
91
|
+
});
|
|
92
|
+
|
|
93
|
+
server.registerTool("kc_get_node", {
|
|
94
|
+
title: "Get one item",
|
|
95
|
+
description: "Fetch a single indexed item by id with provenance." + modeALabel(),
|
|
96
|
+
inputSchema: { id: z.string().max(400).describe("node id, e.g. fs:src/index.ts") },
|
|
97
|
+
annotations: { readOnlyHint: true },
|
|
98
|
+
}, async ({ id }) => {
|
|
99
|
+
const n = getNode(ctx, id);
|
|
100
|
+
return textResult(
|
|
101
|
+
n
|
|
102
|
+
? { ...n, decision_code: "ADVISORY_UNAUTH", mode: "A", authorizing: false }
|
|
103
|
+
: { error: `No item with id ${id}`, decision_code: "ERROR_INVALID_INPUT" },
|
|
104
|
+
);
|
|
105
|
+
});
|
|
106
|
+
|
|
107
|
+
server.registerTool("kc_list_categories", {
|
|
108
|
+
title: "List categories",
|
|
109
|
+
description: "List knowledge categories (city districts) with item counts." + modeALabel(),
|
|
110
|
+
inputSchema: {},
|
|
111
|
+
annotations: { readOnlyHint: true },
|
|
112
|
+
}, async () => {
|
|
113
|
+
const cats = listCategories(ctx);
|
|
114
|
+
return {
|
|
115
|
+
content: [{ type: "text", text: cats.map((c) => `${c.label} (${c.id}): ${c.count}`).join("\n") }],
|
|
116
|
+
structuredContent: { categories: cats, decision_code: "ADVISORY_UNAUTH", mode: "A", authorizing: false },
|
|
117
|
+
};
|
|
118
|
+
});
|
|
119
|
+
|
|
120
|
+
server.registerTool("kc_get_provenance", {
|
|
121
|
+
title: "Get provenance (citation)",
|
|
122
|
+
description: "Citation for an item: live source ref + revision + links." + modeALabel(),
|
|
123
|
+
inputSchema: { id: z.string().max(400) },
|
|
124
|
+
annotations: { readOnlyHint: true },
|
|
125
|
+
}, async ({ id }) => {
|
|
126
|
+
const p = getProvenance(ctx, id);
|
|
127
|
+
return textResult(
|
|
128
|
+
p
|
|
129
|
+
? { ...p, decision_code: "ADVISORY_UNAUTH", mode: "A", authorizing: false }
|
|
130
|
+
: { error: `No item with id ${id}`, decision_code: "ERROR_INVALID_INPUT" },
|
|
131
|
+
);
|
|
132
|
+
});
|
|
133
|
+
|
|
134
|
+
server.registerTool("kc_related", {
|
|
135
|
+
title: "Related files (connections)",
|
|
136
|
+
description: "Imports / importers / churn for a file." + modeALabel(),
|
|
137
|
+
inputSchema: { id: z.string().max(400).describe("node id, e.g. fs:src/auth.js") },
|
|
138
|
+
annotations: { readOnlyHint: true },
|
|
139
|
+
}, async ({ id }) => {
|
|
140
|
+
const r = getRelated(ctx, id);
|
|
141
|
+
if (!r) return textResult({ error: "No item with id " + id, decision_code: "ERROR_INVALID_INPUT" });
|
|
142
|
+
const NL = String.fromCharCode(10);
|
|
143
|
+
const lines = [r.title + " (" + id + ")"];
|
|
144
|
+
if (r.churn) lines.push("recent changes: " + r.churn.c + " commit(s), heat " + r.churn.b);
|
|
145
|
+
lines.push("imports (" + r.imports.length + "): " + (r.imports.map((x) => x.source || x.id).join(", ") || "none"));
|
|
146
|
+
lines.push(
|
|
147
|
+
"imported by (" + r.importedBy.length + "): " + (r.importedBy.map((x) => x.source || x.id).join(", ") || "none"),
|
|
148
|
+
);
|
|
149
|
+
return {
|
|
150
|
+
content: [{ type: "text", text: lines.join(NL) }],
|
|
151
|
+
structuredContent: { ...r, decision_code: "ADVISORY_UNAUTH", mode: "A", authorizing: false },
|
|
152
|
+
};
|
|
153
|
+
});
|
|
154
|
+
|
|
155
|
+
// --- Tier 1 governed tools ---
|
|
156
|
+
|
|
157
|
+
const leaseFields = {
|
|
158
|
+
leaseId: z.string().max(200).optional().describe("Server-issued lease id (Mode B). Required when KC_PROFILE!=advisory."),
|
|
159
|
+
agentId: z
|
|
160
|
+
.string()
|
|
161
|
+
.max(200)
|
|
162
|
+
.optional()
|
|
163
|
+
.describe("Optional agent id claim — NEVER trusted alone; must match lease record"),
|
|
164
|
+
advisory: z.boolean().optional().describe("Force Mode A ADVISORY_UNAUTH path"),
|
|
165
|
+
};
|
|
166
|
+
|
|
167
|
+
server.registerTool("kc_route", {
|
|
168
|
+
title: "Route to a destination (agent GPS)",
|
|
169
|
+
description:
|
|
170
|
+
"Mode B (default coding profile): identity + policy + audit receipt then ALLOW authorized subgraph or DENY_*. " +
|
|
171
|
+
"Mode A when profile=advisory or advisory=true: ADVISORY_UNAUTH labeled tips only. " +
|
|
172
|
+
"Structural navigation with citations; does not replace reading live files. Decision codes: " +
|
|
173
|
+
closedSet().join(", "),
|
|
174
|
+
inputSchema: {
|
|
175
|
+
destination: z.string().max(400).describe("navigation target — file:, folder:, or keywords"),
|
|
176
|
+
limit: z.number().int().min(1).max(20).optional().describe("max route entries (default 8)"),
|
|
177
|
+
...leaseFields,
|
|
178
|
+
},
|
|
179
|
+
annotations: { readOnlyHint: true, openWorldHint: false },
|
|
180
|
+
}, async ({ destination, limit, leaseId, agentId, advisory }) => {
|
|
181
|
+
const env = door.handle({
|
|
182
|
+
tool: "route",
|
|
183
|
+
destination,
|
|
184
|
+
limit,
|
|
185
|
+
leaseId,
|
|
186
|
+
agentId: agentId ?? null,
|
|
187
|
+
advisory: !!advisory,
|
|
188
|
+
});
|
|
189
|
+
return textResult(env);
|
|
190
|
+
});
|
|
191
|
+
|
|
192
|
+
server.registerTool("kc_bundle", {
|
|
193
|
+
title: "Build intent bundle (share-safe pointers)",
|
|
194
|
+
description:
|
|
195
|
+
"Mode B: package a small pointer bundle (intent-manifest) under identity+policy+audit; fail-closed secret scan. " +
|
|
196
|
+
"Not available as authorizing in pure advisory profile.",
|
|
197
|
+
inputSchema: {
|
|
198
|
+
destination: z.string().max(400).optional().describe("optional GPS destination used to pick node ids"),
|
|
199
|
+
nodeIds: z.array(z.string().max(400)).optional().describe("explicit node ids to include"),
|
|
200
|
+
root: z.string().max(1000).optional().describe("repo root for secret scan / sha256"),
|
|
201
|
+
...leaseFields,
|
|
202
|
+
},
|
|
203
|
+
annotations: { readOnlyHint: true, openWorldHint: false },
|
|
204
|
+
}, async ({ destination, nodeIds, root, leaseId, agentId, advisory }) => {
|
|
205
|
+
const env = door.handle({
|
|
206
|
+
tool: "bundle",
|
|
207
|
+
destination,
|
|
208
|
+
nodeIds,
|
|
209
|
+
root: root || process.env.KC_ROOT || null,
|
|
210
|
+
leaseId,
|
|
211
|
+
agentId: agentId ?? null,
|
|
212
|
+
advisory: !!advisory,
|
|
213
|
+
});
|
|
214
|
+
return textResult(env);
|
|
215
|
+
});
|
|
216
|
+
|
|
217
|
+
server.registerTool("kc_policy_check", {
|
|
218
|
+
title: "Dry-run policy check",
|
|
219
|
+
description: "Mode B: would this destination be allowed for the bound agent? Returns decision codes without full route body preference.",
|
|
220
|
+
inputSchema: {
|
|
221
|
+
destination: z.string().max(400),
|
|
222
|
+
...leaseFields,
|
|
223
|
+
},
|
|
224
|
+
annotations: { readOnlyHint: true, openWorldHint: false },
|
|
225
|
+
}, async ({ destination, leaseId, agentId, advisory }) => {
|
|
226
|
+
const env = door.handle({
|
|
227
|
+
tool: "policy_check",
|
|
228
|
+
destination,
|
|
229
|
+
leaseId,
|
|
230
|
+
agentId: agentId ?? null,
|
|
231
|
+
advisory: !!advisory,
|
|
232
|
+
});
|
|
233
|
+
return textResult(env);
|
|
234
|
+
});
|
|
235
|
+
|
|
236
|
+
// --- Security profile only ---
|
|
237
|
+
if (PROFILE === "security") {
|
|
238
|
+
server.registerTool("kc_audit_query", {
|
|
239
|
+
title: "Query local audit receipts",
|
|
240
|
+
description: "Security profile only. Metadata-only audit events for this local trust domain.",
|
|
241
|
+
inputSchema: {
|
|
242
|
+
limit: z.number().int().min(1).max(200).optional(),
|
|
243
|
+
agent_id: z.string().max(200).optional(),
|
|
244
|
+
},
|
|
245
|
+
annotations: { readOnlyHint: true },
|
|
246
|
+
}, async ({ limit, agent_id }) => {
|
|
247
|
+
const rows = queryAudit(door.domainRoot, { limit, agent_id });
|
|
248
|
+
return textResult({ events: rows, domain: door.domainRoot });
|
|
249
|
+
});
|
|
250
|
+
|
|
251
|
+
server.registerTool("kc_audit_verify", {
|
|
252
|
+
title: "Verify audit chain",
|
|
253
|
+
description: "Security profile only. Verify hash chain of local audit ledger.",
|
|
254
|
+
inputSchema: {},
|
|
255
|
+
annotations: { readOnlyHint: true },
|
|
256
|
+
}, async () => {
|
|
257
|
+
return textResult(verifyAuditChain(door.domainRoot));
|
|
258
|
+
});
|
|
259
|
+
}
|
|
260
|
+
|
|
261
|
+
await server.connect(new StdioServerTransport());
|
|
262
|
+
console.error(
|
|
263
|
+
`knosky MCP ready — profile=${PROFILE} ssot=${menuVersion} nodes=${ctx.city.node_count} domain=${door.domainRoot}`,
|
|
264
|
+
);
|
package/package.json
CHANGED
|
@@ -1,46 +1,56 @@
|
|
|
1
|
-
{
|
|
2
|
-
"name": "knosky",
|
|
3
|
-
"version": "0.
|
|
4
|
-
"description": "
|
|
5
|
-
"type": "module",
|
|
6
|
-
"bin": {
|
|
7
|
-
"knosky": "bin/knosky.mjs"
|
|
8
|
-
},
|
|
9
|
-
"files": [
|
|
10
|
-
"
|
|
11
|
-
"
|
|
12
|
-
"
|
|
13
|
-
"
|
|
14
|
-
"
|
|
15
|
-
"
|
|
16
|
-
"
|
|
17
|
-
"
|
|
18
|
-
"
|
|
19
|
-
"
|
|
20
|
-
"
|
|
21
|
-
"
|
|
22
|
-
"
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
"
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
"
|
|
33
|
-
"
|
|
34
|
-
"
|
|
35
|
-
"
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
"
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
"
|
|
44
|
-
"
|
|
45
|
-
|
|
46
|
-
|
|
1
|
+
{
|
|
2
|
+
"name": "knosky",
|
|
3
|
+
"version": "0.7.0",
|
|
4
|
+
"description": "Local-first agentic GPS for repos: map + Mode B governed MCP routes (identity, policy, audit). Free protocol.",
|
|
5
|
+
"type": "module",
|
|
6
|
+
"bin": {
|
|
7
|
+
"knosky": "bin/knosky.mjs"
|
|
8
|
+
},
|
|
9
|
+
"files": [
|
|
10
|
+
"CHANGELOG.md",
|
|
11
|
+
"CREDITS.md",
|
|
12
|
+
"LICENSE.md",
|
|
13
|
+
"LIMITATIONS.md",
|
|
14
|
+
"PRIVACY.md",
|
|
15
|
+
"README.md",
|
|
16
|
+
"SECURITY.md",
|
|
17
|
+
"action",
|
|
18
|
+
"action.yml",
|
|
19
|
+
"bin",
|
|
20
|
+
"core",
|
|
21
|
+
"mcp/server.mjs",
|
|
22
|
+
"renderer",
|
|
23
|
+
"ssot"
|
|
24
|
+
],
|
|
25
|
+
"engines": {
|
|
26
|
+
"node": ">=20"
|
|
27
|
+
},
|
|
28
|
+
"dependencies": {
|
|
29
|
+
"@modelcontextprotocol/sdk": "^1.12.0",
|
|
30
|
+
"zod": "^3.23.8",
|
|
31
|
+
"@simplewebauthn/server": "^13.3.2",
|
|
32
|
+
"otplib": "^13.4.1",
|
|
33
|
+
"@otplib/plugin-crypto-node": "^13.4.1",
|
|
34
|
+
"@levischuck/tiny-cbor": "^0.2.2",
|
|
35
|
+
"@peculiar/x509": "^1.14.3"
|
|
36
|
+
},
|
|
37
|
+
"keywords": [
|
|
38
|
+
"repo-map",
|
|
39
|
+
"codebase-visualization",
|
|
40
|
+
"mcp",
|
|
41
|
+
"ai",
|
|
42
|
+
"citations",
|
|
43
|
+
"local-first",
|
|
44
|
+
"developer-tools"
|
|
45
|
+
],
|
|
46
|
+
"license": "SEE LICENSE IN LICENSE.md",
|
|
47
|
+
"homepage": "https://knosky.com",
|
|
48
|
+
"repository": {
|
|
49
|
+
"type": "git",
|
|
50
|
+
"url": "git+https://github.com/SathiaAI/knosky.git"
|
|
51
|
+
},
|
|
52
|
+
"devDependencies": {
|
|
53
|
+
"@peculiar/asn1-ecc": "^2.6.1",
|
|
54
|
+
"@peculiar/asn1-schema": "^2.6.0"
|
|
55
|
+
}
|
|
56
|
+
}
|