@jc_stack/ez-agents 0.1.0-beta.26 → 0.1.0-beta.28

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 (128) hide show
  1. package/.env.example +10 -1
  2. package/AGENTS.md +40 -9
  3. package/CHANGELOG.md +35 -0
  4. package/CONTRIBUTING.md +31 -1
  5. package/Dockerfile +1 -0
  6. package/README.md +84 -12
  7. package/bin/ezenciel-agents-application +2 -0
  8. package/bin/ezenciel-agents-application.mjs +16 -0
  9. package/compose.yaml +8 -0
  10. package/docker/entrypoint.sh +20 -2
  11. package/docker/healthcheck.mjs +1 -1
  12. package/docker/run.ts +3 -3
  13. package/docker/smoke.mjs +41 -2
  14. package/docs/application-channel.md +366 -0
  15. package/docs/architecture/ai-selection.md +12 -15
  16. package/docs/docker-runtime.md +29 -0
  17. package/docs/host-service.md +5 -8
  18. package/docs/local-qa.md +1 -1
  19. package/docs/managed-applications.md +68 -0
  20. package/docs/plugin-catalog.md +1 -0
  21. package/docs/plugin-connection.md +76 -0
  22. package/docs/plugins.md +54 -5
  23. package/docs/repair.md +26 -25
  24. package/docs/responsive-channels.md +13 -55
  25. package/docs/scheduling.md +40 -36
  26. package/docs/setup.md +11 -21
  27. package/docs/standalone-cli.md +2 -2
  28. package/docs/upgrades.md +43 -18
  29. package/package.json +8 -4
  30. package/src/agent-guidance.ts +32 -3
  31. package/src/ai-cli.ts +5 -1
  32. package/src/ai.ts +6 -28
  33. package/src/application-channel.ts +308 -0
  34. package/src/application-cli.ts +41 -0
  35. package/src/application-client.mjs +87 -0
  36. package/src/application-origin.ts +15 -0
  37. package/src/codex-session.ts +7 -10
  38. package/src/config.ts +23 -5
  39. package/src/control-state.ts +274 -21
  40. package/src/conversation-menu.ts +89 -0
  41. package/src/delivery-context.d.mts +5 -0
  42. package/src/delivery-context.mjs +25 -0
  43. package/src/desktop-bridge.ts +11 -43
  44. package/src/event-sources.ts +2 -2
  45. package/src/execution-authority.ts +2 -0
  46. package/src/executor.ts +29 -58
  47. package/src/host-executor.ts +11 -9
  48. package/src/identity.ts +11 -3
  49. package/src/index.ts +191 -93
  50. package/src/menu.ts +76 -55
  51. package/src/message-history.ts +52 -0
  52. package/src/message-send.ts +1 -1
  53. package/src/message.ts +49 -7
  54. package/src/model-policy.ts +5 -15
  55. package/src/owner.ts +7 -1
  56. package/src/plugins/connection-artifacts.mjs +31 -0
  57. package/src/plugins/connection.mjs +124 -0
  58. package/src/plugins/manager.mjs +93 -23
  59. package/src/plugins/native-tasks.d.mts +4 -0
  60. package/src/plugins/native-tasks.mjs +66 -0
  61. package/src/plugins/workspace-lease.d.mts +3 -0
  62. package/src/plugins/workspace-lease.mjs +44 -0
  63. package/src/repair-policy.ts +0 -8
  64. package/src/reply-context.ts +3 -29
  65. package/src/runs.ts +67 -9
  66. package/src/schedule-cli.ts +33 -15
  67. package/src/scheduled-tasks.ts +20 -21
  68. package/src/scheduler.ts +55 -22
  69. package/src/task-executor.ts +4 -5
  70. package/src/task-workspace.ts +2 -11
  71. package/src/update-attention.ts +1 -1
  72. package/src/updates/binding.mjs +2 -6
  73. package/src/updates/control.mjs +4 -0
  74. package/src/updates/supervisor.mjs +10 -4
  75. package/src/web-launcher.ts +19 -0
  76. package/src/workspace.ts +3 -1
  77. package/templates/agent/AGENTS.md +13 -55
  78. package/templates/agent-guidance.md +90 -37
  79. package/templates/deployments.md +24 -0
  80. package/templates/failure-review.md +6 -0
  81. package/templates/maintainer-purpose.md +12 -6
  82. package/test/agent-guidance.test.ts +29 -39
  83. package/test/ai-cli.test.ts +9 -0
  84. package/test/ai.test.ts +66 -22
  85. package/test/application-channel.test.ts +283 -0
  86. package/test/application-client.test.mjs +84 -0
  87. package/test/application-controls.test.ts +224 -0
  88. package/test/application-only.test.ts +100 -0
  89. package/test/busy-reply-relay.test.ts +11 -7
  90. package/test/channel-delivery.test.ts +63 -0
  91. package/test/channel-owner.test.ts +161 -0
  92. package/test/client-defaults.test.ts +1 -1
  93. package/test/codex-session.test.ts +18 -10
  94. package/test/config.test.ts +16 -1
  95. package/test/connection-artifacts.test.mjs +32 -0
  96. package/test/conversation-menu.test.ts +67 -0
  97. package/test/conversations.test.ts +84 -0
  98. package/test/desktop-bridge.test.ts +17 -11
  99. package/test/engine-handoff.test.ts +73 -0
  100. package/test/event-sources.test.ts +5 -8
  101. package/test/executor.test.ts +68 -16
  102. package/test/failure.test.ts +64 -0
  103. package/test/host-executor.test.ts +58 -17
  104. package/test/install-config.test.ts +1 -1
  105. package/test/intake-relay.test.ts +169 -25
  106. package/test/message-history.test.ts +127 -0
  107. package/test/model-policy.test.ts +23 -48
  108. package/test/native-tasks.test.ts +36 -0
  109. package/test/plugin-connection.test.mjs +124 -0
  110. package/test/plugin-manager.test.mjs +70 -10
  111. package/test/repair-policy.test.ts +8 -12
  112. package/test/runs.test.ts +13 -0
  113. package/test/runtime-identity.test.mjs +18 -0
  114. package/test/schedule-cli.test.ts +34 -5
  115. package/test/scheduled-tasks.test.ts +79 -8
  116. package/test/scheduler.test.ts +30 -1
  117. package/test/task-native.test.ts +5 -2
  118. package/test/update-attention.test.ts +1 -2
  119. package/test/updates.test.mjs +44 -5
  120. package/test/workspace.test.ts +2 -3
  121. package/scripts/smoke-busy-reply.ts +0 -58
  122. package/src/reply-executor.ts +0 -55
  123. package/src/reply-mcp.ts +0 -23
  124. package/templates/agent/TOOLS.md +0 -105
  125. package/templates/chat-guidance.md +0 -23
  126. package/templates/standalone-tools.md +0 -20
  127. package/templates/updates.md +0 -45
  128. package/test/reply.test.ts +0 -159
