@tiflis-io/tiflis-code-workstation 0.3.4 → 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.
Files changed (2) hide show
  1. package/dist/main.js +179 -2
  2. package/package.json +1 -1
package/dist/main.js CHANGED
@@ -1124,8 +1124,21 @@ var HeartbeatSchema = z2.object({
1124
1124
  var SyncMessageSchema = z2.object({
1125
1125
  type: z2.literal("sync"),
1126
1126
  id: z2.string(),
1127
- device_id: z2.string().optional()
1127
+ device_id: z2.string().optional(),
1128
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(),
1140
+ // Injected by tunnel for tunnel connections
1141
+ payload: HistoryRequestPayloadSchema.optional()
1129
1142
  });
1130
1143
  var ListSessionsSchema = z2.object({
1131
1144
  type: z2.literal("supervisor.list_sessions"),
@@ -1282,6 +1295,7 @@ var IncomingClientMessageSchema = z2.discriminatedUnion("type", [
1282
1295
  PingSchema,
1283
1296
  HeartbeatSchema,
1284
1297
  SyncMessageSchema,
1298
+ HistoryRequestSchema,
1285
1299
  ListSessionsSchema,
1286
1300
  CreateSessionSchema,
1287
1301
  TerminateSessionSchema,
@@ -7377,10 +7391,11 @@ async function bootstrap() {
7377
7391
  const syncMessage = message;
7378
7392
  const client = clientRegistry.getBySocket(socket) ?? (syncMessage.device_id ? clientRegistry.getByDeviceId(new DeviceId(syncMessage.device_id)) : void 0);
7379
7393
  const subscriptions2 = client ? client.getSubscriptions() : [];
7394
+ const isLightweight = syncMessage.lightweight === true;
7380
7395
  const inMemorySessions = sessionManager.getSessionInfos();
7381
7396
  const persistedAgentSessions = chatHistoryService.getActiveAgentSessions();
7382
7397
  logger.debug(
7383
- { persistedAgentSessions, inMemoryCount: inMemorySessions.length },
7398
+ { persistedAgentSessions, inMemoryCount: inMemorySessions.length, isLightweight },
7384
7399
  "Sync: fetched sessions"
7385
7400
  );
7386
7401
  const inMemorySessionIds = new Set(
@@ -7405,6 +7420,67 @@ async function bootstrap() {
7405
7420
  };
7406
7421
  });
7407
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
+ }
7408
7484
  const supervisorHistoryRaw = chatHistoryService.getSupervisorHistory();
7409
7485
  const supervisorHistory = await Promise.all(
7410
7486
  supervisorHistoryRaw.map(async (msg) => ({
@@ -8511,6 +8587,107 @@ async function bootstrap() {
8511
8587
  }
8512
8588
  return Promise.resolve();
8513
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
+ },
8514
8691
  "audio.request": async (socket, message) => {
8515
8692
  const audioRequest = message;
8516
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.4",
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",