@tinyrack/devsync 1.1.0 → 1.2.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 (216) hide show
  1. package/README.md +230 -62
  2. package/dist/cli/base-command.d.ts +14 -0
  3. package/dist/cli/base-command.d.ts.map +1 -0
  4. package/dist/cli/base-command.js +22 -0
  5. package/dist/cli/base-command.js.map +1 -0
  6. package/dist/cli/commands/dir.d.ts +8 -0
  7. package/dist/cli/commands/dir.d.ts.map +1 -0
  8. package/dist/cli/commands/dir.js +16 -0
  9. package/dist/cli/commands/dir.js.map +1 -0
  10. package/dist/cli/commands/doctor.d.ts +8 -0
  11. package/dist/cli/commands/doctor.d.ts.map +1 -0
  12. package/dist/cli/commands/doctor.js +18 -0
  13. package/dist/cli/commands/doctor.js.map +1 -0
  14. package/dist/cli/commands/index.d.ts +23 -0
  15. package/dist/cli/commands/index.d.ts.map +1 -0
  16. package/dist/cli/commands/index.js +23 -0
  17. package/dist/cli/commands/index.js.map +1 -0
  18. package/dist/cli/commands/init.d.ts +15 -0
  19. package/dist/cli/commands/init.d.ts.map +1 -0
  20. package/dist/cli/commands/init.js +43 -0
  21. package/dist/cli/commands/init.js.map +1 -0
  22. package/dist/cli/commands/machine/list.d.ts +7 -0
  23. package/dist/cli/commands/machine/list.d.ts.map +1 -0
  24. package/dist/cli/commands/machine/list.js +12 -0
  25. package/dist/cli/commands/machine/list.js.map +1 -0
  26. package/dist/cli/commands/machine/use.d.ts +11 -0
  27. package/dist/cli/commands/machine/use.d.ts.map +1 -0
  28. package/dist/cli/commands/machine/use.js +28 -0
  29. package/dist/cli/commands/machine/use.js.map +1 -0
  30. package/dist/cli/commands/pull.d.ts +12 -0
  31. package/dist/cli/commands/pull.d.ts.map +1 -0
  32. package/dist/cli/commands/pull.js +34 -0
  33. package/dist/cli/commands/pull.js.map +1 -0
  34. package/dist/cli/commands/push.d.ts +12 -0
  35. package/dist/cli/commands/push.d.ts.map +1 -0
  36. package/dist/cli/commands/push.js +34 -0
  37. package/dist/cli/commands/push.js.map +1 -0
  38. package/dist/cli/commands/status.d.ts +11 -0
  39. package/dist/cli/commands/status.d.ts.map +1 -0
  40. package/dist/cli/commands/status.js +27 -0
  41. package/dist/cli/commands/status.js.map +1 -0
  42. package/dist/cli/commands/track.d.ts +16 -0
  43. package/dist/cli/commands/track.d.ts.map +1 -0
  44. package/dist/cli/commands/track.js +82 -0
  45. package/dist/cli/commands/track.js.map +1 -0
  46. package/dist/cli/commands/untrack.d.ts +11 -0
  47. package/dist/cli/commands/untrack.d.ts.map +1 -0
  48. package/dist/cli/commands/untrack.js +28 -0
  49. package/dist/cli/commands/untrack.js.map +1 -0
  50. package/dist/config/global-config.d.ts +21 -0
  51. package/dist/config/global-config.d.ts.map +1 -0
  52. package/dist/config/global-config.js +106 -0
  53. package/dist/config/global-config.js.map +1 -0
  54. package/dist/config/sync.d.ts +96 -0
  55. package/dist/config/sync.d.ts.map +1 -0
  56. package/dist/config/sync.js +412 -0
  57. package/dist/config/sync.js.map +1 -0
  58. package/dist/config/xdg.d.ts +11 -0
  59. package/dist/config/xdg.d.ts.map +1 -0
  60. package/dist/config/xdg.js +79 -0
  61. package/dist/config/xdg.js.map +1 -0
  62. package/dist/index.d.ts +3 -0
  63. package/dist/index.d.ts.map +1 -0
  64. package/{src/index.ts → dist/index.js} +1 -1
  65. package/dist/index.js.map +1 -0
  66. package/dist/lib/file-mode.d.ts +3 -0
  67. package/dist/lib/file-mode.d.ts.map +1 -0
  68. package/dist/lib/file-mode.js +7 -0
  69. package/dist/lib/file-mode.js.map +1 -0
  70. package/dist/lib/output.d.ts +31 -0
  71. package/dist/lib/output.d.ts.map +1 -0
  72. package/dist/lib/output.js +198 -0
  73. package/dist/lib/output.js.map +1 -0
  74. package/dist/lib/path.d.ts +5 -0
  75. package/dist/lib/path.d.ts.map +1 -0
  76. package/dist/lib/path.js +25 -0
  77. package/dist/lib/path.js.map +1 -0
  78. package/dist/lib/string.d.ts +2 -0
  79. package/dist/lib/string.d.ts.map +1 -0
  80. package/dist/lib/string.js +4 -0
  81. package/dist/lib/string.js.map +1 -0
  82. package/dist/lib/validation.d.ts +3 -0
  83. package/dist/lib/validation.d.ts.map +1 -0
  84. package/dist/lib/validation.js +9 -0
  85. package/dist/lib/validation.js.map +1 -0
  86. package/dist/services/add.d.ts +20 -0
  87. package/dist/services/add.d.ts.map +1 -0
  88. package/dist/services/add.js +161 -0
  89. package/dist/services/add.js.map +1 -0
  90. package/dist/services/config-file.d.ts +30 -0
  91. package/dist/services/config-file.d.ts.map +1 -0
  92. package/dist/services/config-file.js +34 -0
  93. package/dist/services/config-file.js.map +1 -0
  94. package/dist/services/crypto.d.ts +9 -0
  95. package/dist/services/crypto.d.ts.map +1 -0
  96. package/dist/services/crypto.js +75 -0
  97. package/dist/services/crypto.js.map +1 -0
  98. package/dist/services/doctor.d.ts +16 -0
  99. package/dist/services/doctor.d.ts.map +1 -0
  100. package/dist/services/doctor.js +84 -0
  101. package/dist/services/doctor.js.map +1 -0
  102. package/dist/services/error.d.ts +14 -0
  103. package/dist/services/error.d.ts.map +1 -0
  104. package/dist/services/error.js +38 -0
  105. package/dist/services/error.js.map +1 -0
  106. package/dist/services/filesystem.d.ts +15 -0
  107. package/dist/services/filesystem.d.ts.map +1 -0
  108. package/dist/services/filesystem.js +113 -0
  109. package/dist/services/filesystem.js.map +1 -0
  110. package/dist/services/forget.d.ts +14 -0
  111. package/dist/services/forget.d.ts.map +1 -0
  112. package/dist/services/forget.js +124 -0
  113. package/dist/services/forget.js.map +1 -0
  114. package/dist/services/git.d.ts +10 -0
  115. package/dist/services/git.d.ts.map +1 -0
  116. package/dist/services/git.js +57 -0
  117. package/dist/services/git.js.map +1 -0
  118. package/dist/services/init.d.ts +19 -0
  119. package/dist/services/init.d.ts.map +1 -0
  120. package/dist/services/init.js +203 -0
  121. package/dist/services/init.js.map +1 -0
  122. package/dist/services/local-materialization.d.ts +28 -0
  123. package/dist/services/local-materialization.d.ts.map +1 -0
  124. package/dist/services/local-materialization.js +262 -0
  125. package/dist/services/local-materialization.js.map +1 -0
  126. package/dist/services/local-snapshot.d.ts +25 -0
  127. package/dist/services/local-snapshot.d.ts.map +1 -0
  128. package/dist/services/local-snapshot.js +93 -0
  129. package/dist/services/local-snapshot.js.map +1 -0
  130. package/dist/services/machine.d.ts +40 -0
  131. package/dist/services/machine.d.ts.map +1 -0
  132. package/dist/services/machine.js +113 -0
  133. package/dist/services/machine.js.map +1 -0
  134. package/dist/services/paths.d.ts +12 -0
  135. package/dist/services/paths.d.ts.map +1 -0
  136. package/dist/services/paths.js +71 -0
  137. package/dist/services/paths.js.map +1 -0
  138. package/dist/services/pull.d.ts +28 -0
  139. package/dist/services/pull.d.ts.map +1 -0
  140. package/dist/services/pull.js +67 -0
  141. package/dist/services/pull.js.map +1 -0
  142. package/dist/services/push.d.ts +35 -0
  143. package/dist/services/push.d.ts.map +1 -0
  144. package/dist/services/push.js +96 -0
  145. package/dist/services/push.js.map +1 -0
  146. package/dist/services/repo-artifacts.d.ts +52 -0
  147. package/dist/services/repo-artifacts.d.ts.map +1 -0
  148. package/dist/services/repo-artifacts.js +251 -0
  149. package/dist/services/repo-artifacts.js.map +1 -0
  150. package/dist/services/repo-snapshot.d.ts +6 -0
  151. package/dist/services/repo-snapshot.d.ts.map +1 -0
  152. package/dist/services/repo-snapshot.js +163 -0
  153. package/dist/services/repo-snapshot.js.map +1 -0
  154. package/dist/services/runtime.d.ts +40 -0
  155. package/dist/services/runtime.d.ts.map +1 -0
  156. package/dist/services/runtime.js +71 -0
  157. package/dist/services/runtime.js.map +1 -0
  158. package/dist/services/set.d.ts +38 -0
  159. package/dist/services/set.d.ts.map +1 -0
  160. package/dist/services/set.js +184 -0
  161. package/dist/services/set.js.map +1 -0
  162. package/dist/services/status.d.ts +30 -0
  163. package/dist/services/status.d.ts.map +1 -0
  164. package/dist/services/status.js +35 -0
  165. package/dist/services/status.js.map +1 -0
  166. package/package.json +15 -7
  167. package/src/cli/commands/add.ts +0 -40
  168. package/src/cli/commands/cd.ts +0 -80
  169. package/src/cli/commands/doctor.ts +0 -20
  170. package/src/cli/commands/forget.ts +0 -32
  171. package/src/cli/commands/index.ts +0 -23
  172. package/src/cli/commands/init.ts +0 -43
  173. package/src/cli/commands/list.ts +0 -17
  174. package/src/cli/commands/pull.ts +0 -31
  175. package/src/cli/commands/push.ts +0 -31
  176. package/src/cli/commands/set.ts +0 -47
  177. package/src/cli/commands/status.ts +0 -18
  178. package/src/cli/sync-output.test.ts +0 -173
  179. package/src/cli/sync-output.ts +0 -200
  180. package/src/config/sync.test.ts +0 -609
  181. package/src/config/sync.ts +0 -572
  182. package/src/config/xdg.ts +0 -138
  183. package/src/lib/string.test.ts +0 -13
  184. package/src/lib/string.ts +0 -3
  185. package/src/lib/validation.test.ts +0 -32
  186. package/src/lib/validation.ts +0 -11
  187. package/src/services/add.ts +0 -178
  188. package/src/services/config-file.test.ts +0 -161
  189. package/src/services/config-file.ts +0 -101
  190. package/src/services/crypto.test.ts +0 -132
  191. package/src/services/crypto.ts +0 -83
  192. package/src/services/doctor.ts +0 -142
  193. package/src/services/error.ts +0 -6
  194. package/src/services/filesystem.test.ts +0 -171
  195. package/src/services/filesystem.ts +0 -183
  196. package/src/services/forget.ts +0 -261
  197. package/src/services/git.test.ts +0 -83
  198. package/src/services/git.ts +0 -74
  199. package/src/services/init.test.ts +0 -109
  200. package/src/services/init.ts +0 -244
  201. package/src/services/list.ts +0 -63
  202. package/src/services/local-materialization.ts +0 -421
  203. package/src/services/local-snapshot.ts +0 -173
  204. package/src/services/paths.test.ts +0 -74
  205. package/src/services/paths.ts +0 -98
  206. package/src/services/pull.ts +0 -144
  207. package/src/services/push.ts +0 -168
  208. package/src/services/repo-artifacts.ts +0 -262
  209. package/src/services/repo-snapshot.ts +0 -197
  210. package/src/services/runtime.ts +0 -57
  211. package/src/services/set.ts +0 -383
  212. package/src/services/status.ts +0 -57
  213. package/src/services/sync.dry-run.test.ts +0 -179
  214. package/src/services/sync.runtime.test.ts +0 -756
  215. package/src/services/sync.service.test.ts +0 -1169
  216. package/src/test/helpers/sync-fixture.ts +0 -47
