pushwork 2.0.0-a.sub.1 → 2.0.0-preview.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.
- package/dist/branches.d.ts +20 -0
- package/dist/branches.d.ts.map +1 -0
- package/dist/branches.js +111 -0
- package/dist/branches.js.map +1 -0
- package/dist/cli.d.ts +1 -1
- package/dist/cli.d.ts.map +1 -1
- package/dist/cli.js +245 -270
- package/dist/cli.js.map +1 -1
- package/dist/config.d.ts +17 -0
- package/dist/config.d.ts.map +1 -0
- package/dist/config.js +84 -0
- package/dist/config.js.map +1 -0
- package/dist/fs-tree.d.ts +6 -0
- package/dist/fs-tree.d.ts.map +1 -0
- package/dist/fs-tree.js +99 -0
- package/dist/fs-tree.js.map +1 -0
- package/dist/ignore.d.ts +6 -0
- package/dist/ignore.d.ts.map +1 -0
- package/dist/ignore.js +74 -0
- package/dist/ignore.js.map +1 -0
- package/dist/index.d.ts +8 -4
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +35 -4
- package/dist/index.js.map +1 -1
- package/dist/log.d.ts +3 -0
- package/dist/log.d.ts.map +1 -0
- package/dist/log.js +14 -0
- package/dist/log.js.map +1 -0
- package/dist/pushwork.d.ts +129 -0
- package/dist/pushwork.d.ts.map +1 -0
- package/dist/pushwork.js +1062 -0
- package/dist/pushwork.js.map +1 -0
- package/dist/repo.d.ts +14 -0
- package/dist/repo.d.ts.map +1 -0
- package/dist/repo.js +60 -0
- package/dist/repo.js.map +1 -0
- package/dist/shapes/custom.d.ts +3 -0
- package/dist/shapes/custom.d.ts.map +1 -0
- package/dist/shapes/custom.js +57 -0
- package/dist/shapes/custom.js.map +1 -0
- package/dist/shapes/file.d.ts +20 -0
- package/dist/shapes/file.d.ts.map +1 -0
- package/dist/shapes/file.js +140 -0
- package/dist/shapes/file.js.map +1 -0
- package/dist/shapes/index.d.ts +10 -0
- package/dist/shapes/index.d.ts.map +1 -0
- package/dist/shapes/index.js +35 -0
- package/dist/shapes/index.js.map +1 -0
- package/dist/shapes/patchwork-folder.d.ts +3 -0
- package/dist/shapes/patchwork-folder.d.ts.map +1 -0
- package/dist/shapes/patchwork-folder.js +160 -0
- package/dist/shapes/patchwork-folder.js.map +1 -0
- package/dist/shapes/types.d.ts +38 -0
- package/dist/shapes/types.d.ts.map +1 -0
- package/dist/shapes/types.js +52 -0
- package/dist/shapes/types.js.map +1 -0
- package/dist/shapes/vfs.d.ts +3 -0
- package/dist/shapes/vfs.d.ts.map +1 -0
- package/dist/shapes/vfs.js +92 -0
- package/dist/shapes/vfs.js.map +1 -0
- package/dist/stash.d.ts +23 -0
- package/dist/stash.d.ts.map +1 -0
- package/dist/stash.js +118 -0
- package/dist/stash.js.map +1 -0
- package/dist/version.d.ts +11 -0
- package/dist/version.d.ts.map +1 -0
- package/dist/version.js +93 -0
- package/dist/version.js.map +1 -0
- package/package.json +19 -48
- package/patches/@automerge__automerge-repo@2.6.0-subduction.15.patch +26 -0
- package/.prettierrc +0 -9
- package/ARCHITECTURE-ACCORDING-TO-CLAUDE.md +0 -248
- package/CLAUDE.md +0 -141
- package/README.md +0 -221
- package/babel.config.js +0 -5
- package/dist/cli/commands.d.ts +0 -71
- package/dist/cli/commands.d.ts.map +0 -1
- package/dist/cli/commands.js +0 -794
- package/dist/cli/commands.js.map +0 -1
- package/dist/cli/index.d.ts +0 -2
- package/dist/cli/index.d.ts.map +0 -1
- package/dist/cli/index.js +0 -19
- package/dist/cli/index.js.map +0 -1
- package/dist/commands.d.ts +0 -61
- package/dist/commands.d.ts.map +0 -1
- package/dist/commands.js +0 -861
- package/dist/commands.js.map +0 -1
- package/dist/config/index.d.ts +0 -71
- package/dist/config/index.d.ts.map +0 -1
- package/dist/config/index.js +0 -314
- package/dist/config/index.js.map +0 -1
- package/dist/core/change-detection.d.ts +0 -80
- package/dist/core/change-detection.d.ts.map +0 -1
- package/dist/core/change-detection.js +0 -523
- package/dist/core/change-detection.js.map +0 -1
- package/dist/core/config.d.ts +0 -81
- package/dist/core/config.d.ts.map +0 -1
- package/dist/core/config.js +0 -258
- package/dist/core/config.js.map +0 -1
- package/dist/core/index.d.ts +0 -6
- package/dist/core/index.d.ts.map +0 -1
- package/dist/core/index.js +0 -6
- package/dist/core/index.js.map +0 -1
- package/dist/core/move-detection.d.ts +0 -34
- package/dist/core/move-detection.d.ts.map +0 -1
- package/dist/core/move-detection.js +0 -121
- package/dist/core/move-detection.js.map +0 -1
- package/dist/core/snapshot.d.ts +0 -105
- package/dist/core/snapshot.d.ts.map +0 -1
- package/dist/core/snapshot.js +0 -217
- package/dist/core/snapshot.js.map +0 -1
- package/dist/core/sync-engine.d.ts +0 -157
- package/dist/core/sync-engine.d.ts.map +0 -1
- package/dist/core/sync-engine.js +0 -1379
- package/dist/core/sync-engine.js.map +0 -1
- package/dist/types/config.d.ts +0 -99
- package/dist/types/config.d.ts.map +0 -1
- package/dist/types/config.js +0 -5
- package/dist/types/config.js.map +0 -1
- package/dist/types/documents.d.ts +0 -88
- package/dist/types/documents.d.ts.map +0 -1
- package/dist/types/documents.js +0 -20
- package/dist/types/documents.js.map +0 -1
- package/dist/types/index.d.ts +0 -4
- package/dist/types/index.d.ts.map +0 -1
- package/dist/types/index.js +0 -4
- package/dist/types/index.js.map +0 -1
- package/dist/types/snapshot.d.ts +0 -64
- package/dist/types/snapshot.d.ts.map +0 -1
- package/dist/types/snapshot.js +0 -2
- package/dist/types/snapshot.js.map +0 -1
- package/dist/utils/content-similarity.d.ts +0 -53
- package/dist/utils/content-similarity.d.ts.map +0 -1
- package/dist/utils/content-similarity.js +0 -155
- package/dist/utils/content-similarity.js.map +0 -1
- package/dist/utils/content.d.ts +0 -10
- package/dist/utils/content.d.ts.map +0 -1
- package/dist/utils/content.js +0 -31
- package/dist/utils/content.js.map +0 -1
- package/dist/utils/directory.d.ts +0 -24
- package/dist/utils/directory.d.ts.map +0 -1
- package/dist/utils/directory.js +0 -52
- package/dist/utils/directory.js.map +0 -1
- package/dist/utils/fs.d.ts +0 -74
- package/dist/utils/fs.d.ts.map +0 -1
- package/dist/utils/fs.js +0 -248
- package/dist/utils/fs.js.map +0 -1
- package/dist/utils/index.d.ts +0 -5
- package/dist/utils/index.d.ts.map +0 -1
- package/dist/utils/index.js +0 -5
- package/dist/utils/index.js.map +0 -1
- package/dist/utils/mime-types.d.ts +0 -13
- package/dist/utils/mime-types.d.ts.map +0 -1
- package/dist/utils/mime-types.js +0 -209
- package/dist/utils/mime-types.js.map +0 -1
- package/dist/utils/network-sync.d.ts +0 -36
- package/dist/utils/network-sync.d.ts.map +0 -1
- package/dist/utils/network-sync.js +0 -250
- package/dist/utils/network-sync.js.map +0 -1
- package/dist/utils/node-polyfills.d.ts +0 -9
- package/dist/utils/node-polyfills.d.ts.map +0 -1
- package/dist/utils/node-polyfills.js +0 -9
- package/dist/utils/node-polyfills.js.map +0 -1
- package/dist/utils/output.d.ts +0 -129
- package/dist/utils/output.d.ts.map +0 -1
- package/dist/utils/output.js +0 -368
- package/dist/utils/output.js.map +0 -1
- package/dist/utils/repo-factory.d.ts +0 -13
- package/dist/utils/repo-factory.d.ts.map +0 -1
- package/dist/utils/repo-factory.js +0 -46
- package/dist/utils/repo-factory.js.map +0 -1
- package/dist/utils/string-similarity.d.ts +0 -14
- package/dist/utils/string-similarity.d.ts.map +0 -1
- package/dist/utils/string-similarity.js +0 -39
- package/dist/utils/string-similarity.js.map +0 -1
- package/dist/utils/text-diff.d.ts +0 -37
- package/dist/utils/text-diff.d.ts.map +0 -1
- package/dist/utils/text-diff.js +0 -93
- package/dist/utils/text-diff.js.map +0 -1
- package/dist/utils/trace.d.ts +0 -19
- package/dist/utils/trace.d.ts.map +0 -1
- package/dist/utils/trace.js +0 -63
- package/dist/utils/trace.js.map +0 -1
- package/src/cli.ts +0 -442
- package/src/commands.ts +0 -1134
- package/src/core/change-detection.ts +0 -712
- package/src/core/config.ts +0 -313
- package/src/core/index.ts +0 -5
- package/src/core/move-detection.ts +0 -169
- package/src/core/snapshot.ts +0 -275
- package/src/core/sync-engine.ts +0 -1795
- package/src/index.ts +0 -4
- package/src/types/config.ts +0 -111
- package/src/types/documents.ts +0 -91
- package/src/types/index.ts +0 -3
- package/src/types/snapshot.ts +0 -67
- package/src/utils/content.ts +0 -34
- package/src/utils/directory.ts +0 -73
- package/src/utils/fs.ts +0 -297
- package/src/utils/index.ts +0 -4
- package/src/utils/mime-types.ts +0 -244
- package/src/utils/network-sync.ts +0 -319
- package/src/utils/node-polyfills.ts +0 -8
- package/src/utils/output.ts +0 -450
- package/src/utils/repo-factory.ts +0 -73
- package/src/utils/string-similarity.ts +0 -54
- package/src/utils/text-diff.ts +0 -101
- package/src/utils/trace.ts +0 -70
- package/test/integration/README.md +0 -328
- package/test/integration/clone-test.sh +0 -310
- package/test/integration/conflict-resolution-test.sh +0 -309
- package/test/integration/debug-both-nested.sh +0 -74
- package/test/integration/debug-concurrent-nested.sh +0 -87
- package/test/integration/debug-nested.sh +0 -73
- package/test/integration/deletion-behavior-test.sh +0 -487
- package/test/integration/deletion-sync-test-simple.sh +0 -193
- package/test/integration/deletion-sync-test.sh +0 -297
- package/test/integration/exclude-patterns.test.ts +0 -144
- package/test/integration/full-integration-test.sh +0 -363
- package/test/integration/fuzzer.test.ts +0 -818
- package/test/integration/in-memory-sync.test.ts +0 -830
- package/test/integration/init-sync.test.ts +0 -89
- package/test/integration/manual-sync-test.sh +0 -84
- package/test/integration/sync-deletion.test.ts +0 -280
- package/test/integration/sync-flow.test.ts +0 -291
- package/test/jest.setup.ts +0 -34
- package/test/run-tests.sh +0 -225
- package/test/unit/deletion-behavior.test.ts +0 -249
- package/test/unit/enhanced-mime-detection.test.ts +0 -244
- package/test/unit/snapshot.test.ts +0 -404
- package/test/unit/sync-convergence.test.ts +0 -298
- package/test/unit/sync-timing.test.ts +0 -134
- package/test/unit/utils.test.ts +0 -366
- package/tsconfig.json +0 -23
|
@@ -1,37 +0,0 @@
|
|
|
1
|
-
import * as A from "@automerge/automerge";
|
|
2
|
-
/**
|
|
3
|
-
* Read content from an Automerge document, normalizing legacy ImmutableString
|
|
4
|
-
* values to plain strings for backwards compatibility.
|
|
5
|
-
*
|
|
6
|
-
* Old documents may store text as ImmutableString. This helper ensures callers
|
|
7
|
-
* always get back `string | Uint8Array | null`.
|
|
8
|
-
*/
|
|
9
|
-
export declare function readDocContent(content: unknown): string | Uint8Array | null;
|
|
10
|
-
/**
|
|
11
|
-
* Update text content on an Automerge document property inside a change
|
|
12
|
-
* callback.
|
|
13
|
-
*
|
|
14
|
-
* If the existing value is already a collaborative text string, we diff and
|
|
15
|
-
* splice for minimal CRDT operations. If the existing value is a legacy
|
|
16
|
-
* ImmutableString we can't splice into it, so we assign the whole string
|
|
17
|
-
* which converts the field to a collaborative text CRDT going forward.
|
|
18
|
-
*
|
|
19
|
-
* @param doc - The mutable Automerge document (inside a change callback)
|
|
20
|
-
* @param path - Property path to the text field, e.g. ["content"]
|
|
21
|
-
* @param newContent - The desired new text value
|
|
22
|
-
*/
|
|
23
|
-
export declare function updateTextContent(doc: any, path: A.Prop[], newContent: string): void;
|
|
24
|
-
/**
|
|
25
|
-
* Apply a text diff between oldContent and newContent as Automerge splice
|
|
26
|
-
* operations on the given document property path.
|
|
27
|
-
*
|
|
28
|
-
* This preserves the collaborative text CRDT structure by making minimal
|
|
29
|
-
* character-level edits rather than replacing the entire string.
|
|
30
|
-
*
|
|
31
|
-
* @param doc - The Automerge document (inside a change callback)
|
|
32
|
-
* @param path - The property path to the text field, e.g. ["content"]
|
|
33
|
-
* @param oldContent - The previous text content
|
|
34
|
-
* @param newContent - The desired new text content
|
|
35
|
-
*/
|
|
36
|
-
export declare function spliceText(doc: any, path: A.Prop[], oldContent: string, newContent: string): void;
|
|
37
|
-
//# sourceMappingURL=text-diff.d.ts.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"text-diff.d.ts","sourceRoot":"","sources":["../../src/utils/text-diff.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,CAAC,MAAM,sBAAsB,CAAA;AAGzC;;;;;;GAMG;AACH,wBAAgB,cAAc,CAAC,OAAO,EAAE,OAAO,GAAG,MAAM,GAAG,UAAU,GAAG,IAAI,CAO3E;AAED;;;;;;;;;;;;GAYG;AACH,wBAAgB,iBAAiB,CAChC,GAAG,EAAE,GAAG,EACR,IAAI,EAAE,CAAC,CAAC,IAAI,EAAE,EACd,UAAU,EAAE,MAAM,GAChB,IAAI,CAeN;AAED;;;;;;;;;;;GAWG;AACH,wBAAgB,UAAU,CACzB,GAAG,EAAE,GAAG,EACR,IAAI,EAAE,CAAC,CAAC,IAAI,EAAE,EACd,UAAU,EAAE,MAAM,EAClB,UAAU,EAAE,MAAM,GAChB,IAAI,CA8BN"}
|
package/dist/utils/text-diff.js
DELETED
|
@@ -1,93 +0,0 @@
|
|
|
1
|
-
import * as A from "@automerge/automerge";
|
|
2
|
-
import * as diffLib from "diff";
|
|
3
|
-
/**
|
|
4
|
-
* Read content from an Automerge document, normalizing legacy ImmutableString
|
|
5
|
-
* values to plain strings for backwards compatibility.
|
|
6
|
-
*
|
|
7
|
-
* Old documents may store text as ImmutableString. This helper ensures callers
|
|
8
|
-
* always get back `string | Uint8Array | null`.
|
|
9
|
-
*/
|
|
10
|
-
export function readDocContent(content) {
|
|
11
|
-
if (content == null)
|
|
12
|
-
return null;
|
|
13
|
-
if (typeof content === "string")
|
|
14
|
-
return content;
|
|
15
|
-
if (content instanceof Uint8Array)
|
|
16
|
-
return content;
|
|
17
|
-
// Legacy ImmutableString — convert to plain string
|
|
18
|
-
if (A.isImmutableString(content))
|
|
19
|
-
return content.toString();
|
|
20
|
-
return null;
|
|
21
|
-
}
|
|
22
|
-
/**
|
|
23
|
-
* Update text content on an Automerge document property inside a change
|
|
24
|
-
* callback.
|
|
25
|
-
*
|
|
26
|
-
* If the existing value is already a collaborative text string, we diff and
|
|
27
|
-
* splice for minimal CRDT operations. If the existing value is a legacy
|
|
28
|
-
* ImmutableString we can't splice into it, so we assign the whole string
|
|
29
|
-
* which converts the field to a collaborative text CRDT going forward.
|
|
30
|
-
*
|
|
31
|
-
* @param doc - The mutable Automerge document (inside a change callback)
|
|
32
|
-
* @param path - Property path to the text field, e.g. ["content"]
|
|
33
|
-
* @param newContent - The desired new text value
|
|
34
|
-
*/
|
|
35
|
-
export function updateTextContent(doc, path, newContent) {
|
|
36
|
-
const target = path.reduce((obj, key) => obj?.[key], doc);
|
|
37
|
-
if (typeof target === "string") {
|
|
38
|
-
// Already a collaborative text string — diff and splice
|
|
39
|
-
spliceText(doc, path, target, newContent);
|
|
40
|
-
}
|
|
41
|
-
else {
|
|
42
|
-
// Legacy ImmutableString, undefined, or other — assign directly.
|
|
43
|
-
// This converts the field to a collaborative text CRDT.
|
|
44
|
-
let obj = doc;
|
|
45
|
-
for (let i = 0; i < path.length - 1; i++) {
|
|
46
|
-
obj = obj[path[i]];
|
|
47
|
-
}
|
|
48
|
-
obj[path[path.length - 1]] = newContent;
|
|
49
|
-
}
|
|
50
|
-
}
|
|
51
|
-
/**
|
|
52
|
-
* Apply a text diff between oldContent and newContent as Automerge splice
|
|
53
|
-
* operations on the given document property path.
|
|
54
|
-
*
|
|
55
|
-
* This preserves the collaborative text CRDT structure by making minimal
|
|
56
|
-
* character-level edits rather than replacing the entire string.
|
|
57
|
-
*
|
|
58
|
-
* @param doc - The Automerge document (inside a change callback)
|
|
59
|
-
* @param path - The property path to the text field, e.g. ["content"]
|
|
60
|
-
* @param oldContent - The previous text content
|
|
61
|
-
* @param newContent - The desired new text content
|
|
62
|
-
*/
|
|
63
|
-
export function spliceText(doc, path, oldContent, newContent) {
|
|
64
|
-
if (oldContent === newContent)
|
|
65
|
-
return;
|
|
66
|
-
// Fast path: if old is empty, just insert everything
|
|
67
|
-
if (oldContent === "") {
|
|
68
|
-
A.splice(doc, path, 0, 0, newContent);
|
|
69
|
-
return;
|
|
70
|
-
}
|
|
71
|
-
// Fast path: if new is empty, just delete everything
|
|
72
|
-
if (newContent === "") {
|
|
73
|
-
A.splice(doc, path, 0, oldContent.length);
|
|
74
|
-
return;
|
|
75
|
-
}
|
|
76
|
-
const changes = diffLib.diffChars(oldContent, newContent);
|
|
77
|
-
let pos = 0;
|
|
78
|
-
for (const part of changes) {
|
|
79
|
-
if (part.removed) {
|
|
80
|
-
A.splice(doc, path, pos, part.value.length);
|
|
81
|
-
// Don't advance pos — text shifted left after deletion
|
|
82
|
-
}
|
|
83
|
-
else if (part.added) {
|
|
84
|
-
A.splice(doc, path, pos, 0, part.value);
|
|
85
|
-
pos += part.value.length;
|
|
86
|
-
}
|
|
87
|
-
else {
|
|
88
|
-
// Unchanged text — just advance the cursor
|
|
89
|
-
pos += part.value.length;
|
|
90
|
-
}
|
|
91
|
-
}
|
|
92
|
-
}
|
|
93
|
-
//# sourceMappingURL=text-diff.js.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"text-diff.js","sourceRoot":"","sources":["../../src/utils/text-diff.ts"],"names":[],"mappings":"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"}
|
package/dist/utils/trace.d.ts
DELETED
|
@@ -1,19 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* Enable or disable tracing
|
|
3
|
-
*/
|
|
4
|
-
export declare function setTracingEnabled(enabled: boolean): void;
|
|
5
|
-
/**
|
|
6
|
-
* Check if tracing is enabled
|
|
7
|
-
*/
|
|
8
|
-
export declare function isTracingEnabled(): boolean;
|
|
9
|
-
/**
|
|
10
|
-
* Trace a span of work by outputting to console
|
|
11
|
-
* Works for both sync and async functions
|
|
12
|
-
* Only outputs if tracing is enabled
|
|
13
|
-
*
|
|
14
|
-
* Usage:
|
|
15
|
-
* await span("operation", async () => { ... })
|
|
16
|
-
* span("operation", () => { ... })
|
|
17
|
-
*/
|
|
18
|
-
export declare function span<T>(name: string, fn: () => T | Promise<T>): T | Promise<T>;
|
|
19
|
-
//# sourceMappingURL=trace.d.ts.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"trace.d.ts","sourceRoot":"","sources":["../../src/utils/trace.ts"],"names":[],"mappings":"AAOA;;GAEG;AACH,wBAAgB,iBAAiB,CAAC,OAAO,EAAE,OAAO,GAAG,IAAI,CAExD;AAED;;GAEG;AACH,wBAAgB,gBAAgB,IAAI,OAAO,CAE1C;AAED;;;;;;;;GAQG;AACH,wBAAgB,IAAI,CAAC,CAAC,EACpB,IAAI,EAAE,MAAM,EACZ,EAAE,EAAE,MAAM,CAAC,GAAG,OAAO,CAAC,CAAC,CAAC,GACvB,CAAC,GAAG,OAAO,CAAC,CAAC,CAAC,CAqBhB"}
|
package/dist/utils/trace.js
DELETED
|
@@ -1,63 +0,0 @@
|
|
|
1
|
-
import { out } from "./output.js";
|
|
2
|
-
/**
|
|
3
|
-
* Global tracing state
|
|
4
|
-
*/
|
|
5
|
-
let tracingEnabled = false;
|
|
6
|
-
/**
|
|
7
|
-
* Enable or disable tracing
|
|
8
|
-
*/
|
|
9
|
-
export function setTracingEnabled(enabled) {
|
|
10
|
-
tracingEnabled = enabled;
|
|
11
|
-
}
|
|
12
|
-
/**
|
|
13
|
-
* Check if tracing is enabled
|
|
14
|
-
*/
|
|
15
|
-
export function isTracingEnabled() {
|
|
16
|
-
return tracingEnabled;
|
|
17
|
-
}
|
|
18
|
-
/**
|
|
19
|
-
* Trace a span of work by outputting to console
|
|
20
|
-
* Works for both sync and async functions
|
|
21
|
-
* Only outputs if tracing is enabled
|
|
22
|
-
*
|
|
23
|
-
* Usage:
|
|
24
|
-
* await span("operation", async () => { ... })
|
|
25
|
-
* span("operation", () => { ... })
|
|
26
|
-
*/
|
|
27
|
-
export function span(name, fn) {
|
|
28
|
-
if (!tracingEnabled) {
|
|
29
|
-
return fn();
|
|
30
|
-
}
|
|
31
|
-
const start = performance.now();
|
|
32
|
-
const result = fn();
|
|
33
|
-
// Check if it's a promise (async)
|
|
34
|
-
if (result instanceof Promise) {
|
|
35
|
-
return result.then((value) => {
|
|
36
|
-
const duration = performance.now() - start;
|
|
37
|
-
out.taskLine(`${name} (${formatDuration(duration)})`, true);
|
|
38
|
-
return value;
|
|
39
|
-
});
|
|
40
|
-
}
|
|
41
|
-
// Sync case
|
|
42
|
-
const duration = performance.now() - start;
|
|
43
|
-
out.taskLine(`${name} (${formatDuration(duration)})`, true);
|
|
44
|
-
return result;
|
|
45
|
-
}
|
|
46
|
-
/**
|
|
47
|
-
* Format duration for display
|
|
48
|
-
*/
|
|
49
|
-
function formatDuration(ms) {
|
|
50
|
-
if (ms < 1) {
|
|
51
|
-
return `${ms.toFixed(2)}ms`;
|
|
52
|
-
}
|
|
53
|
-
else if (ms < 1000) {
|
|
54
|
-
return `${Math.round(ms)}ms`;
|
|
55
|
-
}
|
|
56
|
-
else if (ms < 2000) {
|
|
57
|
-
return `${(ms / 1000).toFixed(2)}s`;
|
|
58
|
-
}
|
|
59
|
-
else {
|
|
60
|
-
return `${(ms / 1000).toFixed(1)}s`;
|
|
61
|
-
}
|
|
62
|
-
}
|
|
63
|
-
//# sourceMappingURL=trace.js.map
|
package/dist/utils/trace.js.map
DELETED
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"trace.js","sourceRoot":"","sources":["../../src/utils/trace.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,GAAG,EAAE,MAAM,aAAa,CAAC;AAElC;;GAEG;AACH,IAAI,cAAc,GAAG,KAAK,CAAC;AAE3B;;GAEG;AACH,MAAM,UAAU,iBAAiB,CAAC,OAAgB;IAChD,cAAc,GAAG,OAAO,CAAC;AAC3B,CAAC;AAED;;GAEG;AACH,MAAM,UAAU,gBAAgB;IAC9B,OAAO,cAAc,CAAC;AACxB,CAAC;AAED;;;;;;;;GAQG;AACH,MAAM,UAAU,IAAI,CAClB,IAAY,EACZ,EAAwB;IAExB,IAAI,CAAC,cAAc,EAAE,CAAC;QACpB,OAAO,EAAE,EAAE,CAAC;IACd,CAAC;IAED,MAAM,KAAK,GAAG,WAAW,CAAC,GAAG,EAAE,CAAC;IAChC,MAAM,MAAM,GAAG,EAAE,EAAE,CAAC;IAEpB,kCAAkC;IAClC,IAAI,MAAM,YAAY,OAAO,EAAE,CAAC;QAC9B,OAAO,MAAM,CAAC,IAAI,CAAC,CAAC,KAAK,EAAE,EAAE;YAC3B,MAAM,QAAQ,GAAG,WAAW,CAAC,GAAG,EAAE,GAAG,KAAK,CAAC;YAC3C,GAAG,CAAC,QAAQ,CAAC,GAAG,IAAI,KAAK,cAAc,CAAC,QAAQ,CAAC,GAAG,EAAE,IAAI,CAAC,CAAC;YAC5D,OAAO,KAAK,CAAC;QACf,CAAC,CAAM,CAAC;IACV,CAAC;IAED,YAAY;IACZ,MAAM,QAAQ,GAAG,WAAW,CAAC,GAAG,EAAE,GAAG,KAAK,CAAC;IAC3C,GAAG,CAAC,QAAQ,CAAC,GAAG,IAAI,KAAK,cAAc,CAAC,QAAQ,CAAC,GAAG,EAAE,IAAI,CAAC,CAAC;IAC5D,OAAO,MAAM,CAAC;AAChB,CAAC;AAED;;GAEG;AACH,SAAS,cAAc,CAAC,EAAU;IAChC,IAAI,EAAE,GAAG,CAAC,EAAE,CAAC;QACX,OAAO,GAAG,EAAE,CAAC,OAAO,CAAC,CAAC,CAAC,IAAI,CAAC;IAC9B,CAAC;SAAM,IAAI,EAAE,GAAG,IAAI,EAAE,CAAC;QACrB,OAAO,GAAG,IAAI,CAAC,KAAK,CAAC,EAAE,CAAC,IAAI,CAAC;IAC/B,CAAC;SAAM,IAAI,EAAE,GAAG,IAAI,EAAE,CAAC;QACrB,OAAO,GAAG,CAAC,EAAE,GAAG,IAAI,CAAC,CAAC,OAAO,CAAC,CAAC,CAAC,GAAG,CAAC;IACtC,CAAC;SAAM,CAAC;QACN,OAAO,GAAG,CAAC,EAAE,GAAG,IAAI,CAAC,CAAC,OAAO,CAAC,CAAC,CAAC,GAAG,CAAC;IACtC,CAAC;AACH,CAAC"}
|
package/src/cli.ts
DELETED
|
@@ -1,442 +0,0 @@
|
|
|
1
|
-
#!/usr/bin/env node
|
|
2
|
-
|
|
3
|
-
import { Command, Option } from "@commander-js/extra-typings";
|
|
4
|
-
import chalk from "chalk";
|
|
5
|
-
import {
|
|
6
|
-
init,
|
|
7
|
-
clone,
|
|
8
|
-
sync,
|
|
9
|
-
root,
|
|
10
|
-
diff,
|
|
11
|
-
status,
|
|
12
|
-
log,
|
|
13
|
-
checkout,
|
|
14
|
-
commit,
|
|
15
|
-
url,
|
|
16
|
-
rm,
|
|
17
|
-
ls,
|
|
18
|
-
config,
|
|
19
|
-
watch,
|
|
20
|
-
read,
|
|
21
|
-
} from "./commands.js";
|
|
22
|
-
|
|
23
|
-
import { createRequire } from "module";
|
|
24
|
-
const require = createRequire(import.meta.url);
|
|
25
|
-
const version = require("../package.json").version;
|
|
26
|
-
const program = new Command()
|
|
27
|
-
.name("pushwork")
|
|
28
|
-
.description("Bidirectional directory synchronization using Automerge CRDTs")
|
|
29
|
-
.version(version, "-V, --version", "output the version number");
|
|
30
|
-
|
|
31
|
-
// Init command
|
|
32
|
-
program
|
|
33
|
-
.command("init")
|
|
34
|
-
.summary("Initialize sync in a directory")
|
|
35
|
-
.argument(
|
|
36
|
-
"[path]",
|
|
37
|
-
"Directory path to initialize (default: current directory)",
|
|
38
|
-
"."
|
|
39
|
-
)
|
|
40
|
-
.option(
|
|
41
|
-
"--sync-server <url>",
|
|
42
|
-
"Custom sync server URL"
|
|
43
|
-
)
|
|
44
|
-
.action(async (path, opts) => {
|
|
45
|
-
await init(path, { syncServer: opts.syncServer });
|
|
46
|
-
});
|
|
47
|
-
|
|
48
|
-
// Track command (set root directory URL without full initialization)
|
|
49
|
-
const trackAction = async (url: string, path: string, opts: { force: boolean }) => {
|
|
50
|
-
await root(url, path, { force: opts.force });
|
|
51
|
-
};
|
|
52
|
-
|
|
53
|
-
program
|
|
54
|
-
.command("track")
|
|
55
|
-
.summary("Set root directory URL without full initialization")
|
|
56
|
-
.argument(
|
|
57
|
-
"<url>",
|
|
58
|
-
"AutomergeUrl of root directory (format: automerge:XXXXX)"
|
|
59
|
-
)
|
|
60
|
-
.argument(
|
|
61
|
-
"[path]",
|
|
62
|
-
"Directory path (default: current directory)",
|
|
63
|
-
"."
|
|
64
|
-
)
|
|
65
|
-
.option("-f, --force", "Overwrite existing pushwork setup", false)
|
|
66
|
-
.action(async (url, path, opts) => {
|
|
67
|
-
await trackAction(url, path, opts);
|
|
68
|
-
});
|
|
69
|
-
|
|
70
|
-
// Hidden alias for backwards compatibility
|
|
71
|
-
program
|
|
72
|
-
.command("root", { hidden: true })
|
|
73
|
-
.argument("<url>")
|
|
74
|
-
.argument("[path]", "", ".")
|
|
75
|
-
.option("-f, --force", "", false)
|
|
76
|
-
.action(async (url: string, path: string, opts: { force: boolean }) => {
|
|
77
|
-
await trackAction(url, path, opts);
|
|
78
|
-
});
|
|
79
|
-
|
|
80
|
-
// Clone command
|
|
81
|
-
program
|
|
82
|
-
.command("clone")
|
|
83
|
-
.summary("Clone an existing synced directory")
|
|
84
|
-
.argument(
|
|
85
|
-
"<url>",
|
|
86
|
-
"AutomergeUrl of root directory to clone (format: automerge:XXXXX)"
|
|
87
|
-
)
|
|
88
|
-
.argument("<path>", "Target directory path")
|
|
89
|
-
.option("-f, --force", "Overwrite existing directory", false)
|
|
90
|
-
.option(
|
|
91
|
-
"--sync-server <url>",
|
|
92
|
-
"Custom sync server URL"
|
|
93
|
-
)
|
|
94
|
-
.option("-v, --verbose", "Verbose output", false)
|
|
95
|
-
.action(async (url, path, opts) => {
|
|
96
|
-
await clone(url, path, {
|
|
97
|
-
force: opts.force,
|
|
98
|
-
verbose: opts.verbose,
|
|
99
|
-
syncServer: opts.syncServer,
|
|
100
|
-
});
|
|
101
|
-
});
|
|
102
|
-
|
|
103
|
-
// Commit command
|
|
104
|
-
program
|
|
105
|
-
.command("commit")
|
|
106
|
-
.summary("Save local changes to Automerge documents")
|
|
107
|
-
.argument(
|
|
108
|
-
"[path]",
|
|
109
|
-
"Directory path to commit (default: current directory)",
|
|
110
|
-
"."
|
|
111
|
-
)
|
|
112
|
-
.action(async (path, _opts) => {
|
|
113
|
-
await commit(path);
|
|
114
|
-
});
|
|
115
|
-
|
|
116
|
-
// Sync command
|
|
117
|
-
program
|
|
118
|
-
.command("sync")
|
|
119
|
-
.summary("Run full bidirectional synchronization")
|
|
120
|
-
.argument(
|
|
121
|
-
"[path]",
|
|
122
|
-
"Directory path to sync (default: current directory)",
|
|
123
|
-
"."
|
|
124
|
-
)
|
|
125
|
-
.option(
|
|
126
|
-
"--dry-run",
|
|
127
|
-
"Show what would be done without applying changes",
|
|
128
|
-
false
|
|
129
|
-
)
|
|
130
|
-
.option(
|
|
131
|
-
"--gentle",
|
|
132
|
-
"Use config files and only sync changed files (instead of default full resync)",
|
|
133
|
-
false
|
|
134
|
-
)
|
|
135
|
-
.option(
|
|
136
|
-
"--nuclear",
|
|
137
|
-
"Recreate all Automerge documents from scratch",
|
|
138
|
-
false
|
|
139
|
-
)
|
|
140
|
-
.addOption(new Option("-f, --force", "Accepted for backwards compatibility").default(false).hideHelp())
|
|
141
|
-
.option("-v, --verbose", "Verbose output", false)
|
|
142
|
-
.action(async (path, opts) => {
|
|
143
|
-
await sync(path, {
|
|
144
|
-
dryRun: opts.dryRun,
|
|
145
|
-
force: opts.force,
|
|
146
|
-
gentle: opts.gentle,
|
|
147
|
-
nuclear: opts.nuclear,
|
|
148
|
-
verbose: opts.verbose,
|
|
149
|
-
});
|
|
150
|
-
});
|
|
151
|
-
|
|
152
|
-
// Diff command
|
|
153
|
-
program
|
|
154
|
-
.command("diff")
|
|
155
|
-
.summary("Show changes in working directory")
|
|
156
|
-
.argument(
|
|
157
|
-
"[path]",
|
|
158
|
-
"Limit diff to specific path (default: current directory)",
|
|
159
|
-
"."
|
|
160
|
-
)
|
|
161
|
-
.option("--name-only", "Show only changed file names", false)
|
|
162
|
-
.action(async (path, opts) => {
|
|
163
|
-
await diff(path, {
|
|
164
|
-
nameOnly: opts.nameOnly,
|
|
165
|
-
});
|
|
166
|
-
});
|
|
167
|
-
|
|
168
|
-
// Status command
|
|
169
|
-
program
|
|
170
|
-
.command("status")
|
|
171
|
-
.summary("Show sync status summary")
|
|
172
|
-
.argument("[path]", "Directory path (default: current directory)", ".")
|
|
173
|
-
.option(
|
|
174
|
-
"-v, --verbose",
|
|
175
|
-
"Show detailed status including document info and all tracked files",
|
|
176
|
-
false
|
|
177
|
-
)
|
|
178
|
-
.action(async (path, opts) => {
|
|
179
|
-
await status(path, {
|
|
180
|
-
verbose: opts.verbose,
|
|
181
|
-
});
|
|
182
|
-
});
|
|
183
|
-
|
|
184
|
-
// Log command
|
|
185
|
-
program
|
|
186
|
-
.command("log")
|
|
187
|
-
.summary("Show sync history (experimental)")
|
|
188
|
-
.argument(
|
|
189
|
-
"[path]",
|
|
190
|
-
"Show history for specific file or directory (default: current directory)",
|
|
191
|
-
"."
|
|
192
|
-
)
|
|
193
|
-
.option("--oneline", "Compact one-line per sync format", false)
|
|
194
|
-
.option("--since <date>", "Show syncs since date")
|
|
195
|
-
.option("--limit <n>", "Limit number of syncs shown", "10")
|
|
196
|
-
.action(async (path, opts) => {
|
|
197
|
-
await log(path, {
|
|
198
|
-
oneline: opts.oneline,
|
|
199
|
-
since: opts.since,
|
|
200
|
-
limit: parseInt(opts.limit),
|
|
201
|
-
});
|
|
202
|
-
});
|
|
203
|
-
|
|
204
|
-
// Checkout command
|
|
205
|
-
program
|
|
206
|
-
.command("checkout")
|
|
207
|
-
.summary("Restore to previous sync (experimental)")
|
|
208
|
-
.argument("<sync-id>", "Sync ID to restore to")
|
|
209
|
-
.argument(
|
|
210
|
-
"[path]",
|
|
211
|
-
"Specific path to restore (default: current directory)",
|
|
212
|
-
"."
|
|
213
|
-
)
|
|
214
|
-
.option(
|
|
215
|
-
"-f, --force",
|
|
216
|
-
"Force checkout even if there are uncommitted changes",
|
|
217
|
-
false
|
|
218
|
-
)
|
|
219
|
-
.action(async (syncId, path, opts) => {
|
|
220
|
-
await checkout(syncId, path, {
|
|
221
|
-
force: opts.force,
|
|
222
|
-
});
|
|
223
|
-
});
|
|
224
|
-
|
|
225
|
-
// URL command
|
|
226
|
-
program
|
|
227
|
-
.command("url")
|
|
228
|
-
.summary("Show the Automerge root URL")
|
|
229
|
-
.argument("[path]", "Directory path (default: current directory)", ".")
|
|
230
|
-
.action(async (path) => {
|
|
231
|
-
await url(path);
|
|
232
|
-
});
|
|
233
|
-
|
|
234
|
-
// Remove command
|
|
235
|
-
program
|
|
236
|
-
.command("rm")
|
|
237
|
-
.summary("Remove local pushwork data")
|
|
238
|
-
.argument("[path]", "Directory path (default: current directory)", ".")
|
|
239
|
-
.action(async (path) => {
|
|
240
|
-
await rm(path);
|
|
241
|
-
});
|
|
242
|
-
|
|
243
|
-
// List command
|
|
244
|
-
program
|
|
245
|
-
.command("ls")
|
|
246
|
-
.summary("List tracked files")
|
|
247
|
-
.argument("[path]", "Directory path (default: current directory)", ".")
|
|
248
|
-
.option("-v, --verbose", "Show with Automerge URLs", false)
|
|
249
|
-
.action(async (path, opts) => {
|
|
250
|
-
await ls(path, {
|
|
251
|
-
verbose: opts.verbose,
|
|
252
|
-
});
|
|
253
|
-
});
|
|
254
|
-
|
|
255
|
-
// Config command
|
|
256
|
-
program
|
|
257
|
-
.command("config")
|
|
258
|
-
.summary("View or edit configuration")
|
|
259
|
-
.argument("[path]", "Directory path (default: current directory)", ".")
|
|
260
|
-
.option("--list", "Show full configuration", false)
|
|
261
|
-
.option(
|
|
262
|
-
"--get <key>",
|
|
263
|
-
"Get specific config value (dot notation, e.g., sync.move_detection_threshold)"
|
|
264
|
-
)
|
|
265
|
-
.action(async (path, opts) => {
|
|
266
|
-
await config(path, {
|
|
267
|
-
list: opts.list,
|
|
268
|
-
get: opts.get,
|
|
269
|
-
});
|
|
270
|
-
});
|
|
271
|
-
|
|
272
|
-
// Watch command
|
|
273
|
-
program
|
|
274
|
-
.command("watch")
|
|
275
|
-
.summary("Watch directory for changes, build, and sync")
|
|
276
|
-
.argument(
|
|
277
|
-
"[path]",
|
|
278
|
-
"Directory path to sync (default: current directory)",
|
|
279
|
-
"."
|
|
280
|
-
)
|
|
281
|
-
.option(
|
|
282
|
-
"--script <command>",
|
|
283
|
-
"Build script to run before syncing",
|
|
284
|
-
"pnpm build"
|
|
285
|
-
)
|
|
286
|
-
.option(
|
|
287
|
-
"--dir <dir>",
|
|
288
|
-
"Directory to watch for changes (relative to working directory)",
|
|
289
|
-
"src"
|
|
290
|
-
)
|
|
291
|
-
.option("-v, --verbose", "Show build script output", false)
|
|
292
|
-
.action(async (path, opts) => {
|
|
293
|
-
await watch(path, {
|
|
294
|
-
script: opts.script,
|
|
295
|
-
watchDir: opts.dir,
|
|
296
|
-
verbose: opts.verbose,
|
|
297
|
-
});
|
|
298
|
-
});
|
|
299
|
-
|
|
300
|
-
// Read command
|
|
301
|
-
program
|
|
302
|
-
.command("read")
|
|
303
|
-
.summary("Read a file document by its Automerge URL")
|
|
304
|
-
.argument(
|
|
305
|
-
"<url>",
|
|
306
|
-
"AutomergeUrl of file document (format: automerge:XXXXX)"
|
|
307
|
-
)
|
|
308
|
-
.option("-r, --remote", "Read from sync server instead of local storage", false)
|
|
309
|
-
.action(async (url, opts) => {
|
|
310
|
-
await read(url, {
|
|
311
|
-
remote: opts.remote,
|
|
312
|
-
});
|
|
313
|
-
});
|
|
314
|
-
|
|
315
|
-
// Completion command (hidden from help)
|
|
316
|
-
program.command("completion", { hidden: true }).action(() => {
|
|
317
|
-
// Generate completion dynamically from registered commands
|
|
318
|
-
const commands = program.commands
|
|
319
|
-
.filter((cmd) => cmd.name() !== "completion") // Exclude self
|
|
320
|
-
.map((cmd) => {
|
|
321
|
-
const name = cmd.name();
|
|
322
|
-
const desc = (cmd.summary() || cmd.description() || "").replace(
|
|
323
|
-
/'/g,
|
|
324
|
-
"\\'"
|
|
325
|
-
);
|
|
326
|
-
return `'${name}:${desc}'`;
|
|
327
|
-
})
|
|
328
|
-
.join(" ");
|
|
329
|
-
|
|
330
|
-
// Generate option completions for each command
|
|
331
|
-
const commandCases = program.commands
|
|
332
|
-
.filter((cmd) => cmd.name() !== "completion")
|
|
333
|
-
.map((cmd) => {
|
|
334
|
-
const options = cmd.options
|
|
335
|
-
.filter((opt) => opt.flags !== "-h, --help") // Exclude help
|
|
336
|
-
.map((opt) => {
|
|
337
|
-
// Parse flags like "-v, --verbose" or "--dry-run"
|
|
338
|
-
const flags = opt.flags.split(",").map((f) => f.trim());
|
|
339
|
-
const desc = (opt.description || "")
|
|
340
|
-
.replace(/'/g, "\\'")
|
|
341
|
-
.replace(/\n/g, " ");
|
|
342
|
-
|
|
343
|
-
// For options with arguments like "--sync-server <url>"
|
|
344
|
-
// Extract just the flag part
|
|
345
|
-
const cleanFlags = flags.map((f) => f.split(/\s+/)[0]);
|
|
346
|
-
|
|
347
|
-
if (cleanFlags.length > 1) {
|
|
348
|
-
// Multiple flags (short and long): '(-v --verbose)'{-v,--verbose}'[description]'
|
|
349
|
-
const short = cleanFlags[0];
|
|
350
|
-
const long = cleanFlags[1];
|
|
351
|
-
return `'(${short} ${long})'{${short},${long}}'[${desc}]'`;
|
|
352
|
-
} else {
|
|
353
|
-
// Single flag: '--flag[description]'
|
|
354
|
-
return `'${cleanFlags[0]}[${desc}]'`;
|
|
355
|
-
}
|
|
356
|
-
})
|
|
357
|
-
.join(" \\\n ");
|
|
358
|
-
|
|
359
|
-
return options
|
|
360
|
-
? ` ${cmd.name()})
|
|
361
|
-
_arguments \\
|
|
362
|
-
${options}
|
|
363
|
-
;;`
|
|
364
|
-
: "";
|
|
365
|
-
})
|
|
366
|
-
.filter(Boolean)
|
|
367
|
-
.join("\n");
|
|
368
|
-
|
|
369
|
-
const completionScript = `
|
|
370
|
-
# pushwork completion for zsh
|
|
371
|
-
_pushwork() {
|
|
372
|
-
local -a commands
|
|
373
|
-
commands=(${commands})
|
|
374
|
-
|
|
375
|
-
_arguments -C \\
|
|
376
|
-
'1: :->command' \\
|
|
377
|
-
'*::arg:->args'
|
|
378
|
-
|
|
379
|
-
case $state in
|
|
380
|
-
command)
|
|
381
|
-
_describe 'command' commands
|
|
382
|
-
;;
|
|
383
|
-
args)
|
|
384
|
-
case $words[1] in
|
|
385
|
-
${commandCases}
|
|
386
|
-
esac
|
|
387
|
-
;;
|
|
388
|
-
esac
|
|
389
|
-
}
|
|
390
|
-
|
|
391
|
-
compdef _pushwork pushwork
|
|
392
|
-
`.trim();
|
|
393
|
-
|
|
394
|
-
console.log(completionScript);
|
|
395
|
-
});
|
|
396
|
-
|
|
397
|
-
process.on("unhandledRejection", (error) => {
|
|
398
|
-
console.log(chalk.bgRed.white(" ERROR "));
|
|
399
|
-
if (error instanceof Error && error.stack) {
|
|
400
|
-
console.log(chalk.red(error.stack));
|
|
401
|
-
} else {
|
|
402
|
-
console.error(chalk.red(error));
|
|
403
|
-
}
|
|
404
|
-
process.exit(1);
|
|
405
|
-
});
|
|
406
|
-
|
|
407
|
-
// Configure help colors using Commander v13's built-in color support
|
|
408
|
-
program
|
|
409
|
-
.configureHelp({
|
|
410
|
-
styleTitle: (str) => chalk.bold(str),
|
|
411
|
-
styleCommandText: (str) => chalk.white(str),
|
|
412
|
-
styleCommandDescription: (str) => chalk.dim(str),
|
|
413
|
-
styleOptionText: (str) => chalk.green(str),
|
|
414
|
-
styleArgumentText: (str) => chalk.cyan(str),
|
|
415
|
-
subcommandTerm: (cmd) => {
|
|
416
|
-
const opts = cmd.options
|
|
417
|
-
.filter((opt) => opt.flags !== "-h, --help")
|
|
418
|
-
.map((opt) => opt.short || opt.long)
|
|
419
|
-
.join(", ");
|
|
420
|
-
|
|
421
|
-
const name = chalk.white(cmd.name());
|
|
422
|
-
const args = cmd.registeredArguments
|
|
423
|
-
.map((arg) =>
|
|
424
|
-
arg.required
|
|
425
|
-
? chalk.cyan(`<${arg.name()}>`)
|
|
426
|
-
: chalk.dim(`[${arg.name()}]`)
|
|
427
|
-
)
|
|
428
|
-
.join(" ");
|
|
429
|
-
|
|
430
|
-
return [name, args, opts && chalk.dim(`[${opts}]`)]
|
|
431
|
-
.filter(Boolean)
|
|
432
|
-
.join(" ");
|
|
433
|
-
},
|
|
434
|
-
})
|
|
435
|
-
.addHelpText(
|
|
436
|
-
"after",
|
|
437
|
-
chalk.dim(
|
|
438
|
-
'\nEnable tab completion by adding this to your ~/.zshrc:\neval "$(pushwork completion)"'
|
|
439
|
-
)
|
|
440
|
-
);
|
|
441
|
-
|
|
442
|
-
program.parseAsync();
|