musubix2 0.5.62 → 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 +38 -7
- package/dist/index.js +38 -7
- 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 = [];
|
|
@@ -12785,7 +12784,7 @@ var init_dist14 = __esm({
|
|
|
12785
12784
|
mockSolve(smtScript) {
|
|
12786
12785
|
const start = Date.now();
|
|
12787
12786
|
try {
|
|
12788
|
-
if (smtScript.includes("(assert false)")) {
|
|
12787
|
+
if (smtScript.includes("(assert false)") || this.hasBooleanContradiction(smtScript)) {
|
|
12789
12788
|
return {
|
|
12790
12789
|
status: "unsat",
|
|
12791
12790
|
time: Date.now() - start
|
|
@@ -12810,6 +12809,38 @@ var init_dist14 = __esm({
|
|
|
12810
12809
|
};
|
|
12811
12810
|
}
|
|
12812
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
|
+
}
|
|
12813
12844
|
};
|
|
12814
12845
|
PreconditionVerifier = class {
|
|
12815
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 = [];
|
|
@@ -12785,7 +12784,7 @@ var init_dist14 = __esm({
|
|
|
12785
12784
|
mockSolve(smtScript) {
|
|
12786
12785
|
const start = Date.now();
|
|
12787
12786
|
try {
|
|
12788
|
-
if (smtScript.includes("(assert false)")) {
|
|
12787
|
+
if (smtScript.includes("(assert false)") || this.hasBooleanContradiction(smtScript)) {
|
|
12789
12788
|
return {
|
|
12790
12789
|
status: "unsat",
|
|
12791
12790
|
time: Date.now() - start
|
|
@@ -12810,6 +12809,38 @@ var init_dist14 = __esm({
|
|
|
12810
12809
|
};
|
|
12811
12810
|
}
|
|
12812
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
|
+
}
|
|
12813
12844
|
};
|
|
12814
12845
|
PreconditionVerifier = class {
|
|
12815
12846
|
async verify(requirement, converter, solver) {
|