ralph-hero-mcp-server 2.5.113 → 2.5.116

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.
@@ -69,7 +69,20 @@ export function readActivity(config) {
69
69
  events.sort((a, b) => a.ts.localeCompare(b.ts));
70
70
  const limited = events.slice(0, config.limit);
71
71
  const cursor = limited.length > 0 ? limited[limited.length - 1].ts : null;
72
- return { events: limited, cursor_advanced_to: cursor, skipped_lines: skipped };
72
+ const out = config.compact
73
+ ? limited.map((e) => {
74
+ const projected = { ts: e.ts, kind: e.kind };
75
+ const toolName = e.target && typeof e.target === "object" && "tool" in e.target
76
+ ? e.target.tool
77
+ : undefined;
78
+ if (typeof toolName === "string")
79
+ projected.tool = toolName;
80
+ if (e.project)
81
+ projected.project = e.project;
82
+ return projected;
83
+ })
84
+ : limited;
85
+ return { events: out, cursor_advanced_to: cursor, skipped_lines: skipped };
73
86
  }
74
87
  function safeReadDir(dir) {
75
88
  try {
@@ -68,6 +68,13 @@ const PR_REVIEW_REQUIRED_BOOST = -200;
68
68
  * waiting for the human's attention.
69
69
  */
70
70
  const HUMAN_NEEDED_UNBLOCK_BOOST = -150;
71
+ /**
72
+ * Penalty applied to Backlog / null-state items that surface only via the
73
+ * `audience === "agent"` fallback. Large positive value ensures Backlog
74
+ * fallback items always rank below any actionable-phase item — Backlog
75
+ * surfaces only when the actionable pool is empty.
76
+ */
77
+ const AGENT_BACKLOG_FALLBACK_PENALTY = 100;
71
78
  /**
72
79
  * Per-estimate penalty applied when audience === "agent". Larger items
73
80
  * cost more (positive score), pushing them down the ranking so agent
@@ -528,6 +535,28 @@ export function rankDirections(items, openPRs, config) {
528
535
  const { score, kind, tags, signals } = scoreIssue(item, items, config);
529
536
  scored.push({ item, score, kind, tags, signals });
530
537
  }
538
+ // 1b. Phase fallback for autonomous audience: when no items passed the
539
+ // standard phase filter, widen the candidate set to include items in
540
+ // `Backlog` and items with a null `workflowState`. This restores
541
+ // autopilot's ability to clear a Backlog-heavy board. Fallback items
542
+ // get +AGENT_BACKLOG_FALLBACK_PENALTY so they always rank below any
543
+ // actionable-phase item — they surface only when the actionable pool
544
+ // is empty. Mirrors the blocker fallback in step 2.
545
+ if (config.audience === "agent" && scored.length === 0) {
546
+ for (const item of items) {
547
+ if (item.workflowState !== "Backlog" && item.workflowState !== null) {
548
+ continue;
549
+ }
550
+ const { score, kind, tags, signals } = scoreIssue(item, items, config);
551
+ scored.push({
552
+ item,
553
+ score: score + AGENT_BACKLOG_FALLBACK_PENALTY,
554
+ kind,
555
+ tags,
556
+ signals,
557
+ });
558
+ }
559
+ }
531
560
  // 2. Drop blocked items unless that would empty the candidate set.
532
561
  const unblocked = scored.filter((s) => !hasOpenBlockers(s.item));
533
562
  let candidates;
@@ -13,7 +13,8 @@ export function registerActivityTools(server) {
13
13
  kinds: z.array(z.string()).nullable().default(null).describe("Filter by event kind (e.g., ['pr_opened','issue_advanced'])"),
14
14
  category: z.enum(["work", "meta", "all"]).default("work").describe("Filter by category; default 'work' excludes meta noise"),
15
15
  project: z.string().nullable().default(null).describe("Filter by project name"),
16
- limit: z.number().int().min(1).default(100).describe("Max events to return"),
16
+ limit: z.number().int().min(1).default(50).describe("Max events to return (default 50; was 100 before 2.5.x)"),
17
+ compact: z.boolean().default(false).describe("When true, project each event to {ts, kind, tool, project}; drops actor/session_id/category/wrapper-target. Use for narrative synthesis."),
17
18
  }, async (params) => {
18
19
  try {
19
20
  const result = readActivity({
@@ -23,7 +24,8 @@ export function registerActivityTools(server) {
23
24
  kinds: params.kinds ?? null,
24
25
  category: (params.category ?? "work"),
25
26
  project: params.project ?? null,
26
- limit: params.limit ?? 100,
27
+ limit: params.limit ?? 50,
28
+ compact: params.compact ?? false,
27
29
  now: new Date(),
28
30
  });
29
31
  return toolSuccess(result);
@@ -294,7 +294,7 @@ export function registerDirectionsTools(server, client, fieldCache) {
294
294
  }, async (args) => {
295
295
  return await runDirections({ ...args, audience: "human" });
296
296
  });
297
- server.tool("ralph_hero__next_actions", "Compute up to N deterministic 'directions' (next actions) with one flagged `recommended: true`. Used by the /hello skill picker (interactive) and by headless orchestrators (auto-select recommended). Open PRs must be passed in as a parameter. Each direction includes a structured signals object (staleDays, staleThresholdDays, tiedAtScore, estimateWeight, parentChainNote) for skills to synthesize prose. The legacy 'reason' string is @deprecated and removed in 2.7.0.", {
297
+ server.tool("ralph_hero__next_actions", "Compute up to N deterministic 'directions' (next actions) with one flagged `recommended: true`. Used by the /hello skill picker (interactive) and by headless orchestrators (auto-select recommended). Open PRs must be passed in as a parameter. Each direction includes a structured signals object (staleDays, staleThresholdDays, tiedAtScore, estimateWeight, parentChainNote) for skills to synthesize prose. The legacy 'reason' string is @deprecated and removed in 2.7.0. When `audience='agent'` and no items are in actionable phases (Plan in Review, In Review, Ready for Plan, Research Needed) or otherwise surfacing (lock-stale, unblock-requested), the picker falls back to Backlog and null-state items so autopilot can drive triage. Fallback items receive a fixed score penalty so they never outrank actionable items when those exist; the fallback never fires for `audience='human'`.", {
298
298
  owner: z
299
299
  .string()
300
300
  .optional()
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "ralph-hero-mcp-server",
3
- "version": "2.5.113",
3
+ "version": "2.5.116",
4
4
  "description": "MCP server for GitHub Projects V2 - Ralph workflow automation",
5
5
  "type": "module",
6
6
  "main": "dist/index.js",