@ankhorage/orchestrator 0.1.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 (67) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +139 -0
  3. package/dist/actions/jsonPath.d.ts +5 -0
  4. package/dist/actions/jsonPath.d.ts.map +1 -0
  5. package/dist/actions/jsonPath.js +148 -0
  6. package/dist/actions/jsonPath.js.map +1 -0
  7. package/dist/actions/types.d.ts +38 -0
  8. package/dist/actions/types.d.ts.map +1 -0
  9. package/dist/actions/types.js +2 -0
  10. package/dist/actions/types.js.map +1 -0
  11. package/dist/fs/exec.d.ts +9 -0
  12. package/dist/fs/exec.d.ts.map +1 -0
  13. package/dist/fs/exec.js +26 -0
  14. package/dist/fs/exec.js.map +1 -0
  15. package/dist/fs/fileSystem.d.ts +12 -0
  16. package/dist/fs/fileSystem.d.ts.map +1 -0
  17. package/dist/fs/fileSystem.js +51 -0
  18. package/dist/fs/fileSystem.js.map +1 -0
  19. package/dist/fs/patchTextBlock.d.ts +19 -0
  20. package/dist/fs/patchTextBlock.d.ts.map +1 -0
  21. package/dist/fs/patchTextBlock.js +46 -0
  22. package/dist/fs/patchTextBlock.js.map +1 -0
  23. package/dist/fs/paths.d.ts +2 -0
  24. package/dist/fs/paths.d.ts.map +1 -0
  25. package/dist/fs/paths.js +18 -0
  26. package/dist/fs/paths.js.map +1 -0
  27. package/dist/fs/types.d.ts +24 -0
  28. package/dist/fs/types.d.ts.map +1 -0
  29. package/dist/fs/types.js +2 -0
  30. package/dist/fs/types.js.map +1 -0
  31. package/dist/index.d.ts +7 -0
  32. package/dist/index.d.ts.map +1 -0
  33. package/dist/index.js +4 -0
  34. package/dist/index.js.map +1 -0
  35. package/dist/ledger/helpers.d.ts +3 -0
  36. package/dist/ledger/helpers.d.ts.map +1 -0
  37. package/dist/ledger/helpers.js +5 -0
  38. package/dist/ledger/helpers.js.map +1 -0
  39. package/dist/ledger/types.d.ts +42 -0
  40. package/dist/ledger/types.d.ts.map +1 -0
  41. package/dist/ledger/types.js +2 -0
  42. package/dist/ledger/types.js.map +1 -0
  43. package/dist/module/defineModule.d.ts +3 -0
  44. package/dist/module/defineModule.d.ts.map +1 -0
  45. package/dist/module/defineModule.js +4 -0
  46. package/dist/module/defineModule.js.map +1 -0
  47. package/dist/module/types.d.ts +13 -0
  48. package/dist/module/types.d.ts.map +1 -0
  49. package/dist/module/types.js +2 -0
  50. package/dist/module/types.js.map +1 -0
  51. package/dist/orchestrator/actionExecutor.d.ts +11 -0
  52. package/dist/orchestrator/actionExecutor.d.ts.map +1 -0
  53. package/dist/orchestrator/actionExecutor.js +203 -0
  54. package/dist/orchestrator/actionExecutor.js.map +1 -0
  55. package/dist/orchestrator/createOrchestrator.d.ts +22 -0
  56. package/dist/orchestrator/createOrchestrator.d.ts.map +1 -0
  57. package/dist/orchestrator/createOrchestrator.js +154 -0
  58. package/dist/orchestrator/createOrchestrator.js.map +1 -0
  59. package/dist/orchestrator/dependencyGraph.d.ts +4 -0
  60. package/dist/orchestrator/dependencyGraph.d.ts.map +1 -0
  61. package/dist/orchestrator/dependencyGraph.js +44 -0
  62. package/dist/orchestrator/dependencyGraph.js.map +1 -0
  63. package/dist/orchestrator/uninstall.d.ts +9 -0
  64. package/dist/orchestrator/uninstall.d.ts.map +1 -0
  65. package/dist/orchestrator/uninstall.js +65 -0
  66. package/dist/orchestrator/uninstall.js.map +1 -0
  67. package/package.json +41 -0
