@vforsh/argus 0.1.4 → 0.1.6

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.
Files changed (72) hide show
  1. package/README.md +0 -2
  2. package/dist/.tsbuildinfo +1 -1
  3. package/dist/argus.js +158 -261
  4. package/dist/bin.js +2 -0
  5. package/dist/bin.js.map +1 -1
  6. package/dist/cli/plugins/registerPlugins.d.ts +3 -0
  7. package/dist/cli/plugins/registerPlugins.d.ts.map +1 -0
  8. package/dist/cli/plugins/registerPlugins.js +134 -0
  9. package/dist/cli/plugins/registerPlugins.js.map +1 -0
  10. package/dist/cli/register/registerExtension.d.ts.map +1 -1
  11. package/dist/cli/register/registerExtension.js +0 -9
  12. package/dist/cli/register/registerExtension.js.map +1 -1
  13. package/dist/commands/configInit.d.ts.map +1 -1
  14. package/dist/commands/configInit.js +1 -0
  15. package/dist/commands/configInit.js.map +1 -1
  16. package/dist/commands/contexts.d.ts +7 -0
  17. package/dist/commands/contexts.d.ts.map +1 -0
  18. package/dist/commands/contexts.js +54 -0
  19. package/dist/commands/contexts.js.map +1 -0
  20. package/dist/commands/domDiff.d.ts +43 -0
  21. package/dist/commands/domDiff.d.ts.map +1 -0
  22. package/dist/commands/domDiff.js +279 -0
  23. package/dist/commands/domDiff.js.map +1 -0
  24. package/dist/commands/extension/attach.d.ts +8 -0
  25. package/dist/commands/extension/attach.d.ts.map +1 -0
  26. package/dist/commands/extension/attach.js +171 -0
  27. package/dist/commands/extension/attach.js.map +1 -0
  28. package/dist/commands/extension/detach.d.ts +6 -0
  29. package/dist/commands/extension/detach.d.ts.map +1 -0
  30. package/dist/commands/extension/detach.js +132 -0
  31. package/dist/commands/extension/detach.js.map +1 -0
  32. package/dist/commands/extension/targets.d.ts +13 -0
  33. package/dist/commands/extension/targets.d.ts.map +1 -0
  34. package/dist/commands/extension/targets.js +77 -0
  35. package/dist/commands/extension/targets.js.map +1 -0
  36. package/dist/commands/frames.d.ts +7 -0
  37. package/dist/commands/frames.d.ts.map +1 -0
  38. package/dist/commands/frames.js +90 -0
  39. package/dist/commands/frames.js.map +1 -0
  40. package/dist/config/argusConfig.d.ts +6 -0
  41. package/dist/config/argusConfig.d.ts.map +1 -1
  42. package/dist/config/argusConfig.js +16 -1
  43. package/dist/config/argusConfig.js.map +1 -1
  44. package/dist/frame/frameSelector.d.ts +14 -0
  45. package/dist/frame/frameSelector.d.ts.map +1 -0
  46. package/dist/frame/frameSelector.js +31 -0
  47. package/dist/frame/frameSelector.js.map +1 -0
  48. package/dist/output/domDiff.d.ts +14 -0
  49. package/dist/output/domDiff.d.ts.map +1 -0
  50. package/dist/output/domDiff.js +151 -0
  51. package/dist/output/domDiff.js.map +1 -0
  52. package/dist/plugin.d.ts +29 -0
  53. package/dist/plugin.d.ts.map +1 -0
  54. package/dist/plugin.js +2 -0
  55. package/dist/plugin.js.map +1 -0
  56. package/dist/throttle/networkPresets.d.ts +6 -0
  57. package/dist/throttle/networkPresets.d.ts.map +1 -0
  58. package/dist/throttle/networkPresets.js +24 -0
  59. package/dist/throttle/networkPresets.js.map +1 -0
  60. package/package.json +15 -5
  61. package/dist/commands/extension/doctor.d.ts +0 -5
  62. package/dist/commands/extension/doctor.d.ts.map +0 -1
  63. package/dist/commands/extension/doctor.js +0 -262
  64. package/dist/commands/extension/doctor.js.map +0 -1
  65. package/dist/commands/extension/id.d.ts +0 -9
  66. package/dist/commands/extension/id.d.ts.map +0 -1
  67. package/dist/commands/extension/id.js +0 -122
  68. package/dist/commands/extension/id.js.map +0 -1
  69. package/dist/commands/extension/list.d.ts +0 -8
  70. package/dist/commands/extension/list.d.ts.map +0 -1
  71. package/dist/commands/extension/list.js +0 -194
  72. package/dist/commands/extension/list.js.map +0 -1
