asdm-cli 0.3.0 → 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.
package/LICENSE ADDED
@@ -0,0 +1,21 @@
1
+ MIT License
2
+
3
+ Copyright (c) 2026 asdm contributors
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in all
13
+ copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
+ SOFTWARE.
package/dist/index.mjs CHANGED
@@ -452,10 +452,26 @@ function formatAgentContent3(parsed) {
452
452
  "---",
453
453
  ""
454
454
  ].join("\n");
455
- return [managedFileHeader(ADAPTER_NAME3), "", frontmatter, parsed.body].join("\n");
455
+ return [frontmatter, "", managedFileHeader(ADAPTER_NAME3), "", parsed.body].join("\n");
456
+ }
457
+ function formatCommandAsSkill(parsed) {
458
+ const frontmatter = [
459
+ "---",
460
+ `name: ${parsed.name}`,
461
+ `description: ${parsed.description}`,
462
+ "---",
463
+ ""
464
+ ].join("\n");
465
+ return [frontmatter, "", managedFileHeader(ADAPTER_NAME3), "", parsed.body].join("\n");
456
466
  }
457
467
  function formatSkillContent3(parsed) {
458
- return [managedFileHeader(ADAPTER_NAME3), "", parsed.body].join("\n");
468
+ const frontmatter = [
469
+ "---",
470
+ `name: ${parsed.name}`,
471
+ `description: ${parsed.description}`,
472
+ "---"
473
+ ].join("\n");
474
+ return [frontmatter, "", managedFileHeader(ADAPTER_NAME3), "", parsed.body].join("\n");
459
475
  }
