feat: implement the wiki field in the issue domain
format.md listed `wiki:` among the domain fields, between depends and origin, and issue.py had never heard of it. The field fell into extra and rendered with the foreign keys — sorted in after the sync fields, which the same document forbids one line below the table. Written without brackets it parsed as a single string, and nothing but a text editor could set it. Implemented rather than de-documented: page_ls.py --titles already prints these titles, so the field was designed and only unwired. DOMAIN_KEYS and LIST_KEYS learn it, Issue carries it, and issue_new.py gets a repeatable --wiki flag. Titles only, as the format says: no path, no sub_url, no lookup. The tracker has no field for it, so it is never sent and a pull does not bring it back — format.md now says so. Closes #32 Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
This commit is contained in:
@@ -64,7 +64,7 @@ url: https://git.noodles.cam/claude-skills/tea/issues/42
|
||||
| `assignees` | domain | logins; may be empty |
|
||||
| `milestone` | domain | title, or `none` |
|
||||
| `depends` | domain | ids this issue depends on — **the authoritative graph** |
|
||||
| `wiki` | domain | page **titles** this issue is written up in; may be empty. Titles, not URLs — a title is a name for a document and stays in this layer, a URL is tracker bookkeeping. `/tea:page` owns what those titles mean; `page_ls.py --titles` prints them |
|
||||
| `wiki` | domain | page **titles** this issue is written up in; may be empty. Titles, not URLs — a title is a name for a document and stays in this layer, a URL is tracker bookkeeping. `/tea:page` owns what those titles mean; `page_ls.py --titles` prints them. Set it with `issue_new.py --wiki "<title>"` (repeatable) or by editing the line. The tracker has no field for it, so it is never sent — and a pull, which merges nothing but checkbox state, does not bring it back |
|
||||
| `origin` | domain | `local`, or the name of a tracker this also lives in |
|
||||
| `gitea` | sync | the handle in that tracker: `owner/repo#N` |
|
||||
| `branch` | sync | the tracker's branch link (Gitea `ref`); push fills an empty one with the current git branch, and never overwrites a filled one |
|
||||
|
||||
@@ -25,6 +25,7 @@ domain has. The file name is the id:
|
||||
assignees: [naudachu]
|
||||
milestone: v0.2
|
||||
depends: [migrate-schema]
|
||||
wiki: [Simple Chains/Ideas/Chain core]
|
||||
origin: gitea
|
||||
gitea: owner/repo#42
|
||||
synced: 2026-08-07T18:40:00Z
|
||||
@@ -113,8 +114,9 @@ ISSUE_ROOT = store_root()
|
||||
|
||||
# Domain-owned metadata, in render order. Foreign keys render after these,
|
||||
# sorted, so the sync layer can add fields without touching this list.
|
||||
DOMAIN_KEYS = ["id", "state", "labels", "assignees", "milestone", "depends", "origin"]
|
||||
LIST_KEYS = {"labels", "assignees", "depends"}
|
||||
DOMAIN_KEYS = ["id", "state", "labels", "assignees", "milestone", "depends",
|
||||
"wiki", "origin"]
|
||||
LIST_KEYS = {"labels", "assignees", "depends", "wiki"}
|
||||
STATES = ("open", "closed")
|
||||
|
||||
# `origin` is "does this issue exist anywhere but here" — a fact about the
|
||||
@@ -247,8 +249,8 @@ class Issue(object):
|
||||
"""One unit of work. `extra` holds metadata this layer does not own."""
|
||||
|
||||
def __init__(self, id="", title="", body="", state="open", labels=None,
|
||||
assignees=None, milestone="", depends=None, origin=LOCAL,
|
||||
extra=None):
|
||||
assignees=None, milestone="", depends=None, wiki=None,
|
||||
origin=LOCAL, extra=None):
|
||||
self.id = id
|
||||
self.title = title
|
||||
self.body = body
|
||||
@@ -257,6 +259,10 @@ class Issue(object):
|
||||
self.assignees = list(assignees or [])
|
||||
self.milestone = milestone or ""
|
||||
self.depends = list(depends or [])
|
||||
# Page TITLES this work is written up in — names for documents, which
|
||||
# is why they are domain-owned. What a title resolves to is /tea:page's
|
||||
# business, and this layer never asks: no path, no URL, no lookup.
|
||||
self.wiki = list(wiki or [])
|
||||
self.origin = origin or LOCAL
|
||||
self.extra = dict(extra or {})
|
||||
|
||||
@@ -302,7 +308,7 @@ class Issue(object):
|
||||
state=meta.get("state") or "open",
|
||||
labels=lst("labels"), assignees=lst("assignees"),
|
||||
milestone="" if ms == "none" else ms,
|
||||
depends=lst("depends"),
|
||||
depends=lst("depends"), wiki=lst("wiki"),
|
||||
origin=meta.get("origin") or LOCAL, extra=extra)
|
||||
|
||||
def to_text(self):
|
||||
@@ -314,6 +320,7 @@ class Issue(object):
|
||||
"assignees": self.assignees,
|
||||
"milestone": self.milestone or "none",
|
||||
"depends": self.depends,
|
||||
"wiki": self.wiki,
|
||||
"origin": self.origin,
|
||||
})
|
||||
body = self.body.strip() or "(no body)"
|
||||
|
||||
@@ -155,6 +155,8 @@ def main():
|
||||
ap.add_argument("--assignee", action="append", default=[], help="assignee; repeat")
|
||||
ap.add_argument("--depends", action="append", default=[],
|
||||
help="id this issue depends on; repeat")
|
||||
ap.add_argument("--wiki", action="append", default=[],
|
||||
help="page title this work is written up in; repeat")
|
||||
ap.add_argument("--out", default=issue.ISSUE_ROOT,
|
||||
help="store root (default: <repo>/tmp/issues)")
|
||||
args = ap.parse_args()
|
||||
@@ -180,7 +182,7 @@ def main():
|
||||
id=id, title=args.title,
|
||||
body=with_depends(TEMPLATES[args.type], args.depends),
|
||||
labels=labels, assignees=args.assignee, milestone=args.milestone,
|
||||
depends=args.depends)
|
||||
depends=args.depends, wiki=args.wiki)
|
||||
|
||||
# The first issue in a fresh checkout has to create the store, but it says
|
||||
# so — and it says where, because the path is absolute.
|
||||
|
||||
Reference in New Issue
Block a user