@agimon-ai/po-config 0.0.0-alpha.2 → 0.0.0-alpha.21
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/LICENSE +149 -21
- package/README.md +11 -11
- package/dist/agentPluginMcp.cjs +313 -134
- package/dist/agentPluginMcp.cjs.map +1 -1
- package/dist/agentPluginMcp.d.mts +22 -4
- package/dist/agentPluginMcp.d.mts.map +1 -1
- package/dist/agentPluginMcp.mjs +312 -134
- package/dist/agentPluginMcp.mjs.map +1 -1
- package/dist/apiContracts.cjs.map +1 -1
- package/dist/apiContracts.mjs.map +1 -1
- package/dist/atomicJson-D3MHqnLW.cjs +59 -0
- package/dist/atomicJson-D3MHqnLW.cjs.map +1 -0
- package/dist/atomicJson-Dj3rlZbD.mjs +40 -0
- package/dist/atomicJson-Dj3rlZbD.mjs.map +1 -0
- package/dist/atomicJson.cjs +4 -2
- package/dist/atomicJson.d.mts +2 -2
- package/dist/atomicJson.mjs +3 -2
- package/dist/{index-BT29GZx5.d.mts → completion-Ba0TiBHa.d.mts} +58 -27
- package/dist/completion-Ba0TiBHa.d.mts.map +1 -0
- package/dist/config-BBvn_ZLP.mjs +1 -0
- package/dist/config-Cdybp9rT.cjs +155 -0
- package/dist/config-Cdybp9rT.cjs.map +1 -0
- package/dist/config-Cxc2xw54.mjs +112 -0
- package/dist/config-Cxc2xw54.mjs.map +1 -0
- package/dist/{config-D2HbBLzo.d.mts → config-pxC7FyUJ.d.mts} +33 -33
- package/dist/config-pxC7FyUJ.d.mts.map +1 -0
- package/dist/config.cjs +21 -17
- package/dist/config.d.mts +3 -3
- package/dist/config.mjs +4 -3
- package/dist/{configPolicy-Ce1QKDxa.cjs → configPolicy-CowlLhK1.cjs} +99 -99
- package/dist/configPolicy-CowlLhK1.cjs.map +1 -0
- package/dist/{configPolicy-DCQgF5-f.mjs → configPolicy-DueX0k6i.mjs} +84 -84
- package/dist/configPolicy-DueX0k6i.mjs.map +1 -0
- package/dist/configSchema.d.mts +2 -2
- package/dist/configWriter-DCASRzr-.mjs +180 -0
- package/dist/configWriter-DCASRzr-.mjs.map +1 -0
- package/dist/configWriter-DGO0gmXo.cjs +218 -0
- package/dist/configWriter-DGO0gmXo.cjs.map +1 -0
- package/dist/configWriter.cjs +7 -4
- package/dist/configWriter.d.mts +2 -2
- package/dist/configWriter.mjs +1 -2
- package/dist/core-B0Qg0Qq2.cjs +224 -0
- package/dist/core-B0Qg0Qq2.cjs.map +1 -0
- package/dist/core-DKWW9gkh.mjs +139 -0
- package/dist/core-DKWW9gkh.mjs.map +1 -0
- package/dist/{domains-DGCb7uMC.cjs → domains-CiDUsRiX.cjs} +473 -171
- package/dist/domains-CiDUsRiX.cjs.map +1 -0
- package/dist/{domains-BroCVHrS.mjs → domains-IlieGHaY.mjs} +437 -170
- package/dist/domains-IlieGHaY.mjs.map +1 -0
- package/dist/domains.cjs +9 -3
- package/dist/domains.d.mts +3 -3
- package/dist/domains.mjs +3 -3
- package/dist/extensions/mcp-ui.mjs +1 -1
- package/dist/extensions/mcp-ui.mjs.map +1 -1
- package/dist/extensions/mcp.cjs +3 -3
- package/dist/extensions/mcp.cjs.map +1 -1
- package/dist/extensions/mcp.d.mts +1 -1
- package/dist/extensions/mcp.mjs +2 -2
- package/dist/extensions/mcp.mjs.map +1 -1
- package/dist/extensions/server.cjs +55 -47
- package/dist/extensions/server.cjs.map +1 -1
- package/dist/extensions/server.d.mts +2 -2
- package/dist/extensions/server.d.mts.map +1 -1
- package/dist/extensions/server.mjs +56 -48
- package/dist/extensions/server.mjs.map +1 -1
- package/dist/{harnessState-Dn_S7fB9.mjs → harnessState-8lZda_8r.mjs} +2 -2
- package/dist/{harnessState-Dn_S7fB9.mjs.map → harnessState-8lZda_8r.mjs.map} +1 -1
- package/dist/{harnessState-CCyBeutB.cjs → harnessState-BrmH0lG5.cjs} +2 -2
- package/dist/{harnessState-CCyBeutB.cjs.map → harnessState-BrmH0lG5.cjs.map} +1 -1
- package/dist/harnessState.cjs +1 -1
- package/dist/harnessState.d.mts +1 -1
- package/dist/harnessState.mjs +1 -2
- package/dist/{harnessStore-CJSxdSkV.cjs → harnessStore-BinxGITh.cjs} +189 -81
- package/dist/harnessStore-BinxGITh.cjs.map +1 -0
- package/dist/{harnessStore-CltwLB7M.mjs → harnessStore-w8zHmJ_H.mjs} +160 -82
- package/dist/harnessStore-w8zHmJ_H.mjs.map +1 -0
- package/dist/harnessStore.cjs +6 -1
- package/dist/harnessStore.d.mts +2 -2
- package/dist/harnessStore.mjs +1 -2
- package/dist/index-7RuIAWX1.d.mts +63 -0
- package/dist/index-7RuIAWX1.d.mts.map +1 -0
- package/dist/{index-CkDDvVQt.d.mts → index-BNcG0voG.d.mts} +61 -16
- package/dist/index-BNcG0voG.d.mts.map +1 -0
- package/dist/{index-Dy_-m7gx.d.mts → index-BTOU4XiI.d.mts} +3 -3
- package/dist/{index-Dy_-m7gx.d.mts.map → index-BTOU4XiI.d.mts.map} +1 -1
- package/dist/index-COokUToB.d.mts +83 -0
- package/dist/index-COokUToB.d.mts.map +1 -0
- package/dist/index-D3vGEYup.d.mts +135 -0
- package/dist/index-D3vGEYup.d.mts.map +1 -0
- package/dist/{index-Ch7ptOkW.d.mts → index-DNEK9W6n.d.mts} +26 -16
- package/dist/index-DNEK9W6n.d.mts.map +1 -0
- package/dist/index-D_OtYtsl.d.mts +37 -0
- package/dist/index-D_OtYtsl.d.mts.map +1 -0
- package/dist/{index-DNk4q0Qm.d.mts → index-Nbj2iQWw.d.mts} +19 -25
- package/dist/index-Nbj2iQWw.d.mts.map +1 -0
- package/dist/{index-CEUc7m16.d.mts → index-dYgF03lE.d.mts} +82 -32
- package/dist/index-dYgF03lE.d.mts.map +1 -0
- package/dist/index-fTuf8tVH.d.mts +34 -0
- package/dist/index-fTuf8tVH.d.mts.map +1 -0
- package/dist/index-nVcEC1jO.d.mts +62 -0
- package/dist/index-nVcEC1jO.d.mts.map +1 -0
- package/dist/index.cjs +81 -59
- package/dist/index.d.mts +16 -15
- package/dist/index.mjs +17 -15
- package/dist/{init-Cd3Ki6Ub.cjs → init-BdZ-gqqk.cjs} +209 -59
- package/dist/init-BdZ-gqqk.cjs.map +1 -0
- package/dist/{init-DVzhiCUE.mjs → init-DG7MxGxC.mjs} +187 -48
- package/dist/init-DG7MxGxC.mjs.map +1 -0
- package/dist/init.cjs +8 -6
- package/dist/init.d.mts +2 -2
- package/dist/init.mjs +1 -2
- package/dist/layeredConfig-BbkoIEfM.mjs +95 -0
- package/dist/layeredConfig-BbkoIEfM.mjs.map +1 -0
- package/dist/layeredConfig-Bs18dXQG.cjs +127 -0
- package/dist/layeredConfig-Bs18dXQG.cjs.map +1 -0
- package/dist/layeredConfig.cjs +5 -4
- package/dist/layeredConfig.d.mts +7 -2
- package/dist/layeredConfig.d.mts.map +1 -0
- package/dist/layeredConfig.mjs +1 -2
- package/dist/{majorModes-D1Itd8SN.mjs → majorModes-B8Km83e1.mjs} +130 -23
- package/dist/majorModes-B8Km83e1.mjs.map +1 -0
- package/dist/{majorModes-DnNSH9ZK.cjs → majorModes-CLccNMZt.cjs} +147 -22
- package/dist/majorModes-CLccNMZt.cjs.map +1 -0
- package/dist/majorModes.cjs +4 -1
- package/dist/majorModes.d.mts +2 -2
- package/dist/majorModes.mjs +1 -2
- package/dist/{piConfig-qGyCbcVj.mjs → piConfig-Bq36PQFF.mjs} +104 -69
- package/dist/piConfig-Bq36PQFF.mjs.map +1 -0
- package/dist/{piConfig-Bx26HMb_.d.mts → piConfig-C9rGUqPe.d.mts} +3 -3
- package/dist/{piConfig-Bx26HMb_.d.mts.map → piConfig-C9rGUqPe.d.mts.map} +1 -1
- package/dist/{piConfig-CCBdZXQr.cjs → piConfig-cluCie5i.cjs} +122 -70
- package/dist/piConfig-cluCie5i.cjs.map +1 -0
- package/dist/piConfig.cjs +4 -1
- package/dist/piConfig.d.mts +2 -2
- package/dist/piConfig.mjs +1 -2
- package/dist/piContext.cjs +27 -16
- package/dist/piContext.d.mts +3 -3
- package/dist/piContext.mjs +1 -2
- package/dist/{profiles-DBcYg5nA.mjs → profiles-CHict0x-.mjs} +322 -101
- package/dist/profiles-CHict0x-.mjs.map +1 -0
- package/dist/{profiles-tpplXY4r.cjs → profiles-t2EUj0aB.cjs} +359 -102
- package/dist/profiles-t2EUj0aB.cjs.map +1 -0
- package/dist/profiles.cjs +7 -1
- package/dist/profiles.d.mts +27 -3
- package/dist/profiles.d.mts.map +1 -1
- package/dist/profiles.mjs +1 -2
- package/dist/selectionSwitch.cjs +88 -22
- package/dist/selectionSwitch.cjs.map +1 -1
- package/dist/selectionSwitch.d.mts +40 -18
- package/dist/selectionSwitch.d.mts.map +1 -1
- package/dist/selectionSwitch.mjs +85 -22
- package/dist/selectionSwitch.mjs.map +1 -1
- package/dist/{sessionConfig-DV5xTRRw.mjs → sessionConfig-DFQF618G.mjs} +48 -47
- package/dist/sessionConfig-DFQF618G.mjs.map +1 -0
- package/dist/{sessionConfig-Bf6xHWLd.cjs → sessionConfig-DeP6pplT.cjs} +74 -85
- package/dist/sessionConfig-DeP6pplT.cjs.map +1 -0
- package/dist/sync-BJ8gCP9s.mjs +29 -0
- package/dist/sync-BJ8gCP9s.mjs.map +1 -0
- package/dist/sync-CC_15kkB.d.mts +46 -0
- package/dist/sync-CC_15kkB.d.mts.map +1 -0
- package/dist/sync-Dlxz2msM.cjs +37 -0
- package/dist/sync-Dlxz2msM.cjs.map +1 -0
- package/dist/types.cjs +2 -2
- package/dist/types.d.mts +2 -2
- package/dist/types.mjs +1 -2
- package/llms.txt +1 -1
- package/package.json +16 -16
- package/src/prompts/po-author-config/SKILL.md +4 -4
- package/src/prompts/po-author-config/agents/openai.yaml +1 -1
- package/src/prompts/po-author-config/references/config-contract.md +5 -5
- package/dist/atomicJson-1W0WhuFF.mjs +0 -44
- package/dist/atomicJson-1W0WhuFF.mjs.map +0 -1
- package/dist/atomicJson-Dt2z_DXl.cjs +0 -52
- package/dist/atomicJson-Dt2z_DXl.cjs.map +0 -1
- package/dist/config-CfTb0_9G.cjs +0 -219
- package/dist/config-CfTb0_9G.cjs.map +0 -1
- package/dist/config-D2HbBLzo.d.mts.map +0 -1
- package/dist/config-DoQWSt1V.mjs +0 -162
- package/dist/config-DoQWSt1V.mjs.map +0 -1
- package/dist/config-NSHRd6na.mjs +0 -2
- package/dist/configPolicy-Ce1QKDxa.cjs.map +0 -1
- package/dist/configPolicy-DCQgF5-f.mjs.map +0 -1
- package/dist/configWriter-B7uO8MuN.cjs +0 -150
- package/dist/configWriter-B7uO8MuN.cjs.map +0 -1
- package/dist/configWriter-DUtLgOlD.mjs +0 -130
- package/dist/configWriter-DUtLgOlD.mjs.map +0 -1
- package/dist/domains-BroCVHrS.mjs.map +0 -1
- package/dist/domains-DGCb7uMC.cjs.map +0 -1
- package/dist/harnessStore-CJSxdSkV.cjs.map +0 -1
- package/dist/harnessStore-CltwLB7M.mjs.map +0 -1
- package/dist/index-78zvoS9s.d.mts +0 -35
- package/dist/index-78zvoS9s.d.mts.map +0 -1
- package/dist/index-BT29GZx5.d.mts.map +0 -1
- package/dist/index-C6GaYjq-.d.mts +0 -6
- package/dist/index-C6GaYjq-.d.mts.map +0 -1
- package/dist/index-CEUc7m16.d.mts.map +0 -1
- package/dist/index-CRcoVYXz.d.mts +0 -39
- package/dist/index-CRcoVYXz.d.mts.map +0 -1
- package/dist/index-CVlciCJF.d.mts +0 -40
- package/dist/index-CVlciCJF.d.mts.map +0 -1
- package/dist/index-Ch7ptOkW.d.mts.map +0 -1
- package/dist/index-CkDDvVQt.d.mts.map +0 -1
- package/dist/index-Cvdt-Y-i.d.mts +0 -66
- package/dist/index-Cvdt-Y-i.d.mts.map +0 -1
- package/dist/index-DNk4q0Qm.d.mts.map +0 -1
- package/dist/index-DdH0w56b.d.mts +0 -116
- package/dist/index-DdH0w56b.d.mts.map +0 -1
- package/dist/init-Cd3Ki6Ub.cjs.map +0 -1
- package/dist/init-DVzhiCUE.mjs.map +0 -1
- package/dist/layeredConfig-fukqN2EA.mjs +0 -67
- package/dist/layeredConfig-fukqN2EA.mjs.map +0 -1
- package/dist/layeredConfig-ol0274TN.cjs +0 -94
- package/dist/layeredConfig-ol0274TN.cjs.map +0 -1
- package/dist/majorModes-D1Itd8SN.mjs.map +0 -1
- package/dist/majorModes-DnNSH9ZK.cjs.map +0 -1
- package/dist/piConfig-CCBdZXQr.cjs.map +0 -1
- package/dist/piConfig-qGyCbcVj.mjs.map +0 -1
- package/dist/profiles-DBcYg5nA.mjs.map +0 -1
- package/dist/profiles-tpplXY4r.cjs.map +0 -1
- package/dist/sessionConfig-Bf6xHWLd.cjs.map +0 -1
- package/dist/sessionConfig-DV5xTRRw.mjs.map +0 -1
|
@@ -17,8 +17,8 @@ const ROOT_KEYS = [
|
|
|
17
17
|
"native"
|
|
18
18
|
];
|
|
19
19
|
const BROWSE_KEYS = ["engine", "fallback"];
|
|
20
|
-
const
|
|
21
|
-
const
|
|
20
|
+
const PO_BROWSE_ENGINES = ["cloak", "chrome-for-testing"];
|
|
21
|
+
const PO_BROWSE_FALLBACKS = ["none", "chrome-for-testing"];
|
|
22
22
|
const SELECTION_KEYS = [
|
|
23
23
|
"majorMode",
|
|
24
24
|
"domains",
|
|
@@ -121,13 +121,13 @@ const MAX_COMPOSE_NUDGE_MS = 6e4;
|
|
|
121
121
|
/**
|
|
122
122
|
* Defaults kept as lists so the phrases that shipped first keep working.
|
|
123
123
|
*
|
|
124
|
-
* `hey
|
|
124
|
+
* `hey po` and `that's it` read as speech; `po prompt` and `po send` are what
|
|
125
125
|
* existing users have in their fingers. Dropping the originals would break them for no
|
|
126
126
|
* gain, and the cost of carrying both is two extra comparisons per command candidate.
|
|
127
127
|
*/
|
|
128
|
-
const DEFAULT_COMPOSE_OPEN_PHRASES = ["hey
|
|
129
|
-
const DEFAULT_COMPOSE_SEND_PHRASES = ["that's it", "
|
|
130
|
-
const DEFAULT_COMPOSE_CANCEL_PHRASES = ["
|
|
128
|
+
const DEFAULT_COMPOSE_OPEN_PHRASES = ["hey po", "po prompt"];
|
|
129
|
+
const DEFAULT_COMPOSE_SEND_PHRASES = ["that's it", "po send"];
|
|
130
|
+
const DEFAULT_COMPOSE_CANCEL_PHRASES = ["po cancel", "scratch that"];
|
|
131
131
|
const DEFAULT_TRANSCRIPTION_TIMEOUT_MS = 12e4;
|
|
132
132
|
const MIN_TRANSCRIPTION_TIMEOUT_MS = 1e3;
|
|
133
133
|
const MAX_TRANSCRIPTION_TIMEOUT_MS = 12e4;
|
|
@@ -145,7 +145,7 @@ const PHRASE_PUNCTUATION_PATTERN = /[\p{P}\p{S}]+/gu;
|
|
|
145
145
|
* and a second hand-written list in the contributing package would drift. The
|
|
146
146
|
* validating Sets below are built from these for the same reason.
|
|
147
147
|
*/
|
|
148
|
-
const
|
|
148
|
+
const PO_PLANNING_THINKING_LEVELS = [
|
|
149
149
|
"off",
|
|
150
150
|
"minimal",
|
|
151
151
|
"low",
|
|
@@ -154,16 +154,16 @@ const DOOM_PLANNING_THINKING_LEVELS = [
|
|
|
154
154
|
"xhigh",
|
|
155
155
|
"max"
|
|
156
156
|
];
|
|
157
|
-
const
|
|
158
|
-
const
|
|
157
|
+
const PO_VOICE_MODES = [DEFAULT_VOICE_MODE, "live"];
|
|
158
|
+
const PO_VOICE_ENGINES = [
|
|
159
159
|
DEFAULT_VOICE_ENGINE,
|
|
160
160
|
WHISPER_CPP_ENGINE,
|
|
161
161
|
OPENAI_WHISPER_ENGINE,
|
|
162
162
|
MLX_WHISPER_ENGINE
|
|
163
163
|
];
|
|
164
|
-
const
|
|
164
|
+
const PO_VOICE_TTS_ENGINES = [MACOS_SAY_TTS_ENGINE];
|
|
165
165
|
/** Codex realtime V3 voices, from `codex-rs/protocol/src/protocol.rs` `RealtimeVoicesList::builtin()`. */
|
|
166
|
-
const
|
|
166
|
+
const PO_VOICE_LIVE_VOICES = [
|
|
167
167
|
"juniper",
|
|
168
168
|
"maple",
|
|
169
169
|
"spruce",
|
|
@@ -190,15 +190,15 @@ const DOOM_VOICE_LIVE_VOICES = [
|
|
|
190
190
|
"tinta",
|
|
191
191
|
"viola"
|
|
192
192
|
];
|
|
193
|
-
const THINKING_VALUES = new Set(
|
|
193
|
+
const THINKING_VALUES = new Set(PO_PLANNING_THINKING_LEVELS);
|
|
194
194
|
const TRUST_VALUES = /* @__PURE__ */ new Set([
|
|
195
195
|
"ask",
|
|
196
196
|
"always",
|
|
197
197
|
"never"
|
|
198
198
|
]);
|
|
199
|
-
const VOICE_MODE_VALUES = new Set(
|
|
200
|
-
const ENGINE_VALUES = new Set(
|
|
201
|
-
const TTS_ENGINE_VALUES = new Set(
|
|
199
|
+
const VOICE_MODE_VALUES = new Set(PO_VOICE_MODES);
|
|
200
|
+
const ENGINE_VALUES = new Set(PO_VOICE_ENGINES);
|
|
201
|
+
const TTS_ENGINE_VALUES = new Set(PO_VOICE_TTS_ENGINES);
|
|
202
202
|
function isObject(value) {
|
|
203
203
|
return typeof value === "object" && value !== null && !Array.isArray(value);
|
|
204
204
|
}
|
|
@@ -207,7 +207,7 @@ function isObject(value) {
|
|
|
207
207
|
*
|
|
208
208
|
* Module scope rather than a parameter threaded through the twelve nested
|
|
209
209
|
* parsers: `assertKeys` is the only reader, parsing is synchronous end to end,
|
|
210
|
-
* and `
|
|
210
|
+
* and `parsePoConfig` owns the whole window in a try/finally. Threading would
|
|
211
211
|
* touch every parser to change behaviour in one of them.
|
|
212
212
|
*/
|
|
213
213
|
let unknownKeySink;
|
|
@@ -222,11 +222,11 @@ function assertKeys(value, allowed, location, filePath) {
|
|
|
222
222
|
});
|
|
223
223
|
return;
|
|
224
224
|
}
|
|
225
|
-
throw new Error(`
|
|
225
|
+
throw new Error(`Po config at ${filePath} has unsupported ${location} field(s): ${unknown.join(", ")}`);
|
|
226
226
|
}
|
|
227
227
|
function optionalString(value, location, filePath) {
|
|
228
228
|
if (value === void 0) return void 0;
|
|
229
|
-
if (typeof value !== "string" || value.trim().length === 0) throw new Error(`
|
|
229
|
+
if (typeof value !== "string" || value.trim().length === 0) throw new Error(`Po config at ${filePath} requires ${location} to be a non-empty string`);
|
|
230
230
|
return value.trim();
|
|
231
231
|
}
|
|
232
232
|
function hasControlCharacters(value) {
|
|
@@ -239,14 +239,14 @@ function hasControlCharacters(value) {
|
|
|
239
239
|
function boundedOptionalString(value, location, filePath, maximumLength) {
|
|
240
240
|
const text = optionalString(value, location, filePath);
|
|
241
241
|
if (!text) return void 0;
|
|
242
|
-
if (text.length > maximumLength) throw new Error(`
|
|
243
|
-
if (hasControlCharacters(text)) throw new Error(`
|
|
242
|
+
if (text.length > maximumLength) throw new Error(`Po config at ${filePath} requires ${location} to be at most ${maximumLength} characters`);
|
|
243
|
+
if (hasControlCharacters(text)) throw new Error(`Po config at ${filePath} does not allow control characters in ${location}`);
|
|
244
244
|
return text;
|
|
245
245
|
}
|
|
246
246
|
function parseModelReference(value, filePath) {
|
|
247
247
|
const location = "voice.autoCapture.model";
|
|
248
248
|
const model = optionalString(value, location, filePath);
|
|
249
|
-
if (!model || !MODEL_REFERENCE_PATTERN.test(model)) throw new Error(`
|
|
249
|
+
if (!model || !MODEL_REFERENCE_PATTERN.test(model)) throw new Error(`Po config at ${filePath} requires ${location} in provider/model-id form`);
|
|
250
250
|
return model;
|
|
251
251
|
}
|
|
252
252
|
function normalizeControlPhrase(value) {
|
|
@@ -254,24 +254,24 @@ function normalizeControlPhrase(value) {
|
|
|
254
254
|
}
|
|
255
255
|
function parseControlPhrases(value, location, filePath) {
|
|
256
256
|
if (value === void 0) return void 0;
|
|
257
|
-
if (!Array.isArray(value) || value.some((phrase) => typeof phrase !== "string")) throw new Error(`
|
|
258
|
-
if (value.length > MAX_CONTROL_PHRASES) throw new Error(`
|
|
257
|
+
if (!Array.isArray(value) || value.some((phrase) => typeof phrase !== "string")) throw new Error(`Po config at ${filePath} requires ${location} to be an array of strings`);
|
|
258
|
+
if (value.length > MAX_CONTROL_PHRASES) throw new Error(`Po config at ${filePath} requires ${location} to contain at most ${MAX_CONTROL_PHRASES} phrases`);
|
|
259
259
|
const phrases = value.map((phrase) => phrase.trim());
|
|
260
260
|
const normalized = /* @__PURE__ */ new Set();
|
|
261
261
|
for (const phrase of phrases) {
|
|
262
|
-
if (phrase.length === 0) throw new Error(`
|
|
263
|
-
if (phrase.length > MAX_CONTROL_PHRASE_LENGTH) throw new Error(`
|
|
264
|
-
if (hasControlCharacters(phrase)) throw new Error(`
|
|
262
|
+
if (phrase.length === 0) throw new Error(`Po config at ${filePath} requires ${location} to contain non-empty strings`);
|
|
263
|
+
if (phrase.length > MAX_CONTROL_PHRASE_LENGTH) throw new Error(`Po config at ${filePath} requires ${location} phrases to be at most ${MAX_CONTROL_PHRASE_LENGTH} characters`);
|
|
264
|
+
if (hasControlCharacters(phrase)) throw new Error(`Po config at ${filePath} does not allow control characters in ${location}`);
|
|
265
265
|
const key = normalizeControlPhrase(phrase);
|
|
266
|
-
if (!key) throw new Error(`
|
|
267
|
-
if (normalized.has(key)) throw new Error(`
|
|
266
|
+
if (!key) throw new Error(`Po config at ${filePath} requires ${location} to contain words`);
|
|
267
|
+
if (normalized.has(key)) throw new Error(`Po config at ${filePath} does not allow normalized duplicates in ${location}`);
|
|
268
268
|
normalized.add(key);
|
|
269
269
|
}
|
|
270
270
|
return phrases;
|
|
271
271
|
}
|
|
272
272
|
function parseBoundedInteger(value, location, filePath, minimum, maximum) {
|
|
273
273
|
if (value === void 0) return void 0;
|
|
274
|
-
if (typeof value !== "number" || !Number.isInteger(value) || value < minimum || value > maximum) throw new Error(`
|
|
274
|
+
if (typeof value !== "number" || !Number.isInteger(value) || value < minimum || value > maximum) throw new Error(`Po config at ${filePath} requires ${location} to be an integer from ${minimum} to ${maximum}`);
|
|
275
275
|
return value;
|
|
276
276
|
}
|
|
277
277
|
/**
|
|
@@ -283,16 +283,16 @@ function parseBoundedInteger(value, location, filePath, minimum, maximum) {
|
|
|
283
283
|
*/
|
|
284
284
|
function assertDisjointPhrases(left, right, leftName, rightName, filePath) {
|
|
285
285
|
const keys = new Set((left ?? []).map(normalizeControlPhrase));
|
|
286
|
-
if ((right ?? []).some((phrase) => keys.has(normalizeControlPhrase(phrase)))) throw new Error(`
|
|
286
|
+
if ((right ?? []).some((phrase) => keys.has(normalizeControlPhrase(phrase)))) throw new Error(`Po config at ${filePath} does not allow a phrase in both ${leftName} and ${rightName}`);
|
|
287
287
|
}
|
|
288
288
|
function parseTtsConfig(value, filePath) {
|
|
289
289
|
const location = "voice.autoCapture.tts";
|
|
290
|
-
if (!isObject(value)) throw new Error(`
|
|
290
|
+
if (!isObject(value)) throw new Error(`Po config at ${filePath} requires ${location} to be an object`);
|
|
291
291
|
assertKeys(value, TTS_KEYS, location, filePath);
|
|
292
|
-
if (typeof value.engine !== "string" || !TTS_ENGINE_VALUES.has(value.engine)) throw new Error(`
|
|
292
|
+
if (typeof value.engine !== "string" || !TTS_ENGINE_VALUES.has(value.engine)) throw new Error(`Po config at ${filePath} requires ${location}.engine to be one of: ${[...TTS_ENGINE_VALUES].join(", ")}`);
|
|
293
293
|
const voice = boundedOptionalString(value.voice, `${location}.voice`, filePath, MAX_TTS_VOICE_LENGTH);
|
|
294
294
|
const rate = value.rate;
|
|
295
|
-
if (rate !== void 0 && (typeof rate !== "number" || !Number.isInteger(rate) || rate < MIN_TTS_RATE || rate > MAX_TTS_RATE)) throw new Error(`
|
|
295
|
+
if (rate !== void 0 && (typeof rate !== "number" || !Number.isInteger(rate) || rate < MIN_TTS_RATE || rate > MAX_TTS_RATE)) throw new Error(`Po config at ${filePath} requires ${location}.rate to be an integer from ${MIN_TTS_RATE} to ${MAX_TTS_RATE}`);
|
|
296
296
|
return {
|
|
297
297
|
engine: value.engine,
|
|
298
298
|
...voice ? { voice } : {},
|
|
@@ -302,7 +302,7 @@ function parseTtsConfig(value, filePath) {
|
|
|
302
302
|
function parseAutoCapture(value, filePath) {
|
|
303
303
|
if (value === void 0) return void 0;
|
|
304
304
|
const location = "voice.autoCapture";
|
|
305
|
-
if (!isObject(value)) throw new Error(`
|
|
305
|
+
if (!isObject(value)) throw new Error(`Po config at ${filePath} requires ${location} to be an object`);
|
|
306
306
|
assertKeys(value, AUTO_CAPTURE_KEYS, location, filePath);
|
|
307
307
|
const startPhrases = parseControlPhrases(value.startPhrases, `${location}.startPhrases`, filePath);
|
|
308
308
|
const stopPhrases = parseControlPhrases(value.stopPhrases, `${location}.stopPhrases`, filePath);
|
|
@@ -335,12 +335,12 @@ function parseAutoCapture(value, filePath) {
|
|
|
335
335
|
}
|
|
336
336
|
function parseThinking(value, location, filePath) {
|
|
337
337
|
if (value === void 0) return void 0;
|
|
338
|
-
if (typeof value !== "string" || !THINKING_VALUES.has(value)) throw new Error(`
|
|
338
|
+
if (typeof value !== "string" || !THINKING_VALUES.has(value)) throw new Error(`Po config at ${filePath} requires ${location}.thinking to be one of: ${[...THINKING_VALUES].join(", ")}`);
|
|
339
339
|
return value;
|
|
340
340
|
}
|
|
341
341
|
function parseAgent(value, location, filePath) {
|
|
342
342
|
if (value === void 0) return void 0;
|
|
343
|
-
if (!isObject(value)) throw new Error(`
|
|
343
|
+
if (!isObject(value)) throw new Error(`Po config at ${filePath} requires ${location} to be an object`);
|
|
344
344
|
assertKeys(value, AGENT_KEYS, location, filePath);
|
|
345
345
|
const thinking = parseThinking(value.thinking, location, filePath);
|
|
346
346
|
const model = optionalString(value.model, `${location}.model`, filePath);
|
|
@@ -362,18 +362,18 @@ function parseFlexibleBoolean(value, location, filePath) {
|
|
|
362
362
|
if (typeof value === "boolean") return value;
|
|
363
363
|
if (value === "true") return true;
|
|
364
364
|
if (value === "false") return false;
|
|
365
|
-
throw new Error(`
|
|
365
|
+
throw new Error(`Po config at ${filePath} requires ${location} to be true or false`);
|
|
366
366
|
}
|
|
367
367
|
/** Same story as the flag: a number, or the string form the settings page writes. */
|
|
368
368
|
function parseFlexibleRatio(value, location, filePath) {
|
|
369
369
|
if (value === void 0) return void 0;
|
|
370
370
|
const ratio = typeof value === "string" ? Number(value.trim()) : value;
|
|
371
|
-
if (typeof ratio !== "number" || !Number.isFinite(ratio) || ratio < MIN_AUTOCOMPACT_RATIO || ratio > MAX_AUTOCOMPACT_RATIO) throw new Error(`
|
|
371
|
+
if (typeof ratio !== "number" || !Number.isFinite(ratio) || ratio < MIN_AUTOCOMPACT_RATIO || ratio > MAX_AUTOCOMPACT_RATIO) throw new Error(`Po config at ${filePath} requires ${location} to be a number from ${MIN_AUTOCOMPACT_RATIO} to ${MAX_AUTOCOMPACT_RATIO}`);
|
|
372
372
|
return ratio;
|
|
373
373
|
}
|
|
374
374
|
function parseAutocompactThresholds(value, location, filePath) {
|
|
375
375
|
if (value === void 0) return void 0;
|
|
376
|
-
if (!isObject(value)) throw new Error(`
|
|
376
|
+
if (!isObject(value)) throw new Error(`Po config at ${filePath} requires ${location} to be an object`);
|
|
377
377
|
assertKeys(value, AUTOCOMPACT_THRESHOLD_KEYS, location, filePath);
|
|
378
378
|
const pass1 = parseFlexibleRatio(value.pass1, `${location}.pass1`, filePath);
|
|
379
379
|
const pass2 = parseFlexibleRatio(value.pass2, `${location}.pass2`, filePath);
|
|
@@ -387,20 +387,20 @@ function parseAutocompactThresholds(value, location, filePath) {
|
|
|
387
387
|
/** Absolute token counts, unlike the ratios, are only ever written by hand, so no string form is accepted. */
|
|
388
388
|
function parseAutocompactTokenCount(value, location, filePath) {
|
|
389
389
|
if (value === void 0) return void 0;
|
|
390
|
-
if (typeof value !== "number" || !Number.isSafeInteger(value) || value < MIN_AUTOCOMPACT_TOKENS) throw new Error(`
|
|
390
|
+
if (typeof value !== "number" || !Number.isSafeInteger(value) || value < MIN_AUTOCOMPACT_TOKENS) throw new Error(`Po config at ${filePath} requires ${location} to be an integer of at least ${MIN_AUTOCOMPACT_TOKENS}`);
|
|
391
391
|
return value;
|
|
392
392
|
}
|
|
393
393
|
function parseAutocompactOverrideEntry(value, location, filePath) {
|
|
394
|
-
if (!isObject(value)) throw new Error(`
|
|
394
|
+
if (!isObject(value)) throw new Error(`Po config at ${filePath} requires ${location} to be an object`);
|
|
395
395
|
assertKeys(value, AUTOCOMPACT_OVERRIDE_KEYS, location, filePath);
|
|
396
396
|
const model = optionalString(value.model, `${location}.model`, filePath);
|
|
397
|
-
if (!model) throw new Error(`
|
|
398
|
-
if (!isObject(value.tokens)) throw new Error(`
|
|
397
|
+
if (!model) throw new Error(`Po config at ${filePath} requires ${location}.model`);
|
|
398
|
+
if (!isObject(value.tokens)) throw new Error(`Po config at ${filePath} requires ${location}.tokens to be an object`);
|
|
399
399
|
assertKeys(value.tokens, AUTOCOMPACT_THRESHOLD_KEYS, `${location}.tokens`, filePath);
|
|
400
400
|
const pass1 = parseAutocompactTokenCount(value.tokens.pass1, `${location}.tokens.pass1`, filePath);
|
|
401
401
|
const pass2 = parseAutocompactTokenCount(value.tokens.pass2, `${location}.tokens.pass2`, filePath);
|
|
402
402
|
const pass3 = parseAutocompactTokenCount(value.tokens.pass3, `${location}.tokens.pass3`, filePath);
|
|
403
|
-
if (pass1 === void 0 && pass2 === void 0 && pass3 === void 0) throw new Error(`
|
|
403
|
+
if (pass1 === void 0 && pass2 === void 0 && pass3 === void 0) throw new Error(`Po config at ${filePath} requires one of ${location}.tokens.pass1, pass2, or pass3`);
|
|
404
404
|
return {
|
|
405
405
|
model,
|
|
406
406
|
tokens: {
|
|
@@ -412,11 +412,11 @@ function parseAutocompactOverrideEntry(value, location, filePath) {
|
|
|
412
412
|
}
|
|
413
413
|
function parseAutocompactOverrides(value, location, filePath) {
|
|
414
414
|
if (value === void 0) return void 0;
|
|
415
|
-
if (!Array.isArray(value)) throw new Error(`
|
|
415
|
+
if (!Array.isArray(value)) throw new Error(`Po config at ${filePath} requires ${location} to be a list`);
|
|
416
416
|
return value.map((entry, index) => parseAutocompactOverrideEntry(entry, `${location}[${index}]`, filePath));
|
|
417
417
|
}
|
|
418
418
|
function parseAutocompactModeConfig(value, filePath, location = "modes.autocompact") {
|
|
419
|
-
if (!isObject(value)) throw new Error(`
|
|
419
|
+
if (!isObject(value)) throw new Error(`Po config at ${filePath} requires ${location} to be an object`);
|
|
420
420
|
assertKeys(value, AUTOCOMPACT_KEYS, location, filePath);
|
|
421
421
|
const enabled = parseFlexibleBoolean(value.enabled, `${location}.enabled`, filePath);
|
|
422
422
|
const model = optionalString(value.model, `${location}.model`, filePath);
|
|
@@ -432,7 +432,7 @@ function parseAutocompactModeConfig(value, filePath, location = "modes.autocompa
|
|
|
432
432
|
};
|
|
433
433
|
}
|
|
434
434
|
function parsePlanningModeConfig(value, filePath, location = "modes.planning") {
|
|
435
|
-
if (!isObject(value)) throw new Error(`
|
|
435
|
+
if (!isObject(value)) throw new Error(`Po config at ${filePath} requires ${location} to be an object`);
|
|
436
436
|
assertKeys(value, PLANNING_KEYS, location, filePath);
|
|
437
437
|
return {
|
|
438
438
|
main: parseAgent(value.main, `${location}.main`, filePath),
|
|
@@ -441,12 +441,12 @@ function parsePlanningModeConfig(value, filePath, location = "modes.planning") {
|
|
|
441
441
|
};
|
|
442
442
|
}
|
|
443
443
|
function parseModel(value, location, filePath, allowId) {
|
|
444
|
-
if (!isObject(value)) throw new Error(`
|
|
444
|
+
if (!isObject(value)) throw new Error(`Po config at ${filePath} requires ${location} to be an object`);
|
|
445
445
|
assertKeys(value, MODEL_KEYS, location, filePath);
|
|
446
446
|
const modelPath = optionalString(value.path, `${location}.path`, filePath);
|
|
447
447
|
const id = optionalString(value.id, `${location}.id`, filePath);
|
|
448
|
-
if (Boolean(modelPath) === Boolean(id)) throw new Error(`
|
|
449
|
-
if (id && !allowId) throw new Error(`
|
|
448
|
+
if (Boolean(modelPath) === Boolean(id)) throw new Error(`Po config at ${filePath} requires exactly one of ${location}.path or ${location}.id`);
|
|
449
|
+
if (id && !allowId) throw new Error(`Po config at ${filePath} does not support ${location}.id for whisper-cpp`);
|
|
450
450
|
return {
|
|
451
451
|
...modelPath ? { path: modelPath } : {},
|
|
452
452
|
...id ? { id } : {}
|
|
@@ -454,7 +454,7 @@ function parseModel(value, location, filePath, allowId) {
|
|
|
454
454
|
}
|
|
455
455
|
function parseAdapter(value, location, filePath, allowId) {
|
|
456
456
|
if (value === void 0) return void 0;
|
|
457
|
-
if (!isObject(value)) throw new Error(`
|
|
457
|
+
if (!isObject(value)) throw new Error(`Po config at ${filePath} requires ${location} to be an object`);
|
|
458
458
|
assertKeys(value, ADAPTER_KEYS, location, filePath);
|
|
459
459
|
const binary = optionalString(value.binary, `${location}.binary`, filePath);
|
|
460
460
|
return {
|
|
@@ -464,21 +464,21 @@ function parseAdapter(value, location, filePath, allowId) {
|
|
|
464
464
|
}
|
|
465
465
|
function parseVoice(value, filePath) {
|
|
466
466
|
if (value === void 0) return void 0;
|
|
467
|
-
if (!isObject(value)) throw new Error(`
|
|
467
|
+
if (!isObject(value)) throw new Error(`Po config at ${filePath} requires voice to be an object`);
|
|
468
468
|
assertKeys(value, VOICE_KEYS, "voice", filePath);
|
|
469
469
|
const result = {};
|
|
470
470
|
if (value.mode !== void 0) {
|
|
471
|
-
if (typeof value.mode !== "string" || !VOICE_MODE_VALUES.has(value.mode)) throw new Error(`
|
|
471
|
+
if (typeof value.mode !== "string" || !VOICE_MODE_VALUES.has(value.mode)) throw new Error(`Po config at ${filePath} requires voice.mode to be one of: ${[...VOICE_MODE_VALUES].join(", ")}`);
|
|
472
472
|
result.mode = value.mode;
|
|
473
473
|
}
|
|
474
474
|
if (value.engine !== void 0) {
|
|
475
|
-
if (typeof value.engine !== "string" || !ENGINE_VALUES.has(value.engine)) throw new Error(`
|
|
475
|
+
if (typeof value.engine !== "string" || !ENGINE_VALUES.has(value.engine)) throw new Error(`Po config at ${filePath} requires voice.engine to be one of: ${[...ENGINE_VALUES].join(", ")}`);
|
|
476
476
|
result.engine = value.engine;
|
|
477
477
|
}
|
|
478
478
|
const language = optionalString(value.language, "voice.language", filePath);
|
|
479
479
|
if (language) result.language = language;
|
|
480
480
|
if (value.recorder !== void 0) {
|
|
481
|
-
if (!isObject(value.recorder)) throw new Error(`
|
|
481
|
+
if (!isObject(value.recorder)) throw new Error(`Po config at ${filePath} requires voice.recorder to be an object`);
|
|
482
482
|
assertKeys(value.recorder, RECORDER_KEYS, "voice.recorder", filePath);
|
|
483
483
|
result.recorder = {};
|
|
484
484
|
const binary = optionalString(value.recorder.binary, "voice.recorder.binary", filePath);
|
|
@@ -487,7 +487,7 @@ function parseVoice(value, filePath) {
|
|
|
487
487
|
if (device) result.recorder.device = device;
|
|
488
488
|
}
|
|
489
489
|
if (value.adapters !== void 0) {
|
|
490
|
-
if (!isObject(value.adapters)) throw new Error(`
|
|
490
|
+
if (!isObject(value.adapters)) throw new Error(`Po config at ${filePath} requires voice.adapters to be an object`);
|
|
491
491
|
assertKeys(value.adapters, ADAPTERS_KEYS, "voice.adapters", filePath);
|
|
492
492
|
result.adapters = {
|
|
493
493
|
[WHISPER_CPP_ENGINE]: parseAdapter(value.adapters[WHISPER_CPP_ENGINE], `voice.adapters.${WHISPER_CPP_ENGINE}`, filePath, false),
|
|
@@ -503,25 +503,25 @@ function parseVoice(value, filePath) {
|
|
|
503
503
|
}
|
|
504
504
|
function parseVoiceLive(value, filePath) {
|
|
505
505
|
if (value === void 0) return void 0;
|
|
506
|
-
if (!isObject(value)) throw new Error(`
|
|
506
|
+
if (!isObject(value)) throw new Error(`Po config at ${filePath} requires voice.live to be an object`);
|
|
507
507
|
assertKeys(value, VOICE_LIVE_KEYS, "voice.live", filePath);
|
|
508
508
|
const result = {};
|
|
509
509
|
if (value.voice !== void 0) {
|
|
510
|
-
if (typeof value.voice !== "string" || !
|
|
510
|
+
if (typeof value.voice !== "string" || !PO_VOICE_LIVE_VOICES.includes(value.voice)) throw new Error(`Po config at ${filePath} requires voice.live.voice to be one of: ${PO_VOICE_LIVE_VOICES.join(", ")}`);
|
|
511
511
|
result.voice = value.voice;
|
|
512
512
|
}
|
|
513
513
|
if (value.model !== void 0) {
|
|
514
|
-
if (typeof value.model !== "string" || value.model.length > MAX_LIVE_MODEL_LENGTH || !LIVE_MODEL_PATTERN.test(value.model)) throw new Error(`
|
|
514
|
+
if (typeof value.model !== "string" || value.model.length > MAX_LIVE_MODEL_LENGTH || !LIVE_MODEL_PATTERN.test(value.model)) throw new Error(`Po config at ${filePath} requires voice.live.model to be a model id of at most ${MAX_LIVE_MODEL_LENGTH} letters, digits, dots, colons, underscores or dashes`);
|
|
515
515
|
result.model = value.model;
|
|
516
516
|
}
|
|
517
517
|
return result;
|
|
518
518
|
}
|
|
519
519
|
function parseSelection(value, filePath) {
|
|
520
520
|
if (value === void 0) return void 0;
|
|
521
|
-
if (!isObject(value)) throw new Error(`
|
|
521
|
+
if (!isObject(value)) throw new Error(`Po config at ${filePath} requires selection to be an object`);
|
|
522
522
|
assertKeys(value, SELECTION_KEYS, "selection", filePath);
|
|
523
523
|
const domains = value.domains;
|
|
524
|
-
if (domains !== void 0 && (!Array.isArray(domains) || domains.some((name) => typeof name !== "string"))) throw new Error(`
|
|
524
|
+
if (domains !== void 0 && (!Array.isArray(domains) || domains.some((name) => typeof name !== "string"))) throw new Error(`Po config at ${filePath} requires selection.domains to be an array of strings`);
|
|
525
525
|
return {
|
|
526
526
|
majorMode: optionalString(value.majorMode, "selection.majorMode", filePath),
|
|
527
527
|
domains,
|
|
@@ -530,22 +530,22 @@ function parseSelection(value, filePath) {
|
|
|
530
530
|
}
|
|
531
531
|
function parseEditor(value, filePath) {
|
|
532
532
|
if (value === void 0) return void 0;
|
|
533
|
-
if (!isObject(value)) throw new Error(`
|
|
533
|
+
if (!isObject(value)) throw new Error(`Po config at ${filePath} requires editor to be an object`);
|
|
534
534
|
assertKeys(value, EDITOR_KEYS, "editor", filePath);
|
|
535
535
|
return { command: optionalString(value.command, "editor.command", filePath) };
|
|
536
536
|
}
|
|
537
537
|
function parseBrowse(value, filePath) {
|
|
538
538
|
if (value === void 0) return void 0;
|
|
539
|
-
if (!isObject(value)) throw new Error(`
|
|
539
|
+
if (!isObject(value)) throw new Error(`Po config at ${filePath} requires browse to be an object`);
|
|
540
540
|
assertKeys(value, BROWSE_KEYS, "browse", filePath);
|
|
541
541
|
const pick = (key, allowed) => {
|
|
542
542
|
const raw = value[key];
|
|
543
543
|
if (raw === void 0) return void 0;
|
|
544
|
-
if (typeof raw !== "string" || !allowed.includes(raw)) throw new Error(`
|
|
544
|
+
if (typeof raw !== "string" || !allowed.includes(raw)) throw new Error(`Po config at ${filePath} requires browse.${key} to be one of: ${allowed.join(", ")}`);
|
|
545
545
|
return raw;
|
|
546
546
|
};
|
|
547
|
-
const engine = pick("engine",
|
|
548
|
-
const fallback = pick("fallback",
|
|
547
|
+
const engine = pick("engine", PO_BROWSE_ENGINES);
|
|
548
|
+
const fallback = pick("fallback", PO_BROWSE_FALLBACKS);
|
|
549
549
|
return {
|
|
550
550
|
...engine ? { engine } : {},
|
|
551
551
|
...fallback ? { fallback } : {}
|
|
@@ -554,21 +554,21 @@ function parseBrowse(value, filePath) {
|
|
|
554
554
|
/** `web` and `native` each choose a template, so both read the same `{ template }` shape. */
|
|
555
555
|
function parseTemplateChoice(value, root, filePath) {
|
|
556
556
|
if (value === void 0) return void 0;
|
|
557
|
-
if (!isObject(value)) throw new Error(`
|
|
557
|
+
if (!isObject(value)) throw new Error(`Po config at ${filePath} requires ${root} to be an object`);
|
|
558
558
|
assertKeys(value, ["template"], root, filePath);
|
|
559
559
|
if (value.template === void 0) return {};
|
|
560
560
|
const template = optionalString(value.template, `${root}.template`, filePath);
|
|
561
|
-
if (!template || template.length > 160 || !/^[a-z][a-z0-9]*(?:-[a-z0-9]+)*$/.test(template)) throw new Error(`
|
|
561
|
+
if (!template || template.length > 160 || !/^[a-z][a-z0-9]*(?:-[a-z0-9]+)*$/.test(template)) throw new Error(`Po config at ${filePath} requires ${root}.template to be a kebab-case template identifier`);
|
|
562
562
|
return { template };
|
|
563
563
|
}
|
|
564
564
|
function parseComputerUse(value, filePath) {
|
|
565
565
|
if (value === void 0) return void 0;
|
|
566
|
-
if (!isObject(value)) throw new Error(`
|
|
566
|
+
if (!isObject(value)) throw new Error(`Po config at ${filePath} requires computerUse to be an object`);
|
|
567
567
|
assertKeys(value, COMPUTER_USE_KEYS, "computerUse", filePath);
|
|
568
568
|
const enabled = parseFlexibleBoolean(value.enabled, "computerUse.enabled", filePath);
|
|
569
569
|
return enabled === void 0 ? {} : { enabled };
|
|
570
570
|
}
|
|
571
|
-
function
|
|
571
|
+
function parsePoConfig(content, filePath, options) {
|
|
572
572
|
if (options?.lenient !== true) return parseStrict(content, filePath);
|
|
573
573
|
const diagnostics = [];
|
|
574
574
|
const previous = unknownKeySink;
|
|
@@ -587,13 +587,13 @@ function parseStrict(content, filePath) {
|
|
|
587
587
|
try {
|
|
588
588
|
parsed = (0, yaml.parse)(content) ?? {};
|
|
589
589
|
} catch (error) {
|
|
590
|
-
throw new Error(`Could not parse
|
|
590
|
+
throw new Error(`Could not parse Po config at ${filePath}`, { cause: error });
|
|
591
591
|
}
|
|
592
|
-
if (!isObject(parsed)) throw new Error(`
|
|
592
|
+
if (!isObject(parsed)) throw new Error(`Po config at ${filePath} must be a YAML object`);
|
|
593
593
|
assertKeys(parsed, ROOT_KEYS, "root", filePath);
|
|
594
594
|
let modes;
|
|
595
595
|
if (parsed.modes !== void 0) {
|
|
596
|
-
if (!isObject(parsed.modes)) throw new Error(`
|
|
596
|
+
if (!isObject(parsed.modes)) throw new Error(`Po config at ${filePath} requires modes to be an object`);
|
|
597
597
|
assertKeys(parsed.modes, MODE_KEYS, "modes", filePath);
|
|
598
598
|
modes = {
|
|
599
599
|
...parsed.modes.planning === void 0 ? {} : { planning: parsePlanningModeConfig(parsed.modes.planning, filePath) },
|
|
@@ -601,7 +601,7 @@ function parseStrict(content, filePath) {
|
|
|
601
601
|
};
|
|
602
602
|
}
|
|
603
603
|
const trust = parsed.projectTrust === void 0 ? DEFAULT_PROJECT_TRUST : parsed.projectTrust;
|
|
604
|
-
if (typeof trust !== "string" || !TRUST_VALUES.has(trust)) throw new Error(`
|
|
604
|
+
if (typeof trust !== "string" || !TRUST_VALUES.has(trust)) throw new Error(`Po config at ${filePath} projectTrust must be ask, always, or never`);
|
|
605
605
|
return {
|
|
606
606
|
modes,
|
|
607
607
|
computerUse: parseComputerUse(parsed.computerUse, filePath),
|
|
@@ -620,12 +620,12 @@ function mergeAgent(globalValue, repositoryValue) {
|
|
|
620
620
|
...repositoryValue
|
|
621
621
|
} : void 0;
|
|
622
622
|
}
|
|
623
|
-
function
|
|
624
|
-
if (repositoryConfig.voice?.mode) throw new Error("Repository
|
|
625
|
-
if (repositoryConfig.voice?.autoCapture) throw new Error("Repository
|
|
626
|
-
if (repositoryConfig.voice?.live) throw new Error("Repository
|
|
627
|
-
if (repositoryConfig.computerUse) throw new Error("Repository
|
|
628
|
-
if (repositoryConfig.browse) throw new Error("Repository
|
|
623
|
+
function mergePoConfigs(globalConfig, repositoryConfig) {
|
|
624
|
+
if (repositoryConfig.voice?.mode) throw new Error("Repository Po config voice.mode is global-only; configure it in ~/.po/config.yaml");
|
|
625
|
+
if (repositoryConfig.voice?.autoCapture) throw new Error("Repository Po config voice.autoCapture is global-only; configure it in ~/.po/config.yaml");
|
|
626
|
+
if (repositoryConfig.voice?.live) throw new Error("Repository Po config voice.live is global-only; configure it in ~/.po/config.yaml");
|
|
627
|
+
if (repositoryConfig.computerUse) throw new Error("Repository Po config computerUse is global-only; configure it in ~/.po/config.yaml");
|
|
628
|
+
if (repositoryConfig.browse) throw new Error("Repository Po config browse is global-only; configure it in ~/.po/config.yaml");
|
|
629
629
|
const globalPlanning = globalConfig.modes?.planning;
|
|
630
630
|
const repositoryPlanning = repositoryConfig.modes?.planning;
|
|
631
631
|
const planning = globalPlanning || repositoryPlanning ? {
|
|
@@ -771,8 +771,8 @@ function isPlainRecord(value) {
|
|
|
771
771
|
* Every key path a parsed document actually sets, as dotted strings.
|
|
772
772
|
*
|
|
773
773
|
* A settings surface needs to tell "this file set this key" from "this file is
|
|
774
|
-
* silent about it", and the parsed `
|
|
775
|
-
* reads as `{ projectTrust: 'ask' }` and `
|
|
774
|
+
* silent about it", and the parsed `PoConfig` cannot answer: an absent file
|
|
775
|
+
* reads as `{ projectTrust: 'ask' }` and `parsePoConfig` always returns all
|
|
776
776
|
* known root keys, some undefined. So the question is asked of the raw document
|
|
777
777
|
* instead, before any defaulting has happened.
|
|
778
778
|
*
|
|
@@ -795,34 +795,34 @@ function valueAtKeyPath(value, keyPath) {
|
|
|
795
795
|
return current;
|
|
796
796
|
}
|
|
797
797
|
//#endregion
|
|
798
|
-
Object.defineProperty(exports, "
|
|
798
|
+
Object.defineProperty(exports, "PO_PLANNING_THINKING_LEVELS", {
|
|
799
799
|
enumerable: true,
|
|
800
800
|
get: function() {
|
|
801
|
-
return
|
|
801
|
+
return PO_PLANNING_THINKING_LEVELS;
|
|
802
802
|
}
|
|
803
803
|
});
|
|
804
|
-
Object.defineProperty(exports, "
|
|
804
|
+
Object.defineProperty(exports, "PO_VOICE_ENGINES", {
|
|
805
805
|
enumerable: true,
|
|
806
806
|
get: function() {
|
|
807
|
-
return
|
|
807
|
+
return PO_VOICE_ENGINES;
|
|
808
808
|
}
|
|
809
809
|
});
|
|
810
|
-
Object.defineProperty(exports, "
|
|
810
|
+
Object.defineProperty(exports, "PO_VOICE_LIVE_VOICES", {
|
|
811
811
|
enumerable: true,
|
|
812
812
|
get: function() {
|
|
813
|
-
return
|
|
813
|
+
return PO_VOICE_LIVE_VOICES;
|
|
814
814
|
}
|
|
815
815
|
});
|
|
816
|
-
Object.defineProperty(exports, "
|
|
816
|
+
Object.defineProperty(exports, "PO_VOICE_MODES", {
|
|
817
817
|
enumerable: true,
|
|
818
818
|
get: function() {
|
|
819
|
-
return
|
|
819
|
+
return PO_VOICE_MODES;
|
|
820
820
|
}
|
|
821
821
|
});
|
|
822
|
-
Object.defineProperty(exports, "
|
|
822
|
+
Object.defineProperty(exports, "PO_VOICE_TTS_ENGINES", {
|
|
823
823
|
enumerable: true,
|
|
824
824
|
get: function() {
|
|
825
|
-
return
|
|
825
|
+
return PO_VOICE_TTS_ENGINES;
|
|
826
826
|
}
|
|
827
827
|
});
|
|
828
828
|
Object.defineProperty(exports, "configLeafKeys", {
|
|
@@ -843,10 +843,10 @@ Object.defineProperty(exports, "configScopeOf", {
|
|
|
843
843
|
return configScopeOf;
|
|
844
844
|
}
|
|
845
845
|
});
|
|
846
|
-
Object.defineProperty(exports, "
|
|
846
|
+
Object.defineProperty(exports, "mergePoConfigs", {
|
|
847
847
|
enumerable: true,
|
|
848
848
|
get: function() {
|
|
849
|
-
return
|
|
849
|
+
return mergePoConfigs;
|
|
850
850
|
}
|
|
851
851
|
});
|
|
852
852
|
Object.defineProperty(exports, "parseAutocompactModeConfig", {
|
|
@@ -855,16 +855,16 @@ Object.defineProperty(exports, "parseAutocompactModeConfig", {
|
|
|
855
855
|
return parseAutocompactModeConfig;
|
|
856
856
|
}
|
|
857
857
|
});
|
|
858
|
-
Object.defineProperty(exports, "
|
|
858
|
+
Object.defineProperty(exports, "parsePlanningModeConfig", {
|
|
859
859
|
enumerable: true,
|
|
860
860
|
get: function() {
|
|
861
|
-
return
|
|
861
|
+
return parsePlanningModeConfig;
|
|
862
862
|
}
|
|
863
863
|
});
|
|
864
|
-
Object.defineProperty(exports, "
|
|
864
|
+
Object.defineProperty(exports, "parsePoConfig", {
|
|
865
865
|
enumerable: true,
|
|
866
866
|
get: function() {
|
|
867
|
-
return
|
|
867
|
+
return parsePoConfig;
|
|
868
868
|
}
|
|
869
869
|
});
|
|
870
870
|
Object.defineProperty(exports, "resolveVoiceConfig", {
|
|
@@ -880,4 +880,4 @@ Object.defineProperty(exports, "valueAtKeyPath", {
|
|
|
880
880
|
}
|
|
881
881
|
});
|
|
882
882
|
|
|
883
|
-
//# sourceMappingURL=configPolicy-
|
|
883
|
+
//# sourceMappingURL=configPolicy-CowlLhK1.cjs.map
|