@sandgarden/miranda 0.1.82 → 0.1.86
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.
package/collector/stub.sh
CHANGED
|
@@ -44,15 +44,15 @@
|
|
|
44
44
|
# now downloads the same release from "sandgardenhq/plugins" with the
|
|
45
45
|
# "miranda-collector" prefix (#813). They stay placeholders rather than
|
|
46
46
|
# literals so the release host can move without editing this file.
|
|
47
|
-
BUILD_VERSION="
|
|
48
|
-
RELEASE_TAG="collector-
|
|
47
|
+
BUILD_VERSION="dfe686cb61ce"
|
|
48
|
+
RELEASE_TAG="collector-dfe686cb61ce"
|
|
49
49
|
RELEASE_REPO="sandgardenhq/plugins"
|
|
50
50
|
ASSET_PREFIX="miranda-collector"
|
|
51
|
-
CHECKSUM_DARWIN_ARM64="
|
|
52
|
-
CHECKSUM_DARWIN_X64="
|
|
53
|
-
CHECKSUM_LINUX_X64="
|
|
54
|
-
CHECKSUM_LINUX_ARM64="
|
|
55
|
-
CHECKSUM_WINDOWS_X64="
|
|
51
|
+
CHECKSUM_DARWIN_ARM64="58b322fa26b3f2b7d2d6796d7f041b03916c78bc3fe34298157d812524697adb"
|
|
52
|
+
CHECKSUM_DARWIN_X64="2de39f78f59bf4fe2482e75ccd182d30e2881400a1d3d662bcb376e54a24e1af"
|
|
53
|
+
CHECKSUM_LINUX_X64="ee4f23586c6a96b86c3a1bcc98b37568c8de3e459cd1c1616096cbe3d8c30d37"
|
|
54
|
+
CHECKSUM_LINUX_ARM64="aa93bc71849dd295817d907f20865bdda1560145b46fbcc850b6b67293bc1a62"
|
|
55
|
+
CHECKSUM_WINDOWS_X64="e4024913af817202bc83e07fb3527ce6fb8ad75527c593e64c49118c11fa63ba"
|
|
56
56
|
|
|
57
57
|
# A download lock older than this is a downloader that died mid-run: take it
|
|
58
58
|
# over (mirrors the collector's sweep-lock staleness cutoff).
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
---
|
|
2
2
|
name: setting-up-usage-tracking
|
|
3
|
-
description: Use when installing the Miranda plugin into a repo ("set up token tracking", "enable usage tracking", "install miranda"), when a repo is missing .miranda/USING-MIRANDA.md or the miranda section in CLAUDE.md/AGENTS.md, or after a Miranda plugin update to refresh a stale doc — copies the canonical USING-MIRANDA.md agent doc into the repo, wires an evergreen Miranda section into the agent instruction files (with the user's permission),
|
|
3
|
+
description: Use when installing the Miranda plugin into a repo ("set up token tracking", "enable usage tracking", "install miranda"), when a repo is missing .miranda/USING-MIRANDA.md or the miranda section in CLAUDE.md/AGENTS.md, or after a Miranda plugin update to refresh a stale doc — copies the canonical USING-MIRANDA.md agent doc into the repo, wires an evergreen Miranda section into the agent instruction files (with the user's permission), enrols this machine for usage collection, and registers the current repository as a Miranda project if it isn't one. Idempotent; safe to re-run.
|
|
4
4
|
---
|
|
5
5
|
|
|
6
6
|
# Setting Up Usage Tracking
|
|
@@ -20,10 +20,14 @@ gets collected. Two files carry that:
|
|
|
20
20
|
releases; only the doc does.
|
|
21
21
|
|
|
22
22
|
Then, once those are wired, enrol this machine so the collector daemon the
|
|
23
|
-
Miranda plugin installs actually starts reporting usage
|
|
23
|
+
Miranda plugin installs actually starts reporting usage, and make sure this
|
|
24
|
+
repository is a Miranda project — the collector attributes a session to a
|
|
25
|
+
project only when the session's `origin` remote matches one, so an
|
|
26
|
+
unregistered repository's spend all lands in **Unassigned**.
|
|
24
27
|
|
|
25
28
|
Never modify the user's files without showing them exactly what will change
|
|
26
|
-
and getting a yes first.
|
|
29
|
+
and getting a yes first. Registering the repository writes no file, and is
|
|
30
|
+
done without asking (step 6).
|
|
27
31
|
|
|
28
32
|
## What the collector reports
|
|
29
33
|
|
|
@@ -44,7 +48,7 @@ they are consenting to.
|
|
|
44
48
|
- `model_request`: the token counts already reported today
|
|
45
49
|
- `tool_call`: tool name, argument names, repo-relative file path, and a shell command's first word only, plus the names of any wrappers a hook added to it before it ran (such as `rtk`)
|
|
46
50
|
- `tool_result`: error flag, size, exit code and test counts, never the output
|
|
47
|
-
- `project_facts`: manifest and instruction file names, sizes and hashes
|
|
51
|
+
- `project_facts`: manifest and instruction file names, sizes and hashes, and the MCP server names the repo's agent config files declare
|
|
48
52
|
- `skill_invoked`: skill name and whether it came from a plugin, the project, or the user
|
|
49
53
|
- `subagent_spawned`: subagent type, model override and whether it ran in the background, never its prompt
|
|
50
54
|
- `plan_mode`: entering or leaving plan mode, never the plan
|
|
@@ -52,6 +56,7 @@ they are consenting to.
|
|
|
52
56
|
- `vcs_event`: commit, push, PR create or merge, or rebase, with PR and issue numbers only, never a branch, message or remote
|
|
53
57
|
- `hook_fired`: hook name, the first word of the hook's own command (such as `rtk`), and whether it blocked, never its arguments or output
|
|
54
58
|
- `mcp_tool_call`: MCP server and tool name, never arguments or results
|
|
59
|
+
- `machine_facts`: the MCP server names the session's agent has configured on the machine, and whether each is on, never their commands, URLs, headers or env
|
|
55
60
|
|
|
56
61
|
## The instruction-file section
|
|
57
62
|
|
|
@@ -121,7 +126,7 @@ commitment the team has made, not a suggestion.
|
|
|
121
126
|
→ the deprecated `GLORIA_HOME` → `$XDG_CONFIG_HOME/sandgarden` →
|
|
122
127
|
`~/.config/sandgarden`). `daemon status` always exits 0, so "not
|
|
123
128
|
enrolled" is not an error. Treat this as extra detail for the report in
|
|
124
|
-
step
|
|
129
|
+
step 7, not as the enrolment test — the `config.json` check above is the
|
|
125
130
|
one that has to work on every machine.
|
|
126
131
|
|
|
127
132
|
### 2. Propose and ask permission — once
|
|
@@ -137,7 +142,9 @@ yes/no. Cover only the actions actually needed, e.g.:
|
|
|
137
142
|
- enrol this machine for usage tracking, if it is not already, saying what
|
|
138
143
|
the collector reports (see "What the collector reports").
|
|
139
144
|
|
|
140
|
-
If everything is already current, say so and skip to step 6.
|
|
145
|
+
If everything is already current, say so and skip to step 6.
|
|
146
|
+
Registering the repository is not part of this yes/no — step 6 does it
|
|
147
|
+
without asking. If the user
|
|
141
148
|
declines the file edits, stop — do not partially apply.
|
|
142
149
|
|
|
143
150
|
### 3. Write the doc
|
|
@@ -272,15 +279,98 @@ this machine's local session stores whether or not any agent plugin fires, so
|
|
|
272
279
|
no further wiring is needed. See `USING-MIRANDA.md`'s "Codex, OpenCode, and
|
|
273
280
|
Cursor" section for per-agent notes.
|
|
274
281
|
|
|
275
|
-
### 6.
|
|
282
|
+
### 6. Register this repository as a project
|
|
283
|
+
|
|
284
|
+
Run this after step 5, whichever enrolment path ran — and also when steps 2–5
|
|
285
|
+
had nothing to do. Do it **without asking**: the developer is setting up
|
|
286
|
+
tracking for exactly this repository, and registering it is the only way its
|
|
287
|
+
spend stops landing in Unassigned. Use the `miranda` MCP tools only.
|
|
288
|
+
|
|
289
|
+
1. **Read the remote.** At the repo root (`git rev-parse --show-toplevel`),
|
|
290
|
+
run:
|
|
291
|
+
|
|
292
|
+
```sh
|
|
293
|
+
git remote get-url origin | sed -E 's#://[^/@]*@#://#'
|
|
294
|
+
```
|
|
295
|
+
|
|
296
|
+
The `sed` drops any userinfo (`user:token@`) before the URL is printed: an
|
|
297
|
+
`https` remote can carry a credential, and it must never reach the
|
|
298
|
+
transcript, a tool argument or the report. Use `origin` and nothing else —
|
|
299
|
+
it is the only remote the collector reads. If this isn't a git repository,
|
|
300
|
+
or the command prints nothing on stdout (no `origin` remote — git's
|
|
301
|
+
`error: No such remote` goes to stderr), skip the rest of step 6 and say
|
|
302
|
+
why in the report (e.g. "this repository has no `origin` remote, so there
|
|
303
|
+
is no URL a project could match").
|
|
304
|
+
|
|
305
|
+
2. **Normalize it** the way the server does, so the comparison means what
|
|
306
|
+
ingest means:
|
|
307
|
+
- scp-like SSH, `git@host:owner/repo.git` → `https://host/owner/repo`;
|
|
308
|
+
- `ssh://`, `git://` and `git+ssh://` URLs → `https://` on the same host
|
|
309
|
+
(port included) and path; `http://` and `https://` keep their scheme;
|
|
310
|
+
- drop any userinfo left, then a trailing `.git` (and any `/` after it),
|
|
311
|
+
then any trailing `/`.
|
|
312
|
+
|
|
313
|
+
Change nothing else — not even letter case.
|
|
314
|
+
|
|
315
|
+
3. **Look for a match.** Call `list_projects`, normalize each project's
|
|
316
|
+
`repoUrl` the same way (older rows can carry a trailing `/` or `.git`), and
|
|
317
|
+
compare exactly, case-sensitive — ingest matches the same way, so a
|
|
318
|
+
case-only difference is not a match. If a project matches, name the
|
|
319
|
+
existing project — its name and slug (all of them, if more than one
|
|
320
|
+
matches) — say spend from this repository is already attributed to it, and
|
|
321
|
+
register nothing.
|
|
322
|
+
|
|
323
|
+
4. **Register when nothing matches.** Call `register_project` with
|
|
324
|
+
`{ "project": { "slug": …, "name": …, "repoUrl": <normalized URL> } }`:
|
|
325
|
+
- `name` — the repository name: the last path segment of the normalized
|
|
326
|
+
URL (`https://github.com/sandgardenhq/gloria.dev` → `gloria.dev`);
|
|
327
|
+
- `slug` — that name lowercased, every run of characters outside `a-z0-9`
|
|
328
|
+
replaced by `-`, leading and trailing `-` trimmed (`gloria-dev`).
|
|
329
|
+
|
|
330
|
+
`register_project` **upserts by slug**: sending a slug some other project
|
|
331
|
+
already has overwrites that project's name and repository. So if
|
|
332
|
+
`list_projects` already has the slug — whatever its `repoUrl`, set or not —
|
|
333
|
+
or the slug came out empty, use `<owner>-<repo>` built the same way
|
|
334
|
+
(`sandgardenhq-gloria-dev`). `<owner>` is the path segment before the
|
|
335
|
+
repository name (for `https://gitlab.com/group/sub/repo`, `sub`). If that is
|
|
336
|
+
taken too, append a number to it — `<owner>-<repo>-2`, `-3`, … — until it
|
|
337
|
+
is free. Slugs can't be changed later, so never guess past this rule.
|
|
338
|
+
|
|
339
|
+
5. **Report what happened** in step 7, from the result's `project` and
|
|
340
|
+
`backfill`:
|
|
341
|
+
- the `slug` it registered under (and the name, when it isn't the same as
|
|
342
|
+
the slug);
|
|
343
|
+
- `backfill.status` `"ran"` with `sessionCount` above 0 — that many earlier
|
|
344
|
+
sessions moved from Unassigned onto the project, worth `spendMicros` ÷
|
|
345
|
+
1,000,000 dollars (round to cents), the earliest from `earliestSessionAt`
|
|
346
|
+
(Unix seconds; show it as a date). When `unpriced` is true, some of that
|
|
347
|
+
spend has no price yet, so the dollar figure is a lower bound — say so;
|
|
348
|
+
- `"ran"` with `sessionCount` 0 — there was no earlier Unassigned spend
|
|
349
|
+
from this repository to move;
|
|
350
|
+
- `"failed"` — the project is saved, but its earlier spend didn't move;
|
|
351
|
+
sessions from now on are attributed to it;
|
|
352
|
+
- `"skipped"` — nothing moved;
|
|
353
|
+
- in every case, spend from more than 80 days before today stays in
|
|
354
|
+
Unassigned.
|
|
355
|
+
|
|
356
|
+
If `list_projects` or `register_project` fails with a transient error (a
|
|
357
|
+
dropped connection, a timeout), retry it once. If it still fails, or the
|
|
358
|
+
`miranda` MCP server isn't connected, or the call returns an error — say so,
|
|
359
|
+
with the error, and carry on to the report. It doesn't undo the file edits or the enrolment.
|
|
360
|
+
|
|
361
|
+
### 7. Report
|
|
276
362
|
|
|
277
363
|
Summarize what changed (files created/updated, section inserted where,
|
|
278
|
-
usage tracking configured or already present
|
|
279
|
-
|
|
364
|
+
usage tracking configured or already present, the project registered or
|
|
365
|
+
matched — or why the step was skipped — with what step 6 moved) and suggest
|
|
366
|
+
committing the changes, e.g. `chore: wire miranda agent doc into instruction
|
|
367
|
+
files`.
|
|
280
368
|
|
|
281
369
|
## Idempotency rules
|
|
282
370
|
|
|
283
371
|
- Re-running with identical content is a no-op; say "already current".
|
|
372
|
+
- Re-running in a repository that is already a project registers nothing:
|
|
373
|
+
step 6 finds the match and names it.
|
|
284
374
|
- Marker blocks are always replaced in place, never duplicated. If a file
|
|
285
375
|
somehow contains multiple marker blocks, replace the first and remove the
|
|
286
376
|
rest, and mention it.
|
|
@@ -13,7 +13,8 @@ Miranda is available two ways, and both apply to you:
|
|
|
13
13
|
`get_my_effectiveness`, `get_my_workflow`, `get_my_tracking_status`,
|
|
14
14
|
`assign_my_session_work_item`, the managers-only `get_team_effectiveness`,
|
|
15
15
|
plus the shared
|
|
16
|
-
`get_info`/`register_project`/`put_project_github_info` —
|
|
16
|
+
`get_info`/`list_projects`/`register_project`/`put_project_github_info` —
|
|
17
|
+
the same rows the
|
|
17
18
|
`gloria` server exposes, since Miranda and gloria share one database).
|
|
18
19
|
- **The usage-collector hooks** installed with the Miranda plugin (Claude
|
|
19
20
|
Code, Codex, OpenCode) — they run automatically once the collector's
|
|
@@ -120,6 +121,28 @@ flight. The collector's `gloria-usage session` subcommand will answer that
|
|
|
120
121
|
locally, with no round-trip, once it ships; until then, say the current
|
|
121
122
|
session's cost isn't available yet rather than estimating it.
|
|
122
123
|
|
|
124
|
+
## When this repository isn't a project
|
|
125
|
+
|
|
126
|
+
Miranda attributes a session to a project only when the session's `origin`
|
|
127
|
+
remote matches a registered project's `repoUrl`; everything else lands in
|
|
128
|
+
**Unassigned**, where no per-project or per-issue figure can see it. So when a
|
|
129
|
+
Miranda tool result shows this repository isn't a project — `list_projects`
|
|
130
|
+
has no project whose `repoUrl` matches this repository's `origin`, or
|
|
131
|
+
`get_my_tracking_status` or `get_my_spend` puts this repository's sessions in
|
|
132
|
+
Unassigned — register it, **without asking**. Registering is part of tracking
|
|
133
|
+
this repository, which the team has already adopted.
|
|
134
|
+
|
|
135
|
+
Follow the `setting-up-usage-tracking` skill's "Register this repository as a
|
|
136
|
+
project" step: read `origin` with
|
|
137
|
+
`git remote get-url origin | sed -E 's#://[^/@]*@#://#'` (the `sed` keeps a
|
|
138
|
+
token embedded in the remote out of the transcript), normalize it (SSH forms
|
|
139
|
+
to `https://`, no userinfo, no `.git` or trailing `/`), compare it against
|
|
140
|
+
every project's `repoUrl` normalized the same way, and when nothing matches, call `register_project` with the repository's name
|
|
141
|
+
and a slug no existing project has. Then tell the user the slug and what the
|
|
142
|
+
result's `backfill` moved out of Unassigned (sessions, dollars, earliest
|
|
143
|
+
session). Spend older than 80 days stays in Unassigned. No `origin` remote
|
|
144
|
+
means nothing to match — say so and move on.
|
|
145
|
+
|
|
123
146
|
## Setting up usage tracking
|
|
124
147
|
|
|
125
148
|
The Miranda plugin ships hooks (Claude Code, Codex, OpenCode) that transmit
|
|
@@ -138,8 +161,13 @@ Reads need `inventory:read` (any member); writes need `inventory:write`.
|
|
|
138
161
|
|
|
139
162
|
- `get_info` — org id/name/slug. Cheap; call it first when you need org
|
|
140
163
|
context or to check the `miranda` MCP server is reachable.
|
|
164
|
+
- `list_projects` — every project in the org, with its `repoUrl`. How you
|
|
165
|
+
tell whether this repository is a project yet.
|
|
141
166
|
- `register_project`, `put_project_github_info` — register this repo as a
|
|
142
|
-
gloria.dev/Miranda project (the same rows either server writes).
|
|
167
|
+
gloria.dev/Miranda project (the same rows either server writes). Upserts by
|
|
168
|
+
slug, so never send a slug another project already has. When it gives a
|
|
169
|
+
project a `repoUrl`, its `backfill` reports the repository's earlier
|
|
170
|
+
Unassigned spend that moved onto it.
|
|
143
171
|
- `tag_session_work_item` — declare the GitHub issue this session is working
|
|
144
172
|
on (bare issue number, `gh:482`, or a full issue URL). Session-local — it
|
|
145
173
|
writes only to this session's own transcript, never the database — the
|