agent-switchboard 0.3.10 → 0.4.1

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 (83) hide show
  1. package/dist/agents/claude-code.d.ts +2 -0
  2. package/dist/agents/claude-code.js +5 -5
  3. package/dist/agents/claude-code.js.map +1 -1
  4. package/dist/agents/codex.d.ts +6 -0
  5. package/dist/agents/codex.js +65 -2
  6. package/dist/agents/codex.js.map +1 -1
  7. package/dist/agents/cursor.d.ts +2 -0
  8. package/dist/agents/cursor.js +5 -3
  9. package/dist/agents/cursor.js.map +1 -1
  10. package/dist/agents/gemini.d.ts +2 -0
  11. package/dist/agents/gemini.js +23 -3
  12. package/dist/agents/gemini.js.map +1 -1
  13. package/dist/agents/json-utils.d.ts +5 -0
  14. package/dist/agents/json-utils.js +21 -0
  15. package/dist/agents/json-utils.js.map +1 -1
  16. package/dist/agents/opencode.d.ts +2 -0
  17. package/dist/agents/opencode.js +14 -6
  18. package/dist/agents/opencode.js.map +1 -1
  19. package/dist/agents/trae.d.ts +2 -0
  20. package/dist/agents/trae.js +5 -3
  21. package/dist/agents/trae.js.map +1 -1
  22. package/dist/commands/distribution.d.ts +2 -2
  23. package/dist/commands/distribution.js +4 -1
  24. package/dist/commands/distribution.js.map +1 -1
  25. package/dist/config/application-config.js +2 -2
  26. package/dist/config/application-config.js.map +1 -1
  27. package/dist/config/schemas.d.ts +683 -0
  28. package/dist/config/schemas.js +33 -0
  29. package/dist/config/schemas.js.map +1 -1
  30. package/dist/index.js +4 -28
  31. package/dist/index.js.map +1 -1
  32. package/dist/library/distribute-bundle.d.ts +13 -1
  33. package/dist/library/distribute-bundle.js +154 -35
  34. package/dist/library/distribute-bundle.js.map +1 -1
  35. package/dist/library/distribute.d.ts +16 -1
  36. package/dist/library/distribute.js +107 -34
  37. package/dist/library/distribute.js.map +1 -1
  38. package/dist/manifest/store.d.ts +53 -0
  39. package/dist/manifest/store.js +183 -0
  40. package/dist/manifest/store.js.map +1 -0
  41. package/dist/manifest/types.d.ts +52 -0
  42. package/dist/manifest/types.js +9 -0
  43. package/dist/manifest/types.js.map +1 -0
  44. package/dist/mcp/distribution.d.ts +5 -0
  45. package/dist/mcp/distribution.js +42 -10
  46. package/dist/mcp/distribution.js.map +1 -1
  47. package/dist/plugins/index.js +21 -7
  48. package/dist/plugins/index.js.map +1 -1
  49. package/dist/rules/block-merge.d.ts +24 -0
  50. package/dist/rules/block-merge.js +68 -0
  51. package/dist/rules/block-merge.js.map +1 -0
  52. package/dist/rules/distribution.d.ts +7 -0
  53. package/dist/rules/distribution.js +94 -8
  54. package/dist/rules/distribution.js.map +1 -1
  55. package/dist/skills/distribution.d.ts +5 -1
  56. package/dist/skills/distribution.js +9 -0
  57. package/dist/skills/distribution.js.map +1 -1
  58. package/dist/subagents/distribution.d.ts +2 -2
  59. package/dist/subagents/distribution.js +4 -1
  60. package/dist/subagents/distribution.js.map +1 -1
  61. package/dist/sync/command.js +58 -14
  62. package/dist/sync/command.js.map +1 -1
  63. package/dist/targets/builtin/claude-code.js +3 -1
  64. package/dist/targets/builtin/claude-code.js.map +1 -1
  65. package/dist/targets/builtin/codex.js +3 -1
  66. package/dist/targets/builtin/codex.js.map +1 -1
  67. package/dist/targets/builtin/cursor.js +3 -1
  68. package/dist/targets/builtin/cursor.js.map +1 -1
  69. package/dist/targets/builtin/gemini.js +1 -1
  70. package/dist/targets/builtin/gemini.js.map +1 -1
  71. package/dist/targets/builtin/opencode.js +1 -1
  72. package/dist/targets/builtin/opencode.js.map +1 -1
  73. package/dist/targets/builtin/trae.js +3 -1
  74. package/dist/targets/builtin/trae.js.map +1 -1
  75. package/dist/targets/types.d.ts +8 -1
  76. package/dist/targets/types.js.map +1 -1
  77. package/dist/types.d.ts +0 -11
  78. package/dist/types.js.map +1 -1
  79. package/dist/ui/mcp-ui.d.ts +1 -10
  80. package/dist/ui/mcp-ui.js +33 -28
  81. package/dist/ui/mcp-ui.js.map +1 -1
  82. package/dist/util/cli.d.ts +1 -1
  83. package/package.json +1 -1
@@ -1,6 +1,7 @@
1
1
  import { createHash } from 'node:crypto';
2
2
  import fs from 'node:fs';
3
3
  import path from 'node:path';
4
+ import { computeLibraryCleanupSet, getLibraryEntry, recordLibraryEntry, removeLibraryEntry, } from '../manifest/store.js';
4
5
  import { ensureParentDir, rmDirRecursive } from './fs.js';
