@neturely/okffs 0.7.0 → 0.9.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 (66) hide show
  1. package/CHANGELOG.md +19 -1
  2. package/README.md +15 -2
  3. package/dist/cli/banner.d.ts +17 -0
  4. package/dist/cli/banner.d.ts.map +1 -0
  5. package/dist/cli/banner.js +65 -0
  6. package/dist/cli/banner.js.map +1 -0
  7. package/dist/cli/env.d.ts +30 -0
  8. package/dist/cli/env.d.ts.map +1 -0
  9. package/dist/cli/env.js +171 -0
  10. package/dist/cli/env.js.map +1 -0
  11. package/dist/cli/index.d.ts +12 -0
  12. package/dist/cli/index.d.ts.map +1 -0
  13. package/dist/cli/index.js +77 -0
  14. package/dist/cli/index.js.map +1 -0
  15. package/dist/cli/manifest.d.ts +48 -0
  16. package/dist/cli/manifest.d.ts.map +1 -0
  17. package/dist/cli/manifest.js +303 -0
  18. package/dist/cli/manifest.js.map +1 -0
  19. package/dist/cli/probe.d.ts +32 -0
  20. package/dist/cli/probe.d.ts.map +1 -0
  21. package/dist/cli/probe.js +101 -0
  22. package/dist/cli/probe.js.map +1 -0
  23. package/dist/cli/sanity.d.ts +16 -0
  24. package/dist/cli/sanity.d.ts.map +1 -0
  25. package/dist/cli/sanity.js +99 -0
  26. package/dist/cli/sanity.js.map +1 -0
  27. package/dist/cli/setup.d.ts +2 -0
  28. package/dist/cli/setup.d.ts.map +1 -0
  29. package/dist/cli/setup.js +254 -0
  30. package/dist/cli/setup.js.map +1 -0
  31. package/dist/github.d.ts.map +1 -1
  32. package/dist/github.js +4 -2
  33. package/dist/github.js.map +1 -1
  34. package/dist/index.d.ts.map +1 -1
  35. package/dist/index.js +19 -105
  36. package/dist/index.js.map +1 -1
  37. package/dist/prompts/setup.d.ts +18 -0
  38. package/dist/prompts/setup.d.ts.map +1 -0
  39. package/dist/prompts/setup.js +77 -0
  40. package/dist/prompts/setup.js.map +1 -0
  41. package/dist/server.d.ts +2 -0
  42. package/dist/server.d.ts.map +1 -0
  43. package/dist/server.js +166 -0
  44. package/dist/server.js.map +1 -0
  45. package/dist/tools/commit_and_update.d.ts +19 -0
  46. package/dist/tools/commit_and_update.d.ts.map +1 -1
  47. package/dist/tools/commit_and_update.js +59 -6
  48. package/dist/tools/commit_and_update.js.map +1 -1
  49. package/dist/tools/configure.d.ts +27 -0
  50. package/dist/tools/configure.d.ts.map +1 -0
  51. package/dist/tools/configure.js +91 -0
  52. package/dist/tools/configure.js.map +1 -0
  53. package/dist/tools/fix_into_base.d.ts +23 -0
  54. package/dist/tools/fix_into_base.d.ts.map +1 -0
  55. package/dist/tools/fix_into_base.js +110 -0
  56. package/dist/tools/fix_into_base.js.map +1 -0
  57. package/dist/tools/merge_pull_request.d.ts +6 -3
  58. package/dist/tools/merge_pull_request.d.ts.map +1 -1
  59. package/dist/tools/merge_pull_request.js +52 -18
  60. package/dist/tools/merge_pull_request.js.map +1 -1
  61. package/dist/tools/reply_to_review_comment.d.ts +4 -1
  62. package/dist/tools/reply_to_review_comment.d.ts.map +1 -1
  63. package/dist/tools/reply_to_review_comment.js +39 -10
  64. package/dist/tools/reply_to_review_comment.js.map +1 -1
  65. package/dist/tools/update_project_status.d.ts +2 -2
  66. package/package.json +6 -2
