codemaxxing 0.1.13 → 0.2.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.
- package/dist/agent.d.ts +6 -0
- package/dist/agent.js +19 -1
- package/dist/index.js +271 -3
- package/dist/skills/registry.d.ts +13 -0
- package/dist/skills/registry.js +472 -0
- package/dist/themes.js +37 -77
- package/dist/utils/context.d.ts +1 -1
- package/dist/utils/context.js +6 -2
- package/dist/utils/skills.d.ts +60 -0
- package/dist/utils/skills.js +203 -0
- package/package.json +1 -1
- package/src/agent.ts +24 -1
- package/src/index.tsx +316 -1
- package/src/skills/registry.ts +482 -0
- package/src/themes.ts +39 -77
- package/src/utils/context.ts +8 -2
- package/src/utils/skills.ts +241 -0
package/dist/agent.d.ts
CHANGED
|
@@ -34,6 +34,7 @@ export declare class CodingAgent {
|
|
|
34
34
|
private totalCost;
|
|
35
35
|
private systemPrompt;
|
|
36
36
|
private compressionThreshold;
|
|
37
|
+
private sessionDisabledSkills;
|
|
37
38
|
constructor(options: AgentOptions);
|
|
38
39
|
/**
|
|
39
40
|
* Initialize the agent — call this after constructor to build async context
|
|
@@ -91,5 +92,10 @@ export declare class CodingAgent {
|
|
|
91
92
|
completionTokens: number;
|
|
92
93
|
totalCost: number;
|
|
93
94
|
};
|
|
95
|
+
disableSkill(name: string): void;
|
|
96
|
+
enableSkill(name: string): void;
|
|
97
|
+
getSessionDisabledSkills(): Set<string>;
|
|
98
|
+
getActiveSkillCount(): number;
|
|
99
|
+
getCwd(): string;
|
|
94
100
|
reset(): void;
|
|
95
101
|
}
|
package/dist/agent.js
CHANGED
|
@@ -3,6 +3,7 @@ import Anthropic from "@anthropic-ai/sdk";
|
|
|
3
3
|
import { FILE_TOOLS, executeTool, generateDiff, getExistingContent } from "./tools/files.js";
|
|
4
4
|
import { buildProjectContext, getSystemPrompt } from "./utils/context.js";
|
|
5
5
|
import { isGitRepo, autoCommit } from "./utils/git.js";
|
|
6
|
+
import { buildSkillPrompts, getActiveSkillCount } from "./utils/skills.js";
|
|
6
7
|
import { createSession, saveMessage, updateTokenEstimate, updateSessionCost, loadMessages } from "./utils/sessions.js";
|
|
7
8
|
// Tools that can modify your project — require approval
|
|
8
9
|
const DANGEROUS_TOOLS = new Set(["write_file", "run_command"]);
|
|
@@ -71,6 +72,7 @@ export class CodingAgent {
|
|
|
71
72
|
totalCost = 0;
|
|
72
73
|
systemPrompt = "";
|
|
73
74
|
compressionThreshold;
|
|
75
|
+
sessionDisabledSkills = new Set();
|
|
74
76
|
constructor(options) {
|
|
75
77
|
this.options = options;
|
|
76
78
|
this.providerType = options.provider.type || "openai";
|
|
@@ -99,7 +101,8 @@ export class CodingAgent {
|
|
|
99
101
|
*/
|
|
100
102
|
async init() {
|
|
101
103
|
const context = await buildProjectContext(this.cwd);
|
|
102
|
-
|
|
104
|
+
const skillPrompts = buildSkillPrompts(this.cwd, this.sessionDisabledSkills);
|
|
105
|
+
this.systemPrompt = await getSystemPrompt(context, skillPrompts);
|
|
103
106
|
this.messages = [
|
|
104
107
|
{ role: "system", content: this.systemPrompt },
|
|
105
108
|
];
|
|
@@ -614,6 +617,21 @@ export class CodingAgent {
|
|
|
614
617
|
totalCost: this.totalCost,
|
|
615
618
|
};
|
|
616
619
|
}
|
|
620
|
+
disableSkill(name) {
|
|
621
|
+
this.sessionDisabledSkills.add(name);
|
|
622
|
+
}
|
|
623
|
+
enableSkill(name) {
|
|
624
|
+
this.sessionDisabledSkills.delete(name);
|
|
625
|
+
}
|
|
626
|
+
getSessionDisabledSkills() {
|
|
627
|
+
return this.sessionDisabledSkills;
|
|
628
|
+
}
|
|
629
|
+
getActiveSkillCount() {
|
|
630
|
+
return getActiveSkillCount(this.cwd, this.sessionDisabledSkills);
|
|
631
|
+
}
|
|
632
|
+
getCwd() {
|
|
633
|
+
return this.cwd;
|
|
634
|
+
}
|
|
617
635
|
reset() {
|
|
618
636
|
const systemMsg = this.messages[0];
|
|
619
637
|
this.messages = [systemMsg];
|
package/dist/index.js
CHANGED
|
@@ -11,6 +11,7 @@ import { execSync } from "child_process";
|
|
|
11
11
|
import { isGitRepo, getBranch, getStatus, getDiff, undoLastCommit } from "./utils/git.js";
|
|
12
12
|
import { getTheme, listThemes, THEMES, DEFAULT_THEME } from "./themes.js";
|
|
13
13
|
import { PROVIDERS, getCredentials, openRouterOAuth, anthropicSetupToken, importCodexToken, importQwenToken, copilotDeviceFlow } from "./utils/auth.js";
|
|
14
|
+
import { listInstalledSkills, installSkill, removeSkill, getRegistrySkills, searchRegistry, createSkillScaffold, getActiveSkills, getActiveSkillCount } from "./utils/skills.js";
|
|
14
15
|
const VERSION = "0.1.9";
|
|
15
16
|
// ── Helpers ──
|
|
16
17
|
function formatTimeAgo(date) {
|
|
@@ -46,6 +47,13 @@ const SLASH_COMMANDS = [
|
|
|
46
47
|
{ cmd: "/sessions", desc: "list past sessions" },
|
|
47
48
|
{ cmd: "/session delete", desc: "delete a session" },
|
|
48
49
|
{ cmd: "/resume", desc: "resume a past session" },
|
|
50
|
+
{ cmd: "/skills", desc: "manage skill packs" },
|
|
51
|
+
{ cmd: "/skills install", desc: "install a skill" },
|
|
52
|
+
{ cmd: "/skills remove", desc: "remove a skill" },
|
|
53
|
+
{ cmd: "/skills list", desc: "show installed skills" },
|
|
54
|
+
{ cmd: "/skills search", desc: "search registry" },
|
|
55
|
+
{ cmd: "/skills on", desc: "enable skill for session" },
|
|
56
|
+
{ cmd: "/skills off", desc: "disable skill for session" },
|
|
49
57
|
{ cmd: "/quit", desc: "exit" },
|
|
50
58
|
];
|
|
51
59
|
const SPINNER_FRAMES = ["⣾", "⣽", "⣻", "⢿", "⡿", "⣟", "⣯", "⣷"];
|
|
@@ -115,6 +123,9 @@ function App() {
|
|
|
115
123
|
const [loginPickerIndex, setLoginPickerIndex] = useState(0);
|
|
116
124
|
const [loginMethodPicker, setLoginMethodPicker] = useState(null);
|
|
117
125
|
const [loginMethodIndex, setLoginMethodIndex] = useState(0);
|
|
126
|
+
const [skillsPicker, setSkillsPicker] = useState(null);
|
|
127
|
+
const [skillsPickerIndex, setSkillsPickerIndex] = useState(0);
|
|
128
|
+
const [sessionDisabledSkills, setSessionDisabledSkills] = useState(new Set());
|
|
118
129
|
const [approval, setApproval] = useState(null);
|
|
119
130
|
// Listen for paste events from stdin interceptor
|
|
120
131
|
useEffect(() => {
|
|
@@ -274,7 +285,9 @@ function App() {
|
|
|
274
285
|
const selected = matches[idx];
|
|
275
286
|
if (selected) {
|
|
276
287
|
// Commands that need args (like /commit, /model) — fill input instead of executing
|
|
277
|
-
if (selected.cmd === "/commit" || selected.cmd === "/model" || selected.cmd === "/session delete"
|
|
288
|
+
if (selected.cmd === "/commit" || selected.cmd === "/model" || selected.cmd === "/session delete" ||
|
|
289
|
+
selected.cmd === "/skills install" || selected.cmd === "/skills remove" || selected.cmd === "/skills search" ||
|
|
290
|
+
selected.cmd === "/skills on" || selected.cmd === "/skills off") {
|
|
278
291
|
setInput(selected.cmd + " ");
|
|
279
292
|
setCmdIndex(0);
|
|
280
293
|
setInputKey((k) => k + 1);
|
|
@@ -333,10 +346,98 @@ function App() {
|
|
|
333
346
|
" /push — push to remote",
|
|
334
347
|
" /git on — enable auto-commits",
|
|
335
348
|
" /git off — disable auto-commits",
|
|
349
|
+
" /skills — manage skill packs",
|
|
336
350
|
" /quit — exit",
|
|
337
351
|
].join("\n"));
|
|
338
352
|
return;
|
|
339
353
|
}
|
|
354
|
+
// ── Skills commands (work without agent) ──
|
|
355
|
+
if (trimmed === "/skills") {
|
|
356
|
+
setSkillsPicker("menu");
|
|
357
|
+
setSkillsPickerIndex(0);
|
|
358
|
+
return;
|
|
359
|
+
}
|
|
360
|
+
if (trimmed.startsWith("/skills install ")) {
|
|
361
|
+
const name = trimmed.replace("/skills install ", "").trim();
|
|
362
|
+
const result = installSkill(name);
|
|
363
|
+
addMsg(result.ok ? "info" : "error", result.ok ? `✅ ${result.message}` : `✗ ${result.message}`);
|
|
364
|
+
return;
|
|
365
|
+
}
|
|
366
|
+
if (trimmed.startsWith("/skills remove ")) {
|
|
367
|
+
const name = trimmed.replace("/skills remove ", "").trim();
|
|
368
|
+
const result = removeSkill(name);
|
|
369
|
+
addMsg(result.ok ? "info" : "error", result.ok ? `✅ ${result.message}` : `✗ ${result.message}`);
|
|
370
|
+
return;
|
|
371
|
+
}
|
|
372
|
+
if (trimmed === "/skills list") {
|
|
373
|
+
const installed = listInstalledSkills();
|
|
374
|
+
if (installed.length === 0) {
|
|
375
|
+
addMsg("info", "No skills installed. Use /skills to browse & install.");
|
|
376
|
+
}
|
|
377
|
+
else {
|
|
378
|
+
const active = getActiveSkills(process.cwd(), sessionDisabledSkills);
|
|
379
|
+
const lines = installed.map((s) => {
|
|
380
|
+
const isActive = active.includes(s.name);
|
|
381
|
+
const disabledBySession = sessionDisabledSkills.has(s.name);
|
|
382
|
+
const status = disabledBySession ? " (off)" : isActive ? " (on)" : "";
|
|
383
|
+
return ` ${isActive ? "●" : "○"} ${s.name} — ${s.description}${status}`;
|
|
384
|
+
});
|
|
385
|
+
addMsg("info", `Installed skills:\n${lines.join("\n")}`);
|
|
386
|
+
}
|
|
387
|
+
return;
|
|
388
|
+
}
|
|
389
|
+
if (trimmed.startsWith("/skills search ")) {
|
|
390
|
+
const query = trimmed.replace("/skills search ", "").trim();
|
|
391
|
+
const results = searchRegistry(query);
|
|
392
|
+
if (results.length === 0) {
|
|
393
|
+
addMsg("info", `No skills found matching "${query}".`);
|
|
394
|
+
}
|
|
395
|
+
else {
|
|
396
|
+
const installed = listInstalledSkills().map((s) => s.name);
|
|
397
|
+
const lines = results.map((s) => {
|
|
398
|
+
const mark = installed.includes(s.name) ? " ✓" : "";
|
|
399
|
+
return ` ${s.name} — ${s.description}${mark}`;
|
|
400
|
+
});
|
|
401
|
+
addMsg("info", `Registry matches:\n${lines.join("\n")}`);
|
|
402
|
+
}
|
|
403
|
+
return;
|
|
404
|
+
}
|
|
405
|
+
if (trimmed.startsWith("/skills create ")) {
|
|
406
|
+
const name = trimmed.replace("/skills create ", "").trim();
|
|
407
|
+
if (!name) {
|
|
408
|
+
addMsg("info", "Usage: /skills create <name>");
|
|
409
|
+
return;
|
|
410
|
+
}
|
|
411
|
+
const result = createSkillScaffold(name);
|
|
412
|
+
addMsg(result.ok ? "info" : "error", result.ok ? `✅ ${result.message}\n Edit: ${result.path}/prompt.md` : `✗ ${result.message}`);
|
|
413
|
+
return;
|
|
414
|
+
}
|
|
415
|
+
if (trimmed.startsWith("/skills on ")) {
|
|
416
|
+
const name = trimmed.replace("/skills on ", "").trim();
|
|
417
|
+
const installed = listInstalledSkills().map((s) => s.name);
|
|
418
|
+
if (!installed.includes(name)) {
|
|
419
|
+
addMsg("error", `Skill "${name}" is not installed.`);
|
|
420
|
+
return;
|
|
421
|
+
}
|
|
422
|
+
setSessionDisabledSkills((prev) => { const next = new Set(prev); next.delete(name); return next; });
|
|
423
|
+
if (agent)
|
|
424
|
+
agent.enableSkill(name);
|
|
425
|
+
addMsg("info", `✅ Enabled skill: ${name}`);
|
|
426
|
+
return;
|
|
427
|
+
}
|
|
428
|
+
if (trimmed.startsWith("/skills off ")) {
|
|
429
|
+
const name = trimmed.replace("/skills off ", "").trim();
|
|
430
|
+
const installed = listInstalledSkills().map((s) => s.name);
|
|
431
|
+
if (!installed.includes(name)) {
|
|
432
|
+
addMsg("error", `Skill "${name}" is not installed.`);
|
|
433
|
+
return;
|
|
434
|
+
}
|
|
435
|
+
setSessionDisabledSkills((prev) => { const next = new Set(prev); next.add(name); return next; });
|
|
436
|
+
if (agent)
|
|
437
|
+
agent.disableSkill(name);
|
|
438
|
+
addMsg("info", `✅ Disabled skill: ${name} (session only)`);
|
|
439
|
+
return;
|
|
440
|
+
}
|
|
340
441
|
if (trimmed.startsWith("/theme")) {
|
|
341
442
|
const themeName = trimmed.replace("/theme", "").trim();
|
|
342
443
|
if (!themeName) {
|
|
@@ -701,6 +802,154 @@ function App() {
|
|
|
701
802
|
}
|
|
702
803
|
return;
|
|
703
804
|
}
|
|
805
|
+
// Skills picker navigation
|
|
806
|
+
if (skillsPicker) {
|
|
807
|
+
if (skillsPicker === "menu") {
|
|
808
|
+
const menuItems = ["browse", "installed", "create", "remove"];
|
|
809
|
+
if (key.upArrow) {
|
|
810
|
+
setSkillsPickerIndex((prev) => (prev - 1 + menuItems.length) % menuItems.length);
|
|
811
|
+
return;
|
|
812
|
+
}
|
|
813
|
+
if (key.downArrow) {
|
|
814
|
+
setSkillsPickerIndex((prev) => (prev + 1) % menuItems.length);
|
|
815
|
+
return;
|
|
816
|
+
}
|
|
817
|
+
if (key.escape) {
|
|
818
|
+
setSkillsPicker(null);
|
|
819
|
+
return;
|
|
820
|
+
}
|
|
821
|
+
if (key.return) {
|
|
822
|
+
const selected = menuItems[skillsPickerIndex];
|
|
823
|
+
if (selected === "browse") {
|
|
824
|
+
setSkillsPicker("browse");
|
|
825
|
+
setSkillsPickerIndex(0);
|
|
826
|
+
}
|
|
827
|
+
else if (selected === "installed") {
|
|
828
|
+
setSkillsPicker("installed");
|
|
829
|
+
setSkillsPickerIndex(0);
|
|
830
|
+
}
|
|
831
|
+
else if (selected === "create") {
|
|
832
|
+
setSkillsPicker(null);
|
|
833
|
+
setInput("/skills create ");
|
|
834
|
+
setInputKey((k) => k + 1);
|
|
835
|
+
}
|
|
836
|
+
else if (selected === "remove") {
|
|
837
|
+
const installed = listInstalledSkills();
|
|
838
|
+
if (installed.length === 0) {
|
|
839
|
+
setSkillsPicker(null);
|
|
840
|
+
addMsg("info", "No skills installed to remove.");
|
|
841
|
+
}
|
|
842
|
+
else {
|
|
843
|
+
setSkillsPicker("remove");
|
|
844
|
+
setSkillsPickerIndex(0);
|
|
845
|
+
}
|
|
846
|
+
}
|
|
847
|
+
return;
|
|
848
|
+
}
|
|
849
|
+
return;
|
|
850
|
+
}
|
|
851
|
+
if (skillsPicker === "browse") {
|
|
852
|
+
const registry = getRegistrySkills();
|
|
853
|
+
if (key.upArrow) {
|
|
854
|
+
setSkillsPickerIndex((prev) => (prev - 1 + registry.length) % registry.length);
|
|
855
|
+
return;
|
|
856
|
+
}
|
|
857
|
+
if (key.downArrow) {
|
|
858
|
+
setSkillsPickerIndex((prev) => (prev + 1) % registry.length);
|
|
859
|
+
return;
|
|
860
|
+
}
|
|
861
|
+
if (key.escape) {
|
|
862
|
+
setSkillsPicker("menu");
|
|
863
|
+
setSkillsPickerIndex(0);
|
|
864
|
+
return;
|
|
865
|
+
}
|
|
866
|
+
if (key.return) {
|
|
867
|
+
const selected = registry[skillsPickerIndex];
|
|
868
|
+
if (selected) {
|
|
869
|
+
const result = installSkill(selected.name);
|
|
870
|
+
addMsg(result.ok ? "info" : "error", result.ok ? `✅ ${result.message}` : `✗ ${result.message}`);
|
|
871
|
+
}
|
|
872
|
+
setSkillsPicker(null);
|
|
873
|
+
return;
|
|
874
|
+
}
|
|
875
|
+
return;
|
|
876
|
+
}
|
|
877
|
+
if (skillsPicker === "installed") {
|
|
878
|
+
const installed = listInstalledSkills();
|
|
879
|
+
if (installed.length === 0) {
|
|
880
|
+
setSkillsPicker("menu");
|
|
881
|
+
setSkillsPickerIndex(0);
|
|
882
|
+
addMsg("info", "No skills installed.");
|
|
883
|
+
return;
|
|
884
|
+
}
|
|
885
|
+
if (key.upArrow) {
|
|
886
|
+
setSkillsPickerIndex((prev) => (prev - 1 + installed.length) % installed.length);
|
|
887
|
+
return;
|
|
888
|
+
}
|
|
889
|
+
if (key.downArrow) {
|
|
890
|
+
setSkillsPickerIndex((prev) => (prev + 1) % installed.length);
|
|
891
|
+
return;
|
|
892
|
+
}
|
|
893
|
+
if (key.escape) {
|
|
894
|
+
setSkillsPicker("menu");
|
|
895
|
+
setSkillsPickerIndex(0);
|
|
896
|
+
return;
|
|
897
|
+
}
|
|
898
|
+
if (key.return) {
|
|
899
|
+
// Toggle on/off for session
|
|
900
|
+
const selected = installed[skillsPickerIndex];
|
|
901
|
+
if (selected) {
|
|
902
|
+
const isDisabled = sessionDisabledSkills.has(selected.name);
|
|
903
|
+
if (isDisabled) {
|
|
904
|
+
setSessionDisabledSkills((prev) => { const next = new Set(prev); next.delete(selected.name); return next; });
|
|
905
|
+
if (agent)
|
|
906
|
+
agent.enableSkill(selected.name);
|
|
907
|
+
addMsg("info", `✅ Enabled: ${selected.name}`);
|
|
908
|
+
}
|
|
909
|
+
else {
|
|
910
|
+
setSessionDisabledSkills((prev) => { const next = new Set(prev); next.add(selected.name); return next; });
|
|
911
|
+
if (agent)
|
|
912
|
+
agent.disableSkill(selected.name);
|
|
913
|
+
addMsg("info", `✅ Disabled: ${selected.name} (session only)`);
|
|
914
|
+
}
|
|
915
|
+
}
|
|
916
|
+
setSkillsPicker(null);
|
|
917
|
+
return;
|
|
918
|
+
}
|
|
919
|
+
return;
|
|
920
|
+
}
|
|
921
|
+
if (skillsPicker === "remove") {
|
|
922
|
+
const installed = listInstalledSkills();
|
|
923
|
+
if (installed.length === 0) {
|
|
924
|
+
setSkillsPicker(null);
|
|
925
|
+
return;
|
|
926
|
+
}
|
|
927
|
+
if (key.upArrow) {
|
|
928
|
+
setSkillsPickerIndex((prev) => (prev - 1 + installed.length) % installed.length);
|
|
929
|
+
return;
|
|
930
|
+
}
|
|
931
|
+
if (key.downArrow) {
|
|
932
|
+
setSkillsPickerIndex((prev) => (prev + 1) % installed.length);
|
|
933
|
+
return;
|
|
934
|
+
}
|
|
935
|
+
if (key.escape) {
|
|
936
|
+
setSkillsPicker("menu");
|
|
937
|
+
setSkillsPickerIndex(0);
|
|
938
|
+
return;
|
|
939
|
+
}
|
|
940
|
+
if (key.return) {
|
|
941
|
+
const selected = installed[skillsPickerIndex];
|
|
942
|
+
if (selected) {
|
|
943
|
+
const result = removeSkill(selected.name);
|
|
944
|
+
addMsg(result.ok ? "info" : "error", result.ok ? `✅ ${result.message}` : `✗ ${result.message}`);
|
|
945
|
+
}
|
|
946
|
+
setSkillsPicker(null);
|
|
947
|
+
return;
|
|
948
|
+
}
|
|
949
|
+
return;
|
|
950
|
+
}
|
|
951
|
+
return;
|
|
952
|
+
}
|
|
704
953
|
// Theme picker navigation
|
|
705
954
|
if (themePicker) {
|
|
706
955
|
const themeKeys = listThemes();
|
|
@@ -915,7 +1164,23 @@ function App() {
|
|
|
915
1164
|
"device-flow": "📱 Device flow (GitHub)",
|
|
916
1165
|
};
|
|
917
1166
|
return (_jsxs(Text, { children: [i === loginMethodIndex ? _jsx(Text, { color: theme.colors.suggestion, bold: true, children: "▸ " }) : _jsx(Text, { children: " " }), _jsx(Text, { color: i === loginMethodIndex ? theme.colors.suggestion : theme.colors.primary, bold: true, children: labels[method] ?? method })] }, method));
|
|
918
|
-
}), _jsx(Text, { dimColor: true, children: " ↑↓ navigate · Enter select · Esc back" })] })),
|
|
1167
|
+
}), _jsx(Text, { dimColor: true, children: " ↑↓ navigate · Enter select · Esc back" })] })), skillsPicker === "menu" && (_jsxs(Box, { flexDirection: "column", borderStyle: "single", borderColor: theme.colors.border, paddingX: 1, marginBottom: 0, children: [_jsx(Text, { bold: true, color: theme.colors.secondary, children: "Skills:" }), [
|
|
1168
|
+
{ key: "browse", label: "Browse & Install", icon: "📦" },
|
|
1169
|
+
{ key: "installed", label: "Installed Skills", icon: "📋" },
|
|
1170
|
+
{ key: "create", label: "Create Custom Skill", icon: "➕" },
|
|
1171
|
+
{ key: "remove", label: "Remove Skill", icon: "🗑️" },
|
|
1172
|
+
].map((item, i) => (_jsxs(Text, { children: [i === skillsPickerIndex ? _jsx(Text, { color: theme.colors.suggestion, bold: true, children: "▸ " }) : _jsx(Text, { children: " " }), _jsxs(Text, { color: i === skillsPickerIndex ? theme.colors.suggestion : theme.colors.primary, bold: true, children: [item.icon, " ", item.label] })] }, item.key))), _jsx(Text, { dimColor: true, children: " ↑↓ navigate · Enter select · Esc cancel" })] })), skillsPicker === "browse" && (() => {
|
|
1173
|
+
const registry = getRegistrySkills();
|
|
1174
|
+
const installed = listInstalledSkills().map((s) => s.name);
|
|
1175
|
+
return (_jsxs(Box, { flexDirection: "column", borderStyle: "single", borderColor: theme.colors.border, paddingX: 1, marginBottom: 0, children: [_jsx(Text, { bold: true, color: theme.colors.secondary, children: "Browse Skills Registry:" }), registry.map((s, i) => (_jsxs(Text, { children: [i === skillsPickerIndex ? _jsx(Text, { color: theme.colors.suggestion, bold: true, children: "▸ " }) : _jsx(Text, { children: " " }), _jsx(Text, { color: i === skillsPickerIndex ? theme.colors.suggestion : theme.colors.primary, bold: true, children: s.name }), _jsxs(Text, { color: theme.colors.muted, children: [" — ", s.description] }), installed.includes(s.name) ? _jsx(Text, { color: theme.colors.success, children: " \u2713" }) : null] }, s.name))), _jsx(Text, { dimColor: true, children: " ↑↓ navigate · Enter install · Esc back" })] }));
|
|
1176
|
+
})(), skillsPicker === "installed" && (() => {
|
|
1177
|
+
const installed = listInstalledSkills();
|
|
1178
|
+
const active = getActiveSkills(process.cwd(), sessionDisabledSkills);
|
|
1179
|
+
return (_jsxs(Box, { flexDirection: "column", borderStyle: "single", borderColor: theme.colors.border, paddingX: 1, marginBottom: 0, children: [_jsx(Text, { bold: true, color: theme.colors.secondary, children: "Installed Skills:" }), installed.length === 0 ? (_jsx(Text, { color: theme.colors.muted, children: " No skills installed. Use Browse & Install." })) : installed.map((s, i) => (_jsxs(Text, { children: [i === skillsPickerIndex ? _jsx(Text, { color: theme.colors.suggestion, bold: true, children: "▸ " }) : _jsx(Text, { children: " " }), _jsx(Text, { color: i === skillsPickerIndex ? theme.colors.suggestion : theme.colors.primary, bold: true, children: s.name }), _jsxs(Text, { color: theme.colors.muted, children: [" — ", s.description] }), active.includes(s.name) ? _jsx(Text, { color: theme.colors.success, children: " (on)" }) : _jsx(Text, { color: theme.colors.muted, children: " (off)" })] }, s.name))), _jsx(Text, { dimColor: true, children: " ↑↓ navigate · Enter toggle · Esc back" })] }));
|
|
1180
|
+
})(), skillsPicker === "remove" && (() => {
|
|
1181
|
+
const installed = listInstalledSkills();
|
|
1182
|
+
return (_jsxs(Box, { flexDirection: "column", borderStyle: "single", borderColor: theme.colors.error, paddingX: 1, marginBottom: 0, children: [_jsx(Text, { bold: true, color: theme.colors.error, children: "Remove a skill:" }), installed.map((s, i) => (_jsxs(Text, { children: [i === skillsPickerIndex ? _jsx(Text, { color: theme.colors.suggestion, bold: true, children: "▸ " }) : _jsx(Text, { children: " " }), _jsxs(Text, { color: i === skillsPickerIndex ? theme.colors.suggestion : theme.colors.muted, children: [s.name, " \u2014 ", s.description] })] }, s.name))), _jsx(Text, { dimColor: true, children: " ↑↓ navigate · Enter remove · Esc back" })] }));
|
|
1183
|
+
})(), themePicker && (_jsxs(Box, { flexDirection: "column", borderStyle: "single", borderColor: theme.colors.border, paddingX: 1, marginBottom: 0, children: [_jsx(Text, { bold: true, color: theme.colors.secondary, children: "Choose a theme:" }), listThemes().map((key, i) => (_jsxs(Text, { children: [i === themePickerIndex ? _jsx(Text, { color: theme.colors.suggestion, bold: true, children: "▸ " }) : _jsx(Text, { children: " " }), _jsx(Text, { color: i === themePickerIndex ? theme.colors.suggestion : theme.colors.primary, bold: true, children: key }), _jsxs(Text, { color: theme.colors.muted, children: [" — ", THEMES[key].description] }), key === theme.name.toLowerCase() ? _jsx(Text, { color: theme.colors.muted, children: " (current)" }) : null] }, key))), _jsx(Text, { dimColor: true, children: " ↑↓ navigate · Enter select · Esc cancel" })] })), sessionPicker && (_jsxs(Box, { flexDirection: "column", borderStyle: "single", borderColor: theme.colors.secondary, paddingX: 1, marginBottom: 0, children: [_jsx(Text, { bold: true, color: theme.colors.secondary, children: "Resume a session:" }), sessionPicker.map((s, i) => (_jsxs(Text, { children: [i === sessionPickerIndex ? _jsx(Text, { color: theme.colors.suggestion, bold: true, children: "▸ " }) : _jsx(Text, { children: " " }), _jsx(Text, { color: i === sessionPickerIndex ? theme.colors.suggestion : theme.colors.muted, children: s.display })] }, s.id))), _jsx(Text, { dimColor: true, children: " ↑↓ navigate · Enter select · Esc cancel" })] })), deleteSessionPicker && (_jsxs(Box, { flexDirection: "column", borderStyle: "single", borderColor: theme.colors.error, paddingX: 1, marginBottom: 0, children: [_jsx(Text, { bold: true, color: theme.colors.error, children: "Delete a session:" }), deleteSessionPicker.map((s, i) => (_jsxs(Text, { children: [i === deleteSessionPickerIndex ? _jsx(Text, { color: theme.colors.suggestion, bold: true, children: "▸ " }) : _jsx(Text, { children: " " }), _jsx(Text, { color: i === deleteSessionPickerIndex ? theme.colors.suggestion : theme.colors.muted, children: s.display })] }, s.id))), _jsx(Text, { dimColor: true, children: " ↑↓ navigate · Enter select · Esc cancel" })] })), deleteSessionConfirm && (_jsxs(Box, { flexDirection: "column", borderStyle: "single", borderColor: theme.colors.warning, paddingX: 1, marginBottom: 0, children: [_jsxs(Text, { bold: true, color: theme.colors.warning, children: ["Delete session ", deleteSessionConfirm.id, "?"] }), _jsxs(Text, { color: theme.colors.muted, children: [" ", deleteSessionConfirm.display] }), _jsxs(Text, { children: [_jsx(Text, { color: theme.colors.error, bold: true, children: " [y]" }), _jsx(Text, { children: "es " }), _jsx(Text, { color: theme.colors.success, bold: true, children: "[n]" }), _jsx(Text, { children: "o" })] })] })), showSuggestions && (_jsxs(Box, { flexDirection: "column", borderStyle: "single", borderColor: theme.colors.muted, paddingX: 1, marginBottom: 0, children: [cmdMatches.slice(0, 6).map((c, i) => (_jsxs(Text, { children: [i === cmdIndex ? _jsx(Text, { color: theme.colors.suggestion, bold: true, children: "▸ " }) : _jsx(Text, { children: " " }), _jsx(Text, { color: i === cmdIndex ? theme.colors.suggestion : theme.colors.primary, bold: true, children: c.cmd }), _jsxs(Text, { color: theme.colors.muted, children: [" — ", c.desc] })] }, i))), _jsx(Text, { dimColor: true, children: " ↑↓ navigate · Tab select" })] })), _jsxs(Box, { borderStyle: "single", borderColor: approval ? theme.colors.warning : theme.colors.border, paddingX: 1, children: [_jsx(Text, { color: theme.colors.secondary, bold: true, children: "> " }), approval ? (_jsx(Text, { color: theme.colors.warning, children: "waiting for approval..." })) : ready && !loading ? (_jsxs(Box, { children: [pastedChunks.map((p) => (_jsxs(Text, { color: theme.colors.muted, children: ["[Pasted text #", p.id, " +", p.lines, " lines]"] }, p.id))), _jsx(TextInput, { value: input, onChange: (v) => { setInput(v); setCmdIndex(0); }, onSubmit: handleSubmit }, inputKey)] })) : (_jsx(Text, { dimColor: true, children: loading ? "waiting for response..." : "initializing..." }))] }), agent && (_jsx(Box, { paddingX: 2, children: _jsxs(Text, { dimColor: true, children: ["💬 ", agent.getContextLength(), " messages · ~", (() => {
|
|
919
1184
|
const tokens = agent.estimateTokens();
|
|
920
1185
|
return tokens >= 1000 ? `${(tokens / 1000).toFixed(1)}k` : String(tokens);
|
|
921
1186
|
})(), " tokens", (() => {
|
|
@@ -924,7 +1189,10 @@ function App() {
|
|
|
924
1189
|
return ` · 💰 $${totalCost < 0.01 ? totalCost.toFixed(4) : totalCost.toFixed(2)}`;
|
|
925
1190
|
}
|
|
926
1191
|
return "";
|
|
927
|
-
})(), modelName ? ` · 🤖 ${modelName}` : ""
|
|
1192
|
+
})(), modelName ? ` · 🤖 ${modelName}` : "", (() => {
|
|
1193
|
+
const count = getActiveSkillCount(process.cwd(), sessionDisabledSkills);
|
|
1194
|
+
return count > 0 ? ` · 🧠 ${count} skill${count !== 1 ? "s" : ""}` : "";
|
|
1195
|
+
})()] }) }))] }));
|
|
928
1196
|
}
|
|
929
1197
|
// Clear screen before render
|
|
930
1198
|
process.stdout.write("\x1B[2J\x1B[3J\x1B[H");
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Built-in skills registry — hardcoded skill packs shipped with codemaxxing.
|
|
3
|
+
* No network needed — everything is local.
|
|
4
|
+
*/
|
|
5
|
+
export interface RegistrySkill {
|
|
6
|
+
name: string;
|
|
7
|
+
description: string;
|
|
8
|
+
version: string;
|
|
9
|
+
author: string;
|
|
10
|
+
tags: string[];
|
|
11
|
+
prompt: string;
|
|
12
|
+
}
|
|
13
|
+
export declare const REGISTRY: RegistrySkill[];
|