@dsh-agentic-roleplay/state 0.1.0 → 0.1.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/README.md CHANGED
@@ -149,9 +149,9 @@ application id, so a file that is not a session database is refused.
149
149
  ## Changing the schema
150
150
 
151
151
  Migrations are applied in order when a session is opened and are never edited
152
- once released: a change is a new entry in `src/sqlite/schema.ts`. Before the
153
- first release the schema is still being shaped, and migration 1 is edited in
154
- place. A database from a newer version is refused rather than damaged.
152
+ once released: a change is a new entry in `src/sqlite/schema.ts`, and a test
153
+ pins the migrations of each release. A database from a newer version is refused
154
+ rather than damaged.
155
155
 
156
156
  ## Errors
157
157
 
package/lib/index.d.ts CHANGED
@@ -273,8 +273,10 @@ interface Location {
273
273
  createdAt: string;
274
274
  }
275
275
  type NewLocation = Omit<Location, 'id' | 'createdAt'>;
276
- /** What may change about a place once it exists; where it is stays. */
277
- type LocationPatch = Partial<Pick<Location, 'name' | 'description' | 'features'>>;
276
+ /** What may change about a place once it exists. `parentId: null` takes it out of the place that contains it. */
277
+ type LocationPatch = Partial<Pick<Location, 'name' | 'description' | 'features'>> & {
278
+ parentId?: LocationId | null;
279
+ };
278
280
  /** Whether people can go through an exit now. */
279
281
  declare const EXIT_STATES: readonly ["open", "locked", "blocked"];
280
282
  type ExitState = (typeof EXIT_STATES)[number];
@@ -627,7 +629,9 @@ interface Item {
627
629
  createdAt: string;
628
630
  }
629
631
  type NewItem = Omit<Item, 'id' | 'createdAt'>;
