@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 +1 -1
- package/dist/src/builders/cli/dpiSettings.cjs +11 -3
- package/dist/src/builders/cli/dpiSettings.cjs.map +1 -1
- package/dist/src/builders/cli/dpiSettings.mjs +12 -4
- package/dist/src/builders/cli/dpiSettings.mjs.map +1 -1
- package/dist/src/builders/server/runtime.cjs +25 -9
- package/dist/src/builders/server/runtime.cjs.map +1 -1
- package/dist/src/builders/server/runtime.mjs +25 -9
- package/dist/src/builders/server/runtime.mjs.map +1 -1
- package/dist/src/builders/server/runtimeResources.cjs +72 -0
- package/dist/src/builders/server/runtimeResources.cjs.map +1 -0
- package/dist/src/builders/server/runtimeResources.mjs +71 -0
- package/dist/src/builders/server/runtimeResources.mjs.map +1 -0
- package/dist/src/composition/layerPackageInstaller/index.cjs +4 -2
- package/dist/src/composition/layerPackageInstaller/index.cjs.map +1 -1
- package/dist/src/composition/layerPackageInstaller/index.d.mts.map +1 -1
- package/dist/src/composition/layerPackageInstaller/index.mjs +4 -2
- package/dist/src/composition/layerPackageInstaller/index.mjs.map +1 -1
- package/package.json +28 -28
- package/dist/src/builders/server/executionBudget.cjs +0 -64
- package/dist/src/builders/server/executionBudget.cjs.map +0 -1
- package/dist/src/builders/server/executionBudget.mjs +0 -64
- package/dist/src/builders/server/executionBudget.mjs.map +0 -1
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.
|
|
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: [
|
|
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: [
|
|
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 {
|
|
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: [
|
|
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: [
|
|
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 {
|
|
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 =
|
|
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
|
-
|
|
314
|
-
|
|
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:
|
|
317
|
-
descriptorSha256:
|
|
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);
|