symbiot 0.62.0 → 0.63.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/CHANGELOG.md CHANGED
@@ -2,6 +2,14 @@
2
2
 
3
3
  What each Symbiot release brought, newest first. When Approve bumps the version, it writes that release here from the tasks it approved, worded as release notes by your connected AI (or in the tasks' own words without one). The app shows the releases newer than yours under "What's new" when it offers an update, and once more after you update.
4
4
 
5
+ ## 0.63.0
6
+
7
+ - **The Android app is built again.** 0.62.1's release went out without its APK: a link to a build folder on this computer had been committed by mistake, so GitHub's build couldn't make the folder. It's gone, and the ignore rule now covers a link as well as a folder. 0.63.0 carries 0.62.1's phone fix (setup going to **Your computer**).
8
+ - **Symbiot's new mark.** The app's own orb, lit the way Home lights it, with an S inside in the two colours Symbiot already speaks in: the silver of agents at work above, the amber of "needs you" below. It's everywhere: the app-menu, Start-menu and dock icon (in each look: Ferrofluid's black chrome, Glass's clear droplet, Pearl's mirror), the window and tab icon (a simpler drawing at small sizes), the app's header (the old green dot is gone), setup, the Windows, Mac and Linux installers (the Mac one inside Apple's icon grid), the tray and the Mac menu bar, the Android app and its notifications, and symbiot.co.za, which now has a sharing image for links.
9
+ ## 0.62.1
10
+
11
+ - **A phone that had Symbiot before goes to "Your computer" first.** Installing the new app over an older one kept the old app's setup, already started at "Meet Symbiot", so the phone went on to "Your AI" and asked to install Claude Code, and never offered to pair with your computer. An unfinished setup on a phone that isn't paired now opens on **Your computer** (scan the QR your computer shows, or type its address and code), once; "No computer" carries on as before. Checked on the Android emulator: 0.59.0, then 0.62.0 over it (the problem), then this over that (fixed).
12
+
5
13
  ## 0.62.0 — 2026-10-09
6
14
 
7
15
  - **Your phone shows your computer's work, and you can act on it there.** Pair Symbiot's Android app (or Symbiot in Termux) with your computer and the phone gets a droplet on Home, **On <your computer>**: your tasks, what needs you, your agents' questions, the work waiting for your Approve, and what Watch found (as notifications too). Tick and add tasks, answer an agent and approve from it. "Watch on your phone" is now **Your phone**, in Settings and in Setup.
package/README.md CHANGED
@@ -248,7 +248,7 @@ are inside it (the same builds Termux installs), and it shows Symbiot full scree
248
248
  with its own icon.
249
249
 
250
250
  - **Install:** on your phone, download `symbiot-aarch64.apk` from the
