pipebrain-mcp 0.50.0 → 0.51.0

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 (2) hide show
  1. package/dist/main.js +38 -18
  2. package/package.json +1 -1
package/dist/main.js CHANGED
@@ -383,9 +383,9 @@ var AGENT_CONFIG_ENTRIES = [
383
383
  { target: "skills/capture-correction/SKILL.md", sha256: "907ee8fc8e7ea15c8296acd23a816e1f9c6454edcf37a93f18af79b1c542fb75" },
384
384
  { target: "skills/pipebrain-header-pass/SKILL.md", sha256: "10545e3c1c5215b031e1c76281e65cd2ecf7420b3f07a4221824591a8263c5fc" },
385
385
  { target: "skills/pipebrain-secrets/SKILL.md", sha256: "52c2136a3cca5612981d50b926195eae3e804911e1e9723dd5eba76e66b52d6f" },
386
- { target: "skills/pipebrain-work-session/SKILL.md", sha256: "09d5741761b43fc13a12a04117edd8b194aac18974bfedb42dfc76c14030ba87" },
386
+ { target: "skills/pipebrain-work-session/SKILL.md", sha256: "1272d0a403b5826a52616cdbf2dc706f69746c21ac6c930e22df87750a2509b7" },
387
387
  { target: "skills/pipebrain-writing/SKILL.md", sha256: "8e5ed4636afcca0cacc220d8fa5310364d2d6854a9fc68ffa03e4c428989f8b8" },
388
- { target: "skills/pipebrain/SKILL.md", sha256: "e53a1cb13d4e2e396c638d8f99055f4082edef030a40ffc8806b1f52f0824b57" },
388
+ { target: "skills/pipebrain/SKILL.md", sha256: "9fdad1b78bb506e9cd91ba55f4baee0adc5f4d2c5d9d418d0e8c922554e8df74" },
389
389
  { target: "skills/requirements-altitude/SKILL.md", sha256: "60d1916da22a52138c046fcf4e5cd4cc420b7a5679a6652eb76573b7a69a1cf4" }
390
390
  ];
391
391
 
@@ -505,7 +505,7 @@ function apiBindingLabel(apiBaseUrl) {
505
505
  }
506
506
 
507
507
  // ../../libs/agent-shared/dist/doctrine.js