@@ -0,0 +1,38 @@
1
+ import { readSyncConfig, type SyncMode } from "#app/config/sync.js";
2
+ import { type SyncContext } from "./runtime.js";
3
+ export type SyncSetRequest = Readonly<{
4
+ state: SyncMode;
5
+ target: string;
6
+ }>;
7
+ type SyncSetAction = "added" | "removed" | "unchanged" | "updated";
8
+ type SyncSetReason = "already-set";
9
+ export type SyncSetResult = Readonly<{
10
+ action: SyncSetAction;
11
+ configPath: string;
12
+ entryRepoPath: string;
13
+ localPath: string;
14
+ mode: SyncMode;
15
+ repoPath: string;
16
+ reason?: SyncSetReason;
17
+ syncDirectory: string;
18
+ }>;
19
+ export declare const resolveSetTarget: (target: string, config: Awaited<ReturnType<typeof readSyncConfig>>, context: Pick<SyncContext, "cwd" | "environment" | "paths">) => Promise<{
20
+ entry: Readonly<{
21
+ configuredLocalPath: string;
22
+ kind: import("#app/config/sync.js").SyncConfigEntryKind;
23
+ localPath: string;
24
+ machines: readonly string[];
25
+ machinesExplicit: boolean;
26
+ mode: SyncMode;
27
+ modeExplicit: boolean;
28
+ name: string;
29
+ repoPath: string;
30
+ }>;
31
+ localPath: string;
32
+ relativePath: string;
33
+ repoPath: string;
34
+ stats: import("node:fs").Stats | undefined;
35
+ }>;
36
+ export declare const setSyncTargetMode: (request: SyncSetRequest, context: SyncContext) => Promise<SyncSetResult>;
37
+ export {};
38
+ //# sourceMappingURL=set.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"set.d.ts","sourceRoot":"","sources":["../../src/services/set.ts"],"names":[],"mappings":"AAEA,OAAO,EAGL,cAAc,EAEd,KAAK,QAAQ,EACd,MAAM,qBAAqB,CAAC;AAgB7B,OAAO,EAAwB,KAAK,WAAW,EAAE,MAAM,cAAc,CAAC;AAEtE,MAAM,MAAM,cAAc,GAAG,QAAQ,CAAC;IACpC,KAAK,EAAE,QAAQ,CAAC;IAChB,MAAM,EAAE,MAAM,CAAC;CAChB,CAAC,CAAC;AAEH,KAAK,aAAa,GAAG,OAAO,GAAG,SAAS,GAAG,WAAW,GAAG,SAAS,CAAC;AACnE,KAAK,aAAa,GAAG,aAAa,CAAC;AAEnC,MAAM,MAAM,aAAa,GAAG,QAAQ,CAAC;IACnC,MAAM,EAAE,aAAa,CAAC;IACtB,UAAU,EAAE,MAAM,CAAC;IACnB,aAAa,EAAE,MAAM,CAAC;IACtB,SAAS,EAAE,MAAM,CAAC;IAClB,IAAI,EAAE,QAAQ,CAAC;IACf,QAAQ,EAAE,MAAM,CAAC;IACjB,MAAM,CAAC,EAAE,aAAa,CAAC;IACvB,aAAa,EAAE,MAAM,CAAC;CACvB,CAAC,CAAC;AAUH,eAAO,MAAM,gBAAgB,GAC3B,QAAQ,MAAM,EACd,QAAQ,OAAO,CAAC,UAAU,CAAC,OAAO,cAAc,CAAC,CAAC,EAClD,SAAS,IAAI,CAAC,WAAW,EAAE,KAAK,GAAG,aAAa,GAAG,OAAO,CAAC;;;;;;;;;;;;;;;;EAuI5D,CAAC;AAEF,eAAO,MAAM,iBAAiB,GAC5B,SAAS,cAAc,EACvB,SAAS,WAAW,KACnB,OAAO,CAAC,aAAa,CAgHvB,CAAC"}
@@ -0,0 +1,184 @@
1
+ import { join } from "node:path";
2
+ import { findOwningSyncEntry, readSyncConfig, resolveEntryRelativeRepoPath, } from "#app/config/sync.js";
3
+ import { createSyncConfigDocument, writeValidatedSyncConfig, } from "./config-file.js";
4
+ import { DevsyncError } from "./error.js";
5
+ import { getPathStats } from "./filesystem.js";
6
+ import { buildConfiguredHomeLocalPath, buildRepoPathWithinRoot, isExplicitLocalPath, resolveCommandTargetPath, tryBuildRepoPathWithinRoot, tryNormalizeRepoPathInput, } from "./paths.js";
7
+ import { ensureSyncRepository } from "./runtime.js";
8
+ const computeLocalPath = (entry, repoPath) => {
9
+ const relativePath = resolveEntryRelativeRepoPath(entry, repoPath);
10
+ if (relativePath === undefined || relativePath === "") {
11
+ return entry.localPath;
12
+ }
13
+ return join(entry.localPath, ...relativePath.split("/"));
14
+ };
15
+ export const resolveSetTarget = async (target, config, context) => {
16
+ const trimmedTarget = target.trim();
17
+ if (trimmedTarget.length === 0) {
18
+ throw new DevsyncError("Target path is required.", {
19
+ code: "TARGET_REQUIRED",
20
+ hint: "Pass a tracked path, for example 'devsync mode ~/.ssh/id_ed25519 secret'.",
21
+ });
22
+ }
23
+ const homeDirectory = context.paths.homeDirectory;
24
+ const explicit = isExplicitLocalPath(trimmedTarget);
25
+ const localTargetPath = resolveCommandTargetPath(trimmedTarget, context.environment, context.cwd);
26
+ const localRepoPath = explicit
27
+ ? buildRepoPathWithinRoot(localTargetPath, homeDirectory, "Sync set target")
28
+ : tryBuildRepoPathWithinRoot(localTargetPath, homeDirectory, "Sync set target");
29
+ // Phase 1: Try resolving as a local path
30
+ if (localRepoPath !== undefined) {
31
+ const localStats = await getPathStats(localTargetPath);
32
+ if (explicit && localStats === undefined) {
33
+ throw new DevsyncError("Sync set target does not exist.", {
34
+ code: "TARGET_NOT_FOUND",
35
+ details: [`Target: ${localTargetPath}`],
36
+ hint: "Use an existing local path, or pass a repository path inside a tracked directory.",
37
+ });
38
+ }
39
+ const exactEntry = config.entries.find((e) => e.repoPath === localRepoPath);
40
+ if (exactEntry !== undefined) {
41
+ return {
42
+ entry: exactEntry,
43
+ localPath: localTargetPath,
44
+ relativePath: "",
45
+ repoPath: localRepoPath,
46
+ stats: localStats,
47
+ };
48
+ }
49
+ const parentEntry = findOwningSyncEntry(config, localRepoPath);
50
+ if (parentEntry?.kind === "directory") {
51
+ const relativePath = resolveEntryRelativeRepoPath(parentEntry, localRepoPath);
52
+ if (relativePath !== undefined) {
53
+ return {
54
+ entry: parentEntry,
55
+ localPath: localTargetPath,
56
+ relativePath,
57
+ repoPath: localRepoPath,
58
+ stats: localStats,
59
+ };
60
+ }
61
+ }
62
+ if (explicit) {
63
+ throw new DevsyncError("Local set target is not inside a tracked directory entry.", {
64
+ code: "TARGET_NOT_TRACKED",
65
+ details: [`Target: ${trimmedTarget}`],
66
+ hint: "Track the parent directory first with 'devsync track', then use 'devsync mode' on the child path.",
67
+ });
68
+ }
69
+ }
70
+ // Phase 2: Fallback to repo path resolution
71
+ const repoPath = tryNormalizeRepoPathInput(trimmedTarget);
72
+ if (repoPath === undefined) {
73
+ throw new DevsyncError("Sync set target is not a valid local or repository path.", {
74
+ code: "INVALID_SET_TARGET",
75
+ details: [`Target: ${trimmedTarget}`],
76
+ hint: "Use an absolute path, a cwd-relative path, or a repository path like '.config/tool/file.json'.",
77
+ });
78
+ }
79
+ const exactEntry = config.entries.find((e) => e.repoPath === repoPath);
80
+ if (exactEntry !== undefined) {
81
+ const localPath = computeLocalPath(exactEntry, repoPath);
82
+ return {
83
+ entry: exactEntry,
84
+ localPath,
85
+ relativePath: "",
86
+ repoPath,
87
+ stats: await getPathStats(localPath),
88
+ };
89
+ }
90
+ const entry = findOwningSyncEntry(config, repoPath);
91
+ const relativePath = entry?.kind === "directory"
92
+ ? resolveEntryRelativeRepoPath(entry, repoPath)
93
+ : undefined;
94
+ if (entry === undefined || relativePath === undefined) {
95
+ throw new DevsyncError("Repository set target is not inside a tracked directory entry.", {
96
+ code: "TARGET_NOT_TRACKED",
97
+ details: [`Target: ${trimmedTarget}`],
98
+ hint: "Use a repository path under an existing tracked directory, or track it first with 'devsync track'.",
99
+ });
100
+ }
101
+ const localPath = computeLocalPath(entry, repoPath);
102
+ return {
103
+ entry,
104
+ localPath,
105
+ relativePath,
106
+ repoPath,
107
+ stats: await getPathStats(localPath),
108
+ };
109
+ };
110
+ export const setSyncTargetMode = async (request, context) => {
111
+ await ensureSyncRepository(context);
112
+ const config = await readSyncConfig(context.paths.syncDirectory, context.environment);
113
+ const target = await resolveSetTarget(request.target, config, context);
114
+ const buildResult = (action, extras) => ({
115
+ action,
116
+ configPath: context.paths.configPath,
117
+ entryRepoPath: target.entry.repoPath,
118
+ localPath: target.localPath,
119
+ mode: request.state,
120
+ repoPath: target.repoPath,
121
+ syncDirectory: context.paths.syncDirectory,
122
+ ...extras,
123
+ });
124
+ if (target.relativePath === "") {
125
+ const action = target.entry.mode === request.state ? "unchanged" : "updated";
126
+ const nextConfig = createSyncConfigDocument({
127
+ ...config,
128
+ entries: config.entries.map((entry) => {
129
+ if (entry.repoPath !== target.entry.repoPath) {
130
+ return entry;
131
+ }
132
+ return {
133
+ ...entry,
134
+ mode: request.state,
135
+ };
136
+ }),
137
+ });
138
+ if (action !== "unchanged") {
139
+ await writeValidatedSyncConfig(context.paths.syncDirectory, nextConfig, context.environment);
140
+ }
141
+ return buildResult(action);
142
+ }
143
+ const childKind = target.stats?.isDirectory() ? "directory" : "file";
144
+ const childRepoPath = target.repoPath;
145
+ const childConfiguredLocalPath = buildConfiguredHomeLocalPath(childRepoPath);
146
+ const existingChild = config.entries.find((e) => e.repoPath === childRepoPath);
147
+ if (existingChild !== undefined) {
148
+ if (existingChild.mode === request.state) {
149
+ return buildResult("unchanged", { reason: "already-set" });
150
+ }
151
+ const nextConfig = createSyncConfigDocument({
152
+ ...config,
153
+ entries: config.entries.map((entry) => {
154
+ if (entry.repoPath !== childRepoPath) {
155
+ return entry;
156
+ }
157
+ return { ...entry, mode: request.state };
158
+ }),
159
+ });
160
+ await writeValidatedSyncConfig(context.paths.syncDirectory, nextConfig, context.environment);
161
+ return buildResult("updated");
162
+ }
163
+ if (request.state === target.entry.mode) {
164
+ return buildResult("unchanged");
165
+ }
166
+ const newEntry = {
167
+ configuredLocalPath: childConfiguredLocalPath,
168
+ kind: childKind,
169
+ localPath: target.localPath,
170
+ machines: [],
171
+ machinesExplicit: false,
172
+ mode: request.state,
173
+ modeExplicit: true,
174
+ name: childRepoPath,
175
+ repoPath: childRepoPath,
176
+ };
177
+ const nextConfig = createSyncConfigDocument({
178
+ ...config,
179
+ entries: [...config.entries, newEntry],
180
+ });
181
+ await writeValidatedSyncConfig(context.paths.syncDirectory, nextConfig, context.environment);
182
+ return buildResult("added");
183
+ };
184
+ //# sourceMappingURL=set.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"set.js","sourceRoot":"","sources":["../../src/services/set.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,30 @@
1
+ import type { SyncConfigEntryKind, SyncMode } from "#app/config/sync.js";
2
+ import { buildPullResultFromPlan } from "./pull.js";
3
+ import { buildPushResultFromPlan } from "./push.js";
4
+ import { type SyncContext } from "./runtime.js";
5
+ export type SyncStatusEntry = Readonly<{
6
+ kind: SyncConfigEntryKind;
7
+ localPath: string;
8
+ machines: readonly string[];
9
+ mode: SyncMode;
10
+ name: string;
11
+ repoPath: string;
12
+ }>;
13
+ export type SyncStatusResult = Readonly<{
14
+ activeMachine?: string;
15
+ configPath: string;
16
+ entries: readonly SyncStatusEntry[];
17
+ entryCount: number;
18
+ pull: ReturnType<typeof buildPullResultFromPlan> & {
19
+ preview: readonly string[];
20
+ };
21
+ push: ReturnType<typeof buildPushResultFromPlan> & {
22
+ preview: readonly string[];
23
+ };
24
+ recipientCount: number;
25
+ syncDirectory: string;
26
+ }>;
27
+ export declare const getSyncStatus: (context: SyncContext, options?: Readonly<{
28
+ machine?: string;
29
+ }>) => Promise<SyncStatusResult>;
30
+ //# sourceMappingURL=status.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"status.d.ts","sourceRoot":"","sources":["../../src/services/status.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,mBAAmB,EAAE,QAAQ,EAAE,MAAM,qBAAqB,CAAC;AAEzE,OAAO,EAGL,uBAAuB,EACxB,MAAM,WAAW,CAAC;AACnB,OAAO,EAGL,uBAAuB,EACxB,MAAM,WAAW,CAAC;AACnB,OAAO,EAGL,KAAK,WAAW,EACjB,MAAM,cAAc,CAAC;AAEtB,MAAM,MAAM,eAAe,GAAG,QAAQ,CAAC;IACrC,IAAI,EAAE,mBAAmB,CAAC;IAC1B,SAAS,EAAE,MAAM,CAAC;IAClB,QAAQ,EAAE,SAAS,MAAM,EAAE,CAAC;IAC5B,IAAI,EAAE,QAAQ,CAAC;IACf,IAAI,EAAE,MAAM,CAAC;IACb,QAAQ,EAAE,MAAM,CAAC;CAClB,CAAC,CAAC;AAEH,MAAM,MAAM,gBAAgB,GAAG,QAAQ,CAAC;IACtC,aAAa,CAAC,EAAE,MAAM,CAAC;IACvB,UAAU,EAAE,MAAM,CAAC;IACnB,OAAO,EAAE,SAAS,eAAe,EAAE,CAAC;IACpC,UAAU,EAAE,MAAM,CAAC;IACnB,IAAI,EAAE,UAAU,CAAC,OAAO,uBAAuB,CAAC,GAAG;QACjD,OAAO,EAAE,SAAS,MAAM,EAAE,CAAC;KAC5B,CAAC;IACF,IAAI,EAAE,UAAU,CAAC,OAAO,uBAAuB,CAAC,GAAG;QACjD,OAAO,EAAE,SAAS,MAAM,EAAE,CAAC;KAC5B,CAAC;IACF,cAAc,EAAE,MAAM,CAAC;IACvB,aAAa,EAAE,MAAM,CAAC;CACvB,CAAC,CAAC;AAEH,eAAO,MAAM,aAAa,GACxB,SAAS,WAAW,EACpB,UAAS,QAAQ,CAAC;IAChB,OAAO,CAAC,EAAE,MAAM,CAAC;CAClB,CAAM,KACN,OAAO,CAAC,gBAAgB,CAmC1B,CAAC"}
@@ -0,0 +1,35 @@
1
+ import { buildPullPlan, buildPullPlanPreview, buildPullResultFromPlan, } from "./pull.js";
2
+ import { buildPushPlan, buildPushPlanPreview, buildPushResultFromPlan, } from "./push.js";
3
+ import { ensureSyncRepository, loadSyncConfig, } from "./runtime.js";
4
+ export const getSyncStatus = async (context, options = {}) => {
5
+ await ensureSyncRepository(context);
6
+ const { effectiveConfig, fullConfig } = await loadSyncConfig(context, options);
7
+ const pushPlan = await buildPushPlan(effectiveConfig, context);
8
+ const pullPlan = await buildPullPlan(effectiveConfig, context);
9
+ return {
10
+ ...(effectiveConfig.activeMachine === undefined
11
+ ? {}
12
+ : { activeMachine: effectiveConfig.activeMachine }),
13
+ configPath: context.paths.configPath,
14
+ entries: fullConfig.entries.map((entry) => ({
15
+ kind: entry.kind,
16
+ localPath: entry.localPath,
17
+ machines: entry.machines,
18
+ mode: entry.mode,
19
+ name: entry.name,
20
+ repoPath: entry.repoPath,
21
+ })),
22
+ entryCount: fullConfig.entries.length,
23
+ pull: {
24
+ ...buildPullResultFromPlan(pullPlan, context, true),
25
+ preview: buildPullPlanPreview(pullPlan),
26
+ },
27
+ push: {
28
+ ...buildPushResultFromPlan(pushPlan, context, true),
29
+ preview: buildPushPlanPreview(pushPlan),
30
+ },
31
+ recipientCount: effectiveConfig.age.recipients.length,
32
+ syncDirectory: context.paths.syncDirectory,
33
+ };
34
+ };
35
+ //# sourceMappingURL=status.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"status.js","sourceRoot":"","sources":["../../src/services/status.ts"],"names":[],"mappings":"AAEA,OAAO,EACL,aAAa,EACb,oBAAoB,EACpB,uBAAuB,GACxB,MAAM,WAAW,CAAC;AACnB,OAAO,EACL,aAAa,EACb,oBAAoB,EACpB,uBAAuB,GACxB,MAAM,WAAW,CAAC;AACnB,OAAO,EACL,oBAAoB,EACpB,cAAc,GAEf,MAAM,cAAc,CAAC;AA0BtB,MAAM,CAAC,MAAM,aAAa,GAAG,KAAK,EAChC,OAAoB,EACpB,UAEK,EAAE,EACoB,EAAE;IAC7B,MAAM,oBAAoB,CAAC,OAAO,CAAC,CAAC;IAEpC,MAAM,EAAE,eAAe,EAAE,UAAU,EAAE,GAAG,MAAM,cAAc,CAC1D,OAAO,EACP,OAAO,CACR,CAAC;IACF,MAAM,QAAQ,GAAG,MAAM,aAAa,CAAC,eAAe,EAAE,OAAO,CAAC,CAAC;IAC/D,MAAM,QAAQ,GAAG,MAAM,aAAa,CAAC,eAAe,EAAE,OAAO,CAAC,CAAC;IAE/D,OAAO;QACL,GAAG,CAAC,eAAe,CAAC,aAAa,KAAK,SAAS;YAC7C,CAAC,CAAC,EAAE;YACJ,CAAC,CAAC,EAAE,aAAa,EAAE,eAAe,CAAC,aAAa,EAAE,CAAC;QACrD,UAAU,EAAE,OAAO,CAAC,KAAK,CAAC,UAAU;QACpC,OAAO,EAAE,UAAU,CAAC,OAAO,CAAC,GAAG,CAAC,CAAC,KAAK,EAAE,EAAE,CAAC,CAAC;YAC1C,IAAI,EAAE,KAAK,CAAC,IAAI;YAChB,SAAS,EAAE,KAAK,CAAC,SAAS;YAC1B,QAAQ,EAAE,KAAK,CAAC,QAAQ;YACxB,IAAI,EAAE,KAAK,CAAC,IAAI;YAChB,IAAI,EAAE,KAAK,CAAC,IAAI;YAChB,QAAQ,EAAE,KAAK,CAAC,QAAQ;SACzB,CAAC,CAAC;QACH,UAAU,EAAE,UAAU,CAAC,OAAO,CAAC,MAAM;QACrC,IAAI,EAAE;YACJ,GAAG,uBAAuB,CAAC,QAAQ,EAAE,OAAO,EAAE,IAAI,CAAC;YACnD,OAAO,EAAE,oBAAoB,CAAC,QAAQ,CAAC;SACxC;QACD,IAAI,EAAE;YACJ,GAAG,uBAAuB,CAAC,QAAQ,EAAE,OAAO,EAAE,IAAI,CAAC;YACnD,OAAO,EAAE,oBAAoB,CAAC,QAAQ,CAAC;SACxC;QACD,cAAc,EAAE,eAAe,CAAC,GAAG,CAAC,UAAU,CAAC,MAAM;QACrD,aAAa,EAAE,OAAO,CAAC,KAAK,CAAC,aAAa;KAC3C,CAAC;AACJ,CAAC,CAAC"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@tinyrack/devsync",
3
- "version": "1.1.0",
3
+ "version": "1.2.2",
4
4
  "description": "A personal CLI tool for git-backed configuration sync.",
