Skills: prefer active OpenClaw paths

This commit is contained in:
Shakker
2026-03-30 15:50:44 +01:00
committed by Shakker
parent 08d365f481
commit a3de1f5f55
12 changed files with 144 additions and 27 deletions

View File

@@ -0,0 +1,64 @@
import fs from "node:fs";
import path from "node:path";
import { describe, expect, it } from "vitest";
const REPO_ROOT = path.resolve(import.meta.dirname, "..", "..");
type GuidanceCase = {
file: string;
required?: string[];
forbidden?: string[];
};
const CASES: GuidanceCase[] = [
{
file: "skills/session-logs/SKILL.md",
required: ["OPENCLAW_STATE_DIR"],
forbidden: [
"for f in ~/.openclaw/agents/<agentId>/sessions/*.jsonl",
'rg -l "phrase" ~/.openclaw/agents/<agentId>/sessions/*.jsonl',
],
},
{
file: "skills/gh-issues/SKILL.md",
required: ["OPENCLAW_CONFIG_PATH"],
forbidden: ["cat ~/.openclaw/openclaw.json"],
},
{
file: "skills/canvas/SKILL.md",
required: ["OPENCLAW_CONFIG_PATH"],
forbidden: ["cat ~/.openclaw/openclaw.json"],
},
{
file: "skills/openai-whisper-api/SKILL.md",
required: ["OPENCLAW_CONFIG_PATH"],
},
{
file: "skills/sherpa-onnx-tts/SKILL.md",
required: ["OPENCLAW_STATE_DIR", "OPENCLAW_CONFIG_PATH"],
forbidden: [
'SHERPA_ONNX_RUNTIME_DIR: "~/.openclaw/tools/sherpa-onnx-tts/runtime"',
'SHERPA_ONNX_MODEL_DIR: "~/.openclaw/tools/sherpa-onnx-tts/models/vits-piper-en_US-lessac-high"',
],
},
{
file: "skills/coding-agent/SKILL.md",
required: ["OPENCLAW_STATE_DIR"],
forbidden: ["NEVER start Codex in ~/.openclaw/"],
},
];
describe("bundled skill env-path guidance", () => {
it.each(CASES)(
"keeps $file aligned with OPENCLAW env overrides",
({ file, required, forbidden }) => {
const content = fs.readFileSync(path.join(REPO_ROOT, file), "utf8");
for (const needle of required ?? []) {
expect(content).toContain(needle);
}
for (const needle of forbidden ?? []) {
expect(content).not.toContain(needle);
}
},
);
});

View File

@@ -153,7 +153,11 @@ export function registerDnsCli(program: Command) {
}).trimEnd(),
);
defaultRuntime.log("");
defaultRuntime.log(theme.heading("Recommended ~/.openclaw/openclaw.json:"));
defaultRuntime.log(
theme.heading(
"Recommended config ($OPENCLAW_CONFIG_PATH, default ~/.openclaw/openclaw.json):",
),
);
defaultRuntime.writeJson({
gateway: { bind: "auto" },
discovery: { wideArea: { enabled: true, domain: wideAreaDomain } },
@@ -248,7 +252,7 @@ export function registerDnsCli(program: Command) {
defaultRuntime.log("");
defaultRuntime.log(
theme.muted(
"Note: enable discovery.wideArea.enabled in ~/.openclaw/openclaw.json on the gateway and restart the gateway so it writes the DNS-SD zone.",
"Note: enable discovery.wideArea.enabled in the active OpenClaw config ($OPENCLAW_CONFIG_PATH, default ~/.openclaw/openclaw.json) on the gateway and restart the gateway so it writes the DNS-SD zone.",
),
);
}

View File

@@ -10,7 +10,7 @@ import { hasExplicitOptions } from "../command-options.js";
export function registerSetupCommand(program: Command) {
program
.command("setup")
.description("Initialize ~/.openclaw/openclaw.json and the agent workspace")
.description("Initialize the active OpenClaw config and agent workspace")
.addHelpText(
"after",
() =>

View File

@@ -282,7 +282,7 @@ export function formatSkillInfo(
` Save via CLI: ${formatCliCommand(`openclaw config set skills.entries.${safeSkillKey}.apiKey YOUR_KEY`)}`,
);
lines.push(
` Stored in: ${theme.muted("~/.openclaw/openclaw.json")} ${theme.muted(`(skills.entries.${safeSkillKey}.apiKey)`)}`,
` Stored in: ${theme.muted("$OPENCLAW_CONFIG_PATH")} ${theme.muted("(default: ~/.openclaw/openclaw.json)")}`,
);
}

View File

@@ -149,6 +149,36 @@ describe("skills-cli", () => {
expect(output).toContain("API_KEY");
});
it("shows API key storage guidance for the active config path", () => {
const report = createMockReport([
createMockSkill({
name: "env-aware-skill",
skillKey: "env-aware-skill",
primaryEnv: "API_KEY",
eligible: false,
requirements: {
bins: [],
anyBins: [],
env: ["API_KEY"],
config: [],
os: [],
},
missing: {
bins: [],
anyBins: [],
env: ["API_KEY"],
config: [],
os: [],
},
}),
]);
const output = formatSkillInfo(report, "env-aware-skill", {});
expect(output).toContain("OPENCLAW_CONFIG_PATH");
expect(output).toContain("default: ~/.openclaw/openclaw.json");
expect(output).toContain("skills.entries.env-aware-skill.apiKey");
});
it("normalizes text-presentation emoji selectors in info output", () => {
const report = createMockReport([
createMockSkill({

View File

@@ -390,7 +390,7 @@ export async function finalizeSetupWizard(
await prompter.note(
[
"Gateway token: shared auth for the Gateway + Control UI.",
"Stored in: ~/.openclaw/openclaw.json (gateway.auth.token) or OPENCLAW_GATEWAY_TOKEN.",
"Stored in: $OPENCLAW_CONFIG_PATH (default: ~/.openclaw/openclaw.json) under gateway.auth.token, or in OPENCLAW_GATEWAY_TOKEN.",
`View token: ${formatCliCommand("openclaw config get gateway.auth.token")}`,
`Generate token: ${formatCliCommand("openclaw doctor --generate-gateway-token")}`,
"Web UI keeps dashboard URL tokens in memory for the current tab and strips them from the URL after load.",