@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.
@@ -7,7 +7,7 @@ on:
7
7
 
8
8
  permissions:
9
9
  contents: read
10
- id-token: write # Required for NPM provenance
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: '20'
36
+ node-version: '22'
37
37
  registry-url: 'https://registry.npmjs.org'
38
38
 
39
- - name: Publish to NPM with provenance
40
- run: npm publish --provenance --access public
41
- env:
42
- NODE_AUTH_TOKEN: ${{ secrets.NPM_TOKEN }}
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
- # Ultracite Code Standards
2
-
3
- This project uses **Ultracite**, a zero-config preset that enforces strict code quality standards through automated formatting and linting.
4
-
5
- ## Quick Reference
6
-
7
- - **Format code**: `bun x ultracite fix`
8
- - **Check for issues**: `bun x ultracite check`
9
- - **Diagnose setup**: `bun x ultracite doctor`
10
-
11
- Biome (the underlying engine) provides robust linting and formatting. Most issues are automatically fixable.
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
- ## Core Principles
140
+ # My Skill
16
141
 
17
- Write code that is **accessible, performant, type-safe, and maintainable**. Focus on clarity and explicit intent over brevity.
142
+ Instructions for the AI agent...
143
+ ```
18
144
 
19
- ### Type Safety & Explicitness
145
+ ## Coding Standards
20
146
 
21
- - Use explicit types for function parameters and return values when they enhance clarity
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
- ### Modern JavaScript/TypeScript
149
+ ```
150
+ https://raw.githubusercontent.com/anaclumos/taal/master/AGENTS.md
151
+ ```
28
152
 
29
- - Use arrow functions for callbacks and short functions
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
- ### Async & Promises
155
+ ### Development Workflow
37
156
 
38
- - Always `await` promises in async functions - don't forget to use the return value
39
- - Use `async/await` syntax instead of promise chains for better readability
40
- - Handle errors appropriately in async code with try-catch blocks
41
- - Don't use async functions as Promise executors
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
- ### React & JSX
162
+ ## Common Tasks for Agents
44
163
 
45
- - Use function components over class components
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
- ### Error Handling & Debugging
166
+ ```bash
167
+ # 1. Edit config
168
+ vim ~/.taal/config.yaml
59
169
 
60
- - Remove `console.log`, `debugger`, and `alert` statements from production code
61
- - Throw `Error` objects with descriptive messages, not strings or other values
62
- - Use `try-catch` blocks meaningfully - don't catch errors just to rethrow them
63
- - Prefer early returns over nested conditionals for error cases
170
+ # 2. Add server configuration
171
+ # mcp:
172
+ # new-server:
173
+ # command: npx
174
+ # args: ["-y", "package-name"]
64
175
 
65
- ### Code Organization
176
+ # 3. Validate
177
+ taal validate
66
178
 
67
- - Keep functions focused and under reasonable cognitive complexity limits
68
- - Extract complex conditions into well-named boolean variables
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
- ### Security
182
+ # 5. Sync
183
+ taal sync
184
+ ```
74
185
 
75
- - Add `rel="noopener"` when using `target="_blank"` on links
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
- ### Performance
188
+ ```bash
189
+ # 1. Create skill directory
190
+ mkdir -p ~/.taal/skills/my-skill
81
191
 
82
- - Avoid spread syntax in accumulators within loops
83
- - Use top-level regex literals instead of creating them in loops
84
- - Prefer specific imports over namespace imports
85
- - Avoid barrel files (index files that re-export everything)
86
- - Use proper image components (e.g., Next.js `<Image>`) over `<img>` tags
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
- ### Framework-Specific Guidance
200
+ # My Skill
89
201
 
90
- **Next.js:**
91
- - Use Next.js `<Image>` component for images
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
- **React 19+:**
96
- - Use ref as a prop instead of `React.forwardRef`
205
+ # 3. Verify discovery
206
+ taal list
97
207
 
98
- **Solid/Svelte/Vue/Qwik:**
99
- - Use `class` and `for` attributes (not `className` or `htmlFor`)
208
+ # 4. Sync to providers
209
+ taal sync
210
+ ```
100
211
 
101
- ---
212
+ ### Task: Troubleshoot configuration
102
213
 
103
- ## Testing
214
+ ```bash
215
+ # Check validation errors
216
+ taal validate
104
217
 
105
- - Write assertions inside `it()` or `test()` blocks
106
- - Avoid done callbacks in async tests - use async/await instead
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
- ## When Biome Can't Help
221
+ # Preview what would change
222
+ taal diff
111
223
 
112
- Biome's linter will catch most issues automatically. Focus your attention on:
224
+ # Check current configuration
225
+ cat ~/.taal/config.yaml
113
226
 
114
- 1. **Business logic correctness** - Biome can't validate your algorithms
115
- 2. **Meaningful naming** - Use descriptive names for functions, variables, and types
116
- 3. **Architecture decisions** - Component structure, data flow, and API design
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
- Most formatting and common issues are automatically fixed by Biome. Run `bun x ultracite fix` before committing to ensure compliance.
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 & Claude Code**
229
+ **Claude Desktop**
230
230
  - Only supports stdio servers (no HTTP)
231
- - Shared skills directory: `~/.claude/skills/`
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
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@anaclumos/taal",
3
- "version": "1.1.4",
3
+ "version": "1.1.8",
4
4
  "description": "CLI tool to sync MCP server configs and Agent Skills across AI coding assistants",
5
5
  "type": "module",
6
6
  "bin": {
@@ -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(currentServers[key]);
90
+ const currentValue = JSON.stringify(
91
+ sortObjectKeys(currentServers[key])
92
+ );
77
93
  const newValue = JSON.stringify(
78
- (transformedServers as Record<string, unknown>)[key]
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 { BaseProvider, createStdioTransformer } from "./base.js";
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 = createStdioTransformer("Claude Code");
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
  }
@@ -1,15 +0,0 @@
1
- {
2
- "hooks": {
3
- "PostToolUse": [
4
- {
5
- "matcher": "Write|Edit",
6
- "hooks": [
7
- {
8
- "type": "command",
9
- "command": "bun x ultracite fix"
10
- }
11
- ]
12
- }
13
- ]
14
- }
15
- }