pipebrain-mcp 0.36.0 → 0.37.1

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 +119 -2
  2. package/package.json +1 -1
package/dist/main.js CHANGED
@@ -15104,6 +15104,9 @@ var requirementRefSchema = external_exports.string().min(1, {
15104
15104
  var conventionRefSchema = external_exports.string().min(1, {
15105
15105
  message: "convention reference must not be empty \u2014 use a display id (`CONV-3`) or uuid"
15106
15106
  });
15107
+ var promptRefSchema = external_exports.string().min(1, {
15108
+ message: "prompt reference must not be empty \u2014 use a display id (`PROMPT-3`) or uuid"
15109
+ });
15107
15110
  var decisionRefSchema = external_exports.string().min(1, {
15108
15111
  message: "decision reference must not be empty \u2014 use a display id (`DWB-D7`) or uuid"
15109
15112
  });
@@ -15445,6 +15448,29 @@ var conventionApprovalSchema = external_exports.object({
15445
15448
  supersededId: uuidSchema.nullable(),
15446
15449
  createdAt: external_exports.iso.datetime({ offset: true })
15447
15450
  });
15451
+ var promptSchema = external_exports.object({
15452
+ id: uuidSchema,
15453
+ displayId: external_exports.string().min(1),
15454
+ orgId: uuidSchema,
15455
+ number: positiveIntSchema,
15456
+ projectId: uuidSchema.nullable(),
15457
+ createdBy: uuidSchema.nullable(),
15458
+ createdAt: external_exports.iso.datetime({ offset: true }),
15459
+ updatedAt: external_exports.iso.datetime({ offset: true }),
15460
+ deletedAt: external_exports.iso.datetime({ offset: true }).nullable()
15461
+ });
15462
+ var promptRevisionSchema = external_exports.object({
15463
+ id: uuidSchema,
15464
+ orgId: uuidSchema,
15465
+ promptId: uuidSchema,
15466
+ revisionNumber: positiveIntSchema,
15467
+ title: external_exports.string().min(1),
15468
+ body: markdownSchema,
15469
+ note: external_exports.string().nullable(),
15470
+ createdBy: uuidSchema.nullable(),
15471
+ viaTokenId: uuidSchema.nullable(),
15472
+ createdAt: external_exports.iso.datetime({ offset: true })
15473
+ });
15448
15474
  var issueRequirementLinkSchema = external_exports.object({
15449
15475
  id: uuidSchema,
15450
15476
  orgId: uuidSchema,
@@ -15909,6 +15935,32 @@ var updateConventionInputSchema = external_exports.strictObject({
15909
15935
  var listConventionsFilterSchema = external_exports.strictObject({
15910
15936
  text: external_exports.string().optional()
15911
15937
  });
15938
+ var createPromptInputSchema = external_exports.strictObject({
15939
+ title: external_exports.string().min(1, { message: "prompt title must not be empty" }),
15940
+ body: markdownSchema.min(1, { message: "prompt body must not be empty" }),
15941
+ note: external_exports.string().min(1, { message: "note must not be empty \u2014 omit it if there is nothing to record" }).optional(),
15942
+ // The OPTIONAL project attachment. Omitted = a prompt that belongs to the organisation
15943
+ // and no project, which is the common case for a prompt about how to work.
15944
+ project: projectRefSchema.optional()
15945
+ });
15946
+ var updatePromptInputSchema = external_exports.strictObject({
15947
+ prompt: promptRefSchema,
15948
+ title: external_exports.string().min(1, { message: "prompt title must not be empty" }).optional(),
15949
+ body: markdownSchema.min(1, { message: "prompt body must not be empty" }).optional(),
15950
+ note: external_exports.string().min(1, { message: "note must not be empty \u2014 omit it if there is nothing to record" }).optional(),
15951
+ // `null` DETACHES the prompt from its project; omitted leaves the attachment alone.
15952
+ // Moving the attachment is a record-level change and writes NO revision — the
15953
+ // revision chain is the history of the text, and a project move changes no text.
15954
+ project: projectRefSchema.nullable().optional()
15955
+ }).refine((v) => v.title !== void 0 || v.body !== void 0 || v.project !== void 0, {
15956
+ message: "empty edit: supply at least one of `title`, `body`, or `project`"
15957
+ });
15958
+ var listPromptsFilterSchema = external_exports.strictObject({
15959
+ // Filters to prompts attached to this project. Omitted returns EVERY prompt in the
15960
+ // organisation, attached or not — the org-wide library is the default view.
15961
+ project: projectRefSchema.optional(),
15962
+ text: external_exports.string().optional()
15963
+ });
15912
15964
  var createDecisionInputSchema = external_exports.strictObject({
15913
15965
  project: projectRefSchema,
15914
15966
  title: external_exports.string().min(1, { message: "decision title must not be empty" }),
@@ -16517,6 +16569,44 @@ var ApiClient = class _ApiClient {
16517
16569
  body: fields
16518
16570
  });
16519
16571
  }
16572
+ // --- prompts (PIPE-196) ----------------------------------------------------
16573
+ //
16574
+ // FOUR methods, and the absence of a fifth is the design here too: there is deliberately
16575
+ // NO `deletePrompt`, and there must not be one. Nothing removes a prompt on any surface
16576
+ // — an edit APPENDS a revision, so the text a prompt used to carry stays readable, and a
16577
+ // prompt nobody runs any more is one whose newest revision says so. There is no route
16578
+ // for such a method to call.
16579
+ /**
16580
+ * The whole organization's library, filtered by `project` and/or `text`.
16581
+ *
16582
+ * `requestList`, like every other list on this client, and NOT {@link listConventions}'s
16583
+ * named object: the convention response is a bespoke envelope because it carries the
16584
+ * delivered count and the threshold that warns about it beside the list — every approved
16585
+ * convention rides along on every work-item read. A prompt is delivered to nobody
16586
+ * automatically, so there is no second number to carry and the plain §9 `{ items }`
16587
+ * envelope is the whole shape. Going through `requestList` is what turns a proxy's
16588
+ * malformed 2xx into a typed `invalid_response` here rather than an opaque TypeError at
16589
+ * whichever caller first maps the result.
16590
+ */
16591
+ listPrompts(filter = {}) {
16592
+ return this.requestList("GET", "/api/v1/prompts", { query: filter });
16593
+ }
16594
+ getPrompt(ref) {
16595
+ return this.request("GET", `/api/v1/prompts/${enc(ref)}`);
16596
+ }
16597
+ createPrompt(input) {
16598
+ return this.request("POST", "/api/v1/prompts", { body: input });
16599
+ }
16600
+ /**
16601
+ * `title`/`body` APPEND a revision; `note` records why. Supplying none of the three
16602
+ * editable fields is an empty edit, refused by the API (400) — a note alone amends
16603
+ * nothing.
16604
+ */
16605
+ updatePrompt(ref, fields) {
16606
+ return this.request("PATCH", `/api/v1/prompts/${enc(ref)}`, {
16607
+ body: fields
16608
+ });
16609
+ }
16520
16610
  // --- decision records (PIPE-84) --------------------------------------------
16521
16611
  //
16522
16612
  // Five routes, no DELETE: PIPE-73 made four record kinds deletable and this epic
@@ -17358,7 +17448,7 @@ function createMcpServer(client2, apiBaseUrl, orgInstructions2 = /* @__PURE__ */
17358
17448
  inputSchema: createIssueInputSchema.shape
17359
17449
  }, (args) => run(() => client2.createIssue(args)));
17360
17450
  server2.registerTool("promote_feedback", {
17361
- description: "Promote a FEEDBACK issue into a NEW epic or task (PIPE-143): creates the issue in the feedback\u2019s project (`title` + `type` required; omitted environment inherits the FEEDBACK\u2019s environment, not the project default; optional status/body/priority/milestone/requirement_links/criteria as in create_issue), records the feedback as its permanent source (`promotedFrom`/`promotedTo` on both details), closes the feedback as done, and comments the new key on it. The feedback\u2019s own title/body are never touched \u2014 write the new issue\u2019s body as real work. Rejected (409) for non-feedback, terminal, or already-promoted sources. Returns the created issue. A `status` other than `triage` or `killed` REQUIRES `milestone` (PIPE-R10 rule 9), exactly as in create_issue; the SOURCE feedback needs none to be closed by the promotion. A `manual` criterion must carry `howTo` \u2014 one or two sentences saying where to look, what to do, and what counts as passing; writing or changing one without it is refused (`how_to_required`), and 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 alike \u2014 with feedback the one exception, refused with `criteria_not_supported` because it is a report rather than agreed work; this tool is what retypes it into work before anything is built. Writing guidance for this tool lives in the product doctrine, which `get_work_context` returns \u2014 see \u201CSearch before you create\u201D and \u201CThe bar for filing a bug\u201D.",
17451
+ description: "Promote a FEEDBACK issue into a NEW epic or task (PIPE-143): creates the issue in the feedback\u2019s project (`title` + `type` required; omitted environment inherits the FEEDBACK\u2019s environment, not the project default; optional status/body/priority/milestone/requirement_links/criteria as in create_issue), records the feedback as its permanent source (`promotedFrom`/`promotedTo` on both details), closes the feedback as done, and comments the new key on it. The feedback\u2019s own title/body are never touched \u2014 write the new issue\u2019s body as real work. Rejected (409) for non-feedback, terminal, or already-promoted sources, and refused (422 `status_guard`, naming each offending child and its status) when the feedback carries a child issue that is not yet `done` or `killed` \u2014 closing the source would strand that child under a finished parent, so finish or kill the child first. Returns the created issue. A `status` other than `triage` or `killed` REQUIRES `milestone` (PIPE-R10 rule 9), exactly as in create_issue; the SOURCE feedback needs none to be closed by the promotion. A `manual` criterion must carry `howTo` \u2014 one or two sentences saying where to look, what to do, and what counts as passing; writing or changing one without it is refused (`how_to_required`), and 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 alike \u2014 with feedback the one exception, refused with `criteria_not_supported` because it is a report rather than agreed work; this tool is what retypes it into work before anything is built. Writing guidance for this tool lives in the product doctrine, which `get_work_context` returns \u2014 see \u201CSearch before you create\u201D and \u201CThe bar for filing a bug\u201D.",
17362
17452
  inputSchema: {
17363
17453
  issue: external_exports.string().min(1),
17364
17454
  ...promoteFeedbackInputSchema.shape
@@ -17506,6 +17596,33 @@ function createMcpServer(client2, apiBaseUrl, orgInstructions2 = /* @__PURE__ */
17506
17596
  note: external_exports.string().min(1).optional()
17507
17597
  }
17508
17598
  }, ({ convention, ...fields }) => run(() => client2.updateConvention(convention, fields)));
17599
+ server2.registerTool("list_prompts", {
17600
+ description: "List this organization\u2019s prompt library \u2014 reusable prompt text, addressed `PROMPT-{n}`. A prompt belongs to the ORGANIZATION rather than to a project, unlike a requirement or a content draft, so with no filter this returns the whole library. Returns display id, title, the current text, the latest revision number, and the attached project when it has one. `project` narrows to the prompts attached to that project \u2014 that attachment is metadata saying what a prompt is ABOUT, never its scope, so a prompt attached elsewhere is still one you may read and run. `text` matches over TITLE AND BODY, because someone looking for a prompt remembers what it says rather than what somebody called it.",
17601
+ inputSchema: listPromptsFilterSchema.shape
17602
+ }, (args) => run(() => client2.listPrompts(args), GUIDANCE_POINTER));
17603
+ server2.registerTool("get_prompt", {
17604
+ description: "Get one prompt by display id (`PROMPT-{n}`) or uuid: its current text \u2014 the LATEST revision, which is simply the prompt, since nothing approves a prompt and nothing pins to an older wording \u2014 plus the full revision history with who wrote each save, through which token, when, and the note saying why. Nothing here was edited in place, so a wording that has been replaced is still readable rather than lost; read the history before rewriting a prompt that already works.",
17605
+ inputSchema: { prompt: promptRefSchema }
17606
+ }, (args) => run(() => client2.getPrompt(args.prompt), GUIDANCE_POINTER));
17607
+ server2.registerTool("create_prompt", {
17608
+ description: "Write a prompt: reusable prompt text kept ORGANIZATION-WIDE (`PROMPT-{n}`) and available in every project here \u2014 unlike a requirement or a content draft, which belong to the one project they are filed under. `body` is the prompt itself and must not be empty; `title` names it; optional `note` records why it was written. Optional `project` ATTACHES the prompt to a project, which says what it is about and nothing more \u2014 the prompt is still the organization\u2019s, and a prompt about no project in particular simply omits it. There is no approval step: it is usable the moment it is written. Nothing deletes a prompt either \u2014 later wording is added as a revision, so what is here now stays readable. Writing guidance for this tool lives in the product doctrine, which `get_work_context` returns \u2014 see \u201CSearch before you create\u201D.",
17609
+ inputSchema: createPromptInputSchema.shape
17610
+ }, (args) => run(() => client2.createPrompt(args)));
17611
+ server2.registerTool("update_prompt", {
17612
+ description: "Amend a prompt: `title` and/or `body` APPEND a new revision \u2014 nothing is ever edited in place \u2014 and optional `note` records why. Amending is therefore safe rather than destructive: the earlier text stays readable, the revision chain is the record of how this prompt got to where it is, and the new wording answers immediately because there is nothing to approve. `project` moves the attachment and `project: null` DETACHES it, leaving a prompt the whole organization still has; either way NO revision is written, because the revision chain is the history of the TEXT and moving the attachment changes no text. Supplying none of `title`, `body` or `project` is an empty edit (400) \u2014 a note alone amends nothing.",
17613
+ // Inline shape (updatePromptInputSchema is a refine, so it has no `.shape`),
17614
+ // mirroring that schema's fields — it is the wording this copy follows, `.min(1)`
17615
+ // bounds included, so a caller learns a blank body is refused from the advertised
17616
+ // schema rather than from a round trip. The ONE rule this shape cannot state is the
17617
+ // empty edit, which lives in the schema's `.refine`; the API enforces it.
17618
+ inputSchema: {
17619
+ prompt: promptRefSchema,
17620
+ title: external_exports.string().min(1).optional(),
17621
+ body: markdownSchema.min(1).optional(),
17622
+ note: external_exports.string().min(1).optional(),
17623
+ project: projectRefSchema.nullable().optional()
17624
+ }
17625
+ }, ({ prompt, ...fields }) => run(() => client2.updatePrompt(prompt, fields)));
17509
17626
  server2.registerTool("create_decision", {
17510
17627
  description: "Record ONE decision as a project-scoped decision record (`KEY-D{n}`): `title` names the decision and `body` says what was decided and why. A new record starts `proposed`; moving it to `accepted` IS the acceptance \u2014 there is no separate approval step. Returns the created record. Title and body can be corrected only while the record is `proposed`; from `accepted` onward it is frozen, and the way to change a decision is to write a NEW record and `supersede_decision` the old one \u2014 which leaves the original readable and says where the current decision went. Nothing on any surface deletes one. Writing guidance for this tool lives in the product doctrine, which `get_work_context` returns \u2014 see \u201CA decision record is written once\u201D and \u201CSearch before you create\u201D.",
17511
17628
  inputSchema: createDecisionInputSchema.shape
@@ -17716,7 +17833,7 @@ function loadMcpConfig() {
17716
17833
  }
17717
17834
 
17718
17835
  // src/version.ts
17719
- var VERSION = "0.36.0";
17836
+ var VERSION = "0.37.1";
17720
17837
 
17721
17838
  // src/main.ts
17722
17839
  var config2 = loadMcpConfig();
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "pipebrain-mcp",
3
- "version": "0.36.0",
3
+ "version": "0.37.1",
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",