moshcode 0.70.0 → 0.72.0

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.
@@ -30,6 +30,30 @@
30
30
  },
31
31
  "homepage": "https://github.com/moshcoder/moshcode#crypto",
32
32
  "keywords": ["crypto", "bitcoin", "markets", "prices", "advis0r"]
33
+ },
34
+ {
35
+ "name": "timer",
36
+ "description": "Track time against projects from inside your engine, backed by @profullstack/timer: start and stop a clock, log time you forgot, and report billable hours with the agent count that priced them.",
37
+ "source": "./plugins/timer",
38
+ "category": "productivity",
39
+ "author": {
40
+ "name": "moshcoder",
41
+ "url": "https://moshcode.sh"
42
+ },
43
+ "homepage": "https://github.com/profullstack/timer#readme",
44
+ "keywords": ["timer", "time-tracking", "billable", "hours", "profullstack"]
45
+ },
46
+ {
47
+ "name": "billing",
48
+ "description": "Turn tracked hours into an invoice, backed by @profullstack/billing: clients, rate cards written as contract sentences, agent-hour arithmetic, and invoices rendered to HTML you can print to PDF.",
49
+ "source": "./plugins/billing",
50
+ "category": "productivity",
51
+ "author": {
52
+ "name": "moshcoder",
53
+ "url": "https://moshcode.sh"
54
+ },
55
+ "homepage": "https://github.com/profullstack/billing#readme",
56
+ "keywords": ["billing", "invoice", "clients", "rates", "profullstack"]
33
57
  }
34
58
  ]
35
59
  }
package/README.md CHANGED
@@ -62,6 +62,12 @@ or miss one that does. A test fails the build when it drifts.
62
62
  | `moshcode crypto` <br>`coins` | tools | crypto market data from advis0r.com |
63
63
  | `moshcode news` | tools | headlines from your feeds, or a search |
64
64
  | `moshcode rss` | tools | read the same headlines in a full-screen reader |
65
+ | `moshcode timer` | business | track time — on, off, and what it added up to |
66
+ | `moshcode client` <br>`business` `merchant` `customer` | business | who the work is for — clients, businesses, merchants |
67
+ | `moshcode team` <br>`teams` | business | who may do what on this machine |
68
+ | `moshcode rate` <br>`rates` | business | what an hour of agent time costs |
69
+ | `moshcode billing` <br>`invoice` | business | turn tracked time into an invoice |
70
+ | `moshcode payments` | business | the rail invoices go out on |
65
71
  | `moshcode plugin` <br>`plugins` | extend | install moshcode's slash commands into Claude Code |
66
72
  | `moshcode commands` | script | list built-in moshscript commands |
67
73
  | `moshcode completion` | extend | print a shell completion script |
@@ -937,6 +943,120 @@ event, and publishes it to the displayed relays. Both flows leave the final
937
943
  confirmation in the browser. If the pit is remote or headless, `/post` prints
938
944
  the composer URL instead.
939
945
 