@@ -0,0 +1,7 @@
1
+ export type { EnsurePackagesAction, JsonSetAction, ModuleAction, ModuleDependency, PatchTextBlockAction, WriteFileInstruction, WriteFilesAction, } from "./actions/types";
2
+ export { LEDGER_DIR, ledgerPath } from "./ledger/helpers";
3
+ export type { AppliedOperation, ModuleLedger } from "./ledger/types";
4
+ export { defineModule } from "./module/defineModule";
5
+ export type { ModuleContext, ModuleDefinition } from "./module/types";
6
+ export { createOrchestrator, type CreateOrchestratorOptions, type InstallModuleOptions, type InstallModuleResult, type Orchestrator, type RemoveModuleResult, } from "./orchestrator/createOrchestrator";
7
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,YAAY,EACV,oBAAoB,EACpB,aAAa,EACb,YAAY,EACZ,gBAAgB,EAChB,oBAAoB,EACpB,oBAAoB,EACpB,gBAAgB,GACjB,MAAM,iBAAiB,CAAC;AACzB,OAAO,EAAE,UAAU,EAAE,UAAU,EAAE,MAAM,kBAAkB,CAAC;AAC1D,YAAY,EAAE,gBAAgB,EAAE,YAAY,EAAE,MAAM,gBAAgB,CAAC;AACrE,OAAO,EAAE,YAAY,EAAE,MAAM,uBAAuB,CAAC;AACrD,YAAY,EAAE,aAAa,EAAE,gBAAgB,EAAE,MAAM,gBAAgB,CAAC;AACtE,OAAO,EACL,kBAAkB,EAClB,KAAK,yBAAyB,EAC9B,KAAK,oBAAoB,EACzB,KAAK,mBAAmB,EACxB,KAAK,YAAY,EACjB,KAAK,kBAAkB,GACxB,MAAM,mCAAmC,CAAC"}
package/dist/index.js ADDED
@@ -0,0 +1,4 @@
1
+ export { LEDGER_DIR, ledgerPath } from "./ledger/helpers";
2
+ export { defineModule } from "./module/defineModule";
3
+ export { createOrchestrator, } from "./orchestrator/createOrchestrator";
4
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AASA,OAAO,EAAE,UAAU,EAAE,UAAU,EAAE,MAAM,kBAAkB,CAAC;AAE1D,OAAO,EAAE,YAAY,EAAE,MAAM,uBAAuB,CAAC;AAErD,OAAO,EACL,kBAAkB,GAMnB,MAAM,mCAAmC,CAAC"}
@@ -0,0 +1,3 @@
1
+ export declare const LEDGER_DIR = ".ankh/ledger";
2
+ export declare function ledgerPath(moduleId: string): string;
3
+ //# sourceMappingURL=helpers.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"helpers.d.ts","sourceRoot":"","sources":["../../src/ledger/helpers.ts"],"names":[],"mappings":"AAAA,eAAO,MAAM,UAAU,iBAAiB,CAAC;AAEzC,wBAAgB,UAAU,CAAC,QAAQ,EAAE,MAAM,GAAG,MAAM,CAEnD"}
@@ -0,0 +1,5 @@
1
+ export const LEDGER_DIR = ".ankh/ledger";
2
+ export function ledgerPath(moduleId) {
3
+ return `${LEDGER_DIR}/${moduleId}.json`;
4
+ }
5
+ //# sourceMappingURL=helpers.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"helpers.js","sourceRoot":"","sources":["../../src/ledger/helpers.ts"],"names":[],"mappings":"AAAA,MAAM,CAAC,MAAM,UAAU,GAAG,cAAc,CAAC;AAEzC,MAAM,UAAU,UAAU,CAAC,QAAgB;IACzC,OAAO,GAAG,UAAU,IAAI,QAAQ,OAAO,CAAC;AAC1C,CAAC"}
@@ -0,0 +1,42 @@
1
+ import type { ModuleAction } from "../actions/types";
2
+ export interface PackageAdditionOperation {
3
+ kind: "pkg-add";
4
+ name: string;
5
+ version?: string;
6
+ dev?: boolean;
7
+ }
8
+ export interface FileWriteOperation {
9
+ kind: "file-write";
10
+ path: string;
11
+ prevContent: string | null;
12
+ }
13
+ export interface TextBlockInsertOperation {
14
+ kind: "text-block-insert";
15
+ path: string;
16
+ blockId: string;
17
+ created: boolean;
18
+ }
19
+ export interface JsonSetOperation {
20
+ kind: "json-set";
21
+ path: string;
22
+ jsonPath: string;
23
+ prevExists: boolean;
24
+ prev: unknown;
25
+ next: unknown;
26
+ }
27
+ export interface JsonFileSnapshotOperation {
28
+ kind: "json-file-snapshot";
29
+ path: string;
30
+ prevContent: string | null;
31
+ }
32
+ export type AppliedOperation = PackageAdditionOperation | FileWriteOperation | TextBlockInsertOperation | JsonSetOperation | JsonFileSnapshotOperation;
33
+ export interface ModuleLedger {
34
+ moduleId: string;
35
+ moduleVersion?: string;
36
+ installedAt: string;
37
+ config: unknown;
38
+ dependencies: string[];
39
+ actions: ModuleAction[];
40
+ applied: AppliedOperation[];
41
+ }
42
+ //# sourceMappingURL=types.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../../src/ledger/types.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,kBAAkB,CAAC;AAErD,MAAM,WAAW,wBAAwB;IACvC,IAAI,EAAE,SAAS,CAAC;IAChB,IAAI,EAAE,MAAM,CAAC;IACb,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,GAAG,CAAC,EAAE,OAAO,CAAC;CACf;AAED,MAAM,WAAW,kBAAkB;IACjC,IAAI,EAAE,YAAY,CAAC;IACnB,IAAI,EAAE,MAAM,CAAC;IACb,WAAW,EAAE,MAAM,GAAG,IAAI,CAAC;CAC5B;AAED,MAAM,WAAW,wBAAwB;IACvC,IAAI,EAAE,mBAAmB,CAAC;IAC1B,IAAI,EAAE,MAAM,CAAC;IACb,OAAO,EAAE,MAAM,CAAC;IAChB,OAAO,EAAE,OAAO,CAAC;CAClB;AAED,MAAM,WAAW,gBAAgB;IAC/B,IAAI,EAAE,UAAU,CAAC;IACjB,IAAI,EAAE,MAAM,CAAC;IACb,QAAQ,EAAE,MAAM,CAAC;IACjB,UAAU,EAAE,OAAO,CAAC;IACpB,IAAI,EAAE,OAAO,CAAC;IACd,IAAI,EAAE,OAAO,CAAC;CACf;AAED,MAAM,WAAW,yBAAyB;IACxC,IAAI,EAAE,oBAAoB,CAAC;IAC3B,IAAI,EAAE,MAAM,CAAC;IACb,WAAW,EAAE,MAAM,GAAG,IAAI,CAAC;CAC5B;AAED,MAAM,MAAM,gBAAgB,GACxB,wBAAwB,GACxB,kBAAkB,GAClB,wBAAwB,GACxB,gBAAgB,GAChB,yBAAyB,CAAC;AAE9B,MAAM,WAAW,YAAY;IAC3B,QAAQ,EAAE,MAAM,CAAC;IACjB,aAAa,CAAC,EAAE,MAAM,CAAC;IACvB,WAAW,EAAE,MAAM,CAAC;IACpB,MAAM,EAAE,OAAO,CAAC;IAChB,YAAY,EAAE,MAAM,EAAE,CAAC;IACvB,OAAO,EAAE,YAAY,EAAE,CAAC;IACxB,OAAO,EAAE,gBAAgB,EAAE,CAAC;CAC7B"}
@@ -0,0 +1,2 @@
1
+ export {};
2
+ //# sourceMappingURL=types.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"types.js","sourceRoot":"","sources":["../../src/ledger/types.ts"],"names":[],"mappings":""}
@@ -0,0 +1,3 @@
1
+ import type { ModuleDefinition } from "./types";
2
+ export declare function defineModule<TConfig = unknown>(moduleDefinition: ModuleDefinition<TConfig>): ModuleDefinition<TConfig>;
3
+ //# sourceMappingURL=defineModule.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"defineModule.d.ts","sourceRoot":"","sources":["../../src/module/defineModule.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,gBAAgB,EAAE,MAAM,SAAS,CAAC;AAEhD,wBAAgB,YAAY,CAAC,OAAO,GAAG,OAAO,EAC5C,gBAAgB,EAAE,gBAAgB,CAAC,OAAO,CAAC,GAC1C,gBAAgB,CAAC,OAAO,CAAC,CAE3B"}
@@ -0,0 +1,4 @@
1
+ export function defineModule(moduleDefinition) {
2
+ return moduleDefinition;
3
+ }
4
+ //# sourceMappingURL=defineModule.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"defineModule.js","sourceRoot":"","sources":["../../src/module/defineModule.ts"],"names":[],"mappings":"AAEA,MAAM,UAAU,YAAY,CAC1B,gBAA2C;IAE3C,OAAO,gBAAgB,CAAC;AAC1B,CAAC"}
@@ -0,0 +1,13 @@
1
+ import type { ModuleAction } from "../actions/types";
2
+ export interface ModuleContext<TConfig = unknown> {
3
+ projectRoot: string;
4
+ moduleId: string;
5
+ config: TConfig;
6
+ }
7
+ export interface ModuleDefinition<TConfig = unknown> {
8
+ id: string;
9
+ version?: string;
10
+ dependencies?: string[];
11
+ plan(context: ModuleContext<TConfig>): Promise<ModuleAction[]> | ModuleAction[];
12
+ }
13
+ //# sourceMappingURL=types.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../../src/module/types.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,kBAAkB,CAAC;AAErD,MAAM,WAAW,aAAa,CAAC,OAAO,GAAG,OAAO;IAC9C,WAAW,EAAE,MAAM,CAAC;IACpB,QAAQ,EAAE,MAAM,CAAC;IACjB,MAAM,EAAE,OAAO,CAAC;CACjB;AAED,MAAM,WAAW,gBAAgB,CAAC,OAAO,GAAG,OAAO;IACjD,EAAE,EAAE,MAAM,CAAC;IACX,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,YAAY,CAAC,EAAE,MAAM,EAAE,CAAC;IACxB,IAAI,CACF,OAAO,EAAE,aAAa,CAAC,OAAO,CAAC,GAC9B,OAAO,CAAC,YAAY,EAAE,CAAC,GAAG,YAAY,EAAE,CAAC;CAC7C"}
@@ -0,0 +1,2 @@
1
+ export {};
2
+ //# sourceMappingURL=types.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"types.js","sourceRoot":"","sources":["../../src/module/types.ts"],"names":[],"mappings":""}
@@ -0,0 +1,11 @@
1
+ import type { ModuleAction } from "../actions/types";
2
+ import type { CommandExecutor, FileSystem } from "../fs/types";
3
+ import type { AppliedOperation } from "../ledger/types";
4
+ export declare function executeModuleActions(args: {
5
+ projectRoot: string;
6
+ actions: ModuleAction[];
7
+ fileSystem: FileSystem;
8
+ commandExecutor: CommandExecutor;
9
+ moduleId: string;
10
+ }): Promise<AppliedOperation[]>;
11
+ //# sourceMappingURL=actionExecutor.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"actionExecutor.d.ts","sourceRoot":"","sources":["../../src/orchestrator/actionExecutor.ts"],"names":[],"mappings":"AAGA,OAAO,KAAK,EAAiB,YAAY,EAAE,MAAM,kBAAkB,CAAC;AAGpE,OAAO,KAAK,EAAE,eAAe,EAAE,UAAU,EAAE,MAAM,aAAa,CAAC;AAC/D,OAAO,KAAK,EAAE,gBAAgB,EAAE,MAAM,iBAAiB,CAAC;AAIxD,wBAAsB,oBAAoB,CAAC,IAAI,EAAE;IAC/C,WAAW,EAAE,MAAM,CAAC;IACpB,OAAO,EAAE,YAAY,EAAE,CAAC;IACxB,UAAU,EAAE,UAAU,CAAC;IACvB,eAAe,EAAE,eAAe,CAAC;IACjC,QAAQ,EAAE,MAAM,CAAC;CAClB,GAAG,OAAO,CAAC,gBAAgB,EAAE,CAAC,CAgI9B"}
@@ -0,0 +1,203 @@
1
+ import path from "node:path";
2
+ import { deepEqual, getAtPath, hasPath, setAtPath } from "../actions/jsonPath";
3
+ import { insertTextBlock } from "../fs/patchTextBlock";
4
+ import { resolveProjectPath } from "../fs/paths";
5
+ export async function executeModuleActions(args) {
6
+ const { projectRoot, actions, fileSystem, commandExecutor, moduleId } = args;
7
+ const applied = [];
8
+ const jsonSnapshots = new Set();
9
+ const jsonBuffer = new Map();
10
+ const flushJson = async () => {
11
+ for (const [relativePath, value] of jsonBuffer.entries()) {
12
+ const absolutePath = resolveProjectPath(projectRoot, relativePath);
13
+ await fileSystem.writeJson(absolutePath, value.doc);
14
+ }
15
+ jsonBuffer.clear();
16
+ };
17
+ try {
18
+ for (const action of actions) {
19
+ switch (action.type) {
20
+ case "write-files": {
21
+ await flushJson();
22
+ for (const file of action.files) {
23
+ const absolutePath = resolveProjectPath(projectRoot, file.path);
24
+ const prevContent = await fileSystem.readText(absolutePath);
25
+ const exists = prevContent !== null;
26
+ if (exists && !file.overwrite) {
27
+ continue;
28
+ }
29
+ await fileSystem.ensureDir(path.dirname(absolutePath));
30
+ await fileSystem.writeText(absolutePath, file.content);
31
+ applied.push({
32
+ kind: "file-write",
33
+ path: file.path,
34
+ prevContent,
35
+ });
36
+ }
37
+ break;
38
+ }
39
+ case "patch-text-block": {
40
+ await flushJson();
41
+ const absolutePath = resolveProjectPath(projectRoot, action.path);
42
+ const existed = await fileSystem.exists(absolutePath);
43
+ await insertTextBlock({
44
+ fileSystem,
45
+ filePath: absolutePath,
46
+ blockId: action.blockId,
47
+ content: action.content,
48
+ anchor: action.anchor,
49
+ });
50
+ applied.push({
51
+ kind: "text-block-insert",
52
+ path: action.path,
53
+ blockId: action.blockId,
54
+ created: !existed,
55
+ });
56
+ break;
57
+ }
58
+ case "json-set": {
59
+ await stageJsonSet({
60
+ action,
61
+ projectRoot,
62
+ fileSystem,
63
+ jsonBuffer,
64
+ jsonSnapshots,
65
+ applied,
66
+ });
67
+ break;
68
+ }
69
+ case "ensure-packages": {
70
+ await flushJson();
71
+ for (const dependency of action.add) {
72
+ const args = ["add"];
73
+ if (dependency.dev) {
74
+ args.push("-d");
75
+ }
76
+ args.push(`${dependency.name}${dependency.version ? `@${dependency.version}` : ""}`);
77
+ const result = await commandExecutor.exec(projectRoot, "bun", args);
78
+ if (result.code !== 0) {
79
+ throw new Error(`Package install failed for ${dependency.name} (${moduleId}): ${result.stderr || result.stdout}`);
80
+ }
81
+ applied.push({
82
+ kind: "pkg-add",
83
+ name: dependency.name,
84
+ version: dependency.version,
85
+ dev: dependency.dev,
86
+ });
87
+ }
88
+ break;
89
+ }
90
+ default: {
91
+ const exhaustive = action;
92
+ return exhaustive;
93
+ }
94
+ }
95
+ }
96
+ await flushJson();
97
+ return applied;
98
+ }
99
+ catch (error) {
100
+ await flushJson();
101
+ await rollbackAppliedOperations({
102
+ projectRoot,
103
+ applied,
104
+ fileSystem,
105
+ commandExecutor,
106
+ moduleId,
107
+ });
108
+ throw error;
109
+ }
110
+ }
111
+ async function rollbackAppliedOperations(args) {
112
+ const { projectRoot, applied, fileSystem, commandExecutor, moduleId } = args;
113
+ for (const operation of [...applied].reverse()) {
114
+ switch (operation.kind) {
115
+ case "file-write": {
116
+ if (operation.prevContent === null) {
117
+ await fileSystem.remove(resolveProjectPath(projectRoot, operation.path));
118
+ }
119
+ else {
120
+ await fileSystem.writeText(resolveProjectPath(projectRoot, operation.path), operation.prevContent);
121
+ }
122
+ break;
123
+ }
124
+ case "text-block-insert": {
125
+ if (operation.created) {
126
+ await fileSystem.remove(resolveProjectPath(projectRoot, operation.path));
127
+ }
128
+ else {
129
+ const absolutePath = resolveProjectPath(projectRoot, operation.path);
130
+ const { removeTextBlock } = await import("../fs/patchTextBlock");
131
+ await removeTextBlock({
132
+ fileSystem,
133
+ filePath: absolutePath,
134
+ blockId: operation.blockId,
135
+ });
136
+ }
137
+ break;
138
+ }
139
+ case "pkg-add": {
140
+ const result = await commandExecutor.exec(projectRoot, "bun", [
141
+ "remove",
142
+ operation.name,
143
+ ]);
144
+ if (result.code !== 0) {
145
+ throw new Error(`Package uninstall failed for ${operation.name} (${moduleId}): ${result.stderr || result.stdout}`);
146
+ }
147
+ break;
148
+ }
149
+ case "json-file-snapshot": {
150
+ const absolutePath = resolveProjectPath(projectRoot, operation.path);
151
+ if (operation.prevContent === null) {
152
+ await fileSystem.remove(absolutePath);
153
+ }
154
+ else {
155
+ await fileSystem.writeText(absolutePath, operation.prevContent);
156
+ }
157
+ break;
158
+ }
159
+ case "json-set": {
160
+ break;
161
+ }
162
+ default: {
163
+ const exhaustive = operation;
164
+ return exhaustive;
165
+ }
166
+ }
167
+ }
168
+ }
169
+ async function stageJsonSet(args) {
170
+ const { action, projectRoot, fileSystem, jsonBuffer, jsonSnapshots, applied, } = args;
171
+ const absolutePath = resolveProjectPath(projectRoot, action.path);
172
+ if (!jsonSnapshots.has(action.path)) {
173
+ const prevContent = await fileSystem.readText(absolutePath);
174
+ applied.push({
175
+ kind: "json-file-snapshot",
176
+ path: action.path,
177
+ prevContent,
178
+ });
179
+ jsonSnapshots.add(action.path);
180
+ }
181
+ let buffer = jsonBuffer.get(action.path);
182
+ if (!buffer) {
183
+ const doc = (await fileSystem.readJson(absolutePath)) ?? {};
184
+ buffer = { doc };
185
+ jsonBuffer.set(action.path, buffer);
186
+ }
187
+ const current = getAtPath(buffer.doc, action.jsonPath);
188
+ if (action.expected !== undefined && !deepEqual(current, action.expected)) {
189
+ throw new Error(`JSON path mismatch at ${action.path}:${action.jsonPath}. Expected ${JSON.stringify(action.expected)}, found ${JSON.stringify(current)}`);
190
+ }
191
+ const prev = current;
192
+ const prevExists = hasPath(buffer.doc, action.jsonPath);
193
+ buffer.doc = setAtPath(buffer.doc, action.jsonPath, action.value, action.createMissing ?? true);
194
+ applied.push({
195
+ kind: "json-set",
196
+ path: action.path,
197
+ jsonPath: action.jsonPath,
198
+ prevExists,
199
+ prev,
200
+ next: action.value,
201
+ });
202
+ }
203
+ //# sourceMappingURL=actionExecutor.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"actionExecutor.js","sourceRoot":"","sources":["../../src/orchestrator/actionExecutor.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,22 @@
1
+ import type { OrchestratorServices } from "../fs/types";
2
+ import type { ModuleDefinition } from "../module/types";
3
+ export interface CreateOrchestratorOptions {
4
+ modules: ModuleDefinition[];
5
+ projectRoot: string;
6
+ }
7
+ export interface InstallModuleOptions<TConfig = unknown> {
8
+ config: TConfig;
9
+ }
10
+ export interface InstallModuleResult {
11
+ installed: string[];
12
+ }
13
+ export interface RemoveModuleResult {
14
+ removed: string[];
15
+ }
16
+ export interface Orchestrator {
17
+ installModule(moduleId: string, options: InstallModuleOptions): Promise<InstallModuleResult>;
18
+ removeModule(moduleId: string): Promise<RemoveModuleResult>;
19
+ }
20
+ export declare function createOrchestrator(options: CreateOrchestratorOptions): Orchestrator;
21
+ export declare function createOrchestratorWithServices(options: CreateOrchestratorOptions, services: OrchestratorServices): Orchestrator;
22
+ //# sourceMappingURL=createOrchestrator.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"createOrchestrator.d.ts","sourceRoot":"","sources":["../../src/orchestrator/createOrchestrator.ts"],"names":[],"mappings":"AAGA,OAAO,KAAK,EAAE,oBAAoB,EAAE,MAAM,aAAa,CAAC;AAGxD,OAAO,KAAK,EAAE,gBAAgB,EAAE,MAAM,iBAAiB,CAAC;AAKxD,MAAM,WAAW,yBAAyB;IACxC,OAAO,EAAE,gBAAgB,EAAE,CAAC;IAC5B,WAAW,EAAE,MAAM,CAAC;CACrB;AAED,MAAM,WAAW,oBAAoB,CAAC,OAAO,GAAG,OAAO;IACrD,MAAM,EAAE,OAAO,CAAC;CACjB;AAED,MAAM,WAAW,mBAAmB;IAClC,SAAS,EAAE,MAAM,EAAE,CAAC;CACrB;AAED,MAAM,WAAW,kBAAkB;IACjC,OAAO,EAAE,MAAM,EAAE,CAAC;CACnB;AAED,MAAM,WAAW,YAAY;IAC3B,aAAa,CACX,QAAQ,EAAE,MAAM,EAChB,OAAO,EAAE,oBAAoB,GAC5B,OAAO,CAAC,mBAAmB,CAAC,CAAC;IAChC,YAAY,CAAC,QAAQ,EAAE,MAAM,GAAG,OAAO,CAAC,kBAAkB,CAAC,CAAC;CAC7D;AAED,wBAAgB,kBAAkB,CAChC,OAAO,EAAE,yBAAyB,GACjC,YAAY,CAKd;AAED,wBAAgB,8BAA8B,CAC5C,OAAO,EAAE,yBAAyB,EAClC,QAAQ,EAAE,oBAAoB,GAC7B,YAAY,CAgHd"}
@@ -0,0 +1,154 @@
1
+ import { NodeCommandExecutor } from "../fs/exec";
2
+ import { NodeFileSystem } from "../fs/fileSystem";
3
+ import { resolveProjectPath } from "../fs/paths";
4
+ import { ledgerPath } from "../ledger/helpers";
5
+ import { executeModuleActions } from "./actionExecutor";
6
+ import { createModuleRegistry, resolveInstallOrder } from "./dependencyGraph";
7
+ import { uninstallFromLedger } from "./uninstall";
8
+ export function createOrchestrator(options) {
9
+ return createOrchestratorWithServices(options, {
10
+ fileSystem: new NodeFileSystem(),
11
+ commandExecutor: new NodeCommandExecutor(),
12
+ });
13
+ }
14
+ export function createOrchestratorWithServices(options, services) {
15
+ const registry = createModuleRegistry(options.modules);
16
+ const { fileSystem } = services;
17
+ const { commandExecutor } = services;
18
+ const now = services.now ?? (() => new Date().toISOString());
19
+ return {
20
+ async installModule(moduleId, installOptions) {
21
+ const requestedModule = registry.get(moduleId);
22
+ if (!requestedModule) {
23
+ throw new Error(`Unknown module "${moduleId}".`);
24
+ }
25
+ const installOrder = resolveInstallOrder(moduleId, registry);
26
+ const requestedLedger = await readLedger(options.projectRoot, moduleId, fileSystem);
27
+ if (requestedLedger) {
28
+ await removeInstalledModule({
29
+ projectRoot: options.projectRoot,
30
+ moduleId,
31
+ fileSystem,
32
+ commandExecutor,
33
+ skipDependencyCheck: true,
34
+ });
35
+ }
36
+ const installedDuringOperation = [];
37
+ try {
38
+ for (const moduleDefinition of installOrder) {
39
+ const existingLedger = await readLedger(options.projectRoot, moduleDefinition.id, fileSystem);
40
+ if (moduleDefinition.id !== moduleId && existingLedger) {
41
+ continue;
42
+ }
43
+ const config = moduleDefinition.id === moduleId
44
+ ? installOptions.config
45
+ : (existingLedger?.config ?? {});
46
+ const actions = await moduleDefinition.plan({
47
+ projectRoot: options.projectRoot,
48
+ moduleId: moduleDefinition.id,
49
+ config,
50
+ });
51
+ const applied = await executeModuleActions({
52
+ projectRoot: options.projectRoot,
53
+ actions,
54
+ fileSystem,
55
+ commandExecutor,
56
+ moduleId: moduleDefinition.id,
57
+ });
58
+ const ledger = {
59
+ moduleId: moduleDefinition.id,
60
+ moduleVersion: moduleDefinition.version,
61
+ installedAt: now(),
62
+ config,
63
+ dependencies: [
64
+ ...new Set(moduleDefinition.dependencies ?? []),
65
+ ].sort((left, right) => left.localeCompare(right)),
66
+ actions,
67
+ applied,
68
+ };
69
+ await writeLedger(options.projectRoot, ledger, fileSystem);
70
+ installedDuringOperation.push(moduleDefinition.id);
71
+ }
72
+ return {
73
+ installed: installedDuringOperation,
74
+ };
75
+ }
76
+ catch (error) {
77
+ for (const installedModuleId of [
78
+ ...installedDuringOperation,
79
+ ].reverse()) {
80
+ await removeInstalledModule({
81
+ projectRoot: options.projectRoot,
82
+ moduleId: installedModuleId,
83
+ fileSystem,
84
+ commandExecutor,
85
+ skipDependencyCheck: true,
86
+ });
87
+ }
88
+ throw error;
89
+ }
90
+ },
91
+ async removeModule(moduleId) {
92
+ await removeInstalledModule({
93
+ projectRoot: options.projectRoot,
94
+ moduleId,
95
+ fileSystem,
96
+ commandExecutor,
97
+ skipDependencyCheck: false,
98
+ });
99
+ return {
100
+ removed: [moduleId],
101
+ };
102
+ },
103
+ };
104
+ }
105
+ async function removeInstalledModule(args) {
106
+ const { projectRoot, moduleId, fileSystem, commandExecutor, skipDependencyCheck, } = args;
107
+ const ledger = await readLedger(projectRoot, moduleId, fileSystem);
108
+ if (!ledger) {
109
+ throw new Error(`Module "${moduleId}" is not installed.`);
110
+ }
111
+ if (!skipDependencyCheck) {
112
+ const installedLedgers = await listLedgers(projectRoot, fileSystem);
113
+ const dependents = installedLedgers
114
+ .filter((candidate) => candidate.moduleId !== moduleId &&
115
+ candidate.dependencies.includes(moduleId))
116
+ .map((candidate) => candidate.moduleId)
117
+ .sort((left, right) => left.localeCompare(right));
118
+ if (dependents.length > 0) {
119
+ throw new Error(`Cannot remove "${moduleId}" while installed modules still depend on it: ${dependents.join(", ")}`);
120
+ }
121
+ }
122
+ await uninstallFromLedger({
123
+ projectRoot,
124
+ ledger,
125
+ fileSystem,
126
+ commandExecutor,
127
+ });
128
+ await deleteLedger(projectRoot, moduleId, fileSystem);
129
+ }
130
+ async function readLedger(projectRoot, moduleId, fileSystem) {
131
+ return fileSystem.readJson(resolveProjectPath(projectRoot, ledgerPath(moduleId)));
132
+ }
133
+ async function writeLedger(projectRoot, ledger, fileSystem) {
134
+ await fileSystem.writeJson(resolveProjectPath(projectRoot, ledgerPath(ledger.moduleId)), ledger);
135
+ }
136
+ async function deleteLedger(projectRoot, moduleId, fileSystem) {
137
+ await fileSystem.remove(resolveProjectPath(projectRoot, ledgerPath(moduleId)));
138
+ }
139
+ async function listLedgers(projectRoot, fileSystem) {
140
+ const ledgerDirectory = resolveProjectPath(projectRoot, ".ankh/ledger");
141
+ const entries = await fileSystem.readDir(ledgerDirectory);
142
+ const ledgers = [];
143
+ for (const entry of entries) {
144
+ if (!entry.endsWith(".json")) {
145
+ continue;
146
+ }
147
+ const text = await fileSystem.readJson(resolveProjectPath(projectRoot, `.ankh/ledger/${entry}`));
148
+ if (text) {
149
+ ledgers.push(text);
150
+ }
151
+ }
152
+ return ledgers;
153
+ }
154
+ //# sourceMappingURL=createOrchestrator.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"createOrchestrator.js","sourceRoot":"","sources":["../../src/orchestrator/createOrchestrator.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,4 @@
1
+ import type { ModuleDefinition } from "../module/types";
2
+ export declare function createModuleRegistry(modules: ModuleDefinition[]): Map<string, ModuleDefinition>;
3
+ export declare function resolveInstallOrder(moduleId: string, registry: Map<string, ModuleDefinition>): ModuleDefinition[];
4
+ //# sourceMappingURL=dependencyGraph.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"dependencyGraph.d.ts","sourceRoot":"","sources":["../../src/orchestrator/dependencyGraph.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,gBAAgB,EAAE,MAAM,iBAAiB,CAAC;AAExD,wBAAgB,oBAAoB,CAClC,OAAO,EAAE,gBAAgB,EAAE,GAC1B,GAAG,CAAC,MAAM,EAAE,gBAAgB,CAAC,CAW/B;AAED,wBAAgB,mBAAmB,CACjC,QAAQ,EAAE,MAAM,EAChB,QAAQ,EAAE,GAAG,CAAC,MAAM,EAAE,gBAAgB,CAAC,GACtC,gBAAgB,EAAE,CAgDpB"}
@@ -0,0 +1,44 @@
1
+ export function createModuleRegistry(modules) {
2
+ const registry = new Map();
3
+ for (const moduleDefinition of modules) {
4
+ if (registry.has(moduleDefinition.id)) {
5
+ throw new Error(`Duplicate module definition "${moduleDefinition.id}".`);
6
+ }
7
+ registry.set(moduleDefinition.id, moduleDefinition);
8
+ }
9
+ return registry;
10
+ }
11
+ export function resolveInstallOrder(moduleId, registry) {
12
+ if (!registry.has(moduleId)) {
13
+ throw new Error(`Unknown module "${moduleId}".`);
14
+ }
15
+ const resolved = new Set();
16
+ const visiting = new Set();
17
+ const order = [];
18
+ const visit = (currentId, stack) => {
19
+ if (resolved.has(currentId)) {
20
+ return;
21
+ }
22
+ if (visiting.has(currentId)) {
23
+ throw new Error(`Dependency cycle detected: ${[...stack, currentId].join(" -> ")}`);
24
+ }
25
+ const moduleDefinition = registry.get(currentId);
26
+ if (!moduleDefinition) {
27
+ throw new Error(`Missing dependency "${currentId}".`);
28
+ }
29
+ visiting.add(currentId);
30
+ const dependencies = [...new Set(moduleDefinition.dependencies ?? [])].sort((left, right) => left.localeCompare(right));
31
+ for (const dependencyId of dependencies) {
32
+ if (!registry.has(dependencyId)) {
33
+ throw new Error(`Module "${moduleDefinition.id}" depends on missing module "${dependencyId}".`);
34
+ }
35
+ visit(dependencyId, [...stack, currentId]);
36
+ }
37
+ visiting.delete(currentId);
38
+ resolved.add(currentId);
39
+ order.push(moduleDefinition);
40
+ };
41
+ visit(moduleId, []);
42
+ return order;
43
+ }
44
+ //# sourceMappingURL=dependencyGraph.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"dependencyGraph.js","sourceRoot":"","sources":["../../src/orchestrator/dependencyGraph.ts"],"names":[],"mappings":"AAEA,MAAM,UAAU,oBAAoB,CAClC,OAA2B;IAE3B,MAAM,QAAQ,GAAG,IAAI,GAAG,EAA4B,CAAC;IAErD,KAAK,MAAM,gBAAgB,IAAI,OAAO,EAAE,CAAC;QACvC,IAAI,QAAQ,CAAC,GAAG,CAAC,gBAAgB,CAAC,EAAE,CAAC,EAAE,CAAC;YACtC,MAAM,IAAI,KAAK,CAAC,gCAAgC,gBAAgB,CAAC,EAAE,IAAI,CAAC,CAAC;QAC3E,CAAC;QACD,QAAQ,CAAC,GAAG,CAAC,gBAAgB,CAAC,EAAE,EAAE,gBAAgB,CAAC,CAAC;IACtD,CAAC;IAED,OAAO,QAAQ,CAAC;AAClB,CAAC;AAED,MAAM,UAAU,mBAAmB,CACjC,QAAgB,EAChB,QAAuC;IAEvC,IAAI,CAAC,QAAQ,CAAC,GAAG,CAAC,QAAQ,CAAC,EAAE,CAAC;QAC5B,MAAM,IAAI,KAAK,CAAC,mBAAmB,QAAQ,IAAI,CAAC,CAAC;IACnD,CAAC;IAED,MAAM,QAAQ,GAAG,IAAI,GAAG,EAAU,CAAC;IACnC,MAAM,QAAQ,GAAG,IAAI,GAAG,EAAU,CAAC;IACnC,MAAM,KAAK,GAAuB,EAAE,CAAC;IAErC,MAAM,KAAK,GAAG,CAAC,SAAiB,EAAE,KAAe,EAAE,EAAE;QACnD,IAAI,QAAQ,CAAC,GAAG,CAAC,SAAS,CAAC,EAAE,CAAC;YAC5B,OAAO;QACT,CAAC;QAED,IAAI,QAAQ,CAAC,GAAG,CAAC,SAAS,CAAC,EAAE,CAAC;YAC5B,MAAM,IAAI,KAAK,CACb,8BAA8B,CAAC,GAAG,KAAK,EAAE,SAAS,CAAC,CAAC,IAAI,CAAC,MAAM,CAAC,EAAE,CACnE,CAAC;QACJ,CAAC;QAED,MAAM,gBAAgB,GAAG,QAAQ,CAAC,GAAG,CAAC,SAAS,CAAC,CAAC;QACjD,IAAI,CAAC,gBAAgB,EAAE,CAAC;YACtB,MAAM,IAAI,KAAK,CAAC,uBAAuB,SAAS,IAAI,CAAC,CAAC;QACxD,CAAC;QAED,QAAQ,CAAC,GAAG,CAAC,SAAS,CAAC,CAAC;QAExB,MAAM,YAAY,GAAG,CAAC,GAAG,IAAI,GAAG,CAAC,gBAAgB,CAAC,YAAY,IAAI,EAAE,CAAC,CAAC,CAAC,IAAI,CACzE,CAAC,IAAI,EAAE,KAAK,EAAE,EAAE,CAAC,IAAI,CAAC,aAAa,CAAC,KAAK,CAAC,CAC3C,CAAC;QAEF,KAAK,MAAM,YAAY,IAAI,YAAY,EAAE,CAAC;YACxC,IAAI,CAAC,QAAQ,CAAC,GAAG,CAAC,YAAY,CAAC,EAAE,CAAC;gBAChC,MAAM,IAAI,KAAK,CACb,WAAW,gBAAgB,CAAC,EAAE,gCAAgC,YAAY,IAAI,CAC/E,CAAC;YACJ,CAAC;YACD,KAAK,CAAC,YAAY,EAAE,CAAC,GAAG,KAAK,EAAE,SAAS,CAAC,CAAC,CAAC;QAC7C,CAAC;QAED,QAAQ,CAAC,MAAM,CAAC,SAAS,CAAC,CAAC;QAC3B,QAAQ,CAAC,GAAG,CAAC,SAAS,CAAC,CAAC;QACxB,KAAK,CAAC,IAAI,CAAC,gBAAgB,CAAC,CAAC;IAC/B,CAAC,CAAC;IAEF,KAAK,CAAC,QAAQ,EAAE,EAAE,CAAC,CAAC;IAEpB,OAAO,KAAK,CAAC;AACf,CAAC"}
@@ -0,0 +1,9 @@
1
+ import type { CommandExecutor, FileSystem } from "../fs/types";
2
+ import type { ModuleLedger } from "../ledger/types";
3
+ export declare function uninstallFromLedger(args: {
4
+ projectRoot: string;
5
+ ledger: ModuleLedger;
6
+ fileSystem: FileSystem;
7
+ commandExecutor: CommandExecutor;
8
+ }): Promise<void>;
9
+ //# sourceMappingURL=uninstall.d.ts.map