@agimon-ai/doompi-config 0.0.1-alpha.26 → 0.0.1-alpha.27
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/package.json +3 -3
- package/dist/_virtual/_rolldown/runtime.cjs +0 -1
- package/dist/adapters/atomicJson.cjs +0 -2
- package/dist/adapters/atomicJson.cjs.map +0 -1
- package/dist/adapters/atomicJson.d.cts +0 -6
- package/dist/adapters/atomicJson.d.cts.map +0 -1
- package/dist/adapters/atomicJson.d.mts +0 -6
- package/dist/adapters/atomicJson.d.mts.map +0 -1
- package/dist/adapters/atomicJson.mjs +0 -2
- package/dist/adapters/atomicJson.mjs.map +0 -1
- package/dist/adapters/config.cjs +0 -2
- package/dist/adapters/config.cjs.map +0 -1
- package/dist/adapters/config.d.cts +0 -11
- package/dist/adapters/config.d.cts.map +0 -1
- package/dist/adapters/config.d.mts +0 -11
- package/dist/adapters/config.d.mts.map +0 -1
- package/dist/adapters/config.mjs +0 -2
- package/dist/adapters/config.mjs.map +0 -1
- package/dist/adapters/configWriter.cjs +0 -2
- package/dist/adapters/configWriter.cjs.map +0 -1
- package/dist/adapters/configWriter.d.cts +0 -52
- package/dist/adapters/configWriter.d.cts.map +0 -1
- package/dist/adapters/configWriter.d.mts +0 -52
- package/dist/adapters/configWriter.d.mts.map +0 -1
- package/dist/adapters/configWriter.mjs +0 -2
- package/dist/adapters/configWriter.mjs.map +0 -1
- package/dist/adapters/domains.cjs +0 -2
- package/dist/adapters/domains.cjs.map +0 -1
- package/dist/adapters/domains.d.cts +0 -35
- package/dist/adapters/domains.d.cts.map +0 -1
- package/dist/adapters/domains.d.mts +0 -35
- package/dist/adapters/domains.d.mts.map +0 -1
- package/dist/adapters/domains.mjs +0 -2
- package/dist/adapters/domains.mjs.map +0 -1
- package/dist/adapters/harnessState.cjs +0 -2
- package/dist/adapters/harnessState.cjs.map +0 -1
- package/dist/adapters/harnessState.d.cts +0 -50
- package/dist/adapters/harnessState.d.cts.map +0 -1
- package/dist/adapters/harnessState.d.mts +0 -50
- package/dist/adapters/harnessState.d.mts.map +0 -1
- package/dist/adapters/harnessState.mjs +0 -2
- package/dist/adapters/harnessState.mjs.map +0 -1
- package/dist/adapters/harnessStore.cjs +0 -2
- package/dist/adapters/harnessStore.cjs.map +0 -1
- package/dist/adapters/harnessStore.d.cts +0 -112
- package/dist/adapters/harnessStore.d.cts.map +0 -1
- package/dist/adapters/harnessStore.d.mts +0 -112
- package/dist/adapters/harnessStore.d.mts.map +0 -1
- package/dist/adapters/harnessStore.mjs +0 -2
- package/dist/adapters/harnessStore.mjs.map +0 -1
- package/dist/adapters/init.cjs +0 -177
- package/dist/adapters/init.cjs.map +0 -1
- package/dist/adapters/init.d.cts +0 -39
- package/dist/adapters/init.d.cts.map +0 -1
- package/dist/adapters/init.d.mts +0 -39
- package/dist/adapters/init.d.mts.map +0 -1
- package/dist/adapters/init.mjs +0 -177
- package/dist/adapters/init.mjs.map +0 -1
- package/dist/adapters/layeredConfig.cjs +0 -2
- package/dist/adapters/layeredConfig.cjs.map +0 -1
- package/dist/adapters/layeredConfig.d.cts +0 -54
- package/dist/adapters/layeredConfig.d.cts.map +0 -1
- package/dist/adapters/layeredConfig.d.mts +0 -54
- package/dist/adapters/layeredConfig.d.mts.map +0 -1
- package/dist/adapters/layeredConfig.mjs +0 -2
- package/dist/adapters/layeredConfig.mjs.map +0 -1
- package/dist/adapters/majorModes.cjs +0 -2
- package/dist/adapters/majorModes.cjs.map +0 -1
- package/dist/adapters/majorModes.d.cts +0 -104
- package/dist/adapters/majorModes.d.cts.map +0 -1
- package/dist/adapters/majorModes.d.mts +0 -104
- package/dist/adapters/majorModes.d.mts.map +0 -1
- package/dist/adapters/majorModes.mjs +0 -2
- package/dist/adapters/majorModes.mjs.map +0 -1
- package/dist/adapters/pi/configExtension.cjs +0 -2
- package/dist/adapters/pi/configExtension.cjs.map +0 -1
- package/dist/adapters/pi/configExtension.d.cts +0 -7
- package/dist/adapters/pi/configExtension.d.cts.map +0 -1
- package/dist/adapters/pi/configExtension.d.mts +0 -7
- package/dist/adapters/pi/configExtension.d.mts.map +0 -1
- package/dist/adapters/pi/configExtension.mjs +0 -2
- package/dist/adapters/pi/configExtension.mjs.map +0 -1
- package/dist/adapters/pi/helpContribution.cjs +0 -2
- package/dist/adapters/pi/helpContribution.cjs.map +0 -1
- package/dist/adapters/pi/helpContribution.mjs +0 -2
- package/dist/adapters/pi/helpContribution.mjs.map +0 -1
- package/dist/adapters/pi/piContext.cjs +0 -2
- package/dist/adapters/pi/piContext.cjs.map +0 -1
- package/dist/adapters/pi/piContext.d.cts +0 -34
- package/dist/adapters/pi/piContext.d.cts.map +0 -1
- package/dist/adapters/pi/piContext.d.mts +0 -34
- package/dist/adapters/pi/piContext.d.mts.map +0 -1
- package/dist/adapters/pi/piContext.mjs +0 -2
- package/dist/adapters/pi/piContext.mjs.map +0 -1
- package/dist/adapters/piConfig.cjs +0 -2
- package/dist/adapters/piConfig.cjs.map +0 -1
- package/dist/adapters/piConfig.d.cts +0 -8
- package/dist/adapters/piConfig.d.cts.map +0 -1
- package/dist/adapters/piConfig.d.mts +0 -8
- package/dist/adapters/piConfig.d.mts.map +0 -1
- package/dist/adapters/piConfig.mjs +0 -2
- package/dist/adapters/piConfig.mjs.map +0 -1
- package/dist/adapters/pluginCatalog.cjs +0 -2
- package/dist/adapters/pluginCatalog.cjs.map +0 -1
- package/dist/adapters/pluginCatalog.d.cts +0 -12
- package/dist/adapters/pluginCatalog.d.cts.map +0 -1
- package/dist/adapters/pluginCatalog.d.mts +0 -12
- package/dist/adapters/pluginCatalog.d.mts.map +0 -1
- package/dist/adapters/pluginCatalog.mjs +0 -2
- package/dist/adapters/pluginCatalog.mjs.map +0 -1
- package/dist/adapters/profiles.cjs +0 -4
- package/dist/adapters/profiles.cjs.map +0 -1
- package/dist/adapters/profiles.d.cts +0 -36
- package/dist/adapters/profiles.d.cts.map +0 -1
- package/dist/adapters/profiles.d.mts +0 -36
- package/dist/adapters/profiles.d.mts.map +0 -1
- package/dist/adapters/profiles.mjs +0 -4
- package/dist/adapters/profiles.mjs.map +0 -1
- package/dist/adapters/selectionSwitch.cjs +0 -2
- package/dist/adapters/selectionSwitch.cjs.map +0 -1
- package/dist/adapters/selectionSwitch.d.cts +0 -31
- package/dist/adapters/selectionSwitch.d.cts.map +0 -1
- package/dist/adapters/selectionSwitch.d.mts +0 -31
- package/dist/adapters/selectionSwitch.d.mts.map +0 -1
- package/dist/adapters/selectionSwitch.mjs +0 -2
- package/dist/adapters/selectionSwitch.mjs.map +0 -1
- package/dist/atomicJson.cjs +0 -1
- package/dist/atomicJson.d.cts +0 -2
- package/dist/atomicJson.d.mts +0 -2
- package/dist/atomicJson.mjs +0 -1
- package/dist/config/piConfig.cjs +0 -1
- package/dist/config/piConfig.d.cts +0 -2
- package/dist/config/piConfig.d.mts +0 -2
- package/dist/config/piConfig.mjs +0 -1
- package/dist/config/schema.cjs +0 -0
- package/dist/config/schema.d.cts +0 -2
- package/dist/config/schema.d.mts +0 -2
- package/dist/config/schema.mjs +0 -1
- package/dist/config.cjs +0 -1
- package/dist/config.d.cts +0 -3
- package/dist/config.d.mts +0 -3
- package/dist/config.mjs +0 -1
- package/dist/configWriter.cjs +0 -1
- package/dist/configWriter.d.cts +0 -2
- package/dist/configWriter.d.mts +0 -2
- package/dist/configWriter.mjs +0 -1
- package/dist/domains.cjs +0 -1
- package/dist/domains.d.cts +0 -6
- package/dist/domains.d.mts +0 -6
- package/dist/domains.mjs +0 -1
- package/dist/extensions/pi.cjs +0 -1
- package/dist/extensions/pi.d.cts +0 -2
- package/dist/extensions/pi.d.mts +0 -2
- package/dist/extensions/pi.mjs +0 -1
- package/dist/harnessState.cjs +0 -1
- package/dist/harnessState.d.cts +0 -2
- package/dist/harnessState.d.mts +0 -2
- package/dist/harnessState.mjs +0 -1
- package/dist/harnessStore.cjs +0 -1
- package/dist/harnessStore.d.cts +0 -2
- package/dist/harnessStore.d.mts +0 -2
- package/dist/harnessStore.mjs +0 -1
- package/dist/index.cjs +0 -1
- package/dist/index.d.cts +0 -19
- package/dist/index.d.mts +0 -19
- package/dist/index.mjs +0 -1
- package/dist/init.cjs +0 -1
- package/dist/init.d.cts +0 -2
- package/dist/init.d.mts +0 -2
- package/dist/init.mjs +0 -1
- package/dist/layeredConfig.cjs +0 -1
- package/dist/layeredConfig.d.cts +0 -2
- package/dist/layeredConfig.d.mts +0 -2
- package/dist/layeredConfig.mjs +0 -1
- package/dist/majorModes.cjs +0 -1
- package/dist/majorModes.d.cts +0 -2
- package/dist/majorModes.d.mts +0 -2
- package/dist/majorModes.mjs +0 -1
- package/dist/piContext.cjs +0 -1
- package/dist/piContext.d.cts +0 -3
- package/dist/piContext.d.mts +0 -3
- package/dist/piContext.mjs +0 -1
- package/dist/profiles.cjs +0 -1
- package/dist/profiles.d.cts +0 -2
- package/dist/profiles.d.mts +0 -2
- package/dist/profiles.mjs +0 -1
- package/dist/providers/doomConfigService.cjs +0 -2
- package/dist/providers/doomConfigService.cjs.map +0 -1
- package/dist/providers/doomConfigService.mjs +0 -2
- package/dist/providers/doomConfigService.mjs.map +0 -1
- package/dist/schemas/config/schema.d.cts +0 -33
- package/dist/schemas/config/schema.d.cts.map +0 -1
- package/dist/schemas/config/schema.d.mts +0 -33
- package/dist/schemas/config/schema.d.mts.map +0 -1
- package/dist/selectionSwitch.cjs +0 -1
- package/dist/selectionSwitch.d.cts +0 -2
- package/dist/selectionSwitch.d.mts +0 -2
- package/dist/selectionSwitch.mjs +0 -1
- package/dist/services/configPolicy.cjs +0 -2
- package/dist/services/configPolicy.cjs.map +0 -1
- package/dist/services/configPolicy.d.cts +0 -19
- package/dist/services/configPolicy.d.cts.map +0 -1
- package/dist/services/configPolicy.d.mts +0 -19
- package/dist/services/configPolicy.d.mts.map +0 -1
- package/dist/services/configPolicy.mjs +0 -2
- package/dist/services/configPolicy.mjs.map +0 -1
- package/dist/services/domains.cjs +0 -2
- package/dist/services/domains.cjs.map +0 -1
- package/dist/services/domains.d.cts +0 -12
- package/dist/services/domains.d.cts.map +0 -1
- package/dist/services/domains.d.mts +0 -12
- package/dist/services/domains.d.mts.map +0 -1
- package/dist/services/domains.mjs +0 -2
- package/dist/services/domains.mjs.map +0 -1
- package/dist/types/config.cjs +0 -1
- package/dist/types/config.d.cts +0 -172
- package/dist/types/config.d.cts.map +0 -1
- package/dist/types/config.d.mts +0 -172
- package/dist/types/config.d.mts.map +0 -1
- package/dist/types/config.mjs +0 -1
- package/dist/types/domains.d.cts +0 -91
- package/dist/types/domains.d.cts.map +0 -1
- package/dist/types/domains.d.mts +0 -91
- package/dist/types/domains.d.mts.map +0 -1
- package/dist/types.cjs +0 -1
- package/dist/types.d.cts +0 -2
- package/dist/types.d.mts +0 -2
- package/dist/types.mjs +0 -1
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@agimon-ai/doompi-config",
|
|
3
|
-
"version": "0.0.1-alpha.
|
|
3
|
+
"version": "0.0.1-alpha.27",
|
|
4
4
|
"description": "Typed configuration loading, validation, and host adapters for composing DoomPi sessions.",
|
|
5
5
|
"keywords": [
|
|
6
6
|
"agent-configuration",
|
|
@@ -125,8 +125,8 @@
|
|
|
125
125
|
"dependencies": {
|
|
126
126
|
"@deepseek-ai/cordis": "4.0.1",
|
|
127
127
|
"yaml": "2.9.0",
|
|
128
|
-
"@agimon-ai/doompi-extension-contracts": "0.0.1-alpha.
|
|
129
|
-
"@agimon-ai/doompi-telemetry": "0.0.1-alpha.
|
|
128
|
+
"@agimon-ai/doompi-extension-contracts": "0.0.1-alpha.27",
|
|
129
|
+
"@agimon-ai/doompi-telemetry": "0.0.1-alpha.27"
|
|
130
130
|
},
|
|
131
131
|
"devDependencies": {
|
|
132
132
|
"@earendil-works/pi-coding-agent": "0.84.2",
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
var e=Object.create,t=Object.defineProperty,n=Object.getOwnPropertyDescriptor,r=Object.getOwnPropertyNames,i=Object.getPrototypeOf,a=Object.prototype.hasOwnProperty,o=(e,i,o,s)=>{if(i&&typeof i==`object`||typeof i==`function`)for(var c=r(i),l=0,u=c.length,d;l<u;l++)d=c[l],!a.call(e,d)&&d!==o&&t(e,d,{get:(e=>i[e]).bind(null,d),enumerable:!(s=n(i,d))||s.enumerable});return e},s=(n,r,s)=>(s=n==null?{}:e(i(n)),o(r||!n||!n.__esModule||!a.call(n,`default`)?t(s,`default`,{value:n,enumerable:!0}):s,n));exports.__toESM=s;
|
|
@@ -1,2 +0,0 @@
|
|
|
1
|
-
const e=require("../_virtual/_rolldown/runtime.cjs");let t=require("node:crypto"),n=require("node:fs");n=e.__toESM(n,1);let r=require("node:path");r=e.__toESM(r,1);function i(e,i){n.default.mkdirSync(r.default.dirname(e),{mode:448,recursive:!0});let a=`${e}.${process.pid}.${(0,t.randomUUID)()}.tmp`;try{n.default.writeFileSync(a,`${JSON.stringify(i,null,2)}\n`,{mode:384}),n.default.renameSync(a,e)}catch(e){throw n.default.rmSync(a,{force:!0}),e}}exports.writePrivateAtomicJson=i;
|
|
2
|
-
//# sourceMappingURL=atomicJson.cjs.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"atomicJson.cjs","names":["path","randomUUID"],"sources":["../../src/adapters/atomicJson.ts"],"sourcesContent":["import { randomUUID } from 'node:crypto';\nimport fs from 'node:fs';\nimport path from 'node:path';\n\n/**\n * Private atomic JSON writes.\n *\n * Write to a uniquely named temporary file in the destination directory, then\n * rename onto the target. Rename is atomic within a filesystem, so a reader\n * sees either the previous file or the complete new one and never a partial\n * write. The temporary name carries the pid and a random suffix, so two\n * processes writing the same target cannot collide on it.\n *\n * This prevents torn reads. It does NOT prevent lost updates: two writers doing\n * read-modify-write still clobber each other, because the rename only publishes\n * what the caller already computed. Harness state avoids that by giving every\n * process a file it owns rather than by locking.\n *\n * AVOID:\n * - Treating this as a lock\n * - Leaving the temporary file behind when the write fails\n */\n\nconst PRIVATE_FILE_MODE = 0o600;\nconst PRIVATE_DIRECTORY_MODE = 0o700;\nconst TEMPORARY_SUFFIX = '.tmp';\n\n/** Writes JSON readable by its owner only, replacing the target atomically. */\nexport function writePrivateAtomicJson(filePath: string, value: unknown): void {\n fs.mkdirSync(path.dirname(filePath), { mode: PRIVATE_DIRECTORY_MODE, recursive: true });\n const temporaryPath = `${filePath}.${process.pid}.${randomUUID()}${TEMPORARY_SUFFIX}`;\n try {\n fs.writeFileSync(temporaryPath, `${JSON.stringify(value, null, 2)}\\n`, { mode: PRIVATE_FILE_MODE });\n fs.renameSync(temporaryPath, filePath);\n } catch (error) {\n fs.rmSync(temporaryPath, { force: true });\n throw error;\n }\n}\n"],"mappings":"oKA4BA,SAAgB,EAAuB,EAAkB,EAAsB,CAC7E,EAAA,QAAG,UAAUA,EAAAA,QAAK,QAAQ,CAAQ,EAAG,CAAE,KAAM,IAAwB,UAAW,EAAK,CAAC,EACtF,IAAM,EAAgB,GAAG,EAAS,GAAG,QAAQ,IAAI,IAAA,EAAGC,EAAAA,WAAAA,CAAW,QAC/D,GAAI,CACF,EAAA,QAAG,cAAc,EAAe,GAAG,KAAK,UAAU,EAAO,KAAM,CAAC,EAAE,IAAK,CAAE,KAAM,GAAkB,CAAC,EAClG,EAAA,QAAG,WAAW,EAAe,CAAQ,CACvC,OAAS,EAAO,CAEd,MADA,EAAA,QAAG,OAAO,EAAe,CAAE,MAAO,EAAK,CAAC,EAClC,CACR,CACF"}
|
|
@@ -1,6 +0,0 @@
|
|
|
1
|
-
//#region src/adapters/atomicJson.d.ts
|
|
2
|
-
/** Writes JSON readable by its owner only, replacing the target atomically. */
|
|
3
|
-
declare function writePrivateAtomicJson(filePath: string, value: unknown): void;
|
|
4
|
-
//#endregion
|
|
5
|
-
export { writePrivateAtomicJson };
|
|
6
|
-
//# sourceMappingURL=atomicJson.d.cts.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"atomicJson.d.cts","names":[],"sources":["../../src/adapters/atomicJson.ts"],"mappings":";;iBA4BgB,uBAAuB,kBAAkB"}
|
|
@@ -1,6 +0,0 @@
|
|
|
1
|
-
//#region src/adapters/atomicJson.d.ts
|
|
2
|
-
/** Writes JSON readable by its owner only, replacing the target atomically. */
|
|
3
|
-
declare function writePrivateAtomicJson(filePath: string, value: unknown): void;
|
|
4
|
-
//#endregion
|
|
5
|
-
export { writePrivateAtomicJson };
|
|
6
|
-
//# sourceMappingURL=atomicJson.d.mts.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"atomicJson.d.mts","names":[],"sources":["../../src/adapters/atomicJson.ts"],"mappings":";;iBA4BgB,uBAAuB,kBAAkB"}
|
|
@@ -1,2 +0,0 @@
|
|
|
1
|
-
import{randomUUID as e}from"node:crypto";import t from"node:fs";import n from"node:path";function r(r,i){t.mkdirSync(n.dirname(r),{mode:448,recursive:!0});let a=`${r}.${process.pid}.${e()}.tmp`;try{t.writeFileSync(a,`${JSON.stringify(i,null,2)}\n`,{mode:384}),t.renameSync(a,r)}catch(e){throw t.rmSync(a,{force:!0}),e}}export{r as writePrivateAtomicJson};
|
|
2
|
-
//# sourceMappingURL=atomicJson.mjs.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"atomicJson.mjs","names":[],"sources":["../../src/adapters/atomicJson.ts"],"sourcesContent":["import { randomUUID } from 'node:crypto';\nimport fs from 'node:fs';\nimport path from 'node:path';\n\n/**\n * Private atomic JSON writes.\n *\n * Write to a uniquely named temporary file in the destination directory, then\n * rename onto the target. Rename is atomic within a filesystem, so a reader\n * sees either the previous file or the complete new one and never a partial\n * write. The temporary name carries the pid and a random suffix, so two\n * processes writing the same target cannot collide on it.\n *\n * This prevents torn reads. It does NOT prevent lost updates: two writers doing\n * read-modify-write still clobber each other, because the rename only publishes\n * what the caller already computed. Harness state avoids that by giving every\n * process a file it owns rather than by locking.\n *\n * AVOID:\n * - Treating this as a lock\n * - Leaving the temporary file behind when the write fails\n */\n\nconst PRIVATE_FILE_MODE = 0o600;\nconst PRIVATE_DIRECTORY_MODE = 0o700;\nconst TEMPORARY_SUFFIX = '.tmp';\n\n/** Writes JSON readable by its owner only, replacing the target atomically. */\nexport function writePrivateAtomicJson(filePath: string, value: unknown): void {\n fs.mkdirSync(path.dirname(filePath), { mode: PRIVATE_DIRECTORY_MODE, recursive: true });\n const temporaryPath = `${filePath}.${process.pid}.${randomUUID()}${TEMPORARY_SUFFIX}`;\n try {\n fs.writeFileSync(temporaryPath, `${JSON.stringify(value, null, 2)}\\n`, { mode: PRIVATE_FILE_MODE });\n fs.renameSync(temporaryPath, filePath);\n } catch (error) {\n fs.rmSync(temporaryPath, { force: true });\n throw error;\n }\n}\n"],"mappings":"yFA4BA,SAAgB,EAAuB,EAAkB,EAAsB,CAC7E,EAAG,UAAU,EAAK,QAAQ,CAAQ,EAAG,CAAE,KAAM,IAAwB,UAAW,EAAK,CAAC,EACtF,IAAM,EAAgB,GAAG,EAAS,GAAG,QAAQ,IAAI,GAAG,EAAW,QAC/D,GAAI,CACF,EAAG,cAAc,EAAe,GAAG,KAAK,UAAU,EAAO,KAAM,CAAC,EAAE,IAAK,CAAE,KAAM,GAAkB,CAAC,EAClG,EAAG,WAAW,EAAe,CAAQ,CACvC,OAAS,EAAO,CAEd,MADA,EAAG,OAAO,EAAe,CAAE,MAAO,EAAK,CAAC,EAClC,CACR,CACF"}
|
package/dist/adapters/config.cjs
DELETED
|
@@ -1,2 +0,0 @@
|
|
|
1
|
-
const e=require("../_virtual/_rolldown/runtime.cjs"),t=require("../services/configPolicy.cjs");let n=require("node:fs");n=e.__toESM(n,1);let r=require("node:path");r=e.__toESM(r,1);let i=require("node:os");i=e.__toESM(i,1);const a=`.doom`,o=`config.yaml`;function s(e){return n.default.existsSync(e)?t.parseDoomConfig(n.default.readFileSync(e,`utf8`),e):{projectTrust:`ask`}}async function c(e){try{return t.parseDoomConfig(await n.default.promises.readFile(e,`utf8`),e)}catch(e){if(e.code===`ENOENT`)return{projectTrust:`ask`};throw e}}function l(e=i.default.homedir()){return r.default.join(e,`.pi`,a)}function u(e=i.default.homedir()){return r.default.join(l(e),o)}function d(e,t,n=i.default.homedir()){if(!e)return r.default.join(n,`.pi`,`plans`);if(e===`~`)return n;if(e.startsWith(`~/`))return r.default.resolve(n,e.slice(2));if(e.startsWith(`~`))throw Error(`Doom planning plansDirectory supports only '~' or '~/' home aliases`);return r.default.isAbsolute(e)?r.default.normalize(e):r.default.resolve(t,e)}function f(e){return r.default.join(e,a,o)}function p(e,n=i.default.homedir()){return t.mergeDoomConfigs(s(u(n)),s(f(e)))}async function m(e,n=i.default.homedir()){let r=await c(u(n)),a=await c(f(e));return t.mergeDoomConfigs(r,a)}exports.globalDoomConfigDirectory=l,exports.globalDoomConfigPath=u,exports.loadDoomConfig=p,exports.loadDoomConfigAsync=m,exports.repositoryDoomConfigPath=f,exports.resolvePlanningPlansDirectory=d;
|
|
2
|
-
//# sourceMappingURL=config.cjs.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"config.cjs","names":["fs","parseDoomConfig","os","path","mergeDoomConfigs"],"sources":["../../src/adapters/config.ts"],"sourcesContent":["import fs from 'node:fs';\nimport os from 'node:os';\nimport path from 'node:path';\nimport { mergeDoomConfigs, parseDoomConfig } from '../services/configPolicy.ts';\nimport type { DoomConfig } from '../types/config.ts';\n\nconst DOOM_DIR = '.doom';\nconst CONFIG_FILE = 'config.yaml';\nconst GLOBAL_CONFIG_DIR = '.pi';\nconst PLANS_DIR = 'plans';\n\nfunction readConfig(filePath: string): DoomConfig {\n return fs.existsSync(filePath)\n ? parseDoomConfig(fs.readFileSync(filePath, 'utf8'), filePath)\n : { projectTrust: 'ask' };\n}\n\nasync function readConfigAsync(filePath: string): Promise<DoomConfig> {\n try {\n return parseDoomConfig(await fs.promises.readFile(filePath, 'utf8'), filePath);\n } catch (error) {\n if ((error as NodeJS.ErrnoException).code === 'ENOENT') return { projectTrust: 'ask' };\n throw error;\n }\n}\n\nexport function globalDoomConfigDirectory(homeDirectory = os.homedir()): string {\n return path.join(homeDirectory, GLOBAL_CONFIG_DIR, DOOM_DIR);\n}\n\nexport function globalDoomConfigPath(homeDirectory = os.homedir()): string {\n return path.join(globalDoomConfigDirectory(homeDirectory), CONFIG_FILE);\n}\n\nexport function resolvePlanningPlansDirectory(\n configured: string | undefined,\n repoRoot: string,\n homeDirectory = os.homedir(),\n): string {\n if (!configured) return path.join(homeDirectory, GLOBAL_CONFIG_DIR, PLANS_DIR);\n if (configured === '~') return homeDirectory;\n if (configured.startsWith('~/')) return path.resolve(homeDirectory, configured.slice(2));\n if (configured.startsWith('~')) {\n throw new Error(\"Doom planning plansDirectory supports only '~' or '~/' home aliases\");\n }\n return path.isAbsolute(configured) ? path.normalize(configured) : path.resolve(repoRoot, configured);\n}\n\nexport function repositoryDoomConfigPath(repoRoot: string): string {\n return path.join(repoRoot, DOOM_DIR, CONFIG_FILE);\n}\n\nexport function loadDoomConfig(repoRoot: string, homeDirectory = os.homedir()): DoomConfig {\n return mergeDoomConfigs(\n readConfig(globalDoomConfigPath(homeDirectory)),\n readConfig(repositoryDoomConfigPath(repoRoot)),\n );\n}\n\nexport async function loadDoomConfigAsync(repoRoot: string, homeDirectory = os.homedir()): Promise<DoomConfig> {\n const globalConfig = await readConfigAsync(globalDoomConfigPath(homeDirectory));\n const repositoryConfig = await readConfigAsync(repositoryDoomConfigPath(repoRoot));\n return mergeDoomConfigs(globalConfig, repositoryConfig);\n}\n"],"mappings":"+NAMA,MAAM,EAAW,QACX,EAAc,cAIpB,SAAS,EAAW,EAA8B,CAChD,OAAOA,EAAAA,QAAG,WAAW,CAAQ,EACzBC,EAAAA,gBAAgBD,EAAAA,QAAG,aAAa,EAAU,MAAM,EAAG,CAAQ,EAC3D,CAAE,aAAc,KAAM,CAC5B,CAEA,eAAe,EAAgB,EAAuC,CACpE,GAAI,CACF,OAAOC,EAAAA,gBAAgB,MAAMD,EAAAA,QAAG,SAAS,SAAS,EAAU,MAAM,EAAG,CAAQ,CAC/E,OAAS,EAAO,CACd,GAAK,EAAgC,OAAS,SAAU,MAAO,CAAE,aAAc,KAAM,EACrF,MAAM,CACR,CACF,CAEA,SAAgB,EAA0B,EAAgBE,EAAAA,QAAG,QAAQ,EAAW,CAC9E,OAAOC,EAAAA,QAAK,KAAK,EAAe,MAAmB,CAAQ,CAC7D,CAEA,SAAgB,EAAqB,EAAgBD,EAAAA,QAAG,QAAQ,EAAW,CACzE,OAAOC,EAAAA,QAAK,KAAK,EAA0B,CAAa,EAAG,CAAW,CACxE,CAEA,SAAgB,EACd,EACA,EACA,EAAgBD,EAAAA,QAAG,QAAQ,EACnB,CACR,GAAI,CAAC,EAAY,OAAOC,EAAAA,QAAK,KAAK,EAAe,MAAmB,OAAS,EAC7E,GAAI,IAAe,IAAK,OAAO,EAC/B,GAAI,EAAW,WAAW,IAAI,EAAG,OAAOA,EAAAA,QAAK,QAAQ,EAAe,EAAW,MAAM,CAAC,CAAC,EACvF,GAAI,EAAW,WAAW,GAAG,EAC3B,MAAU,MAAM,qEAAqE,EAEvF,OAAOA,EAAAA,QAAK,WAAW,CAAU,EAAIA,EAAAA,QAAK,UAAU,CAAU,EAAIA,EAAAA,QAAK,QAAQ,EAAU,CAAU,CACrG,CAEA,SAAgB,EAAyB,EAA0B,CACjE,OAAOA,EAAAA,QAAK,KAAK,EAAU,EAAU,CAAW,CAClD,CAEA,SAAgB,EAAe,EAAkB,EAAgBD,EAAAA,QAAG,QAAQ,EAAe,CACzF,OAAOE,EAAAA,iBACL,EAAW,EAAqB,CAAa,CAAC,EAC9C,EAAW,EAAyB,CAAQ,CAAC,CAC/C,CACF,CAEA,eAAsB,EAAoB,EAAkB,EAAgBF,EAAAA,QAAG,QAAQ,EAAwB,CAC7G,IAAM,EAAe,MAAM,EAAgB,EAAqB,CAAa,CAAC,EACxE,EAAmB,MAAM,EAAgB,EAAyB,CAAQ,CAAC,EACjF,OAAOE,EAAAA,iBAAiB,EAAc,CAAgB,CACxD"}
|
|
@@ -1,11 +0,0 @@
|
|
|
1
|
-
import { DoomConfig } from "../types/config.cjs";
|
|
2
|
-
//#region src/adapters/config.d.ts
|
|
3
|
-
declare function globalDoomConfigDirectory(homeDirectory?: string): string;
|
|
4
|
-
declare function globalDoomConfigPath(homeDirectory?: string): string;
|
|
5
|
-
declare function resolvePlanningPlansDirectory(configured: string | undefined, repoRoot: string, homeDirectory?: string): string;
|
|
6
|
-
declare function repositoryDoomConfigPath(repoRoot: string): string;
|
|
7
|
-
declare function loadDoomConfig(repoRoot: string, homeDirectory?: string): DoomConfig;
|
|
8
|
-
declare function loadDoomConfigAsync(repoRoot: string, homeDirectory?: string): Promise<DoomConfig>;
|
|
9
|
-
//#endregion
|
|
10
|
-
export { globalDoomConfigDirectory, globalDoomConfigPath, loadDoomConfig, loadDoomConfigAsync, repositoryDoomConfigPath, resolvePlanningPlansDirectory };
|
|
11
|
-
//# sourceMappingURL=config.d.cts.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"config.d.cts","names":[],"sources":["../../src/adapters/config.ts"],"mappings":";;iBA0BgB,0BAA0B;iBAI1B,qBAAqB;iBAIrB,8BACd,gCACA,kBACA;iBAWc,yBAAyB;iBAIzB,eAAe,kBAAkB,yBAA+B;iBAO1D,oBAAoB,kBAAkB,yBAA+B,QAAQ"}
|
|
@@ -1,11 +0,0 @@
|
|
|
1
|
-
import { DoomConfig } from "../types/config.mjs";
|
|
2
|
-
//#region src/adapters/config.d.ts
|
|
3
|
-
declare function globalDoomConfigDirectory(homeDirectory?: string): string;
|
|
4
|
-
declare function globalDoomConfigPath(homeDirectory?: string): string;
|
|
5
|
-
declare function resolvePlanningPlansDirectory(configured: string | undefined, repoRoot: string, homeDirectory?: string): string;
|
|
6
|
-
declare function repositoryDoomConfigPath(repoRoot: string): string;
|
|
7
|
-
declare function loadDoomConfig(repoRoot: string, homeDirectory?: string): DoomConfig;
|
|
8
|
-
declare function loadDoomConfigAsync(repoRoot: string, homeDirectory?: string): Promise<DoomConfig>;
|
|
9
|
-
//#endregion
|
|
10
|
-
export { globalDoomConfigDirectory, globalDoomConfigPath, loadDoomConfig, loadDoomConfigAsync, repositoryDoomConfigPath, resolvePlanningPlansDirectory };
|
|
11
|
-
//# sourceMappingURL=config.d.mts.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"config.d.mts","names":[],"sources":["../../src/adapters/config.ts"],"mappings":";;iBA0BgB,0BAA0B;iBAI1B,qBAAqB;iBAIrB,8BACd,gCACA,kBACA;iBAWc,yBAAyB;iBAIzB,eAAe,kBAAkB,yBAA+B;iBAO1D,oBAAoB,kBAAkB,yBAA+B,QAAQ"}
|
package/dist/adapters/config.mjs
DELETED
|
@@ -1,2 +0,0 @@
|
|
|
1
|
-
import{mergeDoomConfigs as e,parseDoomConfig as t}from"../services/configPolicy.mjs";import n from"node:fs";import r from"node:path";import i from"node:os";const a=`.doom`,o=`config.yaml`;function s(e){return n.existsSync(e)?t(n.readFileSync(e,`utf8`),e):{projectTrust:`ask`}}async function c(e){try{return t(await n.promises.readFile(e,`utf8`),e)}catch(e){if(e.code===`ENOENT`)return{projectTrust:`ask`};throw e}}function l(e=i.homedir()){return r.join(e,`.pi`,a)}function u(e=i.homedir()){return r.join(l(e),o)}function d(e,t,n=i.homedir()){if(!e)return r.join(n,`.pi`,`plans`);if(e===`~`)return n;if(e.startsWith(`~/`))return r.resolve(n,e.slice(2));if(e.startsWith(`~`))throw Error(`Doom planning plansDirectory supports only '~' or '~/' home aliases`);return r.isAbsolute(e)?r.normalize(e):r.resolve(t,e)}function f(e){return r.join(e,a,o)}function p(t,n=i.homedir()){return e(s(u(n)),s(f(t)))}async function m(t,n=i.homedir()){let r=await c(u(n)),a=await c(f(t));return e(r,a)}export{l as globalDoomConfigDirectory,u as globalDoomConfigPath,p as loadDoomConfig,m as loadDoomConfigAsync,f as repositoryDoomConfigPath,d as resolvePlanningPlansDirectory};
|
|
2
|
-
//# sourceMappingURL=config.mjs.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"config.mjs","names":[],"sources":["../../src/adapters/config.ts"],"sourcesContent":["import fs from 'node:fs';\nimport os from 'node:os';\nimport path from 'node:path';\nimport { mergeDoomConfigs, parseDoomConfig } from '../services/configPolicy.ts';\nimport type { DoomConfig } from '../types/config.ts';\n\nconst DOOM_DIR = '.doom';\nconst CONFIG_FILE = 'config.yaml';\nconst GLOBAL_CONFIG_DIR = '.pi';\nconst PLANS_DIR = 'plans';\n\nfunction readConfig(filePath: string): DoomConfig {\n return fs.existsSync(filePath)\n ? parseDoomConfig(fs.readFileSync(filePath, 'utf8'), filePath)\n : { projectTrust: 'ask' };\n}\n\nasync function readConfigAsync(filePath: string): Promise<DoomConfig> {\n try {\n return parseDoomConfig(await fs.promises.readFile(filePath, 'utf8'), filePath);\n } catch (error) {\n if ((error as NodeJS.ErrnoException).code === 'ENOENT') return { projectTrust: 'ask' };\n throw error;\n }\n}\n\nexport function globalDoomConfigDirectory(homeDirectory = os.homedir()): string {\n return path.join(homeDirectory, GLOBAL_CONFIG_DIR, DOOM_DIR);\n}\n\nexport function globalDoomConfigPath(homeDirectory = os.homedir()): string {\n return path.join(globalDoomConfigDirectory(homeDirectory), CONFIG_FILE);\n}\n\nexport function resolvePlanningPlansDirectory(\n configured: string | undefined,\n repoRoot: string,\n homeDirectory = os.homedir(),\n): string {\n if (!configured) return path.join(homeDirectory, GLOBAL_CONFIG_DIR, PLANS_DIR);\n if (configured === '~') return homeDirectory;\n if (configured.startsWith('~/')) return path.resolve(homeDirectory, configured.slice(2));\n if (configured.startsWith('~')) {\n throw new Error(\"Doom planning plansDirectory supports only '~' or '~/' home aliases\");\n }\n return path.isAbsolute(configured) ? path.normalize(configured) : path.resolve(repoRoot, configured);\n}\n\nexport function repositoryDoomConfigPath(repoRoot: string): string {\n return path.join(repoRoot, DOOM_DIR, CONFIG_FILE);\n}\n\nexport function loadDoomConfig(repoRoot: string, homeDirectory = os.homedir()): DoomConfig {\n return mergeDoomConfigs(\n readConfig(globalDoomConfigPath(homeDirectory)),\n readConfig(repositoryDoomConfigPath(repoRoot)),\n );\n}\n\nexport async function loadDoomConfigAsync(repoRoot: string, homeDirectory = os.homedir()): Promise<DoomConfig> {\n const globalConfig = await readConfigAsync(globalDoomConfigPath(homeDirectory));\n const repositoryConfig = await readConfigAsync(repositoryDoomConfigPath(repoRoot));\n return mergeDoomConfigs(globalConfig, repositoryConfig);\n}\n"],"mappings":"4JAMA,MAAM,EAAW,QACX,EAAc,cAIpB,SAAS,EAAW,EAA8B,CAChD,OAAO,EAAG,WAAW,CAAQ,EACzB,EAAgB,EAAG,aAAa,EAAU,MAAM,EAAG,CAAQ,EAC3D,CAAE,aAAc,KAAM,CAC5B,CAEA,eAAe,EAAgB,EAAuC,CACpE,GAAI,CACF,OAAO,EAAgB,MAAM,EAAG,SAAS,SAAS,EAAU,MAAM,EAAG,CAAQ,CAC/E,OAAS,EAAO,CACd,GAAK,EAAgC,OAAS,SAAU,MAAO,CAAE,aAAc,KAAM,EACrF,MAAM,CACR,CACF,CAEA,SAAgB,EAA0B,EAAgB,EAAG,QAAQ,EAAW,CAC9E,OAAO,EAAK,KAAK,EAAe,MAAmB,CAAQ,CAC7D,CAEA,SAAgB,EAAqB,EAAgB,EAAG,QAAQ,EAAW,CACzE,OAAO,EAAK,KAAK,EAA0B,CAAa,EAAG,CAAW,CACxE,CAEA,SAAgB,EACd,EACA,EACA,EAAgB,EAAG,QAAQ,EACnB,CACR,GAAI,CAAC,EAAY,OAAO,EAAK,KAAK,EAAe,MAAmB,OAAS,EAC7E,GAAI,IAAe,IAAK,OAAO,EAC/B,GAAI,EAAW,WAAW,IAAI,EAAG,OAAO,EAAK,QAAQ,EAAe,EAAW,MAAM,CAAC,CAAC,EACvF,GAAI,EAAW,WAAW,GAAG,EAC3B,MAAU,MAAM,qEAAqE,EAEvF,OAAO,EAAK,WAAW,CAAU,EAAI,EAAK,UAAU,CAAU,EAAI,EAAK,QAAQ,EAAU,CAAU,CACrG,CAEA,SAAgB,EAAyB,EAA0B,CACjE,OAAO,EAAK,KAAK,EAAU,EAAU,CAAW,CAClD,CAEA,SAAgB,EAAe,EAAkB,EAAgB,EAAG,QAAQ,EAAe,CACzF,OAAO,EACL,EAAW,EAAqB,CAAa,CAAC,EAC9C,EAAW,EAAyB,CAAQ,CAAC,CAC/C,CACF,CAEA,eAAsB,EAAoB,EAAkB,EAAgB,EAAG,QAAQ,EAAwB,CAC7G,IAAM,EAAe,MAAM,EAAgB,EAAqB,CAAa,CAAC,EACxE,EAAmB,MAAM,EAAgB,EAAyB,CAAQ,CAAC,EACjF,OAAO,EAAiB,EAAc,CAAgB,CACxD"}
|
|
@@ -1,2 +0,0 @@
|
|
|
1
|
-
const e=require("../_virtual/_rolldown/runtime.cjs"),t=require("../services/configPolicy.cjs");let n=require("node:crypto"),r=require("node:path");r=e.__toESM(r,1);let i=require("yaml"),a=require("node:fs/promises");a=e.__toESM(a,1);async function o(e){try{return await a.default.readFile(e,`utf8`)}catch(e){if(e instanceof Error&&`code`in e&&e.code===`ENOENT`)return``;throw e}}function s(e){if(typeof e!=`object`||!e)return!1;let t=e.items;return Array.isArray(t)&&t.length===0}function c(e,t){for(let n=t.length-1;n>0;--n){let r=t.slice(0,n);if(e.hasIn(r)){if(!s(e.getIn(r,!0)))return;e.deleteIn(r)}}}async function l(e,s,l={}){if(s.length===0)return;let u=await o(e),d=(0,i.parseDocument)(u,{keepSourceTokens:!0});if(d.errors.length>0)throw Error(`Could not parse Doom config at ${e}`);for(let e of s){let t=[...e.keyPath];if(e.value!==void 0){d.setIn(t,e.value);continue}d.hasIn(t)&&(d.deleteIn(t),l.prune!==!1&&c(d,t))}let f=d.toString();t.parseDoomConfig(f,e),await a.default.mkdir(r.default.dirname(e),{mode:448,recursive:!0});let p=`${e}.${process.pid}.${(0,n.randomUUID)()}.tmp`;try{await a.default.writeFile(p,f,{encoding:`utf8`,mode:384}),await a.default.rename(p,e)}catch(e){throw await a.default.rm(p,{force:!0}),e}}async function u(e,t,n){await l(e,[{keyPath:t,value:n}])}async function d(e,t){await l(e,[{keyPath:t}])}exports.setDoomConfigValue=u,exports.unsetDoomConfigValue=d,exports.writeDoomConfigValues=l;
|
|
2
|
-
//# sourceMappingURL=configWriter.cjs.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"configWriter.cjs","names":["fs","parseDocument","path","randomUUID"],"sources":["../../src/adapters/configWriter.ts"],"sourcesContent":["/**\n * Writes into the global Doom config file, one key path at a time.\n *\n * Extracted from doom-file-edit, which owned the only writer in the repo and had\n * it hard-coded to `editor.command`. Several extensions now edit their own\n * settings from the config panel, and every one of them needs the same four\n * properties: keep the user's comments, never publish a file the parser would\n * reject, never leave a half-written file behind, and apply a set of related\n * edits together.\n *\n * That last one is not a convenience. `voice.adapters.<engine>.model` accepts a\n * path or an id but not both, so switching between them is a set and an unset\n * that must land in the same write, or the file is briefly invalid.\n *\n * Atomicity is the same rename trick as `atomicJson.ts` next door, and carries\n * the same caveat: it prevents torn reads, not lost updates. Two sessions with\n * the panel open still clobber each other, because the rename only publishes\n * what the caller already computed.\n *\n * AVOID:\n * - Treating this as a lock\n * - Writing an empty string; the parser rejects blank values, so clearing a key\n * means removing it\n */\n\nimport { randomUUID } from 'node:crypto';\nimport fs from 'node:fs/promises';\nimport path from 'node:path';\nimport { parseDocument } from 'yaml';\nimport { parseDoomConfig } from '../services/configPolicy.ts';\n\nconst PRIVATE_FILE_MODE = 0o600;\nconst PRIVATE_DIRECTORY_MODE = 0o700;\n\nexport interface DoomConfigEdit {\n /** Key path into the document, e.g. `['voice', 'adapters', 'mlx-whisper', 'model', 'id']`. */\n readonly keyPath: readonly string[];\n /** The value to write. `undefined` removes the key. */\n readonly value?: string;\n}\n\nexport interface WriteDoomConfigOptions {\n /**\n * Remove ancestors left holding nothing. Defaults to true, and is not\n * cosmetic: an adapter left as `{}` fails validation, because the parser\n * requires a model once the adapter exists at all.\n */\n readonly prune?: boolean;\n}\n\nasync function readIfPresent(filePath: string): Promise<string> {\n try {\n return await fs.readFile(filePath, 'utf8');\n } catch (error) {\n if (error instanceof Error && 'code' in error && error.code === 'ENOENT') return '';\n throw error;\n }\n}\n\nfunction isEmptyCollection(value: unknown): boolean {\n if (value === null || typeof value !== 'object') return false;\n const items = (value as { items?: unknown }).items;\n return Array.isArray(items) && items.length === 0;\n}\n\n/** Drops ancestors of a removed key that are now empty, deepest first. */\nfunction pruneEmptyAncestors(document: ReturnType<typeof parseDocument>, keyPath: readonly string[]): void {\n for (let depth = keyPath.length - 1; depth > 0; depth -= 1) {\n const ancestor = keyPath.slice(0, depth);\n if (!document.hasIn(ancestor)) continue;\n if (!isEmptyCollection(document.getIn(ancestor, true))) return;\n document.deleteIn(ancestor);\n }\n}\n\n/**\n * Applies every edit as one document mutation, or throws having written nothing.\n *\n * Validation runs against the serialized result rather than each edit, so a pair\n * of edits only valid together is accepted, and a single edit that breaks an\n * invariant elsewhere is still caught.\n */\nexport async function writeDoomConfigValues(\n filePath: string,\n edits: readonly DoomConfigEdit[],\n options: WriteDoomConfigOptions = {},\n): Promise<void> {\n if (edits.length === 0) return;\n const content = await readIfPresent(filePath);\n // Not `content || '{}\\n'`: seeding an absent file with a flow map makes yaml\n // keep that style, so the first write produces `{ editor: { command: ... } }`\n // and every later one grows that one line. An empty source starts a block map.\n const document = parseDocument(content, { keepSourceTokens: true });\n if (document.errors.length > 0) throw new Error(`Could not parse Doom config at ${filePath}`);\n\n for (const edit of edits) {\n const keyPath = [...edit.keyPath];\n if (edit.value !== undefined) {\n document.setIn(keyPath, edit.value);\n continue;\n }\n // deleteIn throws when an ancestor is missing rather than treating the key as\n // already absent, and clearing an unset key is worth supporting.\n if (!document.hasIn(keyPath)) continue;\n document.deleteIn(keyPath);\n if (options.prune !== false) pruneEmptyAncestors(document, keyPath);\n }\n\n const output = document.toString();\n parseDoomConfig(output, filePath);\n\n await fs.mkdir(path.dirname(filePath), { mode: PRIVATE_DIRECTORY_MODE, recursive: true });\n const temporaryPath = `${filePath}.${process.pid}.${randomUUID()}.tmp`;\n try {\n await fs.writeFile(temporaryPath, output, { encoding: 'utf8', mode: PRIVATE_FILE_MODE });\n await fs.rename(temporaryPath, filePath);\n } catch (error) {\n await fs.rm(temporaryPath, { force: true });\n throw error;\n }\n}\n\nexport async function setDoomConfigValue(filePath: string, keyPath: readonly string[], value: string): Promise<void> {\n await writeDoomConfigValues(filePath, [{ keyPath, value }]);\n}\n\nexport async function unsetDoomConfigValue(filePath: string, keyPath: readonly string[]): Promise<void> {\n await writeDoomConfigValues(filePath, [{ keyPath }]);\n}\n"],"mappings":"yOAkDA,eAAe,EAAc,EAAmC,CAC9D,GAAI,CACF,OAAO,MAAMA,EAAAA,QAAG,SAAS,EAAU,MAAM,CAC3C,OAAS,EAAO,CACd,GAAI,aAAiB,OAAS,SAAU,GAAS,EAAM,OAAS,SAAU,MAAO,GACjF,MAAM,CACR,CACF,CAEA,SAAS,EAAkB,EAAyB,CAClD,GAAsB,OAAO,GAAU,WAAnC,EAA6C,MAAO,GACxD,IAAM,EAAS,EAA8B,MAC7C,OAAO,MAAM,QAAQ,CAAK,GAAK,EAAM,SAAW,CAClD,CAGA,SAAS,EAAoB,EAA4C,EAAkC,CACzG,IAAK,IAAI,EAAQ,EAAQ,OAAS,EAAG,EAAQ,EAAG,IAAY,CAC1D,IAAM,EAAW,EAAQ,MAAM,EAAG,CAAK,EAClC,KAAS,MAAM,CAAQ,EAC5B,IAAI,CAAC,EAAkB,EAAS,MAAM,EAAU,EAAI,CAAC,EAAG,OACxD,EAAS,SAAS,CAAQ,CAD8B,CAE1D,CACF,CASA,eAAsB,EACpB,EACA,EACA,EAAkC,CAAC,EACpB,CACf,GAAI,EAAM,SAAW,EAAG,OACxB,IAAM,EAAU,MAAM,EAAc,CAAQ,EAItC,GAAA,EAAWC,EAAAA,cAAAA,CAAc,EAAS,CAAE,iBAAkB,EAAK,CAAC,EAClE,GAAI,EAAS,OAAO,OAAS,EAAG,MAAU,MAAM,kCAAkC,GAAU,EAE5F,IAAK,IAAM,KAAQ,EAAO,CACxB,IAAM,EAAU,CAAC,GAAG,EAAK,OAAO,EAChC,GAAI,EAAK,QAAU,IAAA,GAAW,CAC5B,EAAS,MAAM,EAAS,EAAK,KAAK,EAClC,QACF,CAGK,EAAS,MAAM,CAAO,IAC3B,EAAS,SAAS,CAAO,EACrB,EAAQ,QAAU,IAAO,EAAoB,EAAU,CAAO,EACpE,CAEA,IAAM,EAAS,EAAS,SAAS,EACjC,EAAA,gBAAgB,EAAQ,CAAQ,EAEhC,MAAMD,EAAAA,QAAG,MAAME,EAAAA,QAAK,QAAQ,CAAQ,EAAG,CAAE,KAAM,IAAwB,UAAW,EAAK,CAAC,EACxF,IAAM,EAAgB,GAAG,EAAS,GAAG,QAAQ,IAAI,IAAA,EAAGC,EAAAA,WAAAA,CAAW,EAAE,MACjE,GAAI,CACF,MAAMH,EAAAA,QAAG,UAAU,EAAe,EAAQ,CAAE,SAAU,OAAQ,KAAM,GAAkB,CAAC,EACvF,MAAMA,EAAAA,QAAG,OAAO,EAAe,CAAQ,CACzC,OAAS,EAAO,CAEd,MADA,MAAMA,EAAAA,QAAG,GAAG,EAAe,CAAE,MAAO,EAAK,CAAC,EACpC,CACR,CACF,CAEA,eAAsB,EAAmB,EAAkB,EAA4B,EAA8B,CACnH,MAAM,EAAsB,EAAU,CAAC,CAAE,UAAS,OAAM,CAAC,CAAC,CAC5D,CAEA,eAAsB,EAAqB,EAAkB,EAA2C,CACtG,MAAM,EAAsB,EAAU,CAAC,CAAE,SAAQ,CAAC,CAAC,CACrD"}
|
|
@@ -1,52 +0,0 @@
|
|
|
1
|
-
//#region src/adapters/configWriter.d.ts
|
|
2
|
-
/**
|
|
3
|
-
* Writes into the global Doom config file, one key path at a time.
|
|
4
|
-
*
|
|
5
|
-
* Extracted from doom-file-edit, which owned the only writer in the repo and had
|
|
6
|
-
* it hard-coded to `editor.command`. Several extensions now edit their own
|
|
7
|
-
* settings from the config panel, and every one of them needs the same four
|
|
8
|
-
* properties: keep the user's comments, never publish a file the parser would
|
|
9
|
-
* reject, never leave a half-written file behind, and apply a set of related
|
|
10
|
-
* edits together.
|
|
11
|
-
*
|
|
12
|
-
* That last one is not a convenience. `voice.adapters.<engine>.model` accepts a
|
|
13
|
-
* path or an id but not both, so switching between them is a set and an unset
|
|
14
|
-
* that must land in the same write, or the file is briefly invalid.
|
|
15
|
-
*
|
|
16
|
-
* Atomicity is the same rename trick as `atomicJson.ts` next door, and carries
|
|
17
|
-
* the same caveat: it prevents torn reads, not lost updates. Two sessions with
|
|
18
|
-
* the panel open still clobber each other, because the rename only publishes
|
|
19
|
-
* what the caller already computed.
|
|
20
|
-
*
|
|
21
|
-
* AVOID:
|
|
22
|
-
* - Treating this as a lock
|
|
23
|
-
* - Writing an empty string; the parser rejects blank values, so clearing a key
|
|
24
|
-
* means removing it
|
|
25
|
-
*/
|
|
26
|
-
interface DoomConfigEdit {
|
|
27
|
-
/** Key path into the document, e.g. `['voice', 'adapters', 'mlx-whisper', 'model', 'id']`. */
|
|
28
|
-
readonly keyPath: readonly string[];
|
|
29
|
-
/** The value to write. `undefined` removes the key. */
|
|
30
|
-
readonly value?: string;
|
|
31
|
-
}
|
|
32
|
-
interface WriteDoomConfigOptions {
|
|
33
|
-
/**
|
|
34
|
-
* Remove ancestors left holding nothing. Defaults to true, and is not
|
|
35
|
-
* cosmetic: an adapter left as `{}` fails validation, because the parser
|
|
36
|
-
* requires a model once the adapter exists at all.
|
|
37
|
-
*/
|
|
38
|
-
readonly prune?: boolean;
|
|
39
|
-
}
|
|
40
|
-
/**
|
|
41
|
-
* Applies every edit as one document mutation, or throws having written nothing.
|
|
42
|
-
*
|
|
43
|
-
* Validation runs against the serialized result rather than each edit, so a pair
|
|
44
|
-
* of edits only valid together is accepted, and a single edit that breaks an
|
|
45
|
-
* invariant elsewhere is still caught.
|
|
46
|
-
*/
|
|
47
|
-
declare function writeDoomConfigValues(filePath: string, edits: readonly DoomConfigEdit[], options?: WriteDoomConfigOptions): Promise<void>;
|
|
48
|
-
declare function setDoomConfigValue(filePath: string, keyPath: readonly string[], value: string): Promise<void>;
|
|
49
|
-
declare function unsetDoomConfigValue(filePath: string, keyPath: readonly string[]): Promise<void>;
|
|
50
|
-
//#endregion
|
|
51
|
-
export { DoomConfigEdit, WriteDoomConfigOptions, setDoomConfigValue, unsetDoomConfigValue, writeDoomConfigValues };
|
|
52
|
-
//# sourceMappingURL=configWriter.d.cts.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"configWriter.d.cts","names":[],"sources":["../../src/adapters/configWriter.ts"],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;UAkCiB;;WAEN;;WAEA;;UAGM;;;;;;WAMN;;;;;;;;;iBAmCW,sBACpB,kBACA,gBAAgB,kBAChB,UAAS,yBACR;iBAoCmB,mBAAmB,kBAAkB,4BAA4B,gBAAgB;iBAIjF,qBAAqB,kBAAkB,6BAA6B"}
|
|
@@ -1,52 +0,0 @@
|
|
|
1
|
-
//#region src/adapters/configWriter.d.ts
|
|
2
|
-
/**
|
|
3
|
-
* Writes into the global Doom config file, one key path at a time.
|
|
4
|
-
*
|
|
5
|
-
* Extracted from doom-file-edit, which owned the only writer in the repo and had
|
|
6
|
-
* it hard-coded to `editor.command`. Several extensions now edit their own
|
|
7
|
-
* settings from the config panel, and every one of them needs the same four
|
|
8
|
-
* properties: keep the user's comments, never publish a file the parser would
|
|
9
|
-
* reject, never leave a half-written file behind, and apply a set of related
|
|
10
|
-
* edits together.
|
|
11
|
-
*
|
|
12
|
-
* That last one is not a convenience. `voice.adapters.<engine>.model` accepts a
|
|
13
|
-
* path or an id but not both, so switching between them is a set and an unset
|
|
14
|
-
* that must land in the same write, or the file is briefly invalid.
|
|
15
|
-
*
|
|
16
|
-
* Atomicity is the same rename trick as `atomicJson.ts` next door, and carries
|
|
17
|
-
* the same caveat: it prevents torn reads, not lost updates. Two sessions with
|
|
18
|
-
* the panel open still clobber each other, because the rename only publishes
|
|
19
|
-
* what the caller already computed.
|
|
20
|
-
*
|
|
21
|
-
* AVOID:
|
|
22
|
-
* - Treating this as a lock
|
|
23
|
-
* - Writing an empty string; the parser rejects blank values, so clearing a key
|
|
24
|
-
* means removing it
|
|
25
|
-
*/
|
|
26
|
-
interface DoomConfigEdit {
|
|
27
|
-
/** Key path into the document, e.g. `['voice', 'adapters', 'mlx-whisper', 'model', 'id']`. */
|
|
28
|
-
readonly keyPath: readonly string[];
|
|
29
|
-
/** The value to write. `undefined` removes the key. */
|
|
30
|
-
readonly value?: string;
|
|
31
|
-
}
|
|
32
|
-
interface WriteDoomConfigOptions {
|
|
33
|
-
/**
|
|
34
|
-
* Remove ancestors left holding nothing. Defaults to true, and is not
|
|
35
|
-
* cosmetic: an adapter left as `{}` fails validation, because the parser
|
|
36
|
-
* requires a model once the adapter exists at all.
|
|
37
|
-
*/
|
|
38
|
-
readonly prune?: boolean;
|
|
39
|
-
}
|
|
40
|
-
/**
|
|
41
|
-
* Applies every edit as one document mutation, or throws having written nothing.
|
|
42
|
-
*
|
|
43
|
-
* Validation runs against the serialized result rather than each edit, so a pair
|
|
44
|
-
* of edits only valid together is accepted, and a single edit that breaks an
|
|
45
|
-
* invariant elsewhere is still caught.
|
|
46
|
-
*/
|
|
47
|
-
declare function writeDoomConfigValues(filePath: string, edits: readonly DoomConfigEdit[], options?: WriteDoomConfigOptions): Promise<void>;
|
|
48
|
-
declare function setDoomConfigValue(filePath: string, keyPath: readonly string[], value: string): Promise<void>;
|
|
49
|
-
declare function unsetDoomConfigValue(filePath: string, keyPath: readonly string[]): Promise<void>;
|
|
50
|
-
//#endregion
|
|
51
|
-
export { DoomConfigEdit, WriteDoomConfigOptions, setDoomConfigValue, unsetDoomConfigValue, writeDoomConfigValues };
|
|
52
|
-
//# sourceMappingURL=configWriter.d.mts.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"configWriter.d.mts","names":[],"sources":["../../src/adapters/configWriter.ts"],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;UAkCiB;;WAEN;;WAEA;;UAGM;;;;;;WAMN;;;;;;;;;iBAmCW,sBACpB,kBACA,gBAAgB,kBAChB,UAAS,yBACR;iBAoCmB,mBAAmB,kBAAkB,4BAA4B,gBAAgB;iBAIjF,qBAAqB,kBAAkB,6BAA6B"}
|
|
@@ -1,2 +0,0 @@
|
|
|
1
|
-
import{parseDoomConfig as e}from"../services/configPolicy.mjs";import{randomUUID as t}from"node:crypto";import n from"node:path";import{parseDocument as r}from"yaml";import i from"node:fs/promises";async function a(e){try{return await i.readFile(e,`utf8`)}catch(e){if(e instanceof Error&&`code`in e&&e.code===`ENOENT`)return``;throw e}}function o(e){if(typeof e!=`object`||!e)return!1;let t=e.items;return Array.isArray(t)&&t.length===0}function s(e,t){for(let n=t.length-1;n>0;--n){let r=t.slice(0,n);if(e.hasIn(r)){if(!o(e.getIn(r,!0)))return;e.deleteIn(r)}}}async function c(o,c,l={}){if(c.length===0)return;let u=await a(o),d=r(u,{keepSourceTokens:!0});if(d.errors.length>0)throw Error(`Could not parse Doom config at ${o}`);for(let e of c){let t=[...e.keyPath];if(e.value!==void 0){d.setIn(t,e.value);continue}d.hasIn(t)&&(d.deleteIn(t),l.prune!==!1&&s(d,t))}let f=d.toString();e(f,o),await i.mkdir(n.dirname(o),{mode:448,recursive:!0});let p=`${o}.${process.pid}.${t()}.tmp`;try{await i.writeFile(p,f,{encoding:`utf8`,mode:384}),await i.rename(p,o)}catch(e){throw await i.rm(p,{force:!0}),e}}async function l(e,t,n){await c(e,[{keyPath:t,value:n}])}async function u(e,t){await c(e,[{keyPath:t}])}export{l as setDoomConfigValue,u as unsetDoomConfigValue,c as writeDoomConfigValues};
|
|
2
|
-
//# sourceMappingURL=configWriter.mjs.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"configWriter.mjs","names":[],"sources":["../../src/adapters/configWriter.ts"],"sourcesContent":["/**\n * Writes into the global Doom config file, one key path at a time.\n *\n * Extracted from doom-file-edit, which owned the only writer in the repo and had\n * it hard-coded to `editor.command`. Several extensions now edit their own\n * settings from the config panel, and every one of them needs the same four\n * properties: keep the user's comments, never publish a file the parser would\n * reject, never leave a half-written file behind, and apply a set of related\n * edits together.\n *\n * That last one is not a convenience. `voice.adapters.<engine>.model` accepts a\n * path or an id but not both, so switching between them is a set and an unset\n * that must land in the same write, or the file is briefly invalid.\n *\n * Atomicity is the same rename trick as `atomicJson.ts` next door, and carries\n * the same caveat: it prevents torn reads, not lost updates. Two sessions with\n * the panel open still clobber each other, because the rename only publishes\n * what the caller already computed.\n *\n * AVOID:\n * - Treating this as a lock\n * - Writing an empty string; the parser rejects blank values, so clearing a key\n * means removing it\n */\n\nimport { randomUUID } from 'node:crypto';\nimport fs from 'node:fs/promises';\nimport path from 'node:path';\nimport { parseDocument } from 'yaml';\nimport { parseDoomConfig } from '../services/configPolicy.ts';\n\nconst PRIVATE_FILE_MODE = 0o600;\nconst PRIVATE_DIRECTORY_MODE = 0o700;\n\nexport interface DoomConfigEdit {\n /** Key path into the document, e.g. `['voice', 'adapters', 'mlx-whisper', 'model', 'id']`. */\n readonly keyPath: readonly string[];\n /** The value to write. `undefined` removes the key. */\n readonly value?: string;\n}\n\nexport interface WriteDoomConfigOptions {\n /**\n * Remove ancestors left holding nothing. Defaults to true, and is not\n * cosmetic: an adapter left as `{}` fails validation, because the parser\n * requires a model once the adapter exists at all.\n */\n readonly prune?: boolean;\n}\n\nasync function readIfPresent(filePath: string): Promise<string> {\n try {\n return await fs.readFile(filePath, 'utf8');\n } catch (error) {\n if (error instanceof Error && 'code' in error && error.code === 'ENOENT') return '';\n throw error;\n }\n}\n\nfunction isEmptyCollection(value: unknown): boolean {\n if (value === null || typeof value !== 'object') return false;\n const items = (value as { items?: unknown }).items;\n return Array.isArray(items) && items.length === 0;\n}\n\n/** Drops ancestors of a removed key that are now empty, deepest first. */\nfunction pruneEmptyAncestors(document: ReturnType<typeof parseDocument>, keyPath: readonly string[]): void {\n for (let depth = keyPath.length - 1; depth > 0; depth -= 1) {\n const ancestor = keyPath.slice(0, depth);\n if (!document.hasIn(ancestor)) continue;\n if (!isEmptyCollection(document.getIn(ancestor, true))) return;\n document.deleteIn(ancestor);\n }\n}\n\n/**\n * Applies every edit as one document mutation, or throws having written nothing.\n *\n * Validation runs against the serialized result rather than each edit, so a pair\n * of edits only valid together is accepted, and a single edit that breaks an\n * invariant elsewhere is still caught.\n */\nexport async function writeDoomConfigValues(\n filePath: string,\n edits: readonly DoomConfigEdit[],\n options: WriteDoomConfigOptions = {},\n): Promise<void> {\n if (edits.length === 0) return;\n const content = await readIfPresent(filePath);\n // Not `content || '{}\\n'`: seeding an absent file with a flow map makes yaml\n // keep that style, so the first write produces `{ editor: { command: ... } }`\n // and every later one grows that one line. An empty source starts a block map.\n const document = parseDocument(content, { keepSourceTokens: true });\n if (document.errors.length > 0) throw new Error(`Could not parse Doom config at ${filePath}`);\n\n for (const edit of edits) {\n const keyPath = [...edit.keyPath];\n if (edit.value !== undefined) {\n document.setIn(keyPath, edit.value);\n continue;\n }\n // deleteIn throws when an ancestor is missing rather than treating the key as\n // already absent, and clearing an unset key is worth supporting.\n if (!document.hasIn(keyPath)) continue;\n document.deleteIn(keyPath);\n if (options.prune !== false) pruneEmptyAncestors(document, keyPath);\n }\n\n const output = document.toString();\n parseDoomConfig(output, filePath);\n\n await fs.mkdir(path.dirname(filePath), { mode: PRIVATE_DIRECTORY_MODE, recursive: true });\n const temporaryPath = `${filePath}.${process.pid}.${randomUUID()}.tmp`;\n try {\n await fs.writeFile(temporaryPath, output, { encoding: 'utf8', mode: PRIVATE_FILE_MODE });\n await fs.rename(temporaryPath, filePath);\n } catch (error) {\n await fs.rm(temporaryPath, { force: true });\n throw error;\n }\n}\n\nexport async function setDoomConfigValue(filePath: string, keyPath: readonly string[], value: string): Promise<void> {\n await writeDoomConfigValues(filePath, [{ keyPath, value }]);\n}\n\nexport async function unsetDoomConfigValue(filePath: string, keyPath: readonly string[]): Promise<void> {\n await writeDoomConfigValues(filePath, [{ keyPath }]);\n}\n"],"mappings":"sMAkDA,eAAe,EAAc,EAAmC,CAC9D,GAAI,CACF,OAAO,MAAM,EAAG,SAAS,EAAU,MAAM,CAC3C,OAAS,EAAO,CACd,GAAI,aAAiB,OAAS,SAAU,GAAS,EAAM,OAAS,SAAU,MAAO,GACjF,MAAM,CACR,CACF,CAEA,SAAS,EAAkB,EAAyB,CAClD,GAAsB,OAAO,GAAU,WAAnC,EAA6C,MAAO,GACxD,IAAM,EAAS,EAA8B,MAC7C,OAAO,MAAM,QAAQ,CAAK,GAAK,EAAM,SAAW,CAClD,CAGA,SAAS,EAAoB,EAA4C,EAAkC,CACzG,IAAK,IAAI,EAAQ,EAAQ,OAAS,EAAG,EAAQ,EAAG,IAAY,CAC1D,IAAM,EAAW,EAAQ,MAAM,EAAG,CAAK,EAClC,KAAS,MAAM,CAAQ,EAC5B,IAAI,CAAC,EAAkB,EAAS,MAAM,EAAU,EAAI,CAAC,EAAG,OACxD,EAAS,SAAS,CAAQ,CAD8B,CAE1D,CACF,CASA,eAAsB,EACpB,EACA,EACA,EAAkC,CAAC,EACpB,CACf,GAAI,EAAM,SAAW,EAAG,OACxB,IAAM,EAAU,MAAM,EAAc,CAAQ,EAItC,EAAW,EAAc,EAAS,CAAE,iBAAkB,EAAK,CAAC,EAClE,GAAI,EAAS,OAAO,OAAS,EAAG,MAAU,MAAM,kCAAkC,GAAU,EAE5F,IAAK,IAAM,KAAQ,EAAO,CACxB,IAAM,EAAU,CAAC,GAAG,EAAK,OAAO,EAChC,GAAI,EAAK,QAAU,IAAA,GAAW,CAC5B,EAAS,MAAM,EAAS,EAAK,KAAK,EAClC,QACF,CAGK,EAAS,MAAM,CAAO,IAC3B,EAAS,SAAS,CAAO,EACrB,EAAQ,QAAU,IAAO,EAAoB,EAAU,CAAO,EACpE,CAEA,IAAM,EAAS,EAAS,SAAS,EACjC,EAAgB,EAAQ,CAAQ,EAEhC,MAAM,EAAG,MAAM,EAAK,QAAQ,CAAQ,EAAG,CAAE,KAAM,IAAwB,UAAW,EAAK,CAAC,EACxF,IAAM,EAAgB,GAAG,EAAS,GAAG,QAAQ,IAAI,GAAG,EAAW,EAAE,MACjE,GAAI,CACF,MAAM,EAAG,UAAU,EAAe,EAAQ,CAAE,SAAU,OAAQ,KAAM,GAAkB,CAAC,EACvF,MAAM,EAAG,OAAO,EAAe,CAAQ,CACzC,OAAS,EAAO,CAEd,MADA,MAAM,EAAG,GAAG,EAAe,CAAE,MAAO,EAAK,CAAC,EACpC,CACR,CACF,CAEA,eAAsB,EAAmB,EAAkB,EAA4B,EAA8B,CACnH,MAAM,EAAsB,EAAU,CAAC,CAAE,UAAS,OAAM,CAAC,CAAC,CAC5D,CAEA,eAAsB,EAAqB,EAAkB,EAA2C,CACtG,MAAM,EAAsB,EAAU,CAAC,CAAE,SAAQ,CAAC,CAAC,CACrD"}
|
|
@@ -1,2 +0,0 @@
|
|
|
1
|
-
const e=require("../_virtual/_rolldown/runtime.cjs"),t=require("./config.cjs"),n=require("../services/domains.cjs"),r=require("./layeredConfig.cjs"),i=require("./pluginCatalog.cjs");let a=require("node:fs");a=e.__toESM(a,1);let o=require("node:path");o=e.__toESM(o,1);let s=require("node:os");s=e.__toESM(s,1);const c=`Plugin directory does not exist`,l=`.doom/domains.yaml`;function u(e){return typeof e==`object`&&!!e&&!Array.isArray(e)}function d(e,t){if(!u(e))throw Error(`${t} must be an object`);return e}function f(e,t,n){let r=Object.keys(e).filter(e=>!t.includes(e));if(r.length>0)throw Error(`${n} contains unsupported field "${r[0]}"`)}function p(e,t){if(typeof e!=`string`||!e.trim())throw Error(`${t} must be a non-empty string`);return e.trim()}function m(e,t){if(e!==void 0)return p(e,t)}function h(e,t){if(!Array.isArray(e))throw Error(`${t} must be an array of non-empty strings`);return[...new Set(e.map((e,n)=>p(e,`${t}[${n}]`)))]}function g(e,t){if(e!==void 0){if(typeof e!=`boolean`)throw Error(`${t} must be a boolean`);return e}}function _(e){return h(e,`defaultDomains in ${l}`)}function v(e,t){if(typeof e==`string`)return p(e,t);let n=d(e,t);f(n,[`name`,`skills`,`agents`,`hooks`,`mcp`],t);let r=n.skills===void 0?void 0:h(n.skills,`${t}.skills`),i=n.agents===void 0?void 0:h(n.agents,`${t}.agents`),a=g(n.hooks,`${t}.hooks`),o=g(n.mcp,`${t}.mcp`);return{name:p(n.name,`${t}.name`),...r?{skills:r}:{},...i?{agents:i}:{},...a===void 0?{}:{hooks:a},...o===void 0?{}:{mcp:o}}}function y(e,t){let n=d(e,t);return f(n,[`servers`,`proxy`],t),{...n.servers===void 0?{}:{servers:h(n.servers,`${t}.servers`)},...n.proxy===void 0?{}:{proxy:h(n.proxy,`${t}.proxy`)}}}function b(e,t){let n=d(e,t);f(n,[`description`,`plugins`,`mcp`,`sharedSkills`],t);let r=m(n.description,`${t}.description`);if(n.plugins!==void 0&&!Array.isArray(n.plugins))throw Error(`${t}.plugins must be an array`);let i=g(n.sharedSkills,`${t}.sharedSkills`);return{...r?{description:r}:{},...Array.isArray(n.plugins)?{plugins:n.plugins.map((e,n)=>v(e,`${t}.plugins[${n}]`))}:{},...n.mcp===void 0?{}:{mcp:y(n.mcp,`${t}.mcp`)},...i===void 0?{}:{sharedSkills:i}}}function x(e,t){if(e===void 0)return{};let n=d(e,t);return Object.fromEntries(Object.entries(n).map(([e,n])=>[e,h(n,`${t}.${e}`)]))}function S(e,t=s.default.homedir()){let a=r.readDoomConfigSources(`domains.yaml`,e,t),o={},c={},u;for(let e of a){let t=d(e.document,e.filePath);if(f(t,[`plugins`,`domains`,`aliases`,`defaultDomains`],e.filePath),Object.assign(o,x(t.aliases,`aliases in ${e.filePath}`)),t.domains!==void 0){let n=d(t.domains,`domains in ${e.filePath}`);for(let[t,r]of Object.entries(n))c[t]={...b(r,`domains.${t} in ${e.filePath}`),baseDirectory:e.baseDirectory}}Object.hasOwn(t,`defaultDomains`)&&(u=_(t.defaultDomains))}let p=i.loadPluginCatalog(a.map(e=>({filePath:e.filePath,baseDirectory:e.baseDirectory,value:d(e.document,e.filePath).plugins})),e,t);if(u){for(let e of n.expandDomainNames({plugins:p,domains:c,aliases:o},u))if(!Object.hasOwn(c,e))throw Error(`Unknown default domain "${e}" in ${l}`)}return{plugins:p,domains:c,aliases:o,...u?{defaultDomains:u}:{}}}function C(e,t){let n=S(e,t);return[...new Set([...Object.keys(n.domains),...Object.keys(n.aliases)])].sort()}function w(e,t,r){let i=S(e,r),a=n.expandDomainNames(i,t);return a.length===0||a.some(e=>i.domains[e]?.sharedSkills!==!1)}function T(e,r,l,u=s.default.homedir()){let d=S(e,u),f=[],p=new Set,m=t.globalDoomConfigDirectory(u);for(let e of n.expandDomainNames(d,r)){let t=d.domains[e];if(!t)throw Error(`Unknown domain: ${e}`);for(let n of t.plugins??[]){let t=typeof n!=`string`,r=t?n.name:n,o=d.plugins.entries[r];if(!o)throw Error(`Unknown plugin "${r}" referenced by domain "${e}"`);let s=i.pluginDirectoryForSource(o.source,m);if(o.source.type===`local`&&(!a.default.existsSync(s)||!a.default.statSync(s).isDirectory()))throw Error(`${c}: ${s}`);p.has(s)||(p.add(s),f.push({name:r,directory:s,source:o.source,...o.manifest?{manifest:o.manifest}:{},...o.manifest?.agentPluginSchema===`https://agent-plugins.org/schemas/1.0.0/plugin.schema.json`?{skillDiscovery:`direct-children`}:{},...t&&n.skills?{skills:n.skills}:{},...t&&n.agents?{agents:n.agents}:{},...t&&n.hooks!==void 0?{hooks:n.hooks}:{},...t&&n.mcp!==void 0?{mcp:n.mcp}:{}}))}}for(let e of l){let t=o.default.resolve(e);if(!a.default.existsSync(t)||!a.default.statSync(t).isDirectory())throw Error(`${c}: ${t}`);p.has(t)||(p.add(t),f.push({name:o.default.basename(t),directory:t,source:{type:`local`,path:t}}))}return f}function E(e,t,n,r){return T(e,t,n,r).map(e=>e.directory)}const D=`DOOMPI_DOMAINS`,O=`default`,k=`marketing`;function A(e){return e.split(`,`).map(e=>e.trim()).filter(Boolean)}function j(e,t,n){let r=t[D];return r===void 0?n===void 0?A(e===k?k:O):[...n]:A(r)}exports.DEFAULT_DOMAIN=O,exports.DOOMPI_DOMAINS_ENV=D,exports.DOOM_DIR=r.DOOM_DIR,exports.defaultDomainsForMajorMode=j,exports.listDomainNames=C,exports.loadDomains=S,exports.resolvePluginDirectories=E,exports.resolvePluginEntries=T,exports.resolveSharedSkills=w;
|
|
2
|
-
//# sourceMappingURL=domains.cjs.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"domains.cjs","names":["os","readDoomConfigSources","loadPluginCatalog","expandDomainNames","globalDoomConfigDirectory","pluginDirectoryForSource","fs","path"],"sources":["../../src/adapters/domains.ts"],"sourcesContent":["import fs from 'node:fs';\nimport os from 'node:os';\nimport path from 'node:path';\nimport { expandDomainNames } from '../services/domains.ts';\nimport type {\n DomainDefinition,\n DomainManifest,\n DomainMcpAllowlist,\n DomainPlugin,\n PluginEntry,\n ResolvedDomain,\n} from '../types/domains.ts';\nimport { globalDoomConfigDirectory } from './config.ts';\nimport { readDoomConfigSources } from './layeredConfig.ts';\nimport { loadPluginCatalog, pluginDirectoryForSource } from './pluginCatalog.ts';\n\nexport { DOOM_DIR } from './layeredConfig.ts';\n\nconst DOMAINS_FILE = 'domains.yaml';\nconst UNKNOWN_DOMAIN_ERROR = 'Unknown domain';\nconst UNKNOWN_PLUGIN_ERROR = 'Unknown plugin';\nconst MISSING_PLUGIN_DIRECTORY_ERROR = 'Plugin directory does not exist';\nconst DEFAULT_DOMAINS_PATH = '.doom/domains.yaml';\nconst SUPPORTED_AGENT_PLUGIN_SCHEMA = 'https://agent-plugins.org/schemas/1.0.0/plugin.schema.json';\n\nfunction isRecord(value: unknown): value is Record<string, unknown> {\n return typeof value === 'object' && value !== null && !Array.isArray(value);\n}\n\nfunction requireRecord(value: unknown, label: string): Record<string, unknown> {\n if (!isRecord(value)) throw new Error(`${label} must be an object`);\n return value;\n}\n\nfunction assertOnlyKeys(record: Record<string, unknown>, allowed: readonly string[], label: string): void {\n const unexpected = Object.keys(record).filter((key) => !allowed.includes(key));\n if (unexpected.length > 0) throw new Error(`${label} contains unsupported field \"${unexpected[0]}\"`);\n}\n\nfunction requireString(value: unknown, label: string): string {\n if (typeof value !== 'string' || !value.trim()) throw new Error(`${label} must be a non-empty string`);\n return value.trim();\n}\n\nfunction optionalString(value: unknown, label: string): string | undefined {\n if (value === undefined) return undefined;\n return requireString(value, label);\n}\n\nfunction parseStringArray(value: unknown, label: string): string[] {\n if (!Array.isArray(value)) throw new Error(`${label} must be an array of non-empty strings`);\n return [...new Set(value.map((entry, index) => requireString(entry, `${label}[${index}]`)))];\n}\n\nfunction parseOptionalBoolean(value: unknown, label: string): boolean | undefined {\n if (value === undefined) return undefined;\n if (typeof value !== 'boolean') throw new Error(`${label} must be a boolean`);\n return value;\n}\n\nfunction parseDefaultDomains(value: unknown): string[] {\n return parseStringArray(value, `defaultDomains in ${DEFAULT_DOMAINS_PATH}`);\n}\n\nfunction parseDomainPlugin(value: unknown, label: string): DomainPlugin {\n if (typeof value === 'string') return requireString(value, label);\n const plugin = requireRecord(value, label);\n assertOnlyKeys(plugin, ['name', 'skills', 'agents', 'hooks', 'mcp'], label);\n const skills = plugin.skills === undefined ? undefined : parseStringArray(plugin.skills, `${label}.skills`);\n const agents = plugin.agents === undefined ? undefined : parseStringArray(plugin.agents, `${label}.agents`);\n const hooks = parseOptionalBoolean(plugin.hooks, `${label}.hooks`);\n const mcp = parseOptionalBoolean(plugin.mcp, `${label}.mcp`);\n return {\n name: requireString(plugin.name, `${label}.name`),\n ...(skills ? { skills } : {}),\n ...(agents ? { agents } : {}),\n ...(hooks === undefined ? {} : { hooks }),\n ...(mcp === undefined ? {} : { mcp }),\n };\n}\n\nfunction parseMcpAllowlist(value: unknown, label: string): DomainMcpAllowlist {\n const mcp = requireRecord(value, label);\n assertOnlyKeys(mcp, ['servers', 'proxy'], label);\n return {\n ...(mcp.servers === undefined ? {} : { servers: parseStringArray(mcp.servers, `${label}.servers`) }),\n ...(mcp.proxy === undefined ? {} : { proxy: parseStringArray(mcp.proxy, `${label}.proxy`) }),\n };\n}\n\nfunction parseDomain(value: unknown, label: string): DomainDefinition {\n const domain = requireRecord(value, label);\n assertOnlyKeys(domain, ['description', 'plugins', 'mcp', 'sharedSkills'], label);\n const description = optionalString(domain.description, `${label}.description`);\n if (domain.plugins !== undefined && !Array.isArray(domain.plugins)) {\n throw new Error(`${label}.plugins must be an array`);\n }\n const sharedSkills = parseOptionalBoolean(domain.sharedSkills, `${label}.sharedSkills`);\n return {\n ...(description ? { description } : {}),\n ...(Array.isArray(domain.plugins)\n ? { plugins: domain.plugins.map((plugin, index) => parseDomainPlugin(plugin, `${label}.plugins[${index}]`)) }\n : {}),\n ...(domain.mcp === undefined ? {} : { mcp: parseMcpAllowlist(domain.mcp, `${label}.mcp`) }),\n ...(sharedSkills === undefined ? {} : { sharedSkills }),\n };\n}\n\nfunction parseAliases(value: unknown, label: string): Record<string, string[]> {\n if (value === undefined) return {};\n const aliases = requireRecord(value, label);\n return Object.fromEntries(\n Object.entries(aliases).map(([name, domains]) => [name, parseStringArray(domains, `${label}.${name}`)]),\n );\n}\n\n/**\n * Reads domains and plugin catalogs from global and repository configs.\n *\n * Named domains and explicit plugin entries are replaced by later repository\n * definitions. Configured roots accumulate, with exact marketplace manifests\n * deduplicated in discovery order. Explicit entries override discovered IDs.\n */\nexport function loadDomains(repoRoot: string, homeDirectory: string = os.homedir()): DomainManifest {\n const sources = readDoomConfigSources<unknown>(DOMAINS_FILE, repoRoot, homeDirectory);\n const aliases: Record<string, string[]> = {};\n const domains: Record<string, ResolvedDomain> = {};\n let defaultDomains: string[] | undefined;\n\n for (const source of sources) {\n const document = requireRecord(source.document, source.filePath);\n assertOnlyKeys(document, ['plugins', 'domains', 'aliases', 'defaultDomains'], source.filePath);\n Object.assign(aliases, parseAliases(document.aliases, `aliases in ${source.filePath}`));\n if (document.domains !== undefined) {\n const sourceDomains = requireRecord(document.domains, `domains in ${source.filePath}`);\n for (const [name, definition] of Object.entries(sourceDomains)) {\n domains[name] = {\n ...parseDomain(definition, `domains.${name} in ${source.filePath}`),\n baseDirectory: source.baseDirectory,\n };\n }\n }\n if (Object.hasOwn(document, 'defaultDomains')) defaultDomains = parseDefaultDomains(document.defaultDomains);\n }\n\n const plugins = loadPluginCatalog(\n sources.map((source) => ({\n filePath: source.filePath,\n baseDirectory: source.baseDirectory,\n value: requireRecord(source.document, source.filePath).plugins,\n })),\n repoRoot,\n homeDirectory,\n );\n\n if (defaultDomains) {\n for (const name of expandDomainNames({ plugins, domains, aliases }, defaultDomains)) {\n if (!Object.hasOwn(domains, name)) {\n throw new Error(`Unknown default domain \"${name}\" in ${DEFAULT_DOMAINS_PATH}`);\n }\n }\n }\n return { plugins, domains, aliases, ...(defaultDomains ? { defaultDomains } : {}) };\n}\n\nexport function listDomainNames(repoRoot: string, homeDirectory?: string): string[] {\n const manifest = loadDomains(repoRoot, homeDirectory);\n return [...new Set([...Object.keys(manifest.domains), ...Object.keys(manifest.aliases)])].sort();\n}\n\n/**\n * Whether to include .claude/skills as shared fallbacks.\n *\n * Shared skills are included unless every selected domain opts out, so mixing a\n * trimmed domain with an untrimmed one cannot strip the untrimmed one's skills.\n */\nexport function resolveSharedSkills(repoRoot: string, domainNames: string[], homeDirectory?: string): boolean {\n const manifest = loadDomains(repoRoot, homeDirectory);\n const expanded = expandDomainNames(manifest, domainNames);\n if (expanded.length === 0) return true;\n return expanded.some((name) => manifest.domains[name]?.sharedSkills !== false);\n}\n\n/** Resolves named domain plugins while preserving each subset filter. */\nexport function resolvePluginEntries(\n repoRoot: string,\n domainNames: string[],\n explicitDirectories: string[],\n homeDirectory: string = os.homedir(),\n): PluginEntry[] {\n const manifest = loadDomains(repoRoot, homeDirectory);\n const entries: PluginEntry[] = [];\n const seen = new Set<string>();\n const homeDoomDirectory = globalDoomConfigDirectory(homeDirectory);\n\n for (const domainName of expandDomainNames(manifest, domainNames)) {\n const domain = manifest.domains[domainName];\n if (!domain) throw new Error(`${UNKNOWN_DOMAIN_ERROR}: ${domainName}`);\n for (const selection of domain.plugins ?? []) {\n const isSubset = typeof selection !== 'string';\n const pluginName = isSubset ? selection.name : selection;\n const plugin = manifest.plugins.entries[pluginName];\n if (!plugin) throw new Error(`${UNKNOWN_PLUGIN_ERROR} \"${pluginName}\" referenced by domain \"${domainName}\"`);\n const directory = pluginDirectoryForSource(plugin.source, homeDoomDirectory);\n if (plugin.source.type === 'local' && (!fs.existsSync(directory) || !fs.statSync(directory).isDirectory())) {\n throw new Error(`${MISSING_PLUGIN_DIRECTORY_ERROR}: ${directory}`);\n }\n if (seen.has(directory)) continue;\n seen.add(directory);\n entries.push({\n name: pluginName,\n directory,\n source: plugin.source,\n ...(plugin.manifest ? { manifest: plugin.manifest } : {}),\n ...(plugin.manifest?.agentPluginSchema === SUPPORTED_AGENT_PLUGIN_SCHEMA\n ? { skillDiscovery: 'direct-children' as const }\n : {}),\n ...(isSubset && selection.skills ? { skills: selection.skills } : {}),\n ...(isSubset && selection.agents ? { agents: selection.agents } : {}),\n ...(isSubset && selection.hooks !== undefined ? { hooks: selection.hooks } : {}),\n ...(isSubset && selection.mcp !== undefined ? { mcp: selection.mcp } : {}),\n });\n }\n }\n\n for (const configuredDirectory of explicitDirectories) {\n const directory = path.resolve(configuredDirectory);\n if (!fs.existsSync(directory) || !fs.statSync(directory).isDirectory()) {\n throw new Error(`${MISSING_PLUGIN_DIRECTORY_ERROR}: ${directory}`);\n }\n if (seen.has(directory)) continue;\n seen.add(directory);\n entries.push({\n name: path.basename(directory),\n directory,\n source: { type: 'local', path: directory },\n });\n }\n return entries;\n}\n\nexport function resolvePluginDirectories(\n repoRoot: string,\n domainNames: string[],\n explicitDirectories: string[],\n homeDirectory?: string,\n): string[] {\n return resolvePluginEntries(repoRoot, domainNames, explicitDirectories, homeDirectory).map(\n (entry) => entry.directory,\n );\n}\n\nexport const DOOMPI_DOMAINS_ENV = 'DOOMPI_DOMAINS';\nexport const DEFAULT_DOMAIN = 'default';\nconst MARKETING_MAJOR_MODE = 'marketing';\n\nfunction parseDomainList(value: string): string[] {\n return value\n .split(',')\n .map((entry) => entry.trim())\n .filter(Boolean);\n}\n\n/**\n * Domains selected when the caller names none.\n *\n * Configuration keeps this axis independent of the major mode. The\n * major-mode-derived choice is retained only as the compatibility fallback for\n * domains files that declare no defaultDomains.\n */\nexport function defaultDomainsForMajorMode(\n majorMode: string,\n environment: NodeJS.ProcessEnv,\n defaultDomains?: readonly string[],\n): string[] {\n const inherited = environment[DOOMPI_DOMAINS_ENV];\n // An explicitly empty variable means no domains, so this tests for the key\n // rather than for a truthy value.\n if (inherited !== undefined) return parseDomainList(inherited);\n if (defaultDomains !== undefined) return [...defaultDomains];\n return parseDomainList(majorMode === MARKETING_MAJOR_MODE ? MARKETING_MAJOR_MODE : DEFAULT_DOMAIN);\n}\n"],"mappings":"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"}
|
|
@@ -1,35 +0,0 @@
|
|
|
1
|
-
import { DomainManifest, PluginEntry } from "../types/domains.cjs";
|
|
2
|
-
import { DOOM_DIR } from "./layeredConfig.cjs";
|
|
3
|
-
//#region src/adapters/domains.d.ts
|
|
4
|
-
/**
|
|
5
|
-
* Reads domains and plugin catalogs from global and repository configs.
|
|
6
|
-
*
|
|
7
|
-
* Named domains and explicit plugin entries are replaced by later repository
|
|
8
|
-
* definitions. Configured roots accumulate, with exact marketplace manifests
|
|
9
|
-
* deduplicated in discovery order. Explicit entries override discovered IDs.
|
|
10
|
-
*/
|
|
11
|
-
declare function loadDomains(repoRoot: string, homeDirectory?: string): DomainManifest;
|
|
12
|
-
declare function listDomainNames(repoRoot: string, homeDirectory?: string): string[];
|
|
13
|
-
/**
|
|
14
|
-
* Whether to include .claude/skills as shared fallbacks.
|
|
15
|
-
*
|
|
16
|
-
* Shared skills are included unless every selected domain opts out, so mixing a
|
|
17
|
-
* trimmed domain with an untrimmed one cannot strip the untrimmed one's skills.
|
|
18
|
-
*/
|
|
19
|
-
declare function resolveSharedSkills(repoRoot: string, domainNames: string[], homeDirectory?: string): boolean;
|
|
20
|
-
/** Resolves named domain plugins while preserving each subset filter. */
|
|
21
|
-
declare function resolvePluginEntries(repoRoot: string, domainNames: string[], explicitDirectories: string[], homeDirectory?: string): PluginEntry[];
|
|
22
|
-
declare function resolvePluginDirectories(repoRoot: string, domainNames: string[], explicitDirectories: string[], homeDirectory?: string): string[];
|
|
23
|
-
declare const DOOMPI_DOMAINS_ENV = "DOOMPI_DOMAINS";
|
|
24
|
-
declare const DEFAULT_DOMAIN = "default";
|
|
25
|
-
/**
|
|
26
|
-
* Domains selected when the caller names none.
|
|
27
|
-
*
|
|
28
|
-
* Configuration keeps this axis independent of the major mode. The
|
|
29
|
-
* major-mode-derived choice is retained only as the compatibility fallback for
|
|
30
|
-
* domains files that declare no defaultDomains.
|
|
31
|
-
*/
|
|
32
|
-
declare function defaultDomainsForMajorMode(majorMode: string, environment: NodeJS.ProcessEnv, defaultDomains?: readonly string[]): string[];
|
|
33
|
-
//#endregion
|
|
34
|
-
export { DEFAULT_DOMAIN, DOOMPI_DOMAINS_ENV, DOOM_DIR, defaultDomainsForMajorMode, listDomainNames, loadDomains, resolvePluginDirectories, resolvePluginEntries, resolveSharedSkills };
|
|
35
|
-
//# sourceMappingURL=domains.d.cts.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"domains.d.cts","names":[],"sources":["../../src/adapters/domains.ts"],"mappings":";;;;;;;;;;iBA2HgB,YAAY,kBAAkB,yBAAuC;iBA0CrE,gBAAgB,kBAAkB;;;;;;;iBAWlC,oBAAoB,kBAAkB,uBAAuB;;iBAQ7D,qBACd,kBACA,uBACA,+BACA,yBACC;iBAoDa,yBACd,kBACA,uBACA,+BACA;cAOW;cACA;;;;;;;;iBAiBG,2BACd,mBACA,aAAa,OAAO,YACpB"}
|
|
@@ -1,35 +0,0 @@
|
|
|
1
|
-
import { DomainManifest, PluginEntry } from "../types/domains.mjs";
|
|
2
|
-
import { DOOM_DIR } from "./layeredConfig.mjs";
|
|
3
|
-
//#region src/adapters/domains.d.ts
|
|
4
|
-
/**
|
|
5
|
-
* Reads domains and plugin catalogs from global and repository configs.
|
|
6
|
-
*
|
|
7
|
-
* Named domains and explicit plugin entries are replaced by later repository
|
|
8
|
-
* definitions. Configured roots accumulate, with exact marketplace manifests
|
|
9
|
-
* deduplicated in discovery order. Explicit entries override discovered IDs.
|
|
10
|
-
*/
|
|
11
|
-
declare function loadDomains(repoRoot: string, homeDirectory?: string): DomainManifest;
|
|
12
|
-
declare function listDomainNames(repoRoot: string, homeDirectory?: string): string[];
|
|
13
|
-
/**
|
|
14
|
-
* Whether to include .claude/skills as shared fallbacks.
|
|
15
|
-
*
|
|
16
|
-
* Shared skills are included unless every selected domain opts out, so mixing a
|
|
17
|
-
* trimmed domain with an untrimmed one cannot strip the untrimmed one's skills.
|
|
18
|
-
*/
|
|
19
|
-
declare function resolveSharedSkills(repoRoot: string, domainNames: string[], homeDirectory?: string): boolean;
|
|
20
|
-
/** Resolves named domain plugins while preserving each subset filter. */
|
|
21
|
-
declare function resolvePluginEntries(repoRoot: string, domainNames: string[], explicitDirectories: string[], homeDirectory?: string): PluginEntry[];
|
|
22
|
-
declare function resolvePluginDirectories(repoRoot: string, domainNames: string[], explicitDirectories: string[], homeDirectory?: string): string[];
|
|
23
|
-
declare const DOOMPI_DOMAINS_ENV = "DOOMPI_DOMAINS";
|
|
24
|
-
declare const DEFAULT_DOMAIN = "default";
|
|
25
|
-
/**
|
|
26
|
-
* Domains selected when the caller names none.
|
|
27
|
-
*
|
|
28
|
-
* Configuration keeps this axis independent of the major mode. The
|
|
29
|
-
* major-mode-derived choice is retained only as the compatibility fallback for
|
|
30
|
-
* domains files that declare no defaultDomains.
|
|
31
|
-
*/
|
|
32
|
-
declare function defaultDomainsForMajorMode(majorMode: string, environment: NodeJS.ProcessEnv, defaultDomains?: readonly string[]): string[];
|
|
33
|
-
//#endregion
|
|
34
|
-
export { DEFAULT_DOMAIN, DOOMPI_DOMAINS_ENV, DOOM_DIR, defaultDomainsForMajorMode, listDomainNames, loadDomains, resolvePluginDirectories, resolvePluginEntries, resolveSharedSkills };
|
|
35
|
-
//# sourceMappingURL=domains.d.mts.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"domains.d.mts","names":[],"sources":["../../src/adapters/domains.ts"],"mappings":";;;;;;;;;;iBA2HgB,YAAY,kBAAkB,yBAAuC;iBA0CrE,gBAAgB,kBAAkB;;;;;;;iBAWlC,oBAAoB,kBAAkB,uBAAuB;;iBAQ7D,qBACd,kBACA,uBACA,+BACA,yBACC;iBAoDa,yBACd,kBACA,uBACA,+BACA;cAOW;cACA;;;;;;;;iBAiBG,2BACd,mBACA,aAAa,OAAO,YACpB"}
|
|
@@ -1,2 +0,0 @@
|
|
|
1
|
-
import{globalDoomConfigDirectory as e}from"./config.mjs";import{expandDomainNames as t}from"../services/domains.mjs";import{DOOM_DIR as n,readDoomConfigSources as r}from"./layeredConfig.mjs";import{loadPluginCatalog as i,pluginDirectoryForSource as a}from"./pluginCatalog.mjs";import o from"node:fs";import s from"node:path";import c from"node:os";const l=`Plugin directory does not exist`,u=`.doom/domains.yaml`;function d(e){return typeof e==`object`&&!!e&&!Array.isArray(e)}function f(e,t){if(!d(e))throw Error(`${t} must be an object`);return e}function p(e,t,n){let r=Object.keys(e).filter(e=>!t.includes(e));if(r.length>0)throw Error(`${n} contains unsupported field "${r[0]}"`)}function m(e,t){if(typeof e!=`string`||!e.trim())throw Error(`${t} must be a non-empty string`);return e.trim()}function h(e,t){if(e!==void 0)return m(e,t)}function g(e,t){if(!Array.isArray(e))throw Error(`${t} must be an array of non-empty strings`);return[...new Set(e.map((e,n)=>m(e,`${t}[${n}]`)))]}function _(e,t){if(e!==void 0){if(typeof e!=`boolean`)throw Error(`${t} must be a boolean`);return e}}function v(e){return g(e,`defaultDomains in ${u}`)}function y(e,t){if(typeof e==`string`)return m(e,t);let n=f(e,t);p(n,[`name`,`skills`,`agents`,`hooks`,`mcp`],t);let r=n.skills===void 0?void 0:g(n.skills,`${t}.skills`),i=n.agents===void 0?void 0:g(n.agents,`${t}.agents`),a=_(n.hooks,`${t}.hooks`),o=_(n.mcp,`${t}.mcp`);return{name:m(n.name,`${t}.name`),...r?{skills:r}:{},...i?{agents:i}:{},...a===void 0?{}:{hooks:a},...o===void 0?{}:{mcp:o}}}function b(e,t){let n=f(e,t);return p(n,[`servers`,`proxy`],t),{...n.servers===void 0?{}:{servers:g(n.servers,`${t}.servers`)},...n.proxy===void 0?{}:{proxy:g(n.proxy,`${t}.proxy`)}}}function x(e,t){let n=f(e,t);p(n,[`description`,`plugins`,`mcp`,`sharedSkills`],t);let r=h(n.description,`${t}.description`);if(n.plugins!==void 0&&!Array.isArray(n.plugins))throw Error(`${t}.plugins must be an array`);let i=_(n.sharedSkills,`${t}.sharedSkills`);return{...r?{description:r}:{},...Array.isArray(n.plugins)?{plugins:n.plugins.map((e,n)=>y(e,`${t}.plugins[${n}]`))}:{},...n.mcp===void 0?{}:{mcp:b(n.mcp,`${t}.mcp`)},...i===void 0?{}:{sharedSkills:i}}}function S(e,t){if(e===void 0)return{};let n=f(e,t);return Object.fromEntries(Object.entries(n).map(([e,n])=>[e,g(n,`${t}.${e}`)]))}function C(e,n=c.homedir()){let a=r(`domains.yaml`,e,n),o={},s={},l;for(let e of a){let t=f(e.document,e.filePath);if(p(t,[`plugins`,`domains`,`aliases`,`defaultDomains`],e.filePath),Object.assign(o,S(t.aliases,`aliases in ${e.filePath}`)),t.domains!==void 0){let n=f(t.domains,`domains in ${e.filePath}`);for(let[t,r]of Object.entries(n))s[t]={...x(r,`domains.${t} in ${e.filePath}`),baseDirectory:e.baseDirectory}}Object.hasOwn(t,`defaultDomains`)&&(l=v(t.defaultDomains))}let d=i(a.map(e=>({filePath:e.filePath,baseDirectory:e.baseDirectory,value:f(e.document,e.filePath).plugins})),e,n);if(l){for(let e of t({plugins:d,domains:s,aliases:o},l))if(!Object.hasOwn(s,e))throw Error(`Unknown default domain "${e}" in ${u}`)}return{plugins:d,domains:s,aliases:o,...l?{defaultDomains:l}:{}}}function w(e,t){let n=C(e,t);return[...new Set([...Object.keys(n.domains),...Object.keys(n.aliases)])].sort()}function T(e,n,r){let i=C(e,r),a=t(i,n);return a.length===0||a.some(e=>i.domains[e]?.sharedSkills!==!1)}function E(n,r,i,u=c.homedir()){let d=C(n,u),f=[],p=new Set,m=e(u);for(let e of t(d,r)){let t=d.domains[e];if(!t)throw Error(`Unknown domain: ${e}`);for(let n of t.plugins??[]){let t=typeof n!=`string`,r=t?n.name:n,i=d.plugins.entries[r];if(!i)throw Error(`Unknown plugin "${r}" referenced by domain "${e}"`);let s=a(i.source,m);if(i.source.type===`local`&&(!o.existsSync(s)||!o.statSync(s).isDirectory()))throw Error(`${l}: ${s}`);p.has(s)||(p.add(s),f.push({name:r,directory:s,source:i.source,...i.manifest?{manifest:i.manifest}:{},...i.manifest?.agentPluginSchema===`https://agent-plugins.org/schemas/1.0.0/plugin.schema.json`?{skillDiscovery:`direct-children`}:{},...t&&n.skills?{skills:n.skills}:{},...t&&n.agents?{agents:n.agents}:{},...t&&n.hooks!==void 0?{hooks:n.hooks}:{},...t&&n.mcp!==void 0?{mcp:n.mcp}:{}}))}}for(let e of i){let t=s.resolve(e);if(!o.existsSync(t)||!o.statSync(t).isDirectory())throw Error(`${l}: ${t}`);p.has(t)||(p.add(t),f.push({name:s.basename(t),directory:t,source:{type:`local`,path:t}}))}return f}function D(e,t,n,r){return E(e,t,n,r).map(e=>e.directory)}const O=`DOOMPI_DOMAINS`,k=`default`,A=`marketing`;function j(e){return e.split(`,`).map(e=>e.trim()).filter(Boolean)}function M(e,t,n){let r=t[O];return r===void 0?n===void 0?j(e===A?A:k):[...n]:j(r)}export{k as DEFAULT_DOMAIN,O as DOOMPI_DOMAINS_ENV,n as DOOM_DIR,M as defaultDomainsForMajorMode,w as listDomainNames,C as loadDomains,D as resolvePluginDirectories,E as resolvePluginEntries,T as resolveSharedSkills};
|
|
2
|
-
//# sourceMappingURL=domains.mjs.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"domains.mjs","names":[],"sources":["../../src/adapters/domains.ts"],"sourcesContent":["import fs from 'node:fs';\nimport os from 'node:os';\nimport path from 'node:path';\nimport { expandDomainNames } from '../services/domains.ts';\nimport type {\n DomainDefinition,\n DomainManifest,\n DomainMcpAllowlist,\n DomainPlugin,\n PluginEntry,\n ResolvedDomain,\n} from '../types/domains.ts';\nimport { globalDoomConfigDirectory } from './config.ts';\nimport { readDoomConfigSources } from './layeredConfig.ts';\nimport { loadPluginCatalog, pluginDirectoryForSource } from './pluginCatalog.ts';\n\nexport { DOOM_DIR } from './layeredConfig.ts';\n\nconst DOMAINS_FILE = 'domains.yaml';\nconst UNKNOWN_DOMAIN_ERROR = 'Unknown domain';\nconst UNKNOWN_PLUGIN_ERROR = 'Unknown plugin';\nconst MISSING_PLUGIN_DIRECTORY_ERROR = 'Plugin directory does not exist';\nconst DEFAULT_DOMAINS_PATH = '.doom/domains.yaml';\nconst SUPPORTED_AGENT_PLUGIN_SCHEMA = 'https://agent-plugins.org/schemas/1.0.0/plugin.schema.json';\n\nfunction isRecord(value: unknown): value is Record<string, unknown> {\n return typeof value === 'object' && value !== null && !Array.isArray(value);\n}\n\nfunction requireRecord(value: unknown, label: string): Record<string, unknown> {\n if (!isRecord(value)) throw new Error(`${label} must be an object`);\n return value;\n}\n\nfunction assertOnlyKeys(record: Record<string, unknown>, allowed: readonly string[], label: string): void {\n const unexpected = Object.keys(record).filter((key) => !allowed.includes(key));\n if (unexpected.length > 0) throw new Error(`${label} contains unsupported field \"${unexpected[0]}\"`);\n}\n\nfunction requireString(value: unknown, label: string): string {\n if (typeof value !== 'string' || !value.trim()) throw new Error(`${label} must be a non-empty string`);\n return value.trim();\n}\n\nfunction optionalString(value: unknown, label: string): string | undefined {\n if (value === undefined) return undefined;\n return requireString(value, label);\n}\n\nfunction parseStringArray(value: unknown, label: string): string[] {\n if (!Array.isArray(value)) throw new Error(`${label} must be an array of non-empty strings`);\n return [...new Set(value.map((entry, index) => requireString(entry, `${label}[${index}]`)))];\n}\n\nfunction parseOptionalBoolean(value: unknown, label: string): boolean | undefined {\n if (value === undefined) return undefined;\n if (typeof value !== 'boolean') throw new Error(`${label} must be a boolean`);\n return value;\n}\n\nfunction parseDefaultDomains(value: unknown): string[] {\n return parseStringArray(value, `defaultDomains in ${DEFAULT_DOMAINS_PATH}`);\n}\n\nfunction parseDomainPlugin(value: unknown, label: string): DomainPlugin {\n if (typeof value === 'string') return requireString(value, label);\n const plugin = requireRecord(value, label);\n assertOnlyKeys(plugin, ['name', 'skills', 'agents', 'hooks', 'mcp'], label);\n const skills = plugin.skills === undefined ? undefined : parseStringArray(plugin.skills, `${label}.skills`);\n const agents = plugin.agents === undefined ? undefined : parseStringArray(plugin.agents, `${label}.agents`);\n const hooks = parseOptionalBoolean(plugin.hooks, `${label}.hooks`);\n const mcp = parseOptionalBoolean(plugin.mcp, `${label}.mcp`);\n return {\n name: requireString(plugin.name, `${label}.name`),\n ...(skills ? { skills } : {}),\n ...(agents ? { agents } : {}),\n ...(hooks === undefined ? {} : { hooks }),\n ...(mcp === undefined ? {} : { mcp }),\n };\n}\n\nfunction parseMcpAllowlist(value: unknown, label: string): DomainMcpAllowlist {\n const mcp = requireRecord(value, label);\n assertOnlyKeys(mcp, ['servers', 'proxy'], label);\n return {\n ...(mcp.servers === undefined ? {} : { servers: parseStringArray(mcp.servers, `${label}.servers`) }),\n ...(mcp.proxy === undefined ? {} : { proxy: parseStringArray(mcp.proxy, `${label}.proxy`) }),\n };\n}\n\nfunction parseDomain(value: unknown, label: string): DomainDefinition {\n const domain = requireRecord(value, label);\n assertOnlyKeys(domain, ['description', 'plugins', 'mcp', 'sharedSkills'], label);\n const description = optionalString(domain.description, `${label}.description`);\n if (domain.plugins !== undefined && !Array.isArray(domain.plugins)) {\n throw new Error(`${label}.plugins must be an array`);\n }\n const sharedSkills = parseOptionalBoolean(domain.sharedSkills, `${label}.sharedSkills`);\n return {\n ...(description ? { description } : {}),\n ...(Array.isArray(domain.plugins)\n ? { plugins: domain.plugins.map((plugin, index) => parseDomainPlugin(plugin, `${label}.plugins[${index}]`)) }\n : {}),\n ...(domain.mcp === undefined ? {} : { mcp: parseMcpAllowlist(domain.mcp, `${label}.mcp`) }),\n ...(sharedSkills === undefined ? {} : { sharedSkills }),\n };\n}\n\nfunction parseAliases(value: unknown, label: string): Record<string, string[]> {\n if (value === undefined) return {};\n const aliases = requireRecord(value, label);\n return Object.fromEntries(\n Object.entries(aliases).map(([name, domains]) => [name, parseStringArray(domains, `${label}.${name}`)]),\n );\n}\n\n/**\n * Reads domains and plugin catalogs from global and repository configs.\n *\n * Named domains and explicit plugin entries are replaced by later repository\n * definitions. Configured roots accumulate, with exact marketplace manifests\n * deduplicated in discovery order. Explicit entries override discovered IDs.\n */\nexport function loadDomains(repoRoot: string, homeDirectory: string = os.homedir()): DomainManifest {\n const sources = readDoomConfigSources<unknown>(DOMAINS_FILE, repoRoot, homeDirectory);\n const aliases: Record<string, string[]> = {};\n const domains: Record<string, ResolvedDomain> = {};\n let defaultDomains: string[] | undefined;\n\n for (const source of sources) {\n const document = requireRecord(source.document, source.filePath);\n assertOnlyKeys(document, ['plugins', 'domains', 'aliases', 'defaultDomains'], source.filePath);\n Object.assign(aliases, parseAliases(document.aliases, `aliases in ${source.filePath}`));\n if (document.domains !== undefined) {\n const sourceDomains = requireRecord(document.domains, `domains in ${source.filePath}`);\n for (const [name, definition] of Object.entries(sourceDomains)) {\n domains[name] = {\n ...parseDomain(definition, `domains.${name} in ${source.filePath}`),\n baseDirectory: source.baseDirectory,\n };\n }\n }\n if (Object.hasOwn(document, 'defaultDomains')) defaultDomains = parseDefaultDomains(document.defaultDomains);\n }\n\n const plugins = loadPluginCatalog(\n sources.map((source) => ({\n filePath: source.filePath,\n baseDirectory: source.baseDirectory,\n value: requireRecord(source.document, source.filePath).plugins,\n })),\n repoRoot,\n homeDirectory,\n );\n\n if (defaultDomains) {\n for (const name of expandDomainNames({ plugins, domains, aliases }, defaultDomains)) {\n if (!Object.hasOwn(domains, name)) {\n throw new Error(`Unknown default domain \"${name}\" in ${DEFAULT_DOMAINS_PATH}`);\n }\n }\n }\n return { plugins, domains, aliases, ...(defaultDomains ? { defaultDomains } : {}) };\n}\n\nexport function listDomainNames(repoRoot: string, homeDirectory?: string): string[] {\n const manifest = loadDomains(repoRoot, homeDirectory);\n return [...new Set([...Object.keys(manifest.domains), ...Object.keys(manifest.aliases)])].sort();\n}\n\n/**\n * Whether to include .claude/skills as shared fallbacks.\n *\n * Shared skills are included unless every selected domain opts out, so mixing a\n * trimmed domain with an untrimmed one cannot strip the untrimmed one's skills.\n */\nexport function resolveSharedSkills(repoRoot: string, domainNames: string[], homeDirectory?: string): boolean {\n const manifest = loadDomains(repoRoot, homeDirectory);\n const expanded = expandDomainNames(manifest, domainNames);\n if (expanded.length === 0) return true;\n return expanded.some((name) => manifest.domains[name]?.sharedSkills !== false);\n}\n\n/** Resolves named domain plugins while preserving each subset filter. */\nexport function resolvePluginEntries(\n repoRoot: string,\n domainNames: string[],\n explicitDirectories: string[],\n homeDirectory: string = os.homedir(),\n): PluginEntry[] {\n const manifest = loadDomains(repoRoot, homeDirectory);\n const entries: PluginEntry[] = [];\n const seen = new Set<string>();\n const homeDoomDirectory = globalDoomConfigDirectory(homeDirectory);\n\n for (const domainName of expandDomainNames(manifest, domainNames)) {\n const domain = manifest.domains[domainName];\n if (!domain) throw new Error(`${UNKNOWN_DOMAIN_ERROR}: ${domainName}`);\n for (const selection of domain.plugins ?? []) {\n const isSubset = typeof selection !== 'string';\n const pluginName = isSubset ? selection.name : selection;\n const plugin = manifest.plugins.entries[pluginName];\n if (!plugin) throw new Error(`${UNKNOWN_PLUGIN_ERROR} \"${pluginName}\" referenced by domain \"${domainName}\"`);\n const directory = pluginDirectoryForSource(plugin.source, homeDoomDirectory);\n if (plugin.source.type === 'local' && (!fs.existsSync(directory) || !fs.statSync(directory).isDirectory())) {\n throw new Error(`${MISSING_PLUGIN_DIRECTORY_ERROR}: ${directory}`);\n }\n if (seen.has(directory)) continue;\n seen.add(directory);\n entries.push({\n name: pluginName,\n directory,\n source: plugin.source,\n ...(plugin.manifest ? { manifest: plugin.manifest } : {}),\n ...(plugin.manifest?.agentPluginSchema === SUPPORTED_AGENT_PLUGIN_SCHEMA\n ? { skillDiscovery: 'direct-children' as const }\n : {}),\n ...(isSubset && selection.skills ? { skills: selection.skills } : {}),\n ...(isSubset && selection.agents ? { agents: selection.agents } : {}),\n ...(isSubset && selection.hooks !== undefined ? { hooks: selection.hooks } : {}),\n ...(isSubset && selection.mcp !== undefined ? { mcp: selection.mcp } : {}),\n });\n }\n }\n\n for (const configuredDirectory of explicitDirectories) {\n const directory = path.resolve(configuredDirectory);\n if (!fs.existsSync(directory) || !fs.statSync(directory).isDirectory()) {\n throw new Error(`${MISSING_PLUGIN_DIRECTORY_ERROR}: ${directory}`);\n }\n if (seen.has(directory)) continue;\n seen.add(directory);\n entries.push({\n name: path.basename(directory),\n directory,\n source: { type: 'local', path: directory },\n });\n }\n return entries;\n}\n\nexport function resolvePluginDirectories(\n repoRoot: string,\n domainNames: string[],\n explicitDirectories: string[],\n homeDirectory?: string,\n): string[] {\n return resolvePluginEntries(repoRoot, domainNames, explicitDirectories, homeDirectory).map(\n (entry) => entry.directory,\n );\n}\n\nexport const DOOMPI_DOMAINS_ENV = 'DOOMPI_DOMAINS';\nexport const DEFAULT_DOMAIN = 'default';\nconst MARKETING_MAJOR_MODE = 'marketing';\n\nfunction parseDomainList(value: string): string[] {\n return value\n .split(',')\n .map((entry) => entry.trim())\n .filter(Boolean);\n}\n\n/**\n * Domains selected when the caller names none.\n *\n * Configuration keeps this axis independent of the major mode. The\n * major-mode-derived choice is retained only as the compatibility fallback for\n * domains files that declare no defaultDomains.\n */\nexport function defaultDomainsForMajorMode(\n majorMode: string,\n environment: NodeJS.ProcessEnv,\n defaultDomains?: readonly string[],\n): string[] {\n const inherited = environment[DOOMPI_DOMAINS_ENV];\n // An explicitly empty variable means no domains, so this tests for the key\n // rather than for a truthy value.\n if (inherited !== undefined) return parseDomainList(inherited);\n if (defaultDomains !== undefined) return [...defaultDomains];\n return parseDomainList(majorMode === MARKETING_MAJOR_MODE ? MARKETING_MAJOR_MODE : DEFAULT_DOMAIN);\n}\n"],"mappings":"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"}
|
|
@@ -1,2 +0,0 @@
|
|
|
1
|
-
const e=require("../_virtual/_rolldown/runtime.cjs");let t=require("node:path");t=e.__toESM(t,1);const n=new Set([`profileEnvironment`,`pluginHooks`,`mcpProjection`]),r={root:`DOOMPI_ROOT`,majorMode:`DOOMPI_MAJOR_MODE`,temporaryDirectory:`DOOMPI_TEMP_DIR`,domains:`DOOMPI_DOMAINS`,layers:`DOOMPI_LAYERS`,compositionFingerprint:`DOOMPI_COMPOSITION_FINGERPRINT`,profile:`DOOMPI_PROFILE`,profileEnvironment:`DOOMPI_PROFILE_ENV`,hookGroups:`DOOMPI_HOOK_GROUPS`,skillDirectories:`DOOMPI_SKILL_DIRS`,agentDirectories:`DOOMPI_AGENT_DIRS`,additionalDirectories:`DOOMPI_ADDITIONAL_DIRS`,childExtensions:`DOOMPI_CHILD_EXTENSIONS`,pluginDirectories:`DOOMPI_PLUGIN_DIRS`,pluginHooks:`DOOMPI_PLUGIN_HOOKS`,mcpConfigPath:`DOOMPI_MCP_CONFIG`,personaFile:`DOOMPI_PERSONA_FILE`,hooks:`DOOMPI_HOOKS_ENABLED`,agents:`DOOMPI_AGENTS_ENABLED`,mcp:`DOOMPI_MCP_ENABLED`,allowProtectedWrites:`DOOMPI_ALLOW_PROTECTED_WRITES`};function i(e){return e?.split(`,`).map(e=>e.trim()).filter(Boolean)??[]}function a(e){return e?.split(t.default.delimiter).map(e=>e.trim()).filter(Boolean)??[]}function o(e){return e!==`0`}function s(e,t,n){if(!e)return{};try{let t=JSON.parse(e);return typeof t!=`object`||!t||Array.isArray(t)?{}:Object.fromEntries(Object.entries(t).filter(e=>typeof e[1]==`string`))}catch(e){return n?.(t,e),{}}}function c(e,t,n){if(!e)return[];try{let t=JSON.parse(e);return Array.isArray(t)?t.filter(e=>typeof e==`string`):[]}catch(e){return n?.(t,e),[]}}function l(e,t,n){if(!e)return[];try{let t=JSON.parse(e);return Array.isArray(t)?t.filter(e=>typeof e==`object`&&!!e&&typeof e.pluginRoot==`string`&&typeof e.configPath==`string`):[]}catch(e){return n?.(t,e),[]}}function u(e=process.env,t){let n=r,u=e[n.hookGroups];return{root:e[n.root]||void 0,majorMode:e[n.majorMode]||`copilot`,temporaryDirectory:e[n.temporaryDirectory]||void 0,domains:i(e[n.domains]),layers:i(e[n.layers]),compositionFingerprint:e[n.compositionFingerprint]||void 0,profile:e[n.profile]||void 0,profileEnvironment:s(e[n.profileEnvironment],n.profileEnvironment,t),hookGroups:u===void 0?void 0:i(u),skillDirectories:a(e[n.skillDirectories]),agentDirectories:a(e[n.agentDirectories]),additionalDirectories:a(e[n.additionalDirectories]),childExtensions:c(e[n.childExtensions],n.childExtensions,t),pluginDirectories:a(e[n.pluginDirectories]),pluginHooks:l(e[n.pluginHooks],n.pluginHooks,t),mcpConfigPath:e[n.mcpConfigPath]||void 0,personaFile:e[n.personaFile]||void 0,hooks:o(e[n.hooks]),agents:o(e[n.agents]),mcp:o(e[n.mcp]),allowProtectedWrites:o(e[n.allowProtectedWrites])}}function d(e,n=process.env){let i=(e,t)=>{t===void 0?delete n[e]:n[e]=t},a=(e,t)=>i(e,t?`1`:`0`),o=r;return`root`in e&&i(o.root,e.root),`majorMode`in e&&i(o.majorMode,e.majorMode),`temporaryDirectory`in e&&i(o.temporaryDirectory,e.temporaryDirectory),`domains`in e&&i(o.domains,e.domains?.join(`,`)),`layers`in e&&i(o.layers,e.layers?.join(`,`)),`compositionFingerprint`in e&&i(o.compositionFingerprint,e.compositionFingerprint),`profile`in e&&i(o.profile,e.profile),`hookGroups`in e&&i(o.hookGroups,e.hookGroups?.join(`,`)),`skillDirectories`in e&&i(o.skillDirectories,e.skillDirectories?.join(t.default.delimiter)),`agentDirectories`in e&&i(o.agentDirectories,e.agentDirectories?.join(t.default.delimiter)),`additionalDirectories`in e&&i(o.additionalDirectories,e.additionalDirectories?.join(t.default.delimiter)),`childExtensions`in e&&i(o.childExtensions,JSON.stringify(e.childExtensions??[])),`pluginDirectories`in e&&i(o.pluginDirectories,e.pluginDirectories?.join(t.default.delimiter)),`mcpConfigPath`in e&&i(o.mcpConfigPath,e.mcpConfigPath),`personaFile`in e&&i(o.personaFile,e.personaFile),e.hooks!==void 0&&a(o.hooks,e.hooks),e.agents!==void 0&&a(o.agents,e.agents),e.mcp!==void 0&&a(o.mcp,e.mcp),e.allowProtectedWrites!==void 0&&a(o.allowProtectedWrites,e.allowProtectedWrites),n}exports.FILE_ONLY_STATE_FIELDS=n,exports.HARNESS_STATE_KEYS=r,exports.projectHarnessEnvironment=d,exports.readHarnessState=u;
|
|
2
|
-
//# sourceMappingURL=harnessState.cjs.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"harnessState.cjs","names":["path"],"sources":["../../src/adapters/harnessState.ts"],"sourcesContent":["import path from 'node:path';\nimport type { HarnessState, PluginHookSource } from '../types/config.ts';\n\n/**\n * The codec between harness state and the environment.\n *\n * Decoding exists for processes that were started without a state file: a\n * nested run, a third-party spawn, or anything older than the store. Encoding\n * exists because bash hooks, the shell launchers, and packages that do not\n * depend on this one can only read an environment. Ownership, persistence and\n * mutation belong to harnessStore.ts; nothing here touches disk or holds state.\n */\n\nconst DEFAULT_MAJOR_MODE = 'copilot';\nconst DISABLED_FLAG = '0';\n\n/**\n * State that lives in the file only.\n *\n * These are JSON documents that every spawned process and every hook would\n * otherwise copy in its environment. The plugin hook list and profile defaults\n * are read from the store, while Config publishes the MCP projection through\n * the session-scoped Cordis registry.\n */\nexport const FILE_ONLY_STATE_FIELDS: ReadonlySet<keyof HarnessState> = new Set([\n 'profileEnvironment',\n 'pluginHooks',\n 'mcpProjection',\n]);\n\nexport type HarnessStateParseReporter = (key: string, error: unknown) => void;\n\nexport const HARNESS_STATE_KEYS = {\n root: 'DOOMPI_ROOT',\n majorMode: 'DOOMPI_MAJOR_MODE',\n temporaryDirectory: 'DOOMPI_TEMP_DIR',\n domains: 'DOOMPI_DOMAINS',\n layers: 'DOOMPI_LAYERS',\n compositionFingerprint: 'DOOMPI_COMPOSITION_FINGERPRINT',\n profile: 'DOOMPI_PROFILE',\n profileEnvironment: 'DOOMPI_PROFILE_ENV',\n hookGroups: 'DOOMPI_HOOK_GROUPS',\n skillDirectories: 'DOOMPI_SKILL_DIRS',\n agentDirectories: 'DOOMPI_AGENT_DIRS',\n additionalDirectories: 'DOOMPI_ADDITIONAL_DIRS',\n childExtensions: 'DOOMPI_CHILD_EXTENSIONS',\n pluginDirectories: 'DOOMPI_PLUGIN_DIRS',\n pluginHooks: 'DOOMPI_PLUGIN_HOOKS',\n mcpConfigPath: 'DOOMPI_MCP_CONFIG',\n personaFile: 'DOOMPI_PERSONA_FILE',\n hooks: 'DOOMPI_HOOKS_ENABLED',\n agents: 'DOOMPI_AGENTS_ENABLED',\n mcp: 'DOOMPI_MCP_ENABLED',\n allowProtectedWrites: 'DOOMPI_ALLOW_PROTECTED_WRITES',\n} as const;\n\nfunction splitCsv(value: string | undefined): string[] {\n return (\n value\n ?.split(',')\n .map((item) => item.trim())\n .filter(Boolean) ?? []\n );\n}\n\nfunction splitPaths(value: string | undefined): string[] {\n return (\n value\n ?.split(path.delimiter)\n .map((item) => item.trim())\n .filter(Boolean) ?? []\n );\n}\n\nfunction parseFlag(value: string | undefined): boolean {\n return value !== DISABLED_FLAG;\n}\n\nfunction parseStringRecord(\n value: string | undefined,\n key: string,\n report?: HarnessStateParseReporter,\n): Record<string, string> {\n if (!value) return {};\n try {\n const parsed = JSON.parse(value) as unknown;\n if (typeof parsed !== 'object' || parsed === null || Array.isArray(parsed)) return {};\n return Object.fromEntries(\n Object.entries(parsed).filter((entry): entry is [string, string] => typeof entry[1] === 'string'),\n );\n } catch (error) {\n report?.(key, error);\n return {};\n }\n}\n\nfunction parseStringList(value: string | undefined, key: string, report?: HarnessStateParseReporter): string[] {\n if (!value) return [];\n try {\n const parsed = JSON.parse(value) as unknown;\n return Array.isArray(parsed) ? parsed.filter((item): item is string => typeof item === 'string') : [];\n } catch (error) {\n report?.(key, error);\n return [];\n }\n}\n\nfunction parsePluginHooks(\n value: string | undefined,\n key: string,\n report?: HarnessStateParseReporter,\n): PluginHookSource[] {\n if (!value) return [];\n try {\n const parsed = JSON.parse(value) as unknown;\n if (!Array.isArray(parsed)) return [];\n return parsed.filter(\n (item): item is PluginHookSource =>\n typeof item === 'object' &&\n item !== null &&\n typeof (item as PluginHookSource).pluginRoot === 'string' &&\n typeof (item as PluginHookSource).configPath === 'string',\n );\n } catch (error) {\n report?.(key, error);\n return [];\n }\n}\n\nexport function readHarnessState(\n environment: NodeJS.ProcessEnv = process.env,\n report?: HarnessStateParseReporter,\n): HarnessState {\n const keys = HARNESS_STATE_KEYS;\n const hookGroups = environment[keys.hookGroups];\n return {\n root: environment[keys.root] || undefined,\n majorMode: environment[keys.majorMode] || DEFAULT_MAJOR_MODE,\n temporaryDirectory: environment[keys.temporaryDirectory] || undefined,\n domains: splitCsv(environment[keys.domains]),\n layers: splitCsv(environment[keys.layers]),\n compositionFingerprint: environment[keys.compositionFingerprint] || undefined,\n profile: environment[keys.profile] || undefined,\n profileEnvironment: parseStringRecord(environment[keys.profileEnvironment], keys.profileEnvironment, report),\n hookGroups: hookGroups === undefined ? undefined : splitCsv(hookGroups),\n skillDirectories: splitPaths(environment[keys.skillDirectories]),\n agentDirectories: splitPaths(environment[keys.agentDirectories]),\n additionalDirectories: splitPaths(environment[keys.additionalDirectories]),\n childExtensions: parseStringList(environment[keys.childExtensions], keys.childExtensions, report),\n pluginDirectories: splitPaths(environment[keys.pluginDirectories]),\n pluginHooks: parsePluginHooks(environment[keys.pluginHooks], keys.pluginHooks, report),\n mcpConfigPath: environment[keys.mcpConfigPath] || undefined,\n personaFile: environment[keys.personaFile] || undefined,\n hooks: parseFlag(environment[keys.hooks]),\n agents: parseFlag(environment[keys.agents]),\n mcp: parseFlag(environment[keys.mcp]),\n allowProtectedWrites: parseFlag(environment[keys.allowProtectedWrites]),\n };\n}\n\n/**\n * Publishes a state patch into an environment.\n *\n * Takes the environment rather than assuming `process.env`, because the\n * launcher builds a child environment and Doom Team builds a spawn snapshot;\n * neither should mutate its own process to describe another one.\n *\n * Fields in FILE_ONLY_FIELDS are skipped: the file carries them, and a reader\n * that needs them reads the store.\n */\nexport function projectHarnessEnvironment(\n patch: Partial<HarnessState>,\n environment: NodeJS.ProcessEnv = process.env,\n): NodeJS.ProcessEnv {\n const assign = (key: string, value: string | undefined): void => {\n if (value === undefined) delete environment[key];\n else environment[key] = value;\n };\n const assignFlag = (key: string, value: boolean): void => assign(key, value ? '1' : DISABLED_FLAG);\n const keys = HARNESS_STATE_KEYS;\n\n if ('root' in patch) assign(keys.root, patch.root);\n if ('majorMode' in patch) assign(keys.majorMode, patch.majorMode);\n if ('temporaryDirectory' in patch) assign(keys.temporaryDirectory, patch.temporaryDirectory);\n if ('domains' in patch) assign(keys.domains, patch.domains?.join(','));\n if ('layers' in patch) assign(keys.layers, patch.layers?.join(','));\n if ('compositionFingerprint' in patch) assign(keys.compositionFingerprint, patch.compositionFingerprint);\n if ('profile' in patch) assign(keys.profile, patch.profile);\n if ('hookGroups' in patch) assign(keys.hookGroups, patch.hookGroups?.join(','));\n if ('skillDirectories' in patch) assign(keys.skillDirectories, patch.skillDirectories?.join(path.delimiter));\n if ('agentDirectories' in patch) assign(keys.agentDirectories, patch.agentDirectories?.join(path.delimiter));\n if ('additionalDirectories' in patch) {\n assign(keys.additionalDirectories, patch.additionalDirectories?.join(path.delimiter));\n }\n if ('childExtensions' in patch) assign(keys.childExtensions, JSON.stringify(patch.childExtensions ?? []));\n if ('pluginDirectories' in patch) assign(keys.pluginDirectories, patch.pluginDirectories?.join(path.delimiter));\n if ('mcpConfigPath' in patch) assign(keys.mcpConfigPath, patch.mcpConfigPath);\n if ('personaFile' in patch) assign(keys.personaFile, patch.personaFile);\n if (patch.hooks !== undefined) assignFlag(keys.hooks, patch.hooks);\n if (patch.agents !== undefined) assignFlag(keys.agents, patch.agents);\n if (patch.mcp !== undefined) assignFlag(keys.mcp, patch.mcp);\n if (patch.allowProtectedWrites !== undefined) assignFlag(keys.allowProtectedWrites, patch.allowProtectedWrites);\n return environment;\n}\n"],"mappings":"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"}
|