Compare commits

..

No commits in common. "main" and "entomologist-data" have entirely different histories.

312 changed files with 1433 additions and 2699 deletions

2
.gitignore vendored
View file

@ -1,2 +0,0 @@
/target
Cargo.lock

View file

@ -0,0 +1,13 @@
add an option to `ent list` to show just the ids of filtered issues
This would be useful in scripts, like:
```
for ISSUE_ID in $(ent list --ids-only ${MY_FILTER}); do
# do thing with ${ISSUE_ID}
done
```
For now you can sort of emulate this with:
```
ent list state=done done-time=2026-01-01T00:00:00-06:00.. | grep ' ' | cut -f 1 -d ' '
```

View file

@ -0,0 +1 @@
backlog

View file

@ -0,0 +1 @@
Allow issues to move within collections.

View file

@ -0,0 +1,11 @@
collections
introduce a new data structure - a "collection".
a collection is a grouping of:
1. ent repositories
2. other collections
a collection is defined by some user-producible, machine readable file (maybe a TOML or something similar) and points to:
1. locations of other ent repositories (local or remote)
2. locations of other collection files (local or remote)

View file

@ -0,0 +1 @@
feature

View file

@ -0,0 +1 @@
seb

View file

@ -1,19 +1,14 @@
#!/bin/bash
#
# This script finds all issues with state=Done which do not have a
# `done_time`.
#
# It sets each issue's `done_time` to the most recent time that the
# `state` was updated from the git log.
#
The done-time thing is implemented and merged, but many issues in our
database were marked Done before this change, so they have no `done_time`.
I fixed this by setting a done-time for each of them using this script:
```
#!/bin/bash
set -e
for ISSUE_ID in $(ent list state=done done-time=9999-01-01T00:00:00-06:00.. | grep ' ' | cut -f 1 -d ' '); do
echo ${ISSUE_ID}
UTIME=$(PAGER='' git log -n1 --pretty=format:%at%n entomologist-data -- ${ISSUE_ID}/state)
echo ${UTIME}
DATETIME=$(date --rfc-3339=seconds --date="@${UTIME}")
echo ${DATETIME}
ent done-time ${ISSUE_ID} "${DATETIME}"
done
```

View file

@ -0,0 +1,26 @@
maybe there's a delineation that's starting to be drawn here between an "issue" and what the database on the backend uses.
for the filesystem DB, i think it might make sense to have a hashmap that stores everything as a key-value pair, where each key is a file, and each value is the contents of that file.
once we go up the stack, i think it makes sense to have things in concrete structs, since that's easier to reason about.
this also frees up the filesystem DB to get used for other things potentially, not just issues.
so you'd have a system where
```
filesystem
^
|
v
db layer: key/value pair
^
|
v
application layer: concrete structs (like `Issue` etc)
^
|
v
presentation layer: (CLI / TUI / etc.)
```

View file

@ -0,0 +1,5 @@
Or maybe things that required special handling in the code should live
directly as fields in the Issue struct? With their own getter/setter
API & CLI?
Not sure what's cleaner.

View file

@ -0,0 +1,44 @@
I like the idea of a layered architecture, with a db layer that manages
filesystem i/o.
# API
* Read a filesystem object into a struct Issue (e.g. `ent show`)
* Write a whole struct Issue into a filesystem object (e.g. `ent new`
or `ent comment`).
* Write a single field from a struct Issue into an existing filesystem
object (e.g. `ent state ISSUE Done`).
On write operations, the git commit message should be meaningful to
the application. Maybe that can be done generically by the db library,
or maybe the application needs to supply the commit message.
# Design
A filesystem stores two kinds of things: directories and files.
A directory contains files, and other directories.
Git stores two kinds of things: trees and blobs. Trees contain blobs,
and other trees.
Maybe this DB tracks two kinds of things: databases and key/value objects.
Databases store key/value objects, and other databases.
Some things we'd want from this DB layer:
* Filesystem objects correspond to structs, like how we have each struct
Issue in its own issue directory.
* Structs are nested, like how struct Issue contains struct Comment
* Some fields are simple types (`author` is String), some are
less simple (`timestamp` is chrono::DateTime), some are custom
(`state` is enum State), and some are complicated (`dependencies`
is Option<Vec<IssueHandle>>, `comments` is Vec<Comment>)
* Filesystem objects are optimized for getting tracked by git - minimize
merge conflicts.

