musubix2 0.5.61 → 0.5.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/.claude/.musubix-managed +1 -1
- package/dist/assets/skills-manifest.json +1 -1
- package/dist/cli.js +48 -9
- package/dist/index.js +48 -9
- package/package.json +1 -1
package/.claude/.musubix-managed
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"generator":"musubix2","version":"0.5.
|
|
1
|
+
{"generator":"musubix2","version":"0.5.63","timestamp":"2026-07-10T20:51:46.354Z"}
|
package/dist/cli.js
CHANGED
|
@@ -2808,7 +2808,8 @@ var init_design = __esm({
|
|
|
2808
2808
|
if (reqs.length === 1) {
|
|
2809
2809
|
const r = reqs[0];
|
|
2810
2810
|
const sig = deriveMethodSignature(r.text, r.title);
|
|
2811
|
-
const
|
|
2811
|
+
const base = this.pascal(r.title) || this.pascal(sig.name) || "Component";
|
|
2812
|
+
const compName = base + (/(service|manager|controller|repository)$/i.test(base) ? "" : "Service");
|
|
2812
2813
|
return [{
|
|
2813
2814
|
name: compName,
|
|
2814
2815
|
responsibility: r.title || `Handle ${r.id}`,
|
|
@@ -2863,12 +2864,10 @@ var init_design = __esm({
|
|
|
2863
2864
|
}
|
|
2864
2865
|
return [...entities];
|
|
2865
2866
|
}
|
|
2867
|
+
/** PascalCase the ASCII words of a string; returns '' if none survive (e.g. a
|
|
2868
|
+
* fully non-ASCII title), so callers can fall back to another name source. */
|
|
2866
2869
|
pascal(text) {
|
|
2867
|
-
|
|
2868
|
-
if (words.length === 0) {
|
|
2869
|
-
return "Component";
|
|
2870
|
-
}
|
|
2871
|
-
return words.map((w) => w.replace(/[^A-Za-z0-9]/g, "")).filter(Boolean).map((w) => w.charAt(0).toUpperCase() + w.slice(1)).join("");
|
|
2870
|
+
return text.split(/[\s_\-,、]+/).map((w) => w.replace(/[^A-Za-z0-9]/g, "")).filter(Boolean).map((w) => w.charAt(0).toUpperCase() + w.slice(1)).join("");
|
|
2872
2871
|
}
|
|
2873
2872
|
suggestInterfaces(reqs) {
|
|
2874
2873
|
const interfaces = [];
|
|
@@ -12588,7 +12587,7 @@ var init_dist14 = __esm({
|
|
|
12588
12587
|
warnings
|
|
12589
12588
|
};
|
|
12590
12589
|
}
|
|
12591
|
-
const
|
|
12590
|
+
const symbols = /* @__PURE__ */ new Set([actionVar]);
|
|
12592
12591
|
const negated = /\bSHALL\s+NOT\b/i.test(requirement.text);
|
|
12593
12592
|
const actionExpr = negated ? `(not ${actionVar})` : actionVar;
|
|
12594
12593
|
let assertions;
|
|
@@ -12598,6 +12597,7 @@ var init_dist14 = __esm({
|
|
|
12598
12597
|
break;
|
|
12599
12598
|
case "event-driven": {
|
|
12600
12599
|
const triggerVar = requirement.trigger ? sanitizeName(requirement.trigger) : "trigger";
|
|
12600
|
+
symbols.add(triggerVar);
|
|
12601
12601
|
assertions = [`(assert (=> ${triggerVar} ${actionExpr}))`];
|
|
12602
12602
|
if (!requirement.trigger) {
|
|
12603
12603
|
warnings.push('No trigger specified; using default "trigger"');
|
|
@@ -12606,6 +12606,7 @@ var init_dist14 = __esm({
|
|
|
12606
12606
|
}
|
|
12607
12607
|
case "state-driven": {
|
|
12608
12608
|
const condVar = requirement.condition ? sanitizeName(requirement.condition) : "condition";
|
|
12609
|
+
symbols.add(condVar);
|
|
12609
12610
|
assertions = [`(assert (=> ${condVar} ${actionExpr}))`];
|
|
12610
12611
|
if (!requirement.condition) {
|
|
12611
12612
|
warnings.push('No condition specified; using default "condition"');
|
|
@@ -12614,13 +12615,16 @@ var init_dist14 = __esm({
|
|
|
12614
12615
|
}
|
|
12615
12616
|
case "unwanted":
|
|
12616
12617
|
if (requirement.condition) {
|
|
12617
|
-
|
|
12618
|
+
const condVar = sanitizeName(requirement.condition);
|
|
12619
|
+
symbols.add(condVar);
|
|
12620
|
+
assertions = [`(assert (=> ${condVar} ${actionExpr}))`];
|
|
12618
12621
|
} else {
|
|
12619
12622
|
assertions = [`(assert ${actionExpr})`];
|
|
12620
12623
|
}
|
|
12621
12624
|
break;
|
|
12622
12625
|
case "optional": {
|
|
12623
12626
|
const featureVar = requirement.trigger ? sanitizeName(requirement.trigger) : "feature_enabled";
|
|
12627
|
+
symbols.add(featureVar);
|
|
12624
12628
|
assertions = [`(assert (=> ${featureVar} ${actionExpr}))`];
|
|
12625
12629
|
if (!requirement.trigger) {
|
|
12626
12630
|
warnings.push('No feature trigger specified; using default "feature_enabled"');
|
|
@@ -12630,6 +12634,8 @@ var init_dist14 = __esm({
|
|
|
12630
12634
|
case "complex": {
|
|
12631
12635
|
const condVar = requirement.condition ? sanitizeName(requirement.condition) : "condition";
|
|
12632
12636
|
const triggerVar = requirement.trigger ? sanitizeName(requirement.trigger) : "trigger";
|
|
12637
|
+
symbols.add(condVar);
|
|
12638
|
+
symbols.add(triggerVar);
|
|
12633
12639
|
assertions = [`(assert (=> (and ${condVar} ${triggerVar}) ${actionExpr}))`];
|
|
12634
12640
|
if (!requirement.condition) {
|
|
12635
12641
|
warnings.push('No condition specified; using default "condition"');
|
|
@@ -12641,6 +12647,7 @@ var init_dist14 = __esm({
|
|
|
12641
12647
|
}
|
|
12642
12648
|
}
|
|
12643
12649
|
const id = makeFormulaId(requirement.id);
|
|
12650
|
+
const variables = [...symbols].map((name) => ({ name, sort: "Bool" }));
|
|
12644
12651
|
const formula = {
|
|
12645
12652
|
id,
|
|
12646
12653
|
requirementId: requirement.id,
|
|
@@ -12777,7 +12784,7 @@ var init_dist14 = __esm({
|
|
|
12777
12784
|
mockSolve(smtScript) {
|
|
12778
12785
|
const start = Date.now();
|
|
12779
12786
|
try {
|
|
12780
|
-
if (smtScript.includes("(assert false)")) {
|
|
12787
|
+
if (smtScript.includes("(assert false)") || this.hasBooleanContradiction(smtScript)) {
|
|
12781
12788
|
return {
|
|
12782
12789
|
status: "unsat",
|
|
12783
12790
|
time: Date.now() - start
|
|
@@ -12802,6 +12809,38 @@ var init_dist14 = __esm({
|
|
|
12802
12809
|
};
|
|
12803
12810
|
}
|
|
12804
12811
|
}
|
|
12812
|
+
/**
|
|
12813
|
+
* Detect a basic Boolean contradiction without a real solver: an atom that is
|
|
12814
|
+
* *unconditionally* forced both true and false. Covers the common EARS cases —
|
|
12815
|
+
* `SHALL X` (`(=> true X)` or `(assert X)`) versus `SHALL NOT X`
|
|
12816
|
+
* (`(not X)`) — so `verify` flags e.g. "grant access" / "not grant access".
|
|
12817
|
+
* Conditional assertions (`(=> cond X)` with cond ≠ true) are not forcing and
|
|
12818
|
+
* are ignored. This is a sound-but-incomplete check (real z3 covers the rest).
|
|
12819
|
+
*/
|
|
12820
|
+
hasBooleanContradiction(smtScript) {
|
|
12821
|
+
const forced = /* @__PURE__ */ new Map();
|
|
12822
|
+
let contradiction = false;
|
|
12823
|
+
const set = (atom, value) => {
|
|
12824
|
+
if (forced.has(atom) && forced.get(atom) !== value) {
|
|
12825
|
+
contradiction = true;
|
|
12826
|
+
}
|
|
12827
|
+
forced.set(atom, value);
|
|
12828
|
+
};
|
|
12829
|
+
for (const raw of smtScript.split("\n")) {
|
|
12830
|
+
const line = raw.trim();
|
|
12831
|
+
let m;
|
|
12832
|
+
if (m = /^\(assert \(=> true \(not (\w+)\)\)\)$/.exec(line)) {
|
|
12833
|
+
set(m[1], false);
|
|
12834
|
+
} else if (m = /^\(assert \(=> true (\w+)\)\)$/.exec(line)) {
|
|
12835
|
+
set(m[1], true);
|
|
12836
|
+
} else if (m = /^\(assert \(not (\w+)\)\)$/.exec(line)) {
|
|
12837
|
+
set(m[1], false);
|
|
12838
|
+
} else if (m = /^\(assert (\w+)\)$/.exec(line)) {
|
|
12839
|
+
set(m[1], true);
|
|
12840
|
+
}
|
|
12841
|
+
}
|
|
12842
|
+
return contradiction;
|
|
12843
|
+
}
|
|
12805
12844
|
};
|
|
12806
12845
|
PreconditionVerifier = class {
|
|
12807
12846
|
async verify(requirement, converter, solver) {
|
package/dist/index.js
CHANGED
|
@@ -2808,7 +2808,8 @@ var init_design = __esm({
|
|
|
2808
2808
|
if (reqs.length === 1) {
|
|
2809
2809
|
const r = reqs[0];
|
|
2810
2810
|
const sig = deriveMethodSignature(r.text, r.title);
|
|
2811
|
-
const
|
|
2811
|
+
const base = this.pascal(r.title) || this.pascal(sig.name) || "Component";
|
|
2812
|
+
const compName = base + (/(service|manager|controller|repository)$/i.test(base) ? "" : "Service");
|
|
2812
2813
|
return [{
|
|
2813
2814
|
name: compName,
|
|
2814
2815
|
responsibility: r.title || `Handle ${r.id}`,
|
|
@@ -2863,12 +2864,10 @@ var init_design = __esm({
|
|
|
2863
2864
|
}
|
|
2864
2865
|
return [...entities];
|
|
2865
2866
|
}
|
|
2867
|
+
/** PascalCase the ASCII words of a string; returns '' if none survive (e.g. a
|
|
2868
|
+
* fully non-ASCII title), so callers can fall back to another name source. */
|
|
2866
2869
|
pascal(text) {
|
|
2867
|
-
|
|
2868
|
-
if (words.length === 0) {
|
|
2869
|
-
return "Component";
|
|
2870
|
-
}
|
|
2871
|
-
return words.map((w) => w.replace(/[^A-Za-z0-9]/g, "")).filter(Boolean).map((w) => w.charAt(0).toUpperCase() + w.slice(1)).join("");
|
|
2870
|
+
return text.split(/[\s_\-,、]+/).map((w) => w.replace(/[^A-Za-z0-9]/g, "")).filter(Boolean).map((w) => w.charAt(0).toUpperCase() + w.slice(1)).join("");
|
|
2872
2871
|
}
|
|
2873
2872
|
suggestInterfaces(reqs) {
|
|
2874
2873
|
const interfaces = [];
|
|
@@ -12588,7 +12587,7 @@ var init_dist14 = __esm({
|
|
|
12588
12587
|
warnings
|
|
12589
12588
|
};
|
|
12590
12589
|
}
|
|
12591
|
-
const
|
|
12590
|
+
const symbols = /* @__PURE__ */ new Set([actionVar]);
|
|
12592
12591
|
const negated = /\bSHALL\s+NOT\b/i.test(requirement.text);
|
|
12593
12592
|
const actionExpr = negated ? `(not ${actionVar})` : actionVar;
|
|
12594
12593
|
let assertions;
|
|
@@ -12598,6 +12597,7 @@ var init_dist14 = __esm({
|
|
|
12598
12597
|
break;
|
|
12599
12598
|
case "event-driven": {
|
|
12600
12599
|
const triggerVar = requirement.trigger ? sanitizeName(requirement.trigger) : "trigger";
|
|
12600
|
+
symbols.add(triggerVar);
|
|
12601
12601
|
assertions = [`(assert (=> ${triggerVar} ${actionExpr}))`];
|
|
12602
12602
|
if (!requirement.trigger) {
|
|
12603
12603
|
warnings.push('No trigger specified; using default "trigger"');
|
|
@@ -12606,6 +12606,7 @@ var init_dist14 = __esm({
|
|
|
12606
12606
|
}
|
|
12607
12607
|
case "state-driven": {
|
|
12608
12608
|
const condVar = requirement.condition ? sanitizeName(requirement.condition) : "condition";
|
|
12609
|
+
symbols.add(condVar);
|
|
12609
12610
|
assertions = [`(assert (=> ${condVar} ${actionExpr}))`];
|
|
12610
12611
|
if (!requirement.condition) {
|
|
12611
12612
|
warnings.push('No condition specified; using default "condition"');
|
|
@@ -12614,13 +12615,16 @@ var init_dist14 = __esm({
|
|
|
12614
12615
|
}
|
|
12615
12616
|
case "unwanted":
|
|
12616
12617
|
if (requirement.condition) {
|
|
12617
|
-
|
|
12618
|
+
const condVar = sanitizeName(requirement.condition);
|
|
12619
|
+
symbols.add(condVar);
|
|
12620
|
+
assertions = [`(assert (=> ${condVar} ${actionExpr}))`];
|
|
12618
12621
|
} else {
|
|
12619
12622
|
assertions = [`(assert ${actionExpr})`];
|
|
12620
12623
|
}
|
|
12621
12624
|
break;
|
|
12622
12625
|
case "optional": {
|
|
12623
12626
|
const featureVar = requirement.trigger ? sanitizeName(requirement.trigger) : "feature_enabled";
|
|
12627
|
+
symbols.add(featureVar);
|
|
12624
12628
|
assertions = [`(assert (=> ${featureVar} ${actionExpr}))`];
|
|
12625
12629
|
if (!requirement.trigger) {
|
|
12626
12630
|
warnings.push('No feature trigger specified; using default "feature_enabled"');
|
|
@@ -12630,6 +12634,8 @@ var init_dist14 = __esm({
|
|
|
12630
12634
|
case "complex": {
|
|
12631
12635
|
const condVar = requirement.condition ? sanitizeName(requirement.condition) : "condition";
|
|
12632
12636
|
const triggerVar = requirement.trigger ? sanitizeName(requirement.trigger) : "trigger";
|
|
12637
|
+
symbols.add(condVar);
|
|
12638
|
+
symbols.add(triggerVar);
|
|
12633
12639
|
assertions = [`(assert (=> (and ${condVar} ${triggerVar}) ${actionExpr}))`];
|
|
12634
12640
|
if (!requirement.condition) {
|
|
12635
12641
|
warnings.push('No condition specified; using default "condition"');
|
|
@@ -12641,6 +12647,7 @@ var init_dist14 = __esm({
|
|
|
12641
12647
|
}
|
|
12642
12648
|
}
|
|
12643
12649
|
const id = makeFormulaId(requirement.id);
|
|
12650
|
+
const variables = [...symbols].map((name) => ({ name, sort: "Bool" }));
|
|
12644
12651
|
const formula = {
|
|
12645
12652
|
id,
|
|
12646
12653
|
requirementId: requirement.id,
|
|
@@ -12777,7 +12784,7 @@ var init_dist14 = __esm({
|
|
|
12777
12784
|
mockSolve(smtScript) {
|
|
12778
12785
|
const start = Date.now();
|
|
12779
12786
|
try {
|
|
12780
|
-
if (smtScript.includes("(assert false)")) {
|
|
12787
|
+
if (smtScript.includes("(assert false)") || this.hasBooleanContradiction(smtScript)) {
|
|
12781
12788
|
return {
|
|
12782
12789
|
status: "unsat",
|
|
12783
12790
|
time: Date.now() - start
|
|
@@ -12802,6 +12809,38 @@ var init_dist14 = __esm({
|
|
|
12802
12809
|
};
|
|
12803
12810
|
}
|
|
12804
12811
|
}
|
|
12812
|
+
/**
|
|
12813
|
+
* Detect a basic Boolean contradiction without a real solver: an atom that is
|
|
12814
|
+
* *unconditionally* forced both true and false. Covers the common EARS cases —
|
|
12815
|
+
* `SHALL X` (`(=> true X)` or `(assert X)`) versus `SHALL NOT X`
|
|
12816
|
+
* (`(not X)`) — so `verify` flags e.g. "grant access" / "not grant access".
|
|
12817
|
+
* Conditional assertions (`(=> cond X)` with cond ≠ true) are not forcing and
|
|
12818
|
+
* are ignored. This is a sound-but-incomplete check (real z3 covers the rest).
|
|
12819
|
+
*/
|
|
12820
|
+
hasBooleanContradiction(smtScript) {
|
|
12821
|
+
const forced = /* @__PURE__ */ new Map();
|
|
12822
|
+
let contradiction = false;
|
|
12823
|
+
const set = (atom, value) => {
|
|
12824
|
+
if (forced.has(atom) && forced.get(atom) !== value) {
|
|
12825
|
+
contradiction = true;
|
|
12826
|
+
}
|
|
12827
|
+
forced.set(atom, value);
|
|
12828
|
+
};
|
|
12829
|
+
for (const raw of smtScript.split("\n")) {
|
|
12830
|
+
const line = raw.trim();
|
|
12831
|
+
let m;
|
|
12832
|
+
if (m = /^\(assert \(=> true \(not (\w+)\)\)\)$/.exec(line)) {
|
|
12833
|
+
set(m[1], false);
|
|
12834
|
+
} else if (m = /^\(assert \(=> true (\w+)\)\)$/.exec(line)) {
|
|
12835
|
+
set(m[1], true);
|
|
12836
|
+
} else if (m = /^\(assert \(not (\w+)\)\)$/.exec(line)) {
|
|
12837
|
+
set(m[1], false);
|
|
12838
|
+
} else if (m = /^\(assert (\w+)\)$/.exec(line)) {
|
|
12839
|
+
set(m[1], true);
|
|
12840
|
+
}
|
|
12841
|
+
}
|
|
12842
|
+
return contradiction;
|
|
12843
|
+
}
|
|
12805
12844
|
};
|
|
12806
12845
|
PreconditionVerifier = class {
|
|
12807
12846
|
async verify(requirement, converter, solver) {
|