@zhanngning/hecode 0.7.0 → 0.8.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/index.js +154 -166
- package/dist/index.js.map +1 -1
- package/package.json +1 -1
package/dist/index.js
CHANGED
|
@@ -1737,14 +1737,14 @@ Expecting one of '${allowedValues.join("', '")}'`);
|
|
|
1737
1737
|
* @return {Command} `this` command for chaining
|
|
1738
1738
|
* @private
|
|
1739
1739
|
*/
|
|
1740
|
-
_optionEx(
|
|
1740
|
+
_optionEx(config2, flags, description, fn, defaultValue) {
|
|
1741
1741
|
if (typeof flags === "object" && flags instanceof Option) {
|
|
1742
1742
|
throw new Error(
|
|
1743
1743
|
"To add an Option object use addOption() instead of option() or requiredOption()"
|
|
1744
1744
|
);
|
|
1745
1745
|
}
|
|
1746
1746
|
const option = this.createOption(flags, description);
|
|
1747
|
-
option.makeOptionMandatory(!!
|
|
1747
|
+
option.makeOptionMandatory(!!config2.mandatory);
|
|
1748
1748
|
if (typeof fn === "function") {
|
|
1749
1749
|
option.default(defaultValue).argParser(fn);
|
|
1750
1750
|
} else if (fn instanceof RegExp) {
|
|
@@ -2730,9 +2730,9 @@ Expecting one of '${allowedValues.join("', '")}'`);
|
|
|
2730
2730
|
this._outputConfiguration.writeErr("\n");
|
|
2731
2731
|
this.outputHelp({ error: true });
|
|
2732
2732
|
}
|
|
2733
|
-
const
|
|
2734
|
-
const exitCode =
|
|
2735
|
-
const code =
|
|
2733
|
+
const config2 = errorOptions || {};
|
|
2734
|
+
const exitCode = config2.exitCode || 1;
|
|
2735
|
+
const code = config2.code || "commander.error";
|
|
2736
2736
|
this._exit(exitCode, code, message);
|
|
2737
2737
|
}
|
|
2738
2738
|
/**
|
|
@@ -3884,9 +3884,9 @@ async function loadConfig() {
|
|
|
3884
3884
|
return { defaultModel: "openai:gpt-4o", models: {} };
|
|
3885
3885
|
}
|
|
3886
3886
|
}
|
|
3887
|
-
async function saveConfig(
|
|
3887
|
+
async function saveConfig(config2) {
|
|
3888
3888
|
await mkdir(CONFIG_DIR, { recursive: true });
|
|
3889
|
-
await writeFile(CONFIG_FILE, JSON.stringify(
|
|
3889
|
+
await writeFile(CONFIG_FILE, JSON.stringify(config2, null, 2), "utf-8");
|
|
3890
3890
|
}
|
|
3891
3891
|
|
|
3892
3892
|
// node_modules/openai/internal/tslib.mjs
|
|
@@ -5434,11 +5434,11 @@ var SUBJECT_TOKEN_TYPES = {
|
|
|
5434
5434
|
};
|
|
5435
5435
|
var TOKEN_EXCHANGE_GRANT_TYPE = "urn:ietf:params:oauth:grant-type:token-exchange";
|
|
5436
5436
|
var WorkloadIdentityAuth = class {
|
|
5437
|
-
constructor(
|
|
5437
|
+
constructor(config2, fetch2) {
|
|
5438
5438
|
this.cachedToken = null;
|
|
5439
5439
|
this.refreshPromise = null;
|
|
5440
5440
|
this.tokenExchangeUrl = "https://auth.openai.com/oauth/token";
|
|
5441
|
-
this.config =
|
|
5441
|
+
this.config = config2;
|
|
5442
5442
|
this.fetch = fetch2 ?? getDefaultFetch();
|
|
5443
5443
|
}
|
|
5444
5444
|
async getToken() {
|
|
@@ -14028,12 +14028,12 @@ var OpenAIProvider = class {
|
|
|
14028
14028
|
name = "openai";
|
|
14029
14029
|
client;
|
|
14030
14030
|
model;
|
|
14031
|
-
constructor(
|
|
14031
|
+
constructor(config2) {
|
|
14032
14032
|
this.client = new OpenAI({
|
|
14033
|
-
apiKey:
|
|
14034
|
-
baseURL:
|
|
14033
|
+
apiKey: config2.apiKey ?? process.env.OPENAI_API_KEY,
|
|
14034
|
+
baseURL: config2.baseUrl
|
|
14035
14035
|
});
|
|
14036
|
-
this.model =
|
|
14036
|
+
this.model = config2.model ?? "gpt-4o";
|
|
14037
14037
|
}
|
|
14038
14038
|
async chat(messages, tools) {
|
|
14039
14039
|
const params = {
|
|
@@ -14106,9 +14106,9 @@ var AnthropicProvider = class {
|
|
|
14106
14106
|
name = "anthropic";
|
|
14107
14107
|
client;
|
|
14108
14108
|
model;
|
|
14109
|
-
constructor(
|
|
14110
|
-
this.client = new Anthropic({ apiKey:
|
|
14111
|
-
this.model =
|
|
14109
|
+
constructor(config2) {
|
|
14110
|
+
this.client = new Anthropic({ apiKey: config2.apiKey ?? process.env.ANTHROPIC_API_KEY });
|
|
14111
|
+
this.model = config2.model ?? "claude-sonnet-4-20250514";
|
|
14112
14112
|
}
|
|
14113
14113
|
async chat(messages, tools) {
|
|
14114
14114
|
const system = messages.find((m) => m.role === "system")?.content ?? "";
|
|
@@ -14170,9 +14170,9 @@ var OllamaProvider = class {
|
|
|
14170
14170
|
name = "ollama";
|
|
14171
14171
|
baseUrl;
|
|
14172
14172
|
model;
|
|
14173
|
-
constructor(
|
|
14174
|
-
this.baseUrl =
|
|
14175
|
-
this.model =
|
|
14173
|
+
constructor(config2) {
|
|
14174
|
+
this.baseUrl = config2.baseUrl ?? "http://localhost:11434";
|
|
14175
|
+
this.model = config2.model ?? "llama3.1";
|
|
14176
14176
|
}
|
|
14177
14177
|
async chat(messages, tools) {
|
|
14178
14178
|
const res = await fetch(`${this.baseUrl}/api/chat`, {
|
|
@@ -14247,13 +14247,13 @@ registry.set("openai", (c) => new OpenAIProvider(c));
|
|
|
14247
14247
|
registry.set("claude", (c) => new AnthropicProvider(c));
|
|
14248
14248
|
registry.set("anthropic", (c) => new AnthropicProvider(c));
|
|
14249
14249
|
registry.set("ollama", (c) => new OllamaProvider(c));
|
|
14250
|
-
function createProvider(name,
|
|
14250
|
+
function createProvider(name, config2) {
|
|
14251
14251
|
const factory = registry.get(name);
|
|
14252
14252
|
if (!factory)
|
|
14253
14253
|
throw new Error(
|
|
14254
14254
|
`Unknown model provider: ${name}. Available: ${[...registry.keys()].join(", ")}`
|
|
14255
14255
|
);
|
|
14256
|
-
return factory(
|
|
14256
|
+
return factory(config2);
|
|
14257
14257
|
}
|
|
14258
14258
|
function parseModelString(modelStr) {
|
|
14259
14259
|
const [provider, ...rest] = modelStr.split(":");
|
|
@@ -14385,26 +14385,50 @@ function matchSkill(skills, userMessage) {
|
|
|
14385
14385
|
}
|
|
14386
14386
|
|
|
14387
14387
|
// src/cli/repl.ts
|
|
14388
|
-
var VERSION2 = "0.
|
|
14389
|
-
|
|
14390
|
-
|
|
14391
|
-
|
|
14392
|
-
|
|
14393
|
-
|
|
14394
|
-
|
|
14395
|
-
|
|
14396
|
-
|
|
14397
|
-
|
|
14398
|
-
|
|
14388
|
+
var VERSION2 = "0.8.0";
|
|
14389
|
+
var theme = {
|
|
14390
|
+
primary: source_default.hex("#00d4ff"),
|
|
14391
|
+
secondary: source_default.hex("#8b5cf6"),
|
|
14392
|
+
accent: source_default.hex("#ec4899"),
|
|
14393
|
+
success: source_default.hex("#10b981"),
|
|
14394
|
+
warning: source_default.hex("#f59e0b"),
|
|
14395
|
+
error: source_default.hex("#ef4444"),
|
|
14396
|
+
muted: source_default.hex("#6b7280"),
|
|
14397
|
+
dim: source_default.hex("#374151"),
|
|
14398
|
+
bg: source_default.hex("#1a1a2e"),
|
|
14399
|
+
border: source_default.hex("#2d2d44")
|
|
14400
|
+
};
|
|
14401
|
+
function drawLine(char = "\u2500", width = 56) {
|
|
14402
|
+
console.log(theme.dim(char.repeat(width)));
|
|
14399
14403
|
}
|
|
14400
|
-
function
|
|
14401
|
-
|
|
14404
|
+
function getSkillIcon(name) {
|
|
14405
|
+
const icons = {
|
|
14406
|
+
coding: "\u03BB",
|
|
14407
|
+
testing: "\u2713",
|
|
14408
|
+
"code-review": "\u25CE",
|
|
14409
|
+
docs: "\xB6",
|
|
14410
|
+
git: "\u2387",
|
|
14411
|
+
explain: "?",
|
|
14412
|
+
refactor: "\u21C4",
|
|
14413
|
+
security: "\u2295",
|
|
14414
|
+
perf: "\u26A1",
|
|
14415
|
+
content: "\u270E",
|
|
14416
|
+
"data-analysis": "\u25A3",
|
|
14417
|
+
translate: "\u2194",
|
|
14418
|
+
ppt: "\u25EB",
|
|
14419
|
+
planning: "\u229E",
|
|
14420
|
+
finance: "$"
|
|
14421
|
+
};
|
|
14422
|
+
return icons[name] || "\u2022";
|
|
14423
|
+
}
|
|
14424
|
+
function getStatusIcon(status) {
|
|
14425
|
+
return status ? theme.success("\u25CF") : theme.dim("\u25CB");
|
|
14402
14426
|
}
|
|
14403
14427
|
async function startREPL(model, opts) {
|
|
14404
14428
|
const session = new SessionMemory();
|
|
14405
14429
|
const skillsDir = join4(process.cwd(), "skills");
|
|
14406
14430
|
const skills = await loadSkills(skillsDir);
|
|
14407
|
-
const
|
|
14431
|
+
const config2 = await loadConfig();
|
|
14408
14432
|
let skillInstructions;
|
|
14409
14433
|
if (opts?.skillName) {
|
|
14410
14434
|
const skill = skills.find((s) => s.name === opts.skillName);
|
|
@@ -14414,71 +14438,23 @@ async function startREPL(model, opts) {
|
|
|
14414
14438
|
model,
|
|
14415
14439
|
skillInstructions,
|
|
14416
14440
|
onToolStart: (name) => {
|
|
14417
|
-
console.log(
|
|
14441
|
+
console.log(theme.warning(` \u25CC ${name}...`));
|
|
14418
14442
|
},
|
|
14419
14443
|
onToolEnd: (_name, result) => {
|
|
14420
14444
|
if (result.error) {
|
|
14421
|
-
console.log(
|
|
14445
|
+
console.log(theme.error(` \u2717 ${_name}: ${result.error}`));
|
|
14422
14446
|
} else {
|
|
14423
|
-
console.log(
|
|
14447
|
+
console.log(theme.success(` \u2713 ${_name}`));
|
|
14424
14448
|
}
|
|
14425
14449
|
}
|
|
14426
14450
|
});
|
|
14427
14451
|
const rl = readline.createInterface({
|
|
14428
14452
|
input: process.stdin,
|
|
14429
14453
|
output: process.stdout,
|
|
14430
|
-
prompt:
|
|
14454
|
+
prompt: theme.primary("\u276F ") + theme.dim("")
|
|
14431
14455
|
});
|
|
14432
14456
|
console.clear();
|
|
14433
|
-
|
|
14434
|
-
source_default.cyan(" \u2588\u2588\u2557 \u2588\u2588\u2557\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2557 \u2588\u2588\u2588\u2588\u2588\u2588\u2557 \u2588\u2588\u2588\u2588\u2588\u2588\u2557 \u2588\u2588\u2588\u2588\u2588\u2588\u2557 \u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2557"),
|
|
14435
|
-
source_default.cyan(" \u2588\u2588\u2551 \u2588\u2588\u2551\u2588\u2588\u2554\u2550\u2550\u2550\u2550\u255D\u2588\u2588\u2554\u2550\u2550\u2550\u2550\u255D\u2588\u2588\u2554\u2550\u2550\u2550\u2588\u2588\u2557\u2588\u2588\u2554\u2550\u2550\u2588\u2588\u2557\u2588\u2588\u2554\u2550\u2550\u2550\u2550\u255D"),
|
|
14436
|
-
source_default.cyan(" \u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2551\u2588\u2588\u2588\u2588\u2588\u2557 \u2588\u2588\u2551 \u2588\u2588\u2551 \u2588\u2588\u2551\u2588\u2588\u2551 \u2588\u2588\u2551\u2588\u2588\u2588\u2588\u2588\u2557 "),
|
|
14437
|
-
source_default.cyan(" \u2588\u2588\u2554\u2550\u2550\u2588\u2588\u2551\u2588\u2588\u2554\u2550\u2550\u255D \u2588\u2588\u2551 \u2588\u2588\u2551 \u2588\u2588\u2551\u2588\u2588\u2551 \u2588\u2588\u2551\u2588\u2588\u2554\u2550\u2550\u255D "),
|
|
14438
|
-
source_default.cyan(" \u2588\u2588\u2551 \u2588\u2588\u2551\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2557\u255A\u2588\u2588\u2588\u2588\u2588\u2588\u2557\u255A\u2588\u2588\u2588\u2588\u2588\u2588\u2554\u255D\u2588\u2588\u2588\u2588\u2588\u2588\u2554\u255D\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2557"),
|
|
14439
|
-
source_default.cyan(" \u255A\u2550\u255D \u255A\u2550\u255D\u255A\u2550\u2550\u2550\u2550\u2550\u2550\u255D \u255A\u2550\u2550\u2550\u2550\u2550\u255D \u255A\u2550\u2550\u2550\u2550\u2550\u255D \u255A\u2550\u2550\u2550\u2550\u2550\u255D \u255A\u2550\u2550\u2550\u2550\u2550\u2550\u255D")
|
|
14440
|
-
];
|
|
14441
|
-
logo.forEach((line) => console.log(line));
|
|
14442
|
-
console.log();
|
|
14443
|
-
drawBox([
|
|
14444
|
-
source_default.bold.white("Your AI Coding Assistant") + source_default.gray(` v${VERSION2}`),
|
|
14445
|
-
source_default.gray("\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500"),
|
|
14446
|
-
source_default.white("Model: ") + source_default.cyan(config.defaultModel),
|
|
14447
|
-
source_default.white("Session: ") + source_default.gray(session.sessionId.substring(0, 12) + "..."),
|
|
14448
|
-
source_default.white("Skills: ") + source_default.gray(`${skills.length} loaded`)
|
|
14449
|
-
]);
|
|
14450
|
-
console.log();
|
|
14451
|
-
if (skills.length > 0) {
|
|
14452
|
-
console.log(source_default.bold.white(" Available Skills:"));
|
|
14453
|
-
drawSeparator();
|
|
14454
|
-
const skillChunks = [];
|
|
14455
|
-
for (let i = 0; i < skills.length; i += 3) {
|
|
14456
|
-
skillChunks.push(skills.slice(i, i + 3));
|
|
14457
|
-
}
|
|
14458
|
-
for (const chunk of skillChunks) {
|
|
14459
|
-
const line = chunk.map((s) => {
|
|
14460
|
-
const icon = getSkillIcon(s.name);
|
|
14461
|
-
return source_default.cyan(`${icon} ${s.name.padEnd(12)}`);
|
|
14462
|
-
}).join("");
|
|
14463
|
-
console.log(" " + line);
|
|
14464
|
-
}
|
|
14465
|
-
console.log();
|
|
14466
|
-
}
|
|
14467
|
-
console.log(source_default.bold.white(" Quick Commands:"));
|
|
14468
|
-
drawSeparator();
|
|
14469
|
-
console.log(source_default.gray(" /help Show help /skills List skills"));
|
|
14470
|
-
console.log(source_default.gray(" /config Show config /clear Clear chat"));
|
|
14471
|
-
console.log(source_default.gray(" /model Switch model /save Save session"));
|
|
14472
|
-
console.log();
|
|
14473
|
-
console.log(source_default.bold.white(" Usage:"));
|
|
14474
|
-
drawSeparator();
|
|
14475
|
-
console.log(source_default.gray(" \u2022 Type naturally to chat with AI"));
|
|
14476
|
-
console.log(source_default.gray(' \u2022 Use --skill flag: hecode --skill coding "write a sort"'));
|
|
14477
|
-
console.log(source_default.gray(" \u2022 Skills auto-activate based on keywords"));
|
|
14478
|
-
console.log();
|
|
14479
|
-
drawSeparator();
|
|
14480
|
-
console.log(source_default.gray(" Press Ctrl+C to exit"));
|
|
14481
|
-
console.log();
|
|
14457
|
+
renderHeader(config2, skills, session);
|
|
14482
14458
|
rl.prompt();
|
|
14483
14459
|
rl.on("line", async (line) => {
|
|
14484
14460
|
const input = line.trim();
|
|
@@ -14495,144 +14471,156 @@ async function startREPL(model, opts) {
|
|
|
14495
14471
|
const matched = matchSkill(skills, input);
|
|
14496
14472
|
if (matched) {
|
|
14497
14473
|
const icon = getSkillIcon(matched.name);
|
|
14498
|
-
console.log(
|
|
14499
|
-
${icon}
|
|
14474
|
+
console.log(theme.muted(`
|
|
14475
|
+
${icon} ${matched.name}
|
|
14476
|
+
`));
|
|
14500
14477
|
}
|
|
14501
14478
|
}
|
|
14502
14479
|
try {
|
|
14503
|
-
console.log();
|
|
14504
14480
|
let hasOutput = false;
|
|
14505
14481
|
for await (const token of orchestrator.runStream(input)) {
|
|
14506
14482
|
process.stdout.write(token);
|
|
14507
14483
|
hasOutput = true;
|
|
14508
14484
|
}
|
|
14509
|
-
if (hasOutput)
|
|
14510
|
-
console.log("\n");
|
|
14511
|
-
}
|
|
14485
|
+
if (hasOutput) console.log("\n");
|
|
14512
14486
|
await session.save(orchestrator.getMessages());
|
|
14513
14487
|
} catch (e) {
|
|
14514
|
-
console.log(
|
|
14515
|
-
\u2717
|
|
14488
|
+
console.log(theme.error(`
|
|
14489
|
+
\u2717 ${e.message}
|
|
14516
14490
|
`));
|
|
14517
14491
|
}
|
|
14518
14492
|
rl.prompt();
|
|
14519
14493
|
});
|
|
14520
14494
|
rl.on("close", () => {
|
|
14521
|
-
console.log(
|
|
14495
|
+
console.log(theme.muted("\n bye\n"));
|
|
14522
14496
|
process.exit(0);
|
|
14523
14497
|
});
|
|
14524
14498
|
}
|
|
14525
|
-
function
|
|
14526
|
-
const
|
|
14527
|
-
|
|
14528
|
-
|
|
14529
|
-
"
|
|
14530
|
-
|
|
14531
|
-
|
|
14532
|
-
|
|
14533
|
-
|
|
14534
|
-
|
|
14535
|
-
|
|
14536
|
-
|
|
14537
|
-
|
|
14538
|
-
|
|
14539
|
-
|
|
14540
|
-
|
|
14541
|
-
|
|
14542
|
-
|
|
14543
|
-
|
|
14499
|
+
function renderHeader(config2, skills, session) {
|
|
14500
|
+
const logo = [
|
|
14501
|
+
theme.primary(" \u2566 \u2566\u2554\u2550\u2557\u2554\u2550\u2557\u2554\u2550\u2557\u2554\u2550\u2557\u2554\u2550\u2557"),
|
|
14502
|
+
theme.primary(" \u2560\u2550\u2563\u2551\u2563 \u2560\u2550\u2563\u2551 \u2551 \u2551\u2563 "),
|
|
14503
|
+
theme.primary(" \u2569 \u2569\u255A\u2550\u255D\u2569 \u2569\u255A\u2550\u255D\u255A\u2550\u255D\u255A\u2550\u255D") + theme.dim(" v" + VERSION2)
|
|
14504
|
+
];
|
|
14505
|
+
logo.forEach((l) => console.log(l));
|
|
14506
|
+
console.log();
|
|
14507
|
+
drawLine("\u2500");
|
|
14508
|
+
console.log(
|
|
14509
|
+
theme.muted(" model ") + theme.primary(config2.defaultModel) + theme.muted(" \u2502 ") + theme.muted("skills ") + theme.success(`${skills.length}`) + theme.muted(" \u2502 ") + theme.muted("session ") + theme.dim(session.sessionId.substring(0, 8))
|
|
14510
|
+
);
|
|
14511
|
+
drawLine("\u2500");
|
|
14512
|
+
console.log();
|
|
14513
|
+
const cols = 3;
|
|
14514
|
+
const colWidth = 20;
|
|
14515
|
+
for (let i = 0; i < skills.length; i += cols) {
|
|
14516
|
+
const row = skills.slice(i, i + cols);
|
|
14517
|
+
const cells = row.map((s) => {
|
|
14518
|
+
const icon = getSkillIcon(s.name);
|
|
14519
|
+
const name = s.name.padEnd(14);
|
|
14520
|
+
return ` ${theme.primary(icon)} ${theme.dim(name)}`;
|
|
14521
|
+
});
|
|
14522
|
+
console.log(cells.join(""));
|
|
14523
|
+
}
|
|
14524
|
+
console.log();
|
|
14525
|
+
drawLine("\u2500");
|
|
14526
|
+
console.log(theme.muted(" /help /skills /config /model /clear /save /exit"));
|
|
14527
|
+
drawLine("\u2500");
|
|
14528
|
+
console.log();
|
|
14544
14529
|
}
|
|
14545
14530
|
function handleCommand(input, orchestrator, session, skills) {
|
|
14546
14531
|
const [cmd, ...args] = input.split(" ");
|
|
14547
14532
|
switch (cmd) {
|
|
14548
14533
|
case "/help":
|
|
14549
14534
|
console.log();
|
|
14550
|
-
console.log(
|
|
14551
|
-
|
|
14552
|
-
|
|
14553
|
-
|
|
14554
|
-
|
|
14555
|
-
|
|
14556
|
-
|
|
14557
|
-
|
|
14558
|
-
|
|
14559
|
-
|
|
14560
|
-
|
|
14535
|
+
console.log(theme.primary(" Commands"));
|
|
14536
|
+
drawLine();
|
|
14537
|
+
const cmds = [
|
|
14538
|
+
["/help", "Show this help"],
|
|
14539
|
+
["/skills", "List all skills"],
|
|
14540
|
+
["/config", "Show configuration"],
|
|
14541
|
+
["/model [name]", "Show or switch model"],
|
|
14542
|
+
["/clear", "Clear conversation"],
|
|
14543
|
+
["/save", "Save session"],
|
|
14544
|
+
["/session", "Show session ID"],
|
|
14545
|
+
["/exit", "Exit hecode"]
|
|
14546
|
+
];
|
|
14547
|
+
for (const [name, desc] of cmds) {
|
|
14548
|
+
console.log(theme.primary(` ${name.padEnd(18)}`) + theme.muted(desc));
|
|
14549
|
+
}
|
|
14561
14550
|
console.log();
|
|
14562
14551
|
break;
|
|
14563
14552
|
case "/skills":
|
|
14564
14553
|
console.log();
|
|
14565
|
-
console.log(
|
|
14566
|
-
|
|
14554
|
+
console.log(theme.primary(" Skills"));
|
|
14555
|
+
drawLine();
|
|
14567
14556
|
for (const skill of skills) {
|
|
14568
14557
|
const icon = getSkillIcon(skill.name);
|
|
14569
|
-
const name =
|
|
14570
|
-
const triggers = skill.trigger ? skill.trigger.split(",").slice(0, 3).map((t) => t.trim()).join(", ") : "
|
|
14571
|
-
console.log(` ${icon} ${name} ${
|
|
14558
|
+
const name = skill.name.padEnd(15);
|
|
14559
|
+
const triggers = skill.trigger ? skill.trigger.split(",").slice(0, 3).map((t) => t.trim()).join(", ") : "";
|
|
14560
|
+
console.log(` ${theme.primary(icon)} ${theme.dim(name)} ${theme.muted(triggers)}`);
|
|
14572
14561
|
}
|
|
14573
14562
|
console.log();
|
|
14574
14563
|
break;
|
|
14575
14564
|
case "/config":
|
|
14576
|
-
loadConfig().then((
|
|
14565
|
+
loadConfig().then((cfg) => {
|
|
14577
14566
|
console.log();
|
|
14578
|
-
console.log(
|
|
14579
|
-
|
|
14580
|
-
console.log(
|
|
14581
|
-
console.log(
|
|
14582
|
-
for (const [name,
|
|
14583
|
-
const hasKey =
|
|
14584
|
-
console.log(` ${hasKey} ${
|
|
14567
|
+
console.log(theme.primary(" Configuration"));
|
|
14568
|
+
drawLine();
|
|
14569
|
+
console.log(theme.muted(" Model: ") + theme.primary(cfg.defaultModel));
|
|
14570
|
+
console.log(theme.muted(" Providers:"));
|
|
14571
|
+
for (const [name, c] of Object.entries(cfg.models || {})) {
|
|
14572
|
+
const hasKey = c.apiKey ? getStatusIcon(true) : getStatusIcon(false);
|
|
14573
|
+
console.log(` ${hasKey} ${theme.dim(name)}`);
|
|
14585
14574
|
}
|
|
14586
14575
|
console.log();
|
|
14587
14576
|
});
|
|
14588
14577
|
break;
|
|
14589
14578
|
case "/model":
|
|
14590
14579
|
if (args[0]) {
|
|
14591
|
-
console.log(
|
|
14592
|
-
\u2713
|
|
14580
|
+
console.log(theme.success(`
|
|
14581
|
+
\u2713 ${args[0]}
|
|
14593
14582
|
`));
|
|
14594
14583
|
} else {
|
|
14595
|
-
loadConfig().then((
|
|
14596
|
-
console.log(
|
|
14597
|
-
|
|
14584
|
+
loadConfig().then((cfg) => {
|
|
14585
|
+
console.log(theme.primary(`
|
|
14586
|
+
${cfg.defaultModel}
|
|
14598
14587
|
`));
|
|
14599
|
-
console.log(
|
|
14600
|
-
console.log(source_default.gray(" Example: /model claude:sonnet\n"));
|
|
14588
|
+
console.log(theme.muted(" /model provider:model\n"));
|
|
14601
14589
|
});
|
|
14602
14590
|
}
|
|
14603
14591
|
break;
|
|
14604
14592
|
case "/clear":
|
|
14605
14593
|
orchestrator.clearMessages();
|
|
14606
14594
|
console.clear();
|
|
14607
|
-
|
|
14595
|
+
renderHeader(config, skills, session);
|
|
14608
14596
|
break;
|
|
14609
14597
|
case "/history":
|
|
14610
|
-
console.log(
|
|
14611
|
-
|
|
14598
|
+
console.log(theme.muted(`
|
|
14599
|
+
${orchestrator.getMessages().length} messages
|
|
14612
14600
|
`));
|
|
14613
14601
|
break;
|
|
14614
14602
|
case "/save":
|
|
14615
14603
|
session.save(orchestrator.getMessages()).then(() => {
|
|
14616
|
-
console.log(
|
|
14604
|
+
console.log(theme.success("\n \u2713 saved\n"));
|
|
14617
14605
|
});
|
|
14618
14606
|
break;
|
|
14619
14607
|
case "/session":
|
|
14620
|
-
console.log(
|
|
14621
|
-
|
|
14608
|
+
console.log(theme.muted(`
|
|
14609
|
+
${session.sessionId}
|
|
14622
14610
|
`));
|
|
14623
14611
|
break;
|
|
14624
14612
|
case "/exit":
|
|
14625
|
-
console.log(
|
|
14613
|
+
console.log(theme.muted("\n bye\n"));
|
|
14626
14614
|
process.exit(0);
|
|
14627
14615
|
default:
|
|
14628
|
-
console.log(
|
|
14629
|
-
|
|
14630
|
-
console.log(
|
|
14616
|
+
console.log(theme.error(`
|
|
14617
|
+
? ${cmd}`));
|
|
14618
|
+
console.log(theme.muted(" /help\n"));
|
|
14631
14619
|
}
|
|
14632
14620
|
}
|
|
14633
14621
|
|
|
14634
14622
|
// src/cli/commands.ts
|
|
14635
|
-
var VERSION3 = "0.
|
|
14623
|
+
var VERSION3 = "0.8.0";
|
|
14636
14624
|
function checkApiKey(provider, modelConfig) {
|
|
14637
14625
|
const envKeys = {
|
|
14638
14626
|
openai: "OPENAI_API_KEY",
|
|
@@ -14661,10 +14649,10 @@ function createProgram() {
|
|
|
14661
14649
|
program3.option("-s, --skill <skill>", "Skill to activate");
|
|
14662
14650
|
program3.argument("[prompt...]", "Single-shot prompt (non-interactive)");
|
|
14663
14651
|
program3.action(async (prompt, opts) => {
|
|
14664
|
-
const
|
|
14665
|
-
const modelStr = opts.model ??
|
|
14652
|
+
const config2 = await loadConfig();
|
|
14653
|
+
const modelStr = opts.model ?? config2.defaultModel;
|
|
14666
14654
|
const { provider, model } = parseModelString(modelStr);
|
|
14667
|
-
const modelConfig =
|
|
14655
|
+
const modelConfig = config2.models[provider] ?? {};
|
|
14668
14656
|
if (model) modelConfig.model = model;
|
|
14669
14657
|
if (!checkApiKey(provider, modelConfig)) {
|
|
14670
14658
|
return;
|
|
@@ -14684,14 +14672,14 @@ function createProgram() {
|
|
|
14684
14672
|
configCmd.argument("[key]", "Config key to get/set");
|
|
14685
14673
|
configCmd.argument("[value]", "Value to set");
|
|
14686
14674
|
configCmd.action(async (key, value) => {
|
|
14687
|
-
const
|
|
14675
|
+
const config2 = await loadConfig();
|
|
14688
14676
|
if (!key) {
|
|
14689
|
-
console.log(JSON.stringify(
|
|
14677
|
+
console.log(JSON.stringify(config2, null, 2));
|
|
14690
14678
|
return;
|
|
14691
14679
|
}
|
|
14692
14680
|
if (!value) {
|
|
14693
14681
|
const keys2 = key.split(".");
|
|
14694
|
-
let result =
|
|
14682
|
+
let result = config2;
|
|
14695
14683
|
for (const k of keys2) {
|
|
14696
14684
|
result = result?.[k];
|
|
14697
14685
|
}
|
|
@@ -14699,13 +14687,13 @@ function createProgram() {
|
|
|
14699
14687
|
return;
|
|
14700
14688
|
}
|
|
14701
14689
|
const keys = key.split(".");
|
|
14702
|
-
let target =
|
|
14690
|
+
let target = config2;
|
|
14703
14691
|
for (let i = 0; i < keys.length - 1; i++) {
|
|
14704
14692
|
if (!target[keys[i]]) target[keys[i]] = {};
|
|
14705
14693
|
target = target[keys[i]];
|
|
14706
14694
|
}
|
|
14707
14695
|
target[keys[keys.length - 1]] = value;
|
|
14708
|
-
await saveConfig(
|
|
14696
|
+
await saveConfig(config2);
|
|
14709
14697
|
console.log(source_default.green(`\u2713 Set ${key} = ${value}`));
|
|
14710
14698
|
});
|
|
14711
14699
|
const initCmd = program3.command("init");
|