面板

pbitante2026-10-27查看 528复制 394

同时在一个问题(代码更改、计划或规范、开放式问题或当前对话)前面放置多个角色,并显示他们不同意的地方和原因。当用户要求面板、多个视角或“X 和 Y 各说些什么”时使用。

Download (.md)

📘如何使用这个技能

  1. 1
    复制技能内容·点击上方「Copy SKILL.md」复制全部内容,或 Download 下载到本地
  2. 2
    打开你的 AI 客户端·支持 Claude Code、Trae、Cursor、ChatGPT、DeepSeek、Kimi 等任意 AI 助手
  3. 3
    粘贴为系统提示/知识文件·Claude Code:放入 .claude/skills/ 目录;普通对话:作为首条消息发送并说「请严格按这份技能文档执行」
  4. 4
    直接提出你的需求·AI 会按技能定义的工作流、格式和约束来处理,无需再解释背景

💡 提示:技能生效后,每次对话只需一句需求,AI 会按 SKILL.md 的流程执行。

SKILL.md28547 chars
---
name: panel
description: Put several personas in front of one question at once (a code change, a plan or spec, an open question, or the current conversation) and show where and why they disagree. Use when the user asks for a panel, multiple perspectives, or "what would X and Y each say".
---

# panel

Run 2–6 personas as parallel, read-only panelists. Validate and compare their judgments, and report their disagreements. A panel always has **at least 2** panelists; for a single persona, suggest the `operator` or `author` skills instead.

## Tools

First check that `<base directory>/../operator/scripts/persona.mjs` exists. If it doesn't, stop and say: "This skill must be used from the aska plugin (its operator skill and CLI are missing)."

Run the CLI from the user's project directory:

    node "<base directory>/../operator/scripts/persona.mjs" <command>

- `list personas --json`, `list panels --json`, `list units --json`: what exists.
- `prompt <name> --panel`: one persona's panel prompt.
- `lineup --json [--model <m>] <names…>`: who sits on the panel and the model each runs on. Pass the names exactly as the user typed them; it prints `{ panel, panelists: [{ persona, canonical, model, modelSource }], diagnostics }`.
- `check-judgment <name> --file <path>`: validate one judgment.
- `check-evidence --file <path>`: validate one investigator's evidence.
- `runs new`: create the run folder and print its path.
- `compare --file <path> --json [--record]`: compare the panel; `--record` also updates the run's `meta.json`.

`list personas --json` rows have fields `canonical, name, scope, plugin, path, description, shadowedBy, valid, errorCount, extends, units, model`, where `units` is `{ primary, secondary, deprioritized }`, each a list of `{ canonical, description, threshold }`, or `null` when the persona doesn't resolve or is shadowed. `model` is the persona's default model for panels, or `null`.

`list panels --json` rows have fields `canonical, name, scope, plugin, path, description, personas, models, shadowedBy, valid, errorCount`, where `models` maps some of `personas`, exactly as listed, to a model alias such as `haiku`, `sonnet` or `opus` (`{}` when the panel sets none).

Never pick panelists or models from these rows yourself: `lineup` does it (step 1b).

`list units --json` rows have fields `canonical, name, scope, plugin, path, description, shadowedBy, valid, errorCount, threshold, appliesWhen`.

ALWAYS pass `--file` to `check-judgment` and to `compare` — never pipe stdin. An idle socket stdin can hang the command forever, and a TTY stdin exits 2.

## 1. Choose the panelists

The user writes `/aska:panel [--model <m>] [<panel> [<member>@<m> …] | <persona>[@<m>] <persona>[@<m>] …] : <question>`.

- `--model <m>` puts every panelist on `<m>` for this run.
- `<persona>@<m>` puts one panelist on `<m>`.
- `<panel> <member>@<m> …` is the saved panel with some members on other models: it applies when the first name is a saved panel and every other name is one of its members with `@<m>`. It still runs as that saved panel. An untagged name after the first makes the names a persona lineup, as before.
- Words work too: "tester on sonnet", "historian on haiku" mean `tester@sonnet`, `historian@haiku`.

A panelist's model comes from, in order: its own `@`, then `--model`, then the saved panel's `models`, then the persona's default, then the session's model. `lineup` applies that order; you never do.