630
- type ItemPatch = Partial<Pick<Item, 'name' | 'description' | 'quantity' | 'quality' | 'notable' | 'hidden' | 'ownerId'>> & {
632
+ /** What may change about a thing. `ownerId: null` says it belongs to no one. */
633
+ type ItemPatch = Partial<Pick<Item, 'name' | 'description' | 'quantity' | 'quality' | 'notable' | 'hidden'>> & {
634
+ ownerId?: CharacterId | null;
631
635
  container?: ContainerSpec;
632
636
  };
633
637
  /** What holds an item: a place, a character (in its hands, or worn) or another item (inside it). */
@@ -1003,7 +1007,7 @@ type TriggerId = number;
1003
1007
  declare const COMPARISONS: readonly ["eq", "ne", "lt", "le", "gt", "ge"];
1004
1008
  type Comparison = (typeof COMPARISONS)[number];
1005
1009
  /**
1006
- * When something happens, decided in code from what the story has recorded; nothing here is judged by a model.
1010
+ * When something happens, decided in code from what the story has recorded; only `judged` is a model's reading of the story, kept as a verdict that the code reads.
1007
1011
  * Keys name characters, places, items and variables as the world's files and the tools do. Times are local to
1008
1012
  * the story's zone: `YYYY-MM-DDTHH:MM`, and `HH:MM` for a time of day.
1009
1013
  */
@@ -1050,6 +1054,11 @@ type TriggerCondition =
1050
1054
  {
1051
1055
  type: 'fired';
1052
1056
  trigger: string;
1057
+ } |
1058
+ /** A statement about the story that a model judges true or false after each turn, for what no record can say ("the mayor has lost the town's trust"); false until judged. */
1059
+ {
1060
+ type: 'judged';
1061
+ text: string;
1053
1062
  } | {
1054
1063
  type: 'all';
1055
1064
  conditions: TriggerCondition[];
@@ -2389,7 +2398,11 @@ declare function triggerReferenceProblems(target: Reading, definition: TriggerDe
2389
2398
  interface TriggerClock {
2390
2399
  now: number;
2391
2400
  zone: string;
2401
+ /** Whether a model has judged a statement true; a statement nobody judged is false. */
2402
+ judged?: (statement: string) => boolean;
2392
2403
  }
2404
+ /** The statements of the `judged` parts of a condition, in order, each once. */
2405
+ declare function judgedStatements(condition: TriggerCondition): string[];
2393
2406
  declare function holds(target: RecordsTarget, condition: TriggerCondition, clock: TriggerClock): boolean;
2394
2407
  /** Whether a condition holds now, judged only from what the story has recorded. */
2395
2408
  declare const conditionHolds: typeof holds;
@@ -3295,5 +3308,5 @@ type LintTarget = Pick<RecordsTarget, 'characters' | 'locations' | 'placements'
3295
3308
  */
3296
3309
  declare function lintWorld(target: LintTarget): LintFinding[];
3297
3310
  //#endregion
3298
- export { ACCURACIES, Accuracy, type Agenda, type AgendaEngagement, type AgendaOptions, type AgentLink, type AgentResolver, type Announcement, type BeliefEdit, CHARACTER_CONTROLS, CHARACTER_KINDS, CHARACTER_ROLES, CHARACTER_TIERS, CLOCK_MODES, COMPARISONS, CONSOLIDATION_KINDS, CONTAINER_STATES, Character, CharacterControl, CharacterDefinition, CharacterFilter, CharacterId, CharacterIntent, CharacterKind, CharacterMemory, CharacterMemoryPatch, type CharacterMove, CharacterPatch, type CharacterRepository, CharacterRole, CharacterSpeech, CharacterStart, CharacterState, CharacterStatePatch, type CharacterStateRepository, CharacterTier, type Clarity, type Clock, ClockMode, ClockState, Comparison, Config, ConflictError, ConsolidationItem, ConsolidationItemId, ConsolidationKind, type ConsolidationRepository, ContainerSpec, ContainerState, CorruptDataError, DAY, DAY_PARTS, DEFAULT_MEMORY_POLICY, DEFAULT_SLOTS, type DayPart, EMOTION_VARIABLES, ENGAGEMENT_GRACE, ENGAGEMENT_STATUSES, EXIT_STATES, type EditChecker, type EditResult, EmbeddingIndexInfo, EmotionStart, EmotionVector, Engagement, EngagementFilter, EngagementId, EngagementPatch, EngagementStatus, EntityKnowledge, type EventEdit, EventId, type EventRepository, Exit, type ExitChange, ExitDefinition, ExitId, ExitOpener, ExitPatch, ExitState, Faction, FactionDefinition, FactionId, FactionIntent, type FactionIntentRepository, FactionMembership, FactionMembershipDefinition, type FactionMembershipRepository, FactionPatch, FactionRelationship, FactionRelationshipDefinition, type FactionRelationshipRepository, type FactionRepository, FactionState, FactionStatePatch, type FactionStateRepository, type FiredTrigger, HOUR, Holder, Holding, IMPORTANCE_MAX, IMPORTANCE_MIN, INTENT_HORIZONS, INTENT_STATUSES, INTENT_TYPES, ITEM_ACTIONS, Intent, IntentFilter, IntentHorizon, IntentId, IntentPatch, type IntentRepository, IntentStatus, IntentType, InvalidEditError, InvalidMoveError, InvalidValueError, Item, type ItemAction, type ItemChange, type ItemChangeSpec, type ItemContext, ItemDefinition, type ItemEditSpec, type ItemEffect, ItemId, ItemPatch, type ItemPlan, type ItemRepository, JsonValue, KNOWLEDGE_KINDS, KnowledgeDefinition, KnowledgeKind, type KnowledgeRepository, type KnownMoveContext, LORE_KINDS, LORE_SUBJECT_KINDS, type LintFinding, type LintSeverity, type LintTarget, type LocalTime, Location, LocationDefinition, LocationFeature, LocationId, LocationPatch, type LocationRepository, Lore, LoreDefinition, LoreId, LoreKind, LorePatch, LoreSubject, LoreSubjectDefinition, LoreSubjectKind, MAX_LOCATION_FEATURES, MAX_ROUTINE_WINDOWS, MAX_SHOWN, MAX_TRIGGERS, MAX_VARIABLES, MEMBERSHIP_STATUSES, MEMORY_KINDS, MINUTE, MembershipPatch, MembershipStatus, MemoryId, MemoryKind, type MemoryPolicy, type MemoryRepository, type MetadataRepository, Move, type MoveContext, MovePlan, type NewBelief, NewCharacter, NewCharacterMemory, type NewCharacterSpec, NewCharacterState, NewEngagement, type NewEvent, NewExit, type NewExitBetween, type NewExit$1 as NewExitEdit, NewFaction, NewFactionState, NewItem, type NewItemSpec, NewLocation, NewLore, NewPerception, type NewPlace, NewPlacement, NewRelationship, NewSession, NewStoryEvent, NewSummary, NewTriggerNote, NotFoundError, type Occurrence, type OpenOptions, PERCEPTION_MODES, PLACEABLE_KINDS, PLOT_NUDGE_MODES, PLOT_STATUSES, PendingCommit, type PendingCommitRepository, PendingEmbedding, type PerceivedBy, PerceivedEvent, Perception, type PerceptionAddition, type PerceptionEdit, PerceptionId, PerceptionMode, PerceptionPatch, type PlaceEdit, PlaceableKind, Placement, type PlacementRepository, PlotDefinition, PlotDevelopment, PlotNudgeMode, PlotProgress, PlotStatus, RECALL_ITEM_KINDS, type RankedGoal, type RecallCandidate, type RecallEvidence, RecallHit, type RecallIndexRepository, RecallItemKind, type RecallPool, type RecallQuery, type RecallSearch, type RecallSource, type Recalled, type RecordsEdit, type RecordsScope, type RecordsTarget, type RecordsView, Relationship, RelationshipDefinition, RelationshipId, RelationshipPatch, type RelationshipRepository, type RelationshipRetraction, type RelationshipSet, RoleplayState, RoutineDefinition, RoutineWindow, type RunResult, LATEST_VERSION as SCHEMA_VERSION, SECOND, SESSION_DATABASE_FILE, SLOT_ID, SUMMARY_LEVELS, SchemaError, type SemanticRanker, type Session, type SessionInit, type SessionListing, SessionMetadata, type SessionStore, type ShownVariable, Slot, type SlotRepository, SocialSubjectKind, type SqlDatabase, type SqlDriver, type SqlValue, StateError, type StatePatch, type StoreOptions, StoredRoutineWindow, StoredVariable, StoryEvent, StoryEventFilter, StoryEventPatch, StoryThread, Summary, SummaryId, SummaryLevel, type SummaryRepository, THREAD_STATUSES, TIME_CHANGE_KINDS, TRIGGER_NOTE_KINDS, TRIGGER_STATUSES, ThreadId, type ThreadRepository, ThreadStatus, TimeChange, TimeChangeFilter, TimeChangeKind, Trigger, TriggerAnnouncement, TriggerAudience, type TriggerClock, TriggerCondition, TriggerDefinition, TriggerEffect, TriggerId, TriggerNote, TriggerNoteKind, type TriggerRun, type TriggerRunOptions, TriggerStatus, VARIABLE_KEY, VARIABLE_KINDS, VARIABLE_SUBJECTS, VARIABLE_VISIBILITIES, VISUAL_SUBJECT_KINDS, type VariableAudience, VariableBand, type VariableChangeSpec, type VariableContext, VariableDefinition, VariableDefinitionInput, type VariableEffect, VariableKind, type VariablePlan, VariableSubject, VariableValue, VariableVisibility, type VectorSearch, type VectorSupport, VisualIdentity, VisualIdentityInput, VisualIdentityPatch, type VisualIdentityRepository, VisualSubjectKind, WEEKDAY_NAMES, WorldReference, addLocalDays, agendaAt, announcements, apply, applyItemPlan, applyRecordsEdit, audienceIds, catchUpPlan, changeItem, changeVariable, characterKey, clarityAt, clockTime, conditionHolds, createCharacterTools, createSession, createSessionStore, createTools, dayPart, deleteSession, denseScore, describeDuration, describeHolder, describeInstant, describeValue, finishRecall, fuseScores, inAudience, inWindow, isSessionId, isTimeZone, itemKey, jitter, lapseNotes, lintWorld, listSessions, localIso, localTime, locationKey, mentioned, moveCharacter, name, nextOccurrence, nextTimeOfDay, nodeSqliteDriver, occurrenceAt, openSession, openSessionStore, overlap, parseInstant, parseRecordsEdit, parseTimeOfDay, parseTriggerDefinition, planItemChange, planKnownMove, planMove, planVariableChange, poolCandidates, rankGoals, readRecords, readTriggerDefinition, recall, recallCandidates, recallPool, recordsEditSchema, retention, runTriggers, seededRoll, sessionDatabase, sessionFolder, shownVariables, subjectOf, systemClock, systemTimeZone, tokens, triggerReferenceProblems, valueIssue, zonedInstant };
3311
+ export { ACCURACIES, Accuracy, type Agenda, type AgendaEngagement, type AgendaOptions, type AgentLink, type AgentResolver, type Announcement, type BeliefEdit, CHARACTER_CONTROLS, CHARACTER_KINDS, CHARACTER_ROLES, CHARACTER_TIERS, CLOCK_MODES, COMPARISONS, CONSOLIDATION_KINDS, CONTAINER_STATES, Character, CharacterControl, CharacterDefinition, CharacterFilter, CharacterId, CharacterIntent, CharacterKind, CharacterMemory, CharacterMemoryPatch, type CharacterMove, CharacterPatch, type CharacterRepository, CharacterRole, CharacterSpeech, CharacterStart, CharacterState, CharacterStatePatch, type CharacterStateRepository, CharacterTier, type Clarity, type Clock, ClockMode, ClockState, Comparison, Config, ConflictError, ConsolidationItem, ConsolidationItemId, ConsolidationKind, type ConsolidationRepository, ContainerSpec, ContainerState, CorruptDataError, DAY, DAY_PARTS, DEFAULT_MEMORY_POLICY, DEFAULT_SLOTS, type DayPart, EMOTION_VARIABLES, ENGAGEMENT_GRACE, ENGAGEMENT_STATUSES, EXIT_STATES, type EditChecker, type EditResult, EmbeddingIndexInfo, EmotionStart, EmotionVector, Engagement, EngagementFilter, EngagementId, EngagementPatch, EngagementStatus, EntityKnowledge, type EventEdit, EventId, type EventRepository, Exit, type ExitChange, ExitDefinition, ExitId, ExitOpener, ExitPatch, ExitState, Faction, FactionDefinition, FactionId, FactionIntent, type FactionIntentRepository, FactionMembership, FactionMembershipDefinition, type FactionMembershipRepository, FactionPatch, FactionRelationship, FactionRelationshipDefinition, type FactionRelationshipRepository, type FactionRepository, FactionState, FactionStatePatch, type FactionStateRepository, type FiredTrigger, HOUR, Holder, Holding, IMPORTANCE_MAX, IMPORTANCE_MIN, INTENT_HORIZONS, INTENT_STATUSES, INTENT_TYPES, ITEM_ACTIONS, Intent, IntentFilter, IntentHorizon, IntentId, IntentPatch, type IntentRepository, IntentStatus, IntentType, InvalidEditError, InvalidMoveError, InvalidValueError, Item, type ItemAction, type ItemChange, type ItemChangeSpec, type ItemContext, ItemDefinition, type ItemEditSpec, type ItemEffect, ItemId, ItemPatch, type ItemPlan, type ItemRepository, JsonValue, KNOWLEDGE_KINDS, KnowledgeDefinition, KnowledgeKind, type KnowledgeRepository, type KnownMoveContext, LORE_KINDS, LORE_SUBJECT_KINDS, type LintFinding, type LintSeverity, type LintTarget, type LocalTime, Location, LocationDefinition, LocationFeature, LocationId, LocationPatch, type LocationRepository, Lore, LoreDefinition, LoreId, LoreKind, LorePatch, LoreSubject, LoreSubjectDefinition, LoreSubjectKind, MAX_LOCATION_FEATURES, MAX_ROUTINE_WINDOWS, MAX_SHOWN, MAX_TRIGGERS, MAX_VARIABLES, MEMBERSHIP_STATUSES, MEMORY_KINDS, MINUTE, MembershipPatch, MembershipStatus, MemoryId, MemoryKind, type MemoryPolicy, type MemoryRepository, type MetadataRepository, Move, type MoveContext, MovePlan, type NewBelief, NewCharacter, NewCharacterMemory, type NewCharacterSpec, NewCharacterState, NewEngagement, type NewEvent, NewExit, type NewExitBetween, type NewExit$1 as NewExitEdit, NewFaction, NewFactionState, NewItem, type NewItemSpec, NewLocation, NewLore, NewPerception, type NewPlace, NewPlacement, NewRelationship, NewSession, NewStoryEvent, NewSummary, NewTriggerNote, NotFoundError, type Occurrence, type OpenOptions, PERCEPTION_MODES, PLACEABLE_KINDS, PLOT_NUDGE_MODES, PLOT_STATUSES, PendingCommit, type PendingCommitRepository, PendingEmbedding, type PerceivedBy, PerceivedEvent, Perception, type PerceptionAddition, type PerceptionEdit, PerceptionId, PerceptionMode, PerceptionPatch, type PlaceEdit, PlaceableKind, Placement, type PlacementRepository, PlotDefinition, PlotDevelopment, PlotNudgeMode, PlotProgress, PlotStatus, RECALL_ITEM_KINDS, type RankedGoal, type RecallCandidate, type RecallEvidence, RecallHit, type RecallIndexRepository, RecallItemKind, type RecallPool, type RecallQuery, type RecallSearch, type RecallSource, type Recalled, type RecordsEdit, type RecordsScope, type RecordsTarget, type RecordsView, Relationship, RelationshipDefinition, RelationshipId, RelationshipPatch, type RelationshipRepository, type RelationshipRetraction, type RelationshipSet, RoleplayState, RoutineDefinition, RoutineWindow, type RunResult, LATEST_VERSION as SCHEMA_VERSION, SECOND, SESSION_DATABASE_FILE, SLOT_ID, SUMMARY_LEVELS, SchemaError, type SemanticRanker, type Session, type SessionInit, type SessionListing, SessionMetadata, type SessionStore, type ShownVariable, Slot, type SlotRepository, SocialSubjectKind, type SqlDatabase, type SqlDriver, type SqlValue, StateError, type StatePatch, type StoreOptions, StoredRoutineWindow, StoredVariable, StoryEvent, StoryEventFilter, StoryEventPatch, StoryThread, Summary, SummaryId, SummaryLevel, type SummaryRepository, THREAD_STATUSES, TIME_CHANGE_KINDS, TRIGGER_NOTE_KINDS, TRIGGER_STATUSES, ThreadId, type ThreadRepository, ThreadStatus, TimeChange, TimeChangeFilter, TimeChangeKind, Trigger, TriggerAnnouncement, TriggerAudience, type TriggerClock, TriggerCondition, TriggerDefinition, TriggerEffect, TriggerId, TriggerNote, TriggerNoteKind, type TriggerRun, type TriggerRunOptions, TriggerStatus, VARIABLE_KEY, VARIABLE_KINDS, VARIABLE_SUBJECTS, VARIABLE_VISIBILITIES, VISUAL_SUBJECT_KINDS, type VariableAudience, VariableBand, type VariableChangeSpec, type VariableContext, VariableDefinition, VariableDefinitionInput, type VariableEffect, VariableKind, type VariablePlan, VariableSubject, VariableValue, VariableVisibility, type VectorSearch, type VectorSupport, VisualIdentity, VisualIdentityInput, VisualIdentityPatch, type VisualIdentityRepository, VisualSubjectKind, WEEKDAY_NAMES, WorldReference, addLocalDays, agendaAt, announcements, apply, applyItemPlan, applyRecordsEdit, audienceIds, catchUpPlan, changeItem, changeVariable, characterKey, clarityAt, clockTime, conditionHolds, createCharacterTools, createSession, createSessionStore, createTools, dayPart, deleteSession, denseScore, describeDuration, describeHolder, describeInstant, describeValue, finishRecall, fuseScores, inAudience, inWindow, isSessionId, isTimeZone, itemKey, jitter, judgedStatements, lapseNotes, lintWorld, listSessions, localIso, localTime, locationKey, mentioned, moveCharacter, name, nextOccurrence, nextTimeOfDay, nodeSqliteDriver, occurrenceAt, openSession, openSessionStore, overlap, parseInstant, parseRecordsEdit, parseTimeOfDay, parseTriggerDefinition, planItemChange, planKnownMove, planMove, planVariableChange, poolCandidates, rankGoals, readRecords, readTriggerDefinition, recall, recallCandidates, recallPool, recordsEditSchema, retention, runTriggers, seededRoll, sessionDatabase, sessionFolder, shownVariables, subjectOf, systemClock, systemTimeZone, tokens, triggerReferenceProblems, valueIssue, zonedInstant };
3299
3312
  //# sourceMappingURL=index.d.ts.map
package/lib/index.js CHANGED
@@ -2033,6 +2033,7 @@ const MAX_DEPTH = 4;
2033
2033
  const MAX_NODES = 24;
2034
2034
  const MAX_EFFECTS = 6;
2035
2035
  const MAX_TEXT$1 = 1e3;
2036
+ const MAX_JUDGED = 300;
2036
2037
  const text = (entry, key) => typeof entry[key] === "string" && entry[key].trim() !== "" ? entry[key].trim() : void 0;
2037
2038
  function parseCondition(value, path, problems, count, depth = 0) {
2038
2039
  count.nodes += 1;
@@ -2132,6 +2133,17 @@ function parseCondition(value, path, problems, count, depth = 0) {
2132
2133
  trigger
2133
2134
  };
2134
2135
  }
2136
+ case "judged": {
2137
+ const statement = need("text");
2138
+ if (statement !== void 0 && statement.length > MAX_JUDGED) {
2139
+ problems.push(`${path}.text: at most ${MAX_JUDGED} characters`);
2140
+ return;
2141
+ }
2142
+ return statement === void 0 ? void 0 : {
2143
+ type: "judged",
2144
+ text: statement
2145
+ };
2146
+ }
2135
2147
  case "all":
2136
2148
  case "any": {
2137
2149
  if (!Array.isArray(value["conditions"]) || value["conditions"].length === 0) {
@@ -2152,7 +2164,7 @@ function parseCondition(value, path, problems, count, depth = 0) {
2152
2164
  };
2153
2165
  }
2154
2166
  default:
2155
- problems.push(`${path}.type: one of time, place, variable, item, event, fired, all, any, not`);
2167
+ problems.push(`${path}.type: one of time, place, variable, item, event, fired, judged, all, any, not`);
2156
2168
  return;
2157
2169
  }
2158
2170
  }
@@ -2302,6 +2314,7 @@ function conditionProblems(target, condition, path, known) {
2302
2314
  ];
2303
2315
  case "event": return [];
2304
2316
  case "fired": return known.has(condition.trigger) ? [] : [`${path}: there is no trigger "${condition.trigger}"`];
2317
+ case "judged": return [];
2305
2318
  case "all":
2306
2319
  case "any": return condition.conditions.flatMap((part, index) => conditionProblems(target, part, `${path}.conditions[${index}]`, known));
2307
2320
  case "not": return conditionProblems(target, condition.condition, `${path}.condition`, known);
@@ -2338,6 +2351,16 @@ function compare(op, have, want) {
2338
2351
  if (typeof have === "number" && typeof want === "number") return COMPARE[op](have, want);
2339
2352
  return op === "ne" ? have !== want : op === "eq" ? have === want : false;
2340
2353
  }
2354
+ /** The statements of the `judged` parts of a condition, in order, each once. */
2355
+ function judgedStatements(condition) {
2356
+ switch (condition.type) {
2357
+ case "judged": return [condition.text];
2358
+ case "all":
2359
+ case "any": return [...new Set(condition.conditions.flatMap(judgedStatements))];
2360
+ case "not": return judgedStatements(condition.condition);
2361
+ default: return [];
2362
+ }
2363
+ }
2341
2364
  function holds(target, condition, clock) {
2342
2365
  switch (condition.type) {
2343
2366
  case "time": {
@@ -2375,6 +2398,7 @@ function holds(target, condition, clock) {
2375
2398
  }
2376
2399
  case "event": return target.events.list().some((event) => event.tags.includes(condition.tag));
2377
2400
  case "fired": return (target.triggers.getByKey(condition.trigger)?.fireCount ?? 0) > 0;
2401
+ case "judged": return clock.judged?.(condition.text) ?? false;
2378
2402
  case "all": return condition.conditions.every((part) => holds(target, part, clock));
2379
2403
  case "any": return condition.conditions.some((part) => holds(target, part, clock));
2380
2404
  case "not": return !holds(target, condition.condition, clock);
@@ -5047,11 +5071,12 @@ const isObject = (value) => typeof value === "object" && value !== null && !Arra
5047
5071
  const DEFAULT_MAX_FIRES = 3;
5048
5072
  /** An edit effect, as it is applied at this turn and round: events default to now and to what those in their place saw. */
5049
5073
  function editOf(target, raw, options) {
5074
+ const round = Math.max(1, options.round);
5050
5075
  const events = Array.isArray(raw["events"]) ? raw["events"].filter(isObject).map((event) => {
5051
5076
  const where = typeof event["location"] === "string" ? target.locations.list().find((entry) => locationKey(entry) === event["location"])?.id : void 0;
5052
5077
  if (event["perceived_by"] === "everyone") return {
5053
5078
  turn: options.turn,
5054
- round: options.round,
5079
+ round,
5055
5080
  importance: 3,
5056
5081
  tags: [],
5057
5082
  involves: [],
@@ -5067,7 +5092,7 @@ function editOf(target, raw, options) {
5067
5092
  }));
5068
5093
  return {
5069
5094
  turn: options.turn,
5070
- round: options.round,
5095
+ round,
5071
5096
  importance: 3,
5072
5097
  tags: [],
5073
5098
  involves: [],
@@ -6716,7 +6741,7 @@ var SqliteItemRepository = class {
6716
6741
  patch.notable ?? current.notable ? 1 : 0,
6717
6742
  patch.hidden ?? current.hidden ? 1 : 0,
6718
6743
  patch.container?.state ?? current.container?.state ?? null,
6719
- patch.ownerId ?? current.ownerId ?? null,
6744
+ patch.ownerId === void 0 ? current.ownerId ?? null : patch.ownerId,
6720
6745
  id
6721
6746
  ]);
6722
6747
  return this.require(id);
@@ -7090,10 +7115,16 @@ var SqliteLocationRepository = class {
7090
7115
  const features = patch.features === void 0 ? current.features : checkedFeatures(patch.features);
7091
7116
  const removed = current.features.filter((feature) => !features.some((kept) => kept.key === feature.key));
7092
7117
  for (const feature of removed) if (this.db.get("SELECT 1 FROM placements WHERE location_id = ? AND feature_key = ?", [id, feature.key]) !== void 0) throw new ConflictError(`feature "${feature.key}" cannot be removed while someone is at it`);
7093
- this.db.run("UPDATE locations SET name = ?, description = ?, features = ? WHERE id = ?", [
7118
+ const parentId = patch.parentId === void 0 ? current.parentId ?? null : patch.parentId;
7119
+ if (parentId !== null && parentId !== (current.parentId ?? null)) {
7120
+ if (this.get(parentId) === void 0) throw new NotFoundError(`the parent place ${parentId} does not exist`);
7121
+ for (let ancestor = parentId; ancestor !== null; ancestor = this.get(ancestor)?.parentId ?? null) if (ancestor === id) throw new InvalidValueError(`${current.name} cannot be inside itself or a place within it`);
7122
+ }
7123
+ this.db.run("UPDATE locations SET name = ?, description = ?, features = ?, parent_id = ? WHERE id = ?", [
7094
7124
  name,
7095
7125
  (patch.description ?? current.description).trim(),
7096
7126
  toJson(features),
7127
+ parentId,
7097
7128
  id
7098
7129
  ]);
7099
7130
  if (name !== current.name) this.renamed(id);
@@ -7621,10 +7652,10 @@ var SqliteMetadataRepository = class {
7621
7652
  //#endregion
7622
7653
  //#region src/sqlite/schema.ts
7623
7654
  /**
7624
- * Migrations are applied in order and never edited once released: a change to
7625
- * the schema is a new entry. Until the first release the schema is still being
7626
- * shaped, so migration 1 is edited in place. Enumerations are spelled out so that
7627
- * a later change to the model cannot alter what an old migration did.
7655
+ * Migrations are applied in order and never edited once released (0.1.0 released
7656
+ * versions 1 to 6; tests/sqlite/migrate.spec.ts pins them): a change to the schema
7657
+ * is a new entry. Enumerations are spelled out so that a later change to the model
7658
+ * cannot alter what an old migration did.
7628
7659
  */
7629
7660
  const MIGRATIONS = [
7630
7661
  {
@@ -11352,6 +11383,6 @@ function createCharacterTools(link, characterId) {
11352
11383
  ];
11353
11384
  }
11354
11385
  //#endregion
11355
- export { ACCURACIES, CHARACTER_CONTROLS, CHARACTER_KINDS, CHARACTER_ROLES, CHARACTER_TIERS, CLOCK_MODES, COMPARISONS, CONSOLIDATION_KINDS, CONTAINER_STATES, Config, ConflictError, CorruptDataError, DAY, DAY_PARTS, DEFAULT_MEMORY_POLICY, DEFAULT_SLOTS, EMOTION_VARIABLES, ENGAGEMENT_GRACE, ENGAGEMENT_STATUSES, EXIT_STATES, HOUR, IMPORTANCE_MAX, IMPORTANCE_MIN, INTENT_HORIZONS, INTENT_STATUSES, INTENT_TYPES, ITEM_ACTIONS, InvalidEditError, InvalidMoveError, InvalidValueError, KNOWLEDGE_KINDS, LORE_KINDS, LORE_SUBJECT_KINDS, MAX_LOCATION_FEATURES, MAX_ROUTINE_WINDOWS, MAX_SHOWN, MAX_TRIGGERS, MAX_VARIABLES, MEMBERSHIP_STATUSES, MEMORY_KINDS, MINUTE, NotFoundError, PERCEPTION_MODES, PLACEABLE_KINDS, PLOT_NUDGE_MODES, PLOT_STATUSES, RECALL_ITEM_KINDS, RoleplayState, LATEST_VERSION as SCHEMA_VERSION, SECOND, SESSION_DATABASE_FILE, SLOT_ID, SUMMARY_LEVELS, SchemaError, StateError, THREAD_STATUSES, TIME_CHANGE_KINDS, TRIGGER_NOTE_KINDS, TRIGGER_STATUSES, VARIABLE_KEY, VARIABLE_KINDS, VARIABLE_SUBJECTS, VARIABLE_VISIBILITIES, VISUAL_SUBJECT_KINDS, WEEKDAY_NAMES, addLocalDays, agendaAt, announcements, apply, applyItemPlan, applyRecordsEdit, audienceIds, catchUpPlan, changeItem, changeVariable, characterKey, clarityAt, clockTime, conditionHolds, createCharacterTools, createSession, createSessionStore, createTools, dayPart, deleteSession, denseScore, describeDuration, describeHolder, describeInstant, describeValue, finishRecall, fuseScores, inAudience, inWindow, isSessionId, isTimeZone, itemKey, jitter, lapseNotes, lintWorld, listSessions, localIso, localTime, locationKey, mentioned, moveCharacter, name, nextOccurrence, nextTimeOfDay, nodeSqliteDriver, occurrenceAt, openSession, openSessionStore, overlap, parseInstant, parseRecordsEdit, parseTimeOfDay, parseTriggerDefinition, planItemChange, planKnownMove, planMove, planVariableChange, poolCandidates, rankGoals, readRecords, readTriggerDefinition, recall, recallCandidates, recallPool, recordsEditSchema, retention, runTriggers, seededRoll, sessionDatabase, sessionFolder, shownVariables, subjectOf, systemClock, systemTimeZone, tokens, triggerReferenceProblems, valueIssue, zonedInstant };
11386
+ export { ACCURACIES, CHARACTER_CONTROLS, CHARACTER_KINDS, CHARACTER_ROLES, CHARACTER_TIERS, CLOCK_MODES, COMPARISONS, CONSOLIDATION_KINDS, CONTAINER_STATES, Config, ConflictError, CorruptDataError, DAY, DAY_PARTS, DEFAULT_MEMORY_POLICY, DEFAULT_SLOTS, EMOTION_VARIABLES, ENGAGEMENT_GRACE, ENGAGEMENT_STATUSES, EXIT_STATES, HOUR, IMPORTANCE_MAX, IMPORTANCE_MIN, INTENT_HORIZONS, INTENT_STATUSES, INTENT_TYPES, ITEM_ACTIONS, InvalidEditError, InvalidMoveError, InvalidValueError, KNOWLEDGE_KINDS, LORE_KINDS, LORE_SUBJECT_KINDS, MAX_LOCATION_FEATURES, MAX_ROUTINE_WINDOWS, MAX_SHOWN, MAX_TRIGGERS, MAX_VARIABLES, MEMBERSHIP_STATUSES, MEMORY_KINDS, MINUTE, NotFoundError, PERCEPTION_MODES, PLACEABLE_KINDS, PLOT_NUDGE_MODES, PLOT_STATUSES, RECALL_ITEM_KINDS, RoleplayState, LATEST_VERSION as SCHEMA_VERSION, SECOND, SESSION_DATABASE_FILE, SLOT_ID, SUMMARY_LEVELS, SchemaError, StateError, THREAD_STATUSES, TIME_CHANGE_KINDS, TRIGGER_NOTE_KINDS, TRIGGER_STATUSES, VARIABLE_KEY, VARIABLE_KINDS, VARIABLE_SUBJECTS, VARIABLE_VISIBILITIES, VISUAL_SUBJECT_KINDS, WEEKDAY_NAMES, addLocalDays, agendaAt, announcements, apply, applyItemPlan, applyRecordsEdit, audienceIds, catchUpPlan, changeItem, changeVariable, characterKey, clarityAt, clockTime, conditionHolds, createCharacterTools, createSession, createSessionStore, createTools, dayPart, deleteSession, denseScore, describeDuration, describeHolder, describeInstant, describeValue, finishRecall, fuseScores, inAudience, inWindow, isSessionId, isTimeZone, itemKey, jitter, judgedStatements, lapseNotes, lintWorld, listSessions, localIso, localTime, locationKey, mentioned, moveCharacter, name, nextOccurrence, nextTimeOfDay, nodeSqliteDriver, occurrenceAt, openSession, openSessionStore, overlap, parseInstant, parseRecordsEdit, parseTimeOfDay, parseTriggerDefinition, planItemChange, planKnownMove, planMove, planVariableChange, poolCandidates, rankGoals, readRecords, readTriggerDefinition, recall, recallCandidates, recallPool, recordsEditSchema, retention, runTriggers, seededRoll, sessionDatabase, sessionFolder, shownVariables, subjectOf, systemClock, systemTimeZone, tokens, triggerReferenceProblems, valueIssue, zonedInstant };
11356
11387
 
11357
11388
  //# sourceMappingURL=index.js.map