@jc_stack/ez-agents 0.1.0-beta.12

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.
Files changed (147) hide show
  1. package/.dockerignore +24 -0
  2. package/.env.example +26 -0
  3. package/AGENTS.md +84 -0
  4. package/CHANGELOG.md +39 -0
  5. package/CONTRIBUTING.md +73 -0
  6. package/Dockerfile +16 -0
  7. package/LICENSE +21 -0
  8. package/README.md +134 -0
  9. package/SECURITY.md +26 -0
  10. package/THIRD_PARTY_NOTICES.md +14 -0
  11. package/bin/ezenciel-agents +2 -0
  12. package/bin/ezenciel-agents-ai +2 -0
  13. package/bin/ezenciel-agents-ai.mjs +5 -0
  14. package/bin/ezenciel-agents-approval +2 -0
  15. package/bin/ezenciel-agents-approval.mjs +16 -0
  16. package/bin/ezenciel-agents-create +12 -0
  17. package/bin/ezenciel-agents-docker +6 -0
  18. package/bin/ezenciel-agents-host +5 -0
  19. package/bin/ezenciel-agents-install +2 -0
  20. package/bin/ezenciel-agents-message +2 -0
  21. package/bin/ezenciel-agents-message.mjs +16 -0
  22. package/bin/ezenciel-agents-owner +2 -0
  23. package/bin/ezenciel-agents-owner.mjs +18 -0
  24. package/bin/ezenciel-agents-react +2 -0
  25. package/bin/ezenciel-agents-react.mjs +16 -0
  26. package/bin/ezenciel-agents-setup.mjs +18 -0
  27. package/bin/ezenciel-agents-source +2 -0
  28. package/bin/ezenciel-agents-source.mjs +16 -0
  29. package/bin/ezenciel-agents-tools.mjs +3 -0
  30. package/bin/ezenciel-agents.mjs +37 -0
  31. package/compose.whatsapp.yaml +12 -0
  32. package/compose.yaml +40 -0
  33. package/default-plugins.json +1 -0
  34. package/docker/entrypoint.sh +15 -0
  35. package/docker/healthcheck.mjs +8 -0
  36. package/docker/plugin-smoke.mjs +48 -0
  37. package/docker/pnpm-lock.yaml +415 -0
  38. package/docker/recovery.ts +11 -0
  39. package/docker/run.ts +52 -0
  40. package/docker/smoke.mjs +47 -0
  41. package/docker/status-smoke.mjs +30 -0
  42. package/docker/upgrade-smoke.mjs +58 -0
  43. package/docs/architecture/ai-selection.md +37 -0
  44. package/docs/architecture/authority-boundaries.md +14 -0
  45. package/docs/architecture/event-sources.md +34 -0
  46. package/docs/architecture/telegram-intake.md +29 -0
  47. package/docs/development-and-testing.md +18 -0
  48. package/docs/docker-runtime.md +118 -0
  49. package/docs/host-service.md +80 -0
  50. package/docs/plugin-contributions.md +34 -0
  51. package/docs/plugins.md +181 -0
  52. package/docs/releasing.md +71 -0
  53. package/docs/setup.md +234 -0
  54. package/docs/upgrades.md +193 -0
  55. package/package.json +106 -0
  56. package/scripts/assert-local-registry.mjs +22 -0
  57. package/scripts/release-check.mjs +14 -0
  58. package/scripts/smoke.ts +102 -0
  59. package/src/agent-install.ts +96 -0
  60. package/src/ai-cli.ts +22 -0
  61. package/src/ai.ts +88 -0
  62. package/src/approval-cli.ts +59 -0
  63. package/src/approval.ts +119 -0
  64. package/src/audio.ts +184 -0
  65. package/src/client-defaults.ts +101 -0
  66. package/src/config.ts +48 -0
  67. package/src/control-state.ts +350 -0
  68. package/src/desktop-bridge.ts +284 -0
  69. package/src/event-sources.ts +112 -0
  70. package/src/executor.ts +335 -0
  71. package/src/files.ts +75 -0
  72. package/src/format.ts +57 -0
  73. package/src/host-executor-client.ts +46 -0
  74. package/src/host-executor-protocol.ts +2 -0
  75. package/src/host-executor.ts +129 -0
  76. package/src/identity.ts +17 -0
  77. package/src/inbox.ts +171 -0
  78. package/src/index.ts +812 -0
  79. package/src/install-config.ts +56 -0
  80. package/src/install-tools.mjs +98 -0
  81. package/src/menu.ts +123 -0
  82. package/src/message-send.ts +57 -0
  83. package/src/message.ts +68 -0
  84. package/src/owner-args.ts +4 -0
  85. package/src/owner.ts +30 -0
  86. package/src/plugins/manager.mjs +272 -0
  87. package/src/react.ts +33 -0
  88. package/src/reaction.ts +32 -0
  89. package/src/read-request.ts +72 -0
  90. package/src/reply.ts +13 -0
  91. package/src/runs.ts +445 -0
  92. package/src/service.ts +28 -0
  93. package/src/setup.ts +180 -0
  94. package/src/software-status.ts +23 -0
  95. package/src/source-cli.ts +18 -0
  96. package/src/update-attention.ts +18 -0
  97. package/src/updates/artifact.mjs +83 -0
  98. package/src/updates/binding.mjs +27 -0
  99. package/src/updates/control.mjs +131 -0
  100. package/src/updates/launch.mjs +13 -0
  101. package/src/updates/runtime.mjs +140 -0
  102. package/src/updates/status.mjs +49 -0
  103. package/src/updates/supervisor.mjs +102 -0
  104. package/src/version.ts +4 -0
  105. package/src/workspace.ts +32 -0
  106. package/templates/agent/AGENTS.md +49 -0
  107. package/templates/agent/SOUL.md +11 -0
  108. package/templates/agent/TOOLS.md +46 -0
  109. package/templates/agent/USER.md +5 -0
  110. package/templates/updates.md +45 -0
  111. package/test/agent-install.test.ts +48 -0
  112. package/test/ai-cli.test.ts +28 -0
  113. package/test/ai.test.ts +105 -0
  114. package/test/approval.test.ts +40 -0
  115. package/test/audio.test.ts +77 -0
  116. package/test/client-defaults.test.ts +64 -0
  117. package/test/codex-context.test.ts +33 -0
  118. package/test/config.test.ts +32 -0
  119. package/test/control-state.test.ts +58 -0
  120. package/test/desktop-bridge.test.ts +159 -0
  121. package/test/docker-runtime.test.ts +23 -0
  122. package/test/event-sources.test.ts +113 -0
  123. package/test/executor.test.ts +135 -0
  124. package/test/files.test.ts +50 -0
  125. package/test/format.test.ts +41 -0
  126. package/test/host-executor.test.ts +149 -0
  127. package/test/inbox-burst.test.ts +66 -0
  128. package/test/inbox.test.ts +102 -0
  129. package/test/install-config.test.ts +75 -0
  130. package/test/install-tools.test.mjs +59 -0
  131. package/test/intake-relay.test.ts +337 -0
  132. package/test/owner-help.test.mjs +10 -0
  133. package/test/plugin-manager.test.mjs +157 -0
  134. package/test/publish-guard.test.ts +21 -0
  135. package/test/reaction.test.ts +122 -0
  136. package/test/read-request.test.ts +134 -0
  137. package/test/relay.test.ts +254 -0
  138. package/test/release-entrypoints.test.mjs +26 -0
  139. package/test/runs.test.ts +116 -0
  140. package/test/security.test.ts +85 -0
  141. package/test/setup.test.ts +68 -0
  142. package/test/software-status.test.ts +31 -0
  143. package/test/update-attention.test.ts +21 -0
  144. package/test/updates.test.mjs +282 -0
  145. package/test/upgrade-pause.test.ts +70 -0
  146. package/test/workspace.test.ts +80 -0
  147. package/tsconfig.json +19 -0
