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

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/README.md CHANGED
@@ -29,7 +29,7 @@
29
29
  #### Bootstrap reliability
30
30
 
31
31
  - **Agents provisioned with complete instructions** — every non-CEO agent is now created by the plugin directly with its full `instructionsBundle` (AGENTS.md + HEARTBEAT/SOUL/TOOLS + skills). Previously the CEO created these agents during bootstrap with only an `instructionsFilePath`, leaving each agent with a bare AGENTS.md and fragile external path references
32
- - **Routines created directly during provisioning** — Paperclip only allows an agent to create routines assigned to itself, so the CEO could not create routines owned by the Product Owner. The plugin now creates all routines with board authority at provisioning time; BOOTSTRAP.md tells the CEO they already exist
32
+ - **Routines created directly during provisioning** — Paperclip only allows an agent to create routines assigned to itself, so the CEO could not create routines owned by the Product Owner. The plugin now creates all routines with board authority at provisioning time and pre-creates the main project so every routine — including those owned by non-CEO agents — is linked to it; BOOTSTRAP.md tells the CEO they already exist
33
33
  - **Worker agents no longer run always-on heartbeats** — enabling heartbeats on every provisioned agent caused bursts of concurrent runs that crashed the dev server. Only the CEO keeps an always-on heartbeat; all other agents are woken on assignment
34
34
  - **Fresh local repos no longer bootstrap with isolated git worktrees** — provisioning a brand-new `local_path` project with an `isolated_workspace` / `git_worktree` policy made worker agents try to branch off `main` before the repo existed, so early runs failed and agents flipped to `error`. The isolated policy is now suppressed for fresh local repos (agents work in the shared project workspace during bootstrap); existing external repos keep it. Guarded in `assemble.js` and removed at the source in `StepRepository` and the AI wizard prompts
35
35
  - **Workspace isolation follows Paperclip instance settings** — `enableIsolatedWorktrees` is no longer a plugin setting. The wizard reads `enableIsolatedWorkspaces` from the Paperclip instance experimental settings and only applies `isolated_workspace` / `git_worktree` for external repositories when that setting is enabled.
@@ -42,6 +42,7 @@
42
42
  - **Doc references use relative paths** (`docs/<file>`) instead of absolute paths that baked in the collision-suffixed company directory name
43
43
  - Duplicate bootstrap issues (same title from module + preset) are now deduplicated; preset issue wins
44
44
  - CFO role removed — was orphaned (no preset, no capability, never activated)
45
+ - **PR bodies and comments use `--body-file`** — review skills posted GitHub PR bodies and comments with inline `gh pr … --body "..."`, where a double-quoted shell string keeps `\n` literal, so multi-line Markdown rendered as literal `text\ntext`. All PR-review guidance now writes Markdown to a file and uses `--body-file`, with a verdict-heading comment template documented in `pr-conventions.md`
45
46
 
46
47
  #### AI wizard
47
48
 
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.21",
5
+ version: "0.3.22",
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>",
@@ -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.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"],
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.22',\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
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
@@ -10116,10 +10116,21 @@ Read: \`docs/${doc}\`
10116
10116
  };
10117
10117
  const mainProject = resolvedProjects[0];
10118
10118
  const mainProjectName = mainProject?.name || companyName;
10119
+ const mainProjectInfo = mainProject ? {
10120
+ name: mainProjectName,
10121
+ description: mainProject.description || "",
10122
+ workspace: normalizeProjectWorkspace(mainProject)
10123
+ } : null;
10124
+ const mainProjectPreCreated = initialRoutines.length > 0 && mainProjectInfo !== null;
10119
10125
  if (resolvedProjects.length > 0) {
10120
10126
  bootstrap += `## Projects
10121
10127
 
10122
10128
  `;
10129
+ if (mainProjectPreCreated) {
10130
+ bootstrap += `> **The Company Wizard has already created the main project "${mainProjectName}"** (with board authority) so the scheduled routines could be linked to it. Do NOT recreate it \u2014 create issues against it, and link the goals above to it.
10131
+
10132
+ `;
10133
+ }
10123
10134
  for (const proj of resolvedProjects) {
10124
10135
  const workspace = normalizeProjectWorkspace(proj);
10125
10136
  bootstrap += `### ${proj.name}
@@ -10312,14 +10323,20 @@ Read: \`docs/${doc}\`
10312
10323
  bootstrap += `${stepN++}. **Create goal** "${g.title}" (level: ${level}${parentNote})