View file

@ -0,0 +1,38 @@
The normal `date` command is helpful here:
```
$ date --iso-8601=seconds
2025-07-19T12:22:56-06:00
$ date --iso-8601=seconds --date='last monday'
2025-07-14T00:00:00-06:00
$ date --iso-8601=seconds --date='last monday - 1 week'
2025-07-07T00:00:00-06:00
```
Given that, here's a "what did we finish last week" command:
```
$ ent list state=done done-time=$(date --iso-8601=seconds --date='last monday - 1 week')..$(date --iso-8601=seconds --date='last monday')
failed to parse issue 87fa3146b90db61c4ea0de182798a0e5, skipping
ignoring error: StdIoError(Os { code: 21, kind: IsADirectory, message: "Is a directory" })
Done:
8c73c9fd5bc4f551ee5069035ae6e866 migrate the Todo list into entomologist
75cefad80aacbf23fc7b9c24a75aa236 🗨️ 4 # implement `ent comment ISSUE [DESCRIPTION]` (👉 seb)
7da3bd5b72de0a05936b094db5d24304 🗨️ 1 implement `ent edit ${COMMENT}` (👉 seb)
198a7d56a19f0579fbc04f2ee9cc234f fix ignoring unknown file in issues directory: "README.md"
e089400e8a9e11fe9bf10d50b2f889d7 add `ent sync` to keep local `entomologist-data` branch in sync with remote
a26da230276d317e85f9fcca41c19d2e `ent edit ${ISSUE}` with no change fails (👉 seb)
317ea8ccac1d414cde55771321bdec30 🗨️ 2 allow multiple read-only ent processes simultaneously (👉 seb)
da435e5e298b28dc223f9dcfe62a9140 add user control over state transitions (👉 lex)
fd81241f795333b64e7911cfb1b57c8f commit messages in the `entomologist-data` branch could be better (👉 seb)
093e87e8049b93bfa2d8fcd544cae75f add optional 'assignee' to issue (👉 seb)
793bda8b9726b0336d97e856895907f8 `ent list` should have a consistent sort order (👉 seb)
af53c561b36e9b2709b939f81daee534 use git author info to attribute issues and comments to people (👉 seb)
9e69a30ad6965d7488514584c97ac63c teach `ent list FILTER` to filter by assignee (👉 seb)
a5ac277614ea4d13f78031abb25ea7d6 `ent new` and `ent comment`: detect empty issue descriptions & comments (👉 seb)
7d2d236668872cf11f167ac0462f8751 🗨️ 1 add `ent tag ISSUE [[-]TAG]` (👉 seb)
54f0eb67b05aa10763c86869ce840f33 `ent sync` should report what changes got fetched & what changes will be pushed (👉 seb)
4e314a8590864fa76d22758e1785ae35 don't spawn an editor if stdin & stdout aren't a terminal (👉 seb)
d3a705245bd69aa56524b80b5ae0bc26 🗨️ 1 move IssuesDatabase out of binary and into library (👉 sigil-03)
```

View file

@ -0,0 +1,17 @@
I'm liking the idea of a per-issue key/value store.
I think keys and values are both strings, with possible further
parsing/interpretation for some keys?
For the application in this issue we'd teach ent to create a "finished"
key, maybe when setting the state to Done, with a value of an
ISO8601-style datetime stamp (e.g. "2025-07-12T15:08:58-06:00").
There would be a documented spec of reserved keys and their special
meanings and handling.
Full user access via CLI, maybe something like `ent get VARIABLE` and
`ent set VARIABLE VALUE`? Or `ent variable [NAME[=VALUE]]`?
Or maybe merge this with the tags somehow? Would that be simpler,
or more complicated (for the user)?

View file

