@jive-sh/skill-sync 0.2.0-latest-linux-arm64 → 0.2.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 +51 -0
- package/bin/skill-sync +568 -0
- package/bin/skill-sync-daemon +568 -0
- package/dist/daemons/skill-sync-daemon.js +269 -0
- package/dist/daemons/skill-sync-daemon.js.map +1 -0
- package/dist/entrypoints/skill-sync.js +160 -0
- package/dist/entrypoints/skill-sync.js.map +1 -0
- package/dist/index.js +10 -0
- package/dist/index.js.map +1 -0
- package/dist/internal/config.js +150 -0
- package/dist/internal/config.js.map +1 -0
- package/dist/internal/folders.js +53 -0
- package/dist/internal/folders.js.map +1 -0
- package/dist/internal/notify.js +50 -0
- package/dist/internal/notify.js.map +1 -0
- package/dist/internal/path.js +36 -0
- package/dist/internal/path.js.map +1 -0
- package/dist/internal/reconcile.js +124 -0
- package/dist/internal/reconcile.js.map +1 -0
- package/dist/internal/sync.js +241 -0
- package/dist/internal/sync.js.map +1 -0
- package/dist/internal/wire.js +13 -0
- package/dist/internal/wire.js.map +1 -0
- package/install.js +568 -0
- package/package.json +39 -11
- package/src/daemons/skill-sync-daemon.ts +267 -0
- package/src/entrypoints/skill-sync.ts +161 -0
- package/src/index.ts +15 -0
- package/src/internal/config.ts +191 -0
- package/src/internal/folders.ts +58 -0
- package/src/internal/notify.ts +53 -0
- package/src/internal/path.ts +32 -0
- package/src/internal/reconcile.ts +165 -0
- package/src/internal/sync.ts +304 -0
- package/src/internal/wire.ts +149 -0
- package/multi-call-binary +0 -4
|
@@ -0,0 +1,149 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* The shapes the daemon and the service exchange.
|
|
3
|
+
*
|
|
4
|
+
* Declared in the library and imported by the service so there is one definition rather than two that
|
|
5
|
+
* drift. The service depends on the library; nothing goes the other way.
|
|
6
|
+
*/
|
|
7
|
+
|
|
8
|
+
export interface RemoteFile {
|
|
9
|
+
readonly path: string;
|
|
10
|
+
/** Null when the file is deleted; the row stays as a tombstone. */
|
|
11
|
+
readonly hash: string | null;
|
|
12
|
+
readonly deleted: boolean;
|
|
13
|
+
readonly updatedAt: number;
|
|
14
|
+
readonly updatedBy: string;
|
|
15
|
+
}
|
|
16
|
+
|
|
17
|
+
export interface ListFilesResponse {
|
|
18
|
+
/** Highest sequence number in this page; the caller sends it back as `since`. */
|
|
19
|
+
readonly cursor: number;
|
|
20
|
+
readonly files: ReadonlyArray<RemoteFile>;
|
|
21
|
+
}
|
|
22
|
+
|
|
23
|
+
export interface PutFileRequest {
|
|
24
|
+
readonly path: string;
|
|
25
|
+
/** What the client believes the server holds. The write is refused if that is no longer true. */
|
|
26
|
+
readonly baseHash: string | null;
|
|
27
|
+
/** Null to delete. */
|
|
28
|
+
readonly hash: string | null;
|
|
29
|
+
/** Base64, absent for a delete. */
|
|
30
|
+
readonly content: string | null;
|
|
31
|
+
readonly machine: string;
|
|
32
|
+
}
|
|
33
|
+
|
|
34
|
+
/**
|
|
35
|
+
* Where a folder's sync stands, as the dashboard shows it.
|
|
36
|
+
*
|
|
37
|
+
* `reconciling` means Claude is merging two versions of a file on that machine; `attention` means a cycle
|
|
38
|
+
* failed or a conflict could not be merged, and `detail` says which.
|
|
39
|
+
*/
|
|
40
|
+
export type FolderState = "idle" | "reconciling" | "attention";
|
|
41
|
+
|
|
42
|
+
/**
|
|
43
|
+
* A skill is a top-level entry of a skills folder — usually a directory like `jive/` holding `SKILL.md`
|
|
44
|
+
* and its files — and it is the unit of opting in: all of its files sync, or none do, so a skill never
|
|
45
|
+
* arrives half-present on another machine.
|
|
46
|
+
*/
|
|
47
|
+
export const skillOf = (path: string): string => path.split("/")[0]!;
|
|
48
|
+
|
|
49
|
+
/** One skill as a folder holds it. */
|
|
50
|
+
export interface LocalSkill {
|
|
51
|
+
readonly name: string;
|
|
52
|
+
readonly files: ReadonlyArray<string>;
|
|
53
|
+
/** True when this folder has synced it before, which makes it synced by default rather than local. */
|
|
54
|
+
readonly tracked: boolean;
|
|
55
|
+
}
|
|
56
|
+
|
|
57
|
+
/**
|
|
58
|
+
* `POST /folders`: every folder this machine found, with the skills in each. Answered with the folders
|
|
59
|
+
* to sync and, for each, the skills that sync there. A skill left out stays local to its folder.
|
|
60
|
+
*/
|
|
61
|
+
export interface FoldersRequest {
|
|
62
|
+
readonly folders: ReadonlyArray<{ readonly path: string; readonly skills: ReadonlyArray<LocalSkill> }>;
|
|
63
|
+
}
|
|
64
|
+
export interface FolderPrefs {
|
|
65
|
+
readonly path: string;
|
|
66
|
+
readonly skills: ReadonlyArray<string>;
|
|
67
|
+
}
|
|
68
|
+
export interface FoldersResponse {
|
|
69
|
+
readonly folders: ReadonlyArray<FolderPrefs>;
|
|
70
|
+
}
|
|
71
|
+
|
|
72
|
+
/** `POST /reconciliations`: one merge Claude did, or failed to do, for the audit log. */
|
|
73
|
+
export interface ReconciliationRequest {
|
|
74
|
+
readonly folder: string;
|
|
75
|
+
readonly path: string;
|
|
76
|
+
readonly outcome: "merged" | "failed";
|
|
77
|
+
/** What differed between the two versions, in a sentence or two. */
|
|
78
|
+
readonly conflict: string;
|
|
79
|
+
/** What the merge kept, dropped or reworded — or why it failed. */
|
|
80
|
+
readonly resolution: string;
|
|
81
|
+
}
|
|
82
|
+
|
|
83
|
+
/** Daemon → hub, over the daemon's WebSocket. */
|
|
84
|
+
export type DaemonMessage = {
|
|
85
|
+
readonly type: "status";
|
|
86
|
+
readonly folder: string;
|
|
87
|
+
readonly state: FolderState;
|
|
88
|
+
readonly detail?: string;
|
|
89
|
+
/** A one-line summary of what the last cycle changed, when it changed anything. */
|
|
90
|
+
readonly activity?: string;
|
|
91
|
+
};
|
|
92
|
+
|
|
93
|
+
/** Hub → daemon. `prefs` replaces what syncs; `changed` means another write landed on the server. */
|
|
94
|
+
export type HubToDaemon =
|
|
95
|
+
| { readonly type: "prefs"; readonly folders: ReadonlyArray<FolderPrefs> }
|
|
96
|
+
| { readonly type: "changed" };
|
|
97
|
+
|
|
98
|
+
export interface SkillView {
|
|
99
|
+
readonly name: string;
|
|
100
|
+
/** Checked on the dashboard: this folder sends and receives the skill. */
|
|
101
|
+
readonly synced: boolean;
|
|
102
|
+
/** The folder has a copy on disk. */
|
|
103
|
+
readonly local: boolean;
|
|
104
|
+
readonly files: ReadonlyArray<string>;
|
|
105
|
+
}
|
|
106
|
+
|
|
107
|
+
export interface FolderView {
|
|
108
|
+
readonly path: string;
|
|
109
|
+
readonly enabled: boolean;
|
|
110
|
+
/** False once the machine stops finding the folder; the row stays so its preference is remembered. */
|
|
111
|
+
readonly present: boolean;
|
|
112
|
+
readonly state: FolderState;
|
|
113
|
+
readonly detail: string | null;
|
|
114
|
+
readonly lastActivityAt: number | null;
|
|
115
|
+
readonly lastActivity: string | null;
|
|
116
|
+
readonly skills: ReadonlyArray<SkillView>;
|
|
117
|
+
}
|
|
118
|
+
|
|
119
|
+
export interface MachineView {
|
|
120
|
+
readonly machine: string;
|
|
121
|
+
/** True while this machine's daemon holds a connection to the hub. */
|
|
122
|
+
readonly online: boolean;
|
|
123
|
+
readonly lastSeen: number | null;
|
|
124
|
+
readonly folders: ReadonlyArray<FolderView>;
|
|
125
|
+
}
|
|
126
|
+
|
|
127
|
+
/** A skill as the server holds it: the synced version every opted-in folder converges on. */
|
|
128
|
+
export interface SyncedSkill {
|
|
129
|
+
readonly name: string;
|
|
130
|
+
readonly files: ReadonlyArray<{ readonly path: string; readonly updatedBy: string; readonly updatedAt: number }>;
|
|
131
|
+
}
|
|
132
|
+
|
|
133
|
+
export interface ReconciliationView extends ReconciliationRequest {
|
|
134
|
+
readonly at: number;
|
|
135
|
+
readonly machine: string;
|
|
136
|
+
}
|
|
137
|
+
|
|
138
|
+
/** Hub → dashboard: the whole picture, resent on every change. It is small, and a diff protocol is not. */
|
|
139
|
+
export interface Snapshot {
|
|
140
|
+
readonly type: "snapshot";
|
|
141
|
+
readonly skills: ReadonlyArray<SyncedSkill>;
|
|
142
|
+
readonly reconciliations: ReadonlyArray<ReconciliationView>;
|
|
143
|
+
readonly machines: ReadonlyArray<MachineView>;
|
|
144
|
+
}
|
|
145
|
+
|
|
146
|
+
/** Dashboard → hub. */
|
|
147
|
+
export type DashboardMessage =
|
|
148
|
+
| { readonly type: "setFolder"; readonly machine: string; readonly path: string; readonly enabled: boolean }
|
|
149
|
+
| { readonly type: "setSkill"; readonly machine: string; readonly folder: string; readonly skill: string; readonly synced: boolean };
|
package/multi-call-binary
DELETED