@mercury-fw/cli 0.43.0 → 0.44.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 +20 -0
- package/README.md +11 -0
- package/dist/src/app/commands.d.ts +3 -0
- package/package.json +5 -5
- package/src/app/commands.ts +3 -0
- package/src/program.ts +29 -0
package/CHANGELOG.md
CHANGED
|
@@ -1,5 +1,25 @@
|
|
|
1
1
|
# @mercury-fw/cli
|
|
2
2
|
|
|
3
|
+
## 0.44.0
|
|
4
|
+
|
|
5
|
+
### Minor Changes
|
|
6
|
+
|
|
7
|
+
- 2c63bbf: One person across accounts: linking them by a code.
|
|
8
|
+
|
|
9
|
+
- `POST /link` on the HTTP surface hands the caller a one-time code (`xxxx-xxxx-xxxx`, ten minutes, single use). They send it from the other account, on any channel, twice. The first time Mercury says whom the account would be linked to, the second time it links it.
|
|
10
|
+
- From then on the account is the person it's linked to: one private area, one memory, the same roles. Its earlier area stays where it was, and undoing the link gives it back.
|
|
11
|
+
- A link never touches the terminal, never chains, and is refused for an account the directory already knows as someone else.
|
|
12
|
+
- The links live on the vault's volume, out of the vault's git and out of reach of the model and the HTTP reads.
|
|
13
|
+
- `mfw identity links | link | unlink` lets the operator manage them, for instances where nobody can be shown a code.
|
|
14
|
+
- Channels get the code through the confirmation hook they already call (`ctx.confirm`), and the HTTP surface gets `ctx.linking`.
|
|
15
|
+
- Fixed: `ctx.confirm` refused someone the core doesn't admit before checking that their text was a token at all. On Google Chat, every message from an unknown sender came back as the refusal.
|
|
16
|
+
|
|
17
|
+
### Patch Changes
|
|
18
|
+
|
|
19
|
+
- Updated dependencies [2c63bbf]
|
|
20
|
+
- @mercury-fw/core@0.44.0
|
|
21
|
+
- @mercury-fw/utils@0.44.0
|
|
22
|
+
|
|
3
23
|
## 0.43.0
|
|
4
24
|
|
|
5
25
|
### Minor Changes
|
package/README.md
CHANGED
|
@@ -16,6 +16,7 @@
|
|
|
16
16
|
- [`mfw vault <command>`](#mfw-vault-command)
|
|
17
17
|
- [`mfw memory list`](#mfw-memory-list)
|
|
18
18
|
- [`mfw memory read <collection> [--limit N]`](#mfw-memory-read-collection---limit-n)
|
|
19
|
+
- [`mfw identity links`, `link`, `unlink`](#mfw-identity-links-link-unlink)
|
|
19
20
|
- [`mfw reset <memory|wiki>`](#mfw-reset-memorywiki)
|
|
20
21
|
- [`mfw credentials setup <plugin>`](#mfw-credentials-setup-plugin)
|
|
21
22
|
- [`mfw credentials check <plugin>`](#mfw-credentials-check-plugin)
|
|
@@ -174,6 +175,16 @@ mfw memory read episodic_memory
|
|
|
174
175
|
mfw memory read semantic_facts --limit 5
|
|
175
176
|
```
|
|
176
177
|
|
|
178
|
+
### `mfw identity links`, `link`, `unlink`
|
|
179
|
+
|
|
180
|
+
The links that make several accounts one person: one private area, one memory, the same roles. People link their own accounts with a code (the HTTP surface's `POST /link` gives one, they send it from the other account, twice); these are for the operator, in a one-off container, where nobody can be shown a code. Identities are written `<provider>:<id>`, as the channel or the auth provider vouches for them (`google-chat:users/123`, `oidc:3123`, `static:alice`). The running service applies a change within five minutes. Undoing a link gives the account back its own area, untouched.
|
|
181
|
+
|
|
182
|
+
```bash
|
|
183
|
+
mfw identity links
|
|
184
|
+
mfw identity link google-chat:users/123 oidc:3123
|
|
185
|
+
mfw identity unlink google-chat:users/123
|
|
186
|
+
```
|
|
187
|
+
|
|
177
188
|
### `mfw reset <memory|wiki>`
|
|
178
189
|
|
|
179
190
|
Deletes for good what the assistant remembers: `memory` is every collection on Qdrant, `wiki` the whole vault. It reads the volume's real name from the compose file, tells you which one is about to go, and asks you to type the app's name (the `name` in `package.json`); anything else, an empty answer, a `y` or closing the input included, deletes nothing and exits 1. Once confirmed it stops the service using the volume, removes its container and the volume, and starts the service again on an empty one (`docker compose stop`, `rm -f`, `docker volume rm`, `up -d`). After `memory`, a running app is restarted too (`docker compose restart mercury`), since it sets up its collections only when it starts.
|
|
@@ -21,6 +21,7 @@ export type AppDeps = {
|
|
|
21
21
|
* bin whose file isn't there yet. The core moves in lockstep with this CLI. */
|
|
22
22
|
export declare const VAULT_CLI = "node_modules/@mercury-fw/core/src/wiki/vault-cli.ts";
|
|
23
23
|
export declare const MEMORY_CLI = "node_modules/@mercury-fw/core/src/memory/memory-cli.ts";
|
|
24
|
+
export declare const IDENTITY_CLI = "node_modules/@mercury-fw/core/src/identity/links-cli.ts";
|
|
24
25
|
/** What `mfw reset` can wipe: the compose service using the volume, the
|
|
25
26
|
* volume's key in the compose file, and how to say what's lost. */
|
|
26
27
|
export declare const RESET_TARGETS: {
|
|
@@ -52,6 +53,8 @@ export declare function appCommands(app: App, deps: AppDeps): {
|
|
|
52
53
|
vault: (args: string[]) => Promise<number>;
|
|
53
54
|
/** `args` is the memory CLI's own command line (`list`, `read <collection>`, …). */
|
|
54
55
|
memory: (args: string[]) => Promise<number>;
|
|
56
|
+
/** `args` is the account links CLI's own command line (`links`, `link <identity> <owner>`, `unlink <identity>`). */
|
|
57
|
+
identity: (args: string[]) => Promise<number>;
|
|
55
58
|
/** Deletes `target`'s volume once the user types the app's name, then
|
|
56
59
|
* brings its service back up on an empty volume. The volume's real name
|
|
57
60
|
* comes from the compose file, and a wrong answer deletes nothing. */
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@mercury-fw/cli",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.44.0",
|
|
4
4
|
"type": "module",
|
|
5
5
|
"license": "MIT",
|
|
6
6
|
"repository": {
|
|
@@ -41,17 +41,17 @@
|
|
|
41
41
|
"comment:shape": "The Mercury CLI (`mfw`). `mfw create <dir>` writes a new Mercury app from the template. The framework packages move in lockstep with it, so a new app gets them at the CLI's own version; plugins and channels at the registry's latest. The plugin and channel packages are devDependencies only for the catalog test. `main(argv)` is exported for create-mercury-agent.",
|
|
42
42
|
"dependencies": {
|
|
43
43
|
"@clack/prompts": "^1.8.1",
|
|
44
|
-
"@mercury-fw/core": "0.
|
|
45
|
-
"@mercury-fw/utils": "0.
|
|
44
|
+
"@mercury-fw/core": "0.44.0",
|
|
45
|
+
"@mercury-fw/utils": "0.44.0",
|
|
46
46
|
"commander": "^15.0.0"
|
|
47
47
|
},
|
|
48
48
|
"devDependencies": {
|
|
49
49
|
"@mercury-fw/auth-oidc": "0.1.0",
|
|
50
50
|
"@mercury-fw/auth-static": "0.2.0",
|
|
51
51
|
"@mercury-fw/channel-google-chat": "0.5.0",
|
|
52
|
-
"@mercury-fw/channel-http": "0.
|
|
52
|
+
"@mercury-fw/channel-http": "0.7.0",
|
|
53
53
|
"@mercury-fw/directory-static": "0.1.0",
|
|
54
|
-
"@mercury-fw/formatter": "0.
|
|
54
|
+
"@mercury-fw/formatter": "0.44.0",
|
|
55
55
|
"@mercury-fw/plugin-atlassian-admin": "0.3.1",
|
|
56
56
|
"@mercury-fw/plugin-bitbucket": "0.3.1",
|
|
57
57
|
"@mercury-fw/plugin-jira": "0.6.1",
|
package/src/app/commands.ts
CHANGED
|
@@ -44,6 +44,7 @@ const SERVICE = "mercury";
|
|
|
44
44
|
* bin whose file isn't there yet. The core moves in lockstep with this CLI. */
|
|
45
45
|
export const VAULT_CLI = "node_modules/@mercury-fw/core/src/wiki/vault-cli.ts";
|
|
46
46
|
export const MEMORY_CLI = "node_modules/@mercury-fw/core/src/memory/memory-cli.ts";
|
|
47
|
+
export const IDENTITY_CLI = "node_modules/@mercury-fw/core/src/identity/links-cli.ts";
|
|
47
48
|
|
|
48
49
|
/** What `mfw reset` can wipe: the compose service using the volume, the
|
|
49
50
|
* volume's key in the compose file, and how to say what's lost. */
|
|
@@ -100,6 +101,8 @@ export function appCommands(app: App, deps: AppDeps) {
|
|
|
100
101
|
vault: (args: string[]) => oneOff(["bun", VAULT_CLI, ...args]),
|
|
101
102
|
/** `args` is the memory CLI's own command line (`list`, `read <collection>`, …). */
|
|
102
103
|
memory: (args: string[]) => oneOff(["bun", MEMORY_CLI, ...args]),
|
|
104
|
+
/** `args` is the account links CLI's own command line (`links`, `link <identity> <owner>`, `unlink <identity>`). */
|
|
105
|
+
identity: (args: string[]) => oneOff(["bun", IDENTITY_CLI, ...args]),
|
|
103
106
|
/** Deletes `target`'s volume once the user types the app's name, then
|
|
104
107
|
* brings its service back up on an empty volume. The volume's real name
|
|
105
108
|
* comes from the compose file, and a wrong answer deletes nothing. */
|
package/src/program.ts
CHANGED
|
@@ -218,6 +218,35 @@ Examples:
|
|
|
218
218
|
inApp((app) => app.memory(["read", collection, ...(opts.limit === undefined ? [] : ["--limit", opts.limit])]))(),
|
|
219
219
|
);
|
|
220
220
|
|
|
221
|
+
const identity = program
|
|
222
|
+
.command("identity")
|
|
223
|
+
.summary("the accounts linked to a person")
|
|
224
|
+
.description(
|
|
225
|
+
"Lists, makes and undoes the links that make several accounts one person (one private area, the same roles), in a one-off container. People link their own accounts with a code; this is for the operator, where nobody can be shown one.",
|
|
226
|
+
)
|
|
227
|
+
.helpCommand(false)
|
|
228
|
+
.addHelpText("after", INSIDE_AN_APP);
|
|
229
|
+
identity
|
|
230
|
+
.command("links")
|
|
231
|
+
.summary("the linked accounts")
|
|
232
|
+
.description("Lists every linked account and the account it belongs to.")
|
|
233
|
+
.action(async () => inApp((app) => app.identity(["links"]))());
|
|
234
|
+
identity
|
|
235
|
+
.command("link")
|
|
236
|
+
.summary("links an account to another")
|
|
237
|
+
.description(
|
|
238
|
+
"Makes <identity> the same person as <owner>, both as <provider>:<id> (e.g. google-chat:users/123, oidc:3123). The running service applies it within five minutes.",
|
|
239
|
+
)
|
|
240
|
+
.argument("<identity>", "the account to link")
|
|
241
|
+
.argument("<owner>", "the account it belongs to")
|
|
242
|
+
.action(async (account: string, owner: string) => inApp((app) => app.identity(["link", account, owner]))());
|
|
243
|
+
identity
|
|
244
|
+
.command("unlink")
|
|
245
|
+
.summary("undoes an account's link")
|
|
246
|
+
.description("Makes <identity> a person of its own again; what it had before being linked is still there.")
|
|
247
|
+
.argument("<identity>", "as mfw identity links prints it")
|
|
248
|
+
.action(async (account: string) => inApp((app) => app.identity(["unlink", account]))());
|
|
249
|
+
|
|
221
250
|
program
|
|
222
251
|
.command("reset")
|
|
223
252
|
.summary("deletes memory or the wiki, after confirmation")
|