package/docs/plugins.md CHANGED
@@ -28,7 +28,7 @@ Without `--catalog`, init loads an empty packaged catalog. Keep it empty for
28
28
  initial main onboarding; no sibling repository, broker or provider account is
29
29
  needed. Finish owner pairing and verify an actual Telegram agent reply first.
30
30
  Init creates a private registry and `tools/bin/ez`, adds a
31
- TOOLS.md discovery entry, and binds the matching host executor to that bin
31
+ managed AGENTS.md registry locator, and binds the matching host executor to that bin
32
32
  folder. Native binaries are linked through; an existing `ez` collision fails.
33
33
  Run before starting the host executor. For an already running installation,
34
34
  place a symlink to the returned launcher in that agent's existing private bin
@@ -263,10 +263,10 @@ Shared workers have a hard Docker CPU quota of half a core by default, across al
263
263
 
264
264
  ## Existing local folders
265
265
 
266
- Use operator-owned read-only folder bindings when a plugin needs files that
266
+ Use operator-owned folder bindings when a plugin needs files that
267
267
  already exist on the host. Keep indexes and writable metadata in the plugin's
268
268
  normal volume. This uses Docker bind mounts; it copies no source bytes and
269
- starts no provider sync. File edits remain with the host's existing tools.
269
+ starts no provider sync. Read-only is the default.
270
270
 
271
271
  Stop the plugin before changing a binding:
272
272
 
@@ -288,9 +288,58 @@ volume contents; inspect those before restarting to avoid using stale files.
288
288
  Never enable another sync writer for an already synchronized host folder.
289
289
 
290
290
  For Library, create/select the library name first and retain its QMD state while
291
- binding the host tree at that library's `files` directory. Keep provider bindings
292
- disabled for that source. Enable the normal shared embedding worker through
291
+ binding the host tree at that library's `files` directory. Enable provider bindings
292
+ only when that plugin supports the selected host folder and owns its sync. Enable the normal shared embedding worker through
293
293
  `plugins shared-enable library embeddings`. Verify `library sources`, real search,
294
294
  and original readback from the actual executor. Document any differences between
295
295
  indexed snapshots and current originals; do not replace Library with private
296
296
  QMD runtimes or edit installed Compose/package files to bypass missing support.
297
+
298
+ ## Generated capability discovery
299
+
300
+ `ez tools list --details` generates a compact index directly from installed
301
+ `ez-plugin.json` manifests: each plugin supplies its `description`, command aliases
302
+ and `skills`. Descriptions are limited to 200 characters in this view; full
303
+ instructions stay in the skill. Installation, replacement and removal are reflected
304
+ on the next read, without hooks, LLM calls or a cached inventory file.
305
+
306
+ `ez tools list` retains its alias mapping for existing clients. Native AGENTS.md
307
+ contains only the agent-bound discovery shortcut. New workspaces do not seed
308
+ TOOLS.md; upgrades preserve legacy notes without rewriting them. Keep owner/account
309
+ policies in agent instructions or linked policy files, separate from plugin metadata.
310
+
311
+ Folder bindings default to read-only. For an explicitly authorized plugin that
312
+ updates the existing source, add `--writable` to `folder-bind` while the plugin
313
+ is stopped. The grant applies only to that folder and survives compatible
314
+ upgrades. Rebind without `--writable` to return it to read-only. Package
315
+ descriptors cannot request this grant. Keep one synchronization owner for each
316
+ source; a writable mount alone does not configure synchronization.
317
+
318
+ ## Browser endpoints for connected plugins
319
+
320
+ `ez tools serve HOST_PORT:CONTAINER_PORT ALIAS ARGS...` runs a plugin's web command
321
+ inside its command container while core handles the existing persistent tool
322
+ protocol. Both ports must be 1024–65535. Publication is always on host 127.0.0.1;
323
+ no plugin manifest can request public ingress. Run the foreground command under
324
+ the host's normal service supervisor if it must survive terminal closure. SIGINT
325
+ or SIGTERM cancels the connection and removes its command container.
326
+
327
+ The plugin owns HTTP, browser authentication, sessions and static assets. HTTPS
328
+ termination, DNS and forwarding are explicit operator configuration. Plugins may
329
+ use the read-only `tools.owner` core request to check the current paired private
330
+ Telegram user and opaque pairing epoch. This is identity data, not an access grant;
331
+ the plugin must authenticate the requester and recheck identity on protected requests.
332
+ No owner returns null, and no bot token is exposed. Standard plugin CLI operations
333
+ still enforce their normal permissions. See the Voice plugin's README for a client.
334
+
335
+ To add an optional launcher without replacing Telegram's command menu, set the
336
+ relay Compose environment or `.env` (then recreate the relay container):
337
+
338
+ ```dotenv
339
+ EZ_TELEGRAM_WEB_APP={"command":"voice","label":"Voice","url":"https://voice.example.com/"}
340
+ ```
341
+
342
+ The command returns a Mini App button to the authenticated owner in private chat;
343
+ `/menu` includes the same button. Reserved commands cannot be replaced. The HTTPS
344
+ URL must not contain credentials, query parameters or a fragment. This setting
345
+ only registers a launcher; it does not expose a port or authenticate web requests.
package/docs/repair.md CHANGED
@@ -1,41 +1,42 @@
1
1
  # Native repair ownership
