Introduction

Running engineering tasks in DSH presents a practical question: where to store the task list? Epics, Stories, and Tickets extracted from tasks are scattered across conversations, requiring realignment whenever a new conversation starts. Markdown documents stored in the repository require the model to re-locate and update them every round, while humans lack a centralized view.

The philosophy behind oh-my-ticket (OMT) is to make the task tree a first-class citizen of the plugin: hierarchy is stored in the project directory, metadata in SQLite, and the body in Markdown. Models create and advance tasks through tools, humans browse and manage them via the UI, and batch execution is backed by the run mechanism. Below, we introduce its structure, installation method, and typical usage.

What is it

oh-my-ticket is a DSH ticket management plugin maintained by rqwj, licensed under MIT, with the current version being 0.6.4. The README badge indicates the platform as DeepSeek Harness (test version 0.1.2-alpha.3). Regarding naming, it corresponds to three identifiers: the README title “Oh-My-Ticket (OMT)”, the npm package name dsh-oh-my-ticket, and the repository rqwj/oh-my-ticket. It will be referred to as OMT below.

In one sentence, it is positioned as a five-level task system (Epic → Story → [SubStory] → Ticket → [SubTicket]), where SQLite stores metadata and hierarchy, Markdown stores the body text, tickets follow the project, and both humans and machines share the same tree, providing batch execution via run.

Core Features

Five-Level Task System and Ownership

The hierarchy is fixed at five levels, with square brackets indicating optional items: Epic → Story → [SubStory] → Ticket → [SubTicket].

Storage is a dual-write system: SQLite stores metadata and hierarchy, while Markdown stores the body text. The body text can be edited directly on disk; after manual changes, simply run omt_reindex to rebuild the index. The SQLite index itself is gitignored and can be rebuilt at any time.

Ownership rules:

  1. If .omt/ exists in the workspace root directory, tickets follow the project and can be directly committed to git;
  2. Otherwise, it falls back to a global home, with the resolution order being plugin config > OMT_HOME > ~/.omt;
  3. IDs are globally unique across homes; when creating an Epic, a popup dialog appears to select the ownership.

The resolution contract for runtime configuration (home / runtime dir) is parameters > environment variables > defaults, ensuring consistency across platforms, locked down by cross-layer parity testing.

Three UI Shells and Tree Interaction

The same ticket tree provides three switchable shells:

  • Left Drawer (shell.overlay overlay);
  • Free-floating draggable window;
  • OMT Tab: Side-by-side with Chat | Trajectory, can pop out as a floating window.

The three shells share the same tree interaction set: type badges (E/S/SS/T/ST), status dots, priority signal bars (P1–P3), search, multi-select filtering by type/status/priority, priority sorting, and numbering display toggle. Filter states are automatically saved to .omt/ui-filters.json in the workspace. Archiving is a read-only dimension independent of lifecycle status.

Change notifications are pushed via the dedicated SSE channel /omt/events, refreshing the UI immediately after the model makes changes.

Document Details and Bi-directional Linkage

Selecting a node opens the full document in the details panel, where you can perform title/status/priority/archiving operations and append progress records; the “Execute” button references the ticket into the input box to submit for execution.

The model and UI have bi-directional linkage: typing @ triggers ticket reference, and a reference bar appears above the input box; at the end of each conversation round, the list of related tickets is automatically displayed.

Batch Execution with run

run snapshots a batch of Tickets/SubTickets into an ordered list, handing them over to the model to claim, execute, and report truthfully. The item state machine is pending → running → done / failed / blocked / skipped / interrupted, with an additional trust policy state awaiting_confirmation—a “naked” done (without a report) requires confirmation or rejection in the run details. run supports pause / resume / retry.

Two design details:

  1. Execution context injection: upon successful claim, the body text of the ancestor chain is read as read-only context to return; recent parents are prioritized within a 16 KiB budget, truncation is explicitly marked, and a single point read failure degrades without blocking;
  2. Ancestor activation: when a ticket starts work, ancestors still marked as open are automatically highlighted; done/blocked/skipped ancestors are never reopened, and archived ancestors are silently skipped.

