@junctionpanel/server 0.1.33 → 0.1.35
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 +66 -12
- 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 +5 -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/claude-agent.d.ts.map +1 -1
- package/dist/server/server/agent/providers/claude-agent.js +38 -90
- package/dist/server/server/agent/providers/claude-agent.js.map +1 -1
- package/dist/server/server/agent/providers/claude-cli-capabilities.d.ts +50 -0
- package/dist/server/server/agent/providers/claude-cli-capabilities.d.ts.map +1 -0
- package/dist/server/server/agent/providers/claude-cli-capabilities.js +247 -0
- package/dist/server/server/agent/providers/claude-cli-capabilities.js.map +1 -0
- 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/agent/providers/gemini-agent.d.ts +287 -1
- package/dist/server/server/agent/providers/gemini-agent.d.ts.map +1 -1
- package/dist/server/server/agent/providers/gemini-agent.js +255 -16
- package/dist/server/server/agent/providers/gemini-agent.js.map +1 -1
- package/dist/server/server/daemon-doctor.d.ts +5 -0
- package/dist/server/server/daemon-doctor.d.ts.map +1 -1
- package/dist/server/server/daemon-doctor.js +26 -0
- package/dist/server/server/daemon-doctor.js.map +1 -1
- package/dist/server/server/file-explorer/service.d.ts +1 -0
- package/dist/server/server/file-explorer/service.d.ts.map +1 -1
- package/dist/server/server/file-explorer/service.js +36 -0
- package/dist/server/server/file-explorer/service.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 +82 -71
- 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 +424 -218
- package/dist/server/shared/messages.d.ts.map +1 -1
- package/dist/server/shared/messages.js +9 -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,17 +11,18 @@ 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';
|
|
19
20
|
import { isValidAgentProvider, AGENT_PROVIDER_IDS } from './agent/provider-manifest.js';
|
|
20
|
-
import { listDirectoryEntries, readExplorerFile, getDownloadableFileInfo, } from './file-explorer/service.js';
|
|
21
|
+
import { listDirectoryEntries, readExplorerFile, getDownloadableFileInfo, isWorkspaceExplorerMissingPathError, } from './file-explorer/service.js';
|
|
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({
|
|
@@ -3745,7 +3743,10 @@ export class Session {
|
|
|
3745
3743
|
}
|
|
3746
3744
|
}
|
|
3747
3745
|
catch (error) {
|
|
3748
|
-
|
|
3746
|
+
const log = isWorkspaceExplorerMissingPathError(error)
|
|
3747
|
+
? this.sessionLogger.debug.bind(this.sessionLogger)
|
|
3748
|
+
: this.sessionLogger.error.bind(this.sessionLogger);
|
|
3749
|
+
log({ err: error, cwd, path: requestedPath }, `Failed to fulfill workspace file explorer request for cwd ${cwd}`);
|
|
3749
3750
|
this.emit({
|
|
3750
3751
|
type: 'workspace_file_explorer_response',
|
|
3751
3752
|
payload: {
|
|
@@ -4217,6 +4218,15 @@ export class Session {
|
|
|
4217
4218
|
});
|
|
4218
4219
|
return;
|
|
4219
4220
|
}
|
|
4221
|
+
const existing = this.agentManager.getAgent(resolved.agentId);
|
|
4222
|
+
if (!existing) {
|
|
4223
|
+
const record = await this.agentStorage.get(resolved.agentId);
|
|
4224
|
+
if (record && !record.internal && !record.archivedAt) {
|
|
4225
|
+
await this.ensureAgentLoaded(resolved.agentId).catch((error) => {
|
|
4226
|
+
this.sessionLogger.warn({ err: error, agentId: resolved.agentId }, 'Failed to lazily load agent before fetch_agent_response; falling back to stored state');
|
|
4227
|
+
});
|
|
4228
|
+
}
|
|
4229
|
+
}
|
|
4220
4230
|
const agent = await this.getAgentPayloadById(resolved.agentId);
|
|
4221
4231
|
if (!agent) {
|
|
4222
4232
|
this.emit({
|
|
@@ -4533,7 +4543,8 @@ export class Session {
|
|
|
4533
4543
|
return;
|
|
4534
4544
|
}
|
|
4535
4545
|
const final = this.buildStoredAgentPayload(record);
|
|
4536
|
-
const
|
|
4546
|
+
const hasPendingPermission = final.pendingPermissions.length > 0;
|
|
4547
|
+
const status = hasPendingPermission
|
|
4537
4548
|
? 'permission'
|
|
4538
4549
|
: record.lastStatus === 'error'
|
|
4539
4550
|
? 'error'
|