@orderful/droid 0.47.0 → 0.50.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.
Files changed (102) hide show
  1. package/.claude-plugin/marketplace.json +1 -1
  2. package/.claude-plugin/plugin.json +4 -1
  3. package/CHANGELOG.md +34 -0
  4. package/bun.lock +137 -3
  5. package/dist/bin/droid.js +355 -90
  6. package/dist/commands/pack.d.ts +5 -0
  7. package/dist/commands/pack.d.ts.map +1 -0
  8. package/dist/index.js +11 -0
  9. package/dist/lib/pack.d.ts +31 -0
  10. package/dist/lib/pack.d.ts.map +1 -0
  11. package/dist/lib/types.d.ts +17 -0
  12. package/dist/lib/types.d.ts.map +1 -1
  13. package/dist/tools/brain/.claude-plugin/plugin.json +1 -1
  14. package/dist/tools/brain/TOOL.yaml +3 -1
  15. package/dist/tools/brain/skills/brain/SKILL.md +3 -1
  16. package/dist/tools/brain/skills/brain/references/workflows.md +4 -2
  17. package/dist/tools/coach/TOOL.yaml +4 -0
  18. package/dist/tools/code-review/.claude-plugin/plugin.json +3 -2
  19. package/dist/tools/code-review/TOOL.yaml +4 -1
  20. package/dist/tools/code-review/agents/codex-context-researcher.md +99 -0
  21. package/dist/tools/code-review/skills/code-review/SKILL.md +20 -1
  22. package/dist/tools/codex/.claude-plugin/plugin.json +1 -1
  23. package/dist/tools/codex/TOOL.yaml +3 -1
  24. package/dist/tools/codex/skills/codex/SKILL.md +5 -1
  25. package/dist/tools/codex/skills/codex/scripts/normalize-frontmatter.d.ts +61 -0
  26. package/dist/tools/codex/skills/codex/scripts/normalize-frontmatter.d.ts.map +1 -0
  27. package/dist/tools/codex/skills/codex/scripts/normalize-frontmatter.ts +402 -0
  28. package/dist/tools/comments/.claude-plugin/plugin.json +1 -1
  29. package/dist/tools/comments/TOOL.yaml +3 -1
  30. package/dist/tools/comments/skills/comments/SKILL.md +14 -0
  31. package/dist/tools/droid/.claude-plugin/plugin.json +1 -1
  32. package/dist/tools/droid/TOOL.yaml +3 -1
  33. package/dist/tools/droid/skills/droid/SKILL.md +48 -2
  34. package/dist/tools/droid/skills/droid/references/new-tool-workflow.md +234 -0
  35. package/dist/tools/edi-schema/TOOL.yaml +2 -0
  36. package/dist/tools/excalidraw/.claude-plugin/plugin.json +22 -0
  37. package/dist/tools/excalidraw/TOOL.yaml +18 -0
  38. package/dist/tools/excalidraw/commands/excalidraw.md +34 -0
  39. package/dist/tools/excalidraw/skills/excalidraw/SKILL.md +100 -0
  40. package/dist/tools/excalidraw/skills/excalidraw/references/element-templates.md +336 -0
  41. package/dist/tools/excalidraw/skills/excalidraw/references/format-spec.md +102 -0
  42. package/dist/tools/meeting/TOOL.yaml +2 -0
  43. package/dist/tools/pii/TOOL.yaml +2 -0
  44. package/dist/tools/plan/.claude-plugin/plugin.json +1 -1
  45. package/dist/tools/plan/TOOL.yaml +5 -1
  46. package/dist/tools/plan/skills/plan/SKILL.md +2 -0
  47. package/dist/tools/plan/skills/plan/references/workflows.md +11 -2
  48. package/dist/tools/project/TOOL.yaml +2 -0
  49. package/dist/tools/release/TOOL.yaml +2 -0
  50. package/dist/tools/share/TOOL.yaml +2 -0
  51. package/dist/tools/status-update/TOOL.yaml +4 -0
  52. package/dist/tools/tech-design/TOOL.yaml +2 -0
  53. package/dist/tools/wrapup/TOOL.yaml +2 -0
  54. package/package.json +3 -1
  55. package/scripts/build.ts +3 -2
  56. package/src/bin/droid.ts +9 -0
  57. package/src/commands/pack.ts +77 -0
  58. package/src/lib/pack.test.ts +85 -0
  59. package/src/lib/pack.ts +293 -0
  60. package/src/lib/types.ts +19 -0
  61. package/src/tools/brain/.claude-plugin/plugin.json +1 -1
  62. package/src/tools/brain/TOOL.yaml +3 -1
  63. package/src/tools/brain/skills/brain/SKILL.md +3 -1
  64. package/src/tools/brain/skills/brain/references/workflows.md +4 -2
  65. package/src/tools/coach/TOOL.yaml +4 -0
  66. package/src/tools/code-review/.claude-plugin/plugin.json +3 -2
  67. package/src/tools/code-review/TOOL.yaml +4 -1
  68. package/src/tools/code-review/agents/codex-context-researcher.md +99 -0
  69. package/src/tools/code-review/skills/code-review/SKILL.md +20 -1
  70. package/src/tools/codex/.claude-plugin/plugin.json +1 -1
  71. package/src/tools/codex/TOOL.yaml +3 -1
  72. package/src/tools/codex/skills/codex/SKILL.md +5 -1
  73. package/src/tools/codex/skills/codex/scripts/normalize-frontmatter.test.ts +331 -0
  74. package/src/tools/codex/skills/codex/scripts/normalize-frontmatter.ts +402 -0
  75. package/src/tools/comments/.claude-plugin/plugin.json +1 -1
  76. package/src/tools/comments/TOOL.yaml +3 -1
  77. package/src/tools/comments/skills/comments/SKILL.md +14 -0
  78. package/src/tools/droid/.claude-plugin/plugin.json +1 -1
  79. package/src/tools/droid/TOOL.yaml +3 -1
  80. package/src/tools/droid/skills/droid/SKILL.md +48 -2
  81. package/src/tools/droid/skills/droid/references/new-tool-workflow.md +234 -0
  82. package/src/tools/edi-schema/TOOL.yaml +2 -0
  83. package/src/tools/excalidraw/.claude-plugin/plugin.json +22 -0
  84. package/src/tools/excalidraw/TOOL.yaml +18 -0
  85. package/src/tools/excalidraw/commands/excalidraw.md +34 -0
  86. package/src/tools/excalidraw/skills/excalidraw/SKILL.md +100 -0
  87. package/src/tools/excalidraw/skills/excalidraw/references/element-templates.md +336 -0
  88. package/src/tools/excalidraw/skills/excalidraw/references/format-spec.md +102 -0
  89. package/src/tools/meeting/TOOL.yaml +2 -0
  90. package/src/tools/pii/TOOL.yaml +2 -0
  91. package/src/tools/plan/.claude-plugin/plugin.json +1 -1
  92. package/src/tools/plan/TOOL.yaml +5 -1
  93. package/src/tools/plan/skills/plan/SKILL.md +2 -0
  94. package/src/tools/plan/skills/plan/references/workflows.md +11 -2
  95. package/src/tools/project/TOOL.yaml +2 -0
  96. package/src/tools/release/TOOL.yaml +2 -0
  97. package/src/tools/share/TOOL.yaml +2 -0
  98. package/src/tools/status-update/TOOL.yaml +4 -0
  99. package/src/tools/tech-design/TOOL.yaml +2 -0
  100. package/src/tools/wrapup/TOOL.yaml +2 -0
  101. package/dist/tools/codex/skills/codex/scripts/git-scripts.test.ts +0 -364
  102. package/dist/tools/pii/skills/pii/scripts/presidio.test.ts +0 -444