2
2
 
3
- Every deployed agent is a repairer by default. When an agent finds a core or
4
- plugin defect, it keeps the context and pursues a tested contribution PR. The
5
- core injects the same mandate into CLI/native and desktop execution, including
6
- existing workspaces; it does not replace the agent's mind or implement a repair
7
- workflow engine. Use native Git/GitHub CLI or the installed GitHub plugin.
3
+ Repair is a capability used by an explicit owner request or owner-saved maintenance
4
+ mandate. Discovering a defect alone does not enroll an ordinary conversation in
5
+ an issue/claim/PR workflow. Preserve useful evidence and continue the requested
6
+ task. The current execution guidance supersedes older default-repair text in
7
+ existing workspaces without rewriting the agent's mind.
8
8
 
9
- The agent searches for the same cause, registers a sanitized issue, requests a
10
- claim, then works in an isolated contribution checkout after the coordinator's
11
- grant. It resumes the same issue/branch/PR after interruption. The installed
12
- runtime is never the repair checkout. Missing credentials or coordination remain
13
- recorded blockers; the default does not invent repository access. Public reports
14
- must exclude private runtime data and use the security reporting route when needed.
9
+ For an authorized repair, use the selected engine with native Git/GitHub tools
10
+ and follow the target repository's CONTRIBUTING.md. Check existing work for the
11
+ same cause and use an isolated contribution checkout; never edit the installed
12
+ runtime as the repair checkout. Resume the same branch/PR after interruption.
13
+ A separate issue, claim service or coordinator grant is not an ez prerequisite.
14
+ Use coordination only where the repository or owner explicitly requires it.
15
15
 
16
- One coordinator grants claims sequentially per repository. Assignment alone is
17
- not a lock. All participating agents must use that coordinator; this convention
18
- cannot prevent an unrelated public contributor from opening a competing PR.
19
- The discovering agent remains the repairer, including when its work moves to a
20
- background task. The coordinator reconciles duplicates and stalled claims. The
21
- maintainer independently reviews and tests, then merges/publishes only within
22
- separate owner-approved policies. Start from templates/maintainer-purpose.md.
16
+ Question the failing wrapper before adding code. Removing behavior or correcting
17
+ existing instructions/tool contracts can fully resolve the defect. Preserve
18
+ useful evidence and verified outcomes, with normal independent review and CI.
19
+ Missing credentials block only operations requiring them; continue useful local
20
+ work and report the precise remaining dependency. Public reports must exclude
21
+ private runtime data and use the security reporting route where appropriate.
22
+ Do not repeatedly check an unchanged dependency.
23
23
 
24
24
  ## Disable
25
25
 
26
26
  Set `EZ_REPAIR_ENABLED=false` in the deployment's Docker environment and recreate
27
27
  the relay. The resolved setting crosses the host transport and is included in
28
28
  every new execution prompt; the default is true and invalid values fail startup.
29
- This changes the automatic mandate, not filesystem/GitHub permissions, and does
29
+ True makes the capability available; it does not itself grant a repair mandate.
30
+ The setting does not change filesystem/GitHub permissions and does
30
31
  not cancel an already running task. Explicitly stop active repair work when needed.
31
32
  An owner can also disable repairs globally or for a repository in the agent's
32
33
  saved USER.md preferences; carry those restrictions into background task context.
33
34
 
34
35
  ## Setup boundary
35
36
 
36
- The shipped mandate and maintainer purpose do not provision a GitHub account,
37
- coordinator service or publishing token. Enroll the allowed repositories and
38
- configure one maintainer execution lane on the owner's host before unattended
39
- claims. Reuse authenticated GitHub CLI where authorized. Repository push and PR
40
- permissions are distinct from package-registry publication and protected-branch
41
- approval. Never put credentials in prompts, issues or test environments.
37
+ Reuse existing authenticated access within the owner's request or saved mandate.
38
+ ez does not provision a coordinator, GitHub identity or publishing token, and
39
+ none is an implicit prerequisite for local diagnosis or an authorized local fix.
40
+ Repository push/PR access, protected-branch review and package publication are
41
+ separate capabilities and permissions. Follow existing release authority; never
42
+ put credentials in prompts, issues or test environments.
@@ -1,57 +1,15 @@
1
1
  # Responsive channels
2
2
 
