@tech-leads-club/harness-toolkit 0.2.4 → 0.3.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +68 -37
- package/bin/tlc-build.mjs +93 -0
- package/bin/tlc-cli.ts +110 -66
- package/bin/tlc-exec.mjs +16 -13
- package/config.example.json +1 -1
- package/dist/compact-before.mjs +66 -8
- package/dist/doctor.mjs +178 -41
- package/dist/help-topic.mjs +0 -0
- package/dist/init-project.mjs +2 -7
- package/dist/install-runtime.mjs +6594 -281
- package/dist/lessons-cli.mjs +67 -1
- package/dist/obs-cli.mjs +64 -1
- package/dist/price-lookup.mjs +45 -23
- package/dist/prompt-submit.mjs +66 -8
- package/dist/refresh-model-prices.mjs +7190 -46
- package/dist/response-after.mjs +66 -8
- package/dist/run.mjs +66 -8
- package/dist/session-end.mjs +66 -8
- package/dist/session-start.mjs +66 -8
- package/dist/shim.mjs +66 -3
- package/dist/stop.mjs +66 -8
- package/dist/subagent-start.mjs +66 -8
- package/dist/subagent-stop.mjs +66 -8
- package/dist/support.mjs +64 -1
- package/dist/tlc-cli.mjs +193 -87
- package/dist/tool-after.mjs +111 -31
- package/dist/tool-before.mjs +66 -8
- package/dist/tool-failure.mjs +66 -8
- package/dist/uninstall-runtime.mjs +9 -10
- package/docs/log.md +2 -0
- package/docs/measure.md +35 -31
- package/package.json +5 -5
- package/src/core/core.facade.ts +7 -0
- package/src/core/index.ts +1 -0
- package/src/core/pricing/pricing.freshness.ts +118 -0
- package/src/core/skill/skill.link.ts +14 -3
- package/src/entrypoints/shim.ts +8 -2
- package/src/platform/links.ts +73 -0
- package/src/platform/pricing.ts +139 -31
- package/src/providers/cursor/cursor.wiring.ts +11 -8
- package/tools/doctor.ts +78 -8
- package/tools/init-project.ts +7 -7
- package/tools/install-runtime.ts +110 -7
- package/tools/refresh-model-prices.ts +242 -75
- package/tools/uninstall-runtime.ts +23 -19
- package/bin/tlc-build +0 -80
- package/bin/tlc-exec +0 -10
- package/bin/tlc-exec.cmd +0 -4
- package/model-aliases.json +0 -12
- package/model-prices.cursor.json +0 -410
- package/model-prices.json +0 -1
package/dist/lessons-cli.mjs
CHANGED
|
@@ -5258,6 +5258,62 @@ function release(root, provider, session) {
|
|
|
5258
5258
|
deletePresenceRecord(root, provider, session);
|
|
5259
5259
|
}
|
|
5260
5260
|
|
|
5261
|
+
// src/core/pricing/pricing.freshness.ts
|
|
5262
|
+
var DEFAULT_TTL_DAYS = 7;
|
|
5263
|
+
var MS_PER_DAY = 86400000;
|
|
5264
|
+
function freshness(meta, now, ttlDays = DEFAULT_TTL_DAYS) {
|
|
5265
|
+
if (meta === null) {
|
|
5266
|
+
return { state: "absent" };
|
|
5267
|
+
}
|
|
5268
|
+
const stamp = meta.refreshedAt;
|
|
5269
|
+
if (stamp === undefined || Number.isNaN(Date.parse(stamp))) {
|
|
5270
|
+
return { state: "undated" };
|
|
5271
|
+
}
|
|
5272
|
+
const ageMs = now.getTime() - Date.parse(stamp);
|
|
5273
|
+
const ageDays = Math.max(0, ageMs / MS_PER_DAY);
|
|
5274
|
+
return ageDays > ttlDays ? { state: "stale", ageDays, refreshedAt: stamp } : { state: "fresh", ageDays, refreshedAt: stamp };
|
|
5275
|
+
}
|
|
5276
|
+
function shouldRefetch(state) {
|
|
5277
|
+
return state.state === "absent" || state.state === "undated" || state.state === "stale";
|
|
5278
|
+
}
|
|
5279
|
+
function freshnessMessage(state, catalogue) {
|
|
5280
|
+
switch (state.state) {
|
|
5281
|
+
case "absent":
|
|
5282
|
+
return `${catalogue}: not on this machine — run \`tlc harness prices refresh\``;
|
|
5283
|
+
case "undated":
|
|
5284
|
+
return `${catalogue}: present but carries no date — it will be refetched`;
|
|
5285
|
+
case "fresh":
|
|
5286
|
+
return `${catalogue}: ${describeAge(state.ageDays)} old`;
|
|
5287
|
+
default:
|
|
5288
|
+
return `${catalogue}: ${describeAge(state.ageDays)} old — run \`tlc harness prices refresh\``;
|
|
5289
|
+
}
|
|
5290
|
+
}
|
|
5291
|
+
var MIN_RETAINED_RATIO = 0.5;
|
|
5292
|
+
function mayReplace(existingCount, incomingCount, minRatio = MIN_RETAINED_RATIO) {
|
|
5293
|
+
if (incomingCount === 0) {
|
|
5294
|
+
return { replace: false, reason: "parsed no entries at all — the upstream format has changed" };
|
|
5295
|
+
}
|
|
5296
|
+
if (existingCount === 0) {
|
|
5297
|
+
return { replace: true, reason: `first catalogue, ${incomingCount} entries` };
|
|
5298
|
+
}
|
|
5299
|
+
if (incomingCount >= existingCount) {
|
|
5300
|
+
return { replace: true, reason: `${existingCount} → ${incomingCount} entries` };
|
|
5301
|
+
}
|
|
5302
|
+
const retained = incomingCount / existingCount;
|
|
5303
|
+
return retained >= minRatio ? { replace: true, reason: `${existingCount} → ${incomingCount} entries` } : {
|
|
5304
|
+
replace: false,
|
|
5305
|
+
reason: `would drop from ${existingCount} to ${incomingCount} entries, keeping the existing catalogue — the upstream format has probably changed`
|
|
5306
|
+
};
|
|
5307
|
+
}
|
|
5308
|
+
function describeAge(ageDays) {
|
|
5309
|
+
if (ageDays < 1) {
|
|
5310
|
+
const hours = Math.max(1, Math.round(ageDays * 24));
|
|
5311
|
+
return `${hours} hour${hours === 1 ? "" : "s"}`;
|
|
5312
|
+
}
|
|
5313
|
+
const days = Math.round(ageDays);
|
|
5314
|
+
return `${days} day${days === 1 ? "" : "s"}`;
|
|
5315
|
+
}
|
|
5316
|
+
|
|
5261
5317
|
// src/core/release/release.decisions.ts
|
|
5262
5318
|
import { existsSync as existsSync17, readdirSync as readdirSync5, readFileSync as readFileSync19 } from "node:fs";
|
|
5263
5319
|
import { join as join18 } from "node:path";
|
|
@@ -5607,7 +5663,8 @@ function linkHealth(target, runtimeHome2, probe) {
|
|
|
5607
5663
|
if (!probe.exists(resolved)) {
|
|
5608
5664
|
return { state: "dangling", target, resolved };
|
|
5609
5665
|
}
|
|
5610
|
-
const
|
|
5666
|
+
const resolveHome = probe.realpath ?? ((path) => path);
|
|
5667
|
+
const home = resolveHome(runtimeHome2).replace(/\/+$/, "");
|
|
5611
5668
|
return resolved === home || resolved.startsWith(`${home}/`) ? { state: "ok", target, resolved } : { state: "outside-runtime", target, resolved };
|
|
5612
5669
|
}
|
|
5613
5670
|
function linkHealthMessage(health) {
|
|
@@ -6754,6 +6811,12 @@ var coreFacade = {
|
|
|
6754
6811
|
coversHandler,
|
|
6755
6812
|
decideShim
|
|
6756
6813
|
},
|
|
6814
|
+
pricing: {
|
|
6815
|
+
freshness,
|
|
6816
|
+
freshnessMessage,
|
|
6817
|
+
mayReplace,
|
|
6818
|
+
shouldRefetch
|
|
6819
|
+
},
|
|
6757
6820
|
skill: {
|
|
6758
6821
|
linkHealth,
|
|
6759
6822
|
linkHealthMessage,
|
|
@@ -6972,6 +7035,9 @@ var NO_HUMAN_MODES = new Set(["bypassPermissions", "dontAsk"]);
|
|
|
6972
7035
|
// bin/write-user-hooks.mjs
|
|
6973
7036
|
if (false) {}
|
|
6974
7037
|
|
|
7038
|
+
// src/platform/pricing.ts
|
|
7039
|
+
var cache = new Map;
|
|
7040
|
+
|
|
6975
7041
|
// tools/doctor.ts
|
|
6976
7042
|
function plural(count, word) {
|
|
6977
7043
|
return `${count} ${word}${count === 1 ? "" : "s"}`;
|
package/dist/obs-cli.mjs
CHANGED
|
@@ -5262,6 +5262,62 @@ function release(root, provider, session) {
|
|
|
5262
5262
|
deletePresenceRecord(root, provider, session);
|
|
5263
5263
|
}
|
|
5264
5264
|
|
|
5265
|
+
// src/core/pricing/pricing.freshness.ts
|
|
5266
|
+
var DEFAULT_TTL_DAYS = 7;
|
|
5267
|
+
var MS_PER_DAY = 86400000;
|
|
5268
|
+
function freshness(meta, now, ttlDays = DEFAULT_TTL_DAYS) {
|
|
5269
|
+
if (meta === null) {
|
|
5270
|
+
return { state: "absent" };
|
|
5271
|
+
}
|
|
5272
|
+
const stamp = meta.refreshedAt;
|
|
5273
|
+
if (stamp === undefined || Number.isNaN(Date.parse(stamp))) {
|
|
5274
|
+
return { state: "undated" };
|
|
5275
|
+
}
|
|
5276
|
+
const ageMs = now.getTime() - Date.parse(stamp);
|
|
5277
|
+
const ageDays = Math.max(0, ageMs / MS_PER_DAY);
|
|
5278
|
+
return ageDays > ttlDays ? { state: "stale", ageDays, refreshedAt: stamp } : { state: "fresh", ageDays, refreshedAt: stamp };
|
|
5279
|
+
}
|
|
5280
|
+
function shouldRefetch(state) {
|
|
5281
|
+
return state.state === "absent" || state.state === "undated" || state.state === "stale";
|
|
5282
|
+
}
|
|
5283
|
+
function freshnessMessage(state, catalogue) {
|
|
5284
|
+
switch (state.state) {
|
|
5285
|
+
case "absent":
|
|
5286
|
+
return `${catalogue}: not on this machine — run \`tlc harness prices refresh\``;
|
|
5287
|
+
case "undated":
|
|
5288
|
+
return `${catalogue}: present but carries no date — it will be refetched`;
|
|
5289
|
+
case "fresh":
|
|
5290
|
+
return `${catalogue}: ${describeAge(state.ageDays)} old`;
|
|
5291
|
+
default:
|
|
5292
|
+
return `${catalogue}: ${describeAge(state.ageDays)} old — run \`tlc harness prices refresh\``;
|
|
5293
|
+
}
|
|
5294
|
+
}
|
|
5295
|
+
var MIN_RETAINED_RATIO = 0.5;
|
|
5296
|
+
function mayReplace(existingCount, incomingCount, minRatio = MIN_RETAINED_RATIO) {
|
|
5297
|
+
if (incomingCount === 0) {
|
|
5298
|
+
return { replace: false, reason: "parsed no entries at all — the upstream format has changed" };
|
|
5299
|
+
}
|
|
5300
|
+
if (existingCount === 0) {
|
|
5301
|
+
return { replace: true, reason: `first catalogue, ${incomingCount} entries` };
|
|
5302
|
+
}
|
|
5303
|
+
if (incomingCount >= existingCount) {
|
|
5304
|
+
return { replace: true, reason: `${existingCount} → ${incomingCount} entries` };
|
|
5305
|
+
}
|
|
5306
|
+
const retained = incomingCount / existingCount;
|
|
5307
|
+
return retained >= minRatio ? { replace: true, reason: `${existingCount} → ${incomingCount} entries` } : {
|
|
5308
|
+
replace: false,
|
|
5309
|
+
reason: `would drop from ${existingCount} to ${incomingCount} entries, keeping the existing catalogue — the upstream format has probably changed`
|
|
5310
|
+
};
|
|
5311
|
+
}
|
|
5312
|
+
function describeAge(ageDays) {
|
|
5313
|
+
if (ageDays < 1) {
|
|
5314
|
+
const hours = Math.max(1, Math.round(ageDays * 24));
|
|
5315
|
+
return `${hours} hour${hours === 1 ? "" : "s"}`;
|
|
5316
|
+
}
|
|
5317
|
+
const days = Math.round(ageDays);
|
|
5318
|
+
return `${days} day${days === 1 ? "" : "s"}`;
|
|
5319
|
+
}
|
|
5320
|
+
|
|
5265
5321
|
// src/core/release/release.decisions.ts
|
|
5266
5322
|
import { existsSync as existsSync17, readdirSync as readdirSync5, readFileSync as readFileSync19 } from "node:fs";
|
|
5267
5323
|
import { join as join18 } from "node:path";
|
|
@@ -5611,7 +5667,8 @@ function linkHealth(target, runtimeHome2, probe) {
|
|
|
5611
5667
|
if (!probe.exists(resolved)) {
|
|
5612
5668
|
return { state: "dangling", target, resolved };
|
|
5613
5669
|
}
|
|
5614
|
-
const
|
|
5670
|
+
const resolveHome = probe.realpath ?? ((path) => path);
|
|
5671
|
+
const home = resolveHome(runtimeHome2).replace(/\/+$/, "");
|
|
5615
5672
|
return resolved === home || resolved.startsWith(`${home}/`) ? { state: "ok", target, resolved } : { state: "outside-runtime", target, resolved };
|
|
5616
5673
|
}
|
|
5617
5674
|
function linkHealthMessage(health) {
|
|
@@ -6758,6 +6815,12 @@ var coreFacade = {
|
|
|
6758
6815
|
coversHandler,
|
|
6759
6816
|
decideShim
|
|
6760
6817
|
},
|
|
6818
|
+
pricing: {
|
|
6819
|
+
freshness,
|
|
6820
|
+
freshnessMessage,
|
|
6821
|
+
mayReplace,
|
|
6822
|
+
shouldRefetch
|
|
6823
|
+
},
|
|
6761
6824
|
skill: {
|
|
6762
6825
|
linkHealth,
|
|
6763
6826
|
linkHealthMessage,
|
package/dist/price-lookup.mjs
CHANGED
|
@@ -38,16 +38,11 @@ function runtimeHome(env = process.env) {
|
|
|
38
38
|
}
|
|
39
39
|
|
|
40
40
|
// src/platform/pricing.ts
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
return JSON.parse(readFileSync(path, "utf8"));
|
|
47
|
-
} catch {
|
|
48
|
-
return null;
|
|
49
|
-
}
|
|
50
|
-
}
|
|
41
|
+
var FALLBACK_PLANE = "litellm";
|
|
42
|
+
var MODEL_ALIASES = {
|
|
43
|
+
"cursor-grok-4.5": "grok-4.5",
|
|
44
|
+
auto: "auto-cost"
|
|
45
|
+
};
|
|
51
46
|
function stripMeta(table) {
|
|
52
47
|
if (!table) {
|
|
53
48
|
return {};
|
|
@@ -56,7 +51,7 @@ function stripMeta(table) {
|
|
|
56
51
|
return rest;
|
|
57
52
|
}
|
|
58
53
|
function slugifyModelName(name) {
|
|
59
|
-
return name.trim().toLowerCase().replace(
|
|
54
|
+
return name.trim().toLowerCase().replace(/\[([^\]]+)\]\([^)]*\)/g, "$1").replace(/[[\]]/g, "").replace(/[^a-z0-9.+]+/g, "-").replace(/^-+|-+$/g, "");
|
|
60
55
|
}
|
|
61
56
|
function candidatesFor(model, aliases) {
|
|
62
57
|
const trimmed = model.trim();
|
|
@@ -93,28 +88,55 @@ function fuzzyFind(table, needle) {
|
|
|
93
88
|
}
|
|
94
89
|
return;
|
|
95
90
|
}
|
|
96
|
-
function
|
|
91
|
+
function cataloguePath() {
|
|
97
92
|
return join2(runtimeHome(), "model-prices.json");
|
|
98
93
|
}
|
|
99
|
-
function
|
|
100
|
-
return join2(runtimeHome(),
|
|
94
|
+
function overridesPath() {
|
|
95
|
+
return join2(runtimeHome(), "model-prices.local.json");
|
|
96
|
+
}
|
|
97
|
+
var cache = new Map;
|
|
98
|
+
function readCatalogue(path) {
|
|
99
|
+
if (!existsSync(path)) {
|
|
100
|
+
cache.delete(path);
|
|
101
|
+
return null;
|
|
102
|
+
}
|
|
103
|
+
let text;
|
|
104
|
+
try {
|
|
105
|
+
text = readFileSync(path, "utf8");
|
|
106
|
+
} catch {
|
|
107
|
+
cache.delete(path);
|
|
108
|
+
return null;
|
|
109
|
+
}
|
|
110
|
+
const hit = cache.get(path);
|
|
111
|
+
if (hit && hit.text === text) {
|
|
112
|
+
return hit.value;
|
|
113
|
+
}
|
|
114
|
+
let parsed;
|
|
115
|
+
try {
|
|
116
|
+
parsed = JSON.parse(text);
|
|
117
|
+
} catch {
|
|
118
|
+
cache.delete(path);
|
|
119
|
+
return null;
|
|
120
|
+
}
|
|
121
|
+
cache.set(path, { text, value: parsed });
|
|
122
|
+
return parsed;
|
|
101
123
|
}
|
|
102
|
-
function
|
|
103
|
-
return
|
|
124
|
+
function loadCatalogue() {
|
|
125
|
+
return readCatalogue(cataloguePath()) ?? {};
|
|
104
126
|
}
|
|
105
|
-
function
|
|
106
|
-
return
|
|
127
|
+
function planeFor(catalogue, plane) {
|
|
128
|
+
return stripMeta(catalogue.planes?.[plane] ?? null);
|
|
107
129
|
}
|
|
108
130
|
function resolveModelPrice(provider, model) {
|
|
109
131
|
const trimmed = model.trim();
|
|
110
132
|
if (!trimmed) {
|
|
111
133
|
return;
|
|
112
134
|
}
|
|
113
|
-
const
|
|
114
|
-
const
|
|
115
|
-
const
|
|
116
|
-
const
|
|
117
|
-
const candidates = candidatesFor(trimmed,
|
|
135
|
+
const catalogue = loadCatalogue();
|
|
136
|
+
const overrides = stripMeta(readCatalogue(overridesPath()));
|
|
137
|
+
const native = provider ? planeFor(catalogue, provider) : {};
|
|
138
|
+
const litellm = planeFor(catalogue, FALLBACK_PLANE);
|
|
139
|
+
const candidates = candidatesFor(trimmed, MODEL_ALIASES);
|
|
118
140
|
for (const id of candidates) {
|
|
119
141
|
const entry = overrides[id];
|
|
120
142
|
if (entry) {
|
package/dist/prompt-submit.mjs
CHANGED
|
@@ -5273,6 +5273,62 @@ function release(root, provider, session) {
|
|
|
5273
5273
|
deletePresenceRecord(root, provider, session);
|
|
5274
5274
|
}
|
|
5275
5275
|
|
|
5276
|
+
// src/core/pricing/pricing.freshness.ts
|
|
5277
|
+
var DEFAULT_TTL_DAYS = 7;
|
|
5278
|
+
var MS_PER_DAY = 86400000;
|
|
5279
|
+
function freshness(meta, now, ttlDays = DEFAULT_TTL_DAYS) {
|
|
5280
|
+
if (meta === null) {
|
|
5281
|
+
return { state: "absent" };
|
|
5282
|
+
}
|
|
5283
|
+
const stamp = meta.refreshedAt;
|
|
5284
|
+
if (stamp === undefined || Number.isNaN(Date.parse(stamp))) {
|
|
5285
|
+
return { state: "undated" };
|
|
5286
|
+
}
|
|
5287
|
+
const ageMs = now.getTime() - Date.parse(stamp);
|
|
5288
|
+
const ageDays = Math.max(0, ageMs / MS_PER_DAY);
|
|
5289
|
+
return ageDays > ttlDays ? { state: "stale", ageDays, refreshedAt: stamp } : { state: "fresh", ageDays, refreshedAt: stamp };
|
|
5290
|
+
}
|
|
5291
|
+
function shouldRefetch(state) {
|
|
5292
|
+
return state.state === "absent" || state.state === "undated" || state.state === "stale";
|
|
5293
|
+
}
|
|
5294
|
+
function freshnessMessage(state, catalogue) {
|
|
5295
|
+
switch (state.state) {
|
|
5296
|
+
case "absent":
|
|
5297
|
+
return `${catalogue}: not on this machine — run \`tlc harness prices refresh\``;
|
|
5298
|
+
case "undated":
|
|
5299
|
+
return `${catalogue}: present but carries no date — it will be refetched`;
|
|
5300
|
+
case "fresh":
|
|
5301
|
+
return `${catalogue}: ${describeAge(state.ageDays)} old`;
|
|
5302
|
+
default:
|
|
5303
|
+
return `${catalogue}: ${describeAge(state.ageDays)} old — run \`tlc harness prices refresh\``;
|
|
5304
|
+
}
|
|
5305
|
+
}
|
|
5306
|
+
var MIN_RETAINED_RATIO = 0.5;
|
|
5307
|
+
function mayReplace(existingCount, incomingCount, minRatio = MIN_RETAINED_RATIO) {
|
|
5308
|
+
if (incomingCount === 0) {
|
|
5309
|
+
return { replace: false, reason: "parsed no entries at all — the upstream format has changed" };
|
|
5310
|
+
}
|
|
5311
|
+
if (existingCount === 0) {
|
|
5312
|
+
return { replace: true, reason: `first catalogue, ${incomingCount} entries` };
|
|
5313
|
+
}
|
|
5314
|
+
if (incomingCount >= existingCount) {
|
|
5315
|
+
return { replace: true, reason: `${existingCount} → ${incomingCount} entries` };
|
|
5316
|
+
}
|
|
5317
|
+
const retained = incomingCount / existingCount;
|
|
5318
|
+
return retained >= minRatio ? { replace: true, reason: `${existingCount} → ${incomingCount} entries` } : {
|
|
5319
|
+
replace: false,
|
|
5320
|
+
reason: `would drop from ${existingCount} to ${incomingCount} entries, keeping the existing catalogue — the upstream format has probably changed`
|
|
5321
|
+
};
|
|
5322
|
+
}
|
|
5323
|
+
function describeAge(ageDays) {
|
|
5324
|
+
if (ageDays < 1) {
|
|
5325
|
+
const hours = Math.max(1, Math.round(ageDays * 24));
|
|
5326
|
+
return `${hours} hour${hours === 1 ? "" : "s"}`;
|
|
5327
|
+
}
|
|
5328
|
+
const days = Math.round(ageDays);
|
|
5329
|
+
return `${days} day${days === 1 ? "" : "s"}`;
|
|
5330
|
+
}
|
|
5331
|
+
|
|
5276
5332
|
// src/core/release/release.decisions.ts
|
|
5277
5333
|
import { existsSync as existsSync17, readdirSync as readdirSync5, readFileSync as readFileSync19 } from "node:fs";
|
|
5278
5334
|
import { join as join18 } from "node:path";
|
|
@@ -5622,7 +5678,8 @@ function linkHealth(target, runtimeHome2, probe) {
|
|
|
5622
5678
|
if (!probe.exists(resolved)) {
|
|
5623
5679
|
return { state: "dangling", target, resolved };
|
|
5624
5680
|
}
|
|
5625
|
-
const
|
|
5681
|
+
const resolveHome = probe.realpath ?? ((path) => path);
|
|
5682
|
+
const home = resolveHome(runtimeHome2).replace(/\/+$/, "");
|
|
5626
5683
|
return resolved === home || resolved.startsWith(`${home}/`) ? { state: "ok", target, resolved } : { state: "outside-runtime", target, resolved };
|
|
5627
5684
|
}
|
|
5628
5685
|
function linkHealthMessage(health) {
|
|
@@ -6769,6 +6826,12 @@ var coreFacade = {
|
|
|
6769
6826
|
coversHandler,
|
|
6770
6827
|
decideShim
|
|
6771
6828
|
},
|
|
6829
|
+
pricing: {
|
|
6830
|
+
freshness,
|
|
6831
|
+
freshnessMessage,
|
|
6832
|
+
mayReplace,
|
|
6833
|
+
shouldRefetch
|
|
6834
|
+
},
|
|
6772
6835
|
skill: {
|
|
6773
6836
|
linkHealth,
|
|
6774
6837
|
linkHealthMessage,
|
|
@@ -7719,14 +7782,9 @@ var ENTRY_SPECS2 = [
|
|
|
7719
7782
|
{ hookEvent: "stop", handler: "stop", timeoutSeconds: 120, loopLimit: 5 },
|
|
7720
7783
|
{ hookEvent: "afterAgentResponse", handler: "response-after", timeoutSeconds: 5, matcher: "AgentResponse" }
|
|
7721
7784
|
];
|
|
7722
|
-
function commandFor(runtime) {
|
|
7723
|
-
if (process.platform === "win32") {
|
|
7724
|
-
return { command: "cmd", argsPrefix: ["/c", "node", runtime.launcherPath] };
|
|
7725
|
-
}
|
|
7726
|
-
return { command: "node", argsPrefix: [runtime.launcherPath] };
|
|
7727
|
-
}
|
|
7728
7785
|
function cursorWiring(runtime) {
|
|
7729
|
-
const
|
|
7786
|
+
const command = "node";
|
|
7787
|
+
const argsPrefix = [runtime.launcherPath];
|
|
7730
7788
|
const entries = ENTRY_SPECS2.map((spec) => ({
|
|
7731
7789
|
hookEvent: spec.hookEvent,
|
|
7732
7790
|
handler: spec.handler,
|