kodingo-cli 1.0.24 → 1.0.25

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/dist/cli.js CHANGED
@@ -18,6 +18,9 @@ const init_1 = require("./commands/init");
18
18
  const install_hook_1 = require("./commands/install-hook");
19
19
  const update_1 = require("./commands/update");
20
20
  const sync_1 = require("./commands/sync");
21
+ const context_1 = require("./commands/context");
22
+ const guardrails_1 = require("./commands/guardrails");
23
+ const session_brief_1 = require("./commands/session-brief");
21
24
  const aging_1 = require("./commands/aging");
22
25
  const program = new commander_1.Command();
23
26
  program.name("kodingo").description("Kodingo CLI").version("1.0.4");
@@ -226,4 +229,22 @@ program
226
229
  payload.repo = String(options.repo);
227
230
  await (0, scan_repo_1.scanRepoCommand)(payload);
228
231
  });
232
+ program
233
+ .command("context")
234
+ .description("Get affirmed memories for a file — designed for AI agents")
235
+ .requiredOption("-f, --file <path>", "File path to get context for")
236
+ .option("--prompt", "Output as prompt-ready string instead of JSON")
237
+ .option("--limit <n>", "Max memories to return", "20")
238
+ .action((opts) => (0, context_1.contextCommand)(opts.file, { prompt: opts.prompt, limit: parseInt(opts.limit) }));
239
+ program
240
+ .command("guardrails")
241
+ .description("Get project guardrails — rules and rejected patterns for AI agents")
242
+ .option("--prompt", "Output as prompt-ready string instead of JSON")
243
+ .action((opts) => (0, guardrails_1.guardrailsCommand)({ prompt: opts.prompt }));
244
+ program
245
+ .command("session-brief")
246
+ .description("Get a compact project intelligence brief — call at the start of an AI coding session")
247
+ .option("--prompt", "Output as prompt-ready string instead of JSON")
248
+ .option("--limit <n>", "Max memories to include", "30")
249
+ .action((opts) => (0, session_brief_1.sessionBriefCommand)({ prompt: opts.prompt, limit: parseInt(opts.limit) }));
229
250
  program.parse(process.argv);
