@kynver-app/mcp-agent-os 0.3.34 → 0.3.36

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/index.js CHANGED
@@ -4,12 +4,17 @@
4
4
  * Run: node dist/index.js
5
5
  * Env: KYNVER_API_URL, KYNVER_API_KEY (required)
6
6
  */
7
+ import { enforceMemoryCostPackageGuardAtStartup } from "@kynver-app/runtime/server/memory-cost-enforce";
7
8
  import { StdioServerTransport } from "@modelcontextprotocol/sdk/server/stdio.js";
8
- import { handleCliVersionFlag } from "./lib/package-version.js";
9
+ import { handleCliVersionFlag, readOwnPackageVersion } from "./lib/package-version.js";
9
10
  import { createAgentOsServer } from "./server.js";
10
11
  if (handleCliVersionFlag(process.argv.slice(2), import.meta.url, "kynver-mcp-agent-os")) {
11
12
  // exits
12
13
  }
14
+ await enforceMemoryCostPackageGuardAtStartup({
15
+ selfPackageName: "@kynver-app/mcp-agent-os",
16
+ selfVersion: readOwnPackageVersion(import.meta.url),
17
+ });
13
18
  const server = createAgentOsServer();
14
19
  const transport = new StdioServerTransport();
15
20
  await server.connect(transport);
package/dist/server.js CHANGED
@@ -305,7 +305,7 @@ export function createAgentOsServer() {
305
305
  });
