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;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "kodingo-cli",
3
- "version": "1.0.25",
3
+ "version": "1.0.27",
4
4
  "description": "Kodingo CLI",
5
5
  "license": "MIT",
6
6
  "private": false,