@rolexjs/local-platform 1.3.1-dev-20260304123741 → 2.0.0-dev-20260305000914

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/dist/index.d.ts CHANGED
@@ -1,4 +1,4 @@
1
- import { Platform, RoleXRepository, PrototypeRegistry, ContextData } from '@rolexjs/core';
1
+ import { PrototypeData, Platform, RoleXRepository, PrototypeRepository, ContextData } from '@rolexjs/core';
2
2
  import { State, Runtime } from '@rolexjs/system';
3
3
  import { CommonXDatabase } from '@deepracticex/drizzle';
4
4
 
@@ -16,8 +16,8 @@ interface LocalPlatformConfig {
16
16
  dataDir?: string | null;
17
17
  /** Directory for ResourceX storage. Defaults to ~/.deepractice/resourcex. Set to null to disable. */
18
18
  resourceDir?: string | null;
19
- /** Prototype sources to settle on genesis. */
20
- bootstrap?: string[];
19
+ /** Prototype data to apply on genesis. */
20
+ prototypes?: PrototypeData[];
21
21
  }
22
22
  /** Create a local Platform. Persistent by default ($DEEPRACTICE_HOME/rolex), in-memory if dataDir is null. */
23
23
  declare function localPlatform(config?: LocalPlatformConfig): Platform;
