<p>Three changes. All in the core. No install required.</p><h2>1. The edit tool tells you when it breaks something</h2><p>Here's what used to happen: the agent edits a TypeScript file, the edit succeeds, the agent moves on to the next file. Three files later, it runs the type checker and discovers that the first edit introduced an error. It goes back, reads the file again, fixes the error, checks again. Four round trips. Thousands of tokens. Minutes of wall time.</p><p>Now, the edit tool runs <code>tsc --noEmit</code> after every successful TypeScript edit and appends any new errors directly to the result:</p><pre><code>Successfully replaced 2 block(s) in src/auth/service.ts.

Diagnostics (1 error):
src/auth/service.ts(42,10): error TS2345: Argument of type 'string'
  is not assignable to parameter of type 'number'.
</code></pre><p>The agent sees the error immediately, in the same turn, before it moves on. It fixes the issue right there. One round trip instead of four.</p><p>This is the kind of change that doesn't look impressive in a changelog but saves ten minutes on every non-trivial coding session. The agent gets feedback at the speed of the compiler, not at the speed of "oh I should probably check if that worked."</p><p>The diagnostic check is wrapped in a try/catch. If <code>tsc</code> isn't available, or if you're editing a Python file, or if the check times out — nothing happens. The edit still succeeds. It's strictly additive.</p><h2>2. Reading a file no longer dumps 500 lines into the context</h2><p>When the agent needs to understand a file, it calls the read tool. Before this release, reading a 400-line file meant 400 lines of content dropped into the context window. The agent would scan through it, find the three functions it cared about, and carry the other 397 lines as dead weight for the rest of the session.</p><p>Now, files over 150 lines get a structural outline instead:</p><pre><code>File: src/auth/service.ts (423 lines)

Outline:
L1    import { User } from "./types.js"
L2    import { hash } from "node:crypto"
      ... 4 more imports
L8    export interface AuthConfig {
L15   export class AuthService {
L18     constructor(config: AuthConfig)
L26     async login(email: string, password: string): Promise&lt;Session&gt;
L48     async logout(sessionId: string): Promise&lt;void&gt;
L61     private validateToken(token: string): boolean
L81     async refreshToken(session: Session): Promise&lt;string&gt;
L98   }
L100  export function createAuthService(config: AuthConfig): AuthService

Use read with offset and limit to see specific sections.
</code></pre><p>The agent sees the structure — every function, class, interface, and export with its line number. It can then read just the 20 lines it needs with <code>read(path, offset: 26, limit: 22)</code> to look at the <code>login</code> method.</p><p>This works for TypeScript, JavaScript, and Python. For other languages, it shows a line count and suggests using offset/limit.</p><p>The outline isn't forced on you. If you (or the agent) pass <code>offset</code> or <code>limit</code>, the read tool returns the actual content as before. The outline only kicks in when reading a large file without specifying a range — which is exactly the case where the old behavior was wasteful.</p><h2>3. Every line gets a fingerprint</h2><p>This one is subtle but compounds over time.</p><p>When the read tool returns content, each line now has a short hash prefix:</p><pre><code>#a3f2 | import { foo } from "./bar.js";
#b7c1 | import { baz } from "./qux.js";
#0e4d |
#f1a8 | export function hello(): void {
#c2b3 |   console.log("hello");
#9d0e | }
</code></pre><p>The hash is a 4-character fingerprint of the line content. When the agent needs to edit this file, it can reference lines by their hash. More importantly, when the agent copies text from a read result into an edit's <code>oldText</code>, the hash annotations are stripped transparently. The agent doesn't need to know they're there.</p><p>Why this matters: the edit tool matches <code>oldText</code> by searching for the exact string in the file. When a file has duplicate lines (closing braces, blank lines, repeated patterns), the match can be ambiguous. The hash gives each line a unique identity. An agent that's learned to include the hash context in its edits will hit the right target every time.</p><p>This is the same principle behind the "hashline" system, which reports a 61% reduction in output tokens for some models. Our implementation is lighter — a 4-character prefix on each line rather than a full content-hash edit format — but the token savings come from the same place: the model can point at code instead of retyping it.</p><h2>What these three changes have in common</h2><p>None of them are new features. You won't find a new slash command, a new extension, or a new settings page. They're improvements to the tools you use on every single prompt: read and edit.</p><p>The agent reads fewer tokens (outlines instead of full files). The agent writes more precisely (hash-anchored lines). The agent catches its mistakes immediately (post-edit diagnostics). Each change is small. Together, they make the entire session tighter.</p><p>That's the work that matters. Not more tools. Better tools.</p><h2>Get it</h2><pre><code class="language-bash">elyra update
</code></pre><p>No configuration needed. The improvements apply automatically to every session.</p><hr><p><em>Elyra v0.7.10 — </em><a target="_blank" rel="noopener noreferrer nofollow" href="https://elyracode.com/changelog"><em>changelog</em></a></p>