episoda 0.2.5 → 0.2.8
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/index.d.ts +2 -8
- package/dist/index.js +3735 -82
- package/dist/index.js.map +1 -1
- package/package.json +5 -4
- package/dist/commands/auth.d.ts +0 -22
- package/dist/commands/auth.d.ts.map +0 -1
- package/dist/commands/auth.js +0 -384
- package/dist/commands/auth.js.map +0 -1
- package/dist/commands/dev.d.ts +0 -20
- package/dist/commands/dev.d.ts.map +0 -1
- package/dist/commands/dev.js +0 -305
- package/dist/commands/dev.js.map +0 -1
- package/dist/commands/status.d.ts +0 -13
- package/dist/commands/status.d.ts.map +0 -1
- package/dist/commands/status.js +0 -102
- package/dist/commands/status.js.map +0 -1
- package/dist/commands/stop.d.ts +0 -17
- package/dist/commands/stop.d.ts.map +0 -1
- package/dist/commands/stop.js +0 -81
- package/dist/commands/stop.js.map +0 -1
- package/dist/daemon/daemon-manager.d.ts +0 -71
- package/dist/daemon/daemon-manager.d.ts.map +0 -1
- package/dist/daemon/daemon-manager.js +0 -289
- package/dist/daemon/daemon-manager.js.map +0 -1
- package/dist/daemon/daemon-process.d.ts +0 -13
- package/dist/daemon/daemon-process.d.ts.map +0 -1
- package/dist/daemon/daemon-process.js +0 -662
- package/dist/daemon/daemon-process.js.map +0 -1
- package/dist/daemon/identity-server.d.ts +0 -51
- package/dist/daemon/identity-server.d.ts.map +0 -1
- package/dist/daemon/identity-server.js +0 -162
- package/dist/daemon/identity-server.js.map +0 -1
- package/dist/daemon/machine-id.d.ts +0 -36
- package/dist/daemon/machine-id.d.ts.map +0 -1
- package/dist/daemon/machine-id.js +0 -195
- package/dist/daemon/machine-id.js.map +0 -1
- package/dist/daemon/project-tracker.d.ts +0 -92
- package/dist/daemon/project-tracker.d.ts.map +0 -1
- package/dist/daemon/project-tracker.js +0 -259
- package/dist/daemon/project-tracker.js.map +0 -1
- package/dist/dev-wrapper.d.ts +0 -88
- package/dist/dev-wrapper.d.ts.map +0 -1
- package/dist/dev-wrapper.js +0 -288
- package/dist/dev-wrapper.js.map +0 -1
- package/dist/framework-detector.d.ts +0 -29
- package/dist/framework-detector.d.ts.map +0 -1
- package/dist/framework-detector.js +0 -276
- package/dist/framework-detector.js.map +0 -1
- package/dist/git-helpers/git-credential-helper.d.ts +0 -29
- package/dist/git-helpers/git-credential-helper.d.ts.map +0 -1
- package/dist/git-helpers/git-credential-helper.js +0 -349
- package/dist/git-helpers/git-credential-helper.js.map +0 -1
- package/dist/index.d.ts.map +0 -1
- package/dist/ipc/ipc-client.d.ts +0 -116
- package/dist/ipc/ipc-client.d.ts.map +0 -1
- package/dist/ipc/ipc-client.js +0 -216
- package/dist/ipc/ipc-client.js.map +0 -1
- package/dist/ipc/ipc-server.d.ts +0 -55
- package/dist/ipc/ipc-server.d.ts.map +0 -1
- package/dist/ipc/ipc-server.js +0 -177
- package/dist/ipc/ipc-server.js.map +0 -1
- package/dist/output.d.ts +0 -48
- package/dist/output.d.ts.map +0 -1
- package/dist/output.js +0 -129
- package/dist/output.js.map +0 -1
- package/dist/utils/port-check.d.ts +0 -15
- package/dist/utils/port-check.d.ts.map +0 -1
- package/dist/utils/port-check.js +0 -79
- package/dist/utils/port-check.js.map +0 -1
- package/dist/utils/update-checker.d.ts +0 -23
- package/dist/utils/update-checker.d.ts.map +0 -1
- package/dist/utils/update-checker.js +0 -95
- package/dist/utils/update-checker.js.map +0 -1
|
@@ -1,349 +0,0 @@
|
|
|
1
|
-
"use strict";
|
|
2
|
-
/**
|
|
3
|
-
* EP548/EP612: Git Credential Helper Script Generator
|
|
4
|
-
*
|
|
5
|
-
* This module generates the git credential helper script that is installed
|
|
6
|
-
* during `episoda auth`. The script is called by git when credentials are needed.
|
|
7
|
-
*
|
|
8
|
-
* The generated script:
|
|
9
|
-
* 1. Detects the environment (local vs cloud)
|
|
10
|
-
* 2. Calls GET /api/git/credentials with appropriate auth
|
|
11
|
-
* 3. Returns credentials in git credential protocol format
|
|
12
|
-
* 4. Caches tokens locally (5 min TTL) to avoid API calls on every git operation
|
|
13
|
-
*
|
|
14
|
-
* EP612: Removed jq dependency - uses pure bash JSON parsing
|
|
15
|
-
*/
|
|
16
|
-
Object.defineProperty(exports, "__esModule", { value: true });
|
|
17
|
-
exports.CREDENTIAL_HELPER_SCRIPT = void 0;
|
|
18
|
-
exports.generateCredentialHelperScript = generateCredentialHelperScript;
|
|
19
|
-
/**
|
|
20
|
-
* Generate the credential helper script content
|
|
21
|
-
*
|
|
22
|
-
* The script needs to:
|
|
23
|
-
* - Be standalone (no external dependencies - just bash and curl)
|
|
24
|
-
* - Work with curl (available on all platforms)
|
|
25
|
-
* - Handle both local (OAuth) and cloud (machine ID) auth
|
|
26
|
-
* - Cache tokens to avoid hitting API on every git operation
|
|
27
|
-
*/
|
|
28
|
-
function generateCredentialHelperScript(apiUrl) {
|
|
29
|
-
// The script uses bash because it's universally available
|
|
30
|
-
// No jq dependency - uses pure bash for JSON parsing
|
|
31
|
-
return `#!/bin/bash
|
|
32
|
-
#
|
|
33
|
-
# Episoda Git Credential Helper
|
|
34
|
-
# EP548/EP612: Unified git authentication for all environments
|
|
35
|
-
#
|
|
36
|
-
# This script is called by git when credentials are needed.
|
|
37
|
-
# It calls the Episoda API to get a fresh GitHub token.
|
|
38
|
-
#
|
|
39
|
-
# Installation: episoda auth
|
|
40
|
-
# Location: ~/.episoda/bin/git-credential-episoda (local)
|
|
41
|
-
# /usr/local/bin/git-credential-episoda (cloud VM)
|
|
42
|
-
#
|
|
43
|
-
# Git credential protocol:
|
|
44
|
-
# - git calls: git-credential-episoda get
|
|
45
|
-
# - input on stdin: protocol=https\\nhost=github.com\\n
|
|
46
|
-
# - output on stdout: username=x-access-token\\npassword=TOKEN\\n
|
|
47
|
-
#
|
|
48
|
-
# Dependencies: bash, curl (no jq required)
|
|
49
|
-
#
|
|
50
|
-
|
|
51
|
-
set -euo pipefail
|
|
52
|
-
|
|
53
|
-
EPISODA_DIR="\${HOME}/.episoda"
|
|
54
|
-
CONFIG_FILE="\${EPISODA_DIR}/config.json"
|
|
55
|
-
CACHE_FILE="\${EPISODA_DIR}/git-token-cache.json"
|
|
56
|
-
API_URL="${apiUrl}"
|
|
57
|
-
|
|
58
|
-
# Cache TTL in seconds (5 minutes)
|
|
59
|
-
CACHE_TTL=300
|
|
60
|
-
|
|
61
|
-
# Log function (to stderr so git doesn't see it)
|
|
62
|
-
log() {
|
|
63
|
-
if [[ "\${GIT_CREDENTIAL_EPISODA_DEBUG:-}" == "1" ]]; then
|
|
64
|
-
echo "[episoda-git] \$(date '+%H:%M:%S') \$*" >&2
|
|
65
|
-
fi
|
|
66
|
-
}
|
|
67
|
-
|
|
68
|
-
# Error log (always shown)
|
|
69
|
-
error() {
|
|
70
|
-
echo "[episoda-git] ERROR: \$*" >&2
|
|
71
|
-
}
|
|
72
|
-
|
|
73
|
-
# Pure bash JSON value extraction (no jq needed)
|
|
74
|
-
# Usage: json_get '{"foo":"bar"}' "foo" -> "bar"
|
|
75
|
-
# Handles simple flat JSON and nested paths like "credentials.username"
|
|
76
|
-
json_get() {
|
|
77
|
-
local json="\$1"
|
|
78
|
-
local key="\$2"
|
|
79
|
-
local value=""
|
|
80
|
-
|
|
81
|
-
# Handle nested keys (e.g., "credentials.username")
|
|
82
|
-
if [[ "\$key" == *.* ]]; then
|
|
83
|
-
local outer="\${key%%.*}"
|
|
84
|
-
local inner="\${key#*.}"
|
|
85
|
-
# Extract outer object first, then inner key
|
|
86
|
-
# Match "outer":{...} and extract the {...} part
|
|
87
|
-
local nested
|
|
88
|
-
nested=\$(echo "\$json" | sed -n 's/.*"'\$outer'"[[:space:]]*:[[:space:]]*{\\([^}]*\\)}.*/\\1/p')
|
|
89
|
-
if [[ -n "\$nested" ]]; then
|
|
90
|
-
json_get "{\$nested}" "\$inner"
|
|
91
|
-
return
|
|
92
|
-
fi
|
|
93
|
-
return
|
|
94
|
-
fi
|
|
95
|
-
|
|
96
|
-
# Simple key extraction: "key":"value" or "key": "value"
|
|
97
|
-
# Handle both quoted strings and unquoted values
|
|
98
|
-
value=\$(echo "\$json" | sed -n 's/.*"'\$key'"[[:space:]]*:[[:space:]]*"\\([^"]*\\)".*/\\1/p')
|
|
99
|
-
|
|
100
|
-
if [[ -n "\$value" ]]; then
|
|
101
|
-
echo "\$value"
|
|
102
|
-
fi
|
|
103
|
-
}
|
|
104
|
-
|
|
105
|
-
# Check for required dependencies
|
|
106
|
-
check_dependencies() {
|
|
107
|
-
if ! command -v curl >/dev/null 2>&1; then
|
|
108
|
-
error "curl is required but not installed"
|
|
109
|
-
return 1
|
|
110
|
-
fi
|
|
111
|
-
return 0
|
|
112
|
-
}
|
|
113
|
-
|
|
114
|
-
# Parse git credential input from stdin
|
|
115
|
-
parse_input() {
|
|
116
|
-
while IFS= read -r line; do
|
|
117
|
-
[[ -z "\$line" ]] && break
|
|
118
|
-
case "\$line" in
|
|
119
|
-
protocol=*) PROTOCOL="\${line#protocol=}" ;;
|
|
120
|
-
host=*) HOST="\${line#host=}" ;;
|
|
121
|
-
path=*) PATH_="\${line#path=}" ;;
|
|
122
|
-
esac
|
|
123
|
-
done
|
|
124
|
-
}
|
|
125
|
-
|
|
126
|
-
# Parse ISO 8601 date to unix timestamp (cross-platform)
|
|
127
|
-
parse_iso_date() {
|
|
128
|
-
local iso_date="\$1"
|
|
129
|
-
# Try GNU date first (Linux)
|
|
130
|
-
if date -d "\$iso_date" +%s 2>/dev/null; then
|
|
131
|
-
return
|
|
132
|
-
fi
|
|
133
|
-
# Try BSD date (macOS) - strip timezone for parsing
|
|
134
|
-
local clean_date="\${iso_date%+*}" # Remove +00:00
|
|
135
|
-
clean_date="\${clean_date%Z}" # Remove Z
|
|
136
|
-
clean_date="\${clean_date%.*}" # Remove .milliseconds
|
|
137
|
-
if date -jf "%Y-%m-%dT%H:%M:%S" "\$clean_date" +%s 2>/dev/null; then
|
|
138
|
-
return
|
|
139
|
-
fi
|
|
140
|
-
# Fallback: return 0 (expired)
|
|
141
|
-
echo "0"
|
|
142
|
-
}
|
|
143
|
-
|
|
144
|
-
# Check if cached token is still valid
|
|
145
|
-
get_cached_token() {
|
|
146
|
-
if [[ ! -f "\$CACHE_FILE" ]]; then
|
|
147
|
-
log "No cache file"
|
|
148
|
-
return 1
|
|
149
|
-
fi
|
|
150
|
-
|
|
151
|
-
# Read cache file
|
|
152
|
-
local cache_content
|
|
153
|
-
cache_content=\$(cat "\$CACHE_FILE" 2>/dev/null) || return 1
|
|
154
|
-
|
|
155
|
-
# Parse cache file using pure bash
|
|
156
|
-
local expires_at
|
|
157
|
-
expires_at=\$(json_get "\$cache_content" "expires_at")
|
|
158
|
-
|
|
159
|
-
if [[ -z "\$expires_at" ]]; then
|
|
160
|
-
log "No expires_at in cache"
|
|
161
|
-
return 1
|
|
162
|
-
fi
|
|
163
|
-
|
|
164
|
-
# Check if expired (with 60 second buffer)
|
|
165
|
-
local now expires_ts buffer
|
|
166
|
-
now=\$(date +%s)
|
|
167
|
-
expires_ts=\$(parse_iso_date "\$expires_at")
|
|
168
|
-
buffer=60
|
|
169
|
-
|
|
170
|
-
if [[ \$((expires_ts - buffer)) -le \$now ]]; then
|
|
171
|
-
log "Cache expired (expires: \$expires_at)"
|
|
172
|
-
return 1
|
|
173
|
-
fi
|
|
174
|
-
|
|
175
|
-
# Return cached token
|
|
176
|
-
CACHED_TOKEN=\$(json_get "\$cache_content" "password")
|
|
177
|
-
CACHED_USER=\$(json_get "\$cache_content" "username")
|
|
178
|
-
|
|
179
|
-
if [[ -n "\$CACHED_TOKEN" && -n "\$CACHED_USER" ]]; then
|
|
180
|
-
log "Using cached token (expires: \$expires_at)"
|
|
181
|
-
return 0
|
|
182
|
-
fi
|
|
183
|
-
|
|
184
|
-
log "Invalid cache content"
|
|
185
|
-
return 1
|
|
186
|
-
}
|
|
187
|
-
|
|
188
|
-
# Save token to cache
|
|
189
|
-
save_to_cache() {
|
|
190
|
-
local username="\$1"
|
|
191
|
-
local password="\$2"
|
|
192
|
-
local expires_at="\$3"
|
|
193
|
-
|
|
194
|
-
mkdir -p "\$EPISODA_DIR"
|
|
195
|
-
cat > "\$CACHE_FILE" <<CACHE_EOF
|
|
196
|
-
{"username":"\$username","password":"\$password","expires_at":"\$expires_at","cached_at":"\$(date -u +"%Y-%m-%dT%H:%M:%SZ")"}
|
|
197
|
-
CACHE_EOF
|
|
198
|
-
chmod 600 "\$CACHE_FILE"
|
|
199
|
-
log "Token cached until \$expires_at"
|
|
200
|
-
}
|
|
201
|
-
|
|
202
|
-
# Get credentials from Episoda API
|
|
203
|
-
fetch_credentials() {
|
|
204
|
-
local api_url="\${EPISODA_API_URL:-\${API_URL}}"
|
|
205
|
-
local response=""
|
|
206
|
-
local http_code=""
|
|
207
|
-
|
|
208
|
-
# Detect environment - check multiple ways to identify a cloud VM
|
|
209
|
-
local machine_id=""
|
|
210
|
-
|
|
211
|
-
# Check FLY_MACHINE_ID (set by Fly.io on all machines)
|
|
212
|
-
if [[ -n "\${FLY_MACHINE_ID:-}" ]]; then
|
|
213
|
-
machine_id="\$FLY_MACHINE_ID"
|
|
214
|
-
log "Cloud environment detected via FLY_MACHINE_ID: \$machine_id"
|
|
215
|
-
# Legacy: check /app/.machine_id file
|
|
216
|
-
elif [[ -f "/app/.machine_id" ]]; then
|
|
217
|
-
machine_id=\$(cat /app/.machine_id)
|
|
218
|
-
log "Cloud environment detected via /app/.machine_id: \$machine_id"
|
|
219
|
-
fi
|
|
220
|
-
|
|
221
|
-
if [[ -n "\$machine_id" ]]; then
|
|
222
|
-
# Cloud VM: use machine ID header
|
|
223
|
-
log "Fetching credentials for machine: \$machine_id"
|
|
224
|
-
response=\$(curl -s -w "\\n%{http_code}" --max-time 10 "\${api_url}/api/git/credentials" \\
|
|
225
|
-
-H "X-Machine-ID: \$machine_id" \\
|
|
226
|
-
-H "Content-Type: application/json" 2>&1) || {
|
|
227
|
-
error "curl failed: \$response"
|
|
228
|
-
return 1
|
|
229
|
-
}
|
|
230
|
-
else
|
|
231
|
-
# Local: use OAuth token from config
|
|
232
|
-
if [[ ! -f "\$CONFIG_FILE" ]]; then
|
|
233
|
-
error "No config found at \$CONFIG_FILE. Run 'episoda auth' first."
|
|
234
|
-
return 1
|
|
235
|
-
fi
|
|
236
|
-
|
|
237
|
-
# Parse config using pure bash
|
|
238
|
-
local config_content
|
|
239
|
-
config_content=\$(cat "\$CONFIG_FILE" 2>/dev/null) || {
|
|
240
|
-
error "Cannot read config file"
|
|
241
|
-
return 1
|
|
242
|
-
}
|
|
243
|
-
|
|
244
|
-
local access_token project_id
|
|
245
|
-
access_token=\$(json_get "\$config_content" "access_token")
|
|
246
|
-
project_id=\$(json_get "\$config_content" "project_id")
|
|
247
|
-
|
|
248
|
-
if [[ -z "\$access_token" ]]; then
|
|
249
|
-
error "No access token in config. Run 'episoda auth' to authenticate."
|
|
250
|
-
return 1
|
|
251
|
-
fi
|
|
252
|
-
|
|
253
|
-
log "Local environment (project: \$project_id)"
|
|
254
|
-
response=\$(curl -s -w "\\n%{http_code}" --max-time 10 "\${api_url}/api/git/credentials" \\
|
|
255
|
-
-H "Authorization: Bearer \$access_token" \\
|
|
256
|
-
-H "X-Project-ID: \$project_id" \\
|
|
257
|
-
-H "Content-Type: application/json" 2>&1) || {
|
|
258
|
-
error "curl failed: \$response"
|
|
259
|
-
return 1
|
|
260
|
-
}
|
|
261
|
-
fi
|
|
262
|
-
|
|
263
|
-
# Split response and HTTP code
|
|
264
|
-
http_code=\$(echo "\$response" | tail -n1)
|
|
265
|
-
response=\$(echo "\$response" | sed '\$d')
|
|
266
|
-
|
|
267
|
-
# Check HTTP status
|
|
268
|
-
if [[ "\$http_code" != "200" ]]; then
|
|
269
|
-
error "API returned HTTP \$http_code"
|
|
270
|
-
log "Response: \$response"
|
|
271
|
-
return 1
|
|
272
|
-
fi
|
|
273
|
-
|
|
274
|
-
# Parse response using pure bash
|
|
275
|
-
CRED_USERNAME=\$(json_get "\$response" "credentials.username")
|
|
276
|
-
CRED_PASSWORD=\$(json_get "\$response" "credentials.password")
|
|
277
|
-
CRED_EXPIRES=\$(json_get "\$response" "credentials.expires_at")
|
|
278
|
-
|
|
279
|
-
if [[ -z "\$CRED_USERNAME" || -z "\$CRED_PASSWORD" ]]; then
|
|
280
|
-
error "Invalid credentials in response"
|
|
281
|
-
log "Response: \$response"
|
|
282
|
-
return 1
|
|
283
|
-
fi
|
|
284
|
-
|
|
285
|
-
# Cache the token
|
|
286
|
-
save_to_cache "\$CRED_USERNAME" "\$CRED_PASSWORD" "\$CRED_EXPIRES"
|
|
287
|
-
|
|
288
|
-
log "Credentials fetched successfully"
|
|
289
|
-
return 0
|
|
290
|
-
}
|
|
291
|
-
|
|
292
|
-
# Main
|
|
293
|
-
main() {
|
|
294
|
-
local command="\${1:-}"
|
|
295
|
-
|
|
296
|
-
# Check dependencies before processing
|
|
297
|
-
if ! check_dependencies; then
|
|
298
|
-
exit 0 # Exit gracefully so git tries other helpers
|
|
299
|
-
fi
|
|
300
|
-
|
|
301
|
-
case "\$command" in
|
|
302
|
-
get)
|
|
303
|
-
parse_input
|
|
304
|
-
|
|
305
|
-
# Only handle github.com
|
|
306
|
-
if [[ "\${HOST:-}" != "github.com" ]]; then
|
|
307
|
-
log "Not handling host: \${HOST:-unknown}"
|
|
308
|
-
exit 0
|
|
309
|
-
fi
|
|
310
|
-
|
|
311
|
-
# Try cache first
|
|
312
|
-
if get_cached_token; then
|
|
313
|
-
echo "username=\$CACHED_USER"
|
|
314
|
-
echo "password=\$CACHED_TOKEN"
|
|
315
|
-
exit 0
|
|
316
|
-
fi
|
|
317
|
-
|
|
318
|
-
# Fetch fresh credentials
|
|
319
|
-
if fetch_credentials; then
|
|
320
|
-
echo "username=\$CRED_USERNAME"
|
|
321
|
-
echo "password=\$CRED_PASSWORD"
|
|
322
|
-
exit 0
|
|
323
|
-
fi
|
|
324
|
-
|
|
325
|
-
# Failed - let git try other credential helpers
|
|
326
|
-
log "Failed to get credentials, falling back to other helpers"
|
|
327
|
-
exit 0
|
|
328
|
-
;;
|
|
329
|
-
|
|
330
|
-
store|erase)
|
|
331
|
-
# We don't store or erase credentials
|
|
332
|
-
exit 0
|
|
333
|
-
;;
|
|
334
|
-
|
|
335
|
-
*)
|
|
336
|
-
# Unknown command
|
|
337
|
-
exit 0
|
|
338
|
-
;;
|
|
339
|
-
esac
|
|
340
|
-
}
|
|
341
|
-
|
|
342
|
-
main "\$@"
|
|
343
|
-
`;
|
|
344
|
-
}
|
|
345
|
-
/**
|
|
346
|
-
* Get the content of the credential helper for embedding in the CLI
|
|
347
|
-
*/
|
|
348
|
-
exports.CREDENTIAL_HELPER_SCRIPT = generateCredentialHelperScript('https://episoda.dev');
|
|
349
|
-
//# sourceMappingURL=git-credential-helper.js.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"git-credential-helper.js","sourceRoot":"","sources":["../../src/git-helpers/git-credential-helper.ts"],"names":[],"mappings":";AAAA;;;;;;;;;;;;;GAaG;;;AAWH,wEA4TC;AArUD;;;;;;;;GAQG;AACH,SAAgB,8BAA8B,CAAC,MAAc;IAC3D,0DAA0D;IAC1D,qDAAqD;IACrD,OAAO;;;;;;;;;;;;;;;;;;;;;;;;;WAyBE,MAAM;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;CA+RhB,CAAA;AACD,CAAC;AAED;;GAEG;AACU,QAAA,wBAAwB,GAAG,8BAA8B,CAAC,qBAAqB,CAAC,CAAA"}
|
package/dist/index.d.ts.map
DELETED
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":";AAEA;;;;GAIG"}
|
package/dist/ipc/ipc-client.d.ts
DELETED
|
@@ -1,116 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* IPC Client - Used by CLI commands
|
|
3
|
-
*
|
|
4
|
-
* Sends commands to daemon via Unix domain socket.
|
|
5
|
-
* Handles request/response communication.
|
|
6
|
-
*
|
|
7
|
-
* Socket location: ~/.episoda/daemon.sock
|
|
8
|
-
*/
|
|
9
|
-
export interface IPCRequest {
|
|
10
|
-
id: string;
|
|
11
|
-
command: string;
|
|
12
|
-
params?: any;
|
|
13
|
-
}
|
|
14
|
-
export interface IPCResponse {
|
|
15
|
-
id: string;
|
|
16
|
-
success: boolean;
|
|
17
|
-
data?: any;
|
|
18
|
-
error?: string;
|
|
19
|
-
}
|
|
20
|
-
/**
|
|
21
|
-
* Send command to daemon
|
|
22
|
-
*
|
|
23
|
-
* Connects to daemon socket, sends command, waits for response.
|
|
24
|
-
*
|
|
25
|
-
* @param command Command name
|
|
26
|
-
* @param params Command parameters
|
|
27
|
-
* @param timeout Timeout in milliseconds (default: 15000)
|
|
28
|
-
* @returns Response data
|
|
29
|
-
* @throws Error if daemon not running or command fails
|
|
30
|
-
*/
|
|
31
|
-
export declare function sendCommand(command: string, params?: any, timeout?: number): Promise<any>;
|
|
32
|
-
/**
|
|
33
|
-
* Check if daemon is reachable via IPC
|
|
34
|
-
*
|
|
35
|
-
* @returns true if daemon is running and responding
|
|
36
|
-
*/
|
|
37
|
-
export declare function isDaemonReachable(): Promise<boolean>;
|
|
38
|
-
/**
|
|
39
|
-
* Add project to daemon
|
|
40
|
-
*
|
|
41
|
-
* EP734: Now blocking - waits for WebSocket connection to complete
|
|
42
|
-
*
|
|
43
|
-
* @param projectId Supabase project ID
|
|
44
|
-
* @param projectPath Absolute path to project
|
|
45
|
-
* @returns Connection result with success/error info
|
|
46
|
-
*/
|
|
47
|
-
export declare function addProject(projectId: string, projectPath: string): Promise<{
|
|
48
|
-
success: boolean;
|
|
49
|
-
connected: boolean;
|
|
50
|
-
error?: string;
|
|
51
|
-
}>;
|
|
52
|
-
/**
|
|
53
|
-
* Remove project from daemon
|
|
54
|
-
*
|
|
55
|
-
* @param projectPath Absolute path to project
|
|
56
|
-
*/
|
|
57
|
-
export declare function removeProject(projectPath: string): Promise<void>;
|
|
58
|
-
/**
|
|
59
|
-
* Get daemon status
|
|
60
|
-
*
|
|
61
|
-
* EP738: Added hostname, platform, arch for status command (HTTP server removed)
|
|
62
|
-
*
|
|
63
|
-
* @returns Status information including connected projects and device info
|
|
64
|
-
*/
|
|
65
|
-
export declare function getStatus(): Promise<{
|
|
66
|
-
running: boolean;
|
|
67
|
-
machineId: string;
|
|
68
|
-
deviceId?: string;
|
|
69
|
-
hostname: string;
|
|
70
|
-
platform: string;
|
|
71
|
-
arch: string;
|
|
72
|
-
projects: Array<{
|
|
73
|
-
id: string;
|
|
74
|
-
path: string;
|
|
75
|
-
name: string;
|
|
76
|
-
connected: boolean;
|
|
77
|
-
}>;
|
|
78
|
-
}>;
|
|
79
|
-
/**
|
|
80
|
-
* Request daemon to connect to a project's WebSocket
|
|
81
|
-
*
|
|
82
|
-
* @param projectPath Absolute path to project
|
|
83
|
-
*/
|
|
84
|
-
export declare function connectProject(projectPath: string): Promise<void>;
|
|
85
|
-
/**
|
|
86
|
-
* Request daemon to disconnect from a project's WebSocket
|
|
87
|
-
*
|
|
88
|
-
* @param projectPath Absolute path to project
|
|
89
|
-
*/
|
|
90
|
-
export declare function disconnectProject(projectPath: string): Promise<void>;
|
|
91
|
-
/**
|
|
92
|
-
* Request daemon shutdown
|
|
93
|
-
*/
|
|
94
|
-
export declare function shutdownDaemon(): Promise<void>;
|
|
95
|
-
/**
|
|
96
|
-
* EP805: Verify connection health
|
|
97
|
-
*
|
|
98
|
-
* Checks if connections are actually healthy (in both connections Map and liveConnections Set).
|
|
99
|
-
* Useful for detecting stale connections where WebSocket died but entry persists.
|
|
100
|
-
*
|
|
101
|
-
* @returns Health status with per-project details
|
|
102
|
-
*/
|
|
103
|
-
export declare function verifyHealth(): Promise<{
|
|
104
|
-
totalProjects: number;
|
|
105
|
-
healthyConnections: number;
|
|
106
|
-
staleConnections: number;
|
|
107
|
-
projects: Array<{
|
|
108
|
-
id: string;
|
|
109
|
-
path: string;
|
|
110
|
-
name: string;
|
|
111
|
-
inConnectionsMap: boolean;
|
|
112
|
-
inLiveConnections: boolean;
|
|
113
|
-
isHealthy: boolean;
|
|
114
|
-
}>;
|
|
115
|
-
}>;
|
|
116
|
-
//# sourceMappingURL=ipc-client.d.ts.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"ipc-client.d.ts","sourceRoot":"","sources":["../../src/ipc/ipc-client.ts"],"names":[],"mappings":"AAAA;;;;;;;GAOG;AAUH,MAAM,WAAW,UAAU;IACzB,EAAE,EAAE,MAAM,CAAA;IACV,OAAO,EAAE,MAAM,CAAA;IACf,MAAM,CAAC,EAAE,GAAG,CAAA;CACb;AAED,MAAM,WAAW,WAAW;IAC1B,EAAE,EAAE,MAAM,CAAA;IACV,OAAO,EAAE,OAAO,CAAA;IAChB,IAAI,CAAC,EAAE,GAAG,CAAA;IACV,KAAK,CAAC,EAAE,MAAM,CAAA;CACf;AAED;;;;;;;;;;GAUG;AACH,wBAAsB,WAAW,CAC/B,OAAO,EAAE,MAAM,EACf,MAAM,CAAC,EAAE,GAAG,EACZ,OAAO,GAAE,MAAwB,GAChC,OAAO,CAAC,GAAG,CAAC,CA2Ed;AAED;;;;GAIG;AACH,wBAAsB,iBAAiB,IAAI,OAAO,CAAC,OAAO,CAAC,CAO1D;AAED;;;;;;;;GAQG;AACH,wBAAsB,UAAU,CAAC,SAAS,EAAE,MAAM,EAAE,WAAW,EAAE,MAAM,GAAG,OAAO,CAAC;IAChF,OAAO,EAAE,OAAO,CAAA;IAChB,SAAS,EAAE,OAAO,CAAA;IAClB,KAAK,CAAC,EAAE,MAAM,CAAA;CACf,CAAC,CAGD;AAED;;;;GAIG;AACH,wBAAsB,aAAa,CAAC,WAAW,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC,CAEtE;AAED;;;;;;GAMG;AACH,wBAAsB,SAAS,IAAI,OAAO,CAAC;IACzC,OAAO,EAAE,OAAO,CAAA;IAChB,SAAS,EAAE,MAAM,CAAA;IACjB,QAAQ,CAAC,EAAE,MAAM,CAAA;IACjB,QAAQ,EAAE,MAAM,CAAA;IAChB,QAAQ,EAAE,MAAM,CAAA;IAChB,IAAI,EAAE,MAAM,CAAA;IACZ,QAAQ,EAAE,KAAK,CAAC;QACd,EAAE,EAAE,MAAM,CAAA;QACV,IAAI,EAAE,MAAM,CAAA;QACZ,IAAI,EAAE,MAAM,CAAA;QACZ,SAAS,EAAE,OAAO,CAAA;KACnB,CAAC,CAAA;CACH,CAAC,CAED;AAED;;;;GAIG;AACH,wBAAsB,cAAc,CAAC,WAAW,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC,CAEvE;AAED;;;;GAIG;AACH,wBAAsB,iBAAiB,CAAC,WAAW,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC,CAE1E;AAED;;GAEG;AACH,wBAAsB,cAAc,IAAI,OAAO,CAAC,IAAI,CAAC,CAEpD;AAED;;;;;;;GAOG;AACH,wBAAsB,YAAY,IAAI,OAAO,CAAC;IAC5C,aAAa,EAAE,MAAM,CAAA;IACrB,kBAAkB,EAAE,MAAM,CAAA;IAC1B,gBAAgB,EAAE,MAAM,CAAA;IACxB,QAAQ,EAAE,KAAK,CAAC;QACd,EAAE,EAAE,MAAM,CAAA;QACV,IAAI,EAAE,MAAM,CAAA;QACZ,IAAI,EAAE,MAAM,CAAA;QACZ,gBAAgB,EAAE,OAAO,CAAA;QACzB,iBAAiB,EAAE,OAAO,CAAA;QAC1B,SAAS,EAAE,OAAO,CAAA;KACnB,CAAC,CAAA;CACH,CAAC,CAED"}
|
package/dist/ipc/ipc-client.js
DELETED
|
@@ -1,216 +0,0 @@
|
|
|
1
|
-
"use strict";
|
|
2
|
-
/**
|
|
3
|
-
* IPC Client - Used by CLI commands
|
|
4
|
-
*
|
|
5
|
-
* Sends commands to daemon via Unix domain socket.
|
|
6
|
-
* Handles request/response communication.
|
|
7
|
-
*
|
|
8
|
-
* Socket location: ~/.episoda/daemon.sock
|
|
9
|
-
*/
|
|
10
|
-
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
|
|
11
|
-
if (k2 === undefined) k2 = k;
|
|
12
|
-
var desc = Object.getOwnPropertyDescriptor(m, k);
|
|
13
|
-
if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
|
|
14
|
-
desc = { enumerable: true, get: function() { return m[k]; } };
|
|
15
|
-
}
|
|
16
|
-
Object.defineProperty(o, k2, desc);
|
|
17
|
-
}) : (function(o, m, k, k2) {
|
|
18
|
-
if (k2 === undefined) k2 = k;
|
|
19
|
-
o[k2] = m[k];
|
|
20
|
-
}));
|
|
21
|
-
var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
|
|
22
|
-
Object.defineProperty(o, "default", { enumerable: true, value: v });
|
|
23
|
-
}) : function(o, v) {
|
|
24
|
-
o["default"] = v;
|
|
25
|
-
});
|
|
26
|
-
var __importStar = (this && this.__importStar) || (function () {
|
|
27
|
-
var ownKeys = function(o) {
|
|
28
|
-
ownKeys = Object.getOwnPropertyNames || function (o) {
|
|
29
|
-
var ar = [];
|
|
30
|
-
for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
|
|
31
|
-
return ar;
|
|
32
|
-
};
|
|
33
|
-
return ownKeys(o);
|
|
34
|
-
};
|
|
35
|
-
return function (mod) {
|
|
36
|
-
if (mod && mod.__esModule) return mod;
|
|
37
|
-
var result = {};
|
|
38
|
-
if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
|
|
39
|
-
__setModuleDefault(result, mod);
|
|
40
|
-
return result;
|
|
41
|
-
};
|
|
42
|
-
})();
|
|
43
|
-
Object.defineProperty(exports, "__esModule", { value: true });
|
|
44
|
-
exports.sendCommand = sendCommand;
|
|
45
|
-
exports.isDaemonReachable = isDaemonReachable;
|
|
46
|
-
exports.addProject = addProject;
|
|
47
|
-
exports.removeProject = removeProject;
|
|
48
|
-
exports.getStatus = getStatus;
|
|
49
|
-
exports.connectProject = connectProject;
|
|
50
|
-
exports.disconnectProject = disconnectProject;
|
|
51
|
-
exports.shutdownDaemon = shutdownDaemon;
|
|
52
|
-
exports.verifyHealth = verifyHealth;
|
|
53
|
-
const net = __importStar(require("net"));
|
|
54
|
-
const path = __importStar(require("path"));
|
|
55
|
-
const crypto = __importStar(require("crypto"));
|
|
56
|
-
const core_1 = require("@episoda/core");
|
|
57
|
-
const getSocketPath = () => path.join((0, core_1.getConfigDir)(), 'daemon.sock');
|
|
58
|
-
const DEFAULT_TIMEOUT = 15000; // 15 seconds (EP606: increased for device registration)
|
|
59
|
-
/**
|
|
60
|
-
* Send command to daemon
|
|
61
|
-
*
|
|
62
|
-
* Connects to daemon socket, sends command, waits for response.
|
|
63
|
-
*
|
|
64
|
-
* @param command Command name
|
|
65
|
-
* @param params Command parameters
|
|
66
|
-
* @param timeout Timeout in milliseconds (default: 15000)
|
|
67
|
-
* @returns Response data
|
|
68
|
-
* @throws Error if daemon not running or command fails
|
|
69
|
-
*/
|
|
70
|
-
async function sendCommand(command, params, timeout = DEFAULT_TIMEOUT) {
|
|
71
|
-
return new Promise((resolve, reject) => {
|
|
72
|
-
const socket = net.createConnection(getSocketPath());
|
|
73
|
-
const requestId = crypto.randomUUID();
|
|
74
|
-
let buffer = '';
|
|
75
|
-
let timeoutHandle;
|
|
76
|
-
// Set timeout
|
|
77
|
-
timeoutHandle = setTimeout(() => {
|
|
78
|
-
socket.destroy();
|
|
79
|
-
reject(new Error(`Command timed out after ${timeout}ms`));
|
|
80
|
-
}, timeout);
|
|
81
|
-
socket.on('connect', () => {
|
|
82
|
-
// Send request
|
|
83
|
-
const request = {
|
|
84
|
-
id: requestId,
|
|
85
|
-
command,
|
|
86
|
-
params,
|
|
87
|
-
};
|
|
88
|
-
socket.write(JSON.stringify(request) + '\n');
|
|
89
|
-
});
|
|
90
|
-
socket.on('data', (chunk) => {
|
|
91
|
-
buffer += chunk.toString();
|
|
92
|
-
// Check for complete response (delimited by newline)
|
|
93
|
-
const newlineIndex = buffer.indexOf('\n');
|
|
94
|
-
if (newlineIndex === -1)
|
|
95
|
-
return;
|
|
96
|
-
// Extract response
|
|
97
|
-
const message = buffer.slice(0, newlineIndex);
|
|
98
|
-
try {
|
|
99
|
-
const response = JSON.parse(message);
|
|
100
|
-
// Verify response ID matches
|
|
101
|
-
if (response.id !== requestId) {
|
|
102
|
-
reject(new Error('Response ID mismatch'));
|
|
103
|
-
return;
|
|
104
|
-
}
|
|
105
|
-
clearTimeout(timeoutHandle);
|
|
106
|
-
socket.end();
|
|
107
|
-
if (response.success) {
|
|
108
|
-
resolve(response.data);
|
|
109
|
-
}
|
|
110
|
-
else {
|
|
111
|
-
reject(new Error(response.error || 'Command failed'));
|
|
112
|
-
}
|
|
113
|
-
}
|
|
114
|
-
catch (error) {
|
|
115
|
-
clearTimeout(timeoutHandle);
|
|
116
|
-
socket.end();
|
|
117
|
-
reject(new Error('Invalid response from daemon'));
|
|
118
|
-
}
|
|
119
|
-
});
|
|
120
|
-
socket.on('error', (error) => {
|
|
121
|
-
clearTimeout(timeoutHandle);
|
|
122
|
-
// Check for common errors
|
|
123
|
-
if (error.code === 'ENOENT' || error.code === 'ECONNREFUSED') {
|
|
124
|
-
reject(new Error('Daemon is not running. Start it with: episoda dev'));
|
|
125
|
-
}
|
|
126
|
-
else {
|
|
127
|
-
reject(error);
|
|
128
|
-
}
|
|
129
|
-
});
|
|
130
|
-
socket.on('timeout', () => {
|
|
131
|
-
clearTimeout(timeoutHandle);
|
|
132
|
-
socket.destroy();
|
|
133
|
-
reject(new Error('Connection timeout'));
|
|
134
|
-
});
|
|
135
|
-
});
|
|
136
|
-
}
|
|
137
|
-
/**
|
|
138
|
-
* Check if daemon is reachable via IPC
|
|
139
|
-
*
|
|
140
|
-
* @returns true if daemon is running and responding
|
|
141
|
-
*/
|
|
142
|
-
async function isDaemonReachable() {
|
|
143
|
-
try {
|
|
144
|
-
await sendCommand('ping', {}, 1000);
|
|
145
|
-
return true;
|
|
146
|
-
}
|
|
147
|
-
catch (error) {
|
|
148
|
-
return false;
|
|
149
|
-
}
|
|
150
|
-
}
|
|
151
|
-
/**
|
|
152
|
-
* Add project to daemon
|
|
153
|
-
*
|
|
154
|
-
* EP734: Now blocking - waits for WebSocket connection to complete
|
|
155
|
-
*
|
|
156
|
-
* @param projectId Supabase project ID
|
|
157
|
-
* @param projectPath Absolute path to project
|
|
158
|
-
* @returns Connection result with success/error info
|
|
159
|
-
*/
|
|
160
|
-
async function addProject(projectId, projectPath) {
|
|
161
|
-
// EP734: Increased timeout to 30s to allow for WebSocket connection
|
|
162
|
-
return await sendCommand('add-project', { projectId, projectPath }, 30000);
|
|
163
|
-
}
|
|
164
|
-
/**
|
|
165
|
-
* Remove project from daemon
|
|
166
|
-
*
|
|
167
|
-
* @param projectPath Absolute path to project
|
|
168
|
-
*/
|
|
169
|
-
async function removeProject(projectPath) {
|
|
170
|
-
await sendCommand('remove-project', { projectPath });
|
|
171
|
-
}
|
|
172
|
-
/**
|
|
173
|
-
* Get daemon status
|
|
174
|
-
*
|
|
175
|
-
* EP738: Added hostname, platform, arch for status command (HTTP server removed)
|
|
176
|
-
*
|
|
177
|
-
* @returns Status information including connected projects and device info
|
|
178
|
-
*/
|
|
179
|
-
async function getStatus() {
|
|
180
|
-
return await sendCommand('status');
|
|
181
|
-
}
|
|
182
|
-
/**
|
|
183
|
-
* Request daemon to connect to a project's WebSocket
|
|
184
|
-
*
|
|
185
|
-
* @param projectPath Absolute path to project
|
|
186
|
-
*/
|
|
187
|
-
async function connectProject(projectPath) {
|
|
188
|
-
await sendCommand('connect-project', { projectPath });
|
|
189
|
-
}
|
|
190
|
-
/**
|
|
191
|
-
* Request daemon to disconnect from a project's WebSocket
|
|
192
|
-
*
|
|
193
|
-
* @param projectPath Absolute path to project
|
|
194
|
-
*/
|
|
195
|
-
async function disconnectProject(projectPath) {
|
|
196
|
-
await sendCommand('disconnect-project', { projectPath });
|
|
197
|
-
}
|
|
198
|
-
/**
|
|
199
|
-
* Request daemon shutdown
|
|
200
|
-
*/
|
|
201
|
-
async function shutdownDaemon() {
|
|
202
|
-
await sendCommand('shutdown', {}, 2000);
|
|
203
|
-
}
|
|
204
|
-
/**
|
|
205
|
-
* EP805: Verify connection health
|
|
206
|
-
*
|
|
207
|
-
* Checks if connections are actually healthy (in both connections Map and liveConnections Set).
|
|
208
|
-
* Useful for detecting stale connections where WebSocket died but entry persists.
|
|
209
|
-
*
|
|
210
|
-
* @returns Health status with per-project details
|
|
211
|
-
*/
|
|
212
|
-
async function verifyHealth() {
|
|
213
|
-
return await sendCommand('verify-health');
|
|
214
|
-
}
|
|
215
|
-
// EP734: Removed getConnectionStatus - no longer needed with blocking add-project
|
|
216
|
-
//# sourceMappingURL=ipc-client.js.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"ipc-client.js","sourceRoot":"","sources":["../../src/ipc/ipc-client.ts"],"names":[],"mappings":"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"}
|