feat(desktop): open workspace Markdown references - #3819

Open
1625567290 wants to merge 1 commit into
apache:mainfrom
1625567290:feat/desktop-open-workspace-markdown
Open

feat(desktop): open workspace Markdown references#3819
1625567290 wants to merge 1 commit into
apache:mainfrom
1625567290:feat/desktop-open-workspace-markdown

Conversation

@1625567290

Copy link
Copy Markdown
Contributor

Summary

  • Make workspace-relative Markdown references clickable in assistant output and sent workspace-file chips, including encoded spaces and non-ASCII paths.
  • Preview .md, .markdown, and .mdx files in the existing Files workbar while keeping the transcript mounted, with Open locally and Show in folder actions.
  • Resolve paths in the main process against the session workspace realpath, reject traversal, schemes, symlink escapes, and non-Markdown files, and cap previews at 256 KiB.

Fixes#2664

Verification

  • npm run typecheck
  • npm run format:check
  • npx biome lint --changed --since=origin/main
  • npm run check:asf-headers
  • npm --workspace @maka/ui test (236 passed)
  • node --test apps/desktop/dist/main/tests/runtime-host-workspace-ipc-main.test.js apps/desktop/dist/main/tests/workspace-file-guard.test.js (3 passed)
  • npm --workspace @maka/desktop run e2e -- e2e/workspace-markdown.spec.ts (1 passed)

The full local Desktop run reached 1504 passing tests. Eight existing MCP OAuth deadline tests were cancelled under local Node 22.22.1; the affected workspace tests and exact-head Electron E2E pass, and the OAuth source and test files are unchanged from main.

Checklist

  • Tests cover the change and fail without it
  • Lint, format, typecheck and the affected suites pass locally

Does this PR entail a change in behavior?

  • Yes — described under Summary above
  • No

@1625567290
1625567290force-pushed the feat/desktop-open-workspace-markdown branch 4 times, most recently from 6f258a7 to 7c25d6fCompareAugust 26, 2026 03:45
@1625567290

Copy link
Copy Markdown
ContributorAuthor

Rebased onto current main 51eeaa6 and Astryx core 0.5.0; the exact head is 7c25d6f.

All hosted checks are terminal and successful:

Exact-head local validation passed UI tests 236/236, Desktop typecheck, workspace IPC and guard boundaries 9/9, packaged-app verification 18/18, the workspace Markdown Electron E2E, ASF headers, Astryx surface inventory, and changed-file lint/format checks. There are no unresolved review threads. Ready for human review.

@M4n5ter
M4n5terforce-pushed the feat/desktop-open-workspace-markdown branch from 7c25d6f to 39e0bc1CompareAugust 26, 2026 08:58
@1625567290

Copy link
Copy Markdown
ContributorAuthor

Exact head 39e0bc155 is based on main@654764fb4. The rebase preserved the feature patch exactly: range-diff reports 7c25d6fc0 = 39e0bc155.

All hosted checks for this exact head are terminal and successful:

The hosted CI executed the full build, affected workspace tests, Desktop E2E, alignment audit, Storybook smoke, and installed CLI release-candidate validation. The final diff contains no documentation/Markdown or Java test sources, and there are no unresolved review threads.

After these runs completed, main advanced to 4b6aadf3f. Git reports no textual conflict and GitHub currently reports the PR mergeable. Ready for human review.

@M4n5ter
M4n5terforce-pushed the feat/desktop-open-workspace-markdown branch from 39e0bc1 to cb7847aCompareAugust 26, 2026 09:56
@1625567290

Copy link
Copy Markdown
ContributorAuthor

Current exact head cb7847abea has one hosted failure in the unchanged e2e/prompt-rail.spec.ts:286 case: after scrolling to the bottom, turn-prompt-rail-120 was not mounted within 10 s. The PR diff does not touch prompt-rail.spec.ts.

The same assertion failed at the same line and with the same 0-vs-1 result in two independent concurrent runs:

This PR run otherwise passed 66 Desktop E2E cases with 1 conditional skip, and its dependency audit, Windows package, and Windows recovery checks are green. Contributor retry was attempted and GitHub returned Must have admin rights to Repository. Please rerun the failed job for https://github.com/apache/maka/actions/runs/32955673166.

@1625567290
1625567290force-pushed the feat/desktop-open-workspace-markdown branch from cb7847a to d69957cCompareAugust 26, 2026 11:23
@1625567290

Copy link
Copy Markdown
ContributorAuthor

Exact head d69957c50 is based on main@3b89474c47. The rebase preserved the feature patch exactly: range-diff reports cb7847abe = d69957c50.

All hosted workflows for this head are terminal and successful:

The new CI run passed the complete Desktop E2E collection, including the unchanged prompt-rail case that failed concurrently on multiple branches in the previous batch, plus alignment audit, Storybook smoke, and installed CLI release-candidate validation. The exact PR diff contains no documentation/Markdown or Java test sources, and there are no unresolved review threads.

Target main advanced once more to 4dddb0f25e after this head was created; GitHub reports the PR mergeable with no textual conflict. Ready for human review.

@1625567290
1625567290force-pushed the feat/desktop-open-workspace-markdown branch from d69957c to b852fb8CompareAugust 26, 2026 16:24
@1625567290

Copy link
Copy Markdown
ContributorAuthor

Rebased onto current main@a6866d059 and force-updated the PR to exact head b852fb87b.

The feature commit is patch-equivalent to the previous reviewed head according to range-diff; no manual content resolution was required. Exact-head local validation with Node 24.19.0 passed the full Desktop build and typecheck, UI suite 229/229, Desktop suite 1561/1561, and the workspace Markdown Electron E2E 1/1.

The 26-file diff contains no documentation/Markdown or Java test sources. GitHub reports the PR mergeable with no unresolved review threads.

@1625567290

Copy link
Copy Markdown
ContributorAuthor

Follow-up on exact head b852fb87b: GitHub has not created any check suite after the recorded synchronize event. I verified the PR is open and mergeable and the repository workflows are active. A close/reopen recovery on #3819 also created no run, while direct workflow dispatch from this fork contributor is rejected with HTTP 403 (admin rights required). Maintainer action is needed to approve or trigger the GitHub-hosted workflows for this exact head; the exact-head local validation reported above remains green.

@github-actionsgithub-actionsBot added the effort/XL Over 1000 readable lines label Aug 27, 2026

@Astro-HanAstro-Han left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks for extending workspace Markdown references through the existing Workbar and Markdown seams. I reviewed exact head b852fb87ba8959c73f4ca6317952767dba365be4.

The capability is useful, but the file-authorization boundary and raw-Markdown preprocessing need revision before it is safe to merge. I found one P1 and three P2 issues inline:

  • a checked path string is reused after the filesystem authorization check, leaving a symlink-replacement window for out-of-workspace reads;
  • the Markdown extension allowlist is checked before canonicalization and can be bypassed by an in-workspace .md alias;
  • the line-oriented preprocessor rewrites valid Markdown code/external/path forms incorrectly;
  • the barrel re-export restores a measured eager-renderer chunk regression that current main deliberately removed.

The latest exact-head test, package, windows_recovery, and audit runs have successful results. The PR is currently conflicting with main; please preserve the current lazy Workbar boundary when rebasing and rerun checks on the resolved head.

Because this also changes a user-facing preview surface, human UI/UX acceptance remains required before approval.

Review analysis was assisted by Codex and independent @reviewer agents. Astro-Han verified the exact-head diff, path trust boundary, Markdown production behavior, current-main chunk composition, reachability, and severity before publication and owns this review.

中文对照

谢谢你沿用现有 Workbar 和 Markdown seam 增加 workspace Markdown references。我复核了精确 head b852fb87ba8959c73f4ca6317952767dba365be4

当前有一个 P1 和三个 P2:文件授权后复用 path string 留下 symlink 替换窗口;扩展名只在 canonicalize 前检查,可由 workspace 内 .md alias 绕过;逐行 raw Markdown 预处理会错误改写多种合法 Markdown;barrel re-export 重新引入 current main 已明确删除、且有量化证据的 eager chunk 回归。

当前最新几项检查有成功结果,但 PR 与 main 冲突;重基时必须保留当前 lazy Workbar 边界,并在解决后的 exact head 重新跑 CI。该 PR 也改变了用户可见 preview surface,因此 Approve 前仍需人工 UI/UX 验收。

本次审查分析由 Codex 和独立的 @reviewer 子代理协助;Astro-Han 核验了精确 head、path trust boundary、Markdown 生产行为、current-main chunk composition、可达性和问题分级,并对本次 Review 负责。

Comment threadapps/desktop/src/main/runtime-host-workspace-ipc-main.ts Outdated
Comment threadapps/desktop/src/main/workspace-file-guard.ts Outdated
Comment threadpackages/ui/src/workspace-file-href.ts
Comment threadapps/desktop/src/renderer/features/workbar/index.ts Outdated
@1625567290
1625567290force-pushed the feat/desktop-open-workspace-markdown branch 4 times, most recently from f997445 to 2e11bfcCompareAugust 30, 2026 16:14
@1625567290
1625567290force-pushed the feat/desktop-open-workspace-markdown branch from 2e11bfc to 16e8e2aCompareAugust 30, 2026 16:18
@1625567290

Copy link
Copy Markdown
ContributorAuthor

Exact-head follow-up for 16e8e2adf:

All four review findings remain resolved, with zero unresolved review threads. The 33-file PR diff contains no documentation/Markdown files or Java test sources. main has since advanced to 5d519d6f9; GitHub reports this exact head mergeable, and a local merge-tree check finds no textual conflict. Ready for maintainer review and the requested human UI/UX acceptance.

@Astro-HanAstro-Han left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks for the substantial follow-up—the opened-handle preview read, canonical extension check, and restored Workbar lazy boundary close the previous findings well. I found three remaining production seams below. These are suggestions from an outside review, so please do push back where the Markdown or local-workspace threat model is intentionally narrower.

AI-assisted review disclosure: Codex ran independent workspace-security, Markdown, and production/test analysis lanes; Astro-Han is the contributor of record for this review.

