Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
31 changes: 31 additions & 0 deletions extensions/backlog-md-manager/AGENTS.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
# Repository Guidelines

## Project Structure & Module Organization

This repository is a Raycast extension for managing Backlog.md tasks. Command entrypoints live in `src/` and map closely to the commands declared in `package.json`, for example `src/list-tasks.tsx`, `src/create-task.tsx`, and `src/search-tasks.tsx`. Shared CLI and preference logic lives in utility modules such as `src/backlog.ts` and `src/preferences.ts`. Static assets are stored in `assets/`, extension metadata lives in `metadata/`, and setup and usage notes belong in `README.md`.

## Build, Test, and Development Commands

- `npm run dev` starts `ray develop` for local extension development in Raycast.
- `npm run build` runs `ray build` and should pass before opening a PR.
- `npm run lint` runs Raycast's ESLint checks.
- `npm run fix-lint` applies safe lint fixes.
- `npm run publish` publishes to the Raycast Store; do not use `npm publish`.

Local validation is currently `npm run lint && npm run build`, followed by a manual smoke test in Raycast against at least one configured Backlog.md project.

## Coding Style & Naming Conventions

Use TypeScript with 2-space indentation, double quotes, and a 120-character line width, matching `.prettierrc`. Keep command files in kebab-case to match Raycast command names, and keep exported helpers in camelCase. Prefer small, focused modules and shared helpers for CLI interaction and parsing.

When invoking the Backlog CLI, use argument arrays with `execFile` rather than shell interpolation. This extension executes user-configured binaries and project paths, so shell-safe process handling is required.

## Testing Guidelines

There is no dedicated automated test suite yet. For every change, run `npm run lint` and `npm run build`, then manually verify the affected command in Raycast. If you add automated tests, place them beside the source file as `*.test.ts` or `*.test.tsx` and keep them deterministic and CLI-mockable.

## Commit & Pull Request Guidelines

Follow Conventional Commits as seen in history, for example `fix(create-task): eliminate shell injection` and `feat(extension): initial Backlog.md Manager`. Keep commits atomic. Use `cortex git commit "<type>(scope): summary" <files...>` or `cortex git patch` for partial hunks; do not use broad staging.

PRs should include a short summary, linked issue or task when available, the exact validation commands run, and screenshots or short recordings for visible Raycast UI changes.
24 changes: 24 additions & 0 deletions extensions/backlog-md-manager/CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,5 +1,29 @@
# Backlog.md Manager Changelog

## [Milestones, Docs & Editing Improvements] - {PR_MERGE_DATE}

### New Features

- **List Docs** — browse Backlog.md documents with a metadata sidebar (ID, type, created date, file path)
- **Milestone Picker** — assign milestones from Create Task and Edit Task, with progress tracking and active/completed filtering
- **Demote to Draft** — move active tasks back into the drafts folder from List and Search views
- **Open Browser launch argument** — pass an optional project name to target a specific configured project regardless of the active selection
- **Smart browser launcher** — reuses the last live port for a project when possible
- **Task-surface browser actions** — open the Backlog.md browser UI directly from the task list and detail views

### Improvements

- **Edit Task** — manage acceptance criteria and Definition of Done (toggle, add, remove via tag picker); pick dependencies via shared task picker; append or replace modes for Notes and Final Summary
- **Create Task** — parent, dependency, and milestone pickers (Command-Option-P, Command-Shift-P, Command-Option-M); streamlined to focus on definition fields, leaving Plan / Notes / Final Summary to the Edit Task flow
- **Task Detail** — shows additional Backlog.md fields in the metadata sidebar

### Fixes

- **Edit Task** — clearing priority to None no longer silently sends `--priority low`
- **Edit Task** — milestone change detection now compares on the resolved milestone id rather than the raw string from the task file, so a picked milestone whose title happens to match the original is no longer skipped
- **Create Task** — the Add Acceptance Criterion keyboard shortcut now works inside form fields (was Command-A, which collided with macOS text-field "Select All"; now Command-Option-A)
- **Open Browser** — when the project-name launch argument matches more than one configured project, the command now surfaces the ambiguous candidates instead of silently picking the first match

## [Initial Release] - 2026-04-28

