You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@maka.apache.org by "1625567290 (via GitHub)" <gi...@apache.org> on 2026/08/25 17:03:58 UTC
[PR] feat(desktop): open workspace Markdown references [maka]
1625567290 opened a new pull request, #3819:
URL: https://github.com/apache/maka/pull/3819
## 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
- [x] Tests cover the change and fail without it
- [x] Lint, format, typecheck and the affected suites pass locally
Does this PR entail a change in behavior?
- [x] Yes — described under Summary above
- [ ] No
--
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.
To unsubscribe, e-mail: commits-unsubscribe@maka.apache.org
For queries about this service, please contact Infrastructure at:
users@infra.apache.org
---------------------------------------------------------------------
To unsubscribe, e-mail: commits-unsubscribe@maka.apache.org
For additional commands, e-mail: commits-help@maka.apache.org
Re: [PR] feat(desktop): open workspace Markdown references [maka]
Posted by "1625567290 (via GitHub)" <gi...@apache.org>.
1625567290 commented on PR #3819:
URL: https://github.com/apache/maka/pull/3819#issuecomment-5428118877
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.
--
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.
To unsubscribe, e-mail: commits-unsubscribe@maka.apache.org
For queries about this service, please contact Infrastructure at:
users@infra.apache.org
---------------------------------------------------------------------
To unsubscribe, e-mail: commits-unsubscribe@maka.apache.org
For additional commands, e-mail: commits-help@maka.apache.org
Re: [PR] feat(desktop): open workspace Markdown references [maka]
Posted by "1625567290 (via GitHub)" <gi...@apache.org>.
1625567290 commented on code in PR #3819:
URL: https://github.com/apache/maka/pull/3819#discussion_r3889806584
##########
apps/desktop/src/main/runtime-host-workspace-ipc-main.ts:
##########
@@ -44,6 +49,90 @@ export function registerRuntimeHostWorkspaceIpc(
if (!cwd) return { ok: false as const, reason: 'workspace_unavailable' as const };
return readGitReview(cwd, request.source, undefined, request.baseBranch);
});
+ handleReconnectableRead(
+ input.ipcMain,
+ 'workspace:readText',
+ async (_event, sessionId: unknown, relativePath: unknown) => {
+ const resolved = await resolveSessionWorkspaceFile(input, sessionId, relativePath);
+ if (!resolved.ok) return resolved;
+ const content = await readBoundedWorkspaceText(resolved.path);
Review Comment:
Fixed in exact head 5199e23df. Workspace reads now open the file first, verify the opened descriptor and canonical containment after open, compare the opened identity to the authorized target, and read through that same handle. A deterministic replacement-race regression verifies that swapping the checked path cannot expose an outside file.
##########
apps/desktop/src/main/workspace-file-guard.ts:
##########
@@ -0,0 +1,83 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+import { realpath, stat } from 'node:fs/promises';
+import { isAbsolute, relative, resolve, sep } from 'node:path';
+
+const RELATIVE_PATH_MAX_LENGTH = 4096;
+
+export type WorkspaceFileFailureReason = 'invalid' | 'missing' | 'not-a-file' | 'not-allowed';
+
+export async function resolveWorkspaceFile(input: {
+ readonly workspaceRoot: string;
+ readonly relativePath: string;
+}): Promise<
+ | { ok: true; path: string; relativePath: string }
+ | { ok: false; reason: WorkspaceFileFailureReason }
+> {
+ const relativePath = parseWorkspaceRelativePath(input.relativePath);
+ if (!relativePath) return { ok: false, reason: 'invalid' };
+ if (!/\.(?:md|markdown|mdx)$/i.test(relativePath)) {
+ return { ok: false, reason: 'not-a-file' };
+ }
+
+ let root: string;
+ let target: string;
+ try {
+ [root, target] = await Promise.all([
+ realpath(input.workspaceRoot),
+ realpath(resolve(input.workspaceRoot, relativePath)),
+ ]);
+ } catch {
+ return { ok: false, reason: 'missing' };
+ }
+ if (!isInsideOrSamePath(root, target) || target === root) {
+ return { ok: false, reason: 'not-allowed' };
+ }
+
+ const targetStat = await stat(target).catch(() => null);
+ if (!targetStat) return { ok: false, reason: 'missing' };
+ if (!targetStat.isFile()) return { ok: false, reason: 'not-a-file' };
+ return { ok: true, path: target, relativePath };
Review Comment:
Fixed in exact head 5199e23df. The Markdown allowlist is now revalidated against the canonical opened target, so a .md alias to a non-Markdown file is rejected. A regression covers that symlink case.
##########
packages/ui/src/workspace-file-href.ts:
##########
@@ -0,0 +1,188 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+const HREF_MAX_LENGTH = 4096;
+const BARE_MARKDOWN_PATH = /(?:\.\/)?(?:[\p{L}\p{N}_@.+-]+\/)*[\p{L}\p{N}_@+-]+(?:\.[\p{L}\p{N}_@+-]+)*\.(?:markdown|mdx|md)/iyu;
+
+export type WorkspaceFileDest = {
+ readonly kind: 'workspace_file';
+ readonly relativePath: string;
+};
+
+/**
+ * Parse a workspace-relative file href from Markdown. Absolute paths, schemes,
+ * traversal, and query/hash fragments stay inert so transcript text cannot
+ * point outside the session workspace.
+ */
+export function parseWorkspaceFileHref(href: string): WorkspaceFileDest | null {
+ if (typeof href !== 'string') return null;
+ if (href.length === 0 || href.length > HREF_MAX_LENGTH) return null;
+ let decoded: string;
+ try {
+ decoded = decodeURIComponent(href);
+ } catch {
+ return null;
+ }
+ if (/[\u0000-\u001f\u007f]/.test(decoded)) return null;
+ if (/^[a-zA-Z][a-zA-Z0-9+.-]*:/.test(decoded)) return null;
+ if (decoded.startsWith('/') || decoded.startsWith('~') || decoded.startsWith('\\')) return null;
+ if (decoded.includes('\\') || decoded.includes('?') || decoded.includes('#')) return null;
+ const trimmed = decoded.replace(/^\.\//, '');
+ const segments = trimmed.split('/');
+ if (segments.length === 0 || segments.some((segment) => segment === '' || segment === '.' || segment === '..')) {
+ return null;
+ }
+ const relativePath = segments.join('/');
+ if (!isMarkdownWorkspaceFile(relativePath)) return null;
+ return { kind: 'workspace_file', relativePath };
+}
+
+export function isMarkdownWorkspaceFile(relativePath: string): boolean {
+ return /\.(?:md|markdown|mdx)$/i.test(relativePath);
+}
+
+/**
+ * Make unambiguous bare Markdown paths clickable without rewriting code,
+ * existing links, autolinks, or reference definitions. Paths containing
+ * spaces remain supported through ordinary Markdown link destinations.
+ */
+export function linkifyBareWorkspaceMarkdownReferences(source: string): string {
+ let fence: { character: string; length: number } | null = null;
+ return source
+ .split('\n')
+ .map((line) => {
+ if (fence) {
+ const closing = new RegExp(
+ `^ {0,3}${escapeRegExp(fence.character)}{${fence.length},}[ \\t]*$`,
+ );
+ if (closing.test(line)) fence = null;
+ return line;
+ }
+
+ const opening = /^ {0,3}(`{3,}|~{3,})/.exec(line);
+ if (opening?.[1]) {
+ fence = { character: opening[1][0]!, length: opening[1].length };
+ return line;
+ }
+ if (/^ {0,3}\[[^\]]+\]:/.test(line)) return line;
+ return linkifyBareWorkspacePathsInLine(line);
Review Comment:
Fixed in exact head 5199e23df. Local-reference linking now tracks Markdown line structure and fence state, preserves CRLF behavior, ignores indented code and blockquote or list-nested fences, rejects suffixes such as .md.txt, and leaves www URLs to normal autolinking. Regressions cover all four reported forms.
##########
apps/desktop/src/renderer/features/workbar/index.ts:
##########
@@ -18,7 +18,7 @@
*/
export { WorkbarHost } from './ui/workbar-host';
-export { WorkbarSurface } from './ui/workbar-surface';
+export { WorkbarSurface, WorkspaceFilePreviewContext } from './ui/workbar-surface';
Review Comment:
Fixed in exact head 5199e23df. WorkspaceFilePreviewContext lives in a lightweight direct module and is not re-exported through the Workbar surface barrel. The renderer build keeps workbar-surface as a separate approximately 82.35 kB chunk, and the AppShell hook budget remains within its enforced limit.
--
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.
To unsubscribe, e-mail: commits-unsubscribe@maka.apache.org
For queries about this service, please contact Infrastructure at:
users@infra.apache.org
---------------------------------------------------------------------
To unsubscribe, e-mail: commits-unsubscribe@maka.apache.org
For additional commands, e-mail: commits-help@maka.apache.org
Re: [PR] feat(desktop): open workspace Markdown references [maka]
Posted by "1625567290 (via GitHub)" <gi...@apache.org>.
1625567290 commented on PR #3819:
URL: https://github.com/apache/maka/pull/3819#issuecomment-5428023301
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.
--
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.
To unsubscribe, e-mail: commits-unsubscribe@maka.apache.org
For queries about this service, please contact Infrastructure at:
users@infra.apache.org
---------------------------------------------------------------------
To unsubscribe, e-mail: commits-unsubscribe@maka.apache.org
For additional commands, e-mail: commits-help@maka.apache.org
Re: [PR] feat(desktop): open workspace Markdown references [maka]
Posted by "github-actions[bot] (via GitHub)" <gi...@apache.org>.
github-actions[bot] commented on PR #3819:
URL: https://github.com/apache/maka/pull/3819#issuecomment-5903690647
<!-- maka-lifecycle:stale-warning -->
This pull request has had no new commits for 30 days and has been marked stale. It will be closed in 7 days unless a new commit is pushed.
Comments do not reset this timer: only a new commit does. If the pull request is intentionally long-lived, a maintainer can apply the `pinned` label.
--
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.
To unsubscribe, e-mail: commits-unsubscribe@maka.apache.org
For queries about this service, please contact Infrastructure at:
users@infra.apache.org
---------------------------------------------------------------------
To unsubscribe, e-mail: commits-unsubscribe@maka.apache.org
For additional commands, e-mail: commits-help@maka.apache.org
Re: [PR] feat(desktop): open workspace Markdown references [maka]
Posted by "github-actions[bot] (via GitHub)" <gi...@apache.org>.
github-actions[bot] closed pull request #3819: feat(desktop): open workspace Markdown references
URL: https://github.com/apache/maka/pull/3819
--
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.
To unsubscribe, e-mail: commits-unsubscribe@maka.apache.org
For queries about this service, please contact Infrastructure at:
users@infra.apache.org
---------------------------------------------------------------------
To unsubscribe, e-mail: commits-unsubscribe@maka.apache.org
For additional commands, e-mail: commits-help@maka.apache.org
Re: [PR] feat(desktop): open workspace Markdown references [maka]
Posted by "1625567290 (via GitHub)" <gi...@apache.org>.
1625567290 commented on PR #3819:
URL: https://github.com/apache/maka/pull/3819#issuecomment-5424275382
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:
- current `main` run: https://github.com/apache/maka/actions/runs/32955378922
- unrelated PR run: https://github.com/apache/maka/actions/runs/32955721105
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.
--
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.
To unsubscribe, e-mail: commits-unsubscribe@maka.apache.org
For queries about this service, please contact Infrastructure at:
users@infra.apache.org
---------------------------------------------------------------------
To unsubscribe, e-mail: commits-unsubscribe@maka.apache.org
For additional commands, e-mail: commits-help@maka.apache.org
Re: [PR] feat(desktop): open workspace Markdown references [maka]
Posted by "1625567290 (via GitHub)" <gi...@apache.org>.
1625567290 commented on PR #3819:
URL: https://github.com/apache/maka/pull/3819#issuecomment-5469972648
Exact-head follow-up for `16e8e2adf`:
- CI `test` succeeded, including renderer architecture, the full Desktop E2E collection, alignment audit, Storybook smoke, and installed CLI release-candidate validation: https://github.com/apache/maka/actions/runs/33322099878
- Windows `package` succeeded, including pinned-version upgrade/uninstall, automatic update, and deterministic rollback: https://github.com/apache/maka/actions/runs/33322099870
- Dependency audit and Windows recovery also succeeded: https://github.com/apache/maka/actions/runs/33322099916 and https://github.com/apache/maka/actions/runs/33322100014
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.
--
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.
To unsubscribe, e-mail: commits-unsubscribe@maka.apache.org
For queries about this service, please contact Infrastructure at:
users@infra.apache.org
---------------------------------------------------------------------
To unsubscribe, e-mail: commits-unsubscribe@maka.apache.org
For additional commands, e-mail: commits-help@maka.apache.org
Re: [PR] feat(desktop): open workspace Markdown references [maka]
Posted by "github-actions[bot] (via GitHub)" <gi...@apache.org>.
github-actions[bot] commented on PR #3819:
URL: https://github.com/apache/maka/pull/3819#issuecomment-6030561875
<!-- maka-lifecycle:stale-close -->
This pull request has been closed because it received no new commits during the 7-day grace period. This is not a judgement on the merit of the change; it only keeps the review queue aligned with work that is actively in flight.
The branch and review history are preserved. Push a new commit and reopen the pull request whenever the work is ready to continue.
--
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.
To unsubscribe, e-mail: commits-unsubscribe@maka.apache.org
For queries about this service, please contact Infrastructure at:
users@infra.apache.org
---------------------------------------------------------------------
To unsubscribe, e-mail: commits-unsubscribe@maka.apache.org
For additional commands, e-mail: commits-help@maka.apache.org
Re: [PR] feat(desktop): open workspace Markdown references [maka]
Posted by "1625567290 (via GitHub)" <gi...@apache.org>.
1625567290 commented on PR #3819:
URL: https://github.com/apache/maka/pull/3819#issuecomment-5424767242
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:
- CI: success (17m36s) — https://github.com/apache/maka/actions/runs/32963073451
- Dependency audit: success — https://github.com/apache/maka/actions/runs/32963073519
- Release Windows check: success (18m04s) — https://github.com/apache/maka/actions/runs/32963073652
- Windows recovery: success — https://github.com/apache/maka/actions/runs/32963073469
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.
--
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.
To unsubscribe, e-mail: commits-unsubscribe@maka.apache.org
For queries about this service, please contact Infrastructure at:
users@infra.apache.org
---------------------------------------------------------------------
To unsubscribe, e-mail: commits-unsubscribe@maka.apache.org
For additional commands, e-mail: commits-help@maka.apache.org
Re: [PR] feat(desktop): open workspace Markdown references [maka]
Posted by "1625567290 (via GitHub)" <gi...@apache.org>.
1625567290 commented on code in PR #3819:
URL: https://github.com/apache/maka/pull/3819#discussion_r3889880661
##########
apps/desktop/src/renderer/features/workbar/index.ts:
##########
@@ -18,7 +18,7 @@
*/
export { WorkbarHost } from './ui/workbar-host';
-export { WorkbarSurface } from './ui/workbar-surface';
+export { WorkbarSurface, WorkspaceFilePreviewContext } from './ui/workbar-surface';
Review Comment:
Follow-up in exact head 16e8e2adf after rebasing onto current main 5058b29f1. The first refreshed CI exposed the renderer architecture and Astryx inventory gates. Preview state and workspace bridge ownership now live entirely in the existing Workbar controller, service port, and lazy Workbar surface; the cross-boundary context and the additional surface file are gone. The renderer architecture suite passes 62/62, the Astryx inventory is current at 229 files with its 15 generator tests green, and the Workbar remains a separate 83.97 kB lazy chunk.
--
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.
To unsubscribe, e-mail: commits-unsubscribe@maka.apache.org
For queries about this service, please contact Infrastructure at:
users@infra.apache.org
---------------------------------------------------------------------
To unsubscribe, e-mail: commits-unsubscribe@maka.apache.org
For additional commands, e-mail: commits-help@maka.apache.org
Re: [PR] feat(desktop): open workspace Markdown references [maka]
Posted by "Astro-Han (via GitHub)" <gi...@apache.org>.
Astro-Han commented on code in PR #3819:
URL: https://github.com/apache/maka/pull/3819#discussion_r3890187381
##########
packages/ui/src/workspace-file-href.ts:
##########
@@ -0,0 +1,209 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+const HREF_MAX_LENGTH = 4096;
+const BARE_MARKDOWN_PATH = /(?:\.\/)?(?:[\p{L}\p{N}_@.+-]+\/)*[\p{L}\p{N}_@+-]+(?:\.[\p{L}\p{N}_@+-]+)*\.(?:markdown|mdx|md)/iyu;
+
+export type WorkspaceFileDest = {
+ readonly kind: 'workspace_file';
+ readonly relativePath: string;
+};
+
+/**
+ * Parse a workspace-relative file href from Markdown. Absolute paths, schemes,
+ * traversal, and query/hash fragments stay inert so transcript text cannot
+ * point outside the session workspace.
+ */
+export function parseWorkspaceFileHref(href: string): WorkspaceFileDest | null {
+ if (typeof href !== 'string') return null;
+ if (href.length === 0 || href.length > HREF_MAX_LENGTH) return null;
+ let decoded: string;
+ try {
+ decoded = decodeURIComponent(href);
+ } catch {
+ return null;
+ }
+ if (/[\u0000-\u001f\u007f]/.test(decoded)) return null;
+ if (/^[a-zA-Z][a-zA-Z0-9+.-]*:/.test(decoded)) return null;
+ if (decoded.startsWith('/') || decoded.startsWith('~') || decoded.startsWith('\\')) return null;
+ if (decoded.includes('\\') || decoded.includes('?') || decoded.includes('#')) return null;
+ const trimmed = decoded.replace(/^\.\//, '');
+ const segments = trimmed.split('/');
+ if (segments.length === 0 || segments.some((segment) => segment === '' || segment === '.' || segment === '..')) {
+ return null;
+ }
+ const relativePath = segments.join('/');
+ if (!isMarkdownWorkspaceFile(relativePath)) return null;
+ return { kind: 'workspace_file', relativePath };
+}
+
+export function isMarkdownWorkspaceFile(relativePath: string): boolean {
+ return /\.(?:md|markdown|mdx)$/i.test(relativePath);
+}
+
+/**
+ * Make unambiguous bare Markdown paths clickable without rewriting code,
+ * existing links, autolinks, or reference definitions. Paths containing
+ * spaces remain supported through ordinary Markdown link destinations.
+ */
+export function linkifyBareWorkspaceMarkdownReferences(source: string): string {
+ let fence: { character: string; length: number } | null = null;
+ return source
+ .split('\n')
+ .map((line) => {
+ const blockLine = markdownBlockContent(line.endsWith('\r') ? line.slice(0, -1) : line);
Review Comment:
[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.
##########
apps/desktop/src/main/runtime-host-workspace-ipc-main.ts:
##########
@@ -44,6 +53,122 @@ export function registerRuntimeHostWorkspaceIpc(
if (!cwd) return { ok: false as const, reason: 'workspace_unavailable' as const };
return readGitReview(cwd, request.source, undefined, request.baseBranch);
});
+ handleReconnectableRead(
+ input.ipcMain,
+ 'workspace:readText',
+ async (_event, sessionId: unknown, relativePath: unknown) => {
+ if (input.allowLocalWorkspace === false) {
+ return { ok: false as const, reason: 'not-allowed' as const };
+ }
+ if (typeof sessionId !== 'string' || sessionId.length === 0) {
+ return { ok: false as const, reason: 'invalid' as const };
+ }
+ if (typeof relativePath !== 'string') {
+ return { ok: false as const, reason: 'invalid' as const };
+ }
+ const cwd = await sessionWorkspace(input.client, sessionId);
+ if (!cwd) return { ok: false as const, reason: 'missing' as const };
+ return readBoundedWorkspaceText({ workspaceRoot: cwd, relativePath });
+ },
+ );
+
+ 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);
Review Comment:
[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.
##########
packages/ui/src/workspace-file-href.ts:
##########
@@ -0,0 +1,209 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+const HREF_MAX_LENGTH = 4096;
+const BARE_MARKDOWN_PATH = /(?:\.\/)?(?:[\p{L}\p{N}_@.+-]+\/)*[\p{L}\p{N}_@+-]+(?:\.[\p{L}\p{N}_@+-]+)*\.(?:markdown|mdx|md)/iyu;
+
+export type WorkspaceFileDest = {
+ readonly kind: 'workspace_file';
+ readonly relativePath: string;
+};
+
+/**
+ * Parse a workspace-relative file href from Markdown. Absolute paths, schemes,
+ * traversal, and query/hash fragments stay inert so transcript text cannot
+ * point outside the session workspace.
+ */
+export function parseWorkspaceFileHref(href: string): WorkspaceFileDest | null {
+ if (typeof href !== 'string') return null;
+ if (href.length === 0 || href.length > HREF_MAX_LENGTH) return null;
+ let decoded: string;
+ try {
+ decoded = decodeURIComponent(href);
Review Comment:
[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.
--
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.
To unsubscribe, e-mail: commits-unsubscribe@maka.apache.org
For queries about this service, please contact Infrastructure at:
users@infra.apache.org
---------------------------------------------------------------------
To unsubscribe, e-mail: commits-unsubscribe@maka.apache.org
For additional commands, e-mail: commits-help@maka.apache.org
Re: [PR] feat(desktop): open workspace Markdown references [maka]
Posted by "1625567290 (via GitHub)" <gi...@apache.org>.
1625567290 commented on PR #3819:
URL: https://github.com/apache/maka/pull/3819#issuecomment-5423551989
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:
- CI `test`: success (16m48s) — https://github.com/apache/maka/actions/runs/32950499012
- dependency `audit`: success (47s) — https://github.com/apache/maka/actions/runs/32950498970
- Windows `package`: success (16m38s) — https://github.com/apache/maka/actions/runs/32950498893
- `windows_recovery`: success (3m10s) — https://github.com/apache/maka/actions/runs/32950498878
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.
--
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.
To unsubscribe, e-mail: commits-unsubscribe@maka.apache.org
For queries about this service, please contact Infrastructure at:
users@infra.apache.org
---------------------------------------------------------------------
To unsubscribe, e-mail: commits-unsubscribe@maka.apache.org
For additional commands, e-mail: commits-help@maka.apache.org
Re: [PR] feat(desktop): open workspace Markdown references [maka]
Posted by "1625567290 (via GitHub)" <gi...@apache.org>.
1625567290 commented on PR #3819:
URL: https://github.com/apache/maka/pull/3819#issuecomment-5420620372
Rebased onto current main 51eeaa60b and Astryx core 0.5.0; the exact head is 7c25d6fc0.
All hosted checks are terminal and successful:
- CI: https://github.com/apache/maka/actions/runs/32927630963
- Dependency audit: https://github.com/apache/maka/actions/runs/32927631179
- Release Windows: https://github.com/apache/maka/actions/runs/32927630957
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.
--
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.
To unsubscribe, e-mail: commits-unsubscribe@maka.apache.org
For queries about this service, please contact Infrastructure at:
users@infra.apache.org
---------------------------------------------------------------------
To unsubscribe, e-mail: commits-unsubscribe@maka.apache.org
For additional commands, e-mail: commits-help@maka.apache.org
Re: [PR] feat(desktop): open workspace Markdown references [maka]
Posted by "1625567290 (via GitHub)" <gi...@apache.org>.
1625567290 closed pull request #3819: feat(desktop): open workspace Markdown references
URL: https://github.com/apache/maka/pull/3819
--
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.
To unsubscribe, e-mail: commits-unsubscribe@maka.apache.org
For queries about this service, please contact Infrastructure at:
users@infra.apache.org
---------------------------------------------------------------------
To unsubscribe, e-mail: commits-unsubscribe@maka.apache.org
For additional commands, e-mail: commits-help@maka.apache.org
Re: [PR] feat(desktop): open workspace Markdown references [maka]
Posted by "Astro-Han (via GitHub)" <gi...@apache.org>.
Astro-Han commented on code in PR #3819:
URL: https://github.com/apache/maka/pull/3819#discussion_r3889522161
##########
packages/ui/src/workspace-file-href.ts:
##########
@@ -0,0 +1,188 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+const HREF_MAX_LENGTH = 4096;
+const BARE_MARKDOWN_PATH = /(?:\.\/)?(?:[\p{L}\p{N}_@.+-]+\/)*[\p{L}\p{N}_@+-]+(?:\.[\p{L}\p{N}_@+-]+)*\.(?:markdown|mdx|md)/iyu;
+
+export type WorkspaceFileDest = {
+ readonly kind: 'workspace_file';
+ readonly relativePath: string;
+};
+
+/**
+ * Parse a workspace-relative file href from Markdown. Absolute paths, schemes,
+ * traversal, and query/hash fragments stay inert so transcript text cannot
+ * point outside the session workspace.
+ */
+export function parseWorkspaceFileHref(href: string): WorkspaceFileDest | null {
+ if (typeof href !== 'string') return null;
+ if (href.length === 0 || href.length > HREF_MAX_LENGTH) return null;
+ let decoded: string;
+ try {
+ decoded = decodeURIComponent(href);
+ } catch {
+ return null;
+ }
+ if (/[\u0000-\u001f\u007f]/.test(decoded)) return null;
+ if (/^[a-zA-Z][a-zA-Z0-9+.-]*:/.test(decoded)) return null;
+ if (decoded.startsWith('/') || decoded.startsWith('~') || decoded.startsWith('\\')) return null;
+ if (decoded.includes('\\') || decoded.includes('?') || decoded.includes('#')) return null;
+ const trimmed = decoded.replace(/^\.\//, '');
+ const segments = trimmed.split('/');
+ if (segments.length === 0 || segments.some((segment) => segment === '' || segment === '.' || segment === '..')) {
+ return null;
+ }
+ const relativePath = segments.join('/');
+ if (!isMarkdownWorkspaceFile(relativePath)) return null;
+ return { kind: 'workspace_file', relativePath };
+}
+
+export function isMarkdownWorkspaceFile(relativePath: string): boolean {
+ return /\.(?:md|markdown|mdx)$/i.test(relativePath);
+}
+
+/**
+ * Make unambiguous bare Markdown paths clickable without rewriting code,
+ * existing links, autolinks, or reference definitions. Paths containing
+ * spaces remain supported through ordinary Markdown link destinations.
+ */
+export function linkifyBareWorkspaceMarkdownReferences(source: string): string {
+ let fence: { character: string; length: number } | null = null;
+ return source
+ .split('\n')
+ .map((line) => {
+ if (fence) {
+ const closing = new RegExp(
+ `^ {0,3}${escapeRegExp(fence.character)}{${fence.length},}[ \\t]*$`,
+ );
+ if (closing.test(line)) fence = null;
+ return line;
+ }
+
+ const opening = /^ {0,3}(`{3,}|~{3,})/.exec(line);
+ if (opening?.[1]) {
+ fence = { character: opening[1][0]!, length: opening[1].length };
+ return line;
+ }
+ if (/^ {0,3}\[[^\]]+\]:/.test(line)) return line;
+ return linkifyBareWorkspacePathsInLine(line);
Review Comment:
[P2 · category ①] This raw line preprocessor is not preserving Markdown semantics. It rewrites 4-space/tab indented code and paths inside blockquote/list-nested fences; a CRLF closing fence retains `\r` and never clears `fence`; `docs/guide.md.txt` is truncated into a link to `docs/guide.md` because `.` is accepted as an end boundary; and GFM `www.example.com/docs/guide.md` is converted to a local workspace link before Astryx can autolink it as HTTP. These are normal transcript forms and lead to altered code text, missing links, or opening the wrong target. Please move this decision to Markdown token/block structure (or otherwise cover the full block and URL boundaries) and add regressions for all four forms rather than extending one regex case at a time.
##########
apps/desktop/src/main/workspace-file-guard.ts:
##########
@@ -0,0 +1,83 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+import { realpath, stat } from 'node:fs/promises';
+import { isAbsolute, relative, resolve, sep } from 'node:path';
+
+const RELATIVE_PATH_MAX_LENGTH = 4096;
+
+export type WorkspaceFileFailureReason = 'invalid' | 'missing' | 'not-a-file' | 'not-allowed';
+
+export async function resolveWorkspaceFile(input: {
+ readonly workspaceRoot: string;
+ readonly relativePath: string;
+}): Promise<
+ | { ok: true; path: string; relativePath: string }
+ | { ok: false; reason: WorkspaceFileFailureReason }
+> {
+ const relativePath = parseWorkspaceRelativePath(input.relativePath);
+ if (!relativePath) return { ok: false, reason: 'invalid' };
+ if (!/\.(?:md|markdown|mdx)$/i.test(relativePath)) {
+ return { ok: false, reason: 'not-a-file' };
+ }
+
+ let root: string;
+ let target: string;
+ try {
+ [root, target] = await Promise.all([
+ realpath(input.workspaceRoot),
+ realpath(resolve(input.workspaceRoot, relativePath)),
+ ]);
+ } catch {
+ return { ok: false, reason: 'missing' };
+ }
+ if (!isInsideOrSamePath(root, target) || target === root) {
+ return { ok: false, reason: 'not-allowed' };
+ }
+
+ const targetStat = await stat(target).catch(() => null);
+ if (!targetStat) return { ok: false, reason: 'missing' };
+ if (!targetStat.isFile()) return { ok: false, reason: 'not-a-file' };
+ return { ok: true, path: target, relativePath };
Review Comment:
[P2 · category ③] The Markdown extension allowlist is checked only on the lexical input before `realpath()`. A stable in-workspace alias such as `public.md -> .env` therefore passes containment and `isFile()`, then is read/opened even though the canonical target is not Markdown. Please revalidate the canonical target type or reject aliases for this capability, and cover a `.md` symlink to a non-Markdown file.
##########
apps/desktop/src/renderer/features/workbar/index.ts:
##########
@@ -18,7 +18,7 @@
*/
export { WorkbarHost } from './ui/workbar-host';
-export { WorkbarSurface } from './ui/workbar-surface';
+export { WorkbarSurface, WorkspaceFilePreviewContext } from './ui/workbar-surface';
Review Comment:
[P2 · category ①] Re-exporting `WorkbarSurface` here reintroduces the eager dependency edge that current `main` deliberately removed in #4101. That change fixed `INEFFECTIVE_DYNAMIC_IMPORT` and measured the renderer entry dropping by about 79 kB while `WorkbarSurface` became its own 81.31 kB chunk. This PR only needs `WorkspaceFilePreviewContext`, but exporting both from the surface module pulls the surface and its five panels back into normal first load. Please move the context to a lightweight module and keep `WorkbarSurface` reachable only through the existing lazy import when rebasing.
##########
apps/desktop/src/main/runtime-host-workspace-ipc-main.ts:
##########
@@ -44,6 +49,90 @@ export function registerRuntimeHostWorkspaceIpc(
if (!cwd) return { ok: false as const, reason: 'workspace_unavailable' as const };
return readGitReview(cwd, request.source, undefined, request.baseBranch);
});
+ handleReconnectableRead(
+ input.ipcMain,
+ 'workspace:readText',
+ async (_event, sessionId: unknown, relativePath: unknown) => {
+ const resolved = await resolveSessionWorkspaceFile(input, sessionId, relativePath);
+ if (!resolved.ok) return resolved;
+ const content = await readBoundedWorkspaceText(resolved.path);
Review Comment:
[P1 · category ②/③] `resolveWorkspaceFile()` authorizes a path with `realpath()` and `stat()`, but this later `readFile` reopens the returned string. A concurrent process can rename the checked file and replace that same path with an out-of-workspace symlink between those operations, so clicking an otherwise valid Markdown reference can read an arbitrary local file. The repository already has the required shape in `readBoundedSourceFile()`: open a handle, verify the opened inode/containment, and read through that handle. Please make the opened file descriptor, not a previously checked path string, the read authorization boundary and add a deterministic replacement-race test.
--
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.
To unsubscribe, e-mail: commits-unsubscribe@maka.apache.org
For queries about this service, please contact Infrastructure at:
users@infra.apache.org
---------------------------------------------------------------------
To unsubscribe, e-mail: commits-unsubscribe@maka.apache.org
For additional commands, e-mail: commits-help@maka.apache.org