coaia-visualizer 1.6.3 β†’ 1.6.4

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 (46) hide show
  1. package/Dockerfile +61 -0
  2. package/Dockerfile.app +50 -0
  3. package/cli.ts +11 -5
  4. package/components/chart-detail-editable.tsx +2 -0
  5. package/components/chart-detail.tsx +6 -1
  6. package/components/edit-action-step.tsx +2 -0
  7. package/components/github-provenance.tsx +226 -0
  8. package/components/relation-graph.tsx +91 -27
  9. package/dist/cli.js +9 -5
  10. package/docker-build-push.sh +20 -0
  11. package/docker-entrypoint.sh +27 -0
  12. package/index.tsx +26 -0
  13. package/lib/chart-editor.ts +3 -3
  14. package/lib/github-provenance.ts +316 -0
  15. package/lib/jsonl-parser.ts +2 -2
  16. package/lib/types.ts +15 -2
  17. package/mcp/test_mcp/.gemini/settings.json +18 -0
  18. package/package.json +14 -13
  19. package/rispecs/README.md +170 -0
  20. package/rispecs/accountability-responsibility.rispec.md +110 -0
  21. package/rispecs/api-mcp-interface.spec.md +287 -0
  22. package/rispecs/app.spec.md +364 -0
  23. package/rispecs/chart-editing-workflow.spec.md +297 -0
  24. package/rispecs/chart-visualization-hierarchy.spec.md +235 -0
  25. package/rispecs/cli-mode.spec.md +224 -0
  26. package/rispecs/github-project-runtime-memory-integration.spec.md +381 -0
  27. package/rispecs/jsonl-parsing-data-types.spec.md +243 -0
  28. package/rispecs/narrative-beats-display.spec.md +189 -0
  29. package/rispecs/pde-integration.spec.md +280 -0
  30. package/rispecs/planning-integration.spec.md +329 -0
  31. package/rispecs/relation-graph-visualization.spec.md +171 -0
  32. package/rispecs/relation-to-mcp-structural-thinking.kin.md +65 -0
  33. package/rispecs/ui-component-library.spec.md +258 -0
  34. package/mcp/dist/api-client.d.ts +0 -138
  35. package/mcp/dist/api-client.d.ts.map +0 -1
  36. package/mcp/dist/api-client.js +0 -115
  37. package/mcp/dist/api-client.js.map +0 -1
  38. package/mcp/dist/index.d.ts +0 -2
  39. package/mcp/dist/index.d.ts.map +0 -1
  40. package/mcp/dist/index.js +0 -286
  41. package/mcp/dist/index.js.map +0 -1
  42. package/mcp/dist/tools/index.d.ts +0 -18
  43. package/mcp/dist/tools/index.d.ts.map +0 -1
  44. package/mcp/dist/tools/index.js +0 -322
  45. package/mcp/dist/tools/index.js.map +0 -1
  46. package/mcp/package-lock.json +0 -210
