@leejungkiin/awkit 1.7.4 → 1.7.6
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/README.md +42 -5
- package/bin/awk.js +673 -15
- package/bin/codex-generators.js +2 -1
- package/core/GEMINI.md +6 -2
- package/core/GEMINI.md.bak +4 -0
- package/core/GreetingEngine/index.js +225 -0
- package/core/GreetingEngine/locales/en.json +6 -0
- package/core/GreetingEngine/locales/ja.json +6 -0
- package/core/GreetingEngine/locales/vi.json +6 -0
- package/core/GreetingEngine/test.js +37 -0
- package/core/skill-runtime-manifest.json +1 -0
- package/docs/PRD.md +57 -0
- package/docs/brainstorm_multi_agent_cli.md +211 -0
- package/docs/history/PRD.v1.md +55 -0
- package/docs/history/PRD.v2.md +57 -0
- package/docs/history/implementation_plan.v1.md +49 -45
- package/docs/history/implementation_plan.v2.md +87 -0
- package/docs/history/memoizedfibonacci_spec.v1.md +127 -0
- package/docs/specs/greetingapp_spec.md +97 -0
- package/docs/specs/memoizedfibonacci_spec.md +211 -0
- package/package.json +1 -1
- package/scripts/codex-goal.js +163 -0
- package/scripts/exec-rtk.js +4 -3
- package/scripts/multi-model-pipeline.js +292 -50
- package/scripts/qwen-exec.js +147 -0
- package/skills/claude-planner/SKILL.md +24 -0
- package/skills/codex-conductor/SKILL.md +25 -1
- package/skills/codex-goal/SKILL.md +82 -0
- package/skills/qwen-conductor/SKILL.md +100 -0
- package/workflows/lifecycle/goal.md +86 -0
- package/workflows/multi-agent-pipeline.md +52 -0
package/bin/awk.js
CHANGED
|
@@ -1945,6 +1945,22 @@ function cmdStatus() {
|
|
|
1945
1945
|
}
|
|
1946
1946
|
|
|
1947
1947
|
log('');
|
|
1948
|
+
|
|
1949
|
+
// ── GitNexus Info ──────────────────────────────────────────────────────
|
|
1950
|
+
const cwd = process.cwd();
|
|
1951
|
+
const gitnexusDir = path.join(cwd, '.gitnexus');
|
|
1952
|
+
if (fs.existsSync(gitnexusDir)) {
|
|
1953
|
+
const registry = readGitnexusRegistry();
|
|
1954
|
+
const match = registry.find(r => r.path === cwd);
|
|
1955
|
+
if (match) {
|
|
1956
|
+
const stats = match.stats || {};
|
|
1957
|
+
log(`${C.bold}GitNexus Info:${C.reset}`);
|
|
1958
|
+
log(` Active repo: ${C.green}${match.name}${C.reset} (${stats.nodes || 0} nodes, ${stats.edges || 0} relations)`);
|
|
1959
|
+
log(` Tip: Run 'awkit index' to refresh index or 'awkit status gn' for details.`);
|
|
1960
|
+
log('');
|
|
1961
|
+
}
|
|
1962
|
+
}
|
|
1963
|
+
|
|
1948
1964
|
log(`${C.gray}Tip: 'awkit sync' = harvest (pull live→repo) + install (push repo→live)${C.reset}`);
|
|
1949
1965
|
log('');
|
|
1950
1966
|
}
|
|
@@ -2026,6 +2042,63 @@ function cmdBuild() {
|
|
|
2026
2042
|
}
|
|
2027
2043
|
}
|
|
2028
2044
|
|
|
2045
|
+
// ─── Run: Safe project-specific run/start script execution ──────────────────
|
|
2046
|
+
|
|
2047
|
+
function cmdRun(runArgs = []) {
|
|
2048
|
+
log('');
|
|
2049
|
+
log(`${C.cyan}${C.bold}🚀 AWK Run Control${C.reset}`);
|
|
2050
|
+
log('');
|
|
2051
|
+
|
|
2052
|
+
const pjPath = path.join(process.cwd(), '.project-identity');
|
|
2053
|
+
const pj = readJsonFile(pjPath, {});
|
|
2054
|
+
|
|
2055
|
+
if (!pj.automation || !pj.automation.run) {
|
|
2056
|
+
warn('No run configuration found in .project-identity under "automation.run".');
|
|
2057
|
+
log('Skipping run...');
|
|
2058
|
+
return;
|
|
2059
|
+
}
|
|
2060
|
+
|
|
2061
|
+
const { enabled, command } = pj.automation.run;
|
|
2062
|
+
|
|
2063
|
+
if (!enabled) {
|
|
2064
|
+
warn('Run is disabled for this project (automation.run.enabled is false).');
|
|
2065
|
+
log('Skipping run...');
|
|
2066
|
+
return;
|
|
2067
|
+
}
|
|
2068
|
+
|
|
2069
|
+
if (!command) {
|
|
2070
|
+
err('Run command is not configured in .project-identity (automation.run.command is empty).');
|
|
2071
|
+
return;
|
|
2072
|
+
}
|
|
2073
|
+
|
|
2074
|
+
const fullCommand = runArgs.length > 0 ? `${command} ${runArgs.join(' ')}` : command;
|
|
2075
|
+
|
|
2076
|
+
info(`Running command: ${C.bold}${fullCommand}${C.reset}`);
|
|
2077
|
+
try {
|
|
2078
|
+
execSync(fullCommand, { stdio: 'inherit' });
|
|
2079
|
+
} catch (e) {
|
|
2080
|
+
log('');
|
|
2081
|
+
err(`Run failed: ${e.message}`);
|
|
2082
|
+
process.exit(e.status || 1);
|
|
2083
|
+
}
|
|
2084
|
+
}
|
|
2085
|
+
|
|
2086
|
+
function cmdTask(taskArgs = []) {
|
|
2087
|
+
try {
|
|
2088
|
+
execSync(`symphony task ${taskArgs.join(' ')}`, { stdio: 'inherit' });
|
|
2089
|
+
} catch (e) {
|
|
2090
|
+
process.exit(e.status || 1);
|
|
2091
|
+
}
|
|
2092
|
+
}
|
|
2093
|
+
|
|
2094
|
+
function cmdProject(projectArgs = []) {
|
|
2095
|
+
try {
|
|
2096
|
+
execSync(`symphony project ${projectArgs.join(' ')}`, { stdio: 'inherit' });
|
|
2097
|
+
} catch (e) {
|
|
2098
|
+
process.exit(e.status || 1);
|
|
2099
|
+
}
|
|
2100
|
+
}
|
|
2101
|
+
|
|
2029
2102
|
async function cmdAdmin() {
|
|
2030
2103
|
info('Mở Symphony Dashboard...');
|
|
2031
2104
|
try {
|
|
@@ -2115,6 +2188,93 @@ async function cmdRestart() {
|
|
|
2115
2188
|
}
|
|
2116
2189
|
}
|
|
2117
2190
|
|
|
2191
|
+
function cmdGreet(args) {
|
|
2192
|
+
let name = 'Guest';
|
|
2193
|
+
let lang = 'en';
|
|
2194
|
+
let timezone = undefined;
|
|
2195
|
+
|
|
2196
|
+
for (let i = 0; i < args.length; i++) {
|
|
2197
|
+
const arg = args[i];
|
|
2198
|
+
if (arg === '--help' || arg === '-h') {
|
|
2199
|
+
log('');
|
|
2200
|
+
log(`${C.cyan}${C.bold}👋 awkit greet — Personalized greetings${C.reset}`);
|
|
2201
|
+
log('');
|
|
2202
|
+
log('Usage:');
|
|
2203
|
+
log(' awkit greet [options]');
|
|
2204
|
+
log('');
|
|
2205
|
+
log('Options:');
|
|
2206
|
+
log(' -n, --name <name> Name of the person to greet (default: "Guest")');
|
|
2207
|
+
log(' -l, --lang <lang> Language code (en, vi, ja) (default: "en")');
|
|
2208
|
+
log(' -t, --timezone <tz> Timezone string (default: system timezone)');
|
|
2209
|
+
log(' -h, --help Show this help message');
|
|
2210
|
+
log('');
|
|
2211
|
+
return;
|
|
2212
|
+
}
|
|
2213
|
+
if ((arg === '--name' || arg === '-n') && args[i + 1] && !args[i + 1].startsWith('-')) {
|
|
2214
|
+
name = args[i + 1];
|
|
2215
|
+
i++;
|
|
2216
|
+
} else if (arg.startsWith('--name=')) {
|
|
2217
|
+
name = arg.split('=')[1];
|
|
2218
|
+
} else if ((arg === '--lang' || arg === '-l') && args[i + 1] && !args[i + 1].startsWith('-')) {
|
|
2219
|
+
lang = args[i + 1];
|
|
2220
|
+
i++;
|
|
2221
|
+
} else if (arg.startsWith('--lang=')) {
|
|
2222
|
+
lang = arg.split('=')[1];
|
|
2223
|
+
} else if ((arg === '--timezone' || arg === '-t') && args[i + 1] && !args[i + 1].startsWith('-')) {
|
|
2224
|
+
timezone = args[i + 1];
|
|
2225
|
+
i++;
|
|
2226
|
+
} else if (arg.startsWith('--timezone=')) {
|
|
2227
|
+
timezone = arg.split('=')[1];
|
|
2228
|
+
}
|
|
2229
|
+
}
|
|
2230
|
+
|
|
2231
|
+
try {
|
|
2232
|
+
const GreetingEngine = require('../core/GreetingEngine');
|
|
2233
|
+
const result = GreetingEngine.generateGreeting({ name, lang, timezone });
|
|
2234
|
+
if (result.status === 'success') {
|
|
2235
|
+
log(result.data.message);
|
|
2236
|
+
} else {
|
|
2237
|
+
err('Failed to generate greeting');
|
|
2238
|
+
}
|
|
2239
|
+
} catch (e) {
|
|
2240
|
+
err('Failed to execute Greeting Engine: ' + e.message);
|
|
2241
|
+
}
|
|
2242
|
+
}
|
|
2243
|
+
|
|
2244
|
+
function cmdGoal(args) {
|
|
2245
|
+
if (args.includes('--help') || args.includes('-h')) {
|
|
2246
|
+
log('');
|
|
2247
|
+
log(`${C.cyan}${C.bold}🎯 awkit goal — Codex Goal Mode Orchestrator${C.reset}`);
|
|
2248
|
+
log('');
|
|
2249
|
+
log('Usage:');
|
|
2250
|
+
log(' awkit goal "<objective>"');
|
|
2251
|
+
log(' awkit goal --status');
|
|
2252
|
+
log(' awkit goal --pause');
|
|
2253
|
+
log(' awkit goal --resume');
|
|
2254
|
+
log(' awkit goal --cancel');
|
|
2255
|
+
log('');
|
|
2256
|
+
return;
|
|
2257
|
+
}
|
|
2258
|
+
|
|
2259
|
+
try {
|
|
2260
|
+
const scriptPath = path.join(__dirname, '..', 'scripts', 'codex-goal.js');
|
|
2261
|
+
const passArgs = [];
|
|
2262
|
+
|
|
2263
|
+
if (args.length > 0 && !args[0].startsWith('-')) {
|
|
2264
|
+
passArgs.push('--prompt', args.join(' '));
|
|
2265
|
+
} else {
|
|
2266
|
+
passArgs.push(...args);
|
|
2267
|
+
}
|
|
2268
|
+
|
|
2269
|
+
const result = spawnSync('node', [scriptPath, ...passArgs], { stdio: 'inherit' });
|
|
2270
|
+
if (result.status !== 0) {
|
|
2271
|
+
process.exit(result.status || 1);
|
|
2272
|
+
}
|
|
2273
|
+
} catch (e) {
|
|
2274
|
+
err('Failed to execute Codex Goal Mode: ' + e.message);
|
|
2275
|
+
}
|
|
2276
|
+
}
|
|
2277
|
+
|
|
2118
2278
|
function cmdHelp() {
|
|
2119
2279
|
const line = `${C.gray}${'─'.repeat(56)}${C.reset}`;
|
|
2120
2280
|
log('');
|
|
@@ -2138,9 +2298,13 @@ function cmdHelp() {
|
|
|
2138
2298
|
if (identity.automation && identity.automation.build && identity.automation.build.enabled) {
|
|
2139
2299
|
bCmd = identity.automation.build.command || 'Enabled';
|
|
2140
2300
|
}
|
|
2301
|
+
let rCmd = 'Disabled';
|
|
2302
|
+
if (identity.automation && identity.automation.run && identity.automation.run.enabled) {
|
|
2303
|
+
rCmd = identity.automation.run.command || 'Enabled';
|
|
2304
|
+
}
|
|
2141
2305
|
|
|
2142
2306
|
log(`${C.cyan}👉 Active Project: ${icon} ${C.bold}${name}${C.reset}`);
|
|
2143
|
-
log(` [${pType} | Build Control: ${bCmd === 'Disabled' ? C.yellow + 'Manual' : C.green + bCmd}${C.reset}]`);
|
|
2307
|
+
log(` [${pType} | Build Control: ${bCmd === 'Disabled' ? C.yellow + 'Manual' : C.green + bCmd} | Run Control: ${rCmd === 'Disabled' ? C.yellow + 'Manual' : C.green + rCmd}${C.reset}]`);
|
|
2144
2308
|
log(` Run ${C.green}awkit identity${C.reset} for full configuration details.`);
|
|
2145
2309
|
log('');
|
|
2146
2310
|
} catch (_) {}
|
|
@@ -2158,6 +2322,10 @@ function cmdHelp() {
|
|
|
2158
2322
|
log(` ${C.green}credentials list${C.reset} List stored API keys`);
|
|
2159
2323
|
log(` ${C.green}credentials set${C.reset} <k> <v> Set API key (e.g., gemini_api_key, openrouter_api_key)`);
|
|
2160
2324
|
log(` ${C.green}set-openrouter${C.reset} <key> Shorthand for setting OpenRouter API Key`);
|
|
2325
|
+
log(` ${C.green}config-global list${C.reset} List all global configurations`);
|
|
2326
|
+
log(` ${C.green}config-global set${C.reset} <k> <v> Set global configuration`);
|
|
2327
|
+
log(` ${C.green}config-global audio${C.reset} <on|off> Turn audio alerts on/off globally`);
|
|
2328
|
+
log(` ${C.green}config audio${C.reset} <on|off> Shorthand to turn audio alerts on/off globally`);
|
|
2161
2329
|
log('');
|
|
2162
2330
|
|
|
2163
2331
|
// Project Init
|
|
@@ -2169,6 +2337,7 @@ function cmdHelp() {
|
|
|
2169
2337
|
log(` ${C.gray} CODEBASE.md, thiết lập router (AGENTS.md, CLAUDE.md)${C.reset}`);
|
|
2170
2338
|
log(` ${C.green}identity${C.reset} Show project identity & active configurations (alias: config)`);
|
|
2171
2339
|
log(` ${C.green}build${C.reset} Run project build based on .project-identity config`);
|
|
2340
|
+
log(` ${C.green}run${C.reset} [args] Run project-specific start/dev commands based on config`);
|
|
2172
2341
|
log('');
|
|
2173
2342
|
|
|
2174
2343
|
// Maintenance
|
|
@@ -2195,10 +2364,31 @@ function cmdHelp() {
|
|
|
2195
2364
|
log(` ${C.green}sync${C.reset} Full sync: harvest + install (one shot)`);
|
|
2196
2365
|
log('');
|
|
2197
2366
|
|
|
2367
|
+
// GreetingApp
|
|
2368
|
+
log(`${C.bold}👋 GreetingApp${C.reset}`);
|
|
2369
|
+
log(line);
|
|
2370
|
+
log(` ${C.green}greet${C.reset} [options] Generate personalized dynamic greeting`);
|
|
2371
|
+
log(` ${C.gray} -n, --name <name>${C.reset} User name to greet (default: Guest)`);
|
|
2372
|
+
log(` ${C.gray} -l, --lang <lang>${C.reset} Language code: en, vi, ja (default: en)`);
|
|
2373
|
+
log(` ${C.gray} -t, --timezone <tz>${C.reset} Timezone parameter`);
|
|
2374
|
+
log('');
|
|
2375
|
+
|
|
2376
|
+
// Goal Mode
|
|
2377
|
+
log(`${C.bold}🎯 Goal Mode${C.reset}`);
|
|
2378
|
+
log(line);
|
|
2379
|
+
log(` ${C.green}goal${C.reset} <objective> Pursue a high-level goal using Codex Goal Conductor`);
|
|
2380
|
+
log(` ${C.green}goal --status${C.reset} Check active goal status and task progress`);
|
|
2381
|
+
log(` ${C.green}goal --pause${C.reset} Pause active goal execution loop`);
|
|
2382
|
+
log(` ${C.green}goal --resume${C.reset} Resume paused goal execution`);
|
|
2383
|
+
log(` ${C.green}goal --cancel${C.reset} Cancel and reset active goal session`);
|
|
2384
|
+
log('');
|
|
2385
|
+
|
|
2198
2386
|
// Symphony
|
|
2199
2387
|
log(`${C.bold}🎶 Symphony${C.reset}`);
|
|
2200
2388
|
log(line);
|
|
2201
2389
|
log(` ${C.green}admin${C.reset} Khởi động Symphony Dashboard`);
|
|
2390
|
+
log(` ${C.green}task${C.reset} [args] Manage Symphony tasks directly`);
|
|
2391
|
+
log(` ${C.green}project${C.reset} [args] Manage Symphony projects directly`);
|
|
2202
2392
|
log('');
|
|
2203
2393
|
|
|
2204
2394
|
// Packs
|
|
@@ -2222,11 +2412,23 @@ function cmdHelp() {
|
|
|
2222
2412
|
log('');
|
|
2223
2413
|
|
|
2224
2414
|
// Pipeline
|
|
2225
|
-
log(`${C.bold}🔗 Pipeline${C.reset}`);
|
|
2415
|
+
log(`${C.bold}🔗 Pipeline & Sub-Agents${C.reset}`);
|
|
2226
2416
|
log(line);
|
|
2227
|
-
log(` ${C.green}pipeline plan${C.reset} <Feature> Lập kế hoạch kiến trúc (
|
|
2228
|
-
log(` ${C.green}pipeline ui${C.reset} <Feature> Thiết kế shell & GUI assets (Codex)`);
|
|
2229
|
-
log(` ${C.green}pipeline code${C.reset} <Feature> Thực thi viết code & review (Gemini
|
|
2417
|
+
log(` ${C.green}pipeline plan${C.reset} <Feature> Lập kế hoạch kiến trúc (Claude / Gemini fallback)`);
|
|
2418
|
+
log(` ${C.green}pipeline ui${C.reset} <Feature> Thiết kế shell & GUI assets (Codex / Gemini fallback)`);
|
|
2419
|
+
log(` ${C.green}pipeline code${C.reset} <Feature> Thực thi viết code & review (Qwen / Gemini fallback)`);
|
|
2420
|
+
log('');
|
|
2421
|
+
log(` ${C.bold}🤖 Multi-Agent Collaborative System${C.reset}`);
|
|
2422
|
+
log(` AWKit integrates third-party CLI agents to optimize reasoning quality & costs:`);
|
|
2423
|
+
log(` • ${C.cyan}Claude Code${C.reset} ➜ Architect planning & complex reasoning (Gate 2/4)`);
|
|
2424
|
+
log(` • ${C.cyan}Codex CLI${C.reset} ➜ UI shell design, asset generation & reviews (Gate 2.5/5)`);
|
|
2425
|
+
log(` • ${C.cyan}Qwen Coder${C.reset} ➜ Fast local boilerplate code execution (Gate 4)`);
|
|
2426
|
+
log(` • ${C.cyan}Gemini Flash${C.reset} ➜ Central coordination, active context & fallback router`);
|
|
2427
|
+
log('');
|
|
2428
|
+
log(` To query or configure active runners and alerts:`);
|
|
2429
|
+
log(` - Run ${C.green}awkit config list${C.reset} to show current settings`);
|
|
2430
|
+
log(` - Run ${C.green}awkit config runners${C.reset} to check paths & binary availability`);
|
|
2431
|
+
log(` - Run ${C.green}awkit config <runner> <on|off>${C.reset} to toggle specific runner`);
|
|
2230
2432
|
log('');
|
|
2231
2433
|
|
|
2232
2434
|
// Trello
|
|
@@ -2252,15 +2454,16 @@ function cmdHelp() {
|
|
|
2252
2454
|
log('');
|
|
2253
2455
|
|
|
2254
2456
|
// GitNexus
|
|
2255
|
-
log(`${C.bold}🔍 GitNexus${C.reset}`);
|
|
2457
|
+
log(`${C.bold}🔍 GitNexus (Shortcuts: index, clean, list)${C.reset}`);
|
|
2256
2458
|
log(line);
|
|
2257
|
-
log(` ${C.green}
|
|
2258
|
-
log(` ${C.green}
|
|
2259
|
-
log(` ${C.green}
|
|
2260
|
-
log(` ${C.green}
|
|
2459
|
+
log(` ${C.green}index${C.reset} Index/refresh current codebase (alias: analyze)`);
|
|
2460
|
+
log(` ${C.green}list${C.reset} List all indexed repositories`);
|
|
2461
|
+
log(` ${C.green}status gn${C.reset} Show current project index info (or 'gn status')`);
|
|
2462
|
+
log(` ${C.green}clean${C.reset} Interactive cleanup of old indexes`);
|
|
2463
|
+
log(` ${C.green}clean${C.reset} ${C.gray}<name...>${C.reset} Remove specific repo(s) by name`);
|
|
2261
2464
|
log(` ${C.gray} --stale${C.reset} Auto-remove repos with missing paths`);
|
|
2262
2465
|
log(` ${C.gray} --all${C.reset} Remove all except current project`);
|
|
2263
|
-
log(` ${C.gray} Alias: gn${C.reset}`);
|
|
2466
|
+
log(` ${C.gray} Alias: gn / gitnexus${C.reset}`);
|
|
2264
2467
|
log('');
|
|
2265
2468
|
|
|
2266
2469
|
// Available packs
|
|
@@ -2615,6 +2818,16 @@ function buildProjectIdentity(projectName, projectType, cwd, date) {
|
|
|
2615
2818
|
automation: {
|
|
2616
2819
|
autoQA: true,
|
|
2617
2820
|
maxSelfCorrectionLoops: 3,
|
|
2821
|
+
multiAgent: {
|
|
2822
|
+
enabled: true,
|
|
2823
|
+
routingMode: 'cost-optimized',
|
|
2824
|
+
audioAlerts: true,
|
|
2825
|
+
runners: {
|
|
2826
|
+
claude: 'claude',
|
|
2827
|
+
codex: 'codex',
|
|
2828
|
+
qwen: 'qwen'
|
|
2829
|
+
}
|
|
2830
|
+
},
|
|
2618
2831
|
telegram: {
|
|
2619
2832
|
enabled: true,
|
|
2620
2833
|
chatId: "",
|
|
@@ -2862,6 +3075,16 @@ async function cmdInit(forceFlag = false) {
|
|
|
2862
3075
|
currentIdentity.automation = {
|
|
2863
3076
|
autoQA: true,
|
|
2864
3077
|
maxSelfCorrectionLoops: 3,
|
|
3078
|
+
multiAgent: {
|
|
3079
|
+
enabled: true,
|
|
3080
|
+
routingMode: 'cost-optimized',
|
|
3081
|
+
audioAlerts: true,
|
|
3082
|
+
runners: {
|
|
3083
|
+
claude: 'claude',
|
|
3084
|
+
codex: 'codex',
|
|
3085
|
+
qwen: 'qwen'
|
|
3086
|
+
}
|
|
3087
|
+
},
|
|
2865
3088
|
telegram: {
|
|
2866
3089
|
enabled: true,
|
|
2867
3090
|
chatId: "",
|
|
@@ -2902,6 +3125,33 @@ async function cmdInit(forceFlag = false) {
|
|
|
2902
3125
|
currentIdentity.automation.maxSelfCorrectionLoops = 3;
|
|
2903
3126
|
changed = true;
|
|
2904
3127
|
}
|
|
3128
|
+
if (!currentIdentity.automation.multiAgent) {
|
|
3129
|
+
currentIdentity.automation.multiAgent = {
|
|
3130
|
+
enabled: true,
|
|
3131
|
+
routingMode: 'cost-optimized',
|
|
3132
|
+
audioAlerts: true,
|
|
3133
|
+
runners: {
|
|
3134
|
+
claude: 'claude',
|
|
3135
|
+
codex: 'codex',
|
|
3136
|
+
qwen: 'qwen'
|
|
3137
|
+
}
|
|
3138
|
+
};
|
|
3139
|
+
changed = true;
|
|
3140
|
+
} else {
|
|
3141
|
+
if (!currentIdentity.automation.multiAgent.runners) {
|
|
3142
|
+
currentIdentity.automation.multiAgent.runners = {
|
|
3143
|
+
claude: 'claude',
|
|
3144
|
+
codex: 'codex',
|
|
3145
|
+
qwen: 'qwen'
|
|
3146
|
+
};
|
|
3147
|
+
changed = true;
|
|
3148
|
+
} else {
|
|
3149
|
+
const runners = currentIdentity.automation.multiAgent.runners;
|
|
3150
|
+
if (!runners.claude) { runners.claude = 'claude'; changed = true; }
|
|
3151
|
+
if (!runners.codex) { runners.codex = 'codex'; changed = true; }
|
|
3152
|
+
if (!runners.qwen) { runners.qwen = 'qwen'; changed = true; }
|
|
3153
|
+
}
|
|
3154
|
+
}
|
|
2905
3155
|
if (!currentIdentity.automation.obsidian) {
|
|
2906
3156
|
currentIdentity.automation.obsidian = { enabled: false, path: "", autoSync: false };
|
|
2907
3157
|
changed = true;
|
|
@@ -4172,9 +4422,34 @@ function cmdGitnexus(args) {
|
|
|
4172
4422
|
break;
|
|
4173
4423
|
}
|
|
4174
4424
|
|
|
4425
|
+
case 'index':
|
|
4426
|
+
case 'analyze':
|
|
4427
|
+
case 'build': {
|
|
4428
|
+
const cwd = process.cwd();
|
|
4429
|
+
const usePnpm = fs.existsSync(path.join(cwd, 'pnpm-lock.yaml'));
|
|
4430
|
+
const indexCmd = usePnpm ? 'pnpm' : 'npx';
|
|
4431
|
+
const indexArgs = usePnpm ? ['dlx', 'gitnexus', 'analyze'] : ['-y', 'gitnexus', 'analyze'];
|
|
4432
|
+
|
|
4433
|
+
info(`Indexing codebase with GitNexus (${usePnpm ? 'pnpm' : 'npx'})...`);
|
|
4434
|
+
dim(`Running: ${indexCmd} ${indexArgs.join(' ')}`);
|
|
4435
|
+
|
|
4436
|
+
const result = spawnSync(indexCmd, indexArgs, {
|
|
4437
|
+
cwd,
|
|
4438
|
+
stdio: 'inherit',
|
|
4439
|
+
shell: true
|
|
4440
|
+
});
|
|
4441
|
+
|
|
4442
|
+
if (result.status === 0) {
|
|
4443
|
+
ok('GitNexus index successfully refreshed! ✨');
|
|
4444
|
+
} else {
|
|
4445
|
+
err(`GitNexus indexing failed with exit code ${result.status}`);
|
|
4446
|
+
}
|
|
4447
|
+
break;
|
|
4448
|
+
}
|
|
4449
|
+
|
|
4175
4450
|
default:
|
|
4176
4451
|
err(`Unknown gitnexus sub-command: ${sub}`);
|
|
4177
|
-
log(` Available: list, status, clean`);
|
|
4452
|
+
log(` Available: index, list, status, clean`);
|
|
4178
4453
|
break;
|
|
4179
4454
|
}
|
|
4180
4455
|
}
|
|
@@ -4352,6 +4627,14 @@ function cmdIdentity(args = []) {
|
|
|
4352
4627
|
} else {
|
|
4353
4628
|
log(` ${C.bold}Build Control:${C.reset} ${C.yellow}Not Configured (Manual Mode)${C.reset}`);
|
|
4354
4629
|
}
|
|
4630
|
+
if (identity.automation && identity.automation.run) {
|
|
4631
|
+
const r = identity.automation.run;
|
|
4632
|
+
const statusStr = r.enabled ? `${C.green}Enabled (Safe Auto-Run via awkit run)${C.reset}` : `${C.yellow}Disabled / Manual Only${C.reset}`;
|
|
4633
|
+
log(` ${C.bold}Run Control:${C.reset} ${statusStr}`);
|
|
4634
|
+
log(` ${C.bold}Run Command:${C.reset} ${C.cyan}${r.command || 'N/A'}${C.reset}`);
|
|
4635
|
+
} else {
|
|
4636
|
+
log(` ${C.bold}Run Control:${C.reset} ${C.yellow}Not Configured (Manual Mode)${C.reset}`);
|
|
4637
|
+
}
|
|
4355
4638
|
log('');
|
|
4356
4639
|
|
|
4357
4640
|
// Automation Gates
|
|
@@ -4488,6 +4771,335 @@ function cmdServe(args) {
|
|
|
4488
4771
|
});
|
|
4489
4772
|
}
|
|
4490
4773
|
|
|
4774
|
+
const GLOBAL_CONFIG_PATH = path.join(HOME, '.awkit_config.json');
|
|
4775
|
+
|
|
4776
|
+
function readGlobalConfig() {
|
|
4777
|
+
const defaultConf = {
|
|
4778
|
+
audioAlerts: true,
|
|
4779
|
+
runners: {
|
|
4780
|
+
claude: true,
|
|
4781
|
+
codex: true,
|
|
4782
|
+
qwen: true
|
|
4783
|
+
}
|
|
4784
|
+
};
|
|
4785
|
+
if (!fs.existsSync(GLOBAL_CONFIG_PATH)) return defaultConf;
|
|
4786
|
+
try {
|
|
4787
|
+
const parsed = JSON.parse(fs.readFileSync(GLOBAL_CONFIG_PATH, 'utf8'));
|
|
4788
|
+
return {
|
|
4789
|
+
...defaultConf,
|
|
4790
|
+
...parsed,
|
|
4791
|
+
runners: {
|
|
4792
|
+
...defaultConf.runners,
|
|
4793
|
+
...(parsed.runners || {})
|
|
4794
|
+
}
|
|
4795
|
+
};
|
|
4796
|
+
} catch (_) {
|
|
4797
|
+
return defaultConf;
|
|
4798
|
+
}
|
|
4799
|
+
}
|
|
4800
|
+
|
|
4801
|
+
function writeGlobalConfig(config) {
|
|
4802
|
+
try {
|
|
4803
|
+
fs.writeFileSync(GLOBAL_CONFIG_PATH, JSON.stringify(config, null, 2) + '\n', 'utf8');
|
|
4804
|
+
return true;
|
|
4805
|
+
} catch (e) {
|
|
4806
|
+
err(`Failed to write global config: ${e.message}`);
|
|
4807
|
+
return false;
|
|
4808
|
+
}
|
|
4809
|
+
}
|
|
4810
|
+
|
|
4811
|
+
function findClaudePath() {
|
|
4812
|
+
let localConfig = {};
|
|
4813
|
+
try {
|
|
4814
|
+
const p = path.join(process.cwd(), '.project-identity');
|
|
4815
|
+
if (fs.existsSync(p)) {
|
|
4816
|
+
localConfig = JSON.parse(fs.readFileSync(p, 'utf8'));
|
|
4817
|
+
}
|
|
4818
|
+
} catch (_) {}
|
|
4819
|
+
|
|
4820
|
+
if (localConfig.automation?.multiAgent?.runners?.claude) {
|
|
4821
|
+
const p = localConfig.automation.multiAgent.runners.claude;
|
|
4822
|
+
if (fs.existsSync(p)) return p;
|
|
4823
|
+
}
|
|
4824
|
+
const homeClaude = path.join(os.homedir(), '.claude', 'local', 'claude');
|
|
4825
|
+
if (fs.existsSync(homeClaude)) return homeClaude;
|
|
4826
|
+
|
|
4827
|
+
try {
|
|
4828
|
+
const shell = process.env.SHELL || '/bin/zsh';
|
|
4829
|
+
const shellCmd = shell.endsWith('zsh') ? 'zsh -lc "which claude"' : 'bash -lc "which claude"';
|
|
4830
|
+
const detected = execSync(shellCmd, { encoding: 'utf8', stdio: ['ignore', 'pipe', 'ignore'] }).trim();
|
|
4831
|
+
if (detected && fs.existsSync(detected)) return detected;
|
|
4832
|
+
} catch (_) {}
|
|
4833
|
+
|
|
4834
|
+
return 'claude';
|
|
4835
|
+
}
|
|
4836
|
+
|
|
4837
|
+
function findCodexPath() {
|
|
4838
|
+
let localConfig = {};
|
|
4839
|
+
try {
|
|
4840
|
+
const p = path.join(process.cwd(), '.project-identity');
|
|
4841
|
+
if (fs.existsSync(p)) {
|
|
4842
|
+
localConfig = JSON.parse(fs.readFileSync(p, 'utf8'));
|
|
4843
|
+
}
|
|
4844
|
+
} catch (_) {}
|
|
4845
|
+
|
|
4846
|
+
if (localConfig.automation?.multiAgent?.runners?.codex) {
|
|
4847
|
+
const p = localConfig.automation.multiAgent.runners.codex;
|
|
4848
|
+
if (fs.existsSync(p)) return p;
|
|
4849
|
+
}
|
|
4850
|
+
try {
|
|
4851
|
+
const shell = process.env.SHELL || '/bin/zsh';
|
|
4852
|
+
const shellCmd = shell.endsWith('zsh') ? 'zsh -lc "which codex"' : 'bash -lc "which codex"';
|
|
4853
|
+
const detected = execSync(shellCmd, { encoding: 'utf8', stdio: ['ignore', 'pipe', 'ignore'] }).trim();
|
|
4854
|
+
if (detected && fs.existsSync(detected)) return detected;
|
|
4855
|
+
} catch (_) {}
|
|
4856
|
+
return 'codex';
|
|
4857
|
+
}
|
|
4858
|
+
|
|
4859
|
+
function findQwenPath() {
|
|
4860
|
+
let localConfig = {};
|
|
4861
|
+
try {
|
|
4862
|
+
const p = path.join(process.cwd(), '.project-identity');
|
|
4863
|
+
if (fs.existsSync(p)) {
|
|
4864
|
+
localConfig = JSON.parse(fs.readFileSync(p, 'utf8'));
|
|
4865
|
+
}
|
|
4866
|
+
} catch (_) {}
|
|
4867
|
+
|
|
4868
|
+
if (localConfig.automation?.multiAgent?.runners?.qwen) {
|
|
4869
|
+
const p = localConfig.automation.multiAgent.runners.qwen;
|
|
4870
|
+
if (fs.existsSync(p)) return p;
|
|
4871
|
+
}
|
|
4872
|
+
try {
|
|
4873
|
+
const shell = process.env.SHELL || '/bin/zsh';
|
|
4874
|
+
const shellCmd = shell.endsWith('zsh') ? 'zsh -lc "which qwen"' : 'bash -lc "which qwen"';
|
|
4875
|
+
const detected = execSync(shellCmd, { encoding: 'utf8', stdio: ['ignore', 'pipe', 'ignore'] }).trim();
|
|
4876
|
+
if (detected && fs.existsSync(detected)) return detected;
|
|
4877
|
+
} catch (_) {}
|
|
4878
|
+
return 'qwen';
|
|
4879
|
+
}
|
|
4880
|
+
|
|
4881
|
+
function isRunnerEnabled(runnerName) {
|
|
4882
|
+
let localConfig = {};
|
|
4883
|
+
try {
|
|
4884
|
+
const p = path.join(process.cwd(), '.project-identity');
|
|
4885
|
+
if (fs.existsSync(p)) {
|
|
4886
|
+
localConfig = JSON.parse(fs.readFileSync(p, 'utf8'));
|
|
4887
|
+
}
|
|
4888
|
+
} catch (_) {}
|
|
4889
|
+
|
|
4890
|
+
const localVal = localConfig.automation?.multiAgent?.runnersEnabled?.[runnerName];
|
|
4891
|
+
if (localVal !== undefined) return localVal;
|
|
4892
|
+
|
|
4893
|
+
const globalConfig = readGlobalConfig();
|
|
4894
|
+
const globalVal = globalConfig.runners?.[runnerName];
|
|
4895
|
+
if (globalVal !== undefined) return globalVal;
|
|
4896
|
+
|
|
4897
|
+
return true;
|
|
4898
|
+
}
|
|
4899
|
+
|
|
4900
|
+
function isRunnerAvailable(runnerName) {
|
|
4901
|
+
if (!isRunnerEnabled(runnerName)) return false;
|
|
4902
|
+
let p;
|
|
4903
|
+
if (runnerName === 'claude') p = findClaudePath();
|
|
4904
|
+
else if (runnerName === 'codex') p = findCodexPath();
|
|
4905
|
+
else if (runnerName === 'qwen') p = findQwenPath();
|
|
4906
|
+
else return false;
|
|
4907
|
+
|
|
4908
|
+
if (fs.existsSync(p)) return true;
|
|
4909
|
+
try {
|
|
4910
|
+
execSync(`which ${p} || command -v ${p}`, { stdio: 'ignore' });
|
|
4911
|
+
return true;
|
|
4912
|
+
} catch (_) {
|
|
4913
|
+
return false;
|
|
4914
|
+
}
|
|
4915
|
+
}
|
|
4916
|
+
|
|
4917
|
+
function cmdGlobalConfig(args = []) {
|
|
4918
|
+
const sub = args[0];
|
|
4919
|
+
if (sub === 'audio') {
|
|
4920
|
+
const config = readGlobalConfig();
|
|
4921
|
+
const action = args[1];
|
|
4922
|
+
if (!action) {
|
|
4923
|
+
info(`Audio Alerts: ${config.audioAlerts ? 'ON' : 'OFF'}`);
|
|
4924
|
+
return;
|
|
4925
|
+
}
|
|
4926
|
+
if (action === 'on' || action === 'true' || action === '1') {
|
|
4927
|
+
config.audioAlerts = true;
|
|
4928
|
+
if (writeGlobalConfig(config)) {
|
|
4929
|
+
ok('Audio alerts turned ON globally.');
|
|
4930
|
+
}
|
|
4931
|
+
} else if (action === 'off' || action === 'false' || action === '0') {
|
|
4932
|
+
config.audioAlerts = false;
|
|
4933
|
+
if (writeGlobalConfig(config)) {
|
|
4934
|
+
ok('Audio alerts turned OFF globally.');
|
|
4935
|
+
}
|
|
4936
|
+
} else {
|
|
4937
|
+
err(`Invalid audio option: ${action}. Use 'on' or 'off'.`);
|
|
4938
|
+
}
|
|
4939
|
+
return;
|
|
4940
|
+
}
|
|
4941
|
+
|
|
4942
|
+
if (sub === 'claude' || sub === 'codex' || sub === 'qwen') {
|
|
4943
|
+
const config = readGlobalConfig();
|
|
4944
|
+
const action = args[1];
|
|
4945
|
+
if (!action) {
|
|
4946
|
+
info(`${sub.toUpperCase()} Runner: ${config.runners?.[sub] !== false ? 'ON' : 'OFF'}`);
|
|
4947
|
+
return;
|
|
4948
|
+
}
|
|
4949
|
+
if (action === 'on' || action === 'true' || action === '1') {
|
|
4950
|
+
config.runners = config.runners || {};
|
|
4951
|
+
config.runners[sub] = true;
|
|
4952
|
+
if (writeGlobalConfig(config)) {
|
|
4953
|
+
ok(`${sub.toUpperCase()} runner turned ON globally.`);
|
|
4954
|
+
}
|
|
4955
|
+
} else if (action === 'off' || action === 'false' || action === '0') {
|
|
4956
|
+
config.runners = config.runners || {};
|
|
4957
|
+
config.runners[sub] = false;
|
|
4958
|
+
if (writeGlobalConfig(config)) {
|
|
4959
|
+
ok(`${sub.toUpperCase()} runner turned OFF globally.`);
|
|
4960
|
+
}
|
|
4961
|
+
} else {
|
|
4962
|
+
err(`Invalid runner option: ${action}. Use 'on' or 'off'.`);
|
|
4963
|
+
}
|
|
4964
|
+
return;
|
|
4965
|
+
}
|
|
4966
|
+
|
|
4967
|
+
if (sub === 'runners' || sub === 'runner') {
|
|
4968
|
+
const line = `${C.gray}${'─'.repeat(60)}${C.reset}`;
|
|
4969
|
+
log('');
|
|
4970
|
+
log(`${C.cyan}${C.bold}🏃 RUNNER AGENTS STATUS${C.reset}`);
|
|
4971
|
+
log(line);
|
|
4972
|
+
|
|
4973
|
+
const runners = ['claude', 'codex', 'qwen'];
|
|
4974
|
+
for (const r of runners) {
|
|
4975
|
+
const enabled = isRunnerEnabled(r);
|
|
4976
|
+
const path = r === 'claude' ? findClaudePath() : (r === 'codex' ? findCodexPath() : findQwenPath());
|
|
4977
|
+
const available = isRunnerAvailable(r);
|
|
4978
|
+
|
|
4979
|
+
const statusStr = enabled ? `${C.green}ON${C.reset}` : `${C.red}OFF${C.reset}`;
|
|
4980
|
+
const availStr = available ? `${C.green}✅ Available${C.reset}` : `${C.red}❌ Unavailable${C.reset}`;
|
|
4981
|
+
|
|
4982
|
+
log(` ● ${C.bold}${r.padEnd(8)}${C.reset} Status: [${statusStr}] Path: ${path.padEnd(30)} [${availStr}]`);
|
|
4983
|
+
}
|
|
4984
|
+
log('');
|
|
4985
|
+
return;
|
|
4986
|
+
}
|
|
4987
|
+
|
|
4988
|
+
if (sub === 'models' || sub === 'model') {
|
|
4989
|
+
const line = `${C.gray}${'─'.repeat(60)}${C.reset}`;
|
|
4990
|
+
log('');
|
|
4991
|
+
log(`${C.cyan}${C.bold}🤖 MODEL ROUTING POLICY${C.reset}`);
|
|
4992
|
+
log(line);
|
|
4993
|
+
|
|
4994
|
+
let localConfig = {};
|
|
4995
|
+
let projectLoaded = false;
|
|
4996
|
+
try {
|
|
4997
|
+
const p = path.join(process.cwd(), '.project-identity');
|
|
4998
|
+
if (fs.existsSync(p)) {
|
|
4999
|
+
localConfig = JSON.parse(fs.readFileSync(p, 'utf8'));
|
|
5000
|
+
projectLoaded = true;
|
|
5001
|
+
}
|
|
5002
|
+
} catch (_) {}
|
|
5003
|
+
|
|
5004
|
+
if (projectLoaded) {
|
|
5005
|
+
log(` Project: ${C.green}${C.bold}${localConfig.projectName || 'Active Project'}${C.reset}`);
|
|
5006
|
+
const policy = localConfig.modelPolicy || {};
|
|
5007
|
+
log(` Routing Mode: ${C.cyan}${policy.mode || 'auto'}${C.reset}`);
|
|
5008
|
+
log(` Default Tier: ${C.cyan}${policy.defaultTier || 'STANDARD'}${C.reset}`);
|
|
5009
|
+
|
|
5010
|
+
if (policy.tierOverrides && Object.keys(policy.tierOverrides).length > 0) {
|
|
5011
|
+
log(` Tier Overrides:`);
|
|
5012
|
+
for (const [pattern, tier] of Object.entries(policy.tierOverrides)) {
|
|
5013
|
+
log(` * ${pattern.padEnd(20)} ➜ ${C.yellow}${tier}${C.reset}`);
|
|
5014
|
+
}
|
|
5015
|
+
}
|
|
5016
|
+
} else {
|
|
5017
|
+
log(` No project loaded in current directory.`);
|
|
5018
|
+
}
|
|
5019
|
+
|
|
5020
|
+
log(line);
|
|
5021
|
+
log(` ${C.bold}Default Models:${C.reset}`);
|
|
5022
|
+
log(` * Standard execution: ${C.green}gemini-3.5-flash${C.reset} (Fast & cost-efficient)`);
|
|
5023
|
+
log(` * Heavy / Spec tasks: ${C.green}gemini-3.1-pro${C.reset} (High reasoning quality)`);
|
|
5024
|
+
log(` * Light tasks: ${C.green}gemini-3.1-flash-lite${C.reset} (Ultra-low latency)`);
|
|
5025
|
+
log('');
|
|
5026
|
+
return;
|
|
5027
|
+
}
|
|
5028
|
+
|
|
5029
|
+
if (!sub || sub === 'list') {
|
|
5030
|
+
const config = readGlobalConfig();
|
|
5031
|
+
const line = `${C.gray}${'─'.repeat(60)}${C.reset}`;
|
|
5032
|
+
log('');
|
|
5033
|
+
log(`${C.cyan}${C.bold}⚙️ AWK CLI CONFIGURATION${C.reset}`);
|
|
5034
|
+
log(line);
|
|
5035
|
+
|
|
5036
|
+
const formatBool = (val) => val !== false ? `${C.green}ON${C.reset}` : `${C.red}OFF${C.reset}`;
|
|
5037
|
+
|
|
5038
|
+
log(` ${C.bold}audioAlerts${C.reset.padEnd(20)} ${formatBool(config.audioAlerts).padEnd(15)} Play speech and chimes on complete`);
|
|
5039
|
+
log(` ${C.bold}runners.claude${C.reset.padEnd(20)} ${formatBool(config.runners?.claude).padEnd(15)} Use Claude Code CLI for planning`);
|
|
5040
|
+
log(` ${C.bold}runners.codex${C.reset.padEnd(20)} ${formatBool(config.runners?.codex).padEnd(15)} Use Codex CLI for UI and assets`);
|
|
5041
|
+
log(` ${C.bold}runners.qwen${C.reset.padEnd(20)} ${formatBool(config.runners?.qwen).padEnd(15)} Use Qwen Coder CLI for execution`);
|
|
5042
|
+
log(line);
|
|
5043
|
+
log(`💡 To toggle, run: ${C.cyan}awkit config <param> <on|off>${C.reset}`);
|
|
5044
|
+
log(` Example: ${C.cyan}awkit config claude off${C.reset}`);
|
|
5045
|
+
log('');
|
|
5046
|
+
return;
|
|
5047
|
+
}
|
|
5048
|
+
|
|
5049
|
+
if (sub === 'get' && args[1]) {
|
|
5050
|
+
const config = readGlobalConfig();
|
|
5051
|
+
const key = args[1];
|
|
5052
|
+
let val;
|
|
5053
|
+
if (key.includes('.')) {
|
|
5054
|
+
val = key.split('.').reduce((acc, part) => acc && acc[part], config);
|
|
5055
|
+
} else {
|
|
5056
|
+
val = config[key];
|
|
5057
|
+
}
|
|
5058
|
+
if (val !== undefined) {
|
|
5059
|
+
console.log(val);
|
|
5060
|
+
} else {
|
|
5061
|
+
err(`Key "${key}" not found in global config.`);
|
|
5062
|
+
}
|
|
5063
|
+
return;
|
|
5064
|
+
}
|
|
5065
|
+
|
|
5066
|
+
if (sub === 'set' && args[1] && args[2] !== undefined) {
|
|
5067
|
+
const config = readGlobalConfig();
|
|
5068
|
+
const key = args[1];
|
|
5069
|
+
let val = args[2];
|
|
5070
|
+
if (val === 'true') val = true;
|
|
5071
|
+
if (val === 'false') val = false;
|
|
5072
|
+
|
|
5073
|
+
if (key.includes('.')) {
|
|
5074
|
+
const parts = key.split('.');
|
|
5075
|
+
let current = config;
|
|
5076
|
+
for (let i = 0; i < parts.length - 1; i++) {
|
|
5077
|
+
current[parts[i]] = current[parts[i]] || {};
|
|
5078
|
+
current = current[parts[i]];
|
|
5079
|
+
}
|
|
5080
|
+
current[parts[parts.length - 1]] = val;
|
|
5081
|
+
} else {
|
|
5082
|
+
config[key] = val;
|
|
5083
|
+
}
|
|
5084
|
+
|
|
5085
|
+
if (writeGlobalConfig(config)) {
|
|
5086
|
+
ok(`Global config updated: "${key}" = ${val}`);
|
|
5087
|
+
}
|
|
5088
|
+
return;
|
|
5089
|
+
}
|
|
5090
|
+
|
|
5091
|
+
err('Usage:');
|
|
5092
|
+
log(' awkit config list');
|
|
5093
|
+
log(' awkit config get <key>');
|
|
5094
|
+
log(' awkit config set <key> <value>');
|
|
5095
|
+
log(' awkit config audio <on|off>');
|
|
5096
|
+
log(' awkit config claude <on|off>');
|
|
5097
|
+
log(' awkit config codex <on|off>');
|
|
5098
|
+
log(' awkit config qwen <on|off>');
|
|
5099
|
+
log(' awkit config runners');
|
|
5100
|
+
log(' awkit config models');
|
|
5101
|
+
}
|
|
5102
|
+
|
|
4491
5103
|
// ─── Main ────────────────────────────────────────────────────────────────────
|
|
4492
5104
|
|
|
4493
5105
|
const [, , command, ...args] = process.argv;
|
|
@@ -4498,6 +5110,15 @@ const [, , command, ...args] = process.argv;
|
|
|
4498
5110
|
case 'build':
|
|
4499
5111
|
cmdBuild();
|
|
4500
5112
|
break;
|
|
5113
|
+
case 'run':
|
|
5114
|
+
cmdRun(args);
|
|
5115
|
+
break;
|
|
5116
|
+
case 'task':
|
|
5117
|
+
cmdTask(args);
|
|
5118
|
+
break;
|
|
5119
|
+
case 'project':
|
|
5120
|
+
cmdProject(args);
|
|
5121
|
+
break;
|
|
4501
5122
|
case 'init':
|
|
4502
5123
|
await cmdInit(args.includes('--force'));
|
|
4503
5124
|
break;
|
|
@@ -4514,7 +5135,11 @@ const [, , command, ...args] = process.argv;
|
|
|
4514
5135
|
cmdSync();
|
|
4515
5136
|
break;
|
|
4516
5137
|
case 'status':
|
|
4517
|
-
|
|
5138
|
+
if (args[0] === 'gn' || args[0] === 'gitnexus') {
|
|
5139
|
+
cmdGitnexus(['status']);
|
|
5140
|
+
} else {
|
|
5141
|
+
cmdStatus();
|
|
5142
|
+
}
|
|
4518
5143
|
break;
|
|
4519
5144
|
case 'harvest':
|
|
4520
5145
|
cmdHarvest(args.includes('--dry-run'));
|
|
@@ -4562,6 +5187,16 @@ const [, , command, ...args] = process.argv;
|
|
|
4562
5187
|
case 'creds':
|
|
4563
5188
|
cmdCredentials(args);
|
|
4564
5189
|
break;
|
|
5190
|
+
case 'index':
|
|
5191
|
+
case 'analyze':
|
|
5192
|
+
cmdGitnexus(['index', ...args]);
|
|
5193
|
+
break;
|
|
5194
|
+
case 'clean':
|
|
5195
|
+
cmdGitnexus(['clean', ...args]);
|
|
5196
|
+
break;
|
|
5197
|
+
case 'list':
|
|
5198
|
+
cmdGitnexus(['list', ...args]);
|
|
5199
|
+
break;
|
|
4565
5200
|
case 'set-openrouter': {
|
|
4566
5201
|
const key = args[0];
|
|
4567
5202
|
if (!key) {
|
|
@@ -4603,11 +5238,34 @@ const [, , command, ...args] = process.argv;
|
|
|
4603
5238
|
case 'restart':
|
|
4604
5239
|
await cmdRestart();
|
|
4605
5240
|
break;
|
|
5241
|
+
case 'greet':
|
|
5242
|
+
cmdGreet(args);
|
|
5243
|
+
break;
|
|
5244
|
+
case 'goal':
|
|
5245
|
+
cmdGoal(args);
|
|
5246
|
+
break;
|
|
5247
|
+
case 'config-global':
|
|
5248
|
+
cmdGlobalConfig(args);
|
|
5249
|
+
break;
|
|
4606
5250
|
case 'identity':
|
|
4607
5251
|
case 'config':
|
|
4608
|
-
case 'project':
|
|
4609
|
-
|
|
5252
|
+
case 'project': {
|
|
5253
|
+
const isGlobalSub = command === 'config' && (
|
|
5254
|
+
args.length === 0 ||
|
|
5255
|
+
['audio', 'claude', 'codex', 'qwen', 'runners', 'runner', 'models', 'model', 'list', 'get', 'set'].includes(args[0])
|
|
5256
|
+
);
|
|
5257
|
+
if (isGlobalSub) {
|
|
5258
|
+
// If there are no arguments but a project identity exists, show project identity as default
|
|
5259
|
+
if (args.length === 0 && fs.existsSync(path.join(process.cwd(), '.project-identity'))) {
|
|
5260
|
+
cmdIdentity(args);
|
|
5261
|
+
} else {
|
|
5262
|
+
cmdGlobalConfig(args);
|
|
5263
|
+
}
|
|
5264
|
+
} else {
|
|
5265
|
+
cmdIdentity(args);
|
|
5266
|
+
}
|
|
4610
5267
|
break;
|
|
5268
|
+
}
|
|
4611
5269
|
case 'help':
|
|
4612
5270
|
case '--help':
|
|
4613
5271
|
case '-h':
|