asdm-cli 0.3.0 → 0.4.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.
package/dist/index.mjs CHANGED
@@ -856,7 +856,7 @@ var TelemetryWriter = class {
856
856
  const fullEvent = {
857
857
  timestamp: (/* @__PURE__ */ new Date()).toISOString(),
858
858
  machineId: machineId(),
859
- version: "0.3.0",
859
+ version: "0.4.0",
860
860
  ...event
861
861
  };
862
862
  const line = JSON.stringify(fullEvent) + "\n";
@@ -1004,8 +1004,77 @@ var logger = {
1004
1004
  }
1005
1005
  };
1006
1006
 
1007
+ // src/utils/prompt.ts
1008
+ import readline from "readline";
1009
+ var RESET2 = "\x1B[0m";
1010
+ var BOLD2 = "\x1B[1m";
1011
+ var DIM2 = "\x1B[2m";
1012
+ var FG_CYAN2 = "\x1B[36m";
1013
+ function renderOptions(options) {
1014
+ for (let i = 0; i < options.length; i++) {
1015
+ console.log(` ${DIM2}${i + 1}.${RESET2} ${options[i].label}`);
1016
+ }
1017
+ }
1018
+ function ask(rl, prompt) {
1019
+ return new Promise((resolve) => {
1020
+ rl.question(prompt, (answer) => resolve(answer));
1021
+ });
1022
+ }
1023
+ async function selectOne(question, options) {
1024
+ if (!process.stdin.isTTY || !process.stdout.isTTY) {
1025
+ return void 0;
1026
+ }
1027
+ const rl = readline.createInterface({ input: process.stdin, output: process.stdout });
1028
+ console.log(`
1029
+ ${BOLD2}${FG_CYAN2}${question}${RESET2} ${DIM2}(enter number)${RESET2}`);
1030
+ renderOptions(options);
1031
+ while (true) {
1032
+ const answer = await ask(rl, "\u276F ");
1033
+ const num = parseInt(answer.trim(), 10);
1034
+ if (!isNaN(num) && num >= 1 && num <= options.length) {
1035
+ rl.close();
1036
+ return options[num - 1].value;
1037
+ }
1038
+ console.log(` ${DIM2}Enter a number between 1 and ${options.length}.${RESET2}`);
1039
+ }
1040
+ }
1041
+ async function selectMany(question, options) {
1042
+ if (!process.stdin.isTTY || !process.stdout.isTTY) {
1043
+ return [];
1044
+ }
1045
+ const rl = readline.createInterface({ input: process.stdin, output: process.stdout });
1046
+ console.log(`
1047
+ ${BOLD2}${FG_CYAN2}${question}${RESET2} ${DIM2}(comma-separated numbers, e.g: 1,2)${RESET2}`);
1048
+ renderOptions(options);
1049
+ while (true) {
1050
+ const answer = await ask(rl, "\u276F ");
1051
+ const parts = answer.split(",").map((s) => s.trim()).filter(Boolean);
1052
+ const nums = parts.map((p) => parseInt(p, 10));
1053
+ const allValid = nums.length > 0 && nums.every((n) => !isNaN(n) && n >= 1 && n <= options.length);
1054
+ if (allValid) {
1055
+ rl.close();
1056
+ return nums.map((n) => options[n - 1].value);
1057
+ }
1058
+ console.log(` ${DIM2}Select at least one. Enter numbers between 1 and ${options.length}.${RESET2}`);
1059
+ }
1060
+ }
1061
+
1007
1062
  // src/cli/commands/init.ts
1008
1063
  var DEFAULT_REGISTRY = "github://lennonalvesdias/asdm";
