@thejeetsingh/kalcode 2.1.0 → 2.2.1

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.
Files changed (125) hide show
  1. package/README.md +89 -89
  2. package/dist/bin/kalcode.d.ts +2 -0
  3. package/dist/bin/kalcode.js +12 -0
  4. package/dist/bin/kalcode.js.map +1 -0
  5. package/dist/src/agent/context.d.ts +6 -0
  6. package/dist/src/agent/context.js +60 -0
  7. package/dist/src/agent/context.js.map +1 -0
  8. package/dist/src/agent/history.d.ts +8 -0
  9. package/dist/src/agent/history.js +59 -0
  10. package/dist/src/agent/history.js.map +1 -0
  11. package/dist/src/agent/loop.d.ts +6 -0
  12. package/dist/src/agent/loop.js +235 -0
  13. package/dist/src/agent/loop.js.map +1 -0
  14. package/dist/src/agent/memory.d.ts +2 -0
  15. package/dist/src/agent/memory.js +27 -0
  16. package/dist/src/agent/memory.js.map +1 -0
  17. package/dist/src/agent/permissions.d.ts +5 -0
  18. package/dist/src/agent/permissions.js +66 -0
  19. package/dist/src/agent/permissions.js.map +1 -0
  20. package/dist/src/agent/text-tool-parser.d.ts +2 -0
  21. package/dist/src/agent/text-tool-parser.js +68 -0
  22. package/dist/src/agent/text-tool-parser.js.map +1 -0
  23. package/dist/src/api/client.d.ts +2 -0
  24. package/dist/src/api/client.js +86 -0
  25. package/dist/src/api/client.js.map +1 -0
  26. package/dist/src/api/stream-parser.d.ts +2 -0
  27. package/dist/src/api/stream-parser.js +97 -0
  28. package/dist/src/api/stream-parser.js.map +1 -0
  29. package/dist/src/config.d.ts +7 -0
  30. package/dist/src/config.js +52 -0
  31. package/dist/src/config.js.map +1 -0
  32. package/dist/src/constants.d.ts +25 -0
  33. package/{src/constants.ts → dist/src/constants.js} +15 -20
  34. package/dist/src/constants.js.map +1 -0
  35. package/dist/src/git/git.d.ts +15 -0
  36. package/dist/src/git/git.js +73 -0
  37. package/dist/src/git/git.js.map +1 -0
  38. package/dist/src/index.d.ts +1 -0
  39. package/dist/src/index.js +415 -0
  40. package/dist/src/index.js.map +1 -0
  41. package/dist/src/proxy/server.d.ts +1 -0
  42. package/dist/src/proxy/server.js +92 -0
  43. package/dist/src/proxy/server.js.map +1 -0
  44. package/dist/src/tools/edit-file.d.ts +2 -0
  45. package/dist/src/tools/edit-file.js +88 -0
  46. package/dist/src/tools/edit-file.js.map +1 -0
  47. package/dist/src/tools/glob-tool.d.ts +2 -0
  48. package/dist/src/tools/glob-tool.js +52 -0
  49. package/dist/src/tools/glob-tool.js.map +1 -0
  50. package/dist/src/tools/grep.d.ts +2 -0
  51. package/dist/src/tools/grep.js +93 -0
  52. package/dist/src/tools/grep.js.map +1 -0
  53. package/dist/src/tools/list-directory.d.ts +2 -0
  54. package/dist/src/tools/list-directory.js +90 -0
  55. package/dist/src/tools/list-directory.js.map +1 -0
  56. package/dist/src/tools/read-file.d.ts +2 -0
  57. package/dist/src/tools/read-file.js +64 -0
  58. package/dist/src/tools/read-file.js.map +1 -0
  59. package/dist/src/tools/registry.d.ts +4 -0
  60. package/dist/src/tools/registry.js +32 -0
  61. package/dist/src/tools/registry.js.map +1 -0
  62. package/dist/src/tools/run-command.d.ts +2 -0
  63. package/dist/src/tools/run-command.js +98 -0
  64. package/dist/src/tools/run-command.js.map +1 -0
  65. package/dist/src/tools/write-file.d.ts +2 -0
  66. package/dist/src/tools/write-file.js +39 -0
  67. package/dist/src/tools/write-file.js.map +1 -0
  68. package/dist/src/types.d.ts +61 -0
  69. package/dist/src/types.js +2 -0
  70. package/dist/src/types.js.map +1 -0
  71. package/dist/src/ui/input.d.ts +5 -0
  72. package/dist/src/ui/input.js +52 -0
  73. package/dist/src/ui/input.js.map +1 -0
  74. package/dist/src/ui/model-picker.d.ts +7 -0
  75. package/dist/src/ui/model-picker.js +70 -0
  76. package/dist/src/ui/model-picker.js.map +1 -0
  77. package/dist/src/ui/skills-picker.d.ts +2 -0
  78. package/dist/src/ui/skills-picker.js +95 -0
  79. package/dist/src/ui/skills-picker.js.map +1 -0
  80. package/dist/src/ui/skills.d.ts +14 -0
  81. package/dist/src/ui/skills.js +137 -0
  82. package/dist/src/ui/skills.js.map +1 -0
  83. package/dist/src/ui/spinner.d.ts +5 -0
  84. package/dist/src/ui/spinner.js +49 -0
  85. package/dist/src/ui/spinner.js.map +1 -0
  86. package/dist/src/ui/stream-renderer.d.ts +2 -0
  87. package/dist/src/ui/stream-renderer.js +66 -0
  88. package/dist/src/ui/stream-renderer.js.map +1 -0
  89. package/dist/src/ui/terminal.d.ts +24 -0
  90. package/dist/src/ui/terminal.js +272 -0
  91. package/dist/src/ui/terminal.js.map +1 -0
  92. package/package.json +16 -16
  93. package/api/health.ts +0 -8
  94. package/api/v1/chat/completions.ts +0 -43
  95. package/bin/kalcode.ts +0 -14
  96. package/src/agent/context.ts +0 -62
  97. package/src/agent/history.ts +0 -70
  98. package/src/agent/loop.ts +0 -282
  99. package/src/agent/memory.ts +0 -26
  100. package/src/agent/permissions.ts +0 -84
  101. package/src/agent/text-tool-parser.ts +0 -71
  102. package/src/api/client.ts +0 -105
  103. package/src/api/stream-parser.ts +0 -109
  104. package/src/config.ts +0 -61
  105. package/src/git/git.ts +0 -86
  106. package/src/index.ts +0 -403
  107. package/src/proxy/server.ts +0 -110
  108. package/src/tools/edit-file.ts +0 -97
  109. package/src/tools/glob-tool.ts +0 -59
  110. package/src/tools/grep.ts +0 -96
  111. package/src/tools/list-directory.ts +0 -101
  112. package/src/tools/read-file.ts +0 -71
  113. package/src/tools/registry.ts +0 -41
  114. package/src/tools/run-command.ts +0 -99
  115. package/src/tools/write-file.ts +0 -42
  116. package/src/types.ts +0 -68
  117. package/src/ui/input.ts +0 -60
  118. package/src/ui/model-picker.ts +0 -92
  119. package/src/ui/skills-picker.ts +0 -113
  120. package/src/ui/skills.ts +0 -152
  121. package/src/ui/spinner.ts +0 -56
  122. package/src/ui/stream-renderer.ts +0 -69
  123. package/src/ui/terminal.ts +0 -337
  124. package/tsconfig.json +0 -16
  125. package/vercel.json +0 -13
