synctax 2.0.0 → 2.0.1
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/CHANGELOG.md +15 -0
- package/README.md +26 -14
- package/dist/synctax.js +11 -9
- package/package.json +1 -1
package/CHANGELOG.md
CHANGED
|
@@ -7,6 +7,21 @@ Versioning follows [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
|
|
|
7
7
|
|
|
8
8
|
---
|
|
9
9
|
|
|
10
|
+
## [2.0.1] — 2026-04-05
|
|
11
|
+
|
|
12
|
+
### Fixed
|
|
13
|
+
|
|
14
|
+
- **TUI data loader**: Invalid `source` in config now correctly falls back to the default adapter instead of remaining set to the invalid value, preventing downstream TUI failures
|
|
15
|
+
- **TUI data loader**: Theme fallback now uses `"rebel"` to match the schema default in `src/types.ts` (was `"synctax"`, causing inconsistent defaults)
|
|
16
|
+
- **TUI entrypoint**: `NODE_ENV` is now restored in the `finally` block after `waitUntilExit()`, ensuring it is always restored even if `render()` throws, and that it doesn't affect code running during the TUI lifetime
|
|
17
|
+
- **Atomic writes**: Temp file now uses a unique name (`pid-timestamp-random` suffix) instead of a deterministic `.synctax-tmp` suffix, preventing stale file collisions from crashed writes under concurrent access
|
|
18
|
+
- **Lock errors**: Error messages now interpolate the actual computed `lockPath` instead of hardcoding `~/.synctax/sync.lock`, which was misleading when `SYNCTAX_HOME` is set (e.g., in tests)
|
|
19
|
+
- **ESLint config**: `.tsx` files (Ink/React TUI components) are now covered by the ESLint config alongside `.ts` files
|
|
20
|
+
- **Module entry**: `index.ts` no longer emits an unconditional `console.log` side effect on import; replaced with `export {}`
|
|
21
|
+
- **`synctax add`**: Scope flag resolution for `agent` and `skill` now mirrors MCP: `--global` → `"global"`, `--local` → `"local"`, neither → `"global"` (was: `agent`/`skill` ignored `--local` and defaulted to `"local"`, inconsistent with MCP)
|
|
22
|
+
|
|
23
|
+
---
|
|
24
|
+
|
|
10
25
|
## [2.0.0] — 2026-04-05
|
|
11
26
|
|
|
12
27
|
### Initial Release
|
package/README.md
CHANGED
|
@@ -7,9 +7,9 @@
|
|
|
7
7
|
|
|
8
8
|
<p align="center">
|
|
9
9
|
<a href="https://github.com/Kaos599/Synctax/actions/workflows/ci.yml"><img alt="CI" src="https://github.com/Kaos599/Synctax/actions/workflows/ci.yml/badge.svg" /></a>
|
|
10
|
-
<img alt="
|
|
10
|
+
<a href="https://www.npmjs.com/package/synctax"><img alt="npm" src="https://img.shields.io/npm/v/synctax?color=brightgreen" /></a>
|
|
11
11
|
<img alt="license" src="https://img.shields.io/github/license/Kaos599/Synctax?color=blue" />
|
|
12
|
-
<img alt="runtime" src="https://img.shields.io/badge/
|
|
12
|
+
<img alt="runtime" src="https://img.shields.io/badge/node-%E2%89%A518-brightgreen" />
|
|
13
13
|
<img alt="clients" src="https://img.shields.io/badge/clients-9%20supported-lightgrey" />
|
|
14
14
|
</p>
|
|
15
15
|
|
|
@@ -29,21 +29,24 @@ Synctax eliminates this. One master config at `~/.synctax/config.json`. One comm
|
|
|
29
29
|
|
|
30
30
|
## Install
|
|
31
31
|
|
|
32
|
-
|
|
32
|
+
```bash
|
|
33
|
+
npm install -g synctax
|
|
34
|
+
```
|
|
35
|
+
|
|
36
|
+
Works with npm, pnpm, yarn, or Bun:
|
|
33
37
|
|
|
34
38
|
```bash
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
bun
|
|
38
|
-
bun ./bin/synctax.ts init
|
|
39
|
-
bun ./bin/synctax.ts sync
|
|
39
|
+
pnpm add -g synctax
|
|
40
|
+
yarn global add synctax
|
|
41
|
+
bun add -g synctax
|
|
40
42
|
```
|
|
41
43
|
|
|
42
|
-
|
|
44
|
+
**Requires Node.js ≥18.** No other runtime needed — Synctax is a self-contained bundle.
|
|
45
|
+
|
|
46
|
+
Then initialize:
|
|
43
47
|
|
|
44
48
|
```bash
|
|
45
49
|
synctax init
|
|
46
|
-
synctax sync
|
|
47
50
|
```
|
|
48
51
|
|
|
49
52
|
---
|
|
@@ -138,10 +141,10 @@ synctax sync --interactive # Select which resources to sync
|
|
|
138
141
|
|--------|-----|--------|--------|-------------|
|
|
139
142
|
| Claude Code | ✅ | ✅ | ✅ | `CLAUDE.md` |
|
|
140
143
|
| Cursor | ✅ | ✅ | ✅ | `.cursorrules` |
|
|
141
|
-
| GitHub Copilot | ✅ | ✅ | ✅ | `.github/copilot-instructions.md` |
|
|
142
|
-
| GitHub Copilot CLI | ✅ | ✅ | ✅ | `.github/copilot-instructions.md` |
|
|
143
144
|
| OpenCode | ✅ | ✅ | ✅ | `AGENTS.md` |
|
|
144
145
|
| Antigravity | ✅ | ✅ | ✅ | `.antigravityrules` |
|
|
146
|
+
| GitHub Copilot (VS Code) | ✅ | — | — | `.github/copilot-instructions.md` |
|
|
147
|
+
| GitHub Copilot CLI | — | — | ✅ | `.github/copilot-instructions.md` |
|
|
145
148
|
| Cline | ✅ | — | — | `.clinerules` |
|
|
146
149
|
| Zed | ✅ | — | — | `.rules` |
|
|
147
150
|
| Gemini CLI | — | — | — | `.geminirules` |
|
|
@@ -238,7 +241,16 @@ synctax profile diff personal
|
|
|
238
241
|
|
|
239
242
|
## Development
|
|
240
243
|
|
|
244
|
+
**Prerequisites for contributing:** [Bun](https://bun.sh) v1.0+
|
|
245
|
+
|
|
241
246
|
```bash
|
|
247
|
+
git clone https://github.com/Kaos599/synctax.git
|
|
248
|
+
cd synctax
|
|
249
|
+
bun install
|
|
250
|
+
|
|
251
|
+
# Run the CLI directly from source
|
|
252
|
+
bun ./bin/synctax.ts <command>
|
|
253
|
+
|
|
242
254
|
# Run all tests
|
|
243
255
|
bun run test
|
|
244
256
|
|
|
@@ -251,8 +263,8 @@ bun run lint
|
|
|
251
263
|
# Run a single test file
|
|
252
264
|
bunx vitest run tests/adapters.test.ts
|
|
253
265
|
|
|
254
|
-
#
|
|
255
|
-
bun
|
|
266
|
+
# Build the Node.js bundle (what gets published to npm)
|
|
267
|
+
bun run build
|
|
256
268
|
```
|
|
257
269
|
|
|
258
270
|
---
|
package/dist/synctax.js
CHANGED
|
@@ -16175,7 +16175,8 @@ import path from "path";
|
|
|
16175
16175
|
async function atomicWriteFile(targetPath, content, mode) {
|
|
16176
16176
|
const dir = path.dirname(targetPath);
|
|
16177
16177
|
await fs.mkdir(dir, { recursive: true }).catch(() => {});
|
|
16178
|
-
const
|
|
16178
|
+
const tmpSuffix = `${process.pid}-${Date.now()}-${Math.random().toString(36).slice(2)}`;
|
|
16179
|
+
const tempPath = `${targetPath}.synctax-tmp-${tmpSuffix}`;
|
|
16179
16180
|
await fs.writeFile(tempPath, content, {
|
|
16180
16181
|
encoding: "utf-8",
|
|
16181
16182
|
mode: mode ?? 420
|
|
@@ -24252,7 +24253,7 @@ var init_adapters = __esm(() => {
|
|
|
24252
24253
|
|
|
24253
24254
|
// src/version.ts
|
|
24254
24255
|
function getVersion() {
|
|
24255
|
-
return "2.0.
|
|
24256
|
+
return "2.0.1";
|
|
24256
24257
|
}
|
|
24257
24258
|
|
|
24258
24259
|
// node_modules/@inquirer/core/dist/lib/key.js
|
|
@@ -26945,7 +26946,7 @@ async function acquireLock(command = "unknown") {
|
|
|
26945
26946
|
try {
|
|
26946
26947
|
await tryWrite();
|
|
26947
26948
|
} catch {
|
|
26948
|
-
throw new Error(
|
|
26949
|
+
throw new Error(`Another synctax process is running. If this is incorrect, delete ${lockPath}`);
|
|
26949
26950
|
}
|
|
26950
26951
|
} else {
|
|
26951
26952
|
let holder = "unknown";
|
|
@@ -26954,7 +26955,7 @@ async function acquireLock(command = "unknown") {
|
|
|
26954
26955
|
const info2 = JSON.parse(content);
|
|
26955
26956
|
holder = `PID ${info2.pid} (${info2.command})`;
|
|
26956
26957
|
} catch {}
|
|
26957
|
-
throw new Error(`Another synctax process is running (${holder}). Wait for it to finish or delete
|
|
26958
|
+
throw new Error(`Another synctax process is running (${holder}). Wait for it to finish or delete ${lockPath}`);
|
|
26958
26959
|
}
|
|
26959
26960
|
} else {
|
|
26960
26961
|
throw err;
|
|
@@ -29203,7 +29204,7 @@ async function addCommand(domain2, name, options) {
|
|
|
29203
29204
|
prompt: options.prompt || "",
|
|
29204
29205
|
model: options.model,
|
|
29205
29206
|
tools: options.tools ? options.tools.split(",") : undefined,
|
|
29206
|
-
scope: options.global ? "global" : "local"
|
|
29207
|
+
scope: options.global ? "global" : options.local ? "local" : "global"
|
|
29207
29208
|
};
|
|
29208
29209
|
} else if (domain2 === "skill") {
|
|
29209
29210
|
config2.resources.skills[name] = {
|
|
@@ -29211,7 +29212,7 @@ async function addCommand(domain2, name, options) {
|
|
|
29211
29212
|
description: options.description,
|
|
29212
29213
|
trigger: options.trigger,
|
|
29213
29214
|
content: options.content || "",
|
|
29214
|
-
scope: options.global ? "global" : "local"
|
|
29215
|
+
scope: options.global ? "global" : options.local ? "local" : "global"
|
|
29215
29216
|
};
|
|
29216
29217
|
} else {
|
|
29217
29218
|
error48(`Unsupported domain for add: ${domain2}`);
|
|
@@ -61530,9 +61531,9 @@ async function runInkTui(options) {
|
|
|
61530
61531
|
exitOnCtrlC: false,
|
|
61531
61532
|
patchConsole: false
|
|
61532
61533
|
});
|
|
61533
|
-
process.env.NODE_ENV = prevEnv;
|
|
61534
61534
|
await instance.waitUntilExit();
|
|
61535
61535
|
} finally {
|
|
61536
|
+
process.env.NODE_ENV = prevEnv;
|
|
61536
61537
|
process.stdout.write("\x1B[?25h");
|
|
61537
61538
|
process.stdout.write("\x1B[?1049l");
|
|
61538
61539
|
}
|
|
@@ -61563,6 +61564,7 @@ async function loadTuiFrameData() {
|
|
|
61563
61564
|
let source = normalizedSource || fallbackSource;
|
|
61564
61565
|
if (normalizedSource && !Object.hasOwn(adapters, normalizedSource)) {
|
|
61565
61566
|
warnings.push(`Configured source '${normalizedSource}' is not a valid adapter.`);
|
|
61567
|
+
source = fallbackSource;
|
|
61566
61568
|
}
|
|
61567
61569
|
const enabledClients = Object.entries(config2.clients).filter(([id, client]) => Object.hasOwn(adapters, id) && client?.enabled).length;
|
|
61568
61570
|
if (enabledClients === 0) {
|
|
@@ -61572,7 +61574,7 @@ async function loadTuiFrameData() {
|
|
|
61572
61574
|
version: getVersion(),
|
|
61573
61575
|
profile: config2.activeProfile || "default",
|
|
61574
61576
|
source,
|
|
61575
|
-
theme: config2.theme
|
|
61577
|
+
theme: config2.theme ?? "rebel",
|
|
61576
61578
|
health: warnings.length > 0 ? "WARN" : "OK",
|
|
61577
61579
|
enabledClients,
|
|
61578
61580
|
totalClients: adapterIds.length,
|
|
@@ -61648,7 +61650,7 @@ init_commands();
|
|
|
61648
61650
|
|
|
61649
61651
|
// src/version.ts
|
|
61650
61652
|
function getVersion2() {
|
|
61651
|
-
return "2.0.
|
|
61653
|
+
return "2.0.1";
|
|
61652
61654
|
}
|
|
61653
61655
|
|
|
61654
61656
|
// bin/synctax.ts
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "synctax",
|
|
3
|
-
"version": "2.0.
|
|
3
|
+
"version": "2.0.1",
|
|
4
4
|
"description": "Universal config sync for the agentic developer stack — sync MCP servers, agents, skills, and permissions across 9 AI clients from a single source of truth.",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"license": "MIT",
|