@jc_stack/ez-agents 0.1.0-beta.27 → 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 (75) hide show
  1. package/.env.example +9 -0
  2. package/AGENTS.md +25 -1
  3. package/CHANGELOG.md +23 -0
  4. package/CONTRIBUTING.md +28 -0
  5. package/Dockerfile +1 -0
  6. package/README.md +79 -8
  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/docker-runtime.md +20 -0
  16. package/docs/managed-applications.md +68 -0
  17. package/docs/plugin-catalog.md +1 -0
  18. package/docs/plugin-connection.md +76 -0
  19. package/docs/plugins.md +40 -4
  20. package/docs/upgrades.md +11 -1
  21. package/package.json +7 -2
  22. package/src/application-channel.ts +308 -0
  23. package/src/application-cli.ts +41 -0
  24. package/src/application-client.mjs +87 -0
  25. package/src/application-origin.ts +15 -0
  26. package/src/codex-session.ts +5 -3
  27. package/src/config.ts +20 -2
  28. package/src/control-state.ts +256 -15
  29. package/src/conversation-menu.ts +89 -0
  30. package/src/delivery-context.d.mts +5 -0
  31. package/src/delivery-context.mjs +25 -0
  32. package/src/event-sources.ts +2 -2
  33. package/src/execution-authority.ts +2 -0
  34. package/src/executor.ts +10 -4
  35. package/src/host-executor.ts +7 -1
  36. package/src/identity.ts +11 -3
  37. package/src/index.ts +149 -54
  38. package/src/menu.ts +26 -9
  39. package/src/message-history.ts +52 -0
  40. package/src/message.ts +48 -7
  41. package/src/owner.ts +7 -1
  42. package/src/plugins/connection-artifacts.mjs +31 -0
  43. package/src/plugins/connection.mjs +124 -0
  44. package/src/plugins/manager.mjs +63 -18
  45. package/src/plugins/native-tasks.d.mts +4 -0
  46. package/src/plugins/native-tasks.mjs +66 -0
  47. package/src/plugins/workspace-lease.d.mts +3 -0
  48. package/src/plugins/workspace-lease.mjs +44 -0
  49. package/src/runs.ts +67 -9
  50. package/src/schedule-cli.ts +11 -6
  51. package/src/scheduler.ts +17 -7
  52. package/src/updates/control.mjs +4 -0
  53. package/src/web-launcher.ts +19 -0
  54. package/templates/agent-guidance.md +58 -2
  55. package/templates/deployments.md +24 -0
  56. package/test/application-channel.test.ts +283 -0
  57. package/test/application-client.test.mjs +84 -0
  58. package/test/application-controls.test.ts +224 -0
  59. package/test/application-only.test.ts +100 -0
  60. package/test/channel-delivery.test.ts +63 -0
  61. package/test/channel-owner.test.ts +161 -0
  62. package/test/codex-session.test.ts +8 -5
  63. package/test/config.test.ts +15 -0
  64. package/test/connection-artifacts.test.mjs +32 -0
  65. package/test/conversation-menu.test.ts +67 -0
  66. package/test/conversations.test.ts +84 -0
  67. package/test/executor.test.ts +56 -0
  68. package/test/host-executor.test.ts +28 -0
  69. package/test/intake-relay.test.ts +126 -5
  70. package/test/message-history.test.ts +127 -0
  71. package/test/native-tasks.test.ts +36 -0
  72. package/test/plugin-connection.test.mjs +124 -0
  73. package/test/plugin-manager.test.mjs +34 -0
  74. package/test/runtime-identity.test.mjs +18 -0
  75. package/test/updates.test.mjs +39 -0
