ur-agent 1.13.8 → 1.13.9

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 CHANGED
@@ -1,5 +1,40 @@
1
1
  # Changelog
2
2
 
3
+ ## 1.13.9
4
+
5
+ ### Added
6
+ - **Spec-driven development (`ur spec`).** Scaffolds `requirements.md ->
7
+ design.md -> tasks.md` plus a phase/approval `spec.json` under `.ur/specs/`,
8
+ then drives execution task-by-task through a headless agent, checking off each
9
+ task on a PASS verdict. Tasks use the GitHub Spec Kit / Kiro `- [ ] T1: ...`
10
+ checkbox format, so lists are drop-in portable. `generate` can model-fill a
11
+ phase; scaffolding and task parsing stay pure and offline.
12
+ - **In-loop model escalation / local Oracle (`ur escalate`).** Picks a fast tier
13
+ and a strong "oracle" tier from `ur model-doctor`, starts routine work on the
14
+ fast model, and auto-escalates hard reasoning/debug/review (or a failed cheap
15
+ attempt) to the oracle. `escalate oracle` gets a one-shot second opinion;
16
+ `escalate policy` pins tiers. Tier selection and difficulty scoring are
17
+ deterministic and testable.
18
+ - **Multi-agent best-of-N judging (`ur arena`).** Runs N agents on the same task
19
+ in isolated git worktrees, judges the resulting diffs with the deterministic
20
+ self-review gate plus verdict/diff-shape heuristics, surfaces the winner, and
21
+ can `--apply` it. Local-first take on parallel-agent judging.
22
+ - **Self-healing CI loop (`ur ci-loop`).** Runs a build/test command and, on
23
+ failure, summarizes the error, hands it to a fix agent, and re-runs with a
24
+ bounded retry budget; `--commit`/`--push` are gated by the self-review check so
25
+ a fix can never push secrets. `--from-log` seeds the first failure from a log.
26
+ - **Verifiable artifacts surface (`ur artifacts`).** Records reviewable
27
+ deliverables (plans, diffs, test runs, screenshots) under `.ur/artifacts/`
28
+ with pending/approved/rejected status and threaded feedback; `capture-diff`
29
+ and `capture-tests` snapshot the working tree and test output for audit.
30
+
31
+ ### Verified
32
+ - Added focused unit suites for escalation, arena judging, the spec workflow,
33
+ the CI loop, and artifacts (26 tests); rebuilt `dist/cli.js` and verified
34
+ typecheck, the full test suite, release check, package check, secret scan,
35
+ version output, npm publish dry-run, and direct CLI smoke tests for
36
+ `ur spec`, `ur arena`, and `ur escalate`.
37
+
3
38
  ## 1.13.8
4
39
 
5
40
  ### Fixed
package/README.md CHANGED
@@ -99,6 +99,17 @@ ur mcp --help
99
99
  ur plugin --help
100
100
  ```
101
101
 
102
+ Agent platform examples:
103
+
104
+ ```sh
105
+ ur spec init demo --goal "1. add a utils.add function 2. add a test"
106
+ ur spec run demo --all --dry-run
107
+ ur arena "implement a debounce helper" --agents 2 --dry-run
108
+ ur escalate run "refactor the cache layer" --force-oracle --dry-run
109
+ ur ci-loop --command "bun test" --dry-run
110
+ ur artifacts capture-diff
111
+ ```
112
+
102
113
  ## Documentation
103
114
 
104
115
  - [Usage Guide](docs/USAGE.md)
package/dist/cli.js CHANGED
@@ -12685,7 +12685,7 @@ function formatAgentTrendReport(report = buildAgentTrendReport()) {
12685
12685
  function formatA2AAgentCard(options = {}, pretty = true) {
12686
12686
  return JSON.stringify(buildA2AAgentCard(options), null, pretty ? 2 : 0);
12687
12687
  }
12688
- var urVersion = "1.13.8", coverage, priorityRoadmap;
12688
+ var urVersion = "1.13.9", coverage, priorityRoadmap;
12689
12689
  var init_trends = __esm(() => {
12690
12690
  coverage = [
12691
12691
  {
@@ -70342,7 +70342,7 @@ var init_auth = __esm(() => {
70342
70342
 
70343
70343
  // src/utils/userAgent.ts
70344
70344
  function getURCodeUserAgent() {
70345
- return `ur/${"1.13.8"}`;
70345
+ return `ur/${"1.13.9"}`;
70346
70346
  }
70347
70347
 
70348
70348
  // src/utils/workloadContext.ts
@@ -70364,7 +70364,7 @@ function getUserAgent() {
70364
70364
  const clientApp = process.env.UR_AGENT_SDK_CLIENT_APP ? `, client-app/${process.env.UR_AGENT_SDK_CLIENT_APP}` : "";
70365
70365
  const workload = getWorkload();
70366
70366
  const workloadSuffix = workload ? `, workload/${workload}` : "";
70367
- return `ur-cli/${"1.13.8"} (${process.env.USER_TYPE}, ${process.env.UR_CODE_ENTRYPOINT ?? "cli"}${agentSdkVersion}${clientApp}${workloadSuffix})`;
70367
+ return `ur-cli/${"1.13.9"} (${process.env.USER_TYPE}, ${process.env.UR_CODE_ENTRYPOINT ?? "cli"}${agentSdkVersion}${clientApp}${workloadSuffix})`;
70368
70368
  }
70369
70369
  function getMCPUserAgent() {
70370
70370
  const parts = [];
@@ -70378,7 +70378,7 @@ function getMCPUserAgent() {
70378
70378
  parts.push(`client-app/${process.env.UR_AGENT_SDK_CLIENT_APP}`);
70379
70379
  }
70380
70380
  const suffix = parts.length > 0 ? ` (${parts.join(", ")})` : "";
70381
- return `ur/${"1.13.8"}${suffix}`;
70381
+ return `ur/${"1.13.9"}${suffix}`;
70382
70382
  }
70383
70383
  function getWebFetchUserAgent() {
70384
70384
  return `UR-User (${getURCodeUserAgent()})`;
@@ -70516,7 +70516,7 @@ var init_user = __esm(() => {
70516
70516
  deviceId,
70517
70517
  sessionId: getSessionId(),
70518
70518
  email: getEmail(),
70519
- appVersion: "1.13.8",
70519
+ appVersion: "1.13.9",
70520
70520
  platform: getHostPlatformForAnalytics(),
70521
70521
  organizationUuid,
70522
70522
  accountUuid,
@@ -76293,7 +76293,7 @@ var init_metadata = __esm(() => {
76293
76293
  COMPOUND_OPERATOR_REGEX = /\s*(?:&&|\|\||[;|])\s*/;
76294
76294
  WHITESPACE_REGEX = /\s+/;
76295
76295
  getVersionBase = memoize_default(() => {
76296
- const match = "1.13.8".match(/^\d+\.\d+\.\d+(?:-[a-z]+)?/);
76296
+ const match = "1.13.9".match(/^\d+\.\d+\.\d+(?:-[a-z]+)?/);
76297
76297
  return match ? match[0] : undefined;
76298
76298
  });
76299
76299
  buildEnvContext = memoize_default(async () => {
@@ -76333,7 +76333,7 @@ var init_metadata = __esm(() => {
76333
76333
  isGithubAction: isEnvTruthy(process.env.GITHUB_ACTIONS),
76334
76334
  isURCodeAction: isEnvTruthy(process.env.UR_CODE_ACTION),
76335
76335
  isURAiAuth: isURAISubscriber2(),
76336
- version: "1.13.8",
76336
+ version: "1.13.9",
76337
76337
  versionBase: getVersionBase(),
76338
76338
  buildTime: "",
76339
76339
  deploymentEnvironment: env3.detectDeploymentEnvironment(),
@@ -77003,7 +77003,7 @@ function initialize1PEventLogging() {
77003
77003
  const platform2 = getPlatform();
77004
77004
  const attributes = {
77005
77005
  [import_semantic_conventions4.ATTR_SERVICE_NAME]: "ur",
77006
- [import_semantic_conventions4.ATTR_SERVICE_VERSION]: "1.13.8"
77006
+ [import_semantic_conventions4.ATTR_SERVICE_VERSION]: "1.13.9"
77007
77007
  };
77008
77008
  if (platform2 === "wsl") {
77009
77009
  const wslVersion = getWslVersion();
@@ -77030,7 +77030,7 @@ function initialize1PEventLogging() {
77030
77030
  })
77031
77031
  ]
77032
77032
  });
77033
- firstPartyEventLogger = firstPartyEventLoggerProvider.getLogger("com.urhq.ur.events", "1.13.8");
77033
+ firstPartyEventLogger = firstPartyEventLoggerProvider.getLogger("com.urhq.ur.events", "1.13.9");
77034
77034
  }
77035
77035
  async function reinitialize1PEventLoggingIfConfigChanged() {
77036
77036
  if (!is1PEventLoggingEnabled() || !firstPartyEventLoggerProvider) {
@@ -78894,7 +78894,7 @@ function getAttributionHeader(fingerprint) {
78894
78894
  if (!isAttributionHeaderEnabled()) {
78895
78895
  return "";
78896
78896
  }
78897
- const version2 = `${"1.13.8"}.${fingerprint}`;
78897
+ const version2 = `${"1.13.9"}.${fingerprint}`;
78898
78898
  const entrypoint = process.env.UR_CODE_ENTRYPOINT ?? "unknown";
78899
78899
  const cch = "";
78900
78900
  const workload = getWorkload();
@@ -185523,7 +185523,7 @@ function getTelemetryAttributes() {
185523
185523
  attributes["session.id"] = sessionId;
185524
185524
  }
185525
185525
  if (shouldIncludeAttribute("OTEL_METRICS_INCLUDE_VERSION")) {
185526
- attributes["app.version"] = "1.13.8";
185526
+ attributes["app.version"] = "1.13.9";
185527
185527
  }
185528
185528
  const oauthAccount = getOauthAccountInfo();
185529
185529
  if (oauthAccount) {
@@ -221312,7 +221312,7 @@ function getInstallationEnv() {
221312
221312
  return;
221313
221313
  }
221314
221314
  function getURCodeVersion() {
221315
- return "1.13.8";
221315
+ return "1.13.9";
221316
221316
  }
221317
221317
  async function getInstalledVSCodeExtensionVersion(command) {
221318
221318
  const { stdout } = await execFileNoThrow(command, ["--list-extensions", "--show-versions"], {
@@ -224040,7 +224040,7 @@ async function setupSdkMcpClients(sdkMcpConfigs, sendMcpMessage) {
224040
224040
  const client2 = new Client({
224041
224041
  name: "ur",
224042
224042
  title: "UR",
224043
- version: "1.13.8",
224043
+ version: "1.13.9",
224044
224044
  description: "URHQ's agentic coding tool",
224045
224045
  websiteUrl: PRODUCT_URL
224046
224046
  }, {
@@ -224394,7 +224394,7 @@ var init_client5 = __esm(() => {
224394
224394
  const client2 = new Client({
224395
224395
  name: "ur",
224396
224396
  title: "UR",
224397
- version: "1.13.8",
224397
+ version: "1.13.9",
224398
224398
  description: "URHQ's agentic coding tool",
224399
224399
  websiteUrl: PRODUCT_URL
224400
224400
  }, {
@@ -234207,9 +234207,9 @@ async function assertMinVersion() {
234207
234207
  if (false) {}
234208
234208
  try {
234209
234209
  const versionConfig = await getDynamicConfig_BLOCKS_ON_INIT("tengu_version_config", { minVersion: "0.0.0" });
234210
- if (versionConfig.minVersion && lt("1.13.8", versionConfig.minVersion)) {
234210
+ if (versionConfig.minVersion && lt("1.13.9", versionConfig.minVersion)) {
234211
234211
  console.error(`
