amicode(home): fix silent dead-end on 'Open chat' with no tracked projects - #8

Merged
kateebonner merged 1 commit into
local/amicodefrom
kate/home-open-chat-empty-projects
Jul 8, 2026
Merged

amicode(home): fix silent dead-end on 'Open chat' with no tracked projects#8
kateebonner merged 1 commit into
local/amicodefrom
kate/home-open-chat-empty-projects

Conversation

@kateebonner

Copy link
Copy Markdown
Contributor

Bug

On a fresh browser profile pointed at a bare opencode serve, the home page's primary CTA — the Meet-Amico card and its Open chat button — does nothing. No navigation, no error.

Root cause (packages/app/src/pages/home.tsx, fork wiring from 5ef6b7e): startWithPrompt needs newSessionProject(), which resolves from the persisted client-side project list (localStorage). On a fresh profile that list is empty, so the !project branch calls openNewSession() — which needs the same empty newSessionProject() and hits if (!conn || !project) return. Silent no-op.

Hit live on 2026-07-08 driving the web UI against an opencode serve on a scratch directory (Pasqal connector testing).

Fix

When no project is tracked, fall back to the focused server's own working directory — focusedSync().data.path.directory, synced from GET /path (defaults to "" until loaded, so the falsy guard holds). Open + touch it as a project (self-healing: the home page tracks it from then on), then start the draft with the prompt preserved.

Deliberately notsync.data.project: the server's "global" project record has worktree: "/" — falling back to "first server project" would open a session on the filesystem root.

Verification

  • New regression spec e2e/regression/home-open-chat-empty-projects.spec.ts: real UI against the mocked server, no localStorage seed (the regression condition), clicks the CTA, expects navigation to /new-session?draftId= and the cwd persisted as a tracked project. Verified failing on the unfixed code, passing with the fix.
  • tsgo -b clean (also re-run by the pre-push hook)
  • bun run test:unit: 376 pass / 0 fail
  • Locator note: the whole Meet-Amico card is also a role=button whose accessible name contains "Open chat" — the spec uses exact: true.
  • Playwright harness note: the config reuses any server on port 3000; run with PLAYWRIGHT_PORT=<free port> if something else holds it (the harmoniqs website dev server did).

Patch-stack entry added to AMICODE-PATCHES.md (entry 9). No vendor bump in amicode implied by this PR — the extension pins local e9b695191; bump on the next scheduled vendor refresh.

🤖 Generated with Claude Code

…jects
On a fresh browser profile against a bare `opencode serve`, the home
page's primary CTA (Meet-Amico card / "Open chat") did nothing: the
persisted client-side project list is empty, so startWithPrompt fell
through to openNewSession(), which needs the same newSessionProject()
that just came back empty and silently returns.
Fall back to the focused server's own working directory, synced from
GET /path (.directory; "" until loaded, so the guard holds). Open and
touch it as a project — self-healing: the home page tracks it from then
on — and start the draft with the prompt preserved. Deliberately not
sync.data.project: the server's "global" record has worktree "/".
Regression spec drives the real UI against a mocked server with no
localStorage seed; verified failing on the unfixed code and passing
with the fix. tsgo -b clean; bun test:unit 376 pass.
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
@kateebonner
kateebonner merged commit 99a5918 into local/amicodeJul 8, 2026
0 of 4 checks passed
Rchari1 added a commit that referenced this pull request Jul 9, 2026
…mo udd hit exactly this) + trunk
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
kateebonner added a commit that referenced this pull request Jul 9, 2026
…99
The fork rendered the old "digi" pixel-H mark in four independent copies
while amicode redesigned its mark (PR #99). This unifies them to a single
MARK_PATH and syncs the geometry to #99's FINAL square mark (viewBox
0 0 3600 3600) — not the intermediate "hackathon" geometry an earlier
draft of this branch had copied, which #99 itself later abandoned.
- logo.tsx: MARK_PATH = amico_reduced.svg's outer-bracket path (fill-rule
evenodd). Mark/Splash render it; viewBox 64x56 → 3600 square.
MarkDetailed = amico.svg's full mark (bracket + internal accents),
viewBox 116 287 3377 3035 → 3600 square, for the Meet Amico card only.
- spinner.tsx (AmicoSpinner) + run-card.tsx (share-card SVG) both now
import MARK_PATH instead of carrying their own copies — run-card was a
fourth private copy of the old glyph; its transform is recalibrated
(scale 0.55 → 0.011) for the 3600-unit space.
- favicon/amico.svg: reduced bracket on the yellow chip, viewBox 3600,
path kept byte-identical to MARK_PATH.
- logo.css: aspect-ratio 8/7 → 1/1 (mark is square now).
- Small contexts use the reduced mark, the Meet Amico card uses the
detailed one — matching amicode's own small/large split.
Rebased onto local/amicode (picks up PR #8; AMICODE-PATCHES.md conflict
resolved, entry 15 rewritten for the final geometry).
Checks: bun turbo typecheck (ui+app) green; ui bun test src 95 pass;
app vite build clean — new mark path in the bundle, old geometry and the
64x56 viewBox gone (0 chunks), favicon carries the new path.
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
kateebonner added a commit that referenced this pull request Jul 9, 2026
…99
The fork rendered the old "digi" pixel-H mark in four independent copies
while amicode redesigned its mark (PR #99). This unifies them to a single
MARK_PATH and syncs the geometry to #99's FINAL square mark (viewBox
0 0 3600 3600) — not the intermediate "hackathon" geometry an earlier
draft of this branch had copied, which #99 itself later abandoned.
- logo.tsx: MARK_PATH = amico_reduced.svg's outer-bracket path (fill-rule
evenodd). Mark/Splash render it; viewBox 64x56 → 3600 square.
MarkDetailed = amico.svg's full mark (bracket + internal accents),
viewBox 116 287 3377 3035 → 3600 square, for the Meet Amico card only.
- spinner.tsx (AmicoSpinner) + run-card.tsx (share-card SVG) both now
import MARK_PATH instead of carrying their own copies — run-card was a
fourth private copy of the old glyph; its transform is recalibrated
(scale 0.55 → 0.011) for the 3600-unit space.
- favicon/amico.svg: reduced bracket on the yellow chip, viewBox 3600,
path kept byte-identical to MARK_PATH.
- logo.css: aspect-ratio 8/7 → 1/1 (mark is square now).
- Small contexts use the reduced mark, the Meet Amico card uses the
detailed one — matching amicode's own small/large split.
Rebased onto local/amicode (picks up PR #8; AMICODE-PATCHES.md conflict
resolved, entry 15 rewritten for the final geometry).
Checks: bun turbo typecheck (ui+app) green; ui bun test src 95 pass;
app vite build clean — new mark path in the bundle, old geometry and the
64x56 viewBox gone (0 chunks), favicon carries the new path.
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
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

@kateebonner
, '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

