@agentprojectcontext/apx 1.34.0 → 1.35.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/package.json +1 -1
- package/skills/apx/SKILL.md +1 -1
- package/src/core/agent/build-agent-system.js +134 -58
- package/src/core/agent/channels/voice-context.js +4 -4
- package/src/core/agent/prompt-builder.js +176 -123
- package/src/core/agent/prompts/channels/code.md +12 -10
- package/src/core/agent/prompts/channels/desktop.md +5 -32
- package/src/core/agent/prompts/channels/telegram.md +4 -15
- package/src/core/agent/prompts/channels/web_code.md +11 -11
- package/src/core/agent/prompts/core/agent-base.md +24 -0
- package/src/core/agent/prompts/core/project-agent.md +11 -0
- package/src/core/agent/prompts/core/super-agent.md +21 -0
- package/src/core/agent/prompts/discipline/action.md +10 -0
- package/src/core/agent/prompts/discipline/single-segment.md +6 -0
- package/src/core/agent/prompts/discipline/two-segment.md +11 -0
- package/src/core/agent/self-memory.js +43 -1
- package/src/core/agent/skills/index-store.js +307 -0
- package/src/core/agent/skills/index.js +15 -1
- package/src/core/agent/skills/inspector.js +317 -0
- package/src/core/agent/super-agent.js +7 -1
- package/src/core/agent/tools/handlers/_git.js +50 -0
- package/src/core/agent/tools/handlers/git-diff.js +44 -0
- package/src/core/agent/tools/handlers/git-log.js +38 -0
- package/src/core/agent/tools/handlers/git-show.js +34 -0
- package/src/core/agent/tools/handlers/git-status.js +61 -0
- package/src/core/agent/tools/names.js +31 -0
- package/src/core/agent/tools/registry.js +36 -5
- package/src/core/config/index.js +21 -0
- package/src/core/runtime-skills/apx/SKILL.md +27 -39
- package/src/core/runtime-skills/apx-agency-agents/SKILL.md +40 -56
- package/src/core/runtime-skills/apx-agent/SKILL.md +27 -30
- package/src/core/runtime-skills/apx-mcp/SKILL.md +31 -36
- package/src/core/runtime-skills/apx-mcp-builder/SKILL.md +37 -51
- package/src/core/runtime-skills/apx-project/SKILL.md +20 -29
- package/src/core/runtime-skills/apx-routine/SKILL.md +34 -47
- package/src/core/runtime-skills/apx-runtime/SKILL.md +32 -50
- package/src/core/runtime-skills/apx-sessions/SKILL.md +96 -145
- package/src/core/runtime-skills/apx-skill-builder/SKILL.md +53 -77
- package/src/core/runtime-skills/apx-task/SKILL.md +18 -21
- package/src/core/runtime-skills/apx-telegram/SKILL.md +43 -54
- package/src/core/runtime-skills/apx-voice/SKILL.md +36 -56
- package/src/host/daemon/api/skills.js +140 -6
- package/src/host/daemon/api/super-agent.js +56 -1
- package/src/host/daemon/index.js +17 -0
- package/src/interfaces/cli/branding.js +53 -0
- package/src/interfaces/cli/commands/skills.js +254 -0
- package/src/interfaces/cli/index.js +84 -2
- package/src/interfaces/web/dist/assets/index-C0fm31dY.js +618 -0
- package/src/interfaces/web/dist/assets/index-C0fm31dY.js.map +1 -0
- package/src/interfaces/web/dist/assets/index-UcAqlBO6.css +1 -0
- package/src/interfaces/web/dist/index.html +2 -2
- package/src/interfaces/web/src/components/chat/MessageBubble.tsx +21 -1
- package/src/interfaces/web/src/components/settings/MemoryPanel.tsx +68 -0
- package/src/interfaces/web/src/components/settings/SkillsInspectorPanel.tsx +222 -0
- package/src/interfaces/web/src/hooks/useChat.ts +19 -0
- package/src/interfaces/web/src/i18n/en.ts +1 -0
- package/src/interfaces/web/src/i18n/es.ts +1 -0
- package/src/interfaces/web/src/lib/api/skills.ts +70 -0
- package/src/interfaces/web/src/screens/SettingsScreen.tsx +6 -2
- package/src/interfaces/web/src/types/daemon.ts +10 -0
- package/src/core/agent/prompts/action-discipline.md +0 -24
- package/src/core/agent/prompts/super-agent-base.md +0 -42
- package/src/interfaces/web/dist/assets/index-DdmSRtsz.css +0 -1
- package/src/interfaces/web/dist/assets/index-M4FspaCH.js +0 -613
- package/src/interfaces/web/dist/assets/index-M4FspaCH.js.map +0 -1
|
@@ -15,6 +15,20 @@ import {
|
|
|
15
15
|
listEngineSkills,
|
|
16
16
|
listLegacyPruneSlugs,
|
|
17
17
|
} from "#core/apc/scaffold.js";
|
|
18
|
+
import {
|
|
19
|
+
ensureIndex,
|
|
20
|
+
planIndex,
|
|
21
|
+
readIndex,
|
|
22
|
+
clearIndex,
|
|
23
|
+
indexPath,
|
|
24
|
+
} from "#core/agent/skills/index-store.js";
|
|
25
|
+
import { isInspectorEnabled } from "#core/agent/skills/inspector.js";
|
|
26
|
+
import {
|
|
27
|
+
inspectPromptForSkills,
|
|
28
|
+
summarizeTrace,
|
|
29
|
+
INSPECTOR_DEFAULTS,
|
|
30
|
+
} from "#core/agent/skills/inspector.js";
|
|
31
|
+
import { readConfig, writeConfig } from "#core/config/index.js";
|
|
18
32
|
|
|
19
33
|
// ---------------------------------------------------------------------------
|
|
20
34
|
// Prompt helper
|
|
@@ -30,6 +44,31 @@ function ask(question) {
|
|
|
30
44
|
});
|
|
31
45
|
}
|
|
32
46
|
|
|
47
|
+
// When the Skill Inspector is on, the catalog it scores against must stay in
|
|
48
|
+
// sync with what's installed. Called after add/sync so a freshly available
|
|
49
|
+
// skill is searchable immediately, without a separate `apx skills index`.
|
|
50
|
+
// No-op (silent) when the inspector is disabled — nothing reads the index then.
|
|
51
|
+
async function reindexInspectorIfEnabled() {
|
|
52
|
+
let config;
|
|
53
|
+
try {
|
|
54
|
+
config = readConfig();
|
|
55
|
+
} catch {
|
|
56
|
+
return;
|
|
57
|
+
}
|
|
58
|
+
if (!isInspectorEnabled(config)) return;
|
|
59
|
+
try {
|
|
60
|
+
const plan = planIndex({});
|
|
61
|
+
const work = plan.missing.length + plan.stale.length + plan.gone.length;
|
|
62
|
+
if (work === 0) return;
|
|
63
|
+
process.stdout.write(`\n Skill Inspector on — reindexing ${work} changed skill(s)… `);
|
|
64
|
+
const out = await ensureIndex({ embedOpts: { globalConfig: config } });
|
|
65
|
+
const c = out.changed;
|
|
66
|
+
console.log(`done (${out.embedder}: +${c.added.length} ~${c.refreshed.length} -${c.removed.length}).`);
|
|
67
|
+
} catch (e) {
|
|
68
|
+
console.log(`\n (skill index refresh failed: ${e.message})`);
|
|
69
|
+
}
|
|
70
|
+
}
|
|
71
|
+
|
|
33
72
|
// ---------------------------------------------------------------------------
|
|
34
73
|
// apx skills add [<target>...] [--global] [--project]
|
|
35
74
|
// ---------------------------------------------------------------------------
|
|
@@ -65,6 +104,7 @@ export async function cmdSkillsAdd(args) {
|
|
|
65
104
|
}
|
|
66
105
|
console.log("\n Loaded by: Claude Code, Cursor, Codex (OpenAI), Antigravity, and skills.sh-compatible tools.");
|
|
67
106
|
console.log(" Activates automatically when working in a project with AGENTS.md or .apc/");
|
|
107
|
+
await reindexInspectorIfEnabled();
|
|
68
108
|
return;
|
|
69
109
|
}
|
|
70
110
|
|
|
@@ -93,6 +133,7 @@ export async function cmdSkillsAdd(args) {
|
|
|
93
133
|
console.log("");
|
|
94
134
|
for (const t of notes) console.log(` note: ${t.note}`);
|
|
95
135
|
}
|
|
136
|
+
await reindexInspectorIfEnabled();
|
|
96
137
|
}
|
|
97
138
|
|
|
98
139
|
// ---------------------------------------------------------------------------
|
|
@@ -154,6 +195,7 @@ export async function cmdSkillsSync(args) {
|
|
|
154
195
|
}
|
|
155
196
|
}
|
|
156
197
|
}
|
|
198
|
+
await reindexInspectorIfEnabled();
|
|
157
199
|
}
|
|
158
200
|
|
|
159
201
|
// ---------------------------------------------------------------------------
|
|
@@ -261,3 +303,215 @@ export async function cmdSkillsStatus() {
|
|
|
261
303
|
console.log("\n Tip: run `apx skills add` for an interactive install.");
|
|
262
304
|
console.log(" Claude Desktop has no project-file support (use apx-mcp instead).");
|
|
263
305
|
}
|
|
306
|
+
|
|
307
|
+
// ---------------------------------------------------------------------------
|
|
308
|
+
// apx skills index [--reset] [--force]
|
|
309
|
+
//
|
|
310
|
+
// Build the persistent vector index that powers the skill Inspector. Runs the
|
|
311
|
+
// configured embedding provider (defaults to local: ollama → tf fallback) over
|
|
312
|
+
// every skill's condensed description and writes ~/.apx/skills/.index.json.
|
|
313
|
+
// ---------------------------------------------------------------------------
|
|
314
|
+
|
|
315
|
+
function renderBar(done, total, width = 24) {
|
|
316
|
+
if (!Number.isFinite(total) || total <= 0) return "";
|
|
317
|
+
const ratio = Math.max(0, Math.min(1, done / total));
|
|
318
|
+
const filled = Math.round(ratio * width);
|
|
319
|
+
return "[" + "█".repeat(filled) + " ".repeat(width - filled) + "]";
|
|
320
|
+
}
|
|
321
|
+
|
|
322
|
+
export async function cmdSkillsIndex(args = {}) {
|
|
323
|
+
const reset = !!args?.flags?.reset;
|
|
324
|
+
const force = !!args?.flags?.force;
|
|
325
|
+
if (reset) clearIndex();
|
|
326
|
+
|
|
327
|
+
const config = readConfig();
|
|
328
|
+
const root = findApfRoot();
|
|
329
|
+
const projectPath = root || undefined;
|
|
330
|
+
|
|
331
|
+
const plan = planIndex({ projectPath });
|
|
332
|
+
if (plan.total === 0) {
|
|
333
|
+
console.log("(no skills available — install some first with `apx skills sync` or drop a SKILL.md in ~/.apx/skills/<slug>/)");
|
|
334
|
+
return;
|
|
335
|
+
}
|
|
336
|
+
|
|
337
|
+
const headline = force
|
|
338
|
+
? `Rebuilding index for ${plan.total} skills (force).`
|
|
339
|
+
: `Indexing ${plan.total} skills (${plan.existing.length} cached · ${plan.missing.length} new · ${plan.stale.length} stale · ${plan.gone.length} gone).`;
|
|
340
|
+
console.log(headline);
|
|
341
|
+
|
|
342
|
+
const t0 = Date.now();
|
|
343
|
+
let lastLine = "";
|
|
344
|
+
const out = await ensureIndex({
|
|
345
|
+
projectPath,
|
|
346
|
+
embedOpts: { globalConfig: config },
|
|
347
|
+
force,
|
|
348
|
+
onProgress: ({ done, total, slug, action }) => {
|
|
349
|
+
const bar = renderBar(done, total);
|
|
350
|
+
const tag = action.padEnd(9);
|
|
351
|
+
const line = `\r${bar} ${done}/${total} ${tag} ${slug}`.padEnd(lastLine.length, " ");
|
|
352
|
+
process.stdout.write(line);
|
|
353
|
+
lastLine = line;
|
|
354
|
+
},
|
|
355
|
+
});
|
|
356
|
+
|
|
357
|
+
const elapsedMs = Date.now() - t0;
|
|
358
|
+
process.stdout.write("\r" + " ".repeat(lastLine.length) + "\r");
|
|
359
|
+
|
|
360
|
+
const c = out.changed;
|
|
361
|
+
console.log(
|
|
362
|
+
`Done in ${(elapsedMs / 1000).toFixed(1)}s using ${out.embedder} (dim ${out.dim}).\n` +
|
|
363
|
+
` added: ${c.added.length}\n` +
|
|
364
|
+
` refreshed: ${c.refreshed.length}\n` +
|
|
365
|
+
` removed: ${c.removed.length}\n` +
|
|
366
|
+
` kept: ${c.kept.length}\n` +
|
|
367
|
+
` index: ${indexPath()}`
|
|
368
|
+
);
|
|
369
|
+
if (c.added.length || c.refreshed.length) {
|
|
370
|
+
const sample = [...c.added, ...c.refreshed].slice(0, 6).join(", ");
|
|
371
|
+
if (sample) console.log(` changes: ${sample}${(c.added.length + c.refreshed.length) > 6 ? ", …" : ""}`);
|
|
372
|
+
}
|
|
373
|
+
if (out.embedder === "tf") {
|
|
374
|
+
console.log(" note: using offline TF fallback (no embedding provider reachable). Configure one in config.memory.embeddings for better recall.");
|
|
375
|
+
}
|
|
376
|
+
}
|
|
377
|
+
|
|
378
|
+
// ---------------------------------------------------------------------------
|
|
379
|
+
// apx skills inspect <prompt>
|
|
380
|
+
//
|
|
381
|
+
// Show what the Inspector would inject for a given user prompt. Doesn't touch
|
|
382
|
+
// the model — pure middleware debug. Useful to tune thresholds and to see why
|
|
383
|
+
// a skill did or didn't fire.
|
|
384
|
+
// ---------------------------------------------------------------------------
|
|
385
|
+
|
|
386
|
+
export async function cmdSkillsInspect(args) {
|
|
387
|
+
const promptParts = args?._ || [];
|
|
388
|
+
const prompt = promptParts.join(" ").trim();
|
|
389
|
+
if (!prompt) {
|
|
390
|
+
console.error("usage: apx skills inspect \"<prompt text>\"");
|
|
391
|
+
process.exitCode = 2;
|
|
392
|
+
return;
|
|
393
|
+
}
|
|
394
|
+
|
|
395
|
+
const config = readConfig();
|
|
396
|
+
const root = findApfRoot();
|
|
397
|
+
const projectPath = root || undefined;
|
|
398
|
+
|
|
399
|
+
// Force the inspector on for this command even if config has it off — the
|
|
400
|
+
// operator is explicitly asking "what WOULD the inspector do?".
|
|
401
|
+
const probedConfig = structuredClone(config);
|
|
402
|
+
probedConfig.skills = probedConfig.skills || {};
|
|
403
|
+
probedConfig.skills.inspector = {
|
|
404
|
+
...INSPECTOR_DEFAULTS,
|
|
405
|
+
...(probedConfig.skills.inspector || {}),
|
|
406
|
+
enabled: true,
|
|
407
|
+
};
|
|
408
|
+
|
|
409
|
+
const out = await inspectPromptForSkills({
|
|
410
|
+
prompt,
|
|
411
|
+
projectPath,
|
|
412
|
+
globalConfig: probedConfig,
|
|
413
|
+
});
|
|
414
|
+
|
|
415
|
+
console.log(`prompt: ${prompt}`);
|
|
416
|
+
console.log(`embedder: ${out.trace.embedder || "(none)"}`);
|
|
417
|
+
console.log(`decision: ${summarizeTrace(out.trace)}`);
|
|
418
|
+
if (out.trace.scored?.length) {
|
|
419
|
+
console.log("scores:");
|
|
420
|
+
for (const s of out.trace.scored) console.log(` ${s.sim.toFixed(3)} ${s.slug}`);
|
|
421
|
+
}
|
|
422
|
+
if (out.contextNote) {
|
|
423
|
+
console.log("");
|
|
424
|
+
console.log("--- contextNote that would be injected ---");
|
|
425
|
+
console.log(out.contextNote);
|
|
426
|
+
console.log("--- end ---");
|
|
427
|
+
}
|
|
428
|
+
}
|
|
429
|
+
|
|
430
|
+
// ---------------------------------------------------------------------------
|
|
431
|
+
// apx skills inspector [enable|disable|status|set <key> <value>]
|
|
432
|
+
//
|
|
433
|
+
// Manage config.skills.inspector. All keys live under that namespace; this
|
|
434
|
+
// command is a thin shortcut so you don't have to remember the path.
|
|
435
|
+
// ---------------------------------------------------------------------------
|
|
436
|
+
|
|
437
|
+
const KNOWN_INSPECTOR_KEYS = Object.keys(INSPECTOR_DEFAULTS);
|
|
438
|
+
|
|
439
|
+
function ensureInspectorBlock(cfg) {
|
|
440
|
+
cfg.skills = cfg.skills || {};
|
|
441
|
+
cfg.skills.inspector = { ...INSPECTOR_DEFAULTS, ...(cfg.skills.inspector || {}) };
|
|
442
|
+
return cfg;
|
|
443
|
+
}
|
|
444
|
+
|
|
445
|
+
function printInspectorStatus(cfg) {
|
|
446
|
+
const insp = cfg.skills?.inspector || {};
|
|
447
|
+
const merged = { ...INSPECTOR_DEFAULTS, ...insp };
|
|
448
|
+
console.log(`Skill Inspector: ${merged.enabled ? "ENABLED" : "disabled"}`);
|
|
449
|
+
for (const k of KNOWN_INSPECTOR_KEYS) {
|
|
450
|
+
if (k === "enabled") continue;
|
|
451
|
+
console.log(` ${k.padEnd(16)} ${merged[k]}`);
|
|
452
|
+
}
|
|
453
|
+
const idx = readIndex();
|
|
454
|
+
const count = Object.keys(idx.items || {}).length;
|
|
455
|
+
console.log("");
|
|
456
|
+
console.log(`Index: ${count} skills (${idx.embedder || "—"}, dim ${idx.dim || "—"})`);
|
|
457
|
+
console.log(`File: ${indexPath()}`);
|
|
458
|
+
}
|
|
459
|
+
|
|
460
|
+
export async function cmdSkillsInspector(args) {
|
|
461
|
+
const sub = (args?._ || [])[0];
|
|
462
|
+
const cfg = readConfig();
|
|
463
|
+
|
|
464
|
+
if (!sub || sub === "status") {
|
|
465
|
+
printInspectorStatus(cfg);
|
|
466
|
+
return;
|
|
467
|
+
}
|
|
468
|
+
if (sub === "enable" || sub === "on") {
|
|
469
|
+
ensureInspectorBlock(cfg).skills.inspector.enabled = true;
|
|
470
|
+
writeConfig(cfg);
|
|
471
|
+
console.log("Skill Inspector ENABLED. The catalog-wide hint block will be suppressed; per-turn RAG decides what skills go into context.");
|
|
472
|
+
console.log("Tip: run `apx skills index` once so the inspector has cached vectors to score against.");
|
|
473
|
+
return;
|
|
474
|
+
}
|
|
475
|
+
if (sub === "disable" || sub === "off") {
|
|
476
|
+
ensureInspectorBlock(cfg).skills.inspector.enabled = false;
|
|
477
|
+
writeConfig(cfg);
|
|
478
|
+
console.log("Skill Inspector disabled. Falling back to the legacy slug hint + passive RAG nudge.");
|
|
479
|
+
return;
|
|
480
|
+
}
|
|
481
|
+
if (sub === "set") {
|
|
482
|
+
const key = args._[1];
|
|
483
|
+
const value = args._[2];
|
|
484
|
+
if (!key || value === undefined) {
|
|
485
|
+
console.error("usage: apx skills inspector set <key> <value>");
|
|
486
|
+
console.error(`keys: ${KNOWN_INSPECTOR_KEYS.join(", ")}`);
|
|
487
|
+
process.exitCode = 2;
|
|
488
|
+
return;
|
|
489
|
+
}
|
|
490
|
+
if (!KNOWN_INSPECTOR_KEYS.includes(key)) {
|
|
491
|
+
console.error(`unknown key "${key}". Known: ${KNOWN_INSPECTOR_KEYS.join(", ")}`);
|
|
492
|
+
process.exitCode = 2;
|
|
493
|
+
return;
|
|
494
|
+
}
|
|
495
|
+
ensureInspectorBlock(cfg);
|
|
496
|
+
const def = INSPECTOR_DEFAULTS[key];
|
|
497
|
+
let coerced = value;
|
|
498
|
+
if (typeof def === "boolean") coerced = value === "true" || value === "1" || value === "on";
|
|
499
|
+
else if (typeof def === "number") {
|
|
500
|
+
const n = Number(value);
|
|
501
|
+
if (!Number.isFinite(n)) {
|
|
502
|
+
console.error(`value for "${key}" must be a number; got "${value}"`);
|
|
503
|
+
process.exitCode = 2;
|
|
504
|
+
return;
|
|
505
|
+
}
|
|
506
|
+
coerced = n;
|
|
507
|
+
}
|
|
508
|
+
cfg.skills.inspector[key] = coerced;
|
|
509
|
+
writeConfig(cfg);
|
|
510
|
+
console.log(`skills.inspector.${key} = ${coerced}`);
|
|
511
|
+
return;
|
|
512
|
+
}
|
|
513
|
+
|
|
514
|
+
console.error(`unknown inspector subcommand: ${sub}`);
|
|
515
|
+
console.error("usage: apx skills inspector [status|enable|disable|set <key> <value>]");
|
|
516
|
+
process.exitCode = 2;
|
|
517
|
+
}
|
|
@@ -100,7 +100,7 @@ import {
|
|
|
100
100
|
import { cmdPluginsList, cmdPluginStatus } from "./commands/plugins.js";
|
|
101
101
|
import { cmdDesktopStart, cmdDesktopStop, cmdDesktopStatus, cmdDesktopInstall, cmdDesktopUninstall } from "./commands/desktop.js";
|
|
102
102
|
import { cmdVoiceSay, cmdVoiceListen, cmdVoiceProviders } from "./commands/voice.js";
|
|
103
|
-
import { cmdSkillsAdd, cmdSkillsList, cmdSkillsStatus, cmdSkillsSync } from "./commands/skills.js";
|
|
103
|
+
import { cmdSkillsAdd, cmdSkillsList, cmdSkillsStatus, cmdSkillsSync, cmdSkillsIndex, cmdSkillsInspect, cmdSkillsInspector } from "./commands/skills.js";
|
|
104
104
|
import { cmdIdentity } from "./commands/identity.js";
|
|
105
105
|
import { cmdCommandList, cmdCommandShow } from "./commands/command.js";
|
|
106
106
|
import { cmdUpdate } from "./commands/update.js";
|
|
@@ -110,6 +110,7 @@ import { cmdModel } from "./commands/model.js";
|
|
|
110
110
|
import { cmdPair, cmdPairWeb, cmdPairList, cmdPairRevoke } from "./commands/pair.js";
|
|
111
111
|
import { checkForUpdate } from "#core/update-check.js";
|
|
112
112
|
import { mascot } from "#core/mascot.js";
|
|
113
|
+
import { apxHeader, apxBanner } from "./branding.js";
|
|
113
114
|
import {
|
|
114
115
|
cmdRoutineList,
|
|
115
116
|
cmdRoutineGet,
|
|
@@ -1350,12 +1351,23 @@ const HELP_TOPICS = new Map(Object.entries({
|
|
|
1350
1351
|
skills: topic({
|
|
1351
1352
|
title: "apx skills",
|
|
1352
1353
|
summary: "Install and inspect APX skill files for IDEs and agent tools.",
|
|
1353
|
-
usage: [
|
|
1354
|
+
usage: [
|
|
1355
|
+
"apx skills [add] [targets] [--global]",
|
|
1356
|
+
"apx skills sync",
|
|
1357
|
+
"apx skills list",
|
|
1358
|
+
"apx skills status",
|
|
1359
|
+
"apx skills index [--reset] [--force]",
|
|
1360
|
+
"apx skills inspect \"<prompt>\"",
|
|
1361
|
+
"apx skills inspector [status|enable|disable|set <key> <value>]",
|
|
1362
|
+
],
|
|
1354
1363
|
commands: [
|
|
1355
1364
|
["add [targets]", "Install APX skills into selected targets."],
|
|
1356
1365
|
["sync | refresh", "Re-install every bundled skill to every global skill dir (idempotent)."],
|
|
1357
1366
|
["list | ls", "List skills installed in this project's .apc/skills/."],
|
|
1358
1367
|
["status", "Show which bundled skills are present in each global dir."],
|
|
1368
|
+
["index", "Build/refresh the local RAG vector index used by the Skill Inspector."],
|
|
1369
|
+
["inspect", "Show which skills the Inspector would surface for a given prompt (debug)."],
|
|
1370
|
+
["inspector", "Toggle and tune the Skill Inspector (per-turn skill RAG middleware)."],
|
|
1359
1371
|
],
|
|
1360
1372
|
examples: [
|
|
1361
1373
|
"apx skills add claude-code cursor",
|
|
@@ -1403,6 +1415,40 @@ const HELP_TOPICS = new Map(Object.entries({
|
|
|
1403
1415
|
usage: ["apx skills status"],
|
|
1404
1416
|
examples: ["apx skills status"],
|
|
1405
1417
|
}),
|
|
1418
|
+
"skills index": topic({
|
|
1419
|
+
title: "apx skills index",
|
|
1420
|
+
summary:
|
|
1421
|
+
"Build or refresh the local vector index that powers the Skill Inspector. Embeds each skill's condensed description with the configured embeddings provider (defaults to local: ollama → tf fallback). Idempotent: skills with unchanged file+description are kept. Use --force to re-embed everything; --reset to also delete the on-disk index first.",
|
|
1422
|
+
usage: ["apx skills index [--reset] [--force]"],
|
|
1423
|
+
options: [
|
|
1424
|
+
["--force", "Re-embed every skill, ignoring cached vectors."],
|
|
1425
|
+
["--reset", "Delete the index file before rebuilding."],
|
|
1426
|
+
],
|
|
1427
|
+
examples: ["apx skills index", "apx skills index --force", "apx skills index --reset"],
|
|
1428
|
+
}),
|
|
1429
|
+
"skills inspect": topic({
|
|
1430
|
+
title: "apx skills inspect",
|
|
1431
|
+
summary:
|
|
1432
|
+
"Dry-run the Skill Inspector against a prompt. Shows top similarity scores, which skill (if any) would be loaded inline, which would be hinted, and the actual contextNote that would be injected into the next turn's system prompt. The model is NOT called.",
|
|
1433
|
+
usage: ["apx skills inspect \"<prompt text>\""],
|
|
1434
|
+
examples: [
|
|
1435
|
+
"apx skills inspect \"crear un video promocional\"",
|
|
1436
|
+
"apx skills inspect \"profile the slow endpoint\"",
|
|
1437
|
+
],
|
|
1438
|
+
}),
|
|
1439
|
+
"skills inspector": topic({
|
|
1440
|
+
title: "apx skills inspector",
|
|
1441
|
+
summary:
|
|
1442
|
+
"Toggle and tune the Skill Inspector (per-turn skill RAG). When ON: the static slug-dump in the system prompt is suppressed and a local RAG picks 0–N skills per turn — loading the body of high-confidence matches, hinting mid-confidence ones, injecting nothing below threshold. When OFF: legacy behaviour (full slug list + passive suggestion). Opt-in test feature.",
|
|
1443
|
+
usage: ["apx skills inspector [status|enable|disable|set <key> <value>]"],
|
|
1444
|
+
examples: [
|
|
1445
|
+
"apx skills inspector enable",
|
|
1446
|
+
"apx skills inspector disable",
|
|
1447
|
+
"apx skills inspector status",
|
|
1448
|
+
"apx skills inspector set load_threshold 0.5",
|
|
1449
|
+
"apx skills inspector set max_loaded 2",
|
|
1450
|
+
],
|
|
1451
|
+
}),
|
|
1406
1452
|
plugins: topic({
|
|
1407
1453
|
title: "apx plugins",
|
|
1408
1454
|
summary: "Inspect loaded APX daemon plugins.",
|
|
@@ -2530,6 +2576,9 @@ async function dispatch(cmd, rest) {
|
|
|
2530
2576
|
else if (sub === "list" || sub === "ls") await cmdSkillsList(a);
|
|
2531
2577
|
else if (sub === "status") await cmdSkillsStatus();
|
|
2532
2578
|
else if (sub === "sync" || sub === "refresh") await cmdSkillsSync(a);
|
|
2579
|
+
else if (sub === "index") await cmdSkillsIndex(a);
|
|
2580
|
+
else if (sub === "inspect") await cmdSkillsInspect(a);
|
|
2581
|
+
else if (sub === "inspector") await cmdSkillsInspector(a);
|
|
2533
2582
|
else die(`unknown skills subcommand: ${sub}`);
|
|
2534
2583
|
break;
|
|
2535
2584
|
}
|
|
@@ -2583,8 +2632,41 @@ async function dispatch(cmd, rest) {
|
|
|
2583
2632
|
}
|
|
2584
2633
|
|
|
2585
2634
|
const [topCmd, ...topRest] = argv;
|
|
2635
|
+
|
|
2636
|
+
// ── CLI branding ────────────────────────────────────────────────────────────
|
|
2637
|
+
// Every command prints an "APX CLI · vX · <command>" mark to stderr (so stdout
|
|
2638
|
+
// pipes stay clean). Two exceptions:
|
|
2639
|
+
// - SELF_BRANDED: commands that already render their own logo/mascot/status
|
|
2640
|
+
// block — re-stamping them would double up.
|
|
2641
|
+
// - BANNERED: branding-heavy moments that get the big ASCII wordmark instead
|
|
2642
|
+
// of the compact line.
|
|
2643
|
+
// Suppress everything with APX_QUIET=1 / APX_NO_BANNER=1 (see branding.js).
|
|
2644
|
+
const SELF_BRANDED = new Set([
|
|
2645
|
+
"status", "setup", "install", "daemon", "update", "upgrade", "help",
|
|
2646
|
+
]);
|
|
2647
|
+
const BANNERED = new Set(["init"]);
|
|
2648
|
+
|
|
2649
|
+
function brandFor(cmd, rest) {
|
|
2650
|
+
if (SELF_BRANDED.has(cmd)) return;
|
|
2651
|
+
// Subtitle = the command path only (cmd + leading subcommand tokens), never
|
|
2652
|
+
// free-form args. Stop at the first token that looks like an argument: a flag,
|
|
2653
|
+
// something with spaces (a quoted prompt), or anything long. So
|
|
2654
|
+
// `skills inspector status` shows fully, but `exec "long prompt…"` shows just
|
|
2655
|
+
// `exec`.
|
|
2656
|
+
const path = [cmd];
|
|
2657
|
+
for (const tok of rest) {
|
|
2658
|
+
if (!tok || tok.startsWith("-") || /\s/.test(tok) || tok.length > 24) break;
|
|
2659
|
+
path.push(tok);
|
|
2660
|
+
if (path.length >= 3) break;
|
|
2661
|
+
}
|
|
2662
|
+
const subtitle = path.join(" ");
|
|
2663
|
+
if (BANNERED.has(cmd)) apxBanner(VERSION, subtitle);
|
|
2664
|
+
else apxHeader(VERSION, subtitle);
|
|
2665
|
+
}
|
|
2666
|
+
|
|
2586
2667
|
(async () => {
|
|
2587
2668
|
try {
|
|
2669
|
+
brandFor(topCmd, topRest);
|
|
2588
2670
|
await dispatch(topCmd, topRest);
|
|
2589
2671
|
checkForUpdate(VERSION);
|
|
2590
2672
|
} catch (err) {
|