@iamu-dev/iamu 0.3.0-beta.0 → 0.3.0-beta.1
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/bin.js +424 -44
- package/dist/commands/set-entity.d.ts +32 -5
- package/dist/index.js +424 -44
- package/dist/templates/skills/iamu-findings.md +55 -34
- package/dist/templates/skills/iamu-run.md +70 -50
- package/dist/templates/skills/iamu-setup.md +32 -33
- package/package.json +3 -3
package/dist/bin.js
CHANGED
|
@@ -5460,10 +5460,20 @@ async function readTestability(projectRoot) {
|
|
|
5460
5460
|
body: parsed.body
|
|
5461
5461
|
};
|
|
5462
5462
|
}
|
|
5463
|
+
async function writeTestability(projectRoot, input, body) {
|
|
5464
|
+
const p = testabilityPath(projectRoot);
|
|
5465
|
+
const isLocalDoc = "frontmatter" in input && typeof input.frontmatter === "object";
|
|
5466
|
+
const fm = isLocalDoc ? input.frontmatter : input;
|
|
5467
|
+
const effectiveBody = body !== void 0 ? body : isLocalDoc ? input.body : "";
|
|
5468
|
+
const validated = testabilityFrontmatterSchema.parse(fm);
|
|
5469
|
+
const serialized = serializeFrontmatter(validated, effectiveBody);
|
|
5470
|
+
await atomicWriteFile(p, serialized);
|
|
5471
|
+
}
|
|
5463
5472
|
var init_testability2 = __esm({
|
|
5464
5473
|
"../../packages/local-store/dist/testability.js"() {
|
|
5465
5474
|
"use strict";
|
|
5466
5475
|
init_dist();
|
|
5476
|
+
init_atomic();
|
|
5467
5477
|
init_markdown();
|
|
5468
5478
|
init_paths();
|
|
5469
5479
|
}
|
|
@@ -8622,7 +8632,7 @@ function formatRefError(err) {
|
|
|
8622
8632
|
const dir = ENTITY_DIRS[err.missing_ref];
|
|
8623
8633
|
const hint = MISSING_REF_HINTS[err.missing_ref] ?? "";
|
|
8624
8634
|
if (!err.missing_slug) {
|
|
8625
|
-
const fieldHint = err.missing_ref === "capability" && err.entity_type === "outline" ?
|
|
8635
|
+
const fieldHint = err.missing_ref === "capability" && err.entity_type === "outline" ? `run \`iamu set outline ${err.entity_slug ?? "<slug>"} --capability <slug>\`` : `add a \`${err.missing_ref}:\` field to the file`;
|
|
8626
8636
|
return `${err.entity_type} ${err.entity_slug || err.entity_id}: ${err.missing_ref} slug is missing from frontmatter \u2014 ${fieldHint}`;
|
|
8627
8637
|
}
|
|
8628
8638
|
return `${err.entity_type} ${err.entity_slug || err.entity_id}: \`${err.missing_slug}\` not found in iamu/${dir}/${hint}`;
|
|
@@ -8636,7 +8646,7 @@ var init_refs = __esm({
|
|
|
8636
8646
|
init_sync_tracking();
|
|
8637
8647
|
init_walkthrough_mirror();
|
|
8638
8648
|
MISSING_REF_HINTS = {
|
|
8639
|
-
capability: " \u2014 create it with `iamu new capability` or
|
|
8649
|
+
capability: " \u2014 create it with `iamu new capability` or set with `iamu set outline <slug> --capability <slug>`",
|
|
8640
8650
|
outline: " \u2014 create it with `iamu new` or verify the slug matches a file in iamu/outlines/",
|
|
8641
8651
|
persona: " \u2014 create it with `iamu new persona` or check the slug",
|
|
8642
8652
|
scenario: " \u2014 verify the scenario exists locally with `iamu list scenarios`"
|
|
@@ -13636,8 +13646,8 @@ import { dirname as dirname3, join as join4, resolve as resolve2 } from "path";
|
|
|
13636
13646
|
import { fileURLToPath as fileURLToPath2 } from "url";
|
|
13637
13647
|
import chalk6 from "chalk";
|
|
13638
13648
|
function getVersion() {
|
|
13639
|
-
if ("0.3.0-beta.
|
|
13640
|
-
return "0.3.0-beta.
|
|
13649
|
+
if ("0.3.0-beta.1") {
|
|
13650
|
+
return "0.3.0-beta.1";
|
|
13641
13651
|
}
|
|
13642
13652
|
try {
|
|
13643
13653
|
const thisDir = dirname3(fileURLToPath2(import.meta.url));
|
|
@@ -20873,6 +20883,15 @@ function validateFile(filePath, raw, projectRoot) {
|
|
|
20873
20883
|
);
|
|
20874
20884
|
}
|
|
20875
20885
|
}
|
|
20886
|
+
if (type2 === "outline" && zodResult.success) {
|
|
20887
|
+
const fm = zodResult.data;
|
|
20888
|
+
if (!fm.primary_capability && !fm.capability) {
|
|
20889
|
+
result.warnings = result.warnings ?? [];
|
|
20890
|
+
result.warnings.push(
|
|
20891
|
+
`outline has no primary capability \u2014 sync will require one (run \`iamu set outline ${fm.slug ?? "<slug>"} --capability <slug>\`)`
|
|
20892
|
+
);
|
|
20893
|
+
}
|
|
20894
|
+
}
|
|
20876
20895
|
return result;
|
|
20877
20896
|
}
|
|
20878
20897
|
async function buildRepairLookups(projectRoot) {
|
|
@@ -21441,6 +21460,15 @@ async function newEntity(type2, opts) {
|
|
|
21441
21460
|
);
|
|
21442
21461
|
return;
|
|
21443
21462
|
}
|
|
21463
|
+
if (entityType === "outline" && !opts.capability) {
|
|
21464
|
+
try {
|
|
21465
|
+
const { entities } = await listEntities(projectRoot, "capability");
|
|
21466
|
+
if (entities.length === 1 && typeof entities[0].frontmatter.slug === "string") {
|
|
21467
|
+
opts.capability = entities[0].frontmatter.slug;
|
|
21468
|
+
}
|
|
21469
|
+
} catch {
|
|
21470
|
+
}
|
|
21471
|
+
}
|
|
21444
21472
|
const id = randomUUID10();
|
|
21445
21473
|
const frontmatter = defaultFrontmatter(entityType, id, slug, opts.name, opts);
|
|
21446
21474
|
const body = opts.body ?? (entityType === "outline" ? "" : opts.narrative) ?? "";
|
|
@@ -21559,6 +21587,42 @@ function applyChanges(type2, fm, opts) {
|
|
|
21559
21587
|
put("paths", paths);
|
|
21560
21588
|
}
|
|
21561
21589
|
if (opts.area !== void 0) put("area", opts.area || null);
|
|
21590
|
+
} else if (type2 === "outline") {
|
|
21591
|
+
if (opts.capability === false) {
|
|
21592
|
+
put("primary_capability", null);
|
|
21593
|
+
put("capability", null);
|
|
21594
|
+
} else if (opts.capability !== void 0) {
|
|
21595
|
+
put("primary_capability", opts.capability || null);
|
|
21596
|
+
put("capability", opts.capability || null);
|
|
21597
|
+
}
|
|
21598
|
+
if (opts.additionalCapabilities === false) {
|
|
21599
|
+
put("additional_capabilities", []);
|
|
21600
|
+
} else if (opts.additionalCapabilities !== void 0) {
|
|
21601
|
+
const caps = typeof opts.additionalCapabilities === "string" ? splitList(opts.additionalCapabilities) : Array.isArray(opts.additionalCapabilities) ? opts.additionalCapabilities : [];
|
|
21602
|
+
put("additional_capabilities", caps);
|
|
21603
|
+
}
|
|
21604
|
+
} else if (type2 === "testability") {
|
|
21605
|
+
if (opts.target !== void 0) put("target_url", opts.target || null);
|
|
21606
|
+
if (opts.devCommand !== void 0)
|
|
21607
|
+
put("dev_command", opts.devCommand || null);
|
|
21608
|
+
if (opts.authStrategy !== void 0)
|
|
21609
|
+
put("auth_strategy", opts.authStrategy || null);
|
|
21610
|
+
if (opts.access !== void 0) put("access", opts.access || null);
|
|
21611
|
+
if (opts.harnesses !== void 0) {
|
|
21612
|
+
put("harnesses", opts.harnesses ? splitList(opts.harnesses) : null);
|
|
21613
|
+
}
|
|
21614
|
+
if (opts.untestableBoundaries !== void 0) {
|
|
21615
|
+
put(
|
|
21616
|
+
"untestable_boundaries",
|
|
21617
|
+
opts.untestableBoundaries ? splitList(opts.untestableBoundaries) : null
|
|
21618
|
+
);
|
|
21619
|
+
}
|
|
21620
|
+
} else if (type2 === "context") {
|
|
21621
|
+
if (opts.domain !== void 0) put("domain", opts.domain || null);
|
|
21622
|
+
if (opts.industry !== void 0) put("industry", opts.industry || null);
|
|
21623
|
+
if (opts.jurisdiction !== void 0)
|
|
21624
|
+
put("jurisdiction", opts.jurisdiction || null);
|
|
21625
|
+
if (opts.notes !== void 0) put("notes", opts.notes || null);
|
|
21562
21626
|
}
|
|
21563
21627
|
return changed;
|
|
21564
21628
|
}
|
|
@@ -21574,6 +21638,15 @@ async function setEntity(type2, slug, opts) {
|
|
|
21574
21638
|
);
|
|
21575
21639
|
return;
|
|
21576
21640
|
}
|
|
21641
|
+
if (type2 !== "testability" && type2 !== "context" && !slug) {
|
|
21642
|
+
commandError(`A slug is required when setting a ${type2}.`, {
|
|
21643
|
+
...opts,
|
|
21644
|
+
code: "missing_slug",
|
|
21645
|
+
fix: `iamu set ${type2} <slug>`
|
|
21646
|
+
});
|
|
21647
|
+
return;
|
|
21648
|
+
}
|
|
21649
|
+
const effectiveSlug = slug || type2;
|
|
21577
21650
|
const foreign = Object.keys(FLAG_NAMES).filter(
|
|
21578
21651
|
(k) => !allowed.includes(k) && given(opts, k)
|
|
21579
21652
|
);
|
|
@@ -21583,7 +21656,7 @@ async function setEntity(type2, slug, opts) {
|
|
|
21583
21656
|
{
|
|
21584
21657
|
...opts,
|
|
21585
21658
|
code: "invalid_field_combination",
|
|
21586
|
-
fix: `iamu set ${type2} ${
|
|
21659
|
+
fix: `iamu set ${type2} ${effectiveSlug} ${FLAG_NAMES[allowed[0]]} ...`
|
|
21587
21660
|
}
|
|
21588
21661
|
);
|
|
21589
21662
|
return;
|
|
@@ -21624,7 +21697,38 @@ async function setEntity(type2, slug, opts) {
|
|
|
21624
21697
|
const allowedPatchKeys = {
|
|
21625
21698
|
scenario: ["entry", "entry_path", "target", "target_url", "state"],
|
|
21626
21699
|
persona: ["access"],
|
|
21627
|
-
capability: ["paths", "addPath", "removePath", "area"]
|
|
21700
|
+
capability: ["paths", "addPath", "removePath", "area"],
|
|
21701
|
+
outline: [
|
|
21702
|
+
"capability",
|
|
21703
|
+
"primary_capability",
|
|
21704
|
+
"additional_capabilities",
|
|
21705
|
+
"additionalCapabilities"
|
|
21706
|
+
],
|
|
21707
|
+
testability: [
|
|
21708
|
+
"target",
|
|
21709
|
+
"target_url",
|
|
21710
|
+
"devCommand",
|
|
21711
|
+
"dev_command",
|
|
21712
|
+
"authStrategy",
|
|
21713
|
+
"auth_strategy",
|
|
21714
|
+
"access",
|
|
21715
|
+
"harnesses",
|
|
21716
|
+
"untestableBoundaries",
|
|
21717
|
+
"untestable_boundaries",
|
|
21718
|
+
"body"
|
|
21719
|
+
],
|
|
21720
|
+
context: [
|
|
21721
|
+
"domain",
|
|
21722
|
+
"industry",
|
|
21723
|
+
"jurisdiction",
|
|
21724
|
+
"notes",
|
|
21725
|
+
"description",
|
|
21726
|
+
"name",
|
|
21727
|
+
"governed_by",
|
|
21728
|
+
"actors",
|
|
21729
|
+
"terminology",
|
|
21730
|
+
"body"
|
|
21731
|
+
]
|
|
21628
21732
|
};
|
|
21629
21733
|
const foreignPatchKeys = Object.keys(parsed).filter(
|
|
21630
21734
|
(k) => !allowedPatchKeys[type2]?.includes(k)
|
|
@@ -21683,6 +21787,65 @@ async function setEntity(type2, slug, opts) {
|
|
|
21683
21787
|
if (effectiveOpts.area === void 0 && parsed.area !== void 0) {
|
|
21684
21788
|
effectiveOpts.area = parsed.area === null || parsed.area === false ? false : String(parsed.area);
|
|
21685
21789
|
}
|
|
21790
|
+
} else if (type2 === "outline") {
|
|
21791
|
+
if (effectiveOpts.capability === void 0 && (parsed.capability !== void 0 || parsed.primary_capability !== void 0)) {
|
|
21792
|
+
const v = parsed.capability ?? parsed.primary_capability;
|
|
21793
|
+
effectiveOpts.capability = v === null || v === false ? false : String(v);
|
|
21794
|
+
}
|
|
21795
|
+
if (effectiveOpts.additionalCapabilities === void 0 && (parsed.additionalCapabilities !== void 0 || parsed.additional_capabilities !== void 0)) {
|
|
21796
|
+
const v = parsed.additionalCapabilities ?? parsed.additional_capabilities;
|
|
21797
|
+
effectiveOpts.additionalCapabilities = v === null || v === false ? false : Array.isArray(v) ? v.join(",") : String(v);
|
|
21798
|
+
}
|
|
21799
|
+
} else if (type2 === "testability") {
|
|
21800
|
+
if (effectiveOpts.target === void 0 && (parsed.target !== void 0 || parsed.target_url !== void 0)) {
|
|
21801
|
+
const v = parsed.target ?? parsed.target_url;
|
|
21802
|
+
effectiveOpts.target = v === null || v === false ? false : String(v);
|
|
21803
|
+
}
|
|
21804
|
+
if (effectiveOpts.devCommand === void 0 && (parsed.devCommand !== void 0 || parsed.dev_command !== void 0)) {
|
|
21805
|
+
const v = parsed.devCommand ?? parsed.dev_command;
|
|
21806
|
+
effectiveOpts.devCommand = v === null || v === false ? false : String(v);
|
|
21807
|
+
}
|
|
21808
|
+
if (effectiveOpts.authStrategy === void 0 && (parsed.authStrategy !== void 0 || parsed.auth_strategy !== void 0)) {
|
|
21809
|
+
const v = parsed.authStrategy ?? parsed.auth_strategy;
|
|
21810
|
+
effectiveOpts.authStrategy = v === null || v === false ? false : String(v);
|
|
21811
|
+
}
|
|
21812
|
+
if (effectiveOpts.access === void 0 && parsed.access !== void 0) {
|
|
21813
|
+
effectiveOpts.access = parsed.access === null || parsed.access === false ? false : String(parsed.access);
|
|
21814
|
+
}
|
|
21815
|
+
if (effectiveOpts.harnesses === void 0 && parsed.harnesses !== void 0) {
|
|
21816
|
+
effectiveOpts.harnesses = parsed.harnesses === null || parsed.harnesses === false ? false : Array.isArray(parsed.harnesses) ? parsed.harnesses.join(",") : String(parsed.harnesses);
|
|
21817
|
+
}
|
|
21818
|
+
if (effectiveOpts.untestableBoundaries === void 0 && (parsed.untestableBoundaries !== void 0 || parsed.untestable_boundaries !== void 0)) {
|
|
21819
|
+
const b = parsed.untestableBoundaries ?? parsed.untestable_boundaries;
|
|
21820
|
+
effectiveOpts.untestableBoundaries = b === null || b === false ? false : Array.isArray(b) ? b.join(",") : String(b);
|
|
21821
|
+
}
|
|
21822
|
+
if (effectiveOpts.body === void 0 && parsed.body !== void 0) {
|
|
21823
|
+
effectiveOpts.body = String(parsed.body);
|
|
21824
|
+
}
|
|
21825
|
+
} else if (type2 === "context") {
|
|
21826
|
+
if (effectiveOpts.domain === void 0 && parsed.domain !== void 0) {
|
|
21827
|
+
effectiveOpts.domain = parsed.domain === null || parsed.domain === false ? false : String(parsed.domain);
|
|
21828
|
+
}
|
|
21829
|
+
if (effectiveOpts.industry === void 0 && parsed.industry !== void 0) {
|
|
21830
|
+
effectiveOpts.industry = parsed.industry === null || parsed.industry === false ? false : String(parsed.industry);
|
|
21831
|
+
}
|
|
21832
|
+
if (effectiveOpts.jurisdiction === void 0 && parsed.jurisdiction !== void 0) {
|
|
21833
|
+
effectiveOpts.jurisdiction = parsed.jurisdiction === null || parsed.jurisdiction === false ? false : String(parsed.jurisdiction);
|
|
21834
|
+
}
|
|
21835
|
+
if (effectiveOpts.notes === void 0 && parsed.notes !== void 0) {
|
|
21836
|
+
effectiveOpts.notes = parsed.notes === null || parsed.notes === false ? false : String(parsed.notes);
|
|
21837
|
+
}
|
|
21838
|
+
if (effectiveOpts.description === void 0 && parsed.description !== void 0) {
|
|
21839
|
+
effectiveOpts.description = parsed.description === null || parsed.description === false ? false : String(parsed.description);
|
|
21840
|
+
}
|
|
21841
|
+
if (effectiveOpts.name === void 0 && parsed.name !== void 0) {
|
|
21842
|
+
effectiveOpts.name = parsed.name === null || parsed.name === false ? false : String(parsed.name);
|
|
21843
|
+
}
|
|
21844
|
+
if (effectiveOpts.body === void 0 && parsed.body !== void 0) {
|
|
21845
|
+
effectiveOpts.body = String(parsed.body);
|
|
21846
|
+
} else if (effectiveOpts.body === void 0 && effectiveOpts.description !== void 0) {
|
|
21847
|
+
effectiveOpts.body = effectiveOpts.description ? String(effectiveOpts.description) : "";
|
|
21848
|
+
}
|
|
21686
21849
|
}
|
|
21687
21850
|
}
|
|
21688
21851
|
if (!allowed.some((k) => given(effectiveOpts, k))) {
|
|
@@ -21691,11 +21854,112 @@ async function setEntity(type2, slug, opts) {
|
|
|
21691
21854
|
{
|
|
21692
21855
|
...opts,
|
|
21693
21856
|
code: "nothing_to_set",
|
|
21694
|
-
fix: `iamu set ${type2} ${
|
|
21857
|
+
fix: `iamu set ${type2}${type2 === "testability" || type2 === "context" ? "" : ` ${effectiveSlug}`} ${FLAG_NAMES[allowed[0]]} ...`
|
|
21695
21858
|
}
|
|
21696
21859
|
);
|
|
21697
21860
|
return;
|
|
21698
21861
|
}
|
|
21862
|
+
if (type2 === "testability") {
|
|
21863
|
+
const doc = await readTestability(projectRoot) ?? {
|
|
21864
|
+
frontmatter: {
|
|
21865
|
+
schema_version: 1,
|
|
21866
|
+
status: "draft",
|
|
21867
|
+
target_url: "http://localhost:3000"
|
|
21868
|
+
},
|
|
21869
|
+
body: ""
|
|
21870
|
+
};
|
|
21871
|
+
const fm2 = { ...doc.frontmatter };
|
|
21872
|
+
const changed2 = applyChanges(type2, fm2, effectiveOpts);
|
|
21873
|
+
let body = doc.body;
|
|
21874
|
+
if (effectiveOpts.body !== void 0) {
|
|
21875
|
+
body = effectiveOpts.body;
|
|
21876
|
+
changed2.push("body");
|
|
21877
|
+
}
|
|
21878
|
+
const writtenPath2 = testabilityPath(projectRoot);
|
|
21879
|
+
try {
|
|
21880
|
+
await writeTestability(
|
|
21881
|
+
projectRoot,
|
|
21882
|
+
fm2,
|
|
21883
|
+
body
|
|
21884
|
+
);
|
|
21885
|
+
} catch (err) {
|
|
21886
|
+
const message = err instanceof ZodError2 ? err.issues.map((i) => `${i.path.join(".") || "root"}: ${i.message}`).join("; ") : err instanceof Error ? err.message : String(err);
|
|
21887
|
+
commandError(`Could not set testability: ${message}`, {
|
|
21888
|
+
...opts,
|
|
21889
|
+
code: "testability_write_error",
|
|
21890
|
+
fix: "iamu set testability --target <url>"
|
|
21891
|
+
});
|
|
21892
|
+
return;
|
|
21893
|
+
}
|
|
21894
|
+
if (opts.json) {
|
|
21895
|
+
console.log(
|
|
21896
|
+
JSON.stringify({
|
|
21897
|
+
slug: "testability",
|
|
21898
|
+
type: "testability",
|
|
21899
|
+
path: writtenPath2,
|
|
21900
|
+
changed: changed2
|
|
21901
|
+
})
|
|
21902
|
+
);
|
|
21903
|
+
return;
|
|
21904
|
+
}
|
|
21905
|
+
console.log();
|
|
21906
|
+
console.log(
|
|
21907
|
+
` ${symbols.success} Updated testability: ${changed2.join(", ")}`
|
|
21908
|
+
);
|
|
21909
|
+
console.log(` ${chalk28.dim("path:")} ${writtenPath2}`);
|
|
21910
|
+
console.log();
|
|
21911
|
+
return;
|
|
21912
|
+
}
|
|
21913
|
+
if (type2 === "context") {
|
|
21914
|
+
const doc = await readContext(projectRoot) ?? {
|
|
21915
|
+
frontmatter: {
|
|
21916
|
+
schema_version: SCHEMA_VERSION,
|
|
21917
|
+
status: "draft"
|
|
21918
|
+
},
|
|
21919
|
+
notes_body: ""
|
|
21920
|
+
};
|
|
21921
|
+
const fm2 = { ...doc.frontmatter };
|
|
21922
|
+
const changed2 = applyChanges(type2, fm2, effectiveOpts);
|
|
21923
|
+
let body = doc.notes_body;
|
|
21924
|
+
if (effectiveOpts.body !== void 0) {
|
|
21925
|
+
body = effectiveOpts.body;
|
|
21926
|
+
changed2.push("body");
|
|
21927
|
+
} else if (effectiveOpts.description !== void 0) {
|
|
21928
|
+
body = effectiveOpts.description ? String(effectiveOpts.description) : "";
|
|
21929
|
+
changed2.push("body");
|
|
21930
|
+
}
|
|
21931
|
+
const writtenPath2 = contextPath(projectRoot);
|
|
21932
|
+
try {
|
|
21933
|
+
await writeContext(projectRoot, {
|
|
21934
|
+
frontmatter: fm2,
|
|
21935
|
+
notes_body: body
|
|
21936
|
+
});
|
|
21937
|
+
} catch (err) {
|
|
21938
|
+
const message = err instanceof ZodError2 ? err.issues.map((i) => `${i.path.join(".") || "root"}: ${i.message}`).join("; ") : err instanceof Error ? err.message : String(err);
|
|
21939
|
+
commandError(`Could not set context: ${message}`, {
|
|
21940
|
+
...opts,
|
|
21941
|
+
code: "context_write_error",
|
|
21942
|
+
fix: "iamu set context --domain <domain>"
|
|
21943
|
+
});
|
|
21944
|
+
return;
|
|
21945
|
+
}
|
|
21946
|
+
if (opts.json) {
|
|
21947
|
+
console.log(
|
|
21948
|
+
JSON.stringify({
|
|
21949
|
+
slug: "context",
|
|
21950
|
+
type: "context",
|
|
21951
|
+
path: writtenPath2,
|
|
21952
|
+
changed: changed2
|
|
21953
|
+
})
|
|
21954
|
+
);
|
|
21955
|
+
return;
|
|
21956
|
+
}
|
|
21957
|
+
console.log();
|
|
21958
|
+
console.log(` ${symbols.success} Updated context: ${changed2.join(", ")}`);
|
|
21959
|
+
console.log(` ${chalk28.dim("path:")} ${writtenPath2}`);
|
|
21960
|
+
console.log();
|
|
21961
|
+
return;
|
|
21962
|
+
}
|
|
21699
21963
|
if (type2 === "capability") {
|
|
21700
21964
|
const candidatePaths = [
|
|
21701
21965
|
...typeof effectiveOpts.paths === "string" ? splitList(effectiveOpts.paths) : [],
|
|
@@ -21708,7 +21972,7 @@ async function setEntity(type2, slug, opts) {
|
|
|
21708
21972
|
{
|
|
21709
21973
|
...opts,
|
|
21710
21974
|
code: "invalid_route_prefix",
|
|
21711
|
-
fix: `iamu set ${type2} ${
|
|
21975
|
+
fix: `iamu set ${type2} ${effectiveSlug} --paths /${invalid[0]?.replace(/^\/+/, "") || ""}`
|
|
21712
21976
|
}
|
|
21713
21977
|
);
|
|
21714
21978
|
return;
|
|
@@ -21781,7 +22045,25 @@ var init_set_entity = __esm({
|
|
|
21781
22045
|
"state"
|
|
21782
22046
|
],
|
|
21783
22047
|
persona: ["access"],
|
|
21784
|
-
capability: ["paths", "addPath", "removePath", "area"]
|
|
22048
|
+
capability: ["paths", "addPath", "removePath", "area"],
|
|
22049
|
+
outline: ["capability", "additionalCapabilities"],
|
|
22050
|
+
testability: [
|
|
22051
|
+
"target",
|
|
22052
|
+
"devCommand",
|
|
22053
|
+
"authStrategy",
|
|
22054
|
+
"access",
|
|
22055
|
+
"harnesses",
|
|
22056
|
+
"untestableBoundaries",
|
|
22057
|
+
"body"
|
|
22058
|
+
],
|
|
22059
|
+
context: [
|
|
22060
|
+
"domain",
|
|
22061
|
+
"industry",
|
|
22062
|
+
"jurisdiction",
|
|
22063
|
+
"notes",
|
|
22064
|
+
"description",
|
|
22065
|
+
"body"
|
|
22066
|
+
]
|
|
21785
22067
|
};
|
|
21786
22068
|
FLAG_NAMES = {
|
|
21787
22069
|
entry: "--entry",
|
|
@@ -21793,7 +22075,20 @@ var init_set_entity = __esm({
|
|
|
21793
22075
|
paths: "--paths",
|
|
21794
22076
|
addPath: "--add-path",
|
|
21795
22077
|
removePath: "--remove-path",
|
|
21796
|
-
area: "--area"
|
|
22078
|
+
area: "--area",
|
|
22079
|
+
capability: "--capability",
|
|
22080
|
+
additionalCapabilities: "--additional-capabilities",
|
|
22081
|
+
devCommand: "--dev-command",
|
|
22082
|
+
authStrategy: "--auth-strategy",
|
|
22083
|
+
harnesses: "--harnesses",
|
|
22084
|
+
untestableBoundaries: "--untestable-boundaries",
|
|
22085
|
+
domain: "--domain",
|
|
22086
|
+
industry: "--industry",
|
|
22087
|
+
jurisdiction: "--jurisdiction",
|
|
22088
|
+
notes: "--notes",
|
|
22089
|
+
description: "--description",
|
|
22090
|
+
name: "--name",
|
|
22091
|
+
body: "--body"
|
|
21797
22092
|
};
|
|
21798
22093
|
}
|
|
21799
22094
|
});
|
|
@@ -23054,7 +23349,7 @@ __export(instructions_walk_exports, {
|
|
|
23054
23349
|
revisitSection: () => revisitSection,
|
|
23055
23350
|
viewportLine: () => viewportLine
|
|
23056
23351
|
});
|
|
23057
|
-
import { existsSync as existsSync16, readFileSync as readFileSync9 } from "fs";
|
|
23352
|
+
import { existsSync as existsSync16, readFileSync as readFileSync9, writeFileSync as writeFileSync4 } from "fs";
|
|
23058
23353
|
import { join as join9 } from "path";
|
|
23059
23354
|
import chalk31 from "chalk";
|
|
23060
23355
|
function selfCommand() {
|
|
@@ -23441,8 +23736,17 @@ async function instructionsWalk(opts) {
|
|
|
23441
23736
|
state: sfm.state ?? null,
|
|
23442
23737
|
context: contextYml,
|
|
23443
23738
|
untestableBoundaries
|
|
23444
|
-
}) : null
|
|
23739
|
+
}) : null,
|
|
23740
|
+
walker_prompt_path: null
|
|
23445
23741
|
};
|
|
23742
|
+
if (runDirPath && result.walker_prompt) {
|
|
23743
|
+
try {
|
|
23744
|
+
const promptPath = join9(runDirPath, "walker_prompt.txt");
|
|
23745
|
+
writeFileSync4(promptPath, result.walker_prompt, "utf-8");
|
|
23746
|
+
result.walker_prompt_path = promptPath;
|
|
23747
|
+
} catch {
|
|
23748
|
+
}
|
|
23749
|
+
}
|
|
23446
23750
|
if (opts.json) {
|
|
23447
23751
|
console.log(JSON.stringify(result, null, 2));
|
|
23448
23752
|
return;
|
|
@@ -24463,13 +24767,25 @@ async function evaluateRecord(runId, opts) {
|
|
|
24463
24767
|
});
|
|
24464
24768
|
return;
|
|
24465
24769
|
}
|
|
24770
|
+
const defaultVerdictsPath = path34.join(runDirPath, "verdicts.json");
|
|
24466
24771
|
if (!opts.file && !opts.data) {
|
|
24467
|
-
|
|
24468
|
-
|
|
24469
|
-
|
|
24470
|
-
|
|
24471
|
-
}
|
|
24472
|
-
|
|
24772
|
+
let hasExisting = false;
|
|
24773
|
+
try {
|
|
24774
|
+
await fs32.access(defaultVerdictsPath);
|
|
24775
|
+
hasExisting = true;
|
|
24776
|
+
} catch {
|
|
24777
|
+
hasExisting = false;
|
|
24778
|
+
}
|
|
24779
|
+
if (hasExisting) {
|
|
24780
|
+
opts.file = defaultVerdictsPath;
|
|
24781
|
+
} else {
|
|
24782
|
+
commandError("Either --file <path> or --data <json> is required", {
|
|
24783
|
+
...opts,
|
|
24784
|
+
code: "missing_verdicts_input",
|
|
24785
|
+
fix: `iamu evaluate-record ${runId} --data '<json>'`
|
|
24786
|
+
});
|
|
24787
|
+
return;
|
|
24788
|
+
}
|
|
24473
24789
|
}
|
|
24474
24790
|
let parsedFile;
|
|
24475
24791
|
try {
|
|
@@ -25426,13 +25742,25 @@ async function matchRecord(runId, opts) {
|
|
|
25426
25742
|
});
|
|
25427
25743
|
const manifest = await completedManifest2(runDirPath, runId, opts);
|
|
25428
25744
|
if (!manifest) return;
|
|
25745
|
+
const defaultMatchesPath = path36.join(runDirPath, "matches.json");
|
|
25429
25746
|
if (!opts.file && !opts.data) {
|
|
25430
|
-
|
|
25431
|
-
|
|
25432
|
-
|
|
25433
|
-
|
|
25434
|
-
}
|
|
25435
|
-
|
|
25747
|
+
let hasExisting = false;
|
|
25748
|
+
try {
|
|
25749
|
+
await fs34.access(defaultMatchesPath);
|
|
25750
|
+
hasExisting = true;
|
|
25751
|
+
} catch {
|
|
25752
|
+
hasExisting = false;
|
|
25753
|
+
}
|
|
25754
|
+
if (hasExisting) {
|
|
25755
|
+
opts.file = defaultMatchesPath;
|
|
25756
|
+
} else {
|
|
25757
|
+
commandError("Either --file <path> or --data <json> is required", {
|
|
25758
|
+
...opts,
|
|
25759
|
+
code: "missing_matches_input",
|
|
25760
|
+
fix: `iamu match-record ${runId} --data '<json>'`
|
|
25761
|
+
});
|
|
25762
|
+
return;
|
|
25763
|
+
}
|
|
25436
25764
|
}
|
|
25437
25765
|
let answer;
|
|
25438
25766
|
try {
|
|
@@ -25874,12 +26202,12 @@ function registerProjectCommands(program2) {
|
|
|
25874
26202
|
await newEntity2(type2, opts);
|
|
25875
26203
|
}
|
|
25876
26204
|
);
|
|
25877
|
-
program2.command("set <type>
|
|
25878
|
-
"Change how an entity is staged: a scenario's start path, target and starting state, a persona's access key, a capability's routes (scenario, persona, capability)"
|
|
26205
|
+
program2.command("set <type> [slug]").helpGroup("Project:").description(
|
|
26206
|
+
"Change how an entity is staged: a scenario's start path, target and starting state, a persona's access key, a capability's routes, or project testability / context (scenario, persona, capability, testability, context)"
|
|
25879
26207
|
).option(
|
|
25880
26208
|
"--entry <path>",
|
|
25881
26209
|
"Where the walk starts, as a path on the product (scenario)"
|
|
25882
|
-
).option("--no-entry", "Clear the start path (scenario)").option("--target <url>", "Default target URL (scenario)").option("--no-target", "Clear the default target URL (scenario)").option(
|
|
26210
|
+
).option("--no-entry", "Clear the start path (scenario)").option("--target <url>", "Default target URL (scenario, testability)").option("--no-target", "Clear the default target URL (scenario)").option(
|
|
25883
26211
|
"--state-description <text>",
|
|
25884
26212
|
"What the world must contain, in domain words (scenario)"
|
|
25885
26213
|
).option(
|
|
@@ -25887,8 +26215,8 @@ function registerProjectCommands(program2) {
|
|
|
25887
26215
|
"How the walker picks the closest record when the exact one is missing (scenario)"
|
|
25888
26216
|
).option("--no-state", "Clear the starting state (scenario)").option(
|
|
25889
26217
|
"--access <key>",
|
|
25890
|
-
"Account, role or switcher key this persona uses (persona)"
|
|
25891
|
-
).option("--no-access", "Clear the access key (persona)").option(
|
|
26218
|
+
"Account, role or switcher key this persona uses (persona, testability)"
|
|
26219
|
+
).option("--no-access", "Clear the access key (persona, testability)").option(
|
|
25892
26220
|
"--paths <paths>",
|
|
25893
26221
|
"Route prefixes, comma-separated; replaces the list (capability)"
|
|
25894
26222
|
).option("--no-paths", "Clear route prefixes (capability)").option(
|
|
@@ -25899,12 +26227,27 @@ function registerProjectCommands(program2) {
|
|
|
25899
26227
|
"--remove-path <path>",
|
|
25900
26228
|
"Remove a route prefix (capability, repeatable)",
|
|
25901
26229
|
(val, prev = []) => [...prev, val]
|
|
25902
|
-
).option("--area <name>", "Visual grouping category (capability)").option("--no-area", "Clear the area (capability)").option(
|
|
26230
|
+
).option("--area <name>", "Visual grouping category (capability)").option("--no-area", "Clear the area (capability)").option("--capability <slug>", "Primary capability slug (outline)").option("--no-capability", "Clear primary capability (outline)").option(
|
|
26231
|
+
"--additional-capabilities <slugs>",
|
|
26232
|
+
"Secondary capability slugs, comma-separated (outline)"
|
|
26233
|
+
).option(
|
|
26234
|
+
"--no-additional-capabilities",
|
|
26235
|
+
"Clear secondary capabilities (outline)"
|
|
26236
|
+
).option("--dev-command <cmd>", "Dev startup command (testability)").option("--no-dev-command", "Clear dev startup command (testability)").option("--auth-strategy <strategy>", "Auth strategy (testability)").option("--no-auth-strategy", "Clear auth strategy (testability)").option(
|
|
26237
|
+
"--harnesses <list>",
|
|
26238
|
+
"Mock frameworks or seed scripts, comma-separated (testability)"
|
|
26239
|
+
).option("--no-harnesses", "Clear harnesses (testability)").option(
|
|
26240
|
+
"--untestable-boundaries <list>",
|
|
26241
|
+
"Forbidden external endpoints, comma-separated (testability)"
|
|
26242
|
+
).option(
|
|
26243
|
+
"--no-untestable-boundaries",
|
|
26244
|
+
"Clear untestable boundaries (testability)"
|
|
26245
|
+
).option("--domain <text>", "Domain name (context)").option("--industry <text>", "Industry category (context)").option("--jurisdiction <text>", "Jurisdiction or region (context)").option("--notes <text>", "Orientation notes (context)").option("--description <text>", "Project description (context)").option("--name <text>", "Project name (context)").option("--body <text>", "Markdown narrative body (testability, context)").option(
|
|
25903
26246
|
"--file <path>",
|
|
25904
26247
|
"JSON patch file to apply staging fields (or - for stdin)"
|
|
25905
26248
|
).option("--json", "Output as JSON").addHelpText(
|
|
25906
26249
|
"after",
|
|
25907
|
-
'\nWhat a scenario is about (narrative, tension, human tests, brief) is not set here.\n\nExamples:\n $ iamu set scenario maria--handoff --entry /incidents --state-description "Five open incidents at one site"\n $ iamu set persona maria --access coordinator@site-a.test\n $ iamu set capability team-access --add-path /team\n $ iamu set scenario maria--handoff --file patch.json'
|
|
26250
|
+
'\nWhat a scenario is about (narrative, tension, human tests, brief) is not set here.\n\nExamples:\n $ iamu set scenario maria--handoff --entry /incidents --state-description "Five open incidents at one site"\n $ iamu set persona maria --access coordinator@site-a.test\n $ iamu set outline shift-handoff --capability incident-reporting\n $ iamu set capability team-access --add-path /team\n $ iamu set testability --target http://localhost:5173 --dev-command "./dev" --auth-strategy dev_switcher\n $ iamu set context --domain "Workplace safety" --industry "Manufacturing" --description "..."\n $ iamu set scenario maria--handoff --file patch.json'
|
|
25908
26251
|
).action(
|
|
25909
26252
|
async (type2, slug, opts) => {
|
|
25910
26253
|
const { setEntity: setEntity2 } = await Promise.resolve().then(() => (init_set_entity(), set_entity_exports));
|
|
@@ -26023,41 +26366,65 @@ function registerWalkthroughCommands(program2) {
|
|
|
26023
26366
|
"--surface <text>",
|
|
26024
26367
|
`"browse" (default) for iamu browse, or a description of your own browser tool \u2014 becomes the walker prompt's Driving surface section`
|
|
26025
26368
|
).option("--json", "Output as JSON").action(
|
|
26026
|
-
async (phase, slug, opts) => {
|
|
26369
|
+
async (phase, slug, opts, cmd) => {
|
|
26370
|
+
const effectiveOpts = {
|
|
26371
|
+
...cmd.optsWithGlobals(),
|
|
26372
|
+
...opts
|
|
26373
|
+
};
|
|
26027
26374
|
const { instructions: instructions2 } = await Promise.resolve().then(() => (init_instructions(), instructions_exports));
|
|
26028
|
-
await instructions2(phase, slug,
|
|
26375
|
+
await instructions2(phase, slug, effectiveOpts);
|
|
26029
26376
|
}
|
|
26030
26377
|
);
|
|
26031
26378
|
instrCmd.command("walk [scenario-slug]").description("Compose walking prompt from scenario + persona + outline").option("--scenario <slug>", "Scenario slug (default: active scenario)").option("--run <run-id>", "Run ID (resolves target URL from manifest)").option(
|
|
26032
26379
|
"--surface <text>",
|
|
26033
26380
|
`"browse" (default) for iamu browse, or a description of your own browser tool \u2014 becomes the walker prompt's Driving surface section`
|
|
26034
26381
|
).option("--json", "Output as JSON").action(
|
|
26035
|
-
async (scenarioSlug, opts) => {
|
|
26382
|
+
async (scenarioSlug, opts, cmd) => {
|
|
26383
|
+
const effectiveOpts = {
|
|
26384
|
+
...cmd.parent?.opts(),
|
|
26385
|
+
...cmd.optsWithGlobals(),
|
|
26386
|
+
...opts
|
|
26387
|
+
};
|
|
26036
26388
|
const { instructionsWalk: instructionsWalk2 } = await Promise.resolve().then(() => (init_instructions_walk(), instructions_walk_exports));
|
|
26037
26389
|
await instructionsWalk2({
|
|
26038
|
-
...
|
|
26039
|
-
scenario: scenarioSlug ??
|
|
26390
|
+
...effectiveOpts,
|
|
26391
|
+
scenario: scenarioSlug ?? effectiveOpts.scenario
|
|
26040
26392
|
});
|
|
26041
26393
|
}
|
|
26042
26394
|
);
|
|
26043
26395
|
instrCmd.command("stage [scenario-slug]").description(
|
|
26044
26396
|
"Dynamic staging instructions: persona, outline, tension, boundaries"
|
|
26045
26397
|
).option("--json", "Output as JSON").action(
|
|
26046
|
-
async (scenarioSlug, opts) => {
|
|
26398
|
+
async (scenarioSlug, opts, cmd) => {
|
|
26399
|
+
const effectiveOpts = {
|
|
26400
|
+
...cmd.parent?.opts(),
|
|
26401
|
+
...cmd.optsWithGlobals(),
|
|
26402
|
+
...opts
|
|
26403
|
+
};
|
|
26047
26404
|
const { instructionsStage: instructionsStage2 } = await Promise.resolve().then(() => (init_instructions(), instructions_exports));
|
|
26048
|
-
await instructionsStage2(scenarioSlug,
|
|
26405
|
+
await instructionsStage2(scenarioSlug, effectiveOpts);
|
|
26049
26406
|
}
|
|
26050
26407
|
);
|
|
26051
|
-
instrCmd.command("setup").description("Dynamic project setup instructions & prerequisite checks").option("--json", "Output as JSON").action(async (opts) => {
|
|
26408
|
+
instrCmd.command("setup").description("Dynamic project setup instructions & prerequisite checks").option("--json", "Output as JSON").action(async (opts, cmd) => {
|
|
26409
|
+
const effectiveOpts = {
|
|
26410
|
+
...cmd.parent?.opts(),
|
|
26411
|
+
...cmd.optsWithGlobals(),
|
|
26412
|
+
...opts
|
|
26413
|
+
};
|
|
26052
26414
|
const { instructionsSetup: instructionsSetup2 } = await Promise.resolve().then(() => (init_instructions(), instructions_exports));
|
|
26053
|
-
await instructionsSetup2(
|
|
26415
|
+
await instructionsSetup2(effectiveOpts);
|
|
26054
26416
|
});
|
|
26055
26417
|
instrCmd.command("triage [run-or-scenario-slug]").description(
|
|
26056
26418
|
"Dynamic triage instructions: finding triage, confirmation, dismissal guidance"
|
|
26057
26419
|
).option("--run <run-id>", "Run ID to triage findings for").option("--json", "Output as JSON").action(
|
|
26058
|
-
async (slug, opts) => {
|
|
26420
|
+
async (slug, opts, cmd) => {
|
|
26421
|
+
const effectiveOpts = {
|
|
26422
|
+
...cmd.parent?.opts(),
|
|
26423
|
+
...cmd.optsWithGlobals(),
|
|
26424
|
+
...opts
|
|
26425
|
+
};
|
|
26059
26426
|
const { instructionsTriage: instructionsTriage2 } = await Promise.resolve().then(() => (init_instructions(), instructions_exports));
|
|
26060
|
-
await instructionsTriage2(slug,
|
|
26427
|
+
await instructionsTriage2(slug, effectiveOpts);
|
|
26061
26428
|
}
|
|
26062
26429
|
);
|
|
26063
26430
|
program2.command("browse <command> [args...]").helpGroup("Walkthrough:").description(
|
|
@@ -26195,7 +26562,14 @@ function registerWalkthroughCommands(program2) {
|
|
|
26195
26562
|
);
|
|
26196
26563
|
program2.command("match-record <run-id>").helpGroup("Walkthrough:").description(
|
|
26197
26564
|
"Record finding matches and re-derive the run's since-last-run delta"
|
|
26198
|
-
).option("--file <path>", "Path to matches JSON file (or - for stdin)").option("--data <json>", "Inline matches JSON string").option("--json", "Output match results as JSON").
|
|
26565
|
+
).option("--file <path>", "Path to matches JSON file (or - for stdin)").option("--data <json>", "Inline matches JSON string").option("--json", "Output match results as JSON").addHelpText(
|
|
26566
|
+
"after",
|
|
26567
|
+
`
|
|
26568
|
+
Examples:
|
|
26569
|
+
$ iamu match-record <run-id> --data '{"matches":[]}'
|
|
26570
|
+
$ iamu match-record <run-id> --file matches.json
|
|
26571
|
+
$ iamu match-record <run-id> --json`
|
|
26572
|
+
).action(
|
|
26199
26573
|
async (runId, opts) => {
|
|
26200
26574
|
const { matchRecord: matchRecord2 } = await Promise.resolve().then(() => (init_match(), match_exports));
|
|
26201
26575
|
await matchRecord2(runId, opts);
|
|
@@ -26209,7 +26583,13 @@ function registerWalkthroughCommands(program2) {
|
|
|
26209
26583
|
);
|
|
26210
26584
|
program2.command("evaluate-record <run-id>").helpGroup("Walkthrough:").description("Record evaluation verdicts into the run's verdicts.json").option("--file <path>", "Path to verdicts JSON file (or - for stdin)").option("--data <json>", "Inline verdicts JSON string").option("--json", "Output summary as JSON").option("-y, --yes", "Skip interactive prompts").option("--no-prompt", "Skip interactive prompt to view results").option("--no-push", "Skip pushing the updated run to Iamu Cloud").option("--view", "Open results in browser immediately without prompt").addHelpText(
|
|
26211
26585
|
"after",
|
|
26212
|
-
|
|
26586
|
+
`
|
|
26587
|
+
Examples:
|
|
26588
|
+
$ iamu evaluate-record <run-id> --data '{"verdicts":[]}' --no-prompt --no-push
|
|
26589
|
+
$ iamu evaluate-record <run-id> --file verdicts.json
|
|
26590
|
+
$ iamu evaluate-record <run-id> --file verdicts.json --no-prompt
|
|
26591
|
+
$ iamu evaluate-record <run-id> --file verdicts.json --no-push
|
|
26592
|
+
$ iamu evaluate-record <run-id> --file verdicts.json --json`
|
|
26213
26593
|
).action(
|
|
26214
26594
|
async (runId, opts) => {
|
|
26215
26595
|
const { evaluateRecord: evaluateRecord2 } = await Promise.resolve().then(() => (init_evaluate(), evaluate_exports));
|