@kraki/tentacle 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.
- package/LICENSE +21 -0
- package/dist/adapters/base.d.ts +107 -0
- package/dist/adapters/base.js +32 -0
- package/dist/adapters/base.js.map +1 -0
- package/dist/adapters/copilot.d.ts +57 -0
- package/dist/adapters/copilot.js +489 -0
- package/dist/adapters/copilot.js.map +1 -0
- package/dist/adapters/index.d.ts +5 -0
- package/dist/adapters/index.js +4 -0
- package/dist/adapters/index.js.map +1 -0
- package/dist/banner-data.json +1 -0
- package/dist/banner.d.ts +7 -0
- package/dist/banner.js +187 -0
- package/dist/banner.js.map +1 -0
- package/dist/checks.d.ts +26 -0
- package/dist/checks.js +74 -0
- package/dist/checks.js.map +1 -0
- package/dist/cli.d.ts +15 -0
- package/dist/cli.js +306 -0
- package/dist/cli.js.map +1 -0
- package/dist/config.d.ts +38 -0
- package/dist/config.js +113 -0
- package/dist/config.js.map +1 -0
- package/dist/daemon-worker.d.ts +21 -0
- package/dist/daemon-worker.js +127 -0
- package/dist/daemon-worker.js.map +1 -0
- package/dist/daemon.d.ts +24 -0
- package/dist/daemon.js +163 -0
- package/dist/daemon.js.map +1 -0
- package/dist/index.d.ts +8 -0
- package/dist/index.js +11 -0
- package/dist/index.js.map +1 -0
- package/dist/key-manager.d.ts +28 -0
- package/dist/key-manager.js +61 -0
- package/dist/key-manager.js.map +1 -0
- package/dist/logger.d.ts +8 -0
- package/dist/logger.js +30 -0
- package/dist/logger.js.map +1 -0
- package/dist/pair.d.ts +32 -0
- package/dist/pair.js +131 -0
- package/dist/pair.js.map +1 -0
- package/dist/parse-permission.d.ts +25 -0
- package/dist/parse-permission.js +67 -0
- package/dist/parse-permission.js.map +1 -0
- package/dist/relay-client.d.ts +90 -0
- package/dist/relay-client.js +525 -0
- package/dist/relay-client.js.map +1 -0
- package/dist/session-manager.d.ts +85 -0
- package/dist/session-manager.js +218 -0
- package/dist/session-manager.js.map +1 -0
- package/dist/setup.d.ts +13 -0
- package/dist/setup.js +234 -0
- package/dist/setup.js.map +1 -0
- package/package.json +48 -0
|
@@ -0,0 +1,218 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Tentacle session manager.
|
|
3
|
+
*
|
|
4
|
+
* Owns session lifecycle: create, resume, crash recovery, context persistence.
|
|
5
|
+
* The head doesn't know about runs or context — it just sees sessionIds.
|
|
6
|
+
* This is the tentacle's local intelligence layer.
|
|
7
|
+
*/
|
|
8
|
+
import { mkdirSync, readFileSync, writeFileSync, existsSync, readdirSync, renameSync } from 'node:fs';
|
|
9
|
+
import { join } from 'node:path';
|
|
10
|
+
import { randomUUID } from 'node:crypto';
|
|
11
|
+
import { getConfigDir } from './config.js';
|
|
12
|
+
// ── Session Manager ─────────────────────────────────────
|
|
13
|
+
export class SessionManager {
|
|
14
|
+
sessionsDir;
|
|
15
|
+
constructor(sessionsDir) {
|
|
16
|
+
this.sessionsDir = sessionsDir ?? join(getConfigDir(), 'sessions');
|
|
17
|
+
mkdirSync(this.sessionsDir, { recursive: true });
|
|
18
|
+
}
|
|
19
|
+
/**
|
|
20
|
+
* Create a new session. Returns the session ID.
|
|
21
|
+
*/
|
|
22
|
+
createSession(agent, model, sessionId) {
|
|
23
|
+
const id = sessionId ?? `sess_${randomUUID().slice(0, 12)}`;
|
|
24
|
+
const runId = 'run_001';
|
|
25
|
+
const sessionDir = this.sessionDir(id);
|
|
26
|
+
mkdirSync(join(sessionDir, 'runs'), { recursive: true });
|
|
27
|
+
const meta = {
|
|
28
|
+
id,
|
|
29
|
+
agent,
|
|
30
|
+
model,
|
|
31
|
+
state: 'active',
|
|
32
|
+
currentRunId: runId,
|
|
33
|
+
totalRuns: 1,
|
|
34
|
+
createdAt: new Date().toISOString(),
|
|
35
|
+
updatedAt: new Date().toISOString(),
|
|
36
|
+
};
|
|
37
|
+
const run = {
|
|
38
|
+
id: runId,
|
|
39
|
+
startedAt: new Date().toISOString(),
|
|
40
|
+
};
|
|
41
|
+
this.writeMeta(id, meta);
|
|
42
|
+
this.writeRun(id, run);
|
|
43
|
+
this.writeContext(id, {
|
|
44
|
+
summary: '',
|
|
45
|
+
keyFiles: [],
|
|
46
|
+
lastUserMessage: '',
|
|
47
|
+
updatedAt: new Date().toISOString(),
|
|
48
|
+
});
|
|
49
|
+
return { sessionId: id, runId };
|
|
50
|
+
}
|
|
51
|
+
/**
|
|
52
|
+
* Resume a session after crash/restart. Creates a new run.
|
|
53
|
+
* Returns context for the agent to recover.
|
|
54
|
+
*/
|
|
55
|
+
resumeSession(sessionId) {
|
|
56
|
+
const meta = this.readMeta(sessionId);
|
|
57
|
+
if (!meta)
|
|
58
|
+
return null;
|
|
59
|
+
const context = this.readContext(sessionId) ?? {
|
|
60
|
+
summary: '',
|
|
61
|
+
keyFiles: [],
|
|
62
|
+
lastUserMessage: '',
|
|
63
|
+
updatedAt: new Date().toISOString(),
|
|
64
|
+
};
|
|
65
|
+
const runNum = meta.totalRuns + 1;
|
|
66
|
+
const runId = `run_${String(runNum).padStart(3, '0')}`;
|
|
67
|
+
// End previous run
|
|
68
|
+
const prevRun = this.readRun(sessionId, meta.currentRunId);
|
|
69
|
+
if (prevRun && !prevRun.endedAt) {
|
|
70
|
+
prevRun.endedAt = new Date().toISOString();
|
|
71
|
+
prevRun.endReason = 'crashed';
|
|
72
|
+
this.writeRun(sessionId, prevRun);
|
|
73
|
+
}
|
|
74
|
+
// Start new run
|
|
75
|
+
const newRun = {
|
|
76
|
+
id: runId,
|
|
77
|
+
startedAt: new Date().toISOString(),
|
|
78
|
+
};
|
|
79
|
+
this.writeRun(sessionId, newRun);
|
|
80
|
+
// Update meta
|
|
81
|
+
meta.state = 'active';
|
|
82
|
+
meta.currentRunId = runId;
|
|
83
|
+
meta.totalRuns = runNum;
|
|
84
|
+
meta.updatedAt = new Date().toISOString();
|
|
85
|
+
this.writeMeta(sessionId, meta);
|
|
86
|
+
return { runId, context };
|
|
87
|
+
}
|
|
88
|
+
/**
|
|
89
|
+
* Mark a session as ended normally.
|
|
90
|
+
*/
|
|
91
|
+
endSession(sessionId, reason) {
|
|
92
|
+
const meta = this.readMeta(sessionId);
|
|
93
|
+
if (!meta)
|
|
94
|
+
return;
|
|
95
|
+
meta.state = 'ended';
|
|
96
|
+
meta.updatedAt = new Date().toISOString();
|
|
97
|
+
this.writeMeta(sessionId, meta);
|
|
98
|
+
const run = this.readRun(sessionId, meta.currentRunId);
|
|
99
|
+
if (run && !run.endedAt) {
|
|
100
|
+
run.endedAt = new Date().toISOString();
|
|
101
|
+
run.endReason = reason;
|
|
102
|
+
this.writeRun(sessionId, run);
|
|
103
|
+
}
|
|
104
|
+
}
|
|
105
|
+
/**
|
|
106
|
+
* Mark a session as disconnected (agent process died unexpectedly).
|
|
107
|
+
*/
|
|
108
|
+
markDisconnected(sessionId) {
|
|
109
|
+
const meta = this.readMeta(sessionId);
|
|
110
|
+
if (!meta)
|
|
111
|
+
return;
|
|
112
|
+
meta.state = 'disconnected';
|
|
113
|
+
meta.updatedAt = new Date().toISOString();
|
|
114
|
+
this.writeMeta(sessionId, meta);
|
|
115
|
+
}
|
|
116
|
+
/**
|
|
117
|
+
* Update session context (rolling summary for recovery).
|
|
118
|
+
*/
|
|
119
|
+
updateContext(sessionId, context) {
|
|
120
|
+
const meta = this.readMeta(sessionId);
|
|
121
|
+
if (!meta)
|
|
122
|
+
return; // Session doesn't exist — no-op
|
|
123
|
+
const existing = this.readContext(sessionId) ?? {
|
|
124
|
+
summary: '',
|
|
125
|
+
keyFiles: [],
|
|
126
|
+
lastUserMessage: '',
|
|
127
|
+
updatedAt: new Date().toISOString(),
|
|
128
|
+
};
|
|
129
|
+
const updated = {
|
|
130
|
+
...existing,
|
|
131
|
+
...context,
|
|
132
|
+
updatedAt: new Date().toISOString(),
|
|
133
|
+
};
|
|
134
|
+
this.writeContext(sessionId, updated);
|
|
135
|
+
}
|
|
136
|
+
/**
|
|
137
|
+
* Update session title (e.g., auto-generated by agent).
|
|
138
|
+
*/
|
|
139
|
+
setTitle(sessionId, title) {
|
|
140
|
+
const meta = this.readMeta(sessionId);
|
|
141
|
+
if (!meta)
|
|
142
|
+
return;
|
|
143
|
+
meta.title = title;
|
|
144
|
+
meta.updatedAt = new Date().toISOString();
|
|
145
|
+
this.writeMeta(sessionId, meta);
|
|
146
|
+
}
|
|
147
|
+
/**
|
|
148
|
+
* Get all sessions that were active/disconnected (need resume on restart).
|
|
149
|
+
*/
|
|
150
|
+
getResumableSessions() {
|
|
151
|
+
const sessions = [];
|
|
152
|
+
if (!existsSync(this.sessionsDir))
|
|
153
|
+
return sessions;
|
|
154
|
+
for (const dir of readdirSync(this.sessionsDir)) {
|
|
155
|
+
const meta = this.readMeta(dir);
|
|
156
|
+
if (meta && (meta.state === 'active' || meta.state === 'disconnected')) {
|
|
157
|
+
sessions.push(meta);
|
|
158
|
+
}
|
|
159
|
+
}
|
|
160
|
+
return sessions;
|
|
161
|
+
}
|
|
162
|
+
/**
|
|
163
|
+
* Get session context for a session.
|
|
164
|
+
*/
|
|
165
|
+
getContext(sessionId) {
|
|
166
|
+
return this.readContext(sessionId);
|
|
167
|
+
}
|
|
168
|
+
/**
|
|
169
|
+
* Get session metadata.
|
|
170
|
+
*/
|
|
171
|
+
getMeta(sessionId) {
|
|
172
|
+
return this.readMeta(sessionId);
|
|
173
|
+
}
|
|
174
|
+
// ── File I/O ──────────────────────────────────────────
|
|
175
|
+
sessionDir(sessionId) {
|
|
176
|
+
return join(this.sessionsDir, sessionId);
|
|
177
|
+
}
|
|
178
|
+
readMeta(sessionId) {
|
|
179
|
+
try {
|
|
180
|
+
return JSON.parse(readFileSync(join(this.sessionDir(sessionId), 'meta.json'), 'utf8'));
|
|
181
|
+
}
|
|
182
|
+
catch {
|
|
183
|
+
return null;
|
|
184
|
+
}
|
|
185
|
+
}
|
|
186
|
+
writeMeta(sessionId, meta) {
|
|
187
|
+
atomicWrite(join(this.sessionDir(sessionId), 'meta.json'), JSON.stringify(meta, null, 2));
|
|
188
|
+
}
|
|
189
|
+
readContext(sessionId) {
|
|
190
|
+
try {
|
|
191
|
+
return JSON.parse(readFileSync(join(this.sessionDir(sessionId), 'context.json'), 'utf8'));
|
|
192
|
+
}
|
|
193
|
+
catch {
|
|
194
|
+
return null;
|
|
195
|
+
}
|
|
196
|
+
}
|
|
197
|
+
writeContext(sessionId, context) {
|
|
198
|
+
atomicWrite(join(this.sessionDir(sessionId), 'context.json'), JSON.stringify(context, null, 2));
|
|
199
|
+
}
|
|
200
|
+
readRun(sessionId, runId) {
|
|
201
|
+
try {
|
|
202
|
+
return JSON.parse(readFileSync(join(this.sessionDir(sessionId), 'runs', `${runId}.json`), 'utf8'));
|
|
203
|
+
}
|
|
204
|
+
catch {
|
|
205
|
+
return null;
|
|
206
|
+
}
|
|
207
|
+
}
|
|
208
|
+
writeRun(sessionId, run) {
|
|
209
|
+
atomicWrite(join(this.sessionDir(sessionId), 'runs', `${run.id}.json`), JSON.stringify(run, null, 2));
|
|
210
|
+
}
|
|
211
|
+
}
|
|
212
|
+
/** Atomic write: write to temp file, then rename (prevents corruption on crash). */
|
|
213
|
+
function atomicWrite(path, data) {
|
|
214
|
+
const tmp = path + '.tmp';
|
|
215
|
+
writeFileSync(tmp, data);
|
|
216
|
+
renameSync(tmp, path);
|
|
217
|
+
}
|
|
218
|
+
//# sourceMappingURL=session-manager.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"session-manager.js","sourceRoot":"","sources":["../src/session-manager.ts"],"names":[],"mappings":"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"}
|
package/dist/setup.d.ts
ADDED
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Interactive first-time setup for Kraki tentacle.
|
|
3
|
+
*
|
|
4
|
+
* Guides the user through relay selection, authentication,
|
|
5
|
+
* device naming, and agent verification.
|
|
6
|
+
*/
|
|
7
|
+
import { type KrakiConfig } from './config.js';
|
|
8
|
+
export declare function runSetup(): Promise<KrakiConfig>;
|
|
9
|
+
/**
|
|
10
|
+
* Generate and display pairing QR code.
|
|
11
|
+
* Called by CLI after daemon is started.
|
|
12
|
+
*/
|
|
13
|
+
export declare function showPairingQr(config: KrakiConfig): Promise<void>;
|
package/dist/setup.js
ADDED
|
@@ -0,0 +1,234 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Interactive first-time setup for Kraki tentacle.
|
|
3
|
+
*
|
|
4
|
+
* Guides the user through relay selection, authentication,
|
|
5
|
+
* device naming, and agent verification.
|
|
6
|
+
*/
|
|
7
|
+
import { select, input } from '@inquirer/prompts';
|
|
8
|
+
import chalk from 'chalk';
|
|
9
|
+
import ora from 'ora';
|
|
10
|
+
import { hostname } from 'node:os';
|
|
11
|
+
import { WebSocket } from 'ws';
|
|
12
|
+
import { DEFAULT_LOG_VERBOSITY, saveConfig, saveChannelKey, getOrCreateDeviceId, } from './config.js';
|
|
13
|
+
import { checkGhAuth, checkCopilotCli, withRetry } from './checks.js';
|
|
14
|
+
import { printAnimatedBanner } from './banner.js';
|
|
15
|
+
const OFFICIAL_RELAY = 'wss://kraki.corelli.cloud';
|
|
16
|
+
function getBrand(s) { return chalk.hex('#ea6046')(s); }
|
|
17
|
+
const icon = '◈';
|
|
18
|
+
function step(n, total) { return chalk.dim(`[${n}/${total}]`); }
|
|
19
|
+
function divider() { console.log(chalk.dim(' ─────────────────────────────────')); }
|
|
20
|
+
// Align inquirer prefix (✔/?) with ora spinners (4-space indent)
|
|
21
|
+
const promptTheme = {
|
|
22
|
+
prefix: { idle: chalk.blue(' ?'), done: chalk.green(' ✔') },
|
|
23
|
+
icon: { cursor: ' ❯' },
|
|
24
|
+
};
|
|
25
|
+
// Terminal hyperlink (OSC 8)
|
|
26
|
+
function link(text, url) {
|
|
27
|
+
return `\u001b]8;;${url}\u0007${text}\u001b]8;;\u0007`;
|
|
28
|
+
}
|
|
29
|
+
/**
|
|
30
|
+
* Connect to the relay, query auth_info, and return server capabilities.
|
|
31
|
+
*/
|
|
32
|
+
function queryRelayInfo(url, timeoutMs = 5000) {
|
|
33
|
+
return new Promise((resolve, reject) => {
|
|
34
|
+
const timer = setTimeout(() => {
|
|
35
|
+
ws.close();
|
|
36
|
+
reject(new Error('Connection timed out'));
|
|
37
|
+
}, timeoutMs);
|
|
38
|
+
const ws = new WebSocket(url);
|
|
39
|
+
ws.on('open', () => {
|
|
40
|
+
ws.send(JSON.stringify({ type: 'auth_info' }));
|
|
41
|
+
});
|
|
42
|
+
ws.on('message', (data) => {
|
|
43
|
+
try {
|
|
44
|
+
const msg = JSON.parse(data.toString());
|
|
45
|
+
if (msg.type === 'auth_info_response') {
|
|
46
|
+
clearTimeout(timer);
|
|
47
|
+
ws.close();
|
|
48
|
+
resolve({
|
|
49
|
+
authModes: msg.authModes ?? ['open'],
|
|
50
|
+
e2e: msg.e2e ?? false,
|
|
51
|
+
pairing: msg.pairing ?? true,
|
|
52
|
+
});
|
|
53
|
+
}
|
|
54
|
+
}
|
|
55
|
+
catch { /* ignore non-JSON */ }
|
|
56
|
+
});
|
|
57
|
+
ws.on('error', (err) => {
|
|
58
|
+
clearTimeout(timer);
|
|
59
|
+
reject(new Error(err.message || 'Connection failed'));
|
|
60
|
+
});
|
|
61
|
+
});
|
|
62
|
+
}
|
|
63
|
+
// ── Box drawing ─────────────────────────────────────────
|
|
64
|
+
function printBox(lines) {
|
|
65
|
+
const plain = (s) => s.replace(/\x1B\[[0-9;]*m/g, '');
|
|
66
|
+
const maxLen = Math.max(...lines.map((l) => plain(l).length));
|
|
67
|
+
const pad = (s) => s + ' '.repeat(maxLen - plain(s).length);
|
|
68
|
+
const border = chalk.dim;
|
|
69
|
+
console.log(border(` ┌${'─'.repeat(maxLen + 2)}┐`));
|
|
70
|
+
for (const line of lines) {
|
|
71
|
+
console.log(border(' │ ') + pad(line) + border(' │'));
|
|
72
|
+
}
|
|
73
|
+
console.log(border(` └${'─'.repeat(maxLen + 2)}┘`));
|
|
74
|
+
}
|
|
75
|
+
// ── Setup flow ──────────────────────────────────────────
|
|
76
|
+
export async function runSetup() {
|
|
77
|
+
await printAnimatedBanner();
|
|
78
|
+
const total = 4;
|
|
79
|
+
// 1. Relay URL (with retry loop)
|
|
80
|
+
let relay = OFFICIAL_RELAY;
|
|
81
|
+
let relayInfo = { authModes: ['open'], e2e: false, pairing: true };
|
|
82
|
+
let urlConfirmed = false;
|
|
83
|
+
while (!urlConfirmed) {
|
|
84
|
+
console.log(`\n ${icon} ${step(1, total)} ${chalk.bold('Relay URL')}`);
|
|
85
|
+
relay = await input({
|
|
86
|
+
message: 'Relay URL:',
|
|
87
|
+
default: OFFICIAL_RELAY,
|
|
88
|
+
theme: promptTheme,
|
|
89
|
+
validate: (v) => {
|
|
90
|
+
if (!v.startsWith('wss://') && !v.startsWith('ws://')) {
|
|
91
|
+
return 'URL must start with wss:// or ws://';
|
|
92
|
+
}
|
|
93
|
+
return true;
|
|
94
|
+
},
|
|
95
|
+
});
|
|
96
|
+
// Test relay connectivity and query auth info
|
|
97
|
+
while (true) {
|
|
98
|
+
const connSpinner = ora({ text: 'Querying relay…', indent: 4 }).start();
|
|
99
|
+
try {
|
|
100
|
+
relayInfo = await queryRelayInfo(relay);
|
|
101
|
+
connSpinner.succeed(`Relay is reachable (auth: ${relayInfo.authModes.join(', ')})`);
|
|
102
|
+
urlConfirmed = true;
|
|
103
|
+
break;
|
|
104
|
+
}
|
|
105
|
+
catch (err) {
|
|
106
|
+
connSpinner.fail(`Cannot reach relay: ${err.message}`);
|
|
107
|
+
const action = await select({
|
|
108
|
+
message: 'What do you want to do?',
|
|
109
|
+
theme: promptTheme,
|
|
110
|
+
choices: [
|
|
111
|
+
{ name: ' Retry', value: 'retry' },
|
|
112
|
+
{ name: ' Enter a different URL', value: 'change' },
|
|
113
|
+
],
|
|
114
|
+
});
|
|
115
|
+
if (action === 'change')
|
|
116
|
+
break; // back to URL input
|
|
117
|
+
// 'retry' continues the inner loop
|
|
118
|
+
}
|
|
119
|
+
}
|
|
120
|
+
}
|
|
121
|
+
divider();
|
|
122
|
+
// 2. Auth method (filtered by what the relay supports)
|
|
123
|
+
const authLabels = {
|
|
124
|
+
github: ' GitHub (recommended)',
|
|
125
|
+
apikey: ' API key',
|
|
126
|
+
'channel-key': ' Channel key (shared secret)',
|
|
127
|
+
open: ' Open (no auth)',
|
|
128
|
+
};
|
|
129
|
+
const supportedModes = relayInfo.authModes;
|
|
130
|
+
let authMethod;
|
|
131
|
+
if (supportedModes.length === 1) {
|
|
132
|
+
// Auto-select
|
|
133
|
+
authMethod = supportedModes[0];
|
|
134
|
+
console.log(` ${icon} ${step(2, total)} ${chalk.bold('Authentication')}`);
|
|
135
|
+
console.log(chalk.dim(` Auto-selected: ${authLabels[authMethod]?.trim() ?? authMethod}`));
|
|
136
|
+
}
|
|
137
|
+
else {
|
|
138
|
+
console.log(` ${icon} ${step(2, total)} ${chalk.bold('Authentication')}`);
|
|
139
|
+
const choices = supportedModes
|
|
140
|
+
.filter((m) => authLabels[m])
|
|
141
|
+
.map((m) => ({ name: authLabels[m], value: m }));
|
|
142
|
+
authMethod = await select({
|
|
143
|
+
message: 'Authentication:',
|
|
144
|
+
theme: promptTheme,
|
|
145
|
+
choices,
|
|
146
|
+
});
|
|
147
|
+
}
|
|
148
|
+
if (authMethod === 'github') {
|
|
149
|
+
const spinner = ora({ text: 'Checking GitHub authentication…', indent: 4 }).start();
|
|
150
|
+
const authResult = await withRetry(checkGhAuth, 'GitHub CLI authentication', 'Run: gh auth login');
|
|
151
|
+
spinner.succeed(`Authenticated as ${chalk.bold(authResult.username ?? 'unknown')}`);
|
|
152
|
+
}
|
|
153
|
+
else if (authMethod === 'channel-key') {
|
|
154
|
+
const channelKey = await input({
|
|
155
|
+
message: 'Channel key:',
|
|
156
|
+
theme: promptTheme,
|
|
157
|
+
validate: (v) => (v.trim().length > 0 ? true : 'Channel key cannot be empty'),
|
|
158
|
+
});
|
|
159
|
+
saveChannelKey(channelKey.trim());
|
|
160
|
+
console.log(chalk.green(' ✔ Channel key saved'));
|
|
161
|
+
}
|
|
162
|
+
divider();
|
|
163
|
+
// 3. Device naming
|
|
164
|
+
console.log(` ${icon} ${step(3, total)} ${chalk.bold('Device Name')}`);
|
|
165
|
+
const defaultName = hostname().replace(/\.local$/, '');
|
|
166
|
+
const deviceName = await input({
|
|
167
|
+
message: 'Device name:',
|
|
168
|
+
theme: promptTheme,
|
|
169
|
+
default: defaultName,
|
|
170
|
+
});
|
|
171
|
+
divider();
|
|
172
|
+
// 4. Agent check
|
|
173
|
+
console.log(` ${icon} ${step(4, total)} ${chalk.bold('Agent Verification')}`);
|
|
174
|
+
const spinner = ora({ text: 'Looking for Copilot CLI…', indent: 4 }).start();
|
|
175
|
+
const copilotResult = await withRetry(checkCopilotCli, 'Copilot CLI', 'Install: npm install -g @github/copilot (or check your PATH)');
|
|
176
|
+
spinner.succeed(`Copilot CLI found (${copilotResult.version ?? 'unknown version'})`);
|
|
177
|
+
// 5. Build config
|
|
178
|
+
const deviceId = getOrCreateDeviceId();
|
|
179
|
+
const config = {
|
|
180
|
+
relay,
|
|
181
|
+
authMethod: authMethod,
|
|
182
|
+
device: { name: deviceName, id: deviceId },
|
|
183
|
+
logging: { verbosity: DEFAULT_LOG_VERBOSITY },
|
|
184
|
+
};
|
|
185
|
+
// 6. Save
|
|
186
|
+
saveConfig(config);
|
|
187
|
+
// 7. Summary box
|
|
188
|
+
console.log('');
|
|
189
|
+
printBox([
|
|
190
|
+
`${chalk.green.bold('✔')} ${chalk.bold('Setup complete!')}`,
|
|
191
|
+
'',
|
|
192
|
+
`${chalk.dim('Relay')} ${chalk.cyan(relay)}`,
|
|
193
|
+
`${chalk.dim('Auth')} ${chalk.cyan(authMethod)}`,
|
|
194
|
+
`${chalk.dim('Device')} ${chalk.cyan(deviceName)}`,
|
|
195
|
+
`${chalk.dim('Logs')} ${chalk.cyan(DEFAULT_LOG_VERBOSITY)}`,
|
|
196
|
+
'',
|
|
197
|
+
chalk.dim('Config saved to ~/.kraki/config.json'),
|
|
198
|
+
]);
|
|
199
|
+
return config;
|
|
200
|
+
}
|
|
201
|
+
/**
|
|
202
|
+
* Generate and display pairing QR code.
|
|
203
|
+
* Called by CLI after daemon is started.
|
|
204
|
+
*/
|
|
205
|
+
export async function showPairingQr(config) {
|
|
206
|
+
console.log('');
|
|
207
|
+
const pairSpinner = ora({ text: 'Generating pairing code…', indent: 2 }).start();
|
|
208
|
+
try {
|
|
209
|
+
let token;
|
|
210
|
+
if (config.authMethod === 'github') {
|
|
211
|
+
try {
|
|
212
|
+
const { execSync } = await import('node:child_process');
|
|
213
|
+
token = execSync('gh auth token 2>/dev/null', { encoding: 'utf8' }).trim() || undefined;
|
|
214
|
+
}
|
|
215
|
+
catch { /* ignore */ }
|
|
216
|
+
}
|
|
217
|
+
else if (config.authMethod === 'channel-key') {
|
|
218
|
+
const { loadChannelKey: loadKey } = await import('./config.js');
|
|
219
|
+
token = loadKey() ?? undefined;
|
|
220
|
+
}
|
|
221
|
+
const { requestPairingToken, buildPairingUrl, renderQrToTerminal } = await import('./pair.js');
|
|
222
|
+
const info = await requestPairingToken(config.relay, token);
|
|
223
|
+
const url = buildPairingUrl(info);
|
|
224
|
+
const qr = await renderQrToTerminal(url);
|
|
225
|
+
pairSpinner.stop();
|
|
226
|
+
console.log(qr);
|
|
227
|
+
console.log(chalk.dim(' Token expires in 5 minutes and can only be claimed once.\n'));
|
|
228
|
+
}
|
|
229
|
+
catch {
|
|
230
|
+
pairSpinner.warn('Could not generate pairing code.');
|
|
231
|
+
console.log(chalk.dim(' Run `kraki connect` later to connect your phone.\n'));
|
|
232
|
+
}
|
|
233
|
+
}
|
|
234
|
+
//# sourceMappingURL=setup.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"setup.js","sourceRoot":"","sources":["../src/setup.ts"],"names":[],"mappings":"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"}
|
package/package.json
ADDED
|
@@ -0,0 +1,48 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "@kraki/tentacle",
|
|
3
|
+
"version": "0.1.0",
|
|
4
|
+
"description": "Kraki agent bridge — the arm that connects your coding agent to the head",
|
|
5
|
+
"type": "module",
|
|
6
|
+
"main": "dist/index.js",
|
|
7
|
+
"types": "dist/index.d.ts",
|
|
8
|
+
"files": [
|
|
9
|
+
"dist"
|
|
10
|
+
],
|
|
11
|
+
"publishConfig": {
|
|
12
|
+
"access": "public"
|
|
13
|
+
},
|
|
14
|
+
"bin": {
|
|
15
|
+
"kraki": "dist/cli.js"
|
|
16
|
+
},
|
|
17
|
+
"dependencies": {
|
|
18
|
+
"@github/copilot-sdk": "^0.1.32",
|
|
19
|
+
"@inquirer/prompts": "^8.3.2",
|
|
20
|
+
"chalk": "^5.6.2",
|
|
21
|
+
"ora": "^9.3.0",
|
|
22
|
+
"pino": "^10.3.1",
|
|
23
|
+
"pino-roll": "^4.0.0",
|
|
24
|
+
"qrcode-terminal": "^0.12.0",
|
|
25
|
+
"uuid": "^13.0.0",
|
|
26
|
+
"ws": "^8.19.0",
|
|
27
|
+
"@kraki/protocol": "0.1.0",
|
|
28
|
+
"@kraki/crypto": "0.1.0"
|
|
29
|
+
},
|
|
30
|
+
"devDependencies": {
|
|
31
|
+
"@types/pino": "^7.0.5",
|
|
32
|
+
"@types/uuid": "^10.0.0",
|
|
33
|
+
"@types/ws": "^8.5.0",
|
|
34
|
+
"@vitest/coverage-v8": "^3.2.4",
|
|
35
|
+
"typescript": "^5.7.0",
|
|
36
|
+
"vitest": "^3.2.4"
|
|
37
|
+
},
|
|
38
|
+
"scripts": {
|
|
39
|
+
"start": "node dist/cli.js",
|
|
40
|
+
"dev": "tsc --watch",
|
|
41
|
+
"dev:local": "KRAKI_APP_URL=http://localhost:3000 node dist/cli.js",
|
|
42
|
+
"build": "rm -rf dist && tsc && cp src/banner-data.json dist/",
|
|
43
|
+
"clean": "rm -rf dist",
|
|
44
|
+
"test": "vitest run",
|
|
45
|
+
"test:watch": "vitest",
|
|
46
|
+
"test:integration": "vitest run --config vitest.integration.config.ts"
|
|
47
|
+
}
|
|
48
|
+
}
|