@junctionpanel/server 0.1.33 → 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 +2 -0
- package/dist/server/client/daemon-client.d.ts.map +1 -1
- package/dist/server/client/daemon-client.js +2 -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 +5 -0
- package/dist/server/server/agent/agent-manager.d.ts.map +1 -1
- package/dist/server/server/agent/agent-manager.js +63 -9
- 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 +4 -0
- 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/session.d.ts +1 -0
- package/dist/server/server/session.d.ts.map +1 -1
- package/dist/server/server/session.js +77 -69
- 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 +277 -218
- package/dist/server/shared/messages.d.ts.map +1 -1
- package/dist/server/shared/messages.js +5 -0
- 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';
|
|
@@ -339,63 +340,7 @@ export class Session {
|
|
|
339
340
|
return payload;
|
|
340
341
|
}
|
|
341
342
|
buildStoredAgentPayload(record) {
|
|
342
|
-
|
|
343
|
-
supportsStreaming: false,
|
|
344
|
-
supportsSessionPersistence: true,
|
|
345
|
-
supportsDynamicModes: false,
|
|
346
|
-
supportsMcpServers: false,
|
|
347
|
-
supportsReasoningStream: false,
|
|
348
|
-
supportsToolInvocations: true,
|
|
349
|
-
};
|
|
350
|
-
const createdAt = new Date(record.createdAt);
|
|
351
|
-
const updatedAt = new Date(record.lastActivityAt ?? record.updatedAt);
|
|
352
|
-
const lastUserMessageAt = record.lastUserMessageAt ? new Date(record.lastUserMessageAt) : null;
|
|
353
|
-
const provider = coerceAgentProvider(this.sessionLogger, record.provider, record.id);
|
|
354
|
-
const runtimeInfo = record.runtimeInfo
|
|
355
|
-
? {
|
|
356
|
-
provider: coerceAgentProvider(this.sessionLogger, record.runtimeInfo.provider, record.id),
|
|
357
|
-
sessionId: record.runtimeInfo.sessionId,
|
|
358
|
-
...(Object.prototype.hasOwnProperty.call(record.runtimeInfo, 'model')
|
|
359
|
-
? { model: record.runtimeInfo.model ?? null }
|
|
360
|
-
: {}),
|
|
361
|
-
...(Object.prototype.hasOwnProperty.call(record.runtimeInfo, 'thinkingOptionId')
|
|
362
|
-
? { thinkingOptionId: record.runtimeInfo.thinkingOptionId ?? null }
|
|
363
|
-
: {}),
|
|
364
|
-
...(Object.prototype.hasOwnProperty.call(record.runtimeInfo, 'modeId')
|
|
365
|
-
? { modeId: record.runtimeInfo.modeId ?? null }
|
|
366
|
-
: {}),
|
|
367
|
-
...(record.runtimeInfo.extra ? { extra: record.runtimeInfo.extra } : {}),
|
|
368
|
-
}
|
|
369
|
-
: undefined;
|
|
370
|
-
return {
|
|
371
|
-
id: record.id,
|
|
372
|
-
provider,
|
|
373
|
-
cwd: record.cwd,
|
|
374
|
-
model: record.config?.model ?? null,
|
|
375
|
-
thinkingOptionId: record.config?.thinkingOptionId ?? null,
|
|
376
|
-
effectiveThinkingOptionId: resolveEffectiveThinkingOptionId({
|
|
377
|
-
runtimeInfo,
|
|
378
|
-
configuredThinkingOptionId: record.config?.thinkingOptionId ?? null,
|
|
379
|
-
}),
|
|
380
|
-
...(runtimeInfo ? { runtimeInfo } : {}),
|
|
381
|
-
createdAt: createdAt.toISOString(),
|
|
382
|
-
updatedAt: updatedAt.toISOString(),
|
|
383
|
-
lastUserMessageAt: lastUserMessageAt ? lastUserMessageAt.toISOString() : null,
|
|
384
|
-
status: record.lastStatus,
|
|
385
|
-
capabilities: defaultCapabilities,
|
|
386
|
-
currentModeId: record.lastModeId ?? null,
|
|
387
|
-
availableModes: [],
|
|
388
|
-
pendingPermissions: [],
|
|
389
|
-
persistence: toAgentPersistenceHandle(this.sessionLogger, record.persistence),
|
|
390
|
-
lastUsage: undefined,
|
|
391
|
-
lastError: undefined,
|
|
392
|
-
title: record.title ?? null,
|
|
393
|
-
requiresAttention: record.requiresAttention ?? false,
|
|
394
|
-
attentionReason: record.attentionReason ?? null,
|
|
395
|
-
attentionTimestamp: record.attentionTimestamp ?? null,
|
|
396
|
-
archivedAt: record.archivedAt ?? null,
|
|
397
|
-
labels: record.labels,
|
|
398
|
-
};
|
|
343
|
+
return toStoredAgentPayload(record);
|
|
399
344
|
}
|
|
400
345
|
fetchStoredTimeline(record, options) {
|
|
401
346
|
const rows = (record.timelineRows ?? []).map((row) => ({ ...row }));
|
|
@@ -543,6 +488,7 @@ export class Session {
|
|
|
543
488
|
this.sessionLogger.info({ agentId, provider: record.provider }, 'Agent created from stored config');
|
|
544
489
|
}
|
|
545
490
|
await this.agentManager.hydrateTimelineFromProvider(agentId);
|
|
491
|
+
await this.reconcilePersistedPendingPermissions(record, agentId);
|
|
546
492
|
return this.agentManager.getAgent(agentId) ?? snapshot;
|
|
547
493
|
})();
|
|
548
494
|
pendingAgentInitializations.set(agentId, initPromise);
|
|
@@ -556,6 +502,45 @@ export class Session {
|
|
|
556
502
|
}
|
|
557
503
|
}
|
|
558
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
|
+
}
|
|
559
544
|
matchesAgentFilter(options) {
|
|
560
545
|
const { agent, project, filter } = options;
|
|
561
546
|
if (filter?.labels) {
|
|
@@ -1210,6 +1195,8 @@ export class Session {
|
|
|
1210
1195
|
restoredWorktree = await restoreInRepoWorktree({
|
|
1211
1196
|
repoRoot: record.archivedWorktree.repoRoot,
|
|
1212
1197
|
baseBranch: record.archivedWorktree.baseBranch,
|
|
1198
|
+
baseBranchSource: record.archivedWorktree.baseBranchSource ?? 'remote',
|
|
1199
|
+
remoteName: record.archivedWorktree.remoteName ?? undefined,
|
|
1213
1200
|
branchName: record.archivedWorktree.branchName,
|
|
1214
1201
|
worktreeSlug: record.archivedWorktree.worktreeSlug,
|
|
1215
1202
|
runSetup: false,
|
|
@@ -1323,6 +1310,8 @@ export class Session {
|
|
|
1323
1310
|
return {
|
|
1324
1311
|
repoRoot: ownership.repoRoot,
|
|
1325
1312
|
baseBranch: metadata.baseRefName,
|
|
1313
|
+
baseBranchSource: metadata.version === 3 ? metadata.baseBranchSource : 'remote',
|
|
1314
|
+
remoteName: metadata.version === 3 ? metadata.remoteName ?? null : null,
|
|
1326
1315
|
branchName,
|
|
1327
1316
|
worktreeSlug: basename(resolvedWorktree.worktreePath),
|
|
1328
1317
|
originalCwd: resolvedWorktree.worktreePath,
|
|
@@ -1720,15 +1709,26 @@ export class Session {
|
|
|
1720
1709
|
};
|
|
1721
1710
|
}
|
|
1722
1711
|
}
|
|
1723
|
-
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;
|
|
1724
1723
|
if (!baseBranch) {
|
|
1725
1724
|
throw new Error('Unable to determine a base branch for worktree creation');
|
|
1726
1725
|
}
|
|
1727
|
-
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');
|
|
1728
1727
|
const createdWorktree = await createInRepoWorktree({
|
|
1729
1728
|
repoRoot,
|
|
1730
1729
|
baseBranch,
|
|
1731
|
-
|
|
1730
|
+
baseBranchSource: resolvedBase.source,
|
|
1731
|
+
remoteName: resolvedBase.remoteName ?? normalized?.remoteName,
|
|
1732
1732
|
runSetup: false,
|
|
1733
1733
|
});
|
|
1734
1734
|
return {
|
|
@@ -1955,6 +1955,7 @@ export class Session {
|
|
|
1955
1955
|
return null;
|
|
1956
1956
|
}
|
|
1957
1957
|
const baseBranch = merged.baseBranch?.trim() || undefined;
|
|
1958
|
+
const baseBranchSource = merged.baseBranchSource ?? 'remote';
|
|
1958
1959
|
const remoteName = merged.remoteName?.trim() || undefined;
|
|
1959
1960
|
const createWorktree = Boolean(merged.createWorktree);
|
|
1960
1961
|
const createNewBranch = Boolean(merged.createNewBranch);
|
|
@@ -1971,12 +1972,6 @@ export class Session {
|
|
|
1971
1972
|
if (remoteName) {
|
|
1972
1973
|
this.assertSafeRemoteName(remoteName);
|
|
1973
1974
|
}
|
|
1974
|
-
if (createWorktree && !baseBranch) {
|
|
1975
|
-
throw new Error('Base branch is required when creating a worktree');
|
|
1976
|
-
}
|
|
1977
|
-
if (createNewBranch && !baseBranch) {
|
|
1978
|
-
throw new Error('Base branch is required when creating a new branch');
|
|
1979
|
-
}
|
|
1980
1975
|
if (createNewBranch) {
|
|
1981
1976
|
if (!normalizedBranchName) {
|
|
1982
1977
|
throw new Error('New branch name is required');
|
|
@@ -1994,6 +1989,7 @@ export class Session {
|
|
|
1994
1989
|
}
|
|
1995
1990
|
return {
|
|
1996
1991
|
baseBranch,
|
|
1992
|
+
baseBranchSource,
|
|
1997
1993
|
remoteName,
|
|
1998
1994
|
createNewBranch,
|
|
1999
1995
|
newBranchName: normalizedBranchName,
|
|
@@ -2597,6 +2593,8 @@ export class Session {
|
|
|
2597
2593
|
const branches = await listBranchSuggestions(resolvedCwd, {
|
|
2598
2594
|
query,
|
|
2599
2595
|
limit,
|
|
2596
|
+
preferredBranches: msg.preferredBranches,
|
|
2597
|
+
source: msg.source,
|
|
2600
2598
|
remoteName: msg.remoteName,
|
|
2601
2599
|
});
|
|
2602
2600
|
this.emit({
|
|
@@ -4217,6 +4215,15 @@ export class Session {
|
|
|
4217
4215
|
});
|
|
4218
4216
|
return;
|
|
4219
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
|
+
}
|
|
4220
4227
|
const agent = await this.getAgentPayloadById(resolved.agentId);
|
|
4221
4228
|
if (!agent) {
|
|
4222
4229
|
this.emit({
|
|
@@ -4533,7 +4540,8 @@ export class Session {
|
|
|
4533
4540
|
return;
|
|
4534
4541
|
}
|
|
4535
4542
|
const final = this.buildStoredAgentPayload(record);
|
|
4536
|
-
const
|
|
4543
|
+
const hasPendingPermission = final.pendingPermissions.length > 0;
|
|
4544
|
+
const status = hasPendingPermission
|
|
4537
4545
|
? 'permission'
|
|
4538
4546
|
: record.lastStatus === 'error'
|
|
4539
4547
|
? 'error'
|