On the UI side, the tree row “▸▸” adds a ticket to run with one click; triggering “Start Execution” from the UI automatically wakes up the execution session to enter the claim loop.

Model Tools and Embedded Skills

The plugin registers 12 omt_* model tools:

  • Ticket operations: omt_create / omt_list / omt_show / omt_update / omt_move / omt_reindex
  • Run operations: omt_run_create / omt_run_list / omt_run_show / omt_run_control / omt_run_claim / omt_run_report

Specifically, omt_run_claim atomically claims the next item and binds the executor, returning read-only ancestor context; omt_run_report reports the result of a single item (done/failed/blocked/skipped), and the note is recorded into the ticket’s progress.

It embeds two skills: omt teaches the operation norms and state transition conventions of the ticket system, and omt-runs teaches the discipline of run batches. After the plugin is enabled, the complete OMT operation norms are written to the system prompt by default, so it is not necessary to load the skill first; the settings page allows adding conventions and selecting ticket splitting skills from installed skills.

Installation and Usage

Install a published version from npm:

pnpm dsh plugin --profile <profile> add dsh-oh-my-ticket@0.6.4

You can also install from local build after building and packaging in this repository:

pnpm install && pnpm build && npm pack    # produces dsh-oh-my-ticket-0.6.4.tgz
pnpm dsh plugin --profile <profile> add /path/to/dsh-oh-my-ticket-0.6.4.tgz

Enabling requires the target profile’s dsh.profile.bundles to be in the following order:

  1. @deepseek-ai/dsh-base
  2. @deepseek-ai/dsh-web-app
  3. dsh-oh-my-ticket

The daemon binary is automatically brought in with the main package as an optionalDependency (@oh-my-ticket/darwin-arm64), but can also be obtained independently via brew / install.sh / GitHub Release.

After installation or upgrade, you need to restart the dsh web process for the new version’s tools and UI to take effect.

Typical Usage

First, let the project have an independent ticket library. Execute in the project root directory:

mkdir .omt

.omt/ is committed to git with the project, and the ticket library follows the project.

The subsequent daily workflow is roughly as follows:

  1. Let the model use omt_create to break down Epic / Story / Ticket hierarchies;
  2. Select a task row in the tree, “▸▸” to add to run, or let the model use omt_run_create to snapshot a batch of Tickets/SubTickets;
  3. Trigger “Start Execution” from the UI, and the execution session enters the claim loop;
  4. The model claims items one by one using omt_run_claim (returning read-only ancestor context and activating open ancestors), and after completion, reports the results using omt_run_report, recording notes into the ticket progress.

If you manually modify the Markdown body text directly on disk, run omt_reindex once to rebuild the SQLite index.

Suitable Scenarios and Notes

Suitable scenarios: For developers of agents running multi-step engineering tasks in DSH, requiring the task tree to be persisted into the project, sharing a task view between the model and humans, and batch execution backed by a state machine and trust strategy.

A few notes:

  • The plugin runs with the permissions of the current dsh process; it is recommended to check the source code and license before installation (this project is MIT);
  • The daemon platform package is currently only available for @oh-my-ticket/darwin-arm64;
  • The order of dsh.profile.bundles in the profile has requirements, see the installation section above;
  • Archiving is a read-only dimension; the SQLite index is gitignored and can be rebuilt using omt_reindex.

Summary

OMT brings task management into a DSH plugin: a five-level tree, dual-write SQLite + Markdown, committed to git with the project, 12 model tools plus 2 skills constraining behavior on the model side, and 3 UI shells for browsing and management on the human side, with batch execution backed by a state machine and trust strategy. Source code and directory page are located at:

  • GitHub: https://github.com/rqwj/oh-my-ticket
  • Directory Page: https://www.skillhub.cn/plugins/rqwj/oh-my-ticket

The directory page is an independently maintained plugin directory by the community, with no official affiliation to DeepSeek / Hypothesis.