@rebon/cli-win32-x64 1.2.0 → 1.4.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (98) hide show
  1. package/LICENSE +202 -0
  2. package/NOTICE +10 -0
  3. package/README.md +203 -144
  4. package/THIRD_PARTY_NOTICES.txt +1232 -128
  5. package/bin/rebon.js +22 -22
  6. package/lib/windows-managed.js +390 -390
  7. package/package.json +9 -2
  8. package/payload/compose-runtime/package.json +17 -17
  9. package/payload/compose-runtime/payload/compose/shims/dsh-anonymous-user-id.js +10 -10
  10. package/payload/compose-runtime/payload/compose/shims/dsh-credentials.js +13 -13
  11. package/payload/compose-runtime/payload/compose/shims/dsh-launch-environment.js +21 -21
  12. package/payload/compose-runtime/payload/compose/shims/dsh-llm.js +313 -313
  13. package/payload/compose-runtime/payload/compose/shims/dsh-settings.js +43 -43
  14. package/payload/compose-runtime/payload/compose/shims/dsh-tools.js +20 -20
  15. package/payload/compose-runtime/payload/compose/shims/dsh-web.js +10 -10
  16. package/payload/compose-runtime/payload/compose/shims/llm-adapter.js +32 -32
  17. package/payload/compose-runtime/payload/compose/shims/zod-lite.js +49 -49
  18. package/payload/compose-runtime/payload/vendor/cordis/LICENSE +21 -0
  19. package/payload/compose-runtime/payload/vendor/cordis/index.js +1530 -1530
  20. package/payload/compose-runtime/payload/vendor/cosmokit/LICENSE +21 -21
  21. package/payload/compose-runtime/payload/vendor/cosmokit/index.mjs +357 -357
  22. package/payload/compose-runtime/payload/vendor/dsh/LICENSE-agent +21 -21
  23. package/payload/compose-runtime/payload/vendor/dsh/LICENSE-agent-loop +21 -21
  24. package/payload/compose-runtime/payload/vendor/dsh/LICENSE-llm-core +21 -21
  25. package/payload/compose-runtime/payload/vendor/dsh/LICENSE-llm-deepseek +21 -21
  26. package/payload/compose-runtime/payload/vendor/dsh/LICENSE-logger-console +21 -21
  27. package/payload/compose-runtime/payload/vendor/dsh/LICENSE-scope +21 -21
  28. package/payload/compose-runtime/payload/vendor/dsh/LICENSE-session +21 -21
  29. package/payload/compose-runtime/payload/vendor/dsh/LICENSE-system-prompt +21 -21
  30. package/payload/compose-runtime/payload/vendor/dsh/LICENSE-timeout +21 -21
  31. package/payload/compose-runtime/payload/vendor/dsh/LICENSE-timer +21 -21
  32. package/payload/compose-runtime/payload/vendor/dsh/LICENSE-tool-todo +21 -21
  33. package/payload/compose-runtime/payload/vendor/dsh/LICENSE-tool-web +21 -21
  34. package/payload/compose-runtime/payload/vendor/dsh/LICENSE-tools-schema +21 -21
  35. package/payload/compose-runtime/payload/vendor/dsh/LICENSE-turndown +21 -0
  36. package/payload/compose-runtime/payload/vendor/dsh/LICENSE-turndown-plugin-gfm +21 -0
  37. package/payload/compose-runtime/payload/vendor/dsh/LICENSE-web-search-exa +21 -21
  38. package/payload/compose-runtime/payload/vendor/dsh/agent-loop.js +1193 -1193
  39. package/payload/compose-runtime/payload/vendor/dsh/agent.js +714 -714
  40. package/payload/compose-runtime/payload/vendor/dsh/llm-core.js +269 -269
  41. package/payload/compose-runtime/payload/vendor/dsh/llm-deepseek.js +672 -672
  42. package/payload/compose-runtime/payload/vendor/dsh/logger-console.js +83 -83
  43. package/payload/compose-runtime/payload/vendor/dsh/scope.js +287 -287
  44. package/payload/compose-runtime/payload/vendor/dsh/session.js +1668 -1668
  45. package/payload/compose-runtime/payload/vendor/dsh/system-prompt.js +309 -309
  46. package/payload/compose-runtime/payload/vendor/dsh/timeout.js +100 -100
  47. package/payload/compose-runtime/payload/vendor/dsh/timer.js +128 -128
  48. package/payload/compose-runtime/payload/vendor/dsh/tool-todo.js +143 -143
  49. package/payload/compose-runtime/payload/vendor/dsh/tool-web.js +1527 -1527
  50. package/payload/compose-runtime/payload/vendor/dsh/tools-schema.js +849 -849
  51. package/payload/compose-runtime/payload/vendor/dsh/web-search-exa.js +122 -122
  52. package/payload/compose-runtime/payload/vendor/eventsource-parser/LICENSE +21 -21
  53. package/payload/compose-runtime/payload/vendor/eventsource-parser/index.js +177 -177
  54. package/payload/compose-runtime/payload/vendor/eventsource-parser/stream.js +48 -48
  55. package/payload/compose-runtime/payload/vendor/schemastery/LICENSE +21 -0
  56. package/payload/compose-runtime/payload/vendor/schemastery/index.mjs +656 -656
  57. package/payload/compose-runtime/payload-manifests.json +48 -48
  58. package/payload/compose-runtime/src/bridge.mjs +193 -195
  59. package/payload/compose-runtime/src/credentials-runtime.mjs +50 -50
  60. package/payload/compose-runtime/src/eventsource-stream.mjs +48 -48
  61. package/payload/compose-runtime/src/index.mjs +7 -7
  62. package/payload/compose-runtime/src/llm-runtime.mjs +326 -326
  63. package/payload/compose-runtime/src/loader.mjs +78 -78
  64. package/payload/compose-runtime/src/loop-assembly.mjs +237 -237
  65. package/payload/compose-runtime/src/payload.mjs +49 -49
  66. package/payload/compose-runtime/src/plugin.mjs +59 -59
  67. package/payload/compose-runtime/src/realm.mjs +223 -223
  68. package/payload/compose-runtime/src/registry.mjs +191 -191
  69. package/payload/compose-runtime/src/resolve.mjs +115 -115
  70. package/payload/compose-runtime/src/systemprompt-runtime.mjs +67 -67
  71. package/payload/compose-runtime/src/tools-runtime.mjs +239 -239
  72. package/payload/compose-runtime/src/web-runtime.mjs +209 -209
  73. package/payload/plugin-host/package.json +11 -11
  74. package/payload/plugin-host/src/bridge.mjs +64 -64
  75. package/payload/plugin-host/src/cli.mjs +147 -147
  76. package/payload/plugin-host/src/framing.mjs +113 -113
  77. package/payload/plugin-host/src/host.mjs +691 -691
  78. package/payload/plugin-host/src/json.mjs +208 -208
  79. package/payload/plugin-host/src/lifecycle.mjs +114 -114
  80. package/payload/plugin-host/src/loader.mjs +183 -183
  81. package/payload/plugin-host/src/methods.mjs +377 -377
  82. package/payload/plugin-host/src/ownership.mjs +57 -57
  83. package/payload/plugin-host/src/protocol.mjs +129 -129
  84. package/payload/plugin-host/src/sdk.mjs +7 -7
  85. package/payload/rebon-boa-helper.exe +0 -0
  86. package/payload/rebon-browser-mcp.exe +0 -0
  87. package/payload/rebon-computer-use.exe +0 -0
  88. package/payload/rebon-lsp-mcp.exe +0 -0
  89. package/payload/rebon.exe +2 -2
  90. package/payload/sandbox-win.exe +0 -0
  91. package/scripts/postinstall.js +112 -112
  92. package/payload/compose-runtime/payload/compose/credentials-runtime.js +0 -38
  93. package/payload/compose-runtime/payload/compose/llm-runtime.js +0 -330
  94. package/payload/compose-runtime/payload/compose/loop-assembly.js +0 -149
  95. package/payload/compose-runtime/payload/compose/serve-dispatch.js +0 -82
  96. package/payload/compose-runtime/payload/compose/systemprompt-runtime.js +0 -74
  97. package/payload/compose-runtime/payload/compose/tools-runtime.js +0 -228
  98. package/payload/compose-runtime/payload/compose/web-runtime.js +0 -204
