@molecule/app-ide-react 1.11.3 → 1.12.1
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.
- package/README.md +237 -1
- package/dist/command-metadata.d.ts.map +1 -1
- package/dist/command-metadata.js +9 -0
- package/dist/command-metadata.js.map +1 -1
- package/dist/components/ChatPanel.d.ts +5 -0
- package/dist/components/ChatPanel.d.ts.map +1 -1
- package/dist/components/ChatPanel.js +128 -24
- package/dist/components/ChatPanel.js.map +1 -1
- package/dist/components/ChatTimestamp.d.ts +33 -0
- package/dist/components/ChatTimestamp.d.ts.map +1 -0
- package/dist/components/ChatTimestamp.js +30 -0
- package/dist/components/ChatTimestamp.js.map +1 -0
- package/dist/components/PreviewPanel.d.ts.map +1 -1
- package/dist/components/PreviewPanel.js +21 -2
- package/dist/components/PreviewPanel.js.map +1 -1
- package/dist/components/chat-timestamps-utilities.d.ts +119 -0
- package/dist/components/chat-timestamps-utilities.d.ts.map +1 -0
- package/dist/components/chat-timestamps-utilities.js +173 -0
- package/dist/components/chat-timestamps-utilities.js.map +1 -0
- package/dist/components/index.d.ts +2 -0
- package/dist/components/index.d.ts.map +1 -1
- package/dist/components/index.js +2 -0
- package/dist/components/index.js.map +1 -1
- package/dist/customEventCards.d.ts +7 -0
- package/dist/customEventCards.d.ts.map +1 -1
- package/dist/customEventCards.js.map +1 -1
- package/dist/hooks/index.d.ts +1 -0
- package/dist/hooks/index.d.ts.map +1 -1
- package/dist/hooks/index.js +1 -0
- package/dist/hooks/index.js.map +1 -1
- package/dist/hooks/useChatTimestampsVisible.d.ts +20 -0
- package/dist/hooks/useChatTimestampsVisible.d.ts.map +1 -0
- package/dist/hooks/useChatTimestampsVisible.js +74 -0
- package/dist/hooks/useChatTimestampsVisible.js.map +1 -0
- package/dist/index.d.ts +12 -0
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +12 -0
- package/dist/index.js.map +1 -1
- package/dist/settings-metadata.d.ts +1 -1
- package/dist/settings-metadata.d.ts.map +1 -1
- package/dist/settings-metadata.js +6 -0
- package/dist/settings-metadata.js.map +1 -1
- package/package.json +3 -3
|
@@ -0,0 +1,173 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Chat timestamp visibility + formatting — the pure half of the `/timestamps`
|
|
3
|
+
* feature (the hook lives in `hooks/useChatTimestampsVisible.ts`, the rendered
|
|
4
|
+
* label in `ChatTimestamp.tsx`).
|
|
5
|
+
*
|
|
6
|
+
* Visibility is a PER-DEVICE, per-user display preference, stored in
|
|
7
|
+
* localStorage like `/sounds` and `/mic` — never project settings, so a viewer
|
|
8
|
+
* can toggle it and it never changes what a teammate sees. A host's own
|
|
9
|
+
* settings UI toggles the same value through {@link setChatTimestampsVisible},
|
|
10
|
+
* and every mounted chat follows via {@link CHAT_TIMESTAMPS_EVENT} (same tab)
|
|
11
|
+
* and the `storage` event (other tabs).
|
|
12
|
+
*
|
|
13
|
+
* @module
|
|
14
|
+
*/
|
|
15
|
+
/** localStorage key holding `'true'` / `'false'`. Absent = the default (hidden). */
|
|
16
|
+
export const CHAT_TIMESTAMPS_STORAGE_KEY = 'mol_chat_show_timestamps';
|
|
17
|
+
/** Window event dispatched (same tab) whenever the preference changes. */
|
|
18
|
+
export const CHAT_TIMESTAMPS_EVENT = 'mol:chat-timestamps-changed';
|
|
19
|
+
/**
|
|
20
|
+
* Parses the stored preference. Only an explicit `'true'` shows every timestamp,
|
|
21
|
+
* so a missing or unreadable value keeps the default (off — only the user's own
|
|
22
|
+
* message headers and critical events carry a time; see {@link planChatTimestamps}).
|
|
23
|
+
*
|
|
24
|
+
* @param raw - The raw localStorage value.
|
|
25
|
+
* @returns Whether timestamps are visible on every item.
|
|
26
|
+
*/
|
|
27
|
+
export function parseChatTimestampsVisible(raw) {
|
|
28
|
+
return raw === 'true';
|
|
29
|
+
}
|
|
30
|
+
/**
|
|
31
|
+
* Reads this device's preference.
|
|
32
|
+
*
|
|
33
|
+
* @returns Whether chat timestamps are visible on every item (default `false`).
|
|
34
|
+
*/
|
|
35
|
+
export function getChatTimestampsVisible() {
|
|
36
|
+
try {
|
|
37
|
+
return parseChatTimestampsVisible(localStorage.getItem(CHAT_TIMESTAMPS_STORAGE_KEY));
|
|
38
|
+
}
|
|
39
|
+
catch (_error) {
|
|
40
|
+
// localStorage unavailable (private mode, SSR) — fall back to the default.
|
|
41
|
+
return false;
|
|
42
|
+
}
|
|
43
|
+
}
|
|
44
|
+
/**
|
|
45
|
+
* Resolves the active i18n locale, falling back to the browser's when no i18n
|
|
46
|
+
* provider is bonded.
|
|
47
|
+
*
|
|
48
|
+
* @param getLocale - The i18n accessor (throws when no provider is bonded).
|
|
49
|
+
* @returns A BCP 47 locale.
|
|
50
|
+
*/
|
|
51
|
+
export function resolveChatLocale(getLocale) {
|
|
52
|
+
try {
|
|
53
|
+
return getLocale();
|
|
54
|
+
}
|
|
55
|
+
catch (_error) {
|
|
56
|
+
// No i18n provider bonded — format in the browser's own locale instead.
|
|
57
|
+
return typeof navigator !== 'undefined' ? navigator.language : 'en';
|
|
58
|
+
}
|
|
59
|
+
}
|
|
60
|
+
/**
|
|
61
|
+
* Decides which timeline items actually render their timestamp. An item is a
|
|
62
|
+
* candidate when timestamps are on, or when its slot is {@link ChatTimestampSlot.alwaysShown}.
|
|
63
|
+
* A candidate renders only when its label differs from the last RENDERED label,
|
|
64
|
+
* so a run of items that would all read "3 minutes ago" shows it once, at the top
|
|
65
|
+
* of the run. Re-run on every minute tick: labels move with the clock, so the
|
|
66
|
+
* grouping does too.
|
|
67
|
+
*
|
|
68
|
+
* @param slots - One entry per rendered timeline item, in order (`null` = no timestamp).
|
|
69
|
+
* @param options - The visibility preference, the current time, and the locale.
|
|
70
|
+
* @param options.visible - Whether timestamps are turned on for every item.
|
|
71
|
+
* @param options.now - Epoch milliseconds to measure from.
|
|
72
|
+
* @param options.locale - BCP 47 locale for the labels.
|
|
73
|
+
* @returns The ids of the items whose timestamp renders.
|
|
74
|
+
*/
|
|
75
|
+
export function planChatTimestamps(slots, options) {
|
|
76
|
+
const shown = new Set();
|
|
77
|
+
let lastLabel;
|
|
78
|
+
for (const slot of slots) {
|
|
79
|
+
if (!slot || !(options.visible || slot.alwaysShown))
|
|
80
|
+
continue;
|
|
81
|
+
const label = formatChatRelativeTime(slot.timestamp, Math.max(options.now, slot.timestamp), options.locale);
|
|
82
|
+
if (label === lastLabel)
|
|
83
|
+
continue;
|
|
84
|
+
shown.add(slot.id);
|
|
85
|
+
lastLabel = label;
|
|
86
|
+
}
|
|
87
|
+
return shown;
|
|
88
|
+
}
|
|
89
|
+
/**
|
|
90
|
+
* Persists this device's preference and notifies every mounted chat in this tab.
|
|
91
|
+
*
|
|
92
|
+
* @param visible - Whether chat timestamps should be shown.
|
|
93
|
+
*/
|
|
94
|
+
export function setChatTimestampsVisible(visible) {
|
|
95
|
+
try {
|
|
96
|
+
localStorage.setItem(CHAT_TIMESTAMPS_STORAGE_KEY, String(visible));
|
|
97
|
+
}
|
|
98
|
+
catch (_error) {
|
|
99
|
+
// localStorage unavailable — the event below still applies it for this session.
|
|
100
|
+
}
|
|
101
|
+
if (typeof window !== 'undefined') {
|
|
102
|
+
window.dispatchEvent(new CustomEvent(CHAT_TIMESTAMPS_EVENT, { detail: visible }));
|
|
103
|
+
}
|
|
104
|
+
}
|
|
105
|
+
/**
|
|
106
|
+
* Parses `/timestamps [on | off]`. `show`/`hide` are accepted as synonyms.
|
|
107
|
+
*
|
|
108
|
+
* @param input - The trimmed composer text.
|
|
109
|
+
* @returns The parsed command, or `null` when the text is not `/timestamps`.
|
|
110
|
+
*/
|
|
111
|
+
export function parseTimestampsCommand(input) {
|
|
112
|
+
const match = input.trim().match(/^\/timestamps(?:\s+(.*))?$/i);
|
|
113
|
+
if (!match)
|
|
114
|
+
return null;
|
|
115
|
+
const arg = match[1]?.trim().toLowerCase() ?? '';
|
|
116
|
+
if (arg === '')
|
|
117
|
+
return { action: 'toggle' };
|
|
118
|
+
if (arg === 'on' || arg === 'show')
|
|
119
|
+
return { action: 'on' };
|
|
120
|
+
if (arg === 'off' || arg === 'hide')
|
|
121
|
+
return { action: 'off' };
|
|
122
|
+
return { action: 'invalid' };
|
|
123
|
+
}
|
|
124
|
+
const MINUTE = 60_000;
|
|
125
|
+
const HOUR = 60 * MINUTE;
|
|
126
|
+
/**
|
|
127
|
+
* Short, localized, MINUTE-precise time for a chat item: "now" and "5 minutes
|
|
128
|
+
* ago" within the hour, then the clock time ("9:25 AM") for earlier today, then
|
|
129
|
+
* the date and time ("Sep 12, 9:25 AM", with the year when it differs).
|
|
130
|
+
*
|
|
131
|
+
* Minute precision at every age is load-bearing: {@link planChatTimestamps}
|
|
132
|
+
* collapses runs of identical labels, so a coarse label ("1 hour ago", "3 days
|
|
133
|
+
* ago") would collapse a whole hour or day of history into one timestamp.
|
|
134
|
+
* Localized by `Intl`, so it needs no translation keys.
|
|
135
|
+
*
|
|
136
|
+
* @param ms - Epoch milliseconds of the item.
|
|
137
|
+
* @param now - Epoch milliseconds to measure from.
|
|
138
|
+
* @param locale - BCP 47 locale (e.g. `'en'`, `'fr'`).
|
|
139
|
+
* @returns The formatted label.
|
|
140
|
+
*/
|
|
141
|
+
export function formatChatRelativeTime(ms, now, locale) {
|
|
142
|
+
const elapsed = Math.max(0, now - ms);
|
|
143
|
+
if (elapsed < HOUR) {
|
|
144
|
+
const rtf = new Intl.RelativeTimeFormat(locale, { numeric: 'auto' });
|
|
145
|
+
return elapsed < MINUTE
|
|
146
|
+
? rtf.format(0, 'second')
|
|
147
|
+
: rtf.format(-Math.floor(elapsed / MINUTE), 'minute');
|
|
148
|
+
}
|
|
149
|
+
const then = new Date(ms);
|
|
150
|
+
const current = new Date(now);
|
|
151
|
+
const clock = { hour: 'numeric', minute: '2-digit' };
|
|
152
|
+
if (then.toDateString() === current.toDateString()) {
|
|
153
|
+
return new Intl.DateTimeFormat(locale, clock).format(ms);
|
|
154
|
+
}
|
|
155
|
+
return new Intl.DateTimeFormat(locale, {
|
|
156
|
+
...clock,
|
|
157
|
+
month: 'short',
|
|
158
|
+
day: 'numeric',
|
|
159
|
+
...(then.getFullYear() === current.getFullYear() ? {} : { year: 'numeric' }),
|
|
160
|
+
}).format(ms);
|
|
161
|
+
}
|
|
162
|
+
/**
|
|
163
|
+
* Exact, localized date and time for a chat item's tooltip and `<time dateTime>`
|
|
164
|
+
* companion (e.g. "Sep 13, 2026, 2:05 PM").
|
|
165
|
+
*
|
|
166
|
+
* @param ms - Epoch milliseconds of the item.
|
|
167
|
+
* @param locale - BCP 47 locale.
|
|
168
|
+
* @returns The formatted date and time.
|
|
169
|
+
*/
|
|
170
|
+
export function formatChatFullTime(ms, locale) {
|
|
171
|
+
return new Intl.DateTimeFormat(locale, { dateStyle: 'medium', timeStyle: 'short' }).format(ms);
|
|
172
|
+
}
|
|
173
|
+
//# sourceMappingURL=chat-timestamps-utilities.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"chat-timestamps-utilities.js","sourceRoot":"","sources":["../../src/components/chat-timestamps-utilities.ts"],"names":[],"mappings":"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"}
|
|
@@ -9,7 +9,9 @@ export { ActivityCard } from './ActivityCard.js';
|
|
|
9
9
|
export * from './chat-autocommit-utilities.js';
|
|
10
10
|
export * from './chat-report-utilities.js';
|
|
11
11
|
export * from './chat-share-utilities.js';
|
|
12
|
+
export * from './chat-timestamps-utilities.js';
|
|
12
13
|
export { ChatPanel } from './ChatPanel.js';
|
|
14
|
+
export * from './ChatTimestamp.js';
|
|
13
15
|
export { CommandPalette } from './CommandPalette.js';
|
|
14
16
|
export * from './device-cycle.js';
|
|
15
17
|
export { DeviceFrameSelector } from './DeviceFrameSelector.js';
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/components/index.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAEH,cAAc,yBAAyB,CAAA;AACvC,YAAY,EAAE,iBAAiB,EAAE,MAAM,mBAAmB,CAAA;AAC1D,OAAO,EAAE,YAAY,EAAE,MAAM,mBAAmB,CAAA;AAChD,cAAc,gCAAgC,CAAA;AAC9C,cAAc,4BAA4B,CAAA;AAC1C,cAAc,2BAA2B,CAAA;AACzC,OAAO,EAAE,SAAS,EAAE,MAAM,gBAAgB,CAAA;AAC1C,OAAO,EAAE,cAAc,EAAE,MAAM,qBAAqB,CAAA;AACpD,cAAc,mBAAmB,CAAA;AACjC,OAAO,EAAE,mBAAmB,EAAE,MAAM,0BAA0B,CAAA;AAC9D,OAAO,EAAE,WAAW,EAAE,MAAM,kBAAkB,CAAA;AAC9C,OAAO,EAAE,YAAY,EAAE,MAAM,mBAAmB,CAAA;AAChD,YAAY,EAAE,SAAS,EAAE,MAAM,WAAW,CAAA;AAC1C,OAAO,EAAE,IAAI,EAAE,MAAM,WAAW,CAAA;AAChC,OAAO,EAAE,sBAAsB,EAAE,MAAM,6BAA6B,CAAA;AACpE,OAAO,EAAE,YAAY,EAAE,MAAM,mBAAmB,CAAA;AAChD,OAAO,EAAE,SAAS,EAAE,MAAM,gBAAgB,CAAA;AAC1C,OAAO,EAAE,WAAW,EAAE,MAAM,kBAAkB,CAAA;AAC9C,OAAO,EAAE,WAAW,EAAE,MAAM,kBAAkB,CAAA;AAC9C,OAAO,EAAE,YAAY,EAAE,MAAM,mBAAmB,CAAA;AAChD,OAAO,EAAE,WAAW,EAAE,MAAM,kBAAkB,CAAA;AAC9C,OAAO,EAAE,gBAAgB,EAAE,MAAM,uBAAuB,CAAA;AACxD,OAAO,EAAE,UAAU,EAAE,MAAM,iBAAiB,CAAA;AAC5C,OAAO,EAAE,WAAW,EAAE,MAAM,kBAAkB,CAAA;AAC9C,OAAO,EAAE,MAAM,EAAE,MAAM,aAAa,CAAA;AACpC,OAAO,EAAE,YAAY,EAAE,MAAM,mBAAmB,CAAA;AAChD,cAAc,4BAA4B,CAAA;AAC1C,YAAY,EAAE,eAAe,EAAE,MAAM,iBAAiB,CAAA;AACtD,OAAO,EAAE,UAAU,EAAE,MAAM,iBAAiB,CAAA;AAC5C,cAAc,iCAAiC,CAAA;AAC/C,OAAO,EAAE,eAAe,EAAE,MAAM,sBAAsB,CAAA"}
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/components/index.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAEH,cAAc,yBAAyB,CAAA;AACvC,YAAY,EAAE,iBAAiB,EAAE,MAAM,mBAAmB,CAAA;AAC1D,OAAO,EAAE,YAAY,EAAE,MAAM,mBAAmB,CAAA;AAChD,cAAc,gCAAgC,CAAA;AAC9C,cAAc,4BAA4B,CAAA;AAC1C,cAAc,2BAA2B,CAAA;AACzC,cAAc,gCAAgC,CAAA;AAC9C,OAAO,EAAE,SAAS,EAAE,MAAM,gBAAgB,CAAA;AAC1C,cAAc,oBAAoB,CAAA;AAClC,OAAO,EAAE,cAAc,EAAE,MAAM,qBAAqB,CAAA;AACpD,cAAc,mBAAmB,CAAA;AACjC,OAAO,EAAE,mBAAmB,EAAE,MAAM,0BAA0B,CAAA;AAC9D,OAAO,EAAE,WAAW,EAAE,MAAM,kBAAkB,CAAA;AAC9C,OAAO,EAAE,YAAY,EAAE,MAAM,mBAAmB,CAAA;AAChD,YAAY,EAAE,SAAS,EAAE,MAAM,WAAW,CAAA;AAC1C,OAAO,EAAE,IAAI,EAAE,MAAM,WAAW,CAAA;AAChC,OAAO,EAAE,sBAAsB,EAAE,MAAM,6BAA6B,CAAA;AACpE,OAAO,EAAE,YAAY,EAAE,MAAM,mBAAmB,CAAA;AAChD,OAAO,EAAE,SAAS,EAAE,MAAM,gBAAgB,CAAA;AAC1C,OAAO,EAAE,WAAW,EAAE,MAAM,kBAAkB,CAAA;AAC9C,OAAO,EAAE,WAAW,EAAE,MAAM,kBAAkB,CAAA;AAC9C,OAAO,EAAE,YAAY,EAAE,MAAM,mBAAmB,CAAA;AAChD,OAAO,EAAE,WAAW,EAAE,MAAM,kBAAkB,CAAA;AAC9C,OAAO,EAAE,gBAAgB,EAAE,MAAM,uBAAuB,CAAA;AACxD,OAAO,EAAE,UAAU,EAAE,MAAM,iBAAiB,CAAA;AAC5C,OAAO,EAAE,WAAW,EAAE,MAAM,kBAAkB,CAAA;AAC9C,OAAO,EAAE,MAAM,EAAE,MAAM,aAAa,CAAA;AACpC,OAAO,EAAE,YAAY,EAAE,MAAM,mBAAmB,CAAA;AAChD,cAAc,4BAA4B,CAAA;AAC1C,YAAY,EAAE,eAAe,EAAE,MAAM,iBAAiB,CAAA;AACtD,OAAO,EAAE,UAAU,EAAE,MAAM,iBAAiB,CAAA;AAC5C,cAAc,iCAAiC,CAAA;AAC/C,OAAO,EAAE,eAAe,EAAE,MAAM,sBAAsB,CAAA"}
|
package/dist/components/index.js
CHANGED
|
@@ -8,7 +8,9 @@ export { ActivityCard } from './ActivityCard.js';
|
|
|
8
8
|
export * from './chat-autocommit-utilities.js';
|
|
9
9
|
export * from './chat-report-utilities.js';
|
|
10
10
|
export * from './chat-share-utilities.js';
|
|
11
|
+
export * from './chat-timestamps-utilities.js';
|
|
11
12
|
export { ChatPanel } from './ChatPanel.js';
|
|
13
|
+
export * from './ChatTimestamp.js';
|
|
12
14
|
export { CommandPalette } from './CommandPalette.js';
|
|
13
15
|
export * from './device-cycle.js';
|
|
14
16
|
export { DeviceFrameSelector } from './DeviceFrameSelector.js';
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/components/index.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAEH,cAAc,yBAAyB,CAAA;AAEvC,OAAO,EAAE,YAAY,EAAE,MAAM,mBAAmB,CAAA;AAChD,cAAc,gCAAgC,CAAA;AAC9C,cAAc,4BAA4B,CAAA;AAC1C,cAAc,2BAA2B,CAAA;AACzC,OAAO,EAAE,SAAS,EAAE,MAAM,gBAAgB,CAAA;AAC1C,OAAO,EAAE,cAAc,EAAE,MAAM,qBAAqB,CAAA;AACpD,cAAc,mBAAmB,CAAA;AACjC,OAAO,EAAE,mBAAmB,EAAE,MAAM,0BAA0B,CAAA;AAC9D,OAAO,EAAE,WAAW,EAAE,MAAM,kBAAkB,CAAA;AAC9C,OAAO,EAAE,YAAY,EAAE,MAAM,mBAAmB,CAAA;AAEhD,OAAO,EAAE,IAAI,EAAE,MAAM,WAAW,CAAA;AAChC,OAAO,EAAE,sBAAsB,EAAE,MAAM,6BAA6B,CAAA;AACpE,OAAO,EAAE,YAAY,EAAE,MAAM,mBAAmB,CAAA;AAChD,OAAO,EAAE,SAAS,EAAE,MAAM,gBAAgB,CAAA;AAC1C,OAAO,EAAE,WAAW,EAAE,MAAM,kBAAkB,CAAA;AAC9C,OAAO,EAAE,WAAW,EAAE,MAAM,kBAAkB,CAAA;AAC9C,OAAO,EAAE,YAAY,EAAE,MAAM,mBAAmB,CAAA;AAChD,OAAO,EAAE,WAAW,EAAE,MAAM,kBAAkB,CAAA;AAC9C,OAAO,EAAE,gBAAgB,EAAE,MAAM,uBAAuB,CAAA;AACxD,OAAO,EAAE,UAAU,EAAE,MAAM,iBAAiB,CAAA;AAC5C,OAAO,EAAE,WAAW,EAAE,MAAM,kBAAkB,CAAA;AAC9C,OAAO,EAAE,MAAM,EAAE,MAAM,aAAa,CAAA;AACpC,OAAO,EAAE,YAAY,EAAE,MAAM,mBAAmB,CAAA;AAChD,cAAc,4BAA4B,CAAA;AAE1C,OAAO,EAAE,UAAU,EAAE,MAAM,iBAAiB,CAAA;AAC5C,cAAc,iCAAiC,CAAA;AAC/C,OAAO,EAAE,eAAe,EAAE,MAAM,sBAAsB,CAAA"}
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/components/index.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAEH,cAAc,yBAAyB,CAAA;AAEvC,OAAO,EAAE,YAAY,EAAE,MAAM,mBAAmB,CAAA;AAChD,cAAc,gCAAgC,CAAA;AAC9C,cAAc,4BAA4B,CAAA;AAC1C,cAAc,2BAA2B,CAAA;AACzC,cAAc,gCAAgC,CAAA;AAC9C,OAAO,EAAE,SAAS,EAAE,MAAM,gBAAgB,CAAA;AAC1C,cAAc,oBAAoB,CAAA;AAClC,OAAO,EAAE,cAAc,EAAE,MAAM,qBAAqB,CAAA;AACpD,cAAc,mBAAmB,CAAA;AACjC,OAAO,EAAE,mBAAmB,EAAE,MAAM,0BAA0B,CAAA;AAC9D,OAAO,EAAE,WAAW,EAAE,MAAM,kBAAkB,CAAA;AAC9C,OAAO,EAAE,YAAY,EAAE,MAAM,mBAAmB,CAAA;AAEhD,OAAO,EAAE,IAAI,EAAE,MAAM,WAAW,CAAA;AAChC,OAAO,EAAE,sBAAsB,EAAE,MAAM,6BAA6B,CAAA;AACpE,OAAO,EAAE,YAAY,EAAE,MAAM,mBAAmB,CAAA;AAChD,OAAO,EAAE,SAAS,EAAE,MAAM,gBAAgB,CAAA;AAC1C,OAAO,EAAE,WAAW,EAAE,MAAM,kBAAkB,CAAA;AAC9C,OAAO,EAAE,WAAW,EAAE,MAAM,kBAAkB,CAAA;AAC9C,OAAO,EAAE,YAAY,EAAE,MAAM,mBAAmB,CAAA;AAChD,OAAO,EAAE,WAAW,EAAE,MAAM,kBAAkB,CAAA;AAC9C,OAAO,EAAE,gBAAgB,EAAE,MAAM,uBAAuB,CAAA;AACxD,OAAO,EAAE,UAAU,EAAE,MAAM,iBAAiB,CAAA;AAC5C,OAAO,EAAE,WAAW,EAAE,MAAM,kBAAkB,CAAA;AAC9C,OAAO,EAAE,MAAM,EAAE,MAAM,aAAa,CAAA;AACpC,OAAO,EAAE,YAAY,EAAE,MAAM,mBAAmB,CAAA;AAChD,cAAc,4BAA4B,CAAA;AAE1C,OAAO,EAAE,UAAU,EAAE,MAAM,iBAAiB,CAAA;AAC5C,cAAc,iCAAiC,CAAA;AAC/C,OAAO,EAAE,eAAe,EAAE,MAAM,sBAAsB,CAAA"}
|
|
@@ -114,6 +114,13 @@ export interface ChatEventCard {
|
|
|
114
114
|
* one). The app owns the identifier; the shared package only matches it.
|
|
115
115
|
*/
|
|
116
116
|
coversLimitType?: string;
|
|
117
|
+
/**
|
|
118
|
+
* Marks the card as a critical event — something failed, was blocked, or stopped
|
|
119
|
+
* the work (a refused deploy, a blocked outbound connection). A critical card
|
|
120
|
+
* keeps its timestamp even while the viewer has timestamps turned off. The app
|
|
121
|
+
* decides; the shared package never infers criticality from a card's tone or copy.
|
|
122
|
+
*/
|
|
123
|
+
critical?: boolean;
|
|
117
124
|
}
|
|
118
125
|
/**
|
|
119
126
|
* Turns a custom event's `data` payload into a chat card, or returns null to render
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"customEventCards.d.ts","sourceRoot":"","sources":["../src/customEventCards.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;GAYG;AAEH,OAAO,KAAK,EAAE,QAAQ,EAAE,MAAM,qBAAqB,CAAA;AAEnD;;;GAGG;AACH,MAAM,WAAW,mBAAmB;IAClC,mDAAmD;IACnD,KAAK,EAAE,MAAM,CAAA;IACb,uEAAuE;IACvE,IAAI,CAAC,EAAE,MAAM,CAAA;IACb,4DAA4D;IAC5D,OAAO,CAAC,EAAE,MAAM,IAAI,CAAA;IACpB;;;OAGG;IACH,IAAI,CAAC,EAAE,OAAO,CAAA;IACd;;;;;;;;OAQG;IACH,KAAK,CAAC,EAAE,SAAS,GAAG,WAAW,GAAG,SAAS,GAAG,SAAS,GAAG,OAAO,GAAG,MAAM,CAAA;CAC3E;AAED;;;;GAIG;AACH,MAAM,WAAW,iBAAiB;IAChC,iDAAiD;IACjD,IAAI,EAAE,MAAM,CAAA;CACb;AAED;;;;GAIG;AACH,MAAM,MAAM,oBAAoB,GAAG,MAAM,GAAG,iBAAiB,GAAG,mBAAmB,CAAA;AAEnF;;;GAGG;AACH,MAAM,WAAW,aAAa;IAC5B,uBAAuB;IACvB,IAAI,EAAE,MAAM,CAAA;IACZ,sFAAsF;IACtF,MAAM,CAAC,EAAE,mBAAmB,GAAG,mBAAmB,EAAE,CAAA;IACpD;;;;;;;;OAQG;IACH,OAAO,CAAC,EAAE,oBAAoB,EAAE,CAAA;IAChC;;;;;OAKG;IACH,UAAU,CAAC,EAAE,OAAO,CAAA;IACpB;;;;;;;;;;;;;OAaG;IACH,IAAI,CAAC,EAAE,MAAM,GAAG,MAAM,GAAG,SAAS,GAAG,SAAS,GAAG,QAAQ,CAAA;IACzD;;;;OAIG;IACH,IAAI,CAAC,EAAE,QAAQ,CAAA;IACf;;;;;;;;;;;OAWG;IACH,eAAe,CAAC,EAAE,MAAM,CAAA;
|
|
1
|
+
{"version":3,"file":"customEventCards.d.ts","sourceRoot":"","sources":["../src/customEventCards.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;GAYG;AAEH,OAAO,KAAK,EAAE,QAAQ,EAAE,MAAM,qBAAqB,CAAA;AAEnD;;;GAGG;AACH,MAAM,WAAW,mBAAmB;IAClC,mDAAmD;IACnD,KAAK,EAAE,MAAM,CAAA;IACb,uEAAuE;IACvE,IAAI,CAAC,EAAE,MAAM,CAAA;IACb,4DAA4D;IAC5D,OAAO,CAAC,EAAE,MAAM,IAAI,CAAA;IACpB;;;OAGG;IACH,IAAI,CAAC,EAAE,OAAO,CAAA;IACd;;;;;;;;OAQG;IACH,KAAK,CAAC,EAAE,SAAS,GAAG,WAAW,GAAG,SAAS,GAAG,SAAS,GAAG,OAAO,GAAG,MAAM,CAAA;CAC3E;AAED;;;;GAIG;AACH,MAAM,WAAW,iBAAiB;IAChC,iDAAiD;IACjD,IAAI,EAAE,MAAM,CAAA;CACb;AAED;;;;GAIG;AACH,MAAM,MAAM,oBAAoB,GAAG,MAAM,GAAG,iBAAiB,GAAG,mBAAmB,CAAA;AAEnF;;;GAGG;AACH,MAAM,WAAW,aAAa;IAC5B,uBAAuB;IACvB,IAAI,EAAE,MAAM,CAAA;IACZ,sFAAsF;IACtF,MAAM,CAAC,EAAE,mBAAmB,GAAG,mBAAmB,EAAE,CAAA;IACpD;;;;;;;;OAQG;IACH,OAAO,CAAC,EAAE,oBAAoB,EAAE,CAAA;IAChC;;;;;OAKG;IACH,UAAU,CAAC,EAAE,OAAO,CAAA;IACpB;;;;;;;;;;;;;OAaG;IACH,IAAI,CAAC,EAAE,MAAM,GAAG,MAAM,GAAG,SAAS,GAAG,SAAS,GAAG,QAAQ,CAAA;IACzD;;;;OAIG;IACH,IAAI,CAAC,EAAE,QAAQ,CAAA;IACf;;;;;;;;;;;OAWG;IACH,eAAe,CAAC,EAAE,MAAM,CAAA;IACxB;;;;;OAKG;IACH,QAAQ,CAAC,EAAE,OAAO,CAAA;CACnB;AAED;;;GAGG;AACH,MAAM,MAAM,oBAAoB,GAAG,CACjC,IAAI,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,GAAG,SAAS,KACtC,aAAa,GAAG,IAAI,CAAA;AAIzB;;;;;;;;GAQG;AACH,wBAAgB,uBAAuB,CAAC,IAAI,EAAE,MAAM,EAAE,OAAO,EAAE,oBAAoB,GAAG,IAAI,CAEzF;AAED;;;;;GAKG;AACH,wBAAgB,yBAAyB,CAAC,IAAI,EAAE,MAAM,GAAG,oBAAoB,GAAG,SAAS,CAExF"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"customEventCards.js","sourceRoot":"","sources":["../src/customEventCards.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;GAYG;
|
|
1
|
+
{"version":3,"file":"customEventCards.js","sourceRoot":"","sources":["../src/customEventCards.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;GAYG;AA8HH,MAAM,QAAQ,GAAG,IAAI,GAAG,EAAgC,CAAA;AAExD;;;;;;;;GAQG;AACH,MAAM,UAAU,uBAAuB,CAAC,IAAY,EAAE,OAA6B;IACjF,QAAQ,CAAC,GAAG,CAAC,IAAI,EAAE,OAAO,CAAC,CAAA;AAC7B,CAAC;AAED;;;;;GAKG;AACH,MAAM,UAAU,yBAAyB,CAAC,IAAY;IACpD,OAAO,QAAQ,CAAC,GAAG,CAAC,IAAI,CAAC,CAAA;AAC3B,CAAC"}
|
package/dist/hooks/index.d.ts
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/hooks/index.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAEH,cAAc,2BAA2B,CAAA;AACzC,cAAc,kBAAkB,CAAA"}
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/hooks/index.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAEH,cAAc,+BAA+B,CAAA;AAC7C,cAAc,2BAA2B,CAAA;AACzC,cAAc,kBAAkB,CAAA"}
|
package/dist/hooks/index.js
CHANGED
package/dist/hooks/index.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/hooks/index.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAEH,cAAc,2BAA2B,CAAA;AACzC,cAAc,kBAAkB,CAAA"}
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/hooks/index.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAEH,cAAc,+BAA+B,CAAA;AAC7C,cAAc,2BAA2B,CAAA;AACzC,cAAc,kBAAkB,CAAA"}
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* React bindings for the per-device chat timestamp preference and the shared
|
|
3
|
+
* minute clock that keeps relative times ("5 minutes ago") current.
|
|
4
|
+
*
|
|
5
|
+
* @module
|
|
6
|
+
*/
|
|
7
|
+
/**
|
|
8
|
+
* Whether chat timestamps are turned on for every item on this device. Re-renders
|
|
9
|
+
* when `/timestamps`, a host settings toggle, or another tab changes it.
|
|
10
|
+
*
|
|
11
|
+
* @returns `true` when every item's timestamp may render (default `false`).
|
|
12
|
+
*/
|
|
13
|
+
export declare function useChatTimestampsVisible(): boolean;
|
|
14
|
+
/**
|
|
15
|
+
* The current time, refreshed once a minute for every subscriber at once.
|
|
16
|
+
*
|
|
17
|
+
* @returns Epoch milliseconds as of the last minute tick.
|
|
18
|
+
*/
|
|
19
|
+
export declare function useMinuteNow(): number;
|
|
20
|
+
//# sourceMappingURL=useChatTimestampsVisible.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"useChatTimestampsVisible.d.ts","sourceRoot":"","sources":["../../src/hooks/useChatTimestampsVisible.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AA6BH;;;;;GAKG;AACH,wBAAgB,wBAAwB,IAAI,OAAO,CAElD;AAgCD;;;;GAIG;AACH,wBAAgB,YAAY,IAAI,MAAM,CAMrC"}
|
|
@@ -0,0 +1,74 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* React bindings for the per-device chat timestamp preference and the shared
|
|
3
|
+
* minute clock that keeps relative times ("5 minutes ago") current.
|
|
4
|
+
*
|
|
5
|
+
* @module
|
|
6
|
+
*/
|
|
7
|
+
import { useSyncExternalStore } from 'react';
|
|
8
|
+
import { CHAT_TIMESTAMPS_EVENT, CHAT_TIMESTAMPS_STORAGE_KEY, getChatTimestampsVisible, } from '../components/chat-timestamps-utilities.js';
|
|
9
|
+
/**
|
|
10
|
+
* Subscribes to preference changes from this tab (the custom event) and from
|
|
11
|
+
* other tabs (the `storage` event).
|
|
12
|
+
*
|
|
13
|
+
* @param onChange - Store-change callback supplied by React.
|
|
14
|
+
* @returns The unsubscribe function.
|
|
15
|
+
*/
|
|
16
|
+
function subscribeVisibility(onChange) {
|
|
17
|
+
const onStorage = (event) => {
|
|
18
|
+
if (event.key === CHAT_TIMESTAMPS_STORAGE_KEY)
|
|
19
|
+
onChange();
|
|
20
|
+
};
|
|
21
|
+
window.addEventListener(CHAT_TIMESTAMPS_EVENT, onChange);
|
|
22
|
+
window.addEventListener('storage', onStorage);
|
|
23
|
+
return () => {
|
|
24
|
+
window.removeEventListener(CHAT_TIMESTAMPS_EVENT, onChange);
|
|
25
|
+
window.removeEventListener('storage', onStorage);
|
|
26
|
+
};
|
|
27
|
+
}
|
|
28
|
+
/**
|
|
29
|
+
* Whether chat timestamps are turned on for every item on this device. Re-renders
|
|
30
|
+
* when `/timestamps`, a host settings toggle, or another tab changes it.
|
|
31
|
+
*
|
|
32
|
+
* @returns `true` when every item's timestamp may render (default `false`).
|
|
33
|
+
*/
|
|
34
|
+
export function useChatTimestampsVisible() {
|
|
35
|
+
return useSyncExternalStore(subscribeVisibility, getChatTimestampsVisible, () => false);
|
|
36
|
+
}
|
|
37
|
+
// One interval for every mounted timestamp, started with the first subscriber
|
|
38
|
+
// and stopped with the last — a long conversation must not run an interval per row.
|
|
39
|
+
const minuteListeners = new Set();
|
|
40
|
+
let minuteTimer;
|
|
41
|
+
let minuteNow = Date.now();
|
|
42
|
+
/**
|
|
43
|
+
* Subscribes to the shared minute clock.
|
|
44
|
+
*
|
|
45
|
+
* @param onChange - Store-change callback supplied by React.
|
|
46
|
+
* @returns The unsubscribe function.
|
|
47
|
+
*/
|
|
48
|
+
function subscribeMinute(onChange) {
|
|
49
|
+
minuteListeners.add(onChange);
|
|
50
|
+
if (minuteTimer === undefined) {
|
|
51
|
+
minuteNow = Date.now();
|
|
52
|
+
minuteTimer = setInterval(() => {
|
|
53
|
+
minuteNow = Date.now();
|
|
54
|
+
for (const listener of minuteListeners)
|
|
55
|
+
listener();
|
|
56
|
+
}, 60_000);
|
|
57
|
+
}
|
|
58
|
+
return () => {
|
|
59
|
+
minuteListeners.delete(onChange);
|
|
60
|
+
if (minuteListeners.size === 0 && minuteTimer !== undefined) {
|
|
61
|
+
clearInterval(minuteTimer);
|
|
62
|
+
minuteTimer = undefined;
|
|
63
|
+
}
|
|
64
|
+
};
|
|
65
|
+
}
|
|
66
|
+
/**
|
|
67
|
+
* The current time, refreshed once a minute for every subscriber at once.
|
|
68
|
+
*
|
|
69
|
+
* @returns Epoch milliseconds as of the last minute tick.
|
|
70
|
+
*/
|
|
71
|
+
export function useMinuteNow() {
|
|
72
|
+
return useSyncExternalStore(subscribeMinute, () => minuteNow, () => minuteNow);
|
|
73
|
+
}
|
|
74
|
+
//# sourceMappingURL=useChatTimestampsVisible.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"useChatTimestampsVisible.js","sourceRoot":"","sources":["../../src/hooks/useChatTimestampsVisible.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAEH,OAAO,EAAE,oBAAoB,EAAE,MAAM,OAAO,CAAA;AAE5C,OAAO,EACL,qBAAqB,EACrB,2BAA2B,EAC3B,wBAAwB,GACzB,MAAM,4CAA4C,CAAA;AAEnD;;;;;;GAMG;AACH,SAAS,mBAAmB,CAAC,QAAoB;IAC/C,MAAM,SAAS,GAAG,CAAC,KAAmB,EAAQ,EAAE;QAC9C,IAAI,KAAK,CAAC,GAAG,KAAK,2BAA2B;YAAE,QAAQ,EAAE,CAAA;IAC3D,CAAC,CAAA;IACD,MAAM,CAAC,gBAAgB,CAAC,qBAAqB,EAAE,QAAQ,CAAC,CAAA;IACxD,MAAM,CAAC,gBAAgB,CAAC,SAAS,EAAE,SAAS,CAAC,CAAA;IAC7C,OAAO,GAAG,EAAE;QACV,MAAM,CAAC,mBAAmB,CAAC,qBAAqB,EAAE,QAAQ,CAAC,CAAA;QAC3D,MAAM,CAAC,mBAAmB,CAAC,SAAS,EAAE,SAAS,CAAC,CAAA;IAClD,CAAC,CAAA;AACH,CAAC;AAED;;;;;GAKG;AACH,MAAM,UAAU,wBAAwB;IACtC,OAAO,oBAAoB,CAAC,mBAAmB,EAAE,wBAAwB,EAAE,GAAG,EAAE,CAAC,KAAK,CAAC,CAAA;AACzF,CAAC;AAED,8EAA8E;AAC9E,oFAAoF;AACpF,MAAM,eAAe,GAAG,IAAI,GAAG,EAAc,CAAA;AAC7C,IAAI,WAAuD,CAAA;AAC3D,IAAI,SAAS,GAAG,IAAI,CAAC,GAAG,EAAE,CAAA;AAE1B;;;;;GAKG;AACH,SAAS,eAAe,CAAC,QAAoB;IAC3C,eAAe,CAAC,GAAG,CAAC,QAAQ,CAAC,CAAA;IAC7B,IAAI,WAAW,KAAK,SAAS,EAAE,CAAC;QAC9B,SAAS,GAAG,IAAI,CAAC,GAAG,EAAE,CAAA;QACtB,WAAW,GAAG,WAAW,CAAC,GAAG,EAAE;YAC7B,SAAS,GAAG,IAAI,CAAC,GAAG,EAAE,CAAA;YACtB,KAAK,MAAM,QAAQ,IAAI,eAAe;gBAAE,QAAQ,EAAE,CAAA;QACpD,CAAC,EAAE,MAAM,CAAC,CAAA;IACZ,CAAC;IACD,OAAO,GAAG,EAAE;QACV,eAAe,CAAC,MAAM,CAAC,QAAQ,CAAC,CAAA;QAChC,IAAI,eAAe,CAAC,IAAI,KAAK,CAAC,IAAI,WAAW,KAAK,SAAS,EAAE,CAAC;YAC5D,aAAa,CAAC,WAAW,CAAC,CAAA;YAC1B,WAAW,GAAG,SAAS,CAAA;QACzB,CAAC;IACH,CAAC,CAAA;AACH,CAAC;AAED;;;;GAIG;AACH,MAAM,UAAU,YAAY;IAC1B,OAAO,oBAAoB,CACzB,eAAe,EACf,GAAG,EAAE,CAAC,SAAS,EACf,GAAG,EAAE,CAAC,SAAS,CAChB,CAAA;AACH,CAAC"}
|
package/dist/index.d.ts
CHANGED
|
@@ -61,6 +61,18 @@
|
|
|
61
61
|
* (`formatReportConfirmation(result)` returns the i18n key + default copy,
|
|
62
62
|
* and `result.url` is the filed issue). `ShareModal` does show the created
|
|
63
63
|
* link inline, but only until it is closed.
|
|
64
|
+
* - Chat timestamps are a PER-DEVICE preference in localStorage, OFF by
|
|
65
|
+
* default — not a `ChatPanel` prop or project setting. Off, only the user's
|
|
66
|
+
* own message headers and critical events show a time; on, every message and
|
|
67
|
+
* event card does. Labels are minute-precise at every age ("3 minutes ago",
|
|
68
|
+
* then "9:25 AM", then "Sep 12, 9:25 AM") and advance each minute; a run of
|
|
69
|
+
* items with the same label shows it once, at the top, so only same-minute
|
|
70
|
+
* runs collapse. A host settings screen
|
|
71
|
+
* toggles it with `setChatTimestampsVisible(bool)` and reads it with
|
|
72
|
+
* `useChatTimestampsVisible()`; `/timestamps [on | off]` writes the same value.
|
|
73
|
+
* - A custom card is a critical event only when its factory sets
|
|
74
|
+
* `critical: true` (a failure, a blocked action, a limit that stopped work) —
|
|
75
|
+
* the package never infers it from tone or copy.
|
|
64
76
|
* - Text routes through `t('ide.*')` — `@molecule/app-locales-ide` supplies
|
|
65
77
|
* translations.
|
|
66
78
|
*
|
package/dist/index.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA+EG;AAEH,cAAc,uBAAuB,CAAA;AACrC,cAAc,uBAAuB,CAAA;AACrC,cAAc,uBAAuB,CAAA;AACrC,cAAc,kBAAkB,CAAA;AAChC,cAAc,wBAAwB,CAAA;AACtC,mBAAmB,YAAY,CAAA"}
|
package/dist/index.js
CHANGED
|
@@ -61,6 +61,18 @@
|
|
|
61
61
|
* (`formatReportConfirmation(result)` returns the i18n key + default copy,
|
|
62
62
|
* and `result.url` is the filed issue). `ShareModal` does show the created
|
|
63
63
|
* link inline, but only until it is closed.
|
|
64
|
+
* - Chat timestamps are a PER-DEVICE preference in localStorage, OFF by
|
|
65
|
+
* default — not a `ChatPanel` prop or project setting. Off, only the user's
|
|
66
|
+
* own message headers and critical events show a time; on, every message and
|
|
67
|
+
* event card does. Labels are minute-precise at every age ("3 minutes ago",
|
|
68
|
+
* then "9:25 AM", then "Sep 12, 9:25 AM") and advance each minute; a run of
|
|
69
|
+
* items with the same label shows it once, at the top, so only same-minute
|
|
70
|
+
* runs collapse. A host settings screen
|
|
71
|
+
* toggles it with `setChatTimestampsVisible(bool)` and reads it with
|
|
72
|
+
* `useChatTimestampsVisible()`; `/timestamps [on | off]` writes the same value.
|
|
73
|
+
* - A custom card is a critical event only when its factory sets
|
|
74
|
+
* `critical: true` (a failure, a blocked action, a limit that stopped work) —
|
|
75
|
+
* the package never infers it from tone or copy.
|
|
64
76
|
* - Text routes through `t('ide.*')` — `@molecule/app-locales-ide` supplies
|
|
65
77
|
* translations.
|
|
66
78
|
*
|
package/dist/index.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA+EG;AAEH,cAAc,uBAAuB,CAAA;AACrC,cAAc,uBAAuB,CAAA;AACrC,cAAc,uBAAuB,CAAA;AACrC,cAAc,kBAAkB,CAAA;AAChC,cAAc,wBAAwB,CAAA"}
|
|
@@ -36,7 +36,7 @@
|
|
|
36
36
|
*/
|
|
37
37
|
import type { CommandId } from './command-metadata.js';
|
|
38
38
|
/** Stable ids for each user-controllable setting (also the i18n key suffix). */
|
|
39
|
-
export type SettingKey = 'model' | 'planModel' | 'executeModel' | 'commitModel' | 'compactModel' | 'mode' | 'effort' | 'maxLoops' | 'autoFix' | 'autoCommit' | 'hooks' | 'autoApproveCommands' | 'sounds';
|
|
39
|
+
export type SettingKey = 'model' | 'planModel' | 'executeModel' | 'commitModel' | 'compactModel' | 'mode' | 'effort' | 'maxLoops' | 'autoFix' | 'autoCommit' | 'hooks' | 'autoApproveCommands' | 'sounds' | 'timestamps';
|
|
40
40
|
/** Canonical, value-free metadata for a single user-controllable setting. */
|
|
41
41
|
export interface SettingMeta {
|
|
42
42
|
/** Stable id (also the i18n key suffix, e.g. `'effort'`). */
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"settings-metadata.d.ts","sourceRoot":"","sources":["../src/settings-metadata.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAmCG;AAEH,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,uBAAuB,CAAA;AAGtD,gFAAgF;AAChF,MAAM,MAAM,UAAU,GAClB,OAAO,GACP,WAAW,GACX,cAAc,GACd,aAAa,GACb,cAAc,GACd,MAAM,GACN,QAAQ,GACR,UAAU,GACV,SAAS,GACT,YAAY,GACZ,OAAO,GACP,qBAAqB,GACrB,QAAQ,CAAA;
|
|
1
|
+
{"version":3,"file":"settings-metadata.d.ts","sourceRoot":"","sources":["../src/settings-metadata.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAmCG;AAEH,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,uBAAuB,CAAA;AAGtD,gFAAgF;AAChF,MAAM,MAAM,UAAU,GAClB,OAAO,GACP,WAAW,GACX,cAAc,GACd,aAAa,GACb,cAAc,GACd,MAAM,GACN,QAAQ,GACR,UAAU,GACV,SAAS,GACT,YAAY,GACZ,OAAO,GACP,qBAAqB,GACrB,QAAQ,GACR,YAAY,CAAA;AAEhB,6EAA6E;AAC7E,MAAM,WAAW,WAAW;IAC1B,6DAA6D;IAC7D,EAAE,EAAE,UAAU,CAAA;IACd,0EAA0E;IAC1E,KAAK,EAAE,MAAM,CAAA;IACb;;;;OAIG;IACH,WAAW,EAAE,MAAM,CAAA;IACnB;;;;OAIG;IACH,WAAW,CAAC,EAAE,SAAS,CAAA;IACvB;;;;;;OAMG;IACH,SAAS,CAAC,EAAE,MAAM,CAAA;CACnB;AAED;;;;;;;;;GASG;AACH,eAAO,MAAM,QAAQ,EAAE,SAAS,WAAW,EAgGjC,CAAA"}
|
|
@@ -127,5 +127,11 @@ export const SETTINGS = [
|
|
|
127
127
|
description: 'Per-event notification sounds for responses, errors, file changes, and more.',
|
|
128
128
|
editCommand: 'sounds',
|
|
129
129
|
},
|
|
130
|
+
{
|
|
131
|
+
id: 'timestamps',
|
|
132
|
+
label: 'Timestamps',
|
|
133
|
+
description: 'Show the time on every chat message and event. Off by default; your own messages and critical events always show it. This device only.',
|
|
134
|
+
editCommand: 'timestamps',
|
|
135
|
+
},
|
|
130
136
|
];
|
|
131
137
|
//# sourceMappingURL=settings-metadata.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"settings-metadata.js","sourceRoot":"","sources":["../src/settings-metadata.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAmCG;AAGH,OAAO,EAAE,2BAA2B,EAAE,MAAM,2CAA2C,CAAA;
|
|
1
|
+
{"version":3,"file":"settings-metadata.js","sourceRoot":"","sources":["../src/settings-metadata.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAmCG;AAGH,OAAO,EAAE,2BAA2B,EAAE,MAAM,2CAA2C,CAAA;AA+CvF;;;;;;;;;GASG;AACH,MAAM,CAAC,MAAM,QAAQ,GAA2B;IAC9C;QACE,EAAE,EAAE,OAAO;QACX,KAAK,EAAE,eAAe;QACtB,WAAW,EAAE,oEAAoE;QACjF,WAAW,EAAE,OAAO;KACrB;IACD;QACE,EAAE,EAAE,WAAW;QACf,KAAK,EAAE,iBAAiB;QACxB,WAAW,EAAE,0EAA0E;QACvF,WAAW,EAAE,OAAO;QACpB,SAAS,EAAE,eAAe;KAC3B;IACD;QACE,EAAE,EAAE,cAAc;QAClB,KAAK,EAAE,oBAAoB;QAC3B,WAAW,EAAE,6EAA6E;QAC1F,WAAW,EAAE,OAAO;QACpB,SAAS,EAAE,kBAAkB;KAC9B;IACD;QACE,EAAE,EAAE,aAAa;QACjB,KAAK,EAAE,sBAAsB;QAC7B,WAAW,EAAE,iFAAiF;QAC9F,WAAW,EAAE,OAAO;QACpB,SAAS,EAAE,iBAAiB;KAC7B;IACD;QACE,EAAE,EAAE,cAAc;QAClB,KAAK,EAAE,kBAAkB;QACzB,WAAW,EACT,kIAAkI;QACpI,WAAW,EAAE,OAAO;QACpB,SAAS,EAAE,kBAAkB;KAC9B;IACD;QACE,EAAE,EAAE,MAAM;QACV,KAAK,EAAE,MAAM;QACb,WAAW,EACT,oFAAoF;QACtF,WAAW,EAAE,MAAM;KACpB;IACD;QACE,EAAE,EAAE,QAAQ;QACZ,KAAK,EAAE,kBAAkB;QACzB,WAAW,EACT,yIAAyI;QAC3I,WAAW,EAAE,QAAQ;KACtB;IACD;QACE,EAAE,EAAE,UAAU;QACd,KAAK,EAAE,qBAAqB;QAC5B,WAAW,EACT,wFAAwF;QAC1F,WAAW,EAAE,UAAU;KACxB;IACD;QACE,EAAE,EAAE,SAAS;QACb,KAAK,EAAE,UAAU;QACjB,WAAW,EACT,kGAAkG;QACpG,WAAW,EAAE,SAAS;KACvB;IACD;QACE,EAAE,EAAE,YAAY;QAChB,KAAK,EAAE,aAAa;QACpB,WAAW,EAAE,sGAAsG,2BAA2B,+LAA+L;QAC7U,WAAW,EAAE,YAAY;KAC1B;IACD;QACE,EAAE,EAAE,OAAO;QACX,KAAK,EAAE,OAAO;QACd,WAAW,EACT,0MAA0M;KAC7M;IACD;QACE,EAAE,EAAE,qBAAqB;QACzB,KAAK,EAAE,uBAAuB;QAC9B,WAAW,EACT,wNAAwN;QAC1N,WAAW,EAAE,aAAa;KAC3B;IACD;QACE,EAAE,EAAE,QAAQ;QACZ,KAAK,EAAE,qBAAqB;QAC5B,WAAW,EAAE,8EAA8E;QAC3F,WAAW,EAAE,QAAQ;KACtB;IACD;QACE,EAAE,EAAE,YAAY;QAChB,KAAK,EAAE,YAAY;QACnB,WAAW,EACT,wIAAwI;QAC1I,WAAW,EAAE,YAAY;KAC1B;CACO,CAAA"}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@molecule/app-ide-react",
|
|
3
|
-
"version": "1.
|
|
3
|
+
"version": "1.12.1",
|
|
4
4
|
"description": "React IDE components for molecule.dev workspace",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"main": "dist/index.js",
|
|
@@ -62,9 +62,9 @@
|
|
|
62
62
|
"@molecule/app-i18n": "1.0.1",
|
|
63
63
|
"@molecule/app-icons": "1.0.1",
|
|
64
64
|
"@molecule/app-live-preview": "1.0.1",
|
|
65
|
-
"@molecule/app-locales-ide": "1.
|
|
65
|
+
"@molecule/app-locales-ide": "1.5.0",
|
|
66
66
|
"@molecule/app-logger": "1.0.1",
|
|
67
|
-
"@molecule/app-react": "1.4.
|
|
67
|
+
"@molecule/app-react": "1.4.3",
|
|
68
68
|
"@molecule/app-storage": "1.0.1",
|
|
69
69
|
"@molecule/app-ui": "1.1.0",
|
|
70
70
|
"@molecule/app-ui-react": "1.0.1",
|