1. **Two or more persona names (any other form):** use exactly those.
2. **A saved panel, alone or followed only by `<member>@<m>` tags** (`list panels --json`): use its personas. Add its notes to the brief. If the single name is `default` or `aska:default` and no such panel exists, say that `aska:default` is now `aska:ship`.
3. **No names, and a user or project `default` panel exists:** use it, and say "using your default panel (`<path>`)". The plugin ships no `default` panel. If that `default` panel is invalid, say so (with its path) and propose a lineup instead.
4. **No names otherwise, or the user asks in words for a suggestion** (for example "suggest a panel for …"): propose a lineup (step 1a) and wait for the user's reply. A request in words overrides even the user's own `default`. There is no `suggest` keyword; a persona or panel named `suggest` is just a name.

If fewer than 2 resolvable personas remain, stop and explain why. If that's because fewer than 2 personas exist at all, say there are no personas to put on a panel (or only one, naming it) and offer to build them with `/aska:author`. This applies to proposals too: never propose fewer than 2 candidates. Don't run a panel any other way.

### 1a. Propose a lineup

Look at the question, the subject type (see step 2), and a light view of the materials: for a change, the changed file list and a diffstat; for documents, their headings. Don't review them. Then read the catalog: `list personas --json`, `list panels --json` and `list units --json`.

Candidates are `list personas --json` rows with `valid: true`, `shadowedBy: null` and non-null `units`. Saved panels you may propose are `list panels --json` rows with `valid: true` and `shadowedBy: null`.

1. **Name the concerns.** Choose 2–5 units the question turns on, only from units some candidate holds. Use each unit's `appliesWhen` to rule it in or out.
2. **Cover them.** Every concern must be primary for at least one panelist. Choose the smallest set of personas that does this, between 2 and 6 personas.
3. **Make disagreement possible.** For the top concern, prefer adding a persona that holds it in a lower tier, deprioritizes it, or ranks it below a competing concern. Never seat two personas whose primary units are identical.
4. **Check the saved panels.** If one covers every concern as primary, propose it by name; it runs as that saved panel, with its notes. If one covers all but one or two concerns, propose it plus the missing personas; that run is ad-hoc (`panel: null`) and keeps the panel's notes in the brief. On a tie between panels, prefer project, then user, then plugin scope. Prefer `aska:code` over `aska:code-lean` unless the user says the branch will be squashed on merge, or its commit history isn't a concern; when you propose `aska:code`, mention that `aska:code-lean` is cheaper for a branch that will be squashed.
5. **Flag gaps.** If a concern that matters is primary for no candidate, say so and offer `/aska:author`. Never stretch a persona to cover a concern it doesn't hold.

Show the proposal in exactly this layout. Nothing launches until the user replies.

Keep any `--model` and `@` the user gave. Once the lineup is drafted, run `lineup --json [--model <m>] <proposed names…>` on the proposed names (as step 1b says to build them), never from your own reading of the catalog. Beside a panelist whose row has a model, show it and where it comes from: `aska:tester (sonnet, saved panel) — …`. Never suggest a model that the user, the saved panel or the persona didn't set, and never suggest `fable`. An edit such as "put the tester on haiku" becomes `tester@haiku`. Dropping a persona drops its tag.

```
Question: "<the user's question, word for word>"
Concerns: <unit>, <unit>, …

Proposed panel:
  <persona> — <the concerns it holds, and their tiers>; <why it's here, if not obvious>
  <persona> — …

<Only if a saved panel was considered and not chosen: which one, and why not.>

Run this panel? Reply yes, edit it ("add …", "drop …"), or name a saved panel.
```

When the proposal is a saved panel, the header line is `Proposed panel: <name> (saved, <scope>)`, and the personas under it are the panel's own. Every reason names units from the catalog. Never preview what any panelist will conclude.

The user can accept, edit ("drop …", "add …", "swap X for Y"), or name a saved panel instead. Re-check an edited lineup: 2–6 panelists, each resolving. An edited saved panel runs ad-hoc (`panel: null`) and keeps that panel's notes in the brief. Resolve the lineup with `lineup` (step 1b).

### 1b. Resolve the lineup

Once the panelists are chosen, run `lineup --json [--model <m>] <names…>`, with `--model` if the user gave one. Which names to pass:

