@agimon-ai/doompi 0.0.1-alpha.102 → 0.0.1-alpha.104

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/README.md CHANGED
@@ -51,7 +51,7 @@ releases.
51
51
 
52
52
  - Node.js 22.19.0 or newer
53
53
  - Release targets: macOS arm64, Linux x64, and Linux arm64
54
- - Pi 0.87.1 and Pi TUI 0.87.1 for packages that declare them as peer requirements
54
+ - Pi 0.99.1 and Pi TUI 0.99.1 for packages that declare them as peer requirements
55
55
 
56
56
  ## Try DoomPi without replacing your Pi setup
57
57
 
@@ -18,7 +18,11 @@ const MANAGED_KEYS = [
18
18
  "quietStartup"
19
19
  ];
20
20
  const DPI_MANAGED_SETTINGS = {
21
- extensions: ["@agimon-ai/doompi", "!extensions/**"],
21
+ extensions: [
22
+ "@agimon-ai/doompi",
23
+ "!extensions/**",
24
+ ..._agimon_ai_doompi_core_runtimePiSettings.DISABLED_PI_BUILTINS
25
+ ],
22
26
  themes: ["themes/doom-pi-dark.json"],
23
27
  theme: "doom-pi-dark",
24
28
  quietStartup: true
@@ -86,12 +90,16 @@ function resolveDpiManagedSettings(cwd, environment = process.env) {
86
90
  if (!registration) return DPI_MANAGED_SETTINGS;
87
91
  return {
88
92
  ...DPI_MANAGED_SETTINGS,
89
- extensions: [registration.package.root, "!extensions/**"]
93
+ extensions: [
94
+ registration.package.root,
95
+ "!extensions/**",
96
+ ..._agimon_ai_doompi_core_runtimePiSettings.DISABLED_PI_BUILTINS
97
+ ]
90
98
  };
91
99
  } catch {
92
100
  return {
93
101
  ...DPI_MANAGED_SETTINGS,
94
- extensions: ["!extensions/**"]
102
+ extensions: ["!extensions/**", ..._agimon_ai_doompi_core_runtimePiSettings.DISABLED_PI_BUILTINS]
95
103
  };
96
104
  }
97
105
  }
