From 6d75d6eeca7d4b5cb8b96f4bd3cd73f7149cd501 Mon Sep 17 00:00:00 2001 From: iamnbutler Date: Wed, 21 Oct 2026 17:55:13 -0400 Subject: [PATCH 1/3] fix(host): keep the directory's service URLs across host restarts directory.json now records the app, hosted, and compute URLs from the last successful sync, so cloud options and the web app origin appear at start and while the directory is unreachable. Joining, changing, or leaving the directory rewrites or removes the file, which drops them. Why: apps/host/src/directory.ts#function remember | only a directory.json naming the synced URL records services; ACE_DIRECTORY alone must not create the file --- apps/host/src/directory.ts | 41 +++++++++++++++++++++++++++----------- docs/data.md | 2 +- 2 files changed, 30 insertions(+), 13 deletions(-) diff --git a/apps/host/src/directory.ts b/apps/host/src/directory.ts index e8a49bca..16f72592 100644 --- a/apps/host/src/directory.ts +++ b/apps/host/src/directory.ts @@ -22,22 +22,38 @@ type Host = { name: string; login: string; github?: string; address?: string; se const config = join(catalog.home, "directory.json"); +/** `app`, `hosted`, and `compute` are the team's web app and services, set where the directory is deployed. */ +type Services = { app?: string; hosted?: string; compute?: string }; +type Known = Services & { hosts: Host[]; channels: Listing[]; shares: Share[] }; + +/** The joined directory's URL and the services it last named. */ +type Saved = Services & { url: string }; + +function saved(): Saved | undefined { + if (existsSync(config)) return JSON.parse(readFileSync(config, "utf8")); +} + export function url(): string | undefined { - if (process.env.ACE_DIRECTORY) return process.env.ACE_DIRECTORY; - if (existsSync(config)) return JSON.parse(readFileSync(config, "utf8")).url; + return process.env.ACE_DIRECTORY || saved()?.url; } -/** `app`, `hosted`, and `compute` are the team's web app and services, set where the directory is deployed. */ -type Known = { - hosts: Host[]; - channels: Listing[]; - shares: Share[]; - app?: string; - hosted?: string; - compute?: string; -}; +/** The services survive a restart so cloud options don't wait for the first sync, or vanish offline. */ +function remembered(): Known { + const value = saved(); + const base = { hosts: [], channels: [], shares: [] }; + if (!value || value.url !== url()) return base; + return { ...base, app: value.app, hosted: value.hosted, compute: value.compute }; +} + +/** Only the joined directory's file records its services; ACE_DIRECTORY alone writes nothing. */ +function remember(base: string, { app, hosted, compute }: Services) { + const value = saved(); + if (value?.url !== base) return; + if (value.app === app && value.hosted === hosted && value.compute === compute) return; + writeFileSync(config, JSON.stringify({ url: base, app, hosted, compute })); +} -let known: Known = { hosts: [], channels: [], shares: [] }; +let known: Known = remembered(); let synced: number | undefined; /** The last sync's failure, kept until a sync succeeds so Settings can say what is wrong and since when. */ let error: string | undefined; @@ -203,6 +219,7 @@ export function watch({ self, channels, changed, published, covered }: Options) // Directories deployed before project access keep no shares. answer.shares ||= []; known = answer; + remember(base, answer); synced = Date.now(); error = undefined; failed = undefined; diff --git a/docs/data.md b/docs/data.md index 5802b0e2..b48a9984 100644 --- a/docs/data.md +++ b/docs/data.md @@ -13,7 +13,7 @@ it. pi-durable owns the database format, messages, runs, tool results, chats, an | A checkout's development build | `~/.local/state/ace-dev-/channels//` | | Opened projects | `/projects.json` | | Preferences on macOS | `~/Library/Application Support/Ace/settings.json` | -| Team directory URL | `/directory.json` | +| Team directory URL and services | `/directory.json` | | Provider credentials and `ACE_SECRET` | OS Keychain; never in channel metadata or preferences | `ACE_HOME` overrides the host data directory. Canary and development preferences have the same From 948127128334244642804d08860697c601b5b32c Mon Sep 17 00:00:00 2001 From: iamnbutler Date: Wed, 21 Oct 2026 17:55:22 -0400 Subject: [PATCH 2/3] chore: lane notes for directory services --- ...YWKAGD3FTMWYWE1KVXT9Q1-the-poll-may-slow-only-while.md | 6 +++--- ...G7C4TB4NT55C348DMACCAP-only-a-directory-json-naming.md | 8 ++++++++ 2 files changed, 11 insertions(+), 3 deletions(-) create mode 100644 .lane/memory/apps/host/src/directory.ts/01M5G7C4TB4NT55C348DMACCAP-only-a-directory-json-naming.md diff --git a/.lane/memory/apps/host/src/directory.ts/01M4YWKAGD3FTMWYWE1KVXT9Q1-the-poll-may-slow-only-while.md b/.lane/memory/apps/host/src/directory.ts/01M4YWKAGD3FTMWYWE1KVXT9Q1-the-poll-may-slow-only-while.md index e15e9f48..c9120bd5 100644 --- a/.lane/memory/apps/host/src/directory.ts/01M4YWKAGD3FTMWYWE1KVXT9Q1-the-poll-may-slow-only-while.md +++ b/.lane/memory/apps/host/src/directory.ts/01M4YWKAGD3FTMWYWE1KVXT9Q1-the-poll-may-slow-only-while.md @@ -4,9 +4,9 @@ anchor: function watch created: 2026-10-15T04:19:48Z norm: '1' sig: 01895e7ff9a47d37 -body_hash: d05a924e14300999 -raw_hash: 37b2264443de0c14 -vouched: 2026-10-19T20:58:11Z +body_hash: fe03a4474929e917 +raw_hash: c6d495788240ddb4 +vouched: 2026-10-21T21:55:17Z lines: 89-149 --- diff --git a/.lane/memory/apps/host/src/directory.ts/01M5G7C4TB4NT55C348DMACCAP-only-a-directory-json-naming.md b/.lane/memory/apps/host/src/directory.ts/01M5G7C4TB4NT55C348DMACCAP-only-a-directory-json-naming.md new file mode 100644 index 00000000..7e630058 --- /dev/null +++ b/.lane/memory/apps/host/src/directory.ts/01M5G7C4TB4NT55C348DMACCAP-only-a-directory-json-naming.md @@ -0,0 +1,8 @@ +--- +id: 01M5G7C4TB4NT55C348DMACCAP +anchor: function remember +created: 2026-10-21T21:55:13Z +norm: '1' +--- + +only a directory.json naming the synced URL records services; ACE_DIRECTORY alone must not create the file From f6c346b705621fb9e5568f3c124efd179a43ca94 Mon Sep 17 00:00:00 2001 From: iamnbutler Date: Wed, 21 Oct 2026 17:55:23 -0400 Subject: [PATCH 3/3] lane: sync directory-services memory --- ...01M5G7C4TB4NT55C348DMACCAP-only-a-directory-json-naming.md | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/.lane/memory/apps/host/src/directory.ts/01M5G7C4TB4NT55C348DMACCAP-only-a-directory-json-naming.md b/.lane/memory/apps/host/src/directory.ts/01M5G7C4TB4NT55C348DMACCAP-only-a-directory-json-naming.md index 7e630058..00c7370a 100644 --- a/.lane/memory/apps/host/src/directory.ts/01M5G7C4TB4NT55C348DMACCAP-only-a-directory-json-naming.md +++ b/.lane/memory/apps/host/src/directory.ts/01M5G7C4TB4NT55C348DMACCAP-only-a-directory-json-naming.md @@ -3,6 +3,10 @@ id: 01M5G7C4TB4NT55C348DMACCAP anchor: function remember created: 2026-10-21T21:55:13Z norm: '1' +sig: 4f21369e4fee9b0a +body_hash: 4e1d54af62a2f1f5 +raw_hash: 2f8b64877de51afc +lines: 49-54 --- only a directory.json naming the synced URL records services; ACE_DIRECTORY alone must not create the file