@agimon-ai/po-config 0.0.0-alpha.0

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.
Files changed (170) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +170 -0
  3. package/dist/agentPluginMcp.cjs +322 -0
  4. package/dist/agentPluginMcp.cjs.map +1 -0
  5. package/dist/agentPluginMcp.d.mts +38 -0
  6. package/dist/agentPluginMcp.d.mts.map +1 -0
  7. package/dist/agentPluginMcp.mjs +318 -0
  8. package/dist/agentPluginMcp.mjs.map +1 -0
  9. package/dist/apiContracts.cjs +203 -0
  10. package/dist/apiContracts.cjs.map +1 -0
  11. package/dist/apiContracts.d.mts +53 -0
  12. package/dist/apiContracts.d.mts.map +1 -0
  13. package/dist/apiContracts.mjs +198 -0
  14. package/dist/apiContracts.mjs.map +1 -0
  15. package/dist/atomicJson-1W0WhuFF.mjs +44 -0
  16. package/dist/atomicJson-1W0WhuFF.mjs.map +1 -0
  17. package/dist/atomicJson-Dt2z_DXl.cjs +52 -0
  18. package/dist/atomicJson-Dt2z_DXl.cjs.map +1 -0
  19. package/dist/atomicJson.cjs +3 -0
  20. package/dist/atomicJson.d.mts +2 -0
  21. package/dist/atomicJson.mjs +2 -0
  22. package/dist/config-BUw5kHsx.cjs +219 -0
  23. package/dist/config-BUw5kHsx.cjs.map +1 -0
  24. package/dist/config-CKA07FxG.mjs +162 -0
  25. package/dist/config-CKA07FxG.mjs.map +1 -0
  26. package/dist/config-Cm3EV1jp.d.mts +320 -0
  27. package/dist/config-Cm3EV1jp.d.mts.map +1 -0
  28. package/dist/config-NSHRd6na.mjs +2 -0
  29. package/dist/config-zZz80Mh5.cjs +1 -0
  30. package/dist/config.cjs +24 -0
  31. package/dist/config.d.mts +3 -0
  32. package/dist/config.mjs +3 -0
  33. package/dist/configPolicy--TNX7feH.mjs +718 -0
  34. package/dist/configPolicy--TNX7feH.mjs.map +1 -0
  35. package/dist/configPolicy-DmsZEp0t.cjs +795 -0
  36. package/dist/configPolicy-DmsZEp0t.cjs.map +1 -0
  37. package/dist/configSchema.cjs +0 -0
  38. package/dist/configSchema.d.mts +2 -0
  39. package/dist/configSchema.mjs +1 -0
  40. package/dist/configWriter-BTuinLjs.cjs +150 -0
  41. package/dist/configWriter-BTuinLjs.cjs.map +1 -0
  42. package/dist/configWriter-BgkGaLrf.mjs +130 -0
  43. package/dist/configWriter-BgkGaLrf.mjs.map +1 -0
  44. package/dist/configWriter.cjs +5 -0
  45. package/dist/configWriter.d.mts +2 -0
  46. package/dist/configWriter.mjs +2 -0
  47. package/dist/domains-CBYkuxs5.cjs +727 -0
  48. package/dist/domains-CBYkuxs5.cjs.map +1 -0
  49. package/dist/domains-DZOu9vYM.mjs +633 -0
  50. package/dist/domains-DZOu9vYM.mjs.map +1 -0
  51. package/dist/domains.cjs +19 -0
  52. package/dist/domains.d.mts +3 -0
  53. package/dist/domains.mjs +3 -0
  54. package/dist/extensions/mcp-ui.mjs +101 -0
  55. package/dist/extensions/mcp-ui.mjs.map +1 -0
  56. package/dist/extensions/mcp.cjs +171 -0
  57. package/dist/extensions/mcp.cjs.map +1 -0
  58. package/dist/extensions/mcp.d.mts +5 -0
  59. package/dist/extensions/mcp.d.mts.map +1 -0
  60. package/dist/extensions/mcp.mjs +166 -0
  61. package/dist/extensions/mcp.mjs.map +1 -0
  62. package/dist/extensions/server.cjs +504 -0
  63. package/dist/extensions/server.cjs.map +1 -0
  64. package/dist/extensions/server.d.mts +5 -0
  65. package/dist/extensions/server.d.mts.map +1 -0
  66. package/dist/extensions/server.mjs +499 -0
  67. package/dist/extensions/server.mjs.map +1 -0
  68. package/dist/harnessState-CCyBeutB.cjs +188 -0
  69. package/dist/harnessState-CCyBeutB.cjs.map +1 -0
  70. package/dist/harnessState-Dn_S7fB9.mjs +163 -0
  71. package/dist/harnessState-Dn_S7fB9.mjs.map +1 -0
  72. package/dist/harnessState.cjs +6 -0
  73. package/dist/harnessState.d.mts +2 -0
  74. package/dist/harnessState.mjs +2 -0
  75. package/dist/harnessStore-CJSxdSkV.cjs +343 -0
  76. package/dist/harnessStore-CJSxdSkV.cjs.map +1 -0
  77. package/dist/harnessStore-CltwLB7M.mjs +262 -0
  78. package/dist/harnessStore-CltwLB7M.mjs.map +1 -0
  79. package/dist/harnessStore.cjs +15 -0
  80. package/dist/harnessStore.d.mts +2 -0
  81. package/dist/harnessStore.mjs +2 -0
  82. package/dist/index-BAaTySaM.d.mts +35 -0
  83. package/dist/index-BAaTySaM.d.mts.map +1 -0
  84. package/dist/index-BT29GZx5.d.mts +142 -0
  85. package/dist/index-BT29GZx5.d.mts.map +1 -0
  86. package/dist/index-B_lp0W3U.d.mts +114 -0
  87. package/dist/index-B_lp0W3U.d.mts.map +1 -0
  88. package/dist/index-C6GaYjq-.d.mts +6 -0
  89. package/dist/index-C6GaYjq-.d.mts.map +1 -0
  90. package/dist/index-CIQrKS1A.d.mts +50 -0
  91. package/dist/index-CIQrKS1A.d.mts.map +1 -0
  92. package/dist/index-CRcoVYXz.d.mts +39 -0
  93. package/dist/index-CRcoVYXz.d.mts.map +1 -0
  94. package/dist/index-CVlciCJF.d.mts +40 -0
  95. package/dist/index-CVlciCJF.d.mts.map +1 -0
  96. package/dist/index-CeOk2kqs.d.mts +118 -0
  97. package/dist/index-CeOk2kqs.d.mts.map +1 -0
  98. package/dist/index-Ch7ptOkW.d.mts +54 -0
  99. package/dist/index-Ch7ptOkW.d.mts.map +1 -0
  100. package/dist/index-Cvdt-Y-i.d.mts +66 -0
  101. package/dist/index-Cvdt-Y-i.d.mts.map +1 -0
  102. package/dist/index-DJpG-I9K.d.mts +122 -0
  103. package/dist/index-DJpG-I9K.d.mts.map +1 -0
  104. package/dist/index-DNk4q0Qm.d.mts +81 -0
  105. package/dist/index-DNk4q0Qm.d.mts.map +1 -0
  106. package/dist/index.cjs +121 -0
  107. package/dist/index.d.mts +15 -0
  108. package/dist/index.mjs +15 -0
  109. package/dist/init-C_9nyp3-.cjs +448 -0
  110. package/dist/init-C_9nyp3-.cjs.map +1 -0
  111. package/dist/init-DJ6wm-dr.mjs +415 -0
  112. package/dist/init-DJ6wm-dr.mjs.map +1 -0
  113. package/dist/init.cjs +7 -0
  114. package/dist/init.d.mts +2 -0
  115. package/dist/init.mjs +2 -0
  116. package/dist/layeredConfig-B922ibgn.mjs +67 -0
  117. package/dist/layeredConfig-B922ibgn.mjs.map +1 -0
  118. package/dist/layeredConfig-DdI5ysUf.cjs +94 -0
  119. package/dist/layeredConfig-DdI5ysUf.cjs.map +1 -0
  120. package/dist/layeredConfig.cjs +6 -0
  121. package/dist/layeredConfig.d.mts +2 -0
  122. package/dist/layeredConfig.mjs +2 -0
  123. package/dist/majorModes-CmPLEpMT.mjs +333 -0
  124. package/dist/majorModes-CmPLEpMT.mjs.map +1 -0
  125. package/dist/majorModes-DPhVMuhT.cjs +383 -0
  126. package/dist/majorModes-DPhVMuhT.cjs.map +1 -0
  127. package/dist/majorModes.cjs +10 -0
  128. package/dist/majorModes.d.mts +2 -0
  129. package/dist/majorModes.mjs +2 -0
  130. package/dist/piConfig-Bx26HMb_.d.mts +33 -0
  131. package/dist/piConfig-Bx26HMb_.d.mts.map +1 -0
  132. package/dist/piConfig-CCBdZXQr.cjs +260 -0
  133. package/dist/piConfig-CCBdZXQr.cjs.map +1 -0
  134. package/dist/piConfig-qGyCbcVj.mjs +197 -0
  135. package/dist/piConfig-qGyCbcVj.mjs.map +1 -0
  136. package/dist/piConfig.cjs +12 -0
  137. package/dist/piConfig.d.mts +2 -0
  138. package/dist/piConfig.mjs +2 -0
  139. package/dist/piContext.cjs +18 -0
  140. package/dist/piContext.d.mts +3 -0
  141. package/dist/piContext.mjs +2 -0
  142. package/dist/profiles-CTrUCmIh.d.mts +27 -0
  143. package/dist/profiles-CTrUCmIh.d.mts.map +1 -0
  144. package/dist/profiles-DnF9DBpd.cjs +552 -0
  145. package/dist/profiles-DnF9DBpd.cjs.map +1 -0
  146. package/dist/profiles-fujQKrS0.mjs +483 -0
  147. package/dist/profiles-fujQKrS0.mjs.map +1 -0
  148. package/dist/profiles.cjs +13 -0
  149. package/dist/profiles.d.mts +25 -0
  150. package/dist/profiles.d.mts.map +1 -0
  151. package/dist/profiles.mjs +2 -0
  152. package/dist/rolldown-runtime-VH7oDXx4.cjs +28 -0
  153. package/dist/selectionSwitch.cjs +70 -0
  154. package/dist/selectionSwitch.cjs.map +1 -0
  155. package/dist/selectionSwitch.d.mts +30 -0
  156. package/dist/selectionSwitch.d.mts.map +1 -0
  157. package/dist/selectionSwitch.mjs +64 -0
  158. package/dist/selectionSwitch.mjs.map +1 -0
  159. package/dist/sessionConfig-Boh4Fdje.cjs +342 -0
  160. package/dist/sessionConfig-Boh4Fdje.cjs.map +1 -0
  161. package/dist/sessionConfig-CtLoc-lO.mjs +240 -0
  162. package/dist/sessionConfig-CtLoc-lO.mjs.map +1 -0
  163. package/dist/types.cjs +9 -0
  164. package/dist/types.d.mts +2 -0
  165. package/dist/types.mjs +2 -0
  166. package/llms.txt +12 -0
  167. package/package.json +206 -0
  168. package/src/prompts/po-author-config/SKILL.md +26 -0
  169. package/src/prompts/po-author-config/agents/openai.yaml +4 -0
  170. package/src/prompts/po-author-config/references/config-contract.md +201 -0
