coaia-visualizer 1.6.3 → 1.6.5
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/Dockerfile +61 -0
- package/Dockerfile.app +50 -0
- package/README.md +2 -1
- package/cli.ts +11 -5
- package/components/asterion-foundation-card.tsx +175 -0
- package/components/asterion-session-context-badge.tsx +122 -0
- package/components/asterion-session-lineage-card.tsx +119 -0
- package/components/chart-detail-editable.tsx +2 -0
- package/components/chart-detail.tsx +9 -1
- package/components/edit-action-step.tsx +2 -0
- package/components/github-provenance.tsx +226 -0
- package/components/metadata-projections.tsx +50 -16
- package/components/narrative-beats.tsx +16 -3
- package/components/relation-graph.tsx +91 -27
- package/dist/cli.js +9 -5
- package/docker-build-push.sh +20 -0
- package/docker-entrypoint.sh +27 -0
- package/index.tsx +39 -2
- package/lib/asterion-metadata.ts +673 -0
- package/lib/chart-editor.ts +8 -3
- package/lib/github-provenance.ts +316 -0
- package/lib/jsonl-parser.ts +7 -2
- package/lib/types.ts +112 -2
- package/mcp/test_mcp/.gemini/settings.json +18 -0
- package/next-env.d.ts +1 -1
- package/package.json +14 -13
- package/rispecs/README.md +170 -0
- package/rispecs/accountability-responsibility.rispec.md +110 -0
- package/rispecs/api-mcp-interface.spec.md +287 -0
- package/rispecs/app.spec.md +364 -0
- package/rispecs/chart-editing-workflow.spec.md +297 -0
- package/rispecs/chart-visualization-hierarchy.spec.md +235 -0
- package/rispecs/cli-mode.spec.md +224 -0
- package/rispecs/github-project-runtime-memory-integration.spec.md +381 -0
- package/rispecs/jsonl-parsing-data-types.spec.md +243 -0
- package/rispecs/narrative-beats-display.spec.md +189 -0
- package/rispecs/pde-integration.spec.md +280 -0
- package/rispecs/planning-integration.spec.md +329 -0
- package/rispecs/relation-graph-visualization.spec.md +171 -0
- package/rispecs/relation-to-mcp-structural-thinking.kin.md +65 -0
- package/rispecs/ui-component-library.spec.md +258 -0
- package/mcp/dist/api-client.d.ts +0 -138
- package/mcp/dist/api-client.d.ts.map +0 -1
- package/mcp/dist/api-client.js +0 -115
- package/mcp/dist/api-client.js.map +0 -1
- package/mcp/dist/index.d.ts +0 -2
- package/mcp/dist/index.d.ts.map +0 -1
- package/mcp/dist/index.js +0 -286
- package/mcp/dist/index.js.map +0 -1
- package/mcp/dist/tools/index.d.ts +0 -18
- package/mcp/dist/tools/index.d.ts.map +0 -1
- package/mcp/dist/tools/index.js +0 -322
- package/mcp/dist/tools/index.js.map +0 -1
- package/mcp/package-lock.json +0 -210
|
@@ -0,0 +1,316 @@
|
|
|
1
|
+
import type { EntityRecord, RelationRecord } from "./types.ts"
|
|
2
|
+
|
|
3
|
+
export const GITHUB_SYNC_STATES = ["synced", "diverged", "conflict", "project-only", "chart-only"] as const
|
|
4
|
+
|
|
5
|
+
export type GithubSyncState = (typeof GITHUB_SYNC_STATES)[number]
|
|
6
|
+
|
|
7
|
+
export interface GithubIssueRef {
|
|
8
|
+
owner: string
|
|
9
|
+
repo: string
|
|
10
|
+
number: number
|
|
11
|
+
nodeId?: string
|
|
12
|
+
url?: string
|
|
13
|
+
}
|
|
14
|
+
|
|
15
|
+
export interface GithubProjectItemRef {
|
|
16
|
+
projectOwner?: string
|
|
17
|
+
projectNumber?: number
|
|
18
|
+
projectTitle?: string
|
|
19
|
+
itemId?: string
|
|
20
|
+
projectId?: string
|
|
21
|
+
url?: string
|
|
22
|
+
fields?: Record<string, unknown>
|
|
23
|
+
fieldValues?: Record<string, unknown>
|
|
24
|
+
projectFields?: Record<string, unknown>
|
|
25
|
+
[key: string]: unknown
|
|
26
|
+
}
|
|
27
|
+
|
|
28
|
+
export interface GithubSourceProvenance {
|
|
29
|
+
system?: string
|
|
30
|
+
toolName?: string
|
|
31
|
+
sessionId?: string
|
|
32
|
+
createdAt?: string
|
|
33
|
+
version?: string
|
|
34
|
+
[key: string]: unknown
|
|
35
|
+
}
|
|
36
|
+
|
|
37
|
+
export interface GithubEntityProvenance {
|
|
38
|
+
issue?: GithubIssueRef
|
|
39
|
+
projectItems: GithubProjectItemRef[]
|
|
40
|
+
syncState?: GithubSyncState
|
|
41
|
+
lastSyncedAt?: string
|
|
42
|
+
source?: GithubSourceProvenance
|
|
43
|
+
hasGithubMetadata: boolean
|
|
44
|
+
}
|
|
45
|
+
|
|
46
|
+
export interface GithubProjectFieldEntry {
|
|
47
|
+
key: string
|
|
48
|
+
label: string
|
|
49
|
+
value: string
|
|
50
|
+
}
|
|
51
|
+
|
|
52
|
+
export const GITHUB_PROJECT_FIELD_KEYS = [
|
|
53
|
+
"goal",
|
|
54
|
+
"current_reality",
|
|
55
|
+
"observations",
|
|
56
|
+
"question",
|
|
57
|
+
"Status",
|
|
58
|
+
"phase",
|
|
59
|
+
"session_id",
|
|
60
|
+
"four_dir_east",
|
|
61
|
+
"four_dir_south",
|
|
62
|
+
"four_dir_west",
|
|
63
|
+
"four_dir_north",
|
|
64
|
+
"relational_assessed",
|
|
65
|
+
"relational_principles",
|
|
66
|
+
] as const
|
|
67
|
+
|
|
68
|
+
export const GITHUB_BRIDGE_RELATION_TYPES = ["synced_to_github", "linked_to_issue", "project_lens_of"] as const
|
|
69
|
+
|
|
70
|
+
export type GithubBridgeRelationType = (typeof GITHUB_BRIDGE_RELATION_TYPES)[number]
|
|
71
|
+
|
|
72
|
+
const PROJECT_FIELD_LABELS: Record<string, string> = {
|
|
73
|
+
goal: "goal",
|
|
74
|
+
current_reality: "current reality",
|
|
75
|
+
observations: "observations",
|
|
76
|
+
question: "question",
|
|
77
|
+
Status: "Status",
|
|
78
|
+
phase: "phase",
|
|
79
|
+
session_id: "session",
|
|
80
|
+
four_dir_east: "East",
|
|
81
|
+
four_dir_south: "South",
|
|
82
|
+
four_dir_west: "West",
|
|
83
|
+
four_dir_north: "North",
|
|
84
|
+
relational_assessed: "relational assessed",
|
|
85
|
+
relational_principles: "relational principles",
|
|
86
|
+
}
|
|
87
|
+
|
|
88
|
+
function isRecord(value: unknown): value is Record<string, unknown> {
|
|
89
|
+
return typeof value === "object" && value !== null && !Array.isArray(value)
|
|
90
|
+
}
|
|
91
|
+
|
|
92
|
+
function firstString(...values: unknown[]): string | undefined {
|
|
93
|
+
for (const value of values) {
|
|
94
|
+
if (typeof value === "string" && value.trim()) {
|
|
95
|
+
return value.trim()
|
|
96
|
+
}
|
|
97
|
+
}
|
|
98
|
+
}
|
|
99
|
+
|
|
100
|
+
function firstNumber(...values: unknown[]): number | undefined {
|
|
101
|
+
for (const value of values) {
|
|
102
|
+
if (typeof value === "number" && Number.isFinite(value)) {
|
|
103
|
+
return value
|
|
104
|
+
}
|
|
105
|
+
if (typeof value === "string" && value.trim()) {
|
|
106
|
+
const parsed = Number(value)
|
|
107
|
+
if (Number.isFinite(parsed)) {
|
|
108
|
+
return parsed
|
|
109
|
+
}
|
|
110
|
+
}
|
|
111
|
+
}
|
|
112
|
+
}
|
|
113
|
+
|
|
114
|
+
function normalizeIssueCandidate(candidate: unknown): GithubIssueRef | undefined {
|
|
115
|
+
if (!isRecord(candidate)) return undefined
|
|
116
|
+
|
|
117
|
+
const owner = firstString(candidate.owner, candidate.ownerLogin, candidate.repositoryOwner)
|
|
118
|
+
const repo = firstString(candidate.repo, candidate.repository, candidate.repositoryName)
|
|
119
|
+
const number = firstNumber(candidate.number, candidate.issue_number, candidate.issueNumber, candidate.issue)
|
|
120
|
+
|
|
121
|
+
if (!owner || !repo || !number) return undefined
|
|
122
|
+
|
|
123
|
+
return {
|
|
124
|
+
owner,
|
|
125
|
+
repo,
|
|
126
|
+
number,
|
|
127
|
+
nodeId: firstString(candidate.nodeId, candidate.node_id),
|
|
128
|
+
url: firstString(candidate.url, candidate.html_url) ?? `https://github.com/${owner}/${repo}/issues/${number}`,
|
|
129
|
+
}
|
|
130
|
+
}
|
|
131
|
+
|
|
132
|
+
function normalizeProjectItemCandidate(candidate: unknown, fallbackOwner?: string): GithubProjectItemRef | undefined {
|
|
133
|
+
if (!isRecord(candidate)) return undefined
|
|
134
|
+
|
|
135
|
+
const projectOwner = firstString(candidate.projectOwner, candidate.owner, candidate.ownerLogin, fallbackOwner)
|
|
136
|
+
const projectNumber = firstNumber(candidate.projectNumber, candidate.project_number, candidate.number)
|
|
137
|
+
const itemId = firstString(candidate.itemId, candidate.item_id, candidate.projectItemId, candidate.project_id)
|
|
138
|
+
const projectId = firstString(candidate.projectId, candidate.project_id)
|
|
139
|
+
const projectTitle = firstString(candidate.projectTitle, candidate.title, candidate.project)
|
|
140
|
+
const url = firstString(candidate.url)
|
|
141
|
+
|
|
142
|
+
if (!projectOwner && !projectNumber && !itemId && !projectId && !projectTitle && !url) {
|
|
143
|
+
return undefined
|
|
144
|
+
}
|
|
145
|
+
|
|
146
|
+
return {
|
|
147
|
+
...candidate,
|
|
148
|
+
projectOwner,
|
|
149
|
+
projectNumber,
|
|
150
|
+
projectTitle,
|
|
151
|
+
itemId,
|
|
152
|
+
projectId,
|
|
153
|
+
url,
|
|
154
|
+
}
|
|
155
|
+
}
|
|
156
|
+
|
|
157
|
+
export function getGithubIssueRef(entity?: EntityRecord): GithubIssueRef | undefined {
|
|
158
|
+
if (!entity) return undefined
|
|
159
|
+
|
|
160
|
+
const metadata = entity.metadata ?? {}
|
|
161
|
+
const github = isRecord(metadata.github) ? metadata.github : undefined
|
|
162
|
+
const syncTarget = isRecord(metadata.sync_target) ? metadata.sync_target : undefined
|
|
163
|
+
const githubRef = isRecord(metadata.github_ref) ? metadata.github_ref : undefined
|
|
164
|
+
|
|
165
|
+
return normalizeIssueCandidate(github?.issue) ?? normalizeIssueCandidate(syncTarget) ?? normalizeIssueCandidate(githubRef)
|
|
166
|
+
}
|
|
167
|
+
|
|
168
|
+
export function getGithubProjectItems(entity?: EntityRecord): GithubProjectItemRef[] {
|
|
169
|
+
if (!entity) return []
|
|
170
|
+
|
|
171
|
+
const metadata = entity.metadata ?? {}
|
|
172
|
+
const github = isRecord(metadata.github) ? metadata.github : undefined
|
|
173
|
+
const syncTarget = isRecord(metadata.sync_target) ? metadata.sync_target : undefined
|
|
174
|
+
const fallbackOwner = getGithubIssueRef(entity)?.owner
|
|
175
|
+
|
|
176
|
+
if (Array.isArray(github?.projectItems)) {
|
|
177
|
+
return github.projectItems
|
|
178
|
+
.map((item) => normalizeProjectItemCandidate(item, fallbackOwner))
|
|
179
|
+
.filter((item): item is GithubProjectItemRef => Boolean(item))
|
|
180
|
+
}
|
|
181
|
+
|
|
182
|
+
const canonicalProjectItem = normalizeProjectItemCandidate(github?.projectItem, fallbackOwner)
|
|
183
|
+
if (canonicalProjectItem) {
|
|
184
|
+
return [canonicalProjectItem]
|
|
185
|
+
}
|
|
186
|
+
|
|
187
|
+
const legacyProjectItem = normalizeProjectItemCandidate(syncTarget, fallbackOwner)
|
|
188
|
+
return legacyProjectItem ? [legacyProjectItem] : []
|
|
189
|
+
}
|
|
190
|
+
|
|
191
|
+
export function getGithubSyncState(entityOrMetadata?: EntityRecord | Record<string, unknown>): GithubSyncState | undefined {
|
|
192
|
+
const metadata =
|
|
193
|
+
entityOrMetadata && "metadata" in entityOrMetadata && isRecord(entityOrMetadata.metadata)
|
|
194
|
+
? entityOrMetadata.metadata
|
|
195
|
+
: entityOrMetadata
|
|
196
|
+
|
|
197
|
+
if (!isRecord(metadata)) return undefined
|
|
198
|
+
|
|
199
|
+
const github = isRecord(metadata.github) ? metadata.github : undefined
|
|
200
|
+
const syncState = github?.syncState ?? metadata.syncState
|
|
201
|
+
|
|
202
|
+
return typeof syncState === "string" && GITHUB_SYNC_STATES.includes(syncState as GithubSyncState)
|
|
203
|
+
? (syncState as GithubSyncState)
|
|
204
|
+
: undefined
|
|
205
|
+
}
|
|
206
|
+
|
|
207
|
+
export function getGithubSource(entity?: EntityRecord): GithubSourceProvenance | undefined {
|
|
208
|
+
if (!entity) return undefined
|
|
209
|
+
|
|
210
|
+
const source = entity.metadata?.source
|
|
211
|
+
return isRecord(source) ? (source as GithubSourceProvenance) : undefined
|
|
212
|
+
}
|
|
213
|
+
|
|
214
|
+
export function getGithubEntityProvenance(entity?: EntityRecord): GithubEntityProvenance {
|
|
215
|
+
const metadata = entity?.metadata ?? {}
|
|
216
|
+
const github = isRecord(metadata.github) ? metadata.github : undefined
|
|
217
|
+
const issue = getGithubIssueRef(entity)
|
|
218
|
+
const projectItems = getGithubProjectItems(entity)
|
|
219
|
+
const syncTarget = isRecord(metadata.sync_target) ? metadata.sync_target : undefined
|
|
220
|
+
const githubRef = isRecord(metadata.github_ref) ? metadata.github_ref : undefined
|
|
221
|
+
const source = getGithubSource(entity)
|
|
222
|
+
|
|
223
|
+
return {
|
|
224
|
+
issue,
|
|
225
|
+
projectItems,
|
|
226
|
+
syncState: getGithubSyncState(entity),
|
|
227
|
+
lastSyncedAt: firstString(github?.lastSyncedAt, metadata.lastSyncedAt),
|
|
228
|
+
source,
|
|
229
|
+
hasGithubMetadata:
|
|
230
|
+
Boolean(github) ||
|
|
231
|
+
Boolean(syncTarget) ||
|
|
232
|
+
Boolean(githubRef) ||
|
|
233
|
+
source?.system === "coaia-github" ||
|
|
234
|
+
Boolean(issue) ||
|
|
235
|
+
projectItems.length > 0,
|
|
236
|
+
}
|
|
237
|
+
}
|
|
238
|
+
|
|
239
|
+
export function formatGithubIssueRef(issue?: GithubIssueRef): string | undefined {
|
|
240
|
+
if (!issue) return undefined
|
|
241
|
+
return `${issue.owner}/${issue.repo}#${issue.number}`
|
|
242
|
+
}
|
|
243
|
+
|
|
244
|
+
export function formatProjectItemRef(projectItem?: GithubProjectItemRef): string | undefined {
|
|
245
|
+
if (!projectItem) return undefined
|
|
246
|
+
|
|
247
|
+
if (projectItem.projectOwner && projectItem.projectNumber) {
|
|
248
|
+
return `${projectItem.projectOwner}/${projectItem.projectNumber}`
|
|
249
|
+
}
|
|
250
|
+
|
|
251
|
+
return projectItem.projectTitle || projectItem.itemId || projectItem.projectId || projectItem.url
|
|
252
|
+
}
|
|
253
|
+
|
|
254
|
+
export function getProjectFieldEntries(
|
|
255
|
+
entity: EntityRecord | undefined,
|
|
256
|
+
projectItem?: GithubProjectItemRef,
|
|
257
|
+
): GithubProjectFieldEntry[] {
|
|
258
|
+
const metadata = entity?.metadata ?? {}
|
|
259
|
+
const github = isRecord(metadata.github) ? metadata.github : undefined
|
|
260
|
+
const sources = [
|
|
261
|
+
projectItem?.fields,
|
|
262
|
+
projectItem?.fieldValues,
|
|
263
|
+
projectItem?.projectFields,
|
|
264
|
+
github?.fields,
|
|
265
|
+
github?.fieldValues,
|
|
266
|
+
github?.projectFields,
|
|
267
|
+
metadata,
|
|
268
|
+
github,
|
|
269
|
+
].filter(isRecord)
|
|
270
|
+
|
|
271
|
+
return GITHUB_PROJECT_FIELD_KEYS.flatMap((key) => {
|
|
272
|
+
for (const source of sources) {
|
|
273
|
+
if (!(key in source)) continue
|
|
274
|
+
const value = stringifyFieldValue(source[key])
|
|
275
|
+
if (value) {
|
|
276
|
+
return [{ key, label: PROJECT_FIELD_LABELS[key], value }]
|
|
277
|
+
}
|
|
278
|
+
}
|
|
279
|
+
return []
|
|
280
|
+
})
|
|
281
|
+
}
|
|
282
|
+
|
|
283
|
+
export function getGithubBridgeRelationType(relation: RelationRecord): GithubBridgeRelationType | undefined {
|
|
284
|
+
const relationType = relation.relationType
|
|
285
|
+
if (GITHUB_BRIDGE_RELATION_TYPES.includes(relationType as GithubBridgeRelationType)) {
|
|
286
|
+
return relationType as GithubBridgeRelationType
|
|
287
|
+
}
|
|
288
|
+
|
|
289
|
+
const metadata = relation.metadata ?? {}
|
|
290
|
+
const github = isRecord(metadata.github) ? metadata.github : undefined
|
|
291
|
+
const context = firstString(
|
|
292
|
+
metadata.context,
|
|
293
|
+
metadata.relation,
|
|
294
|
+
metadata.relationName,
|
|
295
|
+
metadata.semanticType,
|
|
296
|
+
github?.context,
|
|
297
|
+
github?.relation,
|
|
298
|
+
)
|
|
299
|
+
|
|
300
|
+
return GITHUB_BRIDGE_RELATION_TYPES.includes(context as GithubBridgeRelationType)
|
|
301
|
+
? (context as GithubBridgeRelationType)
|
|
302
|
+
: undefined
|
|
303
|
+
}
|
|
304
|
+
|
|
305
|
+
function stringifyFieldValue(value: unknown): string | undefined {
|
|
306
|
+
if (value === null || value === undefined) return undefined
|
|
307
|
+
if (typeof value === "string") return value.trim() || undefined
|
|
308
|
+
if (typeof value === "number" || typeof value === "boolean") return String(value)
|
|
309
|
+
if (Array.isArray(value)) {
|
|
310
|
+
const rendered = value.map(stringifyFieldValue).filter(Boolean).join(", ")
|
|
311
|
+
return rendered || undefined
|
|
312
|
+
}
|
|
313
|
+
if (isRecord(value)) {
|
|
314
|
+
return firstString(value.name, value.text, value.value, value.title, value.label) ?? JSON.stringify(value)
|
|
315
|
+
}
|
|
316
|
+
}
|
package/lib/jsonl-parser.ts
CHANGED
|
@@ -1,5 +1,6 @@
|
|
|
1
|
-
import type { Chart, EntityRecord, JSONLRecord, ParsedData, RawJSONLRecord, RelationRecord, RiseSpecProjection } from "./types"
|
|
2
|
-
import {
|
|
1
|
+
import type { Chart, EntityRecord, JSONLRecord, ParsedData, RawJSONLRecord, RelationRecord, RiseSpecProjection } from "./types.ts"
|
|
2
|
+
import { extractAsterionMetadata } from "./asterion-metadata.ts"
|
|
3
|
+
import { buildMetadataWarnings, buildRecordProjections, normalizeJsonlRecord } from "./jsonl-preservation.ts"
|
|
3
4
|
|
|
4
5
|
export function parseJSONL(content: string): RawJSONLRecord[] {
|
|
5
6
|
const lines = content.trim().split("\n")
|
|
@@ -192,6 +193,10 @@ export function organizeData(records: RawJSONLRecord[]): ParsedData {
|
|
|
192
193
|
}
|
|
193
194
|
}
|
|
194
195
|
|
|
196
|
+
for (const chart of charts.values()) {
|
|
197
|
+
Object.assign(chart, extractAsterionMetadata(chart))
|
|
198
|
+
}
|
|
199
|
+
|
|
195
200
|
// Identify root charts (level 0 or no parent)
|
|
196
201
|
const rootCharts = Array.from(charts.values()).filter((chart) => chart.level === 0 || !chart.parentChart)
|
|
197
202
|
|
package/lib/types.ts
CHANGED
|
@@ -3,7 +3,14 @@
|
|
|
3
3
|
export interface EntityRecord {
|
|
4
4
|
type: "entity"
|
|
5
5
|
name: string
|
|
6
|
-
entityType:
|
|
6
|
+
entityType:
|
|
7
|
+
| "structural_tension_chart"
|
|
8
|
+
| "desired_outcome"
|
|
9
|
+
| "current_reality"
|
|
10
|
+
| "action_step"
|
|
11
|
+
| "narrative_beat"
|
|
12
|
+
| "custom"
|
|
13
|
+
| (string & {})
|
|
7
14
|
observations: string[]
|
|
8
15
|
metadata: Record<string, any>
|
|
9
16
|
[key: string]: any
|
|
@@ -13,7 +20,13 @@ export interface RelationRecord {
|
|
|
13
20
|
type: "relation"
|
|
14
21
|
from: string
|
|
15
22
|
to: string
|
|
16
|
-
relationType:
|
|
23
|
+
relationType:
|
|
24
|
+
| "contains"
|
|
25
|
+
| "creates_tension_with"
|
|
26
|
+
| "advances_toward"
|
|
27
|
+
| "documents"
|
|
28
|
+
| "custom"
|
|
29
|
+
| (string & {})
|
|
17
30
|
metadata: Record<string, any>
|
|
18
31
|
[key: string]: any
|
|
19
32
|
}
|
|
@@ -44,6 +57,101 @@ export interface RiseSpecProjection {
|
|
|
44
57
|
nextOperations: string[]
|
|
45
58
|
}
|
|
46
59
|
|
|
60
|
+
export interface FoundationMetadata {
|
|
61
|
+
packetRoot: string
|
|
62
|
+
foundationType: string
|
|
63
|
+
parentIssue: string
|
|
64
|
+
baselineIssue: string
|
|
65
|
+
inquiryIssue: string
|
|
66
|
+
protocolIssue: string
|
|
67
|
+
schemaIssue: string
|
|
68
|
+
visualizerIssue: string
|
|
69
|
+
expectedArtifacts: string[]
|
|
70
|
+
producedArtifacts: string[]
|
|
71
|
+
evaluationStatus: "expected" | "delegated" | "produced" | "evaluated"
|
|
72
|
+
privacyClass: "public-safe" | "private" | "mixed"
|
|
73
|
+
publicationStatus: "planned" | "draft" | "reviewed" | "published"
|
|
74
|
+
commitHandles: string[]
|
|
75
|
+
}
|
|
76
|
+
|
|
77
|
+
export interface SessionLineageMetadata {
|
|
78
|
+
platform: string
|
|
79
|
+
parentChartId: string
|
|
80
|
+
sourceBeat: string
|
|
81
|
+
originalSessionId: string
|
|
82
|
+
branchSessionId: string
|
|
83
|
+
branchIndex: number
|
|
84
|
+
copiedMessageCount: number
|
|
85
|
+
branchPurpose: string
|
|
86
|
+
relatedIssues: string[]
|
|
87
|
+
handoffState: "requirements-created" | "implementation-ready" | "returned-to-parent"
|
|
88
|
+
}
|
|
89
|
+
|
|
90
|
+
export interface SessionContextMetadata {
|
|
91
|
+
mode: string
|
|
92
|
+
setting: string
|
|
93
|
+
captureQuality: "complete" | "partial" | "noisy" | "transcript-only"
|
|
94
|
+
continuationKind: "new" | "resumption" | "branch-return" | "daily-chronicle"
|
|
95
|
+
privateChroniclePath?: string
|
|
96
|
+
handle?: string
|
|
97
|
+
publicSummaryAllowed: boolean
|
|
98
|
+
}
|
|
99
|
+
|
|
100
|
+
export interface ParsedIssueReference {
|
|
101
|
+
key: string
|
|
102
|
+
raw: string
|
|
103
|
+
label: string
|
|
104
|
+
href?: string
|
|
105
|
+
owner?: string
|
|
106
|
+
repo?: string
|
|
107
|
+
number?: number
|
|
108
|
+
}
|
|
109
|
+
|
|
110
|
+
export interface ArtifactDiffEntry {
|
|
111
|
+
artifact: string
|
|
112
|
+
expected: boolean
|
|
113
|
+
produced: boolean
|
|
114
|
+
status: "matched" | "missing" | "unexpected"
|
|
115
|
+
}
|
|
116
|
+
|
|
117
|
+
export interface FoundationProjection {
|
|
118
|
+
foundation: Partial<FoundationMetadata>
|
|
119
|
+
warnings: MetadataWarning[]
|
|
120
|
+
issueRefs: ParsedIssueReference[]
|
|
121
|
+
artifactDiff: ArtifactDiffEntry[]
|
|
122
|
+
sourceRecords: string[]
|
|
123
|
+
}
|
|
124
|
+
|
|
125
|
+
export interface SessionLineageBranchProjection {
|
|
126
|
+
metadata: Partial<SessionLineageMetadata>
|
|
127
|
+
sourceRecordName?: string
|
|
128
|
+
sourceRecordType?: string
|
|
129
|
+
warnings: MetadataWarning[]
|
|
130
|
+
relatedIssueRefs: ParsedIssueReference[]
|
|
131
|
+
sourceBeatAnchor?: string
|
|
132
|
+
sourceBeatExistsInChart: boolean
|
|
133
|
+
}
|
|
134
|
+
|
|
135
|
+
export interface SessionLineageGroupProjection {
|
|
136
|
+
sourceBeat: string
|
|
137
|
+
sourceBeatAnchor?: string
|
|
138
|
+
sourceBeatExistsInChart: boolean
|
|
139
|
+
branches: SessionLineageBranchProjection[]
|
|
140
|
+
}
|
|
141
|
+
|
|
142
|
+
export interface SessionLineageProjection {
|
|
143
|
+
branches: SessionLineageBranchProjection[]
|
|
144
|
+
groupedBranches: SessionLineageGroupProjection[]
|
|
145
|
+
warnings: MetadataWarning[]
|
|
146
|
+
}
|
|
147
|
+
|
|
148
|
+
export interface SessionContextProjection {
|
|
149
|
+
context: Partial<SessionContextMetadata>
|
|
150
|
+
warnings: MetadataWarning[]
|
|
151
|
+
beatName: string
|
|
152
|
+
beatIndex: number
|
|
153
|
+
}
|
|
154
|
+
|
|
47
155
|
export interface Chart {
|
|
48
156
|
id: string
|
|
49
157
|
chartEntity: EntityRecord
|
|
@@ -55,6 +163,8 @@ export interface Chart {
|
|
|
55
163
|
level: number
|
|
56
164
|
parentChart?: string
|
|
57
165
|
relations: RelationRecord[]
|
|
166
|
+
foundationProjection?: FoundationProjection
|
|
167
|
+
sessionLineageProjection?: SessionLineageProjection
|
|
58
168
|
}
|
|
59
169
|
|
|
60
170
|
export interface ParsedData {
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
{
|
|
2
|
+
"mcpServers": {
|
|
3
|
+
"chart-coaia-narrative-legacy-mcp": {
|
|
4
|
+
"command": "npx",
|
|
5
|
+
"args": ["-y", "${CNCV}", "--memory-path", "${memories}/trading-chart.coaia-narrative.jsonl" ]
|
|
6
|
+
},
|
|
7
|
+
"charts-mcp": {
|
|
8
|
+
"command": "node",
|
|
9
|
+
"args": [
|
|
10
|
+
"/workspace/repos/jgwill/coaia-visualizer-feat-4/mcp/dist/index.js"
|
|
11
|
+
],
|
|
12
|
+
"env": {
|
|
13
|
+
"COAIAN_API_TOKEN":"123",
|
|
14
|
+
"COAIAV_API_URL":"http://localhost:4321"
|
|
15
|
+
}
|
|
16
|
+
}
|
|
17
|
+
}
|
|
18
|
+
}
|
package/next-env.d.ts
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
/// <reference types="next" />
|
|
2
2
|
/// <reference types="next/image-types/global" />
|
|
3
|
-
import "./.next/types/routes.d.ts";
|
|
3
|
+
import "./.next/dev/types/routes.d.ts";
|
|
4
4
|
|
|
5
5
|
// NOTE: This file should not be edited
|
|
6
6
|
// see https://nextjs.org/docs/app/api-reference/config/typescript for more information.
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "coaia-visualizer",
|
|
3
|
-
"version": "1.6.
|
|
3
|
+
"version": "1.6.5",
|
|
4
4
|
"private": false,
|
|
5
5
|
"type": "module",
|
|
6
6
|
"main": "./index.tsx",
|
|
@@ -9,6 +9,7 @@
|
|
|
9
9
|
".": "./index.tsx",
|
|
10
10
|
"./lib/types": "./lib/types.ts",
|
|
11
11
|
"./lib/jsonl-parser": "./lib/jsonl-parser.ts",
|
|
12
|
+
"./lib/github-provenance": "./lib/github-provenance.ts",
|
|
12
13
|
"./lib/utils": "./lib/utils.ts",
|
|
13
14
|
"./hooks/*": "./hooks/*.ts",
|
|
14
15
|
"./components/*": "./components/*.tsx",
|
|
@@ -23,25 +24,24 @@
|
|
|
23
24
|
"components/**/*",
|
|
24
25
|
"hooks/**/*",
|
|
25
26
|
"lib/**/*",
|
|
26
|
-
"styles/**/*",
|
|
27
|
-
"public/**/*",
|
|
28
27
|
"dist/**/*",
|
|
29
|
-
"mcp
|
|
30
|
-
"
|
|
31
|
-
"
|
|
32
|
-
"
|
|
33
|
-
"mcp/README.md",
|
|
34
|
-
"mcp/Dockerfile",
|
|
35
|
-
"mcp/tsconfig.json",
|
|
36
|
-
"index.tsx",
|
|
28
|
+
"mcp/**/*",
|
|
29
|
+
"public/**/*",
|
|
30
|
+
"rispecs/**/*",
|
|
31
|
+
"styles/**/*",
|
|
37
32
|
"cli.ts",
|
|
33
|
+
"index.tsx",
|
|
38
34
|
"skill.ts",
|
|
39
|
-
"components.json",
|
|
40
|
-
"mcp-config.json",
|
|
41
35
|
"next-env.d.ts",
|
|
42
36
|
"next.config.mjs",
|
|
43
37
|
"postcss.config.mjs",
|
|
44
38
|
"tsconfig.json",
|
|
39
|
+
"Dockerfile",
|
|
40
|
+
"Dockerfile.app",
|
|
41
|
+
"docker-build-push.sh",
|
|
42
|
+
"docker-entrypoint.sh",
|
|
43
|
+
"components.json",
|
|
44
|
+
"mcp-config.json",
|
|
45
45
|
"README.md",
|
|
46
46
|
"README_TELESCOPED_NAVIGATION.md",
|
|
47
47
|
"KINSHIP.md",
|
|
@@ -57,6 +57,7 @@
|
|
|
57
57
|
"test": "playwright test",
|
|
58
58
|
"test:rich-jsonl": "playwright test test-scripts/rich-jsonl-preservation.spec.ts",
|
|
59
59
|
"test:global-cli": "playwright test test-scripts/test-global-cli.spec.ts",
|
|
60
|
+
"verify:github-provenance": "node --experimental-strip-types --experimental-specifier-resolution=node test-scripts/verify-github-provenance.mjs",
|
|
60
61
|
"docker:build": "docker build -t jgwill/coaia:visualizer .",
|
|
61
62
|
"docker:push": "docker push jgwill/coaia:visualizer",
|
|
62
63
|
"docker:build-push": "npm run docker:build && npm run docker:push",
|