gitmem-mcp 1.0.8 → 1.0.10
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.
- package/CHANGELOG.md +13 -0
- package/CLAUDE.md.template +5 -5
- package/README.md +13 -13
- package/bin/gitmem.js +21 -21
- package/bin/init-wizard.js +2 -2
- package/bin/uninstall.js +2 -2
- package/dist/commands/check.d.ts +3 -3
- package/dist/commands/check.js +3 -3
- package/dist/constants/closing-questions.js +1 -0
- package/dist/index.js +0 -0
- package/hooks/README.md +2 -2
- package/package.json +1 -1
- package/dist/tools/create-linear-issue.d.ts +0 -18
- package/dist/tools/create-linear-issue.js +0 -197
package/CHANGELOG.md
CHANGED
|
@@ -7,6 +7,19 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
|
|
|
7
7
|
|
|
8
8
|
## [Unreleased]
|
|
9
9
|
|
|
10
|
+
## [1.0.10] - 2026-02-16
|
|
11
|
+
|
|
12
|
+
### Fixed
|
|
13
|
+
- **CI smoke test**: `session_close` test looked for `active-sessions.json` at `process.cwd()` instead of `GITMEM_DIR`, failing in CI where they differ.
|
|
14
|
+
- **CI peer dependencies**: Added `--legacy-peer-deps` to `npm ci` for `zod@4` conflict with `claude-agent-sdk`.
|
|
15
|
+
- **CI unit test**: `quick-retrieve.test.ts` now sets `GITMEM_DIR` so disk cache tests resolve correctly in CI.
|
|
16
|
+
|
|
17
|
+
## [1.0.9] - 2026-02-16
|
|
18
|
+
|
|
19
|
+
### Fixed
|
|
20
|
+
- **Closing payload field name mismatch**: `CLAUDE.md.template` documented wrong field names (`institutional_memory` instead of `institutional_memory_items`, bogus `started_at`/`completed_at` in task_completion) causing agents to write payloads that `session_close` couldn't parse. Fixed template and added `institutional_memory` as normalizer alias.
|
|
21
|
+
- **Missing Q8/Q9 in closing template**: Added `collaborative_dynamic` and `rapport_notes` fields to payload example.
|
|
22
|
+
|
|
10
23
|
## [1.0.6] - 2026-02-16
|
|
11
24
|
|
|
12
25
|
### Fixed
|
package/CLAUDE.md.template
CHANGED
|
@@ -47,17 +47,17 @@ On "closing", "done for now", or "wrapping up":
|
|
|
47
47
|
"do_differently": "...",
|
|
48
48
|
"what_worked": "...",
|
|
49
49
|
"wrong_assumption": "...",
|
|
50
|
-
"scars_applied": "
|
|
51
|
-
"
|
|
50
|
+
"scars_applied": ["scar title 1", "scar title 2"],
|
|
51
|
+
"institutional_memory_items": "...",
|
|
52
|
+
"collaborative_dynamic": "Q8: How human preferred to work",
|
|
53
|
+
"rapport_notes": "Q9: What collaborative dynamic worked"
|
|
52
54
|
},
|
|
53
55
|
"task_completion": {
|
|
54
|
-
"started_at": "ISO timestamp",
|
|
55
|
-
"completed_at": "ISO timestamp",
|
|
56
56
|
"questions_displayed_at": "ISO timestamp",
|
|
57
57
|
"reflection_completed_at": "ISO timestamp",
|
|
58
58
|
"human_asked_at": "ISO timestamp",
|
|
59
59
|
"human_response_at": "ISO timestamp",
|
|
60
|
-
"human_response": "human's correction text or
|
|
60
|
+
"human_response": "human's correction text or 'Looks good'"
|
|
61
61
|
},
|
|
62
62
|
"human_corrections": "",
|
|
63
63
|
"scars_to_record": [],
|
package/README.md
CHANGED
|
@@ -26,7 +26,7 @@ Works with **Claude Code**, **Claude Desktop**, **Cursor**, and any MCP-compatib
|
|
|
26
26
|
## Quick Start
|
|
27
27
|
|
|
28
28
|
```bash
|
|
29
|
-
npx gitmem init
|
|
29
|
+
npx gitmem-mcp init
|
|
30
30
|
```
|
|
31
31
|
|
|
32
32
|
One command. The wizard sets up everything:
|
|
@@ -40,8 +40,8 @@ One command. The wizard sets up everything:
|
|
|
40
40
|
Already have existing config? The wizard merges without destroying anything. Re-running is safe.
|
|
41
41
|
|
|
42
42
|
```bash
|
|
43
|
-
npx gitmem init --yes # Non-interactive
|
|
44
|
-
npx gitmem init --dry-run # Preview changes
|
|
43
|
+
npx gitmem-mcp init --yes # Non-interactive
|
|
44
|
+
npx gitmem-mcp init --dry-run # Preview changes
|
|
45
45
|
```
|
|
46
46
|
|
|
47
47
|
## How It Works
|
|
@@ -73,16 +73,16 @@ Every scar includes **counter-arguments** — reasons why someone might reasonab
|
|
|
73
73
|
- **Session Continuity** — Context, threads, and rapport carry across sessions
|
|
74
74
|
- **Closing Ceremony** — Structured reflection captures what broke, what worked, and what to do differently
|
|
75
75
|
- **20+ MCP Tools** — Full toolkit for memory management, search, threads, and multi-agent coordination
|
|
76
|
-
- **Zero Config** — `npx gitmem init` and you're running
|
|
76
|
+
- **Zero Config** — `npx gitmem-mcp init` and you're running
|
|
77
77
|
- **Non-Destructive** — Merges with your existing `.mcp.json`, `CLAUDE.md`, and hooks
|
|
78
78
|
|
|
79
79
|
## Supported Clients
|
|
80
80
|
|
|
81
81
|
| Client | Setup |
|
|
82
82
|
|--------|-------|
|
|
83
|
-
| **Claude Code** | `npx gitmem init` (auto-detected) |
|
|
84
|
-
| **Claude Desktop** | `npx gitmem init` or add to `claude_desktop_config.json` |
|
|
85
|
-
| **Cursor** | `npx gitmem init` or add to `.cursor/mcp.json` |
|
|
83
|
+
| **Claude Code** | `npx gitmem-mcp init` (auto-detected) |
|
|
84
|
+
| **Claude Desktop** | `npx gitmem-mcp init` or add to `claude_desktop_config.json` |
|
|
85
|
+
| **Cursor** | `npx gitmem-mcp init` or add to `.cursor/mcp.json` |
|
|
86
86
|
| **Any MCP client** | Add `npx -y gitmem-mcp` as an MCP server |
|
|
87
87
|
|
|
88
88
|
<details>
|
|
@@ -105,12 +105,12 @@ Every scar includes **counter-arguments** — reasons why someone might reasonab
|
|
|
105
105
|
|
|
106
106
|
| Command | Description |
|
|
107
107
|
|---------|-------------|
|
|
108
|
-
| `npx gitmem init` | Interactive setup wizard |
|
|
109
|
-
| `npx gitmem init --yes` | Non-interactive setup |
|
|
110
|
-
| `npx gitmem init --dry-run` | Preview changes |
|
|
111
|
-
| `npx gitmem uninstall` | Clean removal (preserves `.gitmem/` data) |
|
|
112
|
-
| `npx gitmem uninstall --all` | Full removal including data |
|
|
113
|
-
| `npx gitmem check` | Diagnostic health check |
|
|
108
|
+
| `npx gitmem-mcp init` | Interactive setup wizard |
|
|
109
|
+
| `npx gitmem-mcp init --yes` | Non-interactive setup |
|
|
110
|
+
| `npx gitmem-mcp init --dry-run` | Preview changes |
|
|
111
|
+
| `npx gitmem-mcp uninstall` | Clean removal (preserves `.gitmem/` data) |
|
|
112
|
+
| `npx gitmem-mcp uninstall --all` | Full removal including data |
|
|
113
|
+
| `npx gitmem-mcp check` | Diagnostic health check |
|
|
114
114
|
|
|
115
115
|
## Pro Tier — Coming Soon
|
|
116
116
|
|
package/bin/gitmem.js
CHANGED
|
@@ -37,31 +37,31 @@ function printUsage() {
|
|
|
37
37
|
GitMem — Institutional Memory for AI Coding
|
|
38
38
|
|
|
39
39
|
Usage:
|
|
40
|
-
npx gitmem init Interactive setup wizard (recommended)
|
|
41
|
-
npx gitmem init --yes Non-interactive setup (accept all defaults)
|
|
42
|
-
npx gitmem init --dry-run Show what would be configured
|
|
43
|
-
npx gitmem uninstall Clean removal of gitmem from project
|
|
44
|
-
npx gitmem uninstall --all Also delete .gitmem/ data directory
|
|
40
|
+
npx gitmem-mcp init Interactive setup wizard (recommended)
|
|
41
|
+
npx gitmem-mcp init --yes Non-interactive setup (accept all defaults)
|
|
42
|
+
npx gitmem-mcp init --dry-run Show what would be configured
|
|
43
|
+
npx gitmem-mcp uninstall Clean removal of gitmem from project
|
|
44
|
+
npx gitmem-mcp uninstall --all Also delete .gitmem/ data directory
|
|
45
45
|
|
|
46
46
|
Other commands:
|
|
47
|
-
npx gitmem setup Output SQL for Supabase schema setup (pro/dev tier)
|
|
48
|
-
npx gitmem configure Generate .mcp.json config for Claude Code
|
|
49
|
-
npx gitmem check Run diagnostic health check
|
|
50
|
-
npx gitmem check --full Full diagnostic with benchmarks
|
|
51
|
-
npx gitmem install-hooks Install Claude Code hooks (standalone)
|
|
52
|
-
npx gitmem uninstall-hooks Remove Claude Code hooks (standalone)
|
|
53
|
-
npx gitmem server Start MCP server (default)
|
|
54
|
-
npx gitmem help Show this help message
|
|
47
|
+
npx gitmem-mcp setup Output SQL for Supabase schema setup (pro/dev tier)
|
|
48
|
+
npx gitmem-mcp configure Generate .mcp.json config for Claude Code
|
|
49
|
+
npx gitmem-mcp check Run diagnostic health check
|
|
50
|
+
npx gitmem-mcp check --full Full diagnostic with benchmarks
|
|
51
|
+
npx gitmem-mcp install-hooks Install Claude Code hooks (standalone)
|
|
52
|
+
npx gitmem-mcp uninstall-hooks Remove Claude Code hooks (standalone)
|
|
53
|
+
npx gitmem-mcp server Start MCP server (default)
|
|
54
|
+
npx gitmem-mcp help Show this help message
|
|
55
55
|
|
|
56
56
|
Quick Start:
|
|
57
|
-
npx gitmem init One command sets up everything
|
|
58
|
-
npx gitmem uninstall One command removes everything
|
|
57
|
+
npx gitmem-mcp init One command sets up everything
|
|
58
|
+
npx gitmem-mcp uninstall One command removes everything
|
|
59
59
|
|
|
60
60
|
Pro Tier (with Supabase):
|
|
61
61
|
1. Create free Supabase project → database.new
|
|
62
|
-
2. npx gitmem setup (copy SQL → Supabase SQL Editor)
|
|
62
|
+
2. npx gitmem-mcp setup (copy SQL → Supabase SQL Editor)
|
|
63
63
|
3. Set SUPABASE_URL + SUPABASE_SERVICE_ROLE_KEY env vars
|
|
64
|
-
4. npx gitmem init (auto-detects pro tier)
|
|
64
|
+
4. npx gitmem-mcp init (auto-detects pro tier)
|
|
65
65
|
5. Start coding — memory is active!
|
|
66
66
|
`);
|
|
67
67
|
}
|
|
@@ -562,7 +562,7 @@ function cmdInstallHooks() {
|
|
|
562
562
|
console.log("GitMem hooks already installed in .claude/settings.json");
|
|
563
563
|
console.log("");
|
|
564
564
|
console.log("To reinstall (overwrite), run:");
|
|
565
|
-
console.log(" npx gitmem install-hooks --force");
|
|
565
|
+
console.log(" npx gitmem-mcp install-hooks --force");
|
|
566
566
|
return;
|
|
567
567
|
}
|
|
568
568
|
}
|
|
@@ -600,14 +600,14 @@ function cmdInstallHooks() {
|
|
|
600
600
|
if (!mcpFound) {
|
|
601
601
|
console.log("WARNING: gitmem MCP server not detected in .mcp.json.");
|
|
602
602
|
console.log(" Hooks will be silent until gitmem MCP is configured.");
|
|
603
|
-
console.log(" Run: npx gitmem configure");
|
|
603
|
+
console.log(" Run: npx gitmem-mcp configure");
|
|
604
604
|
console.log("");
|
|
605
605
|
}
|
|
606
606
|
|
|
607
607
|
console.log("Installed! Hooks will activate on next Claude Code session.");
|
|
608
608
|
console.log("");
|
|
609
609
|
console.log("To update after a gitmem version bump:");
|
|
610
|
-
console.log(" npx gitmem install-hooks --force");
|
|
610
|
+
console.log(" npx gitmem-mcp install-hooks --force");
|
|
611
611
|
}
|
|
612
612
|
|
|
613
613
|
/**
|
|
@@ -693,7 +693,7 @@ function cmdUninstallHooks() {
|
|
|
693
693
|
console.log("Notes:");
|
|
694
694
|
console.log(" - gitmem MCP server config (.mcp.json) was NOT modified");
|
|
695
695
|
console.log(" - Restart Claude Code for changes to take effect");
|
|
696
|
-
console.log(" - To reinstall: npx gitmem install-hooks");
|
|
696
|
+
console.log(" - To reinstall: npx gitmem-mcp install-hooks");
|
|
697
697
|
}
|
|
698
698
|
|
|
699
699
|
switch (command) {
|
package/bin/init-wizard.js
CHANGED
|
@@ -4,7 +4,7 @@
|
|
|
4
4
|
* GitMem Init Wizard
|
|
5
5
|
*
|
|
6
6
|
* Interactive setup that detects existing config, prompts, and merges.
|
|
7
|
-
* Usage: npx gitmem init [--yes] [--dry-run] [--project <name>]
|
|
7
|
+
* Usage: npx gitmem-mcp init [--yes] [--dry-run] [--project <name>]
|
|
8
8
|
*/
|
|
9
9
|
|
|
10
10
|
import {
|
|
@@ -635,7 +635,7 @@ async function main() {
|
|
|
635
635
|
console.log(" Dry run complete — no files were modified.");
|
|
636
636
|
} else {
|
|
637
637
|
console.log(" Setup complete! Start Claude Code — memory is active.");
|
|
638
|
-
console.log(" To remove: npx gitmem uninstall");
|
|
638
|
+
console.log(" To remove: npx gitmem-mcp uninstall");
|
|
639
639
|
}
|
|
640
640
|
console.log("");
|
|
641
641
|
|
package/bin/uninstall.js
CHANGED
|
@@ -3,8 +3,8 @@
|
|
|
3
3
|
/**
|
|
4
4
|
* GitMem Uninstall
|
|
5
5
|
*
|
|
6
|
-
* Cleanly reverses everything `npx gitmem init` did.
|
|
7
|
-
* Usage: npx gitmem uninstall [--yes] [--all]
|
|
6
|
+
* Cleanly reverses everything `npx gitmem-mcp init` did.
|
|
7
|
+
* Usage: npx gitmem-mcp uninstall [--yes] [--all]
|
|
8
8
|
*/
|
|
9
9
|
|
|
10
10
|
import {
|
package/dist/commands/check.d.ts
CHANGED
|
@@ -4,9 +4,9 @@
|
|
|
4
4
|
* Diagnostic CLI command for health checks and benchmarks.
|
|
5
5
|
*
|
|
6
6
|
* Usage:
|
|
7
|
-
* npx gitmem check — Quick health check (~5s)
|
|
8
|
-
* npx gitmem check --full — Full diagnostic (~30s)
|
|
9
|
-
* npx gitmem check --output report.json
|
|
7
|
+
* npx gitmem-mcp check — Quick health check (~5s)
|
|
8
|
+
* npx gitmem-mcp check --full — Full diagnostic (~30s)
|
|
9
|
+
* npx gitmem-mcp check --output report.json
|
|
10
10
|
*
|
|
11
11
|
*
|
|
12
12
|
*/
|
package/dist/commands/check.js
CHANGED
|
@@ -4,9 +4,9 @@
|
|
|
4
4
|
* Diagnostic CLI command for health checks and benchmarks.
|
|
5
5
|
*
|
|
6
6
|
* Usage:
|
|
7
|
-
* npx gitmem check — Quick health check (~5s)
|
|
8
|
-
* npx gitmem check --full — Full diagnostic (~30s)
|
|
9
|
-
* npx gitmem check --output report.json
|
|
7
|
+
* npx gitmem-mcp check — Quick health check (~5s)
|
|
8
|
+
* npx gitmem-mcp check --full — Full diagnostic (~30s)
|
|
9
|
+
* npx gitmem-mcp check --output report.json
|
|
10
10
|
*
|
|
11
11
|
*
|
|
12
12
|
*/
|
|
@@ -137,6 +137,7 @@ const REFLECTION_ALIASES = {
|
|
|
137
137
|
capture: "institutional_memory_items",
|
|
138
138
|
capture_as_memory: "institutional_memory_items",
|
|
139
139
|
memory_items: "institutional_memory_items",
|
|
140
|
+
institutional_memory: "institutional_memory_items",
|
|
140
141
|
// Q8-Q9 (rapport, not in CLOSING_QUESTIONS but used)
|
|
141
142
|
q8_human_style: "human_work_style",
|
|
142
143
|
q9_dynamic: "collaborative_dynamic",
|
package/dist/index.js
CHANGED
|
File without changes
|
package/hooks/README.md
CHANGED
|
@@ -14,7 +14,7 @@ A Claude Code **plugin** that enforces the GitMem institutional memory lifecycle
|
|
|
14
14
|
## Installation
|
|
15
15
|
|
|
16
16
|
```bash
|
|
17
|
-
npx gitmem install-hooks
|
|
17
|
+
npx gitmem-mcp install-hooks
|
|
18
18
|
```
|
|
19
19
|
|
|
20
20
|
This copies the hooks plugin to `~/.claude/plugins/gitmem-hooks/`. Restart Claude Code to activate.
|
|
@@ -22,7 +22,7 @@ This copies the hooks plugin to `~/.claude/plugins/gitmem-hooks/`. Restart Claud
|
|
|
22
22
|
### Uninstall
|
|
23
23
|
|
|
24
24
|
```bash
|
|
25
|
-
npx gitmem uninstall-hooks
|
|
25
|
+
npx gitmem-mcp uninstall-hooks
|
|
26
26
|
```
|
|
27
27
|
|
|
28
28
|
Removes the plugin, cleans up settings and temp state.
|
package/package.json
CHANGED
|
@@ -1,18 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* create_linear_issue Tool (OD-611)
|
|
3
|
-
*
|
|
4
|
-
* Proxy Linear issue creation via GraphQL API.
|
|
5
|
-
* Returns slim response (~50 tokens) instead of Linear MCP's ~1400 tokens.
|
|
6
|
-
*
|
|
7
|
-
* Pattern: File-based payload handoff (same as session_close).
|
|
8
|
-
* Agent writes description to .gitmem/issue-payload.json, then calls this
|
|
9
|
-
* tool with title + teamId inline. Tool reads, merges, calls Linear, deletes file.
|
|
10
|
-
*
|
|
11
|
-
* Performance target: <2000ms (one network call)
|
|
12
|
-
*/
|
|
13
|
-
import type { CreateLinearIssueParams, CreateLinearIssueResult } from "../types/index.js";
|
|
14
|
-
/**
|
|
15
|
-
* Create a Linear issue via GraphQL API with slim response.
|
|
16
|
-
*/
|
|
17
|
-
export declare function createLinearIssue(params: CreateLinearIssueParams): Promise<CreateLinearIssueResult>;
|
|
18
|
-
//# sourceMappingURL=create-linear-issue.d.ts.map
|
|
@@ -1,197 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* create_linear_issue Tool (OD-611)
|
|
3
|
-
*
|
|
4
|
-
* Proxy Linear issue creation via GraphQL API.
|
|
5
|
-
* Returns slim response (~50 tokens) instead of Linear MCP's ~1400 tokens.
|
|
6
|
-
*
|
|
7
|
-
* Pattern: File-based payload handoff (same as session_close).
|
|
8
|
-
* Agent writes description to .gitmem/issue-payload.json, then calls this
|
|
9
|
-
* tool with title + teamId inline. Tool reads, merges, calls Linear, deletes file.
|
|
10
|
-
*
|
|
11
|
-
* Performance target: <2000ms (one network call)
|
|
12
|
-
*/
|
|
13
|
-
import * as fs from "fs";
|
|
14
|
-
import { v4 as uuidv4 } from "uuid";
|
|
15
|
-
import { getGitmemPath } from "../services/gitmem-dir.js";
|
|
16
|
-
import { Timer, buildPerformanceData, recordMetrics, } from "../services/metrics.js";
|
|
17
|
-
import { getEffectTracker } from "../services/effect-tracker.js";
|
|
18
|
-
const LINEAR_API_URL = "https://api.linear.app/graphql";
|
|
19
|
-
/** GraphQL mutation — request only the fields needed for the slim response */
|
|
20
|
-
const ISSUE_CREATE_MUTATION = `
|
|
21
|
-
mutation IssueCreate($input: IssueCreateInput!) {
|
|
22
|
-
issueCreate(input: $input) {
|
|
23
|
-
success
|
|
24
|
-
issue {
|
|
25
|
-
id
|
|
26
|
-
identifier
|
|
27
|
-
url
|
|
28
|
-
state {
|
|
29
|
-
name
|
|
30
|
-
}
|
|
31
|
-
}
|
|
32
|
-
}
|
|
33
|
-
}
|
|
34
|
-
`;
|
|
35
|
-
/**
|
|
36
|
-
* Create a Linear issue via GraphQL API with slim response.
|
|
37
|
-
*/
|
|
38
|
-
export async function createLinearIssue(params) {
|
|
39
|
-
const timer = new Timer();
|
|
40
|
-
const metricsId = uuidv4();
|
|
41
|
-
// 1. Check LINEAR_API_KEY
|
|
42
|
-
const apiKey = process.env.LINEAR_API_KEY;
|
|
43
|
-
if (!apiKey) {
|
|
44
|
-
const latencyMs = timer.stop();
|
|
45
|
-
return {
|
|
46
|
-
success: false,
|
|
47
|
-
error: "LINEAR_API_KEY environment variable is not set. Add it to your MCP server configuration.",
|
|
48
|
-
performance: buildPerformanceData("create_linear_issue", latencyMs, 0),
|
|
49
|
-
};
|
|
50
|
-
}
|
|
51
|
-
// 2. Load file-based payload (same pattern as session_close)
|
|
52
|
-
const payloadPath = params.payload_path || getGitmemPath("issue-payload.json");
|
|
53
|
-
let filePayload = {};
|
|
54
|
-
try {
|
|
55
|
-
if (fs.existsSync(payloadPath)) {
|
|
56
|
-
filePayload = JSON.parse(fs.readFileSync(payloadPath, "utf-8"));
|
|
57
|
-
console.error(`[create_linear_issue] Loaded payload from ${payloadPath}`);
|
|
58
|
-
// Clean up payload file after reading
|
|
59
|
-
try {
|
|
60
|
-
fs.unlinkSync(payloadPath);
|
|
61
|
-
}
|
|
62
|
-
catch {
|
|
63
|
-
/* ignore cleanup errors */
|
|
64
|
-
}
|
|
65
|
-
}
|
|
66
|
-
}
|
|
67
|
-
catch (error) {
|
|
68
|
-
console.error("[create_linear_issue] Failed to read issue-payload.json:", error);
|
|
69
|
-
}
|
|
70
|
-
// 3. Merge: inline params override file payload
|
|
71
|
-
const teamId = params.teamId || filePayload.teamId;
|
|
72
|
-
const title = params.title || filePayload.title;
|
|
73
|
-
if (!teamId || !title) {
|
|
74
|
-
const latencyMs = timer.stop();
|
|
75
|
-
return {
|
|
76
|
-
success: false,
|
|
77
|
-
error: "teamId and title are required. Provide inline or in .gitmem/issue-payload.json.",
|
|
78
|
-
performance: buildPerformanceData("create_linear_issue", latencyMs, 0),
|
|
79
|
-
};
|
|
80
|
-
}
|
|
81
|
-
// 4. Build IssueCreateInput for GraphQL
|
|
82
|
-
const input = {
|
|
83
|
-
teamId,
|
|
84
|
-
title,
|
|
85
|
-
};
|
|
86
|
-
// Description only comes from file payload (the large field)
|
|
87
|
-
if (filePayload.description) {
|
|
88
|
-
input.description = filePayload.description;
|
|
89
|
-
}
|
|
90
|
-
// Merge optional fields — inline overrides file
|
|
91
|
-
if (params.priority !== undefined || filePayload.priority !== undefined) {
|
|
92
|
-
input.priority = params.priority ?? filePayload.priority;
|
|
93
|
-
}
|
|
94
|
-
if (params.labelIds?.length || filePayload.labelIds?.length) {
|
|
95
|
-
input.labelIds = params.labelIds || filePayload.labelIds;
|
|
96
|
-
}
|
|
97
|
-
if (params.projectId || filePayload.projectId) {
|
|
98
|
-
input.projectId = params.projectId || filePayload.projectId;
|
|
99
|
-
}
|
|
100
|
-
if (params.assigneeId || filePayload.assigneeId) {
|
|
101
|
-
input.assigneeId = params.assigneeId || filePayload.assigneeId;
|
|
102
|
-
}
|
|
103
|
-
if (params.parentId || filePayload.parentId) {
|
|
104
|
-
input.parentId = params.parentId || filePayload.parentId;
|
|
105
|
-
}
|
|
106
|
-
if (params.stateId || filePayload.stateId) {
|
|
107
|
-
input.stateId = params.stateId || filePayload.stateId;
|
|
108
|
-
}
|
|
109
|
-
if (params.estimate !== undefined || filePayload.estimate !== undefined) {
|
|
110
|
-
input.estimate = params.estimate ?? filePayload.estimate;
|
|
111
|
-
}
|
|
112
|
-
// 5. Call Linear GraphQL API
|
|
113
|
-
try {
|
|
114
|
-
const response = await fetch(LINEAR_API_URL, {
|
|
115
|
-
method: "POST",
|
|
116
|
-
headers: {
|
|
117
|
-
"Content-Type": "application/json",
|
|
118
|
-
Authorization: apiKey,
|
|
119
|
-
},
|
|
120
|
-
body: JSON.stringify({
|
|
121
|
-
query: ISSUE_CREATE_MUTATION,
|
|
122
|
-
variables: { input },
|
|
123
|
-
}),
|
|
124
|
-
});
|
|
125
|
-
if (!response.ok) {
|
|
126
|
-
const text = await response.text();
|
|
127
|
-
const latencyMs = timer.stop();
|
|
128
|
-
return {
|
|
129
|
-
success: false,
|
|
130
|
-
error: `Linear API HTTP ${response.status}: ${text.slice(0, 200)}`,
|
|
131
|
-
performance: buildPerformanceData("create_linear_issue", latencyMs, 0),
|
|
132
|
-
};
|
|
133
|
-
}
|
|
134
|
-
const data = (await response.json());
|
|
135
|
-
// Handle GraphQL errors
|
|
136
|
-
if (data.errors?.length) {
|
|
137
|
-
const latencyMs = timer.stop();
|
|
138
|
-
return {
|
|
139
|
-
success: false,
|
|
140
|
-
error: `Linear GraphQL error: ${data.errors.map((e) => e.message).join("; ")}`,
|
|
141
|
-
performance: buildPerformanceData("create_linear_issue", latencyMs, 0),
|
|
142
|
-
};
|
|
143
|
-
}
|
|
144
|
-
const issueCreate = data.data?.issueCreate;
|
|
145
|
-
if (!issueCreate?.success || !issueCreate.issue) {
|
|
146
|
-
const latencyMs = timer.stop();
|
|
147
|
-
return {
|
|
148
|
-
success: false,
|
|
149
|
-
error: "Linear API returned unsuccessful issueCreate",
|
|
150
|
-
performance: buildPerformanceData("create_linear_issue", latencyMs, 0),
|
|
151
|
-
};
|
|
152
|
-
}
|
|
153
|
-
const issue = issueCreate.issue;
|
|
154
|
-
const latencyMs = timer.stop();
|
|
155
|
-
// 6. Fire-and-forget metrics recording
|
|
156
|
-
getEffectTracker().track("metrics", "create_linear_issue", () => recordMetrics({
|
|
157
|
-
id: metricsId,
|
|
158
|
-
tool_name: "create_linear_issue",
|
|
159
|
-
latency_ms: latencyMs,
|
|
160
|
-
result_count: 1,
|
|
161
|
-
metadata: {
|
|
162
|
-
identifier: issue.identifier,
|
|
163
|
-
teamId,
|
|
164
|
-
has_description: !!filePayload.description,
|
|
165
|
-
},
|
|
166
|
-
}));
|
|
167
|
-
// 7. Return slim response (~50 tokens vs ~1400)
|
|
168
|
-
return {
|
|
169
|
-
success: true,
|
|
170
|
-
identifier: issue.identifier,
|
|
171
|
-
url: issue.url,
|
|
172
|
-
id: issue.id,
|
|
173
|
-
state: issue.state?.name,
|
|
174
|
-
performance: buildPerformanceData("create_linear_issue", latencyMs, 1, {
|
|
175
|
-
breakdown: {
|
|
176
|
-
upsert: {
|
|
177
|
-
latency_ms: latencyMs,
|
|
178
|
-
source: "supabase",
|
|
179
|
-
cache_status: "not_applicable",
|
|
180
|
-
network_call: true,
|
|
181
|
-
},
|
|
182
|
-
},
|
|
183
|
-
}),
|
|
184
|
-
};
|
|
185
|
-
}
|
|
186
|
-
catch (error) {
|
|
187
|
-
const errorMessage = error instanceof Error ? error.message : String(error);
|
|
188
|
-
console.error("[create_linear_issue] Failed:", error);
|
|
189
|
-
const latencyMs = timer.stop();
|
|
190
|
-
return {
|
|
191
|
-
success: false,
|
|
192
|
-
error: `Linear API call failed: ${errorMessage}`,
|
|
193
|
-
performance: buildPerformanceData("create_linear_issue", latencyMs, 0),
|
|
194
|
-
};
|
|
195
|
-
}
|
|
196
|
-
}
|
|
197
|
-
//# sourceMappingURL=create-linear-issue.js.map
|