acmecode 1.0.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.
Files changed (131) hide show
  1. package/.acmecode/config.json +6 -0
  2. package/README.md +124 -0
  3. package/dist/agent/index.js +161 -0
  4. package/dist/cli/bin/acmecode.js +3 -0
  5. package/dist/cli/package.json +25 -0
  6. package/dist/cli/src/index.d.ts +1 -0
  7. package/dist/cli/src/index.js +53 -0
  8. package/dist/config/index.js +92 -0
  9. package/dist/context/index.js +30 -0
  10. package/dist/core/src/agent/index.d.ts +52 -0
  11. package/dist/core/src/agent/index.js +476 -0
  12. package/dist/core/src/config/index.d.ts +83 -0
  13. package/dist/core/src/config/index.js +318 -0
  14. package/dist/core/src/context/index.d.ts +1 -0
  15. package/dist/core/src/context/index.js +30 -0
  16. package/dist/core/src/llm/provider.d.ts +27 -0
  17. package/dist/core/src/llm/provider.js +202 -0
  18. package/dist/core/src/llm/vision.d.ts +7 -0
  19. package/dist/core/src/llm/vision.js +37 -0
  20. package/dist/core/src/mcp/index.d.ts +10 -0
  21. package/dist/core/src/mcp/index.js +84 -0
  22. package/dist/core/src/prompt/anthropic.d.ts +1 -0
  23. package/dist/core/src/prompt/anthropic.js +32 -0
  24. package/dist/core/src/prompt/architect.d.ts +1 -0
  25. package/dist/core/src/prompt/architect.js +17 -0
  26. package/dist/core/src/prompt/autopilot.d.ts +1 -0
  27. package/dist/core/src/prompt/autopilot.js +18 -0
  28. package/dist/core/src/prompt/beast.d.ts +1 -0
  29. package/dist/core/src/prompt/beast.js +83 -0
  30. package/dist/core/src/prompt/gemini.d.ts +1 -0
  31. package/dist/core/src/prompt/gemini.js +45 -0
  32. package/dist/core/src/prompt/index.d.ts +18 -0
  33. package/dist/core/src/prompt/index.js +239 -0
  34. package/dist/core/src/prompt/zen.d.ts +1 -0
  35. package/dist/core/src/prompt/zen.js +13 -0
  36. package/dist/core/src/session/index.d.ts +18 -0
  37. package/dist/core/src/session/index.js +97 -0
  38. package/dist/core/src/skills/index.d.ts +6 -0
  39. package/dist/core/src/skills/index.js +72 -0
  40. package/dist/core/src/tools/batch.d.ts +2 -0
  41. package/dist/core/src/tools/batch.js +65 -0
  42. package/dist/core/src/tools/browser.d.ts +7 -0
  43. package/dist/core/src/tools/browser.js +86 -0
  44. package/dist/core/src/tools/edit.d.ts +11 -0
  45. package/dist/core/src/tools/edit.js +312 -0
  46. package/dist/core/src/tools/index.d.ts +13 -0
  47. package/dist/core/src/tools/index.js +980 -0
  48. package/dist/core/src/tools/lsp-client.d.ts +11 -0
  49. package/dist/core/src/tools/lsp-client.js +224 -0
  50. package/dist/index.js +41 -0
  51. package/dist/llm/provider.js +34 -0
  52. package/dist/mcp/index.js +84 -0
  53. package/dist/session/index.js +74 -0
  54. package/dist/skills/index.js +32 -0
  55. package/dist/tools/index.js +96 -0
  56. package/dist/tui/App.js +297 -0
  57. package/dist/tui/Spinner.js +16 -0
  58. package/dist/tui/TextInput.js +98 -0
  59. package/dist/tui/src/App.d.ts +11 -0
  60. package/dist/tui/src/App.js +1211 -0
  61. package/dist/tui/src/CatLogo.d.ts +10 -0
  62. package/dist/tui/src/CatLogo.js +99 -0
  63. package/dist/tui/src/OptionList.d.ts +15 -0
  64. package/dist/tui/src/OptionList.js +60 -0
  65. package/dist/tui/src/Spinner.d.ts +7 -0
  66. package/dist/tui/src/Spinner.js +18 -0
  67. package/dist/tui/src/TextInput.d.ts +28 -0
  68. package/dist/tui/src/TextInput.js +139 -0
  69. package/dist/tui/src/Tips.d.ts +2 -0
  70. package/dist/tui/src/Tips.js +62 -0
  71. package/dist/tui/src/Toast.d.ts +19 -0
  72. package/dist/tui/src/Toast.js +39 -0
  73. package/dist/tui/src/TodoItem.d.ts +7 -0
  74. package/dist/tui/src/TodoItem.js +21 -0
  75. package/dist/tui/src/i18n.d.ts +172 -0
  76. package/dist/tui/src/i18n.js +189 -0
  77. package/dist/tui/src/markdown.d.ts +6 -0
  78. package/dist/tui/src/markdown.js +356 -0
  79. package/dist/tui/src/theme.d.ts +31 -0
  80. package/dist/tui/src/theme.js +239 -0
  81. package/output.txt +0 -0
  82. package/package.json +44 -0
  83. package/packages/cli/package.json +25 -0
  84. package/packages/cli/src/index.ts +59 -0
  85. package/packages/cli/tsconfig.json +26 -0
  86. package/packages/core/package.json +39 -0
  87. package/packages/core/src/agent/index.ts +588 -0
  88. package/packages/core/src/config/index.ts +383 -0
  89. package/packages/core/src/context/index.ts +34 -0
  90. package/packages/core/src/llm/provider.ts +237 -0
  91. package/packages/core/src/llm/vision.ts +43 -0
  92. package/packages/core/src/mcp/index.ts +110 -0
  93. package/packages/core/src/prompt/anthropic.ts +32 -0
  94. package/packages/core/src/prompt/architect.ts +17 -0
  95. package/packages/core/src/prompt/autopilot.ts +18 -0
  96. package/packages/core/src/prompt/beast.ts +83 -0
  97. package/packages/core/src/prompt/gemini.ts +45 -0
  98. package/packages/core/src/prompt/index.ts +267 -0
  99. package/packages/core/src/prompt/zen.ts +13 -0
  100. package/packages/core/src/session/index.ts +129 -0
  101. package/packages/core/src/skills/index.ts +86 -0
  102. package/packages/core/src/tools/batch.ts +73 -0
  103. package/packages/core/src/tools/browser.ts +95 -0
  104. package/packages/core/src/tools/edit.ts +317 -0
  105. package/packages/core/src/tools/index.ts +1112 -0
  106. package/packages/core/src/tools/lsp-client.ts +303 -0
  107. package/packages/core/tsconfig.json +19 -0
  108. package/packages/tui/package.json +24 -0
  109. package/packages/tui/src/App.tsx +1702 -0
  110. package/packages/tui/src/CatLogo.tsx +134 -0
  111. package/packages/tui/src/OptionList.tsx +95 -0
  112. package/packages/tui/src/Spinner.tsx +28 -0
  113. package/packages/tui/src/TextInput.tsx +202 -0
  114. package/packages/tui/src/Tips.tsx +64 -0
  115. package/packages/tui/src/Toast.tsx +60 -0
  116. package/packages/tui/src/TodoItem.tsx +29 -0
  117. package/packages/tui/src/i18n.ts +203 -0
  118. package/packages/tui/src/markdown.ts +403 -0
  119. package/packages/tui/src/theme.ts +287 -0
  120. package/packages/tui/tsconfig.json +24 -0
  121. package/tsconfig.json +18 -0
  122. package/vscode-acmecode/.vscodeignore +11 -0
  123. package/vscode-acmecode/README.md +57 -0
  124. package/vscode-acmecode/esbuild.js +46 -0
  125. package/vscode-acmecode/images/button-dark.svg +5 -0
  126. package/vscode-acmecode/images/button-light.svg +5 -0
  127. package/vscode-acmecode/images/icon.png +1 -0
  128. package/vscode-acmecode/package-lock.json +490 -0
  129. package/vscode-acmecode/package.json +87 -0
  130. package/vscode-acmecode/src/extension.ts +128 -0
  131. package/vscode-acmecode/tsconfig.json +16 -0