@@ -0,0 +1,181 @@
1
+ # Native plugin manager
2
+
3
+ Built-in host-side CLI registry and Docker lifecycle manager in the main Ez package. Native Node 22+
4
+ only; no relay imports, provider libraries, model loops or global `ez` install.
5
+ The existing host executor uses an agent-bound launcher. This is the narrow host
6
+ administrative tool, not another executable provider plugin or Docker daemon.
7
+
8
+ ## Initial agent installation
9
+
10
+ The installing agent provisions this once. Use explicit absolute paths:
11
+
12
+ ```sh
13
+ node /absolute/ezenciel_agents/bin/ezenciel-agents-tools.mjs init \
14
+ --home /private/agent/tools --workspace /private/agent/mind \
15
+ --host-config /private/agent/host-executor.json
16
+ ```
17
+
18
+ Without `--catalog`, init loads an empty packaged catalog. Keep it empty for
19
+ initial main onboarding; no sibling repository, broker or provider account is
20
+ needed. Finish owner pairing and verify an actual Telegram agent reply first.
21
+ Init creates a private registry and `tools/bin/ez`, adds a
22
+ TOOLS.md discovery entry, and binds the matching host executor to that bin
23
+ folder. Native binaries are linked through; an existing `ez` collision fails.
24
+ Run before starting the host executor. For an already running installation,
25
+ place a symlink to the returned launcher in that agent's existing private bin
26
+ directory and set that binding's `toolsHome` to the absolute registry directory.
27
+ Restart the host executor between jobs so it loads the binding. Init with
28
+ `--host-config` sets `toolsHome` automatically. Never overwrite global ez.
29
+
30
+ The host validates that `toolsHome` belongs to the bound workspace. For Codex,
31
+ it adds that registry to writable roots and enables network access for Docker.
32
+ Docker Buildx metadata uses `toolsHome/buildx` through `BUILDX_CONFIG`, so builds
33
+ do not need write access to the host's shared Docker configuration.
34
+ The GUI adapter also sets `sandboxPolicy.networkAccess` when `toolsHome` is
35
+ bound, on both new and resumed turns; omitting it blocks Docker socket access.
36
+ Verify status and a harmless plugin command inside the actual executor turn.
37
+ Host-shell success alone does not establish worker access.
38
+ Job requests cannot override this host binding. Filesystem access remains
39
+ `workspace-write`; other agents' directories are not added. Docker access is
40
+ host administration under the existing trusted-host model, not OS isolation.
41
+
42
+ ## Installation completion contract
43
+
44
+ For initial Ez onboarding, plugin requests happen in the working Telegram
45
+ conversation after the main owner exchange is verified. The original host CLI
46
+ must not perform plugin setup instead. The installed agent inspects the supplied
47
+ tarball/checksum, extracts it inside its writable tools directory, and uses
48
+ `ez plugins inspect <id> --source <path>` and `catalog-add` with the returned hash.
49
+ It then handles install/start and QR onboarding in that same conversation. A
50
+ plugin tarball supplied with the main artifact is deferred input, not permission
51
+ to skip the main-first handoff.
52
+
53
+ When the user says install or set up a plugin, the agent owns completion through
54
+ usable capability, unless the user explicitly requests package files only.
55
+ Inspect the package, read its skill, install, start, complete provider onboarding,
56
+ and verify the intended identity and a real supported operation. Reuse existing
57
+ working connections. Registration, container health and setup artifacts alone
58
+ are not completion. Low-level install/start/connect commands remain separate;
59
+ the agent invokes them within the original request without repeated permission.
60
+
61
+ Use the agent's known identity and authorized context. Choose routine technical
62
+ labels, generate credentials into plugin-owned private storage, and select
63
+ permissions appropriate to the requested capability. Ask only for genuinely
64
+ missing inputs or actions requiring the human or external provider, such as a QR
65
+ scan, OAuth consent, verification code, or access to an existing account. Do all
66
+ technical setup yourself, including administrative setup for the owner. When an
67
+ API key is required, ask the owner to provide it with the exact provider link and
68
+ location; handle storage privately and never echo it. Do not assume a separate
69
+ administrator exists or hand the owner internal configuration terminology. Do all
70
+ independent preparation first. Deliver the actual image or exact authorization
71
+ link privately with one concrete action; never hand the user CLI setup chores.
72
+ Keep setup pending, resume after that step, and verify the provider result.
73
+ Reuse the original installation authority; do not invent identity or expand it
74
+ to purchases, unrelated accounts, outbound messages or destructive changes.
75
+
76
+ Each plugin skill must explain required inputs, which can come from agent
77
+ context or be generated, private credential handling, external handoffs,
78
+ resumption/recovery and evidence of readiness. Record non-secret connection
79
+ and maintenance details for future turns. The generic manager remains plumbing;
80
+ provider setup decisions and conversation belong to the agent.
81
+
82
+ ## From the agent conversation
83
+
84
+ ```sh
85
+ ez plugins available
86
+ ez plugins inspect whatsapp
87
+ ez plugins install whatsapp
88
+ ez plugins start whatsapp
89
+ ez tools list
90
+ ez whatsapp doctor --json
91
+ ```
92
+
93
+ The agent reads the installed WhatsApp skill and guides its QR onboarding. Fetch
94
+ the declared QR into the bound workspace with:
95
+
96
+ ```sh
97
+ ez plugins export whatsapp qr --output /private/agent/mind/work/pairing.png
98
+ ```
99
+
100
+ The output file must not exist and its parent must already exist. Deliver it
101
+ through the agent's existing messaging tool, then delete that temporary private
102
+ image. Never publish the profile. `doctor` must confirm the intended identity.
103
+ The manager does not send messages, link accounts, or implement onboarding flows.
104
+
105
+ Other commands: `plugins list`, `status <id>`, `logs <id>` (last 100 lines),
106
+ `stop <id>`, `uninstall <id>`. Uninstall stops/removes only that Compose deployment
107
+ and unregisters its aliases; it retains named data volumes and reviewed source
108
+ snapshots. Reinstallation reuses that data. Plain install does not replace a different release. Use `ez updates` for
109
+ compatible upgrades under saved policy; see [upgrades](upgrades.md). Manual
110
+ uninstall/reinstall remains available but does not promise schema rollback.
111
+
112
+ For another reviewed local package, inspect with `plugins inspect <id> --source
113
+ /absolute/source`, then install with that source and the returned `--revision
114
+ sha256:...`. Changed contents fail. To make a reviewed package discoverable without installing,
115
+ use `ez plugins catalog-add <id> --source /absolute/source --revision sha256:...`.
116
+ Inspection is read-only: its returned revision does not replace the saved catalog
117
+ pin. After reviewing changed source, pass the returned `--source` and `--revision`
118
+ to `catalog-add` to update that entry, then install. Alternatively, pass them
119
+ directly to install for that invocation. Do not retry a plain install against a
120
+ stale catalog pin. A mismatch after passing the inspected revision means the
121
+ source changed again; finish edits and inspect the stable source before pinning.
122
+ Catalog updates preserve other entries. No remote package marketplace or arbitrary
123
+ package-manager proxy is implemented.
124
+
125
+ Installation snapshots only `package.json.files` plus required manifests and
126
+ Docker inputs, validates the descriptor, builds/pulls, then atomically registers.
127
+ It does not start services. Repeated installs report existing state; interrupted
128
+ builds can reuse a matching snapshot. Unknown fields, symlinks, reserved aliases
129
+ and duplicate aliases fail. An interrupted manager leaves `registry.lock` with
130
+ its PID: verify that process is gone before explicitly removing that one lock.
131
+ Never remove an active lock or delete provider data to repair installation.
132
+
133
+ ## Deployment descriptors
134
+
135
+ `ez-plugin.json` retains its v1 executable/args/skills contract.
136
+ `ez-deployment.json` is a separate strict descriptor:
137
+
138
+ - `schemaVersion: 1`.
139
+ - `services`: named services, each with exactly one `buildTarget` (from the
140
+ snapshotted Dockerfile) or digest-pinned `image`; a nonempty `healthcheck` argv;
141
+ optional literal `command`, `volumes` mapping named private volumes to container
142
+ paths, and `workspace: true` for the owning mind mounted read-only.
143
+ - `commands`: the same aliases as the plugin manifest; each names its `service`,
144
+ executable `argv` and optional literal `suffix`. Dispatch is argv + manifest
145
+ args + user args + suffix. No parsing or provider parameter translation.
146
+ - Optional `exports`: named artifacts with an exact service and file path.
147
+ Review these paths: declaring a secret as an export would expose it.
148
+
149
+ V1 remains supported. V2 adds declared generated `secrets`, service `environment`
150
+ (literal strings or declared secret references with literal prefix/suffix),
151
+ `dependsOn` health dependencies, non-root `user` and bounded `memoryMiB`.
152
+ Cycles, unknown dependencies and host environment interpolation are rejected.
153
+ Secrets persist privately across reinstall and are never included in registry
154
+ responses. Twenty provides a complete v2 backend example.
155
+
156
+ Compose JSON is generated, not accepted from untrusted arbitrary Compose input.
157
+ No ports, host network, privileged services, host env inheritance, arbitrary bind mounts,
158
+ Docker socket or raw Compose args can be supplied. Project names include a hash
159
+ of the canonical registry path; networks and volumes inherit that namespace.
160
+ Images use release-specific names. All containers drop capabilities and run as
161
+ UID 1000 by default; v2 can declare another non-root UID:GID. Plugins sharing a profile remain in the same owning deployment.
162
+
163
+ Commands run in one-shot client containers against their own service's volumes;
164
+ stdin, stdout, stderr, literal arguments and exit codes are preserved. SIGINT/
165
+ SIGTERM cancel the Docker call and remove its unique client container. The manager
166
+ never retries a provider operation. Service startup/restart is explicit; commands
167
+ never implicitly start a stopped provider service. Plugin data does not enter the
168
+ relay. The manager sends only a whitelist of Docker client environment variables.
169
+
170
+ ## Verification
171
+
172
+ `npm run verify` runs offline negative/contract tests. Explicit Docker integration:
173
+ `node docker/plugin-smoke.mjs`. It builds the actual WhatsApp package with the
174
+ synthetic transport in an isolated snapshot and tests installation, start,
175
+ registered CLI, literal file paths, idempotency, restart persistence and
176
+ non-destructive uninstall. No live account or recipient is used.
177
+
178
+ ## Agent-owned upgrades
179
+
180
+ This beta includes owner-policy release checks and durable
181
+ main/plugin replacement. See [upgrade setup, tools and recovery](upgrades.md). Earlier main upgrade/rollback VM QA passed; final-release fresh-host/reboot and live plugin upgrade acceptance remain pending.
@@ -0,0 +1,71 @@
1
+ # Releasing
2
+
3
+ Use the same checks for maintainer and external changes. Each repository versions
4
+ independently with SemVer: patch for compatible fixes, minor for new capabilities;
5
+ before 1.0, breaking CLI/state changes require a minor bump and migration notes.
6
+ No automatic dependency updates, release bot or credentials in pull-request CI.
7
+
8
+ 1. In an isolated release worktree/PR, finalize package version and CHANGELOG.md;
9
+ update plugin manifest version when present. After lockfile changes, copy
10
+ `pnpm-lock.yaml` to `docker/pnpm-lock.yaml` (npm omits the root lockfile; CI
11
+ checks this shipping copy is identical). Never overwrite a published version.
12
+ 2. Run `pnpm install --frozen-lockfile`, `pnpm verify`, `npm run release:check`,
13
+ `git diff --check`. Review `npm audit --omit=dev` and dependency licenses.
14
+ Record accepted risks with a reason; never run an unreviewed audit fix.
15
+ 3. Build both Docker targets from a clean checkout:
16
+ `docker build --target test -t ez-release-tests .` and
17
+ `docker build --target runtime -t ez-release-runtime .`.
18
+ Main: `EZ_RELAY_IMAGE=ez-release-runtime node docker/smoke.mjs`.
19
+ WhatsApp: `EZ_WHATSAPP_IMAGE=ez-release-runtime node docker/smoke.mjs`.
20
+ 4. Create an artifact with `npm pack --ignore-scripts`. Inspect its file list,
21
+ hash it, extract into a fresh directory, copy `docker/pnpm-lock.yaml` to
22
+ `pnpm-lock.yaml`, and run `pnpm install --frozen-lockfile`.
23
+ Repeat CLI help and runtime build there. GitHub publication includes the Git
24
+ tree/history; npm's files list does not sanitize Git history. Review both.
25
+ 5. For initial release or onboarding changes, install the exact candidate on a
26
+ disposable clean host. Follow setup without sibling checkouts or personal
27
+ state. Verify owner pairing, real reply, service restart/boot and the first
28
+ plugin through the actual executor. A fixture proves plumbing only. Use an
29
+ authorized test account, record receipts privately, publish only a sanitized
30
+ result. Document any unsupported platform/executor explicitly.
31
+ 6. Confirm repository owner/URLs, package-name availability and publisher access;
32
+ fill package.json repository, homepage and bugs with the actual public URLs.
33
+ Enable GitHub private vulnerability reporting; verify the route. Protect main
34
+ with CI and independent PR review. Maintainers use the same process.
35
+ 7. Record independent review and green CI for the final release PR, then obtain
36
+ maintainer merge/release authorization for the exact commit, tarball SHA-256,
37
+ license/third-party obligations and known limits. Merge the release PR and
38
+ verify its tree matches the reviewed source before tagging `v<version>` and
39
+ publishing that tarball:
40
+ `npm publish /absolute/candidate.tgz --access public --tag beta --registry https://registry.npmjs.org/`
41
+ for prereleases (use `--tag latest` only for an approved stable release).
42
+ Use interactive npm authentication with 2FA; never paste tokens into CI or docs.
43
+ 8. Create the GitHub release from CHANGELOG.md, attach artifact/checksum, and
44
+ install the registry version on a clean host. Verify metadata and the same
45
+ onboarding path before posting launch copy. Stop rollout on failure; publish
46
+ a new patch or deprecate the bad version, never silently replace an artifact.
47
+
48
+ Container images are built locally in this initial release. Public image
49
+ publication is a separate decision and requires the corresponding source and
50
+ third-party notices. Back up private state before upgrades. Uninstall is not
51
+ credential revocation; do not delete volumes as a routine rollback.
52
+
53
+ ## Beta channel
54
+
55
+ Use SemVer prereleases (`0.1.0-beta.1`), GitHub's prerelease flag and npm's
56
+ `--tag beta`; never mark a beta latest/stable. For this first beta the maintainer
57
+ explicitly deferred real account/reboot acceptance. Keep that limitation in the
58
+ README and release notes. Source/tarball publication is permitted after the
59
+ automated gates; deferred live checks remain required for stable release.
60
+ GitHub repositories use `jdorado`; npm packages use `jc_stack`. Verify
61
+ `npm whoami --registry https://registry.npmjs.org/` returns `jc_stack` before
62
+ publishing. Never infer npm scope ownership from a GitHub login. After publishing,
63
+ read back `npm view @jc_stack/ez-agents@0.1.0-beta.12 name version dist-tags --json`
64
+ (using the release being published), download it with `npm pack`, and verify its
65
+ contents/checksum against the reviewed artifact. Keep the npm artifact and
66
+ GitHub tag on the same reviewed commit. Do not create a new token to bypass 2FA.
67
+
68
+ ## Agent-owned upgrades
69
+
70
+ This beta includes owner-policy release checks and durable
71
+ main/plugin replacement. See [upgrade setup, tools and recovery](upgrades.md). Earlier main upgrade/rollback VM QA passed; final-release fresh-host/reboot and live plugin upgrade acceptance remain pending.
package/docs/setup.md ADDED
@@ -0,0 +1,234 @@
1
+ # Agent-led setup
2
+
3
+ The user starts in their existing CLI and says “install Ezenciel”, then “create
4
+ an agent as my family shopper”. The installing agent does the technical work.
5
+ Keep that host CLI and login for every agent; do not request another CLI login.
6
+
7
+ ## Main first, then plugins through Telegram
8
+
9
+ Complete the main installation, verified owner pairing and an actual agent reply
10
+ in Telegram before installing or onboarding any plugin. A supplied WhatsApp
11
+ tarball is optional follow-up input, not a prerequisite. Do not open its setup
12
+ flow, build it, create its catalog entry or ask for a QR scan during main setup.
13
+ Initialize the main registry with the packaged empty catalog only.
14
+
15
+ After the main agent replies successfully, ask the owner to continue in that
16
+ Telegram conversation: “Install WhatsApp from <exact supplied tarball path>.”
17
+ The installed agent owns artifact inspection, extraction into its writable tools
18
+ directory, catalog registration, install/start and QR delivery in Telegram. The
19
+ original installing CLI must not take over plugin onboarding. If Telegram cannot
20
+ complete a required tool action, diagnose that boundary and report the failure;
21
+ do not finish it externally and call the Telegram workflow successful. An explicit
22
+ owner request for standalone plugin development is a separate workflow.
23
+
24
+ ## Defaults and host prerequisites
25
+
26
+ Use the existing owner's host account. Unless a layout was supplied, use
27
+ `${XDG_DATA_HOME:-$HOME/.local/share}/ez/packages/<version>/` for extracted main
28
+ packages and `${XDG_DATA_HOME:-$HOME/.local/share}/ez/agents/` for private deployments.
29
+ Never overwrite an existing package/deployment or extract over its state. Infer
30
+ the agent name and purpose from the owner's request; ask only when missing.
31
+
32
+ Before running Node commands, check `command -v node` and `node --version`.
33
+ If Node 22+ or this package's pinned pnpm is missing, provision it using the
34
+ host OS's supported installation method and official distribution instructions,
35
+ then verify the version and service PATH yourself. This is installer work, like
36
+ Docker setup below; do not ask the owner to execute a dependency checklist.
37
+ Only an actual OS consent, admin credential or account-access boundary needs the
38
+ owner. Do not bundle runtimes or change the host's unrelated default toolchain.
39
+
40
+ Once Node is available, the dependency-free diagnostic works before pnpm install:
41
+
42
+ ```sh
43
+ node /absolute/package/bin/ezenciel-agents-install preflight --executor /absolute/path/to/codex
44
+ ```
45
+
46
+ It reports Node/pnpm, Docker daemon access, Compose, host disk space and the selected
47
+ executor path/version. Disk availability is advisory: inspect Docker's own storage
48
+ too. For an executor path, inspect its identity/version and use the corresponding
49
+ supported key (for example, a verified `/path/to/codex` becomes `codex`). Ensure its
50
+ directory is in the service PATH; a similarly named file is not identity proof.
51
+ The preflight does not prove CLI authentication or sandbox execution; perform the
52
+ harmless tool-call check below. Retry preflight after fixing failed checks.
53
+
54
+ ## Install the supplied release artifact
55
+
56
+ Use `npm pack @jc_stack/ez-agents@0.1.0-beta.12` or the exact GitHub release
57
+ tarball. Verify its SHA-256 against the release receipt when using GitHub.
58
+ Do not guess an npm name or substitute an unscoped package.
59
+ Choose a permanent package directory and a separate private deployment directory.
60
+
61
+ ```sh
62
+ mkdir -p /absolute/ez-package
63
+ # Inspect before extracting; the archive should contain only package/ entries.
64
+ tar -tzf /absolute/jc_stack-ez-agents-0.1.0-beta.12.tgz
65
+ tar -xzf /absolute/jc_stack-ez-agents-0.1.0-beta.12.tgz -C /absolute/ez-package
66
+ cd /absolute/ez-package/package
67
+ cp docker/pnpm-lock.yaml pnpm-lock.yaml
68
+ pnpm install --frozen-lockfile
69
+ export PATH="$PWD/bin:$PATH"
70
+ export EZ_AGENTS_HOME=/absolute/private/agents
71
+ node bin/ezenciel-agents-install build
72
+ # Set EZ_RELAY_IMAGE to the exact image returned by build for create/start.
73
+ export EZ_RELAY_IMAGE='<returned-image>'
74
+ ```
75
+
76
+ Node 22+ and pnpm 10.30.3 are needed by the host transport. The tarball carries
77
+ its lockfile under docker/ because npm excludes the root pnpm lockfile. Do not
78
+ move this package directory after binding a service to its absolute paths.
79
+ For a source checkout the root lockfile is already present. Do not run a second
80
+ copy of an existing bot token. Continue with the per-agent configuration below.
81
+
82
+ Verify the tarball against its adjacent `.sha256` or the kit's `SHA256SUMS` before
83
+ extracting. The build tool uses a content-specific image and exclusive build lock,
84
+ with details in the returned private log. A repeated request reports an existing
85
+ build or reuses its verified completed image. If a build was interrupted, inspect
86
+ the log and owning process before recovering its lock; never start duplicates.
87
+ The creator persists the selected EZ_RELAY_IMAGE in the deployment's `docker.env`,
88
+ so later service starts use the same build without depending on shell environment.
89
+
90
+ ## Create, start and verify
91
+
92
+ 1. Make the host ready yourself. Check Docker Engine, Docker Compose, host
93
+ Node 22+, this package and the current CLI. If Docker or Compose is absent,
94
+ not running, or unusable by the current user, install the official supported
95
+ Docker distribution for this operating system, start it, and complete its
96
+ normal user-access setup. Verify with `docker version`, `docker compose
97
+ version`, and a harmless disposable container before continuing. Do not
98
+ hand Docker installation, daemon startup, image building, or Compose
99
+ commands to the owner. An administrator password, operating-system consent,
100
+ or Docker Desktop sign-in that the installer cannot approve is the only
101
+ reason to ask the owner for one concrete action; resume immediately after.
102
+ Build the relay image once. Record the installing CLI immediately with
103
+ `ezenciel-agents-create --register-cli <current-cli>`. This is installer metadata,
104
+ not a question for the user. Do not assume an unpublished npm package exists.
105
+ Before requesting a bot token, verify a real harmless command through the
106
+ selected CLI's execution sandbox under the same host user and service
107
+ environment. A CLI version check, successful model response, or zero exit
108
+ code does not prove shell tools work. Inspect the tool result itself.
109
+ On Ubuntu, `bwrap: setting up uid map: Permission denied` can indicate
110
+ AppArmor's unprivileged-user-namespace restriction. Confirm this with the
111
+ kernel audit log before changing anything. Explain and obtain authorization
112
+ for any required host security-policy change; prefer an executable-specific
113
+ policy reviewed for the installed CLI path. Do not globally disable AppArmor
114
+ or user-namespace restrictions, or disable the CLI sandbox as a fallback.
115
+ Repeat the actual sandbox command after remediation. If blocked, report
116
+ the precise prerequisite and keep installation pending.
117
+ 2. Obtain a separate BotFather token for the new agent. Pass it through stdin
118
+ to the creator; keep it out of argv, logs, images and Markdown.
119
+ `ezenciel-agents-create` reads the token from stdin by default and does not
120
+ accept `--token-stdin`. That flag belongs to `ezenciel-agents-setup configure`.
121
+ 3. Create its deployment with the host installation's selected CLI:
122
+
123
+ ```sh
124
+ export EZ_AGENTS_HOME=/absolute/private/agents
125
+ bin/ezenciel-agents-create --name family-shopper --purpose 'Help my family plan shopping.' < /private/bot-token
126
+ export EZ_DEPLOYMENT_DIR="$EZ_AGENTS_HOME/family-shopper"
127
+ ```
128
+
129
+ Agent creation defaults to the CLI recorded when the initial package was
130
+ installed. It needs no `--cli` argument. A later shell or different available CLI
131
+ does not change that saved default. No installed-binary ranking or Grok fallback
132
+ is used.
133
+ The creator writes `host-executor.json`, private secrets, mind/control paths,
134
+ purpose and unique plugin volume names. Duplicate names fail without overwriting.
135
+ `ezenciel-agents-create --list` lists deployments without secrets.
136
+
137
+ Before starting that host transport, initialize the main package’s built-in plugin manager. It runs on the host
138
+ for Docker access and adds no separate package or provider library. The packaged catalog is empty so the relay installs independently.
139
+ Use its empty default catalog. Plugin preparation follows the verified Telegram
140
+ handoff, not this step. Run:
141
+
142
+ ```sh
143
+ node /absolute/ezenciel_agents/bin/ezenciel-agents-tools.mjs init \
144
+ --home "$EZ_DEPLOYMENT_DIR/tools" \
145
+ --workspace "$EZ_DEPLOYMENT_DIR/mind" \
146
+ --host-config "$EZ_DEPLOYMENT_DIR/host-executor.json"
147
+ ```
148
+
149
+ This binds a private `ez` and preserves native command access. The default catalog
150
+ is empty. Do not supply a plugin catalog during first-time main onboarding.
151
+ Initialization
152
+ adds discovery instructions to the mind's TOOLS.md. Verify `tools/bin/ez plugins
153
+ available` before the first agent turn. Also execute the agent-bound
154
+ `ezenciel-agents-message --help` through the selected CLI sandbox and verify
155
+ its actual tool output, so absent launchers or blocked execution are detected
156
+ before asking the owner to test Telegram. Only after a real owner exchange has
157
+ succeeded, the owner requests plugin installation in that Telegram conversation;
158
+ the installed agent registers the supplied source, invokes install/start and follows
159
+ the plugin skill through onboarding and verified use under that same request.
160
+ Follow the [installation completion contract](plugins.md#installation-completion-contract).
161
+ Registry initialization itself does not connect accounts or start plugins.
162
+ Never silently reuse a global `ez` from the old sandbox runtime.
163
+
164
+ 4. Follow [host startup templates](host-service.md). Register `bin/ezenciel-agents-host` with the host's native service manager,
165
+ binding `EZ_DEPLOYMENT_DIR` and the user's existing CLI PATH/HOME. On macOS use
166
+ a LaunchAgent; on Linux use a user service. Use the absolute Node/package
167
+ paths. This generic transport is the only host execution bridge. Do not start
168
+ another host relay or install another CLI. Verify its heartbeat, then run
169
+ `bin/ezenciel-agents-docker up -d --wait`.
170
+
171
+ `ezenciel-agents-setup service` is Docker-only startup: run it from the
172
+ deployment directory containing `docker.env`. It starts the relay and does
173
+ not install or start the host-executor user service. Complete the host
174
+ registration above separately.
175
+
176
+ 5. Ask the owner to message the exact bot. Verify the pending numeric identity,
177
+ approve it, and verify a real CLI-produced Telegram reply. Check restart
178
+ persistence and two agents running concurrently with separate state.
179
+ A healthy container and completed CLI run are insufficient: require a
180
+ Telegram receipt from the CLI-produced reply. If absent, inspect the native
181
+ CLI transcript and outbox before claiming success or asking the owner to
182
+ repeat a message. Use the supplied outbound smoke test with the poller
183
+ stopped to verify repairs, then restore the poller; never replay uncertain
184
+ user actions merely to test delivery.
185
+
186
+ The main runtime is fully installer-owned: build it, register its host
187
+ transport, bring its Compose project up, and verify restart persistence. Plugins
188
+ are installed by the working Telegram agent when the owner requests their
189
+ capability there; account onboarding and provider confirmation follow that request.
190
+ Never use a missing plugin as a reason
191
+ to defer the main relay.
192
+
193
+ Check progress with `ezenciel-agents-install status --deployment /absolute/deployment`.
194
+ It distinguishes missing configuration, runtime offline, awaiting owner, awaiting
195
+ a verified Telegram reply and readiness for a Telegram plugin request. It inspects
196
+ current heartbeats and owner-bound completed-run delivery receipts without sending
197
+ messages or exposing tokens. Receipt evidence is historical: separately verify
198
+ the current conversation and restart persistence before declaring setup complete.
199
+
200
+ Purpose seeds SOUL.md once; future customization survives restart. Conversations,
201
+ pairing, files and plugin accounts are separate. The existing host CLI login is
202
+ shared, so this is not a security sandbox against other agents under that user.
203
+ Plugins run in their own containers and own their authentication. Install and
204
+ register them only for the requested agent. Never clone another agent's plugin
205
+ credentials. See [runtime, migration and QA](docker-runtime.md).
206
+
207
+ The installing CLI is an initial default, not a permanent restriction. An explicit
208
+ owner selection may use any supported CLI/model installed on the host. Native
209
+ `ezenciel-agents-ai list` and `select` expose this choice. A cross-CLI switch
210
+ starts a fresh native conversation and preserves the mind and installation
211
+ default. Existing queued jobs retain their captured execution choice.
212
+
213
+ ## Troubleshooting
214
+
215
+ | Symptom | Inspect and recover |
216
+ |---|---|
217
+ | Docker unavailable | Check engine and Compose, start the supported installation; complete any required OS consent. |
218
+ | Bot stays silent | Check pending owner identity, relay health, host heartbeat and outbox; approve only the verified owner. |
219
+ | CLI exits without reply | Inspect the actual tool result and delivery receipt; stdout is not Telegram output. |
220
+ | Exit 73 | An existing writer holds this deployment; stop the exact duplicate, never delete the kernel lock. |
221
+ | Plugin absent | Check the bound catalog and install/start the reviewed package explicitly; no plugin ships by default. |
222
+ | Plugin revision mismatch | Reinspect stable source, review the changed hash and explicitly update its catalog pin. |
223
+ | Interrupted CLI cannot resume | Use the explicit new-conversation command after inspecting the failure; no automatic fallback. |
224
+
225
+ Use `ezenciel-agents-docker logs --tail 100 relay` with EZ_DEPLOYMENT_DIR bound.
226
+ Sanitize logs before sharing. Back up mind/control and private profiles before
227
+ upgrades. Stop the exact Compose project and host service to remove execution;
228
+ retain state unless deletion was requested. Revoke a Telegram bot token through
229
+ BotFather and a WhatsApp device on the phone separately from removing software.
230
+
231
+ ## Agent-owned upgrades
232
+
233
+ This beta includes owner-policy release checks and durable
234
+ main/plugin replacement. See [upgrade setup, tools and recovery](upgrades.md). Earlier main upgrade/rollback VM QA passed; final-release fresh-host/reboot and live plugin upgrade acceptance remain pending.