@saasontools/strauss-kb 0.1.20 → 0.1.21
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 +5 -7
- package/dist/{chunk-XDH6J6CH.js → chunk-VXWN62HT.js} +2 -2
- package/dist/{chunk-EXZQZJU2.js → chunk-WVJULVGY.js} +2 -2
- package/dist/{chunk-QQLPJO4R.js → chunk-XBZ7G5R5.js} +78 -49
- package/dist/chunk-XBZ7G5R5.js.map +1 -0
- package/dist/cli-main.cjs +75 -48
- package/dist/cli-main.cjs.map +1 -1
- package/dist/cli-main.js +2 -2
- package/dist/index.cjs +77 -48
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +2 -0
- package/dist/index.d.ts +2 -0
- package/dist/index.js +3 -3
- package/dist/mcp-main.cjs +75 -48
- package/dist/mcp-main.cjs.map +1 -1
- package/dist/mcp-main.js +2 -2
- package/package.json +1 -1
- package/dist/chunk-QQLPJO4R.js.map +0 -1
- /package/dist/{chunk-XDH6J6CH.js.map → chunk-VXWN62HT.js.map} +0 -0
- /package/dist/{chunk-EXZQZJU2.js.map → chunk-WVJULVGY.js.map} +0 -0
package/dist/index.d.cts
CHANGED
|
@@ -1501,6 +1501,8 @@ declare enum Fault {
|
|
|
1501
1501
|
declare enum ErrorTypes {
|
|
1502
1502
|
KbRecordAlreadyExists = "KbRecordAlreadyExists",
|
|
1503
1503
|
KbClassifyInput = "KbClassifyInput",
|
|
1504
|
+
KbFlagConflict = "KbFlagConflict",
|
|
1505
|
+
KbInvalidActor = "KbInvalidActor",
|
|
1504
1506
|
KbInvalidConceptId = "KbInvalidConceptId",
|
|
1505
1507
|
KbMatchInput = "KbMatchInput",
|
|
1506
1508
|
KbMissingFlagValue = "KbMissingFlagValue",
|
package/dist/index.d.ts
CHANGED
|
@@ -1501,6 +1501,8 @@ declare enum Fault {
|
|
|
1501
1501
|
declare enum ErrorTypes {
|
|
1502
1502
|
KbRecordAlreadyExists = "KbRecordAlreadyExists",
|
|
1503
1503
|
KbClassifyInput = "KbClassifyInput",
|
|
1504
|
+
KbFlagConflict = "KbFlagConflict",
|
|
1505
|
+
KbInvalidActor = "KbInvalidActor",
|
|
1504
1506
|
KbInvalidConceptId = "KbInvalidConceptId",
|
|
1505
1507
|
KbMatchInput = "KbMatchInput",
|
|
1506
1508
|
KbMissingFlagValue = "KbMissingFlagValue",
|
package/dist/index.js
CHANGED
|
@@ -1,10 +1,10 @@
|
|
|
1
1
|
import {
|
|
2
2
|
runKbCli
|
|
3
|
-
} from "./chunk-
|
|
3
|
+
} from "./chunk-VXWN62HT.js";
|
|
4
4
|
import {
|
|
5
5
|
createKbMcpServer,
|
|
6
6
|
runKbMcpServer
|
|
7
|
-
} from "./chunk-
|
|
7
|
+
} from "./chunk-WVJULVGY.js";
|
|
8
8
|
import {
|
|
9
9
|
BaseError,
|
|
10
10
|
CONTEXT_BEGIN,
|
|
@@ -149,7 +149,7 @@ import {
|
|
|
149
149
|
unifiedDiff,
|
|
150
150
|
unpinBase,
|
|
151
151
|
validateBundle
|
|
152
|
-
} from "./chunk-
|
|
152
|
+
} from "./chunk-XBZ7G5R5.js";
|
|
153
153
|
export {
|
|
154
154
|
BaseError,
|
|
155
155
|
CONTEXT_BEGIN,
|
package/dist/mcp-main.cjs
CHANGED
|
@@ -2349,6 +2349,38 @@ var KbSelfVerificationError = class extends BaseError {
|
|
|
2349
2349
|
actor;
|
|
2350
2350
|
generatedBy;
|
|
2351
2351
|
};
|
|
2352
|
+
var KbInvalidActorError = class extends BaseError {
|
|
2353
|
+
constructor(actor, reason) {
|
|
2354
|
+
super({
|
|
2355
|
+
message: `kb: actor ${JSON.stringify(actor)} ${reason} \u2014 set STRAUSS_KB_ACTOR, e.g. human:alice or agent:reviewer`,
|
|
2356
|
+
errorType: "KbInvalidActor" /* KbInvalidActor */,
|
|
2357
|
+
code: 400,
|
|
2358
|
+
fault: "User" /* User */,
|
|
2359
|
+
retriable: false,
|
|
2360
|
+
reportToUser: true,
|
|
2361
|
+
details: { actor, reason, action: "refused" }
|
|
2362
|
+
});
|
|
2363
|
+
this.actor = actor;
|
|
2364
|
+
this.reason = reason;
|
|
2365
|
+
}
|
|
2366
|
+
actor;
|
|
2367
|
+
reason;
|
|
2368
|
+
};
|
|
2369
|
+
var KbFlagConflictError = class extends BaseError {
|
|
2370
|
+
constructor(flags) {
|
|
2371
|
+
super({
|
|
2372
|
+
message: `kb: ${flags.join(" and ")} cannot be combined`,
|
|
2373
|
+
errorType: "KbFlagConflict" /* KbFlagConflict */,
|
|
2374
|
+
code: 400,
|
|
2375
|
+
fault: "User" /* User */,
|
|
2376
|
+
retriable: false,
|
|
2377
|
+
reportToUser: true,
|
|
2378
|
+
details: { flags }
|
|
2379
|
+
});
|
|
2380
|
+
this.flags = flags;
|
|
2381
|
+
}
|
|
2382
|
+
flags;
|
|
2383
|
+
};
|
|
2352
2384
|
var KbPackBudgetExceededError = class extends BaseError {
|
|
2353
2385
|
constructor(recordCount, approxTokens2, budgetTokens, excluded) {
|
|
2354
2386
|
super({
|
|
@@ -2892,19 +2924,11 @@ function argvPositional(argv, ...names) {
|
|
|
2892
2924
|
}
|
|
2893
2925
|
|
|
2894
2926
|
// src/commands/anchor-resolve.ts
|
|
2895
|
-
function resolverSummary(results) {
|
|
2896
|
-
const names = [
|
|
2897
|
-
...new Set(
|
|
2898
|
-
results.flatMap((entry) => entry.resolver ? [entry.resolver] : [])
|
|
2899
|
-
)
|
|
2900
|
-
].sort();
|
|
2901
|
-
return names.length ? `${names.join(" + ")} resolver` : "whole-file";
|
|
2902
|
-
}
|
|
2903
2927
|
var anchorResolveCommand = define({
|
|
2904
2928
|
name: "anchor-resolve",
|
|
2905
2929
|
tool: "kb_anchor_resolve",
|
|
2906
|
-
usage: "anchor-resolve <concept-id> [--repo-root <path>] [--offline] [--rebaseline] [--restamp]",
|
|
2907
|
-
description: "Resolve a record's anchors: stamp a hash onto anchors that lack one, report drift where the code moved. An anchor naming another repository is read from that remote through a bare cache; --offline uses the cache only.
|
|
2930
|
+
usage: "anchor-resolve <concept-id> [--repo-root <path>] [--offline] [--rebaseline] [--restamp] [--check]",
|
|
2931
|
+
description: "Resolve a record's anchors: stamp a hash onto anchors that lack one, report drift where the code moved. An anchor naming another repository is read from that remote through a bare cache; --offline uses the cache only. Never writes verified[]; a judgment is kb_verify. Exits non-zero on drift.",
|
|
2908
2932
|
input: import_zod7.z.object({
|
|
2909
2933
|
bundlePath,
|
|
2910
2934
|
conceptId,
|
|
@@ -2917,6 +2941,9 @@ var anchorResolveCommand = define({
|
|
|
2917
2941
|
),
|
|
2918
2942
|
restamp: import_zod7.z.boolean().optional().describe(
|
|
2919
2943
|
"Refresh `resolved_at` on anchors that already match. Off by default, so a green run writes nothing."
|
|
2944
|
+
),
|
|
2945
|
+
check: import_zod7.z.boolean().optional().describe(
|
|
2946
|
+
"Resolve and report only: no hash, no `resolved_at`, no log entry."
|
|
2920
2947
|
)
|
|
2921
2948
|
}),
|
|
2922
2949
|
fromArgv: (argv, path) => ({
|
|
@@ -2925,9 +2952,24 @@ var anchorResolveCommand = define({
|
|
|
2925
2952
|
repoRoot: argvFlag(argv, "--repo-root"),
|
|
2926
2953
|
offline: argv.includes("--offline"),
|
|
2927
2954
|
rebaseline: argv.includes("--rebaseline"),
|
|
2928
|
-
restamp: argv.includes("--restamp")
|
|
2955
|
+
restamp: argv.includes("--restamp"),
|
|
2956
|
+
check: argv.includes("--check")
|
|
2929
2957
|
}),
|
|
2930
|
-
run: async ({ store, actor, now }, {
|
|
2958
|
+
run: async ({ store, actor, now }, {
|
|
2959
|
+
bundlePath: path,
|
|
2960
|
+
conceptId: id,
|
|
2961
|
+
repoRoot,
|
|
2962
|
+
offline,
|
|
2963
|
+
rebaseline,
|
|
2964
|
+
restamp,
|
|
2965
|
+
check
|
|
2966
|
+
}) => {
|
|
2967
|
+
if (check && (rebaseline || restamp)) {
|
|
2968
|
+
throw new KbFlagConflictError([
|
|
2969
|
+
"check",
|
|
2970
|
+
rebaseline ? "rebaseline" : "restamp"
|
|
2971
|
+
]);
|
|
2972
|
+
}
|
|
2931
2973
|
const root = repoRoot ?? process.cwd();
|
|
2932
2974
|
const record = await store.read(path, id);
|
|
2933
2975
|
if (!record) throw new KbRecordNotFoundError(id);
|
|
@@ -2936,7 +2978,6 @@ var anchorResolveCommand = define({
|
|
|
2936
2978
|
return {
|
|
2937
2979
|
conceptId: id,
|
|
2938
2980
|
results: [],
|
|
2939
|
-
verified: false,
|
|
2940
2981
|
note: "record has no anchors"
|
|
2941
2982
|
};
|
|
2942
2983
|
}
|
|
@@ -2994,7 +3035,7 @@ var anchorResolveCommand = define({
|
|
|
2994
3035
|
if (!anchor.hash) {
|
|
2995
3036
|
results.push({
|
|
2996
3037
|
...base2,
|
|
2997
|
-
state: "stamped",
|
|
3038
|
+
state: check ? "unstamped" : "stamped",
|
|
2998
3039
|
currentHash: stampedHash,
|
|
2999
3040
|
hashKind: stampedKind,
|
|
3000
3041
|
...producedBy ? { resolver: producedBy } : {}
|
|
@@ -3046,7 +3087,7 @@ var anchorResolveCommand = define({
|
|
|
3046
3087
|
if (refresh) dirty = true;
|
|
3047
3088
|
}
|
|
3048
3089
|
let frozen = false;
|
|
3049
|
-
if (dirty) {
|
|
3090
|
+
if (dirty && !check) {
|
|
3050
3091
|
try {
|
|
3051
3092
|
await assertBaseNotFrozen(process.cwd(), path);
|
|
3052
3093
|
} catch (error) {
|
|
@@ -3061,42 +3102,11 @@ var anchorResolveCommand = define({
|
|
|
3061
3102
|
const unreachable = results.filter(
|
|
3062
3103
|
(entry) => isUncheckedReason(entry.reason)
|
|
3063
3104
|
).length;
|
|
3064
|
-
const checked = results.length - unreachable;
|
|
3065
3105
|
const matches3 = results.filter((entry) => entry.state === "match").length;
|
|
3066
|
-
const note = `${matches3}/${
|
|
3067
|
-
const clean = checked > 0 && matches3 === checked && unreachable === 0;
|
|
3068
|
-
if (clean) {
|
|
3069
|
-
try {
|
|
3070
|
-
await store.verify(
|
|
3071
|
-
path,
|
|
3072
|
-
id,
|
|
3073
|
-
`anchor-resolve: ${note} (${resolverSummary(results)})`,
|
|
3074
|
-
actor,
|
|
3075
|
-
now()
|
|
3076
|
-
);
|
|
3077
|
-
} catch (error) {
|
|
3078
|
-
if (!(error instanceof KbSelfVerificationError)) throw error;
|
|
3079
|
-
return {
|
|
3080
|
-
conceptId: id,
|
|
3081
|
-
results,
|
|
3082
|
-
verified: false,
|
|
3083
|
-
verifyRefused: "self-verification",
|
|
3084
|
-
...frozenNote,
|
|
3085
|
-
...hintNote
|
|
3086
|
-
};
|
|
3087
|
-
}
|
|
3088
|
-
return {
|
|
3089
|
-
conceptId: id,
|
|
3090
|
-
results,
|
|
3091
|
-
verified: true,
|
|
3092
|
-
...frozenNote,
|
|
3093
|
-
...hintNote
|
|
3094
|
-
};
|
|
3095
|
-
}
|
|
3106
|
+
const note = `${matches3}/${results.length - unreachable} anchors match, ${unreachable} unreachable`;
|
|
3096
3107
|
return {
|
|
3097
3108
|
conceptId: id,
|
|
3098
3109
|
results,
|
|
3099
|
-
verified: false,
|
|
3100
3110
|
...unreachable ? { note } : {},
|
|
3101
3111
|
...frozenNote,
|
|
3102
3112
|
...hintNote
|
|
@@ -7653,6 +7663,7 @@ var KbStore = class {
|
|
|
7653
7663
|
* its contents.
|
|
7654
7664
|
*/
|
|
7655
7665
|
async write(bundlePath2, input, actor = "unknown") {
|
|
7666
|
+
assertActor(actor);
|
|
7656
7667
|
if (!KB_SLUG_PATTERN.test(input.slug)) {
|
|
7657
7668
|
throw new KbInvalidConceptIdError("slug must be kebab-case", {
|
|
7658
7669
|
slug: input.slug
|
|
@@ -7754,6 +7765,7 @@ var KbStore = class {
|
|
|
7754
7765
|
* timeouts.
|
|
7755
7766
|
*/
|
|
7756
7767
|
async setStatus(bundlePath2, conceptId2, status, actor = "unknown") {
|
|
7768
|
+
assertActor(actor);
|
|
7757
7769
|
return this.mutate(
|
|
7758
7770
|
bundlePath2,
|
|
7759
7771
|
conceptId2,
|
|
@@ -7772,6 +7784,7 @@ var KbStore = class {
|
|
|
7772
7784
|
* the frontmatter must not be published back out under an actor stamp.
|
|
7773
7785
|
*/
|
|
7774
7786
|
async updateAnchors(bundlePath2, conceptId2, anchors, actor = "unknown") {
|
|
7787
|
+
assertActor(actor);
|
|
7775
7788
|
const checked = anchors.map((anchor) => kbAnchorWriteSchema.parse(anchor));
|
|
7776
7789
|
return this.mutate(
|
|
7777
7790
|
bundlePath2,
|
|
@@ -7792,6 +7805,7 @@ var KbStore = class {
|
|
|
7792
7805
|
* logs what it publishes.
|
|
7793
7806
|
*/
|
|
7794
7807
|
async verify(bundlePath2, conceptId2, note, actor = "unknown", at2 = (/* @__PURE__ */ new Date()).toISOString()) {
|
|
7808
|
+
assertActor(actor, { named: true });
|
|
7795
7809
|
const event = kbVerifiedEventSchema.parse({ by: actor, at: at2, note });
|
|
7796
7810
|
const existing = await this.read(bundlePath2, conceptId2);
|
|
7797
7811
|
if (!existing) throw new KbRecordNotFoundError(conceptId2);
|
|
@@ -7822,6 +7836,7 @@ var KbStore = class {
|
|
|
7822
7836
|
* in normal use, and validation drops to catching hand-edits.
|
|
7823
7837
|
*/
|
|
7824
7838
|
async supersede(bundlePath2, conceptId2, replacementId, actor = "unknown") {
|
|
7839
|
+
assertActor(actor);
|
|
7825
7840
|
const replacement = await this.read(bundlePath2, replacementId);
|
|
7826
7841
|
if (!replacement) throw new KbRecordNotFoundError(replacementId);
|
|
7827
7842
|
const superseded = await this.markSuperseded(
|
|
@@ -7845,6 +7860,7 @@ var KbStore = class {
|
|
|
7845
7860
|
}
|
|
7846
7861
|
/** Resolves an open question, stamping who answered and when. */
|
|
7847
7862
|
async answer(bundlePath2, conceptId2, answer, actor = "unknown", at2 = (/* @__PURE__ */ new Date()).toISOString()) {
|
|
7863
|
+
assertActor(actor);
|
|
7848
7864
|
return this.mutate(
|
|
7849
7865
|
bundlePath2,
|
|
7850
7866
|
conceptId2,
|
|
@@ -7871,6 +7887,7 @@ ${answer}
|
|
|
7871
7887
|
* terminal status since the caller listed it is reported, not removed.
|
|
7872
7888
|
*/
|
|
7873
7889
|
async deleteRecord(bundlePath2, conceptId2, expected, actor = "unknown") {
|
|
7890
|
+
assertActor(actor);
|
|
7874
7891
|
const target = this.recordPath(bundlePath2, conceptId2);
|
|
7875
7892
|
const witness = await this.read(bundlePath2, conceptId2);
|
|
7876
7893
|
if (!witness) throw new KbRecordNotFoundError(conceptId2);
|
|
@@ -8174,6 +8191,7 @@ ${answer}
|
|
|
8174
8191
|
* base too, where nothing was written.
|
|
8175
8192
|
*/
|
|
8176
8193
|
async note(bundlePath2, entry) {
|
|
8194
|
+
assertActor(entry.by);
|
|
8177
8195
|
await this.record(this.root(bundlePath2), entry);
|
|
8178
8196
|
}
|
|
8179
8197
|
/**
|
|
@@ -8431,9 +8449,18 @@ function normalizeActor(id) {
|
|
|
8431
8449
|
if (colon === -1) return id.toLowerCase();
|
|
8432
8450
|
return id.slice(0, colon + 1).toLowerCase() + id.slice(colon + 1);
|
|
8433
8451
|
}
|
|
8452
|
+
var KB_ACTOR_PATTERN = /^[A-Za-z][\w-]*(?::[\p{L}\p{M}\p{N}_.@+/-]+)?$/u;
|
|
8453
|
+
function assertActor(actor, { named = false } = {}) {
|
|
8454
|
+
if (!KB_ACTOR_PATTERN.test(actor)) {
|
|
8455
|
+
throw new KbInvalidActorError(actor, "is not kind or kind:name");
|
|
8456
|
+
}
|
|
8457
|
+
if (named && normalizeActor(actor) === "unknown") {
|
|
8458
|
+
throw new KbInvalidActorError(actor, "cannot verify: name who checked");
|
|
8459
|
+
}
|
|
8460
|
+
}
|
|
8434
8461
|
|
|
8435
8462
|
// src/version.ts
|
|
8436
|
-
var VERSION = true ? "0.1.
|
|
8463
|
+
var VERSION = true ? "0.1.21" : "0.0.0-dev";
|
|
8437
8464
|
|
|
8438
8465
|
// src/mcp.ts
|
|
8439
8466
|
function createKbMcpServer() {
|