3
- Ez treats conversational channels as places to answer, clarify and hand off
4
- work. A simple question uses the current conversation; a small authorized action
5
- uses its canonical receipt. Substantial work gets a durable task with enough
6
- context to finish and verify the job. The agent returns to conversation after
7
- the handoff is saved, instead of waiting for the worker. This is agent guidance,
8
- not a keyword classifier, automatic acknowledgement, or latency guarantee.
9
-
10
- New Codex agents use Sol / medium for chat. Scheduled work defaults independently
11
- to Luna / max; the agent can choose another model and effort for complex work.
12
- `ezenciel-agents-schedule create --now --text-file FILE --model MODEL --effort max`
13
- uses the existing scheduler (include `--name` for a useful task label). Busy owner
14
- reply sessions expose the same independent model/effort choice through `defer`.
15
- Its retry returns the first saved schedule; changing arguments does not revise
16
- an accepted job. `xhigh` and `max` are available only for Luna; other models remain capped at high.
17
-
18
- A handoff includes the objective, relevant context and paths, constraints,
19
- authorized actions, acceptance checks and delivery destination. Background
20
- sessions own verification and final delivery, and may use native subagents.
21
- One writer per workspace still applies. Shared external resources require
22
- coordination even when task directories differ. Status must distinguish a saved
23
- schedule from actual execution and a verified result from a process exit.
24
-
25
- The package loads `templates/chat-guidance.md` at each turn for CLI, desktop,
26
- busy owner replies and approved plugin messaging tasks. Upgrades refresh this
27
- behavior without rewriting the agent's personal files. Existing model choices
28
- remain pinned; an upgrade adds Responsive chat as an available selection.
29
-
30
- ## Channel and authority boundaries
31
-
32
- Telegram owner conversations can schedule work under the owner's authority.
33
- The existing restricted busy-reply session keeps Codex chat available while a
34
- writer is active. Other executors retain their existing concurrency behavior.
35
-
36
- WhatsApp and other plugin contacts use the approved messaging task's isolated
37
- context and tools. They receive the conversational guidance and Sol / medium
38
- selection, but cannot invoke owner schedules, shell tools or native subagents.
39
- They report work outside their capabilities to the owner; that report is not
40
- an instruction or permission to execute. Full delegation from a plugin contact
41
- needs an explicitly scoped worker capability and return route; this update does
42
- not grant one. The plugin name alone never confers owner authority.
43
-
44
- An application using `channelBackendUrl` owns its conversation, model and job
45
- lifecycle. The relay does not inject prompts or override the app's model. Such
46
- backends (including AI Fit) must adopt the same handoff policy in their own
47
- runtime to benefit. Reuse their canonical job system; do not create a second
48
- agent in the transport. Telegram polling and app-side queue waits still count
49
- toward user-visible latency.
50
-
51
- ## Verification
52
-
53
- Tests cover independent worker settings, preserved selections across upgrades,
54
- idempotent handoffs, invalid settings, revocation and restricted tool boundaries.
55
- Existing scheduler/host tests cover a conversational reply while work remains
56
- active. Measure time to the first useful reply and verified task completion
57
- separately on the deployed provider before claiming a performance improvement.
3
+ Owner input passes unchanged to the selected engine. The agent decides when to
4
+ delegate or schedule long work to remain available. ez queues foreground input
5
+ while a foreground run is active; it does not create a separate busy-reply agent.
6
+ Independent scheduled task directories retain deterministic writer isolation.
7
+
8
+ Background tasks receive literal task text. Their directories contain no generated
9
+ role instructions or copied identity files; native workspace instructions and
10
+ existing Markdown provide context. The agent chooses what to read and when to use
11
+ the message CLI. Native final text is not automatically delivered to Telegram.
12
+
13
+ Restricted correspondence receives a typed activation event and scoped tools.
14
+ Authorization, sandboxing and tool handlers enforce contact and lifecycle limits.
15
+ Maintenance and group notifications carry event data; CLI help owns operations.
@@ -32,30 +32,26 @@ the host changes zones. Nonexistent DST wall times are skipped; repeated wall
32
32
  times fire once, at the earlier instant. Search is bounded to eight years.
33
33
  Public-holiday calendars and arbitrary RRULE syntax are not implemented.
34
34
 
35
- New tasks, including work deferred by a busy reply session, default to Codex
36
- `gpt-5.6-luna` with `max` reasoning independently of the creating chat.
37
- New chats use the separate Sol/medium preset. Busy reply `defer` accepts optional
38
- `model` and `effort` fields; retries preserve the first saved task choice.
39
- Use `--cli`, `--model`, and `--effort` to specify another choice. `xhigh` and
40
- `max` are available only with Codex `gpt-5.6-luna`; every other model remains capped at
41
- `high`. Non-Codex adapters inherit native effort when unset. Editing preserves the existing AI
42
- choice unless those flags override it. Stored choices are checked again at
43
- launch, including schedules saved before a policy change.
35
+ New tasks inherit selected engine settings. Explicit `--cli`, `--model` and
36
+ `--effort` override those choices; omitted values use native defaults. Edits
37
+ preserve existing choices. Historical deferred tasks keep their source context
38
+ available through `ezenciel-agents-schedule context`.
44
39
 
45
40
  ## Execution and authority
46
41
 
47
- The relay checks due work once per second. Each occurrence enters the durable
48
- run queue with a stable ID. Background work runs in a fresh native CLI session
49
- and `work/tasks/RUN_ID/`, with snapshots of the agent's SOUL, USER and TOOLS files.
50
- Instructions must include any needed context or source paths; full chat history
51
- is not copied. Task folders remain for inspection and artifact delivery.
42
+ Due occurrences enter the durable queue with stable IDs and literal task text.
43
+ Background runs use fresh native sessions in `work/tasks/RUN_ID/`. No identity
44
+ files or role instructions are generated there. Existing workspace Markdown
45
+ provides context; the engine chooses what to read. Codex uses `AGENTS.md` or `.git`
46
+ as its native project-root marker, so a nested task sees the existing agent scope. Task folders remain for
47
+ inspection and artifact delivery.
52
48
 