@@ -0,0 +1,198 @@
1
+ import { defineApiContract, jsonApiResponses } from "@agimon-ai/po-core/apiContracts";
2
+ import { Type } from "typebox";
3
+ //#region src/schemas/apiContracts.ts
4
+ const Text = Type.String();
5
+ const Optional = Type.Optional;
6
+ const Strings = Type.Array(Text);
7
+ const NullableText = Type.Union([Text, Type.Null()]);
8
+ const Scope = Type.Union([Type.Literal("global"), Type.Literal("repository")]);
9
+ const Origin = Type.Union([
10
+ Type.Literal("global"),
11
+ Type.Literal("repository"),
12
+ Type.Literal("default")
13
+ ]);
14
+ const SettingsConfigSchema = Type.Object({
15
+ repoRoot: Text,
16
+ hashes: Type.Object({
17
+ global: Text,
18
+ repository: Text
19
+ }),
20
+ values: Type.Record(Text, Type.Object({
21
+ value: Optional(Text),
22
+ origin: Origin,
23
+ scope: Type.Union([Scope, Type.Literal("both")])
24
+ }))
25
+ });
26
+ const SettingsEditSchema = Type.Object({
27
+ keyPath: Strings,
28
+ value: Type.Union([
29
+ Text,
30
+ Type.Number(),
31
+ Type.Null()
32
+ ])
33
+ });
34
+ const SettingsWriteSchema = Type.Union([Type.Object({
35
+ repoRoot: Text,
36
+ scope: Scope,
37
+ ...SettingsEditSchema.properties,
38
+ expectedHash: Text
39
+ }), Type.Object({
40
+ repoRoot: Text,
41
+ scope: Scope,
42
+ edits: Type.Array(SettingsEditSchema, {
43
+ minItems: 1,
44
+ maxItems: 100
45
+ }),
46
+ expectedHash: Text
47
+ })]);
48
+ const Repository = Type.Object({
49
+ id: Text,
50
+ name: Text,
51
+ path: Text,
52
+ active: Type.Boolean()
53
+ });
54
+ const Catalog = Type.Array(Type.Object({
55
+ name: Text,
56
+ description: Optional(Text),
57
+ expandsTo: Optional(Strings),
58
+ layers: Optional(Strings)
59
+ }));
60
+ const SelectionText = Type.Object({
61
+ effective: Optional(Text),
62
+ repository: Optional(Text),
63
+ origin: Origin
64
+ });
65
+ const SelectionStrings = Type.Object({
66
+ effective: Optional(Strings),
67
+ repository: Optional(Strings),
68
+ origin: Origin
69
+ });
70
+ const RepositorySettingsSchema = Type.Object({
71
+ repository: Repository,
72
+ hash: Text,
73
+ catalogs: Type.Object({
74
+ majorModes: Catalog,
75
+ domains: Catalog,
76
+ profiles: Catalog
77
+ }),
78
+ selection: Type.Object({
79
+ majorMode: SelectionText,
80
+ domains: SelectionStrings,
81
+ profile: SelectionText
82
+ })
83
+ });
84
+ const RepositorySelectionWriteSchema = Type.Object({
85
+ repositoryId: Text,
86
+ expectedHash: Text,
87
+ changes: Type.Object({
88
+ majorMode: Optional(NullableText),
89
+ domains: Optional(Type.Union([Strings, Type.Null()])),
90
+ profile: Optional(NullableText)
91
+ })
92
+ });
93
+ const Images = Type.Object({
94
+ autoResize: Type.Boolean(),
95
+ maxDimension: Type.Number(),
96
+ minDimension: Type.Number(),
97
+ maxAllowedDimension: Type.Number()
98
+ });
99
+ const http = ["global", "workspace"].flatMap((scope) => {
100
+ const common = {
101
+ scope,
102
+ basePath: "settings",
103
+ authentication: "owner"
104
+ };
105
+ return [
106
+ {
107
+ ...common,
108
+ id: "config",
109
+ path: "/",
110
+ method: "GET",
111
+ description: "Read selected settings keys and file hashes.",
112
+ parameters: [{
113
+ name: "key",
114
+ in: "query",
115
+ required: false,
116
+ schema: Strings
117
+ }],
118
+ responses: jsonApiResponses(SettingsConfigSchema)
119
+ },
120
+ {
121
+ ...common,
122
+ id: "value",
123
+ path: "/value",
124
+ method: "PUT",
125
+ description: "Write a setting with an optimistic file hash.",
126
+ body: {
127
+ contentType: "application/json",
128
+ required: true,
129
+ schema: SettingsWriteSchema
130
+ },
131
+ responses: jsonApiResponses(SettingsConfigSchema)
132
+ },
133
+ {
134
+ ...common,
135
+ id: "repositories",
136
+ path: "/repositories",
137
+ method: "GET",
138
+ description: "List admitted repositories.",
139
+ responses: jsonApiResponses(Type.Object({ repositories: Type.Array(Repository) }))
140
+ },
141
+ {
142
+ ...common,
143
+ id: "repository",
144
+ path: "/repository",
145
+ method: "GET",
146
+ description: "Read the mounted workspace catalog and selection.",
147
+ availability: "Requires a workspace mount; global returns 404.",
148
+ responses: jsonApiResponses(RepositorySettingsSchema)
149
+ },
150
+ {
151
+ ...common,
152
+ id: "selection",
153
+ path: "/repository/selection",
154
+ method: "PUT",
155
+ description: "Update the mounted workspace selection.",
156
+ availability: "Requires a workspace mount; global returns 404.",
157
+ body: {
158
+ contentType: "application/json",
159
+ required: true,
160
+ schema: RepositorySelectionWriteSchema
161
+ },
162
+ responses: jsonApiResponses(RepositorySettingsSchema)
163
+ },
164
+ ...scope === "global" ? [{
165
+ ...common,
166
+ id: "images.get",
167
+ path: "/images",
168
+ method: "GET",
169
+ description: "Read image resizing limits.",
170
+ responses: jsonApiResponses(Images)
171
+ }, {
172
+ ...common,
173
+ id: "images.put",
174
+ path: "/images",
175
+ method: "PUT",
176
+ description: "Update image resizing settings; dimensions are clamped.",
177
+ body: {
178
+ contentType: "application/json",
179
+ required: true,
180
+ schema: Type.Object({
181
+ autoResize: Optional(Type.Boolean()),
182
+ maxDimension: Optional(Type.Number())
183
+ })
184
+ },
185
+ responses: jsonApiResponses(Images)
186
+ }] : []
187
+ ];
188
+ });
189
+ const apiContracts = defineApiContract({
190
+ version: 1,
191
+ http,
192
+ sockets: [],
193
+ dynamic: []
194
+ });
195
+ //#endregion
196
+ export { apiContracts, apiContracts as default };
197
+
198
+ //# sourceMappingURL=apiContracts.mjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"apiContracts.mjs","names":[],"sources":["../src/schemas/apiContracts.ts"],"sourcesContent":["import { defineApiContract, jsonApiResponses, type DoomHttpContract } from '@agimon-ai/po-core/apiContracts';\nimport { Type } from 'typebox';\n\nconst Text = Type.String();\nconst Optional = Type.Optional;\nconst Strings = Type.Array(Text);\nconst NullableText = Type.Union([Text, Type.Null()]);\nconst Scope = Type.Union([Type.Literal('global'), Type.Literal('repository')]);\nconst Origin = Type.Union([Type.Literal('global'), Type.Literal('repository'), Type.Literal('default')]);\nexport const SettingsConfigSchema = Type.Object({\n repoRoot: Text,\n hashes: Type.Object({ global: Text, repository: Text }),\n values: Type.Record(\n Text,\n Type.Object({\n value: Optional(Text),\n origin: Origin,\n scope: Type.Union([Scope, Type.Literal('both')]),\n }),\n ),\n});\nconst SettingsEditSchema = Type.Object({ keyPath: Strings, value: Type.Union([Text, Type.Number(), Type.Null()]) });\nexport const SettingsWriteSchema = Type.Union([\n Type.Object({ repoRoot: Text, scope: Scope, ...SettingsEditSchema.properties, expectedHash: Text }),\n Type.Object({\n repoRoot: Text,\n scope: Scope,\n edits: Type.Array(SettingsEditSchema, { minItems: 1, maxItems: 100 }),\n expectedHash: Text,\n }),\n]);\n\nconst Repository = Type.Object({ id: Text, name: Text, path: Text, active: Type.Boolean() });\nconst Catalog = Type.Array(\n Type.Object({ name: Text, description: Optional(Text), expandsTo: Optional(Strings), layers: Optional(Strings) }),\n);\nconst SelectionText = Type.Object({ effective: Optional(Text), repository: Optional(Text), origin: Origin });\nconst SelectionStrings = Type.Object({ effective: Optional(Strings), repository: Optional(Strings), origin: Origin });\nexport const RepositorySettingsSchema = Type.Object({\n repository: Repository,\n hash: Text,\n catalogs: Type.Object({ majorModes: Catalog, domains: Catalog, profiles: Catalog }),\n selection: Type.Object({ majorMode: SelectionText, domains: SelectionStrings, profile: SelectionText }),\n});\nexport const RepositorySelectionWriteSchema = Type.Object({\n repositoryId: Text,\n expectedHash: Text,\n changes: Type.Object({\n majorMode: Optional(NullableText),\n domains: Optional(Type.Union([Strings, Type.Null()])),\n profile: Optional(NullableText),\n }),\n});\nconst Images = Type.Object({\n autoResize: Type.Boolean(),\n maxDimension: Type.Number(),\n minDimension: Type.Number(),\n maxAllowedDimension: Type.Number(),\n});\nconst http: DoomHttpContract[] = (['global', 'workspace'] as const).flatMap((scope) => {\n const common = { scope, basePath: 'settings', authentication: 'owner' as const };\n return [\n {\n ...common,\n id: 'config',\n path: '/',\n method: 'GET',\n description: 'Read selected settings keys and file hashes.',\n parameters: [{ name: 'key', in: 'query', required: false, schema: Strings }],\n responses: jsonApiResponses(SettingsConfigSchema),\n },\n {\n ...common,\n id: 'value',\n path: '/value',\n method: 'PUT',\n description: 'Write a setting with an optimistic file hash.',\n body: { contentType: 'application/json', required: true, schema: SettingsWriteSchema },\n responses: jsonApiResponses(SettingsConfigSchema),\n },\n {\n ...common,\n id: 'repositories',\n path: '/repositories',\n method: 'GET',\n description: 'List admitted repositories.',\n responses: jsonApiResponses(Type.Object({ repositories: Type.Array(Repository) })),\n },\n {\n ...common,\n id: 'repository',\n path: '/repository',\n method: 'GET',\n description: 'Read the mounted workspace catalog and selection.',\n availability: 'Requires a workspace mount; global returns 404.',\n responses: jsonApiResponses(RepositorySettingsSchema),\n },\n {\n ...common,\n id: 'selection',\n path: '/repository/selection',\n method: 'PUT',\n description: 'Update the mounted workspace selection.',\n availability: 'Requires a workspace mount; global returns 404.',\n body: { contentType: 'application/json', required: true, schema: RepositorySelectionWriteSchema },\n responses: jsonApiResponses(RepositorySettingsSchema),\n },\n ...(scope === 'global'\n ? [\n {\n ...common,\n id: 'images.get',\n path: '/images',\n method: 'GET' as const,\n description: 'Read image resizing limits.',\n responses: jsonApiResponses(Images),\n },\n {\n ...common,\n id: 'images.put',\n path: '/images',\n method: 'PUT' as const,\n description: 'Update image resizing settings; dimensions are clamped.',\n body: {\n contentType: 'application/json',\n required: true,\n schema: Type.Object({ autoResize: Optional(Type.Boolean()), maxDimension: Optional(Type.Number()) }),\n },\n responses: jsonApiResponses(Images),\n },\n ]\n : []),\n ] satisfies DoomHttpContract[];\n});\nexport const apiContracts = defineApiContract({ version: 1, http, sockets: [], dynamic: [] });\nexport default apiContracts;\n"],"mappings":"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"}
@@ -0,0 +1,44 @@
1
+ import { randomUUID } from "node:crypto";
2
+ import fs from "node:fs";
3
+ import path from "node:path";
4
+ //#region src/services/atomicJson/index.ts
5
+ /**
6
+ * Private atomic JSON writes.
7
+ *
8
+ * Write to a uniquely named temporary file in the destination directory, then
9
+ * rename onto the target. Rename is atomic within a filesystem, so a reader
10
+ * sees either the previous file or the complete new one and never a partial
11
+ * write. The temporary name carries the pid and a random suffix, so two
12
+ * processes writing the same target cannot collide on it.
13
+ *
14
+ * This prevents torn reads. It does NOT prevent lost updates: two writers doing
15
+ * read-modify-write still clobber each other, because the rename only publishes
16
+ * what the caller already computed. Harness state avoids that by giving every
17
+ * process a file it owns rather than by locking.
18
+ *
19
+ * AVOID:
20
+ * - Treating this as a lock
21
+ * - Leaving the temporary file behind when the write fails
22
+ */
23
+ const PRIVATE_FILE_MODE = 384;
24
+ const PRIVATE_DIRECTORY_MODE = 448;
25
+ const TEMPORARY_SUFFIX = ".tmp";
26
+ /** Writes JSON readable by its owner only, replacing the target atomically. */
27
+ function writePrivateAtomicJson(filePath, value) {
28
+ fs.mkdirSync(path.dirname(filePath), {
29
+ mode: PRIVATE_DIRECTORY_MODE,
30
+ recursive: true
31
+ });
32
+ const temporaryPath = `${filePath}.${process.pid}.${randomUUID()}${TEMPORARY_SUFFIX}`;
33
+ try {
34
+ fs.writeFileSync(temporaryPath, `${JSON.stringify(value, null, 2)}\n`, { mode: PRIVATE_FILE_MODE });
35
+ fs.renameSync(temporaryPath, filePath);
36
+ } catch (error) {
37
+ fs.rmSync(temporaryPath, { force: true });
38
+ throw error;
39
+ }
40
+ }
41
+ //#endregion
42
+ export { writePrivateAtomicJson as t };
43
+
44
+ //# sourceMappingURL=atomicJson-1W0WhuFF.mjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"atomicJson-1W0WhuFF.mjs","names":[],"sources":["../src/services/atomicJson/index.ts"],"sourcesContent":["import { randomUUID } from 'node:crypto';\nimport fs from 'node:fs';\nimport path from 'node:path';\n\n/**\n * Private atomic JSON writes.\n *\n * Write to a uniquely named temporary file in the destination directory, then\n * rename onto the target. Rename is atomic within a filesystem, so a reader\n * sees either the previous file or the complete new one and never a partial\n * write. The temporary name carries the pid and a random suffix, so two\n * processes writing the same target cannot collide on it.\n *\n * This prevents torn reads. It does NOT prevent lost updates: two writers doing\n * read-modify-write still clobber each other, because the rename only publishes\n * what the caller already computed. Harness state avoids that by giving every\n * process a file it owns rather than by locking.\n *\n * AVOID:\n * - Treating this as a lock\n * - Leaving the temporary file behind when the write fails\n */\n\nconst PRIVATE_FILE_MODE = 0o600;\nconst PRIVATE_DIRECTORY_MODE = 0o700;\nconst TEMPORARY_SUFFIX = '.tmp';\n\n/** Writes JSON readable by its owner only, replacing the target atomically. */\nexport function writePrivateAtomicJson(filePath: string, value: unknown): void {\n fs.mkdirSync(path.dirname(filePath), { mode: PRIVATE_DIRECTORY_MODE, recursive: true });\n const temporaryPath = `${filePath}.${process.pid}.${randomUUID()}${TEMPORARY_SUFFIX}`;\n try {\n fs.writeFileSync(temporaryPath, `${JSON.stringify(value, null, 2)}\\n`, { mode: PRIVATE_FILE_MODE });\n fs.renameSync(temporaryPath, filePath);\n } catch (error) {\n fs.rmSync(temporaryPath, { force: true });\n throw error;\n }\n}\n"],"mappings":";;;;;;;;;;;;;;;;;;;;;;AAuBA,MAAM,oBAAoB;AAC1B,MAAM,yBAAyB;AAC/B,MAAM,mBAAmB;;AAGzB,SAAgB,uBAAuB,UAAkB,OAAsB;CAC7E,GAAG,UAAU,KAAK,QAAQ,QAAQ,GAAG;EAAE,MAAM;EAAwB,WAAW;CAAK,CAAC;CACtF,MAAM,gBAAgB,GAAG,SAAS,GAAG,QAAQ,IAAI,GAAG,WAAW,IAAI;CACnE,IAAI;EACF,GAAG,cAAc,eAAe,GAAG,KAAK,UAAU,OAAO,MAAM,CAAC,EAAE,KAAK,EAAE,MAAM,kBAAkB,CAAC;EAClG,GAAG,WAAW,eAAe,QAAQ;CACvC,SAAS,OAAO;EACd,GAAG,OAAO,eAAe,EAAE,OAAO,KAAK,CAAC;EACxC,MAAM;CACR;AACF"}
@@ -0,0 +1,52 @@
1
+ const require_rolldown_runtime = require("./rolldown-runtime-VH7oDXx4.cjs");
2
+ let node_crypto = require("node:crypto");
3
+ let node_fs = require("node:fs");
4
+ node_fs = require_rolldown_runtime.__toESM(node_fs, 1);
5
+ let node_path = require("node:path");
6
+ node_path = require_rolldown_runtime.__toESM(node_path, 1);
7
+ //#region src/services/atomicJson/index.ts
8
+ /**
9
+ * Private atomic JSON writes.
10
+ *
11
+ * Write to a uniquely named temporary file in the destination directory, then
12
+ * rename onto the target. Rename is atomic within a filesystem, so a reader
13
+ * sees either the previous file or the complete new one and never a partial
14
+ * write. The temporary name carries the pid and a random suffix, so two
15
+ * processes writing the same target cannot collide on it.
16
+ *
17
+ * This prevents torn reads. It does NOT prevent lost updates: two writers doing
18
+ * read-modify-write still clobber each other, because the rename only publishes
19
+ * what the caller already computed. Harness state avoids that by giving every
20
+ * process a file it owns rather than by locking.
21
+ *
22
+ * AVOID:
23
+ * - Treating this as a lock
24
+ * - Leaving the temporary file behind when the write fails
25
+ */
26
+ const PRIVATE_FILE_MODE = 384;
27
+ const PRIVATE_DIRECTORY_MODE = 448;
28
+ const TEMPORARY_SUFFIX = ".tmp";
29
+ /** Writes JSON readable by its owner only, replacing the target atomically. */
30
+ function writePrivateAtomicJson(filePath, value) {
31
+ node_fs.default.mkdirSync(node_path.default.dirname(filePath), {
32
+ mode: PRIVATE_DIRECTORY_MODE,
33
+ recursive: true
34
+ });
35
+ const temporaryPath = `${filePath}.${process.pid}.${(0, node_crypto.randomUUID)()}${TEMPORARY_SUFFIX}`;
36
+ try {
37
+ node_fs.default.writeFileSync(temporaryPath, `${JSON.stringify(value, null, 2)}\n`, { mode: PRIVATE_FILE_MODE });
38
+ node_fs.default.renameSync(temporaryPath, filePath);
39
+ } catch (error) {
40
+ node_fs.default.rmSync(temporaryPath, { force: true });
41
+ throw error;
42
+ }
43
+ }
44
+ //#endregion
45
+ Object.defineProperty(exports, "writePrivateAtomicJson", {
46
+ enumerable: true,
47
+ get: function() {
48
+ return writePrivateAtomicJson;
49
+ }
50
+ });
51
+
52
+ //# sourceMappingURL=atomicJson-Dt2z_DXl.cjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"atomicJson-Dt2z_DXl.cjs","names":["path","randomUUID"],"sources":["../src/services/atomicJson/index.ts"],"sourcesContent":["import { randomUUID } from 'node:crypto';\nimport fs from 'node:fs';\nimport path from 'node:path';\n\n/**\n * Private atomic JSON writes.\n *\n * Write to a uniquely named temporary file in the destination directory, then\n * rename onto the target. Rename is atomic within a filesystem, so a reader\n * sees either the previous file or the complete new one and never a partial\n * write. The temporary name carries the pid and a random suffix, so two\n * processes writing the same target cannot collide on it.\n *\n * This prevents torn reads. It does NOT prevent lost updates: two writers doing\n * read-modify-write still clobber each other, because the rename only publishes\n * what the caller already computed. Harness state avoids that by giving every\n * process a file it owns rather than by locking.\n *\n * AVOID:\n * - Treating this as a lock\n * - Leaving the temporary file behind when the write fails\n */\n\nconst PRIVATE_FILE_MODE = 0o600;\nconst PRIVATE_DIRECTORY_MODE = 0o700;\nconst TEMPORARY_SUFFIX = '.tmp';\n\n/** Writes JSON readable by its owner only, replacing the target atomically. */\nexport function writePrivateAtomicJson(filePath: string, value: unknown): void {\n fs.mkdirSync(path.dirname(filePath), { mode: PRIVATE_DIRECTORY_MODE, recursive: true });\n const temporaryPath = `${filePath}.${process.pid}.${randomUUID()}${TEMPORARY_SUFFIX}`;\n try {\n fs.writeFileSync(temporaryPath, `${JSON.stringify(value, null, 2)}\\n`, { mode: PRIVATE_FILE_MODE });\n fs.renameSync(temporaryPath, filePath);\n } catch (error) {\n fs.rmSync(temporaryPath, { force: true });\n throw error;\n }\n}\n"],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;AAuBA,MAAM,oBAAoB;AAC1B,MAAM,yBAAyB;AAC/B,MAAM,mBAAmB;;AAGzB,SAAgB,uBAAuB,UAAkB,OAAsB;CAC7E,QAAA,QAAG,UAAUA,UAAAA,QAAK,QAAQ,QAAQ,GAAG;EAAE,MAAM;EAAwB,WAAW;CAAK,CAAC;CACtF,MAAM,gBAAgB,GAAG,SAAS,GAAG,QAAQ,IAAI,IAAA,GAAGC,YAAAA,WAAAA,CAAW,IAAI;CACnE,IAAI;EACF,QAAA,QAAG,cAAc,eAAe,GAAG,KAAK,UAAU,OAAO,MAAM,CAAC,EAAE,KAAK,EAAE,MAAM,kBAAkB,CAAC;EAClG,QAAA,QAAG,WAAW,eAAe,QAAQ;CACvC,SAAS,OAAO;EACd,QAAA,QAAG,OAAO,eAAe,EAAE,OAAO,KAAK,CAAC;EACxC,MAAM;CACR;AACF"}
@@ -0,0 +1,3 @@
1
+ Object.defineProperty(exports, Symbol.toStringTag, { value: "Module" });
2
+ const require_atomicJson = require("./atomicJson-Dt2z_DXl.cjs");
3
+ exports.writePrivateAtomicJson = require_atomicJson.writePrivateAtomicJson;
@@ -0,0 +1,2 @@
1
+ import { t as writePrivateAtomicJson } from "./index-C6GaYjq-.mjs";
2
+ export { writePrivateAtomicJson };
@@ -0,0 +1,2 @@
1
+ import { t as writePrivateAtomicJson } from "./atomicJson-1W0WhuFF.mjs";
2
+ export { writePrivateAtomicJson };
@@ -0,0 +1,219 @@
1
+ const require_rolldown_runtime = require("./rolldown-runtime-VH7oDXx4.cjs");
2
+ const require_configPolicy = require("./configPolicy-DmsZEp0t.cjs");
3
+ let node_crypto = require("node:crypto");
4
+ let node_fs = require("node:fs");
5
+ node_fs = require_rolldown_runtime.__toESM(node_fs, 1);
6
+ let node_path = require("node:path");
7
+ node_path = require_rolldown_runtime.__toESM(node_path, 1);
8
+ let node_os = require("node:os");
9
+ node_os = require_rolldown_runtime.__toESM(node_os, 1);
10
+ let _agimon_ai_po_core_piSettings = require("@agimon-ai/po-core/piSettings");
11
+ let yaml = require("yaml");
12
+ //#region src/services/config/index.ts
13
+ const DOOM_DIR = ".po";
14
+ const CONFIG_FILE = "config.yaml";
15
+ const PLANS_DIR = "plans";
16
+ function readConfig(filePath) {
17
+ return node_fs.default.existsSync(filePath) ? require_configPolicy.parseDoomConfig(node_fs.default.readFileSync(filePath, "utf8"), filePath) : { projectTrust: "ask" };
18
+ }
19
+ async function readConfigAsync(filePath) {
20
+ try {
21
+ return require_configPolicy.parseDoomConfig(await node_fs.default.promises.readFile(filePath, "utf8"), filePath);
22
+ } catch (error) {
23
+ if (error.code === "ENOENT") return { projectTrust: "ask" };
24
+ throw error;
25
+ }
26
+ }
27
+ function globalDoomConfigDirectory(homeDirectory = node_os.default.homedir()) {
28
+ return (0, _agimon_ai_po_core_piSettings.poHomeDirectory)(homeDirectory);
29
+ }
30
+ function globalDoomConfigPath(homeDirectory = node_os.default.homedir()) {
31
+ return node_path.default.join(globalDoomConfigDirectory(homeDirectory), CONFIG_FILE);
32
+ }
33
+ function resolvePlanningPlansDirectory(configured, repoRoot, homeDirectory = node_os.default.homedir()) {
34
+ if (!configured) return node_path.default.join(globalDoomConfigDirectory(homeDirectory), PLANS_DIR);
35
+ if (configured === "~") return homeDirectory;
36
+ if (configured.startsWith("~/")) return node_path.default.resolve(homeDirectory, configured.slice(2));
37
+ if (configured.startsWith("~")) throw new Error("Doom planning plansDirectory supports only '~' or '~/' home aliases");
38
+ return node_path.default.isAbsolute(configured) ? node_path.default.normalize(configured) : node_path.default.resolve(repoRoot, configured);
39
+ }
40
+ function repositoryDoomConfigPath(repoRoot) {
41
+ return node_path.default.join(repoRoot, DOOM_DIR, CONFIG_FILE);
42
+ }
43
+ /**
44
+ * True when a repository's `.po` folder is Po's home itself, as it is for a
45
+ * session rooted at home. That folder is already the global layer; reading it
46
+ * again as the repository layer would apply global-only keys at repository scope.
47
+ */
48
+ function isGlobalDoomConfigRoot(repoRoot, homeDirectory = node_os.default.homedir()) {
49
+ return node_path.default.resolve(repoRoot, DOOM_DIR) === node_path.default.resolve(globalDoomConfigDirectory(homeDirectory));
50
+ }
51
+ function repositoryConfigFor(repoRoot, homeDirectory) {
52
+ return isGlobalDoomConfigRoot(repoRoot, homeDirectory) ? void 0 : repositoryDoomConfigPath(repoRoot);
53
+ }
54
+ /** Process-local distribution defaults never grant native authority or modify user files. */
55
+ function distributionDefaults(config, environment) {
56
+ if (environment.PO_DISTRIBUTION !== "desktop") return config;
57
+ return {
58
+ ...config,
59
+ computerUse: {
60
+ ...config.computerUse,
61
+ enabled: config.computerUse?.enabled ?? true
62
+ }
63
+ };
64
+ }
65
+ function loadDoomConfig(repoRoot, homeDirectory = node_os.default.homedir(), environment = process.env) {
66
+ const repositoryPath = repositoryConfigFor(repoRoot, homeDirectory);
67
+ return distributionDefaults(require_configPolicy.mergeDoomConfigs(readConfig(globalDoomConfigPath(homeDirectory)), repositoryPath === void 0 ? { projectTrust: "ask" } : readConfig(repositoryPath)), environment);
68
+ }
69
+ /**
70
+ * Loads the merged config, tolerating unknown keys in either file.
71
+ *
72
+ * Only `po sync` uses this. Everything that runs during a session keeps
73
+ * `loadDoomConfig`, because a key a running extension cannot understand is
74
+ * better reported than silently ignored; a build that refuses to start over
75
+ * the same key is not.
76
+ */
77
+ function loadDoomConfigLenient(repoRoot, homeDirectory = node_os.default.homedir(), environment = process.env) {
78
+ const read = (filePath) => filePath !== void 0 && node_fs.default.existsSync(filePath) ? require_configPolicy.parseDoomConfig(node_fs.default.readFileSync(filePath, "utf8"), filePath, { lenient: true }) : {
79
+ config: { projectTrust: "ask" },
80
+ diagnostics: []
81
+ };
82
+ const globalConfig = read(globalDoomConfigPath(homeDirectory));
83
+ const repositoryConfig = read(repositoryConfigFor(repoRoot, homeDirectory));
84
+ const diagnostics = [...globalConfig.diagnostics, ...repositoryConfig.diagnostics];
85
+ return {
86
+ config: distributionDefaults(require_configPolicy.mergeDoomConfigs(globalConfig.config, repositoryConfig.config), environment),
87
+ diagnostics
88
+ };
89
+ }
90
+ async function loadDoomConfigAsync(repoRoot, homeDirectory = node_os.default.homedir(), environment = process.env) {
91
+ const globalConfig = await readConfigAsync(globalDoomConfigPath(homeDirectory));
92
+ const repositoryPath = repositoryConfigFor(repoRoot, homeDirectory);
93
+ const repositoryConfig = repositoryPath === void 0 ? { projectTrust: "ask" } : await readConfigAsync(repositoryPath);
94
+ return distributionDefaults(require_configPolicy.mergeDoomConfigs(globalConfig, repositoryConfig), environment);
95
+ }
96
+ /**
97
+ * Reads one config file as a layer: what it is, what it sets, and the bytes it
98
+ * held. A file that does not exist is a layer that sets nothing, which is a
99
+ * normal state rather than an error.
100
+ */
101
+ function readLayer(filePath) {
102
+ let text;
103
+ try {
104
+ text = node_fs.default.readFileSync(filePath, "utf8");
105
+ } catch (error) {
106
+ if (error.code === "ENOENT") return {
107
+ filePath,
108
+ exists: false,
109
+ hash: "",
110
+ keys: []
111
+ };
112
+ throw error;
113
+ }
114
+ const document = (0, yaml.parse)(text) ?? {};
115
+ return {
116
+ filePath,
117
+ exists: true,
118
+ hash: (0, node_crypto.createHash)("sha256").update(text, "utf8").digest("hex"),
119
+ keys: require_configPolicy.configLeafKeys(document)
120
+ };
121
+ }
122
+ /**
123
+ * The two config files kept apart, with the merge alongside them.
124
+ *
125
+ * `repoRoot` is optional because the global file is complete on its own: a
126
+ * settings surface with no repository in view still has settings to show, and
127
+ * demanding one would leave it with nothing to render rather than with the
128
+ * global half.
129
+ *
130
+ * The origin answer respects the merge's own per-field rules rather than simply
131
+ * preferring the repository: `editor` is read from the global side whatever the
132
+ * repository says, and `projectTrust` from the repository side whatever the
133
+ * global one says. Reporting a file as the source of a value the merge discards
134
+ * is the exact confusion this exists to remove.
135
+ */
136
+ function loadDoomConfigLayers(repoRoot, homeDirectory = node_os.default.homedir(), environment = process.env) {
137
+ const globalLayer = readLayer(globalDoomConfigPath(homeDirectory));
138
+ const repositoryPath = repoRoot === void 0 ? void 0 : repositoryConfigFor(repoRoot, homeDirectory);
139
+ const repositoryLayer = repositoryPath === void 0 ? {
140
+ filePath: "",
141
+ exists: false,
142
+ hash: "",
143
+ keys: []
144
+ } : readLayer(repositoryPath);
145
+ const effective = repoRoot === void 0 ? distributionDefaults(require_configPolicy.mergeDoomConfigs(readConfig(globalDoomConfigPath(homeDirectory)), { projectTrust: "ask" }), environment) : loadDoomConfig(repoRoot, homeDirectory, environment);
146
+ const sets = (layer, keyPath) => {
147
+ const dotted = keyPath.join(".");
148
+ return layer.keys.some((key) => key === dotted || key.startsWith(`${dotted}.`));
149
+ };
150
+ return {
151
+ globalFile: globalLayer,
152
+ repositoryFile: repositoryLayer,
153
+ effective,
154
+ originOf(keyPath) {
155
+ const scope = require_configPolicy.configScopeOf(keyPath);
156
+ if (scope !== "global" && sets(repositoryLayer, keyPath)) return "repository";
157
+ if (scope !== "repository" && sets(globalLayer, keyPath)) return "global";
158
+ return "default";
159
+ },
160
+ valueAt: (keyPath) => require_configPolicy.valueAtKeyPath(effective, keyPath)
161
+ };
162
+ }
163
+ //#endregion
164
+ Object.defineProperty(exports, "globalDoomConfigDirectory", {
165
+ enumerable: true,
166
+ get: function() {
167
+ return globalDoomConfigDirectory;
168
+ }
169
+ });
170
+ Object.defineProperty(exports, "globalDoomConfigPath", {
171
+ enumerable: true,
172
+ get: function() {
173
+ return globalDoomConfigPath;
174
+ }
175
+ });
176
+ Object.defineProperty(exports, "isGlobalDoomConfigRoot", {
177
+ enumerable: true,
178
+ get: function() {
179
+ return isGlobalDoomConfigRoot;
180
+ }
181
+ });
182
+ Object.defineProperty(exports, "loadDoomConfig", {
183
+ enumerable: true,
184
+ get: function() {
185
+ return loadDoomConfig;
186
+ }
187
+ });
188
+ Object.defineProperty(exports, "loadDoomConfigAsync", {
189
+ enumerable: true,
190
+ get: function() {
191
+ return loadDoomConfigAsync;
192
+ }
193
+ });
194
+ Object.defineProperty(exports, "loadDoomConfigLayers", {
195
+ enumerable: true,
196
+ get: function() {
197
+ return loadDoomConfigLayers;
198
+ }
199
+ });
200
+ Object.defineProperty(exports, "loadDoomConfigLenient", {
201
+ enumerable: true,
202
+ get: function() {
203
+ return loadDoomConfigLenient;
204
+ }
205
+ });
206
+ Object.defineProperty(exports, "repositoryDoomConfigPath", {
207
+ enumerable: true,
208
+ get: function() {
209
+ return repositoryDoomConfigPath;
210
+ }
211
+ });
212
+ Object.defineProperty(exports, "resolvePlanningPlansDirectory", {
213
+ enumerable: true,
214
+ get: function() {
215
+ return resolvePlanningPlansDirectory;
216
+ }
217
+ });
218
+
219
+ //# sourceMappingURL=config-BUw5kHsx.cjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"config-BUw5kHsx.cjs","names":["fs","parseDoomConfig","os","poHomeDirectory","path","mergeDoomConfigs","parseYaml","createHash","configLeafKeys","configScopeOf","valueAtKeyPath"],"sources":["../src/services/config/index.ts"],"sourcesContent":["import { createHash } from 'node:crypto';\nimport fs from 'node:fs';\nimport os from 'node:os';\nimport path from 'node:path';\n\nimport { poHomeDirectory } from '@agimon-ai/po-core/piSettings';\nimport { parse as parseYaml } from 'yaml';\n\nimport type {\n ConfigDiagnostic,\n ConfigValueOrigin,\n DoomConfig,\n DoomConfigLayer,\n DoomConfigLayers,\n LenientParseResult,\n} from '../../types/config';\nimport { configLeafKeys, configScopeOf, mergeDoomConfigs, parseDoomConfig, valueAtKeyPath } from '../configPolicy';\n\nconst DOOM_DIR = '.po';\nconst CONFIG_FILE = 'config.yaml';\nconst PLANS_DIR = 'plans';\n\nfunction readConfig(filePath: string): DoomConfig {\n return fs.existsSync(filePath)\n ? parseDoomConfig(fs.readFileSync(filePath, 'utf8'), filePath)\n : { projectTrust: 'ask' };\n}\n\nasync function readConfigAsync(filePath: string): Promise<DoomConfig> {\n try {\n return parseDoomConfig(await fs.promises.readFile(filePath, 'utf8'), filePath);\n } catch (error) {\n if ((error as NodeJS.ErrnoException).code === 'ENOENT') return { projectTrust: 'ask' };\n throw error;\n }\n}\n\nexport function globalDoomConfigDirectory(homeDirectory = os.homedir()): string {\n return poHomeDirectory(homeDirectory);\n}\n\nexport function globalDoomConfigPath(homeDirectory = os.homedir()): string {\n return path.join(globalDoomConfigDirectory(homeDirectory), CONFIG_FILE);\n}\n\nexport function resolvePlanningPlansDirectory(\n configured: string | undefined,\n repoRoot: string,\n homeDirectory = os.homedir(),\n): string {\n // Under Po's home, so Po writes nothing into ~/.pi.\n if (!configured) return path.join(globalDoomConfigDirectory(homeDirectory), PLANS_DIR);\n if (configured === '~') return homeDirectory;\n if (configured.startsWith('~/')) return path.resolve(homeDirectory, configured.slice(2));\n if (configured.startsWith('~')) {\n throw new Error(\"Doom planning plansDirectory supports only '~' or '~/' home aliases\");\n }\n return path.isAbsolute(configured) ? path.normalize(configured) : path.resolve(repoRoot, configured);\n}\n\nexport function repositoryDoomConfigPath(repoRoot: string): string {\n return path.join(repoRoot, DOOM_DIR, CONFIG_FILE);\n}\n\n/**\n * True when a repository's `.po` folder is Po's home itself, as it is for a\n * session rooted at home. That folder is already the global layer; reading it\n * again as the repository layer would apply global-only keys at repository scope.\n */\nexport function isGlobalDoomConfigRoot(repoRoot: string, homeDirectory = os.homedir()): boolean {\n return path.resolve(repoRoot, DOOM_DIR) === path.resolve(globalDoomConfigDirectory(homeDirectory));\n}\n\nfunction repositoryConfigFor(repoRoot: string, homeDirectory: string): string | undefined {\n return isGlobalDoomConfigRoot(repoRoot, homeDirectory) ? undefined : repositoryDoomConfigPath(repoRoot);\n}\n\n/** Process-local distribution defaults never grant native authority or modify user files. */\nfunction distributionDefaults(config: DoomConfig, environment: NodeJS.ProcessEnv): DoomConfig {\n if (environment.PO_DISTRIBUTION !== 'desktop') return config;\n return { ...config, computerUse: { ...config.computerUse, enabled: config.computerUse?.enabled ?? true } };\n}\n\nexport function loadDoomConfig(\n repoRoot: string,\n homeDirectory = os.homedir(),\n environment: NodeJS.ProcessEnv = process.env,\n): DoomConfig {\n const repositoryPath = repositoryConfigFor(repoRoot, homeDirectory);\n return distributionDefaults(\n mergeDoomConfigs(\n readConfig(globalDoomConfigPath(homeDirectory)),\n repositoryPath === undefined ? { projectTrust: 'ask' } : readConfig(repositoryPath),\n ),\n environment,\n );\n}\n\n/**\n * Loads the merged config, tolerating unknown keys in either file.\n *\n * Only `po sync` uses this. Everything that runs during a session keeps\n * `loadDoomConfig`, because a key a running extension cannot understand is\n * better reported than silently ignored; a build that refuses to start over\n * the same key is not.\n */\nexport function loadDoomConfigLenient(\n repoRoot: string,\n homeDirectory = os.homedir(),\n environment: NodeJS.ProcessEnv = process.env,\n): LenientParseResult {\n const read = (filePath: string | undefined): LenientParseResult =>\n filePath !== undefined && fs.existsSync(filePath)\n ? parseDoomConfig(fs.readFileSync(filePath, 'utf8'), filePath, { lenient: true })\n : { config: { projectTrust: 'ask' }, diagnostics: [] };\n const globalConfig = read(globalDoomConfigPath(homeDirectory));\n const repositoryConfig = read(repositoryConfigFor(repoRoot, homeDirectory));\n const diagnostics: ConfigDiagnostic[] = [...globalConfig.diagnostics, ...repositoryConfig.diagnostics];\n // mergeDoomConfigs stays strict on purpose: its errors are cross-file scope\n // violations on known keys, which is a different fault from an unknown key.\n return {\n config: distributionDefaults(mergeDoomConfigs(globalConfig.config, repositoryConfig.config), environment),\n diagnostics,\n };\n}\n\nexport async function loadDoomConfigAsync(\n repoRoot: string,\n homeDirectory = os.homedir(),\n environment: NodeJS.ProcessEnv = process.env,\n): Promise<DoomConfig> {\n const globalConfig = await readConfigAsync(globalDoomConfigPath(homeDirectory));\n const repositoryPath = repositoryConfigFor(repoRoot, homeDirectory);\n const repositoryConfig: DoomConfig =\n repositoryPath === undefined ? { projectTrust: 'ask' } : await readConfigAsync(repositoryPath);\n return distributionDefaults(mergeDoomConfigs(globalConfig, repositoryConfig), environment);\n}\n\n/**\n * Reads one config file as a layer: what it is, what it sets, and the bytes it\n * held. A file that does not exist is a layer that sets nothing, which is a\n * normal state rather than an error.\n */\nfunction readLayer(filePath: string): DoomConfigLayer {\n let text: string;\n try {\n text = fs.readFileSync(filePath, 'utf8');\n } catch (error) {\n if ((error as NodeJS.ErrnoException).code === 'ENOENT') {\n return { filePath, exists: false, hash: '', keys: [] };\n }\n throw error;\n }\n // The raw document, not the parsed config: this is the one read that has to\n // distinguish a key the file set from a key the parser defaulted.\n const document = (parseYaml(text) ?? {}) as unknown;\n return {\n filePath,\n exists: true,\n hash: createHash('sha256').update(text, 'utf8').digest('hex'),\n keys: configLeafKeys(document),\n };\n}\n\n/**\n * The two config files kept apart, with the merge alongside them.\n *\n * `repoRoot` is optional because the global file is complete on its own: a\n * settings surface with no repository in view still has settings to show, and\n * demanding one would leave it with nothing to render rather than with the\n * global half.\n *\n * The origin answer respects the merge's own per-field rules rather than simply\n * preferring the repository: `editor` is read from the global side whatever the\n * repository says, and `projectTrust` from the repository side whatever the\n * global one says. Reporting a file as the source of a value the merge discards\n * is the exact confusion this exists to remove.\n */\nexport function loadDoomConfigLayers(\n repoRoot: string | undefined,\n homeDirectory = os.homedir(),\n environment: NodeJS.ProcessEnv = process.env,\n): DoomConfigLayers {\n const globalLayer = readLayer(globalDoomConfigPath(homeDirectory));\n const repositoryPath = repoRoot === undefined ? undefined : repositoryConfigFor(repoRoot, homeDirectory);\n const repositoryLayer =\n repositoryPath === undefined ? { filePath: '', exists: false, hash: '', keys: [] } : readLayer(repositoryPath);\n // With no repository there is nothing to merge, so the global file stands as\n // the effective config on its own.\n const effective =\n repoRoot === undefined\n ? distributionDefaults(\n mergeDoomConfigs(readConfig(globalDoomConfigPath(homeDirectory)), { projectTrust: 'ask' }),\n environment,\n )\n : loadDoomConfig(repoRoot, homeDirectory, environment);\n const sets = (layer: DoomConfigLayer, keyPath: readonly string[]): boolean => {\n const dotted = keyPath.join('.');\n return layer.keys.some((key) => key === dotted || key.startsWith(`${dotted}.`));\n };\n return {\n globalFile: globalLayer,\n repositoryFile: repositoryLayer,\n effective,\n originOf(keyPath: readonly string[]): ConfigValueOrigin {\n const scope = configScopeOf(keyPath);\n if (scope !== 'global' && sets(repositoryLayer, keyPath)) return 'repository';\n if (scope !== 'repository' && sets(globalLayer, keyPath)) return 'global';\n return 'default';\n },\n valueAt: (keyPath: readonly string[]) => valueAtKeyPath(effective, keyPath),\n };\n}\n"],"mappings":"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"}