5
6
  import { loadLibraryAgentSync, updateLibraryAgentSync } from './state.js';
6
7
  /**
@@ -11,6 +12,14 @@ export function distributeBundle(opts) {
11
12
  const agentSync = loadLibraryAgentSync(opts.section);
12
13
  const results = [];
13
14
  const timestamp = new Date().toISOString();
15
+ const collision = opts.collision ?? 'warn-skip';
16
+ // Safe cast: managed mode guard ensures section is never 'hooks' (hooks don't use manifest)
17
+ const manifestSection = opts.section;
18
+ // Extract managed context with proper narrowing (avoids non-null assertions throughout)
19
+ const managedProjectRoot = opts.scope?.project;
20
+ const manifest = managedProjectRoot && (opts.projectMode ?? 'exclusive') === 'managed'
21
+ ? opts.manifest
22
+ : undefined;
14
23
  for (const platform of opts.platforms) {
15
24
  const platformHash = createHash('sha256');
16
25
  // Apply per-platform filter if provided
@@ -20,6 +29,25 @@ export function distributeBundle(opts) {
20
29
  for (const entry of platformSelected) {
21
30
  const targetDir = opts.resolveTargetDir(platform, entry);
22
31
  const files = opts.listFiles(entry);
32
+ const entryId = opts.getId(entry);
33
+ // Conflict detection in managed mode: check if target dir exists but isn't owned
34
+ if (manifest && fs.existsSync(targetDir)) {
35
+ const manifestEntry = getLibraryEntry(manifest, manifestSection, entryId, platform);
36
+ if (!manifestEntry && collision !== 'takeover') {
37
+ // Foreign directory exists at target path - skip
38
+ results.push({
39
+ platform,
40
+ targetDir,
41
+ status: 'conflict',
42
+ reason: 'foreign directory exists',
43
+ entryId,
44
+ });
45
+ // Intentionally not included in aggregate hash: content was not
46
+ // written, so it should not affect sync-state comparison.
47
+ continue;
48
+ }
49
+ // 'takeover' or manifestEntry exists: fall through to overwrite
50
+ }
23
51
  let filesWritten = 0;
24
52
  let filesSkipped = 0;
25
53
  let hadError = false;
@@ -61,7 +89,11 @@ export function distributeBundle(opts) {
61
89
  break;
62
90
  }
63
91
  }
64
- const entryId = opts.getId(entry);
92
+ // Clean stale files: remove files in target that are no longer in source bundle
93
+ if (!hadError && fs.existsSync(targetDir)) {
94
+ const expectedFiles = new Set(files.map((f) => f.relativePath));
95
+ cleanStaleFiles(targetDir, '', expectedFiles);
96
+ }
65
97
  if (hadError) {
66
98
  results.push({
67
99
  platform,
@@ -90,6 +122,27 @@ export function distributeBundle(opts) {
90
122
  filesSkipped,
91
123
  });
92
124
  }
125
+ // Record in manifest after successful write or skip
126
+ if (manifest && managedProjectRoot) {
127
+ const lastResult = results[results.length - 1];
128
+ if (lastResult.status === 'written' || lastResult.status === 'skipped') {
129
+ const contentHash = createHash('sha256');
130
+ for (const file of files) {
131
+ try {
132
+ contentHash.update(fs.readFileSync(file.sourcePath));
133
+ }
134
+ catch {
135
+ // Ignore
136
+ }
137
+ }
138
+ recordLibraryEntry(manifest, manifestSection, entryId, {
139
+ relativePath: path.relative(path.resolve(managedProjectRoot), targetDir),
140
+ targetId: platform,
141
+ hash: contentHash.digest('hex'),
142
+ updatedAt: timestamp,
143
+ });
144
+ }
145
+ }
93
146
  }
94
147
  // Update sync state
95
148
  const aggregateHash = platformHash.digest('hex');
@@ -101,50 +154,116 @@ export function distributeBundle(opts) {
101
154
  [platform]: { hash: aggregateHash, updatedAt: timestamp },
102
155
  }));
103
156
  }
104
- // Cleanup orphan directories if cleanup config is provided
157
+ // Cleanup orphan directories
105
158
  if (opts.cleanup) {
106
159
  const activeIds = new Set(platformSelected.map(opts.getId));
107
- const parentDir = opts.cleanup.resolveParentDir(platform);
108
- if (fs.existsSync(parentDir)) {
109
- try {
110
- const entries = fs.readdirSync(parentDir, { withFileTypes: true });
111
- for (const entry of entries) {
112
- if (!entry.isDirectory())
113
- continue;
114
- const id = entry.name;
115
- if (opts.cleanup.isReservedDir?.(id, platform))
116
- continue;
117
- if (!activeIds.has(id)) {
118
- const dirPath = path.join(parentDir, id);
119
- try {
120
- rmDirRecursive(dirPath);
121
- results.push({
122
- platform,
123
- targetDir: dirPath,
124
- status: 'deleted',
125
- reason: 'orphan',
126
- entryId: id,
127
- });
128
- }
129
- catch (error) {
130
- const msg = error instanceof Error ? error.message : String(error);
131
- results.push({
132
- platform,
133
- targetDir: dirPath,
134
- status: 'error',
135
- error: `Failed to delete orphan: ${msg}`,
136
- entryId: id,
137
- });
160
+ if (manifest && managedProjectRoot) {
161
+ // Manifest-driven cleanup: only delete entries previously owned by ASB
162
+ const toRemove = computeLibraryCleanupSet(manifest, manifestSection, activeIds, platform);
163
+ for (const item of toRemove) {
164
+ const entryPath = path.join(path.resolve(managedProjectRoot), item.entry.relativePath);
165
+ try {
166
+ if (fs.existsSync(entryPath)) {
167
+ rmDirRecursive(entryPath);
168
+ }
169
+ results.push({
170
+ platform,
171
+ targetDir: entryPath,
172
+ status: 'deleted',
173
+ reason: 'orphan',
174
+ entryId: item.id,
175
+ });
176
+ removeLibraryEntry(manifest, manifestSection, item.id, platform);
177
+ }
178
+ catch (error) {
179
+ const msg = error instanceof Error ? error.message : String(error);
180
+ results.push({
181
+ platform,
182
+ targetDir: entryPath,
183
+ status: 'error',
184
+ error: `Failed to delete orphan: ${msg}`,
185
+ entryId: item.id,
186
+ });
187
+ }
188
+ }
189
+ }
190
+ else {
191
+ // Exclusive mode: scan directory for orphans (existing behavior)
192
+ const parentDir = opts.cleanup.resolveParentDir(platform);
193
+ if (fs.existsSync(parentDir)) {
194
+ try {
195
+ const dirEntries = fs.readdirSync(parentDir, { withFileTypes: true });
196
+ for (const dirEntry of dirEntries) {
197
+ if (!dirEntry.isDirectory())
198
+ continue;
199
+ const id = dirEntry.name;
200
+ if (opts.cleanup.isReservedDir?.(id, platform))
201
+ continue;
202
+ if (!activeIds.has(id)) {
203
+ const dirPath = path.join(parentDir, id);
204
+ try {
205
+ rmDirRecursive(dirPath);
206
+ results.push({
207
+ platform,
208
+ targetDir: dirPath,
209
+ status: 'deleted',
210
+ reason: 'orphan',
211
+ entryId: id,
212
+ });
213
+ }
214
+ catch (error) {
215
+ const msg = error instanceof Error ? error.message : String(error);
216
+ results.push({
217
+ platform,
218
+ targetDir: dirPath,
219
+ status: 'error',
220
+ error: `Failed to delete orphan: ${msg}`,
221
+ entryId: id,
222
+ });
223
+ }
138
224
  }
139
225
  }
140
226
  }
227
+ catch {
228
+ // Ignore errors reading directory
229
+ }
230
+ }
231
+ }
232
+ }
233
+ }
234
+ return { results };
235
+ }
236
+ /** Recursively remove files in targetDir not present in expectedFiles (relative paths). */
237
+ function cleanStaleFiles(dir, prefix, expectedFiles) {
238
+ try {
239
+ const entries = fs.readdirSync(dir, { withFileTypes: true });
240
+ for (const entry of entries) {
241
+ const rel = prefix ? `${prefix}/${entry.name}` : entry.name;
242
+ const abs = path.join(dir, entry.name);
243
+ if (entry.isDirectory()) {
244
+ cleanStaleFiles(abs, rel, expectedFiles);
245
+ // Remove empty directories left after cleaning
246
+ try {
247
+ const remaining = fs.readdirSync(abs);
248
+ if (remaining.length === 0)
249
+ fs.rmdirSync(abs);
250
+ }
251
+ catch {
252
+ // Ignore
253
+ }
254
+ }
255
+ else if (!expectedFiles.has(rel)) {
256
+ try {
257
+ fs.unlinkSync(abs);
141
258
  }
142
259
  catch {
143
- // Ignore errors reading directory
260
+ // Ignore permission errors
144
261
  }
145
262
  }
146
263
  }
147
264
  }
148
- return { results };
265
+ catch {
266
+ // Ignore errors reading directory
267
+ }
149
268
  }
