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

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (170) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +170 -0
  3. package/dist/agentPluginMcp.cjs +322 -0
  4. package/dist/agentPluginMcp.cjs.map +1 -0
  5. package/dist/agentPluginMcp.d.mts +38 -0
  6. package/dist/agentPluginMcp.d.mts.map +1 -0
  7. package/dist/agentPluginMcp.mjs +318 -0
  8. package/dist/agentPluginMcp.mjs.map +1 -0
  9. package/dist/apiContracts.cjs +203 -0
  10. package/dist/apiContracts.cjs.map +1 -0
  11. package/dist/apiContracts.d.mts +53 -0
  12. package/dist/apiContracts.d.mts.map +1 -0
  13. package/dist/apiContracts.mjs +198 -0
  14. package/dist/apiContracts.mjs.map +1 -0
  15. package/dist/atomicJson-1W0WhuFF.mjs +44 -0
  16. package/dist/atomicJson-1W0WhuFF.mjs.map +1 -0
  17. package/dist/atomicJson-Dt2z_DXl.cjs +52 -0
  18. package/dist/atomicJson-Dt2z_DXl.cjs.map +1 -0
  19. package/dist/atomicJson.cjs +3 -0
  20. package/dist/atomicJson.d.mts +2 -0
  21. package/dist/atomicJson.mjs +2 -0
  22. package/dist/config-BUw5kHsx.cjs +219 -0
  23. package/dist/config-BUw5kHsx.cjs.map +1 -0
  24. package/dist/config-CKA07FxG.mjs +162 -0
  25. package/dist/config-CKA07FxG.mjs.map +1 -0
  26. package/dist/config-Cm3EV1jp.d.mts +320 -0
  27. package/dist/config-Cm3EV1jp.d.mts.map +1 -0
  28. package/dist/config-NSHRd6na.mjs +2 -0
  29. package/dist/config-zZz80Mh5.cjs +1 -0
  30. package/dist/config.cjs +24 -0
  31. package/dist/config.d.mts +3 -0
  32. package/dist/config.mjs +3 -0
  33. package/dist/configPolicy--TNX7feH.mjs +718 -0
  34. package/dist/configPolicy--TNX7feH.mjs.map +1 -0
  35. package/dist/configPolicy-DmsZEp0t.cjs +795 -0
  36. package/dist/configPolicy-DmsZEp0t.cjs.map +1 -0
  37. package/dist/configSchema.cjs +0 -0
  38. package/dist/configSchema.d.mts +2 -0
  39. package/dist/configSchema.mjs +1 -0
  40. package/dist/configWriter-BTuinLjs.cjs +150 -0
  41. package/dist/configWriter-BTuinLjs.cjs.map +1 -0
  42. package/dist/configWriter-BgkGaLrf.mjs +130 -0
  43. package/dist/configWriter-BgkGaLrf.mjs.map +1 -0
  44. package/dist/configWriter.cjs +5 -0
  45. package/dist/configWriter.d.mts +2 -0
  46. package/dist/configWriter.mjs +2 -0
  47. package/dist/domains-CBYkuxs5.cjs +727 -0
  48. package/dist/domains-CBYkuxs5.cjs.map +1 -0
  49. package/dist/domains-DZOu9vYM.mjs +633 -0
  50. package/dist/domains-DZOu9vYM.mjs.map +1 -0
  51. package/dist/domains.cjs +19 -0
  52. package/dist/domains.d.mts +3 -0
  53. package/dist/domains.mjs +3 -0
  54. package/dist/extensions/mcp-ui.mjs +101 -0
  55. package/dist/extensions/mcp-ui.mjs.map +1 -0
  56. package/dist/extensions/mcp.cjs +171 -0
  57. package/dist/extensions/mcp.cjs.map +1 -0
  58. package/dist/extensions/mcp.d.mts +5 -0
  59. package/dist/extensions/mcp.d.mts.map +1 -0
  60. package/dist/extensions/mcp.mjs +166 -0
  61. package/dist/extensions/mcp.mjs.map +1 -0
  62. package/dist/extensions/server.cjs +504 -0
  63. package/dist/extensions/server.cjs.map +1 -0
  64. package/dist/extensions/server.d.mts +5 -0
  65. package/dist/extensions/server.d.mts.map +1 -0
  66. package/dist/extensions/server.mjs +499 -0
  67. package/dist/extensions/server.mjs.map +1 -0
  68. package/dist/harnessState-CCyBeutB.cjs +188 -0
  69. package/dist/harnessState-CCyBeutB.cjs.map +1 -0
  70. package/dist/harnessState-Dn_S7fB9.mjs +163 -0
  71. package/dist/harnessState-Dn_S7fB9.mjs.map +1 -0
  72. package/dist/harnessState.cjs +6 -0
  73. package/dist/harnessState.d.mts +2 -0
  74. package/dist/harnessState.mjs +2 -0
  75. package/dist/harnessStore-CJSxdSkV.cjs +343 -0
  76. package/dist/harnessStore-CJSxdSkV.cjs.map +1 -0
  77. package/dist/harnessStore-CltwLB7M.mjs +262 -0
  78. package/dist/harnessStore-CltwLB7M.mjs.map +1 -0
  79. package/dist/harnessStore.cjs +15 -0
  80. package/dist/harnessStore.d.mts +2 -0
  81. package/dist/harnessStore.mjs +2 -0
  82. package/dist/index-BAaTySaM.d.mts +35 -0
  83. package/dist/index-BAaTySaM.d.mts.map +1 -0
  84. package/dist/index-BT29GZx5.d.mts +142 -0
  85. package/dist/index-BT29GZx5.d.mts.map +1 -0
  86. package/dist/index-B_lp0W3U.d.mts +114 -0
  87. package/dist/index-B_lp0W3U.d.mts.map +1 -0
  88. package/dist/index-C6GaYjq-.d.mts +6 -0
  89. package/dist/index-C6GaYjq-.d.mts.map +1 -0
  90. package/dist/index-CIQrKS1A.d.mts +50 -0
  91. package/dist/index-CIQrKS1A.d.mts.map +1 -0
  92. package/dist/index-CRcoVYXz.d.mts +39 -0
  93. package/dist/index-CRcoVYXz.d.mts.map +1 -0
  94. package/dist/index-CVlciCJF.d.mts +40 -0
  95. package/dist/index-CVlciCJF.d.mts.map +1 -0
  96. package/dist/index-CeOk2kqs.d.mts +118 -0
  97. package/dist/index-CeOk2kqs.d.mts.map +1 -0
  98. package/dist/index-Ch7ptOkW.d.mts +54 -0
  99. package/dist/index-Ch7ptOkW.d.mts.map +1 -0
  100. package/dist/index-Cvdt-Y-i.d.mts +66 -0
  101. package/dist/index-Cvdt-Y-i.d.mts.map +1 -0
  102. package/dist/index-DJpG-I9K.d.mts +122 -0
  103. package/dist/index-DJpG-I9K.d.mts.map +1 -0
  104. package/dist/index-DNk4q0Qm.d.mts +81 -0
  105. package/dist/index-DNk4q0Qm.d.mts.map +1 -0
  106. package/dist/index.cjs +121 -0
  107. package/dist/index.d.mts +15 -0
  108. package/dist/index.mjs +15 -0
  109. package/dist/init-C_9nyp3-.cjs +448 -0
  110. package/dist/init-C_9nyp3-.cjs.map +1 -0
  111. package/dist/init-DJ6wm-dr.mjs +415 -0
  112. package/dist/init-DJ6wm-dr.mjs.map +1 -0
  113. package/dist/init.cjs +7 -0
  114. package/dist/init.d.mts +2 -0
  115. package/dist/init.mjs +2 -0
  116. package/dist/layeredConfig-B922ibgn.mjs +67 -0
  117. package/dist/layeredConfig-B922ibgn.mjs.map +1 -0
  118. package/dist/layeredConfig-DdI5ysUf.cjs +94 -0
  119. package/dist/layeredConfig-DdI5ysUf.cjs.map +1 -0
  120. package/dist/layeredConfig.cjs +6 -0
  121. package/dist/layeredConfig.d.mts +2 -0
  122. package/dist/layeredConfig.mjs +2 -0
  123. package/dist/majorModes-CmPLEpMT.mjs +333 -0
  124. package/dist/majorModes-CmPLEpMT.mjs.map +1 -0
  125. package/dist/majorModes-DPhVMuhT.cjs +383 -0
  126. package/dist/majorModes-DPhVMuhT.cjs.map +1 -0
  127. package/dist/majorModes.cjs +10 -0
  128. package/dist/majorModes.d.mts +2 -0
  129. package/dist/majorModes.mjs +2 -0
  130. package/dist/piConfig-Bx26HMb_.d.mts +33 -0
  131. package/dist/piConfig-Bx26HMb_.d.mts.map +1 -0
  132. package/dist/piConfig-CCBdZXQr.cjs +260 -0
  133. package/dist/piConfig-CCBdZXQr.cjs.map +1 -0
  134. package/dist/piConfig-qGyCbcVj.mjs +197 -0
  135. package/dist/piConfig-qGyCbcVj.mjs.map +1 -0
  136. package/dist/piConfig.cjs +12 -0
  137. package/dist/piConfig.d.mts +2 -0
  138. package/dist/piConfig.mjs +2 -0
  139. package/dist/piContext.cjs +18 -0
  140. package/dist/piContext.d.mts +3 -0
  141. package/dist/piContext.mjs +2 -0
  142. package/dist/profiles-CTrUCmIh.d.mts +27 -0
  143. package/dist/profiles-CTrUCmIh.d.mts.map +1 -0
  144. package/dist/profiles-DnF9DBpd.cjs +552 -0
  145. package/dist/profiles-DnF9DBpd.cjs.map +1 -0
  146. package/dist/profiles-fujQKrS0.mjs +483 -0
  147. package/dist/profiles-fujQKrS0.mjs.map +1 -0
  148. package/dist/profiles.cjs +13 -0
  149. package/dist/profiles.d.mts +25 -0
  150. package/dist/profiles.d.mts.map +1 -0
  151. package/dist/profiles.mjs +2 -0
  152. package/dist/rolldown-runtime-VH7oDXx4.cjs +28 -0
  153. package/dist/selectionSwitch.cjs +70 -0
  154. package/dist/selectionSwitch.cjs.map +1 -0
  155. package/dist/selectionSwitch.d.mts +30 -0
  156. package/dist/selectionSwitch.d.mts.map +1 -0
  157. package/dist/selectionSwitch.mjs +64 -0
  158. package/dist/selectionSwitch.mjs.map +1 -0
  159. package/dist/sessionConfig-Boh4Fdje.cjs +342 -0
  160. package/dist/sessionConfig-Boh4Fdje.cjs.map +1 -0
  161. package/dist/sessionConfig-CtLoc-lO.mjs +240 -0
  162. package/dist/sessionConfig-CtLoc-lO.mjs.map +1 -0
  163. package/dist/types.cjs +9 -0
  164. package/dist/types.d.mts +2 -0
  165. package/dist/types.mjs +2 -0
  166. package/llms.txt +12 -0
  167. package/package.json +206 -0
  168. package/src/prompts/po-author-config/SKILL.md +26 -0
  169. package/src/prompts/po-author-config/agents/openai.yaml +4 -0
  170. package/src/prompts/po-author-config/references/config-contract.md +201 -0
