Skip to content
Merged

v3 #9

Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
31 changes: 25 additions & 6 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -65,8 +65,25 @@ the lower-level setup command:
```bash
productize setup --agent codex
productize setup --agent claude --agent codex --yes
productize setup --all-agents --yes
```

Interactive setup chooses exactly one agent. Selecting OpenCode or Codex writes
skills only to `.agents/skills`; selecting Claude Code writes only to
`.claude/skills`. Repeat `--agent` to target several agents. Installing into every
supported agent directory requires the explicit `--all-agents` flag. Before
confirmation, Productize shows the exact unique directories it will modify.

If an older setup populated unwanted agent directories, preview and remove only
Productize-managed copies or symlinks while retaining the agent you use:

```bash
productize setup cleanup --keep-agent opencode --dry-run
productize setup cleanup --keep-agent opencode --yes
```

Cleanup preserves drifted, unknown, and user-owned files for manual review.

### 3. Run the lifecycle

Inside your AI agent (e.g. Claude Code), invoke the lifecycle skills in order. Each writes its output under `.productize/tasks/<slug>/`:
Expand Down Expand Up @@ -117,7 +134,7 @@ That's the whole loop. The rest of this README is reference.

### Skills & the catalog

Skills are self-contained Markdown bundles (`SKILL.md` + optional `references/`, `templates/`, `agents/`). Productize ships hundreds of them, embedded in the binary. `setup` resolves an **effective catalog** (bundled skills + any extensions, with conflicts resolved core-first) and writes it to `~/.productize/catalog/skills.json` (or `.productize/catalog/skills.json` for a single project).
Skills are self-contained Markdown bundles (`SKILL.md` + optional `references/`, `templates/`, `agents/`). Productize ships hundreds of them, embedded in the binary. `setup` resolves an **effective catalog** (bundled skills + any extensions, with conflicts resolved core-first), installs it into one selected agent target by default, and writes it to `~/.productize/catalog/skills.json` (or `.productize/catalog/skills.json` for a single project). Cleanup-only ownership checksums live beside it in `setup-ownership.json`; that manifest is metadata, not another skill store.

Skills are organized by a `tier:` frontmatter field:

