@kitsy/coop 2.1.1 → 2.1.2

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (3) hide show
  1. package/README.md +11 -0
  2. package/dist/index.js +176 -4
  3. package/package.json +4 -4
package/README.md CHANGED
@@ -23,10 +23,21 @@ For AI-oriented command discovery:
23
23
  coop help-ai
24
24
  coop help-ai --format json
25
25
  coop help-ai --format markdown
26
+ coop help-ai --selection --format markdown
27
+ coop help-ai --state-transitions --format json
28
+ coop help-ai --artifacts --format markdown
29
+ coop help-ai --post-execution --format markdown
26
30
  coop help-ai --initial-prompt --strict --repo C:/path/to/repo --delivery MVP --command coop.cmd
31
+ coop help-ai --initial-prompt --rigour balanced --repo C:/path/to/repo --delivery MVP --command coop.cmd
27
32
  coop config artifacts.dir docs/agent-artifacts
28
33
  ```
29
34
 
35
+ Agent contract notes:
36
+ - `coop complete task <id>` requires the task to already be in `in_review`.
37
+ - balanced initial prompts are the recommended default for normal implementation sessions.
38
+ - if an agent is unsure about selection, transitions, artifacts, or whether it should continue, it should call the matching focused `help-ai` topic command instead of guessing.
39
+ - strict initial prompts tell agents to stop after completing the selected task instead of auto-picking another one.
40
+
30
41
  On Windows PowerShell, the global npm install may resolve `coop` to `coop.ps1` first. If an agent or CI shell hits execution-policy issues, use `coop.cmd` explicitly.
31
42
 
32
43
  Both entrypoints operate on the nearest parent `.coop/` workspace. If no workspace log target exists, CLI errors fall back to `~/.coop/logs/cli.log` or `COOP_HOME/logs/cli.log`.
package/dist/index.js CHANGED
@@ -2924,6 +2924,12 @@ var catalog = {
2924
2924
  "coop reopen task <id>",
2925
2925
  "coop transition task <id> <status>"
2926
2926
  ],
2927
+ lifecycle_requirements: [
2928
+ "`coop start task <id>` moves a ready task into `in_progress`.",
2929
+ "`coop review task <id>` requires the task to already be `in_progress` and moves it to `in_review`.",
2930
+ "`coop complete task <id>` requires the task to already be `in_review` and moves it to `done`.",
2931
+ "Do not call `coop complete task <id>` directly from `in_progress` unless COOP explicitly adds that transition later."
2932
+ ],
2927
2933
  unsupported_command_warnings: [
2928
2934
  "Do not invent COOP commands such as `coop complete` when they are not present in `help-ai` output.",
2929
2935
  "If a desired lifecycle action is not represented by an allowed command, state that explicitly instead of paraphrasing.",
@@ -3014,7 +3020,13 @@ var catalog = {
3014
3020
  name: "Execute And Integrate",
3015
3021
  description: "Hand execution to an AI provider or code-agent CLI and expose COOP through MCP/API.",
3016
3022
  commands: [
3023
+ { usage: "coop help-ai --selection --format markdown", purpose: "Show the focused rules for deterministic task selection and workspace resolution." },
3024
+ { usage: "coop help-ai --state-transitions --format json", purpose: "Show exact lifecycle commands, prerequisites, and warnings against invented transitions." },
3025
+ { usage: "coop help-ai --artifacts --format markdown", purpose: "Show where contract-review, audit, and planning artifacts must be written." },
3026
+ { usage: "coop help-ai --post-execution --format markdown", purpose: "Show what an agent must do after finishing the selected task." },
3027
+ { usage: "coop help-ai --naming --format markdown", purpose: "Show naming guidance when IDs and naming templates matter." },
3017
3028
  { usage: "coop help-ai --initial-prompt --strict --repo C:/path/to/repo --delivery MVP --command coop.cmd", purpose: "Generate a strict agent bootstrap prompt for a repository and delivery." },
3029
+ { usage: "coop help-ai --initial-prompt --rigour balanced --repo C:/path/to/repo --delivery MVP --command coop.cmd", purpose: "Generate the recommended balanced agent bootstrap prompt for day-to-day implementation work." },
3018
3030
  { usage: "coop config ai.provider codex_cli", purpose: "Use the installed Codex CLI as the execution/refinement backend." },
3019
3031
  { usage: "coop config ai.provider claude_cli", purpose: "Use the installed Claude CLI as the execution/refinement backend." },
3020
3032
  { usage: "coop config ai.provider gemini_cli", purpose: "Use the installed Gemini CLI as the execution/refinement backend." },
@@ -3042,8 +3054,119 @@ var catalog = {
3042
3054
  "Use `coop create ... --from-file|--stdin` and `coop apply draft` instead of editing `.coop` task or idea files directly.",
3043
3055
  "Use `coop log --last --verbose` when command execution fails and the concise error points to a stack trace.",
3044
3056
  "If a workflow depends on stable human-readable IDs, inspect `coop naming` or `coop config id.naming` before creating items."
3057
+ ],
3058
+ post_execution_rules: [
3059
+ "After completing the currently selected task, stop and wait instead of automatically selecting the next task.",
3060
+ "Do not auto-start a second task in the same run unless the user explicitly asks you to continue.",
3061
+ "If you changed task state in COOP, report the exact command used and the resulting new state before doing anything else."
3045
3062
  ]
3046
3063
  };
3064
+ function renderTopicPayload(topic) {
3065
+ if (topic === "state-transitions") {
3066
+ return {
3067
+ topic,
3068
+ allowed_lifecycle_commands: catalog.allowed_lifecycle_commands,
3069
+ lifecycle_requirements: catalog.lifecycle_requirements,
3070
+ warnings: catalog.unsupported_command_warnings
3071
+ };
3072
+ }
3073
+ if (topic === "artifacts") {
3074
+ return {
3075
+ topic,
3076
+ artifact_policy: catalog.artifact_policy
3077
+ };
3078
+ }
3079
+ if (topic === "post-execution") {
3080
+ return {
3081
+ topic,
3082
+ post_execution_rules: catalog.post_execution_rules
3083
+ };
3084
+ }
3085
+ if (topic === "selection") {
3086
+ return {
3087
+ topic,
3088
+ selection_rules: catalog.selection_rules,
3089
+ workspace_rules: catalog.workspace_rules
3090
+ };
3091
+ }
3092
+ return {
3093
+ topic,
3094
+ naming_guidance: [
3095
+ "Use `coop naming` to inspect the current naming template and token behavior.",
3096
+ 'Use `coop naming preview "<title>"` before creating a new idea, task, or delivery if predictable IDs matter.',
3097
+ "Use `coop config id.naming ...` to override the default semantic naming template."
3098
+ ]
3099
+ };
3100
+ }
3101
+ function renderAiHelpTopic(format, topic) {
3102
+ const payload = renderTopicPayload(topic);
3103
+ if (format === "json") {
3104
+ return `${JSON.stringify(payload, null, 2)}
3105
+ `;
3106
+ }
3107
+ const lines = [];
3108
+ const bullet = (value) => `- ${value}`;
3109
+ const title = topic.split("-").map((part) => part.slice(0, 1).toUpperCase() + part.slice(1)).join(" ");
3110
+ lines.push(format === "markdown" ? `# COOP AI Help: ${title}` : `COOP AI Help: ${title}`, "");
3111
+ if (topic === "state-transitions") {
3112
+ lines.push(format === "markdown" ? "## Allowed Lifecycle Commands" : "Allowed Lifecycle Commands");
3113
+ for (const item of catalog.allowed_lifecycle_commands) {
3114
+ lines.push(bullet(`\`${item}\``));
3115
+ }
3116
+ lines.push("");
3117
+ lines.push(format === "markdown" ? "## Lifecycle Requirements" : "Lifecycle Requirements");
3118
+ for (const item of catalog.lifecycle_requirements) {
3119
+ lines.push(bullet(item));
3120
+ }
3121
+ lines.push("");
3122
+ lines.push(format === "markdown" ? "## Warnings" : "Warnings");
3123
+ for (const item of catalog.unsupported_command_warnings) {
3124
+ lines.push(bullet(item));
3125
+ }
3126
+ lines.push("");
3127
+ return `${lines.join("\n")}
3128
+ `;
3129
+ }
3130
+ if (topic === "artifacts") {
3131
+ lines.push(bullet(`Config key: \`${catalog.artifact_policy.config_key}\``));
3132
+ lines.push(bullet(`Default dir: \`${catalog.artifact_policy.default_dir}\``));
3133
+ lines.push(bullet(`Required for: ${catalog.artifact_policy.required_for.join(", ")}`));
3134
+ for (const item of catalog.artifact_policy.guidance) {
3135
+ lines.push(bullet(item));
3136
+ }
3137
+ lines.push("");
3138
+ return `${lines.join("\n")}
3139
+ `;
3140
+ }
3141
+ if (topic === "post-execution") {
3142
+ for (const item of catalog.post_execution_rules) {
3143
+ lines.push(bullet(item));
3144
+ }
3145
+ lines.push("");
3146
+ return `${lines.join("\n")}
3147
+ `;
3148
+ }
3149
+ if (topic === "selection") {
3150
+ lines.push(format === "markdown" ? "## Selection Rules" : "Selection Rules");
3151
+ for (const item of catalog.selection_rules) {
3152
+ lines.push(bullet(item));
3153
+ }
3154
+ lines.push("");
3155
+ lines.push(format === "markdown" ? "## Workspace Rules" : "Workspace Rules");
3156
+ for (const item of catalog.workspace_rules) {
3157
+ lines.push(bullet(item));
3158
+ }
3159
+ lines.push("");
3160
+ return `${lines.join("\n")}
3161
+ `;
3162
+ }
3163
+ for (const item of renderTopicPayload("naming").naming_guidance) {
3164
+ lines.push(bullet(item));
3165
+ }
3166
+ lines.push("");
3167
+ return `${lines.join("\n")}
3168
+ `;
3169
+ }
3047
3170
  function normalizeRepoPath(repoPath) {
3048
3171
  return repoPath ? path7.resolve(repoPath) : process.cwd();
3049
3172
  }
