@agimon-ai/doompi-config 0.0.1-alpha.2 → 0.0.1-alpha.21
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +139 -14
- package/dist/adapters/atomicJson.cjs +2 -0
- package/dist/adapters/atomicJson.cjs.map +1 -0
- package/dist/adapters/atomicJson.d.cts +6 -0
- package/dist/adapters/atomicJson.d.cts.map +1 -0
- package/dist/adapters/atomicJson.d.mts +6 -0
- package/dist/adapters/atomicJson.d.mts.map +1 -0
- package/dist/adapters/atomicJson.mjs +2 -0
- package/dist/adapters/atomicJson.mjs.map +1 -0
- package/dist/adapters/config.cjs +2 -0
- package/dist/adapters/config.cjs.map +1 -0
- package/dist/adapters/config.d.cts +11 -0
- package/dist/adapters/config.d.cts.map +1 -0
- package/dist/adapters/config.d.mts +11 -0
- package/dist/adapters/config.d.mts.map +1 -0
- package/dist/adapters/config.mjs +2 -0
- package/dist/adapters/config.mjs.map +1 -0
- package/dist/adapters/configWriter.cjs +2 -0
- package/dist/adapters/configWriter.cjs.map +1 -0
- package/dist/adapters/configWriter.d.cts +52 -0
- package/dist/adapters/configWriter.d.cts.map +1 -0
- package/dist/adapters/configWriter.d.mts +52 -0
- package/dist/adapters/configWriter.d.mts.map +1 -0
- package/dist/adapters/configWriter.mjs +2 -0
- package/dist/adapters/configWriter.mjs.map +1 -0
- package/dist/adapters/domains.cjs +2 -0
- package/dist/adapters/domains.cjs.map +1 -0
- package/dist/adapters/domains.d.cts +25 -0
- package/dist/adapters/domains.d.cts.map +1 -0
- package/dist/adapters/domains.d.mts +25 -0
- package/dist/adapters/domains.d.mts.map +1 -0
- package/dist/adapters/domains.mjs +2 -0
- package/dist/adapters/domains.mjs.map +1 -0
- package/dist/adapters/harnessState.cjs +2 -0
- package/dist/adapters/harnessState.cjs.map +1 -0
- package/dist/adapters/harnessState.d.cts +50 -0
- package/dist/adapters/harnessState.d.cts.map +1 -0
- package/dist/adapters/harnessState.d.mts +50 -0
- package/dist/adapters/harnessState.d.mts.map +1 -0
- package/dist/adapters/harnessState.mjs +2 -0
- package/dist/adapters/harnessState.mjs.map +1 -0
- package/dist/adapters/harnessStore.cjs +2 -0
- package/dist/adapters/harnessStore.cjs.map +1 -0
- package/dist/adapters/harnessStore.d.cts +102 -0
- package/dist/adapters/harnessStore.d.cts.map +1 -0
- package/dist/adapters/harnessStore.d.mts +102 -0
- package/dist/adapters/harnessStore.d.mts.map +1 -0
- package/dist/adapters/harnessStore.mjs +2 -0
- package/dist/adapters/harnessStore.mjs.map +1 -0
- package/dist/adapters/init.cjs +178 -0
- package/dist/adapters/init.cjs.map +1 -0
- package/dist/adapters/init.d.cts +39 -0
- package/dist/adapters/init.d.cts.map +1 -0
- package/dist/adapters/init.d.mts +39 -0
- package/dist/adapters/init.d.mts.map +1 -0
- package/dist/adapters/init.mjs +178 -0
- package/dist/adapters/init.mjs.map +1 -0
- package/dist/adapters/layeredConfig.cjs +2 -0
- package/dist/adapters/layeredConfig.cjs.map +1 -0
- package/dist/adapters/layeredConfig.d.cts +49 -0
- package/dist/adapters/layeredConfig.d.cts.map +1 -0
- package/dist/adapters/layeredConfig.d.mts +49 -0
- package/dist/adapters/layeredConfig.d.mts.map +1 -0
- package/dist/adapters/layeredConfig.mjs +2 -0
- package/dist/adapters/layeredConfig.mjs.map +1 -0
- package/dist/adapters/majorModes.cjs +2 -0
- package/dist/adapters/majorModes.cjs.map +1 -0
- package/dist/adapters/majorModes.d.cts +88 -0
- package/dist/adapters/majorModes.d.cts.map +1 -0
- package/dist/adapters/majorModes.d.mts +88 -0
- package/dist/adapters/majorModes.d.mts.map +1 -0
- package/dist/adapters/majorModes.mjs +2 -0
- package/dist/adapters/majorModes.mjs.map +1 -0
- package/dist/adapters/pi/configExtension.cjs +2 -0
- package/dist/adapters/pi/configExtension.cjs.map +1 -0
- package/dist/adapters/pi/configExtension.d.cts +8 -0
- package/dist/adapters/pi/configExtension.d.cts.map +1 -0
- package/dist/adapters/pi/configExtension.d.mts +8 -0
- package/dist/adapters/pi/configExtension.d.mts.map +1 -0
- package/dist/adapters/pi/configExtension.mjs +2 -0
- package/dist/adapters/pi/configExtension.mjs.map +1 -0
- package/dist/adapters/pi/doomConfigExtension.cjs +2 -0
- package/dist/adapters/pi/doomConfigExtension.cjs.map +1 -0
- package/dist/adapters/pi/doomConfigExtension.d.cts +8 -0
- package/dist/adapters/pi/doomConfigExtension.d.cts.map +1 -0
- package/dist/adapters/pi/doomConfigExtension.d.mts +8 -0
- package/dist/adapters/pi/doomConfigExtension.d.mts.map +1 -0
- package/dist/adapters/pi/doomConfigExtension.mjs +2 -0
- package/dist/adapters/pi/doomConfigExtension.mjs.map +1 -0
- package/dist/adapters/pi/helpContribution.cjs +2 -0
- package/dist/adapters/pi/helpContribution.cjs.map +1 -0
- package/dist/adapters/pi/helpContribution.mjs +2 -0
- package/dist/adapters/pi/helpContribution.mjs.map +1 -0
- package/dist/adapters/pi/piContext.cjs +2 -0
- package/dist/adapters/pi/piContext.cjs.map +1 -0
- package/dist/adapters/pi/piContext.d.cts +20 -0
- package/dist/adapters/pi/piContext.d.cts.map +1 -0
- package/dist/adapters/pi/piContext.d.mts +20 -0
- package/dist/adapters/pi/piContext.d.mts.map +1 -0
- package/dist/adapters/pi/piContext.mjs +2 -0
- package/dist/adapters/pi/piContext.mjs.map +1 -0
- package/dist/adapters/piConfig.cjs +2 -0
- package/dist/adapters/piConfig.cjs.map +1 -0
- package/dist/adapters/piConfig.d.cts +8 -0
- package/dist/adapters/piConfig.d.cts.map +1 -0
- package/dist/adapters/piConfig.d.mts +8 -0
- package/dist/adapters/piConfig.d.mts.map +1 -0
- package/dist/adapters/piConfig.mjs +2 -0
- package/dist/adapters/piConfig.mjs.map +1 -0
- package/dist/adapters/pluginCatalog.cjs +2 -0
- package/dist/adapters/pluginCatalog.cjs.map +1 -0
- package/dist/adapters/pluginCatalog.d.cts +12 -0
- package/dist/adapters/pluginCatalog.d.cts.map +1 -0
- package/dist/adapters/pluginCatalog.d.mts +12 -0
- package/dist/adapters/pluginCatalog.d.mts.map +1 -0
- package/dist/adapters/pluginCatalog.mjs +2 -0
- package/dist/adapters/pluginCatalog.mjs.map +1 -0
- package/dist/adapters/profiles.cjs +4 -0
- package/dist/adapters/profiles.cjs.map +1 -0
- package/dist/adapters/profiles.d.cts +36 -0
- package/dist/adapters/profiles.d.cts.map +1 -0
- package/dist/adapters/profiles.d.mts +36 -0
- package/dist/adapters/profiles.d.mts.map +1 -0
- package/dist/adapters/profiles.mjs +4 -0
- package/dist/adapters/profiles.mjs.map +1 -0
- package/dist/atomicJson.cjs +1 -2
- package/dist/atomicJson.d.cts +2 -6
- package/dist/atomicJson.d.mts +2 -6
- package/dist/atomicJson.mjs +1 -2
- package/dist/config/piConfig.cjs +1 -2
- package/dist/config/piConfig.d.cts +2 -7
- package/dist/config/piConfig.d.mts +2 -7
- package/dist/config/piConfig.mjs +1 -2
- package/dist/config/schema.d.cts +2 -33
- package/dist/config/schema.d.mts +2 -33
- package/dist/config.cjs +1 -2
- package/dist/config.d.cts +3 -24
- package/dist/config.d.mts +3 -24
- package/dist/config.mjs +1 -2
- package/dist/configWriter.cjs +1 -2
- package/dist/configWriter.d.cts +2 -52
- package/dist/configWriter.d.mts +2 -52
- package/dist/configWriter.mjs +1 -2
- package/dist/container/doomConfigContainer.cjs +2 -0
- package/dist/container/doomConfigContainer.cjs.map +1 -0
- package/dist/container/doomConfigContainer.d.cts +12 -0
- package/dist/container/doomConfigContainer.d.cts.map +1 -0
- package/dist/container/doomConfigContainer.d.mts +12 -0
- package/dist/container/doomConfigContainer.d.mts.map +1 -0
- package/dist/container/doomConfigContainer.mjs +2 -0
- package/dist/container/doomConfigContainer.mjs.map +1 -0
- package/dist/container.cjs +1 -2
- package/dist/container.d.cts +2 -12
- package/dist/container.d.mts +2 -12
- package/dist/container.mjs +1 -2
- package/dist/domains.cjs +1 -2
- package/dist/domains.d.cts +6 -77
- package/dist/domains.d.mts +6 -77
- package/dist/domains.mjs +1 -2
- package/dist/extensions/doom.cjs +1 -2
- package/dist/extensions/doom.d.cts +2 -8
- package/dist/extensions/doom.d.mts +2 -8
- package/dist/extensions/doom.mjs +1 -2
- package/dist/extensions/pi.cjs +1 -2
- package/dist/extensions/pi.d.cts +2 -8
- package/dist/extensions/pi.d.mts +2 -8
- package/dist/extensions/pi.mjs +1 -2
- package/dist/harnessState.cjs +1 -2
- package/dist/harnessState.d.cts +2 -50
- package/dist/harnessState.d.mts +2 -50
- package/dist/harnessState.mjs +1 -2
- package/dist/harnessStore.cjs +1 -2
- package/dist/harnessStore.d.cts +2 -102
- package/dist/harnessStore.d.mts +2 -102
- package/dist/harnessStore.mjs +1 -2
- package/dist/index.cjs +1 -1
- package/dist/index.d.cts +20 -16
- package/dist/index.d.mts +20 -16
- package/dist/index.mjs +1 -1
- package/dist/init.cjs +1 -76
- package/dist/init.d.cts +2 -33
- package/dist/init.d.mts +2 -33
- package/dist/init.mjs +1 -76
- package/dist/layeredConfig.cjs +1 -2
- package/dist/layeredConfig.d.cts +2 -49
- package/dist/layeredConfig.d.mts +2 -49
- package/dist/layeredConfig.mjs +1 -2
- package/dist/majorModes.cjs +1 -2
- package/dist/majorModes.d.cts +2 -75
- package/dist/majorModes.d.mts +2 -75
- package/dist/majorModes.mjs +1 -2
- package/dist/pi.cjs +1 -1
- package/dist/pi.d.cts +1 -1
- package/dist/pi.d.mts +1 -1
- package/dist/pi.mjs +1 -1
- package/dist/piContext.cjs +1 -2
- package/dist/piContext.d.cts +2 -19
- package/dist/piContext.d.mts +2 -19
- package/dist/piContext.mjs +1 -2
- package/dist/profiles.cjs +1 -4
- package/dist/profiles.d.cts +2 -35
- package/dist/profiles.d.mts +2 -35
- package/dist/profiles.mjs +1 -4
- package/dist/schemas/config/schema.d.cts +33 -0
- package/dist/schemas/config/schema.d.cts.map +1 -0
- package/dist/schemas/config/schema.d.mts +33 -0
- package/dist/schemas/config/schema.d.mts.map +1 -0
- package/dist/services/configPolicy.cjs +2 -0
- package/dist/services/configPolicy.cjs.map +1 -0
- package/dist/services/configPolicy.d.cts +19 -0
- package/dist/services/configPolicy.d.cts.map +1 -0
- package/dist/services/configPolicy.d.mts +19 -0
- package/dist/services/configPolicy.d.mts.map +1 -0
- package/dist/services/configPolicy.mjs +2 -0
- package/dist/services/configPolicy.mjs.map +1 -0
- package/dist/services/domains.cjs +2 -0
- package/dist/services/domains.cjs.map +1 -0
- package/dist/services/domains.d.cts +12 -0
- package/dist/services/domains.d.cts.map +1 -0
- package/dist/services/domains.d.mts +12 -0
- package/dist/services/domains.d.mts.map +1 -0
- package/dist/services/domains.mjs +2 -0
- package/dist/services/domains.mjs.map +1 -0
- package/dist/types/config.cjs +2 -0
- package/dist/types/config.cjs.map +1 -0
- package/dist/types/config.d.cts +136 -0
- package/dist/types/config.d.cts.map +1 -0
- package/dist/types/config.d.mts +136 -0
- package/dist/types/config.d.mts.map +1 -0
- package/dist/types/config.mjs +2 -0
- package/dist/types/config.mjs.map +1 -0
- package/dist/types/domains.d.cts +89 -0
- package/dist/types/domains.d.cts.map +1 -0
- package/dist/types/domains.d.mts +89 -0
- package/dist/types/domains.d.mts.map +1 -0
- package/dist/types.cjs +1 -2
- package/dist/types.d.cts +2 -132
- package/dist/types.d.mts +2 -132
- package/dist/types.mjs +1 -2
- package/llms.txt +9 -0
- package/package.json +18 -6
- package/skills/doom-pi-config/SKILL.md +6 -3
- package/skills/doom-pi-config/references/config-contract.md +123 -8
- package/dist/atomicJson.cjs.map +0 -1
- package/dist/atomicJson.d.cts.map +0 -1
- package/dist/atomicJson.d.mts.map +0 -1
- package/dist/atomicJson.mjs.map +0 -1
- package/dist/config/piConfig.cjs.map +0 -1
- package/dist/config/piConfig.d.cts.map +0 -1
- package/dist/config/piConfig.d.mts.map +0 -1
- package/dist/config/piConfig.mjs.map +0 -1
- package/dist/config/schema.d.cts.map +0 -1
- package/dist/config/schema.d.mts.map +0 -1
- package/dist/config.cjs.map +0 -1
- package/dist/config.d.cts.map +0 -1
- package/dist/config.d.mts.map +0 -1
- package/dist/config.mjs.map +0 -1
- package/dist/configWriter.cjs.map +0 -1
- package/dist/configWriter.d.cts.map +0 -1
- package/dist/configWriter.d.mts.map +0 -1
- package/dist/configWriter.mjs.map +0 -1
- package/dist/container.cjs.map +0 -1
- package/dist/container.d.cts.map +0 -1
- package/dist/container.d.mts.map +0 -1
- package/dist/container.mjs.map +0 -1
- package/dist/domains.cjs.map +0 -1
- package/dist/domains.d.cts.map +0 -1
- package/dist/domains.d.mts.map +0 -1
- package/dist/domains.mjs.map +0 -1
- package/dist/extensions/doom.cjs.map +0 -1
- package/dist/extensions/doom.d.cts.map +0 -1
- package/dist/extensions/doom.d.mts.map +0 -1
- package/dist/extensions/doom.mjs.map +0 -1
- package/dist/extensions/pi.cjs.map +0 -1
- package/dist/extensions/pi.d.cts.map +0 -1
- package/dist/extensions/pi.d.mts.map +0 -1
- package/dist/extensions/pi.mjs.map +0 -1
- package/dist/harnessState.cjs.map +0 -1
- package/dist/harnessState.d.cts.map +0 -1
- package/dist/harnessState.d.mts.map +0 -1
- package/dist/harnessState.mjs.map +0 -1
- package/dist/harnessStore.cjs.map +0 -1
- package/dist/harnessStore.d.cts.map +0 -1
- package/dist/harnessStore.d.mts.map +0 -1
- package/dist/harnessStore.mjs.map +0 -1
- package/dist/init.cjs.map +0 -1
- package/dist/init.d.cts.map +0 -1
- package/dist/init.d.mts.map +0 -1
- package/dist/init.mjs.map +0 -1
- package/dist/layeredConfig.cjs.map +0 -1
- package/dist/layeredConfig.d.cts.map +0 -1
- package/dist/layeredConfig.d.mts.map +0 -1
- package/dist/layeredConfig.mjs.map +0 -1
- package/dist/majorModes.cjs.map +0 -1
- package/dist/majorModes.d.cts.map +0 -1
- package/dist/majorModes.d.mts.map +0 -1
- package/dist/majorModes.mjs.map +0 -1
- package/dist/piContext.cjs.map +0 -1
- package/dist/piContext.d.cts.map +0 -1
- package/dist/piContext.d.mts.map +0 -1
- package/dist/piContext.mjs.map +0 -1
- package/dist/profiles.cjs.map +0 -1
- package/dist/profiles.d.cts.map +0 -1
- package/dist/profiles.d.mts.map +0 -1
- package/dist/profiles.mjs.map +0 -1
- package/dist/types.cjs.map +0 -1
- package/dist/types.d.cts.map +0 -1
- package/dist/types.d.mts.map +0 -1
- package/dist/types.mjs.map +0 -1
|
@@ -0,0 +1,49 @@
|
|
|
1
|
+
//#region src/adapters/layeredConfig.d.ts
|
|
2
|
+
/** Repository-local doom-pi configuration directory, committed to git. */
|
|
3
|
+
declare const DOOM_DIR = ".doom";
|
|
4
|
+
/** One `.doom` document plus the root its relative paths resolve against. */
|
|
5
|
+
interface DoomConfigSource<TDocument> {
|
|
6
|
+
/** Absolute path of the file the document was read from. */
|
|
7
|
+
filePath: string;
|
|
8
|
+
/**
|
|
9
|
+
* Where relative paths inside this document point.
|
|
10
|
+
*
|
|
11
|
+
* A repository document resolves against the repository root, so `plugins/x`
|
|
12
|
+
* keeps meaning the same thing it always has. A global document resolves
|
|
13
|
+
* against the global `.doom` directory, so it can name plugins and extensions
|
|
14
|
+
* that live beside it in `~/.pi/.doom` rather than inside whichever
|
|
15
|
+
* repository happens to be open.
|
|
16
|
+
*/
|
|
17
|
+
baseDirectory: string;
|
|
18
|
+
/** Raw file contents, for callers that cache parsed results by source text. */
|
|
19
|
+
text: string;
|
|
20
|
+
document: TDocument;
|
|
21
|
+
}
|
|
22
|
+
/**
|
|
23
|
+
* Reads one named `.doom` document from the global and repository config
|
|
24
|
+
* directories, lowest precedence first.
|
|
25
|
+
*
|
|
26
|
+
* A missing or empty file contributes nothing, so either location on its own is
|
|
27
|
+
* a complete configuration. Documents are deliberately returned unmerged:
|
|
28
|
+
* merging is by name, and only the caller knows what a name means in its own
|
|
29
|
+
* document, so each one folds the sources itself with the repository last.
|
|
30
|
+
*/
|
|
31
|
+
declare function doomConfigCandidates(fileName: string, repoRoot: string, homeDirectory?: string): Array<{
|
|
32
|
+
filePath: string;
|
|
33
|
+
baseDirectory: string;
|
|
34
|
+
}>;
|
|
35
|
+
declare function readDoomConfigSources<TDocument>(fileName: string, repoRoot: string, homeDirectory?: string): Array<DoomConfigSource<TDocument>>;
|
|
36
|
+
/**
|
|
37
|
+
* Merges same-named records across sources, tagging each entry with the base
|
|
38
|
+
* directory of the document that supplied it.
|
|
39
|
+
*
|
|
40
|
+
* Later sources win outright rather than being deep-merged: a repository that
|
|
41
|
+
* redefines a name is replacing it, and a half-inherited definition whose paths
|
|
42
|
+
* straddle two roots would be impossible to resolve.
|
|
43
|
+
*/
|
|
44
|
+
declare function mergeNamedSources<TDocument, TEntry>(sources: ReadonlyArray<DoomConfigSource<TDocument>>, select: (document: TDocument) => Record<string, TEntry> | undefined): Record<string, TEntry & {
|
|
45
|
+
baseDirectory: string;
|
|
46
|
+
}>;
|
|
47
|
+
//#endregion
|
|
48
|
+
export { DOOM_DIR, DoomConfigSource, doomConfigCandidates, mergeNamedSources, readDoomConfigSources };
|
|
49
|
+
//# sourceMappingURL=layeredConfig.d.mts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"layeredConfig.d.mts","names":[],"sources":["../../src/adapters/layeredConfig.ts"],"mappings":";;cAOa;;UAKI,iBAAiB;;EAEhC;;;;;;;;;;EAUA;;EAEA;EACA,UAAU;;;;;;;;;;;iBAYI,qBACd,kBACA,kBACA,yBACC;EAAQ;EAAkB;;iBAQb,sBAAsB,WACpC,kBACA,kBACA,yBACC,MAAM,iBAAiB;;;;;;;;;iBAwBV,kBAAkB,WAAW,QAC3C,SAAS,cAAc,iBAAiB,aACxC,SAAS,UAAU,cAAc,eAAe,sBAC/C,eAAe;EAAW"}
|
|
@@ -0,0 +1,2 @@
|
|
|
1
|
+
import{globalDoomConfigDirectory as e}from"./config.mjs";import t from"node:fs";import n from"node:path";import r from"node:os";import{parse as i}from"yaml";const a=`.doom`;function o(t,i,o=r.homedir()){let s=e(o);return[{filePath:n.join(s,t),baseDirectory:s},{filePath:n.join(i,a,t),baseDirectory:i}]}function s(e,n,a=r.homedir()){let s=o(e,n,a),c=[];for(let e of s){if(!t.existsSync(e.filePath))continue;let n=t.readFileSync(e.filePath,`utf8`),r=i(n);r!=null&&c.push({...e,text:n,document:r})}return c}function c(e,t){let n={};for(let r of e)for(let[e,i]of Object.entries(t(r.document)??{}))n[e]={...i,baseDirectory:r.baseDirectory};return n}export{a as DOOM_DIR,o as doomConfigCandidates,c as mergeNamedSources,s as readDoomConfigSources};
|
|
2
|
+
//# sourceMappingURL=layeredConfig.mjs.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"layeredConfig.mjs","names":["parseYaml"],"sources":["../../src/adapters/layeredConfig.ts"],"sourcesContent":["import fs from 'node:fs';\nimport os from 'node:os';\nimport path from 'node:path';\nimport { parse as parseYaml } from 'yaml';\nimport { globalDoomConfigDirectory } from './config.ts';\n\n/** Repository-local doom-pi configuration directory, committed to git. */\nexport const DOOM_DIR = '.doom';\n\nconst TEXT_ENCODING = 'utf8';\n\n/** One `.doom` document plus the root its relative paths resolve against. */\nexport interface DoomConfigSource<TDocument> {\n /** Absolute path of the file the document was read from. */\n filePath: string;\n /**\n * Where relative paths inside this document point.\n *\n * A repository document resolves against the repository root, so `plugins/x`\n * keeps meaning the same thing it always has. A global document resolves\n * against the global `.doom` directory, so it can name plugins and extensions\n * that live beside it in `~/.pi/.doom` rather than inside whichever\n * repository happens to be open.\n */\n baseDirectory: string;\n /** Raw file contents, for callers that cache parsed results by source text. */\n text: string;\n document: TDocument;\n}\n\n/**\n * Reads one named `.doom` document from the global and repository config\n * directories, lowest precedence first.\n *\n * A missing or empty file contributes nothing, so either location on its own is\n * a complete configuration. Documents are deliberately returned unmerged:\n * merging is by name, and only the caller knows what a name means in its own\n * document, so each one folds the sources itself with the repository last.\n */\nexport function doomConfigCandidates(\n fileName: string,\n repoRoot: string,\n homeDirectory: string = os.homedir(),\n): Array<{ filePath: string; baseDirectory: string }> {\n const globalDirectory = globalDoomConfigDirectory(homeDirectory);\n return [\n { filePath: path.join(globalDirectory, fileName), baseDirectory: globalDirectory },\n { filePath: path.join(repoRoot, DOOM_DIR, fileName), baseDirectory: repoRoot },\n ];\n}\n\nexport function readDoomConfigSources<TDocument>(\n fileName: string,\n repoRoot: string,\n homeDirectory: string = os.homedir(),\n): Array<DoomConfigSource<TDocument>> {\n const candidates = doomConfigCandidates(fileName, repoRoot, homeDirectory);\n\n const sources: Array<DoomConfigSource<TDocument>> = [];\n for (const candidate of candidates) {\n if (!fs.existsSync(candidate.filePath)) continue;\n const text = fs.readFileSync(candidate.filePath, TEXT_ENCODING);\n const document = parseYaml(text) as TDocument | null | undefined;\n // An empty file parses to null and is treated as an absent one, so a seeded\n // placeholder never has to be deleted to get out of the way.\n if (document === null || document === undefined) continue;\n sources.push({ ...candidate, text, document });\n }\n return sources;\n}\n\n/**\n * Merges same-named records across sources, tagging each entry with the base\n * directory of the document that supplied it.\n *\n * Later sources win outright rather than being deep-merged: a repository that\n * redefines a name is replacing it, and a half-inherited definition whose paths\n * straddle two roots would be impossible to resolve.\n */\nexport function mergeNamedSources<TDocument, TEntry>(\n sources: ReadonlyArray<DoomConfigSource<TDocument>>,\n select: (document: TDocument) => Record<string, TEntry> | undefined,\n): Record<string, TEntry & { baseDirectory: string }> {\n const merged: Record<string, TEntry & { baseDirectory: string }> = {};\n for (const source of sources) {\n for (const [name, entry] of Object.entries(select(source.document) ?? {})) {\n merged[name] = { ...entry, baseDirectory: source.baseDirectory };\n }\n }\n return merged;\n}\n"],"mappings":"6JAOA,MAAa,EAAW,QAgCxB,SAAgB,EACd,EACA,EACA,EAAwB,EAAG,QAAQ,EACiB,CACpD,IAAM,EAAkB,EAA0B,CAAa,EAC/D,MAAO,CACL,CAAE,SAAU,EAAK,KAAK,EAAiB,CAAQ,EAAG,cAAe,CAAgB,EACjF,CAAE,SAAU,EAAK,KAAK,EAAU,EAAU,CAAQ,EAAG,cAAe,CAAS,CAC/E,CACF,CAEA,SAAgB,EACd,EACA,EACA,EAAwB,EAAG,QAAQ,EACC,CACpC,IAAM,EAAa,EAAqB,EAAU,EAAU,CAAa,EAEnE,EAA8C,CAAC,EACrD,IAAK,IAAM,KAAa,EAAY,CAClC,GAAI,CAAC,EAAG,WAAW,EAAU,QAAQ,EAAG,SACxC,IAAM,EAAO,EAAG,aAAa,EAAU,SAAU,MAAa,EACxD,EAAWA,EAAU,CAAI,EAG3B,GAAa,MACjB,EAAQ,KAAK,CAAE,GAAG,EAAW,OAAM,UAAS,CAAC,CAC/C,CACA,OAAO,CACT,CAUA,SAAgB,EACd,EACA,EACoD,CACpD,IAAM,EAA6D,CAAC,EACpE,IAAK,IAAM,KAAU,EACnB,IAAK,GAAM,CAAC,EAAM,KAAU,OAAO,QAAQ,EAAO,EAAO,QAAQ,GAAK,CAAC,CAAC,EACtE,EAAO,GAAQ,CAAE,GAAG,EAAO,cAAe,EAAO,aAAc,EAGnE,OAAO,CACT"}
|
|
@@ -0,0 +1,2 @@
|
|
|
1
|
+
const e=require("../_virtual/_rolldown/runtime.cjs"),t=require("./layeredConfig.cjs");let n=require("node:path");n=e.__toESM(n,1);let r=require("node:os");r=e.__toESM(r,1);const i=`modes.yaml`,a=n.default.join(t.DOOM_DIR,i),o=[`./`,`../`];function s(e){return n.default.isAbsolute(e)||o.some(t=>e.startsWith(t))}const c=[`name`,`optional`,`config`],l=[`description`,`layers`];function u(e){return typeof e==`object`&&!!e&&!Array.isArray(e)}function d(e,t,n){let r=Object.keys(e).filter(e=>!t.includes(e));if(r.length>0)throw Error(`${n} has unsupported field(s): ${r.join(`, `)}`)}function f(e,t,n){let r=`Layer "${e}" package[${n}] in ${a}`;if(typeof t==`string`){if(!t.trim())throw Error(`${r} must be a non-empty string or mapping`);return t.trim()}if(!u(t))throw Error(`${r} must be a non-empty string or mapping`);if(d(t,c,r),typeof t.name!=`string`||!t.name.trim())throw Error(`${r}.name must be a non-empty string`);if(t.optional!==void 0&&typeof t.optional!=`boolean`)throw Error(`${r}.optional must be a boolean`);if(t.config!==void 0&&!u(t.config))throw Error(`${r}.config must be a mapping`);return{name:t.name.trim(),...t.optional===!0?{optional:!0}:{},...t.config?{config:{...t.config}}:{}}}function p(e,t){if(t===void 0)return;let n=`Layer "${e}" extensions in ${a}`;if(!Array.isArray(t))throw Error(`${n} must be an array`);return t.map((e,t)=>{if(typeof e!=`string`||!e.trim())throw Error(`${n}[${t}] must be a non-empty string`);return e.trim()})}function m(e,t){if(t!==void 0){if(!Array.isArray(t))throw Error(`Layer "${e}" packages in ${a} must be an array`);return t.map((t,n)=>f(e,t,n))}}function h(e){if(typeof e!=`string`||!e.trim())throw Error(`defaultMajorMode in ${a} must be a non-empty string`);return e.trim()}function g(e,t){let n=`Major mode "${e}" layers in ${a}`;if(!Array.isArray(t))throw Error(`${n} must be an array`);return t.map((e,t)=>{if(typeof e!=`string`||!e.trim())throw Error(`${n}[${t}] must be a non-empty string`);return e.trim()})}function _(e){return e.length>0?`Uses layers: ${e.join(`, `)}.`:`Uses Doom Pi core extensions only.`}function v(e,t){if(Array.isArray(t)){let n=g(e,t);return{description:_(n),layers:n}}let n=`Major mode "${e}" in ${a}`;if(!u(t))throw Error(`${n} must be a mapping with description and layers`);if(d(t,l,n),typeof t.description!=`string`||!t.description.trim())throw Error(`${n}.description must be a non-empty string`);return{description:t.description.trim(),layers:g(e,t.layers)}}function y(e){if(e===void 0)return{};if(!u(e))throw Error(`majorMode in ${a} must be a mapping`);return Object.fromEntries(Object.entries(e).map(([e,t])=>[e,v(e,t)]))}function b(e,t){if(!u(t))throw Error(`Layer "${e}" in ${a} must be a mapping`);if(`targets`in t)throw Error(`Layer "${e}" in ${a} uses removed field "targets"; select availability through major modes`);if(`config`in t)throw Error(`Layer "${e}" in ${a} uses unsupported field "config"; move it under the package entry that owns it`);let n=p(e,t.extensions),r=m(e,t.packages);return{...t,...n===void 0?{}:{extensions:n},...r===void 0?{}:{packages:r}}}function x(e,n=r.default.homedir()){let o=t.readDoomConfigSources(i,e,n),s={},c={},l=`copilot`,u=!1;for(let e of o){for(let[t,n]of Object.entries(e.document.layers??{}))s[t]={...b(t,n),baseDirectory:e.baseDirectory};Object.hasOwn(e.document,`defaultMajorMode`)&&(l=h(e.document.defaultMajorMode),u=!0),Object.assign(c,y(e.document.majorMode))}for(let[e,t]of Object.entries(c))for(let n of t.layers)if(!s[n])throw Error(`Unknown layer "${n}" in majorMode.${e} of ${a}`);if(u&&!Object.hasOwn(c,l))throw Error(`Unknown default major mode "${l}" in ${a}`);return{layers:s,defaultMajorMode:l,majorMode:c}}function S(e,t,n){let r=n.trim();if(!r)throw Error(`Package name must be a non-empty string`);let i=[];for(let n of t){let t=e.layers[n];if(!t)throw Error(`Unknown layer: ${n}`);for(let e of t.packages??[])typeof e!=`string`&&e.config!==void 0&&(e.name!==r&&!e.name.startsWith(`${r}/`)||i.push({layer:n,specifier:e.name,config:{...e.config}}))}return i}function C(e,t){if(!Object.hasOwn(e.majorMode,t))throw Error(`Unknown major mode: ${t}. Known major modes: ${Object.keys(e.majorMode).sort().join(`, `)}`);return[...e.majorMode[t].layers]}function w(e,t,n){let r=e.localEntries?.(t,n);if(r!==void 0)return r;let i=e.localEntry(t,n);return i?[i]:void 0}function T(e,t,n){let r=e.layers[t];if(!r)throw Error(`Unknown layer: ${t}`);let i=[];for(let e of r.extensions??[]){if(!s(e)){i.push(n.ownEntry(e));continue}let a=w(n,e,r.baseDirectory);if(!a?.length)throw Error(`Layer "${t}" extension "${e}" does not resolve under ${r.baseDirectory}. Point it at a Pi extension file or directory.`);i.push(...a)}for(let e of r.packages??[]){let a=typeof e==`string`?e:e.name,o=typeof e!=`string`&&e.optional===!0;if(s(a)){let e=w(n,a,r.baseDirectory);if(e?.length)i.push(...e);else if(!o)throw Error(`Layer "${t}" package "${a}" does not resolve under ${r.baseDirectory}. Point it at an extension file, or a directory whose package.json declares pi.extensions.`);continue}if(o){let e=n.optionalPackageEntries?.(a);if(e===void 0){let t=n.optionalPackageEntry(a);e=t?[t]:void 0}e&&i.push(...e);continue}let c=n.packageEntries?.(a)??[n.packageEntry(a)];if(c.length===0)throw Error(`Layer "${t}" package "${a}" declares no Pi extensions.`);i.push(...c)}return i}function E(e,t){let n=new Set;for(let r of t)for(let t of e.layers[r]?.hookGroups??[])n.add(t);return[...n]}exports.isLocalPackageSpecifier=s,exports.layerEntries=T,exports.layerHookGroups=E,exports.loadMajorModesConfig=x,exports.resolveLayers=C,exports.resolvePackageConfigurations=S;
|
|
2
|
+
//# sourceMappingURL=majorModes.cjs.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"majorModes.cjs","names":["path","DOOM_DIR","os","readDoomConfigSources"],"sources":["../../src/adapters/majorModes.ts"],"sourcesContent":["import os from 'node:os';\nimport path from 'node:path';\nimport { DOOM_DIR, readDoomConfigSources } from './layeredConfig.ts';\n\nexport type LayerPackageConfig = Record<string, unknown>;\n\n/** One package selected by a layer, plus configuration owned by that package. */\nexport interface LayerPackage {\n name: string;\n optional?: boolean;\n config?: LayerPackageConfig;\n}\n\n/** One configured package found while walking selected layers in order. */\nexport interface ResolvedPackageConfiguration {\n layer: string;\n specifier: string;\n config: LayerPackageConfig;\n}\n\nexport interface LayerDefinition {\n /**\n * DoomPi built-in names, or Pi-compatible local extension paths.\n * Bare names resolve from DoomPi's own extension entries. Paths beginning\n * with `./` or `../`, plus absolute paths, resolve against the config that\n * declares the layer and may name a script file or extension directory.\n */\n extensions?: string[];\n /**\n * npm specifiers, or local package paths retained for compatibility.\n * Relative paths resolve against the repository root for `.doom/modes.yaml`\n * and against the global `.doom` directory for\n * `~/.pi/.doom/modes.yaml`.\n */\n packages?: Array<string | LayerPackage>;\n hookGroups?: string[];\n}\n\n/** A layer plus the root its relative extension and package paths resolve against. */\nexport interface ResolvedLayerDefinition extends LayerDefinition {\n baseDirectory: string;\n}\n\nexport interface MajorModeDefinition {\n /** Human-readable purpose used by pickers and agent-facing catalogs. */\n description: string;\n /** Ordered layer names activated by this mode. */\n layers: string[];\n}\n\nexport interface MajorModesConfig {\n layers: Record<string, ResolvedLayerDefinition>;\n /** The mode selected when neither a flag nor the environment names one. */\n defaultMajorMode: string;\n /** Named major modes, including their purpose and ordered layers. */\n majorMode: Record<string, MajorModeDefinition>;\n}\n\nexport interface LayerResolvers {\n ownEntry: (name: string) => string;\n packageEntry: (name: string) => string;\n optionalPackageEntry: (name: string) => string | undefined;\n /** Resolves every standard package.json pi.extensions entry for a package root. */\n packageEntries?: (name: string) => string[];\n /** Optional counterpart to packageEntries. */\n optionalPackageEntries?: (name: string) => string[] | undefined;\n /** Resolves one path-style layer entry against the config that declared it. */\n localEntry: (specifier: string, baseDirectory: string) => string | undefined;\n /** Resolves every Pi extension entry contributed by a local file or directory. */\n localEntries?: (specifier: string, baseDirectory: string) => string[] | undefined;\n}\n\ninterface ModesDocument {\n layers?: Record<string, unknown>;\n defaultMajorMode?: unknown;\n majorMode?: unknown;\n}\n\nconst MODES_FILE = 'modes.yaml';\nconst FALLBACK_MAJOR_MODE = 'copilot';\nconst MAJOR_MODES_RELATIVE_PATH = path.join(DOOM_DIR, MODES_FILE);\nconst RELATIVE_PREFIXES = ['./', '../'] as const;\n\n/**\n * Whether a layer value names a path rather than a built-in or installed package.\n *\n * The same rule Node applies to import specifiers, so a bare name is always a\n * logical name and a path always looks like one.\n */\nexport function isLocalPackageSpecifier(specifier: string): boolean {\n return path.isAbsolute(specifier) || RELATIVE_PREFIXES.some((prefix) => specifier.startsWith(prefix));\n}\nconst LAYER_PACKAGE_KEYS = ['name', 'optional', 'config'] as const;\nconst MAJOR_MODE_KEYS = ['description', 'layers'] as const;\n\nfunction isRecord(value: unknown): value is Record<string, unknown> {\n return typeof value === 'object' && value !== null && !Array.isArray(value);\n}\n\nfunction assertKnownKeys(value: Record<string, unknown>, keys: readonly string[], location: string): void {\n const unsupported = Object.keys(value).filter((key) => !keys.includes(key));\n if (unsupported.length > 0) {\n throw new Error(`${location} has unsupported field(s): ${unsupported.join(', ')}`);\n }\n}\n\nfunction parseLayerPackage(layerName: string, value: unknown, index: number): string | LayerPackage {\n const location = `Layer \"${layerName}\" package[${index}] in ${MAJOR_MODES_RELATIVE_PATH}`;\n if (typeof value === 'string') {\n if (!value.trim()) throw new Error(`${location} must be a non-empty string or mapping`);\n return value.trim();\n }\n if (!isRecord(value)) throw new Error(`${location} must be a non-empty string or mapping`);\n assertKnownKeys(value, LAYER_PACKAGE_KEYS, location);\n if (typeof value.name !== 'string' || !value.name.trim()) {\n throw new Error(`${location}.name must be a non-empty string`);\n }\n if (value.optional !== undefined && typeof value.optional !== 'boolean') {\n throw new Error(`${location}.optional must be a boolean`);\n }\n if (value.config !== undefined && !isRecord(value.config)) {\n throw new Error(`${location}.config must be a mapping`);\n }\n return {\n name: value.name.trim(),\n ...(value.optional === true ? { optional: true } : {}),\n ...(value.config ? { config: { ...value.config } } : {}),\n };\n}\n\nfunction parseLayerExtensions(layerName: string, value: unknown): string[] | undefined {\n if (value === undefined) return undefined;\n const location = `Layer \"${layerName}\" extensions in ${MAJOR_MODES_RELATIVE_PATH}`;\n if (!Array.isArray(value)) throw new Error(`${location} must be an array`);\n return value.map((entry, index) => {\n if (typeof entry !== 'string' || !entry.trim()) {\n throw new Error(`${location}[${index}] must be a non-empty string`);\n }\n return entry.trim();\n });\n}\n\nfunction parseLayerPackages(layerName: string, value: unknown): Array<string | LayerPackage> | undefined {\n if (value === undefined) return undefined;\n if (!Array.isArray(value)) {\n throw new Error(`Layer \"${layerName}\" packages in ${MAJOR_MODES_RELATIVE_PATH} must be an array`);\n }\n return value.map((entry, index) => parseLayerPackage(layerName, entry, index));\n}\n\nfunction parseDefaultMajorMode(value: unknown): string {\n if (typeof value !== 'string' || !value.trim()) {\n throw new Error(`defaultMajorMode in ${MAJOR_MODES_RELATIVE_PATH} must be a non-empty string`);\n }\n return value.trim();\n}\n\nfunction parseMajorModeLayers(modeName: string, value: unknown): string[] {\n const location = `Major mode \"${modeName}\" layers in ${MAJOR_MODES_RELATIVE_PATH}`;\n if (!Array.isArray(value)) throw new Error(`${location} must be an array`);\n return value.map((layerName, index) => {\n if (typeof layerName !== 'string' || !layerName.trim()) {\n throw new Error(`${location}[${index}] must be a non-empty string`);\n }\n return layerName.trim();\n });\n}\n\nfunction legacyMajorModeDescription(layers: readonly string[]): string {\n return layers.length > 0 ? `Uses layers: ${layers.join(', ')}.` : 'Uses Doom Pi core extensions only.';\n}\n\nfunction parseMajorMode(name: string, value: unknown): MajorModeDefinition {\n if (Array.isArray(value)) {\n const layers = parseMajorModeLayers(name, value);\n return { description: legacyMajorModeDescription(layers), layers };\n }\n\n const location = `Major mode \"${name}\" in ${MAJOR_MODES_RELATIVE_PATH}`;\n if (!isRecord(value)) throw new Error(`${location} must be a mapping with description and layers`);\n assertKnownKeys(value, MAJOR_MODE_KEYS, location);\n if (typeof value.description !== 'string' || !value.description.trim()) {\n throw new Error(`${location}.description must be a non-empty string`);\n }\n return {\n description: value.description.trim(),\n layers: parseMajorModeLayers(name, value.layers),\n };\n}\n\nfunction parseMajorModes(value: unknown): Record<string, MajorModeDefinition> {\n if (value === undefined) return {};\n if (!isRecord(value)) throw new Error(`majorMode in ${MAJOR_MODES_RELATIVE_PATH} must be a mapping`);\n return Object.fromEntries(\n Object.entries(value).map(([name, definition]) => [name, parseMajorMode(name, definition)]),\n );\n}\n\nfunction parseLayer(name: string, definition: unknown): LayerDefinition {\n if (!isRecord(definition)) throw new Error(`Layer \"${name}\" in ${MAJOR_MODES_RELATIVE_PATH} must be a mapping`);\n if ('targets' in definition) {\n throw new Error(\n `Layer \"${name}\" in ${MAJOR_MODES_RELATIVE_PATH} uses removed field \"targets\"; select availability through major modes`,\n );\n }\n if ('config' in definition) {\n throw new Error(\n `Layer \"${name}\" in ${MAJOR_MODES_RELATIVE_PATH} uses unsupported field \"config\"; move it under the package entry that owns it`,\n );\n }\n const extensions = parseLayerExtensions(name, definition.extensions);\n const packages = parseLayerPackages(name, definition.packages);\n return {\n ...definition,\n ...(extensions === undefined ? {} : { extensions }),\n ...(packages === undefined ? {} : { packages }),\n } as LayerDefinition;\n}\n\n/**\n * Reads layers and major modes from the global and repository configs.\n *\n * The repository is read last, so it replaces a global layer or major mode of\n * the same name. Layers keep the root they were declared under so that a\n * global layer naming `./extensions/x` still points beside the global config\n * once it is loaded from inside some other repository.\n */\nexport function loadMajorModesConfig(repoRoot: string, homeDirectory: string = os.homedir()): MajorModesConfig {\n const sources = readDoomConfigSources<ModesDocument>(MODES_FILE, repoRoot, homeDirectory);\n const layers: Record<string, ResolvedLayerDefinition> = {};\n const majorMode: Record<string, MajorModeDefinition> = {};\n let defaultMajorMode = FALLBACK_MAJOR_MODE;\n let hasConfiguredDefault = false;\n for (const source of sources) {\n for (const [name, definition] of Object.entries(source.document.layers ?? {})) {\n layers[name] = { ...parseLayer(name, definition), baseDirectory: source.baseDirectory };\n }\n if (Object.hasOwn(source.document, 'defaultMajorMode')) {\n defaultMajorMode = parseDefaultMajorMode(source.document.defaultMajorMode);\n hasConfiguredDefault = true;\n }\n Object.assign(majorMode, parseMajorModes(source.document.majorMode));\n }\n\n for (const [modeName, definition] of Object.entries(majorMode)) {\n for (const name of definition.layers) {\n if (!layers[name]) {\n throw new Error(`Unknown layer \"${name}\" in majorMode.${modeName} of ${MAJOR_MODES_RELATIVE_PATH}`);\n }\n }\n }\n if (hasConfiguredDefault && !Object.hasOwn(majorMode, defaultMajorMode)) {\n throw new Error(`Unknown default major mode \"${defaultMajorMode}\" in ${MAJOR_MODES_RELATIVE_PATH}`);\n }\n return { layers, defaultMajorMode, majorMode };\n}\n\n/** Finds configuration owned by one package while preserving layer and package order. */\nexport function resolvePackageConfigurations(\n config: MajorModesConfig,\n names: string[],\n packageName: string,\n): ResolvedPackageConfiguration[] {\n const normalizedPackageName = packageName.trim();\n if (!normalizedPackageName) throw new Error('Package name must be a non-empty string');\n const configurations: ResolvedPackageConfiguration[] = [];\n for (const name of names) {\n const layer = config.layers[name];\n if (!layer) throw new Error(`Unknown layer: ${name}`);\n for (const entry of layer.packages ?? []) {\n if (typeof entry === 'string' || entry.config === undefined) continue;\n if (entry.name !== normalizedPackageName && !entry.name.startsWith(`${normalizedPackageName}/`)) continue;\n configurations.push({ layer: name, specifier: entry.name, config: { ...entry.config } });\n }\n }\n return configurations;\n}\n\n/** Resolves one named major mode into its configured layer components. */\nexport function resolveLayers(config: MajorModesConfig, majorMode: string): string[] {\n if (!Object.hasOwn(config.majorMode, majorMode)) {\n throw new Error(\n `Unknown major mode: ${majorMode}. Known major modes: ${Object.keys(config.majorMode).sort().join(', ')}`,\n );\n }\n return [...config.majorMode[majorMode]!.layers];\n}\n\nfunction resolveLocalEntries(\n resolvers: LayerResolvers,\n specifier: string,\n baseDirectory: string,\n): string[] | undefined {\n const resolved = resolvers.localEntries?.(specifier, baseDirectory);\n if (resolved !== undefined) return resolved;\n const single = resolvers.localEntry(specifier, baseDirectory);\n return single ? [single] : undefined;\n}\n\n/** Resolves one layer's extension and package entries to absolute paths. */\nexport function layerEntries(config: MajorModesConfig, name: string, resolvers: LayerResolvers): string[] {\n const layer = config.layers[name];\n if (!layer) throw new Error(`Unknown layer: ${name}`);\n const entries: string[] = [];\n for (const entry of layer.extensions ?? []) {\n if (!isLocalPackageSpecifier(entry)) {\n entries.push(resolvers.ownEntry(entry));\n continue;\n }\n const resolved = resolveLocalEntries(resolvers, entry, layer.baseDirectory);\n if (!resolved?.length) {\n throw new Error(\n `Layer \"${name}\" extension \"${entry}\" does not resolve under ${layer.baseDirectory}. ` +\n 'Point it at a Pi extension file or directory.',\n );\n }\n entries.push(...resolved);\n }\n for (const entry of layer.packages ?? []) {\n const specifier = typeof entry === 'string' ? entry : entry.name;\n const optional = typeof entry === 'string' ? false : entry.optional === true;\n if (isLocalPackageSpecifier(specifier)) {\n const resolved = resolveLocalEntries(resolvers, specifier, layer.baseDirectory);\n if (resolved?.length) entries.push(...resolved);\n else if (!optional) {\n throw new Error(\n `Layer \"${name}\" package \"${specifier}\" does not resolve under ${layer.baseDirectory}. ` +\n 'Point it at an extension file, or a directory whose package.json declares pi.extensions.',\n );\n }\n continue;\n }\n if (optional) {\n let resolved = resolvers.optionalPackageEntries?.(specifier);\n if (resolved === undefined) {\n const single = resolvers.optionalPackageEntry(specifier);\n resolved = single ? [single] : undefined;\n }\n if (resolved) entries.push(...resolved);\n continue;\n }\n const resolved = resolvers.packageEntries?.(specifier) ?? [resolvers.packageEntry(specifier)];\n if (resolved.length === 0) {\n throw new Error(`Layer \"${name}\" package \"${specifier}\" declares no Pi extensions.`);\n }\n entries.push(...resolved);\n }\n return entries;\n}\n\n/** Hook group ids contributed by the selected layers, deduped. */\nexport function layerHookGroups(config: MajorModesConfig, names: string[]): string[] {\n const groups = new Set<string>();\n for (const name of names) {\n for (const group of config.layers[name]?.hookGroups ?? []) groups.add(group);\n }\n return [...groups];\n}\n"],"mappings":"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"}
|
|
@@ -0,0 +1,88 @@
|
|
|
1
|
+
//#region src/adapters/majorModes.d.ts
|
|
2
|
+
type LayerPackageConfig = Record<string, unknown>;
|
|
3
|
+
/** One package selected by a layer, plus configuration owned by that package. */
|
|
4
|
+
interface LayerPackage {
|
|
5
|
+
name: string;
|
|
6
|
+
optional?: boolean;
|
|
7
|
+
config?: LayerPackageConfig;
|
|
8
|
+
}
|
|
9
|
+
/** One configured package found while walking selected layers in order. */
|
|
10
|
+
interface ResolvedPackageConfiguration {
|
|
11
|
+
layer: string;
|
|
12
|
+
specifier: string;
|
|
13
|
+
config: LayerPackageConfig;
|
|
14
|
+
}
|
|
15
|
+
interface LayerDefinition {
|
|
16
|
+
/**
|
|
17
|
+
* DoomPi built-in names, or Pi-compatible local extension paths.
|
|
18
|
+
* Bare names resolve from DoomPi's own extension entries. Paths beginning
|
|
19
|
+
* with `./` or `../`, plus absolute paths, resolve against the config that
|
|
20
|
+
* declares the layer and may name a script file or extension directory.
|
|
21
|
+
*/
|
|
22
|
+
extensions?: string[];
|
|
23
|
+
/**
|
|
24
|
+
* npm specifiers, or local package paths retained for compatibility.
|
|
25
|
+
* Relative paths resolve against the repository root for `.doom/modes.yaml`
|
|
26
|
+
* and against the global `.doom` directory for
|
|
27
|
+
* `~/.pi/.doom/modes.yaml`.
|
|
28
|
+
*/
|
|
29
|
+
packages?: Array<string | LayerPackage>;
|
|
30
|
+
hookGroups?: string[];
|
|
31
|
+
}
|
|
32
|
+
/** A layer plus the root its relative extension and package paths resolve against. */
|
|
33
|
+
interface ResolvedLayerDefinition extends LayerDefinition {
|
|
34
|
+
baseDirectory: string;
|
|
35
|
+
}
|
|
36
|
+
interface MajorModeDefinition {
|
|
37
|
+
/** Human-readable purpose used by pickers and agent-facing catalogs. */
|
|
38
|
+
description: string;
|
|
39
|
+
/** Ordered layer names activated by this mode. */
|
|
40
|
+
layers: string[];
|
|
41
|
+
}
|
|
42
|
+
interface MajorModesConfig {
|
|
43
|
+
layers: Record<string, ResolvedLayerDefinition>;
|
|
44
|
+
/** The mode selected when neither a flag nor the environment names one. */
|
|
45
|
+
defaultMajorMode: string;
|
|
46
|
+
/** Named major modes, including their purpose and ordered layers. */
|
|
47
|
+
majorMode: Record<string, MajorModeDefinition>;
|
|
48
|
+
}
|
|
49
|
+
interface LayerResolvers {
|
|
50
|
+
ownEntry: (name: string) => string;
|
|
51
|
+
packageEntry: (name: string) => string;
|
|
52
|
+
optionalPackageEntry: (name: string) => string | undefined;
|
|
53
|
+
/** Resolves every standard package.json pi.extensions entry for a package root. */
|
|
54
|
+
packageEntries?: (name: string) => string[];
|
|
55
|
+
/** Optional counterpart to packageEntries. */
|
|
56
|
+
optionalPackageEntries?: (name: string) => string[] | undefined;
|
|
57
|
+
/** Resolves one path-style layer entry against the config that declared it. */
|
|
58
|
+
localEntry: (specifier: string, baseDirectory: string) => string | undefined;
|
|
59
|
+
/** Resolves every Pi extension entry contributed by a local file or directory. */
|
|
60
|
+
localEntries?: (specifier: string, baseDirectory: string) => string[] | undefined;
|
|
61
|
+
}
|
|
62
|
+
/**
|
|
63
|
+
* Whether a layer value names a path rather than a built-in or installed package.
|
|
64
|
+
*
|
|
65
|
+
* The same rule Node applies to import specifiers, so a bare name is always a
|
|
66
|
+
* logical name and a path always looks like one.
|
|
67
|
+
*/
|
|
68
|
+
declare function isLocalPackageSpecifier(specifier: string): boolean;
|
|
69
|
+
/**
|
|
70
|
+
* Reads layers and major modes from the global and repository configs.
|
|
71
|
+
*
|
|
72
|
+
* The repository is read last, so it replaces a global layer or major mode of
|
|
73
|
+
* the same name. Layers keep the root they were declared under so that a
|
|
74
|
+
* global layer naming `./extensions/x` still points beside the global config
|
|
75
|
+
* once it is loaded from inside some other repository.
|
|
76
|
+
*/
|
|
77
|
+
declare function loadMajorModesConfig(repoRoot: string, homeDirectory?: string): MajorModesConfig;
|
|
78
|
+
/** Finds configuration owned by one package while preserving layer and package order. */
|
|
79
|
+
declare function resolvePackageConfigurations(config: MajorModesConfig, names: string[], packageName: string): ResolvedPackageConfiguration[];
|
|
80
|
+
/** Resolves one named major mode into its configured layer components. */
|
|
81
|
+
declare function resolveLayers(config: MajorModesConfig, majorMode: string): string[];
|
|
82
|
+
/** Resolves one layer's extension and package entries to absolute paths. */
|
|
83
|
+
declare function layerEntries(config: MajorModesConfig, name: string, resolvers: LayerResolvers): string[];
|
|
84
|
+
/** Hook group ids contributed by the selected layers, deduped. */
|
|
85
|
+
declare function layerHookGroups(config: MajorModesConfig, names: string[]): string[];
|
|
86
|
+
//#endregion
|
|
87
|
+
export { LayerDefinition, LayerPackage, LayerPackageConfig, LayerResolvers, MajorModeDefinition, MajorModesConfig, ResolvedLayerDefinition, ResolvedPackageConfiguration, isLocalPackageSpecifier, layerEntries, layerHookGroups, loadMajorModesConfig, resolveLayers, resolvePackageConfigurations };
|
|
88
|
+
//# sourceMappingURL=majorModes.d.cts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"majorModes.d.cts","names":[],"sources":["../../src/adapters/majorModes.ts"],"mappings":";KAIY,qBAAqB;;UAGhB;EACf;EACA;EACA,SAAS;;;UAIM;EACf;EACA;EACA,QAAQ;;UAGO;;;;;;;EAOf;;;;;;;EAOA,WAAW,eAAe;EAC1B;;;UAIe,gCAAgC;EAC/C;;UAGe;;EAEf;;EAEA;;UAGe;EACf,QAAQ,eAAe;;EAEvB;;EAEA,WAAW,eAAe;;UAGX;EACf,WAAW;EACX,eAAe;EACf,uBAAuB;;EAEvB,kBAAkB;;EAElB,0BAA0B;;EAE1B,aAAa,mBAAmB;;EAEhC,gBAAgB,mBAAmB;;;;;;;;iBAoBrB,wBAAwB;;;;;;;;;iBA0IxB,qBAAqB,kBAAkB,yBAAuC;;iBA+B9E,6BACd,QAAQ,kBACR,iBACA,sBACC;;iBAiBa,cAAc,QAAQ,kBAAkB;;iBAqBxC,aAAa,QAAQ,kBAAkB,cAAc,WAAW;;iBAmDhE,gBAAgB,QAAQ,kBAAkB"}
|
|
@@ -0,0 +1,88 @@
|
|
|
1
|
+
//#region src/adapters/majorModes.d.ts
|
|
2
|
+
type LayerPackageConfig = Record<string, unknown>;
|
|
3
|
+
/** One package selected by a layer, plus configuration owned by that package. */
|
|
4
|
+
interface LayerPackage {
|
|
5
|
+
name: string;
|
|
6
|
+
optional?: boolean;
|
|
7
|
+
config?: LayerPackageConfig;
|
|
8
|
+
}
|
|
9
|
+
/** One configured package found while walking selected layers in order. */
|
|
10
|
+
interface ResolvedPackageConfiguration {
|
|
11
|
+
layer: string;
|
|
12
|
+
specifier: string;
|
|
13
|
+
config: LayerPackageConfig;
|
|
14
|
+
}
|
|
15
|
+
interface LayerDefinition {
|
|
16
|
+
/**
|
|
17
|
+
* DoomPi built-in names, or Pi-compatible local extension paths.
|
|
18
|
+
* Bare names resolve from DoomPi's own extension entries. Paths beginning
|
|
19
|
+
* with `./` or `../`, plus absolute paths, resolve against the config that
|
|
20
|
+
* declares the layer and may name a script file or extension directory.
|
|
21
|
+
*/
|
|
22
|
+
extensions?: string[];
|
|
23
|
+
/**
|
|
24
|
+
* npm specifiers, or local package paths retained for compatibility.
|
|
25
|
+
* Relative paths resolve against the repository root for `.doom/modes.yaml`
|
|
26
|
+
* and against the global `.doom` directory for
|
|
27
|
+
* `~/.pi/.doom/modes.yaml`.
|
|
28
|
+
*/
|
|
29
|
+
packages?: Array<string | LayerPackage>;
|
|
30
|
+
hookGroups?: string[];
|
|
31
|
+
}
|
|
32
|
+
/** A layer plus the root its relative extension and package paths resolve against. */
|
|
33
|
+
interface ResolvedLayerDefinition extends LayerDefinition {
|
|
34
|
+
baseDirectory: string;
|
|
35
|
+
}
|
|
36
|
+
interface MajorModeDefinition {
|
|
37
|
+
/** Human-readable purpose used by pickers and agent-facing catalogs. */
|
|
38
|
+
description: string;
|
|
39
|
+
/** Ordered layer names activated by this mode. */
|
|
40
|
+
layers: string[];
|
|
41
|
+
}
|
|
42
|
+
interface MajorModesConfig {
|
|
43
|
+
layers: Record<string, ResolvedLayerDefinition>;
|
|
44
|
+
/** The mode selected when neither a flag nor the environment names one. */
|
|
45
|
+
defaultMajorMode: string;
|
|
46
|
+
/** Named major modes, including their purpose and ordered layers. */
|
|
47
|
+
majorMode: Record<string, MajorModeDefinition>;
|
|
48
|
+
}
|
|
49
|
+
interface LayerResolvers {
|
|
50
|
+
ownEntry: (name: string) => string;
|
|
51
|
+
packageEntry: (name: string) => string;
|
|
52
|
+
optionalPackageEntry: (name: string) => string | undefined;
|
|
53
|
+
/** Resolves every standard package.json pi.extensions entry for a package root. */
|
|
54
|
+
packageEntries?: (name: string) => string[];
|
|
55
|
+
/** Optional counterpart to packageEntries. */
|
|
56
|
+
optionalPackageEntries?: (name: string) => string[] | undefined;
|
|
57
|
+
/** Resolves one path-style layer entry against the config that declared it. */
|
|
58
|
+
localEntry: (specifier: string, baseDirectory: string) => string | undefined;
|
|
59
|
+
/** Resolves every Pi extension entry contributed by a local file or directory. */
|
|
60
|
+
localEntries?: (specifier: string, baseDirectory: string) => string[] | undefined;
|
|
61
|
+
}
|
|
62
|
+
/**
|
|
63
|
+
* Whether a layer value names a path rather than a built-in or installed package.
|
|
64
|
+
*
|
|
65
|
+
* The same rule Node applies to import specifiers, so a bare name is always a
|
|
66
|
+
* logical name and a path always looks like one.
|
|
67
|
+
*/
|
|
68
|
+
declare function isLocalPackageSpecifier(specifier: string): boolean;
|
|
69
|
+
/**
|
|
70
|
+
* Reads layers and major modes from the global and repository configs.
|
|
71
|
+
*
|
|
72
|
+
* The repository is read last, so it replaces a global layer or major mode of
|
|
73
|
+
* the same name. Layers keep the root they were declared under so that a
|
|
74
|
+
* global layer naming `./extensions/x` still points beside the global config
|
|
75
|
+
* once it is loaded from inside some other repository.
|
|
76
|
+
*/
|
|
77
|
+
declare function loadMajorModesConfig(repoRoot: string, homeDirectory?: string): MajorModesConfig;
|
|
78
|
+
/** Finds configuration owned by one package while preserving layer and package order. */
|
|
79
|
+
declare function resolvePackageConfigurations(config: MajorModesConfig, names: string[], packageName: string): ResolvedPackageConfiguration[];
|
|
80
|
+
/** Resolves one named major mode into its configured layer components. */
|
|
81
|
+
declare function resolveLayers(config: MajorModesConfig, majorMode: string): string[];
|
|
82
|
+
/** Resolves one layer's extension and package entries to absolute paths. */
|
|
83
|
+
declare function layerEntries(config: MajorModesConfig, name: string, resolvers: LayerResolvers): string[];
|
|
84
|
+
/** Hook group ids contributed by the selected layers, deduped. */
|
|
85
|
+
declare function layerHookGroups(config: MajorModesConfig, names: string[]): string[];
|
|
86
|
+
//#endregion
|
|
87
|
+
export { LayerDefinition, LayerPackage, LayerPackageConfig, LayerResolvers, MajorModeDefinition, MajorModesConfig, ResolvedLayerDefinition, ResolvedPackageConfiguration, isLocalPackageSpecifier, layerEntries, layerHookGroups, loadMajorModesConfig, resolveLayers, resolvePackageConfigurations };
|
|
88
|
+
//# sourceMappingURL=majorModes.d.mts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"majorModes.d.mts","names":[],"sources":["../../src/adapters/majorModes.ts"],"mappings":";KAIY,qBAAqB;;UAGhB;EACf;EACA;EACA,SAAS;;;UAIM;EACf;EACA;EACA,QAAQ;;UAGO;;;;;;;EAOf;;;;;;;EAOA,WAAW,eAAe;EAC1B;;;UAIe,gCAAgC;EAC/C;;UAGe;;EAEf;;EAEA;;UAGe;EACf,QAAQ,eAAe;;EAEvB;;EAEA,WAAW,eAAe;;UAGX;EACf,WAAW;EACX,eAAe;EACf,uBAAuB;;EAEvB,kBAAkB;;EAElB,0BAA0B;;EAE1B,aAAa,mBAAmB;;EAEhC,gBAAgB,mBAAmB;;;;;;;;iBAoBrB,wBAAwB;;;;;;;;;iBA0IxB,qBAAqB,kBAAkB,yBAAuC;;iBA+B9E,6BACd,QAAQ,kBACR,iBACA,sBACC;;iBAiBa,cAAc,QAAQ,kBAAkB;;iBAqBxC,aAAa,QAAQ,kBAAkB,cAAc,WAAW;;iBAmDhE,gBAAgB,QAAQ,kBAAkB"}
|
|
@@ -0,0 +1,2 @@
|
|
|
1
|
+
import{DOOM_DIR as e,readDoomConfigSources as t}from"./layeredConfig.mjs";import n from"node:path";import r from"node:os";const i=`modes.yaml`,a=n.join(e,i),o=[`./`,`../`];function s(e){return n.isAbsolute(e)||o.some(t=>e.startsWith(t))}const c=[`name`,`optional`,`config`],l=[`description`,`layers`];function u(e){return typeof e==`object`&&!!e&&!Array.isArray(e)}function d(e,t,n){let r=Object.keys(e).filter(e=>!t.includes(e));if(r.length>0)throw Error(`${n} has unsupported field(s): ${r.join(`, `)}`)}function f(e,t,n){let r=`Layer "${e}" package[${n}] in ${a}`;if(typeof t==`string`){if(!t.trim())throw Error(`${r} must be a non-empty string or mapping`);return t.trim()}if(!u(t))throw Error(`${r} must be a non-empty string or mapping`);if(d(t,c,r),typeof t.name!=`string`||!t.name.trim())throw Error(`${r}.name must be a non-empty string`);if(t.optional!==void 0&&typeof t.optional!=`boolean`)throw Error(`${r}.optional must be a boolean`);if(t.config!==void 0&&!u(t.config))throw Error(`${r}.config must be a mapping`);return{name:t.name.trim(),...t.optional===!0?{optional:!0}:{},...t.config?{config:{...t.config}}:{}}}function p(e,t){if(t===void 0)return;let n=`Layer "${e}" extensions in ${a}`;if(!Array.isArray(t))throw Error(`${n} must be an array`);return t.map((e,t)=>{if(typeof e!=`string`||!e.trim())throw Error(`${n}[${t}] must be a non-empty string`);return e.trim()})}function m(e,t){if(t!==void 0){if(!Array.isArray(t))throw Error(`Layer "${e}" packages in ${a} must be an array`);return t.map((t,n)=>f(e,t,n))}}function h(e){if(typeof e!=`string`||!e.trim())throw Error(`defaultMajorMode in ${a} must be a non-empty string`);return e.trim()}function g(e,t){let n=`Major mode "${e}" layers in ${a}`;if(!Array.isArray(t))throw Error(`${n} must be an array`);return t.map((e,t)=>{if(typeof e!=`string`||!e.trim())throw Error(`${n}[${t}] must be a non-empty string`);return e.trim()})}function _(e){return e.length>0?`Uses layers: ${e.join(`, `)}.`:`Uses Doom Pi core extensions only.`}function v(e,t){if(Array.isArray(t)){let n=g(e,t);return{description:_(n),layers:n}}let n=`Major mode "${e}" in ${a}`;if(!u(t))throw Error(`${n} must be a mapping with description and layers`);if(d(t,l,n),typeof t.description!=`string`||!t.description.trim())throw Error(`${n}.description must be a non-empty string`);return{description:t.description.trim(),layers:g(e,t.layers)}}function y(e){if(e===void 0)return{};if(!u(e))throw Error(`majorMode in ${a} must be a mapping`);return Object.fromEntries(Object.entries(e).map(([e,t])=>[e,v(e,t)]))}function b(e,t){if(!u(t))throw Error(`Layer "${e}" in ${a} must be a mapping`);if(`targets`in t)throw Error(`Layer "${e}" in ${a} uses removed field "targets"; select availability through major modes`);if(`config`in t)throw Error(`Layer "${e}" in ${a} uses unsupported field "config"; move it under the package entry that owns it`);let n=p(e,t.extensions),r=m(e,t.packages);return{...t,...n===void 0?{}:{extensions:n},...r===void 0?{}:{packages:r}}}function x(e,n=r.homedir()){let o=t(i,e,n),s={},c={},l=`copilot`,u=!1;for(let e of o){for(let[t,n]of Object.entries(e.document.layers??{}))s[t]={...b(t,n),baseDirectory:e.baseDirectory};Object.hasOwn(e.document,`defaultMajorMode`)&&(l=h(e.document.defaultMajorMode),u=!0),Object.assign(c,y(e.document.majorMode))}for(let[e,t]of Object.entries(c))for(let n of t.layers)if(!s[n])throw Error(`Unknown layer "${n}" in majorMode.${e} of ${a}`);if(u&&!Object.hasOwn(c,l))throw Error(`Unknown default major mode "${l}" in ${a}`);return{layers:s,defaultMajorMode:l,majorMode:c}}function S(e,t,n){let r=n.trim();if(!r)throw Error(`Package name must be a non-empty string`);let i=[];for(let n of t){let t=e.layers[n];if(!t)throw Error(`Unknown layer: ${n}`);for(let e of t.packages??[])typeof e!=`string`&&e.config!==void 0&&(e.name!==r&&!e.name.startsWith(`${r}/`)||i.push({layer:n,specifier:e.name,config:{...e.config}}))}return i}function C(e,t){if(!Object.hasOwn(e.majorMode,t))throw Error(`Unknown major mode: ${t}. Known major modes: ${Object.keys(e.majorMode).sort().join(`, `)}`);return[...e.majorMode[t].layers]}function w(e,t,n){let r=e.localEntries?.(t,n);if(r!==void 0)return r;let i=e.localEntry(t,n);return i?[i]:void 0}function T(e,t,n){let r=e.layers[t];if(!r)throw Error(`Unknown layer: ${t}`);let i=[];for(let e of r.extensions??[]){if(!s(e)){i.push(n.ownEntry(e));continue}let a=w(n,e,r.baseDirectory);if(!a?.length)throw Error(`Layer "${t}" extension "${e}" does not resolve under ${r.baseDirectory}. Point it at a Pi extension file or directory.`);i.push(...a)}for(let e of r.packages??[]){let a=typeof e==`string`?e:e.name,o=typeof e!=`string`&&e.optional===!0;if(s(a)){let e=w(n,a,r.baseDirectory);if(e?.length)i.push(...e);else if(!o)throw Error(`Layer "${t}" package "${a}" does not resolve under ${r.baseDirectory}. Point it at an extension file, or a directory whose package.json declares pi.extensions.`);continue}if(o){let e=n.optionalPackageEntries?.(a);if(e===void 0){let t=n.optionalPackageEntry(a);e=t?[t]:void 0}e&&i.push(...e);continue}let c=n.packageEntries?.(a)??[n.packageEntry(a)];if(c.length===0)throw Error(`Layer "${t}" package "${a}" declares no Pi extensions.`);i.push(...c)}return i}function E(e,t){let n=new Set;for(let r of t)for(let t of e.layers[r]?.hookGroups??[])n.add(t);return[...n]}export{s as isLocalPackageSpecifier,T as layerEntries,E as layerHookGroups,x as loadMajorModesConfig,C as resolveLayers,S as resolvePackageConfigurations};
|
|
2
|
+
//# sourceMappingURL=majorModes.mjs.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"majorModes.mjs","names":[],"sources":["../../src/adapters/majorModes.ts"],"sourcesContent":["import os from 'node:os';\nimport path from 'node:path';\nimport { DOOM_DIR, readDoomConfigSources } from './layeredConfig.ts';\n\nexport type LayerPackageConfig = Record<string, unknown>;\n\n/** One package selected by a layer, plus configuration owned by that package. */\nexport interface LayerPackage {\n name: string;\n optional?: boolean;\n config?: LayerPackageConfig;\n}\n\n/** One configured package found while walking selected layers in order. */\nexport interface ResolvedPackageConfiguration {\n layer: string;\n specifier: string;\n config: LayerPackageConfig;\n}\n\nexport interface LayerDefinition {\n /**\n * DoomPi built-in names, or Pi-compatible local extension paths.\n * Bare names resolve from DoomPi's own extension entries. Paths beginning\n * with `./` or `../`, plus absolute paths, resolve against the config that\n * declares the layer and may name a script file or extension directory.\n */\n extensions?: string[];\n /**\n * npm specifiers, or local package paths retained for compatibility.\n * Relative paths resolve against the repository root for `.doom/modes.yaml`\n * and against the global `.doom` directory for\n * `~/.pi/.doom/modes.yaml`.\n */\n packages?: Array<string | LayerPackage>;\n hookGroups?: string[];\n}\n\n/** A layer plus the root its relative extension and package paths resolve against. */\nexport interface ResolvedLayerDefinition extends LayerDefinition {\n baseDirectory: string;\n}\n\nexport interface MajorModeDefinition {\n /** Human-readable purpose used by pickers and agent-facing catalogs. */\n description: string;\n /** Ordered layer names activated by this mode. */\n layers: string[];\n}\n\nexport interface MajorModesConfig {\n layers: Record<string, ResolvedLayerDefinition>;\n /** The mode selected when neither a flag nor the environment names one. */\n defaultMajorMode: string;\n /** Named major modes, including their purpose and ordered layers. */\n majorMode: Record<string, MajorModeDefinition>;\n}\n\nexport interface LayerResolvers {\n ownEntry: (name: string) => string;\n packageEntry: (name: string) => string;\n optionalPackageEntry: (name: string) => string | undefined;\n /** Resolves every standard package.json pi.extensions entry for a package root. */\n packageEntries?: (name: string) => string[];\n /** Optional counterpart to packageEntries. */\n optionalPackageEntries?: (name: string) => string[] | undefined;\n /** Resolves one path-style layer entry against the config that declared it. */\n localEntry: (specifier: string, baseDirectory: string) => string | undefined;\n /** Resolves every Pi extension entry contributed by a local file or directory. */\n localEntries?: (specifier: string, baseDirectory: string) => string[] | undefined;\n}\n\ninterface ModesDocument {\n layers?: Record<string, unknown>;\n defaultMajorMode?: unknown;\n majorMode?: unknown;\n}\n\nconst MODES_FILE = 'modes.yaml';\nconst FALLBACK_MAJOR_MODE = 'copilot';\nconst MAJOR_MODES_RELATIVE_PATH = path.join(DOOM_DIR, MODES_FILE);\nconst RELATIVE_PREFIXES = ['./', '../'] as const;\n\n/**\n * Whether a layer value names a path rather than a built-in or installed package.\n *\n * The same rule Node applies to import specifiers, so a bare name is always a\n * logical name and a path always looks like one.\n */\nexport function isLocalPackageSpecifier(specifier: string): boolean {\n return path.isAbsolute(specifier) || RELATIVE_PREFIXES.some((prefix) => specifier.startsWith(prefix));\n}\nconst LAYER_PACKAGE_KEYS = ['name', 'optional', 'config'] as const;\nconst MAJOR_MODE_KEYS = ['description', 'layers'] as const;\n\nfunction isRecord(value: unknown): value is Record<string, unknown> {\n return typeof value === 'object' && value !== null && !Array.isArray(value);\n}\n\nfunction assertKnownKeys(value: Record<string, unknown>, keys: readonly string[], location: string): void {\n const unsupported = Object.keys(value).filter((key) => !keys.includes(key));\n if (unsupported.length > 0) {\n throw new Error(`${location} has unsupported field(s): ${unsupported.join(', ')}`);\n }\n}\n\nfunction parseLayerPackage(layerName: string, value: unknown, index: number): string | LayerPackage {\n const location = `Layer \"${layerName}\" package[${index}] in ${MAJOR_MODES_RELATIVE_PATH}`;\n if (typeof value === 'string') {\n if (!value.trim()) throw new Error(`${location} must be a non-empty string or mapping`);\n return value.trim();\n }\n if (!isRecord(value)) throw new Error(`${location} must be a non-empty string or mapping`);\n assertKnownKeys(value, LAYER_PACKAGE_KEYS, location);\n if (typeof value.name !== 'string' || !value.name.trim()) {\n throw new Error(`${location}.name must be a non-empty string`);\n }\n if (value.optional !== undefined && typeof value.optional !== 'boolean') {\n throw new Error(`${location}.optional must be a boolean`);\n }\n if (value.config !== undefined && !isRecord(value.config)) {\n throw new Error(`${location}.config must be a mapping`);\n }\n return {\n name: value.name.trim(),\n ...(value.optional === true ? { optional: true } : {}),\n ...(value.config ? { config: { ...value.config } } : {}),\n };\n}\n\nfunction parseLayerExtensions(layerName: string, value: unknown): string[] | undefined {\n if (value === undefined) return undefined;\n const location = `Layer \"${layerName}\" extensions in ${MAJOR_MODES_RELATIVE_PATH}`;\n if (!Array.isArray(value)) throw new Error(`${location} must be an array`);\n return value.map((entry, index) => {\n if (typeof entry !== 'string' || !entry.trim()) {\n throw new Error(`${location}[${index}] must be a non-empty string`);\n }\n return entry.trim();\n });\n}\n\nfunction parseLayerPackages(layerName: string, value: unknown): Array<string | LayerPackage> | undefined {\n if (value === undefined) return undefined;\n if (!Array.isArray(value)) {\n throw new Error(`Layer \"${layerName}\" packages in ${MAJOR_MODES_RELATIVE_PATH} must be an array`);\n }\n return value.map((entry, index) => parseLayerPackage(layerName, entry, index));\n}\n\nfunction parseDefaultMajorMode(value: unknown): string {\n if (typeof value !== 'string' || !value.trim()) {\n throw new Error(`defaultMajorMode in ${MAJOR_MODES_RELATIVE_PATH} must be a non-empty string`);\n }\n return value.trim();\n}\n\nfunction parseMajorModeLayers(modeName: string, value: unknown): string[] {\n const location = `Major mode \"${modeName}\" layers in ${MAJOR_MODES_RELATIVE_PATH}`;\n if (!Array.isArray(value)) throw new Error(`${location} must be an array`);\n return value.map((layerName, index) => {\n if (typeof layerName !== 'string' || !layerName.trim()) {\n throw new Error(`${location}[${index}] must be a non-empty string`);\n }\n return layerName.trim();\n });\n}\n\nfunction legacyMajorModeDescription(layers: readonly string[]): string {\n return layers.length > 0 ? `Uses layers: ${layers.join(', ')}.` : 'Uses Doom Pi core extensions only.';\n}\n\nfunction parseMajorMode(name: string, value: unknown): MajorModeDefinition {\n if (Array.isArray(value)) {\n const layers = parseMajorModeLayers(name, value);\n return { description: legacyMajorModeDescription(layers), layers };\n }\n\n const location = `Major mode \"${name}\" in ${MAJOR_MODES_RELATIVE_PATH}`;\n if (!isRecord(value)) throw new Error(`${location} must be a mapping with description and layers`);\n assertKnownKeys(value, MAJOR_MODE_KEYS, location);\n if (typeof value.description !== 'string' || !value.description.trim()) {\n throw new Error(`${location}.description must be a non-empty string`);\n }\n return {\n description: value.description.trim(),\n layers: parseMajorModeLayers(name, value.layers),\n };\n}\n\nfunction parseMajorModes(value: unknown): Record<string, MajorModeDefinition> {\n if (value === undefined) return {};\n if (!isRecord(value)) throw new Error(`majorMode in ${MAJOR_MODES_RELATIVE_PATH} must be a mapping`);\n return Object.fromEntries(\n Object.entries(value).map(([name, definition]) => [name, parseMajorMode(name, definition)]),\n );\n}\n\nfunction parseLayer(name: string, definition: unknown): LayerDefinition {\n if (!isRecord(definition)) throw new Error(`Layer \"${name}\" in ${MAJOR_MODES_RELATIVE_PATH} must be a mapping`);\n if ('targets' in definition) {\n throw new Error(\n `Layer \"${name}\" in ${MAJOR_MODES_RELATIVE_PATH} uses removed field \"targets\"; select availability through major modes`,\n );\n }\n if ('config' in definition) {\n throw new Error(\n `Layer \"${name}\" in ${MAJOR_MODES_RELATIVE_PATH} uses unsupported field \"config\"; move it under the package entry that owns it`,\n );\n }\n const extensions = parseLayerExtensions(name, definition.extensions);\n const packages = parseLayerPackages(name, definition.packages);\n return {\n ...definition,\n ...(extensions === undefined ? {} : { extensions }),\n ...(packages === undefined ? {} : { packages }),\n } as LayerDefinition;\n}\n\n/**\n * Reads layers and major modes from the global and repository configs.\n *\n * The repository is read last, so it replaces a global layer or major mode of\n * the same name. Layers keep the root they were declared under so that a\n * global layer naming `./extensions/x` still points beside the global config\n * once it is loaded from inside some other repository.\n */\nexport function loadMajorModesConfig(repoRoot: string, homeDirectory: string = os.homedir()): MajorModesConfig {\n const sources = readDoomConfigSources<ModesDocument>(MODES_FILE, repoRoot, homeDirectory);\n const layers: Record<string, ResolvedLayerDefinition> = {};\n const majorMode: Record<string, MajorModeDefinition> = {};\n let defaultMajorMode = FALLBACK_MAJOR_MODE;\n let hasConfiguredDefault = false;\n for (const source of sources) {\n for (const [name, definition] of Object.entries(source.document.layers ?? {})) {\n layers[name] = { ...parseLayer(name, definition), baseDirectory: source.baseDirectory };\n }\n if (Object.hasOwn(source.document, 'defaultMajorMode')) {\n defaultMajorMode = parseDefaultMajorMode(source.document.defaultMajorMode);\n hasConfiguredDefault = true;\n }\n Object.assign(majorMode, parseMajorModes(source.document.majorMode));\n }\n\n for (const [modeName, definition] of Object.entries(majorMode)) {\n for (const name of definition.layers) {\n if (!layers[name]) {\n throw new Error(`Unknown layer \"${name}\" in majorMode.${modeName} of ${MAJOR_MODES_RELATIVE_PATH}`);\n }\n }\n }\n if (hasConfiguredDefault && !Object.hasOwn(majorMode, defaultMajorMode)) {\n throw new Error(`Unknown default major mode \"${defaultMajorMode}\" in ${MAJOR_MODES_RELATIVE_PATH}`);\n }\n return { layers, defaultMajorMode, majorMode };\n}\n\n/** Finds configuration owned by one package while preserving layer and package order. */\nexport function resolvePackageConfigurations(\n config: MajorModesConfig,\n names: string[],\n packageName: string,\n): ResolvedPackageConfiguration[] {\n const normalizedPackageName = packageName.trim();\n if (!normalizedPackageName) throw new Error('Package name must be a non-empty string');\n const configurations: ResolvedPackageConfiguration[] = [];\n for (const name of names) {\n const layer = config.layers[name];\n if (!layer) throw new Error(`Unknown layer: ${name}`);\n for (const entry of layer.packages ?? []) {\n if (typeof entry === 'string' || entry.config === undefined) continue;\n if (entry.name !== normalizedPackageName && !entry.name.startsWith(`${normalizedPackageName}/`)) continue;\n configurations.push({ layer: name, specifier: entry.name, config: { ...entry.config } });\n }\n }\n return configurations;\n}\n\n/** Resolves one named major mode into its configured layer components. */\nexport function resolveLayers(config: MajorModesConfig, majorMode: string): string[] {\n if (!Object.hasOwn(config.majorMode, majorMode)) {\n throw new Error(\n `Unknown major mode: ${majorMode}. Known major modes: ${Object.keys(config.majorMode).sort().join(', ')}`,\n );\n }\n return [...config.majorMode[majorMode]!.layers];\n}\n\nfunction resolveLocalEntries(\n resolvers: LayerResolvers,\n specifier: string,\n baseDirectory: string,\n): string[] | undefined {\n const resolved = resolvers.localEntries?.(specifier, baseDirectory);\n if (resolved !== undefined) return resolved;\n const single = resolvers.localEntry(specifier, baseDirectory);\n return single ? [single] : undefined;\n}\n\n/** Resolves one layer's extension and package entries to absolute paths. */\nexport function layerEntries(config: MajorModesConfig, name: string, resolvers: LayerResolvers): string[] {\n const layer = config.layers[name];\n if (!layer) throw new Error(`Unknown layer: ${name}`);\n const entries: string[] = [];\n for (const entry of layer.extensions ?? []) {\n if (!isLocalPackageSpecifier(entry)) {\n entries.push(resolvers.ownEntry(entry));\n continue;\n }\n const resolved = resolveLocalEntries(resolvers, entry, layer.baseDirectory);\n if (!resolved?.length) {\n throw new Error(\n `Layer \"${name}\" extension \"${entry}\" does not resolve under ${layer.baseDirectory}. ` +\n 'Point it at a Pi extension file or directory.',\n );\n }\n entries.push(...resolved);\n }\n for (const entry of layer.packages ?? []) {\n const specifier = typeof entry === 'string' ? entry : entry.name;\n const optional = typeof entry === 'string' ? false : entry.optional === true;\n if (isLocalPackageSpecifier(specifier)) {\n const resolved = resolveLocalEntries(resolvers, specifier, layer.baseDirectory);\n if (resolved?.length) entries.push(...resolved);\n else if (!optional) {\n throw new Error(\n `Layer \"${name}\" package \"${specifier}\" does not resolve under ${layer.baseDirectory}. ` +\n 'Point it at an extension file, or a directory whose package.json declares pi.extensions.',\n );\n }\n continue;\n }\n if (optional) {\n let resolved = resolvers.optionalPackageEntries?.(specifier);\n if (resolved === undefined) {\n const single = resolvers.optionalPackageEntry(specifier);\n resolved = single ? [single] : undefined;\n }\n if (resolved) entries.push(...resolved);\n continue;\n }\n const resolved = resolvers.packageEntries?.(specifier) ?? [resolvers.packageEntry(specifier)];\n if (resolved.length === 0) {\n throw new Error(`Layer \"${name}\" package \"${specifier}\" declares no Pi extensions.`);\n }\n entries.push(...resolved);\n }\n return entries;\n}\n\n/** Hook group ids contributed by the selected layers, deduped. */\nexport function layerHookGroups(config: MajorModesConfig, names: string[]): string[] {\n const groups = new Set<string>();\n for (const name of names) {\n for (const group of config.layers[name]?.hookGroups ?? []) groups.add(group);\n }\n return [...groups];\n}\n"],"mappings":"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"}
|
|
@@ -0,0 +1,2 @@
|
|
|
1
|
+
const e=require("../piConfig.cjs"),t=new WeakSet,n=new WeakMap;function r(e){return n.get(e)}function i(r,i={}){if(t.has(r))throw Error(`Pi config adapter is already registered for this host.`);t.add(r),r.on(`session_start`,async(t,r)=>{n.set(r,await e.loadPiConfigAsync({repoRoot:r.cwd,homeDirectory:i.homeDirectory,defaults:i.defaults,programmatic:i.programmatic,environment:i.environment,cli:i.cli,isProjectTrusted:()=>r.isProjectTrusted()}))}),r.on(`session_shutdown`,(e,t)=>{n.delete(t)})}exports.default=i,exports.readPiConfigContext=r;
|
|
2
|
+
//# sourceMappingURL=configExtension.cjs.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"configExtension.cjs","names":["loadPiConfigAsync"],"sources":["../../../src/adapters/pi/configExtension.ts"],"sourcesContent":["import type { ExtensionAPI, ExtensionContext } from '@earendil-works/pi-coding-agent';\nimport type { ConfigAdapterRegistrationOptions, PiConfig } from '../../schemas/config/schema.ts';\nimport { loadPiConfigAsync } from '../piConfig.ts';\n\nconst SESSION_START_EVENT = 'session_start';\nconst SESSION_SHUTDOWN_EVENT = 'session_shutdown';\n\nconst registeredHosts = new WeakSet<ExtensionAPI>();\nconst resolvedConfigs = new WeakMap<ExtensionContext, PiConfig>();\n\nexport function readPiConfigContext(context: ExtensionContext): PiConfig | undefined {\n return resolvedConfigs.get(context);\n}\n\nexport default function registerPiConfigAdapter(\n pi: ExtensionAPI,\n options: ConfigAdapterRegistrationOptions = {},\n): void {\n if (registeredHosts.has(pi)) throw new Error('Pi config adapter is already registered for this host.');\n registeredHosts.add(pi);\n pi.on(SESSION_START_EVENT, async (_event, context) => {\n resolvedConfigs.set(\n context,\n await loadPiConfigAsync({\n repoRoot: context.cwd,\n homeDirectory: options.homeDirectory,\n defaults: options.defaults,\n programmatic: options.programmatic,\n environment: options.environment,\n cli: options.cli,\n isProjectTrusted: () => context.isProjectTrusted(),\n }),\n );\n });\n pi.on(SESSION_SHUTDOWN_EVENT, (_event, context) => {\n resolvedConfigs.delete(context);\n });\n}\n"],"mappings":"mCAOM,EAAkB,IAAI,QACtB,EAAkB,IAAI,QAE5B,SAAgB,EAAoB,EAAiD,CACnF,OAAO,EAAgB,IAAI,CAAO,CACpC,CAEA,SAAwB,EACtB,EACA,EAA4C,CAAC,EACvC,CACN,GAAI,EAAgB,IAAI,CAAE,EAAG,MAAU,MAAM,wDAAwD,EACrG,EAAgB,IAAI,CAAE,EACtB,EAAG,GAAG,gBAAqB,MAAO,EAAQ,IAAY,CACpD,EAAgB,IACd,EACA,MAAMA,EAAAA,kBAAkB,CACtB,SAAU,EAAQ,IAClB,cAAe,EAAQ,cACvB,SAAU,EAAQ,SAClB,aAAc,EAAQ,aACtB,YAAa,EAAQ,YACrB,IAAK,EAAQ,IACb,qBAAwB,EAAQ,iBAAiB,CACnD,CAAC,CACH,CACF,CAAC,EACD,EAAG,GAAG,oBAAyB,EAAQ,IAAY,CACjD,EAAgB,OAAO,CAAO,CAChC,CAAC,CACH"}
|
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
import { ConfigAdapterRegistrationOptions, PiConfig } from "../../schemas/config/schema.cjs";
|
|
2
|
+
import { ExtensionAPI, ExtensionContext } from "@earendil-works/pi-coding-agent";
|
|
3
|
+
//#region src/adapters/pi/configExtension.d.ts
|
|
4
|
+
declare function readPiConfigContext(context: ExtensionContext): PiConfig | undefined;
|
|
5
|
+
declare function registerPiConfigAdapter(pi: ExtensionAPI, options?: ConfigAdapterRegistrationOptions): void;
|
|
6
|
+
//#endregion
|
|
7
|
+
export { registerPiConfigAdapter as default, readPiConfigContext };
|
|
8
|
+
//# sourceMappingURL=configExtension.d.cts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"configExtension.d.cts","names":[],"sources":["../../../src/adapters/pi/configExtension.ts"],"mappings":";;;iBAUgB,oBAAoB,SAAS,mBAAmB;iBAIxC,wBACtB,IAAI,cACJ,UAAS"}
|
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
import { ConfigAdapterRegistrationOptions, PiConfig } from "../../schemas/config/schema.mjs";
|
|
2
|
+
import { ExtensionAPI, ExtensionContext } from "@earendil-works/pi-coding-agent";
|
|
3
|
+
//#region src/adapters/pi/configExtension.d.ts
|
|
4
|
+
declare function readPiConfigContext(context: ExtensionContext): PiConfig | undefined;
|
|
5
|
+
declare function registerPiConfigAdapter(pi: ExtensionAPI, options?: ConfigAdapterRegistrationOptions): void;
|
|
6
|
+
//#endregion
|
|
7
|
+
export { registerPiConfigAdapter as default, readPiConfigContext };
|
|
8
|
+
//# sourceMappingURL=configExtension.d.mts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"configExtension.d.mts","names":[],"sources":["../../../src/adapters/pi/configExtension.ts"],"mappings":";;;iBAUgB,oBAAoB,SAAS,mBAAmB;iBAIxC,wBACtB,IAAI,cACJ,UAAS"}
|
|
@@ -0,0 +1,2 @@
|
|
|
1
|
+
import{loadPiConfigAsync as e}from"../piConfig.mjs";const t=new WeakSet,n=new WeakMap;function r(e){return n.get(e)}function i(r,i={}){if(t.has(r))throw Error(`Pi config adapter is already registered for this host.`);t.add(r),r.on(`session_start`,async(t,r)=>{n.set(r,await e({repoRoot:r.cwd,homeDirectory:i.homeDirectory,defaults:i.defaults,programmatic:i.programmatic,environment:i.environment,cli:i.cli,isProjectTrusted:()=>r.isProjectTrusted()}))}),r.on(`session_shutdown`,(e,t)=>{n.delete(t)})}export{i as default,r as readPiConfigContext};
|
|
2
|
+
//# sourceMappingURL=configExtension.mjs.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"configExtension.mjs","names":[],"sources":["../../../src/adapters/pi/configExtension.ts"],"sourcesContent":["import type { ExtensionAPI, ExtensionContext } from '@earendil-works/pi-coding-agent';\nimport type { ConfigAdapterRegistrationOptions, PiConfig } from '../../schemas/config/schema.ts';\nimport { loadPiConfigAsync } from '../piConfig.ts';\n\nconst SESSION_START_EVENT = 'session_start';\nconst SESSION_SHUTDOWN_EVENT = 'session_shutdown';\n\nconst registeredHosts = new WeakSet<ExtensionAPI>();\nconst resolvedConfigs = new WeakMap<ExtensionContext, PiConfig>();\n\nexport function readPiConfigContext(context: ExtensionContext): PiConfig | undefined {\n return resolvedConfigs.get(context);\n}\n\nexport default function registerPiConfigAdapter(\n pi: ExtensionAPI,\n options: ConfigAdapterRegistrationOptions = {},\n): void {\n if (registeredHosts.has(pi)) throw new Error('Pi config adapter is already registered for this host.');\n registeredHosts.add(pi);\n pi.on(SESSION_START_EVENT, async (_event, context) => {\n resolvedConfigs.set(\n context,\n await loadPiConfigAsync({\n repoRoot: context.cwd,\n homeDirectory: options.homeDirectory,\n defaults: options.defaults,\n programmatic: options.programmatic,\n environment: options.environment,\n cli: options.cli,\n isProjectTrusted: () => context.isProjectTrusted(),\n }),\n );\n });\n pi.on(SESSION_SHUTDOWN_EVENT, (_event, context) => {\n resolvedConfigs.delete(context);\n });\n}\n"],"mappings":"oDAIA,MAGM,EAAkB,IAAI,QACtB,EAAkB,IAAI,QAE5B,SAAgB,EAAoB,EAAiD,CACnF,OAAO,EAAgB,IAAI,CAAO,CACpC,CAEA,SAAwB,EACtB,EACA,EAA4C,CAAC,EACvC,CACN,GAAI,EAAgB,IAAI,CAAE,EAAG,MAAU,MAAM,wDAAwD,EACrG,EAAgB,IAAI,CAAE,EACtB,EAAG,GAAG,gBAAqB,MAAO,EAAQ,IAAY,CACpD,EAAgB,IACd,EACA,MAAM,EAAkB,CACtB,SAAU,EAAQ,IAClB,cAAe,EAAQ,cACvB,SAAU,EAAQ,SAClB,aAAc,EAAQ,aACtB,YAAa,EAAQ,YACrB,IAAK,EAAQ,IACb,qBAAwB,EAAQ,iBAAiB,CACnD,CAAC,CACH,CACF,CAAC,EACD,EAAG,GAAG,oBAAyB,EAAQ,IAAY,CACjD,EAAgB,OAAO,CAAO,CAChC,CAAC,CACH"}
|
|
@@ -0,0 +1,2 @@
|
|
|
1
|
+
const e=require("../config.cjs"),t=require("./helpContribution.cjs"),n=require("../piConfig.cjs"),r=new WeakSet,i=new WeakMap;function a(e){return i.get(e)}function o(a,o={}){if(r.has(a))throw Error(`Doom config adapter is already registered for this host.`);r.add(a);let s=t.registerDoomConfigHelp(a);a.on(`session_start`,async(t,r)=>{i.set(r,await n.loadPiConfigAsync({repoRoot:r.cwd,homeDirectory:o.homeDirectory,defaults:o.defaults,overlay:{...await e.loadDoomConfigAsync(r.cwd,o.homeDirectory)},programmatic:o.programmatic,environment:o.environment,cli:o.cli,isProjectTrusted:()=>r.isProjectTrusted()}))}),a.on(`session_shutdown`,(e,t)=>{i.delete(t),s.dispose()})}exports.default=o,exports.registerDoomConfigAdapter=o,exports.readDoomConfigContext=a;
|
|
2
|
+
//# sourceMappingURL=doomConfigExtension.cjs.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"doomConfigExtension.cjs","names":["registerDoomConfigHelp","loadPiConfigAsync","loadDoomConfigAsync"],"sources":["../../../src/adapters/pi/doomConfigExtension.ts"],"sourcesContent":["import type { ExtensionAPI, ExtensionContext } from '@earendil-works/pi-coding-agent';\nimport type { ConfigAdapterRegistrationOptions, PiConfig } from '../../schemas/config/schema.ts';\nimport { loadDoomConfigAsync } from '../config.ts';\nimport { loadPiConfigAsync } from '../piConfig.ts';\nimport { registerDoomConfigHelp } from './helpContribution.ts';\n\nconst SESSION_START_EVENT = 'session_start';\nconst SESSION_SHUTDOWN_EVENT = 'session_shutdown';\n\nconst registeredHosts = new WeakSet<ExtensionAPI>();\nconst resolvedConfigs = new WeakMap<ExtensionContext, PiConfig>();\n\nexport function readDoomConfigContext(context: ExtensionContext): PiConfig | undefined {\n return resolvedConfigs.get(context);\n}\n\nexport function registerDoomConfigAdapter(pi: ExtensionAPI, options: ConfigAdapterRegistrationOptions = {}): void {\n if (registeredHosts.has(pi)) throw new Error('Doom config adapter is already registered for this host.');\n registeredHosts.add(pi);\n const help = registerDoomConfigHelp(pi);\n pi.on(SESSION_START_EVENT, async (_event, context) => {\n resolvedConfigs.set(\n context,\n await loadPiConfigAsync({\n repoRoot: context.cwd,\n homeDirectory: options.homeDirectory,\n defaults: options.defaults,\n overlay: { ...(await loadDoomConfigAsync(context.cwd, options.homeDirectory)) },\n programmatic: options.programmatic,\n environment: options.environment,\n cli: options.cli,\n isProjectTrusted: () => context.isProjectTrusted(),\n }),\n );\n });\n pi.on(SESSION_SHUTDOWN_EVENT, (_event, context) => {\n resolvedConfigs.delete(context);\n help.dispose();\n });\n}\n\nexport default registerDoomConfigAdapter;\n"],"mappings":"kGASM,EAAkB,IAAI,QACtB,EAAkB,IAAI,QAE5B,SAAgB,EAAsB,EAAiD,CACrF,OAAO,EAAgB,IAAI,CAAO,CACpC,CAEA,SAAgB,EAA0B,EAAkB,EAA4C,CAAC,EAAS,CAChH,GAAI,EAAgB,IAAI,CAAE,EAAG,MAAU,MAAM,0DAA0D,EACvG,EAAgB,IAAI,CAAE,EACtB,IAAM,EAAOA,EAAAA,uBAAuB,CAAE,EACtC,EAAG,GAAG,gBAAqB,MAAO,EAAQ,IAAY,CACpD,EAAgB,IACd,EACA,MAAMC,EAAAA,kBAAkB,CACtB,SAAU,EAAQ,IAClB,cAAe,EAAQ,cACvB,SAAU,EAAQ,SAClB,QAAS,CAAE,GAAI,MAAMC,EAAAA,oBAAoB,EAAQ,IAAK,EAAQ,aAAa,CAAG,EAC9E,aAAc,EAAQ,aACtB,YAAa,EAAQ,YACrB,IAAK,EAAQ,IACb,qBAAwB,EAAQ,iBAAiB,CACnD,CAAC,CACH,CACF,CAAC,EACD,EAAG,GAAG,oBAAyB,EAAQ,IAAY,CACjD,EAAgB,OAAO,CAAO,EAC9B,EAAK,QAAQ,CACf,CAAC,CACH"}
|
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
import { ConfigAdapterRegistrationOptions, PiConfig } from "../../schemas/config/schema.cjs";
|
|
2
|
+
import { ExtensionAPI, ExtensionContext } from "@earendil-works/pi-coding-agent";
|
|
3
|
+
//#region src/adapters/pi/doomConfigExtension.d.ts
|
|
4
|
+
declare function readDoomConfigContext(context: ExtensionContext): PiConfig | undefined;
|
|
5
|
+
declare function registerDoomConfigAdapter(pi: ExtensionAPI, options?: ConfigAdapterRegistrationOptions): void;
|
|
6
|
+
//#endregion
|
|
7
|
+
export { registerDoomConfigAdapter as default, registerDoomConfigAdapter, readDoomConfigContext };
|
|
8
|
+
//# sourceMappingURL=doomConfigExtension.d.cts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"doomConfigExtension.d.cts","names":[],"sources":["../../../src/adapters/pi/doomConfigExtension.ts"],"mappings":";;;iBAYgB,sBAAsB,SAAS,mBAAmB;iBAIlD,0BAA0B,IAAI,cAAc,UAAS"}
|
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
import { ConfigAdapterRegistrationOptions, PiConfig } from "../../schemas/config/schema.mjs";
|
|
2
|
+
import { ExtensionAPI, ExtensionContext } from "@earendil-works/pi-coding-agent";
|
|
3
|
+
//#region src/adapters/pi/doomConfigExtension.d.ts
|
|
4
|
+
declare function readDoomConfigContext(context: ExtensionContext): PiConfig | undefined;
|
|
5
|
+
declare function registerDoomConfigAdapter(pi: ExtensionAPI, options?: ConfigAdapterRegistrationOptions): void;
|
|
6
|
+
//#endregion
|
|
7
|
+
export { registerDoomConfigAdapter as default, registerDoomConfigAdapter, readDoomConfigContext };
|
|
8
|
+
//# sourceMappingURL=doomConfigExtension.d.mts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"doomConfigExtension.d.mts","names":[],"sources":["../../../src/adapters/pi/doomConfigExtension.ts"],"mappings":";;;iBAYgB,sBAAsB,SAAS,mBAAmB;iBAIlD,0BAA0B,IAAI,cAAc,UAAS"}
|
|
@@ -0,0 +1,2 @@
|
|
|
1
|
+
import{loadDoomConfigAsync as e}from"../config.mjs";import{registerDoomConfigHelp as t}from"./helpContribution.mjs";import{loadPiConfigAsync as n}from"../piConfig.mjs";const r=new WeakSet,i=new WeakMap;function a(e){return i.get(e)}function o(a,o={}){if(r.has(a))throw Error(`Doom config adapter is already registered for this host.`);r.add(a);let s=t(a);a.on(`session_start`,async(t,r)=>{i.set(r,await n({repoRoot:r.cwd,homeDirectory:o.homeDirectory,defaults:o.defaults,overlay:{...await e(r.cwd,o.homeDirectory)},programmatic:o.programmatic,environment:o.environment,cli:o.cli,isProjectTrusted:()=>r.isProjectTrusted()}))}),a.on(`session_shutdown`,(e,t)=>{i.delete(t),s.dispose()})}export{o as default,o as registerDoomConfigAdapter,a as readDoomConfigContext};
|
|
2
|
+
//# sourceMappingURL=doomConfigExtension.mjs.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"doomConfigExtension.mjs","names":[],"sources":["../../../src/adapters/pi/doomConfigExtension.ts"],"sourcesContent":["import type { ExtensionAPI, ExtensionContext } from '@earendil-works/pi-coding-agent';\nimport type { ConfigAdapterRegistrationOptions, PiConfig } from '../../schemas/config/schema.ts';\nimport { loadDoomConfigAsync } from '../config.ts';\nimport { loadPiConfigAsync } from '../piConfig.ts';\nimport { registerDoomConfigHelp } from './helpContribution.ts';\n\nconst SESSION_START_EVENT = 'session_start';\nconst SESSION_SHUTDOWN_EVENT = 'session_shutdown';\n\nconst registeredHosts = new WeakSet<ExtensionAPI>();\nconst resolvedConfigs = new WeakMap<ExtensionContext, PiConfig>();\n\nexport function readDoomConfigContext(context: ExtensionContext): PiConfig | undefined {\n return resolvedConfigs.get(context);\n}\n\nexport function registerDoomConfigAdapter(pi: ExtensionAPI, options: ConfigAdapterRegistrationOptions = {}): void {\n if (registeredHosts.has(pi)) throw new Error('Doom config adapter is already registered for this host.');\n registeredHosts.add(pi);\n const help = registerDoomConfigHelp(pi);\n pi.on(SESSION_START_EVENT, async (_event, context) => {\n resolvedConfigs.set(\n context,\n await loadPiConfigAsync({\n repoRoot: context.cwd,\n homeDirectory: options.homeDirectory,\n defaults: options.defaults,\n overlay: { ...(await loadDoomConfigAsync(context.cwd, options.homeDirectory)) },\n programmatic: options.programmatic,\n environment: options.environment,\n cli: options.cli,\n isProjectTrusted: () => context.isProjectTrusted(),\n }),\n );\n });\n pi.on(SESSION_SHUTDOWN_EVENT, (_event, context) => {\n resolvedConfigs.delete(context);\n help.dispose();\n });\n}\n\nexport default registerDoomConfigAdapter;\n"],"mappings":"wKAMA,MAGM,EAAkB,IAAI,QACtB,EAAkB,IAAI,QAE5B,SAAgB,EAAsB,EAAiD,CACrF,OAAO,EAAgB,IAAI,CAAO,CACpC,CAEA,SAAgB,EAA0B,EAAkB,EAA4C,CAAC,EAAS,CAChH,GAAI,EAAgB,IAAI,CAAE,EAAG,MAAU,MAAM,0DAA0D,EACvG,EAAgB,IAAI,CAAE,EACtB,IAAM,EAAO,EAAuB,CAAE,EACtC,EAAG,GAAG,gBAAqB,MAAO,EAAQ,IAAY,CACpD,EAAgB,IACd,EACA,MAAM,EAAkB,CACtB,SAAU,EAAQ,IAClB,cAAe,EAAQ,cACvB,SAAU,EAAQ,SAClB,QAAS,CAAE,GAAI,MAAM,EAAoB,EAAQ,IAAK,EAAQ,aAAa,CAAG,EAC9E,aAAc,EAAQ,aACtB,YAAa,EAAQ,YACrB,IAAK,EAAQ,IACb,qBAAwB,EAAQ,iBAAiB,CACnD,CAAC,CACH,CACF,CAAC,EACD,EAAG,GAAG,oBAAyB,EAAQ,IAAY,CACjD,EAAgB,OAAO,CAAO,EAC9B,EAAK,QAAQ,CACf,CAAC,CACH"}
|
|
@@ -0,0 +1,2 @@
|
|
|
1
|
+
let e=require("@agimon-ai/doompi-extension-contracts/help");function t(t){return(0,e.registerDoomHelpContribution)(t,{source:`@agimon-ai/doompi-config`,moduleUrl:require("url").pathToFileURL(__filename).href,skills:[{name:`doompi-config-help`,description:`Configure Doom Pi modes, domains, profiles, runtime settings, and package layers.`}]})}exports.registerDoomConfigHelp=t;
|
|
2
|
+
//# sourceMappingURL=helpContribution.cjs.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"helpContribution.cjs","names":["registerDoomHelpContribution"],"sources":["../../../src/adapters/pi/helpContribution.ts"],"sourcesContent":["import type { DoomExtensionHost } from '@agimon-ai/doompi-extension-contracts/config';\nimport {\n type DoomHelpContributionHandle,\n registerDoomHelpContribution,\n} from '@agimon-ai/doompi-extension-contracts/help';\nimport type { ExtensionAPI } from '@earendil-works/pi-coding-agent';\n\nexport function registerDoomConfigHelp(pi: ExtensionAPI): DoomHelpContributionHandle {\n return registerDoomHelpContribution(pi as unknown as DoomExtensionHost, {\n source: '@agimon-ai/doompi-config',\n moduleUrl: import.meta.url,\n skills: [\n {\n name: 'doompi-config-help',\n description: 'Configure Doom Pi modes, domains, profiles, runtime settings, and package layers.',\n },\n ],\n });\n}\n"],"mappings":"4DAOA,SAAgB,EAAuB,EAA8C,CACnF,OAAA,EAAOA,EAAAA,6BAAAA,CAA6B,EAAoC,CACtE,OAAQ,2BACR,UAAA,QAAA,KAAA,CAAA,CAAA,cAAA,UAAA,CAAA,CAAA,KACA,OAAQ,CACN,CACE,KAAM,qBACN,YAAa,mFACf,CACF,CACF,CAAC,CACH"}
|
|
@@ -0,0 +1,2 @@
|
|
|
1
|
+
import{registerDoomHelpContribution as e}from"@agimon-ai/doompi-extension-contracts/help";function t(t){return e(t,{source:`@agimon-ai/doompi-config`,moduleUrl:import.meta.url,skills:[{name:`doompi-config-help`,description:`Configure Doom Pi modes, domains, profiles, runtime settings, and package layers.`}]})}export{t as registerDoomConfigHelp};
|
|
2
|
+
//# sourceMappingURL=helpContribution.mjs.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"helpContribution.mjs","names":[],"sources":["../../../src/adapters/pi/helpContribution.ts"],"sourcesContent":["import type { DoomExtensionHost } from '@agimon-ai/doompi-extension-contracts/config';\nimport {\n type DoomHelpContributionHandle,\n registerDoomHelpContribution,\n} from '@agimon-ai/doompi-extension-contracts/help';\nimport type { ExtensionAPI } from '@earendil-works/pi-coding-agent';\n\nexport function registerDoomConfigHelp(pi: ExtensionAPI): DoomHelpContributionHandle {\n return registerDoomHelpContribution(pi as unknown as DoomExtensionHost, {\n source: '@agimon-ai/doompi-config',\n moduleUrl: import.meta.url,\n skills: [\n {\n name: 'doompi-config-help',\n description: 'Configure Doom Pi modes, domains, profiles, runtime settings, and package layers.',\n },\n ],\n });\n}\n"],"mappings":"0FAOA,SAAgB,EAAuB,EAA8C,CACnF,OAAO,EAA6B,EAAoC,CACtE,OAAQ,2BACR,UAAW,YAAY,IACvB,OAAQ,CACN,CACE,KAAM,qBACN,YAAa,mFACf,CACF,CACF,CAAC,CACH"}
|
|
@@ -0,0 +1,2 @@
|
|
|
1
|
+
const e=require("../config.cjs"),t=require("../harnessStore.cjs"),n=require("./helpContribution.cjs");let r=require("@agimon-ai/doompi-telemetry");const i=`doom-pi:config:v1`,a=new WeakMap;function o(e){if(typeof e!=`object`||!e)return!1;let t=e;return t.version===1&&typeof t.majorMode==`string`&&Array.isArray(t.domains)&&t.domains.every(e=>typeof e==`string`)&&(t.profile===void 0||typeof t.profile==`string`)}function s(e){for(let t=e.length-1;t>=0;--t){let n=e[t];if(n?.type===`custom`&&n.customType===`doom-pi:config:v1`&&o(n.data))return n.data}}function c(e){if(typeof e!=`object`||!e||Object.isFrozen(e))return e;for(let t of Object.values(e))c(t);return Object.freeze(e)}function l(e){return s(e.sessionManager.getBranch())}function u(e){let n=t.getHarnessState(),r=l(e);return{harness:r?{...n,majorMode:r.majorMode,domains:[...r.domains],profile:r.profile}:n,requiresRelaunch:!!(r&&(r.majorMode!==n.majorMode||r.profile!==n.profile||r.domains.join(`,`)!==n.domains.join(`,`))),root:n.root}}function d(t){let{harness:n,requiresRelaunch:r,root:i}=u(t);return c({settings:e.loadDoomConfig(i??t.cwd),harness:n,requiresRelaunch:r})}async function f(t){let{harness:n,requiresRelaunch:r,root:i}=u(t);return c({settings:await e.loadDoomConfigAsync(i??t.cwd),harness:n,requiresRelaunch:r})}function p(e,t){e.appendEntry(i,t)}function m(e,t){let n={context:t,generation:Symbol(`doom-config-context`)};return a.set(e.sessionManager,n),()=>{a.get(e.sessionManager)?.generation===n.generation&&a.delete(e.sessionManager)}}function h(e){let t=a.get(e.sessionManager);if(!t)throw Error(`Doom config context is unavailable. Load @agimon-ai/doompi-config/pi.`);return t.context}const g=e=>{let t=n.registerDoomConfigHelp(e),i,a;e.on(`session_start`,async(e,t)=>{i?.();let n=await f(t);i=m(t,n),a??=(0,r.createDoomTelemetry)({serviceName:`doom-config`,packageName:`@agimon-ai/doompi-config`,cwd:t.cwd,env:process.env,enableLogs:!0,enableTraces:!0}),a.recordEvent(`doom_config.context_bound`,{"config.major_mode":n.harness.majorMode,"config.domain_count":n.harness.domains.length,"config.has_profile":n.harness.profile!==void 0,"config.requires_relaunch":n.requiresRelaunch})}),e.on(`session_shutdown`,async()=>{i=void 0;try{await a?.shutdown()}finally{a=void 0,t.dispose()}})};exports.DOOM_CONFIG_ENTRY_TYPE=i,exports.appendDoomConfigSelection=p,exports.createDoomConfigContext=d,exports.createDoomConfigContextAsync=f,exports.doomConfigExtension=g,exports.provideDoomConfigContext=m,exports.readDoomConfigSelection=l,exports.requireDoomConfigContext=h;
|
|
2
|
+
//# sourceMappingURL=piContext.cjs.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"piContext.cjs","names":["getHarnessState","loadDoomConfig","loadDoomConfigAsync","registerDoomConfigHelp","createDoomTelemetry"],"sources":["../../../src/adapters/pi/piContext.ts"],"sourcesContent":["import { createDoomTelemetry, type DoomTelemetry } from '@agimon-ai/doompi-telemetry';\nimport type { ExtensionAPI, ExtensionContext, ExtensionFactory, SessionEntry } from '@earendil-works/pi-coding-agent';\nimport type { DeepReadonly, DoomConfigContext, HarnessState } from '../../types/config.ts';\nimport { loadDoomConfig, loadDoomConfigAsync } from '../config.ts';\nimport { getHarnessState } from '../harnessStore.ts';\nimport { registerDoomConfigHelp } from './helpContribution.ts';\n\nexport const DOOM_CONFIG_ENTRY_TYPE = 'doom-pi:config:v1';\n\nexport interface DoomConfigSelection {\n readonly version: 1;\n readonly majorMode: string;\n readonly domains: readonly string[];\n readonly profile?: string;\n}\n\ninterface ConfigBinding {\n readonly context: DoomConfigContext;\n readonly generation: symbol;\n}\n\nconst configBindings = new WeakMap<ExtensionContext['sessionManager'], ConfigBinding>();\n\nfunction isSelection(value: unknown): value is DoomConfigSelection {\n if (typeof value !== 'object' || value === null) return false;\n const selection = value as Partial<DoomConfigSelection>;\n return (\n selection.version === 1 &&\n typeof selection.majorMode === 'string' &&\n Array.isArray(selection.domains) &&\n selection.domains.every((domain) => typeof domain === 'string') &&\n (selection.profile === undefined || typeof selection.profile === 'string')\n );\n}\n\nfunction branchSelection(entries: readonly SessionEntry[]): DoomConfigSelection | undefined {\n for (let index = entries.length - 1; index >= 0; index -= 1) {\n const entry = entries[index];\n if (entry?.type === 'custom' && entry.customType === DOOM_CONFIG_ENTRY_TYPE && isSelection(entry.data)) {\n return entry.data;\n }\n }\n return undefined;\n}\n\nfunction deepFreeze<TValue>(value: TValue): DeepReadonly<TValue> {\n if (typeof value !== 'object' || value === null || Object.isFrozen(value)) {\n return value as DeepReadonly<TValue>;\n }\n for (const child of Object.values(value)) deepFreeze(child);\n return Object.freeze(value) as DeepReadonly<TValue>;\n}\n\nexport function readDoomConfigSelection(\n ctx: Pick<ExtensionContext, 'sessionManager'>,\n): DoomConfigSelection | undefined {\n return branchSelection(ctx.sessionManager.getBranch());\n}\n\nfunction resolveContextState(ctx: Pick<ExtensionContext, 'sessionManager'>): {\n harness: HarnessState;\n requiresRelaunch: boolean;\n root: string | undefined;\n} {\n const bootstrap = getHarnessState();\n const selection = readDoomConfigSelection(ctx);\n const harness: HarnessState = selection\n ? { ...bootstrap, majorMode: selection.majorMode, domains: [...selection.domains], profile: selection.profile }\n : bootstrap;\n const requiresRelaunch = Boolean(\n selection &&\n (selection.majorMode !== bootstrap.majorMode ||\n selection.profile !== bootstrap.profile ||\n selection.domains.join(',') !== bootstrap.domains.join(',')),\n );\n return { harness, requiresRelaunch, root: bootstrap.root };\n}\n\nexport function createDoomConfigContext(ctx: Pick<ExtensionContext, 'cwd' | 'sessionManager'>): DoomConfigContext {\n const { harness, requiresRelaunch, root } = resolveContextState(ctx);\n return deepFreeze({ settings: loadDoomConfig(root ?? ctx.cwd), harness, requiresRelaunch });\n}\n\nexport async function createDoomConfigContextAsync(\n ctx: Pick<ExtensionContext, 'cwd' | 'sessionManager'>,\n): Promise<DoomConfigContext> {\n const { harness, requiresRelaunch, root } = resolveContextState(ctx);\n const settings = await loadDoomConfigAsync(root ?? ctx.cwd);\n return deepFreeze({ settings, harness, requiresRelaunch });\n}\n\nexport function appendDoomConfigSelection(pi: Pick<ExtensionAPI, 'appendEntry'>, selection: DoomConfigSelection): void {\n pi.appendEntry(DOOM_CONFIG_ENTRY_TYPE, selection);\n}\n\nexport function provideDoomConfigContext(\n ctx: Pick<ExtensionContext, 'sessionManager'>,\n context: DoomConfigContext,\n): () => void {\n const binding = { context, generation: Symbol('doom-config-context') };\n configBindings.set(ctx.sessionManager, binding);\n return () => {\n if (configBindings.get(ctx.sessionManager)?.generation === binding.generation) {\n configBindings.delete(ctx.sessionManager);\n }\n };\n}\n\nexport function requireDoomConfigContext(ctx: Pick<ExtensionContext, 'sessionManager'>): DoomConfigContext {\n const binding = configBindings.get(ctx.sessionManager);\n if (!binding) throw new Error('Doom config context is unavailable. Load @agimon-ai/doompi-config/pi.');\n return binding.context;\n}\n\nexport const doomConfigExtension: ExtensionFactory = (pi) => {\n const help = registerDoomConfigHelp(pi);\n let dispose: (() => void) | undefined;\n let telemetry: DoomTelemetry | undefined;\n pi.on('session_start', async (_event, ctx) => {\n dispose?.();\n const context = await createDoomConfigContextAsync(ctx);\n dispose = provideDoomConfigContext(ctx, context);\n telemetry ??= createDoomTelemetry({\n serviceName: 'doom-config',\n packageName: '@agimon-ai/doompi-config',\n cwd: ctx.cwd,\n env: process.env,\n enableLogs: true,\n enableTraces: true,\n });\n // Binding is startup-critical; exporting telemetry is not. Do not make\n // later session_start consumers wait for endpoint discovery or health checks.\n void telemetry.recordEvent('doom_config.context_bound', {\n 'config.major_mode': context.harness.majorMode,\n 'config.domain_count': context.harness.domains.length,\n 'config.has_profile': context.harness.profile !== undefined,\n 'config.requires_relaunch': context.requiresRelaunch,\n });\n });\n pi.on('session_shutdown', async () => {\n // Other extensions consume config during shutdown. Keep the WeakMap entry\n // alive for that phase and let it disappear with Pi's sessionManager.\n dispose = undefined;\n try {\n await telemetry?.shutdown();\n } finally {\n telemetry = undefined;\n help.dispose();\n }\n });\n};\n"],"mappings":"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"}
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
import { DoomConfigContext } from "../../types/config.cjs";
|
|
2
|
+
import { ExtensionAPI, ExtensionContext, ExtensionFactory } from "@earendil-works/pi-coding-agent";
|
|
3
|
+
//#region src/adapters/pi/piContext.d.ts
|
|
4
|
+
declare const DOOM_CONFIG_ENTRY_TYPE = "doom-pi:config:v1";
|
|
5
|
+
interface DoomConfigSelection {
|
|
6
|
+
readonly version: 1;
|
|
7
|
+
readonly majorMode: string;
|
|
8
|
+
readonly domains: readonly string[];
|
|
9
|
+
readonly profile?: string;
|
|
10
|
+
}
|
|
11
|
+
declare function readDoomConfigSelection(ctx: Pick<ExtensionContext, 'sessionManager'>): DoomConfigSelection | undefined;
|
|
12
|
+
declare function createDoomConfigContext(ctx: Pick<ExtensionContext, 'cwd' | 'sessionManager'>): DoomConfigContext;
|
|
13
|
+
declare function createDoomConfigContextAsync(ctx: Pick<ExtensionContext, 'cwd' | 'sessionManager'>): Promise<DoomConfigContext>;
|
|
14
|
+
declare function appendDoomConfigSelection(pi: Pick<ExtensionAPI, 'appendEntry'>, selection: DoomConfigSelection): void;
|
|
15
|
+
declare function provideDoomConfigContext(ctx: Pick<ExtensionContext, 'sessionManager'>, context: DoomConfigContext): () => void;
|
|
16
|
+
declare function requireDoomConfigContext(ctx: Pick<ExtensionContext, 'sessionManager'>): DoomConfigContext;
|
|
17
|
+
declare const doomConfigExtension: ExtensionFactory;
|
|
18
|
+
//#endregion
|
|
19
|
+
export { DOOM_CONFIG_ENTRY_TYPE, DoomConfigSelection, appendDoomConfigSelection, createDoomConfigContext, createDoomConfigContextAsync, doomConfigExtension, provideDoomConfigContext, readDoomConfigSelection, requireDoomConfigContext };
|
|
20
|
+
//# sourceMappingURL=piContext.d.cts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"piContext.d.cts","names":[],"sources":["../../../src/adapters/pi/piContext.ts"],"mappings":";;;cAOa;UAEI;WACN;WACA;WACA;WACA;;iBAwCK,wBACd,KAAK,KAAK,sCACT;iBAuBa,wBAAwB,KAAK,KAAK,8CAA8C;iBAK1E,6BACpB,KAAK,KAAK,8CACT,QAAQ;iBAMK,0BAA0B,IAAI,KAAK,8BAA8B,WAAW;iBAI5E,yBACd,KAAK,KAAK,qCACV,SAAS;iBAWK,yBAAyB,KAAK,KAAK,sCAAsC;cAM5E,qBAAqB"}
|