53
49
  One writer runs per task directory. Up to four background tasks can run alongside
54
- the main conversation. When a Codex owner message arrives while work is busy, a separate restricted session reads recent messages and run progress and answers through the normal outbox. It can queue requested work through the scheduler, but cannot run shell commands, access plugins, or edit the agent workspace. Only one reply session runs at a time and it releases its slot after a 60-second reply deadline; this deadline does not apply to writer jobs. Its context is a bounded snapshot, not a shared native transcript. Delivered parallel replies are included as historical context in the next normal conversation turn. Codex 0.153.4 and 0.154.0 are supported for this restricted adapter. Other versions fail closed pending tool-surface validation. A recurring schedule has at most one pending
55
- or active occurrence. Agents should delegate long work with `create --now`, return
56
- to chat, and inspect `runs` or task progress when asked. Native subagents can be
57
- used inside the worker. Sharing provider profiles does not make concurrent CRM,
58
- file or browser writes safe: the agent must coordinate those resources.
50
+ the main conversation. Foreground inputs queue while a foreground turn runs;
51
+ ez does not create another reply agent. The agent can delegate or schedule long
52
+ work and return to chat. It decides when to send through the message CLI.
53
+ A recurring schedule has at most one pending or active occurrence. Shared
54
+ provider resources still need writer coordination.
59
55
 
60
56
  Production relay/host execution has no wall-clock timeout. The old
61
57
  `EZ_EXECUTOR_TIMEOUT_SECONDS` setting is ignored. Individual network/tool waits
@@ -64,13 +60,14 @@ are an executor capability, configured through instructions. Ez has no goal API,
64
60
  continuation loop or rule equating a process exit with goal achievement.
65
61
 
66
62
  Scheduled Codex CLI tasks use a dedicated native app-server session, tested with
67
- CLI 0.153.4. A leading `/goal` in the instruction text maps to the same native
68
- goal command used by the interactive CLI. Codex automatically starts subsequent
69
- turns; the transport stays connected until the native goal is complete or stops
70
- for attention. It sends no continuation prompts and stores no Ez goal state.
71
- Goals created by the agent's native tools also keep the session alive. Ordinary
72
- tasks finish after their turn. A blocked, paused or limited goal is not reported
73
- as successful. Native RPC requests have a response deadline; running tasks do not.
63
+ CLI 0.153.4. Ez forwards the full task as ordinary input without interpreting
64
+ `/goal` or constructing a native goal objective. The engine handles the request,
65
+ context and native goal creation. Codex owns continuation; the transport stays
66
+ connected while a native goal is active and verifies its terminal state. It sends
67
+ no continuation prompts and stores no Ez goal state. Ordinary tasks finish when
68
+ the engine completes its turn without an active goal. A blocked, paused or limited
69
+ goal is not reported as successful. Native RPC requests have a response deadline;
70
+ running tasks do not.
74
71
  Each scheduled task has its own Codex state under `control/cli/codex/tasks/RUN_ID`,
75
72
  with a snapshot of the agent's Codex configuration and the existing auth link.
76
73
  Foreground chat and background tasks do not initialize or migrate one shared
@@ -109,6 +106,15 @@ artifacts are retained. The agent sends through the normal Telegram outbox;
109
106
  `completed` means executor exit, while provider delivery is recorded separately.
110
107
  A timeout or ambiguous send must not cause blind replay of the whole task.
111
108
 
109
+ ## Failure-review stop
110
+
111
+ A schedule using `--when unreviewed-failures` stops dispatching its current
112
+ revision after one of its own runs fails. The failed receipt remains available
113
+ through `runs`/`run`; no new retry queue or automatic repair task is created.
114
+ The paired owner or authorized maintainer diagnoses it and explicitly edits the
115
+ schedule to resume. Marking the failure reviewed or pause/resume alone does not
116
+ clear the stop. Ordinary recurring tasks retain their existing failure behavior.
117
+
112
118
  ## QA
113
119
 
114
120
  `pnpm verify` covers recurrence/DST, restart deduplication, authority revocation,
@@ -136,16 +142,6 @@ exercise cancellation, downtime catch-up and an explicitly requested native goal
136
142
  that needs more than one turn. Synthetic provider evidence does not prove real
137
143
  Telegram delivery, and a sleep test does not prove native goal persistence.
138
144
 
139
- Busy-chat regression probe (real Codex, synthetic Telegram):
140
-
141
- ```sh
142
- pnpm exec tsx scripts/smoke-busy-reply.ts --transport
143
- ```
144
-
145
- The probe holds a writer on a shared workspace, asks an owner question through
146
- the relay and host transport, and requires the restricted reply to complete
147
- while the writer remains active. It sends no real Telegram messages.
148
-
149
145
  ## Optional failure review
150
146
 
151
147
  Create a normal recurring schedule with `--every-seconds 900 --when unreviewed-failures --text-file templates/failure-review.md`. The condition advances empty occurrences without launching an executor. It considers only failures belonging to the paired owner. No separate monitor or automatic retry is introduced.