946
+ ## Getting paid (`/timer`, `/client`, `/rate`, `/billing`, `/payments`)
947
+
948
+ Every agentic CLI helps you do the work. This one also bills for it. Six words,
949
+ each useful on its own — the timer needs no client, the rate needs no gateway
950
+ (PRD [0012](prd/0012-billing-baked-into-the-agent-cli.md)).
951
+
952
+ > **`/timer` and `/billing` now prefer their own CLIs.** Tracking time and
953
+ > sending an invoice are not moshcode ideas — they are useful under any agentic
954
+ > CLI, and on Windows, where moshcode does not go. So they also ship standalone:
955
+ > [`@profullstack/timer`](https://github.com/profullstack/timer) and
956
+ > [`@profullstack/billing`](https://github.com/profullstack/billing).
957
+ >
958
+ > ```sh
959
+ > moshcode install timer billing # or: npm install -g @profullstack/timer @profullstack/billing
960
+ > ```
961
+ >
962
+ > Installing them changes nothing on its own. Switch the hand-over on when you
963
+ > are ready to move:
964
+ >
965
+ > ```sh
966
+ > billing import # look at what would come across
967
+ > billing import --apply # move it
968
+ > export MOSHCODE_EXTERNAL_BILLING=1 # /timer and /billing now run the CLIs
969
+ > ```
970
+ >
971
+ > **It is opt-in for a reason.** Only half this layer has an outside home:
972
+ > `/client`, `/rate`, `/payments` and `/team` stay here, because the rails and
973
+ > the permission model are moshcode's and `/client`'s freeform dotted fields
974
+ > have no shape in the package's typed client model. Handing over the other
975
+ > half automatically would split your records across two stores — `/client` and
976
+ > `/rate` writing `~/.moshcode/business.json` while `/billing` reads the
977
+ > package's own ledger, so the invoice for a client you had just created would
978
+ > not exist. `billing import` is what closes that gap, which is why it comes
979
+ > first.
980
+ >
981
+ > The standalone billing carries the same rate model (`$100/hour/agent/upto:4`)
982
+ > and bills **agent-hours**.
983
+
984
+ ```sh
985
+ moshcode timer on acme --task "batch payments" --agents auto # auto counts the herd
986
+ moshcode timer off # → 1h 12m, $480.00
987
+ moshcode timer log --week # this week's timesheet
988
+ ```
989
+
990
+ The timer is a stopwatch and a ledger in `~/.moshcode/timers.json`, and it knows
991
+ nothing about money. It does know about **agents**, which is what makes it
992
+ different from every other stopwatch: an hour of moshcode is an hour times
993
+ however many engines ran in it.
994
+
995
+ ```sh
996
+ moshcode client create "Acme Inc", https://acme.com, +1-555-0100
997
+ moshcode client create globex --contact.telephone +1-555-0200 --contact.name Jane
998
+ moshcode client payee acme-inc solana:9xQe… # where their payments land
999
+ ```
1000
+
1001
+ Contact details are written the way they arrive: the comma form for what you
1002
+ pasted out of a signature, `--a.b` dotted flags for anything else. There is no
1003
+ fixed field list — `--billing.po` works because it says what it means.
1004
+ `/business`, `/merchant` and `/customer` are the same command.
1005
+
1006
+ ```sh
1007
+ moshcode rate set default $100/hour/agent/upto:4
1008
+ moshcode rate set acme-inc 0.5 SOL/day --prefer SOL,USDC --accept fiat
1009
+ moshcode rate set initech $5000/project
1010
+ ```
1011
+
1012
+ `$100/hour/agent/upto:4` is the sentence from the contract, parsed: price,
1013
+ period, unit, and the cap that made the client sign. Four agents cost four
1014
+ hundred an hour and **so do six**. Order after the price does not matter.
1015
+
1016
+ ```sh
1017
+ moshcode billing acme-inc # a preview — writes nothing
1018
+ moshcode billing acme-inc --month --mark # claim the time, record the invoice
1019
+ moshcode billing acme-inc --send # compose the gateway command
1020
+ moshcode billing acme-inc --send --yes # …and run it
1021
+ ```
1022
+
1023
+ Two rules the shape enforces: time is never billed twice (an entry carries the
1024
+ invoice that claimed it, and `--mark` is the only verb that writes), and nothing
1025
+ settles to an address nobody chose — no payee and no wallet rail is a refusal,
1026
+ not a guess.
1027
+
1028
+ ```sh
1029
+ moshcode payments connect coinpay # runs `coinpay login`
1030
+ moshcode payments connect wallet --chain solana --address 9xQe… # no gateway at all
1031
+ moshcode payments connect paypal --vault profullstack--prod # keys live in the vault
1032
+ ```
1033
+
1034
+ moshcode composes an invoice; a gateway delivers it. No secret is stored here: a
1035
+ CLI gateway keeps its own session, and an OAuth gateway gets a reference to the
1036
+ vault its keys live in (`moshcode secrets`), never the keys.
1037
+
1038
+ ### Teams and grants (`/team`)
1039
+
1040
+ For a machine you handed to somebody else:
1041
+
1042
+ ```sh
1043
+ moshcode team create Profullstack
1044
+ moshcode team add profullstack preshy --role member --rate '$80/hour'
1045
+ moshcode team grant profullstack preshy tools:coinpay
1046
+ moshcode team can profullstack/preshy payments:write # → no
1047
+ ```
1048
+
1049
+ A permission is `surface:target`, written however you say it — `tools:coinpay`,
1050
+ `tools/coinpay` and `allow(tools/coinpay)` are one grant. Roles (`owner`,
1051
+ `admin`, `member`, `client`) are a starting set; grants add to them.
1052
+
1053
+ The pit gates itself only when `MOSHCODE_MEMBER=<team>/<handle>` is set — with
1054
+ it unset the owner is at the keyboard and nothing is checked. **This is a
1055
+ guardrail, not a security boundary.** moshcode runs as the person at the
1056
+ keyboard, and anyone who can type `/team` can also edit
1057
+ `~/.moshcode/business.json`. A boundary that has to hold against somebody is an
1058
+ OS account, a container, or a scoped credential.
1059
+
940
1060
  ## The arcade (`/games`)
941
1061
 
942
1062
  Twenty-two games, in the pit or straight from a shell. There are no menus, no options
package/bin/moshcode.mjs CHANGED
@@ -418,6 +418,52 @@ async function main() {
418
418
  if (code) process.exitCode = code;
419
419
  return;
420
420
  }
421
+ // The business layer. Imported where they are dispatched rather than at the
422
+ // top of the file: six modules that read two JSON files are dead weight in
423
+ // the startup path of `moshcode claude`, which is what this binary is mostly
424
+ // asked to do.
425
+ if (cmd === "timer") {
426
+ // @profullstack/timer when it is installed, the built-in otherwise. See
427
+ // src/business-delegate.mjs for why the external one wins.
428
+ const { delegate, installHint } = await import("../src/business-delegate.mjs");
429
+ const handed = await delegate("timer", rest, {});
430
+ if (handed.delegated) { process.exitCode = handed.code; return; }
431
+ const { timerCommand } = await import("../src/timer.mjs");
432
+ process.exitCode = (await timerCommand(rest)) || 0;
433
+ const hint = installHint("timer");
434
+ if (hint) process.stderr.write(`${hint}\n`);
435
+ return;
436
+ }
437
+ if (cmd === "client" || cmd === "business" || cmd === "merchant" || cmd === "customer") {
438
+ const { clientCommand } = await import("../src/clients.mjs");
439
+ process.exitCode = clientCommand(rest) || 0;
440
+ return;
441
+ }
442
+ if (cmd === "team" || cmd === "teams") {
443
+ const { teamCommand } = await import("../src/teams.mjs");
444
+ process.exitCode = teamCommand(rest) || 0;
445
+ return;
446
+ }
447
+ if (cmd === "rate" || cmd === "rates") {
448
+ const { rateCommand } = await import("../src/rates.mjs");
449
+ process.exitCode = rateCommand(rest) || 0;
450
+ return;
451
+ }
452
+ if (cmd === "billing" || cmd === "invoice") {
453
+ const { delegate, installHint } = await import("../src/business-delegate.mjs");
454
+ const handed = await delegate(cmd, rest, {});
455
+ if (handed.delegated) { process.exitCode = handed.code; return; }
456
+ const { billingCommand } = await import("../src/billing.mjs");
457
+ process.exitCode = billingCommand(rest) || 0;
458
+ const hint = installHint(cmd);
459
+ if (hint) process.stderr.write(`${hint}\n`);
460
+ return;
461
+ }
462
+ if (cmd === "payments") {
463
+ const { paymentsCommand } = await import("../src/payments.mjs");
464
+ process.exitCode = paymentsCommand(rest) || 0;
465
+ return;
466
+ }
421
467
  if (cmd === "games" || cmd === "game" || cmd === "arcade") {
422
468
  const code = await gamesCommand(rest);
423
469
  if (code) process.exitCode = code;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "moshcode",
3
- "version": "0.70.0",
3
+ "version": "0.72.0",
4
4
  "type": "module",
5
5
  "description": "moshcode — a metal wrapper for coding engines and native UGig/CoinPay workflow CLIs, with OpenPRD and moshscript",
6
6
  "repository": {
@@ -0,0 +1,13 @@
1
+ {
2
+ "$schema": "https://anthropic.com/claude-code/plugin.schema.json",
3
+ "name": "billing",
4
+ "description": "Turn tracked hours into an invoice, backed by @profullstack/billing: clients, rate cards written as contract sentences, agent-hour arithmetic, and invoices rendered to HTML you can print to PDF.",
5
+ "version": "0.1.0",
6
+ "author": {
7
+ "name": "moshcoder",
8
+ "url": "https://moshcode.sh"
9
+ },
10
+ "homepage": "https://github.com/profullstack/billing#readme",
11
+ "license": "MIT",
12
+ "keywords": ["billing", "invoice", "clients", "rates", "profullstack"]
13
+ }
@@ -0,0 +1,42 @@
1
+ # billing
2
+
3
+ Slash commands for
4
+ [`@profullstack/billing`](https://github.com/profullstack/billing) — clients,
5
+ rates and invoices, built on the hours `@profullstack/timer` tracked.
6
+
7
+ ```
8
+ /billing:rate set acme '$100/hour/agent/upto:4'
9
+ /billing:hours --client acme --month
10
+ /billing:invoice --client acme --from-timer --month
11
+ /billing:report
12
+ ```
13
+
14
+ ## Install the CLI
15
+
16
+ ```sh
17
+ npm install -g @profullstack/billing
18
+ ```
19
+
20
+ or, inside moshcode:
21
+
22
+ ```
23
+ moshcode install billing
24
+ ```
25
+
26
+ ## What it is for
27
+
28
+ A rate is the sentence from the contract, parsed. `$100/hour/agent/upto:4` means
29
+ four agents cost four hundred an hour and so do six, and the invoice bills
30
+ **agent-hours** so the client can check the line by hand: `quantity × rate`
31
+ always equals `amount`.
32
+
33
+ Two rules the shape enforces. The same hour never reaches two invoices — each
34
+ invoice records the timer entry ids it covers, so voiding one releases them.
35
+ And creating an invoice is a proposal: `--dry-run` validates the whole thing and
36
+ writes nothing, a new invoice is a draft, and nothing is ever emailed.
37
+
38
+ ## Coming from moshcode
39
+
40
+ moshcode used to keep this layer internally. `billing import` brings it across
41
+ from `~/.moshcode/business.json` and `timers.json`, shows the plan first, and
42
+ never modifies the originals.
@@ -0,0 +1,37 @@
1
+ ---
2
+ description: Tracked hours not yet on an invoice, priced at the client's rate.
3
+ argument-hint: --client <name> [--month|--week]
4
+ allowed-tools: Bash(billing hours:*), Bash(billing client:*), Bash(billing rate:*)
5
+ ---
6
+
7
+ ## Task
8
+
9
+ ```bash
10
+ billing hours $ARGUMENTS --json
11
+ ```
12
+
13
+ This is the preview of what `billing invoice new --from-timer` would bill. Same
14
+ filters, same grouping, same arithmetic — it writes nothing.
15
+
16
+ ## Reading the response
17
+
18
+ - `items[]` — the line items, each with `description`, `quantity` (in the rate's
19
+ own billing unit), `unitPriceMajor`, `amount`, `hours` and `timerIds`.
20
+ - `unit` — what `quantity` is measured in: `hours`, or `agent-hours` when the
21
+ rate is priced per agent.
22
+ - `hours` / `units` / `subtotal` — the totals.
23
+ - `skipped` — `{ running, unbillable, alreadyBilled }`.
24
+
25
+ ## Rules
26
+
27
+ - **Always read `skipped.running` back to the user.** Those hours are not
28
+ missing, they are on a clock that is still ticking and become billable the
29
+ moment it stops. "Nothing to bill" is misleading when the real answer is "stop
30
+ the clock first".
31
+ - Exit 3 means no unbilled hours matched, or the client does not exist. Read the
32
+ message; it distinguishes them.
33
+ - When `unit` is `agent-hours`, explain the multiplier if the user seems
34
+ surprised: 3 hours with 2 agents is 6 agent-hours. `quantity * unitPrice`
35
+ always equals `amount`.
36
+ - If there is no rate, the error says so and names the command that sets one.
37
+ Do not invent a rate to get past it.
@@ -0,0 +1,39 @@
1
+ ---
2
+ description: Draft an invoice from tracked time or fixed line items, for a person to approve.
3
+ argument-hint: --client <name> --from-timer --month
4
+ allowed-tools: Bash(billing invoice:*), Bash(billing hours:*), Bash(billing client:*), Bash(billing rate:*)
5
+ ---
6
+
7
+ ## Task
8
+
9
+ Propose an invoice for `$ARGUMENTS`. **Always dry-run first:**
10
+
11
+ ```bash
12
+ billing invoice new $ARGUMENTS --dry-run --json
13
+ ```
14
+
15
+ Show the user what it would create. Only run it again without `--dry-run` when
16
+ they have said to.
17
+
18
+ Line items come from `--from-timer` (tracked hours), from `--item
19
+ "Description|quantity|price"`, or both on the same invoice.
20
+
21
+ ## Rules
22
+
23
+ - **Creating an invoice is a business action. Do not write one unprompted.**
24
+ `--dry-run` builds and validates the entire invoice — the rate lookup and the
25
+ double-billing check included — so a dry run that succeeds means the real one
26
+ will. There is no reason to skip it.
27
+ - A new invoice is a **draft**. `billing invoice mark <n> sent` is a separate,
28
+ deliberate step and this tool never emails anything. Do not mark an invoice
29
+ sent or paid unless the user asked.
30
+ - Read `amounts` (decimal) when talking to a person; the bare `total` is in
31
+ minor units.
32
+ - Exit 3 on `--from-timer` means there were no unbilled hours. Check
33
+ `billing hours` and report `skipped.running` rather than concluding there is
34
+ nothing to bill.
35
+ - The same hour cannot reach two invoices: each invoice records the timer entry
36
+ ids it covers. If the user wants to re-bill something, voiding the old invoice
37
+ releases those hours.
38
+ - Prefer `billing invoice render <n> --format html --out <file>` when they want
39
+ something to send: it is one self-contained file that prints to PDF.
@@ -0,0 +1,40 @@
1
+ ---
2
+ description: Read or set what your time costs, written the way the contract says it.
3
+ argument-hint: "[set <client|default> '$100/hour/agent/upto:4']"
4
+ allowed-tools: Bash(billing rate:*), Bash(billing client:*)
5
+ ---
6
+
7
+ ## Task
8
+
9
+ ```bash
10
+ billing rate $ARGUMENTS --json
11
+ ```
12
+
13
+ With no arguments this lists every rate. `set`, `show` and `rm` take a target,
14
+ which is either a client handle or `default`.
15
+
16
+ ## The spec
17
+
18
+ A price, then any of these in any order:
19
+
20
+ - a period: `hour`, `day` (8h), `week` (40h), `month` (160h), `project`, `task`
21
+ - a unit that gets multiplied: `agent`, `seat`, `person`, `team`
22
+ - `upto:N` to cap the multiplier, `min:N` for a minimum billed period
23
+
24
+ `$100/hour/agent/upto:4` means four agents cost four hundred an hour, and so do
25
+ six. `0.5 SOL/day`, `250 USDC/task` and `$5000/project` all parse too.
26
+
27
+ ## Rules
28
+
29
+ - **Do not set or change a rate unless the user asked.** This is the number in
30
+ somebody's contract.
31
+ - Read `describes` back to them when confirming — it is the rate as a sentence,
32
+ and it is how you catch a spec that parsed differently from how it was meant.
33
+ - Settlement (`--prefer SOL --accept fiat`) is deliberately separate from the
34
+ price. The number in the contract does not change because the rail did, so do
35
+ not "convert" a rate to a preferred ticker.
36
+ - A price given in a ticker invoices in that ticker. Do not turn `0.5 SOL` into
37
+ a dollar figure: nobody computed that number.
38
+ - If a spec is rejected, the error names the words that are allowed. Fix the
39
+ spec rather than falling back to a bare number, which would silently mean
40
+ "per hour, flat".
@@ -0,0 +1,28 @@
1
+ ---
2
+ description: What has been billed, collected, and what is still owed.
3
+ argument-hint: "[--client <name>] [--year|--month]"
4
+ allowed-tools: Bash(billing report:*), Bash(billing invoice:*)
5
+ ---
6
+
7
+ ## Task
8
+
9
+ ```bash
10
+ billing report $ARGUMENTS --json
11
+ ```
12
+
13
+ ## Reading the response
14
+
15
+ - `totals` — `billed`, `collected`, `outstanding`, `overdue`, `draft`, all as
16
+ decimal numbers in `currency`.
17
+ - `byClient[]` — the same figures per client, biggest outstanding first.
18
+
19
+ ## Rules
20
+
21
+ - **`draft` is not money anybody owes you.** A draft invoice has not been
22
+ issued, so keep it out of any "you are owed X" sentence and name it
23
+ separately.
24
+ - `overdue` is derived from the due date at read time, never stored. It is a
25
+ subset of `outstanding`, not an addition to it — do not sum them.
26
+ - Windows apply to the **issue date** here, not to when the work was done.
27
+ - For the invoices behind a figure, use `billing invoice list --overdue --json`
28
+ or `--status sent`. Do not guess at which invoices make up a total.
@@ -0,0 +1,13 @@
1
+ {
2
+ "$schema": "https://anthropic.com/claude-code/plugin.schema.json",
3
+ "name": "timer",
4
+ "description": "Track time against projects from inside your engine, backed by @profullstack/timer: start and stop a clock, log time you forgot, and report billable hours with the agent count that priced them.",
5
+ "version": "0.1.0",
6
+ "author": {
7
+ "name": "moshcoder",
8
+ "url": "https://moshcode.sh"
9
+ },
10
+ "homepage": "https://github.com/profullstack/timer#readme",
11
+ "license": "MIT",
12
+ "keywords": ["timer", "time-tracking", "billable", "hours", "profullstack"]
13
+ }
@@ -0,0 +1,36 @@
1
+ # timer
2
+
3
+ Slash commands for [`@profullstack/timer`](https://github.com/profullstack/timer)
4
+ — a time tracker that runs on Linux, macOS and Windows, and answers `--json` on
5
+ every command so an agent can clock its own work.
6
+
7
+ ```
8
+ /timer:start acme fix the login redirect
9
+ /timer:status
10
+ /timer:stop
11
+ /timer:report --week --group day
12
+ ```
13
+
14
+ ## Install the CLI
15
+
16
+ ```sh
17
+ npm install -g @profullstack/timer
18
+ ```
19
+
20
+ or, inside moshcode:
21
+
22
+ ```
23
+ moshcode install timer
24
+ ```
25
+
26
+ ## What it is for
27
+
28
+ An hour of agentic work is an hour times however many engines ran in it, so an
29
+ entry carries an agent count (`--agents 4`). `@profullstack/billing` multiplies
30
+ by it when the rate says to and ignores it when the rate is flat.
31
+
32
+ Several clocks may run at once. That is deliberate: parallel agents each track
33
+ their own work and do not stop each other.
34
+
35
+ The timesheet is one JSON file at `~/.profullstack/timer/timesheet.json`, and
36
+ billing reads it directly.
@@ -0,0 +1,32 @@
1
+ ---
2
+ description: Totals for a period, grouped by project, task, day, tag or agent.
3
+ argument-hint: "[--week|--month] [--group project|task|day|tag|agent]"
4
+ allowed-tools: Bash(timer report:*), Bash(timer log:*), Bash(timer projects:*)
5
+ ---
6
+
7
+ ## Task
8
+
9
+ ```bash
10
+ timer report $ARGUMENTS --json
11
+ ```
12
+
13
+ Windows: `--today`, `--yesterday`, `--week` (from Monday), `--month`, `--year`,
14
+ or explicit `--since` / `--until`. Groups: `project` (default), `task`, `day`,
15
+ `tag`, `agent`, `none`.
16
+
17
+ ## Reading the response
18
+
19
+ `rows[]` each carry `key`, `entries`, `hours` and `billableHours`. `totals` has
20
+ the same figures for the whole window.
21
+
22
+ ## Rules
23
+
24
+ - **A window compares against the entry's start, and `--until` is exclusive.**
25
+ An entry that ran past midnight belongs to the day it began on. Say so if the
26
+ user questions a boundary rather than guessing at a bug.
27
+ - Report `hours` and `billableHours` separately whenever they differ.
28
+ - `timer log` is the command for the entries behind a number. Reach for it when
29
+ the user asks why a total looks the way it does.
30
+ - Do not convert hours into money here. The rate lives in
31
+ `@profullstack/billing`, which knows about agent multipliers and caps; a
32
+ hours-times-rate figure invented here will disagree with the invoice.
@@ -0,0 +1,33 @@
1
+ ---
2
+ description: Start the clock on a project, optionally recording how many agents are working.
3
+ argument-hint: <project> [task words…]
4
+ allowed-tools: Bash(timer start:*), Bash(timer status:*), Bash(timer on:*)
5
+ ---
6
+
7
+ ## Task
8
+
9
+ Start a clock for `$ARGUMENTS`.
10
+
11
+ ```bash
12
+ timer start $ARGUMENTS --json
13
+ ```
14
+
15
+ The first word is the project; everything after it is the task, so no quoting is
16
+ needed. Useful flags:
17
+
18
+ - `--agents N` — how many engines are working. An agent-priced rate multiplies
19
+ by this, so it is the difference between a $400 afternoon and a $1,600 one.
20
+ - `--at 09:15` or `--at -20m` — the clock you meant to start earlier.
21
+ - `--tag`, `--note`, `--no-billable`.
22
+
23
+ ## Rules
24
+
25
+ - **Do not pass `--switch` unless the user asked to stop their other clocks.**
26
+ Several clocks running at once is normal here: parallel agents each track
27
+ their own work, and stopping someone else's is not recoverable from the log.
28
+ - If `started.alsoRunning` comes back non-empty, mention how many other clocks
29
+ are running. Do not stop them.
30
+ - Report the entry id — `timer stop --id <id>` needs it, and so does the user if
31
+ they want to correct the entry later.
32
+ - If the command exits 2, the command line was wrong; read the error and fix it
33
+ rather than retrying the same thing.
@@ -0,0 +1,27 @@
1
+ ---
2
+ description: What is running right now, and what today adds up to.
3
+ allowed-tools: Bash(timer status:*), Bash(timer log:*)
4
+ ---
5
+
6
+ ## Task
7
+
8
+ ```bash
9
+ timer status --json
10
+ ```
11
+
12
+ ## Reading the response
13
+
14
+ - `running[]` — every live clock, each with `seconds` counting up to now.
15
+ - `today` — totals for entries that *started* today: `hours` and `billableHours`.
16
+ - `dataFile` — where the timesheet lives, worth quoting if the user is surprised
17
+ by what is or is not in it.
18
+
19
+ ## Rules
20
+
21
+ - An empty `running` array is a normal answer. Exit status is 0 either way, so
22
+ never report "nothing running" as a failure.
23
+ - `hours` and `billableHours` differ when something is marked `--no-billable`.
24
+ If they differ, give both — "how long did this take" and "what can I charge
25
+ for it" are different questions.
26
+ - A running clock's duration is still moving. Do not present it as a final
27
+ figure, and note that billing will not invoice it until it is stopped.
@@ -0,0 +1,30 @@
1
+ ---
2
+ description: Stop a running clock and report what it came to.
3
+ argument-hint: "[id]"
4
+ allowed-tools: Bash(timer stop:*), Bash(timer off:*), Bash(timer status:*)
5
+ ---
6
+
7
+ ## Task
8
+
9
+ Stop the clock for `$ARGUMENTS` (empty means the newest one).
10
+
11
+ ```bash
12
+ timer stop $ARGUMENTS --json
13
+ ```
14
+
15
+ Targets: nothing (the most recently started clock), an id or an unambiguous
16
+ prefix of one, `--project <p>`, or `--all`.
17
+
18
+ ## Reading the response
19
+
20
+ `stopped[]` carries `seconds`, `hours` and `agents` for each entry closed.
21
+ `hours` is the figure an invoice uses.
22
+
23
+ ## Rules
24
+
25
+ - **`stopped: []` with exit 0 means nothing was running.** That is an answer,
26
+ not a failure — say so plainly and do not retry or treat it as an error.
27
+ - Do not pass `--all` unless the user asked to stop everything. Other clocks may
28
+ belong to other agents.
29
+ - `--at` can backdate the stop, but a stop earlier than the start is refused
30
+ rather than clamped to zero. If that happens, the entry is untouched.