amicode(home): fix silent dead-end on 'Open chat' with no tracked projects - #8

Merged
kateebonner merged 1 commit into
local/amicodefrom
kate/home-open-chat-empty-projects
Jul 8, 2026
Merged

amicode(home): fix silent dead-end on 'Open chat' with no tracked projects#8
kateebonner merged 1 commit into
local/amicodefrom
kate/home-open-chat-empty-projects

Conversation

@kateebonner

Copy link
Copy Markdown
Contributor

Bug

On a fresh browser profile pointed at a bare opencode serve, the home page's primary CTA — the Meet-Amico card and its Open chat button — does nothing. No navigation, no error.

Root cause (packages/app/src/pages/home.tsx, fork wiring from 5ef6b7e): startWithPrompt needs newSessionProject(), which resolves from the persisted client-side project list (localStorage). On a fresh profile that list is empty, so the !project branch calls openNewSession() — which needs the same empty newSessionProject() and hits if (!conn || !project) return. Silent no-op.

Hit live on 2026-07-08 driving the web UI against an opencode serve on a scratch directory (Pasqal connector testing).

Fix

When no project is tracked, fall back to the focused server's own working directory — focusedSync().data.path.directory, synced from GET /path (defaults to "" until loaded, so the falsy guard holds). Open + touch it as a project (self-healing: the home page tracks it from then on), then start the draft with the prompt preserved.

Deliberately notsync.data.project: the server's "global" project record has worktree: "/" — falling back to "first server project" would open a session on the filesystem root.

Verification

  • New regression spec e2e/regression/home-open-chat-empty-projects.spec.ts: real UI against the mocked server, no localStorage seed (the regression condition), clicks the CTA, expects navigation to /new-session?draftId= and the cwd persisted as a tracked project. Verified failing on the unfixed code, passing with the fix.
  • tsgo -b clean (also re-run by the pre-push hook)
  • bun run test:unit: 376 pass / 0 fail
  • Locator note: the whole Meet-Amico card is also a role=button whose accessible name contains "Open chat" — the spec uses exact: true.
  • Playwright harness note: the config reuses any server on port 3000; run with PLAYWRIGHT_PORT=<free port> if something else holds it (the harmoniqs website dev server did).

Patch-stack entry added to AMICODE-PATCHES.md (entry 9). No vendor bump in amicode implied by this PR — the extension pins local e9b695191; bump on the next scheduled vendor refresh.

🤖 Generated with Claude Code

…jects
On a fresh browser profile against a bare `opencode serve`, the home
page's primary CTA (Meet-Amico card / "Open chat") did nothing: the
persisted client-side project list is empty, so startWithPrompt fell
through to openNewSession(), which needs the same newSessionProject()
that just came back empty and silently returns.
Fall back to the focused server's own working directory, synced from
GET /path (.directory; "" until loaded, so the guard holds). Open and
touch it as a project — self-healing: the home page tracks it from then
on — and start the draft with the prompt preserved. Deliberately not
sync.data.project: the server's "global" record has worktree "/".
Regression spec drives the real UI against a mocked server with no
localStorage seed; verified failing on the unfixed code and passing
with the fix. tsgo -b clean; bun test:unit 376 pass.
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
@kateebonner
kateebonner merged commit 99a5918 into local/amicodeJul 8, 2026
0 of 4 checks passed
Rchari1 added a commit that referenced this pull request Jul 9, 2026
…mo udd hit exactly this) + trunk
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
kateebonner added a commit that referenced this pull request Jul 9, 2026
…99
The fork rendered the old "digi" pixel-H mark in four independent copies
while amicode redesigned its mark (PR #99). This unifies them to a single
MARK_PATH and syncs the geometry to #99's FINAL square mark (viewBox
0 0 3600 3600) — not the intermediate "hackathon" geometry an earlier
draft of this branch had copied, which #99 itself later abandoned.
- logo.tsx: MARK_PATH = amico_reduced.svg's outer-bracket path (fill-rule
evenodd). Mark/Splash render it; viewBox 64x56 → 3600 square.
MarkDetailed = amico.svg's full mark (bracket + internal accents),
viewBox 116 287 3377 3035 → 3600 square, for the Meet Amico card only.
- spinner.tsx (AmicoSpinner) + run-card.tsx (share-card SVG) both now
import MARK_PATH instead of carrying their own copies — run-card was a
fourth private copy of the old glyph; its transform is recalibrated
(scale 0.55 → 0.011) for the 3600-unit space.
- favicon/amico.svg: reduced bracket on the yellow chip, viewBox 3600,
path kept byte-identical to MARK_PATH.
- logo.css: aspect-ratio 8/7 → 1/1 (mark is square now).
- Small contexts use the reduced mark, the Meet Amico card uses the
detailed one — matching amicode's own small/large split.
Rebased onto local/amicode (picks up PR #8; AMICODE-PATCHES.md conflict
resolved, entry 15 rewritten for the final geometry).
Checks: bun turbo typecheck (ui+app) green; ui bun test src 95 pass;
app vite build clean — new mark path in the bundle, old geometry and the
64x56 viewBox gone (0 chunks), favicon carries the new path.
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
kateebonner added a commit that referenced this pull request Jul 9, 2026
…99
The fork rendered the old "digi" pixel-H mark in four independent copies
while amicode redesigned its mark (PR #99). This unifies them to a single
MARK_PATH and syncs the geometry to #99's FINAL square mark (viewBox
0 0 3600 3600) — not the intermediate "hackathon" geometry an earlier
draft of this branch had copied, which #99 itself later abandoned.
- logo.tsx: MARK_PATH = amico_reduced.svg's outer-bracket path (fill-rule
evenodd). Mark/Splash render it; viewBox 64x56 → 3600 square.
MarkDetailed = amico.svg's full mark (bracket + internal accents),
viewBox 116 287 3377 3035 → 3600 square, for the Meet Amico card only.
- spinner.tsx (AmicoSpinner) + run-card.tsx (share-card SVG) both now
import MARK_PATH instead of carrying their own copies — run-card was a
fourth private copy of the old glyph; its transform is recalibrated
(scale 0.55 → 0.011) for the 3600-unit space.
- favicon/amico.svg: reduced bracket on the yellow chip, viewBox 3600,
path kept byte-identical to MARK_PATH.
- logo.css: aspect-ratio 8/7 → 1/1 (mark is square now).
- Small contexts use the reduced mark, the Meet Amico card uses the
detailed one — matching amicode's own small/large split.
Rebased onto local/amicode (picks up PR #8; AMICODE-PATCHES.md conflict
resolved, entry 15 rewritten for the final geometry).
Checks: bun turbo typecheck (ui+app) green; ui bun test src 95 pass;
app vite build clean — new mark path in the bundle, old geometry and the
64x56 viewBox gone (0 chunks), favicon carries the new path.
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
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

@kateebonner
, '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