@@ -153,3 +149,11 @@ Create a normal recurring schedule with `--every-seconds 900 --when unreviewed-f
153
149
  `failures [--all] [--limit N]` returns failedAt, reason, exit code, native session, captured error and runtime versions. Capture keeps at most 4 KiB of redacted stderr; historical failures are not backfilled. `run RUN_ID` reads an owned run. `review RUN_ID --failed-at ISO --status resolved|attention --diagnosis TEXT --recovery TEXT --outcome TEXT` records the investigation without rewriting execution history. A stale timestamp is rejected; a later failure needs a new review. Restricted reply, external and isolated-task callers cannot review failures. An attention review is handed off, not repeatedly relaunched; another new failure wakes the next review.
154
150
 
155
151
  The prompt controls diagnosis, authorized recovery and quiet notification behavior. Inspect prior effects and receipts before retrying anything. A failed review run itself remains visible as a new failure for the next occurrence.
152
+
153
+ The Telegram Scheduled tasks menu lists enabled schedules that still have a pending
154
+ occurrence or a queued/running occurrence. Finished one-time tasks, paused
155
+ schedules and revisions stopped for review are hidden. Each entry shows the
156
+ effective engine/model/effort, next occurrence in UTC (or queued/running state),
157
+ and the first sentence of its saved invocation
158
+ prompt, limited to 140 characters. This is a read-only view; history and full
159
+ prompts remain available through the scheduling CLI.
package/docs/setup.md CHANGED
@@ -52,26 +52,16 @@ owner request for standalone plugin development is a separate workflow.
52
52
 
53
53
  ## Defaults and host prerequisites
54
54
 
55
- New agents using `codex` or `codex-gui` start with `gpt-5.6-sol` and `medium`
56
- reasoning, including when initialized with `ezenciel-agents-setup init`. This
57
- Ez default takes precedence over discovered host client defaults. Saved agent
58
- selections permitted by the current policy are preserved; use the AI settings to choose another model or effort.
59
- Ez accepts `xhigh` and `max` only for `gpt-5.6-luna`; every other model rejects explicit
60
- reasoning above `high` at selection and execution, including old saved or queued choices.
61
- Unset Codex model/effort resolves to
62
- Luna/max at launch. This governs Ez-managed launches; it is not an account-wide
63
- limit on independently launched native clients or executor-created native subagents.
64
- Other adapters inherit their native effort when none is selected in Ez. That
65
- inherited configuration is not capped by Ez; explicit above-high Ez selections
66
- are rejected unless they are Codex Luna/xhigh or Luna/max. Conversation presets pin Sol/medium; the lower-level
67
- Codex fallback is Luna/max for work without an explicit choice.
68
-
69
- New scheduled and one-off background tasks default to Codex Luna/max independently
70
- of the creating chat. Use scheduler `--cli`, `--model`, and `--effort` flags for
71
- explicit overrides. Editing a schedule preserves its settings unless overridden.
72
- Restricted messaging tasks use Sol/medium while retaining their approved tool
73
- and context boundaries. Upgrades add Responsive chat to saved choices without
74
- replacing the selected/default preset. See [responsive channels](responsive-channels.md).
55
+ New agents use the selected engine's native model and effort unless a choice is
56
+ explicitly saved. Scheduling inherits the selected engine settings; `--cli`,
57
+ `--model` and `--effort` provide explicit overrides. Edits preserve saved choices.
58
+ The installed client's catalog supplies supported choices; ez imposes no model-specific
59
+ reasoning cap. Optional compaction settings are passed only when explicitly configured.
60
+
61
+ Restricted correspondence and busy replies retain their audited Codex adapter and
62
+ isolated tool permissions. They honor explicit model/effort choices; unset values
63
+ use that isolated client's native defaults. Unrestricted user configuration is
64
+ not imported into restricted sessions. No workflow prompt is added to input.
75
65
 
76
66
  Use the existing owner's host account. Unless a layout was supplied, use
77
67
  `${XDG_DATA_HOME:-$HOME/.local/share}/ez/packages/<version>/` for extracted main
@@ -199,7 +189,7 @@ node /absolute/ezenciel_agents/bin/ezenciel-agents-tools.mjs init \
199
189
  This binds a private `ez` and preserves native command access. The default catalog
200
190
  is empty. Do not supply a plugin catalog during first-time main onboarding.
201
191
  Initialization
202
- adds discovery instructions to the mind's TOOLS.md. Verify `tools/bin/ez plugins
192
+ adds discovery instructions to the mind's AGENTS.md. Verify `tools/bin/ez plugins
203
193
  available` before the first agent turn. Also execute the agent-bound
204
194
  `ezenciel-agents-message --help` through the selected CLI sandbox and verify
205
195
  its actual tool output, so absent launchers or blocked execution are detected
@@ -23,12 +23,12 @@ node /absolute/package/bin/ezenciel-agents-tools.mjs init --standalone \
23
23
  ```
24
24
 
25
25
  Init starts nothing, uses an empty catalog by default, preserves existing
26
- TOOLS.md notes and appends the registry's discovery instructions. A registry
26
+ workspace notes and adds a managed registry locator to AGENTS.md. A registry
27
27
  cannot be replaced by rerunning init. Keep the package at its original path:
28
28
  the launcher imports it. Status reports `main: null` without a relay binding;
29
29
  automated software upgrades currently require a relay deployment.
30
30
 
31
- Have each executor read the workspace's TOOLS.md and the installed plugin skills.
31
+ Use `ez tools list --details` for generated installed-plugin descriptions, help shortcuts and absolute skill paths. Read only the relevant skill.
32
32
  Add that instruction to its existing project instructions without replacing them.
33
33
  Use the absolute launcher, or prepend its bin directory to that session's PATH.
34
34
  Never overwrite another global `ez`; it may belong to a different installation.
