coaiajs 0.4.3 → 0.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 +2 -2
- package/dist/mcp/config.d.ts.map +1 -1
- package/dist/mcp/config.js +13 -1
- package/dist/mcp/config.js.map +1 -1
- package/dist/mcp/server.js +11 -1
- package/dist/mcp/server.js.map +1 -1
- package/dist/src/cli.js +15 -2
- package/dist/src/cli.js.map +1 -1
- package/dist/src/narrative/argument-hygiene.d.ts +46 -0
- package/dist/src/narrative/argument-hygiene.d.ts.map +1 -0
- package/dist/src/narrative/argument-hygiene.js +155 -0
- package/dist/src/narrative/argument-hygiene.js.map +1 -0
- package/dist/src/narrative/contract.d.ts +200 -0
- package/dist/src/narrative/contract.d.ts.map +1 -0
- package/dist/src/narrative/contract.js +274 -0
- package/dist/src/narrative/contract.js.map +1 -0
- package/dist/src/narrative/github-bridge.d.ts +23 -0
- package/dist/src/narrative/github-bridge.d.ts.map +1 -0
- package/dist/src/narrative/github-bridge.js +320 -0
- package/dist/src/narrative/github-bridge.js.map +1 -0
- package/dist/src/narrative/graph-manager.d.ts +83 -2
- package/dist/src/narrative/graph-manager.d.ts.map +1 -1
- package/dist/src/narrative/graph-manager.js +444 -54
- package/dist/src/narrative/graph-manager.js.map +1 -1
- package/dist/src/narrative/index.d.ts +24 -3
- package/dist/src/narrative/index.d.ts.map +1 -1
- package/dist/src/narrative/index.js +36 -15
- package/dist/src/narrative/index.js.map +1 -1
- package/dist/src/narrative/jsonl-preservation.d.ts +26 -0
- package/dist/src/narrative/jsonl-preservation.d.ts.map +1 -0
- package/dist/src/narrative/jsonl-preservation.js +293 -0
- package/dist/src/narrative/jsonl-preservation.js.map +1 -0
- package/dist/src/narrative/jsonl-records.d.ts +31 -0
- package/dist/src/narrative/jsonl-records.d.ts.map +1 -0
- package/dist/src/narrative/jsonl-records.js +69 -0
- package/dist/src/narrative/jsonl-records.js.map +1 -0
- package/dist/src/narrative/tool-definitions.d.ts +2 -1
- package/dist/src/narrative/tool-definitions.d.ts.map +1 -1
- package/dist/src/narrative/tool-definitions.js +134 -1
- package/dist/src/narrative/tool-definitions.js.map +1 -1
- package/dist/src/narrative/tool-handlers.d.ts.map +1 -1
- package/dist/src/narrative/tool-handlers.js +203 -20
- package/dist/src/narrative/tool-handlers.js.map +1 -1
- package/dist/src/narrative/types.d.ts +1 -1
- package/dist/src/narrative/types.d.ts.map +1 -1
- package/dist/src/narrative/validation.d.ts +13 -2
- package/dist/src/narrative/validation.d.ts.map +1 -1
- package/dist/src/narrative/validation.js +19 -4
- package/dist/src/narrative/validation.js.map +1 -1
- package/dist/src/types.d.ts +189 -0
- package/dist/src/types.d.ts.map +1 -1
- package/dist/src/types.js.map +1 -1
- package/llms-full.txt +64 -6
- package/llms.txt +4 -3
- package/package.json +5 -1
|
@@ -0,0 +1,155 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* COAIA Narrative - Argument Hygiene
|
|
3
|
+
*
|
|
4
|
+
* A malformed tool call must not become chart content.
|
|
5
|
+
*
|
|
6
|
+
* On 2026-07-30 a live store was found carrying seven observations whose bodies
|
|
7
|
+
* ended in `</currentReality>` followed by a `<parameter name="dueDate">` block:
|
|
8
|
+
* the raw text of a call whose argument tags never parsed, persisted verbatim as
|
|
9
|
+
* if it were prose. The call did not fail — it wrote, and every consumer that
|
|
10
|
+
* renders current reality has shown that tag ever since.
|
|
11
|
+
*
|
|
12
|
+
* The check belongs here, at the write boundary. Anything that reaches the JSONL
|
|
13
|
+
* is already in every reader's render, so a read-side filter arrives too late.
|
|
14
|
+
* A body carrying plainly unparsed call syntax is refused with the offending
|
|
15
|
+
* fragment named, so the caller can retry with the text it meant to record.
|
|
16
|
+
*/
|
|
17
|
+
import { ALL_TOOL_DEFINITIONS } from './tool-definitions.js';
|
|
18
|
+
/**
|
|
19
|
+
* Tool-call machinery that has no business inside a text body. These are the
|
|
20
|
+
* tags a call is *made of*, not tags a chart can legitimately talk about in the
|
|
21
|
+
* same breath as its own content.
|
|
22
|
+
*/
|
|
23
|
+
const CALL_MACHINERY = [
|
|
24
|
+
{
|
|
25
|
+
reason: 'a tool-call parameter tag',
|
|
26
|
+
pattern: /<\s*\/?\s*(?:[A-Za-z][\w.-]*:)?parameter\b/i
|
|
27
|
+
},
|
|
28
|
+
{
|
|
29
|
+
reason: 'a tool-call invoke tag',
|
|
30
|
+
pattern: /<\s*\/?\s*(?:[A-Za-z][\w.-]*:)?invoke\b/i
|
|
31
|
+
},
|
|
32
|
+
{
|
|
33
|
+
reason: 'a tool-call function_calls tag',
|
|
34
|
+
pattern: /<\s*\/?\s*(?:[A-Za-z][\w.-]*:)?function_calls\b/i
|
|
35
|
+
}
|
|
36
|
+
];
|
|
37
|
+
/**
|
|
38
|
+
* Every argument name this package declares, gathered from the tool schemas so
|
|
39
|
+
* the vocabulary cannot drift from the tools themselves. A bare closing tag for
|
|
40
|
+
* one of these names inside a text body is a parse that failed, not prose.
|
|
41
|
+
*/
|
|
42
|
+
const ARGUMENT_NAMES = (() => {
|
|
43
|
+
const names = new Set();
|
|
44
|
+
const walk = (node) => {
|
|
45
|
+
if (!node || typeof node !== 'object')
|
|
46
|
+
return;
|
|
47
|
+
const record = node;
|
|
48
|
+
const properties = record.properties;
|
|
49
|
+
if (properties && typeof properties === 'object' && !Array.isArray(properties)) {
|
|
50
|
+
for (const [key, child] of Object.entries(properties)) {
|
|
51
|
+
if (/^[A-Za-z_][A-Za-z0-9_-]*$/.test(key))
|
|
52
|
+
names.add(key);
|
|
53
|
+
walk(child);
|
|
54
|
+
}
|
|
55
|
+
}
|
|
56
|
+
if (record.items)
|
|
57
|
+
walk(record.items);
|
|
58
|
+
};
|
|
59
|
+
for (const tool of ALL_TOOL_DEFINITIONS)
|
|
60
|
+
walk(tool.inputSchema);
|
|
61
|
+
// Longest first, so a report names `</currentReality>` rather than a shorter
|
|
62
|
+
// suffix that happens to match inside it.
|
|
63
|
+
return [...names].sort((a, b) => b.length - a.length);
|
|
64
|
+
})();
|
|
65
|
+
const ARGUMENT_CLOSING_TAG = new RegExp(`<\\s*/\\s*(${ARGUMENT_NAMES.join('|')})\\s*>`, 'i');
|
|
66
|
+
/** Quote back enough of the offending text to be recognisable, not the whole body. */
|
|
67
|
+
function quoteFragment(text, index, matchLength) {
|
|
68
|
+
const close = text.indexOf('>', index + matchLength - 1);
|
|
69
|
+
const end = close !== -1 && close - index < 80 ? close + 1 : Math.min(text.length, index + 60);
|
|
70
|
+
const fragment = text.slice(index, end).replace(/\s+/g, ' ').trim();
|
|
71
|
+
return end < text.length && close === -1 ? `${fragment}…` : fragment;
|
|
72
|
+
}
|
|
73
|
+
/**
|
|
74
|
+
* Return the first unparsed-call-syntax fragment in `text`, or null if the text
|
|
75
|
+
* is ordinary prose. Angle brackets on their own are fine — `<div>`, `a < b`,
|
|
76
|
+
* `<rootDir>` all pass. Only call machinery and argument closing tags are refused.
|
|
77
|
+
*/
|
|
78
|
+
export function findUnparsedCallSyntax(text) {
|
|
79
|
+
if (typeof text !== 'string' || !text.includes('<'))
|
|
80
|
+
return null;
|
|
81
|
+
// Report the earliest fragment, not the first pattern that happens to match.
|
|
82
|
+
// The earliest one is where the prose ended and the call text began — the place
|
|
83
|
+
// the caller needs to look.
|
|
84
|
+
let earliest = null;
|
|
85
|
+
const consider = (index, length, reason) => {
|
|
86
|
+
if (!earliest || index < earliest.index)
|
|
87
|
+
earliest = { index, length, reason };
|
|
88
|
+
};
|
|
89
|
+
for (const { reason, pattern } of CALL_MACHINERY) {
|
|
90
|
+
const match = pattern.exec(text);
|
|
91
|
+
if (match)
|
|
92
|
+
consider(match.index, match[0].length, reason);
|
|
93
|
+
}
|
|
94
|
+
const closing = ARGUMENT_CLOSING_TAG.exec(text);
|
|
95
|
+
if (closing)
|
|
96
|
+
consider(closing.index, closing[0].length, `a closing tag for the '${closing[1]}' argument`);
|
|
97
|
+
if (!earliest)
|
|
98
|
+
return null;
|
|
99
|
+
const hit = earliest;
|
|
100
|
+
return {
|
|
101
|
+
fragment: quoteFragment(text, hit.index, hit.length),
|
|
102
|
+
reason: hit.reason,
|
|
103
|
+
index: hit.index
|
|
104
|
+
};
|
|
105
|
+
}
|
|
106
|
+
/**
|
|
107
|
+
* Walk any argument value — string, array, or object — and return the first
|
|
108
|
+
* location carrying unparsed call syntax.
|
|
109
|
+
*/
|
|
110
|
+
export function findUnparsedCallSyntaxIn(value, path = '') {
|
|
111
|
+
if (typeof value === 'string') {
|
|
112
|
+
const hit = findUnparsedCallSyntax(value);
|
|
113
|
+
return hit ? { ...hit, path: path || 'value' } : null;
|
|
114
|
+
}
|
|
115
|
+
if (Array.isArray(value)) {
|
|
116
|
+
for (let index = 0; index < value.length; index++) {
|
|
117
|
+
const found = findUnparsedCallSyntaxIn(value[index], `${path}[${index}]`);
|
|
118
|
+
if (found)
|
|
119
|
+
return found;
|
|
120
|
+
}
|
|
121
|
+
return null;
|
|
122
|
+
}
|
|
123
|
+
if (value && typeof value === 'object') {
|
|
124
|
+
for (const [key, child] of Object.entries(value)) {
|
|
125
|
+
const found = findUnparsedCallSyntaxIn(child, path ? `${path}.${key}` : key);
|
|
126
|
+
if (found)
|
|
127
|
+
return found;
|
|
128
|
+
}
|
|
129
|
+
return null;
|
|
130
|
+
}
|
|
131
|
+
return null;
|
|
132
|
+
}
|
|
133
|
+
/** The message a caller sees: what was refused, where, and what to do next. */
|
|
134
|
+
export function describeUnparsedCallSyntax(location) {
|
|
135
|
+
return [
|
|
136
|
+
`Malformed call refused — nothing was written.`,
|
|
137
|
+
``,
|
|
138
|
+
`\`${location.path}\` carries unparsed call syntax, not prose:`,
|
|
139
|
+
` ${location.fragment}`,
|
|
140
|
+
`That is ${location.reason}.`,
|
|
141
|
+
``,
|
|
142
|
+
`The argument tags of this call did not parse, so raw call text arrived as the`,
|
|
143
|
+
`value. Storing it would put a tag into the chart where a sentence belongs.`,
|
|
144
|
+
`Re-send the call with \`${location.path}\` holding only the text meant to be recorded.`
|
|
145
|
+
].join('\n');
|
|
146
|
+
}
|
|
147
|
+
/** Throw unless `value` is free of unparsed call syntax. Used at the store's edge. */
|
|
148
|
+
export function assertNoUnparsedCallSyntax(value, path) {
|
|
149
|
+
const location = findUnparsedCallSyntaxIn(value, path);
|
|
150
|
+
if (location)
|
|
151
|
+
throw new Error(describeUnparsedCallSyntax(location));
|
|
152
|
+
}
|
|
153
|
+
/** The argument-name vocabulary, exported so the scrubber reports what the server refuses. */
|
|
154
|
+
export const KNOWN_ARGUMENT_NAMES = ARGUMENT_NAMES;
|
|
155
|
+
//# sourceMappingURL=argument-hygiene.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"argument-hygiene.js","sourceRoot":"","sources":["../../../src/narrative/argument-hygiene.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,200 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* COAIA Narrative — the store read contract.
|
|
3
|
+
*
|
|
4
|
+
* WHAT THIS IS FOR
|
|
5
|
+
*
|
|
6
|
+
* This package owns the writes. Anything that renders a chart store was, until now,
|
|
7
|
+
* re-deriving the store's shape by hand — entity-kind strings, the `${chartId}_chart`
|
|
8
|
+
* naming scheme, which metadata key holds the MMOT trail. That knowledge living in two
|
|
9
|
+
* places is not a style problem: when it drifts, a renderer does not break, it quietly
|
|
10
|
+
* renders LESS. A chart holding real work looks identical to an empty one.
|
|
11
|
+
*
|
|
12
|
+
* HOW IT AVOIDS BEING THE THING IT WARNS ABOUT
|
|
13
|
+
*
|
|
14
|
+
* The first draft of this module re-implemented record classification by hand, and a
|
|
15
|
+
* review measured it returning 73 entities where the writer's own parser returned 76 —
|
|
16
|
+
* it dropped the legacy `type:"narrative_beat"` dialect and reported the losses as
|
|
17
|
+
* corruption. Duplication relocated rather than removed.
|
|
18
|
+
*
|
|
19
|
+
* So classification is NOT defined here. `./jsonl-records.js` holds the single
|
|
20
|
+
* definition, and both the writer (jsonl-preservation.ts) and this contract import it.
|
|
21
|
+
* What this module adds on top is the two things the writer's parser genuinely does not
|
|
22
|
+
* offer a renderer: per-line TOLERANCE (parseJsonlMemory throws on one bad line, which
|
|
23
|
+
* is correct for a writer and fatal for a surface), and the selectors/naming below.
|
|
24
|
+
*
|
|
25
|
+
* THREE RULES THIS MODULE KEEPS
|
|
26
|
+
*
|
|
27
|
+
* 1. Zero I/O. No `fs`, no `process`, no network. Callers own reading; this owns shape.
|
|
28
|
+
* 2. Never imports the server. The package's `main` IS the MCP bootstrap — importing the
|
|
29
|
+
* package root starts a stdio server — which is why this lives behind its own subpath.
|
|
30
|
+
* 3. Tolerant by construction, honest about what it skipped.
|
|
31
|
+
*/
|
|
32
|
+
import type { Entity } from '../types.js';
|
|
33
|
+
/** Bumped when a shape changes in a way a reader must notice. */
|
|
34
|
+
export declare const CONTRACT_VERSION = 2;
|
|
35
|
+
/**
|
|
36
|
+
* Every entityType this package writes. `test-contract.js` scans this package's own
|
|
37
|
+
* source and fails if a kind is written that this list does not publish — so the
|
|
38
|
+
* contract cannot fall behind the writer without the suite going red.
|
|
39
|
+
*/
|
|
40
|
+
export declare const ENTITY_TYPES: {
|
|
41
|
+
readonly chart: "structural_tension_chart";
|
|
42
|
+
readonly desiredOutcome: "desired_outcome";
|
|
43
|
+
readonly currentReality: "current_reality";
|
|
44
|
+
readonly actionStep: "action_step";
|
|
45
|
+
readonly narrativeBeat: "narrative_beat";
|
|
46
|
+
readonly wampumBelt: "wampum_belt";
|
|
47
|
+
};
|
|
48
|
+
export type EntityType = (typeof ENTITY_TYPES)[keyof typeof ENTITY_TYPES];
|
|
49
|
+
/**
|
|
50
|
+
* `EntityType | (string & {})` rather than `EntityType | string`: the latter collapses
|
|
51
|
+
* to plain `string`, which silently permits `e.entityType === 'strucutral_tension_chart'`
|
|
52
|
+
* — a typo that compiles clean and renders nothing. This form keeps autocomplete AND
|
|
53
|
+
* keeps the comparison checked, while still accepting kinds written by a newer writer.
|
|
54
|
+
*/
|
|
55
|
+
export type EntityTypeLike = EntityType | (string & {});
|
|
56
|
+
/**
|
|
57
|
+
* MMOT phases, as the writer accepts them. `'full'` is included deliberately: it is the
|
|
58
|
+
* tool's DEFAULT (`phase: string = 'full'`) and appears in live stores. An earlier draft
|
|
59
|
+
* omitted it, which would have made a phase rail built from this list silently drop
|
|
60
|
+
* every default-phase evaluation.
|
|
61
|
+
*/
|
|
62
|
+
export declare const MMOT_PHASES: readonly ["full", "acknowledge", "analyze", "update", "recommit"];
|
|
63
|
+
export type MmotPhase = (typeof MMOT_PHASES)[number];
|
|
64
|
+
export declare const isMmotPhase: (v: unknown) => v is MmotPhase;
|
|
65
|
+
/**
|
|
66
|
+
* Fritz's creating phases, carried on a chart as `metadata.phase`. Published alongside
|
|
67
|
+
* MMOT_PHASES because both occupy the key `phase` in different records, and a reader
|
|
68
|
+
* that assumes one vocabulary when it holds the other gets a confident wrong answer.
|
|
69
|
+
*/
|
|
70
|
+
export declare const CREATING_PHASES: readonly ["germination", "assimilation", "completion"];
|
|
71
|
+
export type CreatingPhase = (typeof CREATING_PHASES)[number];
|
|
72
|
+
export type Direction = 'North' | 'South' | 'East' | 'West';
|
|
73
|
+
export declare const chartEntityName: (chartId: string) => string;
|
|
74
|
+
export declare const desiredOutcomeName: (chartId: string) => string;
|
|
75
|
+
export declare const currentRealityName: (chartId: string) => string;
|
|
76
|
+
/** MMOT narrative beats are named `${chartId}_mmot_${epochMs}`. */
|
|
77
|
+
export declare const mmotBeatPrefix: (chartId: string) => string;
|
|
78
|
+
export declare const isMmotBeatName: (name: string, chartId: string) => boolean;
|
|
79
|
+
/** One entry in a chart's MMOT trail (`chart.metadata.mmotEvaluations`). */
|
|
80
|
+
export interface MmotEvaluation {
|
|
81
|
+
phase: MmotPhase | (string & {});
|
|
82
|
+
assessment: string;
|
|
83
|
+
direction?: Direction | (string & {});
|
|
84
|
+
timestamp?: string;
|
|
85
|
+
}
|
|
86
|
+
export interface StoreEntity {
|
|
87
|
+
name: string;
|
|
88
|
+
entityType: EntityTypeLike;
|
|
89
|
+
observations?: string[];
|
|
90
|
+
metadata?: Record<string, unknown>;
|
|
91
|
+
type: string;
|
|
92
|
+
}
|
|
93
|
+
export interface StoreRelation {
|
|
94
|
+
from: string;
|
|
95
|
+
to: string;
|
|
96
|
+
relationType: string;
|
|
97
|
+
metadata?: Record<string, unknown>;
|
|
98
|
+
type: 'relation';
|
|
99
|
+
}
|
|
100
|
+
export interface ParsedStore {
|
|
101
|
+
/** Keyed by entity name; a later record for the same name supersedes an earlier one. */
|
|
102
|
+
entities: Map<string, StoreEntity>;
|
|
103
|
+
relations: StoreRelation[];
|
|
104
|
+
/**
|
|
105
|
+
* Lines that were not valid JSON, or were valid JSON that the writer's own predicates
|
|
106
|
+
* do not classify as any known record. NOT a corruption count on its own — see the
|
|
107
|
+
* warning on `parseStore` about what this can and cannot detect.
|
|
108
|
+
*/
|
|
109
|
+
skipped: number;
|
|
110
|
+
}
|
|
111
|
+
/**
|
|
112
|
+
* Parse raw JSONL store content. Pure: give it a string, get records back.
|
|
113
|
+
*
|
|
114
|
+
* Classification is delegated to the writer's own predicates, so every dialect the
|
|
115
|
+
* writer round-trips — including the legacy top-level `type:"narrative_beat"` form — is
|
|
116
|
+
* read here identically. The only behaviour added is per-line tolerance: one unparseable
|
|
117
|
+
* line is skipped rather than throwing away the whole store, which is what a live
|
|
118
|
+
* surface needs and what `parseJsonlMemory` deliberately does not do.
|
|
119
|
+
*
|
|
120
|
+
* WHAT `skipped` CANNOT TELL YOU. Since writeJsonlMemoryFile became atomic (temp +
|
|
121
|
+
* rename) a reader should never see a torn file at all, and `skipped > 0` now genuinely
|
|
122
|
+
* suggests a foreign or damaged line. But a store truncated by something OTHER than this
|
|
123
|
+
* package can still be a syntactically perfect PREFIX — every whole line parses, and the
|
|
124
|
+
* result is simply a smaller store with `skipped === 0`. No reader can detect that from
|
|
125
|
+
* content alone. If that matters to a caller, compare entity counts across reads.
|
|
126
|
+
*/
|
|
127
|
+
export declare function parseStore(raw: string): ParsedStore;
|
|
128
|
+
/** The writer's `Entity` shape, for callers already holding a KnowledgeGraph. */
|
|
129
|
+
export type { Entity };
|
|
130
|
+
/** Read a string-valued metadata key, or undefined when absent or the wrong type. */
|
|
131
|
+
export declare function metaString(e: StoreEntity | undefined, key: string): string | undefined;
|
|
132
|
+
/** A step or chart is complete when `metadata.completionStatus` is exactly true. */
|
|
133
|
+
export declare const isComplete: (e: StoreEntity | undefined) => boolean;
|
|
134
|
+
export declare const getChartEntity: (s: ParsedStore, chartId: string) => StoreEntity | undefined;
|
|
135
|
+
export declare const getDesiredOutcome: (s: ParsedStore, chartId: string) => StoreEntity | undefined;
|
|
136
|
+
export declare const getCurrentReality: (s: ParsedStore, chartId: string) => StoreEntity | undefined;
|
|
137
|
+
/**
|
|
138
|
+
* FLAT action steps only — `action_step` entities carrying this chart's id.
|
|
139
|
+
*
|
|
140
|
+
* Read the name literally: this is NOT "the chart's work". Only steps passed in the
|
|
141
|
+
* `actionSteps[]` array at chart creation become `action_step` entities. `add_action_step`
|
|
142
|
+
* creates a TELESCOPED CHILD CHART instead, and its step is that child's desired outcome.
|
|
143
|
+
* In the live seat store, 49 of 71 charts carry a parent — most work is telescoped and
|
|
144
|
+
* invisible here. Use `getWork` unless you specifically want the flat ones.
|
|
145
|
+
*/
|
|
146
|
+
export declare function getFlatActionSteps(s: ParsedStore, chartId: string): StoreEntity[];
|
|
147
|
+
/**
|
|
148
|
+
* Charts telescoped beneath this one — full charts whose `parentChart` points back here.
|
|
149
|
+
*/
|
|
150
|
+
export declare function getChildCharts(s: ParsedStore, chartId: string): StoreEntity[];
|
|
151
|
+
/** One unit of work on a chart, whether it is a flat step or a telescoped child. */
|
|
152
|
+
export interface WorkItem {
|
|
153
|
+
/** Entity name for a flat step; the CHILD CHART's id for a telescoped one. */
|
|
154
|
+
id: string;
|
|
155
|
+
title: string;
|
|
156
|
+
completed: boolean;
|
|
157
|
+
dueDate?: string;
|
|
158
|
+
updatedAt?: string;
|
|
159
|
+
telescoped: boolean;
|
|
160
|
+
/** The underlying record, for callers that need more than the summary. */
|
|
161
|
+
entity: StoreEntity;
|
|
162
|
+
}
|
|
163
|
+
/**
|
|
164
|
+
* Everything a chart is actually holding: flat action steps PLUS telescoped children,
|
|
165
|
+
* in one list. This is what a progress indicator or a chart view wants — counting only
|
|
166
|
+
* flat steps is precisely the bug that made get_chart_progress report 0/0 for charts
|
|
167
|
+
* full of telescoped work.
|
|
168
|
+
*/
|
|
169
|
+
export declare function getWork(s: ParsedStore, chartId: string): WorkItem[];
|
|
170
|
+
export declare function getMmotBeats(s: ParsedStore, chartId: string): StoreEntity[];
|
|
171
|
+
/**
|
|
172
|
+
* The chart's MMOT trail, normalized. Lives on the CHART entity's metadata, not on
|
|
173
|
+
* current reality — the two are separate records, and a caller may write the trail
|
|
174
|
+
* while deliberately leaving current reality alone.
|
|
175
|
+
*/
|
|
176
|
+
export declare function getMmotEvaluations(chart: StoreEntity | undefined): MmotEvaluation[];
|
|
177
|
+
/**
|
|
178
|
+
* A content-derived revision token for the WHOLE store — newest timestamp, plus the
|
|
179
|
+
* record counts.
|
|
180
|
+
*
|
|
181
|
+
* The counts are not decoration. Two mutations this package performs move no timestamp
|
|
182
|
+
* a chart-scoped scan would see: `updateActionProgress` stamps the step but not the
|
|
183
|
+
* chart, and `removeActionStep` stamps nothing at all. A token built only from
|
|
184
|
+
* `max(updatedAt)` therefore holds steady across a progress update AND across a
|
|
185
|
+
* deletion — so a renderer caching on it serves a removed action step forever. Folding
|
|
186
|
+
* in `entities.size` and `relations.length` makes a deletion move the token.
|
|
187
|
+
*
|
|
188
|
+
* Still derived from content, never from a file mtime: an mtime changes when the store
|
|
189
|
+
* is rewritten with identical bytes, which makes every reader refetch for nothing and
|
|
190
|
+
* makes a real change indistinguishable from a no-op rewrite.
|
|
191
|
+
*/
|
|
192
|
+
export declare function storeRevision(s: ParsedStore): string;
|
|
193
|
+
/**
|
|
194
|
+
* Revision across a specific set of entities. Narrower than `storeRevision` and subject
|
|
195
|
+
* to the blind spots described there — a progress update or a deletion may not move it.
|
|
196
|
+
* Prefer `storeRevision` for cache keys; use this only when a per-chart token is
|
|
197
|
+
* genuinely required and its limits are understood.
|
|
198
|
+
*/
|
|
199
|
+
export declare function revisionOf(entities: Array<StoreEntity | undefined>): string;
|
|
200
|
+
//# sourceMappingURL=contract.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"contract.d.ts","sourceRoot":"","sources":["../../../src/narrative/contract.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,274 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* COAIA Narrative — the store read contract.
|
|
3
|
+
*
|
|
4
|
+
* WHAT THIS IS FOR
|
|
5
|
+
*
|
|
6
|
+
* This package owns the writes. Anything that renders a chart store was, until now,
|
|
7
|
+
* re-deriving the store's shape by hand — entity-kind strings, the `${chartId}_chart`
|
|
8
|
+
* naming scheme, which metadata key holds the MMOT trail. That knowledge living in two
|
|
9
|
+
* places is not a style problem: when it drifts, a renderer does not break, it quietly
|
|
10
|
+
* renders LESS. A chart holding real work looks identical to an empty one.
|
|
11
|
+
*
|
|
12
|
+
* HOW IT AVOIDS BEING THE THING IT WARNS ABOUT
|
|
13
|
+
*
|
|
14
|
+
* The first draft of this module re-implemented record classification by hand, and a
|
|
15
|
+
* review measured it returning 73 entities where the writer's own parser returned 76 —
|
|
16
|
+
* it dropped the legacy `type:"narrative_beat"` dialect and reported the losses as
|
|
17
|
+
* corruption. Duplication relocated rather than removed.
|
|
18
|
+
*
|
|
19
|
+
* So classification is NOT defined here. `./jsonl-records.js` holds the single
|
|
20
|
+
* definition, and both the writer (jsonl-preservation.ts) and this contract import it.
|
|
21
|
+
* What this module adds on top is the two things the writer's parser genuinely does not
|
|
22
|
+
* offer a renderer: per-line TOLERANCE (parseJsonlMemory throws on one bad line, which
|
|
23
|
+
* is correct for a writer and fatal for a surface), and the selectors/naming below.
|
|
24
|
+
*
|
|
25
|
+
* THREE RULES THIS MODULE KEEPS
|
|
26
|
+
*
|
|
27
|
+
* 1. Zero I/O. No `fs`, no `process`, no network. Callers own reading; this owns shape.
|
|
28
|
+
* 2. Never imports the server. The package's `main` IS the MCP bootstrap — importing the
|
|
29
|
+
* package root starts a stdio server — which is why this lives behind its own subpath.
|
|
30
|
+
* 3. Tolerant by construction, honest about what it skipped.
|
|
31
|
+
*/
|
|
32
|
+
import { isEntityRecord, isLegacyNarrativeBeatRecord, isRelationRecord, normalizeLegacyNarrativeBeat, } from './jsonl-records.js';
|
|
33
|
+
/** Bumped when a shape changes in a way a reader must notice. */
|
|
34
|
+
export const CONTRACT_VERSION = 2;
|
|
35
|
+
// ---------------------------------------------------------------------------
|
|
36
|
+
// Entity kinds
|
|
37
|
+
// ---------------------------------------------------------------------------
|
|
38
|
+
/**
|
|
39
|
+
* Every entityType this package writes. `test-contract.js` scans this package's own
|
|
40
|
+
* source and fails if a kind is written that this list does not publish — so the
|
|
41
|
+
* contract cannot fall behind the writer without the suite going red.
|
|
42
|
+
*/
|
|
43
|
+
export const ENTITY_TYPES = {
|
|
44
|
+
chart: 'structural_tension_chart',
|
|
45
|
+
desiredOutcome: 'desired_outcome',
|
|
46
|
+
currentReality: 'current_reality',
|
|
47
|
+
actionStep: 'action_step',
|
|
48
|
+
narrativeBeat: 'narrative_beat',
|
|
49
|
+
wampumBelt: 'wampum_belt',
|
|
50
|
+
};
|
|
51
|
+
/**
|
|
52
|
+
* MMOT phases, as the writer accepts them. `'full'` is included deliberately: it is the
|
|
53
|
+
* tool's DEFAULT (`phase: string = 'full'`) and appears in live stores. An earlier draft
|
|
54
|
+
* omitted it, which would have made a phase rail built from this list silently drop
|
|
55
|
+
* every default-phase evaluation.
|
|
56
|
+
*/
|
|
57
|
+
export const MMOT_PHASES = ['full', 'acknowledge', 'analyze', 'update', 'recommit'];
|
|
58
|
+
export const isMmotPhase = (v) => typeof v === 'string' && MMOT_PHASES.includes(v);
|
|
59
|
+
/**
|
|
60
|
+
* Fritz's creating phases, carried on a chart as `metadata.phase`. Published alongside
|
|
61
|
+
* MMOT_PHASES because both occupy the key `phase` in different records, and a reader
|
|
62
|
+
* that assumes one vocabulary when it holds the other gets a confident wrong answer.
|
|
63
|
+
*/
|
|
64
|
+
export const CREATING_PHASES = ['germination', 'assimilation', 'completion'];
|
|
65
|
+
// ---------------------------------------------------------------------------
|
|
66
|
+
// Naming scheme
|
|
67
|
+
// ---------------------------------------------------------------------------
|
|
68
|
+
export const chartEntityName = (chartId) => `${chartId}_chart`;
|
|
69
|
+
export const desiredOutcomeName = (chartId) => `${chartId}_desired_outcome`;
|
|
70
|
+
export const currentRealityName = (chartId) => `${chartId}_current_reality`;
|
|
71
|
+
/** MMOT narrative beats are named `${chartId}_mmot_${epochMs}`. */
|
|
72
|
+
export const mmotBeatPrefix = (chartId) => `${chartId}_mmot_`;
|
|
73
|
+
export const isMmotBeatName = (name, chartId) => name.startsWith(mmotBeatPrefix(chartId));
|
|
74
|
+
// ---------------------------------------------------------------------------
|
|
75
|
+
// Parsing
|
|
76
|
+
// ---------------------------------------------------------------------------
|
|
77
|
+
/**
|
|
78
|
+
* Parse raw JSONL store content. Pure: give it a string, get records back.
|
|
79
|
+
*
|
|
80
|
+
* Classification is delegated to the writer's own predicates, so every dialect the
|
|
81
|
+
* writer round-trips — including the legacy top-level `type:"narrative_beat"` form — is
|
|
82
|
+
* read here identically. The only behaviour added is per-line tolerance: one unparseable
|
|
83
|
+
* line is skipped rather than throwing away the whole store, which is what a live
|
|
84
|
+
* surface needs and what `parseJsonlMemory` deliberately does not do.
|
|
85
|
+
*
|
|
86
|
+
* WHAT `skipped` CANNOT TELL YOU. Since writeJsonlMemoryFile became atomic (temp +
|
|
87
|
+
* rename) a reader should never see a torn file at all, and `skipped > 0` now genuinely
|
|
88
|
+
* suggests a foreign or damaged line. But a store truncated by something OTHER than this
|
|
89
|
+
* package can still be a syntactically perfect PREFIX — every whole line parses, and the
|
|
90
|
+
* result is simply a smaller store with `skipped === 0`. No reader can detect that from
|
|
91
|
+
* content alone. If that matters to a caller, compare entity counts across reads.
|
|
92
|
+
*/
|
|
93
|
+
export function parseStore(raw) {
|
|
94
|
+
const entities = new Map();
|
|
95
|
+
const relations = [];
|
|
96
|
+
let skipped = 0;
|
|
97
|
+
for (const line of raw.split('\n')) {
|
|
98
|
+
if (line.trim() === '')
|
|
99
|
+
continue;
|
|
100
|
+
let record;
|
|
101
|
+
try {
|
|
102
|
+
const parsed = JSON.parse(line);
|
|
103
|
+
if (typeof parsed !== 'object' || parsed === null || Array.isArray(parsed)) {
|
|
104
|
+
skipped++;
|
|
105
|
+
continue;
|
|
106
|
+
}
|
|
107
|
+
record = parsed;
|
|
108
|
+
}
|
|
109
|
+
catch {
|
|
110
|
+
skipped++;
|
|
111
|
+
continue;
|
|
112
|
+
}
|
|
113
|
+
if (isEntityRecord(record)) {
|
|
114
|
+
entities.set(record.name, record);
|
|
115
|
+
}
|
|
116
|
+
else if (isRelationRecord(record)) {
|
|
117
|
+
relations.push(record);
|
|
118
|
+
}
|
|
119
|
+
else if (isLegacyNarrativeBeatRecord(record)) {
|
|
120
|
+
const normalized = normalizeLegacyNarrativeBeat(record);
|
|
121
|
+
entities.set(normalized.name, normalized);
|
|
122
|
+
}
|
|
123
|
+
else {
|
|
124
|
+
skipped++;
|
|
125
|
+
}
|
|
126
|
+
}
|
|
127
|
+
return { entities, relations, skipped };
|
|
128
|
+
}
|
|
129
|
+
// ---------------------------------------------------------------------------
|
|
130
|
+
// Selectors
|
|
131
|
+
// ---------------------------------------------------------------------------
|
|
132
|
+
const meta = (e) => (e && e.metadata) || {};
|
|
133
|
+
/** Read a string-valued metadata key, or undefined when absent or the wrong type. */
|
|
134
|
+
export function metaString(e, key) {
|
|
135
|
+
const v = meta(e)[key];
|
|
136
|
+
return typeof v === 'string' ? v : undefined;
|
|
137
|
+
}
|
|
138
|
+
/** A step or chart is complete when `metadata.completionStatus` is exactly true. */
|
|
139
|
+
export const isComplete = (e) => meta(e)['completionStatus'] === true;
|
|
140
|
+
export const getChartEntity = (s, chartId) => s.entities.get(chartEntityName(chartId));
|
|
141
|
+
export const getDesiredOutcome = (s, chartId) => s.entities.get(desiredOutcomeName(chartId));
|
|
142
|
+
export const getCurrentReality = (s, chartId) => s.entities.get(currentRealityName(chartId));
|
|
143
|
+
/**
|
|
144
|
+
* FLAT action steps only — `action_step` entities carrying this chart's id.
|
|
145
|
+
*
|
|
146
|
+
* Read the name literally: this is NOT "the chart's work". Only steps passed in the
|
|
147
|
+
* `actionSteps[]` array at chart creation become `action_step` entities. `add_action_step`
|
|
148
|
+
* creates a TELESCOPED CHILD CHART instead, and its step is that child's desired outcome.
|
|
149
|
+
* In the live seat store, 49 of 71 charts carry a parent — most work is telescoped and
|
|
150
|
+
* invisible here. Use `getWork` unless you specifically want the flat ones.
|
|
151
|
+
*/
|
|
152
|
+
export function getFlatActionSteps(s, chartId) {
|
|
153
|
+
const out = [];
|
|
154
|
+
for (const e of s.entities.values()) {
|
|
155
|
+
if (e.entityType === ENTITY_TYPES.actionStep && meta(e)['chartId'] === chartId) {
|
|
156
|
+
out.push(e);
|
|
157
|
+
}
|
|
158
|
+
}
|
|
159
|
+
return out;
|
|
160
|
+
}
|
|
161
|
+
/**
|
|
162
|
+
* Charts telescoped beneath this one — full charts whose `parentChart` points back here.
|
|
163
|
+
*/
|
|
164
|
+
export function getChildCharts(s, chartId) {
|
|
165
|
+
const out = [];
|
|
166
|
+
for (const e of s.entities.values()) {
|
|
167
|
+
if (e.entityType === ENTITY_TYPES.chart && meta(e)['parentChart'] === chartId) {
|
|
168
|
+
out.push(e);
|
|
169
|
+
}
|
|
170
|
+
}
|
|
171
|
+
return out;
|
|
172
|
+
}
|
|
173
|
+
/**
|
|
174
|
+
* Everything a chart is actually holding: flat action steps PLUS telescoped children,
|
|
175
|
+
* in one list. This is what a progress indicator or a chart view wants — counting only
|
|
176
|
+
* flat steps is precisely the bug that made get_chart_progress report 0/0 for charts
|
|
177
|
+
* full of telescoped work.
|
|
178
|
+
*/
|
|
179
|
+
export function getWork(s, chartId) {
|
|
180
|
+
const out = [];
|
|
181
|
+
for (const e of getFlatActionSteps(s, chartId)) {
|
|
182
|
+
out.push({
|
|
183
|
+
id: e.name,
|
|
184
|
+
title: e.observations?.[0] ?? e.name,
|
|
185
|
+
completed: isComplete(e),
|
|
186
|
+
dueDate: metaString(e, 'dueDate'),
|
|
187
|
+
updatedAt: metaString(e, 'updatedAt'),
|
|
188
|
+
telescoped: false,
|
|
189
|
+
entity: e,
|
|
190
|
+
});
|
|
191
|
+
}
|
|
192
|
+
for (const e of getChildCharts(s, chartId)) {
|
|
193
|
+
const childId = metaString(e, 'chartId') ?? e.name.replace(/_chart$/, '');
|
|
194
|
+
const childOutcome = getDesiredOutcome(s, childId);
|
|
195
|
+
out.push({
|
|
196
|
+
id: childId,
|
|
197
|
+
title: childOutcome?.observations?.[0] ?? childId,
|
|
198
|
+
completed: isComplete(e),
|
|
199
|
+
dueDate: metaString(e, 'dueDate'),
|
|
200
|
+
updatedAt: metaString(e, 'updatedAt'),
|
|
201
|
+
telescoped: true,
|
|
202
|
+
entity: e,
|
|
203
|
+
});
|
|
204
|
+
}
|
|
205
|
+
return out;
|
|
206
|
+
}
|
|
207
|
+
export function getMmotBeats(s, chartId) {
|
|
208
|
+
const out = [];
|
|
209
|
+
for (const e of s.entities.values()) {
|
|
210
|
+
if (e.entityType === ENTITY_TYPES.narrativeBeat && isMmotBeatName(e.name, chartId)) {
|
|
211
|
+
out.push(e);
|
|
212
|
+
}
|
|
213
|
+
}
|
|
214
|
+
return out;
|
|
215
|
+
}
|
|
216
|
+
/**
|
|
217
|
+
* The chart's MMOT trail, normalized. Lives on the CHART entity's metadata, not on
|
|
218
|
+
* current reality — the two are separate records, and a caller may write the trail
|
|
219
|
+
* while deliberately leaving current reality alone.
|
|
220
|
+
*/
|
|
221
|
+
export function getMmotEvaluations(chart) {
|
|
222
|
+
const raw = meta(chart)['mmotEvaluations'];
|
|
223
|
+
if (!Array.isArray(raw))
|
|
224
|
+
return [];
|
|
225
|
+
return raw.map((ev) => {
|
|
226
|
+
const r = (ev || {});
|
|
227
|
+
return {
|
|
228
|
+
phase: String(r['phase'] ?? ''),
|
|
229
|
+
assessment: String(r['assessment'] ?? ''),
|
|
230
|
+
direction: typeof r['direction'] === 'string' ? r['direction'] : undefined,
|
|
231
|
+
timestamp: typeof r['timestamp'] === 'string' ? r['timestamp'] : undefined,
|
|
232
|
+
};
|
|
233
|
+
});
|
|
234
|
+
}
|
|
235
|
+
/**
|
|
236
|
+
* A content-derived revision token for the WHOLE store — newest timestamp, plus the
|
|
237
|
+
* record counts.
|
|
238
|
+
*
|
|
239
|
+
* The counts are not decoration. Two mutations this package performs move no timestamp
|
|
240
|
+
* a chart-scoped scan would see: `updateActionProgress` stamps the step but not the
|
|
241
|
+
* chart, and `removeActionStep` stamps nothing at all. A token built only from
|
|
242
|
+
* `max(updatedAt)` therefore holds steady across a progress update AND across a
|
|
243
|
+
* deletion — so a renderer caching on it serves a removed action step forever. Folding
|
|
244
|
+
* in `entities.size` and `relations.length` makes a deletion move the token.
|
|
245
|
+
*
|
|
246
|
+
* Still derived from content, never from a file mtime: an mtime changes when the store
|
|
247
|
+
* is rewritten with identical bytes, which makes every reader refetch for nothing and
|
|
248
|
+
* makes a real change indistinguishable from a no-op rewrite.
|
|
249
|
+
*/
|
|
250
|
+
export function storeRevision(s) {
|
|
251
|
+
let newest = '';
|
|
252
|
+
for (const e of s.entities.values()) {
|
|
253
|
+
const u = metaString(e, 'updatedAt') ?? metaString(e, 'createdAt') ?? '';
|
|
254
|
+
if (u > newest)
|
|
255
|
+
newest = u;
|
|
256
|
+
}
|
|
257
|
+
return `${newest}|${s.entities.size}|${s.relations.length}`;
|
|
258
|
+
}
|
|
259
|
+
/**
|
|
260
|
+
* Revision across a specific set of entities. Narrower than `storeRevision` and subject
|
|
261
|
+
* to the blind spots described there — a progress update or a deletion may not move it.
|
|
262
|
+
* Prefer `storeRevision` for cache keys; use this only when a per-chart token is
|
|
263
|
+
* genuinely required and its limits are understood.
|
|
264
|
+
*/
|
|
265
|
+
export function revisionOf(entities) {
|
|
266
|
+
let revision = '';
|
|
267
|
+
for (const e of entities) {
|
|
268
|
+
const u = metaString(e, 'updatedAt') ?? metaString(e, 'createdAt') ?? '';
|
|
269
|
+
if (u > revision)
|
|
270
|
+
revision = u;
|
|
271
|
+
}
|
|
272
|
+
return revision;
|
|
273
|
+
}
|
|
274
|
+
//# sourceMappingURL=contract.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"contract.js","sourceRoot":"","sources":["../../../src/narrative/contract.ts"],"names":[],"mappings":"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"}
|