@askalf/claude-sync 0.0.3 → 0.1.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 +72 -38
- package/dist/cli.d.ts +2 -0
- package/dist/cli.d.ts.map +1 -1
- package/dist/cli.js +212 -21
- package/dist/cli.js.map +1 -1
- package/dist/config.js +2 -2
- package/dist/config.js.map +1 -1
- package/dist/format.d.ts.map +1 -1
- package/dist/format.js +2 -1
- package/dist/format.js.map +1 -1
- package/dist/index.d.ts +3 -3
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +3 -3
- package/dist/index.js.map +1 -1
- package/dist/project.d.ts +39 -8
- package/dist/project.d.ts.map +1 -1
- package/dist/project.js +98 -15
- package/dist/project.js.map +1 -1
- package/dist/session.d.ts +17 -5
- package/dist/session.d.ts.map +1 -1
- package/dist/session.js +25 -12
- package/dist/session.js.map +1 -1
- package/dist/transport.d.ts +7 -0
- package/dist/transport.d.ts.map +1 -1
- package/dist/transport.js +28 -0
- package/dist/transport.js.map +1 -1
- package/package.json +3 -3
package/dist/config.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"config.js","sourceRoot":"","sources":["../src/config.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;GAoBG;AAEH,OAAO,EAAE,UAAU,EAAE,YAAY,EAAE,aAAa,EAAE,SAAS,EAAE,MAAM,SAAS,CAAC;AAC7E,OAAO,EAAE,OAAO,EAAE,IAAI,EAAE,MAAM,WAAW,CAAC;AAC1C,OAAO,EAAE,QAAQ,EAAE,MAAM,SAAS,CAAC;AACnC,OAAO,EAAE,QAAQ,EAAE,MAAM,cAAc,CAAC;
|
|
1
|
+
{"version":3,"file":"config.js","sourceRoot":"","sources":["../src/config.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;GAoBG;AAEH,OAAO,EAAE,UAAU,EAAE,YAAY,EAAE,aAAa,EAAE,SAAS,EAAE,MAAM,SAAS,CAAC;AAC7E,OAAO,EAAE,OAAO,EAAE,IAAI,EAAE,MAAM,WAAW,CAAC;AAC1C,OAAO,EAAE,QAAQ,EAAE,MAAM,SAAS,CAAC;AACnC,OAAO,EAAE,QAAQ,EAAE,QAAQ,EAAE,MAAM,cAAc,CAAC;AAalD,MAAM,WAAW,GAAG,GAAW,EAAE,CAAC,IAAI,CAAC,QAAQ,EAAE,EAAE,aAAa,CAAC,CAAC;AAElE,MAAM,UAAU,YAAY;IAC1B,OAAO,UAAU,CAAC,WAAW,EAAE,CAAC,CAAC;AACnC,CAAC;AAED,MAAM,UAAU,UAAU;IACxB,MAAM,IAAI,GAAG,WAAW,EAAE,CAAC;IAC3B,IAAI,CAAC,UAAU,CAAC,IAAI,CAAC,EAAE,CAAC;QACtB,MAAM,IAAI,KAAK,CACb,sBAAsB,IAAI,6CAA6C,CACxE,CAAC;IACJ,CAAC;IACD,MAAM,MAAM,GAAG,IAAI,CAAC,KAAK,CAAC,QAAQ,CAAC,YAAY,CAAC,IAAI,EAAE,OAAO,CAAC,CAAC,CAAW,CAAC;IAC3E,IAAI,MAAM,CAAC,cAAc,KAAK,CAAC,EAAE,CAAC;QAChC,MAAM,IAAI,KAAK,CAAC,sCAAsC,MAAM,CAAC,cAAc,EAAE,CAAC,CAAC;IACjF,CAAC;IACD,OAAO,MAAM,CAAC;AAChB,CAAC;AAED,MAAM,UAAU,UAAU,CAAC,GAAW;IACpC,MAAM,IAAI,GAAG,WAAW,EAAE,CAAC;IAC3B,IAAI,CAAC,UAAU,CAAC,OAAO,CAAC,IAAI,CAAC,CAAC;QAAE,SAAS,CAAC,OAAO,CAAC,IAAI,CAAC,EAAE,EAAE,SAAS,EAAE,IAAI,EAAE,CAAC,CAAC;IAC9E,aAAa,CAAC,IAAI,EAAE,IAAI,CAAC,SAAS,CAAC,GAAG,EAAE,IAAI,EAAE,CAAC,CAAC,EAAE,EAAE,IAAI,EAAE,KAAK,EAAE,CAAC,CAAC;AACrE,CAAC;AAED,MAAM,UAAU,kBAAkB;IAChC,oEAAoE;IACpE,4CAA4C;IAC5C,OAAO,QAAQ,EAAE,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,IAAI,SAAS,CAAC;AAC/C,CAAC;AAED,MAAM,UAAU,kBAAkB,CAAC,OAAe,EAAE,WAAoB;IACtE,OAAO;QACL,cAAc,EAAE,CAAC;QACjB,OAAO;QACP,WAAW,EAAE,WAAW,IAAI,kBAAkB,EAAE;KACjD,CAAC;AACJ,CAAC"}
|
package/dist/format.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"format.d.ts","sourceRoot":"","sources":["../src/format.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;GAuBG;
|
|
1
|
+
{"version":3,"file":"format.d.ts","sourceRoot":"","sources":["../src/format.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;GAuBG;AAKH,MAAM,WAAW,UAAU;IACzB,cAAc,EAAE,CAAC,CAAC;IAClB,SAAS,EAAE,MAAM,CAAC;IAClB,UAAU,EAAE,MAAM,CAAC;IACnB;;gBAEY;IACZ,WAAW,EAAE,MAAM,CAAC;IACpB;uBACmB;IACnB,WAAW,EAAE,MAAM,CAAC;IACpB;2EACuE;IACvE,UAAU,EAAE,MAAM,CAAC;IACnB;4DACwD;IACxD,SAAS,EAAE,MAAM,CAAC;IAClB,wCAAwC;IACxC,KAAK,EAAE,MAAM,CAAC;CACf;AAED,eAAO,MAAM,sBAAsB,EAAG,CAAU,CAAC;AAEjD,wBAAgB,WAAW,CAAC,IAAI,EAAE,IAAI,CAAC,UAAU,EAAE,gBAAgB,CAAC,GAAG,UAAU,CAKhF;AAED,wBAAgB,eAAe,CAAC,IAAI,EAAE,UAAU,GAAG,MAAM,CAKxD;AAED,wBAAgB,WAAW,CAAC,GAAG,EAAE,MAAM,GAAG,UAAU,CAwCnD;AAED,wBAAgB,cAAc,CAAC,IAAI,EAAE,MAAM,GAAG,UAAU,CAEvD;AAED,wBAAgB,eAAe,CAAC,IAAI,EAAE,MAAM,EAAE,IAAI,EAAE,UAAU,GAAG,IAAI,CAEpE"}
|
package/dist/format.js
CHANGED
|
@@ -23,6 +23,7 @@
|
|
|
23
23
|
* rather than silently dropping fields.
|
|
24
24
|
*/
|
|
25
25
|
import { readFileSync, writeFileSync } from 'node:fs';
|
|
26
|
+
import { stripBom } from './project.js';
|
|
26
27
|
export const CURRENT_SCHEMA_VERSION = 1;
|
|
27
28
|
export function buildCcsync(opts) {
|
|
28
29
|
return {
|
|
@@ -39,7 +40,7 @@ export function serializeCcsync(file) {
|
|
|
39
40
|
export function parseCcsync(raw) {
|
|
40
41
|
let parsed;
|
|
41
42
|
try {
|
|
42
|
-
parsed = JSON.parse(raw);
|
|
43
|
+
parsed = JSON.parse(stripBom(raw));
|
|
43
44
|
}
|
|
44
45
|
catch (err) {
|
|
45
46
|
throw new Error(`Not a valid .ccsync file (JSON parse failed): ${err instanceof Error ? err.message : err}`);
|
package/dist/format.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"format.js","sourceRoot":"","sources":["../src/format.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;GAuBG;AAEH,OAAO,EAAE,YAAY,EAAE,aAAa,EAAE,MAAM,SAAS,CAAC;
|
|
1
|
+
{"version":3,"file":"format.js","sourceRoot":"","sources":["../src/format.ts"],"names":[],"mappings":"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"}
|
package/dist/index.d.ts
CHANGED
|
@@ -7,11 +7,11 @@
|
|
|
7
7
|
* GitHub Action that snapshots sessions, or an alternative transport
|
|
8
8
|
* (S3, gist, custom relay).
|
|
9
9
|
*/
|
|
10
|
-
export { encodeProjectDir, claudeProjectsRoot, syncRoot, gitRemoteUrl, projectKey, loadRegistry, saveRegistry, registerProject, lookupCwd, type ProjectRegistry, } from './project.js';
|
|
11
|
-
export { listSessions, readSession, writeSession, assignFreshId, type SessionMetadata, } from './session.js';
|
|
10
|
+
export { encodeProjectDir, stripBom, claudeProjectsRoot, syncRoot, gitRemoteUrl, normalizeGitRemote, projectKey, loadRegistry, saveRegistry, registerProject, registerProjectKey, lookupCwd, type ProjectRegistry, } from './project.js';
|
|
11
|
+
export { listSessions, listSessionStats, countSessionLines, readSession, writeSession, assignFreshId, type SessionMetadata, type SessionStat, } from './session.js';
|
|
12
12
|
export { buildCcsync, serializeCcsync, parseCcsync, readCcsyncFile, writeCcsyncFile, CURRENT_SCHEMA_VERSION, type CcsyncFile, } from './format.js';
|
|
13
13
|
export { loadConfig, saveConfig, configExists, defaultMachineName, buildDefaultConfig, type Config, } from './config.js';
|
|
14
|
-
export { projectSubdir, pushToTransport, listTransport, listProjectKeys, type TransportEntry, } from './transport.js';
|
|
14
|
+
export { projectSubdir, pushToTransport, listTransport, listTransportMachines, listProjectKeys, type TransportEntry, } from './transport.js';
|
|
15
15
|
/** Single source of truth: read the version straight from package.json
|
|
16
16
|
* so the published version can never drift from the runtime/CLI banner.
|
|
17
17
|
* dist layout is `dist/index.js`, so `../package.json` resolves to the
|
package/dist/index.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA;;;;;;;;GAQG;AAIH,OAAO,EACL,gBAAgB,EAChB,kBAAkB,EAClB,QAAQ,EACR,YAAY,EACZ,UAAU,EACV,YAAY,EACZ,YAAY,EACZ,eAAe,EACf,SAAS,EACT,KAAK,eAAe,GACrB,MAAM,cAAc,CAAC;AAEtB,OAAO,EACL,YAAY,EACZ,WAAW,EACX,YAAY,EACZ,aAAa,EACb,KAAK,eAAe,
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA;;;;;;;;GAQG;AAIH,OAAO,EACL,gBAAgB,EAChB,QAAQ,EACR,kBAAkB,EAClB,QAAQ,EACR,YAAY,EACZ,kBAAkB,EAClB,UAAU,EACV,YAAY,EACZ,YAAY,EACZ,eAAe,EACf,kBAAkB,EAClB,SAAS,EACT,KAAK,eAAe,GACrB,MAAM,cAAc,CAAC;AAEtB,OAAO,EACL,YAAY,EACZ,gBAAgB,EAChB,iBAAiB,EACjB,WAAW,EACX,YAAY,EACZ,aAAa,EACb,KAAK,eAAe,EACpB,KAAK,WAAW,GACjB,MAAM,cAAc,CAAC;AAEtB,OAAO,EACL,WAAW,EACX,eAAe,EACf,WAAW,EACX,cAAc,EACd,eAAe,EACf,sBAAsB,EACtB,KAAK,UAAU,GAChB,MAAM,aAAa,CAAC;AAErB,OAAO,EACL,UAAU,EACV,UAAU,EACV,YAAY,EACZ,kBAAkB,EAClB,kBAAkB,EAClB,KAAK,MAAM,GACZ,MAAM,aAAa,CAAC;AAErB,OAAO,EACL,aAAa,EACb,eAAe,EACf,aAAa,EACb,qBAAqB,EACrB,eAAe,EACf,KAAK,cAAc,GACpB,MAAM,gBAAgB,CAAC;AAExB;;;8CAG8C;AAC9C,eAAO,MAAM,OAAO,EAAE,MAAoB,CAAC"}
|
package/dist/index.js
CHANGED
|
@@ -8,11 +8,11 @@
|
|
|
8
8
|
* (S3, gist, custom relay).
|
|
9
9
|
*/
|
|
10
10
|
import pkg from '../package.json' with { type: 'json' };
|
|
11
|
-
export { encodeProjectDir, claudeProjectsRoot, syncRoot, gitRemoteUrl, projectKey, loadRegistry, saveRegistry, registerProject, lookupCwd, } from './project.js';
|
|
12
|
-
export { listSessions, readSession, writeSession, assignFreshId, } from './session.js';
|
|
11
|
+
export { encodeProjectDir, stripBom, claudeProjectsRoot, syncRoot, gitRemoteUrl, normalizeGitRemote, projectKey, loadRegistry, saveRegistry, registerProject, registerProjectKey, lookupCwd, } from './project.js';
|
|
12
|
+
export { listSessions, listSessionStats, countSessionLines, readSession, writeSession, assignFreshId, } from './session.js';
|
|
13
13
|
export { buildCcsync, serializeCcsync, parseCcsync, readCcsyncFile, writeCcsyncFile, CURRENT_SCHEMA_VERSION, } from './format.js';
|
|
14
14
|
export { loadConfig, saveConfig, configExists, defaultMachineName, buildDefaultConfig, } from './config.js';
|
|
15
|
-
export { projectSubdir, pushToTransport, listTransport, listProjectKeys, } from './transport.js';
|
|
15
|
+
export { projectSubdir, pushToTransport, listTransport, listTransportMachines, listProjectKeys, } from './transport.js';
|
|
16
16
|
/** Single source of truth: read the version straight from package.json
|
|
17
17
|
* so the published version can never drift from the runtime/CLI banner.
|
|
18
18
|
* dist layout is `dist/index.js`, so `../package.json` resolves to the
|
package/dist/index.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA;;;;;;;;GAQG;AAEH,OAAO,GAAG,MAAM,iBAAiB,CAAC,OAAO,IAAI,EAAE,MAAM,EAAE,CAAC;AAExD,OAAO,EACL,gBAAgB,EAChB,kBAAkB,EAClB,QAAQ,EACR,YAAY,EACZ,UAAU,EACV,YAAY,EACZ,YAAY,EACZ,eAAe,EACf,SAAS,GAEV,MAAM,cAAc,CAAC;AAEtB,OAAO,EACL,YAAY,EACZ,WAAW,EACX,YAAY,EACZ,aAAa,
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA;;;;;;;;GAQG;AAEH,OAAO,GAAG,MAAM,iBAAiB,CAAC,OAAO,IAAI,EAAE,MAAM,EAAE,CAAC;AAExD,OAAO,EACL,gBAAgB,EAChB,QAAQ,EACR,kBAAkB,EAClB,QAAQ,EACR,YAAY,EACZ,kBAAkB,EAClB,UAAU,EACV,YAAY,EACZ,YAAY,EACZ,eAAe,EACf,kBAAkB,EAClB,SAAS,GAEV,MAAM,cAAc,CAAC;AAEtB,OAAO,EACL,YAAY,EACZ,gBAAgB,EAChB,iBAAiB,EACjB,WAAW,EACX,YAAY,EACZ,aAAa,GAGd,MAAM,cAAc,CAAC;AAEtB,OAAO,EACL,WAAW,EACX,eAAe,EACf,WAAW,EACX,cAAc,EACd,eAAe,EACf,sBAAsB,GAEvB,MAAM,aAAa,CAAC;AAErB,OAAO,EACL,UAAU,EACV,UAAU,EACV,YAAY,EACZ,kBAAkB,EAClB,kBAAkB,GAEnB,MAAM,aAAa,CAAC;AAErB,OAAO,EACL,aAAa,EACb,eAAe,EACf,aAAa,EACb,qBAAqB,EACrB,eAAe,GAEhB,MAAM,gBAAgB,CAAC;AAExB;;;8CAG8C;AAC9C,MAAM,CAAC,MAAM,OAAO,GAAW,GAAG,CAAC,OAAO,CAAC"}
|
package/dist/project.d.ts
CHANGED
|
@@ -18,6 +18,12 @@
|
|
|
18
18
|
* - Reverse lookup: given a project key + a registry of local repo
|
|
19
19
|
* locations, pick the right local cwd to install a session into.
|
|
20
20
|
*/
|
|
21
|
+
/** Strip a leading UTF-8 BOM (``) if present. Windows editors
|
|
22
|
+
* (Notepad, some PowerShell `Set-Content` modes) prepend one, and
|
|
23
|
+
* `JSON.parse` rejects it with a cryptic "Unexpected token" — so a user
|
|
24
|
+
* who hand-edits config.json / projects.json on Windows would otherwise
|
|
25
|
+
* crash every command. We tolerate it on read. */
|
|
26
|
+
export declare function stripBom(s: string): string;
|
|
21
27
|
/** Encode a cwd into Claude Code's project-directory format. CC replaces
|
|
22
28
|
* EACH non-alphanumeric character with a single `-` (no run-collapsing),
|
|
23
29
|
* so `C:\Users\me\my app` → `C--Users-me-my-app` and `/root/.askalf/x`
|
|
@@ -49,16 +55,36 @@ export declare function syncRoot(): string;
|
|
|
49
55
|
* - the repo has no remote configured (greenfield, not yet pushed)
|
|
50
56
|
*
|
|
51
57
|
* Trims trailing whitespace + newlines but otherwise leaves the URL
|
|
52
|
-
* exactly as `git` reported.
|
|
53
|
-
* `
|
|
54
|
-
*
|
|
55
|
-
* normalizing one of the two via `git remote set-url`, or by manually
|
|
56
|
-
* registering both in the project registry under one canonical key. */
|
|
58
|
+
* exactly as `git` reported. `projectKey` runs the result through
|
|
59
|
+
* `normalizeGitRemote` so the same repo over SSH and HTTPS resolves to a
|
|
60
|
+
* single key. */
|
|
57
61
|
export declare function gitRemoteUrl(cwd: string): string | null;
|
|
62
|
+
/** Canonicalize a git remote URL so the same repo addressed over
|
|
63
|
+
* different protocols resolves to ONE project key. These all collapse to
|
|
64
|
+
* `github.com/owner/repo`:
|
|
65
|
+
*
|
|
66
|
+
* https://github.com/owner/repo.git
|
|
67
|
+
* https://github.com/owner/repo
|
|
68
|
+
* git@github.com:owner/repo.git (scp-like syntax)
|
|
69
|
+
* ssh://git@github.com/owner/repo.git
|
|
70
|
+
* git://github.com/owner/repo.git
|
|
71
|
+
*
|
|
72
|
+
* The host is lowercased (DNS is case-insensitive); the repo path keeps
|
|
73
|
+
* its case (some forges are case-sensitive). A `git@`/`user@` prefix and
|
|
74
|
+
* any explicit port are dropped — they don't change repo identity — and a
|
|
75
|
+
* single trailing `.git` plus surrounding slashes are trimmed.
|
|
76
|
+
*
|
|
77
|
+
* Anything that doesn't parse as one of these shapes (a bare local path,
|
|
78
|
+
* `file://`, an exotic transport) is returned trimmed-but-otherwise
|
|
79
|
+
* unchanged, so we only ever *canonicalize* the common cases — never lose
|
|
80
|
+
* a key by mangling one we don't recognize. */
|
|
81
|
+
export declare function normalizeGitRemote(url: string): string;
|
|
58
82
|
/** Compute a stable, machine-portable project key for a cwd. Prefers the
|
|
59
|
-
* git remote URL
|
|
60
|
-
*
|
|
61
|
-
*
|
|
83
|
+
* git remote URL (canonicalized via `normalizeGitRemote`, so SSH and
|
|
84
|
+
* HTTPS clones of the same repo share a key); falls back to the directory
|
|
85
|
+
* basename when no remote is configured. The basename fallback is
|
|
86
|
+
* best-effort — collisions between unrelated projects with the same name
|
|
87
|
+
* are possible. */
|
|
62
88
|
export declare function projectKey(cwd: string): string;
|
|
63
89
|
/** Local-project registry. Maps a project key to the local cwd on this
|
|
64
90
|
* machine. Built up as the user runs `claude-sync export` (which
|
|
@@ -77,6 +103,11 @@ export interface ProjectRegistry {
|
|
|
77
103
|
}
|
|
78
104
|
export declare function loadRegistry(): ProjectRegistry;
|
|
79
105
|
export declare function saveRegistry(reg: ProjectRegistry): void;
|
|
106
|
+
/** Register a cwd under an explicit project key. Idempotent. Used by
|
|
107
|
+
* `import` to bind a *peer's* project key to a local directory so later
|
|
108
|
+
* `pull`s resolve it — even when this machine isn't a git repo for that
|
|
109
|
+
* path, or computes the key slightly differently. */
|
|
110
|
+
export declare function registerProjectKey(key: string, cwd: string): ProjectRegistry;
|
|
80
111
|
/** Register a cwd under its computed project key. Idempotent; pushing
|
|
81
112
|
* the same cwd twice doesn't create duplicates. */
|
|
82
113
|
export declare function registerProject(cwd: string): {
|
package/dist/project.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"project.d.ts","sourceRoot":"","sources":["../src/project.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;GAmBG;AAOH;;;;;;;;;;;oEAWoE;AACpE,wBAAgB,gBAAgB,CAAC,GAAG,EAAE,MAAM,GAAG,MAAM,CAEpD;AAED;;;;;iDAKiD;AACjD,wBAAgB,UAAU,IAAI,MAAM,CAEnC;AAED,wDAAwD;AACxD,wBAAgB,kBAAkB,IAAI,MAAM,CAE3C;AAED;uCACuC;AACvC,wBAAgB,QAAQ,IAAI,MAAM,CAEjC;AAED
|
|
1
|
+
{"version":3,"file":"project.d.ts","sourceRoot":"","sources":["../src/project.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;GAmBG;AAOH;;;;mDAImD;AACnD,wBAAgB,QAAQ,CAAC,CAAC,EAAE,MAAM,GAAG,MAAM,CAE1C;AAED;;;;;;;;;;;oEAWoE;AACpE,wBAAgB,gBAAgB,CAAC,GAAG,EAAE,MAAM,GAAG,MAAM,CAEpD;AAED;;;;;iDAKiD;AACjD,wBAAgB,UAAU,IAAI,MAAM,CAEnC;AAED,wDAAwD;AACxD,wBAAgB,kBAAkB,IAAI,MAAM,CAE3C;AAED;uCACuC;AACvC,wBAAgB,QAAQ,IAAI,MAAM,CAEjC;AAED;;;;;;;;iBAQiB;AACjB,wBAAgB,YAAY,CAAC,GAAG,EAAE,MAAM,GAAG,MAAM,GAAG,IAAI,CAavD;AAED;;;;;;;;;;;;;;;;;;gDAkBgD;AAChD,wBAAgB,kBAAkB,CAAC,GAAG,EAAE,MAAM,GAAG,MAAM,CA0CtD;AAED;;;;;oBAKoB;AACpB,wBAAgB,UAAU,CAAC,GAAG,EAAE,MAAM,GAAG,MAAM,CAI9C;AAED;;;yCAGyC;AACzC,MAAM,WAAW,eAAe;IAC9B,cAAc,EAAE,CAAC,CAAC;IAClB;oEACgE;IAChE,WAAW,EAAE,MAAM,CAAC;IACpB;;;mDAG+C;IAC/C,QAAQ,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,EAAE,CAAC,CAAC;CACpC;AAID,wBAAgB,YAAY,IAAI,eAAe,CAmB9C;AAED,wBAAgB,YAAY,CAAC,GAAG,EAAE,eAAe,GAAG,IAAI,CAUvD;AAED;;;sDAGsD;AACtD,wBAAgB,kBAAkB,CAAC,GAAG,EAAE,MAAM,EAAE,GAAG,EAAE,MAAM,GAAG,eAAe,CAQ5E;AAED;oDACoD;AACpD,wBAAgB,eAAe,CAAC,GAAG,EAAE,MAAM,GAAG;IAAE,GAAG,EAAE,MAAM,CAAC;IAAC,QAAQ,EAAE,eAAe,CAAA;CAAE,CAIvF;AAED;;;;eAIe;AACf,wBAAgB,SAAS,CAAC,GAAG,EAAE,MAAM,EAAE,GAAG,CAAC,EAAE,eAAe,GAAG,MAAM,GAAG,IAAI,CAQ3E"}
|
package/dist/project.js
CHANGED
|
@@ -22,6 +22,14 @@ import { execSync } from 'node:child_process';
|
|
|
22
22
|
import { existsSync, readFileSync, writeFileSync, mkdirSync, renameSync } from 'node:fs';
|
|
23
23
|
import { dirname, basename, join } from 'node:path';
|
|
24
24
|
import { homedir } from 'node:os';
|
|
25
|
+
/** Strip a leading UTF-8 BOM (``) if present. Windows editors
|
|
26
|
+
* (Notepad, some PowerShell `Set-Content` modes) prepend one, and
|
|
27
|
+
* `JSON.parse` rejects it with a cryptic "Unexpected token" — so a user
|
|
28
|
+
* who hand-edits config.json / projects.json on Windows would otherwise
|
|
29
|
+
* crash every command. We tolerate it on read. */
|
|
30
|
+
export function stripBom(s) {
|
|
31
|
+
return s.charCodeAt(0) === 0xfeff ? s.slice(1) : s;
|
|
32
|
+
}
|
|
25
33
|
/** Encode a cwd into Claude Code's project-directory format. CC replaces
|
|
26
34
|
* EACH non-alphanumeric character with a single `-` (no run-collapsing),
|
|
27
35
|
* so `C:\Users\me\my app` → `C--Users-me-my-app` and `/root/.askalf/x`
|
|
@@ -61,11 +69,9 @@ export function syncRoot() {
|
|
|
61
69
|
* - the repo has no remote configured (greenfield, not yet pushed)
|
|
62
70
|
*
|
|
63
71
|
* Trims trailing whitespace + newlines but otherwise leaves the URL
|
|
64
|
-
* exactly as `git` reported.
|
|
65
|
-
* `
|
|
66
|
-
*
|
|
67
|
-
* normalizing one of the two via `git remote set-url`, or by manually
|
|
68
|
-
* registering both in the project registry under one canonical key. */
|
|
72
|
+
* exactly as `git` reported. `projectKey` runs the result through
|
|
73
|
+
* `normalizeGitRemote` so the same repo over SSH and HTTPS resolves to a
|
|
74
|
+
* single key. */
|
|
69
75
|
export function gitRemoteUrl(cwd) {
|
|
70
76
|
if (!existsSync(join(cwd, '.git')))
|
|
71
77
|
return null;
|
|
@@ -82,14 +88,83 @@ export function gitRemoteUrl(cwd) {
|
|
|
82
88
|
return null;
|
|
83
89
|
}
|
|
84
90
|
}
|
|
91
|
+
/** Canonicalize a git remote URL so the same repo addressed over
|
|
92
|
+
* different protocols resolves to ONE project key. These all collapse to
|
|
93
|
+
* `github.com/owner/repo`:
|
|
94
|
+
*
|
|
95
|
+
* https://github.com/owner/repo.git
|
|
96
|
+
* https://github.com/owner/repo
|
|
97
|
+
* git@github.com:owner/repo.git (scp-like syntax)
|
|
98
|
+
* ssh://git@github.com/owner/repo.git
|
|
99
|
+
* git://github.com/owner/repo.git
|
|
100
|
+
*
|
|
101
|
+
* The host is lowercased (DNS is case-insensitive); the repo path keeps
|
|
102
|
+
* its case (some forges are case-sensitive). A `git@`/`user@` prefix and
|
|
103
|
+
* any explicit port are dropped — they don't change repo identity — and a
|
|
104
|
+
* single trailing `.git` plus surrounding slashes are trimmed.
|
|
105
|
+
*
|
|
106
|
+
* Anything that doesn't parse as one of these shapes (a bare local path,
|
|
107
|
+
* `file://`, an exotic transport) is returned trimmed-but-otherwise
|
|
108
|
+
* unchanged, so we only ever *canonicalize* the common cases — never lose
|
|
109
|
+
* a key by mangling one we don't recognize. */
|
|
110
|
+
export function normalizeGitRemote(url) {
|
|
111
|
+
const raw = url.trim();
|
|
112
|
+
let host;
|
|
113
|
+
let path;
|
|
114
|
+
if (/^[a-zA-Z][a-zA-Z0-9+.-]*:\/\//.test(raw)) {
|
|
115
|
+
// scheme://[user@]host[:port]/path
|
|
116
|
+
try {
|
|
117
|
+
const u = new URL(raw);
|
|
118
|
+
host = u.hostname;
|
|
119
|
+
path = u.pathname;
|
|
120
|
+
}
|
|
121
|
+
catch {
|
|
122
|
+
return raw;
|
|
123
|
+
}
|
|
124
|
+
}
|
|
125
|
+
else {
|
|
126
|
+
// scp-like: [user@]host:path (e.g. git@github.com:owner/repo.git).
|
|
127
|
+
// Requires a colon and a path with no leading slash — a bare local
|
|
128
|
+
// path like /srv/git/repo.git has no colon and falls through.
|
|
129
|
+
const m = /^(?:[^@/]+@)?([^/:]+):(.+)$/.exec(raw);
|
|
130
|
+
if (m) {
|
|
131
|
+
host = m[1];
|
|
132
|
+
path = m[2];
|
|
133
|
+
}
|
|
134
|
+
else {
|
|
135
|
+
return raw;
|
|
136
|
+
}
|
|
137
|
+
}
|
|
138
|
+
if (!host || !path)
|
|
139
|
+
return raw;
|
|
140
|
+
// Trim surrounding slashes and a single trailing `.git`, WITHOUT a
|
|
141
|
+
// backtracking regex: `/\/+$/` on a remote URL we don't control is a
|
|
142
|
+
// polynomial-ReDoS vector (flagged by CodeQL). A linear two-pointer
|
|
143
|
+
// trim + an endsWith check is both safe and clearer.
|
|
144
|
+
let lo = 0;
|
|
145
|
+
let hi = path.length;
|
|
146
|
+
while (lo < hi && path[lo] === '/')
|
|
147
|
+
lo++;
|
|
148
|
+
while (hi > lo && path[hi - 1] === '/')
|
|
149
|
+
hi--;
|
|
150
|
+
let cleanPath = path.slice(lo, hi);
|
|
151
|
+
if (cleanPath.toLowerCase().endsWith('.git')) {
|
|
152
|
+
cleanPath = cleanPath.slice(0, -4);
|
|
153
|
+
}
|
|
154
|
+
if (!cleanPath)
|
|
155
|
+
return raw;
|
|
156
|
+
return `${host.toLowerCase()}/${cleanPath}`;
|
|
157
|
+
}
|
|
85
158
|
/** Compute a stable, machine-portable project key for a cwd. Prefers the
|
|
86
|
-
* git remote URL
|
|
87
|
-
*
|
|
88
|
-
*
|
|
159
|
+
* git remote URL (canonicalized via `normalizeGitRemote`, so SSH and
|
|
160
|
+
* HTTPS clones of the same repo share a key); falls back to the directory
|
|
161
|
+
* basename when no remote is configured. The basename fallback is
|
|
162
|
+
* best-effort — collisions between unrelated projects with the same name
|
|
163
|
+
* are possible. */
|
|
89
164
|
export function projectKey(cwd) {
|
|
90
165
|
const remote = gitRemoteUrl(cwd);
|
|
91
166
|
if (remote)
|
|
92
|
-
return `git:${remote}`;
|
|
167
|
+
return `git:${normalizeGitRemote(remote)}`;
|
|
93
168
|
return `name:${basename(cwd)}`;
|
|
94
169
|
}
|
|
95
170
|
const REGISTRY_PATH = () => join(syncRoot(), 'projects.json');
|
|
@@ -103,7 +178,7 @@ export function loadRegistry() {
|
|
|
103
178
|
};
|
|
104
179
|
}
|
|
105
180
|
try {
|
|
106
|
-
const raw = readFileSync(path, 'utf-8');
|
|
181
|
+
const raw = stripBom(readFileSync(path, 'utf-8'));
|
|
107
182
|
const parsed = JSON.parse(raw);
|
|
108
183
|
if (parsed._schemaVersion !== 1) {
|
|
109
184
|
throw new Error(`Unsupported registry schema version: ${parsed._schemaVersion}`);
|
|
@@ -126,17 +201,25 @@ export function saveRegistry(reg) {
|
|
|
126
201
|
// close enough for our uses (no concurrent registry writers).
|
|
127
202
|
renameSync(tmp, path);
|
|
128
203
|
}
|
|
129
|
-
/** Register a cwd under
|
|
130
|
-
*
|
|
131
|
-
|
|
204
|
+
/** Register a cwd under an explicit project key. Idempotent. Used by
|
|
205
|
+
* `import` to bind a *peer's* project key to a local directory so later
|
|
206
|
+
* `pull`s resolve it — even when this machine isn't a git repo for that
|
|
207
|
+
* path, or computes the key slightly differently. */
|
|
208
|
+
export function registerProjectKey(key, cwd) {
|
|
132
209
|
const reg = loadRegistry();
|
|
133
|
-
const key = projectKey(cwd);
|
|
134
210
|
const existing = reg.projects[key] ?? [];
|
|
135
211
|
if (!existing.includes(cwd)) {
|
|
136
212
|
reg.projects[key] = [...existing, cwd];
|
|
137
213
|
saveRegistry(reg);
|
|
138
214
|
}
|
|
139
|
-
return
|
|
215
|
+
return reg;
|
|
216
|
+
}
|
|
217
|
+
/** Register a cwd under its computed project key. Idempotent; pushing
|
|
218
|
+
* the same cwd twice doesn't create duplicates. */
|
|
219
|
+
export function registerProject(cwd) {
|
|
220
|
+
const key = projectKey(cwd);
|
|
221
|
+
const registry = registerProjectKey(key, cwd);
|
|
222
|
+
return { key, registry };
|
|
140
223
|
}
|
|
141
224
|
/** Look up a local cwd for a given project key. Returns the first
|
|
142
225
|
* registered match (registries are user-edited; they can reorder if
|
package/dist/project.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"project.js","sourceRoot":"","sources":["../src/project.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;GAmBG;AAEH,OAAO,EAAE,QAAQ,EAAE,MAAM,oBAAoB,CAAC;AAC9C,OAAO,EAAE,UAAU,EAAE,YAAY,EAAE,aAAa,EAAE,SAAS,EAAE,UAAU,EAAE,MAAM,SAAS,CAAC;AACzF,OAAO,EAAE,OAAO,EAAE,QAAQ,EAAE,IAAI,EAAE,MAAM,WAAW,CAAC;AACpD,OAAO,EAAE,OAAO,EAAE,MAAM,SAAS,CAAC;AAElC;;;;;;;;;;;oEAWoE;AACpE,MAAM,UAAU,gBAAgB,CAAC,GAAW;IAC1C,OAAO,GAAG,CAAC,OAAO,CAAC,eAAe,EAAE,GAAG,CAAC,CAAC;AAC3C,CAAC;AAED;;;;;iDAKiD;AACjD,MAAM,UAAU,UAAU;IACxB,OAAO,OAAO,CAAC,GAAG,CAAC,gBAAgB,IAAI,OAAO,EAAE,CAAC;AACnD,CAAC;AAED,wDAAwD;AACxD,MAAM,UAAU,kBAAkB;IAChC,OAAO,IAAI,CAAC,UAAU,EAAE,EAAE,SAAS,EAAE,UAAU,CAAC,CAAC;AACnD,CAAC;AAED;uCACuC;AACvC,MAAM,UAAU,QAAQ;IACtB,OAAO,IAAI,CAAC,UAAU,EAAE,EAAE,cAAc,CAAC,CAAC;AAC5C,CAAC;AAED
|
|
1
|
+
{"version":3,"file":"project.js","sourceRoot":"","sources":["../src/project.ts"],"names":[],"mappings":"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"}
|
package/dist/session.d.ts
CHANGED
|
@@ -8,7 +8,7 @@
|
|
|
8
8
|
* needing claude-sync changes.
|
|
9
9
|
*/
|
|
10
10
|
import { basename } from 'node:path';
|
|
11
|
-
export interface
|
|
11
|
+
export interface SessionStat {
|
|
12
12
|
id: string;
|
|
13
13
|
/** Local file path. Useful for the CLI to print where it found / put
|
|
14
14
|
* a session, but not part of the wire format — paths don't transfer
|
|
@@ -17,15 +17,23 @@ export interface SessionMetadata {
|
|
|
17
17
|
/** Bytes on disk. */
|
|
18
18
|
size: number;
|
|
19
19
|
/** Wall-clock mtime. Used to break ties when picking "the most recent
|
|
20
|
-
* session" for a project. */
|
|
20
|
+
* session" for a project — and to detect change cheaply in watch mode. */
|
|
21
21
|
modifiedAt: number;
|
|
22
|
+
}
|
|
23
|
+
export interface SessionMetadata extends SessionStat {
|
|
22
24
|
/** Number of newline-terminated JSONL records. Cheap proxy for
|
|
23
25
|
* message count — the CC schema means roughly one event per line. */
|
|
24
26
|
lineCount: number;
|
|
25
27
|
}
|
|
26
|
-
/**
|
|
27
|
-
* doesn't exist
|
|
28
|
-
*
|
|
28
|
+
/** Stat-only listing for a cwd — id, path, size, mtime, no line count.
|
|
29
|
+
* Returns [] if the project dir doesn't exist. Sorted by mtime
|
|
30
|
+
* descending. This is the cheap path: watch mode polls it every tick to
|
|
31
|
+
* spot changed sessions WITHOUT reading every file's contents to count
|
|
32
|
+
* lines (which `listSessions` does). */
|
|
33
|
+
export declare function listSessionStats(cwd: string): SessionStat[];
|
|
34
|
+
/** List sessions for a given local cwd, including line counts. Returns []
|
|
35
|
+
* if the project dir doesn't exist (no sessions yet). Sorted by mtime
|
|
36
|
+
* descending so the caller can grab `[0]` for "the most recent session". */
|
|
29
37
|
export declare function listSessions(cwd: string): SessionMetadata[];
|
|
30
38
|
/** Read a session's JSONL content. Returned as the raw bytes (no parse)
|
|
31
39
|
* so we don't have to know about CC's evolving message schema. */
|
|
@@ -50,5 +58,9 @@ export declare function writeSession(targetCwd: string, sessionId: string, jsonl
|
|
|
50
58
|
* practice; we mint a new one in the same shape so resume-by-id works
|
|
51
59
|
* consistently. */
|
|
52
60
|
export declare function assignFreshId(targetCwd: string, baseId: string): string;
|
|
61
|
+
/** Count newline-terminated records in a session file. Exported for watch
|
|
62
|
+
* mode, which counts lines only for the handful of sessions that changed
|
|
63
|
+
* since the last tick (the bulk listing stays on `listSessionStats`). */
|
|
64
|
+
export declare function countSessionLines(path: string): number;
|
|
53
65
|
export { basename as fileBasename };
|
|
54
66
|
//# sourceMappingURL=session.d.ts.map
|
package/dist/session.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"session.d.ts","sourceRoot":"","sources":["../src/session.ts"],"names":[],"mappings":"AAAA;;;;;;;;GAQG;AAMH,OAAO,EAAQ,QAAQ,EAAE,MAAM,WAAW,CAAC;AAG3C,MAAM,WAAW,
|
|
1
|
+
{"version":3,"file":"session.d.ts","sourceRoot":"","sources":["../src/session.ts"],"names":[],"mappings":"AAAA;;;;;;;;GAQG;AAMH,OAAO,EAAQ,QAAQ,EAAE,MAAM,WAAW,CAAC;AAG3C,MAAM,WAAW,WAAW;IAC1B,EAAE,EAAE,MAAM,CAAC;IACX;;2BAEuB;IACvB,IAAI,EAAE,MAAM,CAAC;IACb,qBAAqB;IACrB,IAAI,EAAE,MAAM,CAAC;IACb;+EAC2E;IAC3E,UAAU,EAAE,MAAM,CAAC;CACpB;AAED,MAAM,WAAW,eAAgB,SAAQ,WAAW;IAClD;0EACsE;IACtE,SAAS,EAAE,MAAM,CAAC;CACnB;AAED;;;;yCAIyC;AACzC,wBAAgB,gBAAgB,CAAC,GAAG,EAAE,MAAM,GAAG,WAAW,EAAE,CAqB3D;AAED;;6EAE6E;AAC7E,wBAAgB,YAAY,CAAC,GAAG,EAAE,MAAM,GAAG,eAAe,EAAE,CAE3D;AAED;mEACmE;AACnE,wBAAgB,WAAW,CAAC,IAAI,EAAE,MAAM,GAAG,MAAM,CAEhD;AAWD;;qDAEqD;AACrD,wBAAgB,mBAAmB,CAAC,SAAS,EAAE,MAAM,GAAG,IAAI,CAgB3D;AAED;;;;;;;0BAO0B;AAC1B,wBAAgB,YAAY,CAC1B,SAAS,EAAE,MAAM,EACjB,SAAS,EAAE,MAAM,EACjB,KAAK,EAAE,MAAM,EACb,IAAI,GAAE;IAAE,SAAS,CAAC,EAAE,OAAO,CAAA;CAAO,GACjC,MAAM,CAqBR;AAED;;;oBAGoB;AACpB,wBAAgB,aAAa,CAAC,SAAS,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,GAAG,MAAM,CASvE;AAED;;0EAE0E;AAC1E,wBAAgB,iBAAiB,CAAC,IAAI,EAAE,MAAM,GAAG,MAAM,CAEtD;AAsBD,OAAO,EAAE,QAAQ,IAAI,YAAY,EAAE,CAAC"}
|
package/dist/session.js
CHANGED
|
@@ -10,30 +10,37 @@
|
|
|
10
10
|
import { existsSync, readdirSync, readFileSync, writeFileSync, mkdirSync, statSync, openSync, readSync, closeSync, renameSync, } from 'node:fs';
|
|
11
11
|
import { join, basename } from 'node:path';
|
|
12
12
|
import { claudeProjectsRoot, encodeProjectDir } from './project.js';
|
|
13
|
-
/**
|
|
14
|
-
* doesn't exist
|
|
15
|
-
*
|
|
16
|
-
|
|
13
|
+
/** Stat-only listing for a cwd — id, path, size, mtime, no line count.
|
|
14
|
+
* Returns [] if the project dir doesn't exist. Sorted by mtime
|
|
15
|
+
* descending. This is the cheap path: watch mode polls it every tick to
|
|
16
|
+
* spot changed sessions WITHOUT reading every file's contents to count
|
|
17
|
+
* lines (which `listSessions` does). */
|
|
18
|
+
export function listSessionStats(cwd) {
|
|
17
19
|
const projDir = join(claudeProjectsRoot(), encodeProjectDir(cwd));
|
|
18
20
|
if (!existsSync(projDir))
|
|
19
21
|
return [];
|
|
20
22
|
const entries = readdirSync(projDir, { withFileTypes: true });
|
|
21
|
-
const
|
|
23
|
+
const stats = [];
|
|
22
24
|
for (const entry of entries) {
|
|
23
25
|
if (!entry.isFile() || !entry.name.endsWith('.jsonl'))
|
|
24
26
|
continue;
|
|
25
27
|
const path = join(projDir, entry.name);
|
|
26
|
-
const
|
|
27
|
-
|
|
28
|
+
const st = statSync(path);
|
|
29
|
+
stats.push({
|
|
28
30
|
id: entry.name.replace(/\.jsonl$/, ''),
|
|
29
31
|
path,
|
|
30
|
-
size:
|
|
31
|
-
modifiedAt:
|
|
32
|
-
lineCount: countLines(path),
|
|
32
|
+
size: st.size,
|
|
33
|
+
modifiedAt: st.mtimeMs,
|
|
33
34
|
});
|
|
34
35
|
}
|
|
35
|
-
|
|
36
|
-
return
|
|
36
|
+
stats.sort((a, b) => b.modifiedAt - a.modifiedAt);
|
|
37
|
+
return stats;
|
|
38
|
+
}
|
|
39
|
+
/** List sessions for a given local cwd, including line counts. Returns []
|
|
40
|
+
* if the project dir doesn't exist (no sessions yet). Sorted by mtime
|
|
41
|
+
* descending so the caller can grab `[0]` for "the most recent session". */
|
|
42
|
+
export function listSessions(cwd) {
|
|
43
|
+
return listSessionStats(cwd).map((s) => ({ ...s, lineCount: countLines(s.path) }));
|
|
37
44
|
}
|
|
38
45
|
/** Read a session's JSONL content. Returned as the raw bytes (no parse)
|
|
39
46
|
* so we don't have to know about CC's evolving message schema. */
|
|
@@ -108,6 +115,12 @@ export function assignFreshId(targetCwd, baseId) {
|
|
|
108
115
|
n++;
|
|
109
116
|
return `${baseId}-copy${n === 1 ? '' : `-${n}`}`;
|
|
110
117
|
}
|
|
118
|
+
/** Count newline-terminated records in a session file. Exported for watch
|
|
119
|
+
* mode, which counts lines only for the handful of sessions that changed
|
|
120
|
+
* since the last tick (the bulk listing stays on `listSessionStats`). */
|
|
121
|
+
export function countSessionLines(path) {
|
|
122
|
+
return countLines(path);
|
|
123
|
+
}
|
|
111
124
|
function countLines(path) {
|
|
112
125
|
// Fast newline count without buffering the whole file as a string —
|
|
113
126
|
// sessions can be large.
|
package/dist/session.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"session.js","sourceRoot":"","sources":["../src/session.ts"],"names":[],"mappings":"AAAA;;;;;;;;GAQG;AAEH,OAAO,EACL,UAAU,EAAE,WAAW,EAAE,YAAY,EAAE,aAAa,EAAE,SAAS,EAAE,QAAQ,EACzE,QAAQ,EAAE,QAAQ,EAAE,SAAS,EAAE,UAAU,GAC1C,MAAM,SAAS,CAAC;AACjB,OAAO,EAAE,IAAI,EAAE,QAAQ,EAAE,MAAM,WAAW,CAAC;AAC3C,OAAO,EAAE,kBAAkB,EAAE,gBAAgB,EAAE,MAAM,cAAc,CAAC;
|
|
1
|
+
{"version":3,"file":"session.js","sourceRoot":"","sources":["../src/session.ts"],"names":[],"mappings":"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"}
|
package/dist/transport.d.ts
CHANGED
|
@@ -34,6 +34,13 @@ export interface TransportEntry {
|
|
|
34
34
|
* `selfMachineName`) are omitted — pull is for receiving OTHER
|
|
35
35
|
* machines' work, not echoing your own. */
|
|
36
36
|
export declare function listTransport(syncDir: string, projectKey: string, selfMachineName: string): TransportEntry[];
|
|
37
|
+
/** Tally `machineName` → file count across every `.ccsync` in the
|
|
38
|
+
* transport (all projects). Used by `doctor` to catch the
|
|
39
|
+
* duplicate-machineName footgun: `pull` self-filters files whose
|
|
40
|
+
* machineName matches this machine's, so if two machines share a name —
|
|
41
|
+
* e.g. both defaulted to the same hostname — pull silently imports
|
|
42
|
+
* nothing. Malformed files are skipped quietly. */
|
|
43
|
+
export declare function listTransportMachines(syncDir: string): Map<string, number>;
|
|
37
44
|
/** List all project keys present in the transport. Used by the CLI's
|
|
38
45
|
* `pull` (no args) form to fan out across every known project. */
|
|
39
46
|
export declare function listProjectKeys(syncDir: string): string[];
|
package/dist/transport.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"transport.d.ts","sourceRoot":"","sources":["../src/transport.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;GAkBG;AAQH,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,aAAa,CAAC;AAG9C,wBAAgB,aAAa,CAAC,OAAO,EAAE,MAAM,EAAE,UAAU,EAAE,MAAM,GAAG,MAAM,CAEzE;AAED;;;gBAGgB;AAChB,wBAAgB,eAAe,CAAC,OAAO,EAAE,MAAM,EAAE,IAAI,EAAE,UAAU,GAAG,MAAM,CAWzE;AAED,MAAM,WAAW,cAAc;IAC7B,IAAI,EAAE,MAAM,CAAC;IACb,IAAI,EAAE,UAAU,CAAC;IACjB,KAAK,EAAE,MAAM,CAAC;CACf;AAED;;;4CAG4C;AAC5C,wBAAgB,aAAa,CAC3B,OAAO,EAAE,MAAM,EACf,UAAU,EAAE,MAAM,EAClB,eAAe,EAAE,MAAM,GACtB,cAAc,EAAE,CA0BlB;AAED;mEACmE;AACnE,wBAAgB,eAAe,CAAC,OAAO,EAAE,MAAM,GAAG,MAAM,EAAE,CAWzD"}
|
|
1
|
+
{"version":3,"file":"transport.d.ts","sourceRoot":"","sources":["../src/transport.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;GAkBG;AAQH,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,aAAa,CAAC;AAG9C,wBAAgB,aAAa,CAAC,OAAO,EAAE,MAAM,EAAE,UAAU,EAAE,MAAM,GAAG,MAAM,CAEzE;AAED;;;gBAGgB;AAChB,wBAAgB,eAAe,CAAC,OAAO,EAAE,MAAM,EAAE,IAAI,EAAE,UAAU,GAAG,MAAM,CAWzE;AAED,MAAM,WAAW,cAAc;IAC7B,IAAI,EAAE,MAAM,CAAC;IACb,IAAI,EAAE,UAAU,CAAC;IACjB,KAAK,EAAE,MAAM,CAAC;CACf;AAED;;;4CAG4C;AAC5C,wBAAgB,aAAa,CAC3B,OAAO,EAAE,MAAM,EACf,UAAU,EAAE,MAAM,EAClB,eAAe,EAAE,MAAM,GACtB,cAAc,EAAE,CA0BlB;AAED;;;;;oDAKoD;AACpD,wBAAgB,qBAAqB,CAAC,OAAO,EAAE,MAAM,GAAG,GAAG,CAAC,MAAM,EAAE,MAAM,CAAC,CAkB1E;AAED;mEACmE;AACnE,wBAAgB,eAAe,CAAC,OAAO,EAAE,MAAM,GAAG,MAAM,EAAE,CAWzD"}
|
package/dist/transport.js
CHANGED
|
@@ -73,6 +73,34 @@ export function listTransport(syncDir, projectKey, selfMachineName) {
|
|
|
73
73
|
result.sort((a, b) => b.mtime - a.mtime);
|
|
74
74
|
return result;
|
|
75
75
|
}
|
|
76
|
+
/** Tally `machineName` → file count across every `.ccsync` in the
|
|
77
|
+
* transport (all projects). Used by `doctor` to catch the
|
|
78
|
+
* duplicate-machineName footgun: `pull` self-filters files whose
|
|
79
|
+
* machineName matches this machine's, so if two machines share a name —
|
|
80
|
+
* e.g. both defaulted to the same hostname — pull silently imports
|
|
81
|
+
* nothing. Malformed files are skipped quietly. */
|
|
82
|
+
export function listTransportMachines(syncDir) {
|
|
83
|
+
const counts = new Map();
|
|
84
|
+
if (!existsSync(syncDir))
|
|
85
|
+
return counts;
|
|
86
|
+
for (const sub of readdirSync(syncDir, { withFileTypes: true })) {
|
|
87
|
+
if (!sub.isDirectory())
|
|
88
|
+
continue;
|
|
89
|
+
const dir = join(syncDir, sub.name);
|
|
90
|
+
for (const entry of readdirSync(dir, { withFileTypes: true })) {
|
|
91
|
+
if (!entry.isFile() || !entry.name.endsWith('.ccsync'))
|
|
92
|
+
continue;
|
|
93
|
+
try {
|
|
94
|
+
const file = parseCcsync(readFileSync(join(dir, entry.name), 'utf-8'));
|
|
95
|
+
counts.set(file.machineName, (counts.get(file.machineName) ?? 0) + 1);
|
|
96
|
+
}
|
|
97
|
+
catch {
|
|
98
|
+
// Shared dir may hold in-progress writes / stale tmp files.
|
|
99
|
+
}
|
|
100
|
+
}
|
|
101
|
+
}
|
|
102
|
+
return counts;
|
|
103
|
+
}
|
|
76
104
|
/** List all project keys present in the transport. Used by the CLI's
|
|
77
105
|
* `pull` (no args) form to fan out across every known project. */
|
|
78
106
|
export function listProjectKeys(syncDir) {
|
package/dist/transport.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"transport.js","sourceRoot":"","sources":["../src/transport.ts"],"names":[],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"transport.js","sourceRoot":"","sources":["../src/transport.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;GAkBG;AAEH,OAAO,EACL,UAAU,EAAE,SAAS,EAAE,WAAW,EAAE,QAAQ,EAAE,aAAa,EAAE,YAAY,EACzE,UAAU,GACX,MAAM,SAAS,CAAC;AACjB,OAAO,EAAE,IAAI,EAAE,MAAM,WAAW,CAAC;AACjC,OAAO,EAAE,gBAAgB,EAAE,MAAM,cAAc,CAAC;AAEhD,OAAO,EAAE,WAAW,EAAE,eAAe,EAAE,MAAM,aAAa,CAAC;AAE3D,MAAM,UAAU,aAAa,CAAC,OAAe,EAAE,UAAkB;IAC/D,OAAO,IAAI,CAAC,OAAO,EAAE,gBAAgB,CAAC,UAAU,CAAC,CAAC,CAAC;AACrD,CAAC;AAED;;;gBAGgB;AAChB,MAAM,UAAU,eAAe,CAAC,OAAe,EAAE,IAAgB;IAC/D,MAAM,GAAG,GAAG,aAAa,CAAC,OAAO,EAAE,IAAI,CAAC,UAAU,CAAC,CAAC;IACpD,IAAI,CAAC,UAAU,CAAC,GAAG,CAAC;QAAE,SAAS,CAAC,GAAG,EAAE,EAAE,SAAS,EAAE,IAAI,EAAE,CAAC,CAAC;IAC1D,MAAM,QAAQ,GAAG,GAAG,IAAI,CAAC,SAAS,IAAI,IAAI,CAAC,WAAW,SAAS,CAAC;IAChE,MAAM,IAAI,GAAG,IAAI,CAAC,GAAG,EAAE,QAAQ,CAAC,CAAC;IACjC,qEAAqE;IACrE,6DAA6D;IAC7D,MAAM,GAAG,GAAG,GAAG,IAAI,MAAM,CAAC;IAC1B,aAAa,CAAC,GAAG,EAAE,eAAe,CAAC,IAAI,CAAC,EAAE,EAAE,IAAI,EAAE,KAAK,EAAE,CAAC,CAAC;IAC3D,UAAU,CAAC,GAAG,EAAE,IAAI,CAAC,CAAC;IACtB,OAAO,IAAI,CAAC;AACd,CAAC;AAQD;;;4CAG4C;AAC5C,MAAM,UAAU,aAAa,CAC3B,OAAe,EACf,UAAkB,EAClB,eAAuB;IAEvB,MAAM,GAAG,GAAG,aAAa,CAAC,OAAO,EAAE,UAAU,CAAC,CAAC;IAC/C,IAAI,CAAC,UAAU,CAAC,GAAG,CAAC;QAAE,OAAO,EAAE,CAAC;IAEhC,MAAM,OAAO,GAAG,WAAW,CAAC,GAAG,EAAE,EAAE,aAAa,EAAE,IAAI,EAAE,CAAC,CAAC;IAC1D,MAAM,MAAM,GAAqB,EAAE,CAAC;IAEpC,KAAK,MAAM,KAAK,IAAI,OAAO,EAAE,CAAC;QAC5B,IAAI,CAAC,KAAK,CAAC,MAAM,EAAE,IAAI,CAAC,KAAK,CAAC,IAAI,CAAC,QAAQ,CAAC,SAAS,CAAC;YAAE,SAAS;QACjE,MAAM,IAAI,GAAG,IAAI,CAAC,GAAG,EAAE,KAAK,CAAC,IAAI,CAAC,CAAC;QACnC,IAAI,IAAgB,CAAC;QACrB,IAAI,CAAC;YACH,IAAI,GAAG,WAAW,CAAC,YAAY,CAAC,IAAI,EAAE,OAAO,CAAC,CAAC,CAAC;QAClD,CAAC;QAAC,MAAM,CAAC;YACP,kEAAkE;YAClE,4DAA4D;YAC5D,kCAAkC;YAClC,SAAS;QACX,CAAC;QACD,IAAI,IAAI,CAAC,WAAW,KAAK,eAAe;YAAE,SAAS;QACnD,MAAM,KAAK,GAAG,QAAQ,CAAC,IAAI,CAAC,CAAC,OAAO,CAAC;QACrC,MAAM,CAAC,IAAI,CAAC,EAAE,IAAI,EAAE,IAAI,EAAE,KAAK,EAAE,CAAC,CAAC;IACrC,CAAC;IAED,MAAM,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,KAAK,GAAG,CAAC,CAAC,KAAK,CAAC,CAAC;IACzC,OAAO,MAAM,CAAC;AAChB,CAAC;AAED;;;;;oDAKoD;AACpD,MAAM,UAAU,qBAAqB,CAAC,OAAe;IACnD,MAAM,MAAM,GAAG,IAAI,GAAG,EAAkB,CAAC;IACzC,IAAI,CAAC,UAAU,CAAC,OAAO,CAAC;QAAE,OAAO,MAAM,CAAC;IAExC,KAAK,MAAM,GAAG,IAAI,WAAW,CAAC,OAAO,EAAE,EAAE,aAAa,EAAE,IAAI,EAAE,CAAC,EAAE,CAAC;QAChE,IAAI,CAAC,GAAG,CAAC,WAAW,EAAE;YAAE,SAAS;QACjC,MAAM,GAAG,GAAG,IAAI,CAAC,OAAO,EAAE,GAAG,CAAC,IAAI,CAAC,CAAC;QACpC,KAAK,MAAM,KAAK,IAAI,WAAW,CAAC,GAAG,EAAE,EAAE,aAAa,EAAE,IAAI,EAAE,CAAC,EAAE,CAAC;YAC9D,IAAI,CAAC,KAAK,CAAC,MAAM,EAAE,IAAI,CAAC,KAAK,CAAC,IAAI,CAAC,QAAQ,CAAC,SAAS,CAAC;gBAAE,SAAS;YACjE,IAAI,CAAC;gBACH,MAAM,IAAI,GAAG,WAAW,CAAC,YAAY,CAAC,IAAI,CAAC,GAAG,EAAE,KAAK,CAAC,IAAI,CAAC,EAAE,OAAO,CAAC,CAAC,CAAC;gBACvE,MAAM,CAAC,GAAG,CAAC,IAAI,CAAC,WAAW,EAAE,CAAC,MAAM,CAAC,GAAG,CAAC,IAAI,CAAC,WAAW,CAAC,IAAI,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC;YACxE,CAAC;YAAC,MAAM,CAAC;gBACP,4DAA4D;YAC9D,CAAC;QACH,CAAC;IACH,CAAC;IACD,OAAO,MAAM,CAAC;AAChB,CAAC;AAED;mEACmE;AACnE,MAAM,UAAU,eAAe,CAAC,OAAe;IAC7C,IAAI,CAAC,UAAU,CAAC,OAAO,CAAC;QAAE,OAAO,EAAE,CAAC;IACpC,MAAM,OAAO,GAAG,WAAW,CAAC,OAAO,EAAE,EAAE,aAAa,EAAE,IAAI,EAAE,CAAC,CAAC;IAC9D,OAAO,OAAO;SACX,MAAM,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,WAAW,EAAE,CAAC;SAC9B,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,IAAI,CAAC;QACnB,gEAAgE;QAChE,8DAA8D;QAC9D,iEAAiE;QACjE,gDAAgD;SAC/C,IAAI,EAAE,CAAC;AACZ,CAAC"}
|
package/package.json
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@askalf/claude-sync",
|
|
3
|
-
"version": "0.0
|
|
4
|
-
"description": "
|
|
3
|
+
"version": "0.1.0",
|
|
4
|
+
"description": "own your sessions — move Claude Code sessions across machines. Part of Own Your Stack.",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"bin": {
|
|
7
7
|
"claude-sync": "./dist/cli.js"
|
|
@@ -21,7 +21,7 @@
|
|
|
21
21
|
],
|
|
22
22
|
"scripts": {
|
|
23
23
|
"build": "tsc",
|
|
24
|
-
"test": "node --test test/project.test.mjs test/format.test.mjs test/session.test.mjs test/transport.test.mjs test/cli.test.mjs test/version.test.mjs",
|
|
24
|
+
"test": "node --test test/project.test.mjs test/format.test.mjs test/session.test.mjs test/transport.test.mjs test/cli.test.mjs test/watch.test.mjs test/version.test.mjs",
|
|
25
25
|
"typecheck": "tsc --noEmit",
|
|
26
26
|
"audit": "npm audit --production --audit-level=high",
|
|
27
27
|
"prepublishOnly": "npm run build",
|