@@ -1 +1 @@
1
- {"version":3,"file":"dpiSettings.cjs","names":["path","piCliPath","pathToFileURL","findRepositoryRoot","os","readSyncRegistration","piAgentDirectory"],"sources":["../../../../src/builders/cli/dpiSettings.ts"],"sourcesContent":["import os from 'node:os';\nimport path from 'node:path';\nimport { pathToFileURL } from 'node:url';\n\nimport { piCliPath } from '@agimon-ai/doompi-core/moduleResolution';\nimport { piAgentDirectory } from '@agimon-ai/doompi-core/runtimePiSettings';\nimport { readSyncRegistration } from '@agimon-ai/doompi-core/syncRegistration';\nimport type { SettingsManager, SettingsManagerCreateOptions } from '@earendil-works/pi-coding-agent';\n\nimport { findRepositoryRoot } from '../../composition/repository';\n\nconst GLOBAL_SCOPE = 'global';\nconst PROJECT_SCOPE = 'project';\nconst MANAGED_KEYS = ['extensions', 'themes', 'theme', 'quietStartup'] as const;\n\nexport interface DpiManagedSettings {\n extensions: string[];\n themes: string[];\n theme: string;\n quietStartup: boolean;\n}\n\nexport const DPI_MANAGED_SETTINGS: DpiManagedSettings = {\n extensions: ['@agimon-ai/doompi', '!extensions/**'],\n themes: ['themes/doom-pi-dark.json'],\n theme: 'doom-pi-dark',\n quietStartup: true,\n};\n\nexport type DpiSettingsScope = typeof GLOBAL_SCOPE | typeof PROJECT_SCOPE;\n\nexport interface DpiSettingsStorageBackend {\n withLock(scope: DpiSettingsScope, callback: (current: string | undefined) => string | undefined): void;\n}\n\ninterface SettingsManagerClass {\n create(this: void, cwd: string, agentDir?: string, options?: SettingsManagerCreateOptions): SettingsManager;\n fromStorage(this: void, storage: DpiSettingsStorageBackend, options?: SettingsManagerCreateOptions): SettingsManager;\n}\n\ninterface FileSettingsStorageConstructor {\n new (cwd: string, agentDir: string): DpiSettingsStorageBackend;\n}\n\nexport interface PiSettingsRuntime {\n FileSettingsStorage: FileSettingsStorageConstructor;\n SettingsManager: SettingsManagerClass;\n}\n\nfunction isRecord(value: unknown): value is Record<string, unknown> {\n return typeof value === 'object' && value !== null && !Array.isArray(value);\n}\n\nfunction parseSettings(content: string | undefined): Record<string, unknown> {\n if (content === undefined) return {};\n const parsed: unknown = JSON.parse(content);\n if (!isRecord(parsed)) throw new SyntaxError('Pi settings must contain a JSON object');\n return parsed;\n}\n\nfunction managedView(\n scope: DpiSettingsScope,\n current: string | undefined,\n managedSettings: DpiManagedSettings,\n): string | undefined {\n if (scope === PROJECT_SCOPE && current === undefined) return undefined;\n const settings = parseSettings(current);\n if (scope === GLOBAL_SCOPE) Object.assign(settings, managedSettings);\n else for (const key of MANAGED_KEYS) delete settings[key];\n return JSON.stringify(settings, null, 2);\n}\n\nfunction restorePersistedSettings(current: string | undefined, next: string): string {\n const persisted = parseSettings(current);\n const updated = parseSettings(next);\n for (const key of MANAGED_KEYS) {\n if (Object.hasOwn(persisted, key)) updated[key] = persisted[key];\n else delete updated[key];\n }\n return JSON.stringify(updated, null, 2);\n}\n\n/**\n * Presents DoomPi-owned settings to Pi without allowing that overlay to leak\n * into either the global or project settings file when Pi saves another key.\n */\nexport class DpiSettingsStorage implements DpiSettingsStorageBackend {\n private readonly backend: DpiSettingsStorageBackend;\n private readonly managedSettings: DpiManagedSettings;\n\n constructor(backend: DpiSettingsStorageBackend, managedSettings: DpiManagedSettings = DPI_MANAGED_SETTINGS) {\n this.backend = backend;\n this.managedSettings = managedSettings;\n }\n\n withLock(scope: DpiSettingsScope, callback: (current: string | undefined) => string | undefined): void {\n this.backend.withLock(scope, (current) => {\n const next = callback(managedView(scope, current, this.managedSettings));\n return next === undefined ? undefined : restorePersistedSettings(current, next);\n });\n }\n}\n\nfunction isPiSettingsRuntime(value: unknown): value is PiSettingsRuntime {\n if (!isRecord(value) || typeof value.FileSettingsStorage !== 'function') return false;\n const settingsManager = value.SettingsManager;\n if (typeof settingsManager !== 'function') return false;\n return (\n typeof Reflect.get(settingsManager, 'create') === 'function' &&\n typeof Reflect.get(settingsManager, 'fromStorage') === 'function'\n );\n}\n\n/** Loads Pi's concrete file storage from the same pinned installation as its CLI. */\nexport async function loadPiSettingsRuntime(): Promise<PiSettingsRuntime> {\n const modulePath = path.join(path.dirname(piCliPath()), 'core', 'settings-manager.js');\n const loaded: unknown = await import(pathToFileURL(modulePath).href);\n if (!isPiSettingsRuntime(loaded)) throw new Error(`Unsupported Pi settings runtime: ${modulePath}`);\n return loaded;\n}\n\n/** Selects the package recorded by sync so embedded DPI does not depend on init's global dispatcher. */\nexport function resolveDpiManagedSettings(\n cwd: string,\n environment: NodeJS.ProcessEnv = process.env,\n): DpiManagedSettings {\n try {\n const root = findRepositoryRoot(cwd);\n const homeDirectory = environment.HOME?.trim() || os.homedir();\n const registration = readSyncRegistration(root, homeDirectory);\n if (!registration) return DPI_MANAGED_SETTINGS;\n return { ...DPI_MANAGED_SETTINGS, extensions: [registration.package.root, '!extensions/**'] };\n } catch {\n return { ...DPI_MANAGED_SETTINGS, extensions: ['!extensions/**'] };\n }\n}\n\n/** Installs the process-local create() hook used by upstream Pi startup and reloads. */\nexport function installDpiSettingsOverlay(\n runtime: PiSettingsRuntime,\n environment: NodeJS.ProcessEnv = process.env,\n): () => void {\n const originalCreate = runtime.SettingsManager.create;\n runtime.SettingsManager.create = (cwd, agentDir, options) => {\n const resolvedAgentDirectory = agentDir ?? piAgentDirectory(environment);\n const storage = new runtime.FileSettingsStorage(cwd, resolvedAgentDirectory);\n const managedSettings = resolveDpiManagedSettings(cwd, environment);\n return runtime.SettingsManager.fromStorage(new DpiSettingsStorage(storage, managedSettings), options);\n };\n\n return () => {\n runtime.SettingsManager.create = originalCreate;\n };\n}\n"],"mappings":"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"}
1
+ {"version":3,"file":"dpiSettings.cjs","names":["DISABLED_PI_BUILTINS","path","piCliPath","pathToFileURL","findRepositoryRoot","os","readSyncRegistration","piAgentDirectory"],"sources":["../../../../src/builders/cli/dpiSettings.ts"],"sourcesContent":["import os from 'node:os';\nimport path from 'node:path';\nimport { pathToFileURL } from 'node:url';\n\nimport { piCliPath } from '@agimon-ai/doompi-core/moduleResolution';\nimport { DISABLED_PI_BUILTINS, piAgentDirectory } from '@agimon-ai/doompi-core/runtimePiSettings';\nimport { readSyncRegistration } from '@agimon-ai/doompi-core/syncRegistration';\nimport type { SettingsManager, SettingsManagerCreateOptions } from '@earendil-works/pi-coding-agent';\n\nimport { findRepositoryRoot } from '../../composition/repository';\n\nconst GLOBAL_SCOPE = 'global';\nconst PROJECT_SCOPE = 'project';\nconst MANAGED_KEYS = ['extensions', 'themes', 'theme', 'quietStartup'] as const;\n\nexport interface DpiManagedSettings {\n extensions: string[];\n themes: string[];\n theme: string;\n quietStartup: boolean;\n}\n\nexport const DPI_MANAGED_SETTINGS: DpiManagedSettings = {\n extensions: ['@agimon-ai/doompi', '!extensions/**', ...DISABLED_PI_BUILTINS],\n themes: ['themes/doom-pi-dark.json'],\n theme: 'doom-pi-dark',\n quietStartup: true,\n};\n\nexport type DpiSettingsScope = typeof GLOBAL_SCOPE | typeof PROJECT_SCOPE;\n\nexport interface DpiSettingsStorageBackend {\n withLock(scope: DpiSettingsScope, callback: (current: string | undefined) => string | undefined): void;\n}\n\ninterface SettingsManagerClass {\n create(this: void, cwd: string, agentDir?: string, options?: SettingsManagerCreateOptions): SettingsManager;\n fromStorage(this: void, storage: DpiSettingsStorageBackend, options?: SettingsManagerCreateOptions): SettingsManager;\n}\n\ninterface FileSettingsStorageConstructor {\n new (cwd: string, agentDir: string): DpiSettingsStorageBackend;\n}\n\nexport interface PiSettingsRuntime {\n FileSettingsStorage: FileSettingsStorageConstructor;\n SettingsManager: SettingsManagerClass;\n}\n\nfunction isRecord(value: unknown): value is Record<string, unknown> {\n return typeof value === 'object' && value !== null && !Array.isArray(value);\n}\n\nfunction parseSettings(content: string | undefined): Record<string, unknown> {\n if (content === undefined) return {};\n const parsed: unknown = JSON.parse(content);\n if (!isRecord(parsed)) throw new SyntaxError('Pi settings must contain a JSON object');\n return parsed;\n}\n\nfunction managedView(\n scope: DpiSettingsScope,\n current: string | undefined,\n managedSettings: DpiManagedSettings,\n): string | undefined {\n if (scope === PROJECT_SCOPE && current === undefined) return undefined;\n const settings = parseSettings(current);\n if (scope === GLOBAL_SCOPE) Object.assign(settings, managedSettings);\n else for (const key of MANAGED_KEYS) delete settings[key];\n return JSON.stringify(settings, null, 2);\n}\n\nfunction restorePersistedSettings(current: string | undefined, next: string): string {\n const persisted = parseSettings(current);\n const updated = parseSettings(next);\n for (const key of MANAGED_KEYS) {\n if (Object.hasOwn(persisted, key)) updated[key] = persisted[key];\n else delete updated[key];\n }\n return JSON.stringify(updated, null, 2);\n}\n\n/**\n * Presents DoomPi-owned settings to Pi without allowing that overlay to leak\n * into either the global or project settings file when Pi saves another key.\n */\nexport class DpiSettingsStorage implements DpiSettingsStorageBackend {\n private readonly backend: DpiSettingsStorageBackend;\n private readonly managedSettings: DpiManagedSettings;\n\n constructor(backend: DpiSettingsStorageBackend, managedSettings: DpiManagedSettings = DPI_MANAGED_SETTINGS) {\n this.backend = backend;\n this.managedSettings = managedSettings;\n }\n\n withLock(scope: DpiSettingsScope, callback: (current: string | undefined) => string | undefined): void {\n this.backend.withLock(scope, (current) => {\n const next = callback(managedView(scope, current, this.managedSettings));\n return next === undefined ? undefined : restorePersistedSettings(current, next);\n });\n }\n}\n\nfunction isPiSettingsRuntime(value: unknown): value is PiSettingsRuntime {\n if (!isRecord(value) || typeof value.FileSettingsStorage !== 'function') return false;\n const settingsManager = value.SettingsManager;\n if (typeof settingsManager !== 'function') return false;\n return (\n typeof Reflect.get(settingsManager, 'create') === 'function' &&\n typeof Reflect.get(settingsManager, 'fromStorage') === 'function'\n );\n}\n\n/** Loads Pi's concrete file storage from the same pinned installation as its CLI. */\nexport async function loadPiSettingsRuntime(): Promise<PiSettingsRuntime> {\n const modulePath = path.join(path.dirname(piCliPath()), 'core', 'settings-manager.js');\n const loaded: unknown = await import(pathToFileURL(modulePath).href);\n if (!isPiSettingsRuntime(loaded)) throw new Error(`Unsupported Pi settings runtime: ${modulePath}`);\n return loaded;\n}\n\n/** Selects the package recorded by sync so embedded DPI does not depend on init's global dispatcher. */\nexport function resolveDpiManagedSettings(\n cwd: string,\n environment: NodeJS.ProcessEnv = process.env,\n): DpiManagedSettings {\n try {\n const root = findRepositoryRoot(cwd);\n const homeDirectory = environment.HOME?.trim() || os.homedir();\n const registration = readSyncRegistration(root, homeDirectory);\n if (!registration) return DPI_MANAGED_SETTINGS;\n return {\n ...DPI_MANAGED_SETTINGS,\n extensions: [registration.package.root, '!extensions/**', ...DISABLED_PI_BUILTINS],\n };\n } catch {\n return { ...DPI_MANAGED_SETTINGS, extensions: ['!extensions/**', ...DISABLED_PI_BUILTINS] };\n }\n}\n\n/** Installs the process-local create() hook used by upstream Pi startup and reloads. */\nexport function installDpiSettingsOverlay(\n runtime: PiSettingsRuntime,\n environment: NodeJS.ProcessEnv = process.env,\n): () => void {\n const originalCreate = runtime.SettingsManager.create;\n runtime.SettingsManager.create = (cwd, agentDir, options) => {\n const resolvedAgentDirectory = agentDir ?? piAgentDirectory(environment);\n const storage = new runtime.FileSettingsStorage(cwd, resolvedAgentDirectory);\n const managedSettings = resolveDpiManagedSettings(cwd, environment);\n return runtime.SettingsManager.fromStorage(new DpiSettingsStorage(storage, managedSettings), options);\n };\n\n return () => {\n runtime.SettingsManager.create = originalCreate;\n };\n}\n"],"mappings":"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"}
@@ -3,7 +3,7 @@ import path from "node:path";
3
3
  import os from "node:os";
