@mercury-fw/cli-engine 0.53.1 → 0.54.0

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/CHANGELOG.md CHANGED
@@ -1,5 +1,32 @@
1
1
  # @mercury-fw/cli-engine
2
2
 
3
+ ## 0.54.0
4
+
5
+ ### Minor Changes
6
+
7
+ - 5015642: The plugins' texts a person sees come out in their language, like the core's. Plugin contract version 5:
8
+
9
+ - A plugin declares its texts in English in `messages`, every key under its own name (`web-search.choice.once`); the core refuses a plugin with a key outside it (and a plugin named `core` or `app`, whose keys are the core's and the app's), and the app's language files translate them. The startup log names the missing keys of the plugins too.
10
+ - While a turn runs, a plugin gets the texts of its person as `t`: in `SessionToolContext.t`, as the second argument of a status describer (`toolStatusDescribers`, `StatusDescriber`), the third of a post-processor (`CliPostProcessor`), and in a post-turn guard, whose `statusLabel` is now `(t) => string` and whose `run` gets `t` as its third argument. `Messages`, `Params` and `Translate` are part of the contract.
11
+ - The default status line of a CLI command is the core's `core.status.command` ("Running jira issue search"), `core.status.command-bare` without a subcommand ("Running jira"), and an unreadable command's is `core.status.command-unknown`. `createCliTool` (`@mercury-fw/cli-engine`) takes the turn's `t` among its options, handed to the post-processor: a CLI plugin passes `sctx.t`; `createCliStatusDescriber`'s describer takes it as its second argument.
12
+ - The formatter hands a rule `t` as its second argument, and an `empty` text can be `(t) => string`; existing rules keep working as they are. An app's own texts go under `app.`, in its `locales/en.json`, which declares them (the startup log no longer lists them as unknown); `mfw create` writes the Jira rule's empty text as `app.jira.no-issues`.
13
+ - Web search: the two choices ("Only this time", "Always for \<host\>"), the status lines and the sources heading ("Sources") are `web-search.*` texts, English by default; a list of sources the model writes under the heading in the person's language, or the English one, is still replaced by the plugin's.
14
+
15
+ The first-party plugins released with this change are written for contract 5 and need the core released with it: an older core skips them and says why in the log. A plugin written for contract 4 isn't loaded by this core either, and the log says why: rebuild it against `PLUGIN_API_VERSION` 5 (a status describer, a guard's `statusLabel` and `run`, a post-processor take the new `t`). An app that wants the web search and status lines back in Italian adds their keys to `locales/it.json` (the log lists the missing ones at startup).
16
+
17
+ ### Patch Changes
18
+
19
+ - Updated dependencies [5015642]
20
+ - @mercury-fw/plugin-types@0.54.0
21
+ - @mercury-fw/utils@0.54.0
22
+
23
+ ## 0.53.2
24
+
25
+ ### Patch Changes
26
+
27
+ - @mercury-fw/plugin-types@0.53.2
28
+ - @mercury-fw/utils@0.53.2
29
+
3
30
  ## 0.53.1
4
31
 
5
32
  ### Patch Changes
package/README.md CHANGED
@@ -15,6 +15,6 @@ The allowlist is a JSON file the plugin ships and validates when it loads:
15
15
  }
