kanbo-cli 0.1.1 → 0.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.
@@ -2291,32 +2291,61 @@ async function migrateCards(store, input) {
2291
2291
  };
2292
2292
  }
2293
2293
  //#endregion
2294
- //#region src/ops/prime.ts
2295
- /**
2296
- * The rules of this board, as an agent needs to hear them.
2294
+ //#region src/ops/agent-rules.ts
2295
+ /**
2296
+ * The sentences that tell an agent how to work this board, written once.
2297
+ *
2298
+ * Four surfaces say them: the text `kanbo prime` returns (`BOARD_RULES`), the
2299
+ * block `kanbo init` writes into a project's `CLAUDE.md` / `AGENTS.md`, the
2300
+ * `instructions` the `kanbo mcp` server sends when a client connects, and the
2301
+ * `kanbo_card_create` tool's description. Each surface adds its own way of
2302
+ * doing the thing — a command, a tool name — but the rule itself is read from
2303
+ * here, so the four cannot come to say different things.
2304
+ *
2305
+ * No sentence names a tool or a command: the same text reaches an agent holding
2306
+ * MCP tools, one with a command line, and one talking to a server over HTTP.
2307
+ */
2308
+ const MOVE_CARD_RULE = "You move the card between columns yourself, at the moment its real state changes. The board never moves a card for you.";
2309
+ const STATUS_LINE_RULE = "Write a status line at every step, including before and after anything long-running. One sentence, present tense, about what is happening right now.";
2310
+ const WAIT_FOR_PERSON_RULE = "When you need a person, mark the card as waiting for approval and end your turn. You will be told when the answer comes.";
2311
+ const PERSON_ONLY_RULE = "Only a person approves a card, and only a person takes one out of waiting. Never do either yourself.";
2312
+ const EXECUTION_MODE_RULE = "Each card says where it runs: `worktree` means a separate copy of the project, `main` means the project folder itself. Work in the mode the card names.";
2313
+ /** When to split a card at all — said on its own where the surface names the parent its own way. */
2314
+ const SUBTASK_WHEN_SENTENCE = "Create subtasks only when the person asks for them, or when a task has parts that can be done and checked separately (different stages, owners or pull requests); do not split small work you will finish in one go.";
2315
+ /** How to split one, with the way this surface names the parent card. */
2316
+ function subtaskSplitSentence(parentReference) {
2317
+ return `When you do split a card, make the parts subtasks of it (${parentReference}), not separate top-level cards.`;
2318
+ }
2319
+ const SUBTASK_RULE = `${SUBTASK_WHEN_SENTENCE} ${subtaskSplitSentence("the parent card's id")}`;
2320
+ const PULL_REQUEST_RULE = "Opened a pull request? Link it to the card. Its state and CI checks then reach the card as comments on their own — nothing else tells the board a pull request exists.";
2321
+ const OWN_SESSION_RULE = "Started the work yourself, not launched by an app that tracks the run for you? Say so when you start the run — `claude:<session id>` from Claude Code, `codex:<session id>` from Codex (the session id Codex prints) — so your own log of it can be found later.";
2322
+ /** Said by the `kanbo init` block and the MCP instructions, which name the comment command or tool beside it. */
2323
+ const COMMENT_RULE = "Findings, results, decisions and questions go on the card as comments.";
2324
+ /**
2325
+ * The rules of this board, as `kanbo prime` says them under its column list.
2297
2326
  *
2298
2327
  * They are about the board and nothing else. The board does not hand out a role, a
2299
2328
  * method or a pipeline — that belongs to the instructions the person wrote for
2300
2329
  * their own agent — so the list stops at what the board itself guarantees and
2301
- * expects. No tool is named either: the same text reaches an agent holding MCP
2302
- * tools, one with a command line, and one talking to a server over HTTP, and each
2303
- * of them already knows what it is holding.
2330
+ * expects.
2304
2331
  *
2305
- * Exported because it is also the source `buildCapabilitiesManifest` reads its
2306
- * `rules` from — one list, read by the prompt an agent sees and by the manifest
2307
- * an orchestrator reads about the board.
2332
+ * Also the source `buildCapabilitiesManifest` reads its `rules` from — one list,
2333
+ * read by the prompt an agent sees and by the manifest an orchestrator reads
2334
+ * about the board.
2308
2335
  */
