agentopology 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 (174) hide show
  1. package/LICENSE +191 -0
  2. package/README.md +450 -0
  3. package/dist/analyzer/__tests__/analyzer.test.d.ts +2 -0
  4. package/dist/analyzer/__tests__/analyzer.test.d.ts.map +1 -0
  5. package/dist/analyzer/__tests__/analyzer.test.js +258 -0
  6. package/dist/analyzer/__tests__/analyzer.test.js.map +1 -0
  7. package/dist/analyzer/index.d.ts +44 -0
  8. package/dist/analyzer/index.d.ts.map +1 -0
  9. package/dist/analyzer/index.js +308 -0
  10. package/dist/analyzer/index.js.map +1 -0
  11. package/dist/bindings/__tests__/bindings.test.d.ts +2 -0
  12. package/dist/bindings/__tests__/bindings.test.d.ts.map +1 -0
  13. package/dist/bindings/__tests__/bindings.test.js +2089 -0
  14. package/dist/bindings/__tests__/bindings.test.js.map +1 -0
  15. package/dist/bindings/claude-code.d.ts +12 -0
  16. package/dist/bindings/claude-code.d.ts.map +1 -0
  17. package/dist/bindings/claude-code.js +2063 -0
  18. package/dist/bindings/claude-code.js.map +1 -0
  19. package/dist/bindings/codex.d.ts +18 -0
  20. package/dist/bindings/codex.d.ts.map +1 -0
  21. package/dist/bindings/codex.js +1633 -0
  22. package/dist/bindings/codex.js.map +1 -0
  23. package/dist/bindings/copilot-cli.d.ts +20 -0
  24. package/dist/bindings/copilot-cli.d.ts.map +1 -0
  25. package/dist/bindings/copilot-cli.js +1515 -0
  26. package/dist/bindings/copilot-cli.js.map +1 -0
  27. package/dist/bindings/cursor.d.ts +17 -0
  28. package/dist/bindings/cursor.d.ts.map +1 -0
  29. package/dist/bindings/cursor.js +1715 -0
  30. package/dist/bindings/cursor.js.map +1 -0
  31. package/dist/bindings/gemini-cli.d.ts +18 -0
  32. package/dist/bindings/gemini-cli.d.ts.map +1 -0
  33. package/dist/bindings/gemini-cli.js +1327 -0
  34. package/dist/bindings/gemini-cli.js.map +1 -0
  35. package/dist/bindings/index.d.ts +20 -0
  36. package/dist/bindings/index.d.ts.map +1 -0
  37. package/dist/bindings/index.js +33 -0
  38. package/dist/bindings/index.js.map +1 -0
  39. package/dist/bindings/kiro.d.ts +17 -0
  40. package/dist/bindings/kiro.d.ts.map +1 -0
  41. package/dist/bindings/kiro.js +1624 -0
  42. package/dist/bindings/kiro.js.map +1 -0
  43. package/dist/bindings/openclaw.d.ts +18 -0
  44. package/dist/bindings/openclaw.d.ts.map +1 -0
  45. package/dist/bindings/openclaw.js +1578 -0
  46. package/dist/bindings/openclaw.js.map +1 -0
  47. package/dist/bindings/types.d.ts +33 -0
  48. package/dist/bindings/types.d.ts.map +1 -0
  49. package/dist/bindings/types.js +23 -0
  50. package/dist/bindings/types.js.map +1 -0
  51. package/dist/cli/index.d.ts +19 -0
  52. package/dist/cli/index.d.ts.map +1 -0
  53. package/dist/cli/index.js +679 -0
  54. package/dist/cli/index.js.map +1 -0
  55. package/dist/docs/__tests__/docs.test.d.ts +2 -0
  56. package/dist/docs/__tests__/docs.test.d.ts.map +1 -0
  57. package/dist/docs/__tests__/docs.test.js +438 -0
  58. package/dist/docs/__tests__/docs.test.js.map +1 -0
  59. package/dist/docs/content.d.ts +16 -0
  60. package/dist/docs/content.d.ts.map +1 -0
  61. package/dist/docs/content.js +3273 -0
  62. package/dist/docs/content.js.map +1 -0
  63. package/dist/docs/index.d.ts +17 -0
  64. package/dist/docs/index.d.ts.map +1 -0
  65. package/dist/docs/index.js +117 -0
  66. package/dist/docs/index.js.map +1 -0
  67. package/dist/exporters/__tests__/exporters.test.d.ts +2 -0
  68. package/dist/exporters/__tests__/exporters.test.d.ts.map +1 -0
  69. package/dist/exporters/__tests__/exporters.test.js +731 -0
  70. package/dist/exporters/__tests__/exporters.test.js.map +1 -0
  71. package/dist/exporters/index.d.ts +13 -0
  72. package/dist/exporters/index.d.ts.map +1 -0
  73. package/dist/exporters/index.js +18 -0
  74. package/dist/exporters/index.js.map +1 -0
  75. package/dist/exporters/json.d.ts +8 -0
  76. package/dist/exporters/json.d.ts.map +1 -0
  77. package/dist/exporters/json.js +25 -0
  78. package/dist/exporters/json.js.map +1 -0
  79. package/dist/exporters/markdown.d.ts +9 -0
  80. package/dist/exporters/markdown.d.ts.map +1 -0
  81. package/dist/exporters/markdown.js +686 -0
  82. package/dist/exporters/markdown.js.map +1 -0
  83. package/dist/exporters/mermaid.d.ts +11 -0
  84. package/dist/exporters/mermaid.d.ts.map +1 -0
  85. package/dist/exporters/mermaid.js +161 -0
  86. package/dist/exporters/mermaid.js.map +1 -0
  87. package/dist/exporters/types.d.ts +22 -0
  88. package/dist/exporters/types.d.ts.map +1 -0
  89. package/dist/exporters/types.js +10 -0
  90. package/dist/exporters/types.js.map +1 -0
  91. package/dist/import/__tests__/import.test.d.ts +2 -0
  92. package/dist/import/__tests__/import.test.d.ts.map +1 -0
  93. package/dist/import/__tests__/import.test.js +781 -0
  94. package/dist/import/__tests__/import.test.js.map +1 -0
  95. package/dist/import/claude-code.d.ts +38 -0
  96. package/dist/import/claude-code.d.ts.map +1 -0
  97. package/dist/import/claude-code.js +897 -0
  98. package/dist/import/claude-code.js.map +1 -0
  99. package/dist/import/index.d.ts +18 -0
  100. package/dist/import/index.d.ts.map +1 -0
  101. package/dist/import/index.js +28 -0
  102. package/dist/import/index.js.map +1 -0
  103. package/dist/import/serializer.d.ts +11 -0
  104. package/dist/import/serializer.d.ts.map +1 -0
  105. package/dist/import/serializer.js +960 -0
  106. package/dist/import/serializer.js.map +1 -0
  107. package/dist/index.d.ts +26 -0
  108. package/dist/index.d.ts.map +1 -0
  109. package/dist/index.js +21 -0
  110. package/dist/index.js.map +1 -0
  111. package/dist/parser/__tests__/parser.test.d.ts +2 -0
  112. package/dist/parser/__tests__/parser.test.d.ts.map +1 -0
  113. package/dist/parser/__tests__/parser.test.js +6514 -0
  114. package/dist/parser/__tests__/parser.test.js.map +1 -0
  115. package/dist/parser/ast.d.ts +708 -0
  116. package/dist/parser/ast.d.ts.map +1 -0
  117. package/dist/parser/ast.js +12 -0
  118. package/dist/parser/ast.js.map +1 -0
  119. package/dist/parser/index.d.ts +253 -0
  120. package/dist/parser/index.d.ts.map +1 -0
  121. package/dist/parser/index.js +1985 -0
  122. package/dist/parser/index.js.map +1 -0
  123. package/dist/parser/lexer.d.ts +100 -0
  124. package/dist/parser/lexer.d.ts.map +1 -0
  125. package/dist/parser/lexer.js +304 -0
  126. package/dist/parser/lexer.js.map +1 -0
  127. package/dist/parser/validator.d.ts +42 -0
  128. package/dist/parser/validator.d.ts.map +1 -0
  129. package/dist/parser/validator.js +2568 -0
  130. package/dist/parser/validator.js.map +1 -0
  131. package/dist/scaffold/__tests__/scaffold.test.d.ts +7 -0
  132. package/dist/scaffold/__tests__/scaffold.test.d.ts.map +1 -0
  133. package/dist/scaffold/__tests__/scaffold.test.js +295 -0
  134. package/dist/scaffold/__tests__/scaffold.test.js.map +1 -0
  135. package/dist/scaffold/incremental.d.ts +43 -0
  136. package/dist/scaffold/incremental.d.ts.map +1 -0
  137. package/dist/scaffold/incremental.js +185 -0
  138. package/dist/scaffold/incremental.js.map +1 -0
  139. package/dist/scaffold/index.d.ts +13 -0
  140. package/dist/scaffold/index.d.ts.map +1 -0
  141. package/dist/scaffold/index.js +13 -0
  142. package/dist/scaffold/index.js.map +1 -0
  143. package/dist/scaffold/manifest.d.ts +30 -0
  144. package/dist/scaffold/manifest.d.ts.map +1 -0
  145. package/dist/scaffold/manifest.js +71 -0
  146. package/dist/scaffold/manifest.js.map +1 -0
  147. package/dist/scaffold/merge.d.ts +52 -0
  148. package/dist/scaffold/merge.d.ts.map +1 -0
  149. package/dist/scaffold/merge.js +134 -0
  150. package/dist/scaffold/merge.js.map +1 -0
  151. package/dist/scaffold/types.d.ts +51 -0
  152. package/dist/scaffold/types.d.ts.map +1 -0
  153. package/dist/scaffold/types.js +10 -0
  154. package/dist/scaffold/types.js.map +1 -0
  155. package/dist/sync/index.d.ts +34 -0
  156. package/dist/sync/index.d.ts.map +1 -0
  157. package/dist/sync/index.js +392 -0
  158. package/dist/sync/index.js.map +1 -0
  159. package/dist/visualizer/index.d.ts +17 -0
  160. package/dist/visualizer/index.d.ts.map +1 -0
  161. package/dist/visualizer/index.js +1976 -0
  162. package/dist/visualizer/index.js.map +1 -0
  163. package/examples/code-review.at +167 -0
  164. package/examples/data-processing.at +296 -0
  165. package/examples/openclaw-assistant.at +142 -0
  166. package/examples/scheduled-monitor.at +193 -0
  167. package/examples/simple-pipeline.at +163 -0
  168. package/package.json +77 -0
  169. package/skill/SKILL.md +403 -0
  170. package/skill/scripts/emit.ts +853 -0
  171. package/skill/scripts/visualize.ts +89 -0
  172. package/spec/grammar.md +1466 -0
  173. package/spec/reserved-keywords.md +147 -0
  174. package/spec/validation.md +535 -0