5
5
  "type": "module",
6
6
  "license": "MIT",
@@ -24,22 +24,25 @@
24
24
  "devsync"
25
25
  ],
26
26
  "imports": {
27
- "#app/*": "./src/*"
27
+ "#app/*.js": "./dist/*.js"
28
28
  },
29
29
  "bin": {
30
- "devsync": "./src/index.ts"
30
+ "devsync": "./dist/index.js"
31
31
  },
32
32
  "files": [
33
- "src",
33
+ "dist",
34
34
  "README.md",
35
35
  "LICENSE"
36
36
  ],
37
37
  "oclif": {
38
38
  "bin": "devsync",
39
39
  "dirname": "devsync",
40
+ "helpOptions": {
41
+ "flagSortOrder": "none"
42
+ },
40
43
  "commands": {
41
44
  "strategy": "explicit",
42
- "target": "./src/cli/commands/index.ts",
45
+ "target": "./dist/cli/commands/index.js",
43
46
  "identifier": "COMMANDS"
44
47
  },
45
48
  "topicSeparator": " ",
@@ -54,8 +57,12 @@
54
57
  "node": ">=24"
55
58
  },
56
59
  "scripts": {
57
- "dev": "node --watch src/index.ts",
58
- "start": "node src/index.ts",
60
+ "build": "tsc -p tsconfig.build.json",
61
+ "clean": "rm -rf dist",
62
+ "prebuild": "rm -rf dist",
63
+ "dev": "tsc -p tsconfig.build.json --watch",
64
+ "start": "node dist/index.js",
65
+ "prepack": "npm run build",
59
66
  "typecheck": "tsc -p tsconfig.json",
60
67
  "test": "vitest run",
61
68
  "test:watch": "vitest",
@@ -71,6 +78,7 @@
71
78
  "@oclif/core": "^4.9.0",
72
79
  "@oclif/plugin-autocomplete": "^3.2.41",
73
80
  "age-encryption": "^0.3.0",
81
+ "picocolors": "^1.1.1",
74
82
  "zod": "^4.3.6"
75
83
  },
