ur-agent 1.65.4 → 1.65.6

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,91 @@
1
1
  # Changelog
2
2
 
3
+ ## 1.65.6
4
+
5
+ - Remote sessions no longer reconnect forever when the server repeatedly
6
+ accepts a WebSocket upgrade and then reports that the session is missing.
7
+ Repeated `connect()` calls reuse the live client, malformed permission and
8
+ cancellation frames fail safely, and the cancellation wire type now matches
9
+ the runtime schema.
10
+ - Tool execution can no longer silently run zero tools because of a negative
11
+ concurrency setting. Concurrency is normalized to a bounded range, and
12
+ serial or parallel tool cancellation always clears in-progress state.
13
+ - Replaced scattered and sometimes unsafe model instructions with one compact,
14
+ ordered execution contract shared by normal, minimal, and remote modes. It
15
+ preserves structured tool use, dependency-aware parallel calls, result
16
+ observation, recovery, verification, honest completion, and prompt-injection
17
+ boundaries while removing guesses such as forcing system Python package
18
+ installs. Ollama retains an explicit native-tool discipline and may use text
19
+ recovery only when the runtime says native tools are unavailable.
20
+ - Tool calls are normalized and validated again at the final execution
21
+ boundary, including permission-hook rewrites. Unknown tools, duplicate IDs,
22
+ malformed object inputs, and unsafe read-to-write rewrites fail closed.
23
+ Ollama/Kimi streaming repairs supported split calls without turning invalid
24
+ arguments into empty objects, deduplicates cumulative frames, and preserves
25
+ distinct same-name calls.
26
+ - Task planning now uses dependency-ordered lifecycle guidance, atomic
27
+ task-store updates, transactional dependency checks, and strict gate reads.
28
+ Mutations are classified at execution time, delegation cannot consume the
29
+ short-task allowance, and completion claims are rejected while actionable
30
+ tasks remain or task state cannot be verified.
31
+ - Repeated failing calls now use bounded SHA-256 identities with per-query
32
+ cleanup, TTL and capacity limits, so large or sensitive tool inputs are not
33
+ retained. Identical failures are refused and eventually abort the turn;
34
+ corrected inputs are allowed immediately.
35
+ - `ur crew` now runs independent workers in parallel, honors dependency
36
+ fan-in, claims work across processes, and supports bounded respawns with
37
+ backoff and cancellation. Automatic retries use isolated fresh worktrees;
38
+ ambiguous shared-workspace mutations are never replayed.
39
+ - Hardened the upstream proxy relay against unterminated or overflowing
40
+ protobuf varints, half-open rejected HTTP clients, and synchronous WebSocket
41
+ constructor failures.
42
+ - Terminal UI layouts now remain valid in very small windows. Search pickers,
43
+ fullscreen modals, dividers, highlighted code, the startup logo, and cursor
44
+ widths clamp or reflow instead of overflowing; empty picker focus,
45
+ Meta-key punctuation/input-buffer handling, prompt-footer sizing, live-model
46
+ status refreshes, and task progress presentation are corrected.
47
+ - Hardened IDE state storage against symlink redirection, oversized or corrupt
48
+ state, and interrupted writes. The VS Code chat now treats an abnormal
49
+ process exit as failure even after a result frame, bounds NDJSON/stderr
50
+ buffering, validates webview messages, and improves keyboard focus, live
51
+ status, alert, and attachment accessibility.
52
+ - The Node launcher now enforces the declared Bun minimum, including
53
+ prerelease ordering, rather than checking only whether a `bun` executable
54
+ exists.
55
+ - Release automation now runs the validated serial Bun test command (parallel
56
+ workers currently collide on ephemeral test servers), grants the permissions
57
+ needed to download verified artifacts, keeps
58
+ prereleases off npm's `latest` tag, marks GitHub prereleases correctly,
59
+ validates every version-bearing surface, supports safe prerelease bumps, and
60
+ cleans package-check temporary state. Validation docs and historical
61
+ changelog ordering were corrected.
62
+
63
+ ## 1.65.5
64
+
65
+ - Syntax highlighting works again — in assistant messages, code previews and
66
+ question dialogs. `cli-highlight` was imported by four rendering surfaces and
67
+ declared in `package.json` by none of them, so the import threw on every run
68
+ and every code block rendered as unstyled plain text. Three things had to
69
+ line up for this to stay invisible for as long as it did: the loader caught
70
+ the resolution failure and returned `null` with no message, the import is
71
+ dynamic so the bundler resolved it lazily rather than failing the build, and
72
+ an ambient `declare module 'cli-highlight' { const value: any }` shim
73
+ satisfied the typechecker on a package that was not installed. The dependency
74
+ is declared, the shim is gone (the package ships real types), and a failed
75
+ load now says so instead of silently degrading.
76
+ - Added `test/declaredDependencies.test.ts`: every external module imported by
77
+ `src` must be declared, aliased in `tsconfig` paths, or carry an ambient shim.
78
+ A full scan found no other genuine gap — `@urhq-ai/sdk` is a path alias, and
79
+ `plist`, `cacache` and `turndown` are deliberate optional degradations.
80
+ - The task-list gate no longer blocks simple one-file requests. Its allowance
81
+ for short work counted *messages* rather than tool calls, so any conversation
82
+ at all pushed the count past the threshold and the gate refused the very
83
+ first `Write` — exactly the case the allowance exists to let through.
84
+ - The status bar showed the persisted `provider.model` rather than the live
85
+ session model, so `/model` changed what ran without changing what was
86
+ displayed. The correct value was already in scope and used only as a
87
+ fallback. The render key had the same omission, so even the right source
88
+ could leave a stale value on screen after a switch.
3
89
  ## 1.65.4
