feat(settings): rename and reveal a project from its row menu - #2447

Merged
jackwener merged 1 commit into
mainfrom
feat/project-row-actions
Aug 7, 2026
Merged

feat(settings): rename and reveal a project from its row menu#2447
jackwener merged 1 commit into
mainfrom
feat/project-row-actions

Conversation

@jackwener

Copy link
Copy Markdown
Member

改了什么

补齐 #160 降级掉的两项,项目页从「只能选默认」变成「能管理项目」。task #161

在访达中打开:传 id,不传路径

渲染层传 projectId,主进程向 catalog 问这个项目在哪,再交给已有的 project open-path 守卫复核解析后的目录。渲染层没有机会指定任意目录让 shell 打开 —— 这比把 app:openPath 放开成「接受任意路径」安全,也不需要新的守卫逻辑。

只在 catalog 仍然认可该目录时才可点:一个必然失败的菜单项,比没有这个菜单项更糟。

重命名:复用既有原语,不是新造

SettingsExpandableRow本来就存在(外观页的显示名称在用),它已经封好了「打开时聚焦第一个控件、关闭时把焦点还给行」以及「为什么故意不挂 aria-expanded」这些判断。手写第二套编辑器等于把这些判断重做一遍还容易漏。

给它加了一个 end prop:本来就自带尾部控件簇的行(默认 Badge / 设为默认 / … 菜单)保留自己的簇,而不是再长出一个和它们抢位置的「更改」按钮。重命名从 … 菜单进。既有调用方不传 end,行为不变。

顺带修一个真问题

每行的 … 菜单现在带上项目名(更多操作:astryx-design-system)。四个都叫「更多操作」的按钮,对辅助技术来说等于同一个按钮;它们对测试也同样有歧义——我第一版 e2e 按下标定位,结果重命名了错误的那一行(app 会自注册一个工作区项目,导致渲染顺序和 fixture 种子顺序不一致)。是截图暴露的,不是断言。

怎么验证的

  • e2e 从 1 个扩到 3 个:重命名(含焦点断言 + catalog 真的改了,不只是行变了)、不可用项目的「在访达中打开」为禁用、reveal 对目录不存在的项目返回 ok:false
  • typecheck / lint / format / build / knip 全绿;desktop 1751 passed / 0 failed
  • 测试按名字定位行,不按下标——这次翻车的直接原因。

Completes the two actions #160 deferred, so the Projects page manages a
project rather than only choosing a default.
Reveal takes a project id, never a path. Main asks the catalog where that
project lives and the existing `project` open-path guard re-checks the
resolved directory, so the renderer cannot name an arbitrary folder for the
shell to open. It is offered only while the catalog still vouches for the
folder — a menu entry that could only fail is worse than one that is absent.
Rename reuses `SettingsExpandableRow` rather than hand-rolling a second
editor; it already owns the focus move into the field and back to the row,
and the reasoning about why it carries no aria-expanded. It gained an `end`
prop so a row that already owns its end slot — a default Badge, 设为默认, and
the … menu — keeps that cluster instead of growing a second competing button.
Rename is reached from the menu.
Each row's … menu is now named after its project. Four buttons all called
更多操作 are one button to assistive tech; they were equally ambiguous to a
test, which addressed a row by index and renamed the wrong project.
@jackwener

Copy link
Copy Markdown
MemberAuthor

Review by maka-审美专家 — 通过#160 批准降级的两项回补——重命名复用 SettingsExpandableRow kit 组件(#141 的资产第一次被二次消费,'仓库里没有 inline-edit 原语'被自己的 kit 证伪),访达打开经 resolveOpenPath 校验后扩任意项目路径(ok/reason 失败语义清晰)。CI 全绿零失败。合入。注意:项目页实体列表改版(已定案)将在本 PR 之上进行。

@jackwener
jackwener merged commit 2953869 into mainAug 7, 2026
12 checks passed
Sign up for freeto join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant

@jackwener
, '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(settings): rename and reveal a project from its row menu - #2447

Merged
jackwener merged 1 commit into
mainfrom
feat/project-row-actions
Aug 7, 2026
Merged

feat(settings): rename and reveal a project from its row menu#2447
jackwener merged 1 commit into
mainfrom
feat/project-row-actions

Conversation

@jackwener

Copy link
Copy Markdown
Member

改了什么

补齐 #160 降级掉的两项,项目页从「只能选默认」变成「能管理项目」。task #161

在访达中打开:传 id,不传路径

渲染层传 projectId,主进程向 catalog 问这个项目在哪,再交给已有的 project open-path 守卫复核解析后的目录。渲染层没有机会指定任意目录让 shell 打开 —— 这比把 app:openPath 放开成「接受任意路径」安全,也不需要新的守卫逻辑。

只在 catalog 仍然认可该目录时才可点:一个必然失败的菜单项,比没有这个菜单项更糟。

重命名:复用既有原语,不是新造

SettingsExpandableRow本来就存在(外观页的显示名称在用),它已经封好了「打开时聚焦第一个控件、关闭时把焦点还给行」以及「为什么故意不挂 aria-expanded」这些判断。手写第二套编辑器等于把这些判断重做一遍还容易漏。

给它加了一个 end prop:本来就自带尾部控件簇的行(默认 Badge / 设为默认 / … 菜单)保留自己的簇,而不是再长出一个和它们抢位置的「更改」按钮。重命名从 … 菜单进。既有调用方不传 end,行为不变。

顺带修一个真问题

每行的 … 菜单现在带上项目名(更多操作:astryx-design-system)。四个都叫「更多操作」的按钮,对辅助技术来说等于同一个按钮;它们对测试也同样有歧义——我第一版 e2e 按下标定位,结果重命名了错误的那一行(app 会自注册一个工作区项目,导致渲染顺序和 fixture 种子顺序不一致)。是截图暴露的,不是断言。

怎么验证的

  • e2e 从 1 个扩到 3 个:重命名(含焦点断言 + catalog 真的改了,不只是行变了)、不可用项目的「在访达中打开」为禁用、reveal 对目录不存在的项目返回 ok:false
  • typecheck / lint / format / build / knip 全绿;desktop 1751 passed / 0 failed
  • 测试按名字定位行,不按下标——这次翻车的直接原因。

Completes the two actions #160 deferred, so the Projects page manages a
project rather than only choosing a default.
Reveal takes a project id, never a path. Main asks the catalog where that
project lives and the existing `project` open-path guard re-checks the
resolved directory, so the renderer cannot name an arbitrary folder for the
shell to open. It is offered only while the catalog still vouches for the
folder — a menu entry that could only fail is worse than one that is absent.
Rename reuses `SettingsExpandableRow` rather than hand-rolling a second
editor; it already owns the focus move into the field and back to the row,
and the reasoning about why it carries no aria-expanded. It gained an `end`
prop so a row that already owns its end slot — a default Badge, 设为默认, and
the … menu — keeps that cluster instead of growing a second competing button.
Rename is reached from the menu.
Each row's … menu is now named after its project. Four buttons all called
更多操作 are one button to assistive tech; they were equally ambiguous to a
test, which addressed a row by index and renamed the wrong project.
@jackwener

Copy link
Copy Markdown
MemberAuthor

Review by maka-审美专家 — 通过#160 批准降级的两项回补——重命名复用 SettingsExpandableRow kit 组件(#141 的资产第一次被二次消费,'仓库里没有 inline-edit 原语'被自己的 kit 证伪),访达打开经 resolveOpenPath 校验后扩任意项目路径(ok/reason 失败语义清晰)。CI 全绿零失败。合入。注意:项目页实体列表改版(已定案)将在本 PR 之上进行。

@jackwener
jackwener merged commit 2953869 into mainAug 7, 2026
12 checks passed
Sign up for freeto join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant

