@anaclumos/taal 1.1.4 → 1.1.8
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/.github/workflows/publish.yml +10 -6
- package/AGENTS.md +206 -92
- package/README.md +8 -2
- package/package.json +1 -1
- package/src/commands/diff.ts +20 -2
- package/src/providers/claude-code.ts +30 -2
- package/.claude/settings.json +0 -15
|
@@ -7,7 +7,7 @@ on:
|
|
|
7
7
|
|
|
8
8
|
permissions:
|
|
9
9
|
contents: read
|
|
10
|
-
id-token: write # Required for NPM
|
|
10
|
+
id-token: write # Required for NPM trusted publishing (OIDC)
|
|
11
11
|
|
|
12
12
|
jobs:
|
|
13
13
|
publish:
|
|
@@ -33,10 +33,14 @@ jobs:
|
|
|
33
33
|
- name: Setup Node.js for NPM publishing
|
|
34
34
|
uses: actions/setup-node@v4
|
|
35
35
|
with:
|
|
36
|
-
node-version: '
|
|
36
|
+
node-version: '22'
|
|
37
37
|
registry-url: 'https://registry.npmjs.org'
|
|
38
38
|
|
|
39
|
-
- name:
|
|
40
|
-
run: npm
|
|
41
|
-
|
|
42
|
-
|
|
39
|
+
- name: Update npm to latest (required for trusted publishing)
|
|
40
|
+
run: npm install -g npm@latest
|
|
41
|
+
|
|
42
|
+
- name: Verify npm version
|
|
43
|
+
run: npm --version
|
|
44
|
+
|
|
45
|
+
- name: Publish to NPM with trusted publishing
|
|
46
|
+
run: npm publish --access public
|
package/AGENTS.md
CHANGED
|
@@ -1,123 +1,237 @@
|
|
|
1
|
-
#
|
|
2
|
-
|
|
3
|
-
This
|
|
4
|
-
|
|
5
|
-
##
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
- **
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
1
|
+
# TAAL Agent Instructions
|
|
2
|
+
|
|
3
|
+
This file provides instructions for AI agents working with TAAL configurations.
|
|
4
|
+
|
|
5
|
+
## About TAAL
|
|
6
|
+
|
|
7
|
+
TAAL (Tooling & Agent Abstraction Layer) syncs MCP server configs and Agent Skills across AI coding assistants.
|
|
8
|
+
|
|
9
|
+
- **Repository**: https://github.com/anaclumos/taal
|
|
10
|
+
- **Package**: `@anaclumos/taal`
|
|
11
|
+
- **Config Location**: `~/.taal/config.yaml`
|
|
12
|
+
- **Skills Location**: `~/.taal/skills/`
|
|
13
|
+
|
|
14
|
+
## How to Use TAAL
|
|
15
|
+
|
|
16
|
+
### Installation
|
|
17
|
+
|
|
18
|
+
```bash
|
|
19
|
+
npm install -g @anaclumos/taal
|
|
20
|
+
```
|
|
21
|
+
|
|
22
|
+
### Core Commands
|
|
23
|
+
|
|
24
|
+
| Command | Purpose | Example |
|
|
25
|
+
|---------|---------|---------|
|
|
26
|
+
| `taal init` | Initialize TAAL configuration | `taal init` |
|
|
27
|
+
| `taal collect` | Import configs from installed providers | `taal collect` |
|
|
28
|
+
| `taal validate` | Validate configuration | `taal validate` |
|
|
29
|
+
| `taal diff` | Preview changes before sync | `taal diff` |
|
|
30
|
+
| `taal sync` | Sync configs to all providers | `taal sync` |
|
|
31
|
+
| `taal list` | List configured servers and skills | `taal list` |
|
|
32
|
+
| `taal providers` | Show all supported providers | `taal providers` |
|
|
33
|
+
|
|
34
|
+
### Typical Workflow
|
|
35
|
+
|
|
36
|
+
1. **First-time setup:**
|
|
37
|
+
```bash
|
|
38
|
+
taal init # Creates ~/.taal/config.yaml
|
|
39
|
+
taal collect # Imports existing MCP configs
|
|
40
|
+
taal validate # Checks configuration
|
|
41
|
+
taal sync # Syncs to all providers
|
|
42
|
+
```
|
|
43
|
+
|
|
44
|
+
2. **Adding a new MCP server:**
|
|
45
|
+
```bash
|
|
46
|
+
# Edit ~/.taal/config.yaml to add server
|
|
47
|
+
taal validate # Verify configuration
|
|
48
|
+
taal diff # Preview changes
|
|
49
|
+
taal sync # Apply changes
|
|
50
|
+
```
|
|
51
|
+
|
|
52
|
+
3. **Adding a new skill:**
|
|
53
|
+
```bash
|
|
54
|
+
# Create skill in ~/.taal/skills/my-skill/SKILL.md
|
|
55
|
+
taal list # Verify skill is discovered
|
|
56
|
+
taal sync # Sync to providers
|
|
57
|
+
```
|
|
58
|
+
|
|
59
|
+
### Configuration Structure
|
|
60
|
+
|
|
61
|
+
**File**: `~/.taal/config.yaml`
|
|
62
|
+
|
|
63
|
+
```yaml
|
|
64
|
+
version: "1"
|
|
65
|
+
|
|
66
|
+
mcp:
|
|
67
|
+
# stdio server example
|
|
68
|
+
filesystem:
|
|
69
|
+
command: npx
|
|
70
|
+
args: ["-y", "@modelcontextprotocol/server-filesystem", "/path"]
|
|
71
|
+
env:
|
|
72
|
+
LOG_LEVEL: "info"
|
|
73
|
+
|
|
74
|
+
# HTTP server example
|
|
75
|
+
context7:
|
|
76
|
+
url: https://mcp.context7.com/mcp
|
|
77
|
+
headers:
|
|
78
|
+
CONTEXT7_API_KEY: "${CONTEXT7_API_KEY}"
|
|
79
|
+
|
|
80
|
+
skills:
|
|
81
|
+
paths:
|
|
82
|
+
- ~/.taal/skills
|
|
83
|
+
- ~/projects/custom-skills
|
|
84
|
+
|
|
85
|
+
providers:
|
|
86
|
+
enabled:
|
|
87
|
+
- claude-desktop
|
|
88
|
+
- claude-code
|
|
89
|
+
- cursor
|
|
90
|
+
- zed
|
|
91
|
+
```
|
|
92
|
+
|
|
93
|
+
### Supported Providers
|
|
94
|
+
|
|
95
|
+
- **Claude Desktop** - stdio only, skills: `~/.claude/skills/`
|
|
96
|
+
- **Claude Code** - stdio + HTTP, skills: `~/.claude/skills/`
|
|
97
|
+
- **Cursor** - stdio only
|
|
98
|
+
- **Continue.dev** - stdio + HTTP (SSE)
|
|
99
|
+
- **Zed** - stdio + HTTP
|
|
100
|
+
- **OpenCode** - stdio + HTTP, skills: `~/.config/opencode/skill/`
|
|
101
|
+
- **Codex** - stdio + HTTP, skills: `~/.codex/skills/`
|
|
102
|
+
- **Windsurf** - stdio + HTTP
|
|
103
|
+
- **Antigravity** - stdio only
|
|
104
|
+
|
|
105
|
+
### Environment Variables
|
|
106
|
+
|
|
107
|
+
Use `${VAR_NAME}` syntax in config:
|
|
108
|
+
|
|
109
|
+
```yaml
|
|
110
|
+
mcp:
|
|
111
|
+
my-server:
|
|
112
|
+
url: https://api.example.com
|
|
113
|
+
headers:
|
|
114
|
+
API_KEY: "${MY_API_KEY}"
|
|
115
|
+
```
|
|
116
|
+
|
|
117
|
+
TAAL will substitute variables at sync time and warn if undefined.
|
|
118
|
+
|
|
119
|
+
### Skills Structure
|
|
120
|
+
|
|
121
|
+
Create skills in `~/.taal/skills/`:
|
|
122
|
+
|
|
123
|
+
```
|
|
124
|
+
~/.taal/skills/
|
|
125
|
+
└── my-skill/
|
|
126
|
+
├── SKILL.md # Required: YAML frontmatter + instructions
|
|
127
|
+
├── scripts/ # Optional: Helper scripts
|
|
128
|
+
└── references/ # Optional: Reference materials
|
|
129
|
+
```
|
|
130
|
+
|
|
131
|
+
**SKILL.md format:**
|
|
132
|
+
|
|
133
|
+
```markdown
|
|
134
|
+
---
|
|
135
|
+
name: My Skill
|
|
136
|
+
description: What this skill does
|
|
137
|
+
version: 1.0.0
|
|
13
138
|
---
|
|
14
139
|
|
|
15
|
-
|
|
140
|
+
# My Skill
|
|
16
141
|
|
|
17
|
-
|
|
142
|
+
Instructions for the AI agent...
|
|
143
|
+
```
|
|
18
144
|
|
|
19
|
-
|
|
145
|
+
## Coding Standards
|
|
20
146
|
|
|
21
|
-
|
|
22
|
-
- Prefer `unknown` over `any` when the type is genuinely unknown
|
|
23
|
-
- Use const assertions (`as const`) for immutable values and literal types
|
|
24
|
-
- Leverage TypeScript's type narrowing instead of type assertions
|
|
25
|
-
- Use meaningful variable names instead of magic numbers - extract constants with descriptive names
|
|
147
|
+
When working on TAAL codebase or related projects, fetch and follow the latest coding standards:
|
|
26
148
|
|
|
27
|
-
|
|
149
|
+
```
|
|
150
|
+
https://raw.githubusercontent.com/anaclumos/taal/master/AGENTS.md
|
|
151
|
+
```
|
|
28
152
|
|
|
29
|
-
|
|
30
|
-
- Prefer `for...of` loops over `.forEach()` and indexed `for` loops
|
|
31
|
-
- Use optional chaining (`?.`) and nullish coalescing (`??`) for safer property access
|
|
32
|
-
- Prefer template literals over string concatenation
|
|
33
|
-
- Use destructuring for object and array assignments
|
|
34
|
-
- Use `const` by default, `let` only when reassignment is needed, never `var`
|
|
153
|
+
Use WebFetch or similar tools to retrieve the latest guidelines before making code changes.
|
|
35
154
|
|
|
36
|
-
###
|
|
155
|
+
### Development Workflow
|
|
37
156
|
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
157
|
+
1. Fetch the latest AGENTS.md from the URL above
|
|
158
|
+
2. Review the coding standards and principles
|
|
159
|
+
3. Apply them to your work on TAAL configurations and related code
|
|
160
|
+
4. Ensure all changes comply with Ultracite code quality standards
|
|
42
161
|
|
|
43
|
-
|
|
162
|
+
## Common Tasks for Agents
|
|
44
163
|
|
|
45
|
-
|
|
46
|
-
- Call hooks at the top level only, never conditionally
|
|
47
|
-
- Specify all dependencies in hook dependency arrays correctly
|
|
48
|
-
- Use the `key` prop for elements in iterables (prefer unique IDs over array indices)
|
|
49
|
-
- Nest children between opening and closing tags instead of passing as props
|
|
50
|
-
- Don't define components inside other components
|
|
51
|
-
- Use semantic HTML and ARIA attributes for accessibility:
|
|
52
|
-
- Provide meaningful alt text for images
|
|
53
|
-
- Use proper heading hierarchy
|
|
54
|
-
- Add labels for form inputs
|
|
55
|
-
- Include keyboard event handlers alongside mouse events
|
|
56
|
-
- Use semantic elements (`<button>`, `<nav>`, etc.) instead of divs with roles
|
|
164
|
+
### Task: Add a new MCP server
|
|
57
165
|
|
|
58
|
-
|
|
166
|
+
```bash
|
|
167
|
+
# 1. Edit config
|
|
168
|
+
vim ~/.taal/config.yaml
|
|
59
169
|
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
-
|
|
63
|
-
|
|
170
|
+
# 2. Add server configuration
|
|
171
|
+
# mcp:
|
|
172
|
+
# new-server:
|
|
173
|
+
# command: npx
|
|
174
|
+
# args: ["-y", "package-name"]
|
|
64
175
|
|
|
65
|
-
|
|
176
|
+
# 3. Validate
|
|
177
|
+
taal validate
|
|
66
178
|
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
- Use early returns to reduce nesting
|
|
70
|
-
- Prefer simple conditionals over nested ternary operators
|
|
71
|
-
- Group related code together and separate concerns
|
|
179
|
+
# 4. Preview changes
|
|
180
|
+
taal diff
|
|
72
181
|
|
|
73
|
-
|
|
182
|
+
# 5. Sync
|
|
183
|
+
taal sync
|
|
184
|
+
```
|
|
74
185
|
|
|
75
|
-
|
|
76
|
-
- Avoid `dangerouslySetInnerHTML` unless absolutely necessary
|
|
77
|
-
- Don't use `eval()` or assign directly to `document.cookie`
|
|
78
|
-
- Validate and sanitize user input
|
|
186
|
+
### Task: Create a new skill
|
|
79
187
|
|
|
80
|
-
|
|
188
|
+
```bash
|
|
189
|
+
# 1. Create skill directory
|
|
190
|
+
mkdir -p ~/.taal/skills/my-skill
|
|
81
191
|
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
192
|
+
# 2. Create SKILL.md
|
|
193
|
+
cat > ~/.taal/skills/my-skill/SKILL.md << 'EOF'
|
|
194
|
+
---
|
|
195
|
+
name: My Skill
|
|
196
|
+
description: Skill description
|
|
197
|
+
version: 1.0.0
|
|
198
|
+
---
|
|
87
199
|
|
|
88
|
-
|
|
200
|
+
# My Skill
|
|
89
201
|
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
- Use `next/head` or App Router metadata API for head elements
|
|
93
|
-
- Use Server Components for async data fetching instead of async Client Components
|
|
202
|
+
Instructions for AI agents...
|
|
203
|
+
EOF
|
|
94
204
|
|
|
95
|
-
|
|
96
|
-
|
|
205
|
+
# 3. Verify discovery
|
|
206
|
+
taal list
|
|
97
207
|
|
|
98
|
-
|
|
99
|
-
|
|
208
|
+
# 4. Sync to providers
|
|
209
|
+
taal sync
|
|
210
|
+
```
|
|
100
211
|
|
|
101
|
-
|
|
212
|
+
### Task: Troubleshoot configuration
|
|
102
213
|
|
|
103
|
-
|
|
214
|
+
```bash
|
|
215
|
+
# Check validation errors
|
|
216
|
+
taal validate
|
|
104
217
|
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
- Don't use `.only` or `.skip` in committed code
|
|
108
|
-
- Keep test suites reasonably flat - avoid excessive `describe` nesting
|
|
218
|
+
# Check which providers are installed
|
|
219
|
+
taal providers
|
|
109
220
|
|
|
110
|
-
|
|
221
|
+
# Preview what would change
|
|
222
|
+
taal diff
|
|
111
223
|
|
|
112
|
-
|
|
224
|
+
# Check current configuration
|
|
225
|
+
cat ~/.taal/config.yaml
|
|
113
226
|
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
4. **Edge cases** - Handle boundary conditions and error states
|
|
118
|
-
5. **User experience** - Accessibility, performance, and usability considerations
|
|
119
|
-
6. **Documentation** - Add comments for complex logic, but prefer self-documenting code
|
|
227
|
+
# Check backups if something went wrong
|
|
228
|
+
ls -la ~/.taal/backups/
|
|
229
|
+
```
|
|
120
230
|
|
|
121
|
-
|
|
231
|
+
## Important Notes
|
|
122
232
|
|
|
123
|
-
|
|
233
|
+
- **Backups**: TAAL automatically creates backups before every sync in `~/.taal/backups/`
|
|
234
|
+
- **Environment Variables**: Undefined variables trigger warnings but don't block sync
|
|
235
|
+
- **Provider Detection**: TAAL auto-detects installed providers by checking config directories
|
|
236
|
+
- **Skills Validation**: Invalid skills are skipped with warnings during sync
|
|
237
|
+
- **Mutual Exclusivity**: MCP servers must have either `command` (stdio) OR `url` (HTTP), not both
|
package/README.md
CHANGED
|
@@ -226,9 +226,15 @@ TAAL supports 9 AI coding assistants:
|
|
|
226
226
|
|
|
227
227
|
### Provider-Specific Notes
|
|
228
228
|
|
|
229
|
-
**Claude Desktop
|
|
229
|
+
**Claude Desktop**
|
|
230
230
|
- Only supports stdio servers (no HTTP)
|
|
231
|
-
-
|
|
231
|
+
- Skills directory: `~/.claude/skills/`
|
|
232
|
+
|
|
233
|
+
**Claude Code**
|
|
234
|
+
- Supports both stdio and HTTP servers (SSE deprecated)
|
|
235
|
+
- Uses `type: "http" | "stdio"` format in config
|
|
236
|
+
- Skills directory: `~/.claude/skills/`
|
|
237
|
+
- Can import servers from Claude Desktop via `claude mcp add-from-claude-desktop`
|
|
232
238
|
|
|
233
239
|
**Cursor**
|
|
234
240
|
- Only supports stdio servers
|
package/package.json
CHANGED
package/src/commands/diff.ts
CHANGED
|
@@ -2,6 +2,20 @@ import { homedir } from "node:os";
|
|
|
2
2
|
import { loadTaalConfig } from "../config/loader.js";
|
|
3
3
|
import { initializeProviders, registry } from "../providers/index.js";
|
|
4
4
|
|
|
5
|
+
function sortObjectKeys(obj: unknown): unknown {
|
|
6
|
+
if (obj === null || typeof obj !== "object") {
|
|
7
|
+
return obj;
|
|
8
|
+
}
|
|
9
|
+
if (Array.isArray(obj)) {
|
|
10
|
+
return obj.map(sortObjectKeys);
|
|
11
|
+
}
|
|
12
|
+
const sorted: Record<string, unknown> = {};
|
|
13
|
+
for (const key of Object.keys(obj).sort()) {
|
|
14
|
+
sorted[key] = sortObjectKeys((obj as Record<string, unknown>)[key]);
|
|
15
|
+
}
|
|
16
|
+
return sorted;
|
|
17
|
+
}
|
|
18
|
+
|
|
5
19
|
export interface DiffChange {
|
|
6
20
|
type: "add" | "remove" | "modify";
|
|
7
21
|
serverName: string;
|
|
@@ -73,9 +87,13 @@ export async function diff(
|
|
|
73
87
|
|
|
74
88
|
for (const key of taalKeys) {
|
|
75
89
|
if (currentKeys.has(key)) {
|
|
76
|
-
const currentValue = JSON.stringify(
|
|
90
|
+
const currentValue = JSON.stringify(
|
|
91
|
+
sortObjectKeys(currentServers[key])
|
|
92
|
+
);
|
|
77
93
|
const newValue = JSON.stringify(
|
|
78
|
-
(
|
|
94
|
+
sortObjectKeys(
|
|
95
|
+
(transformedServers as Record<string, unknown>)[key]
|
|
96
|
+
)
|
|
79
97
|
);
|
|
80
98
|
|
|
81
99
|
if (currentValue !== newValue) {
|
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
import { join } from "node:path";
|
|
2
|
-
import {
|
|
2
|
+
import type { McpServer } from "../config/schema.js";
|
|
3
|
+
import { BaseProvider } from "./base.js";
|
|
3
4
|
|
|
4
5
|
export class ClaudeCodeProvider extends BaseProvider {
|
|
5
6
|
name = "claude-code";
|
|
@@ -8,5 +9,32 @@ export class ClaudeCodeProvider extends BaseProvider {
|
|
|
8
9
|
mcpKey = "mcpServers";
|
|
9
10
|
skillsPath = (home: string) => join(home, ".claude", "skills");
|
|
10
11
|
|
|
11
|
-
transformMcpServers
|
|
12
|
+
transformMcpServers(
|
|
13
|
+
servers: Record<string, McpServer>
|
|
14
|
+
): Record<string, unknown> {
|
|
15
|
+
const transformed: Record<string, unknown> = {};
|
|
16
|
+
|
|
17
|
+
for (const [name, server] of Object.entries(servers)) {
|
|
18
|
+
if (server.url) {
|
|
19
|
+
// HTTP server - Claude Code supports HTTP transport
|
|
20
|
+
transformed[name] = {
|
|
21
|
+
type: "http",
|
|
22
|
+
url: server.url,
|
|
23
|
+
...(server.headers && { headers: server.headers }),
|
|
24
|
+
};
|
|
25
|
+
} else if (server.command) {
|
|
26
|
+
// stdio server - Claude Code supports stdio transport
|
|
27
|
+
transformed[name] = {
|
|
28
|
+
type: "stdio",
|
|
29
|
+
command: server.command,
|
|
30
|
+
...(server.args && { args: server.args }),
|
|
31
|
+
...(server.env && { env: server.env }),
|
|
32
|
+
};
|
|
33
|
+
} else {
|
|
34
|
+
console.warn(`Skipping server "${name}" - missing command or url`);
|
|
35
|
+
}
|
|
36
|
+
}
|
|
37
|
+
|
|
38
|
+
return transformed;
|
|
39
|
+
}
|
|
12
40
|
}
|