@@ -0,0 +1,77 @@
1
+ import { SECTIONS } from "../cli/manifest.js";
2
+ export const name = "setup";
3
+ export const description = "Configure okffs for this repo conversationally, right here in the chat — the in-Claude-Code counterpart to the `okffs setup` CLI wizard. Interviews you for the settings that apply, then writes them to .env via the `configure` tool (preserving your own variables and comments).";
4
+ export const argumentDefs = [
5
+ {
6
+ name: "mode",
7
+ description: "Optional: 'quick' (auth + repo + base branch only), 'full' (every section), or 'sync' (only options not yet configured). Defaults to sync when a .env exists, else asks.",
8
+ required: false,
9
+ },
10
+ ];
11
+ // Render the manifest into a compact reference the model can drive the interview
12
+ // from, so the prompt is self-contained (no need to also expose the manifest as a
13
+ // resource). Mirrors how create_issue injects the board's real options.
14
+ function renderReference() {
15
+ const lines = [];
16
+ for (const s of SECTIONS) {
17
+ const gate = !s.gated
18
+ ? "always ask"
19
+ : s.gateKey
20
+ ? `gated — ask "${s.gatePrompt}" and record the answer as ${s.gateKey}=true/false`
21
+ : `gated — ask "${s.gatePrompt}"; if declined, mark its vars declined`;
22
+ const cond = s.onlyIf ? " [only if a protected branch is set]" : "";
23
+ lines.push(`\n### ${s.title} (${gate})${cond}`);
24
+ for (const v of s.vars) {
25
+ const opts = v.options ? ` options: ${v.options.map((o) => o || "(unset)").join("/")};` : "";
26
+ const def = v.default ? ` default: ${v.default};` : "";
27
+ lines.push(`- \`${v.key}\` (${v.kind});${opts}${def} ${v.description}`);
28
+ }
29
+ }
30
+ return lines.join("\n");
31
+ }
32
+ export function build(args) {
33
+ const mode = args.mode?.trim().toLowerCase();
34
+ const text = [
35
+ `Configure okffs for THIS repository by talking with the user, then persist the result by calling the \`configure\` tool. Do not edit .env yourself — \`configure\` owns the write (it preserves the user's own variables and comments, touching only okffs's marked block).`,
36
+ ``,
37
+ `## 1. Assess current state`,
38
+ `- Read \`./.env\` in the current working directory if it exists (use your file-reading tool). Note which \`GITHUB_*\`/\`OKFFS_*\` variables are already set, and look for the \`# okffs:configured-version=…\` stamp.`,
39
+ `- **Never print or echo the value of GITHUB_TOKEN** (or any secret). Acknowledge it's set without showing it.`,
40
+ ``,
41
+ `## 2. Choose breadth`,
42
+ mode
43
+ ? `- The user requested **${mode}** mode.`
44
+ : `- No .env yet → ask the user: **Quick** (auth, repo, base branch only) or **Full** (every section). A .env already exists → default to **sync**: only ask about variables that are not yet set. Offer "reconfigure everything" if they want a full pass.`,
45
+ `- In sync/upgrade situations, only ask about variables that are missing — leave already-configured values alone unless the user asks to change them.`,
46
+ ``,
47
+ `## 3. Interview`,
48
+ `- Go section by section using the reference below. For a **gated** section, ask its single gate question first; if the user declines, skip the whole group (and include those vars in \`declined\`).`,
49
+ `- For each variable: show already-set values (mask the token) with a keep/change choice; for unset ones, give the short description and default and let the user set or skip.`,
50
+ `- For \`GITHUB_TOKEN\`: mention they can leave it blank to use the GitHub CLI (\`gh auth token\`), and share the fine-grained PAT URL from the reference. Let them paste a token OR choose the gh fallback — don't force it.`,
51
+ `- Keep it brief and batch related questions; don't interrogate one variable at a time when a section can be covered together.`,
52
+ ``,
53
+ `## 4. Persist`,
54
+ `- Call \`configure\` once with:`,
55
+ ` - \`set\`: a map of every variable the user gave a value for (booleans as "true"/"false").`,
56
+ ` - \`declined\`: every OPTIONAL variable the user explicitly skipped (so a later sync won't re-ask it). Don't list variables you never brought up.`,
57
+ `- Then relay \`configure\`'s summary and remind the user to **restart the MCP server / Claude Code** so okffs re-reads .env.`,
58
+ ``,
59
+ `## 5. Notes`,
60
+ `- Booleans that default on (inference/metadata) should stay on unless the user wants them off.`,
61
+ `- If the user wants \`OKFFS_AUTO_MERGE_BASE=true\`, confirm \`OKFFS_PROTECTED_BRANCH\` is also set — the merge tool refuses without it.`,
62
+ `- The Projects and promotion sections only matter if the user uses a GitHub Projects board / a protected-branch promotion flow; it's fine to skip them.`,
63
+ ``,
64
+ `## Variable reference`,
65
+ renderReference(),
66
+ ].join("\n");
67
+ return {
68
+ description: "Configure okffs for this repo conversationally, then persist via the configure tool",
69
+ messages: [
70
+ {
71
+ role: "user",
72
+ content: { type: "text", text },
73
+ },
74
+ ],
75
+ };
76
+ }
77
+ //# sourceMappingURL=setup.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"setup.js","sourceRoot":"","sources":["../../src/prompts/setup.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,QAAQ,EAAE,MAAM,oBAAoB,CAAC;AAE9C,MAAM,CAAC,MAAM,IAAI,GAAG,OAAO,CAAC;AAE5B,MAAM,CAAC,MAAM,WAAW,GACtB,sRAAsR,CAAC;AAEzR,MAAM,CAAC,MAAM,YAAY,GAAG;IAC1B;QACE,IAAI,EAAE,MAAM;QACZ,WAAW,EAAE,0KAA0K;QACvL,QAAQ,EAAE,KAAK;KAChB;CACF,CAAC;AAEF,iFAAiF;AACjF,kFAAkF;AAClF,wEAAwE;AACxE,SAAS,eAAe;IACtB,MAAM,KAAK,GAAa,EAAE,CAAC;IAC3B,KAAK,MAAM,CAAC,IAAI,QAAQ,EAAE,CAAC;QACzB,MAAM,IAAI,GAAG,CAAC,CAAC,CAAC,KAAK;YACnB,CAAC,CAAC,YAAY;YACd,CAAC,CAAC,CAAC,CAAC,OAAO;gBACT,CAAC,CAAC,gBAAgB,CAAC,CAAC,UAAU,8BAA8B,CAAC,CAAC,OAAO,aAAa;gBAClF,CAAC,CAAC,gBAAgB,CAAC,CAAC,UAAU,wCAAwC,CAAC;QAC3E,MAAM,IAAI,GAAG,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,sCAAsC,CAAC,CAAC,CAAC,EAAE,CAAC;QACpE,KAAK,CAAC,IAAI,CAAC,SAAS,CAAC,CAAC,KAAK,KAAK,IAAI,IAAI,IAAI,EAAE,CAAC,CAAC;QAChD,KAAK,MAAM,CAAC,IAAI,CAAC,CAAC,IAAI,EAAE,CAAC;YACvB,MAAM,IAAI,GAAG,CAAC,CAAC,OAAO,CAAC,CAAC,CAAC,aAAa,CAAC,CAAC,OAAO,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,IAAI,SAAS,CAAC,CAAC,IAAI,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,CAAC;YAC7F,MAAM,GAAG,GAAG,CAAC,CAAC,OAAO,CAAC,CAAC,CAAC,aAAa,CAAC,CAAC,OAAO,GAAG,CAAC,CAAC,CAAC,EAAE,CAAC;YACvD,KAAK,CAAC,IAAI,CAAC,OAAO,CAAC,CAAC,GAAG,OAAO,CAAC,CAAC,IAAI,KAAK,IAAI,GAAG,GAAG,IAAI,CAAC,CAAC,WAAW,EAAE,CAAC,CAAC;QAC1E,CAAC;IACH,CAAC;IACD,OAAO,KAAK,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;AAC1B,CAAC;AAED,MAAM,UAAU,KAAK,CAAC,IAAwC;IAC5D,MAAM,IAAI,GAAG,IAAI,CAAC,IAAI,EAAE,IAAI,EAAE,CAAC,WAAW,EAAE,CAAC;IAE7C,MAAM,IAAI,GAAG;QACX,6QAA6Q;QAC7Q,EAAE;QACF,4BAA4B;QAC5B,uNAAuN;QACvN,+GAA+G;QAC/G,EAAE;QACF,sBAAsB;QACtB,IAAI;YACF,CAAC,CAAC,0BAA0B,IAAI,UAAU;YAC1C,CAAC,CAAC,0PAA0P;QAC9P,sJAAsJ;QACtJ,EAAE;QACF,iBAAiB;QACjB,sMAAsM;QACtM,+KAA+K;QAC/K,8NAA8N;QAC9N,+HAA+H;QAC/H,EAAE;QACF,eAAe;QACf,iCAAiC;QACjC,8FAA8F;QAC9F,qJAAqJ;QACrJ,8HAA8H;QAC9H,EAAE;QACF,aAAa;QACb,gGAAgG;QAChG,yIAAyI;QACzI,yJAAyJ;QACzJ,EAAE;QACF,uBAAuB;QACvB,eAAe,EAAE;KAClB,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;IAEb,OAAO;QACL,WAAW,EAAE,qFAAqF;QAClG,QAAQ,EAAE;YACR;gBACE,IAAI,EAAE,MAAe;gBACrB,OAAO,EAAE,EAAE,IAAI,EAAE,MAAe,EAAE,IAAI,EAAE;aACzC;SACF;KACF,CAAC;AACJ,CAAC"}
@@ -0,0 +1,2 @@
1
+ export declare function startServer(): Promise<void>;
2
+ //# sourceMappingURL=server.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"server.d.ts","sourceRoot":"","sources":["../src/server.ts"],"names":[],"mappings":"AAgIA,wBAAsB,WAAW,IAAI,OAAO,CAAC,IAAI,CAAC,CAyDjD"}
package/dist/server.js ADDED
@@ -0,0 +1,166 @@
1
+ // The MCP server. Split out of index.ts so the CLI entrypoint can dispatch
2
+ // `okffs setup` WITHOUT importing this file — importing it pulls in the tool
3
+ // chain (→ github.ts), which resolves the token/owner/repo at import time and
4
+ // throws when unconfigured, which is exactly the state `okffs setup` runs in.
5
+ // index.ts only dynamically imports this module for a bare (no-arg) invocation,
6
+ // so the MCP server's behaviour is unchanged.
7
+ import { readFileSync } from "node:fs";
8
+ import { join } from "node:path";
9
+ import { Server } from "@modelcontextprotocol/sdk/server/index.js";
10
+ import { StdioServerTransport } from "@modelcontextprotocol/sdk/server/stdio.js";
11
+ import { CallToolRequestSchema, ListToolsRequestSchema, ListPromptsRequestSchema, GetPromptRequestSchema, } from "@modelcontextprotocol/sdk/types.js";
12
+ import { zodToJsonSchema } from "zod-to-json-schema";
13
+ import * as createIssue from "./tools/create_issue.js";
14
+ import * as listIssues from "./tools/list_issues.js";
15
+ import * as closeIssue from "./tools/close_issue.js";
16
+ import * as deleteIssue from "./tools/delete_issue.js";
17
+ import * as deleteBranch from "./tools/delete_branch.js";
18
+ import * as getIssue from "./tools/get_issue.js";
19
+ import * as commentIssue from "./tools/comment_issue.js";
20
+ import * as createIssuesFromList from "./tools/create_issues_from_list.js";
21
+ import * as plan from "./tools/plan.js";
22
+ import * as linkIssues from "./tools/link_issues.js";
23
+ import * as createPullRequest from "./tools/create_pull_request.js";
24
+ import * as commitAndUpdate from "./tools/commit_and_update.js";
25
+ import * as listPrReviewComments from "./tools/list_pr_review_comments.js";
26
+ import * as replyToReviewComment from "./tools/reply_to_review_comment.js";
27
+ import * as resolveReviewThread from "./tools/resolve_review_thread.js";
28
+ import * as prepareRelease from "./tools/prepare_release.js";
29
+ import * as updateProjectStatus from "./tools/update_project_status.js";
30
+ import * as setIssueFields from "./tools/set_issue_fields.js";
31
+ import * as updateIssue from "./tools/update_issue.js";
32
+ import * as promoteBranch from "./tools/promote_branch.js";
33
+ import * as mergePullRequest from "./tools/merge_pull_request.js";
34
+ import * as fixIntoBase from "./tools/fix_into_base.js";
35
+ import * as configure from "./tools/configure.js";
36
+ import * as addressPrReview from "./prompts/address_pr_review.js";
37
+ import * as updateGuidance from "./prompts/update_guidance.js";
38
+ import * as setupPrompt from "./prompts/setup.js";
39
+ import { parseEnv } from "./cli/env.js";
40
+ import { allKeys } from "./cli/manifest.js";
41
+ const tools = [createIssue, listIssues, closeIssue, deleteIssue, deleteBranch, getIssue, commentIssue, createIssuesFromList, plan, linkIssues, createPullRequest, commitAndUpdate, listPrReviewComments, replyToReviewComment, resolveReviewThread, prepareRelease, updateProjectStatus, setIssueFields, updateIssue, promoteBranch, mergePullRequest, fixIntoBase, configure];
42
+ const prompts = [addressPrReview, updateGuidance, setupPrompt];
43
+ // Read the package version so the server reports the real version (dist/server.js
44
+ // lives one level below package.json in both dev and the published package).
45
+ const version = JSON.parse(readFileSync(new URL("../package.json", import.meta.url), "utf8")).version;
46
+ // Server-level instructions: the MCP `initialize` result carries this string and
47
+ // hosts (Claude Code, etc.) surface it to the agent every session. It ships with
48
+ // the package version, so upgrading okffs automatically updates the guidance the
49
+ // agent sees — this is how new tools/behaviour get adopted instead of the agent
50
+ // defaulting to raw git/gh (#169). Keep it tight: it's always-on context. This is
51
+ // the machine-visible counterpart to the human-facing README/CLAUDE.md guidance.
52
+ const SERVER_INSTRUCTIONS = `okffs owns the GitHub issue → branch → PR → merge → close workflow (plus, when enabled, a GitHub Projects v2 board and releases).
53
+
54
+ ALWAYS reach for an okffs tool before raw git/gh/GraphQL when one covers the action — this is a correctness rule, not a style preference:
55
+ - Identity/permissions: okffs authenticates with the configured GITHUB_TOKEN (a PAT scoped for this repo, incl. Projects / org Issue Fields when set). Raw gh/git uses whatever ambient CLI token is signed in — often the wrong identity or missing the Projects/org scopes, so it fails or acts as the wrong user.
56
+ - Conventions: okffs applies branch naming ({issue}-{slug}), the **Branch:** issue link, Closes #N, board placement, changelog fragments, and the OKFFS_PROTECTED_BRANCH invariant. Hand-rolled gh/git silently skips all of that.
57
+ Fall back to raw git/gh ONLY when no okffs tool fits the action.
58
+
59
+ Common action → tool:
60
+ - Start work: create_issue (creates the issue, the linked branch, and the **Branch:** line that create_pull_request/commit_and_update rely on). Many at once: create_issues_from_list or plan.
61
+ - Progress: commit_and_update (stage + commit + push + issue comment) — prefer over raw git commit/push.
62
+ - Open/finalize an issue's PR (into the base branch): create_pull_request (always adds Closes #N).
63
+ - Promotion/release gate — a base→protected PR with no issue, e.g. develop→main: promote_branch (issue-less; adds the PR to the board; NEVER use raw \`gh pr create\` for this).
64
+ - Edit an existing issue's core fields (title, assignees, labels, milestone, body): update_issue — prefer over raw \`gh issue edit\`. (Board Priority/Effort is set_issue_fields; Status column is update_project_status — those aren't issue fields.)
65
+ - Board: create_issue sets an inferred priority/effort at creation; set them on an EXISTING issue with set_issue_fields; move columns with update_project_status (Backlog/Ready/In Progress/Review — Done is GitHub's own automation).
66
+ - PR review: list_pr_review_comments → fix → reply_to_review_comment → resolve_review_thread (honours OKFFS_RESOLVE_THREADS); or the /okffs:address_pr_review prompt.
67
+ - Release prep: prepare_release (bumps version + rolls the changelog; does NOT tag or publish).
68
+ - Land an issue PR into the BASE branch (e.g. develop): merge_pull_request — the one okffs action that merges. Opt-in (OKFFS_AUTO_MERGE_BASE=true) and heavily gated; it verifies checks/threads itself and NEVER touches OKFFS_PROTECTED_BRANCH. Off by default → it just declines.
69
+ - Land an ISSUE-LESS fix into the BASE branch (no issue, e.g. review-comment cleanups): fix_into_base — the mirror of promote_branch. Opens (always safe) then merges under the same OKFFS_AUTO_MERGE_BASE gating as merge_pull_request. Prefer over raw \`gh pr create\`/\`gh pr merge\`; never targets OKFFS_PROTECTED_BRANCH.
70
+
71
+ Setup/config: if the user needs to configure okffs — a missing token/repo, or turning on a feature like Projects — offer the /okffs:setup prompt, which configures okffs conversationally right here in Claude Code (it interviews the user and persists via the configure tool, no terminal needed). The equivalent terminal wizard is \`npx @neturely/okffs setup\` — a guided CLI that writes/updates .env preserving the user's own vars and comments, but being interactive it must be run in their own terminal, not via a tool or the \`!\` shell.
72
+
73
+ Rules: never merge, tag, or publish into OKFFS_PROTECTED_BRANCH autonomously — okffs may OPEN a PR into it (promote_branch), but the merge/tag are yours to hand back for. merge_pull_request only ever lands PRs into the base tier, never the protected branch. Destructive tools (delete_issue, delete_branch) require confirmed: true (call once to preview, again to act).`;
74
+ // Compare two dotted versions; >0 if a is newer than b. Prerelease suffixes are
75
+ // ignored (split on `.`/`-`), which is fine for the coarse "did we upgrade?" check.
76
+ function isNewer(a, b) {
77
+ const pa = a.split(/[.-]/).map((n) => parseInt(n, 10) || 0);
78
+ const pb = b.split(/[.-]/).map((n) => parseInt(n, 10) || 0);
79
+ for (let i = 0; i < 3; i++) {
80
+ const d = (pa[i] || 0) - (pb[i] || 0);
81
+ if (d !== 0)
82
+ return d > 0;
83
+ }
84
+ return false;
85
+ }
86
+ // Upgrade nudge (#242): if this repo's .env was configured by an older okffs (or
87
+ // predates version stamping) AND this okffs version has config options not set
88
+ // here, append a one-time-per-session note so the agent can OFFER /okffs:setup.
89
+ // Gentle by construction — it lands in the always-on instructions read on connect,
90
+ // not a per-turn interruption, and self-resolves once the user runs setup (which
91
+ // stamps the current version and marks the new options known/declined).
92
+ function upgradeNudge() {
93
+ try {
94
+ const parsed = parseEnv(join(process.cwd(), ".env"));
95
+ if (!parsed.exists)
96
+ return "";
97
+ const stamp = parsed.configuredVersion;
98
+ const configuredCount = allKeys().filter((k) => parsed.known.has(k)).length;
99
+ // Only for repos that actually use okffs config (a stamp, or some okffs vars);
100
+ // don't pester a .env that just isn't an okffs-configured repo.
101
+ if (!stamp && configuredCount === 0)
102
+ return "";
103
+ // Only when this okffs is newer than what configured the .env (or the .env
104
+ // predates stamping — stamp === null).
105
+ if (stamp && !isNewer(version, stamp))
106
+ return "";
107
+ const newKeys = allKeys().filter((k) => !parsed.known.has(k));
108
+ if (newKeys.length === 0)
109
+ return "";
110
+ const from = stamp ? `from ${stamp} ` : "";
111
+ return `\n\nUPGRADE NUDGE: this repo's .env was configured ${from}with an older okffs; okffs ${version} has ${newKeys.length} config option(s) not set here. Once, offer to run the /okffs:setup prompt (sync) to review the new options — if the user declines, drop it, don't repeat.`;
112
+ }
113
+ catch {
114
+ return "";
115
+ }
116
+ }
117
+ export async function startServer() {
118
+ const server = new Server({ name: "okffs", version }, { capabilities: { tools: {}, prompts: {} }, instructions: SERVER_INSTRUCTIONS + upgradeNudge() });
119
+ server.setRequestHandler(ListToolsRequestSchema, async () => ({
120
+ // A tool may export an async getDescription() to compute its description at
121
+ // list time (e.g. create_issue injects the board's real Priority/Effort options
122
+ // — #133). Fall back to the static description on absence or failure.
123
+ tools: await Promise.all(tools.map(async (t) => {
124
+ let description = t.description;
125
+ const getDescription = t.getDescription;
126
+ if (getDescription) {
127
+ try {
128
+ description = await getDescription();
129
+ }
130
+ catch (err) {
131
+ console.warn(`[okffs] getDescription() failed for ${t.name}, using static description:`, err instanceof Error ? err.message : err);
132
+ }
133
+ }
134
+ return {
135
+ name: t.name,
136
+ description,
137
+ inputSchema: zodToJsonSchema(t.inputSchema),
138
+ };
139
+ })),
140
+ }));
141
+ server.setRequestHandler(CallToolRequestSchema, async (req) => {
142
+ const tool = tools.find((t) => t.name === req.params.name);
143
+ if (!tool) {
144
+ throw new Error(`Unknown tool: ${req.params.name}`);
145
+ }
146
+ const input = tool.inputSchema.parse(req.params.arguments);
147
+ return tool.handler(input);
148
+ });
149
+ server.setRequestHandler(ListPromptsRequestSchema, async () => ({
150
+ prompts: prompts.map((p) => ({
151
+ name: p.name,
152
+ description: p.description,
153
+ arguments: p.argumentDefs,
154
+ })),
155
+ }));
156
+ server.setRequestHandler(GetPromptRequestSchema, async (req) => {
157
+ const prompt = prompts.find((p) => p.name === req.params.name);
158
+ if (!prompt) {
159
+ throw new Error(`Unknown prompt: ${req.params.name}`);
160
+ }
161
+ return prompt.build(req.params.arguments ?? {});
162
+ });
163
+ const transport = new StdioServerTransport();
164
+ await server.connect(transport);
165
+ }
166
+ //# sourceMappingURL=server.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"server.js","sourceRoot":"","sources":["../src/server.ts"],"names":[],"mappings":"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"}
@@ -11,6 +11,25 @@ export declare const inputSchema: z.ZodObject<{
11
11
  issue_number: number;
12
12
  hint?: string | undefined;
13
13
  }>;
