ur-agent 1.22.0 → 1.22.1
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/CHANGELOG.md +62 -0
- package/README.md +9 -2
- package/dist/cli.js +1558 -604
- package/docs/AGENT_FEATURES.md +7 -0
- package/docs/USAGE.md +8 -1
- package/documentation/index.html +1 -1
- package/extensions/vscode-ur-inline-diffs/package.json +1 -1
- package/package.json +1 -1
package/dist/cli.js
CHANGED
|
@@ -16939,7 +16939,7 @@ function formatAgentTrendReport(report = buildAgentTrendReport()) {
|
|
|
16939
16939
|
function formatA2AAgentCard(options = {}, pretty = true) {
|
|
16940
16940
|
return JSON.stringify(buildA2AAgentCard(options), null, pretty ? 2 : 0);
|
|
16941
16941
|
}
|
|
16942
|
-
var urVersion = "1.22.
|
|
16942
|
+
var urVersion = "1.22.1", coverage, priorityRoadmap;
|
|
16943
16943
|
var init_trends = __esm(() => {
|
|
16944
16944
|
coverage = [
|
|
16945
16945
|
{
|
|
@@ -71247,7 +71247,7 @@ var init_auth = __esm(() => {
|
|
|
71247
71247
|
|
|
71248
71248
|
// src/utils/userAgent.ts
|
|
71249
71249
|
function getURCodeUserAgent() {
|
|
71250
|
-
return `ur/${"1.22.
|
|
71250
|
+
return `ur/${"1.22.1"}`;
|
|
71251
71251
|
}
|
|
71252
71252
|
|
|
71253
71253
|
// src/utils/workloadContext.ts
|
|
@@ -71269,7 +71269,7 @@ function getUserAgent() {
|
|
|
71269
71269
|
const clientApp = process.env.UR_AGENT_SDK_CLIENT_APP ? `, client-app/${process.env.UR_AGENT_SDK_CLIENT_APP}` : "";
|
|
71270
71270
|
const workload = getWorkload();
|
|
71271
71271
|
const workloadSuffix = workload ? `, workload/${workload}` : "";
|
|
71272
|
-
return `ur-cli/${"1.22.
|
|
71272
|
+
return `ur-cli/${"1.22.1"} (${process.env.USER_TYPE}, ${process.env.UR_CODE_ENTRYPOINT ?? "cli"}${agentSdkVersion}${clientApp}${workloadSuffix})`;
|
|
71273
71273
|
}
|
|
71274
71274
|
function getMCPUserAgent() {
|
|
71275
71275
|
const parts = [];
|
|
@@ -71283,7 +71283,7 @@ function getMCPUserAgent() {
|
|
|
71283
71283
|
parts.push(`client-app/${process.env.UR_AGENT_SDK_CLIENT_APP}`);
|
|
71284
71284
|
}
|
|
71285
71285
|
const suffix = parts.length > 0 ? ` (${parts.join(", ")})` : "";
|
|
71286
|
-
return `ur/${"1.22.
|
|
71286
|
+
return `ur/${"1.22.1"}${suffix}`;
|
|
71287
71287
|
}
|
|
71288
71288
|
function getWebFetchUserAgent() {
|
|
71289
71289
|
return `UR-User (${getURCodeUserAgent()})`;
|
|
@@ -71421,7 +71421,7 @@ var init_user = __esm(() => {
|
|
|
71421
71421
|
deviceId,
|
|
71422
71422
|
sessionId: getSessionId(),
|
|
71423
71423
|
email: getEmail(),
|
|
71424
|
-
appVersion: "1.22.
|
|
71424
|
+
appVersion: "1.22.1",
|
|
71425
71425
|
platform: getHostPlatformForAnalytics(),
|
|
71426
71426
|
organizationUuid,
|
|
71427
71427
|
accountUuid,
|
|
@@ -77198,7 +77198,7 @@ var init_metadata = __esm(() => {
|
|
|
77198
77198
|
COMPOUND_OPERATOR_REGEX = /\s*(?:&&|\|\||[;|])\s*/;
|
|
77199
77199
|
WHITESPACE_REGEX = /\s+/;
|
|
77200
77200
|
getVersionBase = memoize_default(() => {
|
|
77201
|
-
const match = "1.22.
|
|
77201
|
+
const match = "1.22.1".match(/^\d+\.\d+\.\d+(?:-[a-z]+)?/);
|
|
77202
77202
|
return match ? match[0] : undefined;
|
|
77203
77203
|
});
|
|
77204
77204
|
buildEnvContext = memoize_default(async () => {
|
|
@@ -77238,7 +77238,7 @@ var init_metadata = __esm(() => {
|
|
|
77238
77238
|
isGithubAction: isEnvTruthy(process.env.GITHUB_ACTIONS),
|
|
77239
77239
|
isURCodeAction: isEnvTruthy(process.env.UR_CODE_ACTION),
|
|
77240
77240
|
isURAiAuth: isURAISubscriber2(),
|
|
77241
|
-
version: "1.22.
|
|
77241
|
+
version: "1.22.1",
|
|
77242
77242
|
versionBase: getVersionBase(),
|
|
77243
77243
|
buildTime: "",
|
|
77244
77244
|
deploymentEnvironment: env2.detectDeploymentEnvironment(),
|
|
@@ -77908,7 +77908,7 @@ function initialize1PEventLogging() {
|
|
|
77908
77908
|
const platform2 = getPlatform();
|
|
77909
77909
|
const attributes = {
|
|
77910
77910
|
[import_semantic_conventions4.ATTR_SERVICE_NAME]: "ur",
|
|
77911
|
-
[import_semantic_conventions4.ATTR_SERVICE_VERSION]: "1.22.
|
|
77911
|
+
[import_semantic_conventions4.ATTR_SERVICE_VERSION]: "1.22.1"
|
|
77912
77912
|
};
|
|
77913
77913
|
if (platform2 === "wsl") {
|
|
77914
77914
|
const wslVersion = getWslVersion();
|
|
@@ -77935,7 +77935,7 @@ function initialize1PEventLogging() {
|
|
|
77935
77935
|
})
|
|
77936
77936
|
]
|
|
77937
77937
|
});
|
|
77938
|
-
firstPartyEventLogger = firstPartyEventLoggerProvider.getLogger("com.urhq.ur.events", "1.22.
|
|
77938
|
+
firstPartyEventLogger = firstPartyEventLoggerProvider.getLogger("com.urhq.ur.events", "1.22.1");
|
|
77939
77939
|
}
|
|
77940
77940
|
async function reinitialize1PEventLoggingIfConfigChanged() {
|
|
77941
77941
|
if (!is1PEventLoggingEnabled() || !firstPartyEventLoggerProvider) {
|
|
@@ -79803,7 +79803,7 @@ function getAttributionHeader(fingerprint) {
|
|
|
79803
79803
|
if (!isAttributionHeaderEnabled()) {
|
|
79804
79804
|
return "";
|
|
79805
79805
|
}
|
|
79806
|
-
const version2 = `${"1.22.
|
|
79806
|
+
const version2 = `${"1.22.1"}.${fingerprint}`;
|
|
79807
79807
|
const entrypoint = process.env.UR_CODE_ENTRYPOINT ?? "unknown";
|
|
79808
79808
|
const cch = "";
|
|
79809
79809
|
const workload = getWorkload();
|
|
@@ -186485,7 +186485,7 @@ function getTelemetryAttributes() {
|
|
|
186485
186485
|
attributes["session.id"] = sessionId;
|
|
186486
186486
|
}
|
|
186487
186487
|
if (shouldIncludeAttribute("OTEL_METRICS_INCLUDE_VERSION")) {
|
|
186488
|
-
attributes["app.version"] = "1.22.
|
|
186488
|
+
attributes["app.version"] = "1.22.1";
|
|
186489
186489
|
}
|
|
186490
186490
|
const oauthAccount = getOauthAccountInfo();
|
|
186491
186491
|
if (oauthAccount) {
|
|
@@ -222539,7 +222539,7 @@ function getInstallationEnv() {
|
|
|
222539
222539
|
return;
|
|
222540
222540
|
}
|
|
222541
222541
|
function getURCodeVersion() {
|
|
222542
|
-
return "1.22.
|
|
222542
|
+
return "1.22.1";
|
|
222543
222543
|
}
|
|
222544
222544
|
async function getInstalledVSCodeExtensionVersion(command) {
|
|
222545
222545
|
const { stdout } = await execFileNoThrow(command, ["--list-extensions", "--show-versions"], {
|
|
@@ -225267,7 +225267,7 @@ async function setupSdkMcpClients(sdkMcpConfigs, sendMcpMessage) {
|
|
|
225267
225267
|
const client2 = new Client({
|
|
225268
225268
|
name: "ur",
|
|
225269
225269
|
title: "UR",
|
|
225270
|
-
version: "1.22.
|
|
225270
|
+
version: "1.22.1",
|
|
225271
225271
|
description: "URHQ's agentic coding tool",
|
|
225272
225272
|
websiteUrl: PRODUCT_URL
|
|
225273
225273
|
}, {
|
|
@@ -225621,7 +225621,7 @@ var init_client5 = __esm(() => {
|
|
|
225621
225621
|
const client2 = new Client({
|
|
225622
225622
|
name: "ur",
|
|
225623
225623
|
title: "UR",
|
|
225624
|
-
version: "1.22.
|
|
225624
|
+
version: "1.22.1",
|
|
225625
225625
|
description: "URHQ's agentic coding tool",
|
|
225626
225626
|
websiteUrl: PRODUCT_URL
|
|
225627
225627
|
}, {
|
|
@@ -235434,9 +235434,9 @@ async function assertMinVersion() {
|
|
|
235434
235434
|
if (false) {}
|
|
235435
235435
|
try {
|
|
235436
235436
|
const versionConfig = await getDynamicConfig_BLOCKS_ON_INIT("tengu_version_config", { minVersion: "0.0.0" });
|
|
235437
|
-
if (versionConfig.minVersion && lt("1.22.
|
|
235437
|
+
if (versionConfig.minVersion && lt("1.22.1", versionConfig.minVersion)) {
|
|
235438
235438
|
console.error(`
|
|
235439
|
-
It looks like your version of UR (${"1.22.
|
|
235439
|
+
It looks like your version of UR (${"1.22.1"}) needs an update.
|
|
235440
235440
|
A newer version (${versionConfig.minVersion} or higher) is required to continue.
|
|
235441
235441
|
|
|
235442
235442
|
To update, please run:
|
|
@@ -235652,7 +235652,7 @@ async function installGlobalPackage(specificVersion) {
|
|
|
235652
235652
|
logError2(new AutoUpdaterError("Another process is currently installing an update"));
|
|
235653
235653
|
logEvent("tengu_auto_updater_lock_contention", {
|
|
235654
235654
|
pid: process.pid,
|
|
235655
|
-
currentVersion: "1.22.
|
|
235655
|
+
currentVersion: "1.22.1"
|
|
235656
235656
|
});
|
|
235657
235657
|
return "in_progress";
|
|
235658
235658
|
}
|
|
@@ -235661,7 +235661,7 @@ async function installGlobalPackage(specificVersion) {
|
|
|
235661
235661
|
if (!env2.isRunningWithBun() && env2.isNpmFromWindowsPath()) {
|
|
235662
235662
|
logError2(new Error("Windows NPM detected in WSL environment"));
|
|
235663
235663
|
logEvent("tengu_auto_updater_windows_npm_in_wsl", {
|
|
235664
|
-
currentVersion: "1.22.
|
|
235664
|
+
currentVersion: "1.22.1"
|
|
235665
235665
|
});
|
|
235666
235666
|
console.error(`
|
|
235667
235667
|
Error: Windows NPM detected in WSL
|
|
@@ -236196,7 +236196,7 @@ function detectLinuxGlobPatternWarnings() {
|
|
|
236196
236196
|
}
|
|
236197
236197
|
async function getDoctorDiagnostic() {
|
|
236198
236198
|
const installationType = await getCurrentInstallationType();
|
|
236199
|
-
const version2 = typeof MACRO !== "undefined" ? "1.22.
|
|
236199
|
+
const version2 = typeof MACRO !== "undefined" ? "1.22.1" : "unknown";
|
|
236200
236200
|
const installationPath = await getInstallationPath();
|
|
236201
236201
|
const invokedBinary = getInvokedBinary();
|
|
236202
236202
|
const multipleInstallations = await detectMultipleInstallations();
|
|
@@ -237131,8 +237131,8 @@ async function updateLatest(channelOrVersion, forceReinstall = false) {
|
|
|
237131
237131
|
const maxVersion = await getMaxVersion();
|
|
237132
237132
|
if (maxVersion && gt(version2, maxVersion)) {
|
|
237133
237133
|
logForDebugging(`Native installer: maxVersion ${maxVersion} is set, capping update from ${version2} to ${maxVersion}`);
|
|
237134
|
-
if (gte("1.22.
|
|
237135
|
-
logForDebugging(`Native installer: current version ${"1.22.
|
|
237134
|
+
if (gte("1.22.1", maxVersion)) {
|
|
237135
|
+
logForDebugging(`Native installer: current version ${"1.22.1"} is already at or above maxVersion ${maxVersion}, skipping update`);
|
|
237136
237136
|
logEvent("tengu_native_update_skipped_max_version", {
|
|
237137
237137
|
latency_ms: Date.now() - startTime,
|
|
237138
237138
|
max_version: maxVersion,
|
|
@@ -237143,7 +237143,7 @@ async function updateLatest(channelOrVersion, forceReinstall = false) {
|
|
|
237143
237143
|
version2 = maxVersion;
|
|
237144
237144
|
}
|
|
237145
237145
|
}
|
|
237146
|
-
if (!forceReinstall && version2 === "1.22.
|
|
237146
|
+
if (!forceReinstall && version2 === "1.22.1" && await versionIsAvailable(version2) && await isPossibleURBinary(executablePath)) {
|
|
237147
237147
|
logForDebugging(`Found ${version2} at ${executablePath}, skipping install`);
|
|
237148
237148
|
logEvent("tengu_native_update_complete", {
|
|
237149
237149
|
latency_ms: Date.now() - startTime,
|
|
@@ -332970,7 +332970,7 @@ function Feedback({
|
|
|
332970
332970
|
platform: env2.platform,
|
|
332971
332971
|
gitRepo: envInfo.isGit,
|
|
332972
332972
|
terminal: env2.terminal,
|
|
332973
|
-
version: "1.22.
|
|
332973
|
+
version: "1.22.1",
|
|
332974
332974
|
transcript: normalizeMessagesForAPI(messages),
|
|
332975
332975
|
errors: sanitizedErrors,
|
|
332976
332976
|
lastApiRequest: getLastAPIRequest(),
|
|
@@ -333162,7 +333162,7 @@ function Feedback({
|
|
|
333162
333162
|
", ",
|
|
333163
333163
|
env2.terminal,
|
|
333164
333164
|
", v",
|
|
333165
|
-
"1.22.
|
|
333165
|
+
"1.22.1"
|
|
333166
333166
|
]
|
|
333167
333167
|
}, undefined, true, undefined, this)
|
|
333168
333168
|
]
|
|
@@ -333268,7 +333268,7 @@ ${sanitizedDescription}
|
|
|
333268
333268
|
` + `**Environment Info**
|
|
333269
333269
|
` + `- Platform: ${env2.platform}
|
|
333270
333270
|
` + `- Terminal: ${env2.terminal}
|
|
333271
|
-
` + `- Version: ${"1.22.
|
|
333271
|
+
` + `- Version: ${"1.22.1"}
|
|
333272
333272
|
` + `- Feedback ID: ${feedbackId}
|
|
333273
333273
|
` + `
|
|
333274
333274
|
**Errors**
|
|
@@ -336378,7 +336378,7 @@ function buildPrimarySection() {
|
|
|
336378
336378
|
}, undefined, false, undefined, this);
|
|
336379
336379
|
return [{
|
|
336380
336380
|
label: "Version",
|
|
336381
|
-
value: "1.22.
|
|
336381
|
+
value: "1.22.1"
|
|
336382
336382
|
}, {
|
|
336383
336383
|
label: "Session name",
|
|
336384
336384
|
value: nameValue
|
|
@@ -339656,7 +339656,7 @@ function Config({
|
|
|
339656
339656
|
}
|
|
339657
339657
|
}, undefined, false, undefined, this)
|
|
339658
339658
|
}, undefined, false, undefined, this) : showSubmenu === "ChannelDowngrade" ? /* @__PURE__ */ jsx_dev_runtime177.jsxDEV(ChannelDowngradeDialog, {
|
|
339659
|
-
currentVersion: "1.22.
|
|
339659
|
+
currentVersion: "1.22.1",
|
|
339660
339660
|
onChoice: (choice) => {
|
|
339661
339661
|
setShowSubmenu(null);
|
|
339662
339662
|
setTabsHidden(false);
|
|
@@ -339668,7 +339668,7 @@ function Config({
|
|
|
339668
339668
|
autoUpdatesChannel: "stable"
|
|
339669
339669
|
};
|
|
339670
339670
|
if (choice === "stay") {
|
|
339671
|
-
newSettings.minimumVersion = "1.22.
|
|
339671
|
+
newSettings.minimumVersion = "1.22.1";
|
|
339672
339672
|
}
|
|
339673
339673
|
updateSettingsForSource("userSettings", newSettings);
|
|
339674
339674
|
setSettingsData((prev_27) => ({
|
|
@@ -347738,7 +347738,7 @@ function HelpV2(t0) {
|
|
|
347738
347738
|
let t6;
|
|
347739
347739
|
if ($3[31] !== tabs) {
|
|
347740
347740
|
t6 = /* @__PURE__ */ jsx_dev_runtime204.jsxDEV(Tabs, {
|
|
347741
|
-
title: `UR v${"1.22.
|
|
347741
|
+
title: `UR v${"1.22.1"}`,
|
|
347742
347742
|
color: "professionalBlue",
|
|
347743
347743
|
defaultTab: "general",
|
|
347744
347744
|
children: tabs
|
|
@@ -367702,7 +367702,7 @@ function getAllReleaseNotes(changelogContent = getStoredChangelogFromMemory()) {
|
|
|
367702
367702
|
return [];
|
|
367703
367703
|
}
|
|
367704
367704
|
}
|
|
367705
|
-
async function checkForReleaseNotes(lastSeenVersion, currentVersion = "1.22.
|
|
367705
|
+
async function checkForReleaseNotes(lastSeenVersion, currentVersion = "1.22.1") {
|
|
367706
367706
|
if (process.env.USER_TYPE === "ant") {
|
|
367707
367707
|
const changelog = "";
|
|
367708
367708
|
if (changelog) {
|
|
@@ -367729,7 +367729,7 @@ async function checkForReleaseNotes(lastSeenVersion, currentVersion = "1.22.0")
|
|
|
367729
367729
|
releaseNotes
|
|
367730
367730
|
};
|
|
367731
367731
|
}
|
|
367732
|
-
function checkForReleaseNotesSync(lastSeenVersion, currentVersion = "1.22.
|
|
367732
|
+
function checkForReleaseNotesSync(lastSeenVersion, currentVersion = "1.22.1") {
|
|
367733
367733
|
if (process.env.USER_TYPE === "ant") {
|
|
367734
367734
|
const changelog = "";
|
|
367735
367735
|
if (changelog) {
|
|
@@ -368899,7 +368899,7 @@ function getRecentActivitySync() {
|
|
|
368899
368899
|
return cachedActivity;
|
|
368900
368900
|
}
|
|
368901
368901
|
function getLogoDisplayData() {
|
|
368902
|
-
const version2 = process.env.DEMO_VERSION ?? "1.22.
|
|
368902
|
+
const version2 = process.env.DEMO_VERSION ?? "1.22.1";
|
|
368903
368903
|
const serverUrl = getDirectConnectServerUrl();
|
|
368904
368904
|
const displayPath = process.env.DEMO_VERSION ? "/code/ur" : getDisplayPath(getCwd());
|
|
368905
368905
|
const cwd2 = serverUrl ? `${displayPath} in ${serverUrl.replace(/^https?:\/\//, "")}` : displayPath;
|
|
@@ -369688,7 +369688,7 @@ function LogoV2() {
|
|
|
369688
369688
|
if ($3[2] === Symbol.for("react.memo_cache_sentinel")) {
|
|
369689
369689
|
t2 = () => {
|
|
369690
369690
|
const currentConfig = getGlobalConfig();
|
|
369691
|
-
if (currentConfig.lastReleaseNotesSeen === "1.22.
|
|
369691
|
+
if (currentConfig.lastReleaseNotesSeen === "1.22.1") {
|
|
369692
369692
|
return;
|
|
369693
369693
|
}
|
|
369694
369694
|
saveGlobalConfig(_temp326);
|
|
@@ -370373,12 +370373,12 @@ function LogoV2() {
|
|
|
370373
370373
|
return t41;
|
|
370374
370374
|
}
|
|
370375
370375
|
function _temp326(current) {
|
|
370376
|
-
if (current.lastReleaseNotesSeen === "1.22.
|
|
370376
|
+
if (current.lastReleaseNotesSeen === "1.22.1") {
|
|
370377
370377
|
return current;
|
|
370378
370378
|
}
|
|
370379
370379
|
return {
|
|
370380
370380
|
...current,
|
|
370381
|
-
lastReleaseNotesSeen: "1.22.
|
|
370381
|
+
lastReleaseNotesSeen: "1.22.1"
|
|
370382
370382
|
};
|
|
370383
370383
|
}
|
|
370384
370384
|
function _temp243(s_0) {
|
|
@@ -387331,7 +387331,7 @@ function buildToolUseContext(tools, readFileStateCache) {
|
|
|
387331
387331
|
async function handleInitialize() {
|
|
387332
387332
|
return {
|
|
387333
387333
|
name: "ur-agent",
|
|
387334
|
-
version: "1.22.
|
|
387334
|
+
version: "1.22.1",
|
|
387335
387335
|
protocolVersion: "0.1.0"
|
|
387336
387336
|
};
|
|
387337
387337
|
}
|
|
@@ -389494,6 +389494,76 @@ Specialist result:
|
|
|
389494
389494
|
}
|
|
389495
389495
|
]
|
|
389496
389496
|
},
|
|
389497
|
+
{
|
|
389498
|
+
id: "parallel",
|
|
389499
|
+
name: "Parallel specialized subagents",
|
|
389500
|
+
acronym: "PAR",
|
|
389501
|
+
summary: "Run multiple specialist agents in parallel \u2014 bug finder, patch writer, test writer, security auditor, style reviewer \u2014 then synthesize their outputs into one coherent plan. Best for complex code changes that need independent expert scrutiny before integration.",
|
|
389502
|
+
bestFor: [
|
|
389503
|
+
"complex code changes needing independent expert review",
|
|
389504
|
+
"tasks where bug-finding, patching, testing, security, and style can be separated",
|
|
389505
|
+
"high-confidence patches that must survive multiple adversarial checks"
|
|
389506
|
+
],
|
|
389507
|
+
reference: "https://openai.github.io/openai-agents-python/",
|
|
389508
|
+
loop: null,
|
|
389509
|
+
stages: [
|
|
389510
|
+
{
|
|
389511
|
+
id: "find-bugs",
|
|
389512
|
+
role: "Bug finder",
|
|
389513
|
+
agent: "reviewer",
|
|
389514
|
+
goal: "Find concrete bugs in the code relevant to the task.",
|
|
389515
|
+
prompt: "Find bugs in the code related to: {{task}}. List concrete issues with file paths and line numbers. Do not write fixes; only identify problems. End with VERDICT: PASS if no serious bugs were found, or VERDICT: FAIL with the bug list.",
|
|
389516
|
+
dependsOn: [],
|
|
389517
|
+
parallelizable: true
|
|
389518
|
+
},
|
|
389519
|
+
{
|
|
389520
|
+
id: "write-patch",
|
|
389521
|
+
role: "Patch writer",
|
|
389522
|
+
agent: "worker",
|
|
389523
|
+
goal: "Write the minimal correct patch for the task.",
|
|
389524
|
+
prompt: "Write the minimal patch for: {{task}}. Return only the code changes and a VERDICT line. Do not write tests or prose; focus on the implementation.",
|
|
389525
|
+
dependsOn: [],
|
|
389526
|
+
parallelizable: true
|
|
389527
|
+
},
|
|
389528
|
+
{
|
|
389529
|
+
id: "write-tests",
|
|
389530
|
+
role: "Test writer",
|
|
389531
|
+
agent: "test-runner",
|
|
389532
|
+
goal: "Write tests that exercise the expected behavior.",
|
|
389533
|
+
prompt: "Write tests for: {{task}}. Run them and report results. End with VERDICT: PASS if tests pass, or VERDICT: FAIL with failure output.",
|
|
389534
|
+
dependsOn: [],
|
|
389535
|
+
parallelizable: true
|
|
389536
|
+
},
|
|
389537
|
+
{
|
|
389538
|
+
id: "security-review",
|
|
389539
|
+
role: "Security auditor",
|
|
389540
|
+
agent: "security-auditor",
|
|
389541
|
+
goal: "Review the task for security vulnerabilities and unsafe patterns.",
|
|
389542
|
+
prompt: "Security review for: {{task}}. Report any vulnerabilities, unsafe patterns, or trust-boundary issues. End with VERDICT: PASS if no serious issues, or VERDICT: FAIL with specifics.",
|
|
389543
|
+
dependsOn: [],
|
|
389544
|
+
parallelizable: true
|
|
389545
|
+
},
|
|
389546
|
+
{
|
|
389547
|
+
id: "style-review",
|
|
389548
|
+
role: "Style reviewer",
|
|
389549
|
+
agent: "reviewer",
|
|
389550
|
+
goal: "Review maintainability, style, and clarity.",
|
|
389551
|
+
prompt: "Style/review for: {{task}}. Report maintainability, clarity, naming, and consistency issues. End with VERDICT: PASS if acceptable, or VERDICT: FAIL with a concise punch list.",
|
|
389552
|
+
dependsOn: [],
|
|
389553
|
+
parallelizable: true
|
|
389554
|
+
},
|
|
389555
|
+
{
|
|
389556
|
+
id: "synthesize",
|
|
389557
|
+
role: "Synthesizer",
|
|
389558
|
+
agent: "general-purpose",
|
|
389559
|
+
goal: "Merge parallel findings into one coherent, actionable plan.",
|
|
389560
|
+
prompt: "Synthesize the parallel reviews and patch above into a single coherent plan for: {{task}}. Resolve conflicts between findings. Produce a unified patch/test/security/style recommendation. End with VERDICT: PASS if ready to apply, or VERDICT: FAIL if more work is needed.",
|
|
389561
|
+
dependsOn: ["find-bugs", "write-patch", "write-tests", "security-review", "style-review"],
|
|
389562
|
+
gate: "verification",
|
|
389563
|
+
checkpoint: true
|
|
389564
|
+
}
|
|
389565
|
+
]
|
|
389566
|
+
},
|
|
389497
389567
|
{
|
|
389498
389568
|
id: "debate",
|
|
389499
389569
|
name: "Debate (propose, critique, moderate)",
|
|
@@ -389936,6 +390006,7 @@ Known patterns: ${knownIds()}`
|
|
|
389936
390006
|
workflow.name = `${pattern.id}-run`;
|
|
389937
390007
|
const dryRun = tokens.includes("--dry-run");
|
|
389938
390008
|
const maxTurnsValue = Number(optionValue(tokens, "--max-turns") ?? "30");
|
|
390009
|
+
const parallelAgents = pattern.stages.filter((s) => s.parallelizable).length;
|
|
389939
390010
|
const result = await saveAndRunWorkflow(workflow, {
|
|
389940
390011
|
cwd: getCwd(),
|
|
389941
390012
|
stateName: workflow.name,
|
|
@@ -389943,6 +390014,7 @@ Known patterns: ${knownIds()}`
|
|
|
389943
390014
|
resume: tokens.includes("--resume"),
|
|
389944
390015
|
skipPermissions: tokens.includes("--skip-permissions") || tokens.includes("--dangerously-skip-permissions"),
|
|
389945
390016
|
maxTurns: Number.isFinite(maxTurnsValue) && maxTurnsValue > 0 ? maxTurnsValue : 30,
|
|
390017
|
+
maxConcurrency: parallelAgents > 1 ? parallelAgents : undefined,
|
|
389946
390018
|
loop: pattern.loop ? {
|
|
389947
390019
|
from: pattern.loop.from,
|
|
389948
390020
|
to: pattern.loop.to,
|
|
@@ -390006,8 +390078,8 @@ var init_pattern2 = __esm(() => {
|
|
|
390006
390078
|
type: "local",
|
|
390007
390079
|
name: "pattern",
|
|
390008
390080
|
aliases: ["patterns"],
|
|
390009
|
-
description: "Multi-agent collaboration patterns (PEER, DOE): list, show, run, or install",
|
|
390010
|
-
argumentHint: "[list|show|run|install] [peer|doe] [task...] [--execute] [--dry-run] [--save] [--force] [--json]",
|
|
390081
|
+
description: "Multi-agent collaboration patterns (PEER, DOE, concurrent, handoff, debate, parallel): list, show, run, or install",
|
|
390082
|
+
argumentHint: "[list|show|run|install] [peer|doe|concurrent|handoff|debate|parallel] [task...] [--execute] [--dry-run] [--save] [--force] [--json]",
|
|
390011
390083
|
supportsNonInteractive: true,
|
|
390012
390084
|
load: () => Promise.resolve().then(() => (init_pattern(), exports_pattern))
|
|
390013
390085
|
};
|
|
@@ -391817,9 +391889,40 @@ Complete only this subtask. End your reply with VERDICT: PASS if you finished it
|
|
|
391817
391889
|
status: "todo"
|
|
391818
391890
|
};
|
|
391819
391891
|
}
|
|
391892
|
+
function makeTaskFromDecomposed(task, goal) {
|
|
391893
|
+
const title = task.goal.length > 72 ? `${task.goal.slice(0, 69)}...` : task.goal;
|
|
391894
|
+
const files = task.filesTouched.length ? `
|
|
391895
|
+
Files touched: ${task.filesTouched.join(", ")}` : "";
|
|
391896
|
+
const risk = `
|
|
391897
|
+
Risk level: ${task.risk}`;
|
|
391898
|
+
const tests = `
|
|
391899
|
+
Tests required: ${task.testsRequired.join(", ")}`;
|
|
391900
|
+
const rollback = `
|
|
391901
|
+
Rollback point: ${task.rollbackPoint}`;
|
|
391902
|
+
return {
|
|
391903
|
+
id: task.id,
|
|
391904
|
+
title,
|
|
391905
|
+
prompt: `Overall goal: ${goal}
|
|
391906
|
+
|
|
391907
|
+
Your subtask: ${task.goal}${files}${risk}${tests}${rollback}
|
|
391908
|
+
|
|
391909
|
+
Complete only this subtask. End your reply with VERDICT: PASS if you finished it, or VERDICT: FAIL if you could not.`,
|
|
391910
|
+
status: "todo",
|
|
391911
|
+
filesTouched: task.filesTouched,
|
|
391912
|
+
risk: task.risk,
|
|
391913
|
+
testsRequired: task.testsRequired,
|
|
391914
|
+
rollbackPoint: task.rollbackPoint
|
|
391915
|
+
};
|
|
391916
|
+
}
|
|
391820
391917
|
function createCrew(cwd2, name, goal, options2 = {}) {
|
|
391821
391918
|
const now6 = new Date().toISOString();
|
|
391822
|
-
|
|
391919
|
+
let tasks2;
|
|
391920
|
+
if (options2.decomposed && options2.decomposed.length > 0) {
|
|
391921
|
+
tasks2 = options2.decomposed.map((task) => makeTaskFromDecomposed(task, goal));
|
|
391922
|
+
} else {
|
|
391923
|
+
const instructions = options2.tasks && options2.tasks.length > 0 ? options2.tasks : decomposeGoal(goal);
|
|
391924
|
+
tasks2 = instructions.map((instruction, index2) => makeTask(index2, instruction, goal));
|
|
391925
|
+
}
|
|
391823
391926
|
const spec = {
|
|
391824
391927
|
version: 1,
|
|
391825
391928
|
name: sanitizeCrewName(name),
|
|
@@ -391827,7 +391930,7 @@ function createCrew(cwd2, name, goal, options2 = {}) {
|
|
|
391827
391930
|
lead: options2.lead ?? "general-purpose",
|
|
391828
391931
|
createdAt: now6,
|
|
391829
391932
|
updatedAt: now6,
|
|
391830
|
-
tasks:
|
|
391933
|
+
tasks: tasks2
|
|
391831
391934
|
};
|
|
391832
391935
|
saveCrew(cwd2, spec);
|
|
391833
391936
|
return spec;
|
|
@@ -392018,6 +392121,135 @@ var init_crew = __esm(() => {
|
|
|
392018
392121
|
init_cliStepRunner();
|
|
392019
392122
|
});
|
|
392020
392123
|
|
|
392124
|
+
// src/services/agents/decomposer.ts
|
|
392125
|
+
function riskLevelFromKeywords(goal, files = []) {
|
|
392126
|
+
const text = `${goal} ${files.join(" ")}`.toLowerCase();
|
|
392127
|
+
if (HIGH_RISK_KEYWORDS.test(text))
|
|
392128
|
+
return "high";
|
|
392129
|
+
if (MEDIUM_RISK_KEYWORDS.test(text))
|
|
392130
|
+
return "medium";
|
|
392131
|
+
if (LOW_RISK_KEYWORDS.test(text))
|
|
392132
|
+
return "low";
|
|
392133
|
+
return "medium";
|
|
392134
|
+
}
|
|
392135
|
+
async function currentRollbackPoint(cwd2) {
|
|
392136
|
+
const result = await execFileNoThrowWithCwd("git", ["rev-parse", "HEAD"], { cwd: cwd2, preserveOutputOnError: true });
|
|
392137
|
+
if (result.code === 0 && result.stdout.trim())
|
|
392138
|
+
return result.stdout.trim();
|
|
392139
|
+
return "untracked";
|
|
392140
|
+
}
|
|
392141
|
+
function deterministicDecomposition(goal, rollbackPoint) {
|
|
392142
|
+
const items = decomposeGoal(goal);
|
|
392143
|
+
return items.map((item, index2) => ({
|
|
392144
|
+
id: `t${index2 + 1}`,
|
|
392145
|
+
goal: item,
|
|
392146
|
+
filesTouched: [],
|
|
392147
|
+
risk: riskLevelFromKeywords(item),
|
|
392148
|
+
testsRequired: inferTests(item),
|
|
392149
|
+
rollbackPoint
|
|
392150
|
+
}));
|
|
392151
|
+
}
|
|
392152
|
+
function inferTests(goal) {
|
|
392153
|
+
const lower = goal.toLowerCase();
|
|
392154
|
+
const tests = [];
|
|
392155
|
+
if (/\b(test|spec|assert|coverage)\b/i.test(lower))
|
|
392156
|
+
tests.push("unit test");
|
|
392157
|
+
if (/\b(integration|e2e|end-to-end|api)\b/i.test(lower))
|
|
392158
|
+
tests.push("integration test");
|
|
392159
|
+
if (/\b(build|compile|typecheck|tsc)\b/i.test(lower))
|
|
392160
|
+
tests.push("compile/typecheck");
|
|
392161
|
+
if (/\b(lint|format|style)\b/i.test(lower))
|
|
392162
|
+
tests.push("lint");
|
|
392163
|
+
if (tests.length === 0)
|
|
392164
|
+
tests.push("existing test suite");
|
|
392165
|
+
return tests;
|
|
392166
|
+
}
|
|
392167
|
+
function decomposePrompt(goal) {
|
|
392168
|
+
return [
|
|
392169
|
+
"Decompose the following engineering goal into atomic subtasks.",
|
|
392170
|
+
"Return a JSON object with exactly this shape (no markdown, no commentary):",
|
|
392171
|
+
"",
|
|
392172
|
+
"{",
|
|
392173
|
+
' "tasks": [',
|
|
392174
|
+
" {",
|
|
392175
|
+
' "id": "t1",',
|
|
392176
|
+
' "goal": "concise subtask goal",',
|
|
392177
|
+
' "filesTouched": ["src/example.ts"],',
|
|
392178
|
+
' "risk": "low|medium|high",',
|
|
392179
|
+
' "testsRequired": ["unit test"],',
|
|
392180
|
+
' "rollbackPoint": "HEAD"',
|
|
392181
|
+
" }",
|
|
392182
|
+
" ]",
|
|
392183
|
+
"}",
|
|
392184
|
+
"",
|
|
392185
|
+
"Guidelines:",
|
|
392186
|
+
"- Each subtask should be small enough to implement and verify independently.",
|
|
392187
|
+
'- "filesTouched" should list the files likely to change.',
|
|
392188
|
+
'- "risk" should be high for auth/security/concurrency/destructive changes, medium for refactor/API changes, low for docs/style.',
|
|
392189
|
+
'- "testsRequired" should list the test categories that must pass.',
|
|
392190
|
+
'- "rollbackPoint" should be "HEAD".',
|
|
392191
|
+
"",
|
|
392192
|
+
"Goal:",
|
|
392193
|
+
goal
|
|
392194
|
+
].join(`
|
|
392195
|
+
`);
|
|
392196
|
+
}
|
|
392197
|
+
async function decomposeTask(goal, options2) {
|
|
392198
|
+
const rollbackPoint = await currentRollbackPoint(options2.cwd);
|
|
392199
|
+
if (options2.dryRun) {
|
|
392200
|
+
return deterministicDecomposition(goal, rollbackPoint);
|
|
392201
|
+
}
|
|
392202
|
+
const runner2 = options2.runner ?? defaultHeadlessRunner();
|
|
392203
|
+
const out = await runner2({
|
|
392204
|
+
cwd: options2.cwd,
|
|
392205
|
+
prompt: decomposePrompt(goal),
|
|
392206
|
+
maxTurns: 10
|
|
392207
|
+
});
|
|
392208
|
+
const parsed = safeParseJSON(out.output, false);
|
|
392209
|
+
if (parsed && typeof parsed === "object" && Array.isArray(parsed.tasks)) {
|
|
392210
|
+
const tasks2 = parsed.tasks;
|
|
392211
|
+
return tasks2.map((t) => ({
|
|
392212
|
+
...t,
|
|
392213
|
+
rollbackPoint: t.rollbackPoint ?? rollbackPoint,
|
|
392214
|
+
filesTouched: Array.isArray(t.filesTouched) ? t.filesTouched : [],
|
|
392215
|
+
testsRequired: Array.isArray(t.testsRequired) ? t.testsRequired : inferTests(t.goal),
|
|
392216
|
+
risk: ["low", "medium", "high"].includes(t.risk) ? t.risk : riskLevelFromKeywords(t.goal, t.filesTouched)
|
|
392217
|
+
}));
|
|
392218
|
+
}
|
|
392219
|
+
return deterministicDecomposition(goal, rollbackPoint);
|
|
392220
|
+
}
|
|
392221
|
+
function formatDecomposition(result, json2) {
|
|
392222
|
+
if (json2)
|
|
392223
|
+
return JSON.stringify(result, null, 2);
|
|
392224
|
+
const lines = [
|
|
392225
|
+
`Decomposition: ${result.goal}`,
|
|
392226
|
+
`Rollback point: ${result.rollbackPoint}`,
|
|
392227
|
+
`Generated: ${result.generatedAt}`,
|
|
392228
|
+
""
|
|
392229
|
+
];
|
|
392230
|
+
for (const task of result.tasks) {
|
|
392231
|
+
lines.push(`- ${task.id} [${task.risk.toUpperCase()}] ${task.goal}`);
|
|
392232
|
+
if (task.filesTouched.length)
|
|
392233
|
+
lines.push(` files: ${task.filesTouched.join(", ")}`);
|
|
392234
|
+
if (task.testsRequired.length)
|
|
392235
|
+
lines.push(` tests: ${task.testsRequired.join(", ")}`);
|
|
392236
|
+
lines.push(` rollback: ${task.rollbackPoint}`);
|
|
392237
|
+
lines.push("");
|
|
392238
|
+
}
|
|
392239
|
+
return lines.join(`
|
|
392240
|
+
`);
|
|
392241
|
+
}
|
|
392242
|
+
var HIGH_RISK_KEYWORDS, MEDIUM_RISK_KEYWORDS, LOW_RISK_KEYWORDS;
|
|
392243
|
+
var init_decomposer = __esm(() => {
|
|
392244
|
+
init_execFileNoThrow();
|
|
392245
|
+
init_json();
|
|
392246
|
+
init_headlessAgent();
|
|
392247
|
+
init_crew();
|
|
392248
|
+
HIGH_RISK_KEYWORDS = /\b(auth|authoriz|credential|secret|token|password|encrypt|hash|ssl|tls|sandbox|shell|bash|rm\b|drop|delete|migrate|security|vulnerab|exploit|injection|race|deadlock|concurren|distributed)\b/i;
|
|
392249
|
+
MEDIUM_RISK_KEYWORDS = /\b(refactor|rename|move|restructure|extract|interface|api|contract|dependency|config|schema)\b/i;
|
|
392250
|
+
LOW_RISK_KEYWORDS = /\b(comment|doc|readme|changelog|typo|format|style|lint|naming|whitespace)\b/i;
|
|
392251
|
+
});
|
|
392252
|
+
|
|
392021
392253
|
// src/commands/crew/crew.ts
|
|
392022
392254
|
var exports_crew = {};
|
|
392023
392255
|
__export(exports_crew, {
|
|
@@ -392048,10 +392280,11 @@ function usage7() {
|
|
|
392048
392280
|
return [
|
|
392049
392281
|
"Usage:",
|
|
392050
392282
|
" ur crew list [--json]",
|
|
392051
|
-
' ur crew create <name> --goal "..." [--lead <agent>] [--json]',
|
|
392283
|
+
' ur crew create <name> --goal "..." [--lead <agent>] [--decompose] [--json]',
|
|
392284
|
+
' ur crew plan <name> --goal "..." [--decompose] [--json]',
|
|
392052
392285
|
" ur crew show <name> [--json]",
|
|
392053
392286
|
' ur crew add <name> --task "another subtask"',
|
|
392054
|
-
" ur crew run <name> [--workers N] [--worktrees] [--dry-run] [--resume] [--max-turns N] [--skip-permissions] [--json]",
|
|
392287
|
+
" ur crew run <name> [--workers N] [--worktrees] [--dry-run] [--resume] [--decompose] [--max-turns N] [--skip-permissions] [--json]",
|
|
392055
392288
|
" ur crew reset <name>",
|
|
392056
392289
|
" ur crew delete <name>",
|
|
392057
392290
|
"",
|
|
@@ -392074,7 +392307,9 @@ var call69 = async (args) => {
|
|
|
392074
392307
|
const goal = option8(tokens, "--goal");
|
|
392075
392308
|
if (!name || !goal)
|
|
392076
392309
|
return { type: "text", value: usage7() };
|
|
392077
|
-
const
|
|
392310
|
+
const decompose = tokens.includes("--decompose");
|
|
392311
|
+
const decomposed = decompose ? await decomposeTask(goal, { cwd: cwd2, dryRun: tokens.includes("--dry-run") }) : undefined;
|
|
392312
|
+
const spec = createCrew(cwd2, name, goal, { lead: option8(tokens, "--lead"), decomposed });
|
|
392078
392313
|
return {
|
|
392079
392314
|
type: "text",
|
|
392080
392315
|
value: json2 ? formatCrew(spec, true) : `Created crew ${spec.name} with ${spec.tasks.length} task(s).
|
|
@@ -392082,6 +392317,19 @@ var call69 = async (args) => {
|
|
|
392082
392317
|
${formatCrew(spec, false)}`
|
|
392083
392318
|
};
|
|
392084
392319
|
}
|
|
392320
|
+
if (action3 === "plan") {
|
|
392321
|
+
const goal = option8(tokens, "--goal");
|
|
392322
|
+
if (!goal)
|
|
392323
|
+
return { type: "text", value: usage7() };
|
|
392324
|
+
const tasks2 = await decomposeTask(goal, { cwd: cwd2, dryRun: tokens.includes("--dry-run") });
|
|
392325
|
+
const result = {
|
|
392326
|
+
goal,
|
|
392327
|
+
tasks: tasks2,
|
|
392328
|
+
rollbackPoint: tasks2[0]?.rollbackPoint ?? "HEAD",
|
|
392329
|
+
generatedAt: new Date().toISOString()
|
|
392330
|
+
};
|
|
392331
|
+
return { type: "text", value: formatDecomposition(result, json2) };
|
|
392332
|
+
}
|
|
392085
392333
|
if (!name)
|
|
392086
392334
|
return { type: "text", value: usage7() };
|
|
392087
392335
|
if (action3 === "show") {
|
|
@@ -392109,8 +392357,17 @@ ${formatCrew(spec, false)}`
|
|
|
392109
392357
|
return { type: "text", value: deleteCrew(cwd2, name) ? `Deleted crew ${name}.` : `Crew not found: ${name}` };
|
|
392110
392358
|
}
|
|
392111
392359
|
if (action3 === "run") {
|
|
392112
|
-
|
|
392113
|
-
|
|
392360
|
+
const spec = loadCrew(cwd2, name);
|
|
392361
|
+
if (!spec) {
|
|
392362
|
+
const goal = option8(tokens, "--goal");
|
|
392363
|
+
if (!goal)
|
|
392364
|
+
return { type: "text", value: `Crew not found: ${name}` };
|
|
392365
|
+
const decomposed = await decomposeTask(goal, { cwd: cwd2, dryRun: tokens.includes("--dry-run") });
|
|
392366
|
+
createCrew(cwd2, name, goal, { lead: option8(tokens, "--lead"), decomposed });
|
|
392367
|
+
} else if (tokens.includes("--decompose") && spec.tasks.length === 0) {
|
|
392368
|
+
const decomposed = await decomposeTask(spec.goal, { cwd: cwd2, dryRun: tokens.includes("--dry-run") });
|
|
392369
|
+
createCrew(cwd2, name, spec.goal, { lead: spec.lead, decomposed });
|
|
392370
|
+
}
|
|
392114
392371
|
const workersRaw = option8(tokens, "--workers");
|
|
392115
392372
|
const maxTurnsRaw = option8(tokens, "--max-turns");
|
|
392116
392373
|
const events2 = [];
|
|
@@ -392140,6 +392397,7 @@ ${events2.join(`
|
|
|
392140
392397
|
};
|
|
392141
392398
|
var init_crew2 = __esm(() => {
|
|
392142
392399
|
init_crew();
|
|
392400
|
+
init_decomposer();
|
|
392143
392401
|
init_argumentSubstitution();
|
|
392144
392402
|
init_cwd2();
|
|
392145
392403
|
});
|
|
@@ -392152,7 +392410,7 @@ var init_crew3 = __esm(() => {
|
|
|
392152
392410
|
name: "crew",
|
|
392153
392411
|
aliases: ["crews"],
|
|
392154
392412
|
description: "Headless agent crew: a lead splits a goal into a shared task board that worker subagents claim and run",
|
|
392155
|
-
argumentHint: "create|list|show|add|run|reset|delete [name] [--goal ...] [--task ...] [--workers N] [--worktrees] [--dry-run] [--json]",
|
|
392413
|
+
argumentHint: "create|list|plan|show|add|run|reset|delete [name] [--goal ...] [--task ...] [--workers N] [--worktrees] [--dry-run] [--decompose] [--json]",
|
|
392156
392414
|
supportsNonInteractive: true,
|
|
392157
392415
|
load: () => Promise.resolve().then(() => (init_crew2(), exports_crew))
|
|
392158
392416
|
};
|
|
@@ -392434,42 +392692,432 @@ var init_goal2 = __esm(() => {
|
|
|
392434
392692
|
goal_default = goal;
|
|
392435
392693
|
});
|
|
392436
392694
|
|
|
392695
|
+
// src/services/agents/kernel.ts
|
|
392696
|
+
import { existsSync as existsSync26, readFileSync as readFileSync34 } from "fs";
|
|
392697
|
+
import { join as join146 } from "path";
|
|
392698
|
+
function defaultGuard(skipPermissions) {
|
|
392699
|
+
return {
|
|
392700
|
+
canUseTool: (_toolName, _input) => ({
|
|
392701
|
+
allowed: skipPermissions === true,
|
|
392702
|
+
reason: skipPermissions ? "permissions skipped" : "interactive ask treated as deny in kernel"
|
|
392703
|
+
})
|
|
392704
|
+
};
|
|
392705
|
+
}
|
|
392706
|
+
function defaultRouter() {
|
|
392707
|
+
return {
|
|
392708
|
+
routeTask: (task) => routeIntent(task),
|
|
392709
|
+
recommendModel: () => null
|
|
392710
|
+
};
|
|
392711
|
+
}
|
|
392712
|
+
function defaultMemory(cwd2) {
|
|
392713
|
+
return {
|
|
392714
|
+
loadMemorySnippet: (scope, agentType) => {
|
|
392715
|
+
const base2 = scope === "project" ? join146(cwd2, ".ur", "memory") : join146(cwd2, ".ur", "memory");
|
|
392716
|
+
const path22 = join146(base2, `${agentType}.md`);
|
|
392717
|
+
return existsSync26(path22) ? readFileSync34(path22, "utf-8") : null;
|
|
392718
|
+
}
|
|
392719
|
+
};
|
|
392720
|
+
}
|
|
392721
|
+
function defaultExecutor() {
|
|
392722
|
+
return {
|
|
392723
|
+
execute: async (stage, options2) => {
|
|
392724
|
+
const runner2 = options2.runner ?? defaultHeadlessRunner();
|
|
392725
|
+
const out = await runner2({
|
|
392726
|
+
cwd: stage.context.cwd,
|
|
392727
|
+
prompt: stage.instructions ?? stage.goal,
|
|
392728
|
+
maxTurns: options2.maxTurns,
|
|
392729
|
+
skipPermissions: options2.skipPermissions
|
|
392730
|
+
});
|
|
392731
|
+
return {
|
|
392732
|
+
stage,
|
|
392733
|
+
verdict: out.verdict ?? extractVerdict(out.output),
|
|
392734
|
+
output: out.output,
|
|
392735
|
+
isError: out.isError ?? false,
|
|
392736
|
+
artifacts: []
|
|
392737
|
+
};
|
|
392738
|
+
}
|
|
392739
|
+
};
|
|
392740
|
+
}
|
|
392741
|
+
function defaultVerifier() {
|
|
392742
|
+
return {
|
|
392743
|
+
verify: async (stage, options2) => {
|
|
392744
|
+
const config3 = await loadVerifyConfig(stage.context.cwd);
|
|
392745
|
+
const gateResults = [];
|
|
392746
|
+
const emitGate = (command5, ok) => {
|
|
392747
|
+
gateResults.push({ kind: "note", text: `${ok ? "PASS" : "FAIL"} gate: ${command5}` });
|
|
392748
|
+
};
|
|
392749
|
+
if (config3?.afterEdit && config3.afterEdit.length > 0) {
|
|
392750
|
+
const gate = await runGateCommands(config3.afterEdit, stage.context.cwd, config3.timeoutMs);
|
|
392751
|
+
if (!gate.ok) {
|
|
392752
|
+
const failed = gate;
|
|
392753
|
+
emitGate(failed.command, false);
|
|
392754
|
+
return {
|
|
392755
|
+
stage,
|
|
392756
|
+
verdict: "FAIL",
|
|
392757
|
+
output: failed.reminder,
|
|
392758
|
+
isError: true,
|
|
392759
|
+
artifacts: gateResults
|
|
392760
|
+
};
|
|
392761
|
+
}
|
|
392762
|
+
for (const cmd of config3.afterEdit)
|
|
392763
|
+
emitGate(cmd, true);
|
|
392764
|
+
}
|
|
392765
|
+
const runner2 = options2.runner ?? defaultHeadlessRunner();
|
|
392766
|
+
const out = await runner2({
|
|
392767
|
+
cwd: stage.context.cwd,
|
|
392768
|
+
prompt: stage.instructions ?? stage.goal,
|
|
392769
|
+
maxTurns: options2.maxTurns,
|
|
392770
|
+
skipPermissions: options2.skipPermissions
|
|
392771
|
+
});
|
|
392772
|
+
return {
|
|
392773
|
+
stage,
|
|
392774
|
+
verdict: out.verdict ?? extractVerdict(out.output),
|
|
392775
|
+
output: out.output,
|
|
392776
|
+
isError: out.isError ?? false,
|
|
392777
|
+
artifacts: gateResults
|
|
392778
|
+
};
|
|
392779
|
+
}
|
|
392780
|
+
};
|
|
392781
|
+
}
|
|
392782
|
+
function defaultCritic() {
|
|
392783
|
+
return {
|
|
392784
|
+
review: async (stage, previousOutput, options2) => {
|
|
392785
|
+
const runner2 = options2.runner ?? defaultHeadlessRunner();
|
|
392786
|
+
const prompt = [
|
|
392787
|
+
"You are a critic reviewing another agent's work.",
|
|
392788
|
+
"Original task:",
|
|
392789
|
+
stage.goal,
|
|
392790
|
+
"",
|
|
392791
|
+
"Agent output:",
|
|
392792
|
+
previousOutput.slice(0, 4000),
|
|
392793
|
+
"",
|
|
392794
|
+
"Identify gaps, risks, or better approaches. End with VERDICT: PASS if satisfactory, VERDICT: FAIL if material issues remain, or VERDICT: PARTIAL if limited by environment."
|
|
392795
|
+
].join(`
|
|
392796
|
+
`);
|
|
392797
|
+
const out = await runner2({ cwd: stage.context.cwd, prompt, maxTurns: options2.maxTurns });
|
|
392798
|
+
return {
|
|
392799
|
+
stage: { ...stage, name: `${stage.name}:critic`, role: "critic" },
|
|
392800
|
+
verdict: out.verdict ?? extractVerdict(out.output),
|
|
392801
|
+
output: out.output,
|
|
392802
|
+
isError: out.isError ?? false,
|
|
392803
|
+
artifacts: []
|
|
392804
|
+
};
|
|
392805
|
+
}
|
|
392806
|
+
};
|
|
392807
|
+
}
|
|
392808
|
+
function createAgentKernel(options2) {
|
|
392809
|
+
return {
|
|
392810
|
+
guard: defaultGuard(options2.skipPermissions),
|
|
392811
|
+
router: defaultRouter(),
|
|
392812
|
+
memory: defaultMemory(options2.cwd),
|
|
392813
|
+
planner: { planStages: () => [] },
|
|
392814
|
+
executor: defaultExecutor(),
|
|
392815
|
+
verifier: defaultVerifier(),
|
|
392816
|
+
critic: defaultCritic()
|
|
392817
|
+
};
|
|
392818
|
+
}
|
|
392819
|
+
async function runKernelStage(kernel, stage, options2) {
|
|
392820
|
+
options2.onEvent?.({ kind: "stage-start", stage: stage.name, role: stage.role });
|
|
392821
|
+
const runner2 = options2.runner ?? (options2.dryRun ? makeDryHeadlessRunner() : defaultHeadlessRunner());
|
|
392822
|
+
const runOptions = {
|
|
392823
|
+
runner: runner2,
|
|
392824
|
+
maxTurns: options2.maxTurns,
|
|
392825
|
+
skipPermissions: options2.skipPermissions
|
|
392826
|
+
};
|
|
392827
|
+
let result;
|
|
392828
|
+
switch (stage.role) {
|
|
392829
|
+
case "executor":
|
|
392830
|
+
result = await kernel.executor.execute(stage, runOptions);
|
|
392831
|
+
break;
|
|
392832
|
+
case "verifier":
|
|
392833
|
+
result = await kernel.verifier.verify(stage, runOptions);
|
|
392834
|
+
break;
|
|
392835
|
+
case "critic":
|
|
392836
|
+
result = await kernel.critic.review(stage, stage.context.priorOutputs?.previous ?? "", runOptions);
|
|
392837
|
+
break;
|
|
392838
|
+
case "planner":
|
|
392839
|
+
result = {
|
|
392840
|
+
stage,
|
|
392841
|
+
verdict: null,
|
|
392842
|
+
output: "Planner role: stage list produced.",
|
|
392843
|
+
isError: false,
|
|
392844
|
+
artifacts: [],
|
|
392845
|
+
nextStages: kernel.planner.planStages(stage.context)
|
|
392846
|
+
};
|
|
392847
|
+
break;
|
|
392848
|
+
case "memory": {
|
|
392849
|
+
const snippet = kernel.memory.loadMemorySnippet("project", stage.name);
|
|
392850
|
+
result = {
|
|
392851
|
+
stage,
|
|
392852
|
+
verdict: null,
|
|
392853
|
+
output: snippet ?? "(no memory snippet)",
|
|
392854
|
+
isError: false,
|
|
392855
|
+
artifacts: snippet ? [{ kind: "note", text: snippet }] : []
|
|
392856
|
+
};
|
|
392857
|
+
break;
|
|
392858
|
+
}
|
|
392859
|
+
case "router": {
|
|
392860
|
+
const route2 = kernel.router.routeTask(stage.goal);
|
|
392861
|
+
result = {
|
|
392862
|
+
stage,
|
|
392863
|
+
verdict: null,
|
|
392864
|
+
output: `Routed to ${route2.agent} (${route2.category}) with pattern ${route2.pattern ?? "single"}.`,
|
|
392865
|
+
isError: false,
|
|
392866
|
+
artifacts: [{ kind: "note", text: JSON.stringify(route2) }]
|
|
392867
|
+
};
|
|
392868
|
+
break;
|
|
392869
|
+
}
|
|
392870
|
+
case "guard": {
|
|
392871
|
+
const check3 = kernel.guard.canUseTool(stage.name, stage.goal);
|
|
392872
|
+
result = {
|
|
392873
|
+
stage,
|
|
392874
|
+
verdict: check3.allowed ? "PASS" : "FAIL",
|
|
392875
|
+
output: check3.reason ?? (check3.allowed ? "allowed" : "denied"),
|
|
392876
|
+
isError: !check3.allowed,
|
|
392877
|
+
artifacts: []
|
|
392878
|
+
};
|
|
392879
|
+
break;
|
|
392880
|
+
}
|
|
392881
|
+
default:
|
|
392882
|
+
result = {
|
|
392883
|
+
stage,
|
|
392884
|
+
verdict: "PARTIAL",
|
|
392885
|
+
output: `Unsupported kernel role: ${stage.role}`,
|
|
392886
|
+
isError: true,
|
|
392887
|
+
artifacts: []
|
|
392888
|
+
};
|
|
392889
|
+
}
|
|
392890
|
+
options2.onEvent?.({ kind: "stage-done", stage: stage.name, verdict: result.verdict, isError: result.isError });
|
|
392891
|
+
for (const artifact of result.artifacts) {
|
|
392892
|
+
options2.onEvent?.({ kind: "artifact", stage: stage.name, artifact });
|
|
392893
|
+
}
|
|
392894
|
+
return result;
|
|
392895
|
+
}
|
|
392896
|
+
var init_kernel = __esm(() => {
|
|
392897
|
+
init_intentRouter();
|
|
392898
|
+
init_headlessAgent();
|
|
392899
|
+
init_cliStepRunner();
|
|
392900
|
+
init_projectGates();
|
|
392901
|
+
});
|
|
392902
|
+
|
|
392903
|
+
// src/services/agents/kernelSpec.ts
|
|
392904
|
+
var exports_kernelSpec = {};
|
|
392905
|
+
__export(exports_kernelSpec, {
|
|
392906
|
+
runSpecWithKernel: () => runSpecWithKernel,
|
|
392907
|
+
runSpecVerifyWithKernel: () => runSpecVerifyWithKernel,
|
|
392908
|
+
planSpecVerify: () => planSpecVerify,
|
|
392909
|
+
planSpecRun: () => planSpecRun,
|
|
392910
|
+
mapStageResultsToSpecRunResult: () => mapStageResultsToSpecRunResult,
|
|
392911
|
+
mapKernelResultToSpecVerifyResult: () => mapKernelResultToSpecVerifyResult
|
|
392912
|
+
});
|
|
392913
|
+
function isSpecRunStage(stage) {
|
|
392914
|
+
return stage.role === "executor" && "meta" in stage && typeof stage.meta === "object";
|
|
392915
|
+
}
|
|
392916
|
+
function asSpecRunStage(stage) {
|
|
392917
|
+
return isSpecRunStage(stage) ? stage : null;
|
|
392918
|
+
}
|
|
392919
|
+
function planSpecRun(cwd2, name) {
|
|
392920
|
+
const spec = loadSpec(cwd2, name);
|
|
392921
|
+
if (!spec)
|
|
392922
|
+
throw new Error(`Spec not found: ${name}`);
|
|
392923
|
+
const requirements = readPhase(cwd2, name, "requirements") ?? "";
|
|
392924
|
+
const design = readPhase(cwd2, name, "design") ?? "";
|
|
392925
|
+
const tasks2 = parseTasks(readPhase(cwd2, name, "tasks") ?? "");
|
|
392926
|
+
const context4 = {
|
|
392927
|
+
cwd: cwd2,
|
|
392928
|
+
specName: spec.name,
|
|
392929
|
+
goal: spec.goal
|
|
392930
|
+
};
|
|
392931
|
+
const baseContext = `Requirements:
|
|
392932
|
+
${requirements}
|
|
392933
|
+
|
|
392934
|
+
Design:
|
|
392935
|
+
${design}`.slice(0, 6000);
|
|
392936
|
+
return tasks2.filter((t) => !t.done).map((task) => ({
|
|
392937
|
+
name: `spec-${spec.name}-${task.id}`,
|
|
392938
|
+
role: "executor",
|
|
392939
|
+
goal: task.title,
|
|
392940
|
+
context: context4,
|
|
392941
|
+
instructions: `You are implementing one task of a specced feature.
|
|
392942
|
+
|
|
392943
|
+
${baseContext}
|
|
392944
|
+
|
|
392945
|
+
Your task ${task.id}: ${task.title}
|
|
392946
|
+
|
|
392947
|
+
` + `Implement only this task, consistent with the requirements and design. End your reply with VERDICT: PASS if complete, or VERDICT: FAIL.`,
|
|
392948
|
+
meta: { taskId: task.id, taskTitle: task.title }
|
|
392949
|
+
}));
|
|
392950
|
+
}
|
|
392951
|
+
function mapStageResultsToSpecRunResult(spec, results) {
|
|
392952
|
+
const pairs = results.map((r) => ({ result: r, stage: asSpecRunStage(r.stage) })).filter((p2) => p2.stage !== null);
|
|
392953
|
+
const ran = pairs.map((p2) => ({
|
|
392954
|
+
id: p2.stage.meta.taskId,
|
|
392955
|
+
title: p2.stage.meta.taskTitle,
|
|
392956
|
+
status: p2.result.verdict === "FAIL" || p2.result.isError ? "failed" : "done"
|
|
392957
|
+
}));
|
|
392958
|
+
const stoppedOnFailure = pairs.some((p2) => p2.result.verdict === "FAIL" || p2.result.isError);
|
|
392959
|
+
return {
|
|
392960
|
+
name: spec.name,
|
|
392961
|
+
ran,
|
|
392962
|
+
remaining: 0,
|
|
392963
|
+
stoppedOnFailure
|
|
392964
|
+
};
|
|
392965
|
+
}
|
|
392966
|
+
async function runSpecWithKernel(cwd2, name, kernel, options2) {
|
|
392967
|
+
const spec = loadSpec(cwd2, name);
|
|
392968
|
+
if (!spec)
|
|
392969
|
+
throw new Error(`Spec not found: ${name}`);
|
|
392970
|
+
const stages = planSpecRun(cwd2, name);
|
|
392971
|
+
const results = [];
|
|
392972
|
+
for (const stage of stages) {
|
|
392973
|
+
const result = await runKernelStage(kernel, stage, {
|
|
392974
|
+
cwd: cwd2,
|
|
392975
|
+
dryRun: options2.dryRun,
|
|
392976
|
+
maxTurns: options2.maxTurns,
|
|
392977
|
+
skipPermissions: options2.skipPermissions,
|
|
392978
|
+
runner: options2.runner
|
|
392979
|
+
});
|
|
392980
|
+
results.push(result);
|
|
392981
|
+
if ((result.verdict === "FAIL" || result.isError) && stage.context.stopOnError !== false)
|
|
392982
|
+
break;
|
|
392983
|
+
if (!options2.all)
|
|
392984
|
+
break;
|
|
392985
|
+
}
|
|
392986
|
+
return mapStageResultsToSpecRunResult(spec, results);
|
|
392987
|
+
}
|
|
392988
|
+
function planSpecVerify(cwd2, name) {
|
|
392989
|
+
const spec = loadSpec(cwd2, name);
|
|
392990
|
+
if (!spec)
|
|
392991
|
+
throw new Error(`Spec not found: ${name}`);
|
|
392992
|
+
const requirements = readPhase(cwd2, name, "requirements") ?? "";
|
|
392993
|
+
const design = readPhase(cwd2, name, "design") ?? "";
|
|
392994
|
+
const tasks2 = parseTasks(readPhase(cwd2, name, "tasks") ?? "");
|
|
392995
|
+
return {
|
|
392996
|
+
name: `spec-${spec.name}-verify`,
|
|
392997
|
+
role: "verifier",
|
|
392998
|
+
goal: `Verify spec ${spec.name}: ${spec.goal}`,
|
|
392999
|
+
context: {
|
|
393000
|
+
cwd: cwd2,
|
|
393001
|
+
specName: spec.name,
|
|
393002
|
+
goal: spec.goal
|
|
393003
|
+
},
|
|
393004
|
+
instructions: [
|
|
393005
|
+
"You are verifying the implementation of a specced feature.",
|
|
393006
|
+
"",
|
|
393007
|
+
"=== CRITICAL ===",
|
|
393008
|
+
"You are STRICTLY PROHIBITED from modifying the project. Read, run commands, and inspect only.",
|
|
393009
|
+
"You must be stricter than the implementer. No proof = no PASS.",
|
|
393010
|
+
"",
|
|
393011
|
+
"=== REQUIRED PROOFS ===",
|
|
393012
|
+
"Before PASS, confirm ALL of the following with command-run evidence:",
|
|
393013
|
+
"1. Compile proof: the project builds.",
|
|
393014
|
+
"2. Test proof: the relevant test suite passes.",
|
|
393015
|
+
"3. Lint proof: configured linters/type-checkers pass.",
|
|
393016
|
+
"4. Diff proof: changed files match the spec.",
|
|
393017
|
+
"5. Runtime proof: the feature behaves as required.",
|
|
393018
|
+
"",
|
|
393019
|
+
"=== SPEC ===",
|
|
393020
|
+
`Goal: ${spec.goal}`,
|
|
393021
|
+
"",
|
|
393022
|
+
"Requirements:",
|
|
393023
|
+
requirements || "(none written)",
|
|
393024
|
+
"",
|
|
393025
|
+
"Design:",
|
|
393026
|
+
design || "(none written)",
|
|
393027
|
+
"",
|
|
393028
|
+
"Tasks:",
|
|
393029
|
+
tasks2.map((t) => `- [${t.done ? "x" : " "}] ${t.id}: ${t.title}`).join(`
|
|
393030
|
+
`),
|
|
393031
|
+
"",
|
|
393032
|
+
"=== OUTPUT FORMAT ===",
|
|
393033
|
+
"Each check MUST include the exact command you ran and the observed output.",
|
|
393034
|
+
"End with exactly one line: VERDICT: PASS, VERDICT: FAIL, or VERDICT: PARTIAL."
|
|
393035
|
+
].join(`
|
|
393036
|
+
`)
|
|
393037
|
+
};
|
|
393038
|
+
}
|
|
393039
|
+
function mapKernelResultToSpecVerifyResult(result) {
|
|
393040
|
+
return {
|
|
393041
|
+
verdict: result.verdict ?? "PARTIAL",
|
|
393042
|
+
summary: result.verdict === "PASS" ? "All required proofs (compile, test, lint, diff, runtime) were demonstrated by the verifier." : result.verdict === "FAIL" ? "The verifier found failing evidence. See subagent output for details." : "The verifier could not reach a definitive PASS/FAIL verdict.",
|
|
393043
|
+
commandFailures: result.artifacts.filter((a2) => a2.kind === "note" && a2.text.startsWith("FAIL gate")).length,
|
|
393044
|
+
gateResults: [],
|
|
393045
|
+
subagentOutput: result.output,
|
|
393046
|
+
generatedAt: new Date().toISOString()
|
|
393047
|
+
};
|
|
393048
|
+
}
|
|
393049
|
+
async function runSpecVerifyWithKernel(cwd2, name, kernel, options2) {
|
|
393050
|
+
const stage = planSpecVerify(cwd2, name);
|
|
393051
|
+
const result = await runKernelStage(kernel, stage, {
|
|
393052
|
+
cwd: cwd2,
|
|
393053
|
+
dryRun: options2.dryRun,
|
|
393054
|
+
maxTurns: options2.maxTurns,
|
|
393055
|
+
skipPermissions: options2.skipPermissions,
|
|
393056
|
+
runner: options2.runner
|
|
393057
|
+
});
|
|
393058
|
+
return mapKernelResultToSpecVerifyResult(result);
|
|
393059
|
+
}
|
|
393060
|
+
var init_kernelSpec = __esm(() => {
|
|
393061
|
+
init_kernel();
|
|
393062
|
+
init_spec();
|
|
393063
|
+
});
|
|
393064
|
+
|
|
392437
393065
|
// src/services/agents/spec.ts
|
|
393066
|
+
var exports_spec = {};
|
|
393067
|
+
__export(exports_spec, {
|
|
393068
|
+
writePhase: () => writePhase,
|
|
393069
|
+
specsDir: () => specsDir,
|
|
393070
|
+
specDir: () => specDir,
|
|
393071
|
+
slugifySpecName: () => slugifySpecName,
|
|
393072
|
+
runSpec: () => runSpec2,
|
|
393073
|
+
readPhase: () => readPhase,
|
|
393074
|
+
phaseFile: () => phaseFile,
|
|
393075
|
+
parseTasks: () => parseTasks,
|
|
393076
|
+
markTaskDone: () => markTaskDone,
|
|
393077
|
+
loadSpec: () => loadSpec,
|
|
393078
|
+
listSpecs: () => listSpecs2,
|
|
393079
|
+
generatePhase: () => generatePhase,
|
|
393080
|
+
formatSpecStatus: () => formatSpecStatus,
|
|
393081
|
+
formatSpecList: () => formatSpecList,
|
|
393082
|
+
deleteSpec: () => deleteSpec,
|
|
393083
|
+
createSpec: () => createSpec,
|
|
393084
|
+
approvePhase: () => approvePhase
|
|
393085
|
+
});
|
|
392438
393086
|
import {
|
|
392439
|
-
existsSync as
|
|
393087
|
+
existsSync as existsSync27,
|
|
392440
393088
|
mkdirSync as mkdirSync26,
|
|
392441
393089
|
readdirSync as readdirSync13,
|
|
392442
|
-
readFileSync as
|
|
393090
|
+
readFileSync as readFileSync35,
|
|
392443
393091
|
rmSync as rmSync5,
|
|
392444
393092
|
writeFileSync as writeFileSync24
|
|
392445
393093
|
} from "fs";
|
|
392446
|
-
import { join as
|
|
393094
|
+
import { join as join147 } from "path";
|
|
392447
393095
|
function specsDir(cwd2) {
|
|
392448
|
-
return
|
|
393096
|
+
return join147(cwd2, ".ur", "specs");
|
|
392449
393097
|
}
|
|
392450
393098
|
function slugifySpecName(name) {
|
|
392451
393099
|
return name.trim().toLowerCase().replace(/[^a-z0-9_-]+/g, "-").replace(/^-+|-+$/g, "") || "spec";
|
|
392452
393100
|
}
|
|
392453
393101
|
function specDir(cwd2, name) {
|
|
392454
|
-
return
|
|
393102
|
+
return join147(specsDir(cwd2), slugifySpecName(name));
|
|
392455
393103
|
}
|
|
392456
393104
|
function metaPath(cwd2, name) {
|
|
392457
|
-
return
|
|
393105
|
+
return join147(specDir(cwd2, name), "spec.json");
|
|
392458
393106
|
}
|
|
392459
393107
|
function phaseFile(phase) {
|
|
392460
393108
|
return `${phase}.md`;
|
|
392461
393109
|
}
|
|
392462
393110
|
function listSpecs2(cwd2) {
|
|
392463
393111
|
const dir = specsDir(cwd2);
|
|
392464
|
-
if (!
|
|
393112
|
+
if (!existsSync27(dir))
|
|
392465
393113
|
return [];
|
|
392466
|
-
return readdirSync13(dir).filter((entry) =>
|
|
393114
|
+
return readdirSync13(dir).filter((entry) => existsSync27(join147(dir, entry, "spec.json"))).map((entry) => safeParseJSON(readFileSync35(join147(dir, entry, "spec.json"), "utf-8"), false)).filter((m) => !!m && typeof m === "object" && ("goal" in m));
|
|
392467
393115
|
}
|
|
392468
393116
|
function loadSpec(cwd2, name) {
|
|
392469
393117
|
const path22 = metaPath(cwd2, name);
|
|
392470
|
-
if (!
|
|
393118
|
+
if (!existsSync27(path22))
|
|
392471
393119
|
return null;
|
|
392472
|
-
const parsed = safeParseJSON(
|
|
393120
|
+
const parsed = safeParseJSON(readFileSync35(path22, "utf-8"), false);
|
|
392473
393121
|
return parsed && typeof parsed === "object" ? parsed : null;
|
|
392474
393122
|
}
|
|
392475
393123
|
function saveMeta(cwd2, meta) {
|
|
@@ -392478,12 +393126,12 @@ function saveMeta(cwd2, meta) {
|
|
|
392478
393126
|
`);
|
|
392479
393127
|
}
|
|
392480
393128
|
function readPhase(cwd2, name, phase) {
|
|
392481
|
-
const path22 =
|
|
392482
|
-
return
|
|
393129
|
+
const path22 = join147(specDir(cwd2, name), phaseFile(phase));
|
|
393130
|
+
return existsSync27(path22) ? readFileSync35(path22, "utf-8") : null;
|
|
392483
393131
|
}
|
|
392484
393132
|
function writePhase(cwd2, name, phase, body) {
|
|
392485
393133
|
mkdirSync26(specDir(cwd2, name), { recursive: true });
|
|
392486
|
-
writeFileSync24(
|
|
393134
|
+
writeFileSync24(join147(specDir(cwd2, name), phaseFile(phase)), body.endsWith(`
|
|
392487
393135
|
`) ? body : `${body}
|
|
392488
393136
|
`);
|
|
392489
393137
|
}
|
|
@@ -392558,7 +393206,7 @@ function createSpec(cwd2, name, goal2) {
|
|
|
392558
393206
|
}
|
|
392559
393207
|
function deleteSpec(cwd2, name) {
|
|
392560
393208
|
const dir = specDir(cwd2, name);
|
|
392561
|
-
if (!
|
|
393209
|
+
if (!existsSync27(dir))
|
|
392562
393210
|
return false;
|
|
392563
393211
|
rmSync5(dir, { recursive: true, force: true });
|
|
392564
393212
|
return true;
|
|
@@ -392612,6 +393260,19 @@ async function runSpec2(cwd2, name, options2) {
|
|
|
392612
393260
|
const meta = loadSpec(cwd2, name);
|
|
392613
393261
|
if (!meta)
|
|
392614
393262
|
throw new Error(`Spec not found: ${name}`);
|
|
393263
|
+
if (options2.kernel) {
|
|
393264
|
+
const { runSpecWithKernel: runSpecWithKernel2 } = await Promise.resolve().then(() => (init_kernelSpec(), exports_kernelSpec));
|
|
393265
|
+
const kernelResult = await runSpecWithKernel2(cwd2, name, options2.kernel, {
|
|
393266
|
+
dryRun: options2.dryRun,
|
|
393267
|
+
maxTurns: options2.maxTurns,
|
|
393268
|
+
skipPermissions: options2.skipPermissions,
|
|
393269
|
+
all: options2.all,
|
|
393270
|
+
runner: options2.runner
|
|
393271
|
+
});
|
|
393272
|
+
const tasksMd = readPhase(cwd2, name, "tasks") ?? "";
|
|
393273
|
+
const remaining2 = parseTasks(tasksMd).filter((t) => !t.done).length;
|
|
393274
|
+
return { ...kernelResult, remaining: remaining2 };
|
|
393275
|
+
}
|
|
392615
393276
|
const runner2 = options2.runner ?? (options2.dryRun ? makeDryHeadlessRunner() : defaultHeadlessRunner());
|
|
392616
393277
|
const requirements = readPhase(cwd2, name, "requirements") ?? "";
|
|
392617
393278
|
const design = readPhase(cwd2, name, "design") ?? "";
|
|
@@ -392701,12 +393362,15 @@ function formatSpecStatus(cwd2, meta, json2) {
|
|
|
392701
393362
|
return JSON.stringify({ ...meta, tasks: { total: tasks2.length, done } }, null, 2);
|
|
392702
393363
|
}
|
|
392703
393364
|
const mark = (ok) => ok ? "\u2713" : "\u25CB";
|
|
393365
|
+
const v = meta.verification;
|
|
393366
|
+
const vMark = v ? v.verdict === "PASS" ? "\u2713" : v.verdict === "FAIL" ? "\u2717" : "\u25D0" : "\u25CB";
|
|
392704
393367
|
const lines = [
|
|
392705
393368
|
`Spec: ${meta.name}`,
|
|
392706
393369
|
`Goal: ${meta.goal}`,
|
|
392707
393370
|
`Phase: ${meta.phase}`,
|
|
392708
393371
|
`Approvals: ${mark(meta.approvals.requirements)} requirements ${mark(meta.approvals.design)} design ${mark(meta.approvals.tasks)} tasks`,
|
|
392709
393372
|
`Tasks: ${done}/${tasks2.length} done`,
|
|
393373
|
+
`Verification: ${vMark} ${v ? `${v.verdict} (${v.generatedAt})` : "not run"}`,
|
|
392710
393374
|
""
|
|
392711
393375
|
];
|
|
392712
393376
|
for (const task of tasks2) {
|
|
@@ -392723,9 +393387,259 @@ var init_spec = __esm(() => {
|
|
|
392723
393387
|
TASK_RE = /^\s*-\s*\[( |x|X)\]\s*(?:(T\d+)\s*:?\s*)?(.*)$/;
|
|
392724
393388
|
});
|
|
392725
393389
|
|
|
393390
|
+
// src/services/agents/specVerifier.ts
|
|
393391
|
+
import { existsSync as existsSync28, mkdirSync as mkdirSync27, readFileSync as readFileSync36, writeFileSync as writeFileSync25 } from "fs";
|
|
393392
|
+
import { join as join148 } from "path";
|
|
393393
|
+
function recordPath(cwd2, name) {
|
|
393394
|
+
return join148(cwd2, ".ur", "specs", name, RECORD_FILE);
|
|
393395
|
+
}
|
|
393396
|
+
function reportPath(cwd2, name) {
|
|
393397
|
+
return join148(cwd2, ".ur", "specs", name, REPORT_FILE);
|
|
393398
|
+
}
|
|
393399
|
+
function loadVerificationRecord(cwd2, name) {
|
|
393400
|
+
const path22 = recordPath(cwd2, name);
|
|
393401
|
+
if (!existsSync28(path22))
|
|
393402
|
+
return null;
|
|
393403
|
+
const parsed = safeParseJSON(readFileSync36(path22, "utf-8"), false);
|
|
393404
|
+
if (!parsed || typeof parsed !== "object")
|
|
393405
|
+
return null;
|
|
393406
|
+
return parsed;
|
|
393407
|
+
}
|
|
393408
|
+
function listVerificationRecords(cwd2, name) {
|
|
393409
|
+
const records = [];
|
|
393410
|
+
let current = loadVerificationRecord(cwd2, name);
|
|
393411
|
+
if (current)
|
|
393412
|
+
records.push(current);
|
|
393413
|
+
return records;
|
|
393414
|
+
}
|
|
393415
|
+
function saveVerificationRecord(cwd2, name, record3) {
|
|
393416
|
+
const path22 = recordPath(cwd2, name);
|
|
393417
|
+
mkdirSync27(join148(cwd2, ".ur", "specs", name), { recursive: true });
|
|
393418
|
+
writeFileSync25(path22, `${JSON.stringify(record3, null, 2)}
|
|
393419
|
+
`);
|
|
393420
|
+
}
|
|
393421
|
+
function writeVerificationReport(cwd2, name, result) {
|
|
393422
|
+
const lines = [
|
|
393423
|
+
`# Verification: ${name}`,
|
|
393424
|
+
"",
|
|
393425
|
+
`- Verdict: **${result.verdict}**`,
|
|
393426
|
+
`- Generated: ${result.generatedAt}`,
|
|
393427
|
+
`- Command failures: ${result.commandFailures}`,
|
|
393428
|
+
"",
|
|
393429
|
+
"## Summary",
|
|
393430
|
+
"",
|
|
393431
|
+
result.summary,
|
|
393432
|
+
"",
|
|
393433
|
+
"## Gate results",
|
|
393434
|
+
"",
|
|
393435
|
+
...result.gateResults.map((g) => g.ok ? `- \u2713 \`${g.command}\` passed` : `- \u2717 \`${g.command}\` failed (exit ${g.exitCode ?? "killed"})`),
|
|
393436
|
+
"",
|
|
393437
|
+
"## Subagent output",
|
|
393438
|
+
"",
|
|
393439
|
+
"```",
|
|
393440
|
+
result.subagentOutput,
|
|
393441
|
+
"```",
|
|
393442
|
+
""
|
|
393443
|
+
];
|
|
393444
|
+
writeFileSync25(reportPath(cwd2, name), lines.join(`
|
|
393445
|
+
`));
|
|
393446
|
+
}
|
|
393447
|
+
async function captureDiff(cwd2) {
|
|
393448
|
+
const result = await execFileNoThrowWithCwd("git", ["diff", "HEAD", "--stat"], { cwd: cwd2, preserveOutputOnError: true });
|
|
393449
|
+
const statLines = result.stdout.trim().split(`
|
|
393450
|
+
`).filter(Boolean);
|
|
393451
|
+
const changedFiles = statLines.slice(0, -1).map((line) => line.split("|")[0]?.trim()).filter(Boolean);
|
|
393452
|
+
const diffResult = await execFileNoThrowWithCwd("git", ["diff", "HEAD"], { cwd: cwd2, preserveOutputOnError: true });
|
|
393453
|
+
const diff3 = diffResult.stdout.slice(0, MAX_DIFF_CHARS);
|
|
393454
|
+
return { diff: diff3, changedFiles };
|
|
393455
|
+
}
|
|
393456
|
+
function buildVerifierPrompt(evidence2) {
|
|
393457
|
+
const incompleteTasks = evidence2.tasks.filter((t) => !t.done).map((t) => `- ${t.id}: ${t.title}`).join(`
|
|
393458
|
+
`) || "None (all tasks marked done)";
|
|
393459
|
+
const prior = evidence2.priorVerifications.map((r) => `- ${r.generatedAt}: ${r.verdict} \u2014 ${r.summary}`).join(`
|
|
393460
|
+
`) || "No prior verifications.";
|
|
393461
|
+
return [
|
|
393462
|
+
"You are verifying the implementation of a specced feature.",
|
|
393463
|
+
"",
|
|
393464
|
+
"=== CRITICAL ===",
|
|
393465
|
+
"You are STRICTLY PROHIBITED from modifying the project. Read, run commands, and inspect only.",
|
|
393466
|
+
"You must be stricter than the implementer. No proof = no PASS.",
|
|
393467
|
+
"",
|
|
393468
|
+
"=== REQUIRED PROOFS ===",
|
|
393469
|
+
"Before PASS, confirm ALL of the following with command-run evidence:",
|
|
393470
|
+
"1. Compile proof: the project builds (e.g., tsc --noEmit, build script).",
|
|
393471
|
+
"2. Test proof: the relevant test suite passes.",
|
|
393472
|
+
"3. Lint proof: configured linters/type-checkers pass.",
|
|
393473
|
+
"4. Diff proof: the changed files match the spec and do not include unrelated edits.",
|
|
393474
|
+
"5. Runtime proof: the feature behaves as required (run the code / hit the endpoint / exercise the CLI).",
|
|
393475
|
+
"",
|
|
393476
|
+
"=== SPEC ===",
|
|
393477
|
+
`Goal: ${evidence2.spec.goal}`,
|
|
393478
|
+
"",
|
|
393479
|
+
"Requirements:",
|
|
393480
|
+
evidence2.requirements || "(none written)",
|
|
393481
|
+
"",
|
|
393482
|
+
"Design:",
|
|
393483
|
+
evidence2.design || "(none written)",
|
|
393484
|
+
"",
|
|
393485
|
+
"Tasks:",
|
|
393486
|
+
evidence2.tasks.map((t) => `- [${t.done ? "x" : " "}] ${t.id}: ${t.title}`).join(`
|
|
393487
|
+
`),
|
|
393488
|
+
"",
|
|
393489
|
+
"Incomplete tasks at time of verification:",
|
|
393490
|
+
incompleteTasks,
|
|
393491
|
+
"",
|
|
393492
|
+
"Changed files:",
|
|
393493
|
+
evidence2.changedFiles.length ? evidence2.changedFiles.map((f) => `- ${f}`).join(`
|
|
393494
|
+
`) : "(none detected)",
|
|
393495
|
+
"",
|
|
393496
|
+
"Diff preview:",
|
|
393497
|
+
"```diff",
|
|
393498
|
+
evidence2.diff || "(no diff)",
|
|
393499
|
+
"```",
|
|
393500
|
+
"",
|
|
393501
|
+
"Prior verifications:",
|
|
393502
|
+
prior,
|
|
393503
|
+
"",
|
|
393504
|
+
"=== OUTPUT FORMAT ===",
|
|
393505
|
+
"Each check MUST include the exact command you ran and the observed output.",
|
|
393506
|
+
"End with exactly one line: VERDICT: PASS, VERDICT: FAIL, or VERDICT: PARTIAL.",
|
|
393507
|
+
"Use PARTIAL only for missing tools or environment, never for uncertainty."
|
|
393508
|
+
].join(`
|
|
393509
|
+
`);
|
|
393510
|
+
}
|
|
393511
|
+
async function runDeterministicGates(cwd2) {
|
|
393512
|
+
const config3 = await loadVerifyConfig(cwd2);
|
|
393513
|
+
const results = [];
|
|
393514
|
+
if (!config3)
|
|
393515
|
+
return { results, failed: false };
|
|
393516
|
+
const commands = config3.afterEdit?.length ? config3.afterEdit : [];
|
|
393517
|
+
if (commands.length === 0)
|
|
393518
|
+
return { results, failed: false };
|
|
393519
|
+
const gate = await runGateCommands(commands, cwd2, config3.timeoutMs);
|
|
393520
|
+
if (gate.ok) {
|
|
393521
|
+
results.push({ ok: true, command: commands.join(" && "), ranCommands: gate.ranCommands });
|
|
393522
|
+
return { results, failed: false };
|
|
393523
|
+
}
|
|
393524
|
+
const failed = gate;
|
|
393525
|
+
results.push({
|
|
393526
|
+
ok: false,
|
|
393527
|
+
command: failed.command,
|
|
393528
|
+
exitCode: failed.exitCode,
|
|
393529
|
+
stdout: failed.stdout,
|
|
393530
|
+
stderr: failed.stderr
|
|
393531
|
+
});
|
|
393532
|
+
return { results, failed: true };
|
|
393533
|
+
}
|
|
393534
|
+
function countCommandFailures(output) {
|
|
393535
|
+
const markers = ["[ERROR]", "Command failed", "exit code 1", "Error:", "FAILED"];
|
|
393536
|
+
let count4 = 0;
|
|
393537
|
+
const lower = output.toLowerCase();
|
|
393538
|
+
for (const marker of markers) {
|
|
393539
|
+
const re = new RegExp(marker.replace(/\[/g, "\\[").replace(/\]/g, "\\]").toLowerCase(), "g");
|
|
393540
|
+
const matches = lower.match(re);
|
|
393541
|
+
if (matches)
|
|
393542
|
+
count4 += matches.length;
|
|
393543
|
+
}
|
|
393544
|
+
return count4;
|
|
393545
|
+
}
|
|
393546
|
+
async function runSpecVerification(cwd2, name, options2 = {}) {
|
|
393547
|
+
if (options2.kernel) {
|
|
393548
|
+
const { runSpecVerifyWithKernel: runSpecVerifyWithKernel2 } = await Promise.resolve().then(() => (init_kernelSpec(), exports_kernelSpec));
|
|
393549
|
+
return runSpecVerifyWithKernel2(cwd2, name, options2.kernel, {
|
|
393550
|
+
dryRun: options2.dryRun,
|
|
393551
|
+
maxTurns: options2.maxTurns,
|
|
393552
|
+
skipPermissions: options2.skipPermissions,
|
|
393553
|
+
runner: options2.runner
|
|
393554
|
+
});
|
|
393555
|
+
}
|
|
393556
|
+
const runner2 = options2.runner ?? (options2.dryRun ? makeDryHeadlessRunner() : defaultHeadlessRunner());
|
|
393557
|
+
const { readPhase: readPhase2, loadSpec: loadSpec2, parseTasks: parseTasks2 } = await Promise.resolve().then(() => (init_spec(), exports_spec));
|
|
393558
|
+
const spec = loadSpec2(cwd2, name);
|
|
393559
|
+
if (!spec)
|
|
393560
|
+
throw new Error(`Spec not found: ${name}`);
|
|
393561
|
+
const gateRun = await runDeterministicGates(cwd2);
|
|
393562
|
+
if (gateRun.failed) {
|
|
393563
|
+
const generatedAt2 = new Date().toISOString();
|
|
393564
|
+
const summary2 = `Verification failed at project gates: ${gateRun.results.filter((r) => !r.ok).map((r) => r.command).join(", ")}`;
|
|
393565
|
+
const result2 = {
|
|
393566
|
+
verdict: "FAIL",
|
|
393567
|
+
summary: summary2,
|
|
393568
|
+
commandFailures: gateRun.results.filter((r) => !r.ok).length,
|
|
393569
|
+
gateResults: gateRun.results,
|
|
393570
|
+
subagentOutput: "",
|
|
393571
|
+
generatedAt: generatedAt2
|
|
393572
|
+
};
|
|
393573
|
+
const record4 = {
|
|
393574
|
+
version: 1,
|
|
393575
|
+
verdict: "FAIL",
|
|
393576
|
+
summary: summary2,
|
|
393577
|
+
commandFailures: result2.commandFailures,
|
|
393578
|
+
generatedAt: generatedAt2
|
|
393579
|
+
};
|
|
393580
|
+
saveVerificationRecord(cwd2, name, record4);
|
|
393581
|
+
writeVerificationReport(cwd2, name, result2);
|
|
393582
|
+
return result2;
|
|
393583
|
+
}
|
|
393584
|
+
const requirements = readPhase2(cwd2, name, "requirements") ?? "";
|
|
393585
|
+
const design = readPhase2(cwd2, name, "design") ?? "";
|
|
393586
|
+
const tasksMd = readPhase2(cwd2, name, "tasks") ?? "";
|
|
393587
|
+
const tasks2 = parseTasks2(tasksMd);
|
|
393588
|
+
const { diff: diff3, changedFiles } = await captureDiff(cwd2);
|
|
393589
|
+
const priorVerifications = listVerificationRecords(cwd2, name);
|
|
393590
|
+
const evidence2 = {
|
|
393591
|
+
spec,
|
|
393592
|
+
requirements,
|
|
393593
|
+
design,
|
|
393594
|
+
tasks: tasks2,
|
|
393595
|
+
changedFiles,
|
|
393596
|
+
diff: diff3,
|
|
393597
|
+
priorVerifications
|
|
393598
|
+
};
|
|
393599
|
+
const prompt = buildVerifierPrompt(evidence2);
|
|
393600
|
+
const out = await runner2({
|
|
393601
|
+
cwd: cwd2,
|
|
393602
|
+
prompt,
|
|
393603
|
+
maxTurns: options2.maxTurns,
|
|
393604
|
+
skipPermissions: options2.skipPermissions
|
|
393605
|
+
});
|
|
393606
|
+
const verdict = extractVerdict(out.output) ?? "PARTIAL";
|
|
393607
|
+
const commandFailures = countCommandFailures(out.output);
|
|
393608
|
+
const generatedAt = new Date().toISOString();
|
|
393609
|
+
const summary = verdict === "PASS" ? "All required proofs (compile, test, lint, diff, runtime) were demonstrated by the verifier." : verdict === "FAIL" ? "The verifier found failing evidence. See subagent output for details." : "The verifier could not reach a definitive PASS/FAIL verdict.";
|
|
393610
|
+
const result = {
|
|
393611
|
+
verdict,
|
|
393612
|
+
summary,
|
|
393613
|
+
commandFailures,
|
|
393614
|
+
gateResults: gateRun.results,
|
|
393615
|
+
subagentOutput: out.output,
|
|
393616
|
+
generatedAt
|
|
393617
|
+
};
|
|
393618
|
+
const record3 = {
|
|
393619
|
+
version: 1,
|
|
393620
|
+
verdict,
|
|
393621
|
+
summary,
|
|
393622
|
+
commandFailures,
|
|
393623
|
+
generatedAt
|
|
393624
|
+
};
|
|
393625
|
+
if (!options2.dryRun) {
|
|
393626
|
+
saveVerificationRecord(cwd2, name, record3);
|
|
393627
|
+
writeVerificationReport(cwd2, name, result);
|
|
393628
|
+
}
|
|
393629
|
+
return result;
|
|
393630
|
+
}
|
|
393631
|
+
var RECORD_FILE = "verification.json", REPORT_FILE = "verification.md", MAX_DIFF_CHARS = 12000;
|
|
393632
|
+
var init_specVerifier = __esm(() => {
|
|
393633
|
+
init_execFileNoThrow();
|
|
393634
|
+
init_json();
|
|
393635
|
+
init_cliStepRunner();
|
|
393636
|
+
init_headlessAgent();
|
|
393637
|
+
init_projectGates();
|
|
393638
|
+
});
|
|
393639
|
+
|
|
392726
393640
|
// src/commands/spec/spec.ts
|
|
392727
|
-
var
|
|
392728
|
-
__export(
|
|
393641
|
+
var exports_spec2 = {};
|
|
393642
|
+
__export(exports_spec2, {
|
|
392729
393643
|
call: () => call71
|
|
392730
393644
|
});
|
|
392731
393645
|
function usage9() {
|
|
@@ -392738,7 +393652,8 @@ function usage9() {
|
|
|
392738
393652
|
" ur spec approve <name> [requirements|design|tasks] [--json]",
|
|
392739
393653
|
" ur spec generate <name> [requirements|design|tasks] [--dry-run] [--max-turns N] [--json]",
|
|
392740
393654
|
" ur spec next <name> [--json]",
|
|
392741
|
-
" ur spec run <name> [--all] [--dry-run] [--max-turns N] [--skip-permissions] [--json]",
|
|
393655
|
+
" ur spec run <name> [--all] [--dry-run] [--max-turns N] [--skip-permissions] [--kernel] [--json]",
|
|
393656
|
+
" ur spec verify <name> [--dry-run] [--max-turns N] [--skip-permissions] [--kernel] [--json]",
|
|
392742
393657
|
" ur spec delete <name> [--json]"
|
|
392743
393658
|
].join(`
|
|
392744
393659
|
`);
|
|
@@ -392846,6 +393761,7 @@ var PHASES, VALUE_FLAGS, call71 = async (args) => {
|
|
|
392846
393761
|
if (action3 === "run") {
|
|
392847
393762
|
const maxTurnsRaw = option10(tokens, "--max-turns");
|
|
392848
393763
|
const events2 = [];
|
|
393764
|
+
const useKernel = tokens.includes("--kernel");
|
|
392849
393765
|
try {
|
|
392850
393766
|
const result = await runSpec2(cwd2, name, {
|
|
392851
393767
|
cwd: cwd2,
|
|
@@ -392853,6 +393769,7 @@ var PHASES, VALUE_FLAGS, call71 = async (args) => {
|
|
|
392853
393769
|
dryRun: tokens.includes("--dry-run"),
|
|
392854
393770
|
skipPermissions: tokens.includes("--skip-permissions"),
|
|
392855
393771
|
maxTurns: maxTurnsRaw ? Number(maxTurnsRaw) : undefined,
|
|
393772
|
+
kernel: useKernel ? createAgentKernel({ cwd: cwd2, dryRun: tokens.includes("--dry-run"), maxTurns: maxTurnsRaw ? Number(maxTurnsRaw) : undefined, skipPermissions: tokens.includes("--skip-permissions") }) : undefined,
|
|
392856
393773
|
onEvent: (event) => {
|
|
392857
393774
|
events2.push(` ${event.id}: ${event.isError ? "error" : event.verdict ?? "no verdict"}`);
|
|
392858
393775
|
}
|
|
@@ -392877,6 +393794,41 @@ ${ran}${trace4}`
|
|
|
392877
393794
|
return { type: "text", value: error40 instanceof Error ? error40.message : String(error40) };
|
|
392878
393795
|
}
|
|
392879
393796
|
}
|
|
393797
|
+
if (action3 === "verify") {
|
|
393798
|
+
const meta = loadSpec(cwd2, name);
|
|
393799
|
+
if (!meta)
|
|
393800
|
+
return { type: "text", value: notFound2(name) };
|
|
393801
|
+
const maxTurnsRaw = option10(tokens, "--max-turns");
|
|
393802
|
+
const useKernel = tokens.includes("--kernel");
|
|
393803
|
+
try {
|
|
393804
|
+
const result = await runSpecVerification(cwd2, name, {
|
|
393805
|
+
dryRun: tokens.includes("--dry-run"),
|
|
393806
|
+
skipPermissions: tokens.includes("--skip-permissions"),
|
|
393807
|
+
maxTurns: maxTurnsRaw ? Number(maxTurnsRaw) : undefined,
|
|
393808
|
+
kernel: useKernel ? createAgentKernel({ cwd: cwd2, dryRun: tokens.includes("--dry-run"), maxTurns: maxTurnsRaw ? Number(maxTurnsRaw) : undefined, skipPermissions: tokens.includes("--skip-permissions") }) : undefined
|
|
393809
|
+
});
|
|
393810
|
+
if (json2)
|
|
393811
|
+
return { type: "text", value: JSON.stringify(result, null, 2) };
|
|
393812
|
+
const gateLines = result.gateResults.length ? result.gateResults.map((g) => ` ${g.ok ? "\u2713" : "\u2717"} ${g.command}`).join(`
|
|
393813
|
+
`) : " (no project gates configured)";
|
|
393814
|
+
return {
|
|
393815
|
+
type: "text",
|
|
393816
|
+
value: [
|
|
393817
|
+
`Spec ${name}: verification ${result.verdict}`,
|
|
393818
|
+
`Summary: ${result.summary}`,
|
|
393819
|
+
`Command failures: ${result.commandFailures}`,
|
|
393820
|
+
"",
|
|
393821
|
+
"Gates:",
|
|
393822
|
+
gateLines,
|
|
393823
|
+
"",
|
|
393824
|
+
"Report: .ur/specs/verification.md"
|
|
393825
|
+
].join(`
|
|
393826
|
+
`)
|
|
393827
|
+
};
|
|
393828
|
+
} catch (error40) {
|
|
393829
|
+
return { type: "text", value: error40 instanceof Error ? error40.message : String(error40) };
|
|
393830
|
+
}
|
|
393831
|
+
}
|
|
392880
393832
|
if (action3 === "delete" || action3 === "remove") {
|
|
392881
393833
|
const deleted = deleteSpec(cwd2, name);
|
|
392882
393834
|
return {
|
|
@@ -392888,6 +393840,8 @@ ${ran}${trace4}`
|
|
|
392888
393840
|
};
|
|
392889
393841
|
var init_spec2 = __esm(() => {
|
|
392890
393842
|
init_spec();
|
|
393843
|
+
init_kernel();
|
|
393844
|
+
init_specVerifier();
|
|
392891
393845
|
init_argumentSubstitution();
|
|
392892
393846
|
init_cwd2();
|
|
392893
393847
|
PHASES = ["requirements", "design", "tasks"];
|
|
@@ -392901,17 +393855,17 @@ var init_spec3 = __esm(() => {
|
|
|
392901
393855
|
type: "local",
|
|
392902
393856
|
name: "spec",
|
|
392903
393857
|
aliases: ["specs"],
|
|
392904
|
-
description: "Spec-driven development: scaffold requirements -> design -> tasks in .ur/specs
|
|
392905
|
-
argumentHint: "init|list|show|generate|approve|next|run|status|delete [name] [--goal ...] [--all] [--dry-run] [--json]",
|
|
393858
|
+
description: "Spec-driven development: scaffold requirements -> design -> tasks in .ur/specs, execute task-by-task, and verify with strict proof gates",
|
|
393859
|
+
argumentHint: "init|list|show|generate|approve|next|run|verify|status|delete [name] [--goal ...] [--all] [--dry-run] [--kernel] [--json]",
|
|
392906
393860
|
supportsNonInteractive: true,
|
|
392907
|
-
load: () => Promise.resolve().then(() => (init_spec2(),
|
|
393861
|
+
load: () => Promise.resolve().then(() => (init_spec2(), exports_spec2))
|
|
392908
393862
|
};
|
|
392909
393863
|
spec_default = spec;
|
|
392910
393864
|
});
|
|
392911
393865
|
|
|
392912
393866
|
// src/services/agents/escalation.ts
|
|
392913
|
-
import { existsSync as
|
|
392914
|
-
import { join as
|
|
393867
|
+
import { existsSync as existsSync29, mkdirSync as mkdirSync28, readFileSync as readFileSync37, writeFileSync as writeFileSync26 } from "fs";
|
|
393868
|
+
import { join as join149 } from "path";
|
|
392915
393869
|
function scoreOracle(model) {
|
|
392916
393870
|
let score = (model.contextLength ?? 0) / 1000;
|
|
392917
393871
|
if (model.likelyCode)
|
|
@@ -393081,18 +394035,18 @@ ${question}`,
|
|
|
393081
394035
|
return { model: tiers.oracle, output: out.output, verdict: out.verdict ?? null };
|
|
393082
394036
|
}
|
|
393083
394037
|
function policyPath(cwd2) {
|
|
393084
|
-
return
|
|
394038
|
+
return join149(cwd2, ".ur", "escalation.json");
|
|
393085
394039
|
}
|
|
393086
394040
|
function loadPolicy(cwd2) {
|
|
393087
394041
|
const path22 = policyPath(cwd2);
|
|
393088
|
-
if (!
|
|
394042
|
+
if (!existsSync29(path22))
|
|
393089
394043
|
return {};
|
|
393090
|
-
const parsed = safeParseJSON(
|
|
394044
|
+
const parsed = safeParseJSON(readFileSync37(path22, "utf-8"), false);
|
|
393091
394045
|
return parsed && typeof parsed === "object" ? parsed : {};
|
|
393092
394046
|
}
|
|
393093
394047
|
function savePolicy(cwd2, policy) {
|
|
393094
|
-
|
|
393095
|
-
|
|
394048
|
+
mkdirSync28(join149(cwd2, ".ur"), { recursive: true });
|
|
394049
|
+
writeFileSync26(policyPath(cwd2), `${JSON.stringify(policy, null, 2)}
|
|
393096
394050
|
`);
|
|
393097
394051
|
}
|
|
393098
394052
|
function formatPlan(plan, json2) {
|
|
@@ -393140,29 +394094,29 @@ var init_escalation = __esm(() => {
|
|
|
393140
394094
|
|
|
393141
394095
|
// src/services/agents/artifacts.ts
|
|
393142
394096
|
import {
|
|
393143
|
-
existsSync as
|
|
393144
|
-
mkdirSync as
|
|
393145
|
-
readFileSync as
|
|
394097
|
+
existsSync as existsSync30,
|
|
394098
|
+
mkdirSync as mkdirSync29,
|
|
394099
|
+
readFileSync as readFileSync38,
|
|
393146
394100
|
rmSync as rmSync6,
|
|
393147
|
-
writeFileSync as
|
|
394101
|
+
writeFileSync as writeFileSync27
|
|
393148
394102
|
} from "fs";
|
|
393149
|
-
import { join as
|
|
394103
|
+
import { join as join150 } from "path";
|
|
393150
394104
|
function artifactsDir(cwd2) {
|
|
393151
|
-
return
|
|
394105
|
+
return join150(cwd2, ".ur", "artifacts");
|
|
393152
394106
|
}
|
|
393153
394107
|
function manifestPath4(cwd2) {
|
|
393154
|
-
return
|
|
394108
|
+
return join150(artifactsDir(cwd2), "manifest.json");
|
|
393155
394109
|
}
|
|
393156
394110
|
function loadManifest3(cwd2) {
|
|
393157
394111
|
const path22 = manifestPath4(cwd2);
|
|
393158
|
-
if (!
|
|
394112
|
+
if (!existsSync30(path22))
|
|
393159
394113
|
return { version: 1, artifacts: [] };
|
|
393160
|
-
const parsed = safeParseJSON(
|
|
394114
|
+
const parsed = safeParseJSON(readFileSync38(path22, "utf-8"), false);
|
|
393161
394115
|
return parsed && typeof parsed === "object" && Array.isArray(parsed.artifacts) ? parsed : { version: 1, artifacts: [] };
|
|
393162
394116
|
}
|
|
393163
394117
|
function saveManifest3(cwd2, manifest) {
|
|
393164
|
-
|
|
393165
|
-
|
|
394118
|
+
mkdirSync29(artifactsDir(cwd2), { recursive: true });
|
|
394119
|
+
writeFileSync27(manifestPath4(cwd2), `${JSON.stringify(manifest, null, 2)}
|
|
393166
394120
|
`);
|
|
393167
394121
|
}
|
|
393168
394122
|
function nextId2(manifest) {
|
|
@@ -393178,10 +394132,10 @@ function recordArtifact(cwd2, input) {
|
|
|
393178
394132
|
const now6 = new Date().toISOString();
|
|
393179
394133
|
let file2 = input.file;
|
|
393180
394134
|
if (input.body !== undefined && !file2) {
|
|
393181
|
-
const dir =
|
|
393182
|
-
|
|
393183
|
-
const rel =
|
|
393184
|
-
|
|
394135
|
+
const dir = join150(artifactsDir(cwd2), "files");
|
|
394136
|
+
mkdirSync29(dir, { recursive: true });
|
|
394137
|
+
const rel = join150("files", `${id}-${slug2(input.title)}.${EXT[input.kind]}`);
|
|
394138
|
+
writeFileSync27(join150(artifactsDir(cwd2), rel), input.body);
|
|
393185
394139
|
file2 = rel;
|
|
393186
394140
|
}
|
|
393187
394141
|
const artifact = {
|
|
@@ -393210,8 +394164,8 @@ function readArtifactBody(cwd2, id) {
|
|
|
393210
394164
|
const artifact = getArtifact(cwd2, id);
|
|
393211
394165
|
if (!artifact?.file)
|
|
393212
394166
|
return null;
|
|
393213
|
-
const path22 =
|
|
393214
|
-
return
|
|
394167
|
+
const path22 = join150(artifactsDir(cwd2), artifact.file);
|
|
394168
|
+
return existsSync30(path22) ? readFileSync38(path22, "utf-8") : null;
|
|
393215
394169
|
}
|
|
393216
394170
|
function mutate2(cwd2, id, fn) {
|
|
393217
394171
|
const manifest = loadManifest3(cwd2);
|
|
@@ -393239,12 +394193,12 @@ function deleteArtifact(cwd2, id) {
|
|
|
393239
394193
|
if (!artifact)
|
|
393240
394194
|
return false;
|
|
393241
394195
|
if (artifact.file)
|
|
393242
|
-
rmSync6(
|
|
394196
|
+
rmSync6(join150(artifactsDir(cwd2), artifact.file), { force: true });
|
|
393243
394197
|
manifest.artifacts = manifest.artifacts.filter((a2) => a2.id !== id);
|
|
393244
394198
|
saveManifest3(cwd2, manifest);
|
|
393245
394199
|
return true;
|
|
393246
394200
|
}
|
|
393247
|
-
async function
|
|
394201
|
+
async function captureDiff2(cwd2, title = "Working tree diff", exec6 = defaultExec) {
|
|
393248
394202
|
const diff3 = await exec6("git", ["diff", "HEAD"], cwd2);
|
|
393249
394203
|
if (!diff3.stdout.trim())
|
|
393250
394204
|
return null;
|
|
@@ -393330,8 +394284,8 @@ var init_artifacts = __esm(() => {
|
|
|
393330
394284
|
});
|
|
393331
394285
|
|
|
393332
394286
|
// src/services/agents/learning.ts
|
|
393333
|
-
import { existsSync as
|
|
393334
|
-
import { join as
|
|
394287
|
+
import { existsSync as existsSync31, mkdirSync as mkdirSync30, readFileSync as readFileSync39, writeFileSync as writeFileSync28 } from "fs";
|
|
394288
|
+
import { join as join151 } from "path";
|
|
393335
394289
|
function emptyStats() {
|
|
393336
394290
|
return {
|
|
393337
394291
|
version: 1,
|
|
@@ -393440,23 +394394,23 @@ function difficultyBias(stats, category, minSamples = 3) {
|
|
|
393440
394394
|
return 4;
|
|
393441
394395
|
}
|
|
393442
394396
|
function learningDir(cwd2) {
|
|
393443
|
-
return
|
|
394397
|
+
return join151(cwd2, ".ur", "learning");
|
|
393444
394398
|
}
|
|
393445
394399
|
function statsPath(cwd2) {
|
|
393446
|
-
return
|
|
394400
|
+
return join151(learningDir(cwd2), "stats.json");
|
|
393447
394401
|
}
|
|
393448
394402
|
function loadStats(cwd2) {
|
|
393449
394403
|
const path22 = statsPath(cwd2);
|
|
393450
|
-
if (!
|
|
394404
|
+
if (!existsSync31(path22))
|
|
393451
394405
|
return emptyStats();
|
|
393452
|
-
const parsed = safeParseJSON(
|
|
394406
|
+
const parsed = safeParseJSON(readFileSync39(path22, "utf-8"), false);
|
|
393453
394407
|
if (!parsed || typeof parsed !== "object")
|
|
393454
394408
|
return emptyStats();
|
|
393455
394409
|
return { ...emptyStats(), ...parsed };
|
|
393456
394410
|
}
|
|
393457
394411
|
function saveStats(cwd2, stats) {
|
|
393458
|
-
|
|
393459
|
-
|
|
394412
|
+
mkdirSync30(learningDir(cwd2), { recursive: true });
|
|
394413
|
+
writeFileSync28(statsPath(cwd2), `${JSON.stringify(stats, null, 2)}
|
|
393460
394414
|
`);
|
|
393461
394415
|
}
|
|
393462
394416
|
async function reflectOnFailures(input) {
|
|
@@ -393784,7 +394738,7 @@ var exports_guardrails = {};
|
|
|
393784
394738
|
__export(exports_guardrails, {
|
|
393785
394739
|
call: () => call74
|
|
393786
394740
|
});
|
|
393787
|
-
import { existsSync as
|
|
394741
|
+
import { existsSync as existsSync32, readFileSync as readFileSync40 } from "fs";
|
|
393788
394742
|
function optionValue4(tokens, flag) {
|
|
393789
394743
|
const index2 = tokens.indexOf(flag);
|
|
393790
394744
|
return index2 >= 0 ? tokens[index2 + 1] : undefined;
|
|
@@ -393850,10 +394804,10 @@ var call74 = async (args) => {
|
|
|
393850
394804
|
const filePath = optionValue4(tokens, "--file");
|
|
393851
394805
|
let text;
|
|
393852
394806
|
if (filePath) {
|
|
393853
|
-
if (!
|
|
394807
|
+
if (!existsSync32(filePath)) {
|
|
393854
394808
|
return { type: "text", value: `File not found: ${filePath}` };
|
|
393855
394809
|
}
|
|
393856
|
-
text =
|
|
394810
|
+
text = readFileSync40(filePath, "utf-8");
|
|
393857
394811
|
} else {
|
|
393858
394812
|
text = tokens.filter((token) => !token.startsWith("--") && token !== "check").join(" ");
|
|
393859
394813
|
}
|
|
@@ -393891,8 +394845,8 @@ var init_guardrails3 = __esm(() => {
|
|
|
393891
394845
|
});
|
|
393892
394846
|
|
|
393893
394847
|
// src/services/agents/execTarget.ts
|
|
393894
|
-
import { existsSync as
|
|
393895
|
-
import { join as
|
|
394848
|
+
import { existsSync as existsSync33, mkdirSync as mkdirSync31, readFileSync as readFileSync41, writeFileSync as writeFileSync29 } from "fs";
|
|
394849
|
+
import { join as join152 } from "path";
|
|
393896
394850
|
function isContainerized(config3) {
|
|
393897
394851
|
return config3.kind !== "local";
|
|
393898
394852
|
}
|
|
@@ -393916,13 +394870,13 @@ function wrapCommand(config3, command5, cwd2) {
|
|
|
393916
394870
|
return { file: "docker", args: buildDockerArgs(config3, command5, cwd2) };
|
|
393917
394871
|
}
|
|
393918
394872
|
function configPath(cwd2) {
|
|
393919
|
-
return
|
|
394873
|
+
return join152(cwd2, ".ur", "devcontainer.json");
|
|
393920
394874
|
}
|
|
393921
394875
|
function readDevcontainerImage(cwd2) {
|
|
393922
|
-
const path22 =
|
|
393923
|
-
if (!
|
|
394876
|
+
const path22 = join152(cwd2, ".devcontainer", "devcontainer.json");
|
|
394877
|
+
if (!existsSync33(path22))
|
|
393924
394878
|
return;
|
|
393925
|
-
const parsed = safeParseJSON(
|
|
394879
|
+
const parsed = safeParseJSON(readFileSync41(path22, "utf-8"), false);
|
|
393926
394880
|
if (parsed && typeof parsed === "object" && typeof parsed.image === "string") {
|
|
393927
394881
|
return parsed.image;
|
|
393928
394882
|
}
|
|
@@ -393940,8 +394894,8 @@ function resolveExecTarget(cwd2, env4 = process.env) {
|
|
|
393940
394894
|
if (envKind === "local")
|
|
393941
394895
|
return { kind: "local" };
|
|
393942
394896
|
const path22 = configPath(cwd2);
|
|
393943
|
-
if (
|
|
393944
|
-
const parsed = safeParseJSON(
|
|
394897
|
+
if (existsSync33(path22)) {
|
|
394898
|
+
const parsed = safeParseJSON(readFileSync41(path22, "utf-8"), false);
|
|
393945
394899
|
if (parsed && typeof parsed === "object") {
|
|
393946
394900
|
const config3 = parsed;
|
|
393947
394901
|
if (config3.kind === "devcontainer" && !config3.image) {
|
|
@@ -393959,10 +394913,10 @@ function defaultExecTargetConfig(image = "node:22-bookworm") {
|
|
|
393959
394913
|
}
|
|
393960
394914
|
function scaffoldExecTarget(cwd2, options2 = {}) {
|
|
393961
394915
|
const path22 = configPath(cwd2);
|
|
393962
|
-
|
|
393963
|
-
if (
|
|
394916
|
+
mkdirSync31(join152(cwd2, ".ur"), { recursive: true });
|
|
394917
|
+
if (existsSync33(path22) && options2.force !== true)
|
|
393964
394918
|
return { path: path22, created: false };
|
|
393965
|
-
|
|
394919
|
+
writeFileSync29(path22, `${JSON.stringify(defaultExecTargetConfig(options2.image), null, 2)}
|
|
393966
394920
|
`);
|
|
393967
394921
|
return { path: path22, created: true };
|
|
393968
394922
|
}
|
|
@@ -394089,12 +395043,12 @@ var init_devcontainer2 = __esm(() => {
|
|
|
394089
395043
|
|
|
394090
395044
|
// src/services/agents/arena.ts
|
|
394091
395045
|
import {
|
|
394092
|
-
existsSync as
|
|
394093
|
-
mkdirSync as
|
|
395046
|
+
existsSync as existsSync34,
|
|
395047
|
+
mkdirSync as mkdirSync32,
|
|
394094
395048
|
rmSync as rmSync7,
|
|
394095
|
-
writeFileSync as
|
|
395049
|
+
writeFileSync as writeFileSync30
|
|
394096
395050
|
} from "fs";
|
|
394097
|
-
import { join as
|
|
395051
|
+
import { join as join153 } from "path";
|
|
394098
395052
|
function countChangedLines(diff3) {
|
|
394099
395053
|
let count4 = 0;
|
|
394100
395054
|
for (const line of diff3.split(`
|
|
@@ -394164,16 +395118,16 @@ async function git4(cwd2, args) {
|
|
|
394164
395118
|
});
|
|
394165
395119
|
}
|
|
394166
395120
|
async function ensureWorktree2(cwd2, runId, id) {
|
|
394167
|
-
const root2 =
|
|
394168
|
-
const path22 =
|
|
395121
|
+
const root2 = join153(cwd2, ".ur", "arena", ".worktrees");
|
|
395122
|
+
const path22 = join153(root2, `${runId}-${id}`);
|
|
394169
395123
|
const branch = `ur/arena/${runId}/${id}`;
|
|
394170
|
-
if (
|
|
395124
|
+
if (existsSync34(path22))
|
|
394171
395125
|
return path22;
|
|
394172
|
-
|
|
395126
|
+
mkdirSync32(root2, { recursive: true });
|
|
394173
395127
|
const result = await git4(cwd2, ["worktree", "add", "-b", branch, path22]);
|
|
394174
395128
|
return result.code === 0 ? path22 : null;
|
|
394175
395129
|
}
|
|
394176
|
-
async function
|
|
395130
|
+
async function captureDiff3(worktree2) {
|
|
394177
395131
|
await git4(worktree2, ["add", "-A"]);
|
|
394178
395132
|
const diff3 = await git4(worktree2, ["diff", "--cached"]);
|
|
394179
395133
|
return diff3.code === 0 ? diff3.stdout : "";
|
|
@@ -394209,7 +395163,7 @@ Implement this fully and correctly. Make focused changes. End your reply with VE
|
|
|
394209
395163
|
maxTurns: options2.maxTurns,
|
|
394210
395164
|
skipPermissions: options2.skipPermissions
|
|
394211
395165
|
});
|
|
394212
|
-
const diff3 = worktree2 && !options2.dryRun ? await
|
|
395166
|
+
const diff3 = worktree2 && !options2.dryRun ? await captureDiff3(worktree2) : "";
|
|
394213
395167
|
options2.onEvent?.({ kind: "done", id, verdict: out.verdict ?? null, isError: !!out.isError });
|
|
394214
395168
|
return {
|
|
394215
395169
|
id,
|
|
@@ -394224,9 +395178,9 @@ Implement this fully and correctly. Make focused changes. End your reply with VE
|
|
|
394224
395178
|
const { ranked, winner } = judge(candidates2);
|
|
394225
395179
|
let applied = false;
|
|
394226
395180
|
if (options2.apply && winner && winner.diff.trim() && !options2.dryRun) {
|
|
394227
|
-
const patch =
|
|
394228
|
-
|
|
394229
|
-
|
|
395181
|
+
const patch = join153(cwd2, ".ur", "arena", `${runId}-winner.patch`);
|
|
395182
|
+
mkdirSync32(join153(cwd2, ".ur", "arena"), { recursive: true });
|
|
395183
|
+
writeFileSync30(patch, winner.diff);
|
|
394230
395184
|
const result = await git4(cwd2, ["apply", "--3way", patch]);
|
|
394231
395185
|
applied = result.code === 0;
|
|
394232
395186
|
if (applied)
|
|
@@ -394475,7 +395429,7 @@ var exports_ci_loop = {};
|
|
|
394475
395429
|
__export(exports_ci_loop, {
|
|
394476
395430
|
call: () => call77
|
|
394477
395431
|
});
|
|
394478
|
-
import { existsSync as
|
|
395432
|
+
import { existsSync as existsSync35, readFileSync as readFileSync42 } from "fs";
|
|
394479
395433
|
function option13(tokens, name) {
|
|
394480
395434
|
const index2 = tokens.indexOf(name);
|
|
394481
395435
|
return index2 === -1 ? undefined : tokens[index2 + 1];
|
|
@@ -394489,10 +395443,10 @@ var call77 = async (args) => {
|
|
|
394489
395443
|
const fromLog = option13(tokens, "--from-log");
|
|
394490
395444
|
let seedError;
|
|
394491
395445
|
if (fromLog) {
|
|
394492
|
-
if (!
|
|
395446
|
+
if (!existsSync35(fromLog)) {
|
|
394493
395447
|
return { type: "text", value: `Log file not found: ${fromLog}` };
|
|
394494
395448
|
}
|
|
394495
|
-
seedError =
|
|
395449
|
+
seedError = readFileSync42(fromLog, "utf-8");
|
|
394496
395450
|
}
|
|
394497
395451
|
const cwd2 = getCwd();
|
|
394498
395452
|
const target = resolveExecTarget(cwd2);
|
|
@@ -394533,11 +395487,11 @@ var init_ci_loop2 = __esm(() => {
|
|
|
394533
395487
|
});
|
|
394534
395488
|
|
|
394535
395489
|
// src/ur/projectDna.ts
|
|
394536
|
-
import { existsSync as
|
|
394537
|
-
import { join as
|
|
395490
|
+
import { existsSync as existsSync36, mkdirSync as mkdirSync33, readFileSync as readFileSync43, writeFileSync as writeFileSync31 } from "fs";
|
|
395491
|
+
import { join as join154 } from "path";
|
|
394538
395492
|
function readGitignoreDirs(cwd2) {
|
|
394539
395493
|
try {
|
|
394540
|
-
return
|
|
395494
|
+
return readFileSync43(join154(cwd2, ".gitignore"), "utf8").split(`
|
|
394541
395495
|
`).map((l) => l.trim()).filter((l) => l && !l.startsWith("#")).map((l) => l.replace(/^\//, "").replace(/\/$/, "")).filter((l) => l && !l.includes("*") && !l.includes(".")).slice(0, 12);
|
|
394542
395496
|
} catch {
|
|
394543
395497
|
return [];
|
|
@@ -394545,13 +395499,13 @@ function readGitignoreDirs(cwd2) {
|
|
|
394545
395499
|
}
|
|
394546
395500
|
function findReadme(cwd2) {
|
|
394547
395501
|
for (const n2 of ["README.md", "README.rst", "README.txt", "README"])
|
|
394548
|
-
if (
|
|
395502
|
+
if (existsSync36(join154(cwd2, n2)))
|
|
394549
395503
|
return n2;
|
|
394550
395504
|
return null;
|
|
394551
395505
|
}
|
|
394552
395506
|
function readJson(path22) {
|
|
394553
395507
|
try {
|
|
394554
|
-
return JSON.parse(
|
|
395508
|
+
return JSON.parse(readFileSync43(path22, "utf8"));
|
|
394555
395509
|
} catch {
|
|
394556
395510
|
return null;
|
|
394557
395511
|
}
|
|
@@ -394575,7 +395529,7 @@ function detectProjectDna(cwd2) {
|
|
|
394575
395529
|
packageManagers.add("npm");
|
|
394576
395530
|
if (packageManagers.size === 0)
|
|
394577
395531
|
packageManagers.add("npm");
|
|
394578
|
-
const pkg = readJson(
|
|
395532
|
+
const pkg = readJson(join154(cwd2, "package.json"));
|
|
394579
395533
|
const scripts = pkg?.scripts ?? {};
|
|
394580
395534
|
const pm = [...packageManagers][0] ?? "npm";
|
|
394581
395535
|
const run = (s) => pm === "npm" ? `npm run ${s}` : `${pm} run ${s}`;
|
|
@@ -394622,7 +395576,7 @@ function detectProjectDna(cwd2) {
|
|
|
394622
395576
|
runCommands.add("python main.py");
|
|
394623
395577
|
if (has(cwd2, "Makefile"))
|
|
394624
395578
|
buildCommands.add("make");
|
|
394625
|
-
const importantFolders = ["src", "lib", "tests", "test", "app", "packages"].filter((d) =>
|
|
395579
|
+
const importantFolders = ["src", "lib", "tests", "test", "app", "packages"].filter((d) => existsSync36(join154(cwd2, d)));
|
|
394626
395580
|
return {
|
|
394627
395581
|
languages: [...languages],
|
|
394628
395582
|
packageManagers: [...packageManagers],
|
|
@@ -394633,7 +395587,7 @@ function detectProjectDna(cwd2) {
|
|
|
394633
395587
|
importantFolders,
|
|
394634
395588
|
ignoredFolders: readGitignoreDirs(cwd2),
|
|
394635
395589
|
readme: findReadme(cwd2),
|
|
394636
|
-
hasGit:
|
|
395590
|
+
hasGit: existsSync36(join154(cwd2, ".git"))
|
|
394637
395591
|
};
|
|
394638
395592
|
}
|
|
394639
395593
|
function formatDna(dna) {
|
|
@@ -394656,23 +395610,23 @@ function formatDna(dna) {
|
|
|
394656
395610
|
function writeDna(cwd2) {
|
|
394657
395611
|
const md = formatDna(detectProjectDna(cwd2));
|
|
394658
395612
|
try {
|
|
394659
|
-
|
|
394660
|
-
|
|
395613
|
+
mkdirSync33(join154(cwd2, ".ur"), { recursive: true });
|
|
395614
|
+
writeFileSync31(join154(cwd2, ".ur", "project_dna.md"), md + `
|
|
394661
395615
|
`);
|
|
394662
395616
|
} catch {}
|
|
394663
395617
|
return md;
|
|
394664
395618
|
}
|
|
394665
|
-
var has = (cwd2, ...names) => names.some((n2) =>
|
|
395619
|
+
var has = (cwd2, ...names) => names.some((n2) => existsSync36(join154(cwd2, n2)));
|
|
394666
395620
|
var init_projectDna = () => {};
|
|
394667
395621
|
|
|
394668
395622
|
// src/services/agents/testFirstLoop.ts
|
|
394669
395623
|
import {
|
|
394670
|
-
existsSync as
|
|
394671
|
-
mkdirSync as
|
|
394672
|
-
readFileSync as
|
|
394673
|
-
writeFileSync as
|
|
395624
|
+
existsSync as existsSync37,
|
|
395625
|
+
mkdirSync as mkdirSync34,
|
|
395626
|
+
readFileSync as readFileSync44,
|
|
395627
|
+
writeFileSync as writeFileSync32
|
|
394674
395628
|
} from "fs";
|
|
394675
|
-
import { dirname as dirname57, join as
|
|
395629
|
+
import { dirname as dirname57, join as join155, relative as relative31 } from "path";
|
|
394676
395630
|
function uniqueCommands(commands) {
|
|
394677
395631
|
const seen = new Set;
|
|
394678
395632
|
const out = [];
|
|
@@ -394687,7 +395641,7 @@ function uniqueCommands(commands) {
|
|
|
394687
395641
|
}
|
|
394688
395642
|
function readPackageScripts(cwd2) {
|
|
394689
395643
|
try {
|
|
394690
|
-
const parsed = JSON.parse(
|
|
395644
|
+
const parsed = JSON.parse(readFileSync44(join155(cwd2, "package.json"), "utf8"));
|
|
394691
395645
|
if (!parsed.scripts || typeof parsed.scripts !== "object")
|
|
394692
395646
|
return {};
|
|
394693
395647
|
return parsed.scripts;
|
|
@@ -394726,7 +395680,7 @@ function detectTestFirstStack(cwd2) {
|
|
|
394726
395680
|
for (const command5 of dna.lintCommands) {
|
|
394727
395681
|
commands.push({ phase: "lint", command: command5, source: "project-dna lint" });
|
|
394728
395682
|
}
|
|
394729
|
-
if (
|
|
395683
|
+
if (existsSync37(join155(cwd2, "package.json"))) {
|
|
394730
395684
|
const scripts = readPackageScripts(cwd2);
|
|
394731
395685
|
const pm = primaryNodePackageManager(dna.packageManagers);
|
|
394732
395686
|
if (!commands.some((command5) => command5.phase === "compile")) {
|
|
@@ -394736,7 +395690,7 @@ function detectTestFirstStack(cwd2) {
|
|
|
394736
395690
|
command: runScript(pm, "typecheck"),
|
|
394737
395691
|
source: "package.json script:typecheck"
|
|
394738
395692
|
});
|
|
394739
|
-
} else if (
|
|
395693
|
+
} else if (existsSync37(join155(cwd2, "tsconfig.json"))) {
|
|
394740
395694
|
commands.push({
|
|
394741
395695
|
phase: "compile",
|
|
394742
395696
|
command: tscCommand(pm),
|
|
@@ -394778,15 +395732,15 @@ function detectTestFirstStack(cwd2) {
|
|
|
394778
395732
|
};
|
|
394779
395733
|
}
|
|
394780
395734
|
function defaultTraceDir(cwd2) {
|
|
394781
|
-
return
|
|
395735
|
+
return join155(cwd2, ".ur", "test-first", "traces");
|
|
394782
395736
|
}
|
|
394783
395737
|
function slug3(value) {
|
|
394784
395738
|
return value.toLowerCase().replace(/[^a-z0-9]+/g, "-").replace(/^-|-$/g, "").slice(0, 72) || "command";
|
|
394785
395739
|
}
|
|
394786
395740
|
function writeFailureTrace(cwd2, traceDir, run, result, now6) {
|
|
394787
|
-
|
|
395741
|
+
mkdirSync34(traceDir, { recursive: true });
|
|
394788
395742
|
const stamp = now6.toISOString().replace(/[:.]/g, "-");
|
|
394789
|
-
const file2 =
|
|
395743
|
+
const file2 = join155(traceDir, `${stamp}-attempt-${run.attempt}-${run.phase}-${slug3(run.command)}.log`);
|
|
394790
395744
|
const body = [
|
|
394791
395745
|
"# UR test-first failure trace",
|
|
394792
395746
|
"",
|
|
@@ -394805,12 +395759,12 @@ function writeFailureTrace(cwd2, traceDir, run, result, now6) {
|
|
|
394805
395759
|
""
|
|
394806
395760
|
].join(`
|
|
394807
395761
|
`);
|
|
394808
|
-
|
|
395762
|
+
writeFileSync32(file2, body);
|
|
394809
395763
|
return relative31(cwd2, file2);
|
|
394810
395764
|
}
|
|
394811
395765
|
function readExistingVerifyConfig(path22) {
|
|
394812
395766
|
try {
|
|
394813
|
-
const parsed = JSON.parse(
|
|
395767
|
+
const parsed = JSON.parse(readFileSync44(path22, "utf8"));
|
|
394814
395768
|
return parsed && typeof parsed === "object" ? parsed : {};
|
|
394815
395769
|
} catch {
|
|
394816
395770
|
return {};
|
|
@@ -394828,8 +395782,8 @@ function mergeStringArray(existing, additions) {
|
|
|
394828
395782
|
return [...out];
|
|
394829
395783
|
}
|
|
394830
395784
|
function installTestFirstGates(cwd2, stack = detectTestFirstStack(cwd2)) {
|
|
394831
|
-
const path22 =
|
|
394832
|
-
|
|
395785
|
+
const path22 = join155(cwd2, ".ur", "verify.json");
|
|
395786
|
+
mkdirSync34(dirname57(path22), { recursive: true });
|
|
394833
395787
|
const commands = stack.commands.map((command5) => command5.command);
|
|
394834
395788
|
const existing = readExistingVerifyConfig(path22);
|
|
394835
395789
|
const next = {
|
|
@@ -394837,7 +395791,7 @@ function installTestFirstGates(cwd2, stack = detectTestFirstStack(cwd2)) {
|
|
|
394837
395791
|
afterEdit: mergeStringArray(existing.afterEdit, commands),
|
|
394838
395792
|
timeoutMs: typeof existing.timeoutMs === "number" && existing.timeoutMs > 0 ? existing.timeoutMs : 600000
|
|
394839
395793
|
};
|
|
394840
|
-
|
|
395794
|
+
writeFileSync32(path22, `${JSON.stringify(next, null, 2)}
|
|
394841
395795
|
`);
|
|
394842
395796
|
return { path: relative31(cwd2, path22), commands };
|
|
394843
395797
|
}
|
|
@@ -395183,36 +396137,36 @@ var init_safety2 = __esm(() => {
|
|
|
395183
396137
|
|
|
395184
396138
|
// src/services/context/projectContextManifest.ts
|
|
395185
396139
|
import {
|
|
395186
|
-
existsSync as
|
|
395187
|
-
mkdirSync as
|
|
395188
|
-
readFileSync as
|
|
396140
|
+
existsSync as existsSync38,
|
|
396141
|
+
mkdirSync as mkdirSync35,
|
|
396142
|
+
readFileSync as readFileSync45,
|
|
395189
396143
|
readdirSync as readdirSync14,
|
|
395190
|
-
writeFileSync as
|
|
396144
|
+
writeFileSync as writeFileSync33
|
|
395191
396145
|
} from "fs";
|
|
395192
|
-
import { dirname as dirname58, join as
|
|
396146
|
+
import { dirname as dirname58, join as join156, relative as relative32 } from "path";
|
|
395193
396147
|
function contextDir(cwd2) {
|
|
395194
|
-
return
|
|
396148
|
+
return join156(cwd2, ".ur", "context");
|
|
395195
396149
|
}
|
|
395196
396150
|
function projectManifestPath(cwd2) {
|
|
395197
|
-
return
|
|
396151
|
+
return join156(cwd2, ".ur", "project-manifest.json");
|
|
395198
396152
|
}
|
|
395199
396153
|
function taskMemoryPath(cwd2) {
|
|
395200
|
-
return
|
|
396154
|
+
return join156(contextDir(cwd2), "task-memory.jsonl");
|
|
395201
396155
|
}
|
|
395202
396156
|
function compressedContextPath(cwd2) {
|
|
395203
|
-
return
|
|
396157
|
+
return join156(contextDir(cwd2), "compressed.md");
|
|
395204
396158
|
}
|
|
395205
396159
|
function architectureSummaryPath(cwd2) {
|
|
395206
|
-
return
|
|
396160
|
+
return join156(contextDir(cwd2), "architecture.md");
|
|
395207
396161
|
}
|
|
395208
396162
|
function readPackage(cwd2) {
|
|
395209
|
-
const path22 =
|
|
395210
|
-
if (!
|
|
396163
|
+
const path22 = join156(cwd2, "package.json");
|
|
396164
|
+
if (!existsSync38(path22))
|
|
395211
396165
|
return null;
|
|
395212
|
-
return safeParseJSON(
|
|
396166
|
+
return safeParseJSON(readFileSync45(path22, "utf8"), false);
|
|
395213
396167
|
}
|
|
395214
396168
|
function existing(cwd2, names) {
|
|
395215
|
-
return names.filter((name) =>
|
|
396169
|
+
return names.filter((name) => existsSync38(join156(cwd2, name)));
|
|
395216
396170
|
}
|
|
395217
396171
|
function packageScripts(pkg, matcher) {
|
|
395218
396172
|
const scripts = pkg?.scripts;
|
|
@@ -395261,19 +396215,19 @@ function buildProjectContextManifest(cwd2) {
|
|
|
395261
396215
|
"Keep generated runtime state under .ur/ unless a command documents another path."
|
|
395262
396216
|
],
|
|
395263
396217
|
constraints: [
|
|
395264
|
-
|
|
395265
|
-
|
|
396218
|
+
existsSync38(safetyPolicyPath(cwd2)) ? "Project safety policy is configured." : "Default safety policy applies until .ur/safety-policy.json is written.",
|
|
396219
|
+
existsSync38(join156(cwd2, ".ur", "verify.json")) ? "Project verify gates are configured." : "No project verify gate file detected.",
|
|
395266
396220
|
"Do not expose secret-like files or environment values in command output."
|
|
395267
396221
|
]
|
|
395268
396222
|
};
|
|
395269
396223
|
}
|
|
395270
396224
|
function writeProjectContextManifest(cwd2) {
|
|
395271
396225
|
const manifest = buildProjectContextManifest(cwd2);
|
|
395272
|
-
|
|
395273
|
-
|
|
396226
|
+
mkdirSync35(dirname58(projectManifestPath(cwd2)), { recursive: true });
|
|
396227
|
+
writeFileSync33(projectManifestPath(cwd2), `${JSON.stringify(manifest, null, 2)}
|
|
395274
396228
|
`);
|
|
395275
|
-
|
|
395276
|
-
|
|
396229
|
+
mkdirSync35(contextDir(cwd2), { recursive: true });
|
|
396230
|
+
writeFileSync33(architectureSummaryPath(cwd2), formatArchitectureSummary(manifest, cwd2));
|
|
395277
396231
|
return manifest;
|
|
395278
396232
|
}
|
|
395279
396233
|
function formatArchitectureSummary(manifest, cwd2) {
|
|
@@ -395287,7 +396241,7 @@ function formatArchitectureSummary(manifest, cwd2) {
|
|
|
395287
396241
|
importantFolders: manifest.project.importantFolders,
|
|
395288
396242
|
ignoredFolders: [],
|
|
395289
396243
|
readme: manifest.project.readme,
|
|
395290
|
-
hasGit:
|
|
396244
|
+
hasGit: existsSync38(join156(cwd2, ".git"))
|
|
395291
396245
|
});
|
|
395292
396246
|
return [
|
|
395293
396247
|
"# Project Architecture Context",
|
|
@@ -395316,16 +396270,16 @@ function appendTaskMemory(cwd2, kind, text) {
|
|
|
395316
396270
|
kind,
|
|
395317
396271
|
text
|
|
395318
396272
|
};
|
|
395319
|
-
|
|
395320
|
-
|
|
396273
|
+
mkdirSync35(dirname58(taskMemoryPath(cwd2)), { recursive: true });
|
|
396274
|
+
writeFileSync33(taskMemoryPath(cwd2), `${JSON.stringify(entry)}
|
|
395321
396275
|
`, { flag: "a" });
|
|
395322
396276
|
return entry;
|
|
395323
396277
|
}
|
|
395324
396278
|
function readTaskMemory(cwd2) {
|
|
395325
396279
|
const path22 = taskMemoryPath(cwd2);
|
|
395326
|
-
if (!
|
|
396280
|
+
if (!existsSync38(path22))
|
|
395327
396281
|
return [];
|
|
395328
|
-
return
|
|
396282
|
+
return readFileSync45(path22, "utf8").split(`
|
|
395329
396283
|
`).filter(Boolean).map((line) => safeParseJSON(line, false)).filter((entry) => Boolean(entry && typeof entry === "object" && typeof entry.kind === "string" && typeof entry.text === "string"));
|
|
395330
396284
|
}
|
|
395331
396285
|
function compressTaskMemory(cwd2) {
|
|
@@ -395354,8 +396308,8 @@ function compressTaskMemory(cwd2) {
|
|
|
395354
396308
|
const body = `${lines.join(`
|
|
395355
396309
|
`)}
|
|
395356
396310
|
`;
|
|
395357
|
-
|
|
395358
|
-
|
|
396311
|
+
mkdirSync35(dirname58(compressedContextPath(cwd2)), { recursive: true });
|
|
396312
|
+
writeFileSync33(compressedContextPath(cwd2), body);
|
|
395359
396313
|
return body;
|
|
395360
396314
|
}
|
|
395361
396315
|
function contextStatus(cwd2) {
|
|
@@ -395365,10 +396319,10 @@ function contextStatus(cwd2) {
|
|
|
395365
396319
|
taskMemoryPath(cwd2),
|
|
395366
396320
|
compressedContextPath(cwd2)
|
|
395367
396321
|
];
|
|
395368
|
-
const contextFiles =
|
|
396322
|
+
const contextFiles = existsSync38(contextDir(cwd2)) ? readdirSync14(contextDir(cwd2)) : [];
|
|
395369
396323
|
return [
|
|
395370
396324
|
"Project context status:",
|
|
395371
|
-
...files.map((path22) => ` ${
|
|
396325
|
+
...files.map((path22) => ` ${existsSync38(path22) ? "yes" : "no "} ${relative32(cwd2, path22)}`),
|
|
395372
396326
|
` context files: ${contextFiles.length}`
|
|
395373
396327
|
].join(`
|
|
395374
396328
|
`);
|
|
@@ -395580,7 +396534,7 @@ var KINDS, call81 = async (args) => {
|
|
|
395580
396534
|
};
|
|
395581
396535
|
}
|
|
395582
396536
|
if (action3 === "capture-diff") {
|
|
395583
|
-
const artifact = await
|
|
396537
|
+
const artifact = await captureDiff2(cwd2, option17(tokens, "--title") ?? "Working tree diff");
|
|
395584
396538
|
return {
|
|
395585
396539
|
type: "text",
|
|
395586
396540
|
value: artifact ? json2 ? JSON.stringify(artifact, null, 2) : `Captured diff as artifact ${artifact.id} (${artifact.summary}).` : "No working-tree changes to capture."
|
|
@@ -395797,7 +396751,7 @@ var exports_trigger = {};
|
|
|
395797
396751
|
__export(exports_trigger, {
|
|
395798
396752
|
call: () => call82
|
|
395799
396753
|
});
|
|
395800
|
-
import { existsSync as
|
|
396754
|
+
import { existsSync as existsSync39, readFileSync as readFileSync46 } from "fs";
|
|
395801
396755
|
function option18(tokens, name) {
|
|
395802
396756
|
const index2 = tokens.indexOf(name);
|
|
395803
396757
|
if (index2 === -1)
|
|
@@ -395833,10 +396787,10 @@ var call82 = async (args) => {
|
|
|
395833
396787
|
|
|
395834
396788
|
${usage17()}` };
|
|
395835
396789
|
}
|
|
395836
|
-
if (!
|
|
396790
|
+
if (!existsSync39(file2)) {
|
|
395837
396791
|
return { type: "text", value: `Payload file not found: ${file2}` };
|
|
395838
396792
|
}
|
|
395839
|
-
const payload = safeParseJSON(
|
|
396793
|
+
const payload = safeParseJSON(readFileSync46(file2, "utf-8"), false);
|
|
395840
396794
|
if (payload === null || typeof payload !== "object") {
|
|
395841
396795
|
return { type: "text", value: `Payload is not valid JSON: ${file2}` };
|
|
395842
396796
|
}
|
|
@@ -395895,8 +396849,8 @@ var exports_sdk = {};
|
|
|
395895
396849
|
__export(exports_sdk, {
|
|
395896
396850
|
call: () => call83
|
|
395897
396851
|
});
|
|
395898
|
-
import { existsSync as
|
|
395899
|
-
import { join as
|
|
396852
|
+
import { existsSync as existsSync40, mkdirSync as mkdirSync36, writeFileSync as writeFileSync34 } from "fs";
|
|
396853
|
+
import { join as join157 } from "path";
|
|
395900
396854
|
function infoText() {
|
|
395901
396855
|
return [
|
|
395902
396856
|
"UR SDK \u2014 drive UR programmatically (headless).",
|
|
@@ -395976,8 +396930,8 @@ A2A server: \`ur a2a serve\`.
|
|
|
395976
396930
|
const force = tokens.includes("--force");
|
|
395977
396931
|
const action3 = tokens.find((token) => !token.startsWith("--")) ?? "info";
|
|
395978
396932
|
if (action3 === "init") {
|
|
395979
|
-
const root2 =
|
|
395980
|
-
|
|
396933
|
+
const root2 = join157(getCwd(), ".ur", "sdk");
|
|
396934
|
+
mkdirSync36(root2, { recursive: true });
|
|
395981
396935
|
const files = [
|
|
395982
396936
|
["example.ts", TS_EXAMPLE],
|
|
395983
396937
|
["example.py", PY_EXAMPLE],
|
|
@@ -395986,12 +396940,12 @@ A2A server: \`ur a2a serve\`.
|
|
|
395986
396940
|
const created = [];
|
|
395987
396941
|
const skipped = [];
|
|
395988
396942
|
for (const [name, content] of files) {
|
|
395989
|
-
const path22 =
|
|
395990
|
-
if (!force &&
|
|
396943
|
+
const path22 = join157(root2, name);
|
|
396944
|
+
if (!force && existsSync40(path22)) {
|
|
395991
396945
|
skipped.push(name);
|
|
395992
396946
|
continue;
|
|
395993
396947
|
}
|
|
395994
|
-
|
|
396948
|
+
writeFileSync34(path22, content);
|
|
395995
396949
|
created.push(name);
|
|
395996
396950
|
}
|
|
395997
396951
|
return {
|
|
@@ -396060,14 +397014,14 @@ __export(exports_evals, {
|
|
|
396060
397014
|
BENCHMARK_ADAPTERS: () => BENCHMARK_ADAPTERS
|
|
396061
397015
|
});
|
|
396062
397016
|
import {
|
|
396063
|
-
existsSync as
|
|
396064
|
-
mkdirSync as
|
|
396065
|
-
readFileSync as
|
|
397017
|
+
existsSync as existsSync41,
|
|
397018
|
+
mkdirSync as mkdirSync37,
|
|
397019
|
+
readFileSync as readFileSync47,
|
|
396066
397020
|
readdirSync as readdirSync15,
|
|
396067
397021
|
rmSync as rmSync8,
|
|
396068
|
-
writeFileSync as
|
|
397022
|
+
writeFileSync as writeFileSync35
|
|
396069
397023
|
} from "fs";
|
|
396070
|
-
import { join as
|
|
397024
|
+
import { join as join158 } from "path";
|
|
396071
397025
|
function hasAnyExpectation(expect) {
|
|
396072
397026
|
return Boolean(expect.contains?.length || expect.notContains?.length || expect.regex?.length || expect.verdict || typeof expect.maxOutputChars === "number");
|
|
396073
397027
|
}
|
|
@@ -396322,13 +397276,13 @@ async function runSuiteReliability(suite, runner2, options2) {
|
|
|
396322
397276
|
};
|
|
396323
397277
|
}
|
|
396324
397278
|
function metricsFile() {
|
|
396325
|
-
return
|
|
397279
|
+
return join158(process.env.UR_EVAL_METRICS_DIR ?? process.cwd(), `.ur-eval-metrics-${process.pid}.json`);
|
|
396326
397280
|
}
|
|
396327
397281
|
function readChildMetricsFile(path22) {
|
|
396328
|
-
if (!
|
|
397282
|
+
if (!existsSync41(path22))
|
|
396329
397283
|
return;
|
|
396330
397284
|
try {
|
|
396331
|
-
const parsed = safeParseJSON(
|
|
397285
|
+
const parsed = safeParseJSON(readFileSync47(path22, "utf-8"), false);
|
|
396332
397286
|
if (parsed && typeof parsed === "object")
|
|
396333
397287
|
return parsed;
|
|
396334
397288
|
} catch {}
|
|
@@ -396379,7 +397333,7 @@ async function runTestCommand(cwd2, command5) {
|
|
|
396379
397333
|
testStderr: result.stderr || result.error || ""
|
|
396380
397334
|
};
|
|
396381
397335
|
}
|
|
396382
|
-
function
|
|
397336
|
+
function countCommandFailures2(output) {
|
|
396383
397337
|
const markers = ["[ERROR]", "Command failed", "exit code 1", "Error:", "FAILED"];
|
|
396384
397338
|
let count4 = 0;
|
|
396385
397339
|
const lower = output.toLowerCase();
|
|
@@ -396453,7 +397407,7 @@ function makeCliEvalRunner(options2) {
|
|
|
396453
397407
|
testCommand: testResult?.testCommand,
|
|
396454
397408
|
testStdout: testResult?.testStdout,
|
|
396455
397409
|
testStderr: testResult?.testStderr,
|
|
396456
|
-
commandFailures:
|
|
397410
|
+
commandFailures: countCommandFailures2(output),
|
|
396457
397411
|
humanEditsNeeded: countHumanEdits(output)
|
|
396458
397412
|
};
|
|
396459
397413
|
return { output, isError: result.code !== 0, metrics };
|
|
@@ -396563,13 +397517,13 @@ ${body}</body></html>
|
|
|
396563
397517
|
}
|
|
396564
397518
|
function loadAllReports(cwd2) {
|
|
396565
397519
|
const dir = resultsDir(cwd2);
|
|
396566
|
-
if (!
|
|
397520
|
+
if (!existsSync41(dir))
|
|
396567
397521
|
return [];
|
|
396568
397522
|
const reports = [];
|
|
396569
397523
|
for (const file2 of readdirSync15(dir)) {
|
|
396570
397524
|
if (!file2.endsWith(".json") || file2.startsWith("reliability-"))
|
|
396571
397525
|
continue;
|
|
396572
|
-
const parsed = safeParseJSON(
|
|
397526
|
+
const parsed = safeParseJSON(readFileSync47(join158(dir, file2), "utf-8"), false);
|
|
396573
397527
|
if (parsed && typeof parsed === "object")
|
|
396574
397528
|
reports.push(parsed);
|
|
396575
397529
|
}
|
|
@@ -396577,48 +397531,48 @@ function loadAllReports(cwd2) {
|
|
|
396577
397531
|
}
|
|
396578
397532
|
function loadAllReliability(cwd2) {
|
|
396579
397533
|
const dir = resultsDir(cwd2);
|
|
396580
|
-
if (!
|
|
397534
|
+
if (!existsSync41(dir))
|
|
396581
397535
|
return [];
|
|
396582
397536
|
const reports = [];
|
|
396583
397537
|
for (const file2 of readdirSync15(dir)) {
|
|
396584
397538
|
if (!file2.startsWith("reliability-") || !file2.endsWith(".json"))
|
|
396585
397539
|
continue;
|
|
396586
|
-
const parsed = safeParseJSON(
|
|
397540
|
+
const parsed = safeParseJSON(readFileSync47(join158(dir, file2), "utf-8"), false);
|
|
396587
397541
|
if (parsed && typeof parsed === "object")
|
|
396588
397542
|
reports.push(parsed);
|
|
396589
397543
|
}
|
|
396590
397544
|
return reports.sort((a2, b) => a2.name.localeCompare(b.name));
|
|
396591
397545
|
}
|
|
396592
397546
|
function saveReliabilityReport(cwd2, report) {
|
|
396593
|
-
|
|
396594
|
-
const path22 =
|
|
396595
|
-
|
|
397547
|
+
mkdirSync37(resultsDir(cwd2), { recursive: true });
|
|
397548
|
+
const path22 = join158(resultsDir(cwd2), `reliability-${suiteSlug(report.name)}.json`);
|
|
397549
|
+
writeFileSync35(path22, `${JSON.stringify(report, null, 2)}
|
|
396596
397550
|
`);
|
|
396597
397551
|
return path22;
|
|
396598
397552
|
}
|
|
396599
397553
|
function writeDashboard(cwd2) {
|
|
396600
397554
|
const html3 = buildDashboardHtml(loadAllReports(cwd2), loadAllReliability(cwd2));
|
|
396601
|
-
|
|
396602
|
-
const path22 =
|
|
396603
|
-
|
|
397555
|
+
mkdirSync37(evalsDir(cwd2), { recursive: true });
|
|
397556
|
+
const path22 = join158(evalsDir(cwd2), "dashboard.html");
|
|
397557
|
+
writeFileSync35(path22, html3);
|
|
396604
397558
|
return path22;
|
|
396605
397559
|
}
|
|
396606
397560
|
function runsDir(cwd2, suiteName) {
|
|
396607
|
-
return
|
|
397561
|
+
return join158(evalsDir(cwd2), ".runs", suiteSlug(suiteName));
|
|
396608
397562
|
}
|
|
396609
397563
|
function writeRunMetrics(cwd2, suiteName, caseId, metrics) {
|
|
396610
397564
|
const dir = runsDir(cwd2, suiteName);
|
|
396611
|
-
|
|
396612
|
-
const path22 =
|
|
396613
|
-
|
|
397565
|
+
mkdirSync37(dir, { recursive: true });
|
|
397566
|
+
const path22 = join158(dir, `${caseId}.json`);
|
|
397567
|
+
writeFileSync35(path22, `${JSON.stringify(metrics, null, 2)}
|
|
396614
397568
|
`);
|
|
396615
397569
|
return path22;
|
|
396616
397570
|
}
|
|
396617
397571
|
function loadRunMetrics(cwd2, suiteName, caseId) {
|
|
396618
|
-
const path22 =
|
|
396619
|
-
if (!
|
|
397572
|
+
const path22 = join158(runsDir(cwd2, suiteName), `${caseId}.json`);
|
|
397573
|
+
if (!existsSync41(path22))
|
|
396620
397574
|
return null;
|
|
396621
|
-
const parsed = safeParseJSON(
|
|
397575
|
+
const parsed = safeParseJSON(readFileSync47(path22, "utf-8"), false);
|
|
396622
397576
|
if (!parsed || typeof parsed !== "object")
|
|
396623
397577
|
return null;
|
|
396624
397578
|
return parsed;
|
|
@@ -396640,10 +397594,10 @@ function formatReliabilityReport(report, json2) {
|
|
|
396640
397594
|
`);
|
|
396641
397595
|
}
|
|
396642
397596
|
function evalsDir(cwd2) {
|
|
396643
|
-
return
|
|
397597
|
+
return join158(cwd2, ".ur", "evals");
|
|
396644
397598
|
}
|
|
396645
397599
|
function resultsDir(cwd2) {
|
|
396646
|
-
return
|
|
397600
|
+
return join158(evalsDir(cwd2), ".results");
|
|
396647
397601
|
}
|
|
396648
397602
|
function suiteSlug(name) {
|
|
396649
397603
|
return name.trim().toLowerCase().replace(/[^a-z0-9-_]+/g, "-").slice(0, 64);
|
|
@@ -396674,27 +397628,27 @@ function parseSuiteText(text) {
|
|
|
396674
397628
|
}
|
|
396675
397629
|
function listSuites(cwd2) {
|
|
396676
397630
|
const dir = evalsDir(cwd2);
|
|
396677
|
-
if (!
|
|
397631
|
+
if (!existsSync41(dir))
|
|
396678
397632
|
return [];
|
|
396679
397633
|
return readdirSync15(dir).filter((file2) => file2.endsWith(".json")).map((file2) => file2.replace(/\.json$/, "")).sort();
|
|
396680
397634
|
}
|
|
396681
397635
|
function loadSuite(cwd2, name) {
|
|
396682
|
-
const path22 =
|
|
396683
|
-
if (!
|
|
397636
|
+
const path22 = join158(evalsDir(cwd2), `${suiteSlug(name)}.json`);
|
|
397637
|
+
if (!existsSync41(path22))
|
|
396684
397638
|
return null;
|
|
396685
397639
|
try {
|
|
396686
|
-
return parseSuiteText(
|
|
397640
|
+
return parseSuiteText(readFileSync47(path22, "utf-8"));
|
|
396687
397641
|
} catch {
|
|
396688
397642
|
return null;
|
|
396689
397643
|
}
|
|
396690
397644
|
}
|
|
396691
397645
|
function saveSuite(cwd2, suite, options2 = {}) {
|
|
396692
|
-
const path22 =
|
|
396693
|
-
|
|
396694
|
-
if (
|
|
397646
|
+
const path22 = join158(evalsDir(cwd2), `${suiteSlug(suite.name)}.json`);
|
|
397647
|
+
mkdirSync37(evalsDir(cwd2), { recursive: true });
|
|
397648
|
+
if (existsSync41(path22) && options2.force !== true) {
|
|
396695
397649
|
return { path: path22, created: false };
|
|
396696
397650
|
}
|
|
396697
|
-
|
|
397651
|
+
writeFileSync35(path22, `${JSON.stringify(suite, null, 2)}
|
|
396698
397652
|
`);
|
|
396699
397653
|
return { path: path22, created: true };
|
|
396700
397654
|
}
|
|
@@ -396841,7 +397795,7 @@ function buildBenchmarkSuite(adapter2, records, options2 = {}) {
|
|
|
396841
397795
|
};
|
|
396842
397796
|
}
|
|
396843
397797
|
function importBenchmarkSuite(cwd2, adapter2, file2, options2 = {}) {
|
|
396844
|
-
const records = parseBenchmarkRecords(
|
|
397798
|
+
const records = parseBenchmarkRecords(readFileSync47(file2, "utf-8"));
|
|
396845
397799
|
if (records.length === 0) {
|
|
396846
397800
|
throw new Error(`No benchmark records found in ${file2}`);
|
|
396847
397801
|
}
|
|
@@ -396850,17 +397804,17 @@ function importBenchmarkSuite(cwd2, adapter2, file2, options2 = {}) {
|
|
|
396850
397804
|
return { suite, path: saved.path, created: saved.created, records: records.length };
|
|
396851
397805
|
}
|
|
396852
397806
|
function saveReport(cwd2, report) {
|
|
396853
|
-
|
|
396854
|
-
const path22 =
|
|
396855
|
-
|
|
397807
|
+
mkdirSync37(resultsDir(cwd2), { recursive: true });
|
|
397808
|
+
const path22 = join158(resultsDir(cwd2), `${suiteSlug(report.name)}.json`);
|
|
397809
|
+
writeFileSync35(path22, `${JSON.stringify(report, null, 2)}
|
|
396856
397810
|
`);
|
|
396857
397811
|
return path22;
|
|
396858
397812
|
}
|
|
396859
397813
|
function loadReport(cwd2, name) {
|
|
396860
|
-
const path22 =
|
|
396861
|
-
if (!
|
|
397814
|
+
const path22 = join158(resultsDir(cwd2), `${suiteSlug(name)}.json`);
|
|
397815
|
+
if (!existsSync41(path22))
|
|
396862
397816
|
return null;
|
|
396863
|
-
const parsed = safeParseJSON(
|
|
397817
|
+
const parsed = safeParseJSON(readFileSync47(path22, "utf-8"), false);
|
|
396864
397818
|
return parsed && typeof parsed === "object" ? parsed : null;
|
|
396865
397819
|
}
|
|
396866
397820
|
function defaultEvalSuite() {
|
|
@@ -396911,12 +397865,12 @@ function defaultEvalSuite() {
|
|
|
396911
397865
|
function scaffoldEvals(cwd2, options2 = {}) {
|
|
396912
397866
|
const root2 = evalsDir(cwd2);
|
|
396913
397867
|
const result = { root: root2, created: [], skipped: [] };
|
|
396914
|
-
|
|
396915
|
-
const readmePath =
|
|
396916
|
-
if (
|
|
397868
|
+
mkdirSync37(root2, { recursive: true });
|
|
397869
|
+
const readmePath = join158(root2, "README.md");
|
|
397870
|
+
if (existsSync41(readmePath) && options2.force !== true) {
|
|
396917
397871
|
result.skipped.push("evals/README.md");
|
|
396918
397872
|
} else {
|
|
396919
|
-
|
|
397873
|
+
writeFileSync35(readmePath, EVALS_README);
|
|
396920
397874
|
result.created.push("evals/README.md");
|
|
396921
397875
|
}
|
|
396922
397876
|
const saved = saveSuite(cwd2, defaultEvalSuite(), { force: options2.force });
|
|
@@ -397038,8 +397992,8 @@ var exports_eval = {};
|
|
|
397038
397992
|
__export(exports_eval, {
|
|
397039
397993
|
call: () => call84
|
|
397040
397994
|
});
|
|
397041
|
-
import { mkdirSync as
|
|
397042
|
-
import { join as
|
|
397995
|
+
import { mkdirSync as mkdirSync38, writeFileSync as writeFileSync36 } from "fs";
|
|
397996
|
+
import { join as join159 } from "path";
|
|
397043
397997
|
function optionValue6(tokens, flag) {
|
|
397044
397998
|
const index2 = tokens.indexOf(flag);
|
|
397045
397999
|
return index2 >= 0 ? tokens[index2 + 1] : undefined;
|
|
@@ -397116,10 +398070,10 @@ Open it in a browser (local-first, no network).`
|
|
|
397116
398070
|
if (tokens.includes("--dashboard")) {
|
|
397117
398071
|
const { buildDashboardHtml: buildDashboardHtml2 } = await Promise.resolve().then(() => (init_evals(), exports_evals));
|
|
397118
398072
|
const html3 = buildDashboardHtml2([report], []);
|
|
397119
|
-
const dir =
|
|
397120
|
-
|
|
397121
|
-
const path22 =
|
|
397122
|
-
|
|
398073
|
+
const dir = join159(evalsDir(cwd2), ".dashboards");
|
|
398074
|
+
mkdirSync38(dir, { recursive: true });
|
|
398075
|
+
const path22 = join159(dir, `${suiteSlug(report.name)}.html`);
|
|
398076
|
+
writeFileSync36(path22, html3);
|
|
397123
398077
|
return { type: "text", value: `Wrote single-suite dashboard to ${path22}` };
|
|
397124
398078
|
}
|
|
397125
398079
|
return { type: "text", value: formatEvalReport(report, json2) };
|
|
@@ -397284,9 +398238,9 @@ var init_dna2 = __esm(() => {
|
|
|
397284
398238
|
|
|
397285
398239
|
// src/ur/sysinfo.ts
|
|
397286
398240
|
import { spawnSync as spawnSync4 } from "child_process";
|
|
397287
|
-
import { existsSync as
|
|
398241
|
+
import { existsSync as existsSync42, readdirSync as readdirSync16 } from "fs";
|
|
397288
398242
|
import { arch, homedir as homedir30, platform as platform5, release as release2 } from "os";
|
|
397289
|
-
import { join as
|
|
398243
|
+
import { join as join160 } from "path";
|
|
397290
398244
|
function commandExists(bin) {
|
|
397291
398245
|
try {
|
|
397292
398246
|
const cmd = process.platform === "win32" ? "where" : "which";
|
|
@@ -397321,7 +398275,7 @@ function workspaceInfo(cwd2) {
|
|
|
397321
398275
|
try {
|
|
397322
398276
|
fileCount = readdirSync16(cwd2).length;
|
|
397323
398277
|
} catch {}
|
|
397324
|
-
const git5 =
|
|
398278
|
+
const git5 = existsSync42(join160(cwd2, ".git")) ? "yes" : "no";
|
|
397325
398279
|
const dna2 = formatDna(detectProjectDna(cwd2));
|
|
397326
398280
|
return [`workspace: ${cwd2}`, `entries: ${fileCount}`, `git: ${git5}`, "", dna2].join(`
|
|
397327
398281
|
`);
|
|
@@ -397349,16 +398303,16 @@ async function urDoctor(cwd2) {
|
|
|
397349
398303
|
lines.push(` tip: no coder model found \u2014 consider: ollama pull ${pull}`);
|
|
397350
398304
|
}
|
|
397351
398305
|
}
|
|
397352
|
-
const urDir =
|
|
397353
|
-
if (
|
|
397354
|
-
const have = ["actions.jsonl", "project_dna.md", "mode", "graph", "tools", "research", "memory", "index"].filter((n2) =>
|
|
398306
|
+
const urDir = join160(cwd2, ".ur");
|
|
398307
|
+
if (existsSync42(urDir)) {
|
|
398308
|
+
const have = ["actions.jsonl", "project_dna.md", "mode", "graph", "tools", "research", "memory", "index"].filter((n2) => existsSync42(join160(urDir, n2)));
|
|
397355
398309
|
lines.push(`.ur: present \u2014 ${have.join(", ") || "(empty)"}`);
|
|
397356
398310
|
} else {
|
|
397357
398311
|
lines.push(".ur: missing (run /ur-init)");
|
|
397358
398312
|
}
|
|
397359
|
-
const mcp2 = [
|
|
398313
|
+
const mcp2 = [join160(cwd2, ".ur", "mcp", "servers.toml"), join160(homedir30(), ".ur", "mcp", "servers.toml")].filter(existsSync42);
|
|
397360
398314
|
lines.push(`mcp cfg: ${mcp2.length ? mcp2.join(", ") : "none (.ur/mcp/servers.toml)"}`);
|
|
397361
|
-
lines.push(`playwright: ${
|
|
398315
|
+
lines.push(`playwright: ${existsSync42(join160(cwd2, "node_modules", "playwright")) ? "installed" : "not installed"}`);
|
|
397362
398316
|
return lines.join(`
|
|
397363
398317
|
`);
|
|
397364
398318
|
}
|
|
@@ -397445,13 +398399,13 @@ var init_project2 = __esm(() => {
|
|
|
397445
398399
|
});
|
|
397446
398400
|
|
|
397447
398401
|
// src/ur/notes.ts
|
|
397448
|
-
import { appendFileSync as appendFileSync5, existsSync as
|
|
397449
|
-
import { dirname as dirname59, join as
|
|
398402
|
+
import { appendFileSync as appendFileSync5, existsSync as existsSync43, mkdirSync as mkdirSync39, readFileSync as readFileSync48, writeFileSync as writeFileSync37 } from "fs";
|
|
398403
|
+
import { dirname as dirname59, join as join161 } from "path";
|
|
397450
398404
|
function readJsonl(file2) {
|
|
397451
|
-
if (!
|
|
398405
|
+
if (!existsSync43(file2))
|
|
397452
398406
|
return [];
|
|
397453
398407
|
const out = [];
|
|
397454
|
-
for (const line of
|
|
398408
|
+
for (const line of readFileSync48(file2, "utf8").split(`
|
|
397455
398409
|
`).filter(Boolean)) {
|
|
397456
398410
|
try {
|
|
397457
398411
|
out.push(JSON.parse(line));
|
|
@@ -397461,7 +398415,7 @@ function readJsonl(file2) {
|
|
|
397461
398415
|
}
|
|
397462
398416
|
function append2(file2, rec) {
|
|
397463
398417
|
try {
|
|
397464
|
-
|
|
398418
|
+
mkdirSync39(dirname59(file2), { recursive: true });
|
|
397465
398419
|
appendFileSync5(file2, JSON.stringify(rec) + `
|
|
397466
398420
|
`);
|
|
397467
398421
|
} catch {}
|
|
@@ -397479,8 +398433,8 @@ function forget(cwd2, needle) {
|
|
|
397479
398433
|
const removed = all4.length - kept.length;
|
|
397480
398434
|
if (removed > 0) {
|
|
397481
398435
|
try {
|
|
397482
|
-
|
|
397483
|
-
|
|
398436
|
+
mkdirSync39(dirname59(file2), { recursive: true });
|
|
398437
|
+
writeFileSync37(file2, kept.map((n2) => JSON.stringify(n2)).join(`
|
|
397484
398438
|
`) + (kept.length ? `
|
|
397485
398439
|
` : ""));
|
|
397486
398440
|
} catch {}
|
|
@@ -397493,7 +398447,7 @@ function addResearch(cwd2, kind, text) {
|
|
|
397493
398447
|
function listResearch(cwd2, kind) {
|
|
397494
398448
|
return readJsonl(researchFile(cwd2, kind));
|
|
397495
398449
|
}
|
|
397496
|
-
var memFile = (cwd2) =>
|
|
398450
|
+
var memFile = (cwd2) => join161(cwd2, ".ur", "memory", "notes.jsonl"), researchFile = (cwd2, kind) => join161(cwd2, ".ur", "research", `${kind}.jsonl`);
|
|
397497
398451
|
var init_notes = () => {};
|
|
397498
398452
|
|
|
397499
398453
|
// src/commands/remember/remember.ts
|
|
@@ -397532,27 +398486,27 @@ var init_remember2 = __esm(() => {
|
|
|
397532
398486
|
|
|
397533
398487
|
// src/services/agents/memoryRetention.ts
|
|
397534
398488
|
import {
|
|
397535
|
-
existsSync as
|
|
397536
|
-
mkdirSync as
|
|
397537
|
-
readFileSync as
|
|
398489
|
+
existsSync as existsSync44,
|
|
398490
|
+
mkdirSync as mkdirSync40,
|
|
398491
|
+
readFileSync as readFileSync49,
|
|
397538
398492
|
readdirSync as readdirSync17,
|
|
397539
|
-
writeFileSync as
|
|
398493
|
+
writeFileSync as writeFileSync38
|
|
397540
398494
|
} from "fs";
|
|
397541
|
-
import { dirname as dirname60, join as
|
|
398495
|
+
import { dirname as dirname60, join as join162 } from "path";
|
|
397542
398496
|
function memoryDir(cwd2) {
|
|
397543
|
-
return
|
|
398497
|
+
return join162(cwd2, ".ur", "memory");
|
|
397544
398498
|
}
|
|
397545
398499
|
function policyPath2(cwd2) {
|
|
397546
|
-
return
|
|
398500
|
+
return join162(memoryDir(cwd2), "retention.json");
|
|
397547
398501
|
}
|
|
397548
398502
|
function defaultMemoryRetentionPolicy() {
|
|
397549
398503
|
return { version: 1, maxEntries: 1000, updatedAt: new Date().toISOString() };
|
|
397550
398504
|
}
|
|
397551
398505
|
function loadMemoryRetentionPolicy(cwd2) {
|
|
397552
398506
|
const path22 = policyPath2(cwd2);
|
|
397553
|
-
if (!
|
|
398507
|
+
if (!existsSync44(path22))
|
|
397554
398508
|
return defaultMemoryRetentionPolicy();
|
|
397555
|
-
const parsed = safeParseJSON(
|
|
398509
|
+
const parsed = safeParseJSON(readFileSync49(path22, "utf-8"), false);
|
|
397556
398510
|
if (!parsed || typeof parsed !== "object")
|
|
397557
398511
|
return defaultMemoryRetentionPolicy();
|
|
397558
398512
|
const p2 = parsed;
|
|
@@ -397573,8 +398527,8 @@ function saveMemoryRetentionPolicy(cwd2, patch) {
|
|
|
397573
398527
|
decayDays: patch.decayDays === undefined ? current.decayDays : validPositive(patch.decayDays),
|
|
397574
398528
|
updatedAt: new Date().toISOString()
|
|
397575
398529
|
};
|
|
397576
|
-
|
|
397577
|
-
|
|
398530
|
+
mkdirSync40(dirname60(policyPath2(cwd2)), { recursive: true });
|
|
398531
|
+
writeFileSync38(policyPath2(cwd2), `${JSON.stringify(next, null, 2)}
|
|
397578
398532
|
`);
|
|
397579
398533
|
return next;
|
|
397580
398534
|
}
|
|
@@ -397590,10 +398544,10 @@ function timestamp(record3) {
|
|
|
397590
398544
|
return Number.isFinite(time3) ? time3 : 0;
|
|
397591
398545
|
}
|
|
397592
398546
|
function readJsonl2(file2) {
|
|
397593
|
-
if (!
|
|
398547
|
+
if (!existsSync44(file2))
|
|
397594
398548
|
return [];
|
|
397595
398549
|
const records = [];
|
|
397596
|
-
for (const line of
|
|
398550
|
+
for (const line of readFileSync49(file2, "utf-8").split(`
|
|
397597
398551
|
`)) {
|
|
397598
398552
|
if (!line.trim())
|
|
397599
398553
|
continue;
|
|
@@ -397604,7 +398558,7 @@ function readJsonl2(file2) {
|
|
|
397604
398558
|
return records;
|
|
397605
398559
|
}
|
|
397606
398560
|
function writeJsonl(file2, records) {
|
|
397607
|
-
|
|
398561
|
+
writeFileSync38(file2, records.map((r) => JSON.stringify(r)).join(`
|
|
397608
398562
|
`) + (records.length ? `
|
|
397609
398563
|
` : ""));
|
|
397610
398564
|
}
|
|
@@ -397632,9 +398586,9 @@ function applyPolicy(records, policy, nowMs) {
|
|
|
397632
398586
|
}
|
|
397633
398587
|
function memoryJsonlFiles(cwd2) {
|
|
397634
398588
|
const dir = memoryDir(cwd2);
|
|
397635
|
-
if (!
|
|
398589
|
+
if (!existsSync44(dir))
|
|
397636
398590
|
return [];
|
|
397637
|
-
return readdirSync17(dir).filter((name) => name.endsWith(".jsonl")).map((name) =>
|
|
398591
|
+
return readdirSync17(dir).filter((name) => name.endsWith(".jsonl")).map((name) => join162(dir, name));
|
|
397638
398592
|
}
|
|
397639
398593
|
function pruneMemoryRetention(cwd2, policy = loadMemoryRetentionPolicy(cwd2), nowMs = Date.now()) {
|
|
397640
398594
|
const files = memoryJsonlFiles(cwd2).map((file2) => {
|
|
@@ -397755,10 +398709,10 @@ var exports_semantic_memory = {};
|
|
|
397755
398709
|
__export(exports_semantic_memory, {
|
|
397756
398710
|
call: () => call91
|
|
397757
398711
|
});
|
|
397758
|
-
import { existsSync as
|
|
397759
|
-
import { basename as basename40, join as
|
|
398712
|
+
import { existsSync as existsSync45, mkdirSync as mkdirSync41, readdirSync as readdirSync18, readFileSync as readFileSync50, statSync as statSync10, writeFileSync as writeFileSync39 } from "fs";
|
|
398713
|
+
import { basename as basename40, join as join163 } from "path";
|
|
397760
398714
|
function indexPath3() {
|
|
397761
|
-
return
|
|
398715
|
+
return join163(getCwd(), ".ur", "semantic-memory", "index", "index.json");
|
|
397762
398716
|
}
|
|
397763
398717
|
function tokenize7(value) {
|
|
397764
398718
|
return [...new Set(value.toLowerCase().match(/[a-z0-9_]{3,}/g) ?? [])];
|
|
@@ -397767,15 +398721,15 @@ function sourceFiles() {
|
|
|
397767
398721
|
const cwd2 = getCwd();
|
|
397768
398722
|
const files = [];
|
|
397769
398723
|
for (const file2 of ["UR.md", "README.md"]) {
|
|
397770
|
-
const path22 =
|
|
397771
|
-
if (
|
|
398724
|
+
const path22 = join163(cwd2, file2);
|
|
398725
|
+
if (existsSync45(path22))
|
|
397772
398726
|
files.push(path22);
|
|
397773
398727
|
}
|
|
397774
|
-
for (const dir of [
|
|
397775
|
-
if (!
|
|
398728
|
+
for (const dir of [join163(cwd2, ".ur", "memory"), join163(cwd2, ".ur", "docs")]) {
|
|
398729
|
+
if (!existsSync45(dir))
|
|
397776
398730
|
continue;
|
|
397777
398731
|
for (const file2 of readdirSync18(dir)) {
|
|
397778
|
-
const path22 =
|
|
398732
|
+
const path22 = join163(dir, file2);
|
|
397779
398733
|
if (statSync10(path22).isFile() && /\.(md|txt|jsonl)$/i.test(file2)) {
|
|
397780
398734
|
files.push(path22);
|
|
397781
398735
|
}
|
|
@@ -397792,22 +398746,22 @@ function chunkText2(source, text) {
|
|
|
397792
398746
|
}));
|
|
397793
398747
|
}
|
|
397794
398748
|
function buildIndex2() {
|
|
397795
|
-
const entries = sourceFiles().flatMap((file2) => chunkText2(file2,
|
|
398749
|
+
const entries = sourceFiles().flatMap((file2) => chunkText2(file2, readFileSync50(file2, "utf-8")));
|
|
397796
398750
|
const index2 = {
|
|
397797
398751
|
version: 1,
|
|
397798
398752
|
mode: "lexical",
|
|
397799
398753
|
builtAt: new Date().toISOString(),
|
|
397800
398754
|
entries
|
|
397801
398755
|
};
|
|
397802
|
-
|
|
397803
|
-
|
|
398756
|
+
mkdirSync41(join163(getCwd(), ".ur", "semantic-memory", "index"), { recursive: true });
|
|
398757
|
+
writeFileSync39(indexPath3(), `${JSON.stringify(index2, null, 2)}
|
|
397804
398758
|
`);
|
|
397805
398759
|
return index2;
|
|
397806
398760
|
}
|
|
397807
398761
|
function loadIndex3() {
|
|
397808
|
-
if (!
|
|
398762
|
+
if (!existsSync45(indexPath3()))
|
|
397809
398763
|
return null;
|
|
397810
|
-
const parsed = safeParseJSON(
|
|
398764
|
+
const parsed = safeParseJSON(readFileSync50(indexPath3(), "utf-8"), false);
|
|
397811
398765
|
return parsed && typeof parsed === "object" ? parsed : null;
|
|
397812
398766
|
}
|
|
397813
398767
|
function searchIndex(index2, query2) {
|
|
@@ -566988,17 +567942,17 @@ Additional information: BADCLIENT: Bad error code, ${badCode} not found in range
|
|
|
566988
567942
|
// src/services/repoEditing/reliableRepoEdit.ts
|
|
566989
567943
|
import { exec as exec6 } from "child_process";
|
|
566990
567944
|
import {
|
|
566991
|
-
existsSync as
|
|
566992
|
-
mkdirSync as
|
|
566993
|
-
readFileSync as
|
|
567945
|
+
existsSync as existsSync46,
|
|
567946
|
+
mkdirSync as mkdirSync42,
|
|
567947
|
+
readFileSync as readFileSync51,
|
|
566994
567948
|
readdirSync as readdirSync19,
|
|
566995
567949
|
statSync as statSync11,
|
|
566996
|
-
writeFileSync as
|
|
567950
|
+
writeFileSync as writeFileSync40
|
|
566997
567951
|
} from "fs";
|
|
566998
|
-
import { dirname as dirname61, extname as extname15, isAbsolute as isAbsolute26, join as
|
|
567952
|
+
import { dirname as dirname61, extname as extname15, isAbsolute as isAbsolute26, join as join164, relative as relative34, resolve as resolve44 } from "path";
|
|
566999
567953
|
import { promisify as promisify4 } from "util";
|
|
567000
567954
|
function repoEditIndexPath(root2) {
|
|
567001
|
-
return
|
|
567955
|
+
return join164(root2, ".ur", "repo-edit", "index.json");
|
|
567002
567956
|
}
|
|
567003
567957
|
function isSkippedDir(pathFromRoot, name) {
|
|
567004
567958
|
if (SKIP_DIRS.has(name))
|
|
@@ -567029,7 +567983,7 @@ function listRepoFiles(root2, maxFiles = 25000) {
|
|
|
567029
567983
|
for (const entry of entries) {
|
|
567030
567984
|
if (files.length >= maxFiles)
|
|
567031
567985
|
return;
|
|
567032
|
-
const full =
|
|
567986
|
+
const full = join164(dir, entry.name);
|
|
567033
567987
|
const rel = normalizeRelPath(relative34(root2, full));
|
|
567034
567988
|
if (entry.isDirectory()) {
|
|
567035
567989
|
if (entry.name.startsWith(".") && entry.name !== ".ur")
|
|
@@ -567105,7 +568059,7 @@ function collectSymbols(file2, content) {
|
|
|
567105
568059
|
}
|
|
567106
568060
|
function buildRepoEditIndex(root2) {
|
|
567107
568061
|
const files = listRepoFiles(root2).map((path22) => {
|
|
567108
|
-
const abs =
|
|
568062
|
+
const abs = join164(root2, path22);
|
|
567109
568063
|
const stat41 = statSync11(abs);
|
|
567110
568064
|
const ext = extname15(path22).toLowerCase();
|
|
567111
568065
|
const text = isTextPath(path22);
|
|
@@ -567113,7 +568067,7 @@ function buildRepoEditIndex(root2) {
|
|
|
567113
568067
|
let content = "";
|
|
567114
568068
|
if (text && stat41.size <= 1e6) {
|
|
567115
568069
|
try {
|
|
567116
|
-
content =
|
|
568070
|
+
content = readFileSync51(abs, "utf-8");
|
|
567117
568071
|
} catch {
|
|
567118
568072
|
content = "";
|
|
567119
568073
|
}
|
|
@@ -567135,16 +568089,16 @@ ${content}`),
|
|
|
567135
568089
|
builtAt: new Date().toISOString(),
|
|
567136
568090
|
files
|
|
567137
568091
|
};
|
|
567138
|
-
|
|
567139
|
-
|
|
568092
|
+
mkdirSync42(dirname61(repoEditIndexPath(root2)), { recursive: true });
|
|
568093
|
+
writeFileSync40(repoEditIndexPath(root2), `${JSON.stringify(index2, null, 2)}
|
|
567140
568094
|
`);
|
|
567141
568095
|
return index2;
|
|
567142
568096
|
}
|
|
567143
568097
|
function loadRepoEditIndex(root2) {
|
|
567144
568098
|
const path22 = repoEditIndexPath(root2);
|
|
567145
|
-
if (!
|
|
568099
|
+
if (!existsSync46(path22))
|
|
567146
568100
|
return null;
|
|
567147
|
-
const parsed = safeParseJSON(
|
|
568101
|
+
const parsed = safeParseJSON(readFileSync51(path22, "utf-8"), false);
|
|
567148
568102
|
return parsed && typeof parsed === "object" ? parsed : null;
|
|
567149
568103
|
}
|
|
567150
568104
|
function searchRepoEditIndex(root2, query2, index2 = loadRepoEditIndex(root2) ?? buildRepoEditIndex(root2)) {
|
|
@@ -567170,7 +568124,7 @@ function searchRepoEditIndex(root2, query2, index2 = loadRepoEditIndex(root2) ??
|
|
|
567170
568124
|
const lines = [];
|
|
567171
568125
|
if (file2.text && score > 0) {
|
|
567172
568126
|
try {
|
|
567173
|
-
const content =
|
|
568127
|
+
const content = readFileSync51(join164(root2, file2.path), "utf-8");
|
|
567174
568128
|
const split = content.split(`
|
|
567175
568129
|
`);
|
|
567176
568130
|
for (let i3 = 0;i3 < split.length && lines.length < 4; i3++) {
|
|
@@ -567224,10 +568178,10 @@ function planRename(root2, from, to) {
|
|
|
567224
568178
|
if (from === to)
|
|
567225
568179
|
throw new Error("from and to must be different identifiers");
|
|
567226
568180
|
const files = listRepoFiles(root2).filter(isCodePath).flatMap((file2) => {
|
|
567227
|
-
const abs =
|
|
568181
|
+
const abs = join164(root2, file2);
|
|
567228
568182
|
let oldContent;
|
|
567229
568183
|
try {
|
|
567230
|
-
oldContent =
|
|
568184
|
+
oldContent = readFileSync51(abs, "utf-8");
|
|
567231
568185
|
} catch {
|
|
567232
568186
|
return [];
|
|
567233
568187
|
}
|
|
@@ -567284,7 +568238,7 @@ async function runCheck(command5, cwd2) {
|
|
|
567284
568238
|
}
|
|
567285
568239
|
function rollback(root2, snapshots) {
|
|
567286
568240
|
for (const [file2, content] of snapshots) {
|
|
567287
|
-
|
|
568241
|
+
writeFileSync40(join164(root2, file2), content);
|
|
567288
568242
|
}
|
|
567289
568243
|
}
|
|
567290
568244
|
async function applyRename(root2, from, to, options2 = {}) {
|
|
@@ -567297,7 +568251,7 @@ async function applyRename(root2, from, to, options2 = {}) {
|
|
|
567297
568251
|
try {
|
|
567298
568252
|
for (const file2 of plan.files) {
|
|
567299
568253
|
snapshots.set(file2.file, file2.oldContent);
|
|
567300
|
-
|
|
568254
|
+
writeFileSync40(join164(root2, file2.file), file2.newContent);
|
|
567301
568255
|
writtenFiles.push(file2.file);
|
|
567302
568256
|
}
|
|
567303
568257
|
const syntax = plan.files.flatMap((file2) => syntaxErrors(file2.file, file2.newContent));
|
|
@@ -567741,11 +568695,11 @@ var init_cite2 = __esm(() => {
|
|
|
567741
568695
|
});
|
|
567742
568696
|
|
|
567743
568697
|
// src/ur/fileops.ts
|
|
567744
|
-
import { existsSync as
|
|
567745
|
-
import { extname as extname16, isAbsolute as isAbsolute27, join as
|
|
568698
|
+
import { existsSync as existsSync47, mkdirSync as mkdirSync43, readdirSync as readdirSync20, readFileSync as readFileSync52, statSync as statSync12, writeFileSync as writeFileSync41 } from "fs";
|
|
568699
|
+
import { extname as extname16, isAbsolute as isAbsolute27, join as join165, relative as relative35, resolve as resolve45 } from "path";
|
|
567746
568700
|
function readFileSafe2(cwd2, target, maxBytes = 64000) {
|
|
567747
568701
|
const abs = isAbsolute27(target) ? target : resolve45(cwd2, target);
|
|
567748
|
-
if (!
|
|
568702
|
+
if (!existsSync47(abs))
|
|
567749
568703
|
return { ok: false, error: `not found: ${target}` };
|
|
567750
568704
|
const st = statSync12(abs);
|
|
567751
568705
|
if (st.isDirectory())
|
|
@@ -567753,7 +568707,7 @@ function readFileSafe2(cwd2, target, maxBytes = 64000) {
|
|
|
567753
568707
|
if (!isTextLike(abs))
|
|
567754
568708
|
return { ok: false, error: `not a text file (${extname16(abs) || "no ext"}). For images use /image, for video /video, for PDFs/docs ask UR to read it.` };
|
|
567755
568709
|
try {
|
|
567756
|
-
let content =
|
|
568710
|
+
let content = readFileSync52(abs, "utf8");
|
|
567757
568711
|
if (content.length > maxBytes)
|
|
567758
568712
|
content = content.slice(0, maxBytes) + `
|
|
567759
568713
|
\u2026 [truncated at ${maxBytes} bytes]`;
|
|
@@ -567776,7 +568730,7 @@ function* walk(dir, root2, budget = { n: 0 }, max2 = 8000) {
|
|
|
567776
568730
|
return;
|
|
567777
568731
|
if (e.name.startsWith(".") && e.name !== ".ur")
|
|
567778
568732
|
continue;
|
|
567779
|
-
const full =
|
|
568733
|
+
const full = join165(dir, e.name);
|
|
567780
568734
|
if (e.isDirectory()) {
|
|
567781
568735
|
if (SKIP_DIRS2.has(e.name))
|
|
567782
568736
|
continue;
|
|
@@ -567795,7 +568749,7 @@ function searchFiles(cwd2, query2, maxResults = 60) {
|
|
|
567795
568749
|
continue;
|
|
567796
568750
|
let lines;
|
|
567797
568751
|
try {
|
|
567798
|
-
lines =
|
|
568752
|
+
lines = readFileSync52(join165(cwd2, rel), "utf8").split(`
|
|
567799
568753
|
`);
|
|
567800
568754
|
} catch {
|
|
567801
568755
|
continue;
|
|
@@ -567813,8 +568767,8 @@ function searchFiles(cwd2, query2, maxResults = 60) {
|
|
|
567813
568767
|
function indexWorkspace(cwd2) {
|
|
567814
568768
|
const files = [...walk(cwd2, cwd2)];
|
|
567815
568769
|
try {
|
|
567816
|
-
|
|
567817
|
-
|
|
568770
|
+
mkdirSync43(join165(cwd2, ".ur", "index"), { recursive: true });
|
|
568771
|
+
writeFileSync41(join165(cwd2, ".ur", "index", "files.txt"), files.join(`
|
|
567818
568772
|
`) + `
|
|
567819
568773
|
`);
|
|
567820
568774
|
} catch {}
|
|
@@ -568082,14 +569036,14 @@ var exports_image = {};
|
|
|
568082
569036
|
__export(exports_image, {
|
|
568083
569037
|
call: () => call104
|
|
568084
569038
|
});
|
|
568085
|
-
import { existsSync as
|
|
569039
|
+
import { existsSync as existsSync48, statSync as statSync13 } from "fs";
|
|
568086
569040
|
import { extname as extname17, isAbsolute as isAbsolute28, resolve as resolve46 } from "path";
|
|
568087
569041
|
var call104 = async (args) => {
|
|
568088
569042
|
const f = (args ?? "").trim().split(/\s+/)[0] ?? "";
|
|
568089
569043
|
if (!f)
|
|
568090
569044
|
return { type: "text", value: "usage: /image <file> [task]" };
|
|
568091
569045
|
const abs = isAbsolute28(f) ? f : resolve46(getCwd(), f);
|
|
568092
|
-
if (!
|
|
569046
|
+
if (!existsSync48(abs))
|
|
568093
569047
|
return { type: "text", value: `not found: ${f}` };
|
|
568094
569048
|
const kb = Math.round(statSync13(abs).size / 1024);
|
|
568095
569049
|
const lines = [`image ${f} \u2014 ${extname17(abs) || "?"}, ${kb} KB`];
|
|
@@ -568130,7 +569084,7 @@ var exports_video = {};
|
|
|
568130
569084
|
__export(exports_video, {
|
|
568131
569085
|
call: () => call105
|
|
568132
569086
|
});
|
|
568133
|
-
import { existsSync as
|
|
569087
|
+
import { existsSync as existsSync49 } from "fs";
|
|
568134
569088
|
import { isAbsolute as isAbsolute29, resolve as resolve47 } from "path";
|
|
568135
569089
|
var call105 = async (args) => {
|
|
568136
569090
|
const target = (args ?? "").trim().split(/\s+/)[0] ?? "";
|
|
@@ -568143,7 +569097,7 @@ var call105 = async (args) => {
|
|
|
568143
569097
|
${yd}` };
|
|
568144
569098
|
}
|
|
568145
569099
|
const abs = isAbsolute29(target) ? target : resolve47(getCwd(), target);
|
|
568146
|
-
if (!
|
|
569100
|
+
if (!existsSync49(abs))
|
|
568147
569101
|
return { type: "text", value: `not found: ${target}` };
|
|
568148
569102
|
if (!commandExists("ffprobe")) {
|
|
568149
569103
|
return { type: "text", value: `local video: ${target}
|
|
@@ -568239,13 +569193,13 @@ var exports_mode = {};
|
|
|
568239
569193
|
__export(exports_mode, {
|
|
568240
569194
|
call: () => call107
|
|
568241
569195
|
});
|
|
568242
|
-
import { existsSync as
|
|
568243
|
-
import { join as
|
|
568244
|
-
var MODES, SECURITY_MODES2, file2 = (cwd2) =>
|
|
569196
|
+
import { existsSync as existsSync50, mkdirSync as mkdirSync44, readFileSync as readFileSync53, writeFileSync as writeFileSync42 } from "fs";
|
|
569197
|
+
import { join as join166 } from "path";
|
|
569198
|
+
var MODES, SECURITY_MODES2, file2 = (cwd2) => join166(cwd2, ".ur", "mode"), call107 = async (args) => {
|
|
568245
569199
|
const want = (args ?? "").trim().toLowerCase();
|
|
568246
569200
|
const f = file2(getCwd());
|
|
568247
569201
|
if (!want) {
|
|
568248
|
-
const cur =
|
|
569202
|
+
const cur = existsSync50(f) ? readFileSync53(f, "utf8").trim() : "code";
|
|
568249
569203
|
return { type: "text", value: `mode: ${cur}
|
|
568250
569204
|
available: ${MODES.join(", ")}
|
|
568251
569205
|
security: ${SECURITY_MODES2.join(", ")}` };
|
|
@@ -568259,8 +569213,8 @@ available: ${MODES.join(", ")}
|
|
|
568259
569213
|
security: ${SECURITY_MODES2.join(", ")}` };
|
|
568260
569214
|
}
|
|
568261
569215
|
try {
|
|
568262
|
-
|
|
568263
|
-
|
|
569216
|
+
mkdirSync44(join166(getCwd(), ".ur"), { recursive: true });
|
|
569217
|
+
writeFileSync42(f, want + `
|
|
568264
569218
|
`);
|
|
568265
569219
|
} catch {}
|
|
568266
569220
|
return { type: "text", value: `mode \u2192 ${want} (UR will favor ${want}-oriented behavior; persisted to .ur/mode)` };
|
|
@@ -568382,8 +569336,8 @@ var exports_role_mode = {};
|
|
|
568382
569336
|
__export(exports_role_mode, {
|
|
568383
569337
|
call: () => call108
|
|
568384
569338
|
});
|
|
568385
|
-
import { existsSync as
|
|
568386
|
-
import { join as
|
|
569339
|
+
import { existsSync as existsSync51, mkdirSync as mkdirSync45, writeFileSync as writeFileSync43 } from "fs";
|
|
569340
|
+
import { join as join167 } from "path";
|
|
568387
569341
|
function formatList() {
|
|
568388
569342
|
const lines = ["Built-in role modes:", ""];
|
|
568389
569343
|
for (const mode2 of ROLE_MODES) {
|
|
@@ -568437,17 +569391,17 @@ var call108 = async (args) => {
|
|
|
568437
569391
|
value: `Unknown role mode "${target}". Available: ${listModeNames().join(", ")}, or "all".`
|
|
568438
569392
|
};
|
|
568439
569393
|
}
|
|
568440
|
-
const agentsDir =
|
|
568441
|
-
|
|
569394
|
+
const agentsDir = join167(getCwd(), ".ur", "agents");
|
|
569395
|
+
mkdirSync45(agentsDir, { recursive: true });
|
|
568442
569396
|
const created = [];
|
|
568443
569397
|
const skipped = [];
|
|
568444
569398
|
for (const mode2 of modes) {
|
|
568445
|
-
const path22 =
|
|
568446
|
-
if (
|
|
569399
|
+
const path22 = join167(agentsDir, `${mode2.name}.md`);
|
|
569400
|
+
if (existsSync51(path22) && !force) {
|
|
568447
569401
|
skipped.push(`${mode2.name} (exists; use --force to overwrite)`);
|
|
568448
569402
|
continue;
|
|
568449
569403
|
}
|
|
568450
|
-
|
|
569404
|
+
writeFileSync43(path22, renderModeAgent(mode2), { encoding: "utf-8" });
|
|
568451
569405
|
created.push(path22);
|
|
568452
569406
|
}
|
|
568453
569407
|
if (json2) {
|
|
@@ -568493,25 +569447,25 @@ var init_role_mode2 = __esm(() => {
|
|
|
568493
569447
|
});
|
|
568494
569448
|
|
|
568495
569449
|
// src/ur/researchGraph.ts
|
|
568496
|
-
import { appendFileSync as appendFileSync6, existsSync as
|
|
568497
|
-
import { dirname as dirname62, join as
|
|
569450
|
+
import { appendFileSync as appendFileSync6, existsSync as existsSync52, mkdirSync as mkdirSync46, readFileSync as readFileSync54 } from "fs";
|
|
569451
|
+
import { dirname as dirname62, join as join168 } from "path";
|
|
568498
569452
|
function isEntity(s) {
|
|
568499
569453
|
return ENTITIES.includes(s);
|
|
568500
569454
|
}
|
|
568501
569455
|
function addEntity(cwd2, entity, text) {
|
|
568502
569456
|
try {
|
|
568503
569457
|
const f = file3(cwd2, entity);
|
|
568504
|
-
|
|
569458
|
+
mkdirSync46(dirname62(f), { recursive: true });
|
|
568505
569459
|
appendFileSync6(f, JSON.stringify({ ts: new Date().toISOString(), text }) + `
|
|
568506
569460
|
`);
|
|
568507
569461
|
} catch {}
|
|
568508
569462
|
}
|
|
568509
569463
|
function listEntity(cwd2, entity) {
|
|
568510
569464
|
const f = file3(cwd2, entity);
|
|
568511
|
-
if (!
|
|
569465
|
+
if (!existsSync52(f))
|
|
568512
569466
|
return [];
|
|
568513
569467
|
const out = [];
|
|
568514
|
-
for (const line of
|
|
569468
|
+
for (const line of readFileSync54(f, "utf8").split(`
|
|
568515
569469
|
`).filter(Boolean)) {
|
|
568516
569470
|
try {
|
|
568517
569471
|
out.push(JSON.parse(line));
|
|
@@ -568525,7 +569479,7 @@ function graphSummary(cwd2) {
|
|
|
568525
569479
|
out[e] = listEntity(cwd2, e).length;
|
|
568526
569480
|
return out;
|
|
568527
569481
|
}
|
|
568528
|
-
var ENTITIES, file3 = (cwd2, entity) =>
|
|
569482
|
+
var ENTITIES, file3 = (cwd2, entity) => join168(cwd2, ".ur", "graph", `${entity}.jsonl`);
|
|
568529
569483
|
var init_researchGraph = __esm(() => {
|
|
568530
569484
|
ENTITIES = [
|
|
568531
569485
|
"sources",
|
|
@@ -568594,15 +569548,15 @@ var exports_toolsmith = {};
|
|
|
568594
569548
|
__export(exports_toolsmith, {
|
|
568595
569549
|
call: () => call110
|
|
568596
569550
|
});
|
|
568597
|
-
import { existsSync as
|
|
568598
|
-
import { join as
|
|
569551
|
+
import { existsSync as existsSync53, mkdirSync as mkdirSync47, readdirSync as readdirSync21, writeFileSync as writeFileSync44 } from "fs";
|
|
569552
|
+
import { join as join169 } from "path";
|
|
568599
569553
|
var TEMPLATES, call110 = async (args) => {
|
|
568600
569554
|
const [name, langArg] = (args ?? "").trim().split(/\s+/).filter(Boolean);
|
|
568601
569555
|
const auto = [["python3", "python"], ["node", "node"], ["bash", "bash"], ["go", "go"], ["cargo", "rust"]].find(([bin]) => commandExists(bin))?.[1] ?? "python";
|
|
568602
569556
|
const lang = langArg ?? auto;
|
|
568603
|
-
const dir =
|
|
569557
|
+
const dir = join169(getCwd(), ".ur", "tools");
|
|
568604
569558
|
if (!name) {
|
|
568605
|
-
const files =
|
|
569559
|
+
const files = existsSync53(dir) ? readdirSync21(dir) : [];
|
|
568606
569560
|
return { type: "text", value: files.length ? `tools:
|
|
568607
569561
|
` + files.map((f) => " " + f).join(`
|
|
568608
569562
|
`) : "no tools yet. usage: /toolsmith <name> <python|bash|node|go|rust>" };
|
|
@@ -568610,11 +569564,11 @@ var TEMPLATES, call110 = async (args) => {
|
|
|
568610
569564
|
const tpl = TEMPLATES[lang];
|
|
568611
569565
|
if (!tpl)
|
|
568612
569566
|
return { type: "text", value: `unknown lang "${lang}". choose: ${Object.keys(TEMPLATES).join(", ")}` };
|
|
568613
|
-
|
|
568614
|
-
const file4 =
|
|
568615
|
-
if (
|
|
569567
|
+
mkdirSync47(dir, { recursive: true });
|
|
569568
|
+
const file4 = join169(dir, `${name}.${tpl.ext}`);
|
|
569569
|
+
if (existsSync53(file4))
|
|
568616
569570
|
return { type: "text", value: `already exists: .ur/tools/${name}.${tpl.ext}` };
|
|
568617
|
-
|
|
569571
|
+
writeFileSync44(file4, tpl.body);
|
|
568618
569572
|
return { type: "text", value: `created .ur/tools/${name}.${tpl.ext}
|
|
568619
569573
|
Ask UR to run it \u2014 it will request approval before executing, and you can keep it as a plugin if useful.` };
|
|
568620
569574
|
};
|
|
@@ -568674,13 +569628,13 @@ var exports_browser = {};
|
|
|
568674
569628
|
__export(exports_browser, {
|
|
568675
569629
|
call: () => call111
|
|
568676
569630
|
});
|
|
568677
|
-
import { existsSync as
|
|
568678
|
-
import { join as
|
|
569631
|
+
import { existsSync as existsSync54 } from "fs";
|
|
569632
|
+
import { join as join170 } from "path";
|
|
568679
569633
|
var call111 = async (args) => {
|
|
568680
569634
|
const task = (args ?? "").trim();
|
|
568681
569635
|
if (!task)
|
|
568682
569636
|
return { type: "text", value: "usage: /browser <url|task>" };
|
|
568683
|
-
const hasPlaywright =
|
|
569637
|
+
const hasPlaywright = existsSync54(join170(getCwd(), "node_modules", "playwright")) || existsSync54(join170(getCwd(), "node_modules", "playwright-core"));
|
|
568684
569638
|
if (hasPlaywright) {
|
|
568685
569639
|
return { type: "text", value: `Playwright detected \u2014 ask UR to drive the browser for: ${task}
|
|
568686
569640
|
Risky actions (form submit, downloads, login) require your approval.` };
|
|
@@ -568735,22 +569689,22 @@ var init_ur_doctor2 = __esm(() => {
|
|
|
568735
569689
|
});
|
|
568736
569690
|
|
|
568737
569691
|
// src/utils/urAssets.ts
|
|
568738
|
-
import { existsSync as
|
|
568739
|
-
import { join as
|
|
569692
|
+
import { existsSync as existsSync55, mkdirSync as mkdirSync48, writeFileSync as writeFileSync45 } from "fs";
|
|
569693
|
+
import { join as join171 } from "path";
|
|
568740
569694
|
function scaffoldUrAssets(cwd2) {
|
|
568741
|
-
const root2 =
|
|
569695
|
+
const root2 = join171(cwd2, ".ur");
|
|
568742
569696
|
const created = [];
|
|
568743
569697
|
const skipped = [];
|
|
568744
|
-
|
|
569698
|
+
mkdirSync48(root2, { recursive: true });
|
|
568745
569699
|
for (const d of DIRS)
|
|
568746
|
-
|
|
569700
|
+
mkdirSync48(join171(root2, d), { recursive: true });
|
|
568747
569701
|
for (const file4 of SEED_FILES) {
|
|
568748
|
-
const full =
|
|
568749
|
-
if (
|
|
569702
|
+
const full = join171(root2, file4.path);
|
|
569703
|
+
if (existsSync55(full)) {
|
|
568750
569704
|
skipped.push(file4.path);
|
|
568751
569705
|
continue;
|
|
568752
569706
|
}
|
|
568753
|
-
|
|
569707
|
+
writeFileSync45(full, file4.content);
|
|
568754
569708
|
created.push(file4.path);
|
|
568755
569709
|
}
|
|
568756
569710
|
return { root: root2, created, skipped };
|
|
@@ -569043,7 +569997,7 @@ __export(exports_thinkback, {
|
|
|
569043
569997
|
call: () => call117
|
|
569044
569998
|
});
|
|
569045
569999
|
import { readFile as readFile45 } from "fs/promises";
|
|
569046
|
-
import { join as
|
|
570000
|
+
import { join as join172 } from "path";
|
|
569047
570001
|
function getMarketplaceName() {
|
|
569048
570002
|
return OFFICIAL_MARKETPLACE_NAME;
|
|
569049
570003
|
}
|
|
@@ -569061,15 +570015,15 @@ async function getThinkbackSkillDir() {
|
|
|
569061
570015
|
if (!thinkbackPlugin) {
|
|
569062
570016
|
return null;
|
|
569063
570017
|
}
|
|
569064
|
-
const skillDir =
|
|
570018
|
+
const skillDir = join172(thinkbackPlugin.path, "skills", SKILL_NAME);
|
|
569065
570019
|
if (await pathExists(skillDir)) {
|
|
569066
570020
|
return skillDir;
|
|
569067
570021
|
}
|
|
569068
570022
|
return null;
|
|
569069
570023
|
}
|
|
569070
570024
|
async function playAnimation(skillDir) {
|
|
569071
|
-
const dataPath =
|
|
569072
|
-
const playerPath =
|
|
570025
|
+
const dataPath = join172(skillDir, "year_in_review.js");
|
|
570026
|
+
const playerPath = join172(skillDir, "player.js");
|
|
569073
570027
|
try {
|
|
569074
570028
|
await readFile45(dataPath);
|
|
569075
570029
|
} catch (e) {
|
|
@@ -569117,7 +570071,7 @@ async function playAnimation(skillDir) {
|
|
|
569117
570071
|
} catch {} finally {
|
|
569118
570072
|
inkInstance.exitAlternateScreen();
|
|
569119
570073
|
}
|
|
569120
|
-
const htmlPath =
|
|
570074
|
+
const htmlPath = join172(skillDir, "year_in_review.html");
|
|
569121
570075
|
if (await pathExists(htmlPath)) {
|
|
569122
570076
|
const platform6 = getPlatform();
|
|
569123
570077
|
const openCmd = platform6 === "macos" ? "open" : platform6 === "windows" ? "start" : "xdg-open";
|
|
@@ -569453,7 +570407,7 @@ function ThinkbackFlow(t0) {
|
|
|
569453
570407
|
if (!skillDir) {
|
|
569454
570408
|
return;
|
|
569455
570409
|
}
|
|
569456
|
-
const dataPath =
|
|
570410
|
+
const dataPath = join172(skillDir, "year_in_review.js");
|
|
569457
570411
|
pathExists(dataPath).then((exists) => {
|
|
569458
570412
|
logForDebugging(`Checking for ${dataPath}: ${exists ? "found" : "not found"}`);
|
|
569459
570413
|
setHasGenerated(exists);
|
|
@@ -569627,7 +570581,7 @@ var exports_thinkback_play = {};
|
|
|
569627
570581
|
__export(exports_thinkback_play, {
|
|
569628
570582
|
call: () => call118
|
|
569629
570583
|
});
|
|
569630
|
-
import { join as
|
|
570584
|
+
import { join as join173 } from "path";
|
|
569631
570585
|
function getPluginId2() {
|
|
569632
570586
|
const marketplaceName = process.env.USER_TYPE === "ant" ? INTERNAL_MARKETPLACE_NAME : OFFICIAL_MARKETPLACE_NAME;
|
|
569633
570587
|
return `thinkback@${marketplaceName}`;
|
|
@@ -569649,7 +570603,7 @@ async function call118() {
|
|
|
569649
570603
|
value: "Thinkback plugin installation path not found."
|
|
569650
570604
|
};
|
|
569651
570605
|
}
|
|
569652
|
-
const skillDir =
|
|
570606
|
+
const skillDir = join173(firstInstall.installPath, "skills", SKILL_NAME2);
|
|
569653
570607
|
const result = await playAnimation(skillDir);
|
|
569654
570608
|
return { type: "text", value: result.message };
|
|
569655
570609
|
}
|
|
@@ -576044,7 +576998,7 @@ var init_types13 = __esm(() => {
|
|
|
576044
576998
|
|
|
576045
576999
|
// src/components/agents/agentFileUtils.ts
|
|
576046
577000
|
import { mkdir as mkdir35, open as open12, unlink as unlink19 } from "fs/promises";
|
|
576047
|
-
import { join as
|
|
577001
|
+
import { join as join174 } from "path";
|
|
576048
577002
|
function formatAgentAsMarkdown(agentType, whenToUse, tools, systemPrompt, color3, model, memory2, effort) {
|
|
576049
577003
|
const escapedWhenToUse = whenToUse.replace(/\\/g, "\\\\").replace(/"/g, "\\\"").replace(/\n/g, "\\\\n");
|
|
576050
577004
|
const isAllTools = tools === undefined || tools.length === 1 && tools[0] === "*";
|
|
@@ -576071,26 +577025,26 @@ function getAgentDirectoryPath(location2) {
|
|
|
576071
577025
|
case "flagSettings":
|
|
576072
577026
|
throw new Error(`Cannot get directory path for ${location2} agents`);
|
|
576073
577027
|
case "userSettings":
|
|
576074
|
-
return
|
|
577028
|
+
return join174(getURConfigHomeDir(), AGENT_PATHS.AGENTS_DIR);
|
|
576075
577029
|
case "projectSettings":
|
|
576076
|
-
return
|
|
577030
|
+
return join174(getCwd(), AGENT_PATHS.FOLDER_NAME, AGENT_PATHS.AGENTS_DIR);
|
|
576077
577031
|
case "policySettings":
|
|
576078
|
-
return
|
|
577032
|
+
return join174(getManagedFilePath(), AGENT_PATHS.FOLDER_NAME, AGENT_PATHS.AGENTS_DIR);
|
|
576079
577033
|
case "localSettings":
|
|
576080
|
-
return
|
|
577034
|
+
return join174(getCwd(), AGENT_PATHS.FOLDER_NAME, AGENT_PATHS.AGENTS_DIR);
|
|
576081
577035
|
}
|
|
576082
577036
|
}
|
|
576083
577037
|
function getRelativeAgentDirectoryPath(location2) {
|
|
576084
577038
|
switch (location2) {
|
|
576085
577039
|
case "projectSettings":
|
|
576086
|
-
return
|
|
577040
|
+
return join174(".", AGENT_PATHS.FOLDER_NAME, AGENT_PATHS.AGENTS_DIR);
|
|
576087
577041
|
default:
|
|
576088
577042
|
return getAgentDirectoryPath(location2);
|
|
576089
577043
|
}
|
|
576090
577044
|
}
|
|
576091
577045
|
function getNewAgentFilePath(agent) {
|
|
576092
577046
|
const dirPath = getAgentDirectoryPath(agent.source);
|
|
576093
|
-
return
|
|
577047
|
+
return join174(dirPath, `${agent.agentType}.md`);
|
|
576094
577048
|
}
|
|
576095
577049
|
function getActualAgentFilePath(agent) {
|
|
576096
577050
|
if (agent.source === "built-in") {
|
|
@@ -576101,14 +577055,14 @@ function getActualAgentFilePath(agent) {
|
|
|
576101
577055
|
}
|
|
576102
577056
|
const dirPath = getAgentDirectoryPath(agent.source);
|
|
576103
577057
|
const filename = agent.filename || agent.agentType;
|
|
576104
|
-
return
|
|
577058
|
+
return join174(dirPath, `${filename}.md`);
|
|
576105
577059
|
}
|
|
576106
577060
|
function getNewRelativeAgentFilePath(agent) {
|
|
576107
577061
|
if (agent.source === "built-in") {
|
|
576108
577062
|
return "Built-in";
|
|
576109
577063
|
}
|
|
576110
577064
|
const dirPath = getRelativeAgentDirectoryPath(agent.source);
|
|
576111
|
-
return
|
|
577065
|
+
return join174(dirPath, `${agent.agentType}.md`);
|
|
576112
577066
|
}
|
|
576113
577067
|
function getActualRelativeAgentFilePath(agent) {
|
|
576114
577068
|
if (isBuiltInAgent(agent)) {
|
|
@@ -576122,7 +577076,7 @@ function getActualRelativeAgentFilePath(agent) {
|
|
|
576122
577076
|
}
|
|
576123
577077
|
const dirPath = getRelativeAgentDirectoryPath(agent.source);
|
|
576124
577078
|
const filename = agent.filename || agent.agentType;
|
|
576125
|
-
return
|
|
577079
|
+
return join174(dirPath, `${filename}.md`);
|
|
576126
577080
|
}
|
|
576127
577081
|
async function ensureAgentDirectoryExists(source) {
|
|
576128
577082
|
const dirPath = getAgentDirectoryPath(source);
|
|
@@ -582131,9 +583085,9 @@ var init_rewind = __esm(() => {
|
|
|
582131
583085
|
});
|
|
582132
583086
|
|
|
582133
583087
|
// src/utils/heapDumpService.ts
|
|
582134
|
-
import { createWriteStream as createWriteStream3, writeFileSync as
|
|
583088
|
+
import { createWriteStream as createWriteStream3, writeFileSync as writeFileSync46 } from "fs";
|
|
582135
583089
|
import { readdir as readdir26, readFile as readFile47, writeFile as writeFile40 } from "fs/promises";
|
|
582136
|
-
import { join as
|
|
583090
|
+
import { join as join175 } from "path";
|
|
582137
583091
|
import { pipeline as pipeline2 } from "stream/promises";
|
|
582138
583092
|
import {
|
|
582139
583093
|
getHeapSnapshot,
|
|
@@ -582223,7 +583177,7 @@ async function captureMemoryDiagnostics(trigger2, dumpNumber = 0) {
|
|
|
582223
583177
|
smapsRollup,
|
|
582224
583178
|
platform: process.platform,
|
|
582225
583179
|
nodeVersion: process.version,
|
|
582226
|
-
ccVersion: "1.22.
|
|
583180
|
+
ccVersion: "1.22.1"
|
|
582227
583181
|
};
|
|
582228
583182
|
}
|
|
582229
583183
|
async function performHeapDump(trigger2 = "manual", dumpNumber = 0) {
|
|
@@ -582241,8 +583195,8 @@ async function performHeapDump(trigger2 = "manual", dumpNumber = 0) {
|
|
|
582241
583195
|
const suffix = dumpNumber > 0 ? `-dump${dumpNumber}` : "";
|
|
582242
583196
|
const heapFilename = `${sessionId}${suffix}.heapsnapshot`;
|
|
582243
583197
|
const diagFilename = `${sessionId}${suffix}-diagnostics.json`;
|
|
582244
|
-
const heapPath =
|
|
582245
|
-
const diagPath =
|
|
583198
|
+
const heapPath = join175(dumpDir, heapFilename);
|
|
583199
|
+
const diagPath = join175(dumpDir, diagFilename);
|
|
582246
583200
|
await writeFile40(diagPath, jsonStringify(diagnostics, null, 2), {
|
|
582247
583201
|
mode: 384
|
|
582248
583202
|
});
|
|
@@ -582270,7 +583224,7 @@ async function performHeapDump(trigger2 = "manual", dumpNumber = 0) {
|
|
|
582270
583224
|
}
|
|
582271
583225
|
async function writeHeapSnapshot(filepath) {
|
|
582272
583226
|
if (typeof Bun !== "undefined") {
|
|
582273
|
-
|
|
583227
|
+
writeFileSync46(filepath, Bun.generateHeapSnapshot("v8", "arraybuffer"), {
|
|
582274
583228
|
mode: 384
|
|
582275
583229
|
});
|
|
582276
583230
|
Bun.gc(true);
|
|
@@ -582809,7 +583763,7 @@ var init_bridge_kick = __esm(() => {
|
|
|
582809
583763
|
var call133 = async () => {
|
|
582810
583764
|
return {
|
|
582811
583765
|
type: "text",
|
|
582812
|
-
value: "1.22.
|
|
583766
|
+
value: "1.22.1"
|
|
582813
583767
|
};
|
|
582814
583768
|
}, version2, version_default;
|
|
582815
583769
|
var init_version = __esm(() => {
|
|
@@ -584081,7 +585035,7 @@ var init_sandbox_toggle2 = __esm(() => {
|
|
|
584081
585035
|
|
|
584082
585036
|
// src/utils/urInChrome/setupPortable.ts
|
|
584083
585037
|
import { readdir as readdir27 } from "fs/promises";
|
|
584084
|
-
import { join as
|
|
585038
|
+
import { join as join176 } from "path";
|
|
584085
585039
|
function getExtensionIds() {
|
|
584086
585040
|
return process.env.USER_TYPE === "ant" ? [PROD_EXTENSION_ID, DEV_EXTENSION_ID, ANT_EXTENSION_ID] : [PROD_EXTENSION_ID];
|
|
584087
585041
|
}
|
|
@@ -584108,7 +585062,7 @@ async function detectExtensionInstallationPortable(browserPaths, log) {
|
|
|
584108
585062
|
}
|
|
584109
585063
|
for (const profile of profileDirs) {
|
|
584110
585064
|
for (const extensionId of extensionIds) {
|
|
584111
|
-
const extensionPath =
|
|
585065
|
+
const extensionPath = join176(browserBasePath, profile, "Extensions", extensionId);
|
|
584112
585066
|
try {
|
|
584113
585067
|
await readdir27(extensionPath);
|
|
584114
585068
|
log?.(`[UR in Chrome] Extension ${extensionId} found in ${browser2} ${profile}`);
|
|
@@ -584132,7 +585086,7 @@ var init_setupPortable = __esm(() => {
|
|
|
584132
585086
|
// src/utils/urInChrome/setup.ts
|
|
584133
585087
|
import { chmod as chmod10, mkdir as mkdir36, readFile as readFile48, writeFile as writeFile41 } from "fs/promises";
|
|
584134
585088
|
import { homedir as homedir31 } from "os";
|
|
584135
|
-
import { join as
|
|
585089
|
+
import { join as join177 } from "path";
|
|
584136
585090
|
import { fileURLToPath as fileURLToPath6 } from "url";
|
|
584137
585091
|
function shouldEnableURInChrome(chromeFlag) {
|
|
584138
585092
|
if (getIsNonInteractiveSession() && chromeFlag !== true) {
|
|
@@ -584189,8 +585143,8 @@ function setupURInChrome() {
|
|
|
584189
585143
|
};
|
|
584190
585144
|
} else {
|
|
584191
585145
|
const __filename3 = fileURLToPath6(import.meta.url);
|
|
584192
|
-
const __dirname3 =
|
|
584193
|
-
const cliPath =
|
|
585146
|
+
const __dirname3 = join177(__filename3, "..");
|
|
585147
|
+
const cliPath = join177(__dirname3, "cli.js");
|
|
584194
585148
|
createWrapperScript(`"${process.execPath}" "${cliPath}" --chrome-native-host`).then((manifestBinaryPath) => installChromeNativeHostManifest(manifestBinaryPath)).catch((e) => logForDebugging(`[UR in Chrome] Failed to install native host: ${e}`, { level: "error" }));
|
|
584195
585149
|
const mcpConfig = {
|
|
584196
585150
|
[UR_IN_CHROME_MCP_SERVER_NAME]: {
|
|
@@ -584212,8 +585166,8 @@ function getNativeMessagingHostsDirs() {
|
|
|
584212
585166
|
const platform6 = getPlatform();
|
|
584213
585167
|
if (platform6 === "windows") {
|
|
584214
585168
|
const home = homedir31();
|
|
584215
|
-
const appData = process.env.APPDATA ||
|
|
584216
|
-
return [
|
|
585169
|
+
const appData = process.env.APPDATA || join177(home, "AppData", "Local");
|
|
585170
|
+
return [join177(appData, "UR", "ChromeNativeHost")];
|
|
584217
585171
|
}
|
|
584218
585172
|
return getAllNativeMessagingHostsDirs().map(({ path: path22 }) => path22);
|
|
584219
585173
|
}
|
|
@@ -584238,7 +585192,7 @@ async function installChromeNativeHostManifest(manifestBinaryPath) {
|
|
|
584238
585192
|
const manifestContent = jsonStringify(manifest, null, 2);
|
|
584239
585193
|
let anyManifestUpdated = false;
|
|
584240
585194
|
for (const manifestDir of manifestDirs) {
|
|
584241
|
-
const manifestPath5 =
|
|
585195
|
+
const manifestPath5 = join177(manifestDir, NATIVE_HOST_MANIFEST_NAME);
|
|
584242
585196
|
const existingContent = await readFile48(manifestPath5, "utf-8").catch(() => null);
|
|
584243
585197
|
if (existingContent === manifestContent) {
|
|
584244
585198
|
continue;
|
|
@@ -584253,7 +585207,7 @@ async function installChromeNativeHostManifest(manifestBinaryPath) {
|
|
|
584253
585207
|
}
|
|
584254
585208
|
}
|
|
584255
585209
|
if (getPlatform() === "windows") {
|
|
584256
|
-
const manifestPath5 =
|
|
585210
|
+
const manifestPath5 = join177(manifestDirs[0], NATIVE_HOST_MANIFEST_NAME);
|
|
584257
585211
|
registerWindowsNativeHosts(manifestPath5);
|
|
584258
585212
|
}
|
|
584259
585213
|
if (anyManifestUpdated) {
|
|
@@ -584291,8 +585245,8 @@ function registerWindowsNativeHosts(manifestPath5) {
|
|
|
584291
585245
|
}
|
|
584292
585246
|
async function createWrapperScript(command7) {
|
|
584293
585247
|
const platform6 = getPlatform();
|
|
584294
|
-
const chromeDir =
|
|
584295
|
-
const wrapperPath = platform6 === "windows" ?
|
|
585248
|
+
const chromeDir = join177(getURConfigHomeDir(), "chrome");
|
|
585249
|
+
const wrapperPath = platform6 === "windows" ? join177(chromeDir, "chrome-native-host.bat") : join177(chromeDir, "chrome-native-host");
|
|
584296
585250
|
const scriptContent = platform6 === "windows" ? `@echo off
|
|
584297
585251
|
REM Chrome native host wrapper script
|
|
584298
585252
|
REM Generated by UR - do not edit manually
|
|
@@ -584864,7 +585818,7 @@ var init_advisor2 = __esm(() => {
|
|
|
584864
585818
|
// src/skills/bundledSkills.ts
|
|
584865
585819
|
import { constants as fsConstants5 } from "fs";
|
|
584866
585820
|
import { mkdir as mkdir37, open as open13 } from "fs/promises";
|
|
584867
|
-
import { dirname as dirname63, isAbsolute as isAbsolute30, join as
|
|
585821
|
+
import { dirname as dirname63, isAbsolute as isAbsolute30, join as join178, normalize as normalize13, sep as pathSep2 } from "path";
|
|
584868
585822
|
function registerBundledSkill(definition) {
|
|
584869
585823
|
const { files: files2 } = definition;
|
|
584870
585824
|
let skillRoot;
|
|
@@ -584912,7 +585866,7 @@ function getBundledSkills() {
|
|
|
584912
585866
|
return [...bundledSkills];
|
|
584913
585867
|
}
|
|
584914
585868
|
function getBundledSkillExtractDir(skillName) {
|
|
584915
|
-
return
|
|
585869
|
+
return join178(getBundledSkillsRoot(), skillName);
|
|
584916
585870
|
}
|
|
584917
585871
|
async function extractBundledSkillFiles(skillName, files2) {
|
|
584918
585872
|
const dir = getBundledSkillExtractDir(skillName);
|
|
@@ -584954,7 +585908,7 @@ function resolveSkillFilePath(baseDir, relPath) {
|
|
|
584954
585908
|
if (isAbsolute30(normalized) || normalized.split(pathSep2).includes("..") || normalized.split("/").includes("..")) {
|
|
584955
585909
|
throw new Error(`bundled skill file path escapes skill dir: ${relPath}`);
|
|
584956
585910
|
}
|
|
584957
|
-
return
|
|
585911
|
+
return join178(baseDir, normalized);
|
|
584958
585912
|
}
|
|
584959
585913
|
function prependBaseDir(blocks, baseDir) {
|
|
584960
585914
|
const prefix = `Base directory for this skill: ${baseDir}
|
|
@@ -585315,7 +586269,7 @@ var init_exit2 = __esm(() => {
|
|
|
585315
586269
|
});
|
|
585316
586270
|
|
|
585317
586271
|
// src/components/ExportDialog.tsx
|
|
585318
|
-
import { join as
|
|
586272
|
+
import { join as join179 } from "path";
|
|
585319
586273
|
function ExportDialog({
|
|
585320
586274
|
content,
|
|
585321
586275
|
defaultFilename,
|
|
@@ -585348,7 +586302,7 @@ function ExportDialog({
|
|
|
585348
586302
|
};
|
|
585349
586303
|
const handleFilenameSubmit = () => {
|
|
585350
586304
|
const finalFilename = filename.endsWith(".txt") ? filename : filename.replace(/\.[^.]+$/, "") + ".txt";
|
|
585351
|
-
const filepath =
|
|
586305
|
+
const filepath = join179(getCwd(), finalFilename);
|
|
585352
586306
|
try {
|
|
585353
586307
|
writeFileSync_DEPRECATED(filepath, content, {
|
|
585354
586308
|
encoding: "utf-8",
|
|
@@ -585571,7 +586525,7 @@ __export(exports_export, {
|
|
|
585571
586525
|
extractFirstPrompt: () => extractFirstPrompt,
|
|
585572
586526
|
call: () => call138
|
|
585573
586527
|
});
|
|
585574
|
-
import { join as
|
|
586528
|
+
import { join as join180 } from "path";
|
|
585575
586529
|
function formatTimestamp(date6) {
|
|
585576
586530
|
const year = date6.getFullYear();
|
|
585577
586531
|
const month = String(date6.getMonth() + 1).padStart(2, "0");
|
|
@@ -585615,7 +586569,7 @@ async function call138(onDone, context4, args) {
|
|
|
585615
586569
|
const filename = args.trim();
|
|
585616
586570
|
if (filename) {
|
|
585617
586571
|
const finalFilename = filename.endsWith(".txt") ? filename : filename.replace(/\.[^.]+$/, "") + ".txt";
|
|
585618
|
-
const filepath =
|
|
586572
|
+
const filepath = join180(getCwd(), finalFilename);
|
|
585619
586573
|
try {
|
|
585620
586574
|
writeFileSync_DEPRECATED(filepath, content, {
|
|
585621
586575
|
encoding: "utf-8",
|
|
@@ -587463,7 +588417,7 @@ var require_asciichart = __commonJS((exports) => {
|
|
|
587463
588417
|
// src/utils/statsCache.ts
|
|
587464
588418
|
import { randomBytes as randomBytes17 } from "crypto";
|
|
587465
588419
|
import { open as open14 } from "fs/promises";
|
|
587466
|
-
import { join as
|
|
588420
|
+
import { join as join181 } from "path";
|
|
587467
588421
|
async function withStatsCacheLock(fn) {
|
|
587468
588422
|
while (statsCacheLockPromise) {
|
|
587469
588423
|
await statsCacheLockPromise;
|
|
@@ -587480,7 +588434,7 @@ async function withStatsCacheLock(fn) {
|
|
|
587480
588434
|
}
|
|
587481
588435
|
}
|
|
587482
588436
|
function getStatsCachePath() {
|
|
587483
|
-
return
|
|
588437
|
+
return join181(getURConfigHomeDir(), STATS_CACHE_FILENAME);
|
|
587484
588438
|
}
|
|
587485
588439
|
function getEmptyCache() {
|
|
587486
588440
|
return {
|
|
@@ -588148,12 +589102,12 @@ var init_ansiToPng = __esm(() => {
|
|
|
588148
589102
|
// src/utils/screenshotClipboard.ts
|
|
588149
589103
|
import { mkdir as mkdir38, unlink as unlink20, writeFile as writeFile42 } from "fs/promises";
|
|
588150
589104
|
import { tmpdir as tmpdir9 } from "os";
|
|
588151
|
-
import { join as
|
|
589105
|
+
import { join as join182 } from "path";
|
|
588152
589106
|
async function copyAnsiToClipboard(ansiText, options2) {
|
|
588153
589107
|
try {
|
|
588154
|
-
const tempDir =
|
|
589108
|
+
const tempDir = join182(tmpdir9(), "ur-screenshots");
|
|
588155
589109
|
await mkdir38(tempDir, { recursive: true });
|
|
588156
|
-
const pngPath =
|
|
589110
|
+
const pngPath = join182(tempDir, `screenshot-${Date.now()}.png`);
|
|
588157
589111
|
const pngBuffer = ansiToPng(ansiText, options2);
|
|
588158
589112
|
await writeFile42(pngPath, pngBuffer);
|
|
588159
589113
|
const result = await copyPngToClipboard(pngPath);
|
|
@@ -588224,7 +589178,7 @@ var init_screenshotClipboard = __esm(() => {
|
|
|
588224
589178
|
|
|
588225
589179
|
// src/utils/stats.ts
|
|
588226
589180
|
import { open as open15 } from "fs/promises";
|
|
588227
|
-
import { basename as basename41, join as
|
|
589181
|
+
import { basename as basename41, join as join183, sep as sep33 } from "path";
|
|
588228
589182
|
async function processSessionFiles(sessionFiles, options2 = {}) {
|
|
588229
589183
|
const { fromDate, toDate } = options2;
|
|
588230
589184
|
const fs12 = getFsImplementation();
|
|
@@ -588402,17 +589356,17 @@ async function getAllSessionFiles() {
|
|
|
588402
589356
|
return [];
|
|
588403
589357
|
throw e;
|
|
588404
589358
|
}
|
|
588405
|
-
const projectDirs = allEntries.filter((dirent) => dirent.isDirectory()).map((dirent) =>
|
|
589359
|
+
const projectDirs = allEntries.filter((dirent) => dirent.isDirectory()).map((dirent) => join183(projectsDir, dirent.name));
|
|
588406
589360
|
const projectResults = await Promise.all(projectDirs.map(async (projectDir) => {
|
|
588407
589361
|
try {
|
|
588408
589362
|
const entries = await fs12.readdir(projectDir);
|
|
588409
|
-
const mainFiles = entries.filter((dirent) => dirent.isFile() && dirent.name.endsWith(".jsonl")).map((dirent) =>
|
|
589363
|
+
const mainFiles = entries.filter((dirent) => dirent.isFile() && dirent.name.endsWith(".jsonl")).map((dirent) => join183(projectDir, dirent.name));
|
|
588410
589364
|
const sessionDirs = entries.filter((dirent) => dirent.isDirectory());
|
|
588411
589365
|
const subagentResults = await Promise.all(sessionDirs.map(async (sessionDir) => {
|
|
588412
|
-
const subagentsDir =
|
|
589366
|
+
const subagentsDir = join183(projectDir, sessionDir.name, "subagents");
|
|
588413
589367
|
try {
|
|
588414
589368
|
const subagentEntries = await fs12.readdir(subagentsDir);
|
|
588415
|
-
return subagentEntries.filter((dirent) => dirent.isFile() && dirent.name.endsWith(".jsonl") && dirent.name.startsWith("agent-")).map((dirent) =>
|
|
589369
|
+
return subagentEntries.filter((dirent) => dirent.isFile() && dirent.name.endsWith(".jsonl") && dirent.name.startsWith("agent-")).map((dirent) => join183(subagentsDir, dirent.name));
|
|
588416
589370
|
} catch {
|
|
588417
589371
|
return [];
|
|
588418
589372
|
}
|
|
@@ -590410,7 +591364,7 @@ import {
|
|
|
590410
591364
|
writeFile as writeFile43
|
|
590411
591365
|
} from "fs/promises";
|
|
590412
591366
|
import { tmpdir as tmpdir10 } from "os";
|
|
590413
|
-
import { extname as extname18, join as
|
|
591367
|
+
import { extname as extname18, join as join184 } from "path";
|
|
590414
591368
|
function getAnalysisModel() {
|
|
590415
591369
|
return getDefaultmodelOModel();
|
|
590416
591370
|
}
|
|
@@ -590418,13 +591372,13 @@ function getInsightsModel() {
|
|
|
590418
591372
|
return getDefaultmodelOModel();
|
|
590419
591373
|
}
|
|
590420
591374
|
function getDataDir() {
|
|
590421
|
-
return
|
|
591375
|
+
return join184(getURConfigHomeDir(), "usage-data");
|
|
590422
591376
|
}
|
|
590423
591377
|
function getFacetsDir() {
|
|
590424
|
-
return
|
|
591378
|
+
return join184(getDataDir(), "facets");
|
|
590425
591379
|
}
|
|
590426
591380
|
function getSessionMetaDir() {
|
|
590427
|
-
return
|
|
591381
|
+
return join184(getDataDir(), "session-meta");
|
|
590428
591382
|
}
|
|
590429
591383
|
function getLanguageFromPath(filePath) {
|
|
590430
591384
|
const ext = extname18(filePath).toLowerCase();
|
|
@@ -590769,7 +591723,7 @@ async function formatTranscriptWithSummarization(log) {
|
|
|
590769
591723
|
`);
|
|
590770
591724
|
}
|
|
590771
591725
|
async function loadCachedFacets(sessionId) {
|
|
590772
|
-
const facetPath =
|
|
591726
|
+
const facetPath = join184(getFacetsDir(), `${sessionId}.json`);
|
|
590773
591727
|
try {
|
|
590774
591728
|
const content = await readFile49(facetPath, { encoding: "utf-8" });
|
|
590775
591729
|
const parsed = jsonParse(content);
|
|
@@ -590788,14 +591742,14 @@ async function saveFacets(facets) {
|
|
|
590788
591742
|
try {
|
|
590789
591743
|
await mkdir39(getFacetsDir(), { recursive: true });
|
|
590790
591744
|
} catch {}
|
|
590791
|
-
const facetPath =
|
|
591745
|
+
const facetPath = join184(getFacetsDir(), `${facets.session_id}.json`);
|
|
590792
591746
|
await writeFile43(facetPath, jsonStringify(facets, null, 2), {
|
|
590793
591747
|
encoding: "utf-8",
|
|
590794
591748
|
mode: 384
|
|
590795
591749
|
});
|
|
590796
591750
|
}
|
|
590797
591751
|
async function loadCachedSessionMeta(sessionId) {
|
|
590798
|
-
const metaPath2 =
|
|
591752
|
+
const metaPath2 = join184(getSessionMetaDir(), `${sessionId}.json`);
|
|
590799
591753
|
try {
|
|
590800
591754
|
const content = await readFile49(metaPath2, { encoding: "utf-8" });
|
|
590801
591755
|
return jsonParse(content);
|
|
@@ -590807,7 +591761,7 @@ async function saveSessionMeta(meta) {
|
|
|
590807
591761
|
try {
|
|
590808
591762
|
await mkdir39(getSessionMetaDir(), { recursive: true });
|
|
590809
591763
|
} catch {}
|
|
590810
|
-
const metaPath2 =
|
|
591764
|
+
const metaPath2 = join184(getSessionMetaDir(), `${meta.session_id}.json`);
|
|
590811
591765
|
await writeFile43(metaPath2, jsonStringify(meta, null, 2), {
|
|
590812
591766
|
encoding: "utf-8",
|
|
590813
591767
|
mode: 384
|
|
@@ -591864,7 +592818,7 @@ function generateHtmlReport(data, insights) {
|
|
|
591864
592818
|
</html>`;
|
|
591865
592819
|
}
|
|
591866
592820
|
function buildExportData(data, insights, facets, remoteStats) {
|
|
591867
|
-
const version3 = typeof MACRO !== "undefined" ? "1.22.
|
|
592821
|
+
const version3 = typeof MACRO !== "undefined" ? "1.22.1" : "unknown";
|
|
591868
592822
|
const remote_hosts_collected = remoteStats?.hosts.filter((h2) => h2.sessionCount > 0).map((h2) => h2.name);
|
|
591869
592823
|
const facets_summary = {
|
|
591870
592824
|
total: facets.size,
|
|
@@ -591915,7 +592869,7 @@ async function scanAllSessions() {
|
|
|
591915
592869
|
} catch {
|
|
591916
592870
|
return [];
|
|
591917
592871
|
}
|
|
591918
|
-
const projectDirs = dirents.filter((dirent) => dirent.isDirectory()).map((dirent) =>
|
|
592872
|
+
const projectDirs = dirents.filter((dirent) => dirent.isDirectory()).map((dirent) => join184(projectsDir, dirent.name));
|
|
591919
592873
|
const allSessions = [];
|
|
591920
592874
|
for (let i3 = 0;i3 < projectDirs.length; i3++) {
|
|
591921
592875
|
const sessionFiles = await getSessionFilesWithMtime(projectDirs[i3]);
|
|
@@ -591937,7 +592891,7 @@ async function scanAllSessions() {
|
|
|
591937
592891
|
async function generateUsageReport(options2) {
|
|
591938
592892
|
let remoteStats;
|
|
591939
592893
|
if (process.env.USER_TYPE === "ant" && options2?.collectRemote) {
|
|
591940
|
-
const destDir =
|
|
592894
|
+
const destDir = join184(getURConfigHomeDir(), "projects");
|
|
591941
592895
|
const { hosts, totalCopied } = await collectAllRemoteHostData(destDir);
|
|
591942
592896
|
remoteStats = { hosts, totalCopied };
|
|
591943
592897
|
}
|
|
@@ -592076,7 +593030,7 @@ async function generateUsageReport(options2) {
|
|
|
592076
593030
|
try {
|
|
592077
593031
|
await mkdir39(getDataDir(), { recursive: true });
|
|
592078
593032
|
} catch {}
|
|
592079
|
-
const htmlPath =
|
|
593033
|
+
const htmlPath = join184(getDataDir(), "report.html");
|
|
592080
593034
|
await writeFile43(htmlPath, htmlReport, {
|
|
592081
593035
|
encoding: "utf-8",
|
|
592082
593036
|
mode: 384
|
|
@@ -592172,13 +593126,13 @@ var init_insights = __esm(() => {
|
|
|
592172
593126
|
} : async () => 0;
|
|
592173
593127
|
collectFromRemoteHost = process.env.USER_TYPE === "ant" ? async (homespace, destDir) => {
|
|
592174
593128
|
const result = { copied: 0, skipped: 0 };
|
|
592175
|
-
const tempDir = await mkdtemp(
|
|
593129
|
+
const tempDir = await mkdtemp(join184(tmpdir10(), "ur-hs-"));
|
|
592176
593130
|
try {
|
|
592177
593131
|
const scpResult = await execFileNoThrow("scp", ["-rq", `${homespace}.coder:/root/.ur/projects/`, tempDir], { timeout: 300000 });
|
|
592178
593132
|
if (scpResult.code !== 0) {
|
|
592179
593133
|
return result;
|
|
592180
593134
|
}
|
|
592181
|
-
const projectsDir =
|
|
593135
|
+
const projectsDir = join184(tempDir, "projects");
|
|
592182
593136
|
let projectDirents;
|
|
592183
593137
|
try {
|
|
592184
593138
|
projectDirents = await readdir28(projectsDir, { withFileTypes: true });
|
|
@@ -592187,11 +593141,11 @@ var init_insights = __esm(() => {
|
|
|
592187
593141
|
}
|
|
592188
593142
|
await Promise.all(projectDirents.map(async (dirent) => {
|
|
592189
593143
|
const projectName = dirent.name;
|
|
592190
|
-
const projectPath =
|
|
593144
|
+
const projectPath = join184(projectsDir, projectName);
|
|
592191
593145
|
if (!dirent.isDirectory())
|
|
592192
593146
|
return;
|
|
592193
593147
|
const destProjectName = `${projectName}__${homespace}`;
|
|
592194
|
-
const destProjectPath =
|
|
593148
|
+
const destProjectPath = join184(destDir, destProjectName);
|
|
592195
593149
|
try {
|
|
592196
593150
|
await mkdir39(destProjectPath, { recursive: true });
|
|
592197
593151
|
} catch {}
|
|
@@ -592205,8 +593159,8 @@ var init_insights = __esm(() => {
|
|
|
592205
593159
|
const fileName = fileDirent.name;
|
|
592206
593160
|
if (!fileName.endsWith(".jsonl"))
|
|
592207
593161
|
return;
|
|
592208
|
-
const srcFile =
|
|
592209
|
-
const destFile =
|
|
593162
|
+
const srcFile = join184(projectPath, fileName);
|
|
593163
|
+
const destFile = join184(destProjectPath, fileName);
|
|
592210
593164
|
try {
|
|
592211
593165
|
await copyFile9(srcFile, destFile, fsConstants6.COPYFILE_EXCL);
|
|
592212
593166
|
result.copied++;
|
|
@@ -593302,7 +594256,7 @@ import {
|
|
|
593302
594256
|
unlink as unlink22,
|
|
593303
594257
|
writeFile as writeFile44
|
|
593304
594258
|
} from "fs/promises";
|
|
593305
|
-
import { basename as basename42, dirname as dirname65, join as
|
|
594259
|
+
import { basename as basename42, dirname as dirname65, join as join185 } from "path";
|
|
593306
594260
|
function isTranscriptMessage(entry) {
|
|
593307
594261
|
const t = entry.type;
|
|
593308
594262
|
return t === "user" || t === "assistant" || t === "attachment" || t === "system";
|
|
@@ -593317,18 +594271,18 @@ function isEphemeralToolProgress(dataType) {
|
|
|
593317
594271
|
return typeof dataType === "string" && EPHEMERAL_PROGRESS_TYPES.has(dataType);
|
|
593318
594272
|
}
|
|
593319
594273
|
function getProjectsDir2() {
|
|
593320
|
-
return
|
|
594274
|
+
return join185(getURConfigHomeDir(), "projects");
|
|
593321
594275
|
}
|
|
593322
594276
|
function getTranscriptPath() {
|
|
593323
594277
|
const projectDir = getSessionProjectDir() ?? getProjectDir2(getOriginalCwd());
|
|
593324
|
-
return
|
|
594278
|
+
return join185(projectDir, `${getSessionId()}.jsonl`);
|
|
593325
594279
|
}
|
|
593326
594280
|
function getTranscriptPathForSession(sessionId) {
|
|
593327
594281
|
if (sessionId === getSessionId()) {
|
|
593328
594282
|
return getTranscriptPath();
|
|
593329
594283
|
}
|
|
593330
594284
|
const projectDir = getProjectDir2(getOriginalCwd());
|
|
593331
|
-
return
|
|
594285
|
+
return join185(projectDir, `${sessionId}.jsonl`);
|
|
593332
594286
|
}
|
|
593333
594287
|
function setAgentTranscriptSubdir(agentId, subdir) {
|
|
593334
594288
|
agentTranscriptSubdirs.set(agentId, subdir);
|
|
@@ -593340,8 +594294,8 @@ function getAgentTranscriptPath(agentId) {
|
|
|
593340
594294
|
const projectDir = getSessionProjectDir() ?? getProjectDir2(getOriginalCwd());
|
|
593341
594295
|
const sessionId = getSessionId();
|
|
593342
594296
|
const subdir = agentTranscriptSubdirs.get(agentId);
|
|
593343
|
-
const base2 = subdir ?
|
|
593344
|
-
return
|
|
594297
|
+
const base2 = subdir ? join185(projectDir, sessionId, "subagents", subdir) : join185(projectDir, sessionId, "subagents");
|
|
594298
|
+
return join185(base2, `agent-${agentId}.jsonl`);
|
|
593345
594299
|
}
|
|
593346
594300
|
function getAgentMetadataPath(agentId) {
|
|
593347
594301
|
return getAgentTranscriptPath(agentId).replace(/\.jsonl$/, ".meta.json");
|
|
@@ -593364,10 +594318,10 @@ async function readAgentMetadata(agentId) {
|
|
|
593364
594318
|
}
|
|
593365
594319
|
function getRemoteAgentsDir() {
|
|
593366
594320
|
const projectDir = getSessionProjectDir() ?? getProjectDir2(getOriginalCwd());
|
|
593367
|
-
return
|
|
594321
|
+
return join185(projectDir, getSessionId(), "remote-agents");
|
|
593368
594322
|
}
|
|
593369
594323
|
function getRemoteAgentMetadataPath(taskId) {
|
|
593370
|
-
return
|
|
594324
|
+
return join185(getRemoteAgentsDir(), `remote-agent-${taskId}.meta.json`);
|
|
593371
594325
|
}
|
|
593372
594326
|
async function writeRemoteAgentMetadata(taskId, metadata) {
|
|
593373
594327
|
const path22 = getRemoteAgentMetadataPath(taskId);
|
|
@@ -593410,7 +594364,7 @@ async function listRemoteAgentMetadata() {
|
|
|
593410
594364
|
if (!entry.isFile() || !entry.name.endsWith(".meta.json"))
|
|
593411
594365
|
continue;
|
|
593412
594366
|
try {
|
|
593413
|
-
const raw = await readFile50(
|
|
594367
|
+
const raw = await readFile50(join185(dir, entry.name), "utf-8");
|
|
593414
594368
|
results.push(JSON.parse(raw));
|
|
593415
594369
|
} catch (e) {
|
|
593416
594370
|
logForDebugging(`listRemoteAgentMetadata: skipping ${entry.name}: ${String(e)}`);
|
|
@@ -593420,7 +594374,7 @@ async function listRemoteAgentMetadata() {
|
|
|
593420
594374
|
}
|
|
593421
594375
|
function sessionIdExists(sessionId) {
|
|
593422
594376
|
const projectDir = getProjectDir2(getOriginalCwd());
|
|
593423
|
-
const sessionFile =
|
|
594377
|
+
const sessionFile = join185(projectDir, `${sessionId}.jsonl`);
|
|
593424
594378
|
const fs12 = getFsImplementation();
|
|
593425
594379
|
try {
|
|
593426
594380
|
fs12.statSync(sessionFile);
|
|
@@ -595394,7 +596348,7 @@ async function loadTranscriptFile(filePath, opts) {
|
|
|
595394
596348
|
};
|
|
595395
596349
|
}
|
|
595396
596350
|
async function loadSessionFile(sessionId) {
|
|
595397
|
-
const sessionFile =
|
|
596351
|
+
const sessionFile = join185(getSessionProjectDir() ?? getProjectDir2(getOriginalCwd()), `${sessionId}.jsonl`);
|
|
595398
596352
|
return loadTranscriptFile(sessionFile);
|
|
595399
596353
|
}
|
|
595400
596354
|
function clearSessionMessagesCache() {
|
|
@@ -595462,7 +596416,7 @@ async function loadAllProjectsMessageLogsFull(limit) {
|
|
|
595462
596416
|
} catch {
|
|
595463
596417
|
return [];
|
|
595464
596418
|
}
|
|
595465
|
-
const projectDirs = dirents.filter((dirent) => dirent.isDirectory()).map((dirent) =>
|
|
596419
|
+
const projectDirs = dirents.filter((dirent) => dirent.isDirectory()).map((dirent) => join185(projectsDir, dirent.name));
|
|
595466
596420
|
const logsPerProject = await Promise.all(projectDirs.map((projectDir) => getLogsWithoutIndex(projectDir, limit)));
|
|
595467
596421
|
const allLogs = logsPerProject.flat();
|
|
595468
596422
|
const deduped = new Map;
|
|
@@ -595487,7 +596441,7 @@ async function loadAllProjectsMessageLogsProgressive(limit, initialEnrichCount =
|
|
|
595487
596441
|
} catch {
|
|
595488
596442
|
return { logs: [], allStatLogs: [], nextIndex: 0 };
|
|
595489
596443
|
}
|
|
595490
|
-
const projectDirs = dirents.filter((dirent) => dirent.isDirectory()).map((dirent) =>
|
|
596444
|
+
const projectDirs = dirents.filter((dirent) => dirent.isDirectory()).map((dirent) => join185(projectsDir, dirent.name));
|
|
595491
596445
|
const rawLogs = [];
|
|
595492
596446
|
for (const projectDir of projectDirs) {
|
|
595493
596447
|
rawLogs.push(...await getSessionFilesLite(projectDir, limit));
|
|
@@ -595548,7 +596502,7 @@ async function getStatOnlyLogsForWorktrees(worktreePaths, limit) {
|
|
|
595548
596502
|
for (const { path: wtPath, prefix } of indexed) {
|
|
595549
596503
|
if (dirName === prefix || dirName.startsWith(prefix + "-")) {
|
|
595550
596504
|
seenDirs.add(dirName);
|
|
595551
|
-
allLogs.push(...await getSessionFilesLite(
|
|
596505
|
+
allLogs.push(...await getSessionFilesLite(join185(projectsDir, dirent.name), undefined, wtPath));
|
|
595552
596506
|
break;
|
|
595553
596507
|
}
|
|
595554
596508
|
}
|
|
@@ -595617,7 +596571,7 @@ async function loadSubagentTranscripts(agentIds) {
|
|
|
595617
596571
|
return transcripts;
|
|
595618
596572
|
}
|
|
595619
596573
|
async function loadAllSubagentTranscriptsFromDisk() {
|
|
595620
|
-
const subagentsDir =
|
|
596574
|
+
const subagentsDir = join185(getSessionProjectDir() ?? getProjectDir2(getOriginalCwd()), getSessionId(), "subagents");
|
|
595621
596575
|
let entries;
|
|
595622
596576
|
try {
|
|
595623
596577
|
entries = await readdir29(subagentsDir, { withFileTypes: true });
|
|
@@ -595745,7 +596699,7 @@ async function getSessionFilesWithMtime(projectDir) {
|
|
|
595745
596699
|
const sessionId = validateUuid2(basename42(dirent.name, ".jsonl"));
|
|
595746
596700
|
if (!sessionId)
|
|
595747
596701
|
continue;
|
|
595748
|
-
candidates2.push({ sessionId, filePath:
|
|
596702
|
+
candidates2.push({ sessionId, filePath: join185(projectDir, dirent.name) });
|
|
595749
596703
|
}
|
|
595750
596704
|
await Promise.all(candidates2.map(async ({ sessionId, filePath }) => {
|
|
595751
596705
|
try {
|
|
@@ -596131,7 +597085,7 @@ var init_sessionStorage = __esm(() => {
|
|
|
596131
597085
|
init_settings2();
|
|
596132
597086
|
init_slowOperations();
|
|
596133
597087
|
init_uuid();
|
|
596134
|
-
VERSION5 = typeof MACRO !== "undefined" ? "1.22.
|
|
597088
|
+
VERSION5 = typeof MACRO !== "undefined" ? "1.22.1" : "unknown";
|
|
596135
597089
|
MAX_TOMBSTONE_REWRITE_BYTES = 50 * 1024 * 1024;
|
|
596136
597090
|
SKIP_FIRST_PROMPT_PATTERN = /^(?:\s*<[a-z][\w-]*[\s>]|\[Request interrupted by user[^\]]*\])/;
|
|
596137
597091
|
EPHEMERAL_PROGRESS_TYPES = new Set([
|
|
@@ -596143,7 +597097,7 @@ var init_sessionStorage = __esm(() => {
|
|
|
596143
597097
|
MAX_TRANSCRIPT_READ_BYTES = 50 * 1024 * 1024;
|
|
596144
597098
|
agentTranscriptSubdirs = new Map;
|
|
596145
597099
|
getProjectDir2 = memoize_default((projectDir) => {
|
|
596146
|
-
return
|
|
597100
|
+
return join185(getProjectsDir2(), sanitizePath2(projectDir));
|
|
596147
597101
|
});
|
|
596148
597102
|
METADATA_TYPE_MARKERS = [
|
|
596149
597103
|
'"type":"summary"',
|
|
@@ -596381,41 +597335,41 @@ var init_memdir = __esm(() => {
|
|
|
596381
597335
|
});
|
|
596382
597336
|
|
|
596383
597337
|
// src/tools/AgentTool/agentMemory.ts
|
|
596384
|
-
import { join as
|
|
597338
|
+
import { join as join186, normalize as normalize14, sep as sep34 } from "path";
|
|
596385
597339
|
function sanitizeAgentTypeForPath(agentType) {
|
|
596386
597340
|
return agentType.replace(/:/g, "-");
|
|
596387
597341
|
}
|
|
596388
597342
|
function getLocalAgentMemoryDir(dirName) {
|
|
596389
597343
|
if (process.env.UR_CODE_REMOTE_MEMORY_DIR) {
|
|
596390
|
-
return
|
|
597344
|
+
return join186(process.env.UR_CODE_REMOTE_MEMORY_DIR, "projects", sanitizePath2(findCanonicalGitRoot(getProjectRoot()) ?? getProjectRoot()), "agent-memory-local", dirName) + sep34;
|
|
596391
597345
|
}
|
|
596392
|
-
return
|
|
597346
|
+
return join186(getCwd(), ".ur", "agent-memory-local", dirName) + sep34;
|
|
596393
597347
|
}
|
|
596394
597348
|
function getAgentMemoryDir(agentType, scope) {
|
|
596395
597349
|
const dirName = sanitizeAgentTypeForPath(agentType);
|
|
596396
597350
|
switch (scope) {
|
|
596397
597351
|
case "project":
|
|
596398
|
-
return
|
|
597352
|
+
return join186(getCwd(), ".ur", "agent-memory", dirName) + sep34;
|
|
596399
597353
|
case "local":
|
|
596400
597354
|
return getLocalAgentMemoryDir(dirName);
|
|
596401
597355
|
case "user":
|
|
596402
|
-
return
|
|
597356
|
+
return join186(getMemoryBaseDir(), "agent-memory", dirName) + sep34;
|
|
596403
597357
|
}
|
|
596404
597358
|
}
|
|
596405
597359
|
function isAgentMemoryPath(absolutePath) {
|
|
596406
597360
|
const normalizedPath = normalize14(absolutePath);
|
|
596407
597361
|
const memoryBase = getMemoryBaseDir();
|
|
596408
|
-
if (normalizedPath.startsWith(
|
|
597362
|
+
if (normalizedPath.startsWith(join186(memoryBase, "agent-memory") + sep34)) {
|
|
596409
597363
|
return true;
|
|
596410
597364
|
}
|
|
596411
|
-
if (normalizedPath.startsWith(
|
|
597365
|
+
if (normalizedPath.startsWith(join186(getCwd(), ".ur", "agent-memory") + sep34)) {
|
|
596412
597366
|
return true;
|
|
596413
597367
|
}
|
|
596414
597368
|
if (process.env.UR_CODE_REMOTE_MEMORY_DIR) {
|
|
596415
|
-
if (normalizedPath.includes(sep34 + "agent-memory-local" + sep34) && normalizedPath.startsWith(
|
|
597369
|
+
if (normalizedPath.includes(sep34 + "agent-memory-local" + sep34) && normalizedPath.startsWith(join186(process.env.UR_CODE_REMOTE_MEMORY_DIR, "projects") + sep34)) {
|
|
596416
597370
|
return true;
|
|
596417
597371
|
}
|
|
596418
|
-
} else if (normalizedPath.startsWith(
|
|
597372
|
+
} else if (normalizedPath.startsWith(join186(getCwd(), ".ur", "agent-memory-local") + sep34)) {
|
|
596419
597373
|
return true;
|
|
596420
597374
|
}
|
|
596421
597375
|
return false;
|
|
@@ -596423,7 +597377,7 @@ function isAgentMemoryPath(absolutePath) {
|
|
|
596423
597377
|
function getMemoryScopeDisplay(memory2) {
|
|
596424
597378
|
switch (memory2) {
|
|
596425
597379
|
case "user":
|
|
596426
|
-
return `User (${
|
|
597380
|
+
return `User (${join186(getMemoryBaseDir(), "agent-memory")}/)`;
|
|
596427
597381
|
case "project":
|
|
596428
597382
|
return "Project (.ur/agent-memory/)";
|
|
596429
597383
|
case "local":
|
|
@@ -596466,7 +597420,7 @@ var init_agentMemory = __esm(() => {
|
|
|
596466
597420
|
// src/utils/permissions/filesystem.ts
|
|
596467
597421
|
import { randomBytes as randomBytes18 } from "crypto";
|
|
596468
597422
|
import { homedir as homedir32, tmpdir as tmpdir11 } from "os";
|
|
596469
|
-
import { join as
|
|
597423
|
+
import { join as join187, normalize as normalize15, posix as posix9, sep as sep35 } from "path";
|
|
596470
597424
|
function normalizeCaseForComparison(path22) {
|
|
596471
597425
|
return path22.toLowerCase();
|
|
596472
597426
|
}
|
|
@@ -596475,11 +597429,11 @@ function getURSkillScope(filePath) {
|
|
|
596475
597429
|
const absolutePathLower = normalizeCaseForComparison(absolutePath);
|
|
596476
597430
|
const bases = [
|
|
596477
597431
|
{
|
|
596478
|
-
dir: expandPath(
|
|
597432
|
+
dir: expandPath(join187(getOriginalCwd(), ".ur", "skills")),
|
|
596479
597433
|
prefix: "/.ur/skills/"
|
|
596480
597434
|
},
|
|
596481
597435
|
{
|
|
596482
|
-
dir: expandPath(
|
|
597436
|
+
dir: expandPath(join187(homedir32(), ".ur", "skills")),
|
|
596483
597437
|
prefix: "~/.ur/skills/"
|
|
596484
597438
|
}
|
|
596485
597439
|
];
|
|
@@ -596534,21 +597488,21 @@ function isURConfigFilePath(filePath) {
|
|
|
596534
597488
|
if (isURSettingsPath(filePath)) {
|
|
596535
597489
|
return true;
|
|
596536
597490
|
}
|
|
596537
|
-
const commandsDir =
|
|
596538
|
-
const agentsDir =
|
|
596539
|
-
const skillsDir =
|
|
597491
|
+
const commandsDir = join187(getOriginalCwd(), ".ur", "commands");
|
|
597492
|
+
const agentsDir = join187(getOriginalCwd(), ".ur", "agents");
|
|
597493
|
+
const skillsDir = join187(getOriginalCwd(), ".ur", "skills");
|
|
596540
597494
|
return pathInWorkingPath(filePath, commandsDir) || pathInWorkingPath(filePath, agentsDir) || pathInWorkingPath(filePath, skillsDir);
|
|
596541
597495
|
}
|
|
596542
597496
|
function isSessionPlanFile(absolutePath) {
|
|
596543
|
-
const expectedPrefix =
|
|
597497
|
+
const expectedPrefix = join187(getPlansDirectory(), getPlanSlug());
|
|
596544
597498
|
const normalizedPath = normalize15(absolutePath);
|
|
596545
597499
|
return normalizedPath.startsWith(expectedPrefix) && normalizedPath.endsWith(".md");
|
|
596546
597500
|
}
|
|
596547
597501
|
function getSessionMemoryDir() {
|
|
596548
|
-
return
|
|
597502
|
+
return join187(getProjectDir2(getCwd()), getSessionId(), "session-memory") + sep35;
|
|
596549
597503
|
}
|
|
596550
597504
|
function getSessionMemoryPath() {
|
|
596551
|
-
return
|
|
597505
|
+
return join187(getSessionMemoryDir(), "summary.md");
|
|
596552
597506
|
}
|
|
596553
597507
|
function isSessionMemoryPath(absolutePath) {
|
|
596554
597508
|
const normalizedPath = normalize15(absolutePath);
|
|
@@ -596570,10 +597524,10 @@ function getURTempDirName() {
|
|
|
596570
597524
|
return `ur-${uid}`;
|
|
596571
597525
|
}
|
|
596572
597526
|
function getProjectTempDir() {
|
|
596573
|
-
return
|
|
597527
|
+
return join187(getURTempDir(), sanitizePath2(getOriginalCwd())) + sep35;
|
|
596574
597528
|
}
|
|
596575
597529
|
function getScratchpadDir() {
|
|
596576
|
-
return
|
|
597530
|
+
return join187(getProjectTempDir(), getSessionId(), "scratchpad");
|
|
596577
597531
|
}
|
|
596578
597532
|
async function ensureScratchpadDir() {
|
|
596579
597533
|
if (!isScratchpadEnabled()) {
|
|
@@ -597151,7 +598105,7 @@ function checkEditableInternalPath(absolutePath, input) {
|
|
|
597151
598105
|
}
|
|
597152
598106
|
};
|
|
597153
598107
|
}
|
|
597154
|
-
if (normalizeCaseForComparison(normalizedPath) === normalizeCaseForComparison(
|
|
598108
|
+
if (normalizeCaseForComparison(normalizedPath) === normalizeCaseForComparison(join187(getOriginalCwd(), ".ur", "launch.json"))) {
|
|
597155
598109
|
return {
|
|
597156
598110
|
behavior: "allow",
|
|
597157
598111
|
updatedInput: input,
|
|
@@ -597248,7 +598202,7 @@ function checkReadableInternalPath(absolutePath, input) {
|
|
|
597248
598202
|
}
|
|
597249
598203
|
};
|
|
597250
598204
|
}
|
|
597251
|
-
const tasksDir =
|
|
598205
|
+
const tasksDir = join187(getURConfigHomeDir(), "tasks") + sep35;
|
|
597252
598206
|
if (normalizedPath === tasksDir.slice(0, -1) || normalizedPath.startsWith(tasksDir)) {
|
|
597253
598207
|
return {
|
|
597254
598208
|
behavior: "allow",
|
|
@@ -597259,7 +598213,7 @@ function checkReadableInternalPath(absolutePath, input) {
|
|
|
597259
598213
|
}
|
|
597260
598214
|
};
|
|
597261
598215
|
}
|
|
597262
|
-
const teamsReadDir =
|
|
598216
|
+
const teamsReadDir = join187(getURConfigHomeDir(), "teams") + sep35;
|
|
597263
598217
|
if (normalizedPath === teamsReadDir.slice(0, -1) || normalizedPath.startsWith(teamsReadDir)) {
|
|
597264
598218
|
return {
|
|
597265
598219
|
behavior: "allow",
|
|
@@ -597332,11 +598286,11 @@ var init_filesystem = __esm(() => {
|
|
|
597332
598286
|
try {
|
|
597333
598287
|
resolvedBaseTmpDir = fs12.realpathSync(baseTmpDir);
|
|
597334
598288
|
} catch {}
|
|
597335
|
-
return
|
|
598289
|
+
return join187(resolvedBaseTmpDir, getURTempDirName()) + sep35;
|
|
597336
598290
|
});
|
|
597337
598291
|
getBundledSkillsRoot = memoize_default(function getBundledSkillsRoot2() {
|
|
597338
598292
|
const nonce = randomBytes18(16).toString("hex");
|
|
597339
|
-
return
|
|
598293
|
+
return join187(getURTempDir(), "bundled-skills", "1.22.1", nonce);
|
|
597340
598294
|
});
|
|
597341
598295
|
getResolvedWorkingDirPaths = memoize_default(getPathsForPermissionCheck);
|
|
597342
598296
|
});
|
|
@@ -597350,10 +598304,10 @@ import {
|
|
|
597350
598304
|
symlink as symlink4,
|
|
597351
598305
|
unlink as unlink23
|
|
597352
598306
|
} from "fs/promises";
|
|
597353
|
-
import { join as
|
|
598307
|
+
import { join as join188 } from "path";
|
|
597354
598308
|
function getTaskOutputDir() {
|
|
597355
598309
|
if (_taskOutputDir === undefined) {
|
|
597356
|
-
_taskOutputDir =
|
|
598310
|
+
_taskOutputDir = join188(getProjectTempDir(), getSessionId(), "tasks");
|
|
597357
598311
|
}
|
|
597358
598312
|
return _taskOutputDir;
|
|
597359
598313
|
}
|
|
@@ -597361,7 +598315,7 @@ async function ensureOutputDir() {
|
|
|
597361
598315
|
await mkdir41(getTaskOutputDir(), { recursive: true });
|
|
597362
598316
|
}
|
|
597363
598317
|
function getTaskOutputPath(taskId) {
|
|
597364
|
-
return
|
|
598318
|
+
return join188(getTaskOutputDir(), `${taskId}.output`);
|
|
597365
598319
|
}
|
|
597366
598320
|
function track(p2) {
|
|
597367
598321
|
_pendingOps.add(p2);
|
|
@@ -601629,7 +602583,7 @@ import {
|
|
|
601629
602583
|
symlink as symlink5,
|
|
601630
602584
|
utimes as utimes2
|
|
601631
602585
|
} from "fs/promises";
|
|
601632
|
-
import { basename as basename44, dirname as dirname66, join as
|
|
602586
|
+
import { basename as basename44, dirname as dirname66, join as join189 } from "path";
|
|
601633
602587
|
function validateWorktreeSlug(slug4) {
|
|
601634
602588
|
if (slug4.length > MAX_WORKTREE_SLUG_LENGTH) {
|
|
601635
602589
|
throw new Error(`Invalid worktree name: must be ${MAX_WORKTREE_SLUG_LENGTH} characters or fewer (got ${slug4.length})`);
|
|
@@ -601652,8 +602606,8 @@ async function symlinkDirectories(repoRootPath, worktreePath, dirsToSymlink) {
|
|
|
601652
602606
|
logForDebugging(`Skipping symlink for "${dir}": path traversal detected`, { level: "warn" });
|
|
601653
602607
|
continue;
|
|
601654
602608
|
}
|
|
601655
|
-
const sourcePath =
|
|
601656
|
-
const destPath =
|
|
602609
|
+
const sourcePath = join189(repoRootPath, dir);
|
|
602610
|
+
const destPath = join189(worktreePath, dir);
|
|
601657
602611
|
try {
|
|
601658
602612
|
await symlink5(sourcePath, destPath, "dir");
|
|
601659
602613
|
logForDebugging(`Symlinked ${dir} from main repository to worktree to avoid disk bloat`);
|
|
@@ -601677,7 +602631,7 @@ function generateTmuxSessionName(repoPath, branch2) {
|
|
|
601677
602631
|
return combined.replace(/[/.]/g, "_");
|
|
601678
602632
|
}
|
|
601679
602633
|
function worktreesDir2(repoRoot) {
|
|
601680
|
-
return
|
|
602634
|
+
return join189(repoRoot, ".ur", "worktrees");
|
|
601681
602635
|
}
|
|
601682
602636
|
function flattenSlug(slug4) {
|
|
601683
602637
|
return slug4.replaceAll("/", "+");
|
|
@@ -601686,7 +602640,7 @@ function worktreeBranchName(slug4) {
|
|
|
601686
602640
|
return `worktree-${flattenSlug(slug4)}`;
|
|
601687
602641
|
}
|
|
601688
602642
|
function worktreePathFor(repoRoot, slug4) {
|
|
601689
|
-
return
|
|
602643
|
+
return join189(worktreesDir2(repoRoot), flattenSlug(slug4));
|
|
601690
602644
|
}
|
|
601691
602645
|
async function getOrCreateWorktree(repoRoot, slug4, options2) {
|
|
601692
602646
|
const worktreePath = worktreePathFor(repoRoot, slug4);
|
|
@@ -601767,7 +602721,7 @@ async function getOrCreateWorktree(repoRoot, slug4, options2) {
|
|
|
601767
602721
|
async function copyWorktreeIncludeFiles(repoRoot, worktreePath) {
|
|
601768
602722
|
let includeContent;
|
|
601769
602723
|
try {
|
|
601770
|
-
includeContent = await readFile51(
|
|
602724
|
+
includeContent = await readFile51(join189(repoRoot, ".worktreeinclude"), "utf-8");
|
|
601771
602725
|
} catch {
|
|
601772
602726
|
return [];
|
|
601773
602727
|
}
|
|
@@ -601822,8 +602776,8 @@ async function copyWorktreeIncludeFiles(repoRoot, worktreePath) {
|
|
|
601822
602776
|
}
|
|
601823
602777
|
const copied = [];
|
|
601824
602778
|
for (const relativePath2 of files2) {
|
|
601825
|
-
const srcPath =
|
|
601826
|
-
const destPath =
|
|
602779
|
+
const srcPath = join189(repoRoot, relativePath2);
|
|
602780
|
+
const destPath = join189(worktreePath, relativePath2);
|
|
601827
602781
|
try {
|
|
601828
602782
|
await mkdir42(dirname66(destPath), { recursive: true });
|
|
601829
602783
|
await copyFile10(srcPath, destPath);
|
|
@@ -601839,9 +602793,9 @@ async function copyWorktreeIncludeFiles(repoRoot, worktreePath) {
|
|
|
601839
602793
|
}
|
|
601840
602794
|
async function performPostCreationSetup(repoRoot, worktreePath) {
|
|
601841
602795
|
const localSettingsRelativePath = getRelativeSettingsFilePathForSource("localSettings");
|
|
601842
|
-
const sourceSettingsLocal =
|
|
602796
|
+
const sourceSettingsLocal = join189(repoRoot, localSettingsRelativePath);
|
|
601843
602797
|
try {
|
|
601844
|
-
const destSettingsLocal =
|
|
602798
|
+
const destSettingsLocal = join189(worktreePath, localSettingsRelativePath);
|
|
601845
602799
|
await mkdirRecursive(dirname66(destSettingsLocal));
|
|
601846
602800
|
await copyFile10(sourceSettingsLocal, destSettingsLocal);
|
|
601847
602801
|
logForDebugging(`Copied settings.local.json to worktree: ${destSettingsLocal}`);
|
|
@@ -601851,8 +602805,8 @@ async function performPostCreationSetup(repoRoot, worktreePath) {
|
|
|
601851
602805
|
logForDebugging(`Failed to copy settings.local.json: ${e.message}`, { level: "warn" });
|
|
601852
602806
|
}
|
|
601853
602807
|
}
|
|
601854
|
-
const huskyPath =
|
|
601855
|
-
const gitHooksPath =
|
|
602808
|
+
const huskyPath = join189(repoRoot, ".husky");
|
|
602809
|
+
const gitHooksPath = join189(repoRoot, ".git", "hooks");
|
|
601856
602810
|
let hooksPath = null;
|
|
601857
602811
|
for (const candidatePath of [huskyPath, gitHooksPath]) {
|
|
601858
602812
|
try {
|
|
@@ -602127,7 +603081,7 @@ async function cleanupStaleAgentWorktrees(cutoffDate) {
|
|
|
602127
603081
|
if (!EPHEMERAL_WORKTREE_PATTERNS.some((p2) => p2.test(slug4))) {
|
|
602128
603082
|
continue;
|
|
602129
603083
|
}
|
|
602130
|
-
const worktreePath =
|
|
603084
|
+
const worktreePath = join189(dir, slug4);
|
|
602131
603085
|
if (currentPath === worktreePath) {
|
|
602132
603086
|
continue;
|
|
602133
603087
|
}
|
|
@@ -603367,7 +604321,7 @@ function computeFingerprint(messageText, version3) {
|
|
|
603367
604321
|
}
|
|
603368
604322
|
function computeFingerprintFromMessages(messages) {
|
|
603369
604323
|
const firstMessageText = extractFirstMessageText(messages);
|
|
603370
|
-
return computeFingerprint(firstMessageText, "1.22.
|
|
604324
|
+
return computeFingerprint(firstMessageText, "1.22.1");
|
|
603371
604325
|
}
|
|
603372
604326
|
var FINGERPRINT_SALT = "59cf53e54c78";
|
|
603373
604327
|
var init_fingerprint = () => {};
|
|
@@ -605233,7 +606187,7 @@ async function sideQuery(opts) {
|
|
|
605233
606187
|
betas.push(STRUCTURED_OUTPUTS_BETA_HEADER);
|
|
605234
606188
|
}
|
|
605235
606189
|
const messageText = extractFirstUserMessageText(messages);
|
|
605236
|
-
const fingerprint = computeFingerprint(messageText, "1.22.
|
|
606190
|
+
const fingerprint = computeFingerprint(messageText, "1.22.1");
|
|
605237
606191
|
const attributionHeader = getAttributionHeader(fingerprint);
|
|
605238
606192
|
const systemBlocks = [
|
|
605239
606193
|
attributionHeader ? { type: "text", text: attributionHeader } : null,
|
|
@@ -605519,7 +606473,7 @@ import {
|
|
|
605519
606473
|
} from "fs/promises";
|
|
605520
606474
|
import { createServer as createServer5 } from "net";
|
|
605521
606475
|
import { homedir as homedir33, platform as platform6 } from "os";
|
|
605522
|
-
import { join as
|
|
606476
|
+
import { join as join190 } from "path";
|
|
605523
606477
|
function log(message, ...args) {
|
|
605524
606478
|
if (LOG_FILE) {
|
|
605525
606479
|
const timestamp2 = new Date().toISOString();
|
|
@@ -605586,7 +606540,7 @@ class ChromeNativeHost {
|
|
|
605586
606540
|
try {
|
|
605587
606541
|
process.kill(pid, 0);
|
|
605588
606542
|
} catch {
|
|
605589
|
-
await unlink24(
|
|
606543
|
+
await unlink24(join190(socketDir, file4)).catch(() => {});
|
|
605590
606544
|
log(`Removed stale socket for PID ${pid}`);
|
|
605591
606545
|
}
|
|
605592
606546
|
}
|
|
@@ -605857,7 +606811,7 @@ var init_chromeNativeHost = __esm(() => {
|
|
|
605857
606811
|
init_slowOperations();
|
|
605858
606812
|
init_common2();
|
|
605859
606813
|
MAX_MESSAGE_SIZE = 1024 * 1024;
|
|
605860
|
-
LOG_FILE = process.env.USER_TYPE === "ant" ?
|
|
606814
|
+
LOG_FILE = process.env.USER_TYPE === "ant" ? join190(homedir33(), ".ur", "debug", "chrome-native-host.txt") : undefined;
|
|
605861
606815
|
messageSchema = lazySchema(() => exports_external2.object({
|
|
605862
606816
|
type: exports_external2.string()
|
|
605863
606817
|
}).passthrough());
|
|
@@ -608367,7 +609321,7 @@ __export(exports_upstreamproxy, {
|
|
|
608367
609321
|
});
|
|
608368
609322
|
import { mkdir as mkdir44, readFile as readFile52, unlink as unlink25, writeFile as writeFile45 } from "fs/promises";
|
|
608369
609323
|
import { homedir as homedir34 } from "os";
|
|
608370
|
-
import { join as
|
|
609324
|
+
import { join as join191 } from "path";
|
|
608371
609325
|
async function initUpstreamProxy(opts) {
|
|
608372
609326
|
if (!isEnvTruthy(process.env.UR_CODE_REMOTE)) {
|
|
608373
609327
|
return state;
|
|
@@ -608388,7 +609342,7 @@ async function initUpstreamProxy(opts) {
|
|
|
608388
609342
|
}
|
|
608389
609343
|
setNonDumpable();
|
|
608390
609344
|
const baseUrl = opts?.ccrBaseUrl ?? "";
|
|
608391
|
-
const caBundlePath = opts?.caBundlePath ??
|
|
609345
|
+
const caBundlePath = opts?.caBundlePath ?? join191(homedir34(), ".ccr", "ca-bundle.crt");
|
|
608392
609346
|
const caOk = await downloadCaBundle(baseUrl, opts?.systemCaPath ?? SYSTEM_CA_BUNDLE, caBundlePath);
|
|
608393
609347
|
if (!caOk)
|
|
608394
609348
|
return state;
|
|
@@ -608488,7 +609442,7 @@ async function downloadCaBundle(baseUrl, systemCaPath, outPath) {
|
|
|
608488
609442
|
}
|
|
608489
609443
|
const ccrCa = await resp.text();
|
|
608490
609444
|
const systemCa = await readFile52(systemCaPath, "utf8").catch(() => "");
|
|
608491
|
-
await mkdir44(
|
|
609445
|
+
await mkdir44(join191(outPath, ".."), { recursive: true });
|
|
608492
609446
|
await writeFile45(outPath, systemCa + `
|
|
608493
609447
|
` + ccrCa, "utf8");
|
|
608494
609448
|
return true;
|
|
@@ -609970,7 +610924,7 @@ function buildSystemInitMessage(inputs) {
|
|
|
609970
610924
|
slash_commands: inputs.commands.filter((c4) => c4.userInvocable !== false).map((c4) => c4.name),
|
|
609971
610925
|
apiKeySource: getURHQApiKeyWithSource().source,
|
|
609972
610926
|
betas: getSdkBetas(),
|
|
609973
|
-
ur_version: "1.22.
|
|
610927
|
+
ur_version: "1.22.1",
|
|
609974
610928
|
output_style: outputStyle2,
|
|
609975
610929
|
agents: inputs.agents.map((agent) => agent.agentType),
|
|
609976
610930
|
skills: inputs.skills.filter((s) => s.userInvocable !== false).map((skill) => skill.name),
|
|
@@ -616350,7 +617304,7 @@ var init_ShowInIDEPrompt = __esm(() => {
|
|
|
616350
617304
|
|
|
616351
617305
|
// src/components/permissions/FilePermissionDialog/permissionOptions.tsx
|
|
616352
617306
|
import { homedir as homedir35 } from "os";
|
|
616353
|
-
import { basename as basename48, join as
|
|
617307
|
+
import { basename as basename48, join as join192, sep as sep36 } from "path";
|
|
616354
617308
|
function isInURFolder(filePath) {
|
|
616355
617309
|
const absolutePath = expandPath(filePath);
|
|
616356
617310
|
const urFolderPath = expandPath(`${getOriginalCwd()}/.ur`);
|
|
@@ -616360,7 +617314,7 @@ function isInURFolder(filePath) {
|
|
|
616360
617314
|
}
|
|
616361
617315
|
function isInGlobalURFolder(filePath) {
|
|
616362
617316
|
const absolutePath = expandPath(filePath);
|
|
616363
|
-
const globalURFolderPath =
|
|
617317
|
+
const globalURFolderPath = join192(homedir35(), ".ur");
|
|
616364
617318
|
const normalizedAbsolutePath = normalizeCaseForComparison(absolutePath);
|
|
616365
617319
|
const normalizedGlobalURFolderPath = normalizeCaseForComparison(globalURFolderPath);
|
|
616366
617320
|
return normalizedAbsolutePath.startsWith(normalizedGlobalURFolderPath + sep36.toLowerCase()) || normalizedAbsolutePath.startsWith(normalizedGlobalURFolderPath + "/");
|
|
@@ -624598,7 +625552,7 @@ var init_useVoiceEnabled = __esm(() => {
|
|
|
624598
625552
|
function getSemverPart(version3) {
|
|
624599
625553
|
return `${import_semver13.major(version3, { loose: true })}.${import_semver13.minor(version3, { loose: true })}.${import_semver13.patch(version3, { loose: true })}`;
|
|
624600
625554
|
}
|
|
624601
|
-
function useUpdateNotification(updatedVersion, initialVersion = "1.22.
|
|
625555
|
+
function useUpdateNotification(updatedVersion, initialVersion = "1.22.1") {
|
|
624602
625556
|
const [lastNotifiedSemver, setLastNotifiedSemver] = import_react224.useState(() => getSemverPart(initialVersion));
|
|
624603
625557
|
if (!updatedVersion) {
|
|
624604
625558
|
return null;
|
|
@@ -624647,7 +625601,7 @@ function AutoUpdater({
|
|
|
624647
625601
|
return;
|
|
624648
625602
|
}
|
|
624649
625603
|
if (false) {}
|
|
624650
|
-
const currentVersion = "1.22.
|
|
625604
|
+
const currentVersion = "1.22.1";
|
|
624651
625605
|
const channel = getInitialSettings()?.autoUpdatesChannel ?? "latest";
|
|
624652
625606
|
let latestVersion = await getLatestVersion(channel);
|
|
624653
625607
|
const isDisabled = isAutoUpdaterDisabled();
|
|
@@ -624876,12 +625830,12 @@ function NativeAutoUpdater({
|
|
|
624876
625830
|
logEvent("tengu_native_auto_updater_start", {});
|
|
624877
625831
|
try {
|
|
624878
625832
|
const maxVersion = await getMaxVersion();
|
|
624879
|
-
if (maxVersion && gt("1.22.
|
|
625833
|
+
if (maxVersion && gt("1.22.1", maxVersion)) {
|
|
624880
625834
|
const msg = await getMaxVersionMessage();
|
|
624881
625835
|
setMaxVersionIssue(msg ?? "affects your version");
|
|
624882
625836
|
}
|
|
624883
625837
|
const result = await installLatest(channel);
|
|
624884
|
-
const currentVersion = "1.22.
|
|
625838
|
+
const currentVersion = "1.22.1";
|
|
624885
625839
|
const latencyMs = Date.now() - startTime;
|
|
624886
625840
|
if (result.lockFailed) {
|
|
624887
625841
|
logEvent("tengu_native_auto_updater_lock_contention", {
|
|
@@ -625018,17 +625972,17 @@ function PackageManagerAutoUpdater(t0) {
|
|
|
625018
625972
|
const maxVersion = await getMaxVersion();
|
|
625019
625973
|
if (maxVersion && latest && gt(latest, maxVersion)) {
|
|
625020
625974
|
logForDebugging(`PackageManagerAutoUpdater: maxVersion ${maxVersion} is set, capping update from ${latest} to ${maxVersion}`);
|
|
625021
|
-
if (gte("1.22.
|
|
625022
|
-
logForDebugging(`PackageManagerAutoUpdater: current version ${"1.22.
|
|
625975
|
+
if (gte("1.22.1", maxVersion)) {
|
|
625976
|
+
logForDebugging(`PackageManagerAutoUpdater: current version ${"1.22.1"} is already at or above maxVersion ${maxVersion}, skipping update`);
|
|
625023
625977
|
setUpdateAvailable(false);
|
|
625024
625978
|
return;
|
|
625025
625979
|
}
|
|
625026
625980
|
latest = maxVersion;
|
|
625027
625981
|
}
|
|
625028
|
-
const hasUpdate = latest && !gte("1.22.
|
|
625982
|
+
const hasUpdate = latest && !gte("1.22.1", latest) && !shouldSkipVersion(latest);
|
|
625029
625983
|
setUpdateAvailable(!!hasUpdate);
|
|
625030
625984
|
if (hasUpdate) {
|
|
625031
|
-
logForDebugging(`PackageManagerAutoUpdater: Update available ${"1.22.
|
|
625985
|
+
logForDebugging(`PackageManagerAutoUpdater: Update available ${"1.22.1"} -> ${latest}`);
|
|
625032
625986
|
}
|
|
625033
625987
|
};
|
|
625034
625988
|
$3[0] = t1;
|
|
@@ -625062,7 +626016,7 @@ function PackageManagerAutoUpdater(t0) {
|
|
|
625062
626016
|
wrap: "truncate",
|
|
625063
626017
|
children: [
|
|
625064
626018
|
"currentVersion: ",
|
|
625065
|
-
"1.22.
|
|
626019
|
+
"1.22.1"
|
|
625066
626020
|
]
|
|
625067
626021
|
}, undefined, true, undefined, this);
|
|
625068
626022
|
$3[3] = verbose;
|
|
@@ -637424,7 +638378,7 @@ function buildStatusLineCommandInput(permissionMode, exceeds200kTokens, settings
|
|
|
637424
638378
|
project_dir: getOriginalCwd(),
|
|
637425
638379
|
added_dirs: addedDirs
|
|
637426
638380
|
},
|
|
637427
|
-
version: "1.22.
|
|
638381
|
+
version: "1.22.1",
|
|
637428
638382
|
output_style: {
|
|
637429
638383
|
name: outputStyleName
|
|
637430
638384
|
},
|
|
@@ -643532,9 +644486,9 @@ function initSkillImprovement() {
|
|
|
643532
644486
|
async function applySkillImprovement(skillName, updates) {
|
|
643533
644487
|
if (!skillName)
|
|
643534
644488
|
return;
|
|
643535
|
-
const { join:
|
|
644489
|
+
const { join: join193 } = await import("path");
|
|
643536
644490
|
const fs12 = await import("fs/promises");
|
|
643537
|
-
const filePath =
|
|
644491
|
+
const filePath = join193(getCwd(), ".ur", "skills", skillName, "SKILL.md");
|
|
643538
644492
|
let currentContent;
|
|
643539
644493
|
try {
|
|
643540
644494
|
currentContent = await fs12.readFile(filePath, "utf-8");
|
|
@@ -643688,7 +644642,7 @@ function useMoreRight(_args) {
|
|
|
643688
644642
|
// src/utils/cleanup.ts
|
|
643689
644643
|
import * as fs12 from "fs/promises";
|
|
643690
644644
|
import { homedir as homedir36 } from "os";
|
|
643691
|
-
import { join as
|
|
644645
|
+
import { join as join193 } from "path";
|
|
643692
644646
|
function getCutoffDate() {
|
|
643693
644647
|
const settings = getSettings_DEPRECATED() || {};
|
|
643694
644648
|
const cleanupPeriodDays = settings.cleanupPeriodDays ?? DEFAULT_CLEANUP_PERIOD_DAYS;
|
|
@@ -643713,7 +644667,7 @@ async function cleanupOldFilesInDirectory(dirPath, cutoffDate, isMessagePath) {
|
|
|
643713
644667
|
try {
|
|
643714
644668
|
const timestamp2 = convertFileNameToDate(file4.name);
|
|
643715
644669
|
if (timestamp2 < cutoffDate) {
|
|
643716
|
-
await getFsImplementation().unlink(
|
|
644670
|
+
await getFsImplementation().unlink(join193(dirPath, file4.name));
|
|
643717
644671
|
if (isMessagePath) {
|
|
643718
644672
|
result.messages++;
|
|
643719
644673
|
} else {
|
|
@@ -643744,7 +644698,7 @@ async function cleanupOldMessageFiles() {
|
|
|
643744
644698
|
} catch {
|
|
643745
644699
|
return result;
|
|
643746
644700
|
}
|
|
643747
|
-
const mcpLogDirs = dirents.filter((dirent) => dirent.isDirectory() && dirent.name.startsWith("mcp-logs-")).map((dirent) =>
|
|
644701
|
+
const mcpLogDirs = dirents.filter((dirent) => dirent.isDirectory() && dirent.name.startsWith("mcp-logs-")).map((dirent) => join193(baseCachePath, dirent.name));
|
|
643748
644702
|
for (const mcpLogDir of mcpLogDirs) {
|
|
643749
644703
|
result = addCleanupResults(result, await cleanupOldFilesInDirectory(mcpLogDir, cutoffDate, true));
|
|
643750
644704
|
await tryRmdir(mcpLogDir, fsImpl);
|
|
@@ -643783,7 +644737,7 @@ async function cleanupOldSessionFiles() {
|
|
|
643783
644737
|
for (const projectDirent of projectDirents) {
|
|
643784
644738
|
if (!projectDirent.isDirectory())
|
|
643785
644739
|
continue;
|
|
643786
|
-
const projectDir =
|
|
644740
|
+
const projectDir = join193(projectsDir, projectDirent.name);
|
|
643787
644741
|
let entries;
|
|
643788
644742
|
try {
|
|
643789
644743
|
entries = await fsImpl.readdir(projectDir);
|
|
@@ -643797,15 +644751,15 @@ async function cleanupOldSessionFiles() {
|
|
|
643797
644751
|
continue;
|
|
643798
644752
|
}
|
|
643799
644753
|
try {
|
|
643800
|
-
if (await unlinkIfOld(
|
|
644754
|
+
if (await unlinkIfOld(join193(projectDir, entry.name), cutoffDate, fsImpl)) {
|
|
643801
644755
|
result.messages++;
|
|
643802
644756
|
}
|
|
643803
644757
|
} catch {
|
|
643804
644758
|
result.errors++;
|
|
643805
644759
|
}
|
|
643806
644760
|
} else if (entry.isDirectory()) {
|
|
643807
|
-
const sessionDir =
|
|
643808
|
-
const toolResultsDir =
|
|
644761
|
+
const sessionDir = join193(projectDir, entry.name);
|
|
644762
|
+
const toolResultsDir = join193(sessionDir, TOOL_RESULTS_SUBDIR);
|
|
643809
644763
|
let toolDirs;
|
|
643810
644764
|
try {
|
|
643811
644765
|
toolDirs = await fsImpl.readdir(toolResultsDir);
|
|
@@ -643816,14 +644770,14 @@ async function cleanupOldSessionFiles() {
|
|
|
643816
644770
|
for (const toolEntry of toolDirs) {
|
|
643817
644771
|
if (toolEntry.isFile()) {
|
|
643818
644772
|
try {
|
|
643819
|
-
if (await unlinkIfOld(
|
|
644773
|
+
if (await unlinkIfOld(join193(toolResultsDir, toolEntry.name), cutoffDate, fsImpl)) {
|
|
643820
644774
|
result.messages++;
|
|
643821
644775
|
}
|
|
643822
644776
|
} catch {
|
|
643823
644777
|
result.errors++;
|
|
643824
644778
|
}
|
|
643825
644779
|
} else if (toolEntry.isDirectory()) {
|
|
643826
|
-
const toolDirPath =
|
|
644780
|
+
const toolDirPath = join193(toolResultsDir, toolEntry.name);
|
|
643827
644781
|
let toolFiles;
|
|
643828
644782
|
try {
|
|
643829
644783
|
toolFiles = await fsImpl.readdir(toolDirPath);
|
|
@@ -643834,7 +644788,7 @@ async function cleanupOldSessionFiles() {
|
|
|
643834
644788
|
if (!tf.isFile())
|
|
643835
644789
|
continue;
|
|
643836
644790
|
try {
|
|
643837
|
-
if (await unlinkIfOld(
|
|
644791
|
+
if (await unlinkIfOld(join193(toolDirPath, tf.name), cutoffDate, fsImpl)) {
|
|
643838
644792
|
result.messages++;
|
|
643839
644793
|
}
|
|
643840
644794
|
} catch {
|
|
@@ -643866,7 +644820,7 @@ async function cleanupSingleDirectory(dirPath, extension, removeEmptyDir = true)
|
|
|
643866
644820
|
if (!dirent.isFile() || !dirent.name.endsWith(extension))
|
|
643867
644821
|
continue;
|
|
643868
644822
|
try {
|
|
643869
|
-
if (await unlinkIfOld(
|
|
644823
|
+
if (await unlinkIfOld(join193(dirPath, dirent.name), cutoffDate, fsImpl)) {
|
|
643870
644824
|
result.messages++;
|
|
643871
644825
|
}
|
|
643872
644826
|
} catch {
|
|
@@ -643879,7 +644833,7 @@ async function cleanupSingleDirectory(dirPath, extension, removeEmptyDir = true)
|
|
|
643879
644833
|
return result;
|
|
643880
644834
|
}
|
|
643881
644835
|
function cleanupOldPlanFiles() {
|
|
643882
|
-
const plansDir =
|
|
644836
|
+
const plansDir = join193(getURConfigHomeDir(), "plans");
|
|
643883
644837
|
return cleanupSingleDirectory(plansDir, ".md");
|
|
643884
644838
|
}
|
|
643885
644839
|
async function cleanupOldFileHistoryBackups() {
|
|
@@ -643888,14 +644842,14 @@ async function cleanupOldFileHistoryBackups() {
|
|
|
643888
644842
|
const fsImpl = getFsImplementation();
|
|
643889
644843
|
try {
|
|
643890
644844
|
const configDir = getURConfigHomeDir();
|
|
643891
|
-
const fileHistoryStorageDir =
|
|
644845
|
+
const fileHistoryStorageDir = join193(configDir, "file-history");
|
|
643892
644846
|
let dirents;
|
|
643893
644847
|
try {
|
|
643894
644848
|
dirents = await fsImpl.readdir(fileHistoryStorageDir);
|
|
643895
644849
|
} catch {
|
|
643896
644850
|
return result;
|
|
643897
644851
|
}
|
|
643898
|
-
const fileHistorySessionsDirs = dirents.filter((dirent) => dirent.isDirectory()).map((dirent) =>
|
|
644852
|
+
const fileHistorySessionsDirs = dirents.filter((dirent) => dirent.isDirectory()).map((dirent) => join193(fileHistoryStorageDir, dirent.name));
|
|
643899
644853
|
await Promise.all(fileHistorySessionsDirs.map(async (fileHistorySessionDir) => {
|
|
643900
644854
|
try {
|
|
643901
644855
|
const stats2 = await fsImpl.stat(fileHistorySessionDir);
|
|
@@ -643922,14 +644876,14 @@ async function cleanupOldSessionEnvDirs() {
|
|
|
643922
644876
|
const fsImpl = getFsImplementation();
|
|
643923
644877
|
try {
|
|
643924
644878
|
const configDir = getURConfigHomeDir();
|
|
643925
|
-
const sessionEnvBaseDir =
|
|
644879
|
+
const sessionEnvBaseDir = join193(configDir, "session-env");
|
|
643926
644880
|
let dirents;
|
|
643927
644881
|
try {
|
|
643928
644882
|
dirents = await fsImpl.readdir(sessionEnvBaseDir);
|
|
643929
644883
|
} catch {
|
|
643930
644884
|
return result;
|
|
643931
644885
|
}
|
|
643932
|
-
const sessionEnvDirs = dirents.filter((dirent) => dirent.isDirectory()).map((dirent) =>
|
|
644886
|
+
const sessionEnvDirs = dirents.filter((dirent) => dirent.isDirectory()).map((dirent) => join193(sessionEnvBaseDir, dirent.name));
|
|
643933
644887
|
for (const sessionEnvDir of sessionEnvDirs) {
|
|
643934
644888
|
try {
|
|
643935
644889
|
const stats2 = await fsImpl.stat(sessionEnvDir);
|
|
@@ -643951,7 +644905,7 @@ async function cleanupOldDebugLogs() {
|
|
|
643951
644905
|
const cutoffDate = getCutoffDate();
|
|
643952
644906
|
const result = { messages: 0, errors: 0 };
|
|
643953
644907
|
const fsImpl = getFsImplementation();
|
|
643954
|
-
const debugDir =
|
|
644908
|
+
const debugDir = join193(getURConfigHomeDir(), "debug");
|
|
643955
644909
|
let dirents;
|
|
643956
644910
|
try {
|
|
643957
644911
|
dirents = await fsImpl.readdir(debugDir);
|
|
@@ -643963,7 +644917,7 @@ async function cleanupOldDebugLogs() {
|
|
|
643963
644917
|
continue;
|
|
643964
644918
|
}
|
|
643965
644919
|
try {
|
|
643966
|
-
if (await unlinkIfOld(
|
|
644920
|
+
if (await unlinkIfOld(join193(debugDir, dirent.name), cutoffDate, fsImpl)) {
|
|
643967
644921
|
result.messages++;
|
|
643968
644922
|
}
|
|
643969
644923
|
} catch {
|
|
@@ -643973,7 +644927,7 @@ async function cleanupOldDebugLogs() {
|
|
|
643973
644927
|
return result;
|
|
643974
644928
|
}
|
|
643975
644929
|
async function cleanupNpmCacheForURHQPackages() {
|
|
643976
|
-
const markerPath =
|
|
644930
|
+
const markerPath = join193(getURConfigHomeDir(), ".npm-cache-cleanup");
|
|
643977
644931
|
try {
|
|
643978
644932
|
const stat47 = await fs12.stat(markerPath);
|
|
643979
644933
|
if (Date.now() - stat47.mtimeMs < ONE_DAY_MS) {
|
|
@@ -643988,7 +644942,7 @@ async function cleanupNpmCacheForURHQPackages() {
|
|
|
643988
644942
|
return;
|
|
643989
644943
|
}
|
|
643990
644944
|
logForDebugging("npm cache cleanup: starting");
|
|
643991
|
-
const npmCachePath =
|
|
644945
|
+
const npmCachePath = join193(homedir36(), ".npm", "_cacache");
|
|
643992
644946
|
const NPM_CACHE_RETENTION_COUNT = 5;
|
|
643993
644947
|
const startTime = Date.now();
|
|
643994
644948
|
try {
|
|
@@ -644043,7 +644997,7 @@ async function cleanupNpmCacheForURHQPackages() {
|
|
|
644043
644997
|
}
|
|
644044
644998
|
}
|
|
644045
644999
|
async function cleanupOldVersionsThrottled() {
|
|
644046
|
-
const markerPath =
|
|
645000
|
+
const markerPath = join193(getURConfigHomeDir(), ".version-cleanup");
|
|
644047
645001
|
try {
|
|
644048
645002
|
const stat47 = await fs12.stat(markerPath);
|
|
644049
645003
|
if (Date.now() - stat47.mtimeMs < ONE_DAY_MS) {
|
|
@@ -647286,7 +648240,7 @@ __export(exports_asciicast, {
|
|
|
647286
648240
|
_resetRecordingStateForTesting: () => _resetRecordingStateForTesting
|
|
647287
648241
|
});
|
|
647288
648242
|
import { appendFile as appendFile7, rename as rename10 } from "fs/promises";
|
|
647289
|
-
import { basename as basename57, dirname as dirname67, join as
|
|
648243
|
+
import { basename as basename57, dirname as dirname67, join as join195 } from "path";
|
|
647290
648244
|
function getRecordFilePath() {
|
|
647291
648245
|
if (recordingState.filePath !== null) {
|
|
647292
648246
|
return recordingState.filePath;
|
|
@@ -647297,10 +648251,10 @@ function getRecordFilePath() {
|
|
|
647297
648251
|
if (!isEnvTruthy(process.env.UR_CODE_TERMINAL_RECORDING)) {
|
|
647298
648252
|
return null;
|
|
647299
648253
|
}
|
|
647300
|
-
const projectsDir =
|
|
647301
|
-
const projectDir =
|
|
648254
|
+
const projectsDir = join195(getURConfigHomeDir(), "projects");
|
|
648255
|
+
const projectDir = join195(projectsDir, sanitizePath2(getOriginalCwd()));
|
|
647302
648256
|
recordingState.timestamp = Date.now();
|
|
647303
|
-
recordingState.filePath =
|
|
648257
|
+
recordingState.filePath = join195(projectDir, `${getSessionId()}-${recordingState.timestamp}.cast`);
|
|
647304
648258
|
return recordingState.filePath;
|
|
647305
648259
|
}
|
|
647306
648260
|
function _resetRecordingStateForTesting() {
|
|
@@ -647309,13 +648263,13 @@ function _resetRecordingStateForTesting() {
|
|
|
647309
648263
|
}
|
|
647310
648264
|
function getSessionRecordingPaths() {
|
|
647311
648265
|
const sessionId = getSessionId();
|
|
647312
|
-
const projectsDir =
|
|
647313
|
-
const projectDir =
|
|
648266
|
+
const projectsDir = join195(getURConfigHomeDir(), "projects");
|
|
648267
|
+
const projectDir = join195(projectsDir, sanitizePath2(getOriginalCwd()));
|
|
647314
648268
|
try {
|
|
647315
648269
|
const entries = getFsImplementation().readdirSync(projectDir);
|
|
647316
648270
|
const names = typeof entries[0] === "string" ? entries : entries.map((e) => e.name);
|
|
647317
648271
|
const files2 = names.filter((f) => f.startsWith(sessionId) && f.endsWith(".cast")).sort();
|
|
647318
|
-
return files2.map((f) =>
|
|
648272
|
+
return files2.map((f) => join195(projectDir, f));
|
|
647319
648273
|
} catch {
|
|
647320
648274
|
return [];
|
|
647321
648275
|
}
|
|
@@ -647325,9 +648279,9 @@ async function renameRecordingForSession() {
|
|
|
647325
648279
|
if (!oldPath || recordingState.timestamp === 0) {
|
|
647326
648280
|
return;
|
|
647327
648281
|
}
|
|
647328
|
-
const projectsDir =
|
|
647329
|
-
const projectDir =
|
|
647330
|
-
const newPath =
|
|
648282
|
+
const projectsDir = join195(getURConfigHomeDir(), "projects");
|
|
648283
|
+
const projectDir = join195(projectsDir, sanitizePath2(getOriginalCwd()));
|
|
648284
|
+
const newPath = join195(projectDir, `${getSessionId()}-${recordingState.timestamp}.cast`);
|
|
647331
648285
|
if (oldPath === newPath) {
|
|
647332
648286
|
return;
|
|
647333
648287
|
}
|
|
@@ -648932,7 +649886,7 @@ async function submitTranscriptShare(messages, trigger2, appearanceId) {
|
|
|
648932
649886
|
} catch {}
|
|
648933
649887
|
const data = {
|
|
648934
649888
|
trigger: trigger2,
|
|
648935
|
-
version: "1.22.
|
|
649889
|
+
version: "1.22.1",
|
|
648936
649890
|
platform: process.platform,
|
|
648937
649891
|
transcript,
|
|
648938
649892
|
subagentTranscripts: Object.keys(subagentTranscripts).length > 0 ? subagentTranscripts : undefined,
|
|
@@ -650204,7 +651158,7 @@ var init_useChromeExtensionNotification = __esm(() => {
|
|
|
650204
651158
|
});
|
|
650205
651159
|
|
|
650206
651160
|
// src/utils/plugins/officialMarketplaceStartupCheck.ts
|
|
650207
|
-
import { join as
|
|
651161
|
+
import { join as join196 } from "path";
|
|
650208
651162
|
function isOfficialMarketplaceAutoInstallDisabled() {
|
|
650209
651163
|
return isEnvTruthy(process.env.UR_CODE_DISABLE_OFFICIAL_MARKETPLACE_AUTOINSTALL);
|
|
650210
651164
|
}
|
|
@@ -650288,7 +651242,7 @@ async function checkAndInstallOfficialMarketplace() {
|
|
|
650288
651242
|
return { installed: false, skipped: true, reason: "policy_blocked" };
|
|
650289
651243
|
}
|
|
650290
651244
|
const cacheDir = getMarketplacesCacheDir();
|
|
650291
|
-
const installLocation =
|
|
651245
|
+
const installLocation = join196(cacheDir, OFFICIAL_MARKETPLACE_NAME);
|
|
650292
651246
|
const gcsSha = await fetchOfficialMarketplaceFromGcs(installLocation, cacheDir);
|
|
650293
651247
|
if (gcsSha !== null) {
|
|
650294
651248
|
const known = await loadKnownMarketplacesConfig();
|
|
@@ -653303,7 +654257,7 @@ var init_usePluginRecommendationBase = __esm(() => {
|
|
|
653303
654257
|
});
|
|
653304
654258
|
|
|
653305
654259
|
// src/hooks/useLspPluginRecommendation.tsx
|
|
653306
|
-
import { extname as extname20, join as
|
|
654260
|
+
import { extname as extname20, join as join197 } from "path";
|
|
653307
654261
|
function useLspPluginRecommendation() {
|
|
653308
654262
|
const $3 = import_compiler_runtime347.c(12);
|
|
653309
654263
|
const trackedFiles = useAppState(_temp205);
|
|
@@ -653388,7 +654342,7 @@ function useLspPluginRecommendation() {
|
|
|
653388
654342
|
case "yes": {
|
|
653389
654343
|
installPluginAndNotify(pluginId, pluginName, "lsp-plugin", addNotification, async (pluginData) => {
|
|
653390
654344
|
logForDebugging(`[useLspPluginRecommendation] Installing plugin: ${pluginId}`);
|
|
653391
|
-
const localSourcePath = typeof pluginData.entry.source === "string" ?
|
|
654345
|
+
const localSourcePath = typeof pluginData.entry.source === "string" ? join197(pluginData.marketplaceInstallLocation, pluginData.entry.source) : undefined;
|
|
653392
654346
|
await cacheAndRegisterPlugin(pluginId, pluginData.entry, "user", undefined, localSourcePath);
|
|
653393
654347
|
const settings = getSettingsForSource("userSettings");
|
|
653394
654348
|
updateSettingsForSource("userSettings", {
|
|
@@ -656218,7 +657172,7 @@ var exports_REPL = {};
|
|
|
656218
657172
|
__export(exports_REPL, {
|
|
656219
657173
|
REPL: () => REPL
|
|
656220
657174
|
});
|
|
656221
|
-
import { dirname as dirname69, join as
|
|
657175
|
+
import { dirname as dirname69, join as join198 } from "path";
|
|
656222
657176
|
import { tmpdir as tmpdir12 } from "os";
|
|
656223
657177
|
import { writeFile as writeFile47 } from "fs/promises";
|
|
656224
657178
|
import { randomUUID as randomUUID51 } from "crypto";
|
|
@@ -658790,7 +659744,7 @@ Note: ctrl + z now suspends UR, ctrl + _ undoes input.
|
|
|
658790
659744
|
const w = Math.max(80, (process.stdout.columns ?? 80) - 6);
|
|
658791
659745
|
const raw = await renderMessagesToPlainText(deferredMessages, tools, w);
|
|
658792
659746
|
const text = raw.replace(/[ \t]+$/gm, "");
|
|
658793
|
-
const path24 =
|
|
659747
|
+
const path24 = join198(tmpdir12(), `cc-transcript-${Date.now()}.txt`);
|
|
658794
659748
|
await writeFile47(path24, text);
|
|
658795
659749
|
const opened = openFileInExternalEditor(path24);
|
|
658796
659750
|
setStatus2(opened ? `opening ${path24}` : `wrote ${path24} \xB7 no $VISUAL/$EDITOR set`);
|
|
@@ -660841,7 +661795,7 @@ function WelcomeV2() {
|
|
|
660841
661795
|
dimColor: true,
|
|
660842
661796
|
children: [
|
|
660843
661797
|
"v",
|
|
660844
|
-
"1.22.
|
|
661798
|
+
"1.22.1"
|
|
660845
661799
|
]
|
|
660846
661800
|
}, undefined, true, undefined, this)
|
|
660847
661801
|
]
|
|
@@ -662101,7 +663055,7 @@ function completeOnboarding() {
|
|
|
662101
663055
|
saveGlobalConfig((current) => ({
|
|
662102
663056
|
...current,
|
|
662103
663057
|
hasCompletedOnboarding: true,
|
|
662104
|
-
lastOnboardingVersion: "1.22.
|
|
663058
|
+
lastOnboardingVersion: "1.22.1"
|
|
662105
663059
|
}));
|
|
662106
663060
|
}
|
|
662107
663061
|
function showDialog(root2, renderer) {
|
|
@@ -667152,12 +668106,12 @@ var init_createDirectConnectSession = __esm(() => {
|
|
|
667152
668106
|
});
|
|
667153
668107
|
|
|
667154
668108
|
// src/utils/errorLogSink.ts
|
|
667155
|
-
import { dirname as dirname71, join as
|
|
668109
|
+
import { dirname as dirname71, join as join199 } from "path";
|
|
667156
668110
|
function getErrorsPath() {
|
|
667157
|
-
return
|
|
668111
|
+
return join199(CACHE_PATHS.errors(), DATE + ".jsonl");
|
|
667158
668112
|
}
|
|
667159
668113
|
function getMCPLogsPath(serverName) {
|
|
667160
|
-
return
|
|
668114
|
+
return join199(CACHE_PATHS.mcpLogs(serverName), DATE + ".jsonl");
|
|
667161
668115
|
}
|
|
667162
668116
|
function createJsonlWriter(options2) {
|
|
667163
668117
|
const writer = createBufferedWriter(options2);
|
|
@@ -667201,7 +668155,7 @@ function appendToLog(path24, message) {
|
|
|
667201
668155
|
cwd: getFsImplementation().cwd(),
|
|
667202
668156
|
userType: process.env.USER_TYPE,
|
|
667203
668157
|
sessionId: getSessionId(),
|
|
667204
|
-
version: "1.22.
|
|
668158
|
+
version: "1.22.1"
|
|
667205
668159
|
};
|
|
667206
668160
|
getLogWriter(path24).write(messageWithTimestamp);
|
|
667207
668161
|
}
|
|
@@ -667500,7 +668454,7 @@ var init_sessionMemory = __esm(() => {
|
|
|
667500
668454
|
// src/utils/iTermBackup.ts
|
|
667501
668455
|
import { copyFile as copyFile11, stat as stat49 } from "fs/promises";
|
|
667502
668456
|
import { homedir as homedir38 } from "os";
|
|
667503
|
-
import { join as
|
|
668457
|
+
import { join as join200 } from "path";
|
|
667504
668458
|
function markITerm2SetupComplete() {
|
|
667505
668459
|
saveGlobalConfig((current) => ({
|
|
667506
668460
|
...current,
|
|
@@ -667515,7 +668469,7 @@ function getIterm2RecoveryInfo() {
|
|
|
667515
668469
|
};
|
|
667516
668470
|
}
|
|
667517
668471
|
function getITerm2PlistPath() {
|
|
667518
|
-
return
|
|
668472
|
+
return join200(homedir38(), "Library", "Preferences", "com.googlecode.iterm2.plist");
|
|
667519
668473
|
}
|
|
667520
668474
|
async function checkAndRestoreITerm2Backup() {
|
|
667521
668475
|
const { inProgress, backupPath } = getIterm2RecoveryInfo();
|
|
@@ -671024,7 +671978,7 @@ var init_idleTimeout = __esm(() => {
|
|
|
671024
671978
|
// src/bridge/inboundAttachments.ts
|
|
671025
671979
|
import { randomUUID as randomUUID54 } from "crypto";
|
|
671026
671980
|
import { mkdir as mkdir45, writeFile as writeFile49 } from "fs/promises";
|
|
671027
|
-
import { basename as basename58, join as
|
|
671981
|
+
import { basename as basename58, join as join201 } from "path";
|
|
671028
671982
|
function debug(msg) {
|
|
671029
671983
|
logForDebugging(`[bridge:inbound-attach] ${msg}`);
|
|
671030
671984
|
}
|
|
@@ -671040,7 +671994,7 @@ function sanitizeFileName(name) {
|
|
|
671040
671994
|
return base2 || "attachment";
|
|
671041
671995
|
}
|
|
671042
671996
|
function uploadsDir() {
|
|
671043
|
-
return
|
|
671997
|
+
return join201(getURConfigHomeDir(), "uploads", getSessionId());
|
|
671044
671998
|
}
|
|
671045
671999
|
async function resolveOne(att) {
|
|
671046
672000
|
const token = getBridgeAccessToken();
|
|
@@ -671069,7 +672023,7 @@ async function resolveOne(att) {
|
|
|
671069
672023
|
const safeName = sanitizeFileName(att.file_name);
|
|
671070
672024
|
const prefix = (att.file_uuid.slice(0, 8) || randomUUID54().slice(0, 8)).replace(/[^a-zA-Z0-9_-]/g, "_");
|
|
671071
672025
|
const dir = uploadsDir();
|
|
671072
|
-
const outPath =
|
|
672026
|
+
const outPath = join201(dir, `${prefix}-${safeName}`);
|
|
671073
672027
|
try {
|
|
671074
672028
|
await mkdir45(dir, { recursive: true });
|
|
671075
672029
|
await writeFile49(outPath, data);
|
|
@@ -671169,7 +672123,7 @@ var init_sessionUrl = __esm(() => {
|
|
|
671169
672123
|
|
|
671170
672124
|
// src/utils/plugins/zipCacheAdapters.ts
|
|
671171
672125
|
import { readFile as readFile54 } from "fs/promises";
|
|
671172
|
-
import { join as
|
|
672126
|
+
import { join as join202 } from "path";
|
|
671173
672127
|
async function readZipCacheKnownMarketplaces() {
|
|
671174
672128
|
try {
|
|
671175
672129
|
const content = await readFile54(getZipCacheKnownMarketplacesPath(), "utf-8");
|
|
@@ -671194,13 +672148,13 @@ async function saveMarketplaceJsonToZipCache(marketplaceName, installLocation) {
|
|
|
671194
672148
|
const content = await readMarketplaceJsonContent(installLocation);
|
|
671195
672149
|
if (content !== null) {
|
|
671196
672150
|
const relPath = getMarketplaceJsonRelativePath(marketplaceName);
|
|
671197
|
-
await atomicWriteToZipCache(
|
|
672151
|
+
await atomicWriteToZipCache(join202(zipCachePath, relPath), content);
|
|
671198
672152
|
}
|
|
671199
672153
|
}
|
|
671200
672154
|
async function readMarketplaceJsonContent(dir) {
|
|
671201
672155
|
const candidates2 = [
|
|
671202
|
-
|
|
671203
|
-
|
|
672156
|
+
join202(dir, ".ur-plugin", "marketplace.json"),
|
|
672157
|
+
join202(dir, "marketplace.json"),
|
|
671204
672158
|
dir
|
|
671205
672159
|
];
|
|
671206
672160
|
for (const candidate of candidates2) {
|
|
@@ -671330,8 +672284,8 @@ async function getEnvLessBridgeConfig() {
|
|
|
671330
672284
|
}
|
|
671331
672285
|
async function checkEnvLessBridgeMinVersion() {
|
|
671332
672286
|
const cfg = await getEnvLessBridgeConfig();
|
|
671333
|
-
if (cfg.min_version && lt("1.22.
|
|
671334
|
-
return `Your version of UR (${"1.22.
|
|
672287
|
+
if (cfg.min_version && lt("1.22.1", cfg.min_version)) {
|
|
672288
|
+
return `Your version of UR (${"1.22.1"}) is too old for Remote Control.
|
|
671335
672289
|
Version ${cfg.min_version} or higher is required. Run \`ur update\` to update.`;
|
|
671336
672290
|
}
|
|
671337
672291
|
return null;
|
|
@@ -671659,9 +672613,9 @@ __export(exports_bridgePointer, {
|
|
|
671659
672613
|
BRIDGE_POINTER_TTL_MS: () => BRIDGE_POINTER_TTL_MS
|
|
671660
672614
|
});
|
|
671661
672615
|
import { mkdir as mkdir46, readFile as readFile55, stat as stat50, unlink as unlink26, writeFile as writeFile50 } from "fs/promises";
|
|
671662
|
-
import { dirname as dirname72, join as
|
|
672616
|
+
import { dirname as dirname72, join as join203 } from "path";
|
|
671663
672617
|
function getBridgePointerPath(dir) {
|
|
671664
|
-
return
|
|
672618
|
+
return join203(getProjectsDir(), sanitizePath2(dir), "bridge-pointer.json");
|
|
671665
672619
|
}
|
|
671666
672620
|
async function writeBridgePointer(dir, pointer) {
|
|
671667
672621
|
const path24 = getBridgePointerPath(dir);
|
|
@@ -671805,7 +672759,7 @@ async function initBridgeCore(params) {
|
|
|
671805
672759
|
const rawApi = createBridgeApiClient({
|
|
671806
672760
|
baseUrl,
|
|
671807
672761
|
getAccessToken,
|
|
671808
|
-
runnerVersion: "1.22.
|
|
672762
|
+
runnerVersion: "1.22.1",
|
|
671809
672763
|
onDebug: logForDebugging,
|
|
671810
672764
|
onAuth401,
|
|
671811
672765
|
getTrustedDeviceToken
|
|
@@ -677486,7 +678440,7 @@ async function startMCPServer(cwd3, debug2, verbose) {
|
|
|
677486
678440
|
setCwd(cwd3);
|
|
677487
678441
|
const server2 = new Server({
|
|
677488
678442
|
name: "ur/tengu",
|
|
677489
|
-
version: "1.22.
|
|
678443
|
+
version: "1.22.1"
|
|
677490
678444
|
}, {
|
|
677491
678445
|
capabilities: {
|
|
677492
678446
|
tools: {}
|
|
@@ -677618,14 +678572,14 @@ __export(exports_urDesktop, {
|
|
|
677618
678572
|
});
|
|
677619
678573
|
import { readdir as readdir32, readFile as readFile57, stat as stat52 } from "fs/promises";
|
|
677620
678574
|
import { homedir as homedir39 } from "os";
|
|
677621
|
-
import { join as
|
|
678575
|
+
import { join as join204 } from "path";
|
|
677622
678576
|
async function getURDesktopConfigPath() {
|
|
677623
678577
|
const platform7 = getPlatform();
|
|
677624
678578
|
if (!SUPPORTED_PLATFORMS.includes(platform7)) {
|
|
677625
678579
|
throw new Error(`Unsupported platform: ${platform7} - UR Desktop integration only works on macOS and WSL.`);
|
|
677626
678580
|
}
|
|
677627
678581
|
if (platform7 === "macos") {
|
|
677628
|
-
return
|
|
678582
|
+
return join204(homedir39(), "Library", "Application Support", "UR", "ur_desktop_config.json");
|
|
677629
678583
|
}
|
|
677630
678584
|
const windowsHome = process.env.USERPROFILE ? process.env.USERPROFILE.replace(/\\/g, "/") : null;
|
|
677631
678585
|
if (windowsHome) {
|
|
@@ -677644,7 +678598,7 @@ async function getURDesktopConfigPath() {
|
|
|
677644
678598
|
if (user.name === "Public" || user.name === "Default" || user.name === "Default User" || user.name === "All Users") {
|
|
677645
678599
|
continue;
|
|
677646
678600
|
}
|
|
677647
|
-
const potentialConfigPath =
|
|
678601
|
+
const potentialConfigPath = join204(usersDir, user.name, "AppData", "Roaming", "UR", "ur_desktop_config.json");
|
|
677648
678602
|
try {
|
|
677649
678603
|
await stat52(potentialConfigPath);
|
|
677650
678604
|
return potentialConfigPath;
|
|
@@ -678553,12 +679507,12 @@ __export(exports_install, {
|
|
|
678553
679507
|
install: () => install
|
|
678554
679508
|
});
|
|
678555
679509
|
import { homedir as homedir40 } from "os";
|
|
678556
|
-
import { join as
|
|
679510
|
+
import { join as join205 } from "path";
|
|
678557
679511
|
function getInstallationPath2() {
|
|
678558
679512
|
const isWindows2 = env2.platform === "win32";
|
|
678559
679513
|
const homeDir = homedir40();
|
|
678560
679514
|
if (isWindows2) {
|
|
678561
|
-
const windowsPath =
|
|
679515
|
+
const windowsPath = join205(homeDir, ".local", "bin", "ur.exe");
|
|
678562
679516
|
return windowsPath.replace(/\//g, "\\");
|
|
678563
679517
|
}
|
|
678564
679518
|
return "~/.local/bin/ur";
|
|
@@ -679097,7 +680051,7 @@ __export(exports_update, {
|
|
|
679097
680051
|
});
|
|
679098
680052
|
async function update() {
|
|
679099
680053
|
logEvent("tengu_update_check", {});
|
|
679100
|
-
writeToStdout(`Current version: ${"1.22.
|
|
680054
|
+
writeToStdout(`Current version: ${"1.22.1"}
|
|
679101
680055
|
`);
|
|
679102
680056
|
const channel = getInitialSettings()?.autoUpdatesChannel ?? "latest";
|
|
679103
680057
|
writeToStdout(`Checking for updates to ${channel} version...
|
|
@@ -679172,8 +680126,8 @@ async function update() {
|
|
|
679172
680126
|
writeToStdout(`UR is managed by Homebrew.
|
|
679173
680127
|
`);
|
|
679174
680128
|
const latest = await getLatestVersion(channel);
|
|
679175
|
-
if (latest && !gte("1.22.
|
|
679176
|
-
writeToStdout(`${formatUpdateAvailableMessage("1.22.
|
|
680129
|
+
if (latest && !gte("1.22.1", latest)) {
|
|
680130
|
+
writeToStdout(`${formatUpdateAvailableMessage("1.22.1", latest)}
|
|
679177
680131
|
`);
|
|
679178
680132
|
writeToStdout(`
|
|
679179
680133
|
`);
|
|
@@ -679189,8 +680143,8 @@ async function update() {
|
|
|
679189
680143
|
writeToStdout(`UR is managed by winget.
|
|
679190
680144
|
`);
|
|
679191
680145
|
const latest = await getLatestVersion(channel);
|
|
679192
|
-
if (latest && !gte("1.22.
|
|
679193
|
-
writeToStdout(`${formatUpdateAvailableMessage("1.22.
|
|
680146
|
+
if (latest && !gte("1.22.1", latest)) {
|
|
680147
|
+
writeToStdout(`${formatUpdateAvailableMessage("1.22.1", latest)}
|
|
679194
680148
|
`);
|
|
679195
680149
|
writeToStdout(`
|
|
679196
680150
|
`);
|
|
@@ -679206,8 +680160,8 @@ async function update() {
|
|
|
679206
680160
|
writeToStdout(`UR is managed by apk.
|
|
679207
680161
|
`);
|
|
679208
680162
|
const latest = await getLatestVersion(channel);
|
|
679209
|
-
if (latest && !gte("1.22.
|
|
679210
|
-
writeToStdout(`${formatUpdateAvailableMessage("1.22.
|
|
680163
|
+
if (latest && !gte("1.22.1", latest)) {
|
|
680164
|
+
writeToStdout(`${formatUpdateAvailableMessage("1.22.1", latest)}
|
|
679211
680165
|
`);
|
|
679212
680166
|
writeToStdout(`
|
|
679213
680167
|
`);
|
|
@@ -679272,11 +680226,11 @@ async function update() {
|
|
|
679272
680226
|
`);
|
|
679273
680227
|
await gracefulShutdown(1);
|
|
679274
680228
|
}
|
|
679275
|
-
if (result.latestVersion === "1.22.
|
|
679276
|
-
writeToStdout(source_default.green(`UR is up to date (${"1.22.
|
|
680229
|
+
if (result.latestVersion === "1.22.1") {
|
|
680230
|
+
writeToStdout(source_default.green(`UR is up to date (${"1.22.1"})`) + `
|
|
679277
680231
|
`);
|
|
679278
680232
|
} else {
|
|
679279
|
-
writeToStdout(source_default.green(`Successfully updated from ${"1.22.
|
|
680233
|
+
writeToStdout(source_default.green(`Successfully updated from ${"1.22.1"} to version ${result.latestVersion}`) + `
|
|
679280
680234
|
`);
|
|
679281
680235
|
await regenerateCompletionCache();
|
|
679282
680236
|
}
|
|
@@ -679336,12 +680290,12 @@ async function update() {
|
|
|
679336
680290
|
`);
|
|
679337
680291
|
await gracefulShutdown(1);
|
|
679338
680292
|
}
|
|
679339
|
-
if (latestVersion === "1.22.
|
|
679340
|
-
writeToStdout(source_default.green(`UR is up to date (${"1.22.
|
|
680293
|
+
if (latestVersion === "1.22.1") {
|
|
680294
|
+
writeToStdout(source_default.green(`UR is up to date (${"1.22.1"})`) + `
|
|
679341
680295
|
`);
|
|
679342
680296
|
await gracefulShutdown(0);
|
|
679343
680297
|
}
|
|
679344
|
-
writeToStdout(`${formatUpdateAvailableMessage("1.22.
|
|
680298
|
+
writeToStdout(`${formatUpdateAvailableMessage("1.22.1", latestVersion)}
|
|
679345
680299
|
`);
|
|
679346
680300
|
writeToStdout(`Installing update...
|
|
679347
680301
|
`);
|
|
@@ -679386,7 +680340,7 @@ async function update() {
|
|
|
679386
680340
|
logForDebugging(`update: Installation status: ${status2}`);
|
|
679387
680341
|
switch (status2) {
|
|
679388
680342
|
case "success":
|
|
679389
|
-
writeToStdout(source_default.green(`Successfully updated from ${"1.22.
|
|
680343
|
+
writeToStdout(source_default.green(`Successfully updated from ${"1.22.1"} to version ${latestVersion}`) + `
|
|
679390
680344
|
`);
|
|
679391
680345
|
await regenerateCompletionCache();
|
|
679392
680346
|
break;
|
|
@@ -679452,7 +680406,7 @@ __export(exports_main, {
|
|
|
679452
680406
|
startDeferredPrefetches: () => startDeferredPrefetches,
|
|
679453
680407
|
main: () => main
|
|
679454
680408
|
});
|
|
679455
|
-
import { readFileSync as
|
|
680409
|
+
import { readFileSync as readFileSync55 } from "fs";
|
|
679456
680410
|
import { resolve as resolve50 } from "path";
|
|
679457
680411
|
function logManagedSettings() {
|
|
679458
680412
|
try {
|
|
@@ -679608,7 +680562,7 @@ function loadSettingsFromFlag(settingsFile) {
|
|
|
679608
680562
|
resolvedPath: resolvedSettingsPath
|
|
679609
680563
|
} = safeResolvePath(getFsImplementation(), settingsFile);
|
|
679610
680564
|
try {
|
|
679611
|
-
|
|
680565
|
+
readFileSync55(resolvedSettingsPath, "utf8");
|
|
679612
680566
|
} catch (e) {
|
|
679613
680567
|
if (isENOENT(e)) {
|
|
679614
680568
|
process.stderr.write(source_default.red(`Error: Settings file not found: ${resolvedSettingsPath}
|
|
@@ -680013,7 +680967,7 @@ ${getTmuxInstallInstructions2()}
|
|
|
680013
680967
|
}
|
|
680014
680968
|
try {
|
|
680015
680969
|
const filePath = resolve50(options2.systemPromptFile);
|
|
680016
|
-
systemPrompt =
|
|
680970
|
+
systemPrompt = readFileSync55(filePath, "utf8");
|
|
680017
680971
|
} catch (error40) {
|
|
680018
680972
|
const code = getErrnoCode(error40);
|
|
680019
680973
|
if (code === "ENOENT") {
|
|
@@ -680035,7 +680989,7 @@ ${getTmuxInstallInstructions2()}
|
|
|
680035
680989
|
}
|
|
680036
680990
|
try {
|
|
680037
680991
|
const filePath = resolve50(options2.appendSystemPromptFile);
|
|
680038
|
-
appendSystemPrompt =
|
|
680992
|
+
appendSystemPrompt = readFileSync55(filePath, "utf8");
|
|
680039
680993
|
} catch (error40) {
|
|
680040
680994
|
const code = getErrnoCode(error40);
|
|
680041
680995
|
if (code === "ENOENT") {
|
|
@@ -680662,7 +681616,7 @@ ${customInstructions}` : customInstructions;
|
|
|
680662
681616
|
}
|
|
680663
681617
|
}
|
|
680664
681618
|
logForDiagnosticsNoPII("info", "started", {
|
|
680665
|
-
version: "1.22.
|
|
681619
|
+
version: "1.22.1",
|
|
680666
681620
|
is_native_binary: isInBundledMode()
|
|
680667
681621
|
});
|
|
680668
681622
|
registerCleanup(async () => {
|
|
@@ -681446,7 +682400,7 @@ Usage: ur --remote "your task description"`, () => gracefulShutdown(1));
|
|
|
681446
682400
|
pendingHookMessages
|
|
681447
682401
|
}, renderAndRun);
|
|
681448
682402
|
}
|
|
681449
|
-
}).version("1.22.
|
|
682403
|
+
}).version("1.22.1 (Ur)", "-v, --version", "Output the version number");
|
|
681450
682404
|
program2.option("-w, --worktree [name]", "Create a new git worktree for this session (optionally specify a name)");
|
|
681451
682405
|
program2.option("--tmux", "Create a tmux session for the worktree (requires --worktree). Uses iTerm2 native panes when available; use --tmux=classic for traditional tmux.");
|
|
681452
682406
|
if (canUserConfigureAdvisor()) {
|
|
@@ -681750,7 +682704,7 @@ Usage: ur --remote "your task description"`, () => gracefulShutdown(1));
|
|
|
681750
682704
|
});
|
|
681751
682705
|
program2.command("spec [action] [name] [phase]").alias("specs").description("Spec-driven development: scaffold requirements/design/tasks in .ur/specs and drive execution task-by-task").option("--goal <text>", "Goal text for init").option("--all", "Run all open tasks, not just the next one").option("--dry-run", "Run offline without calling any model").option("--max-turns <n>", "Max agentic turns per task when running").option("--skip-permissions", "Pass --dangerously-skip-permissions to each task (sandboxes only)").option("--json", "Output as JSON").action(async (action3, name, phase, opts) => {
|
|
681752
682706
|
const args = [action3, name, phase, opts.goal ? `--goal ${quoteLocalCommandArg(opts.goal)}` : undefined, opts.all ? "--all" : undefined, opts.dryRun ? "--dry-run" : undefined, opts.maxTurns ? `--max-turns ${opts.maxTurns}` : undefined, opts.skipPermissions ? "--skip-permissions" : undefined, opts.json ? "--json" : undefined].filter(Boolean).join(" ");
|
|
681753
|
-
await runLocalTextCommand(() => Promise.resolve().then(() => (init_spec2(),
|
|
682707
|
+
await runLocalTextCommand(() => Promise.resolve().then(() => (init_spec2(), exports_spec2)), args);
|
|
681754
682708
|
});
|
|
681755
682709
|
program2.command("escalate [action] [task...]").description("Capability-aware local model escalation: run on a fast model and auto-escalate hard work to the oracle").option("--dry-run", "Run offline without calling any model").option("--force-oracle", "Start on the oracle regardless of difficulty").option("--fast <model>", "Pin the fast-tier model (policy)").option("--oracle <model>", "Pin the oracle-tier model (policy)").option("--auto <onoff>", "Enable/disable auto-escalation (policy): on|off").option("--max-turns <n>", "Max agentic turns when running").option("--skip-permissions", "Pass --dangerously-skip-permissions (sandboxes only)").option("--json", "Output as JSON").action(async (action3, task = [], opts) => {
|
|
681756
682710
|
const args = [action3, ...task, opts.dryRun ? "--dry-run" : undefined, opts.forceOracle ? "--force-oracle" : undefined, opts.fast ? `--fast ${quoteLocalCommandArg(opts.fast)}` : undefined, opts.oracle ? `--oracle ${quoteLocalCommandArg(opts.oracle)}` : undefined, opts.auto ? `--auto ${quoteLocalCommandArg(opts.auto)}` : undefined, opts.maxTurns ? `--max-turns ${opts.maxTurns}` : undefined, opts.skipPermissions ? "--skip-permissions" : undefined, opts.json ? "--json" : undefined].filter(Boolean).join(" ");
|
|
@@ -682243,7 +683197,7 @@ if (false) {}
|
|
|
682243
683197
|
async function main2() {
|
|
682244
683198
|
const args = process.argv.slice(2);
|
|
682245
683199
|
if (args.length === 1 && (args[0] === "--version" || args[0] === "-v" || args[0] === "-V")) {
|
|
682246
|
-
console.log(`${"1.22.
|
|
683200
|
+
console.log(`${"1.22.1"} (Ur)`);
|
|
682247
683201
|
return;
|
|
682248
683202
|
}
|
|
682249
683203
|
if (args[0] === "a2a" && args[1] === "serve" && !args.includes("--help") && !args.includes("-h")) {
|