@staff0rd/assist 0.125.0 → 0.126.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/README.md CHANGED
@@ -45,6 +45,7 @@ After installation, the `assist` command will be available globally. You can als
45
45
  - `/journal` - Append a journal entry summarising recent work, decisions, and notable observations
46
46
  - `/standup` - Summarise recent journal entries as a standup update
47
47
  - `/sync` - Sync commands and settings to ~/.claude
48
+ - `/seq` - Query Seq logs from a URL or filter expression
48
49
  - `/verify` - Run all verification commands in parallel
49
50
  - `/transcript-format` - Format meeting transcripts from VTT files
50
51
  - `/transcript-summarise` - Summarise transcripts missing summaries
@@ -121,13 +122,21 @@ After installation, the `assist` command will be available globally. You can als
121
122
  - `assist jira auth` - Authenticate with Jira via API token (saves site/email to ~/.assist/jira.json)
122
123
  - `assist jira ac <issue-key>` - Print acceptance criteria for a Jira issue
123
124
  - `assist jira view <issue-key>` - Print the title and description of a Jira issue
124
- - `assist ravendb auth` - Configure a named RavenDB connection (prompts for name, URL, database, op:// secret reference)
125
- - `assist ravendb auth --list` - List configured RavenDB connections
126
- - `assist ravendb auth --remove <name>` - Remove a configured connection
125
+ - `assist ravendb auth add` - Add a new RavenDB connection (prompts for name, URL, database, op:// secret reference)
126
+ - `assist ravendb auth list` - List configured RavenDB connections
127
+ - `assist ravendb auth remove <name>` - Remove a configured connection
127
128
  - `assist ravendb set-connection <name>` - Set the default connection for query/collections commands
128
129
  - `assist ravendb query [connection] [collection]` - Query a RavenDB collection (outputs JSON to stdout)
129
130
  - `assist ravendb query [connection] [collection] --page-size <n> --sort <field> --query <lucene> --limit <n>` - Query with options
130
131
  - `assist ravendb collections [connection]` - List collections and document counts in a database
132
+ - `assist seq auth add` - Add a new Seq connection (prompts for name, URL, API token)
133
+ - `assist seq auth list` - List configured Seq connections
134
+ - `assist seq auth remove <name>` - Remove a configured connection
135
+ - `assist seq set-connection <name>` - Set the default Seq connection
136
+ - `assist seq query <filter>` - Query Seq events with a filter expression
137
+ - `assist seq query <filter> -c <connection>` - Query using a specific connection
138
+ - `assist seq query <filter> --json` - Output raw JSON
139
+ - `assist seq query <filter> -n <count>` - Fetch a specific number of events (default 50)
131
140
  - `assist complexity <pattern>` - Analyze a file (all metrics if single match, maintainability if multiple)
132
141
  - `assist complexity cyclomatic [pattern]` - Calculate cyclomatic complexity per function
133
142
  - `assist complexity halstead [pattern]` - Calculate Halstead metrics per function
@@ -0,0 +1,29 @@
1
+ ---
2
+ description: Query Seq logs from a URL or filter expression
3
+ ---
4
+
5
+ The user wants to query Seq log events. The argument is either a Seq UI URL or a raw filter expression.
6
+
7
+ ## If the argument is a URL
8
+
9
+ Parse it to extract:
10
+ 1. **Base URL** — the origin (e.g., `http://localhost:5341`)
11
+ 2. **Filter** — URL-decode the `filter` query parameter from the fragment (after `#`). For example, from `http://localhost:5341/#/events?filter=JobId%20%3D%3D%20%22abc%22`, extract filter `JobId == "abc"`.
12
+
13
+ Then determine the correct connection:
14
+ - Run `assist seq auth list` to see configured connections.
15
+ - Match the base URL from the parsed URL against a connection's URL.
16
+ - If a match is found, use that connection name with `-c <name>`.
17
+ - If no match is found, tell the user and ask them to run `assist seq auth add` to add the connection. Do NOT attempt to add connections yourself.
18
+
19
+ ## If the argument is a filter expression
20
+
21
+ Use the default connection (no `-c` flag needed).
22
+
23
+ ## Running the query
24
+
25
+ Run: `assist seq query "<filter>"` (add `-c <connection>` if resolved from a URL).
26
+
27
+ Display the results to the user. If the output is large, summarise the key events (errors, warnings, patterns) and highlight anything notable.
28
+
29
+ If the user asks follow-up questions, refine the filter and re-query.
@@ -43,7 +43,9 @@
43
43
  "Bash(assist dotnet:*)",
44
44
  "Bash(assist ravendb query:*)",
45
45
  "Bash(assist ravendb collections:*)",
46
- "Bash(assist ravendb auth --list:*)",
46
+ "Bash(assist ravendb auth list:*)",
47
+ "Bash(assist seq query:*)",
48
+ "Bash(assist seq auth list:*)",
47
49
  "Bash(head:*)",
48
50
  "Bash(tail:*)",
49
51
  "Bash(grep:*)",
@@ -92,6 +94,8 @@
92
94
  "Skill(voice-logs)",
93
95
  "Skill(jira)",
94
96
  "SlashCommand(/jira)",
97
+ "Skill(seq)",
98
+ "SlashCommand(/seq)",
95
99
  "WebFetch(domain:staffordwilliams.com)"
96
100
  ],
97
101
  "deny": ["Bash(git commit:*)", "Bash(npm run:*)", "Bash(npx assist:*)"]
package/dist/index.js CHANGED
@@ -6,7 +6,7 @@ import { Command } from "commander";
6
6
  // package.json
7
7
  var package_default = {
8
8
  name: "@staff0rd/assist",
9
- version: "0.125.0",
9
+ version: "0.126.0",
10
10
  type: "module",
11
11
  main: "dist/index.js",
12
12
  bin: {
@@ -179,6 +179,16 @@ var assistConfigSchema = z.strictObject({
179
179
  ).default([]),
180
180
  defaultConnection: z.string().optional()
181
181
  }).optional(),
182
+ seq: z.strictObject({
183
+ connections: z.array(
184
+ z.strictObject({
185
+ name: z.string(),
186
+ url: z.string(),
187
+ apiToken: z.string()
188
+ })
189
+ ).default([]),
190
+ defaultConnection: z.string().optional()
191
+ }).optional(),
182
192
  voice: z.strictObject({
183
193
  wakeWords: z.array(z.string()).default(DEFAULT_WAKE_WORDS),
184
194
  mic: z.string().optional(),
@@ -5151,7 +5161,6 @@ function acceptanceCriteria(issueKey) {
5151
5161
 
5152
5162
  // src/commands/jira/jiraAuth.ts
5153
5163
  import { execSync as execSync24 } from "child_process";
5154
- import Enquirer from "enquirer";
5155
5164
 
5156
5165
  // src/shared/loadJson.ts
5157
5166
  import { existsSync as existsSync24, mkdirSync as mkdirSync5, readFileSync as readFileSync21, writeFileSync as writeFileSync17 } from "fs";
@@ -5182,24 +5191,29 @@ function saveJson(filename, data) {
5182
5191
  writeFileSync17(getStorePath(filename), JSON.stringify(data, null, 2));
5183
5192
  }
5184
5193
 
5194
+ // src/shared/promptInput.ts
5195
+ import Enquirer from "enquirer";
5196
+ var prompts = Enquirer;
5197
+ async function promptInput(name, message, initial) {
5198
+ return new prompts.Input({ name, message, initial }).run();
5199
+ }
5200
+ async function promptPassword(name, message) {
5201
+ return new prompts.Password({ name, message }).run();
5202
+ }
5203
+
5185
5204
  // src/commands/jira/jiraAuth.ts
5186
5205
  var CONFIG_FILE = "jira.json";
5187
5206
  async function promptCredentials(config) {
5188
- const { Input: Input2, Password } = Enquirer;
5189
- const site = await new Input2({
5190
- name: "site",
5191
- message: "Jira site (e.g., mycompany.atlassian.net):",
5192
- initial: config.site
5193
- }).run();
5194
- const email = await new Input2({
5195
- name: "email",
5196
- message: "Email:",
5197
- initial: config.email
5198
- }).run();
5199
- const token = await new Password({
5200
- name: "token",
5201
- message: "API token (https://id.atlassian.com/manage-profile/security/api-tokens):"
5202
- }).run();
5207
+ const site = await promptInput(
5208
+ "site",
5209
+ "Jira site (e.g., mycompany.atlassian.net):",
5210
+ config.site
5211
+ );
5212
+ const email = await promptInput("email", "Email:", config.email);
5213
+ const token = await promptPassword(
5214
+ "token",
5215
+ "API token (https://id.atlassian.com/manage-profile/security/api-tokens):"
5216
+ );
5203
5217
  return { site, email, token };
5204
5218
  }
5205
5219
  async function jiraAuth() {
@@ -6089,7 +6103,52 @@ function registerPrs(program2) {
6089
6103
  }
6090
6104
 
6091
6105
  // src/commands/ravendb/ravendbAuth.ts
6092
- import chalk69 from "chalk";
6106
+ import chalk70 from "chalk";
6107
+
6108
+ // src/shared/createConnectionAuth.ts
6109
+ import chalk65 from "chalk";
6110
+ function listConnections(connections, format2) {
6111
+ if (connections.length === 0) {
6112
+ console.log("No connections configured.");
6113
+ } else {
6114
+ for (const c of connections) {
6115
+ console.log(format2(c));
6116
+ }
6117
+ }
6118
+ }
6119
+ function removeConnection(connections, name, save) {
6120
+ const filtered = connections.filter((c) => c.name !== name);
6121
+ if (filtered.length === connections.length) {
6122
+ console.error(chalk65.red(`Connection "${name}" not found.`));
6123
+ process.exit(1);
6124
+ }
6125
+ save(filtered);
6126
+ console.log(`Removed connection "${name}".`);
6127
+ }
6128
+ async function addConnection(connections, config) {
6129
+ const isFirst = connections.length === 0;
6130
+ const conn = await config.promptNew(connections.map((c) => c.name));
6131
+ connections.push(conn);
6132
+ config.save(connections);
6133
+ if (isFirst && config.onFirst) {
6134
+ config.onFirst(conn);
6135
+ }
6136
+ console.log(`Connection "${conn.name}" saved.`);
6137
+ }
6138
+ function createConnectionAuth(config) {
6139
+ return {
6140
+ async add() {
6141
+ const connections = config.load();
6142
+ await addConnection(connections, config);
6143
+ },
6144
+ list() {
6145
+ listConnections(config.load(), config.format);
6146
+ },
6147
+ remove(name) {
6148
+ removeConnection(config.load(), name, config.save);
6149
+ }
6150
+ };
6151
+ }
6093
6152
 
6094
6153
  // src/commands/ravendb/loadConnections.ts
6095
6154
  function loadConnections() {
@@ -6106,16 +6165,15 @@ function saveConnections(connections) {
6106
6165
  }
6107
6166
 
6108
6167
  // src/commands/ravendb/promptConnection.ts
6109
- import chalk67 from "chalk";
6110
- import Enquirer3 from "enquirer";
6168
+ import chalk68 from "chalk";
6111
6169
 
6112
6170
  // src/commands/ravendb/selectOpSecret.ts
6113
- import chalk66 from "chalk";
6171
+ import chalk67 from "chalk";
6114
6172
  import Enquirer2 from "enquirer";
6115
6173
 
6116
6174
  // src/commands/ravendb/searchItems.ts
6117
6175
  import { execSync as execSync32 } from "child_process";
6118
- import chalk65 from "chalk";
6176
+ import chalk66 from "chalk";
6119
6177
  function opExec(args) {
6120
6178
  return execSync32(`op ${args}`, {
6121
6179
  encoding: "utf-8",
@@ -6128,7 +6186,7 @@ function searchItems(search) {
6128
6186
  items = JSON.parse(opExec("item list --format=json"));
6129
6187
  } catch {
6130
6188
  console.error(
6131
- chalk65.red(
6189
+ chalk66.red(
6132
6190
  "Failed to search 1Password. Ensure the CLI is installed and you are signed in."
6133
6191
  )
6134
6192
  );
@@ -6142,7 +6200,7 @@ function getItemFields(itemId) {
6142
6200
  const item = JSON.parse(opExec(`item get "${itemId}" --format=json`));
6143
6201
  return item.fields.filter((f) => f.reference && f.label);
6144
6202
  } catch {
6145
- console.error(chalk65.red("Failed to get item details from 1Password."));
6203
+ console.error(chalk66.red("Failed to get item details from 1Password."));
6146
6204
  process.exit(1);
6147
6205
  }
6148
6206
  }
@@ -6161,7 +6219,7 @@ async function selectOpSecret(searchTerm) {
6161
6219
  }).run();
6162
6220
  const items = searchItems(search);
6163
6221
  if (items.length === 0) {
6164
- console.error(chalk66.red(`No items found matching "${search}".`));
6222
+ console.error(chalk67.red(`No items found matching "${search}".`));
6165
6223
  process.exit(1);
6166
6224
  }
6167
6225
  const itemId = await selectOne(
@@ -6170,7 +6228,7 @@ async function selectOpSecret(searchTerm) {
6170
6228
  );
6171
6229
  const fields = getItemFields(itemId);
6172
6230
  if (fields.length === 0) {
6173
- console.error(chalk66.red("No fields with references found on this item."));
6231
+ console.error(chalk67.red("No fields with references found on this item."));
6174
6232
  process.exit(1);
6175
6233
  }
6176
6234
  const ref = await selectOne(
@@ -6182,40 +6240,33 @@ async function selectOpSecret(searchTerm) {
6182
6240
 
6183
6241
  // src/commands/ravendb/promptConnection.ts
6184
6242
  async function promptConnection(existingNames) {
6185
- const { Input: Input2 } = Enquirer3;
6186
- const name = await new Input2({
6187
- name: "name",
6188
- message: "Connection name:"
6189
- }).run();
6243
+ const name = await promptInput("name", "Connection name:");
6190
6244
  if (existingNames.includes(name)) {
6191
- console.error(chalk67.red(`Connection "${name}" already exists.`));
6245
+ console.error(chalk68.red(`Connection "${name}" already exists.`));
6192
6246
  process.exit(1);
6193
6247
  }
6194
- const url = await new Input2({
6195
- name: "url",
6196
- message: "RavenDB base URL (e.g. https://host.ravenhq.com):"
6197
- }).run();
6198
- const database = await new Input2({
6199
- name: "database",
6200
- message: "Database name:"
6201
- }).run();
6248
+ const url = await promptInput(
6249
+ "url",
6250
+ "RavenDB base URL (e.g. https://host.ravenhq.com):"
6251
+ );
6252
+ const database = await promptInput("database", "Database name:");
6202
6253
  if (!name || !url || !database) {
6203
- console.error(chalk67.red("All fields are required."));
6254
+ console.error(chalk68.red("All fields are required."));
6204
6255
  process.exit(1);
6205
6256
  }
6206
6257
  const apiKeyRef = await selectOpSecret();
6207
- console.log(chalk67.dim(`Using: ${apiKeyRef}`));
6258
+ console.log(chalk68.dim(`Using: ${apiKeyRef}`));
6208
6259
  return { name, url, database, apiKeyRef };
6209
6260
  }
6210
6261
 
6211
6262
  // src/commands/ravendb/ravendbSetConnection.ts
6212
- import chalk68 from "chalk";
6263
+ import chalk69 from "chalk";
6213
6264
  function ravendbSetConnection(name) {
6214
6265
  const raw = loadGlobalConfigRaw();
6215
6266
  const ravendb = raw.ravendb ?? {};
6216
6267
  const connections = ravendb.connections ?? [];
6217
6268
  if (!connections.some((c) => c.name === name)) {
6218
- console.error(chalk68.red(`Connection "${name}" not found.`));
6269
+ console.error(chalk69.red(`Connection "${name}" not found.`));
6219
6270
  console.error(
6220
6271
  `Available: ${connections.map((c) => c.name).join(", ") || "(none)"}`
6221
6272
  );
@@ -6228,45 +6279,19 @@ function ravendbSetConnection(name) {
6228
6279
  }
6229
6280
 
6230
6281
  // src/commands/ravendb/ravendbAuth.ts
6231
- async function ravendbAuth(options2) {
6232
- const connections = loadConnections();
6233
- if (options2.list) {
6234
- if (connections.length === 0) {
6235
- console.log("No RavenDB connections configured.");
6236
- return;
6237
- }
6238
- for (const c of connections) {
6239
- console.log(
6240
- `${chalk69.bold(c.name)} ${c.url} db=${c.database} key=${c.apiKeyRef}`
6241
- );
6242
- }
6243
- return;
6244
- }
6245
- if (options2.remove) {
6246
- const filtered = connections.filter((c) => c.name !== options2.remove);
6247
- if (filtered.length === connections.length) {
6248
- console.error(chalk69.red(`Connection "${options2.remove}" not found.`));
6249
- process.exit(1);
6250
- }
6251
- saveConnections(filtered);
6252
- console.log(`Removed connection "${options2.remove}".`);
6253
- return;
6254
- }
6255
- const isFirst = connections.length === 0;
6256
- const newConnection = await promptConnection(connections.map((c) => c.name));
6257
- connections.push(newConnection);
6258
- saveConnections(connections);
6259
- if (isFirst) {
6260
- ravendbSetConnection(newConnection.name);
6261
- }
6262
- console.log(`Connection "${newConnection.name}" saved.`);
6263
- }
6282
+ var ravendbAuth = createConnectionAuth({
6283
+ load: loadConnections,
6284
+ save: saveConnections,
6285
+ format: (c) => `${chalk70.bold(c.name)} ${c.url} db=${c.database} key=${c.apiKeyRef}`,
6286
+ promptNew: promptConnection,
6287
+ onFirst: (c) => ravendbSetConnection(c.name)
6288
+ });
6264
6289
 
6265
6290
  // src/commands/ravendb/ravendbCollections.ts
6266
- import chalk73 from "chalk";
6291
+ import chalk74 from "chalk";
6267
6292
 
6268
6293
  // src/commands/ravendb/ravenFetch.ts
6269
- import chalk71 from "chalk";
6294
+ import chalk72 from "chalk";
6270
6295
 
6271
6296
  // src/commands/ravendb/getAccessToken.ts
6272
6297
  var OAUTH_URL = "https://amazon-useast-1-oauth.ravenhq.com/ApiKeys/OAuth/AccessToken";
@@ -6303,10 +6328,10 @@ ${errorText}`
6303
6328
 
6304
6329
  // src/commands/ravendb/resolveOpSecret.ts
6305
6330
  import { execSync as execSync33 } from "child_process";
6306
- import chalk70 from "chalk";
6331
+ import chalk71 from "chalk";
6307
6332
  function resolveOpSecret(reference) {
6308
6333
  if (!reference.startsWith("op://")) {
6309
- console.error(chalk70.red(`Invalid secret reference: must start with op://`));
6334
+ console.error(chalk71.red(`Invalid secret reference: must start with op://`));
6310
6335
  process.exit(1);
6311
6336
  }
6312
6337
  try {
@@ -6316,7 +6341,7 @@ function resolveOpSecret(reference) {
6316
6341
  }).trim();
6317
6342
  } catch {
6318
6343
  console.error(
6319
- chalk70.red(
6344
+ chalk71.red(
6320
6345
  "Failed to resolve secret reference. Ensure 1Password CLI is installed and you are signed in."
6321
6346
  )
6322
6347
  );
@@ -6343,7 +6368,7 @@ async function ravenFetch(connection, path44) {
6343
6368
  if (!response.ok) {
6344
6369
  const body = await response.text();
6345
6370
  console.error(
6346
- chalk71.red(`RavenDB error: ${response.status} ${response.statusText}`)
6371
+ chalk72.red(`RavenDB error: ${response.status} ${response.statusText}`)
6347
6372
  );
6348
6373
  console.error(body.substring(0, 500));
6349
6374
  process.exit(1);
@@ -6352,7 +6377,7 @@ async function ravenFetch(connection, path44) {
6352
6377
  }
6353
6378
 
6354
6379
  // src/commands/ravendb/resolveConnection.ts
6355
- import chalk72 from "chalk";
6380
+ import chalk73 from "chalk";
6356
6381
  function loadRavendb() {
6357
6382
  const raw = loadGlobalConfigRaw();
6358
6383
  const ravendb = raw.ravendb;
@@ -6366,7 +6391,7 @@ function resolveConnection(name) {
6366
6391
  const connectionName = name ?? defaultConnection;
6367
6392
  if (!connectionName) {
6368
6393
  console.error(
6369
- chalk72.red(
6394
+ chalk73.red(
6370
6395
  "No connection specified and no default set. Use assist ravendb set-connection <name> or pass a connection name."
6371
6396
  )
6372
6397
  );
@@ -6374,7 +6399,7 @@ function resolveConnection(name) {
6374
6399
  }
6375
6400
  const connection = connections.find((c) => c.name === connectionName);
6376
6401
  if (!connection) {
6377
- console.error(chalk72.red(`Connection "${connectionName}" not found.`));
6402
+ console.error(chalk73.red(`Connection "${connectionName}" not found.`));
6378
6403
  console.error(
6379
6404
  `Available: ${connections.map((c) => c.name).join(", ") || "(none)"}`
6380
6405
  );
@@ -6405,15 +6430,15 @@ async function ravendbCollections(connectionName) {
6405
6430
  return;
6406
6431
  }
6407
6432
  for (const c of collections) {
6408
- console.log(`${chalk73.bold(c.Name)} ${c.CountOfDocuments} docs`);
6433
+ console.log(`${chalk74.bold(c.Name)} ${c.CountOfDocuments} docs`);
6409
6434
  }
6410
6435
  }
6411
6436
 
6412
6437
  // src/commands/ravendb/ravendbQuery.ts
6413
- import chalk75 from "chalk";
6438
+ import chalk76 from "chalk";
6414
6439
 
6415
6440
  // src/commands/ravendb/fetchAllPages.ts
6416
- import chalk74 from "chalk";
6441
+ import chalk75 from "chalk";
6417
6442
 
6418
6443
  // src/commands/ravendb/buildQueryPath.ts
6419
6444
  function buildQueryPath(opts) {
@@ -6451,7 +6476,7 @@ async function fetchAllPages(connection, opts) {
6451
6476
  allResults.push(...results);
6452
6477
  start3 += results.length;
6453
6478
  process.stderr.write(
6454
- `\r${chalk74.dim(`Fetched ${allResults.length}/${totalResults}`)}`
6479
+ `\r${chalk75.dim(`Fetched ${allResults.length}/${totalResults}`)}`
6455
6480
  );
6456
6481
  if (start3 >= totalResults) break;
6457
6482
  if (opts.limit !== void 0 && allResults.length >= opts.limit) break;
@@ -6466,7 +6491,7 @@ async function fetchAllPages(connection, opts) {
6466
6491
  async function ravendbQuery(connectionName, collection, options2) {
6467
6492
  const resolved = resolveArgs(connectionName, collection);
6468
6493
  if (!resolved.collection && !options2.query) {
6469
- console.error(chalk75.red("Provide a collection name or --query filter."));
6494
+ console.error(chalk76.red("Provide a collection name or --query filter."));
6470
6495
  process.exit(1);
6471
6496
  }
6472
6497
  const { collection: col } = resolved;
@@ -6484,7 +6509,10 @@ async function ravendbQuery(connectionName, collection, options2) {
6484
6509
  // src/commands/registerRavendb.ts
6485
6510
  function registerRavendb(program2) {
6486
6511
  const cmd = program2.command("ravendb").description("RavenDB query utilities");
6487
- cmd.command("auth").description("Configure a named RavenDB connection").option("--list", "List configured connections").option("--remove <name>", "Remove a configured connection").action((options2) => ravendbAuth(options2));
6512
+ const auth2 = cmd.command("auth").description("Configure a named RavenDB connection");
6513
+ auth2.command("add").description("Add a new connection").action(() => ravendbAuth.add());
6514
+ auth2.command("list").description("List configured connections").action(() => ravendbAuth.list());
6515
+ auth2.command("remove <name>").description("Remove a configured connection").action((name) => ravendbAuth.remove(name));
6488
6516
  cmd.command("set-connection <name>").description("Set the default connection").action((name) => ravendbSetConnection(name));
6489
6517
  cmd.command("query [connection] [collection]").description("Query a RavenDB collection").option("--page-size <n>", "Documents per page", "25").option(
6490
6518
  "--sort <field>",
@@ -6501,7 +6529,7 @@ import { spawn as spawn3 } from "child_process";
6501
6529
  import * as path27 from "path";
6502
6530
 
6503
6531
  // src/commands/refactor/logViolations.ts
6504
- import chalk76 from "chalk";
6532
+ import chalk77 from "chalk";
6505
6533
  var DEFAULT_MAX_LINES = 100;
6506
6534
  function logViolations(violations, maxLines = DEFAULT_MAX_LINES) {
6507
6535
  if (violations.length === 0) {
@@ -6510,43 +6538,43 @@ function logViolations(violations, maxLines = DEFAULT_MAX_LINES) {
6510
6538
  }
6511
6539
  return;
6512
6540
  }
6513
- console.error(chalk76.red(`
6541
+ console.error(chalk77.red(`
6514
6542
  Refactor check failed:
6515
6543
  `));
6516
- console.error(chalk76.red(` The following files exceed ${maxLines} lines:
6544
+ console.error(chalk77.red(` The following files exceed ${maxLines} lines:
6517
6545
  `));
6518
6546
  for (const violation of violations) {
6519
- console.error(chalk76.red(` ${violation.file} (${violation.lines} lines)`));
6547
+ console.error(chalk77.red(` ${violation.file} (${violation.lines} lines)`));
6520
6548
  }
6521
6549
  console.error(
6522
- chalk76.yellow(
6550
+ chalk77.yellow(
6523
6551
  `
6524
6552
  Each file needs to be sensibly refactored, or if there is no sensible
6525
6553
  way to refactor it, ignore it with:
6526
6554
  `
6527
6555
  )
6528
6556
  );
6529
- console.error(chalk76.gray(` assist refactor ignore <file>
6557
+ console.error(chalk77.gray(` assist refactor ignore <file>
6530
6558
  `));
6531
6559
  if (process.env.CLAUDECODE) {
6532
- console.error(chalk76.cyan(`
6560
+ console.error(chalk77.cyan(`
6533
6561
  ## Extracting Code to New Files
6534
6562
  `));
6535
6563
  console.error(
6536
- chalk76.cyan(
6564
+ chalk77.cyan(
6537
6565
  ` When extracting logic from one file to another, consider where the extracted code belongs:
6538
6566
  `
6539
6567
  )
6540
6568
  );
6541
6569
  console.error(
6542
- chalk76.cyan(
6570
+ chalk77.cyan(
6543
6571
  ` 1. Keep related logic together: If the extracted code is tightly coupled to the
6544
6572
  original file's domain, create a new folder containing both the original and extracted files.
6545
6573
  `
6546
6574
  )
6547
6575
  );
6548
6576
  console.error(
6549
- chalk76.cyan(
6577
+ chalk77.cyan(
6550
6578
  ` 2. Share common utilities: If the extracted code can be reused across multiple
6551
6579
  domains, move it to a common/shared folder.
6552
6580
  `
@@ -6702,11 +6730,11 @@ async function check(pattern2, options2) {
6702
6730
 
6703
6731
  // src/commands/refactor/ignore.ts
6704
6732
  import fs17 from "fs";
6705
- import chalk77 from "chalk";
6733
+ import chalk78 from "chalk";
6706
6734
  var REFACTOR_YML_PATH2 = "refactor.yml";
6707
6735
  function ignore(file) {
6708
6736
  if (!fs17.existsSync(file)) {
6709
- console.error(chalk77.red(`Error: File does not exist: ${file}`));
6737
+ console.error(chalk78.red(`Error: File does not exist: ${file}`));
6710
6738
  process.exit(1);
6711
6739
  }
6712
6740
  const content = fs17.readFileSync(file, "utf-8");
@@ -6722,7 +6750,7 @@ function ignore(file) {
6722
6750
  fs17.writeFileSync(REFACTOR_YML_PATH2, entry);
6723
6751
  }
6724
6752
  console.log(
6725
- chalk77.green(
6753
+ chalk78.green(
6726
6754
  `Added ${file} to refactor ignore list (max ${maxLines} lines)`
6727
6755
  )
6728
6756
  );
@@ -6730,7 +6758,7 @@ function ignore(file) {
6730
6758
 
6731
6759
  // src/commands/refactor/rename/index.ts
6732
6760
  import path28 from "path";
6733
- import chalk78 from "chalk";
6761
+ import chalk79 from "chalk";
6734
6762
  import { Project as Project2 } from "ts-morph";
6735
6763
  async function rename(source, destination, options2 = {}) {
6736
6764
  const sourcePath = path28.resolve(source);
@@ -6743,22 +6771,22 @@ async function rename(source, destination, options2 = {}) {
6743
6771
  });
6744
6772
  const sourceFile = project.getSourceFile(sourcePath);
6745
6773
  if (!sourceFile) {
6746
- console.log(chalk78.red(`File not found in project: ${source}`));
6774
+ console.log(chalk79.red(`File not found in project: ${source}`));
6747
6775
  process.exit(1);
6748
6776
  }
6749
- console.log(chalk78.bold(`Rename: ${relSource} \u2192 ${relDest}`));
6777
+ console.log(chalk79.bold(`Rename: ${relSource} \u2192 ${relDest}`));
6750
6778
  if (options2.apply) {
6751
6779
  sourceFile.move(destPath);
6752
6780
  await project.save();
6753
- console.log(chalk78.green("Done"));
6781
+ console.log(chalk79.green("Done"));
6754
6782
  } else {
6755
- console.log(chalk78.dim("Dry run. Use --apply to execute."));
6783
+ console.log(chalk79.dim("Dry run. Use --apply to execute."));
6756
6784
  }
6757
6785
  }
6758
6786
 
6759
6787
  // src/commands/refactor/renameSymbol/index.ts
6760
6788
  import path30 from "path";
6761
- import chalk79 from "chalk";
6789
+ import chalk80 from "chalk";
6762
6790
  import { Project as Project3 } from "ts-morph";
6763
6791
 
6764
6792
  // src/commands/refactor/renameSymbol/findSymbol.ts
@@ -6807,38 +6835,38 @@ async function renameSymbol(file, oldName, newName, options2 = {}) {
6807
6835
  const project = new Project3({ tsConfigFilePath: tsConfigPath });
6808
6836
  const sourceFile = project.getSourceFile(filePath);
6809
6837
  if (!sourceFile) {
6810
- console.log(chalk79.red(`File not found in project: ${file}`));
6838
+ console.log(chalk80.red(`File not found in project: ${file}`));
6811
6839
  process.exit(1);
6812
6840
  }
6813
6841
  const symbol = findSymbol(sourceFile, oldName);
6814
6842
  if (!symbol) {
6815
- console.log(chalk79.red(`Symbol "${oldName}" not found in ${file}`));
6843
+ console.log(chalk80.red(`Symbol "${oldName}" not found in ${file}`));
6816
6844
  process.exit(1);
6817
6845
  }
6818
6846
  const grouped = groupReferences(symbol, cwd);
6819
6847
  const totalRefs = [...grouped.values()].reduce((s, l) => s + l.length, 0);
6820
6848
  console.log(
6821
- chalk79.bold(`Rename: ${oldName} \u2192 ${newName} (${totalRefs} references)
6849
+ chalk80.bold(`Rename: ${oldName} \u2192 ${newName} (${totalRefs} references)
6822
6850
  `)
6823
6851
  );
6824
6852
  for (const [refFile, lines] of grouped) {
6825
6853
  console.log(
6826
- ` ${chalk79.dim(refFile)}: lines ${chalk79.cyan(lines.join(", "))}`
6854
+ ` ${chalk80.dim(refFile)}: lines ${chalk80.cyan(lines.join(", "))}`
6827
6855
  );
6828
6856
  }
6829
6857
  if (options2.apply) {
6830
6858
  symbol.rename(newName);
6831
6859
  await project.save();
6832
- console.log(chalk79.green(`
6860
+ console.log(chalk80.green(`
6833
6861
  Renamed ${oldName} \u2192 ${newName}`));
6834
6862
  } else {
6835
- console.log(chalk79.dim("\nDry run. Use --apply to execute."));
6863
+ console.log(chalk80.dim("\nDry run. Use --apply to execute."));
6836
6864
  }
6837
6865
  }
6838
6866
 
6839
6867
  // src/commands/refactor/restructure/index.ts
6840
6868
  import path39 from "path";
6841
- import chalk82 from "chalk";
6869
+ import chalk83 from "chalk";
6842
6870
 
6843
6871
  // src/commands/refactor/restructure/buildImportGraph/index.ts
6844
6872
  import path31 from "path";
@@ -7081,50 +7109,50 @@ function computeRewrites(moves, edges, allProjectFiles) {
7081
7109
 
7082
7110
  // src/commands/refactor/restructure/displayPlan.ts
7083
7111
  import path35 from "path";
7084
- import chalk80 from "chalk";
7112
+ import chalk81 from "chalk";
7085
7113
  function relPath(filePath) {
7086
7114
  return path35.relative(process.cwd(), filePath);
7087
7115
  }
7088
7116
  function displayMoves(plan) {
7089
7117
  if (plan.moves.length === 0) return;
7090
- console.log(chalk80.bold("\nFile moves:"));
7118
+ console.log(chalk81.bold("\nFile moves:"));
7091
7119
  for (const move of plan.moves) {
7092
7120
  console.log(
7093
- ` ${chalk80.red(relPath(move.from))} \u2192 ${chalk80.green(relPath(move.to))}`
7121
+ ` ${chalk81.red(relPath(move.from))} \u2192 ${chalk81.green(relPath(move.to))}`
7094
7122
  );
7095
- console.log(chalk80.dim(` ${move.reason}`));
7123
+ console.log(chalk81.dim(` ${move.reason}`));
7096
7124
  }
7097
7125
  }
7098
7126
  function displayRewrites(rewrites) {
7099
7127
  if (rewrites.length === 0) return;
7100
7128
  const affectedFiles = new Set(rewrites.map((r) => r.file));
7101
- console.log(chalk80.bold(`
7129
+ console.log(chalk81.bold(`
7102
7130
  Import rewrites (${affectedFiles.size} files):`));
7103
7131
  for (const file of affectedFiles) {
7104
- console.log(` ${chalk80.cyan(relPath(file))}:`);
7132
+ console.log(` ${chalk81.cyan(relPath(file))}:`);
7105
7133
  for (const { oldSpecifier, newSpecifier } of rewrites.filter(
7106
7134
  (r) => r.file === file
7107
7135
  )) {
7108
7136
  console.log(
7109
- ` ${chalk80.red(`"${oldSpecifier}"`)} \u2192 ${chalk80.green(`"${newSpecifier}"`)}`
7137
+ ` ${chalk81.red(`"${oldSpecifier}"`)} \u2192 ${chalk81.green(`"${newSpecifier}"`)}`
7110
7138
  );
7111
7139
  }
7112
7140
  }
7113
7141
  }
7114
7142
  function displayPlan(plan) {
7115
7143
  if (plan.warnings.length > 0) {
7116
- console.log(chalk80.yellow("\nWarnings:"));
7117
- for (const w of plan.warnings) console.log(chalk80.yellow(` ${w}`));
7144
+ console.log(chalk81.yellow("\nWarnings:"));
7145
+ for (const w of plan.warnings) console.log(chalk81.yellow(` ${w}`));
7118
7146
  }
7119
7147
  if (plan.newDirectories.length > 0) {
7120
- console.log(chalk80.bold("\nNew directories:"));
7148
+ console.log(chalk81.bold("\nNew directories:"));
7121
7149
  for (const dir of plan.newDirectories)
7122
- console.log(chalk80.green(` ${dir}/`));
7150
+ console.log(chalk81.green(` ${dir}/`));
7123
7151
  }
7124
7152
  displayMoves(plan);
7125
7153
  displayRewrites(plan.rewrites);
7126
7154
  console.log(
7127
- chalk80.dim(
7155
+ chalk81.dim(
7128
7156
  `
7129
7157
  Summary: ${plan.moves.length} file(s) moved, ${plan.rewrites.length} imports rewritten`
7130
7158
  )
@@ -7134,18 +7162,18 @@ Summary: ${plan.moves.length} file(s) moved, ${plan.rewrites.length} imports rew
7134
7162
  // src/commands/refactor/restructure/executePlan.ts
7135
7163
  import fs19 from "fs";
7136
7164
  import path36 from "path";
7137
- import chalk81 from "chalk";
7165
+ import chalk82 from "chalk";
7138
7166
  function executePlan(plan) {
7139
7167
  const updatedContents = applyRewrites(plan.rewrites);
7140
7168
  for (const [file, content] of updatedContents) {
7141
7169
  fs19.writeFileSync(file, content, "utf-8");
7142
7170
  console.log(
7143
- chalk81.cyan(` Rewrote imports in ${path36.relative(process.cwd(), file)}`)
7171
+ chalk82.cyan(` Rewrote imports in ${path36.relative(process.cwd(), file)}`)
7144
7172
  );
7145
7173
  }
7146
7174
  for (const dir of plan.newDirectories) {
7147
7175
  fs19.mkdirSync(dir, { recursive: true });
7148
- console.log(chalk81.green(` Created ${path36.relative(process.cwd(), dir)}/`));
7176
+ console.log(chalk82.green(` Created ${path36.relative(process.cwd(), dir)}/`));
7149
7177
  }
7150
7178
  for (const move of plan.moves) {
7151
7179
  const targetDir = path36.dirname(move.to);
@@ -7154,7 +7182,7 @@ function executePlan(plan) {
7154
7182
  }
7155
7183
  fs19.renameSync(move.from, move.to);
7156
7184
  console.log(
7157
- chalk81.white(
7185
+ chalk82.white(
7158
7186
  ` Moved ${path36.relative(process.cwd(), move.from)} \u2192 ${path36.relative(process.cwd(), move.to)}`
7159
7187
  )
7160
7188
  );
@@ -7169,7 +7197,7 @@ function removeEmptyDirectories(dirs) {
7169
7197
  if (entries.length === 0) {
7170
7198
  fs19.rmdirSync(dir);
7171
7199
  console.log(
7172
- chalk81.dim(
7200
+ chalk82.dim(
7173
7201
  ` Removed empty directory ${path36.relative(process.cwd(), dir)}`
7174
7202
  )
7175
7203
  );
@@ -7302,22 +7330,22 @@ async function restructure(pattern2, options2 = {}) {
7302
7330
  const targetPattern = pattern2 ?? "src";
7303
7331
  const files = findSourceFiles2(targetPattern);
7304
7332
  if (files.length === 0) {
7305
- console.log(chalk82.yellow("No files found matching pattern"));
7333
+ console.log(chalk83.yellow("No files found matching pattern"));
7306
7334
  return;
7307
7335
  }
7308
7336
  const tsConfigPath = path39.resolve("tsconfig.json");
7309
7337
  const plan = buildPlan(files, tsConfigPath);
7310
7338
  if (plan.moves.length === 0) {
7311
- console.log(chalk82.green("No restructuring needed"));
7339
+ console.log(chalk83.green("No restructuring needed"));
7312
7340
  return;
7313
7341
  }
7314
7342
  displayPlan(plan);
7315
7343
  if (options2.apply) {
7316
- console.log(chalk82.bold("\nApplying changes..."));
7344
+ console.log(chalk83.bold("\nApplying changes..."));
7317
7345
  executePlan(plan);
7318
- console.log(chalk82.green("\nRestructuring complete"));
7346
+ console.log(chalk83.green("\nRestructuring complete"));
7319
7347
  } else {
7320
- console.log(chalk82.dim("\nDry run. Use --apply to execute."));
7348
+ console.log(chalk83.dim("\nDry run. Use --apply to execute."));
7321
7349
  }
7322
7350
  }
7323
7351
 
@@ -7344,6 +7372,205 @@ function registerRefactor(program2) {
7344
7372
  ).action(restructure);
7345
7373
  }
7346
7374
 
7375
+ // src/commands/seq/seqAuth.ts
7376
+ import chalk85 from "chalk";
7377
+
7378
+ // src/commands/seq/loadConnections.ts
7379
+ function loadConnections2() {
7380
+ const raw = loadGlobalConfigRaw();
7381
+ const seq = raw.seq;
7382
+ return seq?.connections ?? [];
7383
+ }
7384
+ function saveConnections2(connections) {
7385
+ const raw = loadGlobalConfigRaw();
7386
+ const seq = raw.seq ?? {};
7387
+ seq.connections = connections;
7388
+ raw.seq = seq;
7389
+ saveGlobalConfig(raw);
7390
+ }
7391
+ function getDefaultConnection() {
7392
+ const raw = loadGlobalConfigRaw();
7393
+ const seq = raw.seq;
7394
+ return seq?.defaultConnection;
7395
+ }
7396
+ function setDefaultConnection(name) {
7397
+ const raw = loadGlobalConfigRaw();
7398
+ const seq = raw.seq ?? {};
7399
+ seq.defaultConnection = name;
7400
+ raw.seq = seq;
7401
+ saveGlobalConfig(raw);
7402
+ }
7403
+
7404
+ // src/commands/seq/promptConnection.ts
7405
+ import chalk84 from "chalk";
7406
+ async function promptConnection2(existingNames) {
7407
+ const name = await promptInput("name", "Connection name:", "default");
7408
+ if (existingNames.includes(name)) {
7409
+ console.error(chalk84.red(`Connection "${name}" already exists.`));
7410
+ process.exit(1);
7411
+ }
7412
+ const url = await promptInput("url", "Seq URL:", "http://localhost:5341");
7413
+ const apiToken = await promptPassword("apiToken", "API token:");
7414
+ return { name, url, apiToken };
7415
+ }
7416
+
7417
+ // src/commands/seq/seqAuth.ts
7418
+ var seqAuth = createConnectionAuth({
7419
+ load: loadConnections2,
7420
+ save: saveConnections2,
7421
+ format: (c) => `${chalk85.bold(c.name)} ${c.url}`,
7422
+ promptNew: promptConnection2,
7423
+ onFirst: (c) => setDefaultConnection(c.name)
7424
+ });
7425
+
7426
+ // src/commands/seq/seqQuery.ts
7427
+ import chalk88 from "chalk";
7428
+
7429
+ // src/commands/seq/formatEvent.ts
7430
+ import chalk86 from "chalk";
7431
+ function levelColor(level) {
7432
+ switch (level) {
7433
+ case "Fatal":
7434
+ return chalk86.bgRed.white;
7435
+ case "Error":
7436
+ return chalk86.red;
7437
+ case "Warning":
7438
+ return chalk86.yellow;
7439
+ case "Information":
7440
+ return chalk86.cyan;
7441
+ case "Debug":
7442
+ return chalk86.gray;
7443
+ case "Verbose":
7444
+ return chalk86.dim;
7445
+ default:
7446
+ return chalk86.white;
7447
+ }
7448
+ }
7449
+ function levelAbbrev(level) {
7450
+ switch (level) {
7451
+ case "Fatal":
7452
+ return "FTL";
7453
+ case "Error":
7454
+ return "ERR";
7455
+ case "Warning":
7456
+ return "WRN";
7457
+ case "Information":
7458
+ return "INF";
7459
+ case "Debug":
7460
+ return "DBG";
7461
+ case "Verbose":
7462
+ return "VRB";
7463
+ default:
7464
+ return level.slice(0, 3).toUpperCase();
7465
+ }
7466
+ }
7467
+ function renderMessage(event) {
7468
+ const props = Object.fromEntries(
7469
+ event.Properties.map((p) => [p.Name, p.Value])
7470
+ );
7471
+ return event.MessageTemplateTokens.map((t) => {
7472
+ if ("Text" in t) return t.Text;
7473
+ const val = props[t.PropertyName];
7474
+ return val !== void 0 ? String(val) : `{${t.PropertyName}}`;
7475
+ }).join("");
7476
+ }
7477
+ function formatTimestamp(iso) {
7478
+ const d = new Date(iso);
7479
+ return d.toLocaleTimeString("en-AU", {
7480
+ hour12: false,
7481
+ fractionalSecondDigits: 3
7482
+ });
7483
+ }
7484
+ function formatEvent(event) {
7485
+ const color = levelColor(event.Level);
7486
+ const abbrev = levelAbbrev(event.Level);
7487
+ const ts8 = chalk86.dim(formatTimestamp(event.Timestamp));
7488
+ const msg = renderMessage(event);
7489
+ const lines = [`${ts8} ${color(`[${abbrev}]`)} ${msg}`];
7490
+ if (event.Exception) {
7491
+ for (const line of event.Exception.split("\n")) {
7492
+ lines.push(chalk86.red(` ${line}`));
7493
+ }
7494
+ }
7495
+ return lines.join("\n");
7496
+ }
7497
+
7498
+ // src/commands/seq/resolveConnection.ts
7499
+ import chalk87 from "chalk";
7500
+ function resolveConnection2(name) {
7501
+ const connections = loadConnections2();
7502
+ if (connections.length === 0) {
7503
+ console.error(
7504
+ chalk87.red("No Seq connections configured. Run 'assist seq auth' first.")
7505
+ );
7506
+ process.exit(1);
7507
+ }
7508
+ const target = name ?? getDefaultConnection() ?? connections[0].name;
7509
+ const connection = connections.find((c) => c.name === target);
7510
+ if (!connection) {
7511
+ console.error(chalk87.red(`Seq connection "${target}" not found.`));
7512
+ process.exit(1);
7513
+ }
7514
+ return connection;
7515
+ }
7516
+
7517
+ // src/commands/seq/seqQuery.ts
7518
+ async function seqQuery(filter, options2) {
7519
+ const conn = resolveConnection2(options2.connection);
7520
+ const count = Number.parseInt(options2.count ?? "50", 10);
7521
+ const params = new URLSearchParams({ filter, count: String(count) });
7522
+ const url = `${conn.url}/api/events?${params}`;
7523
+ const response = await fetch(url, {
7524
+ headers: {
7525
+ Accept: "application/json",
7526
+ "X-Seq-ApiKey": conn.apiToken
7527
+ }
7528
+ });
7529
+ if (!response.ok) {
7530
+ const body = await response.text();
7531
+ console.error(chalk88.red(`Seq returned ${response.status}: ${body}`));
7532
+ process.exit(1);
7533
+ }
7534
+ const events = await response.json();
7535
+ if (events.length === 0) {
7536
+ console.log(chalk88.yellow("No events found."));
7537
+ return;
7538
+ }
7539
+ if (options2.json) {
7540
+ console.log(JSON.stringify(events, null, 2));
7541
+ return;
7542
+ }
7543
+ const chronological = [...events].reverse();
7544
+ for (const event of chronological) {
7545
+ console.log(formatEvent(event));
7546
+ }
7547
+ console.log(chalk88.dim(`
7548
+ ${events.length} events`));
7549
+ }
7550
+
7551
+ // src/commands/seq/seqSetConnection.ts
7552
+ import chalk89 from "chalk";
7553
+ function seqSetConnection(name) {
7554
+ const connections = loadConnections2();
7555
+ if (!connections.find((c) => c.name === name)) {
7556
+ console.error(chalk89.red(`Connection "${name}" not found.`));
7557
+ process.exit(1);
7558
+ }
7559
+ setDefaultConnection(name);
7560
+ console.log(`Default Seq connection set to "${name}".`);
7561
+ }
7562
+
7563
+ // src/commands/registerSeq.ts
7564
+ function registerSeq(program2) {
7565
+ const cmd = program2.command("seq").description("Seq log query utilities");
7566
+ const auth2 = cmd.command("auth").description("Configure a Seq connection");
7567
+ auth2.command("add").description("Add a new connection").action(() => seqAuth.add());
7568
+ auth2.command("list").description("List configured connections").action(() => seqAuth.list());
7569
+ auth2.command("remove <name>").description("Remove a configured connection").action((name) => seqAuth.remove(name));
7570
+ cmd.command("set-connection <name>").description("Set the default Seq connection").action((name) => seqSetConnection(name));
7571
+ cmd.command("query <filter>").description("Query Seq events with a filter expression").option("-c, --connection <name>", "Connection to use").option("-n, --count <n>", "Number of events to fetch", "50").option("--json", "Output raw JSON").action((filter, options2) => seqQuery(filter, options2));
7572
+ }
7573
+
7347
7574
  // src/commands/transcript/shared.ts
7348
7575
  import { existsSync as existsSync27, readdirSync as readdirSync5, statSync as statSync2 } from "fs";
7349
7576
  import { basename as basename4, join as join24, relative } from "path";
@@ -7865,14 +8092,14 @@ import {
7865
8092
  import { dirname as dirname20, join as join28 } from "path";
7866
8093
 
7867
8094
  // src/commands/transcript/summarise/processStagedFile/validateStagedContent.ts
7868
- import chalk83 from "chalk";
8095
+ import chalk90 from "chalk";
7869
8096
  var FULL_TRANSCRIPT_REGEX = /^\[Full Transcript\]\(([^)]+)\)/;
7870
8097
  function validateStagedContent(filename, content) {
7871
8098
  const firstLine = content.split("\n")[0];
7872
8099
  const match = firstLine.match(FULL_TRANSCRIPT_REGEX);
7873
8100
  if (!match) {
7874
8101
  console.error(
7875
- chalk83.red(
8102
+ chalk90.red(
7876
8103
  `Staged file ${filename} missing [Full Transcript](<path>) link on first line.`
7877
8104
  )
7878
8105
  );
@@ -7881,7 +8108,7 @@ function validateStagedContent(filename, content) {
7881
8108
  const contentAfterLink = content.slice(firstLine.length).trim();
7882
8109
  if (!contentAfterLink) {
7883
8110
  console.error(
7884
- chalk83.red(
8111
+ chalk90.red(
7885
8112
  `Staged file ${filename} has no summary content after the transcript link.`
7886
8113
  )
7887
8114
  );
@@ -8274,7 +8501,7 @@ function registerVoice(program2) {
8274
8501
 
8275
8502
  // src/commands/roam/auth.ts
8276
8503
  import { randomBytes } from "crypto";
8277
- import chalk84 from "chalk";
8504
+ import chalk91 from "chalk";
8278
8505
 
8279
8506
  // src/lib/openBrowser.ts
8280
8507
  import { execSync as execSync36 } from "child_process";
@@ -8449,13 +8676,13 @@ async function auth() {
8449
8676
  saveGlobalConfig(config);
8450
8677
  const state = randomBytes(16).toString("hex");
8451
8678
  console.log(
8452
- chalk84.yellow("\nEnsure this Redirect URI is set in your Roam OAuth app:")
8679
+ chalk91.yellow("\nEnsure this Redirect URI is set in your Roam OAuth app:")
8453
8680
  );
8454
- console.log(chalk84.white("http://localhost:14523/callback\n"));
8455
- console.log(chalk84.blue("Opening browser for authorization..."));
8456
- console.log(chalk84.dim("Waiting for authorization callback..."));
8681
+ console.log(chalk91.white("http://localhost:14523/callback\n"));
8682
+ console.log(chalk91.blue("Opening browser for authorization..."));
8683
+ console.log(chalk91.dim("Waiting for authorization callback..."));
8457
8684
  const { code, redirectUri } = await authorizeInBrowser(clientId, state);
8458
- console.log(chalk84.dim("Exchanging code for tokens..."));
8685
+ console.log(chalk91.dim("Exchanging code for tokens..."));
8459
8686
  const tokens = await exchangeToken({
8460
8687
  code,
8461
8688
  clientId,
@@ -8471,7 +8698,7 @@ async function auth() {
8471
8698
  };
8472
8699
  saveGlobalConfig(config);
8473
8700
  console.log(
8474
- chalk84.green("Roam credentials and tokens saved to ~/.assist.yml")
8701
+ chalk91.green("Roam credentials and tokens saved to ~/.assist.yml")
8475
8702
  );
8476
8703
  }
8477
8704
 
@@ -8663,10 +8890,10 @@ function run2(name, args) {
8663
8890
  }
8664
8891
 
8665
8892
  // src/commands/statusLine.ts
8666
- import chalk86 from "chalk";
8893
+ import chalk93 from "chalk";
8667
8894
 
8668
8895
  // src/commands/buildLimitsSegment.ts
8669
- import chalk85 from "chalk";
8896
+ import chalk92 from "chalk";
8670
8897
  var FIVE_HOUR_SECONDS = 5 * 3600;
8671
8898
  var SEVEN_DAY_SECONDS = 7 * 86400;
8672
8899
  function formatTimeLeft(resetsAt) {
@@ -8689,10 +8916,10 @@ function projectUsage(pct, resetsAt, windowSeconds) {
8689
8916
  function colorizeRateLimit(pct, resetsAt, windowSeconds) {
8690
8917
  const label2 = `${Math.round(pct)}%`;
8691
8918
  const projected = projectUsage(pct, resetsAt, windowSeconds);
8692
- if (projected == null) return chalk85.green(label2);
8693
- if (projected > 100) return chalk85.red(label2);
8694
- if (projected > 75) return chalk85.yellow(label2);
8695
- return chalk85.green(label2);
8919
+ if (projected == null) return chalk92.green(label2);
8920
+ if (projected > 100) return chalk92.red(label2);
8921
+ if (projected > 75) return chalk92.yellow(label2);
8922
+ return chalk92.green(label2);
8696
8923
  }
8697
8924
  function formatLimit(pct, resetsAt, windowSeconds, fallbackLabel) {
8698
8925
  const timeLabel = resetsAt ? formatTimeLeft(resetsAt) : fallbackLabel;
@@ -8718,14 +8945,14 @@ function buildLimitsSegment(rateLimits) {
8718
8945
  }
8719
8946
 
8720
8947
  // src/commands/statusLine.ts
8721
- chalk86.level = 3;
8948
+ chalk93.level = 3;
8722
8949
  function formatNumber(num) {
8723
8950
  return num.toLocaleString("en-US");
8724
8951
  }
8725
8952
  function colorizePercent(pct) {
8726
8953
  const label2 = `${Math.round(pct)}%`;
8727
- if (pct > 80) return chalk86.red(label2);
8728
- if (pct > 40) return chalk86.yellow(label2);
8954
+ if (pct > 80) return chalk93.red(label2);
8955
+ if (pct > 40) return chalk93.yellow(label2);
8729
8956
  return label2;
8730
8957
  }
8731
8958
  async function statusLine() {
@@ -8748,7 +8975,7 @@ import { fileURLToPath as fileURLToPath7 } from "url";
8748
8975
  // src/commands/sync/syncClaudeMd.ts
8749
8976
  import * as fs22 from "fs";
8750
8977
  import * as path40 from "path";
8751
- import chalk87 from "chalk";
8978
+ import chalk94 from "chalk";
8752
8979
  async function syncClaudeMd(claudeDir, targetBase) {
8753
8980
  const source = path40.join(claudeDir, "CLAUDE.md");
8754
8981
  const target = path40.join(targetBase, "CLAUDE.md");
@@ -8757,12 +8984,12 @@ async function syncClaudeMd(claudeDir, targetBase) {
8757
8984
  const targetContent = fs22.readFileSync(target, "utf-8");
8758
8985
  if (sourceContent !== targetContent) {
8759
8986
  console.log(
8760
- chalk87.yellow("\n\u26A0\uFE0F Warning: CLAUDE.md differs from existing file")
8987
+ chalk94.yellow("\n\u26A0\uFE0F Warning: CLAUDE.md differs from existing file")
8761
8988
  );
8762
8989
  console.log();
8763
8990
  printDiff(targetContent, sourceContent);
8764
8991
  const confirm = await promptConfirm(
8765
- chalk87.red("Overwrite existing CLAUDE.md?"),
8992
+ chalk94.red("Overwrite existing CLAUDE.md?"),
8766
8993
  false
8767
8994
  );
8768
8995
  if (!confirm) {
@@ -8778,7 +9005,7 @@ async function syncClaudeMd(claudeDir, targetBase) {
8778
9005
  // src/commands/sync/syncSettings.ts
8779
9006
  import * as fs23 from "fs";
8780
9007
  import * as path41 from "path";
8781
- import chalk88 from "chalk";
9008
+ import chalk95 from "chalk";
8782
9009
  async function syncSettings(claudeDir, targetBase, options2) {
8783
9010
  const source = path41.join(claudeDir, "settings.json");
8784
9011
  const target = path41.join(targetBase, "settings.json");
@@ -8794,14 +9021,14 @@ async function syncSettings(claudeDir, targetBase, options2) {
8794
9021
  if (mergedContent !== normalizedTarget) {
8795
9022
  if (!options2?.yes) {
8796
9023
  console.log(
8797
- chalk88.yellow(
9024
+ chalk95.yellow(
8798
9025
  "\n\u26A0\uFE0F Warning: settings.json differs from existing file"
8799
9026
  )
8800
9027
  );
8801
9028
  console.log();
8802
9029
  printDiff(targetContent, mergedContent);
8803
9030
  const confirm = await promptConfirm(
8804
- chalk88.red("Overwrite existing settings.json?"),
9031
+ chalk95.red("Overwrite existing settings.json?"),
8805
9032
  false
8806
9033
  );
8807
9034
  if (!confirm) {
@@ -8918,6 +9145,7 @@ registerComplexity(program);
8918
9145
  registerDotnet(program);
8919
9146
  registerNews(program);
8920
9147
  registerRavendb(program);
9148
+ registerSeq(program);
8921
9149
  registerTranscript(program);
8922
9150
  registerVoice(program);
8923
9151
  program.parse();
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@staff0rd/assist",
3
- "version": "0.125.0",
3
+ "version": "0.126.0",
4
4
  "type": "module",
5
5
  "main": "dist/index.js",
6
6
  "bin": {