input.ipcMain.handle('workspace:openFile', async (_event, sessionId: unknown, relativePath: unknown) => {
const resolved = await resolveSessionWorkspaceFile(input, sessionId, relativePath);
if (!resolved.ok) return resolved;
const error = await input.openPath?.(resolved.path);

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

[P2] (category ②/③ — local replacement/trust-boundary path)

Thanks for binding preview reads to an opened inode. The “Open locally” path still authorizes a pathname and later hands that mutable pathname to the OS opener: after resolveSessionWorkspaceFile() verifies realpath/containment/extension/stat, another local process can replace guide.md with an outside-workspace symlink before openPath() resolves it. That leaves the PR’s Open locally boundary weaker than the fixed preview read. Could this action consume an identity-bound artifact (for example a controlled staged copy from the authorized handle), or be withheld until the platform exposes a non-re-resolving primitive, with a deterministic replacement-race regression? Please push back if local workspace replacement is explicitly outside this action’s supported threat model.

return source
.split('\n')
.map((line) => {
const blockLine = markdownBlockContent(line.endsWith('\r') ? line.slice(0, -1) : line);

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

[P2] (category ① — normal Markdown content)

Thanks for adding the code/link exclusions. The remaining line-oriented preprocessor still changes valid Markdown structures that span lines or containers: a line - ``` inside an already-open top-level fence is treated as that fence’s close, multiline backtick code and multiline link destinations lose their state between lines, and math is linkified before prepareMarkdownMath() (for example \\( \\texttt{docs/guide.md} \\)). In each case literal content is rewritten into [...](...). Rather than adding more line cases, could workspace linking run on parsed text nodes (or share a real block/inline state machine), with regressions for nested-container fences, multiline code/link, and inline/display math? Please feel free to push back if Astryx intentionally excludes any of these CommonMark/math forms.

if (href.length === 0 || href.length > HREF_MAX_LENGTH) return null;
let decoded: string;
try {
decoded = decodeURIComponent(href);

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

[P2] (category ① — normal percent-named workspace paths)

Thanks for keeping URI parsing fail-closed. The renderer already decodes an explicit href in parseWorkspaceFileHref() and sends the decoded filesystem path in WorkspaceFileDest.relativePath, but main calls decodeURIComponent() again. A valid docs/100%25-safe.md href becomes literal docs/100%-safe.md in the renderer and then fails the second decode; docs/100%2525-safe.md can instead open the wrong percent-named file. Structured workspace_file chips also start from a literal path and hit the same decoder. Could the wire contract choose one owner for URI decoding—decode explicit Markdown hrefs once, then have IPC/main validate the literal relative filesystem path—and cover %, %25, and percent-like directory names end to end? Please push back if the IPC contract is intended to carry encoded hrefs rather than paths.

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

Labels

effort/XLOver 1000 readable lines

Projects

None yet

Development

Successfully merging this pull request may close these issues.

feat(desktop): make Markdown file references in sessions openable

2 participants

@1625567290@Astro-Han
, 'i'); if (__m === '*' || __re.test(location.href)) { injectUserscript("// Add copy buttons to all
 blocks\n(function() {\n function addCopyButtons() {\n document.querySelectorAll('pre code').forEach(function(codeBlock) {\n if (codeBlock.parentElement.hasAttribute('data-copy-added')) return;\n codeBlock.parentElement.setAttribute('data-copy-added', 'true');\n \n var btn = document.createElement('button');\n btn.textContent = 'Copy';\n btn.style.cssText = 'position:absolute;top:4px;right:4px;padding:2px 8px;font-size:11px;background:#4ecdc4;border:none;border-radius:4px;color:#1a1a2e;cursor:pointer;opacity:0.7;transition:opacity 0.2s;';\n btn.onmouseover = function() { this.style.opacity = '1'; };\n btn.onmouseout = function() { this.style.opacity = '0.7'; };\n btn.onclick = function() {\n navigator.clipboard.writeText(codeBlock.textContent).then(function() {\n btn.textContent = 'Copied!';\n setTimeout(function() { btn.textContent = 'Copy'; }, 1500);\n });\n };\n codeBlock.parentElement.style.position = 'relative';\n codeBlock.parentElement.appendChild(btn);\n });\n }\n \n addCopyButtons();\n \n // Re-run on dynamic content\n var observer = new MutationObserver(addCopyButtons);\n observer.observe(document.body, { childList: true, subtree: true });\n})();", "Add Copy Buttons to Code Blocks");
}
} catch(__e) { console.warn('[Userscript:Add Copy Buttons to Code Blocks]', __e); }
})();
(function(){
try {
var __m = "github.com";
var __re = new RegExp('^' + "github\\.com" + '
Skip to content

feat(desktop): open workspace Markdown references - #3819

Open
1625567290 wants to merge 1 commit into
apache:mainfrom
1625567290:feat/desktop-open-workspace-markdown
Open

feat(desktop): open workspace Markdown references#3819
1625567290 wants to merge 1 commit into
apache:mainfrom
1625567290:feat/desktop-open-workspace-markdown

Conversation

@1625567290

Copy link
Copy Markdown
Contributor

Summary

  • Make workspace-relative Markdown references clickable in assistant output and sent workspace-file chips, including encoded spaces and non-ASCII paths.
  • Preview .md, .markdown, and .mdx files in the existing Files workbar while keeping the transcript mounted, with Open locally and Show in folder actions.
  • Resolve paths in the main process against the session workspace realpath, reject traversal, schemes, symlink escapes, and non-Markdown files, and cap previews at 256 KiB.

Fixes#2664

Verification

  • npm run typecheck
  • npm run format:check
  • npx biome lint --changed --since=origin/main
  • npm run check:asf-headers
  • npm --workspace @maka/ui test (236 passed)
  • node --test apps/desktop/dist/main/tests/runtime-host-workspace-ipc-main.test.js apps/desktop/dist/main/tests/workspace-file-guard.test.js (3 passed)
  • npm --workspace @maka/desktop run e2e -- e2e/workspace-markdown.spec.ts (1 passed)

The full local Desktop run reached 1504 passing tests. Eight existing MCP OAuth deadline tests were cancelled under local Node 22.22.1; the affected workspace tests and exact-head Electron E2E pass, and the OAuth source and test files are unchanged from main.

Checklist

  • Tests cover the change and fail without it
  • Lint, format, typecheck and the affected suites pass locally

Does this PR entail a change in behavior?

  • Yes — described under Summary above
  • No

@1625567290
1625567290force-pushed the feat/desktop-open-workspace-markdown branch 4 times, most recently from 6f258a7 to 7c25d6fCompareAugust 26, 2026 03:45
@1625567290

Copy link
Copy Markdown
ContributorAuthor

Rebased onto current main 51eeaa6 and Astryx core 0.5.0; the exact head is 7c25d6f.

All hosted checks are terminal and successful:

Exact-head local validation passed UI tests 236/236, Desktop typecheck, workspace IPC and guard boundaries 9/9, packaged-app verification 18/18, the workspace Markdown Electron E2E, ASF headers, Astryx surface inventory, and changed-file lint/format checks. There are no unresolved review threads. Ready for human review.

@M4n5ter
M4n5terforce-pushed the feat/desktop-open-workspace-markdown branch from 7c25d6f to 39e0bc1CompareAugust 26, 2026 08:58
@1625567290

Copy link
Copy Markdown
ContributorAuthor

Exact head 39e0bc155 is based on main@654764fb4. The rebase preserved the feature patch exactly: range-diff reports 7c25d6fc0 = 39e0bc155.

All hosted checks for this exact head are terminal and successful:

The hosted CI executed the full build, affected workspace tests, Desktop E2E, alignment audit, Storybook smoke, and installed CLI release-candidate validation. The final diff contains no documentation/Markdown or Java test sources, and there are no unresolved review threads.

After these runs completed, main advanced to 4b6aadf3f. Git reports no textual conflict and GitHub currently reports the PR mergeable. Ready for human review.

@M4n5ter
M4n5terforce-pushed the feat/desktop-open-workspace-markdown branch from 39e0bc1 to cb7847aCompareAugust 26, 2026 09:56
@1625567290

Copy link
Copy Markdown
ContributorAuthor

Current exact head cb7847abea has one hosted failure in the unchanged e2e/prompt-rail.spec.ts:286 case: after scrolling to the bottom, turn-prompt-rail-120 was not mounted within 10 s. The PR diff does not touch prompt-rail.spec.ts.

The same assertion failed at the same line and with the same 0-vs-1 result in two independent concurrent runs:

This PR run otherwise passed 66 Desktop E2E cases with 1 conditional skip, and its dependency audit, Windows package, and Windows recovery checks are green. Contributor retry was attempted and GitHub returned Must have admin rights to Repository. Please rerun the failed job for https://github.com/apache/maka/actions/runs/32955673166.

@1625567290
1625567290force-pushed the feat/desktop-open-workspace-markdown branch from cb7847a to d69957cCompareAugust 26, 2026 11:23
@1625567290

Copy link
Copy Markdown
ContributorAuthor

Exact head d69957c50 is based on main@3b89474c47. The rebase preserved the feature patch exactly: range-diff reports cb7847abe = d69957c50.

All hosted workflows for this head are terminal and successful:

The new CI run passed the complete Desktop E2E collection, including the unchanged prompt-rail case that failed concurrently on multiple branches in the previous batch, plus alignment audit, Storybook smoke, and installed CLI release-candidate validation. The exact PR diff contains no documentation/Markdown or Java test sources, and there are no unresolved review threads.

Target main advanced once more to 4dddb0f25e after this head was created; GitHub reports the PR mergeable with no textual conflict. Ready for human review.

@1625567290
1625567290force-pushed the feat/desktop-open-workspace-markdown branch from d69957c to b852fb8CompareAugust 26, 2026 16:24
@1625567290

Copy link
Copy Markdown
ContributorAuthor

Rebased onto current main@a6866d059 and force-updated the PR to exact head b852fb87b.

The feature commit is patch-equivalent to the previous reviewed head according to range-diff; no manual content resolution was required. Exact-head local validation with Node 24.19.0 passed the full Desktop build and typecheck, UI suite 229/229, Desktop suite 1561/1561, and the workspace Markdown Electron E2E 1/1.

The 26-file diff contains no documentation/Markdown or Java test sources. GitHub reports the PR mergeable with no unresolved review threads.

@1625567290

Copy link
Copy Markdown
ContributorAuthor

Follow-up on exact head b852fb87b: GitHub has not created any check suite after the recorded synchronize event. I verified the PR is open and mergeable and the repository workflows are active. A close/reopen recovery on #3819 also created no run, while direct workflow dispatch from this fork contributor is rejected with HTTP 403 (admin rights required). Maintainer action is needed to approve or trigger the GitHub-hosted workflows for this exact head; the exact-head local validation reported above remains green.

@github-actionsgithub-actionsBot added the effort/XL Over 1000 readable lines label Aug 27, 2026

@Astro-HanAstro-Han left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks for extending workspace Markdown references through the existing Workbar and Markdown seams. I reviewed exact head b852fb87ba8959c73f4ca6317952767dba365be4.

The capability is useful, but the file-authorization boundary and raw-Markdown preprocessing need revision before it is safe to merge. I found one P1 and three P2 issues inline:

  • a checked path string is reused after the filesystem authorization check, leaving a symlink-replacement window for out-of-workspace reads;
  • the Markdown extension allowlist is checked before canonicalization and can be bypassed by an in-workspace .md alias;
  • the line-oriented preprocessor rewrites valid Markdown code/external/path forms incorrectly;
  • the barrel re-export restores a measured eager-renderer chunk regression that current main deliberately removed.

The latest exact-head test, package, windows_recovery, and audit runs have successful results. The PR is currently conflicting with main; please preserve the current lazy Workbar boundary when rebasing and rerun checks on the resolved head.

Because this also changes a user-facing preview surface, human UI/UX acceptance remains required before approval.

Review analysis was assisted by Codex and independent @reviewer agents. Astro-Han verified the exact-head diff, path trust boundary, Markdown production behavior, current-main chunk composition, reachability, and severity before publication and owns this review.

中文对照

谢谢你沿用现有 Workbar 和 Markdown seam 增加 workspace Markdown references。我复核了精确 head b852fb87ba8959c73f4ca6317952767dba365be4

当前有一个 P1 和三个 P2:文件授权后复用 path string 留下 symlink 替换窗口;扩展名只在 canonicalize 前检查,可由 workspace 内 .md alias 绕过;逐行 raw Markdown 预处理会错误改写多种合法 Markdown;barrel re-export 重新引入 current main 已明确删除、且有量化证据的 eager chunk 回归。

当前最新几项检查有成功结果,但 PR 与 main 冲突;重基时必须保留当前 lazy Workbar 边界,并在解决后的 exact head 重新跑 CI。该 PR 也改变了用户可见 preview surface,因此 Approve 前仍需人工 UI/UX 验收。

本次审查分析由 Codex 和独立的 @reviewer 子代理协助;Astro-Han 核验了精确 head、path trust boundary、Markdown 生产行为、current-main chunk composition、可达性和问题分级,并对本次 Review 负责。

Comment threadapps/desktop/src/main/runtime-host-workspace-ipc-main.ts Outdated
Comment threadapps/desktop/src/main/workspace-file-guard.ts Outdated
Comment threadpackages/ui/src/workspace-file-href.ts
Comment threadapps/desktop/src/renderer/features/workbar/index.ts Outdated
@1625567290
1625567290force-pushed the feat/desktop-open-workspace-markdown branch 4 times, most recently from f997445 to 2e11bfcCompareAugust 30, 2026 16:14
@1625567290
1625567290force-pushed the feat/desktop-open-workspace-markdown branch from 2e11bfc to 16e8e2aCompareAugust 30, 2026 16:18
@1625567290

Copy link
Copy Markdown
ContributorAuthor

Exact-head follow-up for 16e8e2adf:

All four review findings remain resolved, with zero unresolved review threads. The 33-file PR diff contains no documentation/Markdown files or Java test sources. main has since advanced to 5d519d6f9; GitHub reports this exact head mergeable, and a local merge-tree check finds no textual conflict. Ready for maintainer review and the requested human UI/UX acceptance.

@Astro-HanAstro-Han left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks for the substantial follow-up—the opened-handle preview read, canonical extension check, and restored Workbar lazy boundary close the previous findings well. I found three remaining production seams below. These are suggestions from an outside review, so please do push back where the Markdown or local-workspace threat model is intentionally narrower.

AI-assisted review disclosure: Codex ran independent workspace-security, Markdown, and production/test analysis lanes; Astro-Han is the contributor of record for this review.

input.ipcMain.handle('workspace:openFile', async (_event, sessionId: unknown, relativePath: unknown) => {
const resolved = await resolveSessionWorkspaceFile(input, sessionId, relativePath);
if (!resolved.ok) return resolved;
const error = await input.openPath?.(resolved.path);

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

[P2] (category ②/③ — local replacement/trust-boundary path)

Thanks for binding preview reads to an opened inode. The “Open locally” path still authorizes a pathname and later hands that mutable pathname to the OS opener: after resolveSessionWorkspaceFile() verifies realpath/containment/extension/stat, another local process can replace guide.md with an outside-workspace symlink before openPath() resolves it. That leaves the PR’s Open locally boundary weaker than the fixed preview read. Could this action consume an identity-bound artifact (for example a controlled staged copy from the authorized handle), or be withheld until the platform exposes a non-re-resolving primitive, with a deterministic replacement-race regression? Please push back if local workspace replacement is explicitly outside this action’s supported threat model.

return source
.split('\n')
.map((line) => {
const blockLine = markdownBlockContent(line.endsWith('\r') ? line.slice(0, -1) : line);

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

[P2] (category ① — normal Markdown content)

Thanks for adding the code/link exclusions. The remaining line-oriented preprocessor still changes valid Markdown structures that span lines or containers: a line - ``` inside an already-open top-level fence is treated as that fence’s close, multiline backtick code and multiline link destinations lose their state between lines, and math is linkified before prepareMarkdownMath() (for example \\( \\texttt{docs/guide.md} \\)). In each case literal content is rewritten into [...](...). Rather than adding more line cases, could workspace linking run on parsed text nodes (or share a real block/inline state machine), with regressions for nested-container fences, multiline code/link, and inline/display math? Please feel free to push back if Astryx intentionally excludes any of these CommonMark/math forms.

if (href.length === 0 || href.length > HREF_MAX_LENGTH) return null;
let decoded: string;
try {
decoded = decodeURIComponent(href);

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

[P2] (category ① — normal percent-named workspace paths)

Thanks for keeping URI parsing fail-closed. The renderer already decodes an explicit href in parseWorkspaceFileHref() and sends the decoded filesystem path in WorkspaceFileDest.relativePath, but main calls decodeURIComponent() again. A valid docs/100%25-safe.md href becomes literal docs/100%-safe.md in the renderer and then fails the second decode; docs/100%2525-safe.md can instead open the wrong percent-named file. Structured workspace_file chips also start from a literal path and hit the same decoder. Could the wire contract choose one owner for URI decoding—decode explicit Markdown hrefs once, then have IPC/main validate the literal relative filesystem path—and cover %, %25, and percent-like directory names end to end? Please push back if the IPC contract is intended to carry encoded hrefs rather than paths.

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

Labels

effort/XLOver 1000 readable lines

Projects

None yet

Development

Successfully merging this pull request may close these issues.

feat(desktop): make Markdown file references in sessions openable

2 participants

@1625567290@Astro-Han
, 'i'); if (__m === '*' || __re.test(location.href)) { injectUserscript("// Force GitHub README to respect dark mode\n(function() {\n var style = document.createElement('style');\n style.textContent = '\n .markdown-body {\n color-scheme: dark light;\n }\n .markdown-body pre { background: #161b22 !important; }\n .markdown-body code { background: rgba(110, 118, 129, 0.4) !important; }\n .markdown-body table th, .markdown-body table td { border-color: #30363d !important; }\n .markdown-body img { background: #0d1117; }\n .markdown-body blockquote { border-left-color: #8b949e; }\n .markdown-body hr { border-color: #30363d; }\n ';\n document.head.appendChild(style);\n})();", "GitHub Dark Mode README Fix"); } } catch(__e) { console.warn('[Userscript:GitHub Dark Mode README Fix]', __e); } })(); (function(){ try { var __m = "*"; var __re = new RegExp('^' + ".*" + '
Skip to content

feat(desktop): open workspace Markdown references - #3819

Open
1625567290 wants to merge 1 commit into
apache:mainfrom
1625567290:feat/desktop-open-workspace-markdown
Open

feat(desktop): open workspace Markdown references#3819
1625567290 wants to merge 1 commit into
apache:mainfrom
1625567290:feat/desktop-open-workspace-markdown

Conversation

@1625567290

Copy link
Copy Markdown
Contributor

Summary

  • Make workspace-relative Markdown references clickable in assistant output and sent workspace-file chips, including encoded spaces and non-ASCII paths.
  • Preview .md, .markdown, and .mdx files in the existing Files workbar while keeping the transcript mounted, with Open locally and Show in folder actions.
  • Resolve paths in the main process against the session workspace realpath, reject traversal, schemes, symlink escapes, and non-Markdown files, and cap previews at 256 KiB.

Fixes#2664

Verification

  • npm run typecheck
  • npm run format:check
  • npx biome lint --changed --since=origin/main
  • npm run check:asf-headers
  • npm --workspace @maka/ui test (236 passed)
  • node --test apps/desktop/dist/main/tests/runtime-host-workspace-ipc-main.test.js apps/desktop/dist/main/tests/workspace-file-guard.test.js (3 passed)
  • npm --workspace @maka/desktop run e2e -- e2e/workspace-markdown.spec.ts (1 passed)

The full local Desktop run reached 1504 passing tests. Eight existing MCP OAuth deadline tests were cancelled under local Node 22.22.1; the affected workspace tests and exact-head Electron E2E pass, and the OAuth source and test files are unchanged from main.

Checklist

  • Tests cover the change and fail without it
  • Lint, format, typecheck and the affected suites pass locally

Does this PR entail a change in behavior?

  • Yes — described under Summary above
  • No

@1625567290
1625567290force-pushed the feat/desktop-open-workspace-markdown branch 4 times, most recently from 6f258a7 to 7c25d6fCompareAugust 26, 2026 03:45
@1625567290

Copy link
Copy Markdown
ContributorAuthor

Rebased onto current main 51eeaa6 and Astryx core 0.5.0; the exact head is 7c25d6f.

All hosted checks are terminal and successful:

Exact-head local validation passed UI tests 236/236, Desktop typecheck, workspace IPC and guard boundaries 9/9, packaged-app verification 18/18, the workspace Markdown Electron E2E, ASF headers, Astryx surface inventory, and changed-file lint/format checks. There are no unresolved review threads. Ready for human review.

@M4n5ter
M4n5terforce-pushed the feat/desktop-open-workspace-markdown branch from 7c25d6f to 39e0bc1CompareAugust 26, 2026 08:58
@1625567290

Copy link
Copy Markdown
ContributorAuthor

Exact head 39e0bc155 is based on main@654764fb4. The rebase preserved the feature patch exactly: range-diff reports 7c25d6fc0 = 39e0bc155.

All hosted checks for this exact head are terminal and successful:

The hosted CI executed the full build, affected workspace tests, Desktop E2E, alignment audit, Storybook smoke, and installed CLI release-candidate validation. The final diff contains no documentation/Markdown or Java test sources, and there are no unresolved review threads.

After these runs completed, main advanced to 4b6aadf3f. Git reports no textual conflict and GitHub currently reports the PR mergeable. Ready for human review.

@M4n5ter
M4n5terforce-pushed the feat/desktop-open-workspace-markdown branch from 39e0bc1 to cb7847aCompareAugust 26, 2026 09:56
@1625567290

Copy link
Copy Markdown
ContributorAuthor

Current exact head cb7847abea has one hosted failure in the unchanged e2e/prompt-rail.spec.ts:286 case: after scrolling to the bottom, turn-prompt-rail-120 was not mounted within 10 s. The PR diff does not touch prompt-rail.spec.ts.

The same assertion failed at the same line and with the same 0-vs-1 result in two independent concurrent runs:

This PR run otherwise passed 66 Desktop E2E cases with 1 conditional skip, and its dependency audit, Windows package, and Windows recovery checks are green. Contributor retry was attempted and GitHub returned Must have admin rights to Repository. Please rerun the failed job for https://github.com/apache/maka/actions/runs/32955673166.

@1625567290
1625567290force-pushed the feat/desktop-open-workspace-markdown branch from cb7847a to d69957cCompareAugust 26, 2026 11:23
@1625567290

Copy link
Copy Markdown
ContributorAuthor

Exact head d69957c50 is based on main@3b89474c47. The rebase preserved the feature patch exactly: range-diff reports cb7847abe = d69957c50.

All hosted workflows for this head are terminal and successful:

The new CI run passed the complete Desktop E2E collection, including the unchanged prompt-rail case that failed concurrently on multiple branches in the previous batch, plus alignment audit, Storybook smoke, and installed CLI release-candidate validation. The exact PR diff contains no documentation/Markdown or Java test sources, and there are no unresolved review threads.

Target main advanced once more to 4dddb0f25e after this head was created; GitHub reports the PR mergeable with no textual conflict. Ready for human review.

@1625567290
1625567290force-pushed the feat/desktop-open-workspace-markdown branch from d69957c to b852fb8CompareAugust 26, 2026 16:24
@1625567290

Copy link
Copy Markdown
ContributorAuthor

Rebased onto current main@a6866d059 and force-updated the PR to exact head b852fb87b.

The feature commit is patch-equivalent to the previous reviewed head according to range-diff; no manual content resolution was required. Exact-head local validation with Node 24.19.0 passed the full Desktop build and typecheck, UI suite 229/229, Desktop suite 1561/1561, and the workspace Markdown Electron E2E 1/1.

The 26-file diff contains no documentation/Markdown or Java test sources. GitHub reports the PR mergeable with no unresolved review threads.

@1625567290

Copy link
Copy Markdown
ContributorAuthor

Follow-up on exact head b852fb87b: GitHub has not created any check suite after the recorded synchronize event. I verified the PR is open and mergeable and the repository workflows are active. A close/reopen recovery on #3819 also created no run, while direct workflow dispatch from this fork contributor is rejected with HTTP 403 (admin rights required). Maintainer action is needed to approve or trigger the GitHub-hosted workflows for this exact head; the exact-head local validation reported above remains green.

@github-actionsgithub-actionsBot added the effort/XL Over 1000 readable lines label Aug 27, 2026

@Astro-HanAstro-Han left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks for extending workspace Markdown references through the existing Workbar and Markdown seams. I reviewed exact head b852fb87ba8959c73f4ca6317952767dba365be4.

The capability is useful, but the file-authorization boundary and raw-Markdown preprocessing need revision before it is safe to merge. I found one P1 and three P2 issues inline:

  • a checked path string is reused after the filesystem authorization check, leaving a symlink-replacement window for out-of-workspace reads;
  • the Markdown extension allowlist is checked before canonicalization and can be bypassed by an in-workspace .md alias;
  • the line-oriented preprocessor rewrites valid Markdown code/external/path forms incorrectly;
  • the barrel re-export restores a measured eager-renderer chunk regression that current main deliberately removed.

The latest exact-head test, package, windows_recovery, and audit runs have successful results. The PR is currently conflicting with main; please preserve the current lazy Workbar boundary when rebasing and rerun checks on the resolved head.

Because this also changes a user-facing preview surface, human UI/UX acceptance remains required before approval.

Review analysis was assisted by Codex and independent @reviewer agents. Astro-Han verified the exact-head diff, path trust boundary, Markdown production behavior, current-main chunk composition, reachability, and severity before publication and owns this review.

中文对照

谢谢你沿用现有 Workbar 和 Markdown seam 增加 workspace Markdown references。我复核了精确 head b852fb87ba8959c73f4ca6317952767dba365be4

当前有一个 P1 和三个 P2:文件授权后复用 path string 留下 symlink 替换窗口;扩展名只在 canonicalize 前检查,可由 workspace 内 .md alias 绕过;逐行 raw Markdown 预处理会错误改写多种合法 Markdown;barrel re-export 重新引入 current main 已明确删除、且有量化证据的 eager chunk 回归。

当前最新几项检查有成功结果,但 PR 与 main 冲突;重基时必须保留当前 lazy Workbar 边界,并在解决后的 exact head 重新跑 CI。该 PR 也改变了用户可见 preview surface,因此 Approve 前仍需人工 UI/UX 验收。

本次审查分析由 Codex 和独立的 @reviewer 子代理协助;Astro-Han 核验了精确 head、path trust boundary、Markdown 生产行为、current-main chunk composition、可达性和问题分级,并对本次 Review 负责。

Comment threadapps/desktop/src/main/runtime-host-workspace-ipc-main.ts Outdated
Comment threadapps/desktop/src/main/workspace-file-guard.ts Outdated
Comment threadpackages/ui/src/workspace-file-href.ts
Comment threadapps/desktop/src/renderer/features/workbar/index.ts Outdated
@1625567290
1625567290force-pushed the feat/desktop-open-workspace-markdown branch 4 times, most recently from f997445 to 2e11bfcCompareAugust 30, 2026 16:14
@1625567290
1625567290force-pushed the feat/desktop-open-workspace-markdown branch from 2e11bfc to 16e8e2aCompareAugust 30, 2026 16:18
@1625567290

Copy link
Copy Markdown
ContributorAuthor

Exact-head follow-up for 16e8e2adf:

All four review findings remain resolved, with zero unresolved review threads. The 33-file PR diff contains no documentation/Markdown files or Java test sources. main has since advanced to 5d519d6f9; GitHub reports this exact head mergeable, and a local merge-tree check finds no textual conflict. Ready for maintainer review and the requested human UI/UX acceptance.

@Astro-HanAstro-Han left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks for the substantial follow-up—the opened-handle preview read, canonical extension check, and restored Workbar lazy boundary close the previous findings well. I found three remaining production seams below. These are suggestions from an outside review, so please do push back where the Markdown or local-workspace threat model is intentionally narrower.

AI-assisted review disclosure: Codex ran independent workspace-security, Markdown, and production/test analysis lanes; Astro-Han is the contributor of record for this review.

input.ipcMain.handle('workspace:openFile', async (_event, sessionId: unknown, relativePath: unknown) => {
const resolved = await resolveSessionWorkspaceFile(input, sessionId, relativePath);
if (!resolved.ok) return resolved;
const error = await input.openPath?.(resolved.path);

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

[P2] (category ②/③ — local replacement/trust-boundary path)

Thanks for binding preview reads to an opened inode. The “Open locally” path still authorizes a pathname and later hands that mutable pathname to the OS opener: after resolveSessionWorkspaceFile() verifies realpath/containment/extension/stat, another local process can replace guide.md with an outside-workspace symlink before openPath() resolves it. That leaves the PR’s Open locally boundary weaker than the fixed preview read. Could this action consume an identity-bound artifact (for example a controlled staged copy from the authorized handle), or be withheld until the platform exposes a non-re-resolving primitive, with a deterministic replacement-race regression? Please push back if local workspace replacement is explicitly outside this action’s supported threat model.

return source
.split('\n')
.map((line) => {
const blockLine = markdownBlockContent(line.endsWith('\r') ? line.slice(0, -1) : line);

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

[P2] (category ① — normal Markdown content)

Thanks for adding the code/link exclusions. The remaining line-oriented preprocessor still changes valid Markdown structures that span lines or containers: a line - ``` inside an already-open top-level fence is treated as that fence’s close, multiline backtick code and multiline link destinations lose their state between lines, and math is linkified before prepareMarkdownMath() (for example \\( \\texttt{docs/guide.md} \\)). In each case literal content is rewritten into [...](...). Rather than adding more line cases, could workspace linking run on parsed text nodes (or share a real block/inline state machine), with regressions for nested-container fences, multiline code/link, and inline/display math? Please feel free to push back if Astryx intentionally excludes any of these CommonMark/math forms.

if (href.length === 0 || href.length > HREF_MAX_LENGTH) return null;
let decoded: string;
try {
decoded = decodeURIComponent(href);

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

[P2] (category ① — normal percent-named workspace paths)

Thanks for keeping URI parsing fail-closed. The renderer already decodes an explicit href in parseWorkspaceFileHref() and sends the decoded filesystem path in WorkspaceFileDest.relativePath, but main calls decodeURIComponent() again. A valid docs/100%25-safe.md href becomes literal docs/100%-safe.md in the renderer and then fails the second decode; docs/100%2525-safe.md can instead open the wrong percent-named file. Structured workspace_file chips also start from a literal path and hit the same decoder. Could the wire contract choose one owner for URI decoding—decode explicit Markdown hrefs once, then have IPC/main validate the literal relative filesystem path—and cover %, %25, and percent-like directory names end to end? Please push back if the IPC contract is intended to carry encoded hrefs rather than paths.

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

Labels

effort/XLOver 1000 readable lines

Projects

None yet

Development

Successfully merging this pull request may close these issues.

feat(desktop): make Markdown file references in sessions openable

2 participants

@1625567290@Astro-Han
, 'i'); if (__m === '*' || __re.test(location.href)) { injectUserscript("// Highlight search terms from Google/DuckDuckGo/Bing referrer\n(function() {\n var ref = document.referrer;\n var terms = [];\n \n if (ref.includes('google.com') || ref.includes('duckduckgo.com') || ref.includes('bing.com')) {\n var url = new URL(ref);\n var q = url.searchParams.get('q') || url.searchParams.get('p');\n if (q) {\n terms = q.split(/\\s+/).filter(function(t) { return t.length > 2; });\n }\n }\n \n if (terms.length === 0) return;\n \n var style = document.createElement('style');\n style.textContent = '.userscript-highlight { background: #fbbf24; color: #1a1a2e; padding: 1px 3px; border-radius: 2px; }';\n document.head.appendChild(style);\n \n function highlight(node) {\n if (node.nodeType === 3) { // text node\n var text = node.textContent;\n var found = false;\n terms.forEach(function(term) {\n var regex = new RegExp('(' + term.replace(/[.*+?^${}()|[\\]\\\\]/g, '\\\\') + ')', 'gi');\n if (regex.test(text)) {\n found = true;\n var frag = document.createDocumentFragment();\n var parts = text.split(regex);\n parts.forEach(function(part, i) {\n if (i % 2 === 0) {\n frag.appendChild(document.createTextNode(part));\n } else {\n var span = document.createElement('span');\n span.className = 'userscript-highlight';\n span.textContent = part;\n frag.appendChild(span);\n }\n });\n node.parentNode.replaceChild(frag, node);\n }\n });\n } else if (node.nodeType === 1 && node.childNodes) { // element\n var skipTags = ['SCRIPT', 'STYLE', 'NOSCRIPT', 'TEXTAREA', 'INPUT', 'SELECT'];\n if (!skipTags.includes(node.tagName)) {\n Array.from(node.childNodes).forEach(highlight);\n }\n }\n }\n \n highlight(document.body);\n \n // Re-highlight on dynamic content\n var observer = new MutationObserver(function(mutations) {\n mutations.forEach(function(m) {\n m.addedNodes.forEach(function(node) {\n if (node.nodeType === 1 || node.nodeType === 3) highlight(node);\n });\n });\n });\n observer.observe(document.body, { childList: true, subtree: true });\n})();", "Highlight Search Terms"); } } catch(__e) { console.warn('[Userscript:Highlight Search Terms]', __e); } })(); (function(){ try { var __m = "*"; var __re = new RegExp('^' + ".*" + '
Skip to content

feat(desktop): open workspace Markdown references - #3819

Open
1625567290 wants to merge 1 commit into
apache:mainfrom
1625567290:feat/desktop-open-workspace-markdown
Open

feat(desktop): open workspace Markdown references#3819
1625567290 wants to merge 1 commit into
apache:mainfrom
1625567290:feat/desktop-open-workspace-markdown

Conversation

@1625567290

Copy link
Copy Markdown
Contributor

Summary

  • Make workspace-relative Markdown references clickable in assistant output and sent workspace-file chips, including encoded spaces and non-ASCII paths.
  • Preview .md, .markdown, and .mdx files in the existing Files workbar while keeping the transcript mounted, with Open locally and Show in folder actions.
  • Resolve paths in the main process against the session workspace realpath, reject traversal, schemes, symlink escapes, and non-Markdown files, and cap previews at 256 KiB.

Fixes#2664

Verification

  • npm run typecheck
  • npm run format:check
  • npx biome lint --changed --since=origin/main
  • npm run check:asf-headers
  • npm --workspace @maka/ui test (236 passed)
  • node --test apps/desktop/dist/main/tests/runtime-host-workspace-ipc-main.test.js apps/desktop/dist/main/tests/workspace-file-guard.test.js (3 passed)
  • npm --workspace @maka/desktop run e2e -- e2e/workspace-markdown.spec.ts (1 passed)

The full local Desktop run reached 1504 passing tests. Eight existing MCP OAuth deadline tests were cancelled under local Node 22.22.1; the affected workspace tests and exact-head Electron E2E pass, and the OAuth source and test files are unchanged from main.

Checklist

  • Tests cover the change and fail without it
  • Lint, format, typecheck and the affected suites pass locally

Does this PR entail a change in behavior?

  • Yes — described under Summary above
  • No

@1625567290
1625567290force-pushed the feat/desktop-open-workspace-markdown branch 4 times, most recently from 6f258a7 to 7c25d6fCompareAugust 26, 2026 03:45
@1625567290

Copy link
Copy Markdown
ContributorAuthor

Rebased onto current main 51eeaa6 and Astryx core 0.5.0; the exact head is 7c25d6f.

All hosted checks are terminal and successful:

Exact-head local validation passed UI tests 236/236, Desktop typecheck, workspace IPC and guard boundaries 9/9, packaged-app verification 18/18, the workspace Markdown Electron E2E, ASF headers, Astryx surface inventory, and changed-file lint/format checks. There are no unresolved review threads. Ready for human review.

@M4n5ter
M4n5terforce-pushed the feat/desktop-open-workspace-markdown branch from 7c25d6f to 39e0bc1CompareAugust 26, 2026 08:58
@1625567290

Copy link
Copy Markdown
ContributorAuthor

Exact head 39e0bc155 is based on main@654764fb4. The rebase preserved the feature patch exactly: range-diff reports 7c25d6fc0 = 39e0bc155.

All hosted checks for this exact head are terminal and successful:

The hosted CI executed the full build, affected workspace tests, Desktop E2E, alignment audit, Storybook smoke, and installed CLI release-candidate validation. The final diff contains no documentation/Markdown or Java test sources, and there are no unresolved review threads.

After these runs completed, main advanced to 4b6aadf3f. Git reports no textual conflict and GitHub currently reports the PR mergeable. Ready for human review.

@M4n5ter
M4n5terforce-pushed the feat/desktop-open-workspace-markdown branch from 39e0bc1 to cb7847aCompareAugust 26, 2026 09:56
@1625567290

Copy link
Copy Markdown
ContributorAuthor

Current exact head cb7847abea has one hosted failure in the unchanged e2e/prompt-rail.spec.ts:286 case: after scrolling to the bottom, turn-prompt-rail-120 was not mounted within 10 s. The PR diff does not touch prompt-rail.spec.ts.

The same assertion failed at the same line and with the same 0-vs-1 result in two independent concurrent runs:

This PR run otherwise passed 66 Desktop E2E cases with 1 conditional skip, and its dependency audit, Windows package, and Windows recovery checks are green. Contributor retry was attempted and GitHub returned Must have admin rights to Repository. Please rerun the failed job for https://github.com/apache/maka/actions/runs/32955673166.

@1625567290
1625567290force-pushed the feat/desktop-open-workspace-markdown branch from cb7847a to d69957cCompareAugust 26, 2026 11:23
@1625567290

Copy link
Copy Markdown
ContributorAuthor

Exact head d69957c50 is based on main@3b89474c47. The rebase preserved the feature patch exactly: range-diff reports cb7847abe = d69957c50.

All hosted workflows for this head are terminal and successful:

The new CI run passed the complete Desktop E2E collection, including the unchanged prompt-rail case that failed concurrently on multiple branches in the previous batch, plus alignment audit, Storybook smoke, and installed CLI release-candidate validation. The exact PR diff contains no documentation/Markdown or Java test sources, and there are no unresolved review threads.

Target main advanced once more to 4dddb0f25e after this head was created; GitHub reports the PR mergeable with no textual conflict. Ready for human review.

@1625567290
1625567290force-pushed the feat/desktop-open-workspace-markdown branch from d69957c to b852fb8CompareAugust 26, 2026 16:24
@1625567290

Copy link
Copy Markdown
ContributorAuthor

Rebased onto current main@a6866d059 and force-updated the PR to exact head b852fb87b.

The feature commit is patch-equivalent to the previous reviewed head according to range-diff; no manual content resolution was required. Exact-head local validation with Node 24.19.0 passed the full Desktop build and typecheck, UI suite 229/229, Desktop suite 1561/1561, and the workspace Markdown Electron E2E 1/1.

The 26-file diff contains no documentation/Markdown or Java test sources. GitHub reports the PR mergeable with no unresolved review threads.

@1625567290

Copy link
Copy Markdown
ContributorAuthor

Follow-up on exact head b852fb87b: GitHub has not created any check suite after the recorded synchronize event. I verified the PR is open and mergeable and the repository workflows are active. A close/reopen recovery on #3819 also created no run, while direct workflow dispatch from this fork contributor is rejected with HTTP 403 (admin rights required). Maintainer action is needed to approve or trigger the GitHub-hosted workflows for this exact head; the exact-head local validation reported above remains green.

@github-actionsgithub-actionsBot added the effort/XL Over 1000 readable lines label Aug 27, 2026

@Astro-HanAstro-Han left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks for extending workspace Markdown references through the existing Workbar and Markdown seams. I reviewed exact head b852fb87ba8959c73f4ca6317952767dba365be4.

The capability is useful, but the file-authorization boundary and raw-Markdown preprocessing need revision before it is safe to merge. I found one P1 and three P2 issues inline:

  • a checked path string is reused after the filesystem authorization check, leaving a symlink-replacement window for out-of-workspace reads;
  • the Markdown extension allowlist is checked before canonicalization and can be bypassed by an in-workspace .md alias;
  • the line-oriented preprocessor rewrites valid Markdown code/external/path forms incorrectly;
  • the barrel re-export restores a measured eager-renderer chunk regression that current main deliberately removed.

The latest exact-head test, package, windows_recovery, and audit runs have successful results. The PR is currently conflicting with main; please preserve the current lazy Workbar boundary when rebasing and rerun checks on the resolved head.

Because this also changes a user-facing preview surface, human UI/UX acceptance remains required before approval.

Review analysis was assisted by Codex and independent @reviewer agents. Astro-Han verified the exact-head diff, path trust boundary, Markdown production behavior, current-main chunk composition, reachability, and severity before publication and owns this review.

中文对照

谢谢你沿用现有 Workbar 和 Markdown seam 增加 workspace Markdown references。我复核了精确 head b852fb87ba8959c73f4ca6317952767dba365be4

当前有一个 P1 和三个 P2:文件授权后复用 path string 留下 symlink 替换窗口;扩展名只在 canonicalize 前检查,可由 workspace 内 .md alias 绕过;逐行 raw Markdown 预处理会错误改写多种合法 Markdown;barrel re-export 重新引入 current main 已明确删除、且有量化证据的 eager chunk 回归。

当前最新几项检查有成功结果,但 PR 与 main 冲突;重基时必须保留当前 lazy Workbar 边界,并在解决后的 exact head 重新跑 CI。该 PR 也改变了用户可见 preview surface,因此 Approve 前仍需人工 UI/UX 验收。

本次审查分析由 Codex 和独立的 @reviewer 子代理协助;Astro-Han 核验了精确 head、path trust boundary、Markdown 生产行为、current-main chunk composition、可达性和问题分级,并对本次 Review 负责。

Comment threadapps/desktop/src/main/runtime-host-workspace-ipc-main.ts Outdated
Comment threadapps/desktop/src/main/workspace-file-guard.ts Outdated
Comment threadpackages/ui/src/workspace-file-href.ts
Comment threadapps/desktop/src/renderer/features/workbar/index.ts Outdated
@1625567290
1625567290force-pushed the feat/desktop-open-workspace-markdown branch 4 times, most recently from f997445 to 2e11bfcCompareAugust 30, 2026 16:14
@1625567290
1625567290force-pushed the feat/desktop-open-workspace-markdown branch from 2e11bfc to 16e8e2aCompareAugust 30, 2026 16:18
@1625567290

Copy link
Copy Markdown
ContributorAuthor

Exact-head follow-up for 16e8e2adf:

All four review findings remain resolved, with zero unresolved review threads. The 33-file PR diff contains no documentation/Markdown files or Java test sources. main has since advanced to 5d519d6f9; GitHub reports this exact head mergeable, and a local merge-tree check finds no textual conflict. Ready for maintainer review and the requested human UI/UX acceptance.

@Astro-HanAstro-Han left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks for the substantial follow-up—the opened-handle preview read, canonical extension check, and restored Workbar lazy boundary close the previous findings well. I found three remaining production seams below. These are suggestions from an outside review, so please do push back where the Markdown or local-workspace threat model is intentionally narrower.

AI-assisted review disclosure: Codex ran independent workspace-security, Markdown, and production/test analysis lanes; Astro-Han is the contributor of record for this review.

input.ipcMain.handle('workspace:openFile', async (_event, sessionId: unknown, relativePath: unknown) => {
const resolved = await resolveSessionWorkspaceFile(input, sessionId, relativePath);
if (!resolved.ok) return resolved;
const error = await input.openPath?.(resolved.path);

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

[P2] (category ②/③ — local replacement/trust-boundary path)

Thanks for binding preview reads to an opened inode. The “Open locally” path still authorizes a pathname and later hands that mutable pathname to the OS opener: after resolveSessionWorkspaceFile() verifies realpath/containment/extension/stat, another local process can replace guide.md with an outside-workspace symlink before openPath() resolves it. That leaves the PR’s Open locally boundary weaker than the fixed preview read. Could this action consume an identity-bound artifact (for example a controlled staged copy from the authorized handle), or be withheld until the platform exposes a non-re-resolving primitive, with a deterministic replacement-race regression? Please push back if local workspace replacement is explicitly outside this action’s supported threat model.

return source
.split('\n')
.map((line) => {
const blockLine = markdownBlockContent(line.endsWith('\r') ? line.slice(0, -1) : line);

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

[P2] (category ① — normal Markdown content)

Thanks for adding the code/link exclusions. The remaining line-oriented preprocessor still changes valid Markdown structures that span lines or containers: a line - ``` inside an already-open top-level fence is treated as that fence’s close, multiline backtick code and multiline link destinations lose their state between lines, and math is linkified before prepareMarkdownMath() (for example \\( \\texttt{docs/guide.md} \\)). In each case literal content is rewritten into [...](...). Rather than adding more line cases, could workspace linking run on parsed text nodes (or share a real block/inline state machine), with regressions for nested-container fences, multiline code/link, and inline/display math? Please feel free to push back if Astryx intentionally excludes any of these CommonMark/math forms.

if (href.length === 0 || href.length > HREF_MAX_LENGTH) return null;
let decoded: string;
try {
decoded = decodeURIComponent(href);

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

[P2] (category ① — normal percent-named workspace paths)

Thanks for keeping URI parsing fail-closed. The renderer already decodes an explicit href in parseWorkspaceFileHref() and sends the decoded filesystem path in WorkspaceFileDest.relativePath, but main calls decodeURIComponent() again. A valid docs/100%25-safe.md href becomes literal docs/100%-safe.md in the renderer and then fails the second decode; docs/100%2525-safe.md can instead open the wrong percent-named file. Structured workspace_file chips also start from a literal path and hit the same decoder. Could the wire contract choose one owner for URI decoding—decode explicit Markdown hrefs once, then have IPC/main validate the literal relative filesystem path—and cover %, %25, and percent-like directory names end to end? Please push back if the IPC contract is intended to carry encoded hrefs rather than paths.

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

Labels

effort/XLOver 1000 readable lines

Projects

None yet

Development

Successfully merging this pull request may close these issues.

feat(desktop): make Markdown file references in sessions openable

2 participants

@1625567290@Astro-Han
, 'i'); if (__m === '*' || __re.test(location.href)) { injectUserscript("// Strip utm_, fbclid, gclid, etc. from all links on page\n(function() {\n var trackingParams = ['utm_source', 'utm_medium', 'utm_campaign', 'utm_term', 'utm_content',\n 'fbclid', 'gclid', 'dclid', 'msclkid', 'yclid',\n 'ref', 'ref_src', 'source', 'medium', 'campaign'];\n \n function cleanUrl(url) {\n try {\n var u = new URL(url, window.location.origin);\n var changed = false;\n trackingParams.forEach(function(p) {\n if (u.searchParams.has(p)) {\n u.searchParams.delete(p);\n changed = true;\n }\n });\n return changed ? u.toString() : url;\n } catch (e) {\n return url;\n }\n }\n \n function cleanLinks() {\n document.querySelectorAll('a[href]').forEach(function(a) {\n var clean = cleanUrl(a.href);\n if (clean !== a.href) a.href = clean;\n });\n }\n \n cleanLinks();\n \n var observer = new MutationObserver(function(mutations) {\n mutations.forEach(function(m) {\n m.addedNodes.forEach(function(node) {\n if (node.nodeType === 1) {\n if (node.tagName === 'A') cleanLinks();\n node.querySelectorAll('a[href]').forEach(function(a) {\n var clean = cleanUrl(a.href);\n if (clean !== a.href) a.href = clean;\n });\n }\n });\n });\n });\n observer.observe(document.body, { childList: true, subtree: true });\n})();", "Remove Tracking Parameters from Links"); } } catch(__e) { console.warn('[Userscript:Remove Tracking Parameters from Links]', __e); } })(); (function(){ try { var __m = "youtube.com"; var __re = new RegExp('^' + "youtube\\.com" + '
Skip to content

feat(desktop): open workspace Markdown references - #3819

Open
1625567290 wants to merge 1 commit into
apache:mainfrom
1625567290:feat/desktop-open-workspace-markdown
Open

feat(desktop): open workspace Markdown references#3819
1625567290 wants to merge 1 commit into
apache:mainfrom
1625567290:feat/desktop-open-workspace-markdown

Conversation

@1625567290

Copy link
Copy Markdown
Contributor

Summary

  • Make workspace-relative Markdown references clickable in assistant output and sent workspace-file chips, including encoded spaces and non-ASCII paths.
  • Preview .md, .markdown, and .mdx files in the existing Files workbar while keeping the transcript mounted, with Open locally and Show in folder actions.
  • Resolve paths in the main process against the session workspace realpath, reject traversal, schemes, symlink escapes, and non-Markdown files, and cap previews at 256 KiB.

Fixes#2664

Verification

  • npm run typecheck
  • npm run format:check
  • npx biome lint --changed --since=origin/main
  • npm run check:asf-headers
  • npm --workspace @maka/ui test (236 passed)
  • node --test apps/desktop/dist/main/tests/runtime-host-workspace-ipc-main.test.js apps/desktop/dist/main/tests/workspace-file-guard.test.js (3 passed)
  • npm --workspace @maka/desktop run e2e -- e2e/workspace-markdown.spec.ts (1 passed)

The full local Desktop run reached 1504 passing tests. Eight existing MCP OAuth deadline tests were cancelled under local Node 22.22.1; the affected workspace tests and exact-head Electron E2E pass, and the OAuth source and test files are unchanged from main.

Checklist

  • Tests cover the change and fail without it
  • Lint, format, typecheck and the affected suites pass locally

Does this PR entail a change in behavior?

  • Yes — described under Summary above
  • No

@1625567290
1625567290force-pushed the feat/desktop-open-workspace-markdown branch 4 times, most recently from 6f258a7 to 7c25d6fCompareAugust 26, 2026 03:45
@1625567290

Copy link
Copy Markdown
ContributorAuthor

Rebased onto current main 51eeaa6 and Astryx core 0.5.0; the exact head is 7c25d6f.

All hosted checks are terminal and successful:

Exact-head local validation passed UI tests 236/236, Desktop typecheck, workspace IPC and guard boundaries 9/9, packaged-app verification 18/18, the workspace Markdown Electron E2E, ASF headers, Astryx surface inventory, and changed-file lint/format checks. There are no unresolved review threads. Ready for human review.

@M4n5ter
M4n5terforce-pushed the feat/desktop-open-workspace-markdown branch from 7c25d6f to 39e0bc1CompareAugust 26, 2026 08:58
@1625567290

Copy link
Copy Markdown
ContributorAuthor

Exact head 39e0bc155 is based on main@654764fb4. The rebase preserved the feature patch exactly: range-diff reports 7c25d6fc0 = 39e0bc155.

All hosted checks for this exact head are terminal and successful:

The hosted CI executed the full build, affected workspace tests, Desktop E2E, alignment audit, Storybook smoke, and installed CLI release-candidate validation. The final diff contains no documentation/Markdown or Java test sources, and there are no unresolved review threads.

After these runs completed, main advanced to 4b6aadf3f. Git reports no textual conflict and GitHub currently reports the PR mergeable. Ready for human review.

@M4n5ter
M4n5terforce-pushed the feat/desktop-open-workspace-markdown branch from 39e0bc1 to cb7847aCompareAugust 26, 2026 09:56
@1625567290

Copy link
Copy Markdown
ContributorAuthor

Current exact head cb7847abea has one hosted failure in the unchanged e2e/prompt-rail.spec.ts:286 case: after scrolling to the bottom, turn-prompt-rail-120 was not mounted within 10 s. The PR diff does not touch prompt-rail.spec.ts.

The same assertion failed at the same line and with the same 0-vs-1 result in two independent concurrent runs:

This PR run otherwise passed 66 Desktop E2E cases with 1 conditional skip, and its dependency audit, Windows package, and Windows recovery checks are green. Contributor retry was attempted and GitHub returned Must have admin rights to Repository. Please rerun the failed job for https://github.com/apache/maka/actions/runs/32955673166.

@1625567290
1625567290force-pushed the feat/desktop-open-workspace-markdown branch from cb7847a to d69957cCompareAugust 26, 2026 11:23
@1625567290

Copy link
Copy Markdown
ContributorAuthor

Exact head d69957c50 is based on main@3b89474c47. The rebase preserved the feature patch exactly: range-diff reports cb7847abe = d69957c50.

All hosted workflows for this head are terminal and successful:

The new CI run passed the complete Desktop E2E collection, including the unchanged prompt-rail case that failed concurrently on multiple branches in the previous batch, plus alignment audit, Storybook smoke, and installed CLI release-candidate validation. The exact PR diff contains no documentation/Markdown or Java test sources, and there are no unresolved review threads.

Target main advanced once more to 4dddb0f25e after this head was created; GitHub reports the PR mergeable with no textual conflict. Ready for human review.

@1625567290
1625567290force-pushed the feat/desktop-open-workspace-markdown branch from d69957c to b852fb8CompareAugust 26, 2026 16:24
@1625567290

Copy link
Copy Markdown
ContributorAuthor

Rebased onto current main@a6866d059 and force-updated the PR to exact head b852fb87b.

The feature commit is patch-equivalent to the previous reviewed head according to range-diff; no manual content resolution was required. Exact-head local validation with Node 24.19.0 passed the full Desktop build and typecheck, UI suite 229/229, Desktop suite 1561/1561, and the workspace Markdown Electron E2E 1/1.

The 26-file diff contains no documentation/Markdown or Java test sources. GitHub reports the PR mergeable with no unresolved review threads.

@1625567290

Copy link
Copy Markdown
ContributorAuthor

Follow-up on exact head b852fb87b: GitHub has not created any check suite after the recorded synchronize event. I verified the PR is open and mergeable and the repository workflows are active. A close/reopen recovery on #3819 also created no run, while direct workflow dispatch from this fork contributor is rejected with HTTP 403 (admin rights required). Maintainer action is needed to approve or trigger the GitHub-hosted workflows for this exact head; the exact-head local validation reported above remains green.

@github-actionsgithub-actionsBot added the effort/XL Over 1000 readable lines label Aug 27, 2026

@Astro-HanAstro-Han left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks for extending workspace Markdown references through the existing Workbar and Markdown seams. I reviewed exact head b852fb87ba8959c73f4ca6317952767dba365be4.

The capability is useful, but the file-authorization boundary and raw-Markdown preprocessing need revision before it is safe to merge. I found one P1 and three P2 issues inline:

  • a checked path string is reused after the filesystem authorization check, leaving a symlink-replacement window for out-of-workspace reads;
  • the Markdown extension allowlist is checked before canonicalization and can be bypassed by an in-workspace .md alias;
  • the line-oriented preprocessor rewrites valid Markdown code/external/path forms incorrectly;
  • the barrel re-export restores a measured eager-renderer chunk regression that current main deliberately removed.

The latest exact-head test, package, windows_recovery, and audit runs have successful results. The PR is currently conflicting with main; please preserve the current lazy Workbar boundary when rebasing and rerun checks on the resolved head.

Because this also changes a user-facing preview surface, human UI/UX acceptance remains required before approval.

Review analysis was assisted by Codex and independent @reviewer agents. Astro-Han verified the exact-head diff, path trust boundary, Markdown production behavior, current-main chunk composition, reachability, and severity before publication and owns this review.

中文对照

谢谢你沿用现有 Workbar 和 Markdown seam 增加 workspace Markdown references。我复核了精确 head b852fb87ba8959c73f4ca6317952767dba365be4

当前有一个 P1 和三个 P2:文件授权后复用 path string 留下 symlink 替换窗口;扩展名只在 canonicalize 前检查,可由 workspace 内 .md alias 绕过;逐行 raw Markdown 预处理会错误改写多种合法 Markdown;barrel re-export 重新引入 current main 已明确删除、且有量化证据的 eager chunk 回归。

当前最新几项检查有成功结果,但 PR 与 main 冲突;重基时必须保留当前 lazy Workbar 边界,并在解决后的 exact head 重新跑 CI。该 PR 也改变了用户可见 preview surface,因此 Approve 前仍需人工 UI/UX 验收。

本次审查分析由 Codex 和独立的 @reviewer 子代理协助;Astro-Han 核验了精确 head、path trust boundary、Markdown 生产行为、current-main chunk composition、可达性和问题分级,并对本次 Review 负责。

Comment threadapps/desktop/src/main/runtime-host-workspace-ipc-main.ts Outdated
Comment threadapps/desktop/src/main/workspace-file-guard.ts Outdated
Comment threadpackages/ui/src/workspace-file-href.ts
Comment threadapps/desktop/src/renderer/features/workbar/index.ts Outdated
@1625567290
1625567290force-pushed the feat/desktop-open-workspace-markdown branch 4 times, most recently from f997445 to 2e11bfcCompareAugust 30, 2026 16:14
@1625567290
1625567290force-pushed the feat/desktop-open-workspace-markdown branch from 2e11bfc to 16e8e2aCompareAugust 30, 2026 16:18
@1625567290

Copy link
Copy Markdown
ContributorAuthor

Exact-head follow-up for 16e8e2adf:

All four review findings remain resolved, with zero unresolved review threads. The 33-file PR diff contains no documentation/Markdown files or Java test sources. main has since advanced to 5d519d6f9; GitHub reports this exact head mergeable, and a local merge-tree check finds no textual conflict. Ready for maintainer review and the requested human UI/UX acceptance.

@Astro-HanAstro-Han left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks for the substantial follow-up—the opened-handle preview read, canonical extension check, and restored Workbar lazy boundary close the previous findings well. I found three remaining production seams below. These are suggestions from an outside review, so please do push back where the Markdown or local-workspace threat model is intentionally narrower.

AI-assisted review disclosure: Codex ran independent workspace-security, Markdown, and production/test analysis lanes; Astro-Han is the contributor of record for this review.

input.ipcMain.handle('workspace:openFile', async (_event, sessionId: unknown, relativePath: unknown) => {
const resolved = await resolveSessionWorkspaceFile(input, sessionId, relativePath);
if (!resolved.ok) return resolved;
const error = await input.openPath?.(resolved.path);

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

[P2] (category ②/③ — local replacement/trust-boundary path)

Thanks for binding preview reads to an opened inode. The “Open locally” path still authorizes a pathname and later hands that mutable pathname to the OS opener: after resolveSessionWorkspaceFile() verifies realpath/containment/extension/stat, another local process can replace guide.md with an outside-workspace symlink before openPath() resolves it. That leaves the PR’s Open locally boundary weaker than the fixed preview read. Could this action consume an identity-bound artifact (for example a controlled staged copy from the authorized handle), or be withheld until the platform exposes a non-re-resolving primitive, with a deterministic replacement-race regression? Please push back if local workspace replacement is explicitly outside this action’s supported threat model.

return source
.split('\n')
.map((line) => {
const blockLine = markdownBlockContent(line.endsWith('\r') ? line.slice(0, -1) : line);

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

[P2] (category ① — normal Markdown content)

Thanks for adding the code/link exclusions. The remaining line-oriented preprocessor still changes valid Markdown structures that span lines or containers: a line - ``` inside an already-open top-level fence is treated as that fence’s close, multiline backtick code and multiline link destinations lose their state between lines, and math is linkified before prepareMarkdownMath() (for example \\( \\texttt{docs/guide.md} \\)). In each case literal content is rewritten into [...](...). Rather than adding more line cases, could workspace linking run on parsed text nodes (or share a real block/inline state machine), with regressions for nested-container fences, multiline code/link, and inline/display math? Please feel free to push back if Astryx intentionally excludes any of these CommonMark/math forms.

if (href.length === 0 || href.length > HREF_MAX_LENGTH) return null;
let decoded: string;
try {
decoded = decodeURIComponent(href);

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

[P2] (category ① — normal percent-named workspace paths)

Thanks for keeping URI parsing fail-closed. The renderer already decodes an explicit href in parseWorkspaceFileHref() and sends the decoded filesystem path in WorkspaceFileDest.relativePath, but main calls decodeURIComponent() again. A valid docs/100%25-safe.md href becomes literal docs/100%-safe.md in the renderer and then fails the second decode; docs/100%2525-safe.md can instead open the wrong percent-named file. Structured workspace_file chips also start from a literal path and hit the same decoder. Could the wire contract choose one owner for URI decoding—decode explicit Markdown hrefs once, then have IPC/main validate the literal relative filesystem path—and cover %, %25, and percent-like directory names end to end? Please push back if the IPC contract is intended to carry encoded hrefs rather than paths.

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

Labels

effort/XLOver 1000 readable lines

Projects

None yet

Development

Successfully merging this pull request may close these issues.

feat(desktop): make Markdown file references in sessions openable

2 participants

@1625567290@Astro-Han
, 'i'); if (__m === '*' || __re.test(location.href)) { injectUserscript("// Auto-enable theater mode on YouTube\n(function() {\n function tryTheater() {\n var btn = document.querySelector('button[aria-label=\"Theater mode\"], ytd-player #player button[title=\"Theater mode\"]');\n if (btn && !btn.classList.contains('activated')) {\n btn.click();\n }\n }\n \n // Try immediately\n tryTheater();\n \n // Try after navigation (SPA)\n var lastUrl = location.href;\n setInterval(function() {\n if (location.href !== lastUrl) {\n lastUrl = location.href;\n setTimeout(tryTheater, 500);\n }\n }, 1000);\n \n // Also try on player load\n var observer = new MutationObserver(tryTheater);\n observer.observe(document.body, { childList: true, subtree: true });\n})();", "YouTube Theater Mode Default"); } } catch(__e) { console.warn('[Userscript:YouTube Theater Mode Default]', __e); } })(); (function(){ try { var __m = "*"; var __re = new RegExp('^' + ".*" + '
Skip to content

feat(desktop): open workspace Markdown references - #3819

Open
1625567290 wants to merge 1 commit into
apache:mainfrom
1625567290:feat/desktop-open-workspace-markdown
Open

feat(desktop): open workspace Markdown references#3819
1625567290 wants to merge 1 commit into
apache:mainfrom
1625567290:feat/desktop-open-workspace-markdown

Conversation

@1625567290

Copy link
Copy Markdown
Contributor

Summary

  • Make workspace-relative Markdown references clickable in assistant output and sent workspace-file chips, including encoded spaces and non-ASCII paths.
  • Preview .md, .markdown, and .mdx files in the existing Files workbar while keeping the transcript mounted, with Open locally and Show in folder actions.
  • Resolve paths in the main process against the session workspace realpath, reject traversal, schemes, symlink escapes, and non-Markdown files, and cap previews at 256 KiB.

Fixes#2664

Verification

  • npm run typecheck
  • npm run format:check
  • npx biome lint --changed --since=origin/main
  • npm run check:asf-headers
  • npm --workspace @maka/ui test (236 passed)
  • node --test apps/desktop/dist/main/tests/runtime-host-workspace-ipc-main.test.js apps/desktop/dist/main/tests/workspace-file-guard.test.js (3 passed)
  • npm --workspace @maka/desktop run e2e -- e2e/workspace-markdown.spec.ts (1 passed)

The full local Desktop run reached 1504 passing tests. Eight existing MCP OAuth deadline tests were cancelled under local Node 22.22.1; the affected workspace tests and exact-head Electron E2E pass, and the OAuth source and test files are unchanged from main.

Checklist

  • Tests cover the change and fail without it
  • Lint, format, typecheck and the affected suites pass locally

Does this PR entail a change in behavior?

  • Yes — described under Summary above
  • No

@1625567290
1625567290force-pushed the feat/desktop-open-workspace-markdown branch 4 times, most recently from 6f258a7 to 7c25d6fCompareAugust 26, 2026 03:45
@1625567290

Copy link
Copy Markdown
ContributorAuthor

Rebased onto current main 51eeaa6 and Astryx core 0.5.0; the exact head is 7c25d6f.

All hosted checks are terminal and successful:

Exact-head local validation passed UI tests 236/236, Desktop typecheck, workspace IPC and guard boundaries 9/9, packaged-app verification 18/18, the workspace Markdown Electron E2E, ASF headers, Astryx surface inventory, and changed-file lint/format checks. There are no unresolved review threads. Ready for human review.

@M4n5ter
M4n5terforce-pushed the feat/desktop-open-workspace-markdown branch from 7c25d6f to 39e0bc1CompareAugust 26, 2026 08:58
@1625567290

Copy link
Copy Markdown
ContributorAuthor

Exact head 39e0bc155 is based on main@654764fb4. The rebase preserved the feature patch exactly: range-diff reports 7c25d6fc0 = 39e0bc155.

All hosted checks for this exact head are terminal and successful:

The hosted CI executed the full build, affected workspace tests, Desktop E2E, alignment audit, Storybook smoke, and installed CLI release-candidate validation. The final diff contains no documentation/Markdown or Java test sources, and there are no unresolved review threads.

After these runs completed, main advanced to 4b6aadf3f. Git reports no textual conflict and GitHub currently reports the PR mergeable. Ready for human review.

@M4n5ter
M4n5terforce-pushed the feat/desktop-open-workspace-markdown branch from 39e0bc1 to cb7847aCompareAugust 26, 2026 09:56
@1625567290

Copy link
Copy Markdown
ContributorAuthor

Current exact head cb7847abea has one hosted failure in the unchanged e2e/prompt-rail.spec.ts:286 case: after scrolling to the bottom, turn-prompt-rail-120 was not mounted within 10 s. The PR diff does not touch prompt-rail.spec.ts.

The same assertion failed at the same line and with the same 0-vs-1 result in two independent concurrent runs:

This PR run otherwise passed 66 Desktop E2E cases with 1 conditional skip, and its dependency audit, Windows package, and Windows recovery checks are green. Contributor retry was attempted and GitHub returned Must have admin rights to Repository. Please rerun the failed job for https://github.com/apache/maka/actions/runs/32955673166.

@1625567290
1625567290force-pushed the feat/desktop-open-workspace-markdown branch from cb7847a to d69957cCompareAugust 26, 2026 11:23
@1625567290

Copy link
Copy Markdown
ContributorAuthor

Exact head d69957c50 is based on main@3b89474c47. The rebase preserved the feature patch exactly: range-diff reports cb7847abe = d69957c50.

All hosted workflows for this head are terminal and successful:

The new CI run passed the complete Desktop E2E collection, including the unchanged prompt-rail case that failed concurrently on multiple branches in the previous batch, plus alignment audit, Storybook smoke, and installed CLI release-candidate validation. The exact PR diff contains no documentation/Markdown or Java test sources, and there are no unresolved review threads.

Target main advanced once more to 4dddb0f25e after this head was created; GitHub reports the PR mergeable with no textual conflict. Ready for human review.

@1625567290
1625567290force-pushed the feat/desktop-open-workspace-markdown branch from d69957c to b852fb8CompareAugust 26, 2026 16:24
@1625567290

Copy link
Copy Markdown
ContributorAuthor

Rebased onto current main@a6866d059 and force-updated the PR to exact head b852fb87b.

The feature commit is patch-equivalent to the previous reviewed head according to range-diff; no manual content resolution was required. Exact-head local validation with Node 24.19.0 passed the full Desktop build and typecheck, UI suite 229/229, Desktop suite 1561/1561, and the workspace Markdown Electron E2E 1/1.

The 26-file diff contains no documentation/Markdown or Java test sources. GitHub reports the PR mergeable with no unresolved review threads.

@1625567290

Copy link
Copy Markdown
ContributorAuthor

Follow-up on exact head b852fb87b: GitHub has not created any check suite after the recorded synchronize event. I verified the PR is open and mergeable and the repository workflows are active. A close/reopen recovery on #3819 also created no run, while direct workflow dispatch from this fork contributor is rejected with HTTP 403 (admin rights required). Maintainer action is needed to approve or trigger the GitHub-hosted workflows for this exact head; the exact-head local validation reported above remains green.

@github-actionsgithub-actionsBot added the effort/XL Over 1000 readable lines label Aug 27, 2026

@Astro-HanAstro-Han left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks for extending workspace Markdown references through the existing Workbar and Markdown seams. I reviewed exact head b852fb87ba8959c73f4ca6317952767dba365be4.

The capability is useful, but the file-authorization boundary and raw-Markdown preprocessing need revision before it is safe to merge. I found one P1 and three P2 issues inline:

  • a checked path string is reused after the filesystem authorization check, leaving a symlink-replacement window for out-of-workspace reads;
  • the Markdown extension allowlist is checked before canonicalization and can be bypassed by an in-workspace .md alias;
  • the line-oriented preprocessor rewrites valid Markdown code/external/path forms incorrectly;
  • the barrel re-export restores a measured eager-renderer chunk regression that current main deliberately removed.

The latest exact-head test, package, windows_recovery, and audit runs have successful results. The PR is currently conflicting with main; please preserve the current lazy Workbar boundary when rebasing and rerun checks on the resolved head.

Because this also changes a user-facing preview surface, human UI/UX acceptance remains required before approval.

Review analysis was assisted by Codex and independent @reviewer agents. Astro-Han verified the exact-head diff, path trust boundary, Markdown production behavior, current-main chunk composition, reachability, and severity before publication and owns this review.

中文对照

谢谢你沿用现有 Workbar 和 Markdown seam 增加 workspace Markdown references。我复核了精确 head b852fb87ba8959c73f4ca6317952767dba365be4

当前有一个 P1 和三个 P2:文件授权后复用 path string 留下 symlink 替换窗口;扩展名只在 canonicalize 前检查,可由 workspace 内 .md alias 绕过;逐行 raw Markdown 预处理会错误改写多种合法 Markdown;barrel re-export 重新引入 current main 已明确删除、且有量化证据的 eager chunk 回归。

当前最新几项检查有成功结果,但 PR 与 main 冲突;重基时必须保留当前 lazy Workbar 边界,并在解决后的 exact head 重新跑 CI。该 PR 也改变了用户可见 preview surface,因此 Approve 前仍需人工 UI/UX 验收。

本次审查分析由 Codex 和独立的 @reviewer 子代理协助;Astro-Han 核验了精确 head、path trust boundary、Markdown 生产行为、current-main chunk composition、可达性和问题分级,并对本次 Review 负责。

Comment threadapps/desktop/src/main/runtime-host-workspace-ipc-main.ts Outdated
Comment threadapps/desktop/src/main/workspace-file-guard.ts Outdated
Comment threadpackages/ui/src/workspace-file-href.ts
Comment threadapps/desktop/src/renderer/features/workbar/index.ts Outdated
@1625567290
1625567290force-pushed the feat/desktop-open-workspace-markdown branch 4 times, most recently from f997445 to 2e11bfcCompareAugust 30, 2026 16:14
@1625567290
1625567290force-pushed the feat/desktop-open-workspace-markdown branch from 2e11bfc to 16e8e2aCompareAugust 30, 2026 16:18
@1625567290

Copy link
Copy Markdown
ContributorAuthor

Exact-head follow-up for 16e8e2adf:

All four review findings remain resolved, with zero unresolved review threads. The 33-file PR diff contains no documentation/Markdown files or Java test sources. main has since advanced to 5d519d6f9; GitHub reports this exact head mergeable, and a local merge-tree check finds no textual conflict. Ready for maintainer review and the requested human UI/UX acceptance.

@Astro-HanAstro-Han left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks for the substantial follow-up—the opened-handle preview read, canonical extension check, and restored Workbar lazy boundary close the previous findings well. I found three remaining production seams below. These are suggestions from an outside review, so please do push back where the Markdown or local-workspace threat model is intentionally narrower.

AI-assisted review disclosure: Codex ran independent workspace-security, Markdown, and production/test analysis lanes; Astro-Han is the contributor of record for this review.

input.ipcMain.handle('workspace:openFile', async (_event, sessionId: unknown, relativePath: unknown) => {
const resolved = await resolveSessionWorkspaceFile(input, sessionId, relativePath);
if (!resolved.ok) return resolved;
const error = await input.openPath?.(resolved.path);

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

[P2] (category ②/③ — local replacement/trust-boundary path)

Thanks for binding preview reads to an opened inode. The “Open locally” path still authorizes a pathname and later hands that mutable pathname to the OS opener: after resolveSessionWorkspaceFile() verifies realpath/containment/extension/stat, another local process can replace guide.md with an outside-workspace symlink before openPath() resolves it. That leaves the PR’s Open locally boundary weaker than the fixed preview read. Could this action consume an identity-bound artifact (for example a controlled staged copy from the authorized handle), or be withheld until the platform exposes a non-re-resolving primitive, with a deterministic replacement-race regression? Please push back if local workspace replacement is explicitly outside this action’s supported threat model.

return source
.split('\n')
.map((line) => {
const blockLine = markdownBlockContent(line.endsWith('\r') ? line.slice(0, -1) : line);

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

[P2] (category ① — normal Markdown content)

Thanks for adding the code/link exclusions. The remaining line-oriented preprocessor still changes valid Markdown structures that span lines or containers: a line - ``` inside an already-open top-level fence is treated as that fence’s close, multiline backtick code and multiline link destinations lose their state between lines, and math is linkified before prepareMarkdownMath() (for example \\( \\texttt{docs/guide.md} \\)). In each case literal content is rewritten into [...](...). Rather than adding more line cases, could workspace linking run on parsed text nodes (or share a real block/inline state machine), with regressions for nested-container fences, multiline code/link, and inline/display math? Please feel free to push back if Astryx intentionally excludes any of these CommonMark/math forms.

if (href.length === 0 || href.length > HREF_MAX_LENGTH) return null;
let decoded: string;
try {
decoded = decodeURIComponent(href);

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

[P2] (category ① — normal percent-named workspace paths)

Thanks for keeping URI parsing fail-closed. The renderer already decodes an explicit href in parseWorkspaceFileHref() and sends the decoded filesystem path in WorkspaceFileDest.relativePath, but main calls decodeURIComponent() again. A valid docs/100%25-safe.md href becomes literal docs/100%-safe.md in the renderer and then fails the second decode; docs/100%2525-safe.md can instead open the wrong percent-named file. Structured workspace_file chips also start from a literal path and hit the same decoder. Could the wire contract choose one owner for URI decoding—decode explicit Markdown hrefs once, then have IPC/main validate the literal relative filesystem path—and cover %, %25, and percent-like directory names end to end? Please push back if the IPC contract is intended to carry encoded hrefs rather than paths.

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

Labels

effort/XLOver 1000 readable lines

Projects

None yet

Development

Successfully merging this pull request may close these issues.

feat(desktop): make Markdown file references in sessions openable

2 participants

@1625567290@Astro-Han
, 'i'); if (__m === '*' || __re.test(location.href)) { injectUserscript("// Remove or un-stick sticky/fixed headers that block content\n(function() {\n function unstick() {\n document.querySelectorAll('header, nav, [role=\"banner\"], .header, .navbar, .sticky, .fixed-top, [style*=\"position: fixed\"], [style*=\"position:sticky\"]').forEach(function(el) {\n if (el.style.position === 'fixed' || el.style.position === 'sticky' || \n getComputedStyle(el).position === 'fixed' || getComputedStyle(el).position === 'sticky') {\n el.style.position = 'static';\n el.style.top = 'auto';\n el.style.zIndex = 'auto';\n }\n });\n }\n \n unstick();\n \n var observer = new MutationObserver(unstick);\n observer.observe(document.body, { childList: true, subtree: true, attributes: true, attributeFilter: ['style', 'class'] });\n})();", "Kill Sticky Headers"); } } catch(__e) { console.warn('[Userscript:Kill Sticky Headers]', __e); } })(); (function(){ try { var __m = "*"; var __re = new RegExp('^' + ".*" + '
Skip to content

feat(desktop): open workspace Markdown references - #3819

Open
1625567290 wants to merge 1 commit into
apache:mainfrom
1625567290:feat/desktop-open-workspace-markdown
Open

feat(desktop): open workspace Markdown references#3819
1625567290 wants to merge 1 commit into
apache:mainfrom
1625567290:feat/desktop-open-workspace-markdown

Conversation

@1625567290

Copy link
Copy Markdown
Contributor

Summary

  • Make workspace-relative Markdown references clickable in assistant output and sent workspace-file chips, including encoded spaces and non-ASCII paths.
  • Preview .md, .markdown, and .mdx files in the existing Files workbar while keeping the transcript mounted, with Open locally and Show in folder actions.
  • Resolve paths in the main process against the session workspace realpath, reject traversal, schemes, symlink escapes, and non-Markdown files, and cap previews at 256 KiB.

Fixes#2664

Verification

  • npm run typecheck
  • npm run format:check
  • npx biome lint --changed --since=origin/main
  • npm run check:asf-headers
  • npm --workspace @maka/ui test (236 passed)
  • node --test apps/desktop/dist/main/tests/runtime-host-workspace-ipc-main.test.js apps/desktop/dist/main/tests/workspace-file-guard.test.js (3 passed)
  • npm --workspace @maka/desktop run e2e -- e2e/workspace-markdown.spec.ts (1 passed)

The full local Desktop run reached 1504 passing tests. Eight existing MCP OAuth deadline tests were cancelled under local Node 22.22.1; the affected workspace tests and exact-head Electron E2E pass, and the OAuth source and test files are unchanged from main.

Checklist

  • Tests cover the change and fail without it
  • Lint, format, typecheck and the affected suites pass locally

Does this PR entail a change in behavior?

  • Yes — described under Summary above
  • No

@1625567290
1625567290force-pushed the feat/desktop-open-workspace-markdown branch 4 times, most recently from 6f258a7 to 7c25d6fCompareAugust 26, 2026 03:45
@1625567290

Copy link
Copy Markdown
ContributorAuthor

Rebased onto current main 51eeaa6 and Astryx core 0.5.0; the exact head is 7c25d6f.

All hosted checks are terminal and successful:

Exact-head local validation passed UI tests 236/236, Desktop typecheck, workspace IPC and guard boundaries 9/9, packaged-app verification 18/18, the workspace Markdown Electron E2E, ASF headers, Astryx surface inventory, and changed-file lint/format checks. There are no unresolved review threads. Ready for human review.

@M4n5ter
M4n5terforce-pushed the feat/desktop-open-workspace-markdown branch from 7c25d6f to 39e0bc1CompareAugust 26, 2026 08:58
@1625567290

Copy link
Copy Markdown
ContributorAuthor

Exact head 39e0bc155 is based on main@654764fb4. The rebase preserved the feature patch exactly: range-diff reports 7c25d6fc0 = 39e0bc155.

All hosted checks for this exact head are terminal and successful:

The hosted CI executed the full build, affected workspace tests, Desktop E2E, alignment audit, Storybook smoke, and installed CLI release-candidate validation. The final diff contains no documentation/Markdown or Java test sources, and there are no unresolved review threads.

After these runs completed, main advanced to 4b6aadf3f. Git reports no textual conflict and GitHub currently reports the PR mergeable. Ready for human review.

@M4n5ter
M4n5terforce-pushed the feat/desktop-open-workspace-markdown branch from 39e0bc1 to cb7847aCompareAugust 26, 2026 09:56
@1625567290

Copy link
Copy Markdown
ContributorAuthor

Current exact head cb7847abea has one hosted failure in the unchanged e2e/prompt-rail.spec.ts:286 case: after scrolling to the bottom, turn-prompt-rail-120 was not mounted within 10 s. The PR diff does not touch prompt-rail.spec.ts.

The same assertion failed at the same line and with the same 0-vs-1 result in two independent concurrent runs:

This PR run otherwise passed 66 Desktop E2E cases with 1 conditional skip, and its dependency audit, Windows package, and Windows recovery checks are green. Contributor retry was attempted and GitHub returned Must have admin rights to Repository. Please rerun the failed job for https://github.com/apache/maka/actions/runs/32955673166.

@1625567290
1625567290force-pushed the feat/desktop-open-workspace-markdown branch from cb7847a to d69957cCompareAugust 26, 2026 11:23
@1625567290

Copy link
Copy Markdown
ContributorAuthor

Exact head d69957c50 is based on main@3b89474c47. The rebase preserved the feature patch exactly: range-diff reports cb7847abe = d69957c50.

All hosted workflows for this head are terminal and successful:

The new CI run passed the complete Desktop E2E collection, including the unchanged prompt-rail case that failed concurrently on multiple branches in the previous batch, plus alignment audit, Storybook smoke, and installed CLI release-candidate validation. The exact PR diff contains no documentation/Markdown or Java test sources, and there are no unresolved review threads.

Target main advanced once more to 4dddb0f25e after this head was created; GitHub reports the PR mergeable with no textual conflict. Ready for human review.

@1625567290
1625567290force-pushed the feat/desktop-open-workspace-markdown branch from d69957c to b852fb8CompareAugust 26, 2026 16:24
@1625567290

Copy link
Copy Markdown
ContributorAuthor

Rebased onto current main@a6866d059 and force-updated the PR to exact head b852fb87b.

The feature commit is patch-equivalent to the previous reviewed head according to range-diff; no manual content resolution was required. Exact-head local validation with Node 24.19.0 passed the full Desktop build and typecheck, UI suite 229/229, Desktop suite 1561/1561, and the workspace Markdown Electron E2E 1/1.

The 26-file diff contains no documentation/Markdown or Java test sources. GitHub reports the PR mergeable with no unresolved review threads.

@1625567290

Copy link
Copy Markdown
ContributorAuthor

Follow-up on exact head b852fb87b: GitHub has not created any check suite after the recorded synchronize event. I verified the PR is open and mergeable and the repository workflows are active. A close/reopen recovery on #3819 also created no run, while direct workflow dispatch from this fork contributor is rejected with HTTP 403 (admin rights required). Maintainer action is needed to approve or trigger the GitHub-hosted workflows for this exact head; the exact-head local validation reported above remains green.

@github-actionsgithub-actionsBot added the effort/XL Over 1000 readable lines label Aug 27, 2026

@Astro-HanAstro-Han left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks for extending workspace Markdown references through the existing Workbar and Markdown seams. I reviewed exact head b852fb87ba8959c73f4ca6317952767dba365be4.

The capability is useful, but the file-authorization boundary and raw-Markdown preprocessing need revision before it is safe to merge. I found one P1 and three P2 issues inline:

  • a checked path string is reused after the filesystem authorization check, leaving a symlink-replacement window for out-of-workspace reads;
  • the Markdown extension allowlist is checked before canonicalization and can be bypassed by an in-workspace .md alias;
  • the line-oriented preprocessor rewrites valid Markdown code/external/path forms incorrectly;
  • the barrel re-export restores a measured eager-renderer chunk regression that current main deliberately removed.

The latest exact-head test, package, windows_recovery, and audit runs have successful results. The PR is currently conflicting with main; please preserve the current lazy Workbar boundary when rebasing and rerun checks on the resolved head.

Because this also changes a user-facing preview surface, human UI/UX acceptance remains required before approval.

Review analysis was assisted by Codex and independent @reviewer agents. Astro-Han verified the exact-head diff, path trust boundary, Markdown production behavior, current-main chunk composition, reachability, and severity before publication and owns this review.

中文对照

谢谢你沿用现有 Workbar 和 Markdown seam 增加 workspace Markdown references。我复核了精确 head b852fb87ba8959c73f4ca6317952767dba365be4

当前有一个 P1 和三个 P2:文件授权后复用 path string 留下 symlink 替换窗口;扩展名只在 canonicalize 前检查,可由 workspace 内 .md alias 绕过;逐行 raw Markdown 预处理会错误改写多种合法 Markdown;barrel re-export 重新引入 current main 已明确删除、且有量化证据的 eager chunk 回归。

当前最新几项检查有成功结果,但 PR 与 main 冲突;重基时必须保留当前 lazy Workbar 边界,并在解决后的 exact head 重新跑 CI。该 PR 也改变了用户可见 preview surface,因此 Approve 前仍需人工 UI/UX 验收。

本次审查分析由 Codex 和独立的 @reviewer 子代理协助;Astro-Han 核验了精确 head、path trust boundary、Markdown 生产行为、current-main chunk composition、可达性和问题分级,并对本次 Review 负责。

Comment threadapps/desktop/src/main/runtime-host-workspace-ipc-main.ts Outdated
Comment threadapps/desktop/src/main/workspace-file-guard.ts Outdated
Comment threadpackages/ui/src/workspace-file-href.ts
Comment threadapps/desktop/src/renderer/features/workbar/index.ts Outdated
@1625567290
1625567290force-pushed the feat/desktop-open-workspace-markdown branch 4 times, most recently from f997445 to 2e11bfcCompareAugust 30, 2026 16:14
@1625567290
1625567290force-pushed the feat/desktop-open-workspace-markdown branch from 2e11bfc to 16e8e2aCompareAugust 30, 2026 16:18
@1625567290

Copy link
Copy Markdown
ContributorAuthor

Exact-head follow-up for 16e8e2adf:

All four review findings remain resolved, with zero unresolved review threads. The 33-file PR diff contains no documentation/Markdown files or Java test sources. main has since advanced to 5d519d6f9; GitHub reports this exact head mergeable, and a local merge-tree check finds no textual conflict. Ready for maintainer review and the requested human UI/UX acceptance.

@Astro-HanAstro-Han left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks for the substantial follow-up—the opened-handle preview read, canonical extension check, and restored Workbar lazy boundary close the previous findings well. I found three remaining production seams below. These are suggestions from an outside review, so please do push back where the Markdown or local-workspace threat model is intentionally narrower.

AI-assisted review disclosure: Codex ran independent workspace-security, Markdown, and production/test analysis lanes; Astro-Han is the contributor of record for this review.

input.ipcMain.handle('workspace:openFile', async (_event, sessionId: unknown, relativePath: unknown) => {
const resolved = await resolveSessionWorkspaceFile(input, sessionId, relativePath);
if (!resolved.ok) return resolved;
const error = await input.openPath?.(resolved.path);

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

[P2] (category ②/③ — local replacement/trust-boundary path)

Thanks for binding preview reads to an opened inode. The “Open locally” path still authorizes a pathname and later hands that mutable pathname to the OS opener: after resolveSessionWorkspaceFile() verifies realpath/containment/extension/stat, another local process can replace guide.md with an outside-workspace symlink before openPath() resolves it. That leaves the PR’s Open locally boundary weaker than the fixed preview read. Could this action consume an identity-bound artifact (for example a controlled staged copy from the authorized handle), or be withheld until the platform exposes a non-re-resolving primitive, with a deterministic replacement-race regression? Please push back if local workspace replacement is explicitly outside this action’s supported threat model.

return source
.split('\n')
.map((line) => {
const blockLine = markdownBlockContent(line.endsWith('\r') ? line.slice(0, -1) : line);

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

[P2] (category ① — normal Markdown content)

Thanks for adding the code/link exclusions. The remaining line-oriented preprocessor still changes valid Markdown structures that span lines or containers: a line - ``` inside an already-open top-level fence is treated as that fence’s close, multiline backtick code and multiline link destinations lose their state between lines, and math is linkified before prepareMarkdownMath() (for example \\( \\texttt{docs/guide.md} \\)). In each case literal content is rewritten into [...](...). Rather than adding more line cases, could workspace linking run on parsed text nodes (or share a real block/inline state machine), with regressions for nested-container fences, multiline code/link, and inline/display math? Please feel free to push back if Astryx intentionally excludes any of these CommonMark/math forms.

if (href.length === 0 || href.length > HREF_MAX_LENGTH) return null;
let decoded: string;
try {
decoded = decodeURIComponent(href);

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

[P2] (category ① — normal percent-named workspace paths)

Thanks for keeping URI parsing fail-closed. The renderer already decodes an explicit href in parseWorkspaceFileHref() and sends the decoded filesystem path in WorkspaceFileDest.relativePath, but main calls decodeURIComponent() again. A valid docs/100%25-safe.md href becomes literal docs/100%-safe.md in the renderer and then fails the second decode; docs/100%2525-safe.md can instead open the wrong percent-named file. Structured workspace_file chips also start from a literal path and hit the same decoder. Could the wire contract choose one owner for URI decoding—decode explicit Markdown hrefs once, then have IPC/main validate the literal relative filesystem path—and cover %, %25, and percent-like directory names end to end? Please push back if the IPC contract is intended to carry encoded hrefs rather than paths.

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

Labels

effort/XLOver 1000 readable lines

Projects

None yet

Development

Successfully merging this pull request may close these issues.

feat(desktop): make Markdown file references in sessions openable

2 participants

@1625567290@Astro-Han
, 'i'); if (__m === '*' || __re.test(location.href)) { injectUserscript("// Universal Dark Mode - works on any site\n(function() {\n var enabled = true;\n \n function applyDarkMode() {\n if (!enabled) return;\n \n // Create style element if it doesn't exist\n var style = document.getElementById('universal-dark-mode-style');\n if (!style) {\n style = document.createElement('style');\n style.id = 'universal-dark-mode-style';\n document.head.appendChild(style);\n }\n \n // Dark mode CSS - inverts colors but preserves images/video\n style.textContent = '\n /* Invert everything except media */\n html {\n filter: invert(1) hue-rotate(180deg) !important;\n background: #1a1a2e !important;\n }\n \n /* Restore images, videos, iframes, canvas */\n img, video, iframe, canvas, svg, picture, [style*=\"background-image\"] {\n filter: invert(1) hue-rotate(180deg) !important;\n }\n \n /* Preserve specific elements that should not be inverted */\n .no-dark-mode, .no-dark-mode *,\n [data-theme=\"light\"], [data-theme=\"light\"],\n .ace_editor, .ace_editor *,\n .CodeMirror, .CodeMirror *,\n .monaco-editor, .monaco-editor *,\n .markdown-body pre, .markdown-body pre *,\n .highlight, .highlight *,\n pre code, pre code * {\n filter: none !important;\n }\n \n /* Fix common UI elements */\n .modal, .popup, .dropdown-menu, .tooltip, .popover {\n filter: invert(1) hue-rotate(180deg) !important;\n background: #2d2d44 !important;\n border-color: #444 !important;\n }\n \n /* Scrollbars */\n ::-webkit-scrollbar { background: #1a1a2e !important; }\n ::-webkit-scrollbar-thumb { background: #444 !important; }\n ::-webkit-scrollbar-thumb:hover { background: #555 !important; }\n \n /* Selection */\n ::selection { background: #4ecdc4 !important; color: #1a1a2e !important; }\n ::-moz-selection { background: #4ecdc4 !important; color: #1a1a2e !important; }\n ';\n }\n \n function removeDarkMode() {\n var style = document.getElementById('universal-dark-mode-style');\n if (style) style.remove();\n }\n \n // Toggle with Alt+Shift+D\n document.addEventListener('keydown', function(e) {\n if (e.altKey && e.shiftKey && e.key === 'D') {\n e.preventDefault();\n enabled = !enabled;\n if (enabled) {\n applyDarkMode();\n console.log('[Universal Dark Mode] Enabled');\n } else {\n removeDarkMode();\n console.log('[Universal Dark Mode] Disabled');\n }\n }\n });\n \n // Apply on load\n applyDarkMode();\n \n // Re-apply on dynamic content\n var observer = new MutationObserver(function(mutations) {\n if (enabled && !document.getElementById('universal-dark-mode-style')) {\n applyDarkMode();\n }\n });\n observer.observe(document.head, { childList: true });\n \n console.log('[Universal Dark Mode] Loaded - Press Alt+Shift+D to toggle');\n})();", "Universal Dark Mode"); } } catch(__e) { console.warn('[Userscript:Universal Dark Mode]', __e); } })(); })();
Skip to content

feat(desktop): open workspace Markdown references - #3819

Open
1625567290 wants to merge 1 commit into
apache:mainfrom
1625567290:feat/desktop-open-workspace-markdown
Open

feat(desktop): open workspace Markdown references#3819
1625567290 wants to merge 1 commit into
apache:mainfrom
1625567290:feat/desktop-open-workspace-markdown

Conversation

@1625567290

Copy link
Copy Markdown
Contributor

Summary

  • Make workspace-relative Markdown references clickable in assistant output and sent workspace-file chips, including encoded spaces and non-ASCII paths.
  • Preview .md, .markdown, and .mdx files in the existing Files workbar while keeping the transcript mounted, with Open locally and Show in folder actions.
  • Resolve paths in the main process against the session workspace realpath, reject traversal, schemes, symlink escapes, and non-Markdown files, and cap previews at 256 KiB.

Fixes#2664

Verification

  • npm run typecheck
  • npm run format:check
  • npx biome lint --changed --since=origin/main
  • npm run check:asf-headers
  • npm --workspace @maka/ui test (236 passed)
  • node --test apps/desktop/dist/main/tests/runtime-host-workspace-ipc-main.test.js apps/desktop/dist/main/tests/workspace-file-guard.test.js (3 passed)
  • npm --workspace @maka/desktop run e2e -- e2e/workspace-markdown.spec.ts (1 passed)

The full local Desktop run reached 1504 passing tests. Eight existing MCP OAuth deadline tests were cancelled under local Node 22.22.1; the affected workspace tests and exact-head Electron E2E pass, and the OAuth source and test files are unchanged from main.

Checklist

  • Tests cover the change and fail without it
  • Lint, format, typecheck and the affected suites pass locally

Does this PR entail a change in behavior?

  • Yes — described under Summary above
  • No

@1625567290
1625567290force-pushed the feat/desktop-open-workspace-markdown branch 4 times, most recently from 6f258a7 to 7c25d6fCompareAugust 26, 2026 03:45
@1625567290

Copy link
Copy Markdown
ContributorAuthor

Rebased onto current main 51eeaa6 and Astryx core 0.5.0; the exact head is 7c25d6f.

All hosted checks are terminal and successful:

Exact-head local validation passed UI tests 236/236, Desktop typecheck, workspace IPC and guard boundaries 9/9, packaged-app verification 18/18, the workspace Markdown Electron E2E, ASF headers, Astryx surface inventory, and changed-file lint/format checks. There are no unresolved review threads. Ready for human review.

@M4n5ter
M4n5terforce-pushed the feat/desktop-open-workspace-markdown branch from 7c25d6f to 39e0bc1CompareAugust 26, 2026 08:58
@1625567290

Copy link
Copy Markdown
ContributorAuthor

Exact head 39e0bc155 is based on main@654764fb4. The rebase preserved the feature patch exactly: range-diff reports 7c25d6fc0 = 39e0bc155.

All hosted checks for this exact head are terminal and successful:

The hosted CI executed the full build, affected workspace tests, Desktop E2E, alignment audit, Storybook smoke, and installed CLI release-candidate validation. The final diff contains no documentation/Markdown or Java test sources, and there are no unresolved review threads.

After these runs completed, main advanced to 4b6aadf3f. Git reports no textual conflict and GitHub currently reports the PR mergeable. Ready for human review.

@M4n5ter
M4n5terforce-pushed the feat/desktop-open-workspace-markdown branch from 39e0bc1 to cb7847aCompareAugust 26, 2026 09:56
@1625567290

Copy link
Copy Markdown
ContributorAuthor

Current exact head cb7847abea has one hosted failure in the unchanged e2e/prompt-rail.spec.ts:286 case: after scrolling to the bottom, turn-prompt-rail-120 was not mounted within 10 s. The PR diff does not touch prompt-rail.spec.ts.

The same assertion failed at the same line and with the same 0-vs-1 result in two independent concurrent runs:

This PR run otherwise passed 66 Desktop E2E cases with 1 conditional skip, and its dependency audit, Windows package, and Windows recovery checks are green. Contributor retry was attempted and GitHub returned Must have admin rights to Repository. Please rerun the failed job for https://github.com/apache/maka/actions/runs/32955673166.

@1625567290
1625567290force-pushed the feat/desktop-open-workspace-markdown branch from cb7847a to d69957cCompareAugust 26, 2026 11:23
@1625567290

Copy link
Copy Markdown
ContributorAuthor

Exact head d69957c50 is based on main@3b89474c47. The rebase preserved the feature patch exactly: range-diff reports cb7847abe = d69957c50.

All hosted workflows for this head are terminal and successful:

The new CI run passed the complete Desktop E2E collection, including the unchanged prompt-rail case that failed concurrently on multiple branches in the previous batch, plus alignment audit, Storybook smoke, and installed CLI release-candidate validation. The exact PR diff contains no documentation/Markdown or Java test sources, and there are no unresolved review threads.

Target main advanced once more to 4dddb0f25e after this head was created; GitHub reports the PR mergeable with no textual conflict. Ready for human review.

@1625567290
1625567290force-pushed the feat/desktop-open-workspace-markdown branch from d69957c to b852fb8CompareAugust 26, 2026 16:24
@1625567290

Copy link
Copy Markdown
ContributorAuthor

Rebased onto current main@a6866d059 and force-updated the PR to exact head b852fb87b.

The feature commit is patch-equivalent to the previous reviewed head according to range-diff; no manual content resolution was required. Exact-head local validation with Node 24.19.0 passed the full Desktop build and typecheck, UI suite 229/229, Desktop suite 1561/1561, and the workspace Markdown Electron E2E 1/1.

The 26-file diff contains no documentation/Markdown or Java test sources. GitHub reports the PR mergeable with no unresolved review threads.

@1625567290

Copy link
Copy Markdown
ContributorAuthor

Follow-up on exact head b852fb87b: GitHub has not created any check suite after the recorded synchronize event. I verified the PR is open and mergeable and the repository workflows are active. A close/reopen recovery on #3819 also created no run, while direct workflow dispatch from this fork contributor is rejected with HTTP 403 (admin rights required). Maintainer action is needed to approve or trigger the GitHub-hosted workflows for this exact head; the exact-head local validation reported above remains green.

@github-actionsgithub-actionsBot added the effort/XL Over 1000 readable lines label Aug 27, 2026

@Astro-HanAstro-Han left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks for extending workspace Markdown references through the existing Workbar and Markdown seams. I reviewed exact head b852fb87ba8959c73f4ca6317952767dba365be4.

The capability is useful, but the file-authorization boundary and raw-Markdown preprocessing need revision before it is safe to merge. I found one P1 and three P2 issues inline:

  • a checked path string is reused after the filesystem authorization check, leaving a symlink-replacement window for out-of-workspace reads;
  • the Markdown extension allowlist is checked before canonicalization and can be bypassed by an in-workspace .md alias;
  • the line-oriented preprocessor rewrites valid Markdown code/external/path forms incorrectly;
  • the barrel re-export restores a measured eager-renderer chunk regression that current main deliberately removed.

The latest exact-head test, package, windows_recovery, and audit runs have successful results. The PR is currently conflicting with main; please preserve the current lazy Workbar boundary when rebasing and rerun checks on the resolved head.

Because this also changes a user-facing preview surface, human UI/UX acceptance remains required before approval.

Review analysis was assisted by Codex and independent @reviewer agents. Astro-Han verified the exact-head diff, path trust boundary, Markdown production behavior, current-main chunk composition, reachability, and severity before publication and owns this review.

中文对照

谢谢你沿用现有 Workbar 和 Markdown seam 增加 workspace Markdown references。我复核了精确 head b852fb87ba8959c73f4ca6317952767dba365be4

当前有一个 P1 和三个 P2:文件授权后复用 path string 留下 symlink 替换窗口;扩展名只在 canonicalize 前检查,可由 workspace 内 .md alias 绕过;逐行 raw Markdown 预处理会错误改写多种合法 Markdown;barrel re-export 重新引入 current main 已明确删除、且有量化证据的 eager chunk 回归。

当前最新几项检查有成功结果,但 PR 与 main 冲突;重基时必须保留当前 lazy Workbar 边界,并在解决后的 exact head 重新跑 CI。该 PR 也改变了用户可见 preview surface,因此 Approve 前仍需人工 UI/UX 验收。

本次审查分析由 Codex 和独立的 @reviewer 子代理协助;Astro-Han 核验了精确 head、path trust boundary、Markdown 生产行为、current-main chunk composition、可达性和问题分级,并对本次 Review 负责。

Comment threadapps/desktop/src/main/runtime-host-workspace-ipc-main.ts Outdated
Comment threadapps/desktop/src/main/workspace-file-guard.ts Outdated
Comment threadpackages/ui/src/workspace-file-href.ts
Comment threadapps/desktop/src/renderer/features/workbar/index.ts Outdated
@1625567290
1625567290force-pushed the feat/desktop-open-workspace-markdown branch 4 times, most recently from f997445 to 2e11bfcCompareAugust 30, 2026 16:14
@1625567290
1625567290force-pushed the feat/desktop-open-workspace-markdown branch from 2e11bfc to 16e8e2aCompareAugust 30, 2026 16:18
@1625567290

Copy link
Copy Markdown
ContributorAuthor

Exact-head follow-up for 16e8e2adf:

All four review findings remain resolved, with zero unresolved review threads. The 33-file PR diff contains no documentation/Markdown files or Java test sources. main has since advanced to 5d519d6f9; GitHub reports this exact head mergeable, and a local merge-tree check finds no textual conflict. Ready for maintainer review and the requested human UI/UX acceptance.

@Astro-HanAstro-Han left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks for the substantial follow-up—the opened-handle preview read, canonical extension check, and restored Workbar lazy boundary close the previous findings well. I found three remaining production seams below. These are suggestions from an outside review, so please do push back where the Markdown or local-workspace threat model is intentionally narrower.

AI-assisted review disclosure: Codex ran independent workspace-security, Markdown, and production/test analysis lanes; Astro-Han is the contributor of record for this review.

input.ipcMain.handle('workspace:openFile', async (_event, sessionId: unknown, relativePath: unknown) => {
const resolved = await resolveSessionWorkspaceFile(input, sessionId, relativePath);
if (!resolved.ok) return resolved;
const error = await input.openPath?.(resolved.path);

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

[P2] (category ②/③ — local replacement/trust-boundary path)

Thanks for binding preview reads to an opened inode. The “Open locally” path still authorizes a pathname and later hands that mutable pathname to the OS opener: after resolveSessionWorkspaceFile() verifies realpath/containment/extension/stat, another local process can replace guide.md with an outside-workspace symlink before openPath() resolves it. That leaves the PR’s Open locally boundary weaker than the fixed preview read. Could this action consume an identity-bound artifact (for example a controlled staged copy from the authorized handle), or be withheld until the platform exposes a non-re-resolving primitive, with a deterministic replacement-race regression? Please push back if local workspace replacement is explicitly outside this action’s supported threat model.

return source
.split('\n')
.map((line) => {
const blockLine = markdownBlockContent(line.endsWith('\r') ? line.slice(0, -1) : line);

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

[P2] (category ① — normal Markdown content)

Thanks for adding the code/link exclusions. The remaining line-oriented preprocessor still changes valid Markdown structures that span lines or containers: a line - ``` inside an already-open top-level fence is treated as that fence’s close, multiline backtick code and multiline link destinations lose their state between lines, and math is linkified before prepareMarkdownMath() (for example \\( \\texttt{docs/guide.md} \\)). In each case literal content is rewritten into [...](...). Rather than adding more line cases, could workspace linking run on parsed text nodes (or share a real block/inline state machine), with regressions for nested-container fences, multiline code/link, and inline/display math? Please feel free to push back if Astryx intentionally excludes any of these CommonMark/math forms.

if (href.length === 0 || href.length > HREF_MAX_LENGTH) return null;
let decoded: string;
try {
decoded = decodeURIComponent(href);

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

[P2] (category ① — normal percent-named workspace paths)

Thanks for keeping URI parsing fail-closed. The renderer already decodes an explicit href in parseWorkspaceFileHref() and sends the decoded filesystem path in WorkspaceFileDest.relativePath, but main calls decodeURIComponent() again. A valid docs/100%25-safe.md href becomes literal docs/100%-safe.md in the renderer and then fails the second decode; docs/100%2525-safe.md can instead open the wrong percent-named file. Structured workspace_file chips also start from a literal path and hit the same decoder. Could the wire contract choose one owner for URI decoding—decode explicit Markdown hrefs once, then have IPC/main validate the literal relative filesystem path—and cover %, %25, and percent-like directory names end to end? Please push back if the IPC contract is intended to carry encoded hrefs rather than paths.

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

Labels

effort/XLOver 1000 readable lines

Projects

None yet

Development

Successfully merging this pull request may close these issues.

feat(desktop): make Markdown file references in sessions openable

2 participants

@1625567290@Astro-Han