150
269
  //# sourceMappingURL=distribute-bundle.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"distribute-bundle.js","sourceRoot":"","sources":["../../src/library/distribute-bundle.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"distribute-bundle.js","sourceRoot":"","sources":["../../src/library/distribute-bundle.ts"],"names":[],"mappings":"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"}
@@ -1,6 +1,7 @@
1
1
  import type { ConfigScope } from '../config/scope.js';
2
+ import type { ProjectDistributionManifest } from '../manifest/types.js';
2
3
  import { type LibrarySection } from './state.js';
3
- export type DistributionStatus = 'written' | 'skipped' | 'error' | 'deleted';
4
+ export type DistributionStatus = 'written' | 'skipped' | 'error' | 'deleted' | 'conflict';
4
5
  export interface DistributionResult<Platform extends string> {
5
6
  platform: Platform;
6
7
  filePath: string;
@@ -15,6 +16,14 @@ export interface CleanupConfig<Platform extends string> {
15
16
  /** Extract entry ID from filename (without extension) */
16
17
  extractId: (filename: string) => string | null;
17
18
  }
19
+ export type ProjectMode = 'managed' | 'exclusive' | 'none';
20
+ export type CollisionPolicy = 'warn-skip' | 'error' | 'takeover';
21
+ /** Options for managed project-level distribution (commands, agents, skills) */
22
+ export interface LibraryManagedOptions {
23
+ manifest?: ProjectDistributionManifest;
24
+ projectMode?: ProjectMode;
25
+ collision?: CollisionPolicy;
26
+ }
18
27
  export interface DistributeOptions<TEntry, Platform extends string> {
19
28
  section: LibrarySection;
20
29
  selected: TEntry[];
@@ -31,6 +40,12 @@ export interface DistributeOptions<TEntry, Platform extends string> {
31
40
  * Used for per-agent configuration where each platform may have different active items.
32
41
  */
33
42
  filterSelected?: (platform: Platform, selected: TEntry[]) => TEntry[];
43
+ /** Project distribution manifest for managed cleanup (project scope only) */
44
+ manifest?: ProjectDistributionManifest;
45
+ /** Project distribution mode (only used when scope.project is set) */
46
+ projectMode?: ProjectMode;
47
+ /** Collision policy for managed mode */
48
+ collision?: CollisionPolicy;
34
49
  }
35
50
  export interface DistributeOutcome<Platform extends string> {
36
51
  results: DistributionResult<Platform>[];
@@ -1,6 +1,7 @@
1
1
  import { createHash } from 'node:crypto';
2
2
  import fs from 'node:fs';
3
3
  import path from 'node:path';
4
+ import { computeLibraryCleanupSet, getLibraryEntry, recordLibraryEntry, removeLibraryEntry, } from '../manifest/store.js';
4
5
  import { ensureParentDir } from './fs.js';
5
6
  import { loadLibraryAgentSync, updateLibraryAgentSync } from './state.js';
6
7
  /**
@@ -11,6 +12,14 @@ export function distributeLibrary(opts) {
11
12
  const agentSync = loadLibraryAgentSync(opts.section);
12
13
  const results = [];
13
14
  const timestamp = new Date().toISOString();
15
+ const collision = opts.collision ?? 'warn-skip';
16
+ // Safe cast: managed mode guard ensures section is never 'hooks' (hooks don't use manifest)
17
+ const manifestSection = opts.section;
18
+ // Extract managed context with proper narrowing (avoids non-null assertions throughout)
19
+ const managedProjectRoot = opts.scope?.project;
20
+ const manifest = managedProjectRoot && (opts.projectMode ?? 'exclusive') === 'managed'
21
+ ? opts.manifest
22
+ : undefined;
14
23
  for (const platform of opts.platforms) {
15
24
  const hash = createHash('sha256');
16
25
  const writtenOrSkipped = [];
@@ -21,6 +30,7 @@ export function distributeLibrary(opts) {
21
30
  for (const entry of platformSelected) {
22
31
  const filePath = opts.resolveFilePath(platform, entry);
23
32
  const content = opts.render(platform, entry);
33
+ const entryId = opts.getId?.(entry);
24
34
  ensureParentDir(filePath);
25
35
  let existing = null;
26
36
  try {
@@ -30,6 +40,24 @@ export function distributeLibrary(opts) {
30
40
  catch {
31
41
  existing = null;
32
42
  }
43
+ // Conflict detection in managed mode
44
+ if (manifest && existing !== null && entryId) {
45
+ const manifestEntry = getLibraryEntry(manifest, manifestSection, entryId, platform);
46
+ if (!manifestEntry && collision !== 'takeover') {
47
+ // Foreign file exists at target path - skip (warn-skip and error both skip)
48
+ writtenOrSkipped.push({
49
+ platform,
50
+ filePath,
51
+ status: 'conflict',
52
+ reason: 'foreign file exists',
53
+ entryId,
54
+ });
55
+ // Intentionally not included in aggregate hash: content was not
56
+ // written, so it should not affect sync-state comparison.
57
+ continue;
58
+ }
59
+ // 'takeover' or manifestEntry exists: fall through to overwrite
60
+ }
33
61
  const same = existing !== null && existing === content;
34
62
  if (same) {
35
63
  writtenOrSkipped.push({ platform, filePath, status: 'skipped', reason: 'up-to-date' });
@@ -49,6 +77,18 @@ export function distributeLibrary(opts) {
49
77
  writtenOrSkipped.push({ platform, filePath, status: 'error', error: msg });
50
78
  }
51
79
  }
80
+ // Record in manifest after successful write or skip (up-to-date)
81
+ if (manifest && managedProjectRoot && entryId) {
82
+ const lastResult = writtenOrSkipped[writtenOrSkipped.length - 1];
83
+ if (lastResult.status === 'written' || lastResult.status === 'skipped') {
84
+ recordLibraryEntry(manifest, manifestSection, entryId, {
85
+ relativePath: path.relative(path.resolve(managedProjectRoot), filePath),
86
+ targetId: platform,
87
+ hash: createHash('sha256').update(content).digest('hex'),
88
+ updatedAt: timestamp,
89
+ });
90
+ }
91
+ }
52
92
  hash.update(`\n# ${filePath}\n`);
53
93
  hash.update(content);
54
94
  }
@@ -62,45 +102,78 @@ export function distributeLibrary(opts) {
62
102
  }));
63
103
  }
64
104
  results.push(...writtenOrSkipped);
65
- // Cleanup orphan files if cleanup config is provided
105
+ // Cleanup orphan files
66
106
  if (opts.cleanup && opts.getId) {
67
107
  const activeIds = new Set(platformSelected.map(opts.getId));
68
- const targetDir = opts.cleanup.resolveTargetDir(platform);
69
- if (fs.existsSync(targetDir)) {
70
- try {
71
- const files = fs.readdirSync(targetDir);
72
- for (const file of files) {
73
- const filePath = path.join(targetDir, file);
74
- // Skip directories
75
- if (fs.statSync(filePath).isDirectory())
76
- continue;
77
- const id = opts.cleanup.extractId(file);
78
- if (id !== null && !activeIds.has(id)) {
79
- try {
80
- fs.unlinkSync(filePath);
81
- results.push({
82
- platform,
83
- filePath,
84
- status: 'deleted',
85
- reason: 'orphan',
86
- entryId: id,
87
- });
88
- }
89
- catch (error) {
90
- const msg = error instanceof Error ? error.message : String(error);
91
- results.push({
92
- platform,
93
- filePath,
94
- status: 'error',
95
- error: `Failed to delete orphan: ${msg}`,
96
- entryId: id,
97
- });
98
- }
108
+ if (manifest && managedProjectRoot) {
109
+ // Manifest-driven cleanup: only delete entries previously owned by ASB
110
+ const toRemove = computeLibraryCleanupSet(manifest, manifestSection, activeIds, platform);
111
+ for (const item of toRemove) {
112
+ const entryPath = path.join(path.resolve(managedProjectRoot), item.entry.relativePath);
113
+ try {
114
+ if (fs.existsSync(entryPath)) {
115
+ fs.unlinkSync(entryPath);
99
116
  }
117
+ results.push({
118
+ platform,
119
+ filePath: entryPath,
120
+ status: 'deleted',
121
+ reason: 'orphan',
122
+ entryId: item.id,
123
+ });
124
+ removeLibraryEntry(manifest, manifestSection, item.id, platform);
125
+ }
126
+ catch (error) {
127
+ const msg = error instanceof Error ? error.message : String(error);
128
+ results.push({
129
+ platform,
130
+ filePath: entryPath,
131
+ status: 'error',
132
+ error: `Failed to delete orphan: ${msg}`,
133
+ entryId: item.id,
134
+ });
100
135
  }
101
136
  }
102
- catch {
103
- // Ignore errors reading directory
137
+ }
138
+ else {
139
+ // Exclusive mode: scan directory for orphans (existing behavior)
140
+ const targetDir = opts.cleanup.resolveTargetDir(platform);
141
+ if (fs.existsSync(targetDir)) {
142
+ try {
143
+ const files = fs.readdirSync(targetDir);
144
+ for (const file of files) {
145
+ const filePath = path.join(targetDir, file);
146
+ // Skip directories
147
+ if (fs.statSync(filePath).isDirectory())
148
+ continue;
149
+ const id = opts.cleanup.extractId(file);
150
+ if (id !== null && !activeIds.has(id)) {
151
+ try {
152
+ fs.unlinkSync(filePath);
153
+ results.push({
154
+ platform,
155
+ filePath,
156
+ status: 'deleted',
157
+ reason: 'orphan',
158
+ entryId: id,
159
+ });
160
+ }
161
+ catch (error) {
162
+ const msg = error instanceof Error ? error.message : String(error);
163
+ results.push({
164
+ platform,
165
+ filePath,
166
+ status: 'error',
167
+ error: `Failed to delete orphan: ${msg}`,
168
+ entryId: id,
169
+ });
170
+ }
171
+ }
172
+ }
173
+ }
174
+ catch {
175
+ // Ignore errors reading directory
176
+ }
104
177
  }
105
178
  }
106
179
  }
@@ -1 +1 @@
1
- {"version":3,"file":"distribute.js","sourceRoot":"","sources":["../../src/library/distribute.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"distribute.js","sourceRoot":"","sources":["../../src/library/distribute.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,UAAU,EAAE,MAAM,aAAa,CAAC;AACzC,OAAO,EAAE,MAAM,SAAS,CAAC;AACzB,OAAO,IAAI,MAAM,WAAW,CAAC;AAE7B,OAAO,EACL,wBAAwB,EACxB,eAAe,EAEf,kBAAkB,EAClB,kBAAkB,GACnB,MAAM,sBAAsB,CAAC;AAE9B,OAAO,EAAE,eAAe,EAAE,MAAM,SAAS,CAAC;AAC1C,OAAO,EAAuB,oBAAoB,EAAE,sBAAsB,EAAE,MAAM,YAAY,CAAC;AA0D/F;;;GAGG;AACH,MAAM,UAAU,iBAAiB,CAC/B,IAAyC;IAEzC,MAAM,SAAS,GAAG,oBAAoB,CAAC,IAAI,CAAC,OAAO,CAAC,CAAC;IACrD,MAAM,OAAO,GAAmC,EAAE,CAAC;IACnD,MAAM,SAAS,GAAG,IAAI,IAAI,EAAE,CAAC,WAAW,EAAE,CAAC;IAC3C,MAAM,SAAS,GAAG,IAAI,CAAC,SAAS,IAAI,WAAW,CAAC;IAChD,4FAA4F;IAC5F,MAAM,eAAe,GAAG,IAAI,CAAC,OAAiC,CAAC;IAC/D,wFAAwF;IACxF,MAAM,kBAAkB,GAAG,IAAI,CAAC,KAAK,EAAE,OAAO,CAAC;IAC/C,MAAM,QAAQ,GACZ,kBAAkB,IAAI,CAAC,IAAI,CAAC,WAAW,IAAI,WAAW,CAAC,KAAK,SAAS;QACnE,CAAC,CAAC,IAAI,CAAC,QAAQ;QACf,CAAC,CAAC,SAAS,CAAC;IAEhB,KAAK,MAAM,QAAQ,IAAI,IAAI,CAAC,SAAS,EAAE,CAAC;QACtC,MAAM,IAAI,GAAG,UAAU,CAAC,QAAQ,CAAC,CAAC;QAClC,MAAM,gBAAgB,GAAmC,EAAE,CAAC;QAE5D,wCAAwC;QACxC,MAAM,gBAAgB,GAAG,IAAI,CAAC,cAAc;YAC1C,CAAC,CAAC,IAAI,CAAC,cAAc,CAAC,QAAQ,EAAE,IAAI,CAAC,QAAQ,CAAC;YAC9C,CAAC,CAAC,IAAI,CAAC,QAAQ,CAAC;QAElB,KAAK,MAAM,KAAK,IAAI,gBAAgB,EAAE,CAAC;YACrC,MAAM,QAAQ,GAAG,IAAI,CAAC,eAAe,CAAC,QAAQ,EAAE,KAAK,CAAC,CAAC;YACvD,MAAM,OAAO,GAAG,IAAI,CAAC,MAAM,CAAC,QAAQ,EAAE,KAAK,CAAC,CAAC;YAC7C,MAAM,OAAO,GAAG,IAAI,CAAC,KAAK,EAAE,CAAC,KAAK,CAAC,CAAC;YAEpC,eAAe,CAAC,QAAQ,CAAC,CAAC;YAE1B,IAAI,QAAQ,GAAkB,IAAI,CAAC;YACnC,IAAI,CAAC;gBACH,IAAI,EAAE,CAAC,UAAU,CAAC,QAAQ,CAAC;oBAAE,QAAQ,GAAG,EAAE,CAAC,YAAY,CAAC,QAAQ,EAAE,OAAO,CAAC,CAAC;YAC7E,CAAC;YAAC,MAAM,CAAC;gBACP,QAAQ,GAAG,IAAI,CAAC;YAClB,CAAC;YAED,qCAAqC;YACrC,IAAI,QAAQ,IAAI,QAAQ,KAAK,IAAI,IAAI,OAAO,EAAE,CAAC;gBAC7C,MAAM,aAAa,GAAG,eAAe,CACnC,QAAQ,EACR,eAAe,EACf,OAAO,EACP,QAAkB,CACnB,CAAC;gBACF,IAAI,CAAC,aAAa,IAAI,SAAS,KAAK,UAAU,EAAE,CAAC;oBAC/C,4EAA4E;oBAC5E,gBAAgB,CAAC,IAAI,CAAC;wBACpB,QAAQ;wBACR,QAAQ;wBACR,MAAM,EAAE,UAAU;wBAClB,MAAM,EAAE,qBAAqB;wBAC7B,OAAO;qBACR,CAAC,CAAC;oBACH,gEAAgE;oBAChE,0DAA0D;oBAC1D,SAAS;gBACX,CAAC;gBACD,gEAAgE;YAClE,CAAC;YAED,MAAM,IAAI,GAAG,QAAQ,KAAK,IAAI,IAAI,QAAQ,KAAK,OAAO,CAAC;YACvD,IAAI,IAAI,EAAE,CAAC;gBACT,gBAAgB,CAAC,IAAI,CAAC,EAAE,QAAQ,EAAE,QAAQ,EAAE,MAAM,EAAE,SAAS,EAAE,MAAM,EAAE,YAAY,EAAE,CAAC,CAAC;YACzF,CAAC;iBAAM,CAAC;gBACN,IAAI,CAAC;oBACH,EAAE,CAAC,aAAa,CAAC,QAAQ,EAAE,OAAO,EAAE,OAAO,CAAC,CAAC;oBAC7C,gBAAgB,CAAC,IAAI,CAAC;wBACpB,QAAQ;wBACR,QAAQ;wBACR,MAAM,EAAE,SAAS;wBACjB,MAAM,EAAE,QAAQ,CAAC,CAAC,CAAC,SAAS,CAAC,CAAC,CAAC,SAAS;qBACzC,CAAC,CAAC;gBACL,CAAC;gBAAC,OAAO,KAAK,EAAE,CAAC;oBACf,MAAM,GAAG,GAAG,KAAK,YAAY,KAAK,CAAC,CAAC,CAAC,KAAK,CAAC,OAAO,CAAC,CAAC,CAAC,MAAM,CAAC,KAAK,CAAC,CAAC;oBACnE,gBAAgB,CAAC,IAAI,CAAC,EAAE,QAAQ,EAAE,QAAQ,EAAE,MAAM,EAAE,OAAO,EAAE,KAAK,EAAE,GAAG,EAAE,CAAC,CAAC;gBAC7E,CAAC;YACH,CAAC;YAED,iEAAiE;YACjE,IAAI,QAAQ,IAAI,kBAAkB,IAAI,OAAO,EAAE,CAAC;gBAC9C,MAAM,UAAU,GAAG,gBAAgB,CAAC,gBAAgB,CAAC,MAAM,GAAG,CAAC,CAAC,CAAC;gBACjE,IAAI,UAAU,CAAC,MAAM,KAAK,SAAS,IAAI,UAAU,CAAC,MAAM,KAAK,SAAS,EAAE,CAAC;oBACvE,kBAAkB,CAAC,QAAQ,EAAE,eAAe,EAAE,OAAO,EAAE;wBACrD,YAAY,EAAE,IAAI,CAAC,QAAQ,CAAC,IAAI,CAAC,OAAO,CAAC,kBAAkB,CAAC,EAAE,QAAQ,CAAC;wBACvE,QAAQ,EAAE,QAAkB;wBAC5B,IAAI,EAAE,UAAU,CAAC,QAAQ,CAAC,CAAC,MAAM,CAAC,OAAO,CAAC,CAAC,MAAM,CAAC,KAAK,CAAC;wBACxD,SAAS,EAAE,SAAS;qBACrB,CAAC,CAAC;gBACL,CAAC;YACH,CAAC;YAED,IAAI,CAAC,MAAM,CAAC,OAAO,QAAQ,IAAI,CAAC,CAAC;YACjC,IAAI,CAAC,MAAM,CAAC,OAAO,CAAC,CAAC;QACvB,CAAC;QAED,MAAM,aAAa,GAAG,IAAI,CAAC,MAAM,CAAC,KAAK,CAAC,CAAC;QACzC,MAAM,IAAI,GAAG,SAAS,CAAC,QAAQ,CAAC,EAAE,IAAI,CAAC;QACvC,MAAM,SAAS,GAAG,gBAAgB,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,MAAM,KAAK,OAAO,CAAC,CAAC;QACrE,IAAI,CAAC,SAAS,IAAI,IAAI,KAAK,aAAa,EAAE,CAAC;YACzC,sBAAsB,CAAC,IAAI,CAAC,OAAO,EAAE,CAAC,OAAO,EAAE,EAAE,CAAC,CAAC;gBACjD,GAAG,OAAO;gBACV,CAAC,QAAQ,CAAC,EAAE,EAAE,IAAI,EAAE,aAAa,EAAE,SAAS,EAAE,SAAS,EAAE;aAC1D,CAAC,CAAC,CAAC;QACN,CAAC;QAED,OAAO,CAAC,IAAI,CAAC,GAAG,gBAAgB,CAAC,CAAC;QAElC,uBAAuB;QACvB,IAAI,IAAI,CAAC,OAAO,IAAI,IAAI,CAAC,KAAK,EAAE,CAAC;YAC/B,MAAM,SAAS,GAAG,IAAI,GAAG,CAAC,gBAAgB,CAAC,GAAG,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC,CAAC;YAE5D,IAAI,QAAQ,IAAI,kBAAkB,EAAE,CAAC;gBACnC,uEAAuE;gBACvE,MAAM,QAAQ,GAAG,wBAAwB,CACvC,QAAQ,EACR,eAAe,EACf,SAAS,EACT,QAAkB,CACnB,CAAC;gBACF,KAAK,MAAM,IAAI,IAAI,QAAQ,EAAE,CAAC;oBAC5B,MAAM,SAAS,GAAG,IAAI,CAAC,IAAI,CAAC,IAAI,CAAC,OAAO,CAAC,kBAAkB,CAAC,EAAE,IAAI,CAAC,KAAK,CAAC,YAAY,CAAC,CAAC;oBACvF,IAAI,CAAC;wBACH,IAAI,EAAE,CAAC,UAAU,CAAC,SAAS,CAAC,EAAE,CAAC;4BAC7B,EAAE,CAAC,UAAU,CAAC,SAAS,CAAC,CAAC;wBAC3B,CAAC;wBACD,OAAO,CAAC,IAAI,CAAC;4BACX,QAAQ;4BACR,QAAQ,EAAE,SAAS;4BACnB,MAAM,EAAE,SAAS;4BACjB,MAAM,EAAE,QAAQ;4BAChB,OAAO,EAAE,IAAI,CAAC,EAAE;yBACjB,CAAC,CAAC;wBACH,kBAAkB,CAAC,QAAQ,EAAE,eAAe,EAAE,IAAI,CAAC,EAAE,EAAE,QAAkB,CAAC,CAAC;oBAC7E,CAAC;oBAAC,OAAO,KAAK,EAAE,CAAC;wBACf,MAAM,GAAG,GAAG,KAAK,YAAY,KAAK,CAAC,CAAC,CAAC,KAAK,CAAC,OAAO,CAAC,CAAC,CAAC,MAAM,CAAC,KAAK,CAAC,CAAC;wBACnE,OAAO,CAAC,IAAI,CAAC;4BACX,QAAQ;4BACR,QAAQ,EAAE,SAAS;4BACnB,MAAM,EAAE,OAAO;4BACf,KAAK,EAAE,4BAA4B,GAAG,EAAE;4BACxC,OAAO,EAAE,IAAI,CAAC,EAAE;yBACjB,CAAC,CAAC;oBACL,CAAC;gBACH,CAAC;YACH,CAAC;iBAAM,CAAC;gBACN,iEAAiE;gBACjE,MAAM,SAAS,GAAG,IAAI,CAAC,OAAO,CAAC,gBAAgB,CAAC,QAAQ,CAAC,CAAC;gBAE1D,IAAI,EAAE,CAAC,UAAU,CAAC,SAAS,CAAC,EAAE,CAAC;oBAC7B,IAAI,CAAC;wBACH,MAAM,KAAK,GAAG,EAAE,CAAC,WAAW,CAAC,SAAS,CAAC,CAAC;wBACxC,KAAK,MAAM,IAAI,IAAI,KAAK,EAAE,CAAC;4BACzB,MAAM,QAAQ,GAAG,IAAI,CAAC,IAAI,CAAC,SAAS,EAAE,IAAI,CAAC,CAAC;4BAC5C,mBAAmB;4BACnB,IAAI,EAAE,CAAC,QAAQ,CAAC,QAAQ,CAAC,CAAC,WAAW,EAAE;gCAAE,SAAS;4BAElD,MAAM,EAAE,GAAG,IAAI,CAAC,OAAO,CAAC,SAAS,CAAC,IAAI,CAAC,CAAC;4BACxC,IAAI,EAAE,KAAK,IAAI,IAAI,CAAC,SAAS,CAAC,GAAG,CAAC,EAAE,CAAC,EAAE,CAAC;gCACtC,IAAI,CAAC;oCACH,EAAE,CAAC,UAAU,CAAC,QAAQ,CAAC,CAAC;oCACxB,OAAO,CAAC,IAAI,CAAC;wCACX,QAAQ;wCACR,QAAQ;wCACR,MAAM,EAAE,SAAS;wCACjB,MAAM,EAAE,QAAQ;wCAChB,OAAO,EAAE,EAAE;qCACZ,CAAC,CAAC;gCACL,CAAC;gCAAC,OAAO,KAAK,EAAE,CAAC;oCACf,MAAM,GAAG,GAAG,KAAK,YAAY,KAAK,CAAC,CAAC,CAAC,KAAK,CAAC,OAAO,CAAC,CAAC,CAAC,MAAM,CAAC,KAAK,CAAC,CAAC;oCACnE,OAAO,CAAC,IAAI,CAAC;wCACX,QAAQ;wCACR,QAAQ;wCACR,MAAM,EAAE,OAAO;wCACf,KAAK,EAAE,4BAA4B,GAAG,EAAE;wCACxC,OAAO,EAAE,EAAE;qCACZ,CAAC,CAAC;gCACL,CAAC;4BACH,CAAC;wBACH,CAAC;oBACH,CAAC;oBAAC,MAAM,CAAC;wBACP,kCAAkC;oBACpC,CAAC;gBACH,CAAC;YACH,CAAC;QACH,CAAC;IACH,CAAC;IAED,OAAO,EAAE,OAAO,EAAE,CAAC;AACrB,CAAC"}
@@ -0,0 +1,53 @@
1
+ /**
2
+ * Project distribution manifest I/O and helpers.
3
+ *
4
+ * The manifest lives at `<project>/.asb/state/distribution.json` and records
5
+ * which artifacts ASB has written, enabling manifest-driven cleanup.
6
+ */
7
+ import type { ManagedMcpEntry, ManifestEntry, ManifestSections, ProjectDistributionManifest, RulesManifestEntry } from './types.js';
8
+ export declare function resolveManifestPath(projectRoot: string): string;
9
+ export declare function loadManifest(projectRoot: string): ProjectDistributionManifest;
10
+ export declare function saveManifest(projectRoot: string, manifest: ProjectDistributionManifest): void;
11
+ export type LibraryManifestSection = 'skills' | 'commands' | 'agents';
12
+ export interface ManifestCleanupItem {
13
+ id: string;
14
+ entry: ManifestEntry;
15
+ }
16
+ export declare function recordLibraryEntry(manifest: ProjectDistributionManifest, section: LibraryManifestSection, id: string, entry: ManifestEntry): void;
17
+ export declare function removeLibraryEntry(manifest: ProjectDistributionManifest, section: LibraryManifestSection, id: string, targetId?: string): void;
18
+ export declare function recordMcpEntry(manifest: ProjectDistributionManifest, serverName: string, entry: ManagedMcpEntry): void;
19
+ /**
20
+ * Remove an MCP manifest entry by its composite key (as returned by
21
+ * `computeMcpCleanupSet`).
22
+ */
23
+ export declare function removeMcpEntry(manifest: ProjectDistributionManifest, compositeKey: string): void;
24
+ export declare function recordRulesEntry(manifest: ProjectDistributionManifest, filePathKey: string, entry: RulesManifestEntry): void;
25
+ export declare function removeRulesEntry(manifest: ProjectDistributionManifest, filePathKey: string): void;
26
+ /**
27
+ * Compute entries that were previously owned by ASB but are no longer in the
28
+ * current desired set. These are safe to clean up.
29
+ *
30
+ * Returns `ManifestCleanupItem[]` with the bare entry id and the full entry,
31
+ * so callers can resolve file paths and remove the manifest record.
32
+ */
33
+ export declare function computeLibraryCleanupSet(manifest: ProjectDistributionManifest, section: LibraryManifestSection, currentDesiredIds: ReadonlySet<string>, targetId?: string): ManifestCleanupItem[];
34
+ /**
35
+ * Compute MCP composite keys that were previously owned but are no longer enabled.
36
+ * Returns composite keys (serverName::targetId) for use with `removeMcpEntry`.
37
+ */
38
+ export declare function computeMcpCleanupSet(manifest: ProjectDistributionManifest, currentDesiredNames: ReadonlySet<string>, targetId?: string): string[];
39
+ /**
40
+ * Get the set of previously-owned MCP server names for a given target.
41
+ * Returns bare server names (not composite keys).
42
+ */
43
+ export declare function getOwnedMcpServers(manifest: ProjectDistributionManifest, targetId: string): Set<string>;
44
+ /**
45
+ * Get manifest entry for a library section item, if it exists.
46
+ * When targetId is provided, looks up the composite key directly.
47
+ * Without targetId, scans for the first entry matching the bare id.
48
+ */
49
+ export declare function getLibraryEntry(manifest: ProjectDistributionManifest, section: LibraryManifestSection, id: string, targetId?: string): ManifestEntry | undefined;
50
+ /**
51
+ * Resolve the effective sections record, ensuring it exists.
52
+ */
53
+ export declare function ensureSections(manifest: ProjectDistributionManifest): ManifestSections;