@@ -0,0 +1,188 @@
1
+ const require_rolldown_runtime = require("./rolldown-runtime-VH7oDXx4.cjs");
2
+ let node_path = require("node:path");
3
+ node_path = require_rolldown_runtime.__toESM(node_path, 1);
4
+ //#region src/services/harnessState/index.ts
5
+ /**
6
+ * The codec between harness state and the environment.
7
+ *
8
+ * Decoding exists for processes that were started without a state file: a
9
+ * nested run, a third-party spawn, or anything older than the store. Encoding
10
+ * exists because bash hooks, the shell launchers, and packages that do not
11
+ * depend on this one can only read an environment. Ownership, persistence and
12
+ * mutation belong to harnessStore.ts; nothing here touches disk or holds state.
13
+ */
14
+ const DEFAULT_MAJOR_MODE = "copilot";
15
+ const DISABLED_FLAG = "0";
16
+ /**
17
+ * State that lives in the file only.
18
+ *
19
+ * These are JSON documents that every spawned process and every hook would
20
+ * otherwise copy in its environment. The plugin hook list and profile defaults
21
+ * are read from the store, while Config publishes the MCP projection through
22
+ * the session-scoped Cordis registry.
23
+ */
24
+ const FILE_ONLY_STATE_FIELDS = /* @__PURE__ */ new Set([
25
+ "profileEnvironment",
26
+ "pluginHooks",
27
+ "mcpProjection",
28
+ "hookModules",
29
+ "packageAttribution",
30
+ "profileIdentity",
31
+ "profileVoice"
32
+ ]);
33
+ const HARNESS_STATE_KEYS = {
34
+ root: "PO_ROOT",
35
+ majorMode: "PO_MAJOR_MODE",
36
+ temporaryDirectory: "PO_TEMP_DIR",
37
+ domains: "PO_DOMAINS",
38
+ layers: "PO_LAYERS",
39
+ compositionFingerprint: "PO_COMPOSITION_FINGERPRINT",
40
+ profile: "PO_PROFILE",
41
+ profileEnvironment: "PO_PROFILE_ENV",
42
+ hookGroups: "PO_HOOK_GROUPS",
43
+ skillDirectories: "PO_SKILL_DIRS",
44
+ agentDirectories: "PO_AGENT_DIRS",
45
+ additionalDirectories: "PO_ADDITIONAL_DIRS",
46
+ childExtensions: "PO_CHILD_EXTENSIONS",
47
+ pluginDirectories: "PO_PLUGIN_DIRS",
48
+ pluginHooks: "PO_PLUGIN_HOOKS",
49
+ mcpConfigPath: "PO_MCP_CONFIG",
50
+ personaFile: "PO_PERSONA_FILE",
51
+ hooks: "PO_HOOKS_ENABLED",
52
+ agents: "PO_AGENTS_ENABLED",
53
+ mcp: "PO_MCP_ENABLED",
54
+ allowProtectedWrites: "PO_ALLOW_PROTECTED_WRITES"
55
+ };
56
+ function splitCsv(value) {
57
+ return value?.split(",").map((item) => item.trim()).filter(Boolean) ?? [];
58
+ }
59
+ function splitPaths(value) {
60
+ return value?.split(node_path.default.delimiter).map((item) => item.trim()).filter(Boolean) ?? [];
61
+ }
62
+ function parseFlag(value) {
63
+ return value !== DISABLED_FLAG;
64
+ }
65
+ function parseStringRecord(value, key, report) {
66
+ if (!value) return {};
67
+ try {
68
+ const parsed = JSON.parse(value);
69
+ if (typeof parsed !== "object" || parsed === null || Array.isArray(parsed)) return {};
70
+ return Object.fromEntries(Object.entries(parsed).filter((entry) => typeof entry[1] === "string"));
71
+ } catch (error) {
72
+ report?.(key, error);
73
+ return {};
74
+ }
75
+ }
76
+ function parseStringList(value, key, report) {
77
+ if (!value) return [];
78
+ try {
79
+ const parsed = JSON.parse(value);
80
+ return Array.isArray(parsed) ? parsed.filter((item) => typeof item === "string") : [];
81
+ } catch (error) {
82
+ report?.(key, error);
83
+ return [];
84
+ }
85
+ }
86
+ function parsePluginHooks(value, key, report) {
87
+ if (!value) return [];
88
+ try {
89
+ const parsed = JSON.parse(value);
90
+ if (!Array.isArray(parsed)) return [];
91
+ return parsed.filter((item) => typeof item === "object" && item !== null && typeof item.pluginRoot === "string" && typeof item.configPath === "string");
92
+ } catch (error) {
93
+ report?.(key, error);
94
+ return [];
95
+ }
96
+ }
97
+ function readHarnessState(environment = process.env, report) {
98
+ const keys = HARNESS_STATE_KEYS;
99
+ const hookGroups = environment[keys.hookGroups];
100
+ return {
101
+ root: environment[keys.root] || void 0,
102
+ majorMode: environment[keys.majorMode] || DEFAULT_MAJOR_MODE,
103
+ temporaryDirectory: environment[keys.temporaryDirectory] || void 0,
104
+ domains: splitCsv(environment[keys.domains]),
105
+ layers: splitCsv(environment[keys.layers]),
106
+ compositionFingerprint: environment[keys.compositionFingerprint] || void 0,
107
+ profile: environment[keys.profile] || void 0,
108
+ profileEnvironment: parseStringRecord(environment[keys.profileEnvironment], keys.profileEnvironment, report),
109
+ hookGroups: hookGroups === void 0 ? void 0 : splitCsv(hookGroups),
110
+ skillDirectories: splitPaths(environment[keys.skillDirectories]),
111
+ agentDirectories: splitPaths(environment[keys.agentDirectories]),
112
+ additionalDirectories: splitPaths(environment[keys.additionalDirectories]),
113
+ childExtensions: parseStringList(environment[keys.childExtensions], keys.childExtensions, report),
114
+ pluginDirectories: splitPaths(environment[keys.pluginDirectories]),
115
+ pluginHooks: parsePluginHooks(environment[keys.pluginHooks], keys.pluginHooks, report),
116
+ mcpConfigPath: environment[keys.mcpConfigPath] || void 0,
117
+ personaFile: environment[keys.personaFile] || void 0,
118
+ hooks: parseFlag(environment[keys.hooks]),
119
+ agents: parseFlag(environment[keys.agents]),
120
+ mcp: parseFlag(environment[keys.mcp]),
121
+ allowProtectedWrites: parseFlag(environment[keys.allowProtectedWrites])
122
+ };
123
+ }
124
+ /**
125
+ * Publishes a state patch into an environment.
126
+ *
127
+ * Takes the environment rather than assuming `process.env`, because the
128
+ * launcher builds a child environment and Doom Team builds a spawn snapshot;
129
+ * neither should mutate its own process to describe another one.
130
+ *
131
+ * Fields in FILE_ONLY_FIELDS are skipped: the file carries them, and a reader
132
+ * that needs them reads the store.
133
+ */
134
+ function projectHarnessEnvironment(patch, environment = process.env) {
135
+ const assign = (key, value) => {
136
+ if (value === void 0) delete environment[key];
137
+ else environment[key] = value;
138
+ };
139
+ const assignFlag = (key, value) => assign(key, value ? "1" : DISABLED_FLAG);
140
+ const keys = HARNESS_STATE_KEYS;
141
+ if ("root" in patch) assign(keys.root, patch.root);
142
+ if ("majorMode" in patch) assign(keys.majorMode, patch.majorMode);
143
+ if ("temporaryDirectory" in patch) assign(keys.temporaryDirectory, patch.temporaryDirectory);
144
+ if ("domains" in patch) assign(keys.domains, patch.domains?.join(","));
145
+ if ("layers" in patch) assign(keys.layers, patch.layers?.join(","));
146
+ if ("compositionFingerprint" in patch) assign(keys.compositionFingerprint, patch.compositionFingerprint);
147
+ if ("profile" in patch) assign(keys.profile, patch.profile);
148
+ if ("hookGroups" in patch) assign(keys.hookGroups, patch.hookGroups?.join(","));
149
+ if ("skillDirectories" in patch) assign(keys.skillDirectories, patch.skillDirectories?.join(node_path.default.delimiter));
150
+ if ("agentDirectories" in patch) assign(keys.agentDirectories, patch.agentDirectories?.join(node_path.default.delimiter));
151
+ if ("additionalDirectories" in patch) assign(keys.additionalDirectories, patch.additionalDirectories?.join(node_path.default.delimiter));
152
+ if ("childExtensions" in patch) assign(keys.childExtensions, JSON.stringify(patch.childExtensions ?? []));
153
+ if ("pluginDirectories" in patch) assign(keys.pluginDirectories, patch.pluginDirectories?.join(node_path.default.delimiter));
154
+ if ("mcpConfigPath" in patch) assign(keys.mcpConfigPath, patch.mcpConfigPath);
155
+ if ("personaFile" in patch) assign(keys.personaFile, patch.personaFile);
156
+ if (patch.hooks !== void 0) assignFlag(keys.hooks, patch.hooks);
157
+ if (patch.agents !== void 0) assignFlag(keys.agents, patch.agents);
158
+ if (patch.mcp !== void 0) assignFlag(keys.mcp, patch.mcp);
159
+ if (patch.allowProtectedWrites !== void 0) assignFlag(keys.allowProtectedWrites, patch.allowProtectedWrites);
160
+ return environment;
161
+ }
162
+ //#endregion
163
+ Object.defineProperty(exports, "FILE_ONLY_STATE_FIELDS", {
164
+ enumerable: true,
165
+ get: function() {
166
+ return FILE_ONLY_STATE_FIELDS;
167
+ }
168
+ });
169
+ Object.defineProperty(exports, "HARNESS_STATE_KEYS", {
170
+ enumerable: true,
171
+ get: function() {
172
+ return HARNESS_STATE_KEYS;
173
+ }
174
+ });
175
+ Object.defineProperty(exports, "projectHarnessEnvironment", {
176
+ enumerable: true,
177
+ get: function() {
178
+ return projectHarnessEnvironment;
179
+ }
180
+ });
181
+ Object.defineProperty(exports, "readHarnessState", {
182
+ enumerable: true,
183
+ get: function() {
184
+ return readHarnessState;
185
+ }
186
+ });
187
+
188
+ //# sourceMappingURL=harnessState-CCyBeutB.cjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"harnessState-CCyBeutB.cjs","names":["path"],"sources":["../src/services/harnessState/index.ts"],"sourcesContent":["import path from 'node:path';\n\nimport type { HarnessState, PluginHookSource } from '../../types/config';\n\n/**\n * The codec between harness state and the environment.\n *\n * Decoding exists for processes that were started without a state file: a\n * nested run, a third-party spawn, or anything older than the store. Encoding\n * exists because bash hooks, the shell launchers, and packages that do not\n * depend on this one can only read an environment. Ownership, persistence and\n * mutation belong to harnessStore.ts; nothing here touches disk or holds state.\n */\n\nconst DEFAULT_MAJOR_MODE = 'copilot';\nconst DISABLED_FLAG = '0';\n\n/**\n * State that lives in the file only.\n *\n * These are JSON documents that every spawned process and every hook would\n * otherwise copy in its environment. The plugin hook list and profile defaults\n * are read from the store, while Config publishes the MCP projection through\n * the session-scoped Cordis registry.\n */\nexport const FILE_ONLY_STATE_FIELDS: ReadonlySet<keyof HarnessState> = new Set([\n 'profileEnvironment',\n 'pluginHooks',\n 'mcpProjection',\n 'hookModules',\n // One entry per composed package. Nothing that spawns a process needs it,\n // and putting a map that size in front of every exec would cost far more\n // than the one surface that reads it is worth.\n 'packageAttribution',\n // The persona's presentation. The icon is a base64 data URL, which has no\n // business in front of every exec, and nothing that spawns a process reads it.\n 'profileIdentity',\n 'profileVoice',\n]);\n\nexport type HarnessStateParseReporter = (key: string, error: unknown) => void;\n\nexport const HARNESS_STATE_KEYS = {\n root: 'PO_ROOT',\n majorMode: 'PO_MAJOR_MODE',\n temporaryDirectory: 'PO_TEMP_DIR',\n domains: 'PO_DOMAINS',\n layers: 'PO_LAYERS',\n compositionFingerprint: 'PO_COMPOSITION_FINGERPRINT',\n profile: 'PO_PROFILE',\n profileEnvironment: 'PO_PROFILE_ENV',\n hookGroups: 'PO_HOOK_GROUPS',\n skillDirectories: 'PO_SKILL_DIRS',\n agentDirectories: 'PO_AGENT_DIRS',\n additionalDirectories: 'PO_ADDITIONAL_DIRS',\n childExtensions: 'PO_CHILD_EXTENSIONS',\n pluginDirectories: 'PO_PLUGIN_DIRS',\n pluginHooks: 'PO_PLUGIN_HOOKS',\n mcpConfigPath: 'PO_MCP_CONFIG',\n personaFile: 'PO_PERSONA_FILE',\n hooks: 'PO_HOOKS_ENABLED',\n agents: 'PO_AGENTS_ENABLED',\n mcp: 'PO_MCP_ENABLED',\n allowProtectedWrites: 'PO_ALLOW_PROTECTED_WRITES',\n} as const;\n\nfunction splitCsv(value: string | undefined): string[] {\n return (\n value\n ?.split(',')\n .map((item) => item.trim())\n .filter(Boolean) ?? []\n );\n}\n\nfunction splitPaths(value: string | undefined): string[] {\n return (\n value\n ?.split(path.delimiter)\n .map((item) => item.trim())\n .filter(Boolean) ?? []\n );\n}\n\nfunction parseFlag(value: string | undefined): boolean {\n return value !== DISABLED_FLAG;\n}\n\nfunction parseStringRecord(\n value: string | undefined,\n key: string,\n report?: HarnessStateParseReporter,\n): Record<string, string> {\n if (!value) return {};\n try {\n const parsed = JSON.parse(value) as unknown;\n if (typeof parsed !== 'object' || parsed === null || Array.isArray(parsed)) return {};\n return Object.fromEntries(\n Object.entries(parsed).filter((entry): entry is [string, string] => typeof entry[1] === 'string'),\n );\n } catch (error) {\n report?.(key, error);\n return {};\n }\n}\n\nfunction parseStringList(value: string | undefined, key: string, report?: HarnessStateParseReporter): string[] {\n if (!value) return [];\n try {\n const parsed = JSON.parse(value) as unknown;\n return Array.isArray(parsed) ? parsed.filter((item): item is string => typeof item === 'string') : [];\n } catch (error) {\n report?.(key, error);\n return [];\n }\n}\n\nfunction parsePluginHooks(\n value: string | undefined,\n key: string,\n report?: HarnessStateParseReporter,\n): PluginHookSource[] {\n if (!value) return [];\n try {\n const parsed = JSON.parse(value) as unknown;\n if (!Array.isArray(parsed)) return [];\n return parsed.filter(\n (item): item is PluginHookSource =>\n typeof item === 'object' &&\n item !== null &&\n typeof (item as PluginHookSource).pluginRoot === 'string' &&\n typeof (item as PluginHookSource).configPath === 'string',\n );\n } catch (error) {\n report?.(key, error);\n return [];\n }\n}\n\nexport function readHarnessState(\n environment: NodeJS.ProcessEnv = process.env,\n report?: HarnessStateParseReporter,\n): HarnessState {\n const keys = HARNESS_STATE_KEYS;\n const hookGroups = environment[keys.hookGroups];\n return {\n root: environment[keys.root] || undefined,\n majorMode: environment[keys.majorMode] || DEFAULT_MAJOR_MODE,\n temporaryDirectory: environment[keys.temporaryDirectory] || undefined,\n domains: splitCsv(environment[keys.domains]),\n layers: splitCsv(environment[keys.layers]),\n compositionFingerprint: environment[keys.compositionFingerprint] || undefined,\n profile: environment[keys.profile] || undefined,\n profileEnvironment: parseStringRecord(environment[keys.profileEnvironment], keys.profileEnvironment, report),\n hookGroups: hookGroups === undefined ? undefined : splitCsv(hookGroups),\n skillDirectories: splitPaths(environment[keys.skillDirectories]),\n agentDirectories: splitPaths(environment[keys.agentDirectories]),\n additionalDirectories: splitPaths(environment[keys.additionalDirectories]),\n childExtensions: parseStringList(environment[keys.childExtensions], keys.childExtensions, report),\n pluginDirectories: splitPaths(environment[keys.pluginDirectories]),\n pluginHooks: parsePluginHooks(environment[keys.pluginHooks], keys.pluginHooks, report),\n mcpConfigPath: environment[keys.mcpConfigPath] || undefined,\n personaFile: environment[keys.personaFile] || undefined,\n hooks: parseFlag(environment[keys.hooks]),\n agents: parseFlag(environment[keys.agents]),\n mcp: parseFlag(environment[keys.mcp]),\n allowProtectedWrites: parseFlag(environment[keys.allowProtectedWrites]),\n };\n}\n\n/**\n * Publishes a state patch into an environment.\n *\n * Takes the environment rather than assuming `process.env`, because the\n * launcher builds a child environment and Doom Team builds a spawn snapshot;\n * neither should mutate its own process to describe another one.\n *\n * Fields in FILE_ONLY_FIELDS are skipped: the file carries them, and a reader\n * that needs them reads the store.\n */\nexport function projectHarnessEnvironment(\n patch: Partial<HarnessState>,\n environment: NodeJS.ProcessEnv = process.env,\n): NodeJS.ProcessEnv {\n const assign = (key: string, value: string | undefined): void => {\n if (value === undefined) delete environment[key];\n else environment[key] = value;\n };\n const assignFlag = (key: string, value: boolean): void => assign(key, value ? '1' : DISABLED_FLAG);\n const keys = HARNESS_STATE_KEYS;\n\n if ('root' in patch) assign(keys.root, patch.root);\n if ('majorMode' in patch) assign(keys.majorMode, patch.majorMode);\n if ('temporaryDirectory' in patch) assign(keys.temporaryDirectory, patch.temporaryDirectory);\n if ('domains' in patch) assign(keys.domains, patch.domains?.join(','));\n if ('layers' in patch) assign(keys.layers, patch.layers?.join(','));\n if ('compositionFingerprint' in patch) assign(keys.compositionFingerprint, patch.compositionFingerprint);\n if ('profile' in patch) assign(keys.profile, patch.profile);\n if ('hookGroups' in patch) assign(keys.hookGroups, patch.hookGroups?.join(','));\n if ('skillDirectories' in patch) assign(keys.skillDirectories, patch.skillDirectories?.join(path.delimiter));\n if ('agentDirectories' in patch) assign(keys.agentDirectories, patch.agentDirectories?.join(path.delimiter));\n if ('additionalDirectories' in patch) {\n assign(keys.additionalDirectories, patch.additionalDirectories?.join(path.delimiter));\n }\n if ('childExtensions' in patch) assign(keys.childExtensions, JSON.stringify(patch.childExtensions ?? []));\n if ('pluginDirectories' in patch) assign(keys.pluginDirectories, patch.pluginDirectories?.join(path.delimiter));\n if ('mcpConfigPath' in patch) assign(keys.mcpConfigPath, patch.mcpConfigPath);\n if ('personaFile' in patch) assign(keys.personaFile, patch.personaFile);\n if (patch.hooks !== undefined) assignFlag(keys.hooks, patch.hooks);\n if (patch.agents !== undefined) assignFlag(keys.agents, patch.agents);\n if (patch.mcp !== undefined) assignFlag(keys.mcp, patch.mcp);\n if (patch.allowProtectedWrites !== undefined) assignFlag(keys.allowProtectedWrites, patch.allowProtectedWrites);\n return environment;\n}\n"],"mappings":"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"}
@@ -0,0 +1,163 @@
1
+ import path from "node:path";
2
+ //#region src/services/harnessState/index.ts
3
+ /**
4
+ * The codec between harness state and the environment.
5
+ *
6
+ * Decoding exists for processes that were started without a state file: a
7
+ * nested run, a third-party spawn, or anything older than the store. Encoding
8
+ * exists because bash hooks, the shell launchers, and packages that do not
9
+ * depend on this one can only read an environment. Ownership, persistence and
10
+ * mutation belong to harnessStore.ts; nothing here touches disk or holds state.
11
+ */
12
+ const DEFAULT_MAJOR_MODE = "copilot";
13
+ const DISABLED_FLAG = "0";
14
+ /**
15
+ * State that lives in the file only.
16
+ *
17
+ * These are JSON documents that every spawned process and every hook would
18
+ * otherwise copy in its environment. The plugin hook list and profile defaults
19
+ * are read from the store, while Config publishes the MCP projection through
20
+ * the session-scoped Cordis registry.
21
+ */
22
+ const FILE_ONLY_STATE_FIELDS = /* @__PURE__ */ new Set([
23
+ "profileEnvironment",
24
+ "pluginHooks",
25
+ "mcpProjection",
26
+ "hookModules",
27
+ "packageAttribution",
28
+ "profileIdentity",
29
+ "profileVoice"
30
+ ]);
31
+ const HARNESS_STATE_KEYS = {
32
+ root: "PO_ROOT",
33
+ majorMode: "PO_MAJOR_MODE",
34
+ temporaryDirectory: "PO_TEMP_DIR",
35
+ domains: "PO_DOMAINS",
36
+ layers: "PO_LAYERS",
37
+ compositionFingerprint: "PO_COMPOSITION_FINGERPRINT",
38
+ profile: "PO_PROFILE",
39
+ profileEnvironment: "PO_PROFILE_ENV",
40
+ hookGroups: "PO_HOOK_GROUPS",
41
+ skillDirectories: "PO_SKILL_DIRS",
42
+ agentDirectories: "PO_AGENT_DIRS",
43
+ additionalDirectories: "PO_ADDITIONAL_DIRS",
44
+ childExtensions: "PO_CHILD_EXTENSIONS",
45
+ pluginDirectories: "PO_PLUGIN_DIRS",
46
+ pluginHooks: "PO_PLUGIN_HOOKS",
47
+ mcpConfigPath: "PO_MCP_CONFIG",
48
+ personaFile: "PO_PERSONA_FILE",
49
+ hooks: "PO_HOOKS_ENABLED",
50
+ agents: "PO_AGENTS_ENABLED",
51
+ mcp: "PO_MCP_ENABLED",
52
+ allowProtectedWrites: "PO_ALLOW_PROTECTED_WRITES"
53
+ };
54
+ function splitCsv(value) {
55
+ return value?.split(",").map((item) => item.trim()).filter(Boolean) ?? [];
56
+ }
57
+ function splitPaths(value) {
58
+ return value?.split(path.delimiter).map((item) => item.trim()).filter(Boolean) ?? [];
59
+ }
60
+ function parseFlag(value) {
61
+ return value !== DISABLED_FLAG;
62
+ }
63
+ function parseStringRecord(value, key, report) {
64
+ if (!value) return {};
65
+ try {
66
+ const parsed = JSON.parse(value);
67
+ if (typeof parsed !== "object" || parsed === null || Array.isArray(parsed)) return {};
68
+ return Object.fromEntries(Object.entries(parsed).filter((entry) => typeof entry[1] === "string"));
69
+ } catch (error) {
70
+ report?.(key, error);
71
+ return {};
72
+ }
73
+ }
74
+ function parseStringList(value, key, report) {
75
+ if (!value) return [];
76
+ try {
77
+ const parsed = JSON.parse(value);
78
+ return Array.isArray(parsed) ? parsed.filter((item) => typeof item === "string") : [];
79
+ } catch (error) {
80
+ report?.(key, error);
81
+ return [];
82
+ }
83
+ }
84
+ function parsePluginHooks(value, key, report) {
85
+ if (!value) return [];
86
+ try {
87
+ const parsed = JSON.parse(value);
88
+ if (!Array.isArray(parsed)) return [];
89
+ return parsed.filter((item) => typeof item === "object" && item !== null && typeof item.pluginRoot === "string" && typeof item.configPath === "string");
90
+ } catch (error) {
91
+ report?.(key, error);
92
+ return [];
93
+ }
94
+ }
95
+ function readHarnessState(environment = process.env, report) {
96
+ const keys = HARNESS_STATE_KEYS;
97
+ const hookGroups = environment[keys.hookGroups];
98
+ return {
99
+ root: environment[keys.root] || void 0,
100
+ majorMode: environment[keys.majorMode] || DEFAULT_MAJOR_MODE,
101
+ temporaryDirectory: environment[keys.temporaryDirectory] || void 0,
102
+ domains: splitCsv(environment[keys.domains]),
103
+ layers: splitCsv(environment[keys.layers]),
104
+ compositionFingerprint: environment[keys.compositionFingerprint] || void 0,
105
+ profile: environment[keys.profile] || void 0,
106
+ profileEnvironment: parseStringRecord(environment[keys.profileEnvironment], keys.profileEnvironment, report),
107
+ hookGroups: hookGroups === void 0 ? void 0 : splitCsv(hookGroups),
108
+ skillDirectories: splitPaths(environment[keys.skillDirectories]),
109
+ agentDirectories: splitPaths(environment[keys.agentDirectories]),
110
+ additionalDirectories: splitPaths(environment[keys.additionalDirectories]),
111
+ childExtensions: parseStringList(environment[keys.childExtensions], keys.childExtensions, report),
112
+ pluginDirectories: splitPaths(environment[keys.pluginDirectories]),
113
+ pluginHooks: parsePluginHooks(environment[keys.pluginHooks], keys.pluginHooks, report),
114
+ mcpConfigPath: environment[keys.mcpConfigPath] || void 0,
115
+ personaFile: environment[keys.personaFile] || void 0,
116
+ hooks: parseFlag(environment[keys.hooks]),
117
+ agents: parseFlag(environment[keys.agents]),
118
+ mcp: parseFlag(environment[keys.mcp]),
119
+ allowProtectedWrites: parseFlag(environment[keys.allowProtectedWrites])
120
+ };
121
+ }
122
+ /**
123
+ * Publishes a state patch into an environment.
124
+ *
125
+ * Takes the environment rather than assuming `process.env`, because the
126
+ * launcher builds a child environment and Doom Team builds a spawn snapshot;
127
+ * neither should mutate its own process to describe another one.
128
+ *
129
+ * Fields in FILE_ONLY_FIELDS are skipped: the file carries them, and a reader
130
+ * that needs them reads the store.
131
+ */
132
+ function projectHarnessEnvironment(patch, environment = process.env) {
133
+ const assign = (key, value) => {
134
+ if (value === void 0) delete environment[key];
135
+ else environment[key] = value;
136
+ };
137
+ const assignFlag = (key, value) => assign(key, value ? "1" : DISABLED_FLAG);
138
+ const keys = HARNESS_STATE_KEYS;
139
+ if ("root" in patch) assign(keys.root, patch.root);
140
+ if ("majorMode" in patch) assign(keys.majorMode, patch.majorMode);
141
+ if ("temporaryDirectory" in patch) assign(keys.temporaryDirectory, patch.temporaryDirectory);
142
+ if ("domains" in patch) assign(keys.domains, patch.domains?.join(","));
143
+ if ("layers" in patch) assign(keys.layers, patch.layers?.join(","));
144
+ if ("compositionFingerprint" in patch) assign(keys.compositionFingerprint, patch.compositionFingerprint);
145
+ if ("profile" in patch) assign(keys.profile, patch.profile);
146
+ if ("hookGroups" in patch) assign(keys.hookGroups, patch.hookGroups?.join(","));
147
+ if ("skillDirectories" in patch) assign(keys.skillDirectories, patch.skillDirectories?.join(path.delimiter));
148
+ if ("agentDirectories" in patch) assign(keys.agentDirectories, patch.agentDirectories?.join(path.delimiter));
149
+ if ("additionalDirectories" in patch) assign(keys.additionalDirectories, patch.additionalDirectories?.join(path.delimiter));
150
+ if ("childExtensions" in patch) assign(keys.childExtensions, JSON.stringify(patch.childExtensions ?? []));
151
+ if ("pluginDirectories" in patch) assign(keys.pluginDirectories, patch.pluginDirectories?.join(path.delimiter));
152
+ if ("mcpConfigPath" in patch) assign(keys.mcpConfigPath, patch.mcpConfigPath);
153
+ if ("personaFile" in patch) assign(keys.personaFile, patch.personaFile);
154
+ if (patch.hooks !== void 0) assignFlag(keys.hooks, patch.hooks);
155
+ if (patch.agents !== void 0) assignFlag(keys.agents, patch.agents);
156
+ if (patch.mcp !== void 0) assignFlag(keys.mcp, patch.mcp);
157
+ if (patch.allowProtectedWrites !== void 0) assignFlag(keys.allowProtectedWrites, patch.allowProtectedWrites);
158
+ return environment;
159
+ }
160
+ //#endregion
161
+ export { readHarnessState as i, HARNESS_STATE_KEYS as n, projectHarnessEnvironment as r, FILE_ONLY_STATE_FIELDS as t };
162
+
163
+ //# sourceMappingURL=harnessState-Dn_S7fB9.mjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"harnessState-Dn_S7fB9.mjs","names":[],"sources":["../src/services/harnessState/index.ts"],"sourcesContent":["import path from 'node:path';\n\nimport type { HarnessState, PluginHookSource } from '../../types/config';\n\n/**\n * The codec between harness state and the environment.\n *\n * Decoding exists for processes that were started without a state file: a\n * nested run, a third-party spawn, or anything older than the store. Encoding\n * exists because bash hooks, the shell launchers, and packages that do not\n * depend on this one can only read an environment. Ownership, persistence and\n * mutation belong to harnessStore.ts; nothing here touches disk or holds state.\n */\n\nconst DEFAULT_MAJOR_MODE = 'copilot';\nconst DISABLED_FLAG = '0';\n\n/**\n * State that lives in the file only.\n *\n * These are JSON documents that every spawned process and every hook would\n * otherwise copy in its environment. The plugin hook list and profile defaults\n * are read from the store, while Config publishes the MCP projection through\n * the session-scoped Cordis registry.\n */\nexport const FILE_ONLY_STATE_FIELDS: ReadonlySet<keyof HarnessState> = new Set([\n 'profileEnvironment',\n 'pluginHooks',\n 'mcpProjection',\n 'hookModules',\n // One entry per composed package. Nothing that spawns a process needs it,\n // and putting a map that size in front of every exec would cost far more\n // than the one surface that reads it is worth.\n 'packageAttribution',\n // The persona's presentation. The icon is a base64 data URL, which has no\n // business in front of every exec, and nothing that spawns a process reads it.\n 'profileIdentity',\n 'profileVoice',\n]);\n\nexport type HarnessStateParseReporter = (key: string, error: unknown) => void;\n\nexport const HARNESS_STATE_KEYS = {\n root: 'PO_ROOT',\n majorMode: 'PO_MAJOR_MODE',\n temporaryDirectory: 'PO_TEMP_DIR',\n domains: 'PO_DOMAINS',\n layers: 'PO_LAYERS',\n compositionFingerprint: 'PO_COMPOSITION_FINGERPRINT',\n profile: 'PO_PROFILE',\n profileEnvironment: 'PO_PROFILE_ENV',\n hookGroups: 'PO_HOOK_GROUPS',\n skillDirectories: 'PO_SKILL_DIRS',\n agentDirectories: 'PO_AGENT_DIRS',\n additionalDirectories: 'PO_ADDITIONAL_DIRS',\n childExtensions: 'PO_CHILD_EXTENSIONS',\n pluginDirectories: 'PO_PLUGIN_DIRS',\n pluginHooks: 'PO_PLUGIN_HOOKS',\n mcpConfigPath: 'PO_MCP_CONFIG',\n personaFile: 'PO_PERSONA_FILE',\n hooks: 'PO_HOOKS_ENABLED',\n agents: 'PO_AGENTS_ENABLED',\n mcp: 'PO_MCP_ENABLED',\n allowProtectedWrites: 'PO_ALLOW_PROTECTED_WRITES',\n} as const;\n\nfunction splitCsv(value: string | undefined): string[] {\n return (\n value\n ?.split(',')\n .map((item) => item.trim())\n .filter(Boolean) ?? []\n );\n}\n\nfunction splitPaths(value: string | undefined): string[] {\n return (\n value\n ?.split(path.delimiter)\n .map((item) => item.trim())\n .filter(Boolean) ?? []\n );\n}\n\nfunction parseFlag(value: string | undefined): boolean {\n return value !== DISABLED_FLAG;\n}\n\nfunction parseStringRecord(\n value: string | undefined,\n key: string,\n report?: HarnessStateParseReporter,\n): Record<string, string> {\n if (!value) return {};\n try {\n const parsed = JSON.parse(value) as unknown;\n if (typeof parsed !== 'object' || parsed === null || Array.isArray(parsed)) return {};\n return Object.fromEntries(\n Object.entries(parsed).filter((entry): entry is [string, string] => typeof entry[1] === 'string'),\n );\n } catch (error) {\n report?.(key, error);\n return {};\n }\n}\n\nfunction parseStringList(value: string | undefined, key: string, report?: HarnessStateParseReporter): string[] {\n if (!value) return [];\n try {\n const parsed = JSON.parse(value) as unknown;\n return Array.isArray(parsed) ? parsed.filter((item): item is string => typeof item === 'string') : [];\n } catch (error) {\n report?.(key, error);\n return [];\n }\n}\n\nfunction parsePluginHooks(\n value: string | undefined,\n key: string,\n report?: HarnessStateParseReporter,\n): PluginHookSource[] {\n if (!value) return [];\n try {\n const parsed = JSON.parse(value) as unknown;\n if (!Array.isArray(parsed)) return [];\n return parsed.filter(\n (item): item is PluginHookSource =>\n typeof item === 'object' &&\n item !== null &&\n typeof (item as PluginHookSource).pluginRoot === 'string' &&\n typeof (item as PluginHookSource).configPath === 'string',\n );\n } catch (error) {\n report?.(key, error);\n return [];\n }\n}\n\nexport function readHarnessState(\n environment: NodeJS.ProcessEnv = process.env,\n report?: HarnessStateParseReporter,\n): HarnessState {\n const keys = HARNESS_STATE_KEYS;\n const hookGroups = environment[keys.hookGroups];\n return {\n root: environment[keys.root] || undefined,\n majorMode: environment[keys.majorMode] || DEFAULT_MAJOR_MODE,\n temporaryDirectory: environment[keys.temporaryDirectory] || undefined,\n domains: splitCsv(environment[keys.domains]),\n layers: splitCsv(environment[keys.layers]),\n compositionFingerprint: environment[keys.compositionFingerprint] || undefined,\n profile: environment[keys.profile] || undefined,\n profileEnvironment: parseStringRecord(environment[keys.profileEnvironment], keys.profileEnvironment, report),\n hookGroups: hookGroups === undefined ? undefined : splitCsv(hookGroups),\n skillDirectories: splitPaths(environment[keys.skillDirectories]),\n agentDirectories: splitPaths(environment[keys.agentDirectories]),\n additionalDirectories: splitPaths(environment[keys.additionalDirectories]),\n childExtensions: parseStringList(environment[keys.childExtensions], keys.childExtensions, report),\n pluginDirectories: splitPaths(environment[keys.pluginDirectories]),\n pluginHooks: parsePluginHooks(environment[keys.pluginHooks], keys.pluginHooks, report),\n mcpConfigPath: environment[keys.mcpConfigPath] || undefined,\n personaFile: environment[keys.personaFile] || undefined,\n hooks: parseFlag(environment[keys.hooks]),\n agents: parseFlag(environment[keys.agents]),\n mcp: parseFlag(environment[keys.mcp]),\n allowProtectedWrites: parseFlag(environment[keys.allowProtectedWrites]),\n };\n}\n\n/**\n * Publishes a state patch into an environment.\n *\n * Takes the environment rather than assuming `process.env`, because the\n * launcher builds a child environment and Doom Team builds a spawn snapshot;\n * neither should mutate its own process to describe another one.\n *\n * Fields in FILE_ONLY_FIELDS are skipped: the file carries them, and a reader\n * that needs them reads the store.\n */\nexport function projectHarnessEnvironment(\n patch: Partial<HarnessState>,\n environment: NodeJS.ProcessEnv = process.env,\n): NodeJS.ProcessEnv {\n const assign = (key: string, value: string | undefined): void => {\n if (value === undefined) delete environment[key];\n else environment[key] = value;\n };\n const assignFlag = (key: string, value: boolean): void => assign(key, value ? '1' : DISABLED_FLAG);\n const keys = HARNESS_STATE_KEYS;\n\n if ('root' in patch) assign(keys.root, patch.root);\n if ('majorMode' in patch) assign(keys.majorMode, patch.majorMode);\n if ('temporaryDirectory' in patch) assign(keys.temporaryDirectory, patch.temporaryDirectory);\n if ('domains' in patch) assign(keys.domains, patch.domains?.join(','));\n if ('layers' in patch) assign(keys.layers, patch.layers?.join(','));\n if ('compositionFingerprint' in patch) assign(keys.compositionFingerprint, patch.compositionFingerprint);\n if ('profile' in patch) assign(keys.profile, patch.profile);\n if ('hookGroups' in patch) assign(keys.hookGroups, patch.hookGroups?.join(','));\n if ('skillDirectories' in patch) assign(keys.skillDirectories, patch.skillDirectories?.join(path.delimiter));\n if ('agentDirectories' in patch) assign(keys.agentDirectories, patch.agentDirectories?.join(path.delimiter));\n if ('additionalDirectories' in patch) {\n assign(keys.additionalDirectories, patch.additionalDirectories?.join(path.delimiter));\n }\n if ('childExtensions' in patch) assign(keys.childExtensions, JSON.stringify(patch.childExtensions ?? []));\n if ('pluginDirectories' in patch) assign(keys.pluginDirectories, patch.pluginDirectories?.join(path.delimiter));\n if ('mcpConfigPath' in patch) assign(keys.mcpConfigPath, patch.mcpConfigPath);\n if ('personaFile' in patch) assign(keys.personaFile, patch.personaFile);\n if (patch.hooks !== undefined) assignFlag(keys.hooks, patch.hooks);\n if (patch.agents !== undefined) assignFlag(keys.agents, patch.agents);\n if (patch.mcp !== undefined) assignFlag(keys.mcp, patch.mcp);\n if (patch.allowProtectedWrites !== undefined) assignFlag(keys.allowProtectedWrites, patch.allowProtectedWrites);\n return environment;\n}\n"],"mappings":"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"}
@@ -0,0 +1,6 @@
1
+ Object.defineProperty(exports, Symbol.toStringTag, { value: "Module" });
2
+ const require_harnessState = require("./harnessState-CCyBeutB.cjs");
3
+ exports.FILE_ONLY_STATE_FIELDS = require_harnessState.FILE_ONLY_STATE_FIELDS;
4
+ exports.HARNESS_STATE_KEYS = require_harnessState.HARNESS_STATE_KEYS;
5
+ exports.projectHarnessEnvironment = require_harnessState.projectHarnessEnvironment;
6
+ exports.readHarnessState = require_harnessState.readHarnessState;
@@ -0,0 +1,2 @@
1
+ import { a as readHarnessState, i as projectHarnessEnvironment, n as HARNESS_STATE_KEYS, r as HarnessStateParseReporter, t as FILE_ONLY_STATE_FIELDS } from "./index-CIQrKS1A.mjs";
2
+ export { FILE_ONLY_STATE_FIELDS, HARNESS_STATE_KEYS, type HarnessStateParseReporter, projectHarnessEnvironment, readHarnessState };
@@ -0,0 +1,2 @@
1
+ import { i as readHarnessState, n as HARNESS_STATE_KEYS, r as projectHarnessEnvironment, t as FILE_ONLY_STATE_FIELDS } from "./harnessState-Dn_S7fB9.mjs";
2
+ export { FILE_ONLY_STATE_FIELDS, HARNESS_STATE_KEYS, projectHarnessEnvironment, readHarnessState };