skillo 0.2.6 → 0.2.9
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 +198 -198
- package/dist/api-client-BF6GDR7Q.js +12 -0
- package/dist/{chunk-WJKZWKER.js → chunk-63FVALWX.js} +1 -1
- package/dist/chunk-63FVALWX.js.map +1 -0
- package/dist/chunk-6GOJPFZ7.js +113 -0
- package/dist/chunk-6GOJPFZ7.js.map +1 -0
- package/dist/chunk-6UGTWBUW.js +89 -0
- package/dist/chunk-6UGTWBUW.js.map +1 -0
- package/dist/{chunk-2CVEPT6U.js → chunk-73NUWYUO.js} +2 -2
- package/dist/chunk-73NUWYUO.js.map +1 -0
- package/dist/chunk-QIV4VIXA.js +221 -0
- package/dist/chunk-QIV4VIXA.js.map +1 -0
- package/dist/{chunk-CPL3P2OF.js → chunk-QUXHHRRK.js} +2 -2
- package/dist/chunk-QUXHHRRK.js.map +1 -0
- package/dist/{chunk-ODOZM4QV.js → chunk-RQ2SC5HW.js} +72 -10
- package/dist/chunk-RQ2SC5HW.js.map +1 -0
- package/dist/chunk-U53QWUOR.js +727 -0
- package/dist/chunk-U53QWUOR.js.map +1 -0
- package/dist/chunk-VAQ73XPE.js +68 -0
- package/dist/chunk-VAQ73XPE.js.map +1 -0
- package/dist/chunk-XLJGCOVT.js +975 -0
- package/dist/chunk-XLJGCOVT.js.map +1 -0
- package/dist/{claude-watcher-N6GN6WHJ.js → claude-watcher-WKGBJYKN.js} +65 -3
- package/dist/claude-watcher-WKGBJYKN.js.map +1 -0
- package/dist/cli.js +495 -1846
- package/dist/cli.js.map +1 -1
- package/dist/{config-P5EM5L7N.js → config-ZOKAP2LJ.js} +3 -3
- package/dist/daemon-6DTCMOJB.js +28 -0
- package/dist/daemon-runner.js +338 -71
- package/dist/daemon-runner.js.map +1 -1
- package/dist/database-KQY5OSCS.js +9 -0
- package/dist/git-OGUSYBJS.js +16 -0
- package/dist/git-OGUSYBJS.js.map +1 -0
- package/dist/git-OUAHIOY2.js +110 -0
- package/dist/git-OUAHIOY2.js.map +1 -0
- package/dist/index.js.map +1 -1
- package/dist/{paths-INOKEM66.js → paths-MPOZBOKE.js} +2 -2
- package/dist/paths-MPOZBOKE.js.map +1 -0
- package/dist/project-OFU2W6MH.js +19 -0
- package/dist/project-OFU2W6MH.js.map +1 -0
- package/dist/shell-NZABRJLA.js +16 -0
- package/dist/shell-NZABRJLA.js.map +1 -0
- package/dist/skill-installer-F67OAOQN.js +121 -0
- package/dist/skill-installer-F67OAOQN.js.map +1 -0
- package/dist/{skill-usage-detector-EO26MRYV.js → skill-usage-detector-MSW5VWQZ.js} +2 -2
- package/dist/skill-usage-detector-MSW5VWQZ.js.map +1 -0
- package/dist/tray-WKFGUUTO.js +346 -0
- package/dist/tray-WKFGUUTO.js.map +1 -0
- package/package.json +62 -63
- package/scripts/postinstall.mjs +415 -364
- package/scripts/tray-helper-darwin +0 -0
- package/scripts/tray-helper-darwin.swift +180 -180
- package/scripts/tray-helper-linux.py +322 -0
- package/scripts/tray-helper-windows.cs +322 -0
- package/dist/api-client-KUQW7FSC.js +0 -12
- package/dist/chunk-2CVEPT6U.js.map +0 -1
- package/dist/chunk-CPL3P2OF.js.map +0 -1
- package/dist/chunk-ODOZM4QV.js.map +0 -1
- package/dist/chunk-WJKZWKER.js.map +0 -1
- package/dist/claude-watcher-N6GN6WHJ.js.map +0 -1
- package/dist/database-F3BFFZKG.js +0 -9
- package/dist/skill-usage-detector-EO26MRYV.js.map +0 -1
- package/dist/tray-UCAI2U2C.js +0 -408
- package/dist/tray-UCAI2U2C.js.map +0 -1
- /package/dist/{api-client-KUQW7FSC.js.map → api-client-BF6GDR7Q.js.map} +0 -0
- /package/dist/{config-P5EM5L7N.js.map → config-ZOKAP2LJ.js.map} +0 -0
- /package/dist/{database-F3BFFZKG.js.map → daemon-6DTCMOJB.js.map} +0 -0
- /package/dist/{paths-INOKEM66.js.map → database-KQY5OSCS.js.map} +0 -0
package/scripts/postinstall.mjs
CHANGED
|
@@ -1,364 +1,415 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* Postinstall script — auto-setup shell integration on `npm i -g skillo`.
|
|
3
|
-
*
|
|
4
|
-
* Standalone (zero dependencies, plain Node.js).
|
|
5
|
-
* Detects current shell, writes integration script, adds source line to rc file.
|
|
6
|
-
* Silent on failure — never breaks `npm install`.
|
|
7
|
-
*
|
|
8
|
-
* Cross-platform: macOS, Linux, Windows (PowerShell).
|
|
9
|
-
*/
|
|
10
|
-
|
|
11
|
-
import { existsSync, readFileSync, writeFileSync, appendFileSync, mkdirSync, chmodSync
|
|
12
|
-
import { join } from "path";
|
|
13
|
-
import { homedir, platform } from "os";
|
|
14
|
-
|
|
15
|
-
const home = homedir();
|
|
16
|
-
const isWin = platform() === "win32";
|
|
17
|
-
const dataDir = join(home, ".skillo");
|
|
18
|
-
const scriptPath = join(dataDir, "shell-integration");
|
|
19
|
-
|
|
20
|
-
function ensureDir(dir) {
|
|
21
|
-
if (!existsSync(dir)) {
|
|
22
|
-
mkdirSync(dir, { recursive: true });
|
|
23
|
-
}
|
|
24
|
-
}
|
|
25
|
-
|
|
26
|
-
function detectShell() {
|
|
27
|
-
if (isWin)
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
|
|
148
|
-
|
|
149
|
-
|
|
150
|
-
|
|
151
|
-
|
|
152
|
-
|
|
153
|
-
|
|
154
|
-
|
|
155
|
-
|
|
156
|
-
|
|
157
|
-
|
|
158
|
-
|
|
159
|
-
|
|
160
|
-
|
|
161
|
-
|
|
162
|
-
|
|
163
|
-
|
|
164
|
-
|
|
165
|
-
|
|
166
|
-
|
|
167
|
-
|
|
168
|
-
|
|
169
|
-
|
|
170
|
-
|
|
171
|
-
|
|
172
|
-
|
|
173
|
-
|
|
174
|
-
|
|
175
|
-
|
|
176
|
-
|
|
177
|
-
|
|
178
|
-
|
|
179
|
-
|
|
180
|
-
|
|
181
|
-
|
|
182
|
-
|
|
183
|
-
|
|
184
|
-
|
|
185
|
-
|
|
186
|
-
|
|
187
|
-
|
|
188
|
-
|
|
189
|
-
|
|
190
|
-
|
|
191
|
-
|
|
192
|
-
|
|
193
|
-
|
|
194
|
-
|
|
195
|
-
|
|
196
|
-
|
|
197
|
-
|
|
198
|
-
|
|
199
|
-
|
|
200
|
-
|
|
201
|
-
|
|
202
|
-
|
|
203
|
-
|
|
204
|
-
|
|
205
|
-
|
|
206
|
-
|
|
207
|
-
|
|
208
|
-
|
|
209
|
-
|
|
210
|
-
|
|
211
|
-
|
|
212
|
-
|
|
213
|
-
|
|
214
|
-
|
|
215
|
-
|
|
216
|
-
|
|
217
|
-
|
|
218
|
-
|
|
219
|
-
$
|
|
220
|
-
$
|
|
221
|
-
|
|
222
|
-
|
|
223
|
-
|
|
224
|
-
|
|
225
|
-
|
|
226
|
-
|
|
227
|
-
|
|
228
|
-
|
|
229
|
-
|
|
230
|
-
|
|
231
|
-
|
|
232
|
-
|
|
233
|
-
|
|
234
|
-
|
|
235
|
-
|
|
236
|
-
|
|
237
|
-
|
|
238
|
-
|
|
239
|
-
|
|
240
|
-
|
|
241
|
-
|
|
242
|
-
|
|
243
|
-
|
|
244
|
-
|
|
245
|
-
|
|
246
|
-
|
|
247
|
-
|
|
248
|
-
|
|
249
|
-
|
|
250
|
-
|
|
251
|
-
|
|
252
|
-
|
|
253
|
-
|
|
254
|
-
|
|
255
|
-
|
|
256
|
-
|
|
257
|
-
|
|
258
|
-
|
|
259
|
-
|
|
260
|
-
|
|
261
|
-
|
|
262
|
-
|
|
263
|
-
|
|
264
|
-
}
|
|
265
|
-
|
|
266
|
-
|
|
267
|
-
|
|
268
|
-
|
|
269
|
-
|
|
270
|
-
|
|
271
|
-
|
|
272
|
-
|
|
273
|
-
|
|
274
|
-
|
|
275
|
-
|
|
276
|
-
|
|
277
|
-
|
|
278
|
-
|
|
279
|
-
|
|
280
|
-
|
|
281
|
-
|
|
282
|
-
|
|
283
|
-
|
|
284
|
-
|
|
285
|
-
|
|
286
|
-
|
|
287
|
-
|
|
288
|
-
|
|
289
|
-
|
|
290
|
-
|
|
291
|
-
|
|
292
|
-
|
|
293
|
-
|
|
294
|
-
|
|
295
|
-
|
|
296
|
-
|
|
297
|
-
|
|
298
|
-
|
|
299
|
-
|
|
300
|
-
|
|
301
|
-
|
|
302
|
-
|
|
303
|
-
|
|
304
|
-
|
|
305
|
-
|
|
306
|
-
|
|
307
|
-
|
|
308
|
-
|
|
309
|
-
|
|
310
|
-
|
|
311
|
-
|
|
312
|
-
|
|
313
|
-
|
|
314
|
-
|
|
315
|
-
|
|
316
|
-
|
|
317
|
-
|
|
318
|
-
|
|
319
|
-
|
|
320
|
-
|
|
321
|
-
|
|
322
|
-
|
|
323
|
-
|
|
324
|
-
|
|
325
|
-
|
|
326
|
-
|
|
327
|
-
|
|
328
|
-
|
|
329
|
-
|
|
330
|
-
|
|
331
|
-
|
|
332
|
-
|
|
333
|
-
|
|
334
|
-
|
|
335
|
-
|
|
336
|
-
|
|
337
|
-
|
|
338
|
-
|
|
339
|
-
|
|
340
|
-
|
|
341
|
-
|
|
342
|
-
|
|
343
|
-
|
|
344
|
-
|
|
345
|
-
|
|
346
|
-
|
|
347
|
-
|
|
348
|
-
|
|
349
|
-
|
|
350
|
-
|
|
351
|
-
|
|
352
|
-
|
|
353
|
-
|
|
354
|
-
|
|
355
|
-
|
|
356
|
-
|
|
357
|
-
|
|
358
|
-
|
|
359
|
-
|
|
360
|
-
|
|
361
|
-
}
|
|
362
|
-
|
|
363
|
-
|
|
364
|
-
|
|
1
|
+
/**
|
|
2
|
+
* Postinstall script — auto-setup shell integration on `npm i -g skillo`.
|
|
3
|
+
*
|
|
4
|
+
* Standalone (zero dependencies, plain Node.js).
|
|
5
|
+
* Detects current shell, writes integration script, adds source line to rc file.
|
|
6
|
+
* Silent on failure — never breaks `npm install`.
|
|
7
|
+
*
|
|
8
|
+
* Cross-platform: macOS, Linux, Windows (PowerShell).
|
|
9
|
+
*/
|
|
10
|
+
|
|
11
|
+
import { existsSync, readFileSync, writeFileSync, appendFileSync, mkdirSync, chmodSync } from "fs";
|
|
12
|
+
import { join } from "path";
|
|
13
|
+
import { homedir, platform } from "os";
|
|
14
|
+
|
|
15
|
+
const home = homedir();
|
|
16
|
+
const isWin = platform() === "win32";
|
|
17
|
+
const dataDir = join(home, ".skillo");
|
|
18
|
+
const scriptPath = join(dataDir, "shell-integration");
|
|
19
|
+
|
|
20
|
+
function ensureDir(dir) {
|
|
21
|
+
if (!existsSync(dir)) {
|
|
22
|
+
mkdirSync(dir, { recursive: true });
|
|
23
|
+
}
|
|
24
|
+
}
|
|
25
|
+
|
|
26
|
+
function detectShell() {
|
|
27
|
+
if (isWin) {
|
|
28
|
+
// Git Bash / MSYS / MinGW detection
|
|
29
|
+
if (
|
|
30
|
+
process.env.MSYSTEM ||
|
|
31
|
+
(process.env.SHELL && process.env.SHELL.includes("bash")) ||
|
|
32
|
+
process.env.TERM === "mintty"
|
|
33
|
+
) {
|
|
34
|
+
return "bash";
|
|
35
|
+
}
|
|
36
|
+
return "powershell";
|
|
37
|
+
}
|
|
38
|
+
const sh = process.env.SHELL || "";
|
|
39
|
+
if (sh.includes("zsh")) return "zsh";
|
|
40
|
+
if (sh.includes("fish")) return "fish";
|
|
41
|
+
return "bash";
|
|
42
|
+
}
|
|
43
|
+
|
|
44
|
+
// ── Shell scripts ────────────────────────────────────────────────────────────
|
|
45
|
+
//
|
|
46
|
+
// Timing: uses `date +%s` (seconds) everywhere for portability.
|
|
47
|
+
// macOS BSD date does NOT support %N or %3N — those are GNU extensions.
|
|
48
|
+
// Duration is reported in ms (seconds * 1000). Good enough for our purposes.
|
|
49
|
+
|
|
50
|
+
const bashScript = `# Skillo CLI Integration
|
|
51
|
+
# Records commands and auto-detects tracked projects
|
|
52
|
+
|
|
53
|
+
# Ensure daemon is running (< 1ms PID file check)
|
|
54
|
+
_skillo_ensure_daemon() {
|
|
55
|
+
local pidfile="$HOME/.skillo/daemon.pid"
|
|
56
|
+
if [ -f "$pidfile" ]; then
|
|
57
|
+
local pid
|
|
58
|
+
pid=$(cat "$pidfile" 2>/dev/null)
|
|
59
|
+
if [ -n "$pid" ] && kill -0 "$pid" 2>/dev/null; then
|
|
60
|
+
return 0
|
|
61
|
+
fi
|
|
62
|
+
fi
|
|
63
|
+
(skillo start &>/dev/null &)
|
|
64
|
+
}
|
|
65
|
+
_skillo_ensure_daemon
|
|
66
|
+
|
|
67
|
+
_skillo_session="\${SKILLO_SESSION:-default}"
|
|
68
|
+
_skillo_last_cwd=
|
|
69
|
+
|
|
70
|
+
_skillo_preexec() {
|
|
71
|
+
_skillo_cmd="$1"
|
|
72
|
+
_skillo_start_time=$(date +%s)
|
|
73
|
+
}
|
|
74
|
+
|
|
75
|
+
_skillo_check_project() {
|
|
76
|
+
if [ "$PWD" = "$_skillo_last_cwd" ]; then
|
|
77
|
+
return
|
|
78
|
+
fi
|
|
79
|
+
_skillo_last_cwd="$PWD"
|
|
80
|
+
local result
|
|
81
|
+
result=$(skillo session-auto "$PWD" --pid $$ --shell bash 2>/dev/null)
|
|
82
|
+
if [ -n "$result" ]; then
|
|
83
|
+
export SKILLO_SESSION="$result"
|
|
84
|
+
_skillo_session="$result"
|
|
85
|
+
fi
|
|
86
|
+
}
|
|
87
|
+
|
|
88
|
+
_skillo_precmd() {
|
|
89
|
+
local exit_code=$?
|
|
90
|
+
_skillo_check_project
|
|
91
|
+
if [ -n "$_skillo_cmd" ]; then
|
|
92
|
+
local duration=0
|
|
93
|
+
if [ -n "$_skillo_start_time" ]; then
|
|
94
|
+
local end_time=$(date +%s)
|
|
95
|
+
duration=$(( (end_time - _skillo_start_time) * 1000 ))
|
|
96
|
+
fi
|
|
97
|
+
(skillo record "$_skillo_cmd" --cwd "$PWD" --exit-code "$exit_code" --duration "$duration" --session "$_skillo_session" &>/dev/null &)
|
|
98
|
+
_skillo_cmd=""
|
|
99
|
+
fi
|
|
100
|
+
}
|
|
101
|
+
|
|
102
|
+
_skillo_cleanup() {
|
|
103
|
+
if [ -n "$SKILLO_SESSION" ] && [ "$SKILLO_SESSION" != "default" ]; then
|
|
104
|
+
skillo session end --session "$SKILLO_SESSION" &>/dev/null
|
|
105
|
+
fi
|
|
106
|
+
}
|
|
107
|
+
trap _skillo_cleanup EXIT
|
|
108
|
+
|
|
109
|
+
trap '_skillo_preexec "$BASH_COMMAND"' DEBUG
|
|
110
|
+
|
|
111
|
+
if [[ ! "$PROMPT_COMMAND" =~ _skillo_precmd ]]; then
|
|
112
|
+
PROMPT_COMMAND="_skillo_precmd\${PROMPT_COMMAND:+;$PROMPT_COMMAND}"
|
|
113
|
+
fi
|
|
114
|
+
|
|
115
|
+
_skillo_check_project
|
|
116
|
+
|
|
117
|
+
# Show sync status on startup (respects SKILLO_CONFIG_DIR and XDG_CONFIG_HOME)
|
|
118
|
+
if [ -n "$SKILLO_CONFIG_DIR" ]; then
|
|
119
|
+
_skillo_config="$SKILLO_CONFIG_DIR/config.yaml"
|
|
120
|
+
elif [ -n "$XDG_CONFIG_HOME" ]; then
|
|
121
|
+
_skillo_config="$XDG_CONFIG_HOME/skillo/config.yaml"
|
|
122
|
+
else
|
|
123
|
+
_skillo_config="$HOME/.config/skillo/config.yaml"
|
|
124
|
+
fi
|
|
125
|
+
if [ -f "$_skillo_config" ] && grep -q "api_key:" "$_skillo_config" 2>/dev/null; then
|
|
126
|
+
echo -e "\\033[90mSkillo: Command tracking enabled (syncing to platform)\\033[0m"
|
|
127
|
+
else
|
|
128
|
+
echo -e "\\033[33mSkillo: Command tracking enabled (local only — run 'skillo login' to sync)\\033[0m"
|
|
129
|
+
fi
|
|
130
|
+
`;
|
|
131
|
+
|
|
132
|
+
const zshScript = `# Skillo CLI Integration
|
|
133
|
+
# Records commands and auto-detects tracked projects
|
|
134
|
+
|
|
135
|
+
# Ensure daemon is running (< 1ms PID file check)
|
|
136
|
+
_skillo_ensure_daemon() {
|
|
137
|
+
local pidfile="$HOME/.skillo/daemon.pid"
|
|
138
|
+
if [[ -f "$pidfile" ]]; then
|
|
139
|
+
local pid
|
|
140
|
+
pid=$(cat "$pidfile" 2>/dev/null)
|
|
141
|
+
if [[ -n "$pid" ]] && kill -0 "$pid" 2>/dev/null; then
|
|
142
|
+
return 0
|
|
143
|
+
fi
|
|
144
|
+
fi
|
|
145
|
+
(skillo start &>/dev/null &)
|
|
146
|
+
}
|
|
147
|
+
_skillo_ensure_daemon
|
|
148
|
+
|
|
149
|
+
_skillo_session="\${SKILLO_SESSION:-default}"
|
|
150
|
+
_skillo_last_cwd=
|
|
151
|
+
|
|
152
|
+
_skillo_preexec() {
|
|
153
|
+
_skillo_cmd="$1"
|
|
154
|
+
_skillo_start_time=$(date +%s)
|
|
155
|
+
}
|
|
156
|
+
|
|
157
|
+
_skillo_check_project() {
|
|
158
|
+
if [[ "$PWD" == "$_skillo_last_cwd" ]]; then
|
|
159
|
+
return
|
|
160
|
+
fi
|
|
161
|
+
_skillo_last_cwd="$PWD"
|
|
162
|
+
local result
|
|
163
|
+
result=$(skillo session-auto "$PWD" --pid $$ --shell zsh 2>/dev/null)
|
|
164
|
+
if [[ -n "$result" ]]; then
|
|
165
|
+
export SKILLO_SESSION="$result"
|
|
166
|
+
_skillo_session="$result"
|
|
167
|
+
fi
|
|
168
|
+
}
|
|
169
|
+
|
|
170
|
+
_skillo_precmd() {
|
|
171
|
+
local exit_code=$?
|
|
172
|
+
_skillo_check_project
|
|
173
|
+
if [[ -n "$_skillo_cmd" ]]; then
|
|
174
|
+
local duration=0
|
|
175
|
+
if [[ -n "$_skillo_start_time" ]]; then
|
|
176
|
+
local end_time=$(date +%s)
|
|
177
|
+
duration=$(( (end_time - _skillo_start_time) * 1000 ))
|
|
178
|
+
fi
|
|
179
|
+
(skillo record "$_skillo_cmd" --cwd "$PWD" --exit-code "$exit_code" --duration "$duration" --session "$_skillo_session" &>/dev/null &)
|
|
180
|
+
_skillo_cmd=""
|
|
181
|
+
fi
|
|
182
|
+
}
|
|
183
|
+
|
|
184
|
+
_skillo_cleanup() {
|
|
185
|
+
if [[ -n "$SKILLO_SESSION" ]] && [[ "$SKILLO_SESSION" != "default" ]]; then
|
|
186
|
+
skillo session end --session "$SKILLO_SESSION" &>/dev/null
|
|
187
|
+
fi
|
|
188
|
+
}
|
|
189
|
+
trap _skillo_cleanup EXIT
|
|
190
|
+
|
|
191
|
+
autoload -Uz add-zsh-hook
|
|
192
|
+
add-zsh-hook preexec _skillo_preexec
|
|
193
|
+
add-zsh-hook precmd _skillo_precmd
|
|
194
|
+
|
|
195
|
+
_skillo_check_project
|
|
196
|
+
|
|
197
|
+
# Show sync status on startup (respects SKILLO_CONFIG_DIR and XDG_CONFIG_HOME)
|
|
198
|
+
if [ -n "$SKILLO_CONFIG_DIR" ]; then
|
|
199
|
+
_skillo_config="$SKILLO_CONFIG_DIR/config.yaml"
|
|
200
|
+
elif [ -n "$XDG_CONFIG_HOME" ]; then
|
|
201
|
+
_skillo_config="$XDG_CONFIG_HOME/skillo/config.yaml"
|
|
202
|
+
else
|
|
203
|
+
_skillo_config="$HOME/.config/skillo/config.yaml"
|
|
204
|
+
fi
|
|
205
|
+
if [ -f "$_skillo_config" ] && grep -q "api_key:" "$_skillo_config" 2>/dev/null; then
|
|
206
|
+
echo -e "\\033[90mSkillo: Command tracking enabled (syncing to platform)\\033[0m"
|
|
207
|
+
else
|
|
208
|
+
echo -e "\\033[33mSkillo: Command tracking enabled (local only — run 'skillo login' to sync)\\033[0m"
|
|
209
|
+
fi
|
|
210
|
+
`;
|
|
211
|
+
|
|
212
|
+
const fishScript = `# Skillo CLI Integration
|
|
213
|
+
# Records commands and auto-detects tracked projects
|
|
214
|
+
|
|
215
|
+
# Ensure daemon is running (< 1ms PID file check)
|
|
216
|
+
function _skillo_ensure_daemon
|
|
217
|
+
set -l pidfile "$HOME/.skillo/daemon.pid"
|
|
218
|
+
if test -f "$pidfile"
|
|
219
|
+
set -l pid (cat "$pidfile" 2>/dev/null)
|
|
220
|
+
if test -n "$pid"; and kill -0 "$pid" 2>/dev/null
|
|
221
|
+
return 0
|
|
222
|
+
end
|
|
223
|
+
end
|
|
224
|
+
skillo start &>/dev/null &
|
|
225
|
+
end
|
|
226
|
+
_skillo_ensure_daemon
|
|
227
|
+
|
|
228
|
+
set -q SKILLO_SESSION; or set -g SKILLO_SESSION "default"
|
|
229
|
+
|
|
230
|
+
function _skillo_postexec --on-event fish_postexec
|
|
231
|
+
set -l cmd $argv[1]
|
|
232
|
+
set -l exit_code $status
|
|
233
|
+
skillo record "$cmd" --cwd (pwd) --exit-code $exit_code --session $SKILLO_SESSION &>/dev/null &
|
|
234
|
+
end
|
|
235
|
+
|
|
236
|
+
# Show sync status on startup (respects SKILLO_CONFIG_DIR and XDG_CONFIG_HOME)
|
|
237
|
+
if set -q SKILLO_CONFIG_DIR
|
|
238
|
+
set _skillo_config "$SKILLO_CONFIG_DIR/config.yaml"
|
|
239
|
+
else if set -q XDG_CONFIG_HOME
|
|
240
|
+
set _skillo_config "$XDG_CONFIG_HOME/skillo/config.yaml"
|
|
241
|
+
else
|
|
242
|
+
set _skillo_config "$HOME/.config/skillo/config.yaml"
|
|
243
|
+
end
|
|
244
|
+
if test -f "$_skillo_config"; and grep -q "api_key:" "$_skillo_config" 2>/dev/null
|
|
245
|
+
echo -e "\\033[90mSkillo: Command tracking enabled (syncing to platform)\\033[0m"
|
|
246
|
+
else
|
|
247
|
+
echo -e "\\033[33mSkillo: Command tracking enabled (local only — run 'skillo login' to sync)\\033[0m"
|
|
248
|
+
end
|
|
249
|
+
`;
|
|
250
|
+
|
|
251
|
+
const psScript = `# Skillo CLI Integration
|
|
252
|
+
# Records commands and auto-detects tracked projects
|
|
253
|
+
|
|
254
|
+
# Ensure daemon is running (< 1ms PID file check)
|
|
255
|
+
function _SkilloEnsureDaemon {
|
|
256
|
+
$pidfile = Join-Path $env:USERPROFILE ".skillo" "daemon.pid"
|
|
257
|
+
if (Test-Path $pidfile) {
|
|
258
|
+
$pid = Get-Content $pidfile -ErrorAction SilentlyContinue
|
|
259
|
+
if ($pid) {
|
|
260
|
+
try {
|
|
261
|
+
Get-Process -Id ([int]$pid) -ErrorAction Stop | Out-Null
|
|
262
|
+
return
|
|
263
|
+
} catch { }
|
|
264
|
+
}
|
|
265
|
+
}
|
|
266
|
+
Start-Job -ScriptBlock { & skillo start 2>$null } | Out-Null
|
|
267
|
+
}
|
|
268
|
+
_SkilloEnsureDaemon
|
|
269
|
+
|
|
270
|
+
$Global:SkilloSessionId = if ($env:SKILLO_SESSION) { $env:SKILLO_SESSION } else { 'default' }
|
|
271
|
+
$Global:SkilloLastHistoryId = 0
|
|
272
|
+
$Global:SkilloLastCwd = $null
|
|
273
|
+
|
|
274
|
+
function _SkilloCheckProject {
|
|
275
|
+
$cwd = (Get-Location).Path
|
|
276
|
+
if ($cwd -eq $Global:SkilloLastCwd) { return }
|
|
277
|
+
$Global:SkilloLastCwd = $cwd
|
|
278
|
+
|
|
279
|
+
try {
|
|
280
|
+
$result = & skillo session-auto $cwd --pid $PID --shell powershell 2>$null
|
|
281
|
+
if ($result -and $result.Trim()) {
|
|
282
|
+
$env:SKILLO_SESSION = $result.Trim()
|
|
283
|
+
$Global:SkilloSessionId = $result.Trim()
|
|
284
|
+
}
|
|
285
|
+
} catch { }
|
|
286
|
+
}
|
|
287
|
+
|
|
288
|
+
$Global:SkilloOriginalPrompt = $function:prompt
|
|
289
|
+
function Global:prompt {
|
|
290
|
+
$lastCmd = Get-History -Count 1 -ErrorAction SilentlyContinue
|
|
291
|
+
|
|
292
|
+
if ($lastCmd -and $lastCmd.Id -gt $Global:SkilloLastHistoryId) {
|
|
293
|
+
$Global:SkilloLastHistoryId = $lastCmd.Id
|
|
294
|
+
|
|
295
|
+
$duration = 0
|
|
296
|
+
if ($lastCmd.EndExecutionTime -and $lastCmd.StartExecutionTime) {
|
|
297
|
+
$duration = [int]($lastCmd.EndExecutionTime - $lastCmd.StartExecutionTime).TotalMilliseconds
|
|
298
|
+
}
|
|
299
|
+
$exit = if ($null -eq $LASTEXITCODE) { 0 } else { $LASTEXITCODE }
|
|
300
|
+
$cwd = (Get-Location).Path
|
|
301
|
+
|
|
302
|
+
Start-Job -ScriptBlock {
|
|
303
|
+
param($cmd, $cwd, $exit, $dur, $sessionId)
|
|
304
|
+
& skillo record $cmd --cwd $cwd --exit-code $exit --duration $dur --session $sessionId 2>$null
|
|
305
|
+
} -ArgumentList $lastCmd.CommandLine, $cwd, $exit, $duration, $Global:SkilloSessionId | Out-Null
|
|
306
|
+
}
|
|
307
|
+
|
|
308
|
+
_SkilloCheckProject
|
|
309
|
+
& $Global:SkilloOriginalPrompt
|
|
310
|
+
}
|
|
311
|
+
|
|
312
|
+
$null = Register-EngineEvent -SourceIdentifier PowerShell.Exiting -Action {
|
|
313
|
+
if ($Global:SkilloSessionId -and $Global:SkilloSessionId -ne 'default') {
|
|
314
|
+
try { & skillo session end --session $Global:SkilloSessionId 2>$null } catch { }
|
|
315
|
+
}
|
|
316
|
+
}
|
|
317
|
+
|
|
318
|
+
# Show sync status on startup (respects SKILLO_CONFIG_DIR and XDG_CONFIG_HOME)
|
|
319
|
+
if ($env:SKILLO_CONFIG_DIR) {
|
|
320
|
+
$skilloConfigPath = Join-Path $env:SKILLO_CONFIG_DIR "config.yaml"
|
|
321
|
+
} elseif ($env:XDG_CONFIG_HOME) {
|
|
322
|
+
$skilloConfigPath = Join-Path $env:XDG_CONFIG_HOME "skillo" "config.yaml"
|
|
323
|
+
} else {
|
|
324
|
+
$skilloConfigPath = Join-Path $HOME ".config" "skillo" "config.yaml"
|
|
325
|
+
}
|
|
326
|
+
$skilloLoggedIn = $false
|
|
327
|
+
if (Test-Path $skilloConfigPath) {
|
|
328
|
+
$skilloLoggedIn = (Select-String -Path $skilloConfigPath -Pattern "api_key:" -Quiet) -eq $true
|
|
329
|
+
}
|
|
330
|
+
if ($skilloLoggedIn) {
|
|
331
|
+
Write-Host "Skillo: Command tracking enabled (syncing to platform)" -ForegroundColor DarkGray
|
|
332
|
+
} else {
|
|
333
|
+
Write-Host "Skillo: Command tracking enabled (local only - run 'skillo login' to sync)" -ForegroundColor Yellow
|
|
334
|
+
}
|
|
335
|
+
`;
|
|
336
|
+
|
|
337
|
+
// ── Install logic ────────────────────────────────────────────────────────────
|
|
338
|
+
|
|
339
|
+
function install(shell) {
|
|
340
|
+
ensureDir(scriptPath);
|
|
341
|
+
|
|
342
|
+
let scriptFile, rcPath, sourceLine;
|
|
343
|
+
|
|
344
|
+
if (shell === "zsh") {
|
|
345
|
+
scriptFile = join(scriptPath, "skillo.zsh");
|
|
346
|
+
writeFileSync(scriptFile, zshScript, "utf-8");
|
|
347
|
+
rcPath = join(home, ".zshrc");
|
|
348
|
+
sourceLine = `\n# Skillo CLI Integration\n[ -f "${scriptFile}" ] && source "${scriptFile}"\n`;
|
|
349
|
+
} else if (shell === "bash") {
|
|
350
|
+
scriptFile = join(scriptPath, "skillo.bash");
|
|
351
|
+
writeFileSync(scriptFile, bashScript, "utf-8");
|
|
352
|
+
rcPath = join(home, ".bashrc");
|
|
353
|
+
sourceLine = `\n# Skillo CLI Integration\n[ -f "${scriptFile}" ] && source "${scriptFile}"\n`;
|
|
354
|
+
} else if (shell === "fish") {
|
|
355
|
+
scriptFile = join(scriptPath, "skillo.fish");
|
|
356
|
+
writeFileSync(scriptFile, fishScript, "utf-8");
|
|
357
|
+
const fishConfigDir = join(home, ".config", "fish");
|
|
358
|
+
ensureDir(fishConfigDir);
|
|
359
|
+
rcPath = join(fishConfigDir, "config.fish");
|
|
360
|
+
sourceLine = `\n# Skillo CLI Integration\nif test -f "${scriptFile}"\n source "${scriptFile}"\nend\n`;
|
|
361
|
+
} else if (shell === "powershell") {
|
|
362
|
+
scriptFile = join(scriptPath, "skillo.ps1");
|
|
363
|
+
writeFileSync(scriptFile, psScript, "utf-8");
|
|
364
|
+
// Try PowerShell Core profile first, then Windows PowerShell
|
|
365
|
+
const psCorePath = isWin
|
|
366
|
+
? join(home, "Documents", "PowerShell", "Microsoft.PowerShell_profile.ps1")
|
|
367
|
+
: join(home, ".config", "powershell", "Microsoft.PowerShell_profile.ps1");
|
|
368
|
+
const psClassicPath = join(home, "Documents", "WindowsPowerShell", "Microsoft.PowerShell_profile.ps1");
|
|
369
|
+
// Use whichever profile already exists, or default to Core
|
|
370
|
+
rcPath = existsSync(psClassicPath) ? psClassicPath : psCorePath;
|
|
371
|
+
ensureDir(join(rcPath, ".."));
|
|
372
|
+
sourceLine = `\n# Skillo CLI Integration\n. "${scriptFile}"\n`;
|
|
373
|
+
} else {
|
|
374
|
+
return false;
|
|
375
|
+
}
|
|
376
|
+
|
|
377
|
+
// Add source line to rc file (idempotent)
|
|
378
|
+
if (existsSync(rcPath)) {
|
|
379
|
+
const content = readFileSync(rcPath, "utf-8");
|
|
380
|
+
if (content.includes("Skillo CLI Integration")) {
|
|
381
|
+
// Already installed — just update the script file (already written above)
|
|
382
|
+
return true;
|
|
383
|
+
}
|
|
384
|
+
appendFileSync(rcPath, sourceLine);
|
|
385
|
+
} else {
|
|
386
|
+
writeFileSync(rcPath, sourceLine, "utf-8");
|
|
387
|
+
}
|
|
388
|
+
|
|
389
|
+
return true;
|
|
390
|
+
}
|
|
391
|
+
|
|
392
|
+
// ── Main ─────────────────────────────────────────────────────────────────────
|
|
393
|
+
|
|
394
|
+
try {
|
|
395
|
+
const shell = detectShell();
|
|
396
|
+
const installed = install(shell);
|
|
397
|
+
|
|
398
|
+
if (installed) {
|
|
399
|
+
const dim = "\x1b[90m";
|
|
400
|
+
const green = "\x1b[32m";
|
|
401
|
+
const bold = "\x1b[1m";
|
|
402
|
+
const reset = "\x1b[0m";
|
|
403
|
+
console.log("");
|
|
404
|
+
console.log(`${green}${bold}Skillo installed!${reset} Shell integration set up for ${shell}.`);
|
|
405
|
+
console.log("");
|
|
406
|
+
console.log(`${bold} Get started:${reset}`);
|
|
407
|
+
console.log(`${green} skillo start${reset}`);
|
|
408
|
+
console.log("");
|
|
409
|
+
console.log(`${dim} That's it — opens browser to log in, starts the daemon,${reset}`);
|
|
410
|
+
console.log(`${dim} installs auto-start, and adds a tray icon.${reset}`);
|
|
411
|
+
console.log("");
|
|
412
|
+
}
|
|
413
|
+
} catch {
|
|
414
|
+
// Never break npm install — silently skip on any error
|
|
415
|
+
}
|