run-dmcp 0.1.0 → 0.2.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 +76 -10
- package/dist/bin/run-dmcp.d.ts +2 -0
- package/dist/bin/run-dmcp.js +55 -0
- package/dist/db/connection.d.ts +32 -0
- package/dist/db/connection.js +38 -16
- package/dist/db/schema.d.ts +29 -1
- package/dist/db/schema.js +439 -7
- package/dist/http/server.js +3 -3
- package/dist/index.d.ts +36 -2
- package/dist/index.js +184 -92
- package/dist/mcp-server.d.ts +49 -0
- package/dist/mcp-server.js +127 -0
- package/dist/reader/turnReader.d.ts +185 -0
- package/dist/reader/turnReader.js +288 -0
- package/dist/register/batch.js +5 -79
- package/dist/register/mcp-resources.d.ts +9 -0
- package/dist/register/mcp-resources.js +16 -62
- package/dist/register/render.d.ts +17 -0
- package/dist/register/render.js +50 -0
- package/dist/register/resolve.d.ts +14 -0
- package/dist/register/resolve.js +102 -0
- package/dist/register/resources.js +11 -4
- package/dist/register/timeline.d.ts +2 -0
- package/dist/register/timeline.js +311 -0
- package/dist/rpg/index.d.ts +29 -0
- package/dist/rpg/index.js +55 -0
- package/dist/rpg/register/abilities.d.ts +2 -0
- package/dist/rpg/register/abilities.js +165 -0
- package/dist/rpg/register/batch.d.ts +2 -0
- package/dist/rpg/register/batch.js +92 -0
- package/dist/rpg/register/combat.d.ts +2 -0
- package/dist/rpg/register/combat.js +207 -0
- package/dist/rpg/register/mcp-prompts.d.ts +2 -0
- package/dist/rpg/register/mcp-prompts.js +684 -0
- package/dist/rpg/register/mcp-resources.d.ts +2 -0
- package/dist/rpg/register/mcp-resources.js +61 -0
- package/dist/rpg/register/quests.d.ts +2 -0
- package/dist/rpg/register/quests.js +118 -0
- package/dist/rpg/register/status.d.ts +2 -0
- package/dist/rpg/register/status.js +130 -0
- package/dist/rpg/register/tables.d.ts +2 -0
- package/dist/rpg/register/tables.js +146 -0
- package/dist/rpg/tools/ability.d.ts +48 -0
- package/dist/rpg/tools/ability.js +238 -0
- package/dist/rpg/tools/combat.d.ts +13 -0
- package/dist/rpg/tools/combat.js +195 -0
- package/dist/rpg/tools/dice.d.ts +23 -0
- package/dist/rpg/tools/dice.js +111 -0
- package/dist/rpg/tools/quest.d.ts +34 -0
- package/dist/rpg/tools/quest.js +164 -0
- package/dist/rpg/tools/status.d.ts +36 -0
- package/dist/rpg/tools/status.js +218 -0
- package/dist/rpg/tools/tables.d.ts +33 -0
- package/dist/rpg/tools/tables.js +209 -0
- package/dist/schemas/index.d.ts +12 -12
- package/dist/timeline/adjudication.d.ts +150 -0
- package/dist/timeline/adjudication.js +174 -0
- package/dist/timeline/changes.d.ts +100 -0
- package/dist/timeline/changes.js +161 -0
- package/dist/timeline/checkpoint.d.ts +69 -0
- package/dist/timeline/checkpoint.js +131 -0
- package/dist/timeline/clock.d.ts +89 -0
- package/dist/timeline/clock.js +173 -0
- package/dist/timeline/constrained.d.ts +220 -0
- package/dist/timeline/constrained.js +671 -0
- package/dist/timeline/export.d.ts +171 -0
- package/dist/timeline/export.js +329 -0
- package/dist/timeline/irreversible.d.ts +85 -0
- package/dist/timeline/irreversible.js +108 -0
- package/dist/timeline/kinds.d.ts +14 -0
- package/dist/timeline/kinds.js +22 -0
- package/dist/timeline/narration.d.ts +175 -0
- package/dist/timeline/narration.js +259 -0
- package/dist/timeline/projection.d.ts +97 -0
- package/dist/timeline/projection.js +330 -0
- package/dist/timeline/provenance.d.ts +66 -0
- package/dist/timeline/provenance.js +45 -0
- package/dist/timeline/registry.d.ts +95 -0
- package/dist/timeline/registry.js +124 -0
- package/dist/timeline/render.d.ts +121 -0
- package/dist/timeline/render.js +187 -0
- package/dist/timeline/replay.d.ts +64 -0
- package/dist/timeline/replay.js +104 -0
- package/dist/timeline/resolve.d.ts +262 -0
- package/dist/timeline/resolve.js +226 -0
- package/dist/timeline/schema.d.ts +13 -0
- package/dist/timeline/schema.js +262 -0
- package/dist/timeline/t.d.ts +80 -0
- package/dist/timeline/t.js +37 -0
- package/dist/tools/constraint.d.ts +44 -80
- package/dist/tools/constraint.js +115 -124
- package/dist/tools/relationship.d.ts +83 -2
- package/dist/tools/relationship.js +139 -62
- package/dist/tools/resource.d.ts +31 -6
- package/dist/tools/resource.js +106 -153
- package/dist/types/index.d.ts +19 -1
- package/dist/utils/output-schemas.d.ts +593 -2
- package/dist/utils/output-schemas.js +3 -0
- package/dist/utils/webui.d.ts +32 -0
- package/dist/utils/webui.js +54 -1
- package/package.json +20 -4
- package/dist/__tests__/engineVocabulary.test.d.ts +0 -1
- package/dist/__tests__/engineVocabulary.test.js +0 -147
- package/dist/db/__tests__/connection.test.d.ts +0 -1
- package/dist/db/__tests__/connection.test.js +0 -72
- package/dist/db/__tests__/testDb.d.ts +0 -33
- package/dist/db/__tests__/testDb.js +0 -41
- package/dist/test-setup.d.ts +0 -1
- package/dist/test-setup.js +0 -13
- package/dist/tools/__tests__/audio.test.d.ts +0 -1
- package/dist/tools/__tests__/audio.test.js +0 -59
- package/dist/tools/__tests__/conserved.test.d.ts +0 -1
- package/dist/tools/__tests__/conserved.test.js +0 -488
- package/dist/tools/__tests__/constraint.test.d.ts +0 -1
- package/dist/tools/__tests__/constraint.test.js +0 -212
- package/dist/tools/__tests__/expiry-consequences.test.d.ts +0 -1
- package/dist/tools/__tests__/expiry-consequences.test.js +0 -110
- package/dist/tools/__tests__/images.test.d.ts +0 -1
- package/dist/tools/__tests__/images.test.js +0 -59
- package/dist/tools/__tests__/relationship.test.d.ts +0 -1
- package/dist/tools/__tests__/relationship.test.js +0 -132
- package/dist/tools/__tests__/resource-constraints.test.d.ts +0 -1
- package/dist/tools/__tests__/resource-constraints.test.js +0 -131
- package/dist/tools/__tests__/resource.test.d.ts +0 -1
- package/dist/tools/__tests__/resource.test.js +0 -190
- package/dist/tools/__tests__/time.test.d.ts +0 -1
- package/dist/tools/__tests__/time.test.js +0 -404
- package/dist/tools/__tests__/timers.test.d.ts +0 -1
- package/dist/tools/__tests__/timers.test.js +0 -426
- package/dist/tools/__tests__/world.test.d.ts +0 -1
- package/dist/tools/__tests__/world.test.js +0 -70
- package/dist/utils/__tests__/json.test.d.ts +0 -1
- package/dist/utils/__tests__/json.test.js +0 -55
- package/dist/utils/__tests__/validation.test.d.ts +0 -1
- package/dist/utils/__tests__/validation.test.js +0 -90
|
@@ -0,0 +1,220 @@
|
|
|
1
|
+
import { type T } from "./t.js";
|
|
2
|
+
/**
|
|
3
|
+
* The choke point (design §5.4 option (C), Phase 3 step 2): the ONE place a
|
|
4
|
+
* constrained numeric fact key is written, and the ONE place `resources`'
|
|
5
|
+
* former `resource_history` table is replaced by reading the interval-
|
|
6
|
+
* versioned `facts` the projection triggers (projection.ts) already produce.
|
|
7
|
+
*
|
|
8
|
+
* Before this module existed, "what did this value used to be" had two
|
|
9
|
+
* disconnected answers -- a bespoke `resource_history` table that only
|
|
10
|
+
* `updateResourceValue`/`transferResourceValue` (src/tools/resource.ts) wrote
|
|
11
|
+
* to, and the timeline's own `facts`, which the projection triggers were
|
|
12
|
+
* ALREADY appending to on every write, unread by anyone. Two write paths for
|
|
13
|
+
* the same fact is exactly the failure root CLAUDE.md's "engine records
|
|
14
|
+
* decisions" framing and the project's own history (the predecessor's
|
|
15
|
+
* `resource_history`/`relationship_history`, engineVocabulary.test.ts's
|
|
16
|
+
* epigraph) warn about generalizing badly: something gets added because one
|
|
17
|
+
* caller needed it, nothing generalizes the idea, and the concept of
|
|
18
|
+
* versioning ends up living in exactly as many places as someone happened to
|
|
19
|
+
* ask for it. This module collapses that back to one: `writeConstrainedValue`
|
|
20
|
+
* is the only way a constrained numeric value changes, and `valueHistory` is
|
|
21
|
+
* built entirely from what the timeline already recorded.
|
|
22
|
+
*
|
|
23
|
+
* IMPORT DIRECTION IS LOAD-BEARING. This file imports nothing from
|
|
24
|
+
* `src/tools/` -- registry.ts's doc comment explains why in detail, and the
|
|
25
|
+
* short version is: `src/tools/constraint.ts` already imports
|
|
26
|
+
* `src/tools/resource.ts` (for `getResource`), and `src/tools/resource.ts`
|
|
27
|
+
* needs to import THIS module (to delegate `updateResourceValue`/
|
|
28
|
+
* `transferResourceValue` to it). If this module reached back into
|
|
29
|
+
* `src/tools/` for anything -- `getResource`, a resource-shaped type, a
|
|
30
|
+
* resource-specific constant -- that would close
|
|
31
|
+
* `tools/resource.ts -> timeline/constrained.ts -> tools/*` into a cycle.
|
|
32
|
+
* Every value this module needs about "the entity currently reads a column
|
|
33
|
+
* with this key" comes from the timeline's own vocabulary instead:
|
|
34
|
+
* `entities`, `PROJECTED_TABLES`, `liveColumns` (projection.ts) and
|
|
35
|
+
* `constraintsFor`/`conservedConstraintFor` (registry.ts).
|
|
36
|
+
*/
|
|
37
|
+
/**
|
|
38
|
+
* One recorded transition of a constrained numeric fact key. A row, never a
|
|
39
|
+
* verdict (hard rule 2) -- there is no `wasClamped`, no `violatedConstraint`,
|
|
40
|
+
* just what changed, when, and (if a constrained write made it) why.
|
|
41
|
+
*/
|
|
42
|
+
export interface ValueTransition {
|
|
43
|
+
entityId: string;
|
|
44
|
+
key: string;
|
|
45
|
+
previousValue: number;
|
|
46
|
+
newValue: number;
|
|
47
|
+
delta: number;
|
|
48
|
+
reason: string | null;
|
|
49
|
+
/** Where on the timeline this landed. */
|
|
50
|
+
t: T;
|
|
51
|
+
/** The fact this write opened; null when the write changed nothing (no
|
|
52
|
+
* new interval opens for a value that didn't move -- see
|
|
53
|
+
* `applyLiveWrite`). */
|
|
54
|
+
factId: string | null;
|
|
55
|
+
/** The annotation event this write logged; null for a transition no
|
|
56
|
+
* constrained write made (an unannotated fact-only transition -- a
|
|
57
|
+
* direct column write, a bounds re-clamp, a startup reconciliation). */
|
|
58
|
+
eventId: string | null;
|
|
59
|
+
/** Wall-clock ISO stamp recorded by the choke point; null when
|
|
60
|
+
* unannotated. */
|
|
61
|
+
at: string | null;
|
|
62
|
+
}
|
|
63
|
+
/**
|
|
64
|
+
* A2: the single site where the declared constraint family (design §5.3) --
|
|
65
|
+
* `monotonic`, `bounded`, `conserved`, and (issue #13) `resolve_only` -- is
|
|
66
|
+
* evaluated against an intended change. Every one of `checkResourceConstraints()`
|
|
67
|
+
* and `checkBoundedAndMonotonicConstraints()`'s (formerly src/tools/constraint.ts)
|
|
68
|
+
* rules lives here now and ONLY here -- grep the tree for
|
|
69
|
+
* `constraint.direction ===` or `constraint.kind === "bounded"` and this file
|
|
70
|
+
* is the only hit outside a test.
|
|
71
|
+
*
|
|
72
|
+
* Reads via `constraintsFor(entityId, key)` (registry.ts), not
|
|
73
|
+
* `allConstraintsForEntity` -- this is the behavioral point of Phase 3 step
|
|
74
|
+
* 1's key-scoping: a `monotonic` (or, now, `resolve_only`) constraint
|
|
75
|
+
* declared on one fact key must never reach a write to a different key on
|
|
76
|
+
* the same entity, even though every constraint declared through today's
|
|
77
|
+
* `declare*()` functions other than `declareResolveOnlyConstraint` happens
|
|
78
|
+
* to govern `'value'`.
|
|
79
|
+
*
|
|
80
|
+
* `bounds` is optional. When a caller has no bounds to check against (e.g.
|
|
81
|
+
* `updateResource`'s own guard below, which is not itself moving a value
|
|
82
|
+
* against declared min/max -- it is refusing a conserved reclamp), the
|
|
83
|
+
* `bounded` branch is simply skipped rather than crashing on a missing
|
|
84
|
+
* object. `monotonic` and `conserved` need no bounds and are always
|
|
85
|
+
* evaluated when applicable.
|
|
86
|
+
*
|
|
87
|
+
* MESSAGE PRESERVATION: every string thrown below is copied verbatim from
|
|
88
|
+
* `checkResourceConstraints`/`checkBoundedAndMonotonicConstraints` as they
|
|
89
|
+
* stood before this module existed -- `conserved.test.ts` asserts against
|
|
90
|
+
* the conserved-rejection text by regex, and nothing here is worth rewording
|
|
91
|
+
* away from wording a real caller may already be matching on.
|
|
92
|
+
*/
|
|
93
|
+
export declare function assertConstraintsAllow(params: {
|
|
94
|
+
entityId: string;
|
|
95
|
+
key: string;
|
|
96
|
+
previousValue: number;
|
|
97
|
+
intendedValue: number;
|
|
98
|
+
bounds?: {
|
|
99
|
+
minValue: number | null;
|
|
100
|
+
maxValue: number | null;
|
|
101
|
+
};
|
|
102
|
+
/** "reject" -- a direct single-entity write to a conserved member is
|
|
103
|
+
* refused (the ambiguity has no answer). "allow" -- the caller is the
|
|
104
|
+
* counterpart-carrying transfer, the one write that CAN preserve the
|
|
105
|
+
* total. */
|
|
106
|
+
conservedMemberWrite: "reject" | "allow";
|
|
107
|
+
/** Appended to a conserved rejection in place of the default sentence
|
|
108
|
+
* about `update_resource_value`, so the message names the operation the
|
|
109
|
+
* caller actually performed. */
|
|
110
|
+
context?: string;
|
|
111
|
+
}): void;
|
|
112
|
+
/**
|
|
113
|
+
* A3: the only way a constrained numeric value changes. Resolve, check,
|
|
114
|
+
* clamp, write -- in that order, and the order is load-bearing: clamping
|
|
115
|
+
* BEFORE the constraint check would let a declared `bounded` constraint's
|
|
116
|
+
* rejection be silently satisfied by the very clamp it exists to prevent
|
|
117
|
+
* (an intended value of 150 against a [0, 100] bound would arrive at the
|
|
118
|
+
* check already clamped to 100, and a `bounded` constraint's whole point is
|
|
119
|
+
* to refuse 150, not to see 100). Clamping AFTER means the constraint check
|
|
120
|
+
* always sees the caller's actual, unclamped intent.
|
|
121
|
+
*/
|
|
122
|
+
export declare function writeConstrainedValue(params: {
|
|
123
|
+
entityId: string;
|
|
124
|
+
key: string;
|
|
125
|
+
mode: "delta" | "set";
|
|
126
|
+
value: number;
|
|
127
|
+
reason?: string | null;
|
|
128
|
+
bounds?: {
|
|
129
|
+
minValue: number | null;
|
|
130
|
+
maxValue: number | null;
|
|
131
|
+
};
|
|
132
|
+
context?: string;
|
|
133
|
+
}): ValueTransition;
|
|
134
|
+
/**
|
|
135
|
+
* A4: the counterpart-carrying two-leg write for conserved sets. Ported from
|
|
136
|
+
* `transferResourceValue` (src/tools/resource.ts) minus its argument
|
|
137
|
+
* validation (self-transfer, non-finite, negative, not-found), which stays
|
|
138
|
+
* in resource.ts because it is about resource IDENTITY, not about the
|
|
139
|
+
* constraint family this module owns -- see the doc comment there.
|
|
140
|
+
*
|
|
141
|
+
* Checks run BEFORE the transaction (membership, then bounded/monotonic on
|
|
142
|
+
* both legs, then the never-clamp bounds rejection), exactly as
|
|
143
|
+
* `transferResourceValue` ordered them -- a transfer that is going to be
|
|
144
|
+
* rejected should never touch either live row. Both legs' writes, plus the
|
|
145
|
+
* defense-in-depth sum re-verification, land in ONE `withTransaction()`.
|
|
146
|
+
*/
|
|
147
|
+
export declare function transferConstrainedValue(params: {
|
|
148
|
+
fromEntityId: string;
|
|
149
|
+
toEntityId: string;
|
|
150
|
+
key: string;
|
|
151
|
+
amount: number;
|
|
152
|
+
reason?: string | null;
|
|
153
|
+
fromBounds?: {
|
|
154
|
+
minValue: number | null;
|
|
155
|
+
maxValue: number | null;
|
|
156
|
+
};
|
|
157
|
+
toBounds?: {
|
|
158
|
+
minValue: number | null;
|
|
159
|
+
maxValue: number | null;
|
|
160
|
+
};
|
|
161
|
+
fromLabel?: string;
|
|
162
|
+
toLabel?: string;
|
|
163
|
+
}): {
|
|
164
|
+
from: ValueTransition;
|
|
165
|
+
to: ValueTransition;
|
|
166
|
+
};
|
|
167
|
+
/**
|
|
168
|
+
* A5: the payoff -- `valueHistory` is built ENTIRELY from the timeline
|
|
169
|
+
* (`facts` and `events`), with no `resource_history` in sight, because by
|
|
170
|
+
* this point in the merge there is no `resource_history` writer left to
|
|
171
|
+
* read from.
|
|
172
|
+
*
|
|
173
|
+
* Two sources, both scoped to `(entityId, key)`:
|
|
174
|
+
*
|
|
175
|
+
* 1. every FACT TRANSITION: consecutive facts, ordered `(valid_from_t,
|
|
176
|
+
* rowid)`, paired so each fact after the first supplies a
|
|
177
|
+
* previousValue/newValue/delta. The first fact is the value's
|
|
178
|
+
* CREATION, not a change -- `createResource` writes no history row
|
|
179
|
+
* today, and this function must not invent one, so the pairing loop
|
|
180
|
+
* starts at index 1, never 0.
|
|
181
|
+
* 2. every `"value.changed"` annotation event whose `causes.$.fact_id` is
|
|
182
|
+
* JSON null -- a constrained write that changed nothing. A no-op write
|
|
183
|
+
* opens no fact (see `applyLiveWrite`), so its annotation event is the
|
|
184
|
+
* ONLY record of it; without this second source, a zero-amount
|
|
185
|
+
* transfer or a zero-delta update would silently vanish from history,
|
|
186
|
+
* which is exactly what conserved.test.ts's "logged even though
|
|
187
|
+
* nothing moved" assertions were written against.
|
|
188
|
+
*
|
|
189
|
+
* Fact transitions are joined to their annotation (if any) by
|
|
190
|
+
* `json_extract(causes, '$.fact_id') = facts.id` -- an EXACT, unique link,
|
|
191
|
+
* because `applyLiveWrite` recorded the fact id at write time. This is
|
|
192
|
+
* deliberately stronger than irreversible.ts's `findOpenedByEventId`, which
|
|
193
|
+
* has to approximate the same relationship via `(at_t, row_id)` because the
|
|
194
|
+
* projection triggers that write `row_id` have no fact id to record at the
|
|
195
|
+
* point they fire (issue #2 predates this module). Here, recording the real
|
|
196
|
+
* id costs nothing extra and removes the approximation entirely.
|
|
197
|
+
*
|
|
198
|
+
* `json_valid(causes)` guards every extraction, matching irreversible.ts's
|
|
199
|
+
* `CASE WHEN json_valid(causes) THEN causes END` idiom for the same reason
|
|
200
|
+
* given there: `events.causes` has no CHECK constraint, timeline import
|
|
201
|
+
* (export.ts) carries it through verbatim by design, and SQLite's
|
|
202
|
+
* `json_extract` raises for the WHOLE query -- not just the offending row --
|
|
203
|
+
* when it meets a value that isn't JSON. A provenance hop must never be able
|
|
204
|
+
* to fail the query it annotates.
|
|
205
|
+
*
|
|
206
|
+
* Rows with no matching annotation (a direct column write, a bounds
|
|
207
|
+
* re-clamp, a startup reconciliation) come back with `reason: null`,
|
|
208
|
+
* `eventId: null`, `at: null` -- MORE history than `resource_history` ever
|
|
209
|
+
* held, because that table only ever got a row when
|
|
210
|
+
* `updateResourceValue`/`transferResourceValue` themselves wrote one.
|
|
211
|
+
*
|
|
212
|
+
* Ordered newest-first by `(t, rowid)` descending, matching
|
|
213
|
+
* `resource_history`'s old `ORDER BY timestamp DESC` in spirit -- but by the
|
|
214
|
+
* timeline's own axis, `t`, not by wall-clock time, because an unannotated
|
|
215
|
+
* transition has no wall-clock stamp to sort by and `t` is the one ordering
|
|
216
|
+
* this whole codebase agrees on (t.ts). `rowid` is the tiebreak for the rare
|
|
217
|
+
* case two rows share a `t`, mirroring `changes.ts`'s own tiebreak
|
|
218
|
+
* discipline. `limit` applies after ordering, never before.
|
|
219
|
+
*/
|
|
220
|
+
export declare function valueHistory(entityId: string, key: string, limit?: number): ValueTransition[];
|