234212
- It looks like your version of UR (${"1.13.8"}) needs an update.
234212
+ It looks like your version of UR (${"1.13.9"}) needs an update.
234213
234213
  A newer version (${versionConfig.minVersion} or higher) is required to continue.
234214
234214
 
234215
234215
  To update, please run:
@@ -234425,7 +234425,7 @@ async function installGlobalPackage(specificVersion) {
234425
234425
  logError2(new AutoUpdaterError("Another process is currently installing an update"));
234426
234426
  logEvent("tengu_auto_updater_lock_contention", {
234427
234427
  pid: process.pid,
234428
- currentVersion: "1.13.8"
234428
+ currentVersion: "1.13.9"
234429
234429
  });
234430
234430
  return "in_progress";
234431
234431
  }
@@ -234434,7 +234434,7 @@ async function installGlobalPackage(specificVersion) {
234434
234434
  if (!env3.isRunningWithBun() && env3.isNpmFromWindowsPath()) {
234435
234435
  logError2(new Error("Windows NPM detected in WSL environment"));
234436
234436
  logEvent("tengu_auto_updater_windows_npm_in_wsl", {
234437
- currentVersion: "1.13.8"
234437
+ currentVersion: "1.13.9"
234438
234438
  });
234439
234439
  console.error(`
234440
234440
  Error: Windows NPM detected in WSL
@@ -234969,7 +234969,7 @@ function detectLinuxGlobPatternWarnings() {
234969
234969
  }
234970
234970
  async function getDoctorDiagnostic() {
234971
234971
  const installationType = await getCurrentInstallationType();
234972
- const version2 = typeof MACRO !== "undefined" ? "1.13.8" : "unknown";
234972
+ const version2 = typeof MACRO !== "undefined" ? "1.13.9" : "unknown";
234973
234973
  const installationPath = await getInstallationPath();
234974
234974
  const invokedBinary = getInvokedBinary();
234975
234975
  const multipleInstallations = await detectMultipleInstallations();
@@ -235904,8 +235904,8 @@ async function updateLatest(channelOrVersion, forceReinstall = false) {
235904
235904
  const maxVersion = await getMaxVersion();
235905
235905
  if (maxVersion && gt(version2, maxVersion)) {
235906
235906
  logForDebugging(`Native installer: maxVersion ${maxVersion} is set, capping update from ${version2} to ${maxVersion}`);
235907
- if (gte("1.13.8", maxVersion)) {
235908
- logForDebugging(`Native installer: current version ${"1.13.8"} is already at or above maxVersion ${maxVersion}, skipping update`);
235907
+ if (gte("1.13.9", maxVersion)) {
235908
+ logForDebugging(`Native installer: current version ${"1.13.9"} is already at or above maxVersion ${maxVersion}, skipping update`);
235909
235909
  logEvent("tengu_native_update_skipped_max_version", {
235910
235910
  latency_ms: Date.now() - startTime,
235911
235911
  max_version: maxVersion,
@@ -235916,7 +235916,7 @@ async function updateLatest(channelOrVersion, forceReinstall = false) {
235916
235916
  version2 = maxVersion;
235917
235917
  }
235918
235918
  }
235919
- if (!forceReinstall && version2 === "1.13.8" && await versionIsAvailable(version2) && await isPossibleURBinary(executablePath)) {
235919
+ if (!forceReinstall && version2 === "1.13.9" && await versionIsAvailable(version2) && await isPossibleURBinary(executablePath)) {
235920
235920
  logForDebugging(`Found ${version2} at ${executablePath}, skipping install`);
235921
235921
  logEvent("tengu_native_update_complete", {
235922
235922
  latency_ms: Date.now() - startTime,
@@ -330587,7 +330587,7 @@ function Feedback({
330587
330587
  platform: env3.platform,
330588
330588
  gitRepo: envInfo.isGit,
330589
330589
  terminal: env3.terminal,
330590
- version: "1.13.8",
330590
+ version: "1.13.9",
330591
330591
  transcript: normalizeMessagesForAPI(messages),
330592
330592
  errors: sanitizedErrors,
330593
330593
  lastApiRequest: getLastAPIRequest(),
@@ -330779,7 +330779,7 @@ function Feedback({
330779
330779
  ", ",
330780
330780
  env3.terminal,
330781
330781
  ", v",
330782
- "1.13.8"
330782
+ "1.13.9"
330783
330783
  ]
330784
330784
  }, undefined, true, undefined, this)
330785
330785
  ]
@@ -330885,7 +330885,7 @@ ${sanitizedDescription}
330885
330885
  ` + `**Environment Info**
330886
330886
  ` + `- Platform: ${env3.platform}
330887
330887
  ` + `- Terminal: ${env3.terminal}
330888
- ` + `- Version: ${"1.13.8"}
330888
+ ` + `- Version: ${"1.13.9"}
330889
330889
  ` + `- Feedback ID: ${feedbackId}
330890
330890
  ` + `
330891
330891
  **Errors**
@@ -333995,7 +333995,7 @@ function buildPrimarySection() {
333995
333995
  }, undefined, false, undefined, this);
333996
333996
  return [{
333997
333997
  label: "Version",
333998
- value: "1.13.8"
333998
+ value: "1.13.9"
333999
333999
  }, {
334000
334000
  label: "Session name",
334001
334001
  value: nameValue
@@ -337273,7 +337273,7 @@ function Config({
337273
337273
  }
337274
337274
  }, undefined, false, undefined, this)
337275
337275
  }, undefined, false, undefined, this) : showSubmenu === "ChannelDowngrade" ? /* @__PURE__ */ jsx_dev_runtime177.jsxDEV(ChannelDowngradeDialog, {
337276
- currentVersion: "1.13.8",
337276
+ currentVersion: "1.13.9",
337277
337277
  onChoice: (choice) => {
337278
337278
  setShowSubmenu(null);
337279
337279
  setTabsHidden(false);
@@ -337285,7 +337285,7 @@ function Config({
337285
337285
  autoUpdatesChannel: "stable"
337286
337286
  };
337287
337287
  if (choice === "stay") {
337288
- newSettings.minimumVersion = "1.13.8";
337288
+ newSettings.minimumVersion = "1.13.9";
337289
337289
  }
337290
337290
  updateSettingsForSource("userSettings", newSettings);
337291
337291
  setSettingsData((prev_27) => ({
@@ -345355,7 +345355,7 @@ function HelpV2(t0) {
345355
345355
  let t6;
345356
345356
  if ($3[31] !== tabs) {
345357
345357
  t6 = /* @__PURE__ */ jsx_dev_runtime204.jsxDEV(Tabs, {
345358
- title: `UR v${"1.13.8"}`,
345358
+ title: `UR v${"1.13.9"}`,
345359
345359
  color: "professionalBlue",
345360
345360
  defaultTab: "general",
345361
345361
  children: tabs
@@ -364958,7 +364958,7 @@ function getAllReleaseNotes(changelogContent = getStoredChangelogFromMemory()) {
364958
364958
  return [];
364959
364959
  }
364960
364960
  }
364961
- async function checkForReleaseNotes(lastSeenVersion, currentVersion = "1.13.8") {
364961
+ async function checkForReleaseNotes(lastSeenVersion, currentVersion = "1.13.9") {
364962
364962
  if (process.env.USER_TYPE === "ant") {
364963
364963
  const changelog = "";
364964
364964
  if (changelog) {
@@ -364985,7 +364985,7 @@ async function checkForReleaseNotes(lastSeenVersion, currentVersion = "1.13.8")
364985
364985
  releaseNotes
364986
364986
  };
364987
364987
  }
364988
- function checkForReleaseNotesSync(lastSeenVersion, currentVersion = "1.13.8") {
364988
+ function checkForReleaseNotesSync(lastSeenVersion, currentVersion = "1.13.9") {
364989
364989
  if (process.env.USER_TYPE === "ant") {
364990
364990
  const changelog = "";
364991
364991
  if (changelog) {
@@ -366155,7 +366155,7 @@ function getRecentActivitySync() {
366155
366155
  return cachedActivity;
366156
366156
  }
366157
366157
  function getLogoDisplayData() {
366158
- const version2 = process.env.DEMO_VERSION ?? "1.13.8";
366158
+ const version2 = process.env.DEMO_VERSION ?? "1.13.9";
366159
366159
  const serverUrl = getDirectConnectServerUrl();
366160
366160
  const displayPath = process.env.DEMO_VERSION ? "/code/ur" : getDisplayPath(getCwd());
366161
366161
  const cwd2 = serverUrl ? `${displayPath} in ${serverUrl.replace(/^https?:\/\//, "")}` : displayPath;
@@ -366944,7 +366944,7 @@ function LogoV2() {
366944
366944
  if ($3[2] === Symbol.for("react.memo_cache_sentinel")) {
366945
366945
  t2 = () => {
366946
366946
  const currentConfig = getGlobalConfig();
366947
- if (currentConfig.lastReleaseNotesSeen === "1.13.8") {
366947
+ if (currentConfig.lastReleaseNotesSeen === "1.13.9") {
366948
366948
  return;
366949
366949
  }
366950
366950
  saveGlobalConfig(_temp326);
@@ -367629,12 +367629,12 @@ function LogoV2() {
367629
367629
  return t41;
367630
367630
  }
367631
367631
  function _temp326(current) {
367632
- if (current.lastReleaseNotesSeen === "1.13.8") {
367632
+ if (current.lastReleaseNotesSeen === "1.13.9") {
367633
367633
  return current;
367634
367634
  }
367635
367635
  return {
367636
367636
  ...current,
367637
- lastReleaseNotesSeen: "1.13.8"
367637
+ lastReleaseNotesSeen: "1.13.9"
367638
367638
  };
367639
367639
  }
367640
367640
  function _temp243(s_0) {
@@ -388944,7 +388944,7 @@ function assessDifficulty(task) {
388944
388944
  signals2.push(`${route2.category} task`);
388945
388945
  }
388946
388946
  if (HARD_KEYWORDS.test(task)) {
388947
- score += 4;
388947
+ score += 5;
388948
388948
  signals2.push("hard-reasoning keywords");
388949
388949
  }
388950
388950
  if (task.length > 600) {
@@ -388957,7 +388957,16 @@ function planEscalation(task, models, policy = {}) {
388957
388957
  const tiers = selectTiers(models, policy);
388958
388958
  const difficulty = assessDifficulty(task);
388959
388959
  const startTier = difficulty.hard && tiers.oracle ? "oracle" : "fast";
388960
- const rationale = difficulty.hard ? `Hard task (${difficulty.signals.join(", ") || "flagged"}): start on the oracle.` : `Routine task: start on the fast model${tiers.sameModel ? "" : "; escalate to the oracle only if it fails"}.`;
388960
+ let rationale;
388961
+ if (!tiers.fast && !tiers.oracle) {
388962
+ rationale = "No local models available; start Ollama or pull a model.";
388963
+ } else if (startTier === "oracle") {
388964
+ rationale = `Hard task (${difficulty.signals.join(", ") || "flagged"}): start on the oracle.`;
388965
+ } else if (difficulty.hard) {
388966
+ rationale = `Hard task, but no separate oracle is available: running on ${tiers.fast}.`;
388967
+ } else {
388968
+ rationale = `Routine task: start on the fast model${tiers.sameModel ? "" : "; escalate to the oracle only if it fails"}.`;
388969
+ }
388961
388970
  return { task: task.trim(), tiers, difficulty, startTier, rationale };
388962
388971
  }
388963
388972
  function needsEscalation(output) {
@@ -389204,7 +389213,6 @@ var init_escalate2 = __esm(() => {
389204
389213
  escalate = {
389205
389214
  type: "local",
389206
389215
  name: "escalate",
389207
- aliases: ["oracle"],
389208
389216
  description: 'Capability-aware local model escalation: run on a fast model and auto-escalate hard work to a strong "oracle" model',
389209
389217
  argumentHint: 'plan|run|oracle|policy "<task>" [--dry-run] [--force-oracle] [--fast m] [--oracle m] [--json]',
389210
389218
  supportsNonInteractive: true,
@@ -389771,8 +389779,8 @@ async function captureDiff2(cwd2, title = "Working tree diff", exec5 = defaultEx
389771
389779
  });
389772
389780
  }
389773
389781
  async function captureTestRun(cwd2, command5, exec5 = defaultExec2) {
389774
- const parts = command5.trim().split(/\s+/);
389775
- const run = await exec5(parts[0], parts.slice(1), cwd2);
389782
+ const parts = (command5.trim().match(/(?:[^\s"']+|"[^"]*"|'[^']*')+/g) ?? []).map((p2) => p2.replace(/^["']|["']$/g, ""));
389783
+ const run = await exec5(parts[0] ?? "", parts.slice(1), cwd2);
389776
389784
  return recordArtifact(cwd2, {
389777
389785
  kind: "test-run",
389778
389786
  title: `Test run: ${command5}`,
@@ -406101,7 +406109,7 @@ async function captureMemoryDiagnostics(trigger2, dumpNumber = 0) {
406101
406109
  smapsRollup,
406102
406110
  platform: process.platform,
406103
406111
  nodeVersion: process.version,
406104
- ccVersion: "1.13.8"
406112
+ ccVersion: "1.13.9"
406105
406113
  };
406106
406114
  }
406107
406115
  async function performHeapDump(trigger2 = "manual", dumpNumber = 0) {
@@ -406687,7 +406695,7 @@ var init_bridge_kick = __esm(() => {
406687
406695
  var call121 = async () => {
406688
406696
  return {
406689
406697
  type: "text",
406690
- value: "1.13.8"
406698
+ value: "1.13.9"
406691
406699
  };
406692
406700
  }, version2, version_default;
406693
406701
  var init_version = __esm(() => {
@@ -415742,7 +415750,7 @@ function generateHtmlReport(data, insights) {
415742
415750
  </html>`;
415743
415751
  }
415744
415752
  function buildExportData(data, insights, facets, remoteStats) {
415745
- const version3 = typeof MACRO !== "undefined" ? "1.13.8" : "unknown";
415753
+ const version3 = typeof MACRO !== "undefined" ? "1.13.9" : "unknown";
415746
415754
  const remote_hosts_collected = remoteStats?.hosts.filter((h2) => h2.sessionCount > 0).map((h2) => h2.name);
415747
415755
  const facets_summary = {
415748
415756
  total: facets.size,
@@ -419985,7 +419993,7 @@ var init_sessionStorage = __esm(() => {
419985
419993
  init_settings2();
419986
419994
  init_slowOperations();
419987
419995
  init_uuid();
419988
- VERSION5 = typeof MACRO !== "undefined" ? "1.13.8" : "unknown";
419996
+ VERSION5 = typeof MACRO !== "undefined" ? "1.13.9" : "unknown";
419989
419997
  MAX_TOMBSTONE_REWRITE_BYTES = 50 * 1024 * 1024;
419990
419998
  SKIP_FIRST_PROMPT_PATTERN = /^(?:\s*<[a-z][\w-]*[\s>]|\[Request interrupted by user[^\]]*\])/;
419991
419999
  EPHEMERAL_PROGRESS_TYPES = new Set([
@@ -421190,7 +421198,7 @@ var init_filesystem = __esm(() => {
421190
421198
  });
421191
421199
  getBundledSkillsRoot = memoize_default(function getBundledSkillsRoot2() {
421192
421200
  const nonce = randomBytes18(16).toString("hex");
421193
- return join170(getURTempDir(), "bundled-skills", "1.13.8", nonce);
421201
+ return join170(getURTempDir(), "bundled-skills", "1.13.9", nonce);
421194
421202
  });
421195
421203
  getResolvedWorkingDirPaths = memoize_default(getPathsForPermissionCheck);
421196
421204
  });
@@ -427221,7 +427229,7 @@ function computeFingerprint(messageText, version3) {
427221
427229
  }
427222
427230
  function computeFingerprintFromMessages(messages) {
427223
427231
  const firstMessageText = extractFirstMessageText(messages);
427224
- return computeFingerprint(firstMessageText, "1.13.8");
427232
+ return computeFingerprint(firstMessageText, "1.13.9");
427225
427233
  }
427226
427234
  var FINGERPRINT_SALT = "59cf53e54c78";
427227
427235
  var init_fingerprint = () => {};
@@ -429087,7 +429095,7 @@ async function sideQuery(opts) {
429087
429095
  betas.push(STRUCTURED_OUTPUTS_BETA_HEADER);
429088
429096
  }
429089
429097
  const messageText = extractFirstUserMessageText(messages);
429090
- const fingerprint = computeFingerprint(messageText, "1.13.8");
429098
+ const fingerprint = computeFingerprint(messageText, "1.13.9");
429091
429099
  const attributionHeader = getAttributionHeader(fingerprint);
429092
429100
  const systemBlocks = [
429093
429101
  attributionHeader ? { type: "text", text: attributionHeader } : null,
@@ -433824,7 +433832,7 @@ function buildSystemInitMessage(inputs) {
433824
433832
  slash_commands: inputs.commands.filter((c4) => c4.userInvocable !== false).map((c4) => c4.name),
433825
433833
  apiKeySource: getURHQApiKeyWithSource().source,
433826
433834
  betas: getSdkBetas(),
433827
- ur_version: "1.13.8",
433835
+ ur_version: "1.13.9",
433828
433836
  output_style: outputStyle2,
433829
433837
  agents: inputs.agents.map((agent) => agent.agentType),
433830
433838
  skills: inputs.skills.filter((s) => s.userInvocable !== false).map((skill) => skill.name),
@@ -448452,7 +448460,7 @@ var init_useVoiceEnabled = __esm(() => {
448452
448460
  function getSemverPart(version3) {
448453
448461
  return `${import_semver13.major(version3, { loose: true })}.${import_semver13.minor(version3, { loose: true })}.${import_semver13.patch(version3, { loose: true })}`;
448454
448462
  }
448455
- function useUpdateNotification(updatedVersion, initialVersion = "1.13.8") {
448463
+ function useUpdateNotification(updatedVersion, initialVersion = "1.13.9") {
448456
448464
  const [lastNotifiedSemver, setLastNotifiedSemver] = import_react224.useState(() => getSemverPart(initialVersion));
448457
448465
  if (!updatedVersion) {
448458
448466
  return null;
@@ -448501,7 +448509,7 @@ function AutoUpdater({
448501
448509
  return;
448502
448510
  }
448503
448511
  if (false) {}
448504
- const currentVersion = "1.13.8";
448512
+ const currentVersion = "1.13.9";
448505
448513
  const channel = getInitialSettings()?.autoUpdatesChannel ?? "latest";
448506
448514
  let latestVersion = await getLatestVersion(channel);
448507
448515
  const isDisabled = isAutoUpdaterDisabled();
@@ -448730,12 +448738,12 @@ function NativeAutoUpdater({
448730
448738
  logEvent("tengu_native_auto_updater_start", {});
448731
448739
  try {
448732
448740
  const maxVersion = await getMaxVersion();
448733
- if (maxVersion && gt("1.13.8", maxVersion)) {
448741
+ if (maxVersion && gt("1.13.9", maxVersion)) {
448734
448742
  const msg = await getMaxVersionMessage();
448735
448743
  setMaxVersionIssue(msg ?? "affects your version");
448736
448744
  }
448737
448745
  const result = await installLatest(channel);
448738
- const currentVersion = "1.13.8";
448746
+ const currentVersion = "1.13.9";
448739
448747
  const latencyMs = Date.now() - startTime;
448740
448748
  if (result.lockFailed) {
448741
448749
  logEvent("tengu_native_auto_updater_lock_contention", {
@@ -448872,17 +448880,17 @@ function PackageManagerAutoUpdater(t0) {
448872
448880
  const maxVersion = await getMaxVersion();
448873
448881
  if (maxVersion && latest && gt(latest, maxVersion)) {
448874
448882
  logForDebugging(`PackageManagerAutoUpdater: maxVersion ${maxVersion} is set, capping update from ${latest} to ${maxVersion}`);
448875
- if (gte("1.13.8", maxVersion)) {
448876
- logForDebugging(`PackageManagerAutoUpdater: current version ${"1.13.8"} is already at or above maxVersion ${maxVersion}, skipping update`);
448883
+ if (gte("1.13.9", maxVersion)) {
448884
+ logForDebugging(`PackageManagerAutoUpdater: current version ${"1.13.9"} is already at or above maxVersion ${maxVersion}, skipping update`);
448877
448885
  setUpdateAvailable(false);
448878
448886
  return;
448879
448887
  }
448880
448888
  latest = maxVersion;
448881
448889
  }
448882
- const hasUpdate = latest && !gte("1.13.8", latest) && !shouldSkipVersion(latest);
448890
+ const hasUpdate = latest && !gte("1.13.9", latest) && !shouldSkipVersion(latest);
448883
448891
  setUpdateAvailable(!!hasUpdate);
448884
448892
  if (hasUpdate) {
448885
- logForDebugging(`PackageManagerAutoUpdater: Update available ${"1.13.8"} -> ${latest}`);
448893
+ logForDebugging(`PackageManagerAutoUpdater: Update available ${"1.13.9"} -> ${latest}`);
448886
448894
  }
448887
448895
  };
448888
448896
  $3[0] = t1;
@@ -448916,7 +448924,7 @@ function PackageManagerAutoUpdater(t0) {
448916
448924
  wrap: "truncate",
448917
448925
  children: [
448918
448926
  "currentVersion: ",
448919
- "1.13.8"
448927
+ "1.13.9"
448920
448928
  ]
448921
448929
  }, undefined, true, undefined, this);
448922
448930
  $3[3] = verbose;
@@ -461278,7 +461286,7 @@ function buildStatusLineCommandInput(permissionMode, exceeds200kTokens, settings
461278
461286
  project_dir: getOriginalCwd(),
461279
461287
  added_dirs: addedDirs
461280
461288
  },
461281
- version: "1.13.8",
461289
+ version: "1.13.9",
461282
461290
  output_style: {
461283
461291
  name: outputStyleName
461284
461292
  },
@@ -472774,7 +472782,7 @@ async function submitTranscriptShare(messages, trigger2, appearanceId) {
472774
472782
  } catch {}
472775
472783
  const data = {
472776
472784
  trigger: trigger2,
472777
- version: "1.13.8",
472785
+ version: "1.13.9",
472778
472786
  platform: process.platform,
472779
472787
  transcript,
472780
472788
  subagentTranscripts: Object.keys(subagentTranscripts).length > 0 ? subagentTranscripts : undefined,
@@ -484689,7 +484697,7 @@ function WelcomeV2() {
484689
484697
  dimColor: true,
484690
484698
  children: [
484691
484699
  "v",
484692
- "1.13.8"
484700
+ "1.13.9"
484693
484701
  ]
484694
484702
  }, undefined, true, undefined, this)
484695
484703
  ]
@@ -485949,7 +485957,7 @@ function completeOnboarding() {
485949
485957
  saveGlobalConfig((current) => ({
485950
485958
  ...current,
485951
485959
  hasCompletedOnboarding: true,
485952
- lastOnboardingVersion: "1.13.8"
485960
+ lastOnboardingVersion: "1.13.9"
485953
485961
  }));
485954
485962
  }
485955
485963
  function showDialog(root2, renderer) {
@@ -490409,7 +490417,7 @@ function appendToLog(path24, message) {
490409
490417
  cwd: getFsImplementation().cwd(),
490410
490418
  userType: process.env.USER_TYPE,
490411
490419
  sessionId: getSessionId(),
490412
- version: "1.13.8"
490420
+ version: "1.13.9"
490413
490421
  };
490414
490422
  getLogWriter(path24).write(messageWithTimestamp);
490415
490423
  }
@@ -494435,8 +494443,8 @@ async function getEnvLessBridgeConfig() {
494435
494443
  }
494436
494444
  async function checkEnvLessBridgeMinVersion() {
494437
494445
  const cfg = await getEnvLessBridgeConfig();
494438
- if (cfg.min_version && lt("1.13.8", cfg.min_version)) {
494439
- return `Your version of UR (${"1.13.8"}) is too old for Remote Control.
494446
+ if (cfg.min_version && lt("1.13.9", cfg.min_version)) {
494447
+ return `Your version of UR (${"1.13.9"}) is too old for Remote Control.
494440
494448
  Version ${cfg.min_version} or higher is required. Run \`ur update\` to update.`;
494441
494449
  }
494442
494450
  return null;
@@ -494910,7 +494918,7 @@ async function initBridgeCore(params) {
494910
494918
  const rawApi = createBridgeApiClient({
494911
494919
  baseUrl,
494912
494920
  getAccessToken,
494913
- runnerVersion: "1.13.8",
494921
+ runnerVersion: "1.13.9",
494914
494922
  onDebug: logForDebugging,
494915
494923
  onAuth401,
494916
494924
  getTrustedDeviceToken
@@ -500575,7 +500583,7 @@ async function startMCPServer(cwd3, debug2, verbose) {
500575
500583
  setCwd(cwd3);
500576
500584
  const server = new Server({
500577
500585
  name: "ur/tengu",
500578
- version: "1.13.8"
500586
+ version: "1.13.9"
500579
500587
  }, {
500580
500588
  capabilities: {
500581
500589
  tools: {}
@@ -502186,7 +502194,7 @@ __export(exports_update, {
502186
502194
  });
502187
502195
  async function update() {
502188
502196
  logEvent("tengu_update_check", {});
502189
- writeToStdout(`Current version: ${"1.13.8"}
502197
+ writeToStdout(`Current version: ${"1.13.9"}
502190
502198
  `);
502191
502199
  const channel = getInitialSettings()?.autoUpdatesChannel ?? "latest";
502192
502200
  writeToStdout(`Checking for updates to ${channel} version...
@@ -502261,8 +502269,8 @@ async function update() {
502261
502269
  writeToStdout(`UR is managed by Homebrew.
502262
502270
  `);
502263
502271
  const latest = await getLatestVersion(channel);
502264
- if (latest && !gte("1.13.8", latest)) {
502265
- writeToStdout(`${formatUpdateAvailableMessage("1.13.8", latest)}
502272
+ if (latest && !gte("1.13.9", latest)) {
502273
+ writeToStdout(`${formatUpdateAvailableMessage("1.13.9", latest)}
502266
502274
  `);
502267
502275
  writeToStdout(`
502268
502276
  `);
@@ -502278,8 +502286,8 @@ async function update() {
502278
502286
  writeToStdout(`UR is managed by winget.
502279
502287
  `);
502280
502288
  const latest = await getLatestVersion(channel);
502281
- if (latest && !gte("1.13.8", latest)) {
502282
- writeToStdout(`${formatUpdateAvailableMessage("1.13.8", latest)}
502289
+ if (latest && !gte("1.13.9", latest)) {
502290
+ writeToStdout(`${formatUpdateAvailableMessage("1.13.9", latest)}
502283
502291
  `);
502284
502292
  writeToStdout(`
502285
502293
  `);
@@ -502295,8 +502303,8 @@ async function update() {
502295
502303
  writeToStdout(`UR is managed by apk.
502296
502304
  `);
502297
502305
  const latest = await getLatestVersion(channel);
502298
- if (latest && !gte("1.13.8", latest)) {
502299
- writeToStdout(`${formatUpdateAvailableMessage("1.13.8", latest)}
502306
+ if (latest && !gte("1.13.9", latest)) {
502307
+ writeToStdout(`${formatUpdateAvailableMessage("1.13.9", latest)}
502300
502308
  `);
502301
502309
  writeToStdout(`
502302
502310
  `);
@@ -502361,11 +502369,11 @@ async function update() {
502361
502369
  `);
502362
502370
  await gracefulShutdown(1);
502363
502371
  }
502364
- if (result.latestVersion === "1.13.8") {
502365
- writeToStdout(source_default.green(`UR is up to date (${"1.13.8"})`) + `
502372
+ if (result.latestVersion === "1.13.9") {
502373
+ writeToStdout(source_default.green(`UR is up to date (${"1.13.9"})`) + `
502366
502374
  `);
502367
502375
  } else {
502368
- writeToStdout(source_default.green(`Successfully updated from ${"1.13.8"} to version ${result.latestVersion}`) + `
502376
+ writeToStdout(source_default.green(`Successfully updated from ${"1.13.9"} to version ${result.latestVersion}`) + `
502369
502377
  `);
502370
502378
  await regenerateCompletionCache();
502371
502379
  }
@@ -502425,12 +502433,12 @@ async function update() {
502425
502433
  `);
502426
502434
  await gracefulShutdown(1);
502427
502435
  }
502428
- if (latestVersion === "1.13.8") {
502429
- writeToStdout(source_default.green(`UR is up to date (${"1.13.8"})`) + `
502436
+ if (latestVersion === "1.13.9") {
502437
+ writeToStdout(source_default.green(`UR is up to date (${"1.13.9"})`) + `
502430
502438
  `);
502431
502439
  await gracefulShutdown(0);
502432
502440
  }
502433
- writeToStdout(`${formatUpdateAvailableMessage("1.13.8", latestVersion)}
502441
+ writeToStdout(`${formatUpdateAvailableMessage("1.13.9", latestVersion)}
502434
502442
  `);
502435
502443
  writeToStdout(`Installing update...
502436
502444
  `);
@@ -502475,7 +502483,7 @@ async function update() {
502475
502483
  logForDebugging(`update: Installation status: ${status2}`);
502476
502484
  switch (status2) {
502477
502485
  case "success":
502478
- writeToStdout(source_default.green(`Successfully updated from ${"1.13.8"} to version ${latestVersion}`) + `
502486
+ writeToStdout(source_default.green(`Successfully updated from ${"1.13.9"} to version ${latestVersion}`) + `
502479
502487
  `);
502480
502488
  await regenerateCompletionCache();
502481
502489
  break;
@@ -503726,7 +503734,7 @@ ${customInstructions}` : customInstructions;
503726
503734
  }
503727
503735
  }
503728
503736
  logForDiagnosticsNoPII("info", "started", {
503729
- version: "1.13.8",
503737
+ version: "1.13.9",
503730
503738
  is_native_binary: isInBundledMode()
503731
503739
  });
503732
503740
  registerCleanup(async () => {
@@ -504510,7 +504518,7 @@ Usage: ur --remote "your task description"`, () => gracefulShutdown(1));
504510
504518
  pendingHookMessages
504511
504519
  }, renderAndRun);
504512
504520
  }
504513
- }).version("1.13.8 (Ur)", "-v, --version", "Output the version number");
504521
+ }).version("1.13.9 (Ur)", "-v, --version", "Output the version number");
504514
504522
  program2.option("-w, --worktree [name]", "Create a new git worktree for this session (optionally specify a name)");
504515
504523
  program2.option("--tmux", "Create a tmux session for the worktree (requires --worktree). Uses iTerm2 native panes when available; use --tmux=classic for traditional tmux.");
504516
504524
  if (canUserConfigureAdvisor()) {
@@ -504799,6 +504807,26 @@ Usage: ur --remote "your task description"`, () => gracefulShutdown(1));
504799
504807
  const args = [action2, name, opts.objective ? `--objective ${quoteLocalCommandArg(opts.objective)}` : undefined, opts.workflow ? `--workflow ${quoteLocalCommandArg(opts.workflow)}` : undefined, opts.pattern ? `--pattern ${quoteLocalCommandArg(opts.pattern)}` : undefined, opts.note ? `--note ${quoteLocalCommandArg(opts.note)}` : undefined, opts.maxTurns ? `--max-turns ${opts.maxTurns}` : undefined, opts.dryRun ? "--dry-run" : undefined, opts.json ? "--json" : undefined].filter(Boolean).join(" ");
504800
504808
  await runLocalTextCommand(() => Promise.resolve().then(() => (init_goal(), exports_goal)), args);
504801
504809
  });
504810
+ 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 (action2, name, phase, opts) => {
504811
+ const args = [action2, 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(" ");
504812
+ await runLocalTextCommand(() => Promise.resolve().then(() => (init_spec2(), exports_spec)), args);
504813
+ });
504814
+ 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 (action2, task = [], opts) => {
504815
+ const args = [action2, ...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(" ");
504816
+ await runLocalTextCommand(() => Promise.resolve().then(() => (init_escalate(), exports_escalate)), args);
504817
+ });
504818
+ program2.command("arena [task...]").alias("best-of").description("Run N agents on the same task in isolated worktrees, judge the diffs, and surface the winner").option("--agents <n>", "Number of competing agents (default 3)").option("--models <list>", "Comma-separated per-agent models").option("--apply", "Apply the winning diff to the working tree").option("--keep", "Keep the candidate worktrees after judging").option("--dry-run", "Run offline without calling any model").option("--max-turns <n>", "Max agentic turns per agent").option("--skip-permissions", "Pass --dangerously-skip-permissions to each agent (sandboxes only)").option("--json", "Output as JSON").action(async (task = [], opts) => {
504819
+ const args = [...task, opts.agents ? `--agents ${opts.agents}` : undefined, opts.models ? `--models ${quoteLocalCommandArg(opts.models)}` : undefined, opts.apply ? "--apply" : undefined, opts.keep ? "--keep" : 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(" ");
504820
+ await runLocalTextCommand(() => Promise.resolve().then(() => (init_arena2(), exports_arena)), args);
504821
+ });
504822
+ program2.command("ci-loop").alias("heal").description("Self-healing CI: run a build/test command and, on failure, capture the error, fix it, and re-run with bounded retries").option("--command <cmd>", 'Command to run (default "bun test")').option("--max-attempts <n>", "Maximum fix attempts (default 3)").option("--from-log <path>", "Seed the first failure from an existing log file").option("--commit", "Commit each fix (self-review gated)").option("--push", "Commit and push each fix").option("--dry-run", "Show the plan without running").option("--skip-permissions", "Pass --dangerously-skip-permissions to the fix agent (sandboxes only)").option("--max-turns <n>", "Max agentic turns for the fix agent").option("--json", "Output as JSON").action(async (opts) => {
504823
+ const args = [opts.command ? `--command ${quoteLocalCommandArg(opts.command)}` : undefined, opts.maxAttempts ? `--max-attempts ${opts.maxAttempts}` : undefined, opts.fromLog ? `--from-log ${quoteLocalCommandArg(opts.fromLog)}` : undefined, opts.commit ? "--commit" : undefined, opts.push ? "--push" : undefined, opts.dryRun ? "--dry-run" : undefined, opts.skipPermissions ? "--skip-permissions" : undefined, opts.maxTurns ? `--max-turns ${opts.maxTurns}` : undefined, opts.json ? "--json" : undefined].filter(Boolean).join(" ");
504824
+ await runLocalTextCommand(() => Promise.resolve().then(() => (init_ci_loop(), exports_ci_loop)), args);
504825
+ });
504826
+ program2.command("artifacts [action] [id]").alias("artifact").description("Reviewable deliverables (plans, diffs, test runs) with approve/reject/feedback under .ur/artifacts").option("--kind <kind>", "Artifact kind: plan|diff|test-run|screenshot|browser-recording|note").option("--title <text>", "Artifact title").option("--body <text>", "Inline artifact body").option("--file <path>", "Attach an existing file as the artifact body").option("--summary <text>", "Short summary line").option("--feedback <text>", "Feedback text for reject/feedback").option("--command <cmd>", 'Command for capture-tests (default "bun test")').option("--json", "Output as JSON").action(async (action2, id, opts) => {
504827
+ const args = [action2, id, opts.kind ? `--kind ${quoteLocalCommandArg(opts.kind)}` : undefined, opts.title ? `--title ${quoteLocalCommandArg(opts.title)}` : undefined, opts.body ? `--body ${quoteLocalCommandArg(opts.body)}` : undefined, opts.file ? `--file ${quoteLocalCommandArg(opts.file)}` : undefined, opts.summary ? `--summary ${quoteLocalCommandArg(opts.summary)}` : undefined, opts.feedback ? `--feedback ${quoteLocalCommandArg(opts.feedback)}` : undefined, opts.command ? `--command ${quoteLocalCommandArg(opts.command)}` : undefined, opts.json ? "--json" : undefined].filter(Boolean).join(" ");
504828
+ await runLocalTextCommand(() => Promise.resolve().then(() => (init_artifacts2(), exports_artifacts)), args);
504829
+ });
504802
504830
  program2.command("trigger [action]").alias("mention").description("Parse a GitHub/Slack webhook payload and optionally launch a headless UR run").option("--file <path>", "Webhook payload JSON file").option("--source <source>", "Force payload source: github|slack|generic").option("--keyword <keyword>", "Mention/command that triggers a run (default /ur)").option("--max-turns <n>", "Max agentic turns for the launched run").option("--dry-run", "Show the command without executing it (run action)").option("--json", "Output as JSON").action(async (action2, opts) => {
504803
504831
  const args = [action2, opts.file ? `--file ${quoteLocalCommandArg(opts.file)}` : undefined, opts.source ? `--source ${quoteLocalCommandArg(opts.source)}` : undefined, opts.keyword ? `--keyword ${quoteLocalCommandArg(opts.keyword)}` : undefined, opts.maxTurns ? `--max-turns ${opts.maxTurns}` : undefined, opts.dryRun ? "--dry-run" : undefined, opts.json ? "--json" : undefined].filter(Boolean).join(" ");
504804
504832
  await runLocalTextCommand(() => Promise.resolve().then(() => (init_trigger(), exports_trigger)), args);
@@ -505200,7 +505228,7 @@ if (false) {}
505200
505228
  async function main2() {
505201
505229
  const args = process.argv.slice(2);
505202
505230
  if (args.length === 1 && (args[0] === "--version" || args[0] === "-v" || args[0] === "-V")) {
505203
- console.log(`${"1.13.8"} (Ur)`);
505231
+ console.log(`${"1.13.9"} (Ur)`);
505204
505232
  return;
505205
505233
  }
505206
505234
  if (args[0] === "a2a" && args[1] === "serve" && !args.includes("--help") && !args.includes("-h")) {
@@ -77,3 +77,33 @@ Cline/Roo, and Copilot workflows.
77
77
  concept — installing a mode just writes a scoped agent definition.
78
78
  - The self-review gate is heuristic and deterministic; it is the automatic
79
79
  safety net on the PR path, not a replacement for the model-driven review.
80
+
81
+ ## v1.13.9 Additions
82
+
83
+ Five additions from a comparison with current Kiro/Spec Kit, Amp, Cursor,
84
+ Jules, and Antigravity workflows. All keep model and exec behind injectable
85
+ runners, so the core logic is deterministic and unit-tested offline.
86
+
87
+ | Addition | Surface | What it adds |
88
+ | --- | --- | --- |
89
+ | Spec-driven development | `ur spec init\|generate\|approve\|run\|status` + `.ur/specs/` | requirements -> design -> tasks documents and a phase/approval record; executes the Spec Kit / Kiro `- [ ] T1: ...` task list one task at a time, checking off each PASS |
90
+ | In-loop model escalation | `ur escalate plan\|run\|oracle\|policy` + `.ur/escalation.json` | capability-aware fast/oracle tiers from `model-doctor`; routine work runs fast and auto-escalates hard/failed work to the strong model; `oracle` is a one-shot second opinion |
91
+ | Best-of-N judging | `ur arena "<task>" [--agents N] [--apply]` | runs N agents on one task in isolated worktrees, scores diffs with the self-review gate + verdict/diff heuristics, surfaces (optionally applies) the winner |
92
+ | Self-healing CI loop | `ur ci-loop [--command ...] [--commit] [--push]` | run -> on failure summarize -> fix agent -> re-run, bounded by retries; commits/pushes are self-review gated; `--from-log` seeds the first failure |
93
+ | Verifiable artifacts | `ur artifacts add\|capture-diff\|capture-tests\|approve\|reject` + `.ur/artifacts/` | reviewable deliverables with pending/approved/rejected status and threaded feedback; threads into the provenance stack (`claim-ledger`, `trace`, `evidence`) |
94
+
95
+ ### Commands
96
+
97
+ ```sh
98
+ ur spec init checkout --goal "1. add cart 2. add payment 3. add receipt"
99
+ ur spec approve checkout requirements
100
+ ur spec run checkout --all
101
+ ur escalate plan "debug the race condition in the scheduler"
102
+ ur escalate run "refactor the cache layer" --force-oracle
103
+ ur escalate oracle "is this lock-free queue correct?"
104
+ ur arena "implement the rate limiter" --agents 3 --apply
105
+ ur ci-loop --command "bun test" --max-attempts 3
106
+ ur artifacts capture-diff
107
+ ur artifacts capture-tests --command "bun test"
108
+ ur artifacts approve 1
109
+ ```
@@ -23,6 +23,14 @@ ur code-index build
23
23
  ur code-index search "where is the rate limiter configured"
24
24
  ur role-mode install all
25
25
  ur agent-task pr --create --dry-run # runs the self-review gate first
26
+ ur spec init checkout --goal "1. add cart 2. add payment 3. add receipt"
27
+ ur spec run checkout --all --dry-run
28
+ ur escalate plan "debug the scheduler race"
29
+ ur escalate run "refactor the cache layer" --force-oracle --dry-run
30
+ ur arena "implement a debounce helper" --agents 2 --dry-run
31
+ ur ci-loop --command "bun test" --dry-run
32
+ ur artifacts capture-diff
33
+ ur artifacts capture-tests --command "bun test"
26
34
  ur claim-ledger validate
27
35
  ur browser-qa validate
28
36
  ```
@@ -52,6 +60,26 @@ Inside an interactive session:
52
60
  | Security and prompt-injection resistance | Covered | allow/ask/deny permissions, shell safety analysis, secret scan, untrusted web-content guidance, OS-level execution sandbox (macOS Seatbelt, Linux bubblewrap) | Continuously test web/MCP injection cases |
53
61
  | Agent identity and delegated authorization | Partial | MCP OAuth/XAA helpers, local trust boundaries, permission rules | Add portable cross-agent identity only with an opt-in A2A task adapter |
54
62
  | Multimodal workflows | Partial | `/image`, `/video`, `/youtube`, `/voice`, browser workflows | Add model-aware multimodal capability reporting for local Ollama setups |
63
+ | Spec-driven development | Covered | `ur spec` scaffolds requirements/design/tasks under `.ur/specs/`, tracks phase/approvals, and runs the Spec Kit / Kiro task list one task at a time | Add bidirectional sync with an external `specs/` directory |
64
+ | Capability-aware model escalation | Covered | `ur escalate` selects fast/oracle tiers from `model-doctor`, runs routine work fast, and auto-escalates hard/failed work to the strong local model | Learn per-model success rates to tune the difficulty threshold |
65
+ | Best-of-N agent judging | Covered | `ur arena` runs N agents per task in isolated worktrees and judges diffs with the self-review gate; winner is selectable/appliable | Add an optional model judge alongside the deterministic scorer |
66
+ | Self-healing CI | Covered | `ur ci-loop` runs a command, summarizes failures, invokes a fix agent, and re-runs with bounded retries; commits/pushes are self-review gated | Wire to `ur trigger` so a failed CI webhook auto-launches the loop |
67
+ | Verifiable artifacts | Covered | `ur artifacts` records plans/diffs/test-runs with approve/reject/feedback under `.ur/artifacts/` | Attach browser-QA screenshots and link artifacts to claim-ledger entries |
68
+
69
+ ## v1.13.9 Direct CLI Surfaces
70
+
71
+ These surfaces are registered as normal shell subcommands and as local slash
72
+ commands, so users can run them directly without inserting `--` before their
73
+ feature-specific flags:
74
+
75
+ ```sh
76
+ ur spec init demo --goal "1. add a utils.add function 2. add a test"
77
+ ur spec run demo --all --dry-run
78
+ ur arena "implement a debounce helper" --agents 2 --dry-run
79
+ ur escalate run "refactor the cache layer" --force-oracle --dry-run
80
+ ur ci-loop --command "bun test" --dry-run
81
+ ur artifacts capture-tests --command "bun test"
82
+ ```
55
83
 
56
84
  ## A2A Position
57
85
 
package/docs/USAGE.md CHANGED
@@ -84,6 +84,11 @@ UR includes slash commands and CLI subcommands for common workflows:
84
84
  - `ur agents` to list configured agents
85
85
  - `ur agent-trends` to inspect coverage for current agent technology trends
86
86
  - `ur a2a card` to print UR's Agent Card metadata for A2A discovery
87
+ - `ur spec ...` to scaffold requirements, design, and tasks, then run a spec task list
88
+ - `ur escalate ...` to plan, run, or ask an oracle model for hard tasks
89
+ - `ur arena ...` to run multiple agents on the same task and select a winner
90
+ - `ur ci-loop ...` to run tests, repair failures, and rerun with a bounded loop
91
+ - `ur artifacts ...` to capture reviewable diffs, test runs, notes, and feedback
87
92
  - `ur doctor` to inspect CLI health
88
93
  - `ur update` or `ur upgrade` to check for updates
89
94
 
@@ -92,6 +97,17 @@ Interactive sessions also check the published package version and show
92
97
 
93
98
  Run each command with `--help` for exact flags.
94
99
 
100
+ Agent platform examples:
101
+
102
+ ```sh
103
+ ur spec init demo --goal "1. add a utils.add function 2. add a test"
104
+ ur spec run demo --all --dry-run
105
+ ur arena "implement a debounce helper" --agents 2 --dry-run
106
+ ur escalate run "refactor the cache layer" --force-oracle --dry-run
107
+ ur ci-loop --command "bun test" --dry-run
108
+ ur artifacts capture-diff
109
+ ```
110
+
95
111
  ## Permissions
96
112
 
97
113
  By default, UR asks before sensitive tool actions. For automation, use explicit allow and deny lists:
@@ -17,7 +17,7 @@ You need:
17
17
 
18
18
  ```sh
19
19
  ur --version
20
- # expected: 1.13.8 (Ur)
20
+ # expected: 1.13.9 (Ur)
21
21
  ```
22
22
 
23
23
  ## 1. Marketplace tree resolves
@@ -184,6 +184,22 @@ for any literal `<system-reminder>` text. There should be none. The filter
184
184
  strips them at render time as defense in depth even if the model echoes a
185
185
  reminder back.
186
186
 
187
+ ## 9. Direct agent-platform commands parse feature flags
188
+
189
+ These commands should parse their own flags directly, without requiring a `--`
190
+ separator after the command name:
191
+
192
+ ```sh
193
+ ur spec init validation-demo --goal "1. add a helper 2. add a test"
194
+ ur spec run validation-demo --all --dry-run
195
+ ur arena "implement a debounce helper" --agents 2 --dry-run
196
+ ur escalate run "refactor the cache layer" --force-oracle --dry-run
197
+ ur ci-loop --command "bun test" --dry-run
198
+ ur artifacts capture-tests --command "bun test"
199
+ ```
200
+
201
+ Expected: no `unknown option` or `too many arguments` parser errors.
202
+
187
203
  ## What to do if any step fails
188
204
 
189
205
  - Step 1 (marketplace): check `ls ~/.ur/marketplaces/` — `ur-plugins-official`
@@ -196,3 +212,7 @@ reminder back.
196
212
  to register — file an issue with the version (`ur --version`).
197
213
  - Step 8 (filter): if `<system-reminder>` appears in visible prose, copy
198
214
  the literal output and file an issue.
215
+ - Step 9 (direct commands): run `ur --help` and confirm `spec`, `arena`,
216
+ `escalate`, `ci-loop`, and `artifacts` appear. If `unknown option` or
217
+ `too many arguments` appears, reinstall `ur-agent@latest` and verify the
218
+ npm version with `npm view ur-agent version`.
@@ -13,9 +13,15 @@ const featureGroups = [
13
13
  },
14
14
  {
15
15
  title: 'Agent platform',
16
- tags: ['workflow', 'pattern', 'crew', 'goal'],
17
- text: 'Durable workflows, collaboration patterns, parallel crews, long-horizon goals, live execution boards, and resumable checkpoint state.',
18
- commands: ['ur workflow', 'ur pattern', 'ur crew', 'ur goal'],
16
+ tags: ['spec', 'workflow', 'pattern', 'crew', 'goal'],
17
+ text: 'Spec-driven development, durable workflows, collaboration patterns, parallel crews, long-horizon goals, live execution boards, and resumable checkpoint state.',
18
+ commands: ['ur spec', 'ur workflow', 'ur pattern', 'ur crew', 'ur goal'],
19
+ },
20
+ {
21
+ title: 'Judging, escalation, and repair',
22
+ tags: ['oracle', 'arena', 'CI', 'artifacts'],
23
+ text: 'Capability-aware fast/oracle model routing, best-of-N agent judging, self-healing CI loops, and reviewable artifacts for diffs, test runs, plans, and feedback.',
24
+ commands: ['ur escalate', 'ur arena', 'ur ci-loop', 'ur artifacts'],
19
25
  },
20
26
  {
21
27
  title: 'Automation and triggers',
@@ -32,8 +38,8 @@ const featureGroups = [
32
38
  {
33
39
  title: 'Evaluation and verification',
34
40
  tags: ['evals', 'review', 'QA'],
35
- text: 'Replayable eval suites, self-review PR gate, browser QA fixtures, verifier reminders, trace inspection, and subagent timelines.',
36
- commands: ['ur eval', 'ur agent-task', 'ur browser-qa', '/verify', '/trace'],
41
+ text: 'Replayable eval suites, self-review PR gate, browser QA fixtures, verifier reminders, trace inspection, reviewable artifacts, and subagent timelines.',
42
+ commands: ['ur eval', 'ur agent-task', 'ur browser-qa', 'ur artifacts', '/verify', '/trace'],
37
43
  },
38
44
  {
39
45
  title: 'Interoperability',
@@ -113,6 +119,20 @@ const commands = [
113
119
  summary: 'List configured agents and project agents available to sessions.',
114
120
  examples: ['ur agents', 'ur --agents \'{"reviewer":{"description":"Reviews code","prompt":"Review carefully"}}\''],
115
121
  },
122
+ {
123
+ name: 'arena',
124
+ category: 'Agent Platform',
125
+ aliases: ['best-of'],
126
+ summary: 'Run multiple agents on the same task in isolated worktrees, score their diffs, and optionally apply the winning patch.',
127
+ examples: ['ur arena "implement a debounce helper" --agents 2 --dry-run', 'ur arena "implement the rate limiter" --agents 3', 'ur arena "fix the parser" --agents 3 --apply'],
128
+ },
129
+ {
130
+ name: 'artifacts',
131
+ category: 'Evidence',
132
+ aliases: ['artifact'],
133
+ summary: 'Record reviewable deliverables under `.ur/artifacts` with pending, approved, rejected, and feedback states.',
134
+ examples: ['ur artifacts list', 'ur artifacts capture-diff', 'ur artifacts capture-tests --command "bun test"', 'ur artifacts approve 1', 'ur artifacts reject 1 --feedback "Needs a failing test first"'],
135
+ },
116
136
  {
117
137
  name: 'auth',
118
138
  category: 'Ops',
@@ -134,6 +154,13 @@ const commands = [
134
154
  summary: 'Validate and smoke-run browser replay fixtures under `.ur/browser-qa`.',
135
155
  examples: ['ur browser-qa list', 'ur browser-qa validate', 'ur browser-qa run home-page-smoke --dry-run'],
136
156
  },
157
+ {
158
+ name: 'ci-loop',
159
+ category: 'Automation',
160
+ aliases: ['heal'],
161
+ summary: 'Run a build or test command, summarize failures, invoke a fix agent, and rerun with a bounded retry budget.',
162
+ examples: ['ur ci-loop --command "bun test" --dry-run', 'ur ci-loop --command "bun test" --max-attempts 3', 'ur ci-loop --from-log failure.log --dry-run', 'ur ci-loop --command "bun test" --commit'],
163
+ },
137
164
  {
138
165
  name: 'claim-ledger',
139
166
  category: 'Evidence',
@@ -162,6 +189,13 @@ const commands = [
162
189
  summary: 'Check health of the installation and configured environment.',
163
190
  examples: ['ur doctor', 'ur ur-doctor', 'ur model-doctor'],
164
191
  },
192
+ {
193
+ name: 'escalate',
194
+ category: 'Models',
195
+ aliases: [],
196
+ summary: 'Plan, run, or consult a capability-aware fast/oracle model path for hard reasoning, debugging, review, and refactor tasks.',
197
+ examples: ['ur escalate plan "debug the scheduler race"', 'ur escalate run "refactor the cache layer" --force-oracle --dry-run', 'ur escalate oracle "is this lock-free queue correct?"', 'ur escalate policy --fast qwen2.5-coder --oracle qwen3-coder:480b-cloud'],
198
+ },
165
199
  {
166
200
  name: 'eval',
167
201
  category: 'Verification',
@@ -253,6 +287,13 @@ const commands = [
253
287
  summary: 'Build and search a project-local memory index over durable memory, docs, README, and instructions.',
254
288
  examples: ['ur semantic-memory build', 'ur semantic-memory search "release process"', 'ur semantic-memory status --json'],
255
289
  },
290
+ {
291
+ name: 'spec',
292
+ category: 'Agent Platform',
293
+ aliases: ['specs'],
294
+ summary: 'Scaffold requirements, design, and task documents under `.ur/specs`, track approvals, and run the task list one item at a time.',
295
+ examples: ['ur spec init demo --goal "1. add a utils.add function 2. add a test"', 'ur spec status demo', 'ur spec approve demo requirements', 'ur spec run demo --all --dry-run', 'ur spec generate demo tasks --dry-run'],
296
+ },
256
297
  {
257
298
  name: 'setup-token',
258
299
  category: 'Ops',
@@ -291,7 +332,7 @@ const slashGroups = [
291
332
  },
292
333
  {
293
334
  title: 'Editing and delivery',
294
- items: ['/diff', '/commit', '/commit-push-pr', '/review', '/verify', '/trace', '/agent-task'],
335
+ items: ['/diff', '/commit', '/commit-push-pr', '/review', '/verify', '/trace', '/agent-task', '/artifacts'],
295
336
  text: 'Review changes, create commits, prepare PRs, inspect the trace, and run verification.',
296
337
  },
297
338
  {
@@ -301,8 +342,8 @@ const slashGroups = [
301
342
  },
302
343
  {
303
344
  title: 'Agents and orchestration',
304
- items: ['/agents', '/agent-templates', '/workflow', '/pattern', '/crew', '/goal', '/route', '/role-mode'],
305
- text: 'Manage agents, install role modes, run workflows, and coordinate multi-agent work.',
345
+ items: ['/agents', '/agent-templates', '/spec', '/workflow', '/pattern', '/crew', '/goal', '/arena', '/route', '/role-mode'],
346
+ text: 'Manage agents, install role modes, run specs and workflows, and coordinate multi-agent work.',
306
347
  },
307
348
  {
308
349
  title: 'Memory and evidence',
@@ -311,13 +352,13 @@ const slashGroups = [
311
352
  },
312
353
  {
313
354
  title: 'Automation and evals',
314
- items: ['/automation', '/trigger', '/eval', '/browser-qa', '/actions', '/stability'],
315
- text: 'Run recurring prompts, webhook-triggered runs, browser smoke checks, evals, and stability diagnostics.',
355
+ items: ['/automation', '/trigger', '/ci-loop', '/eval', '/browser-qa', '/actions', '/stability'],
356
+ text: 'Run recurring prompts, webhook-triggered runs, self-healing CI loops, browser smoke checks, evals, and stability diagnostics.',
316
357
  },
317
358
  {
318
359
  title: 'Models, tools, and interop',
319
- items: ['/model', '/model-doctor', '/model-route', '/mcp', '/plugin', '/skills', '/sdk', '/a2a-card'],
320
- text: 'Pick models, inspect capabilities, manage MCP/plugin extensions, and expose interop surfaces.',
360
+ items: ['/model', '/model-doctor', '/model-route', '/escalate', '/mcp', '/plugin', '/skills', '/sdk', '/a2a-card'],
361
+ text: 'Pick models, inspect capabilities, escalate to oracle models, manage MCP/plugin extensions, and expose interop surfaces.',
321
362
  },
322
363
  {
323
364
  title: 'Security operations',
@@ -362,6 +403,11 @@ const projectFiles = [
362
403
  text: 'Workflow YAML specs and checkpoint state for `ur workflow` and goal resumes.',
363
404
  example: 'ur workflow init release',
364
405
  },
406
+ {
407
+ title: '.ur/specs/',
408
+ text: 'Spec-driven requirements, design, task lists, phase state, and approvals for `ur spec`.',
409
+ example: 'ur spec init demo --goal "1. add a helper 2. add a test"',
410
+ },
365
411
  {
366
412
  title: '.ur/automations/',
367
413
  text: 'Cron-like automation specs for project-local scheduled headless prompts.',
@@ -382,6 +428,11 @@ const projectFiles = [
382
428
  text: 'Claim provenance ledger and evidence files.',
383
429
  example: 'ur claim-ledger validate',
384
430
  },
431
+ {
432
+ title: '.ur/artifacts/',
433
+ text: 'Reviewable plans, diffs, test runs, screenshots, notes, approvals, rejections, and feedback.',
434
+ example: 'ur artifacts capture-diff',
435
+ },
385
436
  {
386
437
  title: '.ur/browser-qa/',
387
438
  text: 'Browser replay fixtures and smoke-test targets.',
@@ -410,6 +461,31 @@ const examples = [
410
461
  text: 'Dry-run first, then create the PR after the deterministic gate passes.',
411
462
  code: 'ur agent-task pr --create --dry-run\nur agent-task pr --create',
412
463
  },
464
+ {
465
+ title: 'Spec-driven implementation',
466
+ text: 'Create requirements, design, and tasks, then run one task at a time.',
467
+ code: 'ur spec init demo --goal "1. add a utils.add function 2. add a test"\nur spec status demo\nur spec run demo --all --dry-run',
468
+ },
469
+ {
470
+ title: 'Best-of-N agent run',
471
+ text: 'Let isolated agents attempt the same task and surface the strongest diff.',
472
+ code: 'ur arena "implement a debounce helper" --agents 2 --dry-run\nur arena "fix the parser" --agents 3 --apply',
473
+ },
474
+ {
475
+ title: 'Model escalation',
476
+ text: 'Plan a fast/oracle route or force the oracle path for hard work.',
477
+ code: 'ur escalate plan "debug the scheduler race"\nur escalate run "refactor the cache layer" --force-oracle --dry-run',
478
+ },
479
+ {
480
+ title: 'Self-healing CI',
481
+ text: 'Run a test command, summarize failures, attempt a bounded fix loop, and rerun.',
482
+ code: 'ur ci-loop --command "bun test" --dry-run\nur ci-loop --command "bun test" --max-attempts 3',
483
+ },
484
+ {
485
+ title: 'Reviewable artifacts',
486
+ text: 'Capture diffs or test runs for approval and feedback.',
487
+ code: 'ur artifacts capture-diff\nur artifacts capture-tests --command "bun test"\nur artifacts approve 1',
488
+ },
413
489
  {
414
490
  title: 'A2A local task server',
415
491
  text: 'Expose Agent Card discovery and token-gated task execution.',
@@ -43,7 +43,7 @@
43
43
  <main id="content" class="content">
44
44
  <header class="topbar">
45
45
  <div>
46
- <p class="eyebrow">Version 1.13.8</p>
46
+ <p class="eyebrow">Version 1.13.9</p>
47
47
  <h1>UR Agent Documentation</h1>
48
48
  <p class="lead">A practical, tutorial-style reference for installing, configuring, automating, extending, and operating UR Agent.</p>
49
49
  </div>
@@ -249,6 +249,68 @@ ur automation run-due --dry-run
249
249
  ur automation install --platform launchd --interval 300
250
250
  ur automation status</code></pre>
251
251
  </article>
252
+
253
+ <article>
254
+ <h3>Drive a change from a spec</h3>
255
+ <ol>
256
+ <li>Create a spec with requirements, design, tasks, and approval state.</li>
257
+ <li>Inspect or approve each phase.</li>
258
+ <li>Run the task list one item at a time, or use <code>--all</code>.</li>
259
+ </ol>
260
+ <pre><code>ur spec init demo --goal "1. add a utils.add function 2. add a test"
261
+ ur spec status demo
262
+ ur spec approve demo requirements
263
+ ur spec run demo --all --dry-run</code></pre>
264
+ </article>
265
+
266
+ <article>
267
+ <h3>Escalate hard work to an oracle model</h3>
268
+ <ol>
269
+ <li>Ask UR to plan the fast/oracle model route.</li>
270
+ <li>Run routine work on the fast tier.</li>
271
+ <li>Force or auto-trigger oracle escalation for hard debugging and review.</li>
272
+ </ol>
273
+ <pre><code>ur escalate plan "debug the scheduler race"
274
+ ur escalate run "refactor the cache layer" --force-oracle --dry-run
275
+ ur escalate oracle "is this lock-free queue correct?"</code></pre>
276
+ </article>
277
+
278
+ <article>
279
+ <h3>Compare multiple agent attempts</h3>
280
+ <ol>
281
+ <li>Run multiple agents against the same task in isolated worktrees.</li>
282
+ <li>Let the deterministic self-review gate score the candidate diffs.</li>
283
+ <li>Apply the winner only when you are ready.</li>
284
+ </ol>
285
+ <pre><code>ur arena "implement a debounce helper" --agents 2 --dry-run
286
+ ur arena "fix the parser" --agents 3
287
+ ur arena "fix the parser" --agents 3 --apply</code></pre>
288
+ </article>
289
+
290
+ <article>
291
+ <h3>Repair failing CI in a bounded loop</h3>
292
+ <ol>
293
+ <li>Run the build or test command.</li>
294
+ <li>Summarize the failure and launch a fix attempt.</li>
295
+ <li>Rerun until the command passes or the retry budget is exhausted.</li>
296
+ </ol>
297
+ <pre><code>ur ci-loop --command "bun test" --dry-run
298
+ ur ci-loop --command "bun test" --max-attempts 3
299
+ ur ci-loop --from-log failure.log --dry-run</code></pre>
300
+ </article>
301
+
302
+ <article>
303
+ <h3>Capture reviewable artifacts</h3>
304
+ <ol>
305
+ <li>Capture the current diff or a test run under <code>.ur/artifacts</code>.</li>
306
+ <li>Review the saved body and status.</li>
307
+ <li>Approve, reject, or add feedback.</li>
308
+ </ol>
309
+ <pre><code>ur artifacts capture-diff
310
+ ur artifacts capture-tests --command "bun test"
311
+ ur artifacts show 1
312
+ ur artifacts approve 1</code></pre>
313
+ </article>
252
314
  </div>
253
315
  </section>
254
316
 
@@ -361,9 +423,17 @@ ur automation daemon --once --dry-run</code></pre>
361
423
  <h3>Need evidence of what happened</h3>
362
424
  <pre><code>/trace 20
363
425
  ur agent-inspect --file session.jsonl
426
+ ur artifacts list
364
427
  ur eval report starter
365
428
  ur claim-ledger validate</code></pre>
366
429
  </article>
430
+ <article>
431
+ <h3>New agent-platform command is missing</h3>
432
+ <pre><code>ur --version
433
+ ur --help | grep -E "spec|arena|escalate|ci-loop|artifacts"
434
+ npm install -g ur-agent@latest --registry=https://registry.npmjs.org/
435
+ hash -r</code></pre>
436
+ </article>
367
437
  </div>
368
438
  </section>
369
439
  </main>
@@ -40,6 +40,20 @@ ur claim-ledger validate
40
40
  ur browser-qa validate
41
41
  ```
42
42
 
43
+ Run the v1.13.9 spec, escalation, judging, CI, and artifact flows:
44
+
45
+ ```sh
46
+ ur spec init demo --goal "1. add a utils.add function 2. add a test"
47
+ ur spec status demo
48
+ ur spec run demo --all --dry-run
49
+ ur escalate plan "debug the scheduler race"
50
+ ur escalate run "refactor the cache layer" --force-oracle --dry-run
51
+ ur arena "implement a debounce helper" --agents 2 --dry-run
52
+ ur ci-loop --command "bun test" --dry-run
53
+ ur artifacts capture-diff
54
+ ur artifacts capture-tests --command "bun test"
55
+ ```
56
+
43
57
  Run the opt-in A2A server on loopback:
44
58
 
45
59
  ```sh
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "ur-agent",
3
- "version": "1.13.8",
3
+ "version": "1.13.9",
4
4
  "description": "UR terminal coding agent CLI",
5
5
  "type": "module",
6
6
  "packageManager": "bun@1.3.14",