@wrongstack/plugins 0.275.0 → 0.276.2
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/auto-doc.d.ts +3 -2
- package/dist/auto-doc.js +6 -44
- package/dist/cost-tracker.js +1 -0
- package/dist/cron.js +1 -0
- package/dist/file-watcher.js +15 -14
- package/dist/git-autocommit.d.ts +6 -3
- package/dist/git-autocommit.js +7 -137
- package/dist/index.js +111 -844
- package/dist/json-path.d.ts +9 -6
- package/dist/json-path.js +3 -280
- package/dist/semver-bump.js +3 -3
- package/dist/shell-check.d.ts +5 -2
- package/dist/shell-check.js +42 -72
- package/dist/template-engine.js +25 -24
- package/dist/web-search.d.ts +14 -0
- package/dist/web-search.js +4 -274
- package/package.json +2 -2
package/dist/auto-doc.d.ts
CHANGED
|
@@ -4,8 +4,9 @@ import { Plugin } from '@wrongstack/core';
|
|
|
4
4
|
* auto-doc plugin — Auto-generates JSDoc/TSDoc comments for source files.
|
|
5
5
|
*
|
|
6
6
|
* Tools registered:
|
|
7
|
-
* - auto_doc: Generate and inject doc comments into JS/TS files
|
|
8
|
-
*
|
|
7
|
+
* - auto_doc: Generate and inject doc comments into JS/TS files.
|
|
8
|
+
* Pass `dry_run: true` to preview without writing (replaces the former
|
|
9
|
+
* `auto_doc (dry_run)` tool).
|
|
9
10
|
*/
|
|
10
11
|
|
|
11
12
|
declare const plugin: Plugin;
|
package/dist/auto-doc.js
CHANGED
|
@@ -117,7 +117,7 @@ async function runAutoDoc(input, api) {
|
|
|
117
117
|
modified = injectDocComment(modified, entity, doc);
|
|
118
118
|
results.push({ file, entity: entity.name });
|
|
119
119
|
}
|
|
120
|
-
if (!input.
|
|
120
|
+
if (!input.dry_run && results.length > 0) {
|
|
121
121
|
writeFileSync(file, modified, "utf-8");
|
|
122
122
|
api.log.info(`auto-doc: updated ${file}`);
|
|
123
123
|
}
|
|
@@ -127,31 +127,9 @@ async function runAutoDoc(input, api) {
|
|
|
127
127
|
}
|
|
128
128
|
return { ok: true, filesProcessed: input.files.length, changes: results };
|
|
129
129
|
}
|
|
130
|
-
async function runAutoDocPreview(input, api) {
|
|
131
|
-
if (!input.files || typeof input.files !== "object" || !Array.isArray(input.files)) {
|
|
132
|
-
return { ok: false, error: "input.files must be an array of file paths", previews: [] };
|
|
133
|
-
}
|
|
134
|
-
if (input.files.length === 0) {
|
|
135
|
-
return { ok: false, error: "input.files is empty \u2014 provide at least one file path", previews: [] };
|
|
136
|
-
}
|
|
137
|
-
const includeTypes = api.config.extensions?.["auto-doc"]?.["includeTypes"] ?? false;
|
|
138
|
-
const previews = [];
|
|
139
|
-
for (const file of input.files) {
|
|
140
|
-
try {
|
|
141
|
-
const { readFileSync } = await import('fs');
|
|
142
|
-
const content = readFileSync(file, "utf-8");
|
|
143
|
-
const entities = parseSource(content);
|
|
144
|
-
const generated = entities.filter((e) => needsDocComment(content, e)).map((e) => generateDocComment(e, includeTypes));
|
|
145
|
-
previews.push({ file, entities: generated });
|
|
146
|
-
} catch {
|
|
147
|
-
api.log.warn(`auto-doc-preview: could not read file ${file}`);
|
|
148
|
-
}
|
|
149
|
-
}
|
|
150
|
-
return { ok: true, previews };
|
|
151
|
-
}
|
|
152
130
|
var plugin = {
|
|
153
131
|
name: "auto-doc",
|
|
154
|
-
version: "0.
|
|
132
|
+
version: "0.2.0",
|
|
155
133
|
description: "Auto-generates JSDoc/TSDoc comments for functions, classes, types, and interfaces",
|
|
156
134
|
apiVersion: AUTO_DOC_API_VERSION,
|
|
157
135
|
capabilities: { tools: true, pipelines: ["toolCall"] },
|
|
@@ -167,41 +145,25 @@ var plugin = {
|
|
|
167
145
|
setup(api) {
|
|
168
146
|
api.tools.register({
|
|
169
147
|
name: "auto_doc",
|
|
170
|
-
description: "Auto-generate JSDoc/TSDoc comments for functions, classes, types, and interfaces in source files",
|
|
148
|
+
description: "Auto-generate JSDoc/TSDoc comments for functions, classes, types, and interfaces in source files. Set `dry_run: true` to preview without writing.",
|
|
171
149
|
inputSchema: {
|
|
172
150
|
type: "object",
|
|
173
151
|
properties: {
|
|
174
152
|
files: { type: "array", items: { type: "string" }, description: "Source files to document" },
|
|
175
153
|
style: { type: "string", enum: ["jsdoc", "tsdoc"], default: "tsdoc", description: "Comment style" },
|
|
176
154
|
force: { type: "boolean", default: false, description: "Overwrite existing docstrings" },
|
|
177
|
-
|
|
155
|
+
dry_run: { type: "boolean", default: false, description: "Preview generated comments without writing to files" }
|
|
178
156
|
},
|
|
179
157
|
required: ["files"]
|
|
180
158
|
},
|
|
181
159
|
permission: "auto",
|
|
182
160
|
mutating: true,
|
|
161
|
+
category: "Project",
|
|
183
162
|
async execute(input) {
|
|
184
163
|
return runAutoDoc(input, api);
|
|
185
164
|
}
|
|
186
165
|
});
|
|
187
|
-
api.
|
|
188
|
-
name: "auto_doc_preview",
|
|
189
|
-
description: "Preview what JSDoc/TSDoc comments would be generated for files, without writing",
|
|
190
|
-
inputSchema: {
|
|
191
|
-
type: "object",
|
|
192
|
-
properties: {
|
|
193
|
-
files: { type: "array", items: { type: "string" }, description: "Source files to preview" },
|
|
194
|
-
style: { type: "string", enum: ["jsdoc", "tsdoc"], default: "tsdoc" }
|
|
195
|
-
},
|
|
196
|
-
required: ["files"]
|
|
197
|
-
},
|
|
198
|
-
permission: "auto",
|
|
199
|
-
mutating: false,
|
|
200
|
-
async execute(input) {
|
|
201
|
-
return runAutoDocPreview(input, api);
|
|
202
|
-
}
|
|
203
|
-
});
|
|
204
|
-
api.log.info("auto-doc plugin loaded", { version: "0.1.0", capabilities: ["auto_doc", "auto_doc_preview"] });
|
|
166
|
+
api.log.info("auto-doc plugin loaded", { version: "0.2.0", capabilities: ["auto_doc"] });
|
|
205
167
|
},
|
|
206
168
|
teardown(api) {
|
|
207
169
|
api.log.info("auto-doc plugin unloaded");
|
package/dist/cost-tracker.js
CHANGED
|
@@ -91,6 +91,7 @@ var plugin = {
|
|
|
91
91
|
description: "Returns the current session's token usage breakdown by model, total cost estimate, and budget status.",
|
|
92
92
|
inputSchema: { type: "object", properties: {} },
|
|
93
93
|
permission: "auto",
|
|
94
|
+
category: "Meta",
|
|
94
95
|
mutating: false,
|
|
95
96
|
async execute() {
|
|
96
97
|
const { budgetLimit, warningThreshold } = readCostTrackerConfig(
|
package/dist/cron.js
CHANGED
package/dist/file-watcher.js
CHANGED
|
@@ -3,9 +3,9 @@ import * as path from 'path';
|
|
|
3
3
|
|
|
4
4
|
// src/file-watcher/index.ts
|
|
5
5
|
var API_VERSION = "^0.1.10";
|
|
6
|
-
var
|
|
6
|
+
var watch_idCounter = 0;
|
|
7
7
|
function nextId() {
|
|
8
|
-
return `watch_${++
|
|
8
|
+
return `watch_${++watch_idCounter}_${Date.now().toString(36)}`;
|
|
9
9
|
}
|
|
10
10
|
var watches = /* @__PURE__ */ new Map();
|
|
11
11
|
var debounceTimers = /* @__PURE__ */ new Map();
|
|
@@ -90,7 +90,7 @@ var plugin = {
|
|
|
90
90
|
const key = `${handle.id}:${fullPath}:${eventType}`;
|
|
91
91
|
debounceEvent(key, () => {
|
|
92
92
|
api.emitCustom("file-watcher:changed", {
|
|
93
|
-
|
|
93
|
+
watch_id: handle.id,
|
|
94
94
|
path: fullPath,
|
|
95
95
|
event: eventType,
|
|
96
96
|
filename,
|
|
@@ -151,15 +151,16 @@ var plugin = {
|
|
|
151
151
|
required: ["paths"]
|
|
152
152
|
},
|
|
153
153
|
permission: "confirm",
|
|
154
|
+
category: "Filesystem",
|
|
154
155
|
mutating: false,
|
|
155
156
|
async execute(input) {
|
|
156
157
|
const rawPaths = input["paths"];
|
|
157
158
|
if (!rawPaths || typeof rawPaths !== "object" || !Array.isArray(rawPaths)) {
|
|
158
|
-
return { ok: false, error: "paths must be an array of file/directory paths",
|
|
159
|
+
return { ok: false, error: "paths must be an array of file/directory paths", watch_id: null };
|
|
159
160
|
}
|
|
160
161
|
const paths = rawPaths;
|
|
161
162
|
if (paths.length === 0) {
|
|
162
|
-
return { ok: false, error: "paths array is empty \u2014 provide at least one path",
|
|
163
|
+
return { ok: false, error: "paths array is empty \u2014 provide at least one path", watch_id: null };
|
|
163
164
|
}
|
|
164
165
|
const events = input["events"] ?? ["change", "add", "delete"];
|
|
165
166
|
const recursive = input["recursive"] ?? true;
|
|
@@ -179,7 +180,7 @@ var plugin = {
|
|
|
179
180
|
api.metrics.gauge("active_watches", watches.size);
|
|
180
181
|
return {
|
|
181
182
|
ok: true,
|
|
182
|
-
|
|
183
|
+
watch_id: id,
|
|
183
184
|
paths,
|
|
184
185
|
events,
|
|
185
186
|
recursive,
|
|
@@ -193,17 +194,17 @@ var plugin = {
|
|
|
193
194
|
inputSchema: {
|
|
194
195
|
type: "object",
|
|
195
196
|
properties: {
|
|
196
|
-
|
|
197
|
+
watch_id: { type: "string", description: "Watch ID returned by watch_start" }
|
|
197
198
|
},
|
|
198
|
-
required: ["
|
|
199
|
+
required: ["watch_id"]
|
|
199
200
|
},
|
|
200
201
|
permission: "auto",
|
|
201
202
|
mutating: false,
|
|
202
203
|
async execute(input) {
|
|
203
|
-
const
|
|
204
|
-
const handle = watches.get(
|
|
204
|
+
const watch_id = input["watch_id"];
|
|
205
|
+
const handle = watches.get(watch_id);
|
|
205
206
|
if (!handle) {
|
|
206
|
-
return { ok: false, error: `No active watch with ID: ${
|
|
207
|
+
return { ok: false, error: `No active watch with ID: ${watch_id}` };
|
|
207
208
|
}
|
|
208
209
|
for (const w of handle.watchers) {
|
|
209
210
|
try {
|
|
@@ -211,12 +212,12 @@ var plugin = {
|
|
|
211
212
|
} catch {
|
|
212
213
|
}
|
|
213
214
|
}
|
|
214
|
-
watches.delete(
|
|
215
|
+
watches.delete(watch_id);
|
|
215
216
|
api.metrics.gauge("active_watches", watches.size);
|
|
216
217
|
return {
|
|
217
218
|
ok: true,
|
|
218
|
-
|
|
219
|
-
message: `Stopped watch ${
|
|
219
|
+
watch_id,
|
|
220
|
+
message: `Stopped watch ${watch_id}. ${watches.size} watch(es) remaining.`
|
|
220
221
|
};
|
|
221
222
|
}
|
|
222
223
|
});
|
package/dist/git-autocommit.d.ts
CHANGED
|
@@ -4,9 +4,12 @@ import { Plugin } from '@wrongstack/core';
|
|
|
4
4
|
* git-autocommit plugin — AI-powered git staging and commit message generation.
|
|
5
5
|
*
|
|
6
6
|
* Tools registered:
|
|
7
|
-
* - git_autocommit:
|
|
8
|
-
*
|
|
9
|
-
*
|
|
7
|
+
* - git_autocommit: Stage files and create a commit with AI-written conventional commit messages.
|
|
8
|
+
* Supports `files` for specific staging and `dry_run` for preview.
|
|
9
|
+
*
|
|
10
|
+
* Note: The former `git_autocommit` and `git_autocommit` tools have been removed.
|
|
11
|
+
* - For staging: use `git_autocommit` with `files` (it stages automatically), or `bash` with `git add`.
|
|
12
|
+
* - For status: use the built-in `git` tool with `command: "status"` or `command: "diff"`.
|
|
10
13
|
*/
|
|
11
14
|
|
|
12
15
|
declare const plugin: Plugin;
|
package/dist/git-autocommit.js
CHANGED
|
@@ -42,19 +42,6 @@ function stageFiles(files, cwd) {
|
|
|
42
42
|
function commitWithMessage(message, cwd) {
|
|
43
43
|
return runGit(["commit", "-m", message], cwd);
|
|
44
44
|
}
|
|
45
|
-
function getCommitHistory(since, cwd) {
|
|
46
|
-
const range = `${since}..HEAD` ;
|
|
47
|
-
const output = runGit(["log", range, "--format=%H %s"], cwd);
|
|
48
|
-
if (!output) return [];
|
|
49
|
-
return output.split("\n").filter(Boolean).map((line) => {
|
|
50
|
-
const spaceIdx = line.indexOf(" ");
|
|
51
|
-
const hash = line.slice(0, spaceIdx);
|
|
52
|
-
const message = line.slice(spaceIdx + 1);
|
|
53
|
-
const typeMatch = message.match(/^(\w+)(!)?:\s/);
|
|
54
|
-
const type = typeMatch?.[1] ?? "chore";
|
|
55
|
-
return { hash, message, type };
|
|
56
|
-
});
|
|
57
|
-
}
|
|
58
45
|
function getWorktrees(cwd) {
|
|
59
46
|
try {
|
|
60
47
|
const out = runGit(["worktree", "list", "--porcelain"], cwd);
|
|
@@ -118,7 +105,7 @@ ${body}` : "";
|
|
|
118
105
|
}
|
|
119
106
|
var plugin = {
|
|
120
107
|
name: "git-autocommit",
|
|
121
|
-
version: "0.
|
|
108
|
+
version: "0.2.0",
|
|
122
109
|
description: "AI-powered git staging and conventional commit message generation",
|
|
123
110
|
apiVersion: API_VERSION,
|
|
124
111
|
capabilities: { tools: true },
|
|
@@ -161,10 +148,11 @@ var plugin = {
|
|
|
161
148
|
scope: { type: "string", description: "Commit scope (e.g. auth, api, ui)" },
|
|
162
149
|
message: { type: "string", description: "Commit summary message" },
|
|
163
150
|
body: { type: "string", description: "Optional commit body/description" },
|
|
164
|
-
|
|
151
|
+
dry_run: { type: "boolean", default: false, description: "Show what would be committed without committing" }
|
|
165
152
|
}
|
|
166
153
|
},
|
|
167
154
|
permission: "confirm",
|
|
155
|
+
category: "Git",
|
|
168
156
|
mutating: true,
|
|
169
157
|
async execute(input, _ctx) {
|
|
170
158
|
try {
|
|
@@ -172,13 +160,13 @@ var plugin = {
|
|
|
172
160
|
const scope = input["scope"];
|
|
173
161
|
const summary = input["message"] ?? "";
|
|
174
162
|
const body = input["body"];
|
|
175
|
-
const dryRun = input["
|
|
163
|
+
const dryRun = input["dry_run"] ?? false;
|
|
176
164
|
const validTypes = ["feat", "fix", "docs", "style", "refactor", "test", "chore", "perf", "ci", "build", "revert"];
|
|
177
165
|
if (!type || !validTypes.includes(type)) {
|
|
178
166
|
if (dryRun) {
|
|
179
167
|
return {
|
|
180
168
|
ok: true,
|
|
181
|
-
|
|
169
|
+
dry_run: true,
|
|
182
170
|
message: `Would create: ${summary || "update code"}`
|
|
183
171
|
};
|
|
184
172
|
}
|
|
@@ -239,7 +227,7 @@ var plugin = {
|
|
|
239
227
|
if (dryRun) {
|
|
240
228
|
return {
|
|
241
229
|
ok: true,
|
|
242
|
-
|
|
230
|
+
dry_run: true,
|
|
243
231
|
message: `Would create: ${msg}`,
|
|
244
232
|
warning: warning ?? void 0,
|
|
245
233
|
stagedDiff: `
|
|
@@ -301,126 +289,8 @@ ${preCommitDiff}
|
|
|
301
289
|
}
|
|
302
290
|
}
|
|
303
291
|
});
|
|
304
|
-
api.tools.register({
|
|
305
|
-
name: "git_stage",
|
|
306
|
-
description: "Stage specific files for commit. Shows what would be staged without staging if dryRun is true.",
|
|
307
|
-
inputSchema: {
|
|
308
|
-
type: "object",
|
|
309
|
-
properties: {
|
|
310
|
-
files: { type: "array", items: { type: "string" }, description: "Files to stage" },
|
|
311
|
-
dryRun: { type: "boolean", default: false }
|
|
312
|
-
},
|
|
313
|
-
required: ["files"]
|
|
314
|
-
},
|
|
315
|
-
permission: "confirm",
|
|
316
|
-
mutating: true,
|
|
317
|
-
async execute(input) {
|
|
318
|
-
try {
|
|
319
|
-
let files;
|
|
320
|
-
try {
|
|
321
|
-
files = input["files"] ?? [];
|
|
322
|
-
} catch {
|
|
323
|
-
files = [];
|
|
324
|
-
}
|
|
325
|
-
const dryRun = input["dryRun"] ?? false;
|
|
326
|
-
if (!Array.isArray(files) || files.length === 0) {
|
|
327
|
-
return { ok: false, error: "files must be a non-empty array of file paths" };
|
|
328
|
-
}
|
|
329
|
-
if (dryRun) {
|
|
330
|
-
return { ok: true, dryRun: true, files, message: `Would stage: ${files.join(", ")}` };
|
|
331
|
-
}
|
|
332
|
-
try {
|
|
333
|
-
stageFiles(files);
|
|
334
|
-
} catch (err) {
|
|
335
|
-
return { ok: false, error: `Failed to stage files: ${err instanceof Error ? err.message : String(err)}` };
|
|
336
|
-
}
|
|
337
|
-
let stillChanged = [];
|
|
338
|
-
try {
|
|
339
|
-
stillChanged = getChangedFiles();
|
|
340
|
-
} catch {
|
|
341
|
-
stillChanged = [];
|
|
342
|
-
}
|
|
343
|
-
return {
|
|
344
|
-
ok: true,
|
|
345
|
-
staged: files,
|
|
346
|
-
stillChanged,
|
|
347
|
-
message: `Staged ${files.length} file(s). ${stillChanged.length} file(s) still changed.`
|
|
348
|
-
};
|
|
349
|
-
} catch (err) {
|
|
350
|
-
return { ok: false, error: `git_stage error: ${err instanceof Error ? err.message : String(err)}` };
|
|
351
|
-
}
|
|
352
|
-
}
|
|
353
|
-
});
|
|
354
|
-
api.tools.register({
|
|
355
|
-
name: "git_status_summary",
|
|
356
|
-
description: "Returns a summary of the current git repository status: changed files, staged files, current branch, and recent commits.",
|
|
357
|
-
inputSchema: { type: "object", properties: {} },
|
|
358
|
-
permission: "auto",
|
|
359
|
-
mutating: false,
|
|
360
|
-
async execute() {
|
|
361
|
-
let branch = "";
|
|
362
|
-
let changed = [];
|
|
363
|
-
let staged = [];
|
|
364
|
-
let aheadBehind = "";
|
|
365
|
-
const recentCommits = [];
|
|
366
|
-
let worktrees = [];
|
|
367
|
-
let worktreeWarn = null;
|
|
368
|
-
let externalChanges = null;
|
|
369
|
-
try {
|
|
370
|
-
branch = runGit(["branch", "--show-current"]);
|
|
371
|
-
} catch {
|
|
372
|
-
}
|
|
373
|
-
try {
|
|
374
|
-
changed = getChangedFiles();
|
|
375
|
-
} catch {
|
|
376
|
-
}
|
|
377
|
-
try {
|
|
378
|
-
staged = getStagedFiles();
|
|
379
|
-
} catch {
|
|
380
|
-
}
|
|
381
|
-
try {
|
|
382
|
-
aheadBehind = runGit(["status", "-sb"]).split("\n")[0] ?? "";
|
|
383
|
-
} catch {
|
|
384
|
-
}
|
|
385
|
-
try {
|
|
386
|
-
recentCommits.push(...getCommitHistory("-3", void 0).map((c) => ({ hash: (c.hash ?? "").slice(0, 7), message: c.message })));
|
|
387
|
-
} catch {
|
|
388
|
-
}
|
|
389
|
-
try {
|
|
390
|
-
worktrees = getWorktrees();
|
|
391
|
-
} catch {
|
|
392
|
-
}
|
|
393
|
-
try {
|
|
394
|
-
worktreeWarn = simultaneousEditWarning();
|
|
395
|
-
} catch {
|
|
396
|
-
}
|
|
397
|
-
try {
|
|
398
|
-
const out = runGit(["status", "--porcelain"]);
|
|
399
|
-
const unstaged = out.split("\n").filter((l) => {
|
|
400
|
-
const idx = l[0] ?? " ";
|
|
401
|
-
return idx === " " || idx === "?";
|
|
402
|
-
}).map((l) => l.slice(3).trim()).filter(Boolean);
|
|
403
|
-
externalChanges = unstaged.length > 0 ? unstaged : null;
|
|
404
|
-
} catch {
|
|
405
|
-
}
|
|
406
|
-
return {
|
|
407
|
-
ok: true,
|
|
408
|
-
branch,
|
|
409
|
-
changedFiles: changed,
|
|
410
|
-
stagedFiles: staged,
|
|
411
|
-
aheadBehind,
|
|
412
|
-
recentCommits,
|
|
413
|
-
worktrees: worktrees.length > 0 ? worktrees.map((w) => ({
|
|
414
|
-
path: w.path,
|
|
415
|
-
branch: w.branch.replace("refs/heads/", "")
|
|
416
|
-
})) : [],
|
|
417
|
-
worktreeWarning: worktreeWarn ?? void 0,
|
|
418
|
-
externalChanges: externalChanges ?? void 0
|
|
419
|
-
};
|
|
420
|
-
}
|
|
421
|
-
});
|
|
422
292
|
api.log.info("git-autocommit plugin loaded", {
|
|
423
|
-
version: "0.
|
|
293
|
+
version: "0.2.0",
|
|
424
294
|
conventionalCommits: opts.conventionalCommits
|
|
425
295
|
});
|
|
426
296
|
}
|