@agimon-ai/doompi-config 0.0.1-alpha.57 → 0.0.1-alpha.63

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 (105) hide show
  1. package/dist/adapters/agentPluginMcp.d.cts +4 -5
  2. package/dist/adapters/agentPluginMcp.d.cts.map +1 -1
  3. package/dist/adapters/agentPluginMcp.d.mts +4 -5
  4. package/dist/adapters/agentPluginMcp.d.mts.map +1 -1
  5. package/dist/adapters/atomicJson.d.cts +1 -2
  6. package/dist/adapters/atomicJson.d.cts.map +1 -1
  7. package/dist/adapters/atomicJson.d.mts +1 -2
  8. package/dist/adapters/atomicJson.d.mts.map +1 -1
  9. package/dist/adapters/config.d.cts +7 -8
  10. package/dist/adapters/config.d.cts.map +1 -1
  11. package/dist/adapters/config.d.mts +7 -8
  12. package/dist/adapters/config.d.mts.map +1 -1
  13. package/dist/adapters/configWriter.d.cts +6 -7
  14. package/dist/adapters/configWriter.d.cts.map +1 -1
  15. package/dist/adapters/configWriter.d.mts +6 -7
  16. package/dist/adapters/configWriter.d.mts.map +1 -1
  17. package/dist/adapters/domains.d.cts +9 -9
  18. package/dist/adapters/domains.d.cts.map +1 -1
  19. package/dist/adapters/domains.d.mts +9 -9
  20. package/dist/adapters/domains.d.mts.map +1 -1
  21. package/dist/adapters/harnessState.d.cts +5 -6
  22. package/dist/adapters/harnessState.d.cts.map +1 -1
  23. package/dist/adapters/harnessState.d.mts +5 -6
  24. package/dist/adapters/harnessState.d.mts.map +1 -1
  25. package/dist/adapters/harnessStore.cjs +1 -1
  26. package/dist/adapters/harnessStore.cjs.map +1 -1
  27. package/dist/adapters/harnessStore.d.cts +15 -16
  28. package/dist/adapters/harnessStore.d.cts.map +1 -1
  29. package/dist/adapters/harnessStore.d.mts +15 -16
  30. package/dist/adapters/harnessStore.d.mts.map +1 -1
  31. package/dist/adapters/harnessStore.mjs +1 -1
  32. package/dist/adapters/harnessStore.mjs.map +1 -1
  33. package/dist/adapters/init.d.cts +9 -10
  34. package/dist/adapters/init.d.cts.map +1 -1
  35. package/dist/adapters/init.d.mts +9 -10
  36. package/dist/adapters/init.d.mts.map +1 -1
  37. package/dist/adapters/layeredConfig.d.cts +6 -7
  38. package/dist/adapters/layeredConfig.d.cts.map +1 -1
  39. package/dist/adapters/layeredConfig.d.mts +6 -7
  40. package/dist/adapters/layeredConfig.d.mts.map +1 -1
  41. package/dist/adapters/majorModes.cjs +1 -1
  42. package/dist/adapters/majorModes.cjs.map +1 -1
  43. package/dist/adapters/majorModes.d.cts +15 -16
  44. package/dist/adapters/majorModes.d.cts.map +1 -1
  45. package/dist/adapters/majorModes.d.mts +15 -16
  46. package/dist/adapters/majorModes.d.mts.map +1 -1
  47. package/dist/adapters/majorModes.mjs +1 -1
  48. package/dist/adapters/majorModes.mjs.map +1 -1
  49. package/dist/adapters/pi/configExtension.d.cts +2 -2
  50. package/dist/adapters/pi/configExtension.d.cts.map +1 -1
  51. package/dist/adapters/pi/configExtension.d.mts +2 -2
  52. package/dist/adapters/pi/configExtension.d.mts.map +1 -1
  53. package/dist/adapters/pi/piContext.d.cts +17 -18
  54. package/dist/adapters/pi/piContext.d.cts.map +1 -1
  55. package/dist/adapters/pi/piContext.d.mts +17 -18
  56. package/dist/adapters/pi/piContext.d.mts.map +1 -1
  57. package/dist/adapters/piConfig.d.cts +6 -7
  58. package/dist/adapters/piConfig.d.cts.map +1 -1
  59. package/dist/adapters/piConfig.d.mts +6 -7
  60. package/dist/adapters/piConfig.d.mts.map +1 -1
  61. package/dist/adapters/pluginCatalog.d.cts +4 -5
  62. package/dist/adapters/pluginCatalog.d.cts.map +1 -1
  63. package/dist/adapters/pluginCatalog.d.mts +4 -5
  64. package/dist/adapters/pluginCatalog.d.mts.map +1 -1
  65. package/dist/adapters/profiles.d.cts +8 -9
  66. package/dist/adapters/profiles.d.cts.map +1 -1
  67. package/dist/adapters/profiles.d.mts +8 -9
  68. package/dist/adapters/profiles.d.mts.map +1 -1
  69. package/dist/adapters/selectionSwitch.d.cts +3 -4
  70. package/dist/adapters/selectionSwitch.d.cts.map +1 -1
  71. package/dist/adapters/selectionSwitch.d.mts +3 -4
  72. package/dist/adapters/selectionSwitch.d.mts.map +1 -1
  73. package/dist/index.d.cts +2 -2
  74. package/dist/index.d.mts +2 -2
  75. package/dist/schemas/config/schema.d.cts +5 -6
  76. package/dist/schemas/config/schema.d.cts.map +1 -1
  77. package/dist/schemas/config/schema.d.mts +5 -6
  78. package/dist/schemas/config/schema.d.mts.map +1 -1
  79. package/dist/services/configPolicy.cjs +1 -1
  80. package/dist/services/configPolicy.cjs.map +1 -1
  81. package/dist/services/configPolicy.d.cts +13 -14
  82. package/dist/services/configPolicy.d.cts.map +1 -1
  83. package/dist/services/configPolicy.d.mts +13 -14
  84. package/dist/services/configPolicy.d.mts.map +1 -1
  85. package/dist/services/configPolicy.mjs +1 -1
  86. package/dist/services/configPolicy.mjs.map +1 -1
  87. package/dist/services/domains.d.cts +3 -4
  88. package/dist/services/domains.d.cts.map +1 -1
  89. package/dist/services/domains.d.mts +3 -4
  90. package/dist/services/domains.d.mts.map +1 -1
  91. package/dist/services/imageSettings.d.cts +6 -7
  92. package/dist/services/imageSettings.d.cts.map +1 -1
  93. package/dist/services/imageSettings.d.mts +6 -7
  94. package/dist/services/imageSettings.d.mts.map +1 -1
  95. package/dist/types/config.d.cts +62 -34
  96. package/dist/types/config.d.cts.map +1 -1
  97. package/dist/types/config.d.mts +62 -34
  98. package/dist/types/config.d.mts.map +1 -1
  99. package/dist/types/domains.d.cts +14 -15
  100. package/dist/types/domains.d.cts.map +1 -1
  101. package/dist/types/domains.d.mts +14 -15
  102. package/dist/types/domains.d.mts.map +1 -1
  103. package/dist/types.d.cts +2 -2
  104. package/dist/types.d.mts +2 -2
  105. package/package.json +10 -10
@@ -1,12 +1,12 @@
1
1
  import { DoomMcpAgentPluginProjectionSource } from "@agimon-ai/doompi-extension-contracts/mcp-projection";
2
2
  //#region src/adapters/agentPluginMcp.d.ts
3
3
  type JsonObject = Record<string, unknown>;
