omkit 0.4.5 → 0.4.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.
|
@@ -1,9 +1,12 @@
|
|
|
1
1
|
import type { OmkitClient } from "./types.ts";
|
|
2
|
-
export type { OmkitClient, RunSession, RunOptions, Verdict, Diagnostic, PromptRequest, RunEvents, } from "./types.ts";
|
|
2
|
+
export type { OmkitClient, RunSession, RunOptions, InspectOptions, Verdict, Diagnostic, PromptRequest, RunEvents, } from "./types.ts";
|
|
3
3
|
export type { Registry, DiscoveredOm, DiscoveredAction } from "./registry.ts";
|
|
4
|
-
|
|
4
|
+
import type { InspectOptions } from "./types.ts";
|
|
5
|
+
/** Configuration for a client — the project's `tsconfig.omkit.json` and optional debugging. */
|
|
5
6
|
export interface OmkitConfig {
|
|
6
7
|
tsconfig: string;
|
|
8
|
+
/** When set, every run this client launches forks with the Node inspector open. */
|
|
9
|
+
inspect?: InspectOptions;
|
|
7
10
|
}
|
|
8
11
|
/** Build the headless engine: discovery + supervised run + typecheck over one config. */
|
|
9
12
|
export declare function createOmkitClient(config: OmkitConfig): OmkitClient;
|
package/dist/cli/client/index.js
CHANGED
|
@@ -5,7 +5,7 @@ import { runCheck } from "./check.js";
|
|
|
5
5
|
export function createOmkitClient(config) {
|
|
6
6
|
return {
|
|
7
7
|
discover: async () => discover(config.tsconfig),
|
|
8
|
-
run: (omFile, opts) => runOm(omFile, opts),
|
|
8
|
+
run: (omFile, opts) => runOm(omFile, { ...opts, inspect: config.inspect }),
|
|
9
9
|
check: async () => runCheck(config.tsconfig),
|
|
10
10
|
};
|
|
11
11
|
}
|
|
@@ -1,4 +1,10 @@
|
|
|
1
|
-
import type { RunSession, RunOptions } from "./types.ts";
|
|
1
|
+
import type { RunSession, RunOptions, InspectOptions } from "./types.ts";
|
|
2
|
+
/**
|
|
3
|
+
* The inspector flag to prepend to a child's `execArgv` — empty when no inspector is requested.
|
|
4
|
+
* Plain `--inspect` opens the port without stopping, so the child still installs its teardown
|
|
5
|
+
* handlers and settles normally.
|
|
6
|
+
*/
|
|
7
|
+
export declare function inspectArgs(inspect: InspectOptions | undefined): string[];
|
|
2
8
|
/**
|
|
3
9
|
* Fork `omFile` as a supervised child: the `tsx` loader runs the TypeScript directly,
|
|
4
10
|
* `OMKIT_SUPERVISED=1` flips the child into channel mode (see core/interaction.ts), and its
|
|
@@ -10,6 +16,4 @@ export declare function runOm(omFile: string, opts?: RunOptions): RunSession;
|
|
|
10
16
|
* Spawn `omFile` **bare** — inherited stdio, no supervision. The child owns the terminal, so
|
|
11
17
|
* its LiveRenderer, summary, and native `readline` prompts all work. Resolves the exit code.
|
|
12
18
|
*/
|
|
13
|
-
export declare function spawnBare(omFile: string, opts?:
|
|
14
|
-
cwd?: string;
|
|
15
|
-
}): Promise<number>;
|
|
19
|
+
export declare function spawnBare(omFile: string, opts?: RunOptions): Promise<number>;
|
|
@@ -7,6 +7,16 @@ import { createChannel } from "./channel.js";
|
|
|
7
7
|
* a run in any directory still finds the loader shipped with omkit.
|
|
8
8
|
*/
|
|
9
9
|
const tsxLoader = import.meta.resolve("tsx");
|
|
10
|
+
/**
|
|
11
|
+
* The inspector flag to prepend to a child's `execArgv` — empty when no inspector is requested.
|
|
12
|
+
* Plain `--inspect` opens the port without stopping, so the child still installs its teardown
|
|
13
|
+
* handlers and settles normally.
|
|
14
|
+
*/
|
|
15
|
+
export function inspectArgs(inspect) {
|
|
16
|
+
if (!inspect)
|
|
17
|
+
return [];
|
|
18
|
+
return [`--inspect=${inspect.port}`];
|
|
19
|
+
}
|
|
10
20
|
/**
|
|
11
21
|
* Fork `omFile` as a supervised child: the `tsx` loader runs the TypeScript directly,
|
|
12
22
|
* `OMKIT_SUPERVISED=1` flips the child into channel mode (see core/interaction.ts), and its
|
|
@@ -15,7 +25,7 @@ const tsxLoader = import.meta.resolve("tsx");
|
|
|
15
25
|
*/
|
|
16
26
|
export function runOm(omFile, opts = {}) {
|
|
17
27
|
const child = fork(omFile, [], {
|
|
18
|
-
execArgv: ["--import", tsxLoader],
|
|
28
|
+
execArgv: [...inspectArgs(opts.inspect), "--import", tsxLoader],
|
|
19
29
|
cwd: opts.cwd ?? path.dirname(omFile),
|
|
20
30
|
env: { ...process.env, OMKIT_SUPERVISED: "1" },
|
|
21
31
|
stdio: ["ignore", "pipe", "pipe", "ipc"],
|
|
@@ -50,7 +60,7 @@ export function spawnBare(omFile, opts = {}) {
|
|
|
50
60
|
const env = { ...process.env };
|
|
51
61
|
delete env.OMKIT_SUPERVISED;
|
|
52
62
|
const child = fork(omFile, [], {
|
|
53
|
-
execArgv: ["--import", tsxLoader],
|
|
63
|
+
execArgv: [...inspectArgs(opts.inspect), "--import", tsxLoader],
|
|
54
64
|
cwd: opts.cwd ?? path.dirname(omFile),
|
|
55
65
|
stdio: "inherit",
|
|
56
66
|
env,
|
|
@@ -16,10 +16,17 @@ export interface Diagnostic {
|
|
|
16
16
|
readonly line: number;
|
|
17
17
|
readonly message: string;
|
|
18
18
|
}
|
|
19
|
+
/** Node inspector wiring for a run's forked child, so a debugger can attach to the om. */
|
|
20
|
+
export interface InspectOptions {
|
|
21
|
+
/** Inspector port the child listens on. */
|
|
22
|
+
readonly port: number;
|
|
23
|
+
}
|
|
19
24
|
/** Options for launching a run. */
|
|
20
25
|
export interface RunOptions {
|
|
21
26
|
/** Working directory for the child process (defaults to the om file's directory). */
|
|
22
27
|
readonly cwd?: string;
|
|
28
|
+
/** When set, fork the child with the Node inspector open so a debugger can attach. */
|
|
29
|
+
readonly inspect?: InspectOptions;
|
|
23
30
|
}
|
|
24
31
|
/** A prompt the running om is waiting on — surfaced to the frontend, answered via `answer`. */
|
|
25
32
|
export interface PromptRequest {
|
package/dist/cli/index.d.ts
CHANGED
|
@@ -1,9 +1,12 @@
|
|
|
1
1
|
#!/usr/bin/env node
|
|
2
|
+
import { type InspectOptions } from "./client/index.ts";
|
|
2
3
|
export interface Cli {
|
|
3
4
|
command: string;
|
|
4
5
|
target?: string;
|
|
5
6
|
json: boolean;
|
|
6
7
|
tsconfig: string;
|
|
8
|
+
/** The Node inspector, if requested via `--inspect[=port]`. */
|
|
9
|
+
inspect?: InspectOptions;
|
|
7
10
|
}
|
|
8
11
|
/** Parse argv (without node/script) into a command, an optional target, and flags. */
|
|
9
12
|
export declare function parseCli(argv: string[]): Cli;
|
package/dist/cli/index.js
CHANGED
|
@@ -4,10 +4,31 @@ import path from "node:path";
|
|
|
4
4
|
import { fileURLToPath } from "node:url";
|
|
5
5
|
import { realpathSync } from "node:fs";
|
|
6
6
|
import { createOmkitClient } from "./client/index.js";
|
|
7
|
+
/**
|
|
8
|
+
* Pull the Node-style inspector flag out of argv, returning the options plus the remaining args.
|
|
9
|
+
* Matches Node's own syntax: `--inspect`, `--inspect=PORT` (default port 9229); an explicit port
|
|
10
|
+
* always wins.
|
|
11
|
+
*/
|
|
12
|
+
function extractInspect(argv) {
|
|
13
|
+
let inspect;
|
|
14
|
+
const rest = [];
|
|
15
|
+
for (const arg of argv) {
|
|
16
|
+
const m = /^--inspect(?:=(\d+))?$/.exec(arg);
|
|
17
|
+
if (!m) {
|
|
18
|
+
rest.push(arg);
|
|
19
|
+
continue;
|
|
20
|
+
}
|
|
21
|
+
const port = m[1] ? Number(m[1]) : (inspect?.port ?? 9229);
|
|
22
|
+
inspect = { port };
|
|
23
|
+
}
|
|
24
|
+
return { inspect, rest };
|
|
25
|
+
}
|
|
7
26
|
/** Parse argv (without node/script) into a command, an optional target, and flags. */
|
|
8
27
|
export function parseCli(argv) {
|
|
28
|
+
// Inspector flags take an optional `=PORT`, which `parseArgs` can't express — pull them first.
|
|
29
|
+
const { inspect, rest } = extractInspect(argv);
|
|
9
30
|
const { values, positionals } = parseArgs({
|
|
10
|
-
args:
|
|
31
|
+
args: rest,
|
|
11
32
|
options: {
|
|
12
33
|
json: { type: "boolean", default: false },
|
|
13
34
|
tsconfig: { type: "string", default: "tsconfig.omkit.json" },
|
|
@@ -19,12 +40,24 @@ export function parseCli(argv) {
|
|
|
19
40
|
target: positionals[1],
|
|
20
41
|
json: Boolean(values.json),
|
|
21
42
|
tsconfig: values.tsconfig,
|
|
43
|
+
inspect,
|
|
22
44
|
};
|
|
23
45
|
}
|
|
46
|
+
/**
|
|
47
|
+
* Tell the user where the inspector will be. The om runs in a forked child, so the inspector is on
|
|
48
|
+
* that child — never on this omkit process. In the interactive picker the child (and the port) only
|
|
49
|
+
* exists once an om is chosen; a bare run forks it immediately.
|
|
50
|
+
*/
|
|
51
|
+
function announceInspect(inspect, interactive) {
|
|
52
|
+
const p = inspect.port;
|
|
53
|
+
const run = interactive ? "the om you pick runs" : "the om runs";
|
|
54
|
+
console.log(`omkit: ${run} in a forked child with the inspector on :${p} — attach a debugger to that child, not to omkit itself (--inspect).`);
|
|
55
|
+
}
|
|
24
56
|
/** The bin entry: route to a lazily-imported command; owns stdout and the exit code. */
|
|
25
57
|
async function main() {
|
|
26
58
|
const cli = parseCli(process.argv.slice(2));
|
|
27
|
-
const
|
|
59
|
+
const inspect = cli.inspect;
|
|
60
|
+
const client = createOmkitClient({ tsconfig: cli.tsconfig, inspect });
|
|
28
61
|
if (cli.command === "init") {
|
|
29
62
|
const { scaffold } = await import("./commands/init.js");
|
|
30
63
|
const { created, skipped } = scaffold(process.cwd());
|
|
@@ -55,6 +88,10 @@ async function main() {
|
|
|
55
88
|
// No target → open the interactive picker (browse/search oms, run one with live output).
|
|
56
89
|
// A bare `omkit` lands here too, since `run` is the default command.
|
|
57
90
|
if (!cli.target) {
|
|
91
|
+
// Announce before Ink takes the terminal, so the notice isn't swallowed by the live UI —
|
|
92
|
+
// the supervised child's own inspector banner goes to a piped stream nobody sees.
|
|
93
|
+
if (inspect)
|
|
94
|
+
announceInspect(inspect, true);
|
|
58
95
|
const { launchUi } = await import("./commands/ui.js");
|
|
59
96
|
await launchUi(client, cli.tsconfig);
|
|
60
97
|
return;
|
|
@@ -75,8 +112,10 @@ async function main() {
|
|
|
75
112
|
process.exitCode = 1;
|
|
76
113
|
return;
|
|
77
114
|
}
|
|
115
|
+
if (inspect)
|
|
116
|
+
announceInspect(inspect, false);
|
|
78
117
|
process.on("SIGINT", () => { }); // let the child tear down; don't die first
|
|
79
|
-
process.exitCode = await spawnBare(omFile, { cwd: path.dirname(omFile) });
|
|
118
|
+
process.exitCode = await spawnBare(omFile, { cwd: path.dirname(omFile), inspect });
|
|
80
119
|
return;
|
|
81
120
|
}
|
|
82
121
|
console.error(`unknown command "${cli.command}"`);
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "omkit",
|
|
3
|
-
"version": "0.4.
|
|
3
|
+
"version": "0.4.6",
|
|
4
4
|
"description": "A tiny runtime for developer workflows: typed actions that pass runtime capabilities and emit typed events, under one run and one shared log. The operational/runtime layer to tskb's knowledge layer.",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"main": "./dist/index.js",
|