@ -0,0 +1,77 @@
figure out how to make useful reports
In task-warrior we had a pair of custom reports, one to list things we
did last week and another to list things we were planning to do this
coming week.
Docs here:
* custom reports: <https://taskwarrior.org/docs/report/#custom-reports>
* end date (brief): <https://taskwarrior.org/docs/using_dates/#other-dates>
# Done last week
> report.weekly.prev.description='Tasks Completed Last Week'
> report.weekly.prev.columns=uuid,description.desc,project,assignee,end
> report.weekly.prev.sort=end+
> report.weekly.prev.filter=+COMPLETED and -hidden and (end.after=sow - 1 week) and (end.by=eow - 1 week)
The "done last week" report filters on a column called `end`, which is
a datetime made up by tw indicating when the ticket became COMPLETED.
# To do this week
> report.selected.external.description='Tasks Selected for This Week'
> report.selected.external.columns=project,description.desc,assignee,due
> report.selected.external.sort=assignee+/,urgency-
> report.selected.external.filter=-COMPLETED and -internal and -hidden and (due.by=eow or +selected or +interrupt)
The "to do this week" report looks for the tags "selected" or "interrupt",
or a due date this week.
# What is to be done
## Done last week
I can imagine finding the issues with state=done, running `git log` on
their state file, finding the datetime of the transition to done, and
selecting the ones where that datetime is in a particular time window.
This has the drawback that it's hard to lie about... With taskwarrior
I often found myself finishing a task on Week X, but forgetting to mark
it complete. Then the Monday of Week X+1 i would mark it complete.
If i didn't override the completion-date the task would look like it
was completed on Week X+1, not Week X like i wanted.
In git we have `git commit --date=DATE`, but that's only usable at
commit-time (and awkward to express to ent). We can rewrite history with
`git rebase`, but only until we `ent sync`.
Maybe the `state` file should have a date in it, in addition to the
state word? Or maybe `completion-date` should be a key in a per-issue
key-value store? Is that kv store related to tags? Idk...
Not sure how to express to ent what completion-dates i want to see.
Maybe a new filter type? `ent list finished=2025-07-01..now`?
Maybe we can use git tags in the entomologist-data branch somehow?
`git log` between tags and look for "state: _ -> done". But how to
position the tags on the commits i want? Seems cumbersome.
## To do this week
entomologist doesn't have due dates yet, but we should probably add that.
entomologist has tags so it's be easy to list "tags=selected,interrupt".
Or maybe we should just use "state=inprogress"?
## Misc thoughts
It's nice that we can add whatever files we want to the
`entomologist-data` branch. We could add a directory of report
definitions, and have them be shared across the project, and not have
to type them out every time.

View file

@ -0,0 +1 @@
2025-07-19T20:31:35.010603718-06:00

View file

@ -0,0 +1 @@
done

View file

@ -0,0 +1 @@
seb

View file

@ -0,0 +1,7 @@
add optional 'assignee' to issue
This is probably just another free-form text string for now, maybe
something fancier in the future.
NOTE: Teaching `ent list FILTER` to filter by assignee is a separate
issue.

View file

@ -0,0 +1 @@
2025-07-08T18:48:13-06:00

View file

@ -0,0 +1 @@
done

View file

@ -0,0 +1,17 @@
we need some way to search the text of issues and comments
Is this a normal filter? Maybe `ent list text=REGEX`?
Or maybe we want more detailed output than just a list? Showing the
actual Issue or Comment that matches. Maybe `ent search REGEX` producing
something like:
```
$ ent search REGEX
issue: issue1
blah blah
issue: issue2
blah
comment 1
comment 2
```

View file

@ -0,0 +1 @@
backlog

View file

@ -0,0 +1,15 @@
teach `ent sync` to scan `main` branch commits for special commands
I'm thinking primarily of "Fixes: abc123" but maybe there are others?
ent could be informed of the main branch name via
entomologist-data:config.toml, and use a special tag pointing at the
most recent commit in that branch that it has processed. When you run
`ent sync`, after it runs `git fetch` it could log the main branch from
its tagged commit to the just-fetched branch head, read all the commit
messages, and find and process all the ent commands. Then finally move
its tag to the new main branch head.
This way you could put an ent command like "Fixes: abc123" in a bugfix
commit, and after you merge that branch to main, the next ent sync will
mark issue abc123 as done for you.

View file

@ -0,0 +1 @@
backlog

View file