4
90
 
5
91
  - A tool call that keeps failing identically is now stopped. A 4B model refused
@@ -1632,36 +1718,6 @@ Top-tier feature release — closes the gaps against 2026's leading agents.
1632
1718
  `FileEditTool.call`.
1633
1719
  - Verified source and production bundle release checks for the `1.22.6` build.
1634
1720
 
1635
- ## 1.22.3
1636
-
1637
- ### Added
1638
- - **Executable skill directories.** A `.ur/skills/<name>/` directory containing
1639
- `skill.yaml` is now an executable skill that compiles into a `WorkflowSpec`.
1640
- Supports `instructions.md`, `scripts/`, `templates/`, and `checklists/`.
1641
- `src/skills/skillSpec.ts` parses, validates, and compiles skills; step prompts
1642
- support `$ARGUMENTS`, `$0..$N`, and `$ARGUMENTS[N]` substitution.
1643
- - **`ur skill` CLI.** New command surface: `ur skill list`, `ur skill show <name>`,
1644
- `ur skill run <name> [args]`, and `ur skill init <name>`. Registered in
1645
- `src/commands.ts` and `src/main.tsx`.
1646
- - **Semantic repo index.** `src/utils/codeIndex/repoIndex.ts` builds offline,
1647
- dependency-free indexes under `.ur/code-index/`: `repo.json` (file
1648
- classification + imports/importedBy), `symbols.json`, `calls.json`,
1649
- `tests.json`, `docs.json`, and `configs.json`. `ur code-index repo` exposes
1650
- `build|status|search|symbols|callers|tests|docs|configs` subcommands.
1651
- - **`--repo` flag for code-index build/watch.** `ur code-index build --repo`
1652
- builds both the embedding index and the repo index; `watch --repo` refreshes
1653
- the repo index on file changes.
1654
-
1655
- ### Changed
1656
- - Reused the existing workflow engine for executable skills and extended the
1657
- existing `ur code-index` surface for the repo index, keeping changes additive.
1658
-
1659
- ### Verified
1660
- - Added `test/skillSpec.test.ts`, `test/skillCommand.test.ts`, and
1661
- `test/repoIndex.test.ts` covering skill parsing, compilation, CLI scaffolding,
1662
- repo file classification, symbol/call/test/doc/config extraction, and index
1663
- round-trips.
1664
-
1665
1721
  ## 1.22.5
1666
1722
 
1667
1723
  ### Added
@@ -1716,6 +1772,36 @@ Top-tier feature release — closes the gaps against 2026's leading agents.
1716
1772
  import updates, rollback on check failure, move, organize imports, unused
1717
1773
  detection, and caller mapping.
1718
1774
 
1775
+ ## 1.22.3
1776
+
1777
+ ### Added
1778
+ - **Executable skill directories.** A `.ur/skills/<name>/` directory containing
1779
+ `skill.yaml` is now an executable skill that compiles into a `WorkflowSpec`.
1780
+ Supports `instructions.md`, `scripts/`, `templates/`, and `checklists/`.
1781
+ `src/skills/skillSpec.ts` parses, validates, and compiles skills; step prompts
1782
+ support `$ARGUMENTS`, `$0..$N`, and `$ARGUMENTS[N]` substitution.
1783
+ - **`ur skill` CLI.** New command surface: `ur skill list`, `ur skill show <name>`,
1784
+ `ur skill run <name> [args]`, and `ur skill init <name>`. Registered in
1785
+ `src/commands.ts` and `src/main.tsx`.
1786
+ - **Semantic repo index.** `src/utils/codeIndex/repoIndex.ts` builds offline,
1787
+ dependency-free indexes under `.ur/code-index/`: `repo.json` (file
1788
+ classification + imports/importedBy), `symbols.json`, `calls.json`,
1789
+ `tests.json`, `docs.json`, and `configs.json`. `ur code-index repo` exposes
1790
+ `build|status|search|symbols|callers|tests|docs|configs` subcommands.
1791
+ - **`--repo` flag for code-index build/watch.** `ur code-index build --repo`
1792
+ builds both the embedding index and the repo index; `watch --repo` refreshes
1793
+ the repo index on file changes.
1794
+
1795
+ ### Changed
1796
+ - Reused the existing workflow engine for executable skills and extended the
1797
+ existing `ur code-index` surface for the repo index, keeping changes additive.
1798
+
1799
+ ### Verified
1800
+ - Added `test/skillSpec.test.ts`, `test/skillCommand.test.ts`, and
1801
+ `test/repoIndex.test.ts` covering skill parsing, compilation, CLI scaffolding,
1802
+ repo file classification, symbol/call/test/doc/config extraction, and index
1803
+ round-trips.
1804
+
1719
1805
  ## 1.22.2
