agentsys 5.0.0 → 5.0.2

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 (202) hide show
  1. package/.claude-plugin/marketplace.json +13 -13
  2. package/.claude-plugin/plugin.json +1 -1
  3. package/CHANGELOG.md +19 -2
  4. package/README.md +1 -0
  5. package/adapters/README.md +1 -1
  6. package/adapters/codex/skills/consult/SKILL.md +3 -2
  7. package/adapters/codex/skills/next-task/SKILL.md +8 -8
  8. package/adapters/opencode/agents/consult-agent.md +1 -1
  9. package/adapters/opencode/agents/delivery-validator.md +1 -1
  10. package/adapters/opencode/agents/implementation-agent.md +1 -1
  11. package/adapters/opencode/agents/worktree-manager.md +3 -3
  12. package/adapters/opencode/commands/consult.md +3 -2
  13. package/adapters/opencode/commands/next-task.md +7 -7
  14. package/adapters/opencode/skills/agnix/SKILL.md +1 -1
  15. package/adapters/opencode/skills/consult/SKILL.md +16 -4
  16. package/adapters/opencode/skills/deslop/SKILL.md +1 -1
  17. package/adapters/opencode/skills/discover-tasks/SKILL.md +2 -2
  18. package/adapters/opencode/skills/drift-analysis/SKILL.md +1 -1
  19. package/adapters/opencode/skills/enhance-agent-prompts/SKILL.md +1 -1
  20. package/adapters/opencode/skills/enhance-claude-memory/SKILL.md +1 -1
  21. package/adapters/opencode/skills/enhance-cross-file/SKILL.md +1 -1
  22. package/adapters/opencode/skills/enhance-docs/SKILL.md +1 -1
  23. package/adapters/opencode/skills/enhance-hooks/SKILL.md +1 -1
  24. package/adapters/opencode/skills/enhance-orchestrator/SKILL.md +1 -1
  25. package/adapters/opencode/skills/enhance-plugins/SKILL.md +1 -1
  26. package/adapters/opencode/skills/enhance-prompts/SKILL.md +1 -1
  27. package/adapters/opencode/skills/enhance-skills/SKILL.md +1 -1
  28. package/adapters/opencode/skills/learn/SKILL.md +1 -1
  29. package/adapters/opencode/skills/orchestrate-review/SKILL.md +1 -1
  30. package/adapters/opencode/skills/perf-analyzer/SKILL.md +1 -1
  31. package/adapters/opencode/skills/perf-baseline-manager/SKILL.md +1 -1
  32. package/adapters/opencode/skills/perf-benchmarker/SKILL.md +1 -1
  33. package/adapters/opencode/skills/perf-code-paths/SKILL.md +1 -1
  34. package/adapters/opencode/skills/perf-investigation-logger/SKILL.md +1 -1
  35. package/adapters/opencode/skills/perf-profiler/SKILL.md +1 -1
  36. package/adapters/opencode/skills/perf-theory-gatherer/SKILL.md +1 -1
  37. package/adapters/opencode/skills/perf-theory-tester/SKILL.md +1 -1
  38. package/adapters/opencode/skills/sync-docs/SKILL.md +1 -1
  39. package/adapters/opencode/skills/validate-delivery/SKILL.md +2 -2
  40. package/bin/cli.js +42 -8
  41. package/bin/dev-cli.js +16 -6
  42. package/lib/collectors/github.js +76 -12
  43. package/lib/perf/benchmark-runner.js +11 -6
  44. package/lib/perf/investigation-state.js +12 -13
  45. package/lib/perf/profiling-runner.js +23 -4
  46. package/lib/repo-map/concurrency.js +29 -0
  47. package/lib/repo-map/runner.js +218 -19
  48. package/lib/repo-map/updater.js +115 -27
  49. package/lib/state/workflow-state.js +31 -30
  50. package/lib/utils/command-parser.js +0 -0
  51. package/lib/utils/state-helpers.js +61 -0
  52. package/package.json +2 -1
  53. package/plugins/agnix/.claude-plugin/plugin.json +1 -1
  54. package/plugins/agnix/skills/agnix/SKILL.md +1 -1
  55. package/plugins/audit-project/.claude-plugin/plugin.json +1 -1
  56. package/plugins/audit-project/lib/collectors/github.js +76 -12
  57. package/plugins/audit-project/lib/perf/benchmark-runner.js +11 -6
  58. package/plugins/audit-project/lib/perf/investigation-state.js +12 -13
  59. package/plugins/audit-project/lib/perf/profiling-runner.js +23 -4
  60. package/plugins/audit-project/lib/repo-map/concurrency.js +29 -0
  61. package/plugins/audit-project/lib/repo-map/runner.js +218 -19
  62. package/plugins/audit-project/lib/repo-map/updater.js +115 -27
  63. package/plugins/audit-project/lib/state/workflow-state.js +31 -30
  64. package/plugins/audit-project/lib/utils/command-parser.js +0 -0
  65. package/plugins/audit-project/lib/utils/state-helpers.js +61 -0
  66. package/plugins/consult/.claude-plugin/plugin.json +1 -1
  67. package/plugins/consult/agents/consult-agent.md +1 -1
  68. package/plugins/consult/commands/consult.md +3 -2
  69. package/plugins/consult/skills/consult/SKILL.md +16 -4
  70. package/plugins/deslop/.claude-plugin/plugin.json +1 -1
  71. package/plugins/deslop/lib/collectors/github.js +76 -12
  72. package/plugins/deslop/lib/perf/benchmark-runner.js +11 -6
  73. package/plugins/deslop/lib/perf/investigation-state.js +12 -13
  74. package/plugins/deslop/lib/perf/profiling-runner.js +23 -4
  75. package/plugins/deslop/lib/repo-map/concurrency.js +29 -0
  76. package/plugins/deslop/lib/repo-map/runner.js +218 -19
  77. package/plugins/deslop/lib/repo-map/updater.js +115 -27
  78. package/plugins/deslop/lib/state/workflow-state.js +31 -30
  79. package/plugins/deslop/lib/utils/command-parser.js +0 -0
  80. package/plugins/deslop/lib/utils/state-helpers.js +61 -0
  81. package/plugins/deslop/skills/deslop/SKILL.md +1 -1
  82. package/plugins/drift-detect/.claude-plugin/plugin.json +1 -1
  83. package/plugins/drift-detect/lib/collectors/github.js +76 -12
  84. package/plugins/drift-detect/lib/perf/benchmark-runner.js +11 -6
  85. package/plugins/drift-detect/lib/perf/investigation-state.js +12 -13
  86. package/plugins/drift-detect/lib/perf/profiling-runner.js +23 -4
  87. package/plugins/drift-detect/lib/repo-map/concurrency.js +29 -0
  88. package/plugins/drift-detect/lib/repo-map/runner.js +218 -19
  89. package/plugins/drift-detect/lib/repo-map/updater.js +115 -27
  90. package/plugins/drift-detect/lib/state/workflow-state.js +31 -30
  91. package/plugins/drift-detect/lib/utils/command-parser.js +0 -0
  92. package/plugins/drift-detect/lib/utils/state-helpers.js +61 -0
  93. package/plugins/drift-detect/skills/drift-analysis/SKILL.md +1 -1
  94. package/plugins/enhance/.claude-plugin/plugin.json +1 -1
  95. package/plugins/enhance/lib/collectors/github.js +76 -12
  96. package/plugins/enhance/lib/perf/benchmark-runner.js +11 -6
  97. package/plugins/enhance/lib/perf/investigation-state.js +12 -13
  98. package/plugins/enhance/lib/perf/profiling-runner.js +23 -4
  99. package/plugins/enhance/lib/repo-map/concurrency.js +29 -0
  100. package/plugins/enhance/lib/repo-map/runner.js +218 -19
  101. package/plugins/enhance/lib/repo-map/updater.js +115 -27
  102. package/plugins/enhance/lib/state/workflow-state.js +31 -30
  103. package/plugins/enhance/lib/utils/command-parser.js +0 -0
  104. package/plugins/enhance/lib/utils/state-helpers.js +61 -0
  105. package/plugins/enhance/skills/enhance-agent-prompts/SKILL.md +1 -1
  106. package/plugins/enhance/skills/enhance-claude-memory/SKILL.md +1 -1
  107. package/plugins/enhance/skills/enhance-cross-file/SKILL.md +1 -1
  108. package/plugins/enhance/skills/enhance-docs/SKILL.md +1 -1
  109. package/plugins/enhance/skills/enhance-hooks/SKILL.md +1 -1
  110. package/plugins/enhance/skills/enhance-orchestrator/SKILL.md +1 -1
  111. package/plugins/enhance/skills/enhance-plugins/SKILL.md +1 -1
  112. package/plugins/enhance/skills/enhance-prompts/SKILL.md +1 -1
  113. package/plugins/enhance/skills/enhance-skills/SKILL.md +1 -1
  114. package/plugins/learn/.claude-plugin/plugin.json +1 -1
  115. package/plugins/learn/lib/collectors/github.js +76 -12
  116. package/plugins/learn/lib/perf/benchmark-runner.js +11 -6
  117. package/plugins/learn/lib/perf/investigation-state.js +12 -13
  118. package/plugins/learn/lib/perf/profiling-runner.js +23 -4
  119. package/plugins/learn/lib/repo-map/concurrency.js +29 -0
  120. package/plugins/learn/lib/repo-map/runner.js +218 -19
  121. package/plugins/learn/lib/repo-map/updater.js +115 -27
  122. package/plugins/learn/lib/state/workflow-state.js +31 -30
  123. package/plugins/learn/lib/utils/command-parser.js +0 -0
  124. package/plugins/learn/lib/utils/state-helpers.js +61 -0
  125. package/plugins/learn/skills/learn/SKILL.md +1 -1
  126. package/plugins/next-task/.claude-plugin/plugin.json +1 -1
  127. package/plugins/next-task/agents/delivery-validator.md +1 -1
  128. package/plugins/next-task/agents/implementation-agent.md +2 -2
  129. package/plugins/next-task/agents/worktree-manager.md +3 -3
  130. package/plugins/next-task/commands/next-task.md +8 -8
  131. package/plugins/next-task/hooks/hooks.json +1 -1
  132. package/plugins/next-task/lib/collectors/github.js +76 -12
  133. package/plugins/next-task/lib/perf/benchmark-runner.js +11 -6
  134. package/plugins/next-task/lib/perf/investigation-state.js +12 -13
  135. package/plugins/next-task/lib/perf/profiling-runner.js +23 -4
  136. package/plugins/next-task/lib/repo-map/concurrency.js +29 -0
  137. package/plugins/next-task/lib/repo-map/runner.js +218 -19
  138. package/plugins/next-task/lib/repo-map/updater.js +115 -27
  139. package/plugins/next-task/lib/state/workflow-state.js +31 -30
  140. package/plugins/next-task/lib/utils/command-parser.js +0 -0
  141. package/plugins/next-task/lib/utils/state-helpers.js +61 -0
  142. package/plugins/next-task/skills/discover-tasks/SKILL.md +2 -2
  143. package/plugins/next-task/skills/orchestrate-review/SKILL.md +1 -1
  144. package/plugins/next-task/skills/validate-delivery/SKILL.md +2 -2
  145. package/plugins/perf/.claude-plugin/plugin.json +1 -1
  146. package/plugins/perf/lib/collectors/github.js +76 -12
  147. package/plugins/perf/lib/perf/benchmark-runner.js +11 -6
  148. package/plugins/perf/lib/perf/investigation-state.js +12 -13
  149. package/plugins/perf/lib/perf/profiling-runner.js +23 -4
  150. package/plugins/perf/lib/repo-map/concurrency.js +29 -0
  151. package/plugins/perf/lib/repo-map/runner.js +218 -19
  152. package/plugins/perf/lib/repo-map/updater.js +115 -27
  153. package/plugins/perf/lib/state/workflow-state.js +31 -30
  154. package/plugins/perf/lib/utils/command-parser.js +0 -0
  155. package/plugins/perf/lib/utils/state-helpers.js +61 -0
  156. package/plugins/perf/skills/perf-analyzer/SKILL.md +1 -1
  157. package/plugins/perf/skills/perf-baseline-manager/SKILL.md +1 -1
  158. package/plugins/perf/skills/perf-benchmarker/SKILL.md +1 -1
  159. package/plugins/perf/skills/perf-code-paths/SKILL.md +1 -1
  160. package/plugins/perf/skills/perf-investigation-logger/SKILL.md +1 -1
  161. package/plugins/perf/skills/perf-profiler/SKILL.md +1 -1
  162. package/plugins/perf/skills/perf-theory-gatherer/SKILL.md +1 -1
  163. package/plugins/perf/skills/perf-theory-tester/SKILL.md +1 -1
  164. package/plugins/repo-map/.claude-plugin/plugin.json +1 -1
  165. package/plugins/repo-map/lib/collectors/github.js +76 -12
  166. package/plugins/repo-map/lib/perf/benchmark-runner.js +11 -6
  167. package/plugins/repo-map/lib/perf/investigation-state.js +12 -13
  168. package/plugins/repo-map/lib/perf/profiling-runner.js +23 -4
  169. package/plugins/repo-map/lib/repo-map/concurrency.js +29 -0
  170. package/plugins/repo-map/lib/repo-map/runner.js +218 -19
  171. package/plugins/repo-map/lib/repo-map/updater.js +115 -27
  172. package/plugins/repo-map/lib/state/workflow-state.js +31 -30
  173. package/plugins/repo-map/lib/utils/command-parser.js +0 -0
  174. package/plugins/repo-map/lib/utils/state-helpers.js +61 -0
  175. package/plugins/ship/.claude-plugin/plugin.json +1 -1
  176. package/plugins/ship/lib/collectors/github.js +76 -12
  177. package/plugins/ship/lib/perf/benchmark-runner.js +11 -6
  178. package/plugins/ship/lib/perf/investigation-state.js +12 -13
  179. package/plugins/ship/lib/perf/profiling-runner.js +23 -4
  180. package/plugins/ship/lib/repo-map/concurrency.js +29 -0
  181. package/plugins/ship/lib/repo-map/runner.js +218 -19
  182. package/plugins/ship/lib/repo-map/updater.js +115 -27
  183. package/plugins/ship/lib/state/workflow-state.js +31 -30
  184. package/plugins/ship/lib/utils/command-parser.js +0 -0
  185. package/plugins/ship/lib/utils/state-helpers.js +61 -0
  186. package/plugins/sync-docs/.claude-plugin/plugin.json +1 -1
  187. package/plugins/sync-docs/lib/collectors/github.js +76 -12
  188. package/plugins/sync-docs/lib/perf/benchmark-runner.js +11 -6
  189. package/plugins/sync-docs/lib/perf/investigation-state.js +12 -13
  190. package/plugins/sync-docs/lib/perf/profiling-runner.js +23 -4
  191. package/plugins/sync-docs/lib/repo-map/concurrency.js +29 -0
  192. package/plugins/sync-docs/lib/repo-map/runner.js +218 -19
  193. package/plugins/sync-docs/lib/repo-map/updater.js +115 -27
  194. package/plugins/sync-docs/lib/state/workflow-state.js +31 -30
  195. package/plugins/sync-docs/lib/utils/command-parser.js +0 -0
  196. package/plugins/sync-docs/lib/utils/state-helpers.js +61 -0
  197. package/plugins/sync-docs/skills/sync-docs/SKILL.md +1 -1
  198. package/scripts/bump-version.js +4 -1
  199. package/scripts/dev-install.js +9 -0
  200. package/scripts/validate-opencode-install.js +17 -4
  201. package/site/content.json +1 -1
  202. package/site/index.html +1 -1
