@mercury-fw/cli 0.56.0 → 0.57.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 +31 -0
- package/README.md +1 -1
- package/package.json +5 -5
- package/src/render.ts +7 -1
- package/template/Dockerfile.tpl +9 -4
- package/template/bunfig.toml.tpl +2 -0
- package/template/dockerignore.tpl +2 -1
- package/template/gitignore.tpl +1 -0
package/CHANGELOG.md
CHANGED
|
@@ -1,5 +1,36 @@
|
|
|
1
1
|
# @mercury-fw/cli
|
|
2
2
|
|
|
3
|
+
## 0.57.0
|
|
4
|
+
|
|
5
|
+
### Minor Changes
|
|
6
|
+
|
|
7
|
+
- 377ce2a: `mfw create` gives the app a place for plugins of its own: `plugins/<name>`, each a package, as a workspace of the app (`"workspaces": ["plugins/*"]` in `package.json`), listed in `dependencies` as `workspace:*` and declared in `mercury.config.ts`. A `bunfig.toml` keeps Bun's hoisted `node_modules`: with a workspaces key Bun would switch to its isolated linker, whose `node_modules` is made of links. The Dockerfile copies `bunfig.toml` with `package.json`, then `plugins/` before `bun install`, so a plugin's postinstall finds its own scripts, and puts on PATH the binaries a plugin's postinstall writes to its `bin/`, as it does for the framework's packages. `.dockerignore` leaves out every `node_modules`, a plugin's own included, and the binaries a plugin's postinstall wrote on the host, which `.gitignore` keeps out of the repository too. `package.json` gets a `test` script (`bun test`), which runs the plugins' tests too.
|
|
8
|
+
|
|
9
|
+
An existing app keeps working as it is. To give it the same place:
|
|
10
|
+
|
|
11
|
+
1. In `package.json`, add `"workspaces": ["plugins/*"]` and `"test": "bun test"` under `scripts`.
|
|
12
|
+
2. Add a `bunfig.toml` next to it:
|
|
13
|
+
|
|
14
|
+
```toml
|
|
15
|
+
[install]
|
|
16
|
+
linker = "hoisted"
|
|
17
|
+
```
|
|
18
|
+
|
|
19
|
+
3. In the `Dockerfile`, change `COPY --chown=mercury:mercury package.json bun.lock* ./` to `COPY --chown=mercury:mercury package.json bun.lock* bunfig.toml ./`, add `COPY --chown=mercury:mercury plugin[s] ./plugins/` right after `COPY --chown=mercury:mercury .pack[s] ./.packs/`, and replace the line `RUN find /app/node_modules -path '*/@mercury-fw/*/bin/*' -type f -exec ln -sf {} /usr/local/bin/ \;` with:
|
|
20
|
+
|
|
21
|
+
```dockerfile
|
|
22
|
+
RUN mkdir -p /app/plugins \
|
|
23
|
+
&& find /app/node_modules/@mercury-fw /app/plugins -mindepth 3 -maxdepth 3 -path '*/bin/*' -type f -exec ln -sf {} /usr/local/bin/ \;
|
|
24
|
+
```
|
|
25
|
+
|
|
26
|
+
4. In `.dockerignore`, change `node_modules` to `**/node_modules` and add `plugins/*/bin`.
|
|
27
|
+
5. In `.gitignore`, add `plugins/*/bin`.
|
|
28
|
+
|
|
29
|
+
### Patch Changes
|
|
30
|
+
|
|
31
|
+
- @mercury-fw/core@0.57.0
|
|
32
|
+
- @mercury-fw/utils@0.57.0
|
|
33
|
+
|
|
3
34
|
## 0.56.0
|
|
4
35
|
|
|
5
36
|
### Patch Changes
|
package/README.md
CHANGED
|
@@ -51,7 +51,7 @@ Writes a new Mercury app into `<folder>`, which has to be missing or empty; the
|
|
|
51
51
|
- which channels and which tool plugins to include (none is fine: the REPL always works);
|
|
52
52
|
- the git remote for `origin`, which you can leave empty (most of the time it doesn't exist yet when you scaffold).
|
|
53
53
|
|
|
54
|
-
It writes the `mercury.config.ts` for that selection, the persona, a `locales/` folder with an `en.json` for the texts people see (empty, or the starting formatter rules' own texts: `app.jira.no-issues` with Jira), the service and REPL entrypoints, a Dockerfile, a compose file with Qdrant, and an env example listing every variable the chosen pieces read. A plugin that hands over lists comes wrapped in the formatter with a starting rule, yours to change.
|
|
54
|
+
It writes the `mercury.config.ts` for that selection, the persona, a `locales/` folder with an `en.json` for the texts people see (empty, or the starting formatter rules' own texts: `app.jira.no-issues` with Jira), the service and REPL entrypoints, a Dockerfile, a compose file with Qdrant, and an env example listing every variable the chosen pieces read. Its `package.json` declares `plugins/*` as workspaces, the place for the app's own plugins (each a package in `plugins/<name>`, which the image copies before installing), and a `test` script (`bun test`, the plugins' tests included); `bunfig.toml` keeps Bun's hoisted `node_modules`, which the workspaces would otherwise turn into links. A plugin that hands over lists comes wrapped in the formatter with a starting rule, yours to change.
|
|
55
55
|
|
|
56
56
|
Then it runs `bun install` in the app and creates a git repository on `main` with a first commit (`bun.lock` included), adding `origin` when you gave one; nothing is pushed. Each step is best effort and never undoes the ones before it: an install that fails still leaves the app committed, without the lockfile, and the closing message says what to run. The repository is skipped when the folder is already inside one (an app created in a monorepo belongs to it). Whether git can commit is git's call: when it refuses (no identity, a hook) or isn't installed, the message reports why and lists the commands to finish by hand. `bun install` prints its own output as it runs.
|
|
57
57
|
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@mercury-fw/cli",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.57.0",
|
|
4
4
|
"type": "module",
|
|
5
5
|
"license": "MIT",
|
|
6
6
|
"repository": {
|
|
@@ -41,8 +41,8 @@
|
|
|
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.57.0",
|
|
45
|
+
"@mercury-fw/utils": "0.57.0",
|
|
46
46
|
"commander": "^15.0.0"
|
|
47
47
|
},
|
|
48
48
|
"devDependencies": {
|
|
@@ -51,11 +51,11 @@
|
|
|
51
51
|
"@mercury-fw/channel-google-chat": "0.10.0",
|
|
52
52
|
"@mercury-fw/channel-http": "0.12.0",
|
|
53
53
|
"@mercury-fw/directory-static": "0.1.1",
|
|
54
|
-
"@mercury-fw/formatter": "0.
|
|
54
|
+
"@mercury-fw/formatter": "0.57.0",
|
|
55
55
|
"@mercury-fw/plugin-atlassian-admin": "0.5.0",
|
|
56
56
|
"@mercury-fw/plugin-bitbucket": "0.6.0",
|
|
57
57
|
"@mercury-fw/plugin-jira": "0.8.0",
|
|
58
|
-
"@mercury-fw/plugin-web-search": "0.
|
|
58
|
+
"@mercury-fw/plugin-web-search": "0.4.0",
|
|
59
59
|
"@mercury-fw/plugin-zitadel": "0.5.0",
|
|
60
60
|
"@mercury-fw/typescript-config": "*",
|
|
61
61
|
"@mercury-fw/web-search-searxng": "0.1.0",
|
package/src/render.ts
CHANGED
|
@@ -13,6 +13,7 @@ import { CATALOG, type CatalogEntry, type EnvVar } from "./catalog.ts";
|
|
|
13
13
|
import indexTs from "../template/src/index.ts.tpl" with { type: "text" };
|
|
14
14
|
import replTs from "../template/src/repl.ts.tpl" with { type: "text" };
|
|
15
15
|
import tsconfigJson from "../template/tsconfig.json.tpl" with { type: "text" };
|
|
16
|
+
import bunfigToml from "../template/bunfig.toml.tpl" with { type: "text" };
|
|
16
17
|
import gitignore from "../template/gitignore.tpl" with { type: "text" };
|
|
17
18
|
import dockerignore from "../template/dockerignore.tpl" with { type: "text" };
|
|
18
19
|
import dockerfile from "../template/Dockerfile.tpl" with { type: "text" };
|
|
@@ -85,6 +86,7 @@ export function renderApp(input: RenderInput): Map<string, string> {
|
|
|
85
86
|
[".gitignore", gitignore],
|
|
86
87
|
["Dockerfile", dockerfile],
|
|
87
88
|
["README.md", renderReadme(input.name, channels, auth, tools, directory)],
|
|
89
|
+
["bunfig.toml", bunfigToml],
|
|
88
90
|
["docker-compose.yml", renderCompose(input.name, channels.some((c) => c.id === "http"), services)],
|
|
89
91
|
["locales/en.json", renderEnglish(tools)],
|
|
90
92
|
["mercury.config.ts", renderConfig(assistantName, input.role, channels, auth, tools, directory)],
|
|
@@ -308,7 +310,9 @@ function renderPackageJson(
|
|
|
308
310
|
version: "0.1.0",
|
|
309
311
|
type: "module",
|
|
310
312
|
private: true,
|
|
311
|
-
|
|
313
|
+
// The app's own plugins, each a package of its own under plugins/.
|
|
314
|
+
workspaces: ["plugins/*"],
|
|
315
|
+
scripts: { start: "bun src/index.ts", repl: "bun src/repl.ts", typecheck: "tsc --noEmit", test: "bun test" },
|
|
312
316
|
dependencies,
|
|
313
317
|
// The CLI in the app itself, at the framework's version: a global `mfw`
|
|
314
318
|
// hands the app's commands over to it.
|
|
@@ -418,6 +422,8 @@ ${directory ? `- Directory: ${directory.id}\n` : ""}
|
|
|
418
422
|
- \`mercury.config.ts\`: what the app is made of (tool plugins, channels, how their lists read) and the assistant's persona: its name, who it is and how it answers. Edit them freely.
|
|
419
423
|
- \`locales/\`: the texts people see, one file per language the assistant speaks. \`en.json\` overrides the English ones; add \`it.json\` (and \`it\` to \`i18n.locales\` in the config) for Italian, \`i18n.defaultLocale\` for the language people get when they haven't picked one, \`i18n.timeZone\` (an IANA name such as \`Europe/Rome\`) for the time zone of whoever saved none and whose app says none. The app's own texts (a formatter rule's) are \`app.\` keys, written in English in \`en.json\` and translated in every other file. Mercury logs at startup the keys a file is missing.
|
|
420
424
|
- \`src/index.ts\`: the service (channels, crons). \`src/repl.ts\`: an interactive terminal for trying things out.
|
|
425
|
+
- \`plugins/\`: the app's own plugins, when it has any: each one a package in a folder of its own (\`plugins/<name>\`, a workspace), listed in \`dependencies\` as \`workspace:*\` and declared in \`mercury.config.ts\`. \`bun run test\` runs their tests.
|
|
426
|
+
- \`bunfig.toml\`: keeps Bun's hoisted \`node_modules\`, which the workspaces would otherwise turn into links the image's PATH step doesn't follow. Keep it.
|
|
421
427
|
- \`.env.example\`: every variable the app reads. Copy it to \`.env\` and fill it in.
|
|
422
428
|
|
|
423
429
|
## Running it
|
package/template/Dockerfile.tpl
CHANGED
|
@@ -13,12 +13,17 @@ WORKDIR /app
|
|
|
13
13
|
|
|
14
14
|
# Each tool plugin downloads its pinned CLI in its postinstall (allowed by
|
|
15
15
|
# package.json's trustedDependencies); the binaries go on PATH. .packs/ holds
|
|
16
|
-
# local tarballs when the app installs them (mfw local-packages),
|
|
17
|
-
#
|
|
18
|
-
|
|
16
|
+
# local tarballs when the app installs them (mfw local-packages), plugins/ the
|
|
17
|
+
# app's own plugins (workspaces, whose postinstall needs their whole folder),
|
|
18
|
+
# and each is skipped when it isn't there. bunfig.toml keeps Bun's hoisted
|
|
19
|
+
# node_modules, which the workspaces would otherwise turn into symlinks.
|
|
20
|
+
COPY --chown=mercury:mercury package.json bun.lock* bunfig.toml ./
|
|
19
21
|
COPY --chown=mercury:mercury .pack[s] ./.packs/
|
|
22
|
+
COPY --chown=mercury:mercury plugin[s] ./plugins/
|
|
20
23
|
RUN bun install --production && chown -R mercury:mercury node_modules
|
|
21
|
-
|
|
24
|
+
# plugins/ made when the app has none, or find fails on it.
|
|
25
|
+
RUN mkdir -p /app/plugins \
|
|
26
|
+
&& find /app/node_modules/@mercury-fw /app/plugins -mindepth 3 -maxdepth 3 -path '*/bin/*' -type f -exec ln -sf {} /usr/local/bin/ \;
|
|
22
27
|
|
|
23
28
|
COPY --chown=mercury:mercury mercury.config.ts ./
|
|
24
29
|
COPY --chown=mercury:mercury locales ./locales
|
package/template/gitignore.tpl
CHANGED