memory-journal-mcp 7.4.0 → 7.5.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.
- package/README.md +51 -31
- package/dist/{chunk-P5V2VY6N.js → chunk-VHA46GLM.js} +262 -18
- package/dist/{chunk-5ZA77VUW.js → chunk-XNOUTCRV.js} +244 -105
- package/dist/cli.js +11 -3
- package/dist/index.d.ts +8 -2
- package/dist/index.js +2 -2
- package/dist/{tools-WZUENKJ6.js → tools-HTE4YXMW.js} +1 -1
- package/package.json +2 -1
- package/skills/README.md +2 -0
- package/skills/github-commander/SKILL.md +1 -0
- package/skills/github-commander/workflows/copilot-audit.md +48 -0
- package/skills/github-copilot-cli/SKILL.md +64 -0
- package/skills/package.json +1 -0
package/README.md
CHANGED
|
@@ -10,7 +10,7 @@
|
|
|
10
10
|
[](https://registry.modelcontextprotocol.io/v0/servers?search=io.github.neverinfamous/memory-journal-mcp)
|
|
11
11
|
[](SECURITY.md)
|
|
12
12
|
[](https://github.com/neverinfamous/memory-journal-mcp)
|
|
13
|
-

|
|
14
14
|

|
|
15
15
|

|
|
16
16
|
[](https://github.com/neverinfamous/memory-journal-mcp/actions/workflows/gatekeeper.yml)
|
|
@@ -51,7 +51,7 @@ Memory Journal solves this by acting as your project's **long-term memory**, bri
|
|
|
51
51
|
|
|
52
52
|
## 🎯 What Sets Us Apart
|
|
53
53
|
|
|
54
|
-
**
|
|
54
|
+
**70 MCP Tools** · **17 Workflow Prompts** · **36 Resources** · **10 Tool Groups** · **Code Mode** · **GitHub Commander** (Issue Triage, PR Review, Milestone Sprints, Security/Quality/Perf Audits) · **GitHub Integration** (Issues, PRs, Actions, Kanban, Milestones, Insights) · **Team Collaboration** (Shared DB, Vector Search, Cross-Project Insights, Hush Protocol Flags)
|
|
55
55
|
|
|
56
56
|
| Feature | Description |
|
|
57
57
|
| ----------------------------- | --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
|
|
@@ -61,9 +61,10 @@ Memory Journal solves this by acting as your project's **long-term memory**, bri
|
|
|
61
61
|
| **Knowledge Graphs** | 8 relationship types linking specs → implementations → tests → PRs with Mermaid visualization |
|
|
62
62
|
| **Hybrid Search** | Reciprocal Rank Fusion combining FTS5 keywords, semantic vector similarity, auto-heuristics, and date-range filters |
|
|
63
63
|
| **Code Mode** | Execute multi-step operations in a secure sandbox — up to 90% token savings via `mj.*` API |
|
|
64
|
-
| **Configurable Briefing** |
|
|
64
|
+
| **Configurable Briefing** | 15 env vars / CLI flags control `memory://briefing` content — entries, team, GitHub detail, skills awareness, chronological grounding |
|
|
65
65
|
| **Reports & Analytics** | Standups, retrospectives, PR summaries, digests, period analyses, and milestone tracking |
|
|
66
|
-
| **
|
|
66
|
+
| **Hush Protocol (Flags)** | Replace Slack/Teams noise with structured, actionable, and searchable AI flags (blockers, reviews) that automatically surface in session briefings |
|
|
67
|
+
| **Team Collaboration** | 25 tools with full parity — CRUD, vector search, relationship graphs, cross-project insights, author attribution, Hush Protocol flags |
|
|
67
68
|
| **Data Interoperability** | Bidirectional Markdown roundtripping, unified IO namespace, and schema-safe JSON exports with hard bounds-checked path traversal defenses |
|
|
68
69
|
| **Backup & Restore** | One-command backup/restore with automated scheduling, retention policies, and safety-net auto-backups |
|
|
69
70
|
| **Security & Transport** | OAuth 2.1 (RFC 9728/8414, JWT/JWKS, scopes), Streamable HTTP + SSE, rate limiting, CORS, SQL injection prevention, non-root Docker |
|
|
@@ -117,7 +118,7 @@ flowchart TB
|
|
|
117
118
|
---
|
|
118
119
|
|
|
119
120
|
<details>
|
|
120
|
-
<summary><strong>🤖
|
|
121
|
+
<summary><strong>🤖 Recommended AI Agent Instructions/Rule</strong></summary>
|
|
121
122
|
|
|
122
123
|
_Suggested Rule (Add to AGENTS.md, GEMINI.md, system prompts, etc.)_
|
|
123
124
|
|
|
@@ -134,8 +135,10 @@ Execute BEFORE fulfilling any user request in a new session:
|
|
|
134
135
|
- **REQUIRED GROUPS**:
|
|
135
136
|
- **GitHub**: Combine Repo, Branch, CI, PRs, and Insights.
|
|
136
137
|
- **GitHub Issues**: List every issue, one per line.
|
|
137
|
-
-
|
|
138
|
-
|
|
138
|
+
- **Active Flags (Hush Protocol)**: If the briefing JSON contains an `activeFlags` object (with `count > 0`), render each flag in a dedicated row using format: `🚩 {flag_type} → @{target_user}: {preview}`. If `count` is 0 or the field is absent, omit the row entirely.
|
|
139
|
+
- Also include Entry Counts (Journal/Team), Latest Entries/Summaries (titles only), Proactive Analytics/Team Density, Milestones, and Workspaces.
|
|
140
|
+
- **FLAG PROMINENCE**: When `activeFlags.count > 0`, prepend a bold callout line **above** the table: `⚠️ **{count} active flag(s)** — review before proceeding.` This ensures blockers and review requests are impossible to miss.
|
|
141
|
+
4. **STOP & WAIT**: Do NOT autonomously resume past tasks or start work on new issues mentioned in the session summary. The briefing is strictly for context.
|
|
139
142
|
|
|
140
143
|
</details>
|
|
141
144
|
|
|
@@ -150,11 +153,11 @@ Control which tools are exposed via `MEMORY_JOURNAL_MCP_TOOL_FILTER` (or CLI: `-
|
|
|
150
153
|
|
|
151
154
|
| Filter | Tools | Use Case |
|
|
152
155
|
| -------------------- | ----- | ------------------------ |
|
|
153
|
-
| `full` |
|
|
156
|
+
| `full` | 70 | All tools (default) |
|
|
154
157
|
| `starter` | ~11 | Core + search + codemode |
|
|
155
158
|
| `essential` | ~7 | Minimal footprint |
|
|
156
159
|
| `readonly` | 18 | Disable all mutations |
|
|
157
|
-
| `-github` |
|
|
160
|
+
| `-github` | 52 | Exclude a group |
|
|
158
161
|
| `-github,-analytics` | 48 | Exclude multiple groups |
|
|
159
162
|
|
|
160
163
|
**Filter Syntax:** `shortcut` or `group` or `tool_name` (whitelist mode) · `-group` (disable group) · `-tool` (disable tool) · `+tool` (re-enable after group disable)
|
|
@@ -169,20 +172,20 @@ Control which tools are exposed via `MEMORY_JOURNAL_MCP_TOOL_FILTER` (or CLI: `-
|
|
|
169
172
|
|
|
170
173
|
## 📋 Core Capabilities
|
|
171
174
|
|
|
172
|
-
### 🛠️ **
|
|
173
|
-
|
|
174
|
-
| Group | Tools | Description
|
|
175
|
-
| --------------- | ----- |
|
|
176
|
-
| `codemode` | 1 | Code Mode (sandboxed code execution) 🌟 **Recommended**
|
|
177
|
-
| `core` | 6 | Entry CRUD, tags, test
|
|
178
|
-
| `search` | 4 | Text search, date range, semantic, vector stats
|
|
179
|
-
| `analytics` | 2 | Statistics, cross-project insights
|
|
180
|
-
| `relationships` | 2 | Link entries, visualize graphs
|
|
181
|
-
| `io` | 3 | JSON/Markdown export and File-level Markdown Data Integration Interoperability (Import/Export)
|
|
182
|
-
| `admin` | 5 | Update, delete, rebuild/add to vector index, merge tags
|
|
183
|
-
| `github` | 18 | Issues, PRs, context, Kanban, **Milestones**, **Insights**, **issue lifecycle**, **Copilot Reviews**
|
|
184
|
-
| `backup` | 4 | Backup, list, restore, cleanup
|
|
185
|
-
| `team` |
|
|
175
|
+
### 🛠️ **70 MCP Tools** (10 Groups)
|
|
176
|
+
|
|
177
|
+
| Group | Tools | Description |
|
|
178
|
+
| --------------- | ----- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
|
|
179
|
+
| `codemode` | 1 | Code Mode (sandboxed code execution) 🌟 **Recommended** |
|
|
180
|
+
| `core` | 6 | Entry CRUD, tags, test |
|
|
181
|
+
| `search` | 4 | Text search, date range, semantic, vector stats |
|
|
182
|
+
| `analytics` | 2 | Statistics, cross-project insights |
|
|
183
|
+
| `relationships` | 2 | Link entries, visualize graphs |
|
|
184
|
+
| `io` | 3 | JSON/Markdown export and File-level Markdown Data Integration Interoperability (Import/Export) |
|
|
185
|
+
| `admin` | 5 | Update, delete, rebuild/add to vector index, merge tags |
|
|
186
|
+
| `github` | 18 | Issues, PRs, context, Kanban, **Milestones**, **Insights**, **issue lifecycle**, **Copilot Reviews** |
|
|
187
|
+
| `backup` | 4 | Backup, list, restore, cleanup |
|
|
188
|
+
| `team` | 25 | CRUD, search, stats, relationships, IO (Markdown import/export), backup, vector search, cross-project insights, matrix, **Hush Protocol flags** (requires `TEAM_DB_PATH`) |
|
|
186
189
|
|
|
187
190
|
**[Complete tools reference →](https://github.com/neverinfamous/memory-journal-mcp/wiki/Tools)**
|
|
188
191
|
|
|
@@ -209,11 +212,11 @@ Control which tools are exposed via `MEMORY_JOURNAL_MCP_TOOL_FILTER` (or CLI: `-
|
|
|
209
212
|
|
|
210
213
|
**[Complete prompts guide →](https://github.com/neverinfamous/memory-journal-mcp/wiki/Prompts)**
|
|
211
214
|
|
|
212
|
-
### 📡 **
|
|
215
|
+
### 📡 **36 Resources** (27 Static + 9 Template)
|
|
213
216
|
|
|
214
217
|
**Static Resources** (appear in resource lists):
|
|
215
218
|
|
|
216
|
-
- `memory://briefing` - **Session initialization**: compact context for AI agents (~300 tokens)
|
|
219
|
+
- `memory://briefing` - **Session initialization**: compact context for AI agents (~300 tokens) — includes `localTime` and optional `activeFlags`
|
|
217
220
|
- `memory://instructions` - **Behavioral guidance**: complete server instructions for AI agents
|
|
218
221
|
- `memory://recent` - 10 most recent entries
|
|
219
222
|
- `memory://significant` - Significant milestones and breakthroughs
|
|
@@ -238,6 +241,8 @@ Control which tools are exposed via `MEMORY_JOURNAL_MCP_TOOL_FILTER` (or CLI: `-
|
|
|
238
241
|
- `memory://metrics/system` - Process-level metrics: memory (MB), uptime (s), Node.js version, platform — MEDIUM priority
|
|
239
242
|
- `memory://metrics/users` - Per-user call counts (populated when OAuth user identifiers are present) — LOW priority
|
|
240
243
|
- `memory://audit` - Last 50 write/admin tool call entries from the JSONL audit log (requires `AUDIT_LOG_PATH`)
|
|
244
|
+
- `memory://flags` - Active (unresolved) team flags dashboard (requires `TEAM_DB_PATH`)
|
|
245
|
+
- `memory://flags/vocabulary` - Configured flag vocabulary terms
|
|
241
246
|
|
|
242
247
|
**Template Resources** (require parameters, fetch directly by URI):
|
|
243
248
|
|
|
@@ -264,12 +269,12 @@ Code executes in a **sandboxed VM context** with multiple layers of security. Al
|
|
|
264
269
|
- **Static code validation** — blocked patterns include `require()`, `process`, `eval()`, and filesystem access
|
|
265
270
|
- **Rate limiting** — 60 executions per minute per client
|
|
266
271
|
- **Hard timeouts** — configurable execution limit (default 30s)
|
|
267
|
-
- **Full API access** — all 10 tool groups are available via `mj.*` (e.g., `mj.core.createEntry()`, `mj.search.searchEntries()`, `mj.github.getGithubIssues()`, `mj.
|
|
272
|
+
- **Full API access** — all 10 tool groups are available via `mj.*` (e.g., `mj.core.createEntry()`, `mj.search.searchEntries()`, `mj.github.getGithubIssues()`, `mj.team.passTeamFlag()`)
|
|
268
273
|
- **Strict Readonly Contract** — Calling any mutation method under `--tool-filter readonly` safely halts the sandbox to prevent execution, returning a structured `{ success: false, error: "..." }` response to the agent instead of a raw MCP protocol exception.
|
|
269
274
|
|
|
270
275
|
### ⚡ Code Mode Only (Maximum Token Savings)
|
|
271
276
|
|
|
272
|
-
Run with **only Code Mode enabled** — a single tool that provides access to all
|
|
277
|
+
Run with **only Code Mode enabled** — a single tool that provides access to all 69 tools' worth of capability through the `mj.*` API:
|
|
273
278
|
|
|
274
279
|
```json
|
|
275
280
|
{
|
|
@@ -296,6 +301,20 @@ If you prefer individual tool calls, exclude codemode:
|
|
|
296
301
|
|
|
297
302
|
---
|
|
298
303
|
|
|
304
|
+
## 🤫 Hush Protocol: Asynchronous Team Collaboration
|
|
305
|
+
|
|
306
|
+
The **Hush Protocol** reimagines team collaboration for AI-augmented workflows by replacing noisy Slack/Teams messages with structured, machine-actionable flags.
|
|
307
|
+
|
|
308
|
+
When you encounter a blocker, need a review, or want to broadcast a milestone, your AI agent can raise a flag in the shared Team Database:
|
|
309
|
+
|
|
310
|
+
- **Actionable Visibility**: Active flags automatically surface at the very top of the `memory://briefing` payload for all team members. When another developer's agent starts a session, it immediately sees your blockers and can help resolve them autonomously.
|
|
311
|
+
- **Structured Types**: Raise specific flag types (`blocker`, `needs_review`, `help_requested`, `fyi`). You can customize your team's vocabulary via the `--flag-vocabulary` configuration.
|
|
312
|
+
- **Searchable History**: Unlike chat messages that disappear into the void, Hush flags are permanent, query-able AI journal entries. Your agents can search past `needs_review` flags to understand how architectural blockers were conquered.
|
|
313
|
+
|
|
314
|
+
**Dashboard & Operations**: Read `memory://flags` to see an active dashboard overview and use `mj.team.passTeamFlag()` / `mj.team.resolveTeamFlag()` to manage them programmatically in Code Mode.
|
|
315
|
+
|
|
316
|
+
---
|
|
317
|
+
|
|
299
318
|
## 🚀 Quick Start
|
|
300
319
|
|
|
301
320
|
### Option 1: npm (Recommended)
|
|
@@ -527,6 +546,7 @@ The GitHub tools (`get_github_issues`, `get_github_prs`, etc.) auto-detect the r
|
|
|
527
546
|
| `AUDIT_READS` | Log read-scoped tool calls in addition to write/admin (CLI: `--audit-reads`; default: `false`) |
|
|
528
547
|
| `AUDIT_LOG_MAX_SIZE` | Maximum audit log file size in bytes before rotation (CLI: `--audit-log-max-size`; default: `10485760`) |
|
|
529
548
|
| `MCP_METRICS_ENABLED` | Set to `false` to disable in-memory tool call metrics accumulation (default: `true`) |
|
|
549
|
+
| `FLAG_VOCABULARY` | Comma-separated flag types for Hush Protocol (CLI: `--flag-vocabulary`; default: `blocker,needs_review,help_requested,fyi`) |
|
|
530
550
|
|
|
531
551
|
**Multi-Project Workflows**: For agents to seamlessly support multiple projects, provide **`PROJECT_REGISTRY`**.
|
|
532
552
|
|
|
@@ -630,7 +650,7 @@ Memory Journal provides a **hybrid approach** to GitHub management:
|
|
|
630
650
|
|
|
631
651
|
### GitHub Commander Workflows
|
|
632
652
|
|
|
633
|
-
The server natively bundles the `github-commander` agent skill (accessible via `memory://skills/github-commander`). This extends your AI assistant with
|
|
653
|
+
The server natively bundles the `github-commander` agent skill (accessible via `memory://skills/github-commander`). This extends your AI assistant with 9 autonomous DevOps workflows for repository stewardship: **Issue Triage**, **Milestone Sprints**, **PR Reviews**, **Copilot Audits**, **Security Audits**, **Code Quality Audits**, **Performance Audits**, **Roadmap Kickoffs**, and **Dependency Updates**. Configure validation layers using the `PROJECT_*` environment overrides to enforce CI-matching execution locally during agent tasks!
|
|
634
654
|
|
|
635
655
|
## 🏗️ Architecture
|
|
636
656
|
|
|
@@ -641,8 +661,8 @@ flowchart TB
|
|
|
641
661
|
AI["🤖 AI Agent<br/>(Cursor, Windsurf, Claude)"]
|
|
642
662
|
|
|
643
663
|
subgraph MCP["Memory Journal MCP Server"]
|
|
644
|
-
Tools["🛠️
|
|
645
|
-
Resources["📡
|
|
664
|
+
Tools["🛠️ 70 Tools"]
|
|
665
|
+
Resources["📡 36 Resources"]
|
|
646
666
|
Prompts["💬 17 Prompts"]
|
|
647
667
|
end
|
|
648
668
|
|
|
@@ -670,7 +690,7 @@ flowchart TB
|
|
|
670
690
|
┌─────────────────────────────────────────────────────────────┐
|
|
671
691
|
│ MCP Server Layer (TypeScript) │
|
|
672
692
|
│ ┌─────────────────┐ ┌─────────────────┐ ┌─────────────┐ │
|
|
673
|
-
│ │ Tools (
|
|
693
|
+
│ │ Tools (70) │ │ Resources (36) │ │ Prompts (17)│ │
|
|
674
694
|
│ │ with Annotations│ │ with Annotations│ │ │ │
|
|
675
695
|
│ └─────────────────┘ └─────────────────┘ └─────────────┘ │
|
|
676
696
|
├─────────────────────────────────────────────────────────────┤
|
|
@@ -100,6 +100,7 @@ var ENTRY_TYPES = [
|
|
|
100
100
|
"development_note",
|
|
101
101
|
"enhancement",
|
|
102
102
|
"milestone",
|
|
103
|
+
"flag",
|
|
103
104
|
"system_integration_test",
|
|
104
105
|
"test_entry",
|
|
105
106
|
"other"
|
|
@@ -114,7 +115,7 @@ var SIGNIFICANCE_TYPES = [
|
|
|
114
115
|
"release"
|
|
115
116
|
];
|
|
116
117
|
var MAX_CONTENT_LENGTH = 5e4;
|
|
117
|
-
var MAX_QUERY_LIMIT =
|
|
118
|
+
var MAX_QUERY_LIMIT = 500;
|
|
118
119
|
var DATE_MIN_SENTINEL = "1970-01-01";
|
|
119
120
|
var DATE_MAX_SENTINEL = "2999-12-31";
|
|
120
121
|
var DATE_FORMAT_REGEX = /^\d{4}-\d{2}-\d{2}$/;
|
|
@@ -822,7 +823,7 @@ function getSearchTools(context) {
|
|
|
822
823
|
);
|
|
823
824
|
const entryIds = semanticResults.map((r) => r.entryId);
|
|
824
825
|
const entriesMap = db.getEntriesByIds(entryIds);
|
|
825
|
-
|
|
826
|
+
let entries = semanticResults.map((r) => {
|
|
826
827
|
const entry = entriesMap.get(r.entryId);
|
|
827
828
|
if (!entry) return null;
|
|
828
829
|
if (!passMetadataFilters(
|
|
@@ -832,7 +833,7 @@ function getSearchTools(context) {
|
|
|
832
833
|
))
|
|
833
834
|
return null;
|
|
834
835
|
return { ...entry, source: "personal" };
|
|
835
|
-
}).filter((e) => e !== null)
|
|
836
|
+
}).filter((e) => e !== null);
|
|
836
837
|
if (input.sort_by === "importance") {
|
|
837
838
|
const scored = entries.map((e) => {
|
|
838
839
|
const { score } = db.calculateImportance(e.id);
|
|
@@ -841,13 +842,9 @@ function getSearchTools(context) {
|
|
|
841
842
|
scored.sort(
|
|
842
843
|
(a, b) => (b.importanceScore ?? 0) - (a.importanceScore ?? 0)
|
|
843
844
|
);
|
|
844
|
-
|
|
845
|
-
success: true,
|
|
846
|
-
entries: scored,
|
|
847
|
-
count: scored.length,
|
|
848
|
-
searchMode: isAuto ? "semantic (auto)" : "semantic"
|
|
849
|
-
};
|
|
845
|
+
entries = scored;
|
|
850
846
|
}
|
|
847
|
+
entries = entries.slice(0, input.limit);
|
|
851
848
|
return {
|
|
852
849
|
success: true,
|
|
853
850
|
entries,
|
|
@@ -5143,6 +5140,55 @@ var TeamCollaborationMatrixOutputSchema = z.object({
|
|
|
5143
5140
|
).optional(),
|
|
5144
5141
|
error: z.string().optional()
|
|
5145
5142
|
}).extend(ErrorFieldsMixin.shape);
|
|
5143
|
+
var DEFAULT_FLAG_VOCABULARY = [
|
|
5144
|
+
"blocker",
|
|
5145
|
+
"needs_review",
|
|
5146
|
+
"help_requested",
|
|
5147
|
+
"fyi"
|
|
5148
|
+
];
|
|
5149
|
+
var PassTeamFlagSchema = z.object({
|
|
5150
|
+
flag_type: z.string().min(1).describe("Flag type from vocabulary (e.g., blocker, needs_review)"),
|
|
5151
|
+
message: z.string().min(1).max(5e4).describe("Flag message describing the issue or request"),
|
|
5152
|
+
target_user: z.string().optional().describe("Target user to flag (e.g., @sarah)"),
|
|
5153
|
+
link: z.string().optional().describe("Related file path, URL, or reference"),
|
|
5154
|
+
project_number: z.number().optional(),
|
|
5155
|
+
issue_number: z.number().optional(),
|
|
5156
|
+
author: z.string().optional()
|
|
5157
|
+
});
|
|
5158
|
+
var PassTeamFlagSchemaMcp = z.object({
|
|
5159
|
+
flag_type: z.string().optional(),
|
|
5160
|
+
message: z.string().optional(),
|
|
5161
|
+
target_user: z.string().optional(),
|
|
5162
|
+
link: z.string().optional(),
|
|
5163
|
+
project_number: relaxedNumber().optional(),
|
|
5164
|
+
issue_number: relaxedNumber().optional(),
|
|
5165
|
+
author: z.string().optional()
|
|
5166
|
+
});
|
|
5167
|
+
var ResolveTeamFlagSchema = z.object({
|
|
5168
|
+
flag_id: z.number().describe("Entry ID of the flag to resolve"),
|
|
5169
|
+
resolution: z.string().optional().describe("Optional resolution comment")
|
|
5170
|
+
});
|
|
5171
|
+
var ResolveTeamFlagSchemaMcp = z.object({
|
|
5172
|
+
flag_id: relaxedNumber().optional(),
|
|
5173
|
+
resolution: z.string().optional()
|
|
5174
|
+
});
|
|
5175
|
+
var FlagOutputSchema = z.object({
|
|
5176
|
+
success: z.boolean().optional(),
|
|
5177
|
+
entry: TeamEntryOutputSchema.optional(),
|
|
5178
|
+
flag_type: z.string().optional(),
|
|
5179
|
+
target_user: z.string().nullable().optional(),
|
|
5180
|
+
resolved: z.boolean().optional(),
|
|
5181
|
+
author: z.string().optional(),
|
|
5182
|
+
error: z.string().optional()
|
|
5183
|
+
}).extend(ErrorFieldsMixin.shape);
|
|
5184
|
+
var ResolveFlagOutputSchema = z.object({
|
|
5185
|
+
success: z.boolean().optional(),
|
|
5186
|
+
entry: TeamEntryOutputSchema.optional(),
|
|
5187
|
+
flag_type: z.string().optional(),
|
|
5188
|
+
resolved: z.boolean().optional(),
|
|
5189
|
+
resolution: z.string().nullable().optional(),
|
|
5190
|
+
error: z.string().optional()
|
|
5191
|
+
}).extend(ErrorFieldsMixin.shape);
|
|
5146
5192
|
|
|
5147
5193
|
// src/handlers/tools/team/core-tools.ts
|
|
5148
5194
|
function getTeamCoreTools(context) {
|
|
@@ -5313,7 +5359,7 @@ function getTeamSearchTools(context) {
|
|
|
5313
5359
|
return { ...TEAM_DB_ERROR_RESPONSE };
|
|
5314
5360
|
}
|
|
5315
5361
|
const { query, tags, limit, sort_by } = TeamSearchSchema.parse(params);
|
|
5316
|
-
const searchLimit = tags && tags.length > 0 ? Math.min(Math.max(limit * 5, 50),
|
|
5362
|
+
const searchLimit = tags && tags.length > 0 ? Math.min(Math.max(limit * 5, 50), MAX_QUERY_LIMIT) : limit;
|
|
5317
5363
|
let entries;
|
|
5318
5364
|
if (query) {
|
|
5319
5365
|
entries = teamDb.searchEntries(query, {
|
|
@@ -5728,11 +5774,11 @@ function getTeamAnalyticsTools(context) {
|
|
|
5728
5774
|
return { ...TEAM_DB_ERROR_RESPONSE };
|
|
5729
5775
|
}
|
|
5730
5776
|
const { period, limit } = TeamCollaborationMatrixSchema.parse(params);
|
|
5731
|
-
const
|
|
5777
|
+
const dateExpression = period === "week" ? `strftime('%Y-W%W', timestamp)` : period === "quarter" ? `strftime('%Y-Q', timestamp) || cast(((cast(strftime('%m', timestamp) as integer) + 2) / 3) as integer)` : `strftime('%Y-%m', timestamp)`;
|
|
5732
5778
|
const activityResult = teamDb.executeRawQuery(
|
|
5733
5779
|
`SELECT
|
|
5734
5780
|
COALESCE(author, 'unknown') AS author,
|
|
5735
|
-
|
|
5781
|
+
${dateExpression} AS period,
|
|
5736
5782
|
COUNT(*) AS entry_count
|
|
5737
5783
|
FROM memory_journal
|
|
5738
5784
|
WHERE deleted_at IS NULL
|
|
@@ -6543,6 +6589,191 @@ function getTeamVectorTools(context) {
|
|
|
6543
6589
|
];
|
|
6544
6590
|
}
|
|
6545
6591
|
|
|
6592
|
+
// src/handlers/tools/team/flag-tools.ts
|
|
6593
|
+
function getVocabulary(context) {
|
|
6594
|
+
const custom = context.config?.flagVocabulary;
|
|
6595
|
+
return custom && custom.length > 0 ? custom : DEFAULT_FLAG_VOCABULARY;
|
|
6596
|
+
}
|
|
6597
|
+
function parseFlagContext(autoContext) {
|
|
6598
|
+
if (!autoContext) return void 0;
|
|
6599
|
+
try {
|
|
6600
|
+
const parsed = JSON.parse(autoContext);
|
|
6601
|
+
if (typeof parsed === "object" && parsed !== null && "flag_type" in parsed && "resolved" in parsed) {
|
|
6602
|
+
return parsed;
|
|
6603
|
+
}
|
|
6604
|
+
return void 0;
|
|
6605
|
+
} catch {
|
|
6606
|
+
return void 0;
|
|
6607
|
+
}
|
|
6608
|
+
}
|
|
6609
|
+
function getTeamFlagTools(context) {
|
|
6610
|
+
const { teamDb } = context;
|
|
6611
|
+
return [
|
|
6612
|
+
{
|
|
6613
|
+
name: "team_pass_flag",
|
|
6614
|
+
title: "Pass Team Flag",
|
|
6615
|
+
description: "Create a machine-actionable flag in the team database. Flags replace communication noise with structured, searchable signals. Vocabulary: blocker, needs_review, help_requested, fyi (configurable via FLAG_VOCABULARY).",
|
|
6616
|
+
group: "team",
|
|
6617
|
+
inputSchema: PassTeamFlagSchemaMcp,
|
|
6618
|
+
outputSchema: FlagOutputSchema,
|
|
6619
|
+
annotations: {
|
|
6620
|
+
readOnlyHint: false,
|
|
6621
|
+
destructiveHint: false,
|
|
6622
|
+
idempotentHint: false,
|
|
6623
|
+
openWorldHint: false
|
|
6624
|
+
},
|
|
6625
|
+
handler: (params) => {
|
|
6626
|
+
try {
|
|
6627
|
+
if (!teamDb) {
|
|
6628
|
+
return { ...TEAM_DB_ERROR_RESPONSE };
|
|
6629
|
+
}
|
|
6630
|
+
const input = PassTeamFlagSchema.parse(params);
|
|
6631
|
+
const vocabulary = getVocabulary(context);
|
|
6632
|
+
if (!vocabulary.includes(input.flag_type)) {
|
|
6633
|
+
return {
|
|
6634
|
+
success: false,
|
|
6635
|
+
error: `Invalid flag type: "${input.flag_type}". Valid types: ${vocabulary.join(", ")}`,
|
|
6636
|
+
code: "VALIDATION_ERROR",
|
|
6637
|
+
category: "validation",
|
|
6638
|
+
suggestion: `Use one of: ${vocabulary.join(", ")}`,
|
|
6639
|
+
recoverable: true
|
|
6640
|
+
};
|
|
6641
|
+
}
|
|
6642
|
+
const author = input.author ?? resolveAuthor();
|
|
6643
|
+
const targetUser = input.target_user?.replace(/^@/, "") ?? null;
|
|
6644
|
+
const flagContext = {
|
|
6645
|
+
flag_type: input.flag_type,
|
|
6646
|
+
target_user: targetUser,
|
|
6647
|
+
link: input.link ?? null,
|
|
6648
|
+
resolved: false,
|
|
6649
|
+
resolved_at: null,
|
|
6650
|
+
resolution: null,
|
|
6651
|
+
author
|
|
6652
|
+
};
|
|
6653
|
+
const contentPrefix = `flag:${input.flag_type}`;
|
|
6654
|
+
const targetSuffix = targetUser ? ` \u2014 @${targetUser}` : "";
|
|
6655
|
+
const content = `${contentPrefix}${targetSuffix}: ${input.message}`;
|
|
6656
|
+
const tags = [`flag:${input.flag_type}`];
|
|
6657
|
+
if (targetUser) {
|
|
6658
|
+
tags.push(`@${targetUser}`);
|
|
6659
|
+
}
|
|
6660
|
+
const entry = teamDb.createEntry({
|
|
6661
|
+
content,
|
|
6662
|
+
entryType: "flag",
|
|
6663
|
+
tags,
|
|
6664
|
+
isPersonal: false,
|
|
6665
|
+
autoContext: JSON.stringify(flagContext),
|
|
6666
|
+
projectNumber: input.project_number,
|
|
6667
|
+
issueNumber: input.issue_number
|
|
6668
|
+
});
|
|
6669
|
+
teamDb.executeRawQuery("UPDATE memory_journal SET author = ? WHERE id = ?", [
|
|
6670
|
+
author,
|
|
6671
|
+
entry.id
|
|
6672
|
+
]);
|
|
6673
|
+
teamDb.flushSave();
|
|
6674
|
+
return {
|
|
6675
|
+
success: true,
|
|
6676
|
+
entry: { ...entry, author },
|
|
6677
|
+
flag_type: input.flag_type,
|
|
6678
|
+
target_user: targetUser,
|
|
6679
|
+
resolved: false,
|
|
6680
|
+
author
|
|
6681
|
+
};
|
|
6682
|
+
} catch (err) {
|
|
6683
|
+
return formatHandlerError(err);
|
|
6684
|
+
}
|
|
6685
|
+
}
|
|
6686
|
+
},
|
|
6687
|
+
{
|
|
6688
|
+
name: "team_resolve_flag",
|
|
6689
|
+
title: "Resolve Team Flag",
|
|
6690
|
+
description: "Mark a team flag as resolved with an optional resolution comment. Idempotent \u2014 resolving an already-resolved flag returns success with the existing state.",
|
|
6691
|
+
group: "team",
|
|
6692
|
+
inputSchema: ResolveTeamFlagSchemaMcp,
|
|
6693
|
+
outputSchema: ResolveFlagOutputSchema,
|
|
6694
|
+
annotations: {
|
|
6695
|
+
readOnlyHint: false,
|
|
6696
|
+
destructiveHint: false,
|
|
6697
|
+
idempotentHint: true,
|
|
6698
|
+
openWorldHint: false
|
|
6699
|
+
},
|
|
6700
|
+
handler: (params) => {
|
|
6701
|
+
try {
|
|
6702
|
+
if (!teamDb) {
|
|
6703
|
+
return { ...TEAM_DB_ERROR_RESPONSE };
|
|
6704
|
+
}
|
|
6705
|
+
const input = ResolveTeamFlagSchema.parse(params);
|
|
6706
|
+
const entry = teamDb.getEntryById(input.flag_id);
|
|
6707
|
+
if (!entry) {
|
|
6708
|
+
return {
|
|
6709
|
+
success: false,
|
|
6710
|
+
error: `Flag entry ${String(input.flag_id)} not found`,
|
|
6711
|
+
code: "RESOURCE_NOT_FOUND",
|
|
6712
|
+
category: "resource",
|
|
6713
|
+
suggestion: "Verify the flag entry ID and try again",
|
|
6714
|
+
recoverable: true
|
|
6715
|
+
};
|
|
6716
|
+
}
|
|
6717
|
+
if (entry.entryType !== "flag") {
|
|
6718
|
+
return {
|
|
6719
|
+
success: false,
|
|
6720
|
+
error: `Entry ${String(input.flag_id)} is not a flag (type: ${entry.entryType})`,
|
|
6721
|
+
code: "VALIDATION_ERROR",
|
|
6722
|
+
category: "validation",
|
|
6723
|
+
suggestion: "Use team_resolve_flag only on entries created by team_pass_flag",
|
|
6724
|
+
recoverable: true
|
|
6725
|
+
};
|
|
6726
|
+
}
|
|
6727
|
+
const flagCtx = parseFlagContext(entry.autoContext);
|
|
6728
|
+
if (!flagCtx) {
|
|
6729
|
+
return {
|
|
6730
|
+
success: false,
|
|
6731
|
+
error: `Flag entry ${String(input.flag_id)} has invalid auto_context`,
|
|
6732
|
+
code: "INTERNAL_ERROR",
|
|
6733
|
+
category: "internal",
|
|
6734
|
+
recoverable: false
|
|
6735
|
+
};
|
|
6736
|
+
}
|
|
6737
|
+
if (flagCtx.resolved) {
|
|
6738
|
+
const author2 = fetchAuthor(teamDb, input.flag_id);
|
|
6739
|
+
return {
|
|
6740
|
+
success: true,
|
|
6741
|
+
entry: { ...entry, author: author2 },
|
|
6742
|
+
flag_type: flagCtx.flag_type,
|
|
6743
|
+
resolved: true,
|
|
6744
|
+
resolution: flagCtx.resolution
|
|
6745
|
+
};
|
|
6746
|
+
}
|
|
6747
|
+
const updatedContext = {
|
|
6748
|
+
...flagCtx,
|
|
6749
|
+
resolved: true,
|
|
6750
|
+
resolved_at: (/* @__PURE__ */ new Date()).toISOString(),
|
|
6751
|
+
resolution: input.resolution ?? null
|
|
6752
|
+
};
|
|
6753
|
+
const resolutionSuffix = input.resolution ? ` [RESOLVED: ${input.resolution}]` : " [RESOLVED]";
|
|
6754
|
+
const updatedContent = entry.content + resolutionSuffix;
|
|
6755
|
+
teamDb.executeRawQuery(
|
|
6756
|
+
"UPDATE memory_journal SET auto_context = ?, content = ? WHERE id = ?",
|
|
6757
|
+
[JSON.stringify(updatedContext), updatedContent, input.flag_id]
|
|
6758
|
+
);
|
|
6759
|
+
teamDb.flushSave();
|
|
6760
|
+
const updatedEntry = teamDb.getEntryById(input.flag_id);
|
|
6761
|
+
const author = fetchAuthor(teamDb, input.flag_id);
|
|
6762
|
+
return {
|
|
6763
|
+
success: true,
|
|
6764
|
+
entry: updatedEntry ? { ...updatedEntry, author } : void 0,
|
|
6765
|
+
flag_type: flagCtx.flag_type,
|
|
6766
|
+
resolved: true,
|
|
6767
|
+
resolution: input.resolution ?? null
|
|
6768
|
+
};
|
|
6769
|
+
} catch (err) {
|
|
6770
|
+
return formatHandlerError(err);
|
|
6771
|
+
}
|
|
6772
|
+
}
|
|
6773
|
+
}
|
|
6774
|
+
];
|
|
6775
|
+
}
|
|
6776
|
+
|
|
6546
6777
|
// src/handlers/tools/team/index.ts
|
|
6547
6778
|
function getTeamTools(context) {
|
|
6548
6779
|
return [
|
|
@@ -6554,7 +6785,8 @@ function getTeamTools(context) {
|
|
|
6554
6785
|
...getTeamExportTools(context),
|
|
6555
6786
|
...getTeamIoTools(context),
|
|
6556
6787
|
...getTeamBackupTools(context),
|
|
6557
|
-
...getTeamVectorTools(context)
|
|
6788
|
+
...getTeamVectorTools(context),
|
|
6789
|
+
...getTeamFlagTools(context)
|
|
6558
6790
|
];
|
|
6559
6791
|
}
|
|
6560
6792
|
|
|
@@ -6639,7 +6871,11 @@ var METHOD_ALIASES = {
|
|
|
6639
6871
|
vectorStats: "teamGetVectorIndexStats",
|
|
6640
6872
|
rebuildIndex: "teamRebuildVectorIndex",
|
|
6641
6873
|
addToIndex: "teamAddToVectorIndex",
|
|
6642
|
-
insights: "teamGetCrossProjectInsights"
|
|
6874
|
+
insights: "teamGetCrossProjectInsights",
|
|
6875
|
+
passTeamFlag: "teamPassFlag",
|
|
6876
|
+
resolveTeamFlag: "teamResolveFlag",
|
|
6877
|
+
passFlag: "teamPassFlag",
|
|
6878
|
+
resolveFlag: "teamResolveFlag"
|
|
6643
6879
|
}
|
|
6644
6880
|
};
|
|
6645
6881
|
var GROUP_EXAMPLES = {
|
|
@@ -6698,7 +6934,9 @@ var GROUP_EXAMPLES = {
|
|
|
6698
6934
|
'mj.team.teamExportEntries({ format: "json" })',
|
|
6699
6935
|
"mj.team.teamBackup()",
|
|
6700
6936
|
'mj.team.teamSemanticSearch({ query: "deployment" })',
|
|
6701
|
-
"mj.team.teamGetCrossProjectInsights()"
|
|
6937
|
+
"mj.team.teamGetCrossProjectInsights()",
|
|
6938
|
+
'mj.team.passTeamFlag({ flag_type: "blocker", message: "FK constraint issue" })',
|
|
6939
|
+
"mj.team.resolveTeamFlag({ flag_id: 42 })"
|
|
6702
6940
|
]
|
|
6703
6941
|
};
|
|
6704
6942
|
var POSITIONAL_PARAM_MAP = {
|
|
@@ -6752,7 +6990,11 @@ var POSITIONAL_PARAM_MAP = {
|
|
|
6752
6990
|
teamVisualizeRelationships: "entry_id",
|
|
6753
6991
|
teamExportEntries: "format",
|
|
6754
6992
|
teamSemanticSearch: "query",
|
|
6755
|
-
teamAddToVectorIndex: "entry_id"
|
|
6993
|
+
teamAddToVectorIndex: "entry_id",
|
|
6994
|
+
teamPassFlag: "flag_type",
|
|
6995
|
+
teamResolveFlag: "flag_id",
|
|
6996
|
+
passTeamFlag: "flag_type",
|
|
6997
|
+
resolveTeamFlag: "flag_id"
|
|
6756
6998
|
};
|
|
6757
6999
|
var GROUP_PREFIX_MAP = {
|
|
6758
7000
|
core: "",
|
|
@@ -7973,7 +8215,9 @@ var TOOL_GROUPS = {
|
|
|
7973
8215
|
"team_rebuild_vector_index",
|
|
7974
8216
|
"team_add_to_vector_index",
|
|
7975
8217
|
"team_get_cross_project_insights",
|
|
7976
|
-
"team_get_collaboration_matrix"
|
|
8218
|
+
"team_get_collaboration_matrix",
|
|
8219
|
+
"team_pass_flag",
|
|
8220
|
+
"team_resolve_flag"
|
|
7977
8221
|
],
|
|
7978
8222
|
codemode: ["mj_execute_code"]
|
|
7979
8223
|
};
|
|
@@ -8564,4 +8808,4 @@ function getAllToolDefinitions(context) {
|
|
|
8564
8808
|
];
|
|
8565
8809
|
}
|
|
8566
8810
|
|
|
8567
|
-
export { ASSISTANT_FOCUSED, BASE_SCOPES, DEFAULT_AUDIT_LOG_MAX_SIZE_BYTES, DEFAULT_BRIEFING_CONFIG, HIGH_PRIORITY, LOW_PRIORITY, MEDIUM_PRIORITY, META_GROUPS, SUPPORTED_SCOPES, TOOL_GROUPS, calculateTokenSavings, callTool, execQuery, filterTools, getAllToolNames, getAuditResourceDef, getEnabledGroups, getFilterSummary, getGlobalAuditLogger, getRequiredScope, getToolFilterFromEnv, getToolGroup, getTools, globalMetrics, hasScope, initializeAuditLogger, isResourceError, isToolEnabled, milestoneCompletionPct, parseScopes, parseToolFilter, resolveGitHubRepo, sendProgress, setDefaultSandboxMode, transformEntryRow, withPriority, withSessionInit };
|
|
8811
|
+
export { ASSISTANT_FOCUSED, BASE_SCOPES, DEFAULT_AUDIT_LOG_MAX_SIZE_BYTES, DEFAULT_BRIEFING_CONFIG, DEFAULT_FLAG_VOCABULARY, HIGH_PRIORITY, LOW_PRIORITY, MEDIUM_PRIORITY, META_GROUPS, SUPPORTED_SCOPES, TOOL_GROUPS, calculateTokenSavings, callTool, execQuery, filterTools, getAllToolNames, getAuditResourceDef, getEnabledGroups, getFilterSummary, getGlobalAuditLogger, getRequiredScope, getToolFilterFromEnv, getToolGroup, getTools, globalMetrics, hasScope, initializeAuditLogger, isResourceError, isToolEnabled, milestoneCompletionPct, parseScopes, parseToolFilter, resolveGitHubRepo, sendProgress, setDefaultSandboxMode, transformEntryRow, withPriority, withSessionInit };
|