gemba-cli 0.1.0__py3-none-any.whl
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- gemba/__init__.py +1 -0
- gemba/assets/harness/guide.md +88 -0
- gemba/assets/init/gemba.yaml +12 -0
- gemba/assets/skills/gemba-archive/SKILL.md +78 -0
- gemba/assets/skills/gemba-config/SKILL.md +176 -0
- gemba/assets/skills/gemba-create/SKILL.md +99 -0
- gemba/assets/skills/gemba-harness/SKILL.md +194 -0
- gemba/assets/skills/gemba-init/SKILL.md +81 -0
- gemba/assets/skills/gemba-list/SKILL.md +137 -0
- gemba/assets/skills/gemba-mark/SKILL.md +88 -0
- gemba/assets/skills/gemba-record/SKILL.md +89 -0
- gemba/assets/skills/gemba-report/SKILL.md +149 -0
- gemba/assets/skills/gemba-set/SKILL.md +104 -0
- gemba/assets/skills/gemba-worktree/SKILL.md +137 -0
- gemba/cli.py +35 -0
- gemba/commands/__init__.py +1 -0
- gemba/commands/archive.py +62 -0
- gemba/commands/config.py +117 -0
- gemba/commands/create.py +104 -0
- gemba/commands/harness.py +534 -0
- gemba/commands/init.py +112 -0
- gemba/commands/list.py +51 -0
- gemba/commands/mark.py +91 -0
- gemba/commands/record.py +113 -0
- gemba/commands/report.py +80 -0
- gemba/commands/selection.py +170 -0
- gemba/commands/set.py +81 -0
- gemba/commands/skills.py +102 -0
- gemba/commands/worktree.py +292 -0
- gemba/config.py +371 -0
- gemba/harness.py +401 -0
- gemba/metadata.py +442 -0
- gemba/repo.py +76 -0
- gemba/report.py +153 -0
- gemba/skills.py +199 -0
- gemba/tasks.py +621 -0
- gemba/values.py +16 -0
- gemba/worktree.py +191 -0
- gemba_cli-0.1.0.dist-info/METADATA +321 -0
- gemba_cli-0.1.0.dist-info/RECORD +43 -0
- gemba_cli-0.1.0.dist-info/WHEEL +4 -0
- gemba_cli-0.1.0.dist-info/entry_points.txt +2 -0
- gemba_cli-0.1.0.dist-info/licenses/LICENSE +21 -0
|
@@ -0,0 +1,81 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: gemba-init
|
|
3
|
+
description: Configure gemba for the first time in a tasks repo that gemba init just created, through a guided interview, one question at a time. Use whenever the user asks to configure gemba, set up gemba, do the first configuration, or customize this tasks repo for their work, right after gemba init.
|
|
4
|
+
---
|
|
5
|
+
|
|
6
|
+
# Configure a new tasks repo
|
|
7
|
+
|
|
8
|
+
`gemba init` writes a tasks repo that every command accepts, with a minimal
|
|
9
|
+
`gemba.yaml`: one workstream, `default`, and every agent provider the CLI knows. This
|
|
10
|
+
skill turns that scaffold into the config of the person's own work, once, by asking
|
|
11
|
+
what only they know. Your part is to ask one question at a time, propose the values
|
|
12
|
+
from the answers, and hand the edit over to the `gemba-config` skill, which holds the
|
|
13
|
+
reference of every key and the process to edit, check and refresh.
|
|
14
|
+
|
|
15
|
+
## Prerequisite
|
|
16
|
+
|
|
17
|
+
The `gemba` command must be on the PATH. It is installed once from PyPI with
|
|
18
|
+
`uv tool install gemba-cli` and checked with `gemba --version`. If `gemba` is not
|
|
19
|
+
found, stop and tell the user to install it with that command.
|
|
20
|
+
|
|
21
|
+
Run `gemba config show`. This skill is for a tasks repo whose config still holds the
|
|
22
|
+
`default` workstream of the scaffold. When the command finds no config, tell the user
|
|
23
|
+
to run `gemba init` first. When the config holds no `default` workstream, it has been
|
|
24
|
+
configured already: follow the `gemba-config` skill instead.
|
|
25
|
+
|
|
26
|
+
## Process
|
|
27
|
+
|
|
28
|
+
Ask the questions below in this order, one per message, and skip any the user already
|
|
29
|
+
answered. Propose a value from each answer and let the user confirm or change it; never
|
|
30
|
+
fill a value the user did not give or confirm.
|
|
31
|
+
|
|
32
|
+
1. **The organization.** Ask for the name of the organization the work is done for or
|
|
33
|
+
in. Propose `organization` from it: kebab-case, lowercase letters, digits and single
|
|
34
|
+
hyphens. It names the branches of the runs.
|
|
35
|
+
2. **The kinds of work.** Ask what kinds of work the person does. Propose one workstream
|
|
36
|
+
per kind, each with:
|
|
37
|
+
- an identifier, kebab-case;
|
|
38
|
+
- a prefix of uppercase ASCII letters, short and used by no other workstream: the
|
|
39
|
+
refs of its tasks read `<prefix>-<N>`;
|
|
40
|
+
- a description that lets an agent tell which work belongs there and which does not,
|
|
41
|
+
since agents choose the workstream of a new task by it.
|
|
42
|
+
3. **The default workstream.** Ask which workstream takes a task that fits no other.
|
|
43
|
+
The `default` workstream of the scaffold is replaced by the ones the person named,
|
|
44
|
+
unless they want a catch-all, which then keeps or renames it with a description of
|
|
45
|
+
its own.
|
|
46
|
+
4. **What to record per task.** Ask what the person needs to know of every task, such
|
|
47
|
+
as who it is for, the time it took or whether it was billed. Propose one field per
|
|
48
|
+
answer, each with a snake_case name, one of the four types (`text`, `number`,
|
|
49
|
+
`boolean`, `date`), whether it is required, and a description. Propose whether every
|
|
50
|
+
workstream shares the field or only some hold it.
|
|
51
|
+
5. **The agent providers.** The scaffold declares every known provider in
|
|
52
|
+
`agent_providers`. Ask which agents the person uses and propose the list trimmed to
|
|
53
|
+
them.
|
|
54
|
+
6. **The IDE.** Ask for the command that opens a folder in their editor, such as
|
|
55
|
+
`code -n`; it becomes `ide`, run on every harness at launch.
|
|
56
|
+
7. **The repositories folder.** Only when the work involves code: ask for the folder
|
|
57
|
+
that holds the repositories the runs check out as worktrees; it becomes `repos_dir`,
|
|
58
|
+
absolute, starting with `~`, or relative to the tasks repo root.
|
|
59
|
+
|
|
60
|
+
Do not ask for what has a default or comes from use: `branch_prefix`, and the
|
|
61
|
+
`context` and `rules` of the processes.
|
|
62
|
+
|
|
63
|
+
Then:
|
|
64
|
+
|
|
65
|
+
8. **Write the config** by following the `gemba-config` skill from its step 4: edit
|
|
66
|
+
`gemba.yaml` keeping the comments of the scaffold, run `gemba config check` until it
|
|
67
|
+
exits 0, and run `gemba skills update` when `agent_providers` changed, telling the
|
|
68
|
+
user which skills folder is left for them to delete.
|
|
69
|
+
9. **Report** the resulting config: the workstreams with their prefixes, the default,
|
|
70
|
+
the fields, the providers, the IDE command and the repositories folder. End by
|
|
71
|
+
naming the edits that come later, through the `gemba-config` skill: `branch_prefix`,
|
|
72
|
+
the first segment of every branch of a run, `gemba` by default; and the `context`
|
|
73
|
+
and `rules` of any process, which tell agents what to know and do in a workstream
|
|
74
|
+
or in all of them. Do not commit: the user reviews and commits the tasks repo.
|
|
75
|
+
|
|
76
|
+
## Rules
|
|
77
|
+
|
|
78
|
+
- This interview is the first configuration only. Any later change of the config, a
|
|
79
|
+
workstream, a field, a provider or a rule, follows the `gemba-config` skill.
|
|
80
|
+
- One question per message, in the order above; never ask for a value the user already
|
|
81
|
+
gave.
|
|
@@ -0,0 +1,137 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: gemba-list
|
|
3
|
+
description: List, find or count tasks in this tasks repo. Use whenever the user asks to list, show, find, count or filter tasks, or asks "what do I have open", "what am I working on" or what happened on a task, whatever the workstream.
|
|
4
|
+
---
|
|
5
|
+
|
|
6
|
+
# List tasks
|
|
7
|
+
|
|
8
|
+
Answer questions about the tasks in the tasks repo. The `gemba list` command scans the
|
|
9
|
+
task folders, validates every file and applies the filters. Your part is to turn the
|
|
10
|
+
request into filters, run the command, open task files only when the answer needs
|
|
11
|
+
their body, and present the result.
|
|
12
|
+
|
|
13
|
+
Every organization-specific value (workstreams, prefixes, metadata fields, rules) lives
|
|
14
|
+
in `gemba.yaml`. Run `gemba config show` on every run and rely on nothing else you know
|
|
15
|
+
or remember about workstreams or fields: it prints the config resolved, with the fields
|
|
16
|
+
and the blocks shared by every workstream already joined to those of each one.
|
|
17
|
+
|
|
18
|
+
## Prerequisite
|
|
19
|
+
|
|
20
|
+
The `gemba` command must be on the PATH. It is installed once from PyPI with
|
|
21
|
+
`uv tool install gemba-cli` and checked with `gemba --version`. If `gemba` is not
|
|
22
|
+
found, stop and tell the user to install it with that command. Do not run the package's
|
|
23
|
+
Python files directly and do not build the list by reading the task folders yourself.
|
|
24
|
+
|
|
25
|
+
## Process
|
|
26
|
+
|
|
27
|
+
1. **Locate the config.** Walk up from the current folder to the nearest `gemba.yaml`.
|
|
28
|
+
That folder is the tasks repo root. If there is none, stop and tell the user that no
|
|
29
|
+
gemba config was found.
|
|
30
|
+
2. **Choose the workstreams.** Run `gemba config show` from anywhere inside the tasks
|
|
31
|
+
repo: it prints the config resolved as one JSON document, or the problem when the
|
|
32
|
+
config is invalid, which you relay before stopping. When the request names an area
|
|
33
|
+
of work, compare it with the `description` of every entry of `workstreams` in the
|
|
34
|
+
document and pass one `--workstream` per entry that covers it. When the request
|
|
35
|
+
names no area, or you cannot tell which entries cover it, pass no `--workstream`:
|
|
36
|
+
every workstream is listed. Listing is read-only, so listing too much is cheaper
|
|
37
|
+
than asking.
|
|
38
|
+
3. **Read the `list` block** of every chosen workstream (of every workstream when you
|
|
39
|
+
pass none): `processes.list` of its entry in the document. Read its `context` as
|
|
40
|
+
background and follow every entry of its `rules`, in order, when you run the command
|
|
41
|
+
and present the result; when two rules contradict, follow the later one. A rule
|
|
42
|
+
shared by every workstream appears in every entry: follow it once.
|
|
43
|
+
4. **Map the request to filters.** Resolve relative dates against today's date (run
|
|
44
|
+
`date +%F` if you are not sure of it); a week starts on Monday.
|
|
45
|
+
|
|
46
|
+
| The user says | Filters |
|
|
47
|
+
|---|---|
|
|
48
|
+
| open, pending, active, "what do I have", "what am I working on" | `--status open --status in-progress --status blocked` |
|
|
49
|
+
| one or more statuses by name (open, in progress, blocked) | one `--status` per named status |
|
|
50
|
+
| done, finished, closed | `--status done --include-archived` |
|
|
51
|
+
| a task ref, `<PREFIX>-<N>` | `--ref <PREFIX>-<N> --include-archived` and no other filter |
|
|
52
|
+
| created on a day or in a period | `--from` and `--to` (the creation date) |
|
|
53
|
+
| updated, touched or worked on in a period | `--updated-from` and `--updated-to` |
|
|
54
|
+
| finished in a period | `--done-from` and `--done-to`, with `--include-archived` |
|
|
55
|
+
| what could have been worked on on a past day D | `--to D --updated-from D` |
|
|
56
|
+
| archived tasks, everything, including archived | `--include-archived` |
|
|
57
|
+
| a value of a metadata field | `--where <field>=<value>` |
|
|
58
|
+
| a span of a number or date field: at least, at most, between, in a period | `--where-from <field>=<low>`, `--where-to <field>=<high>`, or both |
|
|
59
|
+
|
|
60
|
+
- A time word restricts dates only when it qualifies an event (created, updated,
|
|
61
|
+
finished). "What do I have open today" is the open listing with no date filter.
|
|
62
|
+
- Archived tasks are left out unless the request asks for them, for finished work or
|
|
63
|
+
for a task by its ref.
|
|
64
|
+
- For metadata, compare what the user said with the `name` and `description` of
|
|
65
|
+
every field under `metadata` in the entries of the document, and use the declared
|
|
66
|
+
name exactly. The command refuses a key that no workstream declares.
|
|
67
|
+
- Write every metadata value in the form of the field's declared `type`: a `text`
|
|
68
|
+
value exactly as it is stored, a `number` as a decimal (`3`, `2.5`, `-1`), a
|
|
69
|
+
`boolean` as `true` or `false`, a `date` as `YYYY-MM-DD`. `<field>=null` finds the
|
|
70
|
+
tasks where the field has no value, including those whose workstream declares the
|
|
71
|
+
field and whose file lacks it.
|
|
72
|
+
- Bounds apply to `number` and `date` fields only, and include their own value: a
|
|
73
|
+
period such as a month is `--where-from <field>=<first day>` and
|
|
74
|
+
`--where-to <field>=<last day>`. A task without a value never matches a bound. Give
|
|
75
|
+
at most one `--where-from` and one `--where-to` per field.
|
|
76
|
+
- Repeat an option to give alternatives: two `--status` values list tasks with
|
|
77
|
+
either status, two `--where` values on the same field list tasks with either
|
|
78
|
+
value. Different options must all match.
|
|
79
|
+
5. **Run the command** from anywhere inside the tasks repo root, every time, even when you
|
|
80
|
+
listed the same tasks earlier in the conversation:
|
|
81
|
+
|
|
82
|
+
```bash
|
|
83
|
+
gemba list [--workstream <id> ...] [--status <status> ...] [--ref <ref>] \
|
|
84
|
+
[--from YYYY-MM-DD] [--to YYYY-MM-DD] \
|
|
85
|
+
[--updated-from YYYY-MM-DD] [--updated-to YYYY-MM-DD] \
|
|
86
|
+
[--done-from YYYY-MM-DD] [--done-to YYYY-MM-DD] \
|
|
87
|
+
[--include-archived] [--where <field>=<value> ...] \
|
|
88
|
+
[--where-from <field>=<value> ...] [--where-to <field>=<value> ...]
|
|
89
|
+
```
|
|
90
|
+
|
|
91
|
+
- The command converts every metadata value by the declared type of its field; it
|
|
92
|
+
never reads a value as YAML, so text is matched exactly as written. Quote the whole
|
|
93
|
+
argument for the shell when it contains spaces.
|
|
94
|
+
- If the command refuses, its message lists every invalid filter at once, with the
|
|
95
|
+
valid workstreams, the allowed statuses or the declared fields. Fix the call and
|
|
96
|
+
run it again, asking the user only when the request itself is unclear. If the
|
|
97
|
+
config is missing or invalid, stop and report the message.
|
|
98
|
+
6. **Read the result.** The command prints one JSON object. `tasks` holds one record per
|
|
99
|
+
matching task: `path` (relative to the tasks repo root), `workstream`, `archived`,
|
|
100
|
+
`ref`, `date` (created), `title`, `status`, `updated_at`, `done_at`, `metadata` and
|
|
101
|
+
`description`. `problems` holds the files that are not valid tasks and the metadata
|
|
102
|
+
values that are not of the type their field declares, each with its `path` and the
|
|
103
|
+
`problem`.
|
|
104
|
+
7. **Open a task file only when the answer needs its body**: what happened last, the
|
|
105
|
+
history of the work, the links, what is left to do. Open it from the record's
|
|
106
|
+
`path`. Progress is under `## Updates`, one `### YYYY-MM-DD` subsection per day in
|
|
107
|
+
chronological order, so the last subsection is the latest activity.
|
|
108
|
+
8. **Present the result.** Adapt it to the question: a count gets the number, a
|
|
109
|
+
question about one task gets a short answer, a request for refs gets the refs and
|
|
110
|
+
titles. When a full listing is wanted, this layout reads well:
|
|
111
|
+
|
|
112
|
+
```
|
|
113
|
+
<workstream>
|
|
114
|
+
<ref> <title> <status> updated <updated_at>
|
|
115
|
+
<description, when it helps>
|
|
116
|
+
|
|
117
|
+
Problems
|
|
118
|
+
<path>: <problem>
|
|
119
|
+
|
|
120
|
+
<N> tasks
|
|
121
|
+
```
|
|
122
|
+
|
|
123
|
+
The layout is a suggestion, not a contract; nothing depends on it. When no task
|
|
124
|
+
matches, say so plainly and name the filters you used.
|
|
125
|
+
9. **Relay every problem** the command returned, even when the question was about
|
|
126
|
+
something else: give each path and its problem. Say that a file that is not a valid
|
|
127
|
+
task is left out of the listing until it is fixed, and that a task whose value is of
|
|
128
|
+
another type is still listed but matches no condition on that field until the value
|
|
129
|
+
is set again with `gemba set`. Never fix a task file yourself.
|
|
130
|
+
|
|
131
|
+
## Rules
|
|
132
|
+
|
|
133
|
+
- Read, never write: do not edit, move or create any file, and do not commit.
|
|
134
|
+
- Commands own the frontmatter and the agent owns the body; if a frontmatter value
|
|
135
|
+
looks wrong, tell the user instead of changing it.
|
|
136
|
+
- When `gemba.yaml` changes, follow the new content. This skill never needs an edit when
|
|
137
|
+
a workstream, field or rule is added, changed or removed.
|
|
@@ -0,0 +1,88 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: gemba-mark
|
|
3
|
+
description: Mark a task done, blocked, open or in progress. Use whenever the user says a task is finished, completed, closed or done, that it is stuck, waiting or blocked, or asks to mark, finish, close, complete, block, unblock, reopen or resume a task, from the tasks repo or inside its harness, whatever the workstream.
|
|
4
|
+
---
|
|
5
|
+
|
|
6
|
+
# Mark a task
|
|
7
|
+
|
|
8
|
+
A task moves between four statuses after its creation: `open`, `in-progress`, `blocked`
|
|
9
|
+
and `done`. The `gemba mark` command is the one writer of that move: it sets `status`,
|
|
10
|
+
writes `done_at` when the task reaches `done` and removes it when the task leaves
|
|
11
|
+
`done`, moves `updated_at` forward, and rewrites nothing but the frontmatter. Your part
|
|
12
|
+
is to find the task, turn the user's words into one status, run the command and relay
|
|
13
|
+
what it prints.
|
|
14
|
+
|
|
15
|
+
Every organization-specific value (workstreams and their rules) lives in `gemba.yaml`,
|
|
16
|
+
at the tasks repo root. Run `gemba config show` on every run and rely on nothing else
|
|
17
|
+
you know or remember about workstreams: it prints the config resolved, with the blocks
|
|
18
|
+
shared by every workstream already joined to those of each one.
|
|
19
|
+
|
|
20
|
+
## Prerequisite
|
|
21
|
+
|
|
22
|
+
The `gemba` command must be on the PATH. It is installed once from PyPI with
|
|
23
|
+
`uv tool install gemba-cli` and checked with `gemba --version`. If `gemba` is not
|
|
24
|
+
found, stop and tell the user to install it with that command. Never edit the
|
|
25
|
+
frontmatter of a task by hand.
|
|
26
|
+
|
|
27
|
+
## Process
|
|
28
|
+
|
|
29
|
+
From the tasks repo or from inside the harness of the task. Inside a harness, the
|
|
30
|
+
folder that holds `harness.yaml` is the harness root.
|
|
31
|
+
|
|
32
|
+
1. **Identify the task by its ref**, `<PREFIX>-<N>`. Inside a harness, the task is the
|
|
33
|
+
one named by `ref` in `harness.yaml`, unless the user names another. From the tasks
|
|
34
|
+
repo, take the ref the user gives; when they name the task by its title or
|
|
35
|
+
description instead, find it with the `gemba-list` skill. When two or more tasks
|
|
36
|
+
fit, ask the user which one before marking anything.
|
|
37
|
+
2. **Choose the status** from the user's words:
|
|
38
|
+
|
|
39
|
+
| The user says | Status |
|
|
40
|
+
|---|---|
|
|
41
|
+
| finished, completed, closed, done | `done` |
|
|
42
|
+
| stuck, waiting, blocked | `blocked` |
|
|
43
|
+
| reopen, or bring back a `done` task, without saying the work resumes now | `open` |
|
|
44
|
+
| continue, resume, unblock, working on it now | `in-progress` |
|
|
45
|
+
|
|
46
|
+
When the words fit none of these rows, or fit two, ask the user which status they
|
|
47
|
+
mean.
|
|
48
|
+
3. **Offer to record the day first.** Only inside a harness and only when the status is
|
|
49
|
+
`done`: read today's date with `date +%F`, then read `task.md`. When its
|
|
50
|
+
`## Updates` section has no `### <today>` subsection and `notes/` holds notes of
|
|
51
|
+
today (`notes/<today>-*.md`), tell the user the day is not recorded yet and offer to
|
|
52
|
+
record it with the `gemba-record` skill before marking. If they accept, record the
|
|
53
|
+
day, then go on. If they decline, go on and mark the task anyway.
|
|
54
|
+
4. **Read the `mark` block** of the task's workstream: run `gemba config show` and
|
|
55
|
+
take the entry of `workstreams` whose `prefix` is the prefix of the ref; for the task
|
|
56
|
+
of the harness, `gemba config show --workstream <id>` with the `workstream` of
|
|
57
|
+
`harness.yaml` prints that entry alone. Read `processes.mark` of that entry: `context`
|
|
58
|
+
as background, and every entry of `rules` to follow, in order, before running the
|
|
59
|
+
command; when two rules contradict, follow the later one.
|
|
60
|
+
5. **Run the command:**
|
|
61
|
+
|
|
62
|
+
```bash
|
|
63
|
+
gemba mark <ref> <status> [--date YYYY-MM-DD]
|
|
64
|
+
```
|
|
65
|
+
|
|
66
|
+
- Pass `--date` only when the user says the change happened on a past day, such as
|
|
67
|
+
"I finished it yesterday"; resolve that day against `date +%F`. Without it the
|
|
68
|
+
change is dated today.
|
|
69
|
+
- If the command refuses, its message lists every problem at once. Fix the call
|
|
70
|
+
when the problem is yours (the ref, the status, the date) and run it again. When
|
|
71
|
+
it says the task is archived, relay the message and stop: whether to move the
|
|
72
|
+
file out of `archive/` is the user's decision, not yours.
|
|
73
|
+
6. **Relay the result** and stop: the task path, the `status:` line, the `done_at:` line
|
|
74
|
+
when there is one (the date written, or `removed`) and the `updated_at:` line. When
|
|
75
|
+
the command says the status was left as it was, say the task already had that
|
|
76
|
+
status.
|
|
77
|
+
|
|
78
|
+
## Rules
|
|
79
|
+
|
|
80
|
+
- Commands own the frontmatter: never write `status`, `done_at` or `updated_at` by
|
|
81
|
+
hand, in `task.md` or in the task file.
|
|
82
|
+
- Marking writes no update. What was done belongs under `## Updates`, through the
|
|
83
|
+
`gemba-record` skill; marking never replaces recording.
|
|
84
|
+
- Marking does not touch the harness. A task reopened to `open` moves to `in-progress`
|
|
85
|
+
by itself the next time its harness is launched; a `done` task cannot be launched
|
|
86
|
+
until it is marked `open` or `in-progress`.
|
|
87
|
+
- When `gemba.yaml` changes, follow the new content. This skill never needs an edit when
|
|
88
|
+
a workstream or a rule is added, changed or removed.
|
|
@@ -0,0 +1,89 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: gemba-record
|
|
3
|
+
description: Record the day's work on the task of this harness, distilled from its notes. Use whenever, inside a harness, the user asks to record, log or backfill what was done on the task today, yesterday or on a given date, or to update the task from the notes, whatever the workstream.
|
|
4
|
+
---
|
|
5
|
+
|
|
6
|
+
# Record the day
|
|
7
|
+
|
|
8
|
+
The notes of a harness are the memory of the run; the task file is the durable record,
|
|
9
|
+
with one `### YYYY-MM-DD` subsection per day under `## Updates`. Recording promotes one
|
|
10
|
+
day of the run into the task: you distill the notes of that day into a few bullets in a
|
|
11
|
+
draft, and `gemba record` writes them into the task and moves its `updated_at` in the
|
|
12
|
+
same step. Your part is to decide what the bullets say; the command decides where they
|
|
13
|
+
go.
|
|
14
|
+
|
|
15
|
+
Every organization-specific value (workstreams and their rules) lives in `gemba.yaml`,
|
|
16
|
+
at the tasks repo root. Run `gemba config show` on every run and rely on nothing else
|
|
17
|
+
you know or remember about workstreams: it prints the config resolved, with the blocks
|
|
18
|
+
shared by every workstream already joined to those of each one.
|
|
19
|
+
|
|
20
|
+
## Prerequisite
|
|
21
|
+
|
|
22
|
+
The `gemba` command must be on the PATH. It is installed once from PyPI with
|
|
23
|
+
`uv tool install gemba-cli` and checked with `gemba --version`. If `gemba` is not
|
|
24
|
+
found, stop and tell the user to install it with that command. Never edit `task.md`.
|
|
25
|
+
|
|
26
|
+
## Process
|
|
27
|
+
|
|
28
|
+
Inside the harness of the task. Paths are relative to the harness root, the folder that
|
|
29
|
+
holds `harness.yaml`.
|
|
30
|
+
|
|
31
|
+
1. **Choose the date.** Today, unless the user names another day. Read today's date
|
|
32
|
+
with `date +%F` and resolve "yesterday" or a weekday against it. When several dates
|
|
33
|
+
are to be recorded, take them oldest first and go through steps 2 to 8 once per
|
|
34
|
+
date, each with its own draft and its own run.
|
|
35
|
+
2. **Read the task and the notes of the date.** Read `task.md` for what the task is and
|
|
36
|
+
what is already recorded. Then read every note under `notes/` whose name starts with
|
|
37
|
+
the date, `notes/<YYYY-MM-DD>-*.md`, in the order of their names, whatever their
|
|
38
|
+
type. Notes of other dates are context, not content for this date.
|
|
39
|
+
3. **Stop when there is nothing to record.** When no note carries the date and this
|
|
40
|
+
session did nothing on the task that day, tell the user there is nothing to record
|
|
41
|
+
for that date and stop: write no draft and run no command. When this session did
|
|
42
|
+
work that day that no note holds yet, file that note first with the `gemba-harness`
|
|
43
|
+
skill, so that the notes stay the only source of the update.
|
|
44
|
+
4. **Read the `record` block** of the task's workstream: run
|
|
45
|
+
`gemba config show --workstream <id>` with the `workstream` of `harness.yaml`, from
|
|
46
|
+
anywhere inside the harness, and read `processes.record`. Read `context` as
|
|
47
|
+
background and follow every entry of `rules`, in order, while distilling and
|
|
48
|
+
drafting; when two rules contradict, follow the later one.
|
|
49
|
+
5. **Distill one to five bullets** of what moved that day: what was found, decided,
|
|
50
|
+
changed or delivered, what is blocked and on whom. Each bullet must make sense to
|
|
51
|
+
someone who never opens the harness: name the system, the file, the merge request or
|
|
52
|
+
the person, never a note or an asset of the harness. Leave out process noise: notes
|
|
53
|
+
filed, files read, commands that changed nothing, attempts that led nowhere unless
|
|
54
|
+
their failure is the news. Say nothing the notes do not support.
|
|
55
|
+
6. **Write the draft** at the harness root, `update.md`, with your own tools: bullets
|
|
56
|
+
only, each starting with `- `, and a bullet that runs over several lines continued
|
|
57
|
+
by lines indented by two spaces. No heading, no date, no frontmatter, no other text.
|
|
58
|
+
Never write it under `notes/` or `assets/`.
|
|
59
|
+
7. **Run the command** from the harness root:
|
|
60
|
+
|
|
61
|
+
```bash
|
|
62
|
+
gemba record update.md [--date YYYY-MM-DD]
|
|
63
|
+
```
|
|
64
|
+
|
|
65
|
+
- Pass `--date` whenever the date is not today.
|
|
66
|
+
- The command writes the bullets under `### <date>` in the task, after any bullets
|
|
67
|
+
already recorded for that date, moves `updated_at` to the date when it is later,
|
|
68
|
+
deletes `update.md` and commits nothing.
|
|
69
|
+
- If it refuses, its message lists every problem at once. For a problem with the
|
|
70
|
+
draft or the date, fix the draft or the call and run it again. For a problem with
|
|
71
|
+
the `## Updates` section of the task, tell the user what the message says: the
|
|
72
|
+
task file is theirs to fix, and the draft stays for the retry. Never work around a
|
|
73
|
+
refusal by editing `task.md`.
|
|
74
|
+
- If it says the task is recorded but the draft could not be deleted, delete
|
|
75
|
+
`update.md` yourself and do not run the command again: a second run would write
|
|
76
|
+
the same bullets twice.
|
|
77
|
+
8. **Relay the result:** the task path and the `updated_at` line the command printed,
|
|
78
|
+
which says whether the date moved or was left unchanged because the task was
|
|
79
|
+
already updated later, and the bullets you recorded. The user reviews and commits
|
|
80
|
+
the change in the tasks repo.
|
|
81
|
+
|
|
82
|
+
## Rules
|
|
83
|
+
|
|
84
|
+
- `task.md` is read-only: never edit it, and never write a `### YYYY-MM-DD` heading or a
|
|
85
|
+
frontmatter value by hand. The command is the only writer of the update.
|
|
86
|
+
- Record only what the notes of the date support; when in doubt, leave it out.
|
|
87
|
+
- One draft and one run per date, oldest date first.
|
|
88
|
+
- When `gemba.yaml` changes, follow the new content. This skill never needs an edit when
|
|
89
|
+
a workstream or a rule is added, changed or removed.
|
|
@@ -0,0 +1,149 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: gemba-report
|
|
3
|
+
description: Report what was done in a period, a day, a week or a month, across every task of this tasks repo, with every count and total taken from gemba report. Use whenever the user asks for the daily report, a standup, an end-of-day, weekly or monthly summary, "what did I do today", "yesterday", "this week" or "in September", or how much of an amount went to each workstream, status or value of a field in a period, whatever the workstream.
|
|
4
|
+
---
|
|
5
|
+
|
|
6
|
+
# Report a period
|
|
7
|
+
|
|
8
|
+
The report answers what was done in a period, one day or several consecutive days,
|
|
9
|
+
across every task, and how much of each amount went where. `gemba list` finds the tasks
|
|
10
|
+
alive in the period, each task file records its work under `## Updates`, one
|
|
11
|
+
`### YYYY-MM-DD` subsection per day, and `gemba report` computes every count and every
|
|
12
|
+
sum over a selection of tasks. Your part is to list the candidates, read the
|
|
13
|
+
subsections of the period, take every number from `gemba report`, and compose the
|
|
14
|
+
report without adding anything the files and the commands do not say.
|
|
15
|
+
|
|
16
|
+
Every organization-specific value (workstreams, prefixes, metadata fields, rules) lives
|
|
17
|
+
in `gemba.yaml`. Run `gemba config show` on every run and rely on nothing else you know
|
|
18
|
+
or remember about workstreams or fields: it prints the config resolved, with the fields
|
|
19
|
+
and the blocks shared by every workstream already joined to those of each one.
|
|
20
|
+
|
|
21
|
+
## Prerequisite
|
|
22
|
+
|
|
23
|
+
The `gemba` command must be on the PATH. It is installed once from PyPI with
|
|
24
|
+
`uv tool install gemba-cli` and checked with `gemba --version`. If `gemba` is not
|
|
25
|
+
found, stop and tell the user to install it with that command. Do not build the list of
|
|
26
|
+
candidates by reading the task folders yourself, and do not compute a number yourself.
|
|
27
|
+
|
|
28
|
+
## Process
|
|
29
|
+
|
|
30
|
+
1. **Locate the config.** Walk up from the current folder to the nearest `gemba.yaml`.
|
|
31
|
+
That folder is the tasks repo root. If there is none, stop and tell the user that no
|
|
32
|
+
gemba config was found.
|
|
33
|
+
2. **Choose the period**, from F to T, both included. Today, unless the user names
|
|
34
|
+
another day or period. Read today's date with `date +%F` and resolve "yesterday", a
|
|
35
|
+
weekday, "this week", "last week", a month or "this month" against it; a week starts
|
|
36
|
+
on Monday, and a period never ends after today. A day is F equal to T. Several
|
|
37
|
+
periods give one report each, oldest first, and steps 3 to 9 run once per period.
|
|
38
|
+
3. **List the candidates** of the period with exactly this command, from anywhere
|
|
39
|
+
inside the tasks repo:
|
|
40
|
+
|
|
41
|
+
```bash
|
|
42
|
+
gemba list --to T --updated-from F
|
|
43
|
+
```
|
|
44
|
+
|
|
45
|
+
It returns the tasks created on or before T and updated on or after F, which are
|
|
46
|
+
exactly the tasks alive in the period. Add `--include-archived` only when the user
|
|
47
|
+
asks for archived tasks too, and no other filter: the report covers every
|
|
48
|
+
workstream. Read only the tasks it returns. If the command refuses, relay its
|
|
49
|
+
message and stop.
|
|
50
|
+
4. **Read the signals of each candidate.** Open the file at the record's `path` and
|
|
51
|
+
take:
|
|
52
|
+
- the bullets of every `### D` subsection under `## Updates` whose date D lies from F
|
|
53
|
+
to T: the work of the period, day by day;
|
|
54
|
+
- the record's `date` from F to T: the task was created in the period;
|
|
55
|
+
- the record's `done_at` from F to T: the task was finished in the period.
|
|
56
|
+
|
|
57
|
+
A candidate with none of the three has nothing recorded for the period.
|
|
58
|
+
5. **Read the `report` block** of every workstream that has candidates: run
|
|
59
|
+
`gemba config show` and read `processes.report` of each of their entries. Read
|
|
60
|
+
`context` as background and follow every entry of `rules`, in order, when composing
|
|
61
|
+
the entries of that workstream and when choosing a selection for its numbers; when
|
|
62
|
+
two rules contradict, follow the later one. A rule shared by every workstream
|
|
63
|
+
appears in every entry: follow it once.
|
|
64
|
+
6. **Take the numbers from `gemba report`** whenever the report states a count, a sum or
|
|
65
|
+
a total, and whenever the user asks how much of something went where. The command
|
|
66
|
+
takes the filters of `gemba list` and prints one JSON object:
|
|
67
|
+
|
|
68
|
+
```bash
|
|
69
|
+
gemba report --done-from F --done-to T [--by <grouping> ...] [--sum <field> ...]
|
|
70
|
+
```
|
|
71
|
+
|
|
72
|
+
- **Selection.** A number field holds one total per task, so the totals of a period
|
|
73
|
+
are those of the tasks finished in it: select with `--done-from F --done-to T`
|
|
74
|
+
unless the user asks for another selection (created in the period is
|
|
75
|
+
`--from F --to T`; a date field in the period is `--where-from <field>=F
|
|
76
|
+
--where-to <field>=T`) or the `report.rules` of the workstreams involved say
|
|
77
|
+
otherwise. Add `--include-archived` when the user asks for archived tasks too.
|
|
78
|
+
Narrow it with `--workstream`, `--status` or `--where` when the question does.
|
|
79
|
+
- **Groupings.** `--by workstream`, `--by status`, or `--by <field>` for a field
|
|
80
|
+
whose declared `type` is `text` or `boolean`, when the user asks for amounts per
|
|
81
|
+
workstream, per status or per value of a field. Repeat `--by` to group within
|
|
82
|
+
groups. Map the user's words to fields by the `name` and `description` of every
|
|
83
|
+
field under `metadata` in the entries of the document of step 5, and write every
|
|
84
|
+
value by its field's declared type, as `gemba list` takes them.
|
|
85
|
+
- **Sums.** `--sum <field>` for a field whose declared `type` is `number`.
|
|
86
|
+
- **Reading.** `groups` holds one entry per combination of grouping values: `key`
|
|
87
|
+
(each grouping and its value, `null` for tasks without one), `tasks`, `refs` and,
|
|
88
|
+
per summed field, `total` and `missing`, the tasks without a number to add.
|
|
89
|
+
`total` holds the same over every selected task, each counted once. A task whose
|
|
90
|
+
text field holds a list is counted in the group of each item, so the groups may add
|
|
91
|
+
up to more than the total: say so when you report both.
|
|
92
|
+
- If the command refuses, its message lists every invalid filter, grouping and sum at
|
|
93
|
+
once. Fix the call and run it again, asking the user only when the request itself
|
|
94
|
+
is unclear.
|
|
95
|
+
|
|
96
|
+
State only the numbers the command printed: each total, each count, and the tasks
|
|
97
|
+
without a value whenever `missing` is not zero. Never add, subtract, average or
|
|
98
|
+
compare numbers yourself; when the user wants a total the command did not print,
|
|
99
|
+
such as two groups together, run `gemba report` again with the selection or the
|
|
100
|
+
grouping that yields it. Say which selection the numbers come from, such as "tasks
|
|
101
|
+
finished from F to T".
|
|
102
|
+
7. **Compose the report** in the language the user converses in, grouped by
|
|
103
|
+
workstream unless the user asks for another grouping, with one entry per task that
|
|
104
|
+
has a signal for the period: its title, ref and current status, then the bullets of
|
|
105
|
+
the period, condensed rather than transcribed. A task created or finished in the
|
|
106
|
+
period says so, without bullets made up for it. When no candidate has a signal for
|
|
107
|
+
the period, say plainly that nothing was recorded for it. This layout reads well:
|
|
108
|
+
|
|
109
|
+
```
|
|
110
|
+
Report for <F> to <T>
|
|
111
|
+
|
|
112
|
+
<workstream>
|
|
113
|
+
<ref> <title> <status>
|
|
114
|
+
- <condensed bullet>
|
|
115
|
+
- created on <date> | finished on <done_at>
|
|
116
|
+
|
|
117
|
+
Numbers (<the selection used>)
|
|
118
|
+
<group> <count> tasks <field>: <total> (<missing> without a value)
|
|
119
|
+
|
|
120
|
+
Updated recently, nothing recorded from <F> to <T>
|
|
121
|
+
<ref> <title> <status> updated <updated_at>
|
|
122
|
+
```
|
|
123
|
+
|
|
124
|
+
The layout is guidance, not a contract: adapt it to the question asked; nothing
|
|
125
|
+
depends on it. A question about amounts alone gets the numbers alone.
|
|
126
|
+
8. **List the gaps at the end:** every candidate with nothing recorded for the period,
|
|
127
|
+
under a heading saying they were updated recently with nothing recorded for that
|
|
128
|
+
period, with no bullets, so the user can record what is missing.
|
|
129
|
+
9. **Relay every problem** that `gemba list` or `gemba report` returned, alongside the
|
|
130
|
+
report: give each path and its problem. A file that is not a valid task is left out
|
|
131
|
+
until it is fixed; a value that is not of its field's type is grouped under `null`
|
|
132
|
+
and counted as missing until it is set again with `gemba set`.
|
|
133
|
+
|
|
134
|
+
## Filling a gap
|
|
135
|
+
|
|
136
|
+
The report never fills a gap. To record what a task is missing, point the user to the
|
|
137
|
+
harness of that task, `harnesses/<workstream>/<task file name without .md>/`, and the
|
|
138
|
+
`gemba-record` skill used inside it; a task with no harness yet is launched with the
|
|
139
|
+
`gemba-harness` skill. A metadata value that is missing or wrong is set with the
|
|
140
|
+
`gemba-set` skill.
|
|
141
|
+
|
|
142
|
+
## Rules
|
|
143
|
+
|
|
144
|
+
- Read, never write: do not edit, move or create any file, and do not commit.
|
|
145
|
+
- State no activity that a subsection of the period, a creation date or a `done_at`
|
|
146
|
+
does not support, and no number that `gemba report` did not print. A task with
|
|
147
|
+
nothing recorded is a gap to show, not one to fill from memory.
|
|
148
|
+
- When `gemba.yaml` changes, follow the new content. This skill never needs an edit when
|
|
149
|
+
a workstream, field or rule is added, changed or removed.
|
|
@@ -0,0 +1,104 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: gemba-set
|
|
3
|
+
description: Set, change, correct or clear a metadata value of a task, or add to an amount it holds, such as the time it took, from the tasks repo or inside its harness. Use whenever the user gives a value of a task's field after its creation, says a task took more time or more of any amount than recorded, says something happened to a task on a date a field records, or asks to set, change, fix, clear, log or add to a value of a task, whatever the workstream. Recording the day's work is gemba-record and the status of a task is gemba-mark.
|
|
4
|
+
---
|
|
5
|
+
|
|
6
|
+
# Set metadata of a task
|
|
7
|
+
|
|
8
|
+
The metadata of a task is the map of values its workstream declares in `gemba.yaml`,
|
|
9
|
+
each field with a `type`: `text`, `number`, `boolean` or `date`. The `gemba set` command
|
|
10
|
+
is the one writer of those values after creation: it converts every value by the type
|
|
11
|
+
of its field, adds to a number without anyone doing the sum, completes the map with the
|
|
12
|
+
keys of the current schema, and rewrites nothing but `metadata`; `updated_at` does not
|
|
13
|
+
move. Your part is to find the task, turn the user's words into assignments of declared
|
|
14
|
+
fields, run the command once and relay what it prints.
|
|
15
|
+
|
|
16
|
+
Every organization-specific value (workstreams, prefixes, metadata fields, rules) lives
|
|
17
|
+
in `gemba.yaml`, at the tasks repo root. Run `gemba config show` on every run and rely
|
|
18
|
+
on nothing else you know or remember about workstreams or fields: it prints the config
|
|
19
|
+
resolved, with the fields and the blocks shared by every workstream already joined to
|
|
20
|
+
those of each one.
|
|
21
|
+
|
|
22
|
+
## Prerequisite
|
|
23
|
+
|
|
24
|
+
The `gemba` command must be on the PATH. It is installed once from PyPI with
|
|
25
|
+
`uv tool install gemba-cli` and checked with `gemba --version`. If `gemba` is not
|
|
26
|
+
found, stop and tell the user to install it with that command. Never edit the
|
|
27
|
+
frontmatter of a task by hand.
|
|
28
|
+
|
|
29
|
+
## Process
|
|
30
|
+
|
|
31
|
+
From the tasks repo or from inside the harness of the task. Inside a harness, the
|
|
32
|
+
folder that holds `harness.yaml` is the harness root.
|
|
33
|
+
|
|
34
|
+
1. **Identify the task by its ref**, `<PREFIX>-<N>`. Inside a harness, the task is the
|
|
35
|
+
one named by `ref` in `harness.yaml`, unless the user names another. From the tasks
|
|
36
|
+
repo, take the ref the user gives; when they name the task by its title or
|
|
37
|
+
description instead, find it with the `gemba-list` skill. When two or more tasks
|
|
38
|
+
fit, ask the user which one before setting anything.
|
|
39
|
+
2. **Read the schema of the task.** Its workstream is the one whose `prefix` is the
|
|
40
|
+
prefix of the ref: run `gemba config show` and take the entry of `workstreams` with
|
|
41
|
+
that `prefix`; for the task of the harness, `gemba config show --workstream <id>`
|
|
42
|
+
with the `workstream` of `harness.yaml` prints that entry alone. The `metadata` of
|
|
43
|
+
that entry lists every field the task may hold, each with its `name`, `type`,
|
|
44
|
+
`required` and `description`. Read its `processes.set` too: `context` as background,
|
|
45
|
+
and every entry of `rules` to follow, in order, before running the command; when two
|
|
46
|
+
rules contradict, follow the later one.
|
|
47
|
+
3. **Map the user's words to declared fields** by their names and descriptions. Use the
|
|
48
|
+
declared name exactly. When nothing in the schema fits what the user said, tell them
|
|
49
|
+
which fields are declared and stop: a new field is an edit of `gemba.yaml`, not a
|
|
50
|
+
value to invent.
|
|
51
|
+
4. **Write each assignment by the field's `type`:**
|
|
52
|
+
|
|
53
|
+
| Type | The user says | Assignment |
|
|
54
|
+
|---|---|---|
|
|
55
|
+
| `number` | a new total | `<field>=<decimal>`, such as `3` or `2.5` |
|
|
56
|
+
| `number` | more of an amount, "another", "two more" | `<field>+=<decimal>` |
|
|
57
|
+
| `boolean` | yes or no | `<field>=true` or `<field>=false` |
|
|
58
|
+
| `date` | a day | `<field>=YYYY-MM-DD` |
|
|
59
|
+
| `text` | a value | `<field>=<value>`, exactly as it should read |
|
|
60
|
+
| `text` | several values | `<field>=<one> <field>=<two>`, the whole list |
|
|
61
|
+
| any | remove, clear, unset | `<field>=null` |
|
|
62
|
+
|
|
63
|
+
- Resolve "today", "yesterday" or a weekday against `date +%F`.
|
|
64
|
+
- Use `+=` whenever the user adds to an amount instead of stating the new total, and
|
|
65
|
+
never add, subtract or convert numbers yourself. When the user gives an amount in
|
|
66
|
+
another unit than the one the field's name or description implies, ask for it in
|
|
67
|
+
the field's unit.
|
|
68
|
+
- A text list replaces the whole value: to add one item, give every item.
|
|
69
|
+
- For a `text` field, look up the values already in use before writing one:
|
|
70
|
+
|
|
71
|
+
```bash
|
|
72
|
+
gemba report --by <field> --include-archived
|
|
73
|
+
```
|
|
74
|
+
|
|
75
|
+
The `key` of each group is a value in use. When the user means one of them,
|
|
76
|
+
written another way (another case, an abbreviation), use the spelling in use; when
|
|
77
|
+
you cannot tell whether the user means a value in use or a new one, ask.
|
|
78
|
+
5. **Run the command once,** with every assignment, from anywhere inside the tasks repo
|
|
79
|
+
or the harness:
|
|
80
|
+
|
|
81
|
+
```bash
|
|
82
|
+
gemba set <ref> <field>=<value> [<field>+=<number> ...]
|
|
83
|
+
```
|
|
84
|
+
|
|
85
|
+
Quote an assignment for the shell when it contains spaces. If the command refuses,
|
|
86
|
+
its message lists every problem at once. Fix the call when the problem is yours
|
|
87
|
+
(a field name, the form of a value) and run it again. When it says a required field
|
|
88
|
+
would be left null, ask the user for that value and pass it in the same call. When it
|
|
89
|
+
cannot add to a value that is not a number, tell the user and ask for the total to
|
|
90
|
+
set with `=`.
|
|
91
|
+
6. **Relay the result** and stop: the task path and one line per field, `old -> new`,
|
|
92
|
+
`(unchanged)` when the value was already there, or `added as null` for a field the
|
|
93
|
+
task lacked because it was declared after the task was created.
|
|
94
|
+
|
|
95
|
+
## Rules
|
|
96
|
+
|
|
97
|
+
- Commands own the frontmatter: never write `metadata`, or any other frontmatter key,
|
|
98
|
+
by hand, in `task.md` or in the task file.
|
|
99
|
+
- Setting records no work and moves no status. What was done belongs under
|
|
100
|
+
`## Updates`, through the `gemba-record` skill; the status belongs to the `gemba-mark`
|
|
101
|
+
skill.
|
|
102
|
+
- Choose the assignment by the declared `type` of a field, never by its name.
|
|
103
|
+
- When `gemba.yaml` changes, follow the new content. This skill never needs an edit when
|
|
104
|
+
a workstream, field or rule is added, changed or removed.
|