@theplato/tiro-cli 0.4.0 → 0.4.1
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/AGENTS.md +12 -23
- package/README.md +2 -2
- package/dist/bin/tiro.js +16 -11
- package/package.json +1 -1
package/AGENTS.md
CHANGED
|
@@ -89,26 +89,15 @@ Two ways to authenticate:
|
|
|
89
89
|
The CLI never prints tokens to stdout. `tiro auth status` shows only the
|
|
90
90
|
first 4 characters of the access token.
|
|
91
91
|
|
|
92
|
-
## Security
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
| **H4** | `lib/config.ts` `getOauthClientId` | DCR `client_id` cache is bound to the hostname it was registered against; a swapped hostname misses the cache. |
|
|
105
|
-
| **M1** | `lib/output/file.ts` `assertSafeOutputPath` | `--output` rejects `..` segments unless `--force`; an agent forwarding untrusted input cannot escape its scope. |
|
|
106
|
-
| **M2** | `lib/auth/token.ts` `decodeJwtPayload` | Documented as display-only — claims must never gate auth, scope, identity, or expiry decisions. |
|
|
107
|
-
|
|
108
|
-
Pre-deploy checklist:
|
|
109
|
-
|
|
110
|
-
1. `npm run typecheck`
|
|
111
|
-
2. `npm run test:security` (regression gate)
|
|
112
|
-
3. `npm test` (full suite)
|
|
113
|
-
4. `npm run build`
|
|
114
|
-
5. Smoke: `node dist/bin/tiro.js auth status`
|
|
92
|
+
## Security posture (summary)
|
|
93
|
+
|
|
94
|
+
- OAuth uses Authorization Code + PKCE with a CSRF-checked loopback
|
|
95
|
+
redirect. Tokens are held in the OS keychain or `TIRO_TOKEN` only —
|
|
96
|
+
never written to stdout, stderr, or disk in any other form.
|
|
97
|
+
- `TIRO_HOSTNAME` / `--hostname` are validated against an `https://` (or
|
|
98
|
+
loopback) allowlist before any OAuth or API request runs.
|
|
99
|
+
- `--output` paths that escape the working tree require `--force`.
|
|
100
|
+
- A dedicated regression suite (`npm run test:security`) pins these
|
|
101
|
+
surfaces and runs in `prepublishOnly` — a broken defense blocks publish.
|
|
102
|
+
|
|
103
|
+
Always run on the latest released version; older versions are deprecated.
|
package/README.md
CHANGED
|
@@ -108,7 +108,7 @@ tiro notes list
|
|
|
108
108
|
```bash
|
|
109
109
|
tiro notes list # pretty table in TTY
|
|
110
110
|
tiro notes list --json # NDJSON for pipes
|
|
111
|
-
tiro notes list --keyword "OKR" --since 30d #
|
|
111
|
+
tiro notes list --keyword "OKR" --since 30d # Reorder by keyword relevance
|
|
112
112
|
tiro notes list --folder <id> --limit 100 --cursor <token>
|
|
113
113
|
```
|
|
114
114
|
|
|
@@ -287,7 +287,7 @@ The CLI sits on the public Tiro API alongside the MCP server, sharing the same O
|
|
|
287
287
|
|
|
288
288
|
```
|
|
289
289
|
┌──────────────────────────────┐
|
|
290
|
-
│ Tiro Backend
|
|
290
|
+
│ Tiro Backend │
|
|
291
291
|
│ /v1/external/* + /v1/mcp/* │
|
|
292
292
|
└──────────────┬────────────────┘
|
|
293
293
|
│
|
package/dist/bin/tiro.js
CHANGED
|
@@ -1198,17 +1198,18 @@ Examples:
|
|
|
1198
1198
|
tiro notes list --folder <id> --limit 50
|
|
1199
1199
|
|
|
1200
1200
|
Keyword matching:
|
|
1201
|
-
--keyword reorders results by
|
|
1202
|
-
|
|
1203
|
-
|
|
1204
|
-
by
|
|
1201
|
+
--keyword reorders results by full-text relevance over title and
|
|
1202
|
+
paragraph content (case-insensitive), with createdAt desc as tiebreaker
|
|
1203
|
+
when scores are close. When --keyword is set, nextCursor is always null.
|
|
1204
|
+
Without --keyword, results are ordered by recording time desc (falls back
|
|
1205
|
+
to createdAt for memo-only notes).
|
|
1205
1206
|
|
|
1206
1207
|
Note: placeholder notes (title='Untitled' or sourceType='onboarding') are
|
|
1207
1208
|
filtered out by default. A page of N may return fewer than N visible notes \u2014
|
|
1208
1209
|
keep paginating to fetch more, or pass --include-untitled to surface them.
|
|
1209
1210
|
`;
|
|
1210
1211
|
function registerNotesList(parent) {
|
|
1211
|
-
parent.command("list").description("List notes (lightweight metadata).").option("--keyword <text>", 'Reorder by
|
|
1212
|
+
parent.command("list").description("List notes (lightweight metadata).").option("--keyword <text>", 'Reorder by full-text relevance for this keyword (e.g. "OKR")').option("--folder <id>", "Restrict to a folder and its descendants").option(
|
|
1212
1213
|
"--since <date>",
|
|
1213
1214
|
"Inclusive lower bound on createdAt (ISO-8601 or relative: 7d, 24h, 30m)"
|
|
1214
1215
|
).option("--until <date>", "Exclusive upper bound on createdAt").option(
|
|
@@ -1307,12 +1308,16 @@ Examples:
|
|
|
1307
1308
|
tiro notes search "release" --since 2026-04-01 --until 2026-05-01
|
|
1308
1309
|
|
|
1309
1310
|
Keyword matching:
|
|
1310
|
-
Full-text against note title + paragraph content
|
|
1311
|
-
|
|
1312
|
-
|
|
1313
|
-
|
|
1314
|
-
|
|
1315
|
-
|
|
1311
|
+
Full-text search against note title + paragraph content. Case-insensitive.
|
|
1312
|
+
Multi-word keywords are tokenized \u2014 "OKR planning" matches notes containing
|
|
1313
|
+
both terms. The deep search variant (this command) hydrates each result
|
|
1314
|
+
with its primary documents (one-pager, custom) so an MCP/LLM client can
|
|
1315
|
+
read content alongside metadata in one call.
|
|
1316
|
+
|
|
1317
|
+
Ordering:
|
|
1318
|
+
Results are sorted by full-text relevance, then createdAt desc as
|
|
1319
|
+
tiebreaker. Without --limit, the server returns 50 results (capped
|
|
1320
|
+
at 200). Pass --limit to override.
|
|
1316
1321
|
|
|
1317
1322
|
Note: placeholder notes (title='Untitled' or sourceType='onboarding') are
|
|
1318
1323
|
filtered out by default. Pass --include-untitled to surface them.
|