16
16
  ```
17
17
 
18
- A command runs when its arguments start with one of the `prefix`es (`--help` always runs); `confirm: true` stages it until the user sends the token back. In `build()` the plugin validates the file with `parseCliConfig` and builds its tool with `createCliTool(runCli, configs, …)`; [`@mercury-fw/plugin-bitbucket`](https://github.com/lucabro81/mercury-fw/tree/main/packages/tools/plugin-bitbucket/index.ts) does exactly that.
18
+ A command runs when its arguments start with one of the `prefix`es (`--help` always runs); `confirm: true` stages it until the user sends the token back. In `build()` the plugin validates the file with `parseCliConfig` and builds its tool with `createCliTool(runCli, configs, …)`, passing the turn's texts it gets in its session context as `t` (`t: sctx.t`); the status describer `createCliStatusDescriber` builds takes the command and the same `t`; [`@mercury-fw/plugin-bitbucket`](https://github.com/lucabro81/mercury-fw/tree/main/packages/tools/plugin-bitbucket/index.ts) does exactly that.
19
19
 
20
20
  MIT
package/cli-status.ts CHANGED
@@ -7,23 +7,24 @@
7
7
  * override it (and for file-based CLIs, which aren't plugins). The core no
8
8
  * longer classifies read vs write itself; it only transports whatever the
9
9
  * describer returns. This is CLI-specific, so it lives with the CLI mechanism,
10
- * not in the core session layer.
10
+ * not in the core session layer. Every label is worded in the turn's
11
+ * language (`t`).
11
12
  */
12
- import { defaultStatusLabel, type StatusDescriber } from "@mercury-fw/plugin-types";
13
+ import { defaultStatusLabel, type StatusDescriber, type Translate } from "@mercury-fw/plugin-types";
13
14
  import { parseCommand } from "./command-parser.ts";
14
15
  import { matchCommand, type CliConfig } from "./cli-tool.ts";
15
16
 
16
17
  export function createCliStatusDescriber(
17
18
  configs: Record<string, CliConfig>,
18
19
  describers: Record<string, StatusDescriber>,
19
- ): (command: string) => string {
20
- return (command) => {
20
+ ): (command: string, t: Translate) => string {
21
+ return (command, t) => {
21
22
  const parsed = parseCommand(command);
22
- if (!parsed.ok) return "esecuzione di un comando";
23
+ if (!parsed.ok) return t("core.status.command-unknown");
23
24
  const config = configs[parsed.binary];
24
25
  const match = config ? matchCommand(parsed.args, config) : undefined;
25
26
  const mutating = match !== undefined && match.kind !== "not-allowed" ? match.mutating : false;
26
27
  const describe = describers[parsed.binary] ?? defaultStatusLabel;
27
- return describe({ binary: parsed.binary, args: parsed.args, mutating });
28
+ return describe({ binary: parsed.binary, args: parsed.args, mutating }, t);
28
29
  };
29
30
  }
package/cli-tool.ts CHANGED
@@ -32,7 +32,7 @@ import { cliUserId } from "@mercury-fw/utils";
32
32
  // for the core callers that import it from this module. It runs after every
33
33
  // allowed command and is told which allowlist prefix matched, so the plugin
34
34
  // decides what to touch; cli-tool.ts never knows what it does.
35
- import type { CliPostProcessor } from "@mercury-fw/plugin-types";
35
+ import type { CliPostProcessor, Translate } from "@mercury-fw/plugin-types";
36
36
  export type { CliPostProcessor };
37
37
 
38
38
  export type AllowedCommand = {
@@ -168,6 +168,8 @@ export function createCliTool(
168
168
  * allowed command's result with the matched prefix — `cli-tool.ts` itself
169
169
  * never knows what it does. */
170
170
  postProcess?: CliPostProcessor;
171
+ /** The texts of the turn's person (`SessionToolContext.t`), handed to the post-processor. */
172
+ t: Translate;
171
173
  /** Stashes a post-processor's rendered `display` artifact and returns a ref
172
174
  * the model can `present`. Pre-bound to this turn's session by the
173
175
  * composition root. Optional: with none wired the inline `display` is left
@@ -261,7 +263,7 @@ export function createCliTool(
261
263
  return opts.requireLogin();
262
264
  }
263
265
  const processed = opts.postProcess
264
- ? opts.postProcess({ binary: parsed.binary, args: parsed.args, prefix: match.prefix }, result)
266
+ ? opts.postProcess({ binary: parsed.binary, args: parsed.args, prefix: match.prefix }, result, opts.t)
265
267
  : result;
266
268
 
267
269
  // A rendered display artifact is stashed, not returned to be
@@ -7,8 +7,9 @@
7
7
  * override it (and for file-based CLIs, which aren't plugins). The core no
8
8
  * longer classifies read vs write itself; it only transports whatever the
9
9
  * describer returns. This is CLI-specific, so it lives with the CLI mechanism,
10
- * not in the core session layer.
10
+ * not in the core session layer. Every label is worded in the turn's
11
+ * language (`t`).
11
12
  */
12
- import { type StatusDescriber } from "@mercury-fw/plugin-types";
13
+ import { type StatusDescriber, type Translate } from "@mercury-fw/plugin-types";
13
14
  import { type CliConfig } from "./cli-tool.ts";
14
- export declare function createCliStatusDescriber(configs: Record<string, CliConfig>, describers: Record<string, StatusDescriber>): (command: string) => string;
15
+ export declare function createCliStatusDescriber(configs: Record<string, CliConfig>, describers: Record<string, StatusDescriber>): (command: string, t: Translate) => string;
@@ -1,6 +1,6 @@
1
1
  import { type runCli } from "./cli-executor.ts";
2
2
  import type { StageConfirmation, ExecutableTool, LoginRequired } from "@mercury-fw/plugin-types";
3
- import type { CliPostProcessor } from "@mercury-fw/plugin-types";
3
+ import type { CliPostProcessor, Translate } from "@mercury-fw/plugin-types";
4
4
  export type { CliPostProcessor };
5
5
  export type AllowedCommand = {
6
6
  prefix: string[];
@@ -97,6 +97,8 @@ export declare function createCliTool(runCliFn: typeof runCli, configs: Record<s
97
97
  * allowed command's result with the matched prefix — `cli-tool.ts` itself
98
98
  * never knows what it does. */
99
99
  postProcess?: CliPostProcessor;
100
+ /** The texts of the turn's person (`SessionToolContext.t`), handed to the post-processor. */
101
+ t: Translate;
100
102
  /** Stashes a post-processor's rendered `display` artifact and returns a ref
101
103
  * the model can `present`. Pre-bound to this turn's session by the
102
104
  * composition root. Optional: with none wired the inline `display` is left
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@mercury-fw/cli-engine",
3
- "version": "0.53.1",
3
+ "version": "0.54.0",
4
4
  "license": "MIT",
5
5
  "repository": {
6
6
  "type": "git",
@@ -23,8 +23,8 @@
23
23
  }
24
24
  },
25
25
  "dependencies": {
26
- "@mercury-fw/plugin-types": "0.53.1",
27
- "@mercury-fw/utils": "0.53.1",
26
+ "@mercury-fw/plugin-types": "0.54.0",
27
+ "@mercury-fw/utils": "0.54.0",
28
28
  "ai": "^7.0.126",
29
29
  "shell-quote": "^1.11.0",
30
30
  "zod": "^4.6.5"