@junctionpanel/server 0.1.38 → 0.1.40
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 +20 -1
- package/dist/server/client/daemon-client.d.ts.map +1 -1
- package/dist/server/client/daemon-client.js +33 -0
- package/dist/server/client/daemon-client.js.map +1 -1
- package/dist/server/server/daemon-log-tail.d.ts +23 -0
- package/dist/server/server/daemon-log-tail.d.ts.map +1 -0
- package/dist/server/server/daemon-log-tail.js +52 -0
- package/dist/server/server/daemon-log-tail.js.map +1 -0
- package/dist/server/server/session.d.ts +3 -0
- package/dist/server/server/session.d.ts.map +1 -1
- package/dist/server/server/session.js +219 -4
- package/dist/server/server/session.js.map +1 -1
- package/dist/server/shared/messages.d.ts +1030 -0
- package/dist/server/shared/messages.d.ts.map +1 -1
- package/dist/server/shared/messages.js +50 -0
- package/dist/server/shared/messages.js.map +1 -1
- package/dist/server/utils/checkout-git.d.ts +19 -0
- package/dist/server/utils/checkout-git.d.ts.map +1 -1
- package/dist/server/utils/checkout-git.js +85 -0
- package/dist/server/utils/checkout-git.js.map +1 -1
- package/dist/server/utils/worktree.d.ts +23 -0
- package/dist/server/utils/worktree.d.ts.map +1 -1
- package/dist/server/utils/worktree.js +120 -1
- package/dist/server/utils/worktree.js.map +1 -1
- package/package.json +2 -2
|
@@ -0,0 +1,52 @@
|
|
|
1
|
+
import { open } from "node:fs/promises";
|
|
2
|
+
import path from "node:path";
|
|
3
|
+
const DEFAULT_DAEMON_LOG_LINES = 200;
|
|
4
|
+
const MAX_DAEMON_LOG_READ_BYTES = 128 * 1024;
|
|
5
|
+
/**
|
|
6
|
+
* Reads the tail of `daemon.log` under the given Junction home directory.
|
|
7
|
+
*
|
|
8
|
+
* The daemon clamps `lines` to a minimum of 1 and a maximum of 200, and will
|
|
9
|
+
* only read a bounded slice from the end of the file to keep websocket payloads
|
|
10
|
+
* predictable.
|
|
11
|
+
*/
|
|
12
|
+
export async function readDaemonLogTail(input) {
|
|
13
|
+
const lines = Math.max(1, Math.min(input.lines ?? DEFAULT_DAEMON_LOG_LINES, DEFAULT_DAEMON_LOG_LINES));
|
|
14
|
+
const logPath = path.join(input.junctionHome, "daemon.log");
|
|
15
|
+
const handle = await open(logPath, "r");
|
|
16
|
+
try {
|
|
17
|
+
const stats = await handle.stat();
|
|
18
|
+
const bytesToRead = Math.min(stats.size, MAX_DAEMON_LOG_READ_BYTES);
|
|
19
|
+
const start = Math.max(0, stats.size - bytesToRead);
|
|
20
|
+
const buffer = Buffer.alloc(bytesToRead);
|
|
21
|
+
let raw = "";
|
|
22
|
+
if (bytesToRead > 0) {
|
|
23
|
+
const { bytesRead } = await handle.read(buffer, 0, bytesToRead, start);
|
|
24
|
+
raw = buffer.subarray(0, bytesRead).toString("utf8");
|
|
25
|
+
}
|
|
26
|
+
let truncated = start > 0;
|
|
27
|
+
if (start > 0) {
|
|
28
|
+
const firstNewline = raw.indexOf("\n");
|
|
29
|
+
if (firstNewline >= 0) {
|
|
30
|
+
raw = raw.slice(firstNewline + 1);
|
|
31
|
+
}
|
|
32
|
+
else {
|
|
33
|
+
raw = "";
|
|
34
|
+
}
|
|
35
|
+
}
|
|
36
|
+
const allLines = raw.length === 0 ? [] : (raw.endsWith("\n") ? raw.slice(0, -1) : raw).split("\n");
|
|
37
|
+
const selectedLines = allLines.slice(-lines);
|
|
38
|
+
if (selectedLines.length < allLines.length) {
|
|
39
|
+
truncated = true;
|
|
40
|
+
}
|
|
41
|
+
return {
|
|
42
|
+
logPath,
|
|
43
|
+
content: selectedLines.join("\n"),
|
|
44
|
+
truncated,
|
|
45
|
+
lineCount: selectedLines.length,
|
|
46
|
+
};
|
|
47
|
+
}
|
|
48
|
+
finally {
|
|
49
|
+
await handle.close();
|
|
50
|
+
}
|
|
51
|
+
}
|
|
52
|
+
//# sourceMappingURL=daemon-log-tail.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"daemon-log-tail.js","sourceRoot":"","sources":["../../../src/server/daemon-log-tail.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,IAAI,EAAE,MAAM,kBAAkB,CAAA;AACvC,OAAO,IAAI,MAAM,WAAW,CAAA;AAE5B,MAAM,wBAAwB,GAAG,GAAG,CAAA;AACpC,MAAM,yBAAyB,GAAG,GAAG,GAAG,IAAI,CAAA;AAc5C;;;;;;GAMG;AACH,MAAM,CAAC,KAAK,UAAU,iBAAiB,CAAC,KAGvC;IACC,MAAM,KAAK,GAAG,IAAI,CAAC,GAAG,CACpB,CAAC,EACD,IAAI,CAAC,GAAG,CAAC,KAAK,CAAC,KAAK,IAAI,wBAAwB,EAAE,wBAAwB,CAAC,CAC5E,CAAA;IACD,MAAM,OAAO,GAAG,IAAI,CAAC,IAAI,CAAC,KAAK,CAAC,YAAY,EAAE,YAAY,CAAC,CAAA;IAC3D,MAAM,MAAM,GAAG,MAAM,IAAI,CAAC,OAAO,EAAE,GAAG,CAAC,CAAA;IAEvC,IAAI,CAAC;QACH,MAAM,KAAK,GAAG,MAAM,MAAM,CAAC,IAAI,EAAE,CAAA;QACjC,MAAM,WAAW,GAAG,IAAI,CAAC,GAAG,CAAC,KAAK,CAAC,IAAI,EAAE,yBAAyB,CAAC,CAAA;QACnE,MAAM,KAAK,GAAG,IAAI,CAAC,GAAG,CAAC,CAAC,EAAE,KAAK,CAAC,IAAI,GAAG,WAAW,CAAC,CAAA;QACnD,MAAM,MAAM,GAAG,MAAM,CAAC,KAAK,CAAC,WAAW,CAAC,CAAA;QACxC,IAAI,GAAG,GAAG,EAAE,CAAA;QAEZ,IAAI,WAAW,GAAG,CAAC,EAAE,CAAC;YACpB,MAAM,EAAE,SAAS,EAAE,GAAG,MAAM,MAAM,CAAC,IAAI,CAAC,MAAM,EAAE,CAAC,EAAE,WAAW,EAAE,KAAK,CAAC,CAAA;YACtE,GAAG,GAAG,MAAM,CAAC,QAAQ,CAAC,CAAC,EAAE,SAAS,CAAC,CAAC,QAAQ,CAAC,MAAM,CAAC,CAAA;QACtD,CAAC;QAED,IAAI,SAAS,GAAG,KAAK,GAAG,CAAC,CAAA;QAEzB,IAAI,KAAK,GAAG,CAAC,EAAE,CAAC;YACd,MAAM,YAAY,GAAG,GAAG,CAAC,OAAO,CAAC,IAAI,CAAC,CAAA;YACtC,IAAI,YAAY,IAAI,CAAC,EAAE,CAAC;gBACtB,GAAG,GAAG,GAAG,CAAC,KAAK,CAAC,YAAY,GAAG,CAAC,CAAC,CAAA;YACnC,CAAC;iBAAM,CAAC;gBACN,GAAG,GAAG,EAAE,CAAA;YACV,CAAC;QACH,CAAC;QAED,MAAM,QAAQ,GACZ,GAAG,CAAC,MAAM,KAAK,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,QAAQ,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,KAAK,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,KAAK,CAAC,IAAI,CAAC,CAAA;QACnF,MAAM,aAAa,GAAG,QAAQ,CAAC,KAAK,CAAC,CAAC,KAAK,CAAC,CAAA;QAC5C,IAAI,aAAa,CAAC,MAAM,GAAG,QAAQ,CAAC,MAAM,EAAE,CAAC;YAC3C,SAAS,GAAG,IAAI,CAAA;QAClB,CAAC;QAED,OAAO;YACL,OAAO;YACP,OAAO,EAAE,aAAa,CAAC,IAAI,CAAC,IAAI,CAAC;YACjC,SAAS;YACT,SAAS,EAAE,aAAa,CAAC,MAAM;SAChC,CAAA;IACH,CAAC;YAAS,CAAC;QACT,MAAM,MAAM,CAAC,KAAK,EAAE,CAAA;IACtB,CAAC;AACH,CAAC"}
|
|
@@ -156,10 +156,12 @@ export declare class Session {
|
|
|
156
156
|
private toDaemonMetadata;
|
|
157
157
|
private handleRunDaemonDoctorRequest;
|
|
158
158
|
private handleGetDaemonProviderSettingsRequest;
|
|
159
|
+
private handleGetDaemonLogTailRequest;
|
|
159
160
|
private handleUpdateDaemonProviderSettingsRequest;
|
|
160
161
|
private handleAutoRouteProviderRequest;
|
|
161
162
|
private handleUpdateNotificationRelayConfigRequest;
|
|
162
163
|
private normalizeGitOptions;
|
|
164
|
+
private resolveAttachBranchTarget;
|
|
163
165
|
private assertSafeGitRef;
|
|
164
166
|
private assertSafeRemoteName;
|
|
165
167
|
private toCheckoutError;
|
|
@@ -218,6 +220,7 @@ export declare class Session {
|
|
|
218
220
|
private handleCheckoutPushRequest;
|
|
219
221
|
private handleCheckoutPrCreateRequest;
|
|
220
222
|
private handleCheckoutPrStatusRequest;
|
|
223
|
+
private handleCheckoutPrSearchRequest;
|
|
221
224
|
private handleCheckoutPrFailureLogsRequest;
|
|
222
225
|
private handleCheckoutPrMergeRequest;
|
|
223
226
|
private handleJunctionWorktreeListRequest;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"session.d.ts","sourceRoot":"","sources":["../../../src/server/session.ts"],"names":[],"mappings":"AAQA,OAAO,EAGL,KAAK,qBAAqB,EAC1B,KAAK,sBAAsB,EAwB5B,MAAM,eAAe,CAAA;AACtB,OAAO,KAAK,EAAE,eAAe,EAAyB,MAAM,iCAAiC,CAAA;AAE7F,OAAO,EAIL,KAAK,cAAc,EACpB,MAAM,yBAAyB,CAAA;AAQhC,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,+CAA+C,CAAA;AAE9E,MAAM,MAAM,wBAAwB,GAAG,MAAM,OAAO,CAAC,SAAS,CAAC,CAAA;AAE/D,OAAO,EAEL,KAAK,+BAA+B,EACrC,MAAM,mCAAmC,CAAA;AAC1C,OAAO,EAAE,YAAY,EAAE,MAAM,0BAA0B,CAAA;AAwCvD,OAAO,EAAE,YAAY,EAA0B,MAAM,0BAA0B,CAAA;AAQ/E,OAAO,EAAE,kBAAkB,EAAE,MAAM,gCAAgC,CAAA;
|
|
1
|
+
{"version":3,"file":"session.d.ts","sourceRoot":"","sources":["../../../src/server/session.ts"],"names":[],"mappings":"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"}
|
|
@@ -19,10 +19,10 @@ import { projectTimelineRows, selectTimelineWindowByProjectedLimit, } from './ag
|
|
|
19
19
|
import { DEFAULT_STRUCTURED_GENERATION_PROVIDERS, StructuredAgentFallbackError, StructuredAgentResponseError, generateStructuredAgentResponseWithFallback, } from './agent/agent-response-loop.js';
|
|
20
20
|
import { isValidAgentProvider, AGENT_PROVIDER_IDS } from './agent/provider-manifest.js';
|
|
21
21
|
import { listDirectoryEntries, readExplorerFile, getDownloadableFileInfo, isWorkspaceExplorerMissingPathError, } from './file-explorer/service.js';
|
|
22
|
-
import { slugify, validateBranchSlug, listJunctionWorktrees, deleteJunctionWorktree, isJunctionOwnedWorktreeCwd, resolveJunctionWorktreeRootForCwd, createInRepoWorktree, restoreInRepoWorktree, } from '../utils/worktree.js';
|
|
22
|
+
import { slugify, validateBranchSlug, listJunctionWorktrees, deleteJunctionWorktree, isJunctionOwnedWorktreeCwd, resolveJunctionWorktreeRootForCwd, createInRepoWorktree, attachInRepoWorktree, restoreInRepoWorktree, } from '../utils/worktree.js';
|
|
23
23
|
import { readJunctionWorktreeMetadata } from '../utils/worktree-metadata.js';
|
|
24
24
|
import { runAsyncWorktreeBootstrap } from './worktree-bootstrap.js';
|
|
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
|
+
import { getCheckoutDiff, getCheckoutStatus, getCheckoutStatusLite, listBranchSuggestions, NotGitRepoError, MergeConflictError, MergeFromBaseConflictError, commitChanges, mergeToBase, mergeFromBase, pushCurrentBranch, createPullRequest, getPullRequestFailureLogs, getPullRequestStatus, searchPullRequests, listGitRemotes, mergePullRequest, resolveBaseRefWithSource, } from '../utils/checkout-git.js';
|
|
26
26
|
import { getProjectIcon } from '../utils/project-icon.js';
|
|
27
27
|
import { expandTilde } from '../utils/path.js';
|
|
28
28
|
import { searchHomeDirectories, searchWorkspaceEntries, searchWorkspaceEntriesAtGitRef, searchGitRepositories, checkIsGitRepo, } from '../utils/directory-suggestions.js';
|
|
@@ -32,6 +32,7 @@ import { resolveClientMessageId } from './client-message-id.js';
|
|
|
32
32
|
import { deriveProjectGroupingKey, deriveProjectGroupingName } from '../shared/project-grouping.js';
|
|
33
33
|
import { DEFAULT_DAEMON_PACKAGE_NAME, resolveDaemonPackageVersion, } from './daemon-package-context.js';
|
|
34
34
|
import { runDaemonDoctor } from './daemon-doctor.js';
|
|
35
|
+
import { readDaemonLogTail } from './daemon-log-tail.js';
|
|
35
36
|
import { MANAGED_DAEMON_PROVIDERS, autoRouteProviderExecutable, loadDaemonProviderSettings, saveDaemonProviderExecutablePath, } from './daemon-provider-settings.js';
|
|
36
37
|
import { applyNotificationRelayOwnerLabel, preserveNotificationRelayOwnerLabel, } from './notifications/relay-ownership.js';
|
|
37
38
|
import { saveNotificationRelayConfig } from './notifications/relay-store.js';
|
|
@@ -905,6 +906,9 @@ export class Session {
|
|
|
905
906
|
case 'checkout_pr_status_request':
|
|
906
907
|
await this.handleCheckoutPrStatusRequest(msg);
|
|
907
908
|
break;
|
|
909
|
+
case 'checkout_pr_search_request':
|
|
910
|
+
await this.handleCheckoutPrSearchRequest(msg);
|
|
911
|
+
break;
|
|
908
912
|
case 'checkout_pr_failure_logs_request':
|
|
909
913
|
await this.handleCheckoutPrFailureLogsRequest(msg);
|
|
910
914
|
break;
|
|
@@ -941,6 +945,9 @@ export class Session {
|
|
|
941
945
|
case 'get_daemon_provider_settings_request':
|
|
942
946
|
await this.handleGetDaemonProviderSettingsRequest(msg);
|
|
943
947
|
break;
|
|
948
|
+
case 'get_daemon_log_tail_request':
|
|
949
|
+
await this.handleGetDaemonLogTailRequest(msg);
|
|
950
|
+
break;
|
|
944
951
|
case 'update_daemon_provider_settings_request':
|
|
945
952
|
await this.handleUpdateDaemonProviderSettingsRequest(msg);
|
|
946
953
|
break;
|
|
@@ -1726,6 +1733,7 @@ export class Session {
|
|
|
1726
1733
|
async buildAgentSessionConfig(config, gitOptions, legacyWorktreeName, labels) {
|
|
1727
1734
|
const cwd = expandTilde(config.cwd);
|
|
1728
1735
|
const normalized = this.normalizeGitOptions(gitOptions, legacyWorktreeName);
|
|
1736
|
+
const requestedAttachBranch = normalized?.attachBranchName;
|
|
1729
1737
|
let repoRoot;
|
|
1730
1738
|
try {
|
|
1731
1739
|
const { stdout } = await execAsync('git rev-parse --path-format=absolute --git-common-dir', {
|
|
@@ -1763,6 +1771,64 @@ export class Session {
|
|
|
1763
1771
|
};
|
|
1764
1772
|
}
|
|
1765
1773
|
}
|
|
1774
|
+
if (requestedAttachBranch) {
|
|
1775
|
+
const attachBranchSource = normalized?.attachBranchSource ?? 'remote';
|
|
1776
|
+
const liveWorktrees = await listJunctionWorktrees({ cwd: repoRoot, junctionHome: this.junctionHome });
|
|
1777
|
+
const localMatchingWorktree = attachBranchSource === 'local'
|
|
1778
|
+
? liveWorktrees.find((entry) => entry.branchName?.trim() === requestedAttachBranch)
|
|
1779
|
+
: null;
|
|
1780
|
+
if (localMatchingWorktree) {
|
|
1781
|
+
this.sessionLogger.info({
|
|
1782
|
+
repoRoot,
|
|
1783
|
+
attachBranchName: requestedAttachBranch,
|
|
1784
|
+
attachBranchRef: `refs/heads/${requestedAttachBranch}`,
|
|
1785
|
+
worktreePath: localMatchingWorktree.path,
|
|
1786
|
+
}, 'Reusing existing Junction worktree for agent');
|
|
1787
|
+
return {
|
|
1788
|
+
sessionConfig: {
|
|
1789
|
+
...config,
|
|
1790
|
+
cwd: localMatchingWorktree.path,
|
|
1791
|
+
},
|
|
1792
|
+
autoWorkspaceName: labels?.['junction:workspace'] ?? basename(localMatchingWorktree.path),
|
|
1793
|
+
};
|
|
1794
|
+
}
|
|
1795
|
+
let requestedAttachTarget = null;
|
|
1796
|
+
try {
|
|
1797
|
+
requestedAttachTarget = await this.resolveAttachBranchTarget({
|
|
1798
|
+
repoRoot,
|
|
1799
|
+
branchName: requestedAttachBranch,
|
|
1800
|
+
branchSource: attachBranchSource,
|
|
1801
|
+
remoteName: normalized?.remoteName,
|
|
1802
|
+
});
|
|
1803
|
+
}
|
|
1804
|
+
catch (error) {
|
|
1805
|
+
this.sessionLogger.warn({
|
|
1806
|
+
err: error,
|
|
1807
|
+
repoRoot,
|
|
1808
|
+
attachBranchName: requestedAttachBranch,
|
|
1809
|
+
attachBranchSource,
|
|
1810
|
+
}, 'Failed to resolve attach target before reuse lookup');
|
|
1811
|
+
}
|
|
1812
|
+
const matchingWorktree = requestedAttachTarget?.head
|
|
1813
|
+
? liveWorktrees.find((entry) => entry.branchName?.trim() === requestedAttachBranch
|
|
1814
|
+
&& entry.head === requestedAttachTarget?.head)
|
|
1815
|
+
: null;
|
|
1816
|
+
if (matchingWorktree) {
|
|
1817
|
+
this.sessionLogger.info({
|
|
1818
|
+
repoRoot,
|
|
1819
|
+
attachBranchName: requestedAttachBranch,
|
|
1820
|
+
attachBranchRef: requestedAttachTarget?.ref ?? null,
|
|
1821
|
+
worktreePath: matchingWorktree.path,
|
|
1822
|
+
}, 'Reusing existing Junction worktree for agent');
|
|
1823
|
+
return {
|
|
1824
|
+
sessionConfig: {
|
|
1825
|
+
...config,
|
|
1826
|
+
cwd: matchingWorktree.path,
|
|
1827
|
+
},
|
|
1828
|
+
autoWorkspaceName: labels?.['junction:workspace'] ?? basename(matchingWorktree.path),
|
|
1829
|
+
};
|
|
1830
|
+
}
|
|
1831
|
+
}
|
|
1766
1832
|
const resolvedBase = normalized?.baseBranch
|
|
1767
1833
|
? {
|
|
1768
1834
|
ref: normalized.baseBranch,
|
|
@@ -1777,6 +1843,32 @@ export class Session {
|
|
|
1777
1843
|
if (!baseBranch) {
|
|
1778
1844
|
throw new Error('Unable to determine a base branch for worktree creation');
|
|
1779
1845
|
}
|
|
1846
|
+
if (requestedAttachBranch) {
|
|
1847
|
+
this.sessionLogger.info({
|
|
1848
|
+
repoRoot,
|
|
1849
|
+
baseBranch,
|
|
1850
|
+
baseBranchSource: resolvedBase.source,
|
|
1851
|
+
attachBranchName: requestedAttachBranch,
|
|
1852
|
+
attachBranchSource: normalized?.attachBranchSource ?? 'remote',
|
|
1853
|
+
}, 'Attaching in-repo worktree for new agent');
|
|
1854
|
+
const attachedWorktree = await attachInRepoWorktree({
|
|
1855
|
+
repoRoot,
|
|
1856
|
+
baseBranch,
|
|
1857
|
+
baseBranchSource: resolvedBase.source,
|
|
1858
|
+
remoteName: resolvedBase.remoteName ?? normalized?.remoteName,
|
|
1859
|
+
branchName: requestedAttachBranch,
|
|
1860
|
+
branchSource: normalized?.attachBranchSource ?? 'remote',
|
|
1861
|
+
runSetup: false,
|
|
1862
|
+
});
|
|
1863
|
+
return {
|
|
1864
|
+
sessionConfig: {
|
|
1865
|
+
...config,
|
|
1866
|
+
cwd: attachedWorktree.worktreePath,
|
|
1867
|
+
},
|
|
1868
|
+
worktreeConfig: attachedWorktree,
|
|
1869
|
+
autoWorkspaceName: attachedWorktree.slug,
|
|
1870
|
+
};
|
|
1871
|
+
}
|
|
1780
1872
|
this.sessionLogger.info({ repoRoot, baseBranch, baseBranchSource: resolvedBase.source }, 'Creating in-repo worktree for new agent');
|
|
1781
1873
|
const createdWorktree = await createInRepoWorktree({
|
|
1782
1874
|
repoRoot,
|
|
@@ -1928,6 +2020,39 @@ export class Session {
|
|
|
1928
2020
|
});
|
|
1929
2021
|
}
|
|
1930
2022
|
}
|
|
2023
|
+
async handleGetDaemonLogTailRequest(msg) {
|
|
2024
|
+
try {
|
|
2025
|
+
const result = await readDaemonLogTail({
|
|
2026
|
+
junctionHome: this.junctionHome,
|
|
2027
|
+
lines: msg.lines,
|
|
2028
|
+
});
|
|
2029
|
+
this.emit({
|
|
2030
|
+
type: 'get_daemon_log_tail_response',
|
|
2031
|
+
payload: {
|
|
2032
|
+
logPath: result.logPath,
|
|
2033
|
+
content: result.content,
|
|
2034
|
+
truncated: result.truncated,
|
|
2035
|
+
lineCount: result.lineCount,
|
|
2036
|
+
error: null,
|
|
2037
|
+
requestId: msg.requestId,
|
|
2038
|
+
},
|
|
2039
|
+
});
|
|
2040
|
+
}
|
|
2041
|
+
catch (error) {
|
|
2042
|
+
this.sessionLogger.error({ err: error }, 'Failed to read daemon log tail');
|
|
2043
|
+
this.emit({
|
|
2044
|
+
type: 'get_daemon_log_tail_response',
|
|
2045
|
+
payload: {
|
|
2046
|
+
logPath: null,
|
|
2047
|
+
content: '',
|
|
2048
|
+
truncated: false,
|
|
2049
|
+
lineCount: 0,
|
|
2050
|
+
error: error instanceof Error ? error.message : String(error),
|
|
2051
|
+
requestId: msg.requestId,
|
|
2052
|
+
},
|
|
2053
|
+
});
|
|
2054
|
+
}
|
|
2055
|
+
}
|
|
1931
2056
|
async handleUpdateDaemonProviderSettingsRequest(msg) {
|
|
1932
2057
|
try {
|
|
1933
2058
|
const snapshot = saveDaemonProviderExecutablePath({
|
|
@@ -2054,10 +2179,12 @@ export class Session {
|
|
|
2054
2179
|
const createWorktree = Boolean(merged.createWorktree);
|
|
2055
2180
|
const createNewBranch = Boolean(merged.createNewBranch);
|
|
2056
2181
|
const normalizedBranchName = merged.newBranchName ? slugify(merged.newBranchName) : undefined;
|
|
2182
|
+
const attachBranchName = merged.attachBranchName?.trim() || undefined;
|
|
2183
|
+
const attachBranchSource = merged.attachBranchSource ?? 'remote';
|
|
2057
2184
|
const normalizedWorktreeSlug = merged.worktreeSlug
|
|
2058
2185
|
? slugify(merged.worktreeSlug)
|
|
2059
|
-
: normalizedBranchName;
|
|
2060
|
-
if (!createWorktree && !createNewBranch && !baseBranch) {
|
|
2186
|
+
: normalizedBranchName ?? (attachBranchName ? slugify(attachBranchName) : undefined);
|
|
2187
|
+
if (!createWorktree && !createNewBranch && !attachBranchName && !baseBranch) {
|
|
2061
2188
|
return null;
|
|
2062
2189
|
}
|
|
2063
2190
|
if (baseBranch) {
|
|
@@ -2075,6 +2202,12 @@ export class Session {
|
|
|
2075
2202
|
throw new Error(`Invalid branch name: ${validation.error}`);
|
|
2076
2203
|
}
|
|
2077
2204
|
}
|
|
2205
|
+
if (attachBranchName) {
|
|
2206
|
+
this.assertSafeGitRef(attachBranchName, 'attach branch');
|
|
2207
|
+
}
|
|
2208
|
+
if (attachBranchName && createNewBranch) {
|
|
2209
|
+
throw new Error('Cannot both attach to an existing branch and create a new branch');
|
|
2210
|
+
}
|
|
2078
2211
|
if (normalizedWorktreeSlug) {
|
|
2079
2212
|
const validation = validateBranchSlug(normalizedWorktreeSlug);
|
|
2080
2213
|
if (!validation.valid) {
|
|
@@ -2089,7 +2222,56 @@ export class Session {
|
|
|
2089
2222
|
newBranchName: normalizedBranchName,
|
|
2090
2223
|
createWorktree,
|
|
2091
2224
|
worktreeSlug: normalizedWorktreeSlug,
|
|
2225
|
+
attachBranchName,
|
|
2226
|
+
attachBranchSource,
|
|
2227
|
+
};
|
|
2228
|
+
}
|
|
2229
|
+
async resolveAttachBranchTarget(options) {
|
|
2230
|
+
const resolveLocalRef = async () => {
|
|
2231
|
+
try {
|
|
2232
|
+
const { stdout } = await execAsync(`git rev-parse refs/heads/${options.branchName}`, {
|
|
2233
|
+
cwd: options.repoRoot,
|
|
2234
|
+
env: READ_ONLY_GIT_ENV,
|
|
2235
|
+
});
|
|
2236
|
+
return {
|
|
2237
|
+
head: stdout.trim(),
|
|
2238
|
+
ref: `refs/heads/${options.branchName}`,
|
|
2239
|
+
};
|
|
2240
|
+
}
|
|
2241
|
+
catch {
|
|
2242
|
+
return null;
|
|
2243
|
+
}
|
|
2092
2244
|
};
|
|
2245
|
+
if (options.branchSource === 'local') {
|
|
2246
|
+
return resolveLocalRef();
|
|
2247
|
+
}
|
|
2248
|
+
const remotes = await listGitRemotes(options.repoRoot);
|
|
2249
|
+
const effectiveRemoteName = options.remoteName && remotes.some((remote) => remote.name === options.remoteName)
|
|
2250
|
+
? options.remoteName
|
|
2251
|
+
: remotes.find((remote) => remote.name === 'origin')?.name ?? remotes[0]?.name;
|
|
2252
|
+
if (!effectiveRemoteName) {
|
|
2253
|
+
return null;
|
|
2254
|
+
}
|
|
2255
|
+
this.assertSafeRemoteName(effectiveRemoteName);
|
|
2256
|
+
try {
|
|
2257
|
+
await execAsync(`git fetch ${effectiveRemoteName} --prune`, { cwd: options.repoRoot });
|
|
2258
|
+
}
|
|
2259
|
+
catch {
|
|
2260
|
+
return null;
|
|
2261
|
+
}
|
|
2262
|
+
try {
|
|
2263
|
+
const { stdout } = await execAsync(`git rev-parse refs/remotes/${effectiveRemoteName}/${options.branchName}`, {
|
|
2264
|
+
cwd: options.repoRoot,
|
|
2265
|
+
env: READ_ONLY_GIT_ENV,
|
|
2266
|
+
});
|
|
2267
|
+
return {
|
|
2268
|
+
head: stdout.trim(),
|
|
2269
|
+
ref: `refs/remotes/${effectiveRemoteName}/${options.branchName}`,
|
|
2270
|
+
};
|
|
2271
|
+
}
|
|
2272
|
+
catch {
|
|
2273
|
+
return null;
|
|
2274
|
+
}
|
|
2093
2275
|
}
|
|
2094
2276
|
assertSafeGitRef(ref, label) {
|
|
2095
2277
|
if (!SAFE_GIT_REF_PATTERN.test(ref) || ref.includes('..') || ref.includes('@{')) {
|
|
@@ -3405,6 +3587,39 @@ export class Session {
|
|
|
3405
3587
|
});
|
|
3406
3588
|
}
|
|
3407
3589
|
}
|
|
3590
|
+
async handleCheckoutPrSearchRequest(msg) {
|
|
3591
|
+
const cwd = expandTilde(msg.cwd);
|
|
3592
|
+
const { requestId } = msg;
|
|
3593
|
+
try {
|
|
3594
|
+
const result = await searchPullRequests(cwd, {
|
|
3595
|
+
query: msg.query,
|
|
3596
|
+
limit: msg.limit,
|
|
3597
|
+
remoteName: msg.remoteName,
|
|
3598
|
+
});
|
|
3599
|
+
this.emit({
|
|
3600
|
+
type: 'checkout_pr_search_response',
|
|
3601
|
+
payload: {
|
|
3602
|
+
cwd,
|
|
3603
|
+
pullRequests: result.pullRequests,
|
|
3604
|
+
githubFeaturesEnabled: result.githubFeaturesEnabled,
|
|
3605
|
+
error: null,
|
|
3606
|
+
requestId,
|
|
3607
|
+
},
|
|
3608
|
+
});
|
|
3609
|
+
}
|
|
3610
|
+
catch (error) {
|
|
3611
|
+
this.emit({
|
|
3612
|
+
type: 'checkout_pr_search_response',
|
|
3613
|
+
payload: {
|
|
3614
|
+
cwd,
|
|
3615
|
+
pullRequests: [],
|
|
3616
|
+
githubFeaturesEnabled: true,
|
|
3617
|
+
error: this.toCheckoutError(error),
|
|
3618
|
+
requestId,
|
|
3619
|
+
},
|
|
3620
|
+
});
|
|
3621
|
+
}
|
|
3622
|
+
}
|
|
3408
3623
|
async handleCheckoutPrFailureLogsRequest(msg) {
|
|
3409
3624
|
const { cwd, requestId } = msg;
|
|
3410
3625
|
try {
|