@ai-matrx/rich-content 0.2.171 → 0.2.172

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,6 +1,6 @@
1
1
  # Changelog
2
2
 
3
- ## 0.2.171
3
+ ## 0.2.172
4
4
 
5
5
  UNVERIFIED: this release has no Unreleased entry and the source comparison could not be made (the caller supplied no source comparison). Whether source changed is unknown; consumer action is unknown.
6
6
  Check the package's gitHead on npm against this version's gitHead: `git diff <previous gitHead> <this gitHead> -- apps/shared/rich-content/src`.
@@ -1,3 +1,4 @@
1
+ import { parseUnifiedDiff } from "./parse-unified-diff.js";
1
2
  const searchReplaceHandler = {
2
3
  name: "search-replace",
3
4
  canShowPartial: false,
@@ -55,13 +56,11 @@ const unifiedDiffHandler = {
55
56
  }
56
57
  };
57
58
  },
58
- parse: (content) => {
59
- return { lines: content.split("\n") };
60
- }
59
+ parse: (content) => parseUnifiedDiff(content)
61
60
  };
62
61
  const DIFF_STYLE_HANDLERS = [
63
62
  searchReplaceHandler
64
- // unifiedDiffHandler, // Add when ready
63
+ // unifiedDiffHandler, // parse() is real; register once a unified renderer exists
65
64
  // Add more handlers here as needed
66
65
  ];