508
- var DOCTRINE = "# Pipebrain doctrine\n\nHow an agent works inside Pipebrain. These rules ship with the product and are the same in every organization. Each one protects something the product guarantees.\n\n## How to write here\n\nThe person reading what you write is the operator, deciding something. They have about two minutes. Put the point first. Use short sentences and ordinary words. Headings and bullets are fine. Explain why once, not under every bullet.\n\nA criterion is one sentence: a concrete situation, and what must be true afterward. If you need a general rule, write two or three criteria instead.\n\nEvidence on a criterion opens with the verdict, then how you drove it, then what it does not cover. Keep it to one screen; name the test or command, not every file you read.\n\nA closing comment says what landed, what did not and why, what you filed by key, and whether the tests are green.\n\nAnything else you notice goes to a question, when the operator has to choose; to a new issue at triage, when it is real work; or, most often, nowhere. Never add a notes, caveats, or next-steps section. An item filed and repeated in prose gets triaged twice.\n\nYour organization may add its own writing rules below this document. Most have none.\n\n## Search before you create\n\nLook for an existing record before you add one. A duplicate splits one record's history across two keys, and nothing merges them later. Update or link the record you find.\n\n## Link by key, never paste\n\nRefer to a requirement, decision, or issue by its key. Never paste its text into a body. When the source changes the copy stays stale, and the stale copy is what gets built.\n\n## Most choices are yours\n\nInside an approved requirement you choose the design, the libraries, and the order of work. Ask only when a choice changes what a user sees, costs money, or contradicts a requirement; file that one as a question. Asking about everything makes real questions wait behind choices that were yours. A technical choice worth keeping goes in a decision record.\n\n## File decisions as questions\n\nAn open decision goes in a question on the issue, filed with `ask_questions` and carrying the options you propose. It does not belong in a body, under a heading or in a field. Prose asks nobody and records no answer, so a later session cannot tell whether it was ever decided. Withdraw a question your own work has settled.\n\n## Cross-cutting requirements arrive on their own\n\nThey bind every epic and come back with a work-item read, at their latest approved revision. Never restate them in a body and never add them as explicit requirement links. A copy drifts, and an explicit link pins one revision where the read delivers the newest.\n\n## Conventions need a person's approval\n\nApproved conventions come back with the same work-item read and bind every project in the organization. Never restate one in a body and never add one as an explicit link; a copy goes stale.\n\nA convention you create or amend over the agent surface is a proposal. It is not in force until a person approves it in a browser. Until then, do not work from your own unapproved wording.\n\nA statement that stops being true when this project ends is a cross-cutting requirement. One still true on the next project is a convention. File one when an evaluator rejects work or a criterion fails, and rarely otherwise: each reaches every read, after a person reviews it.\n\n## Choosing auto or manual\n\nFirst find out what this project can drive end to end, and with which command. A criterion is `auto` when an evaluator can drive the input and read the result on the running system, including an interface where a browser harness exists. Only the evaluator's own run qualifies it; a test the implementer wrote does not. An auto criterion nobody can drive never gets evidence.\n\nMark a criterion `manual` only when the verdict needs a person's judgment. A manual row a machine could have checked holds the issue open until a person gets to it. If you cannot say how to drive a criterion, it is worded too vaguely; reword it against something observable. A manual criterion carries instructions for a stranger to the code.\n\nA manual criterion with no recorded artifact is the human gate working as designed, and not a finding.\n\n## The bar for filing a bug\n\nFile a bug only when the behavior breaks an approved requirement or a defined acceptance criterion, and name which one first. Everything else, including unclear code and edge cases nobody specified, is feedback or nothing. A queue that mixes defects with taste has to be read in full before any of it can be trusted.\n\n## A decision record is written once\n\nA decision record says what was decided and why, at the time. Do not edit it later; write a superseding record instead. The chain of records shows how the thinking changed, and an edit destroys it. Read existing records before reopening a settled question.\n\n## A secret value never travels in a tool call\n\nNo tool returns a secret value, by design, and none should receive one. A value in a tool call is in the transcript before the server can encrypt it; the only remedy is rotation. Set values with the command-line tool, from a file or standard input, and inject at run time.\n\n## Setting an instruction replaces the whole body\n\nThere is no partial update. An instruction write stores exactly the body you supply and discards everything that was there. Read the live value, compose the complete replacement, write it, then read it again to confirm what landed.\n\nThis guidance and the tool descriptions are a snapshot from the session's start; an edit reaches the next session, never this one. `list_org_instructions` returns the saved rows as they are now; that is the confirming read.\n";
508
+ var DOCTRINE = "# Pipebrain doctrine\n\nHow an agent works inside Pipebrain. These rules ship with the product and are the same in every organization. Each one protects something the product guarantees.\n\n## How to write here\n\nThe person reading what you write is the operator, deciding something. They have about two minutes. Put the point first. Use short sentences and ordinary words. Headings and bullets are fine. Explain why once, not under every bullet.\n\nA criterion is one sentence: a concrete situation, and what must be true afterward. If you need a general rule, write two or three criteria instead.\n\nEvidence on a criterion opens with the verdict, then how you drove it, then what it does not cover. Keep it to one screen; name the test or command, not every file you read.\n\nA closing comment says what landed, what did not and why, what you filed by key, and whether the tests are green.\n\nAnything else you notice goes to a question, when the operator has to choose; to a new issue at triage, when it is real work; or, most often, nowhere. Never add a notes, caveats, or next-steps section. An item filed and repeated in prose gets triaged twice.\n\nYour organization may add its own writing rules below this document. Most have none.\n\n## Search before you create\n\nLook for an existing record before you add one. A duplicate splits one record's history across two keys, and nothing merges them later. Update or link the record you find.\n\n## Link by key, never paste\n\nRefer to a requirement, decision, or issue by its key. Never paste its text into a body. When the source changes the copy stays stale, and the stale copy is what gets built.\n\n## Most choices are yours\n\nInside an approved requirement you choose the design, the libraries, and the order of work. Ask only when a choice changes what a user sees, costs money, or contradicts a requirement; file that one as a question. Asking about everything makes real questions wait behind choices that were yours. A technical choice worth keeping goes in a decision record.\n\n## File decisions as questions\n\nAn open decision goes in a question on the issue, filed with `ask_questions` and carrying the options you propose. It does not belong in a body, under a heading or in a field. Prose asks nobody and records no answer, so a later session cannot tell whether it was ever decided. If your own work settles a question, answer it with `answer_question` \u2014 the answer is worth keeping, and withdrawing throws it away. Withdraw only a question that should never have been asked.\n\n## Cross-cutting requirements arrive on their own\n\nThey bind every epic and come back with a work-item read, at their latest approved revision. Never restate them in a body and never add them as explicit requirement links. A copy drifts, and an explicit link pins one revision where the read delivers the newest.\n\n## Conventions need a person's approval\n\nApproved conventions come back with the same work-item read and bind every project in the organization. Never restate one in a body and never add one as an explicit link; a copy goes stale.\n\nA convention you create or amend over the agent surface is a proposal. It is not in force until a person approves it in a browser. Until then, do not work from your own unapproved wording.\n\nA statement that stops being true when this project ends is a cross-cutting requirement. One still true on the next project is a convention. File one when an evaluator rejects work or a criterion fails, and rarely otherwise: each reaches every read, after a person reviews it.\n\n## Choosing auto or manual\n\nFirst find out what this project can drive end to end, and with which command. A criterion is `auto` when an evaluator can drive the input and read the result on the running system, including an interface where a browser harness exists. Only the evaluator's own run qualifies it; a test the implementer wrote does not. An auto criterion nobody can drive never gets evidence.\n\nMark a criterion `manual` only when the verdict needs a person's judgment. A manual row a machine could have checked holds the issue open until a person gets to it. If you cannot say how to drive a criterion, it is worded too vaguely; reword it against something observable. A manual criterion carries instructions for a stranger to the code.\n\nA manual criterion with no recorded artifact is the human gate working as designed, and not a finding.\n\nThis choice also decides who can finish the work. What gates finishing is the work rather than the caller \u2014 the status tool names what the gate reads, and the server never asks who is calling. A manual row is the one a credential cannot pass, so work carrying one waits for a person; work whose criteria are all machine-checked does not, and the session that has just passed them can set it done.\n\n## The bar for filing a bug\n\nFile a bug only when the behavior breaks an approved requirement or a defined acceptance criterion, and name which one first. Everything else, including unclear code and edge cases nobody specified, is feedback or nothing. A queue that mixes defects with taste has to be read in full before any of it can be trusted.\n\n## A decision record is written once\n\nA decision record says what was decided and why, at the time. A proposed record is still being written: correct it with `update_decision`, and accept it once it says what you decided. An accepted record is settled, so never edit one; write a superseding record instead. The chain of records shows how the thinking changed, and an edit destroys it. Read existing records before reopening a settled question.\n\n## A secret value never travels in a tool call\n\nNo tool returns a secret value, by design, and none should receive one. A value in a tool call is in the transcript before the server can encrypt it; the only remedy is rotation. Set values with the command-line tool, from a file or standard input, and inject at run time.\n\n## Setting an instruction replaces the whole body\n\nThere is no partial update. An instruction write stores exactly the body you supply and discards everything that was there. Read the live value, compose the complete replacement, write it, then read it again to confirm what landed.\n\nThis guidance and the tool descriptions are a snapshot from the session's start; an edit reaches the next session, never this one. `list_org_instructions` returns the saved rows as they are now; that is the confirming read.\n";
509
509
 
510
510
  // ../../libs/agent-shared/dist/org-reference.js
511
511
  var CANONICAL_UUID_RE = /^[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}$/i;
@@ -16877,8 +16877,9 @@ var ApiClient = class _ApiClient {
16877
16877
  /**
16878
16878
  * Answers a question by its stable `Q-{n}` number with EXACTLY one of `option`
16879
16879
  * (1-based, into the question's options) or `text` (PIPE-93); answering again
16880
- * revises. Session only — a bearer caller is refused, so this is the web app's
16881
- * call, never the MCP's. Returns the updated detail.
16880
+ * revises. Token OR session (PIPE-450): the bearer refusal PIPE-R22 r2 withdrew is
16881
+ * gone, and the answer records the credential behind it instead. Returns the updated
16882
+ * detail.
16882
16883
  */
16883
16884
  answerQuestion(ref, number4, answer) {
16884
16885
  return this.request("POST", `/api/v1/issues/${enc(ref)}/questions/${number4}/answer`, { body: answer });
@@ -17208,9 +17209,12 @@ var ApiClient = class _ApiClient {
17208
17209
  }
17209
17210
  // --- the waiting queue -----------------------------------------------------
17210
17211
  /**
17211
- * Every gate awaiting a person across ALL projects of the caller's organisation
17212
+ * Everything not moving on its own across ALL projects of the caller's organisation
17212
17213
  * (PIPE-87): revisions awaiting approval, questions awaiting an answer, and work
17213
- * in `verify` with a criterion not yet passed, longest wait first.
17214
+ * in `verify` with a criterion not yet passed, longest wait first. Not all of it
17215
+ * waits on a person — a question clears with `answer_question` and an `auto`
17216
+ * criterion with `set_criterion_state`; the one a credential cannot pass is a
17217
+ * criterion marked for human judgment.
17214
17218
  *
17215
17219
  * Takes NO project and NO org PARAMETER: a queue you point at a project is the
17216
17220
  * per-project surface this replaces, and the organization is a property of the CLIENT,
@@ -17675,7 +17679,7 @@ function createMcpServer(baseClient, apiBaseUrl, orgInstructions2 = /* @__PURE__
17675
17679
  );
17676
17680
  }
17677
17681
  registerStrict("list_orgs", {
17678
- description: "List the organizations this credential may act in, with each name, slug, id, kind and your role. This is the one tool that needs no `org`: every other call names the organization it acts in and is refused without one, and this is how you find the names you may use. The answer is your memberships right now, which is what that check reads, so a joined organization appears and a left one does not."
17682
+ description: "List the organizations this credential may act in, with each name, slug, id, kind and your role. Use it to find the names you may pass. This is the one tool that needs no `org`: every other call names the organization it acts in, and omitting it is refused unless this session has a default. The answer is your memberships right now, so a joined organization appears and a left one does not."
17679
17683
  }, () => (
17680
17684
  // A BARE ARRAY, unlike `list_waiting`'s `{ items }`, and for the reason that tool
17681
17685
  // gives rather than against it: the envelope has already been unwrapped by
@@ -17715,7 +17719,7 @@ function createMcpServer(baseClient, apiBaseUrl, orgInstructions2 = /* @__PURE__
17715
17719
  }
17716
17720
  }, (args) => run(() => client2().createProject(args)));
17717
17721
  registerStrict("list_waiting", {
17718
- description: "Every gate awaiting a person across all projects in the organization named by `org`, longest wait first: a requirement revision awaiting approval, a question awaiting an answer, and work at verify still holding a criterion that has not passed. Each entry names its project, the ref to act on, and when the wait began. Read-only, and it clears nothing. A revision clears with `approve_requirement`. Use it to see what is waiting before you ask."
17722
+ description: "Everything not moving on its own across all projects in the organization named by `org`, longest wait first: a requirement revision awaiting approval, an unanswered question, and work at verify holding a criterion that has not passed. Each entry names its project, the ref to act on, and when the wait began. Read-only. A revision clears with `approve_requirement`, a question with `answer_question`, an `auto` criterion with `set_criterion_state`. A criterion marked for human judgment waits for a person."
17719
17723
  }, () => (
17720
17724
  // `{ items }`, mirroring the HTTP envelope rather than unwrapping to a bare array
17721
17725
  // like the sibling list tools. The reason is the envelope itself: this tool is a
@@ -17895,22 +17899,22 @@ function createMcpServer(baseClient, apiBaseUrl, orgInstructions2 = /* @__PURE__
17895
17899
  })
17896
17900
  ), GUIDANCE_POINTER));
17897
17901
  registerStrict("create_issue", {
17898
- description: "Create an epic, task, bug or feedback. Status defaults to triage; anything but triage or killed needs a milestone, else refused `milestone_required`. Optional parent, priority, milestone, links and ordered criteria. An open issue under a done or killed parent is refused `parent_terminal`. Epics, tasks and bugs carry criteria; feedback is refused `criteria_not_supported`. A `manual` criterion needs `howTo`, else refused `how_to_required`. A bug may name the criterion it was filed against. See the doctrine `get_work_context` returns, under \u201CSearch before you create\u201D.",
17902
+ description: "Create an epic, task, bug or feedback. Status defaults to triage; anything but triage or killed needs a milestone, else refused `milestone_required`. An archived milestone is refused `milestone_archived_write`. An open issue under a done or killed parent is refused `parent_terminal`. Epics, tasks and bugs carry criteria; feedback is refused `criteria_not_supported`. A `manual` criterion needs `howTo`, else refused `how_to_required`. A bug may name the criterion it was filed against. See the doctrine `get_work_context` returns, under \u201CSearch before you create\u201D.",
17899
17903
  inputSchema: createIssueInputSchema.shape
17900
17904
  }, (args) => run(() => client2().createIssue(args)));
17901
17905
  registerStrict("promote_feedback", {
17902
- description: "Retype a feedback report as real work \u2014 an epic or a task \u2014 so it can carry criteria and be built. Feedback itself is refused `criteria_not_supported`, which is what this call resolves. Closing the source feedback is refused `status_guard` when anything beneath it, at any depth, is not done or killed, and the refusal names it. A `manual` criterion needs `howTo`, or it is refused `how_to_required`. See the doctrine `get_work_context` returns, under \u201CThe bar for filing a bug\u201D.",
17906
+ description: "Retype a feedback report as real work \u2014 an epic or a task \u2014 so it can carry criteria and be built. Feedback itself is refused `criteria_not_supported`. Scheduling the new work into an archived milestone is refused `milestone_archived_write`. Closing the source feedback is refused `status_guard` when anything beneath it, at any depth, is not done or killed. A `manual` criterion needs `howTo`, else refused `how_to_required`. See the doctrine `get_work_context` returns, under \u201CThe bar for filing a bug\u201D.",
17903
17907
  inputSchema: {
17904
17908
  issue: external_exports.string().min(1),
17905
17909
  ...promoteFeedbackInputSchema.shape
17906
17910
  }
17907
17911
  }, ({ issue: issue2, ...fields }) => run(() => client2().promoteFeedback(issue2, fields)));
17908
17912
  registerStrict("open_review", {
17909
- description: "Open the completion review of an epic\u2019s whole change, by a session that neither built nor evaluated it. It creates one task at ready carrying the checklist. Pass exactly one of `epic`, or `project` plus `milestone`. One review stands per scope; a second is refused `review_already_open`. An epic-form review also holds that milestone scope; a milestone-form review blocks no epic. File findings as children of the epic, not the review. See the doctrine `get_work_context` returns, under \u201CHow to write here\u201D.",
17913
+ description: "Open an epic\u2019s completion review, read by whoever neither built nor evaluated it: one ready task carrying the checklist. Pass exactly one of `epic`, or `project` plus `milestone`. A first call is refused `review_target_not_epic`, `review_target_terminal` (finished epic), `milestone_required` (no milestone), `milestone_not_found` (unknown token). One review per scope; a second is refused `review_already_open`. Epic-form also holds that milestone scope; milestone-form blocks no epic. File findings under the epic, not the review. See the doctrine `get_work_context` returns, under \u201CHow to write here\u201D.",
17910
17914
  inputSchema: openReviewInputSchema
17911
17915
  }, (args) => run(() => client2().openReview(args)));
17912
17916
  registerStrict("update_issue", {
17913
- description: "Change an issue\u2019s fields, parent and links. Header fields are refused here; criteria are set with `set_criteria`, which epics, tasks and bugs all carry. Moving an open issue onto a done or killed parent is refused `parent_terminal`; one with open work beneath it is refused `parent_terminal_subtree`. A cycle-closing re-parent is refused `parent_cycle`. Attaching open work starts its new parent unless that parent is blocked, unscheduled or under a finished parent. See the doctrine `get_work_context` returns, under \u201CMost choices are yours\u201D.",
17917
+ description: "Change an issue\u2019s fields, parent and links. Header fields are refused; `set_criteria` sets criteria, which epics, tasks and bugs carry. An archived milestone is refused `milestone_archived_write`, unless the issue or its parent carries it. A cycle-closing re-parent is refused `parent_cycle`. A finished parent refuses an open issue, `parent_terminal`; a finished one holding open work, `parent_terminal_subtree`. Attaching open work starts a parent that is not blocked, unscheduled or under finished work. See the doctrine `get_work_context` returns, under \u201CMost choices are yours\u201D.",
17914
17918
  inputSchema: updateIssueInputSchema.shape
17915
17919
  }, ({ issue: issue2, ...fields }) => run(() => client2().updateIssue(issue2, fields)));
17916
17920
  registerStrict("set_issue_header", {
@@ -17918,7 +17922,7 @@ function createMcpServer(baseClient, apiBaseUrl, orgInstructions2 = /* @__PURE__
17918
17922
  inputSchema: setIssueHeaderInputSchema.shape
17919
17923
  }, ({ issue: issue2, ...fields }) => run(() => client2().setIssueHeader(issue2, fields)));
17920
17924
  registerStrict("set_status", {
17921
- description: "Move an issue to a new status. verify needs every auto criterion passed; done needs every criterion passed, and every issue beneath it, at any depth, done or killed \u2014 epic, task or bug alike \u2014 read from status. An epic with no criteria is refused at both gates; a task or bug with none moves through. A blocked issue cannot reach ready or in_progress until its blockers clear. An issue with no milestone can only be triage or killed.",
17925
+ description: "Move an issue to another status. An open status under a done or killed parent is refused `parent_terminal_reopen`. verify needs every auto criterion passed; done needs every criterion passed and everything beneath it, at any depth, done or killed. An epic with no criteria is refused at both gates; a task or bug with none moves through. Blocked work cannot reach ready or in_progress until blockers clear. Work with no milestone can only be triage or killed.",
17922
17926
  inputSchema: setStatusInputSchema.shape
17923
17927
  }, (args) => run(() => client2().setStatus(args.issue, args.status)));
17924
17928
  registerStrict("claim_issue", {
@@ -17977,13 +17981,17 @@ function createMcpServer(baseClient, apiBaseUrl, orgInstructions2 = /* @__PURE__
17977
17981
  });
17978
17982
  }));
17979
17983
  registerStrict("ask_questions", {
17980
- description: "Ask the operator one or more questions on an issue. Send the batch in one call \u2014 a half-asked set costs a second pass. Each question gets a stable `Q-{n}` number that is never reused, and `options` are the choices you propose. Answers come back on every later read of the issue, so read them before asking again rather than re-asking a settled decision. Withdraw one with `withdraw_question`. See the doctrine `get_work_context` returns, under \u201CFile decisions as questions\u201D.",
17984
+ description: "Ask the operator questions on an issue. Send them in one call \u2014 a half-asked set costs a second pass. Each question gets a stable `Q-{n}` number, never reused; `options` are the choices you propose. Answers come back on every later read; read them before asking again. Answer one yourself with `answer_question` when your work settles it; withdraw one with `withdraw_question` if it should never have been asked. See the doctrine `get_work_context` returns, under \u201CFile decisions as questions\u201D.",
17981
17985
  inputSchema: askQuestionsInputSchema.shape
17982
17986
  }, (args) => run(() => client2().askQuestions(args.issue, args.questions)));
17983
17987
  registerStrict("withdraw_question", {
17984
- description: "Withdraw a question by its `Q-{n}` number, in the organization named by `org`. Only the asker may withdraw, and the asker is the person your credential belongs to, so another agent\u2019s question is not yours to clear. Use it when your own work settled the question or it was wrong to ask, rather than leaving the operator to answer something nobody awaits. The question is kept for the audit trail, its number retires, and later reads no longer carry it.",
17988
+ description: "Withdraw a question by its `Q-{n}` number, in the organization named by `org`. Only the asker may withdraw, and the asker is the person your credential belongs to, so another agent\u2019s question is not yours to clear. Use it for a question that should never have been asked; one your own work settled deserves `answer_question` instead, which keeps the answer. The question is kept for the audit trail, its number retires, and later reads no longer carry it.",
17985
17989
  inputSchema: withdrawQuestionInputSchema.shape
17986
17990
  }, (args) => run(() => client2().withdrawQuestion(args.issue, args.number)));
17991
+ registerStrict("answer_question", {
17992
+ description: "Answer a question by its `Q-{n}` number, in the organization named by `org`. Pass exactly one of `option` (a 1-based index into the choices offered) or `text` \u2014 both, or neither, is refused here before anything is sent. Answering again revises; every answer records who answered and which credential. An out-of-range index is refused `option_out_of_range`, naming how many choices there are; a withdrawn or unknown number, `question_not_found`. Answer what your own work settled; leave the rest to the operator.",
17993
+ inputSchema: answerQuestionInputSchema
17994
+ }, (args) => run(() => client2().answerQuestion(args.issue, args.number, { option: args.option, text: args.text })));
17987
17995
  registerStrict("list_requirements", {
17988
17996
  description: "List requirements filtered by project and text: lifecycle (draft/approved/amended), the latest and approved revision numbers, the cross-cutting flag and the linked-epic count.",
17989
17997
  inputSchema: listRequirementsFilterSchema.shape
@@ -18078,6 +18086,18 @@ function createMcpServer(baseClient, apiBaseUrl, orgInstructions2 = /* @__PURE__
18078
18086
  description: "List decision records filtered by `project` and `text`: each one\u2019s state, its replacement when superseded, and how many requirements and work items cite it. `text` matches title and body.",
18079
18087
  inputSchema: listDecisionsFilterSchema.shape
18080
18088
  }, (args) => run(() => client2().listDecisions(args), GUIDANCE_POINTER));
18089
+ registerStrict("update_decision", {
18090
+ description: "Correct a decision record while it is still `proposed`: `title`, `body`, or both. An edit naming nothing to change is refused here, before anything is sent. Once a record is `accepted` or `superseded` its text is frozen, and the correction is refused `decision_frozen`, which says to write the change as a new record and supersede this one. Use `accept_decision` to accept; asking for `superseded` here is refused, because superseding must name the replacement.",
18091
+ inputSchema: updateDecisionInputSchema
18092
+ }, (args) => run(() => client2().updateDecision(args.decision, {
18093
+ title: args.title,
18094
+ body: args.body,
18095
+ status: args.status
18096
+ })));
18097
+ registerStrict("accept_decision", {
18098
+ description: "Accept a decision record that is still `proposed`: it becomes `accepted`, stamped with who accepted it and when, and its text is frozen from then on \u2014 changing it later means a new record plus `supersede_decision`. The tool names the move, so the record is the only argument. A record that is already `accepted` or `superseded` is refused `decision_transition_not_allowed`, naming what it can still do.",
18099
+ inputSchema: { decision: decisionRefSchema }
18100
+ }, (args) => run(() => client2().updateDecision(args.decision, { status: "accepted" })));
18081
18101
  registerStrict("supersede_decision", {
18082
18102
  description: "Replace an accepted decision record with another: `decision` becomes `superseded` and points at `replacedBy`, where the current decision lives. Refused while the record is still `proposed` (correct it instead), when a record replaces itself, when the replacement is in another project, or when its chain already leads back to this record.",
18083
18103
  inputSchema: supersedeDecisionInputSchema.shape
@@ -18113,7 +18133,7 @@ function createMcpServer(baseClient, apiBaseUrl, orgInstructions2 = /* @__PURE__
18113
18133
  registerStrict("promote_deliverable", {
18114
18134
  // The paste exception is stated because without it an agent holding the doctrine
18115
18135
  // would refuse this tool's whole purpose.
18116
- description: "Create a NEW issue from a deliverable (`DRAFT-KEY/platform`) with a protected link pinning its current revision, which cannot be removed. Needs `title` and `type`; `status` defaults to triage, `body` seeds the issue. A `status` past triage or killed needs `milestone`, or it is refused `milestone_required`. Seeding `body` with the post text is the exception to linking rather than pasting. See the doctrine `get_work_context` returns, under \u201CLink by key, never paste\u201D.",
18136
+ description: "Create a NEW issue from a deliverable (`DRAFT-KEY/platform`) with a protected link pinning its current revision, which cannot be removed. Needs `title` and `type`; `status` defaults to triage, `body` seeds the issue. A `status` past triage or killed needs a `milestone`, else refused `milestone_required`. An archived milestone is refused `milestone_archived_write`. Seeding `body` with the post text is the exception to linking rather than pasting. See the doctrine `get_work_context` returns, under \u201CLink by key, never paste\u201D.",
18117
18137
  inputSchema: {
18118
18138
  deliverable: external_exports.string().min(1),
18119
18139
  title: external_exports.string().min(1),
@@ -18293,7 +18313,7 @@ function loadMcpConfig() {
18293
18313
  }
18294
18314
 
18295
18315
  // src/version.ts
18296
- var VERSION = "0.50.0";
18316
+ var VERSION = "0.51.0";
18297
18317
 
18298
18318
  // src/main.ts
18299
18319
  async function scopedClient(base, org) {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "pipebrain-mcp",
3
- "version": "0.50.0",
3
+ "version": "0.51.0",
4
4
  "description": "Pipebrain MCP server for Claude Code and Claude Desktop — issues, requirements, decision records, conventions, prompts, content, assets, metadata-only secrets, and more of the platform's modules over the Pipebrain API.",
5
5
  "type": "module",
6
6
  "license": "MIT",