4
- interface AgentPluginMcpConfigSource {
4
+ export interface AgentPluginMcpConfigSource {
5
5
  path: string;
6
6
  format: 'internal';
7
7
  cacheKey: string;
8
8
  }
9
- interface NormalizedAgentPluginMcpSource {
9
+ export interface NormalizedAgentPluginMcpSource {
10
10
  /** Owner-only, content-addressed layer that bypasses Claude env interpolation. */
11
11
  configSource?: AgentPluginMcpConfigSource;
12
12
  /** Claude-compatible definitions for an external merged config. */
@@ -17,7 +17,7 @@ interface NormalizedAgentPluginMcpSource {
17
17
  droppedServers: string[];
18
18
  diagnostics: string[];
19
19
  }
20
- interface NormalizeAgentPluginMcpOptions {
20
+ export interface NormalizeAgentPluginMcpOptions {
21
21
  stagingDirectory: string;
22
22
  /** Empty and absent lists both mean keep every server. */
23
23
  allowedServers?: readonly string[];
@@ -32,7 +32,6 @@ interface NormalizeAgentPluginMcpOptions {
32
32
  * source. Only the two portable plugin placeholders are expanded; the staged
33
33
  * layer is tagged `internal`, so legacy `${ENV}` interpolation cannot run again.
34
34
  */
35
- declare function normalizeAgentPluginMcpSource(source: DoomMcpAgentPluginProjectionSource, options: NormalizeAgentPluginMcpOptions): NormalizedAgentPluginMcpSource;
35
+ export declare function normalizeAgentPluginMcpSource(source: DoomMcpAgentPluginProjectionSource, options: NormalizeAgentPluginMcpOptions): NormalizedAgentPluginMcpSource;
36
36
  //#endregion
37
- export { AgentPluginMcpConfigSource, NormalizeAgentPluginMcpOptions, NormalizedAgentPluginMcpSource, normalizeAgentPluginMcpSource };
38
37
  //# sourceMappingURL=agentPluginMcp.d.cts.map
@@ -1 +1 @@
1
- {"version":3,"file":"agentPluginMcp.d.cts","names":[],"sources":["../../src/adapters/agentPluginMcp.ts"],"mappings":";;KAeK,aAAa;UAED;EACf;EACA;EACA;;UAGe;;EAEf,eAAe;;EAEf;IAAgB,YAAY,eAAe;;EAC3C;EACA;EACA;;UAGe;EACf;;EAEA;;EAEA;;;;;;;;;;iBAuQc,8BACd,QAAQ,oCACR,SAAS,iCACR"}
1
+ {"version":3,"file":"agentPluginMcp.d.cts","names":[],"sources":["../../src/adapters/agentPluginMcp.ts"],"mappings":";;KAeK,aAAa;iBAED;EACf;EACA;EACA;;iBAGe;;EAEf,eAAe;;EAEf;IAAgB,YAAY,eAAe;;EAC3C;EACA;EACA;;iBAGe;EACf;;EAEA;;EAEA;;;;;;;;;;wBAuQc,8BACd,QAAQ,oCACR,SAAS,iCACR"}
@@ -1,12 +1,12 @@
1
1
  import { DoomMcpAgentPluginProjectionSource } from "@agimon-ai/doompi-extension-contracts/mcp-projection";
2
2
  //#region src/adapters/agentPluginMcp.d.ts
3
3
  type JsonObject = Record<string, unknown>;
4
- interface AgentPluginMcpConfigSource {
4
+ export interface AgentPluginMcpConfigSource {
5
5
  path: string;
6
6
  format: 'internal';
7
7
  cacheKey: string;
8
8
  }
9
- interface NormalizedAgentPluginMcpSource {
9
+ export interface NormalizedAgentPluginMcpSource {
10
10
  /** Owner-only, content-addressed layer that bypasses Claude env interpolation. */
11
11
  configSource?: AgentPluginMcpConfigSource;
12
12
  /** Claude-compatible definitions for an external merged config. */
@@ -17,7 +17,7 @@ interface NormalizedAgentPluginMcpSource {
17
17
  droppedServers: string[];
18
18
  diagnostics: string[];
19
19
  }
20
- interface NormalizeAgentPluginMcpOptions {
20
+ export interface NormalizeAgentPluginMcpOptions {
21
21
  stagingDirectory: string;
22
22
  /** Empty and absent lists both mean keep every server. */
23
23
  allowedServers?: readonly string[];
@@ -32,7 +32,6 @@ interface NormalizeAgentPluginMcpOptions {
32
32
  * source. Only the two portable plugin placeholders are expanded; the staged
33
33
  * layer is tagged `internal`, so legacy `${ENV}` interpolation cannot run again.
34
34
  */
35
- declare function normalizeAgentPluginMcpSource(source: DoomMcpAgentPluginProjectionSource, options: NormalizeAgentPluginMcpOptions): NormalizedAgentPluginMcpSource;
35
+ export declare function normalizeAgentPluginMcpSource(source: DoomMcpAgentPluginProjectionSource, options: NormalizeAgentPluginMcpOptions): NormalizedAgentPluginMcpSource;
36
36
  //#endregion
37
- export { AgentPluginMcpConfigSource, NormalizeAgentPluginMcpOptions, NormalizedAgentPluginMcpSource, normalizeAgentPluginMcpSource };
38
37
  //# sourceMappingURL=agentPluginMcp.d.mts.map
@@ -1 +1 @@
1
- {"version":3,"file":"agentPluginMcp.d.mts","names":[],"sources":["../../src/adapters/agentPluginMcp.ts"],"mappings":";;KAeK,aAAa;UAED;EACf;EACA;EACA;;UAGe;;EAEf,eAAe;;EAEf;IAAgB,YAAY,eAAe;;EAC3C;EACA;EACA;;UAGe;EACf;;EAEA;;EAEA;;;;;;;;;;iBAuQc,8BACd,QAAQ,oCACR,SAAS,iCACR"}
1
+ {"version":3,"file":"agentPluginMcp.d.mts","names":[],"sources":["../../src/adapters/agentPluginMcp.ts"],"mappings":";;KAeK,aAAa;iBAED;EACf;EACA;EACA;;iBAGe;;EAEf,eAAe;;EAEf;IAAgB,YAAY,eAAe;;EAC3C;EACA;EACA;;iBAGe;EACf;;EAEA;;EAEA;;;;;;;;;;wBAuQc,8BACd,QAAQ,oCACR,SAAS,iCACR"}
@@ -1,6 +1,5 @@
1
1
  //#region src/adapters/atomicJson.d.ts
2
2
  /** Writes JSON readable by its owner only, replacing the target atomically. */
3
- declare function writePrivateAtomicJson(filePath: string, value: unknown): void;
3
+ export declare function writePrivateAtomicJson(filePath: string, value: unknown): void;
4
4
  //#endregion
5
- export { writePrivateAtomicJson };
6
5
  //# sourceMappingURL=atomicJson.d.cts.map
@@ -1 +1 @@
1
- {"version":3,"file":"atomicJson.d.cts","names":[],"sources":["../../src/adapters/atomicJson.ts"],"mappings":";;iBA4BgB,uBAAuB,kBAAkB"}
1
+ {"version":3,"file":"atomicJson.d.cts","names":[],"sources":["../../src/adapters/atomicJson.ts"],"mappings":";;wBA4BgB,uBAAuB,kBAAkB"}
@@ -1,6 +1,5 @@
1
1
  //#region src/adapters/atomicJson.d.ts
2
2
  /** Writes JSON readable by its owner only, replacing the target atomically. */
3
- declare function writePrivateAtomicJson(filePath: string, value: unknown): void;
3
+ export declare function writePrivateAtomicJson(filePath: string, value: unknown): void;
4
4
  //#endregion
5
- export { writePrivateAtomicJson };
6
5
  //# sourceMappingURL=atomicJson.d.mts.map
@@ -1 +1 @@
1
- {"version":3,"file":"atomicJson.d.mts","names":[],"sources":["../../src/adapters/atomicJson.ts"],"mappings":";;iBA4BgB,uBAAuB,kBAAkB"}
1
+ {"version":3,"file":"atomicJson.d.mts","names":[],"sources":["../../src/adapters/atomicJson.ts"],"mappings":";;wBA4BgB,uBAAuB,kBAAkB"}
@@ -1,11 +1,11 @@
1
1
  import { DoomConfig, DoomConfigLayers } from "../types/config.cjs";
2
2
  //#region src/adapters/config.d.ts
3
- declare function globalDoomConfigDirectory(homeDirectory?: string): string;
4
- declare function globalDoomConfigPath(homeDirectory?: string): string;
5
- declare function resolvePlanningPlansDirectory(configured: string | undefined, repoRoot: string, homeDirectory?: string): string;
6
- declare function repositoryDoomConfigPath(repoRoot: string): string;
7
- declare function loadDoomConfig(repoRoot: string, homeDirectory?: string): DoomConfig;
8
- declare function loadDoomConfigAsync(repoRoot: string, homeDirectory?: string): Promise<DoomConfig>;
3
+ export declare function globalDoomConfigDirectory(homeDirectory?: string): string;
4
+ export declare function globalDoomConfigPath(homeDirectory?: string): string;
5
+ export declare function resolvePlanningPlansDirectory(configured: string | undefined, repoRoot: string, homeDirectory?: string): string;
6
+ export declare function repositoryDoomConfigPath(repoRoot: string): string;
7
+ export declare function loadDoomConfig(repoRoot: string, homeDirectory?: string): DoomConfig;
8
+ export declare function loadDoomConfigAsync(repoRoot: string, homeDirectory?: string): Promise<DoomConfig>;
9
9
  /**
10
10
  * The two config files kept apart, with the merge alongside them.
11
11
  *
@@ -20,7 +20,6 @@ declare function loadDoomConfigAsync(repoRoot: string, homeDirectory?: string):
20
20
  * global one says. Reporting a file as the source of a value the merge discards
21
21
  * is the exact confusion this exists to remove.
22
22
  */
23
- declare function loadDoomConfigLayers(repoRoot: string | undefined, homeDirectory?: string): DoomConfigLayers;
23
+ export declare function loadDoomConfigLayers(repoRoot: string | undefined, homeDirectory?: string): DoomConfigLayers;
24
24
  //#endregion
25
- export { globalDoomConfigDirectory, globalDoomConfigPath, loadDoomConfig, loadDoomConfigAsync, loadDoomConfigLayers, repositoryDoomConfigPath, resolvePlanningPlansDirectory };
26
25
  //# sourceMappingURL=config.d.cts.map
@@ -1 +1 @@
1
- {"version":3,"file":"config.d.cts","names":[],"sources":["../../src/adapters/config.ts"],"mappings":";;iBAmCgB,0BAA0B;iBAI1B,qBAAqB;iBAIrB,8BACd,gCACA,kBACA;iBAWc,yBAAyB;iBAIzB,eAAe,kBAAkB,yBAA+B;iBAO1D,oBAAoB,kBAAkB,yBAA+B,QAAQ;;;;;;;;;;;;;;;iBA8CnF,qBAAqB,8BAA8B,yBAA+B"}
1
+ {"version":3,"file":"config.d.cts","names":[],"sources":["../../src/adapters/config.ts"],"mappings":";;wBAmCgB,0BAA0B;wBAI1B,qBAAqB;wBAIrB,8BACd,gCACA,kBACA;wBAWc,yBAAyB;wBAIzB,eAAe,kBAAkB,yBAA+B;wBAO1D,oBAAoB,kBAAkB,yBAA+B,QAAQ;;;;;;;;;;;;;;;wBA8CnF,qBAAqB,8BAA8B,yBAA+B"}
@@ -1,11 +1,11 @@
1
1
  import { DoomConfig, DoomConfigLayers } from "../types/config.mjs";
2
2
  //#region src/adapters/config.d.ts
3
- declare function globalDoomConfigDirectory(homeDirectory?: string): string;
4
- declare function globalDoomConfigPath(homeDirectory?: string): string;
5
- declare function resolvePlanningPlansDirectory(configured: string | undefined, repoRoot: string, homeDirectory?: string): string;
6
- declare function repositoryDoomConfigPath(repoRoot: string): string;
7
- declare function loadDoomConfig(repoRoot: string, homeDirectory?: string): DoomConfig;
8
- declare function loadDoomConfigAsync(repoRoot: string, homeDirectory?: string): Promise<DoomConfig>;
3
+ export declare function globalDoomConfigDirectory(homeDirectory?: string): string;
4
+ export declare function globalDoomConfigPath(homeDirectory?: string): string;
5
+ export declare function resolvePlanningPlansDirectory(configured: string | undefined, repoRoot: string, homeDirectory?: string): string;
6
+ export declare function repositoryDoomConfigPath(repoRoot: string): string;
7
+ export declare function loadDoomConfig(repoRoot: string, homeDirectory?: string): DoomConfig;
8
+ export declare function loadDoomConfigAsync(repoRoot: string, homeDirectory?: string): Promise<DoomConfig>;
9
9
  /**
10
10
  * The two config files kept apart, with the merge alongside them.
11
11
  *
@@ -20,7 +20,6 @@ declare function loadDoomConfigAsync(repoRoot: string, homeDirectory?: string):
20
20
  * global one says. Reporting a file as the source of a value the merge discards
21
21
  * is the exact confusion this exists to remove.
22
22
  */
23
- declare function loadDoomConfigLayers(repoRoot: string | undefined, homeDirectory?: string): DoomConfigLayers;
23
+ export declare function loadDoomConfigLayers(repoRoot: string | undefined, homeDirectory?: string): DoomConfigLayers;
24
24
  //#endregion
25
- export { globalDoomConfigDirectory, globalDoomConfigPath, loadDoomConfig, loadDoomConfigAsync, loadDoomConfigLayers, repositoryDoomConfigPath, resolvePlanningPlansDirectory };
26
25
  //# sourceMappingURL=config.d.mts.map
@@ -1 +1 @@
1
- {"version":3,"file":"config.d.mts","names":[],"sources":["../../src/adapters/config.ts"],"mappings":";;iBAmCgB,0BAA0B;iBAI1B,qBAAqB;iBAIrB,8BACd,gCACA,kBACA;iBAWc,yBAAyB;iBAIzB,eAAe,kBAAkB,yBAA+B;iBAO1D,oBAAoB,kBAAkB,yBAA+B,QAAQ;;;;;;;;;;;;;;;iBA8CnF,qBAAqB,8BAA8B,yBAA+B"}
1
+ {"version":3,"file":"config.d.mts","names":[],"sources":["../../src/adapters/config.ts"],"mappings":";;wBAmCgB,0BAA0B;wBAI1B,qBAAqB;wBAIrB,8BACd,gCACA,kBACA;wBAWc,yBAAyB;wBAIzB,eAAe,kBAAkB,yBAA+B;wBAO1D,oBAAoB,kBAAkB,yBAA+B,QAAQ;;;;;;;;;;;;;;;wBA8CnF,qBAAqB,8BAA8B,yBAA+B"}
@@ -24,8 +24,8 @@
24
24
  * means removing it
25
25
  */
26
26
  /** Which file a write is aimed at; the modes follow from it. */
27
- type DoomConfigScope = 'global' | 'repository';
28
- interface DoomConfigEdit {
27
+ export type DoomConfigScope = 'global' | 'repository';
28
+ export interface DoomConfigEdit {
29
29
  /** Key path into the document, e.g. `['voice', 'adapters', 'mlx-whisper', 'model', 'id']`. */
30
30
  readonly keyPath: readonly string[];
31
31
  /**
@@ -37,7 +37,7 @@ interface DoomConfigEdit {
37
37
  */
38
38
  readonly value?: string | number | boolean | readonly string[];
39
39
  }
40
- interface WriteDoomConfigOptions {
40
+ export interface WriteDoomConfigOptions {
41
41
  /**
42
42
  * Remove ancestors left holding nothing. Defaults to true, and is not
43
43
  * cosmetic: an adapter left as `{}` fails validation, because the parser
@@ -58,9 +58,8 @@ interface WriteDoomConfigOptions {
58
58
  * of edits only valid together is accepted, and a single edit that breaks an
59
59
  * invariant elsewhere is still caught.
60
60
  */
61
- declare function writeDoomConfigValues(filePath: string, edits: readonly DoomConfigEdit[], options?: WriteDoomConfigOptions): Promise<void>;
62
- declare function setDoomConfigValue(filePath: string, keyPath: readonly string[], value: string, options?: WriteDoomConfigOptions): Promise<void>;
63
- declare function unsetDoomConfigValue(filePath: string, keyPath: readonly string[], options?: WriteDoomConfigOptions): Promise<void>;
61
+ export declare function writeDoomConfigValues(filePath: string, edits: readonly DoomConfigEdit[], options?: WriteDoomConfigOptions): Promise<void>;
62
+ export declare function setDoomConfigValue(filePath: string, keyPath: readonly string[], value: string, options?: WriteDoomConfigOptions): Promise<void>;
63
+ export declare function unsetDoomConfigValue(filePath: string, keyPath: readonly string[], options?: WriteDoomConfigOptions): Promise<void>;
64
64
  //#endregion
65
- export { DoomConfigEdit, DoomConfigScope, WriteDoomConfigOptions, setDoomConfigValue, unsetDoomConfigValue, writeDoomConfigValues };
66
65
  //# sourceMappingURL=configWriter.d.cts.map
@@ -1 +1 @@
1
- {"version":3,"file":"configWriter.d.cts","names":[],"sources":["../../src/adapters/configWriter.ts"],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;KAgDY;UASK;;WAEN;;;;;;;;WAQA;;UAGM;;;;;;WAMN;;;;;;WAMA,QAAQ;;;;;;;;;iBAmCG,sBACpB,kBACA,gBAAgB,kBAChB,UAAS,yBACR;iBAqCmB,mBACpB,kBACA,4BACA,eACA,UAAS,yBACR;iBAImB,qBACpB,kBACA,4BACA,UAAS,yBACR"}
1
+ {"version":3,"file":"configWriter.d.cts","names":[],"sources":["../../src/adapters/configWriter.ts"],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;YAgDY;iBASK;;WAEN;;;;;;;;WAQA;;iBAGM;;;;;;WAMN;;;;;;WAMA,QAAQ;;;;;;;;;wBAmCG,sBACpB,kBACA,gBAAgB,kBAChB,UAAS,yBACR;wBAqCmB,mBACpB,kBACA,4BACA,eACA,UAAS,yBACR;wBAImB,qBACpB,kBACA,4BACA,UAAS,yBACR"}
@@ -24,8 +24,8 @@
24
24
  * means removing it
25
25
  */
26
26
  /** Which file a write is aimed at; the modes follow from it. */
27
- type DoomConfigScope = 'global' | 'repository';
28
- interface DoomConfigEdit {
27
+ export type DoomConfigScope = 'global' | 'repository';
28
+ export interface DoomConfigEdit {
29
29
  /** Key path into the document, e.g. `['voice', 'adapters', 'mlx-whisper', 'model', 'id']`. */
30
30
  readonly keyPath: readonly string[];
31
31
  /**
@@ -37,7 +37,7 @@ interface DoomConfigEdit {
37
37
  */
38
38
  readonly value?: string | number | boolean | readonly string[];
39
39
  }
40
- interface WriteDoomConfigOptions {
40
+ export interface WriteDoomConfigOptions {
41
41
  /**
42
42
  * Remove ancestors left holding nothing. Defaults to true, and is not
43
43
  * cosmetic: an adapter left as `{}` fails validation, because the parser
@@ -58,9 +58,8 @@ interface WriteDoomConfigOptions {
58
58
  * of edits only valid together is accepted, and a single edit that breaks an
59
59
  * invariant elsewhere is still caught.
60
60
  */
61
- declare function writeDoomConfigValues(filePath: string, edits: readonly DoomConfigEdit[], options?: WriteDoomConfigOptions): Promise<void>;
62
- declare function setDoomConfigValue(filePath: string, keyPath: readonly string[], value: string, options?: WriteDoomConfigOptions): Promise<void>;
63
- declare function unsetDoomConfigValue(filePath: string, keyPath: readonly string[], options?: WriteDoomConfigOptions): Promise<void>;
61
+ export declare function writeDoomConfigValues(filePath: string, edits: readonly DoomConfigEdit[], options?: WriteDoomConfigOptions): Promise<void>;
62
+ export declare function setDoomConfigValue(filePath: string, keyPath: readonly string[], value: string, options?: WriteDoomConfigOptions): Promise<void>;
63
+ export declare function unsetDoomConfigValue(filePath: string, keyPath: readonly string[], options?: WriteDoomConfigOptions): Promise<void>;
64
64
  //#endregion
65
- export { DoomConfigEdit, DoomConfigScope, WriteDoomConfigOptions, setDoomConfigValue, unsetDoomConfigValue, writeDoomConfigValues };
66
65
  //# sourceMappingURL=configWriter.d.mts.map
@@ -1 +1 @@
1
- {"version":3,"file":"configWriter.d.mts","names":[],"sources":["../../src/adapters/configWriter.ts"],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;KAgDY;UASK;;WAEN;;;;;;;;WAQA;;UAGM;;;;;;WAMN;;;;;;WAMA,QAAQ;;;;;;;;;iBAmCG,sBACpB,kBACA,gBAAgB,kBAChB,UAAS,yBACR;iBAqCmB,mBACpB,kBACA,4BACA,eACA,UAAS,yBACR;iBAImB,qBACpB,kBACA,4BACA,UAAS,yBACR"}
1
+ {"version":3,"file":"configWriter.d.mts","names":[],"sources":["../../src/adapters/configWriter.ts"],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;YAgDY;iBASK;;WAEN;;;;;;;;WAQA;;iBAGM;;;;;;WAMN;;;;;;WAMA,QAAQ;;;;;;;;;wBAmCG,sBACpB,kBACA,gBAAgB,kBAChB,UAAS,yBACR;wBAqCmB,mBACpB,kBACA,4BACA,eACA,UAAS,yBACR;wBAImB,qBACpB,kBACA,4BACA,UAAS,yBACR"}
@@ -8,20 +8,20 @@ import { DOOM_DIR } from "./layeredConfig.cjs";
8
8
  * definitions. Configured roots accumulate, with exact marketplace manifests
9
9
  * deduplicated in discovery order. Explicit entries override discovered IDs.
10
10
  */
11
- declare function loadDomains(repoRoot: string, homeDirectory?: string): DomainManifest;
12
- declare function listDomainNames(repoRoot: string, homeDirectory?: string): string[];
11
+ export declare function loadDomains(repoRoot: string, homeDirectory?: string): DomainManifest;
12
+ export declare function listDomainNames(repoRoot: string, homeDirectory?: string): string[];
13
13
  /**
14
14
  * Whether to include .claude/skills as shared fallbacks.
15
15
  *
16
16
  * Shared skills are included unless every selected domain opts out, so mixing a
17
17
  * trimmed domain with an untrimmed one cannot strip the untrimmed one's skills.
18
18
  */
19
- declare function resolveSharedSkills(repoRoot: string, domainNames: string[], homeDirectory?: string): boolean;
19
+ export declare function resolveSharedSkills(repoRoot: string, domainNames: string[], homeDirectory?: string): boolean;
20
20
  /** Resolves named domain plugins while preserving each subset filter. */
21
- declare function resolvePluginEntries(repoRoot: string, domainNames: string[], explicitDirectories: string[], homeDirectory?: string): PluginEntry[];
22
- declare function resolvePluginDirectories(repoRoot: string, domainNames: string[], explicitDirectories: string[], homeDirectory?: string): string[];
23
- declare const DOOMPI_DOMAINS_ENV = "DOOMPI_DOMAINS";
24
- declare const DEFAULT_DOMAIN = "default";
21
+ export declare function resolvePluginEntries(repoRoot: string, domainNames: string[], explicitDirectories: string[], homeDirectory?: string): PluginEntry[];
22
+ export declare function resolvePluginDirectories(repoRoot: string, domainNames: string[], explicitDirectories: string[], homeDirectory?: string): string[];
23
+ export declare const DOOMPI_DOMAINS_ENV = "DOOMPI_DOMAINS";
24
+ export declare const DEFAULT_DOMAIN = "default";
25
25
  /**
26
26
  * Domains selected when the caller names none.
27
27
  *
@@ -29,7 +29,7 @@ declare const DEFAULT_DOMAIN = "default";
29
29
  * major-mode-derived choice is retained only as the compatibility fallback for
30
30
  * domains files that declare no defaultDomains.
31
31
  */
32
- declare function defaultDomainsForMajorMode(majorMode: string, environment: NodeJS.ProcessEnv, defaultDomains?: readonly string[]): string[];
32
+ export declare function defaultDomainsForMajorMode(majorMode: string, environment: NodeJS.ProcessEnv, defaultDomains?: readonly string[]): string[];
33
33
  //#endregion
34
- export { DEFAULT_DOMAIN, DOOMPI_DOMAINS_ENV, DOOM_DIR, defaultDomainsForMajorMode, listDomainNames, loadDomains, resolvePluginDirectories, resolvePluginEntries, resolveSharedSkills };
34
+ export { DOOM_DIR };
35
35
  //# sourceMappingURL=domains.d.cts.map
@@ -1 +1 @@
1
- {"version":3,"file":"domains.d.cts","names":[],"sources":["../../src/adapters/domains.ts"],"mappings":";;;;;;;;;;iBA2HgB,YAAY,kBAAkB,yBAAuC;iBA0CrE,gBAAgB,kBAAkB;;;;;;;iBAWlC,oBAAoB,kBAAkB,uBAAuB;;iBAQ7D,qBACd,kBACA,uBACA,+BACA,yBACC;iBAwDa,yBACd,kBACA,uBACA,+BACA;cAOW;cACA;;;;;;;;iBAiBG,2BACd,mBACA,aAAa,OAAO,YACpB"}
1
+ {"version":3,"file":"domains.d.cts","names":[],"sources":["../../src/adapters/domains.ts"],"mappings":";;;;;;;;;;wBA2HgB,YAAY,kBAAkB,yBAAuC;wBA0CrE,gBAAgB,kBAAkB;;;;;;;wBAWlC,oBAAoB,kBAAkB,uBAAuB;;wBAQ7D,qBACd,kBACA,uBACA,+BACA,yBACC;wBAwDa,yBACd,kBACA,uBACA,+BACA;qBAOW;qBACA;;;;;;;;wBAiBG,2BACd,mBACA,aAAa,OAAO,YACpB"}
@@ -8,20 +8,20 @@ import { DOOM_DIR } from "./layeredConfig.mjs";
8
8
  * definitions. Configured roots accumulate, with exact marketplace manifests
9
9
  * deduplicated in discovery order. Explicit entries override discovered IDs.
10
10
  */
11
- declare function loadDomains(repoRoot: string, homeDirectory?: string): DomainManifest;
12
- declare function listDomainNames(repoRoot: string, homeDirectory?: string): string[];
11
+ export declare function loadDomains(repoRoot: string, homeDirectory?: string): DomainManifest;
12
+ export declare function listDomainNames(repoRoot: string, homeDirectory?: string): string[];
13
13
  /**
14
14
  * Whether to include .claude/skills as shared fallbacks.
15
15
  *
16
16
  * Shared skills are included unless every selected domain opts out, so mixing a
17
17
  * trimmed domain with an untrimmed one cannot strip the untrimmed one's skills.
18
18
  */
19
- declare function resolveSharedSkills(repoRoot: string, domainNames: string[], homeDirectory?: string): boolean;
19
+ export declare function resolveSharedSkills(repoRoot: string, domainNames: string[], homeDirectory?: string): boolean;
20
20
  /** Resolves named domain plugins while preserving each subset filter. */
21
- declare function resolvePluginEntries(repoRoot: string, domainNames: string[], explicitDirectories: string[], homeDirectory?: string): PluginEntry[];
22
- declare function resolvePluginDirectories(repoRoot: string, domainNames: string[], explicitDirectories: string[], homeDirectory?: string): string[];
23
- declare const DOOMPI_DOMAINS_ENV = "DOOMPI_DOMAINS";
24
- declare const DEFAULT_DOMAIN = "default";
21
+ export declare function resolvePluginEntries(repoRoot: string, domainNames: string[], explicitDirectories: string[], homeDirectory?: string): PluginEntry[];
22
+ export declare function resolvePluginDirectories(repoRoot: string, domainNames: string[], explicitDirectories: string[], homeDirectory?: string): string[];
23
+ export declare const DOOMPI_DOMAINS_ENV = "DOOMPI_DOMAINS";
24
+ export declare const DEFAULT_DOMAIN = "default";
25
25
  /**
26
26
  * Domains selected when the caller names none.
27
27
  *
@@ -29,7 +29,7 @@ declare const DEFAULT_DOMAIN = "default";
29
29
  * major-mode-derived choice is retained only as the compatibility fallback for
30
30
  * domains files that declare no defaultDomains.
31
31
  */
32
- declare function defaultDomainsForMajorMode(majorMode: string, environment: NodeJS.ProcessEnv, defaultDomains?: readonly string[]): string[];
32
+ export declare function defaultDomainsForMajorMode(majorMode: string, environment: NodeJS.ProcessEnv, defaultDomains?: readonly string[]): string[];
33
33
  //#endregion
34
- export { DEFAULT_DOMAIN, DOOMPI_DOMAINS_ENV, DOOM_DIR, defaultDomainsForMajorMode, listDomainNames, loadDomains, resolvePluginDirectories, resolvePluginEntries, resolveSharedSkills };
34
+ export { DOOM_DIR };
35
35
  //# sourceMappingURL=domains.d.mts.map
@@ -1 +1 @@
1
- {"version":3,"file":"domains.d.mts","names":[],"sources":["../../src/adapters/domains.ts"],"mappings":";;;;;;;;;;iBA2HgB,YAAY,kBAAkB,yBAAuC;iBA0CrE,gBAAgB,kBAAkB;;;;;;;iBAWlC,oBAAoB,kBAAkB,uBAAuB;;iBAQ7D,qBACd,kBACA,uBACA,+BACA,yBACC;iBAwDa,yBACd,kBACA,uBACA,+BACA;cAOW;cACA;;;;;;;;iBAiBG,2BACd,mBACA,aAAa,OAAO,YACpB"}
1
+ {"version":3,"file":"domains.d.mts","names":[],"sources":["../../src/adapters/domains.ts"],"mappings":";;;;;;;;;;wBA2HgB,YAAY,kBAAkB,yBAAuC;wBA0CrE,gBAAgB,kBAAkB;;;;;;;wBAWlC,oBAAoB,kBAAkB,uBAAuB;;wBAQ7D,qBACd,kBACA,uBACA,+BACA,yBACC;wBAwDa,yBACd,kBACA,uBACA,+BACA;qBAOW;qBACA;;;;;;;;wBAiBG,2BACd,mBACA,aAAa,OAAO,YACpB"}
@@ -8,9 +8,9 @@ import { HarnessState } from "../types/config.cjs";
8
8
  * are read from the store, while Config publishes the MCP projection through
9
9
  * the session-scoped Cordis registry.
10
10
  */
11
- declare const FILE_ONLY_STATE_FIELDS: ReadonlySet<keyof HarnessState>;
12
- type HarnessStateParseReporter = (key: string, error: unknown) => void;
13
- declare const HARNESS_STATE_KEYS: {
11
+ export declare const FILE_ONLY_STATE_FIELDS: ReadonlySet<keyof HarnessState>;
12
+ export type HarnessStateParseReporter = (key: string, error: unknown) => void;
13
+ export declare const HARNESS_STATE_KEYS: {
14
14
  readonly root: 'DOOMPI_ROOT';
15
15
  readonly majorMode: 'DOOMPI_MAJOR_MODE';
16
16
  readonly temporaryDirectory: 'DOOMPI_TEMP_DIR';
@@ -33,7 +33,7 @@ declare const HARNESS_STATE_KEYS: {
33
33
  readonly mcp: 'DOOMPI_MCP_ENABLED';
34
34
  readonly allowProtectedWrites: 'DOOMPI_ALLOW_PROTECTED_WRITES';
35
35
  };
36
- declare function readHarnessState(environment?: NodeJS.ProcessEnv, report?: HarnessStateParseReporter): HarnessState;
36
+ export declare function readHarnessState(environment?: NodeJS.ProcessEnv, report?: HarnessStateParseReporter): HarnessState;
37
37
  /**
38
38
  * Publishes a state patch into an environment.
39
39
  *
@@ -44,7 +44,6 @@ declare function readHarnessState(environment?: NodeJS.ProcessEnv, report?: Harn
44
44
  * Fields in FILE_ONLY_FIELDS are skipped: the file carries them, and a reader
45
45
  * that needs them reads the store.
46
46
  */
47
- declare function projectHarnessEnvironment(patch: Partial<HarnessState>, environment?: NodeJS.ProcessEnv): NodeJS.ProcessEnv;
47
+ export declare function projectHarnessEnvironment(patch: Partial<HarnessState>, environment?: NodeJS.ProcessEnv): NodeJS.ProcessEnv;
48
48
  //#endregion
49
- export { FILE_ONLY_STATE_FIELDS, HARNESS_STATE_KEYS, HarnessStateParseReporter, projectHarnessEnvironment, readHarnessState };
50
49
  //# sourceMappingURL=harnessState.d.cts.map
@@ -1 +1 @@
1
- {"version":3,"file":"harnessState.d.cts","names":[],"sources":["../../src/adapters/harnessState.ts"],"mappings":";;;;;;;;;;cAwBa,wBAAwB,kBAAkB;KAU3C,6BAA6B,aAAa;cAEzC;WACX;WACA;WACA;WACA;WACA;WACA;WACA;WACA;WACA;WACA;WACA;WACA;WACA;WACA;WACA;WACA;WACA;WACA;WACA;WACA;WACA;;iBA4Ec,iBACd,cAAa,OAAO,YACpB,SAAS,4BACR;;;;;;;;;;;iBAsCa,0BACd,OAAO,QAAQ,eACf,cAAa,OAAO,aACnB,OAAO"}
1
+ {"version":3,"file":"harnessState.d.cts","names":[],"sources":["../../src/adapters/harnessState.ts"],"mappings":";;;;;;;;;;qBAwBa,wBAAwB,kBAAkB;YAU3C,6BAA6B,aAAa;qBAEzC;WACX;WACA;WACA;WACA;WACA;WACA;WACA;WACA;WACA;WACA;WACA;WACA;WACA;WACA;WACA;WACA;WACA;WACA;WACA;WACA;WACA;;wBA4Ec,iBACd,cAAa,OAAO,YACpB,SAAS,4BACR;;;;;;;;;;;wBAsCa,0BACd,OAAO,QAAQ,eACf,cAAa,OAAO,aACnB,OAAO"}
@@ -8,9 +8,9 @@ import { HarnessState } from "../types/config.mjs";
8
8
  * are read from the store, while Config publishes the MCP projection through
9
9
  * the session-scoped Cordis registry.
10
10
  */
11
- declare const FILE_ONLY_STATE_FIELDS: ReadonlySet<keyof HarnessState>;
12
- type HarnessStateParseReporter = (key: string, error: unknown) => void;
13
- declare const HARNESS_STATE_KEYS: {
11
+ export declare const FILE_ONLY_STATE_FIELDS: ReadonlySet<keyof HarnessState>;
12
+ export type HarnessStateParseReporter = (key: string, error: unknown) => void;
13
+ export declare const HARNESS_STATE_KEYS: {
14
14
  readonly root: 'DOOMPI_ROOT';
15
15
  readonly majorMode: 'DOOMPI_MAJOR_MODE';
16
16
  readonly temporaryDirectory: 'DOOMPI_TEMP_DIR';
@@ -33,7 +33,7 @@ declare const HARNESS_STATE_KEYS: {
33
33
  readonly mcp: 'DOOMPI_MCP_ENABLED';
34
34
  readonly allowProtectedWrites: 'DOOMPI_ALLOW_PROTECTED_WRITES';
35
35
  };
36
- declare function readHarnessState(environment?: NodeJS.ProcessEnv, report?: HarnessStateParseReporter): HarnessState;
36
+ export declare function readHarnessState(environment?: NodeJS.ProcessEnv, report?: HarnessStateParseReporter): HarnessState;
37
37
  /**
38
38
  * Publishes a state patch into an environment.
39
39
  *
@@ -44,7 +44,6 @@ declare function readHarnessState(environment?: NodeJS.ProcessEnv, report?: Harn
44
44
  * Fields in FILE_ONLY_FIELDS are skipped: the file carries them, and a reader
45
45
  * that needs them reads the store.
46
46
  */
47
- declare function projectHarnessEnvironment(patch: Partial<HarnessState>, environment?: NodeJS.ProcessEnv): NodeJS.ProcessEnv;
47
+ export declare function projectHarnessEnvironment(patch: Partial<HarnessState>, environment?: NodeJS.ProcessEnv): NodeJS.ProcessEnv;
48
48
  //#endregion
49
- export { FILE_ONLY_STATE_FIELDS, HARNESS_STATE_KEYS, HarnessStateParseReporter, projectHarnessEnvironment, readHarnessState };
50
49
  //# sourceMappingURL=harnessState.d.mts.map
@@ -1 +1 @@
1
- {"version":3,"file":"harnessState.d.mts","names":[],"sources":["../../src/adapters/harnessState.ts"],"mappings":";;;;;;;;;;cAwBa,wBAAwB,kBAAkB;KAU3C,6BAA6B,aAAa;cAEzC;WACX;WACA;WACA;WACA;WACA;WACA;WACA;WACA;WACA;WACA;WACA;WACA;WACA;WACA;WACA;WACA;WACA;WACA;WACA;WACA;WACA;;iBA4Ec,iBACd,cAAa,OAAO,YACpB,SAAS,4BACR;;;;;;;;;;;iBAsCa,0BACd,OAAO,QAAQ,eACf,cAAa,OAAO,aACnB,OAAO"}
1
+ {"version":3,"file":"harnessState.d.mts","names":[],"sources":["../../src/adapters/harnessState.ts"],"mappings":";;;;;;;;;;qBAwBa,wBAAwB,kBAAkB;YAU3C,6BAA6B,aAAa;qBAEzC;WACX;WACA;WACA;WACA;WACA;WACA;WACA;WACA;WACA;WACA;WACA;WACA;WACA;WACA;WACA;WACA;WACA;WACA;WACA;WACA;WACA;;wBA4Ec,iBACd,cAAa,OAAO,YACpB,SAAS,4BACR;;;;;;;;;;;wBAsCa,0BACd,OAAO,QAAQ,eACf,cAAa,OAAO,aACnB,OAAO"}
@@ -1,2 +1,2 @@
1
- const e=require("../_virtual/_rolldown/runtime.cjs"),t=require("./atomicJson.cjs"),n=require("./harnessState.cjs");let r=require("node:fs");r=e.__toESM(r,1);let i=require("node:path");i=e.__toESM(i,1);let a=require("node:os");a=e.__toESM(a,1);const o=`DOOMPI_STATE`;let s;function c(){s=void 0}function l(e){try{return r.default.statSync(e).mtimeMs}catch{return}}function u(e,t){let n=t[o];if(e.filePath!==n)return!1;if(!e.filePath)return!0;try{return r.default.statSync(e.filePath).mtimeMs===e.mtimeMs}catch{return!1}}function d(e,t){let n=JSON.parse(e);if(n.version!==1)throw Error(`Harness state at ${t} has version ${String(n.version)}, expected 1`);if(typeof n.state!=`object`||n.state===null)throw Error(`Harness state at ${t} has no state object`);return{version:1,owner:{pid:n.owner?.pid??-1,startedAt:n.owner?.startedAt??``},state:n.state}}function f(e=process.env,t){let i=e===process.env;if(i&&s&&u(s,e))return s;let a=e[o],c;if(a&&r.default.existsSync(a))try{let e=d(r.default.readFileSync(a,`utf8`),a);c={filePath:a,owned:e.owner.pid===process.pid||e.owner.pid===0,state:e.state,mtimeMs:l(a)}}catch(e){t?.(o,e)}return c??={owned:!1,state:n.readHarnessState(e,t)},i&&(s=c),c}function p(e=process.env){let t=f(e),r={[o]:e[o]};for(let t of Object.values(n.HARNESS_STATE_KEYS))r[t]=e[t];return{filePath:t.filePath,owned:t.owned,state:structuredClone(t.state),environment:r}}function m(e,t=process.env){let n=f(t);if(e.filePath&&e.owned){if(!n.owned||n.filePath!==e.filePath)throw Error(`Harness state ownership changed; refusing to restore an older snapshot.`);v(e.filePath,e.state)}else if(!e.filePath){if(n.filePath&&!n.owned)throw Error(`Harness state is no longer owned by this process; refusing to restore an older snapshot.`);n.filePath&&n.owned&&r.default.rmSync(n.filePath,{force:!0}),c()}else if(n.filePath!==e.filePath)throw Error(`Harness state pointer changed; refusing to restore an older snapshot.`);for(let[n,r]of Object.entries(e.environment))r===void 0?delete t[n]:t[n]=r;t===process.env&&(s=e.filePath?{filePath:e.filePath,owned:e.owned,state:e.state,mtimeMs:l(e.filePath)}:void 0)}function h(e){return f(process.env,e).state}function g(e){return i.default.join(e,`harness-state.json`)}function _(){return i.default.join(a.default.tmpdir(),`doom-harness`,`${String(process.pid)}.json`)}function v(e,n,r=process.pid){t.writePrivateAtomicJson(e,{version:1,owner:{pid:r,startedAt:new Date().toISOString()},state:n})}function y(e,t){let r=g(t.directory);return v(r,e,t.unclaimed?0:process.pid),t.environment[o]=r,n.projectHarnessEnvironment(e,t.environment),!t.unclaimed&&t.environment===process.env&&(s={filePath:r,owned:!0,state:e,mtimeMs:l(r)}),r}function b(e,t=process.env){let r=f(t),i={...r.state,...e},a=r.owned&&r.filePath?r.filePath:_();return v(a,i),t[o]=a,t===process.env&&(s={filePath:a,owned:!0,state:i,mtimeMs:l(a)}),n.projectHarnessEnvironment(e,t),i}function x(e=process.env){let t=s;c(),!(!t?.owned||!t.filePath)&&(r.default.rmSync(t.filePath,{force:!0}),delete e[o])}function S(e=h()){return e.root??process.cwd()}function C(e=h()){if(!e.root)throw Error(`${n.HARNESS_STATE_KEYS.root} is not set`);return e.root}function w(e=h()){let t=C(e);if(!e.temporaryDirectory)throw Error(`${n.HARNESS_STATE_KEYS.temporaryDirectory} is not set`);return{root:t,temporaryDirectory:e.temporaryDirectory}}exports.HARNESS_STATE_POINTER=o,exports.createHarnessSession=y,exports.disposeHarnessState=x,exports.getHarnessState=h,exports.harnessRoot=S,exports.loadHarnessState=f,exports.requireHarnessPaths=w,exports.requireHarnessRoot=C,exports.resetHarnessStore=c,exports.restoreHarnessStateSnapshot=m,exports.snapshotHarnessState=p,exports.updateHarnessState=b;
1
+ const e=require("../_virtual/_rolldown/runtime.cjs"),t=require("./atomicJson.cjs"),n=require("./harnessState.cjs");let r=require("node:fs");r=e.__toESM(r,1);let i=require("node:path");i=e.__toESM(i,1);let a=require("node:os");a=e.__toESM(a,1);const o=`DOOMPI_STATE`;let s;function c(){s=void 0}function l(e){try{return r.default.statSync(e).mtimeMs}catch{return}}function u(e,t){let n=t[o];if(e.filePath!==n)return!1;if(!e.filePath)return!0;try{return r.default.statSync(e.filePath).mtimeMs===e.mtimeMs}catch{return!1}}function d(e,t){let n=JSON.parse(e);if(n.version!==1)throw Error(`Harness state at ${t} has version ${String(n.version)}, expected 1`);if(typeof n.state!=`object`||n.state===null)throw Error(`Harness state at ${t} has no state object`);return{version:1,owner:{pid:n.owner?.pid??-1,startedAt:n.owner?.startedAt??``},state:n.state}}function f(e=process.env,t){let i=e===process.env;if(i&&s&&u(s,e))return s;let a=e[o],c;if(a&&r.default.existsSync(a))try{let e=d(r.default.readFileSync(a,`utf8`),a);c={filePath:a,owned:e.owner.pid===process.pid||e.owner.pid===0,state:e.state,mtimeMs:l(a)}}catch(e){t?.(o,e)}return c??={owned:!1,state:n.readHarnessState(e,t)},i&&(s=c),c}function p(e=process.env){let t=f(e),r={[o]:e[o]};for(let t of Object.values(n.HARNESS_STATE_KEYS))r[t]=e[t];return{filePath:t.filePath,owned:t.owned,state:structuredClone(t.state),environment:r}}function m(e,t=process.env){let n=f(t);if(e.filePath&&e.owned){if(!n.owned||n.filePath!==e.filePath)throw Error(`Harness state ownership changed; refusing to restore an older snapshot.`);v(e.filePath,e.state)}else if(!e.filePath){if(n.filePath&&!n.owned)throw Error(`Harness state is no longer owned by this process; refusing to restore an older snapshot.`);n.filePath&&n.owned&&r.default.rmSync(n.filePath,{force:!0}),c()}else if(n.filePath!==e.filePath)throw Error(`Harness state pointer changed; refusing to restore an older snapshot.`);for(let[n,r]of Object.entries(e.environment))r===void 0?delete t[n]:t[n]=r;t===process.env&&(s=e.filePath?{filePath:e.filePath,owned:e.owned,state:e.state,mtimeMs:l(e.filePath)}:void 0)}function h(e){return f(process.env,e).state}function g(e){return i.default.join(e,`harness-state.json`)}function _(){return i.default.join(a.default.tmpdir(),`doom-harness`,`${String(process.pid)}.json`)}function v(e,n,r=process.pid){t.writePrivateAtomicJson(e,{version:1,owner:{pid:r,startedAt:new Date().toISOString()},state:n})}function y(e,t){let r=g(t.directory);return v(r,e,t.unclaimed?0:process.pid),t.environment[o]=r,n.projectHarnessEnvironment(e,t.environment),!t.unclaimed&&t.environment===process.env&&(s={filePath:r,owned:!0,state:e,mtimeMs:l(r)}),r}function b(e,t=process.env){let r=f(t),i={...r.state,...e},a=r.owned&&r.filePath?r.filePath:_();return v(a,i),t[o]=a,t===process.env&&(s={filePath:a,owned:!0,state:i,mtimeMs:l(a)}),n.projectHarnessEnvironment(e,t),i}function x(e=process.env){let t=s;c(),t?.owned&&t.filePath&&(r.default.rmSync(t.filePath,{force:!0}),delete e[o])}function S(e=h()){return e.root??process.cwd()}function C(e=h()){if(!e.root)throw Error(`${n.HARNESS_STATE_KEYS.root} is not set`);return e.root}function w(e=h()){let t=C(e);if(!e.temporaryDirectory)throw Error(`${n.HARNESS_STATE_KEYS.temporaryDirectory} is not set`);return{root:t,temporaryDirectory:e.temporaryDirectory}}exports.HARNESS_STATE_POINTER=o,exports.createHarnessSession=y,exports.disposeHarnessState=x,exports.getHarnessState=h,exports.harnessRoot=S,exports.loadHarnessState=f,exports.requireHarnessPaths=w,exports.requireHarnessRoot=C,exports.resetHarnessStore=c,exports.restoreHarnessStateSnapshot=m,exports.snapshotHarnessState=p,exports.updateHarnessState=b;
2
2
  //# sourceMappingURL=harnessStore.cjs.map
@@ -1 +1 @@
1
- {"version":3,"file":"harnessStore.cjs","names":["fs","readHarnessState","HARNESS_STATE_KEYS","path","os"],"sources":["../../src/adapters/harnessStore.ts"],"sourcesContent":["import fs from 'node:fs';\nimport os from 'node:os';\nimport path from 'node:path';\nimport type { HarnessState } from '../types/config.ts';\nimport { writePrivateAtomicJson } from './atomicJson.ts';\nimport {\n HARNESS_STATE_KEYS,\n type HarnessStateParseReporter,\n projectHarnessEnvironment,\n readHarnessState,\n} from './harnessState.ts';\n\n/**\n * Who owns the harness state, and where it lives.\n *\n * The state used to be the environment: twenty variables that every reader\n * re-parsed and every writer mutated globally. The file is the authority now,\n * and the environment is a projection published for the readers that can only\n * see an environment, which are bash hooks, the shell launchers, packages that\n * do not depend on this one, and any process spawned by any of them.\n *\n * OWNERSHIP IS PER PROCESS, AND THAT IS THE WHOLE DESIGN:\n * Doom Team subagents run detached, in their own process group, from an\n * environment snapshot taken at spawn. A child can outlive its parent. If it\n * shared the parent's file it would corrupt a session it does not own, and if\n * that file sat in the parent's run directory the parent's shutdown sweep would\n * delete it from under a live run. So every process writes a file it owns:\n * `owner.pid` records who, and a process that finds someone else's file copies\n * it before its first write.\n *\n * AVOID:\n * - Treating the file as shared mutable state between processes. Atomic writes\n * prevent torn reads, not lost updates\n * - Reading the environment directly for anything this exposes\n */\n\n/** Points at the state file. The one variable that is not derived. */\nexport const HARNESS_STATE_POINTER = 'DOOMPI_STATE';\n\nconst STATE_FILE_VERSION = 1;\nconst STATE_FILE_NAME = 'harness-state.json';\nconst ADOPTED_DIRECTORY = 'doom-harness';\n/**\n * Written for a process that does not exist yet, so the first one to read it\n * owns it. A spawner cannot know its child's pid, and a child that inherited\n * its parent's file would lose it the moment the parent cleaned up.\n */\nconst UNCLAIMED_OWNER = 0;\n\nexport interface HarnessStateFile {\n version: number;\n owner: { pid: number; startedAt: string };\n state: HarnessState;\n}\n\nexport interface HarnessStateTransactionSnapshot {\n readonly filePath?: string;\n readonly owned: boolean;\n readonly state: HarnessState;\n readonly environment: Readonly<Record<string, string | undefined>>;\n}\n\nexport interface LoadedHarnessState {\n /** Undefined when this process is running off the environment fallback. */\n filePath?: string;\n owned: boolean;\n state: HarnessState;\n}\n\ninterface CachedHarnessState extends LoadedHarnessState {\n /** The file's mtime when it was read, so a rewrite by another copy is noticed. */\n mtimeMs?: number;\n}\n\nlet loaded: CachedHarnessState | undefined;\n\n/** Drops the cached state. For tests, and for a process changing identity. */\nexport function resetHarnessStore(): void {\n loaded = undefined;\n}\n\nfunction fileMtime(filePath: string): number | undefined {\n try {\n return fs.statSync(filePath).mtimeMs;\n } catch {\n return undefined;\n }\n}\n\n/**\n * Whether the cache still describes what the process points at.\n *\n * A session can load more than one copy of this package (a layer package\n * installed under .pi/npm brings its own), and each copy caches on its own.\n * The pointer and the file are shared, so a switch persisted through one copy\n * moves the pointer or rewrites the file, and every other copy must notice\n * rather than answer from memory.\n */\nfunction cacheCurrent(cache: CachedHarnessState, environment: NodeJS.ProcessEnv): boolean {\n const pointer = environment[HARNESS_STATE_POINTER];\n if (cache.filePath !== pointer) return false;\n if (!cache.filePath) return true;\n try {\n return fs.statSync(cache.filePath).mtimeMs === cache.mtimeMs;\n } catch {\n return false;\n }\n}\n\nfunction parseStateFile(source: string, filePath: string): HarnessStateFile {\n const parsed = JSON.parse(source) as Partial<HarnessStateFile>;\n if (parsed.version !== STATE_FILE_VERSION) {\n throw new Error(\n `Harness state at ${filePath} has version ${String(parsed.version)}, expected ${STATE_FILE_VERSION}`,\n );\n }\n if (typeof parsed.state !== 'object' || parsed.state === null) {\n throw new Error(`Harness state at ${filePath} has no state object`);\n }\n return {\n version: STATE_FILE_VERSION,\n owner: { pid: parsed.owner?.pid ?? -1, startedAt: parsed.owner?.startedAt ?? '' },\n state: parsed.state as HarnessState,\n };\n}\n\n/**\n * Reads the state for this process, once.\n *\n * A missing pointer means nobody wrote a file for this process, so the\n * environment is all there is: a nested run, a third-party spawn, or a caller\n * older than the store. A pointer that cannot be read is reported and then\n * treated the same way, because a session that starts degraded beats a session\n * that does not start at all.\n */\nexport function loadHarnessState(\n environment: NodeJS.ProcessEnv = process.env,\n report?: HarnessStateParseReporter,\n): LoadedHarnessState {\n // The cache describes this process. Asking about another environment is a\n // question about another process, so it reads through rather than answering\n // from what this one happens to hold.\n const cacheable = environment === process.env;\n if (cacheable && loaded && cacheCurrent(loaded, environment)) return loaded;\n\n const filePath = environment[HARNESS_STATE_POINTER];\n let result: CachedHarnessState | undefined;\n if (filePath && fs.existsSync(filePath)) {\n try {\n const file = parseStateFile(fs.readFileSync(filePath, 'utf8'), filePath);\n const owned = file.owner.pid === process.pid || file.owner.pid === UNCLAIMED_OWNER;\n result = { filePath, owned, state: file.state, mtimeMs: fileMtime(filePath) };\n } catch (error) {\n report?.(HARNESS_STATE_POINTER, error);\n }\n }\n result ??= { owned: false, state: readHarnessState(environment, report) };\n if (cacheable) loaded = result;\n return result;\n}\n\n/** Captures the owned state pointer and every projected harness variable. */\nexport function snapshotHarnessState(environment: NodeJS.ProcessEnv = process.env): HarnessStateTransactionSnapshot {\n const loadedState = loadHarnessState(environment);\n const environmentSnapshot: Record<string, string | undefined> = {\n [HARNESS_STATE_POINTER]: environment[HARNESS_STATE_POINTER],\n };\n for (const key of Object.values(HARNESS_STATE_KEYS)) environmentSnapshot[key] = environment[key];\n return {\n filePath: loadedState.filePath,\n owned: loadedState.owned,\n state: structuredClone(loadedState.state),\n environment: environmentSnapshot,\n };\n}\n\n/** Restores a snapshot only while the current process still owns its state pointer. */\nexport function restoreHarnessStateSnapshot(\n snapshot: HarnessStateTransactionSnapshot,\n environment: NodeJS.ProcessEnv = process.env,\n): void {\n const current = loadHarnessState(environment);\n if (snapshot.filePath && snapshot.owned) {\n if (!current.owned || current.filePath !== snapshot.filePath) {\n throw new Error('Harness state ownership changed; refusing to restore an older snapshot.');\n }\n persist(snapshot.filePath, snapshot.state);\n } else if (!snapshot.filePath) {\n if (current.filePath && !current.owned) {\n throw new Error('Harness state is no longer owned by this process; refusing to restore an older snapshot.');\n }\n if (current.filePath && current.owned) fs.rmSync(current.filePath, { force: true });\n resetHarnessStore();\n } else if (current.filePath !== snapshot.filePath) {\n throw new Error('Harness state pointer changed; refusing to restore an older snapshot.');\n }\n for (const [key, value] of Object.entries(snapshot.environment)) {\n if (value === undefined) delete environment[key];\n else environment[key] = value;\n }\n if (environment === process.env) {\n loaded = snapshot.filePath\n ? {\n filePath: snapshot.filePath,\n owned: snapshot.owned,\n state: snapshot.state,\n mtimeMs: fileMtime(snapshot.filePath),\n }\n : undefined;\n }\n}\n\nexport function getHarnessState(report?: HarnessStateParseReporter): HarnessState {\n return loadHarnessState(process.env, report).state;\n}\n\nfunction stateFilePath(directory: string): string {\n return path.join(directory, STATE_FILE_NAME);\n}\n\n/** Where a process writes state when it was not given a file of its own. */\nfunction adoptedStateFilePath(): string {\n return path.join(os.tmpdir(), ADOPTED_DIRECTORY, `${String(process.pid)}.json`);\n}\n\nfunction persist(filePath: string, state: HarnessState, ownerPid = process.pid): void {\n writePrivateAtomicJson(filePath, {\n version: STATE_FILE_VERSION,\n owner: { pid: ownerPid, startedAt: new Date().toISOString() },\n state,\n } satisfies HarnessStateFile);\n}\n\n/**\n * Starts a session: writes the file and publishes the derived environment.\n *\n * The environment is a parameter because the caller is usually describing a\n * process other than itself. The launcher builds the environment for the Pi it\n * is about to spawn, and Doom Team builds the snapshot for a detached child, so\n * neither should touch its own `process.env` to do it.\n */\nexport function createHarnessSession(\n state: HarnessState,\n options: {\n directory: string;\n environment: NodeJS.ProcessEnv;\n /**\n * Leave the file for a process that does not exist yet to claim.\n *\n * What a spawner wants: the child owns its state from its first read, in a\n * directory the spawner manages, so the parent cleaning up its own session\n * cannot pull the file out from under a detached run.\n */\n unclaimed?: boolean;\n },\n): string {\n const filePath = stateFilePath(options.directory);\n persist(filePath, state, options.unclaimed ? UNCLAIMED_OWNER : process.pid);\n options.environment[HARNESS_STATE_POINTER] = filePath;\n projectHarnessEnvironment(state, options.environment);\n // Only prime the cache when this process is the one being described.\n if (!options.unclaimed && options.environment === process.env)\n loaded = { filePath, owned: true, state, mtimeMs: fileMtime(filePath) };\n return filePath;\n}\n\n/**\n * Applies a patch to this process's state.\n *\n * Copy on write: a process holding a file it does not own writes its own copy\n * and repoints itself at it, so a child can never rewrite its parent's session.\n */\nexport function updateHarnessState(\n patch: Partial<HarnessState>,\n environment: NodeJS.ProcessEnv = process.env,\n): HarnessState {\n const current = loadHarnessState(environment);\n const state = { ...current.state, ...patch };\n const filePath = current.owned && current.filePath ? current.filePath : adoptedStateFilePath();\n persist(filePath, state);\n environment[HARNESS_STATE_POINTER] = filePath;\n if (environment === process.env) loaded = { filePath, owned: true, state, mtimeMs: fileMtime(filePath) };\n projectHarnessEnvironment(patch, environment);\n return state;\n}\n\n/** Removes this process's own state file. Safe when there is none. */\nexport function disposeHarnessState(environment: NodeJS.ProcessEnv = process.env): void {\n const current = loaded;\n resetHarnessStore();\n if (!current?.owned || !current.filePath) return;\n fs.rmSync(current.filePath, { force: true });\n delete environment[HARNESS_STATE_POINTER];\n}\n\nexport function harnessRoot(state: Pick<HarnessState, 'root'> = getHarnessState()): string {\n return state.root ?? process.cwd();\n}\n\n/**\n * The repository root, or a hard error.\n *\n * Separate from `requireHarnessPaths` because most callers only need the root,\n * and separate from `harnessRoot` because falling back to `process.cwd()` would\n * quietly operate on whatever directory the session happens to sit in. A caller\n * that asks for the root wants the session's repository or nothing.\n */\nexport function requireHarnessRoot(state: Pick<HarnessState, 'root'> = getHarnessState()): string {\n if (!state.root) throw new Error(`${HARNESS_STATE_KEYS.root} is not set`);\n return state.root;\n}\n\n/** The root and the run's scratch directory, for callers that write to disk. */\nexport function requireHarnessPaths(state: Pick<HarnessState, 'root' | 'temporaryDirectory'> = getHarnessState()): {\n root: string;\n temporaryDirectory: string;\n} {\n const root = requireHarnessRoot(state);\n if (!state.temporaryDirectory) throw new Error(`${HARNESS_STATE_KEYS.temporaryDirectory} is not set`);\n return { root, temporaryDirectory: state.temporaryDirectory };\n}\n"],"mappings":"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"}
1
+ {"version":3,"file":"harnessStore.cjs","names":["fs","readHarnessState","HARNESS_STATE_KEYS","path","os"],"sources":["../../src/adapters/harnessStore.ts"],"sourcesContent":["import fs from 'node:fs';\nimport os from 'node:os';\nimport path from 'node:path';\nimport type { HarnessState } from '../types/config.ts';\nimport { writePrivateAtomicJson } from './atomicJson.ts';\nimport {\n HARNESS_STATE_KEYS,\n type HarnessStateParseReporter,\n projectHarnessEnvironment,\n readHarnessState,\n} from './harnessState.ts';\n\n/**\n * Who owns the harness state, and where it lives.\n *\n * The state used to be the environment: twenty variables that every reader\n * re-parsed and every writer mutated globally. The file is the authority now,\n * and the environment is a projection published for the readers that can only\n * see an environment, which are bash hooks, the shell launchers, packages that\n * do not depend on this one, and any process spawned by any of them.\n *\n * OWNERSHIP IS PER PROCESS, AND THAT IS THE WHOLE DESIGN:\n * Doom Team subagents run detached, in their own process group, from an\n * environment snapshot taken at spawn. A child can outlive its parent. If it\n * shared the parent's file it would corrupt a session it does not own, and if\n * that file sat in the parent's run directory the parent's shutdown sweep would\n * delete it from under a live run. So every process writes a file it owns:\n * `owner.pid` records who, and a process that finds someone else's file copies\n * it before its first write.\n *\n * AVOID:\n * - Treating the file as shared mutable state between processes. Atomic writes\n * prevent torn reads, not lost updates\n * - Reading the environment directly for anything this exposes\n */\n\n/** Points at the state file. The one variable that is not derived. */\nexport const HARNESS_STATE_POINTER = 'DOOMPI_STATE';\n\nconst STATE_FILE_VERSION = 1;\nconst STATE_FILE_NAME = 'harness-state.json';\nconst ADOPTED_DIRECTORY = 'doom-harness';\n/**\n * Written for a process that does not exist yet, so the first one to read it\n * owns it. A spawner cannot know its child's pid, and a child that inherited\n * its parent's file would lose it the moment the parent cleaned up.\n */\nconst UNCLAIMED_OWNER = 0;\n\nexport interface HarnessStateFile {\n version: number;\n owner: { pid: number; startedAt: string };\n state: HarnessState;\n}\n\nexport interface HarnessStateTransactionSnapshot {\n readonly filePath?: string;\n readonly owned: boolean;\n readonly state: HarnessState;\n readonly environment: Readonly<Record<string, string | undefined>>;\n}\n\nexport interface LoadedHarnessState {\n /** Undefined when this process is running off the environment fallback. */\n filePath?: string;\n owned: boolean;\n state: HarnessState;\n}\n\ninterface CachedHarnessState extends LoadedHarnessState {\n /** The file's mtime when it was read, so a rewrite by another copy is noticed. */\n mtimeMs?: number;\n}\n\nlet loaded: CachedHarnessState | undefined;\n\n/** Drops the cached state. For tests, and for a process changing identity. */\nexport function resetHarnessStore(): void {\n loaded = undefined;\n}\n\nfunction fileMtime(filePath: string): number | undefined {\n try {\n return fs.statSync(filePath).mtimeMs;\n } catch {\n return undefined;\n }\n}\n\n/**\n * Whether the cache still describes what the process points at.\n *\n * A session can load more than one copy of this package (a layer package\n * installed under .pi/npm brings its own), and each copy caches on its own.\n * The pointer and the file are shared, so a switch persisted through one copy\n * moves the pointer or rewrites the file, and every other copy must notice\n * rather than answer from memory.\n */\nfunction cacheCurrent(cache: CachedHarnessState, environment: NodeJS.ProcessEnv): boolean {\n const pointer = environment[HARNESS_STATE_POINTER];\n if (cache.filePath !== pointer) return false;\n if (!cache.filePath) return true;\n try {\n return fs.statSync(cache.filePath).mtimeMs === cache.mtimeMs;\n } catch {\n return false;\n }\n}\n\nfunction parseStateFile(source: string, filePath: string): HarnessStateFile {\n const parsed = JSON.parse(source) as Partial<HarnessStateFile>;\n if (parsed.version !== STATE_FILE_VERSION) {\n throw new Error(\n `Harness state at ${filePath} has version ${String(parsed.version)}, expected ${STATE_FILE_VERSION}`,\n );\n }\n if (typeof parsed.state !== 'object' || parsed.state === null) {\n throw new Error(`Harness state at ${filePath} has no state object`);\n }\n return {\n version: STATE_FILE_VERSION,\n owner: { pid: parsed.owner?.pid ?? -1, startedAt: parsed.owner?.startedAt ?? '' },\n state: parsed.state as HarnessState,\n };\n}\n\n/**\n * Reads the state for this process, once.\n *\n * A missing pointer means nobody wrote a file for this process, so the\n * environment is all there is: a nested run, a third-party spawn, or a caller\n * older than the store. A pointer that cannot be read is reported and then\n * treated the same way, because a session that starts degraded beats a session\n * that does not start at all.\n */\nexport function loadHarnessState(\n environment: NodeJS.ProcessEnv = process.env,\n report?: HarnessStateParseReporter,\n): LoadedHarnessState {\n // The cache describes this process. Asking about another environment is a\n // question about another process, so it reads through rather than answering\n // from what this one happens to hold.\n const cacheable = environment === process.env;\n if (cacheable && loaded && cacheCurrent(loaded, environment)) return loaded;\n\n const filePath = environment[HARNESS_STATE_POINTER];\n let result: CachedHarnessState | undefined;\n if (filePath && fs.existsSync(filePath)) {\n try {\n const file = parseStateFile(fs.readFileSync(filePath, 'utf8'), filePath);\n const owned = file.owner.pid === process.pid || file.owner.pid === UNCLAIMED_OWNER;\n result = { filePath, owned, state: file.state, mtimeMs: fileMtime(filePath) };\n } catch (error) {\n report?.(HARNESS_STATE_POINTER, error);\n }\n }\n result ??= { owned: false, state: readHarnessState(environment, report) };\n if (cacheable) loaded = result;\n return result;\n}\n\n/** Captures the owned state pointer and every projected harness variable. */\nexport function snapshotHarnessState(environment: NodeJS.ProcessEnv = process.env): HarnessStateTransactionSnapshot {\n const loadedState = loadHarnessState(environment);\n const environmentSnapshot: Record<string, string | undefined> = {\n [HARNESS_STATE_POINTER]: environment[HARNESS_STATE_POINTER],\n };\n for (const key of Object.values(HARNESS_STATE_KEYS)) environmentSnapshot[key] = environment[key];\n return {\n filePath: loadedState.filePath,\n owned: loadedState.owned,\n state: structuredClone(loadedState.state),\n environment: environmentSnapshot,\n };\n}\n\n/** Restores a snapshot only while the current process still owns its state pointer. */\nexport function restoreHarnessStateSnapshot(\n snapshot: HarnessStateTransactionSnapshot,\n environment: NodeJS.ProcessEnv = process.env,\n): void {\n const current = loadHarnessState(environment);\n if (snapshot.filePath && snapshot.owned) {\n if (!current.owned || current.filePath !== snapshot.filePath) {\n throw new Error('Harness state ownership changed; refusing to restore an older snapshot.');\n }\n persist(snapshot.filePath, snapshot.state);\n } else if (!snapshot.filePath) {\n if (current.filePath && !current.owned) {\n throw new Error('Harness state is no longer owned by this process; refusing to restore an older snapshot.');\n }\n if (current.filePath && current.owned) fs.rmSync(current.filePath, { force: true });\n resetHarnessStore();\n } else if (current.filePath !== snapshot.filePath) {\n throw new Error('Harness state pointer changed; refusing to restore an older snapshot.');\n }\n for (const [key, value] of Object.entries(snapshot.environment)) {\n if (value === undefined) delete environment[key];\n else environment[key] = value;\n }\n if (environment === process.env) {\n loaded = snapshot.filePath\n ? {\n filePath: snapshot.filePath,\n owned: snapshot.owned,\n state: snapshot.state,\n mtimeMs: fileMtime(snapshot.filePath),\n }\n : undefined;\n }\n}\n\nexport function getHarnessState(report?: HarnessStateParseReporter): HarnessState {\n return loadHarnessState(process.env, report).state;\n}\n\nfunction stateFilePath(directory: string): string {\n return path.join(directory, STATE_FILE_NAME);\n}\n\n/** Where a process writes state when it was not given a file of its own. */\nfunction adoptedStateFilePath(): string {\n return path.join(os.tmpdir(), ADOPTED_DIRECTORY, `${String(process.pid)}.json`);\n}\n\nfunction persist(filePath: string, state: HarnessState, ownerPid = process.pid): void {\n writePrivateAtomicJson(filePath, {\n version: STATE_FILE_VERSION,\n owner: { pid: ownerPid, startedAt: new Date().toISOString() },\n state,\n } satisfies HarnessStateFile);\n}\n\n/**\n * Starts a session: writes the file and publishes the derived environment.\n *\n * The environment is a parameter because the caller is usually describing a\n * process other than itself. The launcher builds the environment for the Pi it\n * is about to spawn, and Doom Team builds the snapshot for a detached child, so\n * neither should touch its own `process.env` to do it.\n */\nexport function createHarnessSession(\n state: HarnessState,\n options: {\n directory: string;\n environment: NodeJS.ProcessEnv;\n /**\n * Leave the file for a process that does not exist yet to claim.\n *\n * What a spawner wants: the child owns its state from its first read, in a\n * directory the spawner manages, so the parent cleaning up its own session\n * cannot pull the file out from under a detached run.\n */\n unclaimed?: boolean;\n },\n): string {\n const filePath = stateFilePath(options.directory);\n persist(filePath, state, options.unclaimed ? UNCLAIMED_OWNER : process.pid);\n options.environment[HARNESS_STATE_POINTER] = filePath;\n projectHarnessEnvironment(state, options.environment);\n // Only prime the cache when this process is the one being described.\n if (!options.unclaimed && options.environment === process.env)\n loaded = { filePath, owned: true, state, mtimeMs: fileMtime(filePath) };\n return filePath;\n}\n\n/**\n * Applies a patch to this process's state.\n *\n * Copy on write: a process holding a file it does not own writes its own copy\n * and repoints itself at it, so a child can never rewrite its parent's session.\n */\nexport function updateHarnessState(\n patch: Partial<HarnessState>,\n environment: NodeJS.ProcessEnv = process.env,\n): HarnessState {\n const current = loadHarnessState(environment);\n const state = { ...current.state, ...patch };\n const filePath = current.owned && current.filePath ? current.filePath : adoptedStateFilePath();\n persist(filePath, state);\n environment[HARNESS_STATE_POINTER] = filePath;\n if (environment === process.env) loaded = { filePath, owned: true, state, mtimeMs: fileMtime(filePath) };\n projectHarnessEnvironment(patch, environment);\n return state;\n}\n\n/** Removes this process's own state file. Safe when there is none. */\nexport function disposeHarnessState(environment: NodeJS.ProcessEnv = process.env): void {\n const current = loaded;\n resetHarnessStore();\n if (!current?.owned || !current.filePath) return;\n fs.rmSync(current.filePath, { force: true });\n delete environment[HARNESS_STATE_POINTER];\n}\n\nexport function harnessRoot(state: Pick<HarnessState, 'root'> = getHarnessState()): string {\n return state.root ?? process.cwd();\n}\n\n/**\n * The repository root, or a hard error.\n *\n * Separate from `requireHarnessPaths` because most callers only need the root,\n * and separate from `harnessRoot` because falling back to `process.cwd()` would\n * quietly operate on whatever directory the session happens to sit in. A caller\n * that asks for the root wants the session's repository or nothing.\n */\nexport function requireHarnessRoot(state: Pick<HarnessState, 'root'> = getHarnessState()): string {\n if (!state.root) throw new Error(`${HARNESS_STATE_KEYS.root} is not set`);\n return state.root;\n}\n\n/** The root and the run's scratch directory, for callers that write to disk. */\nexport function requireHarnessPaths(state: Pick<HarnessState, 'root' | 'temporaryDirectory'> = getHarnessState()): {\n root: string;\n temporaryDirectory: string;\n} {\n const root = requireHarnessRoot(state);\n if (!state.temporaryDirectory) throw new Error(`${HARNESS_STATE_KEYS.temporaryDirectory} is not set`);\n return { root, temporaryDirectory: state.temporaryDirectory };\n}\n"],"mappings":"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"}
@@ -25,8 +25,8 @@ import { HarnessStateParseReporter } from "./harnessState.cjs";
25
25
  * - Reading the environment directly for anything this exposes
26
26
  */
27
27
  /** Points at the state file. The one variable that is not derived. */
28
- declare const HARNESS_STATE_POINTER = "DOOMPI_STATE";
29
- interface HarnessStateFile {
28
+ export declare const HARNESS_STATE_POINTER = "DOOMPI_STATE";
29
+ export interface HarnessStateFile {
30
30
  version: number;
31
31
  owner: {
32
32
  pid: number;
@@ -34,20 +34,20 @@ interface HarnessStateFile {
34
34
  };
35
35
  state: HarnessState;
36
36
  }
37
- interface HarnessStateTransactionSnapshot {
37
+ export interface HarnessStateTransactionSnapshot {
38
38
  readonly filePath?: string;
39
39
  readonly owned: boolean;
40
40
  readonly state: HarnessState;
41
41
  readonly environment: Readonly<Record<string, string | undefined>>;
42
42
  }
43
- interface LoadedHarnessState {
43
+ export interface LoadedHarnessState {
44
44
  /** Undefined when this process is running off the environment fallback. */
45
45
  filePath?: string;
46
46
  owned: boolean;
47
47
  state: HarnessState;
48
48
  }
49
49
  /** Drops the cached state. For tests, and for a process changing identity. */
50
- declare function resetHarnessStore(): void;
50
+ export declare function resetHarnessStore(): void;
51
51
  /**
52
52
  * Reads the state for this process, once.
53
53
  *
@@ -57,12 +57,12 @@ declare function resetHarnessStore(): void;
57
57
  * treated the same way, because a session that starts degraded beats a session
58
58
  * that does not start at all.
59
59
  */
60
- declare function loadHarnessState(environment?: NodeJS.ProcessEnv, report?: HarnessStateParseReporter): LoadedHarnessState;
60
+ export declare function loadHarnessState(environment?: NodeJS.ProcessEnv, report?: HarnessStateParseReporter): LoadedHarnessState;
61
61
  /** Captures the owned state pointer and every projected harness variable. */
62
- declare function snapshotHarnessState(environment?: NodeJS.ProcessEnv): HarnessStateTransactionSnapshot;
62
+ export declare function snapshotHarnessState(environment?: NodeJS.ProcessEnv): HarnessStateTransactionSnapshot;
63
63
  /** Restores a snapshot only while the current process still owns its state pointer. */
64
- declare function restoreHarnessStateSnapshot(snapshot: HarnessStateTransactionSnapshot, environment?: NodeJS.ProcessEnv): void;
65
- declare function getHarnessState(report?: HarnessStateParseReporter): HarnessState;
64
+ export declare function restoreHarnessStateSnapshot(snapshot: HarnessStateTransactionSnapshot, environment?: NodeJS.ProcessEnv): void;
65
+ export declare function getHarnessState(report?: HarnessStateParseReporter): HarnessState;
66
66
  /**
67
67
  * Starts a session: writes the file and publishes the derived environment.
68
68
  *
@@ -71,7 +71,7 @@ declare function getHarnessState(report?: HarnessStateParseReporter): HarnessSta
71
71
  * is about to spawn, and Doom Team builds the snapshot for a detached child, so
72
72
  * neither should touch its own `process.env` to do it.
73
73
  */
74
- declare function createHarnessSession(state: HarnessState, options: {
74
+ export declare function createHarnessSession(state: HarnessState, options: {
75
75
  directory: string;
76
76
  environment: NodeJS.ProcessEnv;
77
77
  /**
@@ -89,10 +89,10 @@ declare function createHarnessSession(state: HarnessState, options: {
89
89
  * Copy on write: a process holding a file it does not own writes its own copy
90
90
  * and repoints itself at it, so a child can never rewrite its parent's session.
91
91
  */
92
- declare function updateHarnessState(patch: Partial<HarnessState>, environment?: NodeJS.ProcessEnv): HarnessState;
92
+ export declare function updateHarnessState(patch: Partial<HarnessState>, environment?: NodeJS.ProcessEnv): HarnessState;
93
93
  /** Removes this process's own state file. Safe when there is none. */
94
- declare function disposeHarnessState(environment?: NodeJS.ProcessEnv): void;
95
- declare function harnessRoot(state?: Pick<HarnessState, 'root'>): string;
94
+ export declare function disposeHarnessState(environment?: NodeJS.ProcessEnv): void;
95
+ export declare function harnessRoot(state?: Pick<HarnessState, 'root'>): string;
96
96
  /**
97
97
  * The repository root, or a hard error.
98
98
  *
@@ -101,12 +101,11 @@ declare function harnessRoot(state?: Pick<HarnessState, 'root'>): string;
101
101
  * quietly operate on whatever directory the session happens to sit in. A caller
102
102
  * that asks for the root wants the session's repository or nothing.
103
103
  */
104
- declare function requireHarnessRoot(state?: Pick<HarnessState, 'root'>): string;
104
+ export declare function requireHarnessRoot(state?: Pick<HarnessState, 'root'>): string;
105
105
  /** The root and the run's scratch directory, for callers that write to disk. */
106
- declare function requireHarnessPaths(state?: Pick<HarnessState, 'root' | 'temporaryDirectory'>): {
106
+ export declare function requireHarnessPaths(state?: Pick<HarnessState, 'root' | 'temporaryDirectory'>): {
107
107
  root: string;
108
108
  temporaryDirectory: string;
109
109
  };
110
110
  //#endregion
111
- export { HARNESS_STATE_POINTER, HarnessStateFile, HarnessStateTransactionSnapshot, LoadedHarnessState, createHarnessSession, disposeHarnessState, getHarnessState, harnessRoot, loadHarnessState, requireHarnessPaths, requireHarnessRoot, resetHarnessStore, restoreHarnessStateSnapshot, snapshotHarnessState, updateHarnessState };
112
111
  //# sourceMappingURL=harnessStore.d.cts.map