@starlein/paperclip-plugin-company-wizard 0.4.17 → 0.4.20
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/CHANGELOG.md +91 -0
- package/README.md +11 -8
- package/dist/manifest.js +3 -1
- package/dist/manifest.js.map +2 -2
- package/dist/ui/index.css +9 -0
- package/dist/ui/index.css.map +2 -2
- package/dist/ui/index.js +164 -9
- package/dist/ui/index.js.map +4 -4
- package/dist/worker.js +2401 -635
- package/dist/worker.js.map +4 -4
- package/package.json +21 -21
- package/templates/bootstrap-instructions.md +0 -5
- package/templates/modules/auto-assign/agents/ceo/skills/auto-assign.fallback.md +2 -1
- package/templates/modules/auto-assign/skills/auto-assign.md +1 -0
- package/templates/modules/backlog/agents/ceo/skills/backlog-health.fallback.md +1 -0
- package/templates/modules/backlog/module.meta.json +2 -1
- package/templates/modules/backlog/skills/backlog-health.md +3 -1
- package/templates/modules/dependency-management/agents/security-engineer/skills/dependency-audit.fallback.md +18 -0
- package/templates/modules/game-design/agents/engineer/skills/game-design.fallback.md +17 -0
- package/templates/modules/github-repo/agents/engineer/skills/git-workflow.md +1 -1
- package/templates/modules/github-repo/docs/git-workflow.md +2 -2
- package/templates/modules/pr-review/README.md +2 -2
- package/templates/modules/pr-review/agents/code-reviewer/skills/code-review.md +3 -3
- package/templates/modules/pr-review/agents/engineer/skills/pr-workflow.md +6 -6
- package/templates/modules/pr-review/docs/pr-conventions.md +2 -2
- package/templates/modules/stall-detection/agents/ceo/skills/stall-detection.md +20 -17
- package/templates/modules/triage/agents/engineer/skills/issue-triage.fallback.md +20 -0
- package/templates/roles/audio-designer/HEARTBEAT.md +2 -2
- package/templates/roles/ceo/HEARTBEAT.md +2 -2
- package/templates/roles/ceo/role.meta.json +1 -1
- package/templates/roles/cmo/HEARTBEAT.md +2 -2
- package/templates/roles/code-reviewer/AGENTS.md +1 -1
- package/templates/roles/code-reviewer/HEARTBEAT.md +3 -2
- package/templates/roles/cto/HEARTBEAT.md +2 -2
- package/templates/roles/cto/role.meta.json +1 -1
- package/templates/roles/customer-success/HEARTBEAT.md +2 -2
- package/templates/roles/devops/HEARTBEAT.md +2 -2
- package/templates/roles/engineer/HEARTBEAT.md +3 -2
- package/templates/roles/game-artist/HEARTBEAT.md +2 -2
- package/templates/roles/game-designer/HEARTBEAT.md +2 -2
- package/templates/roles/level-designer/HEARTBEAT.md +2 -2
- package/templates/roles/product-owner/HEARTBEAT.md +2 -2
- package/templates/roles/qa/HEARTBEAT.md +2 -1
- package/templates/roles/security-engineer/HEARTBEAT.md +2 -2
- package/templates/roles/technical-writer/HEARTBEAT.md +2 -2
- package/templates/roles/ui-designer/HEARTBEAT.md +2 -2
- package/templates/roles/ux-researcher/HEARTBEAT.md +2 -2
package/dist/ui/index.js
CHANGED
|
@@ -581,7 +581,7 @@ var __iconNode45 = [
|
|
|
581
581
|
var Zap = createLucideIcon("zap", __iconNode45);
|
|
582
582
|
|
|
583
583
|
// src/ui/components/WizardShell.tsx
|
|
584
|
-
import { useEffect as useEffect9 } from "react";
|
|
584
|
+
import { useEffect as useEffect9, useRef as useRef8 } from "react";
|
|
585
585
|
|
|
586
586
|
// src/ui/context/WizardContext.tsx
|
|
587
587
|
import { createContext, useCallback, useContext, useState } from "react";
|
|
@@ -650,7 +650,9 @@ var initialState = {
|
|
|
650
650
|
goals: [],
|
|
651
651
|
projects: [],
|
|
652
652
|
issues: [],
|
|
653
|
-
|
|
653
|
+
// model is an optional override; empty means "use the adapter-appropriate default"
|
|
654
|
+
// (gpt-5.6 for Codex, claude-opus-4-8 for Claude) resolved in buildCeoAdapterConfig.
|
|
655
|
+
ceoAdapter: { type: "codex_local", cwd: "", model: "" },
|
|
654
656
|
existingCompanyId: "",
|
|
655
657
|
presetName: "",
|
|
656
658
|
selectedModules: [],
|
|
@@ -679,6 +681,8 @@ function reducer(state, action) {
|
|
|
679
681
|
}
|
|
680
682
|
case "GO_TO":
|
|
681
683
|
return { ...state, step: action.step, error: null };
|
|
684
|
+
case "RESTORE_NAV":
|
|
685
|
+
return { ...state, path: action.path, step: action.step, error: null };
|
|
682
686
|
case "SET_COMPANY_NAME":
|
|
683
687
|
return { ...state, companyName: action.value };
|
|
684
688
|
case "SET_GOALS":
|
|
@@ -4024,6 +4028,19 @@ CardFooter.displayName = "CardFooter";
|
|
|
4024
4028
|
|
|
4025
4029
|
// src/ui/components/steps/StepOnboarding.tsx
|
|
4026
4030
|
import { Fragment, jsx as jsx3, jsxs } from "react/jsx-runtime";
|
|
4031
|
+
async function upgradeInstalledPlugin(pluginId, version) {
|
|
4032
|
+
const response = await fetch(`/api/plugins/${encodeURIComponent(pluginId)}/upgrade`, {
|
|
4033
|
+
method: "POST",
|
|
4034
|
+
headers: { "Content-Type": "application/json" },
|
|
4035
|
+
credentials: "include",
|
|
4036
|
+
body: JSON.stringify({ version })
|
|
4037
|
+
});
|
|
4038
|
+
if (!response.ok) {
|
|
4039
|
+
const body = await response.json().catch(() => null);
|
|
4040
|
+
throw new Error(body?.error || `Plugin upgrade failed (${response.status})`);
|
|
4041
|
+
}
|
|
4042
|
+
return response.json();
|
|
4043
|
+
}
|
|
4027
4044
|
function PathCard({
|
|
4028
4045
|
icon: Icon2,
|
|
4029
4046
|
title,
|
|
@@ -4060,9 +4077,12 @@ function StepOnboarding() {
|
|
|
4060
4077
|
const dispatch = useWizardDispatch();
|
|
4061
4078
|
const refreshTemplates = usePluginAction("refresh-templates");
|
|
4062
4079
|
const checkUpdate = usePluginAction("check-update");
|
|
4080
|
+
const preparePluginUpdate = usePluginAction("prepare-plugin-update");
|
|
4063
4081
|
const [refreshing, setRefreshing] = useState2(false);
|
|
4064
4082
|
const [refreshMsg, setRefreshMsg] = useState2(null);
|
|
4065
4083
|
const [updateInfo, setUpdateInfo] = useState2(null);
|
|
4084
|
+
const [pluginUpdating, setPluginUpdating] = useState2(false);
|
|
4085
|
+
const [pluginUpdateMsg, setPluginUpdateMsg] = useState2(null);
|
|
4066
4086
|
useEffect(() => {
|
|
4067
4087
|
let cancelled = false;
|
|
4068
4088
|
checkUpdate({}).then((result) => {
|
|
@@ -4090,6 +4110,43 @@ function StepOnboarding() {
|
|
|
4090
4110
|
setRefreshing(false);
|
|
4091
4111
|
}
|
|
4092
4112
|
};
|
|
4113
|
+
const handlePluginUpdate = async () => {
|
|
4114
|
+
setPluginUpdating(true);
|
|
4115
|
+
setPluginUpdateMsg("Updating templates...");
|
|
4116
|
+
try {
|
|
4117
|
+
const prepared = await preparePluginUpdate({});
|
|
4118
|
+
if (!prepared?.ok) {
|
|
4119
|
+
throw new Error(prepared?.error || "Could not prepare plugin update");
|
|
4120
|
+
}
|
|
4121
|
+
if (!prepared.updateAvailable) {
|
|
4122
|
+
setUpdateInfo({
|
|
4123
|
+
ok: true,
|
|
4124
|
+
currentVersion: prepared.currentVersion,
|
|
4125
|
+
latestVersion: prepared.latestVersion,
|
|
4126
|
+
updateAvailable: false
|
|
4127
|
+
});
|
|
4128
|
+
setPluginUpdateMsg("Templates updated. Plugin is already current.");
|
|
4129
|
+
return;
|
|
4130
|
+
}
|
|
4131
|
+
if (!prepared.pluginId || !prepared.latestVersion) {
|
|
4132
|
+
throw new Error("Could not resolve installed plugin record or target version");
|
|
4133
|
+
}
|
|
4134
|
+
setPluginUpdateMsg(`Installing Company Wizard ${prepared.latestVersion}...`);
|
|
4135
|
+
await upgradeInstalledPlugin(prepared.pluginId, prepared.latestVersion);
|
|
4136
|
+
setUpdateInfo({
|
|
4137
|
+
ok: true,
|
|
4138
|
+
currentVersion: prepared.latestVersion,
|
|
4139
|
+
latestVersion: prepared.latestVersion,
|
|
4140
|
+
updateAvailable: false
|
|
4141
|
+
});
|
|
4142
|
+
setPluginUpdateMsg("Plugin updated. Reloading...");
|
|
4143
|
+
window.setTimeout(() => window.location.reload(), 1200);
|
|
4144
|
+
} catch (err) {
|
|
4145
|
+
setPluginUpdateMsg(err instanceof Error ? err.message : "Plugin update failed");
|
|
4146
|
+
} finally {
|
|
4147
|
+
setPluginUpdating(false);
|
|
4148
|
+
}
|
|
4149
|
+
};
|
|
4093
4150
|
return /* @__PURE__ */ jsxs("div", { className: "space-y-8", children: [
|
|
4094
4151
|
/* @__PURE__ */ jsxs("div", { className: "space-y-2", children: [
|
|
4095
4152
|
/* @__PURE__ */ jsx3("h1", { className: "text-2xl font-semibold tracking-tight", children: "Create a company" }),
|
|
@@ -4147,7 +4204,7 @@ function StepOnboarding() {
|
|
|
4147
4204
|
"button",
|
|
4148
4205
|
{
|
|
4149
4206
|
onClick: handleRefresh,
|
|
4150
|
-
disabled: refreshing,
|
|
4207
|
+
disabled: refreshing || pluginUpdating,
|
|
4151
4208
|
className: "flex items-center gap-1.5 text-xs text-muted-foreground hover:text-foreground transition-colors disabled:opacity-50",
|
|
4152
4209
|
children: [
|
|
4153
4210
|
/* @__PURE__ */ jsx3(RefreshCw, { className: cn("h-3 w-3", refreshing && "animate-spin") }),
|
|
@@ -4163,14 +4220,28 @@ function StepOnboarding() {
|
|
|
4163
4220
|
updateInfo.currentVersion,
|
|
4164
4221
|
" \u2192 ",
|
|
4165
4222
|
updateInfo.latestVersion,
|
|
4223
|
+
/* @__PURE__ */ jsxs(
|
|
4224
|
+
"button",
|
|
4225
|
+
{
|
|
4226
|
+
type: "button",
|
|
4227
|
+
onClick: handlePluginUpdate,
|
|
4228
|
+
disabled: pluginUpdating,
|
|
4229
|
+
className: "inline-flex items-center gap-1 font-medium text-foreground hover:underline disabled:opacity-50 disabled:no-underline",
|
|
4230
|
+
title: "Install the latest Company Wizard plugin, refresh templates, and reload",
|
|
4231
|
+
children: [
|
|
4232
|
+
/* @__PURE__ */ jsx3(RefreshCw, { className: cn("h-3 w-3", pluginUpdating && "animate-spin") }),
|
|
4233
|
+
pluginUpdating ? "Updating..." : "Update now"
|
|
4234
|
+
]
|
|
4235
|
+
}
|
|
4236
|
+
),
|
|
4166
4237
|
updateInfo.url && /* @__PURE__ */ jsxs(
|
|
4167
4238
|
"a",
|
|
4168
4239
|
{
|
|
4169
4240
|
href: updateInfo.url,
|
|
4170
4241
|
target: "_blank",
|
|
4171
4242
|
rel: "noreferrer",
|
|
4172
|
-
className: "inline-flex items-center gap-0.5
|
|
4173
|
-
title: "
|
|
4243
|
+
className: "inline-flex items-center gap-0.5 text-muted-foreground hover:text-foreground hover:underline",
|
|
4244
|
+
title: "Open the npm package page",
|
|
4174
4245
|
children: [
|
|
4175
4246
|
"npm",
|
|
4176
4247
|
/* @__PURE__ */ jsx3(ExternalLink, { className: "h-3 w-3" })
|
|
@@ -4179,6 +4250,16 @@ function StepOnboarding() {
|
|
|
4179
4250
|
)
|
|
4180
4251
|
] })
|
|
4181
4252
|
] }),
|
|
4253
|
+
pluginUpdateMsg && /* @__PURE__ */ jsx3(
|
|
4254
|
+
"span",
|
|
4255
|
+
{
|
|
4256
|
+
className: cn(
|
|
4257
|
+
"basis-full text-center text-xs",
|
|
4258
|
+
pluginUpdateMsg.includes("failed") || pluginUpdateMsg.includes("Could not") ? "text-destructive" : "text-muted-foreground"
|
|
4259
|
+
),
|
|
4260
|
+
children: pluginUpdateMsg
|
|
4261
|
+
}
|
|
4262
|
+
),
|
|
4182
4263
|
refreshMsg && /* @__PURE__ */ jsx3("span", { className: "text-xs text-muted-foreground", children: refreshMsg })
|
|
4183
4264
|
] })
|
|
4184
4265
|
] });
|
|
@@ -4302,6 +4383,13 @@ var ADAPTER_TYPES = [
|
|
|
4302
4383
|
{ value: "openclaw_gateway", label: "OpenClaw", desc: "OpenClaw gateway" },
|
|
4303
4384
|
{ value: "hermes_local", label: "Hermes", desc: "Local Hermes agent" }
|
|
4304
4385
|
];
|
|
4386
|
+
var MODEL_SUGGESTIONS = {
|
|
4387
|
+
codex_local: ["gpt-5.6", "gpt-5.6-sol", "gpt-5.6-terra", "gpt-5.6-luna", "gpt-5.5", "gpt-5.4"],
|
|
4388
|
+
claude_local: ["claude-opus-4-8", "claude-fable-5", "claude-mythos-5", "claude-sonnet-4-6"]
|
|
4389
|
+
};
|
|
4390
|
+
function modelSuggestionsFor(adapterType) {
|
|
4391
|
+
return MODEL_SUGGESTIONS[adapterType] ?? [];
|
|
4392
|
+
}
|
|
4305
4393
|
function StepName() {
|
|
4306
4394
|
const state = useWizard();
|
|
4307
4395
|
const dispatch = useWizardDispatch();
|
|
@@ -4396,11 +4484,18 @@ function StepName() {
|
|
|
4396
4484
|
/* @__PURE__ */ jsx6(
|
|
4397
4485
|
Input,
|
|
4398
4486
|
{
|
|
4399
|
-
|
|
4487
|
+
list: "ceo-model-suggestions",
|
|
4488
|
+
placeholder: modelSuggestionsFor(state.ceoAdapter.type)[0] || "default for adapter",
|
|
4400
4489
|
value: state.ceoAdapter.model,
|
|
4401
4490
|
onChange: (e) => dispatch({ type: "SET_CEO_ADAPTER", adapter: { model: e.target.value } })
|
|
4402
4491
|
}
|
|
4403
|
-
)
|
|
4492
|
+
),
|
|
4493
|
+
/* @__PURE__ */ jsx6("datalist", { id: "ceo-model-suggestions", children: modelSuggestionsFor(state.ceoAdapter.type).map((m) => /* @__PURE__ */ jsx6("option", { value: m }, m)) }),
|
|
4494
|
+
/* @__PURE__ */ jsxs2("p", { className: "text-xs text-muted-foreground", children: [
|
|
4495
|
+
"Leave empty for the adapter default (",
|
|
4496
|
+
modelSuggestionsFor(state.ceoAdapter.type)[0] || "adapter default",
|
|
4497
|
+
"). Codex: gpt-5.6 (+ sol/terra/luna). Claude: opus-4-8, fable-5, mythos-5."
|
|
4498
|
+
] })
|
|
4404
4499
|
] })
|
|
4405
4500
|
] })
|
|
4406
4501
|
] }),
|
|
@@ -6184,10 +6279,10 @@ function StepSummary() {
|
|
|
6184
6279
|
import { useState as useState8, useRef as useRef4, useEffect as useEffect5 } from "react";
|
|
6185
6280
|
import { usePluginAction as usePluginAction4 } from "@paperclipai/plugin-sdk/ui";
|
|
6186
6281
|
|
|
6187
|
-
// raw:/paperclip/paperclip-plugin-company-wizard/src/ui/prompts/interview-system.md
|
|
6282
|
+
// raw:/home/runner/work/paperclip-plugin-company-wizard/paperclip-plugin-company-wizard/src/ui/prompts/interview-system.md
|
|
6188
6283
|
var interview_system_default = 'You are the Company Wizard \u2014 an expert at assembling AI agent teams. You\'re enthusiastic but concise. Company Wizard bootstraps AI-agent company workspaces from composable templates.\n\nYou are conducting a guided interview to understand what company to set up.\n\n{{CATALOG}}\n\n## How Roles Work\n\n- **Base roles** (marked "always included") are auto-added. You do NOT list them in the JSON.\n- **All other roles** (listed under "Available Extra Roles") are OPTIONAL and must be EXPLICITLY listed in your JSON `roles` array if you want them.\n- **Critically: `engineer` is NOT a base role.** Most software projects need an engineer. If the project involves writing code, building software, or maintaining a repository, you MUST include `engineer` in your `roles` array. The preset does NOT auto-add roles \u2014 you must list every non-base role the company needs.\n- When in doubt, include the engineer. A company that builds software without an engineer agent will have no one to write code.\n\n## Interview Rules\n\n- Ask exactly ONE question per turn. Keep it short and energetic (1-2 sentences). Use a conversational tone.\n- Do NOT output JSON during questions \u2014 just ask the question as plain text.\n- Tailor each question based on previous answers. Show you understood what they said.\n- After 3 questions, summarize what you understood in a brief, enthusiastic paragraph. End with: "Ready to generate your configuration?"\n- When the user confirms, output a human-readable recommendation with reasoning, then the JSON config.\n\n## What to Ask About\n\nAcross your 3 questions, try to cover as many of these as the user\'s initial description left unclear:\n\n1. **What they\'re building** \u2014 Product type, target users, domain (fintech, SaaS, game, etc.)\n2. **Current stage** \u2014 Greenfield, existing codebase, research phase, relaunch?\n3. **Quality vs speed** \u2014 Ship fast, iterate? Or production-grade, high quality from the start?\n4. **Team needs** \u2014 Do they need code review, security, design, marketing, docs, DevOps?\n5. **Special requirements** \u2014 Compliance, accessibility, specific tech stack, CI/CD, game engine?\n6. **Repository** \u2014 Should Paperclip create a new Git repository/workspace, or should the agents use an existing external repo such as GitHub/GitLab? If external, ask for URL and branch/ref; never ask for tokens.\n\nDon\'t ask about things already clear from the initial description. Skip to what\'s missing.\n\n## Information Preservation\n\nThe user\'s interview answers are the primary source of context for the company. When generating the configuration:\n\n- **`companyDescription`**: Write a comprehensive 2-4 paragraph description that captures EVERYTHING learned during the interview \u2014 what the company does, what it\'s building, who it\'s for, key technical decisions, constraints, priorities, and any special context. This is the company\'s permanent record. Be thorough. Do NOT summarize into a single vague sentence.\n- **`goals`**: Array of goals. The first goal is the main user-specific company goal \u2014 its description is the most important field. Keep it outcome-first and product-first: the title and opening sentence must state the primary deliverable or operating outcome, not a supporting constraint. Write a THOROUGH, DETAILED description that includes EVERYTHING the user shared: full requirements, technical specs, acceptance criteria, constraints, edge cases, API contracts, user stories, design decisions, performance targets. Put compliance/security/accessibility/performance constraints in a clearly labelled "Constraints / quality bars" section unless the user explicitly says that constraint is the primary project. If the user\'s wording mixes a main outcome with secondary facts, determine which thing the agents should build/operate first and write that as the top-level goal; put side facts into acceptance criteria, risks, or sub-goals only when they are independent workstreams. Preset/module template goals are added by the wizard after your JSON, so do NOT replace the user\'s objective with generic preset goals like "Build a REST API" or "Set up CI/CD" unless the user explicitly asked only for that.\n- **`projects`**: Array of projects. Each has a `name`, `description`, `goals` array (goal titles it\'s linked to), and repository workspace metadata. If the user chose an external repo, use `workspace.sourceType: "git_repo"` with `repoUrl`, plus `repoRef`/`defaultRef` exactly when the user or repository context provides one; do not force a branch name or remote prefix. If no external repo was provided, use a fresh local Git repository with `workspace.sourceType: "local_path"`, `workspace.defaultRef: "main"` unless the user requested another initial branch, `workspace.setupCommand: "git init -b <defaultRef>"`, and `workspace.isPrimary: true`. Do not include `executionWorkspacePolicy`; the assembler applies isolated worktrees only when Paperclip\'s experimental isolated-workspaces setting is enabled and a usable project base ref exists.\n- **`issues`**: Array of 6-12 CONCRETE, domain-specific initial work items taken straight from what you learned in the interview \u2014 the real features, components, and integrations the user actually described, each with a `title`, a `description` with acceptance criteria, a `priority` (`critical`/`high`/`medium`/`low`), and `assignTo` set to a role on the team. These seed the backlog so the project starts in its actual domain. Issue titles should lead with the core product capability; secondary constraints belong in acceptance criteria or risk notes unless the issue is specifically about that constraint. Do NOT put generic scaffolding here (vision docs, linters, CI, branch protection) \u2014 the wizard adds those automatically.\n\n## RECOMMENDATION Format (when generating config)\n\n- One paragraph explaining your reasoning: why this preset, why these modules, why these roles.\n- A bullet list of the key choices.\n\nThen output the JSON (no markdown fences):\n{{CONFIG_FORMAT}}\n\n## Rules\n\n- `modules` should list ALL modules to activate (including preset ones).\n- `roles` should list ALL non-base roles the company needs. This includes roles that come with the preset. The system does not auto-add preset roles \u2014 you must list them explicitly.\n- If the project involves building software, `engineer` MUST be in `roles`.\n- The primary project MUST state whether it uses a fresh local Git repository or an external Git repository. Do not put credentials or tokens in repository fields.\n- Be pragmatic \u2014 don\'t over-engineer. Match the config to actual needs.\n';
|
|
6189
6284
|
|
|
6190
|
-
// raw:/paperclip/paperclip-plugin-company-wizard/src/ui/prompts/single-shot-system.md
|
|
6285
|
+
// raw:/home/runner/work/paperclip-plugin-company-wizard/paperclip-plugin-company-wizard/src/ui/prompts/single-shot-system.md
|
|
6191
6286
|
var single_shot_system_default = 'You are the Company Wizard. Company Wizard bootstraps AI-agent company workspaces from composable templates.\n\nGiven a natural language description of what the user wants to build, you select the best configuration.\n\n{{CATALOG}}\n\n## How Roles Work\n\n- **Base roles** (marked "always included") are auto-added. You do NOT list them in the JSON.\n- **All other roles** (listed under "Available Extra Roles") are OPTIONAL and must be EXPLICITLY listed in your JSON `roles` array if you want them.\n- **Critically: `engineer` is NOT a base role.** Most software projects need an engineer. If the project involves writing code, building software, or maintaining a repository, you MUST include `engineer` in your `roles` array. The preset does NOT auto-add roles \u2014 you must list every non-base role the company needs.\n- When in doubt, include the engineer. A company that builds software without an engineer agent will have no one to write code.\n\n## Instructions\n\n1. Analyze the user\'s description to understand: what they\'re building, their team size preference, quality vs speed priority, and any specific needs.\n2. Select the best preset as a starting point.\n3. List ALL modules to activate (including preset ones). Add extra modules beyond the preset if the description warrants them.\n4. List ALL non-base roles the company needs. This includes roles from the preset. If the project involves software, include `engineer`.\n5. Suggest a company name (PascalCase-friendly, short, memorable) if not obvious from the description.\n6. Write a thorough company description (2-4 paragraphs) capturing everything the user described \u2014 product, audience, tech stack, constraints, priorities, stage, and special context. This is the company\'s permanent record.\n7. Define goals as an array. The first goal is the main user-specific company goal \u2014 its description is the most important field. Keep it **outcome-first and product-first**: the title and opening sentence must state the primary deliverable or operating outcome, not a supporting constraint. Preserve compliance, security, accessibility, performance, tech-stack, and domain constraints inside the description under a clear "Constraints / quality bars" section unless the user explicitly says that constraint is the primary project. If the user\'s wording mixes a main outcome with secondary facts, ask yourself which thing the agents should build/operate first and write that as the top-level goal; put side facts into acceptance criteria, risks, or sub-goals only when they are independent workstreams. Include EVERYTHING the user described: full requirements, technical specs, acceptance criteria, constraints, edge cases, API contracts, user stories, performance targets. If the user provided a detailed spec, reproduce it in full, but do not let one constraint dominate the goal or initial issues. Preset/module template goals are added by the wizard after your JSON, so do NOT replace the user\'s objective with generic preset goals like "Build a REST API" or "Set up CI/CD" unless the user explicitly asked only for that.\n8. Define projects as an array. Most setups need one project linked to all goals. Name and describe the project concretely.\n9. Always decide the repository setup for the primary project:\n - If the user gives an existing GitHub/GitLab/remote Git repo, set `workspace.sourceType: "git_repo"`, include `repoUrl`, and set `repoRef`/`defaultRef` exactly when the user or repository context provides one. Do not force a branch name or remote prefix; Paperclip\'s project/worktree settings decide the worktree base ref.\n - If no external repository is given, assume Paperclip should create a fresh local Git repository. Set `workspace.sourceType: "local_path"`, `workspace.defaultRef: "main"` unless the user requested another initial branch, `workspace.setupCommand: "git init -b <defaultRef>"`, and `workspace.isPrimary: true`. Do NOT include an `executionWorkspacePolicy`; the assembler applies isolated worktrees only when Paperclip\'s experimental isolated-workspaces setting is enabled and a usable project base ref exists.\n - Never include credentials or tokens in repository URLs or project text.\n10. Define an `issues` array of 6-12 CONCRETE, domain-specific initial work items taken straight from the description \u2014 the real features, components, and integrations the user actually described, each with a `title`, a `description` with acceptance criteria, a `priority`, and `assignTo` set to a role on the team. These seed the backlog so the project starts in its actual domain instead of only doing generic setup. Issue titles should lead with the core product capability; secondary constraints belong in acceptance criteria or risk notes unless the issue is specifically about that constraint. Do NOT put generic scaffolding here (vision docs, linters, CI, branch protection) \u2014 the wizard adds those automatically.\n\nFirst write one paragraph explaining your reasoning: why this preset, why these modules, why these roles.\n\nThen output the JSON (no markdown fences):\n{{CONFIG_FORMAT}}\n';
|
|
6192
6287
|
|
|
6193
6288
|
// src/ui/prompts/messages.json
|
|
@@ -7555,6 +7650,30 @@ var STEP_COMPONENTS = {
|
|
|
7555
7650
|
provision: StepProvision,
|
|
7556
7651
|
done: StepDone
|
|
7557
7652
|
};
|
|
7653
|
+
var WIZARD_HISTORY_MARKER = "company-wizard";
|
|
7654
|
+
function isObject(value) {
|
|
7655
|
+
return typeof value === "object" && value !== null;
|
|
7656
|
+
}
|
|
7657
|
+
function isStep(value) {
|
|
7658
|
+
return typeof value === "string" && value in STEP_COMPONENTS;
|
|
7659
|
+
}
|
|
7660
|
+
function isWizardPath(value) {
|
|
7661
|
+
return value === null || value === "manual" || value === "ai" || value === "update";
|
|
7662
|
+
}
|
|
7663
|
+
function readWizardHistoryState(value) {
|
|
7664
|
+
if (!isObject(value)) return null;
|
|
7665
|
+
if (value.__paperclipPlugin !== WIZARD_HISTORY_MARKER) return null;
|
|
7666
|
+
if (!isStep(value.step) || !isWizardPath(value.path)) return null;
|
|
7667
|
+
return { step: value.step, path: value.path };
|
|
7668
|
+
}
|
|
7669
|
+
function buildWizardHistoryState(currentState, path, step) {
|
|
7670
|
+
return {
|
|
7671
|
+
...isObject(currentState) ? currentState : {},
|
|
7672
|
+
__paperclipPlugin: WIZARD_HISTORY_MARKER,
|
|
7673
|
+
path,
|
|
7674
|
+
step
|
|
7675
|
+
};
|
|
7676
|
+
}
|
|
7558
7677
|
function StepIndicator() {
|
|
7559
7678
|
const state = useWizard();
|
|
7560
7679
|
const current = getUserStepIndex(state);
|
|
@@ -7579,10 +7698,46 @@ function StepIndicator() {
|
|
|
7579
7698
|
function WizardShell() {
|
|
7580
7699
|
const state = useWizard();
|
|
7581
7700
|
const dispatch = useWizardDispatch();
|
|
7701
|
+
const restoredFromHistory = useRef8(false);
|
|
7702
|
+
const seededHistory = useRef8(false);
|
|
7582
7703
|
const StepComponent = STEP_COMPONENTS[state.step];
|
|
7583
7704
|
useEffect9(() => {
|
|
7584
7705
|
window.scrollTo({ top: 0 });
|
|
7585
7706
|
}, [state.step]);
|
|
7707
|
+
useEffect9(() => {
|
|
7708
|
+
const handlePopState = (event) => {
|
|
7709
|
+
const historyState = readWizardHistoryState(event.state);
|
|
7710
|
+
if (!historyState?.step) return;
|
|
7711
|
+
restoredFromHistory.current = true;
|
|
7712
|
+
dispatch({
|
|
7713
|
+
type: "RESTORE_NAV",
|
|
7714
|
+
path: historyState.path ?? null,
|
|
7715
|
+
step: historyState.step
|
|
7716
|
+
});
|
|
7717
|
+
};
|
|
7718
|
+
window.addEventListener("popstate", handlePopState);
|
|
7719
|
+
return () => window.removeEventListener("popstate", handlePopState);
|
|
7720
|
+
}, [dispatch]);
|
|
7721
|
+
useEffect9(() => {
|
|
7722
|
+
if (!seededHistory.current) {
|
|
7723
|
+
seededHistory.current = true;
|
|
7724
|
+
window.history.replaceState(
|
|
7725
|
+
buildWizardHistoryState(window.history.state, state.path, state.step),
|
|
7726
|
+
"",
|
|
7727
|
+
window.location.href
|
|
7728
|
+
);
|
|
7729
|
+
return;
|
|
7730
|
+
}
|
|
7731
|
+
if (restoredFromHistory.current) {
|
|
7732
|
+
restoredFromHistory.current = false;
|
|
7733
|
+
return;
|
|
7734
|
+
}
|
|
7735
|
+
window.history.pushState(
|
|
7736
|
+
buildWizardHistoryState(window.history.state, state.path, state.step),
|
|
7737
|
+
"",
|
|
7738
|
+
window.location.href
|
|
7739
|
+
);
|
|
7740
|
+
}, [state.path, state.step]);
|
|
7586
7741
|
return /* @__PURE__ */ jsxs15("div", { className: "flex flex-col", children: [
|
|
7587
7742
|
getUserStepIndex(state) >= 1 && state.step !== "provision" && state.step !== "done" && /* @__PURE__ */ jsx21("div", { className: "flex items-center justify-end px-6 py-3", children: /* @__PURE__ */ jsx21(StepIndicator, {}) }),
|
|
7588
7743
|
/* @__PURE__ */ jsx21("main", { className: "flex-1 flex items-start justify-center p-6", children: /* @__PURE__ */ jsx21("div", { className: "w-full max-w-2xl", children: /* @__PURE__ */ jsx21(StepComponent, {}) }) }),
|