@dzhechkov/harness-cli 0.3.198 → 0.3.200
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/LICENSE +21 -0
- package/README.md +51 -14
- package/dist/cli.d.ts.map +1 -1
- package/dist/cli.js +180 -18
- package/dist/cli.js.map +1 -1
- package/package.json +12 -12
- package/src/cli.ts +222 -24
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@dzhechkov/harness-cli",
|
|
3
|
-
"version": "0.3.
|
|
3
|
+
"version": "0.3.200",
|
|
4
4
|
"description": "The dz CLI — install AI skills for Claude Code, Codex, OpenCode, Hermes, OpenClaude, GitHub Copilot. 35 commands, 13 presets, 6 platform targets.",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"license": "MIT",
|
|
@@ -37,15 +37,7 @@
|
|
|
37
37
|
"src",
|
|
38
38
|
"README.md"
|
|
39
39
|
],
|
|
40
|
-
"scripts": {
|
|
41
|
-
"build": "tsc -p tsconfig.json",
|
|
42
|
-
"test": "vitest run",
|
|
43
|
-
"test:watch": "vitest",
|
|
44
|
-
"typecheck": "tsc -p tsconfig.json --noEmit",
|
|
45
|
-
"lint": "tsc -p tsconfig.json --noEmit"
|
|
46
|
-
},
|
|
47
40
|
"dependencies": {
|
|
48
|
-
"@dzhechkov/harness-core": "workspace:*",
|
|
49
41
|
"@dzhechkov/harness-presets": "^0.5.0",
|
|
50
42
|
"@dzhechkov/scout": "^0.8.0",
|
|
51
43
|
"@dzhechkov/skills-devops": "^0.3.0",
|
|
@@ -61,7 +53,8 @@
|
|
|
61
53
|
"@dzhechkov/skills-idea2prd": "^0.1.0",
|
|
62
54
|
"@dzhechkov/skills-reverse-engineering": "^0.1.0",
|
|
63
55
|
"@dzhechkov/skills-presentation-storyteller": "^0.1.0",
|
|
64
|
-
"@dzhechkov/skills-website-cloner": "^0.1.0"
|
|
56
|
+
"@dzhechkov/skills-website-cloner": "^0.1.0",
|
|
57
|
+
"@dzhechkov/harness-core": "0.3.100"
|
|
65
58
|
},
|
|
66
59
|
"devDependencies": {
|
|
67
60
|
"@types/node": "^25.6.0",
|
|
@@ -79,5 +72,12 @@
|
|
|
79
72
|
"url": "https://github.com/djd1m/dz-harness-hub.git",
|
|
80
73
|
"directory": "packages/@dzhechkov/harness-cli"
|
|
81
74
|
},
|
|
82
|
-
"homepage": "https://github.com/djd1m/dz-harness-hub/tree/main/packages/@dzhechkov/harness-cli#readme"
|
|
83
|
-
|
|
75
|
+
"homepage": "https://github.com/djd1m/dz-harness-hub/tree/main/packages/@dzhechkov/harness-cli#readme",
|
|
76
|
+
"scripts": {
|
|
77
|
+
"build": "tsc -p tsconfig.json",
|
|
78
|
+
"test": "vitest run",
|
|
79
|
+
"test:watch": "vitest",
|
|
80
|
+
"typecheck": "tsc -p tsconfig.json --noEmit",
|
|
81
|
+
"lint": "tsc -p tsconfig.json --noEmit"
|
|
82
|
+
}
|
|
83
|
+
}
|
package/src/cli.ts
CHANGED
|
@@ -67,6 +67,8 @@ import {
|
|
|
67
67
|
statuslineData,
|
|
68
68
|
writeFeatureAdrState,
|
|
69
69
|
computeUsage,
|
|
70
|
+
deriveUsageCalibration,
|
|
71
|
+
normalizeClaudeUsageModelKey,
|
|
70
72
|
readUsageLimits,
|
|
71
73
|
queryBookKnowledge,
|
|
72
74
|
loadStorePatternsSync,
|
|
@@ -84,7 +86,7 @@ import {
|
|
|
84
86
|
importBrainSlice,
|
|
85
87
|
registerKusToBrain,
|
|
86
88
|
} from '@dzhechkov/harness-core';
|
|
87
|
-
import type { PatternRecord, TargetName, BookKU, HarmonizeReport } from '@dzhechkov/harness-core';
|
|
89
|
+
import type { ClaudeUsageModel, PatternRecord, TargetName, BookKU, HarmonizeReport, UsageCalibrationPlan } from '@dzhechkov/harness-core';
|
|
88
90
|
import { getPreset, PRESET_NAMES } from '@dzhechkov/harness-presets';
|
|
89
91
|
import { scanGitHub, analyzeRepo, generateReport, deepAnalyze, scanAllSources, ScoutMemory } from '@dzhechkov/scout';
|
|
90
92
|
|
|
@@ -127,7 +129,7 @@ Usage:
|
|
|
127
129
|
dz brain init [--project <dir>] [--k <N>] (wire the grounding hook into .claude/settings.json — opt-in)
|
|
128
130
|
dz statusline [--json] [--install] [--project <dir>] (live self-learning panel for Claude Code's status bar; reads the CC JSON payload from STDIN)
|
|
129
131
|
dz statusline --fa-record --slug <s> --step "<label>" [--recalled <n>] [--stored <n>] [--mode <m>] (feature-adr: record live per-run learning state → 📐 panel segment)
|
|
130
|
-
dz usage [--json] [--project <dir>]
|
|
132
|
+
dz usage [--json] [--project <dir>] | dz usage --calibrate --session <pct> --weekly <pct> [--model fable=<pct>] [--project <dir>] (ESTIMATE Claude usage from fixed reset windows; optional per-model weekly binding; exit 0 ALWAYS; pct=null when limits unconfigured)
|
|
131
133
|
dz pretrain [--project <dir>]
|
|
132
134
|
dz recommend "<task description>"
|
|
133
135
|
dz compose <preset1+preset2+...> [--target <name>]
|
|
@@ -170,12 +172,14 @@ export interface CliIo {
|
|
|
170
172
|
interface ParsedArgs {
|
|
171
173
|
readonly command: string;
|
|
172
174
|
readonly options: Map<string, string>;
|
|
175
|
+
readonly optionLists: Map<string, string[]>;
|
|
173
176
|
readonly flags: Set<string>;
|
|
174
177
|
}
|
|
175
178
|
|
|
176
179
|
/** Parse `<command> [--key value] [--flag]` argv. */
|
|
177
180
|
function parseArgs(argv: string[]): ParsedArgs {
|
|
178
181
|
const options = new Map<string, string>();
|
|
182
|
+
const optionLists = new Map<string, string[]>();
|
|
179
183
|
const flags = new Set<string>();
|
|
180
184
|
const positional: string[] = [];
|
|
181
185
|
|
|
@@ -186,6 +190,9 @@ function parseArgs(argv: string[]): ParsedArgs {
|
|
|
186
190
|
const next = argv[index + 1];
|
|
187
191
|
if (next !== undefined && !next.startsWith('--')) {
|
|
188
192
|
options.set(key, next);
|
|
193
|
+
const list = optionLists.get(key) ?? [];
|
|
194
|
+
list.push(next);
|
|
195
|
+
optionLists.set(key, list);
|
|
189
196
|
index += 1;
|
|
190
197
|
} else {
|
|
191
198
|
flags.add(key);
|
|
@@ -200,7 +207,7 @@ function parseArgs(argv: string[]): ParsedArgs {
|
|
|
200
207
|
options.set(`_positional_${pi - 1}`, positional[pi] ?? '');
|
|
201
208
|
}
|
|
202
209
|
|
|
203
|
-
return { command: positional[0] ?? '', options, flags };
|
|
210
|
+
return { command: positional[0] ?? '', options, optionLists, flags };
|
|
204
211
|
}
|
|
205
212
|
|
|
206
213
|
type Write = (line: string) => void;
|
|
@@ -1112,18 +1119,187 @@ function cmdStatusline(
|
|
|
1112
1119
|
}
|
|
1113
1120
|
}
|
|
1114
1121
|
|
|
1122
|
+
function isJsonRecord(value: unknown): value is Record<string, unknown> {
|
|
1123
|
+
return typeof value === 'object' && value !== null && !Array.isArray(value);
|
|
1124
|
+
}
|
|
1125
|
+
|
|
1126
|
+
function usageConfigPath(projectRoot: string): string {
|
|
1127
|
+
return join(projectRoot, '.dz', 'config.json');
|
|
1128
|
+
}
|
|
1129
|
+
|
|
1130
|
+
function readProjectConfigForUsage(projectRoot: string): { config: Record<string, unknown>; warning?: string } {
|
|
1131
|
+
const path = usageConfigPath(projectRoot);
|
|
1132
|
+
try {
|
|
1133
|
+
if (!existsSync(path)) return { config: {} };
|
|
1134
|
+
const parsed = JSON.parse(readFileSync(path, 'utf-8')) as unknown;
|
|
1135
|
+
if (isJsonRecord(parsed)) return { config: parsed };
|
|
1136
|
+
return { config: {}, warning: 'existing config is not a JSON object; writing a minimal config' };
|
|
1137
|
+
} catch {
|
|
1138
|
+
return { config: {}, warning: 'existing config could not be parsed; writing a minimal config' };
|
|
1139
|
+
}
|
|
1140
|
+
}
|
|
1141
|
+
|
|
1142
|
+
function applyUsageCalibrationToConfig(config: Record<string, unknown>, plan: UsageCalibrationPlan): Record<string, unknown> {
|
|
1143
|
+
const next: Record<string, unknown> = { ...config };
|
|
1144
|
+
const memory = isJsonRecord(next['memory']) ? { ...next['memory'] } : {};
|
|
1145
|
+
const usage = isJsonRecord(memory['usage']) ? { ...memory['usage'] } : {};
|
|
1146
|
+
|
|
1147
|
+
for (const change of plan.changes) {
|
|
1148
|
+
if (change.key === 'session') {
|
|
1149
|
+
usage['sessionTokenLimit'] = change.after;
|
|
1150
|
+
} else if (change.key === 'weekly') {
|
|
1151
|
+
usage['weeklyTokenLimit'] = change.after;
|
|
1152
|
+
} else {
|
|
1153
|
+
const model = normalizeClaudeUsageModelKey(change.key);
|
|
1154
|
+
if (model) {
|
|
1155
|
+
const existingByModel = isJsonRecord(usage['weeklyTokenLimitByModel']) ? { ...usage['weeklyTokenLimitByModel'] } : {};
|
|
1156
|
+
existingByModel[model] = change.after;
|
|
1157
|
+
usage['weeklyTokenLimitByModel'] = existingByModel;
|
|
1158
|
+
}
|
|
1159
|
+
}
|
|
1160
|
+
}
|
|
1161
|
+
|
|
1162
|
+
if (plan.changes.length > 0) {
|
|
1163
|
+
usage['calibratedAt'] = plan.after.calibratedAt;
|
|
1164
|
+
usage['source'] = plan.after.source;
|
|
1165
|
+
}
|
|
1166
|
+
|
|
1167
|
+
memory['usage'] = usage;
|
|
1168
|
+
next['memory'] = memory;
|
|
1169
|
+
return next;
|
|
1170
|
+
}
|
|
1171
|
+
|
|
1172
|
+
function parseUsageModelArgs(modelArgs: readonly string[]): { modelPct: Record<string, unknown>; skipped: string[] } {
|
|
1173
|
+
const modelPct: Record<string, unknown> = {};
|
|
1174
|
+
const skipped: string[] = [];
|
|
1175
|
+
for (const raw of modelArgs) {
|
|
1176
|
+
const eq = raw.indexOf('=');
|
|
1177
|
+
if (eq <= 0 || eq === raw.length - 1) {
|
|
1178
|
+
skipped.push(`model ${raw}: skipped malformed model=pct argument`);
|
|
1179
|
+
continue;
|
|
1180
|
+
}
|
|
1181
|
+
const modelName = raw.slice(0, eq).trim();
|
|
1182
|
+
const model = normalizeClaudeUsageModelKey(modelName);
|
|
1183
|
+
if (!model) {
|
|
1184
|
+
skipped.push(`model ${modelName}: skipped unknown model`);
|
|
1185
|
+
continue;
|
|
1186
|
+
}
|
|
1187
|
+
modelPct[model] = raw.slice(eq + 1).trim();
|
|
1188
|
+
}
|
|
1189
|
+
return { modelPct, skipped };
|
|
1190
|
+
}
|
|
1191
|
+
|
|
1192
|
+
function writeUsageCalibrationSummary(opts: {
|
|
1193
|
+
projectRoot: string;
|
|
1194
|
+
plan: UsageCalibrationPlan;
|
|
1195
|
+
preSkipped: readonly string[];
|
|
1196
|
+
configWarning?: string | undefined;
|
|
1197
|
+
wrote: boolean;
|
|
1198
|
+
write: Write;
|
|
1199
|
+
}): void {
|
|
1200
|
+
opts.write('usage calibrate: estimated local transcript counts; claude.ai/settings/usage is authoritative');
|
|
1201
|
+
opts.write(`usage calibrate: project ${opts.projectRoot}`);
|
|
1202
|
+
if (opts.configWarning) opts.write(`usage calibrate: ${opts.configWarning}`);
|
|
1203
|
+
for (const change of opts.plan.changes) {
|
|
1204
|
+
opts.write(
|
|
1205
|
+
`usage calibrate: ${change.key} tokens=${change.tokens} pct=${change.pct}% limit ${change.before ?? 'null'} -> ${change.after}`,
|
|
1206
|
+
);
|
|
1207
|
+
}
|
|
1208
|
+
const skipped = [...opts.preSkipped, ...opts.plan.skipped];
|
|
1209
|
+
for (const item of skipped) opts.write(`usage calibrate: skipped ${item}`);
|
|
1210
|
+
if (opts.wrote) {
|
|
1211
|
+
opts.write('usage calibrate: wrote .dz/config.json with source claude.ai/settings/usage');
|
|
1212
|
+
} else {
|
|
1213
|
+
opts.write('usage calibrate: no config changes written');
|
|
1214
|
+
}
|
|
1215
|
+
}
|
|
1216
|
+
|
|
1217
|
+
function cmdUsageCalibrate(
|
|
1218
|
+
options: Map<string, string>,
|
|
1219
|
+
optionLists: Map<string, string[]>,
|
|
1220
|
+
cwd: string,
|
|
1221
|
+
write: Write,
|
|
1222
|
+
): number {
|
|
1223
|
+
const projectRoot = resolve(cwd, options.get('project') ?? '.');
|
|
1224
|
+
const suppliedModels = optionLists.get('model') ?? [];
|
|
1225
|
+
const parsedModels = parseUsageModelArgs(suppliedModels);
|
|
1226
|
+
const modelPct = parsedModels.modelPct;
|
|
1227
|
+
const hasModelPct = Object.keys(modelPct).length > 0;
|
|
1228
|
+
const input = {
|
|
1229
|
+
...(options.has('session') ? { sessionPct: options.get('session') } : {}),
|
|
1230
|
+
...(options.has('weekly') ? { weeklyPct: options.get('weekly') } : {}),
|
|
1231
|
+
...(hasModelPct ? { modelPct } : {}),
|
|
1232
|
+
calibratedAt: new Date().toISOString(),
|
|
1233
|
+
source: 'claude.ai/settings/usage' as const,
|
|
1234
|
+
};
|
|
1235
|
+
const missingInputs: string[] = [];
|
|
1236
|
+
if (!options.has('session') && !options.has('weekly') && !hasModelPct) {
|
|
1237
|
+
missingInputs.push('no calibration percentages supplied');
|
|
1238
|
+
}
|
|
1239
|
+
|
|
1240
|
+
try {
|
|
1241
|
+
const current = computeUsage(projectRoot);
|
|
1242
|
+
const before = readUsageLimits(projectRoot);
|
|
1243
|
+
const plan = deriveUsageCalibration(current, before, input);
|
|
1244
|
+
if (plan.changes.length === 0) {
|
|
1245
|
+
writeUsageCalibrationSummary({
|
|
1246
|
+
projectRoot,
|
|
1247
|
+
plan,
|
|
1248
|
+
preSkipped: [...parsedModels.skipped, ...missingInputs],
|
|
1249
|
+
wrote: false,
|
|
1250
|
+
write,
|
|
1251
|
+
});
|
|
1252
|
+
return 0;
|
|
1253
|
+
}
|
|
1254
|
+
|
|
1255
|
+
const existing = readProjectConfigForUsage(projectRoot);
|
|
1256
|
+
const nextConfig = applyUsageCalibrationToConfig(existing.config, plan);
|
|
1257
|
+
try {
|
|
1258
|
+
mkdirSync(join(projectRoot, '.dz'), { recursive: true });
|
|
1259
|
+
writeFileSync(usageConfigPath(projectRoot), JSON.stringify(nextConfig, null, 2) + '\n');
|
|
1260
|
+
writeUsageCalibrationSummary({
|
|
1261
|
+
projectRoot,
|
|
1262
|
+
plan,
|
|
1263
|
+
preSkipped: [...parsedModels.skipped, ...missingInputs],
|
|
1264
|
+
configWarning: existing.warning,
|
|
1265
|
+
wrote: true,
|
|
1266
|
+
write,
|
|
1267
|
+
});
|
|
1268
|
+
} catch {
|
|
1269
|
+
writeUsageCalibrationSummary({
|
|
1270
|
+
projectRoot,
|
|
1271
|
+
plan,
|
|
1272
|
+
preSkipped: [...parsedModels.skipped, ...missingInputs, 'write failed'],
|
|
1273
|
+
configWarning: existing.warning,
|
|
1274
|
+
wrote: false,
|
|
1275
|
+
write,
|
|
1276
|
+
});
|
|
1277
|
+
}
|
|
1278
|
+
return 0;
|
|
1279
|
+
} catch {
|
|
1280
|
+
write('usage calibrate: skipped internal error; no config changes written');
|
|
1281
|
+
return 0;
|
|
1282
|
+
}
|
|
1283
|
+
}
|
|
1284
|
+
|
|
1115
1285
|
/**
|
|
1116
|
-
* `dz usage` — print an ESTIMATE of Claude session
|
|
1117
|
-
*
|
|
1118
|
-
*
|
|
1119
|
-
*
|
|
1286
|
+
* `dz usage` — print an ESTIMATE of Claude session + weekly usage from fixed reset windows,
|
|
1287
|
+
* aggregated READONLY from the local transcript store (see {@link computeUsage}). `--json` emits
|
|
1288
|
+
* the single-line contract the feature-adr usage-probe agent parses; `--calibrate` is the only
|
|
1289
|
+
* write path and records human-transcribed claude.ai percentages in `.dz/config.json`.
|
|
1120
1290
|
*
|
|
1121
1291
|
* **Exit code is 0 ALWAYS** — including on internal error the whole body is guarded and prints the
|
|
1122
1292
|
* all-null JSON, so a probe can NEVER distinguish "usage unknown" from "command failed" via a
|
|
1123
|
-
* non-zero exit
|
|
1124
|
-
*
|
|
1293
|
+
* non-zero exit. `--project <dir>` scopes ONLY the `.dz/config.json` read/write; measurement is
|
|
1294
|
+
* account-wide (all projects).
|
|
1125
1295
|
*/
|
|
1126
|
-
function cmdUsage(
|
|
1296
|
+
function cmdUsage(
|
|
1297
|
+
options: Map<string, string>,
|
|
1298
|
+
optionLists: Map<string, string[]>,
|
|
1299
|
+
flags: Set<string>,
|
|
1300
|
+
cwd: string,
|
|
1301
|
+
write: Write,
|
|
1302
|
+
): number {
|
|
1127
1303
|
const projectRoot = resolve(cwd, options.get('project') ?? '.');
|
|
1128
1304
|
const nullContract = () =>
|
|
1129
1305
|
JSON.stringify({
|
|
@@ -1136,19 +1312,40 @@ function cmdUsage(options: Map<string, string>, flags: Set<string>, cwd: string,
|
|
|
1136
1312
|
estimated: true,
|
|
1137
1313
|
});
|
|
1138
1314
|
try {
|
|
1315
|
+
if (flags.has('calibrate')) return cmdUsageCalibrate(options, optionLists, cwd, write);
|
|
1316
|
+
|
|
1139
1317
|
const u = computeUsage(projectRoot);
|
|
1140
1318
|
const lim = readUsageLimits(projectRoot);
|
|
1319
|
+
const modelLimits = lim.weeklyTokenLimitByModel;
|
|
1320
|
+
const hasModelLimits = modelLimits !== undefined && Object.keys(modelLimits).length > 0;
|
|
1141
1321
|
if (flags.has('json')) {
|
|
1322
|
+
const limitsPayload: {
|
|
1323
|
+
session: number | null;
|
|
1324
|
+
weekly: number | null;
|
|
1325
|
+
weeklyByModel?: Partial<Record<ClaudeUsageModel, number>>;
|
|
1326
|
+
} = { session: lim.sessionTokenLimit ?? null, weekly: lim.weeklyTokenLimit ?? null };
|
|
1327
|
+
if (hasModelLimits) limitsPayload.weeklyByModel = { ...modelLimits };
|
|
1328
|
+
const payload: {
|
|
1329
|
+
sessionPct: number | null;
|
|
1330
|
+
weeklyPct: number | null;
|
|
1331
|
+
sessionTokens: number;
|
|
1332
|
+
weeklyTokens: number;
|
|
1333
|
+
resetsAt: { session: string | null; weekly: string | null };
|
|
1334
|
+
limits: typeof limitsPayload;
|
|
1335
|
+
weeklyByModel?: typeof u.weeklyByModel;
|
|
1336
|
+
estimated: true;
|
|
1337
|
+
} = {
|
|
1338
|
+
sessionPct: u.sessionPct,
|
|
1339
|
+
weeklyPct: u.weeklyPct,
|
|
1340
|
+
sessionTokens: u.sessionTokens,
|
|
1341
|
+
weeklyTokens: u.weeklyTokens,
|
|
1342
|
+
resetsAt: { session: u.sessionResetsAt, weekly: u.weeklyResetsAt },
|
|
1343
|
+
limits: limitsPayload,
|
|
1344
|
+
estimated: true,
|
|
1345
|
+
};
|
|
1346
|
+
if (hasModelLimits && u.weeklyByModel !== undefined) payload.weeklyByModel = u.weeklyByModel;
|
|
1142
1347
|
write(
|
|
1143
|
-
JSON.stringify(
|
|
1144
|
-
sessionPct: u.sessionPct,
|
|
1145
|
-
weeklyPct: u.weeklyPct,
|
|
1146
|
-
sessionTokens: u.sessionTokens,
|
|
1147
|
-
weeklyTokens: u.weeklyTokens,
|
|
1148
|
-
resetsAt: { session: u.sessionResetsAt, weekly: u.weeklyResetsAt },
|
|
1149
|
-
limits: { session: lim.sessionTokenLimit ?? null, weekly: lim.weeklyTokenLimit ?? null },
|
|
1150
|
-
estimated: true,
|
|
1151
|
-
}),
|
|
1348
|
+
JSON.stringify(payload),
|
|
1152
1349
|
);
|
|
1153
1350
|
return 0;
|
|
1154
1351
|
}
|
|
@@ -1168,7 +1365,8 @@ function cmdUsage(options: Map<string, string>, flags: Set<string>, cwd: string,
|
|
|
1168
1365
|
}
|
|
1169
1366
|
};
|
|
1170
1367
|
const s = u.sessionPct === null ? 'n/a' : '~' + u.sessionPct + '%';
|
|
1171
|
-
const
|
|
1368
|
+
const binding = hasModelLimits && u.weeklyBindingModel !== undefined ? ' ' + u.weeklyBindingModel + '-bound' : '';
|
|
1369
|
+
const w = u.weeklyPct === null ? 'n/a' : '~' + u.weeklyPct + '%' + binding;
|
|
1172
1370
|
write('usage: session ' + s + ' (resets ' + clock(u.sessionResetsAt) + ') · week ' + w + ' (resets ' + clock(u.weeklyResetsAt) + ') · estimated');
|
|
1173
1371
|
return 0;
|
|
1174
1372
|
} catch {
|
|
@@ -1180,7 +1378,7 @@ function cmdUsage(options: Map<string, string>, flags: Set<string>, cwd: string,
|
|
|
1180
1378
|
}
|
|
1181
1379
|
|
|
1182
1380
|
async function cmdTeach(options: Map<string, string>, flags: Set<string>, cwd: string, write: Write): Promise<number> {
|
|
1183
|
-
const projectRoot = options.get('project') ??
|
|
1381
|
+
const projectRoot = resolve(cwd, options.get('project') ?? '.');
|
|
1184
1382
|
|
|
1185
1383
|
// Vector tier (dz-rvf-vector-bridge FR-1): best-effort mirror AFTER the lexical write is
|
|
1186
1384
|
// durable (I-3). Auto-gated on the agentdb memory backend / an explicit vector-engine config
|
|
@@ -3461,7 +3659,7 @@ export async function runCli(argv: string[], io: CliIo = {}): Promise<number> {
|
|
|
3461
3659
|
return '';
|
|
3462
3660
|
}
|
|
3463
3661
|
};
|
|
3464
|
-
const { command, options, flags } = parseArgs(argv);
|
|
3662
|
+
const { command, options, optionLists, flags } = parseArgs(argv);
|
|
3465
3663
|
|
|
3466
3664
|
if (command === '' || command === 'help' || flags.has('help')) {
|
|
3467
3665
|
write(USAGE);
|
|
@@ -3482,7 +3680,7 @@ export async function runCli(argv: string[], io: CliIo = {}): Promise<number> {
|
|
|
3482
3680
|
case 'create-skill':
|
|
3483
3681
|
return cmdCreateSkill(options, flags, cwd, write);
|
|
3484
3682
|
case 'info':
|
|
3485
|
-
return cmdInfo(options, { command, options, flags }, cwd, write);
|
|
3683
|
+
return cmdInfo(options, { command, options, optionLists, flags }, cwd, write);
|
|
3486
3684
|
case 'scout':
|
|
3487
3685
|
return await cmdScout(options, flags, cwd, write);
|
|
3488
3686
|
case 'workflow':
|
|
@@ -3508,7 +3706,7 @@ export async function runCli(argv: string[], io: CliIo = {}): Promise<number> {
|
|
|
3508
3706
|
case 'statusline':
|
|
3509
3707
|
return cmdStatusline(options, flags, cwd, write, readStdin);
|
|
3510
3708
|
case 'usage':
|
|
3511
|
-
return cmdUsage(options, flags, cwd, write);
|
|
3709
|
+
return cmdUsage(options, optionLists, flags, cwd, write);
|
|
3512
3710
|
case 'setup':
|
|
3513
3711
|
return await cmdSetup(options, flags, cwd, write);
|
|
3514
3712
|
case 'pretrain':
|