teleportation-cli 1.1.4 → 1.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/.claude/hooks/config-loader.mjs +88 -34
- package/.claude/hooks/permission_request.mjs +392 -82
- package/.claude/hooks/post_tool_use.mjs +90 -0
- package/.claude/hooks/pre_tool_use.mjs +247 -305
- package/.claude/hooks/session-register.mjs +94 -105
- package/.claude/hooks/session_end.mjs +41 -42
- package/.claude/hooks/session_start.mjs +45 -60
- package/.claude/hooks/stop.mjs +752 -99
- package/.claude/hooks/user_prompt_submit.mjs +26 -3
- package/README.md +7 -0
- package/lib/auth/api-key.js +12 -0
- package/lib/auth/token-refresh.js +286 -0
- package/lib/cli/daemon-commands.js +1 -1
- package/lib/cli/teleport-commands.js +469 -0
- package/lib/daemon/daemon-v2.js +104 -0
- package/lib/daemon/lifecycle.js +56 -171
- package/lib/daemon/response-classifier.js +15 -1
- package/lib/daemon/services/index.js +3 -0
- package/lib/daemon/services/polling-service.js +173 -0
- package/lib/daemon/services/queue-service.js +318 -0
- package/lib/daemon/services/session-service.js +115 -0
- package/lib/daemon/state.js +35 -0
- package/lib/daemon/task-executor-v2.js +413 -0
- package/lib/daemon/task-executor.js +1235 -0
- package/lib/daemon/teleportation-daemon.js +770 -25
- package/lib/daemon/timeline-analyzer.js +215 -0
- package/lib/daemon/transcript-ingestion.js +696 -0
- package/lib/daemon/utils.js +91 -0
- package/lib/install/installer.js +184 -20
- package/lib/install/uhr-installer.js +136 -0
- package/lib/remote/providers/base-provider.js +46 -0
- package/lib/remote/providers/daytona-provider.js +58 -0
- package/lib/remote/providers/provider-factory.js +90 -19
- package/lib/remote/providers/sprites-provider.js +711 -0
- package/lib/teleport/exporters/claude-exporter.js +302 -0
- package/lib/teleport/exporters/gemini-exporter.js +307 -0
- package/lib/teleport/exporters/index.js +93 -0
- package/lib/teleport/exporters/interface.js +153 -0
- package/lib/teleport/fork-tracker.js +415 -0
- package/lib/teleport/git-committer.js +337 -0
- package/lib/teleport/index.js +48 -0
- package/lib/teleport/manager.js +620 -0
- package/lib/teleport/session-capture.js +282 -0
- package/package.json +11 -5
- package/teleportation-cli.cjs +632 -451
- package/.claude/hooks/heartbeat.mjs +0 -396
- package/lib/daemon/agentic-executor.js +0 -803
- package/lib/daemon/pid-manager.js +0 -160
|
@@ -15,6 +15,56 @@
|
|
|
15
15
|
|
|
16
16
|
import { stdin, stdout, exit, env } from 'node:process';
|
|
17
17
|
import { appendFileSync } from 'node:fs';
|
|
18
|
+
import { homedir } from 'node:os';
|
|
19
|
+
import { join, dirname } from 'node:path';
|
|
20
|
+
import { fileURLToPath } from 'node:url';
|
|
21
|
+
|
|
22
|
+
// Get __dirname equivalent for ES modules
|
|
23
|
+
const __filename = fileURLToPath(import.meta.url);
|
|
24
|
+
const __dirname = dirname(__filename);
|
|
25
|
+
|
|
26
|
+
/**
|
|
27
|
+
* Try to import transcript-ingestion from multiple possible paths
|
|
28
|
+
* This makes the hook work in both development and installed contexts
|
|
29
|
+
*
|
|
30
|
+
* IMPORTANT: Only catches module-not-found errors. Syntax errors, runtime
|
|
31
|
+
* errors, and other exceptions are re-thrown immediately for debugging.
|
|
32
|
+
*/
|
|
33
|
+
async function tryImportTranscriptIngestion() {
|
|
34
|
+
const possiblePaths = [
|
|
35
|
+
// If installed globally to ~/.claude/hooks/, lib is in ~/.teleportation/lib/daemon/
|
|
36
|
+
() => join(homedir(), '.teleportation', 'lib', 'daemon', 'transcript-ingestion.js'),
|
|
37
|
+
// If hook is still in project directory
|
|
38
|
+
() => join(process.cwd(), 'lib', 'daemon', 'transcript-ingestion.js'),
|
|
39
|
+
// Try relative to hook location (development)
|
|
40
|
+
() => join(__dirname, '..', '..', 'lib', 'daemon', 'transcript-ingestion.js')
|
|
41
|
+
];
|
|
42
|
+
|
|
43
|
+
let lastError;
|
|
44
|
+
|
|
45
|
+
for (const getPath of possiblePaths) {
|
|
46
|
+
const modulePath = getPath();
|
|
47
|
+
try {
|
|
48
|
+
const module = await import(modulePath);
|
|
49
|
+
return module;
|
|
50
|
+
} catch (e) {
|
|
51
|
+
lastError = e;
|
|
52
|
+
|
|
53
|
+
// Only skip module-not-found errors - try next path
|
|
54
|
+
// Re-throw syntax errors, runtime errors, reference errors immediately
|
|
55
|
+
if (e.code === 'ERR_MODULE_NOT_FOUND' || e.code === 'ENOENT') {
|
|
56
|
+
continue; // Module doesn't exist at this path, try next
|
|
57
|
+
}
|
|
58
|
+
|
|
59
|
+
// Syntax error, runtime error, etc. - throw immediately with context
|
|
60
|
+
console.error(`[post_tool_use] Failed to import transcript-ingestion from ${modulePath}:`, e.message);
|
|
61
|
+
throw e;
|
|
62
|
+
}
|
|
63
|
+
}
|
|
64
|
+
|
|
65
|
+
// If we get here, module wasn't found in any location
|
|
66
|
+
throw new Error(`Could not find transcript-ingestion module in any expected location. Last error: ${lastError?.message || 'unknown'}`);
|
|
67
|
+
}
|
|
18
68
|
|
|
19
69
|
const readStdin = () => new Promise((resolve, reject) => {
|
|
20
70
|
let data = '';
|
|
@@ -207,6 +257,10 @@ function buildErrorMessage(tool_output) {
|
|
|
207
257
|
const { session_id, tool_name, tool_input, tool_output, tool_use_id } = input || {};
|
|
208
258
|
log(`Session: ${session_id}, Tool: ${tool_name}, tool_use_id: ${tool_use_id || 'none'}`);
|
|
209
259
|
|
|
260
|
+
// Detect message source
|
|
261
|
+
const isAutonomousTask = env.TELEPORTATION_TASK_MODE === 'true' || !!env.TELEPORTATION_PARENT_SESSION_ID;
|
|
262
|
+
const source = isAutonomousTask ? 'autonomous_task' : 'cli_interactive';
|
|
263
|
+
|
|
210
264
|
// Validate session_id
|
|
211
265
|
if (!isValidSessionId(session_id)) {
|
|
212
266
|
log(`ERROR: Invalid session_id format: ${session_id}`);
|
|
@@ -339,6 +393,7 @@ function buildErrorMessage(tool_output) {
|
|
|
339
393
|
body: JSON.stringify({
|
|
340
394
|
session_id,
|
|
341
395
|
type: completionEventType,
|
|
396
|
+
source,
|
|
342
397
|
data: completionEventData
|
|
343
398
|
})
|
|
344
399
|
});
|
|
@@ -362,6 +417,7 @@ function buildErrorMessage(tool_output) {
|
|
|
362
417
|
body: JSON.stringify({
|
|
363
418
|
session_id,
|
|
364
419
|
type: 'tool_error',
|
|
420
|
+
source,
|
|
365
421
|
data: {
|
|
366
422
|
tool_name,
|
|
367
423
|
tool_input,
|
|
@@ -387,6 +443,7 @@ function buildErrorMessage(tool_output) {
|
|
|
387
443
|
body: JSON.stringify({
|
|
388
444
|
session_id,
|
|
389
445
|
type: 'tool_executed',
|
|
446
|
+
source,
|
|
390
447
|
data: {
|
|
391
448
|
tool_name,
|
|
392
449
|
tool_input,
|
|
@@ -401,6 +458,39 @@ function buildErrorMessage(tool_output) {
|
|
|
401
458
|
log(`Failed to record legacy tool_executed: ${e.message}`);
|
|
402
459
|
}
|
|
403
460
|
|
|
461
|
+
// =========================================================================
|
|
462
|
+
// Real-time transcript ingestion after each tool execution
|
|
463
|
+
// Ensures timeline stays in sync with assistant responses
|
|
464
|
+
// =========================================================================
|
|
465
|
+
|
|
466
|
+
try {
|
|
467
|
+
// Import transcript ingestion from multiple possible locations (works in dev + installed contexts)
|
|
468
|
+
const transcriptModule = await tryImportTranscriptIngestion();
|
|
469
|
+
const { ingestTranscriptToTimeline } = transcriptModule;
|
|
470
|
+
|
|
471
|
+
const claude_session_id = env.CLAUDE_SESSION_ID || session_id;
|
|
472
|
+
const cwd = env.TELEPORTATION_CWD || process.cwd();
|
|
473
|
+
|
|
474
|
+
// Use real-time mode flag to only process recent events (max 10)
|
|
475
|
+
await ingestTranscriptToTimeline({
|
|
476
|
+
claude_session_id,
|
|
477
|
+
parent_session_id: session_id,
|
|
478
|
+
task_id: null,
|
|
479
|
+
cwd,
|
|
480
|
+
config: {
|
|
481
|
+
relayApiUrl: RELAY_API_URL,
|
|
482
|
+
apiKey: RELAY_API_KEY
|
|
483
|
+
},
|
|
484
|
+
realTimeMode: true, // Fast mode - only recent events
|
|
485
|
+
maxEvents: 10 // Limit to 10 most recent events (prevents blocking hook)
|
|
486
|
+
});
|
|
487
|
+
|
|
488
|
+
log(`Real-time transcript ingestion completed`);
|
|
489
|
+
} catch (e) {
|
|
490
|
+
log(`Real-time transcript ingestion failed (non-fatal): ${e.message}`);
|
|
491
|
+
// Don't fail the hook if ingestion fails - this is a best-effort feature
|
|
492
|
+
}
|
|
493
|
+
|
|
404
494
|
// PostToolUse hooks don't need to output anything
|
|
405
495
|
return exit(0);
|
|
406
496
|
})();
|