76
84
  "devDependencies": {
@@ -1,40 +0,0 @@
1
- import { Args, Command, Flags } from "@oclif/core";
2
-
3
- import { formatSyncAddResult } from "#app/cli/sync-output.ts";
4
- import { addSyncTarget } from "#app/services/add.ts";
5
- import { createSyncContext } from "#app/services/runtime.ts";
6
-
7
- export default class SyncAdd extends Command {
8
- public static override summary =
9
- "Add a local file or directory under your home directory to sync config.json";
10
-
11
- public static override args = {
12
- target: Args.string({
13
- description:
14
- "Local file or directory under your home directory to track, including cwd-relative paths",
15
- required: true,
16
- }),
17
- };
18
-
19
- public static override flags = {
20
- secret: Flags.boolean({
21
- default: false,
22
- description: "Set the added target mode to secret in sync config.json",
23
- }),
24
- };
25
-
26
- public override async run(): Promise<void> {
27
- const { args, flags } = await this.parse(SyncAdd);
28
- const output = formatSyncAddResult(
29
- await addSyncTarget(
30
- {
31
- secret: flags.secret,
32
- target: args.target,
33
- },
34
- createSyncContext(),
35
- ),
36
- );
37
-
38
- process.stdout.write(output);
39
- }
40
- }
@@ -1,80 +0,0 @@
1
- import { spawn } from "node:child_process";
2
- import { mkdir } from "node:fs/promises";
3
-
4
- import { Command, Flags } from "@oclif/core";
5
-
6
- import { resolveDevsyncSyncDirectory } from "#app/config/xdg.ts";
7
- import { ensureTrailingNewline } from "#app/lib/string.ts";
8
-
9
- const readEnvironmentVariable = (name: "ComSpec" | "SHELL") => {
10
- return process.env[name]?.trim();
11
- };
12
-
13
- const resolveCommandShell = () => {
14
- if (process.platform === "win32") {
15
- return {
16
- args: [] as string[],
17
- command: readEnvironmentVariable("ComSpec") || "cmd.exe",
18
- };
19
- }
20
-
21
- return {
22
- args: ["-i"],
23
- command: readEnvironmentVariable("SHELL") || "/bin/sh",
24
- };
25
- };
26
-
27
- const spawnShellInDirectory = async (directory: string) => {
28
- await mkdir(directory, { recursive: true });
29
-
30
- const shell = resolveCommandShell();
31
-
32
- await new Promise<void>((resolve, reject) => {
33
- const child = spawn(shell.command, shell.args, {
34
- cwd: directory,
35
- stdio: "inherit",
36
- });
37
-
38
- child.once("error", reject);
39
- child.once("exit", (code, signal) => {
40
- if (signal !== null) {
41
- reject(new Error(`Shell exited with signal ${signal}.`));
42
-
43
- return;
44
- }
45
-
46
- if (code === 0) {
47
- resolve();
48
-
49
- return;
50
- }
51
-
52
- reject(new Error(`Shell exited with code ${code ?? 1}.`));
53
- });
54
- });
55
- };
56
-
57
- export default class SyncCd extends Command {
58
- public static override summary =
59
- "Open a shell in the sync directory or print its path";
60
-
61
- public static override flags = {
62
- print: Flags.boolean({
63
- default: false,
64
- description: "Print the sync directory path instead of opening a shell",
65
- }),
66
- };
67
-
68
- public override async run(): Promise<void> {
69
- const { flags } = await this.parse(SyncCd);
70
- const syncDirectory = resolveDevsyncSyncDirectory();
71
-
72
- if (flags.print || !process.stdin.isTTY || !process.stdout.isTTY) {
73
- process.stdout.write(ensureTrailingNewline(syncDirectory));
74
-
75
- return;
76
- }
77
-
78
- await spawnShellInDirectory(syncDirectory);
79
- }
80
- }
@@ -1,20 +0,0 @@
1
- import { Command } from "@oclif/core";
2
-
3
- import { formatSyncDoctorResult } from "#app/cli/sync-output.ts";
4
- import { runSyncDoctor } from "#app/services/doctor.ts";
5
- import { createSyncContext } from "#app/services/runtime.ts";
6
-
7
- export default class SyncDoctor extends Command {
8
- public static override summary =
9
- "Check sync repository, config, age identity, and tracked local paths";
10
-
11
- public override async run(): Promise<void> {
12
- const result = await runSyncDoctor(createSyncContext());
13
-
14
- process.stdout.write(formatSyncDoctorResult(result));
15
-
16
- if (result.hasFailures) {
17
- this.exit(1);
18
- }
19
- }
20
- }
@@ -1,32 +0,0 @@
1
- import { Args, Command } from "@oclif/core";
2
-
3
- import { formatSyncForgetResult } from "#app/cli/sync-output.ts";
4
- import { forgetSyncTarget } from "#app/services/forget.ts";
5
- import { createSyncContext } from "#app/services/runtime.ts";
6
-
7
- export default class SyncForget extends Command {
8
- public static override summary =
9
- "Remove a tracked local path or repository path from sync config.json";
10
-
11
- public static override args = {
12
- target: Args.string({
13
- description:
14
- "Tracked local path (including cwd-relative) or repository path to forget",
15
- required: true,
16
- }),
17
- };
18
-
19
- public override async run(): Promise<void> {
20
- const { args } = await this.parse(SyncForget);
21
- const output = formatSyncForgetResult(
22
- await forgetSyncTarget(
23
- {
24
- target: args.target,
25
- },
26
- createSyncContext(),
27
- ),
28
- );
29
-
30
- process.stdout.write(output);
31
- }
32
- }
@@ -1,23 +0,0 @@
1
- import SyncAdd from "#app/cli/commands/add.ts";
2
- import SyncCd from "#app/cli/commands/cd.ts";
3
- import SyncDoctor from "#app/cli/commands/doctor.ts";
4
- import SyncForget from "#app/cli/commands/forget.ts";
5
- import SyncInit from "#app/cli/commands/init.ts";
6
- import SyncList from "#app/cli/commands/list.ts";
7
- import SyncPull from "#app/cli/commands/pull.ts";
8
- import SyncPush from "#app/cli/commands/push.ts";
9
- import SyncSet from "#app/cli/commands/set.ts";
10
- import SyncStatus from "#app/cli/commands/status.ts";
11
-
12
- export const COMMANDS = {
13
- add: SyncAdd,
14
- cd: SyncCd,
15
- doctor: SyncDoctor,
16
- forget: SyncForget,
17
- init: SyncInit,
18
- list: SyncList,
19
- pull: SyncPull,
20
- push: SyncPush,
21
- status: SyncStatus,
22
- set: SyncSet,
23
- };
@@ -1,43 +0,0 @@
1
- import { Args, Command, Flags } from "@oclif/core";
2
-
3
- import { formatSyncInitResult } from "#app/cli/sync-output.ts";
4
- import { initializeSync } from "#app/services/init.ts";
5
- import { createSyncContext } from "#app/services/runtime.ts";
6
-
7
- export default class SyncInit extends Command {
8
- public static override summary = "Initialize the git-backed sync directory";
9
-
10
- public static override args = {
11
- repository: Args.string({
12
- description: "Remote URL or local git repository path to clone",
13
- required: false,
14
- }),
15
- };
16
-
17
- public static override flags = {
18
- identity: Flags.string({
19
- description:
20
- "Age identity file path to persist in config.json for later pulls",
21
- }),
22
- recipient: Flags.string({
23
- description: "Age recipient public key to persist in config.json",
24
- multiple: true,
25
- }),
26
- };
27
-
28
- public override async run(): Promise<void> {
29
- const { args, flags } = await this.parse(SyncInit);
30
- const output = formatSyncInitResult(
31
- await initializeSync(
32
- {
33
- identityFile: flags.identity,
34
- recipients: flags.recipient ?? [],
35
- repository: args.repository,
36
- },
37
- createSyncContext(),
38
- ),
39
- );
40
-
41
- process.stdout.write(output);
42
- }
43
- }
@@ -1,17 +0,0 @@
1
- import { Command } from "@oclif/core";
2
-
3
- import { formatSyncListResult } from "#app/cli/sync-output.ts";
4
- import { listSyncConfig } from "#app/services/list.ts";
5
- import { createSyncContext } from "#app/services/runtime.ts";
6
-
7
- export default class SyncList extends Command {
8
- public static override summary = "Show tracked sync entries and overrides";
9
-
10
- public override async run(): Promise<void> {
11
- const output = formatSyncListResult(
12
- await listSyncConfig(createSyncContext()),
13
- );
14
-
15
- process.stdout.write(output);
16
- }
17
- }