@wairon/cli 5.0.2-dev.5 → 5.0.2-dev.6
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 +128 -10
- package/dist/cli/index.js.map +1 -1
- package/dist/index.js +64 -4
- package/dist/index.js.map +1 -1
- package/package.json +1 -1
package/dist/cli/index.js
CHANGED
|
@@ -65,7 +65,7 @@ var init_defaults = __esm({
|
|
|
65
65
|
copilot: ".github/prompts",
|
|
66
66
|
codex: ".codex/agents"
|
|
67
67
|
};
|
|
68
|
-
WAIRON_VERSION = "5.0.2-dev.
|
|
68
|
+
WAIRON_VERSION = "5.0.2-dev.6";
|
|
69
69
|
GITHUB_REPO = "SYW-Apps/Waffle-AIron";
|
|
70
70
|
ARCHITECT_AGENT_ID = "agent-architect";
|
|
71
71
|
ARCHITECT_TEMPLATE_ID = "architect";
|
|
@@ -6072,6 +6072,14 @@ var MODEL = __MODEL_JSON__;
|
|
|
6072
6072
|
if (!exposes || !openApiAllowed()) return '';
|
|
6073
6073
|
return '<div class="openbtn"><button class="tbtn" data-openapi-tag="' + esc(tag || '') + '">\\u25A4 View OpenAPI \\u2197</button></div>';
|
|
6074
6074
|
}
|
|
6075
|
+
// "Open in Specs" \u2014 deep-links the focused spec into the hosted Specs value
|
|
6076
|
+
// editor via a host hook (opts.onOpenSpec). Hidden when no host provides it
|
|
6077
|
+
// (standalone file, shared page): those have no editor to open. kind is the
|
|
6078
|
+
// spec layer, id its qualified spec id.
|
|
6079
|
+
function openSpecButton(kind, id) {
|
|
6080
|
+
if (typeof opts === 'undefined' || !opts || typeof opts.onOpenSpec !== 'function') return '';
|
|
6081
|
+
return '<div class="openbtn"><button class="tbtn" data-openspec-kind="' + kind + '" data-openspec-id="' + esc(id) + '">\\u270E Open in Specs \\u2197</button></div>';
|
|
6082
|
+
}
|
|
6075
6083
|
|
|
6076
6084
|
function renderPanel() {
|
|
6077
6085
|
var head = '', body = '';
|
|
@@ -6094,7 +6102,8 @@ var MODEL = __MODEL_JSON__;
|
|
|
6094
6102
|
+ (scopeFocus ? staticChip('current view') : '')
|
|
6095
6103
|
+ chip(c.subsystem, 'subsystem', c.subsystem)
|
|
6096
6104
|
+ (scopeFocus ? '' : openViewButton('component', c.id, c.owns.length > 0))
|
|
6097
|
-
+ openApiButton(componentExposesApi(c), c.apiTag)
|
|
6105
|
+
+ openApiButton(componentExposesApi(c), c.apiTag)
|
|
6106
|
+
+ openSpecButton('component', c.id);
|
|
6098
6107
|
|
|
6099
6108
|
var linkedTypes = MODEL.types.filter(function (t) { return t.componentClass === c.id; });
|
|
6100
6109
|
if (linkedTypes.length) {
|
|
@@ -6178,7 +6187,8 @@ var MODEL = __MODEL_JSON__;
|
|
|
6178
6187
|
MODEL.types.forEach(function (t2) { if (t2.id === focusId) ty = t2; });
|
|
6179
6188
|
if (ty) {
|
|
6180
6189
|
head = '<h2>' + esc(ty.name) + '</h2>' + staticChip('\\u00AB' + ty.kind + '\\u00BB')
|
|
6181
|
-
+ (ty.subsystem ? chip(ty.subsystem, 'subsystem', ty.subsystem) : staticChip('system-level shared'))
|
|
6190
|
+
+ (ty.subsystem ? chip(ty.subsystem, 'subsystem', ty.subsystem) : staticChip('system-level shared'))
|
|
6191
|
+
+ openSpecButton('type', ty.id);
|
|
6182
6192
|
|
|
6183
6193
|
if (ty.componentClass) {
|
|
6184
6194
|
head += '<div style="margin-top:6px"><b style="font-size:11px">Class Component:</b> ' + chip(ty.componentClass, 'component', ty.componentClass) + '</div>';
|
|
@@ -6254,7 +6264,8 @@ var MODEL = __MODEL_JSON__;
|
|
|
6254
6264
|
+ (s.status ? staticChip(s.status) : '')
|
|
6255
6265
|
+ (scopeFocus ? staticChip('current view') : '')
|
|
6256
6266
|
+ (scopeFocus ? '' : openViewButton('subsystem', s.id, subKids > 0))
|
|
6257
|
-
+ openApiButton(subsystemExposesApi(s.id), '')
|
|
6267
|
+
+ openApiButton(subsystemExposesApi(s.id), '')
|
|
6268
|
+
+ openSpecButton('subsystem', s.id);
|
|
6258
6269
|
body += '<p class="desc">' + esc(s.description) + '</p>';
|
|
6259
6270
|
if (s.trustedLinks.length) {
|
|
6260
6271
|
body += section('Trusted links (fast lanes)', s.trustedLinks.length, s.trustedLinks.map(function (t2) {
|
|
@@ -6312,6 +6323,16 @@ var MODEL = __MODEL_JSON__;
|
|
|
6312
6323
|
});
|
|
6313
6324
|
})(oapis[oi]);
|
|
6314
6325
|
}
|
|
6326
|
+
var ospecs = panel.querySelectorAll('[data-openspec-kind]');
|
|
6327
|
+
for (var si = 0; si < ospecs.length; si++) {
|
|
6328
|
+
(function (b) {
|
|
6329
|
+
b.addEventListener('click', function () {
|
|
6330
|
+
if (typeof opts !== 'undefined' && opts && typeof opts.onOpenSpec === 'function') {
|
|
6331
|
+
opts.onOpenSpec(b.getAttribute('data-openspec-kind'), b.getAttribute('data-openspec-id') || '');
|
|
6332
|
+
}
|
|
6333
|
+
});
|
|
6334
|
+
})(ospecs[si]);
|
|
6335
|
+
}
|
|
6315
6336
|
var flows = panel.querySelectorAll('[data-flow-comp]');
|
|
6316
6337
|
for (var j = 0; j < flows.length; j++) {
|
|
6317
6338
|
(function (b) {
|
|
@@ -6324,6 +6345,23 @@ var MODEL = __MODEL_JSON__;
|
|
|
6324
6345
|
}
|
|
6325
6346
|
|
|
6326
6347
|
renderPanel();
|
|
6348
|
+
// Stage G: a deep link may focus a component and/or open a method's narrative
|
|
6349
|
+
// modal once the seeded view + DOM + cy graph exist. The host parses the URL hash
|
|
6350
|
+
// into opts.initialSelect / opts.initialFlow \u2014 both carry the component id, so this
|
|
6351
|
+
// works whether the seeded view is the component itself or its parent subsystem
|
|
6352
|
+
// (a leaf component has no meaningful "inside", so Specs deep-links open the parent
|
|
6353
|
+
// and focus the component here).
|
|
6354
|
+
(function () {
|
|
6355
|
+
if (typeof opts === 'undefined' || !opts) return;
|
|
6356
|
+
var f = opts.initialFlow, s = opts.initialSelect;
|
|
6357
|
+
var focusComp = (f && f.comp) || (s && s.comp);
|
|
6358
|
+
if (focusComp && compById[focusComp]) {
|
|
6359
|
+
try { select('component', focusComp, true); } catch (e) { /* ignore */ }
|
|
6360
|
+
}
|
|
6361
|
+
if (f && f.comp && f.method && compById[f.comp]) {
|
|
6362
|
+
try { openFlow(f.comp, f.method, f.mode === 'steps' ? 'steps' : 'flow'); } catch (e) { /* ignore */ }
|
|
6363
|
+
}
|
|
6364
|
+
})();
|
|
6327
6365
|
})();
|
|
6328
6366
|
</script>
|
|
6329
6367
|
</body>
|
|
@@ -12705,6 +12743,28 @@ function buildGraphModel(level) {
|
|
|
12705
12743
|
...t.subsystem ? { parentId: t.subsystem } : {}
|
|
12706
12744
|
});
|
|
12707
12745
|
}
|
|
12746
|
+
const componentByInterface = /* @__PURE__ */ new Map();
|
|
12747
|
+
for (const c of model.components) {
|
|
12748
|
+
for (const intf of c.interfaces) componentByInterface.set(intf.id, c.id);
|
|
12749
|
+
}
|
|
12750
|
+
for (const impl of loadImplementationSpecs()) {
|
|
12751
|
+
const componentId = componentByInterface.get(impl.contract);
|
|
12752
|
+
if (!componentId) continue;
|
|
12753
|
+
nodes.push({
|
|
12754
|
+
id: impl.id,
|
|
12755
|
+
label: impl.name,
|
|
12756
|
+
kind: "implementation",
|
|
12757
|
+
level: 4,
|
|
12758
|
+
parentId: componentId,
|
|
12759
|
+
...impl.status ? { status: impl.status } : {}
|
|
12760
|
+
});
|
|
12761
|
+
candidates.push({ from: componentId, to: impl.id, edgeKind: "owns" });
|
|
12762
|
+
}
|
|
12763
|
+
for (const c of model.components) {
|
|
12764
|
+
for (const memberId of c.owns) {
|
|
12765
|
+
candidates.push({ from: c.id, to: memberId, edgeKind: "owns" });
|
|
12766
|
+
}
|
|
12767
|
+
}
|
|
12708
12768
|
for (const e of model.edges) {
|
|
12709
12769
|
candidates.push({ from: e.from, to: e.to, edgeKind: "depends_on" });
|
|
12710
12770
|
}
|
|
@@ -27670,6 +27730,7 @@ function removeIdentityProviderRecord(dataDir, id) {
|
|
|
27670
27730
|
}
|
|
27671
27731
|
var PROJECT_CREATE_CAPABILITY = "project:create";
|
|
27672
27732
|
var PROJECT_WRITE_CAPABILITY = "project:write";
|
|
27733
|
+
var PROJECT_READ_CAPABILITY = "project:read";
|
|
27673
27734
|
var POLICY_MANAGE_CAPABILITY = "project:admin";
|
|
27674
27735
|
function carriesInstancePermission(cfg, principal, capability) {
|
|
27675
27736
|
return authorize(cfg.dataDir, principal, capability, "instance", "").value === "yes";
|
|
@@ -27734,6 +27795,19 @@ function recordProjectProfileSelection(root, selection) {
|
|
|
27734
27795
|
writeYamlFile(AI_PATHS.projectConfig(), raw);
|
|
27735
27796
|
});
|
|
27736
27797
|
}
|
|
27798
|
+
function readProjectType(root) {
|
|
27799
|
+
return runWithProjectRoot(root, () => {
|
|
27800
|
+
const raw = readYamlFile(AI_PATHS.projectConfig());
|
|
27801
|
+
return raw?.projectType ?? "backend";
|
|
27802
|
+
});
|
|
27803
|
+
}
|
|
27804
|
+
function writeProjectType(root, projectType) {
|
|
27805
|
+
runWithProjectRoot(root, () => {
|
|
27806
|
+
const raw = readYamlFile(AI_PATHS.projectConfig()) ?? {};
|
|
27807
|
+
raw["projectType"] = projectType;
|
|
27808
|
+
writeYamlFile(AI_PATHS.projectConfig(), raw);
|
|
27809
|
+
});
|
|
27810
|
+
}
|
|
27737
27811
|
function requestPackNames(request) {
|
|
27738
27812
|
const sel = request.profileSelection;
|
|
27739
27813
|
if (!sel) return [];
|
|
@@ -27928,6 +28002,32 @@ function reconcileProjectPolicy(cfg, credential, projectId) {
|
|
|
27928
28002
|
);
|
|
27929
28003
|
return result;
|
|
27930
28004
|
}
|
|
28005
|
+
function getProjectConfig(cfg, credential, projectId) {
|
|
28006
|
+
const principal = requirePrincipal4(cfg, credential);
|
|
28007
|
+
if (authorize(cfg.dataDir, principal, PROJECT_READ_CAPABILITY, "project", projectId).value !== "yes") {
|
|
28008
|
+
throw new ForbiddenError(
|
|
28009
|
+
"reading a project's configuration requires project:read over the project"
|
|
28010
|
+
);
|
|
28011
|
+
}
|
|
28012
|
+
const root = resolveProjectRoot(cfg.dataDir, principal, projectId);
|
|
28013
|
+
if (!root) throw new Error(`Unknown project "${projectId}".`);
|
|
28014
|
+
const projectType = readProjectType(root);
|
|
28015
|
+
const locked = runWithProjectRoot(root, () => hostCore.readLockRecord() !== null);
|
|
28016
|
+
return { projectType, locked };
|
|
28017
|
+
}
|
|
28018
|
+
function setProjectType(cfg, credential, projectId, projectType) {
|
|
28019
|
+
const principal = requirePrincipal4(cfg, credential);
|
|
28020
|
+
if (authorize(cfg.dataDir, principal, PROJECT_WRITE_CAPABILITY, "project", projectId).value !== "yes") {
|
|
28021
|
+
throw new ForbiddenError(
|
|
28022
|
+
"changing a project's configuration requires project:write over the project"
|
|
28023
|
+
);
|
|
28024
|
+
}
|
|
28025
|
+
const root = resolveProjectRoot(cfg.dataDir, principal, projectId);
|
|
28026
|
+
if (!root) throw new Error(`Unknown project "${projectId}".`);
|
|
28027
|
+
writeProjectType(root, projectType);
|
|
28028
|
+
const locked = runWithProjectRoot(root, () => hostCore.readLockRecord() !== null);
|
|
28029
|
+
return { projectType, locked };
|
|
28030
|
+
}
|
|
27931
28031
|
function getPackPolicy(cfg, credential) {
|
|
27932
28032
|
requirePrincipal4(cfg, credential);
|
|
27933
28033
|
return getPackPolicyRecord(cfg.dataDir) ?? PERMISSIVE_DEFAULT_POLICY;
|
|
@@ -27991,7 +28091,7 @@ function handlePolicyRequest(cfg, credential, req, res, body, url) {
|
|
|
27991
28091
|
|
|
27992
28092
|
// src/server/identity.ts
|
|
27993
28093
|
var PROJECT_ADMIN_CAPABILITY2 = "project:admin";
|
|
27994
|
-
var
|
|
28094
|
+
var PROJECT_READ_CAPABILITY2 = "project:read";
|
|
27995
28095
|
var PROJECT_WRITE_CAPABILITY2 = "project:write";
|
|
27996
28096
|
function requireInstanceProjectAdmin(cfg, principal, what) {
|
|
27997
28097
|
if (authorize(cfg.dataDir, principal, PROJECT_ADMIN_CAPABILITY2, "instance", "").value !== "yes") {
|
|
@@ -28137,7 +28237,7 @@ function revokeToken(cfg, credential, tokenId) {
|
|
|
28137
28237
|
}
|
|
28138
28238
|
function mintSelfToken(cfg, credential, projectId, write) {
|
|
28139
28239
|
const principal = requirePrincipal5(cfg, credential);
|
|
28140
|
-
if (authorize(cfg.dataDir, principal,
|
|
28240
|
+
if (authorize(cfg.dataDir, principal, PROJECT_READ_CAPABILITY2, "project", projectId).value !== "yes") {
|
|
28141
28241
|
throw new ForbiddenError("caller lacks project:read on the requested project");
|
|
28142
28242
|
}
|
|
28143
28243
|
if (write && authorize(cfg.dataDir, principal, PROJECT_WRITE_CAPABILITY2, "project", projectId).value !== "yes") {
|
|
@@ -28783,7 +28883,7 @@ function audienceDistance(resolution, targetProjectId) {
|
|
|
28783
28883
|
// src/server/landscape.ts
|
|
28784
28884
|
var yamlLib = __toESM(require("js-yaml"));
|
|
28785
28885
|
var PROJECT_ADMIN_CAPABILITY3 = "project:admin";
|
|
28786
|
-
var
|
|
28886
|
+
var PROJECT_READ_CAPABILITY3 = "project:read";
|
|
28787
28887
|
var PROJECT_WRITE_CAPABILITY3 = "project:write";
|
|
28788
28888
|
function requirePrincipal6(cfg, credential) {
|
|
28789
28889
|
const principal = authenticateCredential(cfg.dataDir, credential);
|
|
@@ -28797,7 +28897,7 @@ function readView(cfg, principal) {
|
|
|
28797
28897
|
if (isInstanceAdmin(principal)) {
|
|
28798
28898
|
return { all: true, projectIds: /* @__PURE__ */ new Set(), unitIds: /* @__PURE__ */ new Set(), contextUnitIds: /* @__PURE__ */ new Set() };
|
|
28799
28899
|
}
|
|
28800
|
-
const read = visibleScopes(cfg.dataDir, principal,
|
|
28900
|
+
const read = visibleScopes(cfg.dataDir, principal, PROJECT_READ_CAPABILITY3);
|
|
28801
28901
|
const admin = visibleScopes(cfg.dataDir, principal, PROJECT_ADMIN_CAPABILITY3);
|
|
28802
28902
|
const unitIds = /* @__PURE__ */ new Set([...actionableUnitIds(read), ...actionableUnitIds(admin)]);
|
|
28803
28903
|
const contextUnitIds = new Set(
|
|
@@ -28812,13 +28912,13 @@ function readView(cfg, principal) {
|
|
|
28812
28912
|
}
|
|
28813
28913
|
function requireLandscapeReach(cfg, principal, view, what) {
|
|
28814
28914
|
if (view.all || view.projectIds.size > 0 || view.unitIds.size > 0) return;
|
|
28815
|
-
if (permitsCap(cfg, principal,
|
|
28915
|
+
if (permitsCap(cfg, principal, PROJECT_READ_CAPABILITY3, "instance", "") || permitsCap(cfg, principal, PROJECT_ADMIN_CAPABILITY3, "instance", "")) {
|
|
28816
28916
|
return;
|
|
28817
28917
|
}
|
|
28818
28918
|
throw new ForbiddenError(`${what} requires project:read reach`);
|
|
28819
28919
|
}
|
|
28820
28920
|
function requireObserverScope(cfg, principal, observerProjectId) {
|
|
28821
|
-
const covered = permitsCap(cfg, principal,
|
|
28921
|
+
const covered = permitsCap(cfg, principal, PROJECT_READ_CAPABILITY3, "project", observerProjectId) || permitsCap(cfg, principal, PROJECT_WRITE_CAPABILITY3, "project", observerProjectId);
|
|
28822
28922
|
if (!covered) {
|
|
28823
28923
|
throw new ForbiddenError("caller lacks scope over the current project");
|
|
28824
28924
|
}
|
|
@@ -30876,6 +30976,12 @@ function evaluateProjectPolicy2(cfg, credential, projectId) {
|
|
|
30876
30976
|
function reconcileProjectPolicy2(cfg, credential, projectId) {
|
|
30877
30977
|
return reconcileProjectPolicy(cfg, credential, projectId);
|
|
30878
30978
|
}
|
|
30979
|
+
function getProjectConfig2(cfg, credential, projectId) {
|
|
30980
|
+
return getProjectConfig(cfg, credential, projectId);
|
|
30981
|
+
}
|
|
30982
|
+
function setProjectType2(cfg, credential, projectId, projectType) {
|
|
30983
|
+
return setProjectType(cfg, credential, projectId, projectType);
|
|
30984
|
+
}
|
|
30879
30985
|
function listProducers2(cfg, credential, project2) {
|
|
30880
30986
|
return listProducers(cfg, credential, project2);
|
|
30881
30987
|
}
|
|
@@ -34178,6 +34284,12 @@ function opsPolicyEvaluate(cfg, sessionId, url, res) {
|
|
|
34178
34284
|
function opsPolicyReconcile(cfg, sessionId, body, res) {
|
|
34179
34285
|
sendJson(res, 200, reconcileProjectPolicy2(cfg, sessionId, String(body?.projectId ?? "")));
|
|
34180
34286
|
}
|
|
34287
|
+
function opsGetProjectConfig(cfg, sessionId, url, res) {
|
|
34288
|
+
sendJson(res, 200, getProjectConfig2(cfg, sessionId, q(url, "projectId") ?? ""));
|
|
34289
|
+
}
|
|
34290
|
+
function opsSetProjectConfig(cfg, sessionId, body, res) {
|
|
34291
|
+
sendJson(res, 200, setProjectType2(cfg, sessionId, String(body?.projectId ?? ""), String(body?.projectType ?? "")));
|
|
34292
|
+
}
|
|
34181
34293
|
function opsListProducers(cfg, sessionId, url, res) {
|
|
34182
34294
|
sendJson(res, 200, { producers: listProducers2(cfg, sessionId, q(url, "projectId") ?? "") });
|
|
34183
34295
|
}
|
|
@@ -34410,6 +34522,12 @@ async function handleWebRequest(cfg, req, res, body, url, ctx) {
|
|
|
34410
34522
|
if (req.method === "POST" && parts.length === 4 && parts[2] === "packs" && parts[3] === "adopt") {
|
|
34411
34523
|
return opsAdoptProjectPack(cfg, sessionId, body, res);
|
|
34412
34524
|
}
|
|
34525
|
+
if (req.method === "GET" && parts.length === 3 && parts[2] === "config") {
|
|
34526
|
+
return opsGetProjectConfig(cfg, sessionId, url, res);
|
|
34527
|
+
}
|
|
34528
|
+
if (req.method === "POST" && parts.length === 3 && parts[2] === "config") {
|
|
34529
|
+
return opsSetProjectConfig(cfg, sessionId, body, res);
|
|
34530
|
+
}
|
|
34413
34531
|
if (req.method === "GET" && parts.length === 3 && parts[2] === "policy") {
|
|
34414
34532
|
return opsPolicyEvaluate(cfg, sessionId, url, res);
|
|
34415
34533
|
}
|