@linxiraos/pi-utils 1.0.0 → 1.0.1
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 +7 -2
- package/dist/types/dirs.d.ts +72 -64
- package/package.json +2 -2
- package/src/dirs.ts +96 -91
- package/src/logger.ts +7 -7
- package/src/stderr-guard.ts +1 -1
package/CHANGELOG.md
CHANGED
|
@@ -2,9 +2,8 @@
|
|
|
2
2
|
|
|
3
3
|
## [Unreleased]
|
|
4
4
|
|
|
5
|
-
|
|
5
|
+
## [1.0.1] - 2026-08-14
|
|
6
6
|
|
|
7
|
-
- Reset the version to 1.0.0 and republished under the `@linxiraos/*` scope, breaking from the `@oh-my-pi` version lineage.
|
|
8
7
|
## [17.2.11] - 2026-08-07
|
|
9
8
|
|
|
10
9
|
### Added
|
|
@@ -447,3 +446,9 @@
|
|
|
447
446
|
### Added
|
|
448
447
|
|
|
449
448
|
- Added an XDG-aware tiny-title model cache directory helper for coding-agent local title models.
|
|
449
|
+
|
|
450
|
+
## [1.0.0] - 2026-08-13
|
|
451
|
+
|
|
452
|
+
### Changed
|
|
453
|
+
|
|
454
|
+
- Reset the version to 1.0.0 and republished under the `@linxiraos/*` scope, breaking from the `@oh-my-pi` version lineage.
|
package/dist/types/dirs.d.ts
CHANGED
|
@@ -1,12 +1,12 @@
|
|
|
1
1
|
/**
|
|
2
2
|
* Centralized path helpers for omp config directories.
|
|
3
3
|
*
|
|
4
|
-
* Uses PI_CONFIG_DIR (default ".
|
|
4
|
+
* Uses PI_CONFIG_DIR (default ".zeta") for the config root and
|
|
5
5
|
* PI_CODING_AGENT_DIR to override the agent directory.
|
|
6
6
|
*
|
|
7
7
|
* On Linux, if XDG_DATA_HOME / XDG_STATE_HOME / XDG_CACHE_HOME environment
|
|
8
8
|
* variables are set, paths are redirected to XDG-compliant locations under
|
|
9
|
-
* $XDG_*_HOME/omp/. This requires running `
|
|
9
|
+
* $XDG_*_HOME/omp/. This requires running `zeta config migrate` first to
|
|
10
10
|
* move data to the new locations. No filesystem existence checks are performed
|
|
11
11
|
* — if the env var is set, omp trusts that the migration has been done.
|
|
12
12
|
*/
|
|
@@ -53,9 +53,17 @@ export declare function setProjectDir(dir: string): void;
|
|
|
53
53
|
* working directory before {@link setProjectDir} throws on it.
|
|
54
54
|
*/
|
|
55
55
|
export declare function directoryExists(dir: string): Promise<boolean>;
|
|
56
|
-
/** Get the config directory name relative to home (e.g. ".zeta" or PI_CONFIG_DIR override).
|
|
56
|
+
/** Get the config directory name relative to home (e.g. ".zeta" or PI_CONFIG_DIR override). */
|
|
57
57
|
export declare function getConfigDirName(): string;
|
|
58
|
-
/**
|
|
58
|
+
/**
|
|
59
|
+
* One-time migration of a legacy `~/.omp` config root to `~/.zeta`. Called
|
|
60
|
+
* from the CLI entrypoint before any user data is written; it only moves the
|
|
61
|
+
* directory when `.zeta` does not exist yet. Zeta keeps no `.omp`
|
|
62
|
+
* compatibility surface afterwards (see AGENTS.md), so this is the single
|
|
63
|
+
* exception that honors pre-existing installs.
|
|
64
|
+
*/
|
|
65
|
+
export declare function migrateLegacyOmpConfigDir(): void;
|
|
66
|
+
/** Get the config agent directory name relative to home (e.g. ".zeta/agent" or PI_CONFIG_DIR + "/agent"). */
|
|
59
67
|
export declare function getConfigAgentDirName(): string;
|
|
60
68
|
/**
|
|
61
69
|
* Rebuild the dirs resolver from the current environment, reusing the profile
|
|
@@ -68,7 +76,7 @@ export declare function getConfigAgentDirName(): string;
|
|
|
68
76
|
* `preProfileAgentDirEnv` snapshot is intentionally left untouched.
|
|
69
77
|
*/
|
|
70
78
|
export declare function refreshDirsFromEnv(): void;
|
|
71
|
-
/** Get the config root directory (~/.
|
|
79
|
+
/** Get the config root directory (~/.zeta). */
|
|
72
80
|
export declare function getConfigRootDir(): string;
|
|
73
81
|
/** Set the coding agent directory. Creates a fresh resolver, invalidating all cached paths. */
|
|
74
82
|
export declare function setAgentDir(dir: string): void;
|
|
@@ -94,18 +102,18 @@ export declare function setProfile(profile: string | undefined): void;
|
|
|
94
102
|
export declare function getActiveProfile(): string | undefined;
|
|
95
103
|
/** Resolve the config root that backs a profile without activating it. */
|
|
96
104
|
export declare function getProfileRootDir(profile: string | undefined): string;
|
|
97
|
-
/** Get the agent config directory (~/.
|
|
105
|
+
/** Get the agent config directory (~/.zeta/agent). */
|
|
98
106
|
export declare function getAgentDir(): string;
|
|
99
|
-
/** Get the project-local config directory (.zeta).
|
|
107
|
+
/** Get the project-local config directory (.zeta). */
|
|
100
108
|
export declare function getProjectAgentDir(cwd?: string): string;
|
|
101
|
-
/** Get the reports directory (~/.
|
|
109
|
+
/** Get the reports directory (~/.zeta/reports). */
|
|
102
110
|
export declare function getReportsDir(): string;
|
|
103
|
-
/** Get the logs directory (~/.
|
|
111
|
+
/** Get the logs directory (~/.zeta/logs). */
|
|
104
112
|
export declare function getLogsDir(): string;
|
|
105
|
-
/** Get this process's dated log path (~/.
|
|
113
|
+
/** Get this process's dated log path (~/.zeta/logs/zeta.YYYY-MM-DD.PID.log). */
|
|
106
114
|
export declare function getLogPath(date?: Date, pid?: number): string;
|
|
107
115
|
/**
|
|
108
|
-
* Get the plugins directory (~/.
|
|
116
|
+
* Get the plugins directory (~/.zeta/plugins or its XDG equivalent).
|
|
109
117
|
*
|
|
110
118
|
* No-arg form (production callers) goes through the XDG-aware DirResolver so
|
|
111
119
|
* reads and writes always agree. The optional `home` parameter is for test
|
|
@@ -115,19 +123,19 @@ export declare function getLogPath(date?: Date, pid?: number): string;
|
|
|
115
123
|
* no-arg form — XDG semantics are preserved.
|
|
116
124
|
*/
|
|
117
125
|
export declare function getPluginsDir(home?: string): string;
|
|
118
|
-
/** Where npm installs packages (~/.
|
|
126
|
+
/** Where npm installs packages (~/.zeta/plugins/node_modules). */
|
|
119
127
|
export declare function getPluginsNodeModules(home?: string): string;
|
|
120
|
-
/** Plugin manifest (~/.
|
|
128
|
+
/** Plugin manifest (~/.zeta/plugins/package.json). */
|
|
121
129
|
export declare function getPluginsPackageJson(home?: string): string;
|
|
122
|
-
/** Plugin lock file (~/.
|
|
130
|
+
/** Plugin lock file (~/.zeta/plugins/zeta-plugins.lock.json). */
|
|
123
131
|
export declare function getPluginsLockfile(home?: string): string;
|
|
124
|
-
/** Get the remote mount directory (~/.
|
|
132
|
+
/** Get the remote mount directory (~/.zeta/remote). */
|
|
125
133
|
export declare function getRemoteDir(): string;
|
|
126
134
|
/**
|
|
127
135
|
* Relocate the base directory for agent-managed worktrees (PR checkouts, task
|
|
128
|
-
* isolation, and `
|
|
136
|
+
* isolation, and `zeta worktree` cleanup all read the same base). Driven by the
|
|
129
137
|
* `worktree.base` setting in coding-agent; pass `undefined`/empty to clear and
|
|
130
|
-
* fall back to `OMP_WORKTREE_DIR` or the `~/.
|
|
138
|
+
* fall back to `OMP_WORKTREE_DIR` or the `~/.zeta/wt` default.
|
|
131
139
|
*
|
|
132
140
|
* `~` is expanded and a relative path is rejected (see {@link resolveWorktreeBase}).
|
|
133
141
|
* Returns the absolute path that took effect, or `undefined` if the input was
|
|
@@ -138,122 +146,122 @@ export declare function setWorktreesDir(dir: string | undefined): string | undef
|
|
|
138
146
|
/**
|
|
139
147
|
* Get the agent-managed worktrees directory. Resolution order: the
|
|
140
148
|
* `OMP_WORKTREE_DIR` env var, then the {@link setWorktreesDir} override (the
|
|
141
|
-
* `worktree.base` setting), then the `~/.
|
|
149
|
+
* `worktree.base` setting), then the `~/.zeta/wt` default. The env var and the
|
|
142
150
|
* override are both `~`-expanded and must be absolute; a relative value is
|
|
143
151
|
* ignored and resolution falls through.
|
|
144
152
|
*/
|
|
145
153
|
export declare function getWorktreesDir(): string;
|
|
146
|
-
/** Get the SSH control socket directory (~/.
|
|
154
|
+
/** Get the SSH control socket directory (~/.zeta/ssh-control). */
|
|
147
155
|
export declare function getSshControlDir(): string;
|
|
148
|
-
/** Get the remote host info directory (~/.
|
|
156
|
+
/** Get the remote host info directory (~/.zeta/remote-host). */
|
|
149
157
|
export declare function getRemoteHostDir(): string;
|
|
150
|
-
/** Get the managed Python venv directory (~/.
|
|
158
|
+
/** Get the managed Python venv directory (~/.zeta/python-env). */
|
|
151
159
|
export declare function getPythonEnvDir(): string;
|
|
152
|
-
/** Get the shared Python gateway state directory (~/.
|
|
160
|
+
/** Get the shared Python gateway state directory (~/.zeta/agent/python-gateway; XDG default: $XDG_STATE_HOME/zeta/python-gateway). */
|
|
153
161
|
export declare function getPythonGatewayDir(): string;
|
|
154
|
-
/** Get the puppeteer sandbox directory (~/.
|
|
162
|
+
/** Get the puppeteer sandbox directory (~/.zeta/puppeteer). */
|
|
155
163
|
export declare function getPuppeteerDir(): string;
|
|
156
|
-
/** Get the browser relay extension install directory (~/.
|
|
164
|
+
/** Get the browser relay extension install directory (~/.zeta/browser-relay). */
|
|
157
165
|
export declare function getBrowserRelayDir(): string;
|
|
158
166
|
/** Get DOCS_RS cache directory () */
|
|
159
167
|
export declare function getDocsRsCacheDir(): string;
|
|
160
|
-
/** Get the auto-QA grievances SQLite database path (~/.
|
|
168
|
+
/** Get the auto-QA grievances SQLite database path (~/.zeta/autoqa.db; XDG: $XDG_DATA_HOME/zeta/autoqa.db). */
|
|
161
169
|
export declare function getAutoQaDbPath(): string;
|
|
162
170
|
/**
|
|
163
171
|
* Stable 7-character hex digest of an absolute filesystem path.
|
|
164
172
|
*
|
|
165
173
|
* Used to pack the project identity into a single short fs-safe segment
|
|
166
|
-
* (e.g. PR-checkout and task-isolation worktree dirs under `~/.
|
|
174
|
+
* (e.g. PR-checkout and task-isolation worktree dirs under `~/.zeta/wt/`).
|
|
167
175
|
* Bun.hash is non-cryptographic — collision space is ~2^28, which is fine
|
|
168
176
|
* for naming a handful of repos on a single machine. Same input on the
|
|
169
177
|
* same Bun runtime yields the same output.
|
|
170
178
|
*/
|
|
171
179
|
export declare function hashPath(absPath: string): string;
|
|
172
|
-
/** Get the path to a single worktree directory (~/.
|
|
180
|
+
/** Get the path to a single worktree directory (~/.zeta/wt/<segment>). */
|
|
173
181
|
export declare function getWorktreeDir(segment: string): string;
|
|
174
|
-
/** Get the GPU cache path (~/.
|
|
182
|
+
/** Get the GPU cache path (~/.zeta/gpu_cache.json). */
|
|
175
183
|
export declare function getGpuCachePath(): string;
|
|
176
184
|
/**
|
|
177
|
-
* Get the GitHub view cache database path (~/.
|
|
185
|
+
* Get the GitHub view cache database path (~/.zeta/cache/github-cache.db).
|
|
178
186
|
* Honors the `OMP_GITHUB_CACHE_DB` env var when set so tests can isolate the
|
|
179
187
|
* cache file without touching the rest of the config root.
|
|
180
188
|
*/
|
|
181
189
|
export declare function getGithubCacheDbPath(): string;
|
|
182
190
|
/**
|
|
183
|
-
* Get the encrypted auth-broker snapshot cache path (~/.
|
|
191
|
+
* Get the encrypted auth-broker snapshot cache path (~/.zeta/cache/auth-broker-snapshot.enc).
|
|
184
192
|
* Honors the `OMP_AUTH_BROKER_SNAPSHOT_CACHE` env var when set so tests and
|
|
185
193
|
* operators can isolate or relocate the cache file.
|
|
186
194
|
*/
|
|
187
195
|
export declare function getAuthBrokerSnapshotCachePath(): string;
|
|
188
|
-
/** Get the local FastEmbed model cache directory (~/.
|
|
196
|
+
/** Get the local FastEmbed model cache directory (~/.zeta/cache/fastembed). */
|
|
189
197
|
export declare function getFastembedCacheDir(): string;
|
|
190
|
-
/** Get the on-demand fastembed runtime install root (~/.
|
|
198
|
+
/** Get the on-demand fastembed runtime install root (~/.zeta/cache/fastembed-runtime). */
|
|
191
199
|
export declare function getFastembedRuntimeDir(): string;
|
|
192
|
-
/** Get the natives directory (~/.
|
|
200
|
+
/** Get the natives directory (~/.zeta/natives). */
|
|
193
201
|
export declare function getNativesDir(): string;
|
|
194
|
-
/** Get the stats database path (~/.
|
|
202
|
+
/** Get the stats database path (~/.zeta/stats.db). */
|
|
195
203
|
export declare function getStatsDbPath(): string;
|
|
196
|
-
/** Get the autoresearch state directory (~/.
|
|
204
|
+
/** Get the autoresearch state directory (~/.zeta/autoresearch). */
|
|
197
205
|
export declare function getAutoresearchDir(): string;
|
|
198
|
-
/** Get the per-project autoresearch state directory (~/.
|
|
206
|
+
/** Get the per-project autoresearch state directory (~/.zeta/autoresearch/<encoded-project>). */
|
|
199
207
|
export declare function getAutoresearchProjectDir(encodedProject: string): string;
|
|
200
|
-
/** Get the per-project autoresearch SQLite database path (~/.
|
|
208
|
+
/** Get the per-project autoresearch SQLite database path (~/.zeta/autoresearch/<encoded-project>.db). */
|
|
201
209
|
export declare function getAutoresearchDbPath(encodedProject: string): string;
|
|
202
|
-
/** Get the per-run artifact directory (~/.
|
|
210
|
+
/** Get the per-run artifact directory (~/.zeta/autoresearch/<encoded-project>/runs/<runId>). */
|
|
203
211
|
export declare function getAutoresearchRunDir(encodedProject: string, runId: number): string;
|
|
204
|
-
/** Get the security-analysis state directory (~/.
|
|
212
|
+
/** Get the security-analysis state directory (~/.zeta/security). */
|
|
205
213
|
export declare function getSecurityDir(): string;
|
|
206
|
-
/** Get one project's security-analysis state directory (~/.
|
|
214
|
+
/** Get one project's security-analysis state directory (~/.zeta/security/<project-key>). */
|
|
207
215
|
export declare function getSecurityProjectDir(projectKey: string): string;
|
|
208
216
|
/** Get the path to agent.db (SQLite database for settings and auth storage). */
|
|
209
217
|
export declare function getAgentDbPath(agentDir?: string): string;
|
|
210
|
-
/** Get the last-seen-changelog-version marker file (~/.
|
|
218
|
+
/** Get the last-seen-changelog-version marker file (~/.zeta/agent/last-changelog-version). */
|
|
211
219
|
export declare function getLastChangelogVersionPath(agentDir?: string): string;
|
|
212
220
|
/** Get the path to history.db (SQLite database for session history). */
|
|
213
221
|
export declare function getHistoryDbPath(agentDir?: string): string;
|
|
214
222
|
/** Get the path to models.db (model cache database). */
|
|
215
223
|
export declare function getModelDbPath(agentDir?: string): string;
|
|
216
|
-
/** Get the tiny title model cache directory (~/.
|
|
224
|
+
/** Get the tiny title model cache directory (~/.zeta/agent/cache/tiny-models). */
|
|
217
225
|
export declare function getTinyModelsCacheDir(agentDir?: string): string;
|
|
218
|
-
/** Get the document conversion cache directory (~/.
|
|
226
|
+
/** Get the document conversion cache directory (~/.zeta/agent/cache/document-conversions; XDG default: $XDG_CACHE_HOME/zeta/cache/document-conversions). */
|
|
219
227
|
export declare function getDocumentConversionCacheDir(agentDir?: string): string;
|
|
220
|
-
/** Get the sessions directory (~/.
|
|
228
|
+
/** Get the sessions directory (~/.zeta/agent/sessions). */
|
|
221
229
|
export declare function getSessionsDir(agentDir?: string): string;
|
|
222
|
-
/** Get the content-addressed blob store directory (~/.
|
|
230
|
+
/** Get the content-addressed blob store directory (~/.zeta/agent/blobs). */
|
|
223
231
|
export declare function getBlobsDir(agentDir?: string): string;
|
|
224
|
-
/** Get the custom themes directory (~/.
|
|
232
|
+
/** Get the custom themes directory (~/.zeta/agent/themes). */
|
|
225
233
|
export declare function getCustomThemesDir(agentDir?: string): string;
|
|
226
|
-
/** Get the tools directory (~/.
|
|
234
|
+
/** Get the tools directory (~/.zeta/agent/tools). */
|
|
227
235
|
export declare function getToolsDir(agentDir?: string): string;
|
|
228
|
-
/** Get the slash commands directory (~/.
|
|
236
|
+
/** Get the slash commands directory (~/.zeta/agent/commands). */
|
|
229
237
|
export declare function getCommandsDir(agentDir?: string): string;
|
|
230
|
-
/** Get the prompts directory (~/.
|
|
238
|
+
/** Get the prompts directory (~/.zeta/agent/prompts). */
|
|
231
239
|
export declare function getPromptsDir(agentDir?: string): string;
|
|
232
|
-
/** Get the user-level Python modules directory (~/.
|
|
240
|
+
/** Get the user-level Python modules directory (~/.zeta/agent/modules). */
|
|
233
241
|
export declare function getAgentModulesDir(agentDir?: string): string;
|
|
234
|
-
/** Get the memories directory (~/.
|
|
242
|
+
/** Get the memories directory (~/.zeta/agent/memories). */
|
|
235
243
|
export declare function getMemoriesDir(agentDir?: string): string;
|
|
236
|
-
/** Get the terminal sessions directory (~/.
|
|
244
|
+
/** Get the terminal sessions directory (~/.zeta/agent/terminal-sessions). */
|
|
237
245
|
export declare function getTerminalSessionsDir(agentDir?: string): string;
|
|
238
|
-
/** Get the crash log path (~/.
|
|
246
|
+
/** Get the crash log path (~/.zeta/agent/zeta-crash.log). */
|
|
239
247
|
export declare function getCrashLogPath(agentDir?: string): string;
|
|
240
|
-
/** Get the debug log path (~/.
|
|
248
|
+
/** Get the debug log path (~/.zeta/agent/zeta-debug.log). */
|
|
241
249
|
export declare function getDebugLogPath(agentDir?: string): string;
|
|
242
|
-
/** Get the secret placeholder key path (~/.
|
|
250
|
+
/** Get the secret placeholder key path (~/.zeta/agent/secret-placeholder.key; XDG default: $XDG_STATE_HOME/zeta/secret-placeholder.key). Adopts a legacy key on first XDG resolution. */
|
|
243
251
|
export declare function getSecretPlaceholderKeyPath(): string;
|
|
244
|
-
/** Get the daemon runtime directory for a project (~/.
|
|
252
|
+
/** Get the daemon runtime directory for a project (~/.zeta/run/daemons/<hash>; XDG default: $XDG_STATE_HOME/zeta/run/daemons/<hash>). */
|
|
245
253
|
export declare function getDaemonRuntimeDir(projectDir: string): string;
|
|
246
254
|
/** Get a profile-independent runtime directory for a machine-global daemon service. */
|
|
247
255
|
export declare function getGlobalDaemonRuntimeDir(service: string): string;
|
|
248
|
-
/** Get the provider in-flight root directory (~/.
|
|
256
|
+
/** Get the provider in-flight root directory (~/.zeta/run/provider-inflight; XDG default: $XDG_STATE_HOME/zeta/run/provider-inflight). */
|
|
249
257
|
export declare function getProviderInFlightRoot(): string;
|
|
250
|
-
/** Get the marketplaces registry path (~/.
|
|
258
|
+
/** Get the marketplaces registry path (~/.zeta/marketplaces.json; XDG default: $XDG_DATA_HOME/zeta/marketplaces.json). Adopts a legacy registry on first XDG resolution. */
|
|
251
259
|
export declare function getMarketplacesRegistryPath(): string;
|
|
252
|
-
/** Get the project-level Python modules directory (.
|
|
260
|
+
/** Get the project-level Python modules directory (.zeta/modules). */
|
|
253
261
|
export declare function getProjectModulesDir(cwd?: string): string;
|
|
254
|
-
/** Get the project-level prompts directory (.
|
|
262
|
+
/** Get the project-level prompts directory (.zeta/prompts). */
|
|
255
263
|
export declare function getProjectPromptsDir(cwd?: string): string;
|
|
256
|
-
/** Get the project-level plugin overrides path (.
|
|
264
|
+
/** Get the project-level plugin overrides path (.zeta/plugin-overrides.json). */
|
|
257
265
|
export declare function getProjectPluginOverridesPath(cwd?: string): string;
|
|
258
266
|
/** Get the primary MCP config file path (first candidate). */
|
|
259
267
|
export declare function getMCPConfigPath(scope: "user" | "project", cwd?: string): string;
|
|
@@ -264,15 +272,15 @@ export declare function getProjectTrackingDir(cwd?: string): string;
|
|
|
264
272
|
/** Get the global tracking index path (~/.zeta/agent/tracking-index.json). */
|
|
265
273
|
export declare function getTrackingIndexPath(agentDir?: string): string;
|
|
266
274
|
/**
|
|
267
|
-
* Persistent per-install UUID stored at `~/.
|
|
275
|
+
* Persistent per-install UUID stored at `~/.zeta/install-id`.
|
|
268
276
|
*
|
|
269
277
|
* Generated lazily on first call and persisted with `O_CREAT|O_EXCL` so
|
|
270
278
|
* concurrent first-call races don't clobber each other (loser re-reads the
|
|
271
279
|
* winner's id). Survives independently of agent state: deleting
|
|
272
|
-
* `~/.
|
|
280
|
+
* `~/.zeta/agent/` does not regenerate it. Server-side dedup for grievance
|
|
273
281
|
* pushes (and similar telemetry) keys on this id.
|
|
274
282
|
*
|
|
275
|
-
* Anchored to the base config root (`~/.
|
|
283
|
+
* Anchored to the base config root (`~/.zeta/install-id`) regardless of the
|
|
276
284
|
* active profile: install identity is per-install, not per-profile, so every
|
|
277
285
|
* profile shares one id and the global cache stays correct no matter the
|
|
278
286
|
* profile / `getInstallId` call order.
|
package/package.json
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"type": "module",
|
|
3
3
|
"name": "@linxiraos/pi-utils",
|
|
4
|
-
"version": "1.0.
|
|
4
|
+
"version": "1.0.1",
|
|
5
5
|
"description": "Shared utilities for pi packages",
|
|
6
6
|
"homepage": "https://linxira-os.github.io",
|
|
7
7
|
"author": "Can Boluk",
|
|
@@ -31,7 +31,7 @@
|
|
|
31
31
|
"fmt": "biome format --write ."
|
|
32
32
|
},
|
|
33
33
|
"dependencies": {
|
|
34
|
-
"@linxiraos/pi-natives": "1.0.
|
|
34
|
+
"@linxiraos/pi-natives": "1.0.1"
|
|
35
35
|
},
|
|
36
36
|
"devDependencies": {
|
|
37
37
|
"@types/bun": "^1.3.14"
|
package/src/dirs.ts
CHANGED
|
@@ -1,12 +1,12 @@
|
|
|
1
1
|
/**
|
|
2
2
|
* Centralized path helpers for omp config directories.
|
|
3
3
|
*
|
|
4
|
-
* Uses PI_CONFIG_DIR (default ".
|
|
4
|
+
* Uses PI_CONFIG_DIR (default ".zeta") for the config root and
|
|
5
5
|
* PI_CODING_AGENT_DIR to override the agent directory.
|
|
6
6
|
*
|
|
7
7
|
* On Linux, if XDG_DATA_HOME / XDG_STATE_HOME / XDG_CACHE_HOME environment
|
|
8
8
|
* variables are set, paths are redirected to XDG-compliant locations under
|
|
9
|
-
* $XDG_*_HOME/omp/. This requires running `
|
|
9
|
+
* $XDG_*_HOME/omp/. This requires running `zeta config migrate` first to
|
|
10
10
|
* move data to the new locations. No filesystem existence checks are performed
|
|
11
11
|
* — if the env var is set, omp trusts that the migration has been done.
|
|
12
12
|
*/
|
|
@@ -202,21 +202,34 @@ export async function directoryExists(dir: string): Promise<boolean> {
|
|
|
202
202
|
}
|
|
203
203
|
}
|
|
204
204
|
|
|
205
|
-
/** Get the config directory name relative to home (e.g. ".zeta" or PI_CONFIG_DIR override).
|
|
205
|
+
/** Get the config directory name relative to home (e.g. ".zeta" or PI_CONFIG_DIR override). */
|
|
206
206
|
export function getConfigDirName(): string {
|
|
207
207
|
if (process.env.PI_CONFIG_DIR) return process.env.PI_CONFIG_DIR;
|
|
208
|
-
|
|
208
|
+
return ".zeta";
|
|
209
|
+
}
|
|
210
|
+
|
|
211
|
+
/**
|
|
212
|
+
* One-time migration of a legacy `~/.omp` config root to `~/.zeta`. Called
|
|
213
|
+
* from the CLI entrypoint before any user data is written; it only moves the
|
|
214
|
+
* directory when `.zeta` does not exist yet. Zeta keeps no `.omp`
|
|
215
|
+
* compatibility surface afterwards (see AGENTS.md), so this is the single
|
|
216
|
+
* exception that honors pre-existing installs.
|
|
217
|
+
*/
|
|
218
|
+
export function migrateLegacyOmpConfigDir(): void {
|
|
219
|
+
if (process.env.PI_CONFIG_DIR) return;
|
|
209
220
|
const home = os.homedir();
|
|
210
221
|
try {
|
|
211
|
-
|
|
212
|
-
|
|
213
|
-
|
|
214
|
-
if (fs.existsSync(
|
|
215
|
-
|
|
216
|
-
|
|
222
|
+
const zetaDir = path.join(home, ".zeta");
|
|
223
|
+
if (fs.existsSync(zetaDir)) return;
|
|
224
|
+
const ompDir = path.join(home, ".omp");
|
|
225
|
+
if (!fs.existsSync(ompDir)) return;
|
|
226
|
+
fs.renameSync(ompDir, zetaDir);
|
|
227
|
+
} catch {
|
|
228
|
+
// Migration is best-effort; a failed rename must not break startup.
|
|
229
|
+
}
|
|
217
230
|
}
|
|
218
231
|
|
|
219
|
-
/** Get the config agent directory name relative to home (e.g. ".
|
|
232
|
+
/** Get the config agent directory name relative to home (e.g. ".zeta/agent" or PI_CONFIG_DIR + "/agent"). */
|
|
220
233
|
export function getConfigAgentDirName(): string {
|
|
221
234
|
const profile = getActiveProfile();
|
|
222
235
|
return profile ? path.join(getConfigDirName(), "profiles", profile, "agent") : `${getConfigDirName()}/agent`;
|
|
@@ -256,12 +269,12 @@ class DirResolver {
|
|
|
256
269
|
const isDefault = this.agentDir === defaultAgent;
|
|
257
270
|
|
|
258
271
|
// XDG is a Linux convention. On supported platforms, default profile state
|
|
259
|
-
// resolves under $XDG_*_HOME/omp once `
|
|
272
|
+
// resolves under $XDG_*_HOME/omp once `zeta config init-xdg` has migrated
|
|
260
273
|
// the user's data. Named profiles follow a stricter rule: the XDG choice
|
|
261
274
|
// is keyed on the profile-specific XDG path, never the base app root.
|
|
262
275
|
//
|
|
263
276
|
// Why: if we consulted the base app root for named profiles too, the same
|
|
264
|
-
// profile could resolve to `~/.
|
|
277
|
+
// profile could resolve to `~/.zeta/profiles/<name>` on first activation
|
|
265
278
|
// (when no $XDG_*_HOME/omp exists yet) and then silently move to
|
|
266
279
|
// `$XDG_*_HOME/omp/profiles/<name>` the moment the base appeared, orphaning
|
|
267
280
|
// the earlier state. Pinning on the profile path means a profile's location
|
|
@@ -299,7 +312,7 @@ class DirResolver {
|
|
|
299
312
|
state: xdgState ?? this.configRoot,
|
|
300
313
|
cache: xdgCache ?? this.configRoot,
|
|
301
314
|
};
|
|
302
|
-
// XDG flattens the agent/ prefix: ~/.
|
|
315
|
+
// XDG flattens the agent/ prefix: ~/.zeta/agent/sessions → $XDG_DATA_HOME/zeta/sessions
|
|
303
316
|
this.#agentDirs = {
|
|
304
317
|
data: xdgData ?? this.agentDir,
|
|
305
318
|
state: xdgState ?? this.agentDir,
|
|
@@ -339,7 +352,7 @@ class DirResolver {
|
|
|
339
352
|
* agent dir. The profile source can be the active profile or a lower-priority
|
|
340
353
|
* `PI_PROFILE` that was bypassed because `OMP_PROFILE` explicitly selected the
|
|
341
354
|
* default profile. Returns `undefined` in those cases so reset falls back to the
|
|
342
|
-
* standard `~/.
|
|
355
|
+
* standard `~/.zeta/agent`.
|
|
343
356
|
*/
|
|
344
357
|
function resolvePreProfileAgentDir(
|
|
345
358
|
profile: string | undefined,
|
|
@@ -374,7 +387,7 @@ let dirs = new DirResolver({
|
|
|
374
387
|
* unconditionally deleting the env var. Without the snapshot, a process started
|
|
375
388
|
* with `PI_CODING_AGENT_DIR=/custom` then `setProfile("work")` then
|
|
376
389
|
* `setProfile(undefined)` would silently lose `/custom` and fall back to
|
|
377
|
-
* `~/.
|
|
390
|
+
* `~/.zeta/agent`. Captured at module load — ignoring a profile-derived value
|
|
378
391
|
* inherited from a parent's `setProfile` (see {@link resolvePreProfileAgentDir})
|
|
379
392
|
* — and refreshed on `setAgentDir`, since that call is the user explicitly
|
|
380
393
|
* redefining the baseline.
|
|
@@ -411,7 +424,7 @@ export function refreshDirsFromEnv(): void {
|
|
|
411
424
|
// Root directories
|
|
412
425
|
// =============================================================================
|
|
413
426
|
|
|
414
|
-
/** Get the config root directory (~/.
|
|
427
|
+
/** Get the config root directory (~/.zeta). */
|
|
415
428
|
export function getConfigRootDir(): string {
|
|
416
429
|
return dirs.configRoot;
|
|
417
430
|
}
|
|
@@ -498,45 +511,37 @@ export function getActiveProfile(): string | undefined {
|
|
|
498
511
|
export function getProfileRootDir(profile: string | undefined): string {
|
|
499
512
|
return getProfileConfigRoot(normalizeProfileName(profile));
|
|
500
513
|
}
|
|
501
|
-
/** Get the agent config directory (~/.
|
|
514
|
+
/** Get the agent config directory (~/.zeta/agent). */
|
|
502
515
|
export function getAgentDir(): string {
|
|
503
516
|
return dirs.agentDir;
|
|
504
517
|
}
|
|
505
518
|
|
|
506
|
-
/** Get the project-local config directory (.zeta).
|
|
519
|
+
/** Get the project-local config directory (.zeta). */
|
|
507
520
|
export function getProjectAgentDir(cwd: string = getProjectDir()): string {
|
|
508
|
-
|
|
509
|
-
try {
|
|
510
|
-
if (fs.existsSync(zetaDir)) return zetaDir;
|
|
511
|
-
} catch {}
|
|
512
|
-
const ompDir = path.join(cwd, ".omp");
|
|
513
|
-
try {
|
|
514
|
-
if (fs.existsSync(ompDir)) return ompDir;
|
|
515
|
-
} catch {}
|
|
516
|
-
return zetaDir; // default for new projects
|
|
521
|
+
return path.join(cwd, ".zeta");
|
|
517
522
|
}
|
|
518
523
|
|
|
519
524
|
// =============================================================================
|
|
520
|
-
// Config-root subdirectories (~/.
|
|
525
|
+
// Config-root subdirectories (~/.zeta/*)
|
|
521
526
|
// =============================================================================
|
|
522
527
|
|
|
523
|
-
/** Get the reports directory (~/.
|
|
528
|
+
/** Get the reports directory (~/.zeta/reports). */
|
|
524
529
|
export function getReportsDir(): string {
|
|
525
530
|
return dirs.rootSubdir("reports", "state");
|
|
526
531
|
}
|
|
527
532
|
|
|
528
|
-
/** Get the logs directory (~/.
|
|
533
|
+
/** Get the logs directory (~/.zeta/logs). */
|
|
529
534
|
export function getLogsDir(): string {
|
|
530
535
|
return dirs.rootSubdir("logs", "state");
|
|
531
536
|
}
|
|
532
537
|
|
|
533
|
-
/** Get this process's dated log path (~/.
|
|
538
|
+
/** Get this process's dated log path (~/.zeta/logs/zeta.YYYY-MM-DD.PID.log). */
|
|
534
539
|
export function getLogPath(date = new Date(), pid = process.pid): string {
|
|
535
540
|
return path.join(getLogsDir(), `${APP_NAME}.${date.toISOString().slice(0, 10)}.${pid}.log`);
|
|
536
541
|
}
|
|
537
542
|
|
|
538
543
|
/**
|
|
539
|
-
* Get the plugins directory (~/.
|
|
544
|
+
* Get the plugins directory (~/.zeta/plugins or its XDG equivalent).
|
|
540
545
|
*
|
|
541
546
|
* No-arg form (production callers) goes through the XDG-aware DirResolver so
|
|
542
547
|
* reads and writes always agree. The optional `home` parameter is for test
|
|
@@ -552,22 +557,22 @@ export function getPluginsDir(home?: string): string {
|
|
|
552
557
|
return dirs.rootSubdir("plugins", "data");
|
|
553
558
|
}
|
|
554
559
|
|
|
555
|
-
/** Where npm installs packages (~/.
|
|
560
|
+
/** Where npm installs packages (~/.zeta/plugins/node_modules). */
|
|
556
561
|
export function getPluginsNodeModules(home?: string): string {
|
|
557
562
|
return path.join(getPluginsDir(home), "node_modules");
|
|
558
563
|
}
|
|
559
564
|
|
|
560
|
-
/** Plugin manifest (~/.
|
|
565
|
+
/** Plugin manifest (~/.zeta/plugins/package.json). */
|
|
561
566
|
export function getPluginsPackageJson(home?: string): string {
|
|
562
567
|
return path.join(getPluginsDir(home), "package.json");
|
|
563
568
|
}
|
|
564
569
|
|
|
565
|
-
/** Plugin lock file (~/.
|
|
570
|
+
/** Plugin lock file (~/.zeta/plugins/zeta-plugins.lock.json). */
|
|
566
571
|
export function getPluginsLockfile(home?: string): string {
|
|
567
|
-
return path.join(getPluginsDir(home), "
|
|
572
|
+
return path.join(getPluginsDir(home), "zeta-plugins.lock.json");
|
|
568
573
|
}
|
|
569
574
|
|
|
570
|
-
/** Get the remote mount directory (~/.
|
|
575
|
+
/** Get the remote mount directory (~/.zeta/remote). */
|
|
571
576
|
export function getRemoteDir(): string {
|
|
572
577
|
return dirs.rootSubdir("remote", "data");
|
|
573
578
|
}
|
|
@@ -577,7 +582,7 @@ export function getRemoteDir(): string {
|
|
|
577
582
|
* empty/whitespace input or a path that is still relative after expansion.
|
|
578
583
|
*
|
|
579
584
|
* A worktree base is process-global and consumed by both creation
|
|
580
|
-
* (PR checkout, task isolation) and cleanup (`
|
|
585
|
+
* (PR checkout, task isolation) and cleanup (`zeta worktree`). A relative value
|
|
581
586
|
* would resolve against whatever cwd happened to launch `omp`, so checkout and
|
|
582
587
|
* cleanup could disagree — we refuse it rather than silently bind it to cwd.
|
|
583
588
|
*/
|
|
@@ -594,9 +599,9 @@ let worktreesDirOverride: string | undefined;
|
|
|
594
599
|
|
|
595
600
|
/**
|
|
596
601
|
* Relocate the base directory for agent-managed worktrees (PR checkouts, task
|
|
597
|
-
* isolation, and `
|
|
602
|
+
* isolation, and `zeta worktree` cleanup all read the same base). Driven by the
|
|
598
603
|
* `worktree.base` setting in coding-agent; pass `undefined`/empty to clear and
|
|
599
|
-
* fall back to `OMP_WORKTREE_DIR` or the `~/.
|
|
604
|
+
* fall back to `OMP_WORKTREE_DIR` or the `~/.zeta/wt` default.
|
|
600
605
|
*
|
|
601
606
|
* `~` is expanded and a relative path is rejected (see {@link resolveWorktreeBase}).
|
|
602
607
|
* Returns the absolute path that took effect, or `undefined` if the input was
|
|
@@ -611,7 +616,7 @@ export function setWorktreesDir(dir: string | undefined): string | undefined {
|
|
|
611
616
|
/**
|
|
612
617
|
* Get the agent-managed worktrees directory. Resolution order: the
|
|
613
618
|
* `OMP_WORKTREE_DIR` env var, then the {@link setWorktreesDir} override (the
|
|
614
|
-
* `worktree.base` setting), then the `~/.
|
|
619
|
+
* `worktree.base` setting), then the `~/.zeta/wt` default. The env var and the
|
|
615
620
|
* override are both `~`-expanded and must be absolute; a relative value is
|
|
616
621
|
* ignored and resolution falls through.
|
|
617
622
|
*/
|
|
@@ -619,32 +624,32 @@ export function getWorktreesDir(): string {
|
|
|
619
624
|
return resolveWorktreeBase(process.env.OMP_WORKTREE_DIR) ?? worktreesDirOverride ?? dirs.rootSubdir("wt", "data");
|
|
620
625
|
}
|
|
621
626
|
|
|
622
|
-
/** Get the SSH control socket directory (~/.
|
|
627
|
+
/** Get the SSH control socket directory (~/.zeta/ssh-control). */
|
|
623
628
|
export function getSshControlDir(): string {
|
|
624
629
|
return dirs.rootSubdir("ssh-control", "state");
|
|
625
630
|
}
|
|
626
631
|
|
|
627
|
-
/** Get the remote host info directory (~/.
|
|
632
|
+
/** Get the remote host info directory (~/.zeta/remote-host). */
|
|
628
633
|
export function getRemoteHostDir(): string {
|
|
629
634
|
return dirs.rootSubdir("remote-host", "data");
|
|
630
635
|
}
|
|
631
636
|
|
|
632
|
-
/** Get the managed Python venv directory (~/.
|
|
637
|
+
/** Get the managed Python venv directory (~/.zeta/python-env). */
|
|
633
638
|
export function getPythonEnvDir(): string {
|
|
634
639
|
return dirs.rootSubdir("python-env", "data");
|
|
635
640
|
}
|
|
636
641
|
|
|
637
|
-
/** Get the shared Python gateway state directory (~/.
|
|
642
|
+
/** Get the shared Python gateway state directory (~/.zeta/agent/python-gateway; XDG default: $XDG_STATE_HOME/zeta/python-gateway). */
|
|
638
643
|
export function getPythonGatewayDir(): string {
|
|
639
644
|
return dirs.agentSubdir(undefined, "python-gateway", "state");
|
|
640
645
|
}
|
|
641
646
|
|
|
642
|
-
/** Get the puppeteer sandbox directory (~/.
|
|
647
|
+
/** Get the puppeteer sandbox directory (~/.zeta/puppeteer). */
|
|
643
648
|
export function getPuppeteerDir(): string {
|
|
644
649
|
return dirs.rootSubdir("puppeteer", "cache");
|
|
645
650
|
}
|
|
646
651
|
|
|
647
|
-
/** Get the browser relay extension install directory (~/.
|
|
652
|
+
/** Get the browser relay extension install directory (~/.zeta/browser-relay). */
|
|
648
653
|
export function getBrowserRelayDir(): string {
|
|
649
654
|
return dirs.rootSubdir("browser-relay", "data");
|
|
650
655
|
}
|
|
@@ -654,7 +659,7 @@ export function getDocsRsCacheDir(): string {
|
|
|
654
659
|
return dirs.rootSubdir("webcache", "cache");
|
|
655
660
|
}
|
|
656
661
|
|
|
657
|
-
/** Get the auto-QA grievances SQLite database path (~/.
|
|
662
|
+
/** Get the auto-QA grievances SQLite database path (~/.zeta/autoqa.db; XDG: $XDG_DATA_HOME/zeta/autoqa.db). */
|
|
658
663
|
export function getAutoQaDbPath(): string {
|
|
659
664
|
return dirs.rootSubdir("autoqa.db", "data");
|
|
660
665
|
}
|
|
@@ -662,7 +667,7 @@ export function getAutoQaDbPath(): string {
|
|
|
662
667
|
* Stable 7-character hex digest of an absolute filesystem path.
|
|
663
668
|
*
|
|
664
669
|
* Used to pack the project identity into a single short fs-safe segment
|
|
665
|
-
* (e.g. PR-checkout and task-isolation worktree dirs under `~/.
|
|
670
|
+
* (e.g. PR-checkout and task-isolation worktree dirs under `~/.zeta/wt/`).
|
|
666
671
|
* Bun.hash is non-cryptographic — collision space is ~2^28, which is fine
|
|
667
672
|
* for naming a handful of repos on a single machine. Same input on the
|
|
668
673
|
* same Bun runtime yields the same output.
|
|
@@ -671,18 +676,18 @@ export function hashPath(absPath: string): string {
|
|
|
671
676
|
return Bun.hash(path.resolve(absPath)).toString(16).padStart(16, "0").slice(-7);
|
|
672
677
|
}
|
|
673
678
|
|
|
674
|
-
/** Get the path to a single worktree directory (~/.
|
|
679
|
+
/** Get the path to a single worktree directory (~/.zeta/wt/<segment>). */
|
|
675
680
|
export function getWorktreeDir(segment: string): string {
|
|
676
681
|
return path.join(getWorktreesDir(), segment);
|
|
677
682
|
}
|
|
678
683
|
|
|
679
|
-
/** Get the GPU cache path (~/.
|
|
684
|
+
/** Get the GPU cache path (~/.zeta/gpu_cache.json). */
|
|
680
685
|
export function getGpuCachePath(): string {
|
|
681
686
|
return dirs.rootSubdir("gpu_cache.json", "cache");
|
|
682
687
|
}
|
|
683
688
|
|
|
684
689
|
/**
|
|
685
|
-
* Get the GitHub view cache database path (~/.
|
|
690
|
+
* Get the GitHub view cache database path (~/.zeta/cache/github-cache.db).
|
|
686
691
|
* Honors the `OMP_GITHUB_CACHE_DB` env var when set so tests can isolate the
|
|
687
692
|
* cache file without touching the rest of the config root.
|
|
688
693
|
*/
|
|
@@ -693,7 +698,7 @@ export function getGithubCacheDbPath(): string {
|
|
|
693
698
|
}
|
|
694
699
|
|
|
695
700
|
/**
|
|
696
|
-
* Get the encrypted auth-broker snapshot cache path (~/.
|
|
701
|
+
* Get the encrypted auth-broker snapshot cache path (~/.zeta/cache/auth-broker-snapshot.enc).
|
|
697
702
|
* Honors the `OMP_AUTH_BROKER_SNAPSHOT_CACHE` env var when set so tests and
|
|
698
703
|
* operators can isolate or relocate the cache file.
|
|
699
704
|
*/
|
|
@@ -703,58 +708,58 @@ export function getAuthBrokerSnapshotCachePath(): string {
|
|
|
703
708
|
return dirs.rootSubdir(path.join("cache", "auth-broker-snapshot.enc"), "cache");
|
|
704
709
|
}
|
|
705
710
|
|
|
706
|
-
/** Get the local FastEmbed model cache directory (~/.
|
|
711
|
+
/** Get the local FastEmbed model cache directory (~/.zeta/cache/fastembed). */
|
|
707
712
|
export function getFastembedCacheDir(): string {
|
|
708
713
|
return dirs.rootSubdir(path.join("cache", "fastembed"), "cache");
|
|
709
714
|
}
|
|
710
715
|
|
|
711
|
-
/** Get the on-demand fastembed runtime install root (~/.
|
|
716
|
+
/** Get the on-demand fastembed runtime install root (~/.zeta/cache/fastembed-runtime). */
|
|
712
717
|
export function getFastembedRuntimeDir(): string {
|
|
713
718
|
return dirs.rootSubdir(path.join("cache", "fastembed-runtime"), "cache");
|
|
714
719
|
}
|
|
715
720
|
|
|
716
|
-
/** Get the natives directory (~/.
|
|
721
|
+
/** Get the natives directory (~/.zeta/natives). */
|
|
717
722
|
export function getNativesDir(): string {
|
|
718
723
|
return dirs.rootSubdir("natives", "cache");
|
|
719
724
|
}
|
|
720
725
|
|
|
721
|
-
/** Get the stats database path (~/.
|
|
726
|
+
/** Get the stats database path (~/.zeta/stats.db). */
|
|
722
727
|
export function getStatsDbPath(): string {
|
|
723
728
|
return dirs.rootSubdir("stats.db", "data");
|
|
724
729
|
}
|
|
725
730
|
|
|
726
|
-
/** Get the autoresearch state directory (~/.
|
|
731
|
+
/** Get the autoresearch state directory (~/.zeta/autoresearch). */
|
|
727
732
|
export function getAutoresearchDir(): string {
|
|
728
733
|
return dirs.rootSubdir("autoresearch", "state");
|
|
729
734
|
}
|
|
730
735
|
|
|
731
|
-
/** Get the per-project autoresearch state directory (~/.
|
|
736
|
+
/** Get the per-project autoresearch state directory (~/.zeta/autoresearch/<encoded-project>). */
|
|
732
737
|
export function getAutoresearchProjectDir(encodedProject: string): string {
|
|
733
738
|
return path.join(getAutoresearchDir(), encodedProject);
|
|
734
739
|
}
|
|
735
740
|
|
|
736
|
-
/** Get the per-project autoresearch SQLite database path (~/.
|
|
741
|
+
/** Get the per-project autoresearch SQLite database path (~/.zeta/autoresearch/<encoded-project>.db). */
|
|
737
742
|
export function getAutoresearchDbPath(encodedProject: string): string {
|
|
738
743
|
return path.join(getAutoresearchDir(), `${encodedProject}.db`);
|
|
739
744
|
}
|
|
740
745
|
|
|
741
|
-
/** Get the per-run artifact directory (~/.
|
|
746
|
+
/** Get the per-run artifact directory (~/.zeta/autoresearch/<encoded-project>/runs/<runId>). */
|
|
742
747
|
export function getAutoresearchRunDir(encodedProject: string, runId: number): string {
|
|
743
748
|
return path.join(getAutoresearchProjectDir(encodedProject), "runs", String(runId).padStart(4, "0"));
|
|
744
749
|
}
|
|
745
750
|
|
|
746
|
-
/** Get the security-analysis state directory (~/.
|
|
751
|
+
/** Get the security-analysis state directory (~/.zeta/security). */
|
|
747
752
|
export function getSecurityDir(): string {
|
|
748
753
|
return dirs.rootSubdir("security", "state");
|
|
749
754
|
}
|
|
750
755
|
|
|
751
|
-
/** Get one project's security-analysis state directory (~/.
|
|
756
|
+
/** Get one project's security-analysis state directory (~/.zeta/security/<project-key>). */
|
|
752
757
|
export function getSecurityProjectDir(projectKey: string): string {
|
|
753
758
|
return path.join(getSecurityDir(), projectKey);
|
|
754
759
|
}
|
|
755
760
|
|
|
756
761
|
// =============================================================================
|
|
757
|
-
// Agent subdirectories (~/.
|
|
762
|
+
// Agent subdirectories (~/.zeta/agent/*)
|
|
758
763
|
// =============================================================================
|
|
759
764
|
|
|
760
765
|
/** Get the path to agent.db (SQLite database for settings and auth storage). */
|
|
@@ -762,7 +767,7 @@ export function getAgentDbPath(agentDir?: string): string {
|
|
|
762
767
|
return dirs.agentSubdir(agentDir, "agent.db", "data");
|
|
763
768
|
}
|
|
764
769
|
|
|
765
|
-
/** Get the last-seen-changelog-version marker file (~/.
|
|
770
|
+
/** Get the last-seen-changelog-version marker file (~/.zeta/agent/last-changelog-version). */
|
|
766
771
|
export function getLastChangelogVersionPath(agentDir?: string): string {
|
|
767
772
|
return dirs.agentSubdir(agentDir, "last-changelog-version", "state");
|
|
768
773
|
}
|
|
@@ -777,67 +782,67 @@ export function getModelDbPath(agentDir?: string): string {
|
|
|
777
782
|
return dirs.agentSubdir(agentDir, "models.db", "data");
|
|
778
783
|
}
|
|
779
784
|
|
|
780
|
-
/** Get the tiny title model cache directory (~/.
|
|
785
|
+
/** Get the tiny title model cache directory (~/.zeta/agent/cache/tiny-models). */
|
|
781
786
|
export function getTinyModelsCacheDir(agentDir?: string): string {
|
|
782
787
|
return dirs.agentSubdir(agentDir, path.join("cache", "tiny-models"), "cache");
|
|
783
788
|
}
|
|
784
789
|
|
|
785
|
-
/** Get the document conversion cache directory (~/.
|
|
790
|
+
/** Get the document conversion cache directory (~/.zeta/agent/cache/document-conversions; XDG default: $XDG_CACHE_HOME/zeta/cache/document-conversions). */
|
|
786
791
|
export function getDocumentConversionCacheDir(agentDir?: string): string {
|
|
787
792
|
return dirs.agentSubdir(agentDir, path.join("cache", "document-conversions"), "cache");
|
|
788
793
|
}
|
|
789
794
|
|
|
790
|
-
/** Get the sessions directory (~/.
|
|
795
|
+
/** Get the sessions directory (~/.zeta/agent/sessions). */
|
|
791
796
|
export function getSessionsDir(agentDir?: string): string {
|
|
792
797
|
return dirs.agentSubdir(agentDir, "sessions", "data");
|
|
793
798
|
}
|
|
794
799
|
|
|
795
|
-
/** Get the content-addressed blob store directory (~/.
|
|
800
|
+
/** Get the content-addressed blob store directory (~/.zeta/agent/blobs). */
|
|
796
801
|
export function getBlobsDir(agentDir?: string): string {
|
|
797
802
|
return dirs.agentSubdir(agentDir, "blobs", "data");
|
|
798
803
|
}
|
|
799
804
|
|
|
800
|
-
/** Get the custom themes directory (~/.
|
|
805
|
+
/** Get the custom themes directory (~/.zeta/agent/themes). */
|
|
801
806
|
export function getCustomThemesDir(agentDir?: string): string {
|
|
802
807
|
return dirs.agentSubdir(agentDir, "themes");
|
|
803
808
|
}
|
|
804
809
|
|
|
805
|
-
/** Get the tools directory (~/.
|
|
810
|
+
/** Get the tools directory (~/.zeta/agent/tools). */
|
|
806
811
|
export function getToolsDir(agentDir?: string): string {
|
|
807
812
|
return dirs.agentSubdir(agentDir, "tools");
|
|
808
813
|
}
|
|
809
814
|
|
|
810
|
-
/** Get the slash commands directory (~/.
|
|
815
|
+
/** Get the slash commands directory (~/.zeta/agent/commands). */
|
|
811
816
|
export function getCommandsDir(agentDir?: string): string {
|
|
812
817
|
return dirs.agentSubdir(agentDir, "commands");
|
|
813
818
|
}
|
|
814
819
|
|
|
815
|
-
/** Get the prompts directory (~/.
|
|
820
|
+
/** Get the prompts directory (~/.zeta/agent/prompts). */
|
|
816
821
|
export function getPromptsDir(agentDir?: string): string {
|
|
817
822
|
return dirs.agentSubdir(agentDir, "prompts");
|
|
818
823
|
}
|
|
819
824
|
|
|
820
|
-
/** Get the user-level Python modules directory (~/.
|
|
825
|
+
/** Get the user-level Python modules directory (~/.zeta/agent/modules). */
|
|
821
826
|
export function getAgentModulesDir(agentDir?: string): string {
|
|
822
827
|
return dirs.agentSubdir(agentDir, "modules");
|
|
823
828
|
}
|
|
824
829
|
|
|
825
|
-
/** Get the memories directory (~/.
|
|
830
|
+
/** Get the memories directory (~/.zeta/agent/memories). */
|
|
826
831
|
export function getMemoriesDir(agentDir?: string): string {
|
|
827
832
|
return dirs.agentSubdir(agentDir, "memories", "state");
|
|
828
833
|
}
|
|
829
834
|
|
|
830
|
-
/** Get the terminal sessions directory (~/.
|
|
835
|
+
/** Get the terminal sessions directory (~/.zeta/agent/terminal-sessions). */
|
|
831
836
|
export function getTerminalSessionsDir(agentDir?: string): string {
|
|
832
837
|
return dirs.agentSubdir(agentDir, "terminal-sessions", "state");
|
|
833
838
|
}
|
|
834
839
|
|
|
835
|
-
/** Get the crash log path (~/.
|
|
840
|
+
/** Get the crash log path (~/.zeta/agent/zeta-crash.log). */
|
|
836
841
|
export function getCrashLogPath(agentDir?: string): string {
|
|
837
|
-
return dirs.agentSubdir(agentDir, "
|
|
842
|
+
return dirs.agentSubdir(agentDir, "zeta-crash.log", "state");
|
|
838
843
|
}
|
|
839
844
|
|
|
840
|
-
/** Get the debug log path (~/.
|
|
845
|
+
/** Get the debug log path (~/.zeta/agent/zeta-debug.log). */
|
|
841
846
|
export function getDebugLogPath(agentDir?: string): string {
|
|
842
847
|
return dirs.agentSubdir(agentDir, `${APP_NAME}-debug.log`, "state");
|
|
843
848
|
}
|
|
@@ -861,14 +866,14 @@ function adoptLegacyFile(legacyPath: string, targetPath: string): void {
|
|
|
861
866
|
}
|
|
862
867
|
}
|
|
863
868
|
|
|
864
|
-
/** Get the secret placeholder key path (~/.
|
|
869
|
+
/** Get the secret placeholder key path (~/.zeta/agent/secret-placeholder.key; XDG default: $XDG_STATE_HOME/zeta/secret-placeholder.key). Adopts a legacy key on first XDG resolution. */
|
|
865
870
|
export function getSecretPlaceholderKeyPath(): string {
|
|
866
871
|
const keyPath = dirs.agentSubdir(undefined, "secret-placeholder.key", "state");
|
|
867
872
|
adoptLegacyFile(path.join(dirs.agentDir, "secret-placeholder.key"), keyPath);
|
|
868
873
|
return keyPath;
|
|
869
874
|
}
|
|
870
875
|
|
|
871
|
-
/** Get the daemon runtime directory for a project (~/.
|
|
876
|
+
/** Get the daemon runtime directory for a project (~/.zeta/run/daemons/<hash>; XDG default: $XDG_STATE_HOME/zeta/run/daemons/<hash>). */
|
|
872
877
|
export function getDaemonRuntimeDir(projectDir: string): string {
|
|
873
878
|
const key = Bun.hash.wyhash(path.resolve(projectDir)).toString(16).padStart(16, "0");
|
|
874
879
|
return dirs.rootSubdir(path.join("run", "daemons", key), "state");
|
|
@@ -882,12 +887,12 @@ export function getGlobalDaemonRuntimeDir(service: string): string {
|
|
|
882
887
|
return path.join(getBaseConfigRoot(), "run", "daemons", "global", service);
|
|
883
888
|
}
|
|
884
889
|
|
|
885
|
-
/** Get the provider in-flight root directory (~/.
|
|
890
|
+
/** Get the provider in-flight root directory (~/.zeta/run/provider-inflight; XDG default: $XDG_STATE_HOME/zeta/run/provider-inflight). */
|
|
886
891
|
export function getProviderInFlightRoot(): string {
|
|
887
892
|
return dirs.rootSubdir(path.join("run", "provider-inflight"), "state");
|
|
888
893
|
}
|
|
889
894
|
|
|
890
|
-
/** Get the marketplaces registry path (~/.
|
|
895
|
+
/** Get the marketplaces registry path (~/.zeta/marketplaces.json; XDG default: $XDG_DATA_HOME/zeta/marketplaces.json). Adopts a legacy registry on first XDG resolution. */
|
|
891
896
|
export function getMarketplacesRegistryPath(): string {
|
|
892
897
|
const registryPath = dirs.rootSubdir("marketplaces.json", "data");
|
|
893
898
|
adoptLegacyFile(path.join(dirs.configRoot, "marketplaces.json"), registryPath);
|
|
@@ -895,20 +900,20 @@ export function getMarketplacesRegistryPath(): string {
|
|
|
895
900
|
}
|
|
896
901
|
|
|
897
902
|
// =============================================================================
|
|
898
|
-
// Project subdirectories (.
|
|
903
|
+
// Project subdirectories (.zeta/*)
|
|
899
904
|
// =============================================================================
|
|
900
905
|
|
|
901
|
-
/** Get the project-level Python modules directory (.
|
|
906
|
+
/** Get the project-level Python modules directory (.zeta/modules). */
|
|
902
907
|
export function getProjectModulesDir(cwd: string = getProjectDir()): string {
|
|
903
908
|
return path.join(getProjectAgentDir(cwd), "modules");
|
|
904
909
|
}
|
|
905
910
|
|
|
906
|
-
/** Get the project-level prompts directory (.
|
|
911
|
+
/** Get the project-level prompts directory (.zeta/prompts). */
|
|
907
912
|
export function getProjectPromptsDir(cwd: string = getProjectDir()): string {
|
|
908
913
|
return path.join(getProjectAgentDir(cwd), "prompts");
|
|
909
914
|
}
|
|
910
915
|
|
|
911
|
-
/** Get the project-level plugin overrides path (.
|
|
916
|
+
/** Get the project-level plugin overrides path (.zeta/plugin-overrides.json). */
|
|
912
917
|
export function getProjectPluginOverridesPath(cwd: string = getProjectDir()): string {
|
|
913
918
|
return path.join(getProjectAgentDir(cwd), "plugin-overrides.json");
|
|
914
919
|
}
|
|
@@ -957,15 +962,15 @@ const INSTALL_ID_FILE = "install-id";
|
|
|
957
962
|
const UUID_RE = /^[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}$/i;
|
|
958
963
|
|
|
959
964
|
/**
|
|
960
|
-
* Persistent per-install UUID stored at `~/.
|
|
965
|
+
* Persistent per-install UUID stored at `~/.zeta/install-id`.
|
|
961
966
|
*
|
|
962
967
|
* Generated lazily on first call and persisted with `O_CREAT|O_EXCL` so
|
|
963
968
|
* concurrent first-call races don't clobber each other (loser re-reads the
|
|
964
969
|
* winner's id). Survives independently of agent state: deleting
|
|
965
|
-
* `~/.
|
|
970
|
+
* `~/.zeta/agent/` does not regenerate it. Server-side dedup for grievance
|
|
966
971
|
* pushes (and similar telemetry) keys on this id.
|
|
967
972
|
*
|
|
968
|
-
* Anchored to the base config root (`~/.
|
|
973
|
+
* Anchored to the base config root (`~/.zeta/install-id`) regardless of the
|
|
969
974
|
* active profile: install identity is per-install, not per-profile, so every
|
|
970
975
|
* profile shares one id and the global cache stays correct no matter the
|
|
971
976
|
* profile / `getInstallId` call order.
|
package/src/logger.ts
CHANGED
|
@@ -1,12 +1,12 @@
|
|
|
1
1
|
/**
|
|
2
|
-
* Centralized logger for
|
|
2
|
+
* Centralized logger for zeta.
|
|
3
3
|
*
|
|
4
|
-
* Default: rotating `~/.
|
|
4
|
+
* Default: rotating `~/.zeta/logs/zeta.<DATE>.<PID>.log`, no console output (writing
|
|
5
5
|
* to stdout/stderr would corrupt the TUI). Long-running headless services
|
|
6
6
|
* (the auth broker, etc.) call {@link setTransports} to swap in a console
|
|
7
7
|
* transport so a process supervisor (pm2, journald, k8s) captures the logs.
|
|
8
8
|
*
|
|
9
|
-
* Each entry includes `process.pid` so concurrent
|
|
9
|
+
* Each entry includes `process.pid` so concurrent zeta instances stay
|
|
10
10
|
* traceable.
|
|
11
11
|
*/
|
|
12
12
|
import { AsyncLocalStorage } from "node:async_hooks";
|
|
@@ -53,8 +53,8 @@ function emitToSinks(level: LogLevel, message: string, context: Record<string, u
|
|
|
53
53
|
}
|
|
54
54
|
}
|
|
55
55
|
|
|
56
|
-
const PROCESS_LOG_PATTERN = /^
|
|
57
|
-
const PROCESS_AUDIT_PATTERN = /^\.
|
|
56
|
+
const PROCESS_LOG_PATTERN = /^zeta\.\d{4}-\d{2}-\d{2}\.(\d+)\.log(?:\.\d+)?$/;
|
|
57
|
+
const PROCESS_AUDIT_PATTERN = /^\.zeta\.(\d+)-audit\.json$/;
|
|
58
58
|
const RETAINED_STALE_LOG_FILES = 5;
|
|
59
59
|
|
|
60
60
|
function processIsRunning(pid: number): boolean {
|
|
@@ -201,11 +201,11 @@ function makeFileTransport(dir?: string): RotatingFileSink {
|
|
|
201
201
|
pruneStaleProcessLogs(logsDir);
|
|
202
202
|
return new RotatingFileSink({
|
|
203
203
|
directory: logsDir,
|
|
204
|
-
filenamePrefix: "
|
|
204
|
+
filenamePrefix: "zeta",
|
|
205
205
|
filenameSuffix: String(process.pid),
|
|
206
206
|
maxBytes: 10 * 1024 * 1024,
|
|
207
207
|
maxFiles: 5,
|
|
208
|
-
auditFile: path.join(logsDir, `.
|
|
208
|
+
auditFile: path.join(logsDir, `.zeta.${process.pid}-audit.json`),
|
|
209
209
|
});
|
|
210
210
|
}
|
|
211
211
|
|
package/src/stderr-guard.ts
CHANGED
|
@@ -104,7 +104,7 @@ export function suppressTerminalStderr(options?: SuppressTerminalStderrOptions):
|
|
|
104
104
|
try {
|
|
105
105
|
const redirectPath = options?.redirectPath ?? getLogPath();
|
|
106
106
|
// getLogsDir() only computes the path; the logger creates it lazily, so
|
|
107
|
-
// on a fresh profile ~/.
|
|
107
|
+
// on a fresh profile ~/.zeta/logs may not exist yet. Create it here so
|
|
108
108
|
// diagnostics land in the log instead of falling through to /dev/null.
|
|
109
109
|
fs.mkdirSync(path.dirname(redirectPath), { recursive: true });
|
|
110
110
|
redirectFd = fs.openSync(redirectPath, "a");
|