@clawmasons/mason 0.1.1 → 0.1.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 (153) hide show
  1. package/dist/acp/bridge.d.ts +92 -0
  2. package/dist/acp/bridge.d.ts.map +1 -0
  3. package/dist/acp/bridge.js +266 -0
  4. package/dist/acp/bridge.js.map +1 -0
  5. package/dist/acp/logger.d.ts +18 -0
  6. package/dist/acp/logger.d.ts.map +1 -0
  7. package/dist/acp/logger.js +35 -0
  8. package/dist/acp/logger.js.map +1 -0
  9. package/dist/acp/matcher.d.ts +60 -0
  10. package/dist/acp/matcher.d.ts.map +1 -0
  11. package/dist/acp/matcher.js +101 -0
  12. package/dist/acp/matcher.js.map +1 -0
  13. package/dist/acp/rewriter.d.ts +35 -0
  14. package/dist/acp/rewriter.d.ts.map +1 -0
  15. package/dist/acp/rewriter.js +46 -0
  16. package/dist/acp/rewriter.js.map +1 -0
  17. package/dist/acp/session.d.ts +202 -0
  18. package/dist/acp/session.d.ts.map +1 -0
  19. package/dist/acp/session.js +444 -0
  20. package/dist/acp/session.js.map +1 -0
  21. package/dist/acp/warnings.d.ts +24 -0
  22. package/dist/acp/warnings.d.ts.map +1 -0
  23. package/dist/acp/warnings.js +32 -0
  24. package/dist/acp/warnings.js.map +1 -0
  25. package/dist/cli/bin.d.ts +3 -0
  26. package/dist/cli/bin.d.ts.map +1 -0
  27. package/dist/cli/bin.js +4 -0
  28. package/dist/cli/bin.js.map +1 -0
  29. package/dist/cli/commands/build.d.ts +22 -0
  30. package/dist/cli/commands/build.d.ts.map +1 -0
  31. package/dist/cli/commands/build.js +107 -0
  32. package/dist/cli/commands/build.js.map +1 -0
  33. package/dist/cli/commands/docker-utils.d.ts +16 -0
  34. package/dist/cli/commands/docker-utils.d.ts.map +1 -0
  35. package/dist/cli/commands/docker-utils.js +54 -0
  36. package/dist/cli/commands/docker-utils.js.map +1 -0
  37. package/dist/cli/commands/index.d.ts +11 -0
  38. package/dist/cli/commands/index.d.ts.map +1 -0
  39. package/dist/cli/commands/index.js +89 -0
  40. package/dist/cli/commands/index.js.map +1 -0
  41. package/dist/cli/commands/list.d.ts +8 -0
  42. package/dist/cli/commands/list.d.ts.map +1 -0
  43. package/dist/cli/commands/list.js +60 -0
  44. package/dist/cli/commands/list.js.map +1 -0
  45. package/dist/cli/commands/package.d.ts +15 -0
  46. package/dist/cli/commands/package.d.ts.map +1 -0
  47. package/dist/cli/commands/package.js +241 -0
  48. package/dist/cli/commands/package.js.map +1 -0
  49. package/dist/cli/commands/permissions.d.ts +8 -0
  50. package/dist/cli/commands/permissions.d.ts.map +1 -0
  51. package/dist/cli/commands/permissions.js +60 -0
  52. package/dist/cli/commands/permissions.js.map +1 -0
  53. package/dist/cli/commands/proxy.d.ts +12 -0
  54. package/dist/cli/commands/proxy.d.ts.map +1 -0
  55. package/dist/cli/commands/proxy.js +253 -0
  56. package/dist/cli/commands/proxy.js.map +1 -0
  57. package/dist/cli/commands/run-agent.d.ts +149 -0
  58. package/dist/cli/commands/run-agent.d.ts.map +1 -0
  59. package/dist/cli/commands/run-agent.js +1072 -0
  60. package/dist/cli/commands/run-agent.js.map +1 -0
  61. package/dist/cli/commands/validate.d.ts +10 -0
  62. package/dist/cli/commands/validate.d.ts.map +1 -0
  63. package/dist/cli/commands/validate.js +138 -0
  64. package/dist/cli/commands/validate.js.map +1 -0
  65. package/dist/cli/index.d.ts +5 -0
  66. package/dist/cli/index.d.ts.map +1 -0
  67. package/dist/cli/index.js +18 -0
  68. package/dist/cli/index.js.map +1 -0
  69. package/dist/cli/proxy-entry.d.ts +8 -0
  70. package/dist/cli/proxy-entry.d.ts.map +1 -0
  71. package/dist/cli/proxy-entry.js +25 -0
  72. package/dist/cli/proxy-entry.js.map +1 -0
  73. package/dist/generator/agent-dockerfile.d.ts +38 -0
  74. package/dist/generator/agent-dockerfile.d.ts.map +1 -0
  75. package/dist/generator/agent-dockerfile.js +120 -0
  76. package/dist/generator/agent-dockerfile.js.map +1 -0
  77. package/dist/generator/credential-service-dockerfile.d.ts +14 -0
  78. package/dist/generator/credential-service-dockerfile.d.ts.map +1 -0
  79. package/dist/generator/credential-service-dockerfile.js +44 -0
  80. package/dist/generator/credential-service-dockerfile.js.map +1 -0
  81. package/dist/generator/index.d.ts +6 -0
  82. package/dist/generator/index.d.ts.map +1 -0
  83. package/dist/generator/index.js +6 -0
  84. package/dist/generator/index.js.map +1 -0
  85. package/dist/generator/mount-volumes.d.ts +30 -0
  86. package/dist/generator/mount-volumes.d.ts.map +1 -0
  87. package/dist/generator/mount-volumes.js +39 -0
  88. package/dist/generator/mount-volumes.js.map +1 -0
  89. package/dist/generator/proxy-dockerfile.d.ts +19 -0
  90. package/dist/generator/proxy-dockerfile.d.ts.map +1 -0
  91. package/dist/generator/proxy-dockerfile.js +59 -0
  92. package/dist/generator/proxy-dockerfile.js.map +1 -0
  93. package/dist/index.d.ts +8 -0
  94. package/dist/index.d.ts.map +1 -0
  95. package/dist/index.js +8 -0
  96. package/dist/index.js.map +1 -0
  97. package/dist/materializer/common.d.ts +17 -0
  98. package/dist/materializer/common.d.ts.map +1 -0
  99. package/dist/materializer/common.js +37 -0
  100. package/dist/materializer/common.js.map +1 -0
  101. package/dist/materializer/docker-generator.d.ts +258 -0
  102. package/dist/materializer/docker-generator.d.ts.map +1 -0
  103. package/dist/materializer/docker-generator.js +529 -0
  104. package/dist/materializer/docker-generator.js.map +1 -0
  105. package/dist/materializer/index.d.ts +9 -0
  106. package/dist/materializer/index.d.ts.map +1 -0
  107. package/dist/materializer/index.js +7 -0
  108. package/dist/materializer/index.js.map +1 -0
  109. package/dist/materializer/proxy-dependencies.d.ts +43 -0
  110. package/dist/materializer/proxy-dependencies.d.ts.map +1 -0
  111. package/dist/materializer/proxy-dependencies.js +452 -0
  112. package/dist/materializer/proxy-dependencies.js.map +1 -0
  113. package/dist/materializer/role-materializer.d.ts +56 -0
  114. package/dist/materializer/role-materializer.d.ts.map +1 -0
  115. package/dist/materializer/role-materializer.js +119 -0
  116. package/dist/materializer/role-materializer.js.map +1 -0
  117. package/dist/materializer/types.d.ts +2 -0
  118. package/dist/materializer/types.d.ts.map +1 -0
  119. package/dist/materializer/types.js +2 -0
  120. package/dist/materializer/types.js.map +1 -0
  121. package/dist/resolver/discover.d.ts +7 -0
  122. package/dist/resolver/discover.d.ts.map +1 -0
  123. package/dist/resolver/discover.js +102 -0
  124. package/dist/resolver/discover.js.map +1 -0
  125. package/dist/resolver/errors.d.ts +35 -0
  126. package/dist/resolver/errors.d.ts.map +1 -0
  127. package/dist/resolver/errors.js +62 -0
  128. package/dist/resolver/errors.js.map +1 -0
  129. package/dist/resolver/index.d.ts +5 -0
  130. package/dist/resolver/index.d.ts.map +1 -0
  131. package/dist/resolver/index.js +4 -0
  132. package/dist/resolver/index.js.map +1 -0
  133. package/dist/resolver/resolve.d.ts +8 -0
  134. package/dist/resolver/resolve.d.ts.map +1 -0
  135. package/dist/resolver/resolve.js +177 -0
  136. package/dist/resolver/resolve.js.map +1 -0
  137. package/dist/runtime/gitignore.d.ts +16 -0
  138. package/dist/runtime/gitignore.d.ts.map +1 -0
  139. package/dist/runtime/gitignore.js +37 -0
  140. package/dist/runtime/gitignore.js.map +1 -0
  141. package/dist/validator/index.d.ts +3 -0
  142. package/dist/validator/index.d.ts.map +1 -0
  143. package/dist/validator/index.js +2 -0
  144. package/dist/validator/index.js.map +1 -0
  145. package/dist/validator/types.d.ts +48 -0
  146. package/dist/validator/types.d.ts.map +1 -0
  147. package/dist/validator/types.js +2 -0
  148. package/dist/validator/types.js.map +1 -0
  149. package/dist/validator/validate.d.ts +8 -0
  150. package/dist/validator/validate.d.ts.map +1 -0
  151. package/dist/validator/validate.js +217 -0
  152. package/dist/validator/validate.js.map +1 -0
  153. package/package.json +10 -9
