@superblocksteam/vite-plugin-file-sync 2.0.151 → 2.0.152-next.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/dist/ai-service/agent/middleware.d.ts.map +1 -1
- package/dist/ai-service/agent/middleware.js +10 -1
- package/dist/ai-service/agent/middleware.js.map +1 -1
- package/dist/ai-service/agent/prompts/build-base-system-prompt.d.ts.map +1 -1
- package/dist/ai-service/agent/prompts/build-base-system-prompt.js +25 -6
- package/dist/ai-service/agent/prompts/build-base-system-prompt.js.map +1 -1
- package/dist/ai-service/agent/prompts/build-security-scan-prompt.d.ts.map +1 -1
- package/dist/ai-service/agent/prompts/build-security-scan-prompt.js +7 -2
- package/dist/ai-service/agent/prompts/build-security-scan-prompt.js.map +1 -1
- package/dist/ai-service/agent/tools/apis/get-sdk-api-docs.d.ts +47 -1
- package/dist/ai-service/agent/tools/apis/get-sdk-api-docs.d.ts.map +1 -1
- package/dist/ai-service/agent/tools/apis/get-sdk-api-docs.js +129 -15
- package/dist/ai-service/agent/tools/apis/get-sdk-api-docs.js.map +1 -1
- package/dist/ai-service/agent/tools/apis/test-api.d.ts.map +1 -1
- package/dist/ai-service/agent/tools/apis/test-api.js +1 -24
- package/dist/ai-service/agent/tools/apis/test-api.js.map +1 -1
- package/dist/ai-service/agent/tools/databases/dev-database-tasks.d.ts +53 -9
- package/dist/ai-service/agent/tools/databases/dev-database-tasks.d.ts.map +1 -1
- package/dist/ai-service/agent/tools/databases/dev-database-tasks.js +304 -67
- package/dist/ai-service/agent/tools/databases/dev-database-tasks.js.map +1 -1
- package/dist/ai-service/agent/tools/databases/dev-database-tools.d.ts +47 -1
- package/dist/ai-service/agent/tools/databases/dev-database-tools.d.ts.map +1 -1
- package/dist/ai-service/agent/tools/databases/dev-database-tools.js +38 -1
- package/dist/ai-service/agent/tools/databases/dev-database-tools.js.map +1 -1
- package/dist/ai-service/agent/tools/integrations/execute-request.d.ts +391 -0
- package/dist/ai-service/agent/tools/integrations/execute-request.d.ts.map +1 -1
- package/dist/ai-service/agent/tools/integrations/execute-request.js +257 -44
- package/dist/ai-service/agent/tools/integrations/execute-request.js.map +1 -1
- package/dist/ai-service/agent/tools/integrations/index.d.ts +1 -1
- package/dist/ai-service/agent/tools/integrations/index.d.ts.map +1 -1
- package/dist/ai-service/agent/tools/integrations/index.js +1 -1
- package/dist/ai-service/agent/tools/integrations/index.js.map +1 -1
- package/dist/ai-service/agent/tools/integrations/managed-app-database.d.ts +16 -0
- package/dist/ai-service/agent/tools/integrations/managed-app-database.d.ts.map +1 -0
- package/dist/ai-service/agent/tools/integrations/managed-app-database.js +31 -0
- package/dist/ai-service/agent/tools/integrations/managed-app-database.js.map +1 -0
- package/dist/ai-service/agent/tools/integrations/sql-classification.d.ts +44 -0
- package/dist/ai-service/agent/tools/integrations/sql-classification.d.ts.map +1 -0
- package/dist/ai-service/agent/tools/integrations/sql-classification.js +352 -0
- package/dist/ai-service/agent/tools/integrations/sql-classification.js.map +1 -0
- package/dist/ai-service/agent/tools/report-security-findings.d.ts +5 -5
- package/dist/ai-service/agent/tools.d.ts.map +1 -1
- package/dist/ai-service/agent/tools.js +5 -1
- package/dist/ai-service/agent/tools.js.map +1 -1
- package/dist/ai-service/agent/tools2/registry.d.ts.map +1 -1
- package/dist/ai-service/agent/tools2/registry.js +2 -0
- package/dist/ai-service/agent/tools2/registry.js.map +1 -1
- package/dist/ai-service/agent/tools2/tools/check-task.d.ts.map +1 -1
- package/dist/ai-service/agent/tools2/tools/check-task.js +4 -1
- package/dist/ai-service/agent/tools2/tools/check-task.js.map +1 -1
- package/dist/ai-service/agent/tools2/tools/exit-plan-mode.d.ts.map +1 -1
- package/dist/ai-service/agent/tools2/tools/exit-plan-mode.js +12 -1
- package/dist/ai-service/agent/tools2/tools/exit-plan-mode.js.map +1 -1
- package/dist/ai-service/agent/tools2/tools/wait-for-task.d.ts.map +1 -1
- package/dist/ai-service/agent/tools2/tools/wait-for-task.js +5 -1
- package/dist/ai-service/agent/tools2/tools/wait-for-task.js.map +1 -1
- package/dist/ai-service/chat/chat-session-store.d.ts +10 -1
- package/dist/ai-service/chat/chat-session-store.d.ts.map +1 -1
- package/dist/ai-service/chat/chat-session-store.js +65 -15
- package/dist/ai-service/chat/chat-session-store.js.map +1 -1
- package/dist/ai-service/context-archive-paths.d.ts +7 -0
- package/dist/ai-service/context-archive-paths.d.ts.map +1 -1
- package/dist/ai-service/context-archive-paths.js +7 -0
- package/dist/ai-service/context-archive-paths.js.map +1 -1
- package/dist/ai-service/context-download.d.ts.map +1 -1
- package/dist/ai-service/context-download.js +8 -10
- package/dist/ai-service/context-download.js.map +1 -1
- package/dist/ai-service/context-flush.d.ts +36 -0
- package/dist/ai-service/context-flush.d.ts.map +1 -0
- package/dist/ai-service/context-flush.js +90 -0
- package/dist/ai-service/context-flush.js.map +1 -0
- package/dist/ai-service/context-restore.d.ts +64 -0
- package/dist/ai-service/context-restore.d.ts.map +1 -0
- package/dist/ai-service/context-restore.js +136 -0
- package/dist/ai-service/context-restore.js.map +1 -0
- package/dist/ai-service/context-upload.d.ts +13 -4
- package/dist/ai-service/context-upload.d.ts.map +1 -1
- package/dist/ai-service/context-upload.js +28 -18
- package/dist/ai-service/context-upload.js.map +1 -1
- package/dist/ai-service/dev-database-client.d.ts +51 -0
- package/dist/ai-service/dev-database-client.d.ts.map +1 -1
- package/dist/ai-service/dev-database-client.js +3 -0
- package/dist/ai-service/dev-database-client.js.map +1 -1
- package/dist/ai-service/index.d.ts +19 -0
- package/dist/ai-service/index.d.ts.map +1 -1
- package/dist/ai-service/index.js +449 -182
- package/dist/ai-service/index.js.map +1 -1
- package/dist/ai-service/llm/context-v2/adapter.d.ts.map +1 -1
- package/dist/ai-service/llm/context-v2/adapter.js +1 -0
- package/dist/ai-service/llm/context-v2/adapter.js.map +1 -1
- package/dist/ai-service/llm/context-v2/compaction/client-side.d.ts +30 -0
- package/dist/ai-service/llm/context-v2/compaction/client-side.d.ts.map +1 -1
- package/dist/ai-service/llm/context-v2/compaction/client-side.js +77 -4
- package/dist/ai-service/llm/context-v2/compaction/client-side.js.map +1 -1
- package/dist/ai-service/llm/context-v2/compaction/compaction-strategy.d.ts +5 -0
- package/dist/ai-service/llm/context-v2/compaction/compaction-strategy.d.ts.map +1 -1
- package/dist/ai-service/llm/context-v2/compaction/server-side.d.ts +1 -0
- package/dist/ai-service/llm/context-v2/compaction/server-side.d.ts.map +1 -1
- package/dist/ai-service/llm/context-v2/compaction/server-side.js +3 -0
- package/dist/ai-service/llm/context-v2/compaction/server-side.js.map +1 -1
- package/dist/ai-service/llm/context-v2/compactor.d.ts.map +1 -1
- package/dist/ai-service/llm/context-v2/compactor.js +57 -6
- package/dist/ai-service/llm/context-v2/compactor.js.map +1 -1
- package/dist/ai-service/llm/context-v2/config.d.ts +13 -1
- package/dist/ai-service/llm/context-v2/config.d.ts.map +1 -1
- package/dist/ai-service/llm/context-v2/config.js +39 -2
- package/dist/ai-service/llm/context-v2/config.js.map +1 -1
- package/dist/ai-service/llm/context-v2/context-metrics.d.ts +23 -0
- package/dist/ai-service/llm/context-v2/context-metrics.d.ts.map +1 -1
- package/dist/ai-service/llm/context-v2/context-metrics.js +52 -1
- package/dist/ai-service/llm/context-v2/context-metrics.js.map +1 -1
- package/dist/ai-service/llm/context-v2/context.d.ts +27 -3
- package/dist/ai-service/llm/context-v2/context.d.ts.map +1 -1
- package/dist/ai-service/llm/context-v2/context.js +107 -10
- package/dist/ai-service/llm/context-v2/context.js.map +1 -1
- package/dist/ai-service/llm/context-v2/manager.d.ts +66 -0
- package/dist/ai-service/llm/context-v2/manager.d.ts.map +1 -1
- package/dist/ai-service/llm/context-v2/manager.js +194 -2
- package/dist/ai-service/llm/context-v2/manager.js.map +1 -1
- package/dist/ai-service/llm/context-v2/storage/event-store.d.ts +31 -5
- package/dist/ai-service/llm/context-v2/storage/event-store.d.ts.map +1 -1
- package/dist/ai-service/llm/context-v2/storage/jsonl-event-store.d.ts +30 -9
- package/dist/ai-service/llm/context-v2/storage/jsonl-event-store.d.ts.map +1 -1
- package/dist/ai-service/llm/context-v2/storage/jsonl-event-store.js +96 -13
- package/dist/ai-service/llm/context-v2/storage/jsonl-event-store.js.map +1 -1
- package/dist/ai-service/llm/context-v2/storage/legacy-context-adoption.d.ts +46 -0
- package/dist/ai-service/llm/context-v2/storage/legacy-context-adoption.d.ts.map +1 -0
- package/dist/ai-service/llm/context-v2/storage/legacy-context-adoption.js +240 -0
- package/dist/ai-service/llm/context-v2/storage/legacy-context-adoption.js.map +1 -0
- package/dist/ai-service/llm/context-v2/storage/local.d.ts +1 -1
- package/dist/ai-service/llm/context-v2/storage/local.d.ts.map +1 -1
- package/dist/ai-service/llm/context-v2/storage/local.js +3 -2
- package/dist/ai-service/llm/context-v2/storage/local.js.map +1 -1
- package/dist/ai-service/llm/context-v2/types.d.ts +5 -1
- package/dist/ai-service/llm/context-v2/types.d.ts.map +1 -1
- package/dist/ai-service/llm/context-v2/types.js.map +1 -1
- package/dist/ai-service/llm/stream/config.d.ts +4 -3
- package/dist/ai-service/llm/stream/config.d.ts.map +1 -1
- package/dist/ai-service/llm/stream/config.js.map +1 -1
- package/dist/ai-service/llm/stream/idle-monitor.d.ts +37 -4
- package/dist/ai-service/llm/stream/idle-monitor.d.ts.map +1 -1
- package/dist/ai-service/llm/stream/idle-monitor.js +38 -3
- package/dist/ai-service/llm/stream/idle-monitor.js.map +1 -1
- package/dist/ai-service/policy-agent-metrics.d.ts +18 -0
- package/dist/ai-service/policy-agent-metrics.d.ts.map +1 -0
- package/dist/ai-service/policy-agent-metrics.js +99 -0
- package/dist/ai-service/policy-agent-metrics.js.map +1 -0
- package/dist/ai-service/state-machine/clark-fsm.d.ts +9 -0
- package/dist/ai-service/state-machine/clark-fsm.d.ts.map +1 -1
- package/dist/ai-service/state-machine/helpers/prompt-request-metrics.d.ts +9 -0
- package/dist/ai-service/state-machine/helpers/prompt-request-metrics.d.ts.map +1 -1
- package/dist/ai-service/state-machine/helpers/prompt-request-metrics.js +27 -0
- package/dist/ai-service/state-machine/helpers/prompt-request-metrics.js.map +1 -1
- package/dist/ai-service/tasks/factory.d.ts +7 -0
- package/dist/ai-service/tasks/factory.d.ts.map +1 -1
- package/dist/ai-service/tasks/factory.js +5 -0
- package/dist/ai-service/tasks/factory.js.map +1 -1
- package/dist/ai-service/tasks/task-store.d.ts +11 -1
- package/dist/ai-service/tasks/task-store.d.ts.map +1 -1
- package/dist/ai-service/tasks/task-store.js +104 -29
- package/dist/ai-service/tasks/task-store.js.map +1 -1
- package/dist/ai-service/tasks/types.d.ts +9 -1
- package/dist/ai-service/tasks/types.d.ts.map +1 -1
- package/dist/extract-api-integrations.d.ts +76 -0
- package/dist/extract-api-integrations.d.ts.map +1 -1
- package/dist/extract-api-integrations.js +428 -109
- package/dist/extract-api-integrations.js.map +1 -1
- package/dist/file-sync-vite-plugin.d.ts +1 -1
- package/dist/file-sync-vite-plugin.d.ts.map +1 -1
- package/dist/file-sync-vite-plugin.js +42 -79
- package/dist/file-sync-vite-plugin.js.map +1 -1
- package/dist/file-system-helpers.d.ts +1 -1
- package/dist/file-system-helpers.d.ts.map +1 -1
- package/dist/file-system-helpers.js +1 -0
- package/dist/file-system-helpers.js.map +1 -1
- package/dist/git-auth-state.d.ts +4 -0
- package/dist/git-auth-state.d.ts.map +1 -0
- package/dist/git-auth-state.js +25 -0
- package/dist/git-auth-state.js.map +1 -0
- package/dist/git-service/checkpoint-commit-metrics.d.ts +2 -0
- package/dist/git-service/checkpoint-commit-metrics.d.ts.map +1 -0
- package/dist/git-service/checkpoint-commit-metrics.js +15 -0
- package/dist/git-service/checkpoint-commit-metrics.js.map +1 -0
- package/dist/git-service/checkpoint-committer.d.ts +22 -0
- package/dist/git-service/checkpoint-committer.d.ts.map +1 -0
- package/dist/git-service/checkpoint-committer.js +91 -0
- package/dist/git-service/checkpoint-committer.js.map +1 -0
- package/dist/git-service/commit-live-branch.d.ts +17 -0
- package/dist/git-service/commit-live-branch.d.ts.map +1 -0
- package/dist/git-service/commit-live-branch.js +28 -0
- package/dist/git-service/commit-live-branch.js.map +1 -0
- package/dist/git-service/provider-workflow-files.d.ts +12 -0
- package/dist/git-service/provider-workflow-files.d.ts.map +1 -0
- package/dist/git-service/provider-workflow-files.js +36 -0
- package/dist/git-service/provider-workflow-files.js.map +1 -0
- package/dist/plugin-options.d.ts +8 -0
- package/dist/plugin-options.d.ts.map +1 -1
- package/dist/plugin-options.js.map +1 -1
- package/dist/policy-gate-runner.d.ts.map +1 -1
- package/dist/policy-gate-runner.js +7 -9
- package/dist/policy-gate-runner.js.map +1 -1
- package/dist/server-rpc/client.d.ts.map +1 -1
- package/dist/server-rpc/client.js +2 -0
- package/dist/server-rpc/client.js.map +1 -1
- package/dist/server-rpc/index.d.ts +43 -1
- package/dist/server-rpc/index.d.ts.map +1 -1
- package/dist/server-rpc/index.js +143 -5
- package/dist/server-rpc/index.js.map +1 -1
- package/dist/server-rpc/request-abort-context.d.ts +3 -0
- package/dist/server-rpc/request-abort-context.d.ts.map +1 -0
- package/dist/server-rpc/request-abort-context.js +23 -0
- package/dist/server-rpc/request-abort-context.js.map +1 -0
- package/dist/server-rpc/rpc-invalidate-metrics.d.ts +20 -0
- package/dist/server-rpc/rpc-invalidate-metrics.d.ts.map +1 -0
- package/dist/server-rpc/rpc-invalidate-metrics.js +86 -0
- package/dist/server-rpc/rpc-invalidate-metrics.js.map +1 -0
- package/dist/socket-manager.d.ts.map +1 -1
- package/dist/socket-manager.js +21 -60
- package/dist/socket-manager.js.map +1 -1
- package/dist/sync-service/index.d.ts +26 -2
- package/dist/sync-service/index.d.ts.map +1 -1
- package/dist/sync-service/index.js +74 -37
- package/dist/sync-service/index.js.map +1 -1
- package/package.json +9 -8
package/dist/server-rpc/index.js
CHANGED
|
@@ -1,5 +1,18 @@
|
|
|
1
1
|
import { getErrorMeta } from "../util/logger.js";
|
|
2
2
|
import { connectToISocketRPCServer, } from "./client.js";
|
|
3
|
+
import { runWithRequestAbortSignal } from "./request-abort-context.js";
|
|
4
|
+
import { recordRpcInvalidate, } from "./rpc-invalidate-metrics.js";
|
|
5
|
+
/** Socket error code for "the server never answered this request". */
|
|
6
|
+
const NO_RESPONSE_TIMEOUT_CODE = 7;
|
|
7
|
+
/** Close reason recorded on requests abandoned by a forced shutdown. */
|
|
8
|
+
const FORCED_SHUTDOWN_REASON = "rpc client forced shutdown";
|
|
9
|
+
export function isNoResponseTimeoutError(error) {
|
|
10
|
+
return (typeof error === "object" &&
|
|
11
|
+
error !== null &&
|
|
12
|
+
"code" in error &&
|
|
13
|
+
typeof error.code === "number" &&
|
|
14
|
+
error.code === NO_RESPONSE_TIMEOUT_CODE);
|
|
15
|
+
}
|
|
3
16
|
export class AutoConnectingRpcClient {
|
|
4
17
|
superblocksBaseUrl;
|
|
5
18
|
authToken;
|
|
@@ -13,6 +26,12 @@ export class AutoConnectingRpcClient {
|
|
|
13
26
|
_connectEpoch = 0;
|
|
14
27
|
_activeOperations = 0;
|
|
15
28
|
_socketCloseCode;
|
|
29
|
+
/**
|
|
30
|
+
* Client currently inside `closeWithTimeout` after `_rpcClient` was nulled.
|
|
31
|
+
* Lets an invalidate that races a plain close() still reject pendings — a
|
|
32
|
+
* plain `ISocket.close()` uses INTENTIONAL_CLOSE_CODE and does not.
|
|
33
|
+
*/
|
|
34
|
+
_closingClient = null;
|
|
16
35
|
constructor(superblocksBaseUrl, authToken, _tracer, tokenManager, _logger) {
|
|
17
36
|
this.superblocksBaseUrl = superblocksBaseUrl;
|
|
18
37
|
this.authToken = authToken;
|
|
@@ -127,7 +146,7 @@ export class AutoConnectingRpcClient {
|
|
|
127
146
|
/**
|
|
128
147
|
* Executes an RPC operations with lifecycle management.
|
|
129
148
|
*/
|
|
130
|
-
async call(operation) {
|
|
149
|
+
async call(operation, options) {
|
|
131
150
|
// Resolve the client first (which itself waits through any in-flight
|
|
132
151
|
// close()/reconnect). We only claim an active-operation slot once we hold a
|
|
133
152
|
// live client, so waiting on close() never blocks doClose()'s drain loop —
|
|
@@ -135,13 +154,72 @@ export class AutoConnectingRpcClient {
|
|
|
135
154
|
const client = await this.getRpcClient();
|
|
136
155
|
this._activeOperations++;
|
|
137
156
|
try {
|
|
138
|
-
return await operation(client);
|
|
157
|
+
return await runWithRequestAbortSignal(options?.signal, () => operation(client));
|
|
158
|
+
}
|
|
159
|
+
catch (error) {
|
|
160
|
+
if (isNoResponseTimeoutError(error)) {
|
|
161
|
+
this.invalidate("no_response_timeout", client);
|
|
162
|
+
}
|
|
163
|
+
throw error;
|
|
139
164
|
}
|
|
140
165
|
finally {
|
|
141
166
|
this._activeOperations--;
|
|
142
167
|
}
|
|
143
168
|
}
|
|
169
|
+
/**
|
|
170
|
+
* Force-close the shared RPC socket so the next call() reconnects, rejecting
|
|
171
|
+
* whatever was still pending on it.
|
|
172
|
+
* When `client` is provided, only acts if that handle is still one we own —
|
|
173
|
+
* the active socket, or one a concurrent close is currently tearing down.
|
|
174
|
+
* Anything else is a socket a reconnect already replaced, and closing it
|
|
175
|
+
* would take down the healthy replacement instead.
|
|
176
|
+
*/
|
|
177
|
+
invalidate(reason, client) {
|
|
178
|
+
if (client !== undefined &&
|
|
179
|
+
this._rpcClient !== client &&
|
|
180
|
+
this._closingClient !== client) {
|
|
181
|
+
recordRpcInvalidate({ reason, outcome: "skipped_stale_client" });
|
|
182
|
+
this.warnStructured("[rpc-client] skipping invalidate; timed-out client already replaced", { "rpc.invalidate.reason": reason });
|
|
183
|
+
return;
|
|
184
|
+
}
|
|
185
|
+
recordRpcInvalidate({ reason, outcome: "invalidated" });
|
|
186
|
+
this.warnStructured("[rpc-client] invalidating RPC client", {
|
|
187
|
+
"rpc.invalidate.reason": reason,
|
|
188
|
+
});
|
|
189
|
+
void this.closeInternal(reason).catch((error) => {
|
|
190
|
+
this.getLogger().warn(`[rpc-client] invalidate close failed; will reconnect lazily on next call`, getErrorMeta(error));
|
|
191
|
+
});
|
|
192
|
+
}
|
|
193
|
+
warnStructured(message, attributes) {
|
|
194
|
+
const logger = this.getLogger();
|
|
195
|
+
if (logger.warnStructured) {
|
|
196
|
+
logger.warnStructured(message, attributes);
|
|
197
|
+
return;
|
|
198
|
+
}
|
|
199
|
+
logger.warn(message, attributes);
|
|
200
|
+
}
|
|
144
201
|
close() {
|
|
202
|
+
return this.closeInternal();
|
|
203
|
+
}
|
|
204
|
+
/**
|
|
205
|
+
* @param rejectPendingReason when set, the socket is torn down with
|
|
206
|
+
* `closeAndRejectPendingRequests` instead of `close()`. See {@link doClose}.
|
|
207
|
+
*/
|
|
208
|
+
closeInternal(rejectPendingReason) {
|
|
209
|
+
if (this._closePromise && rejectPendingReason !== undefined) {
|
|
210
|
+
// A close() is already running — most likely a token-refresh reconnect,
|
|
211
|
+
// which intentionally leaves pending requests alone. Joining it would
|
|
212
|
+
// silently drop this invalidation's whole point, so reject here instead.
|
|
213
|
+
// The in-flight close may already have nulled `_rpcClient` before awaiting
|
|
214
|
+
// client.close(); rejectPendingRequests falls back to `_closingClient` so
|
|
215
|
+
// pendings still settle (plain close uses INTENTIONAL_CLOSE_CODE and does
|
|
216
|
+
// not reject them). The promise returned below belongs to that other close
|
|
217
|
+
// and deliberately does not wait on this: the rejection lands once the
|
|
218
|
+
// handle is read, and callers only need the socket gone.
|
|
219
|
+
void this.rejectPendingRequests(rejectPendingReason).catch((error) => {
|
|
220
|
+
this.getLogger().warn(`[rpc-client] rejecting pending requests failed; reconnecting on next call`, getErrorMeta(error));
|
|
221
|
+
});
|
|
222
|
+
}
|
|
145
223
|
if (!this._closePromise) {
|
|
146
224
|
// Advance the epoch and abandon any in-flight connect reference: a new
|
|
147
225
|
// getRpcClient() after this close starts a fresh connect (with the
|
|
@@ -149,22 +227,48 @@ export class AutoConnectingRpcClient {
|
|
|
149
227
|
// The abandoned connect self-discards its socket via the epoch check.
|
|
150
228
|
this._connectEpoch++;
|
|
151
229
|
this._connectPromise = null;
|
|
152
|
-
this._closePromise = this.doClose().finally(() => {
|
|
230
|
+
this._closePromise = this.doClose(rejectPendingReason).finally(() => {
|
|
153
231
|
this._closePromise = null;
|
|
154
232
|
});
|
|
155
233
|
}
|
|
156
234
|
return this._closePromise;
|
|
157
235
|
}
|
|
158
|
-
|
|
236
|
+
/**
|
|
237
|
+
* @param rejectPendingReason set by the invalidate path. `ISocket.close()`
|
|
238
|
+
* closes with `INTENTIONAL_CLOSE_CODE`, and the socket's own close listener
|
|
239
|
+
* deliberately skips its reject-pending loop for that code — so a plain
|
|
240
|
+
* close() leaves every request already in flight (facts, chat load, lock
|
|
241
|
+
* service) to expire on its own 5-minute `noResponseTimeout`, which is the
|
|
242
|
+
* multi-minute wedge this teardown exists to remove.
|
|
243
|
+
* `closeAndRejectPendingRequests` settles them now. Token refresh and
|
|
244
|
+
* shutdown keep the plain close so in-flight calls on a healthy socket can
|
|
245
|
+
* finish; anything that fails to drain is rejected below regardless.
|
|
246
|
+
*/
|
|
247
|
+
async doClose(rejectPendingReason) {
|
|
159
248
|
this._isShuttingDown = true;
|
|
160
249
|
// Wait for active operations to finish with timeout
|
|
161
250
|
const maxWaitTime = 5_000;
|
|
162
251
|
const startTime = Date.now();
|
|
252
|
+
if (rejectPendingReason !== undefined) {
|
|
253
|
+
// Reject before draining, not after: on a half-open socket the active
|
|
254
|
+
// operations are exactly the ones that will never settle, so draining
|
|
255
|
+
// first would burn the full 5s budget and then close underneath them.
|
|
256
|
+
// Rejecting first is also what lets the loop below drain at all.
|
|
257
|
+
await this.rejectPendingRequests(rejectPendingReason);
|
|
258
|
+
}
|
|
163
259
|
while (this._activeOperations > 0 && Date.now() - startTime < maxWaitTime) {
|
|
164
260
|
await new Promise((resolve) => setTimeout(resolve, 100));
|
|
165
261
|
}
|
|
166
262
|
if (this._activeOperations > 0) {
|
|
167
263
|
this.getLogger().warn(`[rpc-client] Forced shutdown of RPC client with ${this._activeOperations} active operations`);
|
|
264
|
+
// Reaching the deadline means we are about to close a socket that still
|
|
265
|
+
// has work on it. Operations on a healthy socket drain inside the loop
|
|
266
|
+
// above, so the survivors are wedged ones — most often facts or lock
|
|
267
|
+
// calls, which carry no abort signal and no caller-side bound. A plain
|
|
268
|
+
// close() would leave them unreachable (INTENTIONAL_CLOSE_CODE skips the
|
|
269
|
+
// socket's own reject loop) until their 5-minute no-response timeout, so
|
|
270
|
+
// settle them here regardless of how this close was requested.
|
|
271
|
+
await this.rejectPendingRequests(FORCED_SHUTDOWN_REASON);
|
|
168
272
|
}
|
|
169
273
|
if (this._rpcClient) {
|
|
170
274
|
const client = this._rpcClient;
|
|
@@ -173,11 +277,45 @@ export class AutoConnectingRpcClient {
|
|
|
173
277
|
// socket close() that hangs would otherwise wedge every subsequent RPC
|
|
174
278
|
// call indefinitely. Bounding it degrades a stuck socket to a fresh
|
|
175
279
|
// reconnect on the next call() instead of a permanent hang.
|
|
280
|
+
// Stash on `_closingClient` so a concurrent invalidate can still reject
|
|
281
|
+
// pendings — plain close() uses INTENTIONAL_CLOSE_CODE and will not.
|
|
176
282
|
this._rpcClient = null;
|
|
177
|
-
|
|
283
|
+
this._closingClient = client;
|
|
284
|
+
try {
|
|
285
|
+
await this.closeWithTimeout(client, maxWaitTime);
|
|
286
|
+
}
|
|
287
|
+
finally {
|
|
288
|
+
if (this._closingClient === client) {
|
|
289
|
+
this._closingClient = null;
|
|
290
|
+
}
|
|
291
|
+
}
|
|
178
292
|
}
|
|
179
293
|
this._isShuttingDown = false;
|
|
180
294
|
}
|
|
295
|
+
/**
|
|
296
|
+
* Drop the active (or in-flight-closing) handle and settle everything pending
|
|
297
|
+
* on it now. No-op when there is no client to reject on.
|
|
298
|
+
*/
|
|
299
|
+
async rejectPendingRequests(reason) {
|
|
300
|
+
const client = this._rpcClient ?? this._closingClient;
|
|
301
|
+
if (!client) {
|
|
302
|
+
return;
|
|
303
|
+
}
|
|
304
|
+
if (this._rpcClient === client) {
|
|
305
|
+
this._rpcClient = null;
|
|
306
|
+
}
|
|
307
|
+
if (this._closingClient === client) {
|
|
308
|
+
this._closingClient = null;
|
|
309
|
+
}
|
|
310
|
+
try {
|
|
311
|
+
client.closeAndRejectPendingRequests(reason);
|
|
312
|
+
}
|
|
313
|
+
catch (error) {
|
|
314
|
+
this.getLogger().warn(`[rpc-client] rejecting pending requests failed; closing the socket instead`, getErrorMeta(error));
|
|
315
|
+
// The handle is already dropped, so nothing else will close this socket.
|
|
316
|
+
await this.closeWithTimeout(client, 5_000);
|
|
317
|
+
}
|
|
318
|
+
}
|
|
181
319
|
async closeWithTimeout(client, timeoutMs) {
|
|
182
320
|
let timer;
|
|
183
321
|
try {
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/server-rpc/index.ts"],"names":[],"mappings":"AAIA,OAAO,EAAE,YAAY,EAAe,MAAM,mBAAmB,CAAC;AAC9D,OAAO,EACL,yBAAyB,GAE1B,MAAM,aAAa,CAAC;
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/server-rpc/index.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"request-abort-context.d.ts","sourceRoot":"","sources":["../../src/server-rpc/request-abort-context.ts"],"names":[],"mappings":"AAoBA,wBAAgB,yBAAyB,CAAC,CAAC,EACzC,MAAM,EAAE,WAAW,GAAG,SAAS,EAC/B,EAAE,EAAE,MAAM,CAAC,GACV,CAAC,CAEH;AAED,wBAAgB,qBAAqB,IAAI,WAAW,GAAG,SAAS,CAE/D"}
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Threads a caller's AbortSignal to the socket without putting
|
|
3
|
+
* `node:async_hooks` in `@superblocksteam/shared` (browser bundles import it).
|
|
4
|
+
*
|
|
5
|
+
* Contract this depends on: `ISocket.request()` must read its `getAbortSignal`
|
|
6
|
+
* callback synchronously, inside the same async context as the operation passed
|
|
7
|
+
* to `AutoConnectingRpcClient.call`. It does today — the read happens in the
|
|
8
|
+
* `new Promise` executor. If the socket ever defers it to a later tick,
|
|
9
|
+
* `getStore()` returns undefined and cancellation silently stops working;
|
|
10
|
+
* `server-rpc/index.test.ts` ("call({ signal }) cancels an in-flight RPC when
|
|
11
|
+
* aborted") drives a real ISocket and fails if that happens. A request made
|
|
12
|
+
* outside any `runWithRequestAbortSignal` scope simply gets `undefined`, which
|
|
13
|
+
* the socket treats as "no signal".
|
|
14
|
+
*/
|
|
15
|
+
import { AsyncLocalStorage } from "node:async_hooks";
|
|
16
|
+
const requestAbortSignalStorage = new AsyncLocalStorage();
|
|
17
|
+
export function runWithRequestAbortSignal(signal, fn) {
|
|
18
|
+
return requestAbortSignalStorage.run(signal, fn);
|
|
19
|
+
}
|
|
20
|
+
export function getRequestAbortSignal() {
|
|
21
|
+
return requestAbortSignalStorage.getStore();
|
|
22
|
+
}
|
|
23
|
+
//# sourceMappingURL=request-abort-context.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"request-abort-context.js","sourceRoot":"","sources":["../../src/server-rpc/request-abort-context.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;GAaG;AACH,OAAO,EAAE,iBAAiB,EAAE,MAAM,kBAAkB,CAAC;AAErD,MAAM,yBAAyB,GAAG,IAAI,iBAAiB,EAEpD,CAAC;AAEJ,MAAM,UAAU,yBAAyB,CACvC,MAA+B,EAC/B,EAAW;IAEX,OAAO,yBAAyB,CAAC,GAAG,CAAC,MAAM,EAAE,EAAE,CAAC,CAAC;AACnD,CAAC;AAED,MAAM,UAAU,qBAAqB;IACnC,OAAO,yBAAyB,CAAC,QAAQ,EAAE,CAAC;AAC9C,CAAC"}
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* What made the client suspect the socket was dead: `no_response_timeout` is
|
|
3
|
+
* the socket's own no-response error; `chat_push_timeout` is the local
|
|
4
|
+
* per-push bound in `ChatSessionStore.PUSH_TIMEOUT_MS` elapsing first.
|
|
5
|
+
*/
|
|
6
|
+
export declare const RPC_INVALIDATE_REASONS: readonly ["chat_push_timeout", "no_response_timeout"];
|
|
7
|
+
export type RpcInvalidateReason = (typeof RPC_INVALIDATE_REASONS)[number];
|
|
8
|
+
/**
|
|
9
|
+
* `invalidated` means the socket was torn down; `skipped_stale_client` means a
|
|
10
|
+
* concurrent reconnect had already replaced the handle the timed-out call used,
|
|
11
|
+
* so the healthy replacement was left alone.
|
|
12
|
+
*/
|
|
13
|
+
export declare const RPC_INVALIDATE_OUTCOMES: readonly ["invalidated", "skipped_stale_client"];
|
|
14
|
+
export type RpcInvalidateOutcome = (typeof RPC_INVALIDATE_OUTCOMES)[number];
|
|
15
|
+
export declare function recordRpcInvalidate(input: {
|
|
16
|
+
reason: RpcInvalidateReason;
|
|
17
|
+
outcome: RpcInvalidateOutcome;
|
|
18
|
+
}): void;
|
|
19
|
+
export declare function _resetRpcInvalidateMetricsForTesting(): void;
|
|
20
|
+
//# sourceMappingURL=rpc-invalidate-metrics.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"rpc-invalidate-metrics.d.ts","sourceRoot":"","sources":["../../src/server-rpc/rpc-invalidate-metrics.ts"],"names":[],"mappings":"AAyBA;;;;GAIG;AACH,eAAO,MAAM,sBAAsB,uDAGzB,CAAC;AACX,MAAM,MAAM,mBAAmB,GAAG,CAAC,OAAO,sBAAsB,CAAC,CAAC,MAAM,CAAC,CAAC;AAE1E;;;;GAIG;AACH,eAAO,MAAM,uBAAuB,kDAG1B,CAAC;AACX,MAAM,MAAM,oBAAoB,GAAG,CAAC,OAAO,uBAAuB,CAAC,CAAC,MAAM,CAAC,CAAC;AAqD5E,wBAAgB,mBAAmB,CAAC,KAAK,EAAE;IACzC,MAAM,EAAE,mBAAmB,CAAC;IAC5B,OAAO,EAAE,oBAAoB,CAAC;CAC/B,GAAG,IAAI,CAEP;AAED,wBAAgB,oCAAoC,IAAI,IAAI,CAE3D"}
|
|
@@ -0,0 +1,86 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Shared-socket invalidation metrics.
|
|
3
|
+
*
|
|
4
|
+
* Half-open recovery is self-healing: when it works, nothing shows up in a
|
|
5
|
+
* customer report and nothing shows up in a log-based monitor except a single
|
|
6
|
+
* warn line. This counter is the signal that says the recovery path is firing
|
|
7
|
+
* in prod at all, and how often each trigger fires — which is exactly what was
|
|
8
|
+
* missing while a wedged socket sat there for sixteen minutes.
|
|
9
|
+
*
|
|
10
|
+
* Wiring follows `chat-push-metrics.ts`: the meter resolves lazily from the
|
|
11
|
+
* OTel global and the instrument re-binds when the global MeterProvider
|
|
12
|
+
* changes (tests swap providers per case). Zero-config process singleton — no
|
|
13
|
+
* DI plumbing.
|
|
14
|
+
*
|
|
15
|
+
* Metric:
|
|
16
|
+
*
|
|
17
|
+
* - `superblocks.clark.rpc.invalidations` counter
|
|
18
|
+
* {rpc.invalidate.reason, rpc.invalidate.outcome}
|
|
19
|
+
*
|
|
20
|
+
* Cardinality budget: reason ≤ 2 × outcome ≤ 2 → 4 worst-case series. Both
|
|
21
|
+
* labels are compile-time closed unions supplied by Superblocks-owned call
|
|
22
|
+
* sites (never derived from user input or error text).
|
|
23
|
+
*/
|
|
24
|
+
import { metrics } from "@opentelemetry/api";
|
|
25
|
+
/**
|
|
26
|
+
* What made the client suspect the socket was dead: `no_response_timeout` is
|
|
27
|
+
* the socket's own no-response error; `chat_push_timeout` is the local
|
|
28
|
+
* per-push bound in `ChatSessionStore.PUSH_TIMEOUT_MS` elapsing first.
|
|
29
|
+
*/
|
|
30
|
+
export const RPC_INVALIDATE_REASONS = [
|
|
31
|
+
"chat_push_timeout",
|
|
32
|
+
"no_response_timeout",
|
|
33
|
+
];
|
|
34
|
+
/**
|
|
35
|
+
* `invalidated` means the socket was torn down; `skipped_stale_client` means a
|
|
36
|
+
* concurrent reconnect had already replaced the handle the timed-out call used,
|
|
37
|
+
* so the healthy replacement was left alone.
|
|
38
|
+
*/
|
|
39
|
+
export const RPC_INVALIDATE_OUTCOMES = [
|
|
40
|
+
"invalidated",
|
|
41
|
+
"skipped_stale_client",
|
|
42
|
+
];
|
|
43
|
+
const METER_NAME = "superblocks.clark.rpc";
|
|
44
|
+
const METRIC_INVALIDATIONS = "superblocks.clark.rpc.invalidations";
|
|
45
|
+
const ATTR_REASON = "rpc.invalidate.reason";
|
|
46
|
+
const ATTR_OUTCOME = "rpc.invalidate.outcome";
|
|
47
|
+
class RpcInvalidateMetrics {
|
|
48
|
+
cachedMeter;
|
|
49
|
+
cachedCounter;
|
|
50
|
+
/**
|
|
51
|
+
* Lazy instrument factory. Re-creates the counter when the global
|
|
52
|
+
* MeterProvider changes (a stale instrument bound to a replaced provider
|
|
53
|
+
* silently drops data).
|
|
54
|
+
*/
|
|
55
|
+
getCounter() {
|
|
56
|
+
const meter = metrics.getMeter(METER_NAME);
|
|
57
|
+
if (meter === this.cachedMeter && this.cachedCounter) {
|
|
58
|
+
return this.cachedCounter;
|
|
59
|
+
}
|
|
60
|
+
this.cachedMeter = meter;
|
|
61
|
+
this.cachedCounter = meter.createCounter(METRIC_INVALIDATIONS, {
|
|
62
|
+
description: "Times the live-edit → server RPC socket was force-closed because it looked half-open.",
|
|
63
|
+
unit: "{invalidation}",
|
|
64
|
+
});
|
|
65
|
+
return this.cachedCounter;
|
|
66
|
+
}
|
|
67
|
+
record(input) {
|
|
68
|
+
this.getCounter().add(1, {
|
|
69
|
+
[ATTR_REASON]: input.reason,
|
|
70
|
+
[ATTR_OUTCOME]: input.outcome,
|
|
71
|
+
});
|
|
72
|
+
}
|
|
73
|
+
/** Drop cached instrument bindings (tests swap the global provider). */
|
|
74
|
+
_resetForTesting() {
|
|
75
|
+
this.cachedMeter = undefined;
|
|
76
|
+
this.cachedCounter = undefined;
|
|
77
|
+
}
|
|
78
|
+
}
|
|
79
|
+
const rpcInvalidateMetrics = new RpcInvalidateMetrics();
|
|
80
|
+
export function recordRpcInvalidate(input) {
|
|
81
|
+
rpcInvalidateMetrics.record(input);
|
|
82
|
+
}
|
|
83
|
+
export function _resetRpcInvalidateMetricsForTesting() {
|
|
84
|
+
rpcInvalidateMetrics._resetForTesting();
|
|
85
|
+
}
|
|
86
|
+
//# sourceMappingURL=rpc-invalidate-metrics.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"rpc-invalidate-metrics.js","sourceRoot":"","sources":["../../src/server-rpc/rpc-invalidate-metrics.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;GAsBG;AACH,OAAO,EAAE,OAAO,EAAc,MAAM,oBAAoB,CAAC;AAEzD;;;;GAIG;AACH,MAAM,CAAC,MAAM,sBAAsB,GAAG;IACpC,mBAAmB;IACnB,qBAAqB;CACb,CAAC;AAGX;;;;GAIG;AACH,MAAM,CAAC,MAAM,uBAAuB,GAAG;IACrC,aAAa;IACb,sBAAsB;CACd,CAAC;AAGX,MAAM,UAAU,GAAG,uBAAuB,CAAC;AAE3C,MAAM,oBAAoB,GAAG,qCAAqC,CAAC;AAEnE,MAAM,WAAW,GAAG,uBAAuB,CAAC;AAC5C,MAAM,YAAY,GAAG,wBAAwB,CAAC;AAI9C,MAAM,oBAAoB;IAChB,WAAW,CAAoB;IAC/B,aAAa,CAAsB;IAE3C;;;;OAIG;IACK,UAAU;QAChB,MAAM,KAAK,GAAG,OAAO,CAAC,QAAQ,CAAC,UAAU,CAAC,CAAC;QAC3C,IAAI,KAAK,KAAK,IAAI,CAAC,WAAW,IAAI,IAAI,CAAC,aAAa,EAAE,CAAC;YACrD,OAAO,IAAI,CAAC,aAAa,CAAC;QAC5B,CAAC;QACD,IAAI,CAAC,WAAW,GAAG,KAAK,CAAC;QACzB,IAAI,CAAC,aAAa,GAAG,KAAK,CAAC,aAAa,CAAC,oBAAoB,EAAE;YAC7D,WAAW,EACT,uFAAuF;YACzF,IAAI,EAAE,gBAAgB;SACvB,CAAC,CAAC;QACH,OAAO,IAAI,CAAC,aAAa,CAAC;IAC5B,CAAC;IAED,MAAM,CAAC,KAGN;QACC,IAAI,CAAC,UAAU,EAAE,CAAC,GAAG,CAAC,CAAC,EAAE;YACvB,CAAC,WAAW,CAAC,EAAE,KAAK,CAAC,MAAM;YAC3B,CAAC,YAAY,CAAC,EAAE,KAAK,CAAC,OAAO;SAC9B,CAAC,CAAC;IACL,CAAC;IAED,wEAAwE;IACxE,gBAAgB;QACd,IAAI,CAAC,WAAW,GAAG,SAAS,CAAC;QAC7B,IAAI,CAAC,aAAa,GAAG,SAAS,CAAC;IACjC,CAAC;CACF;AAED,MAAM,oBAAoB,GAAG,IAAI,oBAAoB,EAAE,CAAC;AAExD,MAAM,UAAU,mBAAmB,CAAC,KAGnC;IACC,oBAAoB,CAAC,MAAM,CAAC,KAAK,CAAC,CAAC;AACrC,CAAC;AAED,MAAM,UAAU,oCAAoC;IAClD,oBAAoB,CAAC,gBAAgB,EAAE,CAAC;AAC1C,CAAC"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"socket-manager.d.ts","sourceRoot":"","sources":["../src/socket-manager.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,IAAI,MAAM,WAAW,CAAC;AAKlC,OAAO,KAAK,EAAE,MAAM,EAAE,MAAM,oBAAoB,CAAC;AAIjD,OAAO,KAAK,EAGV,mBAAmB,EACnB,oBAAoB,EAGrB,MAAM,uCAAuC,CAAC;AAC/C,OAAO,EAKL,kBAAkB,EAEnB,MAAM,yBAAyB,CAAC;AACjC,OAAO,KAAK,EAEV,aAAa,EAEd,MAAM,yBAAyB,CAAC;AAGjC,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,uBAAuB,CAAC;AAGvD,OAAO,KAAK,EAAE,iBAAiB,EAAE,MAAM,0BAA0B,CAAC;
|
|
1
|
+
{"version":3,"file":"socket-manager.d.ts","sourceRoot":"","sources":["../src/socket-manager.ts"],"names":[],"mappings":"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"}
|
package/dist/socket-manager.js
CHANGED
|
@@ -6,15 +6,13 @@ import { createISocketClient, DEFAULT_NON_GIT_BRANCH, MAX_SOCKET_PAYLOAD_BYTES,
|
|
|
6
6
|
import { uploadContextToBucketeer } from "./ai-service/context-upload.js";
|
|
7
7
|
import { createSocketRecordingMiddleware } from "./ai-service/recording/recorders/socket-recorder.js";
|
|
8
8
|
import { parseJwt } from "./ai-service/util/parse-jwt.js";
|
|
9
|
+
import { clearGitAuthFailed, isGitAuthFailed, markGitAuthFailed, } from "./git-auth-state.js";
|
|
9
10
|
import { GIT_LOG_FORMAT, parseGitLog } from "./git-log.js";
|
|
10
11
|
import { GIT_OPERATION_BUSY_MESSAGE, } from "./git-operation-lock.js";
|
|
11
12
|
import { assertIncomingLiveLayout } from "./git-service/app-layout-guard.js";
|
|
12
|
-
import {
|
|
13
|
-
import { ensureBitbucketWorkflowFile } from "./git-service/bitbucket-workflow.js";
|
|
14
|
-
import { ensureGithubWorkflowFile } from "./git-service/github-workflow.js";
|
|
15
|
-
import { ensureGitlabWorkflowFile } from "./git-service/gitlab-workflow.js";
|
|
16
|
-
import { GitConflictError, GitAuthError, classifyGitError, } from "./git-service/index.js";
|
|
13
|
+
import { GitConflictError } from "./git-service/index.js";
|
|
17
14
|
import { doesRemoteLiveBranchExist, ensureLiveBranchCheckedOut, pushLiveBranchWithAutoRecreate, rollbackLastCommit, } from "./git-service/live-branch.js";
|
|
15
|
+
import { ensureProviderWorkflowFiles } from "./git-service/provider-workflow-files.js";
|
|
18
16
|
import { getSyncCountsAgainstDefaultBranch } from "./git-service/status-sync.js";
|
|
19
17
|
import { getErrorMeta, getLogger } from "./util/logger.js";
|
|
20
18
|
const SB_WORKTREE_SNAPSHOTS_DIR = join(tmpdir(), "sb-worktree-snapshots");
|
|
@@ -94,15 +92,10 @@ class SocketManager extends TracedEventEmitter {
|
|
|
94
92
|
// fire-and-forget `void activateGitService()`) must not override a manual
|
|
95
93
|
// disconnect.
|
|
96
94
|
let disconnectInProgress = false;
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
}
|
|
102
|
-
};
|
|
103
|
-
const clearRuntimeGitAuthFailed = () => {
|
|
104
|
-
runtimeGitAuthFailed = false;
|
|
105
|
-
};
|
|
95
|
+
// The auth flag behind `remoteAuthFailed` lives outside this handler set
|
|
96
|
+
// because the dev server's own auto-commit pushes to the same remote with
|
|
97
|
+
// the same credential and has to be able to report a rejection too.
|
|
98
|
+
clearGitAuthFailed();
|
|
106
99
|
const getActiveGitService = async () => {
|
|
107
100
|
if (disconnectInProgress) {
|
|
108
101
|
return undefined;
|
|
@@ -132,7 +125,7 @@ class SocketManager extends TracedEventEmitter {
|
|
|
132
125
|
}
|
|
133
126
|
activeGitService = activated;
|
|
134
127
|
if (activeGitService) {
|
|
135
|
-
|
|
128
|
+
clearGitAuthFailed();
|
|
136
129
|
await ensureLiveBranchCheckedOut(activeGitService);
|
|
137
130
|
if (disconnectInProgress) {
|
|
138
131
|
return undefined;
|
|
@@ -368,7 +361,6 @@ class SocketManager extends TracedEventEmitter {
|
|
|
368
361
|
commitId: result.commitId,
|
|
369
362
|
branchName: syncService.branchName,
|
|
370
363
|
appRootDirPath: aiService.appRootDirPath,
|
|
371
|
-
userId: contextId.userId,
|
|
372
364
|
useServerUpload: aiService.isAiFileUploadEnabled,
|
|
373
365
|
superblocksBaseUrl: aiService.superblocksBaseUrl,
|
|
374
366
|
logger: getLogger(),
|
|
@@ -593,45 +585,14 @@ class SocketManager extends TracedEventEmitter {
|
|
|
593
585
|
}
|
|
594
586
|
});
|
|
595
587
|
const resolvedBaseUrl = superblocksBaseUrl || aiService?.superblocksBaseUrl;
|
|
596
|
-
await
|
|
597
|
-
getLogger().warn("[git] gitCommitLocal failed to ensure GitHub workflow file", {
|
|
598
|
-
gitCategory: "setup",
|
|
599
|
-
gitOperation: "ensure-github-workflow-file",
|
|
600
|
-
gitOutcome: "failed",
|
|
601
|
-
...getErrorMeta(error),
|
|
602
|
-
});
|
|
603
|
-
});
|
|
604
|
-
await ensureAzureDevOpsWorkflowFile(readyGitService, resolvedBaseUrl).catch((error) => {
|
|
605
|
-
getLogger().warn("[git] gitCommitLocal failed to ensure Azure DevOps workflow file", {
|
|
606
|
-
gitCategory: "setup",
|
|
607
|
-
gitOperation: "ensure-azure-devops-workflow-file",
|
|
608
|
-
gitOutcome: "failed",
|
|
609
|
-
...getErrorMeta(error),
|
|
610
|
-
});
|
|
611
|
-
});
|
|
612
|
-
await ensureGitlabWorkflowFile(readyGitService, resolvedBaseUrl).catch((error) => {
|
|
613
|
-
getLogger().warn("[git] gitCommitLocal failed to ensure GitLab workflow file", {
|
|
614
|
-
gitCategory: "setup",
|
|
615
|
-
gitOperation: "ensure-gitlab-workflow-file",
|
|
616
|
-
gitOutcome: "failed",
|
|
617
|
-
...getErrorMeta(error),
|
|
618
|
-
});
|
|
619
|
-
});
|
|
620
|
-
await ensureBitbucketWorkflowFile(readyGitService, resolvedBaseUrl).catch((error) => {
|
|
621
|
-
getLogger().warn("[git] gitCommitLocal failed to ensure Bitbucket workflow file", {
|
|
622
|
-
gitCategory: "setup",
|
|
623
|
-
gitOperation: "ensure-bitbucket-workflow-file",
|
|
624
|
-
gitOutcome: "failed",
|
|
625
|
-
...getErrorMeta(error),
|
|
626
|
-
});
|
|
627
|
-
});
|
|
588
|
+
await ensureProviderWorkflowFiles(readyGitService, resolvedBaseUrl);
|
|
628
589
|
await readyGitService.add(".");
|
|
629
590
|
const result = await readyGitService.commit(request.message);
|
|
630
591
|
return { sha: result.commit };
|
|
631
592
|
}
|
|
632
593
|
catch (error) {
|
|
633
594
|
getLogger().error("[git] gitCommitLocal failed", getErrorMeta(error));
|
|
634
|
-
|
|
595
|
+
markGitAuthFailed(error);
|
|
635
596
|
throw error;
|
|
636
597
|
}
|
|
637
598
|
}),
|
|
@@ -644,11 +605,11 @@ class SocketManager extends TracedEventEmitter {
|
|
|
644
605
|
throw new Error("Git is not configured for this application");
|
|
645
606
|
}
|
|
646
607
|
await pushLiveBranchWithAutoRecreate(readyGitService);
|
|
647
|
-
|
|
608
|
+
clearGitAuthFailed();
|
|
648
609
|
}
|
|
649
610
|
catch (error) {
|
|
650
611
|
getLogger().error("[git] gitPushLiveBranch failed", getErrorMeta(error));
|
|
651
|
-
|
|
612
|
+
markGitAuthFailed(error);
|
|
652
613
|
throw error;
|
|
653
614
|
}
|
|
654
615
|
}),
|
|
@@ -748,14 +709,14 @@ class SocketManager extends TracedEventEmitter {
|
|
|
748
709
|
conflictedFileCount: conflictedFiles.length,
|
|
749
710
|
conflictedFiles,
|
|
750
711
|
});
|
|
751
|
-
|
|
712
|
+
clearGitAuthFailed();
|
|
752
713
|
return { merged: false, conflictedFiles };
|
|
753
714
|
}
|
|
754
|
-
|
|
715
|
+
clearGitAuthFailed();
|
|
755
716
|
return { merged };
|
|
756
717
|
}
|
|
757
718
|
catch (error) {
|
|
758
|
-
|
|
719
|
+
markGitAuthFailed(error);
|
|
759
720
|
throw error;
|
|
760
721
|
}
|
|
761
722
|
}),
|
|
@@ -807,10 +768,10 @@ class SocketManager extends TracedEventEmitter {
|
|
|
807
768
|
ahead = counts.ahead;
|
|
808
769
|
behind = counts.behind;
|
|
809
770
|
}
|
|
810
|
-
|
|
771
|
+
clearGitAuthFailed();
|
|
811
772
|
}
|
|
812
773
|
catch (fetchErr) {
|
|
813
|
-
|
|
774
|
+
markGitAuthFailed(fetchErr);
|
|
814
775
|
getLogger().warn("[git] gitSyncStatus fetch/revList failed", {
|
|
815
776
|
gitCategory: "status",
|
|
816
777
|
gitOperation: "syncStatus",
|
|
@@ -840,7 +801,7 @@ class SocketManager extends TracedEventEmitter {
|
|
|
840
801
|
hasUncommittedChanges,
|
|
841
802
|
aheadOfDefaultBranch,
|
|
842
803
|
isLiveBranchMissing,
|
|
843
|
-
remoteAuthFailed:
|
|
804
|
+
remoteAuthFailed: isGitAuthFailed(),
|
|
844
805
|
};
|
|
845
806
|
},
|
|
846
807
|
],
|
|
@@ -881,7 +842,7 @@ class SocketManager extends TracedEventEmitter {
|
|
|
881
842
|
// disconnects and then reconnects in the same process
|
|
882
843
|
// would be stuck with git permanently disabled.
|
|
883
844
|
disconnectInProgress = false;
|
|
884
|
-
|
|
845
|
+
clearGitAuthFailed();
|
|
885
846
|
const service = await getActiveGitService();
|
|
886
847
|
return { activated: !!service };
|
|
887
848
|
}),
|
|
@@ -896,7 +857,7 @@ class SocketManager extends TracedEventEmitter {
|
|
|
896
857
|
return { refreshed: false };
|
|
897
858
|
}
|
|
898
859
|
activeGitService = service;
|
|
899
|
-
|
|
860
|
+
clearGitAuthFailed();
|
|
900
861
|
aiService?.setRuntimeGitServices(service, syncService, gitOperationLock);
|
|
901
862
|
return { refreshed: true };
|
|
902
863
|
}),
|
|
@@ -911,7 +872,7 @@ class SocketManager extends TracedEventEmitter {
|
|
|
911
872
|
const serviceToDisconnect = activeGitService;
|
|
912
873
|
activeGitService = undefined;
|
|
913
874
|
disconnectInProgress = true;
|
|
914
|
-
|
|
875
|
+
clearGitAuthFailed();
|
|
915
876
|
// Ensure DBFS sync context is no longer tied to
|
|
916
877
|
// `superblocks/live` immediately after native git disconnect.
|
|
917
878
|
syncService?.setBranchName(DEFAULT_NON_GIT_BRANCH);
|