2309
2336
  const BOARD_RULES = [
2310
- "You move the card between columns yourself, at the moment its real state changes. The board never moves a card for you.",
2311
- "Write a status line at every step, including before and after anything long-running. One sentence, present tense, about what is happening right now.",
2312
- "When you need a person, mark the card as waiting for approval and end your turn. You will be told when the answer comes.",
2313
- "Only a person approves a card, and only a person takes one out of waiting. Never do either yourself.",
2314
- "Each card says where it runs: `worktree` means a separate copy of the project, `main` means the project folder itself. Work in the mode the card names.",
2315
- "Create subtasks only when the person asks for them, or when a task has parts that can be done and checked separately (different stages, owners or pull requests); do not split small work you will finish in one go. When you do split a card, make the parts subtasks of it (the parent card's id), not separate top-level cards.",
2316
- "Opened a pull request? Link it to the card. Its state and CI checks then reach the card as comments on their own — nothing else tells the board a pull request exists.",
2317
- "Started the work yourself, not launched by an app that tracks the run for you? Say so when you start the run — `claude:<session id>` from Claude Code, `codex:<session id>` from Codex (the session id Codex prints) — so your own log of it can be found later.",
2337
+ MOVE_CARD_RULE,
2338
+ STATUS_LINE_RULE,
2339
+ WAIT_FOR_PERSON_RULE,
2340
+ PERSON_ONLY_RULE,
2341
+ EXECUTION_MODE_RULE,
2342
+ SUBTASK_RULE,
2343
+ PULL_REQUEST_RULE,
2344
+ OWN_SESSION_RULE,
2318
2345
  "Read the column descriptions above before moving a card, and do all of this through the board tools or commands you have — a statement in your reply changes nothing."
2319
2346
  ];
2347
+ //#endregion
2348
+ //#region src/ops/prime.ts
2320
2349
  /**
2321
2350
  * What the board tells an agent about itself: the columns it has, what each one
2322
2351
  * means, and how a card is expected to travel across them.
@@ -4334,7 +4363,8 @@ const CODEX_TABLE_PATTERN = new RegExp(String.raw`^\s*\[\s*mcp_servers\s*\.\s*(?
4334
4363
  *
4335
4364
  * It says what to run and when, and nothing about how to do the work: the
4336
4365
  * method is the person's own instructions to their agent, and the board only
4337
- * insists on the part that keeps the card honest.
4366
+ * insists on the part that keeps the card honest. The rules are the sentences
4367
+ * `ops/agent-rules.ts` holds for every surface, with the command beside each.
4338
4368
  */
4339
4369
  const INSTRUCTION_BLOCK = [
4340
4370
  INSTRUCTION_START,
@@ -4343,12 +4373,13 @@ const INSTRUCTION_BLOCK = [
4343
4373
  "Work on this project is tracked on a kanbo board. Before starting a task run `kanbo prime` — it prints the board's columns and what each one means.",
4344
4374
  "",
4345
4375
  "- Take a card from `kanbo ready`.",
4346
- "- Move the card yourself (`kanbo card move <id> <column>`) — a card in the wrong column is a lie.",
4347
- "- Write a status line at every step (`kanbo card status-line <id> --text \"...\"`).",
4348
- "- Create subtasks only when the person asks for them, or when a task has parts that can be done and checked separately (different stages, owners or pull requests); do not split small work you will finish in one go. When you do split a card, make the parts subtasks of it (the parent card's id), not separate top-level cards. (`kanbo card create --description \"...\" --parent <id>`).",
4349
- "- Findings, decisions and questions go on the card (`kanbo card comment <id> --content \"...\"`).",
4350
- "- When you need a person, run `kanbo card wait-approval <id>` and end your turn. Never approve your own work, and never take a card out of a column where it is waiting for a person.",
4351
- "- Started the work yourself, not launched by an app that tracks the run? Pass your own session to `kanbo run start --session` — `claude:<session id>` from Claude Code, `codex:<session id>` from Codex (the session id Codex prints).",
4376
+ `- ${MOVE_CARD_RULE} (\`kanbo card move <id> <column>\`)`,
4377
+ `- ${STATUS_LINE_RULE} (\`kanbo card status-line <id> --text "..."\`)`,
4378
+ `- ${SUBTASK_RULE} (\`kanbo card create --description "..." --parent <id>\`)`,
4379
+ `- ${COMMENT_RULE} (\`kanbo card comment <id> --content "..."\`)`,
4380
+ `- ${WAIT_FOR_PERSON_RULE} (\`kanbo card wait-approval <id>\`)`,
4381
+ `- ${PERSON_ONLY_RULE}`,
4382
+ `- ${OWN_SESSION_RULE} (\`kanbo run start <id> --agent <name> --session <ref>\`)`,
4352
4383
  "- Run `kanbo capabilities` for the full list of tools, commands and rules.",
4353
4384
  INSTRUCTION_END
4354
4385
  ].join("\n");
@@ -5140,7 +5171,7 @@ dirname(fileURLToPath(import.meta.url));
5140
5171
  * `package.version`. A build carries it as a literal; running from source
5141
5172
  * (tests, `tsx`) reads the package's own `package.json` instead.
5142
5173
  */
5143
- const KANBO_PACKAGE_VERSION = "0.1.1";
5174
+ const KANBO_PACKAGE_VERSION = "0.1.2";
5144
5175
  //#endregion
5145
5176
  //#region src/mcp/resources.ts
5146
5177
  /** The URI a client reads the manifest as JSON from. */
@@ -5181,6 +5212,36 @@ function registerKanboCapabilitiesResources(server) {
5181
5212
  }] }));
5182
5213
  }
5183
5214
  //#endregion
5215
+ //#region src/mcp/instructions.ts
5216
+ /** A tool name as the instructions print it — typed, so a renamed tool fails the build here. */
5217
+ function tool(name) {
5218
+ return `\`${name}\``;
5219
+ }
5220
+ /**
5221
+ * What `kanbo mcp` tells a client when it connects — the `instructions` of the
5222
+ * MCP initialize result, which a client hands its model before any tool is
5223
+ * called. An agent with nothing but this server connected learns from it how
5224
+ * to work the board, with no instruction file in the project.
5225
+ *
5226
+ * Static on purpose: it is sent before any board is resolved, so it says
5227
+ * nothing about columns — `kanbo_prime` returns those. The rules are the
5228
+ * sentences `ops/agent-rules.ts` holds for every surface, with the tool beside
5229
+ * each; the full manifest stays a resource.
5230
+ */
5231
+ const KANBO_MCP_INSTRUCTIONS = [
5232
+ "kanbo is a kanban board shared by people and agents; these tools read and change its cards.",
5233
+ "",
5234
+ `- At the start of a session call ${tool("kanbo_prime")} — it returns this board's columns and what each one means.`,
5235
+ `- Take work from ${tool("kanbo_ready")}.`,
5236
+ `- ${MOVE_CARD_RULE} (${tool("kanbo_card_move")})`,
5237
+ `- ${STATUS_LINE_RULE} (${tool("kanbo_status_line")})`,
5238
+ `- ${COMMENT_RULE} (${tool("kanbo_card_comment")})`,
5239
+ `- ${SUBTASK_RULE} (${tool("kanbo_card_create")} with \`parent\`)`,
5240
+ `- ${WAIT_FOR_PERSON_RULE} (${tool("kanbo_wait_approval")})`,
5241
+ `- ${PERSON_ONLY_RULE}`,
5242
+ `- Every tool, rule and canonical string: the resource \`${KANBO_CAPABILITIES_MARKDOWN_RESOURCE_URI}\`.`
5243
+ ].join("\n");
5244
+ //#endregion
5184
5245
  //#region src/mcp/tools/tool.ts
5185
5246
  /**
5186
5247
  * Declare a tool: what it is called, what it takes, and the one thing it does.
@@ -5278,7 +5339,7 @@ const SUBTASK_SENTENCE = "To create a subtask (sub-card) under another card, pas
5278
5339
  const cardCreateTool = defineKanboTool({
5279
5340
  name: "kanbo_card_create",
5280
5341
  title: "Create a card",
5281
- description: `Put a new card on this board. ${SUBTASK_SENTENCE} Create subtasks only when the person asks for them, or when a task has parts that can be done and checked separately (different stages, owners or pull requests); do not split small work you will finish in one go. When you do split a card, make the parts subtasks of it (pass \`parent\`), not separate top-level cards.`,
5342
+ description: `Put a new card on this board. ${SUBTASK_SENTENCE} ${SUBTASK_WHEN_SENTENCE} ${subtaskSplitSentence("pass `parent`")}`,
5282
5343
  inputSchema: {
5283
5344
  title: z.string().optional().describe("What the card is called. Leave it out and the card is titled with its own key; the description then says what the task is."),
5284
5345
  description: z.string().optional().describe("What the card is about, spelled out for whoever picks it up."),
@@ -5550,12 +5611,15 @@ function registerKanboTools(server, transport, options) {
5550
5611
  * function: it documents its capabilities its own way, and adding a second
5551
5612
  * `kanbo://` resource namespace to an inventory that is not only the board's
5552
5613
  * is a decision for that server to make, not this one.
5614
+ *
5615
+ * For the same reason it alone sends `KANBO_MCP_INSTRUCTIONS` in the initialize
5616
+ * result: the instructions of a server that is only the board.
5553
5617
  */
5554
5618
  function createKanboMcpServer(transport, options) {
5555
5619
  const server = new McpServer({
5556
5620
  name: KANBO_MCP_SERVER_NAME,
5557
5621
  version: KANBO_MCP_SERVER_VERSION
5558
- });
5622
+ }, { instructions: KANBO_MCP_INSTRUCTIONS });
5559
5623
  registerKanboTools(server, transport, options);
5560
5624
  registerKanboCapabilitiesResources(server);
5561
5625
  return server;
@@ -7944,6 +8008,6 @@ function buildCapabilitiesManifest() {
7944
8008
  };
7945
8009
  }
7946
8010
  //#endregion
7947
- export { formatActivityIssueReference as $, createBoardOps as A, serializeEntryRules as B, BINDING_FILE_PATH as C, writeBinding as D, readProjectBinding as E, ENTRY_RULE_DESCRIPTIONS as F, TRACKED_FIELDS as G, runBoardWrite as H, UNMET_ENTRY_RULE_REASONS as I, currentUnixSeconds as J, diffFieldChanges as K, evaluateEntryRules as L, parseExternalSessionRef as M, pullRequestFactKeys as N, maskDatabaseUrl as O, ENTRY_RULES as P, commentAuthorReference as Q, readChecklist as R, cardDisplayTitle as S, readBinding as T, DEFAULT_STATUSES as U, readChangeSeq as V, normalizeStatusName as W, activityText as X, activityKindOrder as Y, activityToken as Z, projectKanboRun as _, BOARD_ERROR_RESPONSES as a, normalizeCommentAuthorKind as at, DEFAULT_BOARD_FILE_PATH as b, registerKanboTools as c, nextIssueIdentity as ct, KANBO_CAPABILITIES_MARKDOWN_RESOURCE_URI as d, readIssuePrefix as dt, formatPlainActivityValue as et, KANBO_CAPABILITIES_RESOURCE_URI as f, projectKanboPullRequest as g, projectKanboColumn as h, KANBO_TOOL_NAMES as i, isOutsideWriter as it, formatExternalSessionRef as j, maskDatabaseUrls as k, KANBO_TOOLS as l, nextIssueNumber as lt, projectKanboCard as m, buildCapabilitiesManifest as n, parseActivityStringArray as nt, KANBO_MCP_SERVER_NAME as o, toIssueView as ot, registerKanboCapabilitiesResources as p, BOARD_ACTOR as q, KANBO_TOOL_CLI_EQUIVALENTS as r, readSystemCommentKind as rt, createKanboMcpServer as s, formatIssueId as st, CAPABILITIES_MANIFEST_VERSION as t, isEmptyActivityValue as tt, buildKanboTools as u, nextIssueOrder as ut, projectKanboSprint as v, ignoreBoardFile as w, renderCapabilitiesMarkdown as x, projectKanboSubCard as y, readEntryRules as z };
8011
+ export { commentAuthorReference as $, maskDatabaseUrls as A, readEntryRules as B, cardDisplayTitle as C, readProjectBinding as D, readBinding as E, ENTRY_RULES as F, normalizeStatusName as G, readChangeSeq as H, ENTRY_RULE_DESCRIPTIONS as I, BOARD_ACTOR as J, TRACKED_FIELDS as K, UNMET_ENTRY_RULE_REASONS as L, formatExternalSessionRef as M, parseExternalSessionRef as N, writeBinding as O, pullRequestFactKeys as P, activityToken as Q, evaluateEntryRules as R, renderCapabilitiesMarkdown as S, ignoreBoardFile as T, runBoardWrite as U, serializeEntryRules as V, DEFAULT_STATUSES as W, activityKindOrder as X, currentUnixSeconds as Y, activityText as Z, projectKanboPullRequest as _, BOARD_ERROR_RESPONSES as a, isOutsideWriter as at, projectKanboSubCard as b, registerKanboTools as c, formatIssueId as ct, KANBO_MCP_INSTRUCTIONS as d, nextIssueOrder as dt, formatActivityIssueReference as et, KANBO_CAPABILITIES_MARKDOWN_RESOURCE_URI as f, readIssuePrefix as ft, projectKanboColumn as g, projectKanboCard as h, KANBO_TOOL_NAMES as i, readSystemCommentKind as it, createBoardOps as j, maskDatabaseUrl as k, KANBO_TOOLS as l, nextIssueIdentity as lt, registerKanboCapabilitiesResources as m, buildCapabilitiesManifest as n, isEmptyActivityValue as nt, KANBO_MCP_SERVER_NAME as o, normalizeCommentAuthorKind as ot, KANBO_CAPABILITIES_RESOURCE_URI as p, diffFieldChanges as q, KANBO_TOOL_CLI_EQUIVALENTS as r, parseActivityStringArray as rt, createKanboMcpServer as s, toIssueView as st, CAPABILITIES_MANIFEST_VERSION as t, formatPlainActivityValue as tt, buildKanboTools as u, nextIssueNumber as ut, projectKanboRun as v, BINDING_FILE_PATH as w, DEFAULT_BOARD_FILE_PATH as x, projectKanboSprint as y, readChecklist as z };
7948
8012
 
7949
- //# sourceMappingURL=manifest-DfOBqo-Q.mjs.map
8013
+ //# sourceMappingURL=manifest-NRhhhOkC.mjs.map