🎩 You're Invited:Meet the Socket team at Black Hat in Las Vegas, August 3-6.RSVP
Sign In

@marrowid/cli

Package Overview
Dependencies
Maintainers
1
Versions
17
Alerts
File Explorer

Advanced tools

Socket logo

Install Socket

Detect and block malicious and high-risk dependencies

Install

@marrowid/cli - npm Package Compare versions

Comparing version
1.0.10
to
1.0.11
+4
-3
api/public-dto/build.js

@@ -29,5 +29,6 @@ /**

function projectField(field, raw, audiences) {
if (raw === null && field.emitNull) {
return null;
}
if (raw === undefined)
return undefined;
if (raw === null)
return field.emitNull ? null : undefined;
if (field.items !== undefined) {

@@ -34,0 +35,0 @@ if (!Array.isArray(raw)) {

@@ -56,11 +56,141 @@ /**

},
// ----- evidence query result (POST /v1/query) -----------------------------
evidenceQueryResult: {
id: "evidenceQueryResult",
schemaVersion: "marrow-evidence-query-v2",
queryResult: {
id: "queryResult",
schemaVersion: "marrow-query-result-v1",
routes: ["POST /v1/query", "POST /v1/account/answers/query"],
fields: [
{ key: "schemaVersion" },
{ key: "presetContractVersion" },
{ key: "requestedPreset", allowedValues: ["efficient", "accuracy"] },
{ key: "resolvedPreset", allowedValues: ["efficient", "accuracy"] },
{ key: "generatedAt" },
{ key: "query" },
{ key: "mode", allowedValues: ["evidence", "context", "answer"] },
{ key: "coverage", allowedValues: ["complete", "partial", "unknown", "not_applicable"] },
{ key: "execution", allowedValues: ["ready", "degraded", "provider_required", "preparing"] },
{ key: "stopReason", allowedValues: [
"complete",
"evidence_exhausted",
"budget_exhausted",
"deadline",
"provider_unavailable",
"preparing",
"owner_review_required",
"failed",
] },
{ key: "answer", nested: "queryAnswer", emitNull: true },
{ key: "evidence", items: "queryEvidence" },
{ key: "context", nested: "queryContext", emitNull: true },
{ key: "citations", items: "queryCitation" },
{ key: "limitations" },
{ key: "gaps", items: "queryGap" },
{ key: "conflicts", items: "queryConflict" },
{ key: "operation", nested: "queryOperation" },
],
},
queryAnswer: {
id: "queryAnswer",
fields: [
{ key: "disposition", allowedValues: [
"answered",
"partial",
"insufficient_evidence",
"conflicted",
"withheld",
] },
{ key: "text" },
{ key: "propositions", items: "queryProposition" },
],
},
queryProposition: {
id: "queryProposition",
fields: [
{ key: "text" },
{ key: "support", allowedValues: ["quotation", "compression", "inference"] },
{ key: "citationHandles" },
],
},
queryEvidence: {
id: "queryEvidence",
fields: [
{ key: "citationHandle" },
{ key: "text" },
{ key: "sourceLabel" },
{ key: "support", allowedValues: ["quotation", "compression", "inference"] },
{ key: "authority" },
],
},
queryContext: {
id: "queryContext",
fields: [
{ key: "text" },
{ key: "tokenEstimate" },
{ key: "fragments", items: "queryContextFragment" },
],
},
queryContextFragment: {
id: "queryContextFragment",
fields: [
{ key: "kind", allowedValues: ["evidence", "message", "representation", "generated_context"] },
{ key: "text" },
{ key: "citable" },
{ key: "promptEligible" },
{ key: "sourceLabel" },
],
},
queryCitation: {
id: "queryCitation",
fields: [
{ key: "citationHandle" },
{ key: "displayOrdinal" },
{ key: "excerpt" },
{ key: "sourceLabel" },
{ key: "support", allowedValues: ["quotation", "compression", "inference"] },
{ key: "charOffsetStart" },
{ key: "charOffsetEnd" },
],
},
queryGap: {
id: "queryGap",
fields: [
{ key: "code" },
{ key: "description" },
{ key: "required" },
],
},
queryConflict: {
id: "queryConflict",
fields: [
{ key: "code" },
{ key: "description" },
{ key: "citationHandles" },
],
},
queryOperation: {
id: "queryOperation",
fields: [
{ key: "id" },
{ key: "state" },
{ key: "creditsCharged" },
{ key: "balance", nested: "operationCreditBalance" },
{ key: "usage", nested: "queryOperationUsage" },
],
},
queryOperationUsage: {
id: "queryOperationUsage",
fields: [
{ key: "elapsedMs" },
{ key: "contextCharacters" },
{ key: "inputTokens" },
{ key: "outputTokens" },
{ key: "totalTokens" },
{ key: "providerCalls" },
],
},
// Internal allowlisted projection used while assembling QueryResult.
evidenceQueryResult: {
id: "evidenceQueryResult",
fields: [
{ key: "generatedAt" },
{ key: "query" },
{ key: "answer", nested: "evidenceAnswer" },

@@ -316,2 +446,3 @@ { key: "results", items: "evidenceResult" },

{ key: "scopes" },
{ key: "maxQueryPreset", allowedValues: ["efficient", "accuracy"] },
{ key: "lastUsedAt" },

@@ -792,33 +923,2 @@ { key: "expiresAt" },

},
// ----- context / ask (assembled, fail-closed) -----------------------------
memoryContext: {
id: "memoryContext",
fields: [
{ key: "status" }, // ready|partial|insufficient_evidence|conflicted|withheld — never "answered"
{ key: "placement" },
{ key: "context" }, // the injection-fenced string
{ key: "messages", items: "contextMessage" },
{ key: "blocks", items: "contextBlock" },
{ key: "citations", items: "claimCitation" }, // span citations live here
{ key: "conflicts" },
{ key: "warnings" },
],
},
contextBlock: {
id: "contextBlock",
fields: [
{ key: "authority" },
{ key: "state" },
{ key: "text" },
{ key: "support_status" },
{ key: "citations", items: "claimCitation" },
],
},
contextMessage: {
id: "contextMessage",
fields: [
{ key: "role" },
{ key: "content" },
],
},
// ----- write receipt + representation -------------------------------------

@@ -825,0 +925,0 @@ messagesCreateReceipt: {

@@ -77,3 +77,3 @@ /**

const { client, env } = options;
const callTool = async (name, args) => {
const callTool = async (name, args, queryOperationId) => {
const tool = getTool(name);

@@ -88,2 +88,5 @@ if (!tool) {

}
if (tool.requiresQueryOperationId && !validQueryOperationId(queryOperationId)) {
return toolError("invalid_request", "query_context requires host metadata id.marrow/queryOperationId.", 400);
}
// Fail-closed guards run BEFORE any HTTP call, so a malformed destructive

@@ -96,3 +99,3 @@ // tool request returns an error without reaching the hosted API.

try {
return await dispatch(tool, args, client, env);
return await dispatch(tool, args, client, { ...env, ...(queryOperationId ? { queryOperationId } : {}) });
}

@@ -139,3 +142,7 @@ catch (error) {

const args = (request.params?.arguments ?? {});
const result = await callTool(name, args);
const meta = request.params?._meta;
const operationId = meta && typeof meta === "object"
? meta["id.marrow/queryOperationId"]
: undefined;
const result = await callTool(name, args, typeof operationId === "string" ? operationId : undefined);
return respond(id, result);

@@ -147,1 +154,4 @@ }

}
function validQueryOperationId(value) {
return typeof value === "string" && value.length >= 24 && value.length <= 200;
}

@@ -33,3 +33,3 @@ /**

/**
* The invariant 17 tools advertised by every Marrow transport. API-key scopes
* The invariant target tools advertised by every Marrow transport. API-key scopes
* gate execution; deployment configuration never changes discovery.

@@ -94,3 +94,2 @@ */

