@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,178 @@
|
|
|
1
|
+
const e=require("../_virtual/_rolldown/runtime.cjs"),t=require("./config.cjs");let n=require("node:crypto"),r=require("node:fs");r=e.__toESM(r,1);let i=require("node:path");i=e.__toESM(i,1);let a=require("node:os");a=e.__toESM(a,1);const o=`utf8`,s=`EEXIST`,c=`ENOENT`,l=[`config.yaml`,`modes.yaml`,`domains.yaml`,`profiles.yaml`],u={"config.yaml":`projectTrust: ask
|
|
2
|
+
|
|
3
|
+
# Autonomous voice is opt-in and uses an explicitly configured Pi model.
|
|
4
|
+
# voice:
|
|
5
|
+
# autoCapture:
|
|
6
|
+
# model: provider/model-id
|
|
7
|
+
# startPhrases:
|
|
8
|
+
# - hey doom
|
|
9
|
+
# stopPhrases:
|
|
10
|
+
# - stop speaking
|
|
11
|
+
# utteranceIdleMs: 3000
|
|
12
|
+
# tts:
|
|
13
|
+
# engine: macos-say
|
|
14
|
+
# voice: Samantha
|
|
15
|
+
# rate: 190
|
|
16
|
+
`,"modes.yaml":`# A layer is a reusable named bundle of packages, built-in or local extensions,
|
|
17
|
+
# and hook groups. Major modes below choose which layers load together for a session.
|
|
18
|
+
#
|
|
19
|
+
# Layers and modes defined here apply to every repository. A repository's own
|
|
20
|
+
# .doom/modes.yaml is read after this file and replaces any layer or mode of the
|
|
21
|
+
# same name, so a repository can override one entry without restating the rest.
|
|
22
|
+
#
|
|
23
|
+
# Add a layer by giving it a unique name under layers. Local Pi scripts belong
|
|
24
|
+
# under extensions, while installed Pi packages belong under packages:
|
|
25
|
+
# review-tools:
|
|
26
|
+
# extensions:
|
|
27
|
+
# - './extensions/local-review.ts'
|
|
28
|
+
# packages:
|
|
29
|
+
# - '@scope/review-extension'
|
|
30
|
+
# A bare extension name selects a DoomPi built-in. A path beginning with ./ or
|
|
31
|
+
# ../ loads a custom script or extension directory. A bare package loads its
|
|
32
|
+
# ordered package.json pi.extensions entries, while an exported subpath selects
|
|
33
|
+
# one adapter. Relative paths resolve beside this file here (~/.pi/.doom), or
|
|
34
|
+
# from the repository root in .doom/modes.yaml.
|
|
35
|
+
#
|
|
36
|
+
# Use a package mapping when that package accepts configuration. Configuration
|
|
37
|
+
# belongs under the package entry that consumes it, not beside packages.
|
|
38
|
+
layers:
|
|
39
|
+
team:
|
|
40
|
+
packages:
|
|
41
|
+
- name: '@agimon-ai/doompi-team'
|
|
42
|
+
# Optional Team configuration. Uncomment and choose models available to Pi.
|
|
43
|
+
# config:
|
|
44
|
+
# models:
|
|
45
|
+
# - model: openai-codex/gpt-5.6-luna
|
|
46
|
+
# thinking: xhigh
|
|
47
|
+
# # Tool names excluded from subagents launched by this package. These
|
|
48
|
+
# # remove model-visible tools while preserving hidden team transport.
|
|
49
|
+
# excludeTools: [ask_user_question, intercom, subagent]
|
|
50
|
+
task:
|
|
51
|
+
packages:
|
|
52
|
+
- '@agimon-ai/doompi-task'
|
|
53
|
+
runner:
|
|
54
|
+
packages:
|
|
55
|
+
- '@agimon-ai/doompi-runner'
|
|
56
|
+
ask-user:
|
|
57
|
+
packages:
|
|
58
|
+
- '@agimon-ai/doompi-user-feedback'
|
|
59
|
+
# A major mode explains when it should be used and names its ordered layers.
|
|
60
|
+
# Add another entry under majorMode, then select it with
|
|
61
|
+
# doompi --major-mode <name>. Change defaultMajorMode to make it the default.
|
|
62
|
+
defaultMajorMode: copilot
|
|
63
|
+
majorMode:
|
|
64
|
+
minimal:
|
|
65
|
+
description: Lean mode with Team delegation and persistent tasks.
|
|
66
|
+
layers: [team, task]
|
|
67
|
+
copilot:
|
|
68
|
+
description: General-purpose coding mode with Team delegation, persistent tasks, supervised commands, and structured user feedback.
|
|
69
|
+
layers: [team, task, runner, ask-user]
|
|
70
|
+
# review:
|
|
71
|
+
# description: Focused review mode for inspecting changes and reporting risks.
|
|
72
|
+
# layers: [team, task, ask-user]
|
|
73
|
+
`,"domains.yaml":`# Plugins are named once in this catalog, then selected by one or more domains.
|
|
74
|
+
# DoomPi automatically inspects personal and repository Codex marketplaces.
|
|
75
|
+
# Each configured root may also be a folder whose direct children are plugins;
|
|
76
|
+
# use roots: [plugins] to discover a repository plugin folder without one entry
|
|
77
|
+
# per plugin. Discovery never scans recursively.
|
|
78
|
+
defaultDomains: [default]
|
|
79
|
+
plugins:
|
|
80
|
+
roots: []
|
|
81
|
+
entries: {}
|
|
82
|
+
# Local paths resolve beside this file in ~/.pi/.doom. Repository paths in a
|
|
83
|
+
# repository .doom/domains.yaml resolve from that repository root.
|
|
84
|
+
# entries:
|
|
85
|
+
# development:
|
|
86
|
+
# source: local
|
|
87
|
+
# path: plugins/development
|
|
88
|
+
# remote-review:
|
|
89
|
+
# source: url
|
|
90
|
+
# url: https://github.com/acme/review-plugin.git
|
|
91
|
+
# ref: v1.2.0
|
|
92
|
+
# published-review:
|
|
93
|
+
# source: npm
|
|
94
|
+
# package: '@acme/review-plugin'
|
|
95
|
+
# version: 1.2.0
|
|
96
|
+
# Domains carry descriptions and refer to catalog names, not filesystem paths.
|
|
97
|
+
domains:
|
|
98
|
+
default:
|
|
99
|
+
description: Shared skills and repository MCP only.
|
|
100
|
+
plugins: []
|
|
101
|
+
# development:
|
|
102
|
+
# description: TypeScript implementation and review tools.
|
|
103
|
+
# plugins:
|
|
104
|
+
# - development
|
|
105
|
+
# # Mapping form can load only selected resources from a shared plugin.
|
|
106
|
+
# - name: remote-review
|
|
107
|
+
# skills: [typescript]
|
|
108
|
+
# agents: [reviewer]
|
|
109
|
+
# hooks: false
|
|
110
|
+
# mcp: true
|
|
111
|
+
# # Set false only when this domain should omit shared .claude/skills.
|
|
112
|
+
# sharedSkills: false
|
|
113
|
+
# Select it with doompi --domains development, or add it to defaultDomains.
|
|
114
|
+
#
|
|
115
|
+
# Aliases let one selection enable multiple domains. Replace the empty mapping
|
|
116
|
+
# below with entries like the commented example.
|
|
117
|
+
aliases: {}
|
|
118
|
+
# aliases:
|
|
119
|
+
# work: [default, development]
|
|
120
|
+
`,"profiles.yaml":`# Profiles select a persona and optional environment defaults for a session.
|
|
121
|
+
# Each configured root may itself be a profile or contain direct-child profile
|
|
122
|
+
# folders. A folder is discovered when it contains profile.md, SOUL.md, or
|
|
123
|
+
# AGENTS.md; discovery never scans recursively.
|
|
124
|
+
profiles:
|
|
125
|
+
roots: []
|
|
126
|
+
entries: {}
|
|
127
|
+
# Roots resolve beside this file in ~/.pi/.doom. Repository roots in a
|
|
128
|
+
# repository .doom/profiles.yaml resolve from that repository root.
|
|
129
|
+
# roots: [agents/acme]
|
|
130
|
+
# Explicit entries override an automatically discovered folder of the same
|
|
131
|
+
# name. Environment values must be strings; already exported values win.
|
|
132
|
+
# entries:
|
|
133
|
+
# writer:
|
|
134
|
+
# persona: agents/special/writer
|
|
135
|
+
# env:
|
|
136
|
+
# BRAND: acme
|
|
137
|
+
# TONE: concise
|
|
138
|
+
# Doom Pi concatenates profile.md, SOUL.md, then AGENTS.md for the persona.
|
|
139
|
+
# Select one with: doompi --profile writer
|
|
140
|
+
`},d={"config.yaml":u[`config.yaml`],"modes.yaml":`# Repository-local layers and major modes. These entries override personal
|
|
141
|
+
# entries with the same name from ~/.pi/.doom/modes.yaml.
|
|
142
|
+
layers:
|
|
143
|
+
team:
|
|
144
|
+
packages:
|
|
145
|
+
- name: '@agimon-ai/doompi-team'
|
|
146
|
+
task:
|
|
147
|
+
packages:
|
|
148
|
+
- '@agimon-ai/doompi-task'
|
|
149
|
+
runner:
|
|
150
|
+
packages:
|
|
151
|
+
- '@agimon-ai/doompi-runner'
|
|
152
|
+
ask-user:
|
|
153
|
+
packages:
|
|
154
|
+
- '@agimon-ai/doompi-user-feedback'
|
|
155
|
+
defaultMajorMode: copilot
|
|
156
|
+
majorMode:
|
|
157
|
+
minimal:
|
|
158
|
+
description: Lean mode with Team delegation and persistent tasks.
|
|
159
|
+
layers: [team, task]
|
|
160
|
+
copilot:
|
|
161
|
+
description: General-purpose coding mode with delegation, persistent tasks, supervised commands, and structured user feedback.
|
|
162
|
+
layers: [team, task, runner, ask-user]
|
|
163
|
+
`,"domains.yaml":`# Repository-local plugin catalog and domain selection.
|
|
164
|
+
defaultDomains: [default]
|
|
165
|
+
plugins:
|
|
166
|
+
roots: []
|
|
167
|
+
entries: {}
|
|
168
|
+
domains:
|
|
169
|
+
default:
|
|
170
|
+
description: Shared skills and repository MCP only.
|
|
171
|
+
plugins: []
|
|
172
|
+
aliases: {}
|
|
173
|
+
`,"profiles.yaml":`# Repository-local persona roots and environment defaults.
|
|
174
|
+
profiles:
|
|
175
|
+
roots: []
|
|
176
|
+
entries: {}
|
|
177
|
+
`};function f(e){if(!(e instanceof Error))return;let t=e.code;return typeof t==`string`?t:void 0}function p(e,t){let n;try{n=r.default.lstatSync(e)}catch(i){if(f(i)!==c)throw i;try{r.default.mkdirSync(e,{mode:t}),n=r.default.lstatSync(e)}catch(t){if(f(t)!==s)throw t;n=r.default.lstatSync(e)}}if(n.isSymbolicLink())throw Error(`Refusing to initialize through symlinked directory: ${e}`);if(!n.isDirectory())throw Error(`Doom config path is not a directory: ${e}`)}function m(e,t){p(i.default.dirname(e),t),p(e,t)}function h(e){let t;try{t=r.default.lstatSync(e)}catch(e){if(f(e)===c)return`missing`;throw e}if(t.isFile())return`file`;if(t.isSymbolicLink())try{if(r.default.statSync(e).isFile())return`file`}catch(t){throw Error(`Doom config seed symlink is not file-like: ${e}`,{cause:t})}throw Error(`Doom config seed path is not file-like: ${e}`)}function g(e){try{r.default.unlinkSync(e)}catch(e){if(f(e)!==c)throw e}}function _(e,t,i){let a=`${e}.${process.pid}.${(0,n.randomUUID)()}.tmp`,c;try{c=r.default.openSync(a,`wx`,i),r.default.writeFileSync(c,t,o),r.default.fchmodSync(c,i),r.default.fsyncSync(c);let n=c;c=void 0,r.default.closeSync(n);try{return r.default.linkSync(a,e),!0}catch(t){if(f(t)===s&&h(e)===`file`)return!1;throw t}}finally{if(c!==void 0){let e=c;c=void 0,r.default.closeSync(e)}g(a)}}function v(e,t,i){let a=`${e}.${process.pid}.${(0,n.randomUUID)()}.tmp`,s;try{s=r.default.openSync(a,`wx`,i),r.default.writeFileSync(s,t,o),r.default.fchmodSync(s,i),r.default.fsyncSync(s);let n=s;s=void 0,r.default.closeSync(n),r.default.renameSync(a,e)}finally{if(s!==void 0){let e=s;s=void 0,r.default.closeSync(e)}g(a)}}function y(e,t,n,r,a){m(e,r);let o=[],s=[],c=[];for(let r of l){let l=i.default.join(e,r),u=h(l)===`file`;if(n.force){v(l,t[r],a),(u?c:o).push(r);continue}if(u){s.push(r);continue}_(l,t[r],a)?o.push(r):s.push(r)}return{directory:e,created:o,preserved:s,replaced:c}}function b(e=a.default.homedir(),n={}){return y(t.globalDoomConfigDirectory(e),u,n,448,384)}function x(e=process.cwd(),t={}){return y(i.default.join(i.default.resolve(e),`.doom`),d,t,493,420)}exports.DOOM_CONFIG_TEMPLATES=u,exports.GLOBAL_DOOM_SEED_FILES=l,exports.REPOSITORY_DOOM_CONFIG_TEMPLATES=d,exports.initializeGlobalDoomConfig=b,exports.initializeRepositoryDoomConfig=x;
|
|
178
|
+
//# sourceMappingURL=init.cjs.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"init.cjs","names":["fs","path","randomUUID","os","globalDoomConfigDirectory"],"sources":["../../src/adapters/init.ts"],"sourcesContent":["import { randomUUID } from 'node:crypto';\nimport fs from 'node:fs';\nimport os from 'node:os';\nimport path from 'node:path';\n\nimport { globalDoomConfigDirectory } from './config.ts';\n\nconst PRIVATE_DIRECTORY_MODE = 0o700;\nconst PRIVATE_FILE_MODE = 0o600;\nconst REPOSITORY_DIRECTORY_MODE = 0o755;\nconst REPOSITORY_FILE_MODE = 0o644;\nconst DOOM_DIRECTORY = '.doom';\nconst UTF8_ENCODING = 'utf8';\nconst FILE_ALREADY_EXISTS = 'EEXIST';\nconst FILE_NOT_FOUND = 'ENOENT';\n\n/** The global seed files are processed in this fixed order. */\nexport const GLOBAL_DOOM_SEED_FILES = ['config.yaml', 'modes.yaml', 'domains.yaml', 'profiles.yaml'] as const;\n\ntype DoomSeedFile = (typeof GLOBAL_DOOM_SEED_FILES)[number];\n\n/** Portable defaults for a new global Doom configuration directory. */\nexport const DOOM_CONFIG_TEMPLATES: Readonly<Record<DoomSeedFile, string>> = {\n 'config.yaml': `projectTrust: ask\n\n# Autonomous voice is opt-in and uses an explicitly configured Pi model.\n# voice:\n# autoCapture:\n# model: provider/model-id\n# startPhrases:\n# - hey doom\n# stopPhrases:\n# - stop speaking\n# utteranceIdleMs: 3000\n# tts:\n# engine: macos-say\n# voice: Samantha\n# rate: 190\n`,\n 'modes.yaml': `# A layer is a reusable named bundle of packages, built-in or local extensions,\n# and hook groups. Major modes below choose which layers load together for a session.\n#\n# Layers and modes defined here apply to every repository. A repository's own\n# .doom/modes.yaml is read after this file and replaces any layer or mode of the\n# same name, so a repository can override one entry without restating the rest.\n#\n# Add a layer by giving it a unique name under layers. Local Pi scripts belong\n# under extensions, while installed Pi packages belong under packages:\n# review-tools:\n# extensions:\n# - './extensions/local-review.ts'\n# packages:\n# - '@scope/review-extension'\n# A bare extension name selects a DoomPi built-in. A path beginning with ./ or\n# ../ loads a custom script or extension directory. A bare package loads its\n# ordered package.json pi.extensions entries, while an exported subpath selects\n# one adapter. Relative paths resolve beside this file here (~/.pi/.doom), or\n# from the repository root in .doom/modes.yaml.\n#\n# Use a package mapping when that package accepts configuration. Configuration\n# belongs under the package entry that consumes it, not beside packages.\nlayers:\n team:\n packages:\n - name: '@agimon-ai/doompi-team'\n # Optional Team configuration. Uncomment and choose models available to Pi.\n # config:\n # models:\n # - model: openai-codex/gpt-5.6-luna\n # thinking: xhigh\n # # Tool names excluded from subagents launched by this package. These\n # # remove model-visible tools while preserving hidden team transport.\n # excludeTools: [ask_user_question, intercom, subagent]\n task:\n packages:\n - '@agimon-ai/doompi-task'\n runner:\n packages:\n - '@agimon-ai/doompi-runner'\n ask-user:\n packages:\n - '@agimon-ai/doompi-user-feedback'\n# A major mode explains when it should be used and names its ordered layers.\n# Add another entry under majorMode, then select it with\n# doompi --major-mode <name>. Change defaultMajorMode to make it the default.\ndefaultMajorMode: copilot\nmajorMode:\n minimal:\n description: Lean mode with Team delegation and persistent tasks.\n layers: [team, task]\n copilot:\n description: General-purpose coding mode with Team delegation, persistent tasks, supervised commands, and structured user feedback.\n layers: [team, task, runner, ask-user]\n # review:\n # description: Focused review mode for inspecting changes and reporting risks.\n # layers: [team, task, ask-user]\n`,\n 'domains.yaml': `# Plugins are named once in this catalog, then selected by one or more domains.\n# DoomPi automatically inspects personal and repository Codex marketplaces.\n# Each configured root may also be a folder whose direct children are plugins;\n# use roots: [plugins] to discover a repository plugin folder without one entry\n# per plugin. Discovery never scans recursively.\ndefaultDomains: [default]\nplugins:\n roots: []\n entries: {}\n # Local paths resolve beside this file in ~/.pi/.doom. Repository paths in a\n # repository .doom/domains.yaml resolve from that repository root.\n # entries:\n # development:\n # source: local\n # path: plugins/development\n # remote-review:\n # source: url\n # url: https://github.com/acme/review-plugin.git\n # ref: v1.2.0\n # published-review:\n # source: npm\n # package: '@acme/review-plugin'\n # version: 1.2.0\n# Domains carry descriptions and refer to catalog names, not filesystem paths.\ndomains:\n default:\n description: Shared skills and repository MCP only.\n plugins: []\n # development:\n # description: TypeScript implementation and review tools.\n # plugins:\n # - development\n # # Mapping form can load only selected resources from a shared plugin.\n # - name: remote-review\n # skills: [typescript]\n # agents: [reviewer]\n # hooks: false\n # mcp: true\n # # Set false only when this domain should omit shared .claude/skills.\n # sharedSkills: false\n# Select it with doompi --domains development, or add it to defaultDomains.\n#\n# Aliases let one selection enable multiple domains. Replace the empty mapping\n# below with entries like the commented example.\naliases: {}\n# aliases:\n# work: [default, development]\n`,\n 'profiles.yaml': `# Profiles select a persona and optional environment defaults for a session.\n# Each configured root may itself be a profile or contain direct-child profile\n# folders. A folder is discovered when it contains profile.md, SOUL.md, or\n# AGENTS.md; discovery never scans recursively.\nprofiles:\n roots: []\n entries: {}\n # Roots resolve beside this file in ~/.pi/.doom. Repository roots in a\n # repository .doom/profiles.yaml resolve from that repository root.\n # roots: [agents/acme]\n # Explicit entries override an automatically discovered folder of the same\n # name. Environment values must be strings; already exported values win.\n # entries:\n # writer:\n # persona: agents/special/writer\n # env:\n # BRAND: acme\n # TONE: concise\n# Doom Pi concatenates profile.md, SOUL.md, then AGENTS.md for the persona.\n# Select one with: doompi --profile writer\n`,\n};\n\n/** Standalone defaults for a repository that is trying DoomPi through DPI. */\nexport const REPOSITORY_DOOM_CONFIG_TEMPLATES: Readonly<Record<DoomSeedFile, string>> = {\n 'config.yaml': DOOM_CONFIG_TEMPLATES['config.yaml'],\n 'modes.yaml': `# Repository-local layers and major modes. These entries override personal\n# entries with the same name from ~/.pi/.doom/modes.yaml.\nlayers:\n team:\n packages:\n - name: '@agimon-ai/doompi-team'\n task:\n packages:\n - '@agimon-ai/doompi-task'\n runner:\n packages:\n - '@agimon-ai/doompi-runner'\n ask-user:\n packages:\n - '@agimon-ai/doompi-user-feedback'\ndefaultMajorMode: copilot\nmajorMode:\n minimal:\n description: Lean mode with Team delegation and persistent tasks.\n layers: [team, task]\n copilot:\n description: General-purpose coding mode with delegation, persistent tasks, supervised commands, and structured user feedback.\n layers: [team, task, runner, ask-user]\n`,\n 'domains.yaml': `# Repository-local plugin catalog and domain selection.\ndefaultDomains: [default]\nplugins:\n roots: []\n entries: {}\ndomains:\n default:\n description: Shared skills and repository MCP only.\n plugins: []\naliases: {}\n`,\n 'profiles.yaml': `# Repository-local persona roots and environment defaults.\nprofiles:\n roots: []\n entries: {}\n`,\n};\n\n/** Result of filling a Doom seed directory. File arrays contain names in seed order. */\nexport interface GlobalDoomInitResult {\n directory: string;\n created: string[];\n preserved: string[];\n /** Existing files overwritten from the template. Only ever non-empty under `force`. */\n replaced: string[];\n}\n\nexport interface GlobalDoomInitOptions {\n /**\n * Overwrite existing seed files instead of preserving them.\n *\n * Off by default: init is safe to re-run, and hand-edited config is the\n * normal case rather than the exception.\n */\n force?: boolean;\n}\n\nexport type RepositoryDoomInitOptions = GlobalDoomInitOptions;\nexport type RepositoryDoomInitResult = GlobalDoomInitResult;\n\nfunction errorCode(error: unknown): string | undefined {\n if (!(error instanceof Error)) return undefined;\n const code = (error as NodeJS.ErrnoException).code;\n return typeof code === 'string' ? code : undefined;\n}\n\nfunction ensureDirectory(directory: string, mode: number): void {\n let stats: fs.Stats;\n try {\n stats = fs.lstatSync(directory);\n } catch (error) {\n if (errorCode(error) !== FILE_NOT_FOUND) throw error;\n try {\n fs.mkdirSync(directory, { mode });\n stats = fs.lstatSync(directory);\n } catch (mkdirError) {\n if (errorCode(mkdirError) !== FILE_ALREADY_EXISTS) throw mkdirError;\n stats = fs.lstatSync(directory);\n }\n }\n\n if (stats.isSymbolicLink()) {\n throw new Error(`Refusing to initialize through symlinked directory: ${directory}`);\n }\n if (!stats.isDirectory()) {\n throw new Error(`Doom config path is not a directory: ${directory}`);\n }\n}\n\nfunction ensureDoomDirectory(directory: string, mode: number): void {\n ensureDirectory(path.dirname(directory), mode);\n ensureDirectory(directory, mode);\n}\n\nfunction classifyTarget(targetPath: string): 'missing' | 'file' {\n let stats: fs.Stats;\n try {\n stats = fs.lstatSync(targetPath);\n } catch (error) {\n if (errorCode(error) === FILE_NOT_FOUND) return 'missing';\n throw error;\n }\n\n if (stats.isFile()) return 'file';\n if (stats.isSymbolicLink()) {\n try {\n if (fs.statSync(targetPath).isFile()) return 'file';\n } catch (error) {\n throw new Error(`Doom config seed symlink is not file-like: ${targetPath}`, { cause: error });\n }\n }\n throw new Error(`Doom config seed path is not file-like: ${targetPath}`);\n}\n\nfunction cleanupTemporaryFile(temporaryPath: string): void {\n try {\n fs.unlinkSync(temporaryPath);\n } catch (error) {\n if (errorCode(error) !== FILE_NOT_FOUND) throw error;\n }\n}\n\nfunction publishExclusively(targetPath: string, content: string, mode: number): boolean {\n const temporaryPath = `${targetPath}.${process.pid}.${randomUUID()}.tmp`;\n let fileDescriptor: number | undefined;\n try {\n fileDescriptor = fs.openSync(temporaryPath, 'wx', mode);\n fs.writeFileSync(fileDescriptor, content, UTF8_ENCODING);\n fs.fchmodSync(fileDescriptor, mode);\n fs.fsyncSync(fileDescriptor);\n const descriptorToClose = fileDescriptor;\n fileDescriptor = undefined;\n fs.closeSync(descriptorToClose);\n\n try {\n fs.linkSync(temporaryPath, targetPath);\n return true;\n } catch (error) {\n if (errorCode(error) === FILE_ALREADY_EXISTS && classifyTarget(targetPath) === 'file') return false;\n throw error;\n }\n } finally {\n if (fileDescriptor !== undefined) {\n const descriptorToClose = fileDescriptor;\n fileDescriptor = undefined;\n fs.closeSync(descriptorToClose);\n }\n cleanupTemporaryFile(temporaryPath);\n }\n}\n\n/**\n * Replaces a seed file with the template, atomically.\n *\n * The rename swaps the directory entry in one step, so a reader either sees the\n * whole old file or the whole new one. Renaming onto a symlinked seed replaces\n * the link rather than writing through it.\n */\nfunction publishForcefully(targetPath: string, content: string, mode: number): void {\n const temporaryPath = `${targetPath}.${process.pid}.${randomUUID()}.tmp`;\n let fileDescriptor: number | undefined;\n try {\n fileDescriptor = fs.openSync(temporaryPath, 'wx', mode);\n fs.writeFileSync(fileDescriptor, content, UTF8_ENCODING);\n fs.fchmodSync(fileDescriptor, mode);\n fs.fsyncSync(fileDescriptor);\n const descriptorToClose = fileDescriptor;\n fileDescriptor = undefined;\n fs.closeSync(descriptorToClose);\n\n fs.renameSync(temporaryPath, targetPath);\n } finally {\n if (fileDescriptor !== undefined) {\n const descriptorToClose = fileDescriptor;\n fileDescriptor = undefined;\n fs.closeSync(descriptorToClose);\n }\n cleanupTemporaryFile(temporaryPath);\n }\n}\n\nfunction initializeDoomConfig(\n directory: string,\n templates: Readonly<Record<DoomSeedFile, string>>,\n options: GlobalDoomInitOptions,\n directoryMode: number,\n fileMode: number,\n): GlobalDoomInitResult {\n ensureDoomDirectory(directory, directoryMode);\n\n const created: string[] = [];\n const preserved: string[] = [];\n const replaced: string[] = [];\n for (const fileName of GLOBAL_DOOM_SEED_FILES) {\n const targetPath = path.join(directory, fileName);\n const existed = classifyTarget(targetPath) === 'file';\n\n if (options.force) {\n publishForcefully(targetPath, templates[fileName], fileMode);\n (existed ? replaced : created).push(fileName);\n continue;\n }\n if (existed) {\n preserved.push(fileName);\n continue;\n }\n if (publishExclusively(targetPath, templates[fileName], fileMode)) created.push(fileName);\n else preserved.push(fileName);\n }\n\n return { directory, created, preserved, replaced };\n}\n\n/**\n * Fills missing global seed files.\n *\n * Existing files are left alone so that re-running init never discards\n * hand-edited config; pass `force` to overwrite them from the template.\n */\nexport function initializeGlobalDoomConfig(\n homeDirectory = os.homedir(),\n options: GlobalDoomInitOptions = {},\n): GlobalDoomInitResult {\n return initializeDoomConfig(\n globalDoomConfigDirectory(homeDirectory),\n DOOM_CONFIG_TEMPLATES,\n options,\n PRIVATE_DIRECTORY_MODE,\n PRIVATE_FILE_MODE,\n );\n}\n\n/** Seeds repository-local configuration without creating or changing Pi settings. */\nexport function initializeRepositoryDoomConfig(\n repositoryRoot = process.cwd(),\n options: RepositoryDoomInitOptions = {},\n): RepositoryDoomInitResult {\n return initializeDoomConfig(\n path.join(path.resolve(repositoryRoot), DOOM_DIRECTORY),\n REPOSITORY_DOOM_CONFIG_TEMPLATES,\n options,\n REPOSITORY_DIRECTORY_MODE,\n REPOSITORY_FILE_MODE,\n );\n}\n"],"mappings":"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"}
|
|
@@ -0,0 +1,39 @@
|
|
|
1
|
+
//#region src/adapters/init.d.ts
|
|
2
|
+
/** The global seed files are processed in this fixed order. */
|
|
3
|
+
declare const GLOBAL_DOOM_SEED_FILES: readonly ["config.yaml", "modes.yaml", "domains.yaml", "profiles.yaml"];
|
|
4
|
+
type DoomSeedFile = (typeof GLOBAL_DOOM_SEED_FILES)[number];
|
|
5
|
+
/** Portable defaults for a new global Doom configuration directory. */
|
|
6
|
+
declare const DOOM_CONFIG_TEMPLATES: Readonly<Record<DoomSeedFile, string>>;
|
|
7
|
+
/** Standalone defaults for a repository that is trying DoomPi through DPI. */
|
|
8
|
+
declare const REPOSITORY_DOOM_CONFIG_TEMPLATES: Readonly<Record<DoomSeedFile, string>>;
|
|
9
|
+
/** Result of filling a Doom seed directory. File arrays contain names in seed order. */
|
|
10
|
+
interface GlobalDoomInitResult {
|
|
11
|
+
directory: string;
|
|
12
|
+
created: string[];
|
|
13
|
+
preserved: string[];
|
|
14
|
+
/** Existing files overwritten from the template. Only ever non-empty under `force`. */
|
|
15
|
+
replaced: string[];
|
|
16
|
+
}
|
|
17
|
+
interface GlobalDoomInitOptions {
|
|
18
|
+
/**
|
|
19
|
+
* Overwrite existing seed files instead of preserving them.
|
|
20
|
+
*
|
|
21
|
+
* Off by default: init is safe to re-run, and hand-edited config is the
|
|
22
|
+
* normal case rather than the exception.
|
|
23
|
+
*/
|
|
24
|
+
force?: boolean;
|
|
25
|
+
}
|
|
26
|
+
type RepositoryDoomInitOptions = GlobalDoomInitOptions;
|
|
27
|
+
type RepositoryDoomInitResult = GlobalDoomInitResult;
|
|
28
|
+
/**
|
|
29
|
+
* Fills missing global seed files.
|
|
30
|
+
*
|
|
31
|
+
* Existing files are left alone so that re-running init never discards
|
|
32
|
+
* hand-edited config; pass `force` to overwrite them from the template.
|
|
33
|
+
*/
|
|
34
|
+
declare function initializeGlobalDoomConfig(homeDirectory?: string, options?: GlobalDoomInitOptions): GlobalDoomInitResult;
|
|
35
|
+
/** Seeds repository-local configuration without creating or changing Pi settings. */
|
|
36
|
+
declare function initializeRepositoryDoomConfig(repositoryRoot?: string, options?: RepositoryDoomInitOptions): RepositoryDoomInitResult;
|
|
37
|
+
//#endregion
|
|
38
|
+
export { DOOM_CONFIG_TEMPLATES, GLOBAL_DOOM_SEED_FILES, GlobalDoomInitOptions, GlobalDoomInitResult, REPOSITORY_DOOM_CONFIG_TEMPLATES, RepositoryDoomInitOptions, RepositoryDoomInitResult, initializeGlobalDoomConfig, initializeRepositoryDoomConfig };
|
|
39
|
+
//# sourceMappingURL=init.d.cts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"init.d.cts","names":[],"sources":["../../src/adapters/init.ts"],"mappings":";;cAiBa;KAER,uBAAuB;;cAGf,uBAAuB,SAAS,OAAO;;cAmJvC,kCAAkC,SAAS,OAAO;;UA6C9C;EACf;EACA;EACA;;EAEA;;UAGe;;;;;;;EAOf;;KAGU,4BAA4B;KAC5B,2BAA2B;;;;;;;iBAiKvB,2BACd,wBACA,UAAS,wBACR;;iBAWa,+BACd,yBACA,UAAS,4BACR"}
|
|
@@ -0,0 +1,39 @@
|
|
|
1
|
+
//#region src/adapters/init.d.ts
|
|
2
|
+
/** The global seed files are processed in this fixed order. */
|
|
3
|
+
declare const GLOBAL_DOOM_SEED_FILES: readonly ["config.yaml", "modes.yaml", "domains.yaml", "profiles.yaml"];
|
|
4
|
+
type DoomSeedFile = (typeof GLOBAL_DOOM_SEED_FILES)[number];
|
|
5
|
+
/** Portable defaults for a new global Doom configuration directory. */
|
|
6
|
+
declare const DOOM_CONFIG_TEMPLATES: Readonly<Record<DoomSeedFile, string>>;
|
|
7
|
+
/** Standalone defaults for a repository that is trying DoomPi through DPI. */
|
|
8
|
+
declare const REPOSITORY_DOOM_CONFIG_TEMPLATES: Readonly<Record<DoomSeedFile, string>>;
|
|
9
|
+
/** Result of filling a Doom seed directory. File arrays contain names in seed order. */
|
|
10
|
+
interface GlobalDoomInitResult {
|
|
11
|
+
directory: string;
|
|
12
|
+
created: string[];
|
|
13
|
+
preserved: string[];
|
|
14
|
+
/** Existing files overwritten from the template. Only ever non-empty under `force`. */
|
|
15
|
+
replaced: string[];
|
|
16
|
+
}
|
|
17
|
+
interface GlobalDoomInitOptions {
|
|
18
|
+
/**
|
|
19
|
+
* Overwrite existing seed files instead of preserving them.
|
|
20
|
+
*
|
|
21
|
+
* Off by default: init is safe to re-run, and hand-edited config is the
|
|
22
|
+
* normal case rather than the exception.
|
|
23
|
+
*/
|
|
24
|
+
force?: boolean;
|
|
25
|
+
}
|
|
26
|
+
type RepositoryDoomInitOptions = GlobalDoomInitOptions;
|
|
27
|
+
type RepositoryDoomInitResult = GlobalDoomInitResult;
|
|
28
|
+
/**
|
|
29
|
+
* Fills missing global seed files.
|
|
30
|
+
*
|
|
31
|
+
* Existing files are left alone so that re-running init never discards
|
|
32
|
+
* hand-edited config; pass `force` to overwrite them from the template.
|
|
33
|
+
*/
|
|
34
|
+
declare function initializeGlobalDoomConfig(homeDirectory?: string, options?: GlobalDoomInitOptions): GlobalDoomInitResult;
|
|
35
|
+
/** Seeds repository-local configuration without creating or changing Pi settings. */
|
|
36
|
+
declare function initializeRepositoryDoomConfig(repositoryRoot?: string, options?: RepositoryDoomInitOptions): RepositoryDoomInitResult;
|
|
37
|
+
//#endregion
|
|
38
|
+
export { DOOM_CONFIG_TEMPLATES, GLOBAL_DOOM_SEED_FILES, GlobalDoomInitOptions, GlobalDoomInitResult, REPOSITORY_DOOM_CONFIG_TEMPLATES, RepositoryDoomInitOptions, RepositoryDoomInitResult, initializeGlobalDoomConfig, initializeRepositoryDoomConfig };
|
|
39
|
+
//# sourceMappingURL=init.d.mts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"init.d.mts","names":[],"sources":["../../src/adapters/init.ts"],"mappings":";;cAiBa;KAER,uBAAuB;;cAGf,uBAAuB,SAAS,OAAO;;cAmJvC,kCAAkC,SAAS,OAAO;;UA6C9C;EACf;EACA;EACA;;EAEA;;UAGe;;;;;;;EAOf;;KAGU,4BAA4B;KAC5B,2BAA2B;;;;;;;iBAiKvB,2BACd,wBACA,UAAS,wBACR;;iBAWa,+BACd,yBACA,UAAS,4BACR"}
|
|
@@ -0,0 +1,178 @@
|
|
|
1
|
+
import{globalDoomConfigDirectory as e}from"./config.mjs";import{randomUUID as t}from"node:crypto";import n from"node:fs";import r from"node:path";import i from"node:os";const a=`utf8`,o=`EEXIST`,s=`ENOENT`,c=[`config.yaml`,`modes.yaml`,`domains.yaml`,`profiles.yaml`],l={"config.yaml":`projectTrust: ask
|
|
2
|
+
|
|
3
|
+
# Autonomous voice is opt-in and uses an explicitly configured Pi model.
|
|
4
|
+
# voice:
|
|
5
|
+
# autoCapture:
|
|
6
|
+
# model: provider/model-id
|
|
7
|
+
# startPhrases:
|
|
8
|
+
# - hey doom
|
|
9
|
+
# stopPhrases:
|
|
10
|
+
# - stop speaking
|
|
11
|
+
# utteranceIdleMs: 3000
|
|
12
|
+
# tts:
|
|
13
|
+
# engine: macos-say
|
|
14
|
+
# voice: Samantha
|
|
15
|
+
# rate: 190
|
|
16
|
+
`,"modes.yaml":`# A layer is a reusable named bundle of packages, built-in or local extensions,
|
|
17
|
+
# and hook groups. Major modes below choose which layers load together for a session.
|
|
18
|
+
#
|
|
19
|
+
# Layers and modes defined here apply to every repository. A repository's own
|
|
20
|
+
# .doom/modes.yaml is read after this file and replaces any layer or mode of the
|
|
21
|
+
# same name, so a repository can override one entry without restating the rest.
|
|
22
|
+
#
|
|
23
|
+
# Add a layer by giving it a unique name under layers. Local Pi scripts belong
|
|
24
|
+
# under extensions, while installed Pi packages belong under packages:
|
|
25
|
+
# review-tools:
|
|
26
|
+
# extensions:
|
|
27
|
+
# - './extensions/local-review.ts'
|
|
28
|
+
# packages:
|
|
29
|
+
# - '@scope/review-extension'
|
|
30
|
+
# A bare extension name selects a DoomPi built-in. A path beginning with ./ or
|
|
31
|
+
# ../ loads a custom script or extension directory. A bare package loads its
|
|
32
|
+
# ordered package.json pi.extensions entries, while an exported subpath selects
|
|
33
|
+
# one adapter. Relative paths resolve beside this file here (~/.pi/.doom), or
|
|
34
|
+
# from the repository root in .doom/modes.yaml.
|
|
35
|
+
#
|
|
36
|
+
# Use a package mapping when that package accepts configuration. Configuration
|
|
37
|
+
# belongs under the package entry that consumes it, not beside packages.
|
|
38
|
+
layers:
|
|
39
|
+
team:
|
|
40
|
+
packages:
|
|
41
|
+
- name: '@agimon-ai/doompi-team'
|
|
42
|
+
# Optional Team configuration. Uncomment and choose models available to Pi.
|
|
43
|
+
# config:
|
|
44
|
+
# models:
|
|
45
|
+
# - model: openai-codex/gpt-5.6-luna
|
|
46
|
+
# thinking: xhigh
|
|
47
|
+
# # Tool names excluded from subagents launched by this package. These
|
|
48
|
+
# # remove model-visible tools while preserving hidden team transport.
|
|
49
|
+
# excludeTools: [ask_user_question, intercom, subagent]
|
|
50
|
+
task:
|
|
51
|
+
packages:
|
|
52
|
+
- '@agimon-ai/doompi-task'
|
|
53
|
+
runner:
|
|
54
|
+
packages:
|
|
55
|
+
- '@agimon-ai/doompi-runner'
|
|
56
|
+
ask-user:
|
|
57
|
+
packages:
|
|
58
|
+
- '@agimon-ai/doompi-user-feedback'
|
|
59
|
+
# A major mode explains when it should be used and names its ordered layers.
|
|
60
|
+
# Add another entry under majorMode, then select it with
|
|
61
|
+
# doompi --major-mode <name>. Change defaultMajorMode to make it the default.
|
|
62
|
+
defaultMajorMode: copilot
|
|
63
|
+
majorMode:
|
|
64
|
+
minimal:
|
|
65
|
+
description: Lean mode with Team delegation and persistent tasks.
|
|
66
|
+
layers: [team, task]
|
|
67
|
+
copilot:
|
|
68
|
+
description: General-purpose coding mode with Team delegation, persistent tasks, supervised commands, and structured user feedback.
|
|
69
|
+
layers: [team, task, runner, ask-user]
|
|
70
|
+
# review:
|
|
71
|
+
# description: Focused review mode for inspecting changes and reporting risks.
|
|
72
|
+
# layers: [team, task, ask-user]
|
|
73
|
+
`,"domains.yaml":`# Plugins are named once in this catalog, then selected by one or more domains.
|
|
74
|
+
# DoomPi automatically inspects personal and repository Codex marketplaces.
|
|
75
|
+
# Each configured root may also be a folder whose direct children are plugins;
|
|
76
|
+
# use roots: [plugins] to discover a repository plugin folder without one entry
|
|
77
|
+
# per plugin. Discovery never scans recursively.
|
|
78
|
+
defaultDomains: [default]
|
|
79
|
+
plugins:
|
|
80
|
+
roots: []
|
|
81
|
+
entries: {}
|
|
82
|
+
# Local paths resolve beside this file in ~/.pi/.doom. Repository paths in a
|
|
83
|
+
# repository .doom/domains.yaml resolve from that repository root.
|
|
84
|
+
# entries:
|
|
85
|
+
# development:
|
|
86
|
+
# source: local
|
|
87
|
+
# path: plugins/development
|
|
88
|
+
# remote-review:
|
|
89
|
+
# source: url
|
|
90
|
+
# url: https://github.com/acme/review-plugin.git
|
|
91
|
+
# ref: v1.2.0
|
|
92
|
+
# published-review:
|
|
93
|
+
# source: npm
|
|
94
|
+
# package: '@acme/review-plugin'
|
|
95
|
+
# version: 1.2.0
|
|
96
|
+
# Domains carry descriptions and refer to catalog names, not filesystem paths.
|
|
97
|
+
domains:
|
|
98
|
+
default:
|
|
99
|
+
description: Shared skills and repository MCP only.
|
|
100
|
+
plugins: []
|
|
101
|
+
# development:
|
|
102
|
+
# description: TypeScript implementation and review tools.
|
|
103
|
+
# plugins:
|
|
104
|
+
# - development
|
|
105
|
+
# # Mapping form can load only selected resources from a shared plugin.
|
|
106
|
+
# - name: remote-review
|
|
107
|
+
# skills: [typescript]
|
|
108
|
+
# agents: [reviewer]
|
|
109
|
+
# hooks: false
|
|
110
|
+
# mcp: true
|
|
111
|
+
# # Set false only when this domain should omit shared .claude/skills.
|
|
112
|
+
# sharedSkills: false
|
|
113
|
+
# Select it with doompi --domains development, or add it to defaultDomains.
|
|
114
|
+
#
|
|
115
|
+
# Aliases let one selection enable multiple domains. Replace the empty mapping
|
|
116
|
+
# below with entries like the commented example.
|
|
117
|
+
aliases: {}
|
|
118
|
+
# aliases:
|
|
119
|
+
# work: [default, development]
|
|
120
|
+
`,"profiles.yaml":`# Profiles select a persona and optional environment defaults for a session.
|
|
121
|
+
# Each configured root may itself be a profile or contain direct-child profile
|
|
122
|
+
# folders. A folder is discovered when it contains profile.md, SOUL.md, or
|
|
123
|
+
# AGENTS.md; discovery never scans recursively.
|
|
124
|
+
profiles:
|
|
125
|
+
roots: []
|
|
126
|
+
entries: {}
|
|
127
|
+
# Roots resolve beside this file in ~/.pi/.doom. Repository roots in a
|
|
128
|
+
# repository .doom/profiles.yaml resolve from that repository root.
|
|
129
|
+
# roots: [agents/acme]
|
|
130
|
+
# Explicit entries override an automatically discovered folder of the same
|
|
131
|
+
# name. Environment values must be strings; already exported values win.
|
|
132
|
+
# entries:
|
|
133
|
+
# writer:
|
|
134
|
+
# persona: agents/special/writer
|
|
135
|
+
# env:
|
|
136
|
+
# BRAND: acme
|
|
137
|
+
# TONE: concise
|
|
138
|
+
# Doom Pi concatenates profile.md, SOUL.md, then AGENTS.md for the persona.
|
|
139
|
+
# Select one with: doompi --profile writer
|
|
140
|
+
`},u={"config.yaml":l[`config.yaml`],"modes.yaml":`# Repository-local layers and major modes. These entries override personal
|
|
141
|
+
# entries with the same name from ~/.pi/.doom/modes.yaml.
|
|
142
|
+
layers:
|
|
143
|
+
team:
|
|
144
|
+
packages:
|
|
145
|
+
- name: '@agimon-ai/doompi-team'
|
|
146
|
+
task:
|
|
147
|
+
packages:
|
|
148
|
+
- '@agimon-ai/doompi-task'
|
|
149
|
+
runner:
|
|
150
|
+
packages:
|
|
151
|
+
- '@agimon-ai/doompi-runner'
|
|
152
|
+
ask-user:
|
|
153
|
+
packages:
|
|
154
|
+
- '@agimon-ai/doompi-user-feedback'
|
|
155
|
+
defaultMajorMode: copilot
|
|
156
|
+
majorMode:
|
|
157
|
+
minimal:
|
|
158
|
+
description: Lean mode with Team delegation and persistent tasks.
|
|
159
|
+
layers: [team, task]
|
|
160
|
+
copilot:
|
|
161
|
+
description: General-purpose coding mode with delegation, persistent tasks, supervised commands, and structured user feedback.
|
|
162
|
+
layers: [team, task, runner, ask-user]
|
|
163
|
+
`,"domains.yaml":`# Repository-local plugin catalog and domain selection.
|
|
164
|
+
defaultDomains: [default]
|
|
165
|
+
plugins:
|
|
166
|
+
roots: []
|
|
167
|
+
entries: {}
|
|
168
|
+
domains:
|
|
169
|
+
default:
|
|
170
|
+
description: Shared skills and repository MCP only.
|
|
171
|
+
plugins: []
|
|
172
|
+
aliases: {}
|
|
173
|
+
`,"profiles.yaml":`# Repository-local persona roots and environment defaults.
|
|
174
|
+
profiles:
|
|
175
|
+
roots: []
|
|
176
|
+
entries: {}
|
|
177
|
+
`};function d(e){if(!(e instanceof Error))return;let t=e.code;return typeof t==`string`?t:void 0}function f(e,t){let r;try{r=n.lstatSync(e)}catch(i){if(d(i)!==s)throw i;try{n.mkdirSync(e,{mode:t}),r=n.lstatSync(e)}catch(t){if(d(t)!==o)throw t;r=n.lstatSync(e)}}if(r.isSymbolicLink())throw Error(`Refusing to initialize through symlinked directory: ${e}`);if(!r.isDirectory())throw Error(`Doom config path is not a directory: ${e}`)}function p(e,t){f(r.dirname(e),t),f(e,t)}function m(e){let t;try{t=n.lstatSync(e)}catch(e){if(d(e)===s)return`missing`;throw e}if(t.isFile())return`file`;if(t.isSymbolicLink())try{if(n.statSync(e).isFile())return`file`}catch(t){throw Error(`Doom config seed symlink is not file-like: ${e}`,{cause:t})}throw Error(`Doom config seed path is not file-like: ${e}`)}function h(e){try{n.unlinkSync(e)}catch(e){if(d(e)!==s)throw e}}function g(e,r,i){let s=`${e}.${process.pid}.${t()}.tmp`,c;try{c=n.openSync(s,`wx`,i),n.writeFileSync(c,r,a),n.fchmodSync(c,i),n.fsyncSync(c);let t=c;c=void 0,n.closeSync(t);try{return n.linkSync(s,e),!0}catch(t){if(d(t)===o&&m(e)===`file`)return!1;throw t}}finally{if(c!==void 0){let e=c;c=void 0,n.closeSync(e)}h(s)}}function _(e,r,i){let o=`${e}.${process.pid}.${t()}.tmp`,s;try{s=n.openSync(o,`wx`,i),n.writeFileSync(s,r,a),n.fchmodSync(s,i),n.fsyncSync(s);let t=s;s=void 0,n.closeSync(t),n.renameSync(o,e)}finally{if(s!==void 0){let e=s;s=void 0,n.closeSync(e)}h(o)}}function v(e,t,n,i,a){p(e,i);let o=[],s=[],l=[];for(let i of c){let c=r.join(e,i),u=m(c)===`file`;if(n.force){_(c,t[i],a),(u?l:o).push(i);continue}if(u){s.push(i);continue}g(c,t[i],a)?o.push(i):s.push(i)}return{directory:e,created:o,preserved:s,replaced:l}}function y(t=i.homedir(),n={}){return v(e(t),l,n,448,384)}function b(e=process.cwd(),t={}){return v(r.join(r.resolve(e),`.doom`),u,t,493,420)}export{l as DOOM_CONFIG_TEMPLATES,c as GLOBAL_DOOM_SEED_FILES,u as REPOSITORY_DOOM_CONFIG_TEMPLATES,y as initializeGlobalDoomConfig,b as initializeRepositoryDoomConfig};
|
|
178
|
+
//# sourceMappingURL=init.mjs.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"init.mjs","names":[],"sources":["../../src/adapters/init.ts"],"sourcesContent":["import { randomUUID } from 'node:crypto';\nimport fs from 'node:fs';\nimport os from 'node:os';\nimport path from 'node:path';\n\nimport { globalDoomConfigDirectory } from './config.ts';\n\nconst PRIVATE_DIRECTORY_MODE = 0o700;\nconst PRIVATE_FILE_MODE = 0o600;\nconst REPOSITORY_DIRECTORY_MODE = 0o755;\nconst REPOSITORY_FILE_MODE = 0o644;\nconst DOOM_DIRECTORY = '.doom';\nconst UTF8_ENCODING = 'utf8';\nconst FILE_ALREADY_EXISTS = 'EEXIST';\nconst FILE_NOT_FOUND = 'ENOENT';\n\n/** The global seed files are processed in this fixed order. */\nexport const GLOBAL_DOOM_SEED_FILES = ['config.yaml', 'modes.yaml', 'domains.yaml', 'profiles.yaml'] as const;\n\ntype DoomSeedFile = (typeof GLOBAL_DOOM_SEED_FILES)[number];\n\n/** Portable defaults for a new global Doom configuration directory. */\nexport const DOOM_CONFIG_TEMPLATES: Readonly<Record<DoomSeedFile, string>> = {\n 'config.yaml': `projectTrust: ask\n\n# Autonomous voice is opt-in and uses an explicitly configured Pi model.\n# voice:\n# autoCapture:\n# model: provider/model-id\n# startPhrases:\n# - hey doom\n# stopPhrases:\n# - stop speaking\n# utteranceIdleMs: 3000\n# tts:\n# engine: macos-say\n# voice: Samantha\n# rate: 190\n`,\n 'modes.yaml': `# A layer is a reusable named bundle of packages, built-in or local extensions,\n# and hook groups. Major modes below choose which layers load together for a session.\n#\n# Layers and modes defined here apply to every repository. A repository's own\n# .doom/modes.yaml is read after this file and replaces any layer or mode of the\n# same name, so a repository can override one entry without restating the rest.\n#\n# Add a layer by giving it a unique name under layers. Local Pi scripts belong\n# under extensions, while installed Pi packages belong under packages:\n# review-tools:\n# extensions:\n# - './extensions/local-review.ts'\n# packages:\n# - '@scope/review-extension'\n# A bare extension name selects a DoomPi built-in. A path beginning with ./ or\n# ../ loads a custom script or extension directory. A bare package loads its\n# ordered package.json pi.extensions entries, while an exported subpath selects\n# one adapter. Relative paths resolve beside this file here (~/.pi/.doom), or\n# from the repository root in .doom/modes.yaml.\n#\n# Use a package mapping when that package accepts configuration. Configuration\n# belongs under the package entry that consumes it, not beside packages.\nlayers:\n team:\n packages:\n - name: '@agimon-ai/doompi-team'\n # Optional Team configuration. Uncomment and choose models available to Pi.\n # config:\n # models:\n # - model: openai-codex/gpt-5.6-luna\n # thinking: xhigh\n # # Tool names excluded from subagents launched by this package. These\n # # remove model-visible tools while preserving hidden team transport.\n # excludeTools: [ask_user_question, intercom, subagent]\n task:\n packages:\n - '@agimon-ai/doompi-task'\n runner:\n packages:\n - '@agimon-ai/doompi-runner'\n ask-user:\n packages:\n - '@agimon-ai/doompi-user-feedback'\n# A major mode explains when it should be used and names its ordered layers.\n# Add another entry under majorMode, then select it with\n# doompi --major-mode <name>. Change defaultMajorMode to make it the default.\ndefaultMajorMode: copilot\nmajorMode:\n minimal:\n description: Lean mode with Team delegation and persistent tasks.\n layers: [team, task]\n copilot:\n description: General-purpose coding mode with Team delegation, persistent tasks, supervised commands, and structured user feedback.\n layers: [team, task, runner, ask-user]\n # review:\n # description: Focused review mode for inspecting changes and reporting risks.\n # layers: [team, task, ask-user]\n`,\n 'domains.yaml': `# Plugins are named once in this catalog, then selected by one or more domains.\n# DoomPi automatically inspects personal and repository Codex marketplaces.\n# Each configured root may also be a folder whose direct children are plugins;\n# use roots: [plugins] to discover a repository plugin folder without one entry\n# per plugin. Discovery never scans recursively.\ndefaultDomains: [default]\nplugins:\n roots: []\n entries: {}\n # Local paths resolve beside this file in ~/.pi/.doom. Repository paths in a\n # repository .doom/domains.yaml resolve from that repository root.\n # entries:\n # development:\n # source: local\n # path: plugins/development\n # remote-review:\n # source: url\n # url: https://github.com/acme/review-plugin.git\n # ref: v1.2.0\n # published-review:\n # source: npm\n # package: '@acme/review-plugin'\n # version: 1.2.0\n# Domains carry descriptions and refer to catalog names, not filesystem paths.\ndomains:\n default:\n description: Shared skills and repository MCP only.\n plugins: []\n # development:\n # description: TypeScript implementation and review tools.\n # plugins:\n # - development\n # # Mapping form can load only selected resources from a shared plugin.\n # - name: remote-review\n # skills: [typescript]\n # agents: [reviewer]\n # hooks: false\n # mcp: true\n # # Set false only when this domain should omit shared .claude/skills.\n # sharedSkills: false\n# Select it with doompi --domains development, or add it to defaultDomains.\n#\n# Aliases let one selection enable multiple domains. Replace the empty mapping\n# below with entries like the commented example.\naliases: {}\n# aliases:\n# work: [default, development]\n`,\n 'profiles.yaml': `# Profiles select a persona and optional environment defaults for a session.\n# Each configured root may itself be a profile or contain direct-child profile\n# folders. A folder is discovered when it contains profile.md, SOUL.md, or\n# AGENTS.md; discovery never scans recursively.\nprofiles:\n roots: []\n entries: {}\n # Roots resolve beside this file in ~/.pi/.doom. Repository roots in a\n # repository .doom/profiles.yaml resolve from that repository root.\n # roots: [agents/acme]\n # Explicit entries override an automatically discovered folder of the same\n # name. Environment values must be strings; already exported values win.\n # entries:\n # writer:\n # persona: agents/special/writer\n # env:\n # BRAND: acme\n # TONE: concise\n# Doom Pi concatenates profile.md, SOUL.md, then AGENTS.md for the persona.\n# Select one with: doompi --profile writer\n`,\n};\n\n/** Standalone defaults for a repository that is trying DoomPi through DPI. */\nexport const REPOSITORY_DOOM_CONFIG_TEMPLATES: Readonly<Record<DoomSeedFile, string>> = {\n 'config.yaml': DOOM_CONFIG_TEMPLATES['config.yaml'],\n 'modes.yaml': `# Repository-local layers and major modes. These entries override personal\n# entries with the same name from ~/.pi/.doom/modes.yaml.\nlayers:\n team:\n packages:\n - name: '@agimon-ai/doompi-team'\n task:\n packages:\n - '@agimon-ai/doompi-task'\n runner:\n packages:\n - '@agimon-ai/doompi-runner'\n ask-user:\n packages:\n - '@agimon-ai/doompi-user-feedback'\ndefaultMajorMode: copilot\nmajorMode:\n minimal:\n description: Lean mode with Team delegation and persistent tasks.\n layers: [team, task]\n copilot:\n description: General-purpose coding mode with delegation, persistent tasks, supervised commands, and structured user feedback.\n layers: [team, task, runner, ask-user]\n`,\n 'domains.yaml': `# Repository-local plugin catalog and domain selection.\ndefaultDomains: [default]\nplugins:\n roots: []\n entries: {}\ndomains:\n default:\n description: Shared skills and repository MCP only.\n plugins: []\naliases: {}\n`,\n 'profiles.yaml': `# Repository-local persona roots and environment defaults.\nprofiles:\n roots: []\n entries: {}\n`,\n};\n\n/** Result of filling a Doom seed directory. File arrays contain names in seed order. */\nexport interface GlobalDoomInitResult {\n directory: string;\n created: string[];\n preserved: string[];\n /** Existing files overwritten from the template. Only ever non-empty under `force`. */\n replaced: string[];\n}\n\nexport interface GlobalDoomInitOptions {\n /**\n * Overwrite existing seed files instead of preserving them.\n *\n * Off by default: init is safe to re-run, and hand-edited config is the\n * normal case rather than the exception.\n */\n force?: boolean;\n}\n\nexport type RepositoryDoomInitOptions = GlobalDoomInitOptions;\nexport type RepositoryDoomInitResult = GlobalDoomInitResult;\n\nfunction errorCode(error: unknown): string | undefined {\n if (!(error instanceof Error)) return undefined;\n const code = (error as NodeJS.ErrnoException).code;\n return typeof code === 'string' ? code : undefined;\n}\n\nfunction ensureDirectory(directory: string, mode: number): void {\n let stats: fs.Stats;\n try {\n stats = fs.lstatSync(directory);\n } catch (error) {\n if (errorCode(error) !== FILE_NOT_FOUND) throw error;\n try {\n fs.mkdirSync(directory, { mode });\n stats = fs.lstatSync(directory);\n } catch (mkdirError) {\n if (errorCode(mkdirError) !== FILE_ALREADY_EXISTS) throw mkdirError;\n stats = fs.lstatSync(directory);\n }\n }\n\n if (stats.isSymbolicLink()) {\n throw new Error(`Refusing to initialize through symlinked directory: ${directory}`);\n }\n if (!stats.isDirectory()) {\n throw new Error(`Doom config path is not a directory: ${directory}`);\n }\n}\n\nfunction ensureDoomDirectory(directory: string, mode: number): void {\n ensureDirectory(path.dirname(directory), mode);\n ensureDirectory(directory, mode);\n}\n\nfunction classifyTarget(targetPath: string): 'missing' | 'file' {\n let stats: fs.Stats;\n try {\n stats = fs.lstatSync(targetPath);\n } catch (error) {\n if (errorCode(error) === FILE_NOT_FOUND) return 'missing';\n throw error;\n }\n\n if (stats.isFile()) return 'file';\n if (stats.isSymbolicLink()) {\n try {\n if (fs.statSync(targetPath).isFile()) return 'file';\n } catch (error) {\n throw new Error(`Doom config seed symlink is not file-like: ${targetPath}`, { cause: error });\n }\n }\n throw new Error(`Doom config seed path is not file-like: ${targetPath}`);\n}\n\nfunction cleanupTemporaryFile(temporaryPath: string): void {\n try {\n fs.unlinkSync(temporaryPath);\n } catch (error) {\n if (errorCode(error) !== FILE_NOT_FOUND) throw error;\n }\n}\n\nfunction publishExclusively(targetPath: string, content: string, mode: number): boolean {\n const temporaryPath = `${targetPath}.${process.pid}.${randomUUID()}.tmp`;\n let fileDescriptor: number | undefined;\n try {\n fileDescriptor = fs.openSync(temporaryPath, 'wx', mode);\n fs.writeFileSync(fileDescriptor, content, UTF8_ENCODING);\n fs.fchmodSync(fileDescriptor, mode);\n fs.fsyncSync(fileDescriptor);\n const descriptorToClose = fileDescriptor;\n fileDescriptor = undefined;\n fs.closeSync(descriptorToClose);\n\n try {\n fs.linkSync(temporaryPath, targetPath);\n return true;\n } catch (error) {\n if (errorCode(error) === FILE_ALREADY_EXISTS && classifyTarget(targetPath) === 'file') return false;\n throw error;\n }\n } finally {\n if (fileDescriptor !== undefined) {\n const descriptorToClose = fileDescriptor;\n fileDescriptor = undefined;\n fs.closeSync(descriptorToClose);\n }\n cleanupTemporaryFile(temporaryPath);\n }\n}\n\n/**\n * Replaces a seed file with the template, atomically.\n *\n * The rename swaps the directory entry in one step, so a reader either sees the\n * whole old file or the whole new one. Renaming onto a symlinked seed replaces\n * the link rather than writing through it.\n */\nfunction publishForcefully(targetPath: string, content: string, mode: number): void {\n const temporaryPath = `${targetPath}.${process.pid}.${randomUUID()}.tmp`;\n let fileDescriptor: number | undefined;\n try {\n fileDescriptor = fs.openSync(temporaryPath, 'wx', mode);\n fs.writeFileSync(fileDescriptor, content, UTF8_ENCODING);\n fs.fchmodSync(fileDescriptor, mode);\n fs.fsyncSync(fileDescriptor);\n const descriptorToClose = fileDescriptor;\n fileDescriptor = undefined;\n fs.closeSync(descriptorToClose);\n\n fs.renameSync(temporaryPath, targetPath);\n } finally {\n if (fileDescriptor !== undefined) {\n const descriptorToClose = fileDescriptor;\n fileDescriptor = undefined;\n fs.closeSync(descriptorToClose);\n }\n cleanupTemporaryFile(temporaryPath);\n }\n}\n\nfunction initializeDoomConfig(\n directory: string,\n templates: Readonly<Record<DoomSeedFile, string>>,\n options: GlobalDoomInitOptions,\n directoryMode: number,\n fileMode: number,\n): GlobalDoomInitResult {\n ensureDoomDirectory(directory, directoryMode);\n\n const created: string[] = [];\n const preserved: string[] = [];\n const replaced: string[] = [];\n for (const fileName of GLOBAL_DOOM_SEED_FILES) {\n const targetPath = path.join(directory, fileName);\n const existed = classifyTarget(targetPath) === 'file';\n\n if (options.force) {\n publishForcefully(targetPath, templates[fileName], fileMode);\n (existed ? replaced : created).push(fileName);\n continue;\n }\n if (existed) {\n preserved.push(fileName);\n continue;\n }\n if (publishExclusively(targetPath, templates[fileName], fileMode)) created.push(fileName);\n else preserved.push(fileName);\n }\n\n return { directory, created, preserved, replaced };\n}\n\n/**\n * Fills missing global seed files.\n *\n * Existing files are left alone so that re-running init never discards\n * hand-edited config; pass `force` to overwrite them from the template.\n */\nexport function initializeGlobalDoomConfig(\n homeDirectory = os.homedir(),\n options: GlobalDoomInitOptions = {},\n): GlobalDoomInitResult {\n return initializeDoomConfig(\n globalDoomConfigDirectory(homeDirectory),\n DOOM_CONFIG_TEMPLATES,\n options,\n PRIVATE_DIRECTORY_MODE,\n PRIVATE_FILE_MODE,\n );\n}\n\n/** Seeds repository-local configuration without creating or changing Pi settings. */\nexport function initializeRepositoryDoomConfig(\n repositoryRoot = process.cwd(),\n options: RepositoryDoomInitOptions = {},\n): RepositoryDoomInitResult {\n return initializeDoomConfig(\n path.join(path.resolve(repositoryRoot), DOOM_DIRECTORY),\n REPOSITORY_DOOM_CONFIG_TEMPLATES,\n options,\n REPOSITORY_DIRECTORY_MODE,\n REPOSITORY_FILE_MODE,\n );\n}\n"],"mappings":"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"}
|
|
@@ -0,0 +1,2 @@
|
|
|
1
|
+
const e=require("../_virtual/_rolldown/runtime.cjs"),t=require("./config.cjs");let n=require("node:fs");n=e.__toESM(n,1);let r=require("node:path");r=e.__toESM(r,1);let i=require("node:os");i=e.__toESM(i,1);let a=require("yaml");const o=`.doom`;function s(e,n,a=i.default.homedir()){let s=t.globalDoomConfigDirectory(a);return[{filePath:r.default.join(s,e),baseDirectory:s},{filePath:r.default.join(n,o,e),baseDirectory:n}]}function c(e,t,r=i.default.homedir()){let o=s(e,t,r),c=[];for(let e of o){if(!n.default.existsSync(e.filePath))continue;let t=n.default.readFileSync(e.filePath,`utf8`),r=(0,a.parse)(t);r!=null&&c.push({...e,text:t,document:r})}return c}function l(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}exports.DOOM_DIR=o,exports.doomConfigCandidates=s,exports.mergeNamedSources=l,exports.readDoomConfigSources=c;
|
|
2
|
+
//# sourceMappingURL=layeredConfig.cjs.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"layeredConfig.cjs","names":["os","globalDoomConfigDirectory","path","fs","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":"qOAOA,MAAa,EAAW,QAgCxB,SAAgB,EACd,EACA,EACA,EAAwBA,EAAAA,QAAG,QAAQ,EACiB,CACpD,IAAM,EAAkBC,EAAAA,0BAA0B,CAAa,EAC/D,MAAO,CACL,CAAE,SAAUC,EAAAA,QAAK,KAAK,EAAiB,CAAQ,EAAG,cAAe,CAAgB,EACjF,CAAE,SAAUA,EAAAA,QAAK,KAAK,EAAU,EAAU,CAAQ,EAAG,cAAe,CAAS,CAC/E,CACF,CAEA,SAAgB,EACd,EACA,EACA,EAAwBF,EAAAA,QAAG,QAAQ,EACC,CACpC,IAAM,EAAa,EAAqB,EAAU,EAAU,CAAa,EAEnE,EAA8C,CAAC,EACrD,IAAK,IAAM,KAAa,EAAY,CAClC,GAAI,CAACG,EAAAA,QAAG,WAAW,EAAU,QAAQ,EAAG,SACxC,IAAM,EAAOA,EAAAA,QAAG,aAAa,EAAU,SAAU,MAAa,EACxD,GAAA,EAAWC,EAAAA,MAAAA,CAAU,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,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.cts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"layeredConfig.d.cts","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"}
|