qodewk 0.10.1 → 0.11.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.cjs +492 -263
- package/package.json +1 -1
package/dist/index.cjs
CHANGED
|
@@ -1157,7 +1157,7 @@ var require_command = __commonJS({
|
|
|
1157
1157
|
"use strict";
|
|
1158
1158
|
var EventEmitter2 = require("events").EventEmitter;
|
|
1159
1159
|
var childProcess = require("child_process");
|
|
1160
|
-
var
|
|
1160
|
+
var path18 = require("path");
|
|
1161
1161
|
var fs16 = require("fs");
|
|
1162
1162
|
var process3 = require("process");
|
|
1163
1163
|
var { Argument: Argument2, humanReadableArgName } = require_argument();
|
|
@@ -2157,9 +2157,9 @@ Expecting one of '${allowedValues.join("', '")}'`);
|
|
|
2157
2157
|
let launchWithNode = false;
|
|
2158
2158
|
const sourceExt = [".js", ".ts", ".tsx", ".mjs", ".cjs"];
|
|
2159
2159
|
function findFile(baseDir, baseName) {
|
|
2160
|
-
const localBin =
|
|
2160
|
+
const localBin = path18.resolve(baseDir, baseName);
|
|
2161
2161
|
if (fs16.existsSync(localBin)) return localBin;
|
|
2162
|
-
if (sourceExt.includes(
|
|
2162
|
+
if (sourceExt.includes(path18.extname(baseName))) return void 0;
|
|
2163
2163
|
const foundExt = sourceExt.find(
|
|
2164
2164
|
(ext) => fs16.existsSync(`${localBin}${ext}`)
|
|
2165
2165
|
);
|
|
@@ -2177,17 +2177,17 @@ Expecting one of '${allowedValues.join("', '")}'`);
|
|
|
2177
2177
|
} catch {
|
|
2178
2178
|
resolvedScriptPath = this._scriptPath;
|
|
2179
2179
|
}
|
|
2180
|
-
executableDir =
|
|
2181
|
-
|
|
2180
|
+
executableDir = path18.resolve(
|
|
2181
|
+
path18.dirname(resolvedScriptPath),
|
|
2182
2182
|
executableDir
|
|
2183
2183
|
);
|
|
2184
2184
|
}
|
|
2185
2185
|
if (executableDir) {
|
|
2186
2186
|
let localFile = findFile(executableDir, executableFile);
|
|
2187
2187
|
if (!localFile && !subcommand._executableFile && this._scriptPath) {
|
|
2188
|
-
const legacyName =
|
|
2188
|
+
const legacyName = path18.basename(
|
|
2189
2189
|
this._scriptPath,
|
|
2190
|
-
|
|
2190
|
+
path18.extname(this._scriptPath)
|
|
2191
2191
|
);
|
|
2192
2192
|
if (legacyName !== this._name) {
|
|
2193
2193
|
localFile = findFile(
|
|
@@ -2198,7 +2198,7 @@ Expecting one of '${allowedValues.join("', '")}'`);
|
|
|
2198
2198
|
}
|
|
2199
2199
|
executableFile = localFile || executableFile;
|
|
2200
2200
|
}
|
|
2201
|
-
launchWithNode = sourceExt.includes(
|
|
2201
|
+
launchWithNode = sourceExt.includes(path18.extname(executableFile));
|
|
2202
2202
|
let proc;
|
|
2203
2203
|
if (process3.platform !== "win32") {
|
|
2204
2204
|
if (launchWithNode) {
|
|
@@ -3045,7 +3045,7 @@ Expecting one of '${allowedValues.join("', '")}'`);
|
|
|
3045
3045
|
* @return {Command}
|
|
3046
3046
|
*/
|
|
3047
3047
|
nameFromFilename(filename) {
|
|
3048
|
-
this._name =
|
|
3048
|
+
this._name = path18.basename(filename, path18.extname(filename));
|
|
3049
3049
|
return this;
|
|
3050
3050
|
}
|
|
3051
3051
|
/**
|
|
@@ -3059,9 +3059,9 @@ Expecting one of '${allowedValues.join("', '")}'`);
|
|
|
3059
3059
|
* @param {string} [path]
|
|
3060
3060
|
* @return {(string|null|Command)}
|
|
3061
3061
|
*/
|
|
3062
|
-
executableDir(
|
|
3063
|
-
if (
|
|
3064
|
-
this._executableDir =
|
|
3062
|
+
executableDir(path19) {
|
|
3063
|
+
if (path19 === void 0) return this._executableDir;
|
|
3064
|
+
this._executableDir = path19;
|
|
3065
3065
|
return this;
|
|
3066
3066
|
}
|
|
3067
3067
|
/**
|
|
@@ -4207,10 +4207,10 @@ var require_src2 = __commonJS({
|
|
|
4207
4207
|
var fs_1 = require("fs");
|
|
4208
4208
|
var debug_1 = __importDefault(require_src());
|
|
4209
4209
|
var log = debug_1.default("@kwsites/file-exists");
|
|
4210
|
-
function check(
|
|
4211
|
-
log(`checking %s`,
|
|
4210
|
+
function check(path18, isFile, isDirectory) {
|
|
4211
|
+
log(`checking %s`, path18);
|
|
4212
4212
|
try {
|
|
4213
|
-
const stat = fs_1.statSync(
|
|
4213
|
+
const stat = fs_1.statSync(path18);
|
|
4214
4214
|
if (stat.isFile() && isFile) {
|
|
4215
4215
|
log(`[OK] path represents a file`);
|
|
4216
4216
|
return true;
|
|
@@ -4230,8 +4230,8 @@ var require_src2 = __commonJS({
|
|
|
4230
4230
|
throw e;
|
|
4231
4231
|
}
|
|
4232
4232
|
}
|
|
4233
|
-
function exists2(
|
|
4234
|
-
return check(
|
|
4233
|
+
function exists2(path18, type = exports2.READABLE) {
|
|
4234
|
+
return check(path18, (type & exports2.FILE) > 0, (type & exports2.FOLDER) > 0);
|
|
4235
4235
|
}
|
|
4236
4236
|
exports2.exists = exists2;
|
|
4237
4237
|
exports2.FILE = 1;
|
|
@@ -4842,8 +4842,8 @@ function toLinesWithContent(input = "", trimmed2 = true, separator = "\n") {
|
|
|
4842
4842
|
function forEachLineWithContent(input, callback) {
|
|
4843
4843
|
return toLinesWithContent(input, true).map((line) => callback(line));
|
|
4844
4844
|
}
|
|
4845
|
-
function folderExists(
|
|
4846
|
-
return (0, import_file_exists.exists)(
|
|
4845
|
+
function folderExists(path18) {
|
|
4846
|
+
return (0, import_file_exists.exists)(path18, import_file_exists.FOLDER);
|
|
4847
4847
|
}
|
|
4848
4848
|
function append(target, item) {
|
|
4849
4849
|
if (Array.isArray(target)) {
|
|
@@ -5034,8 +5034,8 @@ function checkIsRepoRootTask() {
|
|
|
5034
5034
|
commands,
|
|
5035
5035
|
format: "utf-8",
|
|
5036
5036
|
onError,
|
|
5037
|
-
parser(
|
|
5038
|
-
return /^\.(git)?$/.test(
|
|
5037
|
+
parser(path18) {
|
|
5038
|
+
return /^\.(git)?$/.test(path18.trim());
|
|
5039
5039
|
}
|
|
5040
5040
|
};
|
|
5041
5041
|
}
|
|
@@ -5291,11 +5291,11 @@ function parseGrep(grep) {
|
|
|
5291
5291
|
const paths = /* @__PURE__ */ new Set();
|
|
5292
5292
|
const results = {};
|
|
5293
5293
|
forEachLineWithContent(grep, (input) => {
|
|
5294
|
-
const [
|
|
5295
|
-
paths.add(
|
|
5296
|
-
(results[
|
|
5294
|
+
const [path18, line, preview] = input.split(NULL);
|
|
5295
|
+
paths.add(path18);
|
|
5296
|
+
(results[path18] = results[path18] || []).push({
|
|
5297
5297
|
line: asNumber(line),
|
|
5298
|
-
path:
|
|
5298
|
+
path: path18,
|
|
5299
5299
|
preview
|
|
5300
5300
|
});
|
|
5301
5301
|
});
|
|
@@ -5592,14 +5592,14 @@ function hashObjectTask(filePath, write) {
|
|
|
5592
5592
|
}
|
|
5593
5593
|
return straightThroughStringTask(commands, true);
|
|
5594
5594
|
}
|
|
5595
|
-
function parseInit(bare,
|
|
5595
|
+
function parseInit(bare, path18, text) {
|
|
5596
5596
|
const response = String(text).trim();
|
|
5597
5597
|
let result;
|
|
5598
5598
|
if (result = initResponseRegex.exec(response)) {
|
|
5599
|
-
return new InitSummary(bare,
|
|
5599
|
+
return new InitSummary(bare, path18, false, result[1]);
|
|
5600
5600
|
}
|
|
5601
5601
|
if (result = reInitResponseRegex.exec(response)) {
|
|
5602
|
-
return new InitSummary(bare,
|
|
5602
|
+
return new InitSummary(bare, path18, true, result[1]);
|
|
5603
5603
|
}
|
|
5604
5604
|
let gitDir = "";
|
|
5605
5605
|
const tokens = response.split(" ");
|
|
@@ -5610,12 +5610,12 @@ function parseInit(bare, path17, text) {
|
|
|
5610
5610
|
break;
|
|
5611
5611
|
}
|
|
5612
5612
|
}
|
|
5613
|
-
return new InitSummary(bare,
|
|
5613
|
+
return new InitSummary(bare, path18, /^re/i.test(response), gitDir);
|
|
5614
5614
|
}
|
|
5615
5615
|
function hasBareCommand(command) {
|
|
5616
5616
|
return command.includes(bareCommand);
|
|
5617
5617
|
}
|
|
5618
|
-
function initTask(bare = false,
|
|
5618
|
+
function initTask(bare = false, path18, customArgs) {
|
|
5619
5619
|
const commands = ["init", ...customArgs];
|
|
5620
5620
|
if (bare && !hasBareCommand(commands)) {
|
|
5621
5621
|
commands.splice(1, 0, bareCommand);
|
|
@@ -5624,7 +5624,7 @@ function initTask(bare = false, path17, customArgs) {
|
|
|
5624
5624
|
commands,
|
|
5625
5625
|
format: "utf-8",
|
|
5626
5626
|
parser(text) {
|
|
5627
|
-
return parseInit(commands.includes("--bare"),
|
|
5627
|
+
return parseInit(commands.includes("--bare"), path18, text);
|
|
5628
5628
|
}
|
|
5629
5629
|
};
|
|
5630
5630
|
}
|
|
@@ -5903,14 +5903,14 @@ function splitLine(result, lineStr) {
|
|
|
5903
5903
|
default:
|
|
5904
5904
|
return;
|
|
5905
5905
|
}
|
|
5906
|
-
function data(index, workingDir,
|
|
5906
|
+
function data(index, workingDir, path18) {
|
|
5907
5907
|
const raw = `${index}${workingDir}`;
|
|
5908
5908
|
const handler = parsers6.get(raw);
|
|
5909
5909
|
if (handler) {
|
|
5910
|
-
handler(result,
|
|
5910
|
+
handler(result, path18);
|
|
5911
5911
|
}
|
|
5912
5912
|
if (raw !== "##" && raw !== "!!") {
|
|
5913
|
-
result.files.push(new FileStatusSummary(
|
|
5913
|
+
result.files.push(new FileStatusSummary(path18, index, workingDir));
|
|
5914
5914
|
}
|
|
5915
5915
|
}
|
|
5916
5916
|
}
|
|
@@ -6097,8 +6097,8 @@ function deleteBranchTask(branch, forceDelete = false) {
|
|
|
6097
6097
|
return task;
|
|
6098
6098
|
}
|
|
6099
6099
|
function toPath(input) {
|
|
6100
|
-
const
|
|
6101
|
-
return
|
|
6100
|
+
const path18 = input.trim().replace(/^["']|["']$/g, "");
|
|
6101
|
+
return path18 && (0, import_node_path.normalize)(path18);
|
|
6102
6102
|
}
|
|
6103
6103
|
function checkIgnoreTask(paths) {
|
|
6104
6104
|
return {
|
|
@@ -6237,8 +6237,8 @@ function stashListTask(opt = {}, customArgs) {
|
|
|
6237
6237
|
parser: parser4
|
|
6238
6238
|
};
|
|
6239
6239
|
}
|
|
6240
|
-
function addSubModuleTask(repo,
|
|
6241
|
-
return subModuleTask(["add", repo,
|
|
6240
|
+
function addSubModuleTask(repo, path18) {
|
|
6241
|
+
return subModuleTask(["add", repo, path18]);
|
|
6242
6242
|
}
|
|
6243
6243
|
function initSubModuleTask(customArgs) {
|
|
6244
6244
|
return subModuleTask(["init", ...customArgs]);
|
|
@@ -6646,12 +6646,12 @@ function gitP(...args) {
|
|
|
6646
6646
|
);
|
|
6647
6647
|
}
|
|
6648
6648
|
return chain.then(function() {
|
|
6649
|
-
return new Promise(function(
|
|
6649
|
+
return new Promise(function(resolve7, reject) {
|
|
6650
6650
|
const callback = (err, result) => {
|
|
6651
6651
|
if (err) {
|
|
6652
6652
|
return reject(toError(err));
|
|
6653
6653
|
}
|
|
6654
|
-
|
|
6654
|
+
resolve7(result);
|
|
6655
6655
|
};
|
|
6656
6656
|
args2.push(callback);
|
|
6657
6657
|
git2[fn].apply(git2, args2);
|
|
@@ -7570,9 +7570,9 @@ var init_esm = __esm({
|
|
|
7570
7570
|
"src/lib/responses/InitSummary.ts"() {
|
|
7571
7571
|
"use strict";
|
|
7572
7572
|
InitSummary = class {
|
|
7573
|
-
constructor(bare,
|
|
7573
|
+
constructor(bare, path18, existing, gitDir) {
|
|
7574
7574
|
this.bare = bare;
|
|
7575
|
-
this.path =
|
|
7575
|
+
this.path = path18;
|
|
7576
7576
|
this.existing = existing;
|
|
7577
7577
|
this.gitDir = gitDir;
|
|
7578
7578
|
}
|
|
@@ -8105,12 +8105,12 @@ var init_esm = __esm({
|
|
|
8105
8105
|
"use strict";
|
|
8106
8106
|
fromPathRegex = /^(.+)\0(.+)$/;
|
|
8107
8107
|
FileStatusSummary = class {
|
|
8108
|
-
constructor(
|
|
8109
|
-
this.path =
|
|
8108
|
+
constructor(path18, index, working_dir) {
|
|
8109
|
+
this.path = path18;
|
|
8110
8110
|
this.index = index;
|
|
8111
8111
|
this.working_dir = working_dir;
|
|
8112
8112
|
if (index === "R" || working_dir === "R") {
|
|
8113
|
-
const detail = fromPathRegex.exec(
|
|
8113
|
+
const detail = fromPathRegex.exec(path18) || [null, path18, path18];
|
|
8114
8114
|
this.from = detail[2] || "";
|
|
8115
8115
|
this.path = detail[1] || "";
|
|
8116
8116
|
}
|
|
@@ -8372,9 +8372,9 @@ var init_esm = __esm({
|
|
|
8372
8372
|
next
|
|
8373
8373
|
);
|
|
8374
8374
|
}
|
|
8375
|
-
hashObject(
|
|
8375
|
+
hashObject(path18, write) {
|
|
8376
8376
|
return this._runTask(
|
|
8377
|
-
hashObjectTask(
|
|
8377
|
+
hashObjectTask(path18, write === true),
|
|
8378
8378
|
trailingFunctionArgument(arguments)
|
|
8379
8379
|
);
|
|
8380
8380
|
}
|
|
@@ -9011,8 +9011,8 @@ var init_esm = __esm({
|
|
|
9011
9011
|
}
|
|
9012
9012
|
return this._runTask(straightThroughStringTask2(command, this._trimmed), next);
|
|
9013
9013
|
};
|
|
9014
|
-
Git2.prototype.submoduleAdd = function(repo,
|
|
9015
|
-
return this._runTask(addSubModuleTask2(repo,
|
|
9014
|
+
Git2.prototype.submoduleAdd = function(repo, path18, then) {
|
|
9015
|
+
return this._runTask(addSubModuleTask2(repo, path18), trailingFunctionArgument2(arguments));
|
|
9016
9016
|
};
|
|
9017
9017
|
Git2.prototype.submoduleUpdate = function(args, then) {
|
|
9018
9018
|
return this._runTask(
|
|
@@ -9319,7 +9319,7 @@ var init_esm = __esm({
|
|
|
9319
9319
|
|
|
9320
9320
|
// src/index.ts
|
|
9321
9321
|
var fs15 = __toESM(require("fs"), 1);
|
|
9322
|
-
var
|
|
9322
|
+
var path17 = __toESM(require("path"), 1);
|
|
9323
9323
|
|
|
9324
9324
|
// ../../node_modules/.pnpm/commander@13.1.0/node_modules/commander/esm.mjs
|
|
9325
9325
|
var import_index = __toESM(require_commander(), 1);
|
|
@@ -9339,7 +9339,7 @@ var {
|
|
|
9339
9339
|
} = import_index.default;
|
|
9340
9340
|
|
|
9341
9341
|
// src/index.ts
|
|
9342
|
-
var
|
|
9342
|
+
var import_picocolors5 = __toESM(require_picocolors(), 1);
|
|
9343
9343
|
|
|
9344
9344
|
// ../core/dist/index.js
|
|
9345
9345
|
var crypto2 = __toESM(require("crypto"), 1);
|
|
@@ -9822,8 +9822,8 @@ function getErrorMap() {
|
|
|
9822
9822
|
|
|
9823
9823
|
// ../../node_modules/.pnpm/zod@3.25.76/node_modules/zod/v3/helpers/parseUtil.js
|
|
9824
9824
|
var makeIssue = (params) => {
|
|
9825
|
-
const { data, path:
|
|
9826
|
-
const fullPath = [...
|
|
9825
|
+
const { data, path: path18, errorMaps, issueData } = params;
|
|
9826
|
+
const fullPath = [...path18, ...issueData.path || []];
|
|
9827
9827
|
const fullIssue = {
|
|
9828
9828
|
...issueData,
|
|
9829
9829
|
path: fullPath
|
|
@@ -9939,11 +9939,11 @@ var errorUtil;
|
|
|
9939
9939
|
|
|
9940
9940
|
// ../../node_modules/.pnpm/zod@3.25.76/node_modules/zod/v3/types.js
|
|
9941
9941
|
var ParseInputLazyPath = class {
|
|
9942
|
-
constructor(parent, value,
|
|
9942
|
+
constructor(parent, value, path18, key) {
|
|
9943
9943
|
this._cachedPath = [];
|
|
9944
9944
|
this.parent = parent;
|
|
9945
9945
|
this.data = value;
|
|
9946
|
-
this._path =
|
|
9946
|
+
this._path = path18;
|
|
9947
9947
|
this._key = key;
|
|
9948
9948
|
}
|
|
9949
9949
|
get path() {
|
|
@@ -13394,11 +13394,13 @@ var AttributionModeSchema = external_exports.enum([
|
|
|
13394
13394
|
"unknown"
|
|
13395
13395
|
]);
|
|
13396
13396
|
var ProviderSessionSchema = external_exports.object({
|
|
13397
|
+
sessionId: external_exports.string().optional(),
|
|
13397
13398
|
provider: external_exports.string(),
|
|
13398
13399
|
// e.g. "anthropic", "openai", "cursor", "copilot", "gemini", "antigravity"
|
|
13399
13400
|
model: external_exports.string().optional(),
|
|
13400
13401
|
task: external_exports.string().optional(),
|
|
13401
13402
|
filesTouched: external_exports.array(external_exports.string()).optional(),
|
|
13403
|
+
turnsCount: external_exports.number().int().nonnegative().optional(),
|
|
13402
13404
|
tokens: external_exports.object({
|
|
13403
13405
|
input: external_exports.number().int().nonnegative().default(0),
|
|
13404
13406
|
output: external_exports.number().int().nonnegative().default(0),
|
|
@@ -13406,7 +13408,8 @@ var ProviderSessionSchema = external_exports.object({
|
|
|
13406
13408
|
}),
|
|
13407
13409
|
cost: external_exports.number().nonnegative(),
|
|
13408
13410
|
confidence: external_exports.number().min(0).max(1),
|
|
13409
|
-
mode: AttributionModeSchema
|
|
13411
|
+
mode: AttributionModeSchema,
|
|
13412
|
+
createdAt: external_exports.string().optional()
|
|
13410
13413
|
});
|
|
13411
13414
|
var ReceiptV1Schema = external_exports.object({
|
|
13412
13415
|
version: external_exports.literal("1.0"),
|
|
@@ -13957,6 +13960,16 @@ var RATE_CARDS = {
|
|
|
13957
13960
|
cacheWritePerMTok: 0.1,
|
|
13958
13961
|
contextWindow: 1e6
|
|
13959
13962
|
},
|
|
13963
|
+
"gemini-3-6-flash": {
|
|
13964
|
+
id: "gemini-3-6-flash",
|
|
13965
|
+
provider: "google",
|
|
13966
|
+
name: "Gemini 3.6 Flash",
|
|
13967
|
+
inputPerMTok: 0.1,
|
|
13968
|
+
outputPerMTok: 0.4,
|
|
13969
|
+
cacheReadPerMTok: 0.025,
|
|
13970
|
+
cacheWritePerMTok: 0.1,
|
|
13971
|
+
contextWindow: 1e6
|
|
13972
|
+
},
|
|
13960
13973
|
"gemini-2-5-pro": {
|
|
13961
13974
|
id: "gemini-2-5-pro",
|
|
13962
13975
|
provider: "google",
|
|
@@ -14065,9 +14078,14 @@ var MODEL_ALIASES = {
|
|
|
14065
14078
|
"gemini-3-1-pro": "gemini-2-5-pro",
|
|
14066
14079
|
"gemini-3-pro": "gemini-2-5-pro",
|
|
14067
14080
|
"gemini-3-1-flash": "gemini-3-8-flash",
|
|
14081
|
+
"gemini-3.8-flash": "gemini-3-8-flash",
|
|
14082
|
+
"gemini-3.6-flash": "gemini-3-6-flash",
|
|
14083
|
+
"gemini-3-6": "gemini-3-6-flash",
|
|
14068
14084
|
"gemini-2.0-flash": "gemini-2-0-flash",
|
|
14069
14085
|
"gemini-1.5-pro": "gemini-1-5-pro",
|
|
14070
14086
|
"gemini-1.5-flash": "gemini-2-0-flash",
|
|
14087
|
+
"google/gemini-3.8-flash": "gemini-3-8-flash",
|
|
14088
|
+
"google/gemini-3.6-flash": "gemini-3-6-flash",
|
|
14071
14089
|
// DeepSeek aliases
|
|
14072
14090
|
"deepseek-chat": "deepseek-v3",
|
|
14073
14091
|
"deepseek-coder": "deepseek-v3",
|
|
@@ -14375,6 +14393,9 @@ function discoverAntigravityEnvironment() {
|
|
|
14375
14393
|
return null;
|
|
14376
14394
|
}
|
|
14377
14395
|
|
|
14396
|
+
// ../core/dist/harvester/index.js
|
|
14397
|
+
var path11 = __toESM(require("path"), 1);
|
|
14398
|
+
|
|
14378
14399
|
// ../core/dist/harvester/antigravity.js
|
|
14379
14400
|
var fs2 = __toESM(require("fs"), 1);
|
|
14380
14401
|
var path3 = __toESM(require("path"), 1);
|
|
@@ -14383,7 +14404,8 @@ var import_node_module = require("module");
|
|
|
14383
14404
|
|
|
14384
14405
|
// ../core/dist/harvester/scoring.js
|
|
14385
14406
|
function normalizeFilePath(filePath, repoPath) {
|
|
14386
|
-
let p2 = filePath.replace(
|
|
14407
|
+
let p2 = filePath.trim().replace(/^["']|["']$/g, "").replace(/\\/g, "/");
|
|
14408
|
+
p2 = p2.replace(/\/+/g, "/");
|
|
14387
14409
|
p2 = p2.replace(/^file:\/\/\/?/, "");
|
|
14388
14410
|
if (repoPath) {
|
|
14389
14411
|
const normRepo = repoPath.replace(/\\/g, "/").replace(/\/$/, "");
|
|
@@ -15799,39 +15821,86 @@ function parseSinceOption2(since) {
|
|
|
15799
15821
|
}
|
|
15800
15822
|
return void 0;
|
|
15801
15823
|
}
|
|
15802
|
-
|
|
15803
|
-
const
|
|
15804
|
-
|
|
15805
|
-
|
|
15806
|
-
let allFootprints = [];
|
|
15807
|
-
if (!options.platform || options.platform === "all" || options.platform === "antigravity") {
|
|
15808
|
-
const agFootprints = harvestAntigravityFootprints(options.repoPath, sinceDate);
|
|
15824
|
+
function harvestRawPlatformFootprints(repoPath, alias, sinceDate, platform) {
|
|
15825
|
+
const allFootprints = [];
|
|
15826
|
+
if (!platform || platform === "all" || platform === "antigravity") {
|
|
15827
|
+
const agFootprints = harvestAntigravityFootprints(repoPath, sinceDate);
|
|
15809
15828
|
allFootprints.push(...agFootprints);
|
|
15810
15829
|
}
|
|
15811
|
-
if (!
|
|
15812
|
-
const claudeFootprints = harvestClaudeFootprints(
|
|
15830
|
+
if (!platform || platform === "all" || platform === "claude") {
|
|
15831
|
+
const claudeFootprints = harvestClaudeFootprints(repoPath, alias, sinceDate);
|
|
15813
15832
|
allFootprints.push(...claudeFootprints);
|
|
15814
15833
|
}
|
|
15815
|
-
if (!
|
|
15816
|
-
const cursorFootprints = harvestCursorFootprints(
|
|
15834
|
+
if (!platform || platform === "all" || platform === "cursor") {
|
|
15835
|
+
const cursorFootprints = harvestCursorFootprints(repoPath, sinceDate);
|
|
15817
15836
|
allFootprints.push(...cursorFootprints);
|
|
15818
15837
|
}
|
|
15819
|
-
if (!
|
|
15820
|
-
const aiderFootprints = harvestAiderFootprints(
|
|
15838
|
+
if (!platform || platform === "all" || platform === "aider") {
|
|
15839
|
+
const aiderFootprints = harvestAiderFootprints(repoPath, sinceDate);
|
|
15821
15840
|
allFootprints.push(...aiderFootprints);
|
|
15822
15841
|
}
|
|
15823
|
-
if (!
|
|
15824
|
-
const windsurfFootprints = harvestWindsurfFootprints(
|
|
15842
|
+
if (!platform || platform === "all" || platform === "windsurf") {
|
|
15843
|
+
const windsurfFootprints = harvestWindsurfFootprints(repoPath, sinceDate);
|
|
15825
15844
|
allFootprints.push(...windsurfFootprints);
|
|
15826
15845
|
}
|
|
15827
|
-
if (!
|
|
15828
|
-
const clineFootprints = harvestClineFootprints(
|
|
15846
|
+
if (!platform || platform === "all" || platform === "cline") {
|
|
15847
|
+
const clineFootprints = harvestClineFootprints(repoPath, sinceDate);
|
|
15829
15848
|
allFootprints.push(...clineFootprints);
|
|
15830
15849
|
}
|
|
15831
|
-
if (!
|
|
15832
|
-
const opencodeFootprints = harvestOpenCodeFootprints(
|
|
15850
|
+
if (!platform || platform === "all" || platform === "opencode") {
|
|
15851
|
+
const opencodeFootprints = harvestOpenCodeFootprints(repoPath, sinceDate);
|
|
15833
15852
|
allFootprints.push(...opencodeFootprints);
|
|
15834
15853
|
}
|
|
15854
|
+
return allFootprints;
|
|
15855
|
+
}
|
|
15856
|
+
async function listProjectChats(options = {}) {
|
|
15857
|
+
const repoPath = options.repoPath || process.cwd();
|
|
15858
|
+
const alias = options.projectAlias || path11.basename(path11.resolve(repoPath)) || "project";
|
|
15859
|
+
let sinceDate;
|
|
15860
|
+
let windowDescription = "All-time";
|
|
15861
|
+
if (!options.all) {
|
|
15862
|
+
if (options.since) {
|
|
15863
|
+
sinceDate = parseSinceOption2(options.since);
|
|
15864
|
+
windowDescription = typeof options.since === "string" ? `Since ${options.since}` : `Since ${options.since.toISOString().slice(0, 10)}`;
|
|
15865
|
+
} else {
|
|
15866
|
+
sinceDate = new Date(Date.now() - 30 * 24 * 60 * 60 * 1e3);
|
|
15867
|
+
windowDescription = "Last 30 Days";
|
|
15868
|
+
}
|
|
15869
|
+
}
|
|
15870
|
+
const allFootprints = harvestRawPlatformFootprints(repoPath, alias, sinceDate, options.platform);
|
|
15871
|
+
allFootprints.sort((a, b2) => new Date(b2.timestamp).getTime() - new Date(a.timestamp).getTime());
|
|
15872
|
+
let totalInput = 0;
|
|
15873
|
+
let totalOutput = 0;
|
|
15874
|
+
let totalCached = 0;
|
|
15875
|
+
let totalCost = 0;
|
|
15876
|
+
let totalSteps = 0;
|
|
15877
|
+
for (const fp of allFootprints) {
|
|
15878
|
+
totalInput += fp.tokens.input;
|
|
15879
|
+
totalOutput += fp.tokens.output;
|
|
15880
|
+
totalCached += fp.tokens.cached;
|
|
15881
|
+
totalCost += fp.cost;
|
|
15882
|
+
totalSteps += fp.stepsCount || 0;
|
|
15883
|
+
}
|
|
15884
|
+
return {
|
|
15885
|
+
repoPath,
|
|
15886
|
+
projectAlias: alias,
|
|
15887
|
+
windowDescription,
|
|
15888
|
+
totalCost: Number(totalCost.toFixed(4)),
|
|
15889
|
+
totalTokens: {
|
|
15890
|
+
input: totalInput,
|
|
15891
|
+
output: totalOutput,
|
|
15892
|
+
cached: totalCached
|
|
15893
|
+
},
|
|
15894
|
+
totalSteps,
|
|
15895
|
+
sessionsCount: allFootprints.length,
|
|
15896
|
+
chats: allFootprints
|
|
15897
|
+
};
|
|
15898
|
+
}
|
|
15899
|
+
async function harvestUniversalFootprints(options) {
|
|
15900
|
+
const parsedSince = parseSinceOption2(options.since);
|
|
15901
|
+
const sinceDate = parsedSince ? new Date(parsedSince.getTime() - 24 * 60 * 60 * 1e3) : void 0;
|
|
15902
|
+
const alias = options.projectAlias || "";
|
|
15903
|
+
let allFootprints = harvestRawPlatformFootprints(options.repoPath, alias, sinceDate, options.platform);
|
|
15835
15904
|
if (options.gitContext?.commitMessage) {
|
|
15836
15905
|
const trailerFps = harvestTrailerFootprints(options.repoPath, options.gitContext.commitMessage, options.gitContext.headSha, options.gitContext.commitDate);
|
|
15837
15906
|
allFootprints.push(...trailerFps);
|
|
@@ -15958,15 +16027,15 @@ function estimateCost(options) {
|
|
|
15958
16027
|
|
|
15959
16028
|
// ../core/dist/pricing-sync.js
|
|
15960
16029
|
var fs10 = __toESM(require("fs"), 1);
|
|
15961
|
-
var
|
|
16030
|
+
var path12 = __toESM(require("path"), 1);
|
|
15962
16031
|
var os10 = __toESM(require("os"), 1);
|
|
15963
16032
|
async function syncDynamicPricing(options) {
|
|
15964
16033
|
try {
|
|
15965
|
-
const qodewkDir =
|
|
16034
|
+
const qodewkDir = path12.join(os10.homedir(), ".qodewk");
|
|
15966
16035
|
if (!fs10.existsSync(qodewkDir)) {
|
|
15967
16036
|
fs10.mkdirSync(qodewkDir, { recursive: true });
|
|
15968
16037
|
}
|
|
15969
|
-
const cacheFile =
|
|
16038
|
+
const cacheFile = path12.join(qodewkDir, "pricing_registry_cache.json");
|
|
15970
16039
|
const TTL_MS = 24 * 60 * 60 * 1e3;
|
|
15971
16040
|
const now = Date.now();
|
|
15972
16041
|
if (!options?.force && fs10.existsSync(cacheFile)) {
|
|
@@ -16001,7 +16070,7 @@ async function syncDynamicPricing(options) {
|
|
|
16001
16070
|
|
|
16002
16071
|
// ../core/dist/env.js
|
|
16003
16072
|
var fs11 = __toESM(require("fs"), 1);
|
|
16004
|
-
var
|
|
16073
|
+
var path13 = __toESM(require("path"), 1);
|
|
16005
16074
|
var os11 = __toESM(require("os"), 1);
|
|
16006
16075
|
var isEnvLoaded = false;
|
|
16007
16076
|
function loadQodewkEnv(startDir = process.cwd()) {
|
|
@@ -16009,11 +16078,11 @@ function loadQodewkEnv(startDir = process.cwd()) {
|
|
|
16009
16078
|
return;
|
|
16010
16079
|
isEnvLoaded = true;
|
|
16011
16080
|
const candidates = [
|
|
16012
|
-
|
|
16013
|
-
|
|
16014
|
-
|
|
16015
|
-
|
|
16016
|
-
|
|
16081
|
+
path13.join(startDir, ".env.local"),
|
|
16082
|
+
path13.join(startDir, ".env"),
|
|
16083
|
+
path13.join(startDir, "apps", "web", ".env.local"),
|
|
16084
|
+
path13.join(startDir, "apps", "web", ".env"),
|
|
16085
|
+
path13.join(os11.homedir(), ".qodewk", "config.env")
|
|
16017
16086
|
];
|
|
16018
16087
|
for (const envPath of candidates) {
|
|
16019
16088
|
if (!fs11.existsSync(envPath))
|
|
@@ -16089,7 +16158,7 @@ function formatMarkdownReceipt(receipt, publicUrl) {
|
|
|
16089
16158
|
|
|
16090
16159
|
// ../core/dist/doctor.js
|
|
16091
16160
|
var fs12 = __toESM(require("fs"), 1);
|
|
16092
|
-
var
|
|
16161
|
+
var path14 = __toESM(require("path"), 1);
|
|
16093
16162
|
var os12 = __toESM(require("os"), 1);
|
|
16094
16163
|
var import_node_child_process = require("child_process");
|
|
16095
16164
|
var HOOK_MARKER_BEGIN = "# --- BEGIN QODEWK HOOK ---";
|
|
@@ -16097,7 +16166,7 @@ function auditAgentEnvironments(repoPath = process.cwd()) {
|
|
|
16097
16166
|
const homedir12 = os12.homedir();
|
|
16098
16167
|
const results = [];
|
|
16099
16168
|
const agEnv = process.env.ANTIGRAVITY_APP_DATA_DIR;
|
|
16100
|
-
const agHome =
|
|
16169
|
+
const agHome = path14.join(homedir12, ".gemini", "antigravity");
|
|
16101
16170
|
const agPath = agEnv && fs12.existsSync(agEnv) ? agEnv : fs12.existsSync(agHome) ? agHome : void 0;
|
|
16102
16171
|
results.push({
|
|
16103
16172
|
id: "antigravity",
|
|
@@ -16106,7 +16175,7 @@ function auditAgentEnvironments(repoPath = process.cwd()) {
|
|
|
16106
16175
|
path: agPath,
|
|
16107
16176
|
details: agPath ? "Antigravity brain telemetry detected" : "No active session brain found"
|
|
16108
16177
|
});
|
|
16109
|
-
const claudeProjects =
|
|
16178
|
+
const claudeProjects = path14.join(homedir12, ".claude", "projects");
|
|
16110
16179
|
const claudeExists = fs12.existsSync(claudeProjects);
|
|
16111
16180
|
results.push({
|
|
16112
16181
|
id: "claude",
|
|
@@ -16117,15 +16186,15 @@ function auditAgentEnvironments(repoPath = process.cwd()) {
|
|
|
16117
16186
|
});
|
|
16118
16187
|
let cursorPath;
|
|
16119
16188
|
if (process.platform === "win32") {
|
|
16120
|
-
const c3 =
|
|
16189
|
+
const c3 = path14.join(process.env.APPDATA || path14.join(homedir12, "AppData", "Roaming"), "Cursor", "User", "workspaceStorage");
|
|
16121
16190
|
if (fs12.existsSync(c3))
|
|
16122
16191
|
cursorPath = c3;
|
|
16123
16192
|
} else if (process.platform === "darwin") {
|
|
16124
|
-
const c3 =
|
|
16193
|
+
const c3 = path14.join(homedir12, "Library", "Application Support", "Cursor", "User", "workspaceStorage");
|
|
16125
16194
|
if (fs12.existsSync(c3))
|
|
16126
16195
|
cursorPath = c3;
|
|
16127
16196
|
} else {
|
|
16128
|
-
const c3 =
|
|
16197
|
+
const c3 = path14.join(homedir12, ".config", "Cursor", "User", "workspaceStorage");
|
|
16129
16198
|
if (fs12.existsSync(c3))
|
|
16130
16199
|
cursorPath = c3;
|
|
16131
16200
|
}
|
|
@@ -16138,15 +16207,15 @@ function auditAgentEnvironments(repoPath = process.cwd()) {
|
|
|
16138
16207
|
});
|
|
16139
16208
|
let windsurfPath;
|
|
16140
16209
|
if (process.platform === "win32") {
|
|
16141
|
-
const w =
|
|
16210
|
+
const w = path14.join(process.env.APPDATA || path14.join(homedir12, "AppData", "Roaming"), "Windsurf", "User", "workspaceStorage");
|
|
16142
16211
|
if (fs12.existsSync(w))
|
|
16143
16212
|
windsurfPath = w;
|
|
16144
16213
|
} else if (process.platform === "darwin") {
|
|
16145
|
-
const w =
|
|
16214
|
+
const w = path14.join(homedir12, "Library", "Application Support", "Windsurf", "User", "workspaceStorage");
|
|
16146
16215
|
if (fs12.existsSync(w))
|
|
16147
16216
|
windsurfPath = w;
|
|
16148
16217
|
} else {
|
|
16149
|
-
const w =
|
|
16218
|
+
const w = path14.join(homedir12, ".config", "Windsurf", "User", "workspaceStorage");
|
|
16150
16219
|
if (fs12.existsSync(w))
|
|
16151
16220
|
windsurfPath = w;
|
|
16152
16221
|
}
|
|
@@ -16158,16 +16227,16 @@ function auditAgentEnvironments(repoPath = process.cwd()) {
|
|
|
16158
16227
|
details: windsurfPath ? "Cascade session workspace storage detected" : "Windsurf IDE storage not detected"
|
|
16159
16228
|
});
|
|
16160
16229
|
let clinePath;
|
|
16161
|
-
const localCline =
|
|
16162
|
-
const localRoo =
|
|
16230
|
+
const localCline = path14.join(repoPath, ".cline");
|
|
16231
|
+
const localRoo = path14.join(repoPath, ".roo");
|
|
16163
16232
|
if (fs12.existsSync(localCline)) {
|
|
16164
16233
|
clinePath = localCline;
|
|
16165
16234
|
} else if (fs12.existsSync(localRoo)) {
|
|
16166
16235
|
clinePath = localRoo;
|
|
16167
16236
|
} else {
|
|
16168
|
-
const appData = process.platform === "win32" ? process.env.APPDATA ||
|
|
16169
|
-
const clineExt =
|
|
16170
|
-
const rooExt =
|
|
16237
|
+
const appData = process.platform === "win32" ? process.env.APPDATA || path14.join(homedir12, "AppData", "Roaming") : process.platform === "darwin" ? path14.join(homedir12, "Library", "Application Support") : path14.join(homedir12, ".config");
|
|
16238
|
+
const clineExt = path14.join(appData, "Code", "User", "globalStorage", "saoudrizwan.claude-dev", "tasks");
|
|
16239
|
+
const rooExt = path14.join(appData, "Code", "User", "globalStorage", "rooveterinaryinc.roo-cline", "tasks");
|
|
16171
16240
|
if (fs12.existsSync(clineExt))
|
|
16172
16241
|
clinePath = clineExt;
|
|
16173
16242
|
else if (fs12.existsSync(rooExt))
|
|
@@ -16180,7 +16249,7 @@ function auditAgentEnvironments(repoPath = process.cwd()) {
|
|
|
16180
16249
|
path: clinePath,
|
|
16181
16250
|
details: clinePath ? "VS Code autonomous agent task storage detected" : "No active Cline or Roo Code tasks found"
|
|
16182
16251
|
});
|
|
16183
|
-
const aiderPath =
|
|
16252
|
+
const aiderPath = path14.join(repoPath, ".aider.chat.history.md");
|
|
16184
16253
|
const aiderExists = fs12.existsSync(aiderPath);
|
|
16185
16254
|
results.push({
|
|
16186
16255
|
id: "aider",
|
|
@@ -16189,8 +16258,8 @@ function auditAgentEnvironments(repoPath = process.cwd()) {
|
|
|
16189
16258
|
path: aiderExists ? aiderPath : void 0,
|
|
16190
16259
|
details: aiderExists ? "Repository pairing transcript found" : "No repo-local .aider.chat.history.md found"
|
|
16191
16260
|
});
|
|
16192
|
-
const localOpenCode =
|
|
16193
|
-
const homeOpenCode =
|
|
16261
|
+
const localOpenCode = path14.join(repoPath, ".opencode");
|
|
16262
|
+
const homeOpenCode = path14.join(homedir12, ".opencode", "sessions");
|
|
16194
16263
|
const opencodePath = fs12.existsSync(localOpenCode) ? localOpenCode : fs12.existsSync(homeOpenCode) ? homeOpenCode : void 0;
|
|
16195
16264
|
results.push({
|
|
16196
16265
|
id: "opencode",
|
|
@@ -16202,32 +16271,38 @@ function auditAgentEnvironments(repoPath = process.cwd()) {
|
|
|
16202
16271
|
return results;
|
|
16203
16272
|
}
|
|
16204
16273
|
function resolveHooksDir(cwd = process.cwd()) {
|
|
16205
|
-
|
|
16206
|
-
|
|
16207
|
-
|
|
16274
|
+
let curr = path14.resolve(cwd);
|
|
16275
|
+
let gitPath = path14.join(curr, ".git");
|
|
16276
|
+
while (!fs12.existsSync(gitPath)) {
|
|
16277
|
+
const parent = path14.dirname(curr);
|
|
16278
|
+
if (parent === curr)
|
|
16279
|
+
return null;
|
|
16280
|
+
curr = parent;
|
|
16281
|
+
gitPath = path14.join(curr, ".git");
|
|
16282
|
+
}
|
|
16208
16283
|
try {
|
|
16209
16284
|
const stat = fs12.statSync(gitPath);
|
|
16210
16285
|
if (stat.isDirectory()) {
|
|
16211
|
-
return
|
|
16286
|
+
return path14.join(gitPath, "hooks");
|
|
16212
16287
|
}
|
|
16213
16288
|
const content = fs12.readFileSync(gitPath, "utf-8");
|
|
16214
16289
|
const match = content.match(/gitdir:\s*(.+)/i);
|
|
16215
16290
|
if (!match?.[1])
|
|
16216
16291
|
return null;
|
|
16217
16292
|
let gitDir = match[1].trim();
|
|
16218
|
-
if (!
|
|
16219
|
-
gitDir =
|
|
16293
|
+
if (!path14.isAbsolute(gitDir)) {
|
|
16294
|
+
gitDir = path14.resolve(curr, gitDir);
|
|
16220
16295
|
}
|
|
16221
|
-
const commonFile =
|
|
16296
|
+
const commonFile = path14.join(gitDir, "commondir");
|
|
16222
16297
|
if (fs12.existsSync(commonFile)) {
|
|
16223
16298
|
let common = fs12.readFileSync(commonFile, "utf-8").trim();
|
|
16224
|
-
if (!
|
|
16225
|
-
common =
|
|
16226
|
-
return
|
|
16227
|
-
} else if (
|
|
16228
|
-
return
|
|
16299
|
+
if (!path14.isAbsolute(common))
|
|
16300
|
+
common = path14.resolve(gitDir, common);
|
|
16301
|
+
return path14.join(common, "hooks");
|
|
16302
|
+
} else if (path14.basename(path14.dirname(gitDir)) === "worktrees") {
|
|
16303
|
+
return path14.join(path14.dirname(path14.dirname(gitDir)), "hooks");
|
|
16229
16304
|
}
|
|
16230
|
-
return
|
|
16305
|
+
return path14.join(gitDir, "hooks");
|
|
16231
16306
|
} catch {
|
|
16232
16307
|
return null;
|
|
16233
16308
|
}
|
|
@@ -16243,8 +16318,8 @@ function auditGitHooks(repoPath = process.cwd()) {
|
|
|
16243
16318
|
markerFound: false
|
|
16244
16319
|
};
|
|
16245
16320
|
}
|
|
16246
|
-
const postCommit =
|
|
16247
|
-
const postRewrite =
|
|
16321
|
+
const postCommit = path14.join(hooksDir, "post-commit");
|
|
16322
|
+
const postRewrite = path14.join(hooksDir, "post-rewrite");
|
|
16248
16323
|
const hasMarker = (filePath) => {
|
|
16249
16324
|
if (!fs12.existsSync(filePath))
|
|
16250
16325
|
return false;
|
|
@@ -16308,7 +16383,7 @@ async function benchmarkHookLatency(trials = 3) {
|
|
|
16308
16383
|
}
|
|
16309
16384
|
}
|
|
16310
16385
|
function auditStorageHealth() {
|
|
16311
|
-
const dbPath =
|
|
16386
|
+
const dbPath = path14.join(os12.homedir(), ".qodewk", "state.db");
|
|
16312
16387
|
try {
|
|
16313
16388
|
const db = new LocalStateDB();
|
|
16314
16389
|
const stats = db.getStats();
|
|
@@ -16335,7 +16410,7 @@ function auditStorageHealth() {
|
|
|
16335
16410
|
}
|
|
16336
16411
|
function auditPricingSync() {
|
|
16337
16412
|
const modelsCount = Object.keys(RATE_CARDS).length;
|
|
16338
|
-
const cachedJson =
|
|
16413
|
+
const cachedJson = path14.join(os12.homedir(), ".qodewk", "pricing.json");
|
|
16339
16414
|
const hasCached = fs12.existsSync(cachedJson);
|
|
16340
16415
|
return {
|
|
16341
16416
|
modelsLoaded: modelsCount,
|
|
@@ -16359,7 +16434,7 @@ async function runDiagnostics(options = {}) {
|
|
|
16359
16434
|
}
|
|
16360
16435
|
return {
|
|
16361
16436
|
overallStatus,
|
|
16362
|
-
version: "0.
|
|
16437
|
+
version: "0.11.0",
|
|
16363
16438
|
timestamp: (/* @__PURE__ */ new Date()).toISOString(),
|
|
16364
16439
|
repoPath,
|
|
16365
16440
|
agents,
|
|
@@ -16422,14 +16497,17 @@ async function generateReceipt(options = {}) {
|
|
|
16422
16497
|
const model = options.model || primaryFp?.model || detected?.model;
|
|
16423
16498
|
const task = options.task || primaryFp?.taskTitle || (harvestResult.tasks.length > 0 ? harvestResult.tasks[0] : void 0);
|
|
16424
16499
|
const sessions = harvestResult.footprints.map((fp) => ({
|
|
16500
|
+
sessionId: fp.sessionId,
|
|
16425
16501
|
provider: fp.platform,
|
|
16426
16502
|
model: fp.model,
|
|
16427
16503
|
task: fp.taskTitle,
|
|
16428
16504
|
filesTouched: fp.filesEdited,
|
|
16505
|
+
turnsCount: fp.stepsCount,
|
|
16429
16506
|
tokens: fp.tokens,
|
|
16430
16507
|
cost: fp.cost,
|
|
16431
16508
|
confidence: fp.confidence,
|
|
16432
|
-
mode: fp.mode
|
|
16509
|
+
mode: fp.mode,
|
|
16510
|
+
createdAt: fp.timestamp
|
|
16433
16511
|
}));
|
|
16434
16512
|
const aiWrittenRatio = computeAiWrittenRatio(metrics.changedFiles, harvestResult.filesEdited);
|
|
16435
16513
|
const costResult = estimateCost({
|
|
@@ -16840,11 +16918,20 @@ function buildTerminalReceipt(receipt, publicUrl) {
|
|
|
16840
16918
|
const provString = receipt.ai.provider + " \xB7 " + (receipt.ai.model || "Unknown");
|
|
16841
16919
|
const cleanProv = provString.length > 40 ? provString.slice(0, 39) + "\u2026" : provString;
|
|
16842
16920
|
printRow(`Provider: ${cleanProv}`);
|
|
16843
|
-
if (receipt.ai.sessions && receipt.ai.sessions.length >
|
|
16844
|
-
|
|
16845
|
-
|
|
16846
|
-
|
|
16921
|
+
if (receipt.ai.sessions && receipt.ai.sessions.length > 0) {
|
|
16922
|
+
printDivider("-");
|
|
16923
|
+
printRow(`ITEMIZED SESSIONS (${receipt.ai.sessions.length}):`);
|
|
16924
|
+
for (const s of receipt.ai.sessions.slice(0, 5)) {
|
|
16925
|
+
const taskLabel = s.task ? s.task.length > 18 ? s.task.slice(0, 17) + "\u2026" : s.task : s.sessionId ? "#" + s.sessionId.slice(0, 8) : s.provider;
|
|
16926
|
+
const cleanMod = (s.model || s.provider).replace(/^(claude-|gemini-|gpt-)/, "");
|
|
16927
|
+
const modelLabel = ` (${cleanMod.length > 11 ? cleanMod.slice(0, 10) + "\u2026" : cleanMod})`;
|
|
16928
|
+
const sCost = s.mode === "verified" ? `$${s.cost.toFixed(2)}` : `~$${s.cost.toFixed(2)}`;
|
|
16929
|
+
printRowSplit(`\u2022 ${taskLabel}${import_picocolors.default.dim(modelLabel)}`, teal(sCost));
|
|
16930
|
+
}
|
|
16931
|
+
if (receipt.ai.sessions.length > 5) {
|
|
16932
|
+
printRow(import_picocolors.default.dim(` ... and ${receipt.ai.sessions.length - 5} more sessions`));
|
|
16847
16933
|
}
|
|
16934
|
+
printDivider("-");
|
|
16848
16935
|
}
|
|
16849
16936
|
if (receipt.ai.aiWrittenRatio !== void 0) {
|
|
16850
16937
|
const aiPct = Math.round(receipt.ai.aiWrittenRatio * 100);
|
|
@@ -16929,7 +17016,7 @@ async function outputReceipt(receipt, options, publicUrl) {
|
|
|
16929
17016
|
|
|
16930
17017
|
// src/hooks.ts
|
|
16931
17018
|
var fs14 = __toESM(require("fs"), 1);
|
|
16932
|
-
var
|
|
17019
|
+
var path15 = __toESM(require("path"), 1);
|
|
16933
17020
|
var HOOK_MARKER_BEGIN2 = "# --- BEGIN QODEWK HOOK ---";
|
|
16934
17021
|
var HOOK_MARKER_END = "# --- END QODEWK HOOK ---";
|
|
16935
17022
|
var HOOK_SNIPPET = `
|
|
@@ -16941,7 +17028,7 @@ fi
|
|
|
16941
17028
|
${HOOK_MARKER_END}
|
|
16942
17029
|
`;
|
|
16943
17030
|
function resolveGitHooksDir(cwd = process.cwd()) {
|
|
16944
|
-
const gitPath =
|
|
17031
|
+
const gitPath = path15.join(cwd, ".git");
|
|
16945
17032
|
if (!fs14.existsSync(gitPath)) return null;
|
|
16946
17033
|
let gitCommonDir;
|
|
16947
17034
|
const stat = fs14.statSync(gitPath);
|
|
@@ -16952,23 +17039,23 @@ function resolveGitHooksDir(cwd = process.cwd()) {
|
|
|
16952
17039
|
const match = content.match(/gitdir:\s*(.+)/i);
|
|
16953
17040
|
if (!match?.[1]) return null;
|
|
16954
17041
|
let gitDir = match[1].trim();
|
|
16955
|
-
if (!
|
|
16956
|
-
gitDir =
|
|
17042
|
+
if (!path15.isAbsolute(gitDir)) {
|
|
17043
|
+
gitDir = path15.resolve(cwd, gitDir);
|
|
16957
17044
|
}
|
|
16958
|
-
const commonFile =
|
|
17045
|
+
const commonFile = path15.join(gitDir, "commondir");
|
|
16959
17046
|
if (fs14.existsSync(commonFile)) {
|
|
16960
17047
|
let common = fs14.readFileSync(commonFile, "utf-8").trim();
|
|
16961
|
-
if (!
|
|
16962
|
-
common =
|
|
17048
|
+
if (!path15.isAbsolute(common)) {
|
|
17049
|
+
common = path15.resolve(gitDir, common);
|
|
16963
17050
|
}
|
|
16964
17051
|
gitCommonDir = common;
|
|
16965
|
-
} else if (
|
|
16966
|
-
gitCommonDir =
|
|
17052
|
+
} else if (path15.basename(path15.dirname(gitDir)) === "worktrees") {
|
|
17053
|
+
gitCommonDir = path15.dirname(path15.dirname(gitDir));
|
|
16967
17054
|
} else {
|
|
16968
17055
|
gitCommonDir = gitDir;
|
|
16969
17056
|
}
|
|
16970
17057
|
}
|
|
16971
|
-
return
|
|
17058
|
+
return path15.join(gitCommonDir, "hooks");
|
|
16972
17059
|
}
|
|
16973
17060
|
function checkHookStatus(hooksDir) {
|
|
16974
17061
|
if (!hooksDir || !fs14.existsSync(hooksDir)) {
|
|
@@ -16979,8 +17066,8 @@ function checkHookStatus(hooksDir) {
|
|
|
16979
17066
|
postRewriteInstalled: false
|
|
16980
17067
|
};
|
|
16981
17068
|
}
|
|
16982
|
-
const postCommit =
|
|
16983
|
-
const postRewrite =
|
|
17069
|
+
const postCommit = path15.join(hooksDir, "post-commit");
|
|
17070
|
+
const postRewrite = path15.join(hooksDir, "post-rewrite");
|
|
16984
17071
|
const hasHook = (p2) => {
|
|
16985
17072
|
if (!fs14.existsSync(p2)) return false;
|
|
16986
17073
|
try {
|
|
@@ -17022,8 +17109,8 @@ function uninstallHookFile(hookFile) {
|
|
|
17022
17109
|
|
|
17023
17110
|
// src/menu.ts
|
|
17024
17111
|
var readline = __toESM(require("readline"), 1);
|
|
17025
|
-
var
|
|
17026
|
-
var
|
|
17112
|
+
var path16 = __toESM(require("path"), 1);
|
|
17113
|
+
var import_picocolors4 = __toESM(require_picocolors(), 1);
|
|
17027
17114
|
|
|
17028
17115
|
// src/doctor-view.ts
|
|
17029
17116
|
var import_picocolors2 = __toESM(require_picocolors(), 1);
|
|
@@ -17110,6 +17197,98 @@ function formatHookTestReport(hooks, benchmark) {
|
|
|
17110
17197
|
return lines.join("\n");
|
|
17111
17198
|
}
|
|
17112
17199
|
|
|
17200
|
+
// src/chat-view.ts
|
|
17201
|
+
var import_picocolors3 = __toESM(require_picocolors(), 1);
|
|
17202
|
+
function buildTerminalChatLedger(report) {
|
|
17203
|
+
const lines = [];
|
|
17204
|
+
const coral = colors.coral;
|
|
17205
|
+
const teal = colors.teal;
|
|
17206
|
+
const green = colors.green;
|
|
17207
|
+
const INNER_WIDTH = 68;
|
|
17208
|
+
const push = (line) => lines.push(line);
|
|
17209
|
+
const printRow = (content, width = INNER_WIDTH) => {
|
|
17210
|
+
const visLen = visibleWidth(content);
|
|
17211
|
+
const pad = Math.max(0, width - visLen);
|
|
17212
|
+
push(` | ${content}${" ".repeat(pad)} |`);
|
|
17213
|
+
};
|
|
17214
|
+
const printRowSplit = (left, right, width = INNER_WIDTH) => {
|
|
17215
|
+
const leftVis = visibleWidth(left);
|
|
17216
|
+
const rightVis = visibleWidth(right);
|
|
17217
|
+
const pad = Math.max(1, width - leftVis - rightVis);
|
|
17218
|
+
push(` | ${left}${" ".repeat(pad)}${right} |`);
|
|
17219
|
+
};
|
|
17220
|
+
const printCenteredRow = (content, width = INNER_WIDTH) => {
|
|
17221
|
+
const visLen = visibleWidth(content);
|
|
17222
|
+
const totalPad = Math.max(0, width - visLen);
|
|
17223
|
+
const leftPad = Math.floor(totalPad / 2);
|
|
17224
|
+
const rightPad = totalPad - leftPad;
|
|
17225
|
+
push(` | ${" ".repeat(leftPad)}${content}${" ".repeat(rightPad)} |`);
|
|
17226
|
+
};
|
|
17227
|
+
const printDivider = (char = "=", width = INNER_WIDTH) => {
|
|
17228
|
+
push(` | ${char.repeat(width)} |`);
|
|
17229
|
+
};
|
|
17230
|
+
push("");
|
|
17231
|
+
push(" " + import_picocolors3.default.bold(coral("/\\".repeat(36))));
|
|
17232
|
+
printCenteredRow(import_picocolors3.default.bold(import_picocolors3.default.white("Q O D E W K")));
|
|
17233
|
+
printCenteredRow(coral("*** WORKSPACE CHAT TELEMETRY LEDGER ***"));
|
|
17234
|
+
printRow("");
|
|
17235
|
+
printRowSplit(
|
|
17236
|
+
`REPO: ${report.projectAlias.slice(0, 24)}`,
|
|
17237
|
+
`WINDOW: ${report.windowDescription}`
|
|
17238
|
+
);
|
|
17239
|
+
printRowSplit(
|
|
17240
|
+
`CHATS: ${report.sessionsCount} sessions`,
|
|
17241
|
+
`STEPS: ${report.totalSteps.toLocaleString()} steps`
|
|
17242
|
+
);
|
|
17243
|
+
printDivider("=");
|
|
17244
|
+
if (report.chats.length === 0) {
|
|
17245
|
+
printCenteredRow(import_picocolors3.default.dim("No agent chat sessions found in this workspace window."));
|
|
17246
|
+
printRow("");
|
|
17247
|
+
} else {
|
|
17248
|
+
const colTask = "CHAT / TASK".padEnd(28);
|
|
17249
|
+
const colModel = "MODEL".padEnd(18);
|
|
17250
|
+
const colTok = "TOKENS".padStart(8);
|
|
17251
|
+
const colCost = "COST".padStart(10);
|
|
17252
|
+
printRow(`${colTask} ${colModel} ${colTok} ${colCost}`);
|
|
17253
|
+
printDivider("-");
|
|
17254
|
+
for (const chat of report.chats) {
|
|
17255
|
+
const cleanTitle = (chat.taskTitle || chat.sessionId || "Untitled Session").replace(/\n/g, " ").trim();
|
|
17256
|
+
const taskDisplay = (cleanTitle.length > 27 ? cleanTitle.slice(0, 26) + "\u2026" : cleanTitle).padEnd(28);
|
|
17257
|
+
const cleanModel = (chat.model || chat.platform || "default").replace(/^(claude-|gemini-|gpt-)/, "").slice(0, 17);
|
|
17258
|
+
const modelDisplay = cleanModel.padEnd(18);
|
|
17259
|
+
const tokK = `${Math.round((chat.tokens.input + chat.tokens.output) / 1e3)}k`.padStart(8);
|
|
17260
|
+
const costStr = (chat.mode === "verified" ? `$${chat.cost.toFixed(2)}` : `~$${chat.cost.toFixed(2)}`).padStart(10);
|
|
17261
|
+
printRow(`${taskDisplay} ${import_picocolors3.default.dim(modelDisplay)} ${teal(tokK)} ${coral(costStr)}`);
|
|
17262
|
+
}
|
|
17263
|
+
}
|
|
17264
|
+
printDivider("=");
|
|
17265
|
+
const totalTokK = `${Math.round((report.totalTokens.input + report.totalTokens.output) / 1e3)}k tokens`;
|
|
17266
|
+
printRowSplit("TOTAL ESTIMATED TOKENS:", green(totalTokK));
|
|
17267
|
+
printRowSplit("TOTAL ESTIMATED SPEND:", import_picocolors3.default.bold(coral(`~$${report.totalCost.toFixed(2)}`)));
|
|
17268
|
+
printDivider("=");
|
|
17269
|
+
printCenteredRow(import_picocolors3.default.dim("[\u2713] Zero code exfiltration \xB7 Telemetry calculated locally"));
|
|
17270
|
+
push(" " + import_picocolors3.default.bold(coral("\\/".repeat(36))));
|
|
17271
|
+
push("");
|
|
17272
|
+
return lines.join("\n");
|
|
17273
|
+
}
|
|
17274
|
+
function buildMarkdownChatLedger(report) {
|
|
17275
|
+
const lines = [];
|
|
17276
|
+
lines.push(`### \u{1F916} Qodewk Workspace Chat Telemetry Ledger`);
|
|
17277
|
+
lines.push(`**Repository:** \`${report.projectAlias}\` | **Window:** ${report.windowDescription} | **Total Spend:** \`~$${report.totalCost.toFixed(2)}\``);
|
|
17278
|
+
lines.push("");
|
|
17279
|
+
lines.push("| Chat / Task | Platform | Model | Steps | Tokens | Cost |");
|
|
17280
|
+
lines.push("| :--- | :--- | :--- | :--- | :--- | :--- |");
|
|
17281
|
+
for (const chat of report.chats) {
|
|
17282
|
+
const title = (chat.taskTitle || chat.sessionId).replace(/\|/g, "\\|").trim();
|
|
17283
|
+
const tokensK = `${Math.round((chat.tokens.input + chat.tokens.output) / 1e3)}k`;
|
|
17284
|
+
const cost = chat.mode === "verified" ? `$${chat.cost.toFixed(2)}` : `~$${chat.cost.toFixed(2)}`;
|
|
17285
|
+
lines.push(`| ${title} | \`${chat.platform}\` | \`${chat.model}\` | ${chat.stepsCount} | ${tokensK} | ${cost} |`);
|
|
17286
|
+
}
|
|
17287
|
+
lines.push("");
|
|
17288
|
+
lines.push(`*Total Sessions: ${report.sessionsCount} \xB7 Total Steps: ${report.totalSteps.toLocaleString()}*`);
|
|
17289
|
+
return lines.join("\n");
|
|
17290
|
+
}
|
|
17291
|
+
|
|
17113
17292
|
// src/menu.ts
|
|
17114
17293
|
var SHARE_PAYLOAD_MAX_BYTES = 5e4;
|
|
17115
17294
|
var BANNER_LINES = [
|
|
@@ -17163,6 +17342,12 @@ var MENU_ITEMS = [
|
|
|
17163
17342
|
label: "System Health & Diagnostics",
|
|
17164
17343
|
description: "Audit AI agents, Git hooks, SQLite & pricing registry (doctor)"
|
|
17165
17344
|
},
|
|
17345
|
+
{
|
|
17346
|
+
id: "chats",
|
|
17347
|
+
key: "8",
|
|
17348
|
+
label: "Workspace Chats & Cost Ledger",
|
|
17349
|
+
description: "Inspect all agent conversation sessions and model costs (chats)"
|
|
17350
|
+
},
|
|
17166
17351
|
{
|
|
17167
17352
|
id: "exit",
|
|
17168
17353
|
key: "0",
|
|
@@ -17246,7 +17431,7 @@ var SHARE_HORIZON_ITEMS = [
|
|
|
17246
17431
|
description: "Return to previous screen"
|
|
17247
17432
|
}
|
|
17248
17433
|
];
|
|
17249
|
-
function buildMenuFrame(selectedIndex, items = MENU_ITEMS, title = "Telemetry Control Panel", subtitle = "\u2191\u2193 move \xB7 enter select \xB7 0-
|
|
17434
|
+
function buildMenuFrame(selectedIndex, items = MENU_ITEMS, title = "Telemetry Control Panel", subtitle = "\u2191\u2193 move \xB7 enter select \xB7 0-8 quick jump \xB7 q quit", options = {}) {
|
|
17250
17435
|
const lines = [];
|
|
17251
17436
|
const push = (line) => lines.push(line);
|
|
17252
17437
|
if (options.showBanner ?? true) {
|
|
@@ -17257,16 +17442,16 @@ function buildMenuFrame(selectedIndex, items = MENU_ITEMS, title = "Telemetry Co
|
|
|
17257
17442
|
}
|
|
17258
17443
|
}
|
|
17259
17444
|
push("");
|
|
17260
|
-
const badge = bg.teal(
|
|
17261
|
-
push(` ${colors.mutedSoft("\u250C")} ${badge} ${
|
|
17445
|
+
const badge = bg.teal(import_picocolors4.default.bold(colors.ink(" qodewk ")));
|
|
17446
|
+
push(` ${colors.mutedSoft("\u250C")} ${badge} ${import_picocolors4.default.dim("v0.11.0")}`);
|
|
17262
17447
|
push(` ${colors.mutedSoft("\u2502")}`);
|
|
17263
17448
|
if (options.actionContext) {
|
|
17264
|
-
push(` ${colors.teal("\u25C7")} ${
|
|
17449
|
+
push(` ${colors.teal("\u25C7")} ${import_picocolors4.default.dim("Action:")} ${import_picocolors4.default.white(options.actionContext)}`);
|
|
17265
17450
|
push(` ${colors.mutedSoft("\u2502")}`);
|
|
17266
17451
|
} else {
|
|
17267
17452
|
const repo = options.repoContext?.alias || "Qodewk";
|
|
17268
17453
|
const branch = options.repoContext?.branch ? `(${options.repoContext.branch})` : "";
|
|
17269
|
-
push(` ${colors.teal("\u25C7")} ${
|
|
17454
|
+
push(` ${colors.teal("\u25C7")} ${import_picocolors4.default.dim("Repository:")} ${import_picocolors4.default.white(repo)} ${import_picocolors4.default.dim(branch)}`);
|
|
17270
17455
|
push(` ${colors.mutedSoft("\u2502")}`);
|
|
17271
17456
|
let telemetryLabel = "Multi-Model Rate Cards (Active)";
|
|
17272
17457
|
try {
|
|
@@ -17278,10 +17463,10 @@ function buildMenuFrame(selectedIndex, items = MENU_ITEMS, title = "Telemetry Co
|
|
|
17278
17463
|
}
|
|
17279
17464
|
} catch {
|
|
17280
17465
|
}
|
|
17281
|
-
push(` ${colors.teal("\u25C7")} ${
|
|
17466
|
+
push(` ${colors.teal("\u25C7")} ${import_picocolors4.default.dim("Telemetry:")} ${import_picocolors4.default.white(telemetryLabel)}`);
|
|
17282
17467
|
push(` ${colors.mutedSoft("\u2502")}`);
|
|
17283
17468
|
}
|
|
17284
|
-
push(` ${colors.coral("\u25C6")} ${
|
|
17469
|
+
push(` ${colors.coral("\u25C6")} ${import_picocolors4.default.bold(import_picocolors4.default.white(title))}`);
|
|
17285
17470
|
push(` ${colors.mutedSoft("\u2502")}`);
|
|
17286
17471
|
const selectedItem = items[selectedIndex] || items[0];
|
|
17287
17472
|
for (let i2 = 0; i2 < items.length; i2++) {
|
|
@@ -17289,44 +17474,44 @@ function buildMenuFrame(selectedIndex, items = MENU_ITEMS, title = "Telemetry Co
|
|
|
17289
17474
|
const isSelected = i2 === selectedIndex;
|
|
17290
17475
|
if (isSelected) {
|
|
17291
17476
|
push(
|
|
17292
|
-
` ${colors.mutedSoft("\u2502")} ${
|
|
17477
|
+
` ${colors.mutedSoft("\u2502")} ${import_picocolors4.default.bold(colors.coral("\u203A"))} ${import_picocolors4.default.bold(colors.coral(item.key))} ${import_picocolors4.default.bold(import_picocolors4.default.white(item.label))}`
|
|
17293
17478
|
);
|
|
17294
17479
|
} else {
|
|
17295
17480
|
push(
|
|
17296
|
-
` ${colors.mutedSoft("\u2502")} ${
|
|
17481
|
+
` ${colors.mutedSoft("\u2502")} ${import_picocolors4.default.dim(item.key)} ${import_picocolors4.default.dim(import_picocolors4.default.white(item.label))}`
|
|
17297
17482
|
);
|
|
17298
17483
|
}
|
|
17299
17484
|
}
|
|
17300
17485
|
const divider = colors.mutedSoft("\u2500".repeat(58));
|
|
17301
17486
|
push(` ${colors.mutedSoft("\u2502")}`);
|
|
17302
17487
|
push(` ${colors.mutedSoft("\u2502")} ${divider}`);
|
|
17303
|
-
push(` ${colors.mutedSoft("\u2502")} ${
|
|
17488
|
+
push(` ${colors.mutedSoft("\u2502")} ${import_picocolors4.default.bold(import_picocolors4.default.dim("Description"))}`);
|
|
17304
17489
|
push(` ${colors.mutedSoft("\u2502")} ${colors.amber(selectedItem.description)}`);
|
|
17305
17490
|
push(` ${colors.mutedSoft("\u2502")} ${divider}`);
|
|
17306
17491
|
push(` ${colors.mutedSoft("\u2502")}`);
|
|
17307
|
-
push(` ${colors.mutedSoft("\u2502")} ${
|
|
17308
|
-
push(` ${colors.mutedSoft("\u2502")} ${colors.green("[\u2713]")} ${
|
|
17492
|
+
push(` ${colors.mutedSoft("\u2502")} ${import_picocolors4.default.dim(subtitle)}`);
|
|
17493
|
+
push(` ${colors.mutedSoft("\u2502")} ${colors.green("[\u2713]")} ${import_picocolors4.default.dim("Source code was never uploaded to Qodewk")}`);
|
|
17309
17494
|
push(` ${colors.mutedSoft("\u2514")}`);
|
|
17310
17495
|
push("");
|
|
17311
17496
|
return lines.join("\n");
|
|
17312
17497
|
}
|
|
17313
17498
|
function askLine(promptText) {
|
|
17314
|
-
return new Promise((
|
|
17499
|
+
return new Promise((resolve7) => {
|
|
17315
17500
|
const rl = readline.createInterface({
|
|
17316
17501
|
input: process.stdin,
|
|
17317
17502
|
output: process.stdout
|
|
17318
17503
|
});
|
|
17319
17504
|
rl.question(promptText, (answer) => {
|
|
17320
17505
|
rl.close();
|
|
17321
|
-
|
|
17506
|
+
resolve7(answer.trim());
|
|
17322
17507
|
});
|
|
17323
17508
|
});
|
|
17324
17509
|
}
|
|
17325
17510
|
function waitForKeyToReturn() {
|
|
17326
|
-
return new Promise((
|
|
17327
|
-
console.log(
|
|
17511
|
+
return new Promise((resolve7) => {
|
|
17512
|
+
console.log(import_picocolors4.default.dim("\n Press any key or Enter to return to menu..."));
|
|
17328
17513
|
if (!process.stdin.isTTY) {
|
|
17329
|
-
|
|
17514
|
+
resolve7();
|
|
17330
17515
|
return;
|
|
17331
17516
|
}
|
|
17332
17517
|
const wasRaw = process.stdin.isRaw;
|
|
@@ -17335,16 +17520,16 @@ function waitForKeyToReturn() {
|
|
|
17335
17520
|
const onKey = () => {
|
|
17336
17521
|
process.stdin.removeListener("data", onKey);
|
|
17337
17522
|
if (wasRaw !== void 0) process.stdin.setRawMode(wasRaw);
|
|
17338
|
-
|
|
17523
|
+
resolve7();
|
|
17339
17524
|
};
|
|
17340
17525
|
process.stdin.once("data", onKey);
|
|
17341
17526
|
});
|
|
17342
17527
|
}
|
|
17343
17528
|
function waitForKeyOrAction(promptText) {
|
|
17344
|
-
return new Promise((
|
|
17529
|
+
return new Promise((resolve7) => {
|
|
17345
17530
|
console.log(promptText);
|
|
17346
17531
|
if (!process.stdin.isTTY) {
|
|
17347
|
-
|
|
17532
|
+
resolve7("");
|
|
17348
17533
|
return;
|
|
17349
17534
|
}
|
|
17350
17535
|
const wasRaw = process.stdin.isRaw;
|
|
@@ -17354,14 +17539,14 @@ function waitForKeyOrAction(promptText) {
|
|
|
17354
17539
|
process.stdin.removeListener("data", onKey);
|
|
17355
17540
|
if (wasRaw !== void 0) process.stdin.setRawMode(wasRaw);
|
|
17356
17541
|
const str = data.toString();
|
|
17357
|
-
|
|
17542
|
+
resolve7(str);
|
|
17358
17543
|
};
|
|
17359
17544
|
process.stdin.once("data", onKey);
|
|
17360
17545
|
});
|
|
17361
17546
|
}
|
|
17362
17547
|
async function publishReceiptToCloud(receipt) {
|
|
17363
17548
|
if (process.env.QODEWK_TELEMETRY === "off") {
|
|
17364
|
-
console.log(
|
|
17549
|
+
console.log(import_picocolors4.default.yellow("\n Cloud publishing is disabled by QODEWK_TELEMETRY=off."));
|
|
17365
17550
|
return null;
|
|
17366
17551
|
}
|
|
17367
17552
|
const sanitized = sanitizeReceiptForShare(receipt);
|
|
@@ -17374,11 +17559,11 @@ async function publishReceiptToCloud(receipt) {
|
|
|
17374
17559
|
body = JSON.stringify(trimmed2);
|
|
17375
17560
|
}
|
|
17376
17561
|
if (Buffer.byteLength(body, "utf-8") > SHARE_PAYLOAD_MAX_BYTES) {
|
|
17377
|
-
console.error(
|
|
17562
|
+
console.error(import_picocolors4.default.red(" Sanitized receipt still exceeds the 50 KB cloud payload limit."));
|
|
17378
17563
|
return null;
|
|
17379
17564
|
}
|
|
17380
17565
|
const endpoint = resolveApiUrl();
|
|
17381
|
-
console.log(
|
|
17566
|
+
console.log(import_picocolors4.default.dim(`
|
|
17382
17567
|
[\xB7] Publishing receipt to ${endpoint}...`));
|
|
17383
17568
|
try {
|
|
17384
17569
|
const response = await fetch(endpoint, {
|
|
@@ -17392,11 +17577,11 @@ async function publishReceiptToCloud(receipt) {
|
|
|
17392
17577
|
if (!response.ok) {
|
|
17393
17578
|
const errText = await response.text().catch(() => "");
|
|
17394
17579
|
if (response.status === 503) {
|
|
17395
|
-
console.log(
|
|
17396
|
-
console.log(
|
|
17397
|
-
console.log(
|
|
17580
|
+
console.log(import_picocolors4.default.yellow("\n Notice: Remote server requires durable storage (Supabase or PostgreSQL) in production"));
|
|
17581
|
+
console.log(import_picocolors4.default.dim(" to protect receipts from serverless cold-start data loss."));
|
|
17582
|
+
console.log(import_picocolors4.default.dim(` Endpoint: ${endpoint}`));
|
|
17398
17583
|
console.log(colors.green("\n [\u2713] Your receipt is safely saved locally in: ~/.qodewk/state.db"));
|
|
17399
|
-
console.log(
|
|
17584
|
+
console.log(import_picocolors4.default.dim(" You can also save it as a local Git note: qodewk --notes\n"));
|
|
17400
17585
|
return null;
|
|
17401
17586
|
}
|
|
17402
17587
|
throw new Error(`API responded with ${response.status}: ${errText.slice(0, 100)}`);
|
|
@@ -17407,14 +17592,14 @@ async function publishReceiptToCloud(receipt) {
|
|
|
17407
17592
|
db.close();
|
|
17408
17593
|
console.log("");
|
|
17409
17594
|
console.log(colors.green(" [\u2713] Published successfully."));
|
|
17410
|
-
console.log(` ${
|
|
17411
|
-
console.log(` ${
|
|
17412
|
-
console.log(
|
|
17595
|
+
console.log(` ${import_picocolors4.default.dim("Public URL:")} ${import_picocolors4.default.underline(import_picocolors4.default.cyan(data.url))}`);
|
|
17596
|
+
console.log(` ${import_picocolors4.default.bold(colors.amber("Claim token:"))} ${colors.amber(data.claimToken)}`);
|
|
17597
|
+
console.log(import_picocolors4.default.dim(" (Saved to ~/.qodewk/state.db for future authorship proofs)\n"));
|
|
17413
17598
|
await renderTerminalReceipt(sanitized, data.url);
|
|
17414
17599
|
return data;
|
|
17415
17600
|
} catch (err) {
|
|
17416
17601
|
const message = err instanceof Error ? err.message : String(err);
|
|
17417
|
-
console.error(
|
|
17602
|
+
console.error(import_picocolors4.default.red(`
|
|
17418
17603
|
Share failed: ${message}`));
|
|
17419
17604
|
return null;
|
|
17420
17605
|
}
|
|
@@ -17432,7 +17617,7 @@ async function getRepoContext() {
|
|
|
17432
17617
|
}
|
|
17433
17618
|
const branchSummary = await git.branch();
|
|
17434
17619
|
const branch = branchSummary.current || "HEAD";
|
|
17435
|
-
const alias =
|
|
17620
|
+
const alias = path16.basename(process.cwd());
|
|
17436
17621
|
cachedRepoContext = { alias, branch };
|
|
17437
17622
|
return cachedRepoContext;
|
|
17438
17623
|
} catch {
|
|
@@ -17443,7 +17628,7 @@ async function getRepoContext() {
|
|
|
17443
17628
|
async function runInteractiveMenu() {
|
|
17444
17629
|
if (!process.stdin.isTTY) {
|
|
17445
17630
|
console.log(buildMenuFrame(0));
|
|
17446
|
-
console.log(
|
|
17631
|
+
console.log(import_picocolors4.default.yellow("Interactive menu requires a TTY terminal. Use `qodewk --help` for commands."));
|
|
17447
17632
|
return;
|
|
17448
17633
|
}
|
|
17449
17634
|
const repoContext = await getRepoContext();
|
|
@@ -17500,15 +17685,15 @@ async function runInteractiveMenu() {
|
|
|
17500
17685
|
since = "7d";
|
|
17501
17686
|
label = "past 7 days weekly sprint (--since 7d)";
|
|
17502
17687
|
} else if (item.id === "custom") {
|
|
17503
|
-
console.log(
|
|
17504
|
-
console.log(
|
|
17688
|
+
console.log(import_picocolors4.default.bold(import_picocolors4.default.white(" Custom Telemetry Horizon")));
|
|
17689
|
+
console.log(import_picocolors4.default.dim(" \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\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500"));
|
|
17505
17690
|
const input = await askLine(" \u203A Enter duration or date (e.g. 12h, 3d, 2026-10-01): ");
|
|
17506
17691
|
if (input) {
|
|
17507
17692
|
since = input;
|
|
17508
17693
|
label = `custom range: ${input}`;
|
|
17509
17694
|
}
|
|
17510
17695
|
}
|
|
17511
|
-
console.log(
|
|
17696
|
+
console.log(import_picocolors4.default.dim(` [\xB7] Generating local receipt for ${label}...`));
|
|
17512
17697
|
try {
|
|
17513
17698
|
const receipt = await generateReceipt({ since, isPublic: false });
|
|
17514
17699
|
const db = new LocalStateDB();
|
|
@@ -17517,7 +17702,7 @@ async function runInteractiveMenu() {
|
|
|
17517
17702
|
await renderTerminalReceipt(receipt);
|
|
17518
17703
|
console.log("");
|
|
17519
17704
|
const actionKey = await waitForKeyOrAction(
|
|
17520
|
-
` ${colors.coral("[s]")} ${
|
|
17705
|
+
` ${colors.coral("[s]")} ${import_picocolors4.default.white("Publish this receipt to cloud")} \xB7 ${import_picocolors4.default.dim("[any other key] Return to menu")}`
|
|
17521
17706
|
);
|
|
17522
17707
|
if (actionKey.trim().toLowerCase() === "s") {
|
|
17523
17708
|
await publishReceiptToCloud(receipt);
|
|
@@ -17525,7 +17710,7 @@ async function runInteractiveMenu() {
|
|
|
17525
17710
|
}
|
|
17526
17711
|
} catch (err) {
|
|
17527
17712
|
const message = err instanceof Error ? err.message : String(err);
|
|
17528
|
-
console.error(
|
|
17713
|
+
console.error(import_picocolors4.default.red(`
|
|
17529
17714
|
Failed to generate receipt: ${message}`));
|
|
17530
17715
|
await waitForKeyToReturn();
|
|
17531
17716
|
}
|
|
@@ -17548,21 +17733,21 @@ async function runInteractiveMenu() {
|
|
|
17548
17733
|
since = "7d";
|
|
17549
17734
|
label = "past 7 days weekly sprint (--since 7d)";
|
|
17550
17735
|
} else if (item.id === "custom") {
|
|
17551
|
-
console.log(
|
|
17552
|
-
console.log(
|
|
17736
|
+
console.log(import_picocolors4.default.bold(import_picocolors4.default.white(" Custom Telemetry Horizon for Cloud Publish")));
|
|
17737
|
+
console.log(import_picocolors4.default.dim(" \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\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500"));
|
|
17553
17738
|
const input = await askLine(" \u203A Enter duration or date (e.g. 12h, 3d, 2026-10-01): ");
|
|
17554
17739
|
if (input) {
|
|
17555
17740
|
since = input;
|
|
17556
17741
|
label = `custom range: ${input}`;
|
|
17557
17742
|
}
|
|
17558
17743
|
}
|
|
17559
|
-
console.log(
|
|
17744
|
+
console.log(import_picocolors4.default.dim(` [\xB7] Generating and publishing receipt for ${label}...`));
|
|
17560
17745
|
try {
|
|
17561
17746
|
const receipt = await generateReceipt({ since, isPublic: false });
|
|
17562
17747
|
await publishReceiptToCloud(receipt);
|
|
17563
17748
|
} catch (err) {
|
|
17564
17749
|
const message = err instanceof Error ? err.message : String(err);
|
|
17565
|
-
console.error(
|
|
17750
|
+
console.error(import_picocolors4.default.red(`
|
|
17566
17751
|
Share failed: ${message}`));
|
|
17567
17752
|
}
|
|
17568
17753
|
await waitForKeyToReturn();
|
|
@@ -17576,8 +17761,8 @@ async function runInteractiveMenu() {
|
|
|
17576
17761
|
const selectedItem = MENU_ITEMS[selectedIndex];
|
|
17577
17762
|
switch (selectedItem.id) {
|
|
17578
17763
|
case "audit": {
|
|
17579
|
-
console.log(
|
|
17580
|
-
console.log(
|
|
17764
|
+
console.log(import_picocolors4.default.bold(import_picocolors4.default.white("\n Audit Branch or Revision Diff")));
|
|
17765
|
+
console.log(import_picocolors4.default.dim(" \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\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500"));
|
|
17581
17766
|
let defaultBase = "origin/main";
|
|
17582
17767
|
try {
|
|
17583
17768
|
defaultBase = await detectDefaultBaseBranch(process.cwd());
|
|
@@ -17589,7 +17774,7 @@ async function runInteractiveMenu() {
|
|
|
17589
17774
|
const head = await askLine(
|
|
17590
17775
|
` \u203A Head git ref or commit SHA [default: HEAD]: `
|
|
17591
17776
|
);
|
|
17592
|
-
console.log(
|
|
17777
|
+
console.log(import_picocolors4.default.dim("\n [\xB7] Auditing git revision range..."));
|
|
17593
17778
|
try {
|
|
17594
17779
|
const receipt = await generateReceipt({
|
|
17595
17780
|
baseSha: base || defaultBase,
|
|
@@ -17602,7 +17787,7 @@ async function runInteractiveMenu() {
|
|
|
17602
17787
|
await renderTerminalReceipt(receipt);
|
|
17603
17788
|
} catch (err) {
|
|
17604
17789
|
const message = err instanceof Error ? err.message : String(err);
|
|
17605
|
-
console.error(
|
|
17790
|
+
console.error(import_picocolors4.default.red(`
|
|
17606
17791
|
Audit failed: ${message}`));
|
|
17607
17792
|
}
|
|
17608
17793
|
await waitForKeyToReturn();
|
|
@@ -17629,10 +17814,14 @@ async function runInteractiveMenu() {
|
|
|
17629
17814
|
await runDoctorDiagnosticsAction();
|
|
17630
17815
|
break;
|
|
17631
17816
|
}
|
|
17817
|
+
case "chats": {
|
|
17818
|
+
await showChatsAction();
|
|
17819
|
+
break;
|
|
17820
|
+
}
|
|
17632
17821
|
case "exit": {
|
|
17633
17822
|
active = false;
|
|
17634
17823
|
cleanup();
|
|
17635
|
-
console.log(
|
|
17824
|
+
console.log(import_picocolors4.default.dim(" Exited Qodewk.\n"));
|
|
17636
17825
|
process.exit(0);
|
|
17637
17826
|
return;
|
|
17638
17827
|
}
|
|
@@ -17641,19 +17830,19 @@ async function runInteractiveMenu() {
|
|
|
17641
17830
|
const manageHooksSubmenu = async () => {
|
|
17642
17831
|
const hooksDir = resolveGitHooksDir();
|
|
17643
17832
|
const status = checkHookStatus(hooksDir);
|
|
17644
|
-
console.log(
|
|
17645
|
-
console.log(
|
|
17833
|
+
console.log(import_picocolors4.default.bold(import_picocolors4.default.white("\n Qodewk Git Hooks Management")));
|
|
17834
|
+
console.log(import_picocolors4.default.dim(" \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\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500"));
|
|
17646
17835
|
if (!status.isGit) {
|
|
17647
|
-
console.log(
|
|
17836
|
+
console.log(import_picocolors4.default.yellow(" Not inside a Git repository. Hooks cannot be configured."));
|
|
17648
17837
|
await waitForKeyToReturn();
|
|
17649
17838
|
return;
|
|
17650
17839
|
}
|
|
17651
|
-
console.log(` Hooks directory: ${
|
|
17840
|
+
console.log(` Hooks directory: ${import_picocolors4.default.dim(status.hooksDir || "None")}`);
|
|
17652
17841
|
console.log(
|
|
17653
|
-
` post-commit: ${status.postCommitInstalled ? colors.green("[\u2713 Installed]") :
|
|
17842
|
+
` post-commit: ${status.postCommitInstalled ? colors.green("[\u2713 Installed]") : import_picocolors4.default.dim("[\xB7 Not installed]")}`
|
|
17654
17843
|
);
|
|
17655
17844
|
console.log(
|
|
17656
|
-
` post-rewrite: ${status.postRewriteInstalled ? colors.green("[\u2713 Installed]") :
|
|
17845
|
+
` post-rewrite: ${status.postRewriteInstalled ? colors.green("[\u2713 Installed]") : import_picocolors4.default.dim("[\xB7 Not installed]")}`
|
|
17657
17846
|
);
|
|
17658
17847
|
console.log("");
|
|
17659
17848
|
console.log(" [1] Install non-blocking hooks (< 5ms background recorder)");
|
|
@@ -17666,7 +17855,7 @@ async function runInteractiveMenu() {
|
|
|
17666
17855
|
if (status.hooksDir) {
|
|
17667
17856
|
const targets = ["post-commit", "post-rewrite"];
|
|
17668
17857
|
for (const t2 of targets) {
|
|
17669
|
-
installHookFile(
|
|
17858
|
+
installHookFile(path16.join(status.hooksDir, t2));
|
|
17670
17859
|
}
|
|
17671
17860
|
console.log(colors.green("\n [\u2713] Non-blocking hooks installed successfully."));
|
|
17672
17861
|
}
|
|
@@ -17674,7 +17863,7 @@ async function runInteractiveMenu() {
|
|
|
17674
17863
|
if (status.hooksDir) {
|
|
17675
17864
|
const targets = ["post-commit", "post-rewrite"];
|
|
17676
17865
|
for (const t2 of targets) {
|
|
17677
|
-
uninstallHookFile(
|
|
17866
|
+
uninstallHookFile(path16.join(status.hooksDir, t2));
|
|
17678
17867
|
}
|
|
17679
17868
|
console.log(colors.green("\n [\u2713] Qodewk hooks removed."));
|
|
17680
17869
|
}
|
|
@@ -17686,8 +17875,8 @@ async function runInteractiveMenu() {
|
|
|
17686
17875
|
await waitForKeyToReturn();
|
|
17687
17876
|
};
|
|
17688
17877
|
const manageGitNotesSubmenu = async () => {
|
|
17689
|
-
console.log(
|
|
17690
|
-
console.log(
|
|
17878
|
+
console.log(import_picocolors4.default.bold(import_picocolors4.default.white("\n Qodewk Git Notes Management (refs/notes/qodewk)")));
|
|
17879
|
+
console.log(import_picocolors4.default.dim(" \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\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500"));
|
|
17691
17880
|
console.log(" [1] List commits with attached Qodewk notes");
|
|
17692
17881
|
console.log(" [2] Show receipt note on a commit (default: HEAD)");
|
|
17693
17882
|
console.log(" [3] Attach receipt note to a Git commit (default: HEAD)");
|
|
@@ -17698,17 +17887,17 @@ async function runInteractiveMenu() {
|
|
|
17698
17887
|
try {
|
|
17699
17888
|
const shas = await listGitReceiptNotes();
|
|
17700
17889
|
if (shas.length === 0) {
|
|
17701
|
-
console.log(
|
|
17890
|
+
console.log(import_picocolors4.default.yellow("\n No Qodewk Git notes found in repository."));
|
|
17702
17891
|
} else {
|
|
17703
|
-
console.log(
|
|
17892
|
+
console.log(import_picocolors4.default.bold(`
|
|
17704
17893
|
Found ${shas.length} commit note(s) in refs/notes/qodewk:`));
|
|
17705
17894
|
for (const sha of shas) {
|
|
17706
|
-
console.log(` ${
|
|
17895
|
+
console.log(` ${import_picocolors4.default.cyan(sha.slice(0, 10))} ${import_picocolors4.default.dim(sha)}`);
|
|
17707
17896
|
}
|
|
17708
17897
|
}
|
|
17709
17898
|
} catch (err) {
|
|
17710
17899
|
const message = err instanceof Error ? err.message : String(err);
|
|
17711
|
-
console.error(
|
|
17900
|
+
console.error(import_picocolors4.default.red(`
|
|
17712
17901
|
Error listing Git notes: ${message}`));
|
|
17713
17902
|
}
|
|
17714
17903
|
} else if (choice === "2") {
|
|
@@ -17716,20 +17905,20 @@ async function runInteractiveMenu() {
|
|
|
17716
17905
|
try {
|
|
17717
17906
|
const receipt = await readGitReceiptNote(commit);
|
|
17718
17907
|
if (!receipt) {
|
|
17719
|
-
console.log(
|
|
17908
|
+
console.log(import_picocolors4.default.yellow(`
|
|
17720
17909
|
No Qodewk receipt note found on commit '${commit}'.`));
|
|
17721
17910
|
} else {
|
|
17722
17911
|
await renderTerminalReceipt(receipt);
|
|
17723
17912
|
}
|
|
17724
17913
|
} catch (err) {
|
|
17725
17914
|
const message = err instanceof Error ? err.message : String(err);
|
|
17726
|
-
console.error(
|
|
17915
|
+
console.error(import_picocolors4.default.red(`
|
|
17727
17916
|
Error reading Git note: ${message}`));
|
|
17728
17917
|
}
|
|
17729
17918
|
} else if (choice === "3") {
|
|
17730
17919
|
const commit = await askLine(" \u203A Commit SHA to attach note [default: HEAD]: ") || "HEAD";
|
|
17731
17920
|
try {
|
|
17732
|
-
console.log(
|
|
17921
|
+
console.log(import_picocolors4.default.dim(`
|
|
17733
17922
|
[\xB7] Generating receipt for ${commit}...`));
|
|
17734
17923
|
const receipt = await generateReceipt({ headSha: commit });
|
|
17735
17924
|
await writeGitReceiptNote(receipt.repository.headSha, receipt);
|
|
@@ -17739,30 +17928,30 @@ async function runInteractiveMenu() {
|
|
|
17739
17928
|
);
|
|
17740
17929
|
} catch (err) {
|
|
17741
17930
|
const message = err instanceof Error ? err.message : String(err);
|
|
17742
|
-
console.error(
|
|
17931
|
+
console.error(import_picocolors4.default.red(`
|
|
17743
17932
|
Error writing Git note: ${message}`));
|
|
17744
17933
|
}
|
|
17745
17934
|
}
|
|
17746
17935
|
await waitForKeyToReturn();
|
|
17747
17936
|
};
|
|
17748
17937
|
const showStorageStatus = async () => {
|
|
17749
|
-
console.log(
|
|
17750
|
-
console.log(
|
|
17938
|
+
console.log(import_picocolors4.default.bold(import_picocolors4.default.white("\n Qodewk Local Database & Storage Status")));
|
|
17939
|
+
console.log(import_picocolors4.default.dim(" \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\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500"));
|
|
17751
17940
|
try {
|
|
17752
17941
|
const db = new LocalStateDB();
|
|
17753
17942
|
const stats = db.getStats();
|
|
17754
17943
|
const recent = db.getRecentReceipts(5);
|
|
17755
17944
|
db.close();
|
|
17756
|
-
console.log(` Database path: ${
|
|
17757
|
-
console.log(` Total saved receipts: ${
|
|
17758
|
-
console.log(` Total agent footprints: ${
|
|
17945
|
+
console.log(` Database path: ${import_picocolors4.default.dim("~/.qodewk/state.db")}`);
|
|
17946
|
+
console.log(` Total saved receipts: ${import_picocolors4.default.bold(import_picocolors4.default.white(String(stats.totalReceipts)))}`);
|
|
17947
|
+
console.log(` Total agent footprints: ${import_picocolors4.default.bold(import_picocolors4.default.white(String(stats.totalFootprints)))}`);
|
|
17759
17948
|
console.log("");
|
|
17760
17949
|
if (recent.length === 0) {
|
|
17761
|
-
console.log(
|
|
17950
|
+
console.log(import_picocolors4.default.dim(" No stored receipts yet. Run 'Generate Local Receipt' to record your first."));
|
|
17762
17951
|
} else {
|
|
17763
|
-
console.log(
|
|
17764
|
-
console.log(
|
|
17765
|
-
console.log(
|
|
17952
|
+
console.log(import_picocolors4.default.dim(" Recent Receipts:"));
|
|
17953
|
+
console.log(import_picocolors4.default.dim(" " + "ID".padEnd(26) + "DATE".padEnd(12) + "BRANCH".padEnd(18) + "COST"));
|
|
17954
|
+
console.log(import_picocolors4.default.dim(" " + "\u2500".repeat(60)));
|
|
17766
17955
|
for (const item of recent) {
|
|
17767
17956
|
const id = item.receipt.receipt.id.slice(0, 24).padEnd(26);
|
|
17768
17957
|
const date = item.receipt.receipt.createdAt.slice(0, 10).padEnd(12);
|
|
@@ -17772,7 +17961,7 @@ async function runInteractiveMenu() {
|
|
|
17772
17961
|
}
|
|
17773
17962
|
}
|
|
17774
17963
|
console.log("");
|
|
17775
|
-
console.log(` ${colors.green("[\u2713]")} ${
|
|
17964
|
+
console.log(` ${colors.green("[\u2713]")} ${import_picocolors4.default.dim("Privacy guarantee: raw source code is never stored in SQLite")}`);
|
|
17776
17965
|
if (recent.length > 0) {
|
|
17777
17966
|
console.log("");
|
|
17778
17967
|
const ans = await askLine(" \u203A Enter receipt ID prefix to publish to cloud [Enter to return]: ");
|
|
@@ -17783,26 +17972,41 @@ async function runInteractiveMenu() {
|
|
|
17783
17972
|
await waitForKeyToReturn();
|
|
17784
17973
|
return;
|
|
17785
17974
|
} else {
|
|
17786
|
-
console.log(
|
|
17975
|
+
console.log(import_picocolors4.default.yellow(` No stored receipt matching '${ans}' found.`));
|
|
17787
17976
|
}
|
|
17788
17977
|
}
|
|
17789
17978
|
}
|
|
17790
17979
|
} catch (err) {
|
|
17791
17980
|
const message = err instanceof Error ? err.message : String(err);
|
|
17792
|
-
console.error(
|
|
17981
|
+
console.error(import_picocolors4.default.red(` Failed to inspect storage: ${message}`));
|
|
17793
17982
|
}
|
|
17794
17983
|
await waitForKeyToReturn();
|
|
17795
17984
|
};
|
|
17796
17985
|
const runDoctorDiagnosticsAction = async () => {
|
|
17797
|
-
console.log(
|
|
17798
|
-
console.log(
|
|
17799
|
-
console.log(
|
|
17986
|
+
console.log(import_picocolors4.default.bold(import_picocolors4.default.white("\n Qodewk System Health & Diagnostics (Doctor)")));
|
|
17987
|
+
console.log(import_picocolors4.default.dim(" \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\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500"));
|
|
17988
|
+
console.log(import_picocolors4.default.dim(" [\xB7] Running diagnostic audit across agents, hooks, storage, and pricing...\n"));
|
|
17800
17989
|
try {
|
|
17801
17990
|
const report = await runDiagnostics();
|
|
17802
17991
|
console.log(formatDoctorReport(report));
|
|
17803
17992
|
} catch (err) {
|
|
17804
17993
|
const message = err instanceof Error ? err.message : String(err);
|
|
17805
|
-
console.error(
|
|
17994
|
+
console.error(import_picocolors4.default.red(` Diagnostic check failed: ${message}`));
|
|
17995
|
+
}
|
|
17996
|
+
await waitForKeyToReturn();
|
|
17997
|
+
};
|
|
17998
|
+
const showChatsAction = async () => {
|
|
17999
|
+
console.log(import_picocolors4.default.bold(import_picocolors4.default.white("\n Qodewk Workspace Chat Telemetry & Cost Ledger")));
|
|
18000
|
+
console.log(import_picocolors4.default.dim(" \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\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500"));
|
|
18001
|
+
console.log(import_picocolors4.default.dim(" [\xB7] Scanning local IDE transcripts (Antigravity, Cursor, Claude, Windsurf, Cline)...\n"));
|
|
18002
|
+
try {
|
|
18003
|
+
const report = await listProjectChats({
|
|
18004
|
+
repoPath: process.cwd()
|
|
18005
|
+
});
|
|
18006
|
+
console.log(buildTerminalChatLedger(report));
|
|
18007
|
+
} catch (err) {
|
|
18008
|
+
const message = err instanceof Error ? err.message : String(err);
|
|
18009
|
+
console.error(import_picocolors4.default.red(` Failed to inspect workspace chats: ${message}`));
|
|
17806
18010
|
}
|
|
17807
18011
|
await waitForKeyToReturn();
|
|
17808
18012
|
};
|
|
@@ -17827,7 +18031,7 @@ async function runInteractiveMenu() {
|
|
|
17827
18031
|
return;
|
|
17828
18032
|
}
|
|
17829
18033
|
cleanup();
|
|
17830
|
-
console.log(
|
|
18034
|
+
console.log(import_picocolors4.default.dim("\n Exited Qodewk.\n"));
|
|
17831
18035
|
process.exit(0);
|
|
17832
18036
|
}
|
|
17833
18037
|
if (key.name === "up" || key.name === "k") {
|
|
@@ -17840,7 +18044,9 @@ async function runInteractiveMenu() {
|
|
|
17840
18044
|
render();
|
|
17841
18045
|
return;
|
|
17842
18046
|
}
|
|
17843
|
-
const itemByKey = items.findIndex(
|
|
18047
|
+
const itemByKey = items.findIndex(
|
|
18048
|
+
(item) => item.key === key.name || item.key === _str || _str && _str.toLowerCase() === "c" && item.id === "chats"
|
|
18049
|
+
);
|
|
17844
18050
|
if (itemByKey !== -1) {
|
|
17845
18051
|
selectedIndex = itemByKey;
|
|
17846
18052
|
render();
|
|
@@ -17932,10 +18138,10 @@ loadQodewkEnv();
|
|
|
17932
18138
|
var SHARE_PAYLOAD_MAX_BYTES2 = 5e4;
|
|
17933
18139
|
function resolveCliVersion() {
|
|
17934
18140
|
try {
|
|
17935
|
-
const argv1 = process.argv[1] ?
|
|
18141
|
+
const argv1 = process.argv[1] ? path17.dirname(path17.resolve(process.argv[1])) : process.cwd();
|
|
17936
18142
|
const candidates = [
|
|
17937
|
-
|
|
17938
|
-
|
|
18143
|
+
path17.join(argv1, "..", "package.json"),
|
|
18144
|
+
path17.join(argv1, "package.json")
|
|
17939
18145
|
];
|
|
17940
18146
|
for (const candidate of candidates) {
|
|
17941
18147
|
if (!fs15.existsSync(candidate)) continue;
|
|
@@ -17944,7 +18150,7 @@ function resolveCliVersion() {
|
|
|
17944
18150
|
}
|
|
17945
18151
|
} catch {
|
|
17946
18152
|
}
|
|
17947
|
-
return "0.
|
|
18153
|
+
return "0.11.0";
|
|
17948
18154
|
}
|
|
17949
18155
|
function resolveSince(options) {
|
|
17950
18156
|
return options.today ? "today" : options.since;
|
|
@@ -17982,21 +18188,44 @@ program2.name("qodewk").description("Universal telemetry and digital receipt gen
|
|
|
17982
18188
|
if (options.notes) {
|
|
17983
18189
|
try {
|
|
17984
18190
|
await writeGitReceiptNote(receipt.repository.headSha, receipt);
|
|
17985
|
-
console.log(
|
|
18191
|
+
console.log(import_picocolors5.default.green(`\u2713 Attached receipt note to ${receipt.repository.headSha.slice(0, 7)} (refs/notes/qodewk)`));
|
|
17986
18192
|
} catch (noteErr) {
|
|
17987
|
-
console.warn(
|
|
18193
|
+
console.warn(import_picocolors5.default.yellow(`Warning: Could not write Git note: ${noteErr.message}`));
|
|
17988
18194
|
}
|
|
17989
18195
|
}
|
|
17990
18196
|
await outputReceipt(receipt, options);
|
|
17991
18197
|
} catch (err) {
|
|
17992
18198
|
const message = err instanceof Error ? err.message : String(err);
|
|
17993
|
-
console.error(
|
|
18199
|
+
console.error(import_picocolors5.default.red(`Error generating receipt: ${message}`));
|
|
17994
18200
|
process.exit(1);
|
|
17995
18201
|
}
|
|
17996
18202
|
});
|
|
17997
18203
|
program2.command("menu").description("Launch interactive terminal control panel").action(async () => {
|
|
17998
18204
|
await runInteractiveMenu();
|
|
17999
18205
|
});
|
|
18206
|
+
program2.command("chats").description("Inspect AI chat sessions and model cost ledger for current workspace").option("-s, --since <duration>", "Filter chats since duration (e.g. today, 24h, 7d, 30d)").option("--today", "Filter chats for today").option("--all", "Show all-time workspace chats (bypass 30-day default window)").option("-p, --platform <platform>", "Filter agent platform (antigravity, claude, cursor, etc.)").option("-j, --json", "Output chat telemetry report in machine-readable JSON format").option("-f, --format <format>", "Output format (terminal, json, markdown)", "terminal").action(async (options) => {
|
|
18207
|
+
try {
|
|
18208
|
+
const since = options.today ? "today" : options.since;
|
|
18209
|
+
const report = await listProjectChats({
|
|
18210
|
+
repoPath: process.cwd(),
|
|
18211
|
+
since,
|
|
18212
|
+
platform: options.platform,
|
|
18213
|
+
all: options.all
|
|
18214
|
+
});
|
|
18215
|
+
const isJson = Boolean(options.json || program2.opts().json || options.format === "json");
|
|
18216
|
+
if (isJson) {
|
|
18217
|
+
console.log(JSON.stringify(report, null, 2));
|
|
18218
|
+
} else if (options.format === "markdown") {
|
|
18219
|
+
console.log(buildMarkdownChatLedger(report));
|
|
18220
|
+
} else {
|
|
18221
|
+
console.log(buildTerminalChatLedger(report));
|
|
18222
|
+
}
|
|
18223
|
+
} catch (err) {
|
|
18224
|
+
const message = err instanceof Error ? err.message : String(err);
|
|
18225
|
+
console.error(import_picocolors5.default.red(`Error listing workspace chats: ${message}`));
|
|
18226
|
+
process.exit(1);
|
|
18227
|
+
}
|
|
18228
|
+
});
|
|
18000
18229
|
program2.command("doctor").description("Run complete diagnostic health check of AI agents, git hooks, and local telemetry").option("-j, --json", "Output diagnostic report in machine-readable JSON format").action(async (options) => {
|
|
18001
18230
|
try {
|
|
18002
18231
|
const isJson = Boolean(options.json || program2.opts().json);
|
|
@@ -18011,7 +18240,7 @@ program2.command("doctor").description("Run complete diagnostic health check of
|
|
|
18011
18240
|
}
|
|
18012
18241
|
} catch (err) {
|
|
18013
18242
|
const message = err instanceof Error ? err.message : String(err);
|
|
18014
|
-
console.error(
|
|
18243
|
+
console.error(import_picocolors5.default.red(`Error running diagnostics: ${message}`));
|
|
18015
18244
|
process.exit(1);
|
|
18016
18245
|
}
|
|
18017
18246
|
});
|
|
@@ -18031,7 +18260,7 @@ program2.command("audit").description("Audit PR or branch diff against a target
|
|
|
18031
18260
|
await outputReceipt(receipt, options);
|
|
18032
18261
|
} catch (err) {
|
|
18033
18262
|
const message = err instanceof Error ? err.message : String(err);
|
|
18034
|
-
console.error(
|
|
18263
|
+
console.error(import_picocolors5.default.red(`Error auditing git range: ${message}`));
|
|
18035
18264
|
process.exit(1);
|
|
18036
18265
|
}
|
|
18037
18266
|
});
|
|
@@ -18048,12 +18277,12 @@ program2.command("share").description("Publish privacy-safe receipt to Qodewk cl
|
|
|
18048
18277
|
const localFlag = program2.opts().local === true;
|
|
18049
18278
|
if (process.env.QODEWK_TELEMETRY === "off" || localFlag) {
|
|
18050
18279
|
console.log(
|
|
18051
|
-
|
|
18280
|
+
import_picocolors5.default.yellow(
|
|
18052
18281
|
`
|
|
18053
18282
|
Cloud publishing is disabled (${localFlag ? "--local" : "QODEWK_TELEMETRY=off"}).`
|
|
18054
18283
|
)
|
|
18055
18284
|
);
|
|
18056
|
-
console.log(
|
|
18285
|
+
console.log(import_picocolors5.default.dim("Telemetry remains strictly stored in local SQLite (~/.qodewk/state.db).\n"));
|
|
18057
18286
|
persistReceipt(receipt);
|
|
18058
18287
|
await renderTerminalReceipt(receipt);
|
|
18059
18288
|
return;
|
|
@@ -18068,11 +18297,11 @@ Cloud publishing is disabled (${localFlag ? "--local" : "QODEWK_TELEMETRY=off"})
|
|
|
18068
18297
|
body = JSON.stringify(trimmed2);
|
|
18069
18298
|
}
|
|
18070
18299
|
if (Buffer.byteLength(body, "utf-8") > SHARE_PAYLOAD_MAX_BYTES2) {
|
|
18071
|
-
console.error(
|
|
18300
|
+
console.error(import_picocolors5.default.red("Sanitized receipt still exceeds the 50 KB cloud payload limit."));
|
|
18072
18301
|
process.exit(1);
|
|
18073
18302
|
}
|
|
18074
18303
|
const endpoint = resolveApiUrl();
|
|
18075
|
-
console.log(
|
|
18304
|
+
console.log(import_picocolors5.default.dim(`Publishing receipt ${sanitized.receipt.id} to ${endpoint}...`));
|
|
18076
18305
|
try {
|
|
18077
18306
|
const response = await fetch(endpoint, {
|
|
18078
18307
|
method: "POST",
|
|
@@ -18089,11 +18318,11 @@ Cloud publishing is disabled (${localFlag ? "--local" : "QODEWK_TELEMETRY=off"})
|
|
|
18089
18318
|
const data = await response.json();
|
|
18090
18319
|
persistReceipt(sanitized, data.claimToken);
|
|
18091
18320
|
console.log("");
|
|
18092
|
-
console.log(
|
|
18093
|
-
console.log(` ${
|
|
18094
|
-
console.log(` ${
|
|
18095
|
-
console.log(` ${
|
|
18096
|
-
console.log(
|
|
18321
|
+
console.log(import_picocolors5.default.green(" Published successfully."));
|
|
18322
|
+
console.log(` ${import_picocolors5.default.dim("Public URL:")} ${import_picocolors5.default.underline(import_picocolors5.default.cyan(data.url))}`);
|
|
18323
|
+
console.log(` ${import_picocolors5.default.bold(import_picocolors5.default.yellow(" Claim token (store securely \u2014 shown once):"))}`);
|
|
18324
|
+
console.log(` ${import_picocolors5.default.yellow(data.claimToken)}`);
|
|
18325
|
+
console.log(import_picocolors5.default.dim(" Saved to ~/.qodewk/state.db \u2014 required to prove authorship later."));
|
|
18097
18326
|
console.log("");
|
|
18098
18327
|
await renderTerminalReceipt(sanitized, data.url);
|
|
18099
18328
|
if (options.json) {
|
|
@@ -18101,14 +18330,14 @@ Cloud publishing is disabled (${localFlag ? "--local" : "QODEWK_TELEMETRY=off"})
|
|
|
18101
18330
|
}
|
|
18102
18331
|
} catch (networkErr) {
|
|
18103
18332
|
const message = networkErr instanceof Error ? networkErr.message : String(networkErr);
|
|
18104
|
-
console.log(
|
|
18333
|
+
console.log(import_picocolors5.default.yellow(`
|
|
18105
18334
|
Could not reach cloud API (${message}). Rendered locally:`));
|
|
18106
18335
|
persistReceipt(receipt);
|
|
18107
18336
|
await renderTerminalReceipt(receipt);
|
|
18108
18337
|
}
|
|
18109
18338
|
} catch (err) {
|
|
18110
18339
|
const message = err instanceof Error ? err.message : String(err);
|
|
18111
|
-
console.error(
|
|
18340
|
+
console.error(import_picocolors5.default.red(`Error sharing receipt: ${message}`));
|
|
18112
18341
|
process.exit(1);
|
|
18113
18342
|
}
|
|
18114
18343
|
});
|
|
@@ -18126,7 +18355,7 @@ hookCommand.command("install").description("Install non-blocking post-commit and
|
|
|
18126
18355
|
try {
|
|
18127
18356
|
const hooksDir = resolveGitHooksDir();
|
|
18128
18357
|
if (!hooksDir) {
|
|
18129
|
-
console.error(
|
|
18358
|
+
console.error(import_picocolors5.default.red("Error: Current directory is not a Git repository (.git not found)."));
|
|
18130
18359
|
process.exit(1);
|
|
18131
18360
|
}
|
|
18132
18361
|
if (!fs15.existsSync(hooksDir)) {
|
|
@@ -18136,25 +18365,25 @@ hookCommand.command("install").description("Install non-blocking post-commit and
|
|
|
18136
18365
|
let installed = 0;
|
|
18137
18366
|
let existing = 0;
|
|
18138
18367
|
for (const name of targets) {
|
|
18139
|
-
const result = installHookFile(
|
|
18368
|
+
const result = installHookFile(path17.join(hooksDir, name));
|
|
18140
18369
|
if (result === "installed") installed++;
|
|
18141
18370
|
else existing++;
|
|
18142
18371
|
}
|
|
18143
18372
|
if (installed === 0 && existing > 0) {
|
|
18144
|
-
console.log(
|
|
18373
|
+
console.log(import_picocolors5.default.yellow("Qodewk Git hooks are already installed (post-commit, post-rewrite)."));
|
|
18145
18374
|
return;
|
|
18146
18375
|
}
|
|
18147
18376
|
console.log(
|
|
18148
|
-
|
|
18377
|
+
import_picocolors5.default.green(
|
|
18149
18378
|
`\u2713 Non-blocking Qodewk hooks installed in ${hooksDir} (post-commit${installed > 1 || existing > 0 ? ", post-rewrite" : installed === 1 && targets.length === 2 ? " + post-rewrite" : ""})`
|
|
18150
18379
|
)
|
|
18151
18380
|
);
|
|
18152
18381
|
if (existing > 0) {
|
|
18153
|
-
console.log(
|
|
18382
|
+
console.log(import_picocolors5.default.dim(` (${existing} hook file(s) already contained the Qodewk marker)`));
|
|
18154
18383
|
}
|
|
18155
18384
|
} catch (err) {
|
|
18156
18385
|
const message = err instanceof Error ? err.message : String(err);
|
|
18157
|
-
console.error(
|
|
18386
|
+
console.error(import_picocolors5.default.red(`Failed to install Git hook: ${message}`));
|
|
18158
18387
|
process.exit(1);
|
|
18159
18388
|
}
|
|
18160
18389
|
});
|
|
@@ -18162,23 +18391,23 @@ hookCommand.command("uninstall").description("Remove Qodewk post-commit and post
|
|
|
18162
18391
|
try {
|
|
18163
18392
|
const hooksDir = resolveGitHooksDir();
|
|
18164
18393
|
if (!hooksDir) {
|
|
18165
|
-
console.log(
|
|
18394
|
+
console.log(import_picocolors5.default.yellow("No Git repository found."));
|
|
18166
18395
|
return;
|
|
18167
18396
|
}
|
|
18168
18397
|
const targets = ["post-commit", "post-rewrite"];
|
|
18169
18398
|
let removed = 0;
|
|
18170
18399
|
for (const name of targets) {
|
|
18171
|
-
const result = uninstallHookFile(
|
|
18400
|
+
const result = uninstallHookFile(path17.join(hooksDir, name));
|
|
18172
18401
|
if (result === "removed") removed++;
|
|
18173
18402
|
}
|
|
18174
18403
|
if (removed === 0) {
|
|
18175
|
-
console.log(
|
|
18404
|
+
console.log(import_picocolors5.default.yellow("Qodewk hooks are not installed."));
|
|
18176
18405
|
return;
|
|
18177
18406
|
}
|
|
18178
|
-
console.log(
|
|
18407
|
+
console.log(import_picocolors5.default.green(`\u2713 Qodewk hook markers removed from ${removed} file(s).`));
|
|
18179
18408
|
} catch (err) {
|
|
18180
18409
|
const message = err instanceof Error ? err.message : String(err);
|
|
18181
|
-
console.error(
|
|
18410
|
+
console.error(import_picocolors5.default.red(`Failed to uninstall hook: ${message}`));
|
|
18182
18411
|
process.exit(1);
|
|
18183
18412
|
}
|
|
18184
18413
|
});
|
|
@@ -18197,7 +18426,7 @@ hookCommand.command("test").aliases(["verify", "check"]).description("Verify non
|
|
|
18197
18426
|
}
|
|
18198
18427
|
} catch (err) {
|
|
18199
18428
|
const message = err instanceof Error ? err.message : String(err);
|
|
18200
|
-
console.error(
|
|
18429
|
+
console.error(import_picocolors5.default.red(`Error testing hooks: ${message}`));
|
|
18201
18430
|
process.exit(1);
|
|
18202
18431
|
}
|
|
18203
18432
|
});
|
|
@@ -18206,7 +18435,7 @@ notesCmd.command("show [commit]").description("Display Qodewk receipt attached t
|
|
|
18206
18435
|
try {
|
|
18207
18436
|
const receipt = await readGitReceiptNote(commit);
|
|
18208
18437
|
if (!receipt) {
|
|
18209
|
-
console.log(
|
|
18438
|
+
console.log(import_picocolors5.default.yellow(`No Qodewk receipt note found on commit '${commit}'.`));
|
|
18210
18439
|
return;
|
|
18211
18440
|
}
|
|
18212
18441
|
if (opts.json) {
|
|
@@ -18216,7 +18445,7 @@ notesCmd.command("show [commit]").description("Display Qodewk receipt attached t
|
|
|
18216
18445
|
}
|
|
18217
18446
|
} catch (err) {
|
|
18218
18447
|
const message = err instanceof Error ? err.message : String(err);
|
|
18219
|
-
console.error(
|
|
18448
|
+
console.error(import_picocolors5.default.red(`Error reading Git note: ${message}`));
|
|
18220
18449
|
process.exit(1);
|
|
18221
18450
|
}
|
|
18222
18451
|
});
|
|
@@ -18225,11 +18454,11 @@ notesCmd.command("write [commit]").description("Generate and attach receipt to a
|
|
|
18225
18454
|
const receipt = await generateReceipt({ headSha: commit });
|
|
18226
18455
|
await writeGitReceiptNote(receipt.repository.headSha, receipt);
|
|
18227
18456
|
console.log(
|
|
18228
|
-
|
|
18457
|
+
import_picocolors5.default.green(`\u2713 Attached receipt note to ${receipt.repository.headSha.slice(0, 7)} (refs/notes/qodewk)`)
|
|
18229
18458
|
);
|
|
18230
18459
|
} catch (err) {
|
|
18231
18460
|
const message = err instanceof Error ? err.message : String(err);
|
|
18232
|
-
console.error(
|
|
18461
|
+
console.error(import_picocolors5.default.red(`Error writing Git note: ${message}`));
|
|
18233
18462
|
process.exit(1);
|
|
18234
18463
|
}
|
|
18235
18464
|
});
|
|
@@ -18237,16 +18466,16 @@ notesCmd.command("list").description("List all commits with attached Qodewk rece
|
|
|
18237
18466
|
try {
|
|
18238
18467
|
const shas = await listGitReceiptNotes();
|
|
18239
18468
|
if (shas.length === 0) {
|
|
18240
|
-
console.log(
|
|
18469
|
+
console.log(import_picocolors5.default.yellow("No Qodewk Git notes found in repository."));
|
|
18241
18470
|
return;
|
|
18242
18471
|
}
|
|
18243
|
-
console.log(
|
|
18472
|
+
console.log(import_picocolors5.default.bold(`Found ${shas.length} commit note(s) in refs/notes/qodewk:`));
|
|
18244
18473
|
for (const sha of shas) {
|
|
18245
|
-
console.log(` ${
|
|
18474
|
+
console.log(` ${import_picocolors5.default.cyan(sha.slice(0, 10))} ${import_picocolors5.default.dim(sha)}`);
|
|
18246
18475
|
}
|
|
18247
18476
|
} catch (err) {
|
|
18248
18477
|
const message = err instanceof Error ? err.message : String(err);
|
|
18249
|
-
console.error(
|
|
18478
|
+
console.error(import_picocolors5.default.red(`Error listing Git notes: ${message}`));
|
|
18250
18479
|
process.exit(1);
|
|
18251
18480
|
}
|
|
18252
18481
|
});
|