Expand Down Expand Up @@ -202,8 +219,9 @@ productize runs watch <run-id> # stream a running job
|---------|--------------|
| `productize onboard existing` | Inventory an existing repo, generate knowledge, install skills, and register the workspace. |
| `productize init existing` | Create or refresh only `.productize/project/` knowledge docs. |
| `productize setup` | Install the skill catalog and reusable agents into your AI agent(s). |
| `productize setup` | Install the skill catalog and reusable agents into one selected agent target. |
| `productize setup --doctor` | Inspect setup targets, paths, and drift without installing. |
| `productize setup cleanup` | Safely remove old Productize-managed agent targets while retaining selected agents. |
| `productize exec [prompt]` | Run one ad-hoc prompt through an ACP runtime (headless). |
| `productize tasks run <slug>` | Execute a task workflow via the daemon. |
| `productize tasks validate` | Validate task-workflow metadata. |
Expand Down Expand Up @@ -275,17 +293,18 @@ See [docs/configuration.md](docs/configuration.md) for every key.
├── project/ ├── daemon/daemon.sock
│ ├── context.md ├── db/global.db
│ ├── conventions.md ├── catalog/skills.json
│ ├── architecture.md ├── runs/
│ ├── decisions.md ├── logs/
│ ├── constraints.md ── agents/
│ └── manual.md (optional)
│ ├── architecture.md ├── catalog/setup-ownership.json
│ ├── decisions.md ├── runs/
│ ├── constraints.md ── logs/
│ └── manual.md (optional) └── agents/
├── tasks/<slug>/
│ ├── _prd.md
│ ├── _techspec.md
│ ├── _tasks.md
│ ├── reviews-001/
│ └── adrs/
├── catalog/skills.json
├── catalog/setup-ownership.json
└── tasks/_archived/
```

Expand Down
7 changes: 7 additions & 0 deletions agents/productize-operator/AGENT.md
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,13 @@ For `/productize build <request>` or `build <request>`:
- If `.productize/project/context.md` is missing, degraded, stale, or reports
unresolved Knowledge Coverage findings, route first to
`productize onboard existing`.
- During setup or onboarding, select one agent target by default. Use one
`--agent <name>` flag per additional explicit target, and use `--all-agents`
only when the user explicitly wants every supported target.
- If old Productize-managed agent directories remain after a targeted install,
preview conservative cleanup with
`productize setup cleanup --keep-agent <name> --dry-run`. Ask for approval
before applying cleanup; drifted, unknown, and user-owned files must remain.
- If project context exists but PRD, TechSpec, or task files are missing, route
through `/create-prd`, `/create-techspec`, then `/create-tasks`.
- If task files exist, route to `productize tasks run <workflow>`.
Expand Down
49 changes: 45 additions & 4 deletions docs/cli-reference.md
Original file line number Diff line number Diff line change
Expand Up @@ -18,8 +18,8 @@ not invoke an AI model.

| Flag | Default | Description |
| ---- | ------- | ----------- |
| `--agent`, `-a` | | Target agent/editor name; repeatable |
| `--all-agents` | `false` | Install into every supported agent/editor destination |
| `--agent`, `-a` | | Target one agent/editor name per occurrence; repeat the flag for several |
| `--all-agents` | `false` | Explicitly install into every supported agent/editor destination |
| `--global`, `-g` | `false` | Install skills in user scope instead of project scope |
| `--copy` | `false` | Copy installed assets instead of symlinking |
| `--core-only` | `false` | Install only core workflow skills |
Expand All @@ -38,6 +38,11 @@ includes root-resolution evidence, inventory coverage, per-step results,
structured diagnostics, and exact next actions. Use `productize init existing`
when only the generated knowledge needs to be refreshed.

Interactive onboarding selects one agent. `--agent` and `--all-agents` are
mutually exclusive, and comma-separated agent lists are rejected. The combined
plan and JSON `setup.directory_summary` report the exact unique agent skill
directories and shared `.productize` metadata before application.

JSON uses `schema_version: 1` with `workspace_root`, `root_resolution`,
`inventory`, `knowledge`, `setup`, `workspace_registration`, `diagnostics`, and
`next_actions`. Step statuses are `planned`, `current`, `changed`, `skipped`,
Expand Down Expand Up @@ -86,7 +91,7 @@ productize setup [flags]

| Flag | Default | Description |
| ---- | ------- | ----------- |
| `--agent`, `-a` | | Target agent name, repeatable |
| `--agent`, `-a` | | Target one agent name per occurrence; repeat for several |
| `--skill`, `-s` | | Skill name to install, repeatable |
| `--global`, `-g` | `false` | Install to user directory instead of project |
| `--copy` | `false` | Copy files instead of symlinking |
Expand All @@ -96,7 +101,7 @@ productize setup [flags]
| `--yes`, `-y` | `false` | Skip confirmation prompts |
| `--core-only` | `false` | Install only core workflow, lifecycle, and gate skills |
| `--no-tactical` | `false` | Alias for `--core-only` |
| `--all-agents` | `false` | Install to every supported agent/editor destination |
| `--all-agents` | `false` | Explicitly install to every supported agent/editor destination |
| `--all` | `false` | Deprecated: setup installs all skills by default; also skips prompts |

Non-interactive installs require an explicit target:
Expand All @@ -107,10 +112,46 @@ productize setup --all-agents --yes
productize setup --doctor --agent opencode --format json
```

Interactive setup uses a single-choice prompt. Exactly one detected agent is
preselected; if several or none are detected, a choice is required with no
default. `--agent` accepts one name per occurrence, cannot be combined with
`--all-agents`, and never creates another agent's skill directory. OpenCode and
Codex intentionally share `.agents/skills`; Claude Code uses `.claude/skills`.
The confirmation summary lists every unique directory, overwrite count, install
mode, skill count, and affected reusable-agent count.

Use `--doctor` to see the detected agents, selected targets, install paths,
catalog path, stale or missing assets, and extension conflicts before changing
anything.

## `productize setup cleanup`

Remove old Productize-managed skill installations without touching the retained
agent targets or shared `.productize` project state.

```bash
productize setup cleanup --keep-agent opencode --dry-run
productize setup cleanup --keep-agent opencode --yes
productize setup cleanup --keep-agent codex --keep-agent claude-code --yes
```

| Flag | Default | Description |
| ---- | ------- | ----------- |
| `--keep-agent` | | Desired agent target to retain; repeatable |
| `--global`, `-g` | `false` | Clean user-scoped instead of project-scoped targets |
| `--dry-run` | `false` | Preview without filesystem mutations |
| `--yes`, `-y` | `false` | Skip the one cleanup confirmation |
| `--format` | `text` | Stable output format: `text` or `json` |

Cleanup uses setup ownership metadata when available. Legacy paths are removable
only when they are Productize symlinks to the expected canonical skill path or
byte-identical copies of the current effective skill source. Drifted, unknown,
and user-owned content is preserved and reported as `needs_review`. Cleanup never
removes `.productize/agents`, the setup catalog, project knowledge, or workflows.
JSON uses `schema_version: 1`; exit codes are `0` for clean/unchanged/feasible
dry-run, `1` for invalid selection, cancellation, or review items, and `2` for
filesystem or output failure.

## `productize upgrade`