251
- [latest release](https://github.com/GarthGhostai/symbiot/releases/latest)
251
+ [latest release](https://github.com/GAWdessey/symbiot/releases/latest)
252
252
  (or copy `symbiot-<version>-aarch64.apk` over from a computer that built it)
253
253
  and open it (allow your browser or file manager to install apps). Android may warn that the
254
254
  app was built for an older version of Android. That's on purpose: it's what lets
package/desktop.mjs CHANGED
@@ -160,21 +160,15 @@ function autostartContent(node, script, platform = OS, path = process.env.PATH |
160
160
  // new Node, a moved install), so it never points at something gone.
161
161
  const launcherFile = (home = homedir()) => join(home, ".local", "share", "applications", "symbiot.desktop");
162
162
  const launcherIcon = (home = homedir()) => join(home, ".local", "share", "icons", "hicolor", "scalable", "apps", "symbiot.svg");
163
- const ICON_SRC = fileURLToPath(new URL("./icon.svg", import.meta.url));
164
- // The orb in each look: Ferrofluid (icon.svg, dark), Glass (clear, on a cool light
165
- // ground) and Pearl (white pearl, on a warm light ground). The app menu's icon and
166
- // the window's follow the look you pick (setLauncherLook).
167
- const LOOK_COLOURS = {
168
- glass: { bg: ["#F4F7FB", "#D9E1EC"], orb: ["#FFFFFF", "#C9D6E6", "#7F93AE"], rim: "#5B8DEF", glow: "#5B8DEF" },
169
- pearl: { bg: ["#F7F4EE", "#E6E0D5"], orb: ["#FFFFFF", "#ECE7DF", "#A99F92"], rim: "#C9A46A", glow: "#F2A541" },
170
- };
171
- function iconSvg(look = "ferro") {
172
- const base = readFileSync(ICON_SRC, "utf8"), c = LOOK_COLOURS[look];
173
- if (!c) return base;
174
- return base.replace('stop-color="#1B1D22"', `stop-color="${c.bg[0]}"`).replace('stop-color="#08090B"', `stop-color="${c.bg[1]}"`)
175
- .replace('stop-color="#3A3D44"', `stop-color="${c.orb[0]}"`).replace('stop-color="#121317"', `stop-color="${c.orb[1]}"`).replace('stop-color="#030304"', `stop-color="${c.orb[2]}"`)
176
- .replace('stop-color="#B0466E" stop-opacity="0.55"', `stop-color="${c.rim}" stop-opacity="0.45"`)
177
- .replace(/stop-color="#F2A541" stop-opacity="0\.16"/, `stop-color="${c.glow}" stop-opacity="0.18"`);
163
+ // Symbiot's mark in each look (icons/): the Home orb as that look draws it (Ferrofluid's
164
+ // black chrome, Glass's clear droplet, Pearl's mirror), with the S inside in the app's two
165
+ // signal colours: the silver of agents at work, the amber of "needs you". small: the
166
+ // drawing for 16-24 px (a browser tab, the header), with no reflections and a heavier S.
167
+ // The app menu's icon and the window's follow the look you pick (setLauncherLook).
168
+ const ICONS = fileURLToPath(new URL("./icons/", import.meta.url));
169
+ function iconSvg(look = "ferro", { small = false } = {}) {
170
+ const l = ["ferro", "glass", "pearl"].includes(look) ? look : "ferro";
171
+ return readFileSync(join(ICONS, `icon-${l}${small ? "-small" : ""}.svg`), "utf8");
178
172
  }
179
173
  // The look changed: the app menu's icon follows, if the app menu has Symbiot.
180
174
  function setLauncherLook(look, home = homedir()) {
package/home.mjs CHANGED
@@ -758,7 +758,19 @@ const ONB_STEPS_PHONE = ["computer", "welcome", "ai", "work", "agent", "apps", "
758
758
  const onbSteps = (app = ANDROID_APP, phone = PHONE) => (app ? ONB_STEPS_PHONE : phone ? ONB_STEPS.filter((s) => s !== "phone") : ONB_STEPS); // (Symbiot in Termux is on the phone already)
759
759
  // A new install (`symbiot app` the first time): setup, from its first step, "Your computer"
760
760
  // in the Android app (it started at "welcome" there, so a phone paired by its QR showed nothing).
761
- function startOnboarding() { const cf = loadConfig(); if (!cf.onboarding) { cf.onboarding = { pending: true, step: onbSteps()[0], skipped: [] }; saveConfig(cf); } return cf.onboarding; }
761
+ function startOnboarding() { const cf = loadConfig(); if (!cf.onboarding) { cf.onboarding = { pending: true, step: onbSteps()[0], skipped: [], ...(onbSteps()[0] === "computer" ? { computer: true } : {}) }; saveConfig(cf); } return cf.onboarding; }
762
+ // The phone app over an older one (a phone that had Symbiot before "Your computer"
763
+ // existed): its unfinished setup carried on at "Meet Symbiot", then "Your AI" asked to
764
+ // install Claude Code on the phone. An unfinished setup on a phone that isn't paired
765
+ // goes to "Your computer" first, once (computer: true): "No computer" carries on as before.
766
+ function phoneSetupFirst({ app = ANDROID_APP, paired = () => !!computerView().paired } = {}) {
767
+ if (!app) return null;
768
+ const cf = loadConfig(), o = cf.onboarding;
769
+ if (!o || !o.pending || o.computer) return o || null;
770
+ let isPaired = false; try { isPaired = paired(); } catch {}
771
+ if (!isPaired) o.step = "computer";
772
+ o.computer = true; saveConfig(cf); return o;
773
+ }
762
774
  function onboarding({ fresh = false } = {}) {
763
775
  const cfg = loadConfig(), o = cfg.onboarding || {}, steps = onbSteps();
764
776
  const tryOr = (f, d) => { try { return f(); } catch { return d; } };
@@ -793,4 +805,4 @@ function setOnboarding({ step, skip, unskip, skipRest, done, restart } = {}) {
793
805
  return onboarding();
794
806
  }
795
807
 
796
- export { reportIdeasAdd, reportAsk, reportDraftAnswer, workTick, waitWhy, AUTO_GRACE, STUCK_AFTER, marketingState, marketingGo, marketingDraftAnswer, marketingTask, moveToMarketing, goLane, homeState, homeContext, homeAsk, homeAnswer, homeNext, nextUp, laneNamed, NEXT_FILE, workScene, workGo, displayName, firstSteps, onboarding, setOnboarding, startOnboarding, ONB_STEPS, ONB_STEPS_PHONE, onbSteps, phoneBits };
808
+ export { reportIdeasAdd, reportAsk, reportDraftAnswer, workTick, waitWhy, AUTO_GRACE, STUCK_AFTER, marketingState, marketingGo, marketingDraftAnswer, marketingTask, moveToMarketing, goLane, homeState, homeContext, homeAsk, homeAnswer, homeNext, nextUp, laneNamed, NEXT_FILE, workScene, workGo, displayName, firstSteps, onboarding, setOnboarding, startOnboarding, ONB_STEPS, ONB_STEPS_PHONE, onbSteps, phoneBits , phoneSetupFirst };
package/icon.ico CHANGED
Binary file
package/icon.svg CHANGED
@@ -1,33 +1 @@
1
- <svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 256 256" width="256" height="256">
2
- <title>Symbiot</title>
3
- <defs>
4
- <radialGradient id="bg" cx="50%" cy="42%" r="70%">
5
- <stop offset="0" stop-color="#1B1D22"/>
6
- <stop offset="1" stop-color="#08090B"/>
7
- </radialGradient>
8
- <radialGradient id="orb" cx="40%" cy="34%" r="66%">
9
- <stop offset="0" stop-color="#3A3D44"/>
10
- <stop offset="0.45" stop-color="#121317"/>
11
- <stop offset="1" stop-color="#030304"/>
12
- </radialGradient>
13
- <radialGradient id="rim" cx="50%" cy="50%" r="50%">
14
- <stop offset="0.86" stop-color="#000" stop-opacity="0"/>
15
- <stop offset="0.97" stop-color="#B0466E" stop-opacity="0.55"/>
16
- <stop offset="1" stop-color="#F2A541" stop-opacity="0"/>
17
- </radialGradient>
18
- <radialGradient id="glow" cx="50%" cy="56%" r="50%">
19
- <stop offset="0.55" stop-color="#F2A541" stop-opacity="0.16"/>
20
- <stop offset="1" stop-color="#F2A541" stop-opacity="0"/>
21
- </radialGradient>
22
- <linearGradient id="shine" x1="0" y1="0" x2="0" y2="1">
23
- <stop offset="0" stop-color="#FFFFFF" stop-opacity="0.85"/>
24
- <stop offset="1" stop-color="#FFFFFF" stop-opacity="0"/>
25
- </linearGradient>
26
- </defs>
27
- <rect width="256" height="256" rx="58" fill="url(#bg)"/>
28
- <circle cx="128" cy="136" r="96" fill="url(#glow)"/>
29
- <circle cx="128" cy="128" r="78" fill="url(#orb)"/>
30
- <circle cx="128" cy="128" r="78" fill="url(#rim)"/>
31
- <ellipse cx="102" cy="92" rx="30" ry="17" transform="rotate(-28 102 92)" fill="url(#shine)"/>
32
- <ellipse cx="160" cy="176" rx="22" ry="5" transform="rotate(-30 160 176)" fill="#FFFFFF" opacity="0.12"/>
33
- </svg>
1
+ <svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 256 256" width="256" height="256"><title>Symbiot</title><defs><radialGradient id="sg" cx="50%" cy="22%" r="85%"><stop offset="0" stop-color="#131416"/><stop offset="1" stop-color="#08090A"/></radialGradient><clipPath id="sc"><circle cx="128" cy="128" r="84"/></clipPath><filter id="sb2" filterUnits="userSpaceOnUse" x="0" y="0" width="256" height="256"><feGaussianBlur stdDeviation="2.2"/></filter><filter id="sb6" filterUnits="userSpaceOnUse" x="0" y="0" width="256" height="256"><feGaussianBlur stdDeviation="6"/></filter><filter id="sb12" filterUnits="userSpaceOnUse" x="0" y="0" width="256" height="256"><feGaussianBlur stdDeviation="12"/></filter><radialGradient id="sfr" cx="50%" cy="50%" r="50%"><stop offset="0.55" stop-color="#2A2C31" stop-opacity="0"/><stop offset="0.9" stop-color="#2A2C31" stop-opacity="0.55"/><stop offset="1" stop-color="#6A6E76" stop-opacity="0.9"/></radialGradient><linearGradient id="sir" x1="0" y1="0" x2="1" y2="1"><stop offset="0" stop-color="#7FE3FF"/><stop offset="0.35" stop-color="#C58AF9"/><stop offset="0.7" stop-color="#F29E38"/><stop offset="1" stop-color="#7FE3FF"/></linearGradient><linearGradient id="st" gradientUnits="userSpaceOnUse" x1="100" y1="72" x2="156" y2="128"><stop offset="0" stop-color="#FFFFFF"/><stop offset="0.45" stop-color="#C9CFD9"/><stop offset="1" stop-color="#6F7887"/></linearGradient><linearGradient id="sa" gradientUnits="userSpaceOnUse" x1="100" y1="128" x2="156" y2="184"><stop offset="0" stop-color="#FFF4E2"/><stop offset="0.45" stop-color="#F2A541"/><stop offset="1" stop-color="#7A4A10"/></linearGradient></defs><rect width="256" height="256" rx="58" fill="url(#sg)"/><ellipse cx="128" cy="206.12" rx="65.52" ry="11.760000000000002" fill="#000000" opacity="0.55" filter="url(#sb6)"/><circle cx="128" cy="128" r="84" fill="#030303"/><circle cx="128" cy="128" r="84" fill="url(#sfr)"/><g clip-path="url(#sc)"><path d="M 153.17 87.73 A 28 28 0 1 0 115.73 125.17" fill="none" stroke="#FFFFFF" stroke-opacity="0.35" stroke-width="23" stroke-linecap="round" filter="url(#sb6)"/><path d="M 102.83 168.27 A 28 28 0 1 0 140.27 130.83" fill="none" stroke="#F2A541" stroke-opacity="0.55" stroke-width="23" stroke-linecap="round" filter="url(#sb6)"/><path d="M 153.17 87.73 A 28 28 0 1 0 115.73 125.17" fill="none" stroke="url(#st)" stroke-width="15" stroke-linecap="round"/><path d="M 102.83 168.27 A 28 28 0 1 0 140.27 130.83" fill="none" stroke="url(#sa)" stroke-width="15" stroke-linecap="round"/></g><g clip-path="url(#sc)"><rect x="62" y="58" width="50" height="24" rx="10" transform="rotate(-24 87 70)" fill="#FFFCF7" opacity="0.85" filter="url(#sb2)"/><rect x="192" y="88" width="8" height="70" rx="4" fill="#D9E6FF" opacity="0.45" filter="url(#sb2)"/><ellipse cx="128" cy="206" rx="52.08" ry="9" fill="#998066" opacity="0.35" filter="url(#sb2)"/></g><circle cx="128" cy="128" r="82.8" fill="none" stroke="url(#sir)" stroke-opacity="0.38" stroke-width="2.4"/></svg>
@@ -0,0 +1 @@
1
+ <svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 256 256" width="256" height="256"><title>Symbiot</title><defs><radialGradient id="sg" cx="50%" cy="22%" r="85%"><stop offset="0" stop-color="#131416"/><stop offset="1" stop-color="#08090A"/></radialGradient><clipPath id="sc"><circle cx="128" cy="128" r="96"/></clipPath><filter id="sb2" filterUnits="userSpaceOnUse" x="0" y="0" width="256" height="256"><feGaussianBlur stdDeviation="2.2"/></filter><filter id="sb6" filterUnits="userSpaceOnUse" x="0" y="0" width="256" height="256"><feGaussianBlur stdDeviation="6"/></filter><filter id="sb12" filterUnits="userSpaceOnUse" x="0" y="0" width="256" height="256"><feGaussianBlur stdDeviation="12"/></filter><radialGradient id="sfr" cx="50%" cy="50%" r="50%"><stop offset="0.55" stop-color="#2A2C31" stop-opacity="0"/><stop offset="0.9" stop-color="#2A2C31" stop-opacity="0.55"/><stop offset="1" stop-color="#6A6E76" stop-opacity="0.9"/></radialGradient><linearGradient id="sir" x1="0" y1="0" x2="1" y2="1"><stop offset="0" stop-color="#7FE3FF"/><stop offset="0.35" stop-color="#C58AF9"/><stop offset="0.7" stop-color="#F29E38"/><stop offset="1" stop-color="#7FE3FF"/></linearGradient><linearGradient id="st" gradientUnits="userSpaceOnUse" x1="97" y1="66" x2="159" y2="128"><stop offset="0" stop-color="#FFFFFF"/><stop offset="0.45" stop-color="#C9CFD9"/><stop offset="1" stop-color="#6F7887"/></linearGradient><linearGradient id="sa" gradientUnits="userSpaceOnUse" x1="97" y1="128" x2="159" y2="190"><stop offset="0" stop-color="#FFF4E2"/><stop offset="0.45" stop-color="#F2A541"/><stop offset="1" stop-color="#7A4A10"/></linearGradient></defs><rect width="256" height="256" rx="58" fill="url(#sg)"/><ellipse cx="128" cy="217.28" rx="74.88" ry="13.440000000000001" fill="#000000" opacity="0.55" filter="url(#sb6)"/><circle cx="128" cy="128" r="96" fill="#030303"/><circle cx="128" cy="128" r="96" fill="url(#sfr)"/><g clip-path="url(#sc)"><path d="M 155.86 83.41 A 31 31 0 1 0 114.41 124.86" fill="none" stroke="#FFFFFF" stroke-opacity="0.35" stroke-width="30" stroke-linecap="round" filter="url(#sb6)"/><path d="M 100.14 172.59 A 31 31 0 1 0 141.59 131.14" fill="none" stroke="#F2A541" stroke-opacity="0.55" stroke-width="30" stroke-linecap="round" filter="url(#sb6)"/><path d="M 155.86 83.41 A 31 31 0 1 0 114.41 124.86" fill="none" stroke="url(#st)" stroke-width="22" stroke-linecap="round"/><path d="M 100.14 172.59 A 31 31 0 1 0 141.59 131.14" fill="none" stroke="url(#sa)" stroke-width="22" stroke-linecap="round"/></g><circle cx="128" cy="128" r="94" fill="none" stroke="#6A6E76" stroke-width="4"/></svg>
@@ -0,0 +1 @@
1
+ <svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 256 256" width="256" height="256"><title>Symbiot</title><defs><radialGradient id="sg" cx="50%" cy="22%" r="85%"><stop offset="0" stop-color="#131416"/><stop offset="1" stop-color="#08090A"/></radialGradient><clipPath id="sc"><circle cx="128" cy="128" r="84"/></clipPath><filter id="sb2" filterUnits="userSpaceOnUse" x="0" y="0" width="256" height="256"><feGaussianBlur stdDeviation="2.2"/></filter><filter id="sb6" filterUnits="userSpaceOnUse" x="0" y="0" width="256" height="256"><feGaussianBlur stdDeviation="6"/></filter><filter id="sb12" filterUnits="userSpaceOnUse" x="0" y="0" width="256" height="256"><feGaussianBlur stdDeviation="12"/></filter><radialGradient id="sfr" cx="50%" cy="50%" r="50%"><stop offset="0.55" stop-color="#2A2C31" stop-opacity="0"/><stop offset="0.9" stop-color="#2A2C31" stop-opacity="0.55"/><stop offset="1" stop-color="#6A6E76" stop-opacity="0.9"/></radialGradient><linearGradient id="sir" x1="0" y1="0" x2="1" y2="1"><stop offset="0" stop-color="#7FE3FF"/><stop offset="0.35" stop-color="#C58AF9"/><stop offset="0.7" stop-color="#F29E38"/><stop offset="1" stop-color="#7FE3FF"/></linearGradient><linearGradient id="st" gradientUnits="userSpaceOnUse" x1="100" y1="72" x2="156" y2="128"><stop offset="0" stop-color="#FFFFFF"/><stop offset="0.45" stop-color="#C9CFD9"/><stop offset="1" stop-color="#6F7887"/></linearGradient><linearGradient id="sa" gradientUnits="userSpaceOnUse" x1="100" y1="128" x2="156" y2="184"><stop offset="0" stop-color="#FFF4E2"/><stop offset="0.45" stop-color="#F2A541"/><stop offset="1" stop-color="#7A4A10"/></linearGradient></defs><rect width="256" height="256" rx="58" fill="url(#sg)"/><ellipse cx="128" cy="206.12" rx="65.52" ry="11.760000000000002" fill="#000000" opacity="0.55" filter="url(#sb6)"/><circle cx="128" cy="128" r="84" fill="#030303"/><circle cx="128" cy="128" r="84" fill="url(#sfr)"/><g clip-path="url(#sc)"><path d="M 153.17 87.73 A 28 28 0 1 0 115.73 125.17" fill="none" stroke="#FFFFFF" stroke-opacity="0.35" stroke-width="23" stroke-linecap="round" filter="url(#sb6)"/><path d="M 102.83 168.27 A 28 28 0 1 0 140.27 130.83" fill="none" stroke="#F2A541" stroke-opacity="0.55" stroke-width="23" stroke-linecap="round" filter="url(#sb6)"/><path d="M 153.17 87.73 A 28 28 0 1 0 115.73 125.17" fill="none" stroke="url(#st)" stroke-width="15" stroke-linecap="round"/><path d="M 102.83 168.27 A 28 28 0 1 0 140.27 130.83" fill="none" stroke="url(#sa)" stroke-width="15" stroke-linecap="round"/></g><g clip-path="url(#sc)"><rect x="62" y="58" width="50" height="24" rx="10" transform="rotate(-24 87 70)" fill="#FFFCF7" opacity="0.85" filter="url(#sb2)"/><rect x="192" y="88" width="8" height="70" rx="4" fill="#D9E6FF" opacity="0.45" filter="url(#sb2)"/><ellipse cx="128" cy="206" rx="52.08" ry="9" fill="#998066" opacity="0.35" filter="url(#sb2)"/></g><circle cx="128" cy="128" r="82.8" fill="none" stroke="url(#sir)" stroke-opacity="0.38" stroke-width="2.4"/></svg>
@@ -0,0 +1 @@
1
+ <svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 256 256" width="256" height="256"><title>Symbiot</title><defs><radialGradient id="sg" cx="50%" cy="50%" r="75%"><stop offset="0" stop-color="#EEF0F2"/><stop offset="1" stop-color="#E1E4E8"/></radialGradient><filter id="ssoft" filterUnits="userSpaceOnUse" x="0" y="0" width="256" height="256"><feGaussianBlur stdDeviation="22"/></filter><clipPath id="stc"><rect width="256" height="256" rx="58"/></clipPath><clipPath id="sc"><circle cx="128" cy="128" r="96"/></clipPath><filter id="sb2" filterUnits="userSpaceOnUse" x="0" y="0" width="256" height="256"><feGaussianBlur stdDeviation="2.2"/></filter><filter id="sb6" filterUnits="userSpaceOnUse" x="0" y="0" width="256" height="256"><feGaussianBlur stdDeviation="6"/></filter><filter id="sb12" filterUnits="userSpaceOnUse" x="0" y="0" width="256" height="256"><feGaussianBlur stdDeviation="12"/></filter><radialGradient id="sgl" cx="45%" cy="40%" r="60%"><stop offset="0" stop-color="#FBFEFF" stop-opacity="0.35"/><stop offset="0.75" stop-color="#FBFEFF" stop-opacity="0.2"/><stop offset="1" stop-color="#FFFFFF" stop-opacity="0.85"/></radialGradient><linearGradient id="st" gradientUnits="userSpaceOnUse" x1="97" y1="66" x2="159" y2="128"><stop offset="0" stop-color="#3B4656"/><stop offset="0.45" stop-color="#3B4656"/><stop offset="1" stop-color="#151A21"/></linearGradient><linearGradient id="sa" gradientUnits="userSpaceOnUse" x1="97" y1="128" x2="159" y2="190"><stop offset="0" stop-color="#FFF4E2"/><stop offset="0.45" stop-color="#F2A541"/><stop offset="1" stop-color="#7A4A10"/></linearGradient></defs><rect width="256" height="256" rx="58" fill="url(#sg)"/><g clip-path="url(#stc)" filter="url(#ssoft)" opacity="0.85"><circle cx="58" cy="70" r="62" fill="#8FC9CC"/><circle cx="206" cy="58" r="58" fill="#FAC999"/><circle cx="134" cy="214" r="64" fill="#B8C2ED"/></g><ellipse cx="128" cy="217.28" rx="74.88" ry="13.440000000000001" fill="#21211F" opacity="0.16" filter="url(#sb6)"/><g clip-path="url(#sc)"><circle cx="128" cy="128" r="96" fill="#EEF1F4"/><g filter="url(#sb12)" opacity="0.9"><circle cx="168" cy="170" r="44" fill="#8FC9CC"/><circle cx="84" cy="162" r="40" fill="#FAC999"/><circle cx="134" cy="80" r="44" fill="#B8C2ED"/></g><circle cx="128" cy="128" r="96" fill="url(#sgl)"/></g><circle cx="128" cy="128" r="95.25" fill="none" stroke="#FFFFFF" stroke-opacity="0.9" stroke-width="1.5"/><g clip-path="url(#sc)"><path d="M 100.14 172.59 A 31 31 0 1 0 141.59 131.14" fill="none" stroke="#F2A541" stroke-opacity="0.45" stroke-width="30" stroke-linecap="round" filter="url(#sb6)"/><path d="M 155.86 83.41 A 31 31 0 1 0 114.41 124.86" fill="none" stroke="url(#st)" stroke-width="22" stroke-linecap="round"/><path d="M 100.14 172.59 A 31 31 0 1 0 141.59 131.14" fill="none" stroke="url(#sa)" stroke-width="22" stroke-linecap="round"/></g><circle cx="128" cy="128" r="94" fill="none" stroke="#5C616B" stroke-opacity="0.45" stroke-width="4"/></svg>
@@ -0,0 +1 @@
1
+ <svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 256 256" width="256" height="256"><title>Symbiot</title><defs><radialGradient id="sg" cx="50%" cy="50%" r="75%"><stop offset="0" stop-color="#EEF0F2"/><stop offset="1" stop-color="#E1E4E8"/></radialGradient><filter id="ssoft" filterUnits="userSpaceOnUse" x="0" y="0" width="256" height="256"><feGaussianBlur stdDeviation="22"/></filter><clipPath id="stc"><rect width="256" height="256" rx="58"/></clipPath><clipPath id="sc"><circle cx="128" cy="128" r="84"/></clipPath><filter id="sb2" filterUnits="userSpaceOnUse" x="0" y="0" width="256" height="256"><feGaussianBlur stdDeviation="2.2"/></filter><filter id="sb6" filterUnits="userSpaceOnUse" x="0" y="0" width="256" height="256"><feGaussianBlur stdDeviation="6"/></filter><filter id="sb12" filterUnits="userSpaceOnUse" x="0" y="0" width="256" height="256"><feGaussianBlur stdDeviation="12"/></filter><radialGradient id="sgl" cx="45%" cy="40%" r="60%"><stop offset="0" stop-color="#FBFEFF" stop-opacity="0.35"/><stop offset="0.75" stop-color="#FBFEFF" stop-opacity="0.2"/><stop offset="1" stop-color="#FFFFFF" stop-opacity="0.85"/></radialGradient><linearGradient id="st" gradientUnits="userSpaceOnUse" x1="100" y1="72" x2="156" y2="128"><stop offset="0" stop-color="#3B4656"/><stop offset="0.45" stop-color="#3B4656"/><stop offset="1" stop-color="#151A21"/></linearGradient><linearGradient id="sa" gradientUnits="userSpaceOnUse" x1="100" y1="128" x2="156" y2="184"><stop offset="0" stop-color="#FFF4E2"/><stop offset="0.45" stop-color="#F2A541"/><stop offset="1" stop-color="#7A4A10"/></linearGradient></defs><rect width="256" height="256" rx="58" fill="url(#sg)"/><g clip-path="url(#stc)" filter="url(#ssoft)" opacity="0.85"><circle cx="58" cy="70" r="62" fill="#8FC9CC"/><circle cx="206" cy="58" r="58" fill="#FAC999"/><circle cx="134" cy="214" r="64" fill="#B8C2ED"/></g><ellipse cx="128" cy="206.12" rx="65.52" ry="11.760000000000002" fill="#21211F" opacity="0.16" filter="url(#sb6)"/><g clip-path="url(#sc)"><circle cx="128" cy="128" r="84" fill="#EEF1F4"/><g filter="url(#sb12)" opacity="0.9"><circle cx="168" cy="170" r="44" fill="#8FC9CC"/><circle cx="84" cy="162" r="40" fill="#FAC999"/><circle cx="134" cy="80" r="44" fill="#B8C2ED"/></g><circle cx="128" cy="128" r="84" fill="url(#sgl)"/></g><circle cx="128" cy="128" r="83.25" fill="none" stroke="#FFFFFF" stroke-opacity="0.9" stroke-width="1.5"/><g clip-path="url(#sc)"><path d="M 102.83 168.27 A 28 28 0 1 0 140.27 130.83" fill="none" stroke="#F2A541" stroke-opacity="0.45" stroke-width="23" stroke-linecap="round" filter="url(#sb6)"/><path d="M 153.17 87.73 A 28 28 0 1 0 115.73 125.17" fill="none" stroke="url(#st)" stroke-width="15" stroke-linecap="round"/><path d="M 102.83 168.27 A 28 28 0 1 0 140.27 130.83" fill="none" stroke="url(#sa)" stroke-width="15" stroke-linecap="round"/></g><g clip-path="url(#sc)"><circle cx="90" cy="82" r="7" fill="#FFFFFF" opacity="0.95" filter="url(#sb2)"/><ellipse cx="162" cy="172" rx="22" ry="10" transform="rotate(-35 162 172)" fill="#FFF7EB" opacity="0.45" filter="url(#sb6)"/></g></svg>
@@ -0,0 +1 @@
1
+ <svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 256 256" width="256" height="256"><title>Symbiot</title><defs><radialGradient id="sg" cx="50%" cy="35%" r="85%"><stop offset="0" stop-color="#EDECEA"/><stop offset="1" stop-color="#E2E0DC"/></radialGradient><clipPath id="sc"><circle cx="128" cy="128" r="96"/></clipPath><filter id="sb2" filterUnits="userSpaceOnUse" x="0" y="0" width="256" height="256"><feGaussianBlur stdDeviation="2.2"/></filter><filter id="sb6" filterUnits="userSpaceOnUse" x="0" y="0" width="256" height="256"><feGaussianBlur stdDeviation="6"/></filter><filter id="sb12" filterUnits="userSpaceOnUse" x="0" y="0" width="256" height="256"><feGaussianBlur stdDeviation="12"/></filter><linearGradient id="senv" x1="0" y1="0" x2="0" y2="1"><stop offset="0" stop-color="#F5F6F7"/><stop offset="0.7" stop-color="#E2E3E6"/><stop offset="1" stop-color="#B9B6B0"/></linearGradient><radialGradient id="spe" cx="50%" cy="50%" r="50%"><stop offset="0.6" stop-color="#FFFFFF" stop-opacity="0"/><stop offset="1" stop-color="#FFFFFF" stop-opacity="0.55"/></radialGradient><linearGradient id="st" gradientUnits="userSpaceOnUse" x1="97" y1="66" x2="159" y2="128"><stop offset="0" stop-color="#3B4656"/><stop offset="0.45" stop-color="#3B4656"/><stop offset="1" stop-color="#151A21"/></linearGradient><linearGradient id="sa" gradientUnits="userSpaceOnUse" x1="97" y1="128" x2="159" y2="190"><stop offset="0" stop-color="#FFF4E2"/><stop offset="0.45" stop-color="#F2A541"/><stop offset="1" stop-color="#7A4A10"/></linearGradient></defs><rect width="256" height="256" rx="58" fill="url(#sg)"/><ellipse cx="128" cy="217.28" rx="74.88" ry="13.440000000000001" fill="#21211F" opacity="0.16" filter="url(#sb6)"/><circle cx="128" cy="128" r="96" fill="url(#senv)"/><circle cx="128" cy="128" r="96" fill="url(#spe)"/><g clip-path="url(#sc)"><path d="M 100.14 172.59 A 31 31 0 1 0 141.59 131.14" fill="none" stroke="#F2A541" stroke-opacity="0.45" stroke-width="30" stroke-linecap="round" filter="url(#sb6)"/><path d="M 155.86 83.41 A 31 31 0 1 0 114.41 124.86" fill="none" stroke="url(#st)" stroke-width="22" stroke-linecap="round"/><path d="M 100.14 172.59 A 31 31 0 1 0 141.59 131.14" fill="none" stroke="url(#sa)" stroke-width="22" stroke-linecap="round"/></g><circle cx="128" cy="128" r="94" fill="none" stroke="#5C616B" stroke-opacity="0.45" stroke-width="4"/></svg>
@@ -0,0 +1 @@
1
+ <svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 256 256" width="256" height="256"><title>Symbiot</title><defs><radialGradient id="sg" cx="50%" cy="35%" r="85%"><stop offset="0" stop-color="#EDECEA"/><stop offset="1" stop-color="#E2E0DC"/></radialGradient><clipPath id="sc"><circle cx="128" cy="128" r="84"/></clipPath><filter id="sb2" filterUnits="userSpaceOnUse" x="0" y="0" width="256" height="256"><feGaussianBlur stdDeviation="2.2"/></filter><filter id="sb6" filterUnits="userSpaceOnUse" x="0" y="0" width="256" height="256"><feGaussianBlur stdDeviation="6"/></filter><filter id="sb12" filterUnits="userSpaceOnUse" x="0" y="0" width="256" height="256"><feGaussianBlur stdDeviation="12"/></filter><linearGradient id="senv" x1="0" y1="0" x2="0" y2="1"><stop offset="0" stop-color="#F5F6F7"/><stop offset="0.62" stop-color="#E6E7E9"/><stop offset="0.86" stop-color="#A3A7AE"/><stop offset="0.93" stop-color="#6E737C"/><stop offset="1" stop-color="#9E9991"/></linearGradient><radialGradient id="spe" cx="50%" cy="50%" r="50%"><stop offset="0.6" stop-color="#FFFFFF" stop-opacity="0"/><stop offset="1" stop-color="#FFFFFF" stop-opacity="0.55"/></radialGradient><linearGradient id="st" gradientUnits="userSpaceOnUse" x1="100" y1="72" x2="156" y2="128"><stop offset="0" stop-color="#3B4656"/><stop offset="0.45" stop-color="#3B4656"/><stop offset="1" stop-color="#151A21"/></linearGradient><linearGradient id="sa" gradientUnits="userSpaceOnUse" x1="100" y1="128" x2="156" y2="184"><stop offset="0" stop-color="#FFF4E2"/><stop offset="0.45" stop-color="#F2A541"/><stop offset="1" stop-color="#7A4A10"/></linearGradient></defs><rect width="256" height="256" rx="58" fill="url(#sg)"/><ellipse cx="128" cy="206.12" rx="65.52" ry="11.760000000000002" fill="#21211F" opacity="0.16" filter="url(#sb6)"/><circle cx="128" cy="128" r="84" fill="url(#senv)"/><circle cx="128" cy="128" r="84" fill="url(#spe)"/><g clip-path="url(#sc)"><path d="M 102.83 168.27 A 28 28 0 1 0 140.27 130.83" fill="none" stroke="#F2A541" stroke-opacity="0.45" stroke-width="23" stroke-linecap="round" filter="url(#sb6)"/><path d="M 153.17 87.73 A 28 28 0 1 0 115.73 125.17" fill="none" stroke="url(#st)" stroke-width="15" stroke-linecap="round"/><path d="M 102.83 168.27 A 28 28 0 1 0 140.27 130.83" fill="none" stroke="url(#sa)" stroke-width="15" stroke-linecap="round"/></g><g clip-path="url(#sc)"><rect x="64" y="64" width="52" height="26" rx="11" transform="rotate(-22 90 77)" fill="#FFFFFF" opacity="0.75" filter="url(#sb2)"/><rect x="188" y="92" width="9" height="62" rx="4.5" fill="#FFFFFF" opacity="0.5" filter="url(#sb2)"/></g></svg>
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "symbiot",
3
- "version": "0.62.0",
3
+ "version": "0.63.0",
4
4
  "description": "Your week, written from your real work. Reads your local git and writes it up with the AI of your choice \u2014 Claude, OpenAI, Gemini, or a local model.",
5
5
  "type": "module",
6
6
  "bin": {
@@ -57,7 +57,8 @@
57
57
  "lang.mjs",
58
58
  "browser.html",
59
59
  "qr.mjs",
60
- "mdns.mjs"
60
+ "mdns.mjs",
61
+ "icons"
61
62
  ],
62
63
  "engines": {
63
64
  "node": ">=18"
@@ -76,15 +77,15 @@
76
77
  "developer-tools",
77
78
  "cli"
78
79
  ],
79
- "author": "Garth White <garth@ghost-ai.co.za>",
80
+ "author": "Garth White <garthwhite507@gmail.com>",
80
81
  "license": "Elastic-2.0",
81
82
  "repository": {
82
83
  "type": "git",
83
- "url": "git+https://github.com/GarthGhostai/symbiot.git"
84
+ "url": "git+https://github.com/GAWdessey/symbiot.git"
84
85
  },
85
- "homepage": "https://github.com/GarthGhostai/symbiot#readme",
86
+ "homepage": "https://github.com/GAWdessey/symbiot#readme",
86
87
  "bugs": {
87
- "url": "https://github.com/GarthGhostai/symbiot/issues"
88
+ "url": "https://github.com/GAWdessey/symbiot/issues"
88
89
  },
89
90
  "dependencies": {
90
91
  "@anthropic-ai/sdk": "^0.128.0"
package/server.mjs CHANGED
@@ -34,7 +34,7 @@ import { mindState, forget } from "./mind.mjs";
34
34
  import { lanesTick, lanesState, partlyDone, orcaRelink } from "./lanes.mjs";
35
35
  import { keepFacts, skipFacts, awaitTick, awaitingState, stopWaiting } from "./handback.mjs";
36
36
  import { adaptState, noteUse } from "./adapt.mjs";
37
- import { reportIdeasAdd, reportAsk, reportDraftAnswer, homeState, homeAsk, homeAnswer, homeNext, workScene, workGo, workTick, firstSteps, marketingState, marketingGo, marketingDraftAnswer, marketingTask, moveToMarketing, onboarding, setOnboarding, startOnboarding } from "./home.mjs";
37
+ import { reportIdeasAdd, reportAsk, reportDraftAnswer, homeState, homeAsk, homeAnswer, homeNext, workScene, workGo, workTick, firstSteps, marketingState, marketingGo, marketingDraftAnswer, marketingTask, moveToMarketing, onboarding, setOnboarding, startOnboarding, phoneSetupFirst } from "./home.mjs";
38
38
  import { MARKETING_DIR, MARKETING, draftPreview, laneMedia, displayName, setDraftMedia } from "./marketing.mjs";
39
39
  import { trays, trayMedia, setBlur, renderCapture } from "./tray.mjs";
40
40
  import { listReports, readReport, reportImage, markAllRead } from "./reports.mjs";
@@ -242,6 +242,7 @@ async function startApp({ bin, since = 7, all = false, c = PLAIN_COLOURS } = {})
242
242
  if (/[\\/]node_modules[\\/]symbiot[\\/]/.test(bin || "") && !SANDBOX && !process.env.SYMBIOT_NO_LAUNCHER) { try { installLauncher({ script: bin }); } catch {} }
243
243
  // setup's first step: "Your computer" in the Android app, so a phone paired by its QR shows it
244
244
  if (FRESH) { try { startOnboarding(); } catch {} }
245
+ try { phoneSetupFirst(); } catch {} // the phone app, over an older one: setup goes to "Your computer" first
245
246
  // your projects: kept, and found again off the main thread, so nothing waits on a search
246
247
  setScanOptions({ cache: true }); REPO_STATE.onChange = () => { try { homeState({ fresh: true }); } catch {} };
247
248
  if (!SANDBOX) { refreshRevoked().catch(() => {}); setInterval(() => refreshRevoked().catch(() => {}), 6 * 3600 * 1000).unref(); } // cancelled Pro keys, about daily
@@ -258,7 +259,7 @@ async function startApp({ bin, since = 7, all = false, c = PLAIN_COLOURS } = {})
258
259
  // the app's typeface ships in the package (fonts/), so it's there offline
259
260
  // the window's own icon (its taskbar entry), the same orb as the app menu's
260
261
  if (req.method === "GET" && (u.pathname === "/favicon.svg" || u.pathname === "/favicon.ico")) {
261
- try { const b = iconSvg(u.searchParams.get("look") || loadConfig().look || "ferro"); res.writeHead(200, { "content-type": "image/svg+xml", "cache-control": "no-cache" }); res.end(b); }
262
+ try { const b = iconSvg(u.searchParams.get("look") || loadConfig().look || "ferro", { small: u.searchParams.get("small") === "1" }); res.writeHead(200, { "content-type": "image/svg+xml", "cache-control": "no-cache" }); res.end(b); }
262
263
  catch { res.writeHead(404); res.end(); }
263
264
  return;
264
265
  }
package/ui.mjs CHANGED
@@ -392,6 +392,7 @@ body.lq-light .thinking{background-image:linear-gradient(90deg,#4A5565 0%,#0F172
392
392
  body{background:var(--ink);color:var(--text);font-family:var(--sans);font-size:14px;display:flex;flex-direction:column}
393
393
  header{padding:16px 18px 10px;display:flex;align-items:center;gap:10px}
394
394
  .dot{width:10px;height:10px;border-radius:50%;background:var(--green);box-shadow:0 0 12px var(--green)}
395
+ header .dot{width:22px;height:22px;border-radius:6px;background:center/contain no-repeat url('/favicon.svg?small=1');box-shadow:none}
395
396
  .brand{font-weight:700;color:var(--bone);font-size:16px}
396
397
  .status{margin-left:auto;font-size:12px;color:var(--faint);text-align:right;max-width:52%}
397
398
  .tabs{display:flex;gap:6px;padding:0 14px;border-bottom:1px solid var(--line)}
@@ -1093,7 +1094,7 @@ body.lq-light .btip .bta button:not(.quiet){background:#151A21;color:#FFFFFF}
1093
1094
  <div id="updatebar" class="updatebar"></div>
1094
1095
  <div id="appbar" class="updatebar"></div>
1095
1096
  <div id="whatsnew" class="whatsnew"></div>
1096
- <header><span class="dot"></span><span class="brand">Symbiot</span><span class="ver" id="ver"></span><span id="lqlook" role="radiogroup" aria-label="Look"><button type="button" role="radio" data-look="glass" aria-checked="false">Glass</button><button type="button" role="radio" data-look="ferro" aria-checked="true">Ferrofluid</button><button type="button" role="radio" data-look="pearl" aria-checked="false">Pearl</button></span><span class="status" id="status">...</span></header>
1097
+ <header><span class="dot" role="img" aria-label="Symbiot"></span><span class="brand">Symbiot</span><span class="ver" id="ver"></span><span id="lqlook" role="radiogroup" aria-label="Look"><button type="button" role="radio" data-look="glass" aria-checked="false">Glass</button><button type="button" role="radio" data-look="ferro" aria-checked="true">Ferrofluid</button><button type="button" role="radio" data-look="pearl" aria-checked="false">Pearl</button></span><span class="status" id="status">...</span></header>
1097
1098
  <div class="tabs">
1098
1099
  <button class="tab active" data-tab="map">Map</button>
1099
1100
  <button class="tab" data-tab="board" id="boardtab">Dashboard</button>
@@ -3652,7 +3653,7 @@ b.querySelectorAll('[data-link]').forEach(function(x){x.addEventListener('click'
3652
3653
  b.querySelectorAll('[data-check]').forEach(function(x){x.addEventListener('click',function(){x.disabled=true;api('/api/links/check',{id:x.getAttribute('data-check')}).then(function(){onbLoad();});});});
3653
3654
  b.querySelectorAll('[data-skip]').forEach(function(x){x.addEventListener('click',function(){api('/api/onboarding/set',{skip:x.getAttribute('data-skip')}).then(function(r){ONB=r;onbRender();});});});
3654
3655
  b.querySelectorAll('[data-unskip]').forEach(function(x){x.addEventListener('click',function(){api('/api/onboarding/set',{unskip:x.getAttribute('data-unskip')}).then(function(r){ONB=r;onbRender();});});});}
3655
- function lqIcon(l){var k=document.querySelector('link[rel=icon]');if(k)k.setAttribute('href','/favicon.svg?look='+encodeURIComponent(l||'ferro'));}
3656
+ function lqIcon(l){var q='/favicon.svg?look='+encodeURIComponent(l||'ferro'),k=document.querySelector('link[rel=icon]');if(k)k.setAttribute('href',q+'&small=1');var d=document.querySelector('header .dot');if(d)d.style.backgroundImage="url('"+q+"&small=1')";document.querySelectorAll('img.onborb').forEach(function(im){im.src=q;});}
3656
3657
  function lqInit(){var bd=document.body;if(!bd||!bd.classList)return;lqIcon(lqLookGet());lqTheme();try{i18nStart();}catch(e){}bd.classList.add('lq-liquid');
3657
3658
  ['(prefers-color-scheme: light)','(prefers-contrast: more)','(forced-colors: active)','(prefers-reduced-transparency: reduce)','(prefers-reduced-motion: reduce)'].forEach(function(q){try{var mq=window.matchMedia&&window.matchMedia(q);if(mq&&mq.addEventListener)mq.addEventListener('change',lqTheme);else if(mq&&mq.addListener)mq.addListener(lqTheme);}catch(e){}});
3658
3659
  if(document.addEventListener){document.addEventListener('contextmenu',function(ev){var b=document.body,t=ev&&ev.target;if(!b||!b.classList||!b.classList.contains('lq-liquid'))return;if(t&&t.closest&&t.closest('input,textarea,select,[contenteditable]'))return;var sel=window.getSelection?String(window.getSelection()):'';if(sel)return;ev.preventDefault();lqBack();});