snow-ai 0.7.15 → 0.7.16
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/bundle/cli.mjs +289 -60
- package/bundle/package.json +1 -1
- package/package.json +1 -1
package/bundle/cli.mjs
CHANGED
|
@@ -53450,7 +53450,24 @@ Notebook is your persistent memory for the codebase. Use it aggressively to reco
|
|
|
53450
53450
|
- If you notice an existing note is outdated or incorrect, fix it immediately \u2014 do NOT leave stale notes
|
|
53451
53451
|
- After refactoring removes the fragile code a note warned about, delete that note
|
|
53452
53452
|
|
|
53453
|
-
**
|
|
53453
|
+
**PARALLEL CALLS RULE:**
|
|
53454
|
+
ALWAYS pair notebook-manage with action tools in same call:
|
|
53455
|
+
- CORRECT: notebook-manage({action:"query"}) + filesystem-read | notebook-manage({action:"add",...}) + filesystem-edit
|
|
53456
|
+
- WRONG: Call notebook-manage alone, wait for result, then act
|
|
53457
|
+
|
|
53458
|
+
**Single tool \u2014 \`notebook-manage\` (required \`action\`):**
|
|
53459
|
+
- **query**: Search by fuzzy file path pattern; optional \`filePathPattern\`, \`topN\`
|
|
53460
|
+
- **list**: All entries for one exact file; required \`filePath\`
|
|
53461
|
+
- **add**: \`filePath\` + \`note\` (string or string[] for batch); records note(s) for a file
|
|
53462
|
+
- **update**: \`notebookId\` + \`note\` (string); updates one entry's content
|
|
53463
|
+
- **delete**: \`notebookId\` (string or string[]); removes entry(s)
|
|
53464
|
+
|
|
53465
|
+
**Examples:**
|
|
53466
|
+
\`\`\`
|
|
53467
|
+
notebook-manage({action:"query", filePathPattern:"auth"}) + filesystem-read("src/auth.ts")
|
|
53468
|
+
notebook-manage({action:"add", filePath:"src/auth.ts", note:["validateInput() MUST be called first","Session token is nullable"]}) + filesystem-edit(...)
|
|
53469
|
+
notebook-manage({action:"delete", notebookId:["id1","id2"]}) + filesystem-edit(...)
|
|
53470
|
+
\`\`\`
|
|
53454
53471
|
|
|
53455
53472
|
**Golden rule:** If you had to think hard to understand something, write it down so the next session doesn't have to.
|
|
53456
53473
|
|
|
@@ -363045,6 +363062,56 @@ function deleteNotebook(notebookId) {
|
|
|
363045
363062
|
}
|
|
363046
363063
|
return found;
|
|
363047
363064
|
}
|
|
363065
|
+
function addNotebooks(filePath, notes) {
|
|
363066
|
+
const normalizedPath = normalizePath2(filePath);
|
|
363067
|
+
const data = readNotebookData();
|
|
363068
|
+
if (!data[normalizedPath]) {
|
|
363069
|
+
data[normalizedPath] = [];
|
|
363070
|
+
}
|
|
363071
|
+
const entries = [];
|
|
363072
|
+
for (const note of notes) {
|
|
363073
|
+
const now = /* @__PURE__ */ new Date();
|
|
363074
|
+
const localTimeStr = `${now.getFullYear()}-${String(now.getMonth() + 1).padStart(2, "0")}-${String(now.getDate()).padStart(2, "0")}T${String(now.getHours()).padStart(2, "0")}:${String(now.getMinutes()).padStart(2, "0")}:${String(now.getSeconds()).padStart(2, "0")}.${String(now.getMilliseconds()).padStart(3, "0")}`;
|
|
363075
|
+
const entry = {
|
|
363076
|
+
id: `notebook-${Date.now()}_${Math.random().toString(36).substr(2, 9)}`,
|
|
363077
|
+
filePath: normalizedPath,
|
|
363078
|
+
note,
|
|
363079
|
+
createdAt: localTimeStr,
|
|
363080
|
+
updatedAt: localTimeStr
|
|
363081
|
+
};
|
|
363082
|
+
data[normalizedPath].unshift(entry);
|
|
363083
|
+
entries.push(entry);
|
|
363084
|
+
}
|
|
363085
|
+
if (data[normalizedPath].length > MAX_ENTRIES_PER_FILE) {
|
|
363086
|
+
data[normalizedPath] = data[normalizedPath].slice(0, MAX_ENTRIES_PER_FILE);
|
|
363087
|
+
}
|
|
363088
|
+
saveNotebookData(data);
|
|
363089
|
+
return entries;
|
|
363090
|
+
}
|
|
363091
|
+
function deleteNotebooks(notebookIds) {
|
|
363092
|
+
var _a20;
|
|
363093
|
+
const data = readNotebookData();
|
|
363094
|
+
const idSet = new Set(notebookIds);
|
|
363095
|
+
const deleted = [];
|
|
363096
|
+
for (const [, entries] of Object.entries(data)) {
|
|
363097
|
+
for (let i = entries.length - 1; i >= 0; i--) {
|
|
363098
|
+
if (idSet.has(entries[i].id)) {
|
|
363099
|
+
deleted.push(entries[i].id);
|
|
363100
|
+
entries.splice(i, 1);
|
|
363101
|
+
idSet.delete(((_a20 = entries[i]) == null ? void 0 : _a20.id) ?? "");
|
|
363102
|
+
}
|
|
363103
|
+
}
|
|
363104
|
+
if (idSet.size === 0)
|
|
363105
|
+
break;
|
|
363106
|
+
}
|
|
363107
|
+
if (deleted.length > 0) {
|
|
363108
|
+
saveNotebookData(data);
|
|
363109
|
+
}
|
|
363110
|
+
return {
|
|
363111
|
+
deleted,
|
|
363112
|
+
notFound: notebookIds.filter((id) => !deleted.includes(id))
|
|
363113
|
+
};
|
|
363114
|
+
}
|
|
363048
363115
|
function getNotebookSnapshotFilePath() {
|
|
363049
363116
|
const projectRoot = process.cwd();
|
|
363050
363117
|
const projectName = path23.basename(projectRoot);
|
|
@@ -441038,6 +441105,7 @@ EXAMPLES:
|
|
|
441038
441105
|
|
|
441039
441106
|
// dist/mcp/notebook.js
|
|
441040
441107
|
async function executeNotebookTool(toolName, args2) {
|
|
441108
|
+
var _a20;
|
|
441041
441109
|
try {
|
|
441042
441110
|
const legacyActionMap = {
|
|
441043
441111
|
"notebook-add": "add",
|
|
@@ -441061,18 +441129,57 @@ async function executeNotebookTool(toolName, args2) {
|
|
|
441061
441129
|
switch (action) {
|
|
441062
441130
|
case "add": {
|
|
441063
441131
|
const { filePath, note } = args2;
|
|
441064
|
-
if (!filePath ||
|
|
441132
|
+
if (!filePath || note === void 0 || note === null) {
|
|
441065
441133
|
return {
|
|
441066
441134
|
content: [
|
|
441067
441135
|
{
|
|
441068
441136
|
type: "text",
|
|
441069
|
-
text:
|
|
441137
|
+
text: 'Error: action=add requires both "filePath" and "note"'
|
|
441070
441138
|
}
|
|
441071
441139
|
],
|
|
441072
441140
|
isError: true
|
|
441073
441141
|
};
|
|
441074
441142
|
}
|
|
441075
|
-
|
|
441143
|
+
let parsedNote = note;
|
|
441144
|
+
if (typeof note === "string") {
|
|
441145
|
+
try {
|
|
441146
|
+
const parsed = JSON.parse(note);
|
|
441147
|
+
if (Array.isArray(parsed)) {
|
|
441148
|
+
parsedNote = parsed;
|
|
441149
|
+
}
|
|
441150
|
+
} catch {
|
|
441151
|
+
}
|
|
441152
|
+
}
|
|
441153
|
+
if (Array.isArray(parsedNote)) {
|
|
441154
|
+
const entries = addNotebooks(filePath, parsedNote);
|
|
441155
|
+
try {
|
|
441156
|
+
const context2 = getConversationContext();
|
|
441157
|
+
if (context2) {
|
|
441158
|
+
for (const entry2 of entries) {
|
|
441159
|
+
recordNotebookAddition(context2.sessionId, context2.messageIndex, entry2.id);
|
|
441160
|
+
}
|
|
441161
|
+
}
|
|
441162
|
+
} catch {
|
|
441163
|
+
}
|
|
441164
|
+
return {
|
|
441165
|
+
content: [
|
|
441166
|
+
{
|
|
441167
|
+
type: "text",
|
|
441168
|
+
text: JSON.stringify({
|
|
441169
|
+
success: true,
|
|
441170
|
+
message: `${entries.length} notebook entries added for: ${((_a20 = entries[0]) == null ? void 0 : _a20.filePath) ?? filePath}`,
|
|
441171
|
+
entries: entries.map((e) => ({
|
|
441172
|
+
id: e.id,
|
|
441173
|
+
filePath: e.filePath,
|
|
441174
|
+
note: e.note,
|
|
441175
|
+
createdAt: e.createdAt
|
|
441176
|
+
}))
|
|
441177
|
+
}, null, 2)
|
|
441178
|
+
}
|
|
441179
|
+
]
|
|
441180
|
+
};
|
|
441181
|
+
}
|
|
441182
|
+
const entry = addNotebook(filePath, parsedNote);
|
|
441076
441183
|
try {
|
|
441077
441184
|
const context2 = getConversationContext();
|
|
441078
441185
|
if (context2) {
|
|
@@ -441136,12 +441243,12 @@ async function executeNotebookTool(toolName, args2) {
|
|
|
441136
441243
|
}
|
|
441137
441244
|
case "update": {
|
|
441138
441245
|
const { notebookId, note } = args2;
|
|
441139
|
-
if (!notebookId || !note) {
|
|
441246
|
+
if (!notebookId || !note || typeof note !== "string") {
|
|
441140
441247
|
return {
|
|
441141
441248
|
content: [
|
|
441142
441249
|
{
|
|
441143
441250
|
type: "text",
|
|
441144
|
-
text:
|
|
441251
|
+
text: 'Error: action=update requires "notebookId" (string) and "note" (string)'
|
|
441145
441252
|
}
|
|
441146
441253
|
],
|
|
441147
441254
|
isError: true
|
|
@@ -441191,47 +441298,60 @@ async function executeNotebookTool(toolName, args2) {
|
|
|
441191
441298
|
}
|
|
441192
441299
|
case "delete": {
|
|
441193
441300
|
const { notebookId } = args2;
|
|
441194
|
-
if (
|
|
441301
|
+
if (notebookId === void 0 || notebookId === null) {
|
|
441195
441302
|
return {
|
|
441196
441303
|
content: [
|
|
441197
441304
|
{
|
|
441198
441305
|
type: "text",
|
|
441199
|
-
text:
|
|
441306
|
+
text: 'Error: action=delete requires "notebookId"'
|
|
441200
441307
|
}
|
|
441201
441308
|
],
|
|
441202
441309
|
isError: true
|
|
441203
441310
|
};
|
|
441204
441311
|
}
|
|
441205
|
-
const
|
|
441206
|
-
const
|
|
441207
|
-
|
|
441312
|
+
const ids = Array.isArray(notebookId) ? notebookId : [notebookId];
|
|
441313
|
+
const entriesToDelete = ids.map((id) => findNotebookById(id)).filter((e) => e !== null);
|
|
441314
|
+
const result2 = ids.length === 1 ? (() => {
|
|
441315
|
+
const deleted = deleteNotebook(ids[0]);
|
|
441316
|
+
return {
|
|
441317
|
+
deleted: deleted ? [ids[0]] : [],
|
|
441318
|
+
notFound: deleted ? [] : [ids[0]]
|
|
441319
|
+
};
|
|
441320
|
+
})() : deleteNotebooks(ids);
|
|
441321
|
+
try {
|
|
441322
|
+
const context2 = getConversationContext();
|
|
441323
|
+
if (context2) {
|
|
441324
|
+
for (const entry of entriesToDelete) {
|
|
441325
|
+
if (result2.deleted.includes(entry.id)) {
|
|
441326
|
+
recordNotebookDeletion(context2.sessionId, context2.messageIndex, entry);
|
|
441327
|
+
}
|
|
441328
|
+
}
|
|
441329
|
+
}
|
|
441330
|
+
} catch {
|
|
441331
|
+
}
|
|
441332
|
+
if (result2.deleted.length === 0) {
|
|
441208
441333
|
return {
|
|
441209
441334
|
content: [
|
|
441210
441335
|
{
|
|
441211
441336
|
type: "text",
|
|
441212
441337
|
text: JSON.stringify({
|
|
441213
441338
|
success: false,
|
|
441214
|
-
message: `Notebook
|
|
441339
|
+
message: `Notebook entries not found: ${result2.notFound.join(", ")}`
|
|
441215
441340
|
}, null, 2)
|
|
441216
441341
|
}
|
|
441217
441342
|
],
|
|
441218
441343
|
isError: true
|
|
441219
441344
|
};
|
|
441220
441345
|
}
|
|
441221
|
-
try {
|
|
441222
|
-
const context2 = getConversationContext();
|
|
441223
|
-
if (context2 && entryToDelete) {
|
|
441224
|
-
recordNotebookDeletion(context2.sessionId, context2.messageIndex, entryToDelete);
|
|
441225
|
-
}
|
|
441226
|
-
} catch {
|
|
441227
|
-
}
|
|
441228
441346
|
return {
|
|
441229
441347
|
content: [
|
|
441230
441348
|
{
|
|
441231
441349
|
type: "text",
|
|
441232
441350
|
text: JSON.stringify({
|
|
441233
441351
|
success: true,
|
|
441234
|
-
message:
|
|
441352
|
+
message: `${result2.deleted.length} notebook entries deleted`,
|
|
441353
|
+
deleted: result2.deleted,
|
|
441354
|
+
...result2.notFound.length > 0 ? { notFound: result2.notFound } : {}
|
|
441235
441355
|
}, null, 2)
|
|
441236
441356
|
}
|
|
441237
441357
|
]
|
|
@@ -441244,7 +441364,7 @@ async function executeNotebookTool(toolName, args2) {
|
|
|
441244
441364
|
content: [
|
|
441245
441365
|
{
|
|
441246
441366
|
type: "text",
|
|
441247
|
-
text:
|
|
441367
|
+
text: 'Error: action=list requires "filePath"'
|
|
441248
441368
|
}
|
|
441249
441369
|
],
|
|
441250
441370
|
isError: true
|
|
@@ -441302,35 +441422,35 @@ var init_notebook = __esm({
|
|
|
441302
441422
|
mcpTools9 = [
|
|
441303
441423
|
{
|
|
441304
441424
|
name: "notebook-manage",
|
|
441305
|
-
description:
|
|
441425
|
+
description: `Unified notebook management tool. Use required field "action" \u2014 one of query | list | add | update | delete.
|
|
441306
441426
|
|
|
441307
|
-
|
|
441427
|
+
PARALLEL CALLS ONLY: MUST pair with other tools (notebook-manage + filesystem-read/terminal-execute/etc).
|
|
441428
|
+
NEVER call notebook-manage alone \u2014 always combine with an action tool in the same turn.
|
|
441308
441429
|
|
|
441309
|
-
|
|
441310
|
-
- query: Search entries by fuzzy file path pattern
|
|
441311
|
-
- list: List all entries for one exact file path
|
|
441312
|
-
- add: Record a
|
|
441313
|
-
- update: Update
|
|
441314
|
-
- delete:
|
|
441430
|
+
ACTIONS:
|
|
441431
|
+
- query: Search entries by fuzzy file path pattern. Optional "filePathPattern" and "topN".
|
|
441432
|
+
- list: List all entries for one exact file path. Required "filePath".
|
|
441433
|
+
- add: Record note(s) for a file. Required "filePath" and "note" (string or string[]). Batch adds share the same filePath.
|
|
441434
|
+
- update: Update note by ID. Required "notebookId" and "note".
|
|
441435
|
+
- delete: Remove note(s) by ID. Required "notebookId" (string or string[]).
|
|
441315
441436
|
|
|
441316
|
-
|
|
441317
|
-
- After fixing bugs
|
|
441318
|
-
-
|
|
441319
|
-
-
|
|
441320
|
-
-
|
|
441437
|
+
BEST PRACTICES:
|
|
441438
|
+
- After fixing non-trivial bugs, record what caused it and why the fix works.
|
|
441439
|
+
- When discovering fragile dependencies or hidden coupling, record immediately.
|
|
441440
|
+
- When an existing note is outdated or incorrect, update/delete it immediately \u2014 do NOT leave stale notes.
|
|
441441
|
+
- Use query before modifying code to recall relevant notes.
|
|
441321
441442
|
|
|
441322
|
-
|
|
441323
|
-
- "
|
|
441324
|
-
- "
|
|
441325
|
-
- "
|
|
441326
|
-
- "Parser expects exact format - adding fields breaks backward compat"`,
|
|
441443
|
+
EXAMPLES:
|
|
441444
|
+
- notebook-manage({action:"query", filePathPattern:"auth"}) + filesystem-read(...)
|
|
441445
|
+
- notebook-manage({action:"add", filePath:"src/auth.ts", note:["validateInput() MUST be called first","Session token is nullable"]}) + filesystem-edit(...)
|
|
441446
|
+
- notebook-manage({action:"delete", notebookId:["id1","id2"]}) + filesystem-edit(...)`,
|
|
441327
441447
|
inputSchema: {
|
|
441328
441448
|
type: "object",
|
|
441329
441449
|
properties: {
|
|
441330
441450
|
action: {
|
|
441331
441451
|
type: "string",
|
|
441332
441452
|
enum: ["query", "list", "add", "update", "delete"],
|
|
441333
|
-
description: "
|
|
441453
|
+
description: "Which operation to run on the notebook."
|
|
441334
441454
|
},
|
|
441335
441455
|
filePath: {
|
|
441336
441456
|
type: "string",
|
|
@@ -441349,12 +441469,32 @@ var init_notebook = __esm({
|
|
|
441349
441469
|
maximum: 50
|
|
441350
441470
|
},
|
|
441351
441471
|
notebookId: {
|
|
441352
|
-
|
|
441353
|
-
|
|
441472
|
+
oneOf: [
|
|
441473
|
+
{
|
|
441474
|
+
type: "string",
|
|
441475
|
+
description: "Single notebook entry ID"
|
|
441476
|
+
},
|
|
441477
|
+
{
|
|
441478
|
+
type: "array",
|
|
441479
|
+
items: { type: "string" },
|
|
441480
|
+
description: "Multiple IDs (same delete applies to all)"
|
|
441481
|
+
}
|
|
441482
|
+
],
|
|
441483
|
+
description: "For action=update or delete: entry id(s) from action=query/list."
|
|
441354
441484
|
},
|
|
441355
441485
|
note: {
|
|
441356
|
-
|
|
441357
|
-
|
|
441486
|
+
oneOf: [
|
|
441487
|
+
{
|
|
441488
|
+
type: "string",
|
|
441489
|
+
description: "For action=add: one note. For action=update: new note content."
|
|
441490
|
+
},
|
|
441491
|
+
{
|
|
441492
|
+
type: "array",
|
|
441493
|
+
items: { type: "string" },
|
|
441494
|
+
description: "For action=add only: batch add multiple notes for the same file."
|
|
441495
|
+
}
|
|
441496
|
+
],
|
|
441497
|
+
description: "For add: required (string or string[]). For update: required string."
|
|
441358
441498
|
}
|
|
441359
441499
|
},
|
|
441360
441500
|
required: ["action"]
|
|
@@ -457684,8 +457824,17 @@ var init_LSPClient = __esm({
|
|
|
457684
457824
|
return Boolean(this.connection && this.isInitialized && this.isProcessAlive && !this.isShuttingDown && stdin && !stdin.destroyed && !stdin.writableEnded);
|
|
457685
457825
|
}
|
|
457686
457826
|
markTransportClosed() {
|
|
457827
|
+
if (!this.isProcessAlive && !this.isInitialized) {
|
|
457828
|
+
return;
|
|
457829
|
+
}
|
|
457687
457830
|
this.isInitialized = false;
|
|
457688
457831
|
this.isProcessAlive = false;
|
|
457832
|
+
if (this.connection) {
|
|
457833
|
+
try {
|
|
457834
|
+
this.connection.dispose();
|
|
457835
|
+
} catch {
|
|
457836
|
+
}
|
|
457837
|
+
}
|
|
457689
457838
|
}
|
|
457690
457839
|
constructor(config3) {
|
|
457691
457840
|
Object.defineProperty(this, "config", {
|
|
@@ -458419,20 +458568,30 @@ var init_LSPManager = __esm({
|
|
|
458419
458568
|
if (!client) {
|
|
458420
458569
|
return null;
|
|
458421
458570
|
}
|
|
458571
|
+
let uri;
|
|
458422
458572
|
try {
|
|
458423
|
-
|
|
458573
|
+
uri = this.pathToUri(filePath);
|
|
458424
458574
|
const content = await this.getDocumentContent(filePath);
|
|
458425
458575
|
if (!content) {
|
|
458426
458576
|
return null;
|
|
458427
458577
|
}
|
|
458428
458578
|
await client.openDocument(uri, content);
|
|
458579
|
+
if (!client.isReady()) {
|
|
458580
|
+
return null;
|
|
458581
|
+
}
|
|
458429
458582
|
const position = { line, character: column };
|
|
458430
458583
|
const locations = await client.gotoDefinition(uri, position);
|
|
458431
|
-
await client.closeDocument(uri);
|
|
458432
458584
|
return locations.length > 0 ? locations[0] : null;
|
|
458433
458585
|
} catch (error40) {
|
|
458434
458586
|
console.debug("LSP findDefinition error:", error40);
|
|
458435
458587
|
return null;
|
|
458588
|
+
} finally {
|
|
458589
|
+
if (uri) {
|
|
458590
|
+
try {
|
|
458591
|
+
await client.closeDocument(uri);
|
|
458592
|
+
} catch {
|
|
458593
|
+
}
|
|
458594
|
+
}
|
|
458436
458595
|
}
|
|
458437
458596
|
}
|
|
458438
458597
|
async findReferences(filePath, line, column, maxResults = 100) {
|
|
@@ -458444,20 +458603,30 @@ var init_LSPManager = __esm({
|
|
|
458444
458603
|
if (!client) {
|
|
458445
458604
|
return [];
|
|
458446
458605
|
}
|
|
458606
|
+
let uri;
|
|
458447
458607
|
try {
|
|
458448
|
-
|
|
458608
|
+
uri = this.pathToUri(filePath);
|
|
458449
458609
|
const content = await this.getDocumentContent(filePath);
|
|
458450
458610
|
if (!content) {
|
|
458451
458611
|
return [];
|
|
458452
458612
|
}
|
|
458453
458613
|
await client.openDocument(uri, content);
|
|
458614
|
+
if (!client.isReady()) {
|
|
458615
|
+
return [];
|
|
458616
|
+
}
|
|
458454
458617
|
const position = { line, character: column };
|
|
458455
458618
|
const locations = await client.findReferences(uri, position, false);
|
|
458456
|
-
await client.closeDocument(uri);
|
|
458457
458619
|
return locations.slice(0, maxResults);
|
|
458458
458620
|
} catch (error40) {
|
|
458459
458621
|
console.debug("LSP findReferences error:", error40);
|
|
458460
458622
|
return [];
|
|
458623
|
+
} finally {
|
|
458624
|
+
if (uri) {
|
|
458625
|
+
try {
|
|
458626
|
+
await client.closeDocument(uri);
|
|
458627
|
+
} catch {
|
|
458628
|
+
}
|
|
458629
|
+
}
|
|
458461
458630
|
}
|
|
458462
458631
|
}
|
|
458463
458632
|
async getDocumentSymbols(filePath) {
|
|
@@ -458469,19 +458638,29 @@ var init_LSPManager = __esm({
|
|
|
458469
458638
|
if (!client) {
|
|
458470
458639
|
return null;
|
|
458471
458640
|
}
|
|
458641
|
+
let uri;
|
|
458472
458642
|
try {
|
|
458473
|
-
|
|
458643
|
+
uri = this.pathToUri(filePath);
|
|
458474
458644
|
const content = await this.getDocumentContent(filePath);
|
|
458475
458645
|
if (!content) {
|
|
458476
458646
|
return null;
|
|
458477
458647
|
}
|
|
458478
458648
|
await client.openDocument(uri, content);
|
|
458649
|
+
if (!client.isReady()) {
|
|
458650
|
+
return null;
|
|
458651
|
+
}
|
|
458479
458652
|
const symbols2 = await client.documentSymbol(uri);
|
|
458480
|
-
await client.closeDocument(uri);
|
|
458481
458653
|
return symbols2;
|
|
458482
458654
|
} catch (error40) {
|
|
458483
458655
|
console.debug("LSP documentSymbol error:", error40);
|
|
458484
458656
|
return null;
|
|
458657
|
+
} finally {
|
|
458658
|
+
if (uri) {
|
|
458659
|
+
try {
|
|
458660
|
+
await client.closeDocument(uri);
|
|
458661
|
+
} catch {
|
|
458662
|
+
}
|
|
458663
|
+
}
|
|
458485
458664
|
}
|
|
458486
458665
|
}
|
|
458487
458666
|
async getHoverInfo(filePath, line, column) {
|
|
@@ -458493,20 +458672,30 @@ var init_LSPManager = __esm({
|
|
|
458493
458672
|
if (!client) {
|
|
458494
458673
|
return null;
|
|
458495
458674
|
}
|
|
458675
|
+
let uri;
|
|
458496
458676
|
try {
|
|
458497
|
-
|
|
458677
|
+
uri = this.pathToUri(filePath);
|
|
458498
458678
|
const content = await this.getDocumentContent(filePath);
|
|
458499
458679
|
if (!content) {
|
|
458500
458680
|
return null;
|
|
458501
458681
|
}
|
|
458502
458682
|
await client.openDocument(uri, content);
|
|
458683
|
+
if (!client.isReady()) {
|
|
458684
|
+
return null;
|
|
458685
|
+
}
|
|
458503
458686
|
const position = { line, character: column };
|
|
458504
458687
|
const hover = await client.hover(uri, position);
|
|
458505
|
-
await client.closeDocument(uri);
|
|
458506
458688
|
return hover;
|
|
458507
458689
|
} catch (error40) {
|
|
458508
458690
|
console.debug("LSP hover error:", error40);
|
|
458509
458691
|
return null;
|
|
458692
|
+
} finally {
|
|
458693
|
+
if (uri) {
|
|
458694
|
+
try {
|
|
458695
|
+
await client.closeDocument(uri);
|
|
458696
|
+
} catch {
|
|
458697
|
+
}
|
|
458698
|
+
}
|
|
458510
458699
|
}
|
|
458511
458700
|
}
|
|
458512
458701
|
async getDocumentContent(filePath) {
|
|
@@ -458641,6 +458830,8 @@ var init_HybridCodeSearchService = __esm({
|
|
|
458641
458830
|
const timeoutMs = contextFile.endsWith(".cs") ? this.csharpLspTimeout : this.lspTimeout;
|
|
458642
458831
|
const timeoutPromise = new Promise((resolve13) => setTimeout(() => resolve13(null), timeoutMs));
|
|
458643
458832
|
const lspPromise = this.lspManager.findDefinition(contextFile, position.line, position.column);
|
|
458833
|
+
lspPromise.catch(() => {
|
|
458834
|
+
});
|
|
458644
458835
|
const location = await Promise.race([lspPromise, timeoutPromise]);
|
|
458645
458836
|
if (!location) {
|
|
458646
458837
|
return null;
|
|
@@ -458662,6 +458853,8 @@ var init_HybridCodeSearchService = __esm({
|
|
|
458662
458853
|
try {
|
|
458663
458854
|
const timeoutPromise = new Promise((resolve13) => setTimeout(() => resolve13(null), this.lspTimeout));
|
|
458664
458855
|
const lspPromise = this.lspManager.getDocumentSymbols(filePath);
|
|
458856
|
+
lspPromise.catch(() => {
|
|
458857
|
+
});
|
|
458665
458858
|
const symbols2 = await Promise.race([lspPromise, timeoutPromise]);
|
|
458666
458859
|
if (symbols2 && symbols2.length > 0) {
|
|
458667
458860
|
return this.convertLSPSymbolsToCodeSymbols(symbols2, filePath);
|
|
@@ -467773,22 +467966,36 @@ function millisecondsToLabel(intervalMs) {
|
|
|
467773
467966
|
}
|
|
467774
467967
|
return `${intervalMs / 1e3}s`;
|
|
467775
467968
|
}
|
|
467969
|
+
function parseDurationString(durationStr) {
|
|
467970
|
+
const pattern = /(\d+)\s*([a-zA-Z]+)/g;
|
|
467971
|
+
let match;
|
|
467972
|
+
let totalMs = 0;
|
|
467973
|
+
while ((match = pattern.exec(durationStr)) !== null) {
|
|
467974
|
+
const value = Number.parseInt(match[1], 10);
|
|
467975
|
+
const unit = match[2];
|
|
467976
|
+
totalMs += unitToMilliseconds(value, unit);
|
|
467977
|
+
}
|
|
467978
|
+
if (totalMs <= 0) {
|
|
467979
|
+
throw new Error("Invalid duration string.");
|
|
467980
|
+
}
|
|
467981
|
+
return totalMs;
|
|
467982
|
+
}
|
|
467776
467983
|
function formatTimestamp(timestamp) {
|
|
467777
467984
|
return new Date(timestamp).toLocaleString();
|
|
467778
467985
|
}
|
|
467779
467986
|
function parseLoopSchedule(rawArgs) {
|
|
467780
467987
|
const args2 = (rawArgs == null ? void 0 : rawArgs.trim()) || "";
|
|
467781
467988
|
if (!args2) {
|
|
467782
|
-
throw new Error("Usage: /loop 5m <prompt> | /loop <prompt> every 2 hours | /loop list | /loop cancel <id> | /loop tasks");
|
|
467989
|
+
throw new Error("Usage: /loop 5m <prompt> | /loop 8h30m <prompt> | /loop <prompt> every 2 hours | /loop list | /loop cancel <id> | /loop tasks");
|
|
467783
467990
|
}
|
|
467784
|
-
if (
|
|
467991
|
+
if (/^(?:\d+\s*[a-zA-Z]+\s*)+\s*$/.test(args2)) {
|
|
467785
467992
|
throw new Error("Loop prompt is required after the interval.");
|
|
467786
467993
|
}
|
|
467787
|
-
const prefixMatch = args2.match(/^(
|
|
467788
|
-
if ((prefixMatch == null ? void 0 : prefixMatch[1]) && prefixMatch[2]
|
|
467789
|
-
const intervalMs =
|
|
467994
|
+
const prefixMatch = args2.match(/^((?:\d+\s*[a-zA-Z]+\s*)+?)\s+([\s\S]+)$/);
|
|
467995
|
+
if ((prefixMatch == null ? void 0 : prefixMatch[1]) && prefixMatch[2]) {
|
|
467996
|
+
const intervalMs = parseDurationString(prefixMatch[1]);
|
|
467790
467997
|
return {
|
|
467791
|
-
prompt: prefixMatch[
|
|
467998
|
+
prompt: prefixMatch[2].trim(),
|
|
467792
467999
|
intervalMs,
|
|
467793
468000
|
intervalLabel: millisecondsToLabel(intervalMs)
|
|
467794
468001
|
};
|
|
@@ -467965,7 +468172,7 @@ var init_loop = __esm({
|
|
|
467965
468172
|
"use strict";
|
|
467966
468173
|
init_commandExecutor();
|
|
467967
468174
|
init_loopManager();
|
|
467968
|
-
LOOP_USAGE = "Usage: /loop 5m <prompt> | /loop <prompt> every 2 hours | /loop list | /loop cancel <id> | /loop tasks";
|
|
468175
|
+
LOOP_USAGE = "Usage: /loop 5m <prompt> | /loop 8h30m <prompt> | /loop <prompt> every 2 hours | /loop list | /loop cancel <id> | /loop tasks";
|
|
467969
468176
|
registerCommand("loop", {
|
|
467970
468177
|
execute: async (args2) => {
|
|
467971
468178
|
const trimmedArgs = args2 == null ? void 0 : args2.trim();
|
|
@@ -602100,7 +602307,7 @@ var require_package3 = __commonJS({
|
|
|
602100
602307
|
"package.json"(exports2, module2) {
|
|
602101
602308
|
module2.exports = {
|
|
602102
602309
|
name: "snow-ai",
|
|
602103
|
-
version: "0.7.
|
|
602310
|
+
version: "0.7.16",
|
|
602104
602311
|
description: "Agentic coding in your terminal",
|
|
602105
602312
|
license: "MIT",
|
|
602106
602313
|
bin: {
|
|
@@ -603602,6 +603809,28 @@ process.emitWarning = function(warning, ...args2) {
|
|
|
603602
603809
|
return;
|
|
603603
603810
|
return originalEmitWarning.apply(process, [warning, ...args2]);
|
|
603604
603811
|
};
|
|
603812
|
+
function isStreamDestroyedError(err) {
|
|
603813
|
+
if (!(err instanceof Error))
|
|
603814
|
+
return false;
|
|
603815
|
+
const code = err.code;
|
|
603816
|
+
if (code === "ERR_STREAM_DESTROYED" || code === "EPIPE")
|
|
603817
|
+
return true;
|
|
603818
|
+
const msg = err.message || "";
|
|
603819
|
+
return msg.includes("stream was destroyed") || msg.includes("ERR_STREAM_DESTROYED") || msg.includes("write after end") || msg.includes("Cannot call write after a stream was destroyed");
|
|
603820
|
+
}
|
|
603821
|
+
process.on("uncaughtException", (err) => {
|
|
603822
|
+
if (isStreamDestroyedError(err)) {
|
|
603823
|
+
return;
|
|
603824
|
+
}
|
|
603825
|
+
console.error("Uncaught Exception:", err);
|
|
603826
|
+
process.exit(1);
|
|
603827
|
+
});
|
|
603828
|
+
process.on("unhandledRejection", (reason) => {
|
|
603829
|
+
if (isStreamDestroyedError(reason)) {
|
|
603830
|
+
return;
|
|
603831
|
+
}
|
|
603832
|
+
console.error("Unhandled Rejection:", reason);
|
|
603833
|
+
});
|
|
603605
603834
|
var args = process.argv.slice(2);
|
|
603606
603835
|
var isQuickCommand = args.some((arg) => arg === "--version" || arg === "-v" || arg === "--help" || arg === "-h" || arg === "--acp" || arg === "--sse" || arg === "--sse-daemon");
|
|
603607
603836
|
if (!isQuickCommand) {
|
package/bundle/package.json
CHANGED