@wairon/cli 5.1.1-dev.61 → 5.1.1-dev.63

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.js CHANGED
@@ -2497,7 +2497,7 @@ var require_dist = __commonJS({
2497
2497
  scaffoldPack: () => scaffoldPack2
2498
2498
  });
2499
2499
  module2.exports = __toCommonJS2(src_exports2);
2500
- var path29 = __toESM2(require("path"));
2500
+ var path28 = __toESM2(require("path"));
2501
2501
  var import_js_yaml3 = require("js-yaml");
2502
2502
  var import_js_yaml = require("js-yaml");
2503
2503
  var import_crypto = require("crypto");
@@ -3060,8 +3060,8 @@ var require_dist = __commonJS({
3060
3060
  function slug(name) {
3061
3061
  return name.toLowerCase().replace(/[^a-z0-9]+/g, "-").replace(/^-+|-+$/g, "");
3062
3062
  }
3063
- var fs19 = __toESM2(require("fs"));
3064
- var path30 = __toESM2(require("path"));
3063
+ var fs18 = __toESM2(require("fs"));
3064
+ var path29 = __toESM2(require("path"));
3065
3065
  var import_fflate = require_node();
3066
3066
  var SKIP_DIRS = /* @__PURE__ */ new Set(["node_modules", ".git", ".hg", ".svn"]);
3067
3067
  function listEntries(archive) {
@@ -3099,9 +3099,9 @@ var require_dist = __commonJS({
3099
3099
  }
3100
3100
  function writeTree(destDir, files) {
3101
3101
  for (const file of files) {
3102
- const absolute = path30.join(destDir, file.path);
3103
- fs19.mkdirSync(path30.dirname(absolute), { recursive: true });
3104
- fs19.writeFileSync(absolute, file.contents);
3102
+ const absolute = path29.join(destDir, file.path);
3103
+ fs18.mkdirSync(path29.dirname(absolute), { recursive: true });
3104
+ fs18.writeFileSync(absolute, file.contents);
3105
3105
  }
3106
3106
  }
3107
3107
  function classifyKind(name, symlinks) {
@@ -3110,14 +3110,14 @@ var require_dist = __commonJS({
3110
3110
  return "file";
3111
3111
  }
3112
3112
  function walkPackDir(root, current2, out) {
3113
- for (const entry of fs19.readdirSync(current2, { withFileTypes: true })) {
3113
+ for (const entry of fs18.readdirSync(current2, { withFileTypes: true })) {
3114
3114
  if (entry.isDirectory()) {
3115
3115
  if (SKIP_DIRS.has(entry.name)) continue;
3116
- walkPackDir(root, path30.join(current2, entry.name), out);
3116
+ walkPackDir(root, path29.join(current2, entry.name), out);
3117
3117
  } else if (entry.isFile()) {
3118
- const absolute = path30.join(current2, entry.name);
3119
- const relative22 = path30.relative(root, absolute).split(path30.sep).join("/");
3120
- out.push({ path: relative22, contents: fs19.readFileSync(absolute) });
3118
+ const absolute = path29.join(current2, entry.name);
3119
+ const relative22 = path29.relative(root, absolute).split(path29.sep).join("/");
3120
+ out.push({ path: relative22, contents: fs18.readFileSync(absolute) });
3121
3121
  }
3122
3122
  }
3123
3123
  }
@@ -3167,7 +3167,7 @@ var require_dist = __commonJS({
3167
3167
  function scaffoldPack(request) {
3168
3168
  const files = render(request);
3169
3169
  writeTree(request.targetDir, files);
3170
- return files.map((file) => path29.join(request.targetDir, file.path));
3170
+ return files.map((file) => path28.join(request.targetDir, file.path));
3171
3171
  }
3172
3172
  function buildPack(sourceDir) {
3173
3173
  const files = readPackDir(sourceDir);
@@ -3224,7 +3224,7 @@ var require_dist = __commonJS({
3224
3224
  }
3225
3225
  const manifest = parseManifest(decode(envelope.contents));
3226
3226
  verifyIntegrity2(manifest, files);
3227
- const directory = path29.resolve(destDir);
3227
+ const directory = path28.resolve(destDir);
3228
3228
  writeTree(directory, files);
3229
3229
  const result = {
3230
3230
  directory,
@@ -3302,7 +3302,7 @@ var require_dist = __commonJS({
3302
3302
  }
3303
3303
  const manifest = parseTreeManifest(decode(envelope.contents));
3304
3304
  verifyTreeIntegrity(manifest, files);
3305
- const directory = path29.resolve(destDir);
3305
+ const directory = path28.resolve(destDir);
3306
3306
  writeTree(directory, files);
3307
3307
  const result = {
3308
3308
  destDir: directory,
@@ -3317,7 +3317,7 @@ var require_dist = __commonJS({
3317
3317
  return normalized === "." ? ".wai/" : `${normalized}/.wai/`;
3318
3318
  }
3319
3319
  function normalizeRootPath(relativePath) {
3320
- const posix2 = relativePath.split(path29.sep).join("/").replace(/^\.\//, "").replace(/\/+$/, "");
3320
+ const posix2 = relativePath.split(path28.sep).join("/").replace(/^\.\//, "").replace(/\/+$/, "");
3321
3321
  return posix2 === "" || posix2 === "." ? "." : posix2;
3322
3322
  }
3323
3323
  function slugify(projectName) {
@@ -3392,7 +3392,6 @@ __export(src_exports, {
3392
3392
  AgentRecordSchema: () => AgentRecordSchema,
3393
3393
  AgentStatusSchema: () => AgentStatusSchema,
3394
3394
  AgentTemplateSchema: () => AgentTemplateSchema,
3395
- AssertionSelectorSchema: () => AssertionSelectorSchema,
3396
3395
  BACKEND_COMMANDS: () => BACKEND_COMMANDS,
3397
3396
  BUILTIN_PROFILES: () => BUILTIN_PROFILES,
3398
3397
  BUILTIN_TYPES: () => BUILTIN_TYPES,
@@ -3400,7 +3399,6 @@ __export(src_exports, {
3400
3399
  BuiltinTargetConfigSchema: () => BuiltinTargetConfigSchema,
3401
3400
  BuiltinTargetSchema: () => BuiltinTargetSchema,
3402
3401
  BundleNotFoundError: () => BundleNotFoundError,
3403
- COMPONENT_AUTH_SOURCE: () => COMPONENT_AUTH_SOURCE,
3404
3402
  CarriedDebtKindSchema: () => CarriedDebtKindSchema,
3405
3403
  CarriedDebtSchema: () => CarriedDebtSchema,
3406
3404
  CarriedFindingSchema: () => CarriedFindingSchema,
@@ -3417,7 +3415,6 @@ __export(src_exports, {
3417
3415
  CustomTargetSchema: () => CustomTargetSchema,
3418
3416
  DEFAULT_TARGET_DIRS: () => DEFAULT_TARGET_DIRS,
3419
3417
  DatabaseSpecSchema: () => DatabaseSpecSchema,
3420
- DeclarativePackSchema: () => DeclarativePackSchema,
3421
3418
  DependencyClassSchema: () => DependencyClassSchema,
3422
3419
  DesignDepthSchema: () => DesignDepthSchema,
3423
3420
  DiagramConfigSchema: () => DiagramConfigSchema,
@@ -3433,7 +3430,6 @@ __export(src_exports, {
3433
3430
  ExternalLinkTypeSchema: () => ExternalLinkTypeSchema,
3434
3431
  FindingDeclarationSchema: () => FindingDeclarationSchema,
3435
3432
  GITHUB_REPO: () => GITHUB_REPO,
3436
- GLOBAL_PACKS_DEFAULT: () => GLOBAL_PACKS_DEFAULT,
3437
3433
  GeminiExporter: () => GeminiExporter,
3438
3434
  GroupSpecSchema: () => GroupSpecSchema,
3439
3435
  GuaranteeSchema: () => GuaranteeSchema,
@@ -3441,7 +3437,6 @@ __export(src_exports, {
3441
3437
  ImplementationSpecSchema: () => ImplementationSpecSchema,
3442
3438
  InterfaceSpecSchema: () => InterfaceSpecSchema,
3443
3439
  InvariantSchema: () => InvariantSchema,
3444
- LanguagePackDefSchema: () => LanguagePackDefSchema,
3445
3440
  LifecycleEntrypointSchema: () => LifecycleEntrypointSchema,
3446
3441
  LintAllowSchema: () => LintAllowSchema,
3447
3442
  LintConfigSchema: () => LintConfigSchema,
@@ -3455,21 +3450,15 @@ __export(src_exports, {
3455
3450
  NarrativeStepSchema: () => NarrativeStepSchema,
3456
3451
  NarrativeStepTypeSchema: () => NarrativeStepTypeSchema,
3457
3452
  OutputTargetSchema: () => OutputTargetSchema,
3458
- PACK_DIR_ENTRIES: () => PACK_DIR_ENTRIES,
3459
3453
  PATTERN_TYPES: () => PATTERN_TYPES,
3460
3454
  PROJECT_KINDS: () => PROJECT_KINDS,
3461
- PackAssertionSchema: () => PackAssertionSchema,
3462
- PackInstructionBlockSchema: () => PackInstructionBlockSchema,
3463
3455
  PackSelectionSchema: () => PackSelectionSchema,
3464
- PackSkillSchema: () => PackSkillSchema,
3465
3456
  ParallelBranchSchema: () => ParallelBranchSchema,
3466
3457
  PathsConfigSchema: () => PathsConfigSchema,
3467
- PatternDefSchema: () => PatternDefSchema,
3468
3458
  PatternRefSchema: () => PatternRefSchema,
3469
3459
  PortalAuthSchema: () => PortalAuthSchema,
3470
3460
  PortalAuthSchemeSchema: () => PortalAuthSchemeSchema,
3471
3461
  PortalTypeSchema: () => PortalTypeSchema,
3472
- ProfileDefSchema: () => ProfileDefSchema,
3473
3462
  ProfileSelectionSubjectSchema: () => ProfileSelectionSubjectSchema,
3474
3463
  ProjectConfigSchema: () => ProjectConfigSchema,
3475
3464
  ProjectNotInitializedError: () => ProjectNotInitializedError,
@@ -3488,10 +3477,8 @@ __export(src_exports, {
3488
3477
  STEP_TYPE_FIELDS: () => STEP_TYPE_FIELDS,
3489
3478
  SUPPORTED_ALIASES: () => SUPPORTED_ALIASES,
3490
3479
  SURFACE_AUDIENCES: () => SURFACE_AUDIENCES,
3491
- SkillResourceNotFoundError: () => SkillResourceNotFoundError,
3492
3480
  SpecIdSchema: () => SpecIdSchema,
3493
3481
  SpecStatusSchema: () => SpecStatusSchema,
3494
- SpecWorkspace: () => SpecWorkspace,
3495
3482
  SubsystemSpecSchema: () => SubsystemSpecSchema,
3496
3483
  SurfaceAudienceSchema: () => SurfaceAudienceSchema,
3497
3484
  SurfaceContractEntrySchema: () => SurfaceContractEntrySchema,
@@ -3511,9 +3498,6 @@ __export(src_exports, {
3511
3498
  TypeKindSchema: () => TypeKindSchema,
3512
3499
  TypeMethodSchema: () => TypeMethodSchema,
3513
3500
  TypeSpecSchema: () => TypeSpecSchema,
3514
- UNVERSIONED: () => UNVERSIONED,
3515
- UnknownAgentError: () => UnknownAgentError,
3516
- VariantDefSchema: () => VariantDefSchema,
3517
3501
  WAIRON_MANAGED_BANNER: () => WAIRON_MANAGED_BANNER,
3518
3502
  WAIRON_MANAGED_MARKER: () => WAIRON_MANAGED_MARKER,
3519
3503
  WAIRON_VERSION: () => WAIRON_VERSION,
@@ -3524,33 +3508,19 @@ __export(src_exports, {
3524
3508
  aiDirAt: () => aiDirAt,
3525
3509
  aiPathsAt: () => aiPathsAt,
3526
3510
  ambiguityMessage: () => ambiguityMessage,
3527
- applySpecStatus: () => applySpecStatus,
3528
3511
  approvalRecord: () => approvalRecord,
3529
- assertContainedProjectPath: () => assertContainedProjectPath,
3512
+ approvalVerdict: () => approvalVerdict,
3530
3513
  assertProjectInitialized: () => assertProjectInitialized,
3531
- assertionFullCode: () => assertionFullCode,
3532
- audienceRank: () => audienceRank,
3533
3514
  backendCommand: () => backendCommand,
3534
- backfillChainedSubprojectConfigs: () => backfillChainedSubprojectConfigs,
3535
3515
  buildCanvasDataModel: () => buildCanvasDataModel,
3536
- buildGraphModel: () => buildGraphModel,
3537
3516
  buildProjectGraph: () => buildProjectGraph,
3538
3517
  buildRuleContext: () => buildRuleContext,
3539
- buildServerInstructions: () => buildServerInstructions2,
3540
- buildTreeArchive: () => buildTreeArchive2,
3541
3518
  callSitesOf: () => callSitesOf,
3542
3519
  captureApprovedSpecs: () => captureApprovedSpecs,
3543
- checkSkillFreshness: () => checkSkillFreshness,
3544
- clearLoaderIssues: () => clearLoaderIssues,
3545
3520
  cognitiveScore: () => cognitiveScore,
3546
- collectPromotableSpecs: () => collectPromotableSpecs,
3547
- commitStagedTree: () => commitStagedTree,
3548
3521
  complexityLevel: () => complexityLevel,
3549
3522
  composeAgentBrief: () => composeAgentBrief,
3550
3523
  composeRuleSequence: () => composeRuleSequence,
3551
- composeVariantGuidance: () => composeVariantGuidance,
3552
- computeGateStateId: () => computeGateStateId,
3553
- computePackDigest: () => computePackDigest,
3554
3524
  computeStateId: () => computeStateId,
3555
3525
  computeStateIdAt: () => computeStateIdAt,
3556
3526
  conceptNoun: () => conceptNoun,
@@ -3560,7 +3530,6 @@ __export(src_exports, {
3560
3530
  createEmptyRegistry: () => createEmptyRegistry,
3561
3531
  createEmptyTopologyConfig: () => createEmptyTopologyConfig,
3562
3532
  createProjectConfig: () => createProjectConfig,
3563
- createStagingDir: () => createStagingDir,
3564
3533
  currentChildPins: () => currentChildPins,
3565
3534
  declaredPackNames: () => declaredPackNames,
3566
3535
  declaredProfileIds: () => declaredProfileIds,
@@ -3570,7 +3539,6 @@ __export(src_exports, {
3570
3539
  defaultPackSelections: () => defaultPackSelections,
3571
3540
  defaultTargetConfig: () => defaultTargetConfig,
3572
3541
  deleteComponentSpec: () => deleteComponentSpec,
3573
- deleteGroupSpec: () => deleteGroupSpec,
3574
3542
  deleteImplementationSpec: () => deleteImplementationSpec,
3575
3543
  deleteInterfaceSpec: () => deleteInterfaceSpec,
3576
3544
  deleteSubsystemSpec: () => deleteSubsystemSpec,
@@ -3578,121 +3546,75 @@ __export(src_exports, {
3578
3546
  deregisterPackRef: () => deregisterPackRef,
3579
3547
  deriveExecutionProfile: () => deriveExecutionProfile,
3580
3548
  derivedDocPaths: () => derivedDocPaths,
3581
- describeApprover: () => describeApprover,
3582
3549
  detectDomainCandidates: () => detectDomainCandidates,
3583
- diagnoseProjectPacks: () => diagnoseProjectPacks,
3584
3550
  diagramSetIndex: () => diagramSetIndex,
3585
3551
  diffAgainstApproval: () => diffAgainstApproval,
3586
3552
  diffSize: () => diffSize,
3587
- discardStagingDir: () => discardStagingDir,
3588
3553
  discoverPacks: () => discoverPacks,
3589
3554
  dryRunSerializeSpecs: () => dryRunSerializeSpecs,
3590
3555
  effectiveDetail: () => effectiveDetail,
3591
3556
  emptyExtensions: () => emptyExtensions,
3592
3557
  ensureDir: () => ensureDir,
3593
3558
  ensureProjectInitialized: () => ensureProjectInitialized,
3594
- exportSddSkills: () => exportSddSkills,
3595
3559
  exportSpecTree: () => exportSpecTree,
3596
- exportSurface: () => exportSurface,
3597
3560
  externalizeSubsystem: () => externalizeSubsystem,
3598
- extractTreeArchive: () => extractTreeArchive2,
3599
3561
  extractTypeIdentifiers: () => extractTypeIdentifiers,
3600
3562
  factsFor: () => factsFor,
3601
3563
  fieldTypeRefs: () => fieldTypeRefs,
3602
3564
  fieldTypesOf: () => fieldTypesOf,
3603
- findChainingParent: () => findChainingParent,
3604
- findChainingSubprojectsMissingConfig: () => findChainingSubprojectsMissingConfig,
3605
- findLegacySpecFiles: () => findLegacySpecFiles,
3606
3565
  findProjectRoot: () => findProjectRoot,
3607
3566
  findSystemRoot: () => findSystemRoot,
3608
- findTestsReferencing: () => findTestsReferencing2,
3609
- fromOpenApi: () => fromOpenApi,
3610
3567
  fromProjectRoot: () => fromProjectRoot,
3611
3568
  generateAgent: () => generateAgent,
3612
3569
  generateAll: () => generateAll,
3613
3570
  generateComponentDiagram: () => generateComponentDiagram,
3614
3571
  generateDiagramSet: () => generateDiagramSet,
3615
3572
  generateSequenceDiagram: () => generateSequenceDiagram,
3616
- getComponentPath: () => getComponentPath,
3617
3573
  getExporter: () => getExporter,
3618
- getGroupPath: () => getGroupPath,
3619
- getImplementationPath: () => getImplementationPath,
3620
- getInterfacePath: () => getInterfacePath,
3621
- getLoaderIssues: () => getLoaderIssues,
3622
3574
  getProjectRoot: () => getProjectRoot,
3623
3575
  getProjectRootOverride: () => getProjectRootOverride,
3624
3576
  getRequestParentReach: () => getRequestParentReach,
3625
3577
  getRequestProjectRoot: () => getRequestProjectRoot,
3626
- getSnapshot: () => getSnapshot,
3627
- getSubprojectPrefix: () => getSubprojectPrefix,
3628
- getSubsystemPath: () => getSubsystemPath,
3629
- getTypePath: () => getTypePath,
3578
+ getStatusReport: () => getStatusReport,
3630
3579
  globalGuideFilePath: () => globalGuideFilePath,
3631
3580
  globalPacksDir: () => globalPacksDir,
3632
- globalPacksEnabled: () => globalPacksEnabled,
3633
3581
  globalTemplatesDir: () => globalTemplatesDir,
3634
- globalVariantsDir: () => globalVariantsDir,
3635
- hasAuthoredSpecs: () => hasAuthoredSpecs,
3636
3582
  hasContext: () => hasContext,
3637
3583
  hasFunctionBody: () => hasFunctionBody,
3638
- hasSpecTree: () => hasSpecTree,
3639
3584
  headNoun: () => headNoun,
3640
3585
  holdsState: () => holdsState,
3641
3586
  implementationSourceFiles: () => implementationSourceFiles,
3642
3587
  importBindingOf: () => importBindingOf,
3643
3588
  importSpecTree: () => importSpecTree,
3644
- importSurface: () => importSurface,
3645
- ineffectiveDeltaPaths: () => ineffectiveDeltaPaths,
3646
3589
  injectGuide: () => injectGuide,
3647
- inspectChainedRoots: () => inspectChainedRoots,
3648
- inspectTreeArchive: () => inspectTreeArchive2,
3649
3590
  installPackFromDirectory: () => installPackFromDirectory,
3650
3591
  interfaceGenericParameters: () => interfaceGenericParameters,
3651
3592
  internalizeSubsystem: () => internalizeSubsystem,
3652
- invalidateSpecCache: () => invalidateSpecCache,
3653
3593
  isDraftSubsystem: () => isDraftSubsystem,
3654
3594
  isLogic: () => isLogic,
3655
- isOpenApiDocument: () => isOpenApiDocument,
3656
3595
  isPattern: () => isPattern,
3657
3596
  isProjectInitialized: () => isProjectInitialized,
3658
3597
  isProvidedBy: () => isProvidedBy,
3659
3598
  isRetired: () => isRetired,
3660
- listChainedRoots: () => listChainedRoots,
3661
3599
  listDirectChainedSubprojects: () => listDirectChainedSubprojects,
3662
- listExternalInterfaces: () => listExternalInterfaces,
3663
3600
  listFiles: () => listFiles,
3664
3601
  listFilesRecursive: () => listFilesRecursive,
3665
3602
  listInstalledPacks: () => listInstalledPacks,
3666
- listMountSnapshots: () => listMountSnapshots,
3667
- listProjectVariants: () => listProjectVariants,
3668
- listResources: () => listResources,
3669
- listRules: () => listRules2,
3670
- listSkillNames: () => listSkillNames,
3671
- listSkillResources: () => listSkillResources,
3672
- listSnapshots: () => listSnapshots,
3673
- listTemplateIds: () => listTemplateIds,
3674
- loadAgentOverride: () => loadAgentOverride,
3675
3603
  loadComponentSpec: () => loadComponentSpec,
3676
3604
  loadComponentSpecs: () => loadComponentSpecs,
3677
3605
  loadExtensionPacks: () => loadExtensionPacks,
3678
3606
  loadExtensions: () => loadExtensions,
3679
- loadGroupSpec: () => loadGroupSpec,
3680
- loadGroupSpecs: () => loadGroupSpecs,
3681
3607
  loadImplementationSpec: () => loadImplementationSpec,
3682
3608
  loadImplementationSpecs: () => loadImplementationSpecs,
3683
3609
  loadInterfaceSpec: () => loadInterfaceSpec,
3684
3610
  loadInterfaceSpecs: () => loadInterfaceSpecs,
3685
- loadMountSurfaceSnapshots: () => loadMountSurfaceSnapshots,
3686
3611
  loadProjectConfig: () => loadProjectConfig4,
3687
3612
  loadProjectExtensions: () => loadProjectExtensions,
3688
- loadProjectVariants: () => loadProjectVariants,
3689
3613
  loadRegistry: () => loadRegistry,
3690
3614
  loadSpecGraph: () => loadSpecGraph,
3691
3615
  loadSubsystemSpec: () => loadSubsystemSpec,
3692
3616
  loadSubsystemSpecs: () => loadSubsystemSpecs,
3693
- loadSurfaceSnapshots: () => loadSurfaceSnapshots,
3694
3617
  loadSystemSpec: () => loadSystemSpec,
3695
- loadTemplate: () => loadTemplate,
3696
3618
  loadTopologyConfig: () => loadTopologyConfig,
3697
3619
  loadTypeSpec: () => loadTypeSpec,
3698
3620
  loadTypeSpecs: () => loadTypeSpecs,
@@ -3710,49 +3632,30 @@ __export(src_exports, {
3710
3632
  moveSubsystemProject: () => moveSubsystemProject,
3711
3633
  movedChildren: () => movedChildren,
3712
3634
  narrativeStepForeignFields: () => narrativeStepForeignFields,
3713
- normalizeApprover: () => normalizeApprover,
3714
- normalizeComponentLayout: () => normalizeComponentLayout,
3715
- packDirEntry: () => packDirEntry,
3716
- packEntryLabel: () => packEntryLabel,
3717
- packEntryRef: () => packEntryRef,
3718
3635
  packStoreDir: () => packStoreDir,
3719
3636
  parseDeclaredCall: () => parseDeclaredCall,
3720
- parseTemplate: () => parseTemplate,
3721
3637
  parseYaml: () => parseYaml,
3722
3638
  passesIntentFloor: () => passesIntentFloor,
3723
3639
  pathExists: () => pathExists,
3724
3640
  pathKey: () => pathKey,
3725
- pinFamilySurfaces: () => pinFamilySurfaces,
3726
- pinInstalledPacksAsSelections: () => pinInstalledPacksAsSelections,
3727
- projectChildSurface: () => projectChildSurface,
3728
3641
  projectConfigExists: () => projectConfigExists,
3729
- projectOwnSurface: () => projectOwnSurface,
3730
- projectSubsystemSurface: () => projectSubsystemSurface,
3731
3642
  provisionProject: () => provisionProject,
3732
3643
  qualifiedTypeId: () => qualifiedTypeId,
3733
3644
  readFileOrNull: () => readFileOrNull,
3734
3645
  readJsonFile: () => readJsonFile,
3735
3646
  readLockRecord: () => readLockRecord,
3736
- readLockRecordAt: () => readLockRecordAt,
3737
3647
  readLockState: () => readLockState,
3738
- readManifest: () => readManifest,
3739
- readResource: () => readResource,
3740
- readSkillResource: () => readSkillResource,
3741
3648
  readStampVersion: () => readStampVersion,
3742
3649
  readYamlFile: () => readYamlFile,
3743
- rebaseProjectVariants: () => rebaseProjectVariants,
3744
- rebaseReference: () => rebaseReference,
3745
3650
  recordProfileSelection: () => recordProfileSelection,
3746
3651
  registerExporter: () => registerExporter,
3747
3652
  registerPackRef: () => registerPackRef,
3748
3653
  reinjectLocalGuides: () => reinjectLocalGuides,
3749
3654
  removeDomain: () => removeDomain,
3750
3655
  removePackSelection: () => removePackSelection,
3751
- removeSnapshot: () => removeSnapshot,
3752
3656
  renameComponent: () => renameComponent,
3753
3657
  renameMethod: () => renameMethod,
3754
3658
  renderDiagram: () => renderDiagram,
3755
- renderTemplateInstructions: () => renderTemplateInstructions,
3756
3659
  repairForeignStepFields: () => repairForeignStepFields,
3757
3660
  resolveAgentTopology: () => resolveAgentTopology,
3758
3661
  resolveBudget: () => resolveBudget,
@@ -3761,47 +3664,31 @@ __export(src_exports, {
3761
3664
  resolveExpectedOutputPaths: () => resolveExpectedOutputPaths,
3762
3665
  resolveImport: () => resolveImport,
3763
3666
  resolveInstalledPack: () => resolveInstalledPack,
3764
- resolvePackRef: () => resolvePackRef,
3765
3667
  resolveSubprojectForNamespace: () => resolveSubprojectForNamespace,
3766
- resolveVariantGuidance: () => resolveVariantGuidance,
3767
- restoreSpecFiles: () => restoreSpecFiles,
3768
3668
  retireSpecialists: () => retireSpecialists,
3769
- rewriteSpecRefs: () => rewriteSpecRefs,
3770
3669
  runWithProjectBinding: () => runWithProjectBinding,
3771
3670
  runWithProjectRoot: () => runWithProjectRoot,
3772
3671
  sameContract: () => sameContract,
3773
3672
  saveComponentSpec: () => saveComponentSpec,
3774
- saveGroupSpec: () => saveGroupSpec,
3775
3673
  saveImplementationSpec: () => saveImplementationSpec,
3776
3674
  saveInterfaceSpec: () => saveInterfaceSpec,
3777
- saveSnapshot: () => saveSnapshot,
3778
3675
  saveSubsystemSpec: () => saveSubsystemSpec,
3779
3676
  saveSystemSpec: () => saveSystemSpec,
3780
3677
  saveTopologyConfig: () => saveTopologyConfig,
3781
3678
  saveTypeSpec: () => saveTypeSpec,
3782
- scanAllSpecs: () => scanAllSpecs,
3783
3679
  serializeYaml: () => serializeYaml,
3784
3680
  setExecutionTier: () => setExecutionTier,
3785
3681
  setLogLevel: () => setLogLevel,
3786
3682
  setProjectRoot: () => setProjectRoot,
3787
3683
  setProjectType: () => setProjectType,
3788
3684
  settledSpecPaths: () => settledSpecPaths,
3789
- skillExtendErrors: () => skillExtendErrors,
3790
- skillsDirForTarget: () => skillsDirForTarget,
3791
- snapshotSpecFiles: () => snapshotSpecFiles,
3792
- specChanges: () => specChanges,
3793
- specKind: () => specKind,
3794
3685
  specPathsInScope: () => specPathsInScope,
3795
3686
  splitNamespace: () => splitNamespace,
3796
- stateIdEquals: () => stateIdEquals,
3797
- stateIdString: () => stateIdString,
3798
3687
  stepConfigVerdict: () => stepConfigVerdict,
3799
3688
  stepFieldsFor: () => stepFieldsFor,
3800
3689
  stepGraph: () => stepGraph,
3801
3690
  syncContextFiles: () => syncContextFiles,
3802
3691
  toMarkdown: () => toMarkdown,
3803
- toOpenApi: () => toOpenApi,
3804
- toOpenApiSet: () => toOpenApiSet,
3805
3692
  typeBindingOf: () => typeBindingOf,
3806
3693
  typeGenericParameters: () => typeGenericParameters,
3807
3694
  typeMatchesRef: () => typeMatchesRef,
@@ -3809,12 +3696,7 @@ __export(src_exports, {
3809
3696
  uninstallPack: () => uninstallPack,
3810
3697
  updateSpec: () => updateSpec,
3811
3698
  upsertPackSelection: () => upsertPackSelection,
3812
- validateAsComplete: () => validateAsComplete,
3813
- validateComponentCandidate: () => validateComponentCandidate,
3814
- validateProjectConfig: () => validateProjectConfig,
3815
- validateRegistry: () => validateRegistry,
3816
3699
  validateSddTree: () => validateSddTree,
3817
- workspaceFor: () => workspaceFor,
3818
3700
  writeFile: () => writeFile,
3819
3701
  writeFileIfChanged: () => writeFileIfChanged,
3820
3702
  writeJsonFile: () => writeJsonFile,
@@ -4710,17 +4592,17 @@ function overlayKnownFields(schema, typed, onDisk) {
4710
4592
  }
4711
4593
  return typed;
4712
4594
  }
4713
- function overlayLevel(typed, onDisk, schemaFor2) {
4595
+ function overlayLevel(typed, onDisk, schemaFor) {
4714
4596
  const document = isPlainObject(onDisk) ? onDisk : {};
4715
4597
  const out = {};
4716
4598
  for (const [key, stored] of Object.entries(document)) {
4717
- const schema = schemaFor2(key);
4599
+ const schema = schemaFor(key);
4718
4600
  if (schema === null) out[key] = stored;
4719
4601
  else if (typed[key] !== void 0) out[key] = overlayKnownFields(schema, typed[key], stored);
4720
4602
  }
4721
4603
  for (const [key, value] of Object.entries(typed)) {
4722
4604
  if (hasOwn(document, key) || value === void 0) continue;
4723
- const schema = schemaFor2(key);
4605
+ const schema = schemaFor(key);
4724
4606
  if (schema !== null) out[key] = overlayKnownFields(schema, value, void 0);
4725
4607
  }
4726
4608
  return out;
@@ -5077,10 +4959,6 @@ function normalizeApprover(value) {
5077
4959
  }
5078
4960
  return { id: typeof value === "string" && value ? value : "unknown", source: "legacy" };
5079
4961
  }
5080
- function describeApprover(who) {
5081
- const label = who.name ? `${who.name} (${who.id})` : who.id;
5082
- return who.source === "hosted" ? `${label} [authenticated]` : label;
5083
- }
5084
4962
  function readLockRecord() {
5085
4963
  try {
5086
4964
  return normalizeRecord(JSON.parse(fs4.readFileSync(lockPath(), "utf8")));
@@ -6398,10 +6276,10 @@ function stepGraph(method) {
6398
6276
  const s = byNum.get(n);
6399
6277
  if (s.type !== "parallel" || s.endStep === void 0 || !s.branches?.length) continue;
6400
6278
  const entries = s.branches.map((b) => b.step).sort((a, b) => a - b);
6401
- const join18 = fallNext(s.endStep);
6279
+ const join17 = fallNext(s.endStep);
6402
6280
  for (let i = 0; i < entries.length; i++) {
6403
6281
  const armEnd = i + 1 < entries.length ? prevOf(entries[i + 1]) : s.endStep;
6404
- if (armEnd !== void 0 && armEnd >= entries[i]) armEndJoin.set(armEnd, join18);
6282
+ if (armEnd !== void 0 && armEnd >= entries[i]) armEndJoin.set(armEnd, join17);
6405
6283
  }
6406
6284
  }
6407
6285
  const successorsOf = (n) => {
@@ -11654,7 +11532,7 @@ function defaultTargetConfig(type) {
11654
11532
  enabled: true
11655
11533
  };
11656
11534
  }
11657
- var WAIRON_VERSION = "5.1.1-dev.61";
11535
+ var WAIRON_VERSION = "5.1.1-dev.63";
11658
11536
  var GITHUB_REPO = "SYW-Apps/Waffle-AIron";
11659
11537
  var ARCHITECT_AGENT_ID = "agent-architect";
11660
11538
  var ARCHITECT_TEMPLATE_ID = "architect";
@@ -12188,66 +12066,6 @@ function defaultPackSelections() {
12188
12066
  return [];
12189
12067
  }
12190
12068
  }
12191
- function diagnoseProjectPacks() {
12192
- const empty = { globalsUndeclared: false, notApplied: [], unresolved: [], globalsApplied: [] };
12193
- try {
12194
- const config = projectConfigRepository.load();
12195
- if (!config) return empty;
12196
- const globalsUndeclared = !projectConfigRepository.declaresGlobalPacks();
12197
- const projectRoot = getProjectRoot();
12198
- const entries = config.extensions?.packs ?? [];
12199
- const unresolved = [];
12200
- const selectedNames = /* @__PURE__ */ new Set();
12201
- for (const entry of entries) {
12202
- if (typeof entry === "string") continue;
12203
- selectedNames.add(entry.name);
12204
- const resolution = resolveSelection(entry, projectRoot);
12205
- if (resolution.failure) {
12206
- unresolved.push({ label: packEntryLabel(entry), message: `[${resolution.failure.code}] ${resolution.failure.message}` });
12207
- }
12208
- }
12209
- const installed = listInstalledPacks();
12210
- const globalsOn = globalPacksEnabled(config);
12211
- const globalsApplied = [];
12212
- if (globalsOn) {
12213
- for (const ref of discoverPacks(globalPacksDir())) {
12214
- const match = installed.find((p) => path10.resolve(p.path) === path10.resolve(ref));
12215
- if (match) globalsApplied.push({ name: match.name, version: match.version });
12216
- }
12217
- }
12218
- const applying = /* @__PURE__ */ new Set([...selectedNames, ...globalsApplied.map((p) => p.name)]);
12219
- const notApplied = installed.filter((p) => !applying.has(p.name)).map((p) => ({ name: p.name, version: p.version, origin: p.origin }));
12220
- return { globalsUndeclared, notApplied, unresolved, globalsApplied };
12221
- } catch {
12222
- return empty;
12223
- }
12224
- }
12225
- function pinInstalledPacksAsSelections() {
12226
- const diagnosis = diagnoseProjectPacks();
12227
- if (!diagnosis.globalsUndeclared || diagnosis.notApplied.length === 0) return [];
12228
- const added = [];
12229
- const selections = [];
12230
- for (const pack of diagnosis.notApplied) {
12231
- selections.push({
12232
- name: pack.name,
12233
- version: pack.version,
12234
- // Carry the origin so the selection can be obtained elsewhere; a local
12235
- // path is not fetchable, so it is deliberately not recorded as a source.
12236
- ...pack.origin && /^[a-z][a-z0-9+.-]*:\/\//i.test(pack.origin) ? { source: pack.origin } : {}
12237
- });
12238
- added.push(`${pack.name}@${pack.version}`);
12239
- }
12240
- projectConfigRepository.pinGlobalPacksAsSelections(selections);
12241
- return added;
12242
- }
12243
- function packEntryLabel(entry) {
12244
- if (typeof entry === "string") return entry;
12245
- return entry.version ? `${entry.name}@${entry.version}` : entry.name;
12246
- }
12247
- function packEntryRef(entry, projectRoot) {
12248
- if (typeof entry === "string") return entry;
12249
- return resolveSelection(entry, projectRoot).ref ?? null;
12250
- }
12251
12069
  function resolveSelection(selection, projectRoot) {
12252
12070
  const wanted = selection.version ? `${selection.name}@${selection.version}` : selection.name;
12253
12071
  const fail = (code, message) => ({ failure: { code, severity: "error", name: selection.name, message } });
@@ -12361,21 +12179,21 @@ function buildCodeIndex(model) {
12361
12179
  const declarations = /* @__PURE__ */ new Map();
12362
12180
  const anchors = /* @__PURE__ */ new Map();
12363
12181
  const findingAnchors = /* @__PURE__ */ new Map();
12364
- const namesAt = (cache, path29, make) => {
12365
- const cached = cache.get(path29);
12182
+ const namesAt = (cache, path28, make) => {
12183
+ const cached = cache.get(path28);
12366
12184
  if (cached) return cached;
12367
- const f = facts.get(path29);
12185
+ const f = facts.get(path28);
12368
12186
  if (!f) return NO_NAMES;
12369
12187
  const built = make(f);
12370
- cache.set(path29, built);
12188
+ cache.set(path28, built);
12371
12189
  return built;
12372
12190
  };
12373
12191
  const republished = /* @__PURE__ */ new Map();
12374
- const republishedFrom = (path29) => {
12375
- const cached = republished.get(path29);
12192
+ const republishedFrom = (path28) => {
12193
+ const cached = republished.get(path28);
12376
12194
  if (cached) return cached;
12377
- const out = /* @__PURE__ */ new Set([path29]);
12378
- const queue = [path29];
12195
+ const out = /* @__PURE__ */ new Set([path28]);
12196
+ const queue = [path28];
12379
12197
  while (queue.length) {
12380
12198
  const from = queue.pop();
12381
12199
  const f = facts.get(from);
@@ -12388,7 +12206,7 @@ function buildCodeIndex(model) {
12388
12206
  }
12389
12207
  }
12390
12208
  }
12391
- republished.set(path29, out);
12209
+ republished.set(path28, out);
12392
12210
  return out;
12393
12211
  };
12394
12212
  const NO_ORIGIN = /* @__PURE__ */ new Set();
@@ -12397,9 +12215,9 @@ function buildCodeIndex(model) {
12397
12215
  return to ? republishedFrom(to) : NO_ORIGIN;
12398
12216
  };
12399
12217
  const scopeOf = (site, from) => {
12400
- const path29 = pathKey(site.from ?? from);
12401
- const f = facts.get(path29);
12402
- return f?.status === "analyzed" && f.analysisGrade === "exact" ? { path: path29, facts: f } : void 0;
12218
+ const path28 = pathKey(site.from ?? from);
12219
+ const f = facts.get(path28);
12220
+ return f?.status === "analyzed" && f.analysisGrade === "exact" ? { path: path28, facts: f } : void 0;
12403
12221
  };
12404
12222
  const originOf = (site, from) => {
12405
12223
  const resolved = scopeOf(site, from);
@@ -12438,14 +12256,14 @@ function buildCodeIndex(model) {
12438
12256
  if (site.via) for (const typeName of localTypesOf(f, site.via)) widenThroughType(typeName);
12439
12257
  return out;
12440
12258
  };
12441
- const declarationsAt = (path29) => namesAt(declarations, pathKey(path29), (f) => /* @__PURE__ */ new Set([...f.declaredNames, ...f.exportedNames]));
12259
+ const declarationsAt = (path28) => namesAt(declarations, pathKey(path28), (f) => /* @__PURE__ */ new Set([...f.declaredNames, ...f.exportedNames]));
12442
12260
  return {
12443
12261
  paths,
12444
12262
  exactPaths,
12445
- factsAt: (path29) => facts.get(pathKey(path29)),
12263
+ factsAt: (path28) => facts.get(pathKey(path28)),
12446
12264
  declarationsAt,
12447
- anchorsAt: (path29) => namesAt(anchors, pathKey(path29), (f) => /* @__PURE__ */ new Set([...f.declaredNames, ...f.exportedNames, ...f.anchoredNames])),
12448
- findingAnchorsAt: (path29) => namesAt(findingAnchors, pathKey(path29), (f) => new Set(f.anchoredNames)),
12265
+ anchorsAt: (path28) => namesAt(anchors, pathKey(path28), (f) => /* @__PURE__ */ new Set([...f.declaredNames, ...f.exportedNames, ...f.anchoredNames])),
12266
+ findingAnchorsAt: (path28) => namesAt(findingAnchors, pathKey(path28), (f) => new Set(f.anchoredNames)),
12449
12267
  originOf,
12450
12268
  possibleOriginsOf
12451
12269
  };
@@ -12483,10 +12301,10 @@ function buildRealizationIndex(ctx) {
12483
12301
  return {
12484
12302
  paths,
12485
12303
  implementationsOf: (compId) => implsByComponent.get(compId) ?? NONE_IMPL,
12486
- implementationsAt: (path29) => implsByPath.get(pathKey(path29)) ?? NONE_IMPL,
12304
+ implementationsAt: (path28) => implsByPath.get(pathKey(path28)) ?? NONE_IMPL,
12487
12305
  filesOf: (compId) => filesByComponent.get(compId) ?? NONE_PATH,
12488
12306
  filesIn: (subsystemId) => filesBySubsystem.get(subsystemId) ?? NONE_PATH,
12489
- componentsAt: (path29) => componentsByPath.get(pathKey(path29)) ?? NONE_COMP
12307
+ componentsAt: (path28) => componentsByPath.get(pathKey(path28)) ?? NONE_COMP
12490
12308
  };
12491
12309
  }
12492
12310
  function buildImportGraph(index, universe) {
@@ -12498,22 +12316,22 @@ function buildImportGraph(index, universe) {
12498
12316
  if (to && to !== from) into.add(to);
12499
12317
  }
12500
12318
  };
12501
- const importsOf = (path29) => {
12502
- const cached = imports.get(path29);
12319
+ const importsOf = (path28) => {
12320
+ const cached = imports.get(path28);
12503
12321
  if (cached) return cached;
12504
- const facts = index.factsAt(path29);
12322
+ const facts = index.factsAt(path28);
12505
12323
  const out = /* @__PURE__ */ new Set();
12506
- if (facts?.status === "analyzed") resolveAll(path29, facts.imports, out);
12507
- imports.set(path29, out);
12324
+ if (facts?.status === "analyzed") resolveAll(path28, facts.imports, out);
12325
+ imports.set(path28, out);
12508
12326
  return out;
12509
12327
  };
12510
- const tracesOf = (path29) => {
12511
- const cached = traces.get(path29);
12328
+ const tracesOf = (path28) => {
12329
+ const cached = traces.get(path28);
12512
12330
  if (cached) return cached;
12513
- const facts = index.factsAt(path29);
12514
- const out = new Set(importsOf(path29));
12515
- if (facts?.status === "analyzed") resolveAll(path29, facts.reexports, out);
12516
- traces.set(path29, out);
12331
+ const facts = index.factsAt(path28);
12332
+ const out = new Set(importsOf(path28));
12333
+ if (facts?.status === "analyzed") resolveAll(path28, facts.reexports, out);
12334
+ traces.set(path28, out);
12517
12335
  return out;
12518
12336
  };
12519
12337
  return {
@@ -13824,11 +13642,11 @@ var unconditionalCallCyclesRule = {
13824
13642
  const memberEdges = keys.flatMap((k) => (adjacency.get(k) ?? []).filter((e) => inScc.has(e.toKey)));
13825
13643
  if (memberEdges.length === 0) continue;
13826
13644
  const anchor = [...memberEdges].sort((a, b) => byCodeUnit(a.fromKey, b.fromKey) || byCodeUnit(a.impl.id, b.impl.id) || a.stepNumber - b.stepNumber)[0];
13827
- const path29 = [...keys].sort(byCodeUnit).join(" \u2192 ");
13645
+ const path28 = [...keys].sort(byCodeUnit).join(" \u2192 ");
13828
13646
  ctx.addIssue(
13829
13647
  "warning",
13830
13648
  "UNCONDITIONAL_CALL_CYCLE",
13831
- `Call cycle with no guard: ${path29} \u2014 every call edge in this cycle is unavoidable on all paths of its narrative (e.g. step ${anchor.stepNumber} of "${anchor.methodName}" in "${anchor.impl.id}" always calls ${anchor.toLabel}). This recurses without a base case, by construction. Guard at least one edge with a branch/return before the call, or lint.allow with the termination argument.`,
13649
+ `Call cycle with no guard: ${path28} \u2014 every call edge in this cycle is unavoidable on all paths of its narrative (e.g. step ${anchor.stepNumber} of "${anchor.methodName}" in "${anchor.impl.id}" always calls ${anchor.toLabel}). This recurses without a base case, by construction. Guard at least one edge with a branch/return before the call, or lint.allow with the termination argument.`,
13832
13650
  anchor.impl.id,
13833
13651
  memberEdges.some((e) => ctx.isImplementationDraft(e.impl))
13834
13652
  );
@@ -16570,11 +16388,11 @@ var hiddenStateRule = {
16570
16388
  byPath.set(key, list);
16571
16389
  }
16572
16390
  }
16573
- for (const path29 of code.exactPaths) {
16574
- const facts = code.factsAt(path29);
16391
+ for (const path28 of code.exactPaths) {
16392
+ const facts = code.factsAt(path28);
16575
16393
  const bindings = facts.topLevelMutableBindings ?? [];
16576
16394
  if (bindings.length === 0) continue;
16577
- const mapped = byPath.get(path29) ?? [];
16395
+ const mapped = byPath.get(path28) ?? [];
16578
16396
  if (mapped.length === 0) continue;
16579
16397
  if (!mapped.every((m) => isStatelessLogic(m.component))) continue;
16580
16398
  const anchor = [...mapped].sort((a, b) => a.impl.id.localeCompare(b.impl.id))[0];
@@ -16640,7 +16458,7 @@ var dependencyConformanceRule = {
16640
16458
  }
16641
16459
  return false;
16642
16460
  };
16643
- const draftAt = (path29) => realization.implementationsAt(path29).some((impl) => ctx.isImplementationDraft(impl));
16461
+ const draftAt = (path28) => realization.implementationsAt(path28).some((impl) => ctx.isImplementationDraft(impl));
16644
16462
  for (const fromPath of mappedPaths) {
16645
16463
  const fromComponents = realization.componentsAt(fromPath);
16646
16464
  for (const toPath of graph.importsOf(fromPath)) {
@@ -18348,9 +18166,6 @@ function ruleSequence() {
18348
18166
  const audits = [carriedDebtRule, lintAllowsRule].filter((r) => ruleSet.includes(r));
18349
18167
  return [...ruleSet.filter((r) => !audits.includes(r)), ...audits];
18350
18168
  }
18351
- function specScopedRules() {
18352
- return ruleSequence().filter((r) => r.scope === "spec");
18353
- }
18354
18169
  function knownIssueCodes() {
18355
18170
  return listRules().flatMap((r) => r.codes);
18356
18171
  }
@@ -18993,48 +18808,6 @@ function buildCodeModel(implementations, types, projectRoot, sourceRoots = [], e
18993
18808
  }
18994
18809
  return { files, projectRoot, rootFiles };
18995
18810
  }
18996
- function readTestFiles(testRoots, projectRoot) {
18997
- const scanned = [];
18998
- for (const key of walkDeclaredRoots(testRoots, [], projectRoot)) {
18999
- let text;
19000
- try {
19001
- const buffer = fs9.readFileSync(path11.resolve(projectRoot, key));
19002
- if (looksBinary(buffer)) continue;
19003
- text = buffer.toString("utf8");
19004
- } catch {
19005
- continue;
19006
- }
19007
- const imports = /* @__PURE__ */ new Set();
19008
- for (const m of text.matchAll(NAMED_IMPORT_BINDINGS_RE)) {
19009
- for (const name of boundNames(m[1] ?? "", false)) imports.add(name);
19010
- }
19011
- const words2 = /* @__PURE__ */ new Set();
19012
- for (const m of text.matchAll(IDENTIFIER_RE)) words2.add(m[0]);
19013
- scanned.push({ path: key, imports, words: words2 });
19014
- }
19015
- return scanned;
19016
- }
19017
- function findTestsReferencing(methods, projectRoot, testRoots = []) {
19018
- const scanned = readTestFiles(testRoots, projectRoot);
19019
- if (scanned.length === 0) return [];
19020
- const indiscriminateAbove = scanned.length / 10;
19021
- const found = [];
19022
- for (const method of methods) {
19023
- const symbol = method.symbol ?? method.name;
19024
- const imported = scanned.filter((f) => f.imports.has(symbol)).map((f) => f.path);
19025
- const mentioned = scanned.filter((f) => !f.imports.has(symbol) && f.words.has(symbol)).map((f) => f.path);
19026
- const indiscriminate = mentioned.length > indiscriminateAbove;
19027
- if (imported.length === 0 && mentioned.length === 0) continue;
19028
- found.push({
19029
- method: method.name,
19030
- symbol,
19031
- imported,
19032
- mentioned: indiscriminate ? [] : mentioned,
19033
- indiscriminate
19034
- });
19035
- }
19036
- return found;
19037
- }
19038
18811
 
19039
18812
  // src/core/rules/index.ts
19040
18813
  function composeRuleSequence(extraRules = []) {
@@ -19529,119 +19302,6 @@ function buildRuleContext(opts) {
19529
19302
  return ctx;
19530
19303
  }
19531
19304
 
19532
- // src/core/rules/candidate.ts
19533
- function stubSystem() {
19534
- const now = (/* @__PURE__ */ new Date()).toISOString();
19535
- return {
19536
- schemaVersion: "1.0.0",
19537
- name: "candidate",
19538
- vision: "",
19539
- boundaries: [],
19540
- globalRequirements: [],
19541
- databases: [],
19542
- createdAt: now,
19543
- updatedAt: now
19544
- };
19545
- }
19546
- function validateComponentCandidate(candidate, opts = {}) {
19547
- const issues = [];
19548
- registerBuiltinRules();
19549
- if (opts.extensions?.rules?.length) registerPackRules(opts.extensions.rules);
19550
- const knownCodes = /* @__PURE__ */ new Set([
19551
- ...knownIssueCodes().map((rc) => rc.code),
19552
- ...(opts.extensions?.assertions ?? []).map((a) => a.fullCode)
19553
- ]);
19554
- const ctx = buildRuleContext({
19555
- system: stubSystem(),
19556
- subsystems: [],
19557
- components: [candidate],
19558
- interfaces: [],
19559
- implementations: [],
19560
- types: [],
19561
- rules: opts.rules,
19562
- projectType: opts.projectType ?? "backend",
19563
- extensions: opts.extensions,
19564
- // Only a tree-scoped rule reads these (roundtrip-serialization); no
19565
- // spec-scoped rule does, so a candidate carries none.
19566
- roundTripIssues: [],
19567
- knownIssueCodes: knownCodes,
19568
- issues
19569
- });
19570
- for (const rule of specScopedRules()) {
19571
- rule.check(ctx);
19572
- }
19573
- const own = issues.filter((i) => !i.specId || i.specId === candidate.id);
19574
- return {
19575
- errors: own.filter((i) => i.severity === "error"),
19576
- warnings: own.filter((i) => i.severity === "warning")
19577
- };
19578
- }
19579
-
19580
- // src/core/rules/gate-identity.ts
19581
- var crypto3 = __toESM(require("crypto"));
19582
- var GATE_ALGORITHM = "sha256+content+doctrine+inputs";
19583
- function doctrineIdentity(doctrine, builtinRules, gate) {
19584
- const byKey = (items, key) => [...items].sort((a, b) => compareOrdinal(key(a), key(b)));
19585
- return {
19586
- /**
19587
- * The BUILTIN rule set, by identity rather than by wairon version.
19588
- *
19589
- * A binary upgrade changes the gate only when the rules change, so hashing the
19590
- * version would invalidate every lock on every patch while hashing nothing
19591
- * would let a minor that ADDS a rule leave locks asserting they passed a gate
19592
- * that no longer exists. Keying on the registry means a release that touches no
19593
- * rule keeps every lock valid, and one that adds, removes, or re-grades a code
19594
- * invalidates exactly the locks it should.
19595
- *
19596
- * Residual gap, accepted knowingly: a rule whose IMPLEMENTATION grows stricter
19597
- * without its name, codes, or default severity changing is not caught. Folding
19598
- * in the wairon version would catch it at the cost of churning every lock on
19599
- * every release — the trade this projection deliberately declines.
19600
- */
19601
- builtinRules: byKey(
19602
- builtinRules.map((r) => ({
19603
- name: r.name,
19604
- codes: byKey(r.codes.map((c) => ({ code: c.code, severity: c.defaultSeverity })), (c) => c.code)
19605
- })),
19606
- (r) => r.name
19607
- ),
19608
- /**
19609
- * Which profile GOVERNS, and the project's own rule tuning. Both decide
19610
- * verdicts — a projectType switch changes the doctrine family outright, and
19611
- * `rules` carries severity overrides, complexity caps, and designDepth.
19612
- */
19613
- projectType: gate.projectType ?? null,
19614
- rulesConfig: gate.rules ?? null,
19615
- packs: byKey(
19616
- doctrine.packs.map((p) => ({ name: p.name, version: p.version ?? null, scope: p.scope })),
19617
- (p) => `${p.name}@${p.version ?? ""}#${p.scope}`
19618
- ),
19619
- // Merged records already encode pack precedence, so their resolved content is
19620
- // the identity — a load-order change that flips a collision winner shows up here.
19621
- profiles: doctrine.profiles,
19622
- languages: doctrine.languages,
19623
- patterns: byKey(
19624
- doctrine.patterns.map((p) => ({ id: p.id, version: p.version, pack: p.pack })),
19625
- (p) => `${p.pack}/${p.id}@${p.version}`
19626
- ),
19627
- guarantees: [...doctrine.guarantees].sort(),
19628
- assertions: byKey(doctrine.assertions.map((a) => ({ ...a })), (a) => a.fullCode),
19629
- rules: byKey(
19630
- doctrine.rules.map((r) => ({ name: r.name, codes: r.codes.map((c) => c.code).sort() })),
19631
- (r) => r.name
19632
- )
19633
- };
19634
- }
19635
- function computeGateIdentity(content, doctrine, builtinRules, inputs, gate) {
19636
- const payload = {
19637
- content: content.digest,
19638
- doctrine: doctrineIdentity(doctrine, builtinRules, gate),
19639
- inputs: [...inputs].sort()
19640
- };
19641
- const digest2 = crypto3.createHash("sha256").update(canonicalize(payload)).digest("hex");
19642
- return { algorithm: GATE_ALGORITHM, digest: digest2 };
19643
- }
19644
-
19645
19305
  // src/core/variants.ts
19646
19306
  var fs10 = __toESM(require("fs"));
19647
19307
  var os3 = __toESM(require("os"));
@@ -19795,523 +19455,14 @@ function rebasedText(content, fromBase, toBase, rebasedContent) {
19795
19455
  var fs11 = __toESM(require("fs"));
19796
19456
  var path13 = __toESM(require("path"));
19797
19457
 
19798
- // src/utils/filenames.ts
19799
- function safeFilenamePart(value) {
19800
- return value.replace(/[^a-zA-Z0-9._-]/g, "-");
19801
- }
19802
-
19803
19458
  // src/core/openapi.ts
19804
19459
  var yaml2 = __toESM(require("js-yaml"));
19805
- var PRIMITIVES = {
19806
- string: { type: "string" },
19807
- number: { type: "number" },
19808
- float: { type: "number" },
19809
- decimal: { type: "number" },
19810
- int: { type: "integer" },
19811
- integer: { type: "integer" },
19812
- boolean: { type: "boolean" },
19813
- bool: { type: "boolean" },
19814
- date: { type: "string", format: "date-time" },
19815
- datetime: { type: "string", format: "date-time" },
19816
- uuid: { type: "string", format: "uuid" },
19817
- json: { type: "object" },
19818
- object: { type: "object" },
19819
- any: {},
19820
- unknown: {},
19821
- void: {}
19822
- };
19823
- function schemaFor(typeRef, closureIds) {
19824
- const trimmed = typeRef.trim().replace(/^promise\s*<(.+)>$/i, "$1").trim();
19825
- const arrayMatch = /^(.+)\[\]$/.exec(trimmed);
19826
- if (arrayMatch) {
19827
- return { type: "array", items: schemaFor(arrayMatch[1], closureIds) };
19828
- }
19829
- const lower = trimmed.toLowerCase();
19830
- if (lower in PRIMITIVES) {
19831
- const p = PRIMITIVES[lower];
19832
- return p.type ? { ...p } : {};
19833
- }
19834
- const local = trimmed.split(/::|\./).pop().toLowerCase().replace(/[^a-z0-9_-]/g, "");
19835
- const hit = [...closureIds].find((id) => id.toLowerCase() === local);
19836
- if (hit) return { $ref: `#/components/schemas/${hit}` };
19837
- return { type: "object", description: `Unresolved type: ${trimmed}` };
19838
- }
19839
- function operationFor(method, closureIds) {
19840
- const endpoint = method.endpoint;
19841
- const httpVerb = endpoint && endpoint.transport === "HTTP" ? endpoint.method.toLowerCase() : "post";
19842
- const bodyVerbs = /* @__PURE__ */ new Set(["post", "put", "patch"]);
19843
- const params = method.params ?? [];
19844
- const op = {
19845
- operationId: method.name,
19846
- summary: method.description,
19847
- responses: {
19848
- "200": {
19849
- description: method.returns || "Success",
19850
- ...method.returns && method.returns.toLowerCase() !== "void" ? { content: { "application/json": { schema: schemaFor(method.returns, closureIds) } } } : {}
19851
- }
19852
- }
19853
- };
19854
- if (method.guarantees?.length) op["x-wairon-guarantees"] = method.guarantees;
19855
- if (method.effect) op["x-wairon-effect"] = method.effect;
19856
- if (method.ext && Object.keys(method.ext).length) op["x-wairon-ext"] = method.ext;
19857
- if (params.length) {
19858
- if (bodyVerbs.has(httpVerb)) {
19859
- op.requestBody = {
19860
- required: true,
19861
- content: {
19862
- "application/json": {
19863
- schema: {
19864
- type: "object",
19865
- properties: Object.fromEntries(params.map((p) => [p.name, schemaFor(p.type, closureIds)])),
19866
- required: params.filter((p) => !p.optional).map((p) => p.name)
19867
- }
19868
- }
19869
- }
19870
- };
19871
- } else {
19872
- op.parameters = params.map((p) => ({
19873
- name: p.name,
19874
- in: "query",
19875
- required: !p.optional,
19876
- ...p.description ? { description: p.description } : {},
19877
- schema: schemaFor(p.type, closureIds)
19878
- }));
19879
- }
19880
- }
19881
- return op;
19882
- }
19883
- function securitySchemeObject(auth) {
19884
- if (auth.scheme === "none") return null;
19885
- const desc = auth.description ? { description: auth.description } : {};
19886
- switch (auth.scheme) {
19887
- case "apiKey":
19888
- return { type: "apiKey", in: auth.in ?? "header", name: auth.name ?? "X-API-Key", ...desc };
19889
- case "bearer":
19890
- return { type: "http", scheme: "bearer", ...auth.bearerFormat ? { bearerFormat: auth.bearerFormat } : {}, ...desc };
19891
- case "basic":
19892
- return { type: "http", scheme: "basic", ...desc };
19893
- case "oauth2": {
19894
- const flow = { scopes: Object.fromEntries((auth.scopes ?? []).map((s) => [s.name, s.description])) };
19895
- if (auth.authorizationUrl) flow.authorizationUrl = auth.authorizationUrl;
19896
- if (auth.tokenUrl) flow.tokenUrl = auth.tokenUrl;
19897
- if (auth.refreshUrl) flow.refreshUrl = auth.refreshUrl;
19898
- return { type: "oauth2", flows: { [auth.flow ?? "authorizationCode"]: flow }, ...desc };
19899
- }
19900
- case "openIdConnect":
19901
- return { type: "openIdConnect", openIdConnectUrl: auth.openIdConnectUrl ?? "", ...desc };
19902
- case "custom":
19903
- return { type: "apiKey", in: auth.in ?? "header", name: auth.name ?? "Authorization", description: auth.description ?? auth.example ?? "Custom authentication scheme." };
19904
- default:
19905
- return null;
19906
- }
19907
- }
19908
- function schemeBaseName(scheme) {
19909
- return { apiKey: "ApiKeyAuth", bearer: "BearerAuth", basic: "BasicAuth", oauth2: "OAuth2", openIdConnect: "OpenIdConnect", custom: "CustomAuth" }[scheme] ?? "Auth";
19910
- }
19911
- function buildSecurity(entries) {
19912
- const schemes = {};
19913
- const nameByContent = /* @__PURE__ */ new Map();
19914
- const securityByEntry = /* @__PURE__ */ new Map();
19915
- for (const entry of entries) {
19916
- if (!entry.auth) continue;
19917
- const obj = securitySchemeObject(entry.auth);
19918
- if (!obj) continue;
19919
- const content = JSON.stringify(obj);
19920
- let name = nameByContent.get(content);
19921
- if (!name) {
19922
- name = schemeBaseName(entry.auth.scheme);
19923
- for (let n = 2; schemes[name]; n++) name = schemeBaseName(entry.auth.scheme) + n;
19924
- schemes[name] = obj;
19925
- nameByContent.set(content, name);
19926
- }
19927
- const scopeNames = entry.auth.scheme === "oauth2" ? (entry.auth.scopes ?? []).map((s) => s.name) : [];
19928
- securityByEntry.set(entry.id, { [name]: scopeNames });
19929
- }
19930
- return { schemes, securityByEntry };
19931
- }
19932
- function httpEntriesOf(snapshot) {
19933
- return snapshot.interfaces.filter((e) => e.type === "REST" || e.methods.some((m) => m.endpoint?.transport === "HTTP"));
19934
- }
19935
- function renderDoc(snapshot, entries, closureIds, opts = {}) {
19936
- const { schemes, securityByEntry } = buildSecurity(entries);
19937
- const paths = {};
19938
- for (const entry of entries) {
19939
- const security = securityByEntry.get(entry.id);
19940
- for (const method of entry.methods) {
19941
- const endpoint = method.endpoint;
19942
- if (!endpoint || endpoint.transport !== "HTTP") continue;
19943
- const p = endpoint.path.startsWith("/") ? endpoint.path : `/${endpoint.path}`;
19944
- paths[p] = paths[p] ?? {};
19945
- paths[p][endpoint.method.toLowerCase()] = {
19946
- tags: [entry.id],
19947
- ...operationFor(method, closureIds),
19948
- ...security ? { security: [security] } : {}
19949
- };
19950
- }
19951
- }
19952
- const schemas = {};
19953
- for (const t of snapshot.types) {
19954
- schemas[t.id] = {
19955
- type: "object",
19956
- title: t.name,
19957
- properties: Object.fromEntries(t.fields.map((f) => [f.name, schemaFor(f.type, closureIds)])),
19958
- required: t.fields.filter((f) => !f.optional).map((f) => f.name)
19959
- };
19960
- }
19961
- const components = {};
19962
- if (Object.keys(schemas).length) components.schemas = schemas;
19963
- if (Object.keys(schemes).length) components.securitySchemes = schemes;
19964
- const basePaths = [...new Set(entries.map((e) => e.basePath).filter((b) => !!b))];
19965
- const servers = opts.servers && basePaths.length === 1 ? [{ url: basePaths[0] }] : void 0;
19966
- return {
19967
- openapi: "3.1.0",
19968
- info: {
19969
- title: opts.title ?? snapshot.projectName,
19970
- version: snapshot.version ?? "0.0.0",
19971
- ...snapshot.stateId ? { "x-wairon-state-id": snapshot.stateId } : {},
19972
- "x-wairon-origin": snapshot.origin,
19973
- "x-wairon-generated-at": snapshot.generatedAt
19974
- },
19975
- ...servers ? { servers } : {},
19976
- paths,
19977
- ...Object.keys(components).length ? { components } : {}
19978
- };
19979
- }
19980
- function toOpenApi(snapshot) {
19981
- const closureIds = new Set(snapshot.types.map((t) => t.id));
19982
- return JSON.stringify(renderDoc(snapshot, httpEntriesOf(snapshot), closureIds), null, 2);
19983
- }
19984
- function toOpenApiSet(snapshot) {
19985
- const closureIds = new Set(snapshot.types.map((t) => t.id));
19986
- const byPortal = /* @__PURE__ */ new Map();
19987
- const order = [];
19988
- for (const entry of httpEntriesOf(snapshot)) {
19989
- if (!byPortal.has(entry.component)) {
19990
- byPortal.set(entry.component, []);
19991
- order.push(entry.component);
19992
- }
19993
- byPortal.get(entry.component).push(entry);
19994
- }
19995
- return order.map((portalId) => {
19996
- const entries = byPortal.get(portalId);
19997
- const name = entries[0]?.name ?? portalId;
19998
- return { portalId, name, document: JSON.stringify(renderDoc(snapshot, entries, closureIds, { title: name, servers: true }), null, 2) };
19999
- });
20000
- }
20001
- function isOpenApiDocument(body) {
20002
- try {
20003
- const parsed = yaml2.load(body);
20004
- return !!parsed && typeof parsed === "object" && typeof parsed.openapi === "string";
20005
- } catch {
20006
- return false;
20007
- }
20008
- }
20009
- function typeRefFromSchema(schema) {
20010
- if (!schema) return "json";
20011
- const ref = schema.$ref;
20012
- if (typeof ref === "string") return ref.split("/").pop() ?? "json";
20013
- if (schema.type === "array") {
20014
- return `${typeRefFromSchema(schema.items)}[]`;
20015
- }
20016
- const t = schema.type;
20017
- if (t === "integer") return "int";
20018
- if (typeof t === "string" && t !== "object") return t;
20019
- return "json";
20020
- }
20021
- function authFromSecurityScheme(scheme) {
20022
- const desc = typeof scheme.description === "string" ? { description: scheme.description } : {};
20023
- if (scheme.type === "apiKey") {
20024
- return {
20025
- scheme: "apiKey",
20026
- ...scheme.in === "header" || scheme.in === "query" || scheme.in === "cookie" ? { in: scheme.in } : {},
20027
- ...typeof scheme.name === "string" ? { name: scheme.name } : {},
20028
- ...desc
20029
- };
20030
- }
20031
- if (scheme.type === "http") {
20032
- if (scheme.scheme === "bearer") return { scheme: "bearer", ...typeof scheme.bearerFormat === "string" ? { bearerFormat: scheme.bearerFormat } : {}, ...desc };
20033
- if (scheme.scheme === "basic") return { scheme: "basic", ...desc };
20034
- }
20035
- if (scheme.type === "oauth2") {
20036
- const flows = scheme.flows ?? {};
20037
- const flowKey = Object.keys(flows)[0];
20038
- const f = flows[flowKey] ?? {};
20039
- return {
20040
- scheme: "oauth2",
20041
- ...flowKey === "authorizationCode" || flowKey === "clientCredentials" || flowKey === "implicit" || flowKey === "password" ? { flow: flowKey } : {},
20042
- ...typeof f.authorizationUrl === "string" ? { authorizationUrl: f.authorizationUrl } : {},
20043
- ...typeof f.tokenUrl === "string" ? { tokenUrl: f.tokenUrl } : {},
20044
- ...typeof f.refreshUrl === "string" ? { refreshUrl: f.refreshUrl } : {},
20045
- scopes: Object.entries(f.scopes ?? {}).map(([name, description]) => ({ name, description })),
20046
- ...desc
20047
- };
20048
- }
20049
- if (scheme.type === "openIdConnect") {
20050
- return { scheme: "openIdConnect", openIdConnectUrl: typeof scheme.openIdConnectUrl === "string" ? scheme.openIdConnectUrl : "", ...desc };
20051
- }
20052
- return void 0;
20053
- }
20054
- function fromOpenApi(document, projectName) {
20055
- let parsed;
20056
- try {
20057
- parsed = yaml2.load(document);
20058
- } catch (e) {
20059
- throw new Error(`Invalid surface document: not parseable as JSON/YAML (${e instanceof Error ? e.message : String(e)})`);
20060
- }
20061
- if (!parsed || typeof parsed !== "object" || typeof parsed.openapi !== "string" || typeof parsed.paths !== "object") {
20062
- throw new Error('Invalid surface document: missing OpenAPI "openapi"/"paths" structure.');
20063
- }
20064
- const info = parsed.info ?? {};
20065
- const methods = [];
20066
- for (const [rawPath, ops] of Object.entries(parsed.paths)) {
20067
- for (const [verb, opRaw] of Object.entries(ops ?? {})) {
20068
- if (!["get", "post", "put", "delete", "patch", "options", "head"].includes(verb)) continue;
20069
- const op = opRaw ?? {};
20070
- const name = typeof op.operationId === "string" && /^[a-zA-Z0-9_]+$/.test(op.operationId) ? op.operationId : `${verb}_${rawPath.replace(/[^a-zA-Z0-9]+/g, "_").replace(/^_+|_+$/g, "")}`;
20071
- const params = [];
20072
- for (const p of op.parameters ?? []) {
20073
- if (typeof p.name !== "string") continue;
20074
- params.push({
20075
- name: p.name,
20076
- type: typeRefFromSchema(p.schema),
20077
- ...p.required === true ? {} : { optional: true },
20078
- ...typeof p.description === "string" ? { description: p.description } : {}
20079
- });
20080
- }
20081
- const bodySchema = op.requestBody?.content?.["application/json"]?.schema;
20082
- if (bodySchema) {
20083
- const props = bodySchema.properties ?? {};
20084
- const required = new Set(bodySchema.required ?? []);
20085
- if (Object.keys(props).length) {
20086
- for (const [pname, pschema] of Object.entries(props)) {
20087
- params.push({ name: pname, type: typeRefFromSchema(pschema), ...required.has(pname) ? {} : { optional: true } });
20088
- }
20089
- } else {
20090
- params.push({ name: "body", type: typeRefFromSchema(bodySchema) });
20091
- }
20092
- }
20093
- const okResponse = op.responses?.["200"] ?? op.responses?.["201"];
20094
- const responseSchema = okResponse?.content?.["application/json"]?.schema;
20095
- const returns = responseSchema ? typeRefFromSchema(responseSchema) : "void";
20096
- const rawGuarantees = op["x-wairon-guarantees"];
20097
- const guarantees = Array.isArray(rawGuarantees) ? rawGuarantees.filter((g) => typeof g === "string" && g.length > 0) : [];
20098
- const rawEffect = op["x-wairon-effect"];
20099
- const effect = rawEffect === "read" || rawEffect === "write" ? rawEffect : void 0;
20100
- const rawExt = op["x-wairon-ext"];
20101
- const ext = rawExt && typeof rawExt === "object" && !Array.isArray(rawExt) ? rawExt : void 0;
20102
- methods.push({
20103
- name,
20104
- description: typeof op.summary === "string" ? op.summary : typeof op.description === "string" ? op.description : name,
20105
- signature: `${name}(${params.map((p) => `${p.name}: ${p.type}`).join(", ")}): ${returns}`,
20106
- returns,
20107
- params,
20108
- endpoint: { transport: "HTTP", method: verb.toUpperCase(), path: rawPath },
20109
- ...guarantees.length ? { guarantees } : {},
20110
- ...effect ? { effect } : {},
20111
- ...ext ? { ext } : {}
20112
- });
20113
- }
20114
- }
20115
- const types = [];
20116
- const schemas = parsed.components?.schemas ?? {};
20117
- for (const [id, schema] of Object.entries(schemas)) {
20118
- const props = schema.properties ?? {};
20119
- const required = new Set(schema.required ?? []);
20120
- types.push({
20121
- id,
20122
- name: typeof schema.title === "string" ? schema.title : id,
20123
- kind: "value-object",
20124
- fields: Object.entries(props).map(([fname, fschema]) => ({
20125
- name: fname,
20126
- type: typeRefFromSchema(fschema),
20127
- ...required.has(fname) ? {} : { optional: true }
20128
- }))
20129
- });
20130
- }
20131
- const securitySchemes = parsed.components?.securitySchemes ?? {};
20132
- const firstScheme = Object.values(securitySchemes)[0];
20133
- const importedAuth = firstScheme ? authFromSecurityScheme(firstScheme) : void 0;
20134
- const entry = {
20135
- id: `${projectName}-api`,
20136
- name: typeof info.title === "string" ? info.title : projectName,
20137
- audience: "external",
20138
- type: "REST",
20139
- component: `${projectName}-api`,
20140
- methods,
20141
- details: typeof info.description === "string" ? info.description : `Imported OpenAPI surface of ${projectName}.`,
20142
- ...typeof info.version === "string" ? { version: info.version } : {},
20143
- ...importedAuth ? { auth: importedAuth } : {}
20144
- };
20145
- return SurfaceSnapshotSchema.parse({
20146
- projectName,
20147
- origin: "authored",
20148
- ...typeof info.version === "string" ? { version: info.version } : {},
20149
- generatedAt: (/* @__PURE__ */ new Date()).toISOString(),
20150
- interfaces: [entry],
20151
- types
20152
- });
20153
- }
20154
19460
 
20155
19461
  // src/core/surfaces.ts
20156
19462
  var SURFACES_DIRNAME = "surfaces";
20157
19463
  function surfacesDir(rootDir) {
20158
19464
  return path13.join(rootDir, ".wai", SURFACES_DIRNAME);
20159
19465
  }
20160
- function audienceRank(audience) {
20161
- const idx = SURFACE_AUDIENCES.indexOf(audience ?? "instance");
20162
- return idx === -1 ? SURFACE_AUDIENCES.indexOf("instance") : idx;
20163
- }
20164
- function stateIdString() {
20165
- const s = computeStateId();
20166
- return `${s.algorithm}:${s.digest}`;
20167
- }
20168
- function computeTypeClosure(entries, types) {
20169
- const included = /* @__PURE__ */ new Map();
20170
- const queue = [];
20171
- const enqueueRef = (ref) => {
20172
- if (BUILTIN_TYPES.has(ref.toLowerCase())) return;
20173
- for (const spec of types) {
20174
- const qualifiedId = spec.subsystem && !spec.id.startsWith(`${spec.subsystem}::`) ? `${spec.subsystem}::${spec.id}` : spec.id;
20175
- if (matchTypeRef(ref, qualifiedId) && !included.has(spec.id)) {
20176
- included.set(spec.id, spec);
20177
- queue.push(spec.id);
20178
- }
20179
- }
20180
- };
20181
- for (const entry of entries) {
20182
- for (const m of entry.methods) {
20183
- for (const ref of methodTypeRefs(m)) enqueueRef(ref);
20184
- }
20185
- }
20186
- while (queue.length) {
20187
- const spec = included.get(queue.shift());
20188
- for (const field of spec.fields) {
20189
- for (const ref of extractTypeIdentifiers(field.type)) enqueueRef(ref);
20190
- }
20191
- }
20192
- return [...included.values()].map((t) => ({
20193
- id: t.id,
20194
- name: t.name,
20195
- kind: t.kind,
20196
- fields: t.fields.map((f) => ({
20197
- name: f.name,
20198
- type: f.type,
20199
- ...f.description ? { description: f.description } : {},
20200
- ...f.optional ? { optional: true } : {}
20201
- }))
20202
- }));
20203
- }
20204
- function projectOwnSurface(maxAudience) {
20205
- const system = loadSystemSpec();
20206
- if (!system) {
20207
- throw new Error("Cannot project a surface: the L0 system spec is missing.");
20208
- }
20209
- const subsystems = loadSubsystemSpecs();
20210
- const components = loadComponentSpecs();
20211
- const interfaces = loadInterfaceSpecs();
20212
- const types = loadTypeSpecs();
20213
- const floor = audienceRank(maxAudience);
20214
- const rawEntries = system.publicInterfaces ?? [];
20215
- const entries = [];
20216
- for (const raw of rawEntries) {
20217
- const audience = raw.audience ?? "instance";
20218
- if (audienceRank(audience) < floor) continue;
20219
- if (!raw.component) continue;
20220
- const comp = components.find((c) => c.id === raw.component);
20221
- if (!comp) continue;
20222
- const compInterfaces = interfaces.filter((i) => i.component === comp.id && (!raw.interface || i.id === raw.interface));
20223
- const methods = compInterfaces.flatMap((i) => i.methods);
20224
- const subsystemType = subsystems.find((s) => s.id === comp.subsystem)?.publicInterfaces.find((pi) => pi.component === comp.id)?.type;
20225
- entries.push({
20226
- id: raw.id ?? raw.interface ?? comp.id,
20227
- name: raw.name ?? comp.name,
20228
- audience,
20229
- type: raw.type ?? subsystemType ?? "Custom",
20230
- component: comp.id,
20231
- methods,
20232
- ...comp.dispatch && comp.dispatch.length ? { dispatch: comp.dispatch } : {},
20233
- // Project the backing Portal's auth + basePath so the codec can emit
20234
- // OpenAPI security + per-portal servers self-contained from the snapshot.
20235
- ...comp.auth && comp.auth.scheme !== "none" ? { auth: comp.auth } : {},
20236
- ...comp.basePath ? { basePath: comp.basePath } : {},
20237
- details: raw.details ?? "",
20238
- ...raw.version ? { version: raw.version } : {},
20239
- ...raw.stability ? { stability: raw.stability } : {}
20240
- });
20241
- }
20242
- return SurfaceSnapshotSchema.parse({
20243
- projectName: system.name,
20244
- origin: "generated",
20245
- stateId: stateIdString(),
20246
- generatedAt: (/* @__PURE__ */ new Date()).toISOString(),
20247
- interfaces: entries,
20248
- types: computeTypeClosure(entries, types)
20249
- });
20250
- }
20251
- function projectChildSurface() {
20252
- return projectOwnSurface("project");
20253
- }
20254
- function localName(id) {
20255
- return id.split("::").pop();
20256
- }
20257
- var CROSS_BOUNDARY_TARGETS = /* @__PURE__ */ new Set(["Portal", "Observer"]);
20258
- function projectSubsystemSurface(subsystemId) {
20259
- const system = loadSystemSpec();
20260
- if (!system) {
20261
- throw new Error("Cannot project a subsystem surface: the L0 system spec is missing.");
20262
- }
20263
- const subsystems = loadSubsystemSpecs();
20264
- const target = subsystems.find((s) => s.id === subsystemId);
20265
- if (!target) {
20266
- throw new Error(`Cannot project a subsystem surface: subsystem "${subsystemId}" does not exist.`);
20267
- }
20268
- const components = loadComponentSpecs();
20269
- const interfaces = loadInterfaceSpecs();
20270
- const types = loadTypeSpecs();
20271
- const entries = [];
20272
- const unprojectable = [];
20273
- for (const pub of target.publicInterfaces ?? []) {
20274
- if (!pub.component) continue;
20275
- const comp = components.find((c) => c.id === pub.component || c.id === `${subsystemId}::${pub.component}`);
20276
- if (!comp) continue;
20277
- if (!CROSS_BOUNDARY_TARGETS.has(comp.componentType)) {
20278
- unprojectable.push({ component: pub.component, componentType: comp.componentType });
20279
- continue;
20280
- }
20281
- const compInterfaces = interfaces.filter((i) => i.component === comp.id && (!pub.interface || i.id === pub.interface || i.id === `${subsystemId}::${pub.interface}`));
20282
- const methods = compInterfaces.flatMap((i) => i.methods);
20283
- entries.push({
20284
- id: localName(pub.interface ?? comp.id),
20285
- name: comp.name,
20286
- // Family ceiling: a sibling surface is consumable by the system family only.
20287
- audience: "project",
20288
- type: pub.type ?? "Custom",
20289
- // The snapshot carries the LOCAL portal name — consumers resolve cross-tree
20290
- // refs by their final segment.
20291
- component: localName(comp.id),
20292
- methods,
20293
- ...comp.dispatch && comp.dispatch.length ? { dispatch: comp.dispatch } : {},
20294
- // Project the backing component's auth + basePath so the codec can emit
20295
- // OpenAPI security + per-portal servers self-contained from the snapshot.
20296
- ...comp.auth && comp.auth.scheme !== "none" ? { auth: comp.auth } : {},
20297
- ...comp.basePath ? { basePath: comp.basePath } : {},
20298
- details: pub.details ?? ""
20299
- });
20300
- }
20301
- for (const skipped of unprojectable) {
20302
- console.error(
20303
- `[surfaces] skipped "${subsystemId}::${skipped.component}": a published ${skipped.componentType} can never serve a cross-boundary caller, so it stays out of every chained child's sibling surface \u2014 publish this surface through a Portal, or an Observer (for events).`
20304
- );
20305
- }
20306
- return SurfaceSnapshotSchema.parse({
20307
- projectName: `${system.name}::${subsystemId}`,
20308
- origin: "generated",
20309
- stateId: stateIdString(),
20310
- generatedAt: (/* @__PURE__ */ new Date()).toISOString(),
20311
- interfaces: entries,
20312
- types: computeTypeClosure(entries, types)
20313
- });
20314
- }
20315
19466
  function listSnapshots(rootDir = getProjectRoot()) {
20316
19467
  const dir = surfacesDir(rootDir);
20317
19468
  if (!fs11.existsSync(dir)) return [];
@@ -20325,54 +19476,6 @@ function listSnapshots(rootDir = getProjectRoot()) {
20325
19476
  }
20326
19477
  return out;
20327
19478
  }
20328
- function getSnapshot(projectName, rootDir = getProjectRoot()) {
20329
- return listSnapshots(rootDir).find((s) => s.projectName === projectName) ?? null;
20330
- }
20331
- function snapshotFilename(projectName) {
20332
- return `${safeFilenamePart(projectName)}.yaml`;
20333
- }
20334
- function writeSnapshotIfChanged(snapshot, rootDir) {
20335
- const dir = surfacesDir(rootDir);
20336
- fs11.mkdirSync(dir, { recursive: true });
20337
- const p = path13.join(dir, snapshotFilename(snapshot.projectName));
20338
- const next = SurfaceSnapshotSchema.parse(snapshot);
20339
- if (fs11.existsSync(p)) {
20340
- try {
20341
- const existing = SurfaceSnapshotSchema.parse(readYamlFile(p));
20342
- if (surfaceContentKey(existing) === surfaceContentKey(next)) {
20343
- return { path: p, changed: false };
20344
- }
20345
- } catch {
20346
- }
20347
- }
20348
- writeYamlFile(p, next);
20349
- return { path: p, changed: true };
20350
- }
20351
- function saveSnapshot(snapshot, rootDir = getProjectRoot()) {
20352
- return writeSnapshotIfChanged(snapshot, rootDir).path;
20353
- }
20354
- function removeSnapshot(projectName, rootDir = getProjectRoot()) {
20355
- const dir = surfacesDir(rootDir);
20356
- const direct = path13.join(dir, snapshotFilename(projectName));
20357
- if (fs11.existsSync(direct)) {
20358
- fs11.unlinkSync(direct);
20359
- return true;
20360
- }
20361
- if (!fs11.existsSync(dir)) return false;
20362
- for (const file of fs11.readdirSync(dir)) {
20363
- if (!file.endsWith(".yaml") && !file.endsWith(".yml")) continue;
20364
- const p = path13.join(dir, file);
20365
- try {
20366
- const snap = SurfaceSnapshotSchema.parse(readYamlFile(p));
20367
- if (snap.projectName === projectName) {
20368
- fs11.unlinkSync(p);
20369
- return true;
20370
- }
20371
- } catch {
20372
- }
20373
- }
20374
- return false;
20375
- }
20376
19479
  function loadSurfaceSnapshots() {
20377
19480
  return listSnapshots();
20378
19481
  }
@@ -20390,136 +19493,12 @@ function listMountSnapshots(mounts) {
20390
19493
  function loadMountSurfaceSnapshots(mounts) {
20391
19494
  return listMountSnapshots(mounts);
20392
19495
  }
20393
- function selectPortalSpec(renderedSet, portalId) {
20394
- const hit = renderedSet.find((spec) => spec.portalId === portalId);
20395
- if (!hit) {
20396
- const known = renderedSet.map((s) => s.portalId).join(", ");
20397
- throw new Error(`Unknown portal "${portalId}" \u2014 this surface renders: ${known || "(no portals)"}.`);
20398
- }
20399
- return [hit];
20400
- }
20401
- function perPortalPath(resolvedOut, portalId) {
20402
- const ext = path13.extname(resolvedOut);
20403
- const stem = ext ? resolvedOut.slice(0, -ext.length) : resolvedOut;
20404
- return `${stem}.${safeFilenamePart(portalId)}${ext}`;
20405
- }
20406
- function writeSurfaceFile(outPath, snapshot, renderedSet) {
20407
- const resolved = path13.resolve(outPath);
20408
- fs11.mkdirSync(path13.dirname(resolved), { recursive: true });
20409
- if (!renderedSet || renderedSet.length === 0) {
20410
- writeYamlFile(resolved, snapshot);
20411
- return [resolved];
20412
- }
20413
- if (renderedSet.length === 1) {
20414
- fs11.writeFileSync(resolved, renderedSet[0].document);
20415
- return [resolved];
20416
- }
20417
- return renderedSet.map((spec) => {
20418
- const target = perPortalPath(resolved, spec.portalId);
20419
- fs11.writeFileSync(target, spec.document);
20420
- return target;
20421
- });
20422
- }
20423
- function exportResult(snapshot, renderedSet, writtenPaths) {
20424
- const rendered = renderedSet?.length === 1 ? renderedSet[0].document : void 0;
20425
- return {
20426
- snapshot,
20427
- ...rendered !== void 0 ? { rendered } : {},
20428
- ...renderedSet ? { renderedSet } : {},
20429
- ...writtenPaths.length === 1 ? { writtenTo: writtenPaths[0] } : {},
20430
- ...writtenPaths.length ? { writtenPaths } : {}
20431
- };
20432
- }
20433
- function exportSurface(maxAudience, format, outPath, portalId) {
20434
- const snapshot = projectOwnSurface(maxAudience);
20435
- let renderedSet = format === "openapi" ? toOpenApiSet(snapshot) : void 0;
20436
- if (renderedSet && portalId) renderedSet = selectPortalSpec(renderedSet, portalId);
20437
- const writtenPaths = outPath ? writeSurfaceFile(outPath, snapshot, renderedSet) : [];
20438
- return exportResult(snapshot, renderedSet, writtenPaths);
20439
- }
20440
- function importSurface(sourcePath, origin) {
20441
- const resolved = path13.resolve(sourcePath);
20442
- if (!fs11.existsSync(resolved)) {
20443
- throw new Error(`Surface document not found: ${resolved}`);
20444
- }
20445
- const body = fs11.readFileSync(resolved, "utf8");
20446
- let snapshot;
20447
- if (isOpenApiDocument(body)) {
20448
- const projectName = path13.basename(resolved).replace(/\.(json|ya?ml)$/i, "");
20449
- snapshot = fromOpenApi(body, projectName);
20450
- snapshot = { ...snapshot, origin };
20451
- } else {
20452
- snapshot = SurfaceSnapshotSchema.parse(readYamlFile(resolved));
20453
- snapshot = { ...snapshot, origin };
20454
- }
20455
- saveSnapshot(snapshot);
20456
- return snapshot;
20457
- }
20458
- function projectFamilySurfaces(parent) {
20459
- return runWithProjectRoot(parent.parentRoot, () => {
20460
- invalidateSpecCache();
20461
- const siblings = loadSubsystemSpecs().filter((s) => !s.id.includes("::") && s.id !== parent.subsystemId);
20462
- return [projectChildSurface(), ...siblings.map((s) => projectSubsystemSurface(s.id))];
20463
- });
20464
- }
20465
- function pinFamilySurfaces() {
20466
- const parent = resolveChainingParent();
20467
- if (!parent) return null;
20468
- const childRoot = getProjectRoot();
20469
- const projected = projectFamilySurfaces(parent);
20470
- const before = new Map(listSnapshots(childRoot).map((s) => [s.projectName, surfaceContentKey(s)]));
20471
- const changed = [];
20472
- for (const snapshot of projected) {
20473
- const stored = saveSnapshot(snapshot, childRoot);
20474
- if (before.get(snapshot.projectName) !== surfaceContentKey(SurfaceSnapshotSchema.parse(snapshot))) {
20475
- changed.push(stored);
20476
- }
20477
- }
20478
- return changed;
20479
- }
20480
- function projectedFamilyContent(parent) {
20481
- try {
20482
- return new Map(projectFamilySurfaces(parent).map((s) => [s.projectName, surfaceContentKey(s)]));
20483
- } catch {
20484
- return null;
20485
- }
20486
- }
20487
- function listExternalInterfaces() {
20488
- const snapshots = listSnapshots();
20489
- const chainingParent = resolveChainingParent();
20490
- const projected = chainingParent ? projectedFamilyContent(chainingParent) : null;
20491
- return snapshots.map((snapshot) => {
20492
- const generated = snapshot.origin === "generated";
20493
- const sourceKind = !generated ? "foreign" : snapshot.projectName.includes("::") ? "sibling" : "parent";
20494
- const freshness = generated && projected ? projected.get(snapshot.projectName) === surfaceContentKey(snapshot) ? "fresh" : "stale" : "unverifiable";
20495
- return {
20496
- projectName: snapshot.projectName,
20497
- origin: snapshot.origin,
20498
- sourceKind,
20499
- generatedAt: snapshot.generatedAt,
20500
- ...snapshot.stateId ? { stateId: snapshot.stateId } : {},
20501
- ...snapshot.version ? { version: snapshot.version } : {},
20502
- freshness,
20503
- interfaceIds: snapshot.interfaces.map((e) => e.id)
20504
- };
20505
- });
20506
- }
20507
- function surfaceContentKey(snapshot) {
20508
- const { stateId, generatedAt, origin, ...content } = snapshot;
20509
- return JSON.stringify(content);
20510
- }
20511
19496
 
20512
19497
  // src/core/validation.ts
20513
19498
  var path14 = __toESM(require("path"));
20514
19499
  function loadProjectConfig2() {
20515
19500
  return loadProjectConfig();
20516
19501
  }
20517
- function computeStateId2() {
20518
- return computeStateId();
20519
- }
20520
- function consumedContractInputs2() {
20521
- return consumedContractInputs();
20522
- }
20523
19502
  function projectPackSelections() {
20524
19503
  try {
20525
19504
  return (loadProjectConfig2()?.extensions?.packs ?? []).filter((e) => typeof e !== "string");
@@ -20527,9 +19506,6 @@ function projectPackSelections() {
20527
19506
  return [];
20528
19507
  }
20529
19508
  }
20530
- function findTestsReferencing2(methods, projectRoot, testRoots = []) {
20531
- return findTestsReferencing(methods, projectRoot, testRoots);
20532
- }
20533
19509
  var RESOLUTION_FAILURE_CODES = /* @__PURE__ */ new Set([
20534
19510
  "UNDEFINED_TYPE_REFERENCE",
20535
19511
  "INVALID_DEPENDENCY_REFERENCE",
@@ -20568,90 +19544,6 @@ function stricterSeverities(parent, child) {
20568
19544
  function issue(severity, code, message, agentId, specId) {
20569
19545
  return { severity, code, message, agentId, specId };
20570
19546
  }
20571
- function validateRegistry(registry, rules) {
20572
- const issues = [];
20573
- const idCounts = /* @__PURE__ */ new Map();
20574
- for (const agent of registry.agents) {
20575
- idCounts.set(agent.id, (idCounts.get(agent.id) ?? 0) + 1);
20576
- }
20577
- for (const [id, count] of idCounts) {
20578
- if (count > 1) {
20579
- issues.push(issue("error", "DUPLICATE_AGENT_ID", `Duplicate agent id: "${id}"`, id));
20580
- }
20581
- }
20582
- for (const agent of registry.agents) {
20583
- validateAgent(agent, rules, issues);
20584
- }
20585
- if (rules.noOverlappingOwnership) {
20586
- checkOverlappingOwnership(registry.agents, issues);
20587
- }
20588
- return {
20589
- valid: issues.every((i) => i.severity !== "error"),
20590
- issues
20591
- };
20592
- }
20593
- function validateAgent(agent, rules, issues) {
20594
- const isMeta = agent.tags.some((t) => rules.metaAgentTags.includes(t));
20595
- if (rules.requireOwnedPaths && !isMeta && agent.ownedPaths.length === 0) {
20596
- issues.push(
20597
- issue(
20598
- "warning",
20599
- "NO_OWNED_PATHS",
20600
- `Agent "${agent.id}" has no ownedPaths. Add paths or tag as meta/guardian.`,
20601
- agent.id
20602
- )
20603
- );
20604
- }
20605
- if (agent.targets.length === 0) {
20606
- issues.push(
20607
- issue("warning", "NO_TARGETS", `Agent "${agent.id}" has no output targets configured.`, agent.id)
20608
- );
20609
- }
20610
- }
20611
- function checkOverlappingOwnership(agents, issues) {
20612
- const pathToAgents = /* @__PURE__ */ new Map();
20613
- for (const agent of agents) {
20614
- for (const p of agent.ownedPaths) {
20615
- const owners = pathToAgents.get(p) ?? [];
20616
- owners.push(agent.id);
20617
- pathToAgents.set(p, owners);
20618
- }
20619
- }
20620
- for (const [p, owners] of pathToAgents) {
20621
- if (owners.length > 1) {
20622
- issues.push(
20623
- issue(
20624
- "error",
20625
- "OVERLAPPING_OWNERSHIP",
20626
- `Path "${p}" is claimed by multiple agents: ${owners.join(", ")}`
20627
- )
20628
- );
20629
- }
20630
- }
20631
- }
20632
- function validateProjectConfig(config) {
20633
- const issues = [];
20634
- if (config.targets.length === 0) {
20635
- issues.push(issue("error", "NO_TARGETS", "No output targets configured in project.yaml"));
20636
- }
20637
- const enabled = config.targets.filter((t) => {
20638
- if (typeof t === "string") return true;
20639
- return t.enabled !== false;
20640
- });
20641
- if (enabled.length === 0) {
20642
- issues.push(issue("error", "NO_ENABLED_TARGETS", "All configured targets are disabled"));
20643
- }
20644
- return {
20645
- valid: issues.every((i) => i.severity !== "error"),
20646
- issues
20647
- };
20648
- }
20649
- function listRules2() {
20650
- const extensions = loadProjectExtensions();
20651
- registerBuiltinRules();
20652
- registerPackRules(extensions.rules);
20653
- return ruleSequence();
20654
- }
20655
19547
  function validateSddTree(rulesOrOptions, projectType = "backend") {
20656
19548
  let rules = rulesOrOptions;
20657
19549
  let scopeSubsystem;
@@ -20889,22 +19781,6 @@ function settledStatusBearing(loaded) {
20889
19781
  take(loaded.implementations, index.paths.implementation);
20890
19782
  return out;
20891
19783
  }
20892
- function validateAsComplete(options) {
20893
- return validateSddTree({ ...options ?? {}, treatAllAsComplete: true });
20894
- }
20895
- function computeGateStateId() {
20896
- const content = computeStateId2();
20897
- const extensions = loadProjectExtensions();
20898
- let gate = {};
20899
- try {
20900
- const config = loadProjectConfig2();
20901
- if (config) gate = { projectType: config.projectType, rules: config.rules };
20902
- } catch {
20903
- }
20904
- const inputs = consumedContractInputs2();
20905
- registerBuiltinRules();
20906
- return computeGateIdentity(content, extensions, ruleSequence(), inputs, gate);
20907
- }
20908
19784
 
20909
19785
  // src/core/diagram.ts
20910
19786
  function renderDiagram(format) {
@@ -22050,13 +20926,13 @@ function ineffectiveDeltaPaths(delta, merged, stored) {
22050
20926
  const isPlain = (v) => typeof v === "object" && v !== null && !Array.isArray(v);
22051
20927
  const same = (a, b) => JSON.stringify(a) === JSON.stringify(b);
22052
20928
  const at = (prefix, key) => prefix ? `${prefix}.${key}` : key;
22053
- const say = (path29, why) => {
22054
- out.push(`${path29} \u2014 ${why}`);
20929
+ const say = (path28, why) => {
20930
+ out.push(`${path28} \u2014 ${why}`);
22055
20931
  };
22056
- const walkValue = (d, m, s, path29, field) => {
20932
+ const walkValue = (d, m, s, path28, field) => {
22057
20933
  if (Array.isArray(d)) {
22058
20934
  if (!Array.isArray(m)) {
22059
- say(path29, "the level does not have this field, so the write dropped it");
20935
+ say(path28, "the level does not have this field, so the write dropped it");
22060
20936
  return;
22061
20937
  }
22062
20938
  if (field === "narrative" && d.some(carriesEditMarker)) return;
@@ -22064,32 +20940,32 @@ function ineffectiveDeltaPaths(delta, merged, stored) {
22064
20940
  if (carriesEditMarker(element)) continue;
22065
20941
  const key = reportIdentityOf(field, element);
22066
20942
  if (key === null) {
22067
- if (!same(m, d)) say(path29, "the level does not keep this value, so the write dropped it");
22068
- else if (same(s, d)) say(path29, "the stored spec already held this value");
20943
+ if (!same(m, d)) say(path28, "the level does not keep this value, so the write dropped it");
20944
+ else if (same(s, d)) say(path28, "the stored spec already held this value");
22069
20945
  return;
22070
20946
  }
22071
20947
  const mMatch = m.find((i) => reportIdentityOf(field, i) === key);
22072
20948
  const sMatch = Array.isArray(s) ? s.find((i) => reportIdentityOf(field, i) === key) : void 0;
22073
20949
  if (mMatch === void 0) {
22074
- say(at(path29, key), "the write did not store this element");
20950
+ say(at(path28, key), "the write did not store this element");
22075
20951
  continue;
22076
20952
  }
22077
- walk2(element, mMatch, sMatch, at(path29, key), field);
20953
+ walk2(element, mMatch, sMatch, at(path28, key), field);
22078
20954
  }
22079
20955
  return;
22080
20956
  }
22081
20957
  if (isPlain(d)) {
22082
20958
  if (!isPlain(m)) {
22083
- say(path29, "the level does not have this field, so the write dropped it");
20959
+ say(path28, "the level does not have this field, so the write dropped it");
22084
20960
  return;
22085
20961
  }
22086
- walk2(d, m, s, path29, field);
20962
+ walk2(d, m, s, path28, field);
22087
20963
  return;
22088
20964
  }
22089
- if (!same(m, d)) say(path29, "the write did not store it \u2014 the level's schema does not keep this value");
22090
- else if (same(s, d)) say(path29, "the stored spec already held this value");
20965
+ if (!same(m, d)) say(path28, "the write did not store it \u2014 the level's schema does not keep this value");
20966
+ else if (same(s, d)) say(path28, "the stored spec already held this value");
22091
20967
  };
22092
- function walk2(d, m, s, path29, container) {
20968
+ function walk2(d, m, s, path28, container) {
22093
20969
  for (const [key, value] of Object.entries(d)) {
22094
20970
  if (DELTA_VERBS.has(key) || JUMP_LABEL_TWINS.has(key)) continue;
22095
20971
  if (key === "label" && LABEL_TWIN_CONTAINERS.has(container)) continue;
@@ -22099,13 +20975,13 @@ function ineffectiveDeltaPaths(delta, merged, stored) {
22099
20975
  if (typeof name !== "string") continue;
22100
20976
  const had = isPlain(s) && s[name] !== void 0;
22101
20977
  const still = isPlain(m) && m[name] !== void 0;
22102
- if (!had) say(at(path29, name), "unset named a field the stored spec did not have");
22103
- else if (still) say(at(path29, name), "unset did not remove it");
20978
+ if (!had) say(at(path28, name), "unset named a field the stored spec did not have");
20979
+ else if (still) say(at(path28, name), "unset did not remove it");
22104
20980
  }
22105
20981
  continue;
22106
20982
  }
22107
20983
  if (value === void 0 || value === null) continue;
22108
- const here = at(path29, key);
20984
+ const here = at(path28, key);
22109
20985
  const mValue = isPlain(m) ? m[key] : void 0;
22110
20986
  const sValue = isPlain(s) ? s[key] : void 0;
22111
20987
  if (mValue === void 0) {
@@ -24444,9 +23320,6 @@ function scanAllSpecs(options) {
24444
23320
  function resolveSubprojectForNamespace(namespace) {
24445
23321
  return current().resolveSubprojectForNamespace(namespace);
24446
23322
  }
24447
- function getSubprojectPrefix(qualifiedId) {
24448
- return current().getSubprojectPrefix(qualifiedId);
24449
- }
24450
23323
  function getSubsystemPath(id) {
24451
23324
  return current().getSubsystemPath(id);
24452
23325
  }
@@ -24459,12 +23332,6 @@ function getInterfacePath(id, componentId) {
24459
23332
  function getImplementationPath(id, contractId) {
24460
23333
  return current().getImplementationPath(id, contractId);
24461
23334
  }
24462
- function getTypePath(id, subsystemId, group) {
24463
- return current().getTypePath(id, subsystemId, group);
24464
- }
24465
- function getGroupPath(id, subsystemId) {
24466
- return current().getGroupPath(id, subsystemId);
24467
- }
24468
23335
  function loadSystemSpec() {
24469
23336
  return current().loadSystemSpec();
24470
23337
  }
@@ -24495,9 +23362,6 @@ function saveComponentSpec(spec, opts) {
24495
23362
  function deleteComponentSpec(id) {
24496
23363
  return current().deleteComponentSpec(id);
24497
23364
  }
24498
- function normalizeComponentLayout() {
24499
- return current().normalizeComponentLayout();
24500
- }
24501
23365
  function loadInterfaceSpecs() {
24502
23366
  return current().loadInterfaceSpecs();
24503
23367
  }
@@ -24609,38 +23473,12 @@ function computeStateIdAt(root) {
24609
23473
  function deleteTypeSpec(id) {
24610
23474
  return current().deleteTypeSpec(id);
24611
23475
  }
24612
- function loadGroupSpecs() {
24613
- return current().loadGroupSpecs();
24614
- }
24615
- function loadGroupSpec(id) {
24616
- return current().loadGroupSpec(id);
24617
- }
24618
- function saveGroupSpec(spec) {
24619
- current().saveGroupSpec(spec);
24620
- }
24621
- function deleteGroupSpec(id) {
24622
- return current().deleteGroupSpec(id);
24623
- }
24624
- function collectPromotableSpecs(scopeSubsystem) {
24625
- return current().collectPromotableSpecs(scopeSubsystem);
24626
- }
24627
- function applySpecStatus(kind, id, status) {
24628
- current().applySpecStatus(kind, id, status);
24629
- }
24630
23476
  function specPathsInScope(scopeSubsystem) {
24631
23477
  return current().specPathsInScope(scopeSubsystem);
24632
23478
  }
24633
23479
  function snapshotSpecFiles() {
24634
23480
  return current().snapshotSpecFiles();
24635
23481
  }
24636
- function restoreSpecFiles(snapshot) {
24637
- for (const [file, content] of snapshot) {
24638
- fs12.writeFileSync(file, content);
24639
- }
24640
- }
24641
- function findLegacySpecFiles() {
24642
- return current().findLegacySpecFiles();
24643
- }
24644
23482
  function updateSpec(kind, id, delta, hooks, dryRun) {
24645
23483
  return current().updateSpec(kind, id, delta, hooks, dryRun);
24646
23484
  }
@@ -24734,219 +23572,9 @@ function unregisterDomain(id) {
24734
23572
  removeFreeStanding(id);
24735
23573
  }
24736
23574
 
24737
- // src/core/detection.ts
23575
+ // src/core/provision.ts
24738
23576
  var fs13 = __toESM(require("fs"));
24739
23577
  var path17 = __toESM(require("path"));
24740
- var PACKAGE_MARKERS = [
24741
- "package.json",
24742
- "pyproject.toml",
24743
- "Cargo.toml",
24744
- "go.mod",
24745
- "build.gradle",
24746
- "build.gradle.kts",
24747
- "pom.xml"
24748
- ];
24749
- var MAX_SCAN_DEPTH = 5;
24750
- function detectDomainCandidates(projectRoot, alreadyTrackedPaths = /* @__PURE__ */ new Set(), alreadyTrackedIds = /* @__PURE__ */ new Set()) {
24751
- const candidates = /* @__PURE__ */ new Map();
24752
- for (const c of detectGitSubmodules(projectRoot)) {
24753
- candidates.set(c.path, { ...c, alreadyTracked: alreadyTrackedPaths.has(c.path) });
24754
- }
24755
- for (const c of detectNestedGitRepos(projectRoot)) {
24756
- if (!candidates.has(c.path)) {
24757
- candidates.set(c.path, { ...c, alreadyTracked: alreadyTrackedPaths.has(c.path) });
24758
- }
24759
- }
24760
- const gitPaths = new Set(
24761
- Array.from(candidates.values()).filter((c) => c.type === "git-submodule" || c.type === "git-repo").map((c) => c.path)
24762
- );
24763
- for (const c of detectPackageRoots(projectRoot)) {
24764
- if (candidates.has(c.path)) continue;
24765
- const insideGit = Array.from(gitPaths).some(
24766
- (gp) => c.path === gp || c.path.startsWith(gp + "/")
24767
- );
24768
- if (insideGit) continue;
24769
- candidates.set(c.path, { ...c, alreadyTracked: alreadyTrackedPaths.has(c.path) });
24770
- }
24771
- const sorted = Array.from(candidates.values()).sort((a, b) => a.path.localeCompare(b.path));
24772
- return deduplicateIds(sorted, alreadyTrackedIds);
24773
- }
24774
- function deduplicateIds(candidates, existingIds = /* @__PURE__ */ new Set()) {
24775
- const idCount = /* @__PURE__ */ new Map();
24776
- for (const id of existingIds) {
24777
- idCount.set(id, (idCount.get(id) ?? 0) + 1);
24778
- }
24779
- for (const c of candidates) {
24780
- idCount.set(c.suggestedId, (idCount.get(c.suggestedId) ?? 0) + 1);
24781
- }
24782
- return candidates.map((c) => {
24783
- if ((idCount.get(c.suggestedId) ?? 0) <= 1) return c;
24784
- const parts = c.path.split("/");
24785
- const qualifiedId = parts.length >= 2 ? pathToId(`${parts[parts.length - 2]}-${parts[parts.length - 1]}`) : c.suggestedId;
24786
- return { ...c, suggestedId: qualifiedId };
24787
- });
24788
- }
24789
- function parseGitmodules(filePath) {
24790
- const content = fs13.readFileSync(filePath, "utf-8");
24791
- const entries = [];
24792
- let current2 = {};
24793
- for (const line of content.split("\n")) {
24794
- const trimmed = line.trim();
24795
- const headerMatch = trimmed.match(/^\[submodule "(.+)"\]$/);
24796
- if (headerMatch) {
24797
- if (current2.path) entries.push(current2);
24798
- current2 = { name: headerMatch[1] };
24799
- continue;
24800
- }
24801
- const keyVal = trimmed.match(/^(\w+)\s*=\s*(.+)$/);
24802
- if (keyVal) {
24803
- const [, key, value] = keyVal;
24804
- if (key === "path") current2.path = value.trim();
24805
- if (key === "url") current2.url = value.trim();
24806
- }
24807
- }
24808
- if (current2.path) entries.push(current2);
24809
- return entries;
24810
- }
24811
- function detectGitSubmodules(projectRoot) {
24812
- const gitmodulesPath = path17.join(projectRoot, ".gitmodules");
24813
- if (!fs13.existsSync(gitmodulesPath)) return [];
24814
- return parseGitmodules(gitmodulesPath).map((entry) => ({
24815
- suggestedId: pathToId(entry.path),
24816
- suggestedName: pathToName(entry.path),
24817
- path: normalizePath(entry.path),
24818
- type: "git-submodule",
24819
- alreadyTracked: false
24820
- }));
24821
- }
24822
- function detectNestedGitRepos(projectRoot) {
24823
- const results = [];
24824
- walkForGit(projectRoot, projectRoot, 0, results);
24825
- return results;
24826
- }
24827
- function walkForGit(projectRoot, currentDir, depth, results) {
24828
- if (depth > MAX_SCAN_DEPTH) return;
24829
- let entries;
24830
- try {
24831
- entries = fs13.readdirSync(currentDir, { withFileTypes: true });
24832
- } catch {
24833
- return;
24834
- }
24835
- for (const entry of entries) {
24836
- if (!entry.isDirectory()) continue;
24837
- if (SCAN_EXCLUDE_DIRS.has(entry.name)) continue;
24838
- const fullPath = path17.join(currentDir, entry.name);
24839
- const relPath = normalizePath(path17.relative(projectRoot, fullPath));
24840
- if (relPath === "" || relPath === ".") continue;
24841
- const gitPath = path17.join(fullPath, ".git");
24842
- if (fs13.existsSync(gitPath)) {
24843
- results.push({
24844
- suggestedId: pathToId(relPath),
24845
- suggestedName: pathToName(relPath),
24846
- path: relPath,
24847
- type: "git-repo",
24848
- alreadyTracked: false
24849
- });
24850
- continue;
24851
- }
24852
- walkForGit(projectRoot, fullPath, depth + 1, results);
24853
- }
24854
- }
24855
- function detectPackageRoots(projectRoot) {
24856
- const results = [];
24857
- walkForPackages(projectRoot, projectRoot, 0, results);
24858
- return results;
24859
- }
24860
- function walkForPackages(projectRoot, currentDir, depth, results) {
24861
- if (depth > MAX_SCAN_DEPTH) return;
24862
- let entries;
24863
- try {
24864
- entries = fs13.readdirSync(currentDir, { withFileTypes: true });
24865
- } catch {
24866
- return;
24867
- }
24868
- for (const entry of entries) {
24869
- if (!entry.isDirectory()) continue;
24870
- if (SCAN_EXCLUDE_DIRS.has(entry.name)) continue;
24871
- const fullPath = path17.join(currentDir, entry.name);
24872
- const relPath = normalizePath(path17.relative(projectRoot, fullPath));
24873
- if (relPath === "" || relPath === ".") continue;
24874
- const hasMarker = PACKAGE_MARKERS.some((m) => fs13.existsSync(path17.join(fullPath, m)));
24875
- if (hasMarker) {
24876
- results.push({
24877
- suggestedId: pathToId(relPath),
24878
- suggestedName: pathToName(relPath),
24879
- path: relPath,
24880
- type: "package-root",
24881
- alreadyTracked: false
24882
- });
24883
- }
24884
- walkForPackages(projectRoot, fullPath, depth + 1, results);
24885
- }
24886
- }
24887
- function pathToId(relPath) {
24888
- const basename11 = path17.basename(relPath);
24889
- return basename11.toLowerCase().replace(/[^a-z0-9-]/g, "-").replace(/-+/g, "-").replace(/^-|-$/g, "");
24890
- }
24891
- function pathToName(relPath) {
24892
- const id = pathToId(relPath);
24893
- return id.split("-").map((w) => w.charAt(0).toUpperCase() + w.slice(1)).join(" ");
24894
- }
24895
- function normalizePath(p) {
24896
- return p.replace(/\\/g, "/");
24897
- }
24898
-
24899
- // src/core/templates.ts
24900
- var path18 = __toESM(require("path"));
24901
- function builtinTemplatesDir() {
24902
- return path18.resolve(__dirname, "..", "templates");
24903
- }
24904
- function loadTemplate(id, globalOverride) {
24905
- const dirs = templateSearchDirs(globalOverride);
24906
- for (const dir of dirs) {
24907
- const filePath = path18.join(dir, `${id}.yaml`);
24908
- if (pathExists(filePath)) {
24909
- const raw = readYamlFile(filePath);
24910
- return { ...TemplateSchema.parse(raw), templateName: id };
24911
- }
24912
- }
24913
- throw new TemplateNotFoundError(id);
24914
- }
24915
- function loadAgentOverride(agentId) {
24916
- const filePath = path18.join(AI_PATHS.root(), "agents", `${agentId}.md`);
24917
- return readFileOrNull(filePath);
24918
- }
24919
- function listTemplateIds(globalOverride) {
24920
- const seen = /* @__PURE__ */ new Set();
24921
- for (const dir of templateSearchDirs(globalOverride)) {
24922
- for (const file of listFiles(dir, ".yaml")) {
24923
- seen.add(path18.basename(file, ".yaml"));
24924
- }
24925
- }
24926
- return Array.from(seen).sort();
24927
- }
24928
- function templateSearchDirs(globalOverride) {
24929
- return [
24930
- AI_PATHS.templatesDir(),
24931
- // 1. project-local
24932
- globalTemplatesDir(globalOverride),
24933
- // 2. global user/org
24934
- builtinTemplatesDir()
24935
- // 3. built-in fallback
24936
- ];
24937
- }
24938
- function renderTemplateInstructions(template, vars) {
24939
- return template.instructions.replace(/\{\{(\w+)\}\}/g, (_match, key) => {
24940
- return key in vars ? vars[key] : `{{${key}}}`;
24941
- });
24942
- }
24943
- function parseTemplate(yamlContent) {
24944
- return TemplateSchema.parse(parseYaml(yamlContent));
24945
- }
24946
-
24947
- // src/core/provision.ts
24948
- var fs14 = __toESM(require("fs"));
24949
- var path19 = __toESM(require("path"));
24950
23578
  function defaultProjectConfig(name, now) {
24951
23579
  return {
24952
23580
  schemaVersion: "1.0.0",
@@ -24994,7 +23622,7 @@ function provisionProject(name) {
24994
23622
  function ensureProjectInitialized(fallbackName) {
24995
23623
  const now = (/* @__PURE__ */ new Date()).toISOString();
24996
23624
  const paths = aiPathsAt(getProjectRoot());
24997
- const hasSystem = fs14.existsSync(paths.specsSystem());
23625
+ const hasSystem = fs13.existsSync(paths.specsSystem());
24998
23626
  let name = fallbackName;
24999
23627
  if (hasSystem) {
25000
23628
  const existing = loadSystemSpec();
@@ -25013,41 +23641,10 @@ function ensureProjectInitialized(fallbackName) {
25013
23641
  if (wroteConfig || wroteSystem) invalidateSpecCache();
25014
23642
  return { wroteConfig, wroteSystem };
25015
23643
  }
25016
- function walkChainedSubprojects(projectRoot, onChild) {
25017
- const visited = /* @__PURE__ */ new Set();
25018
- const walk2 = (dir) => {
25019
- const resolved = path19.resolve(dir);
25020
- if (visited.has(resolved)) return;
25021
- visited.add(resolved);
25022
- const specsDir = aiPathsAt(dir).specsDir();
25023
- if (!fs14.existsSync(specsDir)) return;
25024
- for (const file of listFilesRecursive(specsDir, ".yaml")) {
25025
- let raw;
25026
- try {
25027
- raw = readYamlFile(file);
25028
- } catch {
25029
- continue;
25030
- }
25031
- if (!(raw && typeof raw === "object" && "parentSystem" in raw)) continue;
25032
- const pp = raw.projectPath;
25033
- if (typeof pp !== "string" || pp.trim() === "") continue;
25034
- let childDir;
25035
- try {
25036
- childDir = assertContainedProjectPath(dir, pp);
25037
- } catch {
25038
- continue;
25039
- }
25040
- const id = raw.id;
25041
- onChild(childDir, typeof id === "string" ? id : path19.basename(childDir));
25042
- walk2(childDir);
25043
- }
25044
- };
25045
- walk2(projectRoot);
25046
- }
25047
23644
  function listDirectChainedSubprojects(projectRoot) {
25048
23645
  const out = [];
25049
23646
  const specsDir = aiPathsAt(projectRoot).specsDir();
25050
- if (!fs14.existsSync(specsDir)) return out;
23647
+ if (!fs13.existsSync(specsDir)) return out;
25051
23648
  for (const file of listFilesRecursive(specsDir, ".yaml")) {
25052
23649
  let raw;
25053
23650
  try {
@@ -25065,32 +23662,10 @@ function listDirectChainedSubprojects(projectRoot) {
25065
23662
  continue;
25066
23663
  }
25067
23664
  const id = raw.id;
25068
- out.push({ dir, subsystemId: typeof id === "string" ? id : path19.basename(dir) });
23665
+ out.push({ dir, subsystemId: typeof id === "string" ? id : path17.basename(dir) });
25069
23666
  }
25070
23667
  return out;
25071
23668
  }
25072
- function childHasSpecsButNoConfig(childDir) {
25073
- return fs14.existsSync(aiPathsAt(childDir).specsDir()) && !projectConfigRepositoryAt(childDir).exists();
25074
- }
25075
- function findChainingSubprojectsMissingConfig(projectRoot) {
25076
- const missing = [];
25077
- walkChainedSubprojects(projectRoot, (childDir) => {
25078
- if (childHasSpecsButNoConfig(childDir)) missing.push(childDir);
25079
- });
25080
- return missing;
25081
- }
25082
- function backfillChainedSubprojectConfigs(projectRoot) {
25083
- const backfilled = [];
25084
- walkChainedSubprojects(projectRoot, (childDir, subsystemId) => {
25085
- if (childHasSpecsButNoConfig(childDir)) {
25086
- runWithProjectRoot(childDir, () => {
25087
- ensureProjectInitialized(subsystemId);
25088
- });
25089
- backfilled.push(childDir);
25090
- }
25091
- });
25092
- return backfilled;
25093
- }
25094
23669
  function createChainedSubsystem(subsystem, projectName) {
25095
23670
  if (!subsystem.projectPath || subsystem.projectPath.trim() === "") {
25096
23671
  throw new WaironError("projectPath is required to create a chained subsystem.");
@@ -25119,14 +23694,14 @@ function moveSubsystemProject(subsystemId, newProjectPath) {
25119
23694
  const oldDir = assertContainedProjectPath(root, sub.projectPath);
25120
23695
  const newDir = assertContainedProjectPath(root, nextPath);
25121
23696
  if (oldDir !== newDir) {
25122
- if (!fs14.existsSync(oldDir)) {
23697
+ if (!fs13.existsSync(oldDir)) {
25123
23698
  throw new WaironError(`Subproject directory not found at its current path: ${oldDir}`);
25124
23699
  }
25125
- if (fs14.existsSync(newDir)) {
23700
+ if (fs13.existsSync(newDir)) {
25126
23701
  throw new WaironError(`Target directory already exists: ${newDir}`);
25127
23702
  }
25128
- ensureDir(path19.dirname(newDir));
25129
- fs14.renameSync(oldDir, newDir);
23703
+ ensureDir(path17.dirname(newDir));
23704
+ fs13.renameSync(oldDir, newDir);
25130
23705
  }
25131
23706
  saveSubsystemSpec({ ...sub, projectPath: nextPath, updatedAt: (/* @__PURE__ */ new Date()).toISOString() });
25132
23707
  invalidateSpecCache();
@@ -25135,9 +23710,9 @@ function toPosixPath(p) {
25135
23710
  return p.replace(/\\/g, "/");
25136
23711
  }
25137
23712
  function isWithinDir(dir, file) {
25138
- const d = path19.resolve(dir);
25139
- const f = path19.resolve(file);
25140
- return f === d || f.startsWith(d + path19.sep);
23713
+ const d = path17.resolve(dir);
23714
+ const f = path17.resolve(file);
23715
+ return f === d || f.startsWith(d + path17.sep);
25141
23716
  }
25142
23717
  function externalizeSubsystem(subsystemId, projectPath) {
25143
23718
  if (subsystemId.includes("::")) {
@@ -25149,14 +23724,14 @@ function externalizeSubsystem(subsystemId, projectPath) {
25149
23724
  }
25150
23725
  const parentRoot = getProjectRoot();
25151
23726
  const parentSpecsDir = aiPathsAt(parentRoot).specsDir();
25152
- const fooDir = path19.join(parentSpecsDir, subsystemId);
25153
- if (!fs14.existsSync(fooDir)) {
23727
+ const fooDir = path17.join(parentSpecsDir, subsystemId);
23728
+ if (!fs13.existsSync(fooDir)) {
25154
23729
  throw new WaironError(`subsystem specs directory not found: ${fooDir}`);
25155
23730
  }
25156
23731
  const relPath = toPosixPath(projectPath);
25157
23732
  const childDir = assertContainedProjectPath(parentRoot, relPath);
25158
- const childFooDir = path19.join(childDir, ".wai", "specs", subsystemId);
25159
- if (fs14.existsSync(childFooDir)) {
23733
+ const childFooDir = path17.join(childDir, ".wai", "specs", subsystemId);
23734
+ if (fs13.existsSync(childFooDir)) {
25160
23735
  throw new WaironError(`target already contains a "${subsystemId}" subsystem: ${childFooDir}`);
25161
23736
  }
25162
23737
  const renameMap = buildRenameMap(
@@ -25168,18 +23743,18 @@ function externalizeSubsystem(subsystemId, projectPath) {
25168
23743
  runWithProjectRoot(childDir, () => {
25169
23744
  const now = (/* @__PURE__ */ new Date()).toISOString();
25170
23745
  projectConfigRepository.create(defaultProjectConfig(childSystemName, now));
25171
- ensureDir(path19.join(childDir, ".wai", "specs"));
23746
+ ensureDir(path17.join(childDir, ".wai", "specs"));
25172
23747
  saveSystemSpec(bootstrapSystemSpec(childSystemName, now));
25173
23748
  });
25174
- ensureDir(path19.dirname(childFooDir));
25175
- fs14.renameSync(fooDir, childFooDir);
23749
+ ensureDir(path17.dirname(childFooDir));
23750
+ fs13.renameSync(fooDir, childFooDir);
25176
23751
  rebaseImplementationPaths(childFooDir, parentRoot, childDir);
25177
- patchSubsystemIndex(path19.join(childFooDir, ".index.yaml"), (s) => {
23752
+ patchSubsystemIndex(path17.join(childFooDir, ".index.yaml"), (s) => {
25178
23753
  s.parentSystem = childSystemName;
25179
23754
  delete s.projectPath;
25180
23755
  });
25181
23756
  ensureDir(fooDir);
25182
- writeYamlFile(path19.join(fooDir, ".index.yaml"), {
23757
+ writeYamlFile(path17.join(fooDir, ".index.yaml"), {
25183
23758
  id: subsystemId,
25184
23759
  name: foo.name,
25185
23760
  description: foo.description,
@@ -25206,9 +23781,9 @@ function internalizeSubsystem(subsystemId) {
25206
23781
  const parentRoot = getProjectRoot();
25207
23782
  const parentSpecsDir = aiPathsAt(parentRoot).specsDir();
25208
23783
  const childDir = assertContainedProjectPath(parentRoot, foo.projectPath);
25209
- const childWai = path19.join(childDir, ".wai");
25210
- const childFooDir = path19.join(childDir, ".wai", "specs", subsystemId);
25211
- if (!fs14.existsSync(childFooDir)) {
23784
+ const childWai = path17.join(childDir, ".wai");
23785
+ const childFooDir = path17.join(childDir, ".wai", "specs", subsystemId);
23786
+ if (!fs13.existsSync(childFooDir)) {
25212
23787
  throw new WaironError(`external subproject missing subsystem "${subsystemId}": ${childFooDir}`);
25213
23788
  }
25214
23789
  const childOwnSubs = runWithProjectRoot(childDir, () => loadSubsystemSpecs()).filter((s) => !s.id.includes("::"));
@@ -25221,16 +23796,16 @@ function internalizeSubsystem(subsystemId) {
25221
23796
  false
25222
23797
  );
25223
23798
  const parentSystemName = loadSystemSpec()?.name ?? foo.parentSystem;
25224
- const fooDir = path19.join(parentSpecsDir, subsystemId);
25225
- fs14.rmSync(fooDir, { recursive: true, force: true });
25226
- ensureDir(path19.dirname(fooDir));
25227
- fs14.renameSync(childFooDir, fooDir);
23799
+ const fooDir = path17.join(parentSpecsDir, subsystemId);
23800
+ fs13.rmSync(fooDir, { recursive: true, force: true });
23801
+ ensureDir(path17.dirname(fooDir));
23802
+ fs13.renameSync(childFooDir, fooDir);
25228
23803
  rebaseImplementationPaths(fooDir, childDir, parentRoot);
25229
- patchSubsystemIndex(path19.join(fooDir, ".index.yaml"), (s) => {
23804
+ patchSubsystemIndex(path17.join(fooDir, ".index.yaml"), (s) => {
25230
23805
  s.parentSystem = parentSystemName;
25231
23806
  delete s.projectPath;
25232
23807
  });
25233
- fs14.rmSync(childWai, { recursive: true, force: true });
23808
+ fs13.rmSync(childWai, { recursive: true, force: true });
25234
23809
  rewriteRefsInDir(parentSpecsDir, renameMap, fooDir);
25235
23810
  rebaseMovedRefs(fooDir, subsystemId, "outOf");
25236
23811
  invalidateSpecCache();
@@ -25308,8 +23883,8 @@ function rebaseImplementationPaths(specsDir, fromRoot, toRoot) {
25308
23883
  let changed = false;
25309
23884
  const rebase = (holder, key) => {
25310
23885
  const p = holder[key];
25311
- if (typeof p !== "string" || p === "" || path19.isAbsolute(p)) return;
25312
- const next = toPosixPath(path19.relative(toRoot, path19.resolve(fromRoot, p)));
23886
+ if (typeof p !== "string" || p === "" || path17.isAbsolute(p)) return;
23887
+ const next = toPosixPath(path17.relative(toRoot, path17.resolve(fromRoot, p)));
25313
23888
  if (next !== p) {
25314
23889
  holder[key] = next;
25315
23890
  changed = true;
@@ -25325,7 +23900,7 @@ function rebaseImplementationPaths(specsDir, fromRoot, toRoot) {
25325
23900
  }
25326
23901
  }
25327
23902
  function patchSubsystemIndex(indexPath, mutate) {
25328
- if (!fs14.existsSync(indexPath)) return;
23903
+ if (!fs13.existsSync(indexPath)) return;
25329
23904
  const raw = readYamlFile(indexPath);
25330
23905
  mutate(raw);
25331
23906
  raw.updatedAt = (/* @__PURE__ */ new Date()).toISOString();
@@ -25386,8 +23961,8 @@ function moveRenamedSpecs(componentId, newId, component, movingInterface, moving
25386
23961
  if (movedInterface) saveInterfaceSpec({ ...movedInterface, id: interfaceId, component: newId });
25387
23962
  if (movedImplementation) {
25388
23963
  const oldFile = getImplementationPath(movedImplementation.id);
25389
- if (path19.resolve(getImplementationPath(implementationId, movedImplementation.contract)) === path19.resolve(oldFile)) {
25390
- fs14.unlinkSync(oldFile);
23964
+ if (path17.resolve(getImplementationPath(implementationId, movedImplementation.contract)) === path17.resolve(oldFile)) {
23965
+ fs13.unlinkSync(oldFile);
25391
23966
  }
25392
23967
  saveImplementationSpec({ ...movedImplementation, id: implementationId });
25393
23968
  }
@@ -25397,17 +23972,17 @@ function moveRenamedSpecs(componentId, newId, component, movingInterface, moving
25397
23972
  invalidateSpecCache();
25398
23973
  }
25399
23974
  function removeSpecFile2(file, id) {
25400
- if (!fs14.existsSync(file)) return;
23975
+ if (!fs13.existsSync(file)) return;
25401
23976
  try {
25402
23977
  if (readYamlFile(file)?.id !== id) return;
25403
23978
  } catch {
25404
23979
  return;
25405
23980
  }
25406
- fs14.unlinkSync(file);
25407
- const specsRoot = path19.resolve(aiPathsAt(getProjectRoot()).specsDir());
25408
- for (let dir = path19.dirname(path19.resolve(file)); dir !== specsRoot && isWithinDir(specsRoot, dir); dir = path19.dirname(dir)) {
25409
- if (fs14.readdirSync(dir).length > 0) break;
25410
- fs14.rmdirSync(dir);
23981
+ fs13.unlinkSync(file);
23982
+ const specsRoot = path17.resolve(aiPathsAt(getProjectRoot()).specsDir());
23983
+ for (let dir = path17.dirname(path17.resolve(file)); dir !== specsRoot && isWithinDir(specsRoot, dir); dir = path17.dirname(dir)) {
23984
+ if (fs13.readdirSync(dir).length > 0) break;
23985
+ fs13.rmdirSync(dir);
25411
23986
  }
25412
23987
  }
25413
23988
  var METHOD_NAME = /^[a-z][a-zA-Z0-9]*$/;
@@ -25517,10 +24092,208 @@ function identifierPattern(methodName) {
25517
24092
  return new RegExp(`(?<![A-Za-z0-9_])${methodName}(?![A-Za-z0-9_])`);
25518
24093
  }
25519
24094
 
24095
+ // src/core/detection.ts
24096
+ var fs14 = __toESM(require("fs"));
24097
+ var path18 = __toESM(require("path"));
24098
+ var PACKAGE_MARKERS = [
24099
+ "package.json",
24100
+ "pyproject.toml",
24101
+ "Cargo.toml",
24102
+ "go.mod",
24103
+ "build.gradle",
24104
+ "build.gradle.kts",
24105
+ "pom.xml"
24106
+ ];
24107
+ var MAX_SCAN_DEPTH = 5;
24108
+ function detectDomainCandidates(projectRoot, alreadyTrackedPaths = /* @__PURE__ */ new Set(), alreadyTrackedIds = /* @__PURE__ */ new Set()) {
24109
+ const candidates = /* @__PURE__ */ new Map();
24110
+ for (const c of detectGitSubmodules(projectRoot)) {
24111
+ candidates.set(c.path, { ...c, alreadyTracked: alreadyTrackedPaths.has(c.path) });
24112
+ }
24113
+ for (const c of detectNestedGitRepos(projectRoot)) {
24114
+ if (!candidates.has(c.path)) {
24115
+ candidates.set(c.path, { ...c, alreadyTracked: alreadyTrackedPaths.has(c.path) });
24116
+ }
24117
+ }
24118
+ const gitPaths = new Set(
24119
+ Array.from(candidates.values()).filter((c) => c.type === "git-submodule" || c.type === "git-repo").map((c) => c.path)
24120
+ );
24121
+ for (const c of detectPackageRoots(projectRoot)) {
24122
+ if (candidates.has(c.path)) continue;
24123
+ const insideGit = Array.from(gitPaths).some(
24124
+ (gp) => c.path === gp || c.path.startsWith(gp + "/")
24125
+ );
24126
+ if (insideGit) continue;
24127
+ candidates.set(c.path, { ...c, alreadyTracked: alreadyTrackedPaths.has(c.path) });
24128
+ }
24129
+ const sorted = Array.from(candidates.values()).sort((a, b) => a.path.localeCompare(b.path));
24130
+ return deduplicateIds(sorted, alreadyTrackedIds);
24131
+ }
24132
+ function deduplicateIds(candidates, existingIds = /* @__PURE__ */ new Set()) {
24133
+ const idCount = /* @__PURE__ */ new Map();
24134
+ for (const id of existingIds) {
24135
+ idCount.set(id, (idCount.get(id) ?? 0) + 1);
24136
+ }
24137
+ for (const c of candidates) {
24138
+ idCount.set(c.suggestedId, (idCount.get(c.suggestedId) ?? 0) + 1);
24139
+ }
24140
+ return candidates.map((c) => {
24141
+ if ((idCount.get(c.suggestedId) ?? 0) <= 1) return c;
24142
+ const parts = c.path.split("/");
24143
+ const qualifiedId = parts.length >= 2 ? pathToId(`${parts[parts.length - 2]}-${parts[parts.length - 1]}`) : c.suggestedId;
24144
+ return { ...c, suggestedId: qualifiedId };
24145
+ });
24146
+ }
24147
+ function parseGitmodules(filePath) {
24148
+ const content = fs14.readFileSync(filePath, "utf-8");
24149
+ const entries = [];
24150
+ let current2 = {};
24151
+ for (const line of content.split("\n")) {
24152
+ const trimmed = line.trim();
24153
+ const headerMatch = trimmed.match(/^\[submodule "(.+)"\]$/);
24154
+ if (headerMatch) {
24155
+ if (current2.path) entries.push(current2);
24156
+ current2 = { name: headerMatch[1] };
24157
+ continue;
24158
+ }
24159
+ const keyVal = trimmed.match(/^(\w+)\s*=\s*(.+)$/);
24160
+ if (keyVal) {
24161
+ const [, key, value] = keyVal;
24162
+ if (key === "path") current2.path = value.trim();
24163
+ if (key === "url") current2.url = value.trim();
24164
+ }
24165
+ }
24166
+ if (current2.path) entries.push(current2);
24167
+ return entries;
24168
+ }
24169
+ function detectGitSubmodules(projectRoot) {
24170
+ const gitmodulesPath = path18.join(projectRoot, ".gitmodules");
24171
+ if (!fs14.existsSync(gitmodulesPath)) return [];
24172
+ return parseGitmodules(gitmodulesPath).map((entry) => ({
24173
+ suggestedId: pathToId(entry.path),
24174
+ suggestedName: pathToName(entry.path),
24175
+ path: normalizePath(entry.path),
24176
+ type: "git-submodule",
24177
+ alreadyTracked: false
24178
+ }));
24179
+ }
24180
+ function detectNestedGitRepos(projectRoot) {
24181
+ const results = [];
24182
+ walkForGit(projectRoot, projectRoot, 0, results);
24183
+ return results;
24184
+ }
24185
+ function walkForGit(projectRoot, currentDir, depth, results) {
24186
+ if (depth > MAX_SCAN_DEPTH) return;
24187
+ let entries;
24188
+ try {
24189
+ entries = fs14.readdirSync(currentDir, { withFileTypes: true });
24190
+ } catch {
24191
+ return;
24192
+ }
24193
+ for (const entry of entries) {
24194
+ if (!entry.isDirectory()) continue;
24195
+ if (SCAN_EXCLUDE_DIRS.has(entry.name)) continue;
24196
+ const fullPath = path18.join(currentDir, entry.name);
24197
+ const relPath = normalizePath(path18.relative(projectRoot, fullPath));
24198
+ if (relPath === "" || relPath === ".") continue;
24199
+ const gitPath = path18.join(fullPath, ".git");
24200
+ if (fs14.existsSync(gitPath)) {
24201
+ results.push({
24202
+ suggestedId: pathToId(relPath),
24203
+ suggestedName: pathToName(relPath),
24204
+ path: relPath,
24205
+ type: "git-repo",
24206
+ alreadyTracked: false
24207
+ });
24208
+ continue;
24209
+ }
24210
+ walkForGit(projectRoot, fullPath, depth + 1, results);
24211
+ }
24212
+ }
24213
+ function detectPackageRoots(projectRoot) {
24214
+ const results = [];
24215
+ walkForPackages(projectRoot, projectRoot, 0, results);
24216
+ return results;
24217
+ }
24218
+ function walkForPackages(projectRoot, currentDir, depth, results) {
24219
+ if (depth > MAX_SCAN_DEPTH) return;
24220
+ let entries;
24221
+ try {
24222
+ entries = fs14.readdirSync(currentDir, { withFileTypes: true });
24223
+ } catch {
24224
+ return;
24225
+ }
24226
+ for (const entry of entries) {
24227
+ if (!entry.isDirectory()) continue;
24228
+ if (SCAN_EXCLUDE_DIRS.has(entry.name)) continue;
24229
+ const fullPath = path18.join(currentDir, entry.name);
24230
+ const relPath = normalizePath(path18.relative(projectRoot, fullPath));
24231
+ if (relPath === "" || relPath === ".") continue;
24232
+ const hasMarker = PACKAGE_MARKERS.some((m) => fs14.existsSync(path18.join(fullPath, m)));
24233
+ if (hasMarker) {
24234
+ results.push({
24235
+ suggestedId: pathToId(relPath),
24236
+ suggestedName: pathToName(relPath),
24237
+ path: relPath,
24238
+ type: "package-root",
24239
+ alreadyTracked: false
24240
+ });
24241
+ }
24242
+ walkForPackages(projectRoot, fullPath, depth + 1, results);
24243
+ }
24244
+ }
24245
+ function pathToId(relPath) {
24246
+ const basename11 = path18.basename(relPath);
24247
+ return basename11.toLowerCase().replace(/[^a-z0-9-]/g, "-").replace(/-+/g, "-").replace(/^-|-$/g, "");
24248
+ }
24249
+ function pathToName(relPath) {
24250
+ const id = pathToId(relPath);
24251
+ return id.split("-").map((w) => w.charAt(0).toUpperCase() + w.slice(1)).join(" ");
24252
+ }
24253
+ function normalizePath(p) {
24254
+ return p.replace(/\\/g, "/");
24255
+ }
24256
+
25520
24257
  // src/core/agent_resolver.ts
25521
24258
  var path20 = __toESM(require("path"));
25522
24259
  var fs15 = __toESM(require("fs"));
25523
24260
 
24261
+ // src/core/templates.ts
24262
+ var path19 = __toESM(require("path"));
24263
+ function builtinTemplatesDir() {
24264
+ return path19.resolve(__dirname, "..", "templates");
24265
+ }
24266
+ function loadTemplate(id, globalOverride) {
24267
+ const dirs = templateSearchDirs(globalOverride);
24268
+ for (const dir of dirs) {
24269
+ const filePath = path19.join(dir, `${id}.yaml`);
24270
+ if (pathExists(filePath)) {
24271
+ const raw = readYamlFile(filePath);
24272
+ return { ...TemplateSchema.parse(raw), templateName: id };
24273
+ }
24274
+ }
24275
+ throw new TemplateNotFoundError(id);
24276
+ }
24277
+ function loadAgentOverride(agentId) {
24278
+ const filePath = path19.join(AI_PATHS.root(), "agents", `${agentId}.md`);
24279
+ return readFileOrNull(filePath);
24280
+ }
24281
+ function templateSearchDirs(globalOverride) {
24282
+ return [
24283
+ AI_PATHS.templatesDir(),
24284
+ // 1. project-local
24285
+ globalTemplatesDir(globalOverride),
24286
+ // 2. global user/org
24287
+ builtinTemplatesDir()
24288
+ // 3. built-in fallback
24289
+ ];
24290
+ }
24291
+ function renderTemplateInstructions(template, vars) {
24292
+ return template.instructions.replace(/\{\{(\w+)\}\}/g, (_match, key) => {
24293
+ return key in vars ? vars[key] : `{{${key}}}`;
24294
+ });
24295
+ }
24296
+
25524
24297
  // src/core/execution_profile.ts
25525
24298
  var MECHANICAL_STEREOTYPES = /* @__PURE__ */ new Set(["store", "index", "registry", "adapter"]);
25526
24299
  var DEEP_STEREOTYPES = /* @__PURE__ */ new Set(["orchestrator", "supervisor", "specialist"]);
@@ -26032,514 +24805,50 @@ function loadRegistry() {
26032
24805
  };
26033
24806
  }
26034
24807
 
26035
- // src/core/skills.ts
26036
- var path21 = __toESM(require("path"));
26037
- var fs16 = __toESM(require("fs"));
24808
+ // src/exporters/generate.ts
24809
+ var path24 = __toESM(require("path"));
26038
24810
 
26039
- // src/core/instructions.ts
26040
- function governingProfile() {
26041
- try {
26042
- return loadProjectConfig3()?.projectType ?? null;
26043
- } catch {
26044
- return null;
26045
- }
26046
- }
26047
- function blockApplies(block, profile) {
26048
- if (!block.profile || block.profile.length === 0) return true;
26049
- return profile !== null && block.profile.includes(profile);
26050
- }
26051
- function skillPointers(skills) {
26052
- if (skills.length === 0) return "(none published by this server)";
26053
- return skills.map((s) => `- \`${s.resourceUri}\` \u2014 ${s.description || s.name}`).join("\n");
26054
- }
26055
- function waironInstructions(profile, packNames, skills, variants) {
26056
- return `# wairon \u2014 Spec-Driven Development (SDD)
26057
-
26058
- This server owns one system's **spec tree**: its architecture, specified top-down
26059
- and machine-checked. Author it ONLY through this server's \`sdd_*\` tools \u2014 never by
26060
- writing spec files directly, and never via the \`wairon\` CLI (that is the human
26061
- developer's tool).
26062
-
26063
- ## The tree: L0 \u2192 L5
26064
-
26065
- - **L0 System** \u2014 vision, boundaries, global requirements, target language.
26066
- - **L1 Subsystem** \u2014 an isolated service, its \`publicInterfaces\`, its trusted links.
26067
- - **L2 Component** \u2014 ONE building block (\`Portal\`, \`Orchestrator\`, \`Supervisor\`,
26068
- \`Actor\`, \`Store\`, \`Index\`, \`Query\`, \`Registry\`, \`Adapter\`, \`Observer\`, and
26069
- \`View\` for UIs) or pattern (\`Repository\`, and \`FeatureComponent\` or
26070
- \`RouterComponent\` for UIs), plus \`owns\` (a pattern's private members) and
26071
- \`dependsOn\` (collaborators). Logic is an \`Orchestrator\` whose \`dependencyClass\`
26072
- (\`pure\` or \`read\`; unset, a workflow) bounds what it may depend on; a gateway is
26073
- a \`Portal\` with the \`gateway\` variant. \`Specialist\` and \`Gateway\` are retired.
26074
- - **L3 Interface** \u2014 the contract: method signatures with structured \`params\`,
26075
- plus wire \`endpoint\` bindings for a Portal's methods.
26076
- - **L4 Implementation** \u2014 a concrete realization of one L3 contract: narrative
26077
- detail level, bound \`technologies\` (the vendor swap seam), optional \`sourcePath\`.
26078
- - **L5 Narrative** \u2014 each method's logic as a FLAT numbered step list; \`call\` steps
26079
- resolve to real dependency methods, and flow steps jump by step number.
26080
-
26081
- These stereotypes are not labels \u2014 they carry enforced dependency rules (e.g. a
26082
- Portal may not depend on a Store; state lives in a Store, never as fields inside
26083
- an Orchestrator). \`sdd_validate_tree\` is the gate, and it is the authority on
26084
- whether a design is legal.
26085
-
26086
- ## Authoring order
26087
-
26088
- 1. \`sdd_initialize_system\` (L0), then \`sdd_add_subsystem\` (L1).
26089
- 2. Then, **one subsystem at a time**: \`sdd_add_component\` (L2) \u2192 \`sdd_define_interface\`
26090
- (L3) \u2192 \`sdd_set_endpoints\` for Portals \u2192 \`sdd_write_narrative\` (L4+L5).
26091
- 3. Run \`sdd_validate_tree\` as you go \u2014 early and per subsystem, not once at the end.
26092
- \`sdd_get_status\` reports completeness; \`sdd_get_spec\` reads any spec back as JSON.
26093
- 4. Edit granularly with \`sdd_update_spec\` (it renumbers narrative steps and
26094
- relocates jump targets for you).
26095
-
26096
- ## The tool schemas are the field reference
26097
-
26098
- Every \`sdd_*\` tool's input schema is self-describing and authoritative \u2014 read the
26099
- schema rather than guessing field names, and prefer structured \`params\` over prose
26100
- signatures. Specs are ${profile === null ? "validated against the project's configured profile" : `governed by the **\`${profile}\`** profile`}, which decides which stereotypes are legal
26101
- here, which narrative flow constructs the target language supports, and which
26102
- extra rules apply. A subsystem may override the profile for itself.
26103
-
26104
- ## Loaded extension packs
26105
-
26106
- ${packNames.length === 0 ? "None \u2014 only wairon's built-in doctrine applies." : `${packNames.map((n) => `\`${n}\``).join(", ")} \u2014 these inject profiles, language tables, patterns, and
26107
- additional conformance rules. Their doctrine is enforced by the same gate.`}
26108
-
26109
- ${variants.length === 0 ? "" : `## Component variants in play
26110
-
26111
- This project defines variants \u2014 named, base-anchored kinds carrying implementation
26112
- guidance, so every component of the same kind is built alike: ${variants.map((v) => `\`${v.id}\` (a kind of ${v.base})`).join(", ")}.
26113
- Tag a component with \`variant\` where it fits, and read a component's resolved
26114
- guidance and its same-variant siblings from \`sdd_get_spec\` (kind: component).
26115
-
26116
- `}## Read the skills BEFORE authoring
26117
-
26118
- This server publishes its skills as MCP resources. **Read \`wairon-skill://sdd-architect\`
26119
- before you design anything**, and the others when their turn comes \u2014 they carry the
26120
- architecture standard, the narrative step reference, and the review checklist that
26121
- this briefing only points at:
26122
-
26123
- ${skillPointers(skills)}
26124
-
26125
- ## Delegating implementation
26126
-
26127
- Delegate component work from a LIVE agent brief, never a generated file: discover
26128
- agents via \`listAgents\` (or the \`wairon-agent://\` resources), fetch the target's
26129
- brief with \`sdd_get_agent_brief\`, and spawn a scoped subagent from it \u2014 its
26130
- \`instructions\` as prompt, its \`ownedPaths\` as write fence. Briefs are composed
26131
- from the current spec tree on every call, so a re-lock never requires a session
26132
- restart \u2014 fetch fresh per delegation. \`wairon-skill://sdd-delegate\` carries the
26133
- full flow.`;
26134
- }
26135
- function buildServerInstructions() {
26136
- const profile = governingProfile();
26137
- let skills = [];
26138
- let blocks = [];
26139
- let packNames = [];
26140
- const variants = [];
26141
- try {
26142
- skills = listSkillResources();
26143
- const extensions = loadProjectExtensions2();
26144
- blocks = extensions.instructions;
26145
- packNames = extensions.packNames;
26146
- } catch {
24811
+ // src/exporters/claude.ts
24812
+ var path21 = __toESM(require("path"));
24813
+ var MODEL_BY_TIER = {
24814
+ small: "haiku",
24815
+ standard: "sonnet",
24816
+ large: "opus",
24817
+ frontier: "fable"
24818
+ };
24819
+ var TOOLS_BY_CLASS = {
24820
+ "read-only": ["Read", "Grep", "Glob"],
24821
+ implement: ["Read", "Grep", "Glob", "Edit", "Write", "Bash"],
24822
+ orchestrate: ["Agent", "SendMessage", "TodoWrite"],
24823
+ // `full` means "inherit everything" — expressed by omitting the field.
24824
+ full: void 0
24825
+ };
24826
+ function toolsFor(budget) {
24827
+ const base = TOOLS_BY_CLASS[budget.toolClass];
24828
+ if (!base) return void 0;
24829
+ if (budget.allowNestedDelegation && !base.includes("Agent")) {
24830
+ return [...base, "Agent"];
26147
24831
  }
26148
- const sections = [waironInstructions(profile, packNames, skills, variants)];
26149
- for (const block of blocks) {
26150
- if (!blockApplies(block, profile)) continue;
26151
- sections.push(`## From pack "${block.pack}"
26152
-
26153
- ${block.text.trim()}`);
24832
+ if (!budget.allowNestedDelegation) {
24833
+ return base.filter((t) => t !== "Agent");
26154
24834
  }
26155
- return sections.join("\n\n");
26156
- }
26157
-
26158
- // src/core/skills.ts
26159
- var SKILL_NAMES = ["sdd-architect", "sdd-narrative", "sdd-auditor", "sdd-implement", "sdd-delegate"];
26160
- function loadProjectExtensions2() {
26161
- return loadProjectExtensions();
26162
- }
26163
- function loadProjectConfig3() {
26164
- return loadProjectConfig();
26165
- }
26166
- function packSkillId(skill) {
26167
- return `${packNamespace(skill.pack)}-${skill.id}`;
26168
- }
26169
- function packNamespace(pack) {
26170
- return pack.toLowerCase().replace(/[^a-z0-9]+/g, "-").replace(/^-+|-+$/g, "");
24835
+ return base;
26171
24836
  }
26172
- function extensionsFor(builtin, packSkills) {
26173
- return packSkills.filter((s) => s.extends === builtin && fs16.existsSync(s.sourcePath));
24837
+ function mcpServersFor(access) {
24838
+ return access === "none" ? "[]" : void 0;
26174
24839
  }
26175
- function composeBuiltinSkill(name, packSkills) {
26176
- const srcPath = skillTemplatePath(name);
26177
- const base = fs16.existsSync(srcPath) ? fs16.readFileSync(srcPath, "utf-8") : "";
26178
- const sections = extensionsFor(name, packSkills);
26179
- if (sections.length === 0) return base;
26180
- const parts = [base.trimEnd()];
26181
- for (const section of sections) {
26182
- const body = fs16.readFileSync(section.sourcePath, "utf-8").replace(/^---\r?\n[\s\S]*?\r?\n---\r?\n?/, "");
26183
- parts.push(`## Platform: ${section.pack}`, body.trim());
26184
- }
26185
- return `${parts.join("\n\n")}
26186
- `;
24840
+ function yamlScalar(value) {
24841
+ return /[:#\n]/.test(value) ? `"${value.replace(/"/g, '\\"')}"` : value;
26187
24842
  }
26188
- function readFrontmatter(raw, fallbackName) {
26189
- const match = /^---\r?\n([\s\S]*?)\r?\n---/.exec(raw);
26190
- const block = match ? match[1] : "";
26191
- const field = (key) => {
26192
- const m = new RegExp(`^${key}:\\s*(.*)$`, "m").exec(block);
26193
- return m ? m[1].trim() : "";
26194
- };
26195
- return { name: field("name") || fallbackName, description: field("description") };
26196
- }
26197
- function builtinSkillsDir() {
26198
- return path21.resolve(__dirname, "..", "templates", "skills");
26199
- }
26200
- function skillTemplatePath(name) {
26201
- return path21.join(builtinSkillsDir(), `${name}.md`);
26202
- }
26203
- function skillDestPath(type, destDir, name) {
26204
- if (type === "claude" || type === "codex" || type === "gemini" || type === "agy") {
26205
- return path21.join(destDir, name, "SKILL.md");
26206
- }
26207
- return path21.join(destDir, `${name}.md`);
26208
- }
26209
- function skillsDirForTarget(type) {
26210
- switch (type) {
26211
- case "claude":
26212
- return fromProjectRoot(".claude", "skills");
26213
- case "gemini":
26214
- // Gemini-based Antigravity
26215
- case "agy":
26216
- case "codex":
26217
- return fromProjectRoot(".agents", "skills");
26218
- case "cursor":
26219
- return fromProjectRoot(".cursor", "skills");
26220
- default:
26221
- return null;
24843
+ var ClaudeExporter = class {
24844
+ constructor(options = {}) {
24845
+ this.options = options;
24846
+ this.targetType = "claude";
26222
24847
  }
26223
- }
26224
- function listSkillNames() {
26225
- return [...SKILL_NAMES];
26226
- }
26227
- function exportSddSkills(targetTypes) {
26228
- const types = targetTypes ?? activeTargetTypes2();
26229
- const destinations = [];
26230
- const skipped = [];
26231
- let fileCount = 0;
26232
- const packSkills = loadProjectExtensions2().skills;
26233
- for (const type of types) {
26234
- const destDir = skillsDirForTarget(type);
26235
- if (!destDir) {
26236
- skipped.push(type);
26237
- continue;
26238
- }
26239
- ensureDir(destDir);
26240
- destinations.push(destDir);
26241
- for (const name of SKILL_NAMES) {
26242
- if (!fs16.existsSync(skillTemplatePath(name))) continue;
26243
- const content = composeBuiltinSkill(name, packSkills.filter((s) => s.targets.includes(type)));
26244
- const destPath = skillDestPath(type, destDir, name);
26245
- ensureDir(path21.dirname(destPath));
26246
- fs16.writeFileSync(destPath, content, "utf-8");
26247
- fileCount++;
26248
- }
26249
- for (const skill of packSkills) {
26250
- if (skill.extends !== void 0) continue;
26251
- if (!skill.targets.includes(type)) continue;
26252
- if (!fs16.existsSync(skill.sourcePath)) continue;
26253
- const id = packSkillId(skill);
26254
- const content = fs16.readFileSync(skill.sourcePath, "utf-8");
26255
- const destPath = skillDestPath(type, destDir, id);
26256
- ensureDir(path21.dirname(destPath));
26257
- fs16.writeFileSync(destPath, content, "utf-8");
26258
- fileCount++;
26259
- }
26260
- }
26261
- return { destinations, fileCount, skipped };
26262
- }
26263
- function checkSkillFreshness(type) {
26264
- const dir = skillsDirForTarget(type);
26265
- const result = { dir, missing: [], stale: [], ok: [] };
26266
- if (!dir) return result;
26267
- const packSkills = loadProjectExtensions2().skills.filter((s) => s.targets.includes(type));
26268
- for (const name of SKILL_NAMES) {
26269
- const destPath = skillDestPath(type, dir, name);
26270
- if (!fs16.existsSync(destPath)) {
26271
- result.missing.push(name);
26272
- continue;
26273
- }
26274
- const want = composeBuiltinSkill(name, packSkills);
26275
- const have = fs16.readFileSync(destPath, "utf-8");
26276
- if (have === want) result.ok.push(name);
26277
- else result.stale.push(name);
26278
- }
26279
- return result;
26280
- }
26281
- function activeTargetTypes2() {
26282
- const config = loadProjectConfig3();
26283
- if (!config) return [];
26284
- return activeTargetTypes(config);
26285
- }
26286
- var SKILL_RESOURCE_SCHEME = "wairon-skill";
26287
- var RESOURCE_SKILL_IDS = [...SKILL_NAMES].sort();
26288
- var SkillResourceNotFoundError = class extends Error {
26289
- constructor(resourceId) {
26290
- super(`Unknown SDD skill resource id: "${resourceId}".`);
26291
- this.name = "SkillResourceNotFoundError";
26292
- }
26293
- };
26294
- function readSkillFrontmatter(name) {
26295
- return readFrontmatter(fs16.readFileSync(skillTemplatePath(name), "utf-8"), name);
26296
- }
26297
- function listSkillResources() {
26298
- const builtin = RESOURCE_SKILL_IDS.map((id) => {
26299
- const fm = readSkillFrontmatter(id);
26300
- return {
26301
- id,
26302
- name: fm.name,
26303
- description: fm.description,
26304
- version: WAIRON_VERSION,
26305
- resourceUri: `${SKILL_RESOURCE_SCHEME}://${id}`,
26306
- defaultForHostedMcp: true
26307
- };
26308
- });
26309
- const pack = loadProjectExtensions2().skills.filter((s) => s.extends === void 0 && fs16.existsSync(s.sourcePath)).map((skill) => {
26310
- const id = packSkillId(skill);
26311
- const fm = readFrontmatter(fs16.readFileSync(skill.sourcePath, "utf-8"), id);
26312
- return {
26313
- id,
26314
- name: fm.name,
26315
- description: fm.description,
26316
- version: skill.packVersion ?? WAIRON_VERSION,
26317
- resourceUri: `${SKILL_RESOURCE_SCHEME}://${id}`,
26318
- defaultForHostedMcp: true
26319
- };
26320
- });
26321
- return [...builtin, ...pack];
26322
- }
26323
- function readSkillResource(resourceId) {
26324
- const packSkills = loadProjectExtensions2().skills;
26325
- if (SKILL_NAMES.includes(resourceId)) return composeBuiltinSkill(resourceId, packSkills);
26326
- const packSkill = packSkills.find((s) => s.extends === void 0 && packSkillId(s) === resourceId);
26327
- if (packSkill) return fs16.readFileSync(packSkill.sourcePath, "utf-8");
26328
- return fs16.readFileSync(skillTemplatePath(resourceId), "utf-8");
26329
- }
26330
- function listResources() {
26331
- return listSkillResources();
26332
- }
26333
- function buildServerInstructions2() {
26334
- return buildServerInstructions();
26335
- }
26336
- function readResource(resourceId) {
26337
- const known = listSkillResources().some((d) => d.id === resourceId);
26338
- if (!known) throw new SkillResourceNotFoundError(resourceId);
26339
- return readSkillResource(resourceId);
26340
- }
26341
-
26342
- // src/core/treetransfer.ts
26343
- var fs17 = __toESM(require("fs"));
26344
- var path22 = __toESM(require("path"));
26345
- var sdkPortal = __toESM(require_dist());
26346
- var STAGING_PREFIX = ".wai-staging-";
26347
- var BACKUP_DIR = ".wai-backups";
26348
- function buildTreeArchive2(roots, projectName, stateId, includeDerived) {
26349
- return sdkPortal.buildTreeArchive(roots, projectName, stateId, includeDerived);
26350
- }
26351
- function inspectTreeArchive2(archive) {
26352
- return sdkPortal.inspectTreeArchive(archive);
26353
- }
26354
- function extractTreeArchive2(archive, destDir, refuseExecutableEntries) {
26355
- const limits = void 0;
26356
- return sdkPortal.extractTreeArchive(archive, destDir, limits, refuseExecutableEntries);
26357
- }
26358
- function hasSpecTree(root) {
26359
- if (pathExists(aiPathsAt(root).projectConfig())) {
26360
- return true;
26361
- }
26362
- return false;
26363
- }
26364
- function hasAuthoredSpecs(root) {
26365
- const paths = aiPathsAt(root);
26366
- const specsDir = paths.specsDir();
26367
- if (!pathExists(specsDir)) {
26368
- return false;
26369
- }
26370
- const systemIndex = path22.resolve(paths.specsSystem());
26371
- for (const file of listFilesRecursive(specsDir, ".yaml")) {
26372
- if (path22.resolve(file) !== systemIndex) {
26373
- return true;
26374
- }
26375
- }
26376
- return false;
26377
- }
26378
- function createStagingDir(destDir) {
26379
- const root = path22.resolve(destDir);
26380
- fs17.mkdirSync(root, { recursive: true });
26381
- const stagingDir = fs17.mkdtempSync(path22.join(root, STAGING_PREFIX));
26382
- return stagingDir;
26383
- }
26384
- function commitStagedTree(stagingDir, destDir, roots, backupExisting) {
26385
- const root = path22.resolve(destDir);
26386
- const backupDir = path22.join(root, BACKUP_DIR, timestampSlug());
26387
- let backedUp = false;
26388
- for (const rootRel of roots) {
26389
- const relative9 = rootRel === "." ? "" : rootRel;
26390
- const stagedSpecDir = path22.join(stagingDir, relative9, ".wai");
26391
- if (!fs17.existsSync(stagedSpecDir)) continue;
26392
- const liveSpecDir = liveSpecDirFor(path22.join(root, relative9));
26393
- if (backupExisting && liveSpecDir && fs17.existsSync(liveSpecDir)) {
26394
- const backupTarget = path22.join(backupDir, relative9, path22.basename(liveSpecDir));
26395
- fs17.mkdirSync(path22.dirname(backupTarget), { recursive: true });
26396
- fs17.renameSync(liveSpecDir, backupTarget);
26397
- backedUp = true;
26398
- } else if (liveSpecDir && fs17.existsSync(liveSpecDir)) {
26399
- fs17.rmSync(liveSpecDir, { recursive: true, force: true });
26400
- }
26401
- const target = path22.join(root, relative9, ".wai");
26402
- fs17.mkdirSync(path22.dirname(target), { recursive: true });
26403
- if (fs17.existsSync(target)) fs17.rmSync(target, { recursive: true, force: true });
26404
- fs17.renameSync(stagedSpecDir, target);
26405
- }
26406
- if (backedUp) {
26407
- return backupDir;
26408
- }
26409
- return "";
26410
- }
26411
- function discardStagingDir(stagingDir) {
26412
- try {
26413
- fs17.rmSync(stagingDir, { recursive: true, force: true });
26414
- } catch {
26415
- }
26416
- }
26417
- function exportSpecTree(includeDerived, allowPartial) {
26418
- const system = loadSystemSpec();
26419
- if (!system) {
26420
- throw new Error("no spec tree to export at this project root");
26421
- }
26422
- const inspection = inspectChainedRoots();
26423
- const root = getProjectRoot();
26424
- const skipped = [...inspection.skipped];
26425
- const roots = [{ relativePath: ".", waiDir: aiPathsAt(root).root() }];
26426
- for (const rel2 of inspection.roots) {
26427
- const waiDir = aiPathsAt(path22.resolve(root, rel2)).root();
26428
- if (pathExists(waiDir)) {
26429
- roots.push({ relativePath: rel2, waiDir });
26430
- } else {
26431
- skipped.push({ mount: rel2, projectPath: rel2, reason: "no-spec-tree" });
26432
- }
26433
- }
26434
- if (skipped.length > 0 && !allowPartial) {
26435
- const detail = skipped.map((s) => `${s.mount} (${s.reason})`).join(", ");
26436
- throw new Error(
26437
- `cannot export the whole spec tree \u2014 skipped: ${detail}. Pass allowPartial to export the rest anyway.`
26438
- );
26439
- }
26440
- const stateId = computeStateId();
26441
- const built = buildTreeArchive2(roots, system.name, stateId.digest, includeDerived);
26442
- const result = {
26443
- archive: built.archive,
26444
- suggestedFileName: built.suggestedFileName,
26445
- projectName: built.manifest.projectName,
26446
- roots: built.manifest.roots,
26447
- fileCount: built.fileCount,
26448
- stateId: stateId.digest,
26449
- skipped
26450
- };
26451
- return result;
26452
- }
26453
- function importSpecTree(archive, options) {
26454
- const info = inspectTreeArchive2(archive);
26455
- if (!info.compatible) {
26456
- throw new Error("incompatible .waitree archive (format or minimum wairon version)");
26457
- }
26458
- const destDir = path22.resolve(options.destDir ?? getProjectRoot());
26459
- const occupied = hasSpecTree(destDir);
26460
- const authored = hasAuthoredSpecs(destDir);
26461
- if (authored && options.replaceExisting !== true) {
26462
- throw new Error(
26463
- "the destination already holds an authored spec tree; pass replaceExisting to move it aside and import over it"
26464
- );
26465
- }
26466
- const stagingDir = createStagingDir(destDir);
26467
- let extraction;
26468
- try {
26469
- extraction = extractTreeArchive2(archive, stagingDir, options.refuseExecutableEntries);
26470
- } catch (err) {
26471
- discardStagingDir(stagingDir);
26472
- throw err;
26473
- }
26474
- const backupPath = commitStagedTree(stagingDir, destDir, extraction.roots, occupied);
26475
- discardStagingDir(stagingDir);
26476
- invalidateSpecCache();
26477
- const result = {
26478
- destDir,
26479
- projectName: extraction.manifest.projectName,
26480
- roots: extraction.roots,
26481
- fileCount: extraction.writtenPaths.length,
26482
- replaced: occupied
26483
- };
26484
- if (backupPath) result.backupPath = backupPath;
26485
- if (extraction.manifest.stateId) result.stateId = extraction.manifest.stateId;
26486
- return result;
26487
- }
26488
- function liveSpecDirFor(rootDir) {
26489
- const modern = path22.join(rootDir, ".wai");
26490
- if (fs17.existsSync(modern)) return modern;
26491
- const legacy = path22.join(rootDir, ".wairon");
26492
- if (fs17.existsSync(legacy)) return legacy;
26493
- return null;
26494
- }
26495
- function timestampSlug() {
26496
- return (/* @__PURE__ */ new Date()).toISOString().replace(/[:.]/g, "-");
26497
- }
26498
-
26499
- // src/exporters/generate.ts
26500
- var path26 = __toESM(require("path"));
26501
-
26502
- // src/exporters/claude.ts
26503
- var path23 = __toESM(require("path"));
26504
- var MODEL_BY_TIER = {
26505
- small: "haiku",
26506
- standard: "sonnet",
26507
- large: "opus",
26508
- frontier: "fable"
26509
- };
26510
- var TOOLS_BY_CLASS = {
26511
- "read-only": ["Read", "Grep", "Glob"],
26512
- implement: ["Read", "Grep", "Glob", "Edit", "Write", "Bash"],
26513
- orchestrate: ["Agent", "SendMessage", "TodoWrite"],
26514
- // `full` means "inherit everything" — expressed by omitting the field.
26515
- full: void 0
26516
- };
26517
- function toolsFor(budget) {
26518
- const base = TOOLS_BY_CLASS[budget.toolClass];
26519
- if (!base) return void 0;
26520
- if (budget.allowNestedDelegation && !base.includes("Agent")) {
26521
- return [...base, "Agent"];
26522
- }
26523
- if (!budget.allowNestedDelegation) {
26524
- return base.filter((t) => t !== "Agent");
26525
- }
26526
- return base;
26527
- }
26528
- function mcpServersFor(access) {
26529
- return access === "none" ? "[]" : void 0;
26530
- }
26531
- function yamlScalar(value) {
26532
- return /[:#\n]/.test(value) ? `"${value.replace(/"/g, '\\"')}"` : value;
26533
- }
26534
- var ClaudeExporter = class {
26535
- constructor(options = {}) {
26536
- this.options = options;
26537
- this.targetType = "claude";
26538
- }
26539
- outputPath(ctx) {
26540
- const { agent, target, projectRoot } = ctx;
26541
- const outputDir = "outputDir" in target ? target.outputDir : ".claude/agents";
26542
- return path23.resolve(projectRoot, outputDir, `${agent.id.replace(/::/g, "--")}.md`);
24848
+ outputPath(ctx) {
24849
+ const { agent, target, projectRoot } = ctx;
24850
+ const outputDir = "outputDir" in target ? target.outputDir : ".claude/agents";
24851
+ return path21.resolve(projectRoot, outputDir, `${agent.id.replace(/::/g, "--")}.md`);
26543
24852
  }
26544
24853
  export(ctx) {
26545
24854
  const { agent, renderedInstructions, budget } = ctx;
@@ -26564,7 +24873,7 @@ var ClaudeExporter = class {
26564
24873
  };
26565
24874
 
26566
24875
  // src/exporters/custom.ts
26567
- var path24 = __toESM(require("path"));
24876
+ var path22 = __toESM(require("path"));
26568
24877
  var CustomExporter = class {
26569
24878
  constructor() {
26570
24879
  this.targetType = "custom";
@@ -26574,7 +24883,7 @@ var CustomExporter = class {
26574
24883
  if (!("outputDir" in target)) {
26575
24884
  throw new Error("CustomExporter requires target.outputDir");
26576
24885
  }
26577
- return path24.resolve(projectRoot, target.outputDir, `${agent.id.replace(/::/g, "--")}.md`);
24886
+ return path22.resolve(projectRoot, target.outputDir, `${agent.id.replace(/::/g, "--")}.md`);
26578
24887
  }
26579
24888
  export(ctx) {
26580
24889
  const { agent, target, renderedInstructions } = ctx;
@@ -26597,7 +24906,7 @@ var CustomExporter = class {
26597
24906
  };
26598
24907
 
26599
24908
  // src/exporters/gemini.ts
26600
- var path25 = __toESM(require("path"));
24909
+ var path23 = __toESM(require("path"));
26601
24910
  var GeminiExporter = class {
26602
24911
  constructor() {
26603
24912
  this.targetType = "gemini";
@@ -26605,7 +24914,7 @@ var GeminiExporter = class {
26605
24914
  outputPath(ctx) {
26606
24915
  const { agent, target, projectRoot } = ctx;
26607
24916
  const outputDir = "outputDir" in target ? target.outputDir : ".gemini/agents";
26608
- return path25.resolve(projectRoot, outputDir, `${agent.id.replace(/::/g, "--")}.yaml`);
24917
+ return path23.resolve(projectRoot, outputDir, `${agent.id.replace(/::/g, "--")}.yaml`);
26609
24918
  }
26610
24919
  export(ctx) {
26611
24920
  const { agent, renderedInstructions } = ctx;
@@ -26702,7 +25011,7 @@ function resolveExpectedOutputPaths(agents, projectConfig, projectRoot = getProj
26702
25011
  const targetConfig = resolveTargetConfig(agentTarget, projectConfig);
26703
25012
  if (!targetConfig) continue;
26704
25013
  const ctx = { agent, projectRoot, target: targetConfig };
26705
- expected.add(path26.resolve(getExporter(targetConfig).outputPath(ctx)));
25014
+ expected.add(path24.resolve(getExporter(targetConfig).outputPath(ctx)));
26706
25015
  }
26707
25016
  }
26708
25017
  return expected;
@@ -26715,6 +25024,163 @@ function resolveTargetConfig(agentTarget, projectConfig) {
26715
25024
  });
26716
25025
  }
26717
25026
 
25027
+ // src/core/treetransfer.ts
25028
+ var fs16 = __toESM(require("fs"));
25029
+ var path25 = __toESM(require("path"));
25030
+ var sdkPortal = __toESM(require_dist());
25031
+ var STAGING_PREFIX = ".wai-staging-";
25032
+ var BACKUP_DIR = ".wai-backups";
25033
+ function buildTreeArchive2(roots, projectName, stateId, includeDerived) {
25034
+ return sdkPortal.buildTreeArchive(roots, projectName, stateId, includeDerived);
25035
+ }
25036
+ function inspectTreeArchive2(archive) {
25037
+ return sdkPortal.inspectTreeArchive(archive);
25038
+ }
25039
+ function extractTreeArchive2(archive, destDir, refuseExecutableEntries) {
25040
+ const limits = void 0;
25041
+ return sdkPortal.extractTreeArchive(archive, destDir, limits, refuseExecutableEntries);
25042
+ }
25043
+ function hasSpecTree(root) {
25044
+ if (pathExists(aiPathsAt(root).projectConfig())) {
25045
+ return true;
25046
+ }
25047
+ return false;
25048
+ }
25049
+ function hasAuthoredSpecs(root) {
25050
+ const paths = aiPathsAt(root);
25051
+ const specsDir = paths.specsDir();
25052
+ if (!pathExists(specsDir)) {
25053
+ return false;
25054
+ }
25055
+ const systemIndex = path25.resolve(paths.specsSystem());
25056
+ for (const file of listFilesRecursive(specsDir, ".yaml")) {
25057
+ if (path25.resolve(file) !== systemIndex) {
25058
+ return true;
25059
+ }
25060
+ }
25061
+ return false;
25062
+ }
25063
+ function createStagingDir(destDir) {
25064
+ const root = path25.resolve(destDir);
25065
+ fs16.mkdirSync(root, { recursive: true });
25066
+ const stagingDir = fs16.mkdtempSync(path25.join(root, STAGING_PREFIX));
25067
+ return stagingDir;
25068
+ }
25069
+ function commitStagedTree(stagingDir, destDir, roots, backupExisting) {
25070
+ const root = path25.resolve(destDir);
25071
+ const backupDir = path25.join(root, BACKUP_DIR, timestampSlug());
25072
+ let backedUp = false;
25073
+ for (const rootRel of roots) {
25074
+ const relative9 = rootRel === "." ? "" : rootRel;
25075
+ const stagedSpecDir = path25.join(stagingDir, relative9, ".wai");
25076
+ if (!fs16.existsSync(stagedSpecDir)) continue;
25077
+ const liveSpecDir = liveSpecDirFor(path25.join(root, relative9));
25078
+ if (backupExisting && liveSpecDir && fs16.existsSync(liveSpecDir)) {
25079
+ const backupTarget = path25.join(backupDir, relative9, path25.basename(liveSpecDir));
25080
+ fs16.mkdirSync(path25.dirname(backupTarget), { recursive: true });
25081
+ fs16.renameSync(liveSpecDir, backupTarget);
25082
+ backedUp = true;
25083
+ } else if (liveSpecDir && fs16.existsSync(liveSpecDir)) {
25084
+ fs16.rmSync(liveSpecDir, { recursive: true, force: true });
25085
+ }
25086
+ const target = path25.join(root, relative9, ".wai");
25087
+ fs16.mkdirSync(path25.dirname(target), { recursive: true });
25088
+ if (fs16.existsSync(target)) fs16.rmSync(target, { recursive: true, force: true });
25089
+ fs16.renameSync(stagedSpecDir, target);
25090
+ }
25091
+ if (backedUp) {
25092
+ return backupDir;
25093
+ }
25094
+ return "";
25095
+ }
25096
+ function discardStagingDir(stagingDir) {
25097
+ try {
25098
+ fs16.rmSync(stagingDir, { recursive: true, force: true });
25099
+ } catch {
25100
+ }
25101
+ }
25102
+ function exportSpecTree(includeDerived, allowPartial) {
25103
+ const system = loadSystemSpec();
25104
+ if (!system) {
25105
+ throw new Error("no spec tree to export at this project root");
25106
+ }
25107
+ const inspection = inspectChainedRoots();
25108
+ const root = getProjectRoot();
25109
+ const skipped = [...inspection.skipped];
25110
+ const roots = [{ relativePath: ".", waiDir: aiPathsAt(root).root() }];
25111
+ for (const rel2 of inspection.roots) {
25112
+ const waiDir = aiPathsAt(path25.resolve(root, rel2)).root();
25113
+ if (pathExists(waiDir)) {
25114
+ roots.push({ relativePath: rel2, waiDir });
25115
+ } else {
25116
+ skipped.push({ mount: rel2, projectPath: rel2, reason: "no-spec-tree" });
25117
+ }
25118
+ }
25119
+ if (skipped.length > 0 && !allowPartial) {
25120
+ const detail = skipped.map((s) => `${s.mount} (${s.reason})`).join(", ");
25121
+ throw new Error(
25122
+ `cannot export the whole spec tree \u2014 skipped: ${detail}. Pass allowPartial to export the rest anyway.`
25123
+ );
25124
+ }
25125
+ const stateId = computeStateId();
25126
+ const built = buildTreeArchive2(roots, system.name, stateId.digest, includeDerived);
25127
+ const result = {
25128
+ archive: built.archive,
25129
+ suggestedFileName: built.suggestedFileName,
25130
+ projectName: built.manifest.projectName,
25131
+ roots: built.manifest.roots,
25132
+ fileCount: built.fileCount,
25133
+ stateId: stateId.digest,
25134
+ skipped
25135
+ };
25136
+ return result;
25137
+ }
25138
+ function importSpecTree(archive, options) {
25139
+ const info = inspectTreeArchive2(archive);
25140
+ if (!info.compatible) {
25141
+ throw new Error("incompatible .waitree archive (format or minimum wairon version)");
25142
+ }
25143
+ const destDir = path25.resolve(options.destDir ?? getProjectRoot());
25144
+ const occupied = hasSpecTree(destDir);
25145
+ const authored = hasAuthoredSpecs(destDir);
25146
+ if (authored && options.replaceExisting !== true) {
25147
+ throw new Error(
25148
+ "the destination already holds an authored spec tree; pass replaceExisting to move it aside and import over it"
25149
+ );
25150
+ }
25151
+ const stagingDir = createStagingDir(destDir);
25152
+ let extraction;
25153
+ try {
25154
+ extraction = extractTreeArchive2(archive, stagingDir, options.refuseExecutableEntries);
25155
+ } catch (err) {
25156
+ discardStagingDir(stagingDir);
25157
+ throw err;
25158
+ }
25159
+ const backupPath = commitStagedTree(stagingDir, destDir, extraction.roots, occupied);
25160
+ discardStagingDir(stagingDir);
25161
+ invalidateSpecCache();
25162
+ const result = {
25163
+ destDir,
25164
+ projectName: extraction.manifest.projectName,
25165
+ roots: extraction.roots,
25166
+ fileCount: extraction.writtenPaths.length,
25167
+ replaced: occupied
25168
+ };
25169
+ if (backupPath) result.backupPath = backupPath;
25170
+ if (extraction.manifest.stateId) result.stateId = extraction.manifest.stateId;
25171
+ return result;
25172
+ }
25173
+ function liveSpecDirFor(rootDir) {
25174
+ const modern = path25.join(rootDir, ".wai");
25175
+ if (fs16.existsSync(modern)) return modern;
25176
+ const legacy = path25.join(rootDir, ".wairon");
25177
+ if (fs16.existsSync(legacy)) return legacy;
25178
+ return null;
25179
+ }
25180
+ function timestampSlug() {
25181
+ return (/* @__PURE__ */ new Date()).toISOString().replace(/[:.]/g, "-");
25182
+ }
25183
+
26718
25184
  // src/core/stereotype-migration.ts
26719
25185
  var DATA_FACADES = /* @__PURE__ */ new Set(["Repository", "Index", "Adapter"]);
26720
25186
  function retireSpecialists(apply) {
@@ -26848,22 +25314,30 @@ function repairForeignStepFields(apply) {
26848
25314
  }
26849
25315
 
26850
25316
  // src/core/approval.ts
26851
- var crypto4 = __toESM(require("crypto"));
26852
- var path27 = __toESM(require("path"));
25317
+ var crypto3 = __toESM(require("crypto"));
25318
+ var path26 = __toESM(require("path"));
25319
+
25320
+ // src/models/lock.ts
25321
+ function describeApprover(who) {
25322
+ const label = who.name ? `${who.name} (${who.id})` : who.id;
25323
+ return who.source === "hosted" ? `${label} [authenticated]` : label;
25324
+ }
25325
+
25326
+ // src/core/approval.ts
26853
25327
  function diffSize(d) {
26854
25328
  return d.added.length + d.changed.length + d.removed.length;
26855
25329
  }
26856
25330
  function digest(content) {
26857
25331
  const normalized = content.replace(/\r\n/g, "\n");
26858
- return crypto4.createHash("sha256").update(normalized, "utf8").digest("hex");
25332
+ return crypto3.createHash("sha256").update(normalized, "utf8").digest("hex");
26859
25333
  }
26860
25334
  function currentSpecDigests(root = getProjectRoot()) {
26861
- const mountDirs = loadSubsystemSpecs().filter((s) => s.projectPath && !s.id.includes("::")).map((s) => `${path27.resolve(root, s.projectPath).split(path27.sep).join("/")}/`);
25335
+ const mountDirs = loadSubsystemSpecs().filter((s) => s.projectPath && !s.id.includes("::")).map((s) => `${path26.resolve(root, s.projectPath).split(path26.sep).join("/")}/`);
26862
25336
  const out = {};
26863
25337
  for (const [abs, content] of snapshotSpecFiles()) {
26864
- const normalized = path27.resolve(abs).split(path27.sep).join("/");
25338
+ const normalized = path26.resolve(abs).split(path26.sep).join("/");
26865
25339
  if (mountDirs.some((dir) => normalized.startsWith(dir))) continue;
26866
- out[path27.relative(root, abs).split(path27.sep).join("/")] = digest(content);
25340
+ out[path26.relative(root, abs).split(path26.sep).join("/")] = digest(content);
26867
25341
  }
26868
25342
  return out;
26869
25343
  }
@@ -26921,7 +25395,7 @@ function currentChildPins(mounts, root = getProjectRoot()) {
26921
25395
  const pins = {};
26922
25396
  for (const mount of mounts) {
26923
25397
  if (!mount.projectPath || mount.id.includes("::")) continue;
26924
- const child = readLockRecordAt(path27.resolve(root, mount.projectPath));
25398
+ const child = readLockRecordAt(path26.resolve(root, mount.projectPath));
26925
25399
  if (child) pins[mount.id] = pinOf(child.stateId);
26926
25400
  }
26927
25401
  return pins;
@@ -26937,6 +25411,52 @@ function movedChildren(mounts, root = getProjectRoot()) {
26937
25411
  }
26938
25412
  return moved;
26939
25413
  }
25414
+ function approvalVerdict() {
25415
+ const quiet = { text: "", drifted: false };
25416
+ try {
25417
+ const approval = approvalRecord();
25418
+ if (!approval) return quiet;
25419
+ const by = describeApprover(approval.lockedBy);
25420
+ const moved = movedChildren(loadSubsystemSpecs());
25421
+ const childNote = moved.length ? `
25422
+ ${moved.length} chained child project(s) moved since approval: ${moved.map((m) => m.id).join(", ")}.` : "";
25423
+ const diff = diffAgainstApproval();
25424
+ if (!diff) {
25425
+ return {
25426
+ text: `
25427
+ Approved: ${approval.lockedAt} by ${by} \u2014 this lock predates per-spec approval, so drift is only visible at whole-tree level. Re-lock to record it.${childNote}
25428
+ `,
25429
+ drifted: moved.length > 0
25430
+ };
25431
+ }
25432
+ if (diffSize(diff) === 0) {
25433
+ return {
25434
+ text: `
25435
+ Approved: ${approval.lockedAt} by ${by} \u2014 no spec has changed since.${childNote}
25436
+ `,
25437
+ drifted: moved.length > 0
25438
+ };
25439
+ }
25440
+ const parts = [];
25441
+ if (diff.changed.length) parts.push(`${diff.changed.length} changed`);
25442
+ if (diff.added.length) parts.push(`${diff.added.length} added`);
25443
+ if (diff.removed.length) parts.push(`${diff.removed.length} removed`);
25444
+ const named = [...diff.changed, ...diff.added, ...diff.removed].slice(0, 5);
25445
+ const rest = diffSize(diff) - named.length;
25446
+ const n = diffSize(diff);
25447
+ const noun = `${n} spec${n === 1 ? "" : "s"}`;
25448
+ const headline = parts.length === 1 ? `${noun} ${parts[0].slice(String(diffSize(diff)).length + 1)} since approval` : `${noun} changed since approval (${parts.join(", ")})`;
25449
+ return {
25450
+ text: `
25451
+ ${headline} \u2014 approved ${approval.lockedAt} by ${by}:
25452
+ ` + named.map((p) => ` ${p}`).join("\n") + (rest > 0 ? `
25453
+ \u2026 and ${rest} more` : "") + childNote + "\n",
25454
+ drifted: true
25455
+ };
25456
+ } catch {
25457
+ return quiet;
25458
+ }
25459
+ }
26940
25460
 
26941
25461
  // src/core/approver.ts
26942
25462
  var import_child_process = require("child_process");
@@ -26975,9 +25495,9 @@ function localApprover() {
26975
25495
  }
26976
25496
 
26977
25497
  // src/utils/ai-guide.ts
26978
- var fs18 = __toESM(require("fs"));
25498
+ var fs17 = __toESM(require("fs"));
26979
25499
  var os5 = __toESM(require("os"));
26980
- var path28 = __toESM(require("path"));
25500
+ var path27 = __toESM(require("path"));
26981
25501
 
26982
25502
  // src/core/stamp.ts
26983
25503
  function versionStamp() {
@@ -27037,13 +25557,13 @@ This project uses **wairon**. System specs live under \`.wai/specs/\` (L0 System
27037
25557
  * **Variants**: \`gateway\`, a Portal that authenticates, authorizes, validates or rate-limits before it dispatches. Logic is an Orchestrator, and \`dependencyClass: pure | read\` bounds what it may depend on (unset = a workflow). Specialist and Gateway are retired stereotypes.
27038
25558
  * Use \`owns\` for private member containment (exactly one hop) and \`dependsOn\` for collaborators. Never use generic suffixes like "Manager", "Helper", or "Utils".`;
27039
25559
  function globalGuideFilePath(targetType) {
27040
- if (targetType === "claude") return path28.join(process.env["CLAUDE_CONFIG_DIR"] || path28.join(os5.homedir(), ".claude"), "CLAUDE.md");
27041
- if (targetType === "gemini") return path28.join(process.env["GEMINI_CONFIG_DIR"] || path28.join(os5.homedir(), ".gemini"), "GEMINI.md");
25560
+ if (targetType === "claude") return path27.join(process.env["CLAUDE_CONFIG_DIR"] || path27.join(os5.homedir(), ".claude"), "CLAUDE.md");
25561
+ if (targetType === "gemini") return path27.join(process.env["GEMINI_CONFIG_DIR"] || path27.join(os5.homedir(), ".gemini"), "GEMINI.md");
27042
25562
  return null;
27043
25563
  }
27044
25564
  function localGuideFilePath(projectRoot, targetType) {
27045
- if (targetType === "claude") return path28.join(projectRoot, ".claude", "CLAUDE.md");
27046
- if (targetType === "gemini" || targetType === "agy") return path28.join(projectRoot, ".gemini", "GEMINI.md");
25565
+ if (targetType === "claude") return path27.join(projectRoot, ".claude", "CLAUDE.md");
25566
+ if (targetType === "gemini" || targetType === "agy") return path27.join(projectRoot, ".gemini", "GEMINI.md");
27047
25567
  return null;
27048
25568
  }
27049
25569
  function injectGuide(filePath, scope) {
@@ -27055,11 +25575,11 @@ ${versionStamp()}
27055
25575
  ${body}
27056
25576
  ${GUIDE_MARKER_END}
27057
25577
  `;
27058
- const existing = fs18.existsSync(filePath) ? fs18.readFileSync(filePath, "utf-8") : "";
25578
+ const existing = fs17.existsSync(filePath) ? fs17.readFileSync(filePath, "utf-8") : "";
27059
25579
  const stripped = stripGuideSection(existing);
27060
25580
  const newContent = stripped.trimEnd() + section;
27061
- fs18.mkdirSync(path28.dirname(filePath), { recursive: true });
27062
- fs18.writeFileSync(filePath, newContent, "utf-8");
25581
+ fs17.mkdirSync(path27.dirname(filePath), { recursive: true });
25582
+ fs17.writeFileSync(filePath, newContent, "utf-8");
27063
25583
  }
27064
25584
  function stripGuideSection(content) {
27065
25585
  const start = content.indexOf(GUIDE_MARKER_START);
@@ -27069,7 +25589,7 @@ function stripGuideSection(content) {
27069
25589
  }
27070
25590
  function writeRootGuideDelegator(projectRoot, targetType) {
27071
25591
  if (targetType === "claude") {
27072
- const filePath = path28.join(projectRoot, "CLAUDE.md");
25592
+ const filePath = path27.join(projectRoot, "CLAUDE.md");
27073
25593
  const content = `@.claude/CLAUDE.md
27074
25594
 
27075
25595
  # Wairon SDD Project
@@ -27082,42 +25602,42 @@ To design or modify the system, invoke the **\`sdd-architect\`** skill
27082
25602
  (in \`.claude/skills/\`). Author and validate specs with the \`sdd_*\` MCP tools;
27083
25603
  the \`wairon\` CLI is the human developer's tool, not yours.
27084
25604
  `;
27085
- fs18.writeFileSync(filePath, content, "utf-8");
25605
+ fs17.writeFileSync(filePath, content, "utf-8");
27086
25606
  } else if (targetType === "gemini" || targetType === "agy") {
27087
- const filePath = path28.join(projectRoot, "GEMINI.md");
25607
+ const filePath = path27.join(projectRoot, "GEMINI.md");
27088
25608
  const content = `# Wairon SDD Project
27089
25609
  ${GUIDE_MARKER_START}
27090
25610
  ${versionStamp()}
27091
25611
  ${LOCAL_GUIDE_BODY}
27092
25612
  ${GUIDE_MARKER_END}
27093
25613
  `;
27094
- fs18.writeFileSync(filePath, content, "utf-8");
25614
+ fs17.writeFileSync(filePath, content, "utf-8");
27095
25615
  } else if (targetType === "cursor") {
27096
- const filePath = path28.join(projectRoot, ".cursorrules");
25616
+ const filePath = path27.join(projectRoot, ".cursorrules");
27097
25617
  const content = `# Wairon SDD Project
27098
25618
 
27099
25619
  This project uses the Wairon Spec-Driven Development (SDD) framework.
27100
25620
 
27101
25621
  Refer to the rules in [.cursor/rules/](.cursor/rules/) for full instructions.
27102
25622
  `;
27103
- fs18.writeFileSync(filePath, content, "utf-8");
25623
+ fs17.writeFileSync(filePath, content, "utf-8");
27104
25624
  } else if (targetType === "copilot") {
27105
- const filePath = path28.join(projectRoot, ".github", "copilot-instructions.md");
27106
- fs18.mkdirSync(path28.dirname(filePath), { recursive: true });
25625
+ const filePath = path27.join(projectRoot, ".github", "copilot-instructions.md");
25626
+ fs17.mkdirSync(path27.dirname(filePath), { recursive: true });
27107
25627
  const content = `# Wairon SDD Project
27108
25628
 
27109
25629
  This project uses the Wairon Spec-Driven Development (SDD) framework.
27110
25630
 
27111
25631
  Refer to the prompts in [.github/prompts/](.github/prompts/) for instructions.
27112
25632
  `;
27113
- fs18.writeFileSync(filePath, content, "utf-8");
25633
+ fs17.writeFileSync(filePath, content, "utf-8");
27114
25634
  } else if (targetType === "codex") {
27115
- const filePath = path28.join(projectRoot, ".codexrules");
25635
+ const filePath = path27.join(projectRoot, ".codexrules");
27116
25636
  const content = `# Wairon SDD Project
27117
25637
 
27118
25638
  Refer to [.codex/agents/](.codex/agents/) for full instructions.
27119
25639
  `;
27120
- fs18.writeFileSync(filePath, content, "utf-8");
25640
+ fs17.writeFileSync(filePath, content, "utf-8");
27121
25641
  }
27122
25642
  }
27123
25643
  var GUIDE_TARGETS = ["claude", "gemini", "agy", "cursor", "copilot", "codex"];
@@ -27267,6 +25787,152 @@ function syncContextFiles() {
27267
25787
  return { domainsUpdated, guideUpdated };
27268
25788
  }
27269
25789
 
25790
+ // src/core/status.ts
25791
+ var asWritten = (text) => text;
25792
+ function fillDecor(decor) {
25793
+ return {
25794
+ structure: decor?.structure ?? asWritten,
25795
+ emphasis: decor?.emphasis ?? asWritten,
25796
+ layer: decor?.layer ?? ((_kind, text) => text),
25797
+ score: decor?.score ?? ((_pct, text) => text),
25798
+ draft: decor?.draft ?? asWritten,
25799
+ present: decor?.present ?? asWritten,
25800
+ missing: decor?.missing ?? asWritten
25801
+ };
25802
+ }
25803
+ function getStatusReport(options = {}, decor) {
25804
+ const mark = fillDecor(decor);
25805
+ scanAllSpecs({ recursive: options.recursive ?? true });
25806
+ const system = loadSystemSpec();
25807
+ const loaderErrors = getLoaderIssues();
25808
+ if (loaderErrors.length > 0) {
25809
+ let errText = "Failed to parse specification files:\n";
25810
+ for (const issue2 of loaderErrors) {
25811
+ const prefix = issue2.specId ? mark.structure(`[${issue2.specId}] `) : "";
25812
+ errText += `${prefix}[${issue2.code}] ${issue2.message}
25813
+ `;
25814
+ }
25815
+ return { text: errText, failed: true };
25816
+ }
25817
+ if (!system) {
25818
+ return { text: "L0 System specification (system.yaml) is missing.", failed: true };
25819
+ }
25820
+ let subsystems = loadSubsystemSpecs();
25821
+ let components = loadComponentSpecs();
25822
+ let interfaces = loadInterfaceSpecs();
25823
+ let implementations = loadImplementationSpecs();
25824
+ if (options.subsystem) {
25825
+ subsystems = subsystems.filter((s) => s.id === options.subsystem || s.id.startsWith(`${options.subsystem}::`));
25826
+ components = components.filter((c) => c.subsystem === options.subsystem || c.subsystem.startsWith(`${options.subsystem}::`));
25827
+ interfaces = interfaces.filter((i) => {
25828
+ const c = components.find((comp) => comp.id === i.component);
25829
+ return c !== void 0;
25830
+ });
25831
+ implementations = implementations.filter((im) => {
25832
+ const inf = interfaces.find((i) => i.id === im.contract);
25833
+ return inf !== void 0;
25834
+ });
25835
+ }
25836
+ let output = "";
25837
+ const componentScores = /* @__PURE__ */ new Map();
25838
+ for (const comp of components) {
25839
+ let score = 20;
25840
+ const intf = interfaces.find((i) => i.component === comp.id);
25841
+ if (intf) {
25842
+ score += 30;
25843
+ }
25844
+ const impl = implementations.find((im) => intf && im.contract === intf.id);
25845
+ if (impl) {
25846
+ score += 30;
25847
+ const sourceFiles = implementationSourceFiles(impl);
25848
+ if (sourceFiles.length > 0 && sourceFiles.every((f) => pathExists(fromProjectRoot(f)))) {
25849
+ score += 20;
25850
+ }
25851
+ }
25852
+ const isDraft = comp.status === "draft" || comp.status === "design" || intf && (intf.status === "draft" || intf.status === "design") || impl && (impl.status === "draft" || impl.status === "design");
25853
+ if (isDraft) {
25854
+ score = Math.min(score, 50);
25855
+ }
25856
+ componentScores.set(comp.id, score);
25857
+ }
25858
+ const getSubsystemScore = (subId) => {
25859
+ const sub = subsystems.find((s) => s.id === subId);
25860
+ if (!sub) return 0;
25861
+ const subComps = components.filter((c) => c.subsystem === subId);
25862
+ if (subComps.length === 0) return 0;
25863
+ const totalScore = subComps.reduce((acc, c) => acc + (componentScores.get(c.id) ?? 0), 0);
25864
+ let avg = Math.round(totalScore / subComps.length);
25865
+ if (sub.status === "draft" || sub.status === "design") {
25866
+ avg = Math.min(avg, 50);
25867
+ }
25868
+ return avg;
25869
+ };
25870
+ const totalSubsystemsScore = subsystems.reduce((acc, s) => acc + getSubsystemScore(s.id), 0);
25871
+ const systemScore = subsystems.length > 0 ? Math.round(totalSubsystemsScore / subsystems.length) : 0;
25872
+ output += `${mark.layer("system", "\u25CF System:")} ${mark.emphasis(system.name)} ${mark.score(systemScore, `(${systemScore}% Complete)`)}
25873
+ `;
25874
+ for (let i = 0; i < subsystems.length; i++) {
25875
+ const sub = subsystems[i];
25876
+ const isLastSub = i === subsystems.length - 1;
25877
+ const subPrefix = isLastSub ? "\u2514\u2500\u2500 " : "\u251C\u2500\u2500 ";
25878
+ const subIndent = isLastSub ? " " : "\u2502 ";
25879
+ const subScore = getSubsystemScore(sub.id);
25880
+ const subStatusStr = sub.status !== "complete" ? mark.draft(` [${sub.status}]`) : "";
25881
+ output += `${mark.structure(subPrefix)}${mark.layer("subsystem", `[Subsystem] ${sub.id}`)}${subStatusStr} ${mark.score(subScore, `(${subScore}%)`)}
25882
+ `;
25883
+ const subComps = components.filter((c) => c.subsystem === sub.id);
25884
+ for (let j = 0; j < subComps.length; j++) {
25885
+ const comp = subComps[j];
25886
+ const isLastComp = j === subComps.length - 1;
25887
+ const compPrefix = isLastComp ? "\u2514\u2500\u2500 " : "\u251C\u2500\u2500 ";
25888
+ const compIndent = isLastComp ? " " : "\u2502 ";
25889
+ const compScore = componentScores.get(comp.id) ?? 0;
25890
+ const compStatusStr = comp.status !== "complete" ? mark.draft(` [${comp.status}]`) : "";
25891
+ output += `${mark.structure(subIndent + compPrefix)}${mark.layer("component", `[Component: ${comp.componentType}] ${comp.id}`)}${compStatusStr} ${mark.score(compScore, `(${compScore}%)`)}
25892
+ `;
25893
+ const intf = interfaces.find((inf) => inf.component === comp.id);
25894
+ const impl = implementations.find((im) => intf && im.contract === intf.id);
25895
+ const intfPrefix = intf && impl ? "\u251C\u2500\u2500 " : "\u2514\u2500\u2500 ";
25896
+ if (intf) {
25897
+ const intfStatusStr = intf.status !== "complete" ? mark.draft(` [${intf.status}]`) : "";
25898
+ output += `${mark.structure(subIndent + compIndent + intfPrefix)}${mark.layer("interface", `Interface: ${intf.id}`)}${intfStatusStr} (${intf.methods.length} methods)
25899
+ `;
25900
+ } else {
25901
+ output += `${mark.structure(subIndent + compIndent + intfPrefix)}${mark.missing("Interface: Missing (-30%)")}
25902
+ `;
25903
+ }
25904
+ if (impl) {
25905
+ const implStatusStr = impl.status !== "complete" ? mark.draft(` [${impl.status}]`) : "";
25906
+ const methodsWithOwnPath = impl.methods.filter((m) => m.sourcePath);
25907
+ let pathStr;
25908
+ if (impl.sourcePath) {
25909
+ pathStr = pathExists(fromProjectRoot(impl.sourcePath)) ? mark.present(` -> ${impl.sourcePath}`) : mark.missing(` -> ${impl.sourcePath} (File Missing!)`);
25910
+ } else if (methodsWithOwnPath.length > 0) {
25911
+ pathStr = "";
25912
+ } else {
25913
+ pathStr = mark.structure(" (No source path)");
25914
+ }
25915
+ output += `${mark.structure(subIndent + compIndent + "\u2514\u2500\u2500 ")}${mark.layer("implementation", `Implementation: ${impl.id}`)}${implStatusStr}${pathStr}
25916
+ `;
25917
+ const methodIndent = `${subIndent}${compIndent} `;
25918
+ for (let k = 0; k < methodsWithOwnPath.length; k++) {
25919
+ const method = methodsWithOwnPath[k];
25920
+ const isLastMethod = k === methodsWithOwnPath.length - 1;
25921
+ const methodPrefix = isLastMethod ? "\u2514\u2500\u2500 " : "\u251C\u2500\u2500 ";
25922
+ const methodPath = method.sourcePath;
25923
+ const methodLine = pathExists(fromProjectRoot(methodPath)) ? mark.present(`method ${method.name} -> ${methodPath}`) : mark.missing(`method ${method.name} -> ${methodPath} (File Missing!)`);
25924
+ output += `${mark.structure(methodIndent + methodPrefix)}${methodLine}
25925
+ `;
25926
+ }
25927
+ } else {
25928
+ output += `${mark.structure(subIndent + compIndent + "\u2514\u2500\u2500 ")}${mark.missing("Implementation: Missing (-30%)")}
25929
+ `;
25930
+ }
25931
+ }
25932
+ }
25933
+ return { text: output, failed: false };
25934
+ }
25935
+
27270
25936
  // src/core/index.ts
27271
25937
  function resolveDomains2() {
27272
25938
  return resolveDomains();
@@ -27340,6 +26006,18 @@ var logger = {
27340
26006
  }
27341
26007
  };
27342
26008
 
26009
+ // src/core/skills.ts
26010
+ var SKILL_NAMES = ["sdd-architect", "sdd-narrative", "sdd-auditor", "sdd-implement", "sdd-delegate"];
26011
+ function loadProjectConfig3() {
26012
+ return loadProjectConfig();
26013
+ }
26014
+ function activeTargetTypes2() {
26015
+ const config = loadProjectConfig3();
26016
+ if (!config) return [];
26017
+ return activeTargetTypes(config);
26018
+ }
26019
+ var RESOURCE_SKILL_IDS = [...SKILL_NAMES].sort();
26020
+
27343
26021
  // src/index.ts
27344
26022
  function loadProjectConfig4() {
27345
26023
  const config = loadProjectConfig();
@@ -27355,7 +26033,6 @@ function loadProjectConfig4() {
27355
26033
  AgentRecordSchema,
27356
26034
  AgentStatusSchema,
27357
26035
  AgentTemplateSchema,
27358
- AssertionSelectorSchema,
27359
26036
  BACKEND_COMMANDS,
27360
26037
  BUILTIN_PROFILES,
27361
26038
  BUILTIN_TYPES,
@@ -27363,7 +26040,6 @@ function loadProjectConfig4() {
27363
26040
  BuiltinTargetConfigSchema,
27364
26041
  BuiltinTargetSchema,
27365
26042
  BundleNotFoundError,
27366
- COMPONENT_AUTH_SOURCE,
27367
26043
  CarriedDebtKindSchema,
27368
26044
  CarriedDebtSchema,
27369
26045
  CarriedFindingSchema,
@@ -27380,7 +26056,6 @@ function loadProjectConfig4() {
27380
26056
  CustomTargetSchema,
27381
26057
  DEFAULT_TARGET_DIRS,
27382
26058
  DatabaseSpecSchema,
27383
- DeclarativePackSchema,
27384
26059
  DependencyClassSchema,
27385
26060
  DesignDepthSchema,
27386
26061
  DiagramConfigSchema,
@@ -27396,7 +26071,6 @@ function loadProjectConfig4() {
27396
26071
  ExternalLinkTypeSchema,
27397
26072
  FindingDeclarationSchema,
27398
26073
  GITHUB_REPO,
27399
- GLOBAL_PACKS_DEFAULT,
27400
26074
  GeminiExporter,
27401
26075
  GroupSpecSchema,
27402
26076
  GuaranteeSchema,
@@ -27404,7 +26078,6 @@ function loadProjectConfig4() {
27404
26078
  ImplementationSpecSchema,
27405
26079
  InterfaceSpecSchema,
27406
26080
  InvariantSchema,
27407
- LanguagePackDefSchema,
27408
26081
  LifecycleEntrypointSchema,
27409
26082
  LintAllowSchema,
27410
26083
  LintConfigSchema,
@@ -27418,21 +26091,15 @@ function loadProjectConfig4() {
27418
26091
  NarrativeStepSchema,
27419
26092
  NarrativeStepTypeSchema,
27420
26093
  OutputTargetSchema,
27421
- PACK_DIR_ENTRIES,
27422
26094
  PATTERN_TYPES,
27423
26095
  PROJECT_KINDS,
27424
- PackAssertionSchema,
27425
- PackInstructionBlockSchema,
27426
26096
  PackSelectionSchema,
27427
- PackSkillSchema,
27428
26097
  ParallelBranchSchema,
27429
26098
  PathsConfigSchema,
27430
- PatternDefSchema,
27431
26099
  PatternRefSchema,
27432
26100
  PortalAuthSchema,
27433
26101
  PortalAuthSchemeSchema,
27434
26102
  PortalTypeSchema,
27435
- ProfileDefSchema,
27436
26103
  ProfileSelectionSubjectSchema,
27437
26104
  ProjectConfigSchema,
27438
26105
  ProjectNotInitializedError,
@@ -27451,10 +26118,8 @@ function loadProjectConfig4() {
27451
26118
  STEP_TYPE_FIELDS,
27452
26119
  SUPPORTED_ALIASES,
27453
26120
  SURFACE_AUDIENCES,
27454
- SkillResourceNotFoundError,
27455
26121
  SpecIdSchema,
27456
26122
  SpecStatusSchema,
27457
- SpecWorkspace,
27458
26123
  SubsystemSpecSchema,
27459
26124
  SurfaceAudienceSchema,
27460
26125
  SurfaceContractEntrySchema,
@@ -27474,9 +26139,6 @@ function loadProjectConfig4() {
27474
26139
  TypeKindSchema,
27475
26140
  TypeMethodSchema,
27476
26141
  TypeSpecSchema,
27477
- UNVERSIONED,
27478
- UnknownAgentError,
27479
- VariantDefSchema,
27480
26142
  WAIRON_MANAGED_BANNER,
27481
26143
  WAIRON_MANAGED_MARKER,
27482
26144
  WAIRON_VERSION,
@@ -27487,33 +26149,19 @@ function loadProjectConfig4() {
27487
26149
  aiDirAt,
27488
26150
  aiPathsAt,
27489
26151
  ambiguityMessage,
27490
- applySpecStatus,
27491
26152
  approvalRecord,
27492
- assertContainedProjectPath,
26153
+ approvalVerdict,
27493
26154
  assertProjectInitialized,
27494
- assertionFullCode,
27495
- audienceRank,
27496
26155
  backendCommand,
27497
- backfillChainedSubprojectConfigs,
27498
26156
  buildCanvasDataModel,
27499
- buildGraphModel,
27500
26157
  buildProjectGraph,
27501
26158
  buildRuleContext,
27502
- buildServerInstructions,
27503
- buildTreeArchive,
27504
26159
  callSitesOf,
27505
26160
  captureApprovedSpecs,
27506
- checkSkillFreshness,
27507
- clearLoaderIssues,
27508
26161
  cognitiveScore,
27509
- collectPromotableSpecs,
27510
- commitStagedTree,
27511
26162
  complexityLevel,
27512
26163
  composeAgentBrief,
27513
26164
  composeRuleSequence,
27514
- composeVariantGuidance,
27515
- computeGateStateId,
27516
- computePackDigest,
27517
26165
  computeStateId,
27518
26166
  computeStateIdAt,
27519
26167
  conceptNoun,
@@ -27523,7 +26171,6 @@ function loadProjectConfig4() {
27523
26171
  createEmptyRegistry,
27524
26172
  createEmptyTopologyConfig,
27525
26173
  createProjectConfig,
27526
- createStagingDir,
27527
26174
  currentChildPins,
27528
26175
  declaredPackNames,
27529
26176
  declaredProfileIds,
@@ -27533,7 +26180,6 @@ function loadProjectConfig4() {
27533
26180
  defaultPackSelections,
27534
26181
  defaultTargetConfig,
27535
26182
  deleteComponentSpec,
27536
- deleteGroupSpec,
27537
26183
  deleteImplementationSpec,
27538
26184
  deleteInterfaceSpec,
27539
26185
  deleteSubsystemSpec,
@@ -27541,121 +26187,75 @@ function loadProjectConfig4() {
27541
26187
  deregisterPackRef,
27542
26188
  deriveExecutionProfile,
27543
26189
  derivedDocPaths,
27544
- describeApprover,
27545
26190
  detectDomainCandidates,
27546
- diagnoseProjectPacks,
27547
26191
  diagramSetIndex,
27548
26192
  diffAgainstApproval,
27549
26193
  diffSize,
27550
- discardStagingDir,
27551
26194
  discoverPacks,
27552
26195
  dryRunSerializeSpecs,
27553
26196
  effectiveDetail,
27554
26197
  emptyExtensions,
27555
26198
  ensureDir,
27556
26199
  ensureProjectInitialized,
27557
- exportSddSkills,
27558
26200
  exportSpecTree,
27559
- exportSurface,
27560
26201
  externalizeSubsystem,
27561
- extractTreeArchive,
27562
26202
  extractTypeIdentifiers,
27563
26203
  factsFor,
27564
26204
  fieldTypeRefs,
27565
26205
  fieldTypesOf,
27566
- findChainingParent,
27567
- findChainingSubprojectsMissingConfig,
27568
- findLegacySpecFiles,
27569
26206
  findProjectRoot,
27570
26207
  findSystemRoot,
27571
- findTestsReferencing,
27572
- fromOpenApi,
27573
26208
  fromProjectRoot,
27574
26209
  generateAgent,
27575
26210
  generateAll,
27576
26211
  generateComponentDiagram,
27577
26212
  generateDiagramSet,
27578
26213
  generateSequenceDiagram,
27579
- getComponentPath,
27580
26214
  getExporter,
27581
- getGroupPath,
27582
- getImplementationPath,
27583
- getInterfacePath,
27584
- getLoaderIssues,
27585
26215
  getProjectRoot,
27586
26216
  getProjectRootOverride,
27587
26217
  getRequestParentReach,
27588
26218
  getRequestProjectRoot,
27589
- getSnapshot,
27590
- getSubprojectPrefix,
27591
- getSubsystemPath,
27592
- getTypePath,
26219
+ getStatusReport,
27593
26220
  globalGuideFilePath,
27594
26221
  globalPacksDir,
27595
- globalPacksEnabled,
27596
26222
  globalTemplatesDir,
27597
- globalVariantsDir,
27598
- hasAuthoredSpecs,
27599
26223
  hasContext,
27600
26224
  hasFunctionBody,
27601
- hasSpecTree,
27602
26225
  headNoun,
27603
26226
  holdsState,
27604
26227
  implementationSourceFiles,
27605
26228
  importBindingOf,
27606
26229
  importSpecTree,
27607
- importSurface,
27608
- ineffectiveDeltaPaths,
27609
26230
  injectGuide,
27610
- inspectChainedRoots,
27611
- inspectTreeArchive,
27612
26231
  installPackFromDirectory,
27613
26232
  interfaceGenericParameters,
27614
26233
  internalizeSubsystem,
27615
- invalidateSpecCache,
27616
26234
  isDraftSubsystem,
27617
26235
  isLogic,
27618
- isOpenApiDocument,
27619
26236
  isPattern,
27620
26237
  isProjectInitialized,
27621
26238
  isProvidedBy,
27622
26239
  isRetired,
27623
- listChainedRoots,
27624
26240
  listDirectChainedSubprojects,
27625
- listExternalInterfaces,
27626
26241
  listFiles,
27627
26242
  listFilesRecursive,
27628
26243
  listInstalledPacks,
27629
- listMountSnapshots,
27630
- listProjectVariants,
27631
- listResources,
27632
- listRules,
27633
- listSkillNames,
27634
- listSkillResources,
27635
- listSnapshots,
27636
- listTemplateIds,
27637
- loadAgentOverride,
27638
26244
  loadComponentSpec,
27639
26245
  loadComponentSpecs,
27640
26246
  loadExtensionPacks,
27641
26247
  loadExtensions,
27642
- loadGroupSpec,
27643
- loadGroupSpecs,
27644
26248
  loadImplementationSpec,
27645
26249
  loadImplementationSpecs,
27646
26250
  loadInterfaceSpec,
27647
26251
  loadInterfaceSpecs,
27648
- loadMountSurfaceSnapshots,
27649
26252
  loadProjectConfig,
27650
26253
  loadProjectExtensions,
27651
- loadProjectVariants,
27652
26254
  loadRegistry,
27653
26255
  loadSpecGraph,
27654
26256
  loadSubsystemSpec,
27655
26257
  loadSubsystemSpecs,
27656
- loadSurfaceSnapshots,
27657
26258
  loadSystemSpec,
27658
- loadTemplate,
27659
26259
  loadTopologyConfig,
27660
26260
  loadTypeSpec,
27661
26261
  loadTypeSpecs,
@@ -27673,49 +26273,30 @@ function loadProjectConfig4() {
27673
26273
  moveSubsystemProject,
27674
26274
  movedChildren,
27675
26275
  narrativeStepForeignFields,
27676
- normalizeApprover,
27677
- normalizeComponentLayout,
27678
- packDirEntry,
27679
- packEntryLabel,
27680
- packEntryRef,
27681
26276
  packStoreDir,
27682
26277
  parseDeclaredCall,
27683
- parseTemplate,
27684
26278
  parseYaml,
27685
26279
  passesIntentFloor,
27686
26280
  pathExists,
27687
26281
  pathKey,
27688
- pinFamilySurfaces,
27689
- pinInstalledPacksAsSelections,
27690
- projectChildSurface,
27691
26282
  projectConfigExists,
27692
- projectOwnSurface,
27693
- projectSubsystemSurface,
27694
26283
  provisionProject,
27695
26284
  qualifiedTypeId,
27696
26285
  readFileOrNull,
27697
26286
  readJsonFile,
27698
26287
  readLockRecord,
27699
- readLockRecordAt,
27700
26288
  readLockState,
27701
- readManifest,
27702
- readResource,
27703
- readSkillResource,
27704
26289
  readStampVersion,
27705
26290
  readYamlFile,
27706
- rebaseProjectVariants,
27707
- rebaseReference,
27708
26291
  recordProfileSelection,
27709
26292
  registerExporter,
27710
26293
  registerPackRef,
27711
26294
  reinjectLocalGuides,
27712
26295
  removeDomain,
27713
26296
  removePackSelection,
27714
- removeSnapshot,
27715
26297
  renameComponent,
27716
26298
  renameMethod,
27717
26299
  renderDiagram,
27718
- renderTemplateInstructions,
27719
26300
  repairForeignStepFields,
27720
26301
  resolveAgentTopology,
27721
26302
  resolveBudget,
@@ -27724,47 +26305,31 @@ function loadProjectConfig4() {
27724
26305
  resolveExpectedOutputPaths,
27725
26306
  resolveImport,
27726
26307
  resolveInstalledPack,
27727
- resolvePackRef,
27728
26308
  resolveSubprojectForNamespace,
27729
- resolveVariantGuidance,
27730
- restoreSpecFiles,
27731
26309
  retireSpecialists,
27732
- rewriteSpecRefs,
27733
26310
  runWithProjectBinding,
27734
26311
  runWithProjectRoot,
27735
26312
  sameContract,
27736
26313
  saveComponentSpec,
27737
- saveGroupSpec,
27738
26314
  saveImplementationSpec,
27739
26315
  saveInterfaceSpec,
27740
- saveSnapshot,
27741
26316
  saveSubsystemSpec,
27742
26317
  saveSystemSpec,
27743
26318
  saveTopologyConfig,
27744
26319
  saveTypeSpec,
27745
- scanAllSpecs,
27746
26320
  serializeYaml,
27747
26321
  setExecutionTier,
27748
26322
  setLogLevel,
27749
26323
  setProjectRoot,
27750
26324
  setProjectType,
27751
26325
  settledSpecPaths,
27752
- skillExtendErrors,
27753
- skillsDirForTarget,
27754
- snapshotSpecFiles,
27755
- specChanges,
27756
- specKind,
27757
26326
  specPathsInScope,
27758
26327
  splitNamespace,
27759
- stateIdEquals,
27760
- stateIdString,
27761
26328
  stepConfigVerdict,
27762
26329
  stepFieldsFor,
27763
26330
  stepGraph,
27764
26331
  syncContextFiles,
27765
26332
  toMarkdown,
27766
- toOpenApi,
27767
- toOpenApiSet,
27768
26333
  typeBindingOf,
27769
26334
  typeGenericParameters,
27770
26335
  typeMatchesRef,
@@ -27772,12 +26337,7 @@ function loadProjectConfig4() {
27772
26337
  uninstallPack,
27773
26338
  updateSpec,
27774
26339
  upsertPackSelection,
27775
- validateAsComplete,
27776
- validateComponentCandidate,
27777
- validateProjectConfig,
27778
- validateRegistry,
27779
26340
  validateSddTree,
27780
- workspaceFor,
27781
26341
  writeFile,
27782
26342
  writeFileIfChanged,
27783
26343
  writeJsonFile,