1720
1806
 
1721
1807
  ### Added
package/README.md CHANGED
@@ -400,7 +400,7 @@ as first-class subcommands in the shipped CLI.
400
400
  | `ur task` | Start, run, and hand off worktree-per-task sessions with optional PR creation. |
401
401
  | `ur automation` | Store and run project-local scheduled automation specs under `.ur/automations/`. |
402
402
  | `ur workflow` | Define, validate, graph, run, and resume declarative agent workflows. |
403
- | `ur crew` | Run a lead and worker subagent crew over a shared task board; `--decompose` auto-splits tasks with risk/tests/rollback metadata. |
403
+ | `ur crew` | Run dependency-aware worker subagents over a shared task board; independent tasks fan out, while bounded retries require isolated worktrees. |
404
404
  | `ur pattern` | Run multi-agent collaboration patterns (PEER, DOE, concurrent, handoff, debate, parallel); `--execute` runs them as a workflow. |
405
405
  | `ur goal` | Track long-horizon objectives that persist across sessions. |
406
406
  | `ur repo-edit` | Build a repo edit index, plan AST-aware renames, preview patches, and apply with rollback. |
@@ -572,6 +572,7 @@ ur spec verify checkout --kernel
572
572
  ur crew create parser-crew --goal "fix the flaky parser test" --decompose --dry-run
573
573
  ur crew plan parser-crew --goal "fix the flaky parser test" --decompose
574
574
  ur crew run parser-crew --workers 3 --decompose --dry-run
575
+ ur crew run parser-crew --workers 3 --worktrees --max-attempts 2
575
576
  ur pattern parallel "refactor login without changing behavior" --execute --dry-run
576
577
  ur arena "implement a debounce helper" --agents 3 --judge hybrid --verify "bun test"
577
578
  ur agent-ci init default
package/RELEASE.md CHANGED
@@ -54,15 +54,26 @@ rg -n "Version [0-9]|expected: [0-9]|UR-Nexus v[0-9]" README.md docs documentati
54
54
  bun test test/docsCoverage.test.ts test/docsCommands.test.ts