package/dist/argus.js CHANGED
@@ -19,7 +19,7 @@ var __toESM = (mod, isNodeMode, target) => {
19
19
  var __commonJS = (cb, mod) => () => (mod || cb((mod = { exports: {} }).exports, mod), mod.exports);
20
20
  var __require = import.meta.require;
21
21
 
22
- // ../../node_modules/commander/lib/error.js
22
+ // ../../node_modules/.bun/commander@14.0.2/node_modules/commander/lib/error.js
23
23
  var require_error = __commonJS((exports) => {
24
24
  class CommanderError extends Error {
25
25
  constructor(exitCode, code, message) {
@@ -43,7 +43,7 @@ var require_error = __commonJS((exports) => {
43
43
  exports.InvalidArgumentError = InvalidArgumentError;
44
44
  });
45
45
 
46
- // ../../node_modules/commander/lib/argument.js
46
+ // ../../node_modules/.bun/commander@14.0.2/node_modules/commander/lib/argument.js
47
47
  var require_argument = __commonJS((exports) => {
48
48
  var { InvalidArgumentError } = require_error();
49
49
 
@@ -123,7 +123,7 @@ var require_argument = __commonJS((exports) => {
123
123
  exports.humanReadableArgName = humanReadableArgName;
124
124
  });
125
125
 
126
- // ../../node_modules/commander/lib/help.js
126
+ // ../../node_modules/.bun/commander@14.0.2/node_modules/commander/lib/help.js
127
127
  var require_help = __commonJS((exports) => {
128
128
  var { humanReadableArgName } = require_argument();
129
129
 
@@ -480,7 +480,7 @@ ${itemIndentStr}`);
480
480
  exports.stripColor = stripColor;
481
481
  });
482
482
 
483
- // ../../node_modules/commander/lib/option.js
483
+ // ../../node_modules/.bun/commander@14.0.2/node_modules/commander/lib/option.js
484
484
  var require_option = __commonJS((exports) => {
485
485
  var { InvalidArgumentError } = require_error();
486
486
 
@@ -664,7 +664,7 @@ var require_option = __commonJS((exports) => {
664
664
  exports.DualOptions = DualOptions;
665
665
  });
666
666
 
667
- // ../../node_modules/commander/lib/suggestSimilar.js
667
+ // ../../node_modules/.bun/commander@14.0.2/node_modules/commander/lib/suggestSimilar.js
668
668
  var require_suggestSimilar = __commonJS((exports) => {
669
669
  var maxDistance = 3;
670
670
  function editDistance(a, b) {
@@ -737,7 +737,7 @@ var require_suggestSimilar = __commonJS((exports) => {
737
737
  exports.suggestSimilar = suggestSimilar;
738
738
  });
739
739
 
740
- // ../../node_modules/commander/lib/command.js
740
+ // ../../node_modules/.bun/commander@14.0.2/node_modules/commander/lib/command.js
741
741
  var require_command = __commonJS((exports) => {
742
742
  var EventEmitter = __require("events").EventEmitter;
743
743
  var childProcess = __require("child_process");
@@ -2092,7 +2092,7 @@ Expecting one of '${allowedValues.join("', '")}'`);
2092
2092
  exports.useColor = useColor;
2093
2093
  });
2094
2094
 
2095
- // ../../node_modules/commander/index.js
2095
+ // ../../node_modules/.bun/commander@14.0.2/node_modules/commander/index.js
2096
2096
  var require_commander = __commonJS((exports) => {
2097
2097
  var { Argument } = require_argument();
2098
2098
  var { Command } = require_command();
@@ -2112,7 +2112,7 @@ var require_commander = __commonJS((exports) => {
2112
2112
  exports.InvalidOptionArgumentError = InvalidArgumentError;
2113
2113
  });
2114
2114
 
2115
- // ../../node_modules/commander/esm.mjs
2115
+ // ../../node_modules/.bun/commander@14.0.2/node_modules/commander/esm.mjs
2116
2116
  var import__ = __toESM(require_commander(), 1);
2117
2117
  var {
2118
2118
  program,
@@ -3473,12 +3473,12 @@ import fs7 from "fs/promises";
3473
3473
  import os3 from "os";
3474
3474
  import path7 from "path";
3475
3475
 
3476
- // ../../node_modules/emittery/maps.js
3476
+ // ../../node_modules/.bun/emittery@1.2.0/node_modules/emittery/maps.js
3477
3477
  var anyMap = new WeakMap;
3478
3478
  var eventsMap = new WeakMap;
3479
3479
  var producersMap = new WeakMap;
3480
3480
 
3481
- // ../../node_modules/emittery/index.js
3481
+ // ../../node_modules/.bun/emittery@1.2.0/node_modules/emittery/index.js
3482
3482
  var anyProducer = Symbol("anyProducer");
3483
3483
  var resolvedPromise = Promise.resolve();
3484
3484
  var listenerAdded = Symbol("listenerAdded");
@@ -8008,7 +8008,7 @@ var stripUrlPrefixes = (file, prefixes) => {
8008
8008
  return file;
8009
8009
  };
8010
8010
 
8011
- // ../../node_modules/@jridgewell/sourcemap-codec/dist/sourcemap-codec.mjs
8011
+ // ../../node_modules/.bun/@jridgewell+sourcemap-codec@1.5.5/node_modules/@jridgewell/sourcemap-codec/dist/sourcemap-codec.mjs
8012
8012
  var comma = 44;
8013
8013
  var chars = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/";
8014
8014
  var intToChar = new Uint8Array(64);
@@ -8109,7 +8109,7 @@ function sortComparator(a, b) {
8109
8109
  return a[0] - b[0];
8110
8110
  }
8111
8111
 
8112
- // ../../node_modules/@jridgewell/resolve-uri/dist/resolve-uri.mjs
8112
+ // ../../node_modules/.bun/@jridgewell+resolve-uri@3.1.2/node_modules/@jridgewell/resolve-uri/dist/resolve-uri.mjs
8113
8113
  var schemeRegex = /^[\w+.-]+:\/\//;
8114
8114
  var urlRegex = /^([\w+.-]+:)\/\/([^@/#?]*@)?([^:/#?]*)(:\d+)?(\/[^#?]*)?(\?[^#]*)?(#.*)?/;
8115
8115
  var fileRegex = /^file:(?:\/\/((?![a-z]:)[^/#?]*)?)?(\/?[^#?]*)(\?[^#]*)?(#.*)?/i;
@@ -8272,7 +8272,7 @@ function resolve(input, base) {
8272
8272
  }
8273
8273
  }
8274
8274
 
8275
- // ../../node_modules/@jridgewell/trace-mapping/dist/trace-mapping.mjs
8275
+ // ../../node_modules/.bun/@jridgewell+trace-mapping@0.3.31/node_modules/@jridgewell/trace-mapping/dist/trace-mapping.mjs
8276
8276
  function stripFilename(path7) {
8277
8277
  if (!path7)
8278
8278
  return "";
@@ -10913,6 +10913,21 @@ var validateArgusConfig = (value) => {
10913
10913
  if (!isRecord(value)) {
10914
10914
  return { ok: false, error: "Config root must be an object." };
10915
10915
  }
10916
+ let plugins;
10917
+ if (value.plugins !== undefined) {
10918
+ if (!Array.isArray(value.plugins)) {
10919
+ return { ok: false, error: '"plugins" must be an array of strings.' };
10920
+ }
10921
+ for (const [index, item] of value.plugins.entries()) {
10922
+ if (typeof item !== "string") {
10923
+ return { ok: false, error: `"plugins[${index}]" must be a string.` };
10924
+ }
10925
+ if (item.trim() === "") {
10926
+ return { ok: false, error: `"plugins[${index}]" must be a non-empty string.` };
10927
+ }
10928
+ }
10929
+ plugins = value.plugins;
10930
+ }
10916
10931
  let chromeConfig;
10917
10932
  if (value.chrome !== undefined) {
10918
10933
  if (!isRecord(value.chrome)) {
@@ -10943,7 +10958,7 @@ var validateArgusConfig = (value) => {
10943
10958
  watcherConfig = {};
10944
10959
  }
10945
10960
  }
10946
- return { ok: true, value: { chrome: chromeConfig, watcher: watcherConfig } };
10961
+ return { ok: true, value: { chrome: chromeConfig, watcher: watcherConfig, plugins } };
10947
10962
  };
10948
10963
  var resolveArgusConfigPath = ({ cliPath, cwd }) => {
10949
10964
  if (cliPath) {
@@ -15567,6 +15582,7 @@ import { fileURLToPath, pathToFileURL } from "url";
15567
15582
  var DEFAULT_CONFIG_PATH = ".argus/config.json";
15568
15583
  var buildConfigTemplate = (schemaRef) => ({
15569
15584
  $schema: schemaRef,
15585
+ plugins: [],
15570
15586
  chrome: {
15571
15587
  start: {
15572
15588
  url: "http://localhost:3000",
@@ -16049,250 +16065,6 @@ var runExtensionInfo = async (options) => {
16049
16065
  output.writeHuman("");
16050
16066
  };
16051
16067
 
16052
- // dist/commands/extension/doctor.js
16053
- import fs18 from "fs";
16054
- import { constants as fsConstants } from "fs";
16055
- var runExtensionDoctor = async (options) => {
16056
- const output = createOutput(options);
16057
- let platform;
16058
- try {
16059
- platform = getPlatform();
16060
- } catch (error) {
16061
- const message = error.message;
16062
- if (options.json) {
16063
- output.writeJson({ ok: false, status: "fail", checks: [{ id: "platform", status: "fail", message }] });
16064
- } else {
16065
- output.writeHuman(`FAIL ${message}`);
16066
- }
16067
- process.exitCode = 1;
16068
- return;
16069
- }
16070
- const checks = [];
16071
- const hints = new Set;
16072
- const extensionInstallHint = "Ensure Argus extension is installed and enabled in chrome://extensions (Developer mode for unpacked install).";
16073
- hints.add(extensionInstallHint);
16074
- const manifestPath = getManifestPath(platform);
16075
- const wrapperPath = getWrapperPath(platform);
16076
- const manifestExists = fs18.existsSync(manifestPath);
16077
- const wrapperExists = fs18.existsSync(wrapperPath);
16078
- const wrapperExecutable = wrapperExists && isWrapperExecutable(wrapperPath);
16079
- let extensionId = null;
16080
- let manifestValid = false;
16081
- let manifestHostValid = false;
16082
- let manifestPathExecutable = false;
16083
- let manifestPathMatchesWrapper = false;
16084
- let manifestPathFromFile = null;
16085
- if (manifestExists) {
16086
- const manifest = readManifest(manifestPath);
16087
- if (manifest) {
16088
- manifestPathFromFile = manifest.path;
16089
- manifestHostValid = manifest.name === HOST_NAME && manifest.type === "stdio" && Array.isArray(manifest.allowed_origins);
16090
- const origin = manifest.allowed_origins?.[0];
16091
- if (origin) {
16092
- const match = origin.match(/^chrome-extension:\/\/([^/]+)\/$/);
16093
- if (match) {
16094
- extensionId = match[1];
16095
- }
16096
- }
16097
- if (manifest.path && fileExecutable(manifest.path)) {
16098
- manifestPathExecutable = true;
16099
- }
16100
- manifestPathMatchesWrapper = manifest.path === wrapperPath;
16101
- manifestValid = manifestHostValid && manifestPathExecutable && Boolean(extensionId);
16102
- }
16103
- }
16104
- if (!manifestExists) {
16105
- const hint = "Run: argus extension setup <extensionId> (copy ID from chrome://extensions).";
16106
- checks.push({ id: "native-host-manifest", status: "fail", message: `manifest not found: ${manifestPath}`, hint });
16107
- hints.add(hint);
16108
- } else if (!manifestHostValid) {
16109
- const hint = "Manifest looks invalid. Reinstall host: argus extension setup <extensionId>.";
16110
- checks.push({ id: "native-host-manifest", status: "fail", message: "manifest exists but has invalid schema/host fields", hint });
16111
- hints.add(hint);
16112
- } else if (!extensionId) {
16113
- const hint = "Manifest has no valid extension origin. Re-run: argus extension setup <extensionId>.";
16114
- checks.push({ id: "native-host-manifest", status: "fail", message: "manifest missing chrome-extension origin", hint });
16115
- hints.add(hint);
16116
- } else if (!manifestPathExecutable) {
16117
- const hint = "Manifest points to non-executable host path. Re-run: argus extension setup <extensionId>.";
16118
- checks.push({
16119
- id: "native-host-manifest",
16120
- status: "fail",
16121
- message: `manifest host path is not executable: ${manifestPathFromFile ?? "(unknown)"}`,
16122
- hint
16123
- });
16124
- hints.add(hint);
16125
- } else {
16126
- checks.push({
16127
- id: "native-host-manifest",
16128
- status: "ok",
16129
- message: `manifest configured for extension ${extensionId}`,
16130
- data: {
16131
- path: manifestPath,
16132
- extensionId
16133
- }
16134
- });
16135
- }
16136
- if (!wrapperExists) {
16137
- const hint = "Wrapper script missing. Re-run: argus extension setup <extensionId>.";
16138
- checks.push({ id: "native-host-wrapper", status: "fail", message: `wrapper not found: ${wrapperPath}`, hint });
16139
- hints.add(hint);
16140
- } else if (!wrapperExecutable) {
16141
- const hint = `Wrapper is not executable. Run: chmod +x "${wrapperPath}" or re-run extension setup.`;
16142
- checks.push({ id: "native-host-wrapper", status: "fail", message: `wrapper not executable: ${wrapperPath}`, hint });
16143
- hints.add(hint);
16144
- } else if (!manifestPathMatchesWrapper) {
16145
- const hint = "Manifest path doesn't match wrapper path. Re-run: argus extension setup <extensionId>.";
16146
- checks.push({
16147
- id: "native-host-wrapper",
16148
- status: "warn",
16149
- message: `wrapper exists (${wrapperPath}) but manifest points to ${manifestPathFromFile ?? "(unknown)"}`,
16150
- hint
16151
- });
16152
- hints.add(hint);
16153
- } else {
16154
- checks.push({ id: "native-host-wrapper", status: "ok", message: `wrapper executable: ${wrapperPath}` });
16155
- }
16156
- const watcherReports = [];
16157
- let registryError = null;
16158
- try {
16159
- const registry2 = await loadRegistryWithoutStderrWarnings();
16160
- const extensionWatchers = Object.values(registry2.watchers).filter((entry) => entry.source === "extension");
16161
- if (extensionWatchers.length === 0) {
16162
- const hint = "Start extension mode watcher: argus watcher start --id app --source extension";
16163
- checks.push({ id: "extension-watcher", status: "warn", message: "no extension watchers registered", hint });
16164
- hints.add(hint);
16165
- } else {
16166
- for (const watcher of extensionWatchers) {
16167
- const statusResult = await checkWatcherStatus3(watcher.host, watcher.port);
16168
- if (!statusResult.ok) {
16169
- const hint = `Watcher "${watcher.id}" unreachable. Restart it: argus watcher start --id ${watcher.id} --source extension`;
16170
- watcherReports.push({
16171
- id: watcher.id,
16172
- host: watcher.host,
16173
- port: watcher.port,
16174
- status: "warn",
16175
- message: `unreachable (${statusResult.error})`,
16176
- hint
16177
- });
16178
- hints.add(hint);
16179
- continue;
16180
- }
16181
- const status2 = statusResult.status;
16182
- if (!status2.attached) {
16183
- const hint = `Watcher "${watcher.id}" is running but detached. Open extension popup and attach a tab.`;
16184
- watcherReports.push({
16185
- id: watcher.id,
16186
- host: watcher.host,
16187
- port: watcher.port,
16188
- status: "warn",
16189
- message: "running but no tabs attached",
16190
- hint,
16191
- attached: false,
16192
- target: status2.target
16193
- });
16194
- hints.add(hint);
16195
- } else {
16196
- watcherReports.push({
16197
- id: watcher.id,
16198
- host: watcher.host,
16199
- port: watcher.port,
16200
- status: "ok",
16201
- message: "running and attached",
16202
- attached: true,
16203
- target: status2.target
16204
- });
16205
- }
16206
- }
16207
- const hasAttachedWatcher = watcherReports.some((report) => report.status === "ok" && report.attached);
16208
- if (!hasAttachedWatcher) {
16209
- const hint = "No attached extension tabs detected. Open the Argus extension popup and click Attach.";
16210
- checks.push({ id: "extension-attach", status: "warn", message: "no attached extension tabs", hint });
16211
- hints.add(hint);
16212
- } else {
16213
- checks.push({ id: "extension-attach", status: "ok", message: "at least one extension watcher is attached" });
16214
- }
16215
- }
16216
- } catch (error) {
16217
- registryError = error instanceof Error ? error.message : String(error);
16218
- const hint = "Run `argus doctor` to inspect registry and environment issues.";
16219
- checks.push({ id: "registry", status: "warn", message: `failed to read registry (${registryError})`, hint });
16220
- hints.add(hint);
16221
- }
16222
- const hasFail = checks.some((check) => check.status === "fail");
16223
- const hasWarn = checks.some((check) => check.status === "warn") || watcherReports.some((report) => report.status === "warn");
16224
- const ok = !hasFail && !hasWarn;
16225
- const status = hasFail ? "fail" : hasWarn ? "warn" : "ok";
16226
- if (options.json) {
16227
- output.writeJson({
16228
- ok,
16229
- status,
16230
- hostName: HOST_NAME,
16231
- platform,
16232
- manifestPath,
16233
- wrapperPath,
16234
- extensionId,
16235
- registryError,
16236
- checks,
16237
- watchers: watcherReports,
16238
- hints: Array.from(hints)
16239
- });
16240
- if (!ok) {
16241
- process.exitCode = 1;
16242
- }
16243
- return;
16244
- }
16245
- output.writeHuman("");
16246
- output.writeHuman(`Extension doctor: ${status.toUpperCase()}`);
16247
- output.writeHuman("");
16248
- for (const check of checks) {
16249
- output.writeHuman(`${formatStatus2(check.status)} ${check.message}`);
16250
- }
16251
- for (const watcher of watcherReports) {
16252
- const target = watcher.target?.title ?? watcher.target?.url;
16253
- output.writeHuman(`${formatStatus2(watcher.status)} watcher ${watcher.id} ${watcher.host}:${watcher.port} ${watcher.message}${target ? ` (${target})` : ""}`);
16254
- }
16255
- if (hints.size > 0) {
16256
- output.writeHuman("");
16257
- output.writeHuman("Hints:");
16258
- for (const hint of hints) {
16259
- output.writeHuman(` - ${hint}`);
16260
- }
16261
- }
16262
- output.writeHuman("");
16263
- if (!ok) {
16264
- process.exitCode = 1;
16265
- }
16266
- };
16267
- var loadRegistryWithoutStderrWarnings = async () => {
16268
- const { registry: registry2 } = await readRegistry();
16269
- return registry2;
16270
- };
16271
- var checkWatcherStatus3 = async (host, port) => {
16272
- const url = `http://${host}:${port}/status`;
16273
- try {
16274
- const status = await fetchJson(url, { timeoutMs: 2000 });
16275
- return { ok: true, status };
16276
- } catch (error) {
16277
- return { ok: false, error: error instanceof Error ? error.message : String(error) };
16278
- }
16279
- };
16280
- var fileExecutable = (path13) => {
16281
- try {
16282
- fs18.accessSync(path13, fsConstants.X_OK);
16283
- return true;
16284
- } catch {
16285
- return false;
16286
- }
16287
- };
16288
- var formatStatus2 = (status) => {
16289
- if (status === "ok")
16290
- return "OK";
16291
- if (status === "fail")
16292
- return "FAIL";
16293
- return "WARN";
16294
- };
16295
-
16296
16068
  // dist/cli/register/registerExtension.js
16297
16069
  function registerExtension(program2) {
16298
16070
  const extension = program2.command("extension").alias("ext").description("Browser extension management");
@@ -16314,11 +16086,135 @@ To get your extension ID:
16314
16086
  extension.command("info").description("Show native messaging host paths and configuration").option("--json", "Output JSON for automation").action(async (options) => {
16315
16087
  await runExtensionInfo(options);
16316
16088
  });
16317
- extension.command("doctor").alias("check").description("Run extension diagnostics and print actionable fixes").option("--json", "Output JSON for automation").action(async (options) => {
16318
- await runExtensionDoctor(options);
16319
- });
16320
16089
  }
16321
16090
 
16091
+ // dist/cli/plugins/registerPlugins.js
16092
+ import path13 from "path";
16093
+ import { pathToFileURL as pathToFileURL2 } from "url";
16094
+
16095
+ // dist/plugin.js
16096
+ var ARGUS_PLUGIN_API_VERSION = 1;
16097
+
16098
+ // dist/cli/plugins/registerPlugins.js
16099
+ var parseEnvPlugins = () => {
16100
+ const raw = process.env.ARGUS_PLUGINS;
16101
+ if (!raw)
16102
+ return [];
16103
+ return raw.split(",").map((s) => s.trim()).filter(Boolean);
16104
+ };
16105
+ var uniq = (values) => Array.from(new Set(values));
16106
+ var resolveWithImportMeta = (specifier, parentUrl) => {
16107
+ const resolver2 = import.meta.resolve;
16108
+ if (typeof resolver2 !== "function") {
16109
+ throw new Error("Runtime does not support import.meta.resolve().");
16110
+ }
16111
+ return resolver2(specifier, parentUrl);
16112
+ };
16113
+ var resolvePluginModuleUrl = (specifier, baseDirs) => {
16114
+ const trimmed = specifier.trim();
16115
+ if (!trimmed) {
16116
+ return { ok: false, error: "Empty plugin specifier." };
16117
+ }
16118
+ if (trimmed.startsWith("file:")) {
16119
+ return { ok: true, url: trimmed };
16120
+ }
16121
+ const errors = [];
16122
+ try {
16123
+ return { ok: true, url: resolveWithImportMeta(trimmed, import.meta.url) };
16124
+ } catch (error) {
16125
+ const msg = error instanceof Error ? error.message : String(error);
16126
+ errors.push(`argus: ${msg}`);
16127
+ }
16128
+ for (const baseDir of baseDirs) {
16129
+ try {
16130
+ const baseUrl = pathToFileURL2(path13.join(baseDir, "noop.js")).href;
16131
+ return { ok: true, url: resolveWithImportMeta(trimmed, baseUrl) };
16132
+ } catch (error) {
16133
+ const msg = error instanceof Error ? error.message : String(error);
16134
+ errors.push(`${baseDir}: ${msg}`);
16135
+ }
16136
+ }
16137
+ return { ok: false, error: `Failed to resolve plugin "${specifier}". Tried:
16138
+ ${errors.map((e) => `- ${e}`).join(`
16139
+ `)}` };
16140
+ };
16141
+ var extractPlugin = (mod) => {
16142
+ if (!mod || typeof mod !== "object")
16143
+ return null;
16144
+ const record = mod;
16145
+ const candidate = record.default ?? record.argusPlugin;
16146
+ if (!candidate || typeof candidate !== "object")
16147
+ return null;
16148
+ const plugin = candidate;
16149
+ if (plugin.apiVersion !== ARGUS_PLUGIN_API_VERSION)
16150
+ return null;
16151
+ if (!plugin.name || typeof plugin.name !== "string")
16152
+ return null;
16153
+ if (typeof plugin.register !== "function")
16154
+ return null;
16155
+ return plugin;
16156
+ };
16157
+ var warnPluginLoad = (source, spec, message) => {
16158
+ const output = createOutput({ json: false });
16159
+ output.writeWarn(`[plugins] Failed to load (${source}) "${spec}": ${message}`);
16160
+ };
16161
+ var registerPlugins = async (program2) => {
16162
+ const cwd = process.cwd();
16163
+ const configPath = resolveArgusConfigPath({ cwd });
16164
+ const configResult = configPath ? loadArgusConfig(configPath) : null;
16165
+ const configPlugins = configResult?.config.plugins ?? [];
16166
+ const envPlugins = parseEnvPlugins();
16167
+ const all = [];
16168
+ for (const spec of configPlugins)
16169
+ all.push({ source: "config", spec });
16170
+ for (const spec of envPlugins)
16171
+ all.push({ source: "env", spec });
16172
+ if (all.length === 0)
16173
+ return;
16174
+ const seen = new Set;
16175
+ const ordered = all.filter((p) => {
16176
+ const key = p.spec.trim();
16177
+ if (!key)
16178
+ return false;
16179
+ if (seen.has(key))
16180
+ return false;
16181
+ seen.add(key);
16182
+ return true;
16183
+ });
16184
+ const baseDirs = uniq([configResult?.configDir, cwd].filter((v) => Boolean(v)));
16185
+ const ctxBase = {
16186
+ apiVersion: ARGUS_PLUGIN_API_VERSION,
16187
+ host: { createOutput, requestWatcherJson, writeRequestError, runChromeOpen },
16188
+ cwd,
16189
+ configPath,
16190
+ configDir: configResult?.configDir ?? null
16191
+ };
16192
+ for (const entry of ordered) {
16193
+ const resolved = resolvePluginModuleUrl(entry.spec, baseDirs);
16194
+ if (!resolved.ok) {
16195
+ warnPluginLoad(entry.source, entry.spec, resolved.error);
16196
+ continue;
16197
+ }
16198
+ let mod;
16199
+ try {
16200
+ mod = await import(resolved.url);
16201
+ } catch (error) {
16202
+ warnPluginLoad(entry.source, entry.spec, error instanceof Error ? error.message : String(error));
16203
+ continue;
16204
+ }
16205
+ const plugin = extractPlugin(mod);
16206
+ if (!plugin) {
16207
+ warnPluginLoad(entry.source, entry.spec, "Invalid plugin export (expected default export with { apiVersion: 1, name, register() }).");
16208
+ continue;
16209
+ }
16210
+ try {
16211
+ await plugin.register({ ...ctxBase, program: program2 });
16212
+ } catch (error) {
16213
+ warnPluginLoad(entry.source, entry.spec, error instanceof Error ? error.message : String(error));
16214
+ }
16215
+ }
16216
+ };
16217
+
16322
16218
  // dist/bin.js
16323
16219
  var program2 = createProgram();
16324
16220
  registerQuickAccess(program2);
@@ -16340,6 +16236,7 @@ registerSnapshot(program2);
16340
16236
  registerTrace(program2);
16341
16237
  registerConfig(program2);
16342
16238
  registerExtension(program2);
16239
+ await registerPlugins(program2);
16343
16240
  program2.parseAsync(process.argv).catch((error) => {
16344
16241
  console.error(error);
16345
16242
  process.exit(1);
package/dist/bin.js CHANGED
@@ -19,6 +19,7 @@ import { registerSnapshot } from './cli/register/registerSnapshot.js';
19
19
  import { registerTrace } from './cli/register/registerTrace.js';
20
20
  import { registerConfig } from './cli/register/registerConfig.js';
21
21
  import { registerExtension } from './cli/register/registerExtension.js';
22
+ import { registerPlugins } from './cli/plugins/registerPlugins.js';
22
23
  const program = createProgram();
23
24
  // Quick access
24
25
  registerQuickAccess(program);
@@ -44,6 +45,7 @@ registerTrace(program);
44
45
  // Configuration
45
46
  registerConfig(program);
46
47
  registerExtension(program);
48
+ await registerPlugins(program);
47
49
  program.parseAsync(process.argv).catch((error) => {
48
50
  console.error(error);
49
51
  process.exit(1);
package/dist/bin.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"file":"bin.js","sourceRoot":"","sources":["../src/bin.ts"],"names":[],"mappings":";AACA,OAAO,EAAE,aAAa,EAAE,MAAM,kBAAkB,CAAA;AAChD,OAAO,EAAE,mBAAmB,EAAE,MAAM,uCAAuC,CAAA;AAC3E,OAAO,EAAE,cAAc,EAAE,MAAM,kCAAkC,CAAA;AACjE,OAAO,EAAE,eAAe,EAAE,MAAM,mCAAmC,CAAA;AACnE,OAAO,EAAE,YAAY,EAAE,MAAM,gCAAgC,CAAA;AAC7D,OAAO,EAAE,YAAY,EAAE,MAAM,gCAAgC,CAAA;AAC7D,OAAO,EAAE,WAAW,EAAE,MAAM,+BAA+B,CAAA;AAC3D,OAAO,EAAE,YAAY,EAAE,MAAM,gCAAgC,CAAA;AAC7D,OAAO,EAAE,WAAW,EAAE,MAAM,+BAA+B,CAAA;AAC3D,OAAO,EAAE,aAAa,EAAE,MAAM,iCAAiC,CAAA;AAC/D,OAAO,EAAE,eAAe,EAAE,MAAM,mCAAmC,CAAA;AACnE,OAAO,EAAE,YAAY,EAAE,MAAM,gCAAgC,CAAA;AAC7D,OAAO,EAAE,aAAa,EAAE,MAAM,iCAAiC,CAAA;AAC/D,OAAO,EAAE,gBAAgB,EAAE,MAAM,oCAAoC,CAAA;AACrE,OAAO,EAAE,eAAe,EAAE,MAAM,mCAAmC,CAAA;AACnE,OAAO,EAAE,gBAAgB,EAAE,MAAM,oCAAoC,CAAA;AACrE,OAAO,EAAE,gBAAgB,EAAE,MAAM,oCAAoC,CAAA;AACrE,OAAO,EAAE,aAAa,EAAE,MAAM,iCAAiC,CAAA;AAC/D,OAAO,EAAE,cAAc,EAAE,MAAM,kCAAkC,CAAA;AACjE,OAAO,EAAE,iBAAiB,EAAE,MAAM,qCAAqC,CAAA;AAEvE,MAAM,OAAO,GAAG,aAAa,EAAE,CAAA;AAE/B,eAAe;AACf,mBAAmB,CAAC,OAAO,CAAC,CAAA;AAE5B,yBAAyB;AACzB,cAAc,CAAC,OAAO,CAAC,CAAA;AACvB,eAAe,CAAC,OAAO,CAAC,CAAA;AACxB,YAAY,CAAC,OAAO,CAAC,CAAA;AAErB,kBAAkB;AAClB,YAAY,CAAC,OAAO,CAAC,CAAA;AACrB,WAAW,CAAC,OAAO,CAAC,CAAA;AACpB,YAAY,CAAC,OAAO,CAAC,CAAA;AACrB,WAAW,CAAC,OAAO,CAAC,CAAA;AACpB,aAAa,CAAC,OAAO,CAAC,CAAA;AACtB,eAAe,CAAC,OAAO,CAAC,CAAA;AACxB,YAAY,CAAC,OAAO,CAAC,CAAA;AACrB,aAAa,CAAC,OAAO,CAAC,CAAA;AACtB,gBAAgB,CAAC,OAAO,CAAC,CAAA;AACzB,eAAe,CAAC,OAAO,CAAC,CAAA;AACxB,gBAAgB,CAAC,OAAO,CAAC,CAAA;AAEzB,UAAU;AACV,gBAAgB,CAAC,OAAO,CAAC,CAAA;AACzB,aAAa,CAAC,OAAO,CAAC,CAAA;AAEtB,gBAAgB;AAChB,cAAc,CAAC,OAAO,CAAC,CAAA;AACvB,iBAAiB,CAAC,OAAO,CAAC,CAAA;AAE1B,OAAO,CAAC,UAAU,CAAC,OAAO,CAAC,IAAI,CAAC,CAAC,KAAK,CAAC,CAAC,KAAK,EAAE,EAAE;IAChD,OAAO,CAAC,KAAK,CAAC,KAAK,CAAC,CAAA;IACpB,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAA;AAChB,CAAC,CAAC,CAAA"}
1
+ {"version":3,"file":"bin.js","sourceRoot":"","sources":["../src/bin.ts"],"names":[],"mappings":";AACA,OAAO,EAAE,aAAa,EAAE,MAAM,kBAAkB,CAAA;AAChD,OAAO,EAAE,mBAAmB,EAAE,MAAM,uCAAuC,CAAA;AAC3E,OAAO,EAAE,cAAc,EAAE,MAAM,kCAAkC,CAAA;AACjE,OAAO,EAAE,eAAe,EAAE,MAAM,mCAAmC,CAAA;AACnE,OAAO,EAAE,YAAY,EAAE,MAAM,gCAAgC,CAAA;AAC7D,OAAO,EAAE,YAAY,EAAE,MAAM,gCAAgC,CAAA;AAC7D,OAAO,EAAE,WAAW,EAAE,MAAM,+BAA+B,CAAA;AAC3D,OAAO,EAAE,YAAY,EAAE,MAAM,gCAAgC,CAAA;AAC7D,OAAO,EAAE,WAAW,EAAE,MAAM,+BAA+B,CAAA;AAC3D,OAAO,EAAE,aAAa,EAAE,MAAM,iCAAiC,CAAA;AAC/D,OAAO,EAAE,eAAe,EAAE,MAAM,mCAAmC,CAAA;AACnE,OAAO,EAAE,YAAY,EAAE,MAAM,gCAAgC,CAAA;AAC7D,OAAO,EAAE,aAAa,EAAE,MAAM,iCAAiC,CAAA;AAC/D,OAAO,EAAE,gBAAgB,EAAE,MAAM,oCAAoC,CAAA;AACrE,OAAO,EAAE,eAAe,EAAE,MAAM,mCAAmC,CAAA;AACnE,OAAO,EAAE,gBAAgB,EAAE,MAAM,oCAAoC,CAAA;AACrE,OAAO,EAAE,gBAAgB,EAAE,MAAM,oCAAoC,CAAA;AACrE,OAAO,EAAE,aAAa,EAAE,MAAM,iCAAiC,CAAA;AAC/D,OAAO,EAAE,cAAc,EAAE,MAAM,kCAAkC,CAAA;AACjE,OAAO,EAAE,iBAAiB,EAAE,MAAM,qCAAqC,CAAA;AACvE,OAAO,EAAE,eAAe,EAAE,MAAM,kCAAkC,CAAA;AAElE,MAAM,OAAO,GAAG,aAAa,EAAE,CAAA;AAE/B,eAAe;AACf,mBAAmB,CAAC,OAAO,CAAC,CAAA;AAE5B,yBAAyB;AACzB,cAAc,CAAC,OAAO,CAAC,CAAA;AACvB,eAAe,CAAC,OAAO,CAAC,CAAA;AACxB,YAAY,CAAC,OAAO,CAAC,CAAA;AAErB,kBAAkB;AAClB,YAAY,CAAC,OAAO,CAAC,CAAA;AACrB,WAAW,CAAC,OAAO,CAAC,CAAA;AACpB,YAAY,CAAC,OAAO,CAAC,CAAA;AACrB,WAAW,CAAC,OAAO,CAAC,CAAA;AACpB,aAAa,CAAC,OAAO,CAAC,CAAA;AACtB,eAAe,CAAC,OAAO,CAAC,CAAA;AACxB,YAAY,CAAC,OAAO,CAAC,CAAA;AACrB,aAAa,CAAC,OAAO,CAAC,CAAA;AACtB,gBAAgB,CAAC,OAAO,CAAC,CAAA;AACzB,eAAe,CAAC,OAAO,CAAC,CAAA;AACxB,gBAAgB,CAAC,OAAO,CAAC,CAAA;AAEzB,UAAU;AACV,gBAAgB,CAAC,OAAO,CAAC,CAAA;AACzB,aAAa,CAAC,OAAO,CAAC,CAAA;AAEtB,gBAAgB;AAChB,cAAc,CAAC,OAAO,CAAC,CAAA;AACvB,iBAAiB,CAAC,OAAO,CAAC,CAAA;AAE1B,MAAM,eAAe,CAAC,OAAO,CAAC,CAAA;AAE9B,OAAO,CAAC,UAAU,CAAC,OAAO,CAAC,IAAI,CAAC,CAAC,KAAK,CAAC,CAAC,KAAK,EAAE,EAAE;IAChD,OAAO,CAAC,KAAK,CAAC,KAAK,CAAC,CAAA;IACpB,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAA;AAChB,CAAC,CAAC,CAAA"}
@@ -0,0 +1,3 @@
1
+ import type { Command } from 'commander';
2
+ export declare const registerPlugins: (program: Command) => Promise<void>;
3
+ //# sourceMappingURL=registerPlugins.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"registerPlugins.d.ts","sourceRoot":"","sources":["../../../src/cli/plugins/registerPlugins.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,WAAW,CAAA;AAwFxC,eAAO,MAAM,eAAe,GAAU,SAAS,OAAO,KAAG,OAAO,CAAC,IAAI,CA8DpE,CAAA"}