@theplato/tiro-cli 0.2.0 → 0.2.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/dist/bin/tiro.js +172 -24
- package/dist/bin/tiro.js.map +1 -1
- package/package.json +2 -1
package/dist/bin/tiro.js
CHANGED
|
@@ -175,8 +175,8 @@ async function startLoopbackServer() {
|
|
|
175
175
|
);
|
|
176
176
|
if (pendingResolve) settle(pendingResolve, { code, state });
|
|
177
177
|
});
|
|
178
|
-
await new Promise((
|
|
179
|
-
server.listen(0, "127.0.0.1", () =>
|
|
178
|
+
await new Promise((resolve3) => {
|
|
179
|
+
server.listen(0, "127.0.0.1", () => resolve3());
|
|
180
180
|
});
|
|
181
181
|
const address = server.address();
|
|
182
182
|
const port = address.port;
|
|
@@ -185,7 +185,7 @@ async function startLoopbackServer() {
|
|
|
185
185
|
redirectUri,
|
|
186
186
|
port,
|
|
187
187
|
waitForCallback(timeoutMs) {
|
|
188
|
-
return new Promise((
|
|
188
|
+
return new Promise((resolve3, reject) => {
|
|
189
189
|
const timer = setTimeout(() => {
|
|
190
190
|
pendingResolve = null;
|
|
191
191
|
pendingReject = null;
|
|
@@ -193,7 +193,7 @@ async function startLoopbackServer() {
|
|
|
193
193
|
}, timeoutMs);
|
|
194
194
|
pendingResolve = (r) => {
|
|
195
195
|
clearTimeout(timer);
|
|
196
|
-
|
|
196
|
+
resolve3(r);
|
|
197
197
|
};
|
|
198
198
|
pendingReject = (e) => {
|
|
199
199
|
clearTimeout(timer);
|
|
@@ -971,15 +971,49 @@ function invalidDate(input) {
|
|
|
971
971
|
);
|
|
972
972
|
}
|
|
973
973
|
|
|
974
|
+
// src/lib/util/noteFilter.ts
|
|
975
|
+
var PLACEHOLDER_TITLE = "Untitled";
|
|
976
|
+
var PLACEHOLDER_SOURCE_TYPES = /* @__PURE__ */ new Set(["onboarding"]);
|
|
977
|
+
function isVisibleNote(note) {
|
|
978
|
+
if (note.title === PLACEHOLDER_TITLE) return false;
|
|
979
|
+
if (note.sourceType !== null && note.sourceType !== void 0 && PLACEHOLDER_SOURCE_TYPES.has(note.sourceType)) {
|
|
980
|
+
return false;
|
|
981
|
+
}
|
|
982
|
+
return true;
|
|
983
|
+
}
|
|
984
|
+
|
|
974
985
|
// src/commands/notes/list.ts
|
|
975
986
|
var ListResponseSchema = PageCursorResponseSchema(NoteSchema);
|
|
976
987
|
var DEFAULT_PAGE_SIZE = 100;
|
|
977
988
|
var MAX_PAGE_SIZE = 1e3;
|
|
989
|
+
var HELP_AFTER = `
|
|
990
|
+
Examples:
|
|
991
|
+
tiro notes list --since 7d
|
|
992
|
+
tiro notes list --keyword "OKR" --since 30d --json
|
|
993
|
+
tiro notes list --folder <id> --limit 50
|
|
994
|
+
|
|
995
|
+
Keyword matching:
|
|
996
|
+
--keyword reorders results by OpenSearch relevance (case-insensitive,
|
|
997
|
+
full-text against note title and paragraph content). When --keyword is
|
|
998
|
+
set, nextCursor is always null. Without --keyword, results are ordered
|
|
999
|
+
by createdAt desc.
|
|
1000
|
+
|
|
1001
|
+
Note: placeholder notes (title='Untitled' or sourceType='onboarding') are
|
|
1002
|
+
filtered out by default. A page of N may return fewer than N visible notes \u2014
|
|
1003
|
+
keep paginating to fetch more, or pass --include-untitled to surface them.
|
|
1004
|
+
`;
|
|
978
1005
|
function registerNotesList(parent) {
|
|
979
|
-
parent.command("list").description("List notes (lightweight metadata)").option("--keyword <text>",
|
|
1006
|
+
parent.command("list").description("List notes (lightweight metadata).").option("--keyword <text>", 'Reorder by OpenSearch relevance for this keyword (e.g. "OKR")').option("--folder <id>", "Restrict to a folder and its descendants").option(
|
|
1007
|
+
"--since <date>",
|
|
1008
|
+
"Inclusive lower bound on createdAt (ISO-8601 or relative: 7d, 24h, 30m)"
|
|
1009
|
+
).option("--until <date>", "Exclusive upper bound on createdAt").option(
|
|
980
1010
|
"--limit <n>",
|
|
981
|
-
`
|
|
982
|
-
).option("--cursor <token>", "
|
|
1011
|
+
`Max results per page (default ${DEFAULT_PAGE_SIZE}, max ${MAX_PAGE_SIZE})`
|
|
1012
|
+
).option("--cursor <token>", "Continue a previous page").option(
|
|
1013
|
+
"--include-untitled",
|
|
1014
|
+
"Include placeholder notes (title='Untitled' or sourceType='onboarding'). Default: hidden",
|
|
1015
|
+
false
|
|
1016
|
+
).addHelpText("after", HELP_AFTER).action(async (opts, cmd) => {
|
|
983
1017
|
const globalOpts = cmd.optsWithGlobals();
|
|
984
1018
|
const client = createApiClient({
|
|
985
1019
|
...globalOpts.hostname !== void 0 && { hostnameOverride: globalOpts.hostname }
|
|
@@ -993,12 +1027,13 @@ function registerNotesList(parent) {
|
|
|
993
1027
|
if (size !== void 0) params["size"] = size;
|
|
994
1028
|
if (opts.cursor) params["cursor"] = opts.cursor;
|
|
995
1029
|
const res = await client.getJson("/v1/external/notes", ListResponseSchema, params);
|
|
1030
|
+
const visible = opts.includeUntitled === true ? res.content : res.content.filter(isVisibleNote);
|
|
996
1031
|
const mode = resolveOutputMode(globalOpts);
|
|
997
1032
|
if (mode === "json") {
|
|
998
|
-
for (const note of
|
|
1033
|
+
for (const note of visible) printNdjson(note);
|
|
999
1034
|
if (res.nextCursor) printNdjson({ _cursor: res.nextCursor });
|
|
1000
1035
|
} else {
|
|
1001
|
-
printPretty(
|
|
1036
|
+
printPretty(visible, res.nextCursor, globalOpts);
|
|
1002
1037
|
}
|
|
1003
1038
|
});
|
|
1004
1039
|
}
|
|
@@ -1054,8 +1089,41 @@ import "commander";
|
|
|
1054
1089
|
var SearchResponseSchema = PageCursorResponseSchema(NoteSchema).passthrough();
|
|
1055
1090
|
var DEFAULT_PAGE_SIZE2 = 100;
|
|
1056
1091
|
var MAX_PAGE_SIZE2 = 1e3;
|
|
1092
|
+
var HELP_AFTER2 = `
|
|
1093
|
+
Examples:
|
|
1094
|
+
tiro notes search "Q3 Planning"
|
|
1095
|
+
tiro notes search "Acme Corp" --since 7d --json
|
|
1096
|
+
tiro notes search "release" --since 2026-04-01 --until 2026-05-01
|
|
1097
|
+
|
|
1098
|
+
Keyword matching:
|
|
1099
|
+
Full-text against note title + paragraph content via OpenSearch.
|
|
1100
|
+
Case-insensitive. Multi-word keywords are tokenized \u2014 "OKR planning"
|
|
1101
|
+
matches notes containing both terms. The deep search variant (this
|
|
1102
|
+
command) hydrates each result with its primary documents (one-pager,
|
|
1103
|
+
custom) so an MCP/LLM client can read content alongside metadata in
|
|
1104
|
+
one call.
|
|
1105
|
+
|
|
1106
|
+
Note: placeholder notes (title='Untitled' or sourceType='onboarding') are
|
|
1107
|
+
filtered out by default. Pass --include-untitled to surface them.
|
|
1108
|
+
`;
|
|
1057
1109
|
function registerNotesSearch(parent) {
|
|
1058
|
-
parent.command("search [keyword]").description("Deep keyword search \u2014 returns notes hydrated with their primary documents
|
|
1110
|
+
parent.command("search [keyword]").description("Deep keyword search \u2014 returns notes hydrated with their primary documents.").option(
|
|
1111
|
+
"--keyword <text>",
|
|
1112
|
+
'Alternative to positional keyword (e.g. --keyword "Q3 Planning")'
|
|
1113
|
+
).option("--folder <id>", "Restrict hits to a folder and its descendants").option(
|
|
1114
|
+
"--since <date>",
|
|
1115
|
+
"Inclusive lower bound on createdAt (ISO-8601 or relative: 7d, 24h, 30m)"
|
|
1116
|
+
).option("--until <date>", "Exclusive upper bound on createdAt").option(
|
|
1117
|
+
"--limit <n>",
|
|
1118
|
+
`Max results per page (default ${DEFAULT_PAGE_SIZE2}, max ${MAX_PAGE_SIZE2})`
|
|
1119
|
+
).option(
|
|
1120
|
+
"--cursor <token>",
|
|
1121
|
+
"Continue a previous page (reserved \u2014 backend currently always null)"
|
|
1122
|
+
).option(
|
|
1123
|
+
"--include-untitled",
|
|
1124
|
+
"Include placeholder notes. Default: hidden",
|
|
1125
|
+
false
|
|
1126
|
+
).addHelpText("after", HELP_AFTER2).action(async (positional, opts, cmd) => {
|
|
1059
1127
|
const globalOpts = cmd.optsWithGlobals();
|
|
1060
1128
|
const keyword = (positional ?? opts.keyword ?? "").trim();
|
|
1061
1129
|
if (!keyword) {
|
|
@@ -1088,12 +1156,13 @@ function registerNotesSearch(parent) {
|
|
|
1088
1156
|
SearchResponseSchema,
|
|
1089
1157
|
body
|
|
1090
1158
|
);
|
|
1159
|
+
const visible = opts.includeUntitled === true ? res.content : res.content.filter(isVisibleNote);
|
|
1091
1160
|
const mode = resolveOutputMode(globalOpts);
|
|
1092
1161
|
if (mode === "json") {
|
|
1093
|
-
for (const note of
|
|
1162
|
+
for (const note of visible) printNdjson(note);
|
|
1094
1163
|
if (res.nextCursor) printNdjson({ _cursor: res.nextCursor });
|
|
1095
1164
|
} else {
|
|
1096
|
-
printPretty2(
|
|
1165
|
+
printPretty2(visible, res.nextCursor, globalOpts);
|
|
1097
1166
|
}
|
|
1098
1167
|
});
|
|
1099
1168
|
}
|
|
@@ -1329,11 +1398,24 @@ var ALLOWED_INCLUDES = /* @__PURE__ */ new Set(["transcript"]);
|
|
|
1329
1398
|
var ParagraphsListSchema = SimpleListResponseSchema(ParagraphSchema);
|
|
1330
1399
|
var ParagraphsCursorSchema = PageCursorResponseSchema(ParagraphSchema);
|
|
1331
1400
|
function registerNotesGet(parent) {
|
|
1332
|
-
parent.command("get <guid>").description("Get a single note
|
|
1401
|
+
parent.command("get <guid>").description("Get a single note. Outputs to stdout, or saves to a file with --output.").option("--output <path>", "Write to file (stdout becomes a single metadata line)").option(
|
|
1402
|
+
"--format <md|json|txt>",
|
|
1403
|
+
"Output format (default: md for TTY, json when piped)"
|
|
1404
|
+
).option(
|
|
1333
1405
|
"--include <items>",
|
|
1334
|
-
"Comma-separated extras (v0.2
|
|
1406
|
+
"Comma-separated extras (v0.2 supports: transcript)",
|
|
1335
1407
|
""
|
|
1336
|
-
).option("--force", "Overwrite existing file").
|
|
1408
|
+
).option("--force", "Overwrite existing file at --output path").addHelpText("after", `
|
|
1409
|
+
Examples:
|
|
1410
|
+
tiro notes get <guid> # markdown to stdout
|
|
1411
|
+
tiro notes get <guid> --include transcript # add speaker-attributed paragraphs
|
|
1412
|
+
tiro notes get <guid> --output ./meeting.md --include transcript
|
|
1413
|
+
tiro notes get <guid> --format json # JSON to stdout
|
|
1414
|
+
|
|
1415
|
+
Tip for agents: prefer --output <path>. The actual content goes to disk
|
|
1416
|
+
and stdout collapses to a single metadata line, keeping your context
|
|
1417
|
+
window light.
|
|
1418
|
+
`).action(async (guid, opts, cmd) => {
|
|
1337
1419
|
const globalOpts = cmd.optsWithGlobals();
|
|
1338
1420
|
const includes = parseIncludes(opts.include);
|
|
1339
1421
|
validateIncludes(includes);
|
|
@@ -1463,10 +1545,21 @@ import "commander";
|
|
|
1463
1545
|
var ParagraphsListSchema2 = SimpleListResponseSchema(ParagraphSchema);
|
|
1464
1546
|
var ParagraphsCursorSchema2 = PageCursorResponseSchema(ParagraphSchema);
|
|
1465
1547
|
function registerNotesTranscript(parent) {
|
|
1466
|
-
parent.command("transcript <guid>").description(
|
|
1548
|
+
parent.command("transcript <guid>").description(
|
|
1549
|
+
"Get the full transcript of a note as speaker-attributed paragraphs.\nJSON output matches MCP get_note_transcript shape exactly."
|
|
1550
|
+
).option("--output <path>", "Write to file (stdout = single metadata line)").option(
|
|
1467
1551
|
"--format <md|json|txt>",
|
|
1468
|
-
"Output format (default: md
|
|
1469
|
-
).option("--force", "Overwrite existing file").
|
|
1552
|
+
"Output format (default: md if TTY, txt when piped; json mirrors MCP)"
|
|
1553
|
+
).option("--force", "Overwrite existing file at --output path").addHelpText("after", `
|
|
1554
|
+
Examples:
|
|
1555
|
+
tiro notes transcript <guid> # md in TTY, txt in pipe
|
|
1556
|
+
tiro notes transcript <guid> --format md --output ./t.md
|
|
1557
|
+
tiro notes transcript <guid> --format json # MCP-shape JSON
|
|
1558
|
+
tiro notes transcript <guid> --format txt --output ./embed.txt
|
|
1559
|
+
|
|
1560
|
+
The --format json output is byte-for-byte identical to MCP's
|
|
1561
|
+
get_note_transcript so agents can swap surfaces without changing parsers.
|
|
1562
|
+
`).action(async (guid, opts, cmd) => {
|
|
1470
1563
|
const globalOpts = cmd.optsWithGlobals();
|
|
1471
1564
|
const format = pickFormat2(opts.format, opts.output, globalOpts);
|
|
1472
1565
|
const client = createApiClient({
|
|
@@ -1560,21 +1653,74 @@ function registerNotes(program) {
|
|
|
1560
1653
|
registerNotesTranscript(notes);
|
|
1561
1654
|
}
|
|
1562
1655
|
|
|
1656
|
+
// src/lib/updateCheck.ts
|
|
1657
|
+
import updateNotifier from "update-notifier";
|
|
1658
|
+
import { readFile } from "fs/promises";
|
|
1659
|
+
import { fileURLToPath } from "url";
|
|
1660
|
+
import { dirname as dirname2, resolve as resolve2 } from "path";
|
|
1661
|
+
var HERE = dirname2(fileURLToPath(import.meta.url));
|
|
1662
|
+
var CANDIDATE_PATHS = [
|
|
1663
|
+
resolve2(HERE, "../../package.json"),
|
|
1664
|
+
resolve2(HERE, "../../../package.json")
|
|
1665
|
+
];
|
|
1666
|
+
var ONE_DAY_MS = 24 * 60 * 60 * 1e3;
|
|
1667
|
+
async function startUpdateCheck() {
|
|
1668
|
+
if (process.env["NO_UPDATE_NOTIFIER"] === "1") return null;
|
|
1669
|
+
if (process.env["CI"]) return null;
|
|
1670
|
+
if (process.stdout.isTTY !== true) return null;
|
|
1671
|
+
const pkg = await loadPkg();
|
|
1672
|
+
if (!pkg) return null;
|
|
1673
|
+
try {
|
|
1674
|
+
const factory = updateNotifier;
|
|
1675
|
+
return factory({
|
|
1676
|
+
pkg,
|
|
1677
|
+
updateCheckInterval: ONE_DAY_MS,
|
|
1678
|
+
shouldNotifyInNpmScript: false
|
|
1679
|
+
});
|
|
1680
|
+
} catch {
|
|
1681
|
+
return null;
|
|
1682
|
+
}
|
|
1683
|
+
}
|
|
1684
|
+
function emitUpdateBanner(notifier) {
|
|
1685
|
+
if (!notifier) return;
|
|
1686
|
+
if (!notifier.update) return;
|
|
1687
|
+
notifier.notify({
|
|
1688
|
+
isGlobal: true,
|
|
1689
|
+
defer: false,
|
|
1690
|
+
message: "Update available {currentVersion} \u2192 {latestVersion}\nRun npm install -g {packageName} to update\n\nChangelog: https://www.npmjs.com/package/{packageName}?activeTab=versions"
|
|
1691
|
+
});
|
|
1692
|
+
}
|
|
1693
|
+
async function loadPkg() {
|
|
1694
|
+
for (const path of CANDIDATE_PATHS) {
|
|
1695
|
+
try {
|
|
1696
|
+
const raw = await readFile(path, "utf8");
|
|
1697
|
+
const parsed = JSON.parse(raw);
|
|
1698
|
+
if (typeof parsed.name === "string" && typeof parsed.version === "string" && parsed.name.length > 0 && parsed.version.length > 0) {
|
|
1699
|
+
return { name: parsed.name, version: parsed.version };
|
|
1700
|
+
}
|
|
1701
|
+
} catch {
|
|
1702
|
+
}
|
|
1703
|
+
}
|
|
1704
|
+
return null;
|
|
1705
|
+
}
|
|
1706
|
+
|
|
1563
1707
|
// src/bin/tiro.ts
|
|
1564
1708
|
var EXAMPLES = `
|
|
1565
1709
|
EXAMPLES
|
|
1566
1710
|
$ tiro auth login
|
|
1567
|
-
$ tiro notes
|
|
1711
|
+
$ tiro notes list --since 7d
|
|
1712
|
+
$ tiro notes search "Q3 Planning" --since 30d --json
|
|
1568
1713
|
$ tiro notes get <guid> --output ./meeting.md --include transcript
|
|
1569
|
-
$ tiro notes transcript <guid> --format
|
|
1714
|
+
$ tiro notes transcript <guid> --format md --output ./transcript.md
|
|
1570
1715
|
|
|
1571
1716
|
ENVIRONMENT
|
|
1572
|
-
TIRO_TOKEN
|
|
1573
|
-
TIRO_HOSTNAME
|
|
1574
|
-
NO_COLOR
|
|
1717
|
+
TIRO_TOKEN Bearer token (overrides keychain \u2014 for CI / agents)
|
|
1718
|
+
TIRO_HOSTNAME API base URL (default: https://api.tiro.ooo)
|
|
1719
|
+
NO_COLOR Disable colors (https://no-color.org)
|
|
1720
|
+
NO_UPDATE_NOTIFIER Set to "1" to disable the update banner
|
|
1575
1721
|
|
|
1576
1722
|
DOCS
|
|
1577
|
-
https://api.tiro.ooo/cli
|
|
1723
|
+
https://api-docs.tiro.ooo/cli/overview
|
|
1578
1724
|
`;
|
|
1579
1725
|
function buildProgram() {
|
|
1580
1726
|
const program = new Command10();
|
|
@@ -1586,8 +1732,10 @@ function buildProgram() {
|
|
|
1586
1732
|
}
|
|
1587
1733
|
async function main() {
|
|
1588
1734
|
const program = buildProgram();
|
|
1735
|
+
const notifier = await startUpdateCheck();
|
|
1589
1736
|
try {
|
|
1590
1737
|
await program.parseAsync(process.argv);
|
|
1738
|
+
emitUpdateBanner(notifier);
|
|
1591
1739
|
} catch (err) {
|
|
1592
1740
|
handleError(err, program);
|
|
1593
1741
|
}
|
package/dist/bin/tiro.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../../src/bin/tiro.ts","../../src/lib/version.ts","../../src/lib/error.ts","../../src/lib/output/tty.ts","../../src/lib/output/print.ts","../../src/commands/auth/index.ts","../../src/commands/auth/login.ts","../../src/lib/auth/flow.ts","../../src/lib/auth/pkce.ts","../../src/lib/auth/loopback.ts","../../src/lib/auth/browser.ts","../../src/lib/auth/keychain.ts","../../src/lib/auth/token.ts","../../src/lib/config.ts","../../src/commands/auth/status.ts","../../src/commands/auth/logout.ts","../../src/commands/notes/index.ts","../../src/commands/notes/list.ts","../../src/lib/api/client.ts","../../src/lib/api/types.ts","../../src/lib/util/parseDate.ts","../../src/commands/notes/search.ts","../../src/commands/notes/get.ts","../../src/lib/output/file.ts","../../src/lib/output/transcript.ts","../../src/lib/output/format.ts","../../src/commands/notes/transcript.ts"],"sourcesContent":["import { Command } from \"commander\";\nimport { VERSION } from \"../lib/version.ts\";\nimport { TiroError, ExitCode } from \"../lib/error.ts\";\nimport { printError } from \"../lib/output/print.ts\";\nimport { color } from \"../lib/output/tty.ts\";\nimport { registerAuth } from \"../commands/auth/index.ts\";\nimport { registerNotes } from \"../commands/notes/index.ts\";\n\nconst EXAMPLES = `\nEXAMPLES\n $ tiro auth login\n $ tiro notes search --speaker \"김철수\" --since 7d --json\n $ tiro notes get <guid> --output ./meeting.md --include transcript\n $ tiro notes transcript <guid> --format txt\n\nENVIRONMENT\n TIRO_TOKEN Bearer token (overrides keychain)\n TIRO_HOSTNAME API base URL (default: https://api.tiro.ooo)\n NO_COLOR Disable colors\n\nDOCS\n https://api.tiro.ooo/cli\n`;\n\nfunction buildProgram(): Command {\n const program = new Command();\n\n program\n .name(\"tiro\")\n .description(\"Tiro AI notes & transcripts — agent-first command line\")\n .version(VERSION, \"-v, --version\", \"Print version\")\n .option(\"--hostname <url>\", \"API base URL (default: https://api.tiro.ooo)\")\n .option(\"--json\", \"Force JSON output\")\n .option(\"--pretty\", \"Force pretty (human) output\")\n .option(\"--quiet\", \"Suppress non-error output\")\n .option(\"--verbose\", \"Verbose logging to stderr\")\n .option(\"--no-color\", \"Disable ANSI colors\")\n .addHelpText(\"after\", EXAMPLES);\n\n program.showHelpAfterError(\"(run `tiro --help` for available commands)\");\n\n registerAuth(program);\n registerNotes(program);\n\n return program;\n}\n\nasync function main(): Promise<void> {\n const program = buildProgram();\n try {\n await program.parseAsync(process.argv);\n } catch (err) {\n handleError(err, program);\n }\n}\n\nfunction handleError(err: unknown, program: Command): never {\n const opts = program.opts<{ json?: boolean; quiet?: boolean }>();\n\n if (err instanceof TiroError) {\n if (opts.json) {\n printError(err.toJSON());\n } else if (!opts.quiet) {\n process.stderr.write(`${color(\"✗\", \"red\", opts)} ${err.message}\\n`);\n if (err.suggestion) {\n process.stderr.write(` ${color(\"→\", \"gray\", opts)} ${err.suggestion}\\n`);\n }\n }\n process.exit(err.exitCode);\n }\n\n if (err instanceof Error) {\n if (opts.json) {\n printError({\n ok: false,\n error: { code: \"internal_error\", message: err.message, errorType: \"internal_error\" },\n });\n } else if (!opts.quiet) {\n process.stderr.write(`${color(\"✗\", \"red\", opts)} ${err.message}\\n`);\n }\n process.exit(ExitCode.Generic);\n }\n\n process.stderr.write(`Unknown error: ${String(err)}\\n`);\n process.exit(ExitCode.Generic);\n}\n\nmain().catch((err) => {\n process.stderr.write(`Fatal: ${String(err)}\\n`);\n process.exit(ExitCode.Generic);\n});\n","export const VERSION = \"0.1.0\";\n","export const ExitCode = {\n Ok: 0,\n Generic: 1,\n Usage: 2,\n AuthRequired: 4,\n ExUsage: 64,\n ExDataErr: 65,\n ExConfig: 78,\n} as const;\n\nexport type ExitCodeValue = (typeof ExitCode)[keyof typeof ExitCode];\n\nexport type ErrorType =\n | \"bad_request\"\n | \"unauthorized\"\n | \"forbidden\"\n | \"not_found\"\n | \"not_acceptable\"\n | \"conflict\"\n | \"payload_too_large\"\n | \"unprocessable_entity\"\n | \"too_many_requests\"\n | \"internal_error\"\n | \"auth_required\"\n | \"config_missing\"\n | \"network_error\";\n\nexport interface ErrorPayload {\n code: string;\n message: string;\n suggestion?: string;\n errorType?: ErrorType;\n httpStatus?: number;\n requestId?: string;\n}\n\nexport class TiroError extends Error {\n readonly code: string;\n readonly suggestion?: string;\n readonly errorType?: ErrorType;\n readonly httpStatus?: number;\n readonly requestId?: string;\n readonly exitCode: ExitCodeValue;\n\n constructor(payload: ErrorPayload, exitCode: ExitCodeValue = ExitCode.Generic) {\n super(payload.message);\n this.name = \"TiroError\";\n this.code = payload.code;\n this.suggestion = payload.suggestion;\n this.errorType = payload.errorType;\n this.httpStatus = payload.httpStatus;\n this.requestId = payload.requestId;\n this.exitCode = exitCode;\n }\n\n toJSON(): { ok: false; error: ErrorPayload } {\n return {\n ok: false,\n error: {\n code: this.code,\n message: this.message,\n ...(this.suggestion !== undefined && { suggestion: this.suggestion }),\n ...(this.errorType !== undefined && { errorType: this.errorType }),\n ...(this.httpStatus !== undefined && { httpStatus: this.httpStatus }),\n ...(this.requestId !== undefined && { requestId: this.requestId }),\n },\n };\n }\n}\n\nexport function authRequired(): TiroError {\n return new TiroError(\n {\n code: \"auth_required\",\n message:\n \"Not authenticated. Run `tiro auth login` to sign in, or set TIRO_TOKEN env var.\",\n suggestion: \"tiro auth login\",\n errorType: \"auth_required\",\n },\n ExitCode.AuthRequired,\n );\n}\n\nexport function configMissing(message: string, suggestion?: string): TiroError {\n return new TiroError(\n {\n code: \"config_missing\",\n message,\n ...(suggestion !== undefined && { suggestion }),\n errorType: \"config_missing\",\n },\n ExitCode.ExConfig,\n );\n}\n","export type OutputMode = \"json\" | \"pretty\";\n\nexport interface OutputOptions {\n json?: boolean;\n pretty?: boolean;\n noColor?: boolean;\n quiet?: boolean;\n}\n\nexport function resolveOutputMode(opts: OutputOptions): OutputMode {\n if (opts.json) return \"json\";\n if (opts.pretty) return \"pretty\";\n return process.stdout.isTTY ? \"pretty\" : \"json\";\n}\n\nexport function colorEnabled(opts: OutputOptions): boolean {\n if (opts.noColor) return false;\n if (process.env[\"NO_COLOR\"]) return false;\n if (process.env[\"FORCE_COLOR\"]) return true;\n return process.stdout.isTTY === true;\n}\n\nconst ANSI = {\n reset: \"\\x1b[0m\",\n bold: \"\\x1b[1m\",\n dim: \"\\x1b[2m\",\n red: \"\\x1b[31m\",\n green: \"\\x1b[32m\",\n yellow: \"\\x1b[33m\",\n blue: \"\\x1b[34m\",\n magenta: \"\\x1b[35m\",\n cyan: \"\\x1b[36m\",\n gray: \"\\x1b[90m\",\n} as const;\n\nexport function color(\n text: string,\n style: keyof typeof ANSI,\n opts: OutputOptions = {},\n): string {\n if (!colorEnabled(opts)) return text;\n return `${ANSI[style]}${text}${ANSI.reset}`;\n}\n","import { resolveOutputMode, type OutputOptions } from \"./tty.ts\";\n\nexport function printOutput(value: unknown, opts: OutputOptions = {}): void {\n if (opts.quiet) return;\n const mode = resolveOutputMode(opts);\n if (mode === \"json\") {\n process.stdout.write(`${JSON.stringify(value)}\\n`);\n } else {\n process.stdout.write(`${JSON.stringify(value, null, 2)}\\n`);\n }\n}\n\nexport function printError(value: unknown): void {\n process.stderr.write(`${JSON.stringify(value)}\\n`);\n}\n\nexport function printNdjson(item: unknown): void {\n process.stdout.write(`${JSON.stringify(item)}\\n`);\n}\n","import { Command } from \"commander\";\nimport { registerAuthLogin } from \"./login.ts\";\nimport { registerAuthStatus } from \"./status.ts\";\nimport { registerAuthLogout } from \"./logout.ts\";\n\nexport function registerAuth(program: Command): void {\n const auth = program.command(\"auth\").description(\"Manage authentication\");\n registerAuthLogin(auth);\n registerAuthStatus(auth);\n registerAuthLogout(auth);\n}\n","import { Command } from \"commander\";\nimport { performLogin } from \"../../lib/auth/flow.ts\";\nimport { printOutput } from \"../../lib/output/print.ts\";\nimport { color } from \"../../lib/output/tty.ts\";\nimport { getHostname } from \"../../lib/config.ts\";\n\ninterface LoginOptions {\n hostname?: string;\n noBrowser?: boolean;\n json?: boolean;\n pretty?: boolean;\n noColor?: boolean;\n quiet?: boolean;\n}\n\nexport function registerAuthLogin(parent: Command): void {\n parent\n .command(\"login\")\n .description(\"Sign in to Tiro via OAuth (browser-based, PKCE)\")\n .option(\"--hostname <url>\", \"API base URL (overrides config / TIRO_HOSTNAME)\")\n .option(\"--no-browser\", \"Print the URL instead of opening a browser\")\n .action(async (opts: LoginOptions, cmd: Command) => {\n const globalOpts = cmd.optsWithGlobals<LoginOptions>();\n const result = await performLogin({\n ...(opts.hostname !== undefined && { hostname: opts.hostname }),\n noBrowser: opts.noBrowser === true,\n onPrompt: (msg) => {\n if (globalOpts.quiet) return;\n process.stderr.write(`${color(msg, \"cyan\", globalOpts)}\\n`);\n },\n });\n\n const hostname = getHostname(opts.hostname);\n const expiresIso = new Date(result.expiresAt).toISOString();\n\n if (globalOpts.json) {\n printOutput(\n {\n ok: true,\n data: {\n signedIn: true,\n hostname,\n userId: result.userId ?? null,\n expiresAt: expiresIso,\n },\n },\n globalOpts,\n );\n } else if (!globalOpts.quiet) {\n process.stderr.write(`${color(\"✓\", \"green\", globalOpts)} Signed in to ${hostname}\\n`);\n if (result.userId) {\n process.stderr.write(` user: ${result.userId}\\n`);\n }\n process.stderr.write(` token expires: ${expiresIso}\\n`);\n }\n });\n}\n","import { z } from \"zod\";\nimport { TiroError, ExitCode } from \"../error.ts\";\nimport { generatePkce, generateState } from \"./pkce.ts\";\nimport { startLoopbackServer } from \"./loopback.ts\";\nimport { openBrowser } from \"./browser.ts\";\nimport { saveToken, type StoredToken } from \"./keychain.ts\";\nimport { decodeJwtPayload } from \"./token.ts\";\nimport {\n getHostname,\n getOauthClientId,\n setOauthClientId,\n clearOauthClientId,\n} from \"../config.ts\";\n\nconst RegisterResponseSchema = z.object({\n client_id: z.string(),\n client_secret: z.string().optional(),\n});\n\nconst TokenResponseSchema = z.object({\n access_token: z.string(),\n token_type: z.string(),\n expires_in: z.number().optional(),\n scope: z.string().optional(),\n});\n\nconst CALLBACK_TIMEOUT_MS = 5 * 60 * 1000;\nconst DEFAULT_SCOPE = \"mcp:notes:read\";\n\nexport interface LoginOptions {\n hostname?: string;\n noBrowser?: boolean;\n scope?: string;\n onPrompt?: (msg: string) => void;\n}\n\nexport interface LoginResult {\n hostname: string;\n userId: string | undefined;\n expiresAt: number;\n}\n\nexport async function performLogin(options: LoginOptions = {}): Promise<LoginResult> {\n const hostname = getHostname(options.hostname);\n const onPrompt = options.onPrompt ?? ((msg: string) => process.stderr.write(`${msg}\\n`));\n\n const loopback = await startLoopbackServer();\n\n try {\n const clientId = await ensureOauthClient(hostname, loopback.redirectUri);\n const { codeVerifier, codeChallenge } = generatePkce();\n const state = generateState();\n\n const authorizeUrl = buildAuthorizeUrl({\n hostname,\n clientId,\n redirectUri: loopback.redirectUri,\n state,\n codeChallenge,\n scope: options.scope ?? DEFAULT_SCOPE,\n });\n\n if (options.noBrowser) {\n onPrompt(`Open this URL in your browser:\\n${authorizeUrl}`);\n } else {\n onPrompt(`Opening browser for sign-in...`);\n onPrompt(`If the browser does not open, visit:\\n${authorizeUrl}`);\n await openBrowser(authorizeUrl);\n }\n\n const callback = await loopback.waitForCallback(CALLBACK_TIMEOUT_MS);\n\n if (callback.state !== state) {\n throw new TiroError(\n {\n code: \"auth_state_mismatch\",\n message: \"OAuth state mismatch — possible CSRF. Aborting.\",\n errorType: \"unauthorized\",\n },\n ExitCode.Generic,\n );\n }\n\n const tokenRes = await exchangeToken({\n hostname,\n clientId,\n code: callback.code,\n redirectUri: loopback.redirectUri,\n codeVerifier,\n });\n\n const expiresAt = computeExpiry(tokenRes.expires_in);\n const payload = decodeJwtPayload(tokenRes.access_token);\n const userId = typeof payload?.[\"sub\"] === \"string\" ? (payload[\"sub\"] as string) : undefined;\n\n const stored: StoredToken = {\n accessToken: tokenRes.access_token,\n tokenType: tokenRes.token_type,\n expiresAt,\n hostname,\n ...(tokenRes.scope !== undefined && { scope: tokenRes.scope }),\n ...(userId !== undefined && { userId }),\n };\n saveToken(stored);\n\n return { hostname, userId, expiresAt };\n } finally {\n loopback.close();\n }\n}\n\nasync function ensureOauthClient(hostname: string, redirectUri: string): Promise<string> {\n const cached = getOauthClientId();\n if (cached) return cached;\n\n const url = `${hostname}/v1/mcp/oauth/register`;\n let res: Response;\n try {\n res = await fetch(url, {\n method: \"POST\",\n headers: { \"Content-Type\": \"application/json\" },\n body: JSON.stringify({\n client_name: \"tiro-cli\",\n redirect_uris: [redirectUri],\n grant_types: [\"authorization_code\"],\n response_types: [\"code\"],\n token_endpoint_auth_method: \"none\",\n scope: DEFAULT_SCOPE,\n }),\n });\n } catch (err) {\n throw new TiroError(\n {\n code: \"network_error\",\n message: `Failed to reach ${hostname}: ${(err as Error).message}`,\n errorType: \"network_error\",\n suggestion: \"Check your network connection or --hostname.\",\n },\n ExitCode.Generic,\n );\n }\n\n if (!res.ok) {\n const detail = await safeText(res);\n throw new TiroError(\n {\n code: \"oauth_register_failed\",\n message: `Dynamic Client Registration failed: HTTP ${res.status}`,\n errorType: \"internal_error\",\n httpStatus: res.status,\n ...(detail !== \"\" && { suggestion: detail.slice(0, 200) }),\n },\n ExitCode.Generic,\n );\n }\n\n const json = (await res.json()) as unknown;\n const parsed = RegisterResponseSchema.safeParse(json);\n if (!parsed.success) {\n throw new TiroError(\n {\n code: \"oauth_register_invalid\",\n message: \"Registration response did not match expected shape.\",\n errorType: \"internal_error\",\n },\n ExitCode.Generic,\n );\n }\n\n setOauthClientId(parsed.data.client_id);\n return parsed.data.client_id;\n}\n\ninterface AuthorizeUrlInput {\n hostname: string;\n clientId: string;\n redirectUri: string;\n state: string;\n codeChallenge: string;\n scope: string;\n}\n\nfunction buildAuthorizeUrl(input: AuthorizeUrlInput): string {\n const u = new URL(`${input.hostname}/v1/mcp/oauth/authorize`);\n u.searchParams.set(\"response_type\", \"code\");\n u.searchParams.set(\"client_id\", input.clientId);\n u.searchParams.set(\"redirect_uri\", input.redirectUri);\n u.searchParams.set(\"state\", input.state);\n u.searchParams.set(\"code_challenge\", input.codeChallenge);\n u.searchParams.set(\"code_challenge_method\", \"S256\");\n u.searchParams.set(\"scope\", input.scope);\n return u.toString();\n}\n\ninterface ExchangeInput {\n hostname: string;\n clientId: string;\n code: string;\n redirectUri: string;\n codeVerifier: string;\n}\n\nasync function exchangeToken(input: ExchangeInput): Promise<z.infer<typeof TokenResponseSchema>> {\n const url = `${input.hostname}/v1/mcp/oauth/token`;\n const body = new URLSearchParams({\n grant_type: \"authorization_code\",\n code: input.code,\n redirect_uri: input.redirectUri,\n client_id: input.clientId,\n code_verifier: input.codeVerifier,\n });\n\n let res: Response;\n try {\n res = await fetch(url, {\n method: \"POST\",\n headers: { \"Content-Type\": \"application/x-www-form-urlencoded\" },\n body: body.toString(),\n });\n } catch (err) {\n throw new TiroError(\n {\n code: \"network_error\",\n message: `Failed to reach ${input.hostname}: ${(err as Error).message}`,\n errorType: \"network_error\",\n },\n ExitCode.Generic,\n );\n }\n\n if (!res.ok) {\n if (res.status === 400 || res.status === 401) {\n // Cached client_id may have expired (Redis 30-day TTL). Force re-registration on next try.\n clearOauthClientId();\n }\n const detail = await safeText(res);\n throw new TiroError(\n {\n code: \"oauth_token_failed\",\n message: `Token exchange failed: HTTP ${res.status}`,\n errorType: \"unauthorized\",\n httpStatus: res.status,\n ...(detail !== \"\" && { suggestion: detail.slice(0, 200) }),\n },\n ExitCode.AuthRequired,\n );\n }\n\n const json = (await res.json()) as unknown;\n const parsed = TokenResponseSchema.safeParse(json);\n if (!parsed.success) {\n throw new TiroError(\n {\n code: \"oauth_token_invalid\",\n message: \"Token response did not match expected shape.\",\n errorType: \"internal_error\",\n },\n ExitCode.Generic,\n );\n }\n return parsed.data;\n}\n\nfunction computeExpiry(expiresIn?: number): number {\n // McpJwtService issues 180-day tokens; if expires_in absent, fall back to 180 days.\n const fallbackSeconds = 180 * 24 * 60 * 60;\n const seconds = expiresIn ?? fallbackSeconds;\n return Date.now() + seconds * 1000;\n}\n\nasync function safeText(res: Response): Promise<string> {\n try {\n return await res.text();\n } catch {\n return \"\";\n }\n}\n","import { createHash, randomBytes } from \"node:crypto\";\n\nexport interface PkcePair {\n codeVerifier: string;\n codeChallenge: string;\n method: \"S256\";\n}\n\nexport function generatePkce(): PkcePair {\n const codeVerifier = base64url(randomBytes(32));\n const codeChallenge = base64url(createHash(\"sha256\").update(codeVerifier).digest());\n return { codeVerifier, codeChallenge, method: \"S256\" };\n}\n\nexport function generateState(): string {\n return base64url(randomBytes(24));\n}\n\nfunction base64url(buf: Buffer): string {\n return buf\n .toString(\"base64\")\n .replace(/\\+/g, \"-\")\n .replace(/\\//g, \"_\")\n .replace(/=+$/, \"\");\n}\n","import http from \"node:http\";\nimport type { AddressInfo } from \"node:net\";\n\nexport interface CallbackResult {\n code: string;\n state: string;\n}\n\nexport interface LoopbackServer {\n redirectUri: string;\n port: number;\n waitForCallback: (timeoutMs: number) => Promise<CallbackResult>;\n close: () => void;\n}\n\nexport async function startLoopbackServer(): Promise<LoopbackServer> {\n let pendingResolve: ((r: CallbackResult) => void) | null = null;\n let pendingReject: ((e: Error) => void) | null = null;\n\n const settle = (\n fn: ((arg: CallbackResult) => void) | ((arg: Error) => void),\n arg: CallbackResult | Error,\n ): void => {\n pendingResolve = null;\n pendingReject = null;\n (fn as (arg: CallbackResult | Error) => void)(arg);\n };\n\n const server = http.createServer((req, res) => {\n if (!req.url) {\n res.writeHead(400).end();\n return;\n }\n const url = new URL(req.url, `http://127.0.0.1`);\n if (url.pathname !== \"/callback\") {\n res.writeHead(404, { \"Content-Type\": \"text/plain\" }).end(\"Not found\");\n return;\n }\n\n const code = url.searchParams.get(\"code\");\n const state = url.searchParams.get(\"state\");\n const error = url.searchParams.get(\"error\");\n const errorDesc = url.searchParams.get(\"error_description\") ?? \"\";\n\n if (error) {\n const msg = `OAuth error: ${error}${errorDesc ? ` — ${errorDesc}` : \"\"}`;\n respondPage(res, 500, \"Login failed\", msg);\n if (pendingReject) settle(pendingReject, new Error(msg));\n return;\n }\n if (!code || !state) {\n respondPage(res, 400, \"Missing parameters\", \"Missing `code` or `state`.\");\n if (pendingReject) settle(pendingReject, new Error(\"Missing code or state\"));\n return;\n }\n\n respondPage(\n res,\n 200,\n \"Login successful\",\n \"You're signed in. You can close this tab and return to the terminal.\",\n );\n if (pendingResolve) settle(pendingResolve, { code, state });\n });\n\n await new Promise<void>((resolve) => {\n server.listen(0, \"127.0.0.1\", () => resolve());\n });\n\n const address = server.address() as AddressInfo;\n const port = address.port;\n const redirectUri = `http://127.0.0.1:${port}/callback`;\n\n return {\n redirectUri,\n port,\n waitForCallback(timeoutMs: number) {\n return new Promise<CallbackResult>((resolve, reject) => {\n const timer = setTimeout(() => {\n pendingResolve = null;\n pendingReject = null;\n reject(new Error(`Timed out waiting for OAuth callback (${timeoutMs}ms)`));\n }, timeoutMs);\n pendingResolve = (r) => {\n clearTimeout(timer);\n resolve(r);\n };\n pendingReject = (e) => {\n clearTimeout(timer);\n reject(e);\n };\n });\n },\n close() {\n server.close();\n },\n };\n}\n\nfunction respondPage(\n res: http.ServerResponse,\n status: number,\n title: string,\n body: string,\n): void {\n const html = `<!doctype html>\n<html lang=\"en\">\n<head>\n <meta charset=\"utf-8\">\n <title>${title}</title>\n <style>\n body { font-family: -apple-system, system-ui, sans-serif; padding: 4rem; max-width: 32rem; margin: 0 auto; color: #1a1a1a; }\n h1 { font-size: 1.5rem; margin-bottom: 1rem; }\n p { color: #555; line-height: 1.5; }\n </style>\n</head>\n<body>\n <h1>${title}</h1>\n <p>${body}</p>\n</body>\n</html>`;\n res.writeHead(status, { \"Content-Type\": \"text/html; charset=utf-8\" });\n res.end(html);\n}\n","import open from \"open\";\n\nexport async function openBrowser(url: string): Promise<void> {\n try {\n await open(url, { wait: false });\n } catch {\n // Best-effort. Caller already prints the URL for manual fallback.\n }\n}\n","import { Entry } from \"@napi-rs/keyring\";\nimport { TiroError, ExitCode } from \"../error.ts\";\n\nconst SERVICE = \"io.tiro.cli\";\nconst ACCOUNT = \"default\";\n\nexport interface StoredToken {\n accessToken: string;\n tokenType: string;\n expiresAt: number;\n scope?: string;\n hostname: string;\n userId?: string;\n}\n\nexport function saveToken(token: StoredToken): void {\n const entry = new Entry(SERVICE, ACCOUNT);\n try {\n entry.setPassword(JSON.stringify(token));\n } catch (err) {\n throw new TiroError(\n {\n code: \"keychain_write_failed\",\n message: `Failed to write to OS keychain: ${(err as Error).message}`,\n errorType: \"internal_error\",\n suggestion:\n process.platform === \"linux\"\n ? \"Linux requires a Secret Service daemon (gnome-keyring or kwallet). Or set TIRO_TOKEN env var.\"\n : \"Check OS keychain permissions, or set TIRO_TOKEN env var.\",\n },\n ExitCode.Generic,\n );\n }\n}\n\nexport function loadToken(): StoredToken | null {\n const entry = new Entry(SERVICE, ACCOUNT);\n let raw: string | null;\n try {\n raw = entry.getPassword();\n } catch {\n return null;\n }\n if (!raw) return null;\n try {\n return JSON.parse(raw) as StoredToken;\n } catch {\n return null;\n }\n}\n\nexport function deleteToken(): boolean {\n const entry = new Entry(SERVICE, ACCOUNT);\n try {\n return entry.deletePassword();\n } catch {\n return false;\n }\n}\n","import { loadToken, type StoredToken } from \"./keychain.ts\";\nimport { authRequired } from \"../error.ts\";\n\nexport interface ResolvedToken {\n accessToken: string;\n source: \"env\" | \"keychain\";\n hostname?: string;\n expiresAt?: number;\n userId?: string;\n}\n\nexport function resolveToken(): ResolvedToken | null {\n const envToken = process.env[\"TIRO_TOKEN\"];\n if (envToken) {\n return { accessToken: envToken, source: \"env\" };\n }\n const stored = loadToken();\n if (stored) {\n return {\n accessToken: stored.accessToken,\n source: \"keychain\",\n hostname: stored.hostname,\n expiresAt: stored.expiresAt,\n ...(stored.userId !== undefined && { userId: stored.userId }),\n };\n }\n return null;\n}\n\nexport function requireToken(): ResolvedToken {\n const t = resolveToken();\n if (!t) throw authRequired();\n return t;\n}\n\nexport function decodeJwtPayload(token: string): Record<string, unknown> | null {\n const parts = token.split(\".\");\n if (parts.length !== 3) return null;\n try {\n const payload = parts[1];\n if (!payload) return null;\n const json = Buffer.from(payload, \"base64url\").toString(\"utf8\");\n return JSON.parse(json) as Record<string, unknown>;\n } catch {\n return null;\n }\n}\n\nexport function isTokenExpired(stored: StoredToken): boolean {\n return Date.now() >= stored.expiresAt;\n}\n","import Conf from \"conf\";\n\ninterface TiroConfigSchema {\n hostname: string;\n oauthClientId: string | null;\n oauthClientIdRegisteredAt: number | null;\n defaultOutputDir: string | null;\n}\n\nconst DEFAULT_HOSTNAME = \"https://api.tiro.ooo\";\n\nconst config = new Conf<TiroConfigSchema>({\n projectName: \"tiro\",\n defaults: {\n hostname: DEFAULT_HOSTNAME,\n oauthClientId: null,\n oauthClientIdRegisteredAt: null,\n defaultOutputDir: null,\n },\n});\n\nexport function getHostname(override?: string): string {\n if (override) return stripTrailingSlash(override);\n const env = process.env[\"TIRO_HOSTNAME\"];\n if (env) return stripTrailingSlash(env);\n return stripTrailingSlash(config.get(\"hostname\"));\n}\n\nexport function setHostname(hostname: string): void {\n config.set(\"hostname\", stripTrailingSlash(hostname));\n}\n\nexport function getOauthClientId(): string | null {\n const id = config.get(\"oauthClientId\");\n const registeredAt = config.get(\"oauthClientIdRegisteredAt\");\n if (!id || !registeredAt) return null;\n // DCR clients have 30-day TTL on the backend (Redis). Treat them as expired\n // a day earlier to avoid edge-case 401s during exchange.\n const ttlMs = 29 * 24 * 60 * 60 * 1000;\n if (Date.now() - registeredAt > ttlMs) return null;\n return id;\n}\n\nexport function setOauthClientId(clientId: string): void {\n config.set(\"oauthClientId\", clientId);\n config.set(\"oauthClientIdRegisteredAt\", Date.now());\n}\n\nexport function clearOauthClientId(): void {\n config.set(\"oauthClientId\", null);\n config.set(\"oauthClientIdRegisteredAt\", null);\n}\n\nexport function getDefaultOutputDir(): string | null {\n const env = process.env[\"TIRO_OUTPUT_DIR\"];\n if (env) return env;\n return config.get(\"defaultOutputDir\");\n}\n\nexport function getConfigPath(): string {\n return config.path;\n}\n\nfunction stripTrailingSlash(s: string): string {\n return s.endsWith(\"/\") ? s.slice(0, -1) : s;\n}\n","import { Command } from \"commander\";\nimport { resolveToken, decodeJwtPayload } from \"../../lib/auth/token.ts\";\nimport { printOutput } from \"../../lib/output/print.ts\";\nimport { color } from \"../../lib/output/tty.ts\";\nimport { authRequired } from \"../../lib/error.ts\";\n\ninterface StatusReport {\n signedIn: boolean;\n source: \"env\" | \"keychain\";\n hostname: string | null;\n userId: string | null;\n scope: string | null;\n expiresAt: string | null;\n expired: boolean;\n tokenPrefix: string;\n}\n\ninterface StatusOptions {\n json?: boolean;\n pretty?: boolean;\n noColor?: boolean;\n quiet?: boolean;\n}\n\nexport function registerAuthStatus(parent: Command): void {\n parent\n .command(\"status\")\n .description(\"Show current authenticated account and scopes\")\n .action(async (_opts: StatusOptions, cmd: Command) => {\n const globalOpts = cmd.optsWithGlobals<StatusOptions>();\n const t = resolveToken();\n if (!t) {\n throw authRequired();\n }\n\n const payload = decodeJwtPayload(t.accessToken);\n const sub = typeof payload?.[\"sub\"] === \"string\" ? (payload[\"sub\"] as string) : null;\n const exp = typeof payload?.[\"exp\"] === \"number\" ? (payload[\"exp\"] as number) * 1000 : null;\n const scope = typeof payload?.[\"scope\"] === \"string\" ? (payload[\"scope\"] as string) : null;\n\n const expMs = exp ?? t.expiresAt ?? null;\n const expired = expMs !== null && Date.now() >= expMs;\n\n const report: StatusReport = {\n signedIn: true,\n source: t.source,\n hostname: t.hostname ?? null,\n userId: t.userId ?? sub,\n scope,\n expiresAt: expMs ? new Date(expMs).toISOString() : null,\n expired,\n tokenPrefix: `${t.accessToken.slice(0, 4)}...***`,\n };\n\n if (globalOpts.json || !process.stdout.isTTY) {\n printOutput({ ok: true, data: report }, globalOpts);\n } else {\n const headIcon = expired ? color(\"!\", \"yellow\", globalOpts) : color(\"✓\", \"green\", globalOpts);\n const headText = expired ? \"Token expired\" : \"Signed in\";\n process.stdout.write(`${headIcon} ${headText}\\n`);\n process.stdout.write(` source: ${report.source}\\n`);\n if (report.hostname) process.stdout.write(` hostname: ${report.hostname}\\n`);\n if (report.userId) process.stdout.write(` user: ${report.userId}\\n`);\n if (report.scope) process.stdout.write(` scope: ${report.scope}\\n`);\n if (report.expiresAt) {\n const tag = expired ? color(\" (expired)\", \"red\", globalOpts) : \"\";\n process.stdout.write(` expires at: ${report.expiresAt}${tag}\\n`);\n }\n process.stdout.write(` token: ${report.tokenPrefix}\\n`);\n if (expired) {\n process.stdout.write(\n `\\n${color(\"→\", \"gray\", globalOpts)} Run \\`tiro auth login\\` to refresh.\\n`,\n );\n }\n }\n });\n}\n","import { Command } from \"commander\";\nimport { deleteToken } from \"../../lib/auth/keychain.ts\";\nimport { clearOauthClientId } from \"../../lib/config.ts\";\nimport { printOutput } from \"../../lib/output/print.ts\";\nimport { color } from \"../../lib/output/tty.ts\";\n\ninterface LogoutOptions {\n json?: boolean;\n pretty?: boolean;\n noColor?: boolean;\n quiet?: boolean;\n}\n\nexport function registerAuthLogout(parent: Command): void {\n parent\n .command(\"logout\")\n .description(\"Sign out and clear the stored token\")\n .action(async (_opts: LogoutOptions, cmd: Command) => {\n const globalOpts = cmd.optsWithGlobals<LogoutOptions>();\n const removed = deleteToken();\n clearOauthClientId();\n\n if (globalOpts.json) {\n printOutput({ ok: true, data: { signedOut: true, hadToken: removed } }, globalOpts);\n } else if (!globalOpts.quiet) {\n if (removed) {\n process.stderr.write(`${color(\"✓\", \"green\", globalOpts)} Signed out\\n`);\n } else {\n process.stderr.write(`${color(\"•\", \"gray\", globalOpts)} No token was stored\\n`);\n }\n }\n });\n}\n","import { Command } from \"commander\";\nimport { registerNotesList } from \"./list.ts\";\nimport { registerNotesSearch } from \"./search.ts\";\nimport { registerNotesGet } from \"./get.ts\";\nimport { registerNotesTranscript } from \"./transcript.ts\";\n\nexport function registerNotes(program: Command): void {\n const notes = program.command(\"notes\").description(\"List, search, and download notes\");\n registerNotesList(notes);\n registerNotesSearch(notes);\n registerNotesGet(notes);\n registerNotesTranscript(notes);\n}\n","import { Command } from \"commander\";\nimport { createApiClient } from \"../../lib/api/client.ts\";\nimport { NoteSchema, PageCursorResponseSchema } from \"../../lib/api/types.ts\";\nimport { printNdjson } from \"../../lib/output/print.ts\";\nimport { resolveOutputMode, color } from \"../../lib/output/tty.ts\";\nimport { parseDate } from \"../../lib/util/parseDate.ts\";\n\ninterface ListOptions {\n keyword?: string;\n folder?: string;\n since?: string;\n until?: string;\n limit?: string;\n cursor?: string;\n hostname?: string;\n json?: boolean;\n pretty?: boolean;\n noColor?: boolean;\n quiet?: boolean;\n}\n\nconst ListResponseSchema = PageCursorResponseSchema(NoteSchema);\n\nconst DEFAULT_PAGE_SIZE = 100;\nconst MAX_PAGE_SIZE = 1000;\n\nexport function registerNotesList(parent: Command): void {\n parent\n .command(\"list\")\n .description(\"List notes (lightweight metadata)\")\n .option(\"--keyword <text>\", \"Reorder by OpenSearch relevance for this keyword\")\n .option(\"--folder <id>\", \"Restrict to a folder (recursive)\")\n .option(\"--since <date>\", \"ISO-8601 or relative (7d, 24h, 30m); maps to createdAtFrom\")\n .option(\"--until <date>\", \"ISO-8601 or relative; maps to createdAtTo\")\n .option(\n \"--limit <n>\",\n `Page size (default ${DEFAULT_PAGE_SIZE}, max ${MAX_PAGE_SIZE})`,\n )\n .option(\"--cursor <token>\", \"Cursor for the next page\")\n .action(async (opts: ListOptions, cmd: Command) => {\n const globalOpts = cmd.optsWithGlobals<ListOptions>();\n const client = createApiClient({\n ...(globalOpts.hostname !== undefined && { hostnameOverride: globalOpts.hostname }),\n });\n\n const params: Record<string, string | number | undefined> = {};\n if (opts.keyword) params[\"keyword\"] = opts.keyword;\n if (opts.folder) params[\"folderId\"] = opts.folder;\n if (opts.since) params[\"createdAtFrom\"] = parseDate(opts.since);\n if (opts.until) params[\"createdAtTo\"] = parseDate(opts.until);\n const size = clampLimit(opts.limit);\n if (size !== undefined) params[\"size\"] = size;\n if (opts.cursor) params[\"cursor\"] = opts.cursor;\n\n const res = await client.getJson(\"/v1/external/notes\", ListResponseSchema, params);\n\n const mode = resolveOutputMode(globalOpts);\n if (mode === \"json\") {\n for (const note of res.content) printNdjson(note);\n if (res.nextCursor) printNdjson({ _cursor: res.nextCursor });\n } else {\n printPretty(res.content, res.nextCursor, globalOpts);\n }\n });\n}\n\nfunction clampLimit(raw?: string): number | undefined {\n if (!raw) return undefined;\n const n = parseInt(raw, 10);\n if (!Number.isFinite(n) || n <= 0) return DEFAULT_PAGE_SIZE;\n return Math.min(n, MAX_PAGE_SIZE);\n}\n\ninterface NoteListItem {\n guid: string;\n title: string;\n createdAt: string;\n recordingDurationSeconds: number;\n webUrl: string;\n}\n\nfunction printPretty(\n notes: NoteListItem[],\n nextCursor: string | null,\n opts: { noColor?: boolean },\n): void {\n if (notes.length === 0) {\n process.stdout.write(`${color(\"(no notes)\", \"gray\", opts)}\\n`);\n return;\n }\n const titleWidth = computeTitleWidth();\n for (const n of notes) {\n const date = n.createdAt.slice(0, 10);\n const dur = formatDuration(n.recordingDurationSeconds);\n const title = truncate(n.title, titleWidth);\n process.stdout.write(\n `${color(date, \"gray\", opts)} ${color(n.guid, \"dim\", opts)} ${color(dur, \"cyan\", opts)} ${title}\\n`,\n );\n }\n if (nextCursor) {\n process.stdout.write(\n `${color(`\\n next: --cursor ${nextCursor}`, \"gray\", opts)}\\n`,\n );\n }\n}\n\nfunction computeTitleWidth(): number {\n const cols = process.stdout.columns;\n if (!cols || cols < 60) return 40;\n return Math.max(20, cols - 60);\n}\n\nfunction truncate(s: string, max: number): string {\n if (s.length <= max) return s;\n return s.slice(0, Math.max(0, max - 1)) + \"…\";\n}\n\nfunction formatDuration(sec: number): string {\n if (!sec || sec <= 0) return \"—\";\n const m = Math.floor(sec / 60);\n const s = Math.floor(sec % 60);\n if (m > 0) return `${m}m${s.toString().padStart(2, \"0\")}s`;\n return `${s}s`;\n}\n","import { z } from \"zod\";\nimport { TiroError, ExitCode, type ErrorType } from \"../error.ts\";\nimport { resolveToken } from \"../auth/token.ts\";\nimport { authRequired } from \"../error.ts\";\nimport { getHostname } from \"../config.ts\";\nimport { ApiErrorSchema } from \"./types.ts\";\n\nexport interface ApiClientOptions {\n hostnameOverride?: string;\n tokenOverride?: string;\n}\n\nexport class TiroApiClient {\n constructor(\n private readonly hostname: string,\n private readonly token: string,\n ) {}\n\n async getJson<S extends z.ZodTypeAny>(\n path: string,\n schema: S,\n params?: Record<string, string | number | undefined>,\n ): Promise<z.infer<S>> {\n const url = this.buildUrl(path, params);\n const res = await this.fetch(url, { method: \"GET\" });\n return this.parseJson(res, schema, \"GET\", path);\n }\n\n async postJson<S extends z.ZodTypeAny>(\n path: string,\n schema: S,\n body: unknown,\n ): Promise<z.infer<S>> {\n const url = this.buildUrl(path);\n const res = await this.fetch(url, {\n method: \"POST\",\n headers: { \"Content-Type\": \"application/json\" },\n body: JSON.stringify(body),\n });\n return this.parseJson(res, schema, \"POST\", path);\n }\n\n async putJson<S extends z.ZodTypeAny>(\n path: string,\n schema: S,\n body: unknown,\n ): Promise<z.infer<S>> {\n const url = this.buildUrl(path);\n const res = await this.fetch(url, {\n method: \"PUT\",\n headers: { \"Content-Type\": \"application/json\" },\n body: JSON.stringify(body),\n });\n return this.parseJson(res, schema, \"PUT\", path);\n }\n\n async deleteVoid(path: string): Promise<void> {\n const url = this.buildUrl(path);\n const res = await this.fetch(url, { method: \"DELETE\" });\n if (!res.ok) throw await mapHttpError(res, \"DELETE\", path);\n }\n\n private buildUrl(path: string, params?: Record<string, string | number | undefined>): string {\n const base = path.startsWith(\"http\") ? path : `${this.hostname}${path}`;\n const u = new URL(base);\n if (params) {\n for (const [k, v] of Object.entries(params)) {\n if (v !== undefined && v !== null && v !== \"\") {\n u.searchParams.set(k, String(v));\n }\n }\n }\n return u.toString();\n }\n\n private async fetch(url: string, init: RequestInit): Promise<Response> {\n const headers = new Headers(init.headers);\n headers.set(\"Authorization\", `Bearer ${this.token}`);\n headers.set(\"Accept\", \"application/json\");\n try {\n return await fetch(url, { ...init, headers });\n } catch (err) {\n throw new TiroError(\n {\n code: \"network_error\",\n message: `Network error reaching ${this.hostname}: ${(err as Error).message}`,\n errorType: \"network_error\",\n suggestion: \"Check your network or --hostname.\",\n },\n ExitCode.Generic,\n );\n }\n }\n\n private async parseJson<S extends z.ZodTypeAny>(\n res: Response,\n schema: S,\n method: string,\n path: string,\n ): Promise<z.infer<S>> {\n if (!res.ok) throw await mapHttpError(res, method, path);\n let json: unknown;\n try {\n json = await res.json();\n } catch (err) {\n throw new TiroError(\n {\n code: \"invalid_response\",\n message: `Failed to parse JSON from ${method} ${path}: ${(err as Error).message}`,\n errorType: \"internal_error\",\n },\n ExitCode.Generic,\n );\n }\n const parsed = schema.safeParse(json);\n if (!parsed.success) {\n throw new TiroError(\n {\n code: \"schema_mismatch\",\n message: `Response shape did not match expected schema (${method} ${path}).`,\n errorType: \"internal_error\",\n suggestion: parsed.error.issues\n .slice(0, 3)\n .map((i) => `${i.path.join(\".\") || \"(root)\"}: ${i.message}`)\n .join(\"; \"),\n },\n ExitCode.Generic,\n );\n }\n return parsed.data;\n }\n}\n\nasync function mapHttpError(res: Response, method: string, path: string): Promise<TiroError> {\n const requestId = res.headers.get(\"x-request-id\") ?? undefined;\n const exitCode = res.status === 401 ? ExitCode.AuthRequired : ExitCode.Generic;\n\n const apiError = await tryParseApiError(res);\n if (apiError) {\n return new TiroError(\n {\n code: `${apiError.error.errorType}`,\n message: apiError.error.message,\n errorType: apiError.error.errorType as ErrorType,\n httpStatus: res.status,\n ...(requestId !== undefined && { requestId }),\n ...(res.status === 401 && {\n suggestion: \"Run `tiro auth login` to refresh.\",\n }),\n },\n exitCode,\n );\n }\n\n return new TiroError(\n {\n code: \"http_error\",\n message: `${method} ${path} failed: HTTP ${res.status} ${res.statusText}`,\n errorType: httpStatusToErrorType(res.status),\n httpStatus: res.status,\n ...(requestId !== undefined && { requestId }),\n },\n exitCode,\n );\n}\n\nfunction httpStatusToErrorType(status: number): ErrorType {\n if (status === 400) return \"bad_request\";\n if (status === 401) return \"unauthorized\";\n if (status === 403) return \"forbidden\";\n if (status === 404) return \"not_found\";\n if (status === 409) return \"conflict\";\n if (status === 413) return \"payload_too_large\";\n if (status === 422) return \"unprocessable_entity\";\n if (status === 429) return \"too_many_requests\";\n return \"internal_error\";\n}\n\nasync function tryParseApiError(res: Response): Promise<{ error: { code: number; errorType: string; message: string } } | null> {\n try {\n const json = await res.clone().json();\n const parsed = ApiErrorSchema.safeParse(json);\n return parsed.success ? parsed.data : null;\n } catch {\n return null;\n }\n}\n\nexport function createApiClient(opts: ApiClientOptions = {}): TiroApiClient {\n if (opts.tokenOverride) {\n return new TiroApiClient(getHostname(opts.hostnameOverride), opts.tokenOverride);\n }\n const t = resolveToken();\n if (!t) throw authRequired();\n const hostname = getHostname(opts.hostnameOverride ?? t.hostname);\n return new TiroApiClient(hostname, t.accessToken);\n}\n","import { z } from \"zod\";\n\nexport const CollaboratorSchema = z.object({\n guid: z.string(),\n name: z.string(),\n email: z.string(),\n role: z.enum([\"OWNER\", \"EDITOR\", \"VIEWER\"]),\n});\n\nexport const ParticipantSchema = z.object({\n name: z.string().nullable().optional(),\n email: z.string().nullable().optional(),\n});\n\nexport const NoteSchema = z\n .object({\n guid: z.string(),\n title: z.string(),\n createdAt: z.string(),\n updatedAt: z.string(),\n sourceType: z.string(),\n recordingDurationSeconds: z.number(),\n collaborators: z.array(CollaboratorSchema).optional().default([]),\n participants: z.array(ParticipantSchema).optional().default([]),\n webUrl: z.string(),\n recordingStartAt: z.string().nullable().optional(),\n recordingEndAt: z.string().nullable().optional(),\n })\n .passthrough();\nexport type Note = z.infer<typeof NoteSchema>;\n\nexport const TextObjectSchema = z.object({\n type: z.string(),\n content: z.string(),\n});\nexport type TextObject = z.infer<typeof TextObjectSchema>;\n\nexport const SpeakerInfoSchema = z.object({\n label: z.string(),\n personName: z.string().nullable().optional(),\n});\nexport type SpeakerInfo = z.infer<typeof SpeakerInfoSchema>;\n\nexport const DiarizedSegmentSchema = z.object({\n content: z.string(),\n speaker: SpeakerInfoSchema,\n});\nexport type DiarizedSegment = z.infer<typeof DiarizedSegmentSchema>;\n\nexport const ParagraphSchema = z\n .object({\n uuid: z.string(),\n transcribeLocale: z.string().nullable().optional(),\n transcript: TextObjectSchema.nullable().optional(),\n diarizedSegments: z.array(DiarizedSegmentSchema).nullable().optional(),\n timeFrom: z.string().nullable().optional(),\n timeTo: z.string().nullable().optional(),\n locked: z.boolean().optional(),\n })\n .passthrough();\nexport type Paragraph = z.infer<typeof ParagraphSchema>;\n\nexport const McpSegmentSchema = z.object({\n content: z.string(),\n speaker: z\n .object({\n label: z.string(),\n name: z.string().nullable(),\n })\n .nullable(),\n});\nexport type McpSegment = z.infer<typeof McpSegmentSchema>;\n\nexport const McpParagraphSchema = z.object({\n timeFrom: z.string().nullable(),\n timeTo: z.string().nullable(),\n segments: z.array(McpSegmentSchema),\n});\nexport type McpParagraph = z.infer<typeof McpParagraphSchema>;\n\nexport const McpTranscriptSchema = z.object({\n noteGuid: z.string(),\n title: z.string(),\n participants: z.array(z.string()),\n createdAt: z.string(),\n recordingDurationSeconds: z.number(),\n paragraphs: z.array(McpParagraphSchema),\n});\nexport type McpTranscript = z.infer<typeof McpTranscriptSchema>;\n\nexport const PageCursorResponseSchema = <T extends z.ZodTypeAny>(item: T) =>\n z.object({\n content: z.array(item),\n nextCursor: z.string().nullable(),\n });\n\nexport const SimpleListResponseSchema = <T extends z.ZodTypeAny>(item: T) =>\n z.object({\n content: z.array(item),\n });\n\nexport const ApiErrorSchema = z.object({\n error: z.object({\n code: z.number(),\n errorType: z.string(),\n message: z.string(),\n detail: z.string().nullable().optional(),\n }),\n});\nexport type ApiError = z.infer<typeof ApiErrorSchema>;\n","import { TiroError, ExitCode } from \"../error.ts\";\n\nconst RELATIVE_RE = /^(\\d+)([smhdw])$/i;\nconst UNIT_MS: Record<string, number> = {\n s: 1000,\n m: 60_000,\n h: 3_600_000,\n d: 86_400_000,\n w: 604_800_000,\n};\n\nexport function parseDate(input: string): string {\n const trimmed = input.trim();\n\n const rel = trimmed.match(RELATIVE_RE);\n if (rel) {\n const num = parseInt(rel[1] ?? \"\", 10);\n const unit = (rel[2] ?? \"\").toLowerCase();\n const factor = UNIT_MS[unit];\n if (!factor || !Number.isFinite(num)) {\n throw invalidDate(input);\n }\n return new Date(Date.now() - num * factor).toISOString();\n }\n\n const d = new Date(trimmed);\n if (Number.isNaN(d.getTime())) throw invalidDate(input);\n return d.toISOString();\n}\n\nfunction invalidDate(input: string): TiroError {\n return new TiroError(\n {\n code: \"invalid_date\",\n message: `Invalid date: \"${input}\". Use ISO-8601 (e.g. 2026-04-01T10:00:00Z) or relative (e.g. 7d, 24h, 30m).`,\n errorType: \"bad_request\",\n },\n ExitCode.Usage,\n );\n}\n","import { Command } from \"commander\";\nimport { createApiClient } from \"../../lib/api/client.ts\";\nimport { NoteSchema, PageCursorResponseSchema } from \"../../lib/api/types.ts\";\nimport { printNdjson } from \"../../lib/output/print.ts\";\nimport { resolveOutputMode, color } from \"../../lib/output/tty.ts\";\nimport { parseDate } from \"../../lib/util/parseDate.ts\";\nimport { TiroError, ExitCode } from \"../../lib/error.ts\";\n\ninterface SearchOptions {\n keyword?: string;\n folder?: string;\n since?: string;\n until?: string;\n limit?: string;\n cursor?: string;\n hostname?: string;\n json?: boolean;\n pretty?: boolean;\n noColor?: boolean;\n quiet?: boolean;\n}\n\nconst SearchResponseSchema = PageCursorResponseSchema(NoteSchema).passthrough();\n\nconst DEFAULT_PAGE_SIZE = 100;\nconst MAX_PAGE_SIZE = 1000;\n\nexport function registerNotesSearch(parent: Command): void {\n parent\n .command(\"search [keyword]\")\n .description(\"Deep keyword search — returns notes hydrated with their primary documents\")\n .option(\"--keyword <text>\", \"Alternative to positional keyword\")\n .option(\"--folder <id>\", \"Restrict hits to a folder (recursive)\")\n .option(\"--since <date>\", \"ISO-8601 or relative (7d, 24h, 30m); maps to filter.createdAtFrom\")\n .option(\"--until <date>\", \"ISO-8601 or relative; maps to filter.createdAtTo\")\n .option(\"--limit <n>\", `Page size (default ${DEFAULT_PAGE_SIZE}, max ${MAX_PAGE_SIZE})`)\n .option(\"--cursor <token>\", \"Cursor for the next page (reserved — currently always null)\")\n .action(async (positional: string | undefined, opts: SearchOptions, cmd: Command) => {\n const globalOpts = cmd.optsWithGlobals<SearchOptions>();\n\n const keyword = (positional ?? opts.keyword ?? \"\").trim();\n if (!keyword) {\n throw new TiroError(\n {\n code: \"missing_keyword\",\n message: \"search requires a keyword (positional or --keyword).\",\n errorType: \"bad_request\",\n suggestion: 'tiro notes search \"OKR\"',\n },\n ExitCode.Usage,\n );\n }\n\n const filter: Record<string, string> = {};\n if (opts.folder) filter[\"folderId\"] = opts.folder;\n if (opts.since) filter[\"createdAtFrom\"] = parseDate(opts.since);\n if (opts.until) filter[\"createdAtTo\"] = parseDate(opts.until);\n\n const pagination: Record<string, string | number> = {};\n const size = clampLimit(opts.limit);\n if (size !== undefined) pagination[\"size\"] = size;\n if (opts.cursor) pagination[\"cursor\"] = opts.cursor;\n\n const body: Record<string, unknown> = { keyword };\n if (Object.keys(filter).length > 0) body[\"filter\"] = filter;\n if (Object.keys(pagination).length > 0) body[\"pagination\"] = pagination;\n\n const client = createApiClient({\n ...(globalOpts.hostname !== undefined && { hostnameOverride: globalOpts.hostname }),\n });\n\n const res = await client.postJson(\n \"/v1/external/notes/search\",\n SearchResponseSchema,\n body,\n );\n\n const mode = resolveOutputMode(globalOpts);\n if (mode === \"json\") {\n for (const note of res.content) printNdjson(note);\n if (res.nextCursor) printNdjson({ _cursor: res.nextCursor });\n } else {\n printPretty(res.content, res.nextCursor, globalOpts);\n }\n });\n}\n\nfunction clampLimit(raw?: string): number | undefined {\n if (!raw) return undefined;\n const n = parseInt(raw, 10);\n if (!Number.isFinite(n) || n <= 0) return DEFAULT_PAGE_SIZE;\n return Math.min(n, MAX_PAGE_SIZE);\n}\n\ninterface NoteListItem {\n guid: string;\n title: string;\n createdAt: string;\n}\n\nfunction printPretty(\n notes: NoteListItem[],\n nextCursor: string | null,\n opts: { noColor?: boolean },\n): void {\n if (notes.length === 0) {\n process.stdout.write(`${color(\"(no matches)\", \"gray\", opts)}\\n`);\n return;\n }\n for (const n of notes) {\n const date = n.createdAt.slice(0, 10);\n process.stdout.write(\n `${color(date, \"gray\", opts)} ${color(n.guid, \"dim\", opts)} ${n.title}\\n`,\n );\n }\n if (nextCursor) {\n process.stdout.write(\n `${color(`\\n next: --cursor ${nextCursor}`, \"gray\", opts)}\\n`,\n );\n }\n}\n","import { Command } from \"commander\";\nimport { createApiClient } from \"../../lib/api/client.ts\";\nimport {\n NoteSchema,\n ParagraphSchema,\n SimpleListResponseSchema,\n PageCursorResponseSchema,\n type Paragraph,\n} from \"../../lib/api/types.ts\";\nimport { writeFileAtomic } from \"../../lib/output/file.ts\";\nimport { formatNote, type FileFormat } from \"../../lib/output/format.ts\";\nimport { paragraphsToMcp } from \"../../lib/output/transcript.ts\";\nimport { printOutput } from \"../../lib/output/print.ts\";\nimport { resolveOutputMode, color } from \"../../lib/output/tty.ts\";\nimport { TiroError, ExitCode } from \"../../lib/error.ts\";\n\ninterface GetOptions {\n output?: string;\n format?: string;\n include?: string;\n force?: boolean;\n hostname?: string;\n json?: boolean;\n pretty?: boolean;\n noColor?: boolean;\n quiet?: boolean;\n}\n\nconst ALLOWED_INCLUDES = new Set([\"transcript\"]);\n\nconst ParagraphsListSchema = SimpleListResponseSchema(ParagraphSchema);\nconst ParagraphsCursorSchema = PageCursorResponseSchema(ParagraphSchema);\n\nexport function registerNotesGet(parent: Command): void {\n parent\n .command(\"get <guid>\")\n .description(\"Get a single note (stdout or file)\")\n .option(\"--output <path>\", \"Write to file (stdout becomes metadata only)\")\n .option(\"--format <md|json|txt>\", \"Output format (default: md for TTY, json for pipe)\")\n .option(\n \"--include <items>\",\n \"Comma-separated extras (v0.2.0 supports: transcript)\",\n \"\",\n )\n .option(\"--force\", \"Overwrite existing file\")\n .action(async (guid: string, opts: GetOptions, cmd: Command) => {\n const globalOpts = cmd.optsWithGlobals<GetOptions>();\n\n const includes = parseIncludes(opts.include);\n validateIncludes(includes);\n const format = pickFormat(opts.format, opts.output);\n\n const client = createApiClient({\n ...(globalOpts.hostname !== undefined && { hostnameOverride: globalOpts.hostname }),\n });\n\n const note = await client.getJson(`/v1/external/notes/${guid}`, NoteSchema);\n\n let paragraphs: Paragraph[] | undefined;\n if (includes.has(\"transcript\") || format === \"txt\") {\n paragraphs = await fetchAllParagraphs(client, guid);\n }\n\n const content = formatNote(note, format, {\n includeTranscript: includes.has(\"transcript\"),\n ...(paragraphs !== undefined && { paragraphs }),\n });\n\n if (opts.output) {\n const result = await writeFileAtomic(opts.output, content, {\n ...(opts.force === true && { force: true }),\n });\n printOutput(\n {\n ok: true,\n data: {\n saved: result.path,\n size: result.size,\n format,\n guid: note.guid,\n title: note.title,\n },\n },\n globalOpts,\n );\n return;\n }\n\n const mode = resolveOutputMode(globalOpts);\n if (mode === \"json\" && format !== \"json\") {\n printOutput(\n {\n ok: true,\n data: {\n ...note,\n ...(paragraphs && { transcript: { paragraphs: paragraphsToMcp(paragraphs) } }),\n },\n },\n globalOpts,\n );\n } else if (format === \"json\") {\n process.stdout.write(content);\n } else {\n if (process.stdout.isTTY && format === \"txt\") {\n process.stdout.write(`${color(`# ${note.title}`, \"bold\", globalOpts)}\\n\\n`);\n }\n process.stdout.write(content);\n }\n });\n}\n\nasync function fetchAllParagraphs(\n client: ReturnType<typeof createApiClient>,\n guid: string,\n): Promise<Paragraph[]> {\n const first = await client.getJson(\n `/v1/external/notes/${guid}/paragraphs`,\n ParagraphsCursorSchema.or(ParagraphsListSchema),\n );\n const all: Paragraph[] = [...first.content];\n if (\"nextCursor\" in first) {\n let cursor = first.nextCursor;\n while (cursor) {\n const next = await client.getJson(\n `/v1/external/notes/${guid}/paragraphs`,\n ParagraphsCursorSchema,\n { cursor },\n );\n all.push(...next.content);\n cursor = next.nextCursor;\n }\n }\n return all;\n}\n\nfunction parseIncludes(raw?: string): Set<string> {\n if (!raw) return new Set();\n return new Set(\n raw\n .split(\",\")\n .map((s) => s.trim().toLowerCase())\n .filter((s) => s.length > 0),\n );\n}\n\nfunction validateIncludes(includes: Set<string>): void {\n for (const inc of includes) {\n if (!ALLOWED_INCLUDES.has(inc)) {\n throw new TiroError(\n {\n code: \"invalid_include\",\n message: `Invalid --include \"${inc}\". v0.2.0 supports: transcript.`,\n errorType: \"bad_request\",\n suggestion: \"Use --include transcript\",\n },\n ExitCode.Usage,\n );\n }\n }\n}\n\nfunction pickFormat(format: string | undefined, output: string | undefined): FileFormat {\n const allowed: FileFormat[] = [\"md\", \"json\", \"txt\"];\n if (format) {\n const f = format.toLowerCase() as FileFormat;\n if (!allowed.includes(f)) {\n throw new TiroError(\n {\n code: \"invalid_format\",\n message: `Invalid --format \"${format}\". Allowed: md, json, txt.`,\n errorType: \"bad_request\",\n },\n ExitCode.Usage,\n );\n }\n return f;\n }\n if (output) {\n if (output.endsWith(\".json\")) return \"json\";\n if (output.endsWith(\".txt\")) return \"txt\";\n return \"md\";\n }\n return process.stdout.isTTY ? \"md\" : \"json\";\n}\n","import { mkdir, rename, stat, writeFile, access } from \"node:fs/promises\";\nimport { dirname, resolve } from \"node:path\";\nimport { TiroError, ExitCode } from \"../error.ts\";\n\nexport interface WriteResult {\n path: string;\n size: number;\n}\n\nexport async function writeFileAtomic(\n filepath: string,\n content: string,\n opts: { force?: boolean } = {},\n): Promise<WriteResult> {\n const absPath = resolve(filepath);\n await mkdir(dirname(absPath), { recursive: true });\n\n if (!opts.force) {\n const exists = await fileExists(absPath);\n if (exists) {\n throw new TiroError(\n {\n code: \"file_exists\",\n message: `File already exists: ${absPath}`,\n errorType: \"conflict\",\n suggestion: \"Use --force to overwrite, or pick a different --output.\",\n },\n ExitCode.Generic,\n );\n }\n }\n\n const tmp = `${absPath}.tmp.${process.pid}.${Date.now()}`;\n await writeFile(tmp, content, \"utf8\");\n await rename(tmp, absPath);\n const s = await stat(absPath);\n return { path: absPath, size: s.size };\n}\n\nasync function fileExists(p: string): Promise<boolean> {\n try {\n await access(p);\n return true;\n } catch {\n return false;\n }\n}\n","import type {\n McpParagraph,\n McpSegment,\n McpTranscript,\n Note,\n Paragraph,\n} from \"../api/types.ts\";\n\nexport function buildMcpTranscript(note: Note, paragraphs: Paragraph[]): McpTranscript {\n return {\n noteGuid: note.guid,\n title: note.title,\n participants:\n note.participants\n ?.map((p) => p.name || p.email || \"\")\n .filter((s): s is string => typeof s === \"string\" && s.length > 0) ?? [],\n createdAt: note.createdAt,\n recordingDurationSeconds: note.recordingDurationSeconds,\n paragraphs: paragraphsToMcp(paragraphs),\n };\n}\n\nexport function paragraphsToMcp(paragraphs: Paragraph[]): McpParagraph[] {\n return paragraphs\n .map((p) => ({\n timeFrom: p.timeFrom ?? null,\n timeTo: p.timeTo ?? null,\n segments: paragraphToSegments(p),\n }))\n .filter((p) => p.segments.length > 0);\n}\n\nfunction paragraphToSegments(p: Paragraph): McpSegment[] {\n const ds = p.diarizedSegments;\n if (ds && ds.length > 0) {\n return ds\n .map((s) => ({\n content: stripHtml(s.content),\n speaker: {\n label: s.speaker.label,\n name: s.speaker.personName ? stripHtml(s.speaker.personName) : null,\n },\n }))\n .filter((s) => s.content.length > 0);\n }\n const plain = stripHtml(p.transcript?.content ?? \"\");\n return plain ? [{ content: plain, speaker: null }] : [];\n}\n\nexport function renderTranscriptJson(t: McpTranscript): string {\n return `${JSON.stringify(t, null, 2)}\\n`;\n}\n\nexport function renderTranscriptMarkdown(t: McpTranscript): string {\n const anchor = anchorTime(t);\n const lines: string[] = [];\n lines.push(`# ${t.title}`, \"\");\n\n if (t.participants.length > 0) {\n lines.push(`**Participants**: ${t.participants.join(\", \")}`, \"\");\n }\n\n lines.push(\"## Transcript\", \"\");\n for (const p of t.paragraphs) {\n const ts = elapsed(p.timeFrom, anchor);\n for (const s of p.segments) {\n const who = s.speaker?.name ?? s.speaker?.label ?? \"Unknown\";\n const tag = ts ? `${who}, ${ts}` : who;\n lines.push(`**[${tag}]** ${s.content}`);\n }\n lines.push(\"\");\n }\n\n return `${lines.join(\"\\n\").trimEnd()}\\n`;\n}\n\nexport function renderTranscriptText(t: McpTranscript): string {\n const lines: string[] = [];\n for (const p of t.paragraphs) {\n for (const s of p.segments) {\n const who = s.speaker?.name ?? s.speaker?.label ?? \"Unknown\";\n lines.push(`[${who}] ${s.content}`);\n }\n }\n return `${lines.join(\"\\n\")}\\n`;\n}\n\nfunction anchorTime(t: McpTranscript): string | null {\n for (const p of t.paragraphs) {\n if (p.timeFrom) return p.timeFrom;\n }\n return null;\n}\n\nfunction elapsed(currentIso: string | null, anchorIso: string | null): string {\n if (!currentIso || !anchorIso) return \"\";\n const cur = Date.parse(currentIso);\n const anc = Date.parse(anchorIso);\n if (!Number.isFinite(cur) || !Number.isFinite(anc)) return \"\";\n const seconds = Math.max(0, Math.floor((cur - anc) / 1000));\n const h = Math.floor(seconds / 3600);\n const m = Math.floor((seconds % 3600) / 60);\n const s = seconds % 60;\n if (h > 0) return `${pad(h)}:${pad(m)}:${pad(s)}`;\n return `${pad(m)}:${pad(s)}`;\n}\n\nfunction pad(n: number): string {\n return n.toString().padStart(2, \"0\");\n}\n\nfunction stripHtml(s: string): string {\n return s\n .replace(/<[^>]*>/g, \"\")\n .replace(/ /g, \" \")\n .replace(/&/g, \"&\")\n .replace(/</g, \"<\")\n .replace(/>/g, \">\")\n .replace(/"/g, '\"')\n .replace(/'/g, \"'\")\n .trim();\n}\n","import type { Note, Paragraph } from \"../api/types.ts\";\nimport {\n buildMcpTranscript,\n paragraphsToMcp,\n renderTranscriptJson,\n renderTranscriptMarkdown,\n renderTranscriptText,\n} from \"./transcript.ts\";\n\nexport type FileFormat = \"md\" | \"json\" | \"txt\";\n\nexport interface FormatOptions {\n includeTranscript?: boolean;\n paragraphs?: Paragraph[];\n}\n\nexport function formatNote(\n note: Note,\n format: FileFormat,\n opts: FormatOptions = {},\n): string {\n switch (format) {\n case \"md\":\n return formatMarkdown(note, opts);\n case \"json\":\n return formatJson(note, opts);\n case \"txt\":\n return formatText(note, opts);\n }\n}\n\nfunction formatMarkdown(note: Note, opts: FormatOptions): string {\n const fm = [\n \"---\",\n `guid: ${escapeYaml(note.guid)}`,\n `title: ${escapeYaml(note.title)}`,\n `createdAt: ${note.createdAt}`,\n `updatedAt: ${note.updatedAt}`,\n `sourceType: ${note.sourceType}`,\n `recordingDurationSeconds: ${note.recordingDurationSeconds}`,\n `webUrl: ${note.webUrl}`,\n ];\n if (note.recordingStartAt) fm.push(`recordingStartAt: ${note.recordingStartAt}`);\n if (note.recordingEndAt) fm.push(`recordingEndAt: ${note.recordingEndAt}`);\n fm.push(\"---\", \"\");\n\n const parts: string[] = [fm.join(\"\\n\"), `# ${note.title}`, \"\"];\n\n if (note.participants && note.participants.length > 0) {\n parts.push(\"## Participants\", \"\");\n for (const p of note.participants) {\n const name = p.name ?? \"(no name)\";\n const email = p.email ? ` <${p.email}>` : \"\";\n parts.push(`- ${name}${email}`);\n }\n parts.push(\"\");\n }\n\n if (opts.includeTranscript && opts.paragraphs && opts.paragraphs.length > 0) {\n const mcp = buildMcpTranscript(note, opts.paragraphs);\n const transcriptBody = renderTranscriptMarkdown(mcp);\n const startsWithHeader = transcriptBody.startsWith(`# ${note.title}`);\n const trimmed = startsWithHeader\n ? transcriptBody.slice(transcriptBody.indexOf(\"\\n\") + 1)\n : transcriptBody;\n parts.push(trimmed.replace(/^\\s*\\n+/, \"\"));\n }\n\n return `${parts.join(\"\\n\").trimEnd()}\\n`;\n}\n\nfunction formatJson(note: Note, opts: FormatOptions): string {\n const out: Record<string, unknown> = { ...note };\n if (opts.includeTranscript && opts.paragraphs) {\n out[\"transcript\"] = { paragraphs: paragraphsToMcp(opts.paragraphs) };\n }\n return `${JSON.stringify(out, null, 2)}\\n`;\n}\n\nfunction formatText(note: Note, opts: FormatOptions): string {\n if (!opts.paragraphs || opts.paragraphs.length === 0) {\n return `${note.title}\\n${note.webUrl}\\n`;\n }\n const mcp = buildMcpTranscript(note, opts.paragraphs);\n return renderTranscriptText(mcp);\n}\n\nfunction escapeYaml(s: string): string {\n if (/[:#\\n\"']/.test(s)) {\n return JSON.stringify(s);\n }\n return s;\n}\n\nexport {\n buildMcpTranscript,\n renderTranscriptJson,\n renderTranscriptMarkdown,\n renderTranscriptText,\n};\n","import { Command } from \"commander\";\nimport { createApiClient } from \"../../lib/api/client.ts\";\nimport {\n ParagraphSchema,\n PageCursorResponseSchema,\n SimpleListResponseSchema,\n NoteSchema,\n type Paragraph,\n} from \"../../lib/api/types.ts\";\nimport { writeFileAtomic } from \"../../lib/output/file.ts\";\nimport {\n buildMcpTranscript,\n renderTranscriptJson,\n renderTranscriptMarkdown,\n renderTranscriptText,\n} from \"../../lib/output/transcript.ts\";\nimport { type FileFormat } from \"../../lib/output/format.ts\";\nimport { printOutput } from \"../../lib/output/print.ts\";\nimport { resolveOutputMode } from \"../../lib/output/tty.ts\";\nimport { TiroError, ExitCode } from \"../../lib/error.ts\";\n\ninterface TranscriptOptions {\n output?: string;\n format?: string;\n force?: boolean;\n hostname?: string;\n json?: boolean;\n pretty?: boolean;\n noColor?: boolean;\n quiet?: boolean;\n}\n\nconst ParagraphsListSchema = SimpleListResponseSchema(ParagraphSchema);\nconst ParagraphsCursorSchema = PageCursorResponseSchema(ParagraphSchema);\n\nexport function registerNotesTranscript(parent: Command): void {\n parent\n .command(\"transcript <guid>\")\n .description(\"Get the full transcript of a note (matches MCP get_note_transcript JSON shape)\")\n .option(\"--output <path>\", \"Write to file (stdout = metadata only)\")\n .option(\n \"--format <md|json|txt>\",\n \"Output format (default: md for TTY, txt for pipe; json mirrors MCP shape)\",\n )\n .option(\"--force\", \"Overwrite existing file\")\n .action(async (guid: string, opts: TranscriptOptions, cmd: Command) => {\n const globalOpts = cmd.optsWithGlobals<TranscriptOptions>();\n const format = pickFormat(opts.format, opts.output, globalOpts);\n\n const client = createApiClient({\n ...(globalOpts.hostname !== undefined && { hostnameOverride: globalOpts.hostname }),\n });\n\n const note = await client.getJson(`/v1/external/notes/${guid}`, NoteSchema);\n const paragraphs = await fetchAllParagraphs(client, guid);\n const mcp = buildMcpTranscript(note, paragraphs);\n\n const content =\n format === \"json\"\n ? renderTranscriptJson(mcp)\n : format === \"md\"\n ? renderTranscriptMarkdown(mcp)\n : renderTranscriptText(mcp);\n\n if (opts.output) {\n const result = await writeFileAtomic(opts.output, content, {\n ...(opts.force === true && { force: true }),\n });\n printOutput(\n {\n ok: true,\n data: {\n saved: result.path,\n size: result.size,\n format,\n guid: note.guid,\n paragraphCount: mcp.paragraphs.length,\n segmentCount: mcp.paragraphs.reduce((sum, p) => sum + p.segments.length, 0),\n },\n },\n globalOpts,\n );\n return;\n }\n\n const mode = resolveOutputMode(globalOpts);\n if (mode === \"json\" && format !== \"json\") {\n printOutput({ ok: true, data: mcp }, globalOpts);\n } else {\n process.stdout.write(content);\n }\n });\n}\n\nasync function fetchAllParagraphs(\n client: ReturnType<typeof createApiClient>,\n guid: string,\n): Promise<Paragraph[]> {\n const first = await client.getJson(\n `/v1/external/notes/${guid}/paragraphs`,\n ParagraphsCursorSchema.or(ParagraphsListSchema),\n );\n const all: Paragraph[] = [...first.content];\n if (\"nextCursor\" in first) {\n let cursor = first.nextCursor;\n while (cursor) {\n const next = await client.getJson(\n `/v1/external/notes/${guid}/paragraphs`,\n ParagraphsCursorSchema,\n { cursor },\n );\n all.push(...next.content);\n cursor = next.nextCursor;\n }\n }\n return all;\n}\n\nfunction pickFormat(\n format: string | undefined,\n output: string | undefined,\n globalOpts: { json?: boolean; pretty?: boolean },\n): FileFormat {\n const allowed: FileFormat[] = [\"md\", \"json\", \"txt\"];\n if (format) {\n const f = format.toLowerCase() as FileFormat;\n if (!allowed.includes(f)) {\n throw new TiroError(\n {\n code: \"invalid_format\",\n message: `Invalid --format \"${format}\". Allowed: md, json, txt.`,\n errorType: \"bad_request\",\n },\n ExitCode.Usage,\n );\n }\n return f;\n }\n if (output) {\n if (output.endsWith(\".json\")) return \"json\";\n if (output.endsWith(\".md\")) return \"md\";\n if (output.endsWith(\".txt\")) return \"txt\";\n return \"md\";\n }\n if (globalOpts.json) return \"json\";\n if (globalOpts.pretty) return \"md\";\n return process.stdout.isTTY ? \"md\" : \"txt\";\n}\n"],"mappings":"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","names":["Command","resolve","z","DEFAULT_PAGE_SIZE","MAX_PAGE_SIZE","clampLimit","printPretty","ParagraphsListSchema","ParagraphsCursorSchema","pickFormat","fetchAllParagraphs","Command"]}
|
|
1
|
+
{"version":3,"sources":["../../src/bin/tiro.ts","../../src/lib/version.ts","../../src/lib/error.ts","../../src/lib/output/tty.ts","../../src/lib/output/print.ts","../../src/commands/auth/index.ts","../../src/commands/auth/login.ts","../../src/lib/auth/flow.ts","../../src/lib/auth/pkce.ts","../../src/lib/auth/loopback.ts","../../src/lib/auth/browser.ts","../../src/lib/auth/keychain.ts","../../src/lib/auth/token.ts","../../src/lib/config.ts","../../src/commands/auth/status.ts","../../src/commands/auth/logout.ts","../../src/commands/notes/index.ts","../../src/commands/notes/list.ts","../../src/lib/api/client.ts","../../src/lib/api/types.ts","../../src/lib/util/parseDate.ts","../../src/lib/util/noteFilter.ts","../../src/commands/notes/search.ts","../../src/commands/notes/get.ts","../../src/lib/output/file.ts","../../src/lib/output/transcript.ts","../../src/lib/output/format.ts","../../src/commands/notes/transcript.ts","../../src/lib/updateCheck.ts"],"sourcesContent":["import { Command } from \"commander\";\nimport { VERSION } from \"../lib/version.ts\";\nimport { TiroError, ExitCode } from \"../lib/error.ts\";\nimport { printError } from \"../lib/output/print.ts\";\nimport { color } from \"../lib/output/tty.ts\";\nimport { registerAuth } from \"../commands/auth/index.ts\";\nimport { registerNotes } from \"../commands/notes/index.ts\";\nimport { emitUpdateBanner, startUpdateCheck } from \"../lib/updateCheck.ts\";\n\nconst EXAMPLES = `\nEXAMPLES\n $ tiro auth login\n $ tiro notes list --since 7d\n $ tiro notes search \"Q3 Planning\" --since 30d --json\n $ tiro notes get <guid> --output ./meeting.md --include transcript\n $ tiro notes transcript <guid> --format md --output ./transcript.md\n\nENVIRONMENT\n TIRO_TOKEN Bearer token (overrides keychain — for CI / agents)\n TIRO_HOSTNAME API base URL (default: https://api.tiro.ooo)\n NO_COLOR Disable colors (https://no-color.org)\n NO_UPDATE_NOTIFIER Set to \"1\" to disable the update banner\n\nDOCS\n https://api-docs.tiro.ooo/cli/overview\n`;\n\nfunction buildProgram(): Command {\n const program = new Command();\n\n program\n .name(\"tiro\")\n .description(\"Tiro AI notes & transcripts — agent-first command line\")\n .version(VERSION, \"-v, --version\", \"Print version\")\n .option(\"--hostname <url>\", \"API base URL (default: https://api.tiro.ooo)\")\n .option(\"--json\", \"Force JSON output\")\n .option(\"--pretty\", \"Force pretty (human) output\")\n .option(\"--quiet\", \"Suppress non-error output\")\n .option(\"--verbose\", \"Verbose logging to stderr\")\n .option(\"--no-color\", \"Disable ANSI colors\")\n .addHelpText(\"after\", EXAMPLES);\n\n program.showHelpAfterError(\"(run `tiro --help` for available commands)\");\n\n registerAuth(program);\n registerNotes(program);\n\n return program;\n}\n\nasync function main(): Promise<void> {\n const program = buildProgram();\n const notifier = await startUpdateCheck();\n try {\n await program.parseAsync(process.argv);\n emitUpdateBanner(notifier);\n } catch (err) {\n handleError(err, program);\n }\n}\n\nfunction handleError(err: unknown, program: Command): never {\n const opts = program.opts<{ json?: boolean; quiet?: boolean }>();\n\n if (err instanceof TiroError) {\n if (opts.json) {\n printError(err.toJSON());\n } else if (!opts.quiet) {\n process.stderr.write(`${color(\"✗\", \"red\", opts)} ${err.message}\\n`);\n if (err.suggestion) {\n process.stderr.write(` ${color(\"→\", \"gray\", opts)} ${err.suggestion}\\n`);\n }\n }\n process.exit(err.exitCode);\n }\n\n if (err instanceof Error) {\n if (opts.json) {\n printError({\n ok: false,\n error: { code: \"internal_error\", message: err.message, errorType: \"internal_error\" },\n });\n } else if (!opts.quiet) {\n process.stderr.write(`${color(\"✗\", \"red\", opts)} ${err.message}\\n`);\n }\n process.exit(ExitCode.Generic);\n }\n\n process.stderr.write(`Unknown error: ${String(err)}\\n`);\n process.exit(ExitCode.Generic);\n}\n\nmain().catch((err) => {\n process.stderr.write(`Fatal: ${String(err)}\\n`);\n process.exit(ExitCode.Generic);\n});\n","export const VERSION = \"0.1.0\";\n","export const ExitCode = {\n Ok: 0,\n Generic: 1,\n Usage: 2,\n AuthRequired: 4,\n ExUsage: 64,\n ExDataErr: 65,\n ExConfig: 78,\n} as const;\n\nexport type ExitCodeValue = (typeof ExitCode)[keyof typeof ExitCode];\n\nexport type ErrorType =\n | \"bad_request\"\n | \"unauthorized\"\n | \"forbidden\"\n | \"not_found\"\n | \"not_acceptable\"\n | \"conflict\"\n | \"payload_too_large\"\n | \"unprocessable_entity\"\n | \"too_many_requests\"\n | \"internal_error\"\n | \"auth_required\"\n | \"config_missing\"\n | \"network_error\";\n\nexport interface ErrorPayload {\n code: string;\n message: string;\n suggestion?: string;\n errorType?: ErrorType;\n httpStatus?: number;\n requestId?: string;\n}\n\nexport class TiroError extends Error {\n readonly code: string;\n readonly suggestion?: string;\n readonly errorType?: ErrorType;\n readonly httpStatus?: number;\n readonly requestId?: string;\n readonly exitCode: ExitCodeValue;\n\n constructor(payload: ErrorPayload, exitCode: ExitCodeValue = ExitCode.Generic) {\n super(payload.message);\n this.name = \"TiroError\";\n this.code = payload.code;\n this.suggestion = payload.suggestion;\n this.errorType = payload.errorType;\n this.httpStatus = payload.httpStatus;\n this.requestId = payload.requestId;\n this.exitCode = exitCode;\n }\n\n toJSON(): { ok: false; error: ErrorPayload } {\n return {\n ok: false,\n error: {\n code: this.code,\n message: this.message,\n ...(this.suggestion !== undefined && { suggestion: this.suggestion }),\n ...(this.errorType !== undefined && { errorType: this.errorType }),\n ...(this.httpStatus !== undefined && { httpStatus: this.httpStatus }),\n ...(this.requestId !== undefined && { requestId: this.requestId }),\n },\n };\n }\n}\n\nexport function authRequired(): TiroError {\n return new TiroError(\n {\n code: \"auth_required\",\n message:\n \"Not authenticated. Run `tiro auth login` to sign in, or set TIRO_TOKEN env var.\",\n suggestion: \"tiro auth login\",\n errorType: \"auth_required\",\n },\n ExitCode.AuthRequired,\n );\n}\n\nexport function configMissing(message: string, suggestion?: string): TiroError {\n return new TiroError(\n {\n code: \"config_missing\",\n message,\n ...(suggestion !== undefined && { suggestion }),\n errorType: \"config_missing\",\n },\n ExitCode.ExConfig,\n );\n}\n","export type OutputMode = \"json\" | \"pretty\";\n\nexport interface OutputOptions {\n json?: boolean;\n pretty?: boolean;\n noColor?: boolean;\n quiet?: boolean;\n}\n\nexport function resolveOutputMode(opts: OutputOptions): OutputMode {\n if (opts.json) return \"json\";\n if (opts.pretty) return \"pretty\";\n return process.stdout.isTTY ? \"pretty\" : \"json\";\n}\n\nexport function colorEnabled(opts: OutputOptions): boolean {\n if (opts.noColor) return false;\n if (process.env[\"NO_COLOR\"]) return false;\n if (process.env[\"FORCE_COLOR\"]) return true;\n return process.stdout.isTTY === true;\n}\n\nconst ANSI = {\n reset: \"\\x1b[0m\",\n bold: \"\\x1b[1m\",\n dim: \"\\x1b[2m\",\n red: \"\\x1b[31m\",\n green: \"\\x1b[32m\",\n yellow: \"\\x1b[33m\",\n blue: \"\\x1b[34m\",\n magenta: \"\\x1b[35m\",\n cyan: \"\\x1b[36m\",\n gray: \"\\x1b[90m\",\n} as const;\n\nexport function color(\n text: string,\n style: keyof typeof ANSI,\n opts: OutputOptions = {},\n): string {\n if (!colorEnabled(opts)) return text;\n return `${ANSI[style]}${text}${ANSI.reset}`;\n}\n","import { resolveOutputMode, type OutputOptions } from \"./tty.ts\";\n\nexport function printOutput(value: unknown, opts: OutputOptions = {}): void {\n if (opts.quiet) return;\n const mode = resolveOutputMode(opts);\n if (mode === \"json\") {\n process.stdout.write(`${JSON.stringify(value)}\\n`);\n } else {\n process.stdout.write(`${JSON.stringify(value, null, 2)}\\n`);\n }\n}\n\nexport function printError(value: unknown): void {\n process.stderr.write(`${JSON.stringify(value)}\\n`);\n}\n\nexport function printNdjson(item: unknown): void {\n process.stdout.write(`${JSON.stringify(item)}\\n`);\n}\n","import { Command } from \"commander\";\nimport { registerAuthLogin } from \"./login.ts\";\nimport { registerAuthStatus } from \"./status.ts\";\nimport { registerAuthLogout } from \"./logout.ts\";\n\nexport function registerAuth(program: Command): void {\n const auth = program.command(\"auth\").description(\"Manage authentication\");\n registerAuthLogin(auth);\n registerAuthStatus(auth);\n registerAuthLogout(auth);\n}\n","import { Command } from \"commander\";\nimport { performLogin } from \"../../lib/auth/flow.ts\";\nimport { printOutput } from \"../../lib/output/print.ts\";\nimport { color } from \"../../lib/output/tty.ts\";\nimport { getHostname } from \"../../lib/config.ts\";\n\ninterface LoginOptions {\n hostname?: string;\n noBrowser?: boolean;\n json?: boolean;\n pretty?: boolean;\n noColor?: boolean;\n quiet?: boolean;\n}\n\nexport function registerAuthLogin(parent: Command): void {\n parent\n .command(\"login\")\n .description(\"Sign in to Tiro via OAuth (browser-based, PKCE)\")\n .option(\"--hostname <url>\", \"API base URL (overrides config / TIRO_HOSTNAME)\")\n .option(\"--no-browser\", \"Print the URL instead of opening a browser\")\n .action(async (opts: LoginOptions, cmd: Command) => {\n const globalOpts = cmd.optsWithGlobals<LoginOptions>();\n const result = await performLogin({\n ...(opts.hostname !== undefined && { hostname: opts.hostname }),\n noBrowser: opts.noBrowser === true,\n onPrompt: (msg) => {\n if (globalOpts.quiet) return;\n process.stderr.write(`${color(msg, \"cyan\", globalOpts)}\\n`);\n },\n });\n\n const hostname = getHostname(opts.hostname);\n const expiresIso = new Date(result.expiresAt).toISOString();\n\n if (globalOpts.json) {\n printOutput(\n {\n ok: true,\n data: {\n signedIn: true,\n hostname,\n userId: result.userId ?? null,\n expiresAt: expiresIso,\n },\n },\n globalOpts,\n );\n } else if (!globalOpts.quiet) {\n process.stderr.write(`${color(\"✓\", \"green\", globalOpts)} Signed in to ${hostname}\\n`);\n if (result.userId) {\n process.stderr.write(` user: ${result.userId}\\n`);\n }\n process.stderr.write(` token expires: ${expiresIso}\\n`);\n }\n });\n}\n","import { z } from \"zod\";\nimport { TiroError, ExitCode } from \"../error.ts\";\nimport { generatePkce, generateState } from \"./pkce.ts\";\nimport { startLoopbackServer } from \"./loopback.ts\";\nimport { openBrowser } from \"./browser.ts\";\nimport { saveToken, type StoredToken } from \"./keychain.ts\";\nimport { decodeJwtPayload } from \"./token.ts\";\nimport {\n getHostname,\n getOauthClientId,\n setOauthClientId,\n clearOauthClientId,\n} from \"../config.ts\";\n\nconst RegisterResponseSchema = z.object({\n client_id: z.string(),\n client_secret: z.string().optional(),\n});\n\nconst TokenResponseSchema = z.object({\n access_token: z.string(),\n token_type: z.string(),\n expires_in: z.number().optional(),\n scope: z.string().optional(),\n});\n\nconst CALLBACK_TIMEOUT_MS = 5 * 60 * 1000;\nconst DEFAULT_SCOPE = \"mcp:notes:read\";\n\nexport interface LoginOptions {\n hostname?: string;\n noBrowser?: boolean;\n scope?: string;\n onPrompt?: (msg: string) => void;\n}\n\nexport interface LoginResult {\n hostname: string;\n userId: string | undefined;\n expiresAt: number;\n}\n\nexport async function performLogin(options: LoginOptions = {}): Promise<LoginResult> {\n const hostname = getHostname(options.hostname);\n const onPrompt = options.onPrompt ?? ((msg: string) => process.stderr.write(`${msg}\\n`));\n\n const loopback = await startLoopbackServer();\n\n try {\n const clientId = await ensureOauthClient(hostname, loopback.redirectUri);\n const { codeVerifier, codeChallenge } = generatePkce();\n const state = generateState();\n\n const authorizeUrl = buildAuthorizeUrl({\n hostname,\n clientId,\n redirectUri: loopback.redirectUri,\n state,\n codeChallenge,\n scope: options.scope ?? DEFAULT_SCOPE,\n });\n\n if (options.noBrowser) {\n onPrompt(`Open this URL in your browser:\\n${authorizeUrl}`);\n } else {\n onPrompt(`Opening browser for sign-in...`);\n onPrompt(`If the browser does not open, visit:\\n${authorizeUrl}`);\n await openBrowser(authorizeUrl);\n }\n\n const callback = await loopback.waitForCallback(CALLBACK_TIMEOUT_MS);\n\n if (callback.state !== state) {\n throw new TiroError(\n {\n code: \"auth_state_mismatch\",\n message: \"OAuth state mismatch — possible CSRF. Aborting.\",\n errorType: \"unauthorized\",\n },\n ExitCode.Generic,\n );\n }\n\n const tokenRes = await exchangeToken({\n hostname,\n clientId,\n code: callback.code,\n redirectUri: loopback.redirectUri,\n codeVerifier,\n });\n\n const expiresAt = computeExpiry(tokenRes.expires_in);\n const payload = decodeJwtPayload(tokenRes.access_token);\n const userId = typeof payload?.[\"sub\"] === \"string\" ? (payload[\"sub\"] as string) : undefined;\n\n const stored: StoredToken = {\n accessToken: tokenRes.access_token,\n tokenType: tokenRes.token_type,\n expiresAt,\n hostname,\n ...(tokenRes.scope !== undefined && { scope: tokenRes.scope }),\n ...(userId !== undefined && { userId }),\n };\n saveToken(stored);\n\n return { hostname, userId, expiresAt };\n } finally {\n loopback.close();\n }\n}\n\nasync function ensureOauthClient(hostname: string, redirectUri: string): Promise<string> {\n const cached = getOauthClientId();\n if (cached) return cached;\n\n const url = `${hostname}/v1/mcp/oauth/register`;\n let res: Response;\n try {\n res = await fetch(url, {\n method: \"POST\",\n headers: { \"Content-Type\": \"application/json\" },\n body: JSON.stringify({\n client_name: \"tiro-cli\",\n redirect_uris: [redirectUri],\n grant_types: [\"authorization_code\"],\n response_types: [\"code\"],\n token_endpoint_auth_method: \"none\",\n scope: DEFAULT_SCOPE,\n }),\n });\n } catch (err) {\n throw new TiroError(\n {\n code: \"network_error\",\n message: `Failed to reach ${hostname}: ${(err as Error).message}`,\n errorType: \"network_error\",\n suggestion: \"Check your network connection or --hostname.\",\n },\n ExitCode.Generic,\n );\n }\n\n if (!res.ok) {\n const detail = await safeText(res);\n throw new TiroError(\n {\n code: \"oauth_register_failed\",\n message: `Dynamic Client Registration failed: HTTP ${res.status}`,\n errorType: \"internal_error\",\n httpStatus: res.status,\n ...(detail !== \"\" && { suggestion: detail.slice(0, 200) }),\n },\n ExitCode.Generic,\n );\n }\n\n const json = (await res.json()) as unknown;\n const parsed = RegisterResponseSchema.safeParse(json);\n if (!parsed.success) {\n throw new TiroError(\n {\n code: \"oauth_register_invalid\",\n message: \"Registration response did not match expected shape.\",\n errorType: \"internal_error\",\n },\n ExitCode.Generic,\n );\n }\n\n setOauthClientId(parsed.data.client_id);\n return parsed.data.client_id;\n}\n\ninterface AuthorizeUrlInput {\n hostname: string;\n clientId: string;\n redirectUri: string;\n state: string;\n codeChallenge: string;\n scope: string;\n}\n\nfunction buildAuthorizeUrl(input: AuthorizeUrlInput): string {\n const u = new URL(`${input.hostname}/v1/mcp/oauth/authorize`);\n u.searchParams.set(\"response_type\", \"code\");\n u.searchParams.set(\"client_id\", input.clientId);\n u.searchParams.set(\"redirect_uri\", input.redirectUri);\n u.searchParams.set(\"state\", input.state);\n u.searchParams.set(\"code_challenge\", input.codeChallenge);\n u.searchParams.set(\"code_challenge_method\", \"S256\");\n u.searchParams.set(\"scope\", input.scope);\n return u.toString();\n}\n\ninterface ExchangeInput {\n hostname: string;\n clientId: string;\n code: string;\n redirectUri: string;\n codeVerifier: string;\n}\n\nasync function exchangeToken(input: ExchangeInput): Promise<z.infer<typeof TokenResponseSchema>> {\n const url = `${input.hostname}/v1/mcp/oauth/token`;\n const body = new URLSearchParams({\n grant_type: \"authorization_code\",\n code: input.code,\n redirect_uri: input.redirectUri,\n client_id: input.clientId,\n code_verifier: input.codeVerifier,\n });\n\n let res: Response;\n try {\n res = await fetch(url, {\n method: \"POST\",\n headers: { \"Content-Type\": \"application/x-www-form-urlencoded\" },\n body: body.toString(),\n });\n } catch (err) {\n throw new TiroError(\n {\n code: \"network_error\",\n message: `Failed to reach ${input.hostname}: ${(err as Error).message}`,\n errorType: \"network_error\",\n },\n ExitCode.Generic,\n );\n }\n\n if (!res.ok) {\n if (res.status === 400 || res.status === 401) {\n // Cached client_id may have expired (Redis 30-day TTL). Force re-registration on next try.\n clearOauthClientId();\n }\n const detail = await safeText(res);\n throw new TiroError(\n {\n code: \"oauth_token_failed\",\n message: `Token exchange failed: HTTP ${res.status}`,\n errorType: \"unauthorized\",\n httpStatus: res.status,\n ...(detail !== \"\" && { suggestion: detail.slice(0, 200) }),\n },\n ExitCode.AuthRequired,\n );\n }\n\n const json = (await res.json()) as unknown;\n const parsed = TokenResponseSchema.safeParse(json);\n if (!parsed.success) {\n throw new TiroError(\n {\n code: \"oauth_token_invalid\",\n message: \"Token response did not match expected shape.\",\n errorType: \"internal_error\",\n },\n ExitCode.Generic,\n );\n }\n return parsed.data;\n}\n\nfunction computeExpiry(expiresIn?: number): number {\n // McpJwtService issues 180-day tokens; if expires_in absent, fall back to 180 days.\n const fallbackSeconds = 180 * 24 * 60 * 60;\n const seconds = expiresIn ?? fallbackSeconds;\n return Date.now() + seconds * 1000;\n}\n\nasync function safeText(res: Response): Promise<string> {\n try {\n return await res.text();\n } catch {\n return \"\";\n }\n}\n","import { createHash, randomBytes } from \"node:crypto\";\n\nexport interface PkcePair {\n codeVerifier: string;\n codeChallenge: string;\n method: \"S256\";\n}\n\nexport function generatePkce(): PkcePair {\n const codeVerifier = base64url(randomBytes(32));\n const codeChallenge = base64url(createHash(\"sha256\").update(codeVerifier).digest());\n return { codeVerifier, codeChallenge, method: \"S256\" };\n}\n\nexport function generateState(): string {\n return base64url(randomBytes(24));\n}\n\nfunction base64url(buf: Buffer): string {\n return buf\n .toString(\"base64\")\n .replace(/\\+/g, \"-\")\n .replace(/\\//g, \"_\")\n .replace(/=+$/, \"\");\n}\n","import http from \"node:http\";\nimport type { AddressInfo } from \"node:net\";\n\nexport interface CallbackResult {\n code: string;\n state: string;\n}\n\nexport interface LoopbackServer {\n redirectUri: string;\n port: number;\n waitForCallback: (timeoutMs: number) => Promise<CallbackResult>;\n close: () => void;\n}\n\nexport async function startLoopbackServer(): Promise<LoopbackServer> {\n let pendingResolve: ((r: CallbackResult) => void) | null = null;\n let pendingReject: ((e: Error) => void) | null = null;\n\n const settle = (\n fn: ((arg: CallbackResult) => void) | ((arg: Error) => void),\n arg: CallbackResult | Error,\n ): void => {\n pendingResolve = null;\n pendingReject = null;\n (fn as (arg: CallbackResult | Error) => void)(arg);\n };\n\n const server = http.createServer((req, res) => {\n if (!req.url) {\n res.writeHead(400).end();\n return;\n }\n const url = new URL(req.url, `http://127.0.0.1`);\n if (url.pathname !== \"/callback\") {\n res.writeHead(404, { \"Content-Type\": \"text/plain\" }).end(\"Not found\");\n return;\n }\n\n const code = url.searchParams.get(\"code\");\n const state = url.searchParams.get(\"state\");\n const error = url.searchParams.get(\"error\");\n const errorDesc = url.searchParams.get(\"error_description\") ?? \"\";\n\n if (error) {\n const msg = `OAuth error: ${error}${errorDesc ? ` — ${errorDesc}` : \"\"}`;\n respondPage(res, 500, \"Login failed\", msg);\n if (pendingReject) settle(pendingReject, new Error(msg));\n return;\n }\n if (!code || !state) {\n respondPage(res, 400, \"Missing parameters\", \"Missing `code` or `state`.\");\n if (pendingReject) settle(pendingReject, new Error(\"Missing code or state\"));\n return;\n }\n\n respondPage(\n res,\n 200,\n \"Login successful\",\n \"You're signed in. You can close this tab and return to the terminal.\",\n );\n if (pendingResolve) settle(pendingResolve, { code, state });\n });\n\n await new Promise<void>((resolve) => {\n server.listen(0, \"127.0.0.1\", () => resolve());\n });\n\n const address = server.address() as AddressInfo;\n const port = address.port;\n const redirectUri = `http://127.0.0.1:${port}/callback`;\n\n return {\n redirectUri,\n port,\n waitForCallback(timeoutMs: number) {\n return new Promise<CallbackResult>((resolve, reject) => {\n const timer = setTimeout(() => {\n pendingResolve = null;\n pendingReject = null;\n reject(new Error(`Timed out waiting for OAuth callback (${timeoutMs}ms)`));\n }, timeoutMs);\n pendingResolve = (r) => {\n clearTimeout(timer);\n resolve(r);\n };\n pendingReject = (e) => {\n clearTimeout(timer);\n reject(e);\n };\n });\n },\n close() {\n server.close();\n },\n };\n}\n\nfunction respondPage(\n res: http.ServerResponse,\n status: number,\n title: string,\n body: string,\n): void {\n const html = `<!doctype html>\n<html lang=\"en\">\n<head>\n <meta charset=\"utf-8\">\n <title>${title}</title>\n <style>\n body { font-family: -apple-system, system-ui, sans-serif; padding: 4rem; max-width: 32rem; margin: 0 auto; color: #1a1a1a; }\n h1 { font-size: 1.5rem; margin-bottom: 1rem; }\n p { color: #555; line-height: 1.5; }\n </style>\n</head>\n<body>\n <h1>${title}</h1>\n <p>${body}</p>\n</body>\n</html>`;\n res.writeHead(status, { \"Content-Type\": \"text/html; charset=utf-8\" });\n res.end(html);\n}\n","import open from \"open\";\n\nexport async function openBrowser(url: string): Promise<void> {\n try {\n await open(url, { wait: false });\n } catch {\n // Best-effort. Caller already prints the URL for manual fallback.\n }\n}\n","import { Entry } from \"@napi-rs/keyring\";\nimport { TiroError, ExitCode } from \"../error.ts\";\n\nconst SERVICE = \"io.tiro.cli\";\nconst ACCOUNT = \"default\";\n\nexport interface StoredToken {\n accessToken: string;\n tokenType: string;\n expiresAt: number;\n scope?: string;\n hostname: string;\n userId?: string;\n}\n\nexport function saveToken(token: StoredToken): void {\n const entry = new Entry(SERVICE, ACCOUNT);\n try {\n entry.setPassword(JSON.stringify(token));\n } catch (err) {\n throw new TiroError(\n {\n code: \"keychain_write_failed\",\n message: `Failed to write to OS keychain: ${(err as Error).message}`,\n errorType: \"internal_error\",\n suggestion:\n process.platform === \"linux\"\n ? \"Linux requires a Secret Service daemon (gnome-keyring or kwallet). Or set TIRO_TOKEN env var.\"\n : \"Check OS keychain permissions, or set TIRO_TOKEN env var.\",\n },\n ExitCode.Generic,\n );\n }\n}\n\nexport function loadToken(): StoredToken | null {\n const entry = new Entry(SERVICE, ACCOUNT);\n let raw: string | null;\n try {\n raw = entry.getPassword();\n } catch {\n return null;\n }\n if (!raw) return null;\n try {\n return JSON.parse(raw) as StoredToken;\n } catch {\n return null;\n }\n}\n\nexport function deleteToken(): boolean {\n const entry = new Entry(SERVICE, ACCOUNT);\n try {\n return entry.deletePassword();\n } catch {\n return false;\n }\n}\n","import { loadToken, type StoredToken } from \"./keychain.ts\";\nimport { authRequired } from \"../error.ts\";\n\nexport interface ResolvedToken {\n accessToken: string;\n source: \"env\" | \"keychain\";\n hostname?: string;\n expiresAt?: number;\n userId?: string;\n}\n\nexport function resolveToken(): ResolvedToken | null {\n const envToken = process.env[\"TIRO_TOKEN\"];\n if (envToken) {\n return { accessToken: envToken, source: \"env\" };\n }\n const stored = loadToken();\n if (stored) {\n return {\n accessToken: stored.accessToken,\n source: \"keychain\",\n hostname: stored.hostname,\n expiresAt: stored.expiresAt,\n ...(stored.userId !== undefined && { userId: stored.userId }),\n };\n }\n return null;\n}\n\nexport function requireToken(): ResolvedToken {\n const t = resolveToken();\n if (!t) throw authRequired();\n return t;\n}\n\nexport function decodeJwtPayload(token: string): Record<string, unknown> | null {\n const parts = token.split(\".\");\n if (parts.length !== 3) return null;\n try {\n const payload = parts[1];\n if (!payload) return null;\n const json = Buffer.from(payload, \"base64url\").toString(\"utf8\");\n return JSON.parse(json) as Record<string, unknown>;\n } catch {\n return null;\n }\n}\n\nexport function isTokenExpired(stored: StoredToken): boolean {\n return Date.now() >= stored.expiresAt;\n}\n","import Conf from \"conf\";\n\ninterface TiroConfigSchema {\n hostname: string;\n oauthClientId: string | null;\n oauthClientIdRegisteredAt: number | null;\n defaultOutputDir: string | null;\n}\n\nconst DEFAULT_HOSTNAME = \"https://api.tiro.ooo\";\n\nconst config = new Conf<TiroConfigSchema>({\n projectName: \"tiro\",\n defaults: {\n hostname: DEFAULT_HOSTNAME,\n oauthClientId: null,\n oauthClientIdRegisteredAt: null,\n defaultOutputDir: null,\n },\n});\n\nexport function getHostname(override?: string): string {\n if (override) return stripTrailingSlash(override);\n const env = process.env[\"TIRO_HOSTNAME\"];\n if (env) return stripTrailingSlash(env);\n return stripTrailingSlash(config.get(\"hostname\"));\n}\n\nexport function setHostname(hostname: string): void {\n config.set(\"hostname\", stripTrailingSlash(hostname));\n}\n\nexport function getOauthClientId(): string | null {\n const id = config.get(\"oauthClientId\");\n const registeredAt = config.get(\"oauthClientIdRegisteredAt\");\n if (!id || !registeredAt) return null;\n // DCR clients have 30-day TTL on the backend (Redis). Treat them as expired\n // a day earlier to avoid edge-case 401s during exchange.\n const ttlMs = 29 * 24 * 60 * 60 * 1000;\n if (Date.now() - registeredAt > ttlMs) return null;\n return id;\n}\n\nexport function setOauthClientId(clientId: string): void {\n config.set(\"oauthClientId\", clientId);\n config.set(\"oauthClientIdRegisteredAt\", Date.now());\n}\n\nexport function clearOauthClientId(): void {\n config.set(\"oauthClientId\", null);\n config.set(\"oauthClientIdRegisteredAt\", null);\n}\n\nexport function getDefaultOutputDir(): string | null {\n const env = process.env[\"TIRO_OUTPUT_DIR\"];\n if (env) return env;\n return config.get(\"defaultOutputDir\");\n}\n\nexport function getConfigPath(): string {\n return config.path;\n}\n\nfunction stripTrailingSlash(s: string): string {\n return s.endsWith(\"/\") ? s.slice(0, -1) : s;\n}\n","import { Command } from \"commander\";\nimport { resolveToken, decodeJwtPayload } from \"../../lib/auth/token.ts\";\nimport { printOutput } from \"../../lib/output/print.ts\";\nimport { color } from \"../../lib/output/tty.ts\";\nimport { authRequired } from \"../../lib/error.ts\";\n\ninterface StatusReport {\n signedIn: boolean;\n source: \"env\" | \"keychain\";\n hostname: string | null;\n userId: string | null;\n scope: string | null;\n expiresAt: string | null;\n expired: boolean;\n tokenPrefix: string;\n}\n\ninterface StatusOptions {\n json?: boolean;\n pretty?: boolean;\n noColor?: boolean;\n quiet?: boolean;\n}\n\nexport function registerAuthStatus(parent: Command): void {\n parent\n .command(\"status\")\n .description(\"Show current authenticated account and scopes\")\n .action(async (_opts: StatusOptions, cmd: Command) => {\n const globalOpts = cmd.optsWithGlobals<StatusOptions>();\n const t = resolveToken();\n if (!t) {\n throw authRequired();\n }\n\n const payload = decodeJwtPayload(t.accessToken);\n const sub = typeof payload?.[\"sub\"] === \"string\" ? (payload[\"sub\"] as string) : null;\n const exp = typeof payload?.[\"exp\"] === \"number\" ? (payload[\"exp\"] as number) * 1000 : null;\n const scope = typeof payload?.[\"scope\"] === \"string\" ? (payload[\"scope\"] as string) : null;\n\n const expMs = exp ?? t.expiresAt ?? null;\n const expired = expMs !== null && Date.now() >= expMs;\n\n const report: StatusReport = {\n signedIn: true,\n source: t.source,\n hostname: t.hostname ?? null,\n userId: t.userId ?? sub,\n scope,\n expiresAt: expMs ? new Date(expMs).toISOString() : null,\n expired,\n tokenPrefix: `${t.accessToken.slice(0, 4)}...***`,\n };\n\n if (globalOpts.json || !process.stdout.isTTY) {\n printOutput({ ok: true, data: report }, globalOpts);\n } else {\n const headIcon = expired ? color(\"!\", \"yellow\", globalOpts) : color(\"✓\", \"green\", globalOpts);\n const headText = expired ? \"Token expired\" : \"Signed in\";\n process.stdout.write(`${headIcon} ${headText}\\n`);\n process.stdout.write(` source: ${report.source}\\n`);\n if (report.hostname) process.stdout.write(` hostname: ${report.hostname}\\n`);\n if (report.userId) process.stdout.write(` user: ${report.userId}\\n`);\n if (report.scope) process.stdout.write(` scope: ${report.scope}\\n`);\n if (report.expiresAt) {\n const tag = expired ? color(\" (expired)\", \"red\", globalOpts) : \"\";\n process.stdout.write(` expires at: ${report.expiresAt}${tag}\\n`);\n }\n process.stdout.write(` token: ${report.tokenPrefix}\\n`);\n if (expired) {\n process.stdout.write(\n `\\n${color(\"→\", \"gray\", globalOpts)} Run \\`tiro auth login\\` to refresh.\\n`,\n );\n }\n }\n });\n}\n","import { Command } from \"commander\";\nimport { deleteToken } from \"../../lib/auth/keychain.ts\";\nimport { clearOauthClientId } from \"../../lib/config.ts\";\nimport { printOutput } from \"../../lib/output/print.ts\";\nimport { color } from \"../../lib/output/tty.ts\";\n\ninterface LogoutOptions {\n json?: boolean;\n pretty?: boolean;\n noColor?: boolean;\n quiet?: boolean;\n}\n\nexport function registerAuthLogout(parent: Command): void {\n parent\n .command(\"logout\")\n .description(\"Sign out and clear the stored token\")\n .action(async (_opts: LogoutOptions, cmd: Command) => {\n const globalOpts = cmd.optsWithGlobals<LogoutOptions>();\n const removed = deleteToken();\n clearOauthClientId();\n\n if (globalOpts.json) {\n printOutput({ ok: true, data: { signedOut: true, hadToken: removed } }, globalOpts);\n } else if (!globalOpts.quiet) {\n if (removed) {\n process.stderr.write(`${color(\"✓\", \"green\", globalOpts)} Signed out\\n`);\n } else {\n process.stderr.write(`${color(\"•\", \"gray\", globalOpts)} No token was stored\\n`);\n }\n }\n });\n}\n","import { Command } from \"commander\";\nimport { registerNotesList } from \"./list.ts\";\nimport { registerNotesSearch } from \"./search.ts\";\nimport { registerNotesGet } from \"./get.ts\";\nimport { registerNotesTranscript } from \"./transcript.ts\";\n\nexport function registerNotes(program: Command): void {\n const notes = program.command(\"notes\").description(\"List, search, and download notes\");\n registerNotesList(notes);\n registerNotesSearch(notes);\n registerNotesGet(notes);\n registerNotesTranscript(notes);\n}\n","import { Command } from \"commander\";\nimport { createApiClient } from \"../../lib/api/client.ts\";\nimport { NoteSchema, PageCursorResponseSchema } from \"../../lib/api/types.ts\";\nimport { printNdjson } from \"../../lib/output/print.ts\";\nimport { resolveOutputMode, color } from \"../../lib/output/tty.ts\";\nimport { parseDate } from \"../../lib/util/parseDate.ts\";\nimport { isVisibleNote } from \"../../lib/util/noteFilter.ts\";\n\ninterface ListOptions {\n keyword?: string;\n folder?: string;\n since?: string;\n until?: string;\n limit?: string;\n cursor?: string;\n includeUntitled?: boolean;\n hostname?: string;\n json?: boolean;\n pretty?: boolean;\n noColor?: boolean;\n quiet?: boolean;\n}\n\nconst ListResponseSchema = PageCursorResponseSchema(NoteSchema);\n\nconst DEFAULT_PAGE_SIZE = 100;\nconst MAX_PAGE_SIZE = 1000;\n\nconst HELP_AFTER = `\nExamples:\n tiro notes list --since 7d\n tiro notes list --keyword \"OKR\" --since 30d --json\n tiro notes list --folder <id> --limit 50\n\nKeyword matching:\n --keyword reorders results by OpenSearch relevance (case-insensitive,\n full-text against note title and paragraph content). When --keyword is\n set, nextCursor is always null. Without --keyword, results are ordered\n by createdAt desc.\n\nNote: placeholder notes (title='Untitled' or sourceType='onboarding') are\nfiltered out by default. A page of N may return fewer than N visible notes —\nkeep paginating to fetch more, or pass --include-untitled to surface them.\n`;\n\nexport function registerNotesList(parent: Command): void {\n parent\n .command(\"list\")\n .description(\"List notes (lightweight metadata).\")\n .option(\"--keyword <text>\", 'Reorder by OpenSearch relevance for this keyword (e.g. \"OKR\")')\n .option(\"--folder <id>\", \"Restrict to a folder and its descendants\")\n .option(\n \"--since <date>\",\n \"Inclusive lower bound on createdAt (ISO-8601 or relative: 7d, 24h, 30m)\",\n )\n .option(\"--until <date>\", \"Exclusive upper bound on createdAt\")\n .option(\n \"--limit <n>\",\n `Max results per page (default ${DEFAULT_PAGE_SIZE}, max ${MAX_PAGE_SIZE})`,\n )\n .option(\"--cursor <token>\", \"Continue a previous page\")\n .option(\n \"--include-untitled\",\n \"Include placeholder notes (title='Untitled' or sourceType='onboarding'). Default: hidden\",\n false,\n )\n .addHelpText(\"after\", HELP_AFTER)\n .action(async (opts: ListOptions, cmd: Command) => {\n const globalOpts = cmd.optsWithGlobals<ListOptions>();\n const client = createApiClient({\n ...(globalOpts.hostname !== undefined && { hostnameOverride: globalOpts.hostname }),\n });\n\n const params: Record<string, string | number | undefined> = {};\n if (opts.keyword) params[\"keyword\"] = opts.keyword;\n if (opts.folder) params[\"folderId\"] = opts.folder;\n if (opts.since) params[\"createdAtFrom\"] = parseDate(opts.since);\n if (opts.until) params[\"createdAtTo\"] = parseDate(opts.until);\n const size = clampLimit(opts.limit);\n if (size !== undefined) params[\"size\"] = size;\n if (opts.cursor) params[\"cursor\"] = opts.cursor;\n\n const res = await client.getJson(\"/v1/external/notes\", ListResponseSchema, params);\n const visible = opts.includeUntitled === true ? res.content : res.content.filter(isVisibleNote);\n\n const mode = resolveOutputMode(globalOpts);\n if (mode === \"json\") {\n for (const note of visible) printNdjson(note);\n if (res.nextCursor) printNdjson({ _cursor: res.nextCursor });\n } else {\n printPretty(visible, res.nextCursor, globalOpts);\n }\n });\n}\n\nfunction clampLimit(raw?: string): number | undefined {\n if (!raw) return undefined;\n const n = parseInt(raw, 10);\n if (!Number.isFinite(n) || n <= 0) return DEFAULT_PAGE_SIZE;\n return Math.min(n, MAX_PAGE_SIZE);\n}\n\ninterface NoteListItem {\n guid: string;\n title: string;\n createdAt: string;\n recordingDurationSeconds: number;\n webUrl: string;\n}\n\nfunction printPretty(\n notes: NoteListItem[],\n nextCursor: string | null,\n opts: { noColor?: boolean },\n): void {\n if (notes.length === 0) {\n process.stdout.write(`${color(\"(no notes)\", \"gray\", opts)}\\n`);\n return;\n }\n const titleWidth = computeTitleWidth();\n for (const n of notes) {\n const date = n.createdAt.slice(0, 10);\n const dur = formatDuration(n.recordingDurationSeconds);\n const title = truncate(n.title, titleWidth);\n process.stdout.write(\n `${color(date, \"gray\", opts)} ${color(n.guid, \"dim\", opts)} ${color(dur, \"cyan\", opts)} ${title}\\n`,\n );\n }\n if (nextCursor) {\n process.stdout.write(\n `${color(`\\n next: --cursor ${nextCursor}`, \"gray\", opts)}\\n`,\n );\n }\n}\n\nfunction computeTitleWidth(): number {\n const cols = process.stdout.columns;\n if (!cols || cols < 60) return 40;\n return Math.max(20, cols - 60);\n}\n\nfunction truncate(s: string, max: number): string {\n if (s.length <= max) return s;\n return s.slice(0, Math.max(0, max - 1)) + \"…\";\n}\n\nfunction formatDuration(sec: number): string {\n if (!sec || sec <= 0) return \"—\";\n const m = Math.floor(sec / 60);\n const s = Math.floor(sec % 60);\n if (m > 0) return `${m}m${s.toString().padStart(2, \"0\")}s`;\n return `${s}s`;\n}\n","import { z } from \"zod\";\nimport { TiroError, ExitCode, type ErrorType } from \"../error.ts\";\nimport { resolveToken } from \"../auth/token.ts\";\nimport { authRequired } from \"../error.ts\";\nimport { getHostname } from \"../config.ts\";\nimport { ApiErrorSchema } from \"./types.ts\";\n\nexport interface ApiClientOptions {\n hostnameOverride?: string;\n tokenOverride?: string;\n}\n\nexport class TiroApiClient {\n constructor(\n private readonly hostname: string,\n private readonly token: string,\n ) {}\n\n async getJson<S extends z.ZodTypeAny>(\n path: string,\n schema: S,\n params?: Record<string, string | number | undefined>,\n ): Promise<z.infer<S>> {\n const url = this.buildUrl(path, params);\n const res = await this.fetch(url, { method: \"GET\" });\n return this.parseJson(res, schema, \"GET\", path);\n }\n\n async postJson<S extends z.ZodTypeAny>(\n path: string,\n schema: S,\n body: unknown,\n ): Promise<z.infer<S>> {\n const url = this.buildUrl(path);\n const res = await this.fetch(url, {\n method: \"POST\",\n headers: { \"Content-Type\": \"application/json\" },\n body: JSON.stringify(body),\n });\n return this.parseJson(res, schema, \"POST\", path);\n }\n\n async putJson<S extends z.ZodTypeAny>(\n path: string,\n schema: S,\n body: unknown,\n ): Promise<z.infer<S>> {\n const url = this.buildUrl(path);\n const res = await this.fetch(url, {\n method: \"PUT\",\n headers: { \"Content-Type\": \"application/json\" },\n body: JSON.stringify(body),\n });\n return this.parseJson(res, schema, \"PUT\", path);\n }\n\n async deleteVoid(path: string): Promise<void> {\n const url = this.buildUrl(path);\n const res = await this.fetch(url, { method: \"DELETE\" });\n if (!res.ok) throw await mapHttpError(res, \"DELETE\", path);\n }\n\n private buildUrl(path: string, params?: Record<string, string | number | undefined>): string {\n const base = path.startsWith(\"http\") ? path : `${this.hostname}${path}`;\n const u = new URL(base);\n if (params) {\n for (const [k, v] of Object.entries(params)) {\n if (v !== undefined && v !== null && v !== \"\") {\n u.searchParams.set(k, String(v));\n }\n }\n }\n return u.toString();\n }\n\n private async fetch(url: string, init: RequestInit): Promise<Response> {\n const headers = new Headers(init.headers);\n headers.set(\"Authorization\", `Bearer ${this.token}`);\n headers.set(\"Accept\", \"application/json\");\n try {\n return await fetch(url, { ...init, headers });\n } catch (err) {\n throw new TiroError(\n {\n code: \"network_error\",\n message: `Network error reaching ${this.hostname}: ${(err as Error).message}`,\n errorType: \"network_error\",\n suggestion: \"Check your network or --hostname.\",\n },\n ExitCode.Generic,\n );\n }\n }\n\n private async parseJson<S extends z.ZodTypeAny>(\n res: Response,\n schema: S,\n method: string,\n path: string,\n ): Promise<z.infer<S>> {\n if (!res.ok) throw await mapHttpError(res, method, path);\n let json: unknown;\n try {\n json = await res.json();\n } catch (err) {\n throw new TiroError(\n {\n code: \"invalid_response\",\n message: `Failed to parse JSON from ${method} ${path}: ${(err as Error).message}`,\n errorType: \"internal_error\",\n },\n ExitCode.Generic,\n );\n }\n const parsed = schema.safeParse(json);\n if (!parsed.success) {\n throw new TiroError(\n {\n code: \"schema_mismatch\",\n message: `Response shape did not match expected schema (${method} ${path}).`,\n errorType: \"internal_error\",\n suggestion: parsed.error.issues\n .slice(0, 3)\n .map((i) => `${i.path.join(\".\") || \"(root)\"}: ${i.message}`)\n .join(\"; \"),\n },\n ExitCode.Generic,\n );\n }\n return parsed.data;\n }\n}\n\nasync function mapHttpError(res: Response, method: string, path: string): Promise<TiroError> {\n const requestId = res.headers.get(\"x-request-id\") ?? undefined;\n const exitCode = res.status === 401 ? ExitCode.AuthRequired : ExitCode.Generic;\n\n const apiError = await tryParseApiError(res);\n if (apiError) {\n return new TiroError(\n {\n code: `${apiError.error.errorType}`,\n message: apiError.error.message,\n errorType: apiError.error.errorType as ErrorType,\n httpStatus: res.status,\n ...(requestId !== undefined && { requestId }),\n ...(res.status === 401 && {\n suggestion: \"Run `tiro auth login` to refresh.\",\n }),\n },\n exitCode,\n );\n }\n\n return new TiroError(\n {\n code: \"http_error\",\n message: `${method} ${path} failed: HTTP ${res.status} ${res.statusText}`,\n errorType: httpStatusToErrorType(res.status),\n httpStatus: res.status,\n ...(requestId !== undefined && { requestId }),\n },\n exitCode,\n );\n}\n\nfunction httpStatusToErrorType(status: number): ErrorType {\n if (status === 400) return \"bad_request\";\n if (status === 401) return \"unauthorized\";\n if (status === 403) return \"forbidden\";\n if (status === 404) return \"not_found\";\n if (status === 409) return \"conflict\";\n if (status === 413) return \"payload_too_large\";\n if (status === 422) return \"unprocessable_entity\";\n if (status === 429) return \"too_many_requests\";\n return \"internal_error\";\n}\n\nasync function tryParseApiError(res: Response): Promise<{ error: { code: number; errorType: string; message: string } } | null> {\n try {\n const json = await res.clone().json();\n const parsed = ApiErrorSchema.safeParse(json);\n return parsed.success ? parsed.data : null;\n } catch {\n return null;\n }\n}\n\nexport function createApiClient(opts: ApiClientOptions = {}): TiroApiClient {\n if (opts.tokenOverride) {\n return new TiroApiClient(getHostname(opts.hostnameOverride), opts.tokenOverride);\n }\n const t = resolveToken();\n if (!t) throw authRequired();\n const hostname = getHostname(opts.hostnameOverride ?? t.hostname);\n return new TiroApiClient(hostname, t.accessToken);\n}\n","import { z } from \"zod\";\n\nexport const CollaboratorSchema = z.object({\n guid: z.string(),\n name: z.string(),\n email: z.string(),\n role: z.enum([\"OWNER\", \"EDITOR\", \"VIEWER\"]),\n});\n\nexport const ParticipantSchema = z.object({\n name: z.string().nullable().optional(),\n email: z.string().nullable().optional(),\n});\n\nexport const NoteSchema = z\n .object({\n guid: z.string(),\n title: z.string(),\n createdAt: z.string(),\n updatedAt: z.string(),\n sourceType: z.string(),\n recordingDurationSeconds: z.number(),\n collaborators: z.array(CollaboratorSchema).optional().default([]),\n participants: z.array(ParticipantSchema).optional().default([]),\n webUrl: z.string(),\n recordingStartAt: z.string().nullable().optional(),\n recordingEndAt: z.string().nullable().optional(),\n })\n .passthrough();\nexport type Note = z.infer<typeof NoteSchema>;\n\nexport const TextObjectSchema = z.object({\n type: z.string(),\n content: z.string(),\n});\nexport type TextObject = z.infer<typeof TextObjectSchema>;\n\nexport const SpeakerInfoSchema = z.object({\n label: z.string(),\n personName: z.string().nullable().optional(),\n});\nexport type SpeakerInfo = z.infer<typeof SpeakerInfoSchema>;\n\nexport const DiarizedSegmentSchema = z.object({\n content: z.string(),\n speaker: SpeakerInfoSchema,\n});\nexport type DiarizedSegment = z.infer<typeof DiarizedSegmentSchema>;\n\nexport const ParagraphSchema = z\n .object({\n uuid: z.string(),\n transcribeLocale: z.string().nullable().optional(),\n transcript: TextObjectSchema.nullable().optional(),\n diarizedSegments: z.array(DiarizedSegmentSchema).nullable().optional(),\n timeFrom: z.string().nullable().optional(),\n timeTo: z.string().nullable().optional(),\n locked: z.boolean().optional(),\n })\n .passthrough();\nexport type Paragraph = z.infer<typeof ParagraphSchema>;\n\nexport const McpSegmentSchema = z.object({\n content: z.string(),\n speaker: z\n .object({\n label: z.string(),\n name: z.string().nullable(),\n })\n .nullable(),\n});\nexport type McpSegment = z.infer<typeof McpSegmentSchema>;\n\nexport const McpParagraphSchema = z.object({\n timeFrom: z.string().nullable(),\n timeTo: z.string().nullable(),\n segments: z.array(McpSegmentSchema),\n});\nexport type McpParagraph = z.infer<typeof McpParagraphSchema>;\n\nexport const McpTranscriptSchema = z.object({\n noteGuid: z.string(),\n title: z.string(),\n participants: z.array(z.string()),\n createdAt: z.string(),\n recordingDurationSeconds: z.number(),\n paragraphs: z.array(McpParagraphSchema),\n});\nexport type McpTranscript = z.infer<typeof McpTranscriptSchema>;\n\nexport const PageCursorResponseSchema = <T extends z.ZodTypeAny>(item: T) =>\n z.object({\n content: z.array(item),\n nextCursor: z.string().nullable(),\n });\n\nexport const SimpleListResponseSchema = <T extends z.ZodTypeAny>(item: T) =>\n z.object({\n content: z.array(item),\n });\n\nexport const ApiErrorSchema = z.object({\n error: z.object({\n code: z.number(),\n errorType: z.string(),\n message: z.string(),\n detail: z.string().nullable().optional(),\n }),\n});\nexport type ApiError = z.infer<typeof ApiErrorSchema>;\n","import { TiroError, ExitCode } from \"../error.ts\";\n\nconst RELATIVE_RE = /^(\\d+)([smhdw])$/i;\nconst UNIT_MS: Record<string, number> = {\n s: 1000,\n m: 60_000,\n h: 3_600_000,\n d: 86_400_000,\n w: 604_800_000,\n};\n\nexport function parseDate(input: string): string {\n const trimmed = input.trim();\n\n const rel = trimmed.match(RELATIVE_RE);\n if (rel) {\n const num = parseInt(rel[1] ?? \"\", 10);\n const unit = (rel[2] ?? \"\").toLowerCase();\n const factor = UNIT_MS[unit];\n if (!factor || !Number.isFinite(num)) {\n throw invalidDate(input);\n }\n return new Date(Date.now() - num * factor).toISOString();\n }\n\n const d = new Date(trimmed);\n if (Number.isNaN(d.getTime())) throw invalidDate(input);\n return d.toISOString();\n}\n\nfunction invalidDate(input: string): TiroError {\n return new TiroError(\n {\n code: \"invalid_date\",\n message: `Invalid date: \"${input}\". Use ISO-8601 (e.g. 2026-04-01T10:00:00Z) or relative (e.g. 7d, 24h, 30m).`,\n errorType: \"bad_request\",\n },\n ExitCode.Usage,\n );\n}\n","export interface FilterableNote {\n title?: string | null;\n sourceType?: string | null;\n}\n\nconst PLACEHOLDER_TITLE = \"Untitled\";\nconst PLACEHOLDER_SOURCE_TYPES = new Set<string>([\"onboarding\"]);\n\nexport function isVisibleNote(note: FilterableNote): boolean {\n if (note.title === PLACEHOLDER_TITLE) return false;\n if (note.sourceType !== null && note.sourceType !== undefined && PLACEHOLDER_SOURCE_TYPES.has(note.sourceType)) {\n return false;\n }\n return true;\n}\n","import { Command } from \"commander\";\nimport { createApiClient } from \"../../lib/api/client.ts\";\nimport { NoteSchema, PageCursorResponseSchema } from \"../../lib/api/types.ts\";\nimport { printNdjson } from \"../../lib/output/print.ts\";\nimport { resolveOutputMode, color } from \"../../lib/output/tty.ts\";\nimport { parseDate } from \"../../lib/util/parseDate.ts\";\nimport { isVisibleNote } from \"../../lib/util/noteFilter.ts\";\nimport { TiroError, ExitCode } from \"../../lib/error.ts\";\n\ninterface SearchOptions {\n keyword?: string;\n folder?: string;\n since?: string;\n until?: string;\n limit?: string;\n cursor?: string;\n includeUntitled?: boolean;\n hostname?: string;\n json?: boolean;\n pretty?: boolean;\n noColor?: boolean;\n quiet?: boolean;\n}\n\nconst SearchResponseSchema = PageCursorResponseSchema(NoteSchema).passthrough();\n\nconst DEFAULT_PAGE_SIZE = 100;\nconst MAX_PAGE_SIZE = 1000;\n\nconst HELP_AFTER = `\nExamples:\n tiro notes search \"Q3 Planning\"\n tiro notes search \"Acme Corp\" --since 7d --json\n tiro notes search \"release\" --since 2026-04-01 --until 2026-05-01\n\nKeyword matching:\n Full-text against note title + paragraph content via OpenSearch.\n Case-insensitive. Multi-word keywords are tokenized — \"OKR planning\"\n matches notes containing both terms. The deep search variant (this\n command) hydrates each result with its primary documents (one-pager,\n custom) so an MCP/LLM client can read content alongside metadata in\n one call.\n\nNote: placeholder notes (title='Untitled' or sourceType='onboarding') are\nfiltered out by default. Pass --include-untitled to surface them.\n`;\n\nexport function registerNotesSearch(parent: Command): void {\n parent\n .command(\"search [keyword]\")\n .description(\"Deep keyword search — returns notes hydrated with their primary documents.\")\n .option(\n \"--keyword <text>\",\n 'Alternative to positional keyword (e.g. --keyword \"Q3 Planning\")',\n )\n .option(\"--folder <id>\", \"Restrict hits to a folder and its descendants\")\n .option(\n \"--since <date>\",\n \"Inclusive lower bound on createdAt (ISO-8601 or relative: 7d, 24h, 30m)\",\n )\n .option(\"--until <date>\", \"Exclusive upper bound on createdAt\")\n .option(\n \"--limit <n>\",\n `Max results per page (default ${DEFAULT_PAGE_SIZE}, max ${MAX_PAGE_SIZE})`,\n )\n .option(\n \"--cursor <token>\",\n \"Continue a previous page (reserved — backend currently always null)\",\n )\n .option(\n \"--include-untitled\",\n \"Include placeholder notes. Default: hidden\",\n false,\n )\n .addHelpText(\"after\", HELP_AFTER)\n .action(async (positional: string | undefined, opts: SearchOptions, cmd: Command) => {\n const globalOpts = cmd.optsWithGlobals<SearchOptions>();\n\n const keyword = (positional ?? opts.keyword ?? \"\").trim();\n if (!keyword) {\n throw new TiroError(\n {\n code: \"missing_keyword\",\n message: \"search requires a keyword (positional or --keyword).\",\n errorType: \"bad_request\",\n suggestion: 'tiro notes search \"OKR\"',\n },\n ExitCode.Usage,\n );\n }\n\n const filter: Record<string, string> = {};\n if (opts.folder) filter[\"folderId\"] = opts.folder;\n if (opts.since) filter[\"createdAtFrom\"] = parseDate(opts.since);\n if (opts.until) filter[\"createdAtTo\"] = parseDate(opts.until);\n\n const pagination: Record<string, string | number> = {};\n const size = clampLimit(opts.limit);\n if (size !== undefined) pagination[\"size\"] = size;\n if (opts.cursor) pagination[\"cursor\"] = opts.cursor;\n\n const body: Record<string, unknown> = { keyword };\n if (Object.keys(filter).length > 0) body[\"filter\"] = filter;\n if (Object.keys(pagination).length > 0) body[\"pagination\"] = pagination;\n\n const client = createApiClient({\n ...(globalOpts.hostname !== undefined && { hostnameOverride: globalOpts.hostname }),\n });\n\n const res = await client.postJson(\n \"/v1/external/notes/search\",\n SearchResponseSchema,\n body,\n );\n const visible = opts.includeUntitled === true ? res.content : res.content.filter(isVisibleNote);\n\n const mode = resolveOutputMode(globalOpts);\n if (mode === \"json\") {\n for (const note of visible) printNdjson(note);\n if (res.nextCursor) printNdjson({ _cursor: res.nextCursor });\n } else {\n printPretty(visible, res.nextCursor, globalOpts);\n }\n });\n}\n\nfunction clampLimit(raw?: string): number | undefined {\n if (!raw) return undefined;\n const n = parseInt(raw, 10);\n if (!Number.isFinite(n) || n <= 0) return DEFAULT_PAGE_SIZE;\n return Math.min(n, MAX_PAGE_SIZE);\n}\n\ninterface NoteListItem {\n guid: string;\n title: string;\n createdAt: string;\n}\n\nfunction printPretty(\n notes: NoteListItem[],\n nextCursor: string | null,\n opts: { noColor?: boolean },\n): void {\n if (notes.length === 0) {\n process.stdout.write(`${color(\"(no matches)\", \"gray\", opts)}\\n`);\n return;\n }\n for (const n of notes) {\n const date = n.createdAt.slice(0, 10);\n process.stdout.write(\n `${color(date, \"gray\", opts)} ${color(n.guid, \"dim\", opts)} ${n.title}\\n`,\n );\n }\n if (nextCursor) {\n process.stdout.write(\n `${color(`\\n next: --cursor ${nextCursor}`, \"gray\", opts)}\\n`,\n );\n }\n}\n","import { Command } from \"commander\";\nimport { createApiClient } from \"../../lib/api/client.ts\";\nimport {\n NoteSchema,\n ParagraphSchema,\n SimpleListResponseSchema,\n PageCursorResponseSchema,\n type Paragraph,\n} from \"../../lib/api/types.ts\";\nimport { writeFileAtomic } from \"../../lib/output/file.ts\";\nimport { formatNote, type FileFormat } from \"../../lib/output/format.ts\";\nimport { paragraphsToMcp } from \"../../lib/output/transcript.ts\";\nimport { printOutput } from \"../../lib/output/print.ts\";\nimport { resolveOutputMode, color } from \"../../lib/output/tty.ts\";\nimport { TiroError, ExitCode } from \"../../lib/error.ts\";\n\ninterface GetOptions {\n output?: string;\n format?: string;\n include?: string;\n force?: boolean;\n hostname?: string;\n json?: boolean;\n pretty?: boolean;\n noColor?: boolean;\n quiet?: boolean;\n}\n\nconst ALLOWED_INCLUDES = new Set([\"transcript\"]);\n\nconst ParagraphsListSchema = SimpleListResponseSchema(ParagraphSchema);\nconst ParagraphsCursorSchema = PageCursorResponseSchema(ParagraphSchema);\n\nexport function registerNotesGet(parent: Command): void {\n parent\n .command(\"get <guid>\")\n .description(\"Get a single note. Outputs to stdout, or saves to a file with --output.\")\n .option(\"--output <path>\", \"Write to file (stdout becomes a single metadata line)\")\n .option(\n \"--format <md|json|txt>\",\n \"Output format (default: md for TTY, json when piped)\",\n )\n .option(\n \"--include <items>\",\n \"Comma-separated extras (v0.2 supports: transcript)\",\n \"\",\n )\n .option(\"--force\", \"Overwrite existing file at --output path\")\n .addHelpText(\"after\", `\nExamples:\n tiro notes get <guid> # markdown to stdout\n tiro notes get <guid> --include transcript # add speaker-attributed paragraphs\n tiro notes get <guid> --output ./meeting.md --include transcript\n tiro notes get <guid> --format json # JSON to stdout\n\nTip for agents: prefer --output <path>. The actual content goes to disk\nand stdout collapses to a single metadata line, keeping your context\nwindow light.\n`)\n .action(async (guid: string, opts: GetOptions, cmd: Command) => {\n const globalOpts = cmd.optsWithGlobals<GetOptions>();\n\n const includes = parseIncludes(opts.include);\n validateIncludes(includes);\n const format = pickFormat(opts.format, opts.output);\n\n const client = createApiClient({\n ...(globalOpts.hostname !== undefined && { hostnameOverride: globalOpts.hostname }),\n });\n\n const note = await client.getJson(`/v1/external/notes/${guid}`, NoteSchema);\n\n let paragraphs: Paragraph[] | undefined;\n if (includes.has(\"transcript\") || format === \"txt\") {\n paragraphs = await fetchAllParagraphs(client, guid);\n }\n\n const content = formatNote(note, format, {\n includeTranscript: includes.has(\"transcript\"),\n ...(paragraphs !== undefined && { paragraphs }),\n });\n\n if (opts.output) {\n const result = await writeFileAtomic(opts.output, content, {\n ...(opts.force === true && { force: true }),\n });\n printOutput(\n {\n ok: true,\n data: {\n saved: result.path,\n size: result.size,\n format,\n guid: note.guid,\n title: note.title,\n },\n },\n globalOpts,\n );\n return;\n }\n\n const mode = resolveOutputMode(globalOpts);\n if (mode === \"json\" && format !== \"json\") {\n printOutput(\n {\n ok: true,\n data: {\n ...note,\n ...(paragraphs && { transcript: { paragraphs: paragraphsToMcp(paragraphs) } }),\n },\n },\n globalOpts,\n );\n } else if (format === \"json\") {\n process.stdout.write(content);\n } else {\n if (process.stdout.isTTY && format === \"txt\") {\n process.stdout.write(`${color(`# ${note.title}`, \"bold\", globalOpts)}\\n\\n`);\n }\n process.stdout.write(content);\n }\n });\n}\n\nasync function fetchAllParagraphs(\n client: ReturnType<typeof createApiClient>,\n guid: string,\n): Promise<Paragraph[]> {\n const first = await client.getJson(\n `/v1/external/notes/${guid}/paragraphs`,\n ParagraphsCursorSchema.or(ParagraphsListSchema),\n );\n const all: Paragraph[] = [...first.content];\n if (\"nextCursor\" in first) {\n let cursor = first.nextCursor;\n while (cursor) {\n const next = await client.getJson(\n `/v1/external/notes/${guid}/paragraphs`,\n ParagraphsCursorSchema,\n { cursor },\n );\n all.push(...next.content);\n cursor = next.nextCursor;\n }\n }\n return all;\n}\n\nfunction parseIncludes(raw?: string): Set<string> {\n if (!raw) return new Set();\n return new Set(\n raw\n .split(\",\")\n .map((s) => s.trim().toLowerCase())\n .filter((s) => s.length > 0),\n );\n}\n\nfunction validateIncludes(includes: Set<string>): void {\n for (const inc of includes) {\n if (!ALLOWED_INCLUDES.has(inc)) {\n throw new TiroError(\n {\n code: \"invalid_include\",\n message: `Invalid --include \"${inc}\". v0.2.0 supports: transcript.`,\n errorType: \"bad_request\",\n suggestion: \"Use --include transcript\",\n },\n ExitCode.Usage,\n );\n }\n }\n}\n\nfunction pickFormat(format: string | undefined, output: string | undefined): FileFormat {\n const allowed: FileFormat[] = [\"md\", \"json\", \"txt\"];\n if (format) {\n const f = format.toLowerCase() as FileFormat;\n if (!allowed.includes(f)) {\n throw new TiroError(\n {\n code: \"invalid_format\",\n message: `Invalid --format \"${format}\". Allowed: md, json, txt.`,\n errorType: \"bad_request\",\n },\n ExitCode.Usage,\n );\n }\n return f;\n }\n if (output) {\n if (output.endsWith(\".json\")) return \"json\";\n if (output.endsWith(\".txt\")) return \"txt\";\n return \"md\";\n }\n return process.stdout.isTTY ? \"md\" : \"json\";\n}\n","import { mkdir, rename, stat, writeFile, access } from \"node:fs/promises\";\nimport { dirname, resolve } from \"node:path\";\nimport { TiroError, ExitCode } from \"../error.ts\";\n\nexport interface WriteResult {\n path: string;\n size: number;\n}\n\nexport async function writeFileAtomic(\n filepath: string,\n content: string,\n opts: { force?: boolean } = {},\n): Promise<WriteResult> {\n const absPath = resolve(filepath);\n await mkdir(dirname(absPath), { recursive: true });\n\n if (!opts.force) {\n const exists = await fileExists(absPath);\n if (exists) {\n throw new TiroError(\n {\n code: \"file_exists\",\n message: `File already exists: ${absPath}`,\n errorType: \"conflict\",\n suggestion: \"Use --force to overwrite, or pick a different --output.\",\n },\n ExitCode.Generic,\n );\n }\n }\n\n const tmp = `${absPath}.tmp.${process.pid}.${Date.now()}`;\n await writeFile(tmp, content, \"utf8\");\n await rename(tmp, absPath);\n const s = await stat(absPath);\n return { path: absPath, size: s.size };\n}\n\nasync function fileExists(p: string): Promise<boolean> {\n try {\n await access(p);\n return true;\n } catch {\n return false;\n }\n}\n","import type {\n McpParagraph,\n McpSegment,\n McpTranscript,\n Note,\n Paragraph,\n} from \"../api/types.ts\";\n\nexport function buildMcpTranscript(note: Note, paragraphs: Paragraph[]): McpTranscript {\n return {\n noteGuid: note.guid,\n title: note.title,\n participants:\n note.participants\n ?.map((p) => p.name || p.email || \"\")\n .filter((s): s is string => typeof s === \"string\" && s.length > 0) ?? [],\n createdAt: note.createdAt,\n recordingDurationSeconds: note.recordingDurationSeconds,\n paragraphs: paragraphsToMcp(paragraphs),\n };\n}\n\nexport function paragraphsToMcp(paragraphs: Paragraph[]): McpParagraph[] {\n return paragraphs\n .map((p) => ({\n timeFrom: p.timeFrom ?? null,\n timeTo: p.timeTo ?? null,\n segments: paragraphToSegments(p),\n }))\n .filter((p) => p.segments.length > 0);\n}\n\nfunction paragraphToSegments(p: Paragraph): McpSegment[] {\n const ds = p.diarizedSegments;\n if (ds && ds.length > 0) {\n return ds\n .map((s) => ({\n content: stripHtml(s.content),\n speaker: {\n label: s.speaker.label,\n name: s.speaker.personName ? stripHtml(s.speaker.personName) : null,\n },\n }))\n .filter((s) => s.content.length > 0);\n }\n const plain = stripHtml(p.transcript?.content ?? \"\");\n return plain ? [{ content: plain, speaker: null }] : [];\n}\n\nexport function renderTranscriptJson(t: McpTranscript): string {\n return `${JSON.stringify(t, null, 2)}\\n`;\n}\n\nexport function renderTranscriptMarkdown(t: McpTranscript): string {\n const anchor = anchorTime(t);\n const lines: string[] = [];\n lines.push(`# ${t.title}`, \"\");\n\n if (t.participants.length > 0) {\n lines.push(`**Participants**: ${t.participants.join(\", \")}`, \"\");\n }\n\n lines.push(\"## Transcript\", \"\");\n for (const p of t.paragraphs) {\n const ts = elapsed(p.timeFrom, anchor);\n for (const s of p.segments) {\n const who = s.speaker?.name ?? s.speaker?.label ?? \"Unknown\";\n const tag = ts ? `${who}, ${ts}` : who;\n lines.push(`**[${tag}]** ${s.content}`);\n }\n lines.push(\"\");\n }\n\n return `${lines.join(\"\\n\").trimEnd()}\\n`;\n}\n\nexport function renderTranscriptText(t: McpTranscript): string {\n const lines: string[] = [];\n for (const p of t.paragraphs) {\n for (const s of p.segments) {\n const who = s.speaker?.name ?? s.speaker?.label ?? \"Unknown\";\n lines.push(`[${who}] ${s.content}`);\n }\n }\n return `${lines.join(\"\\n\")}\\n`;\n}\n\nfunction anchorTime(t: McpTranscript): string | null {\n for (const p of t.paragraphs) {\n if (p.timeFrom) return p.timeFrom;\n }\n return null;\n}\n\nfunction elapsed(currentIso: string | null, anchorIso: string | null): string {\n if (!currentIso || !anchorIso) return \"\";\n const cur = Date.parse(currentIso);\n const anc = Date.parse(anchorIso);\n if (!Number.isFinite(cur) || !Number.isFinite(anc)) return \"\";\n const seconds = Math.max(0, Math.floor((cur - anc) / 1000));\n const h = Math.floor(seconds / 3600);\n const m = Math.floor((seconds % 3600) / 60);\n const s = seconds % 60;\n if (h > 0) return `${pad(h)}:${pad(m)}:${pad(s)}`;\n return `${pad(m)}:${pad(s)}`;\n}\n\nfunction pad(n: number): string {\n return n.toString().padStart(2, \"0\");\n}\n\nfunction stripHtml(s: string): string {\n return s\n .replace(/<[^>]*>/g, \"\")\n .replace(/ /g, \" \")\n .replace(/&/g, \"&\")\n .replace(/</g, \"<\")\n .replace(/>/g, \">\")\n .replace(/"/g, '\"')\n .replace(/'/g, \"'\")\n .trim();\n}\n","import type { Note, Paragraph } from \"../api/types.ts\";\nimport {\n buildMcpTranscript,\n paragraphsToMcp,\n renderTranscriptJson,\n renderTranscriptMarkdown,\n renderTranscriptText,\n} from \"./transcript.ts\";\n\nexport type FileFormat = \"md\" | \"json\" | \"txt\";\n\nexport interface FormatOptions {\n includeTranscript?: boolean;\n paragraphs?: Paragraph[];\n}\n\nexport function formatNote(\n note: Note,\n format: FileFormat,\n opts: FormatOptions = {},\n): string {\n switch (format) {\n case \"md\":\n return formatMarkdown(note, opts);\n case \"json\":\n return formatJson(note, opts);\n case \"txt\":\n return formatText(note, opts);\n }\n}\n\nfunction formatMarkdown(note: Note, opts: FormatOptions): string {\n const fm = [\n \"---\",\n `guid: ${escapeYaml(note.guid)}`,\n `title: ${escapeYaml(note.title)}`,\n `createdAt: ${note.createdAt}`,\n `updatedAt: ${note.updatedAt}`,\n `sourceType: ${note.sourceType}`,\n `recordingDurationSeconds: ${note.recordingDurationSeconds}`,\n `webUrl: ${note.webUrl}`,\n ];\n if (note.recordingStartAt) fm.push(`recordingStartAt: ${note.recordingStartAt}`);\n if (note.recordingEndAt) fm.push(`recordingEndAt: ${note.recordingEndAt}`);\n fm.push(\"---\", \"\");\n\n const parts: string[] = [fm.join(\"\\n\"), `# ${note.title}`, \"\"];\n\n if (note.participants && note.participants.length > 0) {\n parts.push(\"## Participants\", \"\");\n for (const p of note.participants) {\n const name = p.name ?? \"(no name)\";\n const email = p.email ? ` <${p.email}>` : \"\";\n parts.push(`- ${name}${email}`);\n }\n parts.push(\"\");\n }\n\n if (opts.includeTranscript && opts.paragraphs && opts.paragraphs.length > 0) {\n const mcp = buildMcpTranscript(note, opts.paragraphs);\n const transcriptBody = renderTranscriptMarkdown(mcp);\n const startsWithHeader = transcriptBody.startsWith(`# ${note.title}`);\n const trimmed = startsWithHeader\n ? transcriptBody.slice(transcriptBody.indexOf(\"\\n\") + 1)\n : transcriptBody;\n parts.push(trimmed.replace(/^\\s*\\n+/, \"\"));\n }\n\n return `${parts.join(\"\\n\").trimEnd()}\\n`;\n}\n\nfunction formatJson(note: Note, opts: FormatOptions): string {\n const out: Record<string, unknown> = { ...note };\n if (opts.includeTranscript && opts.paragraphs) {\n out[\"transcript\"] = { paragraphs: paragraphsToMcp(opts.paragraphs) };\n }\n return `${JSON.stringify(out, null, 2)}\\n`;\n}\n\nfunction formatText(note: Note, opts: FormatOptions): string {\n if (!opts.paragraphs || opts.paragraphs.length === 0) {\n return `${note.title}\\n${note.webUrl}\\n`;\n }\n const mcp = buildMcpTranscript(note, opts.paragraphs);\n return renderTranscriptText(mcp);\n}\n\nfunction escapeYaml(s: string): string {\n if (/[:#\\n\"']/.test(s)) {\n return JSON.stringify(s);\n }\n return s;\n}\n\nexport {\n buildMcpTranscript,\n renderTranscriptJson,\n renderTranscriptMarkdown,\n renderTranscriptText,\n};\n","import { Command } from \"commander\";\nimport { createApiClient } from \"../../lib/api/client.ts\";\nimport {\n ParagraphSchema,\n PageCursorResponseSchema,\n SimpleListResponseSchema,\n NoteSchema,\n type Paragraph,\n} from \"../../lib/api/types.ts\";\nimport { writeFileAtomic } from \"../../lib/output/file.ts\";\nimport {\n buildMcpTranscript,\n renderTranscriptJson,\n renderTranscriptMarkdown,\n renderTranscriptText,\n} from \"../../lib/output/transcript.ts\";\nimport { type FileFormat } from \"../../lib/output/format.ts\";\nimport { printOutput } from \"../../lib/output/print.ts\";\nimport { resolveOutputMode } from \"../../lib/output/tty.ts\";\nimport { TiroError, ExitCode } from \"../../lib/error.ts\";\n\ninterface TranscriptOptions {\n output?: string;\n format?: string;\n force?: boolean;\n hostname?: string;\n json?: boolean;\n pretty?: boolean;\n noColor?: boolean;\n quiet?: boolean;\n}\n\nconst ParagraphsListSchema = SimpleListResponseSchema(ParagraphSchema);\nconst ParagraphsCursorSchema = PageCursorResponseSchema(ParagraphSchema);\n\nexport function registerNotesTranscript(parent: Command): void {\n parent\n .command(\"transcript <guid>\")\n .description(\n \"Get the full transcript of a note as speaker-attributed paragraphs.\\n\" +\n \"JSON output matches MCP get_note_transcript shape exactly.\",\n )\n .option(\"--output <path>\", \"Write to file (stdout = single metadata line)\")\n .option(\n \"--format <md|json|txt>\",\n \"Output format (default: md if TTY, txt when piped; json mirrors MCP)\",\n )\n .option(\"--force\", \"Overwrite existing file at --output path\")\n .addHelpText(\"after\", `\nExamples:\n tiro notes transcript <guid> # md in TTY, txt in pipe\n tiro notes transcript <guid> --format md --output ./t.md\n tiro notes transcript <guid> --format json # MCP-shape JSON\n tiro notes transcript <guid> --format txt --output ./embed.txt\n\nThe --format json output is byte-for-byte identical to MCP's\nget_note_transcript so agents can swap surfaces without changing parsers.\n`)\n .action(async (guid: string, opts: TranscriptOptions, cmd: Command) => {\n const globalOpts = cmd.optsWithGlobals<TranscriptOptions>();\n const format = pickFormat(opts.format, opts.output, globalOpts);\n\n const client = createApiClient({\n ...(globalOpts.hostname !== undefined && { hostnameOverride: globalOpts.hostname }),\n });\n\n const note = await client.getJson(`/v1/external/notes/${guid}`, NoteSchema);\n const paragraphs = await fetchAllParagraphs(client, guid);\n const mcp = buildMcpTranscript(note, paragraphs);\n\n const content =\n format === \"json\"\n ? renderTranscriptJson(mcp)\n : format === \"md\"\n ? renderTranscriptMarkdown(mcp)\n : renderTranscriptText(mcp);\n\n if (opts.output) {\n const result = await writeFileAtomic(opts.output, content, {\n ...(opts.force === true && { force: true }),\n });\n printOutput(\n {\n ok: true,\n data: {\n saved: result.path,\n size: result.size,\n format,\n guid: note.guid,\n paragraphCount: mcp.paragraphs.length,\n segmentCount: mcp.paragraphs.reduce((sum, p) => sum + p.segments.length, 0),\n },\n },\n globalOpts,\n );\n return;\n }\n\n const mode = resolveOutputMode(globalOpts);\n if (mode === \"json\" && format !== \"json\") {\n printOutput({ ok: true, data: mcp }, globalOpts);\n } else {\n process.stdout.write(content);\n }\n });\n}\n\nasync function fetchAllParagraphs(\n client: ReturnType<typeof createApiClient>,\n guid: string,\n): Promise<Paragraph[]> {\n const first = await client.getJson(\n `/v1/external/notes/${guid}/paragraphs`,\n ParagraphsCursorSchema.or(ParagraphsListSchema),\n );\n const all: Paragraph[] = [...first.content];\n if (\"nextCursor\" in first) {\n let cursor = first.nextCursor;\n while (cursor) {\n const next = await client.getJson(\n `/v1/external/notes/${guid}/paragraphs`,\n ParagraphsCursorSchema,\n { cursor },\n );\n all.push(...next.content);\n cursor = next.nextCursor;\n }\n }\n return all;\n}\n\nfunction pickFormat(\n format: string | undefined,\n output: string | undefined,\n globalOpts: { json?: boolean; pretty?: boolean },\n): FileFormat {\n const allowed: FileFormat[] = [\"md\", \"json\", \"txt\"];\n if (format) {\n const f = format.toLowerCase() as FileFormat;\n if (!allowed.includes(f)) {\n throw new TiroError(\n {\n code: \"invalid_format\",\n message: `Invalid --format \"${format}\". Allowed: md, json, txt.`,\n errorType: \"bad_request\",\n },\n ExitCode.Usage,\n );\n }\n return f;\n }\n if (output) {\n if (output.endsWith(\".json\")) return \"json\";\n if (output.endsWith(\".md\")) return \"md\";\n if (output.endsWith(\".txt\")) return \"txt\";\n return \"md\";\n }\n if (globalOpts.json) return \"json\";\n if (globalOpts.pretty) return \"md\";\n return process.stdout.isTTY ? \"md\" : \"txt\";\n}\n","// update-notifier@7 ships no type definitions. We declare a minimal local\n// surface for the bits we use — runtime is the real authority.\n\nimport updateNotifier from \"update-notifier\";\nimport { readFile } from \"node:fs/promises\";\nimport { fileURLToPath } from \"node:url\";\nimport { dirname, resolve } from \"node:path\";\n\ninterface UpdateInfo {\n current: string;\n latest: string;\n type?: string;\n name?: string;\n}\n\ninterface NotifyOptions {\n isGlobal?: boolean;\n defer?: boolean;\n message?: string;\n boxenOptions?: Record<string, unknown>;\n}\n\nexport interface MinimalNotifier {\n update?: UpdateInfo | null | undefined;\n notify(options?: NotifyOptions): unknown;\n}\n\ninterface NotifierFactory {\n (options: {\n pkg: { name: string; version: string };\n updateCheckInterval?: number;\n shouldNotifyInNpmScript?: boolean;\n }): MinimalNotifier;\n}\n\nconst HERE = dirname(fileURLToPath(import.meta.url));\nconst CANDIDATE_PATHS = [\n resolve(HERE, \"../../package.json\"),\n resolve(HERE, \"../../../package.json\"),\n];\n\nconst ONE_DAY_MS = 24 * 60 * 60 * 1000;\n\ninterface CliPackage {\n name: string;\n version: string;\n}\n\nexport async function startUpdateCheck(): Promise<MinimalNotifier | null> {\n if (process.env[\"NO_UPDATE_NOTIFIER\"] === \"1\") return null;\n if (process.env[\"CI\"]) return null;\n if (process.stdout.isTTY !== true) return null;\n\n const pkg = await loadPkg();\n if (!pkg) return null;\n\n try {\n const factory = updateNotifier as unknown as NotifierFactory;\n return factory({\n pkg,\n updateCheckInterval: ONE_DAY_MS,\n shouldNotifyInNpmScript: false,\n });\n } catch {\n return null;\n }\n}\n\nexport function emitUpdateBanner(notifier: MinimalNotifier | null): void {\n if (!notifier) return;\n if (!notifier.update) return;\n\n notifier.notify({\n isGlobal: true,\n defer: false,\n message:\n \"Update available {currentVersion} \\u2192 {latestVersion}\\n\" +\n \"Run npm install -g {packageName} to update\\n\\n\" +\n \"Changelog: https://www.npmjs.com/package/{packageName}?activeTab=versions\",\n });\n}\n\nasync function loadPkg(): Promise<CliPackage | null> {\n for (const path of CANDIDATE_PATHS) {\n try {\n const raw = await readFile(path, \"utf8\");\n const parsed = JSON.parse(raw) as Partial<CliPackage>;\n if (\n typeof parsed.name === \"string\" &&\n typeof parsed.version === \"string\" &&\n parsed.name.length > 0 &&\n parsed.version.length > 0\n ) {\n return { name: parsed.name, version: parsed.version };\n }\n } catch {\n // try next candidate\n }\n }\n return null;\n}\n"],"mappings":"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","names":["Command","resolve","z","DEFAULT_PAGE_SIZE","MAX_PAGE_SIZE","HELP_AFTER","clampLimit","printPretty","ParagraphsListSchema","ParagraphsCursorSchema","pickFormat","fetchAllParagraphs","dirname","resolve","Command"]}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@theplato/tiro-cli",
|
|
3
|
-
"version": "0.2.
|
|
3
|
+
"version": "0.2.1",
|
|
4
4
|
"description": "Tiro AI notes & transcripts — agent-first command line",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"bin": {
|
|
@@ -45,6 +45,7 @@
|
|
|
45
45
|
"commander": "^12.1.0",
|
|
46
46
|
"conf": "^13.0.1",
|
|
47
47
|
"open": "^10.1.0",
|
|
48
|
+
"update-notifier": "^7.3.1",
|
|
48
49
|
"zod": "^3.23.8"
|
|
49
50
|
},
|
|
50
51
|
"devDependencies": {
|