codemaxxing 1.0.0 → 1.0.2

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 (47) hide show
  1. package/README.md +18 -12
  2. package/dist/agent.d.ts +4 -0
  3. package/dist/agent.js +91 -16
  4. package/dist/commands/git.d.ts +2 -0
  5. package/dist/commands/git.js +50 -0
  6. package/dist/commands/ollama.d.ts +27 -0
  7. package/dist/commands/ollama.js +171 -0
  8. package/dist/commands/output.d.ts +2 -0
  9. package/dist/commands/output.js +18 -0
  10. package/dist/commands/registry.d.ts +2 -0
  11. package/dist/commands/registry.js +8 -0
  12. package/dist/commands/skills.d.ts +18 -0
  13. package/dist/commands/skills.js +121 -0
  14. package/dist/commands/types.d.ts +5 -0
  15. package/dist/commands/types.js +1 -0
  16. package/dist/commands/ui.d.ts +16 -0
  17. package/dist/commands/ui.js +79 -0
  18. package/dist/config.d.ts +9 -0
  19. package/dist/config.js +13 -3
  20. package/dist/exec.js +4 -1
  21. package/dist/index.js +75 -401
  22. package/dist/tools/files.js +58 -3
  23. package/dist/utils/context.js +6 -0
  24. package/dist/utils/mcp.d.ts +7 -2
  25. package/dist/utils/mcp.js +34 -6
  26. package/package.json +8 -5
  27. package/src/agent.ts +0 -894
  28. package/src/auth-cli.ts +0 -287
  29. package/src/cli.ts +0 -37
  30. package/src/config.ts +0 -352
  31. package/src/exec.ts +0 -183
  32. package/src/index.tsx +0 -2647
  33. package/src/skills/registry.ts +0 -1436
  34. package/src/themes.ts +0 -335
  35. package/src/tools/files.ts +0 -374
  36. package/src/utils/auth.ts +0 -606
  37. package/src/utils/context.ts +0 -174
  38. package/src/utils/git.ts +0 -117
  39. package/src/utils/hardware.ts +0 -131
  40. package/src/utils/lint.ts +0 -116
  41. package/src/utils/mcp.ts +0 -307
  42. package/src/utils/models.ts +0 -218
  43. package/src/utils/ollama.ts +0 -352
  44. package/src/utils/repomap.ts +0 -220
  45. package/src/utils/sessions.ts +0 -254
  46. package/src/utils/skills.ts +0 -241
  47. package/tsconfig.json +0 -16
