@tesselate-digital/notion-agent-hive 0.0.4 → 0.0.8

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 CHANGED
@@ -1,3 +1,7 @@
1
+ <p align="center">
2
+ <img src="assets/logo.png" alt="Notion Agent Hive" width="400">
3
+ </p>
4
+
1
5
  # notion-agent-hive
2
6
 
3
7
  **Persistent memory for AI coding sessions using Notion.**
@@ -0,0 +1,44 @@
1
+ /**
2
+ * Kanban database schema for feature boards.
3
+ * Used by coordinator when creating new boards.
4
+ */
5
+ export declare const KANBAN_SCHEMA = "```sql\nCREATE TABLE (\n \"Task\" TITLE,\n \"Status\" SELECT('Backlog':default, 'To Do':blue, 'In Progress':yellow, 'Needs Human Input':red, 'In Test':orange, 'Human Review':purple, 'Done':green),\n \"Priority\" SELECT('Critical':red, 'High':orange, 'Medium':yellow, 'Low':green),\n \"Depends On\" RICH_TEXT,\n \"Complexity\" SELECT('Small':green, 'Medium':yellow, 'Large':red),\n \"Notes\" RICH_TEXT\n)\n```";
6
+ /**
7
+ * Status transition rules. Coordinator is the sole agent responsible for all transitions.
8
+ */
9
+ export declare const STATUS_TRANSITIONS = "| Transition | Condition |\n|---|---|\n| Backlog \u2192 To Do | Thinker sets during plan creation, or coordinator adjusts |\n| To Do \u2192 In Progress | When dispatching executor |\n| In Progress \u2192 In Test | Executor reports `READY_FOR_TEST` |\n| In Test \u2192 Human Review | Reviewer reports `PASS` |\n| In Test \u2192 To Do | Reviewer reports `FAIL` |\n| Any \u2192 Needs Human Input | Ambiguity escalation |\n| Human Review \u2192 Done | **Human only**, final sign-off |\n| Human Review \u2192 To Do | Human requests changes |";
10
+ /**
11
+ * Board permissions by agent role.
12
+ * Single source of truth referenced by all agents.
13
+ */
14
+ export declare const BOARD_PERMISSIONS: {
15
+ coordinator: {
16
+ summary: string;
17
+ allowed: string[];
18
+ forbidden: string[];
19
+ };
20
+ executor: {
21
+ summary: string;
22
+ allowed: string[];
23
+ forbidden: string[];
24
+ };
25
+ reviewer: {
26
+ summary: string;
27
+ allowed: string[];
28
+ forbidden: string[];
29
+ };
30
+ thinker: {
31
+ summary: string;
32
+ allowed: string[];
33
+ forbidden: string[];
34
+ };
35
+ };
36
+ /**
37
+ * Generates a thinker dispatch instruction block.
38
+ * Consolidates boilerplate across PLAN_FEATURE, PLAN_FROM_DRAFT, INVESTIGATE, REFINE_TASK.
39
+ */
40
+ export declare function formatThinkerDispatch(type: "PLAN_FEATURE" | "PLAN_FROM_DRAFT" | "INVESTIGATE" | "REFINE_TASK"): string;
41
+ /**
42
+ * Board permissions summary for subagent prompts.
43
+ */
44
+ export declare function getBoardPermissionsBlock(role: keyof typeof BOARD_PERMISSIONS): string;
package/dist/cli/index.js CHANGED
@@ -1,13 +1,17 @@
1
1
  #!/usr/bin/env bun
2
2
  // @bun
3
3
  var __defProp = Object.defineProperty;
4
+ var __returnValue = (v) => v;
5
+ function __exportSetter(name, newValue) {
6
+ this[name] = __returnValue.bind(null, newValue);
7
+ }
4
8
  var __export = (target, all) => {
5
9
  for (var name in all)
6
10
  __defProp(target, name, {
7
11
  get: all[name],
8
12
  enumerable: true,
9
13
  configurable: true,
10
- set: (newValue) => all[name] = () => newValue
14
+ set: __exportSetter.bind(all, name)
11
15
  });
12
16
  };
13
17
 
package/dist/index.js CHANGED
@@ -1,15 +1,142 @@
1
1
  // @bun