14
+ /**
15
+ * Split a free-text hint into a git commit subject + optional body.
16
+ *
17
+ * - Subject: the first **non-blank** line, truncated to ~72 chars at a **word
18
+ * boundary** (never mid-word) — a single unbreakable word longer than the
19
+ * limit is the only case that gets a hard cut. Leading blank lines are skipped
20
+ * so a hint like "\nAdd X" doesn't produce an empty subject (#236).
21
+ * - Body: any lines after the subject line, plus whatever overflowed past the
22
+ * subject, joined as blank-line-separated paragraphs. `undefined` when the
23
+ * hint fits entirely in the subject, so a short single-line hint behaves
24
+ * exactly as before (subject only). (#228)
25
+ *
26
+ * A whitespace-only hint has no usable subject line and returns `{ subject: "" }`
27
+ * — the handler guards against that by treating a blank hint as absent (#236).
28
+ */
29
+ export declare function splitCommitMessage(hint: string): {
30
+ subject: string;
31
+ body?: string;
32
+ };
14
33
  export declare function handler(input: z.infer<typeof inputSchema>): Promise<{
15
34
  content: {
16
35
  type: "text";
@@ -1 +1 @@
1
- {"version":3,"file":"commit_and_update.d.ts","sourceRoot":"","sources":["../../src/tools/commit_and_update.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;AAIxB,eAAO,MAAM,IAAI,sBAAsB,CAAC;AACxC,eAAO,MAAM,WAAW,yLACgK,CAAC;AAEzL,eAAO,MAAM,WAAW;;;;;;;;;EAGtB,CAAC;AAEH,wBAAsB,OAAO,CAAC,KAAK,EAAE,CAAC,CAAC,KAAK,CAAC,OAAO,WAAW,CAAC;;;;;GAyE/D"}
1
+ {"version":3,"file":"commit_and_update.d.ts","sourceRoot":"","sources":["../../src/tools/commit_and_update.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;AAIxB,eAAO,MAAM,IAAI,sBAAsB,CAAC;AACxC,eAAO,MAAM,WAAW,yLACgK,CAAC;AAEzL,eAAO,MAAM,WAAW;;;;;;;;;EAGtB,CAAC;AAIH;;;;;;;;;;;;;;GAcG;AACH,wBAAgB,kBAAkB,CAAC,IAAI,EAAE,MAAM,GAAG;IAAE,OAAO,EAAE,MAAM,CAAC;IAAC,IAAI,CAAC,EAAE,MAAM,CAAA;CAAE,CA0BnF;AAED,wBAAsB,OAAO,CAAC,KAAK,EAAE,CAAC,CAAC,KAAK,CAAC,OAAO,WAAW,CAAC;;;;;GAmF/D"}
@@ -7,6 +7,49 @@ export const inputSchema = z.object({
7
7
  issue_number: z.number().int().positive().describe("The issue number this work is against"),
8
8
  hint: z.string().optional().describe("Short description of what was done — used to build the commit message and issue comment"),
9
9
  });
10
+ const SUBJECT_MAX = 72;
11
+ /**
12
+ * Split a free-text hint into a git commit subject + optional body.
13
+ *
14
+ * - Subject: the first **non-blank** line, truncated to ~72 chars at a **word
15
+ * boundary** (never mid-word) — a single unbreakable word longer than the
16
+ * limit is the only case that gets a hard cut. Leading blank lines are skipped
17
+ * so a hint like "\nAdd X" doesn't produce an empty subject (#236).
18
+ * - Body: any lines after the subject line, plus whatever overflowed past the
19
+ * subject, joined as blank-line-separated paragraphs. `undefined` when the
20
+ * hint fits entirely in the subject, so a short single-line hint behaves
21
+ * exactly as before (subject only). (#228)
22
+ *
23
+ * A whitespace-only hint has no usable subject line and returns `{ subject: "" }`
24
+ * — the handler guards against that by treating a blank hint as absent (#236).
25
+ */
26
+ export function splitCommitMessage(hint) {
27
+ const lines = hint.split("\n");
28
+ // Take the subject from the first non-blank line, not lines[0], so leading
29
+ // blank lines don't yield an empty subject.
30
+ const firstIdx = lines.findIndex((l) => l.trim() !== "");
31
+ if (firstIdx === -1)
32
+ return { subject: "" };
33
+ const firstLine = lines[firstIdx].trim();
34
+ const rest = lines.slice(firstIdx + 1).join("\n").trim();
35
+ let subject = firstLine;
36
+ let overflow = "";
37
+ if (firstLine.length > SUBJECT_MAX) {
38
+ const slice = firstLine.slice(0, SUBJECT_MAX);
39
+ const lastSpace = slice.lastIndexOf(" ");
40
+ if (lastSpace > 0) {
41
+ subject = firstLine.slice(0, lastSpace).trimEnd();
42
+ overflow = firstLine.slice(lastSpace + 1).trim();
43
+ }
44
+ else {
45
+ // A single word longer than the limit — no boundary to break on.
46
+ subject = slice;
47
+ overflow = firstLine.slice(SUBJECT_MAX).trim();
48
+ }
49
+ }
50
+ const body = [overflow, rest].filter(Boolean).join("\n\n");
51
+ return body ? { subject, body } : { subject };
52
+ }
10
53
  export async function handler(input) {
11
54
  const issue = await getIssue(input.issue_number);
12
55
  const branchName = extractBranchFromBody(issue.body);
@@ -18,12 +61,16 @@ export async function handler(input) {
18
61
  catch {
19
62
  changedFiles = [];
20
63
  }
21
- const hintText = input.hint ?? "";
64
+ // Trim so a whitespace-only hint (e.g. " ") counts as absent — otherwise it
65
+ // is truthy and yields an empty commit subject (#236).
66
+ const hintText = (input.hint ?? "").trim();
22
67
  const filesText = changedFiles.length > 0 ? changedFiles.join(", ") : "various files";
23
- // Build the commit message from the hint when provided, else the file list.
24
- const commitMessage = hintText
25
- ? hintText.slice(0, 72)
26
- : `chore: update ${filesText.slice(0, 60)}`;
68
+ // Build the commit subject (and optional body) from the hint when provided,
69
+ // else the file list. A long/multi-line hint is split into a word-boundary
70
+ // subject plus a body rather than blindly sliced mid-word at 72 chars (#228).
71
+ const { subject: commitMessage, body: commitBody } = hintText
72
+ ? splitCommitMessage(hintText)
73
+ : { subject: `chore: update ${filesText.slice(0, 60)}`, body: undefined };
27
74
  // Stage, commit, and push on the issue branch. Arguments are passed as an
28
75
  // array (no shell), so the hint and branch name can't be interpreted as
29
76
  // shell commands. The caller's original branch is restored afterward.
@@ -34,7 +81,13 @@ export async function handler(input) {
34
81
  git(["checkout", branchName]);
35
82
  }
36
83
  git(["add", "-A"]);
37
- git(["commit", "-m", commitMessage]);
84
+ const commitArgs = ["commit", "-m", commitMessage];
85
+ if (commitBody) {
86
+ // A second -m yields a native subject + body (blank-line separated),
87
+ // still passing every arg as an array (no shell).
88
+ commitArgs.push("-m", commitBody);
89
+ }
90
+ git(commitArgs);
38
91
  if (branchName) {
39
92
  git(["push", "origin", branchName]);
40
93
  }
@@ -1 +1 @@
1
- {"version":3,"file":"commit_and_update.js","sourceRoot":"","sources":["../../src/tools/commit_and_update.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"commit_and_update.js","sourceRoot":"","sources":["../../src/tools/commit_and_update.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,27 @@
1
+ import { z } from "zod";
2
+ export declare const name = "configure";
3
+ export declare const description: string;
4
+ export declare const inputSchema: z.ZodObject<{
5
+ set: z.ZodOptional<z.ZodRecord<z.ZodString, z.ZodString>>;
6
+ declined: z.ZodOptional<z.ZodArray<z.ZodString, "many">>;
7
+ }, "strip", z.ZodTypeAny, {
8
+ set?: Record<string, string> | undefined;
9
+ declined?: string[] | undefined;
10
+ }, {
11
+ set?: Record<string, string> | undefined;
12
+ declined?: string[] | undefined;
13
+ }>;
14
+ export declare function handler(input: z.infer<typeof inputSchema>): Promise<{
15
+ content: {
16
+ type: "text";
17
+ text: string;
18
+ }[];
19
+ isError: boolean;
20
+ } | {
21
+ content: {
22
+ type: "text";
23
+ text: string;
24
+ }[];
25
+ isError?: undefined;
26
+ }>;
27
+ //# sourceMappingURL=configure.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"configure.d.ts","sourceRoot":"","sources":["../../src/tools/configure.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;AAOxB,eAAO,MAAM,IAAI,cAAc,CAAC;AAEhC,eAAO,MAAM,WAAW,QAKoI,CAAC;AAE7J,eAAO,MAAM,WAAW;;;;;;;;;EAStB,CAAC;AASH,wBAAsB,OAAO,CAAC,KAAK,EAAE,CAAC,CAAC,KAAK,CAAC,OAAO,WAAW,CAAC;;;;;;;;;;;;GAmE/D"}
@@ -0,0 +1,91 @@
1
+ import { z } from "zod";
2
+ import { join } from "node:path";
3
+ import { allKeys } from "../cli/manifest.js";
4
+ import { parseEnv, serializeEnv, writeEnv } from "../cli/env.js";
5
+ import { packageVersion } from "../cli/banner.js";
6
+ export const name = "configure";
7
+ export const description = "Persist okffs configuration to the .env file in the current working directory — the write backend for the /okffs:setup conversational wizard. " +
8
+ "Reuses the same manifest + serializer as the `okffs setup` CLI, so both paths produce identical files: okffs owns ONLY a marked block, and the user's own variables and comments outside it are preserved verbatim. " +
9
+ "Pass `set` (a map of okffs env var → value) for variables to configure, and/or `declined` (a list of keys) for variables the user explicitly chose to skip (written as commented placeholders so a later sync won't re-ask them). " +
10
+ "Existing configured values that you don't pass are left untouched. Keys are validated against the manifest — unknown keys are rejected. " +
11
+ "Typically called by the /okffs:setup prompt after interviewing the user; not usually called directly. Secrets (GITHUB_TOKEN) are masked in the response.";
12
+ export const inputSchema = z.object({
13
+ set: z
14
+ .record(z.string())
15
+ .optional()
16
+ .describe("Map of okffs env var name → value to set, e.g. { OKFFS_BASE_BRANCH: \"develop\", OKFFS_AUTO_PR: \"true\" }. Booleans are the strings \"true\"/\"false\"."),
17
+ declined: z
18
+ .array(z.string())
19
+ .optional()
20
+ .describe("Env var names the user explicitly declined — written as `# KEY=` placeholders so sync mode treats them as asked-and-declined, not new."),
21
+ });
22
+ const SECRET_KEYS = new Set(["GITHUB_TOKEN"]);
23
+ function mask(v) {
24
+ if (v.length <= 8)
25
+ return "•".repeat(v.length);
26
+ return `${v.slice(0, 4)}${"•".repeat(6)}${v.slice(-4)}`;
27
+ }
28
+ export async function handler(input) {
29
+ const set = input.set ?? {};
30
+ const declined = input.declined ?? [];
31
+ // Validate every provided key against the manifest before touching the file.
32
+ const known = new Set(allKeys());
33
+ const unknown = [...Object.keys(set), ...declined].filter((k) => !known.has(k));
34
+ if (unknown.length > 0) {
35
+ return {
36
+ content: [
37
+ {
38
+ type: "text",
39
+ text: `[okffs] Unknown config key(s): ${unknown.join(", ")}. ` +
40
+ `configure only accepts okffs manifest variables (GITHUB_* / OKFFS_*). No changes were written.`,
41
+ },
42
+ ],
43
+ isError: true,
44
+ };
45
+ }
46
+ const envPath = join(process.cwd(), ".env");
47
+ const parsed = parseEnv(envPath);
48
+ // Seed from the existing file so untouched vars are preserved, then apply the
49
+ // caller's changes on top.
50
+ const collected = {};
51
+ for (const key of parsed.known) {
52
+ const val = parsed.values[key];
53
+ collected[key] = val !== undefined && val !== "" ? { state: "set", value: val } : { state: "declined", value: "" };
54
+ }
55
+ for (const [key, value] of Object.entries(set))
56
+ collected[key] = { state: "set", value };
57
+ for (const key of declined)
58
+ collected[key] = { state: "declined", value: "" };
59
+ try {
60
+ const contents = serializeEnv(collected, parsed.preamble, parsed.postamble, packageVersion());
61
+ writeEnv(envPath, contents);
62
+ }
63
+ catch (err) {
64
+ return {
65
+ content: [
66
+ {
67
+ type: "text",
68
+ text: `[okffs] Failed to write ${envPath}: ${err instanceof Error ? err.message : String(err)}. ` +
69
+ `Check that the directory is writable and not read-only. No changes were made.`,
70
+ },
71
+ ],
72
+ isError: true,
73
+ };
74
+ }
75
+ // Build a human-readable summary (masking secrets).
76
+ const setLines = Object.entries(set).map(([k, v]) => ` ${k}=${SECRET_KEYS.has(k) ? mask(v) : v}`);
77
+ const declinedLine = declined.length ? ` declined (left unset): ${declined.join(", ")}` : "";
78
+ const summary = [
79
+ `Wrote ${envPath} (okffs v${packageVersion()}).`,
80
+ parsed.exists ? "Updated the okffs-managed block; your other variables and comments were preserved." : "Created a new .env with the okffs-managed block.",
81
+ setLines.length ? `Set ${setLines.length} variable(s):` : "",
82
+ ...setLines,
83
+ declinedLine,
84
+ "",
85
+ "Reminder: restart the MCP server (or Claude Code) so okffs re-reads .env.",
86
+ ]
87
+ .filter(Boolean)
88
+ .join("\n");
89
+ return { content: [{ type: "text", text: summary }] };
90
+ }
91
+ //# sourceMappingURL=configure.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"configure.js","sourceRoot":"","sources":["../../src/tools/configure.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;AACxB,OAAO,EAAE,IAAI,EAAE,MAAM,WAAW,CAAC;AAEjC,OAAO,EAAE,OAAO,EAAE,MAAM,oBAAoB,CAAC;AAC7C,OAAO,EAAE,QAAQ,EAAE,YAAY,EAAE,QAAQ,EAAkB,MAAM,eAAe,CAAC;AACjF,OAAO,EAAE,cAAc,EAAE,MAAM,kBAAkB,CAAC;AAElD,MAAM,CAAC,MAAM,IAAI,GAAG,WAAW,CAAC;AAEhC,MAAM,CAAC,MAAM,WAAW,GACtB,gJAAgJ;IAChJ,sNAAsN;IACtN,oOAAoO;IACpO,0IAA0I;IAC1I,0JAA0J,CAAC;AAE7J,MAAM,CAAC,MAAM,WAAW,GAAG,CAAC,CAAC,MAAM,CAAC;IAClC,GAAG,EAAE,CAAC;SACH,MAAM,CAAC,CAAC,CAAC,MAAM,EAAE,CAAC;SAClB,QAAQ,EAAE;SACV,QAAQ,CAAC,0JAA0J,CAAC;IACvK,QAAQ,EAAE,CAAC;SACR,KAAK,CAAC,CAAC,CAAC,MAAM,EAAE,CAAC;SACjB,QAAQ,EAAE;SACV,QAAQ,CAAC,wIAAwI,CAAC;CACtJ,CAAC,CAAC;AAEH,MAAM,WAAW,GAAG,IAAI,GAAG,CAAC,CAAC,cAAc,CAAC,CAAC,CAAC;AAE9C,SAAS,IAAI,CAAC,CAAS;IACrB,IAAI,CAAC,CAAC,MAAM,IAAI,CAAC;QAAE,OAAO,GAAG,CAAC,MAAM,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC;IAC/C,OAAO,GAAG,CAAC,CAAC,KAAK,CAAC,CAAC,EAAE,CAAC,CAAC,GAAG,GAAG,CAAC,MAAM,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC;AAC1D,CAAC;AAED,MAAM,CAAC,KAAK,UAAU,OAAO,CAAC,KAAkC;IAC9D,MAAM,GAAG,GAAG,KAAK,CAAC,GAAG,IAAI,EAAE,CAAC;IAC5B,MAAM,QAAQ,GAAG,KAAK,CAAC,QAAQ,IAAI,EAAE,CAAC;IAEtC,6EAA6E;IAC7E,MAAM,KAAK,GAAG,IAAI,GAAG,CAAC,OAAO,EAAE,CAAC,CAAC;IACjC,MAAM,OAAO,GAAG,CAAC,GAAG,MAAM,CAAC,IAAI,CAAC,GAAG,CAAC,EAAE,GAAG,QAAQ,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC;IAChF,IAAI,OAAO,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC;QACvB,OAAO;YACL,OAAO,EAAE;gBACP;oBACE,IAAI,EAAE,MAAe;oBACrB,IAAI,EACF,kCAAkC,OAAO,CAAC,IAAI,CAAC,IAAI,CAAC,IAAI;wBACxD,gGAAgG;iBACnG;aACF;YACD,OAAO,EAAE,IAAI;SACd,CAAC;IACJ,CAAC;IAED,MAAM,OAAO,GAAG,IAAI,CAAC,OAAO,CAAC,GAAG,EAAE,EAAE,MAAM,CAAC,CAAC;IAC5C,MAAM,MAAM,GAAG,QAAQ,CAAC,OAAO,CAAC,CAAC;IAEjC,8EAA8E;IAC9E,2BAA2B;IAC3B,MAAM,SAAS,GAAc,EAAE,CAAC;IAChC,KAAK,MAAM,GAAG,IAAI,MAAM,CAAC,KAAK,EAAE,CAAC;QAC/B,MAAM,GAAG,GAAG,MAAM,CAAC,MAAM,CAAC,GAAG,CAAC,CAAC;QAC/B,SAAS,CAAC,GAAG,CAAC,GAAG,GAAG,KAAK,SAAS,IAAI,GAAG,KAAK,EAAE,CAAC,CAAC,CAAC,EAAE,KAAK,EAAE,KAAK,EAAE,KAAK,EAAE,GAAG,EAAE,CAAC,CAAC,CAAC,EAAE,KAAK,EAAE,UAAU,EAAE,KAAK,EAAE,EAAE,EAAE,CAAC;IACrH,CAAC;IACD,KAAK,MAAM,CAAC,GAAG,EAAE,KAAK,CAAC,IAAI,MAAM,CAAC,OAAO,CAAC,GAAG,CAAC;QAAE,SAAS,CAAC,GAAG,CAAC,GAAG,EAAE,KAAK,EAAE,KAAK,EAAE,KAAK,EAAE,CAAC;IACzF,KAAK,MAAM,GAAG,IAAI,QAAQ;QAAE,SAAS,CAAC,GAAG,CAAC,GAAG,EAAE,KAAK,EAAE,UAAU,EAAE,KAAK,EAAE,EAAE,EAAE,CAAC;IAE9E,IAAI,CAAC;QACH,MAAM,QAAQ,GAAG,YAAY,CAAC,SAAS,EAAE,MAAM,CAAC,QAAQ,EAAE,MAAM,CAAC,SAAS,EAAE,cAAc,EAAE,CAAC,CAAC;QAC9F,QAAQ,CAAC,OAAO,EAAE,QAAQ,CAAC,CAAC;IAC9B,CAAC;IAAC,OAAO,GAAG,EAAE,CAAC;QACb,OAAO;YACL,OAAO,EAAE;gBACP;oBACE,IAAI,EAAE,MAAe;oBACrB,IAAI,EACF,2BAA2B,OAAO,KAAK,GAAG,YAAY,KAAK,CAAC,CAAC,CAAC,GAAG,CAAC,OAAO,CAAC,CAAC,CAAC,MAAM,CAAC,GAAG,CAAC,IAAI;wBAC3F,+EAA+E;iBAClF;aACF;YACD,OAAO,EAAE,IAAI;SACd,CAAC;IACJ,CAAC;IAED,oDAAoD;IACpD,MAAM,QAAQ,GAAG,MAAM,CAAC,OAAO,CAAC,GAAG,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,EAAE,EAAE,CAAC,KAAK,CAAC,IAAI,WAAW,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC;IACnG,MAAM,YAAY,GAAG,QAAQ,CAAC,MAAM,CAAC,CAAC,CAAC,4BAA4B,QAAQ,CAAC,IAAI,CAAC,IAAI,CAAC,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC;IAC9F,MAAM,OAAO,GAAG;QACd,SAAS,OAAO,YAAY,cAAc,EAAE,IAAI;QAChD,MAAM,CAAC,MAAM,CAAC,CAAC,CAAC,oFAAoF,CAAC,CAAC,CAAC,kDAAkD;QACzJ,QAAQ,CAAC,MAAM,CAAC,CAAC,CAAC,OAAO,QAAQ,CAAC,MAAM,eAAe,CAAC,CAAC,CAAC,EAAE;QAC5D,GAAG,QAAQ;QACX,YAAY;QACZ,EAAE;QACF,2EAA2E;KAC5E;SACE,MAAM,CAAC,OAAO,CAAC;SACf,IAAI,CAAC,IAAI,CAAC,CAAC;IAEd,OAAO,EAAE,OAAO,EAAE,CAAC,EAAE,IAAI,EAAE,MAAe,EAAE,IAAI,EAAE,OAAO,EAAE,CAAC,EAAE,CAAC;AACjE,CAAC"}
@@ -0,0 +1,23 @@
1
+ import { z } from "zod";
2
+ export declare const name = "fix_into_base";
3
+ export declare const description: string;
4
+ export declare const inputSchema: z.ZodObject<{
5
+ head: z.ZodOptional<z.ZodString>;
6
+ base: z.ZodOptional<z.ZodString>;
7
+ summary: z.ZodOptional<z.ZodString>;
8
+ }, "strip", z.ZodTypeAny, {
9
+ summary?: string | undefined;
10
+ head?: string | undefined;
11
+ base?: string | undefined;
12
+ }, {
13
+ summary?: string | undefined;
14
+ head?: string | undefined;
15
+ base?: string | undefined;
16
+ }>;
17
+ export declare function handler(input: z.infer<typeof inputSchema>): Promise<{
18
+ content: {
19
+ type: "text";
20
+ text: string;
21
+ }[];
22
+ }>;
23
+ //# sourceMappingURL=fix_into_base.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"fix_into_base.d.ts","sourceRoot":"","sources":["../../src/tools/fix_into_base.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;AAaxB,eAAO,MAAM,IAAI,kBAAkB,CAAC;AAEpC,eAAO,MAAM,WAAW,QAI4e,CAAC;AAErgB,eAAO,MAAM,WAAW;;;;;;;;;;;;EAatB,CAAC;AAIH,wBAAsB,OAAO,CAAC,KAAK,EAAE,CAAC,CAAC,KAAK,CAAC,OAAO,WAAW,CAAC;;;;;GA4F/D"}