amicode(home): fix silent dead-end on 'Open chat' with no tracked projects - #8

Merged
kateebonner merged 1 commit into
local/amicodefrom
kate/home-open-chat-empty-projects
Jul 8, 2026
Merged

amicode(home): fix silent dead-end on 'Open chat' with no tracked projects#8
kateebonner merged 1 commit into
local/amicodefrom
kate/home-open-chat-empty-projects

Conversation

@kateebonner

Copy link
Copy Markdown
Contributor

Bug

On a fresh browser profile pointed at a bare opencode serve, the home page's primary CTA — the Meet-Amico card and its Open chat button — does nothing. No navigation, no error.

Root cause (packages/app/src/pages/home.tsx, fork wiring from 5ef6b7e): startWithPrompt needs newSessionProject(), which resolves from the persisted client-side project list (localStorage). On a fresh profile that list is empty, so the !project branch calls openNewSession() — which needs the same empty newSessionProject() and hits if (!conn || !project) return. Silent no-op.

Hit live on 2026-07-08 driving the web UI against an opencode serve on a scratch directory (Pasqal connector testing).

Fix

When no project is tracked, fall back to the focused server's own working directory — focusedSync().data.path.directory, synced from GET /path (defaults to "" until loaded, so the falsy guard holds). Open + touch it as a project (self-healing: the home page tracks it from then on), then start the draft with the prompt preserved.

Deliberately notsync.data.project: the server's "global" project record has worktree: "/" — falling back to "first server project" would open a session on the filesystem root.

Verification

  • New regression spec e2e/regression/home-open-chat-empty-projects.spec.ts: real UI against the mocked server, no localStorage seed (the regression condition), clicks the CTA, expects navigation to /new-session?draftId= and the cwd persisted as a tracked project. Verified failing on the unfixed code, passing with the fix.
  • tsgo -b clean (also re-run by the pre-push hook)
  • bun run test:unit: 376 pass / 0 fail
  • Locator note: the whole Meet-Amico card is also a role=button whose accessible name contains "Open chat" — the spec uses exact: true.
  • Playwright harness note: the config reuses any server on port 3000; run with PLAYWRIGHT_PORT=<free port> if something else holds it (the harmoniqs website dev server did).

Patch-stack entry added to AMICODE-PATCHES.md (entry 9). No vendor bump in amicode implied by this PR — the extension pins local e9b695191; bump on the next scheduled vendor refresh.

🤖 Generated with Claude Code

…jects
On a fresh browser profile against a bare `opencode serve`, the home
page's primary CTA (Meet-Amico card / "Open chat") did nothing: the
persisted client-side project list is empty, so startWithPrompt fell
through to openNewSession(), which needs the same newSessionProject()
that just came back empty and silently returns.
Fall back to the focused server's own working directory, synced from
GET /path (.directory; "" until loaded, so the guard holds). Open and
touch it as a project — self-healing: the home page tracks it from then
on — and start the draft with the prompt preserved. Deliberately not
sync.data.project: the server's "global" record has worktree "/".
Regression spec drives the real UI against a mocked server with no
localStorage seed; verified failing on the unfixed code and passing
with the fix. tsgo -b clean; bun test:unit 376 pass.
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
@kateebonner
kateebonner merged commit 99a5918 into local/amicodeJul 8, 2026
0 of 4 checks passed
Rchari1 added a commit that referenced this pull request Jul 9, 2026
…mo udd hit exactly this) + trunk
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
kateebonner added a commit that referenced this pull request Jul 9, 2026
…99
The fork rendered the old "digi" pixel-H mark in four independent copies
while amicode redesigned its mark (PR #99). This unifies them to a single
MARK_PATH and syncs the geometry to #99's FINAL square mark (viewBox
0 0 3600 3600) — not the intermediate "hackathon" geometry an earlier
draft of this branch had copied, which #99 itself later abandoned.
- logo.tsx: MARK_PATH = amico_reduced.svg's outer-bracket path (fill-rule
evenodd). Mark/Splash render it; viewBox 64x56 → 3600 square.
MarkDetailed = amico.svg's full mark (bracket + internal accents),
viewBox 116 287 3377 3035 → 3600 square, for the Meet Amico card only.
- spinner.tsx (AmicoSpinner) + run-card.tsx (share-card SVG) both now
import MARK_PATH instead of carrying their own copies — run-card was a
fourth private copy of the old glyph; its transform is recalibrated
(scale 0.55 → 0.011) for the 3600-unit space.
- favicon/amico.svg: reduced bracket on the yellow chip, viewBox 3600,
path kept byte-identical to MARK_PATH.
- logo.css: aspect-ratio 8/7 → 1/1 (mark is square now).
- Small contexts use the reduced mark, the Meet Amico card uses the
detailed one — matching amicode's own small/large split.
Rebased onto local/amicode (picks up PR #8; AMICODE-PATCHES.md conflict
resolved, entry 15 rewritten for the final geometry).
Checks: bun turbo typecheck (ui+app) green; ui bun test src 95 pass;
app vite build clean — new mark path in the bundle, old geometry and the
64x56 viewBox gone (0 chunks), favicon carries the new path.
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
kateebonner added a commit that referenced this pull request Jul 9, 2026
…99
The fork rendered the old "digi" pixel-H mark in four independent copies
while amicode redesigned its mark (PR #99). This unifies them to a single
MARK_PATH and syncs the geometry to #99's FINAL square mark (viewBox
0 0 3600 3600) — not the intermediate "hackathon" geometry an earlier
draft of this branch had copied, which #99 itself later abandoned.
- logo.tsx: MARK_PATH = amico_reduced.svg's outer-bracket path (fill-rule
evenodd). Mark/Splash render it; viewBox 64x56 → 3600 square.
MarkDetailed = amico.svg's full mark (bracket + internal accents),
viewBox 116 287 3377 3035 → 3600 square, for the Meet Amico card only.
- spinner.tsx (AmicoSpinner) + run-card.tsx (share-card SVG) both now
import MARK_PATH instead of carrying their own copies — run-card was a
fourth private copy of the old glyph; its transform is recalibrated
(scale 0.55 → 0.011) for the 3600-unit space.
- favicon/amico.svg: reduced bracket on the yellow chip, viewBox 3600,
path kept byte-identical to MARK_PATH.
- logo.css: aspect-ratio 8/7 → 1/1 (mark is square now).
- Small contexts use the reduced mark, the Meet Amico card uses the
detailed one — matching amicode's own small/large split.
Rebased onto local/amicode (picks up PR #8; AMICODE-PATCHES.md conflict
resolved, entry 15 rewritten for the final geometry).
Checks: bun turbo typecheck (ui+app) green; ui bun test src 95 pass;
app vite build clean — new mark path in the bundle, old geometry and the
64x56 viewBox gone (0 chunks), favicon carries the new path.
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
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

@kateebonner
, '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