package/dist/bin/droid.js CHANGED
@@ -2,7 +2,7 @@
2
2
 
3
3
  // src/bin/droid.ts
4
4
  import { program } from "commander";
5
- import chalk12 from "chalk";
5
+ import chalk13 from "chalk";
6
6
 
7
7
  // src/commands/setup.ts
8
8
  import inquirer from "inquirer";
@@ -37,6 +37,16 @@ function setPlatformTools(config, tools) {
37
37
  }
38
38
  config.platforms[config.platform].tools = tools;
39
39
  }
40
+ var ToolAudience = /* @__PURE__ */ ((ToolAudience2) => {
41
+ ToolAudience2["All"] = "all";
42
+ ToolAudience2["Engineering"] = "engineering";
43
+ ToolAudience2["Product"] = "product";
44
+ ToolAudience2["Design"] = "design";
45
+ ToolAudience2["IntegrationDevelopers"] = "integration-developers";
46
+ ToolAudience2["CustomerSupport"] = "customer-support";
47
+ ToolAudience2["NetworkOperations"] = "network-operations";
48
+ return ToolAudience2;
49
+ })(ToolAudience || {});
40
50
 
41
51
  // src/lib/config.ts
42
52
  var CONFIG_DIR = join(homedir(), ".droid");
@@ -5158,32 +5168,286 @@ async function execCommand(tool, script, args) {
5158
5168
  });
5159
5169
  }
5160
5170
 
5161
- // src/commands/repos.ts
5171
+ // src/commands/pack.ts
5162
5172
  import chalk10 from "chalk";
