@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 +12 -3
- package/claude/commands/seq.md +29 -0
- package/claude/settings.json +5 -1
- package/dist/index.js +393 -165
- package/package.json +1 -1
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` -
|
|
125
|
-
- `assist ravendb auth
|
|
126
|
-
- `assist ravendb auth
|
|
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.
|
package/claude/settings.json
CHANGED
|
@@ -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
|
|
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.
|
|
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
|
|
5189
|
-
|
|
5190
|
-
|
|
5191
|
-
|
|
5192
|
-
|
|
5193
|
-
|
|
5194
|
-
const
|
|
5195
|
-
|
|
5196
|
-
|
|
5197
|
-
|
|
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
|
|
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
|
|
6110
|
-
import Enquirer3 from "enquirer";
|
|
6168
|
+
import chalk68 from "chalk";
|
|
6111
6169
|
|
|
6112
6170
|
// src/commands/ravendb/selectOpSecret.ts
|
|
6113
|
-
import
|
|
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
|
|
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
|
-
|
|
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(
|
|
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(
|
|
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(
|
|
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
|
|
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(
|
|
6245
|
+
console.error(chalk68.red(`Connection "${name}" already exists.`));
|
|
6192
6246
|
process.exit(1);
|
|
6193
6247
|
}
|
|
6194
|
-
const url = await
|
|
6195
|
-
|
|
6196
|
-
|
|
6197
|
-
|
|
6198
|
-
const database = await
|
|
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(
|
|
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(
|
|
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
|
|
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(
|
|
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
|
-
|
|
6232
|
-
|
|
6233
|
-
|
|
6234
|
-
|
|
6235
|
-
|
|
6236
|
-
|
|
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
|
|
6291
|
+
import chalk74 from "chalk";
|
|
6267
6292
|
|
|
6268
6293
|
// src/commands/ravendb/ravenFetch.ts
|
|
6269
|
-
import
|
|
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
|
|
6331
|
+
import chalk71 from "chalk";
|
|
6307
6332
|
function resolveOpSecret(reference) {
|
|
6308
6333
|
if (!reference.startsWith("op://")) {
|
|
6309
|
-
console.error(
|
|
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
|
-
|
|
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
|
-
|
|
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
|
|
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
|
-
|
|
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(
|
|
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(`${
|
|
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
|
|
6438
|
+
import chalk76 from "chalk";
|
|
6414
6439
|
|
|
6415
6440
|
// src/commands/ravendb/fetchAllPages.ts
|
|
6416
|
-
import
|
|
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${
|
|
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(
|
|
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")
|
|
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
|
|
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(
|
|
6541
|
+
console.error(chalk77.red(`
|
|
6514
6542
|
Refactor check failed:
|
|
6515
6543
|
`));
|
|
6516
|
-
console.error(
|
|
6544
|
+
console.error(chalk77.red(` The following files exceed ${maxLines} lines:
|
|
6517
6545
|
`));
|
|
6518
6546
|
for (const violation of violations) {
|
|
6519
|
-
console.error(
|
|
6547
|
+
console.error(chalk77.red(` ${violation.file} (${violation.lines} lines)`));
|
|
6520
6548
|
}
|
|
6521
6549
|
console.error(
|
|
6522
|
-
|
|
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(
|
|
6557
|
+
console.error(chalk77.gray(` assist refactor ignore <file>
|
|
6530
6558
|
`));
|
|
6531
6559
|
if (process.env.CLAUDECODE) {
|
|
6532
|
-
console.error(
|
|
6560
|
+
console.error(chalk77.cyan(`
|
|
6533
6561
|
## Extracting Code to New Files
|
|
6534
6562
|
`));
|
|
6535
6563
|
console.error(
|
|
6536
|
-
|
|
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
|
-
|
|
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
|
-
|
|
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
|
|
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(
|
|
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
|
-
|
|
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
|
|
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(
|
|
6774
|
+
console.log(chalk79.red(`File not found in project: ${source}`));
|
|
6747
6775
|
process.exit(1);
|
|
6748
6776
|
}
|
|
6749
|
-
console.log(
|
|
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(
|
|
6781
|
+
console.log(chalk79.green("Done"));
|
|
6754
6782
|
} else {
|
|
6755
|
-
console.log(
|
|
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
|
|
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(
|
|
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(
|
|
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
|
-
|
|
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
|
-
` ${
|
|
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(
|
|
6860
|
+
console.log(chalk80.green(`
|
|
6833
6861
|
Renamed ${oldName} \u2192 ${newName}`));
|
|
6834
6862
|
} else {
|
|
6835
|
-
console.log(
|
|
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
|
|
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
|
|
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(
|
|
7118
|
+
console.log(chalk81.bold("\nFile moves:"));
|
|
7091
7119
|
for (const move of plan.moves) {
|
|
7092
7120
|
console.log(
|
|
7093
|
-
` ${
|
|
7121
|
+
` ${chalk81.red(relPath(move.from))} \u2192 ${chalk81.green(relPath(move.to))}`
|
|
7094
7122
|
);
|
|
7095
|
-
console.log(
|
|
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(
|
|
7129
|
+
console.log(chalk81.bold(`
|
|
7102
7130
|
Import rewrites (${affectedFiles.size} files):`));
|
|
7103
7131
|
for (const file of affectedFiles) {
|
|
7104
|
-
console.log(` ${
|
|
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
|
-
` ${
|
|
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(
|
|
7117
|
-
for (const w of plan.warnings) console.log(
|
|
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(
|
|
7148
|
+
console.log(chalk81.bold("\nNew directories:"));
|
|
7121
7149
|
for (const dir of plan.newDirectories)
|
|
7122
|
-
console.log(
|
|
7150
|
+
console.log(chalk81.green(` ${dir}/`));
|
|
7123
7151
|
}
|
|
7124
7152
|
displayMoves(plan);
|
|
7125
7153
|
displayRewrites(plan.rewrites);
|
|
7126
7154
|
console.log(
|
|
7127
|
-
|
|
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
|
|
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
|
-
|
|
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(
|
|
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
|
-
|
|
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
|
-
|
|
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(
|
|
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(
|
|
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(
|
|
7344
|
+
console.log(chalk83.bold("\nApplying changes..."));
|
|
7317
7345
|
executePlan(plan);
|
|
7318
|
-
console.log(
|
|
7346
|
+
console.log(chalk83.green("\nRestructuring complete"));
|
|
7319
7347
|
} else {
|
|
7320
|
-
console.log(
|
|
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
|
|
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
|
-
|
|
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
|
-
|
|
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
|
|
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
|
-
|
|
8679
|
+
chalk91.yellow("\nEnsure this Redirect URI is set in your Roam OAuth app:")
|
|
8453
8680
|
);
|
|
8454
|
-
console.log(
|
|
8455
|
-
console.log(
|
|
8456
|
-
console.log(
|
|
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(
|
|
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
|
-
|
|
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
|
|
8893
|
+
import chalk93 from "chalk";
|
|
8667
8894
|
|
|
8668
8895
|
// src/commands/buildLimitsSegment.ts
|
|
8669
|
-
import
|
|
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
|
|
8693
|
-
if (projected > 100) return
|
|
8694
|
-
if (projected > 75) return
|
|
8695
|
-
return
|
|
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
|
-
|
|
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
|
|
8728
|
-
if (pct > 40) return
|
|
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
|
|
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
|
-
|
|
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
|
-
|
|
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
|
|
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
|
-
|
|
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
|
-
|
|
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();
|