@ -0,0 +1,8 @@
fix ignoring unknown file in issues directory: "README.md"
ignoring unknown file in issues directory: ".git"
b738f2842db428df1b4aad0192a7f36c write a manpage (New)
75cefad80aacbf23fc7b9c24a75aa236 # implement `ent comment ${ISSUE} [-m ${MESSAGE}]` (New)
7da3bd5b72de0a05936b094db5d24304 implement `ent edit ${COMMENT}` (New)
1f85dfac686d5ea2417b2b07f7e1ff01 # implement `ent attach ${ISSUE} ${FILE}` (New)
da435e5e298b28dc223f9dcfe62a914 add user control over state transitions (New)
8c73c9fd5bc4f551ee5069035ae6e866 migrate the Todo list into entomologist (New) emitting warnings for unknown files

View file

@ -0,0 +1 @@
2025-07-07T16:49:13-06:00

View file

@ -0,0 +1 @@
done

View file

@ -0,0 +1 @@
add get() and get_mut() API to database

View file

@ -0,0 +1 @@
backlog

View file

@ -0,0 +1 @@
db

View file

@ -0,0 +1 @@
03

View file

@ -0,0 +1 @@
add delete subcommand to delete ENTries (heh)

View file

@ -0,0 +1 @@
backlog

View file

@ -0,0 +1 @@
sigil-03

View file

@ -0,0 +1 @@
will need an attachments manager, since we probably want to be passing around handles and not actual file data... unless we move the struct remotely? will have to think about it

View file

@ -0,0 +1,4 @@
# implement `ent attach ${ISSUE} ${FILE}`
- each issue has its own independent namespace for attached files
- issue description & comments can reference attached files via standard md links

View file

@ -0,0 +1 @@
inprogress

View file

@ -0,0 +1 @@
feature

View file

@ -0,0 +1,8 @@
Oops, i stupidly ran: ent new "add `ent sync --dry-run`"
Because i used double-quotes, bash saw the `...` and ran that as a
command, which failed, but then bash ran the result anyway ("ent new
"add "), and here we are.
This would be a good time for `ent rm` as suggested by issue
1ebdee0502937bf934bb0d72256dbdd1.

View file

@ -0,0 +1 @@
add

View file

@ -0,0 +1 @@
wontdo

View file

@ -0,0 +1 @@
seb

View file

@ -0,0 +1 @@
`ent assign` and maybe other commands needlessly read the database twice

View file

@ -0,0 +1 @@
2025-07-22T20:37:03.829541278-06:00

View file

@ -0,0 +1 @@
done

View file

@ -0,0 +1 @@
perf

View file

@ -0,0 +1 @@
seb

View file

@ -0,0 +1,5 @@
It's easy to make worktrees with detached heads:
```
$ git worktree add --detach /tmp/ent1 entomologist-data
$ git worktree add --detach /tmp/ent2 entomologist-data
```

View file

@ -0,0 +1,4 @@
Currently the `ent` program makes a worktree before considering what
command it's supposed to run. Which is nice because it simplifies each
command handler, but it's bad because different command handlers will
want different kinds of worktrees to implement this issue.

View file

@ -0,0 +1,15 @@
allow multiple read-only ent processes simultaneously
Currently every time `ent` makes a worktree to read its issues database
branch, it checks out the local branch `entomologist-data`. This means
only one worktree can exist at a time, because each branch can only be
checked out into at most one worktree.
Some ent operations are read-only which means we could `git worktree
add --detached` the `entomologist-data` branch instead, which uses a
detached HEAD checkout, which is sufficient for read-only operations like
`ent list` and `ent show`.
This would be useful if you're sitting in `ent edit ${ISSUE_1}` and want
to look at another issue with `ent show ${ISSUE_2}` or list the issues
with `ent list`.

View file

@ -0,0 +1 @@
2025-07-11T11:54:56-06:00

View file

@ -0,0 +1 @@
done

View file

@ -0,0 +1 @@
sigil-03

View file

@ -0,0 +1,3 @@
include issue ID in the issue
currently the issue ID is not contained by the issue data structure. update the issue data structure so it contains the issue ID.

View file

@ -0,0 +1 @@
2025-07-18T16:26:06.414392436-06:00

View file

@ -0,0 +1 @@
done

View file