@@ -1,57 +1,57 @@
1
- // Which entry a stray promise belonged to.
2
- //
3
- // Node does not stop this process for an unhandled rejection, and before T20
4
- // nothing looked either: a plugin could start an async task, have it fail, and
5
- // leave no trace anywhere rebon reads. T20 made it visible but unattributed,
6
- // on the belief that a failed promise cannot say who created it.
7
- //
8
- // Measured on Node 24.19.0, it can. An `AsyncLocalStorage` store survives
9
- // `setTimeout`, `queueMicrotask` and `await`, and the `unhandledRejection`
10
- // handler reads it directly — so wrapping each `plugin/load` is enough, with no
11
- // per-promise `async_hooks` and therefore no standing cost.
12
- //
13
- // **The store follows the async chain, not the clock**, and that distinction is
14
- // the whole reason `loading` exists. A timer started during `apply` that
15
- // rejects ten seconds later still carries its entry, long after that load
16
- // returned. So there are two questions, not one:
17
- //
18
- // * whose is it — `entry`, always, whenever the chain reaches back;
19
- // * does it fail the load — `loading`, true only while the load is in flight,
20
- // because a load that already succeeded cannot be un-failed.
21
- //
22
- // The flag is flipped on the same object rather than by entering a second
23
- // store: a new store would not be seen by promises already rooted in the first.
24
- import { AsyncLocalStorage } from 'node:async_hooks';
25
-
26
- const owners = new AsyncLocalStorage();
27
-
28
- /// Runs `fn` as `entry`'s work, with the load marked in flight for its
29
- /// duration. Returns whatever `fn` returns; the flag is cleared either way,
30
- /// because a load that threw is over too.
31
- export async function asEntryLoad(entry, fn) {
32
- const store = { entry, loading: true };
33
- try {
34
- const value = await owners.run(store, fn);
35
- // One turn of the loop before deciding. `unhandledRejection` fires after
36
- // the microtask queue drains, so a task this load started that failed
37
- // immediately has not been reported yet at the moment `fn` resolves —
38
- // checking without this yield would call a broken load a good one.
39
- await new Promise((resolve) => setImmediate(resolve));
40
- if (store.rejection !== undefined) {
41
- throw new Error(`[ENTRY_FAILED] ${entry} left a rejection unhandled while loading: ${store.rejection}`);
42
- }
43
- return value;
44
- } finally {
45
- store.loading = false;
46
- }
47
- }
48
-
49
- /// The entry whose async chain this code is on, or `undefined` outside one.
50
- ///
51
- /// Undefined is normal and not a failure: a rejection can escape the chain
52
- /// through an `EventEmitter`, a native callback or a third-party library, and
53
- /// "could not be determined" is a truthful answer worth keeping distinct from a
54
- /// wrong one.
55
- export function currentOwner() {
56
- return owners.getStore();
57
- }
1
+ // Which entry a stray promise belonged to.
2
+ //
3
+ // Node does not stop this process for an unhandled rejection, and nothing else
4
+ // looks either: a plugin could start an async task, have it fail, and leave no
5
+ // trace anywhere rebon reads. Making it visible is not the same as attributing
6
+ // it — a failed promise does not carry who created it.
7
+ //
8
+ // Measured on Node 24.19.0, an `AsyncLocalStorage` store survives
9
+ // `setTimeout`, `queueMicrotask` and `await`, and the `unhandledRejection`
10
+ // handler reads it directly — so wrapping each `plugin/load` is enough, with no
11
+ // per-promise `async_hooks` and therefore no standing cost.
12
+ //
13
+ // **The store follows the async chain, not the clock**, and that distinction is
14
+ // the whole reason `loading` exists. A timer started during `apply` that
15
+ // rejects ten seconds later still carries its entry, long after that load
16
+ // returned. So there are two questions, not one:
17
+ //
18
+ // * whose is it — `entry`, always, whenever the chain reaches back;
19
+ // * does it fail the load — `loading`, true only while the load is in flight,
20
+ // because a load that already succeeded cannot be un-failed.
21
+ //
22
+ // The flag is flipped on the same object rather than by entering a second
23
+ // store: a new store would not be seen by promises already rooted in the first.
24
+ import { AsyncLocalStorage } from 'node:async_hooks';
25
+
26
+ const owners = new AsyncLocalStorage();
27
+
28
+ /// Runs `fn` as `entry`'s work, with the load marked in flight for its
29
+ /// duration. Returns whatever `fn` returns; the flag is cleared either way,
30
+ /// because a load that threw is over too.
31
+ export async function asEntryLoad(entry, fn) {
32
+ const store = { entry, loading: true };
33
+ try {
34
+ const value = await owners.run(store, fn);
35
+ // One turn of the loop before deciding. `unhandledRejection` fires after
36
+ // the microtask queue drains, so a task this load started that failed
37
+ // immediately has not been reported yet at the moment `fn` resolves —
38
+ // checking without this yield would call a broken load a good one.
39
+ await new Promise((resolve) => setImmediate(resolve));
40
+ if (store.rejection !== undefined) {
41
+ throw new Error(`[ENTRY_FAILED] ${entry} left a rejection unhandled while loading: ${store.rejection}`);
42
+ }
43
+ return value;
44
+ } finally {
45
+ store.loading = false;
46
+ }
47
+ }
48
+
49
+ /// The entry whose async chain this code is on, or `undefined` outside one.
50
+ ///
51
+ /// Undefined is normal and not a failure: a rejection can escape the chain
52
+ /// through an `EventEmitter`, a native callback or a third-party library, and
53
+ /// "could not be determined" is a truthful answer worth keeping distinct from a
54
+ /// wrong one.
55
+ export function currentOwner() {
56
+ return owners.getStore();
57
+ }
@@ -1,129 +1,129 @@
1
- export const PROTOCOL_VERSION = 1;
2
- export const MAX_FRAME_BYTES = 8 * 1024 * 1024;
3
- export const MAX_SAFE_WIRE_INTEGER = Number.MAX_SAFE_INTEGER;
4
- export const PLATFORM_PLUGIN_ID = '$rebon/platform';
5
- export const PLATFORM_CONTROL_SCOPE_ID = '$rebon/control';
6
- export const PLATFORM_CONTROL_GENERATION = 0;
7
- export const CALL_CANCEL_METHOD = 'call/cancel';
8
-
9
- export class ProtocolError extends Error {
10
- constructor(code, message) { super(message); this.name = 'ProtocolError'; this.code = code; }
11
- }
12
-
13
- export class RawJsonNumber {
14
- constructor(raw) { this.raw = raw; Object.freeze(this); }
15
- valueOf() { return Number(this.raw); }
16
- toJSON() { throw new ProtocolError('raw_number', 'raw JSON number cannot be emitted without an explicit schema conversion'); }
17
- }
18
-
19
- const own = (value, key) => Object.prototype.hasOwnProperty.call(value, key);
20
- export const plain = (value) => value !== null && typeof value === 'object' && !Array.isArray(value)
21
- && (Object.getPrototypeOf(value) === Object.prototype || Object.getPrototypeOf(value) === null);
22
-
23
- function exact(value, keys, where) {
24
- if (!plain(value)) throw new ProtocolError('wrong_shape', `${where} must be a plain object`);
25
- const actual = Object.keys(value).sort();
26
- const expected = [...keys].sort();
27
- if (actual.length !== expected.length || actual.some((key, index) => key !== expected[index])) {
28
- throw new ProtocolError('unknown_field', `${where} must have exactly: ${expected.join(', ')}`);
29
- }
30
- for (const key of expected) if (!own(value, key)) throw new ProtocolError('wrong_shape', `${where}.${key} is required`);
31
- }
32
-
33
- function wireInteger(value, field) {
34
- if (!Number.isSafeInteger(value) || value < 0) throw new ProtocolError('unsafe_integer', `${field} must be a safe non-negative integer`);
35
- return Object.is(value, -0) ? 0 : value;
36
- }
37
- function string(value, field) {
38
- if (typeof value !== 'string') throw new ProtocolError('wrong_shape', `${field} must be a string`);
39
- return value;
40
- }
41
- function cloneJson(value, seen = new Set()) {
42
- if (value instanceof RawJsonNumber) return value;
43
- if (value === null || typeof value === 'string' || typeof value === 'boolean') return value;
44
- if (typeof value === 'number') {
45
- if (!Number.isFinite(value)) throw new ProtocolError('invalid_payload', 'payload numbers must be finite JSON numbers');
46
- return Object.is(value, -0) ? 0 : value;
47
- }
48
- if (typeof value !== 'object') throw new ProtocolError('invalid_payload', 'payload must be JSON-compatible');
49
- if (seen.has(value)) throw new ProtocolError('invalid_payload', 'payload must not be cyclic');
50
- seen.add(value);
51
- let copy;
52
- if (Array.isArray(value)) copy = value.map((item) => cloneJson(item, seen));
53
- else {
54
- if (!plain(value)) throw new ProtocolError('invalid_payload', 'payload objects must have a plain prototype');
55
- copy = Object.create(null);
56
- for (const key of Object.keys(value)) copy[key] = cloneJson(value[key], seen);
57
- }
58
- seen.delete(value);
59
- return Object.freeze(copy);
60
- }
61
-
62
- /// Every name a message object may carry, whatever its variant.
63
- const MESSAGE_FIELDS = ['type', 'method', 'status', 'payload'];
64
-
65
- /// Checks a message object in the order the other language does.
66
- ///
67
- /// The order is the contract, not an implementation detail. A name nobody knows
68
- /// is refused before the variant is even decided; then the fields every variant
69
- /// needs; only then a name that is real but belongs to a different variant.
70
- /// Collapsing these into one set comparison would report "you left out payload"
71
- /// as "unknown field", which sends a sender to the wrong place — and would say
72
- /// something different from the Rust side for the same bytes.
73
- function messageShape(message, fields) {
74
- if (!plain(message)) throw new ProtocolError('wrong_shape', 'message must be a plain object');
75
- for (const key of Object.keys(message)) {
76
- if (!MESSAGE_FIELDS.includes(key)) throw new ProtocolError('unknown_field', `message has unknown field ${JSON.stringify(key)}`);
77
- }
78
- for (const key of ['type', 'payload']) {
79
- if (!own(message, key)) throw new ProtocolError('wrong_shape', `message.${key} is required`);
80
- }
81
- for (const key of Object.keys(message)) {
82
- if (!fields.includes(key)) throw new ProtocolError('unknown_field', `message must have exactly: ${[...fields].sort().join(', ')}`);
83
- }
84
- for (const key of fields) {
85
- if (!own(message, key)) throw new ProtocolError('wrong_shape', `message.${key} is required`);
86
- }
87
- }
88
-
89
- export function validateEnvelope(input) {
90
- exact(input, ['protocol_version','host_epoch','plugin_id','scope_id','scope_generation','call_id','message'], 'envelope');
91
- if (input.protocol_version !== PROTOCOL_VERSION) throw new ProtocolError('bad_version', `protocol_version must be ${PROTOCOL_VERSION}`);
92
- const type = plain(input.message) ? input.message.type : undefined;
93
- // A chunk carries no method: it belongs to the call whose identity it rides,
94
- // and that call's method already said what it means.
95
- const fields = type === 'terminal' ? ['type','status','payload']
96
- : type === 'chunk' ? ['type','payload']
97
- : ['type','method','payload'];
98
- if (!['request','terminal','notification','chunk'].includes(type)) throw new ProtocolError('wrong_shape', 'message.type is invalid');
99
- messageShape(input.message, fields);
100
- const message = type === 'terminal'
101
- ? Object.freeze({ type, status: terminalStatus(input.message.status), payload: cloneJson(input.message.payload) })
102
- : type === 'chunk'
103
- ? Object.freeze({ type, payload: cloneJson(input.message.payload) })
104
- : Object.freeze({ type, method: string(input.message.method, 'message.method'), payload: cloneJson(input.message.payload) });
105
- return Object.freeze({
106
- protocol_version: PROTOCOL_VERSION,
107
- host_epoch: wireInteger(input.host_epoch, 'host_epoch'),
108
- plugin_id: string(input.plugin_id, 'plugin_id'),
109
- scope_id: string(input.scope_id, 'scope_id'),
110
- scope_generation: wireInteger(input.scope_generation, 'scope_generation'),
111
- call_id: string(input.call_id, 'call_id'),
112
- message,
113
- });
114
- }
115
- function terminalStatus(status) {
116
- if (!['success','error','cancelled'].includes(status)) throw new ProtocolError('bad_status', 'terminal status is invalid');
117
- return status;
118
- }
119
- export function identityOf(envelope) {
120
- return Object.freeze({ host_epoch: envelope.host_epoch, plugin_id: envelope.plugin_id, scope_id: envelope.scope_id,
121
- scope_generation: envelope.scope_generation, call_id: envelope.call_id });
122
- }
123
- export function envelope(identity, message) { return validateEnvelope({ protocol_version: PROTOCOL_VERSION, ...identity, message }); }
124
- export function terminal(identity, status, payload) { return envelope(identity, { type: 'terminal', status, payload }); }
125
- export function request(identity, method, payload) { return envelope(identity, { type: 'request', method, payload }); }
126
- export function notification(identity, method, payload) { return envelope(identity, { type: 'notification', method, payload }); }
127
- export function chunk(identity, payload) { return envelope(identity, { type: 'chunk', payload }); }
128
- export function cancel(target) { return notification(target, CALL_CANCEL_METHOD, null); }
129
- export function isPlatformControl(value) { return value.plugin_id === PLATFORM_PLUGIN_ID && value.scope_id === PLATFORM_CONTROL_SCOPE_ID && value.scope_generation === 0; }
1
+ export const PROTOCOL_VERSION = 1;
2
+ export const MAX_FRAME_BYTES = 8 * 1024 * 1024;
3
+ export const MAX_SAFE_WIRE_INTEGER = Number.MAX_SAFE_INTEGER;
4
+ export const PLATFORM_PLUGIN_ID = '$rebon/platform';
5
+ export const PLATFORM_CONTROL_SCOPE_ID = '$rebon/control';
6
+ export const PLATFORM_CONTROL_GENERATION = 0;
7
+ export const CALL_CANCEL_METHOD = 'call/cancel';
8
+
9
+ export class ProtocolError extends Error {
10
+ constructor(code, message) { super(message); this.name = 'ProtocolError'; this.code = code; }
11
+ }
12
+
13
+ export class RawJsonNumber {
14
+ constructor(raw) { this.raw = raw; Object.freeze(this); }
15
+ valueOf() { return Number(this.raw); }
16
+ toJSON() { throw new ProtocolError('raw_number', 'raw JSON number cannot be emitted without an explicit schema conversion'); }
17
+ }
18
+
19
+ const own = (value, key) => Object.prototype.hasOwnProperty.call(value, key);
20
+ export const plain = (value) => value !== null && typeof value === 'object' && !Array.isArray(value)
21
+ && (Object.getPrototypeOf(value) === Object.prototype || Object.getPrototypeOf(value) === null);
22
+
23
+ function exact(value, keys, where) {
24
+ if (!plain(value)) throw new ProtocolError('wrong_shape', `${where} must be a plain object`);
25
+ const actual = Object.keys(value).sort();
26
+ const expected = [...keys].sort();
27
+ if (actual.length !== expected.length || actual.some((key, index) => key !== expected[index])) {
28
+ throw new ProtocolError('unknown_field', `${where} must have exactly: ${expected.join(', ')}`);
29
+ }
30
+ for (const key of expected) if (!own(value, key)) throw new ProtocolError('wrong_shape', `${where}.${key} is required`);
31
+ }
32
+
33
+ function wireInteger(value, field) {
34
+ if (!Number.isSafeInteger(value) || value < 0) throw new ProtocolError('unsafe_integer', `${field} must be a safe non-negative integer`);
35
+ return Object.is(value, -0) ? 0 : value;
36
+ }
37
+ function string(value, field) {
38
+ if (typeof value !== 'string') throw new ProtocolError('wrong_shape', `${field} must be a string`);
39
+ return value;
40
+ }
41
+ function cloneJson(value, seen = new Set()) {
42
+ if (value instanceof RawJsonNumber) return value;
43
+ if (value === null || typeof value === 'string' || typeof value === 'boolean') return value;
44
+ if (typeof value === 'number') {
45
+ if (!Number.isFinite(value)) throw new ProtocolError('invalid_payload', 'payload numbers must be finite JSON numbers');
46
+ return Object.is(value, -0) ? 0 : value;
47
+ }
48
+ if (typeof value !== 'object') throw new ProtocolError('invalid_payload', 'payload must be JSON-compatible');
49
+ if (seen.has(value)) throw new ProtocolError('invalid_payload', 'payload must not be cyclic');
50
+ seen.add(value);
51
+ let copy;
52
+ if (Array.isArray(value)) copy = value.map((item) => cloneJson(item, seen));
53
+ else {
54
+ if (!plain(value)) throw new ProtocolError('invalid_payload', 'payload objects must have a plain prototype');
55
+ copy = Object.create(null);
56
+ for (const key of Object.keys(value)) copy[key] = cloneJson(value[key], seen);
57
+ }
58
+ seen.delete(value);
59
+ return Object.freeze(copy);
60
+ }
61
+
62
+ /// Every name a message object may carry, whatever its variant.
63
+ const MESSAGE_FIELDS = ['type', 'method', 'status', 'payload'];
64
+
65
+ /// Checks a message object in the order the other language does.
66
+ ///
67
+ /// The order is the contract, not an implementation detail. A name nobody knows
68
+ /// is refused before the variant is even decided; then the fields every variant
69
+ /// needs; only then a name that is real but belongs to a different variant.
70
+ /// Collapsing these into one set comparison would report "you left out payload"
71
+ /// as "unknown field", which sends a sender to the wrong place — and would say
72
+ /// something different from the Rust side for the same bytes.
73
+ function messageShape(message, fields) {
74
+ if (!plain(message)) throw new ProtocolError('wrong_shape', 'message must be a plain object');
75
+ for (const key of Object.keys(message)) {
76
+ if (!MESSAGE_FIELDS.includes(key)) throw new ProtocolError('unknown_field', `message has unknown field ${JSON.stringify(key)}`);
77
+ }
78
+ for (const key of ['type', 'payload']) {
79
+ if (!own(message, key)) throw new ProtocolError('wrong_shape', `message.${key} is required`);
80
+ }
81
+ for (const key of Object.keys(message)) {
82
+ if (!fields.includes(key)) throw new ProtocolError('unknown_field', `message must have exactly: ${[...fields].sort().join(', ')}`);
83
+ }
84
+ for (const key of fields) {
85
+ if (!own(message, key)) throw new ProtocolError('wrong_shape', `message.${key} is required`);
86
+ }
87
+ }
88
+
89
+ export function validateEnvelope(input) {
90
+ exact(input, ['protocol_version','host_epoch','plugin_id','scope_id','scope_generation','call_id','message'], 'envelope');
91
+ if (input.protocol_version !== PROTOCOL_VERSION) throw new ProtocolError('bad_version', `protocol_version must be ${PROTOCOL_VERSION}`);
92
+ const type = plain(input.message) ? input.message.type : undefined;
93
+ // A chunk carries no method: it belongs to the call whose identity it rides,
94
+ // and that call's method already said what it means.
95
+ const fields = type === 'terminal' ? ['type','status','payload']
96
+ : type === 'chunk' ? ['type','payload']
97
+ : ['type','method','payload'];
98
+ if (!['request','terminal','notification','chunk'].includes(type)) throw new ProtocolError('wrong_shape', 'message.type is invalid');
99
+ messageShape(input.message, fields);
100
+ const message = type === 'terminal'
101
+ ? Object.freeze({ type, status: terminalStatus(input.message.status), payload: cloneJson(input.message.payload) })
102
+ : type === 'chunk'
103
+ ? Object.freeze({ type, payload: cloneJson(input.message.payload) })
104
+ : Object.freeze({ type, method: string(input.message.method, 'message.method'), payload: cloneJson(input.message.payload) });
105
+ return Object.freeze({
106
+ protocol_version: PROTOCOL_VERSION,
107
+ host_epoch: wireInteger(input.host_epoch, 'host_epoch'),
108
+ plugin_id: string(input.plugin_id, 'plugin_id'),
109
+ scope_id: string(input.scope_id, 'scope_id'),
110
+ scope_generation: wireInteger(input.scope_generation, 'scope_generation'),
111
+ call_id: string(input.call_id, 'call_id'),
112
+ message,
113
+ });
114
+ }
115
+ function terminalStatus(status) {
116
+ if (!['success','error','cancelled'].includes(status)) throw new ProtocolError('bad_status', 'terminal status is invalid');
117
+ return status;
118
+ }
119
+ export function identityOf(envelope) {
120
+ return Object.freeze({ host_epoch: envelope.host_epoch, plugin_id: envelope.plugin_id, scope_id: envelope.scope_id,
121
+ scope_generation: envelope.scope_generation, call_id: envelope.call_id });
122
+ }
123
+ export function envelope(identity, message) { return validateEnvelope({ protocol_version: PROTOCOL_VERSION, ...identity, message }); }
124
+ export function terminal(identity, status, payload) { return envelope(identity, { type: 'terminal', status, payload }); }
125
+ export function request(identity, method, payload) { return envelope(identity, { type: 'request', method, payload }); }
126
+ export function notification(identity, method, payload) { return envelope(identity, { type: 'notification', method, payload }); }
127
+ export function chunk(identity, payload) { return envelope(identity, { type: 'chunk', payload }); }
128
+ export function cancel(target) { return notification(target, CALL_CANCEL_METHOD, null); }
129
+ export function isPlatformControl(value) { return value.plugin_id === PLATFORM_PLUGIN_ID && value.scope_id === PLATFORM_CONTROL_SCOPE_ID && value.scope_generation === 0; }
@@ -1,7 +1,7 @@
1
- export function createPluginApi(boundBridge) {
2
- if (!boundBridge || typeof boundBridge.call !== 'function' || typeof boundBridge.notify !== 'function') throw new TypeError('boundBridge is invalid');
3
- return Object.freeze({
4
- call(method, payload, options = {}) { return boundBridge.call(method, payload, options); },
5
- notify(method, payload) { return boundBridge.notify(method, payload); },
6
- });
7
- }
1
+ export function createPluginApi(boundBridge) {
2
+ if (!boundBridge || typeof boundBridge.call !== 'function' || typeof boundBridge.notify !== 'function') throw new TypeError('boundBridge is invalid');
3
+ return Object.freeze({
4
+ call(method, payload, options = {}) { return boundBridge.call(method, payload, options); },
5
+ notify(method, payload) { return boundBridge.notify(method, payload); },
6
+ });
7
+ }
Binary file
Binary file
Binary file
Binary file
package/payload/rebon.exe CHANGED
@@ -1,4 +1,4 @@
1
1
  [diffend] Oversized file quarantined before diffing.
