arcane-os 0.37.0 → 0.38.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.
- package/CHANGELOG.md +12 -0
- package/README.md +1 -1
- package/docs/reference/inventory/runtime-components.json +1 -1
- package/docs/reference/inventory/runtime-entities.json +1 -1
- package/docs/reference/runtime-components.md +5 -1
- package/docs/reference/runtime-entities.md +23 -0
- package/package.json +1 -1
- package/runtime/arcane/components/file-manager.html +24 -3
- package/runtime/arcane/entities/User.js +20 -0
package/CHANGELOG.md
CHANGED
|
@@ -1,5 +1,17 @@
|
|
|
1
1
|
# Changelog
|
|
2
2
|
|
|
3
|
+
## 0.38.0
|
|
4
|
+
|
|
5
|
+
- Add `User.AI_name` as an application-owned complete string with an empty-string
|
|
6
|
+
default, ordinary getter/setter, profile loading and `updateExplicit` support.
|
|
7
|
+
Preserve older saved profiles and restore the hydrated baseline after a failed
|
|
8
|
+
save; no existing history or provider/model selection is rewritten.
|
|
9
|
+
- Distinguish saved conversation speakers in file previews using the shared
|
|
10
|
+
action/action-text colors for user cards and surface/text colors for assistant
|
|
11
|
+
cards. Assistant headings use the complete saved nonblank string name or `AI`,
|
|
12
|
+
without a role suffix. Preserve other role labels, timestamps, status, complete
|
|
13
|
+
content and persistence. Capturing names on new Chat turns is separate work.
|
|
14
|
+
|
|
3
15
|
## 0.37.0
|
|
4
16
|
|
|
5
17
|
- Add opt-in `markdown-editor` fit layout and preview following through
|
package/README.md
CHANGED
|
@@ -19,7 +19,7 @@ version-locked SDK runtime, while an integrated Arcane checkout uses its live
|
|
|
19
19
|
`arcane/` runtime. Both profiles share the theme, packaging, event, cancellation,
|
|
20
20
|
and browser run contracts while retaining their selected application layout.
|
|
21
21
|
|
|
22
|
-
This checkout defines the `0.
|
|
22
|
+
This checkout defines the `0.38.0` SDK contract. Applications pin one exact npm
|
|
23
23
|
version and lockfile; registry state is deliberately not baked into application
|
|
24
24
|
artifacts.
|
|
25
25
|
|
|
@@ -421,7 +421,7 @@
|
|
|
421
421
|
],
|
|
422
422
|
"availability": "Browser and supported native WebViews",
|
|
423
423
|
"transport": "HTMLImport + DOM; injected Arcane/provider modules where listed",
|
|
424
|
-
"normalization": "Selection/filter state and neutral previews normalized; storage/provider behavior mixed. Initial directoryFilter and setDirectoryFilter(fn|null) use false-only exclusion before built-in DBOPFS key/metadata reads; data-hidden-prefixes also applies to directories unless data-show-hidden is present. Existing file predicates preserve their first argument and receive optional directory/fileName/path/layout context. previewDescriptor(original File,{directory,fileName,extension,path,mimeType,signal}) may asynchronously return text/markdown/html/json content, conversation messages with role/content/real timestamp and optional name/status, collection items, or image/audio/pdf/download content as Blob/File or a lazy ({signal}) loader. Downloads require fileName; descriptors accept title and images accept alt. Lazy items load only on explicit request and retain item-local retry. Close, replacement, and destroy abort the preview signal, suppress late output, remove iframe srcdoc, stop audio, and revoke all owned object URLs. HTML preserves the exact string in iframe srcdoc; HTML/Markdown MIME fallback supports extensionless files. Nullish descriptors preserve previewTransform for JSON-family files and native previews; untransformed JSONL/NDJSON retains complete raw text, and other binary files download the original File."
|
|
424
|
+
"normalization": "Selection/filter state and neutral previews normalized; storage/provider behavior mixed. Initial directoryFilter and setDirectoryFilter(fn|null) use false-only exclusion before built-in DBOPFS key/metadata reads; data-hidden-prefixes also applies to directories unless data-show-hidden is present. Existing file predicates preserve their first argument and receive optional directory/fileName/path/layout context. previewDescriptor(original File,{directory,fileName,extension,path,mimeType,signal}) may asynchronously return text/markdown/html/json content, conversation messages with role/content/real timestamp and optional name/status, collection items, or image/audio/pdf/download content as Blob/File or a lazy ({signal}) loader. Assistant conversation labels use the exact nonblank string name or AI without a role suffix; other role labels retain existing name/role presentation. User and assistant cards have distinct theme backgrounds and preserve data-role. Downloads require fileName; descriptors accept title and images accept alt. Lazy items load only on explicit request and retain item-local retry. Close, replacement, and destroy abort the preview signal, suppress late output, remove iframe srcdoc, stop audio, and revoke all owned object URLs. HTML preserves the exact string in iframe srcdoc; HTML/Markdown MIME fallback supports extensionless files. Nullish descriptors preserve previewTransform for JSON-family files and native previews; untransformed JSONL/NDJSON retains complete raw text, and other binary files download the original File."
|
|
425
425
|
},
|
|
426
426
|
{
|
|
427
427
|
"file": "runtime/arcane/components/header.html",
|
|
@@ -19,7 +19,7 @@
|
|
|
19
19
|
{"file":"runtime/arcane/entities/Preference.js","exports":["default","preferenceSchema"],"availability":"cross-host","normalization":"normalized"},
|
|
20
20
|
{"file":"runtime/arcane/entities/TerminalSession.js","exports":["default","terminalShells"],"availability":"cross-host","normalization":"normalized"},
|
|
21
21
|
{"file":"runtime/arcane/entities/Theme.js","exports":["arcaneDarkThemeTokens","arcaneLightThemeTokens","default","themeColorToHex","themeTokens"],"availability":"cross-host/dom-when-applied","normalization":"normalized/mixed"},
|
|
22
|
-
{"file":"runtime/arcane/entities/User.js","exports":["default","profileUpdateFromSearchParams"],"availability":"browser/native-webview","normalization":"updateExplicit accepts existing partial/JSON updates or an awaited fresh-profile callback under the existing serialized write owner; callback null skips saving and returns the fresh profile, while failed writes restore the fresh baseline. Timestamp setters persist partial fields through that owner. profileUpdateFromSearchParams purely maps nonempty supplied URLSearchParams values without further decoding, trimming, or persistence."},
|
|
22
|
+
{"file":"runtime/arcane/entities/User.js","exports":["default","profileUpdateFromSearchParams"],"availability":"browser/native-webview","normalization":"AI_name is a persisted string preference with an empty-string default that preserves complete supplied text alongside AI_personality; loading older records does not rewrite them. updateExplicit accepts existing partial/JSON updates or an awaited fresh-profile callback under the existing serialized write owner; callback null skips saving and returns the fresh profile, while failed writes restore the fresh baseline. Timestamp setters persist partial fields through that owner. profileUpdateFromSearchParams purely maps nonempty supplied URLSearchParams values without further decoding, trimming, or persistence."},
|
|
23
23
|
{"file":"runtime/arcane/entities/Weather.js","exports":["WeatherDay","WeatherLocation","WeatherObservation","WeatherSnapshot"],"availability":"cross-host","normalization":"normalized"}
|
|
24
24
|
]
|
|
25
25
|
}
|
|
@@ -844,7 +844,11 @@ Each descriptor accepts an optional `title`. Supported shapes are:
|
|
|
844
844
|
| `image`, `audio`, `pdf`, `download` | `content`: a `Blob` or `File`, or a function receiving `{signal}` and resolving to one |
|
|
845
845
|
|
|
846
846
|
Conversation `role` and complete Markdown `content` are strings. Optional
|
|
847
|
-
`name`
|
|
847
|
+
assistant `name` is displayed exactly when it is a nonblank string; otherwise
|
|
848
|
+
the assistant label is `AI`, without a role suffix. User and other role labels
|
|
849
|
+
retain their supplied name alongside the role. User and assistant cards use
|
|
850
|
+
distinct shared-theme backgrounds, and each card retains its original
|
|
851
|
+
`data-role`. Optional `status` is displayed beside the time. Valid supplied
|
|
848
852
|
timestamps are displayed in local time with their real ISO datetime; absent
|
|
849
853
|
timestamps display `Time unavailable`, and an unrecognized supplied timestamp
|
|
850
854
|
is displayed as supplied. No timestamp is invented.
|
|
@@ -274,6 +274,29 @@ Owns persisted user preference/profile fields, explicit-preference updates,
|
|
|
274
274
|
fresh reads, saves, and JSON projection. It installs `window.user` after its
|
|
275
275
|
DBLS/DBOPFS lifecycle and emits `user-entity-loaded`.
|
|
276
276
|
|
|
277
|
+
### AI_name
|
|
278
|
+
|
|
279
|
+
Saved AI-name preference alongside `AI_personality`. It is a string with an
|
|
280
|
+
empty-string default and preserves the complete supplied text, including
|
|
281
|
+
Unicode, whitespace, and an explicitly empty value. The property setter follows
|
|
282
|
+
the same persistence setting as `AI_personality`; non-string assignments throw
|
|
283
|
+
`Error('AI_name must be string')`.
|
|
284
|
+
|
|
285
|
+
`explicit`, `toJSON()`, `load()`, `refresh()`, and `updateExplicit()` include
|
|
286
|
+
this field through the existing profile schema. Loading an older record that
|
|
287
|
+
omits it leaves a new entity's empty default in memory and does not rewrite the
|
|
288
|
+
stored record. Partial updates that omit it retain the current value.
|
|
289
|
+
|
|
290
|
+
```javascript
|
|
291
|
+
await user.updateExplicit(
|
|
292
|
+
{AI_name: 'Captain Moonboots'}
|
|
293
|
+
);
|
|
294
|
+
```
|
|
295
|
+
|
|
296
|
+
The application owns naming choices and any mapping to its AI display name;
|
|
297
|
+
this preference changes neither the human `username` nor chat history. No
|
|
298
|
+
automatic migration or naming policy runs when it is loaded or saved.
|
|
299
|
+
|
|
277
300
|
### updateExplicit(update)
|
|
278
301
|
|
|
279
302
|
Accepts an ordinary partial profile object, a JSON string, or a function
|
package/package.json
CHANGED
|
@@ -387,6 +387,21 @@
|
|
|
387
387
|
background:var(--background);
|
|
388
388
|
}
|
|
389
389
|
|
|
390
|
+
.file-preview-message[data-role="user"]{
|
|
391
|
+
background:var(--arcane-action,var(--primary-color));
|
|
392
|
+
color:var(--arcane-action-text,var(--button-text-color,var(--text-color)));
|
|
393
|
+
border-color:var(--arcane-action,var(--primary-color));
|
|
394
|
+
}
|
|
395
|
+
|
|
396
|
+
.file-preview-message[data-role="user"] a{
|
|
397
|
+
color:inherit;
|
|
398
|
+
}
|
|
399
|
+
|
|
400
|
+
.file-preview-message[data-role="assistant"]{
|
|
401
|
+
background:var(--arcane-surface,var(--background));
|
|
402
|
+
color:var(--text-color);
|
|
403
|
+
}
|
|
404
|
+
|
|
390
405
|
.file-preview-message header,
|
|
391
406
|
.file-preview-message footer{
|
|
392
407
|
display:flex;
|
|
@@ -1740,9 +1755,15 @@
|
|
|
1740
1755
|
const time=document.createElement('time');
|
|
1741
1756
|
article.className='file-preview-message';
|
|
1742
1757
|
article.dataset.role=message.role;
|
|
1743
|
-
|
|
1744
|
-
|
|
1745
|
-
|
|
1758
|
+
if(message.role==='assistant'){
|
|
1759
|
+
speaker.textContent=is.string(message.name)&&message.name.trim()
|
|
1760
|
+
?message.name
|
|
1761
|
+
:'AI';
|
|
1762
|
+
}else{
|
|
1763
|
+
speaker.textContent=message.name===undefined
|
|
1764
|
+
?message.role
|
|
1765
|
+
:`${message.name} · ${message.role}`;
|
|
1766
|
+
}
|
|
1746
1767
|
header.append(speaker);
|
|
1747
1768
|
if(message.timestamp===undefined||message.timestamp===null){
|
|
1748
1769
|
time.textContent='Time unavailable';
|
|
@@ -110,6 +110,7 @@ function userEntityLifecycleError(code,reason,message){
|
|
|
110
110
|
* @property {string|number} contact_4
|
|
111
111
|
* @property {string|number} contact_5
|
|
112
112
|
* @property {string|number} contact_6
|
|
113
|
+
* @property {string} AI_name
|
|
113
114
|
* @property {string} AI_personality
|
|
114
115
|
* @property {string} religion
|
|
115
116
|
* @property {string} AI_voice
|
|
@@ -176,6 +177,7 @@ class UserEntity {
|
|
|
176
177
|
'contact_5',
|
|
177
178
|
'contact_6',
|
|
178
179
|
|
|
180
|
+
'AI_name',
|
|
179
181
|
'AI_personality',
|
|
180
182
|
'religion',
|
|
181
183
|
'AI_voice',
|
|
@@ -211,6 +213,7 @@ class UserEntity {
|
|
|
211
213
|
#contact_5 = '';
|
|
212
214
|
#contact_6 = '';
|
|
213
215
|
|
|
216
|
+
#aiName = '';
|
|
214
217
|
#AI_personality = '';
|
|
215
218
|
#religion = '';
|
|
216
219
|
#AI_voice = '';
|
|
@@ -515,6 +518,22 @@ class UserEntity {
|
|
|
515
518
|
|
|
516
519
|
|
|
517
520
|
|
|
521
|
+
/** @returns {string} */
|
|
522
|
+
get AI_name() {
|
|
523
|
+
return this.#aiName;
|
|
524
|
+
}
|
|
525
|
+
|
|
526
|
+
/** @param {string} v */
|
|
527
|
+
set AI_name(v) {
|
|
528
|
+
if (!is.string(v)) {
|
|
529
|
+
throw new Error('AI_name must be string');
|
|
530
|
+
}
|
|
531
|
+
|
|
532
|
+
this.#aiName = v;
|
|
533
|
+
|
|
534
|
+
this.#persist();
|
|
535
|
+
}
|
|
536
|
+
|
|
518
537
|
/** @returns {string} */
|
|
519
538
|
get AI_personality(){
|
|
520
539
|
return this.#AI_personality;
|
|
@@ -889,6 +908,7 @@ class UserEntity {
|
|
|
889
908
|
this.persist=persist;
|
|
890
909
|
}
|
|
891
910
|
|
|
911
|
+
baseline = this.explicit;
|
|
892
912
|
const conditional=is.function(src);
|
|
893
913
|
const update=conditional?await src(this.explicit):src;
|
|
894
914
|
if(conditional&&update===null){
|