@aiwg/cli 2026.8.3 → 2026.8.5

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.
@@ -21,6 +21,9 @@ const __filename = fileURLToPath(import.meta.url);
21
21
  const __dirname = path.dirname(__filename);
22
22
  const ROOT_DIR = path.resolve(__dirname, '../..');
23
23
  const PLUGINS_DIR = path.join(ROOT_DIR, 'agentic/code/plugins');
24
+ const RELEASE_VERSION = JSON.parse(
25
+ fs.readFileSync(path.join(ROOT_DIR, 'package.json'), 'utf8'),
26
+ ).version;
24
27
 
25
28
  // Plugin configurations
26
29
  const PLUGIN_CONFIGS = {
@@ -34,6 +37,16 @@ const PLUGIN_CONFIGS = {
34
37
  commands: 'agentic/code/frameworks/sdlc-complete/commands',
35
38
  skills: 'agentic/code/frameworks/sdlc-complete/skills'
36
39
  },
40
+ extraCopy: [
41
+ { from: 'tools/security/threat-assessment.mjs', to: 'tools/security/threat-assessment.mjs' }
42
+ ],
43
+ rewrites: [
44
+ {
45
+ file: 'skills/address-issues-threat-assess/scripts/assess.mjs',
46
+ from: '../../../../../../../tools/security/threat-assessment.mjs',
47
+ to: '../../../tools/security/threat-assessment.mjs'
48
+ }
49
+ ],
37
50
  readme: `# AIWG SDLC Complete
38
51
 
39
52
  Complete Software Development Lifecycle framework with 180+ specialized agents.
@@ -81,7 +94,6 @@ Key agents include:
81
94
  description: 'Marketing automation framework with 37 specialized agents for campaign management.',
82
95
  sources: {
83
96
  agents: 'agentic/code/frameworks/media-marketing-kit/agents',
84
- commands: 'agentic/code/frameworks/media-marketing-kit/commands',
85
97
  skills: 'agentic/code/frameworks/media-marketing-kit/skills'
86
98
  },
87
99
  readme: `# AIWG Marketing Kit
@@ -213,7 +225,6 @@ Writing quality validation and AI pattern detection.
213
225
  description: 'Core AIWG utilities for context regeneration and workspace management.',
214
226
  sources: {
215
227
  agents: 'agentic/code/addons/aiwg-utils/agents',
216
- commands: 'agentic/code/addons/aiwg-utils/commands',
217
228
  skills: 'agentic/code/addons/aiwg-utils/skills'
218
229
  },
219
230
  readme: `# AIWG Utilities
@@ -292,7 +303,6 @@ Then install in Codex via the \`/plugins\` command or the repo marketplace.
292
303
  description: 'Digital forensics and incident response framework with 14 specialized agents covering target profiling, evidence acquisition, log/memory/container/cloud analysis, IOC extraction, and reporting.',
293
304
  sources: {
294
305
  agents: 'agentic/code/frameworks/forensics-complete/agents',
295
- commands: 'agentic/code/frameworks/forensics-complete/commands',
296
306
  skills: 'agentic/code/frameworks/forensics-complete/skills'
297
307
  },
298
308
  readme: `# AIWG Forensics Complete
@@ -336,7 +346,6 @@ Digital forensics and incident response framework with 14 specialized agents.
336
346
  description: 'Applied security framework for cryptographic primitive selection, chain-of-trust design, authentication factor analysis, supply-chain trust, and physical-threat modeling. Complements OWASP-style application audits.',
337
347
  sources: {
338
348
  agents: 'agentic/code/frameworks/security-engineering/agents',
339
- commands: 'agentic/code/frameworks/security-engineering/commands',
340
349
  skills: 'agentic/code/frameworks/security-engineering/skills'
341
350
  },
342
351
  readme: `# AIWG Security Engineering
@@ -383,7 +392,6 @@ Applied security engineering framework for cryptographic primitive selection, ch
383
392
  description: 'Research workflow framework with 9 specialized agents for discovery, acquisition, synthesis, citation management, GRADE quality assessment, and OAIS-compliant archival.',
384
393
  sources: {
385
394
  agents: 'agentic/code/frameworks/research-complete/agents',
386
- commands: 'agentic/code/frameworks/research-complete/commands',
387
395
  skills: 'agentic/code/frameworks/research-complete/skills'
388
396
  },
389
397
  readme: `# AIWG Research Complete
@@ -429,7 +437,6 @@ Research workflow framework with 9 specialized agents for academic and technical
429
437
  description: 'Media archive management framework with 7 specialized agents for source discovery, acquisition (yt-dlp / Internet Archive / Bandcamp), quality assessment, metadata tagging, and provenance tracking.',
430
438
  sources: {
431
439
  agents: 'agentic/code/frameworks/media-curator/agents',
432
- commands: 'agentic/code/frameworks/media-curator/commands',
433
440
  skills: 'agentic/code/frameworks/media-curator/skills'
434
441
  },
435
442
  readme: `# AIWG Media Curator
@@ -484,7 +491,6 @@ Media archive management framework with 7 specialized agents.
484
491
  description: 'Operational infrastructure framework with 12 specialized agents covering incident response, runbook execution, fleet inventory, certificate lifecycle, and disaster recovery planning.',
485
492
  sources: {
486
493
  agents: 'agentic/code/frameworks/ops-complete/agents',
487
- commands: 'agentic/code/frameworks/ops-complete/commands',
488
494
  skills: 'agentic/code/frameworks/ops-complete/skills'
489
495
  },
490
496
  readme: `# AIWG Ops Complete
@@ -603,6 +609,57 @@ Traces are written to \`.aiwg/traces/\` in JSONL format.
603
609
  }
604
610
  };
605
611
 
612
+ // Manifest-backed Claude plugins. Keep the curated framework bundles above,
613
+ // then expose every user-facing addon that contains a Claude-discoverable
614
+ // component. Copying the complete addon directory is intentional: Claude Code
615
+ // installs marketplace plugins into an isolated cache, so skills must not rely
616
+ // on ../ paths back into the AIWG monorepo for templates, schemas, or scripts.
617
+ const MANIFEST_PLUGIN_SOURCES = [
618
+ ['validation-complete', 'agentic/code/frameworks/validation-complete'],
619
+ ['agent-loop', 'agentic/code/addons/agent-loop'],
620
+ ['agent-persistence', 'agentic/code/addons/agent-persistence'],
621
+ ['agentic-installer', 'agentic/code/addons/agentic-installer'],
622
+ ['aiwg-evals', 'agentic/code/addons/aiwg-evals'],
623
+ ['aiwg-dev', 'agentic/code/addons/aiwg-dev'],
624
+ ['auto-memory', 'agentic/code/addons/auto-memory'],
625
+ ['browser-control', 'agentic/code/addons/browser-control'],
626
+ ['color-palette', 'agentic/code/addons/color-palette'],
627
+ ['context-curator', 'agentic/code/addons/context-curator'],
628
+ ['compound-memory', 'agentic/code/addons/compound-memory'],
629
+ ['daemon', 'agentic/code/addons/daemon'],
630
+ ['doc-intelligence', 'agentic/code/addons/doc-intelligence'],
631
+ ['droid-bridge', 'agentic/code/addons/droid-bridge'],
632
+ ['guided-implementation', 'agentic/code/addons/guided-implementation'],
633
+ ['line-memory', 'agentic/code/addons/line-memory'],
634
+ ['llm-wiki', 'agentic/code/addons/llm-wiki'],
635
+ ['nlp-prod', 'agentic/code/addons/nlp-prod'],
636
+ ['prose-integration', 'agentic/code/addons/prose-integration'],
637
+ ['rlm', 'agentic/code/addons/rlm'],
638
+ ['semantic-memory', 'agentic/code/addons/semantic-memory'],
639
+ ['skill-factory', 'agentic/code/addons/skill-factory'],
640
+ ['star-prompt', 'agentic/code/addons/star-prompt'],
641
+ ['testing-quality', 'agentic/code/addons/testing-quality'],
642
+ ['twelve-factor', 'agentic/code/addons/twelve-factor'],
643
+ ['uat-mcp', 'agentic/code/addons/uat-mcp'],
644
+ ['verbalized-sampling', 'agentic/code/addons/verbalized-sampling'],
645
+ ];
646
+
647
+ for (const [id, sourceRoot] of MANIFEST_PLUGIN_SOURCES) {
648
+ if (!fs.existsSync(path.join(ROOT_DIR, sourceRoot, 'manifest.json'))) continue;
649
+ const manifest = JSON.parse(
650
+ fs.readFileSync(path.join(ROOT_DIR, sourceRoot, 'manifest.json'), 'utf8'),
651
+ );
652
+ PLUGIN_CONFIGS[id] = {
653
+ name: id,
654
+ displayName: manifest.name || id,
655
+ version: manifest.version || '1.0.0',
656
+ description: manifest.description || `${manifest.name || id} for AIWG`,
657
+ keywords: manifest.keywords || manifest.tags || [],
658
+ category: manifest.category || 'productivity',
659
+ sourceRoot,
660
+ };
661
+ }
662
+
606
663
  // Parse command line arguments
607
664
  function parseArgs() {
608
665
  const args = process.argv.slice(2);
@@ -723,7 +780,7 @@ function cleanPlugin(pluginDir) {
723
780
 
724
781
  const entries = fs.readdirSync(pluginDir, { withFileTypes: true });
725
782
  for (const entry of entries) {
726
- if (entry.name === '.claude-plugin') continue;
783
+ if (entry.name.endsWith('-plugin') || entry.name === 'clawhub.json') continue;
727
784
 
728
785
  const fullPath = path.join(pluginDir, entry.name);
729
786
  if (entry.isDirectory()) {
@@ -747,6 +804,15 @@ function packagePlugin(name, config, options) {
747
804
  }
748
805
  }
749
806
 
807
+ // Copy a complete manifest-backed component so cached plugins retain every
808
+ // referenced script/template/schema. Curated legacy bundles continue to use
809
+ // their explicit source maps below.
810
+ if (config.sourceRoot) {
811
+ console.log(` šŸ“ Copying self-contained source from ${config.sourceRoot}...`);
812
+ const count = copyDir(config.sourceRoot, pluginDir, options.dryRun);
813
+ console.log(` ${count} files`);
814
+ }
815
+
750
816
  // Copy sources
751
817
  for (const [type, srcPath] of Object.entries(config.sources || {})) {
752
818
  const destPath = path.join(pluginDir, type);
@@ -761,10 +827,30 @@ function packagePlugin(name, config, options) {
761
827
  for (const extra of config.extraCopy || []) {
762
828
  const destPath = path.join(pluginDir, extra.to);
763
829
  console.log(` šŸ“ Copying ${extra.to}...`);
764
- const count = copyDir(extra.from, destPath, options.dryRun);
830
+ const sourcePath = path.join(ROOT_DIR, extra.from);
831
+ let count;
832
+ if (fs.statSync(sourcePath).isFile()) {
833
+ count = 1;
834
+ if (!options.dryRun) {
835
+ fs.mkdirSync(path.dirname(destPath), { recursive: true });
836
+ fs.copyFileSync(sourcePath, destPath);
837
+ }
838
+ } else {
839
+ count = copyDir(extra.from, destPath, options.dryRun);
840
+ }
765
841
  console.log(` ${count} files`);
766
842
  }
767
843
 
844
+ for (const rewrite of config.rewrites || []) {
845
+ if (options.dryRun) continue;
846
+ const target = path.join(pluginDir, rewrite.file);
847
+ const body = fs.readFileSync(target, 'utf8');
848
+ if (!body.includes(rewrite.from)) {
849
+ throw new Error(`${name}: rewrite source not found in ${rewrite.file}`);
850
+ }
851
+ fs.writeFileSync(target, body.replaceAll(rewrite.from, rewrite.to), 'utf8');
852
+ }
853
+
768
854
  // Write README
769
855
  if (config.readme && !options.dryRun) {
770
856
  const readmePath = path.join(pluginDir, 'README.md');
@@ -772,9 +858,74 @@ function packagePlugin(name, config, options) {
772
858
  console.log(' šŸ“„ Created README.md');
773
859
  }
774
860
 
861
+ if (!options.dryRun) {
862
+ const manifestDir = path.join(pluginDir, '.claude-plugin');
863
+ fs.mkdirSync(manifestDir, { recursive: true });
864
+ fs.writeFileSync(path.join(manifestDir, 'plugin.json'), `${JSON.stringify({
865
+ name: config.name,
866
+ // Claude caches pinned marketplace plugins by version. AIWG publishes
867
+ // these generated bundles with the repository release, so their
868
+ // distribution version must advance with package.json even when the
869
+ // canonical component's internal schema/API version does not.
870
+ version: RELEASE_VERSION,
871
+ description: config.description,
872
+ author: { name: 'AIWG Contributors', email: 'support@aiwg.io' },
873
+ homepage: 'https://aiwg.io',
874
+ repository: 'https://github.com/jmagly/aiwg',
875
+ license: 'MIT',
876
+ keywords: config.keywords || [],
877
+ }, null, 2)}\n`);
878
+ }
879
+
775
880
  console.log(` āœ… ${config.displayName} packaged successfully`);
776
881
  }
777
882
 
883
+ function writeClaudeMarketplaceManifest(options) {
884
+ const existingPath = path.join(ROOT_DIR, '.claude-plugin', 'marketplace.json');
885
+ const existing = JSON.parse(fs.readFileSync(existingPath, 'utf8'));
886
+ const external = existing.plugins
887
+ .filter((plugin) => typeof plugin.source !== 'string')
888
+ .map((plugin) => ({
889
+ ...plugin,
890
+ source: plugin.source?.type === 'github'
891
+ ? {
892
+ source: 'github',
893
+ repo: plugin.source.repo,
894
+ ...(plugin.source.branch ? { ref: plugin.source.branch } : {}),
895
+ }
896
+ : plugin.source,
897
+ }));
898
+ const local = Object.entries(PLUGIN_CONFIGS)
899
+ .filter(([, config]) => config.pluginType !== 'codex')
900
+ .map(([name, config]) => ({
901
+ name,
902
+ source: `./agentic/code/plugins/${name}`,
903
+ description: config.description,
904
+ version: RELEASE_VERSION,
905
+ author: { name: 'AIWG Contributors' },
906
+ license: 'MIT',
907
+ category: config.category || 'productivity',
908
+ keywords: config.keywords || [],
909
+ }));
910
+ const manifest = {
911
+ name: existing.name,
912
+ owner: existing.owner,
913
+ description: existing.metadata?.description || existing.description,
914
+ // The marketplace itself is a release artifact and must stay in lockstep
915
+ // with package.json. Preserving the previous manifest value silently
916
+ // leaves stale metadata after a release bump.
917
+ version: RELEASE_VERSION,
918
+ plugins: [...local, ...external],
919
+ };
920
+ if (options.dryRun) {
921
+ console.log(`\n[dry-run] Would write Claude marketplace: ${existingPath}`);
922
+ console.log(` ${manifest.plugins.length} plugins`);
923
+ return;
924
+ }
925
+ fs.writeFileSync(existingPath, `${JSON.stringify(manifest, null, 2)}\n`, 'utf8');
926
+ console.log(`\nāœ“ Wrote Claude marketplace: ${existingPath} (${manifest.plugins.length} plugins)`);
927
+ }
928
+
778
929
  // Package a Codex-format plugin (generates .codex-plugin/plugin.json + marketplace.json)
779
930
  async function packageCodexPlugin(name, config, options) {
780
931
  console.log(`\nšŸ“¦ Packaging ${config.displayName} (Codex plugin format)...`);
@@ -974,11 +1125,11 @@ async function main() {
974
1125
  // Package for each (provider, plugin) combination
975
1126
  for (const provider of providersToRun) {
976
1127
  for (const [name, config] of pluginsToPackage) {
977
- // Respect the legacy pluginType flag when selecting defaults:
978
- // if pluginType is set and provider is 'claude' (default), skip this
979
- // plugin for claude and route it to its declared pluginType instead.
980
- const effectiveProvider =
981
- provider === 'claude' && config.pluginType ? config.pluginType : provider;
1128
+ // Provider-specific bundles are not part of another provider's catalog.
1129
+ if (provider === 'claude' && config.pluginType && config.pluginType !== 'claude') {
1130
+ continue;
1131
+ }
1132
+ const effectiveProvider = provider;
982
1133
 
983
1134
  if (effectiveProvider === 'claude') {
984
1135
  packagePlugin(name, config, options);
@@ -990,8 +1141,12 @@ async function main() {
990
1141
  }
991
1142
  }
992
1143
 
1144
+ if (provider === 'claude') {
1145
+ writeClaudeMarketplaceManifest(options);
1146
+ }
1147
+
993
1148
  // After packaging for Codex, also write the root marketplace.json
994
- if (provider === 'codex' || (provider === 'claude' && pluginsToPackage.some(([, c]) => c.pluginType === 'codex'))) {
1149
+ if (provider === 'codex') {
995
1150
  writeCodexMarketplaceManifest(options);
996
1151
  }
997
1152
  }