skilld 0.7.0 → 0.8.2
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 +20 -9
- package/dist/_chunks/config.mjs.map +1 -1
- package/dist/_chunks/detect-imports.mjs +112 -25
- package/dist/_chunks/detect-imports.mjs.map +1 -1
- package/dist/_chunks/embedding-cache.mjs.map +1 -1
- package/dist/_chunks/npm.mjs +206 -86
- package/dist/_chunks/npm.mjs.map +1 -1
- package/dist/_chunks/pool2.mjs.map +1 -1
- package/dist/_chunks/storage.mjs.map +1 -1
- package/dist/_chunks/utils.d.mts +19 -7
- package/dist/_chunks/utils.d.mts.map +1 -1
- package/dist/_chunks/yaml.mjs +55 -2
- package/dist/_chunks/yaml.mjs.map +1 -1
- package/dist/agent/index.d.mts +26 -19
- package/dist/agent/index.d.mts.map +1 -1
- package/dist/agent/index.mjs +2 -2
- package/dist/cli.mjs +260 -246
- package/dist/cli.mjs.map +1 -1
- package/dist/index.d.mts +1 -1
- package/dist/retriv/index.mjs.map +1 -1
- package/dist/retriv/worker.mjs.map +1 -1
- package/dist/sources/index.d.mts +2 -2
- package/dist/sources/index.mjs +3 -3
- package/dist/types.d.mts +1 -1
- package/package.json +8 -7
package/dist/cli.mjs
CHANGED
|
@@ -5,21 +5,22 @@ import { a as getShippedSkills, b as sanitizeMarkdown, c as linkCachedDir, d as
|
|
|
5
5
|
import "./cache/index.mjs";
|
|
6
6
|
import { n as clearEmbeddingCache } from "./_chunks/embedding-cache.mjs";
|
|
7
7
|
import { closePool, createIndex, openPool, searchPooled, searchSnippets } from "./retriv/index.mjs";
|
|
8
|
-
import { i as
|
|
9
|
-
import { A as resolveEntryFiles, D as fetchGitSkills,
|
|
8
|
+
import { a as getSharedSkillsDir, i as SHARED_SKILLS_DIR, n as yamlParseKV, o as mapInsert, r as yamlUnescape, s as getBlogPreset, t as yamlEscape } from "./_chunks/yaml.mjs";
|
|
9
|
+
import { A as resolveEntryFiles, B as $fetch, D as fetchGitSkills, G as parseGitHubUrl, I as fetchReleaseNotes, J as formatIssueAsMarkdown, L as generateReleaseIndex, M as formatDiscussionAsMarkdown, N as generateDiscussionIndex, O as parseGitSkillInput, P as fetchBlogReleases, T as isShallowGitDocs, X as isGhAvailable, Y as generateIssueIndex, d as resolvePackageDocs, f as resolvePackageDocsWithAttempts, g as fetchLlmsTxt, i as fetchPkgDist, j as fetchGitHubDiscussions, m as downloadLlmsDocs, n as fetchNpmPackage, p as searchNpmPackages, q as fetchGitHubIssues, r as fetchNpmRegistryMeta, s as readLocalDependencies, t as fetchLatestVersion, u as resolveLocalPackageDocs, v as normalizeLlmsLinks, w as fetchReadmeContent, x as fetchGitDocs } from "./_chunks/npm.mjs";
|
|
10
10
|
import "./sources/index.mjs";
|
|
11
|
-
import { _ as
|
|
11
|
+
import { S as targets, _ as maxItems, a as getModelName, b as detectTargetAgent, c as computeSkillDirName, f as unlinkSkillFromAgents, i as getModelLabel, n as createToolProgress, o as optimizeDocs, r as getAvailableModels, s as generateSkillMd, t as detectImportedPackages, u as linkSkillToAgents, v as maxLines, x as getAgentVersion, y as detectInstalledAgents } from "./_chunks/detect-imports.mjs";
|
|
12
12
|
import "./agent/index.mjs";
|
|
13
13
|
import { n as shutdownWorker } from "./_chunks/pool2.mjs";
|
|
14
14
|
import { createRequire } from "node:module";
|
|
15
15
|
import { homedir } from "node:os";
|
|
16
16
|
import { dirname, join, relative, resolve } from "pathe";
|
|
17
17
|
import { appendFileSync, copyFileSync, existsSync, lstatSync, mkdirSync, readFileSync, readdirSync, realpathSync, rmSync, statSync, symlinkSync, unlinkSync, writeFileSync } from "node:fs";
|
|
18
|
-
import { execSync
|
|
18
|
+
import { execSync } from "node:child_process";
|
|
19
19
|
import pLimit from "p-limit";
|
|
20
20
|
import * as p from "@clack/prompts";
|
|
21
21
|
import { defineCommand, runMain } from "citty";
|
|
22
22
|
import { detectCurrentAgent } from "unagent/env";
|
|
23
|
+
import { isCI } from "std-env";
|
|
23
24
|
import logUpdate, { createLogUpdate } from "log-update";
|
|
24
25
|
const defaultFeatures = {
|
|
25
26
|
search: true,
|
|
@@ -450,11 +451,6 @@ function removeLockEntry(skillsDir, skillName) {
|
|
|
450
451
|
}
|
|
451
452
|
writeFileSync(lockPath, serializeLock(lock));
|
|
452
453
|
}
|
|
453
|
-
const SHARED_SKILLS_DIR = ".skills";
|
|
454
|
-
function getSharedSkillsDir(cwd = process.cwd()) {
|
|
455
|
-
const dir = join(cwd, SHARED_SKILLS_DIR);
|
|
456
|
-
return existsSync(dir) ? dir : null;
|
|
457
|
-
}
|
|
458
454
|
function* iterateSkills(opts = {}) {
|
|
459
455
|
const { scope = "all", cwd = process.cwd() } = opts;
|
|
460
456
|
const agentTypes = opts.agents ?? Object.keys(targets);
|
|
@@ -546,7 +542,8 @@ function* iterateSkills(opts = {}) {
|
|
|
546
542
|
}
|
|
547
543
|
function isOutdated(skill, depVersion) {
|
|
548
544
|
if (!skill.info?.version) return true;
|
|
549
|
-
|
|
545
|
+
const depClean = depVersion.replace(/^[\^~]/, "");
|
|
546
|
+
return skill.info.version !== depClean;
|
|
550
547
|
}
|
|
551
548
|
async function getProjectState(cwd = process.cwd()) {
|
|
552
549
|
const skills = [...iterateSkills({
|
|
@@ -804,61 +801,6 @@ function formatCompactSnippet(r, cols) {
|
|
|
804
801
|
preview: firstLine.length > maxPreview ? `${firstLine.slice(0, maxPreview - 1)}…` : firstLine
|
|
805
802
|
};
|
|
806
803
|
}
|
|
807
|
-
async function syncGitSkills(opts) {
|
|
808
|
-
const { source, agent, global: isGlobal, yes } = opts;
|
|
809
|
-
const cwd = process.cwd();
|
|
810
|
-
const agentConfig = targets[agent];
|
|
811
|
-
const baseDir = isGlobal ? join(CACHE_DIR, "skills") : join(cwd, agentConfig.skillsDir);
|
|
812
|
-
const label = source.type === "local" ? source.localPath : `${source.owner}/${source.repo}`;
|
|
813
|
-
const spin = timedSpinner();
|
|
814
|
-
spin.start(`Fetching skills from ${label}`);
|
|
815
|
-
const { skills, commitSha } = await fetchGitSkills(source, (msg) => spin.message(msg));
|
|
816
|
-
if (skills.length === 0) {
|
|
817
|
-
spin.stop(`No skills found in ${label}`);
|
|
818
|
-
return;
|
|
819
|
-
}
|
|
820
|
-
spin.stop(`Found ${skills.length} skill(s) in ${label}`);
|
|
821
|
-
let selected = skills;
|
|
822
|
-
if (source.skillPath) selected = skills;
|
|
823
|
-
else if (skills.length > 1 && !yes) {
|
|
824
|
-
const choices = await p.multiselect({
|
|
825
|
-
message: `Select skills to install from ${label}`,
|
|
826
|
-
options: skills.map((s) => ({
|
|
827
|
-
label: s.name,
|
|
828
|
-
value: s.name,
|
|
829
|
-
hint: s.description || s.path
|
|
830
|
-
})),
|
|
831
|
-
initialValues: skills.map((s) => s.name)
|
|
832
|
-
});
|
|
833
|
-
if (p.isCancel(choices)) return;
|
|
834
|
-
const selectedNames = new Set(choices);
|
|
835
|
-
selected = skills.filter((s) => selectedNames.has(s.name));
|
|
836
|
-
}
|
|
837
|
-
mkdirSync(baseDir, { recursive: true });
|
|
838
|
-
for (const skill of selected) {
|
|
839
|
-
const skillDir = join(baseDir, skill.name);
|
|
840
|
-
mkdirSync(skillDir, { recursive: true });
|
|
841
|
-
writeFileSync(join(skillDir, "SKILL.md"), sanitizeMarkdown(skill.content));
|
|
842
|
-
if (skill.files.length > 0) for (const f of skill.files) {
|
|
843
|
-
const filePath = join(skillDir, ".skilld", f.path);
|
|
844
|
-
mkdirSync(dirname(filePath), { recursive: true });
|
|
845
|
-
writeFileSync(filePath, f.content);
|
|
846
|
-
}
|
|
847
|
-
const sourceType = source.type === "local" ? "local" : source.type;
|
|
848
|
-
writeLock(baseDir, skill.name, {
|
|
849
|
-
source: sourceType,
|
|
850
|
-
repo: source.type === "local" ? source.localPath : `${source.owner}/${source.repo}`,
|
|
851
|
-
path: skill.path || void 0,
|
|
852
|
-
ref: source.ref || "main",
|
|
853
|
-
commit: commitSha,
|
|
854
|
-
syncedAt: (/* @__PURE__ */ new Date()).toISOString().split("T")[0],
|
|
855
|
-
generator: "external"
|
|
856
|
-
});
|
|
857
|
-
}
|
|
858
|
-
if (!isGlobal) registerProject(cwd);
|
|
859
|
-
const names = selected.map((s) => `\x1B[36m${s.name}\x1B[0m`).join(", ");
|
|
860
|
-
p.log.success(`Installed ${names}`);
|
|
861
|
-
}
|
|
862
804
|
const RESOLVE_STEP_LABELS = {
|
|
863
805
|
"npm": "npm registry",
|
|
864
806
|
"github-docs": "GitHub docs",
|
|
@@ -1308,6 +1250,84 @@ async function indexResources(opts) {
|
|
|
1308
1250
|
}
|
|
1309
1251
|
});
|
|
1310
1252
|
}
|
|
1253
|
+
const TELEMETRY_URL = "https://add-skill.vercel.sh/t";
|
|
1254
|
+
const SKILLS_VERSION = "1.3.9";
|
|
1255
|
+
function isEnabled() {
|
|
1256
|
+
return !process.env.DISABLE_TELEMETRY && !process.env.DO_NOT_TRACK;
|
|
1257
|
+
}
|
|
1258
|
+
function track(data) {
|
|
1259
|
+
if (!isEnabled()) return;
|
|
1260
|
+
try {
|
|
1261
|
+
const params = new URLSearchParams();
|
|
1262
|
+
params.set("v", SKILLS_VERSION);
|
|
1263
|
+
if (isCI) params.set("ci", "1");
|
|
1264
|
+
for (const [key, value] of Object.entries(data)) if (value !== void 0 && value !== null) params.set(key, String(value));
|
|
1265
|
+
fetch(`${TELEMETRY_URL}?${params.toString()}`).catch(() => {});
|
|
1266
|
+
} catch {}
|
|
1267
|
+
}
|
|
1268
|
+
async function syncGitSkills(opts) {
|
|
1269
|
+
const { source, agent, global: isGlobal, yes } = opts;
|
|
1270
|
+
const cwd = process.cwd();
|
|
1271
|
+
const agentConfig = targets[agent];
|
|
1272
|
+
const baseDir = isGlobal ? join(CACHE_DIR, "skills") : join(cwd, agentConfig.skillsDir);
|
|
1273
|
+
const label = source.type === "local" ? source.localPath : `${source.owner}/${source.repo}`;
|
|
1274
|
+
const spin = timedSpinner();
|
|
1275
|
+
spin.start(`Fetching skills from ${label}`);
|
|
1276
|
+
const { skills, commitSha } = await fetchGitSkills(source, (msg) => spin.message(msg));
|
|
1277
|
+
if (skills.length === 0) {
|
|
1278
|
+
spin.stop(`No skills found in ${label}`);
|
|
1279
|
+
return;
|
|
1280
|
+
}
|
|
1281
|
+
spin.stop(`Found ${skills.length} skill(s) in ${label}`);
|
|
1282
|
+
let selected = skills;
|
|
1283
|
+
if (source.skillPath) selected = skills;
|
|
1284
|
+
else if (skills.length > 1 && !yes) {
|
|
1285
|
+
const choices = await p.multiselect({
|
|
1286
|
+
message: `Select skills to install from ${label}`,
|
|
1287
|
+
options: skills.map((s) => ({
|
|
1288
|
+
label: s.name,
|
|
1289
|
+
value: s.name,
|
|
1290
|
+
hint: s.description || s.path
|
|
1291
|
+
})),
|
|
1292
|
+
initialValues: skills.map((s) => s.name)
|
|
1293
|
+
});
|
|
1294
|
+
if (p.isCancel(choices)) return;
|
|
1295
|
+
const selectedNames = new Set(choices);
|
|
1296
|
+
selected = skills.filter((s) => selectedNames.has(s.name));
|
|
1297
|
+
}
|
|
1298
|
+
mkdirSync(baseDir, { recursive: true });
|
|
1299
|
+
for (const skill of selected) {
|
|
1300
|
+
const skillDir = join(baseDir, skill.name);
|
|
1301
|
+
mkdirSync(skillDir, { recursive: true });
|
|
1302
|
+
writeFileSync(join(skillDir, "SKILL.md"), sanitizeMarkdown(skill.content));
|
|
1303
|
+
if (skill.files.length > 0) for (const f of skill.files) {
|
|
1304
|
+
const filePath = join(skillDir, ".skilld", f.path);
|
|
1305
|
+
mkdirSync(dirname(filePath), { recursive: true });
|
|
1306
|
+
writeFileSync(filePath, f.content);
|
|
1307
|
+
}
|
|
1308
|
+
const sourceType = source.type === "local" ? "local" : source.type;
|
|
1309
|
+
writeLock(baseDir, skill.name, {
|
|
1310
|
+
source: sourceType,
|
|
1311
|
+
repo: source.type === "local" ? source.localPath : `${source.owner}/${source.repo}`,
|
|
1312
|
+
path: skill.path || void 0,
|
|
1313
|
+
ref: source.ref || "main",
|
|
1314
|
+
commit: commitSha,
|
|
1315
|
+
syncedAt: (/* @__PURE__ */ new Date()).toISOString().split("T")[0],
|
|
1316
|
+
generator: "external"
|
|
1317
|
+
});
|
|
1318
|
+
}
|
|
1319
|
+
if (!isGlobal) registerProject(cwd);
|
|
1320
|
+
if (source.type !== "local" && source.owner && source.repo) track({
|
|
1321
|
+
event: "install",
|
|
1322
|
+
source: `${source.owner}/${source.repo}`,
|
|
1323
|
+
skills: selected.map((s) => s.name).join(","),
|
|
1324
|
+
agents: agent,
|
|
1325
|
+
...isGlobal && { global: "1" },
|
|
1326
|
+
sourceType: source.type
|
|
1327
|
+
});
|
|
1328
|
+
const names = selected.map((s) => `\x1B[36m${s.name}\x1B[0m`).join(", ");
|
|
1329
|
+
p.log.success(`Installed ${names}`);
|
|
1330
|
+
}
|
|
1311
1331
|
const STATUS_ICONS = {
|
|
1312
1332
|
pending: "○",
|
|
1313
1333
|
resolving: "◐",
|
|
@@ -1355,7 +1375,7 @@ async function syncPackagesParallel(config) {
|
|
|
1355
1375
|
});
|
|
1356
1376
|
const doneCount = [...states.values()].filter((s) => s.status === "done").length;
|
|
1357
1377
|
const errorCount = [...states.values()].filter((s) => s.status === "error").length;
|
|
1358
|
-
logUpdate(`\x1B[
|
|
1378
|
+
logUpdate(`\x1B[1m${config.mode === "update" ? "Updating" : "Syncing"} ${packages.length} packages\x1B[0m (${doneCount} done${errorCount > 0 ? `, ${errorCount} failed` : ""})\n` + lines.join("\n"));
|
|
1359
1379
|
}
|
|
1360
1380
|
function update(pkg, status, message, version) {
|
|
1361
1381
|
const state = states.get(pkg);
|
|
@@ -1391,7 +1411,8 @@ async function syncPackagesParallel(config) {
|
|
|
1391
1411
|
});
|
|
1392
1412
|
}
|
|
1393
1413
|
}
|
|
1394
|
-
const
|
|
1414
|
+
const pastVerb = config.mode === "update" ? "Updated" : "Created";
|
|
1415
|
+
const skillMsg = `${pastVerb} ${successfulPkgs.length} base skills${shippedPkgs.length > 1 ? ` (Skipping ${shippedPkgs.length})` : ""}`;
|
|
1395
1416
|
p.log.success(skillMsg);
|
|
1396
1417
|
for (const [, data] of skillData) for (const w of data.warnings) p.log.warn(`\x1B[33m${w}\x1B[0m`);
|
|
1397
1418
|
if (errors.length > 0) for (const { pkg, reason } of errors) p.log.error(` ${pkg}: ${reason}`);
|
|
@@ -1418,7 +1439,7 @@ async function syncPackagesParallel(config) {
|
|
|
1418
1439
|
await ensureGitignore(getSharedSkillsDir(cwd) ? SHARED_SKILLS_DIR : agent.skillsDir, cwd, config.global);
|
|
1419
1440
|
await ensureAgentInstructions(config.agent, cwd, config.global);
|
|
1420
1441
|
await shutdownWorker();
|
|
1421
|
-
p.outro(
|
|
1442
|
+
p.outro(`${pastVerb} ${successfulPkgs.length}/${packages.length} packages`);
|
|
1422
1443
|
}
|
|
1423
1444
|
async function syncBaseSkill(packageName, config, cwd, update) {
|
|
1424
1445
|
const localVersion = (await readLocalDependencies(cwd).catch(() => [])).find((d) => d.name === packageName)?.version;
|
|
@@ -1526,7 +1547,7 @@ async function syncBaseSkill(packageName, config, cwd, update) {
|
|
|
1526
1547
|
const shared = !config.global && getSharedSkillsDir(cwd);
|
|
1527
1548
|
if (shared) linkSkillToAgents(skillDirName, shared, cwd);
|
|
1528
1549
|
if (!config.global) registerProject(cwd);
|
|
1529
|
-
update(packageName, "done", "Base skill created", versionKey);
|
|
1550
|
+
update(packageName, "done", config.mode === "update" ? "Skill updated" : "Base skill created", versionKey);
|
|
1530
1551
|
return {
|
|
1531
1552
|
resolved,
|
|
1532
1553
|
version,
|
|
@@ -1601,6 +1622,98 @@ async function enhanceWithLLM(packageName, data, config, cwd, update, sections,
|
|
|
1601
1622
|
}
|
|
1602
1623
|
update(packageName, "done", "Skill optimized", versionKey);
|
|
1603
1624
|
}
|
|
1625
|
+
function hasGhCli() {
|
|
1626
|
+
if (process.env.SKILLD_NO_GH) return false;
|
|
1627
|
+
try {
|
|
1628
|
+
execSync("gh --version", { stdio: "ignore" });
|
|
1629
|
+
return true;
|
|
1630
|
+
} catch {
|
|
1631
|
+
return false;
|
|
1632
|
+
}
|
|
1633
|
+
}
|
|
1634
|
+
async function runWizard() {
|
|
1635
|
+
if (!isInteractive()) return;
|
|
1636
|
+
p.note("Skilld gives your AI agent skill knowledge on your NPM\ndependencies gathered from versioned docs, source code\nand GitHub issues.", "Welcome to skilld");
|
|
1637
|
+
const ghInstalled = hasGhCli();
|
|
1638
|
+
if (ghInstalled) p.log.success("GitHub CLI detected — will use it to pull issues and discussions.");
|
|
1639
|
+
else p.log.warn("GitHub CLI not found. Install it to enable issues/discussions:\n \x1B[36mhttps://cli.github.com\x1B[0m");
|
|
1640
|
+
const selected = await p.multiselect({
|
|
1641
|
+
message: "Which features would you like to enable?",
|
|
1642
|
+
options: [
|
|
1643
|
+
{
|
|
1644
|
+
label: "Semantic + token search",
|
|
1645
|
+
value: "search",
|
|
1646
|
+
hint: "local query engine to cut token costs and speed up grep"
|
|
1647
|
+
},
|
|
1648
|
+
{
|
|
1649
|
+
label: "Release notes",
|
|
1650
|
+
value: "releases",
|
|
1651
|
+
hint: "track changelogs for installed packages"
|
|
1652
|
+
},
|
|
1653
|
+
{
|
|
1654
|
+
label: "GitHub issues",
|
|
1655
|
+
value: "issues",
|
|
1656
|
+
hint: "surface common problems and solutions",
|
|
1657
|
+
disabled: !ghInstalled
|
|
1658
|
+
},
|
|
1659
|
+
{
|
|
1660
|
+
label: "GitHub discussions",
|
|
1661
|
+
value: "discussions",
|
|
1662
|
+
hint: "include Q&A and community knowledge",
|
|
1663
|
+
disabled: !ghInstalled
|
|
1664
|
+
}
|
|
1665
|
+
],
|
|
1666
|
+
initialValues: [...Object.entries(defaultFeatures).filter(([, v]) => v).map(([k]) => k), ...ghInstalled ? ["issues", "discussions"] : []],
|
|
1667
|
+
required: false
|
|
1668
|
+
});
|
|
1669
|
+
if (p.isCancel(selected)) {
|
|
1670
|
+
p.cancel("Setup cancelled");
|
|
1671
|
+
process.exit(0);
|
|
1672
|
+
}
|
|
1673
|
+
const features = {
|
|
1674
|
+
search: selected.includes("search"),
|
|
1675
|
+
issues: selected.includes("issues"),
|
|
1676
|
+
discussions: selected.includes("discussions"),
|
|
1677
|
+
releases: selected.includes("releases")
|
|
1678
|
+
};
|
|
1679
|
+
const allModels = process.env.SKILLD_NO_AGENTS ? [] : await getAvailableModels();
|
|
1680
|
+
let modelId;
|
|
1681
|
+
if (allModels.length > 0) {
|
|
1682
|
+
p.note("Skills work without an LLM, but one can rewrite your\nSKILL.md files with best practices and better structure.\n\x1B[90mThis is separate from the agent where skills are installed —\nthe target agent is auto-detected from your project files.\x1B[0m", "Optional: LLM optimization");
|
|
1683
|
+
const modelChoice = await p.select({
|
|
1684
|
+
message: "Model for generating SKILL.md",
|
|
1685
|
+
options: [{
|
|
1686
|
+
label: "Skip",
|
|
1687
|
+
value: "",
|
|
1688
|
+
hint: "use raw docs, no LLM needed"
|
|
1689
|
+
}, ...allModels.map((m) => ({
|
|
1690
|
+
label: m.recommended ? `${m.name} (Recommended)` : m.name,
|
|
1691
|
+
value: m.id,
|
|
1692
|
+
hint: `${m.agentName} · ${m.hint}`
|
|
1693
|
+
}))]
|
|
1694
|
+
});
|
|
1695
|
+
if (p.isCancel(modelChoice)) {
|
|
1696
|
+
p.cancel("Setup cancelled");
|
|
1697
|
+
process.exit(0);
|
|
1698
|
+
}
|
|
1699
|
+
modelId = modelChoice || void 0;
|
|
1700
|
+
} else {
|
|
1701
|
+
p.log.warn("No supported LLM CLIs detected (claude, gemini, codex).\n Skills will still work, but won't be LLM-optimized.");
|
|
1702
|
+
const proceed = await p.confirm({
|
|
1703
|
+
message: "Continue without LLM optimization?",
|
|
1704
|
+
initialValue: true
|
|
1705
|
+
});
|
|
1706
|
+
if (p.isCancel(proceed) || !proceed) {
|
|
1707
|
+
p.cancel("Setup cancelled");
|
|
1708
|
+
process.exit(0);
|
|
1709
|
+
}
|
|
1710
|
+
}
|
|
1711
|
+
updateConfig({
|
|
1712
|
+
features,
|
|
1713
|
+
...modelId ? { model: modelId } : { skipLlm: true }
|
|
1714
|
+
});
|
|
1715
|
+
p.outro("Thanks, you're all set! Change config anytime with `skilld config`.");
|
|
1716
|
+
}
|
|
1604
1717
|
var sync_exports = /* @__PURE__ */ __exportAll({
|
|
1605
1718
|
DEFAULT_SECTIONS: () => DEFAULT_SECTIONS,
|
|
1606
1719
|
SKILLD_MARKER_END: () => SKILLD_MARKER_END,
|
|
@@ -1686,7 +1799,8 @@ async function syncCommand(state, opts) {
|
|
|
1686
1799
|
model: opts.model,
|
|
1687
1800
|
yes: opts.yes,
|
|
1688
1801
|
force: opts.force,
|
|
1689
|
-
debug: opts.debug
|
|
1802
|
+
debug: opts.debug,
|
|
1803
|
+
mode: opts.mode
|
|
1690
1804
|
});
|
|
1691
1805
|
await syncSinglePackage(opts.packages[0], opts);
|
|
1692
1806
|
return;
|
|
@@ -1703,7 +1817,8 @@ async function syncCommand(state, opts) {
|
|
|
1703
1817
|
model: opts.model,
|
|
1704
1818
|
yes: opts.yes,
|
|
1705
1819
|
force: opts.force,
|
|
1706
|
-
debug: opts.debug
|
|
1820
|
+
debug: opts.debug,
|
|
1821
|
+
mode: opts.mode
|
|
1707
1822
|
});
|
|
1708
1823
|
await syncSinglePackage(packages[0], opts);
|
|
1709
1824
|
}
|
|
@@ -1790,6 +1905,7 @@ async function selectModel(skipPrompt) {
|
|
|
1790
1905
|
}
|
|
1791
1906
|
const DEFAULT_SECTIONS = ["best-practices", "api-changes"];
|
|
1792
1907
|
async function selectSkillSections(message = "Generate SKILL.md with LLM") {
|
|
1908
|
+
p.log.info("More sections = less budget each. Fewer sections = deeper coverage.");
|
|
1793
1909
|
const selected = await p.multiselect({
|
|
1794
1910
|
message,
|
|
1795
1911
|
options: [
|
|
@@ -1826,6 +1942,25 @@ async function selectSkillSections(message = "Generate SKILL.md with LLM") {
|
|
|
1826
1942
|
sections: [],
|
|
1827
1943
|
cancelled: false
|
|
1828
1944
|
};
|
|
1945
|
+
if (sections.length > 1) {
|
|
1946
|
+
const n = sections.length;
|
|
1947
|
+
const budgetLines = [];
|
|
1948
|
+
for (const s of sections) switch (s) {
|
|
1949
|
+
case "api-changes":
|
|
1950
|
+
budgetLines.push(` API changes ≤${maxLines(50, 80, n)} lines, ${maxItems(6, 12, n)} items`);
|
|
1951
|
+
break;
|
|
1952
|
+
case "best-practices":
|
|
1953
|
+
budgetLines.push(` Best practices ≤${maxLines(80, 150, n)} lines, ${maxItems(4, 10, n)} items`);
|
|
1954
|
+
break;
|
|
1955
|
+
case "api":
|
|
1956
|
+
budgetLines.push(` Doc map ≤${maxLines(15, 25, n)} lines`);
|
|
1957
|
+
break;
|
|
1958
|
+
case "custom":
|
|
1959
|
+
budgetLines.push(` Custom ≤${maxLines(50, 80, n)} lines`);
|
|
1960
|
+
break;
|
|
1961
|
+
}
|
|
1962
|
+
p.log.info(`Budget (${n} sections):\n${budgetLines.join("\n")}`);
|
|
1963
|
+
}
|
|
1829
1964
|
let customPrompt;
|
|
1830
1965
|
if (sections.includes("custom")) {
|
|
1831
1966
|
const heading = await p.text({
|
|
@@ -2054,7 +2189,7 @@ async function syncSinglePackage(packageName, config) {
|
|
|
2054
2189
|
features
|
|
2055
2190
|
});
|
|
2056
2191
|
writeFileSync(join(skillDir, "SKILL.md"), baseSkillMd);
|
|
2057
|
-
p.log.success(`Created base skill: ${relative(cwd, skillDir)}`);
|
|
2192
|
+
p.log.success(config.mode === "update" ? `Updated skill: ${relative(cwd, skillDir)}` : `Created base skill: ${relative(cwd, skillDir)}`);
|
|
2058
2193
|
if (!readConfig().skipLlm && (!config.yes || config.model)) {
|
|
2059
2194
|
const llmConfig = await selectLlmConfig(config.model);
|
|
2060
2195
|
if (llmConfig) {
|
|
@@ -2089,7 +2224,7 @@ async function syncSinglePackage(packageName, config) {
|
|
|
2089
2224
|
await ensureGitignore(shared ? SHARED_SKILLS_DIR : targets[config.agent].skillsDir, cwd, config.global);
|
|
2090
2225
|
await ensureAgentInstructions(config.agent, cwd, config.global);
|
|
2091
2226
|
await shutdownWorker();
|
|
2092
|
-
p.outro(`Synced ${packageName} to ${relative(cwd, skillDir)}`);
|
|
2227
|
+
p.outro(config.mode === "update" ? `Updated ${packageName}` : `Synced ${packageName} to ${relative(cwd, skillDir)}`);
|
|
2093
2228
|
}
|
|
2094
2229
|
async function enhanceSkillWithLLM(opts) {
|
|
2095
2230
|
const { packageName, version, skillDir, dirName, model, resolved, relatedSkills, hasIssues, hasDiscussions, hasReleases, hasChangelog, docsType, hasShippedDocs: shippedDocs, pkgFiles, force, debug, sections, customPrompt, packages, features } = opts;
|
|
@@ -2111,11 +2246,7 @@ async function enhanceSkillWithLLM(opts) {
|
|
|
2111
2246
|
sections,
|
|
2112
2247
|
customPrompt,
|
|
2113
2248
|
features,
|
|
2114
|
-
onProgress: (
|
|
2115
|
-
const prefix = section ? `\x1B[90m[${section}]\x1B[0m ` : "";
|
|
2116
|
-
if (type === "reasoning" && chunk.startsWith("[")) llmLog.message(`${prefix}${chunk}`);
|
|
2117
|
-
else if (type === "text") llmLog.message(`${prefix}Writing...`);
|
|
2118
|
-
}
|
|
2249
|
+
onProgress: createToolProgress(llmLog)
|
|
2119
2250
|
});
|
|
2120
2251
|
if (wasOptimized) {
|
|
2121
2252
|
const costParts = [];
|
|
@@ -2172,6 +2303,7 @@ const addCommandDef = defineCommand({
|
|
|
2172
2303
|
agent = await promptForAgent();
|
|
2173
2304
|
if (!agent) return;
|
|
2174
2305
|
}
|
|
2306
|
+
if (!hasCompletedWizard()) await runWizard();
|
|
2175
2307
|
const rawInputs = [...new Set([args.package, ...args._ || []].map((s) => s.trim()).filter(Boolean))];
|
|
2176
2308
|
const gitSources = [];
|
|
2177
2309
|
const npmTokens = [];
|
|
@@ -2213,31 +2345,57 @@ const updateCommandDef = defineCommand({
|
|
|
2213
2345
|
description: "Package(s) to update (space or comma-separated). Without args, syncs all outdated.",
|
|
2214
2346
|
required: false
|
|
2215
2347
|
},
|
|
2348
|
+
background: {
|
|
2349
|
+
type: "boolean",
|
|
2350
|
+
alias: "b",
|
|
2351
|
+
description: "Run in background (detached process, non-interactive)",
|
|
2352
|
+
default: false
|
|
2353
|
+
},
|
|
2216
2354
|
...sharedArgs
|
|
2217
2355
|
},
|
|
2218
2356
|
async run({ args }) {
|
|
2219
2357
|
const cwd = process.cwd();
|
|
2358
|
+
if (args.background) {
|
|
2359
|
+
const { spawn } = await import("node:child_process");
|
|
2360
|
+
const updateArgs = [
|
|
2361
|
+
"update",
|
|
2362
|
+
...args.package ? [args.package] : [],
|
|
2363
|
+
...args.agent ? ["--agent", args.agent] : [],
|
|
2364
|
+
...args.model ? ["--model", args.model] : []
|
|
2365
|
+
];
|
|
2366
|
+
spawn(process.execPath, [process.argv[1], ...updateArgs], {
|
|
2367
|
+
cwd,
|
|
2368
|
+
detached: true,
|
|
2369
|
+
stdio: "ignore"
|
|
2370
|
+
}).unref();
|
|
2371
|
+
return;
|
|
2372
|
+
}
|
|
2373
|
+
const silent = !isInteractive();
|
|
2220
2374
|
let agent = resolveAgent(args.agent);
|
|
2221
2375
|
if (!agent) {
|
|
2376
|
+
if (silent) return;
|
|
2222
2377
|
agent = await promptForAgent();
|
|
2223
2378
|
if (!agent) return;
|
|
2224
2379
|
}
|
|
2225
|
-
const state = await getProjectState(cwd);
|
|
2226
|
-
const generators = getInstalledGenerators();
|
|
2227
2380
|
const config = readConfig();
|
|
2228
|
-
|
|
2229
|
-
|
|
2230
|
-
generators
|
|
2231
|
-
|
|
2232
|
-
|
|
2381
|
+
const state = await getProjectState(cwd);
|
|
2382
|
+
if (!silent) {
|
|
2383
|
+
const generators = getInstalledGenerators();
|
|
2384
|
+
p.intro(introLine({
|
|
2385
|
+
state,
|
|
2386
|
+
generators,
|
|
2387
|
+
modelId: config.model
|
|
2388
|
+
}));
|
|
2389
|
+
}
|
|
2233
2390
|
if (args.package) return syncCommand(state, {
|
|
2234
2391
|
packages: [...new Set([args.package, ...args._ || []].flatMap((s) => s.split(/[,\s]+/)).map((s) => s.trim()).filter(Boolean))],
|
|
2235
2392
|
global: args.global,
|
|
2236
2393
|
agent,
|
|
2237
|
-
model: args.model,
|
|
2238
|
-
yes: args.yes,
|
|
2394
|
+
model: args.model || (silent ? config.model : void 0),
|
|
2395
|
+
yes: args.yes || silent,
|
|
2239
2396
|
force: args.force,
|
|
2240
|
-
debug: args.debug
|
|
2397
|
+
debug: args.debug,
|
|
2398
|
+
mode: "update"
|
|
2241
2399
|
});
|
|
2242
2400
|
if (state.outdated.length === 0) {
|
|
2243
2401
|
p.log.success("All skills up to date");
|
|
@@ -2247,10 +2405,11 @@ const updateCommandDef = defineCommand({
|
|
|
2247
2405
|
packages: state.outdated.map((s) => s.packageName || s.name),
|
|
2248
2406
|
global: args.global,
|
|
2249
2407
|
agent,
|
|
2250
|
-
model: args.model,
|
|
2251
|
-
yes: args.yes,
|
|
2408
|
+
model: args.model || (silent ? config.model : void 0),
|
|
2409
|
+
yes: args.yes || silent,
|
|
2252
2410
|
force: args.force,
|
|
2253
|
-
debug: args.debug
|
|
2411
|
+
debug: args.debug,
|
|
2412
|
+
mode: "update"
|
|
2254
2413
|
});
|
|
2255
2414
|
}
|
|
2256
2415
|
});
|
|
@@ -2634,11 +2793,7 @@ async function enhanceRegenerated(pkgName, version, skillDir, model, sections, c
|
|
|
2634
2793
|
sections,
|
|
2635
2794
|
customPrompt,
|
|
2636
2795
|
features,
|
|
2637
|
-
onProgress: (
|
|
2638
|
-
const prefix = section ? `\x1B[90m[${section}]\x1B[0m ` : "";
|
|
2639
|
-
if (type === "reasoning" && chunk.startsWith("[")) llmLog.message(`${prefix}${chunk}`);
|
|
2640
|
-
else if (type === "text") llmLog.message(`${prefix}Writing...`);
|
|
2641
|
-
}
|
|
2796
|
+
onProgress: createToolProgress(llmLog)
|
|
2642
2797
|
});
|
|
2643
2798
|
if (wasOptimized) {
|
|
2644
2799
|
llmLog.success("Generated best practices");
|
|
@@ -3282,13 +3437,11 @@ async function countEmbeddings(packageName, version) {
|
|
|
3282
3437
|
if (!existsSync(dbPath)) return null;
|
|
3283
3438
|
try {
|
|
3284
3439
|
const { DatabaseSync } = await import("node:sqlite");
|
|
3285
|
-
|
|
3440
|
+
using db = new DatabaseSync(dbPath, {
|
|
3286
3441
|
open: true,
|
|
3287
3442
|
readOnly: true
|
|
3288
3443
|
});
|
|
3289
|
-
|
|
3290
|
-
db.close();
|
|
3291
|
-
return row?.cnt ?? null;
|
|
3444
|
+
return db.prepare("SELECT count(*) as cnt FROM vector_metadata").get()?.cnt ?? null;
|
|
3292
3445
|
} catch {
|
|
3293
3446
|
return null;
|
|
3294
3447
|
}
|
|
@@ -3363,14 +3516,12 @@ async function statusCommand(opts = {}) {
|
|
|
3363
3516
|
const globalPkgs = /* @__PURE__ */ new Map();
|
|
3364
3517
|
for (const skill of allSkills) {
|
|
3365
3518
|
const key = skill.info?.packageName || skill.name;
|
|
3366
|
-
|
|
3367
|
-
if (!map.has(key)) map.set(key, {
|
|
3519
|
+
mapInsert(skill.scope === "local" ? localPkgs : globalPkgs, key, () => ({
|
|
3368
3520
|
name: skill.name,
|
|
3369
3521
|
info: skill.info || {},
|
|
3370
|
-
agents: new Set(
|
|
3522
|
+
agents: /* @__PURE__ */ new Set(),
|
|
3371
3523
|
scope: skill.scope
|
|
3372
|
-
});
|
|
3373
|
-
else map.get(key).agents.add(skill.agent);
|
|
3524
|
+
})).agents.add(skill.agent);
|
|
3374
3525
|
}
|
|
3375
3526
|
const buildPackageLines = async (pkgs) => {
|
|
3376
3527
|
const lines = [];
|
|
@@ -3551,8 +3702,8 @@ async function uninstallCommand(opts) {
|
|
|
3551
3702
|
if (untrackedByDir.size > 0) {
|
|
3552
3703
|
const groupedUntracked = /* @__PURE__ */ new Map();
|
|
3553
3704
|
for (const [_dir, { label, skills }] of untrackedByDir) {
|
|
3554
|
-
|
|
3555
|
-
for (const s of skills)
|
|
3705
|
+
const set = mapInsert(groupedUntracked, label, () => /* @__PURE__ */ new Set());
|
|
3706
|
+
for (const s of skills) set.add(s);
|
|
3556
3707
|
}
|
|
3557
3708
|
const totalUntracked = [...groupedUntracked.values()].reduce((sum, s) => sum + s.size, 0);
|
|
3558
3709
|
p.log.warn(`${totalUntracked} untracked skill(s) will remain (not managed by skilld):`);
|
|
@@ -3565,8 +3716,7 @@ async function uninstallCommand(opts) {
|
|
|
3565
3716
|
const groups = /* @__PURE__ */ new Map();
|
|
3566
3717
|
for (const item of toRemove) {
|
|
3567
3718
|
const [prefix, name] = item.label.includes(": ") ? item.label.split(": ", 2) : ["other", item.label];
|
|
3568
|
-
|
|
3569
|
-
groups.get(prefix).push({
|
|
3719
|
+
mapInsert(groups, prefix, () => []).push({
|
|
3570
3720
|
name,
|
|
3571
3721
|
version: item.version
|
|
3572
3722
|
});
|
|
@@ -3609,98 +3759,6 @@ const uninstallCommandDef = defineCommand({
|
|
|
3609
3759
|
});
|
|
3610
3760
|
}
|
|
3611
3761
|
});
|
|
3612
|
-
function hasGhCli() {
|
|
3613
|
-
if (process.env.SKILLD_NO_GH) return false;
|
|
3614
|
-
try {
|
|
3615
|
-
execSync("gh --version", { stdio: "ignore" });
|
|
3616
|
-
return true;
|
|
3617
|
-
} catch {
|
|
3618
|
-
return false;
|
|
3619
|
-
}
|
|
3620
|
-
}
|
|
3621
|
-
async function runWizard() {
|
|
3622
|
-
if (!isInteractive()) return;
|
|
3623
|
-
p.note("Skilld gives your AI agent skill knowledge on your NPM\ndependencies gathered from versioned docs, source code\nand GitHub issues.", "Welcome to skilld");
|
|
3624
|
-
const ghInstalled = hasGhCli();
|
|
3625
|
-
if (ghInstalled) p.log.success("GitHub CLI detected — will use it to pull issues and discussions.");
|
|
3626
|
-
else p.log.warn("GitHub CLI not found. Install it to enable issues/discussions:\n \x1B[36mhttps://cli.github.com\x1B[0m");
|
|
3627
|
-
const selected = await p.multiselect({
|
|
3628
|
-
message: "Which features would you like to enable?",
|
|
3629
|
-
options: [
|
|
3630
|
-
{
|
|
3631
|
-
label: "Semantic + token search",
|
|
3632
|
-
value: "search",
|
|
3633
|
-
hint: "local query engine to cut token costs and speed up grep"
|
|
3634
|
-
},
|
|
3635
|
-
{
|
|
3636
|
-
label: "Release notes",
|
|
3637
|
-
value: "releases",
|
|
3638
|
-
hint: "track changelogs for installed packages"
|
|
3639
|
-
},
|
|
3640
|
-
{
|
|
3641
|
-
label: "GitHub issues",
|
|
3642
|
-
value: "issues",
|
|
3643
|
-
hint: "surface common problems and solutions",
|
|
3644
|
-
disabled: !ghInstalled
|
|
3645
|
-
},
|
|
3646
|
-
{
|
|
3647
|
-
label: "GitHub discussions",
|
|
3648
|
-
value: "discussions",
|
|
3649
|
-
hint: "include Q&A and community knowledge",
|
|
3650
|
-
disabled: !ghInstalled
|
|
3651
|
-
}
|
|
3652
|
-
],
|
|
3653
|
-
initialValues: [...Object.entries(defaultFeatures).filter(([, v]) => v).map(([k]) => k), ...ghInstalled ? ["issues", "discussions"] : []],
|
|
3654
|
-
required: false
|
|
3655
|
-
});
|
|
3656
|
-
if (p.isCancel(selected)) {
|
|
3657
|
-
p.cancel("Setup cancelled");
|
|
3658
|
-
process.exit(0);
|
|
3659
|
-
}
|
|
3660
|
-
const features = {
|
|
3661
|
-
search: selected.includes("search"),
|
|
3662
|
-
issues: selected.includes("issues"),
|
|
3663
|
-
discussions: selected.includes("discussions"),
|
|
3664
|
-
releases: selected.includes("releases")
|
|
3665
|
-
};
|
|
3666
|
-
const allModels = process.env.SKILLD_NO_AGENTS ? [] : await getAvailableModels();
|
|
3667
|
-
let modelId;
|
|
3668
|
-
if (allModels.length > 0) {
|
|
3669
|
-
p.note("Skills work without an LLM, but one can rewrite your\nSKILL.md files with best practices and better structure.\n\x1B[90mThis is separate from the agent where skills are installed —\nthe target agent is auto-detected from your project files.\x1B[0m", "Optional: LLM optimization");
|
|
3670
|
-
const modelChoice = await p.select({
|
|
3671
|
-
message: "Model for generating SKILL.md",
|
|
3672
|
-
options: [{
|
|
3673
|
-
label: "Skip",
|
|
3674
|
-
value: "",
|
|
3675
|
-
hint: "use raw docs, no LLM needed"
|
|
3676
|
-
}, ...allModels.map((m) => ({
|
|
3677
|
-
label: m.recommended ? `${m.name} (Recommended)` : m.name,
|
|
3678
|
-
value: m.id,
|
|
3679
|
-
hint: `${m.agentName} · ${m.hint}`
|
|
3680
|
-
}))]
|
|
3681
|
-
});
|
|
3682
|
-
if (p.isCancel(modelChoice)) {
|
|
3683
|
-
p.cancel("Setup cancelled");
|
|
3684
|
-
process.exit(0);
|
|
3685
|
-
}
|
|
3686
|
-
modelId = modelChoice || void 0;
|
|
3687
|
-
} else {
|
|
3688
|
-
p.log.warn("No supported LLM CLIs detected (claude, gemini, codex).\n Skills will still work, but won't be LLM-optimized.");
|
|
3689
|
-
const proceed = await p.confirm({
|
|
3690
|
-
message: "Continue without LLM optimization?",
|
|
3691
|
-
initialValue: true
|
|
3692
|
-
});
|
|
3693
|
-
if (p.isCancel(proceed) || !proceed) {
|
|
3694
|
-
p.cancel("Setup cancelled");
|
|
3695
|
-
process.exit(0);
|
|
3696
|
-
}
|
|
3697
|
-
}
|
|
3698
|
-
updateConfig({
|
|
3699
|
-
features,
|
|
3700
|
-
...modelId ? { model: modelId } : { skipLlm: true }
|
|
3701
|
-
});
|
|
3702
|
-
p.outro("Thanks, you're all set! Change config anytime with `skilld config`.");
|
|
3703
|
-
}
|
|
3704
3762
|
const _emit = process.emit;
|
|
3705
3763
|
process.emit = (event, ...args) => event === "warning" && args[0]?.name === "ExperimentalWarning" && args[0]?.message?.includes("SQLite") ? false : _emit.apply(process, [event, ...args]);
|
|
3706
3764
|
const NOISE_CHARS = "⣿⡿⣷⣾⣽⣻⢿⡷⣯⣟⡾⣵⣳⢾⡽⣞⡷⣝⢯";
|
|
@@ -3790,21 +3848,6 @@ async function brandLoader(work, minMs = 1500) {
|
|
|
3790
3848
|
logUpdate.done();
|
|
3791
3849
|
return result;
|
|
3792
3850
|
}
|
|
3793
|
-
async function prepareSync(cwd, agentFlag) {
|
|
3794
|
-
const agent = resolveAgent(agentFlag);
|
|
3795
|
-
if (!agent) return;
|
|
3796
|
-
const state = await getProjectState(cwd);
|
|
3797
|
-
if (state.outdated.length === 0) {
|
|
3798
|
-
p.log.success("Skills up to date");
|
|
3799
|
-
return;
|
|
3800
|
-
}
|
|
3801
|
-
await syncCommand(state, {
|
|
3802
|
-
packages: state.outdated.map((s) => s.packageName || s.name),
|
|
3803
|
-
global: false,
|
|
3804
|
-
agent,
|
|
3805
|
-
yes: true
|
|
3806
|
-
});
|
|
3807
|
-
}
|
|
3808
3851
|
const SUBCOMMAND_NAMES = [
|
|
3809
3852
|
"add",
|
|
3810
3853
|
"update",
|
|
@@ -3823,20 +3866,7 @@ runMain(defineCommand({
|
|
|
3823
3866
|
version,
|
|
3824
3867
|
description: "Sync package documentation for agentic use"
|
|
3825
3868
|
},
|
|
3826
|
-
args: {
|
|
3827
|
-
prepare: {
|
|
3828
|
-
type: "boolean",
|
|
3829
|
-
description: "Non-interactive sync for pnpm prepare hook (outdated only, no LLM, always exits 0)",
|
|
3830
|
-
default: false
|
|
3831
|
-
},
|
|
3832
|
-
background: {
|
|
3833
|
-
type: "boolean",
|
|
3834
|
-
alias: "b",
|
|
3835
|
-
description: "Run --prepare in background (detached process)",
|
|
3836
|
-
default: false
|
|
3837
|
-
},
|
|
3838
|
-
agent: sharedArgs.agent
|
|
3839
|
-
},
|
|
3869
|
+
args: { agent: sharedArgs.agent },
|
|
3840
3870
|
subCommands: {
|
|
3841
3871
|
add: () => Promise.resolve().then(() => sync_exports).then((m) => m.addCommandDef),
|
|
3842
3872
|
update: () => Promise.resolve().then(() => sync_exports).then((m) => m.updateCommandDef),
|
|
@@ -3853,22 +3883,6 @@ runMain(defineCommand({
|
|
|
3853
3883
|
const firstArg = process.argv[2];
|
|
3854
3884
|
if (firstArg && !firstArg.startsWith("-") && SUBCOMMAND_NAMES.includes(firstArg)) return;
|
|
3855
3885
|
const cwd = process.cwd();
|
|
3856
|
-
if (args.prepare) {
|
|
3857
|
-
if (args.background) {
|
|
3858
|
-
spawn(process.execPath, [
|
|
3859
|
-
process.argv[1],
|
|
3860
|
-
"--prepare",
|
|
3861
|
-
...args.agent ? ["--agent", args.agent] : []
|
|
3862
|
-
], {
|
|
3863
|
-
cwd,
|
|
3864
|
-
detached: true,
|
|
3865
|
-
stdio: "ignore"
|
|
3866
|
-
}).unref();
|
|
3867
|
-
return;
|
|
3868
|
-
}
|
|
3869
|
-
await prepareSync(cwd, args.agent).catch(() => {});
|
|
3870
|
-
return;
|
|
3871
|
-
}
|
|
3872
3886
|
if (!isInteractive()) {
|
|
3873
3887
|
const state = await getProjectState(cwd);
|
|
3874
3888
|
const status = formatStatus(state.synced.length, state.outdated.length);
|