opencode-usage-coach 0.11.1 → 0.11.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/index.js +17 -8
- package/package.json +1 -1
package/dist/index.js
CHANGED
|
@@ -217,7 +217,7 @@ function truncate(input, max) {
|
|
|
217
217
|
return text.length > max ? `${text.slice(0, max)}...` : text;
|
|
218
218
|
}
|
|
219
219
|
function sanitizeQuery(raw) {
|
|
220
|
-
return raw.replace(/```[\s\S]*?```/g, " ").replace(/`[^`]*`/g, " ").replace(/
|
|
220
|
+
return raw.replace(/```[\s\S]*?```/g, " ").replace(/`[^`]*`/g, " ").replace(/https?:\/\/\S+/g, " ").replace(/[^\p{L}\p{N}\s]/gu, " ").replace(/\b(NOT|AND|OR)\b/gi, " ").replace(/\s+/g, " ").trim().slice(0, GH_QUERY_MAX);
|
|
221
221
|
}
|
|
222
222
|
function effectiveFrameworks(frameworks, keyDeps) {
|
|
223
223
|
const set = new Set((frameworks || []).filter(Boolean));
|
|
@@ -249,13 +249,15 @@ async function tier1OfficialDocs(query, fws, results, docRefs, seen, signal) {
|
|
|
249
249
|
if (entry) docRefs.push({ name: entry.name, url: entry.docs });
|
|
250
250
|
}
|
|
251
251
|
if (!query) return errors;
|
|
252
|
+
const cleanQuery = sanitizeQuery(query);
|
|
253
|
+
if (!cleanQuery) return errors;
|
|
252
254
|
for (const fw of fws) {
|
|
253
255
|
if (signal.aborted || results.length >= TARGET_RESULT_COUNT) break;
|
|
254
256
|
const entry = FRAMEWORK_DOCS[fw];
|
|
255
257
|
if (!entry?.githubOrg) continue;
|
|
256
258
|
try {
|
|
257
|
-
const
|
|
258
|
-
const url = `https://api.github.com/search/issues?q=${encodeURIComponent(
|
|
259
|
+
const fullQ = `${cleanQuery} org:${entry.githubOrg}`;
|
|
260
|
+
const url = `https://api.github.com/search/issues?q=${encodeURIComponent(fullQ)}&per_page=3`;
|
|
259
261
|
const data = await ghFetch(url, signal);
|
|
260
262
|
for (const item of data.items ?? []) {
|
|
261
263
|
pushResult(results, seen, {
|
|
@@ -276,7 +278,9 @@ async function tier1OfficialDocs(query, fws, results, docRefs, seen, signal) {
|
|
|
276
278
|
async function tier2GitHubIssues(query, results, seen, signal) {
|
|
277
279
|
const errors = [];
|
|
278
280
|
try {
|
|
279
|
-
const
|
|
281
|
+
const q = sanitizeQuery(query);
|
|
282
|
+
if (!q) return errors;
|
|
283
|
+
const url = `https://api.github.com/search/issues?q=${encodeURIComponent(q)}&per_page=5`;
|
|
280
284
|
const data = await ghFetch(url, signal);
|
|
281
285
|
for (const item of data.items ?? []) {
|
|
282
286
|
pushResult(results, seen, {
|
|
@@ -297,7 +301,9 @@ async function tier3GitHubCode(query, results, seen, signal) {
|
|
|
297
301
|
const errors = [];
|
|
298
302
|
if (!ghToken()) return errors;
|
|
299
303
|
try {
|
|
300
|
-
const
|
|
304
|
+
const q = sanitizeQuery(query);
|
|
305
|
+
if (!q) return errors;
|
|
306
|
+
const url = `https://api.github.com/search/code?q=${encodeURIComponent(q)}&per_page=3`;
|
|
301
307
|
const data = await ghFetch(url, signal);
|
|
302
308
|
for (const item of data.items ?? []) {
|
|
303
309
|
const repo = item.repository?.full_name;
|
|
@@ -1613,6 +1619,7 @@ PATH A \u2014 INDEPENDENT (parallel via generate_batch):
|
|
|
1613
1619
|
4. for each i: PASS -> task_update(i, title, "completed", "PASS"); FAIL -> revise (up to 2x) or task_update(i, title, "failed", "FAIL")
|
|
1614
1620
|
|
|
1615
1621
|
PATH B \u2014 DEPENDENT (sequential):
|
|
1622
|
+
Optional: task_update(1..N, title, "pending") \u2190 pre-register all tasks first
|
|
1616
1623
|
for i in 1..${args.total}:
|
|
1617
1624
|
1. task_update(i, title, "generating")
|
|
1618
1625
|
2. generate({prompt:"Task: <title>. Perform it."}) -> work + NEXT
|
|
@@ -1795,21 +1802,23 @@ Then: harness_done(). Follow the [usage-coach NEXT] directive each tool returns.
|
|
|
1795
1802
|
args: {
|
|
1796
1803
|
id: tool.schema.number(),
|
|
1797
1804
|
title: tool.schema.string(),
|
|
1798
|
-
status: tool.schema.string().describe("generating | grading | revising | completed | failed | timed_out"),
|
|
1805
|
+
status: tool.schema.string().describe("pending | generating | grading | revising | completed | failed | timed_out"),
|
|
1799
1806
|
revisions: tool.schema.number().optional(),
|
|
1800
1807
|
score: tool.schema.string().optional().describe("PASS | FAIL"),
|
|
1801
1808
|
model: tool.schema.string().optional()
|
|
1802
1809
|
},
|
|
1803
1810
|
async execute(args, ctx) {
|
|
1811
|
+
const VALID_STATUSES = ["pending", "generating", "grading", "revising", "completed", "failed", "timed_out", "halted_quota"];
|
|
1812
|
+
const status = args.status && VALID_STATUSES.includes(args.status) ? args.status : "generating";
|
|
1804
1813
|
const cfg = readHarnessCfg(ctx.directory);
|
|
1805
1814
|
const h = readHarness(ctx.sessionID) ?? { name: "batch", total: 0, current: 0, tasks: [], usage: {}, active: true };
|
|
1806
1815
|
h.tasks = h.tasks.filter((x) => x.id !== args.id);
|
|
1807
1816
|
const model = args.model || cfg.generator || "";
|
|
1808
1817
|
if (!model) return `ERROR: task ${args.id} has no model and no generator configured. Set "generator" in harness.config.json.`;
|
|
1809
|
-
h.tasks.push({ id: args.id, title: args.title, status
|
|
1818
|
+
h.tasks.push({ id: args.id, title: args.title, status, model, revisions: args.revisions ?? 0, score: args.score ?? null, startedAt: (/* @__PURE__ */ new Date()).toISOString() });
|
|
1810
1819
|
if (args.id > h.current) h.current = args.id;
|
|
1811
1820
|
writeHarness(ctx.sessionID, h);
|
|
1812
|
-
return `task ${args.id} -> ${
|
|
1821
|
+
return `task ${args.id} -> ${status}${args.score ? ` (${args.score})` : ""}`;
|
|
1813
1822
|
}
|
|
1814
1823
|
}),
|
|
1815
1824
|
harness_done: tool({
|
package/package.json
CHANGED