@@ -0,0 +1,121 @@
1
+ import { listInstalledSkills, installSkill, removeSkill, searchRegistry, createSkillScaffold, getActiveSkills, } from "../utils/skills.js";
2
+ export function tryHandleSkillsCommand(options) {
3
+ const { trimmed, cwd, addMsg, agent, sessionDisabledSkills, setSkillsPicker, setSkillsPickerIndex, setSessionDisabledSkills, setInput, setInputKey, } = options;
4
+ if (trimmed === "/skills") {
5
+ setSkillsPicker("menu");
6
+ setSkillsPickerIndex(0);
7
+ return true;
8
+ }
9
+ if (trimmed.startsWith("/skills install ")) {
10
+ const name = trimmed.replace("/skills install ", "").trim();
11
+ const result = installSkill(name);
12
+ addMsg(result.ok ? "info" : "error", result.ok ? `✅ ${result.message}` : `✗ ${result.message}`);
13
+ return true;
14
+ }
15
+ if (trimmed.startsWith("/skills remove ")) {
16
+ const name = trimmed.replace("/skills remove ", "").trim();
17
+ const result = removeSkill(name);
18
+ addMsg(result.ok ? "info" : "error", result.ok ? `✅ ${result.message}` : `✗ ${result.message}`);
19
+ return true;
20
+ }
21
+ if (trimmed === "/skills list") {
22
+ const installed = listInstalledSkills();
23
+ if (installed.length === 0) {
24
+ addMsg("info", "No skills installed. Use /skills to browse & install.");
25
+ }
26
+ else {
27
+ const active = getActiveSkills(cwd, sessionDisabledSkills);
28
+ const lines = installed.map((skill) => {
29
+ const isActive = active.includes(skill.name);
30
+ const disabledBySession = sessionDisabledSkills.has(skill.name);
31
+ const status = disabledBySession ? " (off)" : isActive ? " (on)" : "";
32
+ return ` ${isActive ? "●" : "○"} ${skill.name} — ${skill.description}${status}`;
33
+ });
34
+ addMsg("info", `Installed skills:\n${lines.join("\n")}`);
35
+ }
36
+ return true;
37
+ }
38
+ if (trimmed === "/skills search") {
39
+ addMsg("info", "Usage: /skills search <query>");
40
+ return true;
41
+ }
42
+ if (trimmed.startsWith("/skills search ")) {
43
+ const query = trimmed.replace("/skills search ", "").trim();
44
+ if (!query) {
45
+ addMsg("info", "Usage: /skills search <query>");
46
+ return true;
47
+ }
48
+ const results = searchRegistry(query);
49
+ if (results.length === 0) {
50
+ addMsg("info", `No skills found matching "${query}".`);
51
+ }
52
+ else {
53
+ const installed = listInstalledSkills().map((skill) => skill.name);
54
+ const lines = results.map((skill) => {
55
+ const mark = installed.includes(skill.name) ? " ✓" : "";
56
+ return ` ${skill.name} — ${skill.description}${mark}`;
57
+ });
58
+ addMsg("info", `Registry matches:\n${lines.join("\n")}`);
59
+ }
60
+ return true;
61
+ }
62
+ if (trimmed.startsWith("/skills create ")) {
63
+ const name = trimmed.replace("/skills create ", "").trim();
64
+ if (!name) {
65
+ addMsg("info", "Usage: /skills create <name>");
66
+ return true;
67
+ }
68
+ const result = createSkillScaffold(name);
69
+ addMsg(result.ok ? "info" : "error", result.ok ? `✅ ${result.message}\n Edit: ${result.path}/prompt.md` : `✗ ${result.message}`);
70
+ return true;
71
+ }
72
+ if (trimmed === "/skills on") {
73
+ addMsg("info", "Usage: /skills on <name>");
74
+ return true;
75
+ }
76
+ if (trimmed.startsWith("/skills on ")) {
77
+ const name = trimmed.replace("/skills on ", "").trim();
78
+ const installed = listInstalledSkills().map((skill) => skill.name);
79
+ if (!installed.includes(name)) {
80
+ addMsg("error", `Skill "${name}" is not installed.`);
81
+ return true;
82
+ }
83
+ setSessionDisabledSkills((prev) => {
84
+ const next = new Set(prev);
85
+ next.delete(name);
86
+ return next;
87
+ });
88
+ if (agent)
89
+ agent.enableSkill(name);
90
+ addMsg("info", `✅ Enabled skill: ${name}`);
91
+ return true;
92
+ }
93
+ if (trimmed === "/skills off") {
94
+ addMsg("info", "Usage: /skills off <name>");
95
+ return true;
96
+ }
97
+ if (trimmed.startsWith("/skills off ")) {
98
+ const name = trimmed.replace("/skills off ", "").trim();
99
+ const installed = listInstalledSkills().map((skill) => skill.name);
100
+ if (!installed.includes(name)) {
101
+ addMsg("error", `Skill "${name}" is not installed.`);
102
+ return true;
103
+ }
104
+ setSessionDisabledSkills((prev) => {
105
+ const next = new Set(prev);
106
+ next.add(name);
107
+ return next;
108
+ });
109
+ if (agent)
110
+ agent.disableSkill(name);
111
+ addMsg("info", `✅ Disabled skill: ${name} (session only)`);
112
+ return true;
113
+ }
114
+ if (trimmed.startsWith("/skills create")) {
115
+ setSkillsPicker(null);
116
+ setInput("/skills create ");
117
+ setInputKey((key) => key + 1);
118
+ return true;
119
+ }
120
+ return false;
121
+ }
@@ -0,0 +1,5 @@
1
+ export type AddMsg = (type: "user" | "response" | "tool" | "tool-result" | "error" | "info", text: string) => void;
2
+ export interface CommandRegistryContext {
3
+ trimmed: string;
4
+ }
5
+ export type CommandRegistryHandler<TContext extends CommandRegistryContext = CommandRegistryContext> = (context: TContext) => boolean | Promise<boolean>;
@@ -0,0 +1 @@
1
+ export {};
@@ -0,0 +1,16 @@
1
+ import { type Dispatch, type SetStateAction } from "react";
2
+ import type { CodingAgent } from "../agent.js";
3
+ import { type Theme } from "../themes.js";
4
+ import type { AddMsg } from "./types.js";
5
+ interface HandleUiCommandOptions {
6
+ trimmed: string;
7
+ cwd: string;
8
+ addMsg: AddMsg;
9
+ agent: CodingAgent | null;
10
+ theme: Theme;
11
+ setTheme: Dispatch<SetStateAction<Theme>>;
12
+ setThemePicker: Dispatch<SetStateAction<boolean>>;
13
+ setThemePickerIndex: Dispatch<SetStateAction<number>>;
14
+ }
15
+ export declare function tryHandleUiCommand(options: HandleUiCommandOptions): Promise<boolean>;
16
+ export {};
@@ -0,0 +1,79 @@
1
+ import { loadConfig } from "../config.js";
2
+ import { THEMES, getTheme, listThemes } from "../themes.js";
3
+ export async function tryHandleUiCommand(options) {
4
+ const { trimmed, cwd, addMsg, agent, theme, setTheme, setThemePicker, setThemePickerIndex, } = options;
5
+ if (trimmed.startsWith("/theme")) {
6
+ const themeName = trimmed.replace("/theme", "").trim();
7
+ if (!themeName) {
8
+ const themeKeys = listThemes();
9
+ const currentIdx = themeKeys.indexOf(theme.name.toLowerCase());
10
+ setThemePicker(true);
11
+ setThemePickerIndex(currentIdx >= 0 ? currentIdx : 0);
12
+ return true;
13
+ }
14
+ if (!THEMES[themeName]) {
15
+ addMsg("error", `Theme "${themeName}" not found. Use /theme to see available themes.`);
16
+ return true;
17
+ }
18
+ setTheme(getTheme(themeName));
19
+ addMsg("info", `✅ Switched to theme: ${THEMES[themeName].name}`);
20
+ return true;
21
+ }
22
+ if (trimmed === "/architect") {
23
+ if (!agent) {
24
+ addMsg("info", "🏗️ Architect mode: no agent connected. Connect first with /login or /connect.");
25
+ return true;
26
+ }
27
+ const current = agent.getArchitectModel();
28
+ if (current) {
29
+ agent.setArchitectModel(null);
30
+ addMsg("info", "🏗️ Architect mode OFF");
31
+ }
32
+ else {
33
+ const defaultModel = loadConfig().defaults.architectModel || agent.getModel();
34
+ agent.setArchitectModel(defaultModel);
35
+ addMsg("info", `🏗️ Architect mode ON (planner: ${defaultModel})`);
36
+ }
37
+ return true;
38
+ }
39
+ if (trimmed.startsWith("/architect ")) {
40
+ const model = trimmed.replace("/architect ", "").trim();
41
+ if (!model) {
42
+ addMsg("info", "Usage: /architect <model> or /architect to toggle");
43
+ return true;
44
+ }
45
+ if (agent) {
46
+ agent.setArchitectModel(model);
47
+ addMsg("info", `🏗️ Architect mode ON (planner: ${model})`);
48
+ }
49
+ else {
50
+ addMsg("info", "⚠ No agent connected. Connect first.");
51
+ }
52
+ return true;
53
+ }
54
+ if (trimmed === "/lint") {
55
+ const { detectLinter } = await import("../utils/lint.js");
56
+ const linter = detectLinter(cwd);
57
+ const enabled = agent ? agent.isAutoLintEnabled() : true;
58
+ if (linter) {
59
+ addMsg("info", `🔍 Auto-lint: ${enabled ? "ON" : "OFF"}\n Detected: ${linter.name}\n Command: ${linter.command} <file>`);
60
+ }
61
+ else {
62
+ addMsg("info", `🔍 Auto-lint: ${enabled ? "ON" : "OFF"}\n No linter detected in this project.`);
63
+ }
64
+ return true;
65
+ }
66
+ if (trimmed === "/lint on") {
67
+ if (agent)
68
+ agent.setAutoLint(true);
69
+ addMsg("info", "🔍 Auto-lint ON");
70
+ return true;
71
+ }
72
+ if (trimmed === "/lint off") {
73
+ if (agent)
74
+ agent.setAutoLint(false);
75
+ addMsg("info", "🔍 Auto-lint OFF");
76
+ return true;
77
+ }
78
+ return false;
79
+ }
package/dist/config.d.ts CHANGED
@@ -62,3 +62,12 @@ export declare function listModels(baseUrl: string, apiKey: string): Promise<str
62
62
  * Priority: CLI args > auth store > config file > auto-detect