@@ -0,0 +1,107 @@
1
+ import * as fs from "node:fs";
2
+ import * as path from "node:path";
3
+ import { discoverRoles, adaptRoleToResolvedAgent, getAppShortName, } from "@clawmasons/shared";
4
+ import { generateRoleDockerBuildDir } from "../../materializer/docker-generator.js";
5
+ import { ensureProxyDependencies, synthesizeRolePackages, } from "../../materializer/proxy-dependencies.js";
6
+ import { inferAgentType, resolveAgentType } from "./run-agent.js";
7
+ import { ensureGitignoreEntry } from "../../runtime/gitignore.js";
8
+ /**
9
+ * Build Docker artifacts for a single role.
10
+ */
11
+ function buildRole(role, agentType, projectDir) {
12
+ const roleName = getAppShortName(role.metadata.name);
13
+ const result = generateRoleDockerBuildDir({
14
+ role,
15
+ agentType,
16
+ projectDir,
17
+ agentName: roleName,
18
+ });
19
+ return { roleName, buildDir: result.buildDir };
20
+ }
21
+ /**
22
+ * Run the build for one or all roles in the workspace.
23
+ *
24
+ * @param projectDir - Absolute path to the project root
25
+ * @param roleName - Optional role name to build (builds all if omitted)
26
+ * @param agentTypeOverride - Optional agent type override (e.g., "mcp-agent")
27
+ */
28
+ export async function runBuild(projectDir, roleName, agentTypeOverride) {
29
+ // 1. Discover roles
30
+ const roles = await discoverRoles(projectDir);
31
+ if (roles.length === 0) {
32
+ console.error("\n No roles found in workspace.\n");
33
+ process.exit(1);
34
+ return;
35
+ }
36
+ // 2. Filter to requested role(s)
37
+ let targetRoles = roles;
38
+ if (roleName) {
39
+ const match = roles.find((r) => getAppShortName(r.metadata.name) === roleName || r.metadata.name === roleName);
40
+ if (!match) {
41
+ const available = roles.map((r) => getAppShortName(r.metadata.name)).join(", ");
42
+ console.error(`\n Role "${roleName}" not found. Available: ${available}\n`);
43
+ process.exit(1);
44
+ return;
45
+ }
46
+ targetRoles = [match];
47
+ }
48
+ // 3. Validate roles via adapter round-trip
49
+ for (const role of targetRoles) {
50
+ const agentType = agentTypeOverride ?? inferAgentType(role);
51
+ try {
52
+ adaptRoleToResolvedAgent(role, agentType);
53
+ }
54
+ catch (err) {
55
+ const msg = err instanceof Error ? err.message : String(err);
56
+ console.error(`\n Validation failed for "${getAppShortName(role.metadata.name)}": ${msg}\n`);
57
+ process.exit(1);
58
+ return;
59
+ }
60
+ }
61
+ // 4. Ensure .mason/.gitignore
62
+ const masonDir = path.join(projectDir, ".mason");
63
+ fs.mkdirSync(masonDir, { recursive: true });
64
+ const gitignorePath = path.join(masonDir, ".gitignore");
65
+ if (!fs.existsSync(gitignorePath) || !fs.readFileSync(gitignorePath, "utf-8").includes("docker/")) {
66
+ fs.appendFileSync(gitignorePath, "docker/\nsessions/\n");
67
+ }
68
+ ensureGitignoreEntry(projectDir, ".mason");
69
+ // 5. Build Docker artifacts for each role
70
+ console.log(`\n Building ${targetRoles.length} role(s)...\n`);
71
+ for (const role of targetRoles) {
72
+ const agentType = agentTypeOverride ?? inferAgentType(role);
73
+ const { roleName: name } = buildRole(role, agentType, projectDir);
74
+ console.log(` ✓ ${name} (${agentType}) → .mason/docker/${name}/`);
75
+ }
76
+ // 6. Populate shared proxy dependencies (node_modules + package.json)
77
+ const dockerDir = path.join(projectDir, ".mason", "docker");
78
+ ensureProxyDependencies(dockerDir, projectDir);
79
+ // 7. Synthesize inline app/role packages for roles with mcp_servers
80
+ for (const role of targetRoles) {
81
+ synthesizeRolePackages(role, dockerDir);
82
+ }
83
+ console.log(`\n Build complete.\n`);
84
+ }
85
+ /**
86
+ * Register the `build` subcommand under `chapter`.
87
+ */
88
+ export function registerBuildCommand(program) {
89
+ program
90
+ .command("build")
91
+ .description("Build Docker artifacts for roles in the workspace")
92
+ .argument("[role]", "Role name to build (builds all if omitted)")
93
+ .option("--agent-type <type>", "Override agent type (e.g., mcp-agent, claude-code-agent)")
94
+ .action(async (role, options) => {
95
+ let agentType;
96
+ if (options.agentType) {
97
+ agentType = resolveAgentType(options.agentType);
98
+ if (!agentType) {
99
+ console.error(`\n Unknown agent type "${options.agentType}".\n`);
100
+ process.exit(1);
101
+ return;
102
+ }
103
+ }
104
+ await runBuild(process.cwd(), role, agentType);
105
+ });
106
+ }
107
+ //# sourceMappingURL=build.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"build.js","sourceRoot":"","sources":["../../../src/cli/commands/build.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,16 @@
1
+ /**
2
+ * Check that `docker compose` (v2) is available on the system.
3
+ * Throws if not found.
4
+ */
5
+ export declare function checkDockerCompose(): void;
6
+ /**
7
+ * Validate that the .env file exists and all variables have non-empty values.
8
+ * Returns the list of variable names that are missing values.
9
+ */
10
+ export declare function validateEnvFile(agentDir: string): string[];
11
+ /**
12
+ * Execute a docker compose command, streaming output to the terminal.
13
+ * Returns the exit code.
14
+ */
15
+ export declare function execDockerCompose(args: string[]): Promise<number>;
16
+ //# sourceMappingURL=docker-utils.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"docker-utils.d.ts","sourceRoot":"","sources":["../../../src/cli/commands/docker-utils.ts"],"names":[],"mappings":"AAIA;;;GAGG;AACH,wBAAgB,kBAAkB,IAAI,IAAI,CAQzC;AAED;;;GAGG;AACH,wBAAgB,eAAe,CAAC,QAAQ,EAAE,MAAM,GAAG,MAAM,EAAE,CA6B1D;AAED;;;GAGG;AACH,wBAAgB,iBAAiB,CAAC,IAAI,EAAE,MAAM,EAAE,GAAG,OAAO,CAAC,MAAM,CAAC,CAMjE"}
@@ -0,0 +1,54 @@
1
+ import * as fs from "node:fs";
2
+ import * as path from "node:path";
3
+ import { execSync, spawn } from "node:child_process";
4
+ /**
5
+ * Check that `docker compose` (v2) is available on the system.
6
+ * Throws if not found.
7
+ */
8
+ export function checkDockerCompose() {
9
+ try {
10
+ execSync("docker compose version", { stdio: "ignore" });
11
+ }
12
+ catch {
13
+ throw new Error("Docker Compose v2 is required but not found. Install Docker Desktop or the compose plugin.");
14
+ }
15
+ }
16
+ /**
17
+ * Validate that the .env file exists and all variables have non-empty values.
18
+ * Returns the list of variable names that are missing values.
19
+ */
20
+ export function validateEnvFile(agentDir) {
21
+ const envPath = path.join(agentDir, ".env");
22
+ if (!fs.existsSync(envPath)) {
23
+ throw new Error(`No .env file found at ${envPath}. Create a .env file with the required credentials.`);
24
+ }
25
+ const content = fs.readFileSync(envPath, "utf-8");
26
+ const missing = [];
27
+ for (const line of content.split("\n")) {
28
+ const trimmed = line.trim();
29
+ // Skip comments and empty lines
30
+ if (!trimmed || trimmed.startsWith("#"))
31
+ continue;
32
+ const eqIndex = trimmed.indexOf("=");
33
+ if (eqIndex === -1)
34
+ continue;
35
+ const key = trimmed.slice(0, eqIndex).trim();
36
+ const value = trimmed.slice(eqIndex + 1).trim();
37
+ if (!value) {
38
+ missing.push(key);
39
+ }
40
+ }
41
+ return missing;
42
+ }
43
+ /**
44
+ * Execute a docker compose command, streaming output to the terminal.
45
+ * Returns the exit code.
46
+ */
47
+ export function execDockerCompose(args) {
48
+ return new Promise((resolve) => {
49
+ const child = spawn("docker", args, { stdio: "inherit" });
50
+ child.on("close", (code) => resolve(code ?? 0));
51
+ child.on("error", () => resolve(1));
52
+ });
53
+ }
54
+ //# sourceMappingURL=docker-utils.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"docker-utils.js","sourceRoot":"","sources":["../../../src/cli/commands/docker-utils.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,MAAM,SAAS,CAAC;AAC9B,OAAO,KAAK,IAAI,MAAM,WAAW,CAAC;AAClC,OAAO,EAAE,QAAQ,EAAE,KAAK,EAAE,MAAM,oBAAoB,CAAC;AAErD;;;GAGG;AACH,MAAM,UAAU,kBAAkB;IAChC,IAAI,CAAC;QACH,QAAQ,CAAC,wBAAwB,EAAE,EAAE,KAAK,EAAE,QAAQ,EAAE,CAAC,CAAC;IAC1D,CAAC;IAAC,MAAM,CAAC;QACP,MAAM,IAAI,KAAK,CACb,4FAA4F,CAC7F,CAAC;IACJ,CAAC;AACH,CAAC;AAED;;;GAGG;AACH,MAAM,UAAU,eAAe,CAAC,QAAgB;IAC9C,MAAM,OAAO,GAAG,IAAI,CAAC,IAAI,CAAC,QAAQ,EAAE,MAAM,CAAC,CAAC;IAE5C,IAAI,CAAC,EAAE,CAAC,UAAU,CAAC,OAAO,CAAC,EAAE,CAAC;QAC5B,MAAM,IAAI,KAAK,CACb,yBAAyB,OAAO,qDAAqD,CACtF,CAAC;IACJ,CAAC;IAED,MAAM,OAAO,GAAG,EAAE,CAAC,YAAY,CAAC,OAAO,EAAE,OAAO,CAAC,CAAC;IAClD,MAAM,OAAO,GAAa,EAAE,CAAC;IAE7B,KAAK,MAAM,IAAI,IAAI,OAAO,CAAC,KAAK,CAAC,IAAI,CAAC,EAAE,CAAC;QACvC,MAAM,OAAO,GAAG,IAAI,CAAC,IAAI,EAAE,CAAC;QAC5B,gCAAgC;QAChC,IAAI,CAAC,OAAO,IAAI,OAAO,CAAC,UAAU,CAAC,GAAG,CAAC;YAAE,SAAS;QAElD,MAAM,OAAO,GAAG,OAAO,CAAC,OAAO,CAAC,GAAG,CAAC,CAAC;QACrC,IAAI,OAAO,KAAK,CAAC,CAAC;YAAE,SAAS;QAE7B,MAAM,GAAG,GAAG,OAAO,CAAC,KAAK,CAAC,CAAC,EAAE,OAAO,CAAC,CAAC,IAAI,EAAE,CAAC;QAC7C,MAAM,KAAK,GAAG,OAAO,CAAC,KAAK,CAAC,OAAO,GAAG,CAAC,CAAC,CAAC,IAAI,EAAE,CAAC;QAEhD,IAAI,CAAC,KAAK,EAAE,CAAC;YACX,OAAO,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC;QACpB,CAAC;IACH,CAAC;IAED,OAAO,OAAO,CAAC;AACjB,CAAC;AAED;;;GAGG;AACH,MAAM,UAAU,iBAAiB,CAAC,IAAc;IAC9C,OAAO,IAAI,OAAO,CAAC,CAAC,OAAO,EAAE,EAAE;QAC7B,MAAM,KAAK,GAAG,KAAK,CAAC,QAAQ,EAAE,IAAI,EAAE,EAAE,KAAK,EAAE,SAAS,EAAE,CAAC,CAAC;QAC1D,KAAK,CAAC,EAAE,CAAC,OAAO,EAAE,CAAC,IAAI,EAAE,EAAE,CAAC,OAAO,CAAC,IAAI,IAAI,CAAC,CAAC,CAAC,CAAC;QAChD,KAAK,CAAC,EAAE,CAAC,OAAO,EAAE,GAAG,EAAE,CAAC,OAAO,CAAC,CAAC,CAAC,CAAC,CAAC;IACtC,CAAC,CAAC,CAAC;AACL,CAAC"}
@@ -0,0 +1,11 @@
1
+ import { Command } from "commander";
2
+ /**
3
+ * Register all chapter workspace subcommands under the `chapter` subcommand group,
4
+ * and register top-level commands (`run`, `package`).
5
+ *
6
+ * Also installs shorthand detection: if the first positional argument is a known
7
+ * agent type or config-declared agent name (e.g., `mason claude --role x`), it is
8
+ * treated as `mason run claude --role x`.
9
+ */
10
+ export declare function registerCommands(program: Command): void;
11
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/cli/commands/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,OAAO,EAAqB,MAAM,WAAW,CAAC;AAUvD;;;;;;;GAOG;AACH,wBAAgB,gBAAgB,CAAC,OAAO,EAAE,OAAO,GAAG,IAAI,CAuBvD"}
@@ -0,0 +1,89 @@
1
+ import { registerBuildCommand } from "./build.js";
2
+ import { registerListCommand } from "./list.js";
3
+ import { registerPackageCommand } from "./package.js";
4
+ import { registerPermissionsCommand } from "./permissions.js";
5
+ import { registerProxyCommand } from "./proxy.js";
6
+ import { registerRunCommand, registerConfigureCommand, isKnownAgentType } from "./run-agent.js";
7
+ import { registerValidateCommand } from "./validate.js";
8
+ import { readConfigAgentNames } from "@clawmasons/agent-sdk";
9
+ /**
10
+ * Register all chapter workspace subcommands under the `chapter` subcommand group,
11
+ * and register top-level commands (`run`, `package`).
12
+ *
13
+ * Also installs shorthand detection: if the first positional argument is a known
14
+ * agent type or config-declared agent name (e.g., `mason claude --role x`), it is
15
+ * treated as `mason run claude --role x`.
16
+ */
17
+ export function registerCommands(program) {
18
+ // Top-level commands
19
+ registerRunCommand(program);
20
+ registerConfigureCommand(program);
21
+ registerPackageCommand(program);
22
+ // `chapter` subcommand group
23
+ const chapter = program
24
+ .command("chapter")
25
+ .description("Chapter workspace management commands");
26
+ registerListCommand(chapter);
27
+ registerValidateCommand(chapter);
28
+ registerPermissionsCommand(chapter);
29
+ registerBuildCommand(chapter);
30
+ registerProxyCommand(chapter);
31
+ // Read config-declared agent names synchronously so shorthand detection
32
+ // can recognise them before program.parse() fires.
33
+ const configAgentNames = new Set(readConfigAgentNames(process.cwd()));
34
+ // Shorthand detection: rewrite `mason <agent> ...` to `mason run <agent> ...`
35
+ installAgentTypeShorthand(program, configAgentNames);
36
+ }
37
+ /**
38
+ * Install a pre-parse hook that detects when the first argument is a known
39
+ * agent type or config-declared agent name (e.g., `mason claude --role x`) and
40
+ * rewrites it to `mason run claude --role x`.
41
+ */
42
+ function installAgentTypeShorthand(program, configAgentNames) {
43
+ // Collect the names of all registered commands (including subcommands)
44
+ const getKnownCommandNames = () => {
45
+ const names = new Set();
46
+ for (const cmd of program.commands) {
47
+ names.add(cmd.name());
48
+ for (const alias of cmd.aliases()) {
49
+ names.add(alias);
50
+ }
51
+ }
52
+ return names;
53
+ };
54
+ const isShorthandTarget = (arg) => isKnownAgentType(arg) || configAgentNames.has(arg);
55
+ // Hook into the pre-parse phase by overriding parse/parseAsync.
56
+ const originalParseAsync = program.parseAsync.bind(program);
57
+ program.parseAsync = async (argv, parseOptions) => {
58
+ const args = argv ? [...argv] : [...process.argv];
59
+ const fromMode = parseOptions?.from ?? "node";
60
+ const userArgStart = fromMode === "user" ? 0 : 2;
61
+ if (args.length > userArgStart) {
62
+ const firstArg = args[userArgStart];
63
+ if (firstArg && !firstArg.startsWith("-")) {
64
+ const knownCommands = getKnownCommandNames();
65
+ if (!knownCommands.has(firstArg) && isShorthandTarget(firstArg)) {
66
+ args.splice(userArgStart, 0, "run");
67
+ }
68
+ }
69
+ }
70
+ return originalParseAsync(args, parseOptions);
71
+ };
72
+ const originalParse = program.parse.bind(program);
73
+ program.parse = (argv, parseOptions) => {
74
+ const args = argv ? [...argv] : [...process.argv];
75
+ const fromMode = parseOptions?.from ?? "node";
76
+ const userArgStart = fromMode === "user" ? 0 : 2;
77
+ if (args.length > userArgStart) {
78
+ const firstArg = args[userArgStart];
79
+ if (firstArg && !firstArg.startsWith("-")) {
80
+ const knownCommands = getKnownCommandNames();
81
+ if (!knownCommands.has(firstArg) && isShorthandTarget(firstArg)) {
82
+ args.splice(userArgStart, 0, "run");
83
+ }
84
+ }
85
+ }
86
+ return originalParse(args, parseOptions);
87
+ };
88
+ }
89
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../../../src/cli/commands/index.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,oBAAoB,EAAE,MAAM,YAAY,CAAC;AAClD,OAAO,EAAE,mBAAmB,EAAE,MAAM,WAAW,CAAC;AAChD,OAAO,EAAE,sBAAsB,EAAE,MAAM,cAAc,CAAC;AACtD,OAAO,EAAE,0BAA0B,EAAE,MAAM,kBAAkB,CAAC;AAC9D,OAAO,EAAE,oBAAoB,EAAE,MAAM,YAAY,CAAC;AAClD,OAAO,EAAE,kBAAkB,EAAE,wBAAwB,EAAE,gBAAgB,EAAE,MAAM,gBAAgB,CAAC;AAChG,OAAO,EAAE,uBAAuB,EAAE,MAAM,eAAe,CAAC;AACxD,OAAO,EAAE,oBAAoB,EAAE,MAAM,uBAAuB,CAAC;AAE7D;;;;;;;GAOG;AACH,MAAM,UAAU,gBAAgB,CAAC,OAAgB;IAC/C,qBAAqB;IACrB,kBAAkB,CAAC,OAAO,CAAC,CAAC;IAC5B,wBAAwB,CAAC,OAAO,CAAC,CAAC;IAClC,sBAAsB,CAAC,OAAO,CAAC,CAAC;IAEhC,6BAA6B;IAC7B,MAAM,OAAO,GAAG,OAAO;SACpB,OAAO,CAAC,SAAS,CAAC;SAClB,WAAW,CAAC,uCAAuC,CAAC,CAAC;IAExD,mBAAmB,CAAC,OAAO,CAAC,CAAC;IAC7B,uBAAuB,CAAC,OAAO,CAAC,CAAC;IACjC,0BAA0B,CAAC,OAAO,CAAC,CAAC;IACpC,oBAAoB,CAAC,OAAO,CAAC,CAAC;IAC9B,oBAAoB,CAAC,OAAO,CAAC,CAAC;IAE9B,wEAAwE;IACxE,mDAAmD;IACnD,MAAM,gBAAgB,GAAG,IAAI,GAAG,CAAC,oBAAoB,CAAC,OAAO,CAAC,GAAG,EAAE,CAAC,CAAC,CAAC;IAEtE,8EAA8E;IAC9E,yBAAyB,CAAC,OAAO,EAAE,gBAAgB,CAAC,CAAC;AACvD,CAAC;AAED;;;;GAIG;AACH,SAAS,yBAAyB,CAAC,OAAgB,EAAE,gBAA6B;IAChF,uEAAuE;IACvE,MAAM,oBAAoB,GAAG,GAAgB,EAAE;QAC7C,MAAM,KAAK,GAAG,IAAI,GAAG,EAAU,CAAC;QAChC,KAAK,MAAM,GAAG,IAAI,OAAO,CAAC,QAAQ,EAAE,CAAC;YACnC,KAAK,CAAC,GAAG,CAAC,GAAG,CAAC,IAAI,EAAE,CAAC,CAAC;YACtB,KAAK,MAAM,KAAK,IAAI,GAAG,CAAC,OAAO,EAAE,EAAE,CAAC;gBAClC,KAAK,CAAC,GAAG,CAAC,KAAK,CAAC,CAAC;YACnB,CAAC;QACH,CAAC;QACD,OAAO,KAAK,CAAC;IACf,CAAC,CAAC;IAEF,MAAM,iBAAiB,GAAG,CAAC,GAAW,EAAW,EAAE,CACjD,gBAAgB,CAAC,GAAG,CAAC,IAAI,gBAAgB,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC;IAErD,gEAAgE;IAChE,MAAM,kBAAkB,GAAG,OAAO,CAAC,UAAU,CAAC,IAAI,CAAC,OAAO,CAAC,CAAC;IAC5D,OAAO,CAAC,UAAU,GAAG,KAAK,EAAE,IAAwB,EAAE,YAA2B,EAAE,EAAE;QACnF,MAAM,IAAI,GAAG,IAAI,CAAC,CAAC,CAAC,CAAC,GAAG,IAAI,CAAC,CAAC,CAAC,CAAC,CAAC,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC;QAClD,MAAM,QAAQ,GAAG,YAAY,EAAE,IAAI,IAAI,MAAM,CAAC;QAC9C,MAAM,YAAY,GAAG,QAAQ,KAAK,MAAM,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC;QAEjD,IAAI,IAAI,CAAC,MAAM,GAAG,YAAY,EAAE,CAAC;YAC/B,MAAM,QAAQ,GAAG,IAAI,CAAC,YAAY,CAAC,CAAC;YACpC,IAAI,QAAQ,IAAI,CAAC,QAAQ,CAAC,UAAU,CAAC,GAAG,CAAC,EAAE,CAAC;gBAC1C,MAAM,aAAa,GAAG,oBAAoB,EAAE,CAAC;gBAC7C,IAAI,CAAC,aAAa,CAAC,GAAG,CAAC,QAAQ,CAAC,IAAI,iBAAiB,CAAC,QAAQ,CAAC,EAAE,CAAC;oBAChE,IAAI,CAAC,MAAM,CAAC,YAAY,EAAE,CAAC,EAAE,KAAK,CAAC,CAAC;gBACtC,CAAC;YACH,CAAC;QACH,CAAC;QAED,OAAO,kBAAkB,CAAC,IAAI,EAAE,YAAY,CAAC,CAAC;IAChD,CAAC,CAAC;IAEF,MAAM,aAAa,GAAG,OAAO,CAAC,KAAK,CAAC,IAAI,CAAC,OAAO,CAAC,CAAC;IAClD,OAAO,CAAC,KAAK,GAAG,CAAC,IAAwB,EAAE,YAA2B,EAAE,EAAE;QACxE,MAAM,IAAI,GAAG,IAAI,CAAC,CAAC,CAAC,CAAC,GAAG,IAAI,CAAC,CAAC,CAAC,CAAC,CAAC,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC;QAClD,MAAM,QAAQ,GAAG,YAAY,EAAE,IAAI,IAAI,MAAM,CAAC;QAC9C,MAAM,YAAY,GAAG,QAAQ,KAAK,MAAM,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC;QAEjD,IAAI,IAAI,CAAC,MAAM,GAAG,YAAY,EAAE,CAAC;YAC/B,MAAM,QAAQ,GAAG,IAAI,CAAC,YAAY,CAAC,CAAC;YACpC,IAAI,QAAQ,IAAI,CAAC,QAAQ,CAAC,UAAU,CAAC,GAAG,CAAC,EAAE,CAAC;gBAC1C,MAAM,aAAa,GAAG,oBAAoB,EAAE,CAAC;gBAC7C,IAAI,CAAC,aAAa,CAAC,GAAG,CAAC,QAAQ,CAAC,IAAI,iBAAiB,CAAC,QAAQ,CAAC,EAAE,CAAC;oBAChE,IAAI,CAAC,MAAM,CAAC,YAAY,EAAE,CAAC,EAAE,KAAK,CAAC,CAAC;gBACtC,CAAC;YACH,CAAC;QACH,CAAC;QAED,OAAO,aAAa,CAAC,IAAI,EAAE,YAAY,CAAC,CAAC;IAC3C,CAAC,CAAC;AACJ,CAAC"}
@@ -0,0 +1,8 @@
1
+ import type { Command } from "commander";
2
+ interface ListOptions {
3
+ json?: boolean;
4
+ }
5
+ export declare function registerListCommand(program: Command): void;
6
+ export declare function runList(rootDir: string, options: ListOptions): Promise<void>;
7
+ export {};
8
+ //# sourceMappingURL=list.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"list.d.ts","sourceRoot":"","sources":["../../../src/cli/commands/list.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AAIzC,UAAU,WAAW;IACnB,IAAI,CAAC,EAAE,OAAO,CAAC;CAChB;AAED,wBAAgB,mBAAmB,CAAC,OAAO,EAAE,OAAO,GAAG,IAAI,CAQ1D;AAED,wBAAsB,OAAO,CAC3B,OAAO,EAAE,MAAM,EACf,OAAO,EAAE,WAAW,GACnB,OAAO,CAAC,IAAI,CAAC,CA0Bf"}
@@ -0,0 +1,60 @@
1
+ import { discoverRoles } from "@clawmasons/shared";
2
+ export function registerListCommand(program) {
3
+ program
4
+ .command("list")
5
+ .description("List available roles (local and installed packages)")
6
+ .option("--json", "Output as JSON")
7
+ .action(async (options) => {
8
+ await runList(process.cwd(), options);
9
+ });
10
+ }
11
+ export async function runList(rootDir, options) {
12
+ try {
13
+ // Discover all roles (local + packaged)
14
+ const roles = await discoverRoles(rootDir);
15
+ if (roles.length === 0) {
16
+ console.error("No roles found.");
17
+ process.exit(1);
18
+ return;
19
+ }
20
+ if (options.json) {
21
+ console.log(JSON.stringify(roles, null, 2));
22
+ return;
23
+ }
24
+ // Print role listing
25
+ console.log("\nAvailable roles:\n");
26
+ for (const role of roles) {
27
+ printRole(role);
28
+ }
29
+ }
30
+ catch (error) {
31
+ const message = error instanceof Error ? error.message : String(error);
32
+ console.error(`\nList failed: ${message}\n`);
33
+ process.exit(1);
34
+ }
35
+ }
36
+ function printRole(role) {
37
+ const source = role.source.type === "local"
38
+ ? `local, ${role.source.path ?? "unknown"}`
39
+ : `package, ${role.source.packageName ?? "unknown"}`;
40
+ const version = role.metadata.version ?? "0.0.0";
41
+ console.log(` ${role.metadata.name}@${version} (${source})`);
42
+ if (role.metadata.description) {
43
+ console.log(` ${role.metadata.description}`);
44
+ }
45
+ const children = [];
46
+ if (role.tasks.length > 0) {
47
+ children.push(`tasks: ${role.tasks.map((t) => t.name).join(", ")}`);
48
+ }
49
+ if (role.apps.length > 0) {
50
+ children.push(`apps: ${role.apps.map((a) => a.name).join(", ")}`);
51
+ }
52
+ if (role.skills.length > 0) {
53
+ children.push(`skills: ${role.skills.map((s) => s.name).join(", ")}`);
54
+ }
55
+ for (const child of children) {
56
+ console.log(` ${child}`);
57
+ }
58
+ console.log("");
59
+ }
60
+ //# sourceMappingURL=list.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"list.js","sourceRoot":"","sources":["../../../src/cli/commands/list.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,15 @@
1
+ /**
2
+ * mason package — Build and pack a role from .mason/roles/<name>/ into a
3
+ * distributable npm .tgz package.
4
+ *
5
+ * Steps:
6
+ * 1. Load ROLE.md from .mason/roles/<name>/ROLE.md
7
+ * 2. Validate all task/skill refs can be resolved from role.sources
8
+ * 3. Assemble build directory at .mason/roles/<name>/build/
9
+ * 4. Generate/merge package.json in build dir
10
+ * 5. Run npm install, npm run build (if script exists), npm pack
11
+ */
12
+ import type { Command } from "commander";
13
+ export declare function registerPackageCommand(program: Command): void;
14
+ export declare function runPackage(projectDir: string, roleName: string): Promise<void>;
15
+ //# sourceMappingURL=package.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"package.d.ts","sourceRoot":"","sources":["../../../src/cli/commands/package.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;GAUG;AAEH,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AAqBzC,wBAAgB,sBAAsB,CAAC,OAAO,EAAE,OAAO,GAAG,IAAI,CAQ7D;AAMD,wBAAsB,UAAU,CAC9B,UAAU,EAAE,MAAM,EAClB,QAAQ,EAAE,MAAM,GACf,OAAO,CAAC,IAAI,CAAC,CAoFf"}
@@ -0,0 +1,241 @@
1
+ /**
2
+ * mason package — Build and pack a role from .mason/roles/<name>/ into a
3
+ * distributable npm .tgz package.
4
+ *
5
+ * Steps:
6
+ * 1. Load ROLE.md from .mason/roles/<name>/ROLE.md
7
+ * 2. Validate all task/skill refs can be resolved from role.sources
8
+ * 3. Assemble build directory at .mason/roles/<name>/build/
9
+ * 4. Generate/merge package.json in build dir
10
+ * 5. Run npm install, npm run build (if script exists), npm pack
11
+ */
12
+ import { mkdir, writeFile, readFile, copyFile, cp, stat, readdir, } from "node:fs/promises";
13
+ import { existsSync } from "node:fs";
14
+ import { join, resolve as pathResolve, basename, extname } from "node:path";
15
+ import { spawnSync } from "node:child_process";
16
+ import { resolveRole, RoleDiscoveryError } from "@clawmasons/shared";
17
+ import { getDialectByDirectory } from "@clawmasons/shared";
18
+ // ---------------------------------------------------------------------------
19
+ // CLI registration
20
+ // ---------------------------------------------------------------------------
21
+ export function registerPackageCommand(program) {
22
+ program
23
+ .command("package")
24
+ .description("Build and pack a role from .mason/roles/<name>/ into an npm package")
25
+ .requiredOption("--role <name>", "Role name to package")
26
+ .action(async (options) => {
27
+ await runPackage(process.cwd(), options.role);
28
+ });
29
+ }
30
+ // ---------------------------------------------------------------------------
31
+ // Main orchestrator
32
+ // ---------------------------------------------------------------------------
33
+ export async function runPackage(projectDir, roleName) {
34
+ try {
35
+ // 1. Load role from .mason/roles/<name>/ROLE.md
36
+ console.log(`\n Loading role "${roleName}"...`);
37
+ let role;
38
+ try {
39
+ role = await resolveRole(roleName, projectDir);
40
+ }
41
+ catch (err) {
42
+ if (err instanceof RoleDiscoveryError) {
43
+ const expectedPath = join(projectDir, ".mason", "roles", roleName, "ROLE.md");
44
+ throw new Error(`Role "${roleName}" not found. Expected ROLE.md at: ${expectedPath}`);
45
+ }
46
+ throw err;
47
+ }
48
+ if (role.source.type !== "local") {
49
+ throw new Error(`Role "${roleName}" is an installed package, not a local role. ` +
50
+ `mason package only works with local roles in .mason/roles/.`);
51
+ }
52
+ // 2. Resolve all task/skill refs from sources
53
+ console.log(" Resolving sources...");
54
+ const { resolvedTasks, resolvedSkills, errors } = await resolveAllRefs(role, projectDir);
55
+ if (errors.length > 0) {
56
+ console.error("\n Unresolved references:");
57
+ for (const e of errors) {
58
+ console.error(` ✘ ${e}`);
59
+ }
60
+ throw new Error(`${errors.length} reference(s) could not be resolved. Fix them before packaging.`);
61
+ }
62
+ // 3. Assemble build directory
63
+ const buildDir = join(projectDir, ".mason", "roles", roleName, "build");
64
+ console.log(` Assembling build directory: ${buildDir}`);
65
+ await assembleBuild(role, buildDir, resolvedTasks, resolvedSkills);
66
+ // 4. Generate/merge package.json
67
+ await writePackageJson(role, roleName, projectDir, buildDir);
68
+ // 5. npm lifecycle
69
+ console.log(" Running npm install...");
70
+ runNpm(["install"], buildDir);
71
+ const pkg = JSON.parse(await readFile(join(buildDir, "package.json"), "utf-8"));
72
+ if (pkg.scripts?.build) {
73
+ console.log(" Running npm run build...");
74
+ runNpm(["run", "build"], buildDir);
75
+ }
76
+ console.log(" Running npm pack...");
77
+ runNpm(["pack"], buildDir);
78
+ // Report result
79
+ const tgzFiles = (await readdir(buildDir)).filter((f) => f.endsWith(".tgz"));
80
+ if (tgzFiles.length > 0) {
81
+ console.log(`\n✔ Packed: ${join(buildDir, tgzFiles[0] ?? "")}\n`);
82
+ }
83
+ else {
84
+ console.log(`\n✔ Package created in ${buildDir}\n`);
85
+ }
86
+ }
87
+ catch (error) {
88
+ const message = error instanceof Error ? error.message : String(error);
89
+ console.error(`\n✘ Package failed: ${message}\n`);
90
+ process.exit(1);
91
+ }
92
+ }
93
+ async function resolveAllRefs(role, projectDir) {
94
+ const resolvedTasks = [];
95
+ const resolvedSkills = [];
96
+ const errors = [];
97
+ const sources = role.sources ?? [];
98
+ for (const task of role.tasks ?? []) {
99
+ const resolved = await resolveRef(task, "task", sources, projectDir);
100
+ if (resolved) {
101
+ resolvedTasks.push(resolved);
102
+ }
103
+ else {
104
+ errors.push(`task "${task.name}" not found in sources: ${sources.join(", ") || "(none)"}`);
105
+ }
106
+ }
107
+ for (const skill of role.skills ?? []) {
108
+ const resolved = await resolveRef(skill, "skill", sources, projectDir);
109
+ if (resolved) {
110
+ resolvedSkills.push(resolved);
111
+ }
112
+ else {
113
+ errors.push(`skill "${skill.name}" not found in sources: ${sources.join(", ") || "(none)"}`);
114
+ }
115
+ }
116
+ return { resolvedTasks, resolvedSkills, errors };
117
+ }
118
+ async function resolveRef(ref, type, sources, projectDir) {
119
+ const name = ref.name;
120
+ // If ref has an explicit absolute path, use it directly
121
+ if (ref.ref && (ref.ref.startsWith("/") || existsSync(ref.ref))) {
122
+ const srcPath = pathResolve(projectDir, ref.ref);
123
+ const dest = type === "task"
124
+ ? `tasks/${basename(srcPath)}`
125
+ : `skills/${basename(srcPath)}`;
126
+ return { name, sourcePath: srcPath, destRelPath: dest };
127
+ }
128
+ // Otherwise scan sources directories
129
+ for (const sourceEntry of sources) {
130
+ const sourceDir = join(projectDir, sourceEntry.replace(/\/$/, ""));
131
+ // Determine which subdirectory to search based on dialect (if any)
132
+ const dirName = basename(sourceDir); // e.g., ".claude" → but sourceEntry is ".claude/"
133
+ const rawDirName = sourceEntry.replace(/^\./, "").replace(/\/$/, ""); // "claude"
134
+ const dialect = getDialectByDirectory(rawDirName);
135
+ let searchSubdir;
136
+ if (type === "task") {
137
+ // Use dialect-specific task subdir, or "tasks" as generic fallback
138
+ searchSubdir = dialect ? dialect.fieldMapping.tasks : "tasks";
139
+ }
140
+ else {
141
+ // Skills are always in "skills/" subdirectory
142
+ searchSubdir = "skills";
143
+ }
144
+ const searchDir = join(sourceDir, searchSubdir);
145
+ const found = await findFileOrDir(searchDir, name);
146
+ if (found) {
147
+ const ext = extname(found);
148
+ const destName = ext ? `${name}${ext}` : name;
149
+ const dest = type === "task" ? `tasks/${destName}` : `skills/${destName}`;
150
+ return { name, sourcePath: found, destRelPath: dest };
151
+ }
152
+ }
153
+ return undefined;
154
+ }
155
+ /**
156
+ * Find a file or directory matching <name> (with or without extension) in dir.
157
+ * Returns the absolute path if found, undefined otherwise.
158
+ */
159
+ async function findFileOrDir(dir, name) {
160
+ let entries;
161
+ try {
162
+ entries = await readdir(dir);
163
+ }
164
+ catch {
165
+ return undefined;
166
+ }
167
+ // Exact match (directory or extensionless file)
168
+ if (entries.includes(name)) {
169
+ return join(dir, name);
170
+ }
171
+ // Match with any extension (e.g., name.md)
172
+ const withExt = entries.find((e) => e.startsWith(name + "."));
173
+ if (withExt) {
174
+ return join(dir, withExt);
175
+ }
176
+ return undefined;
177
+ }
178
+ // ---------------------------------------------------------------------------
179
+ // Build directory assembly
180
+ // ---------------------------------------------------------------------------
181
+ async function assembleBuild(role, buildDir, resolvedTasks, resolvedSkills) {
182
+ await mkdir(buildDir, { recursive: true });
183
+ // Copy ROLE.md
184
+ if (role.source.path) {
185
+ const srcRoleMd = join(role.source.path, "ROLE.md");
186
+ await copyFile(srcRoleMd, join(buildDir, "ROLE.md"));
187
+ }
188
+ // Copy task files
189
+ for (const t of resolvedTasks) {
190
+ const destPath = join(buildDir, t.destRelPath);
191
+ await mkdir(join(destPath, ".."), { recursive: true });
192
+ await copyPath(t.sourcePath, destPath);
193
+ }
194
+ // Copy skill files
195
+ for (const s of resolvedSkills) {
196
+ const destPath = join(buildDir, s.destRelPath);
197
+ await mkdir(join(destPath, ".."), { recursive: true });
198
+ await copyPath(s.sourcePath, destPath);
199
+ }
200
+ }
201
+ async function copyPath(src, dest) {
202
+ const s = await stat(src);
203
+ if (s.isDirectory()) {
204
+ await cp(src, dest, { recursive: true });
205
+ }
206
+ else {
207
+ await copyFile(src, dest);
208
+ }
209
+ }
210
+ // ---------------------------------------------------------------------------
211
+ // package.json generation / merge
212
+ // ---------------------------------------------------------------------------
213
+ async function writePackageJson(role, roleName, projectDir, buildDir) {
214
+ const userPkgPath = join(projectDir, ".mason", "roles", roleName, "package.json");
215
+ let base = {
216
+ name: role.metadata.scope
217
+ ? `@${role.metadata.scope.replace(/\./g, "-")}/${roleName}`
218
+ : roleName,
219
+ version: role.metadata.version ?? "1.0.0",
220
+ description: role.metadata.description,
221
+ };
222
+ // Merge user-supplied package.json if it exists
223
+ if (existsSync(userPkgPath)) {
224
+ const userPkg = JSON.parse(await readFile(userPkgPath, "utf-8"));
225
+ base = { ...base, ...userPkg };
226
+ }
227
+ // Generated fields always win
228
+ base.chapter = { type: "role" };
229
+ base.files = ["ROLE.md", "tasks/", "skills/"];
230
+ await writeFile(join(buildDir, "package.json"), JSON.stringify(base, null, 2) + "\n");
231
+ }
232
+ // ---------------------------------------------------------------------------
233
+ // npm helpers
234
+ // ---------------------------------------------------------------------------
235
+ function runNpm(args, cwd) {
236
+ const result = spawnSync("npm", args, { cwd, stdio: "inherit" });
237
+ if (result.status !== 0) {
238
+ throw new Error(`npm ${args.join(" ")} failed with exit code ${result.status ?? "unknown"}`);
239
+ }
240
+ }
241
+ //# sourceMappingURL=package.js.map