skydive-cli 0.5.0-beta.14 → 0.5.0-beta.15
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/js/bin.mjs +7 -7
- package/dist/js/{boot-CJKq8rvL.mjs → boot-DZKl8JNI.mjs} +150 -50
- package/dist/js/{daemon-DjsUMczp.mjs → daemon-Djei8xaW.mjs} +1 -1
- package/dist/js/daemon-client-Bemq-pLd.mjs +7 -0
- package/dist/js/{daemon-client-k8ICifN2.mjs → daemon-client-N8rvGusv.mjs} +1 -1
- package/dist/js/{daemon-CL25CwjW.mjs → daemon-eb9dm6Ih.mjs} +1 -1
- package/dist/js/{profiler-COGO4LN8.mjs → profiler-B97UpfHm.mjs} +1 -1
- package/package.json +1 -1
- package/dist/js/daemon-client-DEyOdfdA.mjs +0 -7
package/dist/js/bin.mjs
CHANGED
|
@@ -1,12 +1,12 @@
|
|
|
1
1
|
#!/usr/bin/env node
|
|
2
|
-
import { C as ensureActiveOrganization, D as setActiveWorkspace, E as listWorkspaces, O as name, T as getSessionIdentity, a as installCrashHandler, k as version, t as maybeStartProfiling, u as brandHelpArt, w as getActiveWorkspaceId, x as themes } from "./profiler-
|
|
2
|
+
import { C as ensureActiveOrganization, D as setActiveWorkspace, E as listWorkspaces, O as name, T as getSessionIdentity, a as installCrashHandler, k as version, t as maybeStartProfiling, u as brandHelpArt, w as getActiveWorkspaceId, x as themes } from "./profiler-B97UpfHm.mjs";
|
|
3
3
|
import { A as getStoredApiKeyId, B as saveConfig, C as getDefaultAgent, E as getPromptHistoryPath, F as resolveChatAuth, I as resolveConfig, L as resolveManagementAuth, M as getUpdateCheckDisabled, P as resolveAppUrl, R as resolveSession, S as getConfigPath, T as getPreference, U as setLastSeenVersion, V as saveSession, _ as API_KEY_PREFIX, b as PREFERENCES, g as API_KEY_FAMILY_PREFIX, h as API_KEYS_URL, i as resolveAgent, j as getStoredApiKeyWorkspaceName, k as getShareMachineDefault, v as DEFAULT_API_URL, w as getLastSeenVersion, x as deleteConfig } from "./print-riiY5Gly.mjs";
|
|
4
4
|
import { n as printError, r as printTable, t as output } from "./output-DYzzdXYV.mjs";
|
|
5
5
|
import { t as HttpError } from "./http-error-DzyrsLAZ.mjs";
|
|
6
6
|
import { t as createRestClient } from "./rest-CLrHVkxh.mjs";
|
|
7
7
|
import "./billing-blocked-2wju4gC_.mjs";
|
|
8
8
|
import { r as resolveMachineIdentity } from "./client-DbqRBquD.mjs";
|
|
9
|
-
import { i as queryDaemonStatus, l as PORTAL_DAEMON_FLAG, n as ensureDaemonRunning, s as stopDaemon, u as daemonPaths } from "./daemon-
|
|
9
|
+
import { i as queryDaemonStatus, l as PORTAL_DAEMON_FLAG, n as ensureDaemonRunning, s as stopDaemon, u as daemonPaths } from "./daemon-eb9dm6Ih.mjs";
|
|
10
10
|
import { i as grantPortalAccess, n as fetchPortalDevices, o as registerPortalDevice, r as findThisDevice, s as revokePortalAccess } from "./api-DG5W6iwx.mjs";
|
|
11
11
|
import { t as SandboxStream } from "./client-c4c5MmgN.mjs";
|
|
12
12
|
import { hideBin } from "yargs/helpers";
|
|
@@ -1517,7 +1517,7 @@ const importCommand = {
|
|
|
1517
1517
|
process.exit(1);
|
|
1518
1518
|
}
|
|
1519
1519
|
}
|
|
1520
|
-
const { runChat } = await import("./boot-
|
|
1520
|
+
const { runChat } = await import("./boot-DZKl8JNI.mjs");
|
|
1521
1521
|
await runChat({
|
|
1522
1522
|
appUrl,
|
|
1523
1523
|
sessionToken: session.value.sessionToken,
|
|
@@ -1930,7 +1930,7 @@ const chatCommand = {
|
|
|
1930
1930
|
sessionToken: auth.value.token,
|
|
1931
1931
|
agentSelector: argv.agent ?? null
|
|
1932
1932
|
});
|
|
1933
|
-
const { runChat } = await import("./boot-
|
|
1933
|
+
const { runChat } = await import("./boot-DZKl8JNI.mjs");
|
|
1934
1934
|
await runChat({
|
|
1935
1935
|
appUrl: auth.value.appUrl,
|
|
1936
1936
|
sessionToken: auth.value.token,
|
|
@@ -2290,7 +2290,7 @@ const switchCommand = {
|
|
|
2290
2290
|
printError("The workspace picker needs the Bun runtime and it could not be set up automatically. Pass a workspace slug instead, or install Bun and retry.");
|
|
2291
2291
|
process.exit(1);
|
|
2292
2292
|
}
|
|
2293
|
-
const { runWorkspacePicker } = await import("./boot-
|
|
2293
|
+
const { runWorkspacePicker } = await import("./boot-DZKl8JNI.mjs");
|
|
2294
2294
|
await runWorkspacePicker(session);
|
|
2295
2295
|
return;
|
|
2296
2296
|
}
|
|
@@ -2369,7 +2369,7 @@ const openCommand = {
|
|
|
2369
2369
|
const agent = argv.agent ? resolveAgent((await fetchPortalDevices(session)).agents, argv.agent) : null;
|
|
2370
2370
|
const cwd = argv.cwd ? path.resolve(argv.cwd) : process.cwd();
|
|
2371
2371
|
const { machineName } = await resolveMachineIdentity(null);
|
|
2372
|
-
const { PortalDaemonClient } = await import("./daemon-client-
|
|
2372
|
+
const { PortalDaemonClient } = await import("./daemon-client-Bemq-pLd.mjs");
|
|
2373
2373
|
let lastLine = "";
|
|
2374
2374
|
let signalConnected;
|
|
2375
2375
|
const connected = new Promise((resolve) => {
|
|
@@ -4215,7 +4215,7 @@ if (process.argv.includes(UPDATE_WORKER_FLAG)) {
|
|
|
4215
4215
|
process.exit(0);
|
|
4216
4216
|
}
|
|
4217
4217
|
if (process.argv.includes(PORTAL_DAEMON_FLAG)) {
|
|
4218
|
-
const { runPortalDaemon } = await import("./daemon-
|
|
4218
|
+
const { runPortalDaemon } = await import("./daemon-Djei8xaW.mjs");
|
|
4219
4219
|
runPortalDaemon(process.argv);
|
|
4220
4220
|
} else runCli();
|
|
4221
4221
|
function runCli() {
|
|
@@ -1,14 +1,14 @@
|
|
|
1
1
|
#!/usr/bin/env node
|
|
2
|
-
import { D as setActiveWorkspace, E as listWorkspaces, S as themesForMode, _ as themeForMode, a as installCrashHandler, b as themeVersion, c as MARK_CELLS, d as DEFAULT_THEME_ID, f as applyTheme, g as theme, h as noColorRequested, i as writeArtifact, l as WORDMARK, m as monoTheme, n as profilingEnabled, o as buildCrashReport, p as findTheme, r as record, s as writeCrashReport, v as themeMode, w as getActiveWorkspaceId, y as themeModeFromColorFgBg } from "./profiler-
|
|
2
|
+
import { D as setActiveWorkspace, E as listWorkspaces, S as themesForMode, _ as themeForMode, a as installCrashHandler, b as themeVersion, c as MARK_CELLS, d as DEFAULT_THEME_ID, f as applyTheme, g as theme, h as noColorRequested, i as writeArtifact, l as WORDMARK, m as monoTheme, n as profilingEnabled, o as buildCrashReport, p as findTheme, r as record, s as writeCrashReport, v as themeMode, w as getActiveWorkspaceId, y as themeModeFromColorFgBg } from "./profiler-B97UpfHm.mjs";
|
|
3
3
|
import { D as getReviewStateDir, H as saveTheme, N as recordDefaultAgent, O as getSavedTheme, S as getConfigPath, c as cardActionErrorMessage, d as reconcileMaskedInput, f as resolveConnectUrl, i as resolveAgent, l as parseExternalOauthConnectParams, m as specKeyFor, p as parseConnectCard, s as MASK_CHAR, u as parseOauthConnectParams, v as DEFAULT_API_URL, y as DEFAULT_APP_URL, z as resolveWebUrl } from "./print-riiY5Gly.mjs";
|
|
4
4
|
import { t as HttpError } from "./http-error-DzyrsLAZ.mjs";
|
|
5
5
|
import { a as isRecord, i as errorMessage, n as errorDetail, r as sendErrorMessage, t as createRestClient } from "./rest-CLrHVkxh.mjs";
|
|
6
6
|
import { i as billingBlockedOutcomeFromSendResponse } from "./billing-blocked-2wju4gC_.mjs";
|
|
7
7
|
import { t as PortalClient } from "./client-DbqRBquD.mjs";
|
|
8
|
-
import "./daemon-
|
|
8
|
+
import "./daemon-eb9dm6Ih.mjs";
|
|
9
9
|
import "./api-DG5W6iwx.mjs";
|
|
10
10
|
import { t as SandboxStream } from "./client-c4c5MmgN.mjs";
|
|
11
|
-
import { t as PortalDaemonClient } from "./daemon-client-
|
|
11
|
+
import { t as PortalDaemonClient } from "./daemon-client-N8rvGusv.mjs";
|
|
12
12
|
import { t as runRawPtyPassthrough } from "./raw-pty-DY4KelZW.mjs";
|
|
13
13
|
import * as os$1 from "node:os";
|
|
14
14
|
import { homedir, platform, release, tmpdir } from "node:os";
|
|
@@ -1080,42 +1080,133 @@ function createAgentHost({ renderer, notifications }) {
|
|
|
1080
1080
|
* take the one host we can identify unambiguously (github.com, incl. `www.`),
|
|
1081
1081
|
* which covers the common product case; GHES stays the native badge's job.
|
|
1082
1082
|
*
|
|
1083
|
-
* Only the `/pull/<n>` form (not `/issues
|
|
1084
|
-
*
|
|
1085
|
-
*
|
|
1086
|
-
*
|
|
1087
|
-
*
|
|
1088
|
-
|
|
1089
|
-
|
|
1090
|
-
|
|
1091
|
-
*
|
|
1092
|
-
*
|
|
1093
|
-
*
|
|
1094
|
-
*
|
|
1095
|
-
*
|
|
1096
|
-
*
|
|
1097
|
-
*/
|
|
1098
|
-
|
|
1099
|
-
|
|
1100
|
-
|
|
1101
|
-
|
|
1083
|
+
* Only the `/pull/<n>` form (not `/issues/`). A trailing path/query/fragment
|
|
1084
|
+
* (e.g. `/files`, `#discussion`) is allowed but not captured into the canonical
|
|
1085
|
+
* URL. Also matches inside markdown links, backticks, and trailing punctuation.
|
|
1086
|
+
*
|
|
1087
|
+
* The `https://` (and `www.`) prefix is optional: agents and people routinely
|
|
1088
|
+
* write a bare `github.com/o/r/pull/7`, and that should link a PR the same way
|
|
1089
|
+
* the full URL does. To keep a bare host from matching inside a longer hostname
|
|
1090
|
+
* (`mygithub.com/...`, `notgithub.com/...`), a protocol-less match must be
|
|
1091
|
+
* preceded by a start-of-string or a non-host character (anything but a word
|
|
1092
|
+
* char or `.`) — a leading boundary the `(?:^|[^\w.])` group asserts and
|
|
1093
|
+
* consumes. The consumed boundary char is outside the captured groups, so it
|
|
1094
|
+
* never leaks into owner/repo. `matchAll` won't overlap, but the boundary is a
|
|
1095
|
+
* single delimiter (space, `(`, `[`, etc.) between PRs in practice, so distinct
|
|
1096
|
+
* back-to-back URLs still each match.
|
|
1097
|
+
*/
|
|
1098
|
+
const PR_URL_RE = /(?:^|[^\w.])(?:https?:\/\/)?(?:www\.)?github\.com\/([\w.-]+)\/([\w.-]+)\/pull\/(\d+)/gi;
|
|
1099
|
+
/**
|
|
1100
|
+
* Matches a bare, human-style PR reference `#<n>` — the way people (and LLMs)
|
|
1101
|
+
* name a PR in prose ("opened #20858", "landed #42"). Requires a non-word
|
|
1102
|
+
* boundary before the `#` so a fragment tail like `/pull/7#discussion_r5` or a
|
|
1103
|
+
* hex color `#20858` embedded in a word doesn't count, and captures the digits
|
|
1104
|
+
* up to a word boundary. We only harvest these from **assistant prose**, never
|
|
1105
|
+
* from tool output, because `#N` is exactly the relevance signal we're after:
|
|
1106
|
+
* the agent chose to talk about this PR.
|
|
1107
|
+
*/
|
|
1108
|
+
const PR_HASH_RE = /(?:^|[^\w#/])#(\d+)\b/g;
|
|
1109
|
+
/**
|
|
1110
|
+
* Every full `/pull/<n>` github.com URL in `urlText`, keyed by number to the
|
|
1111
|
+
* candidate refs for that number. A number can map to more than one repo, so we
|
|
1112
|
+
* keep all candidates; a bare `#N` label can't say which repo, but the pill's
|
|
1113
|
+
* own URL does. Deduped by repo-qualified identity (`owner/repo#number`) so the
|
|
1114
|
+
* same PR linked twice — even with a different trailing path/fragment —
|
|
1115
|
+
* collapses to one ref.
|
|
1116
|
+
*
|
|
1117
|
+
* `deferTrailingNumber` guards the streaming truncation case: when true, a URL
|
|
1118
|
+
* whose number runs to the very end of `urlText` is skipped because the next
|
|
1119
|
+
* delta may extend those digits (`.../pull/19` now, `.../pull/19739` later).
|
|
1120
|
+
* Only the still-growing PROSE buffer sets this; settled tool output is always
|
|
1121
|
+
* complete, so its URLs are harvested with the guard off.
|
|
1122
|
+
*/
|
|
1123
|
+
function urlsByNumber(urlText, deferTrailingNumber, byNumber) {
|
|
1124
|
+
for (const match of urlText.matchAll(PR_URL_RE)) {
|
|
1102
1125
|
const owner = match[1];
|
|
1103
1126
|
const repo = match[2];
|
|
1104
1127
|
const numberText = match[3];
|
|
1105
1128
|
if (!owner || !repo || !numberText) continue;
|
|
1106
|
-
if (
|
|
1107
|
-
if (match.index + match[0].length >=
|
|
1129
|
+
if (deferTrailingNumber) {
|
|
1130
|
+
if (match.index + match[0].length >= urlText.length) continue;
|
|
1108
1131
|
}
|
|
1109
1132
|
const number = Number.parseInt(numberText, 10);
|
|
1110
1133
|
if (!Number.isFinite(number) || number <= 0) continue;
|
|
1111
|
-
const
|
|
1112
|
-
if (byKey.has(key)) continue;
|
|
1113
|
-
byKey.set(key, {
|
|
1134
|
+
const ref = {
|
|
1114
1135
|
number,
|
|
1115
|
-
key
|
|
1136
|
+
key: `${owner.toLowerCase()}/${repo.toLowerCase()}#${number}`,
|
|
1116
1137
|
url: `https://github.com/${owner}/${repo}/pull/${number}`
|
|
1117
|
-
}
|
|
1138
|
+
};
|
|
1139
|
+
const existing = byNumber.get(number);
|
|
1140
|
+
if (existing) {
|
|
1141
|
+
if (!existing.some((r) => r.key === ref.key)) existing.push(ref);
|
|
1142
|
+
} else byNumber.set(number, [ref]);
|
|
1118
1143
|
}
|
|
1144
|
+
}
|
|
1145
|
+
/** Every human-style `#N` named in `proseText` — the relevance signal. */
|
|
1146
|
+
function hashNumbers(proseText) {
|
|
1147
|
+
const numbers = /* @__PURE__ */ new Set();
|
|
1148
|
+
for (const match of proseText.matchAll(PR_HASH_RE)) {
|
|
1149
|
+
const numberText = match[1];
|
|
1150
|
+
if (!numberText) continue;
|
|
1151
|
+
const number = Number.parseInt(numberText, 10);
|
|
1152
|
+
if (Number.isFinite(number) && number > 0) numbers.add(number);
|
|
1153
|
+
}
|
|
1154
|
+
return numbers;
|
|
1155
|
+
}
|
|
1156
|
+
/**
|
|
1157
|
+
* The relevance contract, in one place.
|
|
1158
|
+
*
|
|
1159
|
+
* A GitHub PR URL is cheap to emit and shows up in bulk any time a tool dumps
|
|
1160
|
+
* PRs the conversation isn't actually about — `gh pr list`, `gh pr status`, a
|
|
1161
|
+
* `gh search` — printing dozens of `/pull/N` URLs the agent never discusses.
|
|
1162
|
+
* Pinning a sidebar pill for every one of those is noise.
|
|
1163
|
+
*
|
|
1164
|
+
* So a PR is surfaced only when BOTH hold:
|
|
1165
|
+
* 1. a fully-qualified `github.com/<o>/<r>/pull/<n>` URL exists — this may
|
|
1166
|
+
* come from the assistant's prose OR from tool output (a `gh pr create`
|
|
1167
|
+
* that printed the URL the agent then referenced by number), and
|
|
1168
|
+
* 2. the **assistant's prose** names the number as a human-style `#<n>`.
|
|
1169
|
+
*
|
|
1170
|
+
* The `#N` in prose is the intent signal — "the agent is talking about this
|
|
1171
|
+
* PR", as opposed to "a tool happened to list it". The full URL (from wherever)
|
|
1172
|
+
* proves the PR is real and pins down its repo + canonical link. A URL with no
|
|
1173
|
+
* `#N` in prose (the whole of a `gh pr list` dump) is dropped; a `#N` with no
|
|
1174
|
+
* matching URL anywhere (a bare issue-style ref) is dropped.
|
|
1175
|
+
*
|
|
1176
|
+
* `proseText` is the assistant's prose alone (the only source of the `#N`
|
|
1177
|
+
* relevance signal); `urlOnlyText` is settled tool output that may carry full
|
|
1178
|
+
* PR URLs but no `#N` intent. URLs are harvested from both; `#N` from prose
|
|
1179
|
+
* only.
|
|
1180
|
+
*/
|
|
1181
|
+
function collectRelevant(proseText, urlOnlyText, options, byKey) {
|
|
1182
|
+
const byNumber = /* @__PURE__ */ new Map();
|
|
1183
|
+
urlsByNumber(proseText, options.requireCompleteNumber, byNumber);
|
|
1184
|
+
if (urlOnlyText) urlsByNumber(urlOnlyText, false, byNumber);
|
|
1185
|
+
if (byNumber.size === 0) return;
|
|
1186
|
+
const named = hashNumbers(proseText);
|
|
1187
|
+
if (named.size === 0) return;
|
|
1188
|
+
for (const [number, refs] of byNumber) {
|
|
1189
|
+
if (!named.has(number)) continue;
|
|
1190
|
+
for (const ref of refs) if (!byKey.has(ref.key)) byKey.set(ref.key, ref);
|
|
1191
|
+
}
|
|
1192
|
+
}
|
|
1193
|
+
/**
|
|
1194
|
+
* Extracts every distinct GitHub PR that is both linked (a full `/pull/<n>`
|
|
1195
|
+
* URL) AND named (`#<n>`), de-duplicated by **repo-qualified identity**
|
|
1196
|
+
* (`owner/repo#number`) — NOT by number, since `#42` can exist in many repos.
|
|
1197
|
+
*
|
|
1198
|
+
* The two-argument form takes the URL pool and the prose separately, so a URL
|
|
1199
|
+
* from tool output can satisfy the link requirement while the `#N` stays a
|
|
1200
|
+
* prose-only signal. The one-argument form (prose only) is the common case: it
|
|
1201
|
+
* requires the URL to be in the same prose that names it.
|
|
1202
|
+
*
|
|
1203
|
+
* See {@link collectRelevant} for the contract.
|
|
1204
|
+
*/
|
|
1205
|
+
function extractPullRequests(proseText, options) {
|
|
1206
|
+
const requireCompleteNumber = options?.requireCompleteNumber ?? true;
|
|
1207
|
+
const urlOnly = options?.urlOnlyText ?? "";
|
|
1208
|
+
const byKey = /* @__PURE__ */ new Map();
|
|
1209
|
+
collectRelevant(proseText, urlOnly, { requireCompleteNumber }, byKey);
|
|
1119
1210
|
return [...byKey.values()];
|
|
1120
1211
|
}
|
|
1121
1212
|
/**
|
|
@@ -1154,28 +1245,34 @@ function stringifyToolOutput(value) {
|
|
|
1154
1245
|
}
|
|
1155
1246
|
/**
|
|
1156
1247
|
* A streaming PR scanner: fed run chunks as they stream, it reports each
|
|
1157
|
-
* distinct PR the moment
|
|
1158
|
-
* the
|
|
1248
|
+
* distinct PR the moment BOTH conditions hold — a full `/pull/<n>` URL has been
|
|
1249
|
+
* seen (in prose OR tool output) AND the assistant's prose names it `#<n>` —
|
|
1250
|
+
* exactly once, without ever rescanning the transcript.
|
|
1159
1251
|
*
|
|
1160
|
-
*
|
|
1161
|
-
*
|
|
1162
|
-
*
|
|
1163
|
-
*
|
|
1164
|
-
*
|
|
1165
|
-
*
|
|
1166
|
-
*
|
|
1252
|
+
* Two sources feed it, with different roles:
|
|
1253
|
+
* - **Assistant text** (`text-delta`): the ONLY source of the `#N` relevance
|
|
1254
|
+
* signal, and also a source of URLs. Accumulated per part id (a URL or `#N`
|
|
1255
|
+
* can split across two deltas); only the current part's buffer is scanned.
|
|
1256
|
+
* - **Tool output** (`tool-output-available`): a URL-only source. A
|
|
1257
|
+
* `gh pr create` prints the URL the agent then references by number, so the
|
|
1258
|
+
* URL for a #N mention often lives here, not in the prose. Tool output can
|
|
1259
|
+
* NEVER originate a pill on its own — a `gh pr list` dump (URLs, no `#N`)
|
|
1260
|
+
* stays silent — but it satisfies the URL half for a PR the prose names.
|
|
1167
1261
|
*
|
|
1168
1262
|
* `onPullRequest` fires once per never-before-seen PR (keyed by
|
|
1169
|
-
* `owner/repo#number`)
|
|
1170
|
-
*
|
|
1171
|
-
* same chunks the transcript reducer sees.
|
|
1263
|
+
* `owner/repo#number`). Construct one per run (or per conversation) and feed it
|
|
1264
|
+
* the same chunks the transcript reducer sees. See {@link collectRelevant}.
|
|
1172
1265
|
*/
|
|
1173
1266
|
function createPullRequestScanner(onPullRequest) {
|
|
1174
1267
|
let text = "";
|
|
1175
1268
|
let lastPartId;
|
|
1269
|
+
let toolUrlText = "";
|
|
1176
1270
|
const seen = /* @__PURE__ */ new Set();
|
|
1177
|
-
const report = (
|
|
1178
|
-
for (const pr of extractPullRequests(
|
|
1271
|
+
const report = (final) => {
|
|
1272
|
+
for (const pr of extractPullRequests(text, {
|
|
1273
|
+
requireCompleteNumber: !final,
|
|
1274
|
+
urlOnlyText: toolUrlText
|
|
1275
|
+
})) {
|
|
1179
1276
|
if (seen.has(pr.key)) continue;
|
|
1180
1277
|
seen.add(pr.key);
|
|
1181
1278
|
onPullRequest(pr);
|
|
@@ -1185,7 +1282,8 @@ function createPullRequestScanner(onPullRequest) {
|
|
|
1185
1282
|
if (chunk["type"] === "tool-output-available") {
|
|
1186
1283
|
const outputText = stringifyToolOutput(chunk["output"]);
|
|
1187
1284
|
if (!outputText.includes("/pull/")) return;
|
|
1188
|
-
|
|
1285
|
+
toolUrlText += `\n${outputText}`;
|
|
1286
|
+
report(true);
|
|
1189
1287
|
return;
|
|
1190
1288
|
}
|
|
1191
1289
|
if (chunk["type"] !== "text-delta") return;
|
|
@@ -1193,13 +1291,12 @@ function createPullRequestScanner(onPullRequest) {
|
|
|
1193
1291
|
if (!delta) return;
|
|
1194
1292
|
const partId = typeof chunk["id"] === "string" ? chunk["id"] : void 0;
|
|
1195
1293
|
if (partId && lastPartId && partId !== lastPartId) {
|
|
1196
|
-
|
|
1294
|
+
report(true);
|
|
1197
1295
|
text = "";
|
|
1198
1296
|
}
|
|
1199
1297
|
text += delta;
|
|
1200
1298
|
lastPartId = partId ?? lastPartId;
|
|
1201
|
-
|
|
1202
|
-
report(text, false);
|
|
1299
|
+
report(false);
|
|
1203
1300
|
} };
|
|
1204
1301
|
}
|
|
1205
1302
|
|
|
@@ -10886,10 +10983,13 @@ function ChatScreen({ agent, conversation }) {
|
|
|
10886
10983
|
text: recapText
|
|
10887
10984
|
});
|
|
10888
10985
|
setItems(loaded);
|
|
10986
|
+
const toolUrlText = loaded.map((item) => item.kind === "tool" && item.output?.kind === "ok" ? stringifyToolOutput(item.output.value) : "").join("\n");
|
|
10889
10987
|
for (const item of loaded) {
|
|
10890
|
-
|
|
10891
|
-
|
|
10892
|
-
|
|
10988
|
+
if (item.kind !== "assistant-text") continue;
|
|
10989
|
+
for (const pr of extractPullRequests(item.text, {
|
|
10990
|
+
requireCompleteNumber: false,
|
|
10991
|
+
urlOnlyText: toolUrlText
|
|
10992
|
+
})) {
|
|
10893
10993
|
if (reportedPrsRef.current.has(pr.key)) continue;
|
|
10894
10994
|
reportedPrsRef.current.set(pr.key, pr);
|
|
10895
10995
|
setPrLinks((prev) => [...prev, pr]);
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
#!/usr/bin/env node
|
|
2
2
|
import "./client-DbqRBquD.mjs";
|
|
3
|
-
import { a as runPortalDaemon, i as queryDaemonStatus, n as ensureDaemonRunning, o as startPortalDaemon, r as isDaemonListening, s as stopDaemon, t as PortalDaemon } from "./daemon-
|
|
3
|
+
import { a as runPortalDaemon, i as queryDaemonStatus, n as ensureDaemonRunning, o as startPortalDaemon, r as isDaemonListening, s as stopDaemon, t as PortalDaemon } from "./daemon-eb9dm6Ih.mjs";
|
|
4
4
|
import "./api-DG5W6iwx.mjs";
|
|
5
5
|
|
|
6
6
|
export { runPortalDaemon };
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
#!/usr/bin/env node
|
|
2
|
-
import { c as LOCAL_PROTOCOL_VERSION, d as encodeLine, f as makeLineParser, n as ensureDaemonRunning, p as parseDaemonMessage, u as daemonPaths } from "./daemon-
|
|
2
|
+
import { c as LOCAL_PROTOCOL_VERSION, d as encodeLine, f as makeLineParser, n as ensureDaemonRunning, p as parseDaemonMessage, u as daemonPaths } from "./daemon-eb9dm6Ih.mjs";
|
|
3
3
|
import { randomUUID } from "node:crypto";
|
|
4
4
|
import { connect } from "node:net";
|
|
5
5
|
|
|
@@ -20,7 +20,7 @@ import { access, appendFile, mkdir, readFile, unlink, writeFile } from "node:fs/
|
|
|
20
20
|
* the commit time of the built tree is one monotonic clock they share.
|
|
21
21
|
*/
|
|
22
22
|
function portalDaemonBuild() {
|
|
23
|
-
return "
|
|
23
|
+
return "1786605017";
|
|
24
24
|
}
|
|
25
25
|
/**
|
|
26
26
|
* Whether a client carrying `mine` should replace a running daemon carrying
|
package/package.json
CHANGED