@yu_robotics/remote-cli 1.6.121 → 1.6.128

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 (63) hide show
  1. package/README.md +21 -1
  2. package/dist/client/WebSocketClient.d.ts +6 -0
  3. package/dist/client/WebSocketClient.d.ts.map +1 -1
  4. package/dist/client/WebSocketClient.js +4 -0
  5. package/dist/client/WebSocketClient.js.map +1 -1
  6. package/dist/commands/config.js +7 -0
  7. package/dist/commands/config.js.map +1 -1
  8. package/dist/commands/start.d.ts.map +1 -1
  9. package/dist/commands/start.js +11 -0
  10. package/dist/commands/start.js.map +1 -1
  11. package/dist/executor/CodexAppServerClient.d.ts +5 -0
  12. package/dist/executor/CodexAppServerClient.d.ts.map +1 -1
  13. package/dist/executor/CodexAppServerClient.js +6 -2
  14. package/dist/executor/CodexAppServerClient.js.map +1 -1
  15. package/dist/executor/claude/ClaudeStderrFilter.d.ts +1 -1
  16. package/dist/executor/claude/ClaudeStderrFilter.d.ts.map +1 -1
  17. package/dist/executor/claude/ClaudeStderrFilter.js +3 -2
  18. package/dist/executor/claude/ClaudeStderrFilter.js.map +1 -1
  19. package/dist/maintenance/CodexStatusProbe.d.ts +26 -0
  20. package/dist/maintenance/CodexStatusProbe.d.ts.map +1 -0
  21. package/dist/maintenance/CodexStatusProbe.js +124 -0
  22. package/dist/maintenance/CodexStatusProbe.js.map +1 -0
  23. package/dist/maintenance/CodexWeekly.d.ts +17 -0
  24. package/dist/maintenance/CodexWeekly.d.ts.map +1 -0
  25. package/dist/maintenance/CodexWeekly.js +60 -0
  26. package/dist/maintenance/CodexWeekly.js.map +1 -0
  27. package/dist/maintenance/MaintenanceClient.d.ts +23 -0
  28. package/dist/maintenance/MaintenanceClient.d.ts.map +1 -0
  29. package/dist/maintenance/MaintenanceClient.js +69 -0
  30. package/dist/maintenance/MaintenanceClient.js.map +1 -0
  31. package/dist/maintenance/PrivateStore.d.ts +10 -0
  32. package/dist/maintenance/PrivateStore.d.ts.map +1 -0
  33. package/dist/maintenance/PrivateStore.js +54 -0
  34. package/dist/maintenance/PrivateStore.js.map +1 -0
  35. package/dist/maintenance/ReleaseNotes.d.ts +30 -0
  36. package/dist/maintenance/ReleaseNotes.d.ts.map +1 -0
  37. package/dist/maintenance/ReleaseNotes.js +139 -0
  38. package/dist/maintenance/ReleaseNotes.js.map +1 -0
  39. package/dist/maintenance/ReleaseOverview.d.ts +23 -0
  40. package/dist/maintenance/ReleaseOverview.d.ts.map +1 -0
  41. package/dist/maintenance/ReleaseOverview.js +56 -0
  42. package/dist/maintenance/ReleaseOverview.js.map +1 -0
  43. package/dist/maintenance/SubscriptionInspection.d.ts +49 -0
  44. package/dist/maintenance/SubscriptionInspection.d.ts.map +1 -0
  45. package/dist/maintenance/SubscriptionInspection.js +193 -0
  46. package/dist/maintenance/SubscriptionInspection.js.map +1 -0
  47. package/dist/maintenance/SubscriptionReminderStore.d.ts +12 -0
  48. package/dist/maintenance/SubscriptionReminderStore.d.ts.map +1 -0
  49. package/dist/maintenance/SubscriptionReminderStore.js +60 -0
  50. package/dist/maintenance/SubscriptionReminderStore.js.map +1 -0
  51. package/dist/maintenance/UpdateNotices.d.ts +21 -0
  52. package/dist/maintenance/UpdateNotices.d.ts.map +1 -0
  53. package/dist/maintenance/UpdateNotices.js +104 -0
  54. package/dist/maintenance/UpdateNotices.js.map +1 -0
  55. package/dist/maintenance/Version.d.ts +3 -0
  56. package/dist/maintenance/Version.d.ts.map +1 -0
  57. package/dist/maintenance/Version.js +42 -0
  58. package/dist/maintenance/Version.js.map +1 -0
  59. package/dist/maintenance/release-notes.json +1 -0
  60. package/dist/types/config.d.ts +5 -0
  61. package/dist/types/config.d.ts.map +1 -1
  62. package/dist/types/config.js.map +1 -1
  63. package/package.json +2 -2
