@wrongstack/plugins 0.87.0 → 0.89.3
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/cost-tracker.js +13 -10
- package/dist/git-autocommit.js +126 -3
- package/dist/index.js +146 -37
- package/dist/json-path.js +2 -6
- package/dist/semver-bump.js +1 -6
- package/package.json +2 -2
package/dist/cost-tracker.js
CHANGED
|
@@ -1,10 +1,6 @@
|
|
|
1
|
+
import { expectDefined } from '@wrongstack/core';
|
|
2
|
+
|
|
1
3
|
// src/cost-tracker/index.ts
|
|
2
|
-
function expectDefined(value) {
|
|
3
|
-
if (value === null || value === void 0) {
|
|
4
|
-
throw new Error("Expected value to be defined");
|
|
5
|
-
}
|
|
6
|
-
return value;
|
|
7
|
-
}
|
|
8
4
|
var API_VERSION = "^0.1.10";
|
|
9
5
|
var PRICING = {
|
|
10
6
|
"gpt-4o": { input: 5, output: 15 },
|
|
@@ -18,6 +14,12 @@ var PRICING = {
|
|
|
18
14
|
"default": { input: 5, output: 15 }
|
|
19
15
|
};
|
|
20
16
|
var DEFAULT_PRICING = { input: 5, output: 15 };
|
|
17
|
+
function readCostTrackerConfig(raw) {
|
|
18
|
+
return {
|
|
19
|
+
budgetLimit: typeof raw?.["budgetLimit"] === "number" ? raw["budgetLimit"] : 0,
|
|
20
|
+
warningThreshold: typeof raw?.["warningThreshold"] === "number" ? raw["warningThreshold"] : 80
|
|
21
|
+
};
|
|
22
|
+
}
|
|
21
23
|
function estimateCost(model, promptTokens, completionTokens) {
|
|
22
24
|
const pricing = PRICING[model.toLowerCase()] ?? DEFAULT_PRICING;
|
|
23
25
|
const inputCost = promptTokens / 1e6 * pricing.input;
|
|
@@ -91,8 +93,9 @@ var plugin = {
|
|
|
91
93
|
permission: "auto",
|
|
92
94
|
mutating: false,
|
|
93
95
|
async execute() {
|
|
94
|
-
const budgetLimit
|
|
95
|
-
|
|
96
|
+
const { budgetLimit, warningThreshold } = readCostTrackerConfig(
|
|
97
|
+
api.config.extensions?.["cost-tracker"]
|
|
98
|
+
);
|
|
96
99
|
const usage = {
|
|
97
100
|
totalRequests: sessionCost.requests.length,
|
|
98
101
|
totalPromptTokens: sessionCost.totalPromptTokens,
|
|
@@ -125,7 +128,7 @@ var plugin = {
|
|
|
125
128
|
description: "Resets all token usage and cost counters for the current session.",
|
|
126
129
|
inputSchema: { type: "object", properties: {} },
|
|
127
130
|
permission: "auto",
|
|
128
|
-
mutating:
|
|
131
|
+
mutating: true,
|
|
129
132
|
async execute() {
|
|
130
133
|
const prev = {
|
|
131
134
|
totalTokens: sessionCost.totalTokens,
|
|
@@ -198,7 +201,7 @@ var plugin = {
|
|
|
198
201
|
};
|
|
199
202
|
}
|
|
200
203
|
});
|
|
201
|
-
api.onEvent("session.
|
|
204
|
+
api.onEvent("session.ended", async () => {
|
|
202
205
|
if (sessionCost.requests.length > 0) {
|
|
203
206
|
await api.session.append({
|
|
204
207
|
type: "cost-tracker:session_summary",
|
package/dist/git-autocommit.js
CHANGED
|
@@ -54,6 +54,60 @@ function getCommitHistory(since, cwd) {
|
|
|
54
54
|
return { hash, message, type };
|
|
55
55
|
});
|
|
56
56
|
}
|
|
57
|
+
function getWorktrees(cwd) {
|
|
58
|
+
try {
|
|
59
|
+
const out = runGit(["worktree", "list", "--porcelain"], cwd);
|
|
60
|
+
if (!out) return [];
|
|
61
|
+
const entries = [];
|
|
62
|
+
let current = {};
|
|
63
|
+
for (const line of out.split("\n")) {
|
|
64
|
+
if (line === "") {
|
|
65
|
+
if (current.path) entries.push(current);
|
|
66
|
+
current = {};
|
|
67
|
+
continue;
|
|
68
|
+
}
|
|
69
|
+
if (line.startsWith("worktree ")) current.path = line.slice(9);
|
|
70
|
+
else if (line.startsWith("HEAD ")) current.head = line.slice(5);
|
|
71
|
+
else if (line.startsWith("branch ")) current.branch = line.slice(7);
|
|
72
|
+
}
|
|
73
|
+
if (current.path) entries.push(current);
|
|
74
|
+
return entries;
|
|
75
|
+
} catch {
|
|
76
|
+
return [];
|
|
77
|
+
}
|
|
78
|
+
}
|
|
79
|
+
function simultaneousEditWarning(cwd) {
|
|
80
|
+
const worktrees = getWorktrees(cwd);
|
|
81
|
+
if (worktrees.length > 1) {
|
|
82
|
+
const otherBranches = worktrees.filter((wt) => wt.branch).map((wt) => wt.branch.replace("refs/heads/", ""));
|
|
83
|
+
return `\u26A0 Simultaneous edits detected: ${worktrees.length} active worktrees (${otherBranches.join(", ")}). Changes from other agents may mix into this commit. Consider using worktree isolation or verifying the diff below before committing.`;
|
|
84
|
+
}
|
|
85
|
+
return null;
|
|
86
|
+
}
|
|
87
|
+
function getStagedDiff(cwd) {
|
|
88
|
+
try {
|
|
89
|
+
const stat = runGit(["diff", "--cached", "--stat"], cwd);
|
|
90
|
+
const diff = runGit(["diff", "--cached"], cwd);
|
|
91
|
+
const MAX_DIFF = 2e4;
|
|
92
|
+
const truncated = diff.length > MAX_DIFF ? diff.slice(0, MAX_DIFF) + "\n\n... (diff truncated)" : diff;
|
|
93
|
+
return { stat: stat || "(no stat)", diff: truncated || "(clean)" };
|
|
94
|
+
} catch {
|
|
95
|
+
return { stat: "(unavailable)", diff: "(unavailable)" };
|
|
96
|
+
}
|
|
97
|
+
}
|
|
98
|
+
function externalChangesSinceStage(cwd) {
|
|
99
|
+
try {
|
|
100
|
+
const out = runGit(["status", "--porcelain"], cwd);
|
|
101
|
+
if (!out) return null;
|
|
102
|
+
const unstaged = out.split("\n").filter((l) => l.trim()).filter((l) => {
|
|
103
|
+
const idx = l[0] ?? " ";
|
|
104
|
+
return idx === " " || idx === "?";
|
|
105
|
+
}).map((l) => l.slice(3).trim());
|
|
106
|
+
return unstaged.length > 0 ? unstaged : null;
|
|
107
|
+
} catch {
|
|
108
|
+
return null;
|
|
109
|
+
}
|
|
110
|
+
}
|
|
57
111
|
function generateCommitMessage(type, scope, summary, body) {
|
|
58
112
|
const scopePart = scope ? `(${scope})` : "";
|
|
59
113
|
const footer = body ? `
|
|
@@ -171,6 +225,39 @@ var plugin = {
|
|
|
171
225
|
if (staged.length === 0) {
|
|
172
226
|
return { ok: false, error: "Nothing staged. Add files with git add or provide files input." };
|
|
173
227
|
}
|
|
228
|
+
const worktreeWarn = simultaneousEditWarning();
|
|
229
|
+
const externalChanges = externalChangesSinceStage();
|
|
230
|
+
let externalWarning = null;
|
|
231
|
+
if (externalChanges && externalChanges.length > 0) {
|
|
232
|
+
const preview = externalChanges.slice(0, 10).join(", ");
|
|
233
|
+
const suffix = externalChanges.length > 10 ? ` and ${externalChanges.length - 10} more` : "";
|
|
234
|
+
externalWarning = `\u26A0 External changes detected since staging: ${preview}${suffix}. Another agent may be modifying files concurrently. These unstaged changes will NOT be included in this commit, but they indicate simultaneous edits. Review carefully.`;
|
|
235
|
+
}
|
|
236
|
+
const warning = [worktreeWarn, externalWarning].filter(Boolean).join("\n") || void 0;
|
|
237
|
+
const { stat, diff: stagedDiff } = getStagedDiff();
|
|
238
|
+
if (dryRun) {
|
|
239
|
+
return {
|
|
240
|
+
ok: true,
|
|
241
|
+
dryRun: true,
|
|
242
|
+
message: `Would create: ${msg}`,
|
|
243
|
+
warning: warning ?? void 0,
|
|
244
|
+
stagedDiff: `
|
|
245
|
+
## Staged changes (dry run)
|
|
246
|
+
|
|
247
|
+
${stat}
|
|
248
|
+
|
|
249
|
+
\`\`\`diff
|
|
250
|
+
${stagedDiff}
|
|
251
|
+
\`\`\``
|
|
252
|
+
};
|
|
253
|
+
}
|
|
254
|
+
let preCommitDiff = stagedDiff;
|
|
255
|
+
let preCommitStat = stat;
|
|
256
|
+
if (staged.length === 0) {
|
|
257
|
+
const fresh = getStagedDiff();
|
|
258
|
+
preCommitDiff = fresh.diff;
|
|
259
|
+
preCommitStat = fresh.stat;
|
|
260
|
+
}
|
|
174
261
|
let hash = "";
|
|
175
262
|
try {
|
|
176
263
|
hash = commitWithMessage(msg);
|
|
@@ -185,7 +272,8 @@ var plugin = {
|
|
|
185
272
|
hash: String(hash),
|
|
186
273
|
commitType: type,
|
|
187
274
|
scope: String(scope ?? ""),
|
|
188
|
-
files: Array.isArray(staged) ? staged : []
|
|
275
|
+
files: Array.isArray(staged) ? staged : [],
|
|
276
|
+
warning: warning ?? null
|
|
189
277
|
});
|
|
190
278
|
} catch (_err) {
|
|
191
279
|
}
|
|
@@ -195,7 +283,16 @@ var plugin = {
|
|
|
195
283
|
message: msg,
|
|
196
284
|
stagedFiles: staged,
|
|
197
285
|
type,
|
|
198
|
-
scope: scope ?? null
|
|
286
|
+
scope: scope ?? null,
|
|
287
|
+
warning: warning ?? void 0,
|
|
288
|
+
diff: `
|
|
289
|
+
## Staged diff
|
|
290
|
+
|
|
291
|
+
${preCommitStat}
|
|
292
|
+
|
|
293
|
+
\`\`\`diff
|
|
294
|
+
${preCommitDiff}
|
|
295
|
+
\`\`\``
|
|
199
296
|
};
|
|
200
297
|
} catch (err) {
|
|
201
298
|
return { ok: false, error: `Uncaught error in git_autocommit: ${err instanceof Error ? err.message : String(err)}` };
|
|
@@ -264,6 +361,9 @@ var plugin = {
|
|
|
264
361
|
let staged = [];
|
|
265
362
|
let aheadBehind = "";
|
|
266
363
|
const recentCommits = [];
|
|
364
|
+
let worktrees = [];
|
|
365
|
+
let worktreeWarn = null;
|
|
366
|
+
let externalChanges = null;
|
|
267
367
|
try {
|
|
268
368
|
branch = runGit(["branch", "--show-current"]);
|
|
269
369
|
} catch {
|
|
@@ -284,13 +384,36 @@ var plugin = {
|
|
|
284
384
|
recentCommits.push(...getCommitHistory("-3", void 0).map((c) => ({ hash: (c.hash ?? "").slice(0, 7), message: c.message })));
|
|
285
385
|
} catch {
|
|
286
386
|
}
|
|
387
|
+
try {
|
|
388
|
+
worktrees = getWorktrees();
|
|
389
|
+
} catch {
|
|
390
|
+
}
|
|
391
|
+
try {
|
|
392
|
+
worktreeWarn = simultaneousEditWarning();
|
|
393
|
+
} catch {
|
|
394
|
+
}
|
|
395
|
+
try {
|
|
396
|
+
const out = runGit(["status", "--porcelain"]);
|
|
397
|
+
const unstaged = out.split("\n").filter((l) => {
|
|
398
|
+
const idx = l[0] ?? " ";
|
|
399
|
+
return idx === " " || idx === "?";
|
|
400
|
+
}).map((l) => l.slice(3).trim()).filter(Boolean);
|
|
401
|
+
externalChanges = unstaged.length > 0 ? unstaged : null;
|
|
402
|
+
} catch {
|
|
403
|
+
}
|
|
287
404
|
return {
|
|
288
405
|
ok: true,
|
|
289
406
|
branch,
|
|
290
407
|
changedFiles: changed,
|
|
291
408
|
stagedFiles: staged,
|
|
292
409
|
aheadBehind,
|
|
293
|
-
recentCommits
|
|
410
|
+
recentCommits,
|
|
411
|
+
worktrees: worktrees.length > 0 ? worktrees.map((w) => ({
|
|
412
|
+
path: w.path,
|
|
413
|
+
branch: w.branch.replace("refs/heads/", "")
|
|
414
|
+
})) : [],
|
|
415
|
+
worktreeWarning: worktreeWarn ?? void 0,
|
|
416
|
+
externalChanges: externalChanges ?? void 0
|
|
294
417
|
};
|
|
295
418
|
}
|
|
296
419
|
});
|
package/dist/index.js
CHANGED
|
@@ -2,6 +2,7 @@ import { execFileSync, execSync } from 'child_process';
|
|
|
2
2
|
import { watch, existsSync, readdirSync, readFileSync } from 'fs';
|
|
3
3
|
import * as path from 'path';
|
|
4
4
|
import { isAbsolute, join } from 'path';
|
|
5
|
+
import { expectDefined } from '@wrongstack/core';
|
|
5
6
|
import { lookup } from 'dns/promises';
|
|
6
7
|
import { isIPv4, isIPv6 } from 'net';
|
|
7
8
|
|
|
@@ -294,6 +295,60 @@ function getCommitHistory(since, cwd) {
|
|
|
294
295
|
return { hash, message, type };
|
|
295
296
|
});
|
|
296
297
|
}
|
|
298
|
+
function getWorktrees(cwd) {
|
|
299
|
+
try {
|
|
300
|
+
const out = runGit(["worktree", "list", "--porcelain"], cwd);
|
|
301
|
+
if (!out) return [];
|
|
302
|
+
const entries = [];
|
|
303
|
+
let current = {};
|
|
304
|
+
for (const line of out.split("\n")) {
|
|
305
|
+
if (line === "") {
|
|
306
|
+
if (current.path) entries.push(current);
|
|
307
|
+
current = {};
|
|
308
|
+
continue;
|
|
309
|
+
}
|
|
310
|
+
if (line.startsWith("worktree ")) current.path = line.slice(9);
|
|
311
|
+
else if (line.startsWith("HEAD ")) current.head = line.slice(5);
|
|
312
|
+
else if (line.startsWith("branch ")) current.branch = line.slice(7);
|
|
313
|
+
}
|
|
314
|
+
if (current.path) entries.push(current);
|
|
315
|
+
return entries;
|
|
316
|
+
} catch {
|
|
317
|
+
return [];
|
|
318
|
+
}
|
|
319
|
+
}
|
|
320
|
+
function simultaneousEditWarning(cwd) {
|
|
321
|
+
const worktrees = getWorktrees(cwd);
|
|
322
|
+
if (worktrees.length > 1) {
|
|
323
|
+
const otherBranches = worktrees.filter((wt) => wt.branch).map((wt) => wt.branch.replace("refs/heads/", ""));
|
|
324
|
+
return `\u26A0 Simultaneous edits detected: ${worktrees.length} active worktrees (${otherBranches.join(", ")}). Changes from other agents may mix into this commit. Consider using worktree isolation or verifying the diff below before committing.`;
|
|
325
|
+
}
|
|
326
|
+
return null;
|
|
327
|
+
}
|
|
328
|
+
function getStagedDiff(cwd) {
|
|
329
|
+
try {
|
|
330
|
+
const stat = runGit(["diff", "--cached", "--stat"], cwd);
|
|
331
|
+
const diff = runGit(["diff", "--cached"], cwd);
|
|
332
|
+
const MAX_DIFF = 2e4;
|
|
333
|
+
const truncated = diff.length > MAX_DIFF ? diff.slice(0, MAX_DIFF) + "\n\n... (diff truncated)" : diff;
|
|
334
|
+
return { stat: stat || "(no stat)", diff: truncated || "(clean)" };
|
|
335
|
+
} catch {
|
|
336
|
+
return { stat: "(unavailable)", diff: "(unavailable)" };
|
|
337
|
+
}
|
|
338
|
+
}
|
|
339
|
+
function externalChangesSinceStage(cwd) {
|
|
340
|
+
try {
|
|
341
|
+
const out = runGit(["status", "--porcelain"], cwd);
|
|
342
|
+
if (!out) return null;
|
|
343
|
+
const unstaged = out.split("\n").filter((l) => l.trim()).filter((l) => {
|
|
344
|
+
const idx = l[0] ?? " ";
|
|
345
|
+
return idx === " " || idx === "?";
|
|
346
|
+
}).map((l) => l.slice(3).trim());
|
|
347
|
+
return unstaged.length > 0 ? unstaged : null;
|
|
348
|
+
} catch {
|
|
349
|
+
return null;
|
|
350
|
+
}
|
|
351
|
+
}
|
|
297
352
|
function generateCommitMessage(type, scope, summary, body) {
|
|
298
353
|
const scopePart = scope ? `(${scope})` : "";
|
|
299
354
|
const footer = body ? `
|
|
@@ -411,6 +466,39 @@ var plugin2 = {
|
|
|
411
466
|
if (staged.length === 0) {
|
|
412
467
|
return { ok: false, error: "Nothing staged. Add files with git add or provide files input." };
|
|
413
468
|
}
|
|
469
|
+
const worktreeWarn = simultaneousEditWarning();
|
|
470
|
+
const externalChanges = externalChangesSinceStage();
|
|
471
|
+
let externalWarning = null;
|
|
472
|
+
if (externalChanges && externalChanges.length > 0) {
|
|
473
|
+
const preview = externalChanges.slice(0, 10).join(", ");
|
|
474
|
+
const suffix = externalChanges.length > 10 ? ` and ${externalChanges.length - 10} more` : "";
|
|
475
|
+
externalWarning = `\u26A0 External changes detected since staging: ${preview}${suffix}. Another agent may be modifying files concurrently. These unstaged changes will NOT be included in this commit, but they indicate simultaneous edits. Review carefully.`;
|
|
476
|
+
}
|
|
477
|
+
const warning = [worktreeWarn, externalWarning].filter(Boolean).join("\n") || void 0;
|
|
478
|
+
const { stat, diff: stagedDiff } = getStagedDiff();
|
|
479
|
+
if (dryRun) {
|
|
480
|
+
return {
|
|
481
|
+
ok: true,
|
|
482
|
+
dryRun: true,
|
|
483
|
+
message: `Would create: ${msg}`,
|
|
484
|
+
warning: warning ?? void 0,
|
|
485
|
+
stagedDiff: `
|
|
486
|
+
## Staged changes (dry run)
|
|
487
|
+
|
|
488
|
+
${stat}
|
|
489
|
+
|
|
490
|
+
\`\`\`diff
|
|
491
|
+
${stagedDiff}
|
|
492
|
+
\`\`\``
|
|
493
|
+
};
|
|
494
|
+
}
|
|
495
|
+
let preCommitDiff = stagedDiff;
|
|
496
|
+
let preCommitStat = stat;
|
|
497
|
+
if (staged.length === 0) {
|
|
498
|
+
const fresh = getStagedDiff();
|
|
499
|
+
preCommitDiff = fresh.diff;
|
|
500
|
+
preCommitStat = fresh.stat;
|
|
501
|
+
}
|
|
414
502
|
let hash = "";
|
|
415
503
|
try {
|
|
416
504
|
hash = commitWithMessage(msg);
|
|
@@ -425,7 +513,8 @@ var plugin2 = {
|
|
|
425
513
|
hash: String(hash),
|
|
426
514
|
commitType: type,
|
|
427
515
|
scope: String(scope ?? ""),
|
|
428
|
-
files: Array.isArray(staged) ? staged : []
|
|
516
|
+
files: Array.isArray(staged) ? staged : [],
|
|
517
|
+
warning: warning ?? null
|
|
429
518
|
});
|
|
430
519
|
} catch (_err) {
|
|
431
520
|
}
|
|
@@ -435,7 +524,16 @@ var plugin2 = {
|
|
|
435
524
|
message: msg,
|
|
436
525
|
stagedFiles: staged,
|
|
437
526
|
type,
|
|
438
|
-
scope: scope ?? null
|
|
527
|
+
scope: scope ?? null,
|
|
528
|
+
warning: warning ?? void 0,
|
|
529
|
+
diff: `
|
|
530
|
+
## Staged diff
|
|
531
|
+
|
|
532
|
+
${preCommitStat}
|
|
533
|
+
|
|
534
|
+
\`\`\`diff
|
|
535
|
+
${preCommitDiff}
|
|
536
|
+
\`\`\``
|
|
439
537
|
};
|
|
440
538
|
} catch (err) {
|
|
441
539
|
return { ok: false, error: `Uncaught error in git_autocommit: ${err instanceof Error ? err.message : String(err)}` };
|
|
@@ -504,6 +602,9 @@ var plugin2 = {
|
|
|
504
602
|
let staged = [];
|
|
505
603
|
let aheadBehind = "";
|
|
506
604
|
const recentCommits = [];
|
|
605
|
+
let worktrees = [];
|
|
606
|
+
let worktreeWarn = null;
|
|
607
|
+
let externalChanges = null;
|
|
507
608
|
try {
|
|
508
609
|
branch = runGit(["branch", "--show-current"]);
|
|
509
610
|
} catch {
|
|
@@ -524,13 +625,36 @@ var plugin2 = {
|
|
|
524
625
|
recentCommits.push(...getCommitHistory("-3", void 0).map((c) => ({ hash: (c.hash ?? "").slice(0, 7), message: c.message })));
|
|
525
626
|
} catch {
|
|
526
627
|
}
|
|
628
|
+
try {
|
|
629
|
+
worktrees = getWorktrees();
|
|
630
|
+
} catch {
|
|
631
|
+
}
|
|
632
|
+
try {
|
|
633
|
+
worktreeWarn = simultaneousEditWarning();
|
|
634
|
+
} catch {
|
|
635
|
+
}
|
|
636
|
+
try {
|
|
637
|
+
const out = runGit(["status", "--porcelain"]);
|
|
638
|
+
const unstaged = out.split("\n").filter((l) => {
|
|
639
|
+
const idx = l[0] ?? " ";
|
|
640
|
+
return idx === " " || idx === "?";
|
|
641
|
+
}).map((l) => l.slice(3).trim()).filter(Boolean);
|
|
642
|
+
externalChanges = unstaged.length > 0 ? unstaged : null;
|
|
643
|
+
} catch {
|
|
644
|
+
}
|
|
527
645
|
return {
|
|
528
646
|
ok: true,
|
|
529
647
|
branch,
|
|
530
648
|
changedFiles: changed,
|
|
531
649
|
stagedFiles: staged,
|
|
532
650
|
aheadBehind,
|
|
533
|
-
recentCommits
|
|
651
|
+
recentCommits,
|
|
652
|
+
worktrees: worktrees.length > 0 ? worktrees.map((w) => ({
|
|
653
|
+
path: w.path,
|
|
654
|
+
branch: w.branch.replace("refs/heads/", "")
|
|
655
|
+
})) : [],
|
|
656
|
+
worktreeWarning: worktreeWarn ?? void 0,
|
|
657
|
+
externalChanges: externalChanges ?? void 0
|
|
534
658
|
};
|
|
535
659
|
}
|
|
536
660
|
});
|
|
@@ -765,14 +889,6 @@ var plugin3 = {
|
|
|
765
889
|
}
|
|
766
890
|
};
|
|
767
891
|
var shell_check_default = plugin3;
|
|
768
|
-
|
|
769
|
-
// src/cost-tracker/index.ts
|
|
770
|
-
function expectDefined(value) {
|
|
771
|
-
if (value === null || value === void 0) {
|
|
772
|
-
throw new Error("Expected value to be defined");
|
|
773
|
-
}
|
|
774
|
-
return value;
|
|
775
|
-
}
|
|
776
892
|
var API_VERSION3 = "^0.1.10";
|
|
777
893
|
var PRICING = {
|
|
778
894
|
"gpt-4o": { input: 5, output: 15 },
|
|
@@ -786,6 +902,12 @@ var PRICING = {
|
|
|
786
902
|
"default": { input: 5, output: 15 }
|
|
787
903
|
};
|
|
788
904
|
var DEFAULT_PRICING = { input: 5, output: 15 };
|
|
905
|
+
function readCostTrackerConfig(raw) {
|
|
906
|
+
return {
|
|
907
|
+
budgetLimit: typeof raw?.["budgetLimit"] === "number" ? raw["budgetLimit"] : 0,
|
|
908
|
+
warningThreshold: typeof raw?.["warningThreshold"] === "number" ? raw["warningThreshold"] : 80
|
|
909
|
+
};
|
|
910
|
+
}
|
|
789
911
|
function estimateCost(model, promptTokens, completionTokens) {
|
|
790
912
|
const pricing = PRICING[model.toLowerCase()] ?? DEFAULT_PRICING;
|
|
791
913
|
const inputCost = promptTokens / 1e6 * pricing.input;
|
|
@@ -859,8 +981,9 @@ var plugin4 = {
|
|
|
859
981
|
permission: "auto",
|
|
860
982
|
mutating: false,
|
|
861
983
|
async execute() {
|
|
862
|
-
const budgetLimit
|
|
863
|
-
|
|
984
|
+
const { budgetLimit, warningThreshold } = readCostTrackerConfig(
|
|
985
|
+
api.config.extensions?.["cost-tracker"]
|
|
986
|
+
);
|
|
864
987
|
const usage = {
|
|
865
988
|
totalRequests: sessionCost.requests.length,
|
|
866
989
|
totalPromptTokens: sessionCost.totalPromptTokens,
|
|
@@ -893,7 +1016,7 @@ var plugin4 = {
|
|
|
893
1016
|
description: "Resets all token usage and cost counters for the current session.",
|
|
894
1017
|
inputSchema: { type: "object", properties: {} },
|
|
895
1018
|
permission: "auto",
|
|
896
|
-
mutating:
|
|
1019
|
+
mutating: true,
|
|
897
1020
|
async execute() {
|
|
898
1021
|
const prev = {
|
|
899
1022
|
totalTokens: sessionCost.totalTokens,
|
|
@@ -966,7 +1089,7 @@ var plugin4 = {
|
|
|
966
1089
|
};
|
|
967
1090
|
}
|
|
968
1091
|
});
|
|
969
|
-
api.onEvent("session.
|
|
1092
|
+
api.onEvent("session.ended", async () => {
|
|
970
1093
|
if (sessionCost.requests.length > 0) {
|
|
971
1094
|
await api.session.append({
|
|
972
1095
|
type: "cost-tracker:session_summary",
|
|
@@ -1509,21 +1632,13 @@ var plugin6 = {
|
|
|
1509
1632
|
}
|
|
1510
1633
|
};
|
|
1511
1634
|
var web_search_default = plugin6;
|
|
1512
|
-
|
|
1513
|
-
// src/json-path/index.ts
|
|
1514
|
-
function expectDefined2(value) {
|
|
1515
|
-
if (value === null || value === void 0) {
|
|
1516
|
-
throw new Error("Expected value to be defined");
|
|
1517
|
-
}
|
|
1518
|
-
return value;
|
|
1519
|
-
}
|
|
1520
1635
|
var API_VERSION6 = "^0.1.10";
|
|
1521
1636
|
function jmespathSearch(data, query) {
|
|
1522
1637
|
if (!query || query === "@") return data;
|
|
1523
1638
|
if (query === "$") return data;
|
|
1524
1639
|
const dotMatch = query.match(/^([a-zA-Z_][a-zA-Z0-9_]*)(?:\.(.+))?$/);
|
|
1525
1640
|
if (dotMatch) {
|
|
1526
|
-
const key =
|
|
1641
|
+
const key = expectDefined(dotMatch[1]);
|
|
1527
1642
|
const rest = dotMatch[2];
|
|
1528
1643
|
const val = data?.[key];
|
|
1529
1644
|
if (rest === void 0) return val;
|
|
@@ -1531,7 +1646,7 @@ function jmespathSearch(data, query) {
|
|
|
1531
1646
|
}
|
|
1532
1647
|
const arrMatch = query.match(/^\[(\d+)\](?:\.(.+))?$/);
|
|
1533
1648
|
if (arrMatch) {
|
|
1534
|
-
const idx = Number.parseInt(
|
|
1649
|
+
const idx = Number.parseInt(expectDefined(arrMatch[1]), 10);
|
|
1535
1650
|
const rest = arrMatch[2];
|
|
1536
1651
|
const arr = data;
|
|
1537
1652
|
const val = arr?.[idx];
|
|
@@ -1546,7 +1661,7 @@ function jmespathSearch(data, query) {
|
|
|
1546
1661
|
}
|
|
1547
1662
|
const multiMatch = query.match(/^([a-zA-Z_][a-zA-Z0-9_]*)\[\*\](?:\.(.+))?$/);
|
|
1548
1663
|
if (multiMatch) {
|
|
1549
|
-
const key =
|
|
1664
|
+
const key = expectDefined(multiMatch[1]);
|
|
1550
1665
|
const rest = multiMatch[2];
|
|
1551
1666
|
const arr = data?.[key];
|
|
1552
1667
|
if (!Array.isArray(arr)) return [];
|
|
@@ -1555,9 +1670,9 @@ function jmespathSearch(data, query) {
|
|
|
1555
1670
|
}
|
|
1556
1671
|
const filterMatch = query.match(/^\[\\?([a-zA-Z_][a-zA-Z0-9_]*)(==|!=|<|>|<=|>=)(`[^`]+`|'[^']*')\](?:\.(.+))?$/);
|
|
1557
1672
|
if (filterMatch) {
|
|
1558
|
-
const field =
|
|
1559
|
-
const op =
|
|
1560
|
-
const rawVal =
|
|
1673
|
+
const field = expectDefined(filterMatch[1]);
|
|
1674
|
+
const op = expectDefined(filterMatch[2]);
|
|
1675
|
+
const rawVal = expectDefined(filterMatch[3]);
|
|
1561
1676
|
const rest = filterMatch[4];
|
|
1562
1677
|
const cmpVal = JSON.parse(rawVal.slice(1, -1));
|
|
1563
1678
|
const arr = data;
|
|
@@ -1586,7 +1701,7 @@ function jmespathSearch(data, query) {
|
|
|
1586
1701
|
}
|
|
1587
1702
|
const fnMatch = query.match(/^(length|keys|values|type)\(@\)$/);
|
|
1588
1703
|
if (fnMatch) {
|
|
1589
|
-
const fn =
|
|
1704
|
+
const fn = expectDefined(fnMatch[1]);
|
|
1590
1705
|
switch (fn) {
|
|
1591
1706
|
case "length":
|
|
1592
1707
|
if (Array.isArray(data)) return data.length;
|
|
@@ -2318,12 +2433,6 @@ var plugin9 = {
|
|
|
2318
2433
|
}
|
|
2319
2434
|
};
|
|
2320
2435
|
var template_engine_default = plugin9;
|
|
2321
|
-
function expectDefined3(value) {
|
|
2322
|
-
if (value === null || value === void 0) {
|
|
2323
|
-
throw new Error("Expected value to be defined");
|
|
2324
|
-
}
|
|
2325
|
-
return value;
|
|
2326
|
-
}
|
|
2327
2436
|
var API_VERSION9 = "^0.1.10";
|
|
2328
2437
|
function runGit2(args, cwd) {
|
|
2329
2438
|
try {
|
|
@@ -2351,7 +2460,7 @@ function getPackageJson(cwd) {
|
|
|
2351
2460
|
function parseVersion(v) {
|
|
2352
2461
|
const m = v.match(/^v?(\d+)\.(\d+)\.(\d+)/);
|
|
2353
2462
|
if (!m) return [0, 0, 0];
|
|
2354
|
-
return [Number.parseInt(
|
|
2463
|
+
return [Number.parseInt(expectDefined(m[1])), Number.parseInt(expectDefined(m[2])), Number.parseInt(expectDefined(m[3]))];
|
|
2355
2464
|
}
|
|
2356
2465
|
function bumpVersion(version, part) {
|
|
2357
2466
|
let [major, minor, patch] = parseVersion(version);
|
package/dist/json-path.js
CHANGED
|
@@ -1,10 +1,6 @@
|
|
|
1
|
+
import { expectDefined } from '@wrongstack/core';
|
|
2
|
+
|
|
1
3
|
// src/json-path/index.ts
|
|
2
|
-
function expectDefined(value) {
|
|
3
|
-
if (value === null || value === void 0) {
|
|
4
|
-
throw new Error("Expected value to be defined");
|
|
5
|
-
}
|
|
6
|
-
return value;
|
|
7
|
-
}
|
|
8
4
|
var API_VERSION = "^0.1.10";
|
|
9
5
|
function jmespathSearch(data, query) {
|
|
10
6
|
if (!query || query === "@") return data;
|
package/dist/semver-bump.js
CHANGED
|
@@ -1,13 +1,8 @@
|
|
|
1
|
+
import { expectDefined } from '@wrongstack/core';
|
|
1
2
|
import { execFileSync } from 'child_process';
|
|
2
3
|
import { existsSync, readFileSync } from 'fs';
|
|
3
4
|
|
|
4
5
|
// src/semver-bump/index.ts
|
|
5
|
-
function expectDefined(value) {
|
|
6
|
-
if (value === null || value === void 0) {
|
|
7
|
-
throw new Error("Expected value to be defined");
|
|
8
|
-
}
|
|
9
|
-
return value;
|
|
10
|
-
}
|
|
11
6
|
var API_VERSION = "^0.1.10";
|
|
12
7
|
function runGit(args, cwd) {
|
|
13
8
|
try {
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@wrongstack/plugins",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.89.3",
|
|
4
4
|
"description": "Official WrongStack plugin collection — auto-doc, git-autocommit, shell-check, cost-tracker, file-watcher, web-search, json-path, cron, template-engine, semver-bump",
|
|
5
5
|
"license": "MIT",
|
|
6
6
|
"author": "ECOSTACK TECHNOLOGY OÜ",
|
|
@@ -63,7 +63,7 @@
|
|
|
63
63
|
"vitest": "^4.1.7"
|
|
64
64
|
},
|
|
65
65
|
"dependencies": {
|
|
66
|
-
"@wrongstack/core": "0.
|
|
66
|
+
"@wrongstack/core": "0.89.3"
|
|
67
67
|
},
|
|
68
68
|
"scripts": {
|
|
69
69
|
"build": "tsup",
|