HivePaaS
Docker Swarm 기반 오픈소스 자체 호스팅 PaaS, SSL·백업·자동 확장 지원
여러 저장소의 스토리와 티켓을 하나의 SQLite DB에 저장하고, CLI로 생성·종료·조회·검증하는 티켓 엔진 및 작업 공간
Ticket engine and workspace job runner for multi-repository development: every repo's stories and append-only ticket log live in one SQLite database, and one CLI creates, closes, queries and verifies
개발 도구C# · PowerShellGitHub @mindattic온라인운영자 미확인
써 보셨어요? 한 번만 눌러 주세요. 로그인은 필요 없어요.
아직 감지된 업데이트가 없습니다. GitHub 릴리스가 나오면 여기에 보입니다.
개인 계정의 공개 저장소 소유자는 GitHub로 로그인해 운영자를 확인하고 소개를 직접 관리할 수 있습니다. 관리자 승인은 필요하지 않습니다.
로그인한 뒤 확인 파일을 만들어 이 저장소의 기본 브랜치에 30분 안에 커밋해 주세요. 다른 브랜치나 포크의 파일은 인정하지 않습니다. 파일을 올린 뒤 아래에서 확인하면 관리자 승인 없이 관리할 수 있습니다. 자격을 유지하려면 파일을 남겨 두세요.
로그인이 필요하면 로그인 화면으로 이동합니다. 로그인 후 이곳으로 돌아와 원하는 확인 버튼을 다시 눌러 주세요.
프로젝트 폴더에서 /nomorevibe verify를 실행하면 소유권을 확인하고 소개를 직접 관리할 수 있습니다.
1분 만에 확인하기Ticket engine and workspace job runner for multi-repository development: every repo's stories and append-only ticket log live in one SQLite database, and one CLI creates, closes, queries and verifies them across all repos, opens a read-only viewer, reports uncommitted and unpushed work, and safely prunes archived repositories.
저장소 README에서 가져옴
README 전체를 불러오는 중입니다.
README 전문 보기 ↗A ticket engine and repo job runner for the MindAttic workspace: every repo's stories and permanent ticket log live in one SQLite database, queried, checked and maintained by a CLI and a WPF desktop app.
$ tickets ticket list --status open
╭────────────────────┬────────────┬────────────┬─────────┬────────┬─────────────────────────────────╮
│ Repo │ ID │ Date │ Type │ Status │ Summary │
├────────────────────┼────────────┼────────────┼─────────┼────────┼─────────────────────────────────┤
│ MindAttic.Tickets │ M.TIX-T7 │ 2026-10-12 │ feature │ open │ /commit logs tickets through … │
│ MindAttic.Tickets │ M.TIX-T8 │ 2026-10-12 │ feature │ open │ Launcher Workflow menu item │
╰────────────────────┴────────────┴────────────┴─────────┴────────┴─────────────────────────────────╯
Stories and tickets (every repo's, in one SQLite database: data/Tickets.db, with links such as requires between any two; each repo's docs/USER_STORIES.md is a generated, read-only view of it, rewritten after every change)
ticket new appends a row with the next free CODE-T<n> ID and prints it. It warns (on stderr, still filing) of open tickets in the repo whose summary reads alike, the same check Tickets Desktop's new-ticket dialog shows as you type. --template starts the description from the type's template (fix: symptom, cause, test; feature: story, acceptance; ticket template TYPE prints it), and the Desktop dialog starts from it too, swapping it as the type changes while it's untouched; an untouched template is never filed as a description.ticket close moves a ticket to closed or wont-do and can set its Ref.ticket correct relabels a nonstandard type to the standard vocabulary, the one sanctioned exception to append-only (recorded in the ticket's history).part-of is the child → parent edge at any depth (an epic is just a ticket with children), requires the prerequisite; every edge is stored once and read back from its other end by its inverse (required-by, parent-of, followed-up-by, superseded-by, duplicated-by, implemented-by), and ticket link takes those words too (and contains, child-of), swapping the ends. A link to an ID that names no ticket, story or epic is refused, as is one that would close a requires or part-of cycle (the refusal names the cycle's path). ticket show lists parents, children, prerequisites, required-by and related as ID · Name · status (--json too); ticket graph adds the part-of tree (Part of: and Children:); ticket verify also fails on a part-of cycle and warns of a closed parent with open children.ticket graph <ID> --hops N --format dot|mermaid exports the neighbourhood N links out for Graphviz or a markdown page (--json adds its nodes, with weight and repo colour, and edges). Tickets Desktop's Graph tab (Ctrl+8) and the Graph tab of tickets view draw it around a focused ticket: nodes labelled ID · Name, outlined in their repo's colour, sized by graph weight, with their status and type; requires a solid arrow, part-of a thick parent → child tree line, related dashed, other kinds dotted. Part-of trees are laid out in rows (parents above), the rest force-directed, seeded by ID so the picture is the same on every refresh. Pick the hops and link kind, narrow it by repo and status (and, in the Desktop, type, label and search), collapse or expand a parent's children (− / +), and click a ticket to focus it and open its details; the same links are listed as text for screen readers.ticket queue shows each weight with a one-line why ("unblocks 7 tickets in 3 repos"), --json carries weight and why, and TicketsDb.GraphWeights() / GraphWeight.Order give the Orchestrator the same order. ticket suggest-links proposes likely duplicates/related links between open tickets whose summaries read alike, each with the ticket link command that accepts it; nothing is linked by it.ticket new --name, ticket correct <ID> --name, recorded in its history). ticket list, queue, show, graph, Tickets Desktop and view show ID · Name, falling back to the summary cut short while a ticket has none; --json carries name (and the queue a ready-made caption). ticket names is the one-time backfill, propose then confirm: it proposes a name for every open ticket without one (--output FILE writes them tab-separated to review and edit), and only --apply FILE writes them.ticket show prints a ticket end to end: its row, queue state, assignee, reservation, the session working it, links, history and its commits: those whose subject names it, each with its GitHub link, as the Desktop detail pane lists them too (--diff adds their full diffs); --versions lists every version of it (on SQL Server, where tickets, their approval and priority, their work and links are system-versioned temporal tables, every save is kept, never pruned; on the SQLite file, versions are worked back from its history) and --version N shows one, its changes marked. ticket link connects two tickets or stories (requires is a prerequisite; a cycle is refused).ticket list shows tickets across the workspace, filtered by repo, status, type or date, as a table or --json. --query takes the ticket query language: repo: (a name or a ticket code), type:, status:, label:, approval: and free text (matched against ID, summary, ref and repo; quote it to keep spaces), every term required; commas give alternatives (status:open,wont-do), a leading - negates (--query=-type:chore), * is a wildcard in repo and label. An unknown field or value is refused, saying what's allowed. --format csv|md exports the filtered list as CSV (RFC 4180, a leading =/+/-/@ defused) or a markdown table, and --output FILE writes it to a file (UTF-8; a .csv or .md name picks the format).ticket stats reports ticket metrics from ticket_events: per day, week (Monday to Sunday) or month in UTC (--by, --periods N), the tickets filed, closed and closed wont-do and those open at each period's end; cycle time from filing to closing (median, mean, 85th percentile) overall and by type; and the tickets open at each period's end by repo and by type. --repo/--type narrow it, --json prints it. A reopen takes back the closing before it; a ticket filed already closed counts as throughput but not cycle time; one imported already closed (no history) counts nowhere.filter save <NAME> <QUERY> / filter list / filter delete <NAME> keep named queries in the database (saved_filters); ticket list --filter <NAME> runs one (and --query narrows it). Tickets Desktop shares them.ticket verify fails if the table breaks the rules or a committed row was deleted or reworded. It checks the versions too: a table no longer system-versioned, a history row that runs backwards, or a ticket whose last recorded change isn't what it says now.ticket queue lists a repo's (or every repo's) open tickets in priority order with their approval state; ticket approve/ticket reject --reason move a ticket through review (--undo puts an approval back to proposed; a reject closes the ticket wont-do with the reason as its ref); ticket priority sets where a ticket sits in that order and ticket bump moves it up or down. ticket estimate keeps each ticket's effort estimate in tokens (ticket_queue.estimate, editable in Tickets Desktop too); within one priority the queue runs the smallest estimate first, and ticket estimate --seed fills in open tickets without one from the median cost of finished tickets of the same type and repo in the Orchestrator's TicketCosts.ticket assign <ID> <email> assigns a ticket to a member's login (--unassign, --redelegate), ticket block <ID> --by X makes it wait for others (--clear), ticket reserve <ID> 2M sets tokens aside for it (0 releases), ticket working <ID> --login --session records the session working it (--clear), ticket hygiene lists closed tickets that may not be done, and ticket intake files GitHub issues labelled orchestrator and CI failures on main as tickets (--dry-run).codes check finds duplicate project codes, repos without a ticket log, and malformed tables.story new/edit/status/list/show, epic new, backlog add add and edit a repo's stories, epics and priority backlog in the database.db migrate, export, check, render, sync import a repo's file once, rebuild it from the database, validate the database, rewrite a stale view, and commit (and push) data/Tickets.db and its readable dump data/Tickets.sql; a sync's commit names the tickets whose rows or history changed since the last one (or --ticket ID), and when a change has nothing to name (a story, epic or backlog edit alone) it opens and closes a chore ticket to carry it instead, so a sync with something to commit always names a ticket.view opens a read-only page of every repo's tickets and stories, with filters, in MindAttic.Browser (or the default browser). It's a snapshot; run it again to refresh.Tickets Desktop (src/MindAttic.Tickets.Desktop, a WPF app built on MindAttic.Components.Wpf, matching the Orchestrator's look)
ticket list --query (a query that doesn't parse says why under it), and Saved filter picks, saves and deletes the named queries tickets filter keeps. Export… (Ctrl+E) saves the tickets the current view shows, every filter, the query and the sort applied, as CSV or markdown.tickets ticket hygiene; each links to its ticket) and the Orchestrator's last audit run (shared agent files that drifted or are missing, duplicate code across repos), read from its database.tickets ticket stats reports, for the repo filter, as four read-only tables a screen reader reads as tables (throughput, cycle time by type, open by repo, open by type), by Day, Week or Month.tickets ticket intake): asks GitHub for issues labelled orchestrator and CI failures on main, shows the dry run, and files exactly those tickets only when you click File; nothing is written to GitHub.MindAttic.Orchestrator.exe --show <email|session|ticket>; nothing happens beyond a message when the Orchestrator isn't installed).requires links shows a Dependencies section: its chains both ways drawn in rows (what it waits for above it, farthest first; what waits for it below), what holds work up now outlined in red and said in words, each ticket a button that goes to it, and the same graph as an indented text list for screen readers (tickets ticket graph prints it too).Workspace jobs
repos status shows each repo's uncommitted, unpushed and stashed work, ignored files that no build regenerates, and its GitHub state (archived, work-in-progress topic). Origins that predate a repo rename are resolved through GitHub's redirect.repos prune lists repos that are archived or untagged on GitHub and deletes the safe ones with --apply and a typed yes. Local-only work blocks a delete unless you name the repo in --override. A repo with no GitHub copy, or one another kept repo loads by relative path (a ProjectReference, a Unity file: package, a solution entry), can't be overridden.repos rollout tickets gives every repo without one a docs/USER_STORIES.md with a unique project code and a ticket log.repos rename renames a repo's folder-name key everywhere the database keys it (backed up first; it doesn't touch anything on disk — rename the folder yourself) and is kept forever in the repo's rename history and in every one of its tickets' history; repos renames lists recorded renames.Prerequisites: the .NET 10 SDK, git on PATH, and (for the GitHub columns and prune) a GitHub token in MindAttic.Vault, set from the Launcher's Settings menu.
git clone https://github.com/mindattic/MindAttic.Tickets.git
cd MindAttic.Tickets
dotnet build MindAttic.Tickets.slnx
dotnet run --project src/MindAttic.Tickets.Cli -- ticket list
You should see every ticket in every repo under D:\Projects\MindAttic.
tickets ticket new [--repo X] --type feature|fix|chore|docs|interview --summary "..." [--name "..."] [--ref ...] [--status open|closed|wont-do] [--template | --description "..." | --description-file F]
tickets ticket template feature|fix|chore|docs|interview # print the type's description template
tickets ticket close <CODE-Tn> [--repo X] [--ref ...] [--wont-do]
tickets ticket correct <CODE-Tn> --type feature|fix|chore|docs|interview --reason "..."
tickets ticket correct <CODE-Tn> --name "Short friendly name" # "" clears it; no --reason needed
tickets ticket names [--repo X] [--output FILE | --apply FILE] # propose names for unnamed open tickets; write only the reviewed file
tickets ticket reassign <CODE-Tn> <CODE-Tm> --reason "..." # the old ID is kept in id_history and still resolves
tickets ticket show <CODE-Tn> [--json] [--diff] [--versions | --version N]
tickets ticket graph <CODE-Tn> [--json | --format text|json|dot|mermaid] [--hops N] # requires chains and the part-of tree; dot/mermaid draw the neighbourhood
tickets ticket link <FROM> requires|related|follow-up-of|supersedes|duplicates|implements|part-of <TO> [--remove] [--note "..."]
# or by the other end: required-by|parent-of|contains|child-of|followed-up-by|superseded-by|duplicated-by|implemented-by
tickets ticket list [--repo X] [--status S] [--type T] [--since YYYY-MM-DD] [--query "repo:X type:fix 'text'"] [--filter NAME] [--json | --format table|json|csv|md] [--output FILE]
tickets ticket stats [--repo X] [--type T] [--by day|week|month] [--periods N] [--json] # throughput, cycle time, open by repo and type
tickets filter save <NAME> <QUERY> # also: tickets filter list [--json], tickets filter delete <NAME>
tickets ticket verify [--repo X]
tickets ticket queue [--repo X] [--json]
tickets ticket approve [<CODE-Tn> ...] [--undo] # no IDs: list what waits for approval
tickets ticket reject <CODE-Tn> --reason "..."
tickets ticket priority <CODE-Tn> <PRIORITY>
tickets ticket bump <CODE-Tn> [--by N]
tickets ticket estimate <CODE-Tn> [<TOKENS> | --clear] # effort estimate, like 300k; within a priority the queue runs the smallest first
tickets ticket estimate --seed [--repo X] [--overwrite] [--dry-run] # estimate open tickets from the Orchestrator's TicketCosts medians
tickets ticket assign <CODE-Tn> [<email>] [--unassign | --redelegate]
tickets ticket block <CODE-Tn> [--by <CODE-Tm> ...] [--clear]
tickets ticket reserve <CODE-Tn> <TOKENS> # like 2M or 500k; 0 releases
tickets ticket working <CODE-Tn> [--login <email>] [--session <id>] | --clear
tickets ticket note <CODE-Tn> "<markdown>" [--author <name>] # append-only comment (- reads stdin); show lists them
tickets ticket hygiene [--repo X] [--json]
tickets ticket intake [--repo X] [--dry-run]
tickets codes check
tickets story list [--repo X] [--status done|partial|planned] [--json]
tickets story show <CODE-US-...>
tickets story new [--repo X] --epic KEY --text "..." [--status planned|partial|done]
tickets story edit <CODE-US-...> --text "..." [--repo X]
tickets story status <CODE-US-...> done|partial|planned [--repo X]
tickets epic new [--repo X] --key KEY --title "..."
tickets backlog add [--repo X] --text "..."
tickets db migrate [--cutover] [--db FILE]
tickets db export [--repo X] [--out FILE]
tickets db check [--fix]
tickets db render [--repo X]
tickets db sync [--no-push] [--ticket ID]
tickets view [--repo X] [--out DIR] [--no-open]
tickets repos status [--json]
tickets repos prune [--apply] [--only A,B] [--override A,B]
tickets repos rollout tickets [--apply]
tickets repos rename <OLD> <NEW> [--reason "..."]
tickets repos renames [--repo X]
tickets repos recode <REPO> <CODE> --reason "..." # every ticket/story/epic ID moves to the new code; old IDs still resolve
Every command takes --root <DIR> (default D:\Projects\MindAttic). --repo defaults to the repo containing the current directory. Exit codes: 0 success, 1 problems found or the operation failed, 2 bad arguments.
tickets CLI · Tickets Desktop (WPF) · Launcher menu · /commit
|
MindAttic.Tickets (library)
| |
Data/ (SQLite, TicketsDb) Repos/ (git + GitHub)
| |
data/Tickets.db, data/Tickets.sql, git -C <repo>, api.github.com/user/repos
<repo>/docs/USER_STORIES.md (generated view)
Every repo's stories, epics, backlog and tickets (and the links between them) live in data/Tickets.db, committed to this repo alongside a readable SQL dump (data/Tickets.sql) so changes show up as text diffs. A repo's docs/USER_STORIES.md is rewritten from the database after every change that touches it (and by tickets db render/sync); it's never read back in, so a hand edit is only ever a mistake db check flags. The GitHub token comes from MindAttic.Vault (bucket GitHub, key github), the same one the Launcher's roster filter uses. The library has no package dependencies: the CLI (and the Launcher) read the token and pass it in.
src/MindAttic.Tickets/ library (packed to C:\LocalNuGet)
Data/ TicketsDb (schema, import/export, tickets, stories, links, history, the ticket queue, sync-commit subjects)
Stories/ StoryDocument (parses a USER_STORIES.md into ordered blocks)
Tickets/ Ticket, TicketRules, StoryFile, WorkspaceTickets (the markdown fallback, pre-migration)
Repos/ RepoStatus, GitHubRepoIndex, DependencyScan, PrunePlanner
Git.cs, Workspace.cs
src/MindAttic.Tickets.Cli/ the tickets exe (Spectre.Console.Cli)
src/MindAttic.Tickets.Desktop/ Tickets Desktop, a WPF ticket app (net10.0-windows, MindAttic.Components.Wpf)
tests/MindAttic.Tickets.Tests/ NUnit 4
tests/MindAttic.Tickets.Desktop.Tests/ NUnit 4: Tickets Desktop's view model and store against a temporary database
tools/codex.ps1 Codex doctor + digest
tools/install.ps1 packs the library and CLI and installs `tickets` as a global tool
run.ps1 publishes Tickets Desktop and (re)creates its shortcuts
dotnet build MindAttic.Tickets.slnx # TreatWarningsAsErrors, Nullable enabled; also builds Tickets Desktop (Windows)
dotnet test MindAttic.Tickets.slnx
powershell -File tools/codex.ps1 doctor # docs canon check
The repo-level tests run real git against temporary repos; nothing touches the real workspace.
Install the CLI as a global tickets tool with powershell -File tools/install.ps1 (packs the library and CLI to
C:\LocalNuGet and installs or updates the tool from there). Publish and install Tickets Desktop, with its Desktop
and Start-menu shortcuts, with powershell -File run.ps1 (add -Launch to open it when done).
D:\Projects\MindAttic, the CLI is built and tested on Windows, and Tickets Desktop (WPF, net10.0-windows) only runs on Windows at all.NO_COLOR; story list wraps rather than truncating in a narrow terminal. See the Priority backlog in docs/USER_STORIES.md for these and other open gaps (restoring the db from its dump, keeping data/Tickets.db out of ordinary feature commits, concurrent writers).tickets view works and why it's a static snapshot.No LICENSE file; all rights reserved.
Part of MindAttic — see more projects at github.com/mindattic. Related: MindAttic.Launcher (workspace launcher) and MindAttic.Vault (credential store).
> lists commands only, # tickets and stories only). Up/Down choose and Enter runs without leaving the box; a screen reader hears the result count and the selected entry as they change. A story opens with its text and links, and any linked ticket opens from there.tickets db sync and shows the result; F5 refreshes.MindAttic.Tickets.Desktop.exe --root <dir> --ticket <ID> opens on that ticket, selected with its detail pane open (an open one in the Queue, to approve, move or close; a closed one in Repos). Started again while the window is open, it hands the id to that window and brings it forward. The Orchestrator dashboard's ticket links start it this way.run.ps1 publishes it as a self-contained exe to C:\Apps\MindAttic.Tickets.Desktop with Desktop and Start-menu shortcuts (and reinstalls the tickets CLI alongside it, via tools/install.ps1, unless -SkipCli). The shortcuts open the install folder's run.bat, which asks first: 1) Deploy & Run republishes (-Republish) and opens the app; 2) Run just opens the installed app. run.ps1 -LauncherOnly rewrites that launcher and the shortcuts without building anything.