4
4
  import { piCliPath } from "@agimon-ai/doompi-core/moduleResolution";
5
5
  import { pathToFileURL } from "node:url";
6
- import { piAgentDirectory } from "@agimon-ai/doompi-core/runtimePiSettings";
6
+ import { DISABLED_PI_BUILTINS, piAgentDirectory } from "@agimon-ai/doompi-core/runtimePiSettings";
7
7
  import { readSyncRegistration } from "@agimon-ai/doompi-core/syncRegistration";
8
8
  //#region src/builders/cli/dpiSettings.ts
9
9
  const GLOBAL_SCOPE = "global";
@@ -15,7 +15,11 @@ const MANAGED_KEYS = [
15
15
  "quietStartup"
16
16
  ];
17
17
  const DPI_MANAGED_SETTINGS = {
18
- extensions: ["@agimon-ai/doompi", "!extensions/**"],
18
+ extensions: [
19
+ "@agimon-ai/doompi",
20
+ "!extensions/**",
21
+ ...DISABLED_PI_BUILTINS
22
+ ],
19
23
  themes: ["themes/doom-pi-dark.json"],
20
24
  theme: "doom-pi-dark",
21
25
  quietStartup: true
@@ -83,12 +87,16 @@ function resolveDpiManagedSettings(cwd, environment = process.env) {
83
87
  if (!registration) return DPI_MANAGED_SETTINGS;
84
88
  return {
85
89
  ...DPI_MANAGED_SETTINGS,
86
- extensions: [registration.package.root, "!extensions/**"]
90
+ extensions: [
91
+ registration.package.root,
92
+ "!extensions/**",
93
+ ...DISABLED_PI_BUILTINS
94
+ ]
87
95
  };
88
96
  } catch {
89
97
  return {
90
98
  ...DPI_MANAGED_SETTINGS,
91
- extensions: ["!extensions/**"]
99
+ extensions: ["!extensions/**", ...DISABLED_PI_BUILTINS]
92
100
  };
93
101
  }
94
102
  }
