@kontextmind/kxm 0.7.53 → 0.7.55

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.
@@ -17121,7 +17121,7 @@ async function deliverInboxNotification(messageId, delivered, notify) {
17121
17121
  }
17122
17122
 
17123
17123
  // plugins/kxm/src/mcp-server.ts
17124
- var VERSION = "0.7.53";
17124
+ var VERSION = "0.7.55";
17125
17125
  var inbox = /* @__PURE__ */ new Map();
17126
17126
  var notifiedInbox = /* @__PURE__ */ new Set();
17127
17127
  var meshClient;
@@ -16256,9 +16256,6 @@ var KxmSchemaRegistry = class {
16256
16256
  localBindingsValidator;
16257
16257
  templateProvenanceValidator;
16258
16258
  initOperationValidator;
16259
- migrationPlanValidator;
16260
- migrationDecisionValidator;
16261
- migrationReceiptValidator;
16262
16259
  permissionDiffValidator;
16263
16260
  runEventValidator;
16264
16261
  driveReceiptValidator;
@@ -16275,9 +16272,6 @@ var KxmSchemaRegistry = class {
16275
16272
  const localBindingsFile = "local-repository-bindings.schema.json";
16276
16273
  const templateProvenanceFile = "template-provenance.schema.json";
16277
16274
  const initOperationFile = "init-operation.schema.json";
16278
- const migrationPlanFile = "migration-plan.schema.json";
16279
- const migrationDecisionFile = "migration-decision.schema.json";
16280
- const migrationReceiptFile = "migration-receipt.schema.json";
16281
16275
  const permissionDiffFile = "permission-diff.schema.json";
16282
16276
  const runEventFile = "run-event.schema.json";
16283
16277
  const driveReceiptFile = "drive-receipt.schema.json";
@@ -16286,9 +16280,6 @@ var KxmSchemaRegistry = class {
16286
16280
  this.ajv.addSchema(readJsonObject(join2(this.schemasDir, localBindingsFile)));
16287
16281
  this.ajv.addSchema(readJsonObject(join2(this.schemasDir, templateProvenanceFile)));
16288
16282
  this.ajv.addSchema(readJsonObject(join2(this.schemasDir, initOperationFile)));
16289
- this.ajv.addSchema(readJsonObject(join2(this.schemasDir, migrationPlanFile)));
16290
- this.ajv.addSchema(readJsonObject(join2(this.schemasDir, migrationDecisionFile)));
16291
- this.ajv.addSchema(readJsonObject(join2(this.schemasDir, migrationReceiptFile)));
16292
16283
  this.ajv.addSchema(readJsonObject(join2(this.schemasDir, permissionDiffFile)));
16293
16284
  this.ajv.addSchema(readJsonObject(join2(this.schemasDir, runEventFile)));
16294
16285
  this.ajv.addSchema(readJsonObject(join2(this.schemasDir, driveReceiptFile)));
@@ -16302,9 +16293,6 @@ var KxmSchemaRegistry = class {
16302
16293
  const localBindingsValidator = this.ajv.getSchema(`https://schemas.kxm.dev/${localBindingsFile}`);
16303
16294
  const templateProvenanceValidator = this.ajv.getSchema(`https://schemas.kxm.dev/${templateProvenanceFile}`);
16304
16295
  const initOperationValidator = this.ajv.getSchema(`https://schemas.kxm.dev/${initOperationFile}`);
16305
- const migrationPlanValidator = this.ajv.getSchema(`https://schemas.kxm.dev/${migrationPlanFile}`);
16306
- const migrationDecisionValidator = this.ajv.getSchema(`https://schemas.kxm.dev/${migrationDecisionFile}`);
16307
- const migrationReceiptValidator = this.ajv.getSchema(`https://schemas.kxm.dev/${migrationReceiptFile}`);
16308
16296
  const permissionDiffValidator = this.ajv.getSchema(`https://schemas.kxm.dev/${permissionDiffFile}`);
16309
16297
  const runEventValidator = this.ajv.getSchema(`https://schemas.kxm.dev/${runEventFile}`);
16310
16298
  const driveReceiptValidator = this.ajv.getSchema(`https://schemas.kxm.dev/${driveReceiptFile}`);
@@ -16313,9 +16301,6 @@ var KxmSchemaRegistry = class {
16313
16301
  if (!localBindingsValidator) throw new Error(`schema did not compile: ${localBindingsFile}`);
16314
16302
  if (!templateProvenanceValidator) throw new Error(`schema did not compile: ${templateProvenanceFile}`);
16315
16303
  if (!initOperationValidator) throw new Error(`schema did not compile: ${initOperationFile}`);
16316
- if (!migrationPlanValidator) throw new Error(`schema did not compile: ${migrationPlanFile}`);
16317
- if (!migrationDecisionValidator) throw new Error(`schema did not compile: ${migrationDecisionFile}`);
16318
- if (!migrationReceiptValidator) throw new Error(`schema did not compile: ${migrationReceiptFile}`);
16319
16304
  if (!permissionDiffValidator) throw new Error(`schema did not compile: ${permissionDiffFile}`);
16320
16305
  if (!runEventValidator) throw new Error(`schema did not compile: ${runEventFile}`);
16321
16306
  if (!driveReceiptValidator) throw new Error(`schema did not compile: ${driveReceiptFile}`);
@@ -16324,9 +16309,6 @@ var KxmSchemaRegistry = class {
16324
16309
  this.localBindingsValidator = localBindingsValidator;
16325
16310
  this.templateProvenanceValidator = templateProvenanceValidator;
16326
16311
  this.initOperationValidator = initOperationValidator;
16327
- this.migrationPlanValidator = migrationPlanValidator;
16328
- this.migrationDecisionValidator = migrationDecisionValidator;
16329
- this.migrationReceiptValidator = migrationReceiptValidator;
16330
16312
  this.permissionDiffValidator = permissionDiffValidator;
16331
16313
  this.runEventValidator = runEventValidator;
16332
16314
  this.driveReceiptValidator = driveReceiptValidator;
@@ -16352,15 +16334,6 @@ var KxmSchemaRegistry = class {
16352
16334
  validateInitOperation(value, file) {
16353
16335
  return this.validateAuxiliary(value, file, "kxm.init-operation.v1", this.initOperationValidator);
16354
16336
  }
16355
- validateMigrationPlan(value, file) {
16356
- return this.validateAuxiliary(value, file, "kxm.migration-plan.v1", this.migrationPlanValidator);
16357
- }
16358
- validateMigrationDecision(value, file) {
16359
- return this.validateAuxiliary(value, file, "kxm.migration-decision.v1", this.migrationDecisionValidator);
16360
- }
16361
- validateMigrationReceipt(value, file) {
16362
- return this.validateAuxiliary(value, file, "kxm.migration-receipt.v1", this.migrationReceiptValidator);
16363
- }
16364
16337
  validatePermissionDiff(value, file) {
16365
16338
  return this.validateAuxiliary(value, file, "kxm.permission-diff.v1", this.permissionDiffValidator);
16366
16339
  }
@@ -17178,11 +17151,14 @@ function assertNoRegisteredGates(options) {
17178
17151
  function loadKxmProject(projectRoot, options = {}) {
17179
17152
  assertNoRegisteredGates(options);
17180
17153
  const root = resolve(projectRoot);
17181
- let migrationReceipt;
17182
- if (legacyConfigFilesAt(root).length > 0 && options.allowUnreceiptedLegacyConfig !== true) {
17183
- const receiptCheck = readKxmMigrationReceipt(root, options);
17184
- if (receiptCheck.issues.length > 0) throw new KxmConfigError(receiptCheck.issues);
17185
- migrationReceipt = receiptCheck.receipt;
17154
+ const legacyPresent = legacyConfigFilesAt(root);
17155
+ if (legacyPresent.length > 0) {
17156
+ throw new KxmConfigError(legacyPresent.map((file) => issue2(
17157
+ "semantic",
17158
+ "legacy_state_unsupported",
17159
+ file,
17160
+ "legacy JSON configuration is present and this build does not migrate it: delete these files once their YAML replacements exist in .kxm/, or initialise a fresh project"
17161
+ )));
17186
17162
  }
17187
17163
  const registry = new KxmSchemaRegistry(options.schemasDir);
17188
17164
  const project = readResource(registry, root, join2(root, ".kxm", "project.yaml"), ".kxm/project.yaml", "project");
@@ -17195,9 +17171,6 @@ function loadKxmProject(projectRoot, options = {}) {
17195
17171
  earlyIssues.push(issue2("semantic", "template_provenance_project_mismatch", ".kxm/template-provenance.yaml", "template provenance belongs to a different project identity"));
17196
17172
  }
17197
17173
  }
17198
- if (migrationReceipt && stringValue(migrationReceipt.projectId) !== stringValue(project.value.id)) {
17199
- earlyIssues.push(issue2("semantic", "migration_project_mismatch", KXM_MIGRATION_RECEIPT_PATH, "migration receipt belongs to a different project identity"));
17200
- }
17201
17174
  const declaredRepositoryIds = new Set(valuesOf(project.value, "repositories").map((candidate) => stringValue(objectValue(candidate)?.id)).filter((candidate) => candidate !== void 0));
17202
17175
  for (const repositoryId of Object.keys(options.repositoryBindings ?? {}).sort(compareCodeUnits3)) {
17203
17176
  if (!resourceIdentifier(repositoryId)) {
@@ -17274,6 +17247,15 @@ function loadKxmProject(projectRoot, options = {}) {
17274
17247
  continue;
17275
17248
  }
17276
17249
  }
17250
+ const memberLegacy = binding === root ? [] : legacyConfigFilesAt(binding);
17251
+ if (memberLegacy.length > 0) {
17252
+ throw new KxmConfigError(memberLegacy.map((file) => issue2(
17253
+ "semantic",
17254
+ "legacy_state_unsupported",
17255
+ `${repositoryId}/${file}`,
17256
+ `repository ${repositoryId} holds legacy JSON configuration and this build does not migrate it: delete those files once their YAML replacements exist, or bind a clean worktree`
17257
+ )));
17258
+ }
17277
17259
  const foldedBinding = canonicalHostPath(binding).toLocaleLowerCase("en-US");
17278
17260
  const priorBinding = seenBindings.get(foldedBinding);
17279
17261
  if (priorBinding && priorBinding !== repositoryId) {
@@ -17327,12 +17309,10 @@ function loadKxmProject(projectRoot, options = {}) {
17327
17309
  environments,
17328
17310
  ...gateRegistry ? { gateRegistry } : {},
17329
17311
  ...templateProvenance === void 0 ? {} : { templateProvenance },
17330
- ...migrationReceipt === void 0 ? {} : { migrationReceipt },
17331
17312
  resources,
17332
17313
  configRevision: bundleRevision(resources)
17333
17314
  };
17334
17315
  }
17335
- var KXM_MIGRATION_RECEIPT_PATH = ".kxm/migration-receipt.yaml";
17336
17316
  var LEGACY_CONFIG_FILES = [".kxm/config/agents.json", ".kxm/config/gates.json"];
17337
17317
  function legacyConfigFilesAt(root) {
17338
17318
  const files = [];
@@ -17358,66 +17338,6 @@ function legacyConfigFilesAt(root) {
17358
17338
  }
17359
17339
  return files;
17360
17340
  }
17361
- function hashFileRecord(root, relativePath) {
17362
- const absolute = join2(root, ...relativePath.split("/"));
17363
- if (!existsSync3(absolute)) return void 0;
17364
- const bytes = readFileSync(absolute);
17365
- return {
17366
- path: relativePath,
17367
- sha256: `sha256:${createHash2("sha256").update(bytes).digest("hex")}`,
17368
- bytes: bytes.byteLength
17369
- };
17370
- }
17371
- function migrationReceiptSelfHash(receipt) {
17372
- const { receiptSha256: _ignored, ...unsigned } = receipt;
17373
- return `sha256:${createHash2("sha256").update(kxmCanonicalJson(unsigned), "utf8").digest("hex")}`;
17374
- }
17375
- function readKxmMigrationReceipt(root, options = {}) {
17376
- const receiptPath = join2(root, ...KXM_MIGRATION_RECEIPT_PATH.split("/"));
17377
- const legacyFiles = legacyConfigFilesAt(root);
17378
- if (!existsSync3(receiptPath)) {
17379
- return {
17380
- issues: legacyFiles.map((file) => issue2("semantic", "legacy_kxm_conflict", file, "legacy and KXM configuration cannot coexist before an accepted migration receipt"))
17381
- };
17382
- }
17383
- const receiptStat = lstatSync(receiptPath);
17384
- if (receiptStat.isSymbolicLink() || !receiptStat.isFile()) {
17385
- return { issues: [issue2("path", "migration_receipt_invalid", KXM_MIGRATION_RECEIPT_PATH, "migration receipt must be a regular file, not a link")] };
17386
- }
17387
- let receipt;
17388
- try {
17389
- receipt = parseRestrictedYaml2(readFileSync(receiptPath), KXM_MIGRATION_RECEIPT_PATH);
17390
- } catch (error) {
17391
- if (error instanceof KxmConfigError) return { issues: [...error.issues] };
17392
- throw error;
17393
- }
17394
- const registry = new KxmSchemaRegistry(options.schemasDir);
17395
- const schemaIssues = registry.validateMigrationReceipt(receipt, KXM_MIGRATION_RECEIPT_PATH);
17396
- if (schemaIssues.length > 0) return { issues: schemaIssues };
17397
- if (receipt.receiptSha256 !== migrationReceiptSelfHash(receipt)) {
17398
- return { issues: [issue2("semantic", "migration_receipt_hash_mismatch", KXM_MIGRATION_RECEIPT_PATH, "receipt self-hash does not match its content")] };
17399
- }
17400
- const sources = (Array.isArray(receipt.sources) ? receipt.sources : []).map((candidate) => candidate && typeof candidate === "object" && !Array.isArray(candidate) ? candidate.path : void 0).filter((candidate) => typeof candidate === "string").sort(compareCodeUnits3);
17401
- const issues = [];
17402
- const declared = new Set(sources);
17403
- for (const file of legacyFiles) {
17404
- if (!declared.has(file)) {
17405
- issues.push(issue2("semantic", "migration_source_unmigrated", file, "legacy configuration file is not covered by the migration receipt"));
17406
- continue;
17407
- }
17408
- const record2 = (Array.isArray(receipt.sources) ? receipt.sources : []).map((candidate) => candidate && typeof candidate === "object" && !Array.isArray(candidate) ? candidate : void 0).find((candidate) => candidate?.path === file);
17409
- const current = hashFileRecord(root, file);
17410
- if (!current || current.sha256 !== record2?.sha256 || current.bytes !== record2?.bytes) {
17411
- issues.push(issue2("semantic", "migration_source_changed", file, "legacy configuration changed after the migration receipt was issued"));
17412
- }
17413
- }
17414
- for (const file of sources) {
17415
- if (!legacyFiles.includes(file)) {
17416
- issues.push(issue2("semantic", "migration_source_missing", file, "receipt covers a legacy configuration file that no longer exists"));
17417
- }
17418
- }
17419
- return issues.length > 0 ? { issues } : { receipt, issues: [] };
17420
- }
17421
17341
 
17422
17342
  // plugins/kxm/src/runtime-store.ts
17423
17343
  import { createHash as createHash3, randomUUID } from "node:crypto";
@@ -17615,7 +17535,7 @@ function openDatabase(file, description, spec) {
17615
17535
  throw databaseError(
17616
17536
  "runtime_schema_outdated",
17617
17537
  file,
17618
- `${description} is schema version ${version}; this build requires ${spec.version}. Delete the state file (or re-run \`kxm init\`) to start fresh \u2014 upgrading old state in place is deliberately unsupported`
17538
+ `${description} is schema version ${version}; this build requires ${spec.version}. Delete the state file to start fresh and let its owning process recreate it (\`kxm hub start\` for hub state, the Runtime for registry/event stores); \`kxm init\` is project-only and rebuilds no database \u2014 upgrading old state in place is deliberately unsupported`
17619
17539
  );
17620
17540
  }
17621
17541
  if (spec.tables) {
@@ -16426,9 +16426,6 @@ var KxmSchemaRegistry = class {
16426
16426
  localBindingsValidator;
16427
16427
  templateProvenanceValidator;
16428
16428
  initOperationValidator;
16429
- migrationPlanValidator;
16430
- migrationDecisionValidator;
16431
- migrationReceiptValidator;
16432
16429
  permissionDiffValidator;
16433
16430
  runEventValidator;
16434
16431
  driveReceiptValidator;
@@ -16445,9 +16442,6 @@ var KxmSchemaRegistry = class {
16445
16442
  const localBindingsFile = "local-repository-bindings.schema.json";
16446
16443
  const templateProvenanceFile = "template-provenance.schema.json";
16447
16444
  const initOperationFile = "init-operation.schema.json";
16448
- const migrationPlanFile = "migration-plan.schema.json";
16449
- const migrationDecisionFile = "migration-decision.schema.json";
16450
- const migrationReceiptFile = "migration-receipt.schema.json";
16451
16445
  const permissionDiffFile = "permission-diff.schema.json";
16452
16446
  const runEventFile = "run-event.schema.json";
16453
16447
  const driveReceiptFile = "drive-receipt.schema.json";
@@ -16456,9 +16450,6 @@ var KxmSchemaRegistry = class {
16456
16450
  this.ajv.addSchema(readJsonObject(join2(this.schemasDir, localBindingsFile)));
16457
16451
  this.ajv.addSchema(readJsonObject(join2(this.schemasDir, templateProvenanceFile)));
16458
16452
  this.ajv.addSchema(readJsonObject(join2(this.schemasDir, initOperationFile)));
16459
- this.ajv.addSchema(readJsonObject(join2(this.schemasDir, migrationPlanFile)));
16460
- this.ajv.addSchema(readJsonObject(join2(this.schemasDir, migrationDecisionFile)));
16461
- this.ajv.addSchema(readJsonObject(join2(this.schemasDir, migrationReceiptFile)));
16462
16453
  this.ajv.addSchema(readJsonObject(join2(this.schemasDir, permissionDiffFile)));
16463
16454
  this.ajv.addSchema(readJsonObject(join2(this.schemasDir, runEventFile)));
16464
16455
  this.ajv.addSchema(readJsonObject(join2(this.schemasDir, driveReceiptFile)));
@@ -16472,9 +16463,6 @@ var KxmSchemaRegistry = class {
16472
16463
  const localBindingsValidator = this.ajv.getSchema(`https://schemas.kxm.dev/${localBindingsFile}`);
16473
16464
  const templateProvenanceValidator = this.ajv.getSchema(`https://schemas.kxm.dev/${templateProvenanceFile}`);
16474
16465
  const initOperationValidator = this.ajv.getSchema(`https://schemas.kxm.dev/${initOperationFile}`);
16475
- const migrationPlanValidator = this.ajv.getSchema(`https://schemas.kxm.dev/${migrationPlanFile}`);
16476
- const migrationDecisionValidator = this.ajv.getSchema(`https://schemas.kxm.dev/${migrationDecisionFile}`);
16477
- const migrationReceiptValidator = this.ajv.getSchema(`https://schemas.kxm.dev/${migrationReceiptFile}`);
16478
16466
  const permissionDiffValidator = this.ajv.getSchema(`https://schemas.kxm.dev/${permissionDiffFile}`);
16479
16467
  const runEventValidator = this.ajv.getSchema(`https://schemas.kxm.dev/${runEventFile}`);
16480
16468
  const driveReceiptValidator = this.ajv.getSchema(`https://schemas.kxm.dev/${driveReceiptFile}`);
@@ -16483,9 +16471,6 @@ var KxmSchemaRegistry = class {
16483
16471
  if (!localBindingsValidator) throw new Error(`schema did not compile: ${localBindingsFile}`);
16484
16472
  if (!templateProvenanceValidator) throw new Error(`schema did not compile: ${templateProvenanceFile}`);
16485
16473
  if (!initOperationValidator) throw new Error(`schema did not compile: ${initOperationFile}`);
16486
- if (!migrationPlanValidator) throw new Error(`schema did not compile: ${migrationPlanFile}`);
16487
- if (!migrationDecisionValidator) throw new Error(`schema did not compile: ${migrationDecisionFile}`);
16488
- if (!migrationReceiptValidator) throw new Error(`schema did not compile: ${migrationReceiptFile}`);
16489
16474
  if (!permissionDiffValidator) throw new Error(`schema did not compile: ${permissionDiffFile}`);
16490
16475
  if (!runEventValidator) throw new Error(`schema did not compile: ${runEventFile}`);
16491
16476
  if (!driveReceiptValidator) throw new Error(`schema did not compile: ${driveReceiptFile}`);
@@ -16494,9 +16479,6 @@ var KxmSchemaRegistry = class {
16494
16479
  this.localBindingsValidator = localBindingsValidator;
16495
16480
  this.templateProvenanceValidator = templateProvenanceValidator;
16496
16481
  this.initOperationValidator = initOperationValidator;
16497
- this.migrationPlanValidator = migrationPlanValidator;
16498
- this.migrationDecisionValidator = migrationDecisionValidator;
16499
- this.migrationReceiptValidator = migrationReceiptValidator;
16500
16482
  this.permissionDiffValidator = permissionDiffValidator;
16501
16483
  this.runEventValidator = runEventValidator;
16502
16484
  this.driveReceiptValidator = driveReceiptValidator;
@@ -16522,15 +16504,6 @@ var KxmSchemaRegistry = class {
16522
16504
  validateInitOperation(value, file) {
16523
16505
  return this.validateAuxiliary(value, file, "kxm.init-operation.v1", this.initOperationValidator);
16524
16506
  }
16525
- validateMigrationPlan(value, file) {
16526
- return this.validateAuxiliary(value, file, "kxm.migration-plan.v1", this.migrationPlanValidator);
16527
- }
16528
- validateMigrationDecision(value, file) {
16529
- return this.validateAuxiliary(value, file, "kxm.migration-decision.v1", this.migrationDecisionValidator);
16530
- }
16531
- validateMigrationReceipt(value, file) {
16532
- return this.validateAuxiliary(value, file, "kxm.migration-receipt.v1", this.migrationReceiptValidator);
16533
- }
16534
16507
  validatePermissionDiff(value, file) {
16535
16508
  return this.validateAuxiliary(value, file, "kxm.permission-diff.v1", this.permissionDiffValidator);
16536
16509
  }
@@ -17348,11 +17321,14 @@ function assertNoRegisteredGates(options) {
17348
17321
  function loadKxmProject(projectRoot, options = {}) {
17349
17322
  assertNoRegisteredGates(options);
17350
17323
  const root = resolve(projectRoot);
17351
- let migrationReceipt;
17352
- if (legacyConfigFilesAt(root).length > 0 && options.allowUnreceiptedLegacyConfig !== true) {
17353
- const receiptCheck = readKxmMigrationReceipt(root, options);
17354
- if (receiptCheck.issues.length > 0) throw new KxmConfigError(receiptCheck.issues);
17355
- migrationReceipt = receiptCheck.receipt;
17324
+ const legacyPresent = legacyConfigFilesAt(root);
17325
+ if (legacyPresent.length > 0) {
17326
+ throw new KxmConfigError(legacyPresent.map((file) => issue2(
17327
+ "semantic",
17328
+ "legacy_state_unsupported",
17329
+ file,
17330
+ "legacy JSON configuration is present and this build does not migrate it: delete these files once their YAML replacements exist in .kxm/, or initialise a fresh project"
17331
+ )));
17356
17332
  }
17357
17333
  const registry = new KxmSchemaRegistry(options.schemasDir);
17358
17334
  const project = readResource(registry, root, join2(root, ".kxm", "project.yaml"), ".kxm/project.yaml", "project");
@@ -17365,9 +17341,6 @@ function loadKxmProject(projectRoot, options = {}) {
17365
17341
  earlyIssues.push(issue2("semantic", "template_provenance_project_mismatch", ".kxm/template-provenance.yaml", "template provenance belongs to a different project identity"));
17366
17342
  }
17367
17343
  }
17368
- if (migrationReceipt && stringValue(migrationReceipt.projectId) !== stringValue(project.value.id)) {
17369
- earlyIssues.push(issue2("semantic", "migration_project_mismatch", KXM_MIGRATION_RECEIPT_PATH, "migration receipt belongs to a different project identity"));
17370
- }
17371
17344
  const declaredRepositoryIds = new Set(valuesOf(project.value, "repositories").map((candidate) => stringValue(objectValue(candidate)?.id)).filter((candidate) => candidate !== void 0));
17372
17345
  for (const repositoryId of Object.keys(options.repositoryBindings ?? {}).sort(compareCodeUnits3)) {
17373
17346
  if (!resourceIdentifier(repositoryId)) {
@@ -17444,6 +17417,15 @@ function loadKxmProject(projectRoot, options = {}) {
17444
17417
  continue;
17445
17418
  }
17446
17419
  }
17420
+ const memberLegacy = binding === root ? [] : legacyConfigFilesAt(binding);
17421
+ if (memberLegacy.length > 0) {
17422
+ throw new KxmConfigError(memberLegacy.map((file) => issue2(
17423
+ "semantic",
17424
+ "legacy_state_unsupported",
17425
+ `${repositoryId}/${file}`,
17426
+ `repository ${repositoryId} holds legacy JSON configuration and this build does not migrate it: delete those files once their YAML replacements exist, or bind a clean worktree`
17427
+ )));
17428
+ }
17447
17429
  const foldedBinding = canonicalHostPath(binding).toLocaleLowerCase("en-US");
17448
17430
  const priorBinding = seenBindings.get(foldedBinding);
17449
17431
  if (priorBinding && priorBinding !== repositoryId) {
@@ -17497,12 +17479,10 @@ function loadKxmProject(projectRoot, options = {}) {
17497
17479
  environments,
17498
17480
  ...gateRegistry ? { gateRegistry } : {},
17499
17481
  ...templateProvenance === void 0 ? {} : { templateProvenance },
17500
- ...migrationReceipt === void 0 ? {} : { migrationReceipt },
17501
17482
  resources,
17502
17483
  configRevision: bundleRevision(resources)
17503
17484
  };
17504
17485
  }
17505
- var KXM_MIGRATION_RECEIPT_PATH = ".kxm/migration-receipt.yaml";
17506
17486
  var LEGACY_CONFIG_FILES = [".kxm/config/agents.json", ".kxm/config/gates.json"];
17507
17487
  function legacyConfigFilesAt(root) {
17508
17488
  const files = [];
@@ -17528,66 +17508,6 @@ function legacyConfigFilesAt(root) {
17528
17508
  }
17529
17509
  return files;
17530
17510
  }
17531
- function hashFileRecord(root, relativePath) {
17532
- const absolute = join2(root, ...relativePath.split("/"));
17533
- if (!existsSync3(absolute)) return void 0;
17534
- const bytes = readFileSync(absolute);
17535
- return {
17536
- path: relativePath,
17537
- sha256: `sha256:${createHash2("sha256").update(bytes).digest("hex")}`,
17538
- bytes: bytes.byteLength
17539
- };
17540
- }
17541
- function migrationReceiptSelfHash(receipt) {
17542
- const { receiptSha256: _ignored, ...unsigned } = receipt;
17543
- return `sha256:${createHash2("sha256").update(kxmCanonicalJson(unsigned), "utf8").digest("hex")}`;
17544
- }
17545
- function readKxmMigrationReceipt(root, options = {}) {
17546
- const receiptPath = join2(root, ...KXM_MIGRATION_RECEIPT_PATH.split("/"));
17547
- const legacyFiles = legacyConfigFilesAt(root);
17548
- if (!existsSync3(receiptPath)) {
17549
- return {
17550
- issues: legacyFiles.map((file) => issue2("semantic", "legacy_kxm_conflict", file, "legacy and KXM configuration cannot coexist before an accepted migration receipt"))
17551
- };
17552
- }
17553
- const receiptStat = lstatSync(receiptPath);
17554
- if (receiptStat.isSymbolicLink() || !receiptStat.isFile()) {
17555
- return { issues: [issue2("path", "migration_receipt_invalid", KXM_MIGRATION_RECEIPT_PATH, "migration receipt must be a regular file, not a link")] };
17556
- }
17557
- let receipt;
17558
- try {
17559
- receipt = parseRestrictedYaml2(readFileSync(receiptPath), KXM_MIGRATION_RECEIPT_PATH);
17560
- } catch (error) {
17561
- if (error instanceof KxmConfigError) return { issues: [...error.issues] };
17562
- throw error;
17563
- }
17564
- const registry = new KxmSchemaRegistry(options.schemasDir);
17565
- const schemaIssues = registry.validateMigrationReceipt(receipt, KXM_MIGRATION_RECEIPT_PATH);
17566
- if (schemaIssues.length > 0) return { issues: schemaIssues };
17567
- if (receipt.receiptSha256 !== migrationReceiptSelfHash(receipt)) {
17568
- return { issues: [issue2("semantic", "migration_receipt_hash_mismatch", KXM_MIGRATION_RECEIPT_PATH, "receipt self-hash does not match its content")] };
17569
- }
17570
- const sources = (Array.isArray(receipt.sources) ? receipt.sources : []).map((candidate) => candidate && typeof candidate === "object" && !Array.isArray(candidate) ? candidate.path : void 0).filter((candidate) => typeof candidate === "string").sort(compareCodeUnits3);
17571
- const issues = [];
17572
- const declared = new Set(sources);
17573
- for (const file of legacyFiles) {
17574
- if (!declared.has(file)) {
17575
- issues.push(issue2("semantic", "migration_source_unmigrated", file, "legacy configuration file is not covered by the migration receipt"));
17576
- continue;
17577
- }
17578
- const record2 = (Array.isArray(receipt.sources) ? receipt.sources : []).map((candidate) => candidate && typeof candidate === "object" && !Array.isArray(candidate) ? candidate : void 0).find((candidate) => candidate?.path === file);
17579
- const current = hashFileRecord(root, file);
17580
- if (!current || current.sha256 !== record2?.sha256 || current.bytes !== record2?.bytes) {
17581
- issues.push(issue2("semantic", "migration_source_changed", file, "legacy configuration changed after the migration receipt was issued"));
17582
- }
17583
- }
17584
- for (const file of sources) {
17585
- if (!legacyFiles.includes(file)) {
17586
- issues.push(issue2("semantic", "migration_source_missing", file, "receipt covers a legacy configuration file that no longer exists"));
17587
- }
17588
- }
17589
- return issues.length > 0 ? { issues } : { receipt, issues: [] };
17590
- }
17591
17511
 
17592
17512
  // plugins/kxm/src/runtime-store.ts
17593
17513
  import { createHash as createHash4, randomUUID } from "node:crypto";
@@ -17786,7 +17706,7 @@ function openDatabase(file, description, spec) {
17786
17706
  throw databaseError(
17787
17707
  "runtime_schema_outdated",
17788
17708
  file,
17789
- `${description} is schema version ${version}; this build requires ${spec.version}. Delete the state file (or re-run \`kxm init\`) to start fresh \u2014 upgrading old state in place is deliberately unsupported`
17709
+ `${description} is schema version ${version}; this build requires ${spec.version}. Delete the state file to start fresh and let its owning process recreate it (\`kxm hub start\` for hub state, the Runtime for registry/event stores); \`kxm init\` is project-only and rebuilds no database \u2014 upgrading old state in place is deliberately unsupported`
17790
17710
  );
17791
17711
  }
17792
17712
  if (spec.tables) {
@@ -27993,20 +27913,37 @@ function extractText(content) {
27993
27913
  }
27994
27914
  return "";
27995
27915
  }
27996
- function determineOutcome2(text, allowedOutcomes) {
27997
- const normalized = text.trim();
27998
- const jsonMatch = /"outcome"\s*:\s*"([^"]+)"/.exec(normalized);
27999
- if (jsonMatch && allowedOutcomes.includes(jsonMatch[1])) {
28000
- return jsonMatch[1];
28001
- }
28002
- for (const outcome of allowedOutcomes) {
28003
- const regex = new RegExp(`\\b${outcome}\\b`, "i");
28004
- if (regex.test(normalized)) {
28005
- return outcome;
28006
- }
27916
+ function asJsonObject2(text) {
27917
+ try {
27918
+ const parsed = JSON.parse(text);
27919
+ return parsed && typeof parsed === "object" && !Array.isArray(parsed) ? parsed : void 0;
27920
+ } catch {
27921
+ return void 0;
28007
27922
  }
28008
- if (allowedOutcomes.includes("passed")) return "passed";
28009
- return allowedOutcomes[0] ?? "completed";
27923
+ }
27924
+ function outcomeField(value) {
27925
+ const outcome = value.outcome;
27926
+ return typeof outcome === "string" ? outcome : void 0;
27927
+ }
27928
+ function declaredOutcomeOf(text) {
27929
+ const trimmed = text.trim();
27930
+ if (!trimmed) return void 0;
27931
+ const whole = asJsonObject2(trimmed);
27932
+ if (whole) return outcomeField(whole);
27933
+ const lines = trimmed.split(/\r?\n/);
27934
+ let declaration;
27935
+ for (let index = 0; index < lines.length; index += 1) {
27936
+ const outcome = outcomeField(asJsonObject2(lines[index].trim()) ?? {});
27937
+ if (outcome !== void 0) declaration = { index, outcome };
27938
+ }
27939
+ if (!declaration) return void 0;
27940
+ const tail = lines.slice(declaration.index + 1).join("\n");
27941
+ if (/"outcome"\s*:/.test(tail)) return void 0;
27942
+ return declaration.outcome;
27943
+ }
27944
+ function determineOutcome2(text, allowedOutcomes) {
27945
+ const declared = declaredOutcomeOf(text);
27946
+ return declared !== void 0 && allowedOutcomes.includes(declared) ? declared : "failed";
28010
27947
  }
28011
27948
  var PiSession = class {
28012
27949
  key;
@@ -28136,7 +28073,7 @@ var PiSession = class {
28136
28073
  const isAborted = active.aborted || active.signal?.aborted;
28137
28074
  let outcome;
28138
28075
  if (isAborted) {
28139
- outcome = active.allowedOutcomes.includes("cancelled") ? "cancelled" : active.allowedOutcomes.includes("failed") ? "failed" : active.allowedOutcomes[0];
28076
+ outcome = "cancelled";
28140
28077
  } else {
28141
28078
  outcome = determineOutcome2(active.text, active.allowedOutcomes);
28142
28079
  }
@@ -28188,8 +28125,7 @@ var PiSession = class {
28188
28125
  throw new Error("pi_session_busy");
28189
28126
  }
28190
28127
  if (signal?.aborted) {
28191
- const outcome = allowedOutcomes.includes("cancelled") ? "cancelled" : allowedOutcomes.includes("failed") ? "failed" : allowedOutcomes[0];
28192
- return { outcome, text: "aborted", usage: {} };
28128
+ return { outcome: "cancelled", text: "aborted", usage: {} };
28193
28129
  }
28194
28130
  this.status = "busy";
28195
28131
  return new Promise((resolve8, reject) => {
@@ -11507,7 +11507,7 @@ function openDatabase(file, description, spec) {
11507
11507
  throw databaseError(
11508
11508
  "runtime_schema_outdated",
11509
11509
  file,
11510
- `${description} is schema version ${version}; this build requires ${spec.version}. Delete the state file (or re-run \`kxm init\`) to start fresh \u2014 upgrading old state in place is deliberately unsupported`
11510
+ `${description} is schema version ${version}; this build requires ${spec.version}. Delete the state file to start fresh and let its owning process recreate it (\`kxm hub start\` for hub state, the Runtime for registry/event stores); \`kxm init\` is project-only and rebuilds no database \u2014 upgrading old state in place is deliberately unsupported`
11511
11511
  );
11512
11512
  }
11513
11513
  if (spec.tables) {
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "claude-plugin",
3
- "version": "0.7.53",
3
+ "version": "0.7.55",
4
4
  "private": true,
5
5
  "type": "module",
6
6
  "engines": {
@@ -14,7 +14,7 @@ authority, admit writers, or replace `.kxm/roster.yaml` trusted policy.
14
14
 
15
15
  The KXM Agent Skills suite is organized by functional areas:
16
16
 
17
- - **Project Setup**: Use `kxm-project-setup` for `init`, `migrate`, `trust`, `config`, `completion`
17
+ - **Project Setup**: Use `kxm-project-setup` for `init`, `trust`, `config`, `completion`
18
18
  - **Harness & Auth**: Use `kxm-harness-auth` for `harness`, `auth`, `update`, `runtime`, `agent`
19
19
  - **Hub Operations**: Use `kxm-hub-ops` for `hub`, `backup`, `restore`
20
20
  - **Session Management**: Use `kxm-session` for `session`, `dash`, `studio`
@@ -1,21 +1,19 @@
1
1
  ---
2
2
  name: kxm-project-setup
3
- description: Initialize, migrate, review permission changes, configure, and add shell completion for KXM projects.
3
+ description: Initialize, review permission changes, configure, and add shell completion for KXM projects.
4
4
  ---
5
5
 
6
6
  # KXM Project Setup
7
7
 
8
8
  Use the current CLI. Inspect `kxm <command> --help` before mutations. Do not
9
- invent `force`, domain-trust, or extra migrate verbs.
9
+ invent `force`, domain-trust, or legacy-migration verbs: this build converts
10
+ nothing.
10
11
 
11
12
  ## Commands
12
13
 
13
14
  | Command | Purpose | Options / arguments |
14
15
  |---|---|---|
15
- | `kxm init` | Create, validate, or plan migration of a KXM project | `--json`, `--dry-run`, `--name`, `--project-id`, `--repository <id=absolute-path>` |
16
- | `kxm migrate plan` | Compute the legacy-to-KXM plan without writes | `--json` |
17
- | `kxm migrate apply` | Install a reviewed migration with a hash-linked receipt | `--decisions <file>`, `--project-id`, `--name` |
18
- | `kxm migrate verify` | Verify a migration receipt | `--json` |
16
+ | `kxm init` | Create, validate, repair, or join a KXM project (a legacy tree is reported as `mode: "legacy"` and never converted) | `--json`, `--dry-run`, `--name`, `--project-id`, `--repository <id=absolute-path>` |
19
17
  | `kxm trust diff` | Structured permission diff against a Git revision | `--base <revision>` |
20
18
  | `kxm trust check` | Fail when the working tree expands permissions | `--base <revision>` |
21
19
  | `kxm config get <key>` | Get a configuration value | `--json` |
@@ -25,7 +23,6 @@ invent `force`, domain-trust, or extra migrate verbs.
25
23
 
26
24
  ```bash
27
25
  kxm init --dry-run --json
28
- kxm migrate plan --json
29
26
  kxm trust diff --base HEAD --json
30
27
  kxm config list --json
31
28
  kxm completion install
@@ -2,7 +2,6 @@ export type SupportedShell = "bash" | "zsh" | "fish";
2
2
 
3
3
  const TOP_LEVEL_COMMANDS = [
4
4
  "init",
5
- "migrate",
6
5
  "backup",
7
6
  "restore",
8
7
  "run",
@@ -36,7 +35,6 @@ const TOP_LEVEL_COMMANDS = [
36
35
 
37
36
  const SUBCOMMANDS: Record<string, string[]> = {
38
37
  runs: ["status", "cancel", "list"],
39
- migrate: ["plan", "apply", "verify"],
40
38
  harness: ["list"],
41
39
  runtime: ["start", "status", "stop"],
42
40
  trust: ["diff", "check"],
@@ -132,7 +130,6 @@ _kxm() {
132
130
  local -a commands
133
131
  commands=(
134
132
  'init:Create or validate a KXM project'
135
- 'migrate:Plan, apply, and verify legacy configuration migration'
136
133
  'backup:Create a verified SQLite backup manifest'
137
134
  'restore:Restore SQLite stores from a backup manifest'
138
135
  'run:Create a KXM workflow run'