- **Names the user typed:** pass the names exactly as the user typed them, `@` tags included. Model requests in words ("tester on sonnet") become `<name>@<m>` before you call `lineup`.
- **The `default` panel:** rules 2 and 3 of step 1 come first (a missing `default` gets the `aska:ship` message; an invalid one gets a proposal). For a valid `default` panel, pass `default`.
- **A proposal:** for an accepted proposal that is a saved panel, pass its canonical name followed by `<member>@<m>` for each tag the user gave a member. A tag on a persona that isn't on the panel makes the run ad-hoc, built as follows. A lineup built from a saved panel but run ad-hoc (a saved panel plus extra personas, or an edited saved panel): pass each remaining member's canonical name, plus each added persona's canonical name, each with any `@` the user gave. Never two tags for one persona. The saved panel's `models` do not carry over (an ad-hoc lineup has no panel layer); only tags the user gave keep a member on a model; never turn a panel's `models` into tags yourself. When you run a saved panel ad-hoc, name each member whose saved-panel model won't apply, and say that an `@` tag keeps it. Never pass a saved panel's name next to untagged persona names: `lineup` reads that as a persona lineup and fails. A new lineup: each persona's canonical name, with any `@` the user gave.

If `lineup` exits 1, report its diagnostics and stop. After `lineup` runs, check that its `panel` is what you expected (`null` for an ad-hoc lineup, the panel's canonical name for a saved one). If it isn't, a persona and a saved panel share a name: report that, and stop. If `lineup` prints a `W_LINEUP_AMBIGUOUS` warning, the first name is both a saved panel and a persona and was read as the panel: ask the user whether they meant the saved panel or the persona before you launch, and pass the names again to match their answer. If they mean the persona, put that name after another name (a lone first name is always tried as the panel), or have them rename one. Otherwise launch exactly the rows it prints, in order, and nothing else: each row's `persona` is the name to record, and its `canonical` is the name for the call's description. Keep the names you passed: a re-run with another model rebuilds them (step 6).

## 2. Write the brief

Create the run folder with `runs new`: it prints the folder's path, outside any git working tree, and the run is kept there after this session. If it fails, say the run won't be kept after this session and use `mktemp -d -t aska-panel-XXXXXX` instead. Write `brief.md` in the run folder. The brief is **identical for every panelist** and contains:

- **Question:** the user's question, word for word.
- **Subject:** one of `change`, `documents`, `conversation` or `none`.
- **Materials:** what to read, as file paths. Panelists can only read files.
  - For a diff, branch or PR, write the diff or PR content to files in the run folder and list them.
  - For a branch, PR or commit range, also write `git log --reverse --stat <base>..<head>` to `commits.txt` in the run folder and list it, so every panelist sees the commit history.
  - For any change, also write the list of tracked files at its head to `files.txt` in the run folder and list it: `git ls-tree -r --name-only <head>`, or `git ls-files` for uncommitted changes. When the head isn't what's on disk, add to the brief that the files on disk are another revision. Add this line to the brief: "The diff shows only the lines that changed. Open a file from `files.txt` when its whole content matters (fixtures, generated files), and use the list to see what's missing."
  - When that list has more than 1,500 paths, write a summary to `files.txt` instead, since a panelist reading a long file sees only its start. It begins with the line `This list is summarised: the repository has <n> tracked files.`, then has a per-directory count for the first two levels of folders, then every path the diff touches, and the other files in their directories (`git ls-tree --name-only <head> <dir>/` for each). Add to the brief: "`files.txt` is a summary, not every file: open a folder to see the rest."
  - When the diff bumps a dependency, also list its docs or type files, so panelists judge its use against its real interface: list the copies step 2a saved in `<dir>/deps/`, which come from the head's lockfile. When step 2a saved none, list those under `node_modules/<name>/` only when the installed version matches the head's lockfile; otherwise say in the brief that the installed docs are for another version.
  - For documents already in the repository, list their paths.
- **Panel notes:** the saved panel's notes, if any.
- **Checks:** for a change, `<dir>/checks.md` (step 2a), with this line: "These are the project's own checks, run once on the change's head commit. A record that says the checks didn't run or didn't finish is not a defect in the change."
- **Evidence:** only after an investigation (step 6), each evidence file's path and the check it answers, with this line: "Evidence is what the panel's investigations found. Weigh it as fact; don't ask to investigate it again unless its *Not determined* section leaves your question open."

For a **conversation** subject, write a neutral summary: the positions taken and decisions made, short quotes of key statements, and open questions. It must contain **no recommendation** and no hint of which way you lean.

### 2a. Run the checks first

For a `change` subject whose head commit exists (a branch, PR, commit or commit range, or uncommitted changes on top of a commit), run the project's checks once before launching the panel, so panelists judge with their result in hand instead of asking for it. You run them yourself, never in the user's checkout; panelists stay read-only. Skip this step for any other subject.

1. **Ask first for untrusted code.** Running the checks runs the change's code: if it comes from someone the user may not trust (a PR from a fork, for example), ask the user before running it. If they decline, record "checks didn't run: the user declined".
2. **Make a throwaway worktree** of the head commit. Run `mktemp -d /tmp/aska-checks-XXXXXX` and save the path it prints to `<dir>/checks-path.txt`; that path is `<checks>` below. Shell variables don't carry from one command to the next, so write the literal path into every later command, and never keep it in a fixed, shared file (such as `/tmp/aska-checks-path`): a panel running at the same time would overwrite it. Then run `git worktree add --detach <checks>/wt <head>`. For uncommitted changes, `<head>` is `HEAD`, and you apply them with `git diff HEAD | git -C <checks>/wt apply`; untracked files aren't included, and the record says so.
3. **Find the documented check command:** the one the README, contributing notes or `CLAUDE.md` give for checking a change, or else the manifest's `check` script. When there's no single check command, run every gate the project defines instead: each of the manifest's `typecheck`, `lint` and `test` scripts (and gates like them, such as `format:check`), plus any other the README's development section gives, never just `test`. If there is none, record "checks didn't run: no documented check command".
4. **Set up:** install dependencies there from the project's lockfile (for example `npm ci`, `uv sync`), installing only inside that worktree. If setup fails, record "checks didn't run: setup failed", with the setup command, its exit code and the last 40 lines of its output.
5. **Run the command once** in the worktree, with a limit of 10 minutes. With several gates, run every command, even after one fails, each with that limit. If one doesn't finish, record "checks didn't finish: stopped after 10 minutes", with the last 40 lines of its output.
6. **Save what the brief needs from the worktree** before cleaning it up, since it's gone afterwards. When the diff bumps a dependency, copy its docs and type files (its README, changelog and `.d.ts` files, for example) from the worktree's installed copy, such as `<checks>/wt/node_modules/<name>/`, to `<dir>/deps/<name>/`. Skip this when setup failed.
7. **Clean up**, even when a step failed: `git worktree remove --force <checks>/wt`, then delete `<checks>`. Remove only the path in this run's `<dir>/checks-path.txt`, never a glob such as `/tmp/aska-checks-*`, which would also catch another panel's worktree.
8. **Write `<dir>/checks.md`,** short and neutral, with no reading of your own:

   ```
   Commit: <full sha><, plus uncommitted changes (untracked files aren't included)>
   Setup: <install command> — exit <code>
   Command: <check command>
   Exit code: <code>
   Output (last 40 lines):
   <output>
   ```

   With several gates, repeat `Command:`, `Exit code:` and `Output (last 40 lines):` for each command, in the order they ran. When the checks didn't run or didn't finish, the record keeps the lines it has and says so in one line: `checks didn't run: <reason>` (or "didn't finish"). Tell the user when that happens.

## 3. Launch the panel

Say how many panelists will run and roughly what they will read. Don't ask for confirmation. A proposal the user accepted in step 1a already counts as confirmation.

For each panelist, save its prompt to a file with `prompt <canonical> --panel > <dir>/prompts/<canonical>.md` (after `mkdir -p <dir>/prompts`), and check that the command exited 0. `<canonical>` is always the row's `canonical`, such as `aska:tester`, in every file name and command for that panelist, never a short name or the name the user typed. Never print a prompt or the brief into your own context to pass it on: each panelist reads both files itself, and copying them costs tokens on every call and every turn after it. Then launch every panelist at once: **all** the `aska:panelist` subagent calls **must** be in one message, one call per panelist. Never launch one panelist and wait for its reply before launching the next. Give each `aska:panelist` call the description `panelist <canonical>`, exactly, using the row's `canonical`. Each call's task is these two lines, with the literal paths, and nothing else:

```
Persona prompt: <dir>/prompts/<canonical>.md
Brief: <dir>/brief.md
```

For each row, pass the row's `model` as the call's `model` parameter when it isn't `null`, and no `model` otherwise. When you say how many panelists will run, name each one on another model and why, from its `modelSource`: `tester on sonnet (you asked)` for `panelist` or `run`, `guardian on opus (saved panel)` for `panel`, `historian on haiku (persona default)` for `persona`.

## 4. Collect and validate

For each reply, before saving it strip one surrounding code fence and nothing else, then save it to `<dir>/judgments/<canonical>.json` and run `check-judgment <canonical> --file <that file>` — pass the saved file with `--file`, never stdin.

- **Valid:** status `ok`.
- **Invalid:** re-ask once, with a fresh `aska:panelist` call whose task is the same two lines, then a line `Previous reply: <dir>/judgments/<canonical>.json`, then the violations and an instruction to reply with the raw JSON object only — no code fence. Save the new reply over the same file. If it is still invalid, status `malformed`, keeping the violations. The re-ask call's description is `panelist <canonical> re-ask`. The re-ask runs on the same model as the first call.
- **The subagent timed out or failed:** status `timeout` or `error`, with the exact reason, for example "timed out after 10 min".
- **A panelist marked `ok` whose persona no longer resolves:** `compare` demotes it to `error` with reason "persona does not resolve — fix the name before re-running". Don't blindly re-run that entry; fix the name yourself if you can tell what it should be, otherwise ask the user.

Write `<dir>/panel-result.json` as `{ "question", "panel", "panelists": [{ "persona", "status", "model", "modelSource", "judgment"?, "violations"?, "reason"? }] }`. `panel` is the `panel` that `lineup` printed (`null` for a persona lineup). Each entry's `persona`, `model` and `modelSource` are its row's.

Then run `compare --file <dir>/panel-result.json --json --record` — again with `--file`, never stdin. Pass `--record` on every compare of a folder from `runs new`: this one, and the ones after every re-run or investigation in step 6. With a `mktemp` folder, omit `--record`.

## 5. Report

Use only the comparison's facts. `compare --json` verdict rows use `null` for an absent `verdict`, `reason` or `tension`, never an absent key — read a `null` as "none", don't treat it as missing data. With fewer than 2 `ok` panelists, `compare --json` prints `ok: false` and exits 1 with no extra sentence in JSON mode; still report the verdicts and follow-ups below, just as you would with 2 or more.

Sections, in order:

1. **Header:** the panel name (or "ad-hoc"), the question and the panelists. When `compare` prints a `Models:` line, list each panelist's model from it.
2. **Verdicts:** one line per panelist, including any that timed out, errored or were malformed, with the reason. When a verdict row has a `tension` (a `proceed` beside that panelist's own medium or higher finding, or its own finding of any severity in a primary security unit), print it after the verdict.
3. **Where they disagree:** `split` and `single-voice` units. One line per panelist: severity and tier with a one-line claim, or why it wasn't raised (not held, not reported with its threshold, cleared, not applicable).
4. **Where they agree:** `all-flag` units, and a count of units nobody raised.
5. **Outside their scope:** if any.
6. **Conditions, missing information and persona sections:** each attributed to its panelist.
7. **Follow-ups:** numbered. Re-runs first, then investigations with the tools each needs.
8. **Chair:** only when the user asks (for example "and recommend"), add `### Recommendation (chair — Claude's synthesis, not a panelist)`. Weigh the disagreements and propose a decision with reasoning. Never add a finding no panelist raised.
9. **Save offer:** only for an ad-hoc run (a proposed new lineup, an edited saved panel, or personas the user named), one line: `Save this lineup as a panel? Reply "save <name>".`
10. **Footer:** the run folder path. Don't delete the folder; follow-ups use it.

Every line of the report comes from `compare`'s output. **Follow-ups** lists exactly `compare`'s `followUps`, in order, one numbered line each — re-runs with their reason, investigations with their `what`, `why` and `tools` — and nothing else: don't merge, reword into new actions, or add your own. **Without a request for a recommendation, add no recommendation, "my read", or verdict of your own anywhere in the report**; the chair section is the only place Claude's view may appear.

Keep the model tags `compare` prints on verdict and disagreement lines. Don't explain a disagreement by the models outside the chair section.

Offer any panelist's full judgment on request.

## 6. Follow-ups

When the user picks a follow-up:

- **Re-run:** launch that persona alone, as `aska:panelist`, with the same brief and the same validation and re-ask. The re-run call's description is `panelist <canonical>`. A re-run keeps the entry's `model` and `modelSource`. If the user names another model ("re-run the tester on opus"), rebuild the names you passed to `lineup` in step 1b: replace that panelist's name, or its existing `<name>@<m>`, with `<name>@<new>`. If it's an untagged member of a saved panel, and so not among the names, append `<member>@<new>`. Keep `--model` as it was. Never append a second tag for the same panelist. Run `lineup` with the rebuilt names, and use the new row for that panelist. Replace its entry in `panel-result.json` — never append, since the duplicate check is a literal string match and would count `p` and `acme:p` as two different panelists — run `compare` again (with `--record` on a kept run, as in step 4), and show the updated report.
- **Investigate:** run it on `aska:investigator`; never use `aska:panelist` for an investigation, since it has no tools. The investigator gathers evidence and doesn't judge, so one check serves the whole panel:
  1. **Group the checks.** Gather the picked items with every other `investigate` follow-up that asks for the same check, however it's worded. Launch one `aska:investigator` call per distinct check, all in one message, each with the description `investigator <n>`, where `<n>` is the number its evidence file will get. Each call's task is the brief, then a line `---`, then each grouped item's what, why and tools. Add nothing else to the task: no instructions of your own, not even to allow a change "somewhere safe", since the investigator's own rule is never to change anything. Never give it a persona prompt or any panelist's judgment: evidence gathered through one persona's eyes finds what that persona already fears. Investigators get no `model`: they run on the session's model, whatever `--model` said. The user's normal permission prompts apply.
  2. **Check the evidence.** For each reply, strip one surrounding code fence and nothing else, save it to `<dir>/evidence/<n>.md` (numbering on from any evidence file already there, rejected ones included), and run `check-evidence --file <that file>`, with `--file`, never stdin.
     - **Valid:** add it to the brief's **Evidence:** list. Keep a reply whose *Not determined* section is all it has; that is evidence too.
     - **Invalid:** re-ask once, with a fresh `aska:investigator` call described as `investigator <n> re-ask`: the same task, then the previous reply, the violations, and an instruction to reply with only the four sections. Save the new reply over the same file and check it again.
     - **Still invalid, or the call timed out or failed:** don't add it to the brief, since every panelist would weigh it as fact. Rename any saved reply to `<dir>/evidence/<n>.rejected.md`, so it's kept to look at but never listed. Tell the user the investigation failed, with the violations or the exact reason (for example "timed out after 10 min"), and that the follow-up stays open to pick again.
  3. **Re-run every panelist**, whatever its status, with the updated brief, exactly as in steps 3 and 4, on each panelist's recorded model: the brief stays identical for every panelist, so one panelist never judges on evidence another hasn't seen. Replace every entry in `panel-result.json`, run `compare` again (with `--record` on a kept run, as in step 4), and show the updated report, marking the units whose status changed. If no evidence was added, don't re-run the panel: nothing in the brief changed.

## 7. Save a lineup

When the user replies `save <name>` after an ad-hoc run:

1. **Ask where:** project scope (`.claude/personas/`, the default) or user scope (`~/.claude/personas/`). Never save into the plugin's own folder. If any panelist is a project-scope persona and the user picks user scope, say the panel won't resolve in other projects and ask before going on.
2. **Check the name.** It must be kebab-case. If `<name>.panel.md` already exists in that scope, stop and ask for another name; never overwrite. If the name would shadow a panel in another scope (`list panels --json`), say which one and ask before going on. If the name is `default`, say: "this will now run whenever you give no names."
3. **Write `<name>.panel.md`:** `name`; a `description` that generalizes the question into an "Is this …?" line, shown to the user to edit before writing; `personas` with each panelist's `canonical` from `list personas --json`; `models` for each panelist whose `modelSource` is `panelist`, keyed by that same `canonical`, and never `persona` (the persona already says it) or `panel` (an ad-hoc run has no panel layer). When some panelist's `modelSource` is `run`, first ask, alongside the description: "This run used `--model <m>`. Save those panelists on <m>? (yes/no)". On yes, add them to `models`; on no, leave them out. Without `--model`, don't ask. Say which models were saved; and a body with the original saved panel's notes, if any.
4. **Validate:** run `validate` and report every diagnostic on the new file's path. If any is an error, delete the file and say why.

Never write a panel file without a `save` reply. Saving doesn't change the run folder or the report.
来源:skillsdirectory

评论0

登录后参与评论

还没有评论,来抢沙发吧