@rk0429/agentic-relay 2.0.0 → 2.0.2

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.
Files changed (2) hide show
  1. package/dist/relay.mjs +147 -37
  2. package/package.json +1 -1
package/dist/relay.mjs CHANGED
@@ -2208,13 +2208,21 @@ var init_access_control = __esm({
2208
2208
  case "escalate_task":
2209
2209
  case "release_task":
2210
2210
  case "decompose_task": {
2211
- if (task.assignee !== agent_id) {
2212
- throw new TasksError("access_denied", "only assignee can perform this action", {
2213
- action,
2214
- task_id,
2215
- agent_id,
2216
- assignee: task.assignee
2217
- });
2211
+ if (task.assignee !== agent_id && !this.isCreatorOrAbove(task, agent_id)) {
2212
+ const parent = task.parent_task_id ? this.get_task(task.parent_task_id) : null;
2213
+ throw new TasksError(
2214
+ "access_denied",
2215
+ "only assignee, creator, or parent assignee can perform this action",
2216
+ {
2217
+ action,
2218
+ task_id,
2219
+ agent_id,
2220
+ assignee: task.assignee,
2221
+ created_by: task.created_by,
2222
+ parent_task_id: task.parent_task_id,
2223
+ parent_assignee: parent?.assignee ?? null
2224
+ }
2225
+ );
2218
2226
  }
2219
2227
  return;
2220
2228
  }
@@ -2268,13 +2276,32 @@ var init_access_control = __esm({
2268
2276
  return;
2269
2277
  }
2270
2278
  case "archive_task": {
2271
- if (task.created_by !== agent_id) {
2272
- throw new TasksError("access_denied", "only creator can archive task", {
2273
- action,
2274
- task_id,
2275
- agent_id,
2276
- created_by: task.created_by
2277
- });
2279
+ if (task.assignee === agent_id && !this.isCreatorOrAbove(task, agent_id)) {
2280
+ throw new TasksError(
2281
+ "access_denied",
2282
+ "assignee cannot archive own task",
2283
+ {
2284
+ action,
2285
+ task_id,
2286
+ agent_id,
2287
+ assignee: task.assignee
2288
+ }
2289
+ );
2290
+ }
2291
+ if (!this.isCreatorOrAbove(task, agent_id)) {
2292
+ const parent = task.parent_task_id ? this.get_task(task.parent_task_id) : null;
2293
+ throw new TasksError(
2294
+ "access_denied",
2295
+ "only creator or parent assignee can archive task",
2296
+ {
2297
+ action,
2298
+ task_id,
2299
+ agent_id,
2300
+ created_by: task.created_by,
2301
+ parent_task_id: task.parent_task_id,
2302
+ parent_assignee: parent?.assignee ?? null
2303
+ }
2304
+ );
2278
2305
  }
2279
2306
  return;
2280
2307
  }
@@ -2353,6 +2380,18 @@ var init_access_control = __esm({
2353
2380
  const task = this.get_task(task_id);
2354
2381
  return task.assignee === agent_id;
2355
2382
  }
2383
+ isCreatorOrAbove(task, agent_id) {
2384
+ if (task.created_by === agent_id) {
2385
+ return true;
2386
+ }
2387
+ if (task.parent_task_id) {
2388
+ const parent = this.get_task(task.parent_task_id);
2389
+ if (parent.assignee === agent_id) {
2390
+ return true;
2391
+ }
2392
+ }
2393
+ return false;
2394
+ }
2356
2395
  get_task(task_id) {
2357
2396
  const row = this.db.prepare(
2358
2397
  `
@@ -2917,7 +2956,7 @@ function nowIso5() {
2917
2956
  return (/* @__PURE__ */ new Date()).toISOString();
2918
2957
  }
2919
2958
  function parseJsonObject(value) {
2920
- if (!value) {
2959
+ if (!value || value === "null") {
2921
2960
  return null;
2922
2961
  }
2923
2962
  return JSON.parse(value);
@@ -2959,7 +2998,7 @@ var init_project_manager = __esm({
2959
2998
  id,
2960
2999
  input.name,
2961
3000
  input.description ?? "",
2962
- JSON.stringify(input.metadata ?? null),
3001
+ input.metadata ? JSON.stringify(input.metadata) : null,
2963
3002
  wip_limit,
2964
3003
  1,
2965
3004
  now,
@@ -4046,7 +4085,7 @@ function normalizeAcceptanceCriteria(criteria) {
4046
4085
  return criteria ?? [];
4047
4086
  }
4048
4087
  function parseJsonObject2(value) {
4049
- if (!value) {
4088
+ if (!value || value === "null") {
4050
4089
  return null;
4051
4090
  }
4052
4091
  return JSON.parse(value);
@@ -4147,7 +4186,7 @@ var init_task_manager = __esm({
4147
4186
  input.sprint_id ?? null,
4148
4187
  input.assignee ?? null,
4149
4188
  JSON.stringify(acceptanceCriteria),
4150
- JSON.stringify(input.metadata ?? null),
4189
+ input.metadata ? JSON.stringify(input.metadata) : null,
4151
4190
  1,
4152
4191
  input.created_by ?? null,
4153
4192
  now,
@@ -4570,7 +4609,7 @@ function nowIso10() {
4570
4609
  return (/* @__PURE__ */ new Date()).toISOString();
4571
4610
  }
4572
4611
  function parseJson(value, fallback) {
4573
- if (!value) {
4612
+ if (!value || value === "null") {
4574
4613
  return fallback;
4575
4614
  }
4576
4615
  return JSON.parse(value);
@@ -5917,8 +5956,8 @@ var init_tasks_runtime = __esm({
5917
5956
  input.project_id,
5918
5957
  input.trigger_type,
5919
5958
  JSON.stringify(input.assessment),
5920
- JSON.stringify(input.decisions ?? null),
5921
- JSON.stringify(input.actions_taken ?? null),
5959
+ input.decisions ? JSON.stringify(input.decisions) : null,
5960
+ input.actions_taken ? JSON.stringify(input.actions_taken) : null,
5922
5961
  created_at
5923
5962
  );
5924
5963
  return {
@@ -6849,12 +6888,20 @@ function applyMigrations(db) {
6849
6888
  const insertApplied = db.prepare(
6850
6889
  "INSERT INTO schema_migrations(version, checksum, applied_at) VALUES (?, ?, ?)"
6851
6890
  );
6891
+ const updateChecksum = db.prepare(
6892
+ "UPDATE schema_migrations SET checksum = ? WHERE version = ?"
6893
+ );
6852
6894
  for (const migration of MIGRATIONS) {
6853
6895
  const checksum = checksumOf(migration.sql);
6854
6896
  const existing = getApplied.get(migration.version);
6855
6897
  if (existing) {
6856
6898
  if (existing.checksum !== checksum) {
6857
- throw new Error(`migration checksum mismatch: ${migration.version}`);
6899
+ const compatibles = COMPATIBLE_CHECKSUMS[migration.version];
6900
+ if (compatibles?.includes(existing.checksum)) {
6901
+ updateChecksum.run(checksum, migration.version);
6902
+ } else {
6903
+ throw new Error(`migration checksum mismatch: ${migration.version}`);
6904
+ }
6858
6905
  }
6859
6906
  continue;
6860
6907
  }
@@ -6912,7 +6959,7 @@ function openDatabase(options) {
6912
6959
  }
6913
6960
  return db;
6914
6961
  }
6915
- var MIGRATIONS;
6962
+ var MIGRATIONS, COMPATIBLE_CHECKSUMS;
6916
6963
  var init_db = __esm({
6917
6964
  "src/tasks/db.ts"() {
6918
6965
  "use strict";
@@ -7082,6 +7129,12 @@ CREATE INDEX IF NOT EXISTS idx_task_events_task_created_at ON task_events(task_i
7082
7129
  `
7083
7130
  }
7084
7131
  ];
7132
+ COMPATIBLE_CHECKSUMS = {
7133
+ "0001_initial": [
7134
+ "237ece3cd571e5b0a089d883b65fa631e316d62ec6fbb9246880c36fd444fe50"
7135
+ // agentic-tasks v0.x
7136
+ ]
7137
+ };
7085
7138
  }
7086
7139
  });
7087
7140
 
@@ -7225,7 +7278,7 @@ function registerTaskTools(server, runtime) {
7225
7278
  ]).nullable().optional(),
7226
7279
  source_ref: z7.string().nullable().optional(),
7227
7280
  expected_effort: z7.enum(["XS", "S", "M", "L", "XL"]).nullable().optional(),
7228
- agent_id: z7.string()
7281
+ agent_id: z7.string().default("orchestrator")
7229
7282
  },
7230
7283
  (input) => ({
7231
7284
  task: runtime.create_task(
@@ -7425,11 +7478,21 @@ function registerTaskTools(server, runtime) {
7425
7478
  registerTool(
7426
7479
  server,
7427
7480
  "dashboard",
7428
- "Get project dashboard including goal progress rollups.",
7481
+ "Get project dashboard including goal progress rollups. Defaults to the first project if project_id is omitted.",
7429
7482
  {
7430
- project_id: z7.string()
7483
+ project_id: z7.string().optional()
7431
7484
  },
7432
- (input) => runtime.dashboard({ project_id: String(input.project_id) })
7485
+ (input) => {
7486
+ let projectId = input.project_id;
7487
+ if (!projectId) {
7488
+ const { projects } = runtime.list_projects();
7489
+ if (projects.length === 0) {
7490
+ return { success: false, error: "no projects found" };
7491
+ }
7492
+ projectId = projects[0].id;
7493
+ }
7494
+ return runtime.dashboard({ project_id: projectId });
7495
+ }
7433
7496
  );
7434
7497
  registerTool(
7435
7498
  server,
@@ -7852,7 +7915,7 @@ function registerTaskTools(server, runtime) {
7852
7915
  ).optional(),
7853
7916
  source_ref: z7.string().optional(),
7854
7917
  priority: z7.enum(["critical", "high", "medium", "low"]).default("medium"),
7855
- agent_id: z7.string()
7918
+ agent_id: z7.string().default("orchestrator")
7856
7919
  },
7857
7920
  (input) => runtime.create_goal(input)
7858
7921
  );
@@ -7892,11 +7955,48 @@ function registerTaskTools(server, runtime) {
7892
7955
  registerTool(
7893
7956
  server,
7894
7957
  "get_execution_view",
7895
- "Get execution view (ready/in_progress/blocked/done and dependency edges).",
7958
+ "Get execution view (ready/in_progress/blocked/done and dependency edges) for a goal or all goals in a project.",
7896
7959
  {
7897
- goal_id: z7.string()
7960
+ goal_id: z7.string().optional(),
7961
+ project_id: z7.string().optional()
7898
7962
  },
7899
- (input) => runtime.get_execution_view(input)
7963
+ (input) => {
7964
+ const goalId = input.goal_id;
7965
+ const projectId = input.project_id;
7966
+ if (!goalId && !projectId) {
7967
+ return { success: false, error: "goal_id or project_id is required" };
7968
+ }
7969
+ if (goalId) {
7970
+ return runtime.get_execution_view({ goal_id: goalId });
7971
+ }
7972
+ const dashboardResult = runtime.dashboard({ project_id: projectId });
7973
+ const goalIds = dashboardResult.goals.map((g) => g.goal_id);
7974
+ if (goalIds.length === 0) {
7975
+ return {
7976
+ ready: [],
7977
+ in_progress: [],
7978
+ blocked: [],
7979
+ done: [],
7980
+ dependency_edges: []
7981
+ };
7982
+ }
7983
+ const merged = {
7984
+ ready: [],
7985
+ in_progress: [],
7986
+ blocked: [],
7987
+ done: [],
7988
+ dependency_edges: []
7989
+ };
7990
+ for (const gid of goalIds) {
7991
+ const view = runtime.get_execution_view({ goal_id: gid });
7992
+ merged.ready.push(...view.ready);
7993
+ merged.in_progress.push(...view.in_progress);
7994
+ merged.blocked.push(...view.blocked);
7995
+ merged.done.push(...view.done);
7996
+ merged.dependency_edges.push(...view.dependency_edges);
7997
+ }
7998
+ return merged;
7999
+ }
7900
8000
  );
7901
8001
  }
7902
8002
  var acceptanceCriteriaSchema;
@@ -8228,6 +8328,16 @@ var init_server = __esm({
8228
8328
  const runtime = this.tasksRuntime;
8229
8329
  this.taskLifecycleManager = {
8230
8330
  createAndStartTask(params) {
8331
+ let createdBy = "orchestrator";
8332
+ if (params.parent_task_id) {
8333
+ try {
8334
+ const parentResult = runtime.get_task(params.parent_task_id, false);
8335
+ if (parentResult.task.assignee) {
8336
+ createdBy = parentResult.task.assignee;
8337
+ }
8338
+ } catch {
8339
+ }
8340
+ }
8231
8341
  const task = runtime.create_task({
8232
8342
  title: params.title,
8233
8343
  project_id: params.project_id,
@@ -8236,7 +8346,7 @@ var init_server = __esm({
8236
8346
  priority: params.priority,
8237
8347
  expected_effort: params.expected_effort,
8238
8348
  description: params.description
8239
- }, params.agent);
8349
+ }, createdBy);
8240
8350
  runtime.claim_and_start({
8241
8351
  task_id: task.id,
8242
8352
  agent_id: params.agent
@@ -8293,7 +8403,7 @@ var init_server = __esm({
8293
8403
  this.agentEventStore
8294
8404
  );
8295
8405
  this.server = new McpServer(
8296
- { name: "agentic-relay", version: "2.0.0" },
8406
+ { name: "agentic-relay", version: "2.0.2" },
8297
8407
  createMcpServerOptions()
8298
8408
  );
8299
8409
  this.registerTools(this.server);
@@ -8779,7 +8889,7 @@ var init_server = __esm({
8779
8889
  sessionIdGenerator: () => randomUUID()
8780
8890
  });
8781
8891
  const server = new McpServer(
8782
- { name: "agentic-relay", version: "2.0.0" },
8892
+ { name: "agentic-relay", version: "2.0.2" },
8783
8893
  createMcpServerOptions()
8784
8894
  );
8785
8895
  this.registerTools(server);
@@ -13219,7 +13329,7 @@ function createMCPCommand(configManager2, registry2, sessionManager2, hooksEngin
13219
13329
  responseOutputDir,
13220
13330
  relayConfig
13221
13331
  );
13222
- await server.start({ transport, port, currentVersion: "2.0.0" });
13332
+ await server.start({ transport, port, currentVersion: "2.0.2" });
13223
13333
  }
13224
13334
  })
13225
13335
  },
@@ -13379,7 +13489,7 @@ function createVersionCommand(registry2) {
13379
13489
  description: "Show relay and backend versions"
13380
13490
  },
13381
13491
  async run() {
13382
- const relayVersion = "2.0.0";
13492
+ const relayVersion = "2.0.2";
13383
13493
  console.log(`agentic-relay v${relayVersion}`);
13384
13494
  console.log("");
13385
13495
  console.log("Backends:");
@@ -13776,7 +13886,7 @@ var subCommandNames = /* @__PURE__ */ new Set(["claude", "codex", "gemini", "upd
13776
13886
  var main = defineCommand11({
13777
13887
  meta: {
13778
13888
  name: "relay",
13779
- version: "2.0.0",
13889
+ version: "2.0.2",
13780
13890
  description: "Unified CLI proxy for Claude Code, Codex CLI, and Gemini CLI"
13781
13891
  },
13782
13892
  args: {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@rk0429/agentic-relay",
3
- "version": "2.0.0",
3
+ "version": "2.0.2",
4
4
  "description": "Unified CLI proxy for Claude Code, Codex CLI, and Gemini CLI with MCP-based multi-layer sub-agent orchestration",
5
5
  "type": "module",
6
6
  "license": "Apache-2.0",