@@ -1 +1 @@
1
- {"version":3,"file":"dpiSettings.mjs","names":[],"sources":["../../../../src/builders/cli/dpiSettings.ts"],"sourcesContent":["import os from 'node:os';\nimport path from 'node:path';\nimport { pathToFileURL } from 'node:url';\n\nimport { piCliPath } from '@agimon-ai/doompi-core/moduleResolution';\nimport { piAgentDirectory } from '@agimon-ai/doompi-core/runtimePiSettings';\nimport { readSyncRegistration } from '@agimon-ai/doompi-core/syncRegistration';\nimport type { SettingsManager, SettingsManagerCreateOptions } from '@earendil-works/pi-coding-agent';\n\nimport { findRepositoryRoot } from '../../composition/repository';\n\nconst GLOBAL_SCOPE = 'global';\nconst PROJECT_SCOPE = 'project';\nconst MANAGED_KEYS = ['extensions', 'themes', 'theme', 'quietStartup'] as const;\n\nexport interface DpiManagedSettings {\n extensions: string[];\n themes: string[];\n theme: string;\n quietStartup: boolean;\n}\n\nexport const DPI_MANAGED_SETTINGS: DpiManagedSettings = {\n extensions: ['@agimon-ai/doompi', '!extensions/**'],\n themes: ['themes/doom-pi-dark.json'],\n theme: 'doom-pi-dark',\n quietStartup: true,\n};\n\nexport type DpiSettingsScope = typeof GLOBAL_SCOPE | typeof PROJECT_SCOPE;\n\nexport interface DpiSettingsStorageBackend {\n withLock(scope: DpiSettingsScope, callback: (current: string | undefined) => string | undefined): void;\n}\n\ninterface SettingsManagerClass {\n create(this: void, cwd: string, agentDir?: string, options?: SettingsManagerCreateOptions): SettingsManager;\n fromStorage(this: void, storage: DpiSettingsStorageBackend, options?: SettingsManagerCreateOptions): SettingsManager;\n}\n\ninterface FileSettingsStorageConstructor {\n new (cwd: string, agentDir: string): DpiSettingsStorageBackend;\n}\n\nexport interface PiSettingsRuntime {\n FileSettingsStorage: FileSettingsStorageConstructor;\n SettingsManager: SettingsManagerClass;\n}\n\nfunction isRecord(value: unknown): value is Record<string, unknown> {\n return typeof value === 'object' && value !== null && !Array.isArray(value);\n}\n\nfunction parseSettings(content: string | undefined): Record<string, unknown> {\n if (content === undefined) return {};\n const parsed: unknown = JSON.parse(content);\n if (!isRecord(parsed)) throw new SyntaxError('Pi settings must contain a JSON object');\n return parsed;\n}\n\nfunction managedView(\n scope: DpiSettingsScope,\n current: string | undefined,\n managedSettings: DpiManagedSettings,\n): string | undefined {\n if (scope === PROJECT_SCOPE && current === undefined) return undefined;\n const settings = parseSettings(current);\n if (scope === GLOBAL_SCOPE) Object.assign(settings, managedSettings);\n else for (const key of MANAGED_KEYS) delete settings[key];\n return JSON.stringify(settings, null, 2);\n}\n\nfunction restorePersistedSettings(current: string | undefined, next: string): string {\n const persisted = parseSettings(current);\n const updated = parseSettings(next);\n for (const key of MANAGED_KEYS) {\n if (Object.hasOwn(persisted, key)) updated[key] = persisted[key];\n else delete updated[key];\n }\n return JSON.stringify(updated, null, 2);\n}\n\n/**\n * Presents DoomPi-owned settings to Pi without allowing that overlay to leak\n * into either the global or project settings file when Pi saves another key.\n */\nexport class DpiSettingsStorage implements DpiSettingsStorageBackend {\n private readonly backend: DpiSettingsStorageBackend;\n private readonly managedSettings: DpiManagedSettings;\n\n constructor(backend: DpiSettingsStorageBackend, managedSettings: DpiManagedSettings = DPI_MANAGED_SETTINGS) {\n this.backend = backend;\n this.managedSettings = managedSettings;\n }\n\n withLock(scope: DpiSettingsScope, callback: (current: string | undefined) => string | undefined): void {\n this.backend.withLock(scope, (current) => {\n const next = callback(managedView(scope, current, this.managedSettings));\n return next === undefined ? undefined : restorePersistedSettings(current, next);\n });\n }\n}\n\nfunction isPiSettingsRuntime(value: unknown): value is PiSettingsRuntime {\n if (!isRecord(value) || typeof value.FileSettingsStorage !== 'function') return false;\n const settingsManager = value.SettingsManager;\n if (typeof settingsManager !== 'function') return false;\n return (\n typeof Reflect.get(settingsManager, 'create') === 'function' &&\n typeof Reflect.get(settingsManager, 'fromStorage') === 'function'\n );\n}\n\n/** Loads Pi's concrete file storage from the same pinned installation as its CLI. */\nexport async function loadPiSettingsRuntime(): Promise<PiSettingsRuntime> {\n const modulePath = path.join(path.dirname(piCliPath()), 'core', 'settings-manager.js');\n const loaded: unknown = await import(pathToFileURL(modulePath).href);\n if (!isPiSettingsRuntime(loaded)) throw new Error(`Unsupported Pi settings runtime: ${modulePath}`);\n return loaded;\n}\n\n/** Selects the package recorded by sync so embedded DPI does not depend on init's global dispatcher. */\nexport function resolveDpiManagedSettings(\n cwd: string,\n environment: NodeJS.ProcessEnv = process.env,\n): DpiManagedSettings {\n try {\n const root = findRepositoryRoot(cwd);\n const homeDirectory = environment.HOME?.trim() || os.homedir();\n const registration = readSyncRegistration(root, homeDirectory);\n if (!registration) return DPI_MANAGED_SETTINGS;\n return { ...DPI_MANAGED_SETTINGS, extensions: [registration.package.root, '!extensions/**'] };\n } catch {\n return { ...DPI_MANAGED_SETTINGS, extensions: ['!extensions/**'] };\n }\n}\n\n/** Installs the process-local create() hook used by upstream Pi startup and reloads. */\nexport function installDpiSettingsOverlay(\n runtime: PiSettingsRuntime,\n environment: NodeJS.ProcessEnv = process.env,\n): () => void {\n const originalCreate = runtime.SettingsManager.create;\n runtime.SettingsManager.create = (cwd, agentDir, options) => {\n const resolvedAgentDirectory = agentDir ?? piAgentDirectory(environment);\n const storage = new runtime.FileSettingsStorage(cwd, resolvedAgentDirectory);\n const managedSettings = resolveDpiManagedSettings(cwd, environment);\n return runtime.SettingsManager.fromStorage(new DpiSettingsStorage(storage, managedSettings), options);\n };\n\n return () => {\n runtime.SettingsManager.create = originalCreate;\n };\n}\n"],"mappings":"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"}
1
+ {"version":3,"file":"dpiSettings.mjs","names":[],"sources":["../../../../src/builders/cli/dpiSettings.ts"],"sourcesContent":["import os from 'node:os';\nimport path from 'node:path';\nimport { pathToFileURL } from 'node:url';\n\nimport { piCliPath } from '@agimon-ai/doompi-core/moduleResolution';\nimport { DISABLED_PI_BUILTINS, piAgentDirectory } from '@agimon-ai/doompi-core/runtimePiSettings';\nimport { readSyncRegistration } from '@agimon-ai/doompi-core/syncRegistration';\nimport type { SettingsManager, SettingsManagerCreateOptions } from '@earendil-works/pi-coding-agent';\n\nimport { findRepositoryRoot } from '../../composition/repository';\n\nconst GLOBAL_SCOPE = 'global';\nconst PROJECT_SCOPE = 'project';\nconst MANAGED_KEYS = ['extensions', 'themes', 'theme', 'quietStartup'] as const;\n\nexport interface DpiManagedSettings {\n extensions: string[];\n themes: string[];\n theme: string;\n quietStartup: boolean;\n}\n\nexport const DPI_MANAGED_SETTINGS: DpiManagedSettings = {\n extensions: ['@agimon-ai/doompi', '!extensions/**', ...DISABLED_PI_BUILTINS],\n themes: ['themes/doom-pi-dark.json'],\n theme: 'doom-pi-dark',\n quietStartup: true,\n};\n\nexport type DpiSettingsScope = typeof GLOBAL_SCOPE | typeof PROJECT_SCOPE;\n\nexport interface DpiSettingsStorageBackend {\n withLock(scope: DpiSettingsScope, callback: (current: string | undefined) => string | undefined): void;\n}\n\ninterface SettingsManagerClass {\n create(this: void, cwd: string, agentDir?: string, options?: SettingsManagerCreateOptions): SettingsManager;\n fromStorage(this: void, storage: DpiSettingsStorageBackend, options?: SettingsManagerCreateOptions): SettingsManager;\n}\n\ninterface FileSettingsStorageConstructor {\n new (cwd: string, agentDir: string): DpiSettingsStorageBackend;\n}\n\nexport interface PiSettingsRuntime {\n FileSettingsStorage: FileSettingsStorageConstructor;\n SettingsManager: SettingsManagerClass;\n}\n\nfunction isRecord(value: unknown): value is Record<string, unknown> {\n return typeof value === 'object' && value !== null && !Array.isArray(value);\n}\n\nfunction parseSettings(content: string | undefined): Record<string, unknown> {\n if (content === undefined) return {};\n const parsed: unknown = JSON.parse(content);\n if (!isRecord(parsed)) throw new SyntaxError('Pi settings must contain a JSON object');\n return parsed;\n}\n\nfunction managedView(\n scope: DpiSettingsScope,\n current: string | undefined,\n managedSettings: DpiManagedSettings,\n): string | undefined {\n if (scope === PROJECT_SCOPE && current === undefined) return undefined;\n const settings = parseSettings(current);\n if (scope === GLOBAL_SCOPE) Object.assign(settings, managedSettings);\n else for (const key of MANAGED_KEYS) delete settings[key];\n return JSON.stringify(settings, null, 2);\n}\n\nfunction restorePersistedSettings(current: string | undefined, next: string): string {\n const persisted = parseSettings(current);\n const updated = parseSettings(next);\n for (const key of MANAGED_KEYS) {\n if (Object.hasOwn(persisted, key)) updated[key] = persisted[key];\n else delete updated[key];\n }\n return JSON.stringify(updated, null, 2);\n}\n\n/**\n * Presents DoomPi-owned settings to Pi without allowing that overlay to leak\n * into either the global or project settings file when Pi saves another key.\n */\nexport class DpiSettingsStorage implements DpiSettingsStorageBackend {\n private readonly backend: DpiSettingsStorageBackend;\n private readonly managedSettings: DpiManagedSettings;\n\n constructor(backend: DpiSettingsStorageBackend, managedSettings: DpiManagedSettings = DPI_MANAGED_SETTINGS) {\n this.backend = backend;\n this.managedSettings = managedSettings;\n }\n\n withLock(scope: DpiSettingsScope, callback: (current: string | undefined) => string | undefined): void {\n this.backend.withLock(scope, (current) => {\n const next = callback(managedView(scope, current, this.managedSettings));\n return next === undefined ? undefined : restorePersistedSettings(current, next);\n });\n }\n}\n\nfunction isPiSettingsRuntime(value: unknown): value is PiSettingsRuntime {\n if (!isRecord(value) || typeof value.FileSettingsStorage !== 'function') return false;\n const settingsManager = value.SettingsManager;\n if (typeof settingsManager !== 'function') return false;\n return (\n typeof Reflect.get(settingsManager, 'create') === 'function' &&\n typeof Reflect.get(settingsManager, 'fromStorage') === 'function'\n );\n}\n\n/** Loads Pi's concrete file storage from the same pinned installation as its CLI. */\nexport async function loadPiSettingsRuntime(): Promise<PiSettingsRuntime> {\n const modulePath = path.join(path.dirname(piCliPath()), 'core', 'settings-manager.js');\n const loaded: unknown = await import(pathToFileURL(modulePath).href);\n if (!isPiSettingsRuntime(loaded)) throw new Error(`Unsupported Pi settings runtime: ${modulePath}`);\n return loaded;\n}\n\n/** Selects the package recorded by sync so embedded DPI does not depend on init's global dispatcher. */\nexport function resolveDpiManagedSettings(\n cwd: string,\n environment: NodeJS.ProcessEnv = process.env,\n): DpiManagedSettings {\n try {\n const root = findRepositoryRoot(cwd);\n const homeDirectory = environment.HOME?.trim() || os.homedir();\n const registration = readSyncRegistration(root, homeDirectory);\n if (!registration) return DPI_MANAGED_SETTINGS;\n return {\n ...DPI_MANAGED_SETTINGS,\n extensions: [registration.package.root, '!extensions/**', ...DISABLED_PI_BUILTINS],\n };\n } catch {\n return { ...DPI_MANAGED_SETTINGS, extensions: ['!extensions/**', ...DISABLED_PI_BUILTINS] };\n }\n}\n\n/** Installs the process-local create() hook used by upstream Pi startup and reloads. */\nexport function installDpiSettingsOverlay(\n runtime: PiSettingsRuntime,\n environment: NodeJS.ProcessEnv = process.env,\n): () => void {\n const originalCreate = runtime.SettingsManager.create;\n runtime.SettingsManager.create = (cwd, agentDir, options) => {\n const resolvedAgentDirectory = agentDir ?? piAgentDirectory(environment);\n const storage = new runtime.FileSettingsStorage(cwd, resolvedAgentDirectory);\n const managedSettings = resolveDpiManagedSettings(cwd, environment);\n return runtime.SettingsManager.fromStorage(new DpiSettingsStorage(storage, managedSettings), options);\n };\n\n return () => {\n runtime.SettingsManager.create = originalCreate;\n };\n}\n"],"mappings":"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"}
@@ -7,8 +7,8 @@ const require_index$4 = require("../../composition/syncDrift/index.cjs");
7
7
  const require_harnessContext = require("../cli/harnessContext.cjs");