@@ -0,0 +1,52 @@
1
+ import * as readline from "readline";
2
+ import chalk from "chalk";
3
+ export function createInput(slashCommands = []) {
4
+ let rl = null;
5
+ const commands = Array.from(new Set(slashCommands.map((c) => c.trim()).filter(Boolean))).sort();
6
+ function completer(line) {
7
+ if (!line.startsWith("/"))
8
+ return [[], line];
9
+ const hits = commands.filter((c) => c.startsWith(line.toLowerCase()));
10
+ // If user just typed "/" show all slash commands like a command menu seed.
11
+ if (line === "/")
12
+ return [commands, line];
13
+ return [hits.length > 0 ? hits : commands, line];
14
+ }
15
+ function ensureRL() {
16
+ if (process.stdin.isRaw) {
17
+ process.stdin.setRawMode(false);
18
+ }
19
+ process.stdin.resume();
20
+ if (rl)
21
+ return rl;
22
+ rl = readline.createInterface({
23
+ input: process.stdin,
24
+ output: process.stdout,
25
+ historySize: 200,
26
+ completer,
27
+ });
28
+ rl.on("close", () => {
29
+ rl = null;
30
+ });
31
+ return rl;
32
+ }
33
+ // Claude Code uses ❯ as the prompt
34
+ const promptStr = chalk.bold.cyan("❯ ");
35
+ return {
36
+ prompt() {
37
+ return new Promise((resolve) => {
38
+ const iface = ensureRL();
39
+ iface.question(promptStr, (answer) => {
40
+ resolve(answer.trim());
41
+ });
42
+ });
43
+ },
44
+ close() {
45
+ if (rl) {
46
+ rl.close();
47
+ rl = null;
48
+ }
49
+ },
50
+ };
51
+ }
52
+ //# sourceMappingURL=input.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"input.js","sourceRoot":"","sources":["../../../src/ui/input.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,QAAQ,MAAM,UAAU,CAAC;AACrC,OAAO,KAAK,MAAM,OAAO,CAAC;AAO1B,MAAM,UAAU,WAAW,CAAC,gBAA0B,EAAE;IACtD,IAAI,EAAE,GAA8B,IAAI,CAAC;IACzC,MAAM,QAAQ,GAAG,KAAK,CAAC,IAAI,CAAC,IAAI,GAAG,CAAC,aAAa,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,IAAI,EAAE,CAAC,CAAC,MAAM,CAAC,OAAO,CAAC,CAAC,CAAC,CAAC,IAAI,EAAE,CAAC;IAEhG,SAAS,SAAS,CAAC,IAAY;QAC7B,IAAI,CAAC,IAAI,CAAC,UAAU,CAAC,GAAG,CAAC;YAAE,OAAO,CAAC,EAAE,EAAE,IAAI,CAAC,CAAC;QAC7C,MAAM,IAAI,GAAG,QAAQ,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,UAAU,CAAC,IAAI,CAAC,WAAW,EAAE,CAAC,CAAC,CAAC;QACtE,2EAA2E;QAC3E,IAAI,IAAI,KAAK,GAAG;YAAE,OAAO,CAAC,QAAQ,EAAE,IAAI,CAAC,CAAC;QAC1C,OAAO,CAAC,IAAI,CAAC,MAAM,GAAG,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,QAAQ,EAAE,IAAI,CAAC,CAAC;IACnD,CAAC;IAED,SAAS,QAAQ;QACf,IAAI,OAAO,CAAC,KAAK,CAAC,KAAK,EAAE,CAAC;YACxB,OAAO,CAAC,KAAK,CAAC,UAAU,CAAC,KAAK,CAAC,CAAC;QAClC,CAAC;QACD,OAAO,CAAC,KAAK,CAAC,MAAM,EAAE,CAAC;QAEvB,IAAI,EAAE;YAAE,OAAO,EAAE,CAAC;QAElB,EAAE,GAAG,QAAQ,CAAC,eAAe,CAAC;YAC5B,KAAK,EAAE,OAAO,CAAC,KAAK;YACpB,MAAM,EAAE,OAAO,CAAC,MAAM;YACtB,WAAW,EAAE,GAAG;YAChB,SAAS;SACV,CAAC,CAAC;QACH,EAAE,CAAC,EAAE,CAAC,OAAO,EAAE,GAAG,EAAE;YAClB,EAAE,GAAG,IAAI,CAAC;QACZ,CAAC,CAAC,CAAC;QACH,OAAO,EAAE,CAAC;IACZ,CAAC;IAED,mCAAmC;IACnC,MAAM,SAAS,GAAG,KAAK,CAAC,IAAI,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;IAExC,OAAO;QACL,MAAM;YACJ,OAAO,IAAI,OAAO,CAAC,CAAC,OAAO,EAAE,EAAE;gBAC7B,MAAM,KAAK,GAAG,QAAQ,EAAE,CAAC;gBACzB,KAAK,CAAC,QAAQ,CAAC,SAAS,EAAE,CAAC,MAAM,EAAE,EAAE;oBACnC,OAAO,CAAC,MAAM,CAAC,IAAI,EAAE,CAAC,CAAC;gBACzB,CAAC,CAAC,CAAC;YACL,CAAC,CAAC,CAAC;QACL,CAAC;QACD,KAAK;YACH,IAAI,EAAE,EAAE,CAAC;gBACP,EAAE,CAAC,KAAK,EAAE,CAAC;gBACX,EAAE,GAAG,IAAI,CAAC;YACZ,CAAC;QACH,CAAC;KACF,CAAC;AACJ,CAAC"}
@@ -0,0 +1,7 @@
1
+ interface ModelOption {
2
+ id: string;
3
+ name: string;
4
+ params: string;
5
+ }
6
+ export declare function pickModel(models: ModelOption[], currentModelId: string): Promise<string | null>;
7
+ export {};
@@ -0,0 +1,70 @@
1
+ import chalk from "chalk";
2
+ export function pickModel(models, currentModelId) {
3
+ return new Promise((resolve) => {
4
+ const startIndex = models.findIndex((m) => m.id === currentModelId);
5
+ let cursor = startIndex >= 0 ? startIndex : 0;
6
+ const stdin = process.stdin;
7
+ const wasRaw = stdin.isRaw;
8
+ stdin.setRawMode(true);
9
+ stdin.resume();
10
+ const totalLines = models.length + 4;
11
+ let firstDraw = true;
12
+ function render() {
13
+ if (!firstDraw) {
14
+ process.stdout.write(`\x1b[${totalLines}A`);
15
+ }
16
+ firstDraw = false;
17
+ draw();
18
+ }
19
+ function draw() {
20
+ console.log("");
21
+ console.log(chalk.bold(" Select model") +
22
+ chalk.dim(" ↑↓ navigate · enter select · esc cancel"));
23
+ console.log("");
24
+ for (let i = 0; i < models.length; i++) {
25
+ const m = models[i];
26
+ const isActive = m.id === currentModelId;
27
+ const isCursor = i === cursor;
28
+ const pointer = isCursor ? chalk.cyan("❯") : " ";
29
+ const marker = isActive ? chalk.green("●") : chalk.dim("○");
30
+ const name = isCursor ? chalk.bold.white(m.name) : chalk.dim(m.name);
31
+ const params = chalk.dim(`(${m.params})`);
32
+ console.log(` ${pointer} ${marker} ${name} ${params}`);
33
+ }
34
+ console.log("");
35
+ }
36
+ function cleanup() {
37
+ stdin.removeListener("data", onKey);
38
+ stdin.setRawMode(wasRaw ?? false);
39
+ }
40
+ function onKey(data) {
41
+ const key = data.toString();
42
+ if (key === "\x1b" || key === "q") {
43
+ cleanup();
44
+ resolve(null);
45
+ return;
46
+ }
47
+ if (key === "\r" || key === "\n") {
48
+ cleanup();
49
+ resolve(models[cursor].id);
50
+ return;
51
+ }
52
+ if (key === "\x03") {
53
+ cleanup();
54
+ resolve(null);
55
+ return;
56
+ }
57
+ if (key === "\x1b[A" || key === "k") {
58
+ cursor = cursor > 0 ? cursor - 1 : models.length - 1;
59
+ render();
60
+ }
61
+ else if (key === "\x1b[B" || key === "j") {
62
+ cursor = cursor < models.length - 1 ? cursor + 1 : 0;
63
+ render();
64
+ }
65
+ }
66
+ stdin.on("data", onKey);
67
+ render();
68
+ });
69
+ }
70
+ //# sourceMappingURL=model-picker.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"model-picker.js","sourceRoot":"","sources":["../../../src/ui/model-picker.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,2 @@
1
+ import type { Skill } from "./skills.js";
2
+ export declare function pickSkill(initialQuery?: string): Promise<Skill | null>;
@@ -0,0 +1,95 @@
1
+ import chalk from "chalk";
2
+ import { searchSkills } from "./skills.js";
3
+ export function pickSkill(initialQuery = "") {
4
+ return new Promise((resolve) => {
5
+ const stdin = process.stdin;
6
+ const wasRaw = stdin.isRaw;
7
+ stdin.setRawMode(true);
8
+ stdin.resume();
9
+ let query = initialQuery;
10
+ let cursor = 0;
11
+ let firstDraw = true;
12
+ let linesRendered = 0;
13
+ function filtered() {
14
+ return searchSkills(query).slice(0, 8);
15
+ }
16
+ function render() {
17
+ if (!firstDraw && linesRendered > 0) {
18
+ process.stdout.write(`\x1b[${linesRendered}A`);
19
+ }
20
+ firstDraw = false;
21
+ const list = filtered();
22
+ const lines = [];
23
+ lines.push("");
24
+ lines.push(chalk.bold(" Command palette") +
25
+ chalk.dim(" type to filter · ↑↓ navigate · enter select · esc cancel"));
26
+ lines.push(` ${chalk.cyan("❯")} ${query}${chalk.dim("│")}`);
27
+ lines.push("");
28
+ if (list.length === 0) {
29
+ lines.push(chalk.dim(" No matching skills"));
30
+ }
31
+ else {
32
+ if (cursor >= list.length)
33
+ cursor = list.length - 1;
34
+ if (cursor < 0)
35
+ cursor = 0;
36
+ for (let i = 0; i < list.length; i++) {
37
+ const skill = list[i];
38
+ const pointer = i === cursor ? chalk.cyan("❯") : " ";
39
+ const title = i === cursor ? chalk.bold.white(skill.displayName) : chalk.dim(skill.displayName);
40
+ const command = chalk.dim(skill.command);
41
+ lines.push(` ${pointer} ${title} ${command}`);
42
+ }
43
+ }
44
+ lines.push("");
45
+ process.stdout.write(lines.map((line) => `${line}\x1b[2K`).join("\n"));
46
+ linesRendered = lines.length;
47
+ }
48
+ function cleanup() {
49
+ stdin.removeListener("data", onKey);
50
+ stdin.setRawMode(wasRaw ?? false);
51
+ }
52
+ function finish(selection) {
53
+ cleanup();
54
+ resolve(selection);
55
+ }
56
+ function onKey(data) {
57
+ const key = data.toString();
58
+ const list = filtered();
59
+ if (key === "\x1b" || key === "\x03") {
60
+ finish(null);
61
+ return;
62
+ }
63
+ if (key === "\r" || key === "\n") {
64
+ finish(list[cursor] || null);
65
+ return;
66
+ }
67
+ if (key === "\x1b[A") {
68
+ cursor = cursor > 0 ? cursor - 1 : Math.max(0, list.length - 1);
69
+ render();
70
+ return;
71
+ }
72
+ if (key === "\x1b[B") {
73
+ cursor = cursor < list.length - 1 ? cursor + 1 : 0;
74
+ render();
75
+ return;
76
+ }
77
+ if (key === "\x7f") {
78
+ if (query.length > 0) {
79
+ query = query.slice(0, -1);
80
+ cursor = 0;
81
+ render();
82
+ }
83
+ return;
84
+ }
85
+ if (key.length === 1 && key >= " " && key <= "~") {
86
+ query += key;
87
+ cursor = 0;
88
+ render();
89
+ }
90
+ }
91
+ stdin.on("data", onKey);
92
+ render();
93
+ });
94
+ }
95
+ //# sourceMappingURL=skills-picker.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"skills-picker.js","sourceRoot":"","sources":["../../../src/ui/skills-picker.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,14 @@
1
+ export interface Skill {
2
+ id: string;
3
+ displayName: string;
4
+ description: string;
5
+ command: string;
6
+ contextTags: string[];
7
+ keybinding?: string;
8
+ inputSchema?: Record<string, unknown>;
9
+ outputSchema?: Record<string, unknown>;
10
+ ui?: Record<string, unknown>;
11
+ }
12
+ export declare function getSkills(): Skill[];
13
+ export declare function searchSkills(query: string): Skill[];
14
+ export declare function renderSkillsList(skills: Skill[], query?: string): void;
@@ -0,0 +1,137 @@
1
+ import chalk from "chalk";
2
+ const SKILLS = [
3
+ {
4
+ id: "help",
5
+ displayName: "Show help",
6
+ description: "Display all available REPL commands.",
7
+ command: "/help",
8
+ contextTags: ["global"],
9
+ keybinding: "h",
10
+ },
11
+ {
12
+ id: "switch_model",
13
+ displayName: "Switch model",
14
+ description: "Open model picker and set active model.",
15
+ command: "/model",
16
+ contextTags: ["global"],
17
+ keybinding: "m",
18
+ },
19
+ {
20
+ id: "list_context_files",
21
+ displayName: "List context files",
22
+ description: "Show files currently pinned into agent context.",
23
+ command: "/files",
24
+ contextTags: ["project_loaded"],
25
+ keybinding: "f",
26
+ },
27
+ {
28
+ id: "add_context_file",
29
+ displayName: "Add context file",
30
+ description: "Add a file to context memory for the session.",
31
+ command: "/add <file>",
32
+ contextTags: ["project_loaded", "code_view"],
33
+ },
34
+ {
35
+ id: "drop_context_file",
36
+ displayName: "Drop context file",
37
+ description: "Remove a file from context memory.",
38
+ command: "/drop <file>",
39
+ contextTags: ["project_loaded", "code_view"],
40
+ },
41
+ {
42
+ id: "show_git_status",
43
+ displayName: "Git status",
44
+ description: "Show changed files and branch status.",
45
+ command: "/status",
46
+ contextTags: ["git_repo"],
47
+ keybinding: "s",
48
+ },
49
+ {
50
+ id: "show_git_diff",
51
+ displayName: "Git diff summary",
52
+ description: "Show uncommitted changes summary.",
53
+ command: "/diff",
54
+ contextTags: ["git_repo"],
55
+ keybinding: "d",
56
+ },
57
+ {
58
+ id: "git_commit",
59
+ displayName: "Commit changes",
60
+ description: "Commit staged and unstaged changes.",
61
+ command: "/commit <message>",
62
+ contextTags: ["git_repo"],
63
+ },
64
+ {
65
+ id: "toggle_read_only",
66
+ displayName: "Toggle read-only mode",
67
+ description: "Prevent write tools from being used by the agent.",
68
+ command: "/ask",
69
+ contextTags: ["global"],
70
+ keybinding: "r",
71
+ },
72
+ {
73
+ id: "toggle_auto_accept",
74
+ displayName: "Toggle auto-accept",
75
+ description: "Auto-approve write and command tool actions.",
76
+ command: "/auto",
77
+ contextTags: ["global"],
78
+ keybinding: "a",
79
+ },
80
+ {
81
+ id: "retry_last",
82
+ displayName: "Retry last request",
83
+ description: "Retry the most recent user prompt.",
84
+ command: "/retry",
85
+ contextTags: ["chat"],
86
+ keybinding: "y",
87
+ },
88
+ ];
89
+ export function getSkills() {
90
+ return SKILLS.slice();
91
+ }
92
+ export function searchSkills(query) {
93
+ const q = query.trim().toLowerCase();
94
+ if (!q)
95
+ return getSkills();
96
+ return getSkills()
97
+ .map((skill) => ({ skill, score: scoreSkill(skill, q) }))
98
+ .filter((entry) => entry.score > 0)
99
+ .sort((a, b) => b.score - a.score || a.skill.displayName.localeCompare(b.skill.displayName))
100
+ .map((entry) => entry.skill);
101
+ }
102
+ export function renderSkillsList(skills, query = "") {
103
+ const q = query.trim();
104
+ console.log("");
105
+ console.log(chalk.bold(" Skills") + (q ? chalk.dim(` — "${q}"`) : ""));
106
+ console.log("");
107
+ if (skills.length === 0) {
108
+ console.log(chalk.dim(" No matching skills"));
109
+ console.log("");
110
+ return;
111
+ }
112
+ for (const skill of skills) {
113
+ const kb = skill.keybinding ? chalk.dim(` [${skill.keybinding}]`) : "";
114
+ console.log(` ${chalk.cyan("●")} ${chalk.bold(skill.displayName)}${kb}`);
115
+ console.log(` ${chalk.dim(skill.description)}`);
116
+ console.log(` ${chalk.dim(skill.command)}`);
117
+ }
118
+ console.log("");
119
+ }
120
+ function scoreSkill(skill, q) {
121
+ const haystack = [
122
+ skill.id,
123
+ skill.displayName,
124
+ skill.description,
125
+ skill.command,
126
+ ...skill.contextTags,
127
+ skill.keybinding || "",
128
+ ].join(" ").toLowerCase();
129
+ if (!haystack.includes(q))
130
+ return 0;
131
+ if (skill.id === q || skill.command === q || skill.displayName.toLowerCase() === q)
132
+ return 100;
133
+ if (skill.command.startsWith(q) || skill.displayName.toLowerCase().startsWith(q))
134
+ return 80;
135
+ return 50;
136
+ }
137
+ //# sourceMappingURL=skills.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"skills.js","sourceRoot":"","sources":["../../../src/ui/skills.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,5 @@
1
+ export declare function startSpinner(text: string): void;
2
+ export declare function stopSpinner(): void;
3
+ export declare function updateSpinner(text: string): void;
4
+ export declare function succeedSpinner(_text: string): void;
5
+ export declare function failSpinner(_text: string): void;
@@ -0,0 +1,49 @@
1
+ import chalk from "chalk";
2
+ // Braille spinner — matches Claude Code's spinner aesthetic
3
+ const frames = ["⠋", "⠙", "⠹", "⠸", "⠼", "⠴", "⠦", "⠧", "⠇", "⠏"];
4
+ let interval = null;
5
+ let frameIdx = 0;
6
+ let currentText = "";
7
+ let startTime = 0;
8
+ export function startSpinner(text) {
9
+ stopSpinner();
10
+ currentText = text;
11
+ startTime = Date.now();
12
+ frameIdx = 0;
13
+ render();
14
+ interval = setInterval(() => {
15
+ frameIdx = (frameIdx + 1) % frames.length;
16
+ render();
17
+ }, 80);
18
+ }
19
+ export function stopSpinner() {
20
+ if (interval) {
21
+ clearInterval(interval);
22
+ interval = null;
23
+ process.stdout.write("\r\x1b[2K");
24
+ }
25
+ }
26
+ export function updateSpinner(text) {
27
+ currentText = text;
28
+ if (interval)
29
+ render();
30
+ }
31
+ export function succeedSpinner(_text) {
32
+ stopSpinner();
33
+ }
34
+ export function failSpinner(_text) {
35
+ stopSpinner();
36
+ }
37
+ function render() {
38
+ const frame = chalk.cyan(frames[frameIdx]);
39
+ const elapsed = formatElapsed();
40
+ process.stdout.write(`\r\x1b[2K ${frame} ${chalk.dim(currentText)} ${chalk.dim(elapsed)}`);
41
+ }
42
+ function formatElapsed() {
43
+ const ms = Date.now() - startTime;
44
+ if (ms < 1000)
45
+ return "";
46
+ const sec = (ms / 1000).toFixed(1);
47
+ return `${sec}s`;
48
+ }
49
+ //# sourceMappingURL=spinner.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"spinner.js","sourceRoot":"","sources":["../../../src/ui/spinner.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,MAAM,OAAO,CAAC;AAE1B,4DAA4D;AAC5D,MAAM,MAAM,GAAG,CAAC,GAAG,EAAE,GAAG,EAAE,GAAG,EAAE,GAAG,EAAE,GAAG,EAAE,GAAG,EAAE,GAAG,EAAE,GAAG,EAAE,GAAG,EAAE,GAAG,CAAC,CAAC;AAClE,IAAI,QAAQ,GAA0C,IAAI,CAAC;AAC3D,IAAI,QAAQ,GAAG,CAAC,CAAC;AACjB,IAAI,WAAW,GAAG,EAAE,CAAC;AACrB,IAAI,SAAS,GAAG,CAAC,CAAC;AAElB,MAAM,UAAU,YAAY,CAAC,IAAY;IACvC,WAAW,EAAE,CAAC;IACd,WAAW,GAAG,IAAI,CAAC;IACnB,SAAS,GAAG,IAAI,CAAC,GAAG,EAAE,CAAC;IACvB,QAAQ,GAAG,CAAC,CAAC;IACb,MAAM,EAAE,CAAC;IACT,QAAQ,GAAG,WAAW,CAAC,GAAG,EAAE;QAC1B,QAAQ,GAAG,CAAC,QAAQ,GAAG,CAAC,CAAC,GAAG,MAAM,CAAC,MAAM,CAAC;QAC1C,MAAM,EAAE,CAAC;IACX,CAAC,EAAE,EAAE,CAAC,CAAC;AACT,CAAC;AAED,MAAM,UAAU,WAAW;IACzB,IAAI,QAAQ,EAAE,CAAC;QACb,aAAa,CAAC,QAAQ,CAAC,CAAC;QACxB,QAAQ,GAAG,IAAI,CAAC;QAChB,OAAO,CAAC,MAAM,CAAC,KAAK,CAAC,WAAW,CAAC,CAAC;IACpC,CAAC;AACH,CAAC;AAED,MAAM,UAAU,aAAa,CAAC,IAAY;IACxC,WAAW,GAAG,IAAI,CAAC;IACnB,IAAI,QAAQ;QAAE,MAAM,EAAE,CAAC;AACzB,CAAC;AAED,MAAM,UAAU,cAAc,CAAC,KAAa;IAC1C,WAAW,EAAE,CAAC;AAChB,CAAC;AAED,MAAM,UAAU,WAAW,CAAC,KAAa;IACvC,WAAW,EAAE,CAAC;AAChB,CAAC;AAED,SAAS,MAAM;IACb,MAAM,KAAK,GAAG,KAAK,CAAC,IAAI,CAAC,MAAM,CAAC,QAAQ,CAAE,CAAC,CAAC;IAC5C,MAAM,OAAO,GAAG,aAAa,EAAE,CAAC;IAChC,OAAO,CAAC,MAAM,CAAC,KAAK,CAClB,cAAc,KAAK,IAAI,KAAK,CAAC,GAAG,CAAC,WAAW,CAAC,IAAI,KAAK,CAAC,GAAG,CAAC,OAAO,CAAC,EAAE,CACtE,CAAC;AACJ,CAAC;AAED,SAAS,aAAa;IACpB,MAAM,EAAE,GAAG,IAAI,CAAC,GAAG,EAAE,GAAG,SAAS,CAAC;IAClC,IAAI,EAAE,GAAG,IAAI;QAAE,OAAO,EAAE,CAAC;IACzB,MAAM,GAAG,GAAG,CAAC,EAAE,GAAG,IAAI,CAAC,CAAC,OAAO,CAAC,CAAC,CAAC,CAAC;IACnC,OAAO,GAAG,GAAG,GAAG,CAAC;AACnB,CAAC"}
@@ -0,0 +1,2 @@
1
+ export declare function writeStreamToken(token: string): void;
2
+ export declare function finishStream(): void;
@@ -0,0 +1,66 @@
1
+ let hasOutput = false;
2
+ let lineStarted = false;
3
+ let currentLine = "";
4
+ let inThinkBlock = false;
5
+ let buffer = "";
6
+ export function writeStreamToken(token) {
7
+ buffer += token;
8
+ // Filter out <think>...</think> blocks (some models emit these)
9
+ while (true) {
10
+ if (inThinkBlock) {
11
+ const closeIdx = buffer.indexOf("</think>");
12
+ if (closeIdx === -1) {
13
+ // Still inside think block, consume everything
14
+ buffer = "";
15
+ return;
16
+ }
17
+ // Skip past closing tag
18
+ buffer = buffer.slice(closeIdx + 8);
19
+ inThinkBlock = false;
20
+ continue;
21
+ }
22
+ const openIdx = buffer.indexOf("<think>");
23
+ if (openIdx === -1)
24
+ break;
25
+ // Output everything before <think>
26
+ const before = buffer.slice(0, openIdx);
27
+ if (before)
28
+ emitText(before);
29
+ buffer = buffer.slice(openIdx + 7);
30
+ inThinkBlock = true;
31
+ }
32
+ // Output remaining buffer
33
+ if (buffer) {
34
+ emitText(buffer);
35
+ buffer = "";
36
+ }
37
+ }
38
+ function emitText(text) {
39
+ const parts = text.split("\n");
40
+ for (let i = 0; i < parts.length; i++) {
41
+ if (i > 0) {
42
+ process.stdout.write("\n");
43
+ lineStarted = false;
44
+ currentLine = "";
45
+ }
46
+ const seg = parts[i];
47
+ if (seg.length === 0 && i > 0)
48
+ continue;
49
+ if (!lineStarted)
50
+ lineStarted = true;
51
+ process.stdout.write(seg);
52
+ currentLine += seg;
53
+ }
54
+ hasOutput = true;
55
+ }
56
+ export function finishStream() {
57
+ if (hasOutput) {
58
+ process.stdout.write("\n");
59
+ }
60
+ hasOutput = false;
61
+ lineStarted = false;
62
+ currentLine = "";
63
+ inThinkBlock = false;
64
+ buffer = "";
65
+ }
66
+ //# sourceMappingURL=stream-renderer.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"stream-renderer.js","sourceRoot":"","sources":["../../../src/ui/stream-renderer.ts"],"names":[],"mappings":"AAAA,IAAI,SAAS,GAAG,KAAK,CAAC;AACtB,IAAI,WAAW,GAAG,KAAK,CAAC;AACxB,IAAI,WAAW,GAAG,EAAE,CAAC;AACrB,IAAI,YAAY,GAAG,KAAK,CAAC;AACzB,IAAI,MAAM,GAAG,EAAE,CAAC;AAEhB,MAAM,UAAU,gBAAgB,CAAC,KAAa;IAC5C,MAAM,IAAI,KAAK,CAAC;IAEhB,gEAAgE;IAChE,OAAO,IAAI,EAAE,CAAC;QACZ,IAAI,YAAY,EAAE,CAAC;YACjB,MAAM,QAAQ,GAAG,MAAM,CAAC,OAAO,CAAC,UAAU,CAAC,CAAC;YAC5C,IAAI,QAAQ,KAAK,CAAC,CAAC,EAAE,CAAC;gBACpB,+CAA+C;gBAC/C,MAAM,GAAG,EAAE,CAAC;gBACZ,OAAO;YACT,CAAC;YACD,wBAAwB;YACxB,MAAM,GAAG,MAAM,CAAC,KAAK,CAAC,QAAQ,GAAG,CAAC,CAAC,CAAC;YACpC,YAAY,GAAG,KAAK,CAAC;YACrB,SAAS;QACX,CAAC;QAED,MAAM,OAAO,GAAG,MAAM,CAAC,OAAO,CAAC,SAAS,CAAC,CAAC;QAC1C,IAAI,OAAO,KAAK,CAAC,CAAC;YAAE,MAAM;QAE1B,mCAAmC;QACnC,MAAM,MAAM,GAAG,MAAM,CAAC,KAAK,CAAC,CAAC,EAAE,OAAO,CAAC,CAAC;QACxC,IAAI,MAAM;YAAE,QAAQ,CAAC,MAAM,CAAC,CAAC;QAE7B,MAAM,GAAG,MAAM,CAAC,KAAK,CAAC,OAAO,GAAG,CAAC,CAAC,CAAC;QACnC,YAAY,GAAG,IAAI,CAAC;IACtB,CAAC;IAED,0BAA0B;IAC1B,IAAI,MAAM,EAAE,CAAC;QACX,QAAQ,CAAC,MAAM,CAAC,CAAC;QACjB,MAAM,GAAG,EAAE,CAAC;IACd,CAAC;AACH,CAAC;AAED,SAAS,QAAQ,CAAC,IAAY;IAC5B,MAAM,KAAK,GAAG,IAAI,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC;IAC/B,KAAK,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,KAAK,CAAC,MAAM,EAAE,CAAC,EAAE,EAAE,CAAC;QACtC,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC;YACV,OAAO,CAAC,MAAM,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC;YAC3B,WAAW,GAAG,KAAK,CAAC;YACpB,WAAW,GAAG,EAAE,CAAC;QACnB,CAAC;QACD,MAAM,GAAG,GAAG,KAAK,CAAC,CAAC,CAAE,CAAC;QACtB,IAAI,GAAG,CAAC,MAAM,KAAK,CAAC,IAAI,CAAC,GAAG,CAAC;YAAE,SAAS;QACxC,IAAI,CAAC,WAAW;YAAE,WAAW,GAAG,IAAI,CAAC;QACrC,OAAO,CAAC,MAAM,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC;QAC1B,WAAW,IAAI,GAAG,CAAC;IACrB,CAAC;IACD,SAAS,GAAG,IAAI,CAAC;AACnB,CAAC;AAED,MAAM,UAAU,YAAY;IAC1B,IAAI,SAAS,EAAE,CAAC;QACd,OAAO,CAAC,MAAM,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC;IAC7B,CAAC;IACD,SAAS,GAAG,KAAK,CAAC;IAClB,WAAW,GAAG,KAAK,CAAC;IACpB,WAAW,GAAG,EAAE,CAAC;IACjB,YAAY,GAAG,KAAK,CAAC;IACrB,MAAM,GAAG,EAAE,CAAC;AACd,CAAC"}
@@ -0,0 +1,24 @@
1
+ import type { TokenUsage } from "../types.js";
2
+ export declare function renderWelcome(model: string): void;
3
+ export declare function renderSeparator(): void;
4
+ export declare function renderHints(): void;
5
+ export declare function renderStatusLine(_opts: {
6
+ model: string;
7
+ askMode: boolean;
8
+ autoAccept: boolean;
9
+ compact: boolean;
10
+ }): void;
11
+ export declare function renderHelp(): void;
12
+ export declare function renderToolCall(name: string, args: Record<string, unknown>): void;
13
+ export declare function renderToolResult(name: string, result: string, compact: boolean): void;
14
+ export declare function renderModelInfo(current: string, available: {
15
+ id: string;
16
+ name: string;
17
+ params: string;
18
+ }[]): void;
19
+ export declare function renderError(message: string): void;
20
+ export declare function renderUsage(usage: TokenUsage | null): void;
21
+ export declare function renderThinking(): void;
22
+ export declare function clearThinking(): void;
23
+ export declare function renderRetryWait(attempt: number, waitSec: number): void;
24
+ export declare function renderInterrupted(): void;