amicode(home): fix silent dead-end on 'Open chat' with no tracked projects - #8

Merged
kateebonner merged 1 commit into
local/amicodefrom
kate/home-open-chat-empty-projects
Jul 8, 2026
Merged

amicode(home): fix silent dead-end on 'Open chat' with no tracked projects#8
kateebonner merged 1 commit into
local/amicodefrom
kate/home-open-chat-empty-projects

Conversation

@kateebonner

Copy link
Copy Markdown
Contributor

Bug

On a fresh browser profile pointed at a bare opencode serve, the home page's primary CTA — the Meet-Amico card and its Open chat button — does nothing. No navigation, no error.

Root cause (packages/app/src/pages/home.tsx, fork wiring from 5ef6b7e): startWithPrompt needs newSessionProject(), which resolves from the persisted client-side project list (localStorage). On a fresh profile that list is empty, so the !project branch calls openNewSession() — which needs the same empty newSessionProject() and hits if (!conn || !project) return. Silent no-op.

Hit live on 2026-07-08 driving the web UI against an opencode serve on a scratch directory (Pasqal connector testing).

Fix

When no project is tracked, fall back to the focused server's own working directory — focusedSync().data.path.directory, synced from GET /path (defaults to "" until loaded, so the falsy guard holds). Open + touch it as a project (self-healing: the home page tracks it from then on), then start the draft with the prompt preserved.

Deliberately notsync.data.project: the server's "global" project record has worktree: "/" — falling back to "first server project" would open a session on the filesystem root.

Verification

  • New regression spec e2e/regression/home-open-chat-empty-projects.spec.ts: real UI against the mocked server, no localStorage seed (the regression condition), clicks the CTA, expects navigation to /new-session?draftId= and the cwd persisted as a tracked project. Verified failing on the unfixed code, passing with the fix.
  • tsgo -b clean (also re-run by the pre-push hook)
  • bun run test:unit: 376 pass / 0 fail
  • Locator note: the whole Meet-Amico card is also a role=button whose accessible name contains "Open chat" — the spec uses exact: true.
  • Playwright harness note: the config reuses any server on port 3000; run with PLAYWRIGHT_PORT=<free port> if something else holds it (the harmoniqs website dev server did).

Patch-stack entry added to AMICODE-PATCHES.md (entry 9). No vendor bump in amicode implied by this PR — the extension pins local e9b695191; bump on the next scheduled vendor refresh.

🤖 Generated with Claude Code

…jects
On a fresh browser profile against a bare `opencode serve`, the home
page's primary CTA (Meet-Amico card / "Open chat") did nothing: the
persisted client-side project list is empty, so startWithPrompt fell
through to openNewSession(), which needs the same newSessionProject()
that just came back empty and silently returns.
Fall back to the focused server's own working directory, synced from
GET /path (.directory; "" until loaded, so the guard holds). Open and
touch it as a project — self-healing: the home page tracks it from then
on — and start the draft with the prompt preserved. Deliberately not
sync.data.project: the server's "global" record has worktree "/".
Regression spec drives the real UI against a mocked server with no
localStorage seed; verified failing on the unfixed code and passing
with the fix. tsgo -b clean; bun test:unit 376 pass.
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
@kateebonner
kateebonner merged commit 99a5918 into local/amicodeJul 8, 2026
0 of 4 checks passed
Rchari1 added a commit that referenced this pull request Jul 9, 2026
…mo udd hit exactly this) + trunk
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
kateebonner added a commit that referenced this pull request Jul 9, 2026
…99
The fork rendered the old "digi" pixel-H mark in four independent copies
while amicode redesigned its mark (PR #99). This unifies them to a single
MARK_PATH and syncs the geometry to #99's FINAL square mark (viewBox
0 0 3600 3600) — not the intermediate "hackathon" geometry an earlier
draft of this branch had copied, which #99 itself later abandoned.
- logo.tsx: MARK_PATH = amico_reduced.svg's outer-bracket path (fill-rule
evenodd). Mark/Splash render it; viewBox 64x56 → 3600 square.
MarkDetailed = amico.svg's full mark (bracket + internal accents),
viewBox 116 287 3377 3035 → 3600 square, for the Meet Amico card only.
- spinner.tsx (AmicoSpinner) + run-card.tsx (share-card SVG) both now
import MARK_PATH instead of carrying their own copies — run-card was a
fourth private copy of the old glyph; its transform is recalibrated
(scale 0.55 → 0.011) for the 3600-unit space.
- favicon/amico.svg: reduced bracket on the yellow chip, viewBox 3600,
path kept byte-identical to MARK_PATH.
- logo.css: aspect-ratio 8/7 → 1/1 (mark is square now).
- Small contexts use the reduced mark, the Meet Amico card uses the
detailed one — matching amicode's own small/large split.
Rebased onto local/amicode (picks up PR #8; AMICODE-PATCHES.md conflict
resolved, entry 15 rewritten for the final geometry).
Checks: bun turbo typecheck (ui+app) green; ui bun test src 95 pass;
app vite build clean — new mark path in the bundle, old geometry and the
64x56 viewBox gone (0 chunks), favicon carries the new path.
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
kateebonner added a commit that referenced this pull request Jul 9, 2026
…99
The fork rendered the old "digi" pixel-H mark in four independent copies
while amicode redesigned its mark (PR #99). This unifies them to a single
MARK_PATH and syncs the geometry to #99's FINAL square mark (viewBox
0 0 3600 3600) — not the intermediate "hackathon" geometry an earlier
draft of this branch had copied, which #99 itself later abandoned.
- logo.tsx: MARK_PATH = amico_reduced.svg's outer-bracket path (fill-rule
evenodd). Mark/Splash render it; viewBox 64x56 → 3600 square.
MarkDetailed = amico.svg's full mark (bracket + internal accents),
viewBox 116 287 3377 3035 → 3600 square, for the Meet Amico card only.
- spinner.tsx (AmicoSpinner) + run-card.tsx (share-card SVG) both now
import MARK_PATH instead of carrying their own copies — run-card was a
fourth private copy of the old glyph; its transform is recalibrated
(scale 0.55 → 0.011) for the 3600-unit space.
- favicon/amico.svg: reduced bracket on the yellow chip, viewBox 3600,
path kept byte-identical to MARK_PATH.
- logo.css: aspect-ratio 8/7 → 1/1 (mark is square now).
- Small contexts use the reduced mark, the Meet Amico card uses the
detailed one — matching amicode's own small/large split.
Rebased onto local/amicode (picks up PR #8; AMICODE-PATCHES.md conflict
resolved, entry 15 rewritten for the final geometry).
Checks: bun turbo typecheck (ui+app) green; ui bun test src 95 pass;
app vite build clean — new mark path in the bundle, old geometry and the
64x56 viewBox gone (0 chunks), favicon carries the new path.
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
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

@kateebonner
, '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

