@vforsh/argus 0.4.0 → 0.5.1
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/.tsbuildinfo +1 -1
- package/dist/argus.js +1141 -561
- package/dist/cli/program.d.ts +11 -1
- package/dist/cli/program.d.ts.map +1 -1
- package/dist/cli/program.js +14 -9
- package/dist/cli/program.js.map +1 -1
- package/dist/cli/register/index.d.ts.map +1 -1
- package/dist/cli/register/index.js +2 -0
- package/dist/cli/register/index.js.map +1 -1
- package/dist/cli/register/keydownCommand.d.ts.map +1 -1
- package/dist/cli/register/keydownCommand.js +2 -1
- package/dist/cli/register/keydownCommand.js.map +1 -1
- package/dist/cli/register/sessionCommands.d.ts +3 -0
- package/dist/cli/register/sessionCommands.d.ts.map +1 -0
- package/dist/cli/register/sessionCommands.js +24 -0
- package/dist/cli/register/sessionCommands.js.map +1 -0
- package/dist/output/io.d.ts +7 -0
- package/dist/output/io.d.ts.map +1 -1
- package/dist/output/io.js +21 -2
- package/dist/output/io.js.map +1 -1
- package/dist/session/runSession.d.ts +15 -0
- package/dist/session/runSession.d.ts.map +1 -0
- package/dist/session/runSession.js +184 -0
- package/dist/session/runSession.js.map +1 -0
- package/dist/session/sessionArgv.d.ts +42 -0
- package/dist/session/sessionArgv.d.ts.map +1 -0
- package/dist/session/sessionArgv.js +224 -0
- package/dist/session/sessionArgv.js.map +1 -0
- package/dist/session/sessionDispatch.d.ts +21 -0
- package/dist/session/sessionDispatch.d.ts.map +1 -0
- package/dist/session/sessionDispatch.js +137 -0
- package/dist/session/sessionDispatch.js.map +1 -0
- package/dist/session/stdioCapture.d.ts +33 -0
- package/dist/session/stdioCapture.d.ts.map +1 -0
- package/dist/session/stdioCapture.js +56 -0
- package/dist/session/stdioCapture.js.map +1 -0
- package/dist/skill/argus/SKILL.md +30 -0
- package/dist/skill/argus/reference/INSPECT.md +4 -0
- package/dist/skill/argus/reference/SESSION.md +153 -0
- package/package.json +5 -5
package/dist/cli/program.d.ts
CHANGED
|
@@ -1,3 +1,13 @@
|
|
|
1
1
|
import { Command } from 'commander';
|
|
2
|
-
export
|
|
2
|
+
export type CreateProgramOptions = {
|
|
3
|
+
/**
|
|
4
|
+
* How the program reacts to Commander's own exits (`--help`, `--version`, parse errors).
|
|
5
|
+
*
|
|
6
|
+
* `'process'` — the CLI process owns the exit code and terminates, as a one-shot run must.
|
|
7
|
+
* `'session'` — the same conditions throw a {@link CommanderError} instead, so the long-lived
|
|
8
|
+
* `argus session` transport can answer the offending request and keep serving the next one.
|
|
9
|
+
*/
|
|
10
|
+
mode?: 'process' | 'session';
|
|
11
|
+
};
|
|
12
|
+
export declare function createProgram(options?: CreateProgramOptions): Command;
|
|
3
13
|
//# sourceMappingURL=program.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"program.d.ts","sourceRoot":"","sources":["../../src/cli/program.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,OAAO,
|
|
1
|
+
{"version":3,"file":"program.d.ts","sourceRoot":"","sources":["../../src/cli/program.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,OAAO,EAAkB,MAAM,WAAW,CAAA;AAGnD,MAAM,MAAM,oBAAoB,GAAG;IAClC;;;;;;OAMG;IACH,IAAI,CAAC,EAAE,SAAS,GAAG,SAAS,CAAA;CAC5B,CAAA;AAED,wBAAgB,aAAa,CAAC,OAAO,GAAE,oBAAyB,GAAG,OAAO,CAmBzE"}
|
package/dist/cli/program.js
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
|
-
import { Command } from 'commander';
|
|
1
|
+
import { Command, CommanderError } from 'commander';
|
|
2
2
|
import packageJson from '../../package.json' with { type: 'json' };
|
|
3
|
-
export function createProgram() {
|
|
3
|
+
export function createProgram(options = {}) {
|
|
4
4
|
const program = new Command();
|
|
5
5
|
program
|
|
6
6
|
.name('argus')
|
|
@@ -15,14 +15,19 @@ export function createProgram() {
|
|
|
15
15
|
// name as a subcommand (`net --method` is a repeatable filter, `net mock add
|
|
16
16
|
// --method` is a scalar match), and without this the parent claims the value.
|
|
17
17
|
.enablePositionalOptions()
|
|
18
|
-
.exitOverride(
|
|
19
|
-
if (error.code === 'commander.helpDisplayed' || error.code === 'commander.version') {
|
|
20
|
-
process.exit(0);
|
|
21
|
-
}
|
|
22
|
-
console.error(error.message);
|
|
23
|
-
process.exit(2);
|
|
24
|
-
});
|
|
18
|
+
.exitOverride(options.mode === 'session' ? throwOnExit : exitProcess);
|
|
25
19
|
return program;
|
|
26
20
|
}
|
|
21
|
+
/** Commander requires the callback to throw; returning from it lets `process.exit` run anyway. */
|
|
22
|
+
const throwOnExit = (error) => {
|
|
23
|
+
throw error;
|
|
24
|
+
};
|
|
25
|
+
const exitProcess = (error) => {
|
|
26
|
+
if (error.code === 'commander.helpDisplayed' || error.code === 'commander.version') {
|
|
27
|
+
process.exit(0);
|
|
28
|
+
}
|
|
29
|
+
console.error(error.message);
|
|
30
|
+
process.exit(2);
|
|
31
|
+
};
|
|
27
32
|
const collectPluginOption = (value, previous) => [...previous, value];
|
|
28
33
|
//# sourceMappingURL=program.js.map
|
package/dist/cli/program.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"program.js","sourceRoot":"","sources":["../../src/cli/program.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,OAAO,EAAE,MAAM,WAAW,CAAA;
|
|
1
|
+
{"version":3,"file":"program.js","sourceRoot":"","sources":["../../src/cli/program.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,OAAO,EAAE,cAAc,EAAE,MAAM,WAAW,CAAA;AACnD,OAAO,WAAW,MAAM,oBAAoB,CAAC,OAAO,IAAI,EAAE,MAAM,EAAE,CAAA;AAalE,MAAM,UAAU,aAAa,CAAC,UAAgC,EAAE;IAC/D,MAAM,OAAO,GAAG,IAAI,OAAO,EAAE,CAAA;IAE7B,OAAO;SACL,IAAI,CAAC,OAAO,CAAC;SACb,WAAW,CAAC,qCAAqC,CAAC;SAClD,OAAO,CAAC,WAAW,CAAC,OAAO,CAAC;SAC5B,MAAM,CAAC,sBAAsB,EAAE,8CAA8C,EAAE,mBAAmB,EAAE,EAAE,CAAC;SACvG,eAAe,CAAC;QAChB,WAAW,EAAE,CAAC,GAAG,EAAE,KAAK,EAAE,EAAE,CAAC,KAAK,CAAC,GAAG,CAAC;KACvC,CAAC;SACD,wBAAwB,CAAC,IAAI,CAAC;QAC/B,mFAAmF;QACnF,6EAA6E;QAC7E,8EAA8E;SAC7E,uBAAuB,EAAE;SACzB,YAAY,CAAC,OAAO,CAAC,IAAI,KAAK,SAAS,CAAC,CAAC,CAAC,WAAW,CAAC,CAAC,CAAC,WAAW,CAAC,CAAA;IAEtE,OAAO,OAAO,CAAA;AACf,CAAC;AAED,kGAAkG;AAClG,MAAM,WAAW,GAAG,CAAC,KAAqB,EAAS,EAAE;IACpD,MAAM,KAAK,CAAA;AACZ,CAAC,CAAA;AAED,MAAM,WAAW,GAAG,CAAC,KAAqB,EAAS,EAAE;IACpD,IAAI,KAAK,CAAC,IAAI,KAAK,yBAAyB,IAAI,KAAK,CAAC,IAAI,KAAK,mBAAmB,EAAE,CAAC;QACpF,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAA;IAChB,CAAC;IACD,OAAO,CAAC,KAAK,CAAC,KAAK,CAAC,OAAO,CAAC,CAAA;IAC5B,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAA;AAChB,CAAC,CAAA;AAED,MAAM,mBAAmB,GAAG,CAAC,KAAa,EAAE,QAAkB,EAAY,EAAE,CAAC,CAAC,GAAG,QAAQ,EAAE,KAAK,CAAC,CAAA"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/cli/register/index.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,WAAW,CAAA;
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/cli/register/index.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,WAAW,CAAA;AAgCxC,MAAM,MAAM,gBAAgB,GAAG,CAAC,OAAO,EAAE,OAAO,KAAK,IAAI,CAAA;AAkCzD,eAAO,MAAM,qBAAqB,EAAE,SAAS,gBAAgB,EAAmE,CAAA"}
|
|
@@ -26,6 +26,7 @@ import { configCommands } from './configCommands.js';
|
|
|
26
26
|
import { pluginCommands } from './pluginCommands.js';
|
|
27
27
|
import { extensionCommands } from './extensionCommands.js';
|
|
28
28
|
import { skillCommands } from './skillCommands.js';
|
|
29
|
+
import { sessionCommands } from './sessionCommands.js';
|
|
29
30
|
/** All built-in CLI commands, in registration (help display) order. */
|
|
30
31
|
const coreCommandDefinitions = [
|
|
31
32
|
...quickAccessCommands,
|
|
@@ -52,6 +53,7 @@ const coreCommandDefinitions = [
|
|
|
52
53
|
...recordCommands,
|
|
53
54
|
...traceCommands,
|
|
54
55
|
...configCommands,
|
|
56
|
+
...sessionCommands,
|
|
55
57
|
...pluginCommands,
|
|
56
58
|
...skillCommands,
|
|
57
59
|
...extensionCommands,
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../../src/cli/register/index.ts"],"names":[],"mappings":"AAEA,OAAO,EAAE,cAAc,EAAE,MAAM,qBAAqB,CAAA;AACpD,OAAO,EAAE,yBAAyB,EAAE,MAAM,4BAA4B,CAAA;AACtE,OAAO,EAAE,wBAAwB,EAAE,MAAM,2BAA2B,CAAA;AACpE,OAAO,EAAE,mBAAmB,EAAE,MAAM,0BAA0B,CAAA;AAC9D,OAAO,EAAE,cAAc,EAAE,MAAM,qBAAqB,CAAA;AACpD,OAAO,EAAE,eAAe,EAAE,MAAM,sBAAsB,CAAA;AACtD,OAAO,EAAE,YAAY,EAAE,MAAM,mBAAmB,CAAA;AAChD,OAAO,EAAE,cAAc,EAAE,MAAM,qBAAqB,CAAA;AACpD,OAAO,EAAE,YAAY,EAAE,MAAM,mBAAmB,CAAA;AAChD,OAAO,EAAE,WAAW,EAAE,MAAM,kBAAkB,CAAA;AAC9C,OAAO,EAAE,YAAY,EAAE,MAAM,mBAAmB,CAAA;AAChD,OAAO,EAAE,YAAY,EAAE,MAAM,mBAAmB,CAAA;AAChD,OAAO,EAAE,cAAc,EAAE,MAAM,qBAAqB,CAAA;AACpD,OAAO,EAAE,YAAY,EAAE,MAAM,mBAAmB,CAAA;AAChD,OAAO,EAAE,WAAW,EAAE,MAAM,kBAAkB,CAAA;AAC9C,OAAO,EAAE,cAAc,EAAE,MAAM,qBAAqB,CAAA;AACpD,OAAO,EAAE,WAAW,EAAE,MAAM,kBAAkB,CAAA;AAC9C,OAAO,EAAE,YAAY,EAAE,MAAM,mBAAmB,CAAA;AAChD,OAAO,EAAE,eAAe,EAAE,MAAM,sBAAsB,CAAA;AACtD,OAAO,EAAE,eAAe,EAAE,MAAM,sBAAsB,CAAA;AACtD,OAAO,EAAE,gBAAgB,EAAE,MAAM,uBAAuB,CAAA;AACxD,OAAO,EAAE,gBAAgB,EAAE,MAAM,uBAAuB,CAAA;AACxD,OAAO,EAAE,cAAc,EAAE,MAAM,qBAAqB,CAAA;AACpD,OAAO,EAAE,aAAa,EAAE,MAAM,oBAAoB,CAAA;AAClD,OAAO,EAAE,cAAc,EAAE,MAAM,qBAAqB,CAAA;AACpD,OAAO,EAAE,cAAc,EAAE,MAAM,qBAAqB,CAAA;AACpD,OAAO,EAAE,iBAAiB,EAAE,MAAM,wBAAwB,CAAA;AAC1D,OAAO,EAAE,aAAa,EAAE,MAAM,oBAAoB,CAAA;
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../../src/cli/register/index.ts"],"names":[],"mappings":"AAEA,OAAO,EAAE,cAAc,EAAE,MAAM,qBAAqB,CAAA;AACpD,OAAO,EAAE,yBAAyB,EAAE,MAAM,4BAA4B,CAAA;AACtE,OAAO,EAAE,wBAAwB,EAAE,MAAM,2BAA2B,CAAA;AACpE,OAAO,EAAE,mBAAmB,EAAE,MAAM,0BAA0B,CAAA;AAC9D,OAAO,EAAE,cAAc,EAAE,MAAM,qBAAqB,CAAA;AACpD,OAAO,EAAE,eAAe,EAAE,MAAM,sBAAsB,CAAA;AACtD,OAAO,EAAE,YAAY,EAAE,MAAM,mBAAmB,CAAA;AAChD,OAAO,EAAE,cAAc,EAAE,MAAM,qBAAqB,CAAA;AACpD,OAAO,EAAE,YAAY,EAAE,MAAM,mBAAmB,CAAA;AAChD,OAAO,EAAE,WAAW,EAAE,MAAM,kBAAkB,CAAA;AAC9C,OAAO,EAAE,YAAY,EAAE,MAAM,mBAAmB,CAAA;AAChD,OAAO,EAAE,YAAY,EAAE,MAAM,mBAAmB,CAAA;AAChD,OAAO,EAAE,cAAc,EAAE,MAAM,qBAAqB,CAAA;AACpD,OAAO,EAAE,YAAY,EAAE,MAAM,mBAAmB,CAAA;AAChD,OAAO,EAAE,WAAW,EAAE,MAAM,kBAAkB,CAAA;AAC9C,OAAO,EAAE,cAAc,EAAE,MAAM,qBAAqB,CAAA;AACpD,OAAO,EAAE,WAAW,EAAE,MAAM,kBAAkB,CAAA;AAC9C,OAAO,EAAE,YAAY,EAAE,MAAM,mBAAmB,CAAA;AAChD,OAAO,EAAE,eAAe,EAAE,MAAM,sBAAsB,CAAA;AACtD,OAAO,EAAE,eAAe,EAAE,MAAM,sBAAsB,CAAA;AACtD,OAAO,EAAE,gBAAgB,EAAE,MAAM,uBAAuB,CAAA;AACxD,OAAO,EAAE,gBAAgB,EAAE,MAAM,uBAAuB,CAAA;AACxD,OAAO,EAAE,cAAc,EAAE,MAAM,qBAAqB,CAAA;AACpD,OAAO,EAAE,aAAa,EAAE,MAAM,oBAAoB,CAAA;AAClD,OAAO,EAAE,cAAc,EAAE,MAAM,qBAAqB,CAAA;AACpD,OAAO,EAAE,cAAc,EAAE,MAAM,qBAAqB,CAAA;AACpD,OAAO,EAAE,iBAAiB,EAAE,MAAM,wBAAwB,CAAA;AAC1D,OAAO,EAAE,aAAa,EAAE,MAAM,oBAAoB,CAAA;AAClD,OAAO,EAAE,eAAe,EAAE,MAAM,sBAAsB,CAAA;AAItD,uEAAuE;AACvE,MAAM,sBAAsB,GAAsC;IACjE,GAAG,mBAAmB;IACtB,GAAG,cAAc;IACjB,GAAG,eAAe;IAClB,GAAG,YAAY;IACf,GAAG,cAAc;IACjB,GAAG,YAAY;IACf,GAAG,WAAW;IACd,GAAG,YAAY;IACf,GAAG,YAAY;IACf,GAAG,cAAc;IACjB,GAAG,YAAY;IACf,GAAG,WAAW;IACd,yBAAyB;IACzB,wBAAwB;IACxB,cAAc;IACd,WAAW;IACX,YAAY;IACZ,eAAe;IACf,GAAG,eAAe;IAClB,GAAG,gBAAgB;IACnB,GAAG,gBAAgB;IACnB,GAAG,cAAc;IACjB,GAAG,aAAa;IAChB,GAAG,cAAc;IACjB,GAAG,eAAe;IAClB,GAAG,cAAc;IACjB,GAAG,aAAa;IAChB,GAAG,iBAAiB;CACpB,CAAA;AAED,MAAM,CAAC,MAAM,qBAAqB,GAAgC,CAAC,CAAC,OAAO,EAAE,EAAE,CAAC,cAAc,CAAC,OAAO,EAAE,sBAAsB,CAAC,CAAC,CAAA"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"keydownCommand.d.ts","sourceRoot":"","sources":["../../../src/cli/register/keydownCommand.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,sBAAsB,EAAE,MAAM,qBAAqB,CAAA;AAKjE,eAAO,MAAM,cAAc,EAAE,
|
|
1
|
+
{"version":3,"file":"keydownCommand.d.ts","sourceRoot":"","sources":["../../../src/cli/register/keydownCommand.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,sBAAsB,EAAE,MAAM,qBAAqB,CAAA;AAKjE,eAAO,MAAM,cAAc,EAAE,sBA8B5B,CAAA"}
|
|
@@ -7,7 +7,7 @@ export const keydownCommand = {
|
|
|
7
7
|
arguments: [{ flags: '[id]', description: 'Watcher id to query' }],
|
|
8
8
|
options: [
|
|
9
9
|
{ flags: '--key <name>', description: 'KeyboardEvent.key value (e.g. Enter, a, ArrowUp)' },
|
|
10
|
-
{ flags: '--code <code>', description: 'KeyboardEvent.code value (e.g. KeyG, Digit1)' },
|
|
10
|
+
{ flags: '--code <code>', description: 'KeyboardEvent.code value (e.g. KeyG, Digit1, Backquote)' },
|
|
11
11
|
{ flags: '--selector <css>', description: 'Focus element before dispatching' },
|
|
12
12
|
{ flags: '--testid <id>', description: 'Shorthand for --selector "[data-testid=\'<id>\']"' },
|
|
13
13
|
{ flags: '--modifiers <list>', description: 'Comma-separated modifiers: shift,ctrl,alt,meta' },
|
|
@@ -23,6 +23,7 @@ export const keydownCommand = {
|
|
|
23
23
|
'argus keydown app --key Enter',
|
|
24
24
|
'argus keydown app --key G',
|
|
25
25
|
'argus keydown app --code KeyG',
|
|
26
|
+
'argus keydown app --code Backquote --shift',
|
|
26
27
|
'argus keydown app --key a --selector "#input"',
|
|
27
28
|
'argus keydown app --key a --shift --ctrl',
|
|
28
29
|
],
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"keydownCommand.js","sourceRoot":"","sources":["../../../src/cli/register/keydownCommand.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,aAAa,EAAE,MAAM,8BAA8B,CAAA;AAC5D,OAAO,EAAE,aAAa,EAAE,MAAM,iCAAiC,CAAA;AAC/D,OAAO,EAAE,UAAU,EAAE,MAAM,oBAAoB,CAAA;AAE/C,MAAM,CAAC,MAAM,cAAc,GAA2B;IACrD,IAAI,EAAE,SAAS;IACf,WAAW,EAAE,iDAAiD;IAC9D,SAAS,EAAE,CAAC,EAAE,KAAK,EAAE,MAAM,EAAE,WAAW,EAAE,qBAAqB,EAAE,CAAC;IAClE,OAAO,EAAE;QACR,EAAE,KAAK,EAAE,cAAc,EAAE,WAAW,EAAE,kDAAkD,EAAE;QAC1F,EAAE,KAAK,EAAE,eAAe,EAAE,WAAW,EAAE,
|
|
1
|
+
{"version":3,"file":"keydownCommand.js","sourceRoot":"","sources":["../../../src/cli/register/keydownCommand.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,aAAa,EAAE,MAAM,8BAA8B,CAAA;AAC5D,OAAO,EAAE,aAAa,EAAE,MAAM,iCAAiC,CAAA;AAC/D,OAAO,EAAE,UAAU,EAAE,MAAM,oBAAoB,CAAA;AAE/C,MAAM,CAAC,MAAM,cAAc,GAA2B;IACrD,IAAI,EAAE,SAAS;IACf,WAAW,EAAE,iDAAiD;IAC9D,SAAS,EAAE,CAAC,EAAE,KAAK,EAAE,MAAM,EAAE,WAAW,EAAE,qBAAqB,EAAE,CAAC;IAClE,OAAO,EAAE;QACR,EAAE,KAAK,EAAE,cAAc,EAAE,WAAW,EAAE,kDAAkD,EAAE;QAC1F,EAAE,KAAK,EAAE,eAAe,EAAE,WAAW,EAAE,yDAAyD,EAAE;QAClG,EAAE,KAAK,EAAE,kBAAkB,EAAE,WAAW,EAAE,kCAAkC,EAAE;QAC9E,EAAE,KAAK,EAAE,eAAe,EAAE,WAAW,EAAE,mDAAmD,EAAE;QAC5F,EAAE,KAAK,EAAE,oBAAoB,EAAE,WAAW,EAAE,gDAAgD,EAAE;QAC9F,EAAE,KAAK,EAAE,SAAS,EAAE,WAAW,EAAE,gCAAgC,EAAE;QACnE,EAAE,KAAK,EAAE,QAAQ,EAAE,WAAW,EAAE,+BAA+B,EAAE;QACjE,EAAE,KAAK,EAAE,OAAO,EAAE,WAAW,EAAE,8BAA8B,EAAE;QAC/D,EAAE,KAAK,EAAE,QAAQ,EAAE,WAAW,EAAE,+BAA+B,EAAE;QACjE,EAAE,KAAK,EAAE,OAAO,EAAE,WAAW,EAAE,kBAAkB,EAAE;QACnD,EAAE,KAAK,EAAE,eAAe,EAAE,WAAW,EAAE,gDAAgD,EAAE;QACzF,UAAU;KACV;IACD,QAAQ,EAAE;QACT,+BAA+B;QAC/B,2BAA2B;QAC3B,+BAA+B;QAC/B,4CAA4C;QAC5C,+CAA+C;QAC/C,0CAA0C;KAC1C;IACD,MAAM,EAAE,KAAK,EAAE,EAAE,EAAE,OAAO,EAAE,EAAE;QAC7B,IAAI,CAAC,aAAa,CAAC,OAAO,CAAC;YAAE,OAAM;QACnC,MAAM,aAAa,CAAC,EAAE,EAAE,OAAO,CAAC,CAAA;IACjC,CAAC;CACD,CAAA"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"sessionCommands.d.ts","sourceRoot":"","sources":["../../../src/cli/register/sessionCommands.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,sBAAsB,EAAE,MAAM,qBAAqB,CAAA;AAIjE,eAAO,MAAM,eAAe,EAAE,SAAS,sBAAsB,EAoB5D,CAAA"}
|
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
import { runSession } from '../../session/runSession.js';
|
|
2
|
+
import { jsonOption } from './sharedOptions.js';
|
|
3
|
+
export const sessionCommands = [
|
|
4
|
+
{
|
|
5
|
+
name: 'session',
|
|
6
|
+
description: 'Serve JSONL commands over stdin/stdout against one watcher, in a single process',
|
|
7
|
+
arguments: [{ flags: '[id]', description: 'Watcher id to pin the session to' }],
|
|
8
|
+
options: [
|
|
9
|
+
{ flags: '--request-timeout <duration>', description: 'Per-request watchdog when the request omits one (default: 120s; 0 disables)' },
|
|
10
|
+
{ flags: '--reconnect', description: 'Stay alive when the watcher disappears and re-resolve it by id on the next request' },
|
|
11
|
+
{ ...jsonOption, description: 'Accepted for symmetry; the transport is always JSONL' },
|
|
12
|
+
],
|
|
13
|
+
examples: [
|
|
14
|
+
'argus session app',
|
|
15
|
+
'argus session app --request-timeout 30s',
|
|
16
|
+
'argus session app --reconnect',
|
|
17
|
+
`echo '{"id":1,"cmd":"eval","args":{"expression":"location.href"}}' | argus session app`,
|
|
18
|
+
],
|
|
19
|
+
action: async (id, options) => {
|
|
20
|
+
await runSession(id, options);
|
|
21
|
+
},
|
|
22
|
+
},
|
|
23
|
+
];
|
|
24
|
+
//# sourceMappingURL=sessionCommands.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"sessionCommands.js","sourceRoot":"","sources":["../../../src/cli/register/sessionCommands.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,UAAU,EAAE,MAAM,6BAA6B,CAAA;AACxD,OAAO,EAAE,UAAU,EAAE,MAAM,oBAAoB,CAAA;AAE/C,MAAM,CAAC,MAAM,eAAe,GAAsC;IACjE;QACC,IAAI,EAAE,SAAS;QACf,WAAW,EAAE,iFAAiF;QAC9F,SAAS,EAAE,CAAC,EAAE,KAAK,EAAE,MAAM,EAAE,WAAW,EAAE,kCAAkC,EAAE,CAAC;QAC/E,OAAO,EAAE;YACR,EAAE,KAAK,EAAE,8BAA8B,EAAE,WAAW,EAAE,6EAA6E,EAAE;YACrI,EAAE,KAAK,EAAE,aAAa,EAAE,WAAW,EAAE,oFAAoF,EAAE;YAC3H,EAAE,GAAG,UAAU,EAAE,WAAW,EAAE,sDAAsD,EAAE;SACtF;QACD,QAAQ,EAAE;YACT,mBAAmB;YACnB,yCAAyC;YACzC,+BAA+B;YAC/B,wFAAwF;SACxF;QACD,MAAM,EAAE,KAAK,EAAE,EAAE,EAAE,OAAO,EAAE,EAAE;YAC7B,MAAM,UAAU,CAAC,EAAE,EAAE,OAAO,CAAC,CAAA;QAC9B,CAAC;KACD;CACD,CAAA"}
|
package/dist/output/io.d.ts
CHANGED
|
@@ -4,6 +4,13 @@ type OutputOptions = {
|
|
|
4
4
|
import type { ArgusOutput } from '@vforsh/argus-plugin-api';
|
|
5
5
|
/** Route incidental console progress to stderr before JSON-mode plugins are loaded. */
|
|
6
6
|
export declare const configureMachineSafeConsole: (argv: readonly string[]) => void;
|
|
7
|
+
/**
|
|
8
|
+
* Send `console.log`/`info`/`debug` to stderr for the rest of the process.
|
|
9
|
+
*
|
|
10
|
+
* Callers that always speak machine output — `argus session`, whose stdout carries nothing but
|
|
11
|
+
* JSONL — need this unconditionally rather than keyed off a flag in argv.
|
|
12
|
+
*/
|
|
13
|
+
export declare const routeConsoleToStderr: () => void;
|
|
7
14
|
/**
|
|
8
15
|
* Output helpers that enforce JSON/stdout vs human/stderr rules.
|
|
9
16
|
*
|
package/dist/output/io.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"io.d.ts","sourceRoot":"","sources":["../../src/output/io.ts"],"names":[],"mappings":"AAAA,KAAK,aAAa,GAAG;IACpB,IAAI,CAAC,EAAE,OAAO,CAAA;CACd,CAAA;AAED,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,0BAA0B,CAAA;AAG3D,uFAAuF;AACvF,eAAO,MAAM,2BAA2B,GAAI,MAAM,SAAS,MAAM,EAAE,KAAG,
|
|
1
|
+
{"version":3,"file":"io.d.ts","sourceRoot":"","sources":["../../src/output/io.ts"],"names":[],"mappings":"AAAA,KAAK,aAAa,GAAG;IACpB,IAAI,CAAC,EAAE,OAAO,CAAA;CACd,CAAA;AAED,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,0BAA0B,CAAA;AAG3D,uFAAuF;AACvF,eAAO,MAAM,2BAA2B,GAAI,MAAM,SAAS,MAAM,EAAE,KAAG,IAIrE,CAAA;AAeD;;;;;GAKG;AACH,eAAO,MAAM,oBAAoB,QAAO,IAKvC,CAAA;AAED;;;;;GAKG;AACH,MAAM,MAAM,MAAM,GAAG,WAAW,CAAA;AAEhC,qEAAqE;AACrE,eAAO,MAAM,YAAY,GAAI,SAAS,aAAa,KAAG,MAoCrD,CAAA"}
|
package/dist/output/io.js
CHANGED
|
@@ -1,9 +1,28 @@
|
|
|
1
1
|
const ensureTrailingNewline = (value) => (value.endsWith('\n') ? value : `${value}\n`);
|
|
2
2
|
/** Route incidental console progress to stderr before JSON-mode plugins are loaded. */
|
|
3
3
|
export const configureMachineSafeConsole = (argv) => {
|
|
4
|
-
if (
|
|
5
|
-
|
|
4
|
+
if (argv.includes('--json') || argv.includes('--json-full') || isMachineOnlyCommand(argv)) {
|
|
5
|
+
routeConsoleToStderr();
|
|
6
6
|
}
|
|
7
|
+
};
|
|
8
|
+
/**
|
|
9
|
+
* Commands whose stdout is machine-only regardless of flags.
|
|
10
|
+
*
|
|
11
|
+
* `argus session` writes JSONL from its first byte, and plugins load — and log — before its
|
|
12
|
+
* action ever runs, so the decision cannot wait for the flag scan the rest of this uses.
|
|
13
|
+
*/
|
|
14
|
+
const MACHINE_ONLY_COMMANDS = new Set(['session']);
|
|
15
|
+
const isMachineOnlyCommand = (argv) => {
|
|
16
|
+
const command = argv.find((token, index) => !token.startsWith('-') && argv[index - 1] !== '--plugin');
|
|
17
|
+
return command != null && MACHINE_ONLY_COMMANDS.has(command);
|
|
18
|
+
};
|
|
19
|
+
/**
|
|
20
|
+
* Send `console.log`/`info`/`debug` to stderr for the rest of the process.
|
|
21
|
+
*
|
|
22
|
+
* Callers that always speak machine output — `argus session`, whose stdout carries nothing but
|
|
23
|
+
* JSONL — need this unconditionally rather than keyed off a flag in argv.
|
|
24
|
+
*/
|
|
25
|
+
export const routeConsoleToStderr = () => {
|
|
7
26
|
const writeConsoleError = console.error.bind(console);
|
|
8
27
|
console.log = writeConsoleError;
|
|
9
28
|
console.info = writeConsoleError;
|
package/dist/output/io.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"io.js","sourceRoot":"","sources":["../../src/output/io.ts"],"names":[],"mappings":"AAKA,MAAM,qBAAqB,GAAG,CAAC,KAAa,EAAU,EAAE,CAAC,CAAC,KAAK,CAAC,QAAQ,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,GAAG,KAAK,IAAI,CAAC,CAAA;AAEtG,uFAAuF;AACvF,MAAM,CAAC,MAAM,2BAA2B,GAAG,CAAC,IAAuB,EAAQ,EAAE;IAC5E,IAAI,CAAC,
|
|
1
|
+
{"version":3,"file":"io.js","sourceRoot":"","sources":["../../src/output/io.ts"],"names":[],"mappings":"AAKA,MAAM,qBAAqB,GAAG,CAAC,KAAa,EAAU,EAAE,CAAC,CAAC,KAAK,CAAC,QAAQ,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,GAAG,KAAK,IAAI,CAAC,CAAA;AAEtG,uFAAuF;AACvF,MAAM,CAAC,MAAM,2BAA2B,GAAG,CAAC,IAAuB,EAAQ,EAAE;IAC5E,IAAI,IAAI,CAAC,QAAQ,CAAC,QAAQ,CAAC,IAAI,IAAI,CAAC,QAAQ,CAAC,aAAa,CAAC,IAAI,oBAAoB,CAAC,IAAI,CAAC,EAAE,CAAC;QAC3F,oBAAoB,EAAE,CAAA;IACvB,CAAC;AACF,CAAC,CAAA;AAED;;;;;GAKG;AACH,MAAM,qBAAqB,GAAG,IAAI,GAAG,CAAC,CAAC,SAAS,CAAC,CAAC,CAAA;AAElD,MAAM,oBAAoB,GAAG,CAAC,IAAuB,EAAW,EAAE;IACjE,MAAM,OAAO,GAAG,IAAI,CAAC,IAAI,CAAC,CAAC,KAAK,EAAE,KAAK,EAAE,EAAE,CAAC,CAAC,KAAK,CAAC,UAAU,CAAC,GAAG,CAAC,IAAI,IAAI,CAAC,KAAK,GAAG,CAAC,CAAC,KAAK,UAAU,CAAC,CAAA;IACrG,OAAO,OAAO,IAAI,IAAI,IAAI,qBAAqB,CAAC,GAAG,CAAC,OAAO,CAAC,CAAA;AAC7D,CAAC,CAAA;AAED;;;;;GAKG;AACH,MAAM,CAAC,MAAM,oBAAoB,GAAG,GAAS,EAAE;IAC9C,MAAM,iBAAiB,GAAG,OAAO,CAAC,KAAK,CAAC,IAAI,CAAC,OAAO,CAAC,CAAA;IACrD,OAAO,CAAC,GAAG,GAAG,iBAAiB,CAAA;IAC/B,OAAO,CAAC,IAAI,GAAG,iBAAiB,CAAA;IAChC,OAAO,CAAC,KAAK,GAAG,iBAAiB,CAAA;AAClC,CAAC,CAAA;AAUD,qEAAqE;AACrE,MAAM,CAAC,MAAM,YAAY,GAAG,CAAC,OAAsB,EAAU,EAAE;IAC9D,MAAM,IAAI,GAAG,OAAO,CAAC,IAAI,KAAK,IAAI,CAAA;IAClC,IAAI,iBAAiB,GAAG,KAAK,CAAA;IAE7B,MAAM,aAAa,GAAG,CAAC,KAAc,EAAQ,EAAE;QAC9C,OAAO,CAAC,MAAM,CAAC,KAAK,CAAC,IAAI,CAAC,SAAS,CAAC,KAAK,CAAC,GAAG,IAAI,CAAC,CAAA;IACnD,CAAC,CAAA;IAED,MAAM,SAAS,GAAG,CAAC,KAAc,EAAQ,EAAE;QAC1C,IAAI,iBAAiB,EAAE,CAAC;YACvB,MAAM,IAAI,KAAK,CAAC,0DAA0D,CAAC,CAAA;QAC5E,CAAC;QACD,iBAAiB,GAAG,IAAI,CAAA;QACxB,aAAa,CAAC,KAAK,CAAC,CAAA;IACrB,CAAC,CAAA;IAED,MAAM,UAAU,GAAG,CAAC,IAAY,EAAQ,EAAE;QACzC,MAAM,IAAI,GAAG,qBAAqB,CAAC,IAAI,CAAC,CAAA;QACxC,IAAI,IAAI,EAAE,CAAC;YACV,OAAO,CAAC,MAAM,CAAC,KAAK,CAAC,IAAI,CAAC,CAAA;QAC3B,CAAC;aAAM,CAAC;YACP,OAAO,CAAC,MAAM,CAAC,KAAK,CAAC,IAAI,CAAC,CAAA;QAC3B,CAAC;IACF,CAAC,CAAA;IAED,MAAM,SAAS,GAAG,CAAC,IAAY,EAAQ,EAAE;QACxC,OAAO,CAAC,MAAM,CAAC,KAAK,CAAC,qBAAqB,CAAC,IAAI,CAAC,CAAC,CAAA;IAClD,CAAC,CAAA;IAED,OAAO;QACN,IAAI;QACJ,SAAS;QACT,aAAa;QACb,UAAU;QACV,SAAS;KACT,CAAA;AACF,CAAC,CAAA"}
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
export type RunSessionOptions = {
|
|
2
|
+
json?: boolean;
|
|
3
|
+
requestTimeout?: string;
|
|
4
|
+
reconnect?: boolean;
|
|
5
|
+
};
|
|
6
|
+
/**
|
|
7
|
+
* Serve JSONL commands over stdin/stdout against one watcher, in one process.
|
|
8
|
+
*
|
|
9
|
+
* A harness that drives a page through dozens of steps pays Node startup plus watcher
|
|
10
|
+
* discovery on every one-shot `argus` invocation. This keeps both: the command tree is
|
|
11
|
+
* built once, the watcher is resolved once, and each request runs the very same Commander
|
|
12
|
+
* action the one-shot CLI would have run.
|
|
13
|
+
*/
|
|
14
|
+
export declare const runSession: (id: string | undefined, options: RunSessionOptions) => Promise<void>;
|
|
15
|
+
//# sourceMappingURL=runSession.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"runSession.d.ts","sourceRoot":"","sources":["../../src/session/runSession.ts"],"names":[],"mappings":"AAeA,MAAM,MAAM,iBAAiB,GAAG;IAC/B,IAAI,CAAC,EAAE,OAAO,CAAA;IACd,cAAc,CAAC,EAAE,MAAM,CAAA;IACvB,SAAS,CAAC,EAAE,OAAO,CAAA;CACnB,CAAA;AAQD;;;;;;;GAOG;AACH,eAAO,MAAM,UAAU,GAAU,IAAI,MAAM,GAAG,SAAS,EAAE,SAAS,iBAAiB,KAAG,OAAO,CAAC,IAAI,CAkCjG,CAAA"}
|
|
@@ -0,0 +1,184 @@
|
|
|
1
|
+
import readline from 'node:readline';
|
|
2
|
+
import { SESSION_PROTOCOL_VERSION, SESSION_REQUEST_SCHEMA, formatProtocolValidationIssues, parseDurationMs } from '@vforsh/argus-core';
|
|
3
|
+
import packageJson from '../../package.json' with { type: 'json' };
|
|
4
|
+
import { createProgram } from '../cli/program.js';
|
|
5
|
+
import { coreProgramRegistrars } from '../cli/register/index.js';
|
|
6
|
+
import { registerPlugins } from '../cli/plugins/registerPlugins.js';
|
|
7
|
+
import { usageError } from '../cli/validation.js';
|
|
8
|
+
import { createOutput, routeConsoleToStderr } from '../output/io.js';
|
|
9
|
+
import { fetchWatcherJson, resolveWatcherOrExit } from '../watchers/requestWatcher.js';
|
|
10
|
+
import { resolveWatcher } from '../watchers/resolveWatcher.js';
|
|
11
|
+
import { dispatchSessionRequest } from './sessionDispatch.js';
|
|
12
|
+
import { installStdioCapture } from './stdioCapture.js';
|
|
13
|
+
/** Watchdog applied to a request that does not carry its own `timeout`. */
|
|
14
|
+
const DEFAULT_REQUEST_TIMEOUT_MS = 120_000;
|
|
15
|
+
/** How long the liveness probe waits before calling the watcher gone. */
|
|
16
|
+
const WATCHER_PROBE_TIMEOUT_MS = 1_500;
|
|
17
|
+
/**
|
|
18
|
+
* Serve JSONL commands over stdin/stdout against one watcher, in one process.
|
|
19
|
+
*
|
|
20
|
+
* A harness that drives a page through dozens of steps pays Node startup plus watcher
|
|
21
|
+
* discovery on every one-shot `argus` invocation. This keeps both: the command tree is
|
|
22
|
+
* built once, the watcher is resolved once, and each request runs the very same Commander
|
|
23
|
+
* action the one-shot CLI would have run.
|
|
24
|
+
*/
|
|
25
|
+
export const runSession = async (id, options) => {
|
|
26
|
+
// stdout carries nothing but responses, so incidental `console.log` has to move before
|
|
27
|
+
// any plugin gets a chance to write one.
|
|
28
|
+
routeConsoleToStderr();
|
|
29
|
+
const output = createOutput({ json: true });
|
|
30
|
+
const defaultTimeoutMs = resolveDefaultTimeout(options, output);
|
|
31
|
+
if (defaultTimeoutMs == null)
|
|
32
|
+
return;
|
|
33
|
+
const resolved = await resolveWatcherOrExit({ id }, output);
|
|
34
|
+
if (!resolved)
|
|
35
|
+
return;
|
|
36
|
+
const program = await buildSessionProgram();
|
|
37
|
+
const capture = installStdioCapture();
|
|
38
|
+
const writeLine = (line) => capture.writeStdout(`${JSON.stringify(line)}\n`);
|
|
39
|
+
writeLine(readyEvent(resolved.watcher));
|
|
40
|
+
const exitCode = await serveRequests({
|
|
41
|
+
program,
|
|
42
|
+
capture,
|
|
43
|
+
writeLine,
|
|
44
|
+
output,
|
|
45
|
+
watcher: resolved.watcher,
|
|
46
|
+
defaultTimeoutMs,
|
|
47
|
+
reconnect: options.reconnect === true,
|
|
48
|
+
});
|
|
49
|
+
capture.restore();
|
|
50
|
+
await flushStdout();
|
|
51
|
+
// A command abandoned by its watchdog can still hold a socket open; exit rather than
|
|
52
|
+
// wait for an event loop the session no longer controls.
|
|
53
|
+
process.exit(exitCode);
|
|
54
|
+
};
|
|
55
|
+
/**
|
|
56
|
+
* Read one request per line until stdin ends or a `quit` arrives.
|
|
57
|
+
*
|
|
58
|
+
* Requests run strictly in submission order. Pipelining is still worth it — the host can
|
|
59
|
+
* keep writing while a command is in flight — but ordering keeps `process.exitCode`, which
|
|
60
|
+
* is how ~200 commands report failure, meaningful for exactly one request at a time.
|
|
61
|
+
*/
|
|
62
|
+
const serveRequests = async (input) => {
|
|
63
|
+
const lines = readline.createInterface({ input: process.stdin, crlfDelay: Infinity });
|
|
64
|
+
try {
|
|
65
|
+
for await (const line of lines) {
|
|
66
|
+
if (line.trim() === '')
|
|
67
|
+
continue;
|
|
68
|
+
const request = parseRequestLine(line);
|
|
69
|
+
if (!request.ok) {
|
|
70
|
+
input.writeLine(request.response);
|
|
71
|
+
continue;
|
|
72
|
+
}
|
|
73
|
+
if (request.value.cmd === 'quit') {
|
|
74
|
+
input.writeLine(controlResponse(request.value.id, { closed: true }));
|
|
75
|
+
return 0;
|
|
76
|
+
}
|
|
77
|
+
if (request.value.cmd === 'ping') {
|
|
78
|
+
input.writeLine(controlResponse(request.value.id, { pong: true, watcher: input.watcher.id }));
|
|
79
|
+
continue;
|
|
80
|
+
}
|
|
81
|
+
const response = await dispatchSessionRequest({
|
|
82
|
+
program: input.program,
|
|
83
|
+
capture: input.capture,
|
|
84
|
+
request: request.value,
|
|
85
|
+
watcherId: input.watcher.id,
|
|
86
|
+
defaultTimeoutMs: input.defaultTimeoutMs,
|
|
87
|
+
});
|
|
88
|
+
input.writeLine(response);
|
|
89
|
+
if (await watcherLost(response, input)) {
|
|
90
|
+
input.output.writeWarn(`Watcher ${input.watcher.id} is no longer reachable; closing session.`);
|
|
91
|
+
return 1;
|
|
92
|
+
}
|
|
93
|
+
}
|
|
94
|
+
}
|
|
95
|
+
finally {
|
|
96
|
+
lines.close();
|
|
97
|
+
}
|
|
98
|
+
return 0;
|
|
99
|
+
};
|
|
100
|
+
/**
|
|
101
|
+
* Decide whether the session should die with the watcher.
|
|
102
|
+
*
|
|
103
|
+
* Default is fail-fast: once the watcher is gone every later request would fail anyway, and
|
|
104
|
+
* a host is better served by a dead session than by an endless stream of `ok: false`.
|
|
105
|
+
* `--reconnect` opts out — each request re-resolves the id through the registry, so a watcher
|
|
106
|
+
* restarted under the same id is picked up without restarting the session.
|
|
107
|
+
*/
|
|
108
|
+
const watcherLost = async (response, input) => {
|
|
109
|
+
if (response.ok || input.reconnect)
|
|
110
|
+
return false;
|
|
111
|
+
// A malformed request says nothing about the watcher's health.
|
|
112
|
+
if (response.error.code && FRAMING_ERROR_CODES.has(response.error.code))
|
|
113
|
+
return false;
|
|
114
|
+
return !(await watcherReachable(input.watcher.id));
|
|
115
|
+
};
|
|
116
|
+
const FRAMING_ERROR_CODES = new Set(['session_invalid_request', 'session_unknown_command', 'session_command_rejected']);
|
|
117
|
+
/** Re-resolve by id — not by the pinned record — so a watcher that moved ports still counts as alive. */
|
|
118
|
+
const watcherReachable = async (id) => {
|
|
119
|
+
const resolved = await resolveWatcher({ id });
|
|
120
|
+
if (!resolved.ok)
|
|
121
|
+
return false;
|
|
122
|
+
try {
|
|
123
|
+
await fetchWatcherJson(resolved.watcher, { path: '/status', timeoutMs: WATCHER_PROBE_TIMEOUT_MS });
|
|
124
|
+
return true;
|
|
125
|
+
}
|
|
126
|
+
catch {
|
|
127
|
+
return false;
|
|
128
|
+
}
|
|
129
|
+
};
|
|
130
|
+
/** Framing failures are answered, never thrown: one bad line must not end a replay. */
|
|
131
|
+
const parseRequestLine = (line) => {
|
|
132
|
+
let decoded;
|
|
133
|
+
try {
|
|
134
|
+
decoded = JSON.parse(line);
|
|
135
|
+
}
|
|
136
|
+
catch (error) {
|
|
137
|
+
return { ok: false, response: framingError(`Request is not valid JSON: ${error.message}`) };
|
|
138
|
+
}
|
|
139
|
+
const parsed = SESSION_REQUEST_SCHEMA.parse(decoded);
|
|
140
|
+
if (!parsed.ok) {
|
|
141
|
+
const id = decoded?.id;
|
|
142
|
+
return { ok: false, response: framingError(formatProtocolValidationIssues(parsed.issues), id) };
|
|
143
|
+
}
|
|
144
|
+
return { ok: true, value: parsed.value };
|
|
145
|
+
};
|
|
146
|
+
const framingError = (message, id) => ({
|
|
147
|
+
...idOf(id),
|
|
148
|
+
ok: false,
|
|
149
|
+
error: { message, code: 'session_invalid_request' },
|
|
150
|
+
exitCode: 2,
|
|
151
|
+
durationMs: 0,
|
|
152
|
+
});
|
|
153
|
+
/** `ping` and `quit` are answered by the session itself, without touching the command tree. */
|
|
154
|
+
const controlResponse = (id, result) => ({ ...idOf(id), ok: true, result, durationMs: 0 });
|
|
155
|
+
const idOf = (id) => (id === undefined ? {} : { id });
|
|
156
|
+
/** Build a second, session-mode command tree; the one currently mid-parse cannot re-enter itself. */
|
|
157
|
+
const buildSessionProgram = async () => {
|
|
158
|
+
const program = createProgram({ mode: 'session' });
|
|
159
|
+
for (const registerProgramPart of coreProgramRegistrars) {
|
|
160
|
+
registerProgramPart(program);
|
|
161
|
+
}
|
|
162
|
+
await registerPlugins(program);
|
|
163
|
+
return program;
|
|
164
|
+
};
|
|
165
|
+
const readyEvent = (watcher) => ({
|
|
166
|
+
type: 'ready',
|
|
167
|
+
protocolVersion: SESSION_PROTOCOL_VERSION,
|
|
168
|
+
argusVersion: packageJson.version,
|
|
169
|
+
watcher: { id: watcher.id, host: watcher.host, port: watcher.port },
|
|
170
|
+
});
|
|
171
|
+
const resolveDefaultTimeout = (options, output) => {
|
|
172
|
+
if (options.requestTimeout == null) {
|
|
173
|
+
return DEFAULT_REQUEST_TIMEOUT_MS;
|
|
174
|
+
}
|
|
175
|
+
const parsed = parseDurationMs(options.requestTimeout, 'ms');
|
|
176
|
+
if (parsed == null || parsed < 0) {
|
|
177
|
+
usageError({ json: output.json }, `Invalid --request-timeout: ${options.requestTimeout}`);
|
|
178
|
+
return null;
|
|
179
|
+
}
|
|
180
|
+
return parsed;
|
|
181
|
+
};
|
|
182
|
+
/** `process.exit` truncates in-flight pipe writes; drain the last response first. */
|
|
183
|
+
const flushStdout = () => new Promise((resolve) => process.stdout.write('', () => resolve()));
|
|
184
|
+
//# sourceMappingURL=runSession.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"runSession.js","sourceRoot":"","sources":["../../src/session/runSession.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,42 @@
|
|
|
1
|
+
import type { Command } from 'commander';
|
|
2
|
+
import type { ArgusErrorCode, SessionRequest } from '@vforsh/argus-core';
|
|
3
|
+
/** A `cmd` string resolved against the live command tree. */
|
|
4
|
+
export type ResolvedSessionCommand = {
|
|
5
|
+
ok: true;
|
|
6
|
+
command: Command;
|
|
7
|
+
/** Canonical command path (aliases resolved), e.g. `['dom', 'tree']`. */
|
|
8
|
+
path: string[];
|
|
9
|
+
};
|
|
10
|
+
/** Why a request could not be turned into an argv. */
|
|
11
|
+
export type SessionArgvFailure = {
|
|
12
|
+
ok: false;
|
|
13
|
+
code: ArgusErrorCode;
|
|
14
|
+
message: string;
|
|
15
|
+
};
|
|
16
|
+
export type SessionArgvSuccess = {
|
|
17
|
+
ok: true;
|
|
18
|
+
argv: string[];
|
|
19
|
+
resolved: ResolvedSessionCommand;
|
|
20
|
+
};
|
|
21
|
+
/**
|
|
22
|
+
* Resolve a space-separated `cmd` against the registered command tree.
|
|
23
|
+
*
|
|
24
|
+
* Aliases resolve like they do on the command line (`js` → `eval`, `ext` → `extension`),
|
|
25
|
+
* so a host can paste the command it already types.
|
|
26
|
+
*/
|
|
27
|
+
export declare const resolveSessionCommand: (program: Command, cmd: string) => ResolvedSessionCommand | SessionArgvFailure;
|
|
28
|
+
/**
|
|
29
|
+
* Turn one session request into the argv the CLI would have been spawned with.
|
|
30
|
+
*
|
|
31
|
+
* Everything is derived from the command's own Commander definition rather than a
|
|
32
|
+
* hand-kept table: option names, whether an option takes a value, which positionals exist,
|
|
33
|
+
* and whether `--json` is even declared. A command added elsewhere in the CLI — or by a
|
|
34
|
+
* plugin — becomes reachable over the session with no change here.
|
|
35
|
+
*/
|
|
36
|
+
export declare const buildSessionArgv: (input: {
|
|
37
|
+
program: Command;
|
|
38
|
+
request: SessionRequest;
|
|
39
|
+
/** Watcher the session is pinned to, injected as the leading `[id]` argument. */
|
|
40
|
+
watcherId: string;
|
|
41
|
+
}) => SessionArgvSuccess | SessionArgvFailure;
|
|
42
|
+
//# sourceMappingURL=sessionArgv.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"sessionArgv.d.ts","sourceRoot":"","sources":["../../src/session/sessionArgv.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,OAAO,EAAU,MAAM,WAAW,CAAA;AAChD,OAAO,KAAK,EAAE,cAAc,EAAE,cAAc,EAAE,MAAM,oBAAoB,CAAA;AAExE,6DAA6D;AAC7D,MAAM,MAAM,sBAAsB,GAAG;IACpC,EAAE,EAAE,IAAI,CAAA;IACR,OAAO,EAAE,OAAO,CAAA;IAChB,yEAAyE;IACzE,IAAI,EAAE,MAAM,EAAE,CAAA;CACd,CAAA;AAED,sDAAsD;AACtD,MAAM,MAAM,kBAAkB,GAAG;IAChC,EAAE,EAAE,KAAK,CAAA;IACT,IAAI,EAAE,cAAc,CAAA;IACpB,OAAO,EAAE,MAAM,CAAA;CACf,CAAA;AAED,MAAM,MAAM,kBAAkB,GAAG;IAChC,EAAE,EAAE,IAAI,CAAA;IACR,IAAI,EAAE,MAAM,EAAE,CAAA;IACd,QAAQ,EAAE,sBAAsB,CAAA;CAChC,CAAA;AAED;;;;;GAKG;AACH,eAAO,MAAM,qBAAqB,GAAI,SAAS,OAAO,EAAE,KAAK,MAAM,KAAG,sBAAsB,GAAG,kBAmB9F,CAAA;AAED;;;;;;;GAOG;AACH,eAAO,MAAM,gBAAgB,GAAI,OAAO;IACvC,OAAO,EAAE,OAAO,CAAA;IAChB,OAAO,EAAE,cAAc,CAAA;IACvB,iFAAiF;IACjF,SAAS,EAAE,MAAM,CAAA;CACjB,KAAG,kBAAkB,GAAG,kBAgCxB,CAAA"}
|