@@ -0,0 +1,105 @@
1
+ "use strict";
2
+ var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
3
+ if (k2 === undefined) k2 = k;
4
+ var desc = Object.getOwnPropertyDescriptor(m, k);
5
+ if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
6
+ desc = { enumerable: true, get: function() { return m[k]; } };
7
+ }
8
+ Object.defineProperty(o, k2, desc);
9
+ }) : (function(o, m, k, k2) {
10
+ if (k2 === undefined) k2 = k;
11
+ o[k2] = m[k];
12
+ }));
13
+ var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
14
+ Object.defineProperty(o, "default", { enumerable: true, value: v });
15
+ }) : function(o, v) {
16
+ o["default"] = v;
17
+ });
18
+ var __importStar = (this && this.__importStar) || (function () {
19
+ var ownKeys = function(o) {
20
+ ownKeys = Object.getOwnPropertyNames || function (o) {
21
+ var ar = [];
22
+ for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
23
+ return ar;
24
+ };
25
+ return ownKeys(o);
26
+ };
27
+ return function (mod) {
28
+ if (mod && mod.__esModule) return mod;
29
+ var result = {};
30
+ if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
31
+ __setModuleDefault(result, mod);
32
+ return result;
33
+ };
34
+ })();
35
+ Object.defineProperty(exports, "__esModule", { value: true });
36
+ exports.contextCommand = contextCommand;
37
+ /**
38
+ * kodingo context --file <path>
39
+ *
40
+ * Returns all affirmed memories relevant to a file.
41
+ * Designed for AI agents — call before touching a file.
42
+ * Output: JSON by default, prompt-ready string with --prompt flag.
43
+ */
44
+ const path = __importStar(require("path"));
45
+ const persistence_config_1 = require("../utils/persistence-config");
46
+ const API_BASE_DEFAULT = "https://kodingo-api.onrender.com";
47
+ function normalizePath(p) {
48
+ return p.replace(/\\\\/g, "/").toLowerCase();
49
+ }
50
+ function getCredentials() {
51
+ const config = (0, persistence_config_1.readConfig)();
52
+ const cwd = normalizePath(process.cwd());
53
+ const ws = (0, persistence_config_1.readWorkspaceConfig)(cwd);
54
+ const token = ws?.token ?? config.token ?? "";
55
+ const apiUrl = ws?.apiUrl ?? config.apiUrl ?? API_BASE_DEFAULT;
56
+ return { token, apiUrl };
57
+ }
58
+ async function contextCommand(filePath, options) {
59
+ const { token, apiUrl } = getCredentials();
60
+ if (!token) {
61
+ console.error("No token found. Run `kodingo init` first.");
62
+ process.exit(1);
63
+ }
64
+ const limit = options.limit ?? 20;
65
+ const repoName = path.basename(process.cwd());
66
+ const relFile = path.relative(process.cwd(), path.resolve(filePath));
67
+ try {
68
+ // Fetch memories for this file (by repo path)
69
+ const res = await fetch(`${apiUrl}/memory?repo=${encodeURIComponent(relFile)}&status=affirmed&limit=${limit}`, { headers: { "X-Kodingo-Token": token } });
70
+ if (!res.ok) {
71
+ console.error(`API error: ${res.status}`);
72
+ process.exit(1);
73
+ }
74
+ const data = await res.json();
75
+ const memories = data.memories ?? [];
76
+ if (!options.prompt) {
77
+ console.log(JSON.stringify({ file: relFile, repo: repoName, count: memories.length, memories }, null, 2));
78
+ return;
79
+ }
80
+ // Prompt-ready format
81
+ if (!memories.length) {
82
+ console.log(`No affirmed memories found for ${relFile}.`);
83
+ return;
84
+ }
85
+ const lines = [
86
+ `# Kortex context for ${relFile}`,
87
+ `# ${memories.length} affirmed decision${memories.length !== 1 ? "s" : ""} your team has made about this file:`,
88
+ "",
89
+ ];
90
+ for (const m of memories) {
91
+ lines.push(`## ${m.title ?? "Decision"}`);
92
+ lines.push(m.content);
93
+ if (m.symbol)
94
+ lines.push(`Symbol: ${m.symbol}`);
95
+ lines.push(`Confidence: ${(m.confidence * 100).toFixed(0)}%`);
96
+ lines.push("");
97
+ }
98
+ lines.push("# End of Kortex context. Respect these decisions in your changes.");
99
+ console.log(lines.join("\n"));
100
+ }
101
+ catch (err) {
102
+ console.error("Failed to fetch context:", err.message);
103
+ process.exit(1);
104
+ }
105
+ }
@@ -0,0 +1,66 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.guardrailsCommand = guardrailsCommand;
4
+ const persistence_config_1 = require("../utils/persistence-config");
5
+ const API_BASE_DEFAULT = "https://kodingo-api.onrender.com";
6
+ function normalizePath(p) {
7
+ return p.replace(/\\\\/g, "/").toLowerCase();
8
+ }
9
+ function getCredentials() {
10
+ const config = (0, persistence_config_1.readConfig)();
11
+ const cwd = normalizePath(process.cwd());
12
+ const ws = (0, persistence_config_1.readWorkspaceConfig)(cwd);
13
+ const token = ws?.token ?? config.token ?? "";
14
+ const apiUrl = ws?.apiUrl ?? config.apiUrl ?? API_BASE_DEFAULT;
15
+ return { token, apiUrl };
16
+ }
17
+ async function guardrailsCommand(options) {
18
+ const { token, apiUrl } = getCredentials();
19
+ if (!token) {
20
+ console.error("No token found. Run `kodingo init` first.");
21
+ process.exit(1);
22
+ }
23
+ try {
24
+ // Fetch denied memories (things explicitly ruled out)
25
+ const [deniedRes, affiredRes] = await Promise.all([
26
+ fetch(`${apiUrl}/memory?status=denied&limit=50`, { headers: { "X-Kodingo-Token": token } }),
27
+ fetch(`${apiUrl}/memory?status=affirmed&limit=50`, { headers: { "X-Kodingo-Token": token } }),
28
+ ]);
29
+ const denied = deniedRes.ok ? (await deniedRes.json()).memories ?? [] : [];
30
+ const affirmed = affiredRes.ok ? (await affiredRes.json()).memories ?? [] : [];
31
+ // High confidence affirmed = guardrails (confidence >= 0.7)
32
+ const rules = affirmed.filter((m) => m.confidence >= 0.7);
33
+ if (!options.prompt) {
34
+ console.log(JSON.stringify({ rules: rules.length, denied: denied.length, rules_list: rules, denied_list: denied }, null, 2));
35
+ return;
36
+ }
37
+ const lines = ["# Kortex guardrails — decisions your team has enforced", ""];
38
+ if (rules.length) {
39
+ lines.push("## Rules to follow:");
40
+ for (const m of rules) {
41
+ lines.push(`- ${m.title ?? m.content.slice(0, 100)}`);
42
+ if (m.symbol)
43
+ lines.push(` (applies to: ${m.symbol})`);
44
+ }
45
+ lines.push("");
46
+ }
47
+ if (denied.length) {
48
+ lines.push("## Patterns explicitly rejected by your team (do NOT use):");
49
+ for (const m of denied) {
50
+ lines.push(`- ${m.title ?? m.content.slice(0, 100)}`);
51
+ if (m.symbol)
52
+ lines.push(` (rejected for: ${m.symbol})`);
53
+ }
54
+ lines.push("");
55
+ }
56
+ if (!rules.length && !denied.length) {
57
+ lines.push("No guardrails defined yet. Affirm and deny memories to build them.");
58
+ }
59
+ lines.push("# End of Kortex guardrails.");
60
+ console.log(lines.join("\n"));
61
+ }
62
+ catch (err) {
63
+ console.error("Failed to fetch guardrails:", err.message);
64
+ process.exit(1);
65
+ }
66
+ }
@@ -0,0 +1,114 @@
1
+ "use strict";
2
+ var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
3
+ if (k2 === undefined) k2 = k;
4
+ var desc = Object.getOwnPropertyDescriptor(m, k);
5
+ if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
6
+ desc = { enumerable: true, get: function() { return m[k]; } };
7
+ }
8
+ Object.defineProperty(o, k2, desc);
9
+ }) : (function(o, m, k, k2) {
10
+ if (k2 === undefined) k2 = k;
11
+ o[k2] = m[k];
12
+ }));
13
+ var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
14
+ Object.defineProperty(o, "default", { enumerable: true, value: v });
15
+ }) : function(o, v) {
16
+ o["default"] = v;
17
+ });
18
+ var __importStar = (this && this.__importStar) || (function () {
19
+ var ownKeys = function(o) {
20
+ ownKeys = Object.getOwnPropertyNames || function (o) {
21
+ var ar = [];
22
+ for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
23
+ return ar;
24
+ };
25
+ return ownKeys(o);
26
+ };
27
+ return function (mod) {
28
+ if (mod && mod.__esModule) return mod;
29
+ var result = {};
30
+ if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
31
+ __setModuleDefault(result, mod);
32
+ return result;
33
+ };
34
+ })();
35
+ Object.defineProperty(exports, "__esModule", { value: true });
36
+ exports.sessionBriefCommand = sessionBriefCommand;
37
+ /**
38
+ * kodingo session-brief
39
+ *
40
+ * Returns a compact summary of the most important decisions across the project.
41
+ * Designed for AI agents — call once at the start of a new coding session.
42
+ * Output: JSON by default, prompt-ready string with --prompt flag.
43
+ */
44
+ const persistence_config_1 = require("../utils/persistence-config");
45
+ const path = __importStar(require("path"));
46
+ const API_BASE_DEFAULT = "https://kodingo-api.onrender.com";
47
+ function normalizePath(p) {
48
+ return p.replace(/\\\\/g, "/").toLowerCase();
49
+ }
50
+ function getCredentials() {
51
+ const config = (0, persistence_config_1.readConfig)();
52
+ const cwd = normalizePath(process.cwd());
53
+ const ws = (0, persistence_config_1.readWorkspaceConfig)(cwd);
54
+ const token = ws?.token ?? config.token ?? "";
55
+ const apiUrl = ws?.apiUrl ?? config.apiUrl ?? API_BASE_DEFAULT;
56
+ return { token, apiUrl };
57
+ }
58
+ async function sessionBriefCommand(options) {
59
+ const { token, apiUrl } = getCredentials();
60
+ if (!token) {
61
+ console.error("No token found. Run `kodingo init` first.");
62
+ process.exit(1);
63
+ }
64
+ const limit = options.limit ?? 30;
65
+ const repoName = path.basename(process.cwd());
66
+ try {
67
+ // Top affirmed memories sorted by confidence
68
+ const res = await fetch(`${apiUrl}/memory?status=affirmed&limit=${limit}`, { headers: { "X-Kodingo-Token": token } });
69
+ if (!res.ok) {
70
+ console.error(`API error: ${res.status}`);
71
+ process.exit(1);
72
+ }
73
+ const data = await res.json();
74
+ const memories = (data.memories ?? []).sort((a, b) => b.confidence - a.confidence);
75
+ if (!options.prompt) {
76
+ console.log(JSON.stringify({
77
+ repo: repoName,
78
+ total_affirmed: data.total,
79
+ showing: memories.length,
80
+ memories,
81
+ }, null, 2));
82
+ return;
83
+ }
84
+ const lines = [
85
+ `# Kortex session brief for ${repoName}`,
86
+ `# ${data.total} total affirmed decisions. Showing top ${memories.length} by confidence.`,
87
+ `# Read these before writing any code.`,
88
+ "",
89
+ ];
90
+ // Group by type
91
+ const byType = {};
92
+ for (const m of memories) {
93
+ const t = m.type ?? "context";
94
+ if (!byType[t])
95
+ byType[t] = [];
96
+ byType[t].push(m);
97
+ }
98
+ for (const [type, items] of Object.entries(byType)) {
99
+ lines.push(`## ${type.charAt(0).toUpperCase() + type.slice(1)} decisions`);
100
+ for (const m of items) {
101
+ const conf = (m.confidence * 100).toFixed(0);
102
+ const symbol = m.symbol ? ` [${m.symbol}]` : "";
103
+ lines.push(`- ${m.title ?? m.content.slice(0, 100)}${symbol} (${conf}% confidence)`);
104
+ }
105
+ lines.push("");
106
+ }
107
+ lines.push("# End of Kortex session brief. These decisions represent your team\'s collective intelligence.");
108
+ console.log(lines.join("\n"));
109
+ }
110
+ catch (err) {
111
+ console.error("Failed to fetch session brief:", err.message);
112
+ process.exit(1);
113
+ }
114
+ }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "kodingo-cli",
3
- "version": "1.0.24",
3
+ "version": "1.0.25",
4
4
  "description": "Kodingo CLI",
5
5
  "license": "MIT",
6
6
  "private": false,