amicode(home): fix silent dead-end on 'Open chat' with no tracked projects - #8

Merged
kateebonner merged 1 commit into
local/amicodefrom
kate/home-open-chat-empty-projects
Jul 8, 2026
Merged

amicode(home): fix silent dead-end on 'Open chat' with no tracked projects#8
kateebonner merged 1 commit into
local/amicodefrom
kate/home-open-chat-empty-projects

Conversation

@kateebonner

Copy link
Copy Markdown
Contributor

Bug

On a fresh browser profile pointed at a bare opencode serve, the home page's primary CTA — the Meet-Amico card and its Open chat button — does nothing. No navigation, no error.

Root cause (packages/app/src/pages/home.tsx, fork wiring from 5ef6b7e): startWithPrompt needs newSessionProject(), which resolves from the persisted client-side project list (localStorage). On a fresh profile that list is empty, so the !project branch calls openNewSession() — which needs the same empty newSessionProject() and hits if (!conn || !project) return. Silent no-op.

Hit live on 2026-07-08 driving the web UI against an opencode serve on a scratch directory (Pasqal connector testing).

Fix

When no project is tracked, fall back to the focused server's own working directory — focusedSync().data.path.directory, synced from GET /path (defaults to "" until loaded, so the falsy guard holds). Open + touch it as a project (self-healing: the home page tracks it from then on), then start the draft with the prompt preserved.

Deliberately notsync.data.project: the server's "global" project record has worktree: "/" — falling back to "first server project" would open a session on the filesystem root.

Verification

  • New regression spec e2e/regression/home-open-chat-empty-projects.spec.ts: real UI against the mocked server, no localStorage seed (the regression condition), clicks the CTA, expects navigation to /new-session?draftId= and the cwd persisted as a tracked project. Verified failing on the unfixed code, passing with the fix.
  • tsgo -b clean (also re-run by the pre-push hook)
  • bun run test:unit: 376 pass / 0 fail
  • Locator note: the whole Meet-Amico card is also a role=button whose accessible name contains "Open chat" — the spec uses exact: true.
  • Playwright harness note: the config reuses any server on port 3000; run with PLAYWRIGHT_PORT=<free port> if something else holds it (the harmoniqs website dev server did).

Patch-stack entry added to AMICODE-PATCHES.md (entry 9). No vendor bump in amicode implied by this PR — the extension pins local e9b695191; bump on the next scheduled vendor refresh.

🤖 Generated with Claude Code

…jects
On a fresh browser profile against a bare `opencode serve`, the home
page's primary CTA (Meet-Amico card / "Open chat") did nothing: the
persisted client-side project list is empty, so startWithPrompt fell
through to openNewSession(), which needs the same newSessionProject()
that just came back empty and silently returns.
Fall back to the focused server's own working directory, synced from
GET /path (.directory; "" until loaded, so the guard holds). Open and
touch it as a project — self-healing: the home page tracks it from then
on — and start the draft with the prompt preserved. Deliberately not
sync.data.project: the server's "global" record has worktree "/".
Regression spec drives the real UI against a mocked server with no
localStorage seed; verified failing on the unfixed code and passing
with the fix. tsgo -b clean; bun test:unit 376 pass.
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
@kateebonner
kateebonner merged commit 99a5918 into local/amicodeJul 8, 2026
0 of 4 checks passed
Rchari1 added a commit that referenced this pull request Jul 9, 2026
…mo udd hit exactly this) + trunk
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
kateebonner added a commit that referenced this pull request Jul 9, 2026
…99
The fork rendered the old "digi" pixel-H mark in four independent copies
while amicode redesigned its mark (PR #99). This unifies them to a single
MARK_PATH and syncs the geometry to #99's FINAL square mark (viewBox
0 0 3600 3600) — not the intermediate "hackathon" geometry an earlier
draft of this branch had copied, which #99 itself later abandoned.
- logo.tsx: MARK_PATH = amico_reduced.svg's outer-bracket path (fill-rule
evenodd). Mark/Splash render it; viewBox 64x56 → 3600 square.
MarkDetailed = amico.svg's full mark (bracket + internal accents),
viewBox 116 287 3377 3035 → 3600 square, for the Meet Amico card only.
- spinner.tsx (AmicoSpinner) + run-card.tsx (share-card SVG) both now
import MARK_PATH instead of carrying their own copies — run-card was a
fourth private copy of the old glyph; its transform is recalibrated
(scale 0.55 → 0.011) for the 3600-unit space.
- favicon/amico.svg: reduced bracket on the yellow chip, viewBox 3600,
path kept byte-identical to MARK_PATH.
- logo.css: aspect-ratio 8/7 → 1/1 (mark is square now).
- Small contexts use the reduced mark, the Meet Amico card uses the
detailed one — matching amicode's own small/large split.
Rebased onto local/amicode (picks up PR #8; AMICODE-PATCHES.md conflict
resolved, entry 15 rewritten for the final geometry).
Checks: bun turbo typecheck (ui+app) green; ui bun test src 95 pass;
app vite build clean — new mark path in the bundle, old geometry and the
64x56 viewBox gone (0 chunks), favicon carries the new path.
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
kateebonner added a commit that referenced this pull request Jul 9, 2026
…99
The fork rendered the old "digi" pixel-H mark in four independent copies
while amicode redesigned its mark (PR #99). This unifies them to a single
MARK_PATH and syncs the geometry to #99's FINAL square mark (viewBox
0 0 3600 3600) — not the intermediate "hackathon" geometry an earlier
draft of this branch had copied, which #99 itself later abandoned.
- logo.tsx: MARK_PATH = amico_reduced.svg's outer-bracket path (fill-rule
evenodd). Mark/Splash render it; viewBox 64x56 → 3600 square.
MarkDetailed = amico.svg's full mark (bracket + internal accents),
viewBox 116 287 3377 3035 → 3600 square, for the Meet Amico card only.
- spinner.tsx (AmicoSpinner) + run-card.tsx (share-card SVG) both now
import MARK_PATH instead of carrying their own copies — run-card was a
fourth private copy of the old glyph; its transform is recalibrated
(scale 0.55 → 0.011) for the 3600-unit space.
- favicon/amico.svg: reduced bracket on the yellow chip, viewBox 3600,
path kept byte-identical to MARK_PATH.
- logo.css: aspect-ratio 8/7 → 1/1 (mark is square now).
- Small contexts use the reduced mark, the Meet Amico card uses the
detailed one — matching amicode's own small/large split.
Rebased onto local/amicode (picks up PR #8; AMICODE-PATCHES.md conflict
resolved, entry 15 rewritten for the final geometry).
Checks: bun turbo typecheck (ui+app) green; ui bun test src 95 pass;
app vite build clean — new mark path in the bundle, old geometry and the
64x56 viewBox gone (0 chunks), favicon carries the new path.
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
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

@kateebonner
, '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