Upgrade Productize to the latest release.
Expand Down
18 changes: 16 additions & 2 deletions docs/skills.md
Original file line number Diff line number Diff line change
Expand Up @@ -39,23 +39,37 @@ Skills are split into two tiers so you can choose how much to install:
- **Core** — the spine of the workflow. The actual core set (from `SkillCatalogTier` in `internal/setup/catalog_export.go`) is: the lifecycle skills `create-prd`, `create-techspec`, `create-tasks`, `execute-task`, `review-round`, `fix-reviews`, `final-verify`, and `workflow-memory`; the review gates `productize-product-review`, `productize-design-review`, `productize-eng-review`, `productize-qa`, `productize-dx-review`, `productize-comms-review`, `productize-release`, and `productize-docs`; and the orchestration skills `productize`, `productize-0-1`, `productize-operate`, `productize-grow`, `productize-autoplan`, and `productize-thesis-review`. Always installed, including with `--core-only`.
- **Tactical** — everything else: the broad library of domain advisors and analyses across product, design, research, QA, growth, metrics, finance, and engineering. Installed by default; skip them with `--no-tactical` (an alias for `--core-only`).

By default, `productize setup` installs **everything** (the full-power default). Narrow it with:
By default, `productize setup` installs the **full skill catalog** into one
interactively selected agent target. It does not populate every detected agent
directory. Narrow the skills or explicitly broaden the agent targets with:

```bash
productize setup --agent codex # explicit target for non-interactive installs
productize setup --core-only # core tier only
productize setup --skill create-prd --skill create-tasks # specific skills
productize setup --list # preview the resolved catalog
productize setup --doctor --agent codex --format json
productize setup --agent codex --agent claude-code # exactly two agent targets
productize setup --all-agents --yes # every target, explicit only
```

OpenCode and Codex use the shared `.agents/skills` discovery directory; Claude
Code uses `.claude/skills`. Repeated targets that share a physical directory are
deduplicated. Use `productize setup cleanup --keep-agent <name> --dry-run` to
inspect old Productize-managed targets before removing them.

## The effective catalog

At setup time Productize resolves an **effective catalog** — the bundled skills plus any installed [extensions](extensibility/index.md), with conflicts resolved deterministically (core skills and higher-precedence sources win). The result is written to:

- `~/.productize/catalog/skills.json` — global install
- `.productize/catalog/skills.json` — project install

Setup also records cleanup-only ownership metadata in
`setup-ownership.json` beside that catalog. It contains scope, agent, skill,
relative target, materialization mode, and installed-content checksum; it is not
a second skill store.

This catalog is what your agents read to discover available skills. It's plain JSON; inspect it any time to see exactly what's installed and where each skill came from (bundled vs. extension).

## How agents use skills
Expand All @@ -72,6 +86,6 @@ the exact lifecycle skill you need.
1. Create `skills/<name>/SKILL.md` (or put it in an extension) with `name`, `description`, and `tier` frontmatter.
2. Add `references/` or `templates/` if the skill needs supporting material.
3. Run `productize setup --list` to confirm it resolves into the catalog.
4. Run `productize setup` to install it into your agents.
4. Run `productize setup` and select one agent, or pass explicit repeated `--agent` flags.

