@starlein/paperclip-plugin-company-wizard 0.3.19 → 0.3.21

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 (39) hide show
  1. package/README.md +7 -1
  2. package/dist/manifest.js +6 -1
  3. package/dist/manifest.js.map +2 -2
  4. package/dist/worker.js +60 -6
  5. package/dist/worker.js.map +2 -2
  6. package/package.json +1 -1
  7. package/templates/modules/accessibility/skills/accessibility-audit.bar.md +11 -0
  8. package/templates/modules/architecture-plan/agents/ui-designer/skills/design-system.bar.md +11 -0
  9. package/templates/modules/architecture-plan/skills/architecture-plan.bar.md +11 -0
  10. package/templates/modules/backlog/skills/backlog-health.bar.md +11 -0
  11. package/templates/modules/brand-identity/skills/brand-identity.bar.md +11 -0
  12. package/templates/modules/build-api/skills/api-design.bar.md +11 -0
  13. package/templates/modules/ci-cd/skills/ci-cd.bar.md +11 -0
  14. package/templates/modules/codebase-onboarding/skills/codebase-audit.bar.md +11 -0
  15. package/templates/modules/github-repo/docs/git-workflow.md +12 -0
  16. package/templates/modules/github-repo/module.meta.json +1 -1
  17. package/templates/modules/market-analysis/skills/market-analysis.bar.md +11 -0
  18. package/templates/modules/monitoring/skills/monitoring.bar.md +11 -0
  19. package/templates/modules/pr-review/agents/engineer/skills/pr-workflow.md +6 -4
  20. package/templates/modules/pr-review/docs/pr-conventions.md +3 -2
  21. package/templates/modules/pr-review/module.meta.json +3 -2
  22. package/templates/modules/security-audit/skills/security-review.bar.md +11 -0
  23. package/templates/modules/security-audit/skills/threat-model.bar.md +11 -0
  24. package/templates/modules/tech-stack/skills/tech-stack.bar.md +11 -0
  25. package/templates/modules/user-testing/skills/user-testing.bar.md +11 -0
  26. package/templates/roles/code-reviewer/DONE.md +10 -0
  27. package/templates/roles/code-reviewer/LENSES.md +11 -0
  28. package/templates/roles/devops/DONE.md +10 -0
  29. package/templates/roles/devops/LENSES.md +12 -0
  30. package/templates/roles/engineer/DONE.md +10 -0
  31. package/templates/roles/product-owner/DONE.md +10 -0
  32. package/templates/roles/product-owner/LENSES.md +11 -0
  33. package/templates/roles/qa/DONE.md +10 -0
  34. package/templates/roles/security-engineer/DONE.md +10 -0
  35. package/templates/roles/security-engineer/LENSES.md +16 -0
  36. package/templates/roles/ui-designer/DONE.md +10 -0
  37. package/templates/roles/ui-designer/LENSES.md +13 -0
  38. package/templates/roles/ux-researcher/DONE.md +10 -0
  39. package/templates/roles/ux-researcher/LENSES.md +14 -0
package/README.md CHANGED
@@ -5,7 +5,7 @@
5
5
  <strong>Bootstrap AI agent teams from modular templates.</strong>
6
6
  </p>
7
7
  <p align="center">
8
- <a href="https://github.com/starlein/paperclip-plugin-company-wizard/pkgs/npm/paperclip-plugin-company-wizard"><img src="https://img.shields.io/badge/GitHub%20Packages-@starlein%2Fpaperclip--plugin--company--wizard-blue" alt="GitHub Packages"></a>
8
+ <a href="https://www.npmjs.com/package/@starlein/paperclip-plugin-company-wizard"><img src="https://img.shields.io/npm/v/@starlein/paperclip-plugin-company-wizard?color=cb3837&label=npm" alt="npm version"></a>
9
9
  <a href="https://github.com/starlein/paperclip-plugin-company-wizard/actions/workflows/ci.yml"><img src="https://github.com/starlein/paperclip-plugin-company-wizard/actions/workflows/ci.yml/badge.svg" alt="CI"></a>
