@tiflis-io/tiflis-code-workstation 0.3.3 → 0.3.5
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/main.js +229 -39
- package/package.json +1 -1
package/dist/main.js
CHANGED
|
@@ -347,6 +347,22 @@ var AGENT_EXECUTION_CONFIG = {
|
|
|
347
347
|
]
|
|
348
348
|
};
|
|
349
349
|
var BASE_AGENT_TYPES = ["cursor", "claude", "opencode"];
|
|
350
|
+
function isBaseAgentDisabled(baseType) {
|
|
351
|
+
const env = getEnv();
|
|
352
|
+
switch (baseType) {
|
|
353
|
+
case "cursor":
|
|
354
|
+
return env.HIDE_BASE_CURSOR;
|
|
355
|
+
case "claude":
|
|
356
|
+
return env.HIDE_BASE_CLAUDE;
|
|
357
|
+
case "opencode":
|
|
358
|
+
return env.HIDE_BASE_OPENCODE;
|
|
359
|
+
default:
|
|
360
|
+
return false;
|
|
361
|
+
}
|
|
362
|
+
}
|
|
363
|
+
function getDisabledBaseAgents() {
|
|
364
|
+
return BASE_AGENT_TYPES.filter(isBaseAgentDisabled);
|
|
365
|
+
}
|
|
350
366
|
function getBaseTypeFromCommand(command) {
|
|
351
367
|
const commandMap = {
|
|
352
368
|
claude: "claude",
|
|
@@ -357,33 +373,39 @@ function getBaseTypeFromCommand(command) {
|
|
|
357
373
|
}
|
|
358
374
|
function getAvailableAgents() {
|
|
359
375
|
const agents = /* @__PURE__ */ new Map();
|
|
360
|
-
|
|
361
|
-
|
|
362
|
-
|
|
363
|
-
|
|
364
|
-
|
|
365
|
-
|
|
366
|
-
|
|
367
|
-
|
|
368
|
-
|
|
369
|
-
|
|
370
|
-
|
|
371
|
-
|
|
372
|
-
|
|
373
|
-
|
|
374
|
-
|
|
375
|
-
|
|
376
|
-
|
|
377
|
-
|
|
378
|
-
|
|
379
|
-
|
|
380
|
-
|
|
381
|
-
|
|
382
|
-
|
|
383
|
-
|
|
384
|
-
|
|
385
|
-
|
|
386
|
-
|
|
376
|
+
if (!isBaseAgentDisabled("cursor")) {
|
|
377
|
+
agents.set("cursor", {
|
|
378
|
+
name: "cursor",
|
|
379
|
+
command: AGENT_COMMANDS.cursor.command,
|
|
380
|
+
aliasArgs: [],
|
|
381
|
+
aliasEnvVars: {},
|
|
382
|
+
baseType: "cursor",
|
|
383
|
+
description: AGENT_COMMANDS.cursor.description,
|
|
384
|
+
isAlias: false
|
|
385
|
+
});
|
|
386
|
+
}
|
|
387
|
+
if (!isBaseAgentDisabled("claude")) {
|
|
388
|
+
agents.set("claude", {
|
|
389
|
+
name: "claude",
|
|
390
|
+
command: AGENT_COMMANDS.claude.command,
|
|
391
|
+
aliasArgs: [],
|
|
392
|
+
aliasEnvVars: {},
|
|
393
|
+
baseType: "claude",
|
|
394
|
+
description: AGENT_COMMANDS.claude.description,
|
|
395
|
+
isAlias: false
|
|
396
|
+
});
|
|
397
|
+
}
|
|
398
|
+
if (!isBaseAgentDisabled("opencode")) {
|
|
399
|
+
agents.set("opencode", {
|
|
400
|
+
name: "opencode",
|
|
401
|
+
command: AGENT_COMMANDS.opencode.command,
|
|
402
|
+
aliasArgs: [],
|
|
403
|
+
aliasEnvVars: {},
|
|
404
|
+
baseType: "opencode",
|
|
405
|
+
description: AGENT_COMMANDS.opencode.description,
|
|
406
|
+
isAlias: false
|
|
407
|
+
});
|
|
408
|
+
}
|
|
387
409
|
const aliases = getAgentAliases();
|
|
388
410
|
for (const [name, alias] of aliases) {
|
|
389
411
|
const baseType = getBaseTypeFromCommand(alias.baseCommand);
|
|
@@ -1102,8 +1124,21 @@ var HeartbeatSchema = z2.object({
|
|
|
1102
1124
|
var SyncMessageSchema = z2.object({
|
|
1103
1125
|
type: z2.literal("sync"),
|
|
1104
1126
|
id: z2.string(),
|
|
1105
|
-
device_id: z2.string().optional()
|
|
1127
|
+
device_id: z2.string().optional(),
|
|
1128
|
+
// Injected by tunnel for tunnel connections
|
|
1129
|
+
lightweight: z2.boolean().optional()
|
|
1130
|
+
// If true, excludes message histories (for watchOS)
|
|
1131
|
+
});
|
|
1132
|
+
var HistoryRequestPayloadSchema = z2.object({
|
|
1133
|
+
session_id: z2.string().optional()
|
|
1134
|
+
// If omitted, returns supervisor history
|
|
1135
|
+
});
|
|
1136
|
+
var HistoryRequestSchema = z2.object({
|
|
1137
|
+
type: z2.literal("history.request"),
|
|
1138
|
+
id: z2.string(),
|
|
1139
|
+
device_id: z2.string().optional(),
|
|
1106
1140
|
// Injected by tunnel for tunnel connections
|
|
1141
|
+
payload: HistoryRequestPayloadSchema.optional()
|
|
1107
1142
|
});
|
|
1108
1143
|
var ListSessionsSchema = z2.object({
|
|
1109
1144
|
type: z2.literal("supervisor.list_sessions"),
|
|
@@ -1260,6 +1295,7 @@ var IncomingClientMessageSchema = z2.discriminatedUnion("type", [
|
|
|
1260
1295
|
PingSchema,
|
|
1261
1296
|
HeartbeatSchema,
|
|
1262
1297
|
SyncMessageSchema,
|
|
1298
|
+
HistoryRequestSchema,
|
|
1263
1299
|
ListSessionsSchema,
|
|
1264
1300
|
CreateSessionSchema,
|
|
1265
1301
|
TerminateSessionSchema,
|
|
@@ -7355,10 +7391,11 @@ async function bootstrap() {
|
|
|
7355
7391
|
const syncMessage = message;
|
|
7356
7392
|
const client = clientRegistry.getBySocket(socket) ?? (syncMessage.device_id ? clientRegistry.getByDeviceId(new DeviceId(syncMessage.device_id)) : void 0);
|
|
7357
7393
|
const subscriptions2 = client ? client.getSubscriptions() : [];
|
|
7394
|
+
const isLightweight = syncMessage.lightweight === true;
|
|
7358
7395
|
const inMemorySessions = sessionManager.getSessionInfos();
|
|
7359
7396
|
const persistedAgentSessions = chatHistoryService.getActiveAgentSessions();
|
|
7360
7397
|
logger.debug(
|
|
7361
|
-
{ persistedAgentSessions, inMemoryCount: inMemorySessions.length },
|
|
7398
|
+
{ persistedAgentSessions, inMemoryCount: inMemorySessions.length, isLightweight },
|
|
7362
7399
|
"Sync: fetched sessions"
|
|
7363
7400
|
);
|
|
7364
7401
|
const inMemorySessionIds = new Set(
|
|
@@ -7383,6 +7420,67 @@ async function bootstrap() {
|
|
|
7383
7420
|
};
|
|
7384
7421
|
});
|
|
7385
7422
|
const sessions2 = [...inMemorySessions, ...restoredAgentSessions];
|
|
7423
|
+
if (isLightweight) {
|
|
7424
|
+
const availableAgentsMap2 = getAvailableAgents();
|
|
7425
|
+
const availableAgents2 = Array.from(availableAgentsMap2.values()).map(
|
|
7426
|
+
(agent) => ({
|
|
7427
|
+
name: agent.name,
|
|
7428
|
+
base_type: agent.baseType,
|
|
7429
|
+
description: agent.description,
|
|
7430
|
+
is_alias: agent.isAlias
|
|
7431
|
+
})
|
|
7432
|
+
);
|
|
7433
|
+
const hiddenBaseTypes2 = getDisabledBaseAgents();
|
|
7434
|
+
const workspacesList2 = await workspaceDiscovery.listWorkspaces();
|
|
7435
|
+
const workspaces2 = await Promise.all(
|
|
7436
|
+
workspacesList2.map(async (ws) => {
|
|
7437
|
+
const projects = await workspaceDiscovery.listProjects(ws.name);
|
|
7438
|
+
return {
|
|
7439
|
+
name: ws.name,
|
|
7440
|
+
projects: projects.map((p) => ({
|
|
7441
|
+
name: p.name,
|
|
7442
|
+
is_git_repo: p.isGitRepo,
|
|
7443
|
+
default_branch: p.defaultBranch
|
|
7444
|
+
}))
|
|
7445
|
+
};
|
|
7446
|
+
})
|
|
7447
|
+
);
|
|
7448
|
+
const executingStates2 = {};
|
|
7449
|
+
for (const session of sessions2) {
|
|
7450
|
+
if (session.session_type === "cursor" || session.session_type === "claude" || session.session_type === "opencode") {
|
|
7451
|
+
executingStates2[session.session_id] = agentSessionManager.isExecuting(
|
|
7452
|
+
session.session_id
|
|
7453
|
+
);
|
|
7454
|
+
}
|
|
7455
|
+
}
|
|
7456
|
+
const supervisorIsExecuting2 = supervisorAgent.isProcessing();
|
|
7457
|
+
logger.info(
|
|
7458
|
+
{
|
|
7459
|
+
totalSessions: sessions2.length,
|
|
7460
|
+
isLightweight: true,
|
|
7461
|
+
availableAgentsCount: availableAgents2.length,
|
|
7462
|
+
workspacesCount: workspaces2.length,
|
|
7463
|
+
supervisorIsExecuting: supervisorIsExecuting2
|
|
7464
|
+
},
|
|
7465
|
+
"Sync: sending lightweight state to client (no histories)"
|
|
7466
|
+
);
|
|
7467
|
+
const syncStateMessage2 = JSON.stringify({
|
|
7468
|
+
type: "sync.state",
|
|
7469
|
+
id: syncMessage.id,
|
|
7470
|
+
payload: {
|
|
7471
|
+
sessions: sessions2,
|
|
7472
|
+
subscriptions: subscriptions2,
|
|
7473
|
+
availableAgents: availableAgents2,
|
|
7474
|
+
hiddenBaseTypes: hiddenBaseTypes2,
|
|
7475
|
+
workspaces: workspaces2,
|
|
7476
|
+
supervisorIsExecuting: supervisorIsExecuting2,
|
|
7477
|
+
executingStates: executingStates2
|
|
7478
|
+
// Omit: supervisorHistory, agentHistories, currentStreamingBlocks
|
|
7479
|
+
}
|
|
7480
|
+
});
|
|
7481
|
+
sendToDevice(socket, syncMessage.device_id, syncStateMessage2);
|
|
7482
|
+
return Promise.resolve();
|
|
7483
|
+
}
|
|
7386
7484
|
const supervisorHistoryRaw = chatHistoryService.getSupervisorHistory();
|
|
7387
7485
|
const supervisorHistory = await Promise.all(
|
|
7388
7486
|
supervisorHistoryRaw.map(async (msg) => ({
|
|
@@ -7437,16 +7535,7 @@ async function bootstrap() {
|
|
|
7437
7535
|
is_alias: agent.isAlias
|
|
7438
7536
|
})
|
|
7439
7537
|
);
|
|
7440
|
-
const hiddenBaseTypes =
|
|
7441
|
-
if (env.HIDE_BASE_CURSOR) {
|
|
7442
|
-
hiddenBaseTypes.push("cursor");
|
|
7443
|
-
}
|
|
7444
|
-
if (env.HIDE_BASE_CLAUDE) {
|
|
7445
|
-
hiddenBaseTypes.push("claude");
|
|
7446
|
-
}
|
|
7447
|
-
if (env.HIDE_BASE_OPENCODE) {
|
|
7448
|
-
hiddenBaseTypes.push("opencode");
|
|
7449
|
-
}
|
|
7538
|
+
const hiddenBaseTypes = getDisabledBaseAgents();
|
|
7450
7539
|
const workspacesList = await workspaceDiscovery.listWorkspaces();
|
|
7451
7540
|
const workspaces = await Promise.all(
|
|
7452
7541
|
workspacesList.map(async (ws) => {
|
|
@@ -8498,6 +8587,107 @@ async function bootstrap() {
|
|
|
8498
8587
|
}
|
|
8499
8588
|
return Promise.resolve();
|
|
8500
8589
|
},
|
|
8590
|
+
"history.request": async (socket, message) => {
|
|
8591
|
+
const historyRequest = message;
|
|
8592
|
+
const sessionId = historyRequest.payload?.session_id;
|
|
8593
|
+
const isSupervisor = !sessionId;
|
|
8594
|
+
logger.debug(
|
|
8595
|
+
{ sessionId, isSupervisor, requestId: historyRequest.id },
|
|
8596
|
+
"History request received"
|
|
8597
|
+
);
|
|
8598
|
+
try {
|
|
8599
|
+
if (isSupervisor) {
|
|
8600
|
+
const supervisorHistoryRaw = chatHistoryService.getSupervisorHistory();
|
|
8601
|
+
const supervisorHistory = await Promise.all(
|
|
8602
|
+
supervisorHistoryRaw.map(async (msg) => ({
|
|
8603
|
+
message_id: msg.id,
|
|
8604
|
+
// Include message ID for audio.request
|
|
8605
|
+
sequence: msg.sequence,
|
|
8606
|
+
role: msg.role,
|
|
8607
|
+
content: msg.content,
|
|
8608
|
+
content_blocks: await chatHistoryService.enrichBlocksWithAudio(
|
|
8609
|
+
msg.contentBlocks,
|
|
8610
|
+
msg.audioOutputPath,
|
|
8611
|
+
msg.audioInputPath,
|
|
8612
|
+
false
|
|
8613
|
+
// Don't include audio in history response
|
|
8614
|
+
),
|
|
8615
|
+
createdAt: msg.createdAt.toISOString()
|
|
8616
|
+
}))
|
|
8617
|
+
);
|
|
8618
|
+
const isExecuting = supervisorAgent.isProcessing();
|
|
8619
|
+
socket.send(
|
|
8620
|
+
JSON.stringify({
|
|
8621
|
+
type: "history.response",
|
|
8622
|
+
id: historyRequest.id,
|
|
8623
|
+
payload: {
|
|
8624
|
+
session_id: null,
|
|
8625
|
+
// Indicates supervisor
|
|
8626
|
+
history: supervisorHistory,
|
|
8627
|
+
is_executing: isExecuting
|
|
8628
|
+
}
|
|
8629
|
+
})
|
|
8630
|
+
);
|
|
8631
|
+
logger.debug(
|
|
8632
|
+
{ messageCount: supervisorHistory.length, isExecuting },
|
|
8633
|
+
"Supervisor history sent"
|
|
8634
|
+
);
|
|
8635
|
+
} else {
|
|
8636
|
+
const history = chatHistoryService.getAgentHistory(sessionId);
|
|
8637
|
+
const enrichedHistory = await Promise.all(
|
|
8638
|
+
history.map(async (msg) => ({
|
|
8639
|
+
sequence: msg.sequence,
|
|
8640
|
+
role: msg.role,
|
|
8641
|
+
content: msg.content,
|
|
8642
|
+
content_blocks: await chatHistoryService.enrichBlocksWithAudio(
|
|
8643
|
+
msg.contentBlocks,
|
|
8644
|
+
msg.audioOutputPath,
|
|
8645
|
+
msg.audioInputPath,
|
|
8646
|
+
false
|
|
8647
|
+
// Don't include audio in history response
|
|
8648
|
+
),
|
|
8649
|
+
createdAt: msg.createdAt.toISOString()
|
|
8650
|
+
}))
|
|
8651
|
+
);
|
|
8652
|
+
const isExecuting = agentSessionManager.isExecuting(sessionId);
|
|
8653
|
+
let currentStreamingBlocks;
|
|
8654
|
+
if (isExecuting) {
|
|
8655
|
+
const blocks = agentMessageAccumulator.get(sessionId);
|
|
8656
|
+
if (blocks && blocks.length > 0) {
|
|
8657
|
+
currentStreamingBlocks = blocks;
|
|
8658
|
+
}
|
|
8659
|
+
}
|
|
8660
|
+
socket.send(
|
|
8661
|
+
JSON.stringify({
|
|
8662
|
+
type: "history.response",
|
|
8663
|
+
id: historyRequest.id,
|
|
8664
|
+
payload: {
|
|
8665
|
+
session_id: sessionId,
|
|
8666
|
+
history: enrichedHistory,
|
|
8667
|
+
is_executing: isExecuting,
|
|
8668
|
+
current_streaming_blocks: currentStreamingBlocks
|
|
8669
|
+
}
|
|
8670
|
+
})
|
|
8671
|
+
);
|
|
8672
|
+
logger.debug(
|
|
8673
|
+
{ sessionId, messageCount: enrichedHistory.length, isExecuting },
|
|
8674
|
+
"Agent session history sent"
|
|
8675
|
+
);
|
|
8676
|
+
}
|
|
8677
|
+
} catch (error) {
|
|
8678
|
+
logger.error({ error, sessionId }, "Failed to get history");
|
|
8679
|
+
socket.send(
|
|
8680
|
+
JSON.stringify({
|
|
8681
|
+
type: "history.response",
|
|
8682
|
+
id: historyRequest.id,
|
|
8683
|
+
payload: {
|
|
8684
|
+
session_id: sessionId ?? null,
|
|
8685
|
+
error: error instanceof Error ? error.message : "Failed to get history"
|
|
8686
|
+
}
|
|
8687
|
+
})
|
|
8688
|
+
);
|
|
8689
|
+
}
|
|
8690
|
+
},
|
|
8501
8691
|
"audio.request": async (socket, message) => {
|
|
8502
8692
|
const audioRequest = message;
|
|
8503
8693
|
const { message_id, type = "output" } = audioRequest.payload;
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@tiflis-io/tiflis-code-workstation",
|
|
3
|
-
"version": "0.3.
|
|
3
|
+
"version": "0.3.5",
|
|
4
4
|
"description": "Workstation server for tiflis-code - manages agent sessions and terminal access",
|
|
5
5
|
"author": "Roman Barinov <rbarinov@gmail.com>",
|
|
6
6
|
"license": "FSL-1.1-NC",
|