@@ -16,11 +16,11 @@ const path = require('path');
16
16
  const crypto = require('crypto');
17
17
  const { getStateDir } = require('../platform/state-dir');
18
18
  const { writeJsonAtomic } = require('../utils/atomic-write');
19
+ const { isPlainObject, updatesApplied, sleepForRetry } = require('../utils/state-helpers');
19
20
 
20
21
  // File paths
21
22
  const TASKS_FILE = 'tasks.json';
22
23
  const FLOW_FILE = 'flow.json';
23
-
24
24
  /**
25
25
  * Validate and resolve path to prevent path traversal attacks
26
26
  * @param {string} basePath - Base directory path
@@ -223,7 +223,7 @@ function writeFlow(flow, worktreePath = process.cwd()) {
223
223
  * Uses optimistic locking with version check and retry
224
224
  */
225
225
  function updateFlow(updates, worktreePath = process.cwd()) {
226
- const MAX_RETRIES = 3;
226
+ const MAX_RETRIES = 5;
227
227
 
228
228
  for (let attempt = 0; attempt < MAX_RETRIES; attempt++) {
229
229
  const flow = readFlow(worktreePath) || {};
@@ -238,10 +238,7 @@ function updateFlow(updates, worktreePath = process.cwd()) {
238
238
  flow[key] = null;
239
239
  }
240
240
  // Deep merge if both source and target are non-null objects
241
- else if (
242
- value && typeof value === 'object' && !Array.isArray(value) &&
243
- flow[key] && typeof flow[key] === 'object' && !Array.isArray(flow[key])
244
- ) {
241
+ else if (isPlainObject(value) && isPlainObject(flow[key])) {
245
242
  flow[key] = { ...flow[key], ...value };
246
243
  }
247
244
  // Otherwise direct assignment
@@ -258,24 +255,26 @@ function updateFlow(updates, worktreePath = process.cwd()) {
258
255
 
259
256
  // Re-read to verify our write succeeded
260
257
  const afterWrite = readFlow(worktreePath);
261
- if (afterWrite && afterWrite._version === initialVersion + 1) {
258
+ if (afterWrite && afterWrite._version >= initialVersion + 1 && updatesApplied(afterWrite, updates)) {
262
259
  return true; // Success
263
260
  }
264
261
 
265
- // Version conflict - retry after brief delay
262
+ // Version conflict or overwrite - retry after brief delay
266
263
  if (attempt < MAX_RETRIES - 1) {
267
- // Small random delay to reduce collision probability
268
264
  const delay = Math.floor(Math.random() * 50) + 10;
269
- const start = Date.now();
270
- while (Date.now() - start < delay) {
271
- // Busy wait (synchronous delay)
272
- }
265
+ sleepForRetry(delay);
273
266
  }
274
267
  }
275
268
 
276
- // All retries exhausted
277
- console.error('[WARN] updateFlow: max retries exceeded, possible version conflict');
278
- return true; // Return true to not break callers, but log warning
269
+ // All retries exhausted. One final read can detect if another writer
270
+ // applied the same updates while we were retrying.
271
+ const latest = readFlow(worktreePath);
272
+ if (latest && updatesApplied(latest, updates)) {
273
+ return true;
274
+ }
275
+
276
+ console.error('[ERROR] updateFlow: failed to apply updates after max retries');
277
+ return false;
279
278
  }
280
279
 
281
280
  /**
@@ -420,8 +419,8 @@ function completePhase(result = null, worktreePath = process.cwd()) {
420
419
  }
421
420
  }
422
421
 
423
- updateFlow(updates, worktreePath);
424
- return readFlow(worktreePath);
422
+ const updated = updateFlow(updates, worktreePath);
423
+ return updated ? readFlow(worktreePath) : null;
425
424
  }
426
425
 
427
426
  /**
@@ -454,16 +453,17 @@ function failWorkflow(error, worktreePath = process.cwd()) {
454
453
  function completeWorkflow(worktreePath = process.cwd()) {
455
454
  const flow = readFlow(worktreePath);
456
455
 
457
- // Clear active task from main project if projectPath is stored
458
- if (flow && flow.projectPath) {
459
- clearActiveTask(flow.projectPath);
460
- }
461
-
462
- return updateFlow({
456
+ const updated = updateFlow({
463
457
  phase: 'complete',
464
458
  status: 'completed',
465
459
  completedAt: new Date().toISOString()
466
460
  }, worktreePath);
461
+
462
+ if (updated && flow && flow.projectPath) {
463
+ clearActiveTask(flow.projectPath);
464
+ }
465
+
466
+ return updated;
467
467
  }
468
468
 
469
469
  /**
@@ -473,16 +473,17 @@ function completeWorkflow(worktreePath = process.cwd()) {
473
473
  function abortWorkflow(reason, worktreePath = process.cwd()) {
474
474
  const flow = readFlow(worktreePath);
475
475
 
476
- // Clear active task from main project if projectPath is stored
477
- if (flow && flow.projectPath) {
478
- clearActiveTask(flow.projectPath);
479
- }
480
-
481
- return updateFlow({
476
+ const updated = updateFlow({
482
477
  status: 'aborted',
483
478
  abortReason: reason,
484
479
  abortedAt: new Date().toISOString()
485
480
  }, worktreePath);
481
+
482
+ if (updated && flow && flow.projectPath) {
483
+ clearActiveTask(flow.projectPath);
484
+ }
485
+
486
+ return updated;
486
487
  }
487
488
 
488
489
  // =============================================================================
@@ -0,0 +1,61 @@
1
+ 'use strict';
2
+
3
+ const { isDeepStrictEqual } = require('util');
4
+
5
+ const RETRY_SLEEP_STATE = typeof SharedArrayBuffer === 'function' && typeof Atomics === 'object' && typeof Atomics.wait === 'function'
6
+ ? new Int32Array(new SharedArrayBuffer(4))
7
+ : null;
8
+
9
+ function isPlainObject(value) {
10
+ return Boolean(value) && typeof value === 'object' && !Array.isArray(value);
11
+ }
12
+
13
+ function hasUpdatedSubset(target, subset) {
14
+ if (!isPlainObject(subset)) {
15
+ return isDeepStrictEqual(target, subset);
16
+ }
17
+ if (!isPlainObject(target)) {
18
+ return false;
19
+ }
20
+
21
+ for (const [key, value] of Object.entries(subset)) {
22
+ if (!hasUpdatedSubset(target[key], value)) {
23
+ return false;
24
+ }
25
+ }
26
+ return true;
27
+ }
28
+
29
+ function updatesApplied(state, updates) {
30
+ if (!state) return false;
31
+
32
+ for (const [key, value] of Object.entries(updates || {})) {
33
+ if (key === '_version') continue;
34
+ if (!hasUpdatedSubset(state[key], value)) {
35
+ return false;
36
+ }
37
+ }
38
+
39
+ return true;
40
+ }
41
+
42
+ function sleepForRetry(ms) {
43
+ if (!Number.isFinite(ms) || ms <= 0) {
44
+ return;
45
+ }
46
+
47
+ const delayMs = Math.floor(ms);
48
+ if (RETRY_SLEEP_STATE) {
49
+ try {
50
+ Atomics.wait(RETRY_SLEEP_STATE, 0, 0, delayMs);
51
+ } catch {
52
+ // Ignore environments where Atomics.wait exists but cannot be used.
53
+ }
54
+ }
55
+ }
56
+
57
+ module.exports = {
58
+ isPlainObject,
59
+ updatesApplied,
60
+ sleepForRetry
61
+ };
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  name: sync-docs
3
3
  description: "Sync documentation with code. Use when user asks to update docs, check docs, fix stale documentation, update changelog, or after code changes."
4
- version: 5.0.0
4
+ version: 5.0.2
5
5
  argument-hint: "[report|apply] [--scope=all|recent|before-pr] [--include-undocumented]"
6
6
  allowed-tools: Bash(git:*), Read, Grep, Glob
7
7
  ---
@@ -63,7 +63,10 @@ Files updated (via npm version + stamp-version.js):
63
63
  // npm version updates package.json + package-lock.json, then triggers
64
64
  // the "version" lifecycle script which runs stamp-version.js.
65
65
  // Version is validated by VERSION_PATTERN above (safe for shell use).
66
- execFileSync('npm', ['version', newVersion, '--no-git-tag-version'], {
66
+ // On Windows, execFileSync does not resolve npm.cmd via PATHEXT.
67
+ // Prefer the explicit .cmd suffix when running on win32.
68
+ const npmCommand = process.platform === 'win32' ? 'npm.cmd' : 'npm';
69
+ execFileSync(npmCommand, ['version', newVersion, '--no-git-tag-version'], {
67
70
  cwd: path.join(__dirname, '..'),
68
71
  stdio: 'inherit'
69
72
  });
@@ -128,6 +128,15 @@ function cleanAll() {
128
128
  removedCount++;
129
129
  }
130
130
  }
131
+ // Remove legacy agent files from pre-rename installs
132
+ const legacyAgentFiles = ['review.md', 'ship.md', 'workflow.md'];
133
+ for (const legacyFile of legacyAgentFiles) {
134
+ const legacyPath = path.join(opencodeAgentsDir, legacyFile);
135
+ if (fs.existsSync(legacyPath)) {
136
+ fs.unlinkSync(legacyPath);
137
+ removedCount++;
138
+ }
139
+ }
131
140
  if (removedCount > 0) {
132
141
  log(` Removed ${removedCount} OpenCode agents`);
133
142
  }
@@ -12,6 +12,9 @@
12
12
 
13
13
  const fs = require('fs');
14
14
  const path = require('path');
15
+ const discovery = require('../lib/discovery');
16
+
17
+ const ROOT_DIR = path.join(__dirname, '..');
15
18
 
16
19
  const home = process.env.HOME || process.env.USERPROFILE;
17
20
 
@@ -29,6 +32,10 @@ function getOpenCodeConfigDir() {
29
32
 
30
33
  const OPENCODE_DIR = getOpenCodeConfigDir();
31
34
 
35
+ const AGENT_FILES = new Set(discovery.discoverAgents(ROOT_DIR).map(agent => agent.file));
36
+ const COMMAND_FILES = new Set(discovery.getCommandMappings(ROOT_DIR).map(([target]) => target));
37
+ const SKILL_DIRS = new Set(discovery.discoverSkills(ROOT_DIR).map(skill => skill.dir));
38
+
32
39
  const issues = [];
33
40
 
34
41
  function checkFile(filePath, checks) {
@@ -87,7 +94,7 @@ const REQUIRED_PATTERNS = {
87
94
  ]
88
95
  };
89
96
 
90
- function validateDirectory(dir, type) {
97
+ function validateDirectory(dir, type, allowlist) {
91
98
  if (!fs.existsSync(dir)) {
92
99
  console.log(`[SKIP] ${type} directory not found: ${dir}`);
93
100
  return;
@@ -99,10 +106,16 @@ function validateDirectory(dir, type) {
99
106
  for (const file of files) {
100
107
  let filePath;
101
108
  if (file.isDirectory()) {
109
+ if (allowlist && !allowlist.has(file.name)) {
110
+ continue;
111
+ }
102
112
  // For skills, check SKILL.md inside directory
103
113
  filePath = path.join(dir, file.name, 'SKILL.md');
104
114
  if (!fs.existsSync(filePath)) continue;
105
115
  } else if (file.name.endsWith('.md')) {
116
+ if (allowlist && !allowlist.has(file.name)) {
117
+ continue;
118
+ }
106
119
  filePath = path.join(dir, file.name);
107
120
  } else {
108
121
  continue;
@@ -137,9 +150,9 @@ function main() {
137
150
 
138
151
  // Validate each type
139
152
  // OpenCode expects commands directly in commands/, not a subdirectory
140
- validateDirectory(path.join(OPENCODE_DIR, 'commands'), 'commands');
141
- validateDirectory(path.join(OPENCODE_DIR, 'agents'), 'agents');
142
- validateDirectory(path.join(OPENCODE_DIR, 'skills'), 'skills');
153
+ validateDirectory(path.join(OPENCODE_DIR, 'commands'), 'commands', COMMAND_FILES);
154
+ validateDirectory(path.join(OPENCODE_DIR, 'agents'), 'agents', AGENT_FILES);
155
+ validateDirectory(path.join(OPENCODE_DIR, 'skills'), 'skills', SKILL_DIRS);
143
156
 
144
157
  // Report results
145
158
  console.log('\n--- Results ---\n');
package/site/content.json CHANGED
@@ -5,7 +5,7 @@
5
5
  "url": "https://avifenesh.github.io/agentsys",
6
6
  "repo": "https://github.com/avifenesh/agentsys",
7
7
  "npm": "https://www.npmjs.com/package/agentsys",
8
- "version": "5.0.0",
8
+ "version": "5.0.2",
9
9
  "author": "Avi Fenesh",
10
10
  "author_url": "https://github.com/avifenesh"
11
11
  },
package/site/index.html CHANGED
@@ -689,7 +689,7 @@ npm install">
689
689
  <a href="https://github.com/avifenesh/agentsys/discussions" target="_blank" rel="noopener noreferrer">Discussions</a>
690
690
  </div>
691
691
  <div class="footer__meta">
692
- <span class="footer__version" id="site-version">v4.1.0</span>
692
+ <span class="footer__version" id="site-version">v5.0.0</span>
693
693
  <span class="footer__author">Made by <a href="https://github.com/avifenesh" target="_blank" rel="noopener noreferrer">Avi Fenesh</a></span>
694
694
  </div>
695
695
  </div>