460
476
  function generateCopilotInstructions(profile) {
461
477
  const lines = [
@@ -473,8 +489,10 @@ function generateCopilotInstructions(profile) {
473
489
  }
474
490
  if (profile.commands.length > 0) {
475
491
  lines.push("## Commands Available", "");
492
+ lines.push("The following commands are available as Copilot skills.");
493
+ lines.push("Invoke with `/command-name` or describe the task naturally.", "");
476
494
  for (const cmd of profile.commands) {
477
- lines.push(`- **${cmd}**`);
495
+ lines.push(`- **${cmd}**: See \`.github/skills/${cmd}/SKILL.md\``);
478
496
  }
479
497
  lines.push("");
480
498
  }
@@ -510,8 +528,10 @@ var init_copilot = __esm({
510
528
  const content = formatSkillContent3(parsed);
511
529
  return [createEmittedFile(relativePath, content, ADAPTER_NAME3, parsed.sourcePath)];
512
530
  }
513
- emitCommand(_parsed, _targetDir) {
514
- return [];
531
+ emitCommand(parsed, _targetDir) {
532
+ const relativePath = `.github/skills/${parsed.name}/SKILL.md`;
533
+ const content = formatCommandAsSkill(parsed);
534
+ return [createEmittedFile(relativePath, content, ADAPTER_NAME3, parsed.sourcePath)];
515
535
  }
516
536
  emitRootInstructions(profile, _targetDir) {
517
537
  const content = generateCopilotInstructions(profile);
@@ -856,7 +876,7 @@ var TelemetryWriter = class {
856
876
  const fullEvent = {
857
877
  timestamp: (/* @__PURE__ */ new Date()).toISOString(),
858
878
  machineId: machineId(),
859
- version: "0.3.0",
879
+ version: "0.4.1",
860
880
  ...event
861
881
  };
862
882
  const line = JSON.stringify(fullEvent) + "\n";
@@ -1004,8 +1024,77 @@ var logger = {
1004
1024
  }
1005
1025
  };
1006
1026
 
1027
+ // src/utils/prompt.ts
1028
+ import readline from "readline";
1029
+ var RESET2 = "\x1B[0m";
1030
+ var BOLD2 = "\x1B[1m";
1031
+ var DIM2 = "\x1B[2m";
1032
+ var FG_CYAN2 = "\x1B[36m";
1033
+ function renderOptions(options) {
1034
+ for (let i = 0; i < options.length; i++) {
1035
+ console.log(` ${DIM2}${i + 1}.${RESET2} ${options[i].label}`);
1036
+ }
1037
+ }
1038
+ function ask(rl, prompt) {
1039
+ return new Promise((resolve) => {
1040
+ rl.question(prompt, (answer) => resolve(answer));
1041
+ });
1042
+ }
1043
+ async function selectOne(question, options) {
1044
+ if (!process.stdin.isTTY || !process.stdout.isTTY) {
1045
+ return void 0;
1046
+ }
1047
+ const rl = readline.createInterface({ input: process.stdin, output: process.stdout });
1048
+ console.log(`
1049
+ ${BOLD2}${FG_CYAN2}${question}${RESET2} ${DIM2}(enter number)${RESET2}`);
1050
+ renderOptions(options);
1051
+ while (true) {
1052
+ const answer = await ask(rl, "\u276F ");
1053
+ const num = parseInt(answer.trim(), 10);
1054
+ if (!isNaN(num) && num >= 1 && num <= options.length) {
1055
+ rl.close();
1056
+ return options[num - 1].value;
1057
+ }
1058
+ console.log(` ${DIM2}Enter a number between 1 and ${options.length}.${RESET2}`);
1059
+ }
1060
+ }
1061
+ async function selectMany(question, options) {
1062
+ if (!process.stdin.isTTY || !process.stdout.isTTY) {
1063
+ return [];
1064
+ }
1065
+ const rl = readline.createInterface({ input: process.stdin, output: process.stdout });
1066
+ console.log(`
1067
+ ${BOLD2}${FG_CYAN2}${question}${RESET2} ${DIM2}(comma-separated numbers, e.g: 1,2)${RESET2}`);
1068
+ renderOptions(options);
1069
+ while (true) {
1070
+ const answer = await ask(rl, "\u276F ");
1071
+ const parts = answer.split(",").map((s) => s.trim()).filter(Boolean);
1072
+ const nums = parts.map((p) => parseInt(p, 10));
1073
+ const allValid = nums.length > 0 && nums.every((n) => !isNaN(n) && n >= 1 && n <= options.length);
1074
+ if (allValid) {
1075
+ rl.close();
1076
+ return nums.map((n) => options[n - 1].value);
1077
+ }
1078
+ console.log(` ${DIM2}Select at least one. Enter numbers between 1 and ${options.length}.${RESET2}`);
1079
+ }
1080
+ }
1081
+
1007
1082
  // src/cli/commands/init.ts
1008
1083
  var DEFAULT_REGISTRY = "github://lennonalvesdias/asdm";
1084
+ var DEFAULT_PROVIDERS = ["opencode"];
1085
+ var PROVIDER_OPTIONS = [
1086
+ { label: "opencode \u2014 OpenCode IDE integration (.opencode/)", value: "opencode" },
1087
+ { label: "claude-code \u2014 Claude Code IDE integration (.claude/)", value: "claude-code" },
1088
+ { label: "copilot \u2014 GitHub Copilot integration (.github/)", value: "copilot" },
1089
+ { label: "agents-dir \u2014 Cross-provider agents directory (.agents/)", value: "agents-dir" }
1090
+ ];
1091
+ var PROFILE_OPTIONS = [
1092
+ { label: "base \u2014 Base configuration with common agents and skills", value: "base" },
1093
+ { label: "data-analytics \u2014 Data analysis, SQL, pandas, and reporting", value: "data-analytics" },
1094
+ { label: "fullstack-engineer \u2014 Full-stack web development", value: "fullstack-engineer" },
1095
+ { label: "mobile \u2014 Mobile development (iOS + Android)", value: "mobile" },
1096
+ { label: "security \u2014 Security auditing and threat modeling", value: "security" }
1097
+ ];
1009
1098
  var init_default = defineCommand({
1010
1099
  meta: {
1011
1100
  name: "init",
@@ -1041,9 +1130,22 @@ var init_default = defineCommand({
1041
1130
  },
1042
1131
  async run(ctx) {
1043
1132
  const cwd = process.cwd();
1044
- const profile = ctx.args.profile || "base";
1045
1133
  const registry = ctx.args.registry || DEFAULT_REGISTRY;
1046
- const providers = ["opencode"];
1134
+ const isTTY = process.stdin.isTTY && process.stdout.isTTY;
1135
+ let profile;
1136
+ let providers;
1137
+ if (isTTY) {
1138
+ const selectedProviders = await selectMany("Select providers", PROVIDER_OPTIONS);
1139
+ providers = selectedProviders.length > 0 ? selectedProviders : DEFAULT_PROVIDERS;
1140
+ const selectedProfile = await selectOne("Select profile", PROFILE_OPTIONS);
1141
+ profile = selectedProfile ?? "base";
1142
+ console.log("");
1143
+ logger.info(` Profile: ${profile}`);
1144
+ logger.info(` Providers: ${providers.join(", ")}`);
1145
+ } else {
1146
+ profile = ctx.args.profile || "base";
1147
+ providers = DEFAULT_PROVIDERS;
1148
+ }
1047
1149
  if (ctx.args.global) {
1048
1150
  const targetPath = getGlobalConfigPath();
1049
1151
  const alreadyExists2 = await exists(targetPath);
@@ -1482,6 +1584,28 @@ function parseAsset(content, sourcePath, provider = "opencode") {
1482
1584
  }
1483
1585
 
1484
1586
  // src/core/syncer.ts
1587
+ var ADAPTER_SCAN_DIRS = {
1588
+ "opencode": [".opencode/agents", ".opencode/skills", ".opencode/commands"],
1589
+ "claude-code": [".claude/agents", ".claude/skills", ".claude/commands"],
1590
+ "copilot": [".github/agents", ".github/skills"],
1591
+ "agents-dir": [".agents"]
1592
+ };
1593
+ async function findManagedFilesInDir(dir) {
1594
+ let allFiles;
1595
+ try {
1596
+ allFiles = await listFiles(dir);
1597
+ } catch {
1598
+ return [];
1599
+ }
1600
+ const result = [];
1601
+ for (const filePath of allFiles) {
1602
+ const content = await readFile(filePath);
1603
+ if (content?.includes("ASDM MANAGED FILE")) {
1604
+ result.push(filePath);
1605
+ }
1606
+ }
1607
+ return result;
1608
+ }
1485
1609
  async function loadAdapters(providers) {
1486
1610
  const adapters = [];
1487
1611
  for (const provider of providers) {
@@ -1511,7 +1635,7 @@ async function loadAdapters(providers) {
1511
1635
  return adapters;
1512
1636
  }
1513
1637
  async function getCliVersion() {
1514
- return "0.3.0";
1638
+ return "0.4.1";
1515
1639
  }
1516
1640
  async function sync(options) {
1517
1641
  const startTime = Date.now();
@@ -1534,9 +1658,9 @@ async function sync(options) {
1534
1658
  resolvedProfile.commands
1535
1659
  );
1536
1660
  const lockfilePath = options.global ? getGlobalLockfilePath() : void 0;
1537
- const existingLockfile = options.force ? null : await readLockfile(cwd, lockfilePath);
1661
+ const existingLockfile = await readLockfile(cwd, lockfilePath);
1538
1662
  const localSourceShas = {};
1539
- if (existingLockfile) {
1663
+ if (!options.force && existingLockfile) {
1540
1664
  for (const [, entry] of Object.entries(existingLockfile.files)) {
1541
1665
  if (entry.managed && entry.source) {
1542
1666
  localSourceShas[entry.source] = entry.sha256;
@@ -1573,7 +1697,7 @@ async function sync(options) {
1573
1697
  } catch {
1574
1698
  }
1575
1699
  }
1576
- if (options.dryRun || options.noEmit) {
1700
+ if (options.noEmit) {
1577
1701
  const stats2 = {
1578
1702
  filesAdded: diff.added.length,
1579
1703
  filesUpdated: diff.updated.length,
@@ -1593,7 +1717,7 @@ async function sync(options) {
1593
1717
  durationMs: stats2.duration
1594
1718
  }).catch(() => {
1595
1719
  });
1596
- return { stats: stats2, emittedFiles: [], dryRun: !!options.dryRun };
1720
+ return { stats: stats2, emittedFiles: [], dryRun: false };
1597
1721
  }
1598
1722
  const adapters = await loadAdapters(activeProviders);
1599
1723
  const allEmittedFiles = [];
@@ -1627,6 +1751,67 @@ async function sync(options) {
1627
1751
  const configFiles = adapter.emitConfig(resolvedProfile, cwd);
1628
1752
  allEmittedFiles.push(...configFiles);
1629
1753
  }
1754
+ const newRelativePaths = new Set(allEmittedFiles.map((f) => f.relativePath));
1755
+ const orphansToDelete = [];
1756
+ if (options.clean) {
1757
+ const activeAdapterSet = new Set(
1758
+ options.provider ? [options.provider] : activeProviders
1759
+ );
1760
+ if (existingLockfile) {
1761
+ for (const [relPath, entry] of Object.entries(existingLockfile.files)) {
1762
+ if (!entry.managed || !activeAdapterSet.has(entry.adapter)) continue;
1763
+ if (newRelativePaths.has(relPath)) continue;
1764
+ let absPath;
1765
+ if (options.global) {
1766
+ const p = resolveGlobalEmitPath(relPath, entry.adapter);
1767
+ if (!p) continue;
1768
+ absPath = p;
1769
+ } else {
1770
+ absPath = path12.join(cwd, relPath);
1771
+ }
1772
+ orphansToDelete.push(absPath);
1773
+ }
1774
+ }
1775
+ if (!options.global) {
1776
+ const orphanAbsPaths = new Set(orphansToDelete);
1777
+ for (const provider of activeProviders) {
1778
+ const scanDirs = ADAPTER_SCAN_DIRS[provider] ?? [];
1779
+ for (const scanDir of scanDirs) {
1780
+ const absDir = path12.join(cwd, scanDir);
1781
+ const managed = await findManagedFilesInDir(absDir);
1782
+ for (const absFile of managed) {
1783
+ const relPath = path12.relative(cwd, absFile).split(path12.sep).join("/");
1784
+ if (!newRelativePaths.has(relPath) && !orphanAbsPaths.has(absFile)) {
1785
+ orphansToDelete.push(absFile);
1786
+ orphanAbsPaths.add(absFile);
1787
+ }
1788
+ }
1789
+ }
1790
+ }
1791
+ }
1792
+ }
1793
+ if (options.dryRun) {
1794
+ const stats2 = {
1795
+ filesAdded: diff.added.length,
1796
+ filesUpdated: diff.updated.length,
1797
+ filesUnchanged: diff.unchanged.length,
1798
+ filesRemoved: diff.removed.length + orphansToDelete.length,
1799
+ duration: Date.now() - startTime,
1800
+ manifestVersion: manifest.version,
1801
+ profile: resolvedConfig.profile,
1802
+ providers: activeProviders
1803
+ };
1804
+ options.telemetry?.write({
1805
+ event: "sync.completed",
1806
+ profile: resolvedConfig.profile,
1807
+ registry: resolvedConfig.registry,
1808
+ providers: activeProviders,
1809
+ assetCount: 0,
1810
+ durationMs: stats2.duration
1811
+ }).catch(() => {
1812
+ });
1813
+ return { stats: stats2, emittedFiles: [], dryRun: true };
1814
+ }
1630
1815
  const resolvedPaths = /* @__PURE__ */ new Map();
1631
1816
  for (const emittedFile of allEmittedFiles) {
1632
1817
  const absolutePath = options.global ? resolveGlobalEmitPath(emittedFile.relativePath, emittedFile.adapter) : path12.join(cwd, emittedFile.relativePath);
@@ -1639,6 +1824,11 @@ async function sync(options) {
1639
1824
  if (absolutePath === void 0) continue;
1640
1825
  await writeFile(absolutePath, emittedFile.content);
1641
1826
  }
1827
+ let orphanFilesRemoved = 0;
1828
+ for (const absPath of orphansToDelete) {
1829
+ await removeFile(absPath);
1830
+ orphanFilesRemoved++;
1831
+ }
1642
1832
  const lockfileFiles = {};
1643
1833
  for (const emittedFile of allEmittedFiles) {
1644
1834
  if (!resolvedPaths.has(emittedFile.relativePath)) continue;
@@ -1663,7 +1853,7 @@ async function sync(options) {
1663
1853
  filesAdded: diff.added.length,
1664
1854
  filesUpdated: diff.updated.length,
1665
1855
  filesUnchanged: diff.unchanged.length,
1666
- filesRemoved: diff.removed.length,
1856
+ filesRemoved: diff.removed.length + orphanFilesRemoved,
1667
1857
  duration: Date.now() - startTime,
1668
1858
  manifestVersion: manifest.version,
1669
1859
  profile: resolvedConfig.profile,
@@ -1719,6 +1909,11 @@ var sync_default = defineCommand2({
1719
1909
  description: "Re-download all assets even if SHA matches",
1720
1910
  default: false
1721
1911
  },
1912
+ clean: {
1913
+ type: "boolean",
1914
+ description: "Remove managed files from previous profile that are no longer in use",
1915
+ default: false
1916
+ },
1722
1917
  verbose: {
1723
1918
  type: "boolean",
1724
1919
  description: "Print verbose output",
@@ -1754,6 +1949,7 @@ var sync_default = defineCommand2({
1754
1949
  verbose,
1755
1950
  provider: ctx.args.provider,
1756
1951
  global: ctx.args.global ?? false,
1952
+ clean: ctx.args.clean,
1757
1953
  telemetry
1758
1954
  });
1759
1955
  const { stats } = result;
@@ -1774,6 +1970,7 @@ var sync_default = defineCommand2({
1774
1970
  ["Files added", String(stats.filesAdded)],
1775
1971
  ["Files updated", String(stats.filesUpdated)],
1776
1972
  ["Files unchanged", String(stats.filesUnchanged)],
1973
+ ["Files removed", String(stats.filesRemoved)],
1777
1974
  ["Duration", `${stats.duration}ms`]
1778
1975
  ]);
1779
1976
  } catch (err) {
@@ -2443,7 +2640,7 @@ var version_default = defineCommand10({
2443
2640
  description: "Print CLI version and environment info"
2444
2641
  },
2445
2642
  run(_ctx) {
2446
- console.log(`asdm v${"0.3.0"}`);
2643
+ console.log(`asdm v${"0.4.1"}`);
2447
2644
  console.log(`node ${process.version}`);
2448
2645
  console.log(`os ${os3.type()} ${os3.release()} (${process.platform})`);
2449
2646
  }
@@ -2684,7 +2881,7 @@ var doctor_default = defineCommand11({
2684
2881
  import { defineCommand as defineCommand12 } from "citty";
2685
2882
  import path17 from "path";
2686
2883
  import { promises as fs5 } from "fs";
2687
- import readline from "readline";
2884
+ import readline2 from "readline";
2688
2885
  init_fs();
2689
2886
  var LOCKFILE_NAME = ".asdm-lock.json";
2690
2887
  async function getFileSizeBytes(filePath) {
@@ -2702,7 +2899,7 @@ function formatBytes(bytes) {
2702
2899
  return `${(kb / 1024).toFixed(2)} MB`;
2703
2900
  }
2704
2901
  async function confirmPrompt(question) {
2705
- const rl = readline.createInterface({
2902
+ const rl = readline2.createInterface({
2706
2903
  input: process.stdin,
2707
2904
  output: process.stdout
2708
2905
  });
@@ -3574,7 +3771,7 @@ async function checkForUpdate(currentVersion) {
3574
3771
  var rootCommand = defineCommand17({
3575
3772
  meta: {
3576
3773
  name: "asdm",
3577
- version: "0.3.0",
3774
+ version: "0.4.1",
3578
3775
  description: "Agentic Software Delivery Model \u2014 Write Once, Emit Many"
3579
3776
  },
3580
3777
  subCommands: {
@@ -3598,8 +3795,8 @@ var rootCommand = defineCommand17({
3598
3795
  });
3599
3796
  function printUpdateBox(currentVersion, latestVersion) {
3600
3797
  const YELLOW = "\x1B[33m";
3601
- const BOLD2 = "\x1B[1m";
3602
- const RESET2 = "\x1B[0m";
3798
+ const BOLD3 = "\x1B[1m";
3799
+ const RESET3 = "\x1B[0m";
3603
3800
  const updateLine = ` Update available: ${currentVersion} \u2192 ${latestVersion}`;
3604
3801
  const cmdLine = ` Run: npm install -g asdm-cli`;
3605
3802
  const MIN_WIDTH = 45;
@@ -3612,18 +3809,18 @@ function printUpdateBox(currentVersion, latestVersion) {
3612
3809
  const r2 = `\u2502${cmdLine.padEnd(innerWidth)}\u2502`;
3613
3810
  const bot = `\u2570${"\u2500".repeat(innerWidth)}\u256F`;
3614
3811
  console.log(`
3615
- ${YELLOW}${BOLD2}${top}
3812
+ ${YELLOW}${BOLD3}${top}
3616
3813
  ${r1}
3617
3814
  ${r2}
3618
- ${bot}${RESET2}`);
3815
+ ${bot}${RESET3}`);
3619
3816
  }
3620
3817
  async function main() {
3621
3818
  await runMain(rootCommand);
3622
3819
  if (process.exitCode !== void 0 && process.exitCode !== 0) return;
3623
3820
  try {
3624
- const latestVersion = await checkForUpdate("0.3.0");
3821
+ const latestVersion = await checkForUpdate("0.4.1");
3625
3822
  if (latestVersion) {
3626
- printUpdateBox("0.3.0", latestVersion);
3823
+ printUpdateBox("0.4.1", latestVersion);
3627
3824
  }
3628
3825
  } catch {
3629
3826
  }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "asdm-cli",
3
- "version": "0.3.0",
3
+ "version": "0.4.1",
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.1",
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.1"
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
+ }
@@ -0,0 +1,255 @@
1
+ {
2
+ "$schema": "https://asdm.dev/schemas/manifest.schema.json",
3
+ "version": "0.4.1",
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.1"
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
+ }