To distribute skills to others, package them as an [extension](extensibility/index.md).
9 changes: 8 additions & 1 deletion docs/workflow.md
Original file line number Diff line number Diff line change
Expand Up @@ -65,7 +65,14 @@ productize setup
```

This lower-level command is useful for new repositories or when setup must be
managed separately. `onboard existing` already performs project-scoped setup.
managed separately. Interactive setup selects one agent and shows the exact
directories before confirmation. Use repeated `--agent` flags for several
targets or explicit `--all-agents` for every supported target. `onboard existing`
uses the same selection contract and already performs project-scoped setup.

To remove old Productize-managed agent directories without deleting drifted or
user-owned content, run `productize setup cleanup --keep-agent <name> --dry-run`,
then rerun with `--yes` after reviewing the plan.

---

Expand Down
55 changes: 41 additions & 14 deletions internal/cli/onboard_command.go
Original file line number Diff line number Diff line change
Expand Up @@ -47,6 +47,7 @@ type onboardCommandOptions struct {
force bool
yes bool
format string
interactive bool
}

type onboardInventorySummary struct {
Expand Down Expand Up @@ -92,14 +93,16 @@ type onboardKnowledgeStep struct {
}

type onboardSetupStep struct {
Status onboardStepStatus `json:"status"`
Scope string `json:"scope,omitempty"`
Mode string `json:"mode,omitempty"`
SelectedAgents []string `json:"selected_agents"`
SkillTargets int `json:"skill_targets"`
ReusableAgentTargets int `json:"reusable_agent_targets"`
Changes int `json:"changes"`
OverwriteTargets []string `json:"overwrite_targets"`
Status onboardStepStatus `json:"status"`
Scope string `json:"scope,omitempty"`
Mode string `json:"mode,omitempty"`
SelectedAgents []string `json:"selected_agents"`
SkillTargets int `json:"skill_targets"`
ReusableAgentTargets int `json:"reusable_agent_targets"`
Changes int `json:"changes"`
OverwriteTargets []string `json:"overwrite_targets"`
DirectorySummary setupDirectorySummary `json:"directory_summary"`
CleanupCommand string `json:"cleanup_command,omitempty"`
}

type onboardRegistrationStep struct {
Expand Down Expand Up @@ -196,7 +199,8 @@ func newOnboardExistingCommandWithState(state *onboardCommandState) *cobra.Comma
SilenceUsage: true,
Args: cobra.MaximumNArgs(1),
Long: `Deterministically inspect an existing repository, generate Productize project
knowledge, install Productize setup assets for selected agents, and register the workspace.`,
knowledge, install Productize setup assets for one interactively selected agent (or explicit
repeated --agent targets), and register the workspace.`,
Example: ` productize onboard existing
productize onboard existing ../my-app --agent codex --yes
productize onboard existing --all-agents --yes
Expand All @@ -205,8 +209,13 @@ knowledge, install Productize setup assets for selected agents, and register the
RunE: state.run,
}
flags := cmd.Flags()
flags.StringSliceVarP(&state.options.agentNames, "agent", "a", nil, "Target agent/editor name (repeatable)")
flags.BoolVar(&state.options.allAgents, "all-agents", false, "Install to every supported agent/editor destination")
flags.StringArrayVarP(&state.options.agentNames, "agent", "a", nil, "Target one agent/editor name per occurrence")
flags.BoolVar(
&state.options.allAgents,
"all-agents",
false,
"Explicitly install to every supported agent/editor destination",
)
flags.BoolVarP(&state.options.global, "global", "g", false, "Install setup assets in the user scope")
flags.BoolVar(&state.options.copy, "copy", false, "Copy setup assets instead of symlinking them")
flags.BoolVar(&state.options.coreOnly, "core-only", false, "Install only core Productize skills")
Expand Down Expand Up @@ -277,18 +286,20 @@ func onboardPreflightExitCode(err error) int {

func (s *onboardCommandState) validate() error {
interactive := s.isInteractive != nil && s.isInteractive()
s.options.interactive = interactive
if err := s.validateFlagCombinations(); err != nil {
return err
}
return s.validateExecutionMode(interactive)
}

func (s *onboardCommandState) validateFlagCombinations() error {
if err := validateAgentTargetFlags("--agent", s.options.agentNames, s.options.allAgents); err != nil {
return err
}
switch {
case s.options.coreOnly && s.options.noTactical:
return errors.New("use only one of --core-only or --no-tactical")
case s.options.allAgents && len(s.options.agentNames) > 0:
return errors.New("use only one of --agent or --all-agents")
case s.options.skipSetup && (len(s.options.agentNames) > 0 || s.options.allAgents):
return errors.New("--skip-setup cannot be combined with --agent or --all-agents")
case s.options.skipSetup && (s.options.global || s.options.copy || s.options.coreOnly || s.options.noTactical):
Expand Down Expand Up @@ -664,11 +675,19 @@ func reviewStatus(result *onboardResult) onboardStatus {

func nextOnboardActions(result *onboardResult) []onboardNextAction {
if result.Status == onboardStatusReady && !result.DryRun {
return []onboardNextAction{{
actions := []onboardNextAction{{
Type: "skill",
Command: "/create-prd <feature>",
Description: "Create the first Productize PRD",
}}
if result.Setup.CleanupCommand != "" {
actions = append(actions, onboardNextAction{
Type: "command",
Command: result.Setup.CleanupCommand,
Description: "Optionally remove old Productize-managed agent targets",
})
}
return actions
}
if result.Status == onboardStatusReady {
return []onboardNextAction{{
Expand Down Expand Up @@ -708,6 +727,14 @@ func nextOnboardActions(result *onboardResult) []onboardNextAction {
}
actions = append(actions, action)
}
if !result.DryRun && result.Setup.CleanupCommand != "" &&
result.Setup.Status != onboardStepFailed && result.Setup.Status != onboardStepSkipped {
actions = append(actions, onboardNextAction{
Type: "command",
Command: result.Setup.CleanupCommand,
Description: "Optionally remove old Productize-managed agent targets",
})
}
sort.Slice(actions, func(i, j int) bool {
left := strings.Join(
[]string{actions[i].Type, actions[i].Path, actions[i].Command, actions[i].Description},
Expand Down
Loading