rrce-workflow 0.3.11 → 0.3.13

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.
@@ -9,7 +9,7 @@ Use values from the **System Context** table above. Never guess or construct pat
9
9
  - `RRCE_HOME` - Global RRCE installation directory
10
10
 
11
11
  ## Tool Preference Order
12
- 1. **Semantic search** (`rrce_search_knowledge`, `rrce_search_code`) - finds concepts without exact matches
12
+ 1. **Semantic search** (`search_knowledge`, `search_code`) - finds concepts without exact matches
13
13
  2. **Direct read** (`read`) - for specific known files
14
14
  3. **Pattern search** (`glob`, `grep`) - last resort for exact strings or when RAG unavailable
15
15
 
@@ -25,6 +25,13 @@ If a `PRE-FETCHED CONTEXT` block exists in your prompt:
25
25
  ## Metadata Updates
26
26
  For `meta.json` changes, use `rrce_update_task()` - it auto-saves. Never use `write` for meta.json.
27
27
 
28
+ ## Checklist Sync (OpenCode)
29
+ When working on a task with a checklist:
30
+ 1. Always read the current checklist from `meta.json`.
31
+ 2. Sync the checklist to OpenCode's Todo sidebar using `todowrite`.
32
+ 3. Format the checklist for `todowrite` as a structured list of sub-tasks relevant to your current phase.
33
+ 4. Update the sidebar whenever a sub-task status changes.
34
+
28
35
  ## Completion Signal
29
36
  When your phase completes, emit:
30
37
  ```
@@ -34,7 +34,7 @@ You are the Project Doctor for RRCE-Workflow. Perform a health check on the code
34
34
  ### Step 1: Load Project Context
35
35
 
36
36
  ```
37
- Tool: rrce_get_project_context
37
+ Tool: get_project_context
38
38
  Args: { "project": "{{WORKSPACE_NAME}}" }
39
39
  ```
40
40
 
@@ -72,7 +72,7 @@ Use `search_knowledge` to efficiently find problem areas. Run queries based on F
72
72
 
73
73
  **Query Execution:**
74
74
  ```
75
- Tool: rrce_search_knowledge
75
+ Tool: search_knowledge
76
76
  Args: { "query": "<query>", "project": "{{WORKSPACE_NAME}}" }
77
77
  ```
78
78
 
@@ -2,7 +2,7 @@
2
2
  name: RRCE Documentation
3
3
  description: Produce project documentation aligned with the latest delivery.
4
4
  argument-hint: "DOC_TYPE=<type> [TASK_SLUG=<slug> | TARGET_PATH=<relative>] [RELEASE_REF=<tag/sha>]"
5
- tools: ['search_knowledge', 'get_project_context', 'list_projects', 'update_task', 'read', 'write', 'edit', 'bash', 'glob', 'grep', 'todoread', 'todowrite']
5
+ tools: ['search_knowledge', 'get_project_context', 'list_projects', 'update_task']
6
6
  required-args:
7
7
  - name: DOC_TYPE
8
8
  prompt: "Enter the documentation type (e.g., api, architecture, runbook, changelog)"
@@ -2,7 +2,7 @@
2
2
  name: RRCE Executor
3
3
  description: Execute the planned tasks to deliver working code and tests. The ONLY agent authorized to modify source code.
4
4
  argument-hint: "TASK_SLUG=<slug> [BRANCH=<git ref>]"
5
- tools: ['search_knowledge', 'search_code', 'find_related_files', 'get_project_context', 'index_knowledge', 'update_task', 'read', 'write', 'edit', 'bash', 'glob', 'grep', 'todoread', 'todowrite']
5
+ tools: ['search_knowledge', 'search_code', 'find_related_files', 'get_project_context', 'index_knowledge', 'update_task', 'read', 'write', 'edit', 'bash', 'glob', 'grep']
6
6
  required-args:
7
7
  - name: TASK_SLUG
8
8
  prompt: "Enter the task slug to execute"
@@ -2,7 +2,7 @@
2
2
  name: RRCE Init
3
3
  description: Initialize project context and semantic search index by analyzing codebase structure, tech stack, and conventions.
4
4
  argument-hint: "[PROJECT_NAME=<name>]"
5
- tools: ['search_knowledge', 'index_knowledge', 'get_project_context', 'list_projects', 'read', 'write', 'bash', 'glob', 'grep']
5
+ tools: ['search_knowledge', 'index_knowledge', 'get_project_context', 'list_projects']
6
6
  required-args: []
7
7
  optional-args:
8
8
  - name: PROJECT_NAME
@@ -2,7 +2,7 @@
2
2
  name: RRCE
3
3
  description: Phase coordinator for RRCE workflow. Checks state, guides transitions. Uses slash commands for token efficiency.
4
4
  argument-hint: "[PHASE=<init|research|plan|execute|docs>] [TASK_SLUG=<slug>]"
5
- tools: ['search_knowledge', 'search_code', 'find_related_files', 'get_project_context', 'list_projects', 'list_agents', 'get_agent_prompt', 'list_tasks', 'get_task', 'create_task', 'update_task', 'delete_task', 'index_knowledge', 'resolve_path', 'read', 'write', 'edit', 'bash', 'glob', 'grep', 'task', 'webfetch', 'todoread', 'todowrite']
5
+ tools: ['search_knowledge', 'search_code', 'find_related_files', 'get_project_context', 'list_projects', 'list_agents', 'get_agent_prompt', 'list_tasks', 'get_task', 'create_task', 'update_task', 'delete_task', 'index_knowledge', 'resolve_path', 'read', 'write', 'bash', 'task']
6
6
  mode: primary
7
7
  required-args: []
8
8
  optional-args:
@@ -83,9 +83,14 @@ Use `@rrce_executor` subagent only for:
83
83
 
84
84
  Otherwise: Use `/rrce_execute` for in-context execution.
85
85
 
86
- ## Delegation Protocol (When Using Subagent)
86
+ ## Delegation Protocol (OpenCode Optimized)
87
87
 
88
- **CRITICAL: Use summarized context, not full search results.**
88
+ **Slash commands run in-context and are ~60% more token-efficient than subagent delegation.**
89
+
90
+ For isolated execution (e.g. `@rrce_executor`):
91
+ 1. **Mention**: Print `@rrce_executor TASK_SLUG=${TASK_SLUG}` in your message for user visibility.
92
+ 2. **Suggest**: Use OpenCode's interactive confirmation to trigger the handoff.
93
+ 3. **Summarize**: Provide a < 200 token context summary.
89
94
 
90
95
  ```javascript
