zedx 0.5.0 → 0.6.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/README.md +1 -0
- package/dist/check.js +0 -4
- package/dist/index.js +7 -1
- package/dist/sync.d.ts +1 -0
- package/dist/sync.js +76 -0
- package/package.json +55 -53
package/README.md
CHANGED
|
@@ -34,6 +34,7 @@ zedx version major # 1.2.3 → 2.0.0
|
|
|
34
34
|
# Sync Zed settings and extensions via a GitHub repo
|
|
35
35
|
zedx sync init # Link a GitHub repo as the sync target (run once)
|
|
36
36
|
zedx sync # Sync local and remote config automatically
|
|
37
|
+
zedx sync status # Show sync state between local config and the remote repo
|
|
37
38
|
zedx sync install # Install an OS daemon to auto-sync when Zed config changes
|
|
38
39
|
zedx sync uninstall # Remove the OS daemon
|
|
39
40
|
```
|
package/dist/check.js
CHANGED
|
@@ -10,10 +10,6 @@ function tomlGet(content, key) {
|
|
|
10
10
|
function tomlHasUncommentedKey(content, key) {
|
|
11
11
|
return new RegExp(`^${key}\\s*=`, 'm').test(content);
|
|
12
12
|
}
|
|
13
|
-
function tomlHasSection(content, section) {
|
|
14
|
-
// Looks for an uncommented [section] or [section.something] header
|
|
15
|
-
return new RegExp(`^\\[${section.replace('.', '\\.')}`, 'm').test(content);
|
|
16
|
-
}
|
|
17
13
|
export async function runCheck(callerDir) {
|
|
18
14
|
p.intro(`${color.bgBlue(color.bold(' zedx check '))} ${color.blue('Validating extension config…')}`);
|
|
19
15
|
const tomlPath = path.join(callerDir, 'extension.toml');
|
package/dist/index.js
CHANGED
|
@@ -8,7 +8,7 @@ import { promptUser, promptThemeDetails, promptLanguageDetails } from './prompts
|
|
|
8
8
|
import { generateExtension } from './generator.js';
|
|
9
9
|
import { runCheck } from './check.js';
|
|
10
10
|
import { addTheme, addLanguage } from './add.js';
|
|
11
|
-
import { syncInit, runSync } from './sync.js';
|
|
11
|
+
import { syncInit, runSync, syncStatus } from './sync.js';
|
|
12
12
|
import { syncInstall, syncUninstall } from './daemon.js';
|
|
13
13
|
function bumpVersion(version, type) {
|
|
14
14
|
const [major, minor, patch] = version.split('.').map(Number);
|
|
@@ -90,6 +90,12 @@ async function main() {
|
|
|
90
90
|
.action(async () => {
|
|
91
91
|
await syncInit();
|
|
92
92
|
});
|
|
93
|
+
syncCmd
|
|
94
|
+
.command('status')
|
|
95
|
+
.description('Show sync state between local Zed config and the remote repo')
|
|
96
|
+
.action(async () => {
|
|
97
|
+
await syncStatus();
|
|
98
|
+
});
|
|
93
99
|
syncCmd
|
|
94
100
|
.command('install')
|
|
95
101
|
.description('Install the OS daemon to auto-sync when Zed config changes')
|
package/dist/sync.d.ts
CHANGED
package/dist/sync.js
CHANGED
|
@@ -75,6 +75,82 @@ async function applyRemoteSettings(repoSettings, repoExtensions, localSettingsPa
|
|
|
75
75
|
await fs.ensureDir(path.dirname(localSettingsPath));
|
|
76
76
|
await fs.writeFile(localSettingsPath, settingsJson, 'utf-8');
|
|
77
77
|
}
|
|
78
|
+
// zedx sync status
|
|
79
|
+
export async function syncStatus() {
|
|
80
|
+
p.intro(color.bold('zedx sync status'));
|
|
81
|
+
const config = await requireSyncConfig();
|
|
82
|
+
const zedPaths = resolveZedPaths();
|
|
83
|
+
p.log.info(`Repo: ${color.dim(config.syncRepo)} ${color.dim(`(${config.branch})`)}`);
|
|
84
|
+
if (config.lastSync) {
|
|
85
|
+
p.log.info(`Last sync: ${color.dim(new Date(config.lastSync).toLocaleString())}`);
|
|
86
|
+
}
|
|
87
|
+
else {
|
|
88
|
+
p.log.info(`Last sync: ${color.dim('never')}`);
|
|
89
|
+
}
|
|
90
|
+
const spinner = p.spinner();
|
|
91
|
+
await withTempDir(async (tmp) => {
|
|
92
|
+
spinner.start(`Fetching ${config.syncRepo}...`);
|
|
93
|
+
let remoteExists = true;
|
|
94
|
+
try {
|
|
95
|
+
const git = simpleGit(tmp);
|
|
96
|
+
await git.clone(config.syncRepo, tmp, ['--depth', '1', '--branch', config.branch]);
|
|
97
|
+
spinner.stop('Remote fetched.');
|
|
98
|
+
}
|
|
99
|
+
catch {
|
|
100
|
+
remoteExists = false;
|
|
101
|
+
spinner.stop(color.yellow('Remote is empty or branch not found.'));
|
|
102
|
+
}
|
|
103
|
+
const files = [
|
|
104
|
+
{
|
|
105
|
+
repoPath: path.join(tmp, 'settings.json'),
|
|
106
|
+
localPath: zedPaths.settings,
|
|
107
|
+
label: 'settings.json'
|
|
108
|
+
},
|
|
109
|
+
{
|
|
110
|
+
repoPath: path.join(tmp, 'extensions', 'index.json'),
|
|
111
|
+
localPath: zedPaths.extensions,
|
|
112
|
+
label: 'extensions/index.json'
|
|
113
|
+
}
|
|
114
|
+
];
|
|
115
|
+
for (const file of files) {
|
|
116
|
+
const localExists = await fs.pathExists(file.localPath);
|
|
117
|
+
const remoteFileExists = remoteExists && (await fs.pathExists(file.repoPath));
|
|
118
|
+
if (!localExists && !remoteFileExists) {
|
|
119
|
+
p.log.warn(`${color.bold(file.label)}: not found locally or remotely`);
|
|
120
|
+
continue;
|
|
121
|
+
}
|
|
122
|
+
if (localExists && !remoteFileExists) {
|
|
123
|
+
p.log.warn(`${color.bold(file.label)}: ${color.green('local only')} — not pushed yet`);
|
|
124
|
+
continue;
|
|
125
|
+
}
|
|
126
|
+
if (!localExists && remoteFileExists) {
|
|
127
|
+
p.log.warn(`${color.bold(file.label)}: ${color.cyan('remote only')} — not pulled yet`);
|
|
128
|
+
continue;
|
|
129
|
+
}
|
|
130
|
+
const localContent = await fs.readFile(file.localPath, 'utf-8');
|
|
131
|
+
const remoteContent = await fs.readFile(file.repoPath, 'utf-8');
|
|
132
|
+
if (localContent === remoteContent) {
|
|
133
|
+
p.log.success(`${color.bold(file.label)}: in sync`);
|
|
134
|
+
continue;
|
|
135
|
+
}
|
|
136
|
+
const localMtime = (await fs.stat(file.localPath)).mtime;
|
|
137
|
+
const remoteMtime = (await fs.stat(file.repoPath)).mtime;
|
|
138
|
+
const lastSync = config.lastSync ? new Date(config.lastSync) : null;
|
|
139
|
+
const localChanged = !lastSync || localMtime > lastSync;
|
|
140
|
+
const remoteChanged = !lastSync || remoteMtime > lastSync;
|
|
141
|
+
if (localChanged && !remoteChanged) {
|
|
142
|
+
p.log.warn(`${color.bold(file.label)}: ${color.green('local ahead')} — modified ${color.dim(localMtime.toLocaleString())}`);
|
|
143
|
+
}
|
|
144
|
+
else if (remoteChanged && !localChanged) {
|
|
145
|
+
p.log.warn(`${color.bold(file.label)}: ${color.cyan('remote ahead')} — modified ${color.dim(remoteMtime.toLocaleString())}`);
|
|
146
|
+
}
|
|
147
|
+
else {
|
|
148
|
+
p.log.warn(`${color.bold(file.label)}: ${color.yellow('conflict')} — both changed since last sync`);
|
|
149
|
+
}
|
|
150
|
+
}
|
|
151
|
+
});
|
|
152
|
+
p.outro(`Run ${color.cyan('zedx sync')} to resolve.`);
|
|
153
|
+
}
|
|
78
154
|
// zedx sync init
|
|
79
155
|
export async function syncInit() {
|
|
80
156
|
p.intro(color.bold('zedx sync init'));
|
package/package.json
CHANGED
|
@@ -1,54 +1,56 @@
|
|
|
1
1
|
{
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
2
|
+
"name": "zedx",
|
|
3
|
+
"version": "0.6.0",
|
|
4
|
+
"description": "Boilerplate generator for Zed Edittor extensions.",
|
|
5
|
+
"type": "module",
|
|
6
|
+
"main": "dist/index.js",
|
|
7
|
+
"bin": {
|
|
8
|
+
"zedx": "dist/index.js"
|
|
9
|
+
},
|
|
10
|
+
"files": [
|
|
11
|
+
"dist"
|
|
12
|
+
],
|
|
13
|
+
"keywords": [
|
|
14
|
+
"zed",
|
|
15
|
+
"zed-editor",
|
|
16
|
+
"extension",
|
|
17
|
+
"boilerplate",
|
|
18
|
+
"scaffold"
|
|
19
|
+
],
|
|
20
|
+
"author": "Taha Nejad <taha@noiserandom.com>",
|
|
21
|
+
"repository": {
|
|
22
|
+
"type": "git",
|
|
23
|
+
"url": "https://github.com/tahayvr/zedx.git"
|
|
24
|
+
},
|
|
25
|
+
"homepage": "https://github.com/tahayvr/zedx#readme",
|
|
26
|
+
"license": "Apache-2.0",
|
|
27
|
+
"publishConfig": {
|
|
28
|
+
"access": "public"
|
|
29
|
+
},
|
|
30
|
+
"engines": {
|
|
31
|
+
"node": ">=18"
|
|
32
|
+
},
|
|
33
|
+
"devDependencies": {
|
|
34
|
+
"@types/ejs": "^3.1.5",
|
|
35
|
+
"@types/fs-extra": "^11.0.4",
|
|
36
|
+
"@types/node": "^25.2.3",
|
|
37
|
+
"oxlint": "^1.57.0",
|
|
38
|
+
"tsx": "^4.21.0",
|
|
39
|
+
"typescript": "^5.9.3"
|
|
40
|
+
},
|
|
41
|
+
"dependencies": {
|
|
42
|
+
"@clack/prompts": "^0.10.1",
|
|
43
|
+
"commander": "^14.0.3",
|
|
44
|
+
"ejs": "^4.0.1",
|
|
45
|
+
"fs-extra": "^11.3.3",
|
|
46
|
+
"picocolors": "^1.1.1",
|
|
47
|
+
"simple-git": "^3.33.0"
|
|
48
|
+
},
|
|
49
|
+
"scripts": {
|
|
50
|
+
"build": "tsc && cp -r src/templates dist/",
|
|
51
|
+
"start": "node dist/index.js",
|
|
52
|
+
"dev": "tsx src/index.ts",
|
|
53
|
+
"lint": "oxlint",
|
|
54
|
+
"lint:fix": "oxlint --fix"
|
|
55
|
+
}
|
|
56
|
+
}
|