const eventArg = z.string().min(1).optional();
const topKArg = z.number().int().positive().optional();
const headRevisionArg = z.string().min(1).max(128);

@@ -123,36 +122,6 @@ const messageArg = z.object({

}
function optionalQuery(args, keys) {
const query = {};
for (const key of keys) {
const value = args[key];
if (typeof value === "string" && value.length > 0)
query[key] = value;
}
return query;
}
export const TOOLS = [
{
name: "create_peer",
description: "Get-or-create a peer (a user, agent, or group the memory is about).",
annotations: IDEMPOTENT_WRITE,
inputSchema: {
type: "object",
properties: {
peer: { type: "string", description: "The peer id (subject label)." },
workspace: { type: "string", description: "Workspace label (default: 'default')." },
},
required: ["peer"],
},
scope: "memory.write",
route: { method: "POST", path: "/v1/workspaces/{ws}/peers" },
required: ["peer"],
preflight: schemaGuard("create_peer", z.object({ peer: peerArg, workspace: workspaceArg }).strict()),
argsToRequest: (args, env) => ({
pathParams: { ws: wsLabel(args, env) },
body: { id: peerLabel(args) },
}),
},
{
name: "ask_peer",
description: "Ask a peer's memory a question. Returns span-cited evidence or an honest insufficient_evidence — never a synthesized opinion.",
name: "query_context",
description: "Retrieve evidence, assemble context, or produce a cited answer through Marrow's canonical query operation.",
annotations: READ_ONLY,

@@ -162,26 +131,46 @@ inputSchema: {

properties: {
peer: { type: "string" },
mode: { type: "string", enum: ["evidence", "context", "answer"] },
query: { type: "string" },
session: { type: "string", description: "Optional session to narrow to." },
top_k: { type: "integer" },
preset: { type: "string", enum: ["efficient", "accuracy"], default: "accuracy" },
workspace: { type: "string" },
audience: { type: "string" },
source_ids: { type: "array", maxItems: 100, items: { type: "string", format: "uuid" } },
peer_ids: { type: "array", maxItems: 100, items: { type: "string" } },
session_ids: { type: "array", maxItems: 100, items: { type: "string" } },
agent_id: { type: "string" },
},
required: ["peer", "query"],
required: ["mode"],
},
scope: "memory.read",
route: { method: "POST", path: "/v1/workspaces/{ws}/peers/{peer}/ask" },
required: ["peer", "query"],
preflight: schemaGuard("ask_peer", z.object({
peer: peerArg,
query: z.string().min(1),
session: z.string().min(1).optional(),
top_k: topKArg,
scope: "query",
route: { method: "POST", path: "/v1/query" },
required: ["mode"],
requiresQueryOperationId: true,
preflight: schemaGuard("query_context", z.object({
mode: z.enum(["evidence", "context", "answer"]),
query: z.string().min(1).optional(),
preset: z.enum(["efficient", "accuracy"]).optional(),
workspace: workspaceArg,
}).strict()),
audience: z.string().min(1).optional(),
source_ids: z.array(z.string().uuid()).min(1).max(100).optional(),
peer_ids: z.array(z.string().min(1)).min(1).max(100).optional(),
session_ids: z.array(z.string().min(1)).min(1).max(100).optional(),
agent_id: z.string().min(1).optional(),
}).strict().superRefine((input, issueContext) => {
if (!input.query && !(input.mode === "context"
&& (input.source_ids || input.peer_ids || input.session_ids || input.agent_id))) {
issueContext.addIssue({
code: z.ZodIssueCode.custom,
path: ["query"],
message: "Query is required except for Context with an explicit selector.",
});
}
})),
argsToRequest: (args, env) => ({
pathParams: { ws: wsLabel(args, env), peer: peerLabel(args) },
body: {
query: str(args, "query"),
...(typeof args.session === "string" && args.session.length > 0 ? { session_id: args.session } : {}),
...optionalBody(args, ["top_k"]),
idempotencyKey: env.queryOperationId,
mode: args.mode,
...(str(args, "query") ? { query: str(args, "query") } : {}),
preset: args.preset ?? "accuracy",
workspace: args.workspace ?? env.defaultWorkspace ?? "default",
...optionalBody(args, ["audience", "source_ids", "peer_ids", "session_ids", "agent_id"]),
},

@@ -191,22 +180,20 @@ }),

{
name: "get_peer_context",
description: "Fetch a peer's token-bounded, fail-closed assembled context for prompt injection.",
annotations: READ_ONLY,
name: "create_peer",
description: "Get-or-create a peer (a user, agent, or group the memory is about).",
annotations: IDEMPOTENT_WRITE,
inputSchema: {
type: "object",
properties: {
peer: { type: "string" },
session: { type: "string" },
q: { type: "string", description: "Optional focusing query." },
workspace: { type: "string" },
peer: { type: "string", description: "The peer id (subject label)." },
workspace: { type: "string", description: "Workspace label (default: 'default')." },
},
required: ["peer"],
},
scope: "memory.read",
route: { method: "GET", path: "/v1/workspaces/{ws}/peers/{peer}/context" },
scope: "memory.write",
route: { method: "POST", path: "/v1/workspaces/{ws}/peers" },
required: ["peer"],
preflight: schemaGuard("get_peer_context", z.object({ peer: peerArg, session: z.string().min(1).optional(), q: z.string().min(1).optional(), workspace: workspaceArg }).strict()),
preflight: schemaGuard("create_peer", z.object({ peer: peerArg, workspace: workspaceArg }).strict()),
argsToRequest: (args, env) => ({
pathParams: { ws: wsLabel(args, env), peer: peerLabel(args) },
query: optionalQuery(args, ["session", "q"]),
pathParams: { ws: wsLabel(args, env) },
body: { id: peerLabel(args) },
}),

@@ -304,63 +291,2 @@ },

{
name: "get_session_context",
description: "Fetch a peer's fail-closed assembled context narrowed to a session.",
annotations: READ_ONLY,
inputSchema: {
type: "object",
properties: {
session: { type: "string" },
peer: { type: "string" },
q: { type: "string" },
workspace: { type: "string" },
},
required: ["session", "peer"],
},
scope: "memory.read",
route: { method: "GET", path: "/v1/workspaces/{ws}/sessions/{s}/context" },
required: ["session", "peer"],
preflight: schemaGuard("get_session_context", z.object({ session: z.string().min(1), peer: peerArg, q: z.string().min(1).optional(), workspace: workspaceArg }).strict()),
argsToRequest: (args, env) => ({
pathParams: { ws: wsLabel(args, env), s: str(args, "session") },
query: { peer: peerLabel(args), ...optionalQuery(args, ["q"]) },
}),
},
{
name: "query_claims",
description: "Ranked search over a peer's claims. Returns authority, valid_at, and lifecycle state; use ask/context for span citations.",
annotations: READ_ONLY,
inputSchema: {
type: "object",
properties: {
peer: { type: "string" },
query: { type: "string" },
agent: { type: "string" },
session: { type: "string" },
top_k: { type: "integer" },
workspace: { type: "string" },
},
required: ["peer", "query"],
},
scope: "memory.read",
route: { method: "POST", path: "/v1/workspaces/{ws}/claims/query" },
required: ["peer", "query"],
preflight: schemaGuard("query_claims", z.object({
peer: peerArg,
query: z.string().min(1),
agent: z.string().min(1).optional(),
session: z.string().min(1).optional(),
top_k: topKArg,
workspace: workspaceArg,
}).strict()),
argsToRequest: (args, env) => ({
pathParams: { ws: wsLabel(args, env) },
body: {
peer_id: peerLabel(args),
query: str(args, "query"),
...(args.agent !== undefined ? { agent_id: args.agent } : {}),
...(args.session !== undefined ? { session_id: args.session } : {}),
...optionalBody(args, ["top_k"]),
},
}),
},
{
name: "list_claims",

@@ -367,0 +293,0 @@ description: "List a peer's current claims (paginated).",

{
"name": "@marrowid/cli",
"mcpName": "id.marrow/marrow",
"version": "1.0.10",
"gitHead": "40f5fdc9371ce2bb098c5eb9faa1cbd5135acc72",
"version": "1.0.11",
"gitHead": "5e878e91c8291c3e4884fb18ee76b62b7ff1a175",
"description": "Marrow CLI and local MCP for carrying context across apps and agents.",

@@ -7,0 +7,0 @@ "private": false,

@@ -19,3 +19,3 @@ /**

description: "One context. Every AI.",
version: "1.0.10",
version: "1.0.11",
showHelpAfterError: "(run `marrow --help` for the CLI workflow)",

@@ -177,6 +177,9 @@ options: [

path: ["query"],
description: "Retrieve context",
description: "Retrieve evidence, assemble context, or answer from one query",
arguments: ["question"],
options: [
MEMORY_WORKSPACE_OPTION,
{ flag: "--mode <mode>", description: "evidence, context, or answer", required: true },
{ flag: "--preset <preset>", description: "efficient or accuracy", default: "accuracy" },
{ flag: "--idempotency-key <key>", description: "reuse this operation key only to retry the same query" },
{ flag: "--audience <audience>", description: "audience label" },

@@ -186,4 +189,3 @@ { flag: "--source-id <source-id>", description: "narrow to an ingested source (source id or ingest job id); repeat up to 100", collect: true },

{ flag: "--session <session>", description: "narrow to a session; repeat up to 100", collect: true },
{ flag: "--limit <n>", description: "maximum matched results", default: "5" },
{ flag: "--evidence-limit <n>", description: "maximum supporting excerpts per matched result", default: "3" },
{ flag: "--agent <agent>", description: "narrow to an agent" },
JSON_OPTION,

@@ -205,3 +207,5 @@ ],

MEMORY_SESSION_OPTION,
{ flag: "--top-k <n>", description: "maximum evidence blocks" },
{ flag: "--preset <preset>", description: "efficient or accuracy", default: "accuracy" },
{ flag: "--idempotency-key <key>", description: "reuse this operation key only to retry the same query" },
{ flag: "--agent <agent>", description: "narrow to an agent" },
JSON_OPTION,

@@ -219,2 +223,5 @@ ],

{ flag: "--q <q>", description: "focusing query" },
{ flag: "--preset <preset>", description: "efficient or accuracy", default: "accuracy" },
{ flag: "--idempotency-key <key>", description: "reuse this operation key only to retry the same query" },
{ flag: "--agent <agent>", description: "narrow to an agent" },
JSON_OPTION,

@@ -255,2 +262,5 @@ ],

{ flag: "--q <q>", description: "focusing query" },
{ flag: "--preset <preset>", description: "efficient or accuracy", default: "accuracy" },
{ flag: "--idempotency-key <key>", description: "reuse this operation key only to retry the same query" },
{ flag: "--agent <agent>", description: "narrow to an agent" },
JSON_OPTION,

@@ -267,3 +277,5 @@ ],

MEMORY_PEER_REQUIRED_OPTION,
{ flag: "--top-k <n>", description: "maximum hits" },
{ flag: "--preset <preset>", description: "efficient or accuracy", default: "accuracy" },
{ flag: "--idempotency-key <key>", description: "reuse this operation key only to retry the same query" },
{ flag: "--agent <agent>", description: "narrow to an agent" },
JSON_OPTION,

@@ -302,3 +314,3 @@ ],

Both transports expose the same 17 tools against the same Marrow account.`,
Both transports expose the same 14 tools against the same Marrow account.`,
},

@@ -305,0 +317,0 @@ ];

+15
-12

@@ -6,3 +6,3 @@ # Marrow CLI

`https://mcp.marrow.id`; use `marrow mcp` when a client requires a local stdio
server. Version `1.0.10` uses separate credentials for account and product work:
server. Version `1.0.11` uses separate credentials for account and product work:

@@ -21,7 +21,7 @@ - a CLI session authorizes human account and API-key management;

Install CLI version 1.0.10 with Node.js 20 or newer:
Install CLI version 1.0.11 with Node.js 20 or newer:
```bash
npm install -g @marrowid/cli@1.0.10
npm exec --package @marrowid/cli@1.0.10 -- marrow --version
npm install -g @marrowid/cli@1.0.11
npm exec --package @marrowid/cli@1.0.11 -- marrow --version
marrow --version

@@ -32,3 +32,3 @@ marrow --help

If an older global binary is already on `PATH`, the `npm exec` check verifies
1.0.10 independently before you replace the global install.
1.0.11 independently before you replace the global install.

@@ -69,3 +69,3 @@ ## First setup

Device sign-in is available on macOS in version 1.0.10:
Device sign-in is available on macOS in version 1.0.11:

@@ -123,3 +123,5 @@ ```bash

```bash
marrow query "What should this workflow remember about onboarding?" --limit 5 --evidence-limit 3
marrow query "What should this workflow remember about onboarding?" \
--mode answer \
--preset accuracy
```

@@ -165,3 +167,3 @@

Use `marrow mcp` when the MCP client requires a local stdio server. It connects
to the same Marrow account and exposes the same 17 tools as Hosted MCP.
to the same Marrow account and exposes the same 14 tools as Hosted MCP.

@@ -176,6 +178,7 @@ `marrow mcp` is the shipped local newline-delimited JSON-RPC entrypoint over

The server exposes 17 tools for peer, session, claim, event, queue, context,
and representation workflows. Read tools require `memory.read`; write tools
require `memory.write`. Wrong-scope and revoked-key errors are returned to the
client. See the [MCP tool table](./app-context.md#mcp-tools) and the short
The server exposes 14 tools for query, peer, session, claim, event, queue, and
representation workflows. The canonical query tool requires `query`;
native-memory reads require `memory.read`; writes require `memory.write`.
Wrong-scope and revoked-key errors are returned to the client. See the
[MCP tool table](./app-context.md#mcp-tools) and the short
[coding-agent prompt](./app-context.md#prompt-for-a-coding-agent).

@@ -182,0 +185,0 @@

Sorry, the diff of this file is too big to display