@@ -0,0 +1 @@
1
+ {"version":3,"file":"ReleaseOverview.d.ts","sourceRoot":"","sources":["../../src/maintenance/ReleaseOverview.ts"],"names":[],"mappings":"AAAA,eAAO,MAAM,cAAc,QAAW,CAAC;AACvC,eAAO,MAAM,mBAAmB,IAAI,CAAC;AACrC,eAAO,MAAM,kBAAkB,KAAK,CAAC;AACrC,MAAM,WAAW,aAAa;IAAG,KAAK,EAAE,MAAM,CAAC;IAAC,KAAK,EAAE,MAAM,CAAC;IAAC,IAAI,EAAE,MAAM,CAAA;CAAE;AAC7E,MAAM,WAAW,eAAe;IAC9B,MAAM,EAAE;QAAE,KAAK,EAAE,MAAM,CAAC;QAAC,KAAK,EAAE,MAAM,CAAC;QAAC,KAAK,EAAE,MAAM,EAAE,CAAA;KAAE,EAAE,CAAC;IAC5D,WAAW,EAAE,MAAM,CAAC;IACpB,UAAU,EAAE,MAAM,CAAC;CACpB;AAED,wBAAgB,mBAAmB,CAAC,KAAK,EAAE,OAAO,GAAG,KAAK,IAAI,aAAa,EAAE,CAO5E;AAED,kFAAkF;AAClF,wBAAgB,oBAAoB,CAAC,QAAQ,EAAE;IAAE,OAAO,CAAC,EAAE,aAAa,EAAE,CAAA;CAAE,EAAE,EAAE,MAAM,SAAiB,GAAG,eAAe,GAAG,SAAS,CAyBpI"}
@@ -0,0 +1,56 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.OVERVIEW_MAX_ITEMS = exports.OVERVIEW_MAX_GROUPS = exports.OVERVIEW_BYTES = void 0;
4
+ exports.validReleaseChanges = validReleaseChanges;
5
+ exports.buildReleaseOverview = buildReleaseOverview;
6
+ exports.OVERVIEW_BYTES = 6 * 1024;
7
+ exports.OVERVIEW_MAX_GROUPS = 6;
8
+ exports.OVERVIEW_MAX_ITEMS = 12;
9
+ function validReleaseChanges(value) {
10
+ return Array.isArray(value) && value.length >= 1 && value.length <= 3 && value.every(change => change && typeof change.topic === 'string' && /^[a-z][a-z0-9-]{0,39}$/.test(change.topic)
11
+ && typeof change.title === 'string' && change.title.trim() === change.title && change.title.length > 0
12
+ && Array.from(change.title).length <= 80 && !/[\r\n\[\]<>|*\x60]/.test(change.title)
13
+ && typeof change.text === 'string' && change.text.trim() === change.text && change.text.length > 0
14
+ && !/[\r\n]/.test(change.text) && Buffer.byteLength(change.text) <= 2 * 1024);
15
+ }
16
+ /** Aggregate the full selected range, never only the currently displayed page. */
17
+ function buildReleaseOverview(sections, budget = exports.OVERVIEW_BYTES) {
18
+ if (!Number.isFinite(budget) || budget <= 0 || !sections.length || sections.some(section => !section.changes))
19
+ return;
20
+ const groups = new Map();
21
+ for (const section of sections)
22
+ for (const change of section.changes) {
23
+ let group = groups.get(change.topic);
24
+ if (!group) {
25
+ group = { topic: change.topic, title: change.title, items: [], seen: new Set() };
26
+ groups.set(change.topic, group);
27
+ }
28
+ if (!group.seen.has(change.text)) {
29
+ group.items.push(change.text);
30
+ group.seen.add(change.text);
31
+ }
32
+ }
33
+ const overview = { groups: [], totalGroups: groups.size,
34
+ totalItems: [...groups.values()].reduce((total, group) => total + group.items.length, 0) };
35
+ let shown = 0;
36
+ const limit = Math.min(budget, exports.OVERVIEW_BYTES);
37
+ for (const group of groups.values()) {
38
+ if (overview.groups.length >= exports.OVERVIEW_MAX_GROUPS || shown >= exports.OVERVIEW_MAX_ITEMS)
39
+ break;
40
+ const visible = { topic: group.topic, title: group.title, items: [] };
41
+ overview.groups.push(visible);
42
+ for (const item of group.items) {
43
+ if (shown >= exports.OVERVIEW_MAX_ITEMS)
44
+ break;
45
+ visible.items.push(item);
46
+ if (Buffer.byteLength(JSON.stringify(overview)) > limit)
47
+ visible.items.pop();
48
+ else
49
+ shown++;
50
+ }
51
+ if (!visible.items.length)
52
+ overview.groups.pop();
53
+ }
54
+ return overview.groups.length ? overview : undefined;
55
+ }
56
+ //# sourceMappingURL=ReleaseOverview.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"ReleaseOverview.js","sourceRoot":"","sources":["../../src/maintenance/ReleaseOverview.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,49 @@
1
+ import type { BackendKey } from '../types/config';
2
+ import { type WeeklyObservation } from './CodexWeekly';
3
+ import type { SubscriptionReminderStore } from './SubscriptionReminderStore';
4
+ export interface InspectionAdapter {
5
+ backend: BackendKey;
6
+ inspect(signal: AbortSignal): Promise<{
7
+ kind: 'unsupported' | 'unavailable';
8
+ } | {
9
+ kind: 'observed';
10
+ observation: WeeklyObservation;
11
+ }>;
12
+ }
13
+ export declare function inspectionAdapters(codex: (signal: AbortSignal) => Promise<WeeklyObservation | undefined>): InspectionAdapter[];
14
+ /** Observations stay in memory; acknowledged delivery suppression can survive CLI restarts. */
15
+ export declare class SubscriptionInspection {
16
+ private readonly adapters;
17
+ private readonly send;
18
+ private readonly now;
19
+ private readonly intervalMs;
20
+ private readonly retryMs;
21
+ private readonly store?;
22
+ private previous?;
23
+ private reminder?;
24
+ private suppressed;
25
+ private accountKey?;
26
+ private conditionRevision;
27
+ private persistenceUnavailable;
28
+ private operations;
29
+ private supported;
30
+ private stopped;
31
+ private inFlight?;
32
+ private timer?;
33
+ private deliveryTimer?;
34
+ private readonly controller;
35
+ private readonly generation;
36
+ constructor(adapters: InspectionAdapter[], send: (message: object) => void, now?: () => number, intervalMs?: number, retryMs?: number, store?: SubscriptionReminderStore | undefined);
37
+ start(): void;
38
+ registered(supported: boolean): void;
39
+ disconnected(): void;
40
+ stop(): Promise<void>;
41
+ cycle(): Promise<void>;
42
+ handle(message: any): Promise<void>;
43
+ private enqueue;
44
+ private disablePersistence;
45
+ private scheduleCycle;
46
+ private deliver;
47
+ private clearDeliveryTimer;
48
+ }
49
+ //# sourceMappingURL=SubscriptionInspection.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"SubscriptionInspection.d.ts","sourceRoot":"","sources":["../../src/maintenance/SubscriptionInspection.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,iBAAiB,CAAC;AAClD,OAAO,EAA8C,KAAK,iBAAiB,EAAE,MAAM,eAAe,CAAC;AACnG,OAAO,KAAK,EAAE,yBAAyB,EAAE,MAAM,6BAA6B,CAAC;AAE7E,MAAM,WAAW,iBAAiB;IAChC,OAAO,EAAE,UAAU,CAAC;IACpB,OAAO,CAAC,MAAM,EAAE,WAAW,GAAG,OAAO,CAAC;QAAE,IAAI,EAAE,aAAa,GAAG,aAAa,CAAA;KAAE,GAAG;QAAE,IAAI,EAAE,UAAU,CAAC;QAAC,WAAW,EAAE,iBAAiB,CAAA;KAAE,CAAC,CAAC;CACvI;AAID,wBAAgB,kBAAkB,CAAC,KAAK,EAAE,CAAC,MAAM,EAAE,WAAW,KAAK,OAAO,CAAC,iBAAiB,GAAG,SAAS,CAAC,GAAG,iBAAiB,EAAE,CAM9H;AAED,+FAA+F;AAC/F,qBAAa,sBAAsB;IAerB,OAAO,CAAC,QAAQ,CAAC,QAAQ;IAAuB,OAAO,CAAC,QAAQ,CAAC,IAAI;IAC/E,OAAO,CAAC,QAAQ,CAAC,GAAG;IAAa,OAAO,CAAC,QAAQ,CAAC,UAAU;IAA2B,OAAO,CAAC,QAAQ,CAAC,OAAO;IAC/G,OAAO,CAAC,QAAQ,CAAC,KAAK,CAAC;IAhBzB,OAAO,CAAC,QAAQ,CAAC,CAAoB;IACrC,OAAO,CAAC,QAAQ,CAAC,CAAW;IAC5B,OAAO,CAAC,UAAU,CAAS;IAC3B,OAAO,CAAC,UAAU,CAAC,CAAS;IAC5B,OAAO,CAAC,iBAAiB,CAAK;IAC9B,OAAO,CAAC,sBAAsB,CAAS;IACvC,OAAO,CAAC,UAAU,CAAqB;IACvC,OAAO,CAAC,SAAS,CAAS;IAC1B,OAAO,CAAC,OAAO,CAAS;IACxB,OAAO,CAAC,QAAQ,CAAC,CAAgB;IACjC,OAAO,CAAC,KAAK,CAAC,CAAgC;IAC9C,OAAO,CAAC,aAAa,CAAC,CAAgC;IACtD,OAAO,CAAC,QAAQ,CAAC,UAAU,CAAyB;IACpD,OAAO,CAAC,QAAQ,CAAC,UAAU,CAAgB;gBACd,QAAQ,EAAE,iBAAiB,EAAE,EAAmB,IAAI,EAAE,CAAC,OAAO,EAAE,MAAM,KAAK,IAAI,EACzF,GAAG,eAAW,EAAmB,UAAU,SAAyB,EAAmB,OAAO,SAAS,EACvG,KAAK,CAAC,EAAE,yBAAyB,YAAA;IAEpD,KAAK,IAAI,IAAI;IACb,UAAU,CAAC,SAAS,EAAE,OAAO,GAAG,IAAI;IACpC,YAAY,IAAI,IAAI;IACd,IAAI,IAAI,OAAO,CAAC,IAAI,CAAC;IAQ3B,KAAK,IAAI,OAAO,CAAC,IAAI,CAAC;IA6CtB,MAAM,CAAC,OAAO,EAAE,GAAG,GAAG,OAAO,CAAC,IAAI,CAAC;IAiBnC,OAAO,CAAC,OAAO;IAMf,OAAO,CAAC,kBAAkB;IAK1B,OAAO,CAAC,aAAa;IAOrB,OAAO,CAAC,OAAO;IAOf,OAAO,CAAC,kBAAkB;CAC3B"}
@@ -0,0 +1,193 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.SubscriptionInspection = void 0;
4
+ exports.inspectionAdapters = inspectionAdapters;
5
+ const crypto_1 = require("crypto");
6
+ const CodexWeekly_1 = require("./CodexWeekly");
7
+ const BACKENDS = ['claude', 'codex', 'agy', 'pi', 'opencode', 'kimi', 'zcode', 'dsh'];
8
+ function inspectionAdapters(codex) {
9
+ return BACKENDS.map(backend => ({ backend, inspect: async (signal) => {
10
+ if (backend !== 'codex')
11
+ return { kind: 'unsupported' };
12
+ const observation = await codex(signal);
13
+ return observation ? { kind: 'observed', observation } : { kind: 'unavailable' };
14
+ } }));
15
+ }
16
+ /** Observations stay in memory; acknowledged delivery suppression can survive CLI restarts. */
17
+ class SubscriptionInspection {
18
+ adapters;
19
+ send;
20
+ now;
21
+ intervalMs;
22
+ retryMs;
23
+ store;
24
+ previous;
25
+ reminder;
26
+ suppressed = false;
27
+ accountKey;
28
+ conditionRevision = 0;
29
+ persistenceUnavailable = false;
30
+ operations = Promise.resolve();
31
+ supported = false;
32
+ stopped = false;
33
+ inFlight;
34
+ timer;
35
+ deliveryTimer;
36
+ controller = new AbortController();
37
+ generation = (0, crypto_1.randomUUID)();
38
+ constructor(adapters, send, now = Date.now, intervalMs = CodexWeekly_1.INSPECTION_INTERVAL_MS, retryMs = 60_000, store) {
39
+ this.adapters = adapters;
40
+ this.send = send;
41
+ this.now = now;
42
+ this.intervalMs = intervalMs;
43
+ this.retryMs = retryMs;
44
+ this.store = store;
45
+ }
46
+ start() { if (!this.stopped && !this.timer && !this.inFlight)
47
+ this.scheduleCycle(0); }
48
+ registered(supported) { this.supported = supported; this.deliver(); }
49
+ disconnected() { this.supported = false; this.clearDeliveryTimer(); }
50
+ async stop() {
51
+ this.stopped = true;
52
+ this.disconnected();
53
+ this.controller.abort();
54
+ if (this.timer)
55
+ clearTimeout(this.timer);
56
+ this.timer = undefined;
57
+ await this.inFlight;
58
+ await this.operations;
59
+ this.previous = undefined;
60
+ this.reminder = undefined;
61
+ }
62
+ cycle() {
63
+ if (this.stopped)
64
+ return Promise.resolve();
65
+ if (this.inFlight)
66
+ return this.inFlight;
67
+ const operation = this.enqueue(async () => {
68
+ if (this.stopped || this.persistenceUnavailable)
69
+ return;
70
+ if (this.store) {
71
+ try {
72
+ await this.store.initialize();
73
+ }
74
+ catch {
75
+ this.disablePersistence();
76
+ return;
77
+ }
78
+ }
79
+ for (const adapter of this.adapters) {
80
+ if (this.stopped)
81
+ break;
82
+ let result;
83
+ try {
84
+ result = await adapter.inspect(this.controller.signal);
85
+ }
86
+ catch {
87
+ continue;
88
+ } // Unavailable evidence never clears delivery suppression or a valid baseline.
89
+ if (this.stopped || adapter.backend !== 'codex' || result.kind !== 'observed')
90
+ continue;
91
+ try {
92
+ const current = result.observation;
93
+ if (current.accountKey !== this.accountKey) {
94
+ this.suppressed = this.store ? await this.store.isSuppressed(current.accountKey) : false;
95
+ this.accountKey = current.accountKey;
96
+ this.conditionRevision++;
97
+ this.reminder = undefined;
98
+ this.clearDeliveryTimer();
99
+ this.previous = undefined;
100
+ }
101
+ if (this.previous && (current.identity !== this.previous.identity || current.observedAt < this.previous.observedAt)) {
102
+ this.reminder = undefined;
103
+ this.clearDeliveryTimer();
104
+ this.previous = undefined;
105
+ }
106
+ if (!current.candidate) {
107
+ this.conditionRevision++;
108
+ this.reminder = undefined;
109
+ this.clearDeliveryTimer();
110
+ if (this.suppressed && this.store)
111
+ await this.store.setSuppressed(current.accountKey, false);
112
+ this.suppressed = false;
113
+ }
114
+ if (!this.suppressed && !this.reminder && this.previous && (0, CodexWeekly_1.floatingWeeklyPair)(this.previous, current)) {
115
+ this.reminder = { reminderId: (0, crypto_1.randomUUID)(), generation: this.generation, expiresAt: this.now() + 2 * CodexWeekly_1.INSPECTION_INTERVAL_MS,
116
+ activationAvailable: false, backend: 'codex' };
117
+ this.deliver();
118
+ }
119
+ // Retry samples within the hourly cadence do not replace the previous independent sample.
120
+ if (!this.previous || current.observedAt - this.previous.observedAt >= this.intervalMs - 120_000 || !current.candidate)
121
+ this.previous = current;
122
+ }
123
+ catch {
124
+ this.disablePersistence();
125
+ break;
126
+ }
127
+ }
128
+ });
129
+ this.inFlight = operation;
130
+ return operation.finally(() => { if (this.inFlight === operation)
131
+ this.inFlight = undefined; });
132
+ }
133
+ handle(message) {
134
+ if (!this.supported || !this.reminder || !this.accountKey || message.reminderId !== this.reminder.reminderId || message.generation !== this.generation
135
+ || this.reminder.expiresAt <= this.now())
136
+ return Promise.resolve();
137
+ if (message.type === 'subscription_reminder_ack' || message.type === 'subscription_action' && message.decision === 'dismiss') {
138
+ const accountKey = this.accountKey, revision = this.conditionRevision;
139
+ this.suppressed = true;
140
+ this.clearDeliveryTimer();
141
+ return this.enqueue(async () => {
142
+ // A valid non-candidate observation takes precedence over an ACK queued during that probe.
143
+ if (this.persistenceUnavailable || this.accountKey === accountKey && this.conditionRevision !== revision)
144
+ return;
145
+ try {
146
+ await this.store?.setSuppressed(accountKey, true);
147
+ }
148
+ catch {
149
+ this.disablePersistence();
150
+ }
151
+ });
152
+ }
153
+ // Every other action is ignored: quota notices never execute prompts or trigger extra probes.
154
+ return Promise.resolve();
155
+ }
156
+ enqueue(operation) {
157
+ const result = this.operations.then(operation);
158
+ this.operations = result.catch(() => { });
159
+ return result;
160
+ }
161
+ disablePersistence() {
162
+ if (!this.persistenceUnavailable)
163
+ console.warn('[Maintenance] Quota reminders paused: local delivery state is unavailable. Normal messaging is unchanged.');
164
+ this.persistenceUnavailable = true;
165
+ this.clearDeliveryTimer();
166
+ }
167
+ scheduleCycle(delay) {
168
+ this.timer = setTimeout(() => {
169
+ this.timer = undefined;
170
+ void this.cycle().finally(() => { if (!this.stopped)
171
+ this.scheduleCycle(this.intervalMs); });
172
+ }, delay);
173
+ this.timer.unref?.();
174
+ }
175
+ deliver() {
176
+ if (this.stopped || this.persistenceUnavailable || !this.supported || !this.reminder || this.suppressed || this.deliveryTimer)
177
+ return;
178
+ if (this.reminder.expiresAt <= this.now()) {
179
+ this.reminder = undefined;
180
+ return;
181
+ }
182
+ try {
183
+ this.send({ type: 'subscription_reminder', reminder: this.reminder });
184
+ }
185
+ catch { /* Retry only the card, never a model request. */ }
186
+ this.deliveryTimer = setTimeout(() => { this.deliveryTimer = undefined; this.deliver(); }, this.retryMs);
187
+ this.deliveryTimer.unref?.();
188
+ }
189
+ clearDeliveryTimer() { if (this.deliveryTimer)
190
+ clearTimeout(this.deliveryTimer); this.deliveryTimer = undefined; }
191
+ }
192
+ exports.SubscriptionInspection = SubscriptionInspection;
193
+ //# sourceMappingURL=SubscriptionInspection.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"SubscriptionInspection.js","sourceRoot":"","sources":["../../src/maintenance/SubscriptionInspection.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,12 @@
1
+ /** Persist delivery suppression, never credentials, raw account IDs, or quota observations. */
2
+ export declare class SubscriptionReminderStore {
3
+ private readonly store;
4
+ private accounts;
5
+ private initializing?;
6
+ private operations;
7
+ constructor(configDir: string, serverUrl: string, deviceId: string);
8
+ initialize(): Promise<void>;
9
+ isSuppressed(accountKey: string): Promise<boolean>;
10
+ setSuppressed(accountKey: string, suppressed: boolean): Promise<void>;
11
+ }
12
+ //# sourceMappingURL=SubscriptionReminderStore.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"SubscriptionReminderStore.d.ts","sourceRoot":"","sources":["../../src/maintenance/SubscriptionReminderStore.ts"],"names":[],"mappings":"AAcA,+FAA+F;AAC/F,qBAAa,yBAAyB;IACpC,OAAO,CAAC,QAAQ,CAAC,KAAK,CAAuB;IAC7C,OAAO,CAAC,QAAQ,CAAqB;IACrC,OAAO,CAAC,YAAY,CAAC,CAAgB;IACrC,OAAO,CAAC,UAAU,CAAqB;gBAE3B,SAAS,EAAE,MAAM,EAAE,SAAS,EAAE,MAAM,EAAE,QAAQ,EAAE,MAAM;IAKlE,UAAU,IAAI,OAAO,CAAC,IAAI,CAAC;IAMrB,YAAY,CAAC,UAAU,EAAE,MAAM,GAAG,OAAO,CAAC,OAAO,CAAC;IAOxD,aAAa,CAAC,UAAU,EAAE,MAAM,EAAE,UAAU,EAAE,OAAO,GAAG,OAAO,CAAC,IAAI,CAAC;CAatE"}
@@ -0,0 +1,60 @@
1
+ "use strict";
2
+ var __importDefault = (this && this.__importDefault) || function (mod) {
3
+ return (mod && mod.__esModule) ? mod : { "default": mod };
4
+ };
5
+ Object.defineProperty(exports, "__esModule", { value: true });
6
+ exports.SubscriptionReminderStore = void 0;
7
+ const path_1 = __importDefault(require("path"));
8
+ const crypto_1 = require("crypto");
9
+ const PrivateStore_1 = require("./PrivateStore");
10
+ const FINGERPRINT = /^[a-f0-9]{64}$/;
11
+ const MAX_ACCOUNTS = 256;
12
+ function validLedger(value) {
13
+ return value?.format === 1 && Object.keys(value).every(key => key === 'format' || key === 'suppressedAccounts')
14
+ && Array.isArray(value.suppressedAccounts) && value.suppressedAccounts.length <= MAX_ACCOUNTS
15
+ && value.suppressedAccounts.every((key) => typeof key === 'string' && FINGERPRINT.test(key))
16
+ && new Set(value.suppressedAccounts).size === value.suppressedAccounts.length;
17
+ }
18
+ /** Persist delivery suppression, never credentials, raw account IDs, or quota observations. */
19
+ class SubscriptionReminderStore {
20
+ store;
21
+ accounts = new Set();
22
+ initializing;
23
+ operations = Promise.resolve();
24
+ constructor(configDir, serverUrl, deviceId) {
25
+ const namespace = (0, crypto_1.createHash)('sha256').update(JSON.stringify([serverUrl, deviceId])).digest('hex');
26
+ this.store = new PrivateStore_1.PrivateStore(path_1.default.join(configDir, 'subscription-reminders', `${namespace}.json`), validLedger);
27
+ }
28
+ initialize() {
29
+ return this.initializing ??= this.store.read().then(ledger => {
30
+ this.accounts = new Set(ledger?.suppressedAccounts ?? []);
31
+ });
32
+ }
33
+ async isSuppressed(accountKey) {
34
+ if (!FINGERPRINT.test(accountKey))
35
+ throw new Error('Invalid quota account fingerprint.');
36
+ await this.initialize();
37
+ await this.operations;
38
+ return this.accounts.has(accountKey);
39
+ }
40
+ setSuppressed(accountKey, suppressed) {
41
+ const operation = this.operations.then(async () => {
42
+ if (!FINGERPRINT.test(accountKey))
43
+ throw new Error('Invalid quota account fingerprint.');
44
+ await this.initialize();
45
+ if (this.accounts.has(accountKey) === suppressed)
46
+ return;
47
+ const next = new Set(this.accounts);
48
+ if (suppressed)
49
+ next.add(accountKey);
50
+ else
51
+ next.delete(accountKey);
52
+ await this.store.write({ format: 1, suppressedAccounts: [...next] });
53
+ this.accounts = next;
54
+ });
55
+ this.operations = operation.catch(() => { });
56
+ return operation;
57
+ }
58
+ }
59
+ exports.SubscriptionReminderStore = SubscriptionReminderStore;
60
+ //# sourceMappingURL=SubscriptionReminderStore.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"SubscriptionReminderStore.js","sourceRoot":"","sources":["../../src/maintenance/SubscriptionReminderStore.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,21 @@
1
+ /** A notice tracks successful starts, not package installation or WebSocket OPEN. */
2
+ export declare class UpdateNotices {
3
+ private readonly send;
4
+ private readonly retryMs;
5
+ private ledger?;
6
+ private index?;
7
+ private supported;
8
+ private timer?;
9
+ private stopped;
10
+ private operations;
11
+ private readonly store;
12
+ constructor(configDir: string, serverUrl: string, deviceId: string, send: (message: object) => void, retryMs?: number);
13
+ started(version: string): Promise<void>;
14
+ registered(supported: boolean): void;
15
+ disconnected(): void;
16
+ stop(): void;
17
+ handle(message: any): Promise<void>;
18
+ private deliver;
19
+ private clearTimer;
20
+ }
21
+ //# sourceMappingURL=UpdateNotices.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"UpdateNotices.d.ts","sourceRoot":"","sources":["../../src/maintenance/UpdateNotices.ts"],"names":[],"mappings":"AAsBA,qFAAqF;AACrF,qBAAa,aAAa;IAS4C,OAAO,CAAC,QAAQ,CAAC,IAAI;IACvF,OAAO,CAAC,QAAQ,CAAC,OAAO;IAT1B,OAAO,CAAC,MAAM,CAAC,CAAS;IACxB,OAAO,CAAC,KAAK,CAAC,CAAe;IAC7B,OAAO,CAAC,SAAS,CAAS;IAC1B,OAAO,CAAC,KAAK,CAAC,CAAgC;IAC9C,OAAO,CAAC,OAAO,CAAS;IACxB,OAAO,CAAC,UAAU,CAAqB;IACvC,OAAO,CAAC,QAAQ,CAAC,KAAK,CAAuB;gBAEjC,SAAS,EAAE,MAAM,EAAE,SAAS,EAAE,MAAM,EAAE,QAAQ,EAAE,MAAM,EAAmB,IAAI,EAAE,CAAC,OAAO,EAAE,MAAM,KAAK,IAAI,EACjG,OAAO,SAAS;IAK7B,OAAO,CAAC,OAAO,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC;IAmB7C,UAAU,CAAC,SAAS,EAAE,OAAO,GAAG,IAAI;IACpC,YAAY,IAAI,IAAI;IACpB,IAAI,IAAI,IAAI;IAEZ,MAAM,CAAC,OAAO,EAAE,GAAG,GAAG,OAAO,CAAC,IAAI,CAAC;IAyBnC,OAAO,CAAC,OAAO;IASf,OAAO,CAAC,UAAU;CACnB"}
@@ -0,0 +1,104 @@
1
+ "use strict";
2
+ var __importDefault = (this && this.__importDefault) || function (mod) {
3
+ return (mod && mod.__esModule) ? mod : { "default": mod };
4
+ };
5
+ Object.defineProperty(exports, "__esModule", { value: true });
6
+ exports.UpdateNotices = void 0;
7
+ const path_1 = __importDefault(require("path"));
8
+ const crypto_1 = require("crypto");
9
+ const PrivateStore_1 = require("./PrivateStore");
10
+ const Version_1 = require("./Version");
11
+ const ReleaseNotes_1 = require("./ReleaseNotes");
12
+ const UUID = /^[a-f0-9]{8}-[a-f0-9]{4}-4[a-f0-9]{3}-[89ab][a-f0-9]{3}-[a-f0-9]{12}$/i;
13
+ function validLedger(value) {
14
+ return value?.format === 1 && (0, Version_1.validNoticeVersion)(value.lastStartedVersion) && (0, Version_1.validNoticeVersion)(value.notificationBaselineVersion)
15
+ && (0, Version_1.validNoticeVersion)(value.firstAdoptionVersion) && (!value.pending || UUID.test(value.pending.noticeKey)
16
+ && (0, Version_1.validNoticeVersion)(value.pending.fromVersion) && (0, Version_1.validNoticeVersion)(value.pending.toVersion)
17
+ && value.pending.fromVersion === value.notificationBaselineVersion && (0, Version_1.compareNoticeVersions)(value.pending.fromVersion, value.pending.toVersion) < 0);
18
+ }
19
+ /** A notice tracks successful starts, not package installation or WebSocket OPEN. */
20
+ class UpdateNotices {
21
+ send;
22
+ retryMs;
23
+ ledger;
24
+ index;
25
+ supported = false;
26
+ timer;
27
+ stopped = false;
28
+ operations = Promise.resolve();
29
+ store;
30
+ constructor(configDir, serverUrl, deviceId, send, retryMs = 60_000) {
31
+ this.send = send;
32
+ this.retryMs = retryMs;
33
+ const namespace = (0, crypto_1.createHash)('sha256').update(JSON.stringify([serverUrl, deviceId])).digest('hex');
34
+ this.store = new PrivateStore_1.PrivateStore(path_1.default.join(configDir, 'update-notices', `${namespace}.json`), validLedger);
35
+ }
36
+ async started(version) {
37
+ if (!(0, Version_1.validNoticeVersion)(version))
38
+ throw new Error('Invalid running CLI version.');
39
+ this.index = await (0, ReleaseNotes_1.loadReleaseIndex)();
40
+ const previous = await this.store.read();
41
+ const next = previous ? { ...previous, lastStartedVersion: version } : {
42
+ format: 1, lastStartedVersion: version, notificationBaselineVersion: version, firstAdoptionVersion: version,
43
+ };
44
+ if (previous) {
45
+ if ((0, Version_1.compareNoticeVersions)(version, next.notificationBaselineVersion) <= 0
46
+ || (0, Version_1.compareNoticeVersions)(version, previous.lastStartedVersion) < 0)
47
+ delete next.pending;
48
+ else if ((0, Version_1.compareNoticeVersions)(version, previous.lastStartedVersion) > 0)
49
+ next.pending = {
50
+ noticeKey: (0, crypto_1.randomUUID)(), fromVersion: next.notificationBaselineVersion, toVersion: version,
51
+ };
52
+ }
53
+ await this.store.write(next);
54
+ this.ledger = next;
55
+ this.deliver();
56
+ }
57
+ registered(supported) { this.supported = supported; this.deliver(); }
58
+ disconnected() { this.supported = false; this.clearTimer(); }
59
+ stop() { this.stopped = true; this.disconnected(); }
60
+ handle(message) {
61
+ const operation = this.operations.then(async () => {
62
+ if (!this.supported || this.stopped || !this.ledger)
63
+ return;
64
+ if (message.type === 'update_notice_ack') {
65
+ const pending = this.ledger.pending;
66
+ if (!pending || message.noticeKey !== pending.noticeKey || message.fromVersion !== pending.fromVersion
67
+ || message.toVersion !== pending.toVersion)
68
+ return;
69
+ const next = { ...this.ledger, notificationBaselineVersion: pending.toVersion };
70
+ delete next.pending;
71
+ await this.store.write(next);
72
+ this.ledger = next;
73
+ this.clearTimer();
74
+ }
75
+ else if (message.type === 'update_notice_view') {
76
+ const { fromVersion: from, toVersion: to, offset, requestId, noticeKey } = message;
77
+ if (!UUID.test(requestId) || !UUID.test(noticeKey) || !(0, Version_1.validNoticeVersion)(from) || !(0, Version_1.validNoticeVersion)(to)
78
+ || (0, Version_1.compareNoticeVersions)(from, this.ledger.firstAdoptionVersion) < 0
79
+ || (0, Version_1.compareNoticeVersions)(to, this.ledger.lastStartedVersion) > 0 || (0, Version_1.compareNoticeVersions)(from, to) >= 0
80
+ || !Number.isSafeInteger(offset) || offset < 0 || offset > 10000)
81
+ return;
82
+ this.send({ type: 'update_notice_page', noticeKey, requestId, fromVersion: from, toVersion: to,
83
+ page: (0, ReleaseNotes_1.releasePage)(this.index, from, to, offset) });
84
+ }
85
+ });
86
+ this.operations = operation.catch(() => { });
87
+ return operation;
88
+ }
89
+ deliver() {
90
+ if (this.stopped || !this.supported || !this.ledger?.pending || this.timer)
91
+ return;
92
+ const pending = this.ledger.pending;
93
+ try {
94
+ this.send({ type: 'update_notice', ...pending, page: (0, ReleaseNotes_1.releasePage)(this.index, pending.fromVersion, pending.toVersion) });
95
+ }
96
+ catch { /* Retain the notice for a later compatible connection. */ }
97
+ this.timer = setTimeout(() => { this.timer = undefined; this.deliver(); }, this.retryMs);
98
+ this.timer.unref?.();
99
+ }
100
+ clearTimer() { if (this.timer)
101
+ clearTimeout(this.timer); this.timer = undefined; }
102
+ }
103
+ exports.UpdateNotices = UpdateNotices;
104
+ //# sourceMappingURL=UpdateNotices.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"UpdateNotices.js","sourceRoot":"","sources":["../../src/maintenance/UpdateNotices.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,3 @@
1
+ export declare function validNoticeVersion(value: unknown): value is string;
2
+ export declare function compareNoticeVersions(a: string, b: string): number;
3
+ //# sourceMappingURL=Version.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"Version.d.ts","sourceRoot":"","sources":["../../src/maintenance/Version.ts"],"names":[],"mappings":"AAaA,wBAAgB,kBAAkB,CAAC,KAAK,EAAE,OAAO,GAAG,KAAK,IAAI,MAAM,CAAkC;AAErG,wBAAgB,qBAAqB,CAAC,CAAC,EAAE,MAAM,EAAE,CAAC,EAAE,MAAM,GAAG,MAAM,CAclE"}
@@ -0,0 +1,42 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.validNoticeVersion = validNoticeVersion;
4
+ exports.compareNoticeVersions = compareNoticeVersions;
5
+ /** Strict SemVer precedence for maintenance notices; updater semantics are unchanged. */
6
+ const PATTERN = /^(0|[1-9]\d*)\.(0|[1-9]\d*)\.(0|[1-9]\d*)(?:-([0-9A-Za-z-]+(?:\.[0-9A-Za-z-]+)*))?(?:\+([0-9A-Za-z-]+(?:\.[0-9A-Za-z-]+)*))?$/;
7
+ function parse(value) {
8
+ if (typeof value !== 'string' || value.length > 100)
9
+ return;
10
+ const match = PATTERN.exec(value);
11
+ if (!match)
12
+ return;
13
+ const core = match.slice(1, 4).map(Number);
14
+ const pre = match[4]?.split('.') ?? [];
15
+ if (core.some(n => !Number.isSafeInteger(n)) || pre.some(s => /^\d+$/.test(s) && (s.length > 1 && s[0] === '0')))
16
+ return;
17
+ return { core, pre };
18
+ }
19
+ function validNoticeVersion(value) { return Boolean(parse(value)); }
20
+ function compareNoticeVersions(a, b) {
21
+ const left = parse(a), right = parse(b);
22
+ if (!left || !right)
23
+ throw new Error('Invalid maintenance version.');
24
+ for (let i = 0; i < 3; i++)
25
+ if (left.core[i] !== right.core[i])
26
+ return left.core[i] < right.core[i] ? -1 : 1;
27
+ if (!left.pre.length || !right.pre.length)
28
+ return left.pre.length === right.pre.length ? 0 : left.pre.length ? -1 : 1;
29
+ for (let i = 0; i < Math.max(left.pre.length, right.pre.length); i++) {
30
+ const l = left.pre[i], r = right.pre[i];
31
+ if (l === undefined || r === undefined)
32
+ return l === r ? 0 : l === undefined ? -1 : 1;
33
+ if (l === r)
34
+ continue;
35
+ const ln = /^\d+$/.test(l), rn = /^\d+$/.test(r);
36
+ if (ln && rn)
37
+ return l.length === r.length ? (l < r ? -1 : 1) : l.length < r.length ? -1 : 1;
38
+ return ln !== rn ? ln ? -1 : 1 : l < r ? -1 : 1;
39
+ }
40
+ return 0;
41
+ }
42
+ //# sourceMappingURL=Version.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"Version.js","sourceRoot":"","sources":["../../src/maintenance/Version.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1 @@
1
+ {"format":1,"firstVersion":"1.6.123","sections":[{"version":"1.6.128","text":"### 按功能汇总更新\n- 跨多个版本升级时,按功能汇总当前设备尚未收到的变化;逐版本记录保留在折叠详情中。","changes":[{"topic":"upgrade-notices","title":"升级通知","text":"跨多个版本升级时,按功能汇总当前设备尚未收到的变化;逐版本记录保留在折叠详情中。"}],"details":"### Changed\n- Aggregate upgrade summaries by stable feature tags across each device's full pending version range, deduplicate identical items, and keep per-version summaries and technical details collapsed. Bounded overviews report omitted items while retaining complete paged records, with additive old-peer fallback and no runtime model calls."},{"version":"1.6.127","text":"### 升级通知更易读\n- 升级卡片优先展示中文摘要,快速了解有哪些变化。\n- 技术细节保留在折叠区域,需要时再展开查看。","changes":[{"topic":"upgrade-notices","title":"升级通知","text":"升级卡片优先展示中文摘要,快速了解有哪些变化。"},{"topic":"upgrade-notices","title":"升级通知","text":"技术细节保留在折叠区域,需要时再展开查看。"}],"details":"### Changed\n- Bundle concise Chinese user release summaries alongside English technical changelog entries. Upgrade cards display localized summaries directly and keep technical details collapsed, with legacy-peer fallback and the existing silent first-adoption behavior.\n- Require matching technical and user-summary entries for the current release during CLI builds, with bounded summary structure and package payloads."},{"version":"1.6.126","text":"### 提醒更稳定,卡片更简洁\n- 修复 Codex Reset 提醒在 CLI 升级、重启后容易重复出现的问题。\n- 移除多余的 Dismiss 按钮,无需手动关闭提醒。","changes":[{"topic":"codex-reset","title":"Codex 提醒","text":"修复 Codex Reset 提醒在 CLI 升级、重启后容易重复出现的问题。"},{"topic":"codex-reset","title":"Codex 提醒","text":"移除多余的 Dismiss 按钮,无需手动关闭提醒。"}],"details":"### Fixed\n- Preserve acknowledged Codex quota-reminder suppression across CLI upgrades, restarts, reconnects, and credential refreshes using a private local fingerprint ledger. Valid non-candidate observations rearm reminders; unavailable probes do not, and shutdown waits for accepted acknowledgement writes.\n\n### Changed\n- Remove the redundant Dismiss button from new quota-reminder cards while retaining validated legacy callbacks and the existing notification-only inspection criteria."},{"version":"1.6.125","text":"### Codex 提醒更直观\n- 额度提醒改名为 Codex Reset,明确显示每周额度为 100%。\n- 简化卡片说明,保留开始新一轮使用的操作指引。","changes":[{"topic":"codex-reset","title":"Codex 提醒","text":"额度提醒改名为 Codex Reset,明确显示每周额度为 100%。"},{"topic":"codex-reset","title":"Codex 提醒","text":"简化卡片说明,保留开始新一轮使用的操作指引。"}],"details":"### Changed\n- Rename Codex weekly-quota reminders to \"Codex Reset\" with a target emoji and the summary \"Weekly quota reset: 100%\", and remove their sampling-disclaimer footer, retaining normal-task guidance, optional dismissal, and the existing inspection logic."},{"version":"1.6.124","text":"### Claude 输出更干净\n- 隐藏 Claude 子 agent 偶尔显示的无关模型警告,保留真正的接口和登录错误。","changes":[{"topic":"claude-output","title":"Claude 输出","text":"隐藏 Claude 子 agent 偶尔显示的无关模型警告,保留真正的接口和登录错误。"}],"details":"### Fixed\n- Suppress Claude Code model-recognition stderr diagnostics from session-title generation as well as SDK queries, including delegated-worker streaming and results. Preserve real API/authentication errors, nonzero exits, assistant text, and other backends."},{"version":"1.6.123","text":"### 新增升级通知与额度提醒\n- 升级后可查看跳过版本的更新内容,首次启用不会发送历史通知。\n- 新增 Codex 每周额度状态提醒,提示何时可以开始新一轮使用。","changes":[{"topic":"upgrade-notices","title":"升级通知","text":"升级后可查看跳过版本的更新内容,首次启用不会发送历史通知。"},{"topic":"codex-reset","title":"Codex 提醒","text":"新增 Codex 每周额度状态提醒,提示何时可以开始新一轮使用。"}],"details":"### Added\n- Standalone CLI upgrade notices with cumulative bundled release notes, offline delivery, and a silent baseline on first adoption.\n- Hourly, status-only Codex weekly-quota inspection and explicit maintenance reminders, without changing user threads or other backends.\n- Notification-only weekly-quota snapshots with backend-specific explanations and normal-task guidance, without verification steps, activation requests, or claims that a quota reset occurred. Dismissal remains optional."}]}