@claudeskill/cli 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.
Files changed (65) hide show
  1. package/dist/api.d.ts +148 -0
  2. package/dist/api.d.ts.map +1 -0
  3. package/dist/api.js +218 -0
  4. package/dist/api.js.map +1 -0
  5. package/dist/commands/checkout.d.ts +8 -0
  6. package/dist/commands/checkout.d.ts.map +1 -0
  7. package/dist/commands/checkout.js +134 -0
  8. package/dist/commands/checkout.js.map +1 -0
  9. package/dist/commands/diff.d.ts +8 -0
  10. package/dist/commands/diff.d.ts.map +1 -0
  11. package/dist/commands/diff.js +156 -0
  12. package/dist/commands/diff.js.map +1 -0
  13. package/dist/commands/list.d.ts +14 -0
  14. package/dist/commands/list.d.ts.map +1 -0
  15. package/dist/commands/list.js +251 -0
  16. package/dist/commands/list.js.map +1 -0
  17. package/dist/commands/log.d.ts +8 -0
  18. package/dist/commands/log.d.ts.map +1 -0
  19. package/dist/commands/log.js +74 -0
  20. package/dist/commands/log.js.map +1 -0
  21. package/dist/commands/login.d.ts +8 -0
  22. package/dist/commands/login.d.ts.map +1 -0
  23. package/dist/commands/login.js +201 -0
  24. package/dist/commands/login.js.map +1 -0
  25. package/dist/commands/logout.d.ts +8 -0
  26. package/dist/commands/logout.d.ts.map +1 -0
  27. package/dist/commands/logout.js +33 -0
  28. package/dist/commands/logout.js.map +1 -0
  29. package/dist/commands/pull.d.ts +11 -0
  30. package/dist/commands/pull.d.ts.map +1 -0
  31. package/dist/commands/pull.js +123 -0
  32. package/dist/commands/pull.js.map +1 -0
  33. package/dist/commands/push.d.ts +12 -0
  34. package/dist/commands/push.d.ts.map +1 -0
  35. package/dist/commands/push.js +128 -0
  36. package/dist/commands/push.js.map +1 -0
  37. package/dist/commands/status.d.ts +8 -0
  38. package/dist/commands/status.d.ts.map +1 -0
  39. package/dist/commands/status.js +104 -0
  40. package/dist/commands/status.js.map +1 -0
  41. package/dist/config.d.ts +25 -0
  42. package/dist/config.d.ts.map +1 -0
  43. package/dist/config.js +54 -0
  44. package/dist/config.js.map +1 -0
  45. package/dist/credentials.d.ts +24 -0
  46. package/dist/credentials.d.ts.map +1 -0
  47. package/dist/credentials.js +54 -0
  48. package/dist/credentials.js.map +1 -0
  49. package/dist/index.d.ts +8 -0
  50. package/dist/index.d.ts.map +1 -0
  51. package/dist/index.js +166 -0
  52. package/dist/index.js.map +1 -0
  53. package/dist/menu.d.ts +8 -0
  54. package/dist/menu.d.ts.map +1 -0
  55. package/dist/menu.js +130 -0
  56. package/dist/menu.js.map +1 -0
  57. package/dist/onboarding.d.ts +8 -0
  58. package/dist/onboarding.d.ts.map +1 -0
  59. package/dist/onboarding.js +252 -0
  60. package/dist/onboarding.js.map +1 -0
  61. package/dist/sync.d.ts +83 -0
  62. package/dist/sync.d.ts.map +1 -0
  63. package/dist/sync.js +294 -0
  64. package/dist/sync.js.map +1 -0
  65. package/package.json +47 -0