10
10
  <a href="LICENSE"><img src="https://img.shields.io/badge/license-MIT-blue" alt="License"></a>
11
11
  <a href="https://nodejs.org"><img src="https://img.shields.io/badge/node-%3E%3D20-brightgreen" alt="Node.js"></a>
@@ -139,6 +139,8 @@ Every company starts with just the **CEO** — and that's already a functional t
139
139
 
140
140
  No role is ever truly missing. When a specialist isn't present, the next best available person steps in. The CEO is always the final fallback.
141
141
 
142
+ > **Enriched personas (opt-in):** set `enableEnrichedPersonas` to give expert roles named **domain lenses** (e.g. STRIDE, Nielsen's 10, RICE) in their `SOUL.md`, add **output/review bars** to module skills, and append **done-criteria** to `HEARTBEAT.md`. Off by default — the baseline personas stay lean.
143
+
142
144
  <details>
143
145
  <summary><strong>Full capability ownership table</strong></summary>
144
146
 
@@ -334,6 +336,8 @@ Git workflow and commit conventions.
334
336
 
335
337
  PR-based review workflow. Requires `github-repo`. Activates with `code-reviewer`, `product-owner`, `ui-designer`, `ux-researcher`, `qa`, or `devops`.
336
338
 
339
+ Reviews run through the issue's native `executionPolicy` (stages), not child issues: a `review` stage for the Code Reviewer (plus relevant domain reviewers), an `approval` stage for the Product Owner, then a final `approval` **merge gate** owned by the Engineer — who is woken last to merge the PR before recording the verdict that closes the issue. The merge gate is deliberately the last stage so the Product Owner's approval does not auto-close the issue with the PR still open.
340
+
337
341
  - **Task:** Engineer sets up branch protection
338
342
  - **Doc:** `docs/pr-conventions.md`
339
343
 
@@ -587,6 +591,8 @@ Configure the plugin via **Settings → Plugins → Company Wizard** in the Pape
587
591
  | `paperclipPassword` | No | Board login password. Stored as a secret ref. |
588
592
  | `anthropicApiKey` | No | Anthropic API key for AI wizard mode. Stored as a secret ref. Required to use the AI-powered setup path. |
589
593
  | `disableBoardApprovalOnNewCompanies` | No | If `true`, the wizard PATCHes new companies to set `requireBoardApprovalForNewAgents=false` during provisioning. Leave `false` to preserve approval-gated hiring. Defaults to `false`. |
594
+ | `enableEnrichedPersonas` | No | If `true`, expert roles get domain lenses (named mental models) in `SOUL.md`, module skills get concrete output/review bars, and `HEARTBEAT.md` gets explicit done-criteria. Leave `false` (default) for the lean baseline personas. |
595
+
590
596
  For isolated worktrees: there is no plugin setting. The policy is controlled by Paperclip instance settings under **Settings → Instance → Experimental → enableIsolatedWorkspaces** and is consumed by the plugin during provisioning.
591
597
 
592
598
  <br>
package/dist/manifest.js CHANGED
@@ -2,7 +2,7 @@
2
2
  var manifest = {
3
3
  id: "starlein.paperclip-plugin-company-wizard",
4
4
  apiVersion: 1,
5
- version: "0.3.19",
5
+ version: "0.3.21",
6
6
  displayName: "Company Wizard",
7
7
  description: "AI-powered wizard to bootstrap agent companies from composable templates",
8
8
  author: "Sascha Pietrowski <sp@speednetwork.de>",
@@ -59,6 +59,11 @@ var manifest = {
59
59
  type: "boolean",
60
60
  default: false,
61
61
  description: "Optional. If true, the wizard will PATCH new companies to set requireBoardApprovalForNewAgents=false during provisioning. Leave false to preserve approval-gated hiring policies."
62
+ },
63
+ enableEnrichedPersonas: {
64
+ type: "boolean",
65
+ default: false,
66
+ description: "Optional. If true, expert roles are enriched with domain lenses (named mental models), module skills gain concrete output/review bars with negative examples, and HEARTBEAT.md gains explicit done-criteria. Leave false (default) for the lean baseline personas."
62
67
  }
63
68
  }
64
69
  },
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "version": 3,
3
3
  "sources": ["../src/manifest.ts"],
