skilld 1.7.4 → 2.0.0
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/add.mjs +66 -0
- package/dist/_chunks/add.mjs.map +1 -0
- package/dist/_chunks/agent-prompt.mjs +88 -0
- package/dist/_chunks/agent-prompt.mjs.map +1 -0
- package/dist/_chunks/agent.mjs +81 -57
- package/dist/_chunks/agent.mjs.map +1 -1
- package/dist/_chunks/args.mjs +42 -0
- package/dist/_chunks/args.mjs.map +1 -0
- package/dist/_chunks/assemble.mjs +10 -7
- package/dist/_chunks/assemble.mjs.map +1 -1
- package/dist/_chunks/author.mjs +33 -17
- package/dist/_chunks/author.mjs.map +1 -1
- package/dist/_chunks/cache.mjs +143 -183
- package/dist/_chunks/cache.mjs.map +1 -1
- package/dist/_chunks/cache2.mjs +7 -6
- package/dist/_chunks/cache2.mjs.map +1 -1
- package/dist/_chunks/client.mjs +117 -0
- package/dist/_chunks/client.mjs.map +1 -0
- package/dist/_chunks/core.mjs +5 -5
- package/dist/_chunks/detect.mjs +53 -43
- package/dist/_chunks/detect.mjs.map +1 -1
- package/dist/_chunks/eject.mjs +69 -0
- package/dist/_chunks/eject.mjs.map +1 -0
- package/dist/_chunks/embedding-cache2.mjs +1 -1
- package/dist/_chunks/env.mjs +19 -0
- package/dist/_chunks/env.mjs.map +1 -0
- package/dist/_chunks/install-many.mjs +376 -0
- package/dist/_chunks/install-many.mjs.map +1 -0
- package/dist/_chunks/install.mjs +81 -326
- package/dist/_chunks/install.mjs.map +1 -1
- package/dist/_chunks/intro.mjs +63 -0
- package/dist/_chunks/intro.mjs.map +1 -0
- package/dist/_chunks/list.mjs +2 -2
- package/dist/_chunks/list.mjs.map +1 -1
- package/dist/_chunks/lockfile.mjs +3 -2
- package/dist/_chunks/lockfile.mjs.map +1 -1
- package/dist/_chunks/login.mjs +233 -0
- package/dist/_chunks/login.mjs.map +1 -0
- package/dist/_chunks/logout.mjs +27 -0
- package/dist/_chunks/logout.mjs.map +1 -0
- package/dist/_chunks/map.mjs +11 -0
- package/dist/_chunks/map.mjs.map +1 -0
- package/dist/_chunks/markdown.mjs +79 -54
- package/dist/_chunks/markdown.mjs.map +1 -1
- package/dist/_chunks/menu.mjs +33 -0
- package/dist/_chunks/menu.mjs.map +1 -0
- package/dist/_chunks/model-picker.mjs +61 -0
- package/dist/_chunks/model-picker.mjs.map +1 -0
- package/dist/_chunks/monorepo.mjs +4 -2
- package/dist/_chunks/monorepo.mjs.map +1 -1
- package/dist/_chunks/package-json.mjs.map +1 -1
- package/dist/_chunks/paths.mjs +3 -5
- package/dist/_chunks/paths.mjs.map +1 -1
- package/dist/_chunks/{sync-pipeline.mjs → pipeline.mjs} +346 -313
- package/dist/_chunks/pipeline.mjs.map +1 -0
- package/dist/_chunks/pool2.mjs +1 -1
- package/dist/_chunks/portable.mjs +151 -0
- package/dist/_chunks/portable.mjs.map +1 -0
- package/dist/_chunks/prepare-hook.mjs +2 -0
- package/dist/_chunks/prepare-hook2.mjs +61 -0
- package/dist/_chunks/prepare-hook2.mjs.map +1 -0
- package/dist/_chunks/prepare.mjs +47 -3
- package/dist/_chunks/prepare.mjs.map +1 -1
- package/dist/_chunks/prepare2.mjs +7 -6
- package/dist/_chunks/prepare2.mjs.map +1 -1
- package/dist/_chunks/prompts.mjs +484 -74
- package/dist/_chunks/prompts.mjs.map +1 -1
- package/dist/_chunks/pull.mjs +219 -0
- package/dist/_chunks/pull.mjs.map +1 -0
- package/dist/_chunks/regex.mjs +19 -0
- package/dist/_chunks/regex.mjs.map +1 -0
- package/dist/_chunks/retriv.mjs +2 -171
- package/dist/_chunks/retriv2.mjs +159 -0
- package/dist/_chunks/retriv2.mjs.map +1 -0
- package/dist/_chunks/sanitize.mjs +12 -9
- package/dist/_chunks/sanitize.mjs.map +1 -1
- package/dist/_chunks/search-helpers.mjs +8 -6
- package/dist/_chunks/search-helpers.mjs.map +1 -1
- package/dist/_chunks/search-interactive.mjs +23 -20
- package/dist/_chunks/search-interactive.mjs.map +1 -1
- package/dist/_chunks/search.mjs +3 -3
- package/dist/_chunks/search.mjs.map +1 -1
- package/dist/_chunks/semver.mjs +2755 -1
- package/dist/_chunks/semver.mjs.map +1 -1
- package/dist/_chunks/skill-installer2.mjs +10 -11
- package/dist/_chunks/skill-installer2.mjs.map +1 -1
- package/dist/_chunks/skills.mjs +6 -7
- package/dist/_chunks/skills.mjs.map +1 -1
- package/dist/_chunks/store.mjs +107 -0
- package/dist/_chunks/store.mjs.map +1 -0
- package/dist/_chunks/sync.mjs +411 -910
- package/dist/_chunks/sync.mjs.map +1 -1
- package/dist/_chunks/sync2.mjs +2 -5
- package/dist/_chunks/telemetry.mjs +26 -0
- package/dist/_chunks/telemetry.mjs.map +1 -0
- package/dist/_chunks/uninstall.mjs +12 -9
- package/dist/_chunks/uninstall.mjs.map +1 -1
- package/dist/_chunks/update.mjs +171 -0
- package/dist/_chunks/update.mjs.map +1 -0
- package/dist/_chunks/upload.mjs +3 -3
- package/dist/_chunks/validate.mjs +1 -1
- package/dist/_chunks/version.mjs +16 -17
- package/dist/_chunks/version.mjs.map +1 -1
- package/dist/_chunks/whoami.mjs +21 -0
- package/dist/_chunks/whoami.mjs.map +1 -0
- package/dist/_chunks/wizard.mjs +2 -190
- package/dist/_chunks/wizard2.mjs +200 -0
- package/dist/_chunks/wizard2.mjs.map +1 -0
- package/dist/cli.mjs +72 -53
- package/dist/cli.mjs.map +1 -1
- package/dist/prepare.mjs +4 -3
- package/dist/prepare.mjs.map +1 -1
- package/dist/retriv/worker.d.mts +5 -1
- package/dist/retriv/worker.d.mts.map +1 -1
- package/dist/retriv/worker.mjs +1 -1
- package/package.json +19 -28
- package/dist/_chunks/author-group.mjs +0 -17
- package/dist/_chunks/author-group.mjs.map +0 -1
- package/dist/_chunks/cli-helpers.mjs +0 -335
- package/dist/_chunks/cli-helpers.mjs.map +0 -1
- package/dist/_chunks/cli-helpers2.mjs +0 -2
- package/dist/_chunks/index.d.mts +0 -344
- package/dist/_chunks/index.d.mts.map +0 -1
- package/dist/_chunks/index2.d.mts +0 -279
- package/dist/_chunks/index2.d.mts.map +0 -1
- package/dist/_chunks/index3.d.mts +0 -44
- package/dist/_chunks/index3.d.mts.map +0 -1
- package/dist/_chunks/index4.d.mts +0 -553
- package/dist/_chunks/index4.d.mts.map +0 -1
- package/dist/_chunks/package-registry.mjs +0 -465
- package/dist/_chunks/package-registry.mjs.map +0 -1
- package/dist/_chunks/retriv.mjs.map +0 -1
- package/dist/_chunks/setup.mjs +0 -17
- package/dist/_chunks/setup.mjs.map +0 -1
- package/dist/_chunks/sources.mjs +0 -2654
- package/dist/_chunks/sources.mjs.map +0 -1
- package/dist/_chunks/sync-pipeline.mjs.map +0 -1
- package/dist/_chunks/sync-registry.mjs +0 -65
- package/dist/_chunks/sync-registry.mjs.map +0 -1
- package/dist/_chunks/types.d.mts +0 -76
- package/dist/_chunks/types.d.mts.map +0 -1
- package/dist/_chunks/types2.d.mts +0 -88
- package/dist/_chunks/types2.d.mts.map +0 -1
- package/dist/_chunks/wizard.mjs.map +0 -1
- package/dist/agent/index.d.mts +0 -2
- package/dist/agent/index.mjs +0 -4
- package/dist/cache/index.d.mts +0 -2
- package/dist/cache/index.mjs +0 -5
- package/dist/index.d.mts +0 -6
- package/dist/index.mjs +0 -6
- package/dist/retriv/index.d.mts +0 -3
- package/dist/retriv/index.mjs +0 -2
- package/dist/sources/index.d.mts +0 -3
- package/dist/sources/index.mjs +0 -3
- package/dist/types.d.mts +0 -4
- package/dist/types.mjs +0 -1
|
@@ -0,0 +1,66 @@
|
|
|
1
|
+
import { n as COMMA_OR_WHITESPACE_RE } from "./regex.mjs";
|
|
2
|
+
import { l as hasCompletedWizard } from "./cache.mjs";
|
|
3
|
+
import { t as autoResolveAgent } from "./agent-prompt.mjs";
|
|
4
|
+
import { t as sharedArgs } from "./args.mjs";
|
|
5
|
+
import { s as parseSkillInput } from "./semver.mjs";
|
|
6
|
+
import { t as runWizard } from "./wizard2.mjs";
|
|
7
|
+
import { t as installSkills } from "./install-many.mjs";
|
|
8
|
+
import { t as exportPortablePrompts } from "./portable.mjs";
|
|
9
|
+
import * as p from "@clack/prompts";
|
|
10
|
+
import { defineCommand } from "citty";
|
|
11
|
+
const addCommandDef = defineCommand({
|
|
12
|
+
meta: {
|
|
13
|
+
name: "add",
|
|
14
|
+
description: "Install skills (npm:<pkg>, crate:<name>, gh:<owner/repo>, @<curator>)"
|
|
15
|
+
},
|
|
16
|
+
args: {
|
|
17
|
+
"package": {
|
|
18
|
+
type: "positional",
|
|
19
|
+
description: "Package(s) to sync (space/comma-separated; npm:<pkg>, crate:<name>, or owner/repo)",
|
|
20
|
+
required: true
|
|
21
|
+
},
|
|
22
|
+
"skill": {
|
|
23
|
+
type: "string",
|
|
24
|
+
alias: "s",
|
|
25
|
+
description: "Select specific skills from a git repo (comma-separated)",
|
|
26
|
+
valueHint: "name"
|
|
27
|
+
},
|
|
28
|
+
"allow-unsafe": {
|
|
29
|
+
type: "boolean",
|
|
30
|
+
description: "Install skills that fail the upstream audit gate"
|
|
31
|
+
},
|
|
32
|
+
...sharedArgs
|
|
33
|
+
},
|
|
34
|
+
async run({ args }) {
|
|
35
|
+
const rawInputs = [...new Set([args.package, ...args._ || []].map((s) => s.trim()).filter(Boolean))];
|
|
36
|
+
if (args.agent === "none") {
|
|
37
|
+
const packages = [...new Set(rawInputs.flatMap((s) => s.split(COMMA_OR_WHITESPACE_RE)).map((s) => s.trim()).filter(Boolean))];
|
|
38
|
+
for (const pkg of packages) await exportPortablePrompts(pkg, {
|
|
39
|
+
force: args.force,
|
|
40
|
+
agent: "none"
|
|
41
|
+
});
|
|
42
|
+
return;
|
|
43
|
+
}
|
|
44
|
+
const agent = autoResolveAgent(args.agent);
|
|
45
|
+
if (!agent) {
|
|
46
|
+
p.log.error("No target agent detected.\n Pass --agent <name> (claude-code, cursor, codex, …) or run `skilld config` to set a default.\n Use --agent none for portable export.");
|
|
47
|
+
process.exitCode = 1;
|
|
48
|
+
return;
|
|
49
|
+
}
|
|
50
|
+
if (!hasCompletedWizard()) await runWizard({ agent });
|
|
51
|
+
await installSkills(rawInputs.map(parseSkillInput), {
|
|
52
|
+
agent,
|
|
53
|
+
surface: "cli:add",
|
|
54
|
+
global: args.global,
|
|
55
|
+
yes: args.yes,
|
|
56
|
+
force: args.force,
|
|
57
|
+
debug: args.debug,
|
|
58
|
+
model: args.model,
|
|
59
|
+
skillFilter: args.skill,
|
|
60
|
+
allowUnsafe: args["allow-unsafe"]
|
|
61
|
+
});
|
|
62
|
+
}
|
|
63
|
+
});
|
|
64
|
+
export { addCommandDef };
|
|
65
|
+
|
|
66
|
+
//# sourceMappingURL=add.mjs.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"add.mjs","names":[],"sources":["../../src/commands/sync/add.ts"],"sourcesContent":["import type { AgentType, OptimizeModel } from '../../agent/index.ts'\nimport * as p from '@clack/prompts'\nimport { defineCommand } from 'citty'\nimport { autoResolveAgent } from '../../cli/agent-prompt.ts'\nimport { sharedArgs } from '../../cli/args.ts'\nimport { hasCompletedWizard } from '../../core/config.ts'\nimport { parseSkillInput } from '../../core/prefix.ts'\nimport { COMMA_OR_WHITESPACE_RE } from '../../core/regex.ts'\nimport { runWizard } from '../wizard.ts'\nimport { installSkills } from './install-many.ts'\nimport { exportPortablePrompts } from './portable.ts'\n\nexport const addCommandDef = defineCommand({\n meta: { name: 'add', description: 'Install skills (npm:<pkg>, crate:<name>, gh:<owner/repo>, @<curator>)' },\n args: {\n 'package': {\n type: 'positional',\n description: 'Package(s) to sync (space/comma-separated; npm:<pkg>, crate:<name>, or owner/repo)',\n required: true,\n },\n 'skill': {\n type: 'string',\n alias: 's',\n description: 'Select specific skills from a git repo (comma-separated)',\n valueHint: 'name',\n },\n 'allow-unsafe': {\n type: 'boolean',\n description: 'Install skills that fail the upstream audit gate',\n },\n ...sharedArgs,\n },\n async run({ args }) {\n const rawInputs = [...new Set(\n [args.package, ...((args as any)._ || [])]\n .map((s: string) => s.trim())\n .filter(Boolean),\n )]\n\n // --agent none → portable export (no installed-agent target needed).\n if (args.agent === 'none') {\n const packages = [...new Set(rawInputs.flatMap(s => s.split(COMMA_OR_WHITESPACE_RE)).map(s => s.trim()).filter(Boolean))]\n for (const pkg of packages)\n await exportPortablePrompts(pkg, { force: args.force, agent: 'none' })\n return\n }\n\n const agent: AgentType | null = autoResolveAgent(args.agent)\n if (!agent) {\n p.log.error('No target agent detected.\\n Pass --agent <name> (claude-code, cursor, codex, …) or run `skilld config` to set a default.\\n Use --agent none for portable export.')\n process.exitCode = 1\n return\n }\n\n if (!hasCompletedWizard())\n await runWizard({ agent })\n\n const items = rawInputs.map(parseSkillInput)\n await installSkills(items, {\n agent,\n surface: 'cli:add',\n global: args.global,\n yes: args.yes,\n force: args.force,\n debug: args.debug,\n model: args.model as OptimizeModel | undefined,\n skillFilter: args.skill,\n allowUnsafe: args['allow-unsafe'],\n })\n },\n})\n"],"mappings":";;;;;;;;;;AAYA,MAAa,gBAAgB,cAAc;CACzC,MAAM;EAAE,MAAM;EAAO,aAAa;EAAyE;CAC3G,MAAM;EACJ,WAAW;GACT,MAAM;GACN,aAAa;GACb,UAAU;GACX;EACD,SAAS;GACP,MAAM;GACN,OAAO;GACP,aAAa;GACb,WAAW;GACZ;EACD,gBAAgB;GACd,MAAM;GACN,aAAa;GACd;EACD,GAAG;EACJ;CACD,MAAM,IAAI,EAAE,QAAQ;EAClB,MAAM,YAAY,CAAC,GAAG,IAAI,IACxB,CAAC,KAAK,SAAS,GAAK,KAAa,KAAK,EAAE,CAAE,CACvC,KAAK,MAAc,EAAE,MAAM,CAAC,CAC5B,OAAO,QAAQ,CACnB,CAAC;EAGF,IAAI,KAAK,UAAU,QAAQ;GACzB,MAAM,WAAW,CAAC,GAAG,IAAI,IAAI,UAAU,SAAQ,MAAK,EAAE,MAAM,uBAAuB,CAAC,CAAC,KAAI,MAAK,EAAE,MAAM,CAAC,CAAC,OAAO,QAAQ,CAAC,CAAC;GACzH,KAAK,MAAM,OAAO,UAChB,MAAM,sBAAsB,KAAK;IAAE,OAAO,KAAK;IAAO,OAAO;IAAQ,CAAC;GACxE;;EAGF,MAAM,QAA0B,iBAAiB,KAAK,MAAM;EAC5D,IAAI,CAAC,OAAO;GACV,EAAE,IAAI,MAAM,qKAAqK;GACjL,QAAQ,WAAW;GACnB;;EAGF,IAAI,CAAC,oBAAoB,EACvB,MAAM,UAAU,EAAE,OAAO,CAAC;EAG5B,MAAM,cADQ,UAAU,IAAI,gBACH,EAAE;GACzB;GACA,SAAS;GACT,QAAQ,KAAK;GACb,KAAK,KAAK;GACV,OAAO,KAAK;GACZ,OAAO,KAAK;GACZ,OAAO,KAAK;GACZ,aAAa,KAAK;GAClB,aAAa,KAAK;GACnB,CAAC;;CAEL,CAAC"}
|
|
@@ -0,0 +1,88 @@
|
|
|
1
|
+
import { a as targets, n as detectProjectAgents, r as detectTargetAgent, t as detectInstalledAgents } from "./detect.mjs";
|
|
2
|
+
import "./agent.mjs";
|
|
3
|
+
import { d as readConfig, m as updateConfig } from "./cache.mjs";
|
|
4
|
+
import { t as isInteractive } from "./env.mjs";
|
|
5
|
+
import { styleText } from "node:util";
|
|
6
|
+
import * as p from "@clack/prompts";
|
|
7
|
+
function resolveAgent(agentFlag) {
|
|
8
|
+
if (process.env.SKILLD_NO_AGENT) return null;
|
|
9
|
+
return agentFlag ?? detectTargetAgent() ?? readConfig().agent ?? null;
|
|
10
|
+
}
|
|
11
|
+
function autoResolveAgent(agentFlag) {
|
|
12
|
+
const resolved = resolveAgent(agentFlag);
|
|
13
|
+
if (resolved && resolved !== "none") return resolved;
|
|
14
|
+
if (process.env.SKILLD_NO_AGENT) return null;
|
|
15
|
+
const projectMatches = detectProjectAgents();
|
|
16
|
+
if (projectMatches.length === 1) return projectMatches[0];
|
|
17
|
+
const installed = detectInstalledAgents();
|
|
18
|
+
if (installed.length === 1) return installed[0];
|
|
19
|
+
return null;
|
|
20
|
+
}
|
|
21
|
+
let _warnedNoAgent = false;
|
|
22
|
+
function warnNoAgent() {
|
|
23
|
+
if (_warnedNoAgent) return;
|
|
24
|
+
_warnedNoAgent = true;
|
|
25
|
+
p.log.warn("No target agent detected — falling back to prompt-only mode.\n Use --agent <name> to specify, or run `skilld config` to set a default.");
|
|
26
|
+
}
|
|
27
|
+
async function promptForAgent() {
|
|
28
|
+
const noAgent = !!process.env.SKILLD_NO_AGENT;
|
|
29
|
+
const installed = noAgent ? [] : detectInstalledAgents();
|
|
30
|
+
const projectMatches = noAgent ? [] : detectProjectAgents();
|
|
31
|
+
if (!isInteractive()) {
|
|
32
|
+
if (installed.length === 1) {
|
|
33
|
+
updateConfig({ agent: installed[0] });
|
|
34
|
+
return installed[0];
|
|
35
|
+
}
|
|
36
|
+
warnNoAgent();
|
|
37
|
+
return "none";
|
|
38
|
+
}
|
|
39
|
+
p.log.info("Skilld generates reference cards from package docs so your AI agent\n always has accurate APIs for your exact dependency versions.");
|
|
40
|
+
const candidateIds = projectMatches.length > 0 ? projectMatches : installed.length > 0 ? installed : Object.keys(targets);
|
|
41
|
+
const sharedAgents = new Set(Object.entries(targets).filter(([, a]) => a.additionalSkillsDirs.some((d) => d.includes(".claude/skills"))).map(([id]) => id));
|
|
42
|
+
const sharedIds = candidateIds.filter((id) => id === "claude-code" || sharedAgents.has(id));
|
|
43
|
+
const isolatedIds = candidateIds.filter((id) => id !== "claude-code" && !sharedAgents.has(id));
|
|
44
|
+
const options = [];
|
|
45
|
+
if (sharedIds.length > 0 && isolatedIds.length > 0) for (const id of sharedIds) {
|
|
46
|
+
const a = targets[id];
|
|
47
|
+
const hint = id === "claude-code" ? `skills shared with ${sharedIds.length - 1} other agents` : `skills shared with Claude Code and others`;
|
|
48
|
+
options.push({
|
|
49
|
+
label: a.displayName,
|
|
50
|
+
value: id,
|
|
51
|
+
hint
|
|
52
|
+
});
|
|
53
|
+
}
|
|
54
|
+
const isolatedAgentIds = new Set(Object.entries(targets).filter(([, a]) => a.additionalSkillsDirs.length === 0).map(([id]) => id));
|
|
55
|
+
for (const id of sharedIds.length > 0 && isolatedIds.length > 0 ? isolatedIds : candidateIds) {
|
|
56
|
+
if (options.some((o) => o.value === id)) continue;
|
|
57
|
+
const a = targets[id];
|
|
58
|
+
const hint = sharedAgents.has(id) && id !== "claude-code" ? "skills shared with Claude Code and others" : isolatedAgentIds.has(id) ? "skills only visible to this agent" : void 0;
|
|
59
|
+
options.push({
|
|
60
|
+
label: a.displayName,
|
|
61
|
+
value: id,
|
|
62
|
+
hint
|
|
63
|
+
});
|
|
64
|
+
}
|
|
65
|
+
options.push({
|
|
66
|
+
label: "No agent",
|
|
67
|
+
value: "none",
|
|
68
|
+
hint: "export as standalone files for any AI"
|
|
69
|
+
});
|
|
70
|
+
if (!_warnedNoAgent) {
|
|
71
|
+
_warnedNoAgent = true;
|
|
72
|
+
const hint = projectMatches.length > 1 ? `Multiple agent directories found: ${projectMatches.map((t) => targets[t].displayName).join(", ")}` : installed.length > 0 ? `Found ${installed.map((t) => targets[t].displayName).join(", ")} but couldn't determine which to use` : "No agents auto-detected";
|
|
73
|
+
const crossNote = sharedIds.length > 1 ? `\n ${styleText("gray", `Tip: Picking Claude Code shares skills with ${sharedIds.filter((id) => id !== "claude-code").map((id) => targets[id].displayName).join(", ")} automatically.`)}` : "";
|
|
74
|
+
p.log.warn(`${hint}\n Pick the agent you actively code with.${crossNote}`);
|
|
75
|
+
}
|
|
76
|
+
const choice = await p.select({
|
|
77
|
+
message: "Which AI coding agent do you use?",
|
|
78
|
+
options
|
|
79
|
+
});
|
|
80
|
+
if (p.isCancel(choice)) return null;
|
|
81
|
+
if (choice === "none") return "none";
|
|
82
|
+
updateConfig({ agent: choice });
|
|
83
|
+
p.log.success(`Target agent set to ${targets[choice].displayName}`);
|
|
84
|
+
return choice;
|
|
85
|
+
}
|
|
86
|
+
export { promptForAgent as n, resolveAgent as r, autoResolveAgent as t };
|
|
87
|
+
|
|
88
|
+
//# sourceMappingURL=agent-prompt.mjs.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"agent-prompt.mjs","names":["agents"],"sources":["../../src/cli/agent-prompt.ts"],"sourcesContent":["import type { AgentType } from '../agent/index.ts'\nimport { styleText } from 'node:util'\nimport * as p from '@clack/prompts'\nimport { agents, detectInstalledAgents, detectProjectAgents, detectTargetAgent } from '../agent/index.ts'\nimport { readConfig, updateConfig } from '../core/config.ts'\nimport { isInteractive } from './env.ts'\n\nexport function resolveAgent(agentFlag?: string): AgentType | 'none' | null {\n if (process.env.SKILLD_NO_AGENT)\n return null\n return (agentFlag as AgentType | undefined)\n ?? detectTargetAgent()\n ?? (readConfig().agent as AgentType | undefined)\n ?? null\n}\n\n/**\n * Auto-resolve target agent without prompting. Consults, in order:\n * 1. Explicit `--agent` flag.\n * 2. Env-detected target (`CLAUDE_CODE`, `CURSOR_SESSION`, etc).\n * 3. Saved config default.\n * 4. Project marker dirs (`.claude/skills`, `.cursor/`, …) when exactly one\n * agent matches the cwd.\n * 5. Installed agents on the machine when exactly one is found.\n *\n * Returns `null` when nothing is determined. Callers should error with a clear\n * \"pass --agent <name>\" hint rather than prompting — keeps commands\n * scriptable.\n */\nexport function autoResolveAgent(agentFlag?: string): AgentType | null {\n const resolved = resolveAgent(agentFlag)\n if (resolved && resolved !== 'none')\n return resolved\n\n if (process.env.SKILLD_NO_AGENT)\n return null\n\n const projectMatches = detectProjectAgents()\n if (projectMatches.length === 1)\n return projectMatches[0]!\n\n const installed = detectInstalledAgents()\n if (installed.length === 1)\n return installed[0]!\n\n return null\n}\n\nexport function listKnownAgents(): AgentType[] {\n return Object.keys(agents) as AgentType[]\n}\n\nlet _warnedNoAgent = false\nfunction warnNoAgent(): void {\n if (_warnedNoAgent)\n return\n _warnedNoAgent = true\n p.log.warn('No target agent detected — falling back to prompt-only mode.\\n Use --agent <name> to specify, or run `skilld config` to set a default.')\n}\n\nexport async function promptForAgent(): Promise<AgentType | 'none' | null> {\n const noAgent = !!process.env.SKILLD_NO_AGENT\n const installed = noAgent ? [] : detectInstalledAgents()\n const projectMatches = noAgent ? [] : detectProjectAgents()\n\n if (!isInteractive()) {\n if (installed.length === 1) {\n updateConfig({ agent: installed[0] })\n return installed[0]!\n }\n warnNoAgent()\n return 'none'\n }\n\n p.log.info(\n `Skilld generates reference cards from package docs so your AI agent\\n`\n + ` always has accurate APIs for your exact dependency versions.`,\n )\n\n const candidateIds = projectMatches.length > 0\n ? projectMatches\n : installed.length > 0\n ? installed\n : Object.keys(agents) as AgentType[]\n\n const sharedAgents = new Set(\n Object.entries(agents)\n .filter(([, a]) => a.additionalSkillsDirs.some(d => d.includes('.claude/skills')))\n .map(([id]) => id),\n )\n\n const sharedIds = candidateIds.filter(id => id === 'claude-code' || sharedAgents.has(id))\n const isolatedIds = candidateIds.filter(id => id !== 'claude-code' && !sharedAgents.has(id))\n\n const options: Array<{ label: string, value: AgentType | 'none', hint?: string }> = []\n\n if (sharedIds.length > 0 && isolatedIds.length > 0) {\n for (const id of sharedIds) {\n const a = agents[id]\n const hint = id === 'claude-code'\n ? `skills shared with ${sharedIds.length - 1} other agents`\n : `skills shared with Claude Code and others`\n options.push({ label: a.displayName, value: id as AgentType, hint })\n }\n }\n\n const isolatedAgentIds = new Set(\n Object.entries(agents)\n .filter(([, a]) => a.additionalSkillsDirs.length === 0)\n .map(([id]) => id),\n )\n\n for (const id of (sharedIds.length > 0 && isolatedIds.length > 0 ? isolatedIds : candidateIds)) {\n if (options.some(o => o.value === id))\n continue\n const a = agents[id]\n const hint = sharedAgents.has(id) && id !== 'claude-code'\n ? 'skills shared with Claude Code and others'\n : isolatedAgentIds.has(id)\n ? 'skills only visible to this agent'\n : undefined\n options.push({ label: a.displayName, value: id as AgentType, hint })\n }\n\n options.push({ label: 'No agent', value: 'none', hint: 'export as standalone files for any AI' })\n\n if (!_warnedNoAgent) {\n _warnedNoAgent = true\n const hint = projectMatches.length > 1\n ? `Multiple agent directories found: ${projectMatches.map(t => agents[t].displayName).join(', ')}`\n : installed.length > 0\n ? `Found ${installed.map(t => agents[t].displayName).join(', ')} but couldn't determine which to use`\n : 'No agents auto-detected'\n const crossNote = sharedIds.length > 1\n ? `\\n ${styleText('gray', `Tip: Picking Claude Code shares skills with ${sharedIds.filter(id => id !== 'claude-code').map(id => agents[id].displayName).join(', ')} automatically.`)}`\n : ''\n p.log.warn(`${hint}\\n Pick the agent you actively code with.${crossNote}`)\n }\n\n const choice = await p.select({\n message: 'Which AI coding agent do you use?',\n options,\n })\n\n if (p.isCancel(choice))\n return null\n\n if (choice === 'none')\n return 'none'\n\n updateConfig({ agent: choice })\n p.log.success(`Target agent set to ${agents[choice].displayName}`)\n return choice\n}\n"],"mappings":";;;;;;AAOA,SAAgB,aAAa,WAA+C;CAC1E,IAAI,QAAQ,IAAI,iBACd,OAAO;CACT,OAAQ,aACH,mBAAmB,IAClB,YAAY,CAAC,SACd;;;;;;;;;;;;;;CAgBP,IAAA,gBAAgB;CACd,iBAAiB;CACjB,EAAA,IAAI,KAAA,0IACK;;eAKH,iBAAiB;CACvB,MAAI,UAAA,CAAA,CAAA,QAAe,IAAW;CAG9B,MAAM,YAAY,UAAA,EAAA,GAAA,uBAAuB;CACzC,MAAI,iBAAU,UACZ,EAAO,GAAA,qBAAU;CAEnB,IAAA,CAAA,eAAO,EAAA;;GAOT,aAAI,EAAA,OAAiB,UAAA,IAAA,CAAA;GACrB,OAAS,UAAA;;EAGP,aAAA;EACA,OAAM;;CAGR,EAAA,IAAA,KAAA,sIAA2E;CACzE,MAAM,eAAY,eAAY,SAAA,IAAA,iBAAA,UAAA,SAAA,IAAA,YAAA,OAAA,KAAA,QAAA;CAC9B,MAAM,eAAY,IAAA,IAAU,OAAK,QAAA,QAAA,CAAA,QAAuB,GAAA,OAAA,EAAA,qBAAA,MAAA,MAAA,EAAA,SAAA,iBAAA,CAAA,CAAA,CAAA,KAAA,CAAA,QAAA,GAAA,CAAA;CACxD,MAAM,YAAA,aAAiB,QAAe,OAAA,OAAA,iBAAqB,aAAA,IAAA,GAAA,CAAA;CAE3D,MAAK,cAAe,aAAE,QAAA,OAAA,OAAA,iBAAA,CAAA,aAAA,IAAA,GAAA,CAAA;OAChB,UAAU,EAAA;KACZ,UAAA,SAAe,KAAO,YAAe,SAAA,GAAA,KAAA,MAAA,MAAA,WAAA;QACrC,IAAO,QAAU;;EAEnB,QAAA,KAAa;GACb,OAAO,EAAA;;GAGP;GAKF,CAAA;;CAYA,MAAM,mBAAY,IAAA,IAAa,OAAO,QAAM,QAAO,CAAA,QAAA,GAAA,OAAiB,EAAA,qBAAqB,WAAA,EAAA,CAAA,KAAA,CAAA,QAAA,GAAA,CAAA;CACzF,KAAA,MAAM,MAAA,UAAc,SAAa,KAAO,YAAM,SAAO,IAAA,cAAkB,cAAqB;EAE5F,IAAA,QAAM,MAAgF,MAAA,EAAA,UAAA,GAAA,EAAA;EAEtF,MAAI,IAAA,QAAU;EAEV,MAAM,OAAIA,aAAO,IAAA,GAAA,IAAA,OAAA,gBAAA,8CAAA,iBAAA,IAAA,GAAA,GAAA,sCAAA,KAAA;EACjB,QAAM,KAAO;GAGb,OAAQ,EAAA;GAAO,OAAO;GAAe;GAAwB,CAAA;;;EAIjE,OAAM;EAMN,OAAK;EACH,MAAI;EAEJ,CAAA;KACA,CAAA,gBAAa;EAKb,iBAAa;QAAE,OAAS,eAAA,SAAA,IAAA,qCAAA,eAAA,KAAA,MAAA,QAAA,GAAA,YAAA,CAAA,KAAA,KAAA,KAAA,UAAA,SAAA,IAAA,SAAA,UAAA,KAAA,MAAA,QAAA,GAAA,YAAA,CAAA,KAAA,KAAA,CAAA,wCAAA;QAAa,YAAO,UAAA,SAAA,IAAA,OAAA,UAAA,QAAA,+CAAA,UAAA,QAAA,OAAA,OAAA,cAAA,CAAA,KAAA,OAAA,QAAA,IAAA,YAAA,CAAA,KAAA,KAAA,CAAA,iBAAA,KAAA;IAAiB,IAAA,KAAA,GAAA,KAAA,4CAAA,YAAA;;;EAG/D,SAAQ;EAAO;EAAmB,CAAA;KAAe,EAAA,SAAM,OAAA,EAAA,OAAA;KAA0C,WAAA,QAAA,OAAA;CAEjG,aAAK,EAAA,OAAgB,QAAA,CAAA;GACnB,IAAA,QAAA,uBAAiB,QAAA,QAAA,cAAA;QACX"}
|
package/dist/_chunks/agent.mjs
CHANGED
|
@@ -1,28 +1,30 @@
|
|
|
1
|
-
import { a as PI_AI_AUTH_PATH, h as skillLogDir, p as skillInternalDir, r as LLM_CACHE_DIR, t as CACHE_DIR } from "./paths.mjs";
|
|
2
|
-
import { E as getSkillReferenceDirs, t as createReferenceCache } from "./cache.mjs";
|
|
3
|
-
import { n as sanitizeMarkdown } from "./sanitize.mjs";
|
|
4
1
|
import { a as targets, t as detectInstalledAgents } from "./detect.mjs";
|
|
5
|
-
import {
|
|
2
|
+
import { A as resolveSkilldCommand, C as SECTION_OUTPUT_FILES, S as SECTION_MERGE_ORDER, _ as buildAllSectionPrompts, x as wrapSection, y as getSectionValidator } from "./prompts.mjs";
|
|
3
|
+
import { g as skillLogDir, i as LLM_CACHE_DIR, m as skillInternalDir, n as CACHE_DIR, o as PI_AI_AUTH_PATH } from "./paths.mjs";
|
|
4
|
+
import { d as SECTION_HEADING_RE, m as TRAILING_SLASH_RE, p as SOURCE_LINK_RE, t as API_CHANGE_BULLET_RE } from "./regex.mjs";
|
|
5
|
+
import { n as sanitizeMarkdown } from "./sanitize.mjs";
|
|
6
|
+
import { n as getSkillReferenceDirs, t as createReferenceCache } from "./cache.mjs";
|
|
6
7
|
import { existsSync, lstatSync, mkdirSync, readFileSync, readdirSync, unlinkSync, writeFileSync } from "node:fs";
|
|
7
|
-
import {
|
|
8
|
+
import { promisify, styleText } from "node:util";
|
|
8
9
|
import { join } from "pathe";
|
|
9
10
|
import { exec, execFileSync, spawn } from "node:child_process";
|
|
10
|
-
import { glob } from "tinyglobby";
|
|
11
|
-
import { findDynamicImports, findStaticImports } from "mlly";
|
|
12
|
-
import { promisify } from "node:util";
|
|
13
11
|
import { isWindows } from "std-env";
|
|
14
|
-
import {
|
|
15
|
-
import {
|
|
12
|
+
import { homedir } from "node:os";
|
|
13
|
+
import { getEnvApiKey, getEnvApiKey as getEnvApiKey$1, getModel, getModels, getProviders, streamSimple } from "@earendil-works/pi-ai";
|
|
14
|
+
import { getOAuthApiKey, getOAuthProvider, getOAuthProviders } from "@earendil-works/pi-ai/oauth";
|
|
16
15
|
import { resolve as resolve$1 } from "node:path";
|
|
17
16
|
import { Type } from "typebox";
|
|
18
|
-
import { readFile } from "node:fs/promises";
|
|
17
|
+
import { glob, readFile } from "node:fs/promises";
|
|
19
18
|
import { parseSync } from "oxc-parser";
|
|
20
19
|
import { setTimeout as setTimeout$1 } from "node:timers/promises";
|
|
21
20
|
import { createHash } from "node:crypto";
|
|
21
|
+
const STATIC_REGEX_1$6 = /-\d{8}$/;
|
|
22
|
+
const STATIC_REGEX_2$5 = /-\d{4}-\d{2}-\d{2}$/;
|
|
23
|
+
const STATIC_REGEX_3$3 = /-preview/;
|
|
22
24
|
function isStableId(id) {
|
|
23
|
-
if (
|
|
24
|
-
if (
|
|
25
|
-
if (
|
|
25
|
+
if (STATIC_REGEX_1$6.test(id)) return false;
|
|
26
|
+
if (STATIC_REGEX_2$5.test(id)) return false;
|
|
27
|
+
if (STATIC_REGEX_3$3.test(id)) return false;
|
|
26
28
|
return true;
|
|
27
29
|
}
|
|
28
30
|
function compareVersions(a, b) {
|
|
@@ -120,7 +122,9 @@ function extractToolHint(input) {
|
|
|
120
122
|
if (typeof v === "string" && v) return v;
|
|
121
123
|
}
|
|
122
124
|
}
|
|
123
|
-
const
|
|
125
|
+
const STATIC_REGEX_1$5 = /^Claude\s+/;
|
|
126
|
+
const STATIC_REGEX_2$4 = /\s*\(latest\)\s*$/i;
|
|
127
|
+
const stripClaude = (n) => n.replace(STATIC_REGEX_1$5, "").replace(STATIC_REGEX_2$4, "");
|
|
124
128
|
function buildArgs$2(model, skillDir, symlinkDirs) {
|
|
125
129
|
return [
|
|
126
130
|
"-p",
|
|
@@ -218,6 +222,7 @@ const adapter$2 = {
|
|
|
218
222
|
buildArgs: buildArgs$2,
|
|
219
223
|
parseEvent: parseEvent$2
|
|
220
224
|
};
|
|
225
|
+
const STATIC_REGEX_1$4 = /^cat\s*>|>/;
|
|
221
226
|
function buildArgs$1(model, _skillDir, _symlinkDirs) {
|
|
222
227
|
return [
|
|
223
228
|
"exec",
|
|
@@ -240,7 +245,7 @@ function parseEvent$1(line) {
|
|
|
240
245
|
};
|
|
241
246
|
if (item.type === "command_execution" && item.aggregated_output) {
|
|
242
247
|
const cmd = item.command || "";
|
|
243
|
-
const writeContent =
|
|
248
|
+
const writeContent = STATIC_REGEX_1$4.test(cmd) ? item.aggregated_output : void 0;
|
|
244
249
|
return {
|
|
245
250
|
kind: "tool-call",
|
|
246
251
|
tool: "Bash",
|
|
@@ -546,6 +551,10 @@ function getAvailablePiAiModels() {
|
|
|
546
551
|
}
|
|
547
552
|
return available;
|
|
548
553
|
}
|
|
554
|
+
const STATIC_REGEX_1$3 = /^\.\/\.skilld\//;
|
|
555
|
+
const STATIC_REGEX_2$3 = /^\.skilld\//;
|
|
556
|
+
const STATIC_REGEX_3$2 = /^\.\//;
|
|
557
|
+
const STATIC_REGEX_5$2 = /\s+/;
|
|
549
558
|
const TOOLS = [
|
|
550
559
|
{
|
|
551
560
|
name: "Read",
|
|
@@ -582,7 +591,7 @@ const SAFE_COMMANDS = new Set([
|
|
|
582
591
|
]);
|
|
583
592
|
const SHELL_META_RE = /[;&|`$()<>]/;
|
|
584
593
|
function resolveSandboxedPath(p, skilldDir) {
|
|
585
|
-
const resolved = resolve$1(skilldDir, String(p).replace(
|
|
594
|
+
const resolved = resolve$1(skilldDir, String(p).replace(STATIC_REGEX_1$3, "./").replace(STATIC_REGEX_2$3, "./").replace(STATIC_REGEX_3$2, ""));
|
|
586
595
|
if (!resolved.startsWith(`${skilldDir}/`) && resolved !== skilldDir) throw new Error(`Path traversal blocked: ${p}`);
|
|
587
596
|
return resolved;
|
|
588
597
|
}
|
|
@@ -638,7 +647,7 @@ function executeTool(toolCall, skilldDir) {
|
|
|
638
647
|
return sanitizeMarkdown(readFileSync(filePath, "utf-8"));
|
|
639
648
|
}
|
|
640
649
|
case "Glob": {
|
|
641
|
-
const pattern = String(args.pattern).replace(
|
|
650
|
+
const pattern = String(args.pattern).replace(STATIC_REGEX_1$3, "./").replace(STATIC_REGEX_2$3, "./").replace(STATIC_REGEX_3$2, "");
|
|
642
651
|
const results = [];
|
|
643
652
|
const walkDir = (dir, prefix) => {
|
|
644
653
|
if (!existsSync(dir)) return;
|
|
@@ -648,9 +657,9 @@ function executeTool(toolCall, skilldDir) {
|
|
|
648
657
|
else results.push(`./.skilld/${relPath}`);
|
|
649
658
|
}
|
|
650
659
|
};
|
|
651
|
-
const baseDir = pattern.split("*")[0]?.replace(
|
|
660
|
+
const baseDir = pattern.split("*")[0]?.replace(TRAILING_SLASH_RE, "") ?? "";
|
|
652
661
|
walkDir(join(skilldDir, baseDir), baseDir);
|
|
653
|
-
const matched = results.filter((r) => globMatch(r.replace(
|
|
662
|
+
const matched = results.filter((r) => globMatch(r.replace(STATIC_REGEX_1$3, ""), pattern));
|
|
654
663
|
return matched.length > 0 ? matched.join("\n") : `No files matching: ${args.pattern}`;
|
|
655
664
|
}
|
|
656
665
|
case "Write":
|
|
@@ -658,7 +667,7 @@ function executeTool(toolCall, skilldDir) {
|
|
|
658
667
|
return "File written successfully.";
|
|
659
668
|
case "Bash": {
|
|
660
669
|
const cmd = String(args.command).trim();
|
|
661
|
-
const parts = cmd.split(
|
|
670
|
+
const parts = cmd.split(STATIC_REGEX_5$2);
|
|
662
671
|
const bin = parts[0] ?? "";
|
|
663
672
|
if (!SAFE_COMMANDS.has(bin) || SHELL_META_RE.test(cmd)) return `Error: command not allowed. Only skilld, ls, cat, find commands are permitted.`;
|
|
664
673
|
try {
|
|
@@ -789,24 +798,31 @@ async function optimizeSectionPiAi(opts) {
|
|
|
789
798
|
cost: totalCost
|
|
790
799
|
};
|
|
791
800
|
}
|
|
801
|
+
const STATIC_REGEX_1$2 = /^```(?:markdown|md)?[^\S\n]*\n([\s\S]+)\n```[^\S\n]*$/;
|
|
802
|
+
const STATIC_REGEX_2$2 = /^```(?:markdown|md)/;
|
|
803
|
+
const STATIC_REGEX_5$1 = /^-{3,}\n/;
|
|
804
|
+
const STATIC_REGEX_6 = /\n-{3,}/;
|
|
805
|
+
const STATIC_REGEX_7 = /^(##\s|- (?:BREAKING|DEPRECATED|NEW): )/m;
|
|
806
|
+
const STATIC_REGEX_8 = /^(## .+)\n/;
|
|
807
|
+
const STATIC_REGEX_9 = /^\.\/(?:\.skilld\/|references\/)/;
|
|
792
808
|
function cleanSectionOutput(content) {
|
|
793
809
|
let cleaned = content.trim();
|
|
794
|
-
const wrapMatch = cleaned.match(
|
|
810
|
+
const wrapMatch = cleaned.match(STATIC_REGEX_1$2);
|
|
795
811
|
if (wrapMatch) {
|
|
796
812
|
const inner = wrapMatch[1].trim();
|
|
797
|
-
if (
|
|
813
|
+
if (STATIC_REGEX_2$2.test(cleaned) || SECTION_HEADING_RE.test(inner) || API_CHANGE_BULLET_RE.test(inner)) cleaned = inner;
|
|
798
814
|
}
|
|
799
815
|
cleaned = cleaned.replace(/^# (?!#)/gm, "## ");
|
|
800
|
-
const fmMatch = cleaned.match(
|
|
816
|
+
const fmMatch = cleaned.match(STATIC_REGEX_5$1);
|
|
801
817
|
if (fmMatch) {
|
|
802
818
|
const afterOpen = fmMatch[0].length;
|
|
803
|
-
const closeMatch = cleaned.slice(afterOpen).match(
|
|
819
|
+
const closeMatch = cleaned.slice(afterOpen).match(STATIC_REGEX_6);
|
|
804
820
|
if (closeMatch) cleaned = cleaned.slice(afterOpen + closeMatch.index + closeMatch[0].length).trim();
|
|
805
821
|
else cleaned = cleaned.slice(afterOpen).trim();
|
|
806
822
|
}
|
|
807
|
-
const firstMarker = cleaned.match(
|
|
823
|
+
const firstMarker = cleaned.match(STATIC_REGEX_7);
|
|
808
824
|
if (firstMarker?.index && firstMarker.index > 0) cleaned = cleaned.slice(firstMarker.index).trim();
|
|
809
|
-
const headingMatch = cleaned.match(
|
|
825
|
+
const headingMatch = cleaned.match(STATIC_REGEX_8);
|
|
810
826
|
if (headingMatch) {
|
|
811
827
|
const heading = headingMatch[1];
|
|
812
828
|
const afterFirst = headingMatch[0].length;
|
|
@@ -816,14 +832,17 @@ function cleanSectionOutput(content) {
|
|
|
816
832
|
}
|
|
817
833
|
}
|
|
818
834
|
cleaned = cleaned.replace(/\(?\[`?\.\/(?:\.skilld\/|references\/)[^)\]]*\]\(([^)]+)\)\)?/g, (match, url) => {
|
|
819
|
-
if (
|
|
835
|
+
if (STATIC_REGEX_9.test(url)) return `[source](${url})`;
|
|
820
836
|
return match;
|
|
821
837
|
});
|
|
822
838
|
cleaned = cleaned.replace(/\[source\]\(\.\/((docs|issues|discussions|releases|pkg|guide)\/)/g, "[source](./.skilld/$1");
|
|
823
839
|
cleaned = sanitizeMarkdown(cleaned);
|
|
824
|
-
if (
|
|
840
|
+
if (!SECTION_HEADING_RE.test(cleaned) && !API_CHANGE_BULLET_RE.test(cleaned) && !SOURCE_LINK_RE.test(cleaned)) return "";
|
|
825
841
|
return cleaned;
|
|
826
842
|
}
|
|
843
|
+
const STATIC_REGEX_1$1 = /^\[(?:starting|retrying|cached)/;
|
|
844
|
+
const STATIC_REGEX_2$1 = /^\[([^:[\]]+)(?::\s(.+))?\]$/;
|
|
845
|
+
const STATIC_REGEX_3$1 = /skilld search\s+"([^"]+)"/;
|
|
827
846
|
function createToolProgress(log) {
|
|
828
847
|
let lastMsg = "";
|
|
829
848
|
let repeatCount = 0;
|
|
@@ -832,7 +851,7 @@ function createToolProgress(log) {
|
|
|
832
851
|
function emit(msg) {
|
|
833
852
|
if (msg === lastMsg) {
|
|
834
853
|
repeatCount++;
|
|
835
|
-
log.message(`${msg}
|
|
854
|
+
log.message(`${msg} ${styleText("gray", `(+${repeatCount})`)}`);
|
|
836
855
|
} else {
|
|
837
856
|
lastMsg = msg;
|
|
838
857
|
repeatCount = 0;
|
|
@@ -845,17 +864,17 @@ function createToolProgress(log) {
|
|
|
845
864
|
const now = Date.now();
|
|
846
865
|
if (now - (lastTextEmit.get(key) ?? 0) < TEXT_THROTTLE_MS) return;
|
|
847
866
|
lastTextEmit.set(key, now);
|
|
848
|
-
const prefix = section ?
|
|
867
|
+
const prefix = section ? `${styleText("gray", `[${section}]`)} ` : "";
|
|
849
868
|
const items = text ? text.match(/^- (?:BREAKING|DEPRECATED|NEW|CHANGED|REMOVED|Use |Do |Set |Add |Avoid |Always |Never |Prefer |Check |Ensure )/gm)?.length ?? 0 : 0;
|
|
850
|
-
emit(items > 0 ? `${prefix}Writing...
|
|
869
|
+
emit(items > 0 ? `${prefix}Writing... ${styleText("gray", `(${items} items)`)}` : `${prefix}Writing...`);
|
|
851
870
|
return;
|
|
852
871
|
}
|
|
853
872
|
if (type !== "reasoning" || !chunk.startsWith("[")) return;
|
|
854
|
-
if (
|
|
855
|
-
emit(`${section ?
|
|
873
|
+
if (STATIC_REGEX_1$1.test(chunk)) {
|
|
874
|
+
emit(`${section ? `${styleText("gray", `[${section}]`)} ` : ""}${chunk.slice(1, -1)}`);
|
|
856
875
|
return;
|
|
857
876
|
}
|
|
858
|
-
const match = chunk.match(
|
|
877
|
+
const match = chunk.match(STATIC_REGEX_2$1);
|
|
859
878
|
if (!match) return;
|
|
860
879
|
const names = match[1].split(",").map((n) => n.trim());
|
|
861
880
|
const hints = match[2]?.split(",").map((h) => h.trim()) ?? [];
|
|
@@ -863,16 +882,16 @@ function createToolProgress(log) {
|
|
|
863
882
|
const rawName = names[i];
|
|
864
883
|
const hint = hints[i] ?? hints[0] ?? "";
|
|
865
884
|
const verb = TOOL_NAMES[rawName]?.verb ?? rawName;
|
|
866
|
-
const prefix = section ?
|
|
885
|
+
const prefix = section ? `${styleText("gray", `[${section}]`)} ` : "";
|
|
867
886
|
if ((rawName === "Bash" || rawName === "run_shell_command") && hint) {
|
|
868
|
-
const searchMatch = hint.match(
|
|
869
|
-
if (searchMatch) emit(`${prefix}Searching
|
|
887
|
+
const searchMatch = hint.match(STATIC_REGEX_3$1);
|
|
888
|
+
if (searchMatch) emit(`${prefix}Searching ${styleText("cyan", `"${searchMatch[1]}"`)}`);
|
|
870
889
|
else if (hint.includes("skilld validate")) emit(`${prefix}Validating...`);
|
|
871
890
|
else {
|
|
872
891
|
const shortened = shortenCommand(hint);
|
|
873
892
|
emit(`${prefix}Running ${shortened.length > 50 ? `${shortened.slice(0, 47)}...` : shortened}`);
|
|
874
893
|
}
|
|
875
|
-
} else emit(`${prefix}${verb}
|
|
894
|
+
} else emit(`${prefix}${verb} ${styleText("gray", shortenPath(hint || "..."))}`);
|
|
876
895
|
}
|
|
877
896
|
};
|
|
878
897
|
}
|
|
@@ -1031,13 +1050,16 @@ async function detectNuxtModules(cwd) {
|
|
|
1031
1050
|
async function detectPresetPackages(cwd) {
|
|
1032
1051
|
return detectNuxtModules(cwd);
|
|
1033
1052
|
}
|
|
1053
|
+
const FROM_STATIC_IMPORT_RE = /\bfrom\s*['"]([^'"\n]+)['"]/g;
|
|
1054
|
+
const SIDE_EFFECT_IMPORT_RE = /\bimport\s*['"]([^'"\n]+)['"]/g;
|
|
1055
|
+
const DYNAMIC_IMPORT_RE = /\bimport\s*\(\s*['"]([^'"\n]+)['"]\s*\)/g;
|
|
1034
1056
|
const PATTERNS = ["**/*.{ts,js,vue,mjs,cjs,tsx,jsx,mts,cts}"];
|
|
1035
|
-
const
|
|
1036
|
-
"
|
|
1037
|
-
"
|
|
1038
|
-
"
|
|
1039
|
-
"
|
|
1040
|
-
"
|
|
1057
|
+
const IGNORE_DIRS = [
|
|
1058
|
+
"node_modules",
|
|
1059
|
+
"dist",
|
|
1060
|
+
".nuxt",
|
|
1061
|
+
".output",
|
|
1062
|
+
"coverage"
|
|
1041
1063
|
];
|
|
1042
1064
|
function addPackage(counts, specifier) {
|
|
1043
1065
|
if (!specifier || specifier.startsWith(".") || specifier.startsWith("/")) return;
|
|
@@ -1047,19 +1069,16 @@ function addPackage(counts, specifier) {
|
|
|
1047
1069
|
async function detectImportedPackages(cwd = process.cwd()) {
|
|
1048
1070
|
try {
|
|
1049
1071
|
const counts = /* @__PURE__ */ new Map();
|
|
1050
|
-
const files =
|
|
1072
|
+
const files = [];
|
|
1073
|
+
for await (const file of glob(PATTERNS, {
|
|
1051
1074
|
cwd,
|
|
1052
|
-
|
|
1053
|
-
|
|
1054
|
-
expandDirectories: false
|
|
1055
|
-
});
|
|
1075
|
+
exclude: (p) => IGNORE_DIRS.some((dir) => p === dir || p.endsWith(`/${dir}`))
|
|
1076
|
+
})) files.push(join(cwd, file));
|
|
1056
1077
|
await Promise.all(files.map(async (file) => {
|
|
1057
1078
|
const content = await readFile(file, "utf8");
|
|
1058
|
-
for (const
|
|
1059
|
-
for (const
|
|
1060
|
-
|
|
1061
|
-
if (match) addPackage(counts, match[1]);
|
|
1062
|
-
}
|
|
1079
|
+
for (const m of content.matchAll(FROM_STATIC_IMPORT_RE)) addPackage(counts, m[1]);
|
|
1080
|
+
for (const m of content.matchAll(SIDE_EFFECT_IMPORT_RE)) addPackage(counts, m[1]);
|
|
1081
|
+
for (const m of content.matchAll(DYNAMIC_IMPORT_RE)) addPackage(counts, m[1]);
|
|
1063
1082
|
}));
|
|
1064
1083
|
const packages = Array.from(counts.entries(), ([name, count]) => ({
|
|
1065
1084
|
name,
|
|
@@ -1358,6 +1377,11 @@ function piAiExecutor(model) {
|
|
|
1358
1377
|
function selectExecutor(model) {
|
|
1359
1378
|
return isPiAiModel(model) ? piAiExecutor(model) : cliExecutor(model);
|
|
1360
1379
|
}
|
|
1380
|
+
const STATIC_REGEX_1 = /\b429\b/;
|
|
1381
|
+
const STATIC_REGEX_2 = /rate.?limit/i;
|
|
1382
|
+
const STATIC_REGEX_3 = /exhausted.*capacity/i;
|
|
1383
|
+
const STATIC_REGEX_4 = /quota.*reset/i;
|
|
1384
|
+
const STATIC_REGEX_5 = /reset\s+after\s+(\d+)s/i;
|
|
1361
1385
|
async function optimizeSection(opts) {
|
|
1362
1386
|
const { section, prompt, outputFile, skillDir, executor, onProgress, timeout, debug, preExistingFiles } = opts;
|
|
1363
1387
|
const skilldDir = skillInternalDir(skillDir);
|
|
@@ -1604,11 +1628,11 @@ async function optimizeDocs(opts) {
|
|
|
1604
1628
|
}
|
|
1605
1629
|
function isRateLimitError(error) {
|
|
1606
1630
|
if (!error) return false;
|
|
1607
|
-
return
|
|
1631
|
+
return STATIC_REGEX_1.test(error) || STATIC_REGEX_2.test(error) || STATIC_REGEX_3.test(error) || STATIC_REGEX_4.test(error);
|
|
1608
1632
|
}
|
|
1609
1633
|
function parseRateLimitDelay(error) {
|
|
1610
1634
|
if (!error || !isRateLimitError(error)) return void 0;
|
|
1611
|
-
const match = error.match(
|
|
1635
|
+
const match = error.match(STATIC_REGEX_5);
|
|
1612
1636
|
return match ? Number(match[1]) : 10;
|
|
1613
1637
|
}
|
|
1614
1638
|
function getRetryError(result) {
|