@roll-agent/core 0.14.1 → 0.16.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/cli/chat/banner.d.ts +21 -0
- package/dist/cli/chat/banner.js +1 -0
- package/dist/cli/chat/ink/app.d.ts +2 -0
- package/dist/cli/chat/ink/app.js +1 -1
- package/dist/cli/chat/ink/commands.d.ts +28 -0
- package/dist/cli/chat/ink/commands.js +1 -1
- package/dist/cli/chat/ink/history-item.js +1 -1
- package/dist/cli/chat/ink/live-region.js +1 -1
- package/dist/cli/chat/ink/run-ink-repl.d.ts +3 -0
- package/dist/cli/chat/ink/run-ink-repl.js +1 -1
- package/dist/cli/chat/ink/slash-popup.d.ts +2 -2
- package/dist/cli/chat/ink/slash-popup.js +1 -1
- package/dist/cli/chat/ink/state.d.ts +6 -0
- package/dist/cli/chat/ink/state.js +1 -1
- package/dist/cli/chat/ink/text-prompt.d.ts +1 -0
- package/dist/cli/chat/ink/text-prompt.js +1 -1
- package/dist/cli/chat/ink/use-session.d.ts +1 -1
- package/dist/cli/chat/ink/use-session.js +1 -1
- package/dist/cli/commands/agent-add.js +1 -1
- package/dist/cli/commands/agent-env-guidance.d.ts +2 -0
- package/dist/cli/commands/agent-env-guidance.js +1 -0
- package/dist/cli/commands/agent-install.d.ts +5 -0
- package/dist/cli/commands/agent-install.js +1 -1
- package/dist/cli/commands/agent-list.d.ts +5 -0
- package/dist/cli/commands/agent-list.js +1 -1
- package/dist/cli/commands/chat.d.ts +3 -0
- package/dist/cli/commands/chat.js +1 -1
- package/dist/cli/commands/config-guidance.d.ts +27 -0
- package/dist/cli/commands/config-guidance.js +1 -1
- package/dist/cli/commands/config-prompts.d.ts +6 -0
- package/dist/cli/commands/config-prompts.js +1 -1
- package/dist/cli/commands/config-setup.d.ts +6 -1
- package/dist/cli/commands/config-setup.js +1 -1
- package/dist/cli/commands/config.d.ts +1 -0
- package/dist/cli/commands/config.js +1 -1
- package/dist/cli/commands/setup.d.ts +38 -0
- package/dist/cli/commands/setup.js +1 -0
- package/dist/cli/commands/skills-install.d.ts +30 -0
- package/dist/cli/commands/skills-install.js +1 -0
- package/dist/cli/commands/skills-utils.d.ts +4 -7
- package/dist/cli/commands/skills-utils.js +1 -1
- package/dist/cli/commands/skills.js +1 -1
- package/dist/cli/index.js +1 -1
- package/dist/cli/utils/catalog-status.d.ts +20 -0
- package/dist/cli/utils/catalog-status.js +1 -0
- package/dist/cli/utils/chat-renderer.d.ts +1 -0
- package/dist/cli/utils/chat-renderer.js +1 -1
- package/dist/cli/utils/git-source.d.ts +7 -0
- package/dist/cli/utils/git-source.js +1 -0
- package/dist/cli/utils/tool-format.d.ts +1 -0
- package/dist/cli/utils/tool-format.js +1 -1
- package/dist/config/defaults.js +1 -1
- package/dist/config/helpers.d.ts +17 -0
- package/dist/config/helpers.js +1 -1
- package/dist/config/key-codec.js +1 -1
- package/dist/config/loader.d.ts +2 -0
- package/dist/config/loader.js +1 -1
- package/dist/config/migration.d.ts +5 -1
- package/dist/config/migration.js +1 -1
- package/dist/config/runtime-env.d.ts +30 -30
- package/dist/config/schema.d.ts +273 -0
- package/dist/config/schema.js +1 -1
- package/dist/mcp/client-manager.js +1 -1
- package/dist/registry/catalog-discovery.d.ts +30 -0
- package/dist/registry/catalog-discovery.js +1 -0
- package/dist/registry/catalog.d.ts +42 -0
- package/dist/registry/catalog.js +1 -0
- package/dist/registry/discovery.js +1 -1
- package/dist/registry/index.d.ts +4 -0
- package/dist/registry/index.js +1 -1
- package/dist/registry/install.d.ts +69 -0
- package/dist/registry/install.js +1 -0
- package/dist/skills/documents.d.ts +8 -0
- package/dist/skills/documents.js +1 -0
- package/dist/skills/install.d.ts +17 -0
- package/dist/skills/install.js +1 -0
- package/dist/skills/library.d.ts +31 -0
- package/dist/skills/library.js +1 -0
- package/dist/skills/orchestrators.d.ts +39 -0
- package/dist/skills/orchestrators.js +1 -0
- package/package.json +6 -2
package/dist/registry/index.d.ts
CHANGED
|
@@ -1,3 +1,7 @@
|
|
|
1
|
+
export { OFFICIAL_AGENT_CATALOG, catalogPackageSpec, findCatalogEntry, getAgentCatalog, } from "./catalog.ts";
|
|
2
|
+
export type { AgentCatalogEntry, CatalogEntryMatch, OfficialAgentShortName } from "./catalog.ts";
|
|
3
|
+
export { resolveAgentCatalog } from "./catalog-discovery.ts";
|
|
4
|
+
export type { ResolveCatalogOptions } from "./catalog-discovery.ts";
|
|
1
5
|
export { discoverAgent } from "./discovery.ts";
|
|
2
6
|
export type { DiscoveredAgent } from "./discovery.ts";
|
|
3
7
|
export { AgentStore } from "./store.ts";
|
package/dist/registry/index.js
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
export{discoverAgent}from"./discovery.js";export{AgentStore}from"./store.js";export{startAgent,stopAgent,stopAgentGracefully,getAgentPid,getAgentLogPath,probeAgentEndpoint,waitForAgentReady}from"./process-manager.js";export{runAgentSetup}from"./runtime-setup.js";
|
|
1
|
+
export{OFFICIAL_AGENT_CATALOG,catalogPackageSpec,findCatalogEntry,getAgentCatalog}from"./catalog.js";export{resolveAgentCatalog}from"./catalog-discovery.js";export{discoverAgent}from"./discovery.js";export{AgentStore}from"./store.js";export{startAgent,stopAgent,stopAgentGracefully,getAgentPid,getAgentLogPath,probeAgentEndpoint,waitForAgentReady}from"./process-manager.js";export{runAgentSetup}from"./runtime-setup.js";
|
|
@@ -0,0 +1,69 @@
|
|
|
1
|
+
import { runPackageManagerWithRetry } from "../cli/utils/package-manager.ts";
|
|
2
|
+
import { discoverAgent } from "./discovery.ts";
|
|
3
|
+
import { startAgent, stopAgentGracefully, waitForAgentReady } from "./process-manager.ts";
|
|
4
|
+
import { runAgentSetup } from "./runtime-setup.ts";
|
|
5
|
+
import { readInstalledPackageManifest, resolveInstalledPackageRoot } from "./source.ts";
|
|
6
|
+
import { AgentStore } from "./store.ts";
|
|
7
|
+
import type { AgentEnvCheckReport } from "../config/helpers.ts";
|
|
8
|
+
import type { RollConfig } from "../config/schema.ts";
|
|
9
|
+
import type { RegisteredAgent } from "../types/agent.ts";
|
|
10
|
+
export declare const INSTALL_AGENT_STEPS: readonly ["resolve", "download", "discover", "setup", "register", "start"];
|
|
11
|
+
export type InstallAgentStep = (typeof INSTALL_AGENT_STEPS)[number];
|
|
12
|
+
export type InstallAgentEvent = {
|
|
13
|
+
readonly type: "step";
|
|
14
|
+
readonly step: InstallAgentStep;
|
|
15
|
+
readonly message: string;
|
|
16
|
+
} | {
|
|
17
|
+
readonly type: "info";
|
|
18
|
+
readonly message: string;
|
|
19
|
+
} | {
|
|
20
|
+
readonly type: "warn";
|
|
21
|
+
readonly message: string;
|
|
22
|
+
} | {
|
|
23
|
+
readonly type: "success";
|
|
24
|
+
readonly message: string;
|
|
25
|
+
} | {
|
|
26
|
+
readonly type: "retry";
|
|
27
|
+
readonly attempt: number;
|
|
28
|
+
readonly delayMs: number;
|
|
29
|
+
};
|
|
30
|
+
export type InstallAgentReporter = (event: InstallAgentEvent) => void;
|
|
31
|
+
export interface InstallAgentInput {
|
|
32
|
+
readonly packageSpec: string;
|
|
33
|
+
readonly skipBrowserSetup?: boolean;
|
|
34
|
+
readonly autoStart?: boolean;
|
|
35
|
+
readonly replaceExisting?: boolean;
|
|
36
|
+
readonly expectedSkillName?: string;
|
|
37
|
+
}
|
|
38
|
+
export interface InstallAgentCollaborators {
|
|
39
|
+
readonly runInstall?: typeof runPackageManagerWithRetry;
|
|
40
|
+
readonly discover?: typeof discoverAgent;
|
|
41
|
+
readonly runSetup?: typeof runAgentSetup;
|
|
42
|
+
readonly start?: typeof startAgent;
|
|
43
|
+
readonly waitReady?: typeof waitForAgentReady;
|
|
44
|
+
readonly stopGracefully?: typeof stopAgentGracefully;
|
|
45
|
+
readonly resolvePackageRoot?: typeof resolveInstalledPackageRoot;
|
|
46
|
+
readonly readManifest?: typeof readInstalledPackageManifest;
|
|
47
|
+
}
|
|
48
|
+
export interface InstallAgentDeps {
|
|
49
|
+
readonly agentsConfig: RollConfig["agents"];
|
|
50
|
+
readonly installConfig: RollConfig["install"];
|
|
51
|
+
readonly getStartEnv: (agentName: string) => Readonly<Record<string, string>> | undefined;
|
|
52
|
+
readonly store?: AgentStore;
|
|
53
|
+
readonly report?: InstallAgentReporter;
|
|
54
|
+
readonly collaborators?: InstallAgentCollaborators;
|
|
55
|
+
}
|
|
56
|
+
export interface InstallAgentFailure {
|
|
57
|
+
readonly ok: false;
|
|
58
|
+
readonly step: InstallAgentStep;
|
|
59
|
+
readonly message: string;
|
|
60
|
+
readonly retryCommand?: string;
|
|
61
|
+
}
|
|
62
|
+
export interface InstallAgentSuccess {
|
|
63
|
+
readonly ok: true;
|
|
64
|
+
readonly agent: RegisteredAgent;
|
|
65
|
+
readonly envReport: AgentEnvCheckReport | undefined;
|
|
66
|
+
readonly started: boolean;
|
|
67
|
+
}
|
|
68
|
+
export type InstallAgentResult = InstallAgentSuccess | InstallAgentFailure;
|
|
69
|
+
export declare function installAgent(input: InstallAgentInput, deps: InstallAgentDeps): Promise<InstallAgentResult>;
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
import{existsSync as e,mkdirSync as t,rmSync as s,statSync as r}from"node:fs";import{resolve as a}from"node:path";import{buildNpmRetryPolicy as n,formatPackageManagerError as i,npmInstallNetworkArgs as o,runPackageManagerWithRetry as l}from"../cli/utils/package-manager.js";import{inspectAgentEnvRequirements as g}from"../config/helpers.js";import{discoverAgent as m}from"./discovery.js";import{startAgent as p,stopAgentGracefully as c,waitForAgentReady as u}from"./process-manager.js";import{runAgentSetup as d}from"./runtime-setup.js";import{parsePackageName as f,readInstalledPackageManifest as k,resolveInstalledPackageRoot as y,sanitizeInstallId as h}from"./source.js";import{AgentStore as w}from"./store.js";export const INSTALL_AGENT_STEPS=["resolve","download","discover","setup","register","start"];function v(e){return o({...e.registry?{registry:e.registry}:{},fetchRetries:e.fetchRetries,preferOffline:e.preferOffline})}function S(e){return e.startsWith("git@")||e.startsWith("git+")||e.startsWith("github:")||e.startsWith("gitlab:")||e.startsWith("bitbucket:")||e.endsWith(".git")}function $(t){const s=a(t);return e(s)&&r(s).isDirectory()}function C(e){return e instanceof Error?e.message:String(e)}function A(e){return e.source?.type??"unknown"}function D(e,t,s){return{ok:!1,step:"register",message:`Agent "${e}" 已通过 ${t} 来源注册。为避免覆盖本地/Git Agent,默认不会替换为 npm 安装。请先运行 \`roll agent remove ${e}\`,或确认风险后使用 \`roll agent install ${s} --force\`。`,retryCommand:`roll agent install ${s} --force`}}function j(e,t){return void 0!==e&&"installed-package"!==e.source?.type&&!t}export async function installAgent(r,o){const R=o.report??(()=>{}),B=o.collaborators??{},b=B.runInstall??l,M=B.discover??m,N=B.runSetup??d,T=B.start??p,W=B.waitReady??u,x=B.stopGracefully??c,E=B.resolvePackageRoot??y,L=B.readManifest??k,{packageSpec:G}=r,I=r.autoStart??!0,O=r.replaceExisting??!1;if(S(G))return{ok:!1,step:"resolve",message:`Git URL 请使用 \`roll agent add ${G}\` 注册,不要使用 \`roll agent install\``};if($(G))return{ok:!1,step:"resolve",message:`本地源码目录请使用 \`roll agent add ${G}\` 注册,不要使用 \`roll agent install\``};const P=f(G),_=a(o.agentsConfig.dataDir,"installed",h(P)),q=o.store??new w(o.agentsConfig.dataDir),K=r.expectedSkillName,U=K?q.findByName(K):void 0;if(U&&j(U,O))return D(U.skill.name,A(U),G);const V=e(_);V||t(_,{recursive:!0}),o.installConfig.registry&&R({type:"info",message:`使用 npm registry: ${o.installConfig.registry}(roll.config.yaml install.registry)`}),R({type:"step",step:"download",message:`安装 ${G}...`});const z={command:"npm",args:["install","--prefix",_,G,...v(o.installConfig)]};try{await b(z,{timeout:o.installConfig.networkTimeoutMs},{...n(o.installConfig.fetchRetries),onRetry:({attempt:e,delayMs:t})=>{R({type:"retry",attempt:e,delayMs:t})}})}catch(e){return{ok:!1,step:"download",message:`安装失败: ${i(z,e)}`}}const F=E(_,P);if(!e(F))return{ok:!1,step:"discover",message:`安装完成但未找到包目录: ${F}`};const H=L(F);let J;R({type:"step",step:"discover",message:"解析已安装 Agent 的 SKILL.md..."});try{J=M(F)}catch(e){return{ok:!1,step:"discover",message:C(e)}}const Q={skill:J.skill,transport:J.transport,runtime:J.runtime,installPath:F,registeredAt:(new Date).toISOString(),status:"idle",source:{type:"installed-package",packageName:H?.name??P,packageSpec:G,installDir:_,...H?.version?{installedVersion:H.version}:{}},...J.skillBody.length>0?{skillBody:J.skillBody}:{}},X=q.findByName(J.skill.name);if(X&&j(X,O))return V||s(_,{recursive:!0,force:!0}),D(J.skill.name,A(X),G);"core-managed"===Q.runtime.ownership&&Q.runtime.setup?.playwright&&!r.skipBrowserSetup&&R({type:"info",message:`即将安装浏览器运行时 (${Q.runtime.setup.playwright.browsers.join(", ")}),这可能需要一些时间...`});const Y=await N(Q,{skipBrowserSetup:r.skipBrowserSetup??!1});Y.ok&&!Y.skipped?R({type:"success",message:Y.message}):Y.ok&&R({type:"info",message:Y.message});const Z="core-managed"===X?.runtime.ownership&&"online"===X.status;try{if("installed-package"===X?.source?.type||X&&O){if("installed-package"!==X.source?.type){const e=X.source?.type??"unknown";R({type:"info",message:`Agent "${J.skill.name}" 已通过 ${e} 来源注册,将替换为 npm 安装`})}q.replace(X.skill.name,Q)}else q.add(Q)}catch(e){return{ok:!1,step:"register",message:C(e)}}if(!Y.ok)return Z&&await x(o.agentsConfig.dataDir,Q.skill.name).catch(()=>{}),q.updateStatus(J.skill.name,"error"),{ok:!1,step:"setup",message:Y.message,...Y.retryCommand?{retryCommand:Y.retryCommand}:{}};const ee=g(Q.skill.name,J.skill.env,o.agentsConfig.env),te=ee?.missingRequired??[];let se=!1;const re="core-managed"===Q.runtime.ownership&&I,ae=re&&0===te.length;if(Z&&!ae&&(await x(o.agentsConfig.dataDir,Q.skill.name).catch(()=>{}),q.updateStatus(Q.skill.name,"idle")),re)if(te.length>0)R({type:"warn",message:`Agent "${Q.skill.name}" 缺少必填环境变量(${te.map(e=>e.name).join(", ")}),暂不启动。配置后运行 \`roll agent start ${Q.skill.name}\` 启动`});else{let e=!1;try{Z&&await x(o.agentsConfig.dataDir,Q.skill.name),q.updateStatus(Q.skill.name,"starting"),T(Q,o.agentsConfig.dataDir,o.getStartEnv(Q.skill.name)),e=!0,await W(Q,{startupTimeoutMs:15e3,probeTimeoutMs:2e3}),q.updateStatus(Q.skill.name,"online"),se=!0}catch(t){return e&&await x(o.agentsConfig.dataDir,Q.skill.name).catch(()=>{}),q.updateStatus(Q.skill.name,"error"),{ok:!1,step:"start",message:`Agent "${J.skill.name}" 已安装,但自动启动失败:${C(t)}`}}}return{ok:!0,agent:Q,envReport:ee,started:se}}
|
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
export interface SkillReferenceDocument {
|
|
2
|
+
readonly relativePath: string;
|
|
3
|
+
readonly path: string;
|
|
4
|
+
readonly content: string;
|
|
5
|
+
}
|
|
6
|
+
export declare function collectReferencedSkillPaths(content: string): readonly string[];
|
|
7
|
+
export declare function readReferencedSkillDocuments(skillPath: string, content: string): readonly SkillReferenceDocument[];
|
|
8
|
+
export declare function readReferencedSkillDocument(skillPath: string, referencePath: string): SkillReferenceDocument | undefined;
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
import{existsSync as t,readFileSync as e,realpathSync as n,statSync as o}from"node:fs";import{dirname as r,extname as s,isAbsolute as c,normalize as i,relative as l,resolve as f,sep as a}from"node:path";const u=/(?:\.\/)?references\/[A-Za-z0-9._~!$&+,;=:@%/-]+/g,h=new Set([".md",".yaml",".yml",".json",".txt"]);export function collectReferencedSkillPaths(t){const e=new Set;for(const n of t.matchAll(u)){const t=d(n[0]);t&&e.add(t)}return[...e].sort()}export function readReferencedSkillDocuments(t,e){const o=r(t),s=n(o),c=[];for(const t of collectReferencedSkillPaths(e)){const e=p(o,s,t);e&&c.push(e)}return c}export function readReferencedSkillDocument(t,e){const o=d(e.split("/").join(a));if(!o)return;const s=r(t);return p(s,n(s),o)}function d(t){const e=((t.startsWith("./")?t.slice(2):t).split("#",1)[0]??"").split("?",1)[0]??"",n=i(e);if(0!==n.length&&!c(n)&&!n.startsWith("..")&&"references"!==n&&n.startsWith(`references${a}`)&&h.has(s(n).toLowerCase()))return n}function p(r,s,i){const u=f(r,i);if(!t(u))return;const h=n(u),d=l(s,h);return d.startsWith("..")||c(d)||!o(h).isFile()?void 0:{relativePath:i.split(a).join("/"),path:h,content:e(h,"utf-8")}}
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
export interface SkillInstallCandidate {
|
|
2
|
+
readonly name: string;
|
|
3
|
+
readonly description: string;
|
|
4
|
+
readonly sourceDir: string;
|
|
5
|
+
}
|
|
6
|
+
export interface CollectInstallableSkillsResult {
|
|
7
|
+
readonly skills: readonly SkillInstallCandidate[];
|
|
8
|
+
readonly issues: readonly string[];
|
|
9
|
+
}
|
|
10
|
+
export interface InstalledSkillRecord {
|
|
11
|
+
readonly name: string;
|
|
12
|
+
readonly targetPath: string;
|
|
13
|
+
readonly overwritten: boolean;
|
|
14
|
+
}
|
|
15
|
+
export declare function collectInstallableSkills(sourceDir: string): CollectInstallableSkillsResult;
|
|
16
|
+
export declare function installSkillsToDir(skills: readonly SkillInstallCandidate[], targetSkillsDir: string): readonly InstalledSkillRecord[];
|
|
17
|
+
export declare function findExistingSkillInstalls(skills: readonly SkillInstallCandidate[], targetSkillsDir: string): readonly string[];
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
import{cpSync as t,existsSync as r,mkdirSync as s,readFileSync as e,readdirSync as n,rmSync as i,statSync as o}from"node:fs";import{join as u,resolve as c}from"node:path";import l from"gray-matter";import{sanitizeInstallId as a}from"../registry/source.js";const m="SKILL.md";function f(t){try{return o(t).isDirectory()}catch{return!1}}function p(t){return t instanceof Error?t.message:String(t)}function h(t){const r=u(t,m);let s,n;try{s=e(r,"utf-8")}catch(t){return{issue:`无法读取 ${r}: ${p(t)}`}}try{n=l(s).data}catch(t){return{issue:`SKILL.md frontmatter 解析失败 ${r}: ${p(t)}`}}const i=n.name;if("string"!=typeof i||0===i.trim().length)return{issue:`${r} 缺少有效的 frontmatter name,已跳过`};const o=n.description;return"string"!=typeof o||0===o.trim().length?{issue:`${r} 缺少有效的 frontmatter description,已跳过`}:{skill:{name:i.trim(),description:o.trim(),sourceDir:t}}}export function collectInstallableSkills(t){const s=c(t);if(!f(s))return{skills:[],issues:[`目录不存在: ${s}`]};if(r(u(s,m))){const{skill:t,issue:r}=h(s);return{skills:t?[t]:[],issues:r?[r]:[]}}const e=[],i=[];let o;try{o=n(s)}catch(t){return{skills:[],issues:[`无法读取目录 ${s}: ${p(t)}`]}}for(const t of o.sort()){const n=u(s,t);if(!f(n)||!r(u(n,m)))continue;const{skill:o,issue:c}=h(n);o&&e.push(o),c&&i.push(c)}return 0===e.length&&0===i.length&&i.push(`未在 ${s} 找到包含 SKILL.md 的 skill 目录`),{skills:e,issues:i}}export function installSkillsToDir(e,n){return s(n,{recursive:!0}),e.map(s=>{const e=u(n,a(s.name)),o=r(e);return o&&i(e,{recursive:!0,force:!0}),t(s.sourceDir,e,{recursive:!0}),{name:s.name,targetPath:e,overwritten:o}})}export function findExistingSkillInstalls(t,s){return t.filter(t=>r(u(s,a(t.name)))).map(t=>t.name)}
|
|
@@ -0,0 +1,31 @@
|
|
|
1
|
+
import type { RegisteredAgent } from "../types/agent.ts";
|
|
2
|
+
export declare const SKILL_SOURCES: readonly ["agent", "project", "user", "config"];
|
|
3
|
+
export type SkillSource = (typeof SKILL_SOURCES)[number];
|
|
4
|
+
export interface SkillSummary {
|
|
5
|
+
readonly name: string;
|
|
6
|
+
readonly description: string;
|
|
7
|
+
readonly source: SkillSource;
|
|
8
|
+
}
|
|
9
|
+
export interface LoadedSkill {
|
|
10
|
+
readonly summary: SkillSummary;
|
|
11
|
+
readonly content: string;
|
|
12
|
+
readonly referencePaths: readonly string[];
|
|
13
|
+
}
|
|
14
|
+
export interface SkillLibrary {
|
|
15
|
+
list(): readonly SkillSummary[];
|
|
16
|
+
load(name: string): LoadedSkill | undefined;
|
|
17
|
+
loadReference(name: string, referencePath: string): string | undefined;
|
|
18
|
+
}
|
|
19
|
+
export interface CreateSkillLibraryOptions {
|
|
20
|
+
readonly agents?: readonly RegisteredAgent[];
|
|
21
|
+
readonly extraDirs?: readonly string[];
|
|
22
|
+
readonly cwd?: string;
|
|
23
|
+
readonly home?: string;
|
|
24
|
+
readonly onIssue?: (message: string) => void;
|
|
25
|
+
}
|
|
26
|
+
export declare const SKILL_FILE_NAME = "SKILL.md";
|
|
27
|
+
export declare const SKILL_TOOL_ID = "roll__skill";
|
|
28
|
+
export declare function getAgentSkillPath(agent: RegisteredAgent): string;
|
|
29
|
+
export declare function resolveAgentSkillPath(agent: RegisteredAgent): string | undefined;
|
|
30
|
+
export declare function findProjectSkillsDir(cwd: string): string | undefined;
|
|
31
|
+
export declare function createSkillLibrary(options?: CreateSkillLibraryOptions): SkillLibrary;
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
import{existsSync as t,readdirSync as r,readFileSync as n,realpathSync as e,statSync as o}from"node:fs";import{homedir as s}from"node:os";import{basename as i,dirname as a,join as c,resolve as l}from"node:path";import m from"gray-matter";import{collectReferencedSkillPaths as u,readReferencedSkillDocument as f}from"./documents.js";export const SKILL_SOURCES=["agent","project","user","config"];export const SKILL_FILE_NAME="SKILL.md";export const SKILL_TOOL_ID="roll__skill";export function getAgentSkillPath(t){return l(t.installPath,"SKILL.md")}export function resolveAgentSkillPath(r){const n=getAgentSkillPath(r);return t(n)?n:void 0}export function findProjectSkillsDir(r){let n=l(r);for(;;){const r=c(n,".agents","skills");if(t(r))return r;const e=a(n);if(e===n)return;n=e}}function d(t){try{return o(t).isDirectory()}catch{return!1}}function h(t){try{return e(t)}catch{return}}function p(t,r,e,o){let s,i;try{s=n(t,"utf-8")}catch(r){return void o?.(`无法读取 ${t}: ${r instanceof Error?r.message:String(r)}`)}try{i=m(s).data}catch(r){return void o?.(`SKILL.md frontmatter 解析失败 ${t}: ${r instanceof Error?r.message:String(r)}`)}return{summary:{name:"string"==typeof i.name&&i.name.length>0?i.name:r,description:"string"==typeof i.description?i.description.trim():"",source:e},skillPath:t}}function y(n,e,o){if(!d(n))return[];const s=c(n,"SKILL.md");if(t(s)){const t=p(s,i(n),e,o);return t?[t]:[]}const a=[];let l;try{l=r(n)}catch{return[]}for(const r of l.sort()){const s=c(n,r);if(!d(s))continue;const i=c(s,"SKILL.md");if(!t(i))continue;const l=p(i,r,e,o);l&&a.push(l)}return a}function g(t){return t.map(t=>{const r=resolveAgentSkillPath(t),n=t.skillBody?.trim();return{summary:{name:t.skill.name,description:t.skill.description,source:"agent"},...void 0!==r?{skillPath:r}:{},...n&&n.length>0?{fallbackContent:n}:{}}})}export function createSkillLibrary(t={}){const r=t.onIssue,e=t.cwd??process.cwd(),o=t.home??s(),i=[...g(t.agents??[])],a=findProjectSkillsDir(e);void 0!==a&&i.push(...y(a,"project",r)),i.push(...y(c(o,".agents","skills"),"user",r));for(const n of t.extraDirs??[])i.push(...y(n,"config",r));const l=new Map,m=new Set;for(const t of i){const n=void 0!==t.skillPath?h(t.skillPath):void 0;void 0!==n&&m.has(n)||(l.has(t.summary.name)?r?.(`skill "${t.summary.name}" 重名,保留 ${l.get(t.summary.name)?.summary.source} 来源,跳过 ${t.summary.source} 来源`):(l.set(t.summary.name,t),void 0!==n&&m.add(n)))}return{list:()=>[...l.values()].map(t=>t.summary),load:t=>{const e=l.get(t);if(e){if(void 0!==e.skillPath){let t;try{t=n(e.skillPath,"utf-8")}catch(t){return void r?.(`无法读取 ${e.skillPath}: ${t instanceof Error?t.message:String(t)}`)}return{summary:e.summary,content:t,referencePaths:u(t)}}return void 0!==e.fallbackContent?{summary:e.summary,content:e.fallbackContent,referencePaths:[]}:{summary:e.summary,content:e.summary.description,referencePaths:[]}}},loadReference:(t,r)=>{const n=l.get(t);if(n&&void 0!==n.skillPath)return f(n.skillPath,r)?.content}}}
|
|
@@ -0,0 +1,39 @@
|
|
|
1
|
+
export interface OrchestratorSkillTarget {
|
|
2
|
+
readonly id: string;
|
|
3
|
+
readonly label: string;
|
|
4
|
+
readonly userDir: string;
|
|
5
|
+
readonly projectDir: string;
|
|
6
|
+
readonly detectDir: string;
|
|
7
|
+
}
|
|
8
|
+
export declare const ORCHESTRATOR_SKILL_TARGETS: readonly [{
|
|
9
|
+
readonly id: "claude-code";
|
|
10
|
+
readonly label: "Claude Code";
|
|
11
|
+
readonly userDir: "~/.claude/skills";
|
|
12
|
+
readonly projectDir: ".claude/skills";
|
|
13
|
+
readonly detectDir: "~/.claude";
|
|
14
|
+
}, {
|
|
15
|
+
readonly id: "codex";
|
|
16
|
+
readonly label: "Codex";
|
|
17
|
+
readonly userDir: "~/.codex/skills";
|
|
18
|
+
readonly projectDir: ".codex/skills";
|
|
19
|
+
readonly detectDir: "~/.codex";
|
|
20
|
+
}, {
|
|
21
|
+
readonly id: "agents";
|
|
22
|
+
readonly label: "通用 .agents 目录";
|
|
23
|
+
readonly userDir: "~/.agents/skills";
|
|
24
|
+
readonly projectDir: ".agents/skills";
|
|
25
|
+
readonly detectDir: "~/.agents";
|
|
26
|
+
}];
|
|
27
|
+
export type OrchestratorTargetId = (typeof ORCHESTRATOR_SKILL_TARGETS)[number]["id"];
|
|
28
|
+
export declare function isOrchestratorTargetId(value: string): value is OrchestratorTargetId;
|
|
29
|
+
export interface DetectOrchestratorOptions {
|
|
30
|
+
readonly home?: string;
|
|
31
|
+
readonly cwd?: string;
|
|
32
|
+
readonly project?: boolean;
|
|
33
|
+
}
|
|
34
|
+
export interface DetectedOrchestratorTarget {
|
|
35
|
+
readonly target: OrchestratorSkillTarget;
|
|
36
|
+
readonly present: boolean;
|
|
37
|
+
readonly skillsDir: string;
|
|
38
|
+
}
|
|
39
|
+
export declare function detectOrchestratorTargets(options?: DetectOrchestratorOptions): readonly DetectedOrchestratorTarget[];
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
import{existsSync as e}from"node:fs";import{homedir as r}from"node:os";import{join as t,resolve as o}from"node:path";export const ORCHESTRATOR_SKILL_TARGETS=[{id:"claude-code",label:"Claude Code",userDir:"~/.claude/skills",projectDir:".claude/skills",detectDir:"~/.claude"},{id:"codex",label:"Codex",userDir:"~/.codex/skills",projectDir:".codex/skills",detectDir:"~/.codex"},{id:"agents",label:"通用 .agents 目录",userDir:"~/.agents/skills",projectDir:".agents/skills",detectDir:"~/.agents"}];const s=Object.fromEntries(ORCHESTRATOR_SKILL_TARGETS.map(e=>[e.id,e]));export function isOrchestratorTargetId(e){return e in s}function i(e,r){return t(e,r.replace(/^~\//,""))}export function detectOrchestratorTargets(t={}){const s=t.home??r(),c=t.cwd??process.cwd();return ORCHESTRATOR_SKILL_TARGETS.map(r=>({target:r,present:e(i(s,r.detectDir)),skillsDir:t.project?o(c,r.projectDir):i(s,r.userDir)}))}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@roll-agent/core",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.16.0",
|
|
4
4
|
"type": "module",
|
|
5
5
|
"repository": {
|
|
6
6
|
"type": "git",
|
|
@@ -27,6 +27,10 @@
|
|
|
27
27
|
"types": "./dist/registry/*.d.ts",
|
|
28
28
|
"default": "./dist/registry/*.js"
|
|
29
29
|
},
|
|
30
|
+
"./skills/*": {
|
|
31
|
+
"types": "./dist/skills/*.d.ts",
|
|
32
|
+
"default": "./dist/skills/*.js"
|
|
33
|
+
},
|
|
30
34
|
"./tool-runtime/*": {
|
|
31
35
|
"types": "./dist/tool-runtime/*.d.ts",
|
|
32
36
|
"default": "./dist/tool-runtime/*.js"
|
|
@@ -78,7 +82,7 @@
|
|
|
78
82
|
"react": "19.2.7",
|
|
79
83
|
"yaml": "^2.7.0",
|
|
80
84
|
"zod": "^3.25.76",
|
|
81
|
-
"@roll-agent/runtime": "0.
|
|
85
|
+
"@roll-agent/runtime": "0.5.0"
|
|
82
86
|
},
|
|
83
87
|
"devDependencies": {
|
|
84
88
|
"@types/cross-spawn": "6.0.6",
|