@@ -3082,22 +3205,30 @@ function renderInitialPrompt(options = {}) {
3082
3205
  "",
3083
3206
  "Rules:",
3084
3207
  "- Learn COOP capabilities from `coop help-ai` before proposing commands.",
3208
+ `- If you are unsure how to pick work, run \`${commandName} help-ai --selection --format markdown\`.`,
3209
+ `- If you are unsure about lifecycle changes, run \`${commandName} help-ai --state-transitions --format markdown\`.`,
3210
+ `- If you are unsure where artifacts should go, run \`${commandName} help-ai --artifacts --format markdown\`.`,
3211
+ `- If you are unsure whether to continue after a task, run \`${commandName} help-ai --post-execution --format markdown\`.`,
3085
3212
  "- Use only commands that actually exist in COOP. Do not invent command names.",
3086
3213
  "- Do not reprioritize work outside COOP unless the user explicitly overrides it.",
3087
3214
  "- Select only the first ready task from the COOP readiness output.",
3088
3215
  "- Inspect the selected task with `coop show task <id>` before implementation.",
3216
+ "- Do not create, edit, move, or normalize files directly inside `.coop/`; use COOP commands, MCP, or API surfaces so COOP remains the canonical writer.",
3217
+ "- Respect lifecycle prerequisites: use `coop review task <id>` before `coop complete task <id>`; do not complete directly from `in_progress`.",
3089
3218
  `- Write any contract-review, audit, or planning artifact under \`${artifactsDir}\` unless the user explicitly chooses another location.`
3090
3219
  ];
3091
3220
  if (rigour === "strict") {
3092
3221
  lines.push(
3093
3222
  "- Before mentioning a COOP command, verify the exact command name from `coop help-ai --format json`.",
3094
3223
  "- If a needed workflow is not supported by an exact COOP command, say that explicitly instead of inventing one.",
3095
- "- Do not switch to another task unless COOP state changes or the user explicitly redirects you."
3224
+ "- Do not switch to another task unless COOP state changes or the user explicitly redirects you.",
3225
+ "- After executing or completing the selected task, stop and wait for user confirmation before picking another task."
3096
3226
  );
3097
3227
  } else if (rigour === "balanced") {
3098
3228
  lines.push(
3099
3229
  "- Prefer exact COOP commands from `coop help-ai --format json` when describing next actions.",
3100
- "- If COOP lacks a named command for a desired action, state the limitation plainly."
3230
+ "- If COOP lacks a named command for a desired action, state the limitation plainly.",
3231
+ "- After finishing the selected task, report the resulting COOP state before proposing follow-up work."
3101
3232
  );
3102
3233
  } else {
3103
3234
  lines.push("- Keep COOP as the authority for task selection and lifecycle state.");
@@ -3141,6 +3272,11 @@ function renderAiHelp(format) {
3141
3272
  lines.push(bullet(`\`${item}\``));
3142
3273
  }
3143
3274
  lines.push("");
3275
+ lines.push(format === "markdown" ? "## Lifecycle Requirements" : "Lifecycle Requirements");
3276
+ for (const item of catalog.lifecycle_requirements) {
3277
+ lines.push(bullet(item));
3278
+ }
3279
+ lines.push("");
3144
3280
  lines.push(format === "markdown" ? "## Unsupported / Invented Command Warnings" : "Unsupported / Invented Command Warnings");
3145
3281
  for (const item of catalog.unsupported_command_warnings) {
3146
3282
  lines.push(bullet(item));
@@ -3173,6 +3309,11 @@ function renderAiHelp(format) {
3173
3309
  lines.push(bullet(item));
3174
3310
  }
3175
3311
  lines.push("");
3312
+ lines.push(format === "markdown" ? "## Post-Execution Rules" : "Post-Execution Rules");
3313
+ for (const item of catalog.post_execution_rules) {
3314
+ lines.push(bullet(item));
3315
+ }
3316
+ lines.push("");
3176
3317
  return `${lines.join("\n")}
3177
3318
  `;
3178
3319
  }
@@ -3182,7 +3323,7 @@ function renderAiInitialPrompt(options = {}) {
3182
3323
 
3183
3324
  // src/commands/help-ai.ts
3184
3325
  function registerHelpAiCommand(program) {
3185
- program.command("help-ai").description("Print AI-oriented COOP capability and usage help").option("--format <format>", "Output format: text | json | markdown", "text").option("--initial-prompt", "Print an agent bootstrap prompt instead of the capability catalog").option("--repo <path>", "Repository path to embed in the initial prompt").option("--delivery <delivery>", "Delivery to embed in the initial prompt").option("--track <track>", "Track to embed in the initial prompt").option("--command <name>", "Command name to embed, e.g. coop or coop.cmd", "coop").option("--rigour <level>", "Prompt rigour: strict | balanced | light", "balanced").option("--strict", "Shortcut for --rigour strict").option("--balanced", "Shortcut for --rigour balanced").option("--light", "Shortcut for --rigour light").action((options) => {
3326
+ program.command("help-ai").description("Print AI-oriented COOP capability and usage help").option("--format <format>", "Output format: text | json | markdown", "text").option("--initial-prompt", "Print an agent bootstrap prompt instead of the capability catalog").option("--topic <topic>", "Focused help topic: state-transitions | artifacts | post-execution | selection | naming").option("--state-transitions", "Focused help for lifecycle and state transition usage").option("--artifacts", "Focused help for artifact placement and policy").option("--post-execution", "Focused help for what to do after finishing the selected task").option("--selection", "Focused help for task selection and workspace resolution").option("--naming", "Focused help for naming IDs and naming templates").option("--repo <path>", "Repository path to embed in the initial prompt").option("--delivery <delivery>", "Delivery to embed in the initial prompt").option("--track <track>", "Track to embed in the initial prompt").option("--command <name>", "Command name to embed, e.g. coop or coop.cmd", "coop").option("--rigour <level>", "Prompt rigour: strict | balanced | light", "balanced").option("--strict", "Shortcut for --rigour strict").option("--balanced", "Shortcut for --rigour balanced").option("--light", "Shortcut for --rigour light").action((options) => {
3186
3327
  const format = options.format ?? "text";
3187
3328
  if (format !== "text" && format !== "json" && format !== "markdown") {
3188
3329
  throw new Error(`Unsupported help-ai format '${format}'. Expected text|json|markdown.`);
@@ -3191,6 +3332,7 @@ function registerHelpAiCommand(program) {
3191
3332
  if (rigour !== "strict" && rigour !== "balanced" && rigour !== "light") {
3192
3333
  throw new Error(`Unsupported help-ai rigour '${rigour}'. Expected strict|balanced|light.`);
3193
3334
  }
3335
+ const topic = resolveHelpTopic(options);
3194
3336
  let artifactsDir = "docs";
3195
3337
  const repoRoot = options.repo ? resolveRepoRoot(options.repo) : resolveRepoRoot();
3196
3338
  try {
@@ -3206,10 +3348,40 @@ function registerHelpAiCommand(program) {
3206
3348
  commandName: options.command,
3207
3349
  rigour,
3208
3350
  artifactsDir
3209
- }) : renderAiHelp(format);
3351
+ }) : topic ? renderAiHelpTopic(format, topic) : renderAiHelp(format);
3210
3352
  console.log(output3.trimEnd());
3211
3353
  });
3212
3354
  }
3355
+ function resolveHelpTopic(options) {
3356
+ const requestedTopics = [];
3357
+ if (options.topic) {
3358
+ requestedTopics.push(options.topic);
3359
+ }
3360
+ if (options.stateTransitions) {
3361
+ requestedTopics.push("state-transitions");
3362
+ }
3363
+ if (options.artifacts) {
3364
+ requestedTopics.push("artifacts");
3365
+ }
3366
+ if (options.postExecution) {
3367
+ requestedTopics.push("post-execution");
3368
+ }
3369
+ if (options.selection) {
3370
+ requestedTopics.push("selection");
3371
+ }
3372
+ if (options.naming) {
3373
+ requestedTopics.push("naming");
3374
+ }
3375
+ const unique2 = [...new Set(requestedTopics)];
3376
+ if (unique2.length > 1) {
3377
+ throw new Error(`Specify only one focused help-ai topic at a time. Received: ${unique2.join(", ")}.`);
3378
+ }
3379
+ const topic = unique2[0];
3380
+ if (topic !== void 0 && topic !== "state-transitions" && topic !== "artifacts" && topic !== "post-execution" && topic !== "selection" && topic !== "naming") {
3381
+ throw new Error(`Unsupported help-ai topic '${topic}'. Expected state-transitions|artifacts|post-execution|selection|naming.`);
3382
+ }
3383
+ return topic;
3384
+ }
3213
3385
 
3214
3386
  // src/commands/index.ts
3215
3387
  import path8 from "path";
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "@kitsy/coop",
3
3
  "description": "COOP command-line interface.",
4
- "version": "2.1.1",
4
+ "version": "2.1.2",
5
5
  "license": "MIT",
6
6
  "type": "module",
7
7
  "publishConfig": {
@@ -39,9 +39,9 @@
39
39
  "chalk": "^5.6.2",
40
40
  "commander": "^14.0.0",
41
41
  "octokit": "^5.0.5",
42
- "@kitsy/coop-ai": "2.1.1",
43
- "@kitsy/coop-ui": "^2.1.1",
44
- "@kitsy/coop-core": "2.1.1"
42
+ "@kitsy/coop-ui": "^2.1.2",
43
+ "@kitsy/coop-ai": "2.1.2",
44
+ "@kitsy/coop-core": "2.1.2"
45
45
  },
46
46
  "devDependencies": {
47
47
  "@types/node": "^24.12.0",