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..00c7370a --- /dev/null +++ b/.lane/memory/apps/host/src/directory.ts/01M5G7C4TB4NT55C348DMACCAP-only-a-directory-json-naming.md @@ -0,0 +1,12 @@ +--- +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 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