@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.
- package/LICENSE +21 -0
- package/README.md +170 -0
- package/dist/agentPluginMcp.cjs +322 -0
- package/dist/agentPluginMcp.cjs.map +1 -0
- package/dist/agentPluginMcp.d.mts +38 -0
- package/dist/agentPluginMcp.d.mts.map +1 -0
- package/dist/agentPluginMcp.mjs +318 -0
- package/dist/agentPluginMcp.mjs.map +1 -0
- package/dist/apiContracts.cjs +203 -0
- package/dist/apiContracts.cjs.map +1 -0
- package/dist/apiContracts.d.mts +53 -0
- package/dist/apiContracts.d.mts.map +1 -0
- package/dist/apiContracts.mjs +198 -0
- package/dist/apiContracts.mjs.map +1 -0
- package/dist/atomicJson-1W0WhuFF.mjs +44 -0
- package/dist/atomicJson-1W0WhuFF.mjs.map +1 -0
- package/dist/atomicJson-Dt2z_DXl.cjs +52 -0
- package/dist/atomicJson-Dt2z_DXl.cjs.map +1 -0
- package/dist/atomicJson.cjs +3 -0
- package/dist/atomicJson.d.mts +2 -0
- package/dist/atomicJson.mjs +2 -0
- package/dist/config-BUw5kHsx.cjs +219 -0
- package/dist/config-BUw5kHsx.cjs.map +1 -0
- package/dist/config-CKA07FxG.mjs +162 -0
- package/dist/config-CKA07FxG.mjs.map +1 -0
- package/dist/config-Cm3EV1jp.d.mts +320 -0
- package/dist/config-Cm3EV1jp.d.mts.map +1 -0
- package/dist/config-NSHRd6na.mjs +2 -0
- package/dist/config-zZz80Mh5.cjs +1 -0
- package/dist/config.cjs +24 -0
- package/dist/config.d.mts +3 -0
- package/dist/config.mjs +3 -0
- package/dist/configPolicy--TNX7feH.mjs +718 -0
- package/dist/configPolicy--TNX7feH.mjs.map +1 -0
- package/dist/configPolicy-DmsZEp0t.cjs +795 -0
- package/dist/configPolicy-DmsZEp0t.cjs.map +1 -0
- package/dist/configSchema.cjs +0 -0
- package/dist/configSchema.d.mts +2 -0
- package/dist/configSchema.mjs +1 -0
- package/dist/configWriter-BTuinLjs.cjs +150 -0
- package/dist/configWriter-BTuinLjs.cjs.map +1 -0
- package/dist/configWriter-BgkGaLrf.mjs +130 -0
- package/dist/configWriter-BgkGaLrf.mjs.map +1 -0
- package/dist/configWriter.cjs +5 -0
- package/dist/configWriter.d.mts +2 -0
- package/dist/configWriter.mjs +2 -0
- package/dist/domains-CBYkuxs5.cjs +727 -0
- package/dist/domains-CBYkuxs5.cjs.map +1 -0
- package/dist/domains-DZOu9vYM.mjs +633 -0
- package/dist/domains-DZOu9vYM.mjs.map +1 -0
- package/dist/domains.cjs +19 -0
- package/dist/domains.d.mts +3 -0
- package/dist/domains.mjs +3 -0
- package/dist/extensions/mcp-ui.mjs +101 -0
- package/dist/extensions/mcp-ui.mjs.map +1 -0
- package/dist/extensions/mcp.cjs +171 -0
- package/dist/extensions/mcp.cjs.map +1 -0
- package/dist/extensions/mcp.d.mts +5 -0
- package/dist/extensions/mcp.d.mts.map +1 -0
- package/dist/extensions/mcp.mjs +166 -0
- package/dist/extensions/mcp.mjs.map +1 -0
- package/dist/extensions/server.cjs +504 -0
- package/dist/extensions/server.cjs.map +1 -0
- package/dist/extensions/server.d.mts +5 -0
- package/dist/extensions/server.d.mts.map +1 -0
- package/dist/extensions/server.mjs +499 -0
- package/dist/extensions/server.mjs.map +1 -0
- package/dist/harnessState-CCyBeutB.cjs +188 -0
- package/dist/harnessState-CCyBeutB.cjs.map +1 -0
- package/dist/harnessState-Dn_S7fB9.mjs +163 -0
- package/dist/harnessState-Dn_S7fB9.mjs.map +1 -0
- package/dist/harnessState.cjs +6 -0
- package/dist/harnessState.d.mts +2 -0
- package/dist/harnessState.mjs +2 -0
- package/dist/harnessStore-CJSxdSkV.cjs +343 -0
- package/dist/harnessStore-CJSxdSkV.cjs.map +1 -0
- package/dist/harnessStore-CltwLB7M.mjs +262 -0
- package/dist/harnessStore-CltwLB7M.mjs.map +1 -0
- package/dist/harnessStore.cjs +15 -0
- package/dist/harnessStore.d.mts +2 -0
- package/dist/harnessStore.mjs +2 -0
- package/dist/index-BAaTySaM.d.mts +35 -0
- package/dist/index-BAaTySaM.d.mts.map +1 -0
- package/dist/index-BT29GZx5.d.mts +142 -0
- package/dist/index-BT29GZx5.d.mts.map +1 -0
- package/dist/index-B_lp0W3U.d.mts +114 -0
- package/dist/index-B_lp0W3U.d.mts.map +1 -0
- package/dist/index-C6GaYjq-.d.mts +6 -0
- package/dist/index-C6GaYjq-.d.mts.map +1 -0
- package/dist/index-CIQrKS1A.d.mts +50 -0
- package/dist/index-CIQrKS1A.d.mts.map +1 -0
- package/dist/index-CRcoVYXz.d.mts +39 -0
- package/dist/index-CRcoVYXz.d.mts.map +1 -0
- package/dist/index-CVlciCJF.d.mts +40 -0
- package/dist/index-CVlciCJF.d.mts.map +1 -0
- package/dist/index-CeOk2kqs.d.mts +118 -0
- package/dist/index-CeOk2kqs.d.mts.map +1 -0
- package/dist/index-Ch7ptOkW.d.mts +54 -0
- package/dist/index-Ch7ptOkW.d.mts.map +1 -0
- package/dist/index-Cvdt-Y-i.d.mts +66 -0
- package/dist/index-Cvdt-Y-i.d.mts.map +1 -0
- package/dist/index-DJpG-I9K.d.mts +122 -0
- package/dist/index-DJpG-I9K.d.mts.map +1 -0
- package/dist/index-DNk4q0Qm.d.mts +81 -0
- package/dist/index-DNk4q0Qm.d.mts.map +1 -0
- package/dist/index.cjs +121 -0
- package/dist/index.d.mts +15 -0
- package/dist/index.mjs +15 -0
- package/dist/init-C_9nyp3-.cjs +448 -0
- package/dist/init-C_9nyp3-.cjs.map +1 -0
- package/dist/init-DJ6wm-dr.mjs +415 -0
- package/dist/init-DJ6wm-dr.mjs.map +1 -0
- package/dist/init.cjs +7 -0
- package/dist/init.d.mts +2 -0
- package/dist/init.mjs +2 -0
- package/dist/layeredConfig-B922ibgn.mjs +67 -0
- package/dist/layeredConfig-B922ibgn.mjs.map +1 -0
- package/dist/layeredConfig-DdI5ysUf.cjs +94 -0
- package/dist/layeredConfig-DdI5ysUf.cjs.map +1 -0
- package/dist/layeredConfig.cjs +6 -0
- package/dist/layeredConfig.d.mts +2 -0
- package/dist/layeredConfig.mjs +2 -0
- package/dist/majorModes-CmPLEpMT.mjs +333 -0
- package/dist/majorModes-CmPLEpMT.mjs.map +1 -0
- package/dist/majorModes-DPhVMuhT.cjs +383 -0
- package/dist/majorModes-DPhVMuhT.cjs.map +1 -0
- package/dist/majorModes.cjs +10 -0
- package/dist/majorModes.d.mts +2 -0
- package/dist/majorModes.mjs +2 -0
- package/dist/piConfig-Bx26HMb_.d.mts +33 -0
- package/dist/piConfig-Bx26HMb_.d.mts.map +1 -0
- package/dist/piConfig-CCBdZXQr.cjs +260 -0
- package/dist/piConfig-CCBdZXQr.cjs.map +1 -0
- package/dist/piConfig-qGyCbcVj.mjs +197 -0
- package/dist/piConfig-qGyCbcVj.mjs.map +1 -0
- package/dist/piConfig.cjs +12 -0
- package/dist/piConfig.d.mts +2 -0
- package/dist/piConfig.mjs +2 -0
- package/dist/piContext.cjs +18 -0
- package/dist/piContext.d.mts +3 -0
- package/dist/piContext.mjs +2 -0
- package/dist/profiles-CTrUCmIh.d.mts +27 -0
- package/dist/profiles-CTrUCmIh.d.mts.map +1 -0
- package/dist/profiles-DnF9DBpd.cjs +552 -0
- package/dist/profiles-DnF9DBpd.cjs.map +1 -0
- package/dist/profiles-fujQKrS0.mjs +483 -0
- package/dist/profiles-fujQKrS0.mjs.map +1 -0
- package/dist/profiles.cjs +13 -0
- package/dist/profiles.d.mts +25 -0
- package/dist/profiles.d.mts.map +1 -0
- package/dist/profiles.mjs +2 -0
- package/dist/rolldown-runtime-VH7oDXx4.cjs +28 -0
- package/dist/selectionSwitch.cjs +70 -0
- package/dist/selectionSwitch.cjs.map +1 -0
- package/dist/selectionSwitch.d.mts +30 -0
- package/dist/selectionSwitch.d.mts.map +1 -0
- package/dist/selectionSwitch.mjs +64 -0
- package/dist/selectionSwitch.mjs.map +1 -0
- package/dist/sessionConfig-Boh4Fdje.cjs +342 -0
- package/dist/sessionConfig-Boh4Fdje.cjs.map +1 -0
- package/dist/sessionConfig-CtLoc-lO.mjs +240 -0
- package/dist/sessionConfig-CtLoc-lO.mjs.map +1 -0
- package/dist/types.cjs +9 -0
- package/dist/types.d.mts +2 -0
- package/dist/types.mjs +2 -0
- package/llms.txt +12 -0
- package/package.json +206 -0
- package/src/prompts/po-author-config/SKILL.md +26 -0
- package/src/prompts/po-author-config/agents/openai.yaml +4 -0
- 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,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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"}
|