55
55
  ```
56
56
 
57
+ Run the repository-owned bump script so dependency ranges cannot be changed by
58
+ an accidental text replacement:
59
+
60
+ ```bash
61
+ node scripts/version-bump.mjs <next-version>
62
+ ```
63
+
57
64
  Version bump checklist (all versioned release surfaces must move together):
58
65
 
59
66
  1. `package.json` `version`
60
67
  2. `bunfig.toml` `MACRO.VERSION`
61
- 3. `documentation/index.html` version eyebrow
68
+ 3. `documentation/index.html` version eyebrow and the expected version in
69
+ `docs/VALIDATION.md`
62
70
  4. `extensions/vscode-ur-inline-diffs/package.json` and its lockfile version
63
71
  fields (the VSIX test requires them to match the root package version)
64
72
  5. `extensions/jetbrains-ur/build.gradle.kts` `version`
65
- 6. Add a `CHANGELOG.md` entry, then run `bun run build` so `dist/cli.js`
73
+ 6. The `MACRO.VERSION` fallbacks in `src/commands/agent-ci/agent-ci.ts`,
74
+ `src/services/agents/agenticCi.ts`, and
75
+ `src/services/agents/featureScaffolds.ts`
76
+ 7. Add a `CHANGELOG.md` entry, then run `bun run build` so `dist/cli.js`
66
77
  embeds the new version (`bun run release:check` verifies all of this).
67
78
 
68
79
  If `npm whoami` fails, run:
package/bin/ur.js CHANGED
@@ -38,7 +38,10 @@ const bun = process.env.BUN_BIN || process.env.BUN_EXECUTABLE || 'bun'
38
38
  const ollamaModel =
39
39
  process.env.OLLAMA_MODEL || process.env.UR_MODEL
40
40
  const userArgs = process.argv.slice(2)
41
- const requiredBun = packageMetadata.engines?.bun ?? '>=1.3.0'
41
+ const requiredBun =
42
+ typeof packageMetadata.engines?.bun === 'string'
43
+ ? packageMetadata.engines.bun
44
+ : '>=1.3.0'
42
45
 
43
46
  function printBunRuntimeError(detail) {
44
47
  const attempted = bun
@@ -51,12 +54,62 @@ function printBunRuntimeError(detail) {
51
54
  console.error(
52
55
  [
53
56
  `UR-Nexus requires Bun ${requiredBun} at runtime because the published CLI bundle is built with --target bun.`,
54
- `Could not execute "${attempted}" from ${source}.${detail ? ` ${detail}` : ''}`,
57
+ `Bun executable: "${attempted}" (resolved from ${source}).`,
58
+ detail,
55
59
  'Install Bun from https://bun.sh, or set BUN_BIN to the absolute path of a Bun executable.',
56
- ].join('\n'),
60
+ ].filter(Boolean).join('\n'),
57
61
  )
58
62
  }
59
63
 
64
+ function parseSemver(value) {
65
+ const match = value.match(
66
+ /^v?(\d+)\.(\d+)\.(\d+)(?:-([0-9A-Za-z.-]+))?(?:\+[0-9A-Za-z.-]+)?$/,
67
+ )
68
+ if (!match) return null
69
+ return {
70
+ core: [Number(match[1]), Number(match[2]), Number(match[3])],
71
+ prerelease: match[4]?.split('.') ?? [],
72
+ }
73
+ }
74
+
75
+ function compareSemver(left, right) {
76
+ for (let index = 0; index < 3; index += 1) {
77
+ if (left.core[index] !== right.core[index]) {
78
+ return left.core[index] > right.core[index] ? 1 : -1
79
+ }
80
+ }
81
+
82
+ if (left.prerelease.length === 0 && right.prerelease.length === 0) return 0
83
+ if (left.prerelease.length === 0) return 1
84
+ if (right.prerelease.length === 0) return -1
85
+
86
+ const length = Math.max(left.prerelease.length, right.prerelease.length)
87
+ for (let index = 0; index < length; index += 1) {
88
+ const leftPart = left.prerelease[index]
89
+ const rightPart = right.prerelease[index]
90
+ if (leftPart === undefined) return -1
91
+ if (rightPart === undefined) return 1
92
+ if (leftPart === rightPart) continue
93
+
94
+ const leftNumeric = /^\d+$/.test(leftPart)
95
+ const rightNumeric = /^\d+$/.test(rightPart)
96
+ if (leftNumeric && rightNumeric) {
97
+ return Number(leftPart) > Number(rightPart) ? 1 : -1
98
+ }
99
+ if (leftNumeric !== rightNumeric) return leftNumeric ? -1 : 1
100
+ return leftPart > rightPart ? 1 : -1
101
+ }
102
+ return 0
103
+ }
104
+
105
+ function satisfiesBunEngine(version, range) {
106
+ const actual = parseSemver(version)
107
+ const minimumMatch = range.trim().match(/^>=\s*(.+)$/)
108
+ const minimum = minimumMatch ? parseSemver(minimumMatch[1]) : null
109
+ if (!actual || !minimum) return null
110
+ return compareSemver(actual, minimum) >= 0
111
+ }
112
+
60
113
  function assertBunAvailable() {
61
114
  const result = spawnSync(bun, ['--version'], {
62
115
  encoding: 'utf8',
@@ -64,14 +117,33 @@ function assertBunAvailable() {
64
117
  })
65
118
 
66
119
  if (result.error) {
67
- printBunRuntimeError(result.error.message)
120
+ printBunRuntimeError(`Could not execute Bun: ${result.error.message}`)
68
121
  process.exit(1)
69
122
  }
70
123
  if (result.status !== 0) {
71
124
  const detail = (result.stderr || result.stdout || '').trim()
72
- printBunRuntimeError(detail || `Exited with status ${result.status}.`)
125
+ printBunRuntimeError(
126
+ detail
127
+ ? `Bun --version failed: ${detail}`
128
+ : `Bun --version exited with status ${result.status}.`,
129
+ )
73
130
  process.exit(result.status ?? 1)
74
131
  }
132
+
133
+ const installedBun = result.stdout.trim()
134
+ const satisfies = satisfiesBunEngine(installedBun, requiredBun)
135
+ if (satisfies === null) {
136
+ printBunRuntimeError(
137
+ `Could not validate Bun version "${installedBun}" against engines.bun "${requiredBun}".`,
138
+ )
139
+ process.exit(1)
140
+ }
141
+ if (!satisfies) {
142
+ printBunRuntimeError(
143
+ `Found Bun ${installedBun}, which does not satisfy engines.bun "${requiredBun}".`,
144
+ )
145
+ process.exit(1)
146
+ }
75
147
  }
76
148
 
77
149
  const args =