amicode(home): fix silent dead-end on 'Open chat' with no tracked projects - #8

Merged
kateebonner merged 1 commit into
local/amicodefrom
kate/home-open-chat-empty-projects
Jul 8, 2026
Merged

amicode(home): fix silent dead-end on 'Open chat' with no tracked projects#8
kateebonner merged 1 commit into
local/amicodefrom
kate/home-open-chat-empty-projects

Conversation

@kateebonner

Copy link
Copy Markdown
Contributor

Bug

On a fresh browser profile pointed at a bare opencode serve, the home page's primary CTA — the Meet-Amico card and its Open chat button — does nothing. No navigation, no error.

Root cause (packages/app/src/pages/home.tsx, fork wiring from 5ef6b7e): startWithPrompt needs newSessionProject(), which resolves from the persisted client-side project list (localStorage). On a fresh profile that list is empty, so the !project branch calls openNewSession() — which needs the same empty newSessionProject() and hits if (!conn || !project) return. Silent no-op.

Hit live on 2026-07-08 driving the web UI against an opencode serve on a scratch directory (Pasqal connector testing).

Fix

When no project is tracked, fall back to the focused server's own working directory — focusedSync().data.path.directory, synced from GET /path (defaults to "" until loaded, so the falsy guard holds). Open + touch it as a project (self-healing: the home page tracks it from then on), then start the draft with the prompt preserved.

Deliberately notsync.data.project: the server's "global" project record has worktree: "/" — falling back to "first server project" would open a session on the filesystem root.

Verification

  • New regression spec e2e/regression/home-open-chat-empty-projects.spec.ts: real UI against the mocked server, no localStorage seed (the regression condition), clicks the CTA, expects navigation to /new-session?draftId= and the cwd persisted as a tracked project. Verified failing on the unfixed code, passing with the fix.
  • tsgo -b clean (also re-run by the pre-push hook)
  • bun run test:unit: 376 pass / 0 fail
  • Locator note: the whole Meet-Amico card is also a role=button whose accessible name contains "Open chat" — the spec uses exact: true.
  • Playwright harness note: the config reuses any server on port 3000; run with PLAYWRIGHT_PORT=<free port> if something else holds it (the harmoniqs website dev server did).

Patch-stack entry added to AMICODE-PATCHES.md (entry 9). No vendor bump in amicode implied by this PR — the extension pins local e9b695191; bump on the next scheduled vendor refresh.

🤖 Generated with Claude Code

…jects
On a fresh browser profile against a bare `opencode serve`, the home
page's primary CTA (Meet-Amico card / "Open chat") did nothing: the
persisted client-side project list is empty, so startWithPrompt fell
through to openNewSession(), which needs the same newSessionProject()
that just came back empty and silently returns.
Fall back to the focused server's own working directory, synced from
GET /path (.directory; "" until loaded, so the guard holds). Open and
touch it as a project — self-healing: the home page tracks it from then
on — and start the draft with the prompt preserved. Deliberately not
sync.data.project: the server's "global" record has worktree "/".
Regression spec drives the real UI against a mocked server with no
localStorage seed; verified failing on the unfixed code and passing
with the fix. tsgo -b clean; bun test:unit 376 pass.
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
@kateebonner
kateebonner merged commit 99a5918 into local/amicodeJul 8, 2026
0 of 4 checks passed
Rchari1 added a commit that referenced this pull request Jul 9, 2026
…mo udd hit exactly this) + trunk
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
kateebonner added a commit that referenced this pull request Jul 9, 2026
…99
The fork rendered the old "digi" pixel-H mark in four independent copies
while amicode redesigned its mark (PR #99). This unifies them to a single
MARK_PATH and syncs the geometry to #99's FINAL square mark (viewBox
0 0 3600 3600) — not the intermediate "hackathon" geometry an earlier
draft of this branch had copied, which #99 itself later abandoned.
- logo.tsx: MARK_PATH = amico_reduced.svg's outer-bracket path (fill-rule
evenodd). Mark/Splash render it; viewBox 64x56 → 3600 square.
MarkDetailed = amico.svg's full mark (bracket + internal accents),
viewBox 116 287 3377 3035 → 3600 square, for the Meet Amico card only.
- spinner.tsx (AmicoSpinner) + run-card.tsx (share-card SVG) both now
import MARK_PATH instead of carrying their own copies — run-card was a
fourth private copy of the old glyph; its transform is recalibrated
(scale 0.55 → 0.011) for the 3600-unit space.
- favicon/amico.svg: reduced bracket on the yellow chip, viewBox 3600,
path kept byte-identical to MARK_PATH.
- logo.css: aspect-ratio 8/7 → 1/1 (mark is square now).
- Small contexts use the reduced mark, the Meet Amico card uses the
detailed one — matching amicode's own small/large split.
Rebased onto local/amicode (picks up PR #8; AMICODE-PATCHES.md conflict
resolved, entry 15 rewritten for the final geometry).
Checks: bun turbo typecheck (ui+app) green; ui bun test src 95 pass;
app vite build clean — new mark path in the bundle, old geometry and the
64x56 viewBox gone (0 chunks), favicon carries the new path.
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
kateebonner added a commit that referenced this pull request Jul 9, 2026
…99
The fork rendered the old "digi" pixel-H mark in four independent copies
while amicode redesigned its mark (PR #99). This unifies them to a single
MARK_PATH and syncs the geometry to #99's FINAL square mark (viewBox
0 0 3600 3600) — not the intermediate "hackathon" geometry an earlier
draft of this branch had copied, which #99 itself later abandoned.
- logo.tsx: MARK_PATH = amico_reduced.svg's outer-bracket path (fill-rule
evenodd). Mark/Splash render it; viewBox 64x56 → 3600 square.
MarkDetailed = amico.svg's full mark (bracket + internal accents),
viewBox 116 287 3377 3035 → 3600 square, for the Meet Amico card only.
- spinner.tsx (AmicoSpinner) + run-card.tsx (share-card SVG) both now
import MARK_PATH instead of carrying their own copies — run-card was a
fourth private copy of the old glyph; its transform is recalibrated
(scale 0.55 → 0.011) for the 3600-unit space.
- favicon/amico.svg: reduced bracket on the yellow chip, viewBox 3600,
path kept byte-identical to MARK_PATH.
- logo.css: aspect-ratio 8/7 → 1/1 (mark is square now).
- Small contexts use the reduced mark, the Meet Amico card uses the
detailed one — matching amicode's own small/large split.
Rebased onto local/amicode (picks up PR #8; AMICODE-PATCHES.md conflict
resolved, entry 15 rewritten for the final geometry).
Checks: bun turbo typecheck (ui+app) green; ui bun test src 95 pass;
app vite build clean — new mark path in the bundle, old geometry and the
64x56 viewBox gone (0 chunks), favicon carries the new path.
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
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

@kateebonner
, '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