91
96
  task({
@@ -107,6 +112,11 @@ Execute non-interactively. Return completion signal when done.`,
107
112
 
108
113
  **Hard rule:** Context summary should be < 200 tokens.
109
114
 
115
+ Example handoff:
116
+ > Task research complete. Proceeding to execution?
117
+ > @rrce_executor TASK_SLUG=my-feature
118
+
119
+
110
120
  ## Retrieval Budget
111
121
  - Max **2 retrieval calls per turn**
112
122
  - Use `rrce_get_task` to check phase state
@@ -2,7 +2,7 @@
2
2
  name: RRCE Planning
3
3
  description: Transform research findings into an actionable execution plan through interactive task breakdown.
4
4
  argument-hint: "TASK_SLUG=<slug>"
5
- tools: ['search_knowledge', 'search_code', 'find_related_files', 'get_project_context', 'list_projects', 'update_task', 'read', 'glob', 'grep', 'write', 'todoread', 'todowrite']
5
+ tools: ['search_knowledge', 'search_code', 'find_related_files', 'get_project_context', 'list_projects', 'update_task']
6
6
  required-args:
7
7
  - name: TASK_SLUG
8
8
  prompt: "Enter the task slug to create a plan for"
@@ -2,7 +2,7 @@
2
2
  name: RRCE Research
3
3
  description: Interactive research and requirements clarification through constructive dialogue. Achieves 100% understanding before planning.
4
4
  argument-hint: REQUEST="<user prompt>" [TASK_SLUG=<slug>] [TITLE="<task title>"] [SOURCE=<url>]
5
- tools: ['search_knowledge', 'search_code', 'find_related_files', 'get_project_context', 'list_projects', 'create_task', 'update_task', 'read', 'glob', 'grep', 'write']
5
+ tools: ['search_knowledge', 'search_code', 'find_related_files', 'get_project_context', 'list_projects', 'create_task', 'update_task']
6
6
  required-args:
7
7
  - name: TASK_SLUG
8
8
  prompt: "Enter a task slug (kebab-case identifier)"
@@ -27,7 +27,7 @@ You are the Research agent for RRCE-Workflow. Clarify requirements through focus
27
27
 
28
28
  ## Retrieval Budget
29
29
  - Max **2 retrieval calls per turn**
30
- - First turn: `rrce_search_knowledge` + `rrce_search_code` + `rrce_get_project_context`
30
+ - First turn: `search_knowledge` + `search_code` + `get_project_context`
31
31
  - Subsequent turns: reference cached findings, avoid repeat searches
32
32
 
33
33
  ## Workflow
@@ -2,7 +2,7 @@
2
2
  name: RRCE Sync
3
3
  description: Reconcile project state with the RRCE knowledge base and update semantic index.
4
4
  argument-hint: "[SCOPE=<path|module>]"
5
- tools: ['search_knowledge', 'get_project_context', 'index_knowledge', 'list_projects', 'update_task', 'read', 'write', 'edit', 'bash', 'glob', 'grep']
5
+ tools: ['search_knowledge', 'get_project_context', 'index_knowledge', 'list_projects', 'update_task']
6
6
  required-args: []
7
7
  optional-args:
8
8
  - name: SCOPE
package/dist/index.js CHANGED
@@ -1239,11 +1239,7 @@ function convertToOpenCodeAgent(prompt, useFileReference = false, promptFilePath
1239
1239
  const hostTools = ["read", "write", "edit", "bash", "grep", "glob", "webfetch", "terminalLastCommand", "task"];
1240
1240
  if (frontmatter.tools) {
1241
1241
  for (const tool of frontmatter.tools) {
1242
- if (hostTools.includes(tool)) {
1243
- tools[tool] = true;
1244
- } else {
1245
- tools[`rrce_${tool}`] = true;
1246
- }
1242
+ tools[tool] = true;
1247
1243
  }
1248
1244
  }
1249
1245
  tools["webfetch"] = true;
@@ -4213,7 +4209,7 @@ var Header;
4213
4209
  var init_Header = __esm({
4214
4210
  "src/mcp/ui/Header.tsx"() {
4215
4211
  "use strict";
4216
- Header = () => /* @__PURE__ */ jsx(Box, { flexDirection: "column", paddingBottom: 1, children: /* @__PURE__ */ jsx(Box, { borderStyle: "double", borderColor: "cyan", paddingX: 2, justifyContent: "center", children: /* @__PURE__ */ jsx(Text, { bold: true, color: "white", children: " RRCE MCP Hub " }) }) });
4212
+ Header = () => /* @__PURE__ */ jsx(Box, { flexDirection: "column", paddingBottom: 1, children: /* @__PURE__ */ jsx(Box, { borderStyle: "double", borderColor: "white", paddingX: 2, justifyContent: "center", children: /* @__PURE__ */ jsx(Text, { bold: true, color: "white", children: " RRCE MCP Hub " }) }) });
4217
4213
  }
4218
4214
  });
4219
4215
 
@@ -4640,15 +4636,21 @@ function SimpleSelect({
4640
4636
  onCancel?.();
4641
4637
  }
4642
4638
  });
4643
- return /* @__PURE__ */ jsxs2(Box3, { flexDirection: "column", borderStyle: "round", borderColor: "cyan", padding: 1, children: [
4639
+ return /* @__PURE__ */ jsxs2(Box3, { flexDirection: "column", borderStyle: "round", borderColor: "white", padding: 1, children: [
4644
4640
  message && /* @__PURE__ */ jsx4(Box3, { marginBottom: 1, children: /* @__PURE__ */ jsx4(Text3, { bold: true, children: message }) }),
4645
4641
  items.map((item, index) => {
4646
4642
  const isSelected = index === selectedIndex;
4647
4643
  const isChecked = isMulti && selectedValues.has(item.value);
4648
- return /* @__PURE__ */ jsxs2(Box3, { children: [
4649
- /* @__PURE__ */ jsx4(Text3, { color: isSelected ? "cyan" : "white", children: isSelected ? "> " : " " }),
4650
- isMulti && /* @__PURE__ */ jsx4(Text3, { color: isChecked ? "green" : "gray", children: isChecked ? "[x] " : "[ ] " }),
4651
- /* @__PURE__ */ jsx4(Text3, { color: isSelected ? "cyan" : "white", children: item.label })
4644
+ return /* @__PURE__ */ jsxs2(Box3, { flexDirection: "column", children: [
4645
+ /* @__PURE__ */ jsxs2(Box3, { children: [
4646
+ /* @__PURE__ */ jsx4(Text3, { color: isSelected ? "cyan" : "white", children: isSelected ? "> " : " " }),
4647
+ isMulti && /* @__PURE__ */ jsx4(Text3, { color: isChecked ? "green" : "gray", children: isChecked ? "[x] " : "[ ] " }),
4648
+ /* @__PURE__ */ jsx4(Text3, { color: isSelected ? "cyan" : "white", children: item.label.split("\n")[0] })
4649
+ ] }),
4650
+ item.label.includes("\n") && /* @__PURE__ */ jsxs2(Box3, { paddingLeft: isSelected ? 2 : 2, children: [
4651
+ isMulti && /* @__PURE__ */ jsx4(Text3, { children: " " }),
4652
+ /* @__PURE__ */ jsx4(Text3, { dimColor: true, children: item.label.split("\n").slice(1).join("\n") })
4653
+ ] })
4652
4654
  ] }, item.key || String(item.value));
4653
4655
  }),
4654
4656
  /* @__PURE__ */ jsx4(Box3, { marginTop: 1, children: /* @__PURE__ */ jsx4(Text3, { color: "gray", children: isMulti ? "Space to toggle, Enter to confirm, Esc to cancel" : "Enter to select, Esc to cancel" }) })
@@ -4680,17 +4682,21 @@ var init_ProjectsView = __esm({
4680
4682
  init_ConfigContext();
4681
4683
  init_indexing_jobs();
4682
4684
  init_config_utils();
4683
- ProjectsView = ({ config: initialConfig, projects: allProjects, onConfigChange }) => {
4685
+ ProjectsView = ({ config: initialConfig, projects: allProjects, onConfigChange, workspacePath }) => {
4684
4686
  const { driftReports, checkAllDrift } = useConfig();
4685
4687
  const [config, setConfig] = useState3(initialConfig);
4686
4688
  const [indexingStats, setIndexingStats] = useState3({});
4687
4689
  const sortedProjects = useMemo3(() => {
4688
4690
  return [...allProjects].sort((a, b) => {
4691
+ const aIsCurrent = a.path === workspacePath;
4692
+ const bIsCurrent = b.path === workspacePath;
4693
+ if (aIsCurrent && !bIsCurrent) return -1;
4694
+ if (!aIsCurrent && bIsCurrent) return 1;
4689
4695
  const byName = a.name.localeCompare(b.name);
4690
4696
  if (byName !== 0) return byName;
4691
4697
  return projectKey(a).localeCompare(projectKey(b));
4692
4698
  });
4693
- }, [allProjects]);
4699
+ }, [allProjects, workspacePath]);
4694
4700
  useEffect3(() => {
4695
4701
  const updateStats = () => {
4696
4702
  const next = {};
@@ -4736,15 +4742,18 @@ var init_ProjectsView = __esm({
4736
4742
  const drift = driftReports[p.path];
4737
4743
  const idx = indexingStats[p.name];
4738
4744
  let label = formatProjectLabel(p);
4745
+ if (drift?.hasDrift) {
4746
+ label += ` \u26A0`;
4747
+ }
4739
4748
  if (idx?.state === "running") {
4740
- label += ` [\u27F3 Indexing ${idx.itemsDone}/${idx.itemsTotal ?? "?"}]`;
4749
+ label += `
4750
+ \u27F3 Indexing ${idx.itemsDone}/${idx.itemsTotal ?? "?"}`;
4741
4751
  } else if (idx?.state === "failed") {
4742
- label += ` [\u2715 Index Fail]`;
4752
+ label += `
4753
+ \u2715 Index Fail`;
4743
4754
  } else if (idx?.enabled && idx?.state === "complete") {
4744
- label += ` [\u2713 Indexed]`;
4745
- }
4746
- if (drift?.hasDrift) {
4747
- label += ` \u26A0`;
4755
+ label += `
4756
+ \u2713 Indexed`;
4748
4757
  }
4749
4758
  return {
4750
4759
  label,
@@ -4779,7 +4788,7 @@ var init_ProjectsView = __esm({
4779
4788
  setConfig(newConfig);
4780
4789
  onConfigChange?.();
4781
4790
  };
4782
- return /* @__PURE__ */ jsxs3(Box4, { flexDirection: "column", padding: 1, borderStyle: "round", borderColor: "cyan", flexGrow: 1, children: [
4791
+ return /* @__PURE__ */ jsxs3(Box4, { flexDirection: "column", padding: 1, borderStyle: "round", borderColor: "white", flexGrow: 1, children: [
4783
4792
  /* @__PURE__ */ jsxs3(Box4, { justifyContent: "space-between", children: [
4784
4793
  /* @__PURE__ */ jsxs3(Box4, { children: [
4785
4794
  /* @__PURE__ */ jsx5(Text4, { bold: true, color: "cyan", children: " Projects " }),
@@ -4791,7 +4800,7 @@ var init_ProjectsView = __esm({
4791
4800
  ] }),
4792
4801
  /* @__PURE__ */ jsx5(Box4, { children: /* @__PURE__ */ jsx5(Text4, { color: "dim", children: "a:Toggle Auto u:Drift Space:Select Enter:Save" }) })
4793
4802
  ] }),
4794
- /* @__PURE__ */ jsx5(Text4, { color: "dim", children: " Manage which projects are exposed to the MCP server. Indexing status shown in-line." }),
4803
+ /* @__PURE__ */ jsx5(Text4, { color: "dim", children: " Manage which projects are exposed to the MCP server." }),
4795
4804
  /* @__PURE__ */ jsx5(Box4, { marginTop: 1, flexDirection: "column", flexGrow: 1, children: /* @__PURE__ */ jsx5(
4796
4805
  SimpleSelect,
4797
4806
  {
@@ -4884,7 +4893,7 @@ var init_TasksView = __esm({
4884
4893
  init_ConfigContext();
4885
4894
  init_ui_helpers();
4886
4895
  STATUS_CYCLE = ["pending", "in_progress", "blocked", "complete"];
4887
- TasksView = ({ projects: allProjects }) => {
4896
+ TasksView = ({ projects: allProjects, workspacePath }) => {
4888
4897
  const { driftReports } = useConfig();
4889
4898
  const [expanded, setExpanded] = useState4(() => /* @__PURE__ */ new Set());
4890
4899
  const [selectedIndex, setSelectedIndex] = useState4(0);
@@ -4892,11 +4901,29 @@ var init_TasksView = __esm({
4892
4901
  const [errorLine, setErrorLine] = useState4(null);
4893
4902
  const sortedProjects = useMemo4(() => {
4894
4903
  return [...allProjects].sort((a, b) => {
4904
+ const aIsCurrent = a.path === workspacePath;
4905
+ const bIsCurrent = b.path === workspacePath;
4906
+ if (aIsCurrent && !bIsCurrent) return -1;
4907
+ if (!aIsCurrent && bIsCurrent) return 1;
4895
4908
  const byName = a.name.localeCompare(b.name);
4896
4909
  if (byName !== 0) return byName;
4897
4910
  return projectKey2(a).localeCompare(projectKey2(b));
4898
4911
  });
4899
- }, [allProjects]);
4912
+ }, [allProjects, workspacePath]);
4913
+ useEffect4(() => {
4914
+ const current = sortedProjects.find((p) => p.path === workspacePath);
4915
+ if (current) {
4916
+ const k = projectKey2(current);
4917
+ setExpanded((prev) => {
4918
+ const next = new Set(prev);
4919
+ if (!next.has(k)) {
4920
+ next.add(k);
4921
+ refreshTasksForProject(current);
4922
+ }
4923
+ return next;
4924
+ });
4925
+ }
4926
+ }, [sortedProjects, workspacePath]);
4900
4927
  const refreshTasksForProject = (project) => {
4901
4928
  const res = listProjectTasks(project);
4902
4929
  setTaskCache((prev) => ({ ...prev, [projectKey2(project)]: res.tasks }));
@@ -4981,7 +5008,7 @@ var init_TasksView = __esm({
4981
5008
  }, [flattenedRows]);
4982
5009
  const selectedRow = flattenedRows[selectedIndex];
4983
5010
  const selectedTask = selectedRow?.kind === "task" && selectedRow.task.task_slug !== "__none__" ? selectedRow.task : null;
4984
- return /* @__PURE__ */ jsxs4(Box5, { flexDirection: "column", padding: 1, borderStyle: "round", borderColor: "cyan", flexGrow: 1, children: [
5011
+ return /* @__PURE__ */ jsxs4(Box5, { flexDirection: "column", padding: 1, borderStyle: "round", borderColor: "white", flexGrow: 1, children: [
4985
5012
  /* @__PURE__ */ jsxs4(Box5, { justifyContent: "space-between", children: [
4986
5013
  /* @__PURE__ */ jsxs4(Box5, { children: [
4987
5014
  /* @__PURE__ */ jsx6(Text5, { bold: true, color: "cyan", children: "\u2699 Tasks" }),
@@ -5033,20 +5060,23 @@ var init_TasksView = __esm({
5033
5060
  }),
5034
5061
  /* @__PURE__ */ jsx6(Box5, { marginTop: 1, children: /* @__PURE__ */ jsx6(Text5, { color: "gray", children: "\u25B2/\u25BC navigate \u2022 Enter expand/collapse \u2022 s cycle status \u2022 R refresh" }) })
5035
5062
  ] }),
5036
- /* @__PURE__ */ jsx6(Box5, { flexDirection: "column", width: "45%", paddingLeft: 2, children: !selectedTask ? /* @__PURE__ */ jsxs4(Box5, { flexDirection: "column", justifyContent: "center", alignItems: "center", gap: 1, children: [
5063
+ /* @__PURE__ */ jsx6(Box5, { flexDirection: "column", width: "45%", paddingLeft: 2, children: !selectedTask ? /* @__PURE__ */ jsxs4(Box5, { flexDirection: "column", justifyContent: "center", alignItems: "center", gap: 1, flexGrow: 1, children: [
5037
5064
  /* @__PURE__ */ jsx6(Text5, { bold: true, color: "dim", children: "\u2500 No Task Selected \u2500" }),
5038
5065
  /* @__PURE__ */ jsx6(Text5, { color: "dim", children: "Use \u2191/\u2193 to navigate, Enter to expand projects" }),
5039
5066
  /* @__PURE__ */ jsx6(Text5, { color: "dim", children: "Press 's' to cycle task status" })
5040
5067
  ] }) : /* @__PURE__ */ jsxs4(Box5, { flexDirection: "column", children: [
5041
- /* @__PURE__ */ jsx6(Text5, { bold: true, color: "cyan", children: selectedTask.title || selectedTask.task_slug }),
5042
- selectedTask.summary && /* @__PURE__ */ jsx6(Text5, { children: selectedTask.summary }),
5043
- /* @__PURE__ */ jsxs4(Box5, { marginTop: 1, borderStyle: "single", borderColor: "dim", padding: 1, flexDirection: "column", children: [
5044
- /* @__PURE__ */ jsx6(Text5, { bold: true, color: "cyan", children: "\u{1F4CB} Status" }),
5045
- /* @__PURE__ */ jsxs4(Box5, { flexDirection: "column", marginTop: 0, children: [
5068
+ /* @__PURE__ */ jsxs4(Box5, { marginBottom: 1, flexDirection: "column", children: [
5069
+ /* @__PURE__ */ jsx6(Text5, { bold: true, color: "cyan", children: selectedTask.title || selectedTask.task_slug }),
5070
+ selectedTask.summary && /* @__PURE__ */ jsx6(Text5, { color: "white", children: selectedTask.summary })
5071
+ ] }),
5072
+ /* @__PURE__ */ jsx6(Text5, { dimColor: true, children: "\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500" }),
5073
+ /* @__PURE__ */ jsxs4(Box5, { marginTop: 1, paddingX: 1, flexDirection: "column", children: [
5074
+ /* @__PURE__ */ jsx6(Text5, { bold: true, color: "white", children: "\u{1F4CB} STATUS" }),
5075
+ /* @__PURE__ */ jsxs4(Box5, { flexDirection: "column", marginTop: 1, children: [
5046
5076
  /* @__PURE__ */ jsxs4(Text5, { children: [
5047
- /* @__PURE__ */ jsx6(Text5, { color: "dim", children: "Status:" }),
5077
+ /* @__PURE__ */ jsx6(Text5, { color: "dim", children: "Status: " }),
5048
5078
  " ",
5049
- /* @__PURE__ */ jsx6(Text5, { children: selectedTask.status || "unknown" })
5079
+ /* @__PURE__ */ jsx6(Text5, { color: getStatusColor(selectedTask.status || ""), children: selectedTask.status || "unknown" })
5050
5080
  ] }),
5051
5081
  /* @__PURE__ */ jsxs4(Text5, { children: [
5052
5082
  /* @__PURE__ */ jsx6(Text5, { color: "dim", children: "Updated:" }),
@@ -5054,7 +5084,7 @@ var init_TasksView = __esm({
5054
5084
  /* @__PURE__ */ jsx6(Text5, { children: selectedTask.updated_at || "\u2014" })
5055
5085
  ] }),
5056
5086
  /* @__PURE__ */ jsxs4(Text5, { children: [
5057
- /* @__PURE__ */ jsx6(Text5, { color: "dim", children: "Tags:" }),
5087
+ /* @__PURE__ */ jsx6(Text5, { color: "dim", children: "Tags: " }),
5058
5088
  " ",
5059
5089
  " ",
5060
5090
  (() => {
@@ -5067,9 +5097,10 @@ var init_TasksView = __esm({
5067
5097
  ] })
5068
5098
  ] })
5069
5099
  ] }),
5070
- /* @__PURE__ */ jsxs4(Box5, { marginTop: 1, borderStyle: "single", borderColor: "dim", padding: 1, flexDirection: "column", children: [
5071
- /* @__PURE__ */ jsx6(Text5, { bold: true, color: "cyan", children: "\u{1F4CB} Checklist" }),
5072
- selectedTask.checklist && selectedTask.checklist.length > 0 && /* @__PURE__ */ jsx6(Box5, { marginTop: 0, flexDirection: "column", children: /* @__PURE__ */ jsxs4(Box5, { children: [
5100
+ /* @__PURE__ */ jsx6(Box5, { marginTop: 1, children: /* @__PURE__ */ jsx6(Text5, { dimColor: true, children: "\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500" }) }),
5101
+ /* @__PURE__ */ jsxs4(Box5, { marginTop: 1, paddingX: 1, flexDirection: "column", children: [
5102
+ /* @__PURE__ */ jsx6(Text5, { bold: true, color: "white", children: "\u{1F4CB} CHECKLIST" }),
5103
+ selectedTask.checklist && selectedTask.checklist.length > 0 && /* @__PURE__ */ jsx6(Box5, { marginTop: 1, flexDirection: "column", children: /* @__PURE__ */ jsxs4(Box5, { marginBottom: 1, children: [
5073
5104
  /* @__PURE__ */ jsx6(Text5, { backgroundColor: "white", children: getProgressBar(getChecklistProgress(selectedTask.checklist).percentage) }),
5074
5105
  /* @__PURE__ */ jsxs4(Text5, { dimColor: true, children: [
5075
5106
  " ",
@@ -5082,17 +5113,21 @@ var init_TasksView = __esm({
5082
5113
  "%)"
5083
5114
  ] })
5084
5115
  ] }) }),
5085
- (selectedTask.checklist || []).length === 0 ? /* @__PURE__ */ jsx6(Text5, { color: "dim", children: "\u2014" }) : (selectedTask.checklist || []).slice(0, 12).map((c, i) => /* @__PURE__ */ jsxs4(Text5, { children: [
5086
- /* @__PURE__ */ jsxs4(Text5, { color: "dim", children: [
5087
- getCheckbox(c.status || "pending"),
5088
- " "
5089
- ] }),
5090
- c.label || c.id || "item"
5091
- ] }, c.id || i))
5116
+ (selectedTask.checklist || []).length === 0 ? /* @__PURE__ */ jsx6(Text5, { color: "dim", children: "\u2014" }) : (selectedTask.checklist || []).slice(0, 12).map((c, i) => {
5117
+ const isDone = c.status === "done";
5118
+ return /* @__PURE__ */ jsxs4(Text5, { color: isDone ? "dim" : "white", children: [
5119
+ /* @__PURE__ */ jsxs4(Text5, { color: isDone ? "green" : "dim", children: [
5120
+ getCheckbox(c.status || "pending"),
5121
+ " "
5122
+ ] }),
5123
+ c.label || c.id || "item"
5124
+ ] }, c.id || i);
5125
+ })
5092
5126
  ] }),
5093
- /* @__PURE__ */ jsxs4(Box5, { marginTop: 1, borderStyle: "single", borderColor: "dim", padding: 1, flexDirection: "column", children: [
5094
- /* @__PURE__ */ jsx6(Text5, { bold: true, color: "cyan", children: "\u{1F916} Agents" }),
5095
- !selectedTask.agents ? /* @__PURE__ */ jsx6(Text5, { color: "dim", children: "\u2014" }) : Object.entries(selectedTask.agents).map(([agent, info]) => /* @__PURE__ */ jsxs4(Text5, { children: [
5127
+ /* @__PURE__ */ jsx6(Box5, { marginTop: 1, children: /* @__PURE__ */ jsx6(Text5, { dimColor: true, children: "\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500" }) }),
5128
+ /* @__PURE__ */ jsxs4(Box5, { marginTop: 1, paddingX: 1, flexDirection: "column", children: [
5129
+ /* @__PURE__ */ jsx6(Text5, { bold: true, color: "white", children: "\u{1F916} AGENTS" }),
5130
+ /* @__PURE__ */ jsx6(Box5, { marginTop: 1, flexDirection: "column", children: !selectedTask.agents ? /* @__PURE__ */ jsx6(Text5, { color: "dim", children: "\u2014" }) : Object.entries(selectedTask.agents).map(([agent, info]) => /* @__PURE__ */ jsxs4(Text5, { children: [
5096
5131
  /* @__PURE__ */ jsxs4(Text5, { color: "dim", children: [
5097
5132
  "- ",
5098
5133
  agent,
@@ -5102,16 +5137,16 @@ var init_TasksView = __esm({
5102
5137
  info?.status === "in_progress" && /* @__PURE__ */ jsx6(Text5, { color: "yellow", children: "\u27F3" }),
5103
5138
  info?.status === "pending" && /* @__PURE__ */ jsx6(Text5, { color: "dim", children: "\u25CB" }),
5104
5139
  info?.blocked && /* @__PURE__ */ jsx6(Text5, { color: "red", children: "\u2715" }),
5105
- /* @__PURE__ */ jsxs4(Text5, { dimColor: true, children: [
5140
+ /* @__PURE__ */ jsxs4(Text5, { color: info?.status === "complete" ? "dim" : "white", children: [
5106
5141
  " ",
5107
5142
  info?.status || "\u2014"
5108
5143
  ] }),
5109
5144
  info?.artifact && /* @__PURE__ */ jsxs4(Text5, { dimColor: true, children: [
5110
- "(",
5145
+ " (",
5111
5146
  info.artifact,
5112
5147
  ")"
5113
5148
  ] })
5114
- ] }, agent))
5149
+ ] }, agent)) })
5115
5150
  ] })
5116
5151
  ] }) })
5117
5152
  ] })
@@ -5140,7 +5175,7 @@ var init_LogViewer = __esm({
5140
5175
  if (log.includes("Success")) return /* @__PURE__ */ jsx7(Text6, { color: "green", children: log });
5141
5176
  return /* @__PURE__ */ jsx7(Text6, { children: log });
5142
5177
  };
5143
- return /* @__PURE__ */ jsxs5(Box6, { flexDirection: "column", borderStyle: "round", borderColor: "dim", paddingX: 1, height: height + 2, flexGrow: 1, children: [
5178
+ return /* @__PURE__ */ jsxs5(Box6, { flexDirection: "column", borderStyle: "round", borderColor: "white", paddingX: 1, height: height + 2, flexGrow: 1, children: [
5144
5179
  padding.map((_, i) => /* @__PURE__ */ jsx7(Text6, { children: " " }, `empty-${i}`)),
5145
5180
  visibleLogs.map((log, i) => /* @__PURE__ */ jsx7(Box6, { children: formatLog(log) }, `log-${i}`))
5146
5181
  ] });
@@ -5157,7 +5192,7 @@ var init_StatusBoard = __esm({
5157
5192
  "src/mcp/ui/StatusBoard.tsx"() {
5158
5193
  "use strict";
5159
5194
  StatusBoard = ({ exposedLabel, port, pid, running, hasDrift }) => {
5160
- return /* @__PURE__ */ jsx8(Box7, { borderStyle: "single", borderColor: "cyan", paddingX: 1, flexGrow: 1, children: /* @__PURE__ */ jsxs6(Text7, { children: [
5195
+ return /* @__PURE__ */ jsx8(Box7, { borderStyle: "single", borderColor: "white", paddingX: 1, flexGrow: 1, children: /* @__PURE__ */ jsxs6(Text7, { children: [
5161
5196
  running ? /* @__PURE__ */ jsx8(Text7, { color: "green", children: "\u25CF RUNNING" }) : /* @__PURE__ */ jsx8(Text7, { color: "red", children: "\u25CF STOPPED" }),
5162
5197
  " ",
5163
5198
  "\u2502",
@@ -5266,6 +5301,7 @@ var init_App = __esm({
5266
5301
  pid: process.pid,
5267
5302
  running: false
5268
5303
  });
5304
+ const workspacePath = useMemo5(() => detectWorkspaceRoot(), []);
5269
5305
  const isRAGEnabled = useMemo5(() => {
5270
5306
  return exposedProjects.some((p) => {
5271
5307
  const cfg = findProjectConfig(config, { name: p.name, path: p.path });
@@ -5284,7 +5320,6 @@ var init_App = __esm({
5284
5320
  { id: "projects", label: "Projects" }
5285
5321
  ];
5286
5322
  }, []);
5287
- const workspacePath = detectWorkspaceRoot();
5288
5323
  const installStatus = checkInstallStatus(workspacePath);
5289
5324
  const installedCount = [
5290
5325
  installStatus.antigravity,
@@ -5375,8 +5410,8 @@ var init_App = __esm({
5375
5410
  }
5376
5411
  ),
5377
5412
  activeTab === "logs" && /* @__PURE__ */ jsx10(LogViewer, { logs, height: contentHeight }),
5378
- activeTab === "tasks" && /* @__PURE__ */ jsx10(TasksView, { projects }),
5379
- activeTab === "projects" && /* @__PURE__ */ jsx10(ProjectsView, { config, projects, onConfigChange: handleConfigChange })
5413
+ activeTab === "tasks" && /* @__PURE__ */ jsx10(TasksView, { projects, workspacePath }),
5414
+ activeTab === "projects" && /* @__PURE__ */ jsx10(ProjectsView, { config, projects, onConfigChange: handleConfigChange, workspacePath })
5380
5415
  ] }),
5381
5416
  /* @__PURE__ */ jsx10(Box9, { marginTop: 0, children: /* @__PURE__ */ jsx10(
5382
5417
  StatusBoard,
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "rrce-workflow",
3
- "version": "0.3.11",
3
+ "version": "0.3.13",
4
4
  "description": "RRCE-Workflow TUI - Agentic code workflow generator for AI-assisted development",
5
5
  "author": "RRCE Team",
6
6
  "license": "MIT",