4
- "sourcesContent": ["import type { PaperclipPluginManifestV1 } from '@paperclipai/plugin-sdk';\n\nconst manifest: PaperclipPluginManifestV1 = {\n id: 'starlein.paperclip-plugin-company-wizard',\n apiVersion: 1,\n version: '0.3.19',\n displayName: 'Company Wizard',\n description: 'AI-powered wizard to bootstrap agent companies from composable templates',\n author: 'Sascha Pietrowski <sp@speednetwork.de>',\n categories: ['workspace', 'ui'],\n capabilities: [\n 'companies.read',\n 'issues.create',\n 'issues.read',\n 'issues.update',\n 'goals.create',\n 'goals.read',\n 'agents.read',\n 'projects.read',\n 'plugin.state.read',\n 'plugin.state.write',\n 'secrets.read-ref',\n 'events.subscribe',\n 'ui.page.register',\n 'ui.sidebar.register',\n ],\n instanceConfigSchema: {\n type: 'object',\n properties: {\n companiesDir: {\n type: 'string',\n description:\n 'Directory where assembled company workspaces are written. Defaults to ~/.paperclip/instances/default/companies. Override for Docker setups (e.g. /paperclip/instances/default/companies).',\n },\n templatesPath: {\n type: 'string',\n description:\n 'Path to the templates directory. Defaults to ~/.paperclip/plugin-templates (auto-downloaded from templatesRepoUrl if missing). Override for Docker setups (e.g. /paperclip/plugin-templates).',\n },\n templatesRepoUrl: {\n type: 'string',\n default: 'https://github.com/starlein/paperclip-plugin-company-wizard/tree/main/templates',\n description:\n 'GitHub tree URL to pull templates from when the templates directory does not exist.',\n },\n anthropicApiKey: {\n type: 'string',\n description:\n 'Anthropic API key for the AI wizard (e.g. sk-ant-...). Required to use the AI-powered company setup path.',\n },\n paperclipUrl: {\n type: 'string',\n description:\n 'Paperclip instance URL. Defaults to http://localhost:3100 or the PAPERCLIP_PUBLIC_URL env var.',\n },\n paperclipEmail: {\n type: 'string',\n description: 'Board login email (for authenticated instances).',\n },\n paperclipPassword: {\n type: 'string',\n description: 'Board login password (for authenticated instances).',\n },\n disableBoardApprovalOnNewCompanies: {\n type: 'boolean',\n default: false,\n description:\n 'Optional. If true, the wizard will PATCH new companies to set requireBoardApprovalForNewAgents=false during provisioning. Leave false to preserve approval-gated hiring policies.',\n },\n },\n },\n entrypoints: {\n worker: './dist/worker.js',\n ui: './dist/ui',\n },\n ui: {\n slots: [\n {\n type: 'page',\n id: 'company-wizard',\n displayName: 'Company Wizard',\n exportName: 'WizardPage',\n routePath: 'company-creator',\n },\n {\n type: 'sidebar',\n id: 'company-wizard-link',\n displayName: 'Create Company',\n exportName: 'SidebarLink',\n },\n ],\n },\n};\n\nexport default manifest;\n"],
5
- "mappings": ";AAEA,IAAM,WAAsC;AAAA,EAC1C,IAAI;AAAA,EACJ,YAAY;AAAA,EACZ,SAAS;AAAA,EACT,aAAa;AAAA,EACb,aAAa;AAAA,EACb,QAAQ;AAAA,EACR,YAAY,CAAC,aAAa,IAAI;AAAA,EAC9B,cAAc;AAAA,IACZ;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,EACF;AAAA,EACA,sBAAsB;AAAA,IACpB,MAAM;AAAA,IACN,YAAY;AAAA,MACV,cAAc;AAAA,QACZ,MAAM;AAAA,QACN,aACE;AAAA,MACJ;AAAA,MACA,eAAe;AAAA,QACb,MAAM;AAAA,QACN,aACE;AAAA,MACJ;AAAA,MACA,kBAAkB;AAAA,QAChB,MAAM;AAAA,QACN,SAAS;AAAA,QACT,aACE;AAAA,MACJ;AAAA,MACA,iBAAiB;AAAA,QACf,MAAM;AAAA,QACN,aACE;AAAA,MACJ;AAAA,MACA,cAAc;AAAA,QACZ,MAAM;AAAA,QACN,aACE;AAAA,MACJ;AAAA,MACA,gBAAgB;AAAA,QACd,MAAM;AAAA,QACN,aAAa;AAAA,MACf;AAAA,MACA,mBAAmB;AAAA,QACjB,MAAM;AAAA,QACN,aAAa;AAAA,MACf;AAAA,MACA,oCAAoC;AAAA,QAClC,MAAM;AAAA,QACN,SAAS;AAAA,QACT,aACE;AAAA,MACJ;AAAA,IACF;AAAA,EACF;AAAA,EACA,aAAa;AAAA,IACX,QAAQ;AAAA,IACR,IAAI;AAAA,EACN;AAAA,EACA,IAAI;AAAA,IACF,OAAO;AAAA,MACL;AAAA,QACE,MAAM;AAAA,QACN,IAAI;AAAA,QACJ,aAAa;AAAA,QACb,YAAY;AAAA,QACZ,WAAW;AAAA,MACb;AAAA,MACA;AAAA,QACE,MAAM;AAAA,QACN,IAAI;AAAA,QACJ,aAAa;AAAA,QACb,YAAY;AAAA,MACd;AAAA,IACF;AAAA,EACF;AACF;AAEA,IAAO,mBAAQ;",
4
+ "sourcesContent": ["import type { PaperclipPluginManifestV1 } from '@paperclipai/plugin-sdk';\n\nconst manifest: PaperclipPluginManifestV1 = {\n id: 'starlein.paperclip-plugin-company-wizard',\n apiVersion: 1,\n version: '0.3.21',\n displayName: 'Company Wizard',\n description: 'AI-powered wizard to bootstrap agent companies from composable templates',\n author: 'Sascha Pietrowski <sp@speednetwork.de>',\n categories: ['workspace', 'ui'],\n capabilities: [\n 'companies.read',\n 'issues.create',\n 'issues.read',\n 'issues.update',\n 'goals.create',\n 'goals.read',\n 'agents.read',\n 'projects.read',\n 'plugin.state.read',\n 'plugin.state.write',\n 'secrets.read-ref',\n 'events.subscribe',\n 'ui.page.register',\n 'ui.sidebar.register',\n ],\n instanceConfigSchema: {\n type: 'object',\n properties: {\n companiesDir: {\n type: 'string',\n description:\n 'Directory where assembled company workspaces are written. Defaults to ~/.paperclip/instances/default/companies. Override for Docker setups (e.g. /paperclip/instances/default/companies).',\n },\n templatesPath: {\n type: 'string',\n description:\n 'Path to the templates directory. Defaults to ~/.paperclip/plugin-templates (auto-downloaded from templatesRepoUrl if missing). Override for Docker setups (e.g. /paperclip/plugin-templates).',\n },\n templatesRepoUrl: {\n type: 'string',\n default: 'https://github.com/starlein/paperclip-plugin-company-wizard/tree/main/templates',\n description:\n 'GitHub tree URL to pull templates from when the templates directory does not exist.',\n },\n anthropicApiKey: {\n type: 'string',\n description:\n 'Anthropic API key for the AI wizard (e.g. sk-ant-...). Required to use the AI-powered company setup path.',\n },\n paperclipUrl: {\n type: 'string',\n description:\n 'Paperclip instance URL. Defaults to http://localhost:3100 or the PAPERCLIP_PUBLIC_URL env var.',\n },\n paperclipEmail: {\n type: 'string',\n description: 'Board login email (for authenticated instances).',\n },\n paperclipPassword: {\n type: 'string',\n description: 'Board login password (for authenticated instances).',\n },\n disableBoardApprovalOnNewCompanies: {\n type: 'boolean',\n default: false,\n description:\n 'Optional. If true, the wizard will PATCH new companies to set requireBoardApprovalForNewAgents=false during provisioning. Leave false to preserve approval-gated hiring policies.',\n },\n enableEnrichedPersonas: {\n type: 'boolean',\n default: false,\n description:\n 'Optional. If true, expert roles are enriched with domain lenses (named mental models), module skills gain concrete output/review bars with negative examples, and HEARTBEAT.md gains explicit done-criteria. Leave false (default) for the lean baseline personas.',\n },\n },\n },\n entrypoints: {\n worker: './dist/worker.js',\n ui: './dist/ui',\n },\n ui: {\n slots: [\n {\n type: 'page',\n id: 'company-wizard',\n displayName: 'Company Wizard',\n exportName: 'WizardPage',\n routePath: 'company-creator',\n },\n {\n type: 'sidebar',\n id: 'company-wizard-link',\n displayName: 'Create Company',\n exportName: 'SidebarLink',\n },\n ],\n },\n};\n\nexport default manifest;\n"],
5
+ "mappings": ";AAEA,IAAM,WAAsC;AAAA,EAC1C,IAAI;AAAA,EACJ,YAAY;AAAA,EACZ,SAAS;AAAA,EACT,aAAa;AAAA,EACb,aAAa;AAAA,EACb,QAAQ;AAAA,EACR,YAAY,CAAC,aAAa,IAAI;AAAA,EAC9B,cAAc;AAAA,IACZ;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,EACF;AAAA,EACA,sBAAsB;AAAA,IACpB,MAAM;AAAA,IACN,YAAY;AAAA,MACV,cAAc;AAAA,QACZ,MAAM;AAAA,QACN,aACE;AAAA,MACJ;AAAA,MACA,eAAe;AAAA,QACb,MAAM;AAAA,QACN,aACE;AAAA,MACJ;AAAA,MACA,kBAAkB;AAAA,QAChB,MAAM;AAAA,QACN,SAAS;AAAA,QACT,aACE;AAAA,MACJ;AAAA,MACA,iBAAiB;AAAA,QACf,MAAM;AAAA,QACN,aACE;AAAA,MACJ;AAAA,MACA,cAAc;AAAA,QACZ,MAAM;AAAA,QACN,aACE;AAAA,MACJ;AAAA,MACA,gBAAgB;AAAA,QACd,MAAM;AAAA,QACN,aAAa;AAAA,MACf;AAAA,MACA,mBAAmB;AAAA,QACjB,MAAM;AAAA,QACN,aAAa;AAAA,MACf;AAAA,MACA,oCAAoC;AAAA,QAClC,MAAM;AAAA,QACN,SAAS;AAAA,QACT,aACE;AAAA,MACJ;AAAA,MACA,wBAAwB;AAAA,QACtB,MAAM;AAAA,QACN,SAAS;AAAA,QACT,aACE;AAAA,MACJ;AAAA,IACF;AAAA,EACF;AAAA,EACA,aAAa;AAAA,IACX,QAAQ;AAAA,IACR,IAAI;AAAA,EACN;AAAA,EACA,IAAI;AAAA,IACF,OAAO;AAAA,MACL;AAAA,QACE,MAAM;AAAA,QACN,IAAI;AAAA,QACJ,aAAa;AAAA,QACb,YAAY;AAAA,QACZ,WAAW;AAAA,MACb;AAAA,MACA;AAAA,QACE,MAAM;AAAA,QACN,IAAI;AAAA,QACJ,aAAa;AAAA,QACb,YAAY;AAAA,MACd;AAAA,IACF;AAAA,EACF;AACF;AAEA,IAAO,mBAAQ;",
6
6
  "names": []