2
2
  var __defProp = Object.defineProperty;
3
+ var __returnValue = (v) => v;
4
+ function __exportSetter(name, newValue) {
5
+ this[name] = __returnValue.bind(null, newValue);
6
+ }
3
7
  var __export = (target, all) => {
4
8
  for (var name in all)
5
9
  __defProp(target, name, {
6
10
  get: all[name],
7
11
  enumerable: true,
8
12
  configurable: true,
9
- set: (newValue) => all[name] = () => newValue
13
+ set: __exportSetter.bind(all, name)
10
14
  });
11
15
  };
12
16
 
17
+ // src/agents/shared.ts
18
+ var KANBAN_SCHEMA = `\`\`\`sql
19
+ CREATE TABLE (
20
+ "Task" TITLE,
21
+ "Status" SELECT('Backlog':default, 'To Do':blue, 'In Progress':yellow, 'Needs Human Input':red, 'In Test':orange, 'Human Review':purple, 'Done':green),
22
+ "Priority" SELECT('Critical':red, 'High':orange, 'Medium':yellow, 'Low':green),
23
+ "Depends On" RICH_TEXT,
24
+ "Complexity" SELECT('Small':green, 'Medium':yellow, 'Large':red),
25
+ "Notes" RICH_TEXT
26
+ )
27
+ \`\`\``;
28
+ var STATUS_TRANSITIONS = `| Transition | Condition |
29
+ |---|---|
30
+ | Backlog \u2192 To Do | Thinker sets during plan creation, or coordinator adjusts |
31
+ | To Do \u2192 In Progress | When dispatching executor |
32
+ | In Progress \u2192 In Test | Executor reports \`READY_FOR_TEST\` |
33
+ | In Test \u2192 Human Review | Reviewer reports \`PASS\` |
34
+ | In Test \u2192 To Do | Reviewer reports \`FAIL\` |
35
+ | Any \u2192 Needs Human Input | Ambiguity escalation |
36
+ | Human Review \u2192 Done | **Human only**, final sign-off |
37
+ | Human Review \u2192 To Do | Human requests changes |`;
38
+ var BOARD_PERMISSIONS = {
39
+ coordinator: {
40
+ summary: "Full board control. Creates pages, databases, tickets. Handles ALL status transitions.",
41
+ allowed: ["create pages/databases/tickets", "all status transitions", "update ticket properties"],
42
+ forbidden: ["implementing code", "deep research"]
43
+ },
44
+ executor: {
45
+ summary: "Limited board access. Read context, write findings on assigned ticket only.",
46
+ allowed: ["read board/ticket context", "write implementation notes on assigned ticket page"],
47
+ forbidden: ["moving tasks between statuses", "creating/deleting tickets", "scanning board for next task"]
48
+ },
49
+ reviewer: {
50
+ summary: "Read-only for source code. Can move In Test \u2192 Human Review on PASS verdict.",
51
+ allowed: ["read board/ticket context", "write QA findings on ticket page"],
52
+ forbidden: ["moving to Done (human only)", "moving to To Do/In Progress", "creating/deleting tickets"]
53
+ },
54
+ thinker: {
55
+ summary: "Read-only Notion access. Returns reports; coordinator handles all writes.",
56
+ allowed: ["read Notion pages for context"],
57
+ forbidden: ["create/update/delete anything in Notion", "move tickets", "dispatch subagents"]
58
+ }
59
+ };
60
+ function formatThinkerDispatch(type) {
61
+ const headers = {
62
+ PLAN_FEATURE: "You are being dispatched to research and plan a feature.",
63
+ PLAN_FROM_DRAFT: "You are being dispatched to convert a user's draft into a structured feature plan.",
64
+ INVESTIGATE: "You are being dispatched to investigate an issue.",
65
+ REFINE_TASK: "You are being dispatched to refine a task specification."
66
+ };
67
+ const contexts = {
68
+ PLAN_FEATURE: `BOARD_CONTEXT:
69
+ thinking_board_id: <page ID>
70
+ existing_context: <any relevant board state, or "new board">
71
+
72
+ USER_REQUEST:
73
+ <verbatim user request>`,
74
+ PLAN_FROM_DRAFT: `BOARD_CONTEXT:
75
+ thinking_board_id: <page ID>
76
+ draft_page_id: <same page ID, or child page if draft is nested>
77
+
78
+ USER_DRAFT_CONTENT:
79
+ <full content extracted from the Notion page>
80
+
81
+ USER_REQUEST:
82
+ <any additional instructions from the user, or "Convert this draft into a thinking board">`,
83
+ INVESTIGATE: `BOARD_CONTEXT:
84
+ thinking_board_id: <page ID>
85
+ task_page_id: <page ID of the affected task>
86
+
87
+ QUESTION:
88
+ <specific question or problem to investigate>
89
+
90
+ CONTEXT:
91
+ <execution report, reviewer findings, human comments, or other relevant context>`,
92
+ REFINE_TASK: `BOARD_CONTEXT:
93
+ thinking_board_id: <page ID>
94
+ task_page_id: <page ID of the task to refine>
95
+
96
+ FEEDBACK:
97
+ <execution report, reviewer findings, or human comments>
98
+
99
+ CURRENT_SPECIFICATION:
100
+ <full current task page content>`
101
+ };
102
+ const instructions = {
103
+ PLAN_FEATURE: `Interrogate the user, explore the codebase, decompose into tasks.
104
+ Return a PLANNING_REPORT with the complete feature context and task specifications.
105
+ Do NOT create anything in Notion - just return the report.`,
106
+ PLAN_FROM_DRAFT: `The user has already done preliminary thinking. Your job is to:
107
+ 1. Understand their intent, ideas, and any structure they've established
108
+ 2. Ask clarifying questions if critical details are missing
109
+ 3. Preserve their terminology and framing where sensible
110
+ 4. Decompose into concrete, actionable tasks
111
+ 5. Return a PLANNING_REPORT as usual
112
+
113
+ Do NOT discard or override the user's ideas. Build on them.
114
+ Do NOT create anything in Notion - just return the report.`,
115
+ INVESTIGATE: `Research the issue, explore the codebase, and return an INVESTIGATION_REPORT.
116
+ Do NOT modify Notion - just return the report.`,
117
+ REFINE_TASK: `Research the issue and return a REFINEMENT_REPORT with the updated specification.
118
+ Do NOT modify Notion - just return the report.`
119
+ };
120
+ return `\`\`\`
121
+ ${headers[type]}
122
+
123
+ DISPATCH_TYPE: ${type}
124
+
125
+ ${contexts[type]}
126
+
127
+ ${instructions[type]}
128
+ \`\`\``;
129
+ }
130
+ function getBoardPermissionsBlock(role) {
131
+ const perms = BOARD_PERMISSIONS[role];
132
+ return `## Board Permissions
133
+
134
+ ${perms.summary}
135
+
136
+ - **Allowed:** ${perms.allowed.join("; ")}
137
+ - **Forbidden:** ${perms.forbidden.join("; ")}`;
138
+ }
139
+
13
140
  // src/agents/coordinator.ts
