@junctionpanel/server 0.1.32 → 0.1.34
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/client/daemon-client.d.ts +6 -1
- package/dist/server/client/daemon-client.d.ts.map +1 -1
- package/dist/server/client/daemon-client.js +17 -0
- package/dist/server/client/daemon-client.js.map +1 -1
- package/dist/server/server/agent/agent-management-mcp.d.ts.map +1 -1
- package/dist/server/server/agent/agent-management-mcp.js +44 -7
- package/dist/server/server/agent/agent-management-mcp.js.map +1 -1
- package/dist/server/server/agent/agent-manager.d.ts +6 -0
- package/dist/server/server/agent/agent-manager.d.ts.map +1 -1
- package/dist/server/server/agent/agent-manager.js +88 -10
- package/dist/server/server/agent/agent-manager.js.map +1 -1
- package/dist/server/server/agent/agent-permission-fingerprint.d.ts +6 -0
- package/dist/server/server/agent/agent-permission-fingerprint.d.ts.map +1 -0
- package/dist/server/server/agent/agent-permission-fingerprint.js +28 -0
- package/dist/server/server/agent/agent-permission-fingerprint.js.map +1 -0
- package/dist/server/server/agent/agent-projections.d.ts +1 -0
- package/dist/server/server/agent/agent-projections.d.ts.map +1 -1
- package/dist/server/server/agent/agent-projections.js +61 -3
- package/dist/server/server/agent/agent-projections.js.map +1 -1
- package/dist/server/server/agent/agent-sdk-types.d.ts +10 -1
- package/dist/server/server/agent/agent-sdk-types.d.ts.map +1 -1
- package/dist/server/server/agent/agent-storage.d.ts +13 -0
- package/dist/server/server/agent/agent-storage.d.ts.map +1 -1
- package/dist/server/server/agent/agent-storage.js +4 -2
- package/dist/server/server/agent/agent-storage.js.map +1 -1
- package/dist/server/server/agent/mcp-server.d.ts.map +1 -1
- package/dist/server/server/agent/mcp-server.js +44 -7
- package/dist/server/server/agent/mcp-server.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 +4 -0
- package/dist/server/server/agent/providers/codex-app-server-agent.js.map +1 -1
- package/dist/server/server/bootstrap.d.ts.map +1 -1
- package/dist/server/server/bootstrap.js +2 -1
- package/dist/server/server/bootstrap.js.map +1 -1
- package/dist/server/server/cli-runtime-exports.d.ts +2 -0
- package/dist/server/server/cli-runtime-exports.d.ts.map +1 -1
- package/dist/server/server/cli-runtime-exports.js +2 -0
- package/dist/server/server/cli-runtime-exports.js.map +1 -1
- package/dist/server/server/daemon-doctor.d.ts +4 -0
- package/dist/server/server/daemon-doctor.d.ts.map +1 -1
- package/dist/server/server/daemon-doctor.js +33 -12
- package/dist/server/server/daemon-doctor.js.map +1 -1
- package/dist/server/server/daemon-package-context.d.ts +10 -0
- package/dist/server/server/daemon-package-context.d.ts.map +1 -0
- package/dist/server/server/daemon-package-context.js +31 -0
- package/dist/server/server/daemon-package-context.js.map +1 -0
- package/dist/server/server/package-update.d.ts +32 -0
- package/dist/server/server/package-update.d.ts.map +1 -0
- package/dist/server/server/package-update.js +196 -0
- package/dist/server/server/package-update.js.map +1 -0
- package/dist/server/server/session.d.ts +1 -0
- package/dist/server/server/session.d.ts.map +1 -1
- package/dist/server/server/session.js +91 -85
- package/dist/server/server/session.js.map +1 -1
- package/dist/server/server/worktree-bootstrap.d.ts +2 -1
- package/dist/server/server/worktree-bootstrap.d.ts.map +1 -1
- package/dist/server/server/worktree-bootstrap.js +1 -0
- package/dist/server/server/worktree-bootstrap.js.map +1 -1
- package/dist/server/shared/messages.d.ts +617 -446
- package/dist/server/shared/messages.d.ts.map +1 -1
- package/dist/server/shared/messages.js +22 -1
- package/dist/server/shared/messages.js.map +1 -1
- package/dist/server/utils/checkout-git.d.ts +14 -0
- package/dist/server/utils/checkout-git.d.ts.map +1 -1
- package/dist/server/utils/checkout-git.js +73 -44
- package/dist/server/utils/checkout-git.js.map +1 -1
- package/dist/server/utils/worktree-metadata.d.ts +30 -0
- package/dist/server/utils/worktree-metadata.d.ts.map +1 -1
- package/dist/server/utils/worktree-metadata.js +38 -9
- package/dist/server/utils/worktree-metadata.js.map +1 -1
- package/dist/server/utils/worktree.d.ts +7 -3
- package/dist/server/utils/worktree.d.ts.map +1 -1
- package/dist/server/utils/worktree.js +91 -47
- package/dist/server/utils/worktree.js.map +1 -1
- package/package.json +2 -2
|
@@ -11,8 +11,9 @@ import { buildConfigOverrides, buildSessionConfig, extractTimestamps, extractTim
|
|
|
11
11
|
import { experimental_createMCPClient } from 'ai';
|
|
12
12
|
import { buildProviderRegistry } from './agent/provider-registry.js';
|
|
13
13
|
import { applyProviderEnv, } from './agent/provider-launch-config.js';
|
|
14
|
+
import { buildPermissionRecoveryFingerprint } from './agent/agent-permission-fingerprint.js';
|
|
14
15
|
import { scheduleAgentMetadataGeneration } from './agent/agent-metadata-generator.js';
|
|
15
|
-
import { resolveEffectiveThinkingOptionId,
|
|
16
|
+
import { toAgentPayload, resolveEffectiveThinkingOptionId, toStoredAgentPayload, } from './agent/agent-projections.js';
|
|
16
17
|
import { appendTimelineItemIfAgentKnown, emitLiveTimelineItemIfAgentKnown, } from './agent/timeline-append.js';
|
|
17
18
|
import { projectTimelineRows, selectTimelineWindowByProjectedLimit, } from './agent/timeline-projection.js';
|
|
18
19
|
import { DEFAULT_STRUCTURED_GENERATION_PROVIDERS, StructuredAgentFallbackError, StructuredAgentResponseError, generateStructuredAgentResponseWithFallback, } from './agent/agent-response-loop.js';
|
|
@@ -21,7 +22,7 @@ import { listDirectoryEntries, readExplorerFile, getDownloadableFileInfo, } from
|
|
|
21
22
|
import { slugify, validateBranchSlug, listJunctionWorktrees, deleteJunctionWorktree, isJunctionOwnedWorktreeCwd, resolveJunctionWorktreeRootForCwd, createInRepoWorktree, restoreInRepoWorktree, } from '../utils/worktree.js';
|
|
22
23
|
import { readJunctionWorktreeMetadata } from '../utils/worktree-metadata.js';
|
|
23
24
|
import { runAsyncWorktreeBootstrap } from './worktree-bootstrap.js';
|
|
24
|
-
import { getCheckoutDiff, getCheckoutStatus, getCheckoutStatusLite, listBranchSuggestions, NotGitRepoError, MergeConflictError, MergeFromBaseConflictError, commitChanges, mergeToBase, mergeFromBase, pushCurrentBranch, createPullRequest, getPullRequestFailureLogs, getPullRequestStatus, listGitRemotes, mergePullRequest,
|
|
25
|
+
import { getCheckoutDiff, getCheckoutStatus, getCheckoutStatusLite, listBranchSuggestions, NotGitRepoError, MergeConflictError, MergeFromBaseConflictError, commitChanges, mergeToBase, mergeFromBase, pushCurrentBranch, createPullRequest, getPullRequestFailureLogs, getPullRequestStatus, listGitRemotes, mergePullRequest, resolveBaseRefWithSource, } from '../utils/checkout-git.js';
|
|
25
26
|
import { getProjectIcon } from '../utils/project-icon.js';
|
|
26
27
|
import { expandTilde } from '../utils/path.js';
|
|
27
28
|
import { searchHomeDirectories, searchWorkspaceEntries, searchWorkspaceEntriesAtGitRef, searchGitRepositories, checkIsGitRepo, } from '../utils/directory-suggestions.js';
|
|
@@ -29,9 +30,10 @@ import { cloneRepository } from '../utils/git-clone.js';
|
|
|
29
30
|
import { initRepository } from '../utils/git-init.js';
|
|
30
31
|
import { resolveClientMessageId } from './client-message-id.js';
|
|
31
32
|
import { deriveProjectGroupingKey, deriveProjectGroupingName } from '../shared/project-grouping.js';
|
|
32
|
-
import {
|
|
33
|
+
import { DEFAULT_DAEMON_PACKAGE_NAME, resolveDaemonPackageVersion, } from './daemon-package-context.js';
|
|
33
34
|
import { runDaemonDoctor } from './daemon-doctor.js';
|
|
34
35
|
import { MANAGED_DAEMON_PROVIDERS, autoRouteProviderExecutable, loadDaemonProviderSettings, saveDaemonProviderExecutablePath, } from './daemon-provider-settings.js';
|
|
36
|
+
import { resolvePackageUpdateInfo } from './package-update.js';
|
|
35
37
|
import { loadPersistedConfig } from './persisted-config.js';
|
|
36
38
|
const execAsync = promisify(exec);
|
|
37
39
|
const READ_ONLY_GIT_ENV = {
|
|
@@ -338,63 +340,7 @@ export class Session {
|
|
|
338
340
|
return payload;
|
|
339
341
|
}
|
|
340
342
|
buildStoredAgentPayload(record) {
|
|
341
|
-
|
|
342
|
-
supportsStreaming: false,
|
|
343
|
-
supportsSessionPersistence: true,
|
|
344
|
-
supportsDynamicModes: false,
|
|
345
|
-
supportsMcpServers: false,
|
|
346
|
-
supportsReasoningStream: false,
|
|
347
|
-
supportsToolInvocations: true,
|
|
348
|
-
};
|
|
349
|
-
const createdAt = new Date(record.createdAt);
|
|
350
|
-
const updatedAt = new Date(record.lastActivityAt ?? record.updatedAt);
|
|
351
|
-
const lastUserMessageAt = record.lastUserMessageAt ? new Date(record.lastUserMessageAt) : null;
|
|
352
|
-
const provider = coerceAgentProvider(this.sessionLogger, record.provider, record.id);
|
|
353
|
-
const runtimeInfo = record.runtimeInfo
|
|
354
|
-
? {
|
|
355
|
-
provider: coerceAgentProvider(this.sessionLogger, record.runtimeInfo.provider, record.id),
|
|
356
|
-
sessionId: record.runtimeInfo.sessionId,
|
|
357
|
-
...(Object.prototype.hasOwnProperty.call(record.runtimeInfo, 'model')
|
|
358
|
-
? { model: record.runtimeInfo.model ?? null }
|
|
359
|
-
: {}),
|
|
360
|
-
...(Object.prototype.hasOwnProperty.call(record.runtimeInfo, 'thinkingOptionId')
|
|
361
|
-
? { thinkingOptionId: record.runtimeInfo.thinkingOptionId ?? null }
|
|
362
|
-
: {}),
|
|
363
|
-
...(Object.prototype.hasOwnProperty.call(record.runtimeInfo, 'modeId')
|
|
364
|
-
? { modeId: record.runtimeInfo.modeId ?? null }
|
|
365
|
-
: {}),
|
|
366
|
-
...(record.runtimeInfo.extra ? { extra: record.runtimeInfo.extra } : {}),
|
|
367
|
-
}
|
|
368
|
-
: undefined;
|
|
369
|
-
return {
|
|
370
|
-
id: record.id,
|
|
371
|
-
provider,
|
|
372
|
-
cwd: record.cwd,
|
|
373
|
-
model: record.config?.model ?? null,
|
|
374
|
-
thinkingOptionId: record.config?.thinkingOptionId ?? null,
|
|
375
|
-
effectiveThinkingOptionId: resolveEffectiveThinkingOptionId({
|
|
376
|
-
runtimeInfo,
|
|
377
|
-
configuredThinkingOptionId: record.config?.thinkingOptionId ?? null,
|
|
378
|
-
}),
|
|
379
|
-
...(runtimeInfo ? { runtimeInfo } : {}),
|
|
380
|
-
createdAt: createdAt.toISOString(),
|
|
381
|
-
updatedAt: updatedAt.toISOString(),
|
|
382
|
-
lastUserMessageAt: lastUserMessageAt ? lastUserMessageAt.toISOString() : null,
|
|
383
|
-
status: record.lastStatus,
|
|
384
|
-
capabilities: defaultCapabilities,
|
|
385
|
-
currentModeId: record.lastModeId ?? null,
|
|
386
|
-
availableModes: [],
|
|
387
|
-
pendingPermissions: [],
|
|
388
|
-
persistence: toAgentPersistenceHandle(this.sessionLogger, record.persistence),
|
|
389
|
-
lastUsage: undefined,
|
|
390
|
-
lastError: undefined,
|
|
391
|
-
title: record.title ?? null,
|
|
392
|
-
requiresAttention: record.requiresAttention ?? false,
|
|
393
|
-
attentionReason: record.attentionReason ?? null,
|
|
394
|
-
attentionTimestamp: record.attentionTimestamp ?? null,
|
|
395
|
-
archivedAt: record.archivedAt ?? null,
|
|
396
|
-
labels: record.labels,
|
|
397
|
-
};
|
|
343
|
+
return toStoredAgentPayload(record);
|
|
398
344
|
}
|
|
399
345
|
fetchStoredTimeline(record, options) {
|
|
400
346
|
const rows = (record.timelineRows ?? []).map((row) => ({ ...row }));
|
|
@@ -542,6 +488,7 @@ export class Session {
|
|
|
542
488
|
this.sessionLogger.info({ agentId, provider: record.provider }, 'Agent created from stored config');
|
|
543
489
|
}
|
|
544
490
|
await this.agentManager.hydrateTimelineFromProvider(agentId);
|
|
491
|
+
await this.reconcilePersistedPendingPermissions(record, agentId);
|
|
545
492
|
return this.agentManager.getAgent(agentId) ?? snapshot;
|
|
546
493
|
})();
|
|
547
494
|
pendingAgentInitializations.set(agentId, initPromise);
|
|
@@ -555,6 +502,45 @@ export class Session {
|
|
|
555
502
|
}
|
|
556
503
|
}
|
|
557
504
|
}
|
|
505
|
+
async reconcilePersistedPendingPermissions(record, agentId) {
|
|
506
|
+
const persistedPending = record.pendingPermissions ?? [];
|
|
507
|
+
if (persistedPending.length === 0) {
|
|
508
|
+
return;
|
|
509
|
+
}
|
|
510
|
+
const liveAgent = this.agentManager.getAgent(agentId);
|
|
511
|
+
const sessionPending = liveAgent && liveAgent.lifecycle !== 'closed'
|
|
512
|
+
? liveAgent.session.getPendingPermissions()
|
|
513
|
+
: [];
|
|
514
|
+
const recoveredIds = new Set(sessionPending.map((request) => request.id));
|
|
515
|
+
const recoveredFingerprints = new Set(sessionPending.map((request) => buildPermissionRecoveryFingerprint(request)));
|
|
516
|
+
const expiredRequests = persistedPending.filter((request) => {
|
|
517
|
+
if (recoveredIds.has(request.id)) {
|
|
518
|
+
return false;
|
|
519
|
+
}
|
|
520
|
+
return !recoveredFingerprints.has(buildPermissionRecoveryFingerprint(request));
|
|
521
|
+
});
|
|
522
|
+
if (expiredRequests.length === 0) {
|
|
523
|
+
return;
|
|
524
|
+
}
|
|
525
|
+
if (liveAgent && liveAgent.lifecycle !== 'closed') {
|
|
526
|
+
const expiredIds = new Set(expiredRequests.map((request) => request.id));
|
|
527
|
+
const expiredFingerprints = new Set(expiredRequests.map((request) => buildPermissionRecoveryFingerprint(request)));
|
|
528
|
+
this.agentManager.prunePendingPermissions(agentId, {
|
|
529
|
+
requestIds: expiredIds,
|
|
530
|
+
requestFingerprints: expiredFingerprints,
|
|
531
|
+
settleLifecycleIfInactive: sessionPending.length === 0,
|
|
532
|
+
});
|
|
533
|
+
}
|
|
534
|
+
if (sessionPending.length === 0) {
|
|
535
|
+
await this.agentManager.clearAgentAttention(agentId);
|
|
536
|
+
}
|
|
537
|
+
const requestLabel = expiredRequests.length === 1 ? 'approval request' : `${expiredRequests.length} approval requests`;
|
|
538
|
+
await this.agentManager.appendTimelineItem(agentId, {
|
|
539
|
+
type: 'error',
|
|
540
|
+
message: `${requestLabel} expired while the daemon was offline. Re-run the request if you still want to continue.`,
|
|
541
|
+
});
|
|
542
|
+
this.agentManager.notifyAgentState(agentId);
|
|
543
|
+
}
|
|
558
544
|
matchesAgentFilter(options) {
|
|
559
545
|
const { agent, project, filter } = options;
|
|
560
546
|
if (filter?.labels) {
|
|
@@ -1209,6 +1195,8 @@ export class Session {
|
|
|
1209
1195
|
restoredWorktree = await restoreInRepoWorktree({
|
|
1210
1196
|
repoRoot: record.archivedWorktree.repoRoot,
|
|
1211
1197
|
baseBranch: record.archivedWorktree.baseBranch,
|
|
1198
|
+
baseBranchSource: record.archivedWorktree.baseBranchSource ?? 'remote',
|
|
1199
|
+
remoteName: record.archivedWorktree.remoteName ?? undefined,
|
|
1212
1200
|
branchName: record.archivedWorktree.branchName,
|
|
1213
1201
|
worktreeSlug: record.archivedWorktree.worktreeSlug,
|
|
1214
1202
|
runSetup: false,
|
|
@@ -1322,6 +1310,8 @@ export class Session {
|
|
|
1322
1310
|
return {
|
|
1323
1311
|
repoRoot: ownership.repoRoot,
|
|
1324
1312
|
baseBranch: metadata.baseRefName,
|
|
1313
|
+
baseBranchSource: metadata.version === 3 ? metadata.baseBranchSource : 'remote',
|
|
1314
|
+
remoteName: metadata.version === 3 ? metadata.remoteName ?? null : null,
|
|
1325
1315
|
branchName,
|
|
1326
1316
|
worktreeSlug: basename(resolvedWorktree.worktreePath),
|
|
1327
1317
|
originalCwd: resolvedWorktree.worktreePath,
|
|
@@ -1719,15 +1709,26 @@ export class Session {
|
|
|
1719
1709
|
};
|
|
1720
1710
|
}
|
|
1721
1711
|
}
|
|
1722
|
-
const
|
|
1712
|
+
const resolvedBase = normalized?.baseBranch
|
|
1713
|
+
? {
|
|
1714
|
+
ref: normalized.baseBranch,
|
|
1715
|
+
source: normalized.baseBranchSource ?? 'remote',
|
|
1716
|
+
remoteName: normalized?.remoteName ?? null,
|
|
1717
|
+
}
|
|
1718
|
+
: await resolveBaseRefWithSource(repoRoot, {
|
|
1719
|
+
remoteName: normalized?.remoteName,
|
|
1720
|
+
source: normalized?.baseBranchSource ?? 'remote',
|
|
1721
|
+
});
|
|
1722
|
+
const baseBranch = resolvedBase.ref;
|
|
1723
1723
|
if (!baseBranch) {
|
|
1724
1724
|
throw new Error('Unable to determine a base branch for worktree creation');
|
|
1725
1725
|
}
|
|
1726
|
-
this.sessionLogger.info({ repoRoot, baseBranch }, 'Creating in-repo worktree for new agent');
|
|
1726
|
+
this.sessionLogger.info({ repoRoot, baseBranch, baseBranchSource: resolvedBase.source }, 'Creating in-repo worktree for new agent');
|
|
1727
1727
|
const createdWorktree = await createInRepoWorktree({
|
|
1728
1728
|
repoRoot,
|
|
1729
1729
|
baseBranch,
|
|
1730
|
-
|
|
1730
|
+
baseBranchSource: resolvedBase.source,
|
|
1731
|
+
remoteName: resolvedBase.remoteName ?? normalized?.remoteName,
|
|
1731
1732
|
runSetup: false,
|
|
1732
1733
|
});
|
|
1733
1734
|
return {
|
|
@@ -1797,12 +1798,7 @@ export class Session {
|
|
|
1797
1798
|
}
|
|
1798
1799
|
}
|
|
1799
1800
|
resolveDaemonVersionSafe() {
|
|
1800
|
-
|
|
1801
|
-
return resolveDaemonVersion(import.meta.url);
|
|
1802
|
-
}
|
|
1803
|
-
catch {
|
|
1804
|
-
return null;
|
|
1805
|
-
}
|
|
1801
|
+
return resolveDaemonPackageVersion(import.meta.url);
|
|
1806
1802
|
}
|
|
1807
1803
|
toDaemonMetadata(input) {
|
|
1808
1804
|
const homeDir = input?.homeDir ?? homedir();
|
|
@@ -1822,6 +1818,7 @@ export class Session {
|
|
|
1822
1818
|
type: 'run_daemon_doctor_response',
|
|
1823
1819
|
payload: {
|
|
1824
1820
|
daemon: result.daemon,
|
|
1821
|
+
update: result.update,
|
|
1825
1822
|
summary: result.summary,
|
|
1826
1823
|
checks: result.checks,
|
|
1827
1824
|
ranAt: result.ranAt,
|
|
@@ -1837,6 +1834,11 @@ export class Session {
|
|
|
1837
1834
|
type: 'run_daemon_doctor_response',
|
|
1838
1835
|
payload: {
|
|
1839
1836
|
daemon: this.toDaemonMetadata(snapshot),
|
|
1837
|
+
update: resolvePackageUpdateInfo({
|
|
1838
|
+
npmInvocation: null,
|
|
1839
|
+
packageName: DEFAULT_DAEMON_PACKAGE_NAME,
|
|
1840
|
+
currentVersion: this.resolveDaemonVersionSafe(),
|
|
1841
|
+
}),
|
|
1840
1842
|
summary: 'fail',
|
|
1841
1843
|
checks: [],
|
|
1842
1844
|
ranAt: new Date().toISOString(),
|
|
@@ -1914,21 +1916,16 @@ export class Session {
|
|
|
1914
1916
|
if (!executablePath) {
|
|
1915
1917
|
throw new SessionRequestError('provider_not_found', `Could not automatically locate ${msg.provider} on this daemon.`);
|
|
1916
1918
|
}
|
|
1917
|
-
const snapshot = saveDaemonProviderExecutablePath({
|
|
1918
|
-
junctionHome: this.junctionHome,
|
|
1919
|
-
provider: msg.provider,
|
|
1920
|
-
executablePath,
|
|
1921
|
-
});
|
|
1922
1919
|
this.emit({
|
|
1923
1920
|
type: 'auto_route_provider_response',
|
|
1924
1921
|
payload: {
|
|
1925
|
-
daemon: this.toDaemonMetadata(
|
|
1926
|
-
provider:
|
|
1922
|
+
daemon: this.toDaemonMetadata(),
|
|
1923
|
+
provider: msg.provider,
|
|
1924
|
+
executablePath,
|
|
1927
1925
|
error: null,
|
|
1928
1926
|
requestId: msg.requestId,
|
|
1929
1927
|
},
|
|
1930
1928
|
});
|
|
1931
|
-
await this.handleRestartServerRequest(msg.requestId, 'settings_update');
|
|
1932
1929
|
}
|
|
1933
1930
|
catch (error) {
|
|
1934
1931
|
this.sessionLogger.error({ err: error, provider: msg.provider }, 'Failed to auto-route provider executable');
|
|
@@ -1936,7 +1933,8 @@ export class Session {
|
|
|
1936
1933
|
type: 'auto_route_provider_response',
|
|
1937
1934
|
payload: {
|
|
1938
1935
|
daemon: this.toDaemonMetadata(),
|
|
1939
|
-
provider:
|
|
1936
|
+
provider: msg.provider,
|
|
1937
|
+
executablePath: null,
|
|
1940
1938
|
error: error instanceof Error ? error.message : String(error),
|
|
1941
1939
|
requestId: msg.requestId,
|
|
1942
1940
|
},
|
|
@@ -1957,6 +1955,7 @@ export class Session {
|
|
|
1957
1955
|
return null;
|
|
1958
1956
|
}
|
|
1959
1957
|
const baseBranch = merged.baseBranch?.trim() || undefined;
|
|
1958
|
+
const baseBranchSource = merged.baseBranchSource ?? 'remote';
|
|
1960
1959
|
const remoteName = merged.remoteName?.trim() || undefined;
|
|
1961
1960
|
const createWorktree = Boolean(merged.createWorktree);
|
|
1962
1961
|
const createNewBranch = Boolean(merged.createNewBranch);
|
|
@@ -1973,12 +1972,6 @@ export class Session {
|
|
|
1973
1972
|
if (remoteName) {
|
|
1974
1973
|
this.assertSafeRemoteName(remoteName);
|
|
1975
1974
|
}
|
|
1976
|
-
if (createWorktree && !baseBranch) {
|
|
1977
|
-
throw new Error('Base branch is required when creating a worktree');
|
|
1978
|
-
}
|
|
1979
|
-
if (createNewBranch && !baseBranch) {
|
|
1980
|
-
throw new Error('Base branch is required when creating a new branch');
|
|
1981
|
-
}
|
|
1982
1975
|
if (createNewBranch) {
|
|
1983
1976
|
if (!normalizedBranchName) {
|
|
1984
1977
|
throw new Error('New branch name is required');
|
|
@@ -1996,6 +1989,7 @@ export class Session {
|
|
|
1996
1989
|
}
|
|
1997
1990
|
return {
|
|
1998
1991
|
baseBranch,
|
|
1992
|
+
baseBranchSource,
|
|
1999
1993
|
remoteName,
|
|
2000
1994
|
createNewBranch,
|
|
2001
1995
|
newBranchName: normalizedBranchName,
|
|
@@ -2599,6 +2593,8 @@ export class Session {
|
|
|
2599
2593
|
const branches = await listBranchSuggestions(resolvedCwd, {
|
|
2600
2594
|
query,
|
|
2601
2595
|
limit,
|
|
2596
|
+
preferredBranches: msg.preferredBranches,
|
|
2597
|
+
source: msg.source,
|
|
2602
2598
|
remoteName: msg.remoteName,
|
|
2603
2599
|
});
|
|
2604
2600
|
this.emit({
|
|
@@ -4219,6 +4215,15 @@ export class Session {
|
|
|
4219
4215
|
});
|
|
4220
4216
|
return;
|
|
4221
4217
|
}
|
|
4218
|
+
const existing = this.agentManager.getAgent(resolved.agentId);
|
|
4219
|
+
if (!existing) {
|
|
4220
|
+
const record = await this.agentStorage.get(resolved.agentId);
|
|
4221
|
+
if (record && !record.internal && !record.archivedAt) {
|
|
4222
|
+
await this.ensureAgentLoaded(resolved.agentId).catch((error) => {
|
|
4223
|
+
this.sessionLogger.warn({ err: error, agentId: resolved.agentId }, 'Failed to lazily load agent before fetch_agent_response; falling back to stored state');
|
|
4224
|
+
});
|
|
4225
|
+
}
|
|
4226
|
+
}
|
|
4222
4227
|
const agent = await this.getAgentPayloadById(resolved.agentId);
|
|
4223
4228
|
if (!agent) {
|
|
4224
4229
|
this.emit({
|
|
@@ -4535,7 +4540,8 @@ export class Session {
|
|
|
4535
4540
|
return;
|
|
4536
4541
|
}
|
|
4537
4542
|
const final = this.buildStoredAgentPayload(record);
|
|
4538
|
-
const
|
|
4543
|
+
const hasPendingPermission = final.pendingPermissions.length > 0;
|
|
4544
|
+
const status = hasPendingPermission
|
|
4539
4545
|
? 'permission'
|
|
4540
4546
|
: record.lastStatus === 'error'
|
|
4541
4547
|
? 'error'
|