@jackwener
, '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(settings): rename and reveal a project from its row menu - #2447

Merged
jackwener merged 1 commit into
mainfrom
feat/project-row-actions
Aug 7, 2026
Merged

feat(settings): rename and reveal a project from its row menu#2447
jackwener merged 1 commit into
mainfrom
feat/project-row-actions

Conversation

@jackwener

Copy link
Copy Markdown
Member

改了什么

补齐 #160 降级掉的两项,项目页从「只能选默认」变成「能管理项目」。task #161

在访达中打开:传 id,不传路径

渲染层传 projectId,主进程向 catalog 问这个项目在哪,再交给已有的 project open-path 守卫复核解析后的目录。渲染层没有机会指定任意目录让 shell 打开 —— 这比把 app:openPath 放开成「接受任意路径」安全,也不需要新的守卫逻辑。

只在 catalog 仍然认可该目录时才可点:一个必然失败的菜单项,比没有这个菜单项更糟。

重命名:复用既有原语,不是新造

SettingsExpandableRow本来就存在(外观页的显示名称在用),它已经封好了「打开时聚焦第一个控件、关闭时把焦点还给行」以及「为什么故意不挂 aria-expanded」这些判断。手写第二套编辑器等于把这些判断重做一遍还容易漏。

给它加了一个 end prop:本来就自带尾部控件簇的行(默认 Badge / 设为默认 / … 菜单)保留自己的簇,而不是再长出一个和它们抢位置的「更改」按钮。重命名从 … 菜单进。既有调用方不传 end,行为不变。

顺带修一个真问题

每行的 … 菜单现在带上项目名(更多操作:astryx-design-system)。四个都叫「更多操作」的按钮,对辅助技术来说等于同一个按钮;它们对测试也同样有歧义——我第一版 e2e 按下标定位,结果重命名了错误的那一行(app 会自注册一个工作区项目,导致渲染顺序和 fixture 种子顺序不一致)。是截图暴露的,不是断言。

怎么验证的

  • e2e 从 1 个扩到 3 个:重命名(含焦点断言 + catalog 真的改了,不只是行变了)、不可用项目的「在访达中打开」为禁用、reveal 对目录不存在的项目返回 ok:false
  • typecheck / lint / format / build / knip 全绿;desktop 1751 passed / 0 failed
  • 测试按名字定位行,不按下标——这次翻车的直接原因。

Completes the two actions #160 deferred, so the Projects page manages a
project rather than only choosing a default.
Reveal takes a project id, never a path. Main asks the catalog where that
project lives and the existing `project` open-path guard re-checks the
resolved directory, so the renderer cannot name an arbitrary folder for the
shell to open. It is offered only while the catalog still vouches for the
folder — a menu entry that could only fail is worse than one that is absent.
Rename reuses `SettingsExpandableRow` rather than hand-rolling a second
editor; it already owns the focus move into the field and back to the row,
and the reasoning about why it carries no aria-expanded. It gained an `end`
prop so a row that already owns its end slot — a default Badge, 设为默认, and
the … menu — keeps that cluster instead of growing a second competing button.
Rename is reached from the menu.
Each row's … menu is now named after its project. Four buttons all called
更多操作 are one button to assistive tech; they were equally ambiguous to a
test, which addressed a row by index and renamed the wrong project.
@jackwener

Copy link
Copy Markdown
MemberAuthor

Review by maka-审美专家 — 通过#160 批准降级的两项回补——重命名复用 SettingsExpandableRow kit 组件(#141 的资产第一次被二次消费,'仓库里没有 inline-edit 原语'被自己的 kit 证伪),访达打开经 resolveOpenPath 校验后扩任意项目路径(ok/reason 失败语义清晰)。CI 全绿零失败。合入。注意:项目页实体列表改版(已定案)将在本 PR 之上进行。

@jackwener
jackwener merged commit 2953869 into mainAug 7, 2026
12 checks passed
Sign up for freeto join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant

@jackwener
, '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(settings): rename and reveal a project from its row menu - #2447

Merged
jackwener merged 1 commit into
mainfrom
feat/project-row-actions
Aug 7, 2026
Merged

feat(settings): rename and reveal a project from its row menu#2447
jackwener merged 1 commit into
mainfrom
feat/project-row-actions

Conversation

@jackwener

Copy link
Copy Markdown
Member

改了什么

补齐 #160 降级掉的两项,项目页从「只能选默认」变成「能管理项目」。task #161

在访达中打开:传 id,不传路径

渲染层传 projectId,主进程向 catalog 问这个项目在哪,再交给已有的 project open-path 守卫复核解析后的目录。渲染层没有机会指定任意目录让 shell 打开 —— 这比把 app:openPath 放开成「接受任意路径」安全,也不需要新的守卫逻辑。

只在 catalog 仍然认可该目录时才可点:一个必然失败的菜单项,比没有这个菜单项更糟。

重命名:复用既有原语,不是新造

SettingsExpandableRow本来就存在(外观页的显示名称在用),它已经封好了「打开时聚焦第一个控件、关闭时把焦点还给行」以及「为什么故意不挂 aria-expanded」这些判断。手写第二套编辑器等于把这些判断重做一遍还容易漏。

给它加了一个 end prop:本来就自带尾部控件簇的行(默认 Badge / 设为默认 / … 菜单)保留自己的簇,而不是再长出一个和它们抢位置的「更改」按钮。重命名从 … 菜单进。既有调用方不传 end,行为不变。

顺带修一个真问题

每行的 … 菜单现在带上项目名(更多操作:astryx-design-system)。四个都叫「更多操作」的按钮,对辅助技术来说等于同一个按钮;它们对测试也同样有歧义——我第一版 e2e 按下标定位,结果重命名了错误的那一行(app 会自注册一个工作区项目,导致渲染顺序和 fixture 种子顺序不一致)。是截图暴露的,不是断言。

怎么验证的

  • e2e 从 1 个扩到 3 个:重命名(含焦点断言 + catalog 真的改了,不只是行变了)、不可用项目的「在访达中打开」为禁用、reveal 对目录不存在的项目返回 ok:false
  • typecheck / lint / format / build / knip 全绿;desktop 1751 passed / 0 failed
  • 测试按名字定位行,不按下标——这次翻车的直接原因。

Completes the two actions #160 deferred, so the Projects page manages a
project rather than only choosing a default.
Reveal takes a project id, never a path. Main asks the catalog where that
project lives and the existing `project` open-path guard re-checks the
resolved directory, so the renderer cannot name an arbitrary folder for the
shell to open. It is offered only while the catalog still vouches for the
folder — a menu entry that could only fail is worse than one that is absent.
Rename reuses `SettingsExpandableRow` rather than hand-rolling a second
editor; it already owns the focus move into the field and back to the row,
and the reasoning about why it carries no aria-expanded. It gained an `end`
prop so a row that already owns its end slot — a default Badge, 设为默认, and
the … menu — keeps that cluster instead of growing a second competing button.
Rename is reached from the menu.
Each row's … menu is now named after its project. Four buttons all called
更多操作 are one button to assistive tech; they were equally ambiguous to a
test, which addressed a row by index and renamed the wrong project.
@jackwener

Copy link
Copy Markdown
MemberAuthor

Review by maka-审美专家 — 通过#160 批准降级的两项回补——重命名复用 SettingsExpandableRow kit 组件(#141 的资产第一次被二次消费,'仓库里没有 inline-edit 原语'被自己的 kit 证伪),访达打开经 resolveOpenPath 校验后扩任意项目路径(ok/reason 失败语义清晰)。CI 全绿零失败。合入。注意:项目页实体列表改版(已定案)将在本 PR 之上进行。

@jackwener
jackwener merged commit 2953869 into mainAug 7, 2026
12 checks passed
Sign up for freeto join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant

