kodingo-cli 1.0.25 → 1.0.27
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.
|
@@ -4,6 +4,39 @@
|
|
|
4
4
|
* Drop-in replacement for memory-persistence.ts — same function signatures,
|
|
5
5
|
* same return types, but talks to kodingo-api over HTTP instead of psql.
|
|
6
6
|
*/
|
|
7
|
+
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
|
|
8
|
+
if (k2 === undefined) k2 = k;
|
|
9
|
+
var desc = Object.getOwnPropertyDescriptor(m, k);
|
|
10
|
+
if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
|
|
11
|
+
desc = { enumerable: true, get: function() { return m[k]; } };
|
|
12
|
+
}
|
|
13
|
+
Object.defineProperty(o, k2, desc);
|
|
14
|
+
}) : (function(o, m, k, k2) {
|
|
15
|
+
if (k2 === undefined) k2 = k;
|
|
16
|
+
o[k2] = m[k];
|
|
17
|
+
}));
|
|
18
|
+
var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
|
|
19
|
+
Object.defineProperty(o, "default", { enumerable: true, value: v });
|
|
20
|
+
}) : function(o, v) {
|
|
21
|
+
o["default"] = v;
|
|
22
|
+
});
|
|
23
|
+
var __importStar = (this && this.__importStar) || (function () {
|
|
24
|
+
var ownKeys = function(o) {
|
|
25
|
+
ownKeys = Object.getOwnPropertyNames || function (o) {
|
|
26
|
+
var ar = [];
|
|
27
|
+
for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
|
|
28
|
+
return ar;
|
|
29
|
+
};
|
|
30
|
+
return ownKeys(o);
|
|
31
|
+
};
|
|
32
|
+
return function (mod) {
|
|
33
|
+
if (mod && mod.__esModule) return mod;
|
|
34
|
+
var result = {};
|
|
35
|
+
if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
|
|
36
|
+
__setModuleDefault(result, mod);
|
|
37
|
+
return result;
|
|
38
|
+
};
|
|
39
|
+
})();
|
|
7
40
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
8
41
|
exports.initDb = initDb;
|
|
9
42
|
exports.checkDatabaseConnection = checkDatabaseConnection;
|
|
@@ -18,6 +51,8 @@ exports.getProposedOrIgnoredRecordBySymbol = getProposedOrIgnoredRecordBySymbol;
|
|
|
18
51
|
exports.deleteMemoryById = deleteMemoryById;
|
|
19
52
|
exports.queryMemory = queryMemory;
|
|
20
53
|
exports.queryMemoryBySymbol = queryMemoryBySymbol;
|
|
54
|
+
const os = __importStar(require("os"));
|
|
55
|
+
const persistence_config_1 = require("../../utils/persistence-config");
|
|
21
56
|
function getConfig() {
|
|
22
57
|
const apiUrl = process.env.KODINGO_API_URL;
|
|
23
58
|
const token = process.env.KODINGO_API_TOKEN;
|
|
@@ -124,6 +159,15 @@ async function saveMemory(input) {
|
|
|
124
159
|
body.correctsId = input.correctsId;
|
|
125
160
|
if (input.correctedById)
|
|
126
161
|
body.correctedById = input.correctedById;
|
|
162
|
+
// Attribution
|
|
163
|
+
try {
|
|
164
|
+
const config = (0, persistence_config_1.readConfig)();
|
|
165
|
+
if (config.machineId) {
|
|
166
|
+
body.machineId = config.machineId;
|
|
167
|
+
body.displayName = os.hostname();
|
|
168
|
+
}
|
|
169
|
+
}
|
|
170
|
+
catch { }
|
|
127
171
|
const record = await apiFetch("/memory", {
|
|
128
172
|
method: "POST",
|
|
129
173
|
body: JSON.stringify(body),
|
package/dist/cli.js
CHANGED
|
@@ -21,6 +21,7 @@ const sync_1 = require("./commands/sync");
|
|
|
21
21
|
const context_1 = require("./commands/context");
|
|
22
22
|
const guardrails_1 = require("./commands/guardrails");
|
|
23
23
|
const session_brief_1 = require("./commands/session-brief");
|
|
24
|
+
const check_rules_1 = require("./commands/check-rules");
|
|
24
25
|
const aging_1 = require("./commands/aging");
|
|
25
26
|
const program = new commander_1.Command();
|
|
26
27
|
program.name("kodingo").description("Kodingo CLI").version("1.0.4");
|
|
@@ -247,4 +248,8 @@ program
|
|
|
247
248
|
.option("--prompt", "Output as prompt-ready string instead of JSON")
|
|
248
249
|
.option("--limit <n>", "Max memories to include", "30")
|
|
249
250
|
.action((opts) => (0, session_brief_1.sessionBriefCommand)({ prompt: opts.prompt, limit: parseInt(opts.limit) }));
|
|
251
|
+
program
|
|
252
|
+
.command("check-rules")
|
|
253
|
+
.description("Check staged diff against project guardrails — called by pre-commit hook")
|
|
254
|
+
.action(() => (0, check_rules_1.checkRulesCommand)());
|
|
250
255
|
program.parse(process.argv);
|
|
@@ -0,0 +1,75 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.checkRulesCommand = checkRulesCommand;
|
|
4
|
+
const child_process_1 = require("child_process");
|
|
5
|
+
const persistence_config_1 = require("../utils/persistence-config");
|
|
6
|
+
const API_BASE_DEFAULT = "https://kodingo-api.onrender.com";
|
|
7
|
+
function normalizePath(p) {
|
|
8
|
+
return p.replace(/\\/g, "/").toLowerCase();
|
|
9
|
+
}
|
|
10
|
+
function getCredentials() {
|
|
11
|
+
const config = (0, persistence_config_1.readConfig)();
|
|
12
|
+
const cwd = normalizePath(process.cwd());
|
|
13
|
+
const ws = (0, persistence_config_1.readWorkspaceConfig)(cwd);
|
|
14
|
+
const token = ws?.token ?? config.token ?? "";
|
|
15
|
+
const apiUrl = ws?.apiUrl ?? config.apiUrl ?? API_BASE_DEFAULT;
|
|
16
|
+
return { token, apiUrl };
|
|
17
|
+
}
|
|
18
|
+
function getStagedDiff() {
|
|
19
|
+
try {
|
|
20
|
+
return (0, child_process_1.execSync)("git diff --cached", { encoding: "utf-8", timeout: 10000 });
|
|
21
|
+
}
|
|
22
|
+
catch {
|
|
23
|
+
return "";
|
|
24
|
+
}
|
|
25
|
+
}
|
|
26
|
+
function getProjectId(token, apiUrl) {
|
|
27
|
+
return fetch(`${apiUrl}/org/projects/by-token`, {
|
|
28
|
+
headers: { "X-Kodingo-Token": token },
|
|
29
|
+
})
|
|
30
|
+
.then(r => r.ok ? r.json() : null)
|
|
31
|
+
.then((d) => d?.project?.id ?? null)
|
|
32
|
+
.catch(() => null);
|
|
33
|
+
}
|
|
34
|
+
async function checkRulesCommand() {
|
|
35
|
+
const { token, apiUrl } = getCredentials();
|
|
36
|
+
if (!token)
|
|
37
|
+
return; // No token — silent pass, never block
|
|
38
|
+
const diff = getStagedDiff();
|
|
39
|
+
if (!diff.trim())
|
|
40
|
+
return; // Empty diff — nothing to check
|
|
41
|
+
try {
|
|
42
|
+
const projectId = await getProjectId(token, apiUrl);
|
|
43
|
+
if (!projectId)
|
|
44
|
+
return; // Can't resolve project — silent pass
|
|
45
|
+
const res = await fetch(`${apiUrl}/org/projects/${projectId}/rules/check`, {
|
|
46
|
+
method: "POST",
|
|
47
|
+
headers: { "Content-Type": "application/json", "X-Kodingo-Token": token },
|
|
48
|
+
body: JSON.stringify({ diff }),
|
|
49
|
+
});
|
|
50
|
+
if (!res.ok)
|
|
51
|
+
return; // API error — silent pass, never block on infrastructure failure
|
|
52
|
+
const data = await res.json();
|
|
53
|
+
const violations = data.violations ?? [];
|
|
54
|
+
if (!violations.length)
|
|
55
|
+
return; // All clear
|
|
56
|
+
// Hard block
|
|
57
|
+
console.error("\n╔════════════════════════════════════════════════════════════╗");
|
|
58
|
+
console.error("║ KORTEX GUARDRAIL VIOLATION — COMMIT BLOCKED ║");
|
|
59
|
+
console.error("╚════════════════════════════════════════════════════════════╝\n");
|
|
60
|
+
console.error(`${violations.length} rule${violations.length !== 1 ? "s" : ""} violated:\n`);
|
|
61
|
+
for (const v of violations) {
|
|
62
|
+
console.error(` ✕ ${v.title}`);
|
|
63
|
+
console.error(` ${v.description}`);
|
|
64
|
+
if (v.explanation)
|
|
65
|
+
console.error(` → ${v.explanation}`);
|
|
66
|
+
console.error("");
|
|
67
|
+
}
|
|
68
|
+
console.error("Fix the violations above or contact your engineering lead to update the rules.");
|
|
69
|
+
console.error("To bypass in an emergency: git commit --no-verify\n");
|
|
70
|
+
process.exit(1);
|
|
71
|
+
}
|
|
72
|
+
catch {
|
|
73
|
+
return; // Any unexpected error — silent pass
|
|
74
|
+
}
|
|
75
|
+
}
|
|
@@ -20,6 +20,28 @@ async function installHookCommand(options) {
|
|
|
20
20
|
`"${kodingoBin}" scan-git --repo "$(git rev-parse --show-toplevel)" &`,
|
|
21
21
|
"# </kodingo>",
|
|
22
22
|
].join("\n");
|
|
23
|
+
// Pre-commit hook — runs synchronously to enforce guardrails
|
|
24
|
+
const preCommitPath = path_1.default.join(hooksDir, "pre-commit");
|
|
25
|
+
const preCommitBlock = [
|
|
26
|
+
"# <kodingo-guardrails>",
|
|
27
|
+
"# Kortex: enforce project guardrails before commit",
|
|
28
|
+
`"${kodingoBin}" check-rules`,
|
|
29
|
+
"# </kodingo-guardrails>",
|
|
30
|
+
].join("\n");
|
|
31
|
+
if (fs_1.default.existsSync(preCommitPath)) {
|
|
32
|
+
const existing = fs_1.default.readFileSync(preCommitPath, "utf-8");
|
|
33
|
+
if (!existing.includes("# <kodingo-guardrails>")) {
|
|
34
|
+
const updated = existing.endsWith("\n")
|
|
35
|
+
? existing + "\n" + preCommitBlock + "\n"
|
|
36
|
+
: existing + "\n\n" + preCommitBlock + "\n";
|
|
37
|
+
fs_1.default.writeFileSync(preCommitPath, updated, "utf-8");
|
|
38
|
+
}
|
|
39
|
+
}
|
|
40
|
+
else {
|
|
41
|
+
const content = "#!/bin/sh\n\n" + preCommitBlock + "\n";
|
|
42
|
+
fs_1.default.writeFileSync(preCommitPath, content, "utf-8");
|
|
43
|
+
}
|
|
44
|
+
fs_1.default.chmodSync(preCommitPath, 0o755);
|
|
23
45
|
if (fs_1.default.existsSync(hookPath)) {
|
|
24
46
|
const existing = fs_1.default.readFileSync(hookPath, "utf-8");
|
|
25
47
|
if (existing.includes("# <kodingo>")) {
|
|
@@ -12,6 +12,39 @@
|
|
|
12
12
|
* Caps at 50 symbols per run to avoid overwhelming the API.
|
|
13
13
|
* Safe to run multiple times — skips symbols that already have memory.
|
|
14
14
|
*/
|
|
15
|
+
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
|
|
16
|
+
if (k2 === undefined) k2 = k;
|
|
17
|
+
var desc = Object.getOwnPropertyDescriptor(m, k);
|
|
18
|
+
if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
|
|
19
|
+
desc = { enumerable: true, get: function() { return m[k]; } };
|
|
20
|
+
}
|
|
21
|
+
Object.defineProperty(o, k2, desc);
|
|
22
|
+
}) : (function(o, m, k, k2) {
|
|
23
|
+
if (k2 === undefined) k2 = k;
|
|
24
|
+
o[k2] = m[k];
|
|
25
|
+
}));
|
|
26
|
+
var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
|
|
27
|
+
Object.defineProperty(o, "default", { enumerable: true, value: v });
|
|
28
|
+
}) : function(o, v) {
|
|
29
|
+
o["default"] = v;
|
|
30
|
+
});
|
|
31
|
+
var __importStar = (this && this.__importStar) || (function () {
|
|
32
|
+
var ownKeys = function(o) {
|
|
33
|
+
ownKeys = Object.getOwnPropertyNames || function (o) {
|
|
34
|
+
var ar = [];
|
|
35
|
+
for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
|
|
36
|
+
return ar;
|
|
37
|
+
};
|
|
38
|
+
return ownKeys(o);
|
|
39
|
+
};
|
|
40
|
+
return function (mod) {
|
|
41
|
+
if (mod && mod.__esModule) return mod;
|
|
42
|
+
var result = {};
|
|
43
|
+
if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
|
|
44
|
+
__setModuleDefault(result, mod);
|
|
45
|
+
return result;
|
|
46
|
+
};
|
|
47
|
+
})();
|
|
15
48
|
var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
16
49
|
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
17
50
|
};
|
|
@@ -20,6 +53,7 @@ exports.scanRepoCommand = scanRepoCommand;
|
|
|
20
53
|
const fs_1 = __importDefault(require("fs"));
|
|
21
54
|
const path_1 = __importDefault(require("path"));
|
|
22
55
|
const persistence_config_1 = require("../utils/persistence-config");
|
|
56
|
+
const os = __importStar(require("os"));
|
|
23
57
|
const API_BASE = "https://kodingo-api.onrender.com";
|
|
24
58
|
const SUPPORTED_EXTENSIONS = [
|
|
25
59
|
".ts", ".tsx", ".js", ".jsx",
|
|
@@ -144,6 +178,8 @@ async function inferAndCapture(token, symbol, repo) {
|
|
|
144
178
|
tags: [...(inferred.tags ?? []), "scan-repo"],
|
|
145
179
|
status: "proposed",
|
|
146
180
|
confidence: 0.35,
|
|
181
|
+
machineId: (0, persistence_config_1.readConfig)().machineId ?? undefined,
|
|
182
|
+
displayName: os.hostname(),
|
|
147
183
|
}),
|
|
148
184
|
});
|
|
149
185
|
return saveRes.ok;
|