67
66
  function detectDiffStyle(content) {
@@ -0,0 +1,6 @@
1
+ /**
2
+ * Unified diff parser, safe on a stream: a partial last hunk parses as far as it goes and reports
3
+ * `isComplete: false` until the line counts in its `@@ -a,b +c,d @@` header are met.
4
+ */
5
+ import type { UnifiedDiffBlock } from './types.js';
6
+ export declare function parseUnifiedDiff(content: string): UnifiedDiffBlock;
@@ -0,0 +1,77 @@
1
+ const HUNK_HEADER = /^@@ -(\d+)(?:,(\d+))? \+(\d+)(?:,(\d+))? @@ ?(.*)$/;
2
+ function parseUnifiedDiff(content) {
3
+ const lines = content.split("\n");
4
+ if (lines.length > 1 && lines[lines.length - 1] === "") lines.pop();
5
+ const parsed = [];
6
+ const hunks = [];
7
+ let added = 0;
8
+ let removed = 0;
9
+ let oldLine = 0;
10
+ let newLine = 0;
11
+ let oldLeft = 0;
12
+ let newLeft = 0;
13
+ let open = null;
14
+ const closeHunk = () => {
15
+ if (open) open.to = parsed.length - 1;
16
+ open = null;
17
+ };
18
+ for (const raw of lines) {
19
+ const header = HUNK_HEADER.exec(raw);
20
+ if (header) {
21
+ closeHunk();
22
+ const oldCount = header[2] === void 0 ? 1 : Number(header[2]);
23
+ const newCount = header[4] === void 0 ? 1 : Number(header[4]);
24
+ open = {
25
+ oldStart: Number(header[1]),
26
+ oldCount,
27
+ newStart: Number(header[3]),
28
+ newCount,
29
+ section: header[5] ?? "",
30
+ from: parsed.length,
31
+ to: parsed.length
32
+ };
33
+ hunks.push(open);
34
+ oldLine = open.oldStart;
35
+ newLine = open.newStart;
36
+ oldLeft = oldCount;
37
+ newLeft = newCount;
38
+ parsed.push({ kind: "hunk", text: raw, oldLine: null, newLine: null });
39
+ continue;
40
+ }
41
+ const insideBody = open !== null && (oldLeft > 0 || newLeft > 0);
42
+ if (insideBody) {
43
+ const marker = raw[0];
44
+ if (marker === "+") {
45
+ parsed.push({ kind: "add", text: raw.slice(1), oldLine: null, newLine: newLine++ });
46
+ newLeft--;
47
+ added++;
48
+ continue;
49
+ }
50
+ if (marker === "-") {
51
+ parsed.push({ kind: "remove", text: raw.slice(1), oldLine: oldLine++, newLine: null });
52
+ oldLeft--;
53
+ removed++;
54
+ continue;
55
+ }
56
+ if (marker === "\\") {
57
+ parsed.push({ kind: "no-newline", text: raw, oldLine: null, newLine: null });
58
+ continue;
59
+ }
60
+ parsed.push({ kind: "context", text: marker === " " ? raw.slice(1) : raw, oldLine: oldLine++, newLine: newLine++ });
61
+ oldLeft--;
62
+ newLeft--;
63
+ continue;
64
+ }
65
+ if (open) closeHunk();
66
+ if (raw.startsWith("--- ")) parsed.push({ kind: "file-old", text: raw.slice(4), oldLine: null, newLine: null });
67
+ else if (raw.startsWith("+++ ")) parsed.push({ kind: "file-new", text: raw.slice(4), oldLine: null, newLine: null });
68
+ else if (raw.startsWith("\\")) parsed.push({ kind: "no-newline", text: raw, oldLine: null, newLine: null });
69
+ else parsed.push({ kind: "meta", text: raw, oldLine: null, newLine: null });
70
+ }
71
+ closeHunk();
72
+ const isComplete = hunks.length > 0 && oldLeft <= 0 && newLeft <= 0;
73
+ return { lines, parsed, hunks, added, removed, isComplete };
74
+ }
75
+ export {
76
+ parseUnifiedDiff
77
+ };
@@ -24,8 +24,37 @@ export interface SearchReplaceBlock {
24
24
  /**
25
25
  * Parsed unified diff (line-based) block
26
26
  */
27
+ export type UnifiedDiffLineKind = 'meta' | 'file-old' | 'file-new' | 'hunk' | 'add' | 'remove' | 'context' | 'no-newline';
28
+ export interface UnifiedDiffLine {
29
+ kind: UnifiedDiffLineKind;
30
+ /** The line without its leading +/-/space marker (full text for meta, file and hunk lines). */
31
+ text: string;
32
+ /** 1-based line number in the old file; null for added and structural lines. */
33
+ oldLine: number | null;
34
+ /** 1-based line number in the new file; null for removed and structural lines. */
35
+ newLine: number | null;
36
+ }
37
+ export interface UnifiedDiffHunk {
38
+ oldStart: number;
39
+ oldCount: number;
40
+ newStart: number;
41
+ newCount: number;
42
+ /** Text after the second `@@` (usually the enclosing function). */
43
+ section: string;
44
+ /** Index range into `UnifiedDiffBlock.parsed` covered by this hunk (header included). */
45
+ from: number;
46
+ to: number;
47
+ }
27
48
  export interface UnifiedDiffBlock {
49
+ /** The raw lines, unchanged. */
28
50
  lines: string[];
51
+ /** Every line classified, with old/new line numbers tracked through the hunks. */
52
+ parsed: UnifiedDiffLine[];
53
+ hunks: UnifiedDiffHunk[];
54
+ added: number;
55
+ removed: number;
56
+ /** True when the last hunk has received every line its header promised. */
57
+ isComplete: boolean;
29
58
  }
30
59
  /**
31
60
  * Union of every shape a diff style handler's parse() can return.
@@ -1,4 +1,4 @@
1
- import { classifyMediaUrl, isDurableMediaUrl, shareableMediaUrl, type MediaUrlKind } from "@ai-matrx/data/files";
1
+ import { classifyMediaUrl, isDurableMediaUrl, shareableMediaUrl, type MediaUrlKind } from "@ai-matrx/files/client";
2
2
  export { classifyMediaUrl, isDurableMediaUrl, shareableMediaUrl };
3
3
  export type { MediaUrlKind };
4
4
  /**
@@ -3,7 +3,7 @@ import {
3
3
  createFileUrlRecognizer,
4
4
  isDurableMediaUrl,
5
5
  shareableMediaUrl
6
- } from "@ai-matrx/data/files";
6
+ } from "@ai-matrx/files/client";
7
7
  import { captureError } from "../../host/diagnostics.js";
8
8
  const recognizer = createFileUrlRecognizer();
9
9
  function fileIdFromUserFilesUrl(url) {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@ai-matrx/rich-content",
3
- "version": "0.2.171",
3
+ "version": "0.2.172",
4
4
  "description": "The AI Matrx formatted-text engine: the one markdown renderer, streaming markdown, the block splitter and renderer, the generic blocks, <RichContent> levels, the rich-document action registry and menus, copy, and the selection toolbar — as portable React.",
5
5
  "type": "module",
6
6
  "license": "MIT",
@@ -130,21 +130,22 @@
130
130
  "unist-util-visit": "^5.1.0",
131
131
  "unist-util-visit-parents": "^6.0.2",
132
132
  "yaml": "^2.9.1",
133
+ "@ai-matrx/agents": "latest",
133
134
  "@ai-matrx/alchemy": "latest",
134
135
  "@ai-matrx/api": "latest",
135
136
  "@ai-matrx/canvas": "latest",
136
- "@ai-matrx/content-ir-react": "latest",
137
- "@ai-matrx/agents": "latest",
138
137
  "@ai-matrx/content-ir": "latest",
139
- "@ai-matrx/data": "latest",
138
+ "@ai-matrx/content-ir-react": "latest",
140
139
  "@ai-matrx/design-system": "latest",
141
140
  "@ai-matrx/diff": "latest",
141
+ "@ai-matrx/data": "latest",
142
142
  "@ai-matrx/icons": "latest",
143
- "@ai-matrx/media": "latest",
143
+ "@ai-matrx/files": "latest",
144
+ "@ai-matrx/kit": "latest",
144
145
  "@ai-matrx/print": "latest",
145
- "@ai-matrx/records": "latest",
146
146
  "@ai-matrx/records-ui": "latest",
147
- "@ai-matrx/kit": "latest"
147
+ "@ai-matrx/media": "latest",
148
+ "@ai-matrx/records": "latest"
148
149
  },
149
150
  "peerDependencies": {
150
151
  "react": ">=19.0.0",
@@ -205,5 +206,5 @@
205
206
  "verify:modules-tarball": "node ./scripts/verify-modules-tarball.mjs",
206
207
  "verify:tarball": "node ./scripts/verify-tarball.mjs"
207
208
  },
208
- "gitHead": "4c4a847d5532256ccea7048e09783b8587ae079e"
209
+ "gitHead": "de1c78033bf8d06b35b03b2443e3c99cb9ed6f19"
209
210
  }