@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.
- package/README.md +11 -0
- package/dist/index.js +176 -4
- 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.
|
|
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-
|
|
43
|
-
"@kitsy/coop-
|
|
44
|
-
"@kitsy/coop-core": "2.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",
|