8
8
  const require_computerUseBinding = require("./computerUseBinding.cjs");
9
9
  const require_defaultWorkspace = require("./defaultWorkspace.cjs");
10
- const require_executionBudget = require("./executionBudget.cjs");
11
10
  const require_logSink = require("./logSink.cjs");
11
+ const require_runtimeResources = require("./runtimeResources.cjs");
12
12
  const require_selectionStatus = require("./selectionStatus.cjs");
13
13
  const require_sessionArguments = require("./sessionArguments.cjs");
14
14
  const require_sessionArtifact = require("./sessionArtifact.cjs");
@@ -35,6 +35,7 @@ let _agimon_ai_doompi_core_headlessHub = require("@agimon-ai/doompi-core/headles
35
35
  let _agimon_ai_doompi_core_headlessServer = require("@agimon-ai/doompi-core/headlessServer");
36
36
  let _agimon_ai_doompi_core_headlessSessionManager = require("@agimon-ai/doompi-core/headlessSessionManager");
37
37
  let _agimon_ai_doompi_core_history = require("@agimon-ai/doompi-core/history");
38
+ let _agimon_ai_doompi_core_packageApi = require("@agimon-ai/doompi-core/packageApi");
38
39
  let _agimon_ai_doompi_core_packageApiServer = require("@agimon-ai/doompi-core/packageApiServer");
39
40
  let _agimon_ai_doompi_core_piSettings = require("@agimon-ai/doompi-core/piSettings");
40
41
  let _agimon_ai_doompi_core_remoteRuntime = require("@agimon-ai/doompi-core/remoteRuntime");
@@ -58,7 +59,7 @@ async function runServerRuntime(options, runtime) {
58
59
  ...incomingEnvironment,
59
60
  LOG_SINK_INSTANCE: "global"
60
61
  };
61
- const executionBudget = require_executionBudget.createExecutionBudget(Number(baseEnvironment.DOOM_RUNNER_MAX_HEAVY_JOBS ?? 2));
62
+ const executionBudget = (0, _agimon_ai_doompi_core_packageApi.createServerExecutionBudget)(baseEnvironment);
62
63
  await require_logSink.ensureGlobalLogSink({
63
64
  cwd: baseCwd,
64
65
  env: baseEnvironment,
@@ -276,6 +277,19 @@ async function runServerRuntime(options, runtime) {
276
277
  let remoteRuntime;
277
278
  let attachToken;
278
279
  let webCompositions;
280
+ const stopResourceMonitor = require_runtimeResources.monitorRuntimeResources({
281
+ record: (attributes) => telemetry.recordEvent("doompi_server.resources", attributes),
282
+ counts: () => {
283
+ const budget = executionBudget.getSnapshot();
284
+ return {
285
+ sessions: sessionManager.sessions().length,
286
+ running_jobs: budget.running,
287
+ queued_jobs: budget.queued,
288
+ job_limit: budget.limit
289
+ };
290
+ },
291
+ warn: notice
292
+ });
279
293
  try {
280
294
  await telemetry.runInSpan("doompi_server.startup", {}, async () => {
281
295
  const token = node_fs.default.readFileSync(options.tokenFile, "utf8").trim();
@@ -300,26 +314,27 @@ async function runServerRuntime(options, runtime) {
300
314
  activeLayers: (0, _agimon_ai_doompi_config_majorModes.resolveLayers)(config, majorMode)
301
315
  };
302
316
  })();
303
- return (0, _agimon_ai_doompi_core_serverFacet.loadServerBundle)(scope, {
317
+ return telemetry.runInSpan("doompi_server.composition_load", { scope }, () => (0, _agimon_ai_doompi_core_serverFacet.loadServerBundle)(scope, {
304
318
  ...source,
305
319
  ...selected,
306
320
  retainCandidates: scope === "session",
307
321
  onNotice: notice
308
- });
322
+ }));
309
323
  };
310
324
  const loadSessionMcp = async (root, selection, pinnedRegistration) => {
311
325
  const registration = pinnedRegistration ?? (0, _agimon_ai_doompi_core_syncRegistration.readSyncRegistration)(root, homeDirectory);
312
326
  if (registration?.mcpBundle === void 0) throw new Error(`Run the scoped DoomPi sync for '${root}' before opening its MCP runtime.`);
313
- return (0, _agimon_ai_doompi_core_mcpFacet.loadMcpBundle)({
314
- directory: node_path.default.dirname(registration.mcpBundle.path),
327
+ const bundle = registration.mcpBundle;
328
+ return telemetry.runInSpan("doompi_server.mcp_bundle_load", {}, () => (0, _agimon_ai_doompi_core_mcpFacet.loadMcpBundle)({
329
+ directory: node_path.default.dirname(bundle.path),
315
330
  generation: registration.generation,
316
- fingerprint: registration.mcpBundle.fingerprint,
317
- descriptorSha256: registration.mcpBundle.sha256,
331
+ fingerprint: bundle.fingerprint,
332
+ descriptorSha256: bundle.sha256,
318
333
  majorMode: selection.majorMode,
319
334
  activeLayers: selection.activeLayers,
320
335
  retainCandidates: true,
321
336
  onNotice: notice
322
- });
337
+ }));
323
338
  };
324
339
  const sharedApiContext = {
325
340
  homeDirectory,
@@ -961,6 +976,7 @@ async function runServerRuntime(options, runtime) {
961
976
  }
962
977
  } finally {
963
978
  shuttingDown = true;
979
+ stopResourceMonitor();
964
980
  executionBudget.close();
965
981
  stopPersistSessionNames();
966
982
  clearInterval(eventLoopMonitor);