@@ -0,0 +1,185 @@
1
+ /**
2
+ * Incremental scaffold orchestrator.
3
+ *
4
+ * Computes a plan of file actions (create, update, delete, unchanged, conflict)
5
+ * by comparing freshly generated files against what is on disk and what was
6
+ * previously tracked in the scaffold manifest.
7
+ *
8
+ * @module
9
+ */
10
+ import { existsSync, mkdirSync, readFileSync, unlinkSync, writeFileSync } from "node:fs";
11
+ import { dirname, join } from "node:path";
12
+ import { mergeAgentFile, shouldOverwriteScript, deepMergeJson } from "./merge.js";
13
+ /**
14
+ * Compute an incremental scaffold plan.
15
+ *
16
+ * Compares generated files against what exists on disk and the previous
17
+ * manifest to determine the minimal set of file operations needed.
18
+ *
19
+ * @param basePath - Absolute path to the project root
20
+ * @param target - Binding target name (e.g. "claude-code")
21
+ * @param generatedFiles - Files produced by the binding's scaffold function
22
+ * @param manifest - Previous scaffold manifest (null if first scaffold)
23
+ * @returns Array of file actions to execute
24
+ */
25
+ export function computeIncrementalPlan(basePath, target, generatedFiles, manifest) {
26
+ const actions = [];
27
+ // Build map of generated files by path
28
+ const generatedMap = new Map();
29
+ for (const file of generatedFiles) {
30
+ generatedMap.set(file.path, file);
31
+ }
32
+ // Process each generated file
33
+ for (const file of generatedFiles) {
34
+ const absPath = join(basePath, file.path);
35
+ const category = file.category ?? "machine";
36
+ const onDisk = existsSync(absPath);
37
+ if (!onDisk) {
38
+ actions.push({ type: "create", path: file.path, content: file.content });
39
+ continue;
40
+ }
41
+ const existingContent = readFileSync(absPath, "utf-8");
42
+ const manifestEntry = manifest?.files[file.path] ?? null;
43
+ switch (category) {
44
+ case "agent": {
45
+ const merged = mergeAgentFile(existingContent, file.content, target);
46
+ if (merged === existingContent) {
47
+ actions.push({ type: "unchanged", path: file.path });
48
+ }
49
+ else {
50
+ actions.push({
51
+ type: "update",
52
+ path: file.path,
53
+ content: merged,
54
+ detail: "prompt preserved",
55
+ });
56
+ }
57
+ break;
58
+ }
59
+ case "script": {
60
+ const manifestHash = manifestEntry?.hash ?? "";
61
+ if (shouldOverwriteScript(existingContent, manifestHash)) {
62
+ // User hasn't edited — safe to overwrite
63
+ if (file.content === existingContent) {
64
+ actions.push({ type: "unchanged", path: file.path });
65
+ }
66
+ else {
67
+ actions.push({
68
+ type: "update",
69
+ path: file.path,
70
+ content: file.content,
71
+ detail: "script regenerated",
72
+ });
73
+ }
74
+ }
75
+ else {
76
+ // User has edited — conflict
77
+ actions.push({
78
+ type: "conflict",
79
+ path: file.path,
80
+ content: file.content,
81
+ detail: "user edited",
82
+ });
83
+ }
84
+ break;
85
+ }
86
+ case "shared-config": {
87
+ const merged = deepMergeJson(existingContent, file.content);
88
+ if (merged === existingContent) {
89
+ actions.push({ type: "unchanged", path: file.path });
90
+ }
91
+ else {
92
+ actions.push({
93
+ type: "update",
94
+ path: file.path,
95
+ content: merged,
96
+ detail: "config merged",
97
+ });
98
+ }
99
+ break;
100
+ }
101
+ case "machine":
102
+ default: {
103
+ if (file.content === existingContent) {
104
+ actions.push({ type: "unchanged", path: file.path });
105
+ }
106
+ else {
107
+ actions.push({
108
+ type: "update",
109
+ path: file.path,
110
+ content: file.content,
111
+ detail: "config updated",
112
+ });
113
+ }
114
+ break;
115
+ }
116
+ }
117
+ }
118
+ // Check for files in manifest that are no longer generated (deletions)
119
+ if (manifest) {
120
+ for (const manifestPath of Object.keys(manifest.files)) {
121
+ if (!generatedMap.has(manifestPath)) {
122
+ actions.push({ type: "delete", path: manifestPath });
123
+ }
124
+ }
125
+ }
126
+ return actions;
127
+ }
128
+ /**
129
+ * Execute a set of file actions against the filesystem.
130
+ *
131
+ * @param basePath - Absolute path to the project root
132
+ * @param actions - File actions computed by {@link computeIncrementalPlan}
133
+ * @param options - Execution options
134
+ * @returns Counts of each action type performed
135
+ */
136
+ export function executeActions(basePath, actions, options) {
137
+ const counts = { created: 0, updated: 0, deleted: 0, unchanged: 0, conflicts: 0 };
138
+ for (const action of actions) {
139
+ const absPath = join(basePath, action.path);
140
+ switch (action.type) {
141
+ case "create": {
142
+ const dir = dirname(absPath);
143
+ if (!existsSync(dir)) {
144
+ mkdirSync(dir, { recursive: true });
145
+ }
146
+ writeFileSync(absPath, action.content, "utf-8");
147
+ counts.created++;
148
+ break;
149
+ }
150
+ case "update": {
151
+ const dir = dirname(absPath);
152
+ if (!existsSync(dir)) {
153
+ mkdirSync(dir, { recursive: true });
154
+ }
155
+ writeFileSync(absPath, action.content, "utf-8");
156
+ counts.updated++;
157
+ break;
158
+ }
159
+ case "delete": {
160
+ if (options.prune && existsSync(absPath)) {
161
+ unlinkSync(absPath);
162
+ }
163
+ counts.deleted++;
164
+ break;
165
+ }
166
+ case "conflict": {
167
+ if (options.force) {
168
+ const dir = dirname(absPath);
169
+ if (!existsSync(dir)) {
170
+ mkdirSync(dir, { recursive: true });
171
+ }
172
+ writeFileSync(absPath, action.content, "utf-8");
173
+ }
174
+ counts.conflicts++;
175
+ break;
176
+ }
177
+ case "unchanged": {
178
+ counts.unchanged++;
179
+ break;
180
+ }
181
+ }
182
+ }
183
+ return counts;
184
+ }
185
+ //# sourceMappingURL=incremental.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"incremental.js","sourceRoot":"","sources":["../../src/scaffold/incremental.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,13 @@
1
+ /**
2
+ * Incremental scaffold system.
3
+ *
4
+ * Provides manifest tracking and merge logic so that `scaffold` can
5
+ * intelligently update files on disk without destroying user edits.
6
+ *
7
+ * @module
8
+ */
9
+ export * from "./types.js";
10
+ export * from "./manifest.js";
11
+ export * from "./merge.js";
12
+ export * from "./incremental.js";
13
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/scaffold/index.ts"],"names":[],"mappings":"AAAA;;;;;;;GAOG;AAEH,cAAc,YAAY,CAAC;AAC3B,cAAc,eAAe,CAAC;AAC9B,cAAc,YAAY,CAAC;AAC3B,cAAc,kBAAkB,CAAC"}
@@ -0,0 +1,13 @@
1
+ /**
2
+ * Incremental scaffold system.
3
+ *
4
+ * Provides manifest tracking and merge logic so that `scaffold` can
5
+ * intelligently update files on disk without destroying user edits.
6
+ *
7
+ * @module
8
+ */
9
+ export * from "./types.js";
10
+ export * from "./manifest.js";
11
+ export * from "./merge.js";
12
+ export * from "./incremental.js";
13
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/scaffold/index.ts"],"names":[],"mappings":"AAAA;;;;;;;GAOG;AAEH,cAAc,YAAY,CAAC;AAC3B,cAAc,eAAe,CAAC;AAC9B,cAAc,YAAY,CAAC;AAC3B,cAAc,kBAAkB,CAAC"}
@@ -0,0 +1,30 @@
1
+ /**
2
+ * Manifest I/O for the incremental scaffold system.
3
+ *
4
+ * Reads and writes `.scaffold-manifest.json` files that track what was
5
+ * generated, enabling intelligent re-scaffolding.
6
+ *
7
+ * @module
8
+ */
9
+ import type { ScaffoldManifest } from "./types.js";
10
+ /**
11
+ * Return the platform-specific manifest path (relative to project root).
12
+ *
13
+ * Each binding stores the manifest inside its own config directory so it
14
+ * doesn't collide with other bindings scaffolded into the same project.
15
+ */
16
+ export declare function getManifestPath(target: string): string;
17
+ /**
18
+ * Read an existing scaffold manifest from disk.
19
+ * Returns `null` if the manifest does not exist or cannot be parsed.
20
+ */
21
+ export declare function readManifest(basePath: string, target: string): ScaffoldManifest | null;
22
+ /**
23
+ * Write a scaffold manifest to disk, creating parent directories as needed.
24
+ */
25
+ export declare function writeManifest(basePath: string, target: string, manifest: ScaffoldManifest): void;
26
+ /**
27
+ * Compute a SHA-256 hex digest of a string.
28
+ */
29
+ export declare function hashContent(content: string): string;
30
+ //# sourceMappingURL=manifest.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"manifest.d.ts","sourceRoot":"","sources":["../../src/scaffold/manifest.ts"],"names":[],"mappings":"AAAA;;;;;;;GAOG;AAMH,OAAO,KAAK,EAAE,gBAAgB,EAAE,MAAM,YAAY,CAAC;AAInD;;;;;GAKG;AACH,wBAAgB,eAAe,CAAC,MAAM,EAAE,MAAM,GAAG,MAAM,CAkBtD;AAED;;;GAGG;AACH,wBAAgB,YAAY,CAC1B,QAAQ,EAAE,MAAM,EAChB,MAAM,EAAE,MAAM,GACb,gBAAgB,GAAG,IAAI,CAUzB;AAED;;GAEG;AACH,wBAAgB,aAAa,CAC3B,QAAQ,EAAE,MAAM,EAChB,MAAM,EAAE,MAAM,EACd,QAAQ,EAAE,gBAAgB,GACzB,IAAI,CAON;AAED;;GAEG;AACH,wBAAgB,WAAW,CAAC,OAAO,EAAE,MAAM,GAAG,MAAM,CAEnD"}
@@ -0,0 +1,71 @@
1
+ /**
2
+ * Manifest I/O for the incremental scaffold system.
3
+ *
4
+ * Reads and writes `.scaffold-manifest.json` files that track what was
5
+ * generated, enabling intelligent re-scaffolding.
6
+ *
7
+ * @module
8
+ */
9
+ import { createHash } from "node:crypto";
10
+ import { existsSync, mkdirSync, readFileSync, writeFileSync } from "node:fs";
11
+ import { dirname, join } from "node:path";
12
+ const MANIFEST_FILENAME = ".scaffold-manifest.json";
13
+ /**
14
+ * Return the platform-specific manifest path (relative to project root).
15
+ *
16
+ * Each binding stores the manifest inside its own config directory so it
17
+ * doesn't collide with other bindings scaffolded into the same project.
18
+ */
19
+ export function getManifestPath(target) {
20
+ switch (target) {
21
+ case "claude-code":
22
+ return join(".claude", MANIFEST_FILENAME);
23
+ case "codex":
24
+ return join(".codex", MANIFEST_FILENAME);
25
+ case "gemini-cli":
26
+ return join(".gemini", MANIFEST_FILENAME);
27
+ case "copilot-cli":
28
+ return join(".github", MANIFEST_FILENAME);
29
+ case "openclaw":
30
+ return join(".openclaw", MANIFEST_FILENAME);
31
+ case "kiro":
32
+ return join(".kiro", MANIFEST_FILENAME);
33
+ default:
34
+ // SDK bindings and unknown targets use root
35
+ return MANIFEST_FILENAME;
36
+ }
37
+ }
38
+ /**
39
+ * Read an existing scaffold manifest from disk.
40
+ * Returns `null` if the manifest does not exist or cannot be parsed.
41
+ */
42
+ export function readManifest(basePath, target) {
43
+ const manifestPath = join(basePath, getManifestPath(target));
44
+ if (!existsSync(manifestPath))
45
+ return null;
46
+ try {
47
+ const raw = readFileSync(manifestPath, "utf-8");
48
+ return JSON.parse(raw);
49
+ }
50
+ catch {
51
+ return null;
52
+ }
53
+ }
54
+ /**
55
+ * Write a scaffold manifest to disk, creating parent directories as needed.
56
+ */
57
+ export function writeManifest(basePath, target, manifest) {
58
+ const manifestPath = join(basePath, getManifestPath(target));
59
+ const dir = dirname(manifestPath);
60
+ if (!existsSync(dir)) {
61
+ mkdirSync(dir, { recursive: true });
62
+ }
63
+ writeFileSync(manifestPath, JSON.stringify(manifest, null, 2) + "\n", "utf-8");
64
+ }
65
+ /**
66
+ * Compute a SHA-256 hex digest of a string.
67
+ */
68
+ export function hashContent(content) {
69
+ return createHash("sha256").update(content, "utf-8").digest("hex");
70
+ }
71
+ //# sourceMappingURL=manifest.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"manifest.js","sourceRoot":"","sources":["../../src/scaffold/manifest.ts"],"names":[],"mappings":"AAAA;;;;;;;GAOG;AAEH,OAAO,EAAE,UAAU,EAAE,MAAM,aAAa,CAAC;AACzC,OAAO,EAAE,UAAU,EAAE,SAAS,EAAE,YAAY,EAAE,aAAa,EAAE,MAAM,SAAS,CAAC;AAC7E,OAAO,EAAE,OAAO,EAAE,IAAI,EAAE,MAAM,WAAW,CAAC;AAI1C,MAAM,iBAAiB,GAAG,yBAAyB,CAAC;AAEpD;;;;;GAKG;AACH,MAAM,UAAU,eAAe,CAAC,MAAc;IAC5C,QAAQ,MAAM,EAAE,CAAC;QACf,KAAK,aAAa;YAChB,OAAO,IAAI,CAAC,SAAS,EAAE,iBAAiB,CAAC,CAAC;QAC5C,KAAK,OAAO;YACV,OAAO,IAAI,CAAC,QAAQ,EAAE,iBAAiB,CAAC,CAAC;QAC3C,KAAK,YAAY;YACf,OAAO,IAAI,CAAC,SAAS,EAAE,iBAAiB,CAAC,CAAC;QAC5C,KAAK,aAAa;YAChB,OAAO,IAAI,CAAC,SAAS,EAAE,iBAAiB,CAAC,CAAC;QAC5C,KAAK,UAAU;YACb,OAAO,IAAI,CAAC,WAAW,EAAE,iBAAiB,CAAC,CAAC;QAC9C,KAAK,MAAM;YACT,OAAO,IAAI,CAAC,OAAO,EAAE,iBAAiB,CAAC,CAAC;QAC1C;YACE,4CAA4C;YAC5C,OAAO,iBAAiB,CAAC;IAC7B,CAAC;AACH,CAAC;AAED;;;GAGG;AACH,MAAM,UAAU,YAAY,CAC1B,QAAgB,EAChB,MAAc;IAEd,MAAM,YAAY,GAAG,IAAI,CAAC,QAAQ,EAAE,eAAe,CAAC,MAAM,CAAC,CAAC,CAAC;IAC7D,IAAI,CAAC,UAAU,CAAC,YAAY,CAAC;QAAE,OAAO,IAAI,CAAC;IAE3C,IAAI,CAAC;QACH,MAAM,GAAG,GAAG,YAAY,CAAC,YAAY,EAAE,OAAO,CAAC,CAAC;QAChD,OAAO,IAAI,CAAC,KAAK,CAAC,GAAG,CAAqB,CAAC;IAC7C,CAAC;IAAC,MAAM,CAAC;QACP,OAAO,IAAI,CAAC;IACd,CAAC;AACH,CAAC;AAED;;GAEG;AACH,MAAM,UAAU,aAAa,CAC3B,QAAgB,EAChB,MAAc,EACd,QAA0B;IAE1B,MAAM,YAAY,GAAG,IAAI,CAAC,QAAQ,EAAE,eAAe,CAAC,MAAM,CAAC,CAAC,CAAC;IAC7D,MAAM,GAAG,GAAG,OAAO,CAAC,YAAY,CAAC,CAAC;IAClC,IAAI,CAAC,UAAU,CAAC,GAAG,CAAC,EAAE,CAAC;QACrB,SAAS,CAAC,GAAG,EAAE,EAAE,SAAS,EAAE,IAAI,EAAE,CAAC,CAAC;IACtC,CAAC;IACD,aAAa,CAAC,YAAY,EAAE,IAAI,CAAC,SAAS,CAAC,QAAQ,EAAE,IAAI,EAAE,CAAC,CAAC,GAAG,IAAI,EAAE,OAAO,CAAC,CAAC;AACjF,CAAC;AAED;;GAEG;AACH,MAAM,UAAU,WAAW,CAAC,OAAe;IACzC,OAAO,UAAU,CAAC,QAAQ,CAAC,CAAC,MAAM,CAAC,OAAO,EAAE,OAAO,CAAC,CAAC,MAAM,CAAC,KAAK,CAAC,CAAC;AACrE,CAAC"}
@@ -0,0 +1,52 @@
1
+ /**
2
+ * Merge logic for incremental scaffold.
3
+ *
4
+ * Handles preserving user-edited content (HUMAN zone) in agent files
5
+ * while updating machine-generated sections, and hash-based overwrite
6
+ * decisions for script files.
7
+ *
8
+ * @module
9
+ */
10
+ /**
11
+ * Merge an existing agent file with a freshly generated one.
12
+ *
13
+ * Preserves the HUMAN zone (everything under `## Instructions` until the next
14
+ * structural heading) from the existing file, while taking all machine-generated
15
+ * sections from the generated file.
16
+ *
17
+ * If the existing file has no `## Instructions` section, returns the generated
18
+ * file as-is.
19
+ *
20
+ * @param existing - Current file content on disk
21
+ * @param generated - Freshly generated file content
22
+ * @param binding - Target binding name (e.g. "claude-code")
23
+ * @returns Merged file content
24
+ */
25
+ export declare function mergeAgentFile(existing: string, generated: string, binding: string): string;
26
+ /**
27
+ * Determine whether a script file should be overwritten.
28
+ *
29
+ * Compares the hash of the existing file content against the hash stored
30
+ * in the manifest. If they match, the user has not edited the file and
31
+ * it is safe to overwrite.
32
+ *
33
+ * @param existingContent - Current file content on disk
34
+ * @param manifestHash - Hash from the scaffold manifest
35
+ * @returns `true` if the file is unmodified and safe to overwrite
36
+ */
37
+ export declare function shouldOverwriteScript(existingContent: string, manifestHash: string): boolean;
38
+ /**
39
+ * Deep-merge two JSON config files.
40
+ *
41
+ * Scaffold-generated keys are added/updated into the existing config,
42
+ * but user-only keys (not present in generated) are preserved.
43
+ *
44
+ * For nested objects (like mcpServers), merges by key — scaffold stubs
45
+ * don't overwrite existing entries that have real config.
46
+ *
47
+ * @param existingRaw - Current file content on disk (JSON string)
48
+ * @param generatedRaw - Freshly generated file content (JSON string)
49
+ * @returns Merged JSON string, or existingRaw if parse fails
50
+ */
51
+ export declare function deepMergeJson(existingRaw: string, generatedRaw: string): string;
52
+ //# sourceMappingURL=merge.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"merge.d.ts","sourceRoot":"","sources":["../../src/scaffold/merge.ts"],"names":[],"mappings":"AAAA;;;;;;;;GAQG;AAuBH;;;;;;;;;;;;;;GAcG;AACH,wBAAgB,cAAc,CAC5B,QAAQ,EAAE,MAAM,EAChB,SAAS,EAAE,MAAM,EACjB,OAAO,EAAE,MAAM,GACd,MAAM,CA4CR;AAED;;;;;;;;;;GAUG;AACH,wBAAgB,qBAAqB,CACnC,eAAe,EAAE,MAAM,EACvB,YAAY,EAAE,MAAM,GACnB,OAAO,CAET;AAED;;;;;;;;;;;;GAYG;AACH,wBAAgB,aAAa,CAAC,WAAW,EAAE,MAAM,EAAE,YAAY,EAAE,MAAM,GAAG,MAAM,CAc/E"}
@@ -0,0 +1,134 @@
1
+ /**
2
+ * Merge logic for incremental scaffold.
3
+ *
4
+ * Handles preserving user-edited content (HUMAN zone) in agent files
5
+ * while updating machine-generated sections, and hash-based overwrite
6
+ * decisions for script files.
7
+ *
8
+ * @module
9
+ */
10
+ import { extractSectionUntilKnownHeading, CLAUDE_CODE_STRUCTURAL_HEADINGS, COPILOT_STRUCTURAL_HEADINGS, } from "../sync/index.js";
11
+ import { hashContent } from "./manifest.js";
12
+ /**
13
+ * Return the list of known structural headings for a binding.
14
+ * Falls back to the Claude Code list for unknown bindings.
15
+ */
16
+ function getStructuralHeadings(binding) {
17
+ switch (binding) {
18
+ case "copilot-cli":
19
+ return COPILOT_STRUCTURAL_HEADINGS;
20
+ case "claude-code":
21
+ default:
22
+ return CLAUDE_CODE_STRUCTURAL_HEADINGS;
23
+ }
24
+ }
25
+ /**
26
+ * Merge an existing agent file with a freshly generated one.
27
+ *
28
+ * Preserves the HUMAN zone (everything under `## Instructions` until the next
29
+ * structural heading) from the existing file, while taking all machine-generated
30
+ * sections from the generated file.
31
+ *
32
+ * If the existing file has no `## Instructions` section, returns the generated
33
+ * file as-is.
34
+ *
35
+ * @param existing - Current file content on disk
36
+ * @param generated - Freshly generated file content
37
+ * @param binding - Target binding name (e.g. "claude-code")
38
+ * @returns Merged file content
39
+ */
40
+ export function mergeAgentFile(existing, generated, binding) {
41
+ const structuralHeadings = getStructuralHeadings(binding);
42
+ // Extract the HUMAN zone from the existing file
43
+ const humanContent = extractSectionUntilKnownHeading(existing, "## Instructions", structuralHeadings);
44
+ // If no Instructions section exists in existing, return generated as-is
45
+ if (humanContent === null) {
46
+ return generated;
47
+ }
48
+ // Find the ## Instructions section in the generated file
49
+ const instructionsPattern = /^## Instructions\s*$/m;
50
+ const instrMatch = instructionsPattern.exec(generated);
51
+ if (!instrMatch) {
52
+ // Generated file has no Instructions section — return it as-is
53
+ return generated;
54
+ }
55
+ // Find where the generated instructions content ends (next structural heading or EOF)
56
+ const afterHeading = instrMatch.index + instrMatch[0].length;
57
+ const rest = generated.slice(afterHeading);
58
+ let endPos = rest.length;
59
+ for (const kh of structuralHeadings) {
60
+ const khPattern = new RegExp(`^${kh.replace(/[.*+?^${}()|[\]\\]/g, "\\$&")}\\s*$`, "m");
61
+ const khMatch = khPattern.exec(rest);
62
+ if (khMatch && khMatch.index < endPos) {
63
+ endPos = khMatch.index;
64
+ }
65
+ }
66
+ // Build merged file: everything before instructions content + human content + everything after
67
+ const beforeContent = generated.slice(0, afterHeading);
68
+ const afterContent = rest.slice(endPos);
69
+ return beforeContent + "\n\n" + humanContent + "\n\n" + afterContent;
70
+ }
71
+ /**
72
+ * Determine whether a script file should be overwritten.
73
+ *
74
+ * Compares the hash of the existing file content against the hash stored
75
+ * in the manifest. If they match, the user has not edited the file and
76
+ * it is safe to overwrite.
77
+ *
78
+ * @param existingContent - Current file content on disk
79
+ * @param manifestHash - Hash from the scaffold manifest
80
+ * @returns `true` if the file is unmodified and safe to overwrite
81
+ */
82
+ export function shouldOverwriteScript(existingContent, manifestHash) {
83
+ return hashContent(existingContent) === manifestHash;
84
+ }
85
+ /**
86
+ * Deep-merge two JSON config files.
87
+ *
88
+ * Scaffold-generated keys are added/updated into the existing config,
89
+ * but user-only keys (not present in generated) are preserved.
90
+ *
91
+ * For nested objects (like mcpServers), merges by key — scaffold stubs
92
+ * don't overwrite existing entries that have real config.
93
+ *
94
+ * @param existingRaw - Current file content on disk (JSON string)
95
+ * @param generatedRaw - Freshly generated file content (JSON string)
96
+ * @returns Merged JSON string, or existingRaw if parse fails
97
+ */
98
+ export function deepMergeJson(existingRaw, generatedRaw) {
99
+ let existing;
100
+ let generated;
101
+ try {
102
+ existing = JSON.parse(existingRaw);
103
+ generated = JSON.parse(generatedRaw);
104
+ }
105
+ catch {
106
+ // If either file isn't valid JSON, return existing unchanged
107
+ return existingRaw;
108
+ }
109
+ const merged = mergeObjects(existing, generated);
110
+ return JSON.stringify(merged, null, 2) + "\n";
111
+ }
112
+ function mergeObjects(existing, generated) {
113
+ // Start with a copy of existing (preserves user-only keys)
114
+ const result = { ...existing };
115
+ for (const [key, genValue] of Object.entries(generated)) {
116
+ const exValue = existing[key];
117
+ if (genValue !== null &&
118
+ typeof genValue === "object" &&
119
+ !Array.isArray(genValue) &&
120
+ exValue !== null &&
121
+ typeof exValue === "object" &&
122
+ !Array.isArray(exValue)) {
123
+ // Both are objects — recurse
124
+ result[key] = mergeObjects(exValue, genValue);
125
+ }
126
+ else if (exValue === undefined) {
127
+ // Key only in generated — add it
128
+ result[key] = genValue;
129
+ }
130
+ // else: key exists in both and at least one is not an object — keep existing value
131
+ }
132
+ return result;
133
+ }
134
+ //# sourceMappingURL=merge.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"merge.js","sourceRoot":"","sources":["../../src/scaffold/merge.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,51 @@
1
+ /**
2
+ * Types for the incremental scaffold system.
3
+ *
4
+ * The scaffold manifest tracks generated files so re-scaffolding can
5
+ * intelligently merge, overwrite, or preserve content on disk.
6
+ *
7
+ * @module
8
+ */
9
+ /** A single entry in the scaffold manifest. */
10
+ export interface ManifestEntry {
11
+ /** SHA-256 hash of the file content at generation time. */
12
+ hash: string;
13
+ /** Merge category that determines how the file is handled on re-scaffold. */
14
+ category: "machine" | "agent" | "script" | "shared-config";
15
+ }
16
+ /** Manifest written to disk after each scaffold run. */
17
+ export interface ScaffoldManifest {
18
+ /** Source .at file name. */
19
+ source: string;
20
+ /** SHA-256 hash of the source .at file at generation time. */
21
+ sourceHash: string;
22
+ /** Target binding name (e.g. "claude-code"). */
23
+ target: string;
24
+ /** ISO 8601 timestamp of when the scaffold was generated. */
25
+ generatedAt: string;
26
+ /** Map of relative file paths to their manifest entries. */
27
+ files: Record<string, ManifestEntry>;
28
+ }
29
+ /** An action to perform on a single file during incremental scaffold. */
30
+ export type FileAction = {
31
+ type: "create";
32
+ path: string;
33
+ content: string;
34
+ } | {
35
+ type: "update";
36
+ path: string;
37
+ content: string;
38
+ detail: string;
39
+ } | {
40
+ type: "delete";
41
+ path: string;
42
+ } | {
43
+ type: "unchanged";
44
+ path: string;
45
+ } | {
46
+ type: "conflict";
47
+ path: string;
48
+ content: string;
49
+ detail: string;
50
+ };
51
+ //# sourceMappingURL=types.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../../src/scaffold/types.ts"],"names":[],"mappings":"AAAA;;;;;;;GAOG;AAEH,+CAA+C;AAC/C,MAAM,WAAW,aAAa;IAC5B,2DAA2D;IAC3D,IAAI,EAAE,MAAM,CAAC;IACb,6EAA6E;IAC7E,QAAQ,EAAE,SAAS,GAAG,OAAO,GAAG,QAAQ,GAAG,eAAe,CAAC;CAC5D;AAED,wDAAwD;AACxD,MAAM,WAAW,gBAAgB;IAC/B,4BAA4B;IAC5B,MAAM,EAAE,MAAM,CAAC;IACf,8DAA8D;IAC9D,UAAU,EAAE,MAAM,CAAC;IACnB,gDAAgD;IAChD,MAAM,EAAE,MAAM,CAAC;IACf,6DAA6D;IAC7D,WAAW,EAAE,MAAM,CAAC;IACpB,4DAA4D;IAC5D,KAAK,EAAE,MAAM,CAAC,MAAM,EAAE,aAAa,CAAC,CAAC;CACtC;AAED,yEAAyE;AACzE,MAAM,MAAM,UAAU,GAClB;IAAE,IAAI,EAAE,QAAQ,CAAC;IAAC,IAAI,EAAE,MAAM,CAAC;IAAC,OAAO,EAAE,MAAM,CAAA;CAAE,GACjD;IAAE,IAAI,EAAE,QAAQ,CAAC;IAAC,IAAI,EAAE,MAAM,CAAC;IAAC,OAAO,EAAE,MAAM,CAAC;IAAC,MAAM,EAAE,MAAM,CAAA;CAAE,GACjE;IAAE,IAAI,EAAE,QAAQ,CAAC;IAAC,IAAI,EAAE,MAAM,CAAA;CAAE,GAChC;IAAE,IAAI,EAAE,WAAW,CAAC;IAAC,IAAI,EAAE,MAAM,CAAA;CAAE,GACnC;IAAE,IAAI,EAAE,UAAU,CAAC;IAAC,IAAI,EAAE,MAAM,CAAC;IAAC,OAAO,EAAE,MAAM,CAAC;IAAC,MAAM,EAAE,MAAM,CAAA;CAAE,CAAC"}
@@ -0,0 +1,10 @@
1
+ /**
2
+ * Types for the incremental scaffold system.
3
+ *
4
+ * The scaffold manifest tracks generated files so re-scaffolding can
5
+ * intelligently merge, overwrite, or preserve content on disk.
6
+ *
7
+ * @module
8
+ */
9
+ export {};
10
+ //# sourceMappingURL=types.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"types.js","sourceRoot":"","sources":["../../src/scaffold/types.ts"],"names":[],"mappings":"AAAA;;;;;;;GAOG"}
@@ -0,0 +1,34 @@
1
+ /**
2
+ * Sync-back module — extracts prompt content from platform agent files
3
+ * and writes it back into .at file prompt {} blocks.
4
+ * @module
5
+ */
6
+ /** A platform file with its path and content. */
7
+ export interface PlatformFile {
8
+ path: string;
9
+ content: string;
10
+ }
11
+ /**
12
+ * Sync prompt content from platform agent files back into an .at source string.
13
+ *
14
+ * @param atSource - Current .at file content
15
+ * @param files - Platform agent files [{path, content}]
16
+ * @param binding - Target binding name
17
+ * @returns Updated .at file content with prompt {} blocks
18
+ */
19
+ export declare function syncFromPlatform(atSource: string, files: PlatformFile[], binding: string): string;
20
+ /** Known structural headings in Claude Code AGENT.md files (not part of prompt content). */
21
+ export declare const CLAUDE_CODE_STRUCTURAL_HEADINGS: string[];
22
+ /** Known structural headings in Copilot .agent.md files. */
23
+ export declare const COPILOT_STRUCTURAL_HEADINGS: string[];
24
+ /**
25
+ * Extract content of a markdown section until one of the known structural headings.
26
+ *
27
+ * Unlike extractSectionContent which stops at ANY heading at the same level,
28
+ * this only stops at headings that are part of the binding's structural format.
29
+ * This allows prompt content to contain arbitrary ## headings (like ## Guidelines).
30
+ *
31
+ * Skips YAML frontmatter if present.
32
+ */
33
+ export declare function extractSectionUntilKnownHeading(fileContent: string, heading: string, knownHeadings: string[]): string | null;
34
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/sync/index.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAIH,iDAAiD;AACjD,MAAM,WAAW,YAAY;IAC3B,IAAI,EAAE,MAAM,CAAC;IACb,OAAO,EAAE,MAAM,CAAC;CACjB;AAQD;;;;;;;GAOG;AACH,wBAAgB,gBAAgB,CAC9B,QAAQ,EAAE,MAAM,EAChB,KAAK,EAAE,YAAY,EAAE,EACrB,OAAO,EAAE,MAAM,GACd,MAAM,CAqBR;AAsCD,4FAA4F;AAC5F,eAAO,MAAM,+BAA+B,UAM3C,CAAC;AAEF,4DAA4D;AAC5D,eAAO,MAAM,2BAA2B,UAMvC,CAAC;AA8LF;;;;;;;;GAQG;AACH,wBAAgB,+BAA+B,CAC7C,WAAW,EAAE,MAAM,EACnB,OAAO,EAAE,MAAM,EACf,aAAa,EAAE,MAAM,EAAE,GACtB,MAAM,GAAG,IAAI,CAgCf"}