@@ -79,15 +79,15 @@ declare function filesToState(manifest: Manifest, fileContents: Record<string, s
79
79
  /**
80
80
  * SqliteRepository — RoleXRepository backed by SQLite via Drizzle.
81
81
  *
82
- * Single database, four tables: nodes, links, prototypes, contexts.
83
- * All state in one place — swap the db connection to go from local to cloud.
82
+ * Five tables: nodes, links, prototypes, contexts, prototype_migrations.
83
+ * Schema managed by Drizzle ORM migrations.
84
84
  */
85
85
 
86
86
  type DB = CommonXDatabase;
87
87
  declare class SqliteRepository implements RoleXRepository {
88
88
  private db;
89
89
  readonly runtime: Runtime;
90
- readonly prototype: PrototypeRegistry;
90
+ readonly prototype: PrototypeRepository;
91
91
  constructor(db: DB);
92
92
  saveContext(roleId: string, data: ContextData): Promise<void>;
93
93
  loadContext(roleId: string): Promise<ContextData | null>;
package/dist/index.js CHANGED
@@ -1,20 +1,22 @@
1
1
  // src/LocalPlatform.ts
2
2
  import { mkdirSync } from "fs";
3
3
  import { homedir } from "os";
4
- import { join } from "path";
4
+ import { join as join2 } from "path";
5
5
  import { drizzle } from "@deepracticex/drizzle";
6
6
  import { openDatabase } from "@deepracticex/sqlite";
7
7
  import { NodeProvider as IssueXNodeProvider } from "@issuexjs/node";
8
8
  import { NodeProvider } from "@resourcexjs/node-provider";
9
9
 
10
10
  // src/SqliteRepository.ts
11
+ import { join } from "path";
12
+ import { migrate } from "@deepracticex/drizzle";
11
13
  import { sql } from "drizzle-orm";
12
14
 
13
15
  // src/sqliteRuntime.ts
14
16
  import { and, eq, isNull } from "drizzle-orm";
15
17
 
16
18
  // src/schema.ts
17
- import { index, primaryKey, sqliteTable, text } from "drizzle-orm/sqlite-core";
19
+ import { index, integer, primaryKey, sqliteTable, text } from "drizzle-orm/sqlite-core";
18
20
  var nodes = sqliteTable(
19
21
  "nodes",
20
22
  {
@@ -47,6 +49,26 @@ var links = sqliteTable(
47
49
  index("idx_links_to").on(table.toRef)
48
50
  ]
49
51
  );
52
+ var prototypes = sqliteTable("prototypes", {
53
+ id: text("id").primaryKey(),
54
+ source: text("source").notNull()
55
+ });
56
+ var contexts = sqliteTable("contexts", {
57
+ roleId: text("role_id").primaryKey(),
58
+ focusedGoalId: text("focused_goal_id"),
59
+ focusedPlanId: text("focused_plan_id")
60
+ });
61
+ var prototypeMigrations = sqliteTable(
62
+ "prototype_migrations",
63
+ {
64
+ prototypeId: text("prototype_id").notNull(),
65
+ migrationId: text("migration_id").notNull(),
66
+ version: integer("version").notNull(),
67
+ checksum: text("checksum").notNull(),
68
+ executedAt: text("executed_at").notNull()
69
+ },
70
+ (table) => [primaryKey({ columns: [table.prototypeId, table.migrationId] })]
71
+ );
50
72
 
51
73
  // src/sqliteRuntime.ts
52
74
  function nextRef(db) {
@@ -200,47 +222,14 @@ function createSqliteRuntime(db) {
200
222
  }
201
223
 
202
224
  // src/SqliteRepository.ts
203
- var DDL = [
204
- sql`CREATE TABLE IF NOT EXISTS nodes (
205
- ref TEXT PRIMARY KEY,
206
- id TEXT,
207
- alias TEXT,
208
- name TEXT NOT NULL,
209
- description TEXT DEFAULT '',
210
- parent_ref TEXT REFERENCES nodes(ref),
211
- information TEXT,
212
- tag TEXT
213
- )`,
214
- sql`CREATE TABLE IF NOT EXISTS links (
215
- from_ref TEXT NOT NULL REFERENCES nodes(ref),
216
- to_ref TEXT NOT NULL REFERENCES nodes(ref),
217
- relation TEXT NOT NULL,
218
- PRIMARY KEY (from_ref, to_ref, relation)
219
- )`,
220
- sql`CREATE TABLE IF NOT EXISTS prototypes (
221
- id TEXT PRIMARY KEY,
222
- source TEXT NOT NULL
223
- )`,
224
- sql`CREATE TABLE IF NOT EXISTS contexts (
225
- role_id TEXT PRIMARY KEY,
226
- focused_goal_id TEXT,
227
- focused_plan_id TEXT
228
- )`,
229
- // Indexes
230
- sql`CREATE INDEX IF NOT EXISTS idx_nodes_id ON nodes(id)`,
231
- sql`CREATE INDEX IF NOT EXISTS idx_nodes_name ON nodes(name)`,
232
- sql`CREATE INDEX IF NOT EXISTS idx_nodes_parent_ref ON nodes(parent_ref)`,
233
- sql`CREATE INDEX IF NOT EXISTS idx_links_from ON links(from_ref)`,
234
- sql`CREATE INDEX IF NOT EXISTS idx_links_to ON links(to_ref)`
235
- ];
236
225
  var SqliteRepository = class {
237
226
  constructor(db) {
238
227
  this.db = db;
239
- for (const stmt of DDL) {
240
- db.run(stmt);
241
- }
228
+ migrate(db, {
229
+ migrationsFolder: join(import.meta.dirname, "../drizzle")
230
+ });
242
231
  this.runtime = createSqliteRuntime(db);
243
- this.prototype = createPrototypeRegistry(db);
232
+ this.prototype = createPrototypeRepository(db);
244
233
  }
245
234
  runtime;
246
235
  prototype;
@@ -261,13 +250,14 @@ var SqliteRepository = class {
261
250
  };
262
251
  }
263
252
  };
264
- function createPrototypeRegistry(db) {
253
+ function createPrototypeRepository(db) {
265
254
  return {
266
255
  settle(id, source) {
267
256
  db.run(sql`INSERT OR REPLACE INTO prototypes (id, source) VALUES (${id}, ${source})`);
268
257
  },
269
258
  evict(id) {
270
259
  db.run(sql`DELETE FROM prototypes WHERE id = ${id}`);
260
+ db.run(sql`DELETE FROM prototype_migrations WHERE prototype_id = ${id}`);
271
261
  },
272
262
  list() {
273
263
  const rows = db.all(sql`SELECT id, source FROM prototypes`);
@@ -276,20 +266,48 @@ function createPrototypeRegistry(db) {
276
266
  result[row.id] = row.source;
277
267
  }
278
268
  return result;
269
+ },
270
+ recordMigration(prototypeId, migrationId, version, checksum) {
271
+ const executedAt = (/* @__PURE__ */ new Date()).toISOString();
272
+ db.run(
273
+ sql`INSERT OR REPLACE INTO prototype_migrations (prototype_id, migration_id, version, checksum, executed_at)
274
+ VALUES (${prototypeId}, ${migrationId}, ${version}, ${checksum}, ${executedAt})`
275
+ );
276
+ },
277
+ getMigrationHistory(prototypeId) {
278
+ return db.all(
279
+ sql`SELECT prototype_id, migration_id, version, checksum, executed_at
280
+ FROM prototype_migrations
281
+ WHERE prototype_id = ${prototypeId}
282
+ ORDER BY version`
283
+ ).map((row) => ({
284
+ prototypeId: row.prototype_id,
285
+ migrationId: row.migration_id,
286
+ version: row.version,
287
+ checksum: row.checksum,
288
+ executedAt: row.executed_at
289
+ }));
290
+ },
291
+ hasMigration(prototypeId, migrationId) {
292
+ const rows = db.all(
293
+ sql`SELECT COUNT(*) as cnt FROM prototype_migrations
294
+ WHERE prototype_id = ${prototypeId} AND migration_id = ${migrationId}`
295
+ );
296
+ return rows.length > 0 && rows[0].cnt > 0;
279
297
  }
280
298
  };
281
299
  }
282
300
 
283
301
  // src/LocalPlatform.ts
284
302
  function deepracticeHome() {
285
- return process.env.DEEPRACTICE_HOME ?? join(homedir(), ".deepractice");
303
+ return process.env.DEEPRACTICE_HOME ?? join2(homedir(), ".deepractice");
286
304
  }
287
305
  function localPlatform(config = {}) {
288
- const dataDir = config.dataDir === null ? void 0 : config.dataDir ?? join(deepracticeHome(), "rolex");
306
+ const dataDir = config.dataDir === null ? void 0 : config.dataDir ?? join2(deepracticeHome(), "rolex");
289
307
  let dbPath;
290
308
  if (dataDir) {
291
309
  mkdirSync(dataDir, { recursive: true });
292
- dbPath = join(dataDir, "rolex.db");
310
+ dbPath = join2(dataDir, "rolex.db");
293
311
  } else {
294
312
  dbPath = ":memory:";
295
313
  }
@@ -319,7 +337,7 @@ function localPlatform(config = {}) {
319
337
  resourcexProvider,
320
338
  issuexProvider,
321
339
  initializer,
322
- bootstrap: config.bootstrap
340
+ prototypes: config.prototypes
323
341
  };
324
342
  }
325
343
 
package/dist/index.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"sources":["../src/LocalPlatform.ts","../src/SqliteRepository.ts","../src/sqliteRuntime.ts","../src/schema.ts","../src/manifest.ts"],"sourcesContent":["/**\n * localPlatform — create a Platform backed by SQLite + local filesystem.\n *\n * Storage:\n * {dataDir}/rolex.db — SQLite database (all state: nodes, links, prototypes, contexts)\n *\n * When dataDir is null, runs with in-memory SQLite (useful for tests).\n */\n\nimport { mkdirSync } from \"node:fs\";\nimport { homedir } from \"node:os\";\nimport { join } from \"node:path\";\nimport { drizzle } from \"@deepracticex/drizzle\";\nimport { openDatabase } from \"@deepracticex/sqlite\";\nimport { NodeProvider as IssueXNodeProvider } from \"@issuexjs/node\";\nimport { NodeProvider } from \"@resourcexjs/node-provider\";\nimport type { Platform } from \"@rolexjs/core\";\nimport type { Initializer } from \"@rolexjs/system\";\nimport { SqliteRepository } from \"./SqliteRepository.js\";\n\n// ===== Config =====\n\nexport interface LocalPlatformConfig {\n /** Directory for persistent storage. Defaults to ~/.deepractice/rolex. Set to null for in-memory only. */\n dataDir?: string | null;\n /** Directory for ResourceX storage. Defaults to ~/.deepractice/resourcex. Set to null to disable. */\n resourceDir?: string | null;\n /** Prototype sources to settle on genesis. */\n bootstrap?: string[];\n}\n\n// ===== Factory =====\n\n/** Resolve the DEEPRACTICE_HOME base directory. Env > default (~/.deepractice). */\nfunction deepracticeHome(): string {\n return process.env.DEEPRACTICE_HOME ?? join(homedir(), \".deepractice\");\n}\n\n/** Create a local Platform. Persistent by default ($DEEPRACTICE_HOME/rolex), in-memory if dataDir is null. */\nexport function localPlatform(config: LocalPlatformConfig = {}): Platform {\n const dataDir =\n config.dataDir === null ? undefined : (config.dataDir ?? join(deepracticeHome(), \"rolex\"));\n\n // ===== SQLite database =====\n\n let dbPath: string;\n if (dataDir) {\n mkdirSync(dataDir, { recursive: true });\n dbPath = join(dataDir, \"rolex.db\");\n } else {\n dbPath = \":memory:\";\n }\n\n const rawDb = openDatabase(dbPath);\n const db = drizzle(rawDb);\n\n // ===== Repository (all state in one place) =====\n\n const repository = new SqliteRepository(db);\n\n // ===== ResourceX Provider =====\n\n const resourcexProvider = config.resourceDir !== null ? new NodeProvider() : undefined;\n\n // ===== IssueX Provider =====\n\n const issuexProvider = new IssueXNodeProvider({\n db: {\n run(sql: string, ...params: unknown[]) {\n rawDb.prepare(sql).run(...params);\n },\n get<T = unknown>(sql: string, ...params: unknown[]): T | null {\n return rawDb.prepare(sql).get(...params) as T | null;\n },\n all<T = unknown>(sql: string, ...params: unknown[]): T[] {\n return rawDb.prepare(sql).all(...params) as T[];\n },\n },\n });\n\n // ===== Initializer =====\n\n const initializer: Initializer = {\n async bootstrap() {},\n };\n\n return {\n repository,\n resourcexProvider,\n issuexProvider,\n initializer,\n bootstrap: config.bootstrap,\n };\n}\n","/**\n * SqliteRepository — RoleXRepository backed by SQLite via Drizzle.\n *\n * Single database, four tables: nodes, links, prototypes, contexts.\n * All state in one place — swap the db connection to go from local to cloud.\n */\n\nimport type { CommonXDatabase } from \"@deepracticex/drizzle\";\nimport type { ContextData, PrototypeRegistry, RoleXRepository } from \"@rolexjs/core\";\nimport type { Runtime } from \"@rolexjs/system\";\nimport { sql } from \"drizzle-orm\";\nimport { createSqliteRuntime } from \"./sqliteRuntime.js\";\n\ntype DB = CommonXDatabase;\n\n// ===== DDL =====\n\nconst DDL = [\n sql`CREATE TABLE IF NOT EXISTS nodes (\n ref TEXT PRIMARY KEY,\n id TEXT,\n alias TEXT,\n name TEXT NOT NULL,\n description TEXT DEFAULT '',\n parent_ref TEXT REFERENCES nodes(ref),\n information TEXT,\n tag TEXT\n )`,\n sql`CREATE TABLE IF NOT EXISTS links (\n from_ref TEXT NOT NULL REFERENCES nodes(ref),\n to_ref TEXT NOT NULL REFERENCES nodes(ref),\n relation TEXT NOT NULL,\n PRIMARY KEY (from_ref, to_ref, relation)\n )`,\n sql`CREATE TABLE IF NOT EXISTS prototypes (\n id TEXT PRIMARY KEY,\n source TEXT NOT NULL\n )`,\n sql`CREATE TABLE IF NOT EXISTS contexts (\n role_id TEXT PRIMARY KEY,\n focused_goal_id TEXT,\n focused_plan_id TEXT\n )`,\n // Indexes\n sql`CREATE INDEX IF NOT EXISTS idx_nodes_id ON nodes(id)`,\n sql`CREATE INDEX IF NOT EXISTS idx_nodes_name ON nodes(name)`,\n sql`CREATE INDEX IF NOT EXISTS idx_nodes_parent_ref ON nodes(parent_ref)`,\n sql`CREATE INDEX IF NOT EXISTS idx_links_from ON links(from_ref)`,\n sql`CREATE INDEX IF NOT EXISTS idx_links_to ON links(to_ref)`,\n];\n\n// ===== Repository =====\n\nexport class SqliteRepository implements RoleXRepository {\n readonly runtime: Runtime;\n readonly prototype: PrototypeRegistry;\n\n constructor(private db: DB) {\n // Ensure all tables exist\n for (const stmt of DDL) {\n db.run(stmt);\n }\n\n this.runtime = createSqliteRuntime(db);\n this.prototype = createPrototypeRegistry(db);\n }\n\n async saveContext(roleId: string, data: ContextData): Promise<void> {\n this.db.run(\n sql`INSERT OR REPLACE INTO contexts (role_id, focused_goal_id, focused_plan_id)\n VALUES (${roleId}, ${data.focusedGoalId}, ${data.focusedPlanId})`\n );\n }\n\n async loadContext(roleId: string): Promise<ContextData | null> {\n const row = this.db.all<{\n role_id: string;\n focused_goal_id: string | null;\n focused_plan_id: string | null;\n }>(\n sql`SELECT role_id, focused_goal_id, focused_plan_id FROM contexts WHERE role_id = ${roleId}`\n );\n if (row.length === 0) return null;\n return {\n focusedGoalId: row[0].focused_goal_id,\n focusedPlanId: row[0].focused_plan_id,\n };\n }\n}\n\n// ===== Prototype Registry (SQLite-backed) =====\n\nfunction createPrototypeRegistry(db: DB): PrototypeRegistry {\n return {\n settle(id: string, source: string) {\n db.run(sql`INSERT OR REPLACE INTO prototypes (id, source) VALUES (${id}, ${source})`);\n },\n\n evict(id: string) {\n db.run(sql`DELETE FROM prototypes WHERE id = ${id}`);\n },\n\n list(): Record<string, string> {\n const rows = db.all<{ id: string; source: string }>(sql`SELECT id, source FROM prototypes`);\n const result: Record<string, string> = {};\n for (const row of rows) {\n result[row.id] = row.source;\n }\n return result;\n },\n };\n}\n","/**\n * SQLite-backed Runtime — single source of truth.\n *\n * Every operation reads/writes directly to SQLite.\n * No in-memory Map, no load/save cycle, no stale refs.\n */\n\nimport type { CommonXDatabase } from \"@deepracticex/drizzle\";\nimport type { Runtime, State, Structure } from \"@rolexjs/system\";\nimport { and, eq, isNull } from \"drizzle-orm\";\nimport { links, nodes } from \"./schema.js\";\n\ntype DB = CommonXDatabase;\n\n// ===== Helpers =====\n\nfunction nextRef(db: DB): string {\n const max = db\n .select({ ref: nodes.ref })\n .from(nodes)\n .all()\n .reduce((max, r) => {\n const n = parseInt(r.ref.slice(1), 10);\n return Number.isNaN(n) ? max : Math.max(max, n);\n }, 0);\n return `n${max + 1}`;\n}\n\nfunction toStructure(row: typeof nodes.$inferSelect): Structure {\n return {\n ref: row.ref,\n ...(row.id ? { id: row.id } : {}),\n ...(row.alias ? { alias: JSON.parse(row.alias) } : {}),\n name: row.name,\n description: row.description ?? \"\",\n parent: null, // Runtime doesn't use parent as Structure; tree is via parentRef\n ...(row.information ? { information: row.information } : {}),\n ...(row.tag ? { tag: row.tag } : {}),\n };\n}\n\n// ===== Projection =====\n\nfunction projectNode(db: DB, ref: string): State {\n const row = db.select().from(nodes).where(eq(nodes.ref, ref)).get();\n if (!row) throw new Error(`Node not found: ${ref}`);\n\n const children = db.select().from(nodes).where(eq(nodes.parentRef, ref)).all();\n\n const nodeLinks = db.select().from(links).where(eq(links.fromRef, ref)).all();\n\n return {\n ...toStructure(row),\n children: children.map((c) => projectNode(db, c.ref)),\n ...(nodeLinks.length > 0\n ? {\n links: nodeLinks.map((l) => ({\n relation: l.relation,\n target: projectLinked(db, l.toRef),\n })),\n }\n : {}),\n };\n}\n\n/** Project a node with full subtree but without following links (prevents cycles). */\nfunction projectLinked(db: DB, ref: string): State {\n const row = db.select().from(nodes).where(eq(nodes.ref, ref)).get();\n if (!row) throw new Error(`Node not found: ${ref}`);\n const children = db.select().from(nodes).where(eq(nodes.parentRef, ref)).all();\n return {\n ...toStructure(row),\n children: children.map((c) => projectLinked(db, c.ref)),\n };\n}\n\n// ===== Subtree removal =====\n\nfunction removeSubtree(db: DB, ref: string): void {\n // Remove children first (depth-first)\n const children = db.select({ ref: nodes.ref }).from(nodes).where(eq(nodes.parentRef, ref)).all();\n for (const child of children) {\n removeSubtree(db, child.ref);\n }\n\n // Remove links from/to this node\n db.delete(links).where(eq(links.fromRef, ref)).run();\n db.delete(links).where(eq(links.toRef, ref)).run();\n\n // Remove the node itself\n db.delete(nodes).where(eq(nodes.ref, ref)).run();\n}\n\n// ===== Runtime factory =====\n\nexport function createSqliteRuntime(db: DB): Runtime {\n return {\n async create(parent, type, information, id, alias) {\n // Idempotent: same id under same parent → return existing.\n if (id) {\n const existing = db\n .select()\n .from(nodes)\n .where(and(eq(nodes.id, id), eq(nodes.parentRef, parent?.ref ?? null)))\n .get();\n if (existing) return toStructure(existing);\n }\n const ref = nextRef(db);\n db.insert(nodes)\n .values({\n ref,\n id: id ?? null,\n alias: alias && alias.length > 0 ? JSON.stringify(alias) : null,\n name: type.name,\n description: type.description,\n parentRef: parent?.ref ?? null,\n information: information ?? null,\n tag: null,\n })\n .run();\n return toStructure(db.select().from(nodes).where(eq(nodes.ref, ref)).get()!);\n },\n\n async remove(node) {\n if (!node.ref) return;\n const row = db.select().from(nodes).where(eq(nodes.ref, node.ref)).get();\n if (!row) return;\n\n // Detach from parent's children (implicit via parentRef)\n removeSubtree(db, node.ref);\n },\n\n async transform(source, target, information) {\n if (!source.ref) throw new Error(\"Source node has no ref\");\n const row = db.select().from(nodes).where(eq(nodes.ref, source.ref)).get();\n if (!row) throw new Error(`Source node not found: ${source.ref}`);\n\n const targetParent = target.parent;\n if (!targetParent) {\n throw new Error(`Cannot transform to root structure: ${target.name}`);\n }\n\n const parentRow = db.select().from(nodes).where(eq(nodes.name, targetParent.name)).get();\n if (!parentRow) {\n throw new Error(`No node found for structure: ${targetParent.name}`);\n }\n\n // Reparent + update type in place — subtree preserved\n db.update(nodes)\n .set({\n parentRef: parentRow.ref,\n name: target.name,\n description: target.description,\n ...(information !== undefined ? { information } : {}),\n })\n .where(eq(nodes.ref, source.ref))\n .run();\n\n return toStructure(db.select().from(nodes).where(eq(nodes.ref, source.ref)).get()!);\n },\n\n async link(from, to, relationName, reverseName) {\n if (!from.ref) throw new Error(\"Source node has no ref\");\n if (!to.ref) throw new Error(\"Target node has no ref\");\n\n // Forward: from → to\n const existsForward = db\n .select()\n .from(links)\n .where(\n and(\n eq(links.fromRef, from.ref),\n eq(links.toRef, to.ref),\n eq(links.relation, relationName)\n )\n )\n .get();\n if (!existsForward) {\n db.insert(links).values({ fromRef: from.ref, toRef: to.ref, relation: relationName }).run();\n }\n\n // Reverse: to → from\n const existsReverse = db\n .select()\n .from(links)\n .where(\n and(eq(links.fromRef, to.ref), eq(links.toRef, from.ref), eq(links.relation, reverseName))\n )\n .get();\n if (!existsReverse) {\n db.insert(links).values({ fromRef: to.ref, toRef: from.ref, relation: reverseName }).run();\n }\n },\n\n async unlink(from, to, relationName, reverseName) {\n if (!from.ref || !to.ref) return;\n\n db.delete(links)\n .where(\n and(\n eq(links.fromRef, from.ref),\n eq(links.toRef, to.ref),\n eq(links.relation, relationName)\n )\n )\n .run();\n\n db.delete(links)\n .where(\n and(eq(links.fromRef, to.ref), eq(links.toRef, from.ref), eq(links.relation, reverseName))\n )\n .run();\n },\n\n async tag(node, tagValue) {\n if (!node.ref) throw new Error(\"Node has no ref\");\n const row = db.select().from(nodes).where(eq(nodes.ref, node.ref)).get();\n if (!row) throw new Error(`Node not found: ${node.ref}`);\n db.update(nodes).set({ tag: tagValue }).where(eq(nodes.ref, node.ref)).run();\n },\n\n async project(node) {\n if (!node.ref) throw new Error(`Node has no ref`);\n return projectNode(db, node.ref);\n },\n\n async roots() {\n const rows = db.select().from(nodes).where(isNull(nodes.parentRef)).all();\n return rows.map(toStructure);\n },\n };\n}\n","/**\n * Drizzle schema — SQLite tables for the RoleX runtime graph.\n *\n * Two tables:\n * nodes — tree backbone (Structure instances)\n * links — cross-branch relations (bidirectional)\n */\n\nimport { index, primaryKey, sqliteTable, text } from \"drizzle-orm/sqlite-core\";\n\n/**\n * nodes — every node in the society graph.\n *\n * Maps 1:1 to the Structure interface:\n * ref → graph-internal reference (primary key)\n * id → user-facing kebab-case identifier\n * alias → JSON array of alternative names\n * name → structure type (\"individual\", \"goal\", \"task\", etc.)\n * description → what this structure is\n * parent_ref → tree parent (self-referencing foreign key)\n * information → Gherkin Feature source text\n * tag → generic label (\"done\", \"abandoned\")\n */\nexport const nodes = sqliteTable(\n \"nodes\",\n {\n ref: text(\"ref\").primaryKey(),\n id: text(\"id\"),\n alias: text(\"alias\"), // JSON array: '[\"Sean\",\"姜山\"]'\n name: text(\"name\").notNull(),\n description: text(\"description\").default(\"\"),\n parentRef: text(\"parent_ref\").references((): any => nodes.ref),\n information: text(\"information\"),\n tag: text(\"tag\"),\n },\n (table) => [\n index(\"idx_nodes_id\").on(table.id),\n index(\"idx_nodes_name\").on(table.name),\n index(\"idx_nodes_parent_ref\").on(table.parentRef),\n ]\n);\n\n/**\n * links — cross-branch relations between nodes.\n *\n * Bidirectional: if A→B is \"membership\", B→A is \"belong\".\n * Both directions stored as separate rows.\n */\nexport const links = sqliteTable(\n \"links\",\n {\n fromRef: text(\"from_ref\")\n .notNull()\n .references(() => nodes.ref),\n toRef: text(\"to_ref\")\n .notNull()\n .references(() => nodes.ref),\n relation: text(\"relation\").notNull(),\n },\n (table) => [\n primaryKey({ columns: [table.fromRef, table.toRef, table.relation] }),\n index(\"idx_links_from\").on(table.fromRef),\n index(\"idx_links_to\").on(table.toRef),\n ]\n);\n","/**\n * Manifest — file-based storage format for RoleX entities.\n *\n * Storage layout:\n * role/<id>/\n * individual.json — manifest (tree structure + links)\n * <id>.<type>.feature — node information (Gherkin)\n *\n * organization/<id>/\n * organization.json — manifest (tree structure + links)\n * <id>.<type>.feature — node information (Gherkin)\n *\n * Rules:\n * - Directories: only role/ and organization/ at top level\n * - Files: all [id].[type].feature, flat within the entity directory\n * - Manifest: tree structure in JSON, content in .feature files\n * - Nodes without explicit id default to their type name\n */\n\nimport type { State } from \"@rolexjs/system\";\n\n// ===== Manifest types =====\n\n/** A node in the manifest tree. */\nexport interface ManifestNode {\n readonly type: string;\n readonly ref?: string;\n readonly tag?: string;\n readonly children?: Record<string, ManifestNode>;\n readonly links?: Record<string, string[]>;\n}\n\n/** Root manifest for an entity (individual or organization). */\nexport interface Manifest {\n readonly id: string;\n readonly type: string;\n readonly ref?: string;\n readonly alias?: readonly string[];\n readonly children?: Record<string, ManifestNode>;\n readonly links?: Record<string, string[]>;\n}\n\n// ===== State → files =====\n\nexport interface FileEntry {\n readonly path: string;\n readonly content: string;\n}\n\n/**\n * Convert a State tree to a manifest + feature files.\n * Returns the manifest and a list of file entries (path → content).\n */\nexport function stateToFiles(state: State): { manifest: Manifest; files: FileEntry[] } {\n const files: FileEntry[] = [];\n\n const collectFiles = (node: State, nodeId: string) => {\n if (node.information) {\n files.push({\n path: `${nodeId}.${node.name}.feature`,\n content: node.information,\n });\n }\n if (node.children) {\n for (const child of node.children) {\n const childId = child.id ?? child.name;\n collectFiles(child, childId);\n }\n }\n };\n\n const rootId = state.id ?? state.name;\n collectFiles(state, rootId);\n\n const buildManifestNode = (node: State): ManifestNode => {\n const entry: ManifestNode = {\n type: node.name,\n ...(node.ref ? { ref: node.ref } : {}),\n ...(node.tag ? { tag: node.tag } : {}),\n ...(node.links && node.links.length > 0 ? { links: buildManifestLinks(node.links) } : {}),\n };\n if (node.children && node.children.length > 0) {\n const children: Record<string, ManifestNode> = {};\n for (const child of node.children) {\n const childId = child.id ?? child.name;\n children[childId] = buildManifestNode(child);\n }\n return { ...entry, children };\n }\n return entry;\n };\n\n const manifestNode = buildManifestNode(state);\n\n const manifest: Manifest = {\n id: rootId,\n type: state.name,\n ...(state.ref ? { ref: state.ref } : {}),\n ...(state.alias ? { alias: state.alias } : {}),\n ...(manifestNode.children ? { children: manifestNode.children } : {}),\n ...(state.links && state.links.length > 0\n ? {\n links: buildManifestLinks(state.links),\n }\n : {}),\n };\n\n return { manifest, files };\n}\n\nfunction buildManifestLinks(\n links: readonly { readonly relation: string; readonly target: State }[]\n): Record<string, string[]> {\n const result: Record<string, string[]> = {};\n for (const link of links) {\n const targetId = link.target.id ?? link.target.name;\n if (!result[link.relation]) {\n result[link.relation] = [];\n }\n result[link.relation].push(targetId);\n }\n return result;\n}\n\n// ===== Files → State =====\n\n/**\n * Convert a manifest + feature file contents to a State tree.\n * fileContents maps filename (e.g. \"role-creation.principle.feature\") to Gherkin text.\n */\nexport function filesToState(manifest: Manifest, fileContents: Record<string, string>): State {\n const buildState = (id: string, node: ManifestNode): State => {\n const filename = `${id}.${node.type}.feature`;\n const information = fileContents[filename];\n\n const children: State[] = [];\n if (node.children) {\n for (const [childId, childNode] of Object.entries(node.children)) {\n children.push(buildState(childId, childNode));\n }\n }\n\n const nodeLinks: { relation: string; target: State }[] = [];\n if (node.links) {\n for (const [relation, targetIds] of Object.entries(node.links)) {\n for (const targetId of targetIds) {\n nodeLinks.push({\n relation,\n target: { id: targetId, name: \"\", description: \"\", parent: null },\n });\n }\n }\n }\n\n return {\n ...(node.ref ? { ref: node.ref } : {}),\n id,\n name: node.type,\n description: \"\",\n parent: null,\n ...(node.tag ? { tag: node.tag } : {}),\n ...(information ? { information } : {}),\n ...(children.length > 0 ? { children } : {}),\n ...(nodeLinks.length > 0 ? { links: nodeLinks } : {}),\n };\n };\n\n const rootFilename = `${manifest.id}.${manifest.type}.feature`;\n const rootInformation = fileContents[rootFilename];\n\n const children: State[] = [];\n if (manifest.children) {\n for (const [childId, childNode] of Object.entries(manifest.children)) {\n children.push(buildState(childId, childNode));\n }\n }\n\n const links: { relation: string; target: State }[] = [];\n if (manifest.links) {\n for (const [relation, targetIds] of Object.entries(manifest.links)) {\n for (const targetId of targetIds) {\n links.push({\n relation,\n target: {\n id: targetId,\n name: \"\",\n description: \"\",\n parent: null,\n },\n });\n }\n }\n }\n\n return {\n ...(manifest.ref ? { ref: manifest.ref } : {}),\n id: manifest.id,\n ...(manifest.alias ? { alias: manifest.alias } : {}),\n name: manifest.type,\n description: \"\",\n parent: null,\n ...(rootInformation ? { information: rootInformation } : {}),\n ...(children.length > 0 ? { children } : {}),\n ...(links.length > 0 ? { links } : {}),\n };\n}\n"],"mappings":"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","names":["max","sql","links","children"]}
1
+ {"version":3,"sources":["../src/LocalPlatform.ts","../src/SqliteRepository.ts","../src/sqliteRuntime.ts","../src/schema.ts","../src/manifest.ts"],"sourcesContent":["/**\n * localPlatform — create a Platform backed by SQLite + local filesystem.\n *\n * Storage:\n * {dataDir}/rolex.db — SQLite database (all state: nodes, links, prototypes, contexts)\n *\n * When dataDir is null, runs with in-memory SQLite (useful for tests).\n */\n\nimport { mkdirSync } from \"node:fs\";\nimport { homedir } from \"node:os\";\nimport { join } from \"node:path\";\nimport { drizzle } from \"@deepracticex/drizzle\";\nimport { openDatabase } from \"@deepracticex/sqlite\";\nimport { NodeProvider as IssueXNodeProvider } from \"@issuexjs/node\";\nimport { NodeProvider } from \"@resourcexjs/node-provider\";\nimport type { Platform, PrototypeData } from \"@rolexjs/core\";\nimport type { Initializer } from \"@rolexjs/system\";\nimport { SqliteRepository } from \"./SqliteRepository.js\";\n\n// ===== Config =====\n\nexport interface LocalPlatformConfig {\n /** Directory for persistent storage. Defaults to ~/.deepractice/rolex. Set to null for in-memory only. */\n dataDir?: string | null;\n /** Directory for ResourceX storage. Defaults to ~/.deepractice/resourcex. Set to null to disable. */\n resourceDir?: string | null;\n /** Prototype data to apply on genesis. */\n prototypes?: PrototypeData[];\n}\n\n// ===== Factory =====\n\n/** Resolve the DEEPRACTICE_HOME base directory. Env > default (~/.deepractice). */\nfunction deepracticeHome(): string {\n return process.env.DEEPRACTICE_HOME ?? join(homedir(), \".deepractice\");\n}\n\n/** Create a local Platform. Persistent by default ($DEEPRACTICE_HOME/rolex), in-memory if dataDir is null. */\nexport function localPlatform(config: LocalPlatformConfig = {}): Platform {\n const dataDir =\n config.dataDir === null ? undefined : (config.dataDir ?? join(deepracticeHome(), \"rolex\"));\n\n // ===== SQLite database =====\n\n let dbPath: string;\n if (dataDir) {\n mkdirSync(dataDir, { recursive: true });\n dbPath = join(dataDir, \"rolex.db\");\n } else {\n dbPath = \":memory:\";\n }\n\n const rawDb = openDatabase(dbPath);\n const db = drizzle(rawDb);\n\n // ===== Repository (all state in one place) =====\n\n const repository = new SqliteRepository(db);\n\n // ===== ResourceX Provider =====\n\n const resourcexProvider = config.resourceDir !== null ? new NodeProvider() : undefined;\n\n // ===== IssueX Provider =====\n\n const issuexProvider = new IssueXNodeProvider({\n db: {\n run(sql: string, ...params: unknown[]) {\n rawDb.prepare(sql).run(...params);\n },\n get<T = unknown>(sql: string, ...params: unknown[]): T | null {\n return rawDb.prepare(sql).get(...params) as T | null;\n },\n all<T = unknown>(sql: string, ...params: unknown[]): T[] {\n return rawDb.prepare(sql).all(...params) as T[];\n },\n },\n });\n\n // ===== Initializer =====\n\n const initializer: Initializer = {\n async bootstrap() {},\n };\n\n return {\n repository,\n resourcexProvider,\n issuexProvider,\n initializer,\n prototypes: config.prototypes,\n };\n}\n","/**\n * SqliteRepository — RoleXRepository backed by SQLite via Drizzle.\n *\n * Five tables: nodes, links, prototypes, contexts, prototype_migrations.\n * Schema managed by Drizzle ORM migrations.\n */\n\nimport { join } from \"node:path\";\nimport type { CommonXDatabase } from \"@deepracticex/drizzle\";\nimport { migrate } from \"@deepracticex/drizzle\";\nimport type {\n ContextData,\n MigrationRecord,\n PrototypeRepository,\n RoleXRepository,\n} from \"@rolexjs/core\";\nimport type { Runtime } from \"@rolexjs/system\";\nimport { sql } from \"drizzle-orm\";\nimport { createSqliteRuntime } from \"./sqliteRuntime.js\";\n\ntype DB = CommonXDatabase;\n\n// ===== Repository =====\n\nexport class SqliteRepository implements RoleXRepository {\n readonly runtime: Runtime;\n readonly prototype: PrototypeRepository;\n\n constructor(private db: DB) {\n // Run Drizzle migrations — handles schema creation and evolution\n migrate(db, {\n migrationsFolder: join(import.meta.dirname, \"../drizzle\"),\n });\n\n this.runtime = createSqliteRuntime(db);\n this.prototype = createPrototypeRepository(db);\n }\n\n async saveContext(roleId: string, data: ContextData): Promise<void> {\n this.db.run(\n sql`INSERT OR REPLACE INTO contexts (role_id, focused_goal_id, focused_plan_id)\n VALUES (${roleId}, ${data.focusedGoalId}, ${data.focusedPlanId})`\n );\n }\n\n async loadContext(roleId: string): Promise<ContextData | null> {\n const row = this.db.all<{\n role_id: string;\n focused_goal_id: string | null;\n focused_plan_id: string | null;\n }>(\n sql`SELECT role_id, focused_goal_id, focused_plan_id FROM contexts WHERE role_id = ${roleId}`\n );\n if (row.length === 0) return null;\n return {\n focusedGoalId: row[0].focused_goal_id,\n focusedPlanId: row[0].focused_plan_id,\n };\n }\n}\n\n// ===== Prototype Registry (SQLite-backed) =====\n\nfunction createPrototypeRepository(db: DB): PrototypeRepository {\n return {\n settle(id: string, source: string) {\n db.run(sql`INSERT OR REPLACE INTO prototypes (id, source) VALUES (${id}, ${source})`);\n },\n\n evict(id: string) {\n db.run(sql`DELETE FROM prototypes WHERE id = ${id}`);\n db.run(sql`DELETE FROM prototype_migrations WHERE prototype_id = ${id}`);\n },\n\n list(): Record<string, string> {\n const rows = db.all<{ id: string; source: string }>(sql`SELECT id, source FROM prototypes`);\n const result: Record<string, string> = {};\n for (const row of rows) {\n result[row.id] = row.source;\n }\n return result;\n },\n\n recordMigration(prototypeId: string, migrationId: string, version: number, checksum: string) {\n const executedAt = new Date().toISOString();\n db.run(\n sql`INSERT OR REPLACE INTO prototype_migrations (prototype_id, migration_id, version, checksum, executed_at)\n VALUES (${prototypeId}, ${migrationId}, ${version}, ${checksum}, ${executedAt})`\n );\n },\n\n getMigrationHistory(prototypeId: string): MigrationRecord[] {\n return db\n .all<{\n prototype_id: string;\n migration_id: string;\n version: number;\n checksum: string;\n executed_at: string;\n }>(\n sql`SELECT prototype_id, migration_id, version, checksum, executed_at\n FROM prototype_migrations\n WHERE prototype_id = ${prototypeId}\n ORDER BY version`\n )\n .map((row) => ({\n prototypeId: row.prototype_id,\n migrationId: row.migration_id,\n version: row.version,\n checksum: row.checksum,\n executedAt: row.executed_at,\n }));\n },\n\n hasMigration(prototypeId: string, migrationId: string): boolean {\n const rows = db.all<{ cnt: number }>(\n sql`SELECT COUNT(*) as cnt FROM prototype_migrations\n WHERE prototype_id = ${prototypeId} AND migration_id = ${migrationId}`\n );\n return rows.length > 0 && rows[0].cnt > 0;\n },\n };\n}\n","/**\n * SQLite-backed Runtime — single source of truth.\n *\n * Every operation reads/writes directly to SQLite.\n * No in-memory Map, no load/save cycle, no stale refs.\n */\n\nimport type { CommonXDatabase } from \"@deepracticex/drizzle\";\nimport type { Runtime, State, Structure } from \"@rolexjs/system\";\nimport { and, eq, isNull } from \"drizzle-orm\";\nimport { links, nodes } from \"./schema.js\";\n\ntype DB = CommonXDatabase;\n\n// ===== Helpers =====\n\nfunction nextRef(db: DB): string {\n const max = db\n .select({ ref: nodes.ref })\n .from(nodes)\n .all()\n .reduce((max, r) => {\n const n = parseInt(r.ref.slice(1), 10);\n return Number.isNaN(n) ? max : Math.max(max, n);\n }, 0);\n return `n${max + 1}`;\n}\n\nfunction toStructure(row: typeof nodes.$inferSelect): Structure {\n return {\n ref: row.ref,\n ...(row.id ? { id: row.id } : {}),\n ...(row.alias ? { alias: JSON.parse(row.alias) } : {}),\n name: row.name,\n description: row.description ?? \"\",\n parent: null, // Runtime doesn't use parent as Structure; tree is via parentRef\n ...(row.information ? { information: row.information } : {}),\n ...(row.tag ? { tag: row.tag } : {}),\n };\n}\n\n// ===== Projection =====\n\nfunction projectNode(db: DB, ref: string): State {\n const row = db.select().from(nodes).where(eq(nodes.ref, ref)).get();\n if (!row) throw new Error(`Node not found: ${ref}`);\n\n const children = db.select().from(nodes).where(eq(nodes.parentRef, ref)).all();\n\n const nodeLinks = db.select().from(links).where(eq(links.fromRef, ref)).all();\n\n return {\n ...toStructure(row),\n children: children.map((c) => projectNode(db, c.ref)),\n ...(nodeLinks.length > 0\n ? {\n links: nodeLinks.map((l) => ({\n relation: l.relation,\n target: projectLinked(db, l.toRef),\n })),\n }\n : {}),\n };\n}\n\n/** Project a node with full subtree but without following links (prevents cycles). */\nfunction projectLinked(db: DB, ref: string): State {\n const row = db.select().from(nodes).where(eq(nodes.ref, ref)).get();\n if (!row) throw new Error(`Node not found: ${ref}`);\n const children = db.select().from(nodes).where(eq(nodes.parentRef, ref)).all();\n return {\n ...toStructure(row),\n children: children.map((c) => projectLinked(db, c.ref)),\n };\n}\n\n// ===== Subtree removal =====\n\nfunction removeSubtree(db: DB, ref: string): void {\n // Remove children first (depth-first)\n const children = db.select({ ref: nodes.ref }).from(nodes).where(eq(nodes.parentRef, ref)).all();\n for (const child of children) {\n removeSubtree(db, child.ref);\n }\n\n // Remove links from/to this node\n db.delete(links).where(eq(links.fromRef, ref)).run();\n db.delete(links).where(eq(links.toRef, ref)).run();\n\n // Remove the node itself\n db.delete(nodes).where(eq(nodes.ref, ref)).run();\n}\n\n// ===== Runtime factory =====\n\nexport function createSqliteRuntime(db: DB): Runtime {\n return {\n async create(parent, type, information, id, alias) {\n // Idempotent: same id under same parent → return existing.\n if (id) {\n const existing = db\n .select()\n .from(nodes)\n .where(and(eq(nodes.id, id), eq(nodes.parentRef, parent?.ref ?? null)))\n .get();\n if (existing) return toStructure(existing);\n }\n const ref = nextRef(db);\n db.insert(nodes)\n .values({\n ref,\n id: id ?? null,\n alias: alias && alias.length > 0 ? JSON.stringify(alias) : null,\n name: type.name,\n description: type.description,\n parentRef: parent?.ref ?? null,\n information: information ?? null,\n tag: null,\n })\n .run();\n return toStructure(db.select().from(nodes).where(eq(nodes.ref, ref)).get()!);\n },\n\n async remove(node) {\n if (!node.ref) return;\n const row = db.select().from(nodes).where(eq(nodes.ref, node.ref)).get();\n if (!row) return;\n\n // Detach from parent's children (implicit via parentRef)\n removeSubtree(db, node.ref);\n },\n\n async transform(source, target, information) {\n if (!source.ref) throw new Error(\"Source node has no ref\");\n const row = db.select().from(nodes).where(eq(nodes.ref, source.ref)).get();\n if (!row) throw new Error(`Source node not found: ${source.ref}`);\n\n const targetParent = target.parent;\n if (!targetParent) {\n throw new Error(`Cannot transform to root structure: ${target.name}`);\n }\n\n const parentRow = db.select().from(nodes).where(eq(nodes.name, targetParent.name)).get();\n if (!parentRow) {\n throw new Error(`No node found for structure: ${targetParent.name}`);\n }\n\n // Reparent + update type in place — subtree preserved\n db.update(nodes)\n .set({\n parentRef: parentRow.ref,\n name: target.name,\n description: target.description,\n ...(information !== undefined ? { information } : {}),\n })\n .where(eq(nodes.ref, source.ref))\n .run();\n\n return toStructure(db.select().from(nodes).where(eq(nodes.ref, source.ref)).get()!);\n },\n\n async link(from, to, relationName, reverseName) {\n if (!from.ref) throw new Error(\"Source node has no ref\");\n if (!to.ref) throw new Error(\"Target node has no ref\");\n\n // Forward: from → to\n const existsForward = db\n .select()\n .from(links)\n .where(\n and(\n eq(links.fromRef, from.ref),\n eq(links.toRef, to.ref),\n eq(links.relation, relationName)\n )\n )\n .get();\n if (!existsForward) {\n db.insert(links).values({ fromRef: from.ref, toRef: to.ref, relation: relationName }).run();\n }\n\n // Reverse: to → from\n const existsReverse = db\n .select()\n .from(links)\n .where(\n and(eq(links.fromRef, to.ref), eq(links.toRef, from.ref), eq(links.relation, reverseName))\n )\n .get();\n if (!existsReverse) {\n db.insert(links).values({ fromRef: to.ref, toRef: from.ref, relation: reverseName }).run();\n }\n },\n\n async unlink(from, to, relationName, reverseName) {\n if (!from.ref || !to.ref) return;\n\n db.delete(links)\n .where(\n and(\n eq(links.fromRef, from.ref),\n eq(links.toRef, to.ref),\n eq(links.relation, relationName)\n )\n )\n .run();\n\n db.delete(links)\n .where(\n and(eq(links.fromRef, to.ref), eq(links.toRef, from.ref), eq(links.relation, reverseName))\n )\n .run();\n },\n\n async tag(node, tagValue) {\n if (!node.ref) throw new Error(\"Node has no ref\");\n const row = db.select().from(nodes).where(eq(nodes.ref, node.ref)).get();\n if (!row) throw new Error(`Node not found: ${node.ref}`);\n db.update(nodes).set({ tag: tagValue }).where(eq(nodes.ref, node.ref)).run();\n },\n\n async project(node) {\n if (!node.ref) throw new Error(`Node has no ref`);\n return projectNode(db, node.ref);\n },\n\n async roots() {\n const rows = db.select().from(nodes).where(isNull(nodes.parentRef)).all();\n return rows.map(toStructure);\n },\n };\n}\n","/**\n * Drizzle schema — SQLite tables for RoleX.\n *\n * Five tables:\n * nodes — tree backbone (Structure instances)\n * links — cross-branch relations (bidirectional)\n * prototypes — which prototype packages are settled\n * contexts — per-role session focus state\n * prototype_migrations — Flyway-style migration history\n */\n\nimport { index, integer, primaryKey, sqliteTable, text } from \"drizzle-orm/sqlite-core\";\n\n/**\n * nodes — every node in the society graph.\n *\n * Maps 1:1 to the Structure interface:\n * ref → graph-internal reference (primary key)\n * id → user-facing kebab-case identifier\n * alias → JSON array of alternative names\n * name → structure type (\"individual\", \"goal\", \"task\", etc.)\n * description → what this structure is\n * parent_ref → tree parent (self-referencing foreign key)\n * information → Gherkin Feature source text\n * tag → generic label (\"done\", \"abandoned\")\n */\nexport const nodes = sqliteTable(\n \"nodes\",\n {\n ref: text(\"ref\").primaryKey(),\n id: text(\"id\"),\n alias: text(\"alias\"), // JSON array: '[\"Sean\",\"姜山\"]'\n name: text(\"name\").notNull(),\n description: text(\"description\").default(\"\"),\n parentRef: text(\"parent_ref\").references((): any => nodes.ref),\n information: text(\"information\"),\n tag: text(\"tag\"),\n },\n (table) => [\n index(\"idx_nodes_id\").on(table.id),\n index(\"idx_nodes_name\").on(table.name),\n index(\"idx_nodes_parent_ref\").on(table.parentRef),\n ]\n);\n\n/**\n * links — cross-branch relations between nodes.\n *\n * Bidirectional: if A→B is \"membership\", B→A is \"belong\".\n * Both directions stored as separate rows.\n */\nexport const links = sqliteTable(\n \"links\",\n {\n fromRef: text(\"from_ref\")\n .notNull()\n .references(() => nodes.ref),\n toRef: text(\"to_ref\")\n .notNull()\n .references(() => nodes.ref),\n relation: text(\"relation\").notNull(),\n },\n (table) => [\n primaryKey({ columns: [table.fromRef, table.toRef, table.relation] }),\n index(\"idx_links_from\").on(table.fromRef),\n index(\"idx_links_to\").on(table.toRef),\n ]\n);\n\n/**\n * prototypes — which prototype packages are settled.\n */\nexport const prototypes = sqliteTable(\"prototypes\", {\n id: text(\"id\").primaryKey(),\n source: text(\"source\").notNull(),\n});\n\n/**\n * contexts — per-role session focus state.\n */\nexport const contexts = sqliteTable(\"contexts\", {\n roleId: text(\"role_id\").primaryKey(),\n focusedGoalId: text(\"focused_goal_id\"),\n focusedPlanId: text(\"focused_plan_id\"),\n});\n\n/**\n * prototype_migrations — Flyway-style migration history.\n *\n * Records which migrations have been executed for each prototype.\n */\nexport const prototypeMigrations = sqliteTable(\n \"prototype_migrations\",\n {\n prototypeId: text(\"prototype_id\").notNull(),\n migrationId: text(\"migration_id\").notNull(),\n version: integer(\"version\").notNull(),\n checksum: text(\"checksum\").notNull(),\n executedAt: text(\"executed_at\").notNull(),\n },\n (table) => [primaryKey({ columns: [table.prototypeId, table.migrationId] })]\n);\n","/**\n * Manifest — file-based storage format for RoleX entities.\n *\n * Storage layout:\n * role/<id>/\n * individual.json — manifest (tree structure + links)\n * <id>.<type>.feature — node information (Gherkin)\n *\n * organization/<id>/\n * organization.json — manifest (tree structure + links)\n * <id>.<type>.feature — node information (Gherkin)\n *\n * Rules:\n * - Directories: only role/ and organization/ at top level\n * - Files: all [id].[type].feature, flat within the entity directory\n * - Manifest: tree structure in JSON, content in .feature files\n * - Nodes without explicit id default to their type name\n */\n\nimport type { State } from \"@rolexjs/system\";\n\n// ===== Manifest types =====\n\n/** A node in the manifest tree. */\nexport interface ManifestNode {\n readonly type: string;\n readonly ref?: string;\n readonly tag?: string;\n readonly children?: Record<string, ManifestNode>;\n readonly links?: Record<string, string[]>;\n}\n\n/** Root manifest for an entity (individual or organization). */\nexport interface Manifest {\n readonly id: string;\n readonly type: string;\n readonly ref?: string;\n readonly alias?: readonly string[];\n readonly children?: Record<string, ManifestNode>;\n readonly links?: Record<string, string[]>;\n}\n\n// ===== State → files =====\n\nexport interface FileEntry {\n readonly path: string;\n readonly content: string;\n}\n\n/**\n * Convert a State tree to a manifest + feature files.\n * Returns the manifest and a list of file entries (path → content).\n */\nexport function stateToFiles(state: State): { manifest: Manifest; files: FileEntry[] } {\n const files: FileEntry[] = [];\n\n const collectFiles = (node: State, nodeId: string) => {\n if (node.information) {\n files.push({\n path: `${nodeId}.${node.name}.feature`,\n content: node.information,\n });\n }\n if (node.children) {\n for (const child of node.children) {\n const childId = child.id ?? child.name;\n collectFiles(child, childId);\n }\n }\n };\n\n const rootId = state.id ?? state.name;\n collectFiles(state, rootId);\n\n const buildManifestNode = (node: State): ManifestNode => {\n const entry: ManifestNode = {\n type: node.name,\n ...(node.ref ? { ref: node.ref } : {}),\n ...(node.tag ? { tag: node.tag } : {}),\n ...(node.links && node.links.length > 0 ? { links: buildManifestLinks(node.links) } : {}),\n };\n if (node.children && node.children.length > 0) {\n const children: Record<string, ManifestNode> = {};\n for (const child of node.children) {\n const childId = child.id ?? child.name;\n children[childId] = buildManifestNode(child);\n }\n return { ...entry, children };\n }\n return entry;\n };\n\n const manifestNode = buildManifestNode(state);\n\n const manifest: Manifest = {\n id: rootId,\n type: state.name,\n ...(state.ref ? { ref: state.ref } : {}),\n ...(state.alias ? { alias: state.alias } : {}),\n ...(manifestNode.children ? { children: manifestNode.children } : {}),\n ...(state.links && state.links.length > 0\n ? {\n links: buildManifestLinks(state.links),\n }\n : {}),\n };\n\n return { manifest, files };\n}\n\nfunction buildManifestLinks(\n links: readonly { readonly relation: string; readonly target: State }[]\n): Record<string, string[]> {\n const result: Record<string, string[]> = {};\n for (const link of links) {\n const targetId = link.target.id ?? link.target.name;\n if (!result[link.relation]) {\n result[link.relation] = [];\n }\n result[link.relation].push(targetId);\n }\n return result;\n}\n\n// ===== Files → State =====\n\n/**\n * Convert a manifest + feature file contents to a State tree.\n * fileContents maps filename (e.g. \"role-creation.principle.feature\") to Gherkin text.\n */\nexport function filesToState(manifest: Manifest, fileContents: Record<string, string>): State {\n const buildState = (id: string, node: ManifestNode): State => {\n const filename = `${id}.${node.type}.feature`;\n const information = fileContents[filename];\n\n const children: State[] = [];\n if (node.children) {\n for (const [childId, childNode] of Object.entries(node.children)) {\n children.push(buildState(childId, childNode));\n }\n }\n\n const nodeLinks: { relation: string; target: State }[] = [];\n if (node.links) {\n for (const [relation, targetIds] of Object.entries(node.links)) {\n for (const targetId of targetIds) {\n nodeLinks.push({\n relation,\n target: { id: targetId, name: \"\", description: \"\", parent: null },\n });\n }\n }\n }\n\n return {\n ...(node.ref ? { ref: node.ref } : {}),\n id,\n name: node.type,\n description: \"\",\n parent: null,\n ...(node.tag ? { tag: node.tag } : {}),\n ...(information ? { information } : {}),\n ...(children.length > 0 ? { children } : {}),\n ...(nodeLinks.length > 0 ? { links: nodeLinks } : {}),\n };\n };\n\n const rootFilename = `${manifest.id}.${manifest.type}.feature`;\n const rootInformation = fileContents[rootFilename];\n\n const children: State[] = [];\n if (manifest.children) {\n for (const [childId, childNode] of Object.entries(manifest.children)) {\n children.push(buildState(childId, childNode));\n }\n }\n\n const links: { relation: string; target: State }[] = [];\n if (manifest.links) {\n for (const [relation, targetIds] of Object.entries(manifest.links)) {\n for (const targetId of targetIds) {\n links.push({\n relation,\n target: {\n id: targetId,\n name: \"\",\n description: \"\",\n parent: null,\n },\n });\n }\n }\n }\n\n return {\n ...(manifest.ref ? { ref: manifest.ref } : {}),\n id: manifest.id,\n ...(manifest.alias ? { alias: manifest.alias } : {}),\n name: manifest.type,\n description: \"\",\n parent: null,\n ...(rootInformation ? { information: rootInformation } : {}),\n ...(children.length > 0 ? { children } : {}),\n ...(links.length > 0 ? { links } : {}),\n };\n}\n"],"mappings":"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","names":["join","max","join","sql","links","children"]}
@@ -0,0 +1,44 @@
1
+ CREATE TABLE IF NOT EXISTS `contexts` (
2
+ `role_id` text PRIMARY KEY NOT NULL,
3
+ `focused_goal_id` text,
4
+ `focused_plan_id` text
5
+ );
6
+ --> statement-breakpoint
7
+ CREATE TABLE IF NOT EXISTS `links` (
8
+ `from_ref` text NOT NULL,
9
+ `to_ref` text NOT NULL,
10
+ `relation` text NOT NULL,
11
+ PRIMARY KEY(`from_ref`, `to_ref`, `relation`),
12
+ FOREIGN KEY (`from_ref`) REFERENCES `nodes`(`ref`) ON UPDATE no action ON DELETE no action,
13
+ FOREIGN KEY (`to_ref`) REFERENCES `nodes`(`ref`) ON UPDATE no action ON DELETE no action
14
+ );
15
+ --> statement-breakpoint
16
+ CREATE INDEX IF NOT EXISTS `idx_links_from` ON `links` (`from_ref`);--> statement-breakpoint
17
+ CREATE INDEX IF NOT EXISTS `idx_links_to` ON `links` (`to_ref`);--> statement-breakpoint
18
+ CREATE TABLE IF NOT EXISTS `nodes` (
19
+ `ref` text PRIMARY KEY NOT NULL,
20
+ `id` text,
21
+ `alias` text,
22
+ `name` text NOT NULL,
23
+ `description` text DEFAULT '',
24
+ `parent_ref` text,
25
+ `information` text,
26
+ `tag` text,
27
+ FOREIGN KEY (`parent_ref`) REFERENCES `nodes`(`ref`) ON UPDATE no action ON DELETE no action
28
+ );
29
+ --> statement-breakpoint
30
+ CREATE INDEX IF NOT EXISTS `idx_nodes_id` ON `nodes` (`id`);--> statement-breakpoint
31
+ CREATE INDEX IF NOT EXISTS `idx_nodes_name` ON `nodes` (`name`);--> statement-breakpoint
32
+ CREATE INDEX IF NOT EXISTS `idx_nodes_parent_ref` ON `nodes` (`parent_ref`);--> statement-breakpoint
33
+ CREATE TABLE IF NOT EXISTS `prototype_migrations` (
34
+ `prototype_id` text NOT NULL,
35
+ `migration_id` text NOT NULL,
36
+ `checksum` text NOT NULL,
37
+ `executed_at` text NOT NULL,
38
+ PRIMARY KEY(`prototype_id`, `migration_id`)
39
+ );
40
+ --> statement-breakpoint
41
+ CREATE TABLE IF NOT EXISTS `prototypes` (
42
+ `id` text PRIMARY KEY NOT NULL,
43
+ `source` text NOT NULL
44
+ );
@@ -0,0 +1 @@
1
+ ALTER TABLE `prototype_migrations` ADD `version` integer NOT NULL DEFAULT 0;
@@ -0,0 +1,275 @@
1
+ {
2
+ "version": "6",
3
+ "dialect": "sqlite",
4
+ "id": "86f29a5e-3324-4b28-8b2a-b022b6d19fde",
5
+ "prevId": "00000000-0000-0000-0000-000000000000",
6
+ "tables": {
7
+ "contexts": {
8
+ "name": "contexts",
9
+ "columns": {
10
+ "role_id": {
11
+ "name": "role_id",
12
+ "type": "text",
13
+ "primaryKey": true,
14
+ "notNull": true,
15
+ "autoincrement": false
16
+ },
17
+ "focused_goal_id": {
18
+ "name": "focused_goal_id",
19
+ "type": "text",
20
+ "primaryKey": false,
21
+ "notNull": false,
22
+ "autoincrement": false
23
+ },
24
+ "focused_plan_id": {
25
+ "name": "focused_plan_id",
26
+ "type": "text",
27
+ "primaryKey": false,
28
+ "notNull": false,
29
+ "autoincrement": false
30
+ }
31
+ },
32
+ "indexes": {},
33
+ "foreignKeys": {},
34
+ "compositePrimaryKeys": {},
35
+ "uniqueConstraints": {},
36
+ "checkConstraints": {}
37
+ },
38
+ "links": {
39
+ "name": "links",
40
+ "columns": {
41
+ "from_ref": {
42
+ "name": "from_ref",
43
+ "type": "text",
44
+ "primaryKey": false,
45
+ "notNull": true,
46
+ "autoincrement": false
47
+ },
48
+ "to_ref": {
49
+ "name": "to_ref",
50
+ "type": "text",
51
+ "primaryKey": false,
52
+ "notNull": true,
53
+ "autoincrement": false
54
+ },
55
+ "relation": {
56
+ "name": "relation",
57
+ "type": "text",
58
+ "primaryKey": false,
59
+ "notNull": true,
60
+ "autoincrement": false
61
+ }
62
+ },
63
+ "indexes": {
64
+ "idx_links_from": {
65
+ "name": "idx_links_from",
66
+ "columns": ["from_ref"],
67
+ "isUnique": false
68
+ },
69
+ "idx_links_to": {
70
+ "name": "idx_links_to",
71
+ "columns": ["to_ref"],
72
+ "isUnique": false
73
+ }
74
+ },
75
+ "foreignKeys": {
76
+ "links_from_ref_nodes_ref_fk": {
77
+ "name": "links_from_ref_nodes_ref_fk",
78
+ "tableFrom": "links",
79
+ "tableTo": "nodes",
80
+ "columnsFrom": ["from_ref"],
81
+ "columnsTo": ["ref"],
82
+ "onDelete": "no action",
83
+ "onUpdate": "no action"
84
+ },
85
+ "links_to_ref_nodes_ref_fk": {
86
+ "name": "links_to_ref_nodes_ref_fk",
87
+ "tableFrom": "links",
88
+ "tableTo": "nodes",
89
+ "columnsFrom": ["to_ref"],
90
+ "columnsTo": ["ref"],
91
+ "onDelete": "no action",
92
+ "onUpdate": "no action"
93
+ }
94
+ },
95
+ "compositePrimaryKeys": {
96
+ "links_from_ref_to_ref_relation_pk": {
97
+ "columns": ["from_ref", "to_ref", "relation"],
98
+ "name": "links_from_ref_to_ref_relation_pk"
99
+ }
100
+ },
101
+ "uniqueConstraints": {},
102
+ "checkConstraints": {}
103
+ },
104
+ "nodes": {
105
+ "name": "nodes",
106
+ "columns": {
107
+ "ref": {
108
+ "name": "ref",
109
+ "type": "text",
110
+ "primaryKey": true,
111
+ "notNull": true,
112
+ "autoincrement": false
113
+ },
114
+ "id": {
115
+ "name": "id",
116
+ "type": "text",
117
+ "primaryKey": false,
118
+ "notNull": false,
119
+ "autoincrement": false
120
+ },
121
+ "alias": {
122
+ "name": "alias",
123
+ "type": "text",
124
+ "primaryKey": false,
125
+ "notNull": false,
126
+ "autoincrement": false
127
+ },
128
+ "name": {
129
+ "name": "name",
130
+ "type": "text",
131
+ "primaryKey": false,
132
+ "notNull": true,
133
+ "autoincrement": false
134
+ },
135
+ "description": {
136
+ "name": "description",
137
+ "type": "text",
138
+ "primaryKey": false,
139
+ "notNull": false,
140
+ "autoincrement": false,
141
+ "default": "''"
142
+ },
143
+ "parent_ref": {
144
+ "name": "parent_ref",
145
+ "type": "text",
146
+ "primaryKey": false,
147
+ "notNull": false,
148
+ "autoincrement": false
149
+ },
150
+ "information": {
151
+ "name": "information",
152
+ "type": "text",
153
+ "primaryKey": false,
154
+ "notNull": false,
155
+ "autoincrement": false
156
+ },
157
+ "tag": {
158
+ "name": "tag",
159
+ "type": "text",
160
+ "primaryKey": false,
161
+ "notNull": false,
162
+ "autoincrement": false
163
+ }
164
+ },
165
+ "indexes": {
166
+ "idx_nodes_id": {
167
+ "name": "idx_nodes_id",
168
+ "columns": ["id"],
169
+ "isUnique": false
170
+ },
171
+ "idx_nodes_name": {
172
+ "name": "idx_nodes_name",
173
+ "columns": ["name"],
174
+ "isUnique": false
175
+ },
176
+ "idx_nodes_parent_ref": {
177
+ "name": "idx_nodes_parent_ref",
178
+ "columns": ["parent_ref"],
179
+ "isUnique": false
180
+ }
181
+ },
182
+ "foreignKeys": {
183
+ "nodes_parent_ref_nodes_ref_fk": {
184
+ "name": "nodes_parent_ref_nodes_ref_fk",
185
+ "tableFrom": "nodes",
186
+ "tableTo": "nodes",
187
+ "columnsFrom": ["parent_ref"],
188
+ "columnsTo": ["ref"],
189
+ "onDelete": "no action",
190
+ "onUpdate": "no action"
191
+ }
192
+ },
193
+ "compositePrimaryKeys": {},
194
+ "uniqueConstraints": {},
195
+ "checkConstraints": {}
196
+ },
197
+ "prototype_migrations": {
198
+ "name": "prototype_migrations",
199
+ "columns": {
200
+ "prototype_id": {
201
+ "name": "prototype_id",
202
+ "type": "text",
203
+ "primaryKey": false,
204
+ "notNull": true,
205
+ "autoincrement": false
206
+ },
207
+ "migration_id": {
208
+ "name": "migration_id",
209
+ "type": "text",
210
+ "primaryKey": false,
211
+ "notNull": true,
212
+ "autoincrement": false
213
+ },
214
+ "checksum": {
215
+ "name": "checksum",
216
+ "type": "text",
217
+ "primaryKey": false,
218
+ "notNull": true,
219
+ "autoincrement": false
220
+ },
221
+ "executed_at": {
222
+ "name": "executed_at",
223
+ "type": "text",
224
+ "primaryKey": false,
225
+ "notNull": true,
226
+ "autoincrement": false
227
+ }
228
+ },
229
+ "indexes": {},
230
+ "foreignKeys": {},
231
+ "compositePrimaryKeys": {
232
+ "prototype_migrations_prototype_id_migration_id_pk": {
233
+ "columns": ["prototype_id", "migration_id"],
234
+ "name": "prototype_migrations_prototype_id_migration_id_pk"
235
+ }
236
+ },
237
+ "uniqueConstraints": {},
238
+ "checkConstraints": {}
239
+ },
240
+ "prototypes": {
241
+ "name": "prototypes",
242
+ "columns": {
243
+ "id": {
244
+ "name": "id",
245
+ "type": "text",
246
+ "primaryKey": true,
247
+ "notNull": true,
248
+ "autoincrement": false
249
+ },
250
+ "source": {
251
+ "name": "source",
252
+ "type": "text",
253
+ "primaryKey": false,
254
+ "notNull": true,
255
+ "autoincrement": false
256
+ }
257
+ },
258
+ "indexes": {},
259
+ "foreignKeys": {},
260
+ "compositePrimaryKeys": {},
261
+ "uniqueConstraints": {},
262
+ "checkConstraints": {}
263
+ }
264
+ },
265
+ "views": {},
266
+ "enums": {},
267
+ "_meta": {
268
+ "schemas": {},
269
+ "tables": {},
270
+ "columns": {}
271
+ },
272
+ "internal": {
273
+ "indexes": {}
274
+ }
275
+ }
@@ -0,0 +1,282 @@
1
+ {
2
+ "version": "6",
3
+ "dialect": "sqlite",
4
+ "id": "66a1f576-4d19-430a-a848-ed8256da44ae",
5
+ "prevId": "86f29a5e-3324-4b28-8b2a-b022b6d19fde",
6
+ "tables": {
7
+ "contexts": {
8
+ "name": "contexts",
9
+ "columns": {
10
+ "role_id": {
11
+ "name": "role_id",
12
+ "type": "text",
13
+ "primaryKey": true,
14
+ "notNull": true,
15
+ "autoincrement": false
16
+ },
17
+ "focused_goal_id": {
18
+ "name": "focused_goal_id",
19
+ "type": "text",
20
+ "primaryKey": false,
21
+ "notNull": false,
22
+ "autoincrement": false
23
+ },
24
+ "focused_plan_id": {
25
+ "name": "focused_plan_id",
26
+ "type": "text",
27
+ "primaryKey": false,
28
+ "notNull": false,
29
+ "autoincrement": false
30
+ }
31
+ },
32
+ "indexes": {},
33
+ "foreignKeys": {},
34
+ "compositePrimaryKeys": {},
35
+ "uniqueConstraints": {},
36
+ "checkConstraints": {}
37
+ },
38
+ "links": {
39
+ "name": "links",
40
+ "columns": {
41
+ "from_ref": {
42
+ "name": "from_ref",
43
+ "type": "text",
44
+ "primaryKey": false,
45
+ "notNull": true,
46
+ "autoincrement": false
47
+ },
48
+ "to_ref": {
49
+ "name": "to_ref",
50
+ "type": "text",
51
+ "primaryKey": false,
52
+ "notNull": true,
53
+ "autoincrement": false
54
+ },
55
+ "relation": {
56
+ "name": "relation",
57
+ "type": "text",
58
+ "primaryKey": false,
59
+ "notNull": true,
60
+ "autoincrement": false
61
+ }
62
+ },
63
+ "indexes": {
64
+ "idx_links_from": {
65
+ "name": "idx_links_from",
66
+ "columns": ["from_ref"],
67
+ "isUnique": false
68
+ },
69
+ "idx_links_to": {
70
+ "name": "idx_links_to",
71
+ "columns": ["to_ref"],
72
+ "isUnique": false
73
+ }
74
+ },
75
+ "foreignKeys": {
76
+ "links_from_ref_nodes_ref_fk": {
77
+ "name": "links_from_ref_nodes_ref_fk",
78
+ "tableFrom": "links",
79
+ "tableTo": "nodes",
80
+ "columnsFrom": ["from_ref"],
81
+ "columnsTo": ["ref"],
82
+ "onDelete": "no action",
83
+ "onUpdate": "no action"
84
+ },
85
+ "links_to_ref_nodes_ref_fk": {
86
+ "name": "links_to_ref_nodes_ref_fk",
87
+ "tableFrom": "links",
88
+ "tableTo": "nodes",
89
+ "columnsFrom": ["to_ref"],
90
+ "columnsTo": ["ref"],
91
+ "onDelete": "no action",
92
+ "onUpdate": "no action"
93
+ }
94
+ },
95
+ "compositePrimaryKeys": {
96
+ "links_from_ref_to_ref_relation_pk": {
97
+ "columns": ["from_ref", "to_ref", "relation"],
98
+ "name": "links_from_ref_to_ref_relation_pk"
99
+ }
100
+ },
101
+ "uniqueConstraints": {},
102
+ "checkConstraints": {}
103
+ },
104
+ "nodes": {
105
+ "name": "nodes",
106
+ "columns": {
107
+ "ref": {
108
+ "name": "ref",
109
+ "type": "text",
110
+ "primaryKey": true,
111
+ "notNull": true,
112
+ "autoincrement": false
113
+ },
114
+ "id": {
115
+ "name": "id",
116
+ "type": "text",
117
+ "primaryKey": false,
118
+ "notNull": false,
119
+ "autoincrement": false
120
+ },
121
+ "alias": {
122
+ "name": "alias",
123
+ "type": "text",
124
+ "primaryKey": false,
125
+ "notNull": false,
126
+ "autoincrement": false
127
+ },
128
+ "name": {
129
+ "name": "name",
130
+ "type": "text",
131
+ "primaryKey": false,
132
+ "notNull": true,
133
+ "autoincrement": false
134
+ },
135
+ "description": {
136
+ "name": "description",
137
+ "type": "text",
138
+ "primaryKey": false,
139
+ "notNull": false,
140
+ "autoincrement": false,
141
+ "default": "''"
142
+ },
143
+ "parent_ref": {
144
+ "name": "parent_ref",
145
+ "type": "text",
146
+ "primaryKey": false,
147
+ "notNull": false,
148
+ "autoincrement": false
149
+ },
150
+ "information": {
151
+ "name": "information",
152
+ "type": "text",
153
+ "primaryKey": false,
154
+ "notNull": false,
155
+ "autoincrement": false
156
+ },
157
+ "tag": {
158
+ "name": "tag",
159
+ "type": "text",
160
+ "primaryKey": false,
161
+ "notNull": false,
162
+ "autoincrement": false
163
+ }
164
+ },
165
+ "indexes": {
166
+ "idx_nodes_id": {
167
+ "name": "idx_nodes_id",
168
+ "columns": ["id"],
169
+ "isUnique": false
170
+ },
171
+ "idx_nodes_name": {
172
+ "name": "idx_nodes_name",
173
+ "columns": ["name"],
174
+ "isUnique": false
175
+ },
176
+ "idx_nodes_parent_ref": {
177
+ "name": "idx_nodes_parent_ref",
178
+ "columns": ["parent_ref"],
179
+ "isUnique": false
180
+ }
181
+ },
182
+ "foreignKeys": {
183
+ "nodes_parent_ref_nodes_ref_fk": {
184
+ "name": "nodes_parent_ref_nodes_ref_fk",
185
+ "tableFrom": "nodes",
186
+ "tableTo": "nodes",
187
+ "columnsFrom": ["parent_ref"],
188
+ "columnsTo": ["ref"],
189
+ "onDelete": "no action",
190
+ "onUpdate": "no action"
191
+ }
192
+ },
193
+ "compositePrimaryKeys": {},
194
+ "uniqueConstraints": {},
195
+ "checkConstraints": {}
196
+ },
197
+ "prototype_migrations": {
198
+ "name": "prototype_migrations",
199
+ "columns": {
200
+ "prototype_id": {
201
+ "name": "prototype_id",
202
+ "type": "text",
203
+ "primaryKey": false,
204
+ "notNull": true,
205
+ "autoincrement": false
206
+ },
207
+ "migration_id": {
208
+ "name": "migration_id",
209
+ "type": "text",
210
+ "primaryKey": false,
211
+ "notNull": true,
212
+ "autoincrement": false
213
+ },
214
+ "version": {
215
+ "name": "version",
216
+ "type": "integer",
217
+ "primaryKey": false,
218
+ "notNull": true,
219
+ "autoincrement": false
220
+ },
221
+ "checksum": {
222
+ "name": "checksum",
223
+ "type": "text",
224
+ "primaryKey": false,
225
+ "notNull": true,
226
+ "autoincrement": false
227
+ },
228
+ "executed_at": {
229
+ "name": "executed_at",
230
+ "type": "text",
231
+ "primaryKey": false,
232
+ "notNull": true,
233
+ "autoincrement": false
234
+ }
235
+ },
236
+ "indexes": {},
237
+ "foreignKeys": {},
238
+ "compositePrimaryKeys": {
239
+ "prototype_migrations_prototype_id_migration_id_pk": {
240
+ "columns": ["prototype_id", "migration_id"],
241
+ "name": "prototype_migrations_prototype_id_migration_id_pk"
242
+ }
243
+ },
244
+ "uniqueConstraints": {},
245
+ "checkConstraints": {}
246
+ },
247
+ "prototypes": {
248
+ "name": "prototypes",
249
+ "columns": {
250
+ "id": {
251
+ "name": "id",
252
+ "type": "text",
253
+ "primaryKey": true,
254
+ "notNull": true,
255
+ "autoincrement": false
256
+ },
257
+ "source": {
258
+ "name": "source",
259
+ "type": "text",
260
+ "primaryKey": false,
261
+ "notNull": true,
262
+ "autoincrement": false
263
+ }
264
+ },
265
+ "indexes": {},
266
+ "foreignKeys": {},
267
+ "compositePrimaryKeys": {},
268
+ "uniqueConstraints": {},
269
+ "checkConstraints": {}
270
+ }
271
+ },
272
+ "views": {},
273
+ "enums": {},
274
+ "_meta": {
275
+ "schemas": {},
276
+ "tables": {},
277
+ "columns": {}
278
+ },
279
+ "internal": {
280
+ "indexes": {}
281
+ }
282
+ }
@@ -0,0 +1,20 @@
1
+ {
2
+ "version": "7",
3
+ "dialect": "sqlite",
4
+ "entries": [
5
+ {
6
+ "idx": 0,
7
+ "version": "6",
8
+ "when": 1772631387631,
9
+ "tag": "0000_spooky_amazoness",
10
+ "breakpoints": true
11
+ },
12
+ {
13
+ "idx": 1,
14
+ "version": "6",
15
+ "when": 1772634146909,
16
+ "tag": "0001_slimy_joystick",
17
+ "breakpoints": true
18
+ }
19
+ ]
20
+ }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@rolexjs/local-platform",
3
- "version": "1.3.1-dev-20260304123741",
3
+ "version": "2.0.0-dev-20260305000914",
4
4
  "description": "Local filesystem Platform for RoleX — stores roles in .rolex/ directories",
5
5
  "type": "module",
6
6
  "main": "./dist/index.js",
@@ -12,19 +12,20 @@
12
12
  }
13
13
  },
14
14
  "files": [
15
- "dist"
15
+ "dist",
16
+ "drizzle"
16
17
  ],
17
18
  "scripts": {
18
19
  "build": "tsup",
19
20
  "clean": "rm -rf dist"
20
21
  },
21
22
  "dependencies": {
22
- "@deepracticex/drizzle": "^0.2.0",
23
+ "@deepracticex/drizzle": "^0.3.1",
23
24
  "@deepracticex/sqlite": "^0.2.0",
24
25
  "@issuexjs/node": "^0.2.0",
25
26
  "@resourcexjs/node-provider": "^2.14.0",
26
- "@rolexjs/core": "1.3.1-dev-20260304123741",
27
- "@rolexjs/system": "1.3.1-dev-20260304123741",
27
+ "@rolexjs/core": "2.0.0-dev-20260305000914",
28
+ "@rolexjs/system": "2.0.0-dev-20260305000914",
28
29
  "drizzle-orm": "^0.45.1"
29
30
  },
30
31
  "devDependencies": {},