@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/cli/index.js +1154 -1221
- package/dist/cli/index.js.map +1 -1
- package/dist/index.js +752 -2192
- package/dist/index.js.map +1 -1
- package/package.json +1 -1
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
|
|
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
|
|
3064
|
-
var
|
|
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 =
|
|
3103
|
-
|
|
3104
|
-
|
|
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
|
|
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,
|
|
3116
|
+
walkPackDir(root, path29.join(current2, entry.name), out);
|
|
3117
3117
|
} else if (entry.isFile()) {
|
|
3118
|
-
const absolute =
|
|
3119
|
-
const relative22 =
|
|
3120
|
-
out.push({ path: relative22, contents:
|
|
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) =>
|
|
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 =
|
|
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 =
|
|
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(
|
|
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
|
-
|
|
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
|
-
|
|
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,
|
|
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 =
|
|
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 =
|
|
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
|
|
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,
|
|
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.
|
|
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,
|
|
12365
|
-
const cached = cache.get(
|
|
12182
|
+
const namesAt = (cache, path28, make) => {
|
|
12183
|
+
const cached = cache.get(path28);
|
|
12366
12184
|
if (cached) return cached;
|
|
12367
|
-
const f = facts.get(
|
|
12185
|
+
const f = facts.get(path28);
|
|
12368
12186
|
if (!f) return NO_NAMES;
|
|
12369
12187
|
const built = make(f);
|
|
12370
|
-
cache.set(
|
|
12188
|
+
cache.set(path28, built);
|
|
12371
12189
|
return built;
|
|
12372
12190
|
};
|
|
12373
12191
|
const republished = /* @__PURE__ */ new Map();
|
|
12374
|
-
const republishedFrom = (
|
|
12375
|
-
const cached = republished.get(
|
|
12192
|
+
const republishedFrom = (path28) => {
|
|
12193
|
+
const cached = republished.get(path28);
|
|
12376
12194
|
if (cached) return cached;
|
|
12377
|
-
const out = /* @__PURE__ */ new Set([
|
|
12378
|
-
const queue = [
|
|
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(
|
|
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
|
|
12401
|
-
const f = facts.get(
|
|
12402
|
-
return f?.status === "analyzed" && f.analysisGrade === "exact" ? { path:
|
|
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 = (
|
|
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: (
|
|
12263
|
+
factsAt: (path28) => facts.get(pathKey(path28)),
|
|
12446
12264
|
declarationsAt,
|
|
12447
|
-
anchorsAt: (
|
|
12448
|
-
findingAnchorsAt: (
|
|
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: (
|
|
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: (
|
|
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 = (
|
|
12502
|
-
const cached = imports.get(
|
|
12319
|
+
const importsOf = (path28) => {
|
|
12320
|
+
const cached = imports.get(path28);
|
|
12503
12321
|
if (cached) return cached;
|
|
12504
|
-
const facts = index.factsAt(
|
|
12322
|
+
const facts = index.factsAt(path28);
|
|
12505
12323
|
const out = /* @__PURE__ */ new Set();
|
|
12506
|
-
if (facts?.status === "analyzed") resolveAll(
|
|
12507
|
-
imports.set(
|
|
12324
|
+
if (facts?.status === "analyzed") resolveAll(path28, facts.imports, out);
|
|
12325
|
+
imports.set(path28, out);
|
|
12508
12326
|
return out;
|
|
12509
12327
|
};
|
|
12510
|
-
const tracesOf = (
|
|
12511
|
-
const cached = traces.get(
|
|
12328
|
+
const tracesOf = (path28) => {
|
|
12329
|
+
const cached = traces.get(path28);
|
|
12512
12330
|
if (cached) return cached;
|
|
12513
|
-
const facts = index.factsAt(
|
|
12514
|
-
const out = new Set(importsOf(
|
|
12515
|
-
if (facts?.status === "analyzed") resolveAll(
|
|
12516
|
-
traces.set(
|
|
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
|
|
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: ${
|
|
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
|
|
16574
|
-
const facts = code.factsAt(
|
|
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(
|
|
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 = (
|
|
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 = (
|
|
22054
|
-
out.push(`${
|
|
20929
|
+
const say = (path28, why) => {
|
|
20930
|
+
out.push(`${path28} \u2014 ${why}`);
|
|
22055
20931
|
};
|
|
22056
|
-
const walkValue = (d, m, s,
|
|
20932
|
+
const walkValue = (d, m, s, path28, field) => {
|
|
22057
20933
|
if (Array.isArray(d)) {
|
|
22058
20934
|
if (!Array.isArray(m)) {
|
|
22059
|
-
say(
|
|
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(
|
|
22068
|
-
else if (same(s, d)) say(
|
|
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(
|
|
20950
|
+
say(at(path28, key), "the write did not store this element");
|
|
22075
20951
|
continue;
|
|
22076
20952
|
}
|
|
22077
|
-
walk2(element, mMatch, sMatch, at(
|
|
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(
|
|
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,
|
|
20962
|
+
walk2(d, m, s, path28, field);
|
|
22087
20963
|
return;
|
|
22088
20964
|
}
|
|
22089
|
-
if (!same(m, d)) say(
|
|
22090
|
-
else if (same(s, d)) say(
|
|
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,
|
|
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(
|
|
22103
|
-
else if (still) say(at(
|
|
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(
|
|
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/
|
|
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 =
|
|
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 (!
|
|
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 :
|
|
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 (!
|
|
23697
|
+
if (!fs13.existsSync(oldDir)) {
|
|
25123
23698
|
throw new WaironError(`Subproject directory not found at its current path: ${oldDir}`);
|
|
25124
23699
|
}
|
|
25125
|
-
if (
|
|
23700
|
+
if (fs13.existsSync(newDir)) {
|
|
25126
23701
|
throw new WaironError(`Target directory already exists: ${newDir}`);
|
|
25127
23702
|
}
|
|
25128
|
-
ensureDir(
|
|
25129
|
-
|
|
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 =
|
|
25139
|
-
const f =
|
|
25140
|
-
return f === d || f.startsWith(d +
|
|
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 =
|
|
25153
|
-
if (!
|
|
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 =
|
|
25159
|
-
if (
|
|
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(
|
|
23746
|
+
ensureDir(path17.join(childDir, ".wai", "specs"));
|
|
25172
23747
|
saveSystemSpec(bootstrapSystemSpec(childSystemName, now));
|
|
25173
23748
|
});
|
|
25174
|
-
ensureDir(
|
|
25175
|
-
|
|
23749
|
+
ensureDir(path17.dirname(childFooDir));
|
|
23750
|
+
fs13.renameSync(fooDir, childFooDir);
|
|
25176
23751
|
rebaseImplementationPaths(childFooDir, parentRoot, childDir);
|
|
25177
|
-
patchSubsystemIndex(
|
|
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(
|
|
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 =
|
|
25210
|
-
const childFooDir =
|
|
25211
|
-
if (!
|
|
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 =
|
|
25225
|
-
|
|
25226
|
-
ensureDir(
|
|
25227
|
-
|
|
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(
|
|
23804
|
+
patchSubsystemIndex(path17.join(fooDir, ".index.yaml"), (s) => {
|
|
25230
23805
|
s.parentSystem = parentSystemName;
|
|
25231
23806
|
delete s.projectPath;
|
|
25232
23807
|
});
|
|
25233
|
-
|
|
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 === "" ||
|
|
25312
|
-
const next = toPosixPath(
|
|
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 (!
|
|
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 (
|
|
25390
|
-
|
|
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 (!
|
|
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
|
-
|
|
25407
|
-
const specsRoot =
|
|
25408
|
-
for (let dir =
|
|
25409
|
-
if (
|
|
25410
|
-
|
|
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/
|
|
26036
|
-
var
|
|
26037
|
-
var fs16 = __toESM(require("fs"));
|
|
24808
|
+
// src/exporters/generate.ts
|
|
24809
|
+
var path24 = __toESM(require("path"));
|
|
26038
24810
|
|
|
26039
|
-
// src/
|
|
26040
|
-
|
|
26041
|
-
|
|
26042
|
-
|
|
26043
|
-
|
|
26044
|
-
|
|
26045
|
-
|
|
26046
|
-
}
|
|
26047
|
-
|
|
26048
|
-
|
|
26049
|
-
|
|
26050
|
-
|
|
26051
|
-
|
|
26052
|
-
|
|
26053
|
-
|
|
26054
|
-
|
|
26055
|
-
|
|
26056
|
-
|
|
26057
|
-
|
|
26058
|
-
|
|
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
|
-
|
|
26149
|
-
|
|
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
|
|
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
|
|
26173
|
-
return
|
|
24837
|
+
function mcpServersFor(access) {
|
|
24838
|
+
return access === "none" ? "[]" : void 0;
|
|
26174
24839
|
}
|
|
26175
|
-
function
|
|
26176
|
-
|
|
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
|
-
|
|
26189
|
-
|
|
26190
|
-
|
|
26191
|
-
|
|
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
|
-
|
|
26225
|
-
|
|
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
|
|
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
|
|
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
|
|
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
|
|
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(
|
|
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
|
|
26852
|
-
var
|
|
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
|
|
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) => `${
|
|
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 =
|
|
25338
|
+
const normalized = path26.resolve(abs).split(path26.sep).join("/");
|
|
26865
25339
|
if (mountDirs.some((dir) => normalized.startsWith(dir))) continue;
|
|
26866
|
-
out[
|
|
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(
|
|
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
|
|
25498
|
+
var fs17 = __toESM(require("fs"));
|
|
26979
25499
|
var os5 = __toESM(require("os"));
|
|
26980
|
-
var
|
|
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
|
|
27041
|
-
if (targetType === "gemini") return
|
|
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
|
|
27046
|
-
if (targetType === "gemini" || targetType === "agy") return
|
|
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 =
|
|
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
|
-
|
|
27062
|
-
|
|
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 =
|
|
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
|
-
|
|
25605
|
+
fs17.writeFileSync(filePath, content, "utf-8");
|
|
27086
25606
|
} else if (targetType === "gemini" || targetType === "agy") {
|
|
27087
|
-
const filePath =
|
|
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
|
-
|
|
25614
|
+
fs17.writeFileSync(filePath, content, "utf-8");
|
|
27095
25615
|
} else if (targetType === "cursor") {
|
|
27096
|
-
const filePath =
|
|
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
|
-
|
|
25623
|
+
fs17.writeFileSync(filePath, content, "utf-8");
|
|
27104
25624
|
} else if (targetType === "copilot") {
|
|
27105
|
-
const filePath =
|
|
27106
|
-
|
|
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
|
-
|
|
25633
|
+
fs17.writeFileSync(filePath, content, "utf-8");
|
|
27114
25634
|
} else if (targetType === "codex") {
|
|
27115
|
-
const filePath =
|
|
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
|
-
|
|
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
|
-
|
|
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
|
-
|
|
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,
|