@wairon/cli 5.0.2-dev.5 → 5.0.2-dev.7

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/index.js CHANGED
@@ -393,7 +393,7 @@ var init_template = __esm({
393
393
  });
394
394
 
395
395
  // src/models/specs.ts
396
- var import_zod6, SpecIdSchema, SpecStatusSchema, BoundaryItemSchema, RequirementItemSchema, DatabaseSpecSchema, DiagramConfigSchema, SURFACE_AUDIENCES, SurfaceAudienceSchema, SystemPublicInterfaceSchema, SystemSpecSchema, PublicInterfaceTypeSchema, PublicInterfaceSchema, TrustedLinkSchema, LintAllowSchema, LintConfigSchema, ExtDataSchema, LifecycleEntrypointSchema, SubsystemSpecSchema, ComponentTypeSchema, PATTERN_TYPES, PortalTypeSchema, DispatchBindingSchema, DurabilitySchema, PatternRefSchema, EventBindingSchema, ComponentSpecSchema, HttpMethodSchema, TransportSchema, EndpointSchema, SEMANTIC_GUARANTEES, GuaranteeSchema, MethodParamSchema, MethodSignatureSchema, InterfaceSpecSchema, NarrativeStepTypeSchema, LoopKindSchema, SwitchCaseSchema, CatchClauseSchema, ParallelBranchSchema, NarrativeStepSchema, NarrativeDetailSchema, ConformanceTierSchema, MethodImplementationSchema, ImplementationSpecSchema, TypeKindSchema, TypeFieldSchema, TypeMethodSchema, InvariantSchema, TypeSpecSchema, SurfaceOriginSchema, SurfaceTypeDefSchema, SurfaceContractEntrySchema, SurfaceSnapshotSchema, GroupSpecSchema;
396
+ var import_zod6, SpecIdSchema, SpecStatusSchema, BoundaryItemSchema, RequirementItemSchema, DatabaseSpecSchema, DiagramConfigSchema, SURFACE_AUDIENCES, SurfaceAudienceSchema, SystemPublicInterfaceSchema, SystemSpecSchema, PublicInterfaceTypeSchema, PublicInterfaceSchema, TrustedLinkSchema, LintAllowSchema, LintConfigSchema, ExtDataSchema, LifecycleEntrypointSchema, SubsystemSpecSchema, ComponentTypeSchema, PATTERN_TYPES, PortalTypeSchema, DispatchBindingSchema, DurabilitySchema, PatternRefSchema, EventBindingSchema, ExternalLinkTypeSchema, ExternalLinkSchema, ComponentSpecSchema, HttpMethodSchema, TransportSchema, EndpointSchema, SEMANTIC_GUARANTEES, GuaranteeSchema, MethodParamSchema, MethodSignatureSchema, InterfaceSpecSchema, NarrativeStepTypeSchema, LoopKindSchema, SwitchCaseSchema, CatchClauseSchema, ParallelBranchSchema, NarrativeStepSchema, NarrativeDetailSchema, ConformanceTierSchema, MethodImplementationSchema, ImplementationSpecSchema, TypeKindSchema, TypeFieldSchema, TypeMethodSchema, InvariantSchema, TypeSpecSchema, SurfaceOriginSchema, SurfaceTypeDefSchema, SurfaceContractEntrySchema, SurfaceSnapshotSchema, GroupSpecSchema;
397
397
  var init_specs = __esm({
398
398
  "src/models/specs.ts"() {
399
399
  "use strict";
@@ -597,6 +597,13 @@ var init_specs = __esm({
597
597
  event: import_zod6.z.string().optional(),
598
598
  description: import_zod6.z.string().optional()
599
599
  });
600
+ ExternalLinkTypeSchema = import_zod6.z.enum(["implementation", "informative"]);
601
+ ExternalLinkSchema = import_zod6.z.object({
602
+ url: import_zod6.z.string(),
603
+ /** Defaults to 'informative' so an untyped link never silently satisfies the source requirement. */
604
+ type: ExternalLinkTypeSchema.default("informative"),
605
+ label: import_zod6.z.string().optional()
606
+ });
600
607
  ComponentSpecSchema = import_zod6.z.object({
601
608
  id: SpecIdSchema,
602
609
  name: import_zod6.z.string(),
@@ -622,6 +629,11 @@ var init_specs = __esm({
622
629
  patterns: import_zod6.z.array(PatternRefSchema).optional(),
623
630
  /** Optional component variant — a declared, base-anchored specialization of this component's stereotype (resolved against the variant registry; UNKNOWN_VARIANT / VARIANT_BASE_MISMATCH). */
624
631
  variant: import_zod6.z.string().optional(),
632
+ /** Opaque external references (see ExternalLinkSchema) — documented URLs wairon does
633
+ * not fetch or validate. An `implementation` link is the external source-of-record and
634
+ * satisfies the source requirement for a source-less implementation (suppresses
635
+ * MISSING_SOURCE_PATH); `informative` links are context only. */
636
+ externalLinks: import_zod6.z.array(ExternalLinkSchema).optional(),
625
637
  /** Per-spec lint suppressions (see LintConfigSchema). */
626
638
  lint: LintConfigSchema.optional(),
627
639
  /** Opaque pack/tool extension data (see ExtDataSchema) — preserved verbatim. */
@@ -1998,6 +2010,7 @@ function buildCanvasModel(issues = []) {
1998
2010
  ...ownerOf.has(comp.id) ? { owner: ownerOf.get(comp.id) } : {},
1999
2011
  owns: comp.owns.filter((o) => componentIds.has(o)),
2000
2012
  dependsOn: comp.dependsOn,
2013
+ ...comp.externalLinks && comp.externalLinks.length ? { externalLinks: comp.externalLinks } : {},
2001
2014
  interfaces: compInterfaces.map((i) => ({
2002
2015
  id: i.id,
2003
2016
  name: i.name,
@@ -5418,6 +5431,14 @@ var MODEL = __MODEL_JSON__;
5418
5431
  if (!exposes || !openApiAllowed()) return '';
5419
5432
  return '<div class="openbtn"><button class="tbtn" data-openapi-tag="' + esc(tag || '') + '">\\u25A4 View OpenAPI \\u2197</button></div>';
5420
5433
  }
5434
+ // "Open in Specs" \u2014 deep-links the focused spec into the hosted Specs value
5435
+ // editor via a host hook (opts.onOpenSpec). Hidden when no host provides it
5436
+ // (standalone file, shared page): those have no editor to open. kind is the
5437
+ // spec layer, id its qualified spec id.
5438
+ function openSpecButton(kind, id) {
5439
+ if (typeof opts === 'undefined' || !opts || typeof opts.onOpenSpec !== 'function') return '';
5440
+ return '<div class="openbtn"><button class="tbtn" data-openspec-kind="' + kind + '" data-openspec-id="' + esc(id) + '">\\u270E Open in Specs \\u2197</button></div>';
5441
+ }
5421
5442
 
5422
5443
  function renderPanel() {
5423
5444
  var head = '', body = '';
@@ -5440,7 +5461,8 @@ var MODEL = __MODEL_JSON__;
5440
5461
  + (scopeFocus ? staticChip('current view') : '')
5441
5462
  + chip(c.subsystem, 'subsystem', c.subsystem)
5442
5463
  + (scopeFocus ? '' : openViewButton('component', c.id, c.owns.length > 0))
5443
- + openApiButton(componentExposesApi(c), c.apiTag);
5464
+ + openApiButton(componentExposesApi(c), c.apiTag)
5465
+ + openSpecButton('component', c.id);
5444
5466
 
5445
5467
  var linkedTypes = MODEL.types.filter(function (t) { return t.componentClass === c.id; });
5446
5468
  if (linkedTypes.length) {
@@ -5450,6 +5472,14 @@ var MODEL = __MODEL_JSON__;
5450
5472
  }
5451
5473
  body += '<p class="desc">' + esc(c.description) + '</p>';
5452
5474
 
5475
+ if (c.externalLinks && c.externalLinks.length) {
5476
+ body += section('External links', c.externalLinks.length, c.externalLinks.map(function (l) {
5477
+ var label = l.label || l.url;
5478
+ var tag = l.type === 'implementation' ? staticChip('source') : '';
5479
+ return '<div class="method">' + tag + '<a href="' + esc(l.url) + '" target="_blank" rel="noopener" style="color:var(--accent);word-break:break-all">' + esc(label) + ' \\u2197</a></div>';
5480
+ }).join(''), true);
5481
+ }
5482
+
5453
5483
  var depInner = (c.dependsOn.length ? c.dependsOn.map(function (d) { return chip(d, 'component', d); }).join('') : '<span class="desc">none</span>')
5454
5484
  + (c.owns.length ? '<div style="margin-top:8px"><b style="font-size:11px">Owns:</b><br>' + c.owns.map(function (d) { return chip(d, 'component', d); }).join('') + '</div>' : '');
5455
5485
  body += section('Dependencies', c.dependsOn.length + c.owns.length, depInner, true);
@@ -5524,7 +5554,8 @@ var MODEL = __MODEL_JSON__;
5524
5554
  MODEL.types.forEach(function (t2) { if (t2.id === focusId) ty = t2; });
5525
5555
  if (ty) {
5526
5556
  head = '<h2>' + esc(ty.name) + '</h2>' + staticChip('\\u00AB' + ty.kind + '\\u00BB')
5527
- + (ty.subsystem ? chip(ty.subsystem, 'subsystem', ty.subsystem) : staticChip('system-level shared'));
5557
+ + (ty.subsystem ? chip(ty.subsystem, 'subsystem', ty.subsystem) : staticChip('system-level shared'))
5558
+ + openSpecButton('type', ty.id);
5528
5559
 
5529
5560
  if (ty.componentClass) {
5530
5561
  head += '<div style="margin-top:6px"><b style="font-size:11px">Class Component:</b> ' + chip(ty.componentClass, 'component', ty.componentClass) + '</div>';
@@ -5600,7 +5631,8 @@ var MODEL = __MODEL_JSON__;
5600
5631
  + (s.status ? staticChip(s.status) : '')
5601
5632
  + (scopeFocus ? staticChip('current view') : '')
5602
5633
  + (scopeFocus ? '' : openViewButton('subsystem', s.id, subKids > 0))
5603
- + openApiButton(subsystemExposesApi(s.id), '');
5634
+ + openApiButton(subsystemExposesApi(s.id), '')
5635
+ + openSpecButton('subsystem', s.id);
5604
5636
  body += '<p class="desc">' + esc(s.description) + '</p>';
5605
5637
  if (s.trustedLinks.length) {
5606
5638
  body += section('Trusted links (fast lanes)', s.trustedLinks.length, s.trustedLinks.map(function (t2) {
@@ -5658,6 +5690,16 @@ var MODEL = __MODEL_JSON__;
5658
5690
  });
5659
5691
  })(oapis[oi]);
5660
5692
  }
5693
+ var ospecs = panel.querySelectorAll('[data-openspec-kind]');
5694
+ for (var si = 0; si < ospecs.length; si++) {
5695
+ (function (b) {
5696
+ b.addEventListener('click', function () {
5697
+ if (typeof opts !== 'undefined' && opts && typeof opts.onOpenSpec === 'function') {
5698
+ opts.onOpenSpec(b.getAttribute('data-openspec-kind'), b.getAttribute('data-openspec-id') || '');
5699
+ }
5700
+ });
5701
+ })(ospecs[si]);
5702
+ }
5661
5703
  var flows = panel.querySelectorAll('[data-flow-comp]');
5662
5704
  for (var j = 0; j < flows.length; j++) {
5663
5705
  (function (b) {
@@ -5670,6 +5712,23 @@ var MODEL = __MODEL_JSON__;
5670
5712
  }
5671
5713
 
5672
5714
  renderPanel();
5715
+ // Stage G: a deep link may focus a component and/or open a method's narrative
5716
+ // modal once the seeded view + DOM + cy graph exist. The host parses the URL hash
5717
+ // into opts.initialSelect / opts.initialFlow \u2014 both carry the component id, so this
5718
+ // works whether the seeded view is the component itself or its parent subsystem
5719
+ // (a leaf component has no meaningful "inside", so Specs deep-links open the parent
5720
+ // and focus the component here).
5721
+ (function () {
5722
+ if (typeof opts === 'undefined' || !opts) return;
5723
+ var f = opts.initialFlow, s = opts.initialSelect;
5724
+ var focusComp = (f && f.comp) || (s && s.comp);
5725
+ if (focusComp && compById[focusComp]) {
5726
+ try { select('component', focusComp, true); } catch (e) { /* ignore */ }
5727
+ }
5728
+ if (f && f.comp && f.method && compById[f.comp]) {
5729
+ try { openFlow(f.comp, f.method, f.mode === 'steps' ? 'steps' : 'flow'); } catch (e) { /* ignore */ }
5730
+ }
5731
+ })();
5673
5732
  })();
5674
5733
  </script>
5675
5734
  </body>
@@ -7791,13 +7850,16 @@ var init_conformance = __esm({
7791
7850
  if (isInChainedSubproject(component.subsystem, ctx)) continue;
7792
7851
  const draft = ctx.isImplementationDraft(impl);
7793
7852
  if (!impl.sourcePath) {
7794
- ctx.addIssue(
7795
- "warning",
7796
- "MISSING_SOURCE_PATH",
7797
- `Implementation "${impl.id}" declares no sourcePath \u2014 its contract "${impl.contract}" cannot be structurally checked against code.`,
7798
- impl.id,
7799
- draft
7800
- );
7853
+ const hasExternalSource = (component.externalLinks ?? []).some((l) => l.type === "implementation");
7854
+ if (!hasExternalSource) {
7855
+ ctx.addIssue(
7856
+ "warning",
7857
+ "MISSING_SOURCE_PATH",
7858
+ `Implementation "${impl.id}" declares no sourcePath \u2014 its contract "${impl.contract}" cannot be structurally checked against code.`,
7859
+ impl.id,
7860
+ draft
7861
+ );
7862
+ }
7801
7863
  continue;
7802
7864
  }
7803
7865
  const lookup = lookups.get(normalizeSourcePath(impl.sourcePath));
@@ -12117,6 +12179,28 @@ function buildGraphModel(level) {
12117
12179
  ...t.subsystem ? { parentId: t.subsystem } : {}
12118
12180
  });
12119
12181
  }
12182
+ const componentByInterface = /* @__PURE__ */ new Map();
12183
+ for (const c of model.components) {
12184
+ for (const intf of c.interfaces) componentByInterface.set(intf.id, c.id);
12185
+ }
12186
+ for (const impl of loadImplementationSpecs()) {
12187
+ const componentId = componentByInterface.get(impl.contract);
12188
+ if (!componentId) continue;
12189
+ nodes.push({
12190
+ id: impl.id,
12191
+ label: impl.name,
12192
+ kind: "implementation",
12193
+ level: 4,
12194
+ parentId: componentId,
12195
+ ...impl.status ? { status: impl.status } : {}
12196
+ });
12197
+ candidates.push({ from: componentId, to: impl.id, edgeKind: "owns" });
12198
+ }
12199
+ for (const c of model.components) {
12200
+ for (const memberId of c.owns) {
12201
+ candidates.push({ from: c.id, to: memberId, edgeKind: "owns" });
12202
+ }
12203
+ }
12120
12204
  for (const e of model.edges) {
12121
12205
  candidates.push({ from: e.from, to: e.to, edgeKind: "depends_on" });
12122
12206
  }
@@ -15043,6 +15127,8 @@ __export(src_exports, {
15043
15127
  EndpointSchema: () => EndpointSchema,
15044
15128
  EventBindingSchema: () => EventBindingSchema,
15045
15129
  ExtDataSchema: () => ExtDataSchema,
15130
+ ExternalLinkSchema: () => ExternalLinkSchema,
15131
+ ExternalLinkTypeSchema: () => ExternalLinkTypeSchema,
15046
15132
  GITHUB_REPO: () => GITHUB_REPO,
15047
15133
  GeminiExporter: () => GeminiExporter,
15048
15134
  GroupSpecSchema: () => GroupSpecSchema,
@@ -15327,7 +15413,7 @@ function defaultTargetConfig(type) {
15327
15413
  enabled: true
15328
15414
  };
15329
15415
  }
15330
- var WAIRON_VERSION = "5.0.2-dev.5";
15416
+ var WAIRON_VERSION = "5.0.2-dev.7";
15331
15417
  var GITHUB_REPO = "SYW-Apps/Waffle-AIron";
15332
15418
  var ARCHITECT_AGENT_ID = "agent-architect";
15333
15419
  var ARCHITECT_TEMPLATE_ID = "architect";
@@ -16624,6 +16710,8 @@ init_yaml();
16624
16710
  EndpointSchema,
16625
16711
  EventBindingSchema,
16626
16712
  ExtDataSchema,
16713
+ ExternalLinkSchema,
16714
+ ExternalLinkTypeSchema,
16627
16715
  GITHUB_REPO,
16628
16716
  GeminiExporter,
16629
16717
  GroupSpecSchema,