package/docs/upgrades.md CHANGED
@@ -1,5 +1,10 @@
1
1
  # Agent-owned software upgrades
2
2
 
3
+ For an application's independently deployed frontend, backend or embedded gateway,
4
+ see [managed applications](managed-applications.md). They use their existing
5
+ deployment tools and a saved maintenance mandate; this package updater inventories
6
+ only core and registered plugins.
7
+
3
8
  Available in this beta. Earlier main upgrade/rollback VM QA passed; final-release
4
9
  fresh-host/reboot and live plugin upgrade acceptance remain pending. npm
5
10
  publication is not required to test this feature. The beta channel is the default
@@ -14,13 +19,18 @@ runs the normal CLI transport. It checks npm every six hours while running and
14
19
  queues an owner-bound maintenance turn only when an automatic channel changes.
15
20
  No owner means no maintenance executor. Normal user work and maintenance share
16
21
  one serial queue. Checks use the installed scoped npm identity; failures are
17
- visible in `updates check` and private `tools/updates/available.json`.
22
+ visible in `updates check` and private `tools/updates/available.json`. Plugins marked
23
+ `private: true` in their package metadata are reported as local-source updates
24
+ only, without querying public npm; this does not mean they are up to date.
25
+ Explicit local-file updates retain the existing release-contract checks; plugins
26
+ without that contract use their reviewed local-source installation procedure.
27
+ Public packages still receive discovery checks under a manual policy.
18
28
 
19
29
  ## Installation and scope
20
30
 
21
31
  Use normal setup and initialize the registry with this deployment's
22
32
  `host-executor.json`. This binds `ez updates`, the active package root and the
23
- Software updates guidance in TOOLS.md. Start `ezenciel-agents-host` using the
33
+ native registry discovery guidance in AGENTS.md. Start `ezenciel-agents-host` using the
24
34
  normal OS service template. The host service must use the existing user's Node,
25
35
  pnpm (or Corepack) and Docker access. Never put tokens in its environment. Keep the original
26
36
  package directory: its small bootstrap remains the service entry point and loads
@@ -185,11 +195,9 @@ written by the new one. Increment it for incompatible writes; this updater will
185
195
  refuse that migration. `mainProtocol` identifies the supported updater/registry
186
196
  contract, currently 1. Plugin package and manifest versions must match.
187
197
 
188
- The Luna/max durable default keeps this contract: persisted Codex Luna presets
189
- omit the effort field so older runtimes can read and fail over to their native
190
- safe default, while the current launcher resolves an omitted Luna effort to
191
- `max`. The execution choice, rather than the storage encoding, is the policy
192
- surface.
198
+ Explicit model/effort fields remain stored as selected. Unset values are no longer
199
+ filled by router policy; legacy records with omitted effort use native defaults.
200
+ Upgrading does not invent an explicit setting for an omitted field.
193
201
 
194
202
  Verify upgrade from the previous supported artifact, retained identity/state,
195
203
  failed-health rollback, and rejection of incompatible candidates. Main runtime
@@ -206,14 +214,31 @@ updaters need an exact-version core update to adopt this discovery behavior.
206
214
 
207
215
  ## Shared agent guidance
208
216
 
209
- Ez includes `templates/agent-guidance.md` from the running package in every
210
- owner-worker prompt, including resumed CLI and desktop conversations and scheduled
211
- owner work. After the runtime upgrades, the next turn receives the new guidance.
212
- An already running turn keeps its original prompt. Restricted contact tasks and
213
- reply-only workers retain their separate, bounded instructions.
214
-
215
- Keep general operating defaults in this package-owned file. Keep agent purpose,
216
- preferences and local conventions in the workspace's `AGENTS.md`, `SOUL.md`,
217
- `USER.md` and memory files; upgrades preserve them. Shared guidance does not
218
- grant permissions, and explicit owner instructions take precedence over its
219
- defaults within existing execution permissions.
217
+ Setup and runtime startup install `templates/agent-guidance.md` into a marked
218
+ section of the workspace's native `AGENTS.md` (and existing `AGENTS.override.md`).
219
+ Upgrade refreshes only that section; personal content outside it is preserved
220
+ byte-for-byte. New scheduled task workspaces receive the same shared guidance.
221
+ Malformed markers and symlinks fail visibly rather than overwriting personal work.
222
+
223
+ Codex, agy, Grok and OpenCode discover workspace instructions natively. Claude
224
+ receives the native `--append-system-prompt-file` binding to `AGENTS.md`, alongside
225
+ its own normal instructions. Fresh and resumed owner input is literal; ez does
226
+ not surround it with policies, tool recipes, repair instructions or history.
227
+ The native engine owns instruction loading and its context/token overhead.
228
+ Already running sessions retain their current context until native reload.
229
+
230
+ Desktop start/resume configuration binds the current run's sanitized environment;
231
+ message commands no longer require a prose environment prefix. Existing
232
+ credentials, permissions, queues, busy replies, scheduling and monitoring are
233
+ preserved. Restricted contact tasks retain their separate
234
+ bounded instruction scopes. For delivered busy replies absent from the native
235
+ conversation, the owner engine can call `ezenciel-agents-schedule context`.
236
+
237
+ Keep general defaults in the shipped shared file and identity/preferences in
238
+ workspace personal files. Instructions cannot grant permissions; explicit owner
239
+ requests take precedence within existing execution authority.
240
+
241
+ Update discovery runs independently of active host work. A discovery failure is
242
+ logged locally and retried at the next regular six-hour check; it does not stop
243
+ the host or create a repair task. Inspect `ez updates check` for target diagnostics.
244
+ Actual update transactions retain their existing admission, drain and rollback rules.
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@jc_stack/ez-agents",
3
- "version": "0.1.0-beta.26",
3
+ "version": "0.1.0-beta.28",
4
4
  "private": false,