@jackwener
, '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(settings): rename and reveal a project from its row menu - #2447

Merged
jackwener merged 1 commit into
mainfrom
feat/project-row-actions
Aug 7, 2026
Merged

feat(settings): rename and reveal a project from its row menu#2447
jackwener merged 1 commit into
mainfrom
feat/project-row-actions

Conversation

@jackwener

Copy link
Copy Markdown
Member

改了什么

补齐 #160 降级掉的两项,项目页从「只能选默认」变成「能管理项目」。task #161

在访达中打开:传 id,不传路径

渲染层传 projectId,主进程向 catalog 问这个项目在哪,再交给已有的 project open-path 守卫复核解析后的目录。渲染层没有机会指定任意目录让 shell 打开 —— 这比把 app:openPath 放开成「接受任意路径」安全,也不需要新的守卫逻辑。

只在 catalog 仍然认可该目录时才可点:一个必然失败的菜单项,比没有这个菜单项更糟。

重命名:复用既有原语,不是新造

SettingsExpandableRow本来就存在(外观页的显示名称在用),它已经封好了「打开时聚焦第一个控件、关闭时把焦点还给行」以及「为什么故意不挂 aria-expanded」这些判断。手写第二套编辑器等于把这些判断重做一遍还容易漏。

给它加了一个 end prop:本来就自带尾部控件簇的行(默认 Badge / 设为默认 / … 菜单)保留自己的簇,而不是再长出一个和它们抢位置的「更改」按钮。重命名从 … 菜单进。既有调用方不传 end,行为不变。

顺带修一个真问题

每行的 … 菜单现在带上项目名(更多操作:astryx-design-system)。四个都叫「更多操作」的按钮,对辅助技术来说等于同一个按钮;它们对测试也同样有歧义——我第一版 e2e 按下标定位,结果重命名了错误的那一行(app 会自注册一个工作区项目,导致渲染顺序和 fixture 种子顺序不一致)。是截图暴露的,不是断言。

怎么验证的

  • e2e 从 1 个扩到 3 个:重命名(含焦点断言 + catalog 真的改了,不只是行变了)、不可用项目的「在访达中打开」为禁用、reveal 对目录不存在的项目返回 ok:false
  • typecheck / lint / format / build / knip 全绿;desktop 1751 passed / 0 failed
  • 测试按名字定位行,不按下标——这次翻车的直接原因。

Completes the two actions #160 deferred, so the Projects page manages a
project rather than only choosing a default.
Reveal takes a project id, never a path. Main asks the catalog where that
project lives and the existing `project` open-path guard re-checks the
resolved directory, so the renderer cannot name an arbitrary folder for the
shell to open. It is offered only while the catalog still vouches for the
folder — a menu entry that could only fail is worse than one that is absent.
Rename reuses `SettingsExpandableRow` rather than hand-rolling a second
editor; it already owns the focus move into the field and back to the row,
and the reasoning about why it carries no aria-expanded. It gained an `end`
prop so a row that already owns its end slot — a default Badge, 设为默认, and
the … menu — keeps that cluster instead of growing a second competing button.
Rename is reached from the menu.
Each row's … menu is now named after its project. Four buttons all called
更多操作 are one button to assistive tech; they were equally ambiguous to a
test, which addressed a row by index and renamed the wrong project.
@jackwener

Copy link
Copy Markdown
MemberAuthor

Review by maka-审美专家 — 通过#160 批准降级的两项回补——重命名复用 SettingsExpandableRow kit 组件(#141 的资产第一次被二次消费,'仓库里没有 inline-edit 原语'被自己的 kit 证伪),访达打开经 resolveOpenPath 校验后扩任意项目路径(ok/reason 失败语义清晰)。CI 全绿零失败。合入。注意:项目页实体列表改版(已定案)将在本 PR 之上进行。

@jackwener
jackwener merged commit 2953869 into mainAug 7, 2026
12 checks passed
Sign up for freeto join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant

@jackwener
, '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(settings): rename and reveal a project from its row menu - #2447

Merged
jackwener merged 1 commit into
mainfrom
feat/project-row-actions
Aug 7, 2026
Merged

feat(settings): rename and reveal a project from its row menu#2447
jackwener merged 1 commit into
mainfrom
feat/project-row-actions

Conversation

@jackwener

Copy link
Copy Markdown
Member

改了什么

补齐 #160 降级掉的两项,项目页从「只能选默认」变成「能管理项目」。task #161

在访达中打开:传 id,不传路径

渲染层传 projectId,主进程向 catalog 问这个项目在哪,再交给已有的 project open-path 守卫复核解析后的目录。渲染层没有机会指定任意目录让 shell 打开 —— 这比把 app:openPath 放开成「接受任意路径」安全,也不需要新的守卫逻辑。

只在 catalog 仍然认可该目录时才可点:一个必然失败的菜单项,比没有这个菜单项更糟。

重命名:复用既有原语,不是新造

SettingsExpandableRow本来就存在(外观页的显示名称在用),它已经封好了「打开时聚焦第一个控件、关闭时把焦点还给行」以及「为什么故意不挂 aria-expanded」这些判断。手写第二套编辑器等于把这些判断重做一遍还容易漏。

给它加了一个 end prop:本来就自带尾部控件簇的行(默认 Badge / 设为默认 / … 菜单)保留自己的簇,而不是再长出一个和它们抢位置的「更改」按钮。重命名从 … 菜单进。既有调用方不传 end,行为不变。

顺带修一个真问题

每行的 … 菜单现在带上项目名(更多操作:astryx-design-system)。四个都叫「更多操作」的按钮,对辅助技术来说等于同一个按钮;它们对测试也同样有歧义——我第一版 e2e 按下标定位,结果重命名了错误的那一行(app 会自注册一个工作区项目,导致渲染顺序和 fixture 种子顺序不一致)。是截图暴露的,不是断言。

怎么验证的

  • e2e 从 1 个扩到 3 个:重命名(含焦点断言 + catalog 真的改了,不只是行变了)、不可用项目的「在访达中打开」为禁用、reveal 对目录不存在的项目返回 ok:false
  • typecheck / lint / format / build / knip 全绿;desktop 1751 passed / 0 failed
  • 测试按名字定位行,不按下标——这次翻车的直接原因。

Completes the two actions #160 deferred, so the Projects page manages a
project rather than only choosing a default.
Reveal takes a project id, never a path. Main asks the catalog where that
project lives and the existing `project` open-path guard re-checks the
resolved directory, so the renderer cannot name an arbitrary folder for the
shell to open. It is offered only while the catalog still vouches for the
folder — a menu entry that could only fail is worse than one that is absent.
Rename reuses `SettingsExpandableRow` rather than hand-rolling a second
editor; it already owns the focus move into the field and back to the row,
and the reasoning about why it carries no aria-expanded. It gained an `end`
prop so a row that already owns its end slot — a default Badge, 设为默认, and
the … menu — keeps that cluster instead of growing a second competing button.
Rename is reached from the menu.
Each row's … menu is now named after its project. Four buttons all called
更多操作 are one button to assistive tech; they were equally ambiguous to a
test, which addressed a row by index and renamed the wrong project.
@jackwener

Copy link
Copy Markdown
MemberAuthor

Review by maka-审美专家 — 通过#160 批准降级的两项回补——重命名复用 SettingsExpandableRow kit 组件(#141 的资产第一次被二次消费,'仓库里没有 inline-edit 原语'被自己的 kit 证伪),访达打开经 resolveOpenPath 校验后扩任意项目路径(ok/reason 失败语义清晰)。CI 全绿零失败。合入。注意:项目页实体列表改版(已定案)将在本 PR 之上进行。

@jackwener
jackwener merged commit 2953869 into mainAug 7, 2026
12 checks passed
Sign up for freeto join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant

@jackwener
, '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(settings): rename and reveal a project from its row menu - #2447

Merged
jackwener merged 1 commit into
mainfrom
feat/project-row-actions
Aug 7, 2026
Merged

feat(settings): rename and reveal a project from its row menu#2447
jackwener merged 1 commit into
mainfrom
feat/project-row-actions

Conversation

@jackwener

Copy link
Copy Markdown
Member

改了什么

补齐 #160 降级掉的两项,项目页从「只能选默认」变成「能管理项目」。task #161

在访达中打开:传 id,不传路径

渲染层传 projectId,主进程向 catalog 问这个项目在哪,再交给已有的 project open-path 守卫复核解析后的目录。渲染层没有机会指定任意目录让 shell 打开 —— 这比把 app:openPath 放开成「接受任意路径」安全,也不需要新的守卫逻辑。

只在 catalog 仍然认可该目录时才可点:一个必然失败的菜单项,比没有这个菜单项更糟。

重命名:复用既有原语,不是新造

SettingsExpandableRow本来就存在(外观页的显示名称在用),它已经封好了「打开时聚焦第一个控件、关闭时把焦点还给行」以及「为什么故意不挂 aria-expanded」这些判断。手写第二套编辑器等于把这些判断重做一遍还容易漏。

给它加了一个 end prop:本来就自带尾部控件簇的行(默认 Badge / 设为默认 / … 菜单)保留自己的簇,而不是再长出一个和它们抢位置的「更改」按钮。重命名从 … 菜单进。既有调用方不传 end,行为不变。

顺带修一个真问题

每行的 … 菜单现在带上项目名(更多操作:astryx-design-system)。四个都叫「更多操作」的按钮,对辅助技术来说等于同一个按钮;它们对测试也同样有歧义——我第一版 e2e 按下标定位,结果重命名了错误的那一行(app 会自注册一个工作区项目,导致渲染顺序和 fixture 种子顺序不一致)。是截图暴露的,不是断言。

怎么验证的

  • e2e 从 1 个扩到 3 个:重命名(含焦点断言 + catalog 真的改了,不只是行变了)、不可用项目的「在访达中打开」为禁用、reveal 对目录不存在的项目返回 ok:false
  • typecheck / lint / format / build / knip 全绿;desktop 1751 passed / 0 failed
  • 测试按名字定位行,不按下标——这次翻车的直接原因。

Completes the two actions #160 deferred, so the Projects page manages a
project rather than only choosing a default.
Reveal takes a project id, never a path. Main asks the catalog where that
project lives and the existing `project` open-path guard re-checks the
resolved directory, so the renderer cannot name an arbitrary folder for the
shell to open. It is offered only while the catalog still vouches for the
folder — a menu entry that could only fail is worse than one that is absent.
Rename reuses `SettingsExpandableRow` rather than hand-rolling a second
editor; it already owns the focus move into the field and back to the row,
and the reasoning about why it carries no aria-expanded. It gained an `end`
prop so a row that already owns its end slot — a default Badge, 设为默认, and
the … menu — keeps that cluster instead of growing a second competing button.
Rename is reached from the menu.
Each row's … menu is now named after its project. Four buttons all called
更多操作 are one button to assistive tech; they were equally ambiguous to a
test, which addressed a row by index and renamed the wrong project.
@jackwener

Copy link
Copy Markdown
MemberAuthor

Review by maka-审美专家 — 通过#160 批准降级的两项回补——重命名复用 SettingsExpandableRow kit 组件(#141 的资产第一次被二次消费,'仓库里没有 inline-edit 原语'被自己的 kit 证伪),访达打开经 resolveOpenPath 校验后扩任意项目路径(ok/reason 失败语义清晰)。CI 全绿零失败。合入。注意:项目页实体列表改版(已定案)将在本 PR 之上进行。

@jackwener
jackwener merged commit 2953869 into mainAug 7, 2026
12 checks passed
Sign up for freeto join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant

@jackwener
, '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(settings): rename and reveal a project from its row menu - #2447

Merged
jackwener merged 1 commit into
mainfrom
feat/project-row-actions
Aug 7, 2026
Merged

feat(settings): rename and reveal a project from its row menu#2447
jackwener merged 1 commit into
mainfrom
feat/project-row-actions

Conversation

@jackwener

Copy link
Copy Markdown
Member

改了什么

补齐 #160 降级掉的两项,项目页从「只能选默认」变成「能管理项目」。task #161

在访达中打开:传 id,不传路径

渲染层传 projectId,主进程向 catalog 问这个项目在哪,再交给已有的 project open-path 守卫复核解析后的目录。渲染层没有机会指定任意目录让 shell 打开 —— 这比把 app:openPath 放开成「接受任意路径」安全,也不需要新的守卫逻辑。

只在 catalog 仍然认可该目录时才可点:一个必然失败的菜单项,比没有这个菜单项更糟。

重命名:复用既有原语,不是新造

SettingsExpandableRow本来就存在(外观页的显示名称在用),它已经封好了「打开时聚焦第一个控件、关闭时把焦点还给行」以及「为什么故意不挂 aria-expanded」这些判断。手写第二套编辑器等于把这些判断重做一遍还容易漏。

给它加了一个 end prop:本来就自带尾部控件簇的行(默认 Badge / 设为默认 / … 菜单)保留自己的簇,而不是再长出一个和它们抢位置的「更改」按钮。重命名从 … 菜单进。既有调用方不传 end,行为不变。

顺带修一个真问题

每行的 … 菜单现在带上项目名(更多操作:astryx-design-system)。四个都叫「更多操作」的按钮,对辅助技术来说等于同一个按钮;它们对测试也同样有歧义——我第一版 e2e 按下标定位,结果重命名了错误的那一行(app 会自注册一个工作区项目,导致渲染顺序和 fixture 种子顺序不一致)。是截图暴露的,不是断言。

怎么验证的

  • e2e 从 1 个扩到 3 个:重命名(含焦点断言 + catalog 真的改了,不只是行变了)、不可用项目的「在访达中打开」为禁用、reveal 对目录不存在的项目返回 ok:false
  • typecheck / lint / format / build / knip 全绿;desktop 1751 passed / 0 failed
  • 测试按名字定位行,不按下标——这次翻车的直接原因。

Completes the two actions #160 deferred, so the Projects page manages a
project rather than only choosing a default.
Reveal takes a project id, never a path. Main asks the catalog where that
project lives and the existing `project` open-path guard re-checks the
resolved directory, so the renderer cannot name an arbitrary folder for the
shell to open. It is offered only while the catalog still vouches for the
folder — a menu entry that could only fail is worse than one that is absent.
Rename reuses `SettingsExpandableRow` rather than hand-rolling a second
editor; it already owns the focus move into the field and back to the row,
and the reasoning about why it carries no aria-expanded. It gained an `end`
prop so a row that already owns its end slot — a default Badge, 设为默认, and
the … menu — keeps that cluster instead of growing a second competing button.
Rename is reached from the menu.
Each row's … menu is now named after its project. Four buttons all called
更多操作 are one button to assistive tech; they were equally ambiguous to a
test, which addressed a row by index and renamed the wrong project.
@jackwener

Copy link
Copy Markdown
MemberAuthor

Review by maka-审美专家 — 通过#160 批准降级的两项回补——重命名复用 SettingsExpandableRow kit 组件(#141 的资产第一次被二次消费,'仓库里没有 inline-edit 原语'被自己的 kit 证伪),访达打开经 resolveOpenPath 校验后扩任意项目路径(ok/reason 失败语义清晰)。CI 全绿零失败。合入。注意:项目页实体列表改版(已定案)将在本 PR 之上进行。

@jackwener
jackwener merged commit 2953869 into mainAug 7, 2026
12 checks passed
Sign up for freeto join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant

@jackwener