skilld 0.9.5 → 0.9.6
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/_chunks/detect-imports.mjs +94 -58
- package/dist/_chunks/detect-imports.mjs.map +1 -1
- package/dist/_chunks/npm.mjs +19 -2
- package/dist/_chunks/npm.mjs.map +1 -1
- package/dist/_chunks/yaml.mjs +1 -20
- package/dist/_chunks/yaml.mjs.map +1 -1
- package/dist/agent/index.d.mts +1 -1
- package/dist/agent/index.d.mts.map +1 -1
- package/dist/cli.mjs +2 -2
- package/dist/sources/index.mjs +1 -1
- package/package.json +1 -1
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { t as __exportAll } from "./chunk.mjs";
|
|
2
2
|
import { _ as writeSections, b as sanitizeMarkdown, h as readCachedSection, y as repairMarkdown } from "./storage.mjs";
|
|
3
|
-
import {
|
|
3
|
+
import { o as getFilePatterns, s as getPackageRules, t as yamlEscape } from "./yaml.mjs";
|
|
4
4
|
import { homedir } from "node:os";
|
|
5
5
|
import { dirname, join, relative } from "pathe";
|
|
6
6
|
import { existsSync, lstatSync, mkdirSync, readFileSync, readdirSync, realpathSync, symlinkSync, unlinkSync, writeFileSync } from "node:fs";
|
|
@@ -8,6 +8,7 @@ import { exec, spawn, spawnSync } from "node:child_process";
|
|
|
8
8
|
import { globby } from "globby";
|
|
9
9
|
import { findDynamicImports, findStaticImports } from "mlly";
|
|
10
10
|
import { createHash } from "node:crypto";
|
|
11
|
+
import { setTimeout } from "node:timers/promises";
|
|
11
12
|
import { promisify } from "node:util";
|
|
12
13
|
import { readFile } from "node:fs/promises";
|
|
13
14
|
import { parseSync } from "oxc-parser";
|
|
@@ -1392,58 +1393,39 @@ const TOOL_VERBS = {
|
|
|
1392
1393
|
search_file_content: "Searching"
|
|
1393
1394
|
};
|
|
1394
1395
|
function createToolProgress(log) {
|
|
1395
|
-
|
|
1396
|
-
let
|
|
1397
|
-
|
|
1398
|
-
|
|
1399
|
-
|
|
1400
|
-
|
|
1401
|
-
|
|
1402
|
-
|
|
1403
|
-
|
|
1404
|
-
const msg = parts.join(" ");
|
|
1405
|
-
if (msg && msg !== lastEmitted) {
|
|
1396
|
+
let lastMsg = "";
|
|
1397
|
+
let repeatCount = 0;
|
|
1398
|
+
function emit(msg) {
|
|
1399
|
+
if (msg === lastMsg) {
|
|
1400
|
+
repeatCount++;
|
|
1401
|
+
log.message(`${msg} \x1B[90m(+${repeatCount})\x1B[0m`);
|
|
1402
|
+
} else {
|
|
1403
|
+
lastMsg = msg;
|
|
1404
|
+
repeatCount = 0;
|
|
1406
1405
|
log.message(msg);
|
|
1407
|
-
lastEmitted = msg;
|
|
1408
1406
|
}
|
|
1409
|
-
pending.clear();
|
|
1410
|
-
timer = null;
|
|
1411
1407
|
}
|
|
1412
1408
|
return ({ type, chunk, section }) => {
|
|
1413
1409
|
if (type === "text") {
|
|
1414
|
-
|
|
1410
|
+
emit(`${section ? `\x1B[90m[${section}]\x1B[0m ` : ""}Writing...`);
|
|
1415
1411
|
return;
|
|
1416
1412
|
}
|
|
1417
1413
|
if (type !== "reasoning" || !chunk.startsWith("[")) return;
|
|
1418
|
-
const
|
|
1419
|
-
const match = chunk.match(/^\[(\w+)(?:,\s\w+)*(?::\s(.+))?\]$/);
|
|
1414
|
+
const match = chunk.match(/^\[([^:[\]]+)(?::\s(.+))?\]$/);
|
|
1420
1415
|
if (!match) return;
|
|
1421
|
-
const
|
|
1422
|
-
const
|
|
1423
|
-
let
|
|
1424
|
-
|
|
1425
|
-
|
|
1426
|
-
const
|
|
1427
|
-
if (searchMatch) {
|
|
1428
|
-
verb = "skilld search:";
|
|
1429
|
-
path = searchMatch[1];
|
|
1430
|
-
} else path = hint.length > 60 ? `${hint.slice(0, 57)}...` : hint;
|
|
1431
|
-
} else path = shortenPath(path);
|
|
1432
|
-
if (rawName === "Write") {
|
|
1433
|
-
if (timer) flush();
|
|
1416
|
+
const names = match[1].split(",").map((n) => n.trim());
|
|
1417
|
+
const hints = match[2]?.split(",").map((h) => h.trim()) ?? [];
|
|
1418
|
+
for (let i = 0; i < names.length; i++) {
|
|
1419
|
+
const rawName = names[i];
|
|
1420
|
+
const hint = hints[i] ?? hints[0] ?? "";
|
|
1421
|
+
const verb = TOOL_VERBS[rawName] ?? rawName;
|
|
1434
1422
|
const prefix = section ? `\x1B[90m[${section}]\x1B[0m ` : "";
|
|
1435
|
-
|
|
1436
|
-
|
|
1423
|
+
if (rawName === "Bash" && hint) {
|
|
1424
|
+
const searchMatch = hint.match(/skilld search\s+"([^"]+)"/);
|
|
1425
|
+
if (searchMatch) emit(`${prefix}Searching \x1B[36m"${searchMatch[1]}"\x1B[0m`);
|
|
1426
|
+
else emit(`${prefix}Running ${hint.length > 50 ? `${hint.slice(0, 47)}...` : hint}`);
|
|
1427
|
+
} else emit(`${prefix}${verb} \x1B[90m${shortenPath(hint || "...")}\x1B[0m`);
|
|
1437
1428
|
}
|
|
1438
|
-
const entry = mapInsert(pending, key, () => ({
|
|
1439
|
-
verb,
|
|
1440
|
-
path,
|
|
1441
|
-
count: 0
|
|
1442
|
-
}));
|
|
1443
|
-
entry.verb = verb;
|
|
1444
|
-
entry.path = path;
|
|
1445
|
-
entry.count++;
|
|
1446
|
-
if (!timer) timer = setTimeout(flush, 400);
|
|
1447
1429
|
};
|
|
1448
1430
|
}
|
|
1449
1431
|
const CLI_DEFS = [
|
|
@@ -1622,13 +1604,16 @@ function optimizeSection(opts) {
|
|
|
1622
1604
|
} catch {}
|
|
1623
1605
|
}
|
|
1624
1606
|
const raw = (existsSync(outputPath) ? readFileSync(outputPath, "utf-8") : lastWriteContent || accumulatedText).trim();
|
|
1607
|
+
const logsDir = join(skilldDir, "logs");
|
|
1608
|
+
const logName = section.toUpperCase().replace(/-/g, "_");
|
|
1609
|
+
if (debug || stderr && (!raw || code !== 0)) {
|
|
1610
|
+
mkdirSync(logsDir, { recursive: true });
|
|
1611
|
+
if (stderr) writeFileSync(join(logsDir, `${logName}.stderr.log`), stderr);
|
|
1612
|
+
}
|
|
1625
1613
|
if (debug) {
|
|
1626
|
-
const logsDir = join(skilldDir, "logs");
|
|
1627
1614
|
mkdirSync(logsDir, { recursive: true });
|
|
1628
|
-
const logName = section.toUpperCase().replace(/-/g, "_");
|
|
1629
1615
|
if (rawLines.length) writeFileSync(join(logsDir, `${logName}.jsonl`), rawLines.join("\n"));
|
|
1630
1616
|
if (raw) writeFileSync(join(logsDir, `${logName}.md`), raw);
|
|
1631
|
-
if (stderr) writeFileSync(join(logsDir, `${logName}.stderr.log`), stderr);
|
|
1632
1617
|
}
|
|
1633
1618
|
if (!raw && code !== 0) {
|
|
1634
1619
|
resolve({
|
|
@@ -1739,10 +1724,22 @@ async function optimizeDocs(opts) {
|
|
|
1739
1724
|
}
|
|
1740
1725
|
const skilldDir = join(skillDir, ".skilld");
|
|
1741
1726
|
mkdirSync(skilldDir, { recursive: true });
|
|
1727
|
+
for (const entry of readdirSync(skilldDir)) {
|
|
1728
|
+
const entryPath = join(skilldDir, entry);
|
|
1729
|
+
try {
|
|
1730
|
+
if (lstatSync(entryPath).isSymbolicLink() && !existsSync(entryPath)) onProgress?.({
|
|
1731
|
+
chunk: `[warn: broken symlink .skilld/${entry}]`,
|
|
1732
|
+
type: "reasoning",
|
|
1733
|
+
text: "",
|
|
1734
|
+
reasoning: ""
|
|
1735
|
+
});
|
|
1736
|
+
} catch {}
|
|
1737
|
+
}
|
|
1742
1738
|
const preExistingFiles = new Set(readdirSync(skilldDir));
|
|
1743
|
-
const
|
|
1739
|
+
const STAGGER_MS = 3e3;
|
|
1740
|
+
const spawnResults = uncachedSections.length > 0 ? await Promise.allSettled(uncachedSections.map(({ section, prompt }, i) => {
|
|
1744
1741
|
const outputFile = SECTION_OUTPUT_FILES[section];
|
|
1745
|
-
|
|
1742
|
+
const run = () => optimizeSection({
|
|
1746
1743
|
section,
|
|
1747
1744
|
prompt,
|
|
1748
1745
|
outputFile,
|
|
@@ -1754,32 +1751,71 @@ async function optimizeDocs(opts) {
|
|
|
1754
1751
|
debug,
|
|
1755
1752
|
preExistingFiles
|
|
1756
1753
|
});
|
|
1754
|
+
if (i === 0) return run();
|
|
1755
|
+
return setTimeout(i * STAGGER_MS).then(run);
|
|
1757
1756
|
})) : [];
|
|
1758
1757
|
const allResults = [...cachedResults];
|
|
1759
1758
|
let totalUsage;
|
|
1760
1759
|
let totalCost = 0;
|
|
1760
|
+
const retryQueue = [];
|
|
1761
1761
|
for (let i = 0; i < spawnResults.length; i++) {
|
|
1762
1762
|
const r = spawnResults[i];
|
|
1763
1763
|
const { section, prompt } = uncachedSections[i];
|
|
1764
|
-
if (r.status === "fulfilled") {
|
|
1765
|
-
|
|
1766
|
-
|
|
1767
|
-
if (result.wasOptimized && !noCache) setCache(prompt, model, section, result.content);
|
|
1768
|
-
if (result.usage) {
|
|
1764
|
+
if (r.status === "fulfilled" && r.value.wasOptimized) {
|
|
1765
|
+
allResults.push(r.value);
|
|
1766
|
+
if (r.value.usage) {
|
|
1769
1767
|
totalUsage = totalUsage ?? {
|
|
1770
1768
|
input: 0,
|
|
1771
1769
|
output: 0
|
|
1772
1770
|
};
|
|
1773
|
-
totalUsage.input +=
|
|
1774
|
-
totalUsage.output +=
|
|
1771
|
+
totalUsage.input += r.value.usage.input;
|
|
1772
|
+
totalUsage.output += r.value.usage.output;
|
|
1775
1773
|
}
|
|
1776
|
-
if (
|
|
1777
|
-
|
|
1774
|
+
if (r.value.cost != null) totalCost += r.value.cost;
|
|
1775
|
+
if (!noCache) setCache(prompt, model, section, r.value.content);
|
|
1776
|
+
} else retryQueue.push({
|
|
1777
|
+
index: i,
|
|
1778
|
+
section,
|
|
1779
|
+
prompt
|
|
1780
|
+
});
|
|
1781
|
+
}
|
|
1782
|
+
for (const { section, prompt } of retryQueue) {
|
|
1783
|
+
onProgress?.({
|
|
1784
|
+
chunk: `[${section}: retrying...]`,
|
|
1785
|
+
type: "reasoning",
|
|
1786
|
+
text: "",
|
|
1787
|
+
reasoning: "",
|
|
1788
|
+
section
|
|
1789
|
+
});
|
|
1790
|
+
await setTimeout(STAGGER_MS);
|
|
1791
|
+
const result = await optimizeSection({
|
|
1792
|
+
section,
|
|
1793
|
+
prompt,
|
|
1794
|
+
outputFile: SECTION_OUTPUT_FILES[section],
|
|
1795
|
+
skillDir,
|
|
1796
|
+
model,
|
|
1797
|
+
packageName,
|
|
1798
|
+
onProgress,
|
|
1799
|
+
timeout,
|
|
1800
|
+
debug,
|
|
1801
|
+
preExistingFiles
|
|
1802
|
+
}).catch((err) => ({
|
|
1778
1803
|
section,
|
|
1779
1804
|
content: "",
|
|
1780
1805
|
wasOptimized: false,
|
|
1781
|
-
error:
|
|
1782
|
-
});
|
|
1806
|
+
error: err.message
|
|
1807
|
+
}));
|
|
1808
|
+
allResults.push(result);
|
|
1809
|
+
if (result.wasOptimized && !noCache) setCache(prompt, model, section, result.content);
|
|
1810
|
+
if (result.usage) {
|
|
1811
|
+
totalUsage = totalUsage ?? {
|
|
1812
|
+
input: 0,
|
|
1813
|
+
output: 0
|
|
1814
|
+
};
|
|
1815
|
+
totalUsage.input += result.usage.input;
|
|
1816
|
+
totalUsage.output += result.usage.output;
|
|
1817
|
+
}
|
|
1818
|
+
if (result.cost != null) totalCost += result.cost;
|
|
1783
1819
|
}
|
|
1784
1820
|
if (version) {
|
|
1785
1821
|
const sectionFiles = allResults.filter((r) => r.wasOptimized && r.content).map((r) => ({
|