10313
10324
  `;
10314
10325
  }
10315
- for (const proj of resolvedProjects) {
10326
+ resolvedProjects.forEach((proj, idx) => {
10316
10327
  const workspace = normalizeProjectWorkspace(proj);
10317
10328
  const goalLinks = proj.goals?.length > 0 ? `, goalIds \u2192 [${proj.goals.map((g) => `"${g}"`).join(", ")}]` : "";
10318
10329
  const activePolicy = effectiveExecutionPolicy(proj, workspace);
10319
10330
  const policy = activePolicy?.defaultMode ? `, executionWorkspacePolicy.defaultMode: "${activePolicy.defaultMode}"` : "";
10320
- bootstrap += `${stepN++}. **Create project** "${proj.name}" (workspace: ${formatWorkspaceObject(workspace)}${policy}${goalLinks})
10331
+ if (idx === 0 && mainProjectPreCreated) {
10332
+ const goalLinkInstruction = goalLinks ? ` After creating the goals above, link them to it (${goalLinks.replace(/^, /, "")}).` : "";
10333
+ bootstrap += `${stepN++}. **Main project already created** \u2014 the Company Wizard provisioned project "${proj.name}" (with board authority) so the scheduled routines could be linked to it. Do NOT recreate it.${goalLinkInstruction}
10321
10334
  `;
10322
- }
10335
+ } else {
10336
+ bootstrap += `${stepN++}. **Create project** "${proj.name}" (workspace: ${formatWorkspaceObject(workspace)}${policy}${goalLinks})
10337
+ `;
10338
+ }
10339
+ });
10323
10340
  if (bootstrapLabels.length > 0) {
10324
10341
  bootstrap += `${stepN++}. **Create labels** \u2014 create each label exactly as listed in the Labels section before creating issues
10325
10342
  `;
@@ -10338,7 +10355,14 @@ Read: \`docs/${doc}\`
10338
10355
  `;
10339
10356
  await writeFile(join(companyDir, "BOOTSTRAP.md"), bootstrap);
10340
10357
  onProgress("+ BOOTSTRAP.md");
10341
- return { companyDir, allRoles, initialIssues, initialRoutines, roleAdapterOverrides };
10358
+ return {
10359
+ companyDir,
10360
+ allRoles,
10361
+ initialIssues,
10362
+ initialRoutines,
10363
+ roleAdapterOverrides,
10364
+ mainProject: mainProjectInfo
10365
+ };
10342
10366
  }
10343
10367
 
10344
10368
  // src/api/client.js
@@ -11599,6 +11623,25 @@ var plugin = definePlugin({
11599
11623
  }
11600
11624
  if (!existingCompanyId) {
11601
11625
  const routines = Array.isArray(assembleResult.initialRoutines) ? assembleResult.initialRoutines : [];
11626
+ let mainProjectId;
11627
+ const mainProject = assembleResult.mainProject;
11628
+ if (routines.length > 0 && mainProject?.name) {
11629
+ try {
11630
+ const createdProject = await client.createProject(companyId, {
11631
+ name: mainProject.name,
11632
+ description: mainProject.description,
11633
+ workspace: mainProject.workspace
11634
+ });
11635
+ mainProjectId = createdProject?.id;
11636
+ log(
11637
+ `\u2713 Main project "${mainProject.name}" created${mainProjectId ? ` (${mainProjectId})` : " (no id returned)"}`
11638
+ );
11639
+ } catch (err) {
11640
+ log(
11641
+ `\u26A0 Could not create main project "${mainProject.name}": ${err instanceof Error ? err.message : String(err)}. Routines will be created without a project.`
11642
+ );
11643
+ }
11644
+ }
11602
11645
  for (const routine of routines) {
11603
11646
  const title = typeof routine.title === "string" && routine.title.trim() ? routine.title.trim() : typeof routine.name === "string" ? routine.name.trim() : "";
11604
11647
  if (!title) continue;
@@ -11609,6 +11652,7 @@ var plugin = definePlugin({
11609
11652
  title,
11610
11653
  description: routine.description,
11611
11654
  assigneeAgentId,
11655
+ projectId: mainProjectId,
11612
11656
  priority: routine.priority || "medium",
11613
11657
  concurrencyPolicy: routine.concurrencyPolicy || "skip_if_active"
11614
11658
  });