7
7
  }
package/dist/worker.js CHANGED
@@ -9366,6 +9366,9 @@ async function appendToFile(filePath, content) {
9366
9366
  await appendFile(filePath, content);
9367
9367
  }
9368
9368
  }
9369
+ function isEnrichmentFragment(name) {
9370
+ return name === "LENSES.md" || name === "DONE.md" || name.endsWith(".bar.md");
9371
+ }
9369
9372
  async function readJson(p) {
9370
9373
  if (!await exists(p)) return null;
9371
9374
  return JSON.parse(await readFile(p, "utf-8"));
@@ -9397,6 +9400,7 @@ async function assembleCompany({
9397
9400
  presetRoutines = [],
9398
9401
  presetLabels = [],
9399
9402
  enableIsolatedWorktrees = false,
9403
+ enableEnrichedPersonas = false,
9400
9404
  outputDir,
9401
9405
  templatesDir,
9402
9406
  onProgress = () => {
@@ -9480,7 +9484,7 @@ async function assembleCompany({
9480
9484
  await copyDir(join(roleSrc, entry.name), join(roleDest, entry.name), {
9481
9485
  skipExt: ".meta.json"
9482
9486
  });
9483
- } else if (!entry.name.endsWith(".meta.json")) {
9487
+ } else if (!entry.name.endsWith(".meta.json") && !isEnrichmentFragment(entry.name)) {
9484
9488
  await copyFile(join(roleSrc, entry.name), join(roleDest, entry.name));
9485
9489
  }
9486
9490
  }
@@ -9497,6 +9501,7 @@ async function assembleCompany({
9497
9501
  const entries = await readdir(roleDir, { withFileTypes: true });
9498
9502
  for (const entry of entries) {
9499
9503
  if (entry.isDirectory() || !entry.name.endsWith(".md")) continue;
9504
+ if (isEnrichmentFragment(entry.name)) continue;
9500
9505
  await copyFile(join(roleDir, entry.name), join(destDir, entry.name));
9501
9506
  }
9502
9507
  onProgress(`+ agents/${roleName}/ (role)`);
@@ -9538,12 +9543,13 @@ async function assembleCompany({
9538
9543
  reviewers.push(role);
9539
9544
  }
9540
9545
  const approver = typeof reviewGate.approver === "string" && allRoles.has(reviewGate.approver) ? reviewGate.approver : void 0;
9546
+ const mergeGate = typeof reviewGate.mergeGate === "string" && allRoles.has(reviewGate.mergeGate) ? reviewGate.mergeGate : void 0;
9541
9547
  if (approver) {
9542
9548
  const idx = reviewers.indexOf(approver);
9543
9549
  if (idx !== -1) reviewers.splice(idx, 1);
9544
9550
  }
9545
- if (reviewers.length === 0 && !approver) return null;
9546
- return { reviewers, approver };
9551
+ if (reviewers.length === 0 && !approver && !mergeGate) return null;
9552
+ return { reviewers, approver, mergeGate };
9547
9553
  };
9548
9554
  const renderReviewGate = (gate) => {
9549
9555
  const stages = [];
@@ -9555,6 +9561,11 @@ async function assembleCompany({
9555
9561
  ` - stage ${stages.length + 1} (approval) \u2192 assign ${JSON.stringify(gate.approver)}`
9556
9562
  );
9557
9563
  }
9564
+ if (gate.mergeGate) {
9565
+ stages.push(
9566
+ ` - stage ${stages.length + 1} (approval) \u2192 assign ${JSON.stringify(gate.mergeGate)} \u2014 merge gate: merge the PR, then record approved to close`
9567
+ );
9568
+ }
9558
9569
  return `- **executionPolicy** (set when creating this issue; resolve each role to its agentId):
9559
9570
  ${stages.join("\n")}
9560
9571
 
@@ -9671,7 +9682,18 @@ ${stages.join("\n")}
9671
9682
  if (!resolved) return false;
9672
9683
  const destSkillsDir = join(companyDir, "agents", roleName, "skills");
9673
9684
  await mkdir(destSkillsDir, { recursive: true });
9674
- await copyFile(resolved.path, join(destSkillsDir, fileName));
9685
+ const destFile = join(destSkillsDir, fileName);
9686
+ await copyFile(resolved.path, destFile);
9687
+ let barApplied = false;
9688
+ if (enableEnrichedPersonas && label === "primary") {
9689
+ const barFileName = fileName.replace(/\.md$/, ".bar.md");
9690
+ const bar = await resolveSkillFile(roleName, barFileName);
9691
+ if (bar) {
9692
+ const barContent = await readFile(bar.path, "utf-8");
9693
+ await appendToFile(destFile, "\n" + barContent.trim() + "\n");
9694
+ barApplied = true;
9695
+ }
9696
+ }
9675
9697
  await appendToFile(
9676
9698
  join(companyDir, "agents", roleName, "AGENTS.md"),
9677
9699
  `
@@ -9679,7 +9701,10 @@ Read and follow: \`$AGENT_HOME/skills/${fileName}\`
9679
9701
  `
9680
9702
  );
9681
9703
  const sourceTag = resolved.source === "shared" ? ", shared" : "";
9682
- onProgress(`+ agents/${roleName}/skills/${fileName} (${moduleName}, ${label}${sourceTag})`);
9704
+ const barTag = barApplied ? ", output bar" : "";
9705
+ onProgress(
9706
+ `+ agents/${roleName}/skills/${fileName} (${moduleName}, ${label}${sourceTag}${barTag})`
9707
+ );
9683
9708
  return true;
9684
9709
  }
9685
9710
  for (const [skillName, { primary, cap }] of capabilityOwners) {
@@ -9701,6 +9726,7 @@ Read and follow: \`$AGENT_HOME/skills/${fileName}\`
9701
9726
  if (!await exists(skillsDir)) continue;
9702
9727
  const skills = await readdir(skillsDir);
9703
9728
  for (const skillFile of skills) {
9729
+ if (skillFile.endsWith(".bar.md")) continue;
9704
9730
  const skillName = skillFile.replace(/\.md$/, "");
9705
9731
  const skillBaseName = skillName.replace(/\.fallback$/, "");
9706
9732
  if (capabilityOwners.has(skillBaseName)) continue;
@@ -9744,6 +9770,24 @@ Read and follow: \`$AGENT_HOME/skills/${skillFile}\`
9744
9770
  onProgress(`+ agents/${modRole.name}/HEARTBEAT.md (${moduleName}, heartbeat section)`);
9745
9771
  }
9746
9772
  }
9773
+ if (enableEnrichedPersonas) {
9774
+ for (const roleName of allRoles) {
9775
+ const lensesSrc = join(rolesDir, roleName, "LENSES.md");
9776
+ const soulPath = join(companyDir, "agents", roleName, "SOUL.md");
9777
+ if (await exists(lensesSrc) && await exists(soulPath)) {
9778
+ const lenses = await readFile(lensesSrc, "utf-8");
9779
+ await appendToFile(soulPath, "\n" + lenses.trim() + "\n");
9780
+ onProgress(`+ agents/${roleName}/SOUL.md (domain lenses)`);
9781
+ }
9782
+ const doneSrc = join(rolesDir, roleName, "DONE.md");
9783
+ const heartbeatPath = join(companyDir, "agents", roleName, "HEARTBEAT.md");
9784
+ if (await exists(doneSrc) && await exists(heartbeatPath)) {
9785
+ const done = await readFile(doneSrc, "utf-8");
9786
+ await appendToFile(heartbeatPath, "\n" + done.trim() + "\n");
9787
+ onProgress(`+ agents/${roleName}/HEARTBEAT.md (done criteria)`);
9788
+ }
9789
+ }
9790
+ }
9747
9791
  const finalDocsDir = join(companyDir, "docs");
9748
9792
  if (await exists(finalDocsDir)) {
9749
9793
  const docs = (await readdir(finalDocsDir)).sort();
@@ -10064,6 +10108,12 @@ Read: \`docs/${doc}\`
10064
10108
  }
10065
10109
  return rows;
10066
10110
  };
10111
+ const renderDeferredIsolationNote = (workspace) => {
10112
+ if (!enableIsolatedWorktrees || !isFreshLocalRepo(workspace)) return "";
10113
+ return `> **Enable isolated worktrees once the repo exists.** This instance has isolated worktrees enabled, but this project starts as a fresh local repository, so the \`executionWorkspacePolicy\` is intentionally omitted now \u2014 worktrees need an existing base ref and would fail on the first run. As the final step of **"Prepare GitHub repository"**, after the initial commit is pushed to \`main\`, switch this project to isolated worktrees (Project settings \u2192 isolated workspaces, or set \`executionWorkspacePolicy: { defaultMode: "isolated_workspace", workspaceStrategy: { type: "git_worktree", baseRef: "main" } }\` on the project). Until then agents share the project workspace; do not flip it before the repo has its first commit.
10114
+
10115
+ `;
10116
+ };
10067
10117
  const mainProject = resolvedProjects[0];
10068
10118
  const mainProjectName = mainProject?.name || companyName;
10069
10119
  if (resolvedProjects.length > 0) {
@@ -10088,6 +10138,7 @@ Read: \`docs/${doc}\`
10088
10138
 
10089
10139
  `;
10090
10140
  }
10141
+ bootstrap += renderDeferredIsolationNote(workspace);
10091
10142
  }
10092
10143
  }
10093
10144
  if (bootstrapLabels.length > 0) {
@@ -10212,7 +10263,7 @@ Read: \`docs/${doc}\`
10212
10263
  bootstrap += `- Do not reuse parent workspaces for subissues unless explicitly requested.
10213
10264
  `;
10214
10265
  if (moduleNames.includes("pr-review")) {
10215
- bootstrap += `- Required PR reviews use the issue's \`executionPolicy\`: a \`review\` stage for the Code Reviewer (plus any relevant domain reviewer \u2014 QA/UI/UX/DevOps), then a final \`approval\` stage for the Product Owner. Resolve each reviewer/approver role to its agentId. Do not create separate child review issues and do not use @-mentions.
10266
+ bootstrap += `- Required PR reviews use the issue's \`executionPolicy\`: a \`review\` stage for the Code Reviewer (plus any relevant domain reviewer \u2014 QA/UI/UX/DevOps), an \`approval\` stage for the Product Owner, then a final \`approval\` merge-gate stage for the Engineer (who merges the PR before recording approval, which closes the issue). The merge gate must be last so the Product Owner's approval does not auto-close the issue with the PR still open. Resolve each role to its agentId. Do not create separate child review issues and do not use @-mentions.
10216
10267
  `;
10217
10268
  }
10218
10269
  bootstrap += `
@@ -11150,6 +11201,7 @@ var plugin = definePlugin({
11150
11201
  presetRoutines: presetBootstrapData.routines,
11151
11202
  presetLabels: presetBootstrapData.labels,
11152
11203
  enableIsolatedWorktrees: await resolveEnableIsolatedWorkspacesFromInstance(cfg),
11204
+ enableEnrichedPersonas: cfgBool(cfg, "enableEnrichedPersonas"),
11153
11205
  outputDir: tmpDir,
11154
11206
  templatesDir
11155
11207
  });
@@ -11255,6 +11307,7 @@ var plugin = definePlugin({
11255
11307
  "disableBoardApprovalOnNewCompanies"
11256
11308
  );
11257
11309
  const enableIsolatedWorktrees = await resolveEnableIsolatedWorkspacesFromInstance(cfg, log);
11310
+ const enableEnrichedPersonas = cfgBool(cfg, "enableEnrichedPersonas");
11258
11311
  const companyName = typeof params.companyName === "string" ? params.companyName.trim() : "";
11259
11312
  const existingCompanyId = typeof params.existingCompanyId === "string" && params.existingCompanyId.trim() ? params.existingCompanyId.trim() : "";
11260
11313
  if (!companyName) return { error: "companyName is required", logs };
@@ -11295,6 +11348,7 @@ var plugin = definePlugin({
11295
11348
  presetRoutines: presetBootstrapData.routines,
11296
11349
  presetLabels: presetBootstrapData.labels,
11297
11350
  enableIsolatedWorktrees,
11351
+ enableEnrichedPersonas,
11298
11352
  outputDir,
11299
11353
  templatesDir,
11300
11354
  onProgress: log