@@ -0,0 +1,356 @@
1
+ import { theme } from "./theme.js";
2
+ import pc from "picocolors"; // Keep pc for some low-level things if needed, but primarily use theme
3
+ /**
4
+ * Lightweight terminal markdown renderer.
5
+ * Converts common markdown syntax to ANSI-styled text for terminal display.
6
+ * Handles: headers, bold, italic, inline code, code blocks, lists, checkboxes, horizontal rules.
7
+ */
8
+ export function renderMarkdown(input) {
9
+ const lines = input.split("\n");
10
+ const result = [];
11
+ let inCodeBlock = false;
12
+ let codeBlockLang = "";
13
+ let codeBuffer = [];
14
+ for (let i = 0; i < lines.length; i++) {
15
+ const line = lines[i];
16
+ // ── Code block toggle ──
17
+ if (line.trimStart().startsWith("```")) {
18
+ if (!inCodeBlock) {
19
+ inCodeBlock = true;
20
+ codeBlockLang = line.trimStart().slice(3).trim();
21
+ codeBuffer = [];
22
+ continue;
23
+ }
24
+ else {
25
+ // End code block — render it
26
+ inCodeBlock = false;
27
+ if (codeBlockLang === "diff" || codeBlockLang === "patch") {
28
+ // Diff-specific rendering — colored lines, no box border
29
+ for (const codeLine of codeBuffer) {
30
+ result.push(renderDiffLine(codeLine));
31
+ }
32
+ }
33
+ else {
34
+ const header = codeBlockLang
35
+ ? theme.muted(`┌─ ${codeBlockLang} ${"─".repeat(Math.max(0, 36 - codeBlockLang.length))}`)
36
+ : theme.muted(`┌${"─".repeat(40)}`);
37
+ const footer = theme.muted(`└${"─".repeat(40)}`);
38
+ result.push(header);
39
+ for (const codeLine of codeBuffer) {
40
+ result.push(theme.muted("│ ") + highlightCode(codeLine, codeBlockLang));
41
+ }
42
+ result.push(footer);
43
+ }
44
+ codeBlockLang = "";
45
+ codeBuffer = [];
46
+ continue;
47
+ }
48
+ }
49
+ if (inCodeBlock) {
50
+ codeBuffer.push(line);
51
+ continue;
52
+ }
53
+ // ── Horizontal rule ──
54
+ if (/^(\s*[-*_]){3,}\s*$/.test(line)) {
55
+ result.push(theme.muted("─".repeat(40)));
56
+ continue;
57
+ }
58
+ // ── Headers ──
59
+ const h1Match = line.match(/^# (.+)/);
60
+ if (h1Match) {
61
+ result.push("");
62
+ result.push(theme.highlight(theme.primary(`█ ${h1Match[1]}`)));
63
+ result.push(theme.muted("─".repeat(Math.min(40, (h1Match[1]?.length || 0) + 4))));
64
+ continue;
65
+ }
66
+ const h2Match = line.match(/^## (.+)/);
67
+ if (h2Match) {
68
+ result.push("");
69
+ result.push(theme.highlight(theme.info(`▌ ${h2Match[1]}`)));
70
+ continue;
71
+ }
72
+ const h3Match = line.match(/^### (.+)/);
73
+ if (h3Match) {
74
+ result.push(theme.highlight(theme.secondary(` ▸ ${h3Match[1]}`)));
75
+ continue;
76
+ }
77
+ const h4Match = line.match(/^#### (.+)/);
78
+ if (h4Match) {
79
+ result.push(theme.highlight(` ${h4Match[1]}`));
80
+ continue;
81
+ }
82
+ // ── Checkbox lists ──
83
+ const checkMatch = line.match(/^(\s*)- \[([ xX])\] (.+)/);
84
+ if (checkMatch) {
85
+ const indent = checkMatch[1] || "";
86
+ const checked = checkMatch[2].toLowerCase() === "x";
87
+ const text = formatInline(checkMatch[3]);
88
+ const icon = checked ? theme.success("✔") : theme.muted("○");
89
+ result.push(`${indent} ${icon} ${checked ? theme.muted(pc.strikethrough(text)) : text}`);
90
+ continue;
91
+ }
92
+ // ── Unordered lists ──
93
+ const ulMatch = line.match(/^(\s*)[-*] (.+)/);
94
+ if (ulMatch) {
95
+ const indent = ulMatch[1] || "";
96
+ const text = formatInline(ulMatch[2]);
97
+ result.push(`${indent} ${theme.primary("•")} ${text}`);
98
+ continue;
99
+ }
100
+ // ── Ordered lists ──
101
+ const olMatch = line.match(/^(\s*)(\d+)\. (.+)/);
102
+ if (olMatch) {
103
+ const indent = olMatch[1] || "";
104
+ const num = olMatch[2];
105
+ const text = formatInline(olMatch[3]);
106
+ result.push(`${indent} ${theme.primary(num + ".")} ${text}`);
107
+ continue;
108
+ }
109
+ // ── Blockquotes ──
110
+ const bqMatch = line.match(/^>\s?(.*)/);
111
+ if (bqMatch) {
112
+ result.push(` ${theme.muted("│")} ${theme.muted(pc.italic(bqMatch[1] || ""))}`);
113
+ continue;
114
+ }
115
+ // ── Regular text with inline formatting ──
116
+ result.push(formatInline(line));
117
+ }
118
+ // Handle unclosed code block
119
+ if (inCodeBlock && codeBuffer.length > 0) {
120
+ result.push(theme.muted(`┌${"─".repeat(40)}`));
121
+ for (const codeLine of codeBuffer) {
122
+ result.push(theme.muted("│ ") + highlightCode(codeLine, codeBlockLang));
123
+ }
124
+ result.push(theme.muted(`└${"─".repeat(40)}`));
125
+ }
126
+ return result.join("\n");
127
+ }
128
+ /**
129
+ * Format inline markdown: bold, italic, inline code, strikethrough, links
130
+ */
131
+ function formatInline(text) {
132
+ // Inline code (must be first to prevent inner formatting)
133
+ text = text.replace(/`([^`]+)`/g, (_, code) => theme.warning(pc.bgBlack(` ${code} `)));
134
+ // Bold + italic
135
+ text = text.replace(/\*\*\*(.+?)\*\*\*/g, (_, t) => theme.highlight(pc.italic(t)));
136
+ // Bold
137
+ text = text.replace(/\*\*(.+?)\*\*/g, (_, t) => theme.highlight(t));
138
+ // Italic
139
+ text = text.replace(/\*(.+?)\*/g, (_, t) => pc.italic(t));
140
+ text = text.replace(/_(.+?)_/g, (_, t) => pc.italic(t));
141
+ // Strikethrough
142
+ text = text.replace(/~~(.+?)~~/g, (_, t) => theme.muted(pc.strikethrough(t)));
143
+ // Links [text](url) → text (url)
144
+ text = text.replace(/\[([^\]]+)\]\(([^)]+)\)/g, (_, label, url) => `${pc.underline(theme.info(label))} ${theme.muted(`(${url})`)}`);
145
+ return text;
146
+ }
147
+ // ── Syntax highlighting keywords ──
148
+ const KEYWORDS = new Set([
149
+ // JS/TS
150
+ "const",
151
+ "let",
152
+ "var",
153
+ "function",
154
+ "return",
155
+ "if",
156
+ "else",
157
+ "for",
158
+ "while",
159
+ "do",
160
+ "switch",
161
+ "case",
162
+ "break",
163
+ "continue",
164
+ "new",
165
+ "this",
166
+ "class",
167
+ "extends",
168
+ "super",
169
+ "import",
170
+ "export",
171
+ "from",
172
+ "default",
173
+ "async",
174
+ "await",
175
+ "try",
176
+ "catch",
177
+ "finally",
178
+ "throw",
179
+ "typeof",
180
+ "instanceof",
181
+ "in",
182
+ "of",
183
+ "yield",
184
+ "delete",
185
+ "void",
186
+ // Python
187
+ "def",
188
+ "lambda",
189
+ "pass",
190
+ "raise",
191
+ "with",
192
+ "as",
193
+ "global",
194
+ "nonlocal",
195
+ "assert",
196
+ "elif",
197
+ "except",
198
+ "is",
199
+ "not",
200
+ "and",
201
+ "or",
202
+ "True",
203
+ "False",
204
+ "None",
205
+ "print",
206
+ // Common
207
+ "true",
208
+ "false",
209
+ "null",
210
+ "undefined",
211
+ "nil",
212
+ ]);
213
+ const TYPES = new Set([
214
+ "string",
215
+ "number",
216
+ "boolean",
217
+ "object",
218
+ "any",
219
+ "void",
220
+ "never",
221
+ "unknown",
222
+ "int",
223
+ "float",
224
+ "double",
225
+ "char",
226
+ "long",
227
+ "short",
228
+ "byte",
229
+ "bool",
230
+ "String",
231
+ "Number",
232
+ "Boolean",
233
+ "Array",
234
+ "Object",
235
+ "Map",
236
+ "Set",
237
+ "Promise",
238
+ "Record",
239
+ "Partial",
240
+ "Required",
241
+ "Readonly",
242
+ "interface",
243
+ "type",
244
+ "enum",
245
+ "struct",
246
+ "impl",
247
+ "trait",
248
+ "pub",
249
+ "fn",
250
+ "mod",
251
+ "use",
252
+ "crate",
253
+ ]);
254
+ /**
255
+ * Simple token-based syntax highlighter for code blocks.
256
+ */
257
+ function highlightCode(line, _lang) {
258
+ // Line-level comment detection
259
+ const trimmed = line.trimStart();
260
+ if (trimmed.startsWith("//") ||
261
+ trimmed.startsWith("#") ||
262
+ trimmed.startsWith("--")) {
263
+ return theme.muted(pc.italic(line));
264
+ }
265
+ let result = "";
266
+ let i = 0;
267
+ while (i < line.length) {
268
+ const ch = line[i];
269
+ // ── String literals ──
270
+ if (ch === '"' || ch === "'" || ch === "`") {
271
+ const quote = ch;
272
+ let end = i + 1;
273
+ while (end < line.length && line[end] !== quote) {
274
+ if (line[end] === "\\")
275
+ end++; // skip escaped
276
+ end++;
277
+ }
278
+ end = Math.min(end + 1, line.length);
279
+ result += theme.success(line.slice(i, end));
280
+ i = end;
281
+ continue;
282
+ }
283
+ // ── Numbers ──
284
+ if (/\d/.test(ch) &&
285
+ (i === 0 || /[\s(,=:+\-*/<>[\]{}!&|^~%]/.test(line[i - 1] || " "))) {
286
+ let end = i;
287
+ while (end < line.length && /[\d.xXa-fA-FeEoObB_]/.test(line[end]))
288
+ end++;
289
+ result += theme.warning(line.slice(i, end));
290
+ i = end;
291
+ continue;
292
+ }
293
+ // ── Words (keywords/types/identifiers) ──
294
+ if (/[a-zA-Z_$@]/.test(ch)) {
295
+ let end = i;
296
+ while (end < line.length && /[a-zA-Z0-9_$]/.test(line[end]))
297
+ end++;
298
+ const word = line.slice(i, end);
299
+ if (KEYWORDS.has(word)) {
300
+ result += theme.secondary(word);
301
+ }
302
+ else if (TYPES.has(word)) {
303
+ result += theme.primary(word);
304
+ }
305
+ else {
306
+ result += word;
307
+ }
308
+ i = end;
309
+ continue;
310
+ }
311
+ // ── Operators/punctuation ──
312
+ if (/[(){}[\];,.<>+\-*/%=!&|^~?:]/.test(ch)) {
313
+ result += theme.muted(ch);
314
+ i++;
315
+ continue;
316
+ }
317
+ result += ch;
318
+ i++;
319
+ }
320
+ return result;
321
+ }
322
+ // ANSI truecolor background helpers (terminals supporting 24-bit color)
323
+ function bgRgb(r, g, b, text) {
324
+ return `\x1b[48;2;${r};${g};${b}m${text}\x1b[49m`;
325
+ }
326
+ // Diff background colors — matching opencode's diffAddedBg / diffRemovedBg
327
+ const DIFF_ADDED_BG = (t) => bgRgb(32, 48, 59, t); // #20303b deep teal-green
328
+ const DIFF_REMOVED_BG = (t) => bgRgb(55, 34, 44, t); // #37222c deep rose-red
329
+ /**
330
+ * Render a single line of a unified diff with appropriate colors.
331
+ * + added lines → green fg + deep green bg
332
+ * - removed lines → red fg + deep red bg
333
+ * @@ hunk headers → cyan
334
+ * --- / +++ file headers → bold dim
335
+ * context lines → dim
336
+ */
337
+ function renderDiffLine(line) {
338
+ if (line.startsWith("+++") || line.startsWith("---")) {
339
+ return theme.muted(theme.highlight(line));
340
+ }
341
+ if (line.startsWith("@@")) {
342
+ const match = line.match(/^(@@ .+? @@)(.*)/);
343
+ if (match) {
344
+ return theme.info(match[1]) + theme.muted(match[2] || "");
345
+ }
346
+ return theme.info(line);
347
+ }
348
+ if (line.startsWith("+")) {
349
+ return DIFF_ADDED_BG(theme.success(line));
350
+ }
351
+ if (line.startsWith("-")) {
352
+ return DIFF_REMOVED_BG(theme.danger(line));
353
+ }
354
+ // Context line
355
+ return theme.muted(line);
356
+ }
@@ -0,0 +1,31 @@
1
+ export interface ThemeColors {
2
+ primary: (text: string) => string;
3
+ secondary: (text: string) => string;
4
+ muted: (text: string) => string;
5
+ success: (text: string) => string;
6
+ danger: (text: string) => string;
7
+ warning: (text: string) => string;
8
+ info: (text: string) => string;
9
+ highlight: (text: string) => string;
10
+ border: string;
11
+ borderDim: string;
12
+ logo: string;
13
+ /** Hex color for the header card background */
14
+ bgHeader: string;
15
+ /** Hex color for the input card background */
16
+ bgInput: string;
17
+ /** Hex color for the accent bar on the left of the input */
18
+ accentIdle: string;
19
+ /** Hex color for the accent bar when generating */
20
+ accentBusy: string;
21
+ }
22
+ export declare function getTheme(): ThemeColors;
23
+ export declare function setTheme(name: string): boolean;
24
+ export declare function onThemeChange(listener: (name: string) => void): void;
25
+ export declare function getThemeName(): string;
26
+ export declare function listThemes(): string[];
27
+ export declare const theme: ThemeColors;
28
+ export declare function formatToolIcon(toolName: string): string;
29
+ export declare function formatToolName(toolName: string): string;
30
+ export declare function formatBorder(width: number, char?: string): string;
31
+ export declare function formatKeyHint(key: string, label: string): string;
@@ -0,0 +1,239 @@
1
+ import pc from "picocolors";
2
+ import { t } from "./i18n.js";
3
+ import { loadThemeConfig, saveGlobalThemeConfig, } from "@acmecode/core/config/index.js";
4
+ // Helper: ANSI 256-color foreground
5
+ const c256 = (n) => (text) => `\x1b[38;5;${n}m${text}\x1b[0m`;
6
+ // ── Built-in Themes ──
7
+ const themes = {
8
+ dark: {
9
+ primary: pc.cyan,
10
+ secondary: pc.magenta,
11
+ muted: pc.gray,
12
+ success: pc.green,
13
+ danger: pc.red,
14
+ warning: pc.yellow,
15
+ info: pc.blue,
16
+ highlight: pc.bold,
17
+ border: "─",
18
+ borderDim: "┄",
19
+ logo: `${pc.cyan(pc.bold("AcmeCode"))} ${pc.gray("v1.0")}`,
20
+ bgHeader: "#141414",
21
+ bgInput: "#1e1e1e",
22
+ accentIdle: "cyan",
23
+ accentBusy: "yellow",
24
+ },
25
+ dracula: {
26
+ primary: c256(141), // purple
27
+ secondary: c256(212), // pink
28
+ muted: c256(103), // comment gray
29
+ success: c256(84), // green
30
+ danger: c256(203), // red
31
+ warning: c256(228), // yellow
32
+ info: c256(117), // cyan
33
+ highlight: pc.bold,
34
+ border: "─",
35
+ borderDim: "┄",
36
+ logo: `\x1b[38;5;141m\x1b[1mAcmeCode\x1b[0m \x1b[38;5;103mv1.0\x1b[0m`,
37
+ bgHeader: "#21222c",
38
+ bgInput: "#282a36",
39
+ accentIdle: "#bd93f9",
40
+ accentBusy: "#ffb86c",
41
+ },
42
+ tokyonight: {
43
+ primary: c256(111), // blue
44
+ secondary: c256(176), // magenta
45
+ muted: c256(60), // dark comment
46
+ success: c256(115), // green
47
+ danger: c256(210), // red
48
+ warning: c256(222), // yellow
49
+ info: c256(81), // cyan
50
+ highlight: pc.bold,
51
+ border: "─",
52
+ borderDim: "┄",
53
+ logo: `\x1b[38;5;111m\x1b[1mAcmeCode\x1b[0m \x1b[38;5;60mv1.0\x1b[0m`,
54
+ bgHeader: "#16161e",
55
+ bgInput: "#1a1b26",
56
+ accentIdle: "#7aa2f7",
57
+ accentBusy: "#e0af68",
58
+ },
59
+ nord: {
60
+ primary: c256(110), // frost blue
61
+ secondary: c256(139), // purple
62
+ muted: c256(59), // polar night
63
+ success: c256(108), // aurora green
64
+ danger: c256(174), // aurora red
65
+ warning: c256(179), // aurora yellow
66
+ info: c256(67), // frost darker
67
+ highlight: pc.bold,
68
+ border: "─",
69
+ borderDim: "┄",
70
+ logo: `\x1b[38;5;110m\x1b[1mAcmeCode\x1b[0m \x1b[38;5;59mv1.0\x1b[0m`,
71
+ bgHeader: "#2e3440",
72
+ bgInput: "#3b4252",
73
+ accentIdle: "#88c0d0",
74
+ accentBusy: "#ebcb8b",
75
+ },
76
+ catppuccin: {
77
+ primary: c256(183), // lavender
78
+ secondary: c256(211), // pink
79
+ muted: c256(244), // overlay
80
+ success: c256(120), // green
81
+ danger: c256(210), // red
82
+ warning: c256(223), // peach
83
+ info: c256(152), // teal
84
+ highlight: pc.bold,
85
+ border: "─",
86
+ borderDim: "┄",
87
+ logo: `\x1b[38;5;183m\x1b[1mAcmeCode\x1b[0m \x1b[38;5;244mv1.0\x1b[0m`,
88
+ bgHeader: "#1e1e2e",
89
+ bgInput: "#24273a",
90
+ accentIdle: "#cba6f7",
91
+ accentBusy: "#fab387",
92
+ },
93
+ monokai: {
94
+ primary: c256(81), // cyan
95
+ secondary: c256(148), // green
96
+ muted: c256(242), // comment
97
+ success: c256(148), // green
98
+ danger: c256(204), // pink/red
99
+ warning: c256(186), // yellow
100
+ info: c256(141), // purple
101
+ highlight: pc.bold,
102
+ border: "─",
103
+ borderDim: "┄",
104
+ logo: `\x1b[38;5;81m\x1b[1mAcmeCode\x1b[0m \x1b[38;5;242mv1.0\x1b[0m`,
105
+ bgHeader: "#1e1e1e",
106
+ bgInput: "#272822",
107
+ accentIdle: "#66d9e8",
108
+ accentBusy: "#e6db74",
109
+ },
110
+ gruvbox: {
111
+ primary: c256(214), // orange
112
+ secondary: c256(108), // aqua
113
+ muted: c256(243), // gray
114
+ success: c256(142), // green
115
+ danger: c256(167), // red
116
+ warning: c256(214), // orange
117
+ info: c256(108), // aqua
118
+ highlight: pc.bold,
119
+ border: "─",
120
+ borderDim: "┄",
121
+ logo: `\x1b[38;5;214m\x1b[1mAcmeCode\x1b[0m \x1b[38;5;243mv1.0\x1b[0m`,
122
+ bgHeader: "#1d2021",
123
+ bgInput: "#282828",
124
+ accentIdle: "#fabd2f",
125
+ accentBusy: "#fe8019",
126
+ },
127
+ everforest: {
128
+ primary: c256(108), // green
129
+ secondary: c256(175), // purple
130
+ muted: c256(243), // gray
131
+ success: c256(142), // green
132
+ danger: c256(167), // red
133
+ warning: c256(214), // yellow
134
+ info: c256(109), // blue
135
+ highlight: pc.bold,
136
+ border: "─",
137
+ borderDim: "┄",
138
+ logo: `\x1b[38;5;108m\x1b[1mAcmeCode\x1b[0m \x1b[38;5;243mv1.0\x1b[0m`,
139
+ bgHeader: "#1e2326",
140
+ bgInput: "#272e33",
141
+ accentIdle: "#a7c080",
142
+ accentBusy: "#e69875",
143
+ },
144
+ rosepine: {
145
+ primary: c256(189), // iris
146
+ secondary: c256(217), // rose
147
+ muted: c256(60), // muted
148
+ success: c256(115), // foam
149
+ danger: c256(210), // love
150
+ warning: c256(222), // gold
151
+ info: c256(116), // pine
152
+ highlight: pc.bold,
153
+ border: "─",
154
+ borderDim: "┄",
155
+ logo: `\x1b[38;5;189m\x1b[1mAcmeCode\x1b[0m \x1b[38;5;60mv1.0\x1b[0m`,
156
+ bgHeader: "#191724",
157
+ bgInput: "#1f1d2e",
158
+ accentIdle: "#c4a7e7",
159
+ accentBusy: "#ebbcba",
160
+ },
161
+ solarized: {
162
+ primary: c256(37), // cyan
163
+ secondary: c256(61), // violet
164
+ muted: c256(240), // base01
165
+ success: c256(64), // green
166
+ danger: c256(160), // red
167
+ warning: c256(136), // yellow
168
+ info: c256(33), // blue
169
+ highlight: pc.bold,
170
+ border: "─",
171
+ borderDim: "┄",
172
+ logo: `\x1b[38;5;37m\x1b[1mAcmeCode\x1b[0m \x1b[38;5;240mv1.0\x1b[0m`,
173
+ bgHeader: "#002731",
174
+ bgInput: "#00212b",
175
+ accentIdle: "#2aa198",
176
+ accentBusy: "#b58900",
177
+ },
178
+ };
179
+ // ── Active theme state ──
180
+ let activeThemeName = loadThemeConfig();
181
+ const listeners = [];
182
+ export function getTheme() {
183
+ return themes[activeThemeName] || themes["dark"];
184
+ }
185
+ export function setTheme(name) {
186
+ if (themes[name]) {
187
+ activeThemeName = name;
188
+ saveGlobalThemeConfig(name);
189
+ listeners.forEach((l) => l(name));
190
+ return true;
191
+ }
192
+ return false;
193
+ }
194
+ export function onThemeChange(listener) {
195
+ listeners.push(listener);
196
+ }
197
+ export function getThemeName() {
198
+ return activeThemeName;
199
+ }
200
+ export function listThemes() {
201
+ return Object.keys(themes);
202
+ }
203
+ // ── Re-export active theme (backward compatible) ──
204
+ export const theme = new Proxy({}, {
205
+ get(_target, prop) {
206
+ return getTheme()[prop];
207
+ },
208
+ });
209
+ // ── Formatting helpers ──
210
+ export function formatToolIcon(toolName) {
211
+ const icons = {
212
+ read_file: "📖",
213
+ write_file: "📝",
214
+ run_command: "⚡",
215
+ list_dir: "📂",
216
+ edit_file: "✏️",
217
+ grep_search: "🔍",
218
+ webfetch: "🌐",
219
+ websearch: "🔎",
220
+ codesearch: "💻",
221
+ lsp: "🧠",
222
+ switch_mode: "⚙️",
223
+ batch: "📦",
224
+ browser_action: "🖥️",
225
+ };
226
+ return icons[toolName] || "🔧";
227
+ }
228
+ export function formatToolName(toolName) {
229
+ const key = `tool.${toolName}`;
230
+ const translated = t(key);
231
+ return translated !== key ? translated : toolName;
232
+ }
233
+ export function formatBorder(width, char) {
234
+ return (char || getTheme().border).repeat(width);
235
+ }
236
+ export function formatKeyHint(key, label) {
237
+ const t = getTheme();
238
+ return `${t.muted("[")}${t.primary(key)}${t.muted("]")} ${t.muted(label)}`;
239
+ }
package/output.txt ADDED
Binary file
package/package.json ADDED
@@ -0,0 +1,44 @@
1
+ {
2
+ "name": "acmecode",
3
+ "version": "1.0.0",
4
+ "type": "module",
5
+ "description": "AI Coding Assistant CLI",
6
+ "main": "dist/cli/index.js",
7
+ "bin": {
8
+ "acmecode": "dist/cli/bin/acmecode.js"
9
+ },
10
+ "scripts": {
11
+ "build": "tsc -p tsconfig.json",
12
+ "start": "node dist/index.js",
13
+ "dev": "tsx bin/acmecode.ts",
14
+ "prepublishOnly": "npm run build"
15
+ },
16
+ "dependencies": {
17
+ "ai": "^4.1.0",
18
+ "@ai-sdk/anthropic": "^1.1.0",
19
+ "@ai-sdk/deepinfra": "^0.1.0",
20
+ "@ai-sdk/google": "^1.2.0",
21
+ "@ai-sdk/groq": "^0.1.0",
22
+ "@ai-sdk/mistral": "^0.1.0",
23
+ "@ai-sdk/openai": "^1.1.0",
24
+ "@ai-sdk/xai": "^0.1.0",
25
+ "@openrouter/ai-sdk-provider": "^0.1.0",
26
+ "better-sqlite3": "^11.8.1",
27
+ "chalk": "^5.4.1",
28
+ "commander": "^14.0.3",
29
+ "dotenv": "^16.5.0",
30
+ "ink": "^6.8.0",
31
+ "react": "^19.2.4",
32
+ "zod": "^3.25.0"
33
+ },
34
+ "devDependencies": {
35
+ "@types/better-sqlite3": "^7.6.13",
36
+ "@types/node": "^25.3.0",
37
+ "@types/react": "^19.2.14",
38
+ "tsx": "^4.21.0",
39
+ "typescript": "^5.9.3"
40
+ },
41
+ "engines": {
42
+ "node": ">=18"
43
+ }
44
+ }
@@ -0,0 +1,25 @@
1
+ {
2
+ "name": "@acmecode/cli",
3
+ "version": "1.0.0",
4
+ "type": "module",
5
+ "main": "dist/index.js",
6
+ "bin": {
7
+ "acmecode": "bin/acmecode.js"
8
+ },
9
+ "scripts": {
10
+ "build": "tsc",
11
+ "start": "node dist/index.js",
12
+ "dev": "tsx src/index.ts"
13
+ },
14
+ "dependencies": {
15
+ "@acmecode/core": "^1.0.0",
16
+ "@acmecode/tui": "^1.0.0",
17
+ "commander": "^14.0.3",
18
+ "ink": "^6.8.0",
19
+ "react": "^19.2.4"
20
+ },
21
+ "devDependencies": {
22
+ "@types/node": "^25.3.0",
23
+ "@types/react": "^19.2.14"
24
+ }
25
+ }