agenticros 0.1.11 → 0.1.13
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 +3 -2
- package/dist/commands/doctor.d.ts.map +1 -1
- package/dist/commands/doctor.js +56 -0
- package/dist/commands/doctor.js.map +1 -1
- package/dist/commands/skills.d.ts +24 -0
- package/dist/commands/skills.d.ts.map +1 -0
- package/dist/commands/skills.js +357 -0
- package/dist/commands/skills.js.map +1 -0
- package/dist/index.js +7 -0
- package/dist/index.js.map +1 -1
- package/dist/menu.d.ts.map +1 -1
- package/dist/menu.js +63 -0
- package/dist/menu.js.map +1 -1
- package/dist/util/openclaw-config.d.ts +40 -0
- package/dist/util/openclaw-config.d.ts.map +1 -0
- package/dist/util/openclaw-config.js +89 -0
- package/dist/util/openclaw-config.js.map +1 -0
- package/dist/util/skills.d.ts +112 -0
- package/dist/util/skills.d.ts.map +1 -0
- package/dist/util/skills.js +361 -0
- package/dist/util/skills.js.map +1 -0
- package/package.json +1 -1
- package/runtime/BUNDLE.json +1 -1
- package/runtime/README.md +84 -23
- package/runtime/packages/agenticros/openclaw.plugin.json +6 -2
- package/runtime/packages/agenticros-claude-code/src/tools.ts +29 -0
- package/runtime/packages/core/src/transport/local/transport.ts +30 -9
package/dist/menu.js
CHANGED
|
@@ -13,8 +13,10 @@ import { doctorCommand, hasRedChecks } from "./commands/doctor.js";
|
|
|
13
13
|
import { statusCommand } from "./commands/status.js";
|
|
14
14
|
import { logsCommand } from "./commands/logs.js";
|
|
15
15
|
import { configCommand } from "./commands/config.js";
|
|
16
|
+
import { skillsCommand } from "./commands/skills.js";
|
|
16
17
|
import { header, info, isTty, dim } from "./util/logger.js";
|
|
17
18
|
import { readState, formatAge } from "./util/state.js";
|
|
19
|
+
import { listSkills } from "./util/skills.js";
|
|
18
20
|
export async function runMenu() {
|
|
19
21
|
if (!isTty) {
|
|
20
22
|
info("Interactive menu requires a TTY. Use a subcommand (e.g. `agenticros up real`) or `agenticros --help`.");
|
|
@@ -28,10 +30,13 @@ export async function runMenu() {
|
|
|
28
30
|
}
|
|
29
31
|
// Need-setup detection. Doctor returns a count; we use that to reorder.
|
|
30
32
|
const setupNeeded = await hasRedChecks();
|
|
33
|
+
const skillsListing = safeListSkills();
|
|
34
|
+
const skillsSuffix = formatSkillsSuffix(skillsListing);
|
|
31
35
|
const baseChoices = [
|
|
32
36
|
{ name: "Launch with real robot", value: "real" },
|
|
33
37
|
{ name: "Launch with simulation", value: "sim" },
|
|
34
38
|
{ name: "First-time setup (workspace + OpenClaw plugin + API key)", value: "init" },
|
|
39
|
+
{ name: `Manage skills${skillsSuffix}`, value: "skills" },
|
|
35
40
|
{ name: "Stop everything", value: "down" },
|
|
36
41
|
{ name: "Doctor (health check)", value: "doctor" },
|
|
37
42
|
{ name: "Configure (API keys, namespace, transport)", value: "config" },
|
|
@@ -82,6 +87,9 @@ export async function runMenu() {
|
|
|
82
87
|
case "config":
|
|
83
88
|
await configCommand({ action: "show" });
|
|
84
89
|
break;
|
|
90
|
+
case "skills":
|
|
91
|
+
await skillsSubmenu();
|
|
92
|
+
break;
|
|
85
93
|
case "logs":
|
|
86
94
|
await logsCommand({ target: undefined });
|
|
87
95
|
break;
|
|
@@ -93,4 +101,59 @@ export async function runMenu() {
|
|
|
93
101
|
break;
|
|
94
102
|
}
|
|
95
103
|
}
|
|
104
|
+
/**
|
|
105
|
+
* Skills sub-menu. Reads the OpenClaw config so the prompt can show how many
|
|
106
|
+
* skills are registered and offer the right next step (discover when nothing
|
|
107
|
+
* is registered yet, otherwise list-first).
|
|
108
|
+
*/
|
|
109
|
+
async function skillsSubmenu() {
|
|
110
|
+
const listing = safeListSkills();
|
|
111
|
+
const hasAvailable = listing && listing.available.length > 0;
|
|
112
|
+
const hasRegistered = listing && listing.registered.length > 0;
|
|
113
|
+
const action = await select({
|
|
114
|
+
message: "Skills:",
|
|
115
|
+
choices: [
|
|
116
|
+
{ name: "List registered + available", value: "list" },
|
|
117
|
+
{
|
|
118
|
+
name: hasAvailable
|
|
119
|
+
? `Discover & register (${listing.available.length} unregistered found)`
|
|
120
|
+
: "Discover & register (interactive picker)",
|
|
121
|
+
value: "discover",
|
|
122
|
+
},
|
|
123
|
+
{ name: "Add a skill by path or package name", value: "add" },
|
|
124
|
+
{ name: "Remove a skill", value: "remove" },
|
|
125
|
+
{ name: "Sync OpenClaw contracts.tools allowlist", value: "sync" },
|
|
126
|
+
{ name: "Back", value: "back" },
|
|
127
|
+
],
|
|
128
|
+
default: hasRegistered ? "list" : "discover",
|
|
129
|
+
});
|
|
130
|
+
if (action === "back")
|
|
131
|
+
return;
|
|
132
|
+
await skillsCommand({ action });
|
|
133
|
+
}
|
|
134
|
+
/** Read skills without throwing; the menu must keep working even if the config is broken. */
|
|
135
|
+
function safeListSkills() {
|
|
136
|
+
try {
|
|
137
|
+
return listSkills();
|
|
138
|
+
}
|
|
139
|
+
catch {
|
|
140
|
+
return undefined;
|
|
141
|
+
}
|
|
142
|
+
}
|
|
143
|
+
/** Inline summary attached to the "Manage skills" menu label. */
|
|
144
|
+
function formatSkillsSuffix(listing) {
|
|
145
|
+
if (!listing)
|
|
146
|
+
return "";
|
|
147
|
+
const parts = [];
|
|
148
|
+
if (listing.registered.length > 0) {
|
|
149
|
+
parts.push(`${listing.registered.length} registered`);
|
|
150
|
+
}
|
|
151
|
+
if (listing.available.length > 0) {
|
|
152
|
+
parts.push(`${listing.available.length} available`);
|
|
153
|
+
}
|
|
154
|
+
if (listing.brokenPaths.length > 0) {
|
|
155
|
+
parts.push(`${listing.brokenPaths.length} broken`);
|
|
156
|
+
}
|
|
157
|
+
return parts.length > 0 ? ` (${parts.join(", ")})` : "";
|
|
158
|
+
}
|
|
96
159
|
//# sourceMappingURL=menu.js.map
|
package/dist/menu.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"menu.js","sourceRoot":"","sources":["../src/menu.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;AAEH,OAAO,EAAE,MAAM,EAAE,OAAO,EAAE,MAAM,mBAAmB,CAAC;AAEpD,OAAO,EAAE,SAAS,EAAE,MAAM,kBAAkB,CAAC;AAC7C,OAAO,EAAE,WAAW,EAAE,MAAM,oBAAoB,CAAC;AACjD,OAAO,EAAE,WAAW,EAAE,MAAM,oBAAoB,CAAC;AACjD,OAAO,EAAE,aAAa,EAAE,YAAY,EAAE,MAAM,sBAAsB,CAAC;AACnE,OAAO,EAAE,aAAa,EAAE,MAAM,sBAAsB,CAAC;AACrD,OAAO,EAAE,WAAW,EAAE,MAAM,oBAAoB,CAAC;AACjD,OAAO,EAAE,aAAa,EAAE,MAAM,sBAAsB,CAAC;AACrD,OAAO,EAAE,MAAM,EAAE,IAAI,EAAE,KAAK,EAAE,GAAG,EAAE,MAAM,kBAAkB,CAAC;AAC5D,OAAO,EAAE,SAAS,EAAE,SAAS,EAAE,MAAM,iBAAiB,CAAC;
|
|
1
|
+
{"version":3,"file":"menu.js","sourceRoot":"","sources":["../src/menu.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,40 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Safe read/write helper for the OpenClaw gateway config file.
|
|
3
|
+
*
|
|
4
|
+
* The OpenClaw config (default: `~/.openclaw/openclaw.json`) is the source of
|
|
5
|
+
* truth for the AgenticROS *plugin*'s skill configuration —
|
|
6
|
+
* `plugins.entries.agenticros.config.skillPaths` and `.skillPackages` decide
|
|
7
|
+
* which skill packages the plugin loads at gateway start. The MCP server and
|
|
8
|
+
* the Gemini CLI read their config from `~/.agenticros/config.json` instead;
|
|
9
|
+
* neither currently loads skills.
|
|
10
|
+
*
|
|
11
|
+
* This module exists so the rest of the CLI can mutate that nested
|
|
12
|
+
* `plugins.entries.agenticros.config` slice without round-tripping the entire
|
|
13
|
+
* JSON document or accidentally clobbering unrelated keys (gateway auth,
|
|
14
|
+
* other plugins, etc). Every write goes through the full JSON parse → mutate
|
|
15
|
+
* → stringify cycle to keep the file valid; comments are not supported in the
|
|
16
|
+
* source JSON either way.
|
|
17
|
+
*/
|
|
18
|
+
/** Default location of the OpenClaw config. Overridable via `$OPENCLAW_CONFIG`. */
|
|
19
|
+
export declare function openclawConfigPath(): string;
|
|
20
|
+
export declare function openclawConfigExists(): boolean;
|
|
21
|
+
/**
|
|
22
|
+
* Read the OpenClaw config or return `undefined` if it doesn't exist / is
|
|
23
|
+
* not valid JSON. We never throw — callers can decide how loudly to fail.
|
|
24
|
+
*/
|
|
25
|
+
export declare function readOpenclawConfig(): Record<string, unknown> | undefined;
|
|
26
|
+
/** Write the config back, pretty-printed (2-space indent), with a trailing newline. */
|
|
27
|
+
export declare function writeOpenclawConfig(cfg: Record<string, unknown>): void;
|
|
28
|
+
/**
|
|
29
|
+
* Locate (and lazily create) the `plugins.entries.agenticros.config` subtree.
|
|
30
|
+
* Mutates `cfg` in place and returns the inner config object so callers can
|
|
31
|
+
* read/modify its `skillPaths`, `skillPackages`, `skills`, etc.
|
|
32
|
+
*/
|
|
33
|
+
export declare function getAgenticrosPluginConfig(cfg: Record<string, unknown>): Record<string, unknown>;
|
|
34
|
+
/**
|
|
35
|
+
* Ensure `obj[key]` is an array of strings and return it (creating an empty
|
|
36
|
+
* array if needed). Non-string entries in an existing array are preserved so
|
|
37
|
+
* we don't silently drop opaque values, but lookups still operate on strings.
|
|
38
|
+
*/
|
|
39
|
+
export declare function ensureStringArray(obj: Record<string, unknown>, key: string): unknown[];
|
|
40
|
+
//# sourceMappingURL=openclaw-config.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"openclaw-config.d.ts","sourceRoot":"","sources":["../../src/util/openclaw-config.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;GAgBG;AAMH,mFAAmF;AACnF,wBAAgB,kBAAkB,IAAI,MAAM,CAI3C;AAED,wBAAgB,oBAAoB,IAAI,OAAO,CAE9C;AAED;;;GAGG;AACH,wBAAgB,kBAAkB,IAAI,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,GAAG,SAAS,CAYxE;AAED,uFAAuF;AACvF,wBAAgB,mBAAmB,CAAC,GAAG,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,GAAG,IAAI,CAItE;AAED;;;;GAIG;AACH,wBAAgB,yBAAyB,CAAC,GAAG,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,GAAG,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAK/F;AAYD;;;;GAIG;AACH,wBAAgB,iBAAiB,CAC/B,GAAG,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,EAC5B,GAAG,EAAE,MAAM,GACV,OAAO,EAAE,CAMX"}
|
|
@@ -0,0 +1,89 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Safe read/write helper for the OpenClaw gateway config file.
|
|
3
|
+
*
|
|
4
|
+
* The OpenClaw config (default: `~/.openclaw/openclaw.json`) is the source of
|
|
5
|
+
* truth for the AgenticROS *plugin*'s skill configuration —
|
|
6
|
+
* `plugins.entries.agenticros.config.skillPaths` and `.skillPackages` decide
|
|
7
|
+
* which skill packages the plugin loads at gateway start. The MCP server and
|
|
8
|
+
* the Gemini CLI read their config from `~/.agenticros/config.json` instead;
|
|
9
|
+
* neither currently loads skills.
|
|
10
|
+
*
|
|
11
|
+
* This module exists so the rest of the CLI can mutate that nested
|
|
12
|
+
* `plugins.entries.agenticros.config` slice without round-tripping the entire
|
|
13
|
+
* JSON document or accidentally clobbering unrelated keys (gateway auth,
|
|
14
|
+
* other plugins, etc). Every write goes through the full JSON parse → mutate
|
|
15
|
+
* → stringify cycle to keep the file valid; comments are not supported in the
|
|
16
|
+
* source JSON either way.
|
|
17
|
+
*/
|
|
18
|
+
import { existsSync, mkdirSync, readFileSync, writeFileSync } from "node:fs";
|
|
19
|
+
import { dirname, join } from "node:path";
|
|
20
|
+
import { homedir } from "node:os";
|
|
21
|
+
/** Default location of the OpenClaw config. Overridable via `$OPENCLAW_CONFIG`. */
|
|
22
|
+
export function openclawConfigPath() {
|
|
23
|
+
const env = process.env["OPENCLAW_CONFIG"];
|
|
24
|
+
if (env && env.trim().length > 0)
|
|
25
|
+
return env;
|
|
26
|
+
return join(homedir(), ".openclaw", "openclaw.json");
|
|
27
|
+
}
|
|
28
|
+
export function openclawConfigExists() {
|
|
29
|
+
return existsSync(openclawConfigPath());
|
|
30
|
+
}
|
|
31
|
+
/**
|
|
32
|
+
* Read the OpenClaw config or return `undefined` if it doesn't exist / is
|
|
33
|
+
* not valid JSON. We never throw — callers can decide how loudly to fail.
|
|
34
|
+
*/
|
|
35
|
+
export function readOpenclawConfig() {
|
|
36
|
+
const p = openclawConfigPath();
|
|
37
|
+
if (!existsSync(p))
|
|
38
|
+
return undefined;
|
|
39
|
+
try {
|
|
40
|
+
const parsed = JSON.parse(readFileSync(p, "utf8"));
|
|
41
|
+
if (parsed && typeof parsed === "object" && !Array.isArray(parsed)) {
|
|
42
|
+
return parsed;
|
|
43
|
+
}
|
|
44
|
+
return undefined;
|
|
45
|
+
}
|
|
46
|
+
catch {
|
|
47
|
+
return undefined;
|
|
48
|
+
}
|
|
49
|
+
}
|
|
50
|
+
/** Write the config back, pretty-printed (2-space indent), with a trailing newline. */
|
|
51
|
+
export function writeOpenclawConfig(cfg) {
|
|
52
|
+
const p = openclawConfigPath();
|
|
53
|
+
mkdirSync(dirname(p), { recursive: true });
|
|
54
|
+
writeFileSync(p, `${JSON.stringify(cfg, null, 2)}\n`);
|
|
55
|
+
}
|
|
56
|
+
/**
|
|
57
|
+
* Locate (and lazily create) the `plugins.entries.agenticros.config` subtree.
|
|
58
|
+
* Mutates `cfg` in place and returns the inner config object so callers can
|
|
59
|
+
* read/modify its `skillPaths`, `skillPackages`, `skills`, etc.
|
|
60
|
+
*/
|
|
61
|
+
export function getAgenticrosPluginConfig(cfg) {
|
|
62
|
+
const plugins = asObject(cfg, "plugins");
|
|
63
|
+
const entries = asObject(plugins, "entries");
|
|
64
|
+
const agenticros = asObject(entries, "agenticros");
|
|
65
|
+
return asObject(agenticros, "config");
|
|
66
|
+
}
|
|
67
|
+
function asObject(parent, key) {
|
|
68
|
+
const cur = parent[key];
|
|
69
|
+
if (cur && typeof cur === "object" && !Array.isArray(cur)) {
|
|
70
|
+
return cur;
|
|
71
|
+
}
|
|
72
|
+
const fresh = {};
|
|
73
|
+
parent[key] = fresh;
|
|
74
|
+
return fresh;
|
|
75
|
+
}
|
|
76
|
+
/**
|
|
77
|
+
* Ensure `obj[key]` is an array of strings and return it (creating an empty
|
|
78
|
+
* array if needed). Non-string entries in an existing array are preserved so
|
|
79
|
+
* we don't silently drop opaque values, but lookups still operate on strings.
|
|
80
|
+
*/
|
|
81
|
+
export function ensureStringArray(obj, key) {
|
|
82
|
+
const cur = obj[key];
|
|
83
|
+
if (Array.isArray(cur))
|
|
84
|
+
return cur;
|
|
85
|
+
const fresh = [];
|
|
86
|
+
obj[key] = fresh;
|
|
87
|
+
return fresh;
|
|
88
|
+
}
|
|
89
|
+
//# sourceMappingURL=openclaw-config.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"openclaw-config.js","sourceRoot":"","sources":["../../src/util/openclaw-config.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,112 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Skill discovery, validation, and config-file mutation primitives.
|
|
3
|
+
*
|
|
4
|
+
* An AgenticROS skill is a Node package whose `package.json` carries
|
|
5
|
+
* `"agenticrosSkill": true` and exports a `registerSkill(api, config, context)`
|
|
6
|
+
* function from its `main` entry. The OpenClaw AgenticROS plugin loads them
|
|
7
|
+
* at gateway start by walking two arrays in its config:
|
|
8
|
+
*
|
|
9
|
+
* - `skillPaths[]` — absolute directories to scan (validate `package.json`)
|
|
10
|
+
* - `skillPackages[]` — npm-resolvable names (e.g. `agenticros-skill-find`)
|
|
11
|
+
*
|
|
12
|
+
* This module is the single place the CLI talks to those arrays. It also
|
|
13
|
+
* encapsulates discovery (where on disk users typically clone skill repos)
|
|
14
|
+
* and the `deriveSkillId` convention shared with `@agenticros/agenticros`'s
|
|
15
|
+
* skill-loader so menu / list output uses the same short ids the plugin
|
|
16
|
+
* surfaces (e.g. `followme`, `find`).
|
|
17
|
+
*/
|
|
18
|
+
export interface SkillRef {
|
|
19
|
+
/** Short id (matches what the OpenClaw plugin uses for `config.skills.<id>`). */
|
|
20
|
+
id: string;
|
|
21
|
+
/** npm package name (from `package.json.name`). */
|
|
22
|
+
packageName: string;
|
|
23
|
+
/** Absolute directory containing `package.json`, when known. */
|
|
24
|
+
dir?: string;
|
|
25
|
+
/** Where the skill is currently registered with the gateway. */
|
|
26
|
+
registeredAs: ("path" | "package")[];
|
|
27
|
+
/**
|
|
28
|
+
* Absolute path the skill's `package.json` declares as its entry (`main`),
|
|
29
|
+
* resolved against `dir`. Only set when we inspected the directory.
|
|
30
|
+
*/
|
|
31
|
+
entry?: string;
|
|
32
|
+
/** True when `entry` exists on disk; false when the skill needs `pnpm build`. */
|
|
33
|
+
built?: boolean;
|
|
34
|
+
}
|
|
35
|
+
/**
|
|
36
|
+
* Apply the same short-id transform the OpenClaw plugin's skill-loader uses,
|
|
37
|
+
* so menu output and the plugin's `config.skills.<id>` keys line up exactly.
|
|
38
|
+
* `agenticros-skill-followme` → `followme`; scoped packages drop the scope.
|
|
39
|
+
*/
|
|
40
|
+
export declare function deriveSkillId(packageName: string): string;
|
|
41
|
+
/**
|
|
42
|
+
* Inspect a directory and decide whether it's a valid AgenticROS skill clone.
|
|
43
|
+
* Returns a partial `SkillRef` (no `registeredAs`) or `undefined` when the
|
|
44
|
+
* directory is missing, lacks `package.json`, or doesn't opt in via the
|
|
45
|
+
* `agenticrosSkill: true` flag.
|
|
46
|
+
*/
|
|
47
|
+
export declare function inspectSkillDir(dir: string): Omit<SkillRef, "registeredAs"> | undefined;
|
|
48
|
+
/**
|
|
49
|
+
* Return a deduped list of "places we should look for skill clones" — the
|
|
50
|
+
* directories whose children the CLI scans on `agenticros skills discover`.
|
|
51
|
+
*
|
|
52
|
+
* We include both the parent of the active repo / install dir (so siblings
|
|
53
|
+
* of `agenticros/` work, e.g. `../agenticros-skill-find`) and `$HOME` /
|
|
54
|
+
* `$HOME/Projects/` / `$HOME/Code/` so a vanilla clone-into-Projects flow
|
|
55
|
+
* is found without configuration.
|
|
56
|
+
*/
|
|
57
|
+
export declare function discoveryRoots(extra?: string[]): string[];
|
|
58
|
+
/**
|
|
59
|
+
* Walk every directory in `roots`, returning a `SkillRef` for each child
|
|
60
|
+
* directory that passes `inspectSkillDir`. Used by both `discover` and
|
|
61
|
+
* `list` (which uses it to render orphaned-but-cloned skills).
|
|
62
|
+
*/
|
|
63
|
+
export declare function scanForSkills(extra?: string[]): SkillRef[];
|
|
64
|
+
export interface SkillsListing {
|
|
65
|
+
/** Skills currently registered in the OpenClaw config (path-loaded or package-loaded). */
|
|
66
|
+
registered: SkillRef[];
|
|
67
|
+
/** Skill clones that exist on disk in known discovery roots but aren't registered. */
|
|
68
|
+
available: SkillRef[];
|
|
69
|
+
/** `skillPaths` entries that refer to a directory that no longer exists. */
|
|
70
|
+
brokenPaths: string[];
|
|
71
|
+
}
|
|
72
|
+
/**
|
|
73
|
+
* Build a snapshot of the user's current skill state: what's registered,
|
|
74
|
+
* what's available-but-not-registered, and what registrations are broken.
|
|
75
|
+
* The single source of truth for the `agenticros skills` (list) view.
|
|
76
|
+
*/
|
|
77
|
+
export declare function listSkills(): SkillsListing;
|
|
78
|
+
export interface AddResult {
|
|
79
|
+
ok: boolean;
|
|
80
|
+
/** Human-readable summary of what changed (or why nothing changed). */
|
|
81
|
+
message: string;
|
|
82
|
+
skill?: SkillRef;
|
|
83
|
+
}
|
|
84
|
+
/**
|
|
85
|
+
* Add a skill to the OpenClaw plugin config by absolute directory path.
|
|
86
|
+
* Idempotent: re-adding an existing entry is a no-op and returns `ok: true`
|
|
87
|
+
* with an explanatory message. The directory must contain a valid
|
|
88
|
+
* `package.json` with `agenticrosSkill: true`.
|
|
89
|
+
*/
|
|
90
|
+
export declare function addSkillByPath(dir: string): AddResult;
|
|
91
|
+
/**
|
|
92
|
+
* Add a skill by npm package name (must be resolvable on the gateway's
|
|
93
|
+
* Node search path). Mainly intended for skills published to a registry —
|
|
94
|
+
* for local clones, prefer `addSkillByPath` so the absolute directory is
|
|
95
|
+
* recorded.
|
|
96
|
+
*/
|
|
97
|
+
export declare function addSkillByPackage(name: string): AddResult;
|
|
98
|
+
export interface RemoveResult {
|
|
99
|
+
ok: boolean;
|
|
100
|
+
message: string;
|
|
101
|
+
removedPaths: string[];
|
|
102
|
+
removedPackages: string[];
|
|
103
|
+
}
|
|
104
|
+
/**
|
|
105
|
+
* Remove every registration that matches `idOrName` — either a derived skill
|
|
106
|
+
* id (e.g. `find`), a full package name (e.g. `agenticros-skill-find`), or an
|
|
107
|
+
* absolute path that appears in `skillPaths`. Both `skillPaths` (matched by
|
|
108
|
+
* resolving each path back through `inspectSkillDir`) and `skillPackages`
|
|
109
|
+
* are cleaned in a single pass.
|
|
110
|
+
*/
|
|
111
|
+
export declare function removeSkill(idOrName: string): RemoveResult;
|
|
112
|
+
//# sourceMappingURL=skills.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"skills.d.ts","sourceRoot":"","sources":["../../src/util/skills.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;GAgBG;AAgBH,MAAM,WAAW,QAAQ;IACvB,iFAAiF;IACjF,EAAE,EAAE,MAAM,CAAC;IACX,mDAAmD;IACnD,WAAW,EAAE,MAAM,CAAC;IACpB,gEAAgE;IAChE,GAAG,CAAC,EAAE,MAAM,CAAC;IACb,gEAAgE;IAChE,YAAY,EAAE,CAAC,MAAM,GAAG,SAAS,CAAC,EAAE,CAAC;IACrC;;;OAGG;IACH,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,iFAAiF;IACjF,KAAK,CAAC,EAAE,OAAO,CAAC;CACjB;AAED;;;;GAIG;AACH,wBAAgB,aAAa,CAAC,WAAW,EAAE,MAAM,GAAG,MAAM,CAMzD;AAED;;;;;GAKG;AACH,wBAAgB,eAAe,CAAC,GAAG,EAAE,MAAM,GAAG,IAAI,CAAC,QAAQ,EAAE,cAAc,CAAC,GAAG,SAAS,CA6BvF;AAED;;;;;;;;GAQG;AACH,wBAAgB,cAAc,CAAC,KAAK,GAAE,MAAM,EAAO,GAAG,MAAM,EAAE,CAuB7D;AAED;;;;GAIG;AACH,wBAAgB,aAAa,CAAC,KAAK,GAAE,MAAM,EAAO,GAAG,QAAQ,EAAE,CAqB9D;AA0BD,MAAM,WAAW,aAAa;IAC5B,0FAA0F;IAC1F,UAAU,EAAE,QAAQ,EAAE,CAAC;IACvB,sFAAsF;IACtF,SAAS,EAAE,QAAQ,EAAE,CAAC;IACtB,4EAA4E;IAC5E,WAAW,EAAE,MAAM,EAAE,CAAC;CACvB;AAED;;;;GAIG;AACH,wBAAgB,UAAU,IAAI,aAAa,CAyC1C;AAED,MAAM,WAAW,SAAS;IACxB,EAAE,EAAE,OAAO,CAAC;IACZ,uEAAuE;IACvE,OAAO,EAAE,MAAM,CAAC;IAChB,KAAK,CAAC,EAAE,QAAQ,CAAC;CAClB;AAED;;;;;GAKG;AACH,wBAAgB,cAAc,CAAC,GAAG,EAAE,MAAM,GAAG,SAAS,CAuCrD;AAED;;;;;GAKG;AACH,wBAAgB,iBAAiB,CAAC,IAAI,EAAE,MAAM,GAAG,SAAS,CA6BzD;AAED,MAAM,WAAW,YAAY;IAC3B,EAAE,EAAE,OAAO,CAAC;IACZ,OAAO,EAAE,MAAM,CAAC;IAChB,YAAY,EAAE,MAAM,EAAE,CAAC;IACvB,eAAe,EAAE,MAAM,EAAE,CAAC;CAC3B;AAED;;;;;;GAMG;AACH,wBAAgB,WAAW,CAAC,QAAQ,EAAE,MAAM,GAAG,YAAY,CA+D1D"}
|