@ax-llm/ax 25.4.1 → 25.4.2
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 +29 -0
- package/cli/index.mjs +70 -317
- package/package.json +1 -1
- package/scripts/postinstall.mjs +16 -202
- package/scripts/skill-bundles.mjs +70 -0
- package/scripts/skill-config.mjs +59 -0
- package/scripts/skill-install.mjs +123 -0
- package/skills/ax-agent-context.md +1 -1
- package/skills/ax-agent-memory-skills.md +1 -1
- package/skills/ax-agent-observability.md +1 -1
- package/skills/ax-agent-optimize.md +1 -1
- package/skills/ax-agent-rlm.md +1 -1
- package/skills/ax-agent.md +1 -1
- package/skills/ax-ai.md +1 -1
- package/skills/ax-audio.md +1 -1
- package/skills/ax-flow.md +1 -1
- package/skills/ax-gen.md +1 -1
- package/skills/ax-gepa.md +1 -1
- package/skills/ax-llm.md +46 -353
- package/skills/ax-mcp.md +1 -1
- package/skills/ax-playbook.md +1 -1
- package/skills/ax-refine.md +1 -1
- package/skills/ax-signature.md +1 -1
- package/skills/ax-typesafe.md +1 -1
- package/skills/references/quickstart.md +354 -0
|
@@ -0,0 +1,70 @@
|
|
|
1
|
+
import { readdirSync, readFileSync } from 'node:fs';
|
|
2
|
+
import { join } from 'node:path';
|
|
3
|
+
|
|
4
|
+
export function parseSkillFrontmatter(markdown) {
|
|
5
|
+
const text = markdown.match(/^---\r?\n([\s\S]*?)\r?\n---(?:\r?\n|$)/)?.[1];
|
|
6
|
+
if (!text) return {};
|
|
7
|
+
const field = (key) =>
|
|
8
|
+
text.match(new RegExp(`^${key}:\\s*["']?(.+?)["']?\\s*$`, 'm'))?.[1];
|
|
9
|
+
return {
|
|
10
|
+
name: field('name'),
|
|
11
|
+
description: field('description'),
|
|
12
|
+
version: field('version'),
|
|
13
|
+
};
|
|
14
|
+
}
|
|
15
|
+
|
|
16
|
+
export function stripSkillFrontmatter(markdown) {
|
|
17
|
+
return markdown.replace(/^---\r?\n[\s\S]*?\r?\n---(?:\r?\n|$)(?:\r?\n)*/, '');
|
|
18
|
+
}
|
|
19
|
+
|
|
20
|
+
// The source docs remain independently installable. The entry point bundles
|
|
21
|
+
// those same docs as ordinary references, so only one skill needs registering.
|
|
22
|
+
export function readTypeScriptSkillBundles(skillsRoot, version) {
|
|
23
|
+
const sources = readdirSync(skillsRoot)
|
|
24
|
+
.filter((file) => file.endsWith('.md'))
|
|
25
|
+
.sort()
|
|
26
|
+
.map((file) => {
|
|
27
|
+
const content = readFileSync(join(skillsRoot, file), 'utf8').replace(
|
|
28
|
+
/^version:\s*["']?__VERSION__["']?/m,
|
|
29
|
+
`version: "${version}"`
|
|
30
|
+
);
|
|
31
|
+
const metadata = parseSkillFrontmatter(content);
|
|
32
|
+
if (!metadata.name || !metadata.description) {
|
|
33
|
+
throw new Error(`${file} is missing skill name or description`);
|
|
34
|
+
}
|
|
35
|
+
return { ...metadata, file, content };
|
|
36
|
+
});
|
|
37
|
+
const byFile = new Map(sources.map((skill) => [skill.file, skill]));
|
|
38
|
+
return sources.map((skill) => {
|
|
39
|
+
const files = {};
|
|
40
|
+
const addReference = (file) => {
|
|
41
|
+
const key = `references/${file}`;
|
|
42
|
+
if (files[key]) return;
|
|
43
|
+
const source = byFile.get(file);
|
|
44
|
+
if (!source) throw new Error(`Missing skill reference: ${file}`);
|
|
45
|
+
files[key] = stripSkillFrontmatter(source.content);
|
|
46
|
+
for (const match of files[key].matchAll(
|
|
47
|
+
/\]\((ax-[\w-]+\.md)(?:#[^)]*)?\)/g
|
|
48
|
+
)) {
|
|
49
|
+
addReference(match[1]);
|
|
50
|
+
}
|
|
51
|
+
};
|
|
52
|
+
const content = skill.content.replace(
|
|
53
|
+
/\]\((ax-[\w-]+\.md)((?:#[^)]*)?)\)/g,
|
|
54
|
+
(_, file, anchor) => {
|
|
55
|
+
addReference(file);
|
|
56
|
+
return `](references/${file}${anchor})`;
|
|
57
|
+
}
|
|
58
|
+
);
|
|
59
|
+
if (skill.name === 'ax-llm') {
|
|
60
|
+
for (const source of sources) {
|
|
61
|
+
if (source.name !== skill.name) addReference(source.file);
|
|
62
|
+
}
|
|
63
|
+
files['references/quickstart.md'] = readFileSync(
|
|
64
|
+
join(skillsRoot, 'references', 'quickstart.md'),
|
|
65
|
+
'utf8'
|
|
66
|
+
);
|
|
67
|
+
}
|
|
68
|
+
return { ...skill, content, files: { 'SKILL.md': content, ...files } };
|
|
69
|
+
});
|
|
70
|
+
}
|
|
@@ -0,0 +1,59 @@
|
|
|
1
|
+
import { readFileSync, writeFileSync } from 'node:fs';
|
|
2
|
+
import { join } from 'node:path';
|
|
3
|
+
|
|
4
|
+
function isObject(value) {
|
|
5
|
+
return value !== null && typeof value === 'object' && !Array.isArray(value);
|
|
6
|
+
}
|
|
7
|
+
|
|
8
|
+
function readProjectConfig(projectRoot) {
|
|
9
|
+
const file = join(projectRoot, 'package.json');
|
|
10
|
+
const source = readFileSync(file, 'utf8');
|
|
11
|
+
const config = JSON.parse(source);
|
|
12
|
+
if (
|
|
13
|
+
!isObject(config) ||
|
|
14
|
+
('ax' in config && !isObject(config.ax)) ||
|
|
15
|
+
(config.ax && 'skills' in config.ax && !isObject(config.ax.skills)) ||
|
|
16
|
+
(config.ax?.skills &&
|
|
17
|
+
'autoInstall' in config.ax.skills &&
|
|
18
|
+
typeof config.ax.skills.autoInstall !== 'boolean')
|
|
19
|
+
)
|
|
20
|
+
throw new Error(
|
|
21
|
+
'Expected package.json ax.skills.autoInstall to be a boolean within ax and skills objects.'
|
|
22
|
+
);
|
|
23
|
+
return { file, source, config };
|
|
24
|
+
}
|
|
25
|
+
|
|
26
|
+
export function autoSkillInstallEnabled(projectRoot) {
|
|
27
|
+
try {
|
|
28
|
+
return (
|
|
29
|
+
readProjectConfig(projectRoot).config.ax?.skills?.autoInstall !== false
|
|
30
|
+
);
|
|
31
|
+
} catch (error) {
|
|
32
|
+
if (error.code === 'ENOENT') return true;
|
|
33
|
+
throw error;
|
|
34
|
+
}
|
|
35
|
+
}
|
|
36
|
+
|
|
37
|
+
export function setAutoSkillInstall(projectRoot, enabled) {
|
|
38
|
+
let project;
|
|
39
|
+
try {
|
|
40
|
+
project = readProjectConfig(projectRoot);
|
|
41
|
+
} catch (error) {
|
|
42
|
+
if (error.code === 'ENOENT')
|
|
43
|
+
throw new Error(
|
|
44
|
+
'No package.json found. Run this command from your project root.'
|
|
45
|
+
);
|
|
46
|
+
throw error;
|
|
47
|
+
}
|
|
48
|
+
const { file, source, config } = project;
|
|
49
|
+
config.ax ??= {};
|
|
50
|
+
config.ax.skills ??= {};
|
|
51
|
+
config.ax.skills.autoInstall = enabled;
|
|
52
|
+
const indent = source.match(/^[\t ]+(?=")/m)?.[0] ?? 2;
|
|
53
|
+
const newline = source.includes('\r\n') ? '\r\n' : '\n';
|
|
54
|
+
const content = JSON.stringify(config, null, indent).replaceAll(
|
|
55
|
+
'\n',
|
|
56
|
+
newline
|
|
57
|
+
);
|
|
58
|
+
writeFileSync(file, content + (source.endsWith('\n') ? newline : ''), 'utf8');
|
|
59
|
+
}
|
|
@@ -0,0 +1,123 @@
|
|
|
1
|
+
import {
|
|
2
|
+
existsSync,
|
|
3
|
+
mkdirSync,
|
|
4
|
+
readdirSync,
|
|
5
|
+
readFileSync,
|
|
6
|
+
rmdirSync,
|
|
7
|
+
rmSync,
|
|
8
|
+
writeFileSync,
|
|
9
|
+
} from 'node:fs';
|
|
10
|
+
import { dirname, join } from 'node:path';
|
|
11
|
+
import {
|
|
12
|
+
parseSkillFrontmatter,
|
|
13
|
+
readTypeScriptSkillBundles,
|
|
14
|
+
} from './skill-bundles.mjs';
|
|
15
|
+
|
|
16
|
+
function packageSkills(packageRoot) {
|
|
17
|
+
const { version } = JSON.parse(
|
|
18
|
+
readFileSync(join(packageRoot, 'package.json'), 'utf8')
|
|
19
|
+
);
|
|
20
|
+
return readTypeScriptSkillBundles(join(packageRoot, 'skills'), version);
|
|
21
|
+
}
|
|
22
|
+
|
|
23
|
+
function compareVersions(a, b) {
|
|
24
|
+
const parts = (value) =>
|
|
25
|
+
value
|
|
26
|
+
.match(/^(\d+)\.(\d+)\.(\d+)/)
|
|
27
|
+
?.slice(1)
|
|
28
|
+
.map(Number) ?? [0, 0, 0];
|
|
29
|
+
const left = parts(a);
|
|
30
|
+
const right = parts(b);
|
|
31
|
+
for (let i = 0; i < 3; i++) {
|
|
32
|
+
if (left[i] !== right[i]) return left[i] > right[i] ? 1 : -1;
|
|
33
|
+
}
|
|
34
|
+
return 0;
|
|
35
|
+
}
|
|
36
|
+
|
|
37
|
+
export function installSkills(
|
|
38
|
+
packageRoot,
|
|
39
|
+
projectRoot,
|
|
40
|
+
{ all = false, names = [], force = false, upgradeInstalled = false } = {}
|
|
41
|
+
) {
|
|
42
|
+
const skills = packageSkills(packageRoot);
|
|
43
|
+
const selectedNames = all
|
|
44
|
+
? skills.map((skill) => skill.name)
|
|
45
|
+
: names.length
|
|
46
|
+
? names
|
|
47
|
+
: ['ax-llm'];
|
|
48
|
+
if (upgradeInstalled) {
|
|
49
|
+
for (const skill of skills) {
|
|
50
|
+
if (
|
|
51
|
+
existsSync(
|
|
52
|
+
join(projectRoot, '.claude', 'skills', skill.name, 'SKILL.md')
|
|
53
|
+
) &&
|
|
54
|
+
!selectedNames.includes(skill.name)
|
|
55
|
+
) {
|
|
56
|
+
selectedNames.push(skill.name);
|
|
57
|
+
}
|
|
58
|
+
}
|
|
59
|
+
}
|
|
60
|
+
for (const name of selectedNames) {
|
|
61
|
+
if (!skills.some((skill) => skill.name === name))
|
|
62
|
+
throw new Error(`Unknown Ax skill: ${name}`);
|
|
63
|
+
}
|
|
64
|
+
const results = [];
|
|
65
|
+
// Keep the default entry point ahead of optional upgrades, so a broken
|
|
66
|
+
// specialist folder cannot prevent the main capability index installing.
|
|
67
|
+
for (const name of new Set(selectedNames)) {
|
|
68
|
+
const skill = skills.find((entry) => entry.name === name);
|
|
69
|
+
const dir = join(projectRoot, '.claude', 'skills', skill.name);
|
|
70
|
+
const target = join(dir, 'SKILL.md');
|
|
71
|
+
const installed = existsSync(target)
|
|
72
|
+
? parseSkillFrontmatter(readFileSync(target, 'utf8')).version
|
|
73
|
+
: undefined;
|
|
74
|
+
const comparison = installed
|
|
75
|
+
? compareVersions(skill.version, installed)
|
|
76
|
+
: 1;
|
|
77
|
+
// Refresh equal-version legacy installs which predate bundled references.
|
|
78
|
+
const missingFiles = Object.keys(skill.files).some(
|
|
79
|
+
(file) => !existsSync(join(dir, file))
|
|
80
|
+
);
|
|
81
|
+
if (!force && (comparison < 0 || (comparison === 0 && !missingFiles)))
|
|
82
|
+
continue;
|
|
83
|
+
for (const [file, content] of Object.entries(skill.files)) {
|
|
84
|
+
if (file === 'SKILL.md') continue;
|
|
85
|
+
const dest = join(dir, file);
|
|
86
|
+
mkdirSync(dirname(dest), { recursive: true });
|
|
87
|
+
writeFileSync(dest, content, 'utf8');
|
|
88
|
+
}
|
|
89
|
+
// Register the skill only after every guide was successfully written.
|
|
90
|
+
mkdirSync(dir, { recursive: true });
|
|
91
|
+
writeFileSync(target, skill.content, 'utf8');
|
|
92
|
+
results.push(skill.name);
|
|
93
|
+
}
|
|
94
|
+
return results;
|
|
95
|
+
}
|
|
96
|
+
|
|
97
|
+
// Remove only package-defined files, preserving unrelated files in skill folders.
|
|
98
|
+
export function removeSkills(packageRoot, projectRoot) {
|
|
99
|
+
const skills = packageSkills(packageRoot);
|
|
100
|
+
const base = join(projectRoot, '.claude', 'skills');
|
|
101
|
+
let removed = 0;
|
|
102
|
+
for (const skill of skills) {
|
|
103
|
+
const dir = join(base, skill.name);
|
|
104
|
+
if (existsSync(join(dir, 'SKILL.md'))) removed++;
|
|
105
|
+
for (const file of Object.keys(skill.files))
|
|
106
|
+
rmSync(join(dir, file), { force: true });
|
|
107
|
+
for (const folder of ['references', '']) {
|
|
108
|
+
try {
|
|
109
|
+
rmdirSync(join(dir, folder));
|
|
110
|
+
} catch {
|
|
111
|
+
/* Keep nonempty folders. */
|
|
112
|
+
}
|
|
113
|
+
}
|
|
114
|
+
}
|
|
115
|
+
const legacy = join(base, 'ax');
|
|
116
|
+
if (existsSync(legacy)) {
|
|
117
|
+
for (const file of readdirSync(legacy)) {
|
|
118
|
+
if (skills.some((skill) => skill.file === file))
|
|
119
|
+
rmSync(join(legacy, file), { force: true });
|
|
120
|
+
}
|
|
121
|
+
}
|
|
122
|
+
return removed;
|
|
123
|
+
}
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
2
|
name: ax-agent-context
|
|
3
3
|
description: This skill helps an LLM pick the right AxAgent context tool for a job - contextMap for recurring corpora, contextPolicy presets for within-run trajectory compaction, agent.optimize for offline GEPA instruction/demo tuning, agent.playbook for an evolving context playbook (offline evolve + online update), and recall/memories + skills for per-turn retrieval. Use when the user asks "which context feature should I use", confuses contextMap with contextPolicy or memory, or wants a decision guide for long-context agents. For contextPolicy/contextMap codegen use ax-agent-rlm; for recall/skills use ax-agent-memory-skills; for agent.optimize or agent.playbook use ax-agent-optimize.
|
|
4
|
-
version: "25.4.
|
|
4
|
+
version: "25.4.2"
|
|
5
5
|
---
|
|
6
6
|
|
|
7
7
|
# AxAgent Context Selection (@ax-llm/ax)
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
2
|
name: ax-agent-memory-skills
|
|
3
3
|
description: This skill helps an LLM generate correct AxAgent memory retrieval, context-map, and dynamic skill-loading code using @ax-llm/ax. Use when the user asks about contextMap, AxAgentContextMap, onMemoriesSearch, memoriesCatalog, recall(...), inputs.memories, onLoadedMemories, onUsedMemories, onSkillsSearch, skillsCatalog, AxAgentCatalogSkill, discover({ skills }), onLoadedSkills, onUsedSkills, preloaded skills, preloading memories at forward time, relevanceRanking hints, loaded memory/skill IDs, or carrying memories across forward() calls.
|
|
4
|
-
version: "25.4.
|
|
4
|
+
version: "25.4.2"
|
|
5
5
|
---
|
|
6
6
|
|
|
7
7
|
# AxAgent Memory And Skills Rules (@ax-llm/ax)
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
2
|
name: ax-agent-observability
|
|
3
3
|
description: This skill helps an LLM generate correct AxAgent observability code using @ax-llm/ax. Use when the user asks about axGlobals.onUsage, usageContext, centralized or multi-tenant usage accounting, actorTurnCallback, onContextEvent, agentStatusCallback, onFunctionCall, reportSuccess, reportFailure, getChatLog(), getUsage(), resetUsage(), debug traces, progress updates, or telemetry for AxAgent runs.
|
|
4
|
-
version: "25.4.
|
|
4
|
+
version: "25.4.2"
|
|
5
5
|
---
|
|
6
6
|
|
|
7
7
|
# AxAgent Observability Rules (@ax-llm/ax)
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
2
|
name: ax-agent-optimize
|
|
3
3
|
description: This skill helps an LLM generate correct AxAgent tuning and evaluation code using @ax-llm/ax. Use when the user asks about agent.optimize(...), judgeOptions, eval datasets, optimization targets, saved optimizedProgram artifacts, or agent optimization guidance.
|
|
4
|
-
version: "25.4.
|
|
4
|
+
version: "25.4.2"
|
|
5
5
|
---
|
|
6
6
|
|
|
7
7
|
# AxAgent Optimize Codegen Rules (@ax-llm/ax)
|
package/skills/ax-agent-rlm.md
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
2
|
name: ax-agent-rlm
|
|
3
3
|
description: This skill helps an LLM generate correct AxAgent RLM/runtime code using @ax-llm/ax. Use when the user asks about RLM code execution, AxJSRuntime, contextFields, contextPolicy, liveRuntimeState, promptLevel, stage prompt controls, executorModelPolicy, maxRuntimeChars, agent.test(...), llmQuery(...), recursionOptions, or long-running agent runtime behavior.
|
|
4
|
-
version: "25.4.
|
|
4
|
+
version: "25.4.2"
|
|
5
5
|
---
|
|
6
6
|
|
|
7
7
|
# AxAgent RLM Runtime Rules (@ax-llm/ax)
|
package/skills/ax-agent.md
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
2
|
name: ax-agent
|
|
3
3
|
description: This skill helps an LLM generate correct core AxAgent code using @ax-llm/ax. Use when the user asks about agent(), child agents, namespaced functions, discovery mode, clarification, bubbleErrors, host-side final/clarification protocol, or ordinary agent runtime behavior. For MCP clients, native runtime modules, subscriptions, tasks, or authentication use ax-mcp alongside this skill. For RLM/code-runtime work use ax-agent-rlm; for callbacks and telemetry use ax-agent-observability; for recall/memory/skill loading use ax-agent-memory-skills; for agent.optimize(...) use ax-agent-optimize.
|
|
4
|
-
version: "25.4.
|
|
4
|
+
version: "25.4.2"
|
|
5
5
|
---
|
|
6
6
|
|
|
7
7
|
# AxAgent Codegen Rules (@ax-llm/ax)
|
package/skills/ax-ai.md
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
2
|
name: ax-ai
|
|
3
3
|
description: This skill helps an LLM generate correct AI provider setup and configuration code using @ax-llm/ax. Use when the user asks about ai(), providers, models, routing, adaptive balancing, presets, embeddings, batch audio with ai.transcribe() or ai.speak(), extended thinking, context caching, or mentions OpenAI/Anthropic/Google/Azure/DeepSeek/Meta/Mistral/Cohere/Reka/Grok/Typesafe/Jev with @ax-llm/ax.
|
|
4
|
-
version: "25.4.
|
|
4
|
+
version: "25.4.2"
|
|
5
5
|
---
|
|
6
6
|
|
|
7
7
|
# AI Provider Codegen Rules (@ax-llm/ax)
|
package/skills/ax-audio.md
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
2
|
name: ax-audio
|
|
3
3
|
description: This skill helps an LLM generate correct audio code with @ax-llm/ax. Use when the user asks about ai.transcribe(), ai.speak(), signature audio inputs or outputs, agent audio behavior, .chat() conversational audio, OpenAI audio or realtime models, Gemini Live native audio, Grok Voice Agent models, voices, formats, transcripts, or how audio fits with structured outputs.
|
|
4
|
-
version: "25.4.
|
|
4
|
+
version: "25.4.2"
|
|
5
5
|
---
|
|
6
6
|
|
|
7
7
|
# Audio I/O Codegen Rules (@ax-llm/ax)
|
package/skills/ax-flow.md
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
2
|
name: ax-flow
|
|
3
3
|
description: This skill helps an LLM generate correct AxFlow workflow code using @ax-llm/ax. Use when the user asks about flow(), AxFlow, workflow orchestration, parallel execution, DAG workflows, conditional routing, map/reduce patterns, or multi-node AI pipelines.
|
|
4
|
-
version: "25.4.
|
|
4
|
+
version: "25.4.2"
|
|
5
5
|
---
|
|
6
6
|
|
|
7
7
|
# AxFlow Codegen Rules (@ax-llm/ax)
|
package/skills/ax-gen.md
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
2
|
name: ax-gen
|
|
3
3
|
description: This skill helps an LLM generate correct AxGen code using @ax-llm/ax. Use when the user asks about ax(), AxGen, generators, forward(), streamingForward(), validation, assertions, streaming assertions, field processors, step hooks, self-tuning, or structured outputs. For MCP clients, transports, prompts, resources, tasks, subscriptions, or authentication use ax-mcp alongside this skill.
|
|
4
|
-
version: "25.4.
|
|
4
|
+
version: "25.4.2"
|
|
5
5
|
---
|
|
6
6
|
|
|
7
7
|
# AxGen Codegen Rules (@ax-llm/ax)
|
package/skills/ax-gepa.md
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
2
|
name: ax-gepa
|
|
3
3
|
description: This skill helps an LLM generate correct AxGEPA optimization code using @ax-llm/ax. Use when the user asks about AxGEPA, GEPA, Pareto optimization, multi-objective prompt tuning, reflective prompt evolution, validationExamples, maxMetricCalls, or optimizing a generator, flow, or agent tree.
|
|
4
|
-
version: "25.4.
|
|
4
|
+
version: "25.4.2"
|
|
5
5
|
---
|
|
6
6
|
|
|
7
7
|
# GEPA Optimization Codegen Rules (@ax-llm/ax)
|