@@ -0,0 +1,18 @@
1
+ import assert from 'node:assert/strict';
2
+ import {spawnSync} from 'node:child_process';
3
+ import test from 'node:test';
4
+
5
+ test('container identity rejects root, malformed IDs and shared relay/executor UID before startup', () => {
6
+ for (const overrides of [
7
+ {EZ_RUNTIME_UID:'0'}, {EZ_RUNTIME_GID:'0'}, {EZ_RELAY_UID:'0'},
8
+ {EZ_RUNTIME_UID:'-1'}, {EZ_RUNTIME_UID:'20001;id'},
9
+ {EZ_RUNTIME_UID:'020001'}, {EZ_RUNTIME_UID:'2147483648'},
10
+ {EZ_RUNTIME_UID:'99999999999999999999999999999'},
11
+ {EZ_RUNTIME_UID:'20001',EZ_RELAY_UID:'20001'},
12
+ ]) {
13
+ const result=spawnSync('sh',['docker/entrypoint.sh','exec','true'], {
14
+ encoding:'utf8', env:{PATH:process.env.PATH,EZ_RUNTIME_UID:'1000',EZ_RUNTIME_GID:'1000',EZ_RELAY_UID:'1001',...overrides},
15
+ });
16
+ assert.equal(result.status,64,JSON.stringify(overrides)+': '+result.stderr);
17
+ }
18
+ });
@@ -332,3 +332,42 @@ test('update discovery follows latest while preserving legacy beta and stable-on
332
332
  data.versions['0.2.0-beta.2'].name='@wrong/package';await assert.rejects(registryCandidate(name,'beta'),/identity|version mismatch/i);
333
333
  data.name='@wrong/package';await assert.rejects(registryCandidate(name,'beta'),/identity mismatch/i);
334
334
  });
335
+
336
+
337
+ test('private plugins skip npm discovery while private main builds and public manual targets still check',async t=>{
338
+ const f=await fixture(t,'plugin');
339
+ const pkg=await read(path.join(f.old,'package.json'));pkg.private=true;
340
+ await atomic(path.join(f.old,'package.json'),pkg);
341
+ const calls=[];const original=globalThis.fetch;
342
+ globalThis.fetch=async url=>{calls.push(String(url));return new Response(JSON.stringify({name:pkg.name,'dist-tags':{latest:'0.1.1'},versions:{'0.1.1':{name:pkg.name,version:'0.1.1'}}}));};
343
+ t.after(()=>globalThis.fetch=original);
344
+ const results=await command(f.home,['check']);
345
+ assert.equal(calls.length,1); // fixture main shares the package root; its private flag must not disable core discovery
346
+ assert.equal(results[0].target,'main');assert.equal(results[0].newer,true);
347
+ assert.deepEqual(results[1],{target:'sample',installed:'0.1.0',available:null,newer:false,policy:{automatic:true,channel:'beta'},package:pkg.name,updates:'Private plugin; public npm discovery unavailable. Use the reviewed local source.'});
348
+ for(const privacy of [false,undefined]) {
349
+ if(privacy===undefined)delete pkg.private;else pkg.private=privacy;
350
+ await atomic(path.join(f.old,'package.json'),pkg);
351
+ await command(f.home,['policy','sample','manual']);calls.length=0;
352
+ const checked=await command(f.home,['check']);assert.equal(calls.length,2);
353
+ assert.equal(checked[1].newer,true);assert.equal(checked[1].policy.automatic,false);
354
+ }
355
+ for(const failure of [404,401,'network']) {
356
+ globalThis.fetch=async()=>{if(failure==='network')throw Error('network unavailable');return new Response('',{status:failure});};
357
+ const checked=await command(f.home,['check']);
358
+ assert.equal(checked[1].error,failure==='network'?'network unavailable':`npm metadata unavailable (${failure})`);
359
+ }
360
+ });
361
+
362
+ test('private plugins retain explicit local-file preparation and application guards',async t=>{
363
+ const f=await fixture(t,'plugin');
364
+ for(const root of [f.old,f.source]) {
365
+ const pkg=await read(path.join(root,'package.json'));pkg.private=true;await atomic(path.join(root,'package.json'),pkg);
366
+ }
367
+ const job=await prepare(f.home,f.target,{file:await f.pack()});
368
+ assert.equal(job.status,'prepared');assert.equal(job.version,'0.1.1');
369
+ await atomic(path.join(f.home,'updates/supervisor.json'),{at:Date.now()});
370
+ await assert.rejects(submit(f.home,job.id,true),/Local candidates require an explicit upgrade request/);
371
+ const submitted=await submit(f.home,job.id,false);assert.equal(submitted.status,'queued');
372
+ const result=await perform(f.home,submitted,runtime(f));assert.equal(result.status,'completed');
373
+ });