63
63
  */
64
64
  export declare function resolveProvider(providerId: string, cliArgs: CLIArgs): ProviderConfig | null;
65
+ /**
66
+ * Detect provider transport type.
67
+ *
68
+ * Important: model family does NOT decide this. OpenRouter, Gemini-compatible,
69
+ * Qwen-compatible, Copilot, LM Studio, Ollama, and custom OpenAI-compatible
70
+ * endpoints should all stay on the OpenAI-compatible transport even when the
71
+ * selected model is Claude.
72
+ */
73
+ export declare function detectProviderType(providerId: string, baseUrl: string): "openai" | "anthropic";
package/dist/config.js CHANGED
@@ -280,10 +280,20 @@ export function resolveProvider(providerId, cliArgs) {
280
280
  return null;
281
281
  }
282
282
  /**
283
- * Detect provider type from ID or base URL
283
+ * Detect provider transport type.
284
+ *
285
+ * Important: model family does NOT decide this. OpenRouter, Gemini-compatible,
286
+ * Qwen-compatible, Copilot, LM Studio, Ollama, and custom OpenAI-compatible
287
+ * endpoints should all stay on the OpenAI-compatible transport even when the
288
+ * selected model is Claude.
284
289
  */
285
- function detectProviderType(providerId, baseUrl) {
286
- if (providerId === "anthropic" || baseUrl.includes("anthropic.com")) {
290
+ export function detectProviderType(providerId, baseUrl) {
291
+ const id = providerId.toLowerCase();
292
+ const url = baseUrl.toLowerCase();
293
+ if (id === "anthropic")
294
+ return "anthropic";
295
+ // Only treat Anthropic's native API as anthropic transport.
296
+ if (url.includes("api.anthropic.com") || url.includes("api.us.anthropic.com")) {
287
297
  return "anthropic";
288
298
  }
289
299
  return "openai";
package/dist/exec.js CHANGED
@@ -151,7 +151,10 @@ export async function runExec(argv) {
151
151
  process.stdout.write(JSON.stringify(output, null, 2) + "\n");
152
152
  }
153
153
  await disconnectAll();
154
- process.exit(hasChanges ? 0 : 2);
154
+ // Exit 0 = success (always, with or without file changes)
155
+ // Exit 2 = no file changes were made (useful for CI scripts that check if work was done)
156
+ // Only exit(1) is reserved for actual errors (see catch block below)
157
+ process.exit(0);
155
158
  }
156
159
  catch (err) {
157
160
  await disconnectAll();