devsync-ai 0.0.1 → 0.1.0-rc.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.
Files changed (3) hide show
  1. package/README.md +73 -0
  2. package/bin/devsync.js +89 -0
  3. package/package.json +23 -4
package/README.md CHANGED
@@ -3,3 +3,76 @@
3
3
  This package name is reserved for DevSync (https://devsync.ai), a neutral command surface for AI coding agents.
4
4
 
5
5
  It is under development. This 0.0.1 release is a placeholder and contains no functionality.
6
+
7
+ ## Distribution
8
+
9
+ How DevSync ships on npm (decision D12). Nothing here is published by agents; the user publishes.
10
+
11
+ ### Packages
12
+
13
+ | Package | Holds |
14
+ | --- | --- |
15
+ | `devsync-ai` | The `devsync` command: a small JS launcher (`bin/devsync.js`) and nothing else. Lists the four platform packages below as `optionalDependencies`, pinned to its own version. |
16
+ | `devsync-ai-linux-x64` | `bin/devsync` and `bin/devsync-hook` for Linux on x86-64 (`os: ["linux"]`, `cpu: ["x64"]`) |
17
+ | `devsync-ai-linux-arm64` | the same for Linux on ARM64 (`os: ["linux"]`, `cpu: ["arm64"]`) |
18
+ | `devsync-ai-darwin-x64` | the same for macOS on Intel (`os: ["darwin"]`, `cpu: ["x64"]`) |
19
+ | `devsync-ai-darwin-arm64` | the same for macOS on Apple silicon (`os: ["darwin"]`, `cpu: ["arm64"]`) |
20
+
21
+ Every package has the same version; a release publishes all five. Because each platform package declares `os` and `cpu`, npm, pnpm, yarn and bun install only the one that matches the machine and skip the rest without an error.
22
+
23
+ The binaries have no runtime dependencies beyond the system's C library, so a clean machine needs only Node (to run the launcher) and Claude Code.
24
+
25
+ ### How `devsync` finds its binary
26
+
27
+ `npm install -g devsync-ai` puts `devsync` on the PATH, pointing at `bin/devsync.js`. The launcher:
28
+
29
+ 1. maps `process.platform` and `process.arch` to a package name, `devsync-ai-<platform>-<arch>`;
30
+ 2. resolves `<that package>/bin/devsync` with `require.resolve`;
31
+ 3. runs it with the same arguments, stdin, stdout and stderr, and exits with its exit code (or re-raises its signal).
32
+
33
+ The launcher runs the binary from its real path, not a copy or a symlink, because the binary finds things next to itself.
34
+
35
+ ### Where `devsync-hook` lands
36
+
37
+ `devsync-hook` sits next to `devsync` in the platform package's `bin/`. It is not on the PATH. `devsync install-hooks` copies it from beside the running `devsync` to `~/.devsync/bin/devsync-hook` (or `$DEVSYNC_HOME/bin/devsync-hook`) and points Claude Code's hooks there, so upgrading or removing the npm package never breaks a running session's hooks. After an upgrade, run `devsync install-hooks` again to pick up the new hook.
38
+
39
+ ### Errors
40
+
41
+ On a platform with no package (Windows, FreeBSD, Linux on 32-bit ARM, and so on) the launcher prints this and exits 1:
42
+
43
+ ```
44
+ devsync: DevSync supports Linux and macOS (x64, arm64); this is <platform>-<arch>
45
+ ```
46
+
47
+ When the platform is supported but its package is missing (installed with `--omit=optional` or `--no-optional`, or copied between machines), it prints this and exits 1:
48
+
49
+ ```
50
+ devsync: devsync-ai-<platform>-<arch> is not installed. Reinstall without --omit=optional: npm install -g devsync-ai
51
+ ```
52
+
53
+ When the binary is there but can't be run (lost its execute bit, wrong architecture under emulation), it prints the system error with the path, and exits 1:
54
+
55
+ ```
56
+ devsync: can't run <path>: <error>
57
+ ```
58
+
59
+ ### Building, packing, publishing
60
+
61
+ Agents build and pack; only the user publishes.
62
+
63
+ ```
64
+ scripts/build.sh 1.2.3 # dist/<platform>/{devsync,devsync-hook} + dist/SHA256SUMS
65
+ scripts/test-build.sh # missing toolchains, reproducible host build, archs, no local paths
66
+ scripts/pack.sh 1.2.3 # pack/devsync-ai-<platform>-1.2.3.tgz and pack/devsync-ai-1.2.3.tgz
67
+ npm test # the launcher (node --test)
68
+ ```
69
+
70
+ `build.sh` builds the host and the Linux targets; the macOS targets build only on a Mac, because linking them needs Apple's SDK (chrono's local time zone pulls in CoreFoundation). With no platforms named it builds `linux-x64` and `linux-arm64`, plus both `darwin-*` on a Mac. Linux targets other than the host need `cargo-zigbuild` and `zig` (its header says how to add them). A release tag builds all four on GitHub runners, macOS natively on a Mac (`.github/workflows/release.yml`). `pack.sh` checks each binary against `dist/SHA256SUMS` and pins every platform package to exactly the same version.
71
+
72
+ To publish, platform packages first, so `devsync-ai`'s optional dependencies exist when it lands:
73
+
74
+ ```
75
+ cd pack
76
+ for p in linux-x64 linux-arm64 darwin-x64 darwin-arm64; do npm publish devsync-ai-$p-1.2.3.tgz; done
77
+ npm publish devsync-ai-1.2.3.tgz
78
+ ```
package/bin/devsync.js ADDED
@@ -0,0 +1,89 @@
1
+ #!/usr/bin/env node
2
+ // The `devsync` command from npm: finds the binary in the platform package
3
+ // npm installed for this machine (devsync-ai-<platform>-<arch>) and runs
4
+ // it with the same arguments, stdin, stdout and stderr, then exits as it
5
+ // did. See README.md, "Distribution".
6
+ 'use strict';
7
+
8
+ const { spawn } = require('node:child_process');
9
+ const path = require('node:path');
10
+
11
+ const PLATFORMS = {
12
+ 'linux-x64': 'devsync-ai-linux-x64',
13
+ 'linux-arm64': 'devsync-ai-linux-arm64',
14
+ 'darwin-x64': 'devsync-ai-darwin-x64',
15
+ 'darwin-arm64': 'devsync-ai-darwin-arm64',
16
+ };
17
+
18
+ /** The platform package for this platform and arch, or null. */
19
+ function platformPackage(platform, arch) {
20
+ return PLATFORMS[`${platform}-${arch}`] || null;
21
+ }
22
+
23
+ /**
24
+ * The binary to run, as { binary } or { error } with the text to print.
25
+ * `resolve` is require.resolve (tests pass their own).
26
+ */
27
+ function locate(platform, arch, resolve) {
28
+ const pkg = platformPackage(platform, arch);
29
+ if (!pkg) {
30
+ return {
31
+ error: `devsync: DevSync supports Linux and macOS (x64, arm64); this is ${platform}-${arch}`,
32
+ };
33
+ }
34
+ try {
35
+ // The package's own folder, then its binary: the real path, not a
36
+ // symlink, because devsync finds devsync-hook next to itself.
37
+ const dir = path.dirname(resolve(`${pkg}/package.json`));
38
+ return { binary: path.join(dir, 'bin', 'devsync') };
39
+ } catch {
40
+ return {
41
+ error: `devsync: ${pkg} is not installed. Reinstall without --omit=optional: npm install -g devsync-ai`,
42
+ };
43
+ }
44
+ }
45
+
46
+ /** Run `binary` with `args`, passing signals on, and exit as it does. */
47
+ function run(binary, args) {
48
+ const child = spawn(binary, args, { stdio: 'inherit' });
49
+ const forward = ['SIGINT', 'SIGTERM', 'SIGHUP', 'SIGQUIT'];
50
+ const handlers = forward.map((sig) => {
51
+ const h = () => {
52
+ try {
53
+ child.kill(sig);
54
+ } catch {
55
+ // Already gone: its exit is on the way.
56
+ }
57
+ };
58
+ process.on(sig, h);
59
+ return [sig, h];
60
+ });
61
+ child.on('error', (e) => {
62
+ process.stderr.write(`devsync: can't run ${binary}: ${e.message}\n`);
63
+ process.exit(1);
64
+ });
65
+ child.on('exit', (code, signal) => {
66
+ for (const [sig, h] of handlers) process.removeListener(sig, h);
67
+ if (signal) {
68
+ // Die of the same signal, so the shell sees what the binary saw.
69
+ process.kill(process.pid, signal);
70
+ return;
71
+ }
72
+ process.exit(code === null ? 1 : code);
73
+ });
74
+ }
75
+
76
+ function main() {
77
+ const found = locate(process.platform, process.arch, require.resolve);
78
+ if (found.error) {
79
+ process.stderr.write(`${found.error}\n`);
80
+ process.exit(1);
81
+ }
82
+ run(found.binary, process.argv.slice(2));
83
+ }
84
+
85
+ module.exports = { PLATFORMS, platformPackage, locate };
86
+
87
+ if (require.main === module) {
88
+ main();
89
+ }
package/package.json CHANGED
@@ -1,8 +1,27 @@
1
1
  {
2
2
  "name": "devsync-ai",
3
- "version": "0.0.1",
4
- "description": "Name reservation for DevSync (devsync.ai): a neutral command surface for AI coding agents. Under development.",
3
+ "version": "0.1.0-rc.2",
4
+ "description": "DevSync (devsync.ai): one terminal screen over your coding-agent sessions, and the roadmap they work from.",
5
5
  "homepage": "https://devsync.ai",
6
- "keywords": ["devsync", "ai", "coding-agents"],
7
- "files": ["README.md"]
6
+ "keywords": [
7
+ "devsync",
8
+ "ai",
9
+ "coding-agents"
10
+ ],
11
+ "bin": {
12
+ "devsync": "bin/devsync.js"
13
+ },
14
+ "files": [
15
+ "bin/devsync.js",
16
+ "README.md"
17
+ ],
18
+ "engines": {
19
+ "node": ">=18"
20
+ },
21
+ "optionalDependencies": {
22
+ "devsync-ai-linux-x64": "0.1.0-rc.2",
23
+ "devsync-ai-linux-arm64": "0.1.0-rc.2",
24
+ "devsync-ai-darwin-x64": "0.1.0-rc.2",
25
+ "devsync-ai-darwin-arm64": "0.1.0-rc.2"
26
+ }
8
27
  }