amicode(home): fix silent dead-end on 'Open chat' with no tracked projects - #8

Merged
kateebonner merged 1 commit into
local/amicodefrom
kate/home-open-chat-empty-projects
Jul 8, 2026
Merged

amicode(home): fix silent dead-end on 'Open chat' with no tracked projects#8
kateebonner merged 1 commit into
local/amicodefrom
kate/home-open-chat-empty-projects

Conversation

@kateebonner

Copy link
Copy Markdown
Contributor

Bug

On a fresh browser profile pointed at a bare opencode serve, the home page's primary CTA — the Meet-Amico card and its Open chat button — does nothing. No navigation, no error.

Root cause (packages/app/src/pages/home.tsx, fork wiring from 5ef6b7e): startWithPrompt needs newSessionProject(), which resolves from the persisted client-side project list (localStorage). On a fresh profile that list is empty, so the !project branch calls openNewSession() — which needs the same empty newSessionProject() and hits if (!conn || !project) return. Silent no-op.

Hit live on 2026-07-08 driving the web UI against an opencode serve on a scratch directory (Pasqal connector testing).

Fix

When no project is tracked, fall back to the focused server's own working directory — focusedSync().data.path.directory, synced from GET /path (defaults to "" until loaded, so the falsy guard holds). Open + touch it as a project (self-healing: the home page tracks it from then on), then start the draft with the prompt preserved.

Deliberately notsync.data.project: the server's "global" project record has worktree: "/" — falling back to "first server project" would open a session on the filesystem root.

Verification

  • New regression spec e2e/regression/home-open-chat-empty-projects.spec.ts: real UI against the mocked server, no localStorage seed (the regression condition), clicks the CTA, expects navigation to /new-session?draftId= and the cwd persisted as a tracked project. Verified failing on the unfixed code, passing with the fix.
  • tsgo -b clean (also re-run by the pre-push hook)
  • bun run test:unit: 376 pass / 0 fail
  • Locator note: the whole Meet-Amico card is also a role=button whose accessible name contains "Open chat" — the spec uses exact: true.
  • Playwright harness note: the config reuses any server on port 3000; run with PLAYWRIGHT_PORT=<free port> if something else holds it (the harmoniqs website dev server did).

Patch-stack entry added to AMICODE-PATCHES.md (entry 9). No vendor bump in amicode implied by this PR — the extension pins local e9b695191; bump on the next scheduled vendor refresh.

🤖 Generated with Claude Code

…jects
On a fresh browser profile against a bare `opencode serve`, the home
page's primary CTA (Meet-Amico card / "Open chat") did nothing: the
persisted client-side project list is empty, so startWithPrompt fell
through to openNewSession(), which needs the same newSessionProject()
that just came back empty and silently returns.
Fall back to the focused server's own working directory, synced from
GET /path (.directory; "" until loaded, so the guard holds). Open and
touch it as a project — self-healing: the home page tracks it from then
on — and start the draft with the prompt preserved. Deliberately not
sync.data.project: the server's "global" record has worktree "/".
Regression spec drives the real UI against a mocked server with no
localStorage seed; verified failing on the unfixed code and passing
with the fix. tsgo -b clean; bun test:unit 376 pass.
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
@kateebonner
kateebonner merged commit 99a5918 into local/amicodeJul 8, 2026
0 of 4 checks passed
Rchari1 added a commit that referenced this pull request Jul 9, 2026
…mo udd hit exactly this) + trunk
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
kateebonner added a commit that referenced this pull request Jul 9, 2026
…99
The fork rendered the old "digi" pixel-H mark in four independent copies
while amicode redesigned its mark (PR #99). This unifies them to a single
MARK_PATH and syncs the geometry to #99's FINAL square mark (viewBox
0 0 3600 3600) — not the intermediate "hackathon" geometry an earlier
draft of this branch had copied, which #99 itself later abandoned.
- logo.tsx: MARK_PATH = amico_reduced.svg's outer-bracket path (fill-rule
evenodd). Mark/Splash render it; viewBox 64x56 → 3600 square.
MarkDetailed = amico.svg's full mark (bracket + internal accents),
viewBox 116 287 3377 3035 → 3600 square, for the Meet Amico card only.
- spinner.tsx (AmicoSpinner) + run-card.tsx (share-card SVG) both now
import MARK_PATH instead of carrying their own copies — run-card was a
fourth private copy of the old glyph; its transform is recalibrated
(scale 0.55 → 0.011) for the 3600-unit space.
- favicon/amico.svg: reduced bracket on the yellow chip, viewBox 3600,
path kept byte-identical to MARK_PATH.
- logo.css: aspect-ratio 8/7 → 1/1 (mark is square now).
- Small contexts use the reduced mark, the Meet Amico card uses the
detailed one — matching amicode's own small/large split.
Rebased onto local/amicode (picks up PR #8; AMICODE-PATCHES.md conflict
resolved, entry 15 rewritten for the final geometry).
Checks: bun turbo typecheck (ui+app) green; ui bun test src 95 pass;
app vite build clean — new mark path in the bundle, old geometry and the
64x56 viewBox gone (0 chunks), favicon carries the new path.
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
kateebonner added a commit that referenced this pull request Jul 9, 2026
…99
The fork rendered the old "digi" pixel-H mark in four independent copies
while amicode redesigned its mark (PR #99). This unifies them to a single
MARK_PATH and syncs the geometry to #99's FINAL square mark (viewBox
0 0 3600 3600) — not the intermediate "hackathon" geometry an earlier
draft of this branch had copied, which #99 itself later abandoned.
- logo.tsx: MARK_PATH = amico_reduced.svg's outer-bracket path (fill-rule
evenodd). Mark/Splash render it; viewBox 64x56 → 3600 square.
MarkDetailed = amico.svg's full mark (bracket + internal accents),
viewBox 116 287 3377 3035 → 3600 square, for the Meet Amico card only.
- spinner.tsx (AmicoSpinner) + run-card.tsx (share-card SVG) both now
import MARK_PATH instead of carrying their own copies — run-card was a
fourth private copy of the old glyph; its transform is recalibrated
(scale 0.55 → 0.011) for the 3600-unit space.
- favicon/amico.svg: reduced bracket on the yellow chip, viewBox 3600,
path kept byte-identical to MARK_PATH.
- logo.css: aspect-ratio 8/7 → 1/1 (mark is square now).
- Small contexts use the reduced mark, the Meet Amico card uses the
detailed one — matching amicode's own small/large split.
Rebased onto local/amicode (picks up PR #8; AMICODE-PATCHES.md conflict
resolved, entry 15 rewritten for the final geometry).
Checks: bun turbo typecheck (ui+app) green; ui bun test src 95 pass;
app vite build clean — new mark path in the bundle, old geometry and the
64x56 viewBox gone (0 chunks), favicon carries the new path.
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
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

@kateebonner
, '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