2
2
  name: package/payload/rebon.exe
3
- size: 71994880 bytes
4
- sha256: 8bc368970303b3d0410c6d7905dc50bd4945260160c45d38859c4602e2ddaa7a
3
+ size: 73743360 bytes
4
+ sha256: 06ad89a7bfb9c17c8b5731da3069a8a08e0d05366d13a0bd4eab86a7ba526cf6
Binary file
@@ -1,112 +1,112 @@
1
- "use strict";
2
-
3
- const childProcess = require("child_process");
4
- const fs = require("fs");
5
- const path = require("path");
6
-
7
- const INSTALL_SUPERVISOR_ENV = "REBON_INSTALL_SUPERVISOR";
8
-
9
- function log(message) {
10
- console.log(`[rebon postinstall] ${message}`);
11
- }
12
-
13
- function envFlagEnabled(value) {
14
- return /^(1|true|yes|on)$/i.test(String(value || "").trim());
15
- }
16
-
17
- function supervisorHintMessage() {
18
- return "background supervisor scheduler was not registered; run `rebon agents service install` to keep queued jobs moving after login, or set REBON_INSTALL_SUPERVISOR=1 before install to opt in.";
19
- }
20
-
21
- function packageRootFromScript() {
22
- return path.resolve(__dirname, "..");
23
- }
24
-
25
- function installWindowsPayload(packageRoot) {
26
- const {
27
- installManagedPackage,
28
- readPackageInfo,
29
- requireManagedBinDir,
30
- } = require("../lib/windows-managed");
31
-
32
- requireManagedBinDir();
33
- const packageInfo = readPackageInfo(packageRoot);
34
- if (!fs.existsSync(packageInfo.payloadPath)) {
35
- throw new Error(`payload executable is missing: ${packageInfo.payloadPath}`);
36
- }
37
-
38
- const managedExe = installManagedPackage(packageInfo);
39
- if (!managedExe) {
40
- throw new Error("could not install payload executable into managed bin directory");
41
- }
42
- return managedExe;
43
- }
44
-
45
- function packageExecutable(packageRoot, platform) {
46
- if (platform === "win32") {
47
- return installWindowsPayload(packageRoot);
48
- }
49
-
50
- const exePath = path.join(packageRoot, "bin", "rebon");
51
- if (!fs.existsSync(exePath)) {
52
- throw new Error(`payload executable is missing: ${exePath}`);
53
- }
54
-
55
- try {
56
- fs.chmodSync(exePath, 0o755);
57
- } catch (_) {
58
- }
59
- return exePath;
60
- }
61
-
62
- function installSupervisorScheduler(exePath, spawnSyncImpl) {
63
- const result = spawnSyncImpl(exePath, ["agents", "service", "install"], {
64
- stdio: "inherit",
65
- windowsHide: true,
66
- });
67
-
68
- if (result.error) {
69
- throw result.error;
70
- }
71
- if (result.status !== 0) {
72
- throw new Error(`supervisor scheduler install exited with status ${result.status}`);
73
- }
74
- }
75
-
76
- function runPostinstall(options = {}) {
77
- const platform = options.platform || process.platform;
78
- const env = options.env || process.env;
79
- const logger = options.log || log;
80
- const spawnSyncImpl = options.spawnSync || childProcess.spawnSync;
81
- const packageRoot = options.packageRoot || packageRootFromScript();
82
- const exePath = packageExecutable(packageRoot, platform);
83
-
84
- logger(`installed ${exePath}`);
85
-
86
- if (envFlagEnabled(env[INSTALL_SUPERVISOR_ENV])) {
87
- logger(`registering per-user background supervisor scheduler because ${INSTALL_SUPERVISOR_ENV} is enabled`);
88
- installSupervisorScheduler(exePath, spawnSyncImpl);
89
- logger("registered background supervisor scheduler");
90
- return;
91
- }
92
-
93
- logger(supervisorHintMessage());
94
- }
95
-
96
- try {
97
- if (require.main === module) {
98
- runPostinstall();
99
- }
100
- } catch (error) {
101
- console.error(`[rebon postinstall] ${error.message}`);
102
- process.exit(1);
103
- }
104
-
105
- module.exports = {
106
- INSTALL_SUPERVISOR_ENV,
107
- envFlagEnabled,
108
- installSupervisorScheduler,
109
- packageExecutable,
110
- runPostinstall,
111
- supervisorHintMessage,
112
- };
1
+ "use strict";
2
+
3
+ const childProcess = require("child_process");
4
+ const fs = require("fs");
5
+ const path = require("path");
6
+
7
+ const INSTALL_SUPERVISOR_ENV = "REBON_INSTALL_SUPERVISOR";
8
+
9
+ function log(message) {
10
+ console.log(`[rebon postinstall] ${message}`);
11
+ }
12
+
13
+ function envFlagEnabled(value) {
14
+ return /^(1|true|yes|on)$/i.test(String(value || "").trim());
15
+ }
16
+
17
+ function supervisorHintMessage() {
18
+ return "background supervisor scheduler was not registered; run `rebon agents service install` to keep queued jobs moving after login, or set REBON_INSTALL_SUPERVISOR=1 before install to opt in.";
19
+ }
20
+
21
+ function packageRootFromScript() {
22
+ return path.resolve(__dirname, "..");
23
+ }
24
+
25
+ function installWindowsPayload(packageRoot) {
26
+ const {
27
+ installManagedPackage,
28
+ readPackageInfo,
29
+ requireManagedBinDir,
30
+ } = require("../lib/windows-managed");
31
+
32
+ requireManagedBinDir();
33
+ const packageInfo = readPackageInfo(packageRoot);
34
+ if (!fs.existsSync(packageInfo.payloadPath)) {
35
+ throw new Error(`payload executable is missing: ${packageInfo.payloadPath}`);
36
+ }
37
+
38
+ const managedExe = installManagedPackage(packageInfo);
39
+ if (!managedExe) {
40
+ throw new Error("could not install payload executable into managed bin directory");
41
+ }
42
+ return managedExe;
43
+ }
44
+
45
+ function packageExecutable(packageRoot, platform) {
46
+ if (platform === "win32") {
47
+ return installWindowsPayload(packageRoot);
48
+ }
49
+
50
+ const exePath = path.join(packageRoot, "bin", "rebon");
51
+ if (!fs.existsSync(exePath)) {
52
+ throw new Error(`payload executable is missing: ${exePath}`);
53
+ }
54
+
55
+ try {
56
+ fs.chmodSync(exePath, 0o755);
57
+ } catch (_) {
58
+ }
59
+ return exePath;
60
+ }
61
+
62
+ function installSupervisorScheduler(exePath, spawnSyncImpl) {
63
+ const result = spawnSyncImpl(exePath, ["agents", "service", "install"], {
64
+ stdio: "inherit",
65
+ windowsHide: true,
66
+ });
67
+
68
+ if (result.error) {
69
+ throw result.error;
70
+ }
71
+ if (result.status !== 0) {
72
+ throw new Error(`supervisor scheduler install exited with status ${result.status}`);
73
+ }
74
+ }
75
+
76
+ function runPostinstall(options = {}) {
77
+ const platform = options.platform || process.platform;
78
+ const env = options.env || process.env;
79
+ const logger = options.log || log;
80
+ const spawnSyncImpl = options.spawnSync || childProcess.spawnSync;
81
+ const packageRoot = options.packageRoot || packageRootFromScript();
82
+ const exePath = packageExecutable(packageRoot, platform);
83
+
84
+ logger(`installed ${exePath}`);
85
+
86
+ if (envFlagEnabled(env[INSTALL_SUPERVISOR_ENV])) {
87
+ logger(`registering per-user background supervisor scheduler because ${INSTALL_SUPERVISOR_ENV} is enabled`);
88
+ installSupervisorScheduler(exePath, spawnSyncImpl);
89
+ logger("registered background supervisor scheduler");
90
+ return;
91
+ }
92
+
93
+ logger(supervisorHintMessage());
94
+ }
95
+
96
+ try {
97
+ if (require.main === module) {
98
+ runPostinstall();
99
+ }
100
+ } catch (error) {
101
+ console.error(`[rebon postinstall] ${error.message}`);
102
+ process.exit(1);
103
+ }
104
+
105
+ module.exports = {
106
+ INSTALL_SUPERVISOR_ENV,
107
+ envFlagEnabled,
108
+ installSupervisorScheduler,
109
+ packageExecutable,
110
+ runPostinstall,
111
+ supervisorHintMessage,
112
+ };