bantamkit-mcp 0.35.2 → 0.35.3
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.
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "shiftwork_clock_out",
|
|
3
|
-
"description": "Shift-work clock-out: record a finished unit — set its status, advance plan.cursor, merge handoff_patch, push history_entry onto the 5-entry ring — validating the whole mutated document against the checkpoint schema BEFORE an atomic write (a failure writes nothing and returns result=error). Every success appends one accounting line (unit, role, status, ts, briefed, plus your accounting fields, e.g. tokens/duration_ms/model) to <checkpoint>.log.jsonl, beside the brief lines clock_in writes (a brief line carries `event` and no `status`). `briefed` is written by the runtime, never taken from you — a self-reported value is overwritten by the measured one: true when a brief was issued for this unit since its LAST clock-out (not ever), so a unit re-run inline after a blocked clock-out reads false.
|
|
3
|
+
"description": "Shift-work clock-out: record a finished unit — set its status, advance plan.cursor, merge handoff_patch, push history_entry onto the 5-entry ring — validating the whole mutated document against the checkpoint schema BEFORE an atomic write (a failure writes nothing and returns result=error). `unit_id` must be `plan.cursor`, the one unit clock_in briefs; any other id is refused (`unit X is not the cursor unit Y`). `handoff_patch` and `history_entry` are both required arguments: `handoff_patch` is shallow-merged into `handoff` and takes only its four keys (pass `{}` to leave it unchanged); `history_entry` needs `unit` and `outcome`; `status` is one of the five unit statuses — a value outside these shapes is refused by the schema check, nothing written. Every success appends one accounting line (unit, role, status, ts, briefed, plus your accounting fields, e.g. tokens/duration_ms/model) to <checkpoint>.log.jsonl, beside the brief lines clock_in writes (a brief line carries `event` and no `status`). `accounting` is optional: null, the default, logs a line with no cost figures at all; a non-null line must fit the accounting shape below. `briefed` is written by the runtime, never taken from you — a self-reported value is overwritten by the measured one: true when a brief was issued for this unit since its LAST clock-out (not ever), so a unit re-run inline after a blocked clock-out reads false. A brief is not a precondition: a unit that was never clocked in still clocks out, with briefed=false. If the checkpoint's job.roles names this unit's role, accounting.model must be one of that role's model identifiers, spelled exactly — a model that is not on the list, or none reported at all, is refused before anything is written; a role job.roles omits, and a checkpoint carrying no job.roles, are unconstrained.",
|
|
4
4
|
"surfaces": [
|
|
5
5
|
"mcp"
|
|
6
6
|
],
|
|
@@ -12,21 +12,76 @@
|
|
|
12
12
|
},
|
|
13
13
|
"unit_id": {
|
|
14
14
|
"title": "Unit Id",
|
|
15
|
-
"type": "string"
|
|
15
|
+
"type": "string",
|
|
16
|
+
"description": "The unit being clocked out. Must equal plan.cursor — the single-pointer contract: clock_in briefs only the cursor unit and clock_out accepts only it."
|
|
16
17
|
},
|
|
17
18
|
"status": {
|
|
18
19
|
"title": "Status",
|
|
19
|
-
"type": "string"
|
|
20
|
+
"type": "string",
|
|
21
|
+
"enum": [
|
|
22
|
+
"todo",
|
|
23
|
+
"in_progress",
|
|
24
|
+
"done",
|
|
25
|
+
"blocked",
|
|
26
|
+
"dropped"
|
|
27
|
+
],
|
|
28
|
+
"description": "The unit's new status; the same five values the checkpoint schema allows on plan.units[].status."
|
|
20
29
|
},
|
|
21
30
|
"handoff_patch": {
|
|
22
|
-
"additionalProperties": true,
|
|
23
31
|
"title": "Handoff Patch",
|
|
24
|
-
"type": "object"
|
|
32
|
+
"type": "object",
|
|
33
|
+
"additionalProperties": false,
|
|
34
|
+
"description": "Shallow-merged into `handoff`: only these four keys exist there, and a key outside them is refused by the schema check. Required; `{}` leaves `handoff` unchanged.",
|
|
35
|
+
"properties": {
|
|
36
|
+
"next_action": {
|
|
37
|
+
"type": "string",
|
|
38
|
+
"minLength": 1,
|
|
39
|
+
"description": "Imperative first move — zero re-derivation."
|
|
40
|
+
},
|
|
41
|
+
"open_questions": {
|
|
42
|
+
"type": "array",
|
|
43
|
+
"items": {
|
|
44
|
+
"type": "string",
|
|
45
|
+
"minLength": 1
|
|
46
|
+
},
|
|
47
|
+
"description": "The autonomy switch: empty = driver keeps cycling, non-empty = STOP and ask."
|
|
48
|
+
},
|
|
49
|
+
"do_not": {
|
|
50
|
+
"type": "array",
|
|
51
|
+
"items": {
|
|
52
|
+
"type": "string",
|
|
53
|
+
"minLength": 1
|
|
54
|
+
},
|
|
55
|
+
"description": "Negative space — near-mistakes past sessions made."
|
|
56
|
+
},
|
|
57
|
+
"notes": {
|
|
58
|
+
"type": "string",
|
|
59
|
+
"description": "Free-form prose for the next session, one string; the empty string clears it."
|
|
60
|
+
}
|
|
61
|
+
}
|
|
25
62
|
},
|
|
26
63
|
"history_entry": {
|
|
27
|
-
"additionalProperties": true,
|
|
28
64
|
"title": "History Entry",
|
|
29
|
-
"type": "object"
|
|
65
|
+
"type": "object",
|
|
66
|
+
"required": [
|
|
67
|
+
"unit",
|
|
68
|
+
"outcome"
|
|
69
|
+
],
|
|
70
|
+
"additionalProperties": true,
|
|
71
|
+
"description": "Pushed onto the 5-entry `history` ring; `unit` and `outcome` are required, `notes` optional, other keys pass through.",
|
|
72
|
+
"properties": {
|
|
73
|
+
"unit": {
|
|
74
|
+
"type": "string",
|
|
75
|
+
"minLength": 1
|
|
76
|
+
},
|
|
77
|
+
"outcome": {
|
|
78
|
+
"type": "string",
|
|
79
|
+
"minLength": 1
|
|
80
|
+
},
|
|
81
|
+
"notes": {
|
|
82
|
+
"type": "string"
|
|
83
|
+
}
|
|
84
|
+
}
|
|
30
85
|
},
|
|
31
86
|
"accounting": {
|
|
32
87
|
"anyOf": [
|
|
@@ -37,7 +92,7 @@
|
|
|
37
92
|
"tokens": {
|
|
38
93
|
"type": "integer",
|
|
39
94
|
"minimum": 0,
|
|
40
|
-
"description": "Tokens the unit consumed as the harness's subagent counter reports them: every class it reports (input, output, cache creation) summed, EXCLUDING cache reads.
|
|
95
|
+
"description": "Tokens the unit consumed as the harness's subagent counter reports them: every class it reports (input, output, cache creation) summed, EXCLUDING cache reads. In a non-null accounting line it is required — a line without it is refused before anything is written; only `accounting: null`, the default, is exempt, and that logs no cost at all. A rounded self-estimate is allowed only if `note` says it is one; a unit whose cost is unknown cannot be compared with any other."
|
|
41
96
|
},
|
|
42
97
|
"cache_read_tokens": {
|
|
43
98
|
"type": "integer",
|
|
@@ -47,7 +102,7 @@
|
|
|
47
102
|
"duration_ms": {
|
|
48
103
|
"type": "integer",
|
|
49
104
|
"minimum": 0,
|
|
50
|
-
"description": "Wall-clock from spawning the subagent to its final message, in whole milliseconds.
|
|
105
|
+
"description": "Wall-clock from spawning the subagent to its final message, in whole milliseconds. In a non-null line it is required, and it is the only duration key with a defined meaning: older lines carry `duration`, `duration_min` or `duration_s`, which this schema neither reads nor renames."
|
|
51
106
|
},
|
|
52
107
|
"model": {
|
|
53
108
|
"type": "string",
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "shiftwork_plan",
|
|
3
|
-
"description": "Shift-work plan: read-only batch view of a checkpoint — which units its `depends_on` graph permits to run in parallel. Answers `{\"result\": \"plan\", \"batches\", \"ready\", \"sequence\", \"width\", \"cursor\"}`: `ready` is `batches[0]`, the units
|
|
3
|
+
"description": "Shift-work plan: read-only batch view of a checkpoint — which units its `depends_on` graph permits to run in parallel. Answers `{\"result\": \"plan\", \"batches\", \"ready\", \"sequence\", \"width\", \"cursor\"}`: `ready` is `batches[0]`, the units whose dependencies are all satisfied, and `width` is the largest batch length, the widest fan-out. Only `cursor` can be clocked: shiftwork_clock_in briefs it and shiftwork_clock_out refuses every other id, so a `ready` member beyond the cursor is what the graph permits, not a unit the clock accepts yet. Units with status `done` or `dropped` are satisfied — dropped from the graph, and edges pointing at them treated as already resolved; `todo`, `in_progress` and `blocked` stay in it. Every unit has priority 0, because the checkpoint schema has no priority field, so order inside a batch is `plan.units` order. Same refusal sentences as `work_plan` for a duplicate id, an unknown dependency or a cycle, and the same refusals `shiftwork_status` gives for a checkpoint it cannot read. It reports what the dependency graph permits; it does not move the cursor, which is echoed unchanged so the single-pointer contract and the batch view can be read side by side. An orchestrator stays responsible for what it actually dispatches: `depends_on` encodes logical order, not file contention. Never mutates.",
|
|
4
4
|
"surfaces": [
|
|
5
5
|
"mcp"
|
|
6
6
|
],
|
package/dist/mcp/server.js
CHANGED
|
@@ -1068,6 +1068,24 @@ export function buildServer(memory, wire, version, log = EventLog.fromEnv(memory
|
|
|
1068
1068
|
const uri = request.params.uri;
|
|
1069
1069
|
const skill = /^bantamkit:\/\/skills\/([^/]*)$/.exec(uri);
|
|
1070
1070
|
if (skill) {
|
|
1071
|
+
// A skill that pairs with a tool is served on that tool's surfaces and no other. The
|
|
1072
|
+
// pairing is the one the reference's `filegraph.py` spells — `load_tool("file_graph")`
|
|
1073
|
+
// beside `load_skill("file-graph")`, the skill's name with `-` for `_`. `file-graph` is
|
|
1074
|
+
// the eval agent's snippet telling it to call `file_graph`, whose asset claims only
|
|
1075
|
+
// `agent`; handing it to an MCP client names a tool `tools/list` does not carry (job60
|
|
1076
|
+
// row 46). Same sentence and code as the reference; the `instructions` suite gates it.
|
|
1077
|
+
const paired = skill[1].replace(/-/g, '_');
|
|
1078
|
+
let pairedSurfaces = null;
|
|
1079
|
+
try {
|
|
1080
|
+
pairedSurfaces = (loadToolAsset(paired)['surfaces'] ?? []);
|
|
1081
|
+
}
|
|
1082
|
+
catch (e) {
|
|
1083
|
+
if (!(e instanceof AssetNotFound))
|
|
1084
|
+
throw e;
|
|
1085
|
+
}
|
|
1086
|
+
if (pairedSurfaces !== null && !pairedSurfaces.includes('mcp')) {
|
|
1087
|
+
throw rpcError(ErrorCode.InternalError, `skill asset ${skill[1]} is not served here: it pairs with tool ${paired}, whose asset claims surfaces [${pairedSurfaces.map((s) => `'${s}'`).join(', ')}], not mcp`, { uri });
|
|
1088
|
+
}
|
|
1071
1089
|
let text;
|
|
1072
1090
|
try {
|
|
1073
1091
|
text = loadSkill(skill[1]);
|
package/dist/memory/store.js
CHANGED
|
@@ -258,7 +258,7 @@ const FACTS_UNREADABLE = 'a store whose facts could not be listed is not a store
|
|
|
258
258
|
"answering 'empty' here is what rewrites index.md from nothing";
|
|
259
259
|
const ARCHIVE_UNREADABLE = 'an archive that could not be listed is not an empty archive, and answering ' +
|
|
260
260
|
"'nothing is archived' here is what makes compaction look like deletion — the " +
|
|
261
|
-
'facts
|
|
261
|
+
'facts that compaction moved are still on disk under this path';
|
|
262
262
|
const ARCHIVE_UNREACHABLE = "an archived fact that could not be stat'd is not an archived fact that is not " +
|
|
263
263
|
"there, and answering 'no archived fact' here sends the operator looking for a " +
|
|
264
264
|
'file that is still on disk under this path';
|
|
@@ -1412,7 +1412,7 @@ export class MemoryStore {
|
|
|
1412
1412
|
const size = Buffer.byteLength(this.indexText(), 'utf8');
|
|
1413
1413
|
if (size > this.indexBudget) {
|
|
1414
1414
|
throw new MemoryBudgetExceeded(`memory index is ${size} bytes, budget is ${this.indexBudget}: ` +
|
|
1415
|
-
'
|
|
1415
|
+
'compact the store or tersen descriptions');
|
|
1416
1416
|
}
|
|
1417
1417
|
}
|
|
1418
1418
|
}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "bantamkit-mcp",
|
|
3
|
-
"version": "0.35.
|
|
3
|
+
"version": "0.35.3",
|
|
4
4
|
"description": "Memory MCP server for Claude Code, Cursor, VS Code Copilot and Claude Desktop: per-person memory, JSON Schema validation, shift-work tools. Pure Node; install once with npx, run offline.",
|
|
5
5
|
"keywords": [
|
|
6
6
|
"mcp",
|