@@ -0,0 +1,110 @@
1
+ # RISPEC: Accountability & Responsibility Rendering in coaia-visualizer
2
+
3
+ > How the visualizer displays accountability and responsibility distinctions in Structural Tension Charts
4
+
5
+ ## 🎯 What This Enables Users to Create
6
+
7
+ - Visual clarity on who holds accountability for chart outcomes
8
+ - Inline responsibility attribution on action steps
9
+ - Delegation chain awareness across chart hierarchies
10
+ - Filtered views by responsible entity type (human / AI / pair)
11
+
12
+ ## Current Reality
13
+
14
+ `coaia-visualizer` renders STCs from coaia-narrative JSONL. It shows chart components (desired outcome, current reality, action steps), telescoping navigation, and completion status. There is no visual representation of:
15
+ - Who is accountable for a chart's desired outcome
16
+ - Who is responsible for each action step
17
+ - The delegation chain between them
18
+
19
+ ## Desired Result
20
+
21
+ The visualizer renders accountability and responsibility as first-class visual elements:
22
+ - **Chart header**: shows the accountable entity with a distinct badge
23
+ - **Action steps**: show responsible entity/entities inline
24
+ - **Delegation view**: optional view showing the accountability→responsibility chain
25
+
26
+ ## UI Components
27
+
28
+ ### Chart Header β€” Accountability Badge
29
+
30
+ ```
31
+ β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”
32
+ β”‚ 🎯 Deploy PDE across all variants β”‚
33
+ β”‚ β—‰ Accountable: jgi (human) β”‚
34
+ β”‚ Due: 2026-03-21 β”‚
35
+ β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜
36
+ ```
37
+
38
+ - `β—‰` icon distinguishes accountability from responsibility
39
+ - Color-coded by `accountableEntityType`: human (blue), ai_companion (purple), team_lead (green)
40
+ - Click to view accountability context
41
+
42
+ ### Action Steps β€” Responsibility Indicators
43
+
44
+ ```
45
+ β–‘ Audit mcp-pde implementation β†’ mia, sub-agent:south
46
+ β–‘ Update coaia-pde stc-mapper β†’ mia
47
+ β–  Research IAIP reference format β†’ sub-agent:south βœ“ completedBy: south-3
48
+ ```
49
+
50
+ - Responsible entities shown inline, right-aligned
51
+ - `pair` type shows both entities with a link icon
52
+ - Completed steps show `completedBy` if different from responsible
53
+
54
+ ### Delegation Chain View (Optional Panel)
55
+
56
+ ```
57
+ jgi (accountable)
58
+ β”œβ”€β”€ delegates β†’ mia (NORTH actions)
59
+ β”œβ”€β”€ delegates β†’ sub-agent:south (SOUTH actions)
60
+ β”œβ”€β”€ co-holds β†’ jgi + miette (WEST actions)
61
+ └── retains β†’ jgi (EAST actions)
62
+ ```
63
+
64
+ ### Filter/Group Controls
65
+
66
+ - Filter action steps by responsible entity
67
+ - Group by responsibility type (human / AI / pair)
68
+ - Highlight items where responsibility β‰  completed-by (delegation shift)
69
+
70
+ ## Schema Consumption
71
+
72
+ Reads from Entity.metadata:
73
+
74
+ ```typescript
75
+ // Chart entity
76
+ metadata.accountability?.accountableEntity
77
+ metadata.accountability?.accountableEntityType
78
+ metadata.accountability?.accountabilityContext
79
+
80
+ // Action step entity
81
+ metadata.responsibility?.responsibleEntities
82
+ metadata.responsibility?.responsibilityType
83
+ metadata.responsibility?.delegatedFrom
84
+ metadata.assignedTo // backward compat fallback
85
+ ```
86
+
87
+ ## Backward Compatibility
88
+
89
+ When `accountability` / `responsibility` fields are absent:
90
+ - Chart header shows no accountability badge (no default assumption)
91
+ - Action steps show no responsibility indicator
92
+ - Existing charts render identically to current behavior
93
+
94
+ ## Dependency
95
+
96
+ - Canonical schema: `coaia-narrative/rispecs/accountability-responsibility-distinction.rispec.md`
97
+ - Data source: coaia-narrative JSONL with Entity.metadata extensions
98
+
99
+ ## Priority
100
+
101
+ Medium β€” rendering follows schema. Implement after coaia-narrative schema extension is merged.
102
+
103
+ ---
104
+
105
+ ## πŸ”— Related Components
106
+
107
+ - [chart-visualization-hierarchy.spec.md](./chart-visualization-hierarchy.spec.md) β€” ChartDetail/ChartDetailEditable host accountability badges in header
108
+ - [chart-editing-workflow.spec.md](./chart-editing-workflow.spec.md) β€” EditActionStep would need responsibility indicator integration
109
+ - [jsonl-parsing-data-types.spec.md](./jsonl-parsing-data-types.spec.md) β€” EntityRecord metadata extensions for accountability/responsibility fields
110
+ - [api-mcp-interface.spec.md](./api-mcp-interface.spec.md) β€” API routes would need to support accountability/responsibility updates
@@ -0,0 +1,287 @@
1
+ # API & MCP Interface
2
+ ## RISE Specification for REST API, MCP Server, and Agent Access Patterns
3
+
4
+ **Component Purpose**: Provide complete programmatic access to structural tension chart operations via REST API endpoints and a 15-tool MCP server, enabling AI agents and external tools to create, read, update, and delete charts with the same fidelity as the web UI.
5
+
6
+ **Source Files**: `app/api/**/*.ts`, `mcp/src/index.ts`, `mcp/src/tools/index.ts`, `mcp/src/api-client.ts`, `lib/api-auth.ts`
7
+
8
+ ---
9
+
10
+ ## 🎯 What This Component Enables Users to Create
11
+
12
+ - AI agent workflows that manage structural tension charts programmatically
13
+ - Automated chart creation from Claude, GPT, or any MCP-compatible agent
14
+ - External tool integrations via standard REST API calls
15
+ - Secure multi-user access with token-based authentication
16
+ - Live data synchronization between web UI and agent sessions
17
+
18
+ ---
19
+
20
+ ## 🌊 Structural Tension Dynamics
21
+
22
+ ### Current Reality
23
+ coaia-narrative stores data as JSONL files on disk. Without an API layer, agents must read/write files directly, parse JSONL manually, and implement their own chart assembly logic. The MCP protocol exists but needs a server that maps chart operations to tool definitions.
24
+
25
+ ### Desired Result
26
+ A complete API surface where:
27
+ - 6 REST route groups expose all chart operations
28
+ - 15 MCP tools provide agent-native access
29
+ - Bearer token authentication protects all mutating endpoints
30
+ - Every write operation creates a timestamped backup
31
+ - Response formats are consistent (JSON with error/success patterns)
32
+
33
+ ### Natural Resolution
34
+ The REST API implements chart operations using `ChartEditor` and JSONL parsing. The MCP server wraps the REST API via `CoaiaVisualizerClient`, translating tool calls into HTTP requests. Both share the same authentication layer.
35
+
36
+ ---
37
+
38
+ ## πŸ“‹ Authentication (`lib/api-auth.ts`)
39
+
40
+ ### Token Resolution
41
+ ```
42
+ 1. Check COAIAN_API_TOKEN environment variable
43
+ 2. If set β†’ use as API token
44
+ 3. If not set β†’ generate random 64-char hex token (crypto.randomBytes(32))
45
+ 4. Cache generated token for process lifetime
46
+ 5. Log generated token to console with warning (development convenience)
47
+ ```
48
+
49
+ ### Request Validation
50
+ ```typescript
51
+ validateApiToken(request: NextRequest): boolean
52
+ 1. Extract Authorization header
53
+ 2. Match regex /^Bearer\s+(.+)$/
54
+ 3. Compare extracted token against getApiToken()
55
+ 4. Return true only if match
56
+ ```
57
+
58
+ ### Middleware Pattern
59
+ ```typescript
60
+ withAuth(handler): wrappedHandler
61
+ 1. Call validateApiToken(request)
62
+ 2. If invalid β†’ return 401 { error: "Unauthorized" }
63
+ 3. If valid β†’ delegate to handler(request, context)
64
+ ```
65
+
66
+ ### Response Helpers
67
+ - `successResponse(data, status=200)` β†’ `NextResponse.json(data, { status })`
68
+ - `errorResponse(message, status=400)` β†’ `NextResponse.json({ error: message }, { status })`
69
+ - `unauthorizedResponse()` β†’ 401 with explanation message
70
+
71
+ ---
72
+
73
+ ## πŸ“‹ REST API Routes
74
+
75
+ ### GET /api/charts β€” List Charts
76
+ **Auth**: Required (withAuth)
77
+ **Query Params**:
78
+ - `level` β€” Filter by chart depth (number)
79
+ - `rootOnly` β€” Return only level-0 charts (boolean)
80
+
81
+ **Response**: `{ charts: Chart[], total: number, memoryPath: string }`
82
+
83
+ ### POST /api/charts β€” Create Chart
84
+ **Auth**: Required (withAuth)
85
+ **Body**:
86
+ ```json
87
+ {
88
+ "desiredOutcome": "string (required)",
89
+ "currentReality": "string (required)",
90
+ "dueDate": "ISO date string (optional)",
91
+ "parentChartId": "string (optional, for sub-charts)"
92
+ }
93
+ ```
94
+ **Behavior**:
95
+ 1. Generate new chart_N ID (max existing + 1)
96
+ 2. Create 3 entities: chart, desired_outcome, current_reality
97
+ 3. Create 3 relations: contains (Γ—2), creates_tension_with
98
+ 4. If parentChartId: create parent→child contains relation
99
+ 5. Create timestamped backup of existing file
100
+ 6. Write updated JSONL
101
+
102
+ **Response**: `{ chartId: string, message: string, backup: string }`
103
+
104
+ ### GET /api/charts/[id] β€” Get Chart
105
+ **Auth**: Required
106
+ **Response**: Full Chart object with all properties
107
+
108
+ ### POST /api/charts/[id] β€” Update Chart
109
+ **Auth**: Required
110
+ **Body**: Object with one or more update operations:
111
+
112
+ | Operation | Fields | Effect |
113
+ |:---|:---|:---|
114
+ | `updateDesiredOutcome` | `{ text: string }` | Replace desired outcome |
115
+ | `addCurrentRealityObservation` | `{ observation: string }` | Add observation |
116
+ | `updateCurrentReality` | `{ observations: string[] }` | Replace observations |
117
+ | `updateCurrentRealityObservation` | `{ index, text }` | Update specific observation |
118
+ | `deleteCurrentRealityObservation` | `{ index }` | Remove observation |
119
+ | `addActionStep` | `{ title, currentReality, dueDate? }` | Create telescoped action |
120
+ | `updateActionStep` | `{ actionName, description }` | Update action text |
121
+ | `toggleActionCompletion` | `{ actionName }` | Toggle done status |
122
+ | `markActionComplete` | `{ actionStepName }` | Complete + update parent |
123
+ | `updateActionProgress` | `{ actionStepName, observation, updateReality? }` | Add progress |
124
+ | `updateActionDueDate` | `{ actionName, dueDate }` | Change action date |
125
+ | `deleteActionStep` | `{ actionName }` | Remove action |
126
+ | `createTelescopedChart` | `{ actionName }` | Convert action to sub-chart |
127
+ | `updateDueDate` | `{ dueDate }` | Change chart date |
128
+
129
+ **Response**: `{ chart: Chart, updates: string[], backup: string, message: string }`
130
+
131
+ ### DELETE /api/charts/[id] β€” Delete Chart
132
+ **Auth**: Required
133
+ **Behavior**: Recursively deletes chart + all sub-charts, their entities, and all related relations
134
+ **Response**: `{ message: string, deletedEntities: string[], backup: string }`
135
+
136
+ ### GET /api/charts/search β€” Search Charts
137
+ **Auth**: Required
138
+ **Query Params**:
139
+ - `q` β€” Text search (case-insensitive, searches outcomes/reality/actions)
140
+ - `level` β€” Filter by depth
141
+ - `completed` β€” Boolean: all actions done?
142
+ - `hasActions` β€” Boolean: has action steps?
143
+
144
+ **Response**: `{ charts: Chart[], total: number, query: { q, level, completed, hasActions } }`
145
+
146
+ ### GET /api/jsonl β€” Read Memory File
147
+ **Auth**: Not required
148
+ **Dependency**: Requires `COAIAV_MEMORY_PATH` environment variable to locate the JSONL file on disk
149
+ **Filename Resolution**: Uses `COAIAV_MEMORY_DISPLAY_NAME` if set, otherwise falls back to `path.basename(COAIAV_MEMORY_PATH)`. This preserves the original filename when Docker remaps paths to `/data/memory.jsonl`.
150
+ **Response**: `{ content: string, filename: string, path: string }`
151
+
152
+ ### POST /api/jsonl β€” Write Memory File
153
+ **Auth**: Not required
154
+ **Body**: `{ content: string }`
155
+ **Behavior**: Creates timestamped backup, writes new content
156
+ **Response**: `{ success: true, backupPath: string }`
157
+
158
+ ### GET /api/watch β€” File Statistics
159
+ **Auth**: Not required
160
+ **Response**: `{ lastModified: number, beatCount: number, fileSize: number, totalRecords: number }`
161
+ **Purpose**: Support live polling for file change detection
162
+
163
+ ### GET /api/audio/[filename] β€” Serve Audio
164
+ **Auth**: Not required
165
+ **Security**: Only serves `.mp3` files from `COAIAV_AUDIO_DIR`
166
+ **Response**: Binary MP3 with 1-year cache header
167
+
168
+ ---
169
+
170
+ ## πŸ“‹ MCP Server (`mcp/`)
171
+
172
+ ### Configuration
173
+ - **Transport**: stdio (standard input/output)
174
+ - **API Base URL**: `COAIAV_API_URL` env var (default fallback: `http://localhost:3000`)
175
+ - **Token**: `COAIAN_API_TOKEN` env var (required β€” server refuses to start without it)
176
+
177
+ ### 15 MCP Tools
178
+
179
+ | # | Tool Name | Required Args | Optional Args | Maps To |
180
+ |:---|:---|:---|:---|:---|
181
+ | 1 | `list_charts` | β€” | level, rootOnly | GET /api/charts |
182
+ | 2 | `get_chart` | chartId | β€” | GET /api/charts/{id} |
183
+ | 3 | `create_chart` | desiredOutcome, currentReality | dueDate, parentChartId | POST /api/charts |
184
+ | 4 | `update_chart` | chartId | desiredOutcome, currentReality, dueDate | POST /api/charts/{id} |
185
+ | 5 | `add_action_step` | parentChartId, actionStepTitle, currentReality | dueDate | POST /api/charts/{id} |
186
+ | 6 | `update_action_step` | chartId, actionName, description | β€” | POST /api/charts/{id} |
187
+ | 7 | `mark_action_complete` | chartId, actionStepName | β€” | POST /api/charts/{id} |
188
+ | 8 | `update_action_progress` | chartId, actionStepName, progressObservation | updateCurrentReality | POST /api/charts/{id} |
189
+ | 9 | `update_current_reality` | chartId, newObservations | β€” | POST /api/charts/{id} |
190
+ | 10 | `toggle_action_completion` | chartId, actionName | β€” | POST /api/charts/{id} |
191
+ | 11 | `delete_action_step` | chartId, actionName | β€” | POST /api/charts/{id} |
192
+ | 12 | `create_telescoped_chart` | chartId, actionName | β€” | POST /api/charts/{id} |
193
+ | 13 | `delete_chart` | chartId | β€” | DELETE /api/charts/{id} |
194
+ | 14 | `search_charts` | β€” | query, level, completed, hasActions | GET /api/charts/search |
195
+ | 15 | `get_chart_progress` | chartId | β€” | GET /api/charts/{id} + compute |
196
+
197
+ ### Tool Response Format
198
+ ```json
199
+ {
200
+ "content": [{ "type": "text", "text": "JSON string of response data" }],
201
+ "isError": false
202
+ }
203
+ ```
204
+ Error responses set `isError: true` with error message in text field.
205
+
206
+ ### CoaiaVisualizerClient (`mcp/src/api-client.ts`)
207
+ HTTP wrapper class used by the MCP server.
208
+
209
+ > **Note**: The client uses a simplified `Chart` type (plain objects, not full `EntityRecord` instances). Entity names returned by the API may differ from those used internally by `ChartEditor` (e.g., API route params use `chartId` while ChartEditor methods reference `chart.chartEntity.name`).
210
+
211
+ ```typescript
212
+ class CoaiaVisualizerClient {
213
+ constructor(config: { baseUrl: string, token: string })
214
+
215
+ listCharts(options?): Promise<Chart[]>
216
+ getChart(id: string): Promise<Chart>
217
+ createChart(data): Promise<{ chartId: string }>
218
+ updateChart(id, updates): Promise<Chart>
219
+ createTelescopedChart(chartId, actionName): Promise<Chart>
220
+ deleteChart(id): Promise<void>
221
+ searchCharts(query): Promise<Chart[]>
222
+ getChartProgress(chart): number // Local computation
223
+ getChartSummary(chart): string // Local computation (100 char truncate)
224
+ }
225
+ ```
226
+
227
+ ---
228
+
229
+ ## πŸ“‹ Agent Access Scenario
230
+
231
+ ### Claude Desktop Configuration
232
+ ```json
233
+ {
234
+ "mcpServers": {
235
+ "coaia-visualizer": {
236
+ "command": "node",
237
+ "args": ["path/to/mcp/dist/index.js"],
238
+ "env": {
239
+ "COAIAN_API_TOKEN": "your-token-here",
240
+ "COAIAV_API_URL": "http://localhost:3000"
241
+ }
242
+ }
243
+ }
244
+ }
245
+ ```
246
+
247
+ ### Typical Agent Session
248
+ ```
249
+ 1. Agent calls list_charts β†’ gets all chart summaries
250
+ 2. Agent calls get_chart(chartId) β†’ gets full detail
251
+ 3. Agent calls update_current_reality β†’ adds new observations
252
+ 4. Agent calls add_action_step β†’ creates telescoped sub-chart
253
+ 5. Agent calls mark_action_complete β†’ action done + parent updated
254
+ 6. Agent calls get_chart_progress β†’ checks advancement percentage
255
+ ```
256
+
257
+ ---
258
+
259
+ ## βœ… Quality Criteria
260
+
261
+ βœ… **API Completeness**
262
+ - Every operation available in the web UI is also available via API
263
+ - 15 MCP tools cover all chart lifecycle operations
264
+ - Search supports text, level, completion, and action filters
265
+
266
+ βœ… **Authentication Security**
267
+ - All chart mutation endpoints require Bearer token
268
+ - Token from environment variable or auto-generated
269
+ - Consistent 401 response for unauthorized requests
270
+
271
+ βœ… **Data Safety**
272
+ - Timestamped backup created before every write
273
+ - Recursive deletion handles sub-chart cascades
274
+ - Error responses include descriptive messages
275
+
276
+ βœ… **Agent Ergonomics**
277
+ - All responses are JSON (parseable by agents)
278
+ - Tool descriptions include required/optional parameter documentation
279
+ - MCP tools use JSON Schema inputSchema for parameter validation
280
+
281
+ ---
282
+
283
+ ## πŸ”— Related Components
284
+
285
+ - [chart-editing-workflow.spec.md](./chart-editing-workflow.spec.md) β€” ChartEditor class used by API routes
286
+ - [jsonl-parsing-data-types.spec.md](./jsonl-parsing-data-types.spec.md) β€” types shared between API and client
287
+ - [cli-mode.spec.md](./cli-mode.spec.md) β€” CLI starts the server that API routes run on