@saasontools/strauss-kb 0.1.5 → 0.1.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/README.md +30 -2
- package/dist/{chunk-VOJ6D6OX.js → chunk-BVF7X5VO.js} +2 -2
- package/dist/{chunk-FZIMFPGR.js → chunk-PNSRTKYN.js} +102 -6
- package/dist/chunk-PNSRTKYN.js.map +1 -0
- package/dist/{chunk-KQMGKSPZ.js → chunk-V7TRZ2ER.js} +2 -2
- package/dist/cli-main.cjs +98 -5
- package/dist/cli-main.cjs.map +1 -1
- package/dist/cli-main.js +2 -2
- package/dist/index.cjs +103 -5
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +33 -1
- package/dist/index.d.ts +33 -1
- package/dist/index.js +7 -3
- package/dist/index.js.map +1 -1
- package/dist/mcp-main.cjs +98 -5
- package/dist/mcp-main.cjs.map +1 -1
- package/dist/mcp-main.js +2 -2
- package/package.json +1 -1
- package/dist/chunk-FZIMFPGR.js.map +0 -1
- /package/dist/{chunk-VOJ6D6OX.js.map → chunk-BVF7X5VO.js.map} +0 -0
- /package/dist/{chunk-KQMGKSPZ.js.map → chunk-V7TRZ2ER.js.map} +0 -0
package/dist/cli-main.cjs
CHANGED
|
@@ -45,6 +45,11 @@ var kbActorStampSchema = import_zod.z.object({
|
|
|
45
45
|
by: import_zod.z.string().min(1),
|
|
46
46
|
at: import_zod.z.string().min(1)
|
|
47
47
|
}).passthrough();
|
|
48
|
+
var kbVerifiedEventSchema = kbActorStampSchema.extend({
|
|
49
|
+
note: import_zod.z.string().refine((s) => s.trim().length > 0, {
|
|
50
|
+
message: "note must say what the check found"
|
|
51
|
+
})
|
|
52
|
+
});
|
|
48
53
|
var kbAnchorSchema = import_zod.z.object({
|
|
49
54
|
file: import_zod.z.string().min(1),
|
|
50
55
|
symbol: import_zod.z.string().min(1).optional()
|
|
@@ -1576,8 +1581,37 @@ var validateCommand = define({
|
|
|
1576
1581
|
failsWhen: (result) => Array.isArray(result) && result.length > 0
|
|
1577
1582
|
});
|
|
1578
1583
|
|
|
1579
|
-
// src/commands/
|
|
1584
|
+
// src/commands/verify.ts
|
|
1580
1585
|
var import_zod26 = require("zod");
|
|
1586
|
+
var verifyCommand = define({
|
|
1587
|
+
name: "verify",
|
|
1588
|
+
tool: "kb_verify",
|
|
1589
|
+
usage: "verify <concept-id> --note <text>",
|
|
1590
|
+
description: "Append one verified[] event \u2014 who checked the record, when, and what the check found. Appends only; prior events are never rewritten. A record's own generator is refused unless the actor is human: re-reading your own output is not an independent check.",
|
|
1591
|
+
input: import_zod26.z.object({
|
|
1592
|
+
bundlePath,
|
|
1593
|
+
conceptId,
|
|
1594
|
+
note: import_zod26.z.string().refine((s) => s.trim().length > 0, {
|
|
1595
|
+
message: "note must say what the check found"
|
|
1596
|
+
})
|
|
1597
|
+
}),
|
|
1598
|
+
fromArgv: (argv, path) => ({
|
|
1599
|
+
bundlePath: path,
|
|
1600
|
+
conceptId: argv[1],
|
|
1601
|
+
note: argvFlag(argv, "--note")
|
|
1602
|
+
}),
|
|
1603
|
+
run: async ({ store, actor, now }, { bundlePath: path, conceptId: id, note }) => {
|
|
1604
|
+
await assertBaseNotFrozen(process.cwd(), path);
|
|
1605
|
+
const record = await store.verify(path, id, note, actor, now());
|
|
1606
|
+
return {
|
|
1607
|
+
conceptId: record.conceptId,
|
|
1608
|
+
verified: record.frontmatter.verified?.length ?? 0
|
|
1609
|
+
};
|
|
1610
|
+
}
|
|
1611
|
+
});
|
|
1612
|
+
|
|
1613
|
+
// src/commands/write.ts
|
|
1614
|
+
var import_zod27 = require("zod");
|
|
1581
1615
|
var writeCommand = define({
|
|
1582
1616
|
name: "write",
|
|
1583
1617
|
tool: "kb_write",
|
|
@@ -1591,9 +1625,9 @@ var writeCommand = define({
|
|
|
1591
1625
|
"- Prefer a new record over overloading an existing one, and keep each short. A record nobody finishes reading is not durable memory.",
|
|
1592
1626
|
"- Records are never deleted; supersede instead, so the earlier reasoning stays inspectable."
|
|
1593
1627
|
].join("\n"),
|
|
1594
|
-
input:
|
|
1628
|
+
input: import_zod27.z.object({
|
|
1595
1629
|
bundlePath,
|
|
1596
|
-
type:
|
|
1630
|
+
type: import_zod27.z.enum(KB_RECORD_TYPES),
|
|
1597
1631
|
input: composeInputSchema
|
|
1598
1632
|
}),
|
|
1599
1633
|
fromArgv: async (argv, path, stdin) => ({
|
|
@@ -1617,7 +1651,7 @@ var writeCommand = define({
|
|
|
1617
1651
|
});
|
|
1618
1652
|
|
|
1619
1653
|
// src/commands/write-decision.ts
|
|
1620
|
-
var
|
|
1654
|
+
var import_zod28 = require("zod");
|
|
1621
1655
|
var writeDecisionCommand = define({
|
|
1622
1656
|
name: "write-decision",
|
|
1623
1657
|
tool: "kb_write_decision",
|
|
@@ -1630,7 +1664,7 @@ var writeDecisionCommand = define({
|
|
|
1630
1664
|
"- `alternative` is what you turned down and why, not a list of everything considered.",
|
|
1631
1665
|
"- A reference to material you read goes in `sources`; a reference to code goes in `anchors`; a reference to another record goes in `relatedConceptIds`."
|
|
1632
1666
|
].join("\n"),
|
|
1633
|
-
input:
|
|
1667
|
+
input: import_zod28.z.object({ bundlePath, input: decisionInputSchema }),
|
|
1634
1668
|
fromArgv: async (_argv, path, stdin) => ({
|
|
1635
1669
|
bundlePath: path,
|
|
1636
1670
|
input: JSON.parse(await stdin())
|
|
@@ -1658,6 +1692,7 @@ var KB_COMMANDS = [
|
|
|
1658
1692
|
statusCommand,
|
|
1659
1693
|
supersedeCommand,
|
|
1660
1694
|
answerCommand,
|
|
1695
|
+
verifyCommand,
|
|
1661
1696
|
loadCommand,
|
|
1662
1697
|
queryCommand,
|
|
1663
1698
|
traceCommand,
|
|
@@ -1773,6 +1808,25 @@ var KbWriteConflictError = class extends BaseError {
|
|
|
1773
1808
|
}
|
|
1774
1809
|
conceptId;
|
|
1775
1810
|
};
|
|
1811
|
+
var KbSelfVerificationError = class extends BaseError {
|
|
1812
|
+
constructor(conceptId2, actor, generatedBy) {
|
|
1813
|
+
super({
|
|
1814
|
+
message: `kb: ${conceptId2} was generated by ${generatedBy}, and a record's generator cannot verify it \u2014 only a human or a different actor can`,
|
|
1815
|
+
errorType: "KbSelfVerification" /* KbSelfVerification */,
|
|
1816
|
+
code: 400,
|
|
1817
|
+
fault: "User" /* User */,
|
|
1818
|
+
retriable: false,
|
|
1819
|
+
reportToUser: true,
|
|
1820
|
+
details: { conceptId: conceptId2, actor, generatedBy, action: "refused" }
|
|
1821
|
+
});
|
|
1822
|
+
this.conceptId = conceptId2;
|
|
1823
|
+
this.actor = actor;
|
|
1824
|
+
this.generatedBy = generatedBy;
|
|
1825
|
+
}
|
|
1826
|
+
conceptId;
|
|
1827
|
+
actor;
|
|
1828
|
+
generatedBy;
|
|
1829
|
+
};
|
|
1776
1830
|
var KbInvalidConceptIdError = class extends BaseError {
|
|
1777
1831
|
constructor(message, details) {
|
|
1778
1832
|
super({
|
|
@@ -1991,6 +2045,40 @@ var KbStore = class {
|
|
|
1991
2045
|
{ operation: `status:${status}`, by: actor }
|
|
1992
2046
|
);
|
|
1993
2047
|
}
|
|
2048
|
+
/**
|
|
2049
|
+
* Appends one `verified[]` event: who checked the record, when, and what the
|
|
2050
|
+
* check found. Append-only — prior events are history, and are spread into
|
|
2051
|
+
* the new array untouched rather than reshaped through the write schema.
|
|
2052
|
+
*
|
|
2053
|
+
* A record's generator cannot verify its own record unless the actor is
|
|
2054
|
+
* human: the generator re-reading its own output is not an independent
|
|
2055
|
+
* check. The rule runs before the mutation so a refusal never publishes,
|
|
2056
|
+
* and the refusal is logged under its own operation name — `mutate` only
|
|
2057
|
+
* logs what it publishes.
|
|
2058
|
+
*/
|
|
2059
|
+
async verify(bundlePath2, conceptId2, note, actor = "unknown", at = (/* @__PURE__ */ new Date()).toISOString()) {
|
|
2060
|
+
const event = kbVerifiedEventSchema.parse({ by: actor, at, note });
|
|
2061
|
+
const existing = await this.read(bundlePath2, conceptId2);
|
|
2062
|
+
if (!existing) throw new KbRecordNotFoundError(conceptId2);
|
|
2063
|
+
const generatedBy = existing.frontmatter.generated?.by;
|
|
2064
|
+
if (generatedBy !== void 0 && actor.toLowerCase() === generatedBy.toLowerCase() && !normalizeActor(actor).startsWith("human:")) {
|
|
2065
|
+
await this.record(this.root(bundlePath2), {
|
|
2066
|
+
operation: "verify:refused",
|
|
2067
|
+
conceptId: conceptId2,
|
|
2068
|
+
by: actor
|
|
2069
|
+
});
|
|
2070
|
+
throw new KbSelfVerificationError(conceptId2, actor, generatedBy);
|
|
2071
|
+
}
|
|
2072
|
+
return this.mutate(
|
|
2073
|
+
bundlePath2,
|
|
2074
|
+
conceptId2,
|
|
2075
|
+
(frontmatter) => ({
|
|
2076
|
+
...frontmatter,
|
|
2077
|
+
verified: [...frontmatter.verified ?? [], event]
|
|
2078
|
+
}),
|
|
2079
|
+
{ operation: "verify", by: actor }
|
|
2080
|
+
);
|
|
2081
|
+
}
|
|
1994
2082
|
/**
|
|
1995
2083
|
* Marks `conceptId` superseded by `replacementId`, and links both directions.
|
|
1996
2084
|
*
|
|
@@ -2325,6 +2413,11 @@ function matches(record, needle) {
|
|
|
2325
2413
|
(field) => field?.toLowerCase().includes(needle)
|
|
2326
2414
|
);
|
|
2327
2415
|
}
|
|
2416
|
+
function normalizeActor(id) {
|
|
2417
|
+
const colon = id.indexOf(":");
|
|
2418
|
+
if (colon === -1) return id.toLowerCase();
|
|
2419
|
+
return id.slice(0, colon + 1).toLowerCase() + id.slice(colon + 1);
|
|
2420
|
+
}
|
|
2328
2421
|
function digest(contents) {
|
|
2329
2422
|
return (0, import_node_crypto.createHash)("sha256").update(contents).digest("hex");
|
|
2330
2423
|
}
|