306
306
  register("agent_os_search_memory", "Semantic + keyword hybrid search over the agent's long-term memory (ownerType=agent). Use to recall specific decisions, project details, or lessons without loading full context. Replaces grep/reading MEMORY.md. Optionally restrict to one source namespace via sourceId, or several via sourceIds (sourceId takes precedence when both are set). Workspace owners and env admins receive operator diagnostics (rrfScore, lanes, hygiene) unless surface=customer; grantees always receive grantee-safe hits (content, trust, evidence links only).", {
307
307
  query: z.string().describe("Natural language query to search memory."),
308
- k: z.number().optional().describe("Number of results (default 10, max 50)."),
308
+ k: z.number().optional().describe("Number of results (default 5, max 50)."),
309
309
  sourceId: z
310
310
  .string()
311
311
  .optional()
package/dist/sse.js CHANGED
@@ -1,6 +1,12 @@
1
+ import { enforceMemoryCostPackageGuardAtStartup } from "@kynver-app/runtime/server/memory-cost-enforce";
1
2
  import { startKynverMcpSseServer } from "./lib/mcp-sse-server.js";
3
+ import { readOwnPackageVersion } from "./lib/package-version.js";
2
4
  import { createAgentOsServer } from "./server.js";
3
5
  import { requestContext } from "./lib/kynver-client.js";
6
+ await enforceMemoryCostPackageGuardAtStartup({
7
+ selfPackageName: "@kynver-app/mcp-agent-os",
8
+ selfVersion: readOwnPackageVersion(import.meta.url),
9
+ });
4
10
  startKynverMcpSseServer({
5
11
  label: "Agentic OS server",
6
12
  defaultPort: 3101,
@@ -0,0 +1 @@
1
+ export {};
@@ -0,0 +1,65 @@
1
+ import { beforeEach, describe, expect, it, vi } from "vitest";
2
+ const postMock = vi.fn().mockResolvedValue({ task: { id: "task-1" }, created: true });
3
+ vi.mock("../../lib/kynver-client.js", () => ({
4
+ get: vi.fn(),
5
+ post: (...args) => postMock(...args),
6
+ patch: vi.fn(),
7
+ }));
8
+ import { registerTaskTools } from "../tasks.js";
9
+ describe("AgentTask MCP plan linkage", () => {
10
+ let createHandler;
11
+ let createSchema;
12
+ let updateSchema;
13
+ beforeEach(() => {
14
+ postMock.mockClear();
15
+ createHandler = undefined;
16
+ createSchema = undefined;
17
+ updateSchema = undefined;
18
+ registerTaskTools({
19
+ register: (name, _description, schema, cb) => {
20
+ if (name === "agent_os_task_create") {
21
+ createSchema = schema;
22
+ createHandler = cb;
23
+ }
24
+ if (name === "agent_os_task_update") {
25
+ updateSchema = schema;
26
+ }
27
+ },
28
+ resolveToolSlug: async (slug) => slug ?? "ghost",
29
+ jsonResult: (data) => ({ content: [], structuredContent: data }),
30
+ compact: (source) => Object.fromEntries(Object.entries(source).filter(([, value]) => value !== undefined)),
31
+ });
32
+ });
33
+ it("exposes planId so harness tasks can satisfy lineage admission", async () => {
34
+ expect(createSchema).toHaveProperty("planId");
35
+ await createHandler({
36
+ title: "Milestone PR 1: Heavy eval harness",
37
+ executor: "harness",
38
+ planId: "plan-123",
39
+ idempotencyKey: "plan-123:m1",
40
+ });
41
+ expect(postMock).toHaveBeenCalledWith("/agent-os/ghost/tasks", {
42
+ title: "Milestone PR 1: Heavy eval harness",
43
+ executor: "harness",
44
+ planId: "plan-123",
45
+ idempotencyKey: "plan-123:m1",
46
+ });
47
+ });
48
+ it("exposes standaloneReason for explicitly unscoped harness tasks", async () => {
49
+ expect(createSchema).toHaveProperty("standaloneReason");
50
+ await createHandler({
51
+ title: "Operator-requested sandbox",
52
+ executor: "harness",
53
+ standaloneReason: "operator-requested sandbox task outside a plan",
54
+ });
55
+ expect(postMock).toHaveBeenCalledWith("/agent-os/ghost/tasks", {
56
+ title: "Operator-requested sandbox",
57
+ executor: "harness",
58
+ standaloneReason: "operator-requested sandbox task outside a plan",
59
+ });
60
+ });
61
+ it("exposes planId on update so existing tasks can be linked after creation", () => {
62
+ expect(updateSchema).toHaveProperty("planId");
63
+ expect(updateSchema).toHaveProperty("planStageId");
64
+ });
65
+ });
@@ -82,9 +82,18 @@ export function registerTaskTools({ register, resolveToolSlug, jsonResult, compa
82
82
  parentTaskId: z.string().optional().describe("Parent task id when this is one of 2+ coordinated workers."),
83
83
  goalId: z.string().optional(),
84
84
  projectId: z.string().optional(),
85
+ planId: z
86
+ .string()
87
+ .optional()
88
+ .describe("AgentPlan id to link this task to; required for plan-scoped harness work."),
89
+ planStageId: z.string().optional().describe("Optional AgentPlan stage id for finer plan lineage."),
85
90
  personaSlug,
86
91
  scheduledFor,
87
92
  dependsOnTaskIds,
93
+ standaloneReason: z
94
+ .string()
95
+ .optional()
96
+ .describe("Required when intentionally creating an unscoped harness task without parentTaskId or planId; explain why it is standalone."),
88
97
  idempotencyKey: z.string().optional().describe("Dedupe key from the foreground turn. Strongly recommended."),
89
98
  requestId: z.string().optional().describe("Raw foreground request id; used as the dedupe key if idempotencyKey is absent."),
90
99
  slug: slugField,
@@ -132,6 +141,8 @@ export function registerTaskTools({ register, resolveToolSlug, jsonResult, compa
132
141
  parentTaskId: z.string().optional(),
133
142
  goalId: z.string().optional(),
134
143
  projectId: z.string().optional(),
144
+ planId: z.string().optional(),
145
+ planStageId: z.string().optional(),
135
146
  personaSlug,
136
147
  scheduledFor,
137
148
  dependsOnTaskIds,
@@ -211,4 +222,30 @@ export function registerTaskTools({ register, resolveToolSlug, jsonResult, compa
211
222
  const s = await resolveToolSlug(slug);
212
223
  return jsonResult(await post(`/agent-os/${s}/tasks/${taskId}/renew-lease`, compact(body)));
213
224
  });
225
+ const operatorPriorityLevel = z
226
+ .enum(["high", "critical"])
227
+ .optional()
228
+ .describe("Override dispatch level when expediting (default high). Separate from stored task priority — " +
229
+ "uses audited operatorPriority* fields, not priority inflation.");
230
+ register("agent_os_task_operator_priority", "Expedite a ready task to the front of the operator dispatch queue, or clear the override. " +
231
+ "Requires tasks:write. Set action=set with reason (12+ chars); action=clear to demote. " +
232
+ "Does not bypass blockers, dependencies, scheduledFor, Will/security gates, or lane filters — " +
233
+ "only reorders eligible dispatch candidates.", {
234
+ taskId: z.string(),
235
+ action: z
236
+ .enum(["set", "clear"])
237
+ .optional()
238
+ .describe("set = front-of-queue override (default). clear = remove override."),
239
+ reason: z
240
+ .string()
241
+ .optional()
242
+ .describe("Required for set — operator-authored reason (min 12 chars)."),
243
+ level: operatorPriorityLevel,
244
+ clearNote: z.string().optional().describe("Optional note when clearing the override."),
245
+ slug: slugField,
246
+ }, async (args) => {
247
+ const { slug, taskId, ...body } = args;
248
+ const s = await resolveToolSlug(slug);
249
+ return jsonResult(await post(`/agent-os/${s}/tasks/${taskId}/operator-priority`, compact(body)));
250
+ });
214
251
  }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@kynver-app/mcp-agent-os",
3
- "version": "0.3.34",
3
+ "version": "0.3.36",
4
4
  "description": "Kynver Agentic OS MCP server — slug-keyed agent identity, goals, projects, sessions, and long-term memory",
5
5
  "type": "module",
6
6
  "bin": {
@@ -22,6 +22,7 @@
22
22
  "node": ">=18"
23
23
  },
24
24
  "dependencies": {
25
+ "@kynver-app/runtime": "^0.1.0",
25
26
  "@modelcontextprotocol/sdk": "^1.27.0",
26
27
  "zod": "^3.23.0"
27
28
  },