chore: extract apps/mac + apps/chrome to lobu-ai/owletto#784
Conversation
Owletto becomes a separate private repo (renamed from lobu-ai/owletto-web). Mac app and Chrome extension history preserved via git-filter-repo into the new repo; lobu engine + connectors stay here. - Rename submodule URL packages/web → lobu-ai/owletto - Bump submodule pointer to owletto/main HEAD that includes the import merge - Drop apps/mac/, apps/chrome/, .github/workflows/mac-release.yml - Update submodule drift check, setup-submodule action, and CI comments - Update cross-repo references in code comments and personal-mode-auth plan - Land strategic plan at docs/plans/owletto.md
|
You have reached your Codex usage limits for code reviews. You can see your limits in the Codex usage dashboard. |
|
Note Reviews pausedIt looks like this branch is under active development. To avoid overwhelming you with review comments due to an influx of new commits, CodeRabbit has automatically paused this review. You can configure this behavior by changing the Use the following commands to manage reviews:
Use the checkboxes below for quick actions:
📝 WalkthroughWalkthroughThis PR migrates the macOS and Chrome extension implementations from the main lobu repository to a private ChangesSubmodule, CI, and workflow infrastructure
Source code migration and removals
Product planning and cross-repo documentation
Estimated code review effort🎯 4 (Complex) | ⏱️ ~60 minutes Possibly related PRs
Suggested labels
Poem
🚥 Pre-merge checks | ✅ 5✅ Passed checks (5 passed)
✏️ Tip: You can configure your own custom pre-merge checks in the settings. ✨ Finishing Touches🧪 Generate unit tests (beta)
Comment |
|
Codecov Report✅ All modified and coverable lines are covered by tests. 📢 Thoughts on this report? Let us know! |
There was a problem hiding this comment.
Actionable comments posted: 5
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.
Inline comments:
In `@docs/plans/owletto.md`:
- Around line 113-144: Add explicit language identifiers ("text") to the two
fenced code blocks: the ASCII diagram block that begins with
"┌────────────────────────────────────────────────────────────────┐" and the
directory tree block that begins with "owletto/"; replace the opening triple
backticks (```) with "```text" for each fenced block so markdownlint stops
complaining (leave the closing ``` as-is).
- Around line 191-201: The docs contain a contradiction: the "Proactive
precision: the 'should this interrupt' gate" section introduces an LLM interrupt
gate as a first-class v1 feature while the v1 scope elsewhere explicitly states
"No LLM interrupt gate"; resolve by reconciling the contract—either remove or
move the LLM gate content (the paragraph titled "Proactive precision: the
'should this interrupt' gate") out of the v1 plan and mark it as a future
v2/experimental feature, or adjust the v1 scope language to explicitly include a
lightweight/local LLM gate (e.g., "small + cheap" gate) and update the v1 scope
lines to match; ensure the edited sections reference the same concept name
("interrupt gate" / "LLM gate") so there is a single authoritative v1 contract.
- Line 1: Add a single-sentence memory entry to CLAUDE.md summarizing the
Owletto plan change: state that the Owletto repo is being split and adopting a
local-first architecture (e.g., "Owletto repo split and moving to a local-first
plan"). Edit the CLAUDE.md file to append this one-line sentence in the memory
section so it matches the guideline for "*.md" files.
In `@docs/plans/personal-mode-auth.md`:
- Around line 3-5: Replace the placeholder "`#TBD`" in the top-level note of
docs/plans/personal-mode-auth.md with a concrete migration reference: either the
exact migration date (e.g., "2026-06-01") or a specific PR/commit identifier
(e.g., "PR `#1234`" or commit SHA) that documents when the Mac app + Chrome
extension moved to lobu-ai/owletto; update the sentence so it reads clearly
(e.g., "as of PR `#1234` (2026-06-01)"), ensuring the change targets the note
containing the string "`#TBD`".
In `@packages/web`:
- Line 1: The submodule pointer for packages/web is currently pinned to a commit
not reachable from the owletto/main branch, causing the Submodule Drift gate to
fail; update the submodule reference for packages/web to a commit SHA that
exists on owletto/main (i.e., repin the gitlink in the repository metadata where
packages/web is referenced), commit that updated submodule SHA, and push and
rerun the drift/CI checks so the reachability check succeeds before merging.
🪄 Autofix (Beta)
Fix all unresolved CodeRabbit comments on this PR:
- Push a commit to this branch (recommended)
- Create a new PR with the fixes
ℹ️ Review info
⚙️ Run configuration
Configuration used: defaults
Review profile: CHILL
Plan: Pro Plus
Run ID: d927f571-6b52-4f09-a408-49279089682b
⛔ Files ignored due to path filters (11)
apps/mac/Lobu/Assets.xcassets/AppIcon.appiconset/icon_128x128.pngis excluded by!**/*.pngapps/mac/Lobu/Assets.xcassets/AppIcon.appiconset/icon_128x128@2x.pngis excluded by!**/*.pngapps/mac/Lobu/Assets.xcassets/AppIcon.appiconset/icon_16x16.pngis excluded by!**/*.pngapps/mac/Lobu/Assets.xcassets/AppIcon.appiconset/icon_16x16@2x.pngis excluded by!**/*.pngapps/mac/Lobu/Assets.xcassets/AppIcon.appiconset/icon_256x256.pngis excluded by!**/*.pngapps/mac/Lobu/Assets.xcassets/AppIcon.appiconset/icon_256x256@2x.pngis excluded by!**/*.pngapps/mac/Lobu/Assets.xcassets/AppIcon.appiconset/icon_32x32.pngis excluded by!**/*.pngapps/mac/Lobu/Assets.xcassets/AppIcon.appiconset/icon_32x32@2x.pngis excluded by!**/*.pngapps/mac/Lobu/Assets.xcassets/AppIcon.appiconset/icon_512x512.pngis excluded by!**/*.pngapps/mac/Lobu/Assets.xcassets/AppIcon.appiconset/icon_512x512@2x.pngis excluded by!**/*.pngapps/mac/Lobu/Assets.xcassets/MenuBarIcon.imageset/lobster-mark.svgis excluded by!**/*.svg
📒 Files selected for processing (52)
.github/actions/setup-submodule/action.yml.github/workflows/ci.yml.github/workflows/mac-release.yml.github/workflows/submodule-drift.yml.gitmodulesAGENTS.mdapps/chrome/README.mdapps/chrome/SCOPE.mdapps/chrome/background.jsapps/chrome/bridge.jsapps/chrome/config.jsapps/chrome/manifest.jsonapps/chrome/pairing.htmlapps/chrome/pairing.jsapps/chrome/permissions.htmlapps/chrome/permissions.jsapps/chrome/sidepanel.htmlapps/chrome/sidepanel.jsapps/mac/Lobu.xcodeproj/project.pbxprojapps/mac/Lobu.xcodeproj/project.xcworkspace/xcshareddata/swiftpm/Package.resolvedapps/mac/Lobu.xcodeproj/xcshareddata/xcschemes/Lobu.xcschemeapps/mac/Lobu/AppState.swiftapps/mac/Lobu/Assets.xcassets/AppIcon.appiconset/Contents.jsonapps/mac/Lobu/Assets.xcassets/Contents.jsonapps/mac/Lobu/Assets.xcassets/MenuBarIcon.imageset/Contents.jsonapps/mac/Lobu/BrowserProfileManager.swiftapps/mac/Lobu/BrowserProfilesView.swiftapps/mac/Lobu/ChromeBridgeHost.swiftapps/mac/Lobu/HealthKitSyncService.swiftapps/mac/Lobu/Info.plistapps/mac/Lobu/KeychainTokenStore.swiftapps/mac/Lobu/KnowledgeKitReader.swiftapps/mac/Lobu/Lobu.entitlementsapps/mac/Lobu/LobuApp.swiftapps/mac/Lobu/LobuClient.swiftapps/mac/Lobu/LobuUpdater.swiftapps/mac/Lobu/LocalDirectorySyncService.swiftapps/mac/Lobu/LocalLobuRunner.swiftapps/mac/Lobu/MenuBarContent.swiftapps/mac/Lobu/OAuthClient.swiftapps/mac/Lobu/ObsidianVaultManager.swiftapps/mac/Lobu/PhotosSyncService.swiftapps/mac/Lobu/ScreenTimeSyncService.swiftapps/mac/Lobu/WhatsAppLocalSyncService.swiftapps/mac/sparkle/.gitignoreapps/mac/sparkle/README.mdapps/mac/sparkle/update-appcast.pydocs/plans/owletto.mddocs/plans/personal-mode-auth.mdpackages/connectors/src/chrome_tabs.tspackages/core/src/capabilities.tspackages/web
💤 Files with no reviewable changes (42)
- apps/mac/Lobu/Assets.xcassets/MenuBarIcon.imageset/Contents.json
- apps/mac/Lobu/Lobu.entitlements
- apps/mac/Lobu/Assets.xcassets/Contents.json
- apps/mac/Lobu.xcodeproj/project.pbxproj
- apps/mac/Lobu/BrowserProfileManager.swift
- apps/chrome/SCOPE.md
- apps/chrome/permissions.html
- apps/chrome/bridge.js
- apps/chrome/background.js
- apps/mac/Lobu/Assets.xcassets/AppIcon.appiconset/Contents.json
- apps/mac/Lobu/LobuApp.swift
- apps/chrome/manifest.json
- apps/mac/Lobu/Info.plist
- apps/chrome/pairing.html
- apps/mac/Lobu.xcodeproj/project.xcworkspace/xcshareddata/swiftpm/Package.resolved
- apps/mac/sparkle/.gitignore
- apps/chrome/permissions.js
- apps/chrome/config.js
- apps/mac/Lobu/ObsidianVaultManager.swift
- apps/mac/sparkle/update-appcast.py
- .github/workflows/mac-release.yml
- apps/chrome/README.md
- apps/chrome/pairing.js
- apps/mac/Lobu/KeychainTokenStore.swift
- apps/mac/sparkle/README.md
- apps/mac/Lobu.xcodeproj/xcshareddata/xcschemes/Lobu.xcscheme
- apps/mac/Lobu/WhatsAppLocalSyncService.swift
- apps/mac/Lobu/BrowserProfilesView.swift
- apps/mac/Lobu/LocalLobuRunner.swift
- apps/mac/Lobu/ChromeBridgeHost.swift
- apps/mac/Lobu/PhotosSyncService.swift
- apps/mac/Lobu/KnowledgeKitReader.swift
- apps/mac/Lobu/AppState.swift
- apps/chrome/sidepanel.js
- apps/mac/Lobu/HealthKitSyncService.swift
- apps/mac/Lobu/MenuBarContent.swift
- apps/mac/Lobu/LobuUpdater.swift
- apps/mac/Lobu/ScreenTimeSyncService.swift
- apps/mac/Lobu/LocalDirectorySyncService.swift
- apps/mac/Lobu/OAuthClient.swift
- apps/mac/Lobu/LobuClient.swift
- apps/chrome/sidepanel.html
| @@ -0,0 +1,506 @@ | |||
| # Owletto | |||
There was a problem hiding this comment.
🛠️ Refactor suggestion | 🟠 Major | ⚡ Quick win
Record this plan change in CLAUDE.md memory as a single sentence.
Please add a one-line memory entry capturing the Owletto repo split/local-first plan context.
As per coding guidelines "**/*.md: Add memory to CLAUDE.md as a single sentence when documenting important context`."
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.
In `@docs/plans/owletto.md` at line 1, Add a single-sentence memory entry to
CLAUDE.md summarizing the Owletto plan change: state that the Owletto repo is
being split and adopting a local-first architecture (e.g., "Owletto repo split
and moving to a local-first plan"). Edit the CLAUDE.md file to append this
one-line sentence in the memory section so it matches the guideline for "*.md"
files.
| > **Note:** The Mac app + Chrome extension live in `lobu-ai/owletto` as of | ||
| > #TBD. Mac-side changes specified in this plan happen in that repo; | ||
| > server/gateway/auth changes (the majority of this plan) still happen here |
There was a problem hiding this comment.
Replace #TBD with a concrete migration date or PR reference.
The top-level note currently leaves repo-move timing unresolved, which weakens this doc as an implementation reference.
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.
In `@docs/plans/personal-mode-auth.md` around lines 3 - 5, Replace the placeholder
"`#TBD`" in the top-level note of docs/plans/personal-mode-auth.md with a concrete
migration reference: either the exact migration date (e.g., "2026-06-01") or a
specific PR/commit identifier (e.g., "PR `#1234`" or commit SHA) that documents
when the Mac app + Chrome extension moved to lobu-ai/owletto; update the
sentence so it reads clearly (e.g., "as of PR `#1234` (2026-06-01)"), ensuring the
change targets the note containing the string "`#TBD`".
The previous commit incorrectly deleted mac-release.yml under the assumption
that Mac releases would move to owletto. They can't: owletto is private, so
its GitHub Releases require auth to download, breaking the
releases/latest/download/Lobu.dmg pattern and the Sparkle appcast URL that
existing installed apps hardcode in Info.plist.
Keep mac-release.yml here (public) and reach the Mac source via the owletto
submodule:
- Add the existing setup-submodule action so the deploy key clones owletto.
- Update xcodebuild -project paths from apps/mac/Lobu.xcodeproj to
packages/web/apps/mac/Lobu.xcodeproj.
- Update the Sparkle update-appcast.py path similarly.
- Header comment now documents the private-source-public-release split.
No secret migration needed — the workflow already runs in lobu where all the
Apple signing + Sparkle secrets live.
There was a problem hiding this comment.
Actionable comments posted: 1
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.
Inline comments:
In @.github/workflows/mac-release.yml:
- Line 102: The workflow references the non-existent Xcode project
"Lobu.xcodeproj" in the mac-release.yml xcodebuild steps, which will cause the
job to fail; either ensure the mac submodule is initialized and contains the
expected Lobu.xcodeproj or update the mac-release.yml xcodebuild invocations to
point to the correct Xcode project/target in this repo (or skip the mac build
when the project is absent). Locate the xcodebuild command lines that reference
"Lobu.xcodeproj" and replace them with the actual project path/target used in
this repository, or add a pre-check step that verifies the project exists (and
exits with a clear message) before running xcodebuild so the workflow fails fast
and clearly if the submodule/project is missing.
🪄 Autofix (Beta)
Fix all unresolved CodeRabbit comments on this PR:
- Push a commit to this branch (recommended)
- Create a new PR with the fixes
ℹ️ Review info
⚙️ Run configuration
Configuration used: defaults
Review profile: CHILL
Plan: Pro Plus
Run ID: ba308462-3820-49e0-bd5c-e5fdbfe96e07
📒 Files selected for processing (1)
.github/workflows/mac-release.yml
Post-extraction verificationCodeQL Swift orphanDisabled `swift` in the repo's CodeQL default-setup language list via API (now: `actions, javascript, javascript-typescript, python, typescript`). The `Analyze (swift)` CI job will no longer run. Owletto brand markShipped in `lobu-ai/owletto@f759d61` — `<··>` owl in the existing Lobu orange gradient (`#ff4b00` → `#ff8a1a`) for "Powered by Lobu" family kinship. The two-dot motif between the brackets is what makes it read as an owl face. Files updated in owletto repo:
`lobu-og.png` (Open Graph share image, 1200×630) intentionally untouched — needs separate layout work for a wider format. This PR's submodule pointer is bumped accordingly to include the brand-mark commit. Mac release smoke test (workflow_dispatch on this branch, version=0.0.0-smoke)Verified end-to-end that the path migration works:
The Sparkle step failed identically on the most recent `main` run (May 14, run 25841148752 — same step, same ~1.5s timeout). Not introduced by this PR; a separate follow-up. Draft release `lobu-v0.0.0-smoke` + tag deleted post-test. Remaining truly out-of-scope follow-ups
|
Addresses pi review findings on PR #784: 1. Fail fast on stubbed submodule. setup-submodule writes a stub package.json when OWLETTO_WEB_DEPLOY_KEY is missing — fine for fork CI, catastrophic for a release. Make it fatal. 2. Assert packages/web origin URL resolves to lobu-ai/owletto. If .gitmodules drifts or the submodule URL changes, surface it before we publish an artifact from the wrong codebase. 3. Assert the Mac project + Info.plist paths actually exist at the pinned SHA. A silent rename inside owletto (lobster-mark.svg → owletto-mark.svg style) would otherwise only surface inside xcodebuild or sign_update. 4. Move scripts/sparkle/update-appcast.py back into lobu. Release infrastructure for a public-repo release pipeline shouldn't live in a private submodule where an owletto-side cleanup could silently delete it. 5. Update docs/plans/owletto.md to reflect the actual posture: owletto product (Mac app + Chrome extension + web SPA) is closed-source + private; Lobu engine stays Apache-2.0 OSS. The earlier "OSS / public repo" framing was from before we settled on closed product surface.
Pi review — applied + deferredRan `pi -p` on the PR. Triaged the 8 findings: Fixed in this PR (commit `5ab5555`)Pi #2 — fail fast on stubbed submodule. Mac release now hard-fails when `OWLETTO_WEB_DEPLOY_KEY` is missing/invalid, when `packages/web` origin doesn't resolve to `lobu-ai/owletto`, and when expected Mac paths don't exist at the pinned SHA. See `Verify release contract` step in `.github/workflows/mac-release.yml`. Pi #3 — release infra in private submodule was fragile. Moved `update-appcast.py` to `scripts/sparkle/update-appcast.py` in this public repo. Owletto-side cleanup can no longer silently delete the release pipeline's script. Pi #5 + #6 — submodule URL drift not asserted. The new `Verify release contract` step asserts `git -C packages/web config remote.origin.url` resolves to `lobu-ai/owletto.git` before any build step runs. Pi #8 — plan doc contradicted reality. `docs/plans/owletto.md` now correctly says owletto product (Mac/extension/SPA) is closed-source + private, Lobu engine stays Apache-2.0 OSS. The earlier "new public OSS repo" framing was pre-decision. Pi #4 — Sparkle smoke test was already doneSmoke test ran earlier on this branch (`gh workflow run` against the pinned SHA, version=0.0.0-smoke). Result: setup-submodule + xcodebuild + DMG + release-attach all ✅. Sparkle step failed identically to the May 14 run on `main` — pre-existing, not introduced by this PR. Documented in the post-extraction verification comment above. Deferred (filed as follow-ups, not merge-blocking)Pi #1 — `packages/web` submodule mount is mis-named now that it contains Mac + Chrome source. Renaming the mount path is its own ~50-file PR (every workflow, tsconfig exclude, script reference) and is best bundled with renaming `@lobu/web` inside the owletto repo. Tracked separately. The release-contract path checks now serve as the guardrail Pi suggested in the interim. Pi #7 — owletto branch protection. Public lobu release pipeline now depends on a private repo never force-pushing or deleting `main`. Need to enable: no force-push on `main`, no branch deletion, and ideally a Mac-build CI job inside owletto on every PR. That's a GitHub settings change on the private repo, separate from this PR. NetThe PR now hard-fails before doing anything destructive (or producing a wrong/empty release artifact) when the submodule contract drifts. Release infra is back in the public repo. Plan doc matches reality. |
There was a problem hiding this comment.
Actionable comments posted: 1
♻️ Duplicate comments (3)
docs/plans/owletto.md (3)
272-272:⚠️ Potential issue | 🟡 Minor | ⚡ Quick winAdd language identifier to code block.
The directory tree code block is missing a language identifier. Add
textafter the opening backticks.-``` +```text owletto/ # private; renamed from owletto-web🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the rest with a brief reason, keep changes minimal, and validate. In `@docs/plans/owletto.md` at line 272, The markdown code block in docs/plans/owletto.md is missing a language identifier; update the opening triple-backtick for the directory tree to include the language tag "text" (i.e., change the backtick-only fence that precedes the line "owletto/ # private; renamed from owletto-web" to "```text") so the block is explicitly marked as plain text.
114-114:⚠️ Potential issue | 🟡 Minor | ⚡ Quick winAdd language identifier to code block.
The fenced code block is missing a language identifier, which violates markdown lint rules. Add
textafter the opening backticks.-``` +```text ┌────────────────────────────────────────────────────────────────┐🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the rest with a brief reason, keep changes minimal, and validate. In `@docs/plans/owletto.md` at line 114, The fenced code block that begins with ``` before the ASCII box needs a language identifier to satisfy markdown linting: change the opening fence from ``` to ```text so the block becomes a text-code block (i.e., replace the opening triple-backticks for the ASCII-art block with ```text).
192-202:⚠️ Potential issue | 🟠 Major | ⚡ Quick winResolve the v1 LLM interrupt gate contradiction.
This section describes the LLM interrupt gate as a "first-class step, not a heuristic" that runs between watcher-fire and surface events. However, the v1 scope explicitly states "No LLM interrupt gate in v1" (Line 64), the v1.1 out-of-scope section says "Add the gate in v1.1 if precision is still bad" (Lines 90-92), and the resolved decisions confirm "No LLM interrupt gate in v1" (Line 483).
The contradiction creates ambiguity about:
- Whether v1 implementation must include this gate
- What "per-watcher cooldowns + daily interrupt budget" (Line 64) means if the gate is also present
- Timeline and scope boundaries for M3-M5 milestones
Either remove this section entirely and move it to a "V2 Architecture" heading, or reconcile the v1 scope to explicitly include a lightweight local LLM gate and update Lines 64, 90-92, and 483 accordingly.
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the rest with a brief reason, keep changes minimal, and validate. In `@docs/plans/owletto.md` around lines 192 - 202, The "Proactive precision: the 'should this interrupt' gate" section conflicts with stated v1 scope; either remove/move this section to a V2 Architecture chapter or reconcile the v1 scope to include a lightweight local LLM gate. If you choose removal: delete this section and add a brief pointer in v2 architecture that describes the gate. If you choose reconciliation: update the "v1 scope" paragraph, the "v1.1 out-of-scope" note, and the "resolved decisions" entry to explicitly state a lightweight local LLM gate will run before surfacing (describe it as Haiku-tier/local-only, used only for interrupt filtering alongside per-watcher cooldowns and daily interrupt budget), and clarify timeline/milestone placement for M3–M5.
🧹 Nitpick comments (1)
docs/plans/owletto.md (1)
313-313: 💤 Low valueConsider clearer phrasing for signin work.
The term "unmandatory-signin work" is awkward. Consider "make-signin-optional work" or "optional-signin work" for clarity.
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the rest with a brief reason, keep changes minimal, and validate. In `@docs/plans/owletto.md` at line 313, Replace the awkward phrase "unmandatory-signin" with a clearer term like "optional-signin" (or "make-signin-optional") throughout the plan text; search for the exact token "unmandatory-signin" and update occurrences in the docs/plans/owletto.md content and branch instructions so the intent reads clearly (e.g., "Cut a branch in this repo that completes the optional-signin work").
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.
Inline comments:
In `@docs/plans/owletto.md`:
- Around line 159-165: The text is ambiguous about where the LocalSurface
adapter should live and how it integrates with gateway routing; update the doc
to state that LocalSurface is a distinct adapter placed in a new sibling
directory (e.g., packages/server/src/gateway/surfaces/) rather than inside
packages/server/src/gateway/connections/, and describe that it implements a
separate interface (LocalSurface) that the gateway recognizes alongside
Connection types; explain that the gateway's event router should treat
LocalSurface events by matching on a surface identity field (e.g., surfaceId)
and applying surface-specific filters (rather than channel/reply/history
semantics) so routing logic in the gateway checks event.source.type === 'local'
or event.surfaceId to dispatch to LocalSurface handlers without inheriting
chat-platform assumptions.
---
Duplicate comments:
In `@docs/plans/owletto.md`:
- Line 272: The markdown code block in docs/plans/owletto.md is missing a
language identifier; update the opening triple-backtick for the directory tree
to include the language tag "text" (i.e., change the backtick-only fence that
precedes the line "owletto/ # private; renamed from
owletto-web" to "```text") so the block is explicitly marked as plain text.
- Line 114: The fenced code block that begins with ``` before the ASCII box
needs a language identifier to satisfy markdown linting: change the opening
fence from ``` to ```text so the block becomes a text-code block (i.e., replace
the opening triple-backticks for the ASCII-art block with ```text).
- Around line 192-202: The "Proactive precision: the 'should this interrupt'
gate" section conflicts with stated v1 scope; either remove/move this section to
a V2 Architecture chapter or reconcile the v1 scope to include a lightweight
local LLM gate. If you choose removal: delete this section and add a brief
pointer in v2 architecture that describes the gate. If you choose
reconciliation: update the "v1 scope" paragraph, the "v1.1 out-of-scope" note,
and the "resolved decisions" entry to explicitly state a lightweight local LLM
gate will run before surfacing (describe it as Haiku-tier/local-only, used only
for interrupt filtering alongside per-watcher cooldowns and daily interrupt
budget), and clarify timeline/milestone placement for M3–M5.
---
Nitpick comments:
In `@docs/plans/owletto.md`:
- Line 313: Replace the awkward phrase "unmandatory-signin" with a clearer term
like "optional-signin" (or "make-signin-optional") throughout the plan text;
search for the exact token "unmandatory-signin" and update occurrences in the
docs/plans/owletto.md content and branch instructions so the intent reads
clearly (e.g., "Cut a branch in this repo that completes the optional-signin
work").
🪄 Autofix (Beta)
Fix all unresolved CodeRabbit comments on this PR:
- Push a commit to this branch (recommended)
- Create a new PR with the fixes
ℹ️ Review info
⚙️ Run configuration
Configuration used: defaults
Review profile: CHILL
Plan: Pro Plus
Run ID: 4fbe1390-13c8-4ba4-86ce-128402a685ce
📒 Files selected for processing (3)
.github/workflows/mac-release.ymldocs/plans/owletto.mdscripts/sparkle/update-appcast.py
| 3. **`LocalSurface` adapter (not a chat-platform connection).** Mac | ||
| canvas + native notifications are an event/UI bus, not a chat | ||
| transport. Forcing them through the existing chat-platform connection | ||
| abstraction would leak chat assumptions (channels, replies, | ||
| histories) into the surface. Define a parallel `LocalSurface` | ||
| adapter alongside `packages/server/src/gateway/connections/` — | ||
| filters on its own surface identity, no chat-shaped contract. |
There was a problem hiding this comment.
🛠️ Refactor suggestion | 🟠 Major | ⚡ Quick win
Clarify LocalSurface adapter placement and integration.
The phrasing "alongside packages/server/src/gateway/connections/" is ambiguous when the text also states it's NOT a chat-platform connection. Should LocalSurface live:
- Inside
packages/server/src/gateway/connections/as a parallel adapter type? - In a sibling directory like
packages/server/src/gateway/surfaces/? - Somewhere else entirely?
Additionally, specify how "filters on its own surface identity" integrates with the existing gateway event routing without inheriting chat-platform assumptions.
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.
In `@docs/plans/owletto.md` around lines 159 - 165, The text is ambiguous about
where the LocalSurface adapter should live and how it integrates with gateway
routing; update the doc to state that LocalSurface is a distinct adapter placed
in a new sibling directory (e.g., packages/server/src/gateway/surfaces/) rather
than inside packages/server/src/gateway/connections/, and describe that it
implements a separate interface (LocalSurface) that the gateway recognizes
alongside Connection types; explain that the gateway's event router should treat
LocalSurface events by matching on a surface identity field (e.g., surfaceId)
and applying surface-specific filters (rather than channel/reply/history
semantics) so routing logic in the gateway checks event.source.type === 'local'
or event.surfaceId to dispatch to LocalSurface handlers without inheriting
chat-platform assumptions.
Plan was an owletto product/strategy doc, not a Lobu engine plan. Moved to lobu-ai/owletto:docs/owletto-plan.md so it lives next to the code it describes (private, matches the rest of owletto's posture). Also bumps submodule pointer to pick up the relocated doc commit.
Pi second-pass found that 'set -x' at the top of the Sparkle step traces through the SPARKLE_ED_PRIVATE_KEY file write + sign_update invocation + the gh-pages clone URL containing GITHUB_TOKEN. GitHub Actions masks known secret strings in logs but we shouldn't rely on that masking for release correctness. Toggle xtrace selectively: on around curl/tar/sign_update path checks and around the python appcast script invocation; off around the key-file write, the sign_update execution, and the token-bearing git clone.
Final state — ready to mergePi second-pass reviewFound one new issue: `set -x` traced through SPARKLE_ED_PRIVATE_KEY handling + GITHUB_TOKEN-bearing git clone URL. Fixed in commit `87a517f` — xtrace now toggles off around the key file write, sign_update invocation, and gh-pages clone. All commits on this branch
Deferred items — all filed as issues
Owletto repo follow-ups landed in tandem
CIAll substantive checks green: typecheck, unit, frontend, build-test, check-drift, format-lint, Security tests (bun + vitest), Static security guards, CodeQL, Analyze (actions/js-ts/python), CodeRabbit, pr-title. Three red checks (integration, migrations, pr-size) are pre-existing on `main` and tracked separately. Smoke test`mac-release.yml` triggered against the pinned SHA: submodule init ✅, xcodebuild from `packages/web/apps/mac/` ✅, DMG build ✅, release attach ✅. Sparkle step fails for the unrelated credential reason in #788. Merging with `--squash --admin` per the established workflow. |
Summary
Owletto becomes its own private repo. This PR is the plumbing pivot — no product code changes.
apps/mac/andapps/chrome/move tolobu-ai/owletto(renamed fromlobu-ai/owletto-web). Full commit history preserved viagit filter-repo+ merge intoowletto/mainwith--allow-unrelated-histories(merge commit on owletto side:551ac9f).packages/websubmodule now points atlobu-ai/owletto.git(URL change in.gitmodules); pinned SHA bumped to the merge commit on owletto/main.mac-release.ymlstays in lobu, sources via the submodule pathpackages/web/apps/mac/. Owletto is private, so its GitHub Releases would require auth to download — releases ship from this public repo soreleases/latest/download/Lobu.dmgandlobu-ai.github.io/lobu/appcast.xmlstay reachable to anonymous users and existing installed apps. (The first commit on this branch incorrectly deleted the workflow; the second commit restores it with submodule paths.)owlettoinstead ofowletto-web.packages/core/src/capabilities.ts,packages/connectors/src/chrome_tabs.ts) and the personal-mode-auth plan updated to use cross-repo path references (lobu-ai/owletto: apps/mac/…).docs/plans/owletto.md.Old deprecated
lobu-ai/owletto(memory-server work) was renamed tolobu-ai/owletto-archiveseparately, freeing the name.What stays in lobu
chrome_tabswhich still defines the platform string).mac-release.yml— Mac DMG release pipeline, now sourcing through the submodule.What's now in owletto
apps/mac/— SwiftUI menubar app source.apps/chrome/— MV3 Chrome extension source.Follow-ups in owletto repo (out of scope here)
deploy/that still reference the oldowletto-webURL.apps/mac/Lobu/OAuthClient.swift+AppState.swift.Follow-ups in lobu (out of scope here)
LOBU_MODE=local, local-CLI executor, PGlite production path,lobu pull --local.packages/web→packages/owlettofor accuracy (touches every workflow + tsconfig reference; bundle with internal owletto-side package renames).Naming notes (intentionally deferred)
OWLETTO_WEB_DEPLOY_KEYis unchanged. Functionally fine (it's just a label, the key itself works for the renamed repo). Cosmetic rename can happen later.packages/webeven though the submodule now contains the Mac app + Chrome extension. Renaming the mount is a much bigger ripple (workflows, tsconfig, scripts) and is best paired with renaming@lobu/webinside the owletto repo. Out of scope here.Test plan
bun installcleanmake build-packagespassesmake typecheckpasses (strict, matches Dockerfile)packages/websubmodule resolves at the newlobu-ai/owletto.gitURLapps/mac/apps/chromereferences outside intentional cross-repo pathsowletto-webreferences outside CHANGELOG (historic)mac-release.ymlsmoke test (manual workflow_dispatch with a test version, optional — secrets unchanged so structurally same as before)Summary by CodeRabbit
Chores
lobu-ai/owlettorepositoryDocumentation