### New
Expand Down
42 changes: 27 additions & 15 deletions extensions/backlog-md-manager/README.md
Original file line number Diff line number Diff line change
@@ -1,47 +1,59 @@
# Backlog.md Manager

Manage your [Backlog.md](https://www.npmjs.com/package/backlog.md) tasks directly from Raycast. Browse, create, search, edit, and change task status across multiple projects without leaving Raycast.
Manage your [Backlog.md](https://www.npmjs.com/package/backlog.md) tasks, milestones, and docs directly from Raycast. Browse, create, search, edit, manage milestones, and open the browser UI across multiple projects without leaving Raycast.

## Prerequisites

- **Backlog.md CLI** install via `npm install -g backlog.md`
- **Backlog.md CLI** - install via `npm install -g backlog.md`
- At least one project initialized with `backlog init`

## Setup

On first launch, you'll be prompted to configure two preferences:
On first launch, configure these extension preferences:

- **Project Directories** comma-separated absolute paths to your Backlog.md projects (e.g. `/Users/you/Dev/ProjectA, /Users/you/Dev/ProjectB`). Tilde paths like `~/Dev/ProjectA` are also supported.
- **Backlog CLI Path** absolute path to the `backlog` binary. Defaults to `/opt/homebrew/bin/backlog`. If you installed via npm globally, you can find it with `which backlog`.
- **Project Directories** - comma-separated absolute paths to your Backlog.md projects, for example `/Users/you/Dev/ProjectA, /Users/you/Dev/ProjectB`. Tilde paths like `~/Dev/ProjectA` are also supported.
- **Backlog CLI Path** - absolute path to the `backlog` binary. It defaults to `/opt/homebrew/bin/backlog`.

## Commands

### List Tasks

Browse all tasks grouped by status (To Do, In Progress, Done, Blocked). Use the action panel to filter by status or priority. If you have multiple projects configured, switch between them with the dropdown in the search bar.
Browse all tasks grouped by status (To Do, In Progress, Done, Blocked). Use the action panel to filter by status or priority. If you have multiple projects configured, switch between them with the dropdown in the search bar. The action panel also offers Demote to Draft to move an active task back into the drafts folder.

| Shortcut | Action |
| -------- | ------------------------ |
| `↵` | View task details |
| `⌘E` | Edit task |
| `⇧⌘S` | Start task (In Progress) |
| `⇧⌘D` | Complete task (Done) |
| `⌘R` | Refresh list |

### Create Task

Full-featured task creation form supporting all `backlog task create` options:
Create tasks with the full Raycast form. Pick a parent task, dependencies, and milestone through dedicated pickers (Command-Option-P for parent, Command-Shift-P for a dependency, Command-Option-M for milestone); add acceptance criteria (Command-Option-A) and Definition of Done items (Command-D); attach references and supporting documents through file pickers. Implementation plan, notes, and final summary are filled in by the agent that picks up the task — use Edit Task for those.

- Title, description, priority, labels, assignee
- Draft mode, parent task, and dependencies
- Acceptance criteria — press `⌘A` to add more fields
- Definition of Done — press `⌘D` to add more fields
- References and documentation links — press `⌘R` / `⇧⌘D` to add more
- File attachments via drag and drop (added as `--ref`)
### Edit Task

Edit any field of an existing task from a pre-populated form:

- **Basic fields** — title, description, status, priority, labels, assignee
- **Acceptance Criteria & Definition of Done** — toggle existing items via checkboxes, mark items for removal via tag picker, and add new items inline (Command-Option-A / Command-D)
- **Dependencies** — add via the shared task picker (Command-Shift-P), remove the most recent (Option-Shift-P)
- **Milestone** — assign or change via picker (Command-Option-M); clear via the action panel
- **Plan, Notes, Final Summary** — Plan replaces in place. For Notes and Final Summary, you can either append a paragraph (preserves existing content) or replace the whole field

### Search Tasks

Full-text search powered by the Backlog.md index. Results are ranked by relevance and show status and priority at a glance. Press `↵` to view full task details.
Full-text search across tasks. Results show status and priority at a glance and support the same detail, edit, and demote actions as the list command.

### List Docs

Browse the project's Backlog.md documents and read them with a metadata sidebar (ID, type, created date, file path). Open a doc in Finder or copy its ID directly from the action panel.

### Open Browser

Launch the Backlog.md browser UI for the current active project. The command reuses the last known live browser port for that project when possible, otherwise it prefers the project's configured `defaultPort` and falls back to a stable free port near the Backlog default. Pass an optional **Project Name** argument at launch to target a specific configured project regardless of the current active selection.

## Multi-Project Support

Configure multiple project paths in preferences. The extension remembers your last selected project across launches using Raycast's persistent cache. Switch projects from the dropdown in the search bar (List/Search) or the form dropdown (Create).
The extension remembers your last selected project across launches using Raycast's persistent cache. Switch projects from the dropdown in any list view, and Open Browser will follow the same active project on the next launch unless overridden by the launch argument.
6 changes: 6 additions & 0 deletions extensions/backlog-md-manager/eslint.config.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
const { defineConfig } = require("eslint/config");
const raycastConfig = require("@raycast/eslint-config");

module.exports = defineConfig([
...raycastConfig,
]);
Binary file modified extensions/backlog-md-manager/metadata/backlog-md-manager-1.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file modified extensions/backlog-md-manager/metadata/backlog-md-manager-2.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file modified extensions/backlog-md-manager/metadata/backlog-md-manager-3.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file modified extensions/backlog-md-manager/metadata/backlog-md-manager-4.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file modified extensions/backlog-md-manager/metadata/backlog-md-manager-5.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file modified extensions/backlog-md-manager/metadata/backlog-md-manager-6.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
7 changes: 0 additions & 7 deletions extensions/backlog-md-manager/package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

36 changes: 36 additions & 0 deletions extensions/backlog-md-manager/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -81,6 +81,42 @@
"query",
"backlog"
]
},
{
"name": "list-docs",
"title": "List Docs",
"subtitle": "Backlog.md",
"description": "Browse Backlog.md documents and preview their contents",
"mode": "view",
"keywords": [
"docs",
"documents",
"backlog",
"list",
"browse"
]
},
{
"name": "open-browser",
"title": "Open Browser",
"subtitle": "Backlog.md",
"description": "Open the Backlog.md browser UI using a reused or intelligently selected local port",
"mode": "view",
"keywords": [
"browser",
"web",
"ui",
"open",
"dashboard"
],
"arguments": [
{
"name": "projectName",
"placeholder": "Project name (optional)",
"type": "text",
"required": false
}
]
}
],
"dependencies": {
Expand Down
52 changes: 52 additions & 0 deletions extensions/backlog-md-manager/src/backlog.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,13 @@ import { getProjectConfig } from "./preferences";

const execFileAsync = promisify(execFile);

export interface BacklogTaskSummary {
id: string;
title: string;
priority: string;
status: string;
}

export async function runBacklog(args: string[], cwd: string): Promise<string> {
const { backlogPath } = getProjectConfig();

Expand All @@ -15,3 +22,48 @@ export async function runBacklog(args: string[], cwd: string): Promise<string> {

return stdout;
}

export function parseTaskSummaries(output: string): BacklogTaskSummary[] {
const tasks: BacklogTaskSummary[] = [];
let currentStatus = "";

for (const line of output.split("\n")) {
const trimmed = line.trim();
if (!trimmed) continue;

if (trimmed.endsWith(":") && !trimmed.startsWith("[")) {
currentStatus = trimmed.slice(0, -1);
continue;
}

const match = trimmed.match(/^\[(\w+)\]\s+([\w-]+)\s+-\s+(.+)$/);
if (!match || !currentStatus) continue;

tasks.push({
priority: match[1].toLowerCase(),
id: match[2],
title: match[3],
status: currentStatus,
});
}

return tasks;
}

export async function listTaskSummaries(
cwd: string,
filters: { status?: string; priority?: string } = {},
): Promise<BacklogTaskSummary[]> {
const args = ["task", "list", "--plain"];

if (filters.status && filters.status !== "All") {
args.push("--status", filters.status);
}

if (filters.priority && filters.priority !== "All") {
args.push("--priority", filters.priority.toLowerCase());
}

const stdout = await runBacklog(args, cwd);
return parseTaskSummaries(stdout);
}
Loading
Loading