@ -0,0 +1,20 @@
put ent issue database in a dir in the main branches?
Currently entomologist can access an issue database in a branch (via
temporary worktrees), or in a directory (via direct access).
The directory-based issue database mode is kind of broken, because
entomologist blindly runs `git commit` after modifying the database
(and isn't careful about managing the git index when doing so).
(Tangent: The IssueDatabase and IssueDatabaseSource structs of the `ent`
binary should maybe move into the lib Issues struct, and the code could
make smarter choices about how to access the database.)
Putting the entomologist issue database in the main branch(es) of the
repo has some appealing qualities. For example, a bug-fix branch could
both fix the bug in the code, and change the bug's issue status from
"InProgress" to "Done", so that when the branch is merged to main,
the bug gets fixed there.
The branch can be rebased on top of main to pick up changes to the bug.

View file

@ -0,0 +1 @@
backlog

View file

@ -0,0 +1 @@
seb

View file

@ -0,0 +1,18 @@
I added a simple performance-measuring tool, `tools/time-ent`. It runs
ent a couple of different ways, against a known entomologist-data branch
(specified by a commit in the regular entomologist-data branch in this
repo). That script gives a rough, over-all measurement of how long
different ent commands take.
More detailed information, including the call tree and flame graph,
can be gathered like this:
```
$ perf record -g -F 999 ent tag 7e2a3a59fb6b77403ff1035255367607
$ perf script -F +pid > /tmp/test.perf
```
Then upload the `test.perf` file to the firefox visualizer at
<https://profiler.firefox.com/>.
A local visualizer would be nice, i'm sure there is one somewhere.

View file

@ -0,0 +1 @@
profile ent to determine where slowdowns occur

View file

@ -0,0 +1 @@
2025-07-22T20:47:14.363750382-06:00

View file

@ -0,0 +1 @@
done

View file

@ -0,0 +1,2 @@
debug
perf

View file

@ -0,0 +1,10 @@
Yeah that red blob 🛑 is super heavy, and the octagonal shape is pretty
subtle - it looks more like a stop light than a stop sign.
I like your thought of somehow showing the state of the issues we
dependend on... How about showing the count of not-Done dependencies?
And once all the dependencies are Done, not showing the ↖ or ⌛ or
whatever at all.
In the `ent show` output we could list all dependencies with a ↖ or
⌛ for the not-Done ones and a ✅ for the Done ones.

View file

@ -0,0 +1,3 @@
stop sign is an interesting thought, does definitely represent that the issue is blocked... although it feels like a very visually heavy emoji to use, and if we use a color to represent issue state later on Stop Sign is similar to Red Circle and might get visually confusing.
and yeah, that's exactly what i'm envisioning - i'd like to be able to see at a glance that an issue has dependencies. it might be nice to see the state of those dependencies? but that starts to feel off in the weeds. for now just seeing the count would be nice i think.

View file

@ -0,0 +1 @@
i think my preference is ↖ since it more concisely represents that this issue is waiting on other issues in the DAG / flow...

View file

@ -0,0 +1,10 @@
Of the three options you suggested i like "Hourglass Not Done" (⏳)
best, because it most clearly shows that we're waiting for something.
Or how about Stop Sign, 🛑?
Do you want `ent list` to show the number of issues that this issue is
blocked waiting on? Something like:
012345 This issues stands alone
abc123 ⏳4 This other issue depends on four things

View file

@ -0,0 +1,8 @@
add dependency count to `ent list`
candidate emojis:
↖ - represents the "dependency tree" DAG edge that points to this issue
⌛- shows that the issue is waiting on something else
🔗- shows that the issue is linked to something else

View file

@ -0,0 +1 @@
backlog

View file

@ -0,0 +1 @@
seb

View file

@ -0,0 +1,8 @@
don't spawn an editor if stdin & stdout aren't a terminal
I sometimes run `ent show ISSUE | more` because ISSUE doesn't fit on my
screen and we don't have built-in pager support yet.
Then i see something i want to change, or i want to add a comment, so
i up-arrow in the shell and change `show` to `edit` or `comment`, and
ent opens what is in effect `vi | more` which isn't what i want at all.

View file

@ -0,0 +1 @@
2025-07-13T10:39:17-06:00

View file

@ -0,0 +1 @@
done

View file

@ -0,0 +1 @@
seb

View file

@ -0,0 +1,7 @@
i have some work which might take care of this which is happening here:
entomologist:cffd805252f9a2b4373abf7852d9e750
this creates a new type Entry<T>, which has the basic author / creation-time / id as files, and then stores T in the filesystem however it likes to be stored.
it's still a ways off, but maybe it's worth waiting for so we don't have duplicate work? and for now we can just live with the git log penalty.

View file

@ -0,0 +1 @@
store Author and Creation-time of Issue & Comment as files, don't run `git log`

View file

@ -0,0 +1 @@
inprogress

View file

@ -0,0 +1 @@
perf

View file

@ -0,0 +1,8 @@
We can determine something like an "mtime" for an Issue by running a
command like:
`git log --pretty=format:%ai --max-count 1 entomologist-data -- ${ISSUE_ID}`
Running it on `${ISSUE_ID}/comments` gives you the most recent time
there was a commit in the comments directory, indicating a new or
edited comment.

View file

@ -0,0 +1 @@
filter issues with comment activity in a particular timeframe

View file

@ -0,0 +1 @@
backlog

View file

@ -0,0 +1 @@
seb

View file

@ -0,0 +1,19 @@
`ent sync` should report what changes got fetched & what changes will be pushed
Currently `ent sync` does:
1. `git fetch origin`
2. `git merge origin/entomologist-data`
3. `git push origin entomologist-data`
I think after (1), before (2), we can do some easy, partially useful things:
1. Show what we have locally that's not on the remote yet:
`git log -p entomologist-data ^origin/entomologist-data`
2. Show what the remote has that we don't have locally:
`git log -p origin/entomologist-data ^entomologist-data `
Eventually (maybe after issue 5fe71e27727f4243dc997e63b9a02971 and/or
issue fd81241f795333b64e7911cfb1b57c8f) we can display the changes in
a simpler way.

View file

@ -0,0 +1 @@
2025-07-11T20:32:59-06:00

View file

@ -0,0 +1 @@
done

View file

@ -0,0 +1 @@
sigil-03

View file

@ -0,0 +1,5 @@
have initial rough copy of the TUI binary. i had initially started developing it as a standalone application but then decided it would be better to include it as part of the entomologist repository.
currently the TUI can only list issues and show a preview, and scaling is broken.
i also need to update it so that the widget implementations are done as part of the library instead of using the horrible, cursed wrappers that are currently around the types... (since it was a seperate binary, and the trait was from a different crate and the type was from a different crate, rust won't let you `impl` a trait)

View file

@ -0,0 +1,14 @@
TUI v0.1
build a TUI binary for ent which mirrors the CLI functionality
- [ ] issues list (88d5111fd6e59802d0b839ff1fd6bf71)
- [ ] filtering(?)
- [ ] show issue preview (bd00a62f9d7c77fd8dd0da5d20aa803d)
- [ ] show issue detail
- [ ] show issue comments
- [ ] commands
- [ ] new ($EDITOR)
- [ ] edit ($EDITOR)
- [ ] comment ($EDITOR)
- [ ] state

View file

@ -0,0 +1 @@
backlog

View file

@ -0,0 +1,2 @@
tui
tui/v0.1

View file

@ -0,0 +1,3 @@
yeah exactly that. just a convenience thing to be able to (from any directory) run `ent update`.
i could just make it an alias as well... not sure which is more idiomatic

View file

@ -0,0 +1,3 @@
What do you mean by ent updating itself?
Do you mean it git clones itself and cargo builds and installs itself?

View file

@ -0,0 +1,3 @@
add `ent update`
allow `ent` to update itself when commanded to

View file

@ -0,0 +1,7 @@
add a way to see how an issue has changed over time
Maybe `ent log ISSUE` (and `ent log COMMENT`)?
This could be a thinly veiled wrapper around:
`git log entomologist-data -- ISSUE`

View file

@ -0,0 +1 @@
backlog

View file

@ -0,0 +1,5 @@
refactor IssuesDatabaseSource / IssuesDatabase / Issues
If feels like there's a lot of overlap and intimate sharing of
responsibility among these three, and i'm not sure we have the best
abstraction to describe it.

View file

@ -0,0 +1 @@
backlog

View file

@ -0,0 +1,7 @@
add `ent modify ISSUE CHANGE...`
CHANGE is one or more changes to make to the issue, that looks a bit
like the FILTER of `ent list`. Something like:
```
$ ent modify 123abc state=inprogress assignee=seb tag=bug,cli
```

View file

@ -0,0 +1 @@
backlog

Some files were not shown because too many files have changed in this diff Show more