1064
+ var DEFAULT_PROVIDERS = ["opencode"];
1065
+ var PROVIDER_OPTIONS = [
1066
+ { label: "opencode \u2014 OpenCode IDE integration (.opencode/)", value: "opencode" },
1067
+ { label: "claude-code \u2014 Claude Code IDE integration (.claude/)", value: "claude-code" },
1068
+ { label: "copilot \u2014 GitHub Copilot integration (.github/)", value: "copilot" },
1069
+ { label: "agents-dir \u2014 Cross-provider agents directory (.agents/)", value: "agents-dir" }
1070
+ ];
1071
+ var PROFILE_OPTIONS = [
1072
+ { label: "base \u2014 Base configuration with common agents and skills", value: "base" },
1073
+ { label: "data-analytics \u2014 Data analysis, SQL, pandas, and reporting", value: "data-analytics" },
1074
+ { label: "fullstack-engineer \u2014 Full-stack web development", value: "fullstack-engineer" },
1075
+ { label: "mobile \u2014 Mobile development (iOS + Android)", value: "mobile" },
1076
+ { label: "security \u2014 Security auditing and threat modeling", value: "security" }
1077
+ ];
1009
1078
  var init_default = defineCommand({
1010
1079
  meta: {
1011
1080
  name: "init",
@@ -1041,9 +1110,22 @@ var init_default = defineCommand({
1041
1110
  },
1042
1111
  async run(ctx) {
1043
1112
  const cwd = process.cwd();
1044
- const profile = ctx.args.profile || "base";
1045
1113
  const registry = ctx.args.registry || DEFAULT_REGISTRY;
1046
- const providers = ["opencode"];
1114
+ const isTTY = process.stdin.isTTY && process.stdout.isTTY;
1115
+ let profile;
1116
+ let providers;
1117
+ if (isTTY) {
1118
+ const selectedProviders = await selectMany("Select providers", PROVIDER_OPTIONS);
1119
+ providers = selectedProviders.length > 0 ? selectedProviders : DEFAULT_PROVIDERS;
1120
+ const selectedProfile = await selectOne("Select profile", PROFILE_OPTIONS);
1121
+ profile = selectedProfile ?? "base";
1122
+ console.log("");
1123
+ logger.info(` Profile: ${profile}`);
1124
+ logger.info(` Providers: ${providers.join(", ")}`);
1125
+ } else {
1126
+ profile = ctx.args.profile || "base";
1127
+ providers = DEFAULT_PROVIDERS;
1128
+ }
1047
1129
  if (ctx.args.global) {
1048
1130
  const targetPath = getGlobalConfigPath();
1049
1131
  const alreadyExists2 = await exists(targetPath);
@@ -1482,6 +1564,28 @@ function parseAsset(content, sourcePath, provider = "opencode") {
1482
1564
  }
1483
1565
 
1484
1566
  // src/core/syncer.ts
1567
+ var ADAPTER_SCAN_DIRS = {
1568
+ "opencode": [".opencode/agents", ".opencode/skills", ".opencode/commands"],
1569
+ "claude-code": [".claude/agents", ".claude/skills", ".claude/commands"],
1570
+ "copilot": [".github/agents", ".github/skills"],
1571
+ "agents-dir": [".agents"]
1572
+ };
1573
+ async function findManagedFilesInDir(dir) {
1574
+ let allFiles;
1575
+ try {
1576
+ allFiles = await listFiles(dir);
1577
+ } catch {
1578
+ return [];
1579
+ }
1580
+ const result = [];
1581
+ for (const filePath of allFiles) {
1582
+ const content = await readFile(filePath);
1583
+ if (content?.includes("ASDM MANAGED FILE")) {
1584
+ result.push(filePath);
1585
+ }
1586
+ }
1587
+ return result;
1588
+ }
1485
1589
  async function loadAdapters(providers) {
1486
1590
  const adapters = [];
1487
1591
  for (const provider of providers) {
@@ -1511,7 +1615,7 @@ async function loadAdapters(providers) {
1511
1615
  return adapters;
1512
1616
  }
1513
1617
  async function getCliVersion() {
1514
- return "0.3.0";
1618
+ return "0.4.0";
1515
1619
  }
1516
1620
  async function sync(options) {
1517
1621
  const startTime = Date.now();
@@ -1534,9 +1638,9 @@ async function sync(options) {
1534
1638
  resolvedProfile.commands
1535
1639
  );
1536
1640
  const lockfilePath = options.global ? getGlobalLockfilePath() : void 0;
1537
- const existingLockfile = options.force ? null : await readLockfile(cwd, lockfilePath);
1641
+ const existingLockfile = await readLockfile(cwd, lockfilePath);
1538
1642
  const localSourceShas = {};
1539
- if (existingLockfile) {
1643
+ if (!options.force && existingLockfile) {
1540
1644
  for (const [, entry] of Object.entries(existingLockfile.files)) {
1541
1645
  if (entry.managed && entry.source) {
1542
1646
  localSourceShas[entry.source] = entry.sha256;
@@ -1573,7 +1677,7 @@ async function sync(options) {
1573
1677
  } catch {
1574
1678
  }
1575
1679
  }
1576
- if (options.dryRun || options.noEmit) {
1680
+ if (options.noEmit) {
1577
1681
  const stats2 = {
1578
1682
  filesAdded: diff.added.length,
1579
1683
  filesUpdated: diff.updated.length,
@@ -1593,7 +1697,7 @@ async function sync(options) {
1593
1697
  durationMs: stats2.duration
1594
1698
  }).catch(() => {
1595
1699
  });
1596
- return { stats: stats2, emittedFiles: [], dryRun: !!options.dryRun };
1700
+ return { stats: stats2, emittedFiles: [], dryRun: false };
1597
1701
  }
1598
1702
  const adapters = await loadAdapters(activeProviders);
1599
1703
  const allEmittedFiles = [];
@@ -1627,6 +1731,67 @@ async function sync(options) {
1627
1731
  const configFiles = adapter.emitConfig(resolvedProfile, cwd);
1628
1732
  allEmittedFiles.push(...configFiles);
1629
1733
  }
1734
+ const newRelativePaths = new Set(allEmittedFiles.map((f) => f.relativePath));
1735
+ const orphansToDelete = [];
1736
+ if (options.clean) {
1737
+ const activeAdapterSet = new Set(
1738
+ options.provider ? [options.provider] : activeProviders
1739
+ );
1740
+ if (existingLockfile) {
1741
+ for (const [relPath, entry] of Object.entries(existingLockfile.files)) {
1742
+ if (!entry.managed || !activeAdapterSet.has(entry.adapter)) continue;
1743
+ if (newRelativePaths.has(relPath)) continue;
1744
+ let absPath;
1745
+ if (options.global) {
1746
+ const p = resolveGlobalEmitPath(relPath, entry.adapter);
1747
+ if (!p) continue;
1748
+ absPath = p;
1749
+ } else {
1750
+ absPath = path12.join(cwd, relPath);
1751
+ }
1752
+ orphansToDelete.push(absPath);
1753
+ }
1754
+ }
1755
+ if (!options.global) {
1756
+ const orphanAbsPaths = new Set(orphansToDelete);
1757
+ for (const provider of activeProviders) {
1758
+ const scanDirs = ADAPTER_SCAN_DIRS[provider] ?? [];
1759
+ for (const scanDir of scanDirs) {
1760
+ const absDir = path12.join(cwd, scanDir);
1761
+ const managed = await findManagedFilesInDir(absDir);
1762
+ for (const absFile of managed) {
1763
+ const relPath = path12.relative(cwd, absFile).split(path12.sep).join("/");
1764
+ if (!newRelativePaths.has(relPath) && !orphanAbsPaths.has(absFile)) {
1765
+ orphansToDelete.push(absFile);
1766
+ orphanAbsPaths.add(absFile);
1767
+ }
1768
+ }
1769
+ }
1770
+ }
1771
+ }
1772
+ }
1773
+ if (options.dryRun) {
1774
+ const stats2 = {
1775
+ filesAdded: diff.added.length,
1776
+ filesUpdated: diff.updated.length,
1777
+ filesUnchanged: diff.unchanged.length,
1778
+ filesRemoved: diff.removed.length + orphansToDelete.length,
1779
+ duration: Date.now() - startTime,
1780
+ manifestVersion: manifest.version,
1781
+ profile: resolvedConfig.profile,
1782
+ providers: activeProviders
1783
+ };
1784
+ options.telemetry?.write({
1785
+ event: "sync.completed",
1786
+ profile: resolvedConfig.profile,
1787
+ registry: resolvedConfig.registry,
1788
+ providers: activeProviders,
1789
+ assetCount: 0,
1790
+ durationMs: stats2.duration
1791
+ }).catch(() => {
1792
+ });
1793
+ return { stats: stats2, emittedFiles: [], dryRun: true };
1794
+ }
1630
1795
  const resolvedPaths = /* @__PURE__ */ new Map();
1631
1796
  for (const emittedFile of allEmittedFiles) {
1632
1797
  const absolutePath = options.global ? resolveGlobalEmitPath(emittedFile.relativePath, emittedFile.adapter) : path12.join(cwd, emittedFile.relativePath);
@@ -1639,6 +1804,11 @@ async function sync(options) {
1639
1804
  if (absolutePath === void 0) continue;
1640
1805
  await writeFile(absolutePath, emittedFile.content);
1641
1806
  }
1807
+ let orphanFilesRemoved = 0;
1808
+ for (const absPath of orphansToDelete) {
1809
+ await removeFile(absPath);
1810
+ orphanFilesRemoved++;
1811
+ }
1642
1812
  const lockfileFiles = {};
1643
1813
  for (const emittedFile of allEmittedFiles) {
1644
1814
  if (!resolvedPaths.has(emittedFile.relativePath)) continue;
@@ -1663,7 +1833,7 @@ async function sync(options) {
1663
1833
  filesAdded: diff.added.length,
1664
1834
  filesUpdated: diff.updated.length,
1665
1835
  filesUnchanged: diff.unchanged.length,
1666
- filesRemoved: diff.removed.length,
1836
+ filesRemoved: diff.removed.length + orphanFilesRemoved,
1667
1837
  duration: Date.now() - startTime,
1668
1838
  manifestVersion: manifest.version,
1669
1839
  profile: resolvedConfig.profile,
@@ -1719,6 +1889,11 @@ var sync_default = defineCommand2({
1719
1889
  description: "Re-download all assets even if SHA matches",
1720
1890
  default: false
1721
1891
  },
1892
+ clean: {
1893
+ type: "boolean",
1894
+ description: "Remove managed files from previous profile that are no longer in use",
1895
+ default: false
1896
+ },
1722
1897
  verbose: {
1723
1898
  type: "boolean",
1724
1899
  description: "Print verbose output",
@@ -1754,6 +1929,7 @@ var sync_default = defineCommand2({
1754
1929
  verbose,
1755
1930
  provider: ctx.args.provider,
1756
1931
  global: ctx.args.global ?? false,
1932
+ clean: ctx.args.clean,
1757
1933
  telemetry
1758
1934
  });
1759
1935
  const { stats } = result;
@@ -1774,6 +1950,7 @@ var sync_default = defineCommand2({
1774
1950
  ["Files added", String(stats.filesAdded)],
1775
1951
  ["Files updated", String(stats.filesUpdated)],
1776
1952
  ["Files unchanged", String(stats.filesUnchanged)],
1953
+ ["Files removed", String(stats.filesRemoved)],
1777
1954
  ["Duration", `${stats.duration}ms`]
1778
1955
  ]);
1779
1956
  } catch (err) {
@@ -2443,7 +2620,7 @@ var version_default = defineCommand10({
2443
2620
  description: "Print CLI version and environment info"
2444
2621
  },
2445
2622
  run(_ctx) {
2446
- console.log(`asdm v${"0.3.0"}`);
2623
+ console.log(`asdm v${"0.4.0"}`);
2447
2624
  console.log(`node ${process.version}`);
2448
2625
  console.log(`os ${os3.type()} ${os3.release()} (${process.platform})`);
2449
2626
  }
@@ -2684,7 +2861,7 @@ var doctor_default = defineCommand11({
2684
2861
  import { defineCommand as defineCommand12 } from "citty";
2685
2862
  import path17 from "path";
2686
2863
  import { promises as fs5 } from "fs";
2687
- import readline from "readline";
2864
+ import readline2 from "readline";
2688
2865
  init_fs();
2689
2866
  var LOCKFILE_NAME = ".asdm-lock.json";
2690
2867
  async function getFileSizeBytes(filePath) {
@@ -2702,7 +2879,7 @@ function formatBytes(bytes) {
2702
2879
  return `${(kb / 1024).toFixed(2)} MB`;
2703
2880
  }
2704
2881
  async function confirmPrompt(question) {
2705
- const rl = readline.createInterface({
2882
+ const rl = readline2.createInterface({
2706
2883
  input: process.stdin,
2707
2884
  output: process.stdout
2708
2885
  });
@@ -3574,7 +3751,7 @@ async function checkForUpdate(currentVersion) {
3574
3751
  var rootCommand = defineCommand17({
3575
3752
  meta: {
3576
3753
  name: "asdm",
3577
- version: "0.3.0",
3754
+ version: "0.4.0",
3578
3755
  description: "Agentic Software Delivery Model \u2014 Write Once, Emit Many"
3579
3756
  },
3580
3757
  subCommands: {
@@ -3598,8 +3775,8 @@ var rootCommand = defineCommand17({
3598
3775
  });
3599
3776
  function printUpdateBox(currentVersion, latestVersion) {
3600
3777
  const YELLOW = "\x1B[33m";
3601
- const BOLD2 = "\x1B[1m";
3602
- const RESET2 = "\x1B[0m";
3778
+ const BOLD3 = "\x1B[1m";
3779
+ const RESET3 = "\x1B[0m";
3603
3780
  const updateLine = ` Update available: ${currentVersion} \u2192 ${latestVersion}`;
3604
3781
  const cmdLine = ` Run: npm install -g asdm-cli`;
3605
3782
  const MIN_WIDTH = 45;
@@ -3612,18 +3789,18 @@ function printUpdateBox(currentVersion, latestVersion) {
3612
3789
  const r2 = `\u2502${cmdLine.padEnd(innerWidth)}\u2502`;
3613
3790
  const bot = `\u2570${"\u2500".repeat(innerWidth)}\u256F`;
3614
3791
  console.log(`
3615
- ${YELLOW}${BOLD2}${top}
3792
+ ${YELLOW}${BOLD3}${top}
3616
3793
  ${r1}
3617
3794
  ${r2}
3618
- ${bot}${RESET2}`);
3795
+ ${bot}${RESET3}`);
3619
3796
  }
3620
3797
  async function main() {
3621
3798
  await runMain(rootCommand);
3622
3799
  if (process.exitCode !== void 0 && process.exitCode !== 0) return;
3623
3800
  try {
3624
- const latestVersion = await checkForUpdate("0.3.0");
3801
+ const latestVersion = await checkForUpdate("0.4.0");
3625
3802
  if (latestVersion) {
3626
- printUpdateBox("0.3.0", latestVersion);
3803
+ printUpdateBox("0.4.0", latestVersion);
3627
3804
  }
3628
3805
  } catch {
3629
3806
  }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "asdm-cli",
3
- "version": "0.3.0",
3
+ "version": "0.4.0",
4
4
  "description": "Agentic Software Delivery Model — CLI for unified AI coding assistant governance",
5
5
  "type": "module",
6
6
  "bin": {
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "$schema": "https://asdm.dev/schemas/manifest.schema.json",
3
- "version": "0.3.0",
3
+ "version": "0.4.0",
4
4
  "policy": {
5
5
  "locked_fields": [
6
6
  "telemetry",
@@ -23,7 +23,7 @@
23
23
  "copilot",
24
24
  "agents-dir"
25
25
  ],
26
- "min_cli_version": "0.3.0"
26
+ "min_cli_version": "0.4.0"
27
27
  },
28
28
  "profiles": {
29
29
  "base": {
@@ -0,0 +1,255 @@
1
+ {
2
+ "$schema": "https://asdm.dev/schemas/manifest.schema.json",
3
+ "version": "0.4.0",
4
+ "policy": {
5
+ "locked_fields": [
6
+ "telemetry",
7
+ "install_hooks",
8
+ "auto_verify"
9
+ ],
10
+ "telemetry": true,
11
+ "auto_verify": true,
12
+ "install_hooks": true,
13
+ "allowed_profiles": [
14
+ "base",
15
+ "fullstack-engineer",
16
+ "data-analytics",
17
+ "mobile",
18
+ "security"
19
+ ],
20
+ "allowed_providers": [
21
+ "opencode",
22
+ "claude-code",
23
+ "copilot",
24
+ "agents-dir"
25
+ ],
26
+ "min_cli_version": "0.4.0"
27
+ },
28
+ "profiles": {
29
+ "base": {
30
+ "agents": [
31
+ "code-reviewer",
32
+ "documentation-writer"
33
+ ],
34
+ "skills": [
35
+ "plan-protocol",
36
+ "code-review"
37
+ ],
38
+ "commands": [
39
+ "check-file",
40
+ "summarize"
41
+ ],
42
+ "providers": [
43
+ "opencode",
44
+ "claude-code",
45
+ "copilot",
46
+ "agents-dir"
47
+ ]
48
+ },
49
+ "data-analytics": {
50
+ "extends": [
51
+ "base"
52
+ ],
53
+ "agents": [
54
+ "code-reviewer",
55
+ "data-analyst",
56
+ "documentation-writer"
57
+ ],
58
+ "skills": [
59
+ "plan-protocol",
60
+ "code-review",
61
+ "data-pipeline"
62
+ ],
63
+ "commands": [
64
+ "check-file",
65
+ "summarize",
66
+ "analyze-schema"
67
+ ],
68
+ "providers": [
69
+ "opencode",
70
+ "claude-code",
71
+ "copilot"
72
+ ]
73
+ },
74
+ "fullstack-engineer": {
75
+ "extends": [
76
+ "base"
77
+ ],
78
+ "agents": [
79
+ "code-reviewer",
80
+ "documentation-writer",
81
+ "architect",
82
+ "test-engineer"
83
+ ],
84
+ "skills": [
85
+ "plan-protocol",
86
+ "code-review",
87
+ "frontend-design",
88
+ "api-design"
89
+ ],
90
+ "commands": [
91
+ "check-file",
92
+ "summarize",
93
+ "generate-types",
94
+ "scaffold-component"
95
+ ],
96
+ "providers": [
97
+ "opencode",
98
+ "claude-code",
99
+ "copilot"
100
+ ]
101
+ },
102
+ "mobile": {
103
+ "extends": [
104
+ "base"
105
+ ],
106
+ "agents": [
107
+ "code-reviewer",
108
+ "documentation-writer",
109
+ "mobile-engineer"
110
+ ],
111
+ "skills": [
112
+ "plan-protocol",
113
+ "code-review",
114
+ "mobile-patterns"
115
+ ],
116
+ "commands": [
117
+ "check-file",
118
+ "summarize",
119
+ "scaffold-component"
120
+ ],
121
+ "providers": [
122
+ "opencode",
123
+ "claude-code",
124
+ "copilot"
125
+ ]
126
+ },
127
+ "security": {
128
+ "extends": [
129
+ "base"
130
+ ],
131
+ "agents": [
132
+ "code-reviewer",
133
+ "security-auditor",
134
+ "documentation-writer"
135
+ ],
136
+ "skills": [
137
+ "plan-protocol",
138
+ "code-review",
139
+ "threat-modeling"
140
+ ],
141
+ "commands": [
142
+ "check-file",
143
+ "summarize",
144
+ "audit-deps"
145
+ ],
146
+ "providers": [
147
+ "opencode",
148
+ "claude-code",
149
+ "copilot"
150
+ ]
151
+ }
152
+ },
153
+ "assets": {
154
+ "agents/architect.asdm.md": {
155
+ "sha256": "cac0b010fd350f9d23bfbb090327dc2e8e971be9daafa764269619224c5ca742",
156
+ "size": 3011,
157
+ "version": "1.0.0"
158
+ },
159
+ "agents/code-reviewer.asdm.md": {
160
+ "sha256": "682c73710a84ad8c40e3d8548f82811390ce3db32c6f136116afcde7f87fc75d",
161
+ "size": 2911,
162
+ "version": "1.0.0"
163
+ },
164
+ "agents/data-analyst.asdm.md": {
165
+ "sha256": "bb0ce105b9dd19eaef3be5d6b76f5ad273b4b95057d3bb2c998acbaf3dfc7589",
166
+ "size": 2865,
167
+ "version": "1.0.0"
168
+ },
169
+ "agents/documentation-writer.asdm.md": {
170
+ "sha256": "05f22780898bdc7dc9e842caab967241b99e02ca7d43d30b09ca8d19fc85d63a",
171
+ "size": 2788,
172
+ "version": "1.0.0"
173
+ },
174
+ "agents/mobile-engineer.asdm.md": {
175
+ "sha256": "ab51f952dcc8ce72cf3f48359e11c30fc7a3f5b32b534e56b04ee47cd382c3bd",
176
+ "size": 2903,
177
+ "version": "1.0.0"
178
+ },
179
+ "agents/security-auditor.asdm.md": {
180
+ "sha256": "8285378a7b30009a02f537d9fc882344c50444c1c1fe1b0ff35b8e49e475b2eb",
181
+ "size": 3167,
182
+ "version": "1.0.0"
183
+ },
184
+ "agents/test-engineer.asdm.md": {
185
+ "sha256": "e23266b82c0e3ccb96d613167c3c27d88651ff159fcb8e9b8eaf34b125681278",
186
+ "size": 2811,
187
+ "version": "1.0.0"
188
+ },
189
+ "skills/api-design/SKILL.asdm.md": {
190
+ "sha256": "637fc8014c22ddd8fa9122a44eb68cef70ffecfed724e8535b8d7d54091c579c",
191
+ "size": 3506,
192
+ "version": "1.0.0"
193
+ },
194
+ "skills/code-review/SKILL.asdm.md": {
195
+ "sha256": "de2011667b7f9e5c07cef878d43e85bb2d9fa2109c4ba64e161b6038012fab20",
196
+ "size": 3112,
197
+ "version": "1.0.0"
198
+ },
199
+ "skills/data-pipeline/SKILL.asdm.md": {
200
+ "sha256": "35e45153c4eafc4f1654b46865a226509634b3659365b03e19de482d10233699",
201
+ "size": 3686,
202
+ "version": "1.0.0"
203
+ },
204
+ "skills/frontend-design/SKILL.asdm.md": {
205
+ "sha256": "9cdddedd6f2b6caa8bafb8f8fa9864b6473c89170c4feedd05aaa9f1a30a8d3f",
206
+ "size": 3267,
207
+ "version": "1.0.0"
208
+ },
209
+ "skills/mobile-patterns/SKILL.asdm.md": {
210
+ "sha256": "9f336da4b1979cbdadad95012a4347f0e9830597f60e98e9084d6a0d07459acd",
211
+ "size": 3561,
212
+ "version": "1.0.0"
213
+ },
214
+ "skills/plan-protocol/SKILL.asdm.md": {
215
+ "sha256": "c0226a04e91caedc6dd9b51946508b9c05c29b51aa3402217c176161c0e7a16c",
216
+ "size": 2781,
217
+ "version": "1.0.0"
218
+ },
219
+ "skills/threat-modeling/SKILL.asdm.md": {
220
+ "sha256": "255ec1cc1773315b994bff8f09e647750210bc34f233c5ff83053fb6568f67e5",
221
+ "size": 4256,
222
+ "version": "1.0.0"
223
+ },
224
+ "commands/analyze-schema.asdm.md": {
225
+ "sha256": "2c855b9b02257cecc71c5a03faa05da52e215df148aa141c9258db8e0d2b6174",
226
+ "size": 2538,
227
+ "version": "1.0.0"
228
+ },
229
+ "commands/audit-deps.asdm.md": {
230
+ "sha256": "b5d54e07d9596b996090aae8e83476fb2d53b62301dd3feef82facd3d08f7150",
231
+ "size": 2781,
232
+ "version": "1.0.0"
233
+ },
234
+ "commands/check-file.asdm.md": {
235
+ "sha256": "3090793fb1eb3484626f7a4c9569df87ff486586e2e3f4046c15749003a4af73",
236
+ "size": 1700,
237
+ "version": "1.0.0"
238
+ },
239
+ "commands/generate-types.asdm.md": {
240
+ "sha256": "d1b1401c495410ee68aedc055700cfb11794228d8f363bdf6463b75e58bdff20",
241
+ "size": 2259,
242
+ "version": "1.0.0"
243
+ },
244
+ "commands/scaffold-component.asdm.md": {
245
+ "sha256": "312cf07c16a44fe334037281213aed99d8410070acbfe35e6ae0968ec8a5263f",
246
+ "size": 2327,
247
+ "version": "1.0.0"
248
+ },
249
+ "commands/summarize.asdm.md": {
250
+ "sha256": "0f52ab9a25f6f802aa2a9025d8a4e9a5825aa04ba94173884bb189566ad07ad0",
251
+ "size": 1919,
252
+ "version": "1.0.0"
253
+ }
254
+ }
255
+ }