arcane-os 0.44.0 → 0.46.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 +42 -0
- package/README.md +1 -1
- package/docs/reference/runtime-components.md +78 -7
- package/docs/reference/runtime-modules.md +139 -7
- package/package.json +2 -2
- package/runtime/arcane/components/chat.html +27 -6
- package/runtime/arcane/components/file-manager.html +146 -8
- package/runtime/arcane/components/markdown-document.html +31 -4
- package/runtime/arcane/components/markdown-editor.html +113 -4
- package/runtime/arcane/css/theme.css +41 -0
- package/runtime/arcane/entities/Chat.js +6 -4
- package/runtime/arcane/modules/MD.js +14 -0
- package/runtime/arcane/modules/MarkdownMedia.js +239 -0
- package/runtime/arcane/modules/PersistentAIChatSession.js +22 -8
- package/runtime/arcane/modules/PrintView.js +74 -15
package/CHANGELOG.md
CHANGED
|
@@ -1,5 +1,47 @@
|
|
|
1
1
|
# Changelog
|
|
2
2
|
|
|
3
|
+
## 0.46.0
|
|
4
|
+
|
|
5
|
+
- Add public `decodeMarkdownMediaRecord` for complete stored image records or
|
|
6
|
+
JSON text without storage or network access. Preserve singleton record layers,
|
|
7
|
+
original content and explicit decoding errors; never select from multiple
|
|
8
|
+
records. File previews recognize declared image records in JSON-family files
|
|
9
|
+
while ordinary untyped/non-image JSON and application preview hooks keep their
|
|
10
|
+
existing presentation and precedence.
|
|
11
|
+
- Preserve complete standalone IMG tags with multiline quoted descriptions
|
|
12
|
+
through the shared Markdown renderer and its original-source mapping. Native
|
|
13
|
+
HTML handling and literal Markdown examples keep their existing parsing;
|
|
14
|
+
stored Markdown is unchanged and requires no migration.
|
|
15
|
+
- Use the existing light paper palette and 15mm page margins for rendered print
|
|
16
|
+
snapshots and direct shared-theme printing. Preserve full content, rendered
|
|
17
|
+
fonts, image pixels, SVG artwork, live screen preferences, cancellation and
|
|
18
|
+
resource ownership through afterprint. A dialog request is not proof of
|
|
19
|
+
physical printing or PDF completion.
|
|
20
|
+
- Keep image destinations, export selection, model and credentials application
|
|
21
|
+
owned. No saved-data migration, model/provider/default change or app layout
|
|
22
|
+
change is introduced.
|
|
23
|
+
|
|
24
|
+
## 0.45.0
|
|
25
|
+
|
|
26
|
+
- Add public MarkdownMedia save, read, reference parsing and hydration helpers.
|
|
27
|
+
Store complete image records in application-owned DBOPFS tables outside raw
|
|
28
|
+
Markdown, with stable references and application-selected filenames. Preserve
|
|
29
|
+
JSONL/NDJSON singleton records across cold reads and backup restoration.
|
|
30
|
+
- Hydrate local images independently in shared Markdown views while preserving
|
|
31
|
+
raw Markdown, external URLs, source maps and saving. Observe cancellation and
|
|
32
|
+
individual failures without removing successful sibling images. Retain print
|
|
33
|
+
resources through afterprint; explicit PrintView preparation awaits local
|
|
34
|
+
media while native beforeprint remains synchronous.
|
|
35
|
+
- Apply no-retention semantics to entity-wide persistence choices as well as
|
|
36
|
+
request persist:false: complete input and response remain available to the
|
|
37
|
+
active operation, then stay outside retained transcript, recurring model
|
|
38
|
+
context, DBOPFS and memory extraction. Capture the accepted choice before
|
|
39
|
+
rendering waits and preserve original pending calls after temporary tool
|
|
40
|
+
continuations. Existing retained turns and saved history remain untouched;
|
|
41
|
+
structural sanitization applies to new durable writes only, without migration.
|
|
42
|
+
- Keep image model selection, credentials, storage selection and app orchestration
|
|
43
|
+
application-owned. No model/provider/default changes are introduced.
|
|
44
|
+
|
|
3
45
|
## 0.44.0
|
|
4
46
|
|
|
5
47
|
- Add stateless `generateImages` through `arcane-os/ai/twin-cloud` with
|
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.46.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
|
|
|
@@ -54,6 +54,16 @@ imported component's `destroy()` through `HTMLImport`; callers that invoke
|
|
|
54
54
|
`destroy()` directly retain responsibility for removing the element when
|
|
55
55
|
appropriate.
|
|
56
56
|
|
|
57
|
+
## Shared print presentation
|
|
58
|
+
|
|
59
|
+
Applications loading the shared `theme.css` receive a print-only base light
|
|
60
|
+
palette with a white paper surface and `15mm` page margins. Root, body, and
|
|
61
|
+
scoped `data-arcane-palette` tokens override screen/custom colors during print;
|
|
62
|
+
root/body margins are reset. Saved preferences, screen presentation, scrolling,
|
|
63
|
+
media, and other layout rules remain unchanged. Registered rendered-print
|
|
64
|
+
views use the separate [`PrintView.js`](runtime-modules.md#printviewjs) snapshot
|
|
65
|
+
owner described with the editor and file preview below.
|
|
66
|
+
|
|
57
67
|
## Canonical inventory
|
|
58
68
|
|
|
59
69
|
| Component | Capability | Principal methods | Events | Normalization |
|
|
@@ -426,7 +436,8 @@ history stores each tool's required user-facing message as an ordinary
|
|
|
426
436
|
call envelope or ID and therefore does not recreate a pending executable call
|
|
427
437
|
after reload. `submitToolResult()` and `submitToolResults()` accept `status` as
|
|
428
438
|
the public result term; `disposition` remains an accepted input spelling.
|
|
429
|
-
When a submitted turn uses `persist:false`,
|
|
439
|
+
When a submitted turn uses `persist:false`, or its session's Chat entity has
|
|
440
|
+
`persist=false`, Chat may show its cards while that
|
|
430
441
|
one operation is active, then removes them when the operation settles; neither
|
|
431
442
|
the input nor response remains in the retained transcript or model context.
|
|
432
443
|
This cleanup also applies to failed, cancelled, detached, or replaced-session
|
|
@@ -437,6 +448,15 @@ operation's nodes so a completion listener can start another turn safely.
|
|
|
437
448
|
Submission code passes those card references directly when it creates them;
|
|
438
449
|
reusing an operation identifier never selects earlier conversation cards for
|
|
439
450
|
cleanup or timestamp updates.
|
|
451
|
+
The session's terminal `retained` boolean reports its actual commit decision;
|
|
452
|
+
Chat uses that decision instead of retroactively interpreting a flag changed
|
|
453
|
+
for a later request. A completion listener cannot erase an earlier settled
|
|
454
|
+
turn by changing the next operation's retention setting.
|
|
455
|
+
Chat carries a submission's no-retention choice into its copied session request
|
|
456
|
+
before any rendering wait, so re-enabling the entity before dispatch cannot
|
|
457
|
+
retain that temporary input. Existing falsy entity settings retain their
|
|
458
|
+
no-retention meaning; a compatible custom session without a Chat entity keeps
|
|
459
|
+
its existing default behavior.
|
|
440
460
|
Persistent-turn recovery and existing saved history remain unchanged.
|
|
441
461
|
|
|
442
462
|
For streaming sessions, every provisional structural card and the terminal
|
|
@@ -909,7 +929,16 @@ extension. Routing compares the lowercase MIME essence without its parameters;
|
|
|
909
929
|
the callback's `mimeType` and the file content remain unchanged.
|
|
910
930
|
HTML uses its complete original string in `srcdoc` without an
|
|
911
931
|
added sandbox policy; Markdown reads the complete original text before
|
|
912
|
-
rendering.
|
|
932
|
+
rendering. With no descriptor or `previewTransform`, JSON, JSONL, and NDJSON
|
|
933
|
+
files are read in full and recognized through
|
|
934
|
+
[`decodeMarkdownMediaRecord()`](runtime-modules.md#markdownmediajs). A complete
|
|
935
|
+
stored image record, including nested single-record arrays, opens as an image
|
|
936
|
+
when its decoded Blob has an `image/` media type. Untyped/non-image records,
|
|
937
|
+
multiple records, and unrecognized content keep their ordinary JSON-family
|
|
938
|
+
presentation; malformed recognized image encoding follows the existing
|
|
939
|
+
file-open failure path.
|
|
940
|
+
This recognition leaves saved content unchanged and performs no migration.
|
|
941
|
+
Untransformed JSONL/NDJSON shows its complete original text,
|
|
913
942
|
including lines that are not JSON records. Other binary files offer a download
|
|
914
943
|
of the original `File`.
|
|
915
944
|
The larger file-preview dialog reuses `--modal-width`, `--modal-max-height`,
|
|
@@ -921,11 +950,26 @@ preview ahead of the editor. Printing uses the shared
|
|
|
921
950
|
[`PrintView.js`](runtime-modules.md#printviewjs) owner; accessible HTML frames
|
|
922
951
|
are copied from their current rendered document, never substituted with source
|
|
923
952
|
text. Explicit printing waits for images/fonts and HTML frame readiness.
|
|
953
|
+
The shared print surface uses a light paper palette and `15mm` page margins
|
|
954
|
+
while preserving image/SVG colors and leaving the screen theme unchanged.
|
|
924
955
|
Native PDF and inaccessible embedded viewers require their own print command.
|
|
925
956
|
`true` means the browser print dialog was requested, not that paper or a PDF
|
|
926
957
|
was produced. Closed, destroyed, or unavailable previews return `false`;
|
|
927
958
|
preparation failures reject and the visible control reports a concise failure.
|
|
928
959
|
|
|
960
|
+
Markdown previews resolve saved `arcane-media:` images through
|
|
961
|
+
[`MarkdownMedia.js`](runtime-modules.md#markdownmediajs) before connecting IMG
|
|
962
|
+
nodes. Text appears while independent image reads finish; failures leave the
|
|
963
|
+
complete text and successful images visible with a concise recovery status.
|
|
964
|
+
Explicit printing waits for local reads and decoding. Native Print reports
|
|
965
|
+
pending media because it cannot await them. Closing or replacing a preview
|
|
966
|
+
cancels display readiness without waiting for storage; URLs already retained
|
|
967
|
+
by a requested print remain until `afterprint`. Original Markdown and ordinary
|
|
968
|
+
external image URLs remain unchanged.
|
|
969
|
+
Standalone IMG blocks with multiline quoted descriptions use the shared
|
|
970
|
+
[`MD.js`](runtime-modules.md#mdjs) tokenizer in both ordinary and source-mapped
|
|
971
|
+
rendering; the complete description and stored Markdown remain intact.
|
|
972
|
+
|
|
929
973
|
`await close()` cancels pending presentation work and closes delete, file, and
|
|
930
974
|
directory dialogs in that order. A settled preview keeps its rendered content,
|
|
931
975
|
media, and printing available until the file dialog actually closes; refusing
|
|
@@ -937,7 +981,7 @@ writes complete through the storage owner without reopening closed dialogs.
|
|
|
937
981
|
|
|
938
982
|
Events: `file-manager-ready`, `file-manager-select`, `file-manager-open`, `file-manager-action`.
|
|
939
983
|
|
|
940
|
-
Shared dependencies: [`DBOPFS.js`](runtime-modules.md#dbopfsjs), [`File.js`](runtime-entities.md#filejs), [`MD.js`](runtime-modules.md#mdjs), [`WaitForComponent.js`](runtime-modules.md#waitforcomponentjs).
|
|
984
|
+
Shared dependencies: [`DBOPFS.js`](runtime-modules.md#dbopfsjs), [`File.js`](runtime-entities.md#filejs), [`MD.js`](runtime-modules.md#mdjs), [`MarkdownMedia.js`](runtime-modules.md#markdownmediajs), [`PrintView.js`](runtime-modules.md#printviewjs), [`WaitForComponent.js`](runtime-modules.md#waitforcomponentjs).
|
|
941
985
|
|
|
942
986
|
### Availability and normalization
|
|
943
987
|
|
|
@@ -1054,7 +1098,19 @@ Events: `markdown-document-ready`, `markdown-document-state`,
|
|
|
1054
1098
|
`markdown-document-empty`, `markdown-document-error`, and
|
|
1055
1099
|
`markdown-document-navigate`.
|
|
1056
1100
|
|
|
1057
|
-
|
|
1101
|
+
Saved local image references use
|
|
1102
|
+
[`MarkdownMedia.js`](runtime-modules.md#markdownmediajs). Text rendering and
|
|
1103
|
+
the existing rendered event do not wait for image reads. The optional
|
|
1104
|
+
`labels.mediaError` supplies concise visible failure text while complete
|
|
1105
|
+
diagnostics remain in the developer console; successful images and document
|
|
1106
|
+
text remain visible. Replacing, clearing, failing, or destroying the document
|
|
1107
|
+
releases its display resources without deleting stored media. Markdown source
|
|
1108
|
+
and ordinary external image URLs remain unchanged.
|
|
1109
|
+
Complete standalone IMG blocks with quoted multiline descriptions render
|
|
1110
|
+
through the shared [`MD.js`](runtime-modules.md#mdjs) tokenizer without
|
|
1111
|
+
rewriting saved Markdown.
|
|
1112
|
+
|
|
1113
|
+
Shared dependencies: [`MD.js`](runtime-modules.md#mdjs), [`MarkdownMedia.js`](runtime-modules.md#markdownmediajs).
|
|
1058
1114
|
|
|
1059
1115
|
### Availability and normalization
|
|
1060
1116
|
|
|
@@ -1096,14 +1152,29 @@ The visible **Print** control and `await print()` print the complete rendered
|
|
|
1096
1152
|
Markdown with `entryTitle`, independently of saving. Native browser Print uses
|
|
1097
1153
|
that same registered view unless an open file preview takes precedence.
|
|
1098
1154
|
The SDK copies current rendered DOM/styles into a temporary print-only view,
|
|
1099
|
-
leaving the editor's source, controls, and screen layout in place.
|
|
1100
|
-
|
|
1155
|
+
leaving the editor's source, controls, and screen layout in place. Both explicit
|
|
1156
|
+
and native print use the shared light paper palette and `15mm` page margins;
|
|
1157
|
+
image pixels and SVG artwork keep their colors. Explicit printing waits for
|
|
1158
|
+
resource readiness; native `beforeprint` is synchronous
|
|
1101
1159
|
and uses the currently rendered content. `print()` returns `false` when the
|
|
1102
1160
|
view is unavailable, rejects preparation failures, and returns `true` only
|
|
1103
1161
|
when the browser dialog was requested. Completion of physical printing or PDF
|
|
1104
1162
|
saving is not observable through this method. See
|
|
1105
1163
|
[`PrintView.js`](runtime-modules.md#printviewjs).
|
|
1106
1164
|
|
|
1165
|
+
Saved `arcane-media:` image references are hydrated through
|
|
1166
|
+
[`MarkdownMedia.js`](runtime-modules.md#markdownmediajs) in detached rendered
|
|
1167
|
+
nodes. Source text, edit selection, source-map comments, ordinary image URLs,
|
|
1168
|
+
and the existing save flow remain unchanged. Image status has its own
|
|
1169
|
+
idle-hidden `media-status` part, separate from save status. Explicit printing
|
|
1170
|
+
waits for the current image reads/decoding, follows a replacement preview, and
|
|
1171
|
+
rechecks readiness before capture. Native Print reports still-pending media
|
|
1172
|
+
synchronously; it cannot wait or cancel the native dialog. Print-owned URLs
|
|
1173
|
+
outlive a changed or destroyed editor until `afterprint`.
|
|
1174
|
+
The shared [`MD.js`](runtime-modules.md#mdjs) tokenizer preserves complete
|
|
1175
|
+
standalone IMG blocks with quoted multiline descriptions in ordinary and
|
|
1176
|
+
source-mapped rendering. Existing saved markup needs no rewriting.
|
|
1177
|
+
|
|
1107
1178
|
`configure({fit:true,followPreview:true})` opts into the two independent
|
|
1108
1179
|
behaviors. Both options default to `false`; omitted options retain their
|
|
1109
1180
|
previous values during reconfiguration, and explicit `false` disables either.
|
|
@@ -1140,7 +1211,7 @@ lists, quotes, and tables follow their block, while invisible source positions
|
|
|
1140
1211
|
use a nearby available rendered block rather than exact glyph geometry.
|
|
1141
1212
|
|
|
1142
1213
|
Public CSS parts are `editor`, `title`, `toolbar`, `input`, `preview`,
|
|
1143
|
-
`actions`, `status`, `print-action`, and `save-action`. Applications can make the title
|
|
1214
|
+
`actions`, `status`, `media-status`, `print-action`, and `save-action`. Applications can make the title
|
|
1144
1215
|
borderless and compact through `::part(title)` while retaining its native
|
|
1145
1216
|
editing behavior and visible keyboard focus. These parts are styling hooks,
|
|
1146
1217
|
not slots or replacement controls.
|
|
@@ -96,6 +96,7 @@ own asynchronous work, cancellation, and backpressure.
|
|
|
96
96
|
| [`Mail.js`](#mailjs) | esm | Builds complete reports and prefers the native mail capability with an explicit HTTP transport fallback. | Browser/native hybrid + cloud | Mail inputs/results normalized; transport failures mixed. |
|
|
97
97
|
| [`MailOutbox.mjs`](#mailoutboxmjs) | esm | Persists complete mail reports before delivery and normalizes idempotent enqueue, retry, reconciliation, and invalid-record maintenance. | Browser/native WebView or compatible injected host | Complete records, full work, cancellation, and lifecycle states normalized; storage, lock, and delivery failures coded. |
|
|
98
98
|
| [`MailTransport.mjs`](#mailtransportmjs) | esm | Sends one complete mail report to a normalized HTTP(S) endpoint. | Browser/server with fetch + cloud | Normalized endpoint and transport errors; remote detail preserved. |
|
|
99
|
+
| [`MarkdownMedia.js`](#markdownmediajs) | esm | Saves local Markdown images separately, decodes complete stored records, and resolves stable references in rendered views. | Browser / supported native WebView | Complete image records, concurrent display reads, cancellation, and print-owned URL lifetime. |
|
|
99
100
|
| [`MarkdownSpeech.js`](#markdownspeechjs) | esm | Removes repeated Markdown formatting marks from streamed narration. | Cross-host | Speech-only filtering; single marks and ordinary punctuation remain literal. |
|
|
100
101
|
| [`Marked.min.js`](#markedminjs) | esm | Vendored Marked 18.0.5 Markdown lexer, parser, renderer, extension, and walk-token API. | Cross-host vendor module | Vendor-native Marked contract. |
|
|
101
102
|
| [`MD.js`](#mdjs) | esm | Renders complete Markdown with Marked and optionally maps source blocks to rendered comment anchors. | Browser / native WebView | Complete raw and rendered Marked values; opt-in original-source offsets; parse errors vendor-native. |
|
|
@@ -2794,6 +2795,85 @@ import * as module from '/arcane/modules/Marked.min.js';
|
|
|
2794
2795
|
console.log(Object.keys(module));
|
|
2795
2796
|
```
|
|
2796
2797
|
|
|
2798
|
+
## MarkdownMedia.js
|
|
2799
|
+
|
|
2800
|
+
### Overview
|
|
2801
|
+
|
|
2802
|
+
Stores complete images in the application's existing DBOPFS database while
|
|
2803
|
+
Markdown contains only a short, stable `arcane-media:` reference. Rendering
|
|
2804
|
+
resolves those local references into temporary display URLs. Importing the
|
|
2805
|
+
module starts no storage, network, provider, or rendering operation.
|
|
2806
|
+
|
|
2807
|
+
### Public surface
|
|
2808
|
+
|
|
2809
|
+
Public package import: `arcane-os/modules/MarkdownMedia.js`.
|
|
2810
|
+
|
|
2811
|
+
- `await saveMarkdownMedia({blob,tableName='markdown-media',fileName})` writes
|
|
2812
|
+
`{mediaType,dataUrl}` as a JSON-compatible record and returns
|
|
2813
|
+
`{reference,tableName,fileName,mediaType}` only after the write completes.
|
|
2814
|
+
The default filename is a new UUID followed by `.json`. There is no abort
|
|
2815
|
+
option: accepted storage writes settle through the storage owner.
|
|
2816
|
+
- `parseMarkdownMediaReference(reference)` returns `{tableName,fileName}` for
|
|
2817
|
+
a local reference, or `null` for an ordinary URL. Malformed local addresses
|
|
2818
|
+
report their actual parsing error.
|
|
2819
|
+
- `decodeMarkdownMediaRecord(value)` synchronously decodes a complete
|
|
2820
|
+
`{dataUrl,mediaType?}` record or its JSON text into a `Blob`, without storage
|
|
2821
|
+
or network access. Nested single-record arrays are unwrapped; arrays with
|
|
2822
|
+
multiple records are never reduced to one image. Unrecognized content,
|
|
2823
|
+
including text that is not complete JSON, returns `null`. A recognized
|
|
2824
|
+
record with unreadable base64 data-URL content throws its decoding error.
|
|
2825
|
+
Omitted `mediaType` preserves the Blob's empty type. Input remains unchanged.
|
|
2826
|
+
- `await readMarkdownMedia(reference)` returns the complete `Blob`, using
|
|
2827
|
+
only local storage and data-URL decoding; stored strings are never fetched
|
|
2828
|
+
as network addresses. It uses the same record decoder after loading, while
|
|
2829
|
+
preserving JSON parse errors for unreadable stored JSON strings and reporting
|
|
2830
|
+
an unreadable record as an error rather than `null`.
|
|
2831
|
+
- `hydrateMarkdownMedia(root,{signal}={})` returns `{ready,destroy,retain}`
|
|
2832
|
+
immediately. It includes an IMG root and descendant IMG elements, removes
|
|
2833
|
+
local-reference `src` values synchronously, starts independent reads
|
|
2834
|
+
together, and assigns owned object URLs. `ready` includes image decoding.
|
|
2835
|
+
Use a detached fragment before connecting those images to the document.
|
|
2836
|
+
|
|
2837
|
+
Hydration preserves Markdown source, image descriptions, ordinary URLs, and
|
|
2838
|
+
surrounding content. Failed reads or decodes reject `ready` with an
|
|
2839
|
+
`AggregateError` whose complete `failures` array contains
|
|
2840
|
+
`{image,reference,reason}`; successful sibling images remain visible.
|
|
2841
|
+
|
|
2842
|
+
`destroy()` or abort settles display readiness promptly, prevents late display,
|
|
2843
|
+
and releases owned URLs. An already-started storage read remains observed and
|
|
2844
|
+
settles independently. `retain()` returns an idempotent release callback for
|
|
2845
|
+
printing; retained URLs survive destruction of the original view until every
|
|
2846
|
+
print owner releases them. Destruction never deletes stored images.
|
|
2847
|
+
|
|
2848
|
+
Applications own record names, entry association, cleanup policy, and which
|
|
2849
|
+
records their existing JSON backup/export includes. Reusing the same filename
|
|
2850
|
+
supports an application-selected save-only retry without another generation
|
|
2851
|
+
request. The helper performs no existing-data migration.
|
|
2852
|
+
|
|
2853
|
+
Exact exports: `saveMarkdownMedia`, `parseMarkdownMediaReference`,
|
|
2854
|
+
`decodeMarkdownMediaRecord`, `readMarkdownMedia`, `hydrateMarkdownMedia`.
|
|
2855
|
+
|
|
2856
|
+
### Availability and normalization
|
|
2857
|
+
|
|
2858
|
+
Browser or native WebView with the existing app-scoped DBOPFS owner, Blob,
|
|
2859
|
+
FileReader, object URLs, and IMG decoding. Encoding, storage, missing-record,
|
|
2860
|
+
parsing, and decoding errors remain observable. No Core capability is selected.
|
|
2861
|
+
|
|
2862
|
+
### Example
|
|
2863
|
+
|
|
2864
|
+
```javascript
|
|
2865
|
+
import {saveMarkdownMedia} from 'arcane-os/modules/MarkdownMedia.js';
|
|
2866
|
+
|
|
2867
|
+
const mural = new Blob([
|
|
2868
|
+
'<svg xmlns="http://www.w3.org/2000/svg" width="240" height="80"><text x="10" y="45">Octopus parking only</text></svg>'
|
|
2869
|
+
], {type:'image/svg+xml'});
|
|
2870
|
+
const {reference} = await saveMarkdownMedia({blob:mural});
|
|
2871
|
+
editor.insertMarkdown(``);
|
|
2872
|
+
```
|
|
2873
|
+
|
|
2874
|
+
Here `editor` is the ready shared Markdown Editor. Its normal change/save flow
|
|
2875
|
+
still owns saving the Markdown; this operation saves the image record.
|
|
2876
|
+
|
|
2797
2877
|
## MD.js
|
|
2798
2878
|
|
|
2799
2879
|
### Overview
|
|
@@ -2828,16 +2908,29 @@ mapping, not exact rendered glyph or caret geometry.
|
|
|
2828
2908
|
|
|
2829
2909
|
Assigning `raw` or calling `append(string)` rebuilds both the complete rendered
|
|
2830
2910
|
result and its current mapping. Without `sourceMap:true`, `sourceMap` is empty
|
|
2831
|
-
and the
|
|
2911
|
+
and the same parsing runs without comment anchors. Existing raw content, link
|
|
2832
2912
|
behavior, no-op `rendered` setter, and complete `append()` result remain.
|
|
2833
2913
|
|
|
2914
|
+
Both rendering paths first use Marked's native HTML block tokenizer. When it
|
|
2915
|
+
does not recognize a complete standalone `<img>` tag with a newline inside a
|
|
2916
|
+
quoted attribute value, MD keeps that complete tag together as one HTML block.
|
|
2917
|
+
This includes blank lines in an image's full `alt` description. The tag must
|
|
2918
|
+
start at an existing Markdown block boundary with at most three leading spaces
|
|
2919
|
+
and end on its own line or at the end of the source. Separate inserted image
|
|
2920
|
+
blocks from surrounding Markdown with blank lines. Native HTML handling,
|
|
2921
|
+
inline prose, fenced/indented/inline code, escaped examples, and incomplete
|
|
2922
|
+
tags retain their existing parsing behavior. No source is rewritten or saved
|
|
2923
|
+
data migrated. Marked's existing rendered line-ending normalization remains;
|
|
2924
|
+
mapped offsets still address the exact original source, including CRLF or CR.
|
|
2925
|
+
|
|
2834
2926
|
Exact exports: `default`.
|
|
2835
2927
|
|
|
2836
2928
|
### Availability and normalization
|
|
2837
2929
|
|
|
2838
|
-
**Browser / native WebView.**
|
|
2839
|
-
|
|
2840
|
-
scrolling belong to the
|
|
2930
|
+
**Browser / native WebView.** Marked parsing, including the shared standalone
|
|
2931
|
+
image-token correction above; parse errors remain vendor-native. Rendering and
|
|
2932
|
+
the getters are DOM-independent. DOM lookup and scrolling belong to the
|
|
2933
|
+
consuming component;
|
|
2841
2934
|
mapping performs no persistence or viewport movement. Transport: Marked.
|
|
2842
2935
|
[Deep protocol details](protocols.md).
|
|
2843
2936
|
|
|
@@ -3071,6 +3164,9 @@ assistant content in configured model context and ChatEntity/DBOPFS history.
|
|
|
3071
3164
|
That assistant-only opening survives reload and empty-chat maintenance without
|
|
3072
3165
|
a fabricated user turn. A second opening rejects as `AI_CHAT_OPENING_EXISTS`;
|
|
3073
3166
|
an unavailable durable ChatEntity rejects as `AI_CHAT_PERSISTENCE_UNAVAILABLE`.
|
|
3167
|
+
If retention is disabled while the opening is being prepared, that same error
|
|
3168
|
+
rolls back the opening before its append; it does not leave hidden model context.
|
|
3169
|
+
An opening write already accepted by DBOPFS still completes normally.
|
|
3074
3170
|
|
|
3075
3171
|
`send()` accepts either
|
|
3076
3172
|
`{message:{content,role:'user'|'tool',tool_call_id?,message?,name?,status?,persist},...}`
|
|
@@ -3086,6 +3182,20 @@ the retained transcript, memory extraction, or DBOPFS. A nonpersistent response
|
|
|
3086
3182
|
therefore does not open a retained structural-tool continuation. A retained
|
|
3087
3183
|
structural tool result must use the persistence choice captured by its matching
|
|
3088
3184
|
assistant tool call.
|
|
3185
|
+
An explicitly nonretained tool-result continuation uses its matching pending
|
|
3186
|
+
call only for that operation, then rolls back without settling or changing the
|
|
3187
|
+
retained call. A later retained continuation can still settle it normally.
|
|
3188
|
+
|
|
3189
|
+
The entity-wide `session.chatEntity.persist=false` applies the same no-retention
|
|
3190
|
+
rule to new turns and direct entity additions; it is not a disk-only switch.
|
|
3191
|
+
The session captures that setting when it accepts a request and observes it
|
|
3192
|
+
again before accepting a durable append. Changing it later cannot bring back
|
|
3193
|
+
discarded inputs or responses. A write already accepted by DBOPFS finishes
|
|
3194
|
+
normally; toggling the setting does not undo that write or rewrite saved data.
|
|
3195
|
+
Completed `send()` and `stream()` responses include a session-owned `retained`
|
|
3196
|
+
boolean outside `message` and the provider payload, identifying whether the
|
|
3197
|
+
turn entered recurring history. Existing retained and stored records remain
|
|
3198
|
+
untouched: this boundary applies to new additions and performs no migration.
|
|
3089
3199
|
|
|
3090
3200
|
`history()` returns provider-safe configured model context, including the
|
|
3091
3201
|
system prompt and every complete ordinary visible committed turn. Only a
|
|
@@ -3260,14 +3370,26 @@ Shared rendered-print owner used by Markdown Editor and File Manager. It
|
|
|
3260
3370
|
captures the current DOM and computed styles, including accessible rendered
|
|
3261
3371
|
HTML frames, complete text, selected images, and the current title. A temporary
|
|
3262
3372
|
print-only surface expands scrollable content without editing the live screen.
|
|
3373
|
+
That surface uses the shared Arcane light-theme text, paper, and border colors,
|
|
3374
|
+
with `15mm` page margins. It retains rendered fonts, emphasis, and complete
|
|
3375
|
+
content while removing screen-theme text/shadow paint from ordinary HTML and
|
|
3376
|
+
pseudo-elements. Links are underlined and table cells receive visible borders.
|
|
3377
|
+
Image pixels, canvas snapshots, and SVG artwork keep their own colors. These
|
|
3378
|
+
print rules leave the live screen theme unchanged; browser print settings still
|
|
3379
|
+
control the eventual page output.
|
|
3263
3380
|
|
|
3264
3381
|
### Public surface
|
|
3265
3382
|
|
|
3266
|
-
Named `createPrintView({host,content,title,active,priority=0,signal,onError,retain})`
|
|
3383
|
+
Named `createPrintView({host,content,title,active,priority=0,signal,onError,retain,prepare})`
|
|
3267
3384
|
returns `{print,destroy}`. `host` is a connected element; synchronous callbacks
|
|
3268
3385
|
return the rendered content node, string title, and whether the view is active.
|
|
3269
3386
|
Optional `retain()` returns a resource-release callback. It keeps owned media
|
|
3270
3387
|
available until preparation is cancelled or the browser emits `afterprint`.
|
|
3388
|
+
Optional `prepare(signal)` may await view-owned readiness during an explicit
|
|
3389
|
+
print request. After it settles, current content and title are read again
|
|
3390
|
+
synchronously immediately before capture. A view whose content changes during
|
|
3391
|
+
preparation must keep its owned media retained and reject a still-pending
|
|
3392
|
+
snapshot through its synchronous `content()` callback.
|
|
3271
3393
|
|
|
3272
3394
|
`await print()` selects that view, waits for accessible HTML frame, image, and
|
|
3273
3395
|
font readiness, and requests the browser print dialog. It returns `false` when
|
|
@@ -3281,6 +3403,8 @@ on ties. File preview uses priority `1`; editor uses `0`. Native `beforeprint`
|
|
|
3281
3403
|
is synchronous: it snapshots currently rendered content, cannot await a newly
|
|
3282
3404
|
loading resource, and cannot cancel the browser's dialog. `onError(error)` or
|
|
3283
3405
|
the developer console receives complete preparation failures.
|
|
3406
|
+
Native printing never invokes the asynchronous `prepare` callback; prepared
|
|
3407
|
+
views still receive the synchronous content/title read at capture.
|
|
3284
3408
|
|
|
3285
3409
|
`destroy()` unregisters the view and cancels pending preparation. Once the
|
|
3286
3410
|
dialog has been requested, its snapshot and retained media remain until
|
|
@@ -3930,12 +4054,20 @@ is applied once the body is available.
|
|
|
3930
4054
|
|
|
3931
4055
|
The shared `theme.css` owns the default, warm, curious, hopeful, harmony, and
|
|
3932
4056
|
warrior palettes. Each works with explicit light/dark or system appearance.
|
|
3933
|
-
`layout.css` imports that same owner.
|
|
3934
|
-
through `data-arcane-skin="custom"` and their inline tokens.
|
|
4057
|
+
`layout.css` imports that same owner. On screen, explicit custom themes retain
|
|
4058
|
+
precedence through `data-arcane-skin="custom"` and their inline tokens.
|
|
3935
4059
|
The bare root retains the generic neutral light/dark baseline; the prior
|
|
3936
4060
|
layout default palette is selected explicitly through `data-user-skin="default"`,
|
|
3937
4061
|
`body.default` compatibility, or the default swatch.
|
|
3938
4062
|
|
|
4063
|
+
During printing, `theme.css` applies the existing base light palette, with a
|
|
4064
|
+
white paper surface and `15mm` page margins, to the root, body, and scoped
|
|
4065
|
+
`data-arcane-palette` elements. These print-only tokens override screen/custom
|
|
4066
|
+
palette tokens. It resets the root/body margin without changing saved
|
|
4067
|
+
preferences, screen presentation, scrolling, media, or other layout rules.
|
|
4068
|
+
The separate [`PrintView.js`](#printviewjs) owner uses the same light palette
|
|
4069
|
+
and margins for its expanded rendered-content snapshot.
|
|
4070
|
+
|
|
3939
4071
|
A scoped `data-arcane-palette="warm"` element exposes the same palette variables
|
|
3940
4072
|
for a chooser preview without changing the page's selection. Use any of the
|
|
3941
4073
|
six named palettes and paint the preview with ordinary shared variables such
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "arcane-os",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.46.0",
|
|
4
4
|
"description": "Arcane OS JavaScript SDK, project-local CLI, browser runtime, and repository-portable application packager.",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"main": "./src/index.mjs",
|
|
@@ -86,7 +86,7 @@
|
|
|
86
86
|
"test": "npm run test:unit && npm run test:functional && npm run test:integration && npm run test:regression",
|
|
87
87
|
"test:release": "node ./bin/arcane-test.mjs test/npm-release.test.mjs",
|
|
88
88
|
"test:unit": "node ./bin/arcane-test.mjs test/app-descriptor.test.mjs test/app-schema.test.mjs test/app-selection.test.mjs test/contracts.test.mjs test/conversation-closing-report.test.mjs test/doctor.test.mjs test/mail-credentials.test.mjs test/mail-outbox.test.mjs test/mail-public-api.test.mjs test/mail-send.test.mjs test/mail-transport.test.mjs test/targets.test.mjs test/workspace-operation-lock.test.mjs",
|
|
89
|
-
"test:functional": "node ./bin/arcane-test.mjs test/ai-request-model.test.mjs test/ai-request-retry.test.mjs test/ai-stream-cancellation.test.mjs test/browser-speech-providers.test.mjs test/browser-wasm-gpu-notice.test.mjs test/browser-wasm-download-resume.test.mjs test/chat-input.test.mjs test/chat-stream-speech.test.mjs test/chat-transcript-scroll.test.mjs test/chat-transient-retention.test.mjs test/cli.test.mjs test/continuous-voice-capture.test.mjs test/dbopfs-document-library.test.mjs test/dbopfs-png.test.mjs test/dbopfs.test.mjs test/dev-server.test.mjs test/dev-pwa.test.mjs test/dom-event-instrumentation.test.mjs test/event-manager.test.mjs test/events.test.mjs test/file-preview.test.mjs test/import-map.test.mjs test/mail-cli.test.mjs test/mail-runtime.test.mjs test/mail-server.test.mjs test/markdown-editor.test.mjs test/markdown-source-map.test.mjs test/modal.test.mjs test/packaging.test.mjs test/pwa-packaging.test.mjs test/pwa-client.test.mjs test/pwa-install.test.mjs test/pwa-worker.test.mjs test/persistent-ai-chat-session.test.mjs test/reference-completeness.test.mjs test/runtime-api-behavior.test.mjs test/runtime.test.mjs test/scaffold.test.mjs test/speech-playback.test.mjs test/site.test.mjs test/twin-cloud-images.test.mjs test/twin-cloud.test.mjs test/update-check.test.mjs test/user-explicit-updates.test.mjs",
|
|
89
|
+
"test:functional": "node ./bin/arcane-test.mjs test/ai-request-model.test.mjs test/ai-request-retry.test.mjs test/ai-stream-cancellation.test.mjs test/browser-speech-providers.test.mjs test/browser-wasm-gpu-notice.test.mjs test/browser-wasm-download-resume.test.mjs test/chat-input.test.mjs test/chat-stream-speech.test.mjs test/chat-transcript-scroll.test.mjs test/chat-transient-retention.test.mjs test/cli.test.mjs test/continuous-voice-capture.test.mjs test/dbopfs-document-library.test.mjs test/dbopfs-png.test.mjs test/dbopfs.test.mjs test/dev-server.test.mjs test/dev-pwa.test.mjs test/dom-event-instrumentation.test.mjs test/event-manager.test.mjs test/events.test.mjs test/file-preview.test.mjs test/import-map.test.mjs test/mail-cli.test.mjs test/mail-runtime.test.mjs test/mail-server.test.mjs test/markdown-editor.test.mjs test/markdown-media.test.mjs test/markdown-source-map.test.mjs test/modal.test.mjs test/packaging.test.mjs test/pwa-packaging.test.mjs test/pwa-client.test.mjs test/pwa-install.test.mjs test/pwa-worker.test.mjs test/persistent-ai-chat-session.test.mjs test/reference-completeness.test.mjs test/rendered-print.test.mjs test/runtime-api-behavior.test.mjs test/runtime.test.mjs test/scaffold.test.mjs test/speech-playback.test.mjs test/site.test.mjs test/theme-manager.test.mjs test/twin-cloud-images.test.mjs test/twin-cloud.test.mjs test/update-check.test.mjs test/user-explicit-updates.test.mjs",
|
|
90
90
|
"test:integration": "node ./bin/arcane-test.mjs test/installed-package-runtime.test.mjs test/root-app-layout.test.mjs test/integrated-shared.test.mjs test/integrated-workspace.test.mjs test/mail-browser.test.mjs test/native-plan.test.mjs test/native-provider-loader.test.mjs test/npm-release.test.mjs test/release-bundle.test.mjs test/release-capability-smoke.test.mjs test/shared-payload-batch.test.mjs test/tarball.test.mjs test/browser-wasm-cpu.test.mjs test/wllama-webgpu-runtime.test.mjs",
|
|
91
91
|
"test:regression": "node ./bin/arcane-test.mjs test/channel-workflows.test.mjs test/html-import-registration.test.mjs test/logging-regression.test.mjs test/markdown-speech.test.mjs test/prepared-speech.test.mjs test/native-provider-generation.test.mjs test/speech-queue-regression.test.mjs test/testing.test.mjs test/test-sets.test.mjs",
|
|
92
92
|
"check": "node tools/check-source.mjs && npm test",
|
|
@@ -3255,13 +3255,22 @@
|
|
|
3255
3255
|
);
|
|
3256
3256
|
}
|
|
3257
3257
|
|
|
3258
|
-
const
|
|
3258
|
+
const submittedMessages=is.array(sessionRequest)
|
|
3259
3259
|
?sessionRequest
|
|
3260
3260
|
:[sessionRequest];
|
|
3261
|
-
if(!
|
|
3261
|
+
if(!submittedMessages.length){
|
|
3262
3262
|
throw new TypeError('A chat session request must contain at least one message.');
|
|
3263
3263
|
}
|
|
3264
|
-
|
|
3264
|
+
function entityRetainsMessages(){
|
|
3265
|
+
return !session.chatEntity||Boolean(session.chatEntity.persist);
|
|
3266
|
+
}
|
|
3267
|
+
let retainTurn=submittedMessages.every(message=>message.persist!==false)
|
|
3268
|
+
&&entityRetainsMessages();
|
|
3269
|
+
// Preserve this submission's choice across the rendering await before
|
|
3270
|
+
// dispatch; a later entity setting belongs to a later submission.
|
|
3271
|
+
const sessionRequestMessages=retainTurn
|
|
3272
|
+
?submittedMessages
|
|
3273
|
+
:submittedMessages.map(message=>({...message,persist:false}));
|
|
3265
3274
|
const request={
|
|
3266
3275
|
...(sessionRequestMessages.length===1
|
|
3267
3276
|
?{message:sessionRequestMessages[0]}
|
|
@@ -3276,9 +3285,18 @@
|
|
|
3276
3285
|
?session.aiName
|
|
3277
3286
|
:host.aiName;
|
|
3278
3287
|
const sessionMessageToken=Symbol(messageId);
|
|
3279
|
-
const transientCards=
|
|
3288
|
+
const transientCards=[...requestMessages];
|
|
3289
|
+
let retentionSettled=false;
|
|
3290
|
+
function settleTurnRetention(result){
|
|
3291
|
+
if(retentionSettled) return;
|
|
3292
|
+
// The session reports the decision made at its actual commit boundary.
|
|
3293
|
+
retainTurn=retainTurn&&(is.boolean(result?.retained)
|
|
3294
|
+
?result.retained
|
|
3295
|
+
:entityRetainsMessages());
|
|
3296
|
+
retentionSettled=true;
|
|
3297
|
+
}
|
|
3280
3298
|
function removeTransientSessionCards(){
|
|
3281
|
-
if(
|
|
3299
|
+
if(retainTurn||!transientCards.length) return;
|
|
3282
3300
|
// The submitter supplies only nodes created for this submission.
|
|
3283
3301
|
for(const card of transientCards) card.remove();
|
|
3284
3302
|
transientCards.length=0;
|
|
@@ -3290,7 +3308,7 @@
|
|
|
3290
3308
|
setSessionStatus('sending','AI is responding…');
|
|
3291
3309
|
try{
|
|
3292
3310
|
const responseCard=receivedMessage(responseName, '', messageId);
|
|
3293
|
-
|
|
3311
|
+
transientCards.push(responseCard);
|
|
3294
3312
|
await streamMessage('',messageId,true);
|
|
3295
3313
|
setMessageProgress(
|
|
3296
3314
|
messageId,
|
|
@@ -3344,6 +3362,7 @@
|
|
|
3344
3362
|
}
|
|
3345
3363
|
)
|
|
3346
3364
|
:await session.send(request);
|
|
3365
|
+
settleTurnRetention(result);
|
|
3347
3366
|
if(
|
|
3348
3367
|
destroyed
|
|
3349
3368
|
||bindingGeneration!==sessionBindingGeneration
|
|
@@ -3441,6 +3460,7 @@
|
|
|
3441
3460
|
);
|
|
3442
3461
|
return result;
|
|
3443
3462
|
}catch(error){
|
|
3463
|
+
settleTurnRetention();
|
|
3444
3464
|
if(!destroyed&&bindingGeneration===sessionBindingGeneration){
|
|
3445
3465
|
setPendingStructuralToolCalls(previousPendingToolCalls);
|
|
3446
3466
|
}
|
|
@@ -3501,6 +3521,7 @@
|
|
|
3501
3521
|
}
|
|
3502
3522
|
throw error;
|
|
3503
3523
|
}finally{
|
|
3524
|
+
settleTurnRetention();
|
|
3504
3525
|
removeTransientSessionCards();
|
|
3505
3526
|
if(activeSessionMessageToken===sessionMessageToken){
|
|
3506
3527
|
activeSessionMessageToken=null;
|