@@ -0,0 +1,201 @@
1
+ /**
2
+ * Login command - authenticate with server
3
+ */
4
+ import * as p from "@clack/prompts";
5
+ import { generateSalt, generateMasterKey, generateRecoveryKey, deriveKeyFromPassphrase, encryptMasterKey, formatRecoveryKey, toBase64, } from "@claudeskill/core";
6
+ import { loadConfig } from "../config.js";
7
+ import { saveCredentials, loadCredentials } from "../credentials.js";
8
+ import * as api from "../api.js";
9
+ /**
10
+ * Run the login command
11
+ */
12
+ export const runLogin = async () => {
13
+ const config = await loadConfig();
14
+ if (!config) {
15
+ p.log.error("Not configured. Run 'claude-skill-sync' first to set up.");
16
+ return;
17
+ }
18
+ if (config.mode === "local") {
19
+ p.log.error("Cannot login in local-only mode.");
20
+ return;
21
+ }
22
+ p.intro("Login to Claude Skill Sync");
23
+ // Check server health
24
+ const healthResult = await api.checkHealth();
25
+ if (!healthResult.ok) {
26
+ p.log.error(`Cannot connect to server: ${healthResult.error}`);
27
+ return;
28
+ }
29
+ // Get email
30
+ const email = await p.text({
31
+ message: "Email:",
32
+ placeholder: config.email ?? "you@example.com",
33
+ initialValue: config.email ?? undefined,
34
+ validate: (value) => {
35
+ if (!value)
36
+ return "Email is required";
37
+ if (!value.includes("@"))
38
+ return "Invalid email";
39
+ },
40
+ });
41
+ if (p.isCancel(email)) {
42
+ p.cancel("Login cancelled.");
43
+ return;
44
+ }
45
+ // Request OTP
46
+ const spinner = p.spinner();
47
+ spinner.start("Sending verification code...");
48
+ const otpResult = await api.requestOtp(email);
49
+ if (!otpResult.ok) {
50
+ spinner.stop("Failed to send code");
51
+ p.log.error(otpResult.error);
52
+ return;
53
+ }
54
+ spinner.stop("Verification code sent!");
55
+ // Get OTP code
56
+ const code = await p.text({
57
+ message: "Enter the 6-digit code from your email:",
58
+ validate: (value) => {
59
+ if (!value)
60
+ return "Code is required";
61
+ if (!/^\d{6}$/.test(value))
62
+ return "Code must be 6 digits";
63
+ },
64
+ });
65
+ if (p.isCancel(code)) {
66
+ p.cancel("Login cancelled.");
67
+ return;
68
+ }
69
+ // Verify OTP
70
+ spinner.start("Verifying...");
71
+ const verifyResult = await api.verifyOtp(email, code);
72
+ if (!verifyResult.ok) {
73
+ spinner.stop("Verification failed");
74
+ p.log.error(verifyResult.error);
75
+ return;
76
+ }
77
+ spinner.stop("Verified!");
78
+ const { accessToken, refreshToken, user } = verifyResult.data;
79
+ // Check if this is a new user or existing
80
+ if (user.isNewUser) {
81
+ // New user - need to set up encryption
82
+ p.log.info("Setting up encryption for your account...");
83
+ const passphrase = await p.password({
84
+ message: "Create a vault passphrase:",
85
+ mask: "*",
86
+ validate: (value) => {
87
+ if (!value)
88
+ return "Passphrase is required";
89
+ if (value.length < 8)
90
+ return "Passphrase must be at least 8 characters";
91
+ },
92
+ });
93
+ if (p.isCancel(passphrase)) {
94
+ p.cancel("Login cancelled.");
95
+ return;
96
+ }
97
+ const confirmPassphrase = await p.password({
98
+ message: "Confirm passphrase:",
99
+ mask: "*",
100
+ validate: (value) => {
101
+ if (value !== passphrase)
102
+ return "Passphrases do not match";
103
+ },
104
+ });
105
+ if (p.isCancel(confirmPassphrase)) {
106
+ p.cancel("Login cancelled.");
107
+ return;
108
+ }
109
+ // Generate keys
110
+ spinner.start("Generating encryption keys...");
111
+ const salt = generateSalt();
112
+ const masterKey = generateMasterKey();
113
+ const recoveryKey = generateRecoveryKey();
114
+ const derivedKey = deriveKeyFromPassphrase(passphrase, salt);
115
+ const encryptedMaster = encryptMasterKey(masterKey, derivedKey.key);
116
+ // Combine IV + tag + ciphertext for storage
117
+ const encryptedMasterKeyFull = new Uint8Array(encryptedMaster.iv.length +
118
+ encryptedMaster.tag.length +
119
+ encryptedMaster.encrypted.length);
120
+ encryptedMasterKeyFull.set(encryptedMaster.iv, 0);
121
+ encryptedMasterKeyFull.set(encryptedMaster.tag, encryptedMaster.iv.length);
122
+ encryptedMasterKeyFull.set(encryptedMaster.encrypted, encryptedMaster.iv.length + encryptedMaster.tag.length);
123
+ // Save credentials first so API calls work
124
+ await saveCredentials({
125
+ accessToken,
126
+ refreshToken,
127
+ encryptedMasterKey: toBase64(encryptedMasterKeyFull),
128
+ salt: toBase64(salt),
129
+ });
130
+ // Upload salt to server
131
+ const saltResult = await api.setSalt(toBase64(salt));
132
+ if (!saltResult.ok) {
133
+ spinner.stop("Failed to save encryption settings");
134
+ p.log.error(saltResult.error);
135
+ return;
136
+ }
137
+ // Upload encrypted master key to server (for web dashboard decryption)
138
+ const masterKeyResult = await api.setMasterKey(toBase64(encryptedMasterKeyFull));
139
+ if (!masterKeyResult.ok) {
140
+ // Non-fatal - dashboard decryption won't work but CLI will
141
+ p.log.warn("Could not sync master key for web dashboard");
142
+ }
143
+ spinner.stop("Encryption configured!");
144
+ // Show recovery key
145
+ const formattedRecoveryKey = formatRecoveryKey(recoveryKey);
146
+ p.note(`
147
+ ${formattedRecoveryKey}
148
+
149
+ This is the ONLY way to recover your skills if you
150
+ forget your passphrase. Store it somewhere safe.
151
+ `.trim(), "SAVE YOUR RECOVERY KEY");
152
+ const saved = await p.confirm({
153
+ message: "I have saved my recovery key",
154
+ });
155
+ if (p.isCancel(saved) || !saved) {
156
+ p.note(formattedRecoveryKey, "RECOVERY KEY (showing again)");
157
+ await p.confirm({ message: "I have saved my recovery key" });
158
+ }
159
+ }
160
+ else {
161
+ // Existing user - need to get salt and decrypt master key
162
+ p.log.info("Welcome back! Enter your passphrase to unlock.");
163
+ // Get salt from server
164
+ const saltResult = await api.getSalt();
165
+ if (!saltResult.ok) {
166
+ p.log.error(`Failed to get encryption settings: ${saltResult.error}`);
167
+ return;
168
+ }
169
+ const passphrase = await p.password({
170
+ message: "Vault passphrase:",
171
+ mask: "*",
172
+ });
173
+ if (p.isCancel(passphrase)) {
174
+ p.cancel("Login cancelled.");
175
+ return;
176
+ }
177
+ // For existing users, we need to verify the passphrase
178
+ // by trying to decrypt something or asking them to re-enter
179
+ // For now, just save the credentials
180
+ const existingCreds = await loadCredentials();
181
+ // Try to get master key from server, fall back to local
182
+ let encryptedMasterKey = existingCreds?.encryptedMasterKey ?? "";
183
+ const masterKeyResult = await api.getMasterKey();
184
+ if (masterKeyResult.ok && masterKeyResult.data.encryptedMasterKey) {
185
+ encryptedMasterKey = masterKeyResult.data.encryptedMasterKey;
186
+ }
187
+ else if (existingCreds?.encryptedMasterKey) {
188
+ // Sync local master key to server for web dashboard
189
+ await api.setMasterKey(existingCreds.encryptedMasterKey);
190
+ }
191
+ await saveCredentials({
192
+ accessToken,
193
+ refreshToken,
194
+ encryptedMasterKey,
195
+ salt: saltResult.data.salt,
196
+ });
197
+ }
198
+ p.log.success("Logged in successfully!");
199
+ p.outro(`Logged in as ${email}`);
200
+ };
201
+ //# sourceMappingURL=login.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"login.js","sourceRoot":"","sources":["../../src/commands/login.ts"],"names":[],"mappings":"AAAA;;GAEG;AAEH,OAAO,KAAK,CAAC,MAAM,gBAAgB,CAAC;AACpC,OAAO,EACL,YAAY,EACZ,iBAAiB,EACjB,mBAAmB,EACnB,uBAAuB,EACvB,gBAAgB,EAChB,iBAAiB,EACjB,QAAQ,GACT,MAAM,mBAAmB,CAAC;AAC3B,OAAO,EAAE,UAAU,EAAE,MAAM,cAAc,CAAC;AAC1C,OAAO,EAAE,eAAe,EAAE,eAAe,EAAE,MAAM,mBAAmB,CAAC;AACrE,OAAO,KAAK,GAAG,MAAM,WAAW,CAAC;AAEjC;;GAEG;AACH,MAAM,CAAC,MAAM,QAAQ,GAAG,KAAK,IAAI,EAAE;IACjC,MAAM,MAAM,GAAG,MAAM,UAAU,EAAE,CAAC;IAElC,IAAI,CAAC,MAAM,EAAE,CAAC;QACZ,CAAC,CAAC,GAAG,CAAC,KAAK,CAAC,0DAA0D,CAAC,CAAC;QACxE,OAAO;IACT,CAAC;IAED,IAAI,MAAM,CAAC,IAAI,KAAK,OAAO,EAAE,CAAC;QAC5B,CAAC,CAAC,GAAG,CAAC,KAAK,CAAC,kCAAkC,CAAC,CAAC;QAChD,OAAO;IACT,CAAC;IAED,CAAC,CAAC,KAAK,CAAC,4BAA4B,CAAC,CAAC;IAEtC,sBAAsB;IACtB,MAAM,YAAY,GAAG,MAAM,GAAG,CAAC,WAAW,EAAE,CAAC;IAC7C,IAAI,CAAC,YAAY,CAAC,EAAE,EAAE,CAAC;QACrB,CAAC,CAAC,GAAG,CAAC,KAAK,CAAC,6BAA6B,YAAY,CAAC,KAAK,EAAE,CAAC,CAAC;QAC/D,OAAO;IACT,CAAC;IAED,YAAY;IACZ,MAAM,KAAK,GAAG,MAAM,CAAC,CAAC,IAAI,CAAC;QACzB,OAAO,EAAE,QAAQ;QACjB,WAAW,EAAE,MAAM,CAAC,KAAK,IAAI,iBAAiB;QAC9C,YAAY,EAAE,MAAM,CAAC,KAAK,IAAI,SAAS;QACvC,QAAQ,EAAE,CAAC,KAAK,EAAE,EAAE;YAClB,IAAI,CAAC,KAAK;gBAAE,OAAO,mBAAmB,CAAC;YACvC,IAAI,CAAC,KAAK,CAAC,QAAQ,CAAC,GAAG,CAAC;gBAAE,OAAO,eAAe,CAAC;QACnD,CAAC;KACF,CAAC,CAAC;IAEH,IAAI,CAAC,CAAC,QAAQ,CAAC,KAAK,CAAC,EAAE,CAAC;QACtB,CAAC,CAAC,MAAM,CAAC,kBAAkB,CAAC,CAAC;QAC7B,OAAO;IACT,CAAC;IAED,cAAc;IACd,MAAM,OAAO,GAAG,CAAC,CAAC,OAAO,EAAE,CAAC;IAC5B,OAAO,CAAC,KAAK,CAAC,8BAA8B,CAAC,CAAC;IAE9C,MAAM,SAAS,GAAG,MAAM,GAAG,CAAC,UAAU,CAAC,KAAK,CAAC,CAAC;IAC9C,IAAI,CAAC,SAAS,CAAC,EAAE,EAAE,CAAC;QAClB,OAAO,CAAC,IAAI,CAAC,qBAAqB,CAAC,CAAC;QACpC,CAAC,CAAC,GAAG,CAAC,KAAK,CAAC,SAAS,CAAC,KAAK,CAAC,CAAC;QAC7B,OAAO;IACT,CAAC;IAED,OAAO,CAAC,IAAI,CAAC,yBAAyB,CAAC,CAAC;IAExC,eAAe;IACf,MAAM,IAAI,GAAG,MAAM,CAAC,CAAC,IAAI,CAAC;QACxB,OAAO,EAAE,yCAAyC;QAClD,QAAQ,EAAE,CAAC,KAAK,EAAE,EAAE;YAClB,IAAI,CAAC,KAAK;gBAAE,OAAO,kBAAkB,CAAC;YACtC,IAAI,CAAC,SAAS,CAAC,IAAI,CAAC,KAAK,CAAC;gBAAE,OAAO,uBAAuB,CAAC;QAC7D,CAAC;KACF,CAAC,CAAC;IAEH,IAAI,CAAC,CAAC,QAAQ,CAAC,IAAI,CAAC,EAAE,CAAC;QACrB,CAAC,CAAC,MAAM,CAAC,kBAAkB,CAAC,CAAC;QAC7B,OAAO;IACT,CAAC;IAED,aAAa;IACb,OAAO,CAAC,KAAK,CAAC,cAAc,CAAC,CAAC;IAE9B,MAAM,YAAY,GAAG,MAAM,GAAG,CAAC,SAAS,CAAC,KAAK,EAAE,IAAI,CAAC,CAAC;IACtD,IAAI,CAAC,YAAY,CAAC,EAAE,EAAE,CAAC;QACrB,OAAO,CAAC,IAAI,CAAC,qBAAqB,CAAC,CAAC;QACpC,CAAC,CAAC,GAAG,CAAC,KAAK,CAAC,YAAY,CAAC,KAAK,CAAC,CAAC;QAChC,OAAO;IACT,CAAC;IAED,OAAO,CAAC,IAAI,CAAC,WAAW,CAAC,CAAC;IAE1B,MAAM,EAAE,WAAW,EAAE,YAAY,EAAE,IAAI,EAAE,GAAG,YAAY,CAAC,IAAI,CAAC;IAE9D,0CAA0C;IAC1C,IAAI,IAAI,CAAC,SAAS,EAAE,CAAC;QACnB,uCAAuC;QACvC,CAAC,CAAC,GAAG,CAAC,IAAI,CAAC,2CAA2C,CAAC,CAAC;QAExD,MAAM,UAAU,GAAG,MAAM,CAAC,CAAC,QAAQ,CAAC;YAClC,OAAO,EAAE,4BAA4B;YACrC,IAAI,EAAE,GAAG;YACT,QAAQ,EAAE,CAAC,KAAK,EAAE,EAAE;gBAClB,IAAI,CAAC,KAAK;oBAAE,OAAO,wBAAwB,CAAC;gBAC5C,IAAI,KAAK,CAAC,MAAM,GAAG,CAAC;oBAAE,OAAO,0CAA0C,CAAC;YAC1E,CAAC;SACF,CAAC,CAAC;QAEH,IAAI,CAAC,CAAC,QAAQ,CAAC,UAAU,CAAC,EAAE,CAAC;YAC3B,CAAC,CAAC,MAAM,CAAC,kBAAkB,CAAC,CAAC;YAC7B,OAAO;QACT,CAAC;QAED,MAAM,iBAAiB,GAAG,MAAM,CAAC,CAAC,QAAQ,CAAC;YACzC,OAAO,EAAE,qBAAqB;YAC9B,IAAI,EAAE,GAAG;YACT,QAAQ,EAAE,CAAC,KAAK,EAAE,EAAE;gBAClB,IAAI,KAAK,KAAK,UAAU;oBAAE,OAAO,0BAA0B,CAAC;YAC9D,CAAC;SACF,CAAC,CAAC;QAEH,IAAI,CAAC,CAAC,QAAQ,CAAC,iBAAiB,CAAC,EAAE,CAAC;YAClC,CAAC,CAAC,MAAM,CAAC,kBAAkB,CAAC,CAAC;YAC7B,OAAO;QACT,CAAC;QAED,gBAAgB;QAChB,OAAO,CAAC,KAAK,CAAC,+BAA+B,CAAC,CAAC;QAE/C,MAAM,IAAI,GAAG,YAAY,EAAE,CAAC;QAC5B,MAAM,SAAS,GAAG,iBAAiB,EAAE,CAAC;QACtC,MAAM,WAAW,GAAG,mBAAmB,EAAE,CAAC;QAC1C,MAAM,UAAU,GAAG,uBAAuB,CAAC,UAAU,EAAE,IAAI,CAAC,CAAC;QAC7D,MAAM,eAAe,GAAG,gBAAgB,CAAC,SAAS,EAAE,UAAU,CAAC,GAAG,CAAC,CAAC;QAEpE,4CAA4C;QAC5C,MAAM,sBAAsB,GAAG,IAAI,UAAU,CAC3C,eAAe,CAAC,EAAE,CAAC,MAAM;YACvB,eAAe,CAAC,GAAG,CAAC,MAAM;YAC1B,eAAe,CAAC,SAAS,CAAC,MAAM,CACnC,CAAC;QACF,sBAAsB,CAAC,GAAG,CAAC,eAAe,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC;QAClD,sBAAsB,CAAC,GAAG,CAAC,eAAe,CAAC,GAAG,EAAE,eAAe,CAAC,EAAE,CAAC,MAAM,CAAC,CAAC;QAC3E,sBAAsB,CAAC,GAAG,CACxB,eAAe,CAAC,SAAS,EACzB,eAAe,CAAC,EAAE,CAAC,MAAM,GAAG,eAAe,CAAC,GAAG,CAAC,MAAM,CACvD,CAAC;QAEF,2CAA2C;QAC3C,MAAM,eAAe,CAAC;YACpB,WAAW;YACX,YAAY;YACZ,kBAAkB,EAAE,QAAQ,CAAC,sBAAsB,CAAC;YACpD,IAAI,EAAE,QAAQ,CAAC,IAAI,CAAC;SACrB,CAAC,CAAC;QAEH,wBAAwB;QACxB,MAAM,UAAU,GAAG,MAAM,GAAG,CAAC,OAAO,CAAC,QAAQ,CAAC,IAAI,CAAC,CAAC,CAAC;QACrD,IAAI,CAAC,UAAU,CAAC,EAAE,EAAE,CAAC;YACnB,OAAO,CAAC,IAAI,CAAC,oCAAoC,CAAC,CAAC;YACnD,CAAC,CAAC,GAAG,CAAC,KAAK,CAAC,UAAU,CAAC,KAAK,CAAC,CAAC;YAC9B,OAAO;QACT,CAAC;QAED,uEAAuE;QACvE,MAAM,eAAe,GAAG,MAAM,GAAG,CAAC,YAAY,CAAC,QAAQ,CAAC,sBAAsB,CAAC,CAAC,CAAC;QACjF,IAAI,CAAC,eAAe,CAAC,EAAE,EAAE,CAAC;YACxB,2DAA2D;YAC3D,CAAC,CAAC,GAAG,CAAC,IAAI,CAAC,6CAA6C,CAAC,CAAC;QAC5D,CAAC;QAED,OAAO,CAAC,IAAI,CAAC,wBAAwB,CAAC,CAAC;QAEvC,oBAAoB;QACpB,MAAM,oBAAoB,GAAG,iBAAiB,CAAC,WAAW,CAAC,CAAC;QAE5D,CAAC,CAAC,IAAI,CACJ;IACF,oBAAoB;;;;OAIjB,CAAC,IAAI,EAAE,EACR,wBAAwB,CACzB,CAAC;QAEF,MAAM,KAAK,GAAG,MAAM,CAAC,CAAC,OAAO,CAAC;YAC5B,OAAO,EAAE,8BAA8B;SACxC,CAAC,CAAC;QAEH,IAAI,CAAC,CAAC,QAAQ,CAAC,KAAK,CAAC,IAAI,CAAC,KAAK,EAAE,CAAC;YAChC,CAAC,CAAC,IAAI,CAAC,oBAAoB,EAAE,8BAA8B,CAAC,CAAC;YAC7D,MAAM,CAAC,CAAC,OAAO,CAAC,EAAE,OAAO,EAAE,8BAA8B,EAAE,CAAC,CAAC;QAC/D,CAAC;IACH,CAAC;SAAM,CAAC;QACN,0DAA0D;QAC1D,CAAC,CAAC,GAAG,CAAC,IAAI,CAAC,gDAAgD,CAAC,CAAC;QAE7D,uBAAuB;QACvB,MAAM,UAAU,GAAG,MAAM,GAAG,CAAC,OAAO,EAAE,CAAC;QACvC,IAAI,CAAC,UAAU,CAAC,EAAE,EAAE,CAAC;YACnB,CAAC,CAAC,GAAG,CAAC,KAAK,CAAC,sCAAsC,UAAU,CAAC,KAAK,EAAE,CAAC,CAAC;YACtE,OAAO;QACT,CAAC;QAED,MAAM,UAAU,GAAG,MAAM,CAAC,CAAC,QAAQ,CAAC;YAClC,OAAO,EAAE,mBAAmB;YAC5B,IAAI,EAAE,GAAG;SACV,CAAC,CAAC;QAEH,IAAI,CAAC,CAAC,QAAQ,CAAC,UAAU,CAAC,EAAE,CAAC;YAC3B,CAAC,CAAC,MAAM,CAAC,kBAAkB,CAAC,CAAC;YAC7B,OAAO;QACT,CAAC;QAED,uDAAuD;QACvD,4DAA4D;QAC5D,qCAAqC;QACrC,MAAM,aAAa,GAAG,MAAM,eAAe,EAAE,CAAC;QAE9C,wDAAwD;QACxD,IAAI,kBAAkB,GAAG,aAAa,EAAE,kBAAkB,IAAI,EAAE,CAAC;QACjE,MAAM,eAAe,GAAG,MAAM,GAAG,CAAC,YAAY,EAAE,CAAC;QACjD,IAAI,eAAe,CAAC,EAAE,IAAI,eAAe,CAAC,IAAI,CAAC,kBAAkB,EAAE,CAAC;YAClE,kBAAkB,GAAG,eAAe,CAAC,IAAI,CAAC,kBAAkB,CAAC;QAC/D,CAAC;aAAM,IAAI,aAAa,EAAE,kBAAkB,EAAE,CAAC;YAC7C,oDAAoD;YACpD,MAAM,GAAG,CAAC,YAAY,CAAC,aAAa,CAAC,kBAAkB,CAAC,CAAC;QAC3D,CAAC;QAED,MAAM,eAAe,CAAC;YACpB,WAAW;YACX,YAAY;YACZ,kBAAkB;YAClB,IAAI,EAAE,UAAU,CAAC,IAAI,CAAC,IAAI;SAC3B,CAAC,CAAC;IACL,CAAC;IAED,CAAC,CAAC,GAAG,CAAC,OAAO,CAAC,yBAAyB,CAAC,CAAC;IACzC,CAAC,CAAC,KAAK,CAAC,gBAAgB,KAAK,EAAE,CAAC,CAAC;AACnC,CAAC,CAAC"}
@@ -0,0 +1,8 @@
1
+ /**
2
+ * Logout command - clear local credentials
3
+ */
4
+ /**
5
+ * Run the logout command
6
+ */
7
+ export declare const runLogout: () => Promise<void>;
8
+ //# sourceMappingURL=logout.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"logout.d.ts","sourceRoot":"","sources":["../../src/commands/logout.ts"],"names":[],"mappings":"AAAA;;GAEG;AAMH;;GAEG;AACH,eAAO,MAAM,SAAS,qBA8BrB,CAAC"}
@@ -0,0 +1,33 @@
1
+ /**
2
+ * Logout command - clear local credentials
3
+ */
4
+ import * as p from "@clack/prompts";
5
+ import { deleteCredentials, loadCredentials } from "../credentials.js";
6
+ import * as api from "../api.js";
7
+ /**
8
+ * Run the logout command
9
+ */
10
+ export const runLogout = async () => {
11
+ const credentials = await loadCredentials();
12
+ if (!credentials?.accessToken) {
13
+ p.log.info("Not logged in.");
14
+ return;
15
+ }
16
+ const confirm = await p.confirm({
17
+ message: "Are you sure you want to logout?",
18
+ });
19
+ if (p.isCancel(confirm) || !confirm) {
20
+ p.cancel("Logout cancelled.");
21
+ return;
22
+ }
23
+ const spinner = p.spinner();
24
+ spinner.start("Logging out...");
25
+ // Invalidate server session
26
+ await api.logout();
27
+ // Delete local credentials
28
+ await deleteCredentials();
29
+ spinner.stop("Logged out");
30
+ p.log.success("Successfully logged out.");
31
+ p.log.info("Your encrypted skills remain on the server. Login again to access them.");
32
+ };
33
+ //# sourceMappingURL=logout.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"logout.js","sourceRoot":"","sources":["../../src/commands/logout.ts"],"names":[],"mappings":"AAAA;;GAEG;AAEH,OAAO,KAAK,CAAC,MAAM,gBAAgB,CAAC;AACpC,OAAO,EAAE,iBAAiB,EAAE,eAAe,EAAE,MAAM,mBAAmB,CAAC;AACvE,OAAO,KAAK,GAAG,MAAM,WAAW,CAAC;AAEjC;;GAEG;AACH,MAAM,CAAC,MAAM,SAAS,GAAG,KAAK,IAAI,EAAE;IAClC,MAAM,WAAW,GAAG,MAAM,eAAe,EAAE,CAAC;IAE5C,IAAI,CAAC,WAAW,EAAE,WAAW,EAAE,CAAC;QAC9B,CAAC,CAAC,GAAG,CAAC,IAAI,CAAC,gBAAgB,CAAC,CAAC;QAC7B,OAAO;IACT,CAAC;IAED,MAAM,OAAO,GAAG,MAAM,CAAC,CAAC,OAAO,CAAC;QAC9B,OAAO,EAAE,kCAAkC;KAC5C,CAAC,CAAC;IAEH,IAAI,CAAC,CAAC,QAAQ,CAAC,OAAO,CAAC,IAAI,CAAC,OAAO,EAAE,CAAC;QACpC,CAAC,CAAC,MAAM,CAAC,mBAAmB,CAAC,CAAC;QAC9B,OAAO;IACT,CAAC;IAED,MAAM,OAAO,GAAG,CAAC,CAAC,OAAO,EAAE,CAAC;IAC5B,OAAO,CAAC,KAAK,CAAC,gBAAgB,CAAC,CAAC;IAEhC,4BAA4B;IAC5B,MAAM,GAAG,CAAC,MAAM,EAAE,CAAC;IAEnB,2BAA2B;IAC3B,MAAM,iBAAiB,EAAE,CAAC;IAE1B,OAAO,CAAC,IAAI,CAAC,YAAY,CAAC,CAAC;IAE3B,CAAC,CAAC,GAAG,CAAC,OAAO,CAAC,0BAA0B,CAAC,CAAC;IAC1C,CAAC,CAAC,GAAG,CAAC,IAAI,CAAC,yEAAyE,CAAC,CAAC;AACxF,CAAC,CAAC"}
@@ -0,0 +1,11 @@
1
+ /**
2
+ * Pull command - download remote skills to local
3
+ */
4
+ export type PullOptions = Partial<{
5
+ interactive: boolean;
6
+ }>;
7
+ /**
8
+ * Run the pull command
9
+ */
10
+ export declare const runPull: (options?: PullOptions) => Promise<void>;
11
+ //# sourceMappingURL=pull.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"pull.d.ts","sourceRoot":"","sources":["../../src/commands/pull.ts"],"names":[],"mappings":"AAAA;;GAEG;AAYH,MAAM,MAAM,WAAW,GAAG,OAAO,CAAC;IAChC,WAAW,EAAE,OAAO,CAAC;CACtB,CAAC,CAAC;AAEH;;GAEG;AACH,eAAO,MAAM,OAAO,GAAU,UAAS,WAAgB,kBAsItD,CAAC"}
@@ -0,0 +1,123 @@
1
+ /**
2
+ * Pull command - download remote skills to local
3
+ */
4
+ import * as p from "@clack/prompts";
5
+ import { listAllSkills, getSkillKey, } from "@claudeskill/core";
6
+ import { loadConfig } from "../config.js";
7
+ import { loadCredentials } from "../credentials.js";
8
+ import { getMasterKey, pullSkills, loadSyncIndex } from "../sync.js";
9
+ import * as api from "../api.js";
10
+ /**
11
+ * Run the pull command
12
+ */
13
+ export const runPull = async (options = {}) => {
14
+ const config = await loadConfig();
15
+ if (!config) {
16
+ p.log.error("Not configured. Run 'claude-skill-sync' first to set up.");
17
+ return;
18
+ }
19
+ if (config.mode === "local") {
20
+ p.log.error("Cannot pull in local-only mode. Change mode with 'claude-skill-sync config'.");
21
+ return;
22
+ }
23
+ const credentials = await loadCredentials();
24
+ if (!credentials?.accessToken) {
25
+ p.log.error("Not logged in. Run 'claude-skill-sync login' first.");
26
+ return;
27
+ }
28
+ // Check server connection
29
+ const healthResult = await api.checkHealth();
30
+ if (!healthResult.ok) {
31
+ p.log.error(`Cannot connect to server: ${healthResult.error}`);
32
+ return;
33
+ }
34
+ // In interactive mode, show preview of what will be pulled
35
+ if (options.interactive) {
36
+ const spinner = p.spinner();
37
+ spinner.start("Checking for updates...");
38
+ const skills = await listAllSkills();
39
+ const index = await loadSyncIndex();
40
+ const localSkillKeys = new Set(skills.map((s) => getSkillKey(s)));
41
+ // Get remote skills list
42
+ const listResult = await api.listSkills();
43
+ if (!listResult.ok) {
44
+ spinner.stop("Failed to check updates");
45
+ p.log.error(`Cannot list remote skills: ${listResult.error}`);
46
+ return;
47
+ }
48
+ const changes = listResult.data.skills
49
+ .filter((remoteSkill) => remoteSkill.currentHash)
50
+ .map((remoteSkill) => {
51
+ const existing = index.skills[remoteSkill.skillKey];
52
+ if (!localSkillKeys.has(remoteSkill.skillKey)) {
53
+ return { skillKey: remoteSkill.skillKey, status: "new" };
54
+ }
55
+ if (existing?.hash !== remoteSkill.currentHash) {
56
+ return { skillKey: remoteSkill.skillKey, status: "updated" };
57
+ }
58
+ return null;
59
+ })
60
+ .filter((change) => change !== null);
61
+ spinner.stop("Updates checked");
62
+ if (changes.length === 0) {
63
+ p.log.info("No updates to pull. Everything is up to date.");
64
+ return;
65
+ }
66
+ // Show preview
67
+ console.log("");
68
+ console.log("Updates to pull:");
69
+ changes.forEach((change) => {
70
+ const icon = change.status === "new" ? "+" : "~";
71
+ const label = change.status === "new" ? "new" : "updated";
72
+ console.log(` ${icon} ${change.skillKey} (${label})`);
73
+ });
74
+ console.log("");
75
+ // Confirm
76
+ const confirm = await p.confirm({
77
+ message: `Pull ${changes.length} item${changes.length === 1 ? "" : "s"}?`,
78
+ });
79
+ if (p.isCancel(confirm) || !confirm) {
80
+ p.cancel("Pull cancelled.");
81
+ return;
82
+ }
83
+ }
84
+ // Get passphrase to unlock vault
85
+ const passphrase = await p.password({
86
+ message: "Vault passphrase:",
87
+ mask: "*",
88
+ });
89
+ if (p.isCancel(passphrase)) {
90
+ p.cancel("Pull cancelled.");
91
+ return;
92
+ }
93
+ // Get master key
94
+ const spinner = p.spinner();
95
+ spinner.start("Unlocking vault...");
96
+ const masterKey = await getMasterKey(passphrase);
97
+ if (!masterKey) {
98
+ spinner.stop("Failed to unlock vault");
99
+ p.log.error("Invalid passphrase or corrupted credentials.");
100
+ return;
101
+ }
102
+ spinner.stop("Vault unlocked");
103
+ // Pull skills
104
+ spinner.start("Pulling skills...");
105
+ const { pulled, errors } = await pullSkills(masterKey, (msg) => {
106
+ spinner.message(msg);
107
+ });
108
+ spinner.stop("Pull complete");
109
+ // Report results
110
+ if (pulled > 0) {
111
+ p.log.success(`Pulled ${pulled} skill${pulled === 1 ? "" : "s"}`);
112
+ }
113
+ else {
114
+ p.log.info("No new skills to pull");
115
+ }
116
+ if (errors.length > 0) {
117
+ p.log.warning("Some skills failed to pull:");
118
+ errors.forEach((error) => {
119
+ p.log.error(` ${error}`);
120
+ });
121
+ }
122
+ };
123
+ //# sourceMappingURL=pull.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"pull.js","sourceRoot":"","sources":["../../src/commands/pull.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,12 @@
1
+ /**
2
+ * Push command - upload local skills to server
3
+ */
4
+ export type PushOptions = Partial<{
5
+ message: string;
6
+ interactive: boolean;
7
+ }>;
8
+ /**
9
+ * Run the push command
10
+ */
11
+ export declare const runPush: (options?: PushOptions) => Promise<void>;
12
+ //# sourceMappingURL=push.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"push.d.ts","sourceRoot":"","sources":["../../src/commands/push.ts"],"names":[],"mappings":"AAAA;;GAEG;AAcH,MAAM,MAAM,WAAW,GAAG,OAAO,CAAC;IAChC,OAAO,EAAE,MAAM,CAAC;IAChB,WAAW,EAAE,OAAO,CAAC;CACtB,CAAC,CAAC;AAEH;;GAEG;AACH,eAAO,MAAM,OAAO,GAAU,UAAS,WAAgB,kBA6ItD,CAAC"}
@@ -0,0 +1,128 @@
1
+ /**
2
+ * Push command - upload local skills to server
3
+ */
4
+ import * as p from "@clack/prompts";
5
+ import { listAllSkills, computeSkillHash, getSkillKey, } from "@claudeskill/core";
6
+ import { loadConfig } from "../config.js";
7
+ import { loadCredentials } from "../credentials.js";
8
+ import { getMasterKey, pushSkills, loadSyncIndex } from "../sync.js";
9
+ import * as api from "../api.js";
10
+ /**
11
+ * Run the push command
12
+ */
13
+ export const runPush = async (options = {}) => {
14
+ const config = await loadConfig();
15
+ if (!config) {
16
+ p.log.error("Not configured. Run 'claude-skill-sync' first to set up.");
17
+ return;
18
+ }
19
+ if (config.mode === "local") {
20
+ p.log.error("Cannot push in local-only mode. Change mode with 'claude-skill-sync config'.");
21
+ return;
22
+ }
23
+ const credentials = await loadCredentials();
24
+ if (!credentials?.accessToken) {
25
+ p.log.error("Not logged in. Run 'claude-skill-sync login' first.");
26
+ return;
27
+ }
28
+ // Check server connection
29
+ const healthResult = await api.checkHealth();
30
+ if (!healthResult.ok) {
31
+ p.log.error(`Cannot connect to server: ${healthResult.error}`);
32
+ return;
33
+ }
34
+ // In interactive mode, show preview of what will be pushed
35
+ if (options.interactive) {
36
+ const spinner = p.spinner();
37
+ spinner.start("Checking for changes...");
38
+ const skills = await listAllSkills();
39
+ const index = await loadSyncIndex();
40
+ const changes = skills
41
+ .map((skill) => {
42
+ const skillKey = getSkillKey(skill);
43
+ const contentHash = computeSkillHash(skill);
44
+ const existing = index.skills[skillKey];
45
+ if (!existing) {
46
+ return { name: skill.name, type: skill.type, status: "new" };
47
+ }
48
+ if (existing.hash !== contentHash) {
49
+ return { name: skill.name, type: skill.type, status: "modified" };
50
+ }
51
+ return null;
52
+ })
53
+ .filter((change) => change !== null);
54
+ spinner.stop("Changes detected");
55
+ if (changes.length === 0) {
56
+ p.log.info("No changes to push. Everything is up to date.");
57
+ return;
58
+ }
59
+ // Show preview
60
+ console.log("");
61
+ console.log("Changes to push:");
62
+ changes.forEach((change) => {
63
+ const icon = change.status === "new" ? "+" : "~";
64
+ const label = change.status === "new" ? "new" : "modified";
65
+ console.log(` ${icon} ${change.type}/${change.name} (${label})`);
66
+ });
67
+ console.log("");
68
+ // Confirm
69
+ const confirm = await p.confirm({
70
+ message: `Push ${changes.length} item${changes.length === 1 ? "" : "s"}?`,
71
+ });
72
+ if (p.isCancel(confirm) || !confirm) {
73
+ p.cancel("Push cancelled.");
74
+ return;
75
+ }
76
+ // Ask for commit message
77
+ const commitMessage = await p.text({
78
+ message: "Commit message (optional):",
79
+ placeholder: "Describe your changes...",
80
+ });
81
+ if (p.isCancel(commitMessage)) {
82
+ p.cancel("Push cancelled.");
83
+ return;
84
+ }
85
+ if (commitMessage) {
86
+ options.message = commitMessage;
87
+ }
88
+ }
89
+ // Get passphrase to unlock vault
90
+ const passphrase = await p.password({
91
+ message: "Vault passphrase:",
92
+ mask: "*",
93
+ });
94
+ if (p.isCancel(passphrase)) {
95
+ p.cancel("Push cancelled.");
96
+ return;
97
+ }
98
+ // Get master key
99
+ const spinner = p.spinner();
100
+ spinner.start("Unlocking vault...");
101
+ const masterKey = await getMasterKey(passphrase);
102
+ if (!masterKey) {
103
+ spinner.stop("Failed to unlock vault");
104
+ p.log.error("Invalid passphrase or corrupted credentials.");
105
+ return;
106
+ }
107
+ spinner.stop("Vault unlocked");
108
+ // Push skills
109
+ spinner.start("Pushing skills...");
110
+ const { pushed, errors } = await pushSkills(masterKey, (msg) => {
111
+ spinner.message(msg);
112
+ }, options.message);
113
+ spinner.stop("Push complete");
114
+ // Report results
115
+ if (pushed > 0) {
116
+ p.log.success(`Pushed ${pushed} skill${pushed === 1 ? "" : "s"}`);
117
+ }
118
+ else {
119
+ p.log.info("No changes to push");
120
+ }
121
+ if (errors.length > 0) {
122
+ p.log.warning("Some skills failed to push:");
123
+ errors.forEach((error) => {
124
+ p.log.error(` ${error}`);
125
+ });
126
+ }
127
+ };
128
+ //# sourceMappingURL=push.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"push.js","sourceRoot":"","sources":["../../src/commands/push.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,8 @@
1
+ /**
2
+ * Status command - show sync status
3
+ */
4
+ /**
5
+ * Run the status command
6
+ */
7
+ export declare const runStatus: () => Promise<void>;
8
+ //# sourceMappingURL=status.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"status.d.ts","sourceRoot":"","sources":["../../src/commands/status.ts"],"names":[],"mappings":"AAAA;;GAEG;AA0BH;;GAEG;AACH,eAAO,MAAM,SAAS,qBA8ErB,CAAC"}