5173
+
5174
+ // src/lib/pack.ts
5175
+ import { existsSync as existsSync12, readdirSync as readdirSync7, readFileSync as readFileSync11, createWriteStream } from "fs";
5176
+ import { join as join14 } from "path";
5177
+ import archiver from "archiver";
5178
+ function getToolsForAudience(audience) {
5179
+ const allTools = getBundledTools();
5180
+ return allTools.filter((tool) => {
5181
+ if (!tool.audience || tool.audience.length === 0) {
5182
+ return false;
5183
+ }
5184
+ return tool.audience.includes(audience) || tool.audience.includes("all" /* All */);
5185
+ });
5186
+ }
5187
+ function getAudienceInfo() {
5188
+ const allTools = getBundledTools();
5189
+ const audiences = Object.values(ToolAudience).filter(
5190
+ (a) => a !== "all" /* All */
5191
+ );
5192
+ return audiences.map((audience) => {
5193
+ const tools = allTools.filter(
5194
+ (tool) => tool.audience && (tool.audience.includes(audience) || tool.audience.includes("all" /* All */))
5195
+ );
5196
+ return {
5197
+ audience,
5198
+ toolCount: tools.length,
5199
+ toolNames: tools.map((t) => t.name)
5200
+ };
5201
+ }).filter((info) => info.toolCount > 0);
5202
+ }
5203
+ function collectToolArtifacts(tool) {
5204
+ const artifacts = [];
5205
+ const toolDir = join14(getBundledToolsDir(), tool.name);
5206
+ for (const skill of tool.includes.skills) {
5207
+ const skillDir = join14(toolDir, "skills", skill.name);
5208
+ if (!existsSync12(skillDir)) continue;
5209
+ const skillMd = join14(skillDir, "SKILL.md");
5210
+ if (existsSync12(skillMd)) {
5211
+ artifacts.push({
5212
+ sourcePath: skillMd,
5213
+ zipPath: `skills/${skill.name}/SKILL.md`
5214
+ });
5215
+ }
5216
+ const refsDir = join14(skillDir, "references");
5217
+ if (existsSync12(refsDir)) {
5218
+ const refFiles = readdirSync7(refsDir).filter((f) => f.endsWith(".md"));
5219
+ for (const file of refFiles) {
5220
+ artifacts.push({
5221
+ sourcePath: join14(refsDir, file),
5222
+ zipPath: `skills/${skill.name}/references/${file}`
5223
+ });
5224
+ }
5225
+ }
5226
+ }
5227
+ const commandsDir = join14(toolDir, "commands");
5228
+ if (existsSync12(commandsDir)) {
5229
+ const commandFiles = readdirSync7(commandsDir).filter(
5230
+ (f) => f.endsWith(".md") && f.toLowerCase() !== "readme.md"
5231
+ );
5232
+ for (const file of commandFiles) {
5233
+ artifacts.push({
5234
+ sourcePath: join14(commandsDir, file),
5235
+ zipPath: `commands/${file}`
5236
+ });
5237
+ }
5238
+ }
5239
+ const agentsDir = join14(toolDir, "agents");
5240
+ if (existsSync12(agentsDir)) {
5241
+ const agentFiles = readdirSync7(agentsDir).filter(
5242
+ (f) => f.endsWith(".md") && f.toLowerCase() !== "readme.md"
5243
+ );
5244
+ for (const file of agentFiles) {
5245
+ artifacts.push({
5246
+ sourcePath: join14(agentsDir, file),
5247
+ zipPath: `agents/${file}`
5248
+ });
5249
+ }
5250
+ }
5251
+ return artifacts;
5252
+ }
5253
+ function generateClaudeMd(tools) {
5254
+ const skillNames = [];
5255
+ for (const tool of tools) {
5256
+ for (const skill of tool.includes.skills) {
5257
+ skillNames.push(skill.name);
5258
+ }
5259
+ }
5260
+ const lines = [
5261
+ "# Droid Skills",
5262
+ "",
5263
+ "Skills installed from a Droid pack. Each skill teaches your AI new capabilities.",
5264
+ ""
5265
+ ];
5266
+ for (const name of skillNames) {
5267
+ lines.push(`- [${name}](skills/${name}/SKILL.md)`);
5268
+ }
5269
+ lines.push("");
5270
+ return lines.join("\n");
5271
+ }
5272
+ function generateReadme(audience, tools) {
5273
+ const lines = [
5274
+ `# Droid Pack: ${audience}`,
5275
+ "",
5276
+ "This pack contains AI skills, commands, and agents for Claude Desktop.",
5277
+ "",
5278
+ "## Installation",
5279
+ "",
5280
+ "1. Unzip this archive",
5281
+ "2. Copy the contents into your `~/.claude/` directory:",
5282
+ "",
5283
+ "```bash",
5284
+ "# From the directory where you unzipped:",
5285
+ "cp -r skills/ ~/.claude/skills/",
5286
+ "cp -r commands/ ~/.claude/commands/",
5287
+ "cp -r agents/ ~/.claude/agents/",
5288
+ "```",
5289
+ "",
5290
+ "3. Append the contents of `CLAUDE.md` to your `~/.claude/CLAUDE.md`:",
5291
+ "",
5292
+ "```bash",
5293
+ "cat CLAUDE.md >> ~/.claude/CLAUDE.md",
5294
+ "```",
5295
+ "",
5296
+ "## Included Tools",
5297
+ ""
5298
+ ];
5299
+ for (const tool of tools) {
5300
+ lines.push(`- **${tool.name}** (v${tool.version}) \u2014 ${tool.description}`);
5301
+ }
5302
+ lines.push("");
5303
+ return lines.join("\n");
5304
+ }
5305
+ function checkDependencies(tools) {
5306
+ const warnings = [];
5307
+ const toolNames = new Set(tools.map((t) => t.name));
5308
+ for (const tool of tools) {
5309
+ if (!tool.dependencies) continue;
5310
+ for (const dep of tool.dependencies) {
5311
+ if (!toolNames.has(dep)) {
5312
+ warnings.push(
5313
+ `Tool '${tool.name}' depends on '${dep}' which is not included in this pack`
5314
+ );
5315
+ }
5316
+ }
5317
+ }
5318
+ return warnings;
5319
+ }
5320
+ async function buildPack(options) {
5321
+ const { audience, outputDir } = options;
5322
+ const tools = getToolsForAudience(audience);
5323
+ if (tools.length === 0) {
5324
+ return {
5325
+ success: false,
5326
+ message: `No tools found for audience '${audience}'`
5327
+ };
5328
+ }
5329
+ const warnings = checkDependencies(tools);
5330
+ const filename = `droid-${audience}-pack.zip`;
5331
+ const outputPath = join14(outputDir, filename);
5332
+ return new Promise((resolve) => {
5333
+ const output = createWriteStream(outputPath);
5334
+ const archive = archiver("zip", { zlib: { level: 9 } });
5335
+ output.on("close", () => {
5336
+ resolve({
5337
+ success: true,
5338
+ message: `Pack created: ${filename}`,
5339
+ outputPath,
5340
+ toolCount: tools.length,
5341
+ warnings: warnings.length > 0 ? warnings : void 0
5342
+ });
5343
+ });
5344
+ archive.on("error", (err) => {
5345
+ resolve({
5346
+ success: false,
5347
+ message: `Failed to create pack: ${err.message}`
5348
+ });
5349
+ });
5350
+ archive.pipe(output);
5351
+ for (const tool of tools) {
5352
+ const artifacts = collectToolArtifacts(tool);
5353
+ for (const artifact of artifacts) {
5354
+ const content = readFileSync11(artifact.sourcePath, "utf-8");
5355
+ archive.append(content, { name: artifact.zipPath });
5356
+ }
5357
+ }
5358
+ archive.append(generateClaudeMd(tools), { name: "CLAUDE.md" });
5359
+ archive.append(generateReadme(audience, tools), { name: "README.md" });
5360
+ archive.finalize();
5361
+ });
5362
+ }
5363
+
5364
+ // src/commands/pack.ts
5365
+ function isValidAudience(value) {
5366
+ return Object.values(ToolAudience).includes(value);
5367
+ }
5368
+ async function packCommand(audience, options) {
5369
+ if (options.list) {
5370
+ const infos = getAudienceInfo();
5371
+ if (infos.length === 0) {
5372
+ console.log(chalk10.yellow("No tools with audience metadata found."));
5373
+ return;
5374
+ }
5375
+ console.log(chalk10.bold("\nAvailable audiences:\n"));
5376
+ for (const info of infos) {
5377
+ console.log(
5378
+ ` ${chalk10.cyan(info.audience.padEnd(24))} ${chalk10.gray(`${info.toolCount} tools`)} ${chalk10.gray(info.toolNames.join(", "))}`
5379
+ );
5380
+ }
5381
+ console.log("");
5382
+ return;
5383
+ }
5384
+ if (!audience) {
5385
+ console.error(chalk10.red("\nError: audience argument required"));
5386
+ console.log(chalk10.gray("Usage: droid pack <audience>"));
5387
+ console.log(chalk10.gray(" droid pack --list"));
5388
+ process.exit(1);
5389
+ }
5390
+ if (!isValidAudience(audience)) {
5391
+ console.error(chalk10.red(`
5392
+ Error: unknown audience '${audience}'`));
5393
+ console.log(chalk10.gray("\nValid audiences:"));
5394
+ for (const a of Object.values(ToolAudience)) {
5395
+ if (a !== "all" /* All */) {
5396
+ console.log(chalk10.gray(` - ${a}`));
5397
+ }
5398
+ }
5399
+ process.exit(1);
5400
+ }
5401
+ const outputDir = options.output || process.cwd();
5402
+ console.log(
5403
+ chalk10.bold(`
5404
+ Packing tools for ${chalk10.cyan(audience)}...`)
5405
+ );
5406
+ const result = await buildPack({ audience, outputDir });
5407
+ if (!result.success) {
5408
+ console.error(chalk10.red(`
5409
+ ${result.message}`));
5410
+ process.exit(1);
5411
+ }
5412
+ console.log(chalk10.green(`
5413
+ ${result.message}`));
5414
+ console.log(chalk10.gray(` ${result.toolCount} tools included`));
5415
+ console.log(chalk10.gray(` Output: ${result.outputPath}`));
5416
+ if (result.warnings && result.warnings.length > 0) {
5417
+ console.log(chalk10.yellow("\nWarnings:"));
5418
+ for (const warning of result.warnings) {
5419
+ console.log(chalk10.yellow(` - ${warning}`));
5420
+ }
5421
+ }
5422
+ console.log("");
5423
+ }
5424
+
5425
+ // src/commands/repos.ts
5426
+ import chalk11 from "chalk";
5163
5427
  import inquirer4 from "inquirer";
