Skip to content

Remove diff from cli-kit/app#7727

Draft
amcaplan wants to merge 1 commit into
mainfrom
remove-dep/diff
Draft

Remove diff from cli-kit/app#7727
amcaplan wants to merge 1 commit into
mainfrom
remove-dep/diff

Conversation

@amcaplan
Copy link
Copy Markdown
Contributor

@amcaplan amcaplan commented Jun 5, 2026

Remove diff from @shopify/app / @shopify/cli-kit

Why: diff (jsdiff) is a high-churn dependency (58 Dependabot bumps / 24 months). Part of an initiative to cut low-value dependency churn.

Replacement: Inlined a faithful line-diff implementation at packages/app/src/cli/services/app/env/lines-diff.ts.

  • ⚠️ Implementation note: This is a faithful port of jsdiff's actual Myers O(ND) line-diff algorithm, NOT a generic LCS backtrace. We verified that a naive LCS does not reproduce jsdiff's output byte-for-byte (~12% divergence on fuzzed inputs), so the upstream algorithm was ported directly. (The commit message/changeset say "LCS-based" for continuity — the behavior is Myers.)
  • Parity proof: A 1,000,000-case fuzz against the original diff package produced 0 divergences. That battery is frozen into 13 static parity cases in lines-diff.test.ts.
  • cli-kit's content-tokens.ts / output.ts now use a local exported LinesDiffSegment type, preserving the outputToken.linesDiff contract.

Validation: type-check ✅, lint ✅, vitest ✅ (33/33 tests).

🤖 AI-generated draft — needs human review before merge.

Co-Authored-By: Claude <noreply@anthropic.com>

🤖 Generated with [Claude Code](https://claude.ai/code)

Co-Authored-By: Claude <noreply@anthropic.com>
@github-actions github-actions Bot added the Area: @shopify/cli @shopify/cli package issues label Jun 5, 2026
@github-actions
Copy link
Copy Markdown
Contributor

github-actions Bot commented Jun 5, 2026

Differences in type declarations

We detected differences in the type declarations generated by Typescript for this branch compared to the baseline ('main' branch). Please, review them to ensure they are backward-compatible. Here are some important things to keep in mind:

  • Some seemingly private modules might be re-exported through public modules.
  • If the branch is behind main you might see odd diffs, rebase main into this branch.

New type declarations

We found no new type declarations in this PR

Existing type declarations

packages/cli-kit/dist/private/node/content-tokens.d.ts
@@ -1,5 +1,14 @@
 import { OutputMessage } from '../../public/node/output.js';
-import type { Change } from 'diff';
+/**
+ * A single segment of a line-based diff, as consumed by {@link LinesDiffContentToken}.
+ * Structurally a subset of jsdiff's  type: unchanged segments have neither
+ *  nor  set; changed segments set exactly one of them to .
+ */
+export interface LinesDiffSegment {
+    value: string;
+    added?: boolean;
+    removed?: boolean;
+}
 export declare abstract class ContentToken<T> {
     value: T;
     constructor(value: T);
@@ -20,7 +29,7 @@ export declare class CommandContentToken extends ContentToken<OutputMessage> {
 export declare class JsonContentToken extends ContentToken<any> {
     output(): string;
 }
-export declare class LinesDiffContentToken extends ContentToken<Change[]> {
+export declare class LinesDiffContentToken extends ContentToken<LinesDiffSegment[]> {
     output(): string[];
 }
 export declare class ColorContentToken extends ContentToken<OutputMessage> {
packages/cli-kit/dist/public/node/output.d.ts
@@ -1,9 +1,9 @@
 import { PackageManager } from './node-package-manager.js';
 import { AbortSignal } from './abort.js';
 import { TokenItem } from './ui.js';
-import { ColorContentToken, CommandContentToken, ContentToken, ErrorContentToken, HeadingContentToken, ItalicContentToken, JsonContentToken, LinesDiffContentToken, LinkContentToken, PathContentToken, RawContentToken, SubHeadingContentToken } from '../../private/node/content-tokens.js';
+import { ColorContentToken, CommandContentToken, ContentToken, ErrorContentToken, HeadingContentToken, ItalicContentToken, JsonContentToken, LinesDiffContentToken, LinesDiffSegment, LinkContentToken, PathContentToken, RawContentToken, SubHeadingContentToken } from '../../private/node/content-tokens.js';
 import { Writable } from 'stream';
-import type { Change } from 'diff';
+export type { LinesDiffSegment };
 export type Logger = Writable | ((message: string, logLevel?: LogLevel) => void);
 export declare class TokenizedString {
     value: string;
@@ -28,7 +28,7 @@ export declare const outputToken: {
     packagejsonScript(packageManager: PackageManager, scriptName: string, ...scriptArgs: string[]): CommandContentToken;
     successIcon(): ColorContentToken;
     failIcon(): ErrorContentToken;
-    linesDiff(value: Change[]): LinesDiffContentToken;
+    linesDiff(value: LinesDiffSegment[]): LinesDiffContentToken;
 };
 /**
  * Given a command and its arguments, it formats it depending on the package manager.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

Area: @shopify/cli @shopify/cli package issues

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant