pipebrain-mcp 0.25.0 → 0.27.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 +39 -5
  2. package/package.json +1 -1
package/dist/main.js CHANGED
@@ -15613,8 +15613,10 @@ var createIssueInputSchema = external_exports.strictObject({
15613
15613
  deliverableLinks: external_exports.array(deliverableRefSchema).optional(),
15614
15614
  criteria: external_exports.array(criterionInputSchema).optional(),
15615
15615
  // The acceptance criterion this bug was filed against (PIPE-272). Records on the
15616
- // BUG which row sent someone to file it, so that row can name the bug instead of
15617
- // offering to file another. Server-refused on any type but `bug`
15616
+ // BUG which row sent someone to file it, so that row can name what has already
15617
+ // been reported beside the action that reports again — a criterion can carry
15618
+ // more than one bug (PIPE-287), and a duplicate is prevented by information, not
15619
+ // by removing the control. Server-refused on any type but `bug`
15618
15620
  // (`criterion_requires_bug`) and on a criterion outside the caller's org.
15619
15621
  criterionId: uuidSchema.optional()
15620
15622
  });
@@ -15664,6 +15666,17 @@ var getWorkContextInputSchema = external_exports.strictObject({
15664
15666
  }).refine((v) => v.issue === void 0 !== (v.project === void 0), {
15665
15667
  message: "pass exactly one of `issue` or `project` \u2014 an issue names its own project, and passing neither names nothing to read"
15666
15668
  });
15669
+ var openReviewInputSchema = external_exports.strictObject({
15670
+ epic: issueRefSchema.optional(),
15671
+ project: projectRefSchema.optional(),
15672
+ milestone: external_exports.string().min(1, { message: "milestone must not be empty \u2014 name the token the review reads" }).optional()
15673
+ }).refine((v) => {
15674
+ const epicForm = v.epic !== void 0 && v.project === void 0 && v.milestone === void 0;
15675
+ const milestoneForm = v.epic === void 0 && v.project !== void 0 && v.milestone !== void 0;
15676
+ return epicForm !== milestoneForm;
15677
+ }, {
15678
+ message: "pass exactly one of `epic` or `project` + `milestone` \u2014 an epic names its own project and milestone, and passing neither names nothing to review"
15679
+ });
15667
15680
  var claimInputSchema = external_exports.strictObject({
15668
15681
  issue: issueRefSchema
15669
15682
  });
@@ -16017,7 +16030,12 @@ var deleteOrgInstructionInputSchema = external_exports.strictObject({
16017
16030
  });
16018
16031
 
16019
16032
  // ../../libs/domain/dist/instructions.js
16020
- var ISSUE_WRITE_TOOLS = ["create_issue", "update_issue", "promote_feedback"];
16033
+ var ISSUE_WRITE_TOOLS = [
16034
+ "create_issue",
16035
+ "update_issue",
16036
+ "promote_feedback",
16037
+ "open_review"
16038
+ ];
16021
16039
  var INSTRUCTION_SCOPE_TARGETS = {
16022
16040
  general: { kind: "server" },
16023
16041
  requirements: { kind: "tools", tools: ["create_requirement", "update_requirement"] },
@@ -16218,6 +16236,14 @@ var ApiClient = class _ApiClient {
16218
16236
  createIssue(input) {
16219
16237
  return this.request("POST", "/api/v1/issues", { body: input });
16220
16238
  }
16239
+ /**
16240
+ * Opens a completion review (PIPE-217) — `{epic}` or `{project, milestone}`,
16241
+ * exactly one. Returns the created task: a review is an ordinary issue, so this
16242
+ * is the same detail payload the create path returns.
16243
+ */
16244
+ openReview(input) {
16245
+ return this.request("POST", "/api/v1/reviews", { body: input });
16246
+ }
16221
16247
  /** Promotes a feedback issue into a new epic or task (PIPE-143). */
16222
16248
  promoteFeedback(ref, input) {
16223
16249
  return this.request("POST", `/api/v1/issues/${enc(ref)}/promote`, { body: input });
@@ -17099,7 +17125,7 @@ Every loose end has one destination, and none of them is prose. Anything you not
17099
17125
  inputSchema: { issue: issueRefSchema }
17100
17126
  }, (args) => run(() => client2.getIssue(args.issue)));
17101
17127
  registerTool("create_issue", {
17102
- description: 'Create an issue (epic/task/bug/feedback). Omitted status defaults to triage (still subject to \xA76 guards); omitted environment resolves explicit \u2192 parent\u2019s environment \u2192 project default (prod). Optional parent (self/cycle rejected), priority, milestone, requirement_links (pins each at its approved revision; a target with no approved revision is rejected), deliverable_links (content deliverables like DWB-C3/bsky \u2014 pins each at its current revision; the promotion path), and ordered {text, verification, howTo} criteria (\xA77). A `status` other than `triage` or `killed` REQUIRES `milestone` (PIPE-R10 rule 9): work past triage belongs to a release, and the create is refused (`milestone_required`) without one. Search before you create: `list_issues` takes a `text` filter \u2014 run it on the distinctive nouns first. Sessions do not see each other, so a duplicate is invisible until someone finds both; on a near match, comment or amend the existing record rather than filing again. The bar for filing a bug: file `type: bug` only when the observed behavior breaks an approved requirement or a defined acceptance criterion, and name which one before you file. If you cannot name one, this is not a bug \u2014 code you find unclear, an edge case nobody specified, a performance number nobody set, and anything you would phrase as "this could be better" are opinions about the product, so file each as `type: feedback`, or not at all. The bar exists because a queue holding both real defects and unshared taste has to be read entirely before any of it can be trusted. When the criterion you named is an acceptance criterion, pass its uuid as `criterionId` and the bug records which criterion it was filed against \u2014 the criterion then names the bug (it arrives as `filedBugs` on every criteria read) instead of inviting the next reader to file it again. Bugs only: any other type naming a criterion is refused (`criterion_requires_bug`). Link another record by key plus title on first mention; never paste its text into a body \u2014 the source changes, the copy does not, and a stale copy gets built. A decision you need from the operator is filed as a question via `ask_questions`, never written as an "Open questions" heading inside a body \u2014 a heading prompts nobody and records no answer, so a later session cannot tell whether the decision was made. Before assigning any verification mode, establish what this project can drive end to end \u2014 an end-to-end test harness and the command that runs it. A criterion is `auto` when an evaluator can drive the input and read the result against the running system, which includes behavior shown in the interface wherever such a harness exists; the mode follows from what can be driven, not from where the behavior appears. What qualifies a criterion as `auto` is the evaluator\u2019s own run, never the existence of a test the implementer wrote. Mark `manual` only when the verdict needs a person\u2019s judgment; a criterion you cannot describe as drivable is usually worded too vaguely, so reword it against the observable rather than fall back to a person. A `manual` criterion must also carry `howTo` \u2014 one or two sentences, not an essay, saying where to look, what to do, and what counts as passing for whoever checks it by hand. Writing or changing one without it is refused (`how_to_required`); so is supplying it on an `auto` criterion, which a machine checks. Work of any kind carries criteria \u2014 an epic, a task, a bug \u2014 because what they answer is how anyone knows the thing is done, and that question does not get easier as the work gets smaller; feedback is the one exception, refused with `criteria_not_supported`, because it is a report rather than agreed work and `promote_feedback` retypes it into work before anything is built. Cross-cutting requirements bind every epic automatically and arrive with `get_issue` \u2014 never restate them in a body and never add them to `requirement_links`; an explicit link pins the linked document\u2019s approved revision.',
17128
+ description: 'Create an issue (epic/task/bug/feedback). Omitted status defaults to triage (still subject to \xA76 guards); omitted environment resolves explicit \u2192 parent\u2019s environment \u2192 project default (prod). Optional parent (self/cycle rejected), priority, milestone, requirement_links (pins each at its approved revision; a target with no approved revision is rejected), deliverable_links (content deliverables like DWB-C3/bsky \u2014 pins each at its current revision; the promotion path), and ordered {text, verification, howTo} criteria (\xA77). A `status` other than `triage` or `killed` REQUIRES `milestone` (PIPE-R10 rule 9): work past triage belongs to a release, and the create is refused (`milestone_required`) without one. Search before you create: `list_issues` takes a `text` filter \u2014 run it on the distinctive nouns first. Sessions do not see each other, so a duplicate is invisible until someone finds both; on a near match, comment or amend the existing record rather than filing again. The bar for filing a bug: file `type: bug` only when the observed behavior breaks an approved requirement or a defined acceptance criterion, and name which one before you file. If you cannot name one, this is not a bug \u2014 code you find unclear, an edge case nobody specified, a performance number nobody set, and anything you would phrase as "this could be better" are opinions about the product, so file each as `type: feedback`, or not at all. The bar exists because a queue holding both real defects and unshared taste has to be read entirely before any of it can be trusted. When the criterion you named is an acceptance criterion, pass its uuid as `criterionId` and the bug records which criterion it was filed against \u2014 the criterion then names what has already been reported (it arrives as `filedBugs` on every criteria read) beside the action that files again, so a duplicate is prevented by information rather than by removal. Filing a second bug against one criterion is a supported situation, not a mistake: one row can fail for two different reasons at once. Bugs only: any other type naming a criterion is refused (`criterion_requires_bug`). Link another record by key plus title on first mention; never paste its text into a body \u2014 the source changes, the copy does not, and a stale copy gets built. A decision you need from the operator is filed as a question via `ask_questions`, never written as an "Open questions" heading inside a body \u2014 a heading prompts nobody and records no answer, so a later session cannot tell whether the decision was made. Before assigning any verification mode, establish what this project can drive end to end \u2014 an end-to-end test harness and the command that runs it. A criterion is `auto` when an evaluator can drive the input and read the result against the running system, which includes behavior shown in the interface wherever such a harness exists; the mode follows from what can be driven, not from where the behavior appears. What qualifies a criterion as `auto` is the evaluator\u2019s own run, never the existence of a test the implementer wrote. Mark `manual` only when the verdict needs a person\u2019s judgment; a criterion you cannot describe as drivable is usually worded too vaguely, so reword it against the observable rather than fall back to a person. A `manual` criterion must also carry `howTo` \u2014 one or two sentences, not an essay, saying where to look, what to do, and what counts as passing for whoever checks it by hand. Writing or changing one without it is refused (`how_to_required`); so is supplying it on an `auto` criterion, which a machine checks. Work of any kind carries criteria \u2014 an epic, a task, a bug \u2014 because what they answer is how anyone knows the thing is done, and that question does not get easier as the work gets smaller; feedback is the one exception, refused with `criteria_not_supported`, because it is a report rather than agreed work and `promote_feedback` retypes it into work before anything is built. Cross-cutting requirements bind every epic automatically and arrive with `get_issue` \u2014 never restate them in a body and never add them to `requirement_links`; an explicit link pins the linked document\u2019s approved revision.',
17103
17129
  inputSchema: createIssueInputSchema.shape
17104
17130
  }, (args) => run(() => client2.createIssue(args)));
17105
17131
  registerTool("promote_feedback", {
@@ -17109,6 +17135,14 @@ Every loose end has one destination, and none of them is prose. Anything you not
17109
17135
  ...promoteFeedbackInputSchema.shape
17110
17136
  }
17111
17137
  }, ({ issue: issue2, ...fields }) => run(() => client2.promoteFeedback(issue2, fields)));
17138
+ registerTool("open_review", {
17139
+ description: "Open the COMPLETION REVIEW \u2014 the reading of an epic\u2019s WHOLE accumulated change as one body of work, by a third fresh session that neither built it nor evaluated it. It runs at one moment: once the epic\u2019s contract is green and nothing is left to check, and before anyone sets it `done`. It creates one ORDINARY `task` at `ready` carrying the review checklist as its body \u2014 no new record type. The epic form (`epic`) titles it `Completion review \u2014 <KEY-n> <epic title>`, files it as a CHILD of the epic and inherits the epic\u2019s milestone; the milestone form (`project` + `milestone`) titles it `Completion review \u2014 milestone <token>`, carries that token and has no parent \u2014 nothing here models a milestone as complete. Pass EXACTLY ONE of `epic` or `project` + `milestone`: both, or neither, is refused. One review at a time per scope \u2014 a second is refused (`review_already_open`) NAMING the standing one, so read, finish or kill that task instead \u2014 and a review opens only on an epic (`review_target_not_epic`). NO NEW GATE was added to `done`, and the whole mechanism depends on that: file each finding as ordinary work \u2014 a CHILD OF THE EPIC, a sibling of this review \u2014 and the children clause already on `done` holds the epic open until every finding is done or killed. A finding filed UNDER the review gates nothing, because that gate reads one level deep. Killing the review, or any finding, is the recorded waiver: deliberately ungated, and written to the status history with who did it and through which token. An epic that never opened a review still closes exactly as it did before.",
17140
+ // The WHOLE domain schema rather than its `.shape`, for `get_work_context`'s
17141
+ // reason: the exactly-one-of rule is a refinement on the OBJECT, and a raw
17142
+ // shape drops it — the refusal naming the two forms would never reach the
17143
+ // caller, and both arguments (or neither) would be accepted here.
17144
+ inputSchema: openReviewInputSchema
17145
+ }, (args) => run(() => client2.openReview(args)));
17112
17146
  registerTool("update_issue", {
17113
17147
  description: 'Update any subset of an issue\u2019s title, body, type, priority, milestone, environment, parent (self/cycle rejected), requirement_links (add/remove; adding a link to an unapproved requirement is rejected), deliverable_links (add/remove content-deliverable links, add pins at the current revision), or decision_links (add/remove decision records this work sits under \u2014 `KEY-D{n}`, from `list_decisions`). Changing type to `feedback` is rejected while the issue has criteria (\xA77), since feedback carries none; epic, task and bug interchange freely and the criteria ride along, keeping their AC-{n} numbers and their states. Clearing `milestone` (passing null) is rejected while the issue sits past `triage` \u2014 work already scheduled keeps a milestone (PIPE-R10 rule 9); swap it for a different one, or move the issue back to `triage` first. Cite the decision record a piece of work implements rather than restating what was decided in its body: the record is where the reasoning stays correct, and a body repeating it goes stale the moment the decision is superseded. Link another record by key plus title on first mention; never paste its text into a body \u2014 the source changes, the copy does not, and a stale copy gets built. A decision you need from the operator is filed as a question via `ask_questions`, never written as an "Open questions" heading inside a body \u2014 a heading prompts nobody and records no answer, so a later session cannot tell whether the decision was made. Cross-cutting requirements bind every epic automatically and arrive with `get_issue` \u2014 never restate them in a body and never add them to `requirement_links`; an explicit link pins the linked document\u2019s approved revision.',
17114
17148
  inputSchema: updateIssueInputSchema.shape
@@ -17425,7 +17459,7 @@ function loadMcpConfig() {
17425
17459
  }
17426
17460
 
17427
17461
  // src/version.ts
17428
- var VERSION = "0.25.0";
17462
+ var VERSION = "0.27.0";
17429
17463
 
17430
17464
  // src/main.ts
17431
17465
  var config2 = loadMcpConfig();
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "pipebrain-mcp",
3
- "version": "0.25.0",
3
+ "version": "0.27.0",
4
4
  "description": "Pipebrain MCP server for Claude Code and Claude Desktop — issues, requirements, content, assets, and metadata-only secrets over the Pipebrain API.",
5
5
  "type": "module",
6
6
  "license": "MIT",