@junctionpanel/server 0.1.57 → 0.1.59
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/server/server/agent/provider-launch-config.d.ts.map +1 -1
- package/dist/server/server/agent/provider-launch-config.js +6 -39
- package/dist/server/server/agent/provider-launch-config.js.map +1 -1
- package/dist/server/server/agent/providers/claude-agent.d.ts.map +1 -1
- package/dist/server/server/agent/providers/claude-agent.js +40 -15
- package/dist/server/server/agent/providers/claude-agent.js.map +1 -1
- package/dist/server/server/agent/providers/claude-cli-capabilities.d.ts +39 -2
- package/dist/server/server/agent/providers/claude-cli-capabilities.d.ts.map +1 -1
- package/dist/server/server/agent/providers/claude-cli-capabilities.js +88 -23
- package/dist/server/server/agent/providers/claude-cli-capabilities.js.map +1 -1
- package/dist/server/server/agent/providers/codex-app-server-agent.d.ts.map +1 -1
- package/dist/server/server/agent/providers/codex-app-server-agent.js +14 -13
- package/dist/server/server/agent/providers/codex-app-server-agent.js.map +1 -1
- package/dist/server/server/agent/providers/gemini-agent.d.ts +1 -0
- package/dist/server/server/agent/providers/gemini-agent.d.ts.map +1 -1
- package/dist/server/server/agent/providers/gemini-agent.js +53 -15
- package/dist/server/server/agent/providers/gemini-agent.js.map +1 -1
- package/dist/server/server/daemon-doctor.d.ts +2 -1
- package/dist/server/server/daemon-doctor.d.ts.map +1 -1
- package/dist/server/server/daemon-doctor.js +107 -13
- package/dist/server/server/daemon-doctor.js.map +1 -1
- package/dist/server/server/daemon-provider-settings.d.ts +3 -9
- package/dist/server/server/daemon-provider-settings.d.ts.map +1 -1
- package/dist/server/server/daemon-provider-settings.js +27 -83
- package/dist/server/server/daemon-provider-settings.js.map +1 -1
- package/dist/server/server/provider-command-resolution.d.ts +33 -0
- package/dist/server/server/provider-command-resolution.d.ts.map +1 -0
- package/dist/server/server/provider-command-resolution.js +198 -0
- package/dist/server/server/provider-command-resolution.js.map +1 -0
- package/dist/server/server/session.d.ts +13 -0
- package/dist/server/server/session.d.ts.map +1 -1
- package/dist/server/server/session.js +53 -3
- package/dist/server/server/session.js.map +1 -1
- package/dist/server/server/websocket-server.d.ts.map +1 -1
- package/dist/server/server/websocket-server.js +14 -2
- package/dist/server/server/websocket-server.js.map +1 -1
- package/package.json +3 -3
|
@@ -109,6 +109,13 @@ function normalizeAgentRunOptions(runOptions) {
|
|
|
109
109
|
...(runOptions.extra ? { extra: runOptions.extra } : {}),
|
|
110
110
|
};
|
|
111
111
|
}
|
|
112
|
+
function isLoopbackAddress(remoteAddress) {
|
|
113
|
+
if (!remoteAddress) {
|
|
114
|
+
return false;
|
|
115
|
+
}
|
|
116
|
+
const normalized = remoteAddress.trim().toLowerCase();
|
|
117
|
+
return normalized === '127.0.0.1' || normalized === '::1' || normalized === '::ffff:127.0.0.1';
|
|
118
|
+
}
|
|
112
119
|
/**
|
|
113
120
|
* Session represents a single connected client session.
|
|
114
121
|
* It owns all state management, orchestration logic, and message processing.
|
|
@@ -135,7 +142,7 @@ export class Session {
|
|
|
135
142
|
this.checkoutDiffSubscriptions = new Map();
|
|
136
143
|
this.checkoutDiffTargets = new Map();
|
|
137
144
|
this.workspaceGitOperationStates = sharedWorkspaceGitOperationStates;
|
|
138
|
-
const { clientId, userId, onMessage, onBinaryMessage, onLifecycleIntent, logger, downloadTokenStore, junctionHome, agentManager, agentStorage, createAgentMcpTransport, terminalManager, agentProviderRuntimeSettings, } = options;
|
|
145
|
+
const { clientId, userId, onMessage, onBinaryMessage, onLifecycleIntent, logger, downloadTokenStore, junctionHome, agentManager, agentStorage, createAgentMcpTransport, terminalManager, agentProviderRuntimeSettings, connectionContext, } = options;
|
|
139
146
|
this.clientId = clientId;
|
|
140
147
|
this.userId = userId;
|
|
141
148
|
this.sessionId = uuidv4();
|
|
@@ -148,6 +155,14 @@ export class Session {
|
|
|
148
155
|
this.agentStorage = agentStorage;
|
|
149
156
|
this.createAgentMcpTransport = createAgentMcpTransport;
|
|
150
157
|
this.terminalManager = terminalManager;
|
|
158
|
+
this.connectionContext = {
|
|
159
|
+
clientType: connectionContext?.clientType ?? 'browser',
|
|
160
|
+
transport: connectionContext?.transport ?? 'direct',
|
|
161
|
+
host: connectionContext?.host ?? null,
|
|
162
|
+
origin: connectionContext?.origin ?? null,
|
|
163
|
+
userAgent: connectionContext?.userAgent ?? null,
|
|
164
|
+
remoteAddress: connectionContext?.remoteAddress ?? null,
|
|
165
|
+
};
|
|
151
166
|
if (this.terminalManager) {
|
|
152
167
|
this.unsubscribeTerminalsChanged = this.terminalManager.subscribeTerminalsChanged((event) => this.handleTerminalsChanged(event));
|
|
153
168
|
}
|
|
@@ -157,6 +172,9 @@ export class Session {
|
|
|
157
172
|
module: 'session',
|
|
158
173
|
clientId: this.clientId,
|
|
159
174
|
sessionId: this.sessionId,
|
|
175
|
+
transport: this.connectionContext.transport,
|
|
176
|
+
clientType: this.connectionContext.clientType,
|
|
177
|
+
remoteAddress: this.connectionContext.remoteAddress,
|
|
160
178
|
});
|
|
161
179
|
this.providerRegistry = buildProviderRegistry(this.sessionLogger, {
|
|
162
180
|
runtimeSettings: this.agentProviderRuntimeSettings,
|
|
@@ -1119,6 +1137,13 @@ export class Session {
|
|
|
1119
1137
|
this.sessionLogger.warn({ streamId: frame.streamId, messageType: frame.messageType }, 'Unhandled terminal binary frame');
|
|
1120
1138
|
}
|
|
1121
1139
|
async handleRestartServerRequest(requestId, reason) {
|
|
1140
|
+
this.assertLifecycleControlAllowed('restart', requestId, reason);
|
|
1141
|
+
this.requestServerRestart(requestId, reason, {
|
|
1142
|
+
logLevel: 'warn',
|
|
1143
|
+
logMessage: 'Restart requested via websocket',
|
|
1144
|
+
});
|
|
1145
|
+
}
|
|
1146
|
+
requestServerRestart(requestId, reason, options) {
|
|
1122
1147
|
const payload = {
|
|
1123
1148
|
status: 'restart_requested',
|
|
1124
1149
|
clientId: this.clientId,
|
|
@@ -1127,7 +1152,9 @@ export class Session {
|
|
|
1127
1152
|
payload.reason = reason;
|
|
1128
1153
|
}
|
|
1129
1154
|
payload.requestId = requestId;
|
|
1130
|
-
|
|
1155
|
+
const logLevel = options?.logLevel ?? 'warn';
|
|
1156
|
+
const logMessage = options?.logMessage ?? 'Restart requested';
|
|
1157
|
+
this.sessionLogger[logLevel]({ reason, requestId }, logMessage);
|
|
1131
1158
|
this.emit({
|
|
1132
1159
|
type: 'status',
|
|
1133
1160
|
payload,
|
|
@@ -1140,6 +1167,7 @@ export class Session {
|
|
|
1140
1167
|
});
|
|
1141
1168
|
}
|
|
1142
1169
|
async handleShutdownServerRequest(requestId) {
|
|
1170
|
+
this.assertLifecycleControlAllowed('shutdown', requestId);
|
|
1143
1171
|
this.sessionLogger.warn('Shutdown requested via websocket');
|
|
1144
1172
|
this.emit({
|
|
1145
1173
|
type: 'status',
|
|
@@ -1155,6 +1183,25 @@ export class Session {
|
|
|
1155
1183
|
requestId,
|
|
1156
1184
|
});
|
|
1157
1185
|
}
|
|
1186
|
+
assertLifecycleControlAllowed(action, requestId, reason) {
|
|
1187
|
+
const allowed = this.connectionContext.clientType === 'cli'
|
|
1188
|
+
&& this.connectionContext.transport === 'direct'
|
|
1189
|
+
&& isLoopbackAddress(this.connectionContext.remoteAddress);
|
|
1190
|
+
if (allowed) {
|
|
1191
|
+
return;
|
|
1192
|
+
}
|
|
1193
|
+
this.sessionLogger.warn({
|
|
1194
|
+
action,
|
|
1195
|
+
requestId,
|
|
1196
|
+
reason: reason ?? null,
|
|
1197
|
+
clientType: this.connectionContext.clientType,
|
|
1198
|
+
transport: this.connectionContext.transport,
|
|
1199
|
+
remoteAddress: this.connectionContext.remoteAddress,
|
|
1200
|
+
host: this.connectionContext.host,
|
|
1201
|
+
origin: this.connectionContext.origin,
|
|
1202
|
+
}, 'Rejected lifecycle request from unauthorized client');
|
|
1203
|
+
throw new SessionRequestError('lifecycle_forbidden', `Only direct localhost CLI sessions can ${action} the daemon.`);
|
|
1204
|
+
}
|
|
1158
1205
|
emitLifecycleIntent(intent) {
|
|
1159
1206
|
if (!this.onLifecycleIntent) {
|
|
1160
1207
|
return;
|
|
@@ -2119,7 +2166,10 @@ export class Session {
|
|
|
2119
2166
|
requestId: msg.requestId,
|
|
2120
2167
|
},
|
|
2121
2168
|
});
|
|
2122
|
-
|
|
2169
|
+
this.requestServerRestart(msg.requestId, 'settings_update', {
|
|
2170
|
+
logLevel: 'info',
|
|
2171
|
+
logMessage: 'Restart requested after daemon provider settings update',
|
|
2172
|
+
});
|
|
2123
2173
|
}
|
|
2124
2174
|
catch (error) {
|
|
2125
2175
|
this.sessionLogger.error({ err: error, provider: msg.provider }, 'Failed to update daemon provider settings');
|