5
5
  "type": "module",
6
6
  "description": "A lightweight foundation for persistent business AI assistants using existing AI harnesses, workspaces and plugins.",
@@ -21,7 +21,8 @@
21
21
  "ezenciel-agents-host": "bin/ezenciel-agents-host",
22
22
  "ezenciel-agents-tools": "bin/ezenciel-agents-tools.mjs",
23
23
  "ezenciel-agents-ai": "bin/ezenciel-agents-ai.mjs",
24
- "ezenciel-agents-watch": "bin/ezenciel-agents-watch.mjs"
24
+ "ezenciel-agents-watch": "bin/ezenciel-agents-watch.mjs",
25
+ "ezenciel-agents-application": "bin/ezenciel-agents-application.mjs"
25
26
  },
26
27
  "files": [
27
28
  "default-plugins.json",
@@ -51,8 +52,7 @@
51
52
  "scripts/assert-local-registry.mjs",
52
53
  ".dockerignore",
53
54
  "scripts/trusted-beta.mjs",
54
- "scripts/generate-publish-caller.mjs",
55
- "scripts/smoke-busy-reply.ts"
55
+ "scripts/generate-publish-caller.mjs"
56
56
  ],
57
57
  "publishConfig": {
58
58
  "access": "public",
@@ -112,5 +112,9 @@
112
112
  "kind": "main",
113
113
  "stateSchema": 1,
114
114
  "mainProtocol": 1
115
+ },
116
+ "exports": {
117
+ "./application-client": "./src/application-client.mjs",
118
+ "./*": "./*"
115
119
  }
116
120
  }
@@ -1,9 +1,38 @@
1
+ import { lstat, readFile, rename, rm, writeFile } from 'node:fs/promises'
2
+ import { randomUUID } from 'node:crypto'
3
+ import path from 'node:path'
1
4
  import { readFileSync } from 'node:fs'
2
5
 
3
6
  // Resolve against the installed package, never the agent's editable workspace.
4
7
  export const agentGuidance = (): string =>
5
8
  readFileSync(new URL('../templates/agent-guidance.md', import.meta.url), 'utf8').trim()
6
9
 
7
- // Channel behavior is shared without exposing owner workspace guidance to contacts.
8
- export const chatGuidance = (): string =>
9
- readFileSync(new URL('../templates/chat-guidance.md', import.meta.url), 'utf8').trim()
10
+ const start = '<!-- ez shared guidance: begin -->'
11
+ const end = '<!-- ez shared guidance: end -->'
12
+
13
+ // Native instruction installation, refreshed at setup/runtime upgrade, not per turn.
14
+ // Personal instructions outside this one managed block remain byte-for-byte intact.
15
+ export async function installAgentGuidance(workspace: string): Promise<void> {
16
+ for (const name of ['AGENTS.md', 'AGENTS.override.md']) {
17
+ const file = path.join(workspace, name)
18
+ let original: string
19
+ try {
20
+ if (!(await lstat(file)).isFile()) throw new Error(`Native instructions must be a regular file: ${file}`)
21
+ original = await readFile(file, 'utf8')
22
+ } catch (error) {
23
+ if ((error as NodeJS.ErrnoException).code === 'ENOENT') continue
24
+ throw error
25
+ }
26
+ const block = `${start}\n${agentGuidance()}\n${end}\n\n`
27
+ const from = original.indexOf(start), to = original.indexOf(end)
28
+ if ((from < 0) !== (to < 0) || (from >= 0 && (to < from || original.indexOf(start, from + start.length) >= 0 || original.indexOf(end, to + end.length) >= 0)))
29
+ throw new Error(`Malformed shared guidance block: ${file}`)
30
+ const updated = from < 0 ? block + original : original.slice(0, from) + block.trimEnd() + original.slice(to + end.length)
31
+ if (updated === original) continue
32
+ const temporary = `${file}.${randomUUID()}.tmp`
33
+ try {
34
+ await writeFile(temporary, updated, { mode: 0o600, flag: 'wx' })
35
+ await rename(temporary, file)
36
+ } finally { await rm(temporary, { force: true }) }
37
+ }
38
+ }
package/src/ai-cli.ts CHANGED
@@ -4,7 +4,11 @@ import { join } from 'node:path'
4
4
  import { readModels, validateSelection, type AiPreset } from './ai.js'
5
5
  import { ControlStore } from './control-state.js'
6
6
 
7
- const {values,positionals}=parseArgs({allowPositionals:true,options:{cli:{type:'string'},model:{type:'string'},effort:{type:'string'}}})
7
+ const {values,positionals}=parseArgs({allowPositionals:true,options:{help:{type:'boolean'},cli:{type:'string'},model:{type:'string'},effort:{type:'string'}}})
8
+ if(values.help){
9
+ console.log('Usage: ezenciel-agents-ai list | select --cli <installed-cli> [--model <model>] [--effort <effort>]\nChoose only values returned by list. Selection affects subsequent messages; queued work and the installation default are unchanged.')
10
+ process.exit(0)
11
+ }
8
12
  if (!process.env.EZ_CONTROL_DIR) throw new Error('Use this agent’s bound control directory')
9
13
  const catalog=await readModels(undefined,undefined,join(process.env.EZ_CONTROL_DIR,'cli','codex'))
10
14
  if(positionals[0]==='list')console.log(JSON.stringify(catalog))