amicode(home): fix silent dead-end on 'Open chat' with no tracked projects - #8

Merged
kateebonner merged 1 commit into
local/amicodefrom
kate/home-open-chat-empty-projects
Jul 8, 2026
Merged

amicode(home): fix silent dead-end on 'Open chat' with no tracked projects#8
kateebonner merged 1 commit into
local/amicodefrom
kate/home-open-chat-empty-projects

Conversation

@kateebonner

Copy link
Copy Markdown
Contributor

Bug

On a fresh browser profile pointed at a bare opencode serve, the home page's primary CTA — the Meet-Amico card and its Open chat button — does nothing. No navigation, no error.

Root cause (packages/app/src/pages/home.tsx, fork wiring from 5ef6b7e): startWithPrompt needs newSessionProject(), which resolves from the persisted client-side project list (localStorage). On a fresh profile that list is empty, so the !project branch calls openNewSession() — which needs the same empty newSessionProject() and hits if (!conn || !project) return. Silent no-op.

Hit live on 2026-07-08 driving the web UI against an opencode serve on a scratch directory (Pasqal connector testing).

Fix

When no project is tracked, fall back to the focused server's own working directory — focusedSync().data.path.directory, synced from GET /path (defaults to "" until loaded, so the falsy guard holds). Open + touch it as a project (self-healing: the home page tracks it from then on), then start the draft with the prompt preserved.

Deliberately notsync.data.project: the server's "global" project record has worktree: "/" — falling back to "first server project" would open a session on the filesystem root.

Verification

  • New regression spec e2e/regression/home-open-chat-empty-projects.spec.ts: real UI against the mocked server, no localStorage seed (the regression condition), clicks the CTA, expects navigation to /new-session?draftId= and the cwd persisted as a tracked project. Verified failing on the unfixed code, passing with the fix.
  • tsgo -b clean (also re-run by the pre-push hook)
  • bun run test:unit: 376 pass / 0 fail
  • Locator note: the whole Meet-Amico card is also a role=button whose accessible name contains "Open chat" — the spec uses exact: true.
  • Playwright harness note: the config reuses any server on port 3000; run with PLAYWRIGHT_PORT=<free port> if something else holds it (the harmoniqs website dev server did).

Patch-stack entry added to AMICODE-PATCHES.md (entry 9). No vendor bump in amicode implied by this PR — the extension pins local e9b695191; bump on the next scheduled vendor refresh.

🤖 Generated with Claude Code

…jects
On a fresh browser profile against a bare `opencode serve`, the home
page's primary CTA (Meet-Amico card / "Open chat") did nothing: the
persisted client-side project list is empty, so startWithPrompt fell
through to openNewSession(), which needs the same newSessionProject()
that just came back empty and silently returns.
Fall back to the focused server's own working directory, synced from
GET /path (.directory; "" until loaded, so the guard holds). Open and
touch it as a project — self-healing: the home page tracks it from then
on — and start the draft with the prompt preserved. Deliberately not
sync.data.project: the server's "global" record has worktree "/".
Regression spec drives the real UI against a mocked server with no
localStorage seed; verified failing on the unfixed code and passing
with the fix. tsgo -b clean; bun test:unit 376 pass.
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
@kateebonner
kateebonner merged commit 99a5918 into local/amicodeJul 8, 2026
0 of 4 checks passed
Rchari1 added a commit that referenced this pull request Jul 9, 2026
…mo udd hit exactly this) + trunk
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
kateebonner added a commit that referenced this pull request Jul 9, 2026
…99
The fork rendered the old "digi" pixel-H mark in four independent copies
while amicode redesigned its mark (PR #99). This unifies them to a single
MARK_PATH and syncs the geometry to #99's FINAL square mark (viewBox
0 0 3600 3600) — not the intermediate "hackathon" geometry an earlier
draft of this branch had copied, which #99 itself later abandoned.
- logo.tsx: MARK_PATH = amico_reduced.svg's outer-bracket path (fill-rule
evenodd). Mark/Splash render it; viewBox 64x56 → 3600 square.
MarkDetailed = amico.svg's full mark (bracket + internal accents),
viewBox 116 287 3377 3035 → 3600 square, for the Meet Amico card only.
- spinner.tsx (AmicoSpinner) + run-card.tsx (share-card SVG) both now
import MARK_PATH instead of carrying their own copies — run-card was a
fourth private copy of the old glyph; its transform is recalibrated
(scale 0.55 → 0.011) for the 3600-unit space.
- favicon/amico.svg: reduced bracket on the yellow chip, viewBox 3600,
path kept byte-identical to MARK_PATH.
- logo.css: aspect-ratio 8/7 → 1/1 (mark is square now).
- Small contexts use the reduced mark, the Meet Amico card uses the
detailed one — matching amicode's own small/large split.
Rebased onto local/amicode (picks up PR #8; AMICODE-PATCHES.md conflict
resolved, entry 15 rewritten for the final geometry).
Checks: bun turbo typecheck (ui+app) green; ui bun test src 95 pass;
app vite build clean — new mark path in the bundle, old geometry and the
64x56 viewBox gone (0 chunks), favicon carries the new path.
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
kateebonner added a commit that referenced this pull request Jul 9, 2026
…99
The fork rendered the old "digi" pixel-H mark in four independent copies
while amicode redesigned its mark (PR #99). This unifies them to a single
MARK_PATH and syncs the geometry to #99's FINAL square mark (viewBox
0 0 3600 3600) — not the intermediate "hackathon" geometry an earlier
draft of this branch had copied, which #99 itself later abandoned.
- logo.tsx: MARK_PATH = amico_reduced.svg's outer-bracket path (fill-rule
evenodd). Mark/Splash render it; viewBox 64x56 → 3600 square.
MarkDetailed = amico.svg's full mark (bracket + internal accents),
viewBox 116 287 3377 3035 → 3600 square, for the Meet Amico card only.
- spinner.tsx (AmicoSpinner) + run-card.tsx (share-card SVG) both now
import MARK_PATH instead of carrying their own copies — run-card was a
fourth private copy of the old glyph; its transform is recalibrated
(scale 0.55 → 0.011) for the 3600-unit space.
- favicon/amico.svg: reduced bracket on the yellow chip, viewBox 3600,
path kept byte-identical to MARK_PATH.
- logo.css: aspect-ratio 8/7 → 1/1 (mark is square now).
- Small contexts use the reduced mark, the Meet Amico card uses the
detailed one — matching amicode's own small/large split.
Rebased onto local/amicode (picks up PR #8; AMICODE-PATCHES.md conflict
resolved, entry 15 rewritten for the final geometry).
Checks: bun turbo typecheck (ui+app) green; ui bun test src 95 pass;
app vite build clean — new mark path in the bundle, old geometry and the
64x56 viewBox gone (0 chunks), favicon carries the new path.
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
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

@kateebonner