5164
5428
  async function reposListCommand(options) {
5165
5429
  const repos2 = getRepos();
5166
5430
  if (repos2.length === 0) {
5167
- console.log(chalk10.yellow("No repos configured."));
5168
- console.log(chalk10.gray("\nAdd a repo with:"));
5169
- console.log(chalk10.gray(" droid repos add <name>"));
5431
+ console.log(chalk11.yellow("No repos configured."));
5432
+ console.log(chalk11.gray("\nAdd a repo with:"));
5433
+ console.log(chalk11.gray(" droid repos add <name>"));
5170
5434
  return;
5171
5435
  }
5172
5436
  if (options?.json) {
5173
5437
  console.log(JSON.stringify(repos2, null, 2));
5174
5438
  return;
5175
5439
  }
5176
- console.log(chalk10.bold("\n\u{1F4E6} Registered Repos\n"));
5440
+ console.log(chalk11.bold("\n\u{1F4E6} Registered Repos\n"));
5177
5441
  for (const repo of repos2) {
5178
5442
  const expandedPath = getRepoPath(repo.name);
5179
- console.log(chalk10.cyan(`${repo.name}`));
5180
- console.log(chalk10.gray(` Path: ${expandedPath}`));
5443
+ console.log(chalk11.cyan(`${repo.name}`));
5444
+ console.log(chalk11.gray(` Path: ${expandedPath}`));
5181
5445
  if (repo.description) {
5182
- console.log(chalk10.gray(` ${repo.description}`));
5446
+ console.log(chalk11.gray(` ${repo.description}`));
5183
5447
  }
5184
5448
  if (repo.release_branch) {
5185
5449
  const prod = repo.production_branch || "master";
5186
- console.log(chalk10.gray(` Release: ${repo.release_branch} \u2192 ${prod}`));
5450
+ console.log(chalk11.gray(` Release: ${repo.release_branch} \u2192 ${prod}`));
5187
5451
  }
5188
5452
  console.log();
5189
5453
  }
@@ -5246,7 +5510,7 @@ async function reposAddCommand(name, path, description) {
5246
5510
  productionBranch = prodAnswers.production_branch || "master";
5247
5511
  }
5248
5512
  if (!repoName || !repoPath) {
5249
- console.error(chalk10.red("Name and path are required"));
5513
+ console.error(chalk11.red("Name and path are required"));
5250
5514
  return;
5251
5515
  }
5252
5516
  const repo = {
@@ -5258,11 +5522,11 @@ async function reposAddCommand(name, path, description) {
5258
5522
  };
5259
5523
  addRepo(repo);
5260
5524
  const expandedPath = getRepoPath(repoName);
5261
- console.log(chalk10.green(`
5525
+ console.log(chalk11.green(`
5262
5526
  \u2713 Added repo: ${repoName}`));
5263
- console.log(chalk10.gray(` Path: ${expandedPath}`));
5527
+ console.log(chalk11.gray(` Path: ${expandedPath}`));
5264
5528
  if (repoDescription) {
5265
- console.log(chalk10.gray(` ${repoDescription}`));
5529
+ console.log(chalk11.gray(` ${repoDescription}`));
5266
5530
  }
5267
5531
  }
5268
5532
  async function reposRemoveCommand(name) {
@@ -5270,7 +5534,7 @@ async function reposRemoveCommand(name) {
5270
5534
  if (!repoName) {
5271
5535
  const repos2 = getRepos();
5272
5536
  if (repos2.length === 0) {
5273
- console.log(chalk10.yellow("No repos configured."));
5537
+ console.log(chalk11.yellow("No repos configured."));
5274
5538
  return;
5275
5539
  }
5276
5540
  const answers2 = await inquirer4.prompt([
@@ -5284,7 +5548,7 @@ async function reposRemoveCommand(name) {
5284
5548
  repoName = answers2.name;
5285
5549
  }
5286
5550
  if (!repoName) {
5287
- console.error(chalk10.red("Repo name is required"));
5551
+ console.error(chalk11.red("Repo name is required"));
5288
5552
  return;
5289
5553
  }
5290
5554
  const answers = await inquirer4.prompt([
@@ -5296,22 +5560,22 @@ async function reposRemoveCommand(name) {
5296
5560
  }
5297
5561
  ]);
5298
5562
  if (!answers.confirm) {
5299
- console.log(chalk10.gray("Cancelled"));
5563
+ console.log(chalk11.gray("Cancelled"));
5300
5564
  return;
5301
5565
  }
5302
5566
  const existed = removeRepo(repoName);
5303
5567
  if (existed) {
5304
- console.log(chalk10.green(`
5568
+ console.log(chalk11.green(`
5305
5569
  \u2713 Removed repo: ${repoName}`));
5306
5570
  } else {
5307
- console.log(chalk10.yellow(`
5571
+ console.log(chalk11.yellow(`
5308
5572
  Repo '${repoName}' not found`));
5309
5573
  }
5310
5574
  }
5311
5575
  async function reposGetCommand(name) {
5312
5576
  const repo = getRepo(name);
5313
5577
  if (!repo) {
5314
- console.error(chalk10.red(`Repo '${name}' not found`));
5578
+ console.error(chalk11.red(`Repo '${name}' not found`));
5315
5579
  process.exit(1);
5316
5580
  }
5317
5581
  console.log(JSON.stringify(repo, null, 2));
@@ -5319,11 +5583,11 @@ async function reposGetCommand(name) {
5319
5583
 
5320
5584
  // src/commands/integrations.ts
5321
5585
  import inquirer5 from "inquirer";
5322
- import chalk11 from "chalk";
5586
+ import chalk12 from "chalk";
5323
5587
  import { execSync as execSync6 } from "child_process";
5324
5588
  import { createServer } from "https";
5325
- import { readFileSync as readFileSync11, mkdirSync as mkdirSync7, appendFileSync as appendFileSync2, writeFileSync as writeFileSync6 } from "fs";
5326
- import { join as join14 } from "path";
5589
+ import { readFileSync as readFileSync12, mkdirSync as mkdirSync7, appendFileSync as appendFileSync2, writeFileSync as writeFileSync6 } from "fs";
5590
+ import { join as join15 } from "path";
5327
5591
 
5328
5592
  // src/integrations/slack/index.ts
5329
5593
  import { WebClient } from "@slack/web-api";
@@ -5445,13 +5709,13 @@ var SUCCESS_HTML = `<!DOCTYPE html>
5445
5709
  </div>
5446
5710
  </body>
5447
5711
  </html>`;
5448
- var CERT_DIR = join14(process.env.HOME || "", ".droid", "certs");
5449
- var CERT_KEY_PATH = join14(CERT_DIR, "localhost-key.pem");
5450
- var CERT_PATH = join14(CERT_DIR, "localhost.pem");
5712
+ var CERT_DIR = join15(process.env.HOME || "", ".droid", "certs");
5713
+ var CERT_KEY_PATH = join15(CERT_DIR, "localhost-key.pem");
5714
+ var CERT_PATH = join15(CERT_DIR, "localhost.pem");
5451
5715
  function getOrCreateCert() {
5452
5716
  try {
5453
- const key = readFileSync11(CERT_KEY_PATH, "utf-8");
5454
- const cert = readFileSync11(CERT_PATH, "utf-8");
5717
+ const key = readFileSync12(CERT_KEY_PATH, "utf-8");
5718
+ const cert = readFileSync12(CERT_PATH, "utf-8");
5455
5719
  if (key && cert) return { key, cert };
5456
5720
  } catch {
5457
5721
  }
@@ -5461,8 +5725,8 @@ function getOrCreateCert() {
5461
5725
  { stdio: "ignore" }
5462
5726
  );
5463
5727
  return {
5464
- key: readFileSync11(CERT_KEY_PATH, "utf-8"),
5465
- cert: readFileSync11(CERT_PATH, "utf-8")
5728
+ key: readFileSync12(CERT_KEY_PATH, "utf-8"),
5729
+ cert: readFileSync12(CERT_PATH, "utf-8")
5466
5730
  };
5467
5731
  }
5468
5732
  function trustCertInKeychain() {
@@ -5524,7 +5788,7 @@ function writeTokenToShellRc(key, value) {
5524
5788
  const exportLine = buildExportLine(key, value, isFish);
5525
5789
  const fullPath = expandHome(rcPath);
5526
5790
  try {
5527
- const existing = readFileSync11(fullPath, "utf-8");
5791
+ const existing = readFileSync12(fullPath, "utf-8");
5528
5792
  if (existing.includes(`${key}=`) || existing.includes(`${key} "`)) {
5529
5793
  const lines = existing.split("\n");
5530
5794
  const pattern = isFish ? new RegExp(`^set\\s+-gx\\s+${key}\\s+`) : new RegExp(`^export\\s+${key}=`);
@@ -5554,9 +5818,9 @@ ${exportLine}
5554
5818
  }
5555
5819
  }
5556
5820
  async function integrationsSetupSlackCommand() {
5557
- console.log(chalk11.bold("\nSlack Integration Setup\n"));
5821
+ console.log(chalk12.bold("\nSlack Integration Setup\n"));
5558
5822
  if (hasSlackToken()) {
5559
- console.log(chalk11.green(" SLACK_USER_TOKEN is already set in your environment\n"));
5823
+ console.log(chalk12.green(" SLACK_USER_TOKEN is already set in your environment\n"));
5560
5824
  const { reauth } = await inquirer5.prompt([
5561
5825
  {
5562
5826
  type: "confirm",
@@ -5574,23 +5838,23 @@ async function integrationsSetupSlackCommand() {
5574
5838
  const clientSecret = process.env.SLACK_CLIENT_SECRET;
5575
5839
  if (!clientId || !clientSecret) {
5576
5840
  const { rcPath: rcPath2 } = getShellInfo();
5577
- console.log(chalk11.yellow(" Missing Slack app credentials.\n"));
5578
- console.log(chalk11.gray(' Get Client ID and Client Secret from 1Password ("Droid Slack App")'));
5579
- console.log(chalk11.gray(` and add to your ${rcPath2}:
5841
+ console.log(chalk12.yellow(" Missing Slack app credentials.\n"));
5842
+ console.log(chalk12.gray(' Get Client ID and Client Secret from 1Password ("Droid Slack App")'));
5843
+ console.log(chalk12.gray(` and add to your ${rcPath2}:
5580
5844
  `));
5581
- console.log(chalk11.white(' export SLACK_CLIENT_ID="your-client-id"'));
5582
- console.log(chalk11.white(' export SLACK_CLIENT_SECRET="your-client-secret"\n'));
5583
- console.log(chalk11.gray(" Then reload and run this again:\n"));
5584
- console.log(chalk11.white(` source ${rcPath2} && droid integrations setup slack
5845
+ console.log(chalk12.white(' export SLACK_CLIENT_ID="your-client-id"'));
5846
+ console.log(chalk12.white(' export SLACK_CLIENT_SECRET="your-client-secret"\n'));
5847
+ console.log(chalk12.gray(" Then reload and run this again:\n"));
5848
+ console.log(chalk12.white(` source ${rcPath2} && droid integrations setup slack
5585
5849
  `));
5586
5850
  return;
5587
5851
  }
5588
- console.log(chalk11.gray(" Checking credentials...") + chalk11.green(" SLACK_CLIENT_ID found"));
5852
+ console.log(chalk12.gray(" Checking credentials...") + chalk12.green(" SLACK_CLIENT_ID found"));
5589
5853
  const authorizeUrl = `https://slack.com/oauth/v2/authorize?client_id=${clientId}&user_scope=${SLACK_SCOPES}&redirect_uri=${encodeURIComponent(REDIRECT_URI)}`;
5590
5854
  getOrCreateCert();
5591
5855
  const certTrusted = getConfigValue("integrations.slack.cert_trusted");
5592
5856
  if (!certTrusted) {
5593
- console.log(chalk11.gray(" The OAuth callback uses a local HTTPS certificate."));
5857
+ console.log(chalk12.gray(" The OAuth callback uses a local HTTPS certificate."));
5594
5858
  const { trust } = await inquirer5.prompt([
5595
5859
  {
5596
5860
  type: "confirm",
@@ -5600,45 +5864,45 @@ async function integrationsSetupSlackCommand() {
5600
5864
  }
5601
5865
  ]);
5602
5866
  if (trust) {
5603
- console.log(chalk11.gray(" Adding certificate to Keychain (you may be prompted for your password)..."));
5867
+ console.log(chalk12.gray(" Adding certificate to Keychain (you may be prompted for your password)..."));
5604
5868
  if (trustCertInKeychain()) {
5605
- console.log(chalk11.green(" Certificate trusted."));
5869
+ console.log(chalk12.green(" Certificate trusted."));
5606
5870
  setConfigValue("integrations.slack.cert_trusted", true);
5607
5871
  } else {
5608
- console.log(chalk11.yellow(" Could not trust certificate \u2014 you may see a browser warning."));
5872
+ console.log(chalk12.yellow(" Could not trust certificate \u2014 you may see a browser warning."));
5609
5873
  }
5610
5874
  }
5611
5875
  console.log("");
5612
5876
  }
5613
- console.log(chalk11.gray(" Opening browser for Slack authorisation..."));
5877
+ console.log(chalk12.gray(" Opening browser for Slack authorisation..."));
5614
5878
  const callbackPromise = waitForCallback();
5615
5879
  try {
5616
5880
  execSync6(`open "${authorizeUrl}"`, { stdio: "ignore" });
5617
5881
  } catch {
5618
- console.log(chalk11.gray("\n Could not open browser. Open this URL manually:\n"));
5619
- console.log(chalk11.cyan(` ${authorizeUrl}
5882
+ console.log(chalk12.gray("\n Could not open browser. Open this URL manually:\n"));
5883
+ console.log(chalk12.cyan(` ${authorizeUrl}
5620
5884
  `));
5621
5885
  }
5622
- console.log(chalk11.gray(" Waiting for callback..."));
5886
+ console.log(chalk12.gray(" Waiting for callback..."));
5623
5887
  let code;
5624
5888
  try {
5625
5889
  code = await callbackPromise;
5626
5890
  } catch (error) {
5627
- console.log(chalk11.red(`
5891
+ console.log(chalk12.red(`
5628
5892
  ${error instanceof Error ? error.message : "Failed to receive callback"}`));
5629
5893
  return;
5630
5894
  }
5631
- console.log(chalk11.green(" Authorisation received"));
5895
+ console.log(chalk12.green(" Authorisation received"));
5632
5896
  const result = await exchangeOAuthCode(clientId, clientSecret, code, REDIRECT_URI);
5633
5897
  if (!result.ok || !result.token) {
5634
- console.log(chalk11.red(`
5898
+ console.log(chalk12.red(`
5635
5899
  Slack API error: ${result.error}`));
5636
5900
  if (result.error === "invalid_code") {
5637
- console.log(chalk11.gray(" The code may have expired. Try again."));
5901
+ console.log(chalk12.gray(" The code may have expired. Try again."));
5638
5902
  }
5639
5903
  return;
5640
5904
  }
5641
- console.log(chalk11.green(" Token exchanged successfully"));
5905
+ console.log(chalk12.green(" Token exchanged successfully"));
5642
5906
  const { rcPath } = getShellInfo();
5643
5907
  const { writeToRc } = await inquirer5.prompt([
5644
5908
  {
@@ -5651,91 +5915,91 @@ async function integrationsSetupSlackCommand() {
5651
5915
  if (writeToRc) {
5652
5916
  const written = writeTokenToShellRc("SLACK_USER_TOKEN", result.token);
5653
5917
  if (written) {
5654
- console.log(chalk11.green(`
5918
+ console.log(chalk12.green(`
5655
5919
  Token saved to ${rcPath}`));
5656
- console.log(chalk11.gray(" Source your shell or open a new tab to use it."));
5920
+ console.log(chalk12.gray(" Source your shell or open a new tab to use it."));
5657
5921
  } else {
5658
- console.log(chalk11.yellow(`
5922
+ console.log(chalk12.yellow(`
5659
5923
  Could not write to ${rcPath}. Add manually:
5660
5924
  `));
5661
5925
  const { isFish } = getShellInfo();
5662
- console.log(chalk11.white(` ${buildExportLine("SLACK_USER_TOKEN", result.token, isFish)}
5926
+ console.log(chalk12.white(` ${buildExportLine("SLACK_USER_TOKEN", result.token, isFish)}
5663
5927
  `));
5664
5928
  }
5665
5929
  } else {
5666
5930
  const { isFish } = getShellInfo();
5667
- console.log(chalk11.yellow("\n Add to your shell config manually:\n"));
5668
- console.log(chalk11.white(` ${buildExportLine("SLACK_USER_TOKEN", result.token, isFish)}
5931
+ console.log(chalk12.yellow("\n Add to your shell config manually:\n"));
5932
+ console.log(chalk12.white(` ${buildExportLine("SLACK_USER_TOKEN", result.token, isFish)}
5669
5933
  `));
5670
5934
  }
5671
5935
  setConfigValue("integrations.slack.configured", true);
5672
- console.log(chalk11.green("\n Slack integration configured!\n"));
5936
+ console.log(chalk12.green("\n Slack integration configured!\n"));
5673
5937
  }
5674
5938
  async function integrationsStatusCommand() {
5675
- console.log(chalk11.bold("\nIntegrations Status\n"));
5676
- console.log(chalk11.bold(" Slack"));
5939
+ console.log(chalk12.bold("\nIntegrations Status\n"));
5940
+ console.log(chalk12.bold(" Slack"));
5677
5941
  const configured = getConfigValue("integrations.slack.configured");
5678
5942
  const clientId = process.env.SLACK_CLIENT_ID;
5679
5943
  const clientSecret = process.env.SLACK_CLIENT_SECRET;
5680
5944
  const hasCredentials = clientId && clientSecret;
5681
5945
  if (hasCredentials) {
5682
- console.log(chalk11.green(" App credentials configured"));
5946
+ console.log(chalk12.green(" App credentials configured"));
5683
5947
  } else {
5684
- console.log(chalk11.yellow(" App credentials missing"));
5685
- console.log(chalk11.gray(" Run: droid integrations setup slack"));
5948
+ console.log(chalk12.yellow(" App credentials missing"));
5949
+ console.log(chalk12.gray(" Run: droid integrations setup slack"));
5686
5950
  }
5687
5951
  if (hasSlackToken()) {
5688
5952
  const token = process.env.SLACK_USER_TOKEN;
5689
5953
  const masked = token.slice(0, 10) + "..." + token.slice(-4);
5690
- console.log(chalk11.green(" User token configured"));
5691
- console.log(chalk11.gray(` Token: ${masked}`));
5954
+ console.log(chalk12.green(" User token configured"));
5955
+ console.log(chalk12.gray(` Token: ${masked}`));
5692
5956
  } else {
5693
- console.log(chalk11.yellow(" User token missing"));
5957
+ console.log(chalk12.yellow(" User token missing"));
5694
5958
  if (hasCredentials) {
5695
- console.log(chalk11.gray(" Run: droid integrations setup slack"));
5959
+ console.log(chalk12.gray(" Run: droid integrations setup slack"));
5696
5960
  }
5697
5961
  }
5698
5962
  if (configured) {
5699
- console.log(chalk11.green(" Status: configured"));
5963
+ console.log(chalk12.green(" Status: configured"));
5700
5964
  } else {
5701
- console.log(chalk11.yellow(" Status: not configured"));
5965
+ console.log(chalk12.yellow(" Status: not configured"));
5702
5966
  }
5703
5967
  console.log("");
5704
- console.log(chalk11.bold(" Atlassian"));
5968
+ console.log(chalk12.bold(" Atlassian"));
5705
5969
  const atlassianConfigured = getConfigValue("integrations.atlassian.configured");
5706
5970
  if (atlassianConfigured) {
5707
- console.log(chalk11.green(" MCP: Connected"));
5708
- console.log(chalk11.green(" Status: configured"));
5971
+ console.log(chalk12.green(" MCP: Connected"));
5972
+ console.log(chalk12.green(" Status: configured"));
5709
5973
  } else {
5710
- console.log(chalk11.yellow(" MCP: Not yet verified"));
5711
- console.log(chalk11.gray(" Use /share confluence to verify, or see setup guide"));
5974
+ console.log(chalk12.yellow(" MCP: Not yet verified"));
5975
+ console.log(chalk12.gray(" Use /share confluence to verify, or see setup guide"));
5712
5976
  }
5713
5977
  console.log("");
5714
- console.log(chalk11.bold(" GitHub"));
5978
+ console.log(chalk12.bold(" GitHub"));
5715
5979
  const githubConfigured = getConfigValue("integrations.github.configured");
5716
5980
  if (githubConfigured) {
5717
- console.log(chalk11.green(" CLI: Installed"));
5718
- console.log(chalk11.green(" Status: configured"));
5981
+ console.log(chalk12.green(" CLI: Installed"));
5982
+ console.log(chalk12.green(" Status: configured"));
5719
5983
  } else {
5720
- console.log(chalk11.yellow(" CLI: Not verified"));
5721
- console.log(chalk11.gray(" Run: gh auth login"));
5984
+ console.log(chalk12.yellow(" CLI: Not verified"));
5985
+ console.log(chalk12.gray(" Run: gh auth login"));
5722
5986
  }
5723
5987
  console.log("");
5724
- console.log(chalk11.bold(" Granola"));
5988
+ console.log(chalk12.bold(" Granola"));
5725
5989
  const granolaConfigured = getConfigValue("integrations.granola.configured");
5726
5990
  if (granolaConfigured) {
5727
- console.log(chalk11.green(" MCP: Connected"));
5728
- console.log(chalk11.green(" Status: configured"));
5991
+ console.log(chalk12.green(" MCP: Connected"));
5992
+ console.log(chalk12.green(" Status: configured"));
5729
5993
  } else {
5730
- console.log(chalk11.yellow(" MCP: Not yet verified"));
5731
- console.log(chalk11.gray(" Use /mcp to add the Granola server, then verify with a meeting query"));
5994
+ console.log(chalk12.yellow(" MCP: Not yet verified"));
5995
+ console.log(chalk12.gray(" Use /mcp to add the Granola server, then verify with a meeting query"));
5732
5996
  }
5733
5997
  console.log("");
5734
5998
  }
5735
5999
  async function slackPostCommand(options) {
5736
6000
  let input;
5737
6001
  try {
5738
- input = readFileSync11(0, "utf-8").trim();
6002
+ input = readFileSync12(0, "utf-8").trim();
5739
6003
  } catch {
5740
6004
  console.log(JSON.stringify({ ok: false, error: "Failed to read from stdin. Pipe JSON payload via stdin." }));
5741
6005
  process.exit(1);
@@ -5787,6 +6051,7 @@ program.command("install <tool>").description("Install a tool and run its setup
5787
6051
  program.command("uninstall <tool>").description("Uninstall a tool").action(uninstallCommand);
5788
6052
  program.command("update").description("Update droid and installed tools").option("--tools", "Only update tools").option("--cli", "Only update the CLI").argument("[tool]", "Update a specific tool").action(updateCommand);
5789
6053
  program.command("tui").description("Launch interactive TUI dashboard").action(tuiCommand);
6054
+ program.command("pack").description("Create audience-filtered zip packs for distribution").argument("[audience]", "Target audience (e.g., engineering, customer-support)").option("-l, --list", "List available audiences and tool counts").option("-o, --output <dir>", "Output directory (default: cwd)").action(packCommand);
5790
6055
  program.command("exec <tool> <script>").description("Execute a tool script").argument("[args...]", "Arguments to pass to the script").allowUnknownOption().action(execCommand);
5791
6056
  var integrations = program.command("integrations").description("Manage external service integrations");
5792
6057
  var integrationsSetup = integrations.command("setup").description("Set up an integration");
@@ -5799,8 +6064,8 @@ if (configExists()) {
5799
6064
  const config = loadConfig();
5800
6065
  const newPlatforms = syncNewPlatforms(config);
5801
6066
  if (newPlatforms.length > 0) {
5802
- console.log(chalk12.green(`\u2713 Detected new platform(s): ${newPlatforms.join(", ")}`));
5803
- console.log(chalk12.gray(" Synced installed tools to new platform(s)\n"));
6067
+ console.log(chalk13.green(`\u2713 Detected new platform(s): ${newPlatforms.join(", ")}`));
6068
+ console.log(chalk13.gray(" Synced installed tools to new platform(s)\n"));
5804
6069
  saveConfig(config);
5805
6070
  }
5806
6071
  }