14
141
  var COORDINATOR_PROMPT = `# Notion Agent Hive (Coordinator)
15
142
 
@@ -28,43 +155,47 @@ The coordinator is orchestration-only and must never implement code directly. It
28
155
 
29
156
  ## Communication Style
30
157
 
31
- Be brief. The user does not need to see your internal reasoning or step-by-step thought process.
32
-
33
- - **Status updates**: One line per action taken. "Moved Task X to In Progress. Dispatching executor."
34
- - **Subagent dispatches**: Do not narrate. Just dispatch and report the verdict when it returns.
35
- - **Board state**: Bullet list of tasks with status. No commentary unless something needs user attention.
36
- - **Decisions**: State what you are doing, not why (unless the user asks or it is non-obvious).
37
- - **Errors/escalations**: Be direct. "Task X blocked: missing API credentials. Need your input."
38
-
39
- Do not explain the workflow, quote the prompt back, or summarize what you are about to do before doing it. Act, then report results concisely.
158
+ Be brief. Act, then report results concisely. One line per action. Do not narrate dispatches or explain the workflow. Be direct on errors: "Task X blocked: missing API credentials."
40
159
 
41
160
  ---
42
161
 
43
162
  ## Board Discovery
44
163
 
45
- At the start of every conversation, determine the Thinking Board page ID and whether this is a new plan or a continuation:
164
+ At the start of every conversation, determine the Thinking Board page ID and classify the board state:
46
165
 
47
166
  1. **Check the user's message first.** If the user included a Notion URL or page ID anywhere in their prompt (e.g., "create a board at https://notion.so/...", "restart the plan at abc123def", "continue from https://notion.so/..."), extract and use it directly. Notion URLs contain the page ID as the last segment (after the final \`-\` or as the trailing hex string). Do NOT ask the user to confirm a link they already gave you. A provided URL/ID is only an identifier for loading context/records; it is never permission to bypass the Thinker -> Executor -> Reviewer flow.
48
167
  2. **Only if no URL or page ID is present** in the user's message, ask using AskHuman tool: *"What is the Notion page ID (or URL) of the Thinking Board where I should create feature pages?"*
49
168
 
50
169
  Store the result as the **Thinking Board page ID** for the rest of the session. All feature sub-pages are created as children of this page.
51
170
 
171
+ ### Board State Classification
172
+
173
+ After obtaining the page ID, fetch the page content via Notion MCP and classify it into one of three states:
174
+
175
+ | State | Detection | Action |
176
+ |-------|-----------|--------|
177
+ | **Empty Board** | Page has no content or only a title | Proceed to Plan Phase with user's request as new feature |
178
+ | **Existing Thinking Board** | Page contains a kanban database with Status column matching schema | Proceed to Session Resumption |
179
+ | **Draft Page** | Page contains content (text, lists, notes) but NO kanban database | Proceed to Draft Conversion |
180
+
181
+ ### Draft Conversion
182
+
183
+ When the user points to a page containing their own draft ideas, notes, or planning content (but no kanban database), treat this as source material for the thinker:
184
+
185
+ 1. **Read the draft content** from the Notion page via MCP.
186
+ 2. **Dispatch the thinker** with PLAN_FROM_DRAFT (see Plan Phase for dispatch template).
187
+ 3. **Process the PLANNING_REPORT** as usual (create feature page, kanban database, task tickets).
188
+ 4. **Decide where to create the board:**
189
+ - If the draft page is mostly planning notes \u2192 create the kanban as a sibling, link from draft page
190
+ - If the draft page should become the feature page \u2192 restructure it: move draft content into a "Background" section, add kanban database link
191
+
52
192
  ---
53
193
 
54
194
  ## Kanban Database Schema
55
195
 
56
196
  When creating a kanban database for a feature, create it as a separate database (child of the Thinking Board, sibling to the feature page). Link to it from the feature page. Use this schema:
57
197
 
58
- \`\`\`sql
59
- CREATE TABLE (
60
- "Task" TITLE,
61
- "Status" SELECT('Backlog':default, 'To Do':blue, 'In Progress':yellow, 'Needs Human Input':red, 'In Test':orange, 'Human Review':purple, 'Done':green),
62
- "Priority" SELECT('Critical':red, 'High':orange, 'Medium':yellow, 'Low':green),
63
- "Depends On" RICH_TEXT,
64
- "Complexity" SELECT('Small':green, 'Medium':yellow, 'Large':red),
65
- "Notes" RICH_TEXT
66
- )
67
- \`\`\`
198
+ ${KANBAN_SCHEMA}
68
199
 
69
200
  After creating the database, **always create a Board view** grouped by \`"Status"\` so the kanban is immediately usable.
70
201
 
@@ -74,20 +205,9 @@ After creating the database, **always create a Board view** grouped by \`"Status
74
205
 
75
206
  You are the sole agent responsible for all status transitions:
76
207
 
77
- | Transition | Condition |
78
- |---|---|
79
- | Backlog \u2192 To Do | Thinker sets during plan creation, or coordinator adjusts |
80
- | To Do \u2192 In Progress | When dispatching executor |
81
- | In Progress \u2192 In Test | Executor reports \`READY_FOR_TEST\` |
82
- | In Test \u2192 Human Review | Reviewer reports \`PASS\` |
83
- | In Test \u2192 To Do | Reviewer reports \`FAIL\` |
84
- | Any \u2192 Needs Human Input | Ambiguity escalation |
85
- | Human Review \u2192 Done | **Human only**, final sign-off |
86
- | Human Review \u2192 To Do | Human requests changes |
87
-
88
- No subagent moves tickets. You do ALL status transitions. Subagents write their findings directly on ticket pages.
208
+ ${STATUS_TRANSITIONS}
89
209
 
90
- No agent may ever move a ticket to \`Done\`. Only the human user can.
210
+ No subagent moves tickets. You do ALL status transitions. No agent may ever move a ticket to \`Done\`. Only the human user can.
91
211
 
92
212
  ---
93
213
 
@@ -104,74 +224,23 @@ Default to dispatching the thinker. Only skip the thinker for genuinely trivial
104
224
 
105
225
  ### Dispatching the Thinker
106
226
 
107
- The thinker researches and returns structured reports. You handle all Notion operations.
227
+ The thinker researches and returns structured reports. You handle all Notion operations. Spawn a \`notion-thinker\` subagent via the Task tool with the appropriate dispatch type:
108
228
 
109
- #### For Feature Planning (PLAN_FEATURE)
229
+ #### PLAN_FEATURE
230
+ New feature research and decomposition.
231
+ ${formatThinkerDispatch("PLAN_FEATURE")}
110
232
 
111
- Spawn a \`notion-thinker\` subagent via the Task tool with this prefix:
233
+ #### PLAN_FROM_DRAFT
234
+ Convert user's draft notes into a structured plan. Thinker builds on existing work.
235
+ ${formatThinkerDispatch("PLAN_FROM_DRAFT")}
112
236
 
113
- \`\`\`
114
- You are being dispatched to research and plan a feature.
115
-
116
- DISPATCH_TYPE: PLAN_FEATURE
237
+ #### INVESTIGATE
238
+ Research a blocker, failure, or design problem during execution.
239
+ ${formatThinkerDispatch("INVESTIGATE")}
117
240
 
118
- BOARD_CONTEXT:
119
- thinking_board_id: <page ID>
120
- existing_context: <any relevant board state, or "new board">
121
-
122
- USER_REQUEST:
123
- <verbatim user request>
124
-
125
- Interrogate the user, explore the codebase, decompose into tasks.
126
- Return a PLANNING_REPORT with the complete feature context and task specifications.
127
- Do NOT create anything in Notion - just return the report.
128
- \`\`\`
129
-
130
- #### For Investigation (INVESTIGATE)
131
-
132
- Used during execution when a task is blocked, partially complete, or failed review due to a design problem. Spawn a \`notion-thinker\` subagent with:
133
-
134
- \`\`\`
135
- You are being dispatched to investigate an issue.
136
-
137
- DISPATCH_TYPE: INVESTIGATE
138
-
139
- BOARD_CONTEXT:
140
- thinking_board_id: <page ID>
141
- task_page_id: <page ID of the affected task>
142
-
143
- QUESTION:
144
- <specific question or problem to investigate>
145
-
146
- CONTEXT:
147
- <execution report, reviewer findings, human comments, or other relevant context>
148
-
149
- Research the issue, explore the codebase, and return an INVESTIGATION_REPORT.
150
- Do NOT modify Notion - just return the report.
151
- \`\`\`
152
-
153
- #### For Task Refinement (REFINE_TASK)
154
-
155
- Used when a task specification needs updating based on feedback. Spawn a \`notion-thinker\` subagent with:
156
-
157
- \`\`\`
158
- You are being dispatched to refine a task specification.
159
-
160
- DISPATCH_TYPE: REFINE_TASK
161
-
162
- BOARD_CONTEXT:
163
- thinking_board_id: <page ID>
164
- task_page_id: <page ID of the task to refine>
165
-
166
- FEEDBACK:
167
- <execution report, reviewer findings, or human comments>
168
-
169
- CURRENT_SPECIFICATION:
170
- <full current task page content>
171
-
172
- Research the issue and return a REFINEMENT_REPORT with the updated specification.
173
- Do NOT modify Notion - just return the report.
174
- \`\`\`
241
+ #### REFINE_TASK
242
+ Update a task specification based on feedback.
243
+ ${formatThinkerDispatch("REFINE_TASK")}
175
244
 
176
245
  ### Processing the Thinker's Planning Report
177
246
 
@@ -183,20 +252,7 @@ Create a sub-page under the Thinking Board with the feature title. Write the \`f
183
252
 
184
253
  #### Step 2 \u2014 Create the Kanban Database
185
254
 
186
- Create a separate database as a child of the Thinking Board (sibling to the feature page, not inline). Use this schema:
187
-
188
- \`\`\`sql
189
- CREATE TABLE (
190
- "Task" TITLE,
191
- "Status" SELECT('Backlog':default, 'To Do':blue, 'In Progress':yellow, 'Needs Human Input':red, 'In Test':orange, 'Human Review':purple, 'Done':green),
192
- "Priority" SELECT('Critical':red, 'High':orange, 'Medium':yellow, 'Low':green),
193
- "Depends On" RICH_TEXT,
194
- "Complexity" SELECT('Small':green, 'Medium':yellow, 'Large':red),
195
- "Notes" RICH_TEXT
196
- )
197
- \`\`\`
198
-
199
- Create a **Board view** grouped by \`"Status"\`. Add a link to the database on the feature page so they are connected.
255
+ Create a separate database as a child of the Thinking Board (sibling to the feature page, not inline). Use the schema from the Kanban Database Schema section above. Create a **Board view** grouped by \`"Status"\`. Add a link to the database on the feature page.
200
256
 
201
257
  #### Step 3 \u2014 Populate Task Tickets
202
258
 
@@ -451,14 +507,7 @@ You will be invoked with task context from the orchestrator. The payload may inc
451
507
  - Parent task intent overrides sibling assumptions.
452
508
  - If unresolved, report ambiguity clearly.
453
509
 
454
- ## Board Permissions
455
-
456
- You have **limited** board access:
457
- - **Allowed:** Read board/ticket context needed for implementation.
458
- - **Allowed:** Write implementation notes on the assigned ticket page (findings, progress notes, execution summary, blocker notes).
459
- - **Forbidden:** Moving tasks between statuses. Only the orchestrator (\`notion-agent-hive\`) handles status transitions.
460
- - **Forbidden:** Creating or deleting tickets.
461
- - **Forbidden:** Scanning the board to decide what to do next. Task routing belongs to the orchestrator.
510
+ ${getBoardPermissionsBlock("executor")}
462
511
 
463
512
  ## Execution Workflow
464
513
 
@@ -523,13 +572,7 @@ You are not checking boxes. You are evaluating:
523
572
 
524
573
  You are the last line of defense before code reaches human review. Take that responsibility seriously.
525
574
 
526
- ## Board Permissions
527
-
528
- You have **limited** board access:
529
- - **Allowed:** Move a task from \`In Test\` \u2192 \`Human Review\` when all checks pass.
530
- - **Forbidden:** Moving tasks to \`Done\`. Only the human user may do this.
531
- - **Forbidden:** Moving tasks to \`To Do\` or \`In Progress\`. Report failures back to the Thinker and it will handle rework transitions.
532
- - **Forbidden:** Creating or deleting tickets. Only the Thinker may do this.
575
+ ${getBoardPermissionsBlock("reviewer")}
533
576
 
534
577
  ## Inputs
535
578
 
package/package.json CHANGED
@@ -1,6 +1,11 @@
1
1
  {
2
2
  "name": "@tesselate-digital/notion-agent-hive",
3
- "version": "0.0.4",
3
+ "version": "0.0.8",
4
+ "provenance": true,
5
+ "repository": {
6
+ "type": "git",
7
+ "url": "https://github.com/tessellate-digital/notion-agent-hive"
8
+ },
4
9
  "type": "module",
5
10
  "main": "dist/index.js",
6
11
  "types": "dist/index.d.ts",
@@ -13,6 +18,10 @@
13
18
  "README.md",
14
19
  "LICENSE"
15
20
  ],
21
+ "publishConfig": {
22
+ "access": "public",
23
+ "provenance": true
24
+ },
16
25
  "scripts": {
17
26
  "build": "bun build src/index.ts --outdir dist --target bun --format esm && bun build src/cli/index.ts --outdir dist/cli --target bun --format esm && tsc --emitDeclarationOnly",
18
27
  "test": "bun test",