arcane-os 0.16.0 → 0.16.2
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 +17 -0
- package/README.md +1 -1
- package/package.json +2 -2
- package/runtime/arcane/components/markdown-document.html +23 -2
- package/src/workspace.mjs +11 -11
package/CHANGELOG.md
CHANGED
|
@@ -1,5 +1,22 @@
|
|
|
1
1
|
# Changelog
|
|
2
2
|
|
|
3
|
+
## 0.16.2
|
|
4
|
+
|
|
5
|
+
- Scope explicit application selection and workspace resolution to the named
|
|
6
|
+
app before reading its descriptor. An unrelated invalid descriptor no longer
|
|
7
|
+
blocks that operation. Selected descriptors and unscoped discovery retain
|
|
8
|
+
their existing validation. Named resolution reports only the selected app in
|
|
9
|
+
`appIds`; unknown selections report the requested missing identifier without
|
|
10
|
+
validating or listing unrelated apps.
|
|
11
|
+
|
|
12
|
+
## 0.16.1
|
|
13
|
+
|
|
14
|
+
- Remove raw script elements and inline event-handler attributes at the
|
|
15
|
+
`markdown-document` insertion boundary, including nested template contents.
|
|
16
|
+
Preserve literal fenced and inline code examples, formatting, navigation,
|
|
17
|
+
and asynchronous document loading. This targeted reader correction does not
|
|
18
|
+
provide a general-purpose HTML sanitizer or alter other Markdown consumers.
|
|
19
|
+
|
|
3
20
|
## 0.16.0
|
|
4
21
|
|
|
5
22
|
- Make mail hosting domain-based: use the current browser origin by default,
|
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 preserve the same app URLs, theme, packaging,
|
|
20
20
|
event, cancellation, and browser run contracts.
|
|
21
21
|
|
|
22
|
-
This checkout defines the `0.16.
|
|
22
|
+
This checkout defines the `0.16.2` 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
|
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "arcane-os",
|
|
3
|
-
"version": "0.16.
|
|
3
|
+
"version": "0.16.2",
|
|
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",
|
|
@@ -67,7 +67,7 @@
|
|
|
67
67
|
"scripts": {
|
|
68
68
|
"test": "npm run test:unit && npm run test:functional && npm run test:integration && npm run test:regression",
|
|
69
69
|
"test:release": "node ./bin/arcane-test.mjs test/npm-release.test.mjs",
|
|
70
|
-
"test:unit": "node ./bin/arcane-test.mjs test/app-descriptor.test.mjs test/app-schema.test.mjs test/contracts.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",
|
|
70
|
+
"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/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",
|
|
71
71
|
"test:functional": "node ./bin/arcane-test.mjs test/browser-speech-providers.test.mjs test/browser-wasm-gpu-notice.test.mjs test/browser-wasm-download-resume.test.mjs test/cli.test.mjs test/dbopfs-document-library.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/import-map.test.mjs test/mail-cli.test.mjs test/mail-runtime.test.mjs test/mail-server.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/update-check.test.mjs",
|
|
72
72
|
"test:integration": "node ./bin/arcane-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",
|
|
73
73
|
"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",
|
|
@@ -616,8 +616,8 @@
|
|
|
616
616
|
return true;
|
|
617
617
|
}
|
|
618
618
|
|
|
619
|
-
// MD
|
|
620
|
-
// source-relative
|
|
619
|
+
// MD renders Markdown; the detached fragment removes active script
|
|
620
|
+
// markup and resolves source-relative assets before insertion.
|
|
621
621
|
const safeRendered=new MD(markdown).safeRendered;
|
|
622
622
|
const fragment=renderedMarkdownFragment(safeRendered,sourceURL);
|
|
623
623
|
const meaningful=Boolean(
|
|
@@ -648,6 +648,27 @@
|
|
|
648
648
|
const template=document.createElement('template');
|
|
649
649
|
template.innerHTML=html;
|
|
650
650
|
|
|
651
|
+
// Code examples are text nodes, so their literal markup stays intact.
|
|
652
|
+
// Visit nested template contents too, without reparsing cleaned HTML.
|
|
653
|
+
const pendingFragments=[template.content];
|
|
654
|
+
while(pendingFragments.length){
|
|
655
|
+
const fragment=pendingFragments.pop();
|
|
656
|
+
for(const element of fragment.querySelectorAll('*')){
|
|
657
|
+
if(element.localName.toLowerCase()==='script'){
|
|
658
|
+
element.remove();
|
|
659
|
+
continue;
|
|
660
|
+
}
|
|
661
|
+
for(const attribute of Array.from(element.attributes)){
|
|
662
|
+
if(attribute.name.toLowerCase().startsWith('on')){
|
|
663
|
+
element.removeAttributeNode(attribute);
|
|
664
|
+
}
|
|
665
|
+
}
|
|
666
|
+
if(element.localName==='template'&&element.content){
|
|
667
|
+
pendingFragments.push(element.content);
|
|
668
|
+
}
|
|
669
|
+
}
|
|
670
|
+
}
|
|
671
|
+
|
|
651
672
|
for(const link of template.content.querySelectorAll('a[href]')){
|
|
652
673
|
const originalHref=link.getAttribute('href')||'';
|
|
653
674
|
const policy=markdownDocumentLinkPolicy(originalHref,sourceURL,pageOrigin);
|
package/src/workspace.mjs
CHANGED
|
@@ -216,12 +216,17 @@ function classifyRootConfig(config){
|
|
|
216
216
|
});
|
|
217
217
|
}
|
|
218
218
|
|
|
219
|
-
async function discoverAppsInRoot(root,config){
|
|
219
|
+
async function discoverAppsInRoot(root,config,appId){
|
|
220
|
+
if(appId!==undefined&&(!is.string(appId)||!APP_ID_PATTERN.test(appId))){
|
|
221
|
+
fail(`Invalid app id: ${String(appId)}.`,'ARCANE_USAGE');
|
|
222
|
+
}
|
|
220
223
|
const appsRoot=path.join(root,'apps');
|
|
221
224
|
await assertRealDirectory(appsRoot,'Workspace apps root');
|
|
222
225
|
const entries=await readdir(appsRoot,{withFileTypes:true});
|
|
223
226
|
const apps=[];
|
|
224
227
|
for(const entry of entries.sort((left,right)=>ordinal(left.name,right.name))){
|
|
228
|
+
// A named operation validates that app, not unrelated application descriptors.
|
|
229
|
+
if(appId!==undefined&&entry.name!==appId)continue;
|
|
225
230
|
if(!APP_ID_PATTERN.test(entry.name))continue;
|
|
226
231
|
if(entry.isSymbolicLink())fail(`apps/${entry.name} must not be a symbolic link or junction.`);
|
|
227
232
|
if(!entry.isDirectory())continue;
|
|
@@ -274,13 +279,11 @@ export async function inspectWorkspaceProfile(workspaceRoot=process.cwd()){
|
|
|
274
279
|
}
|
|
275
280
|
|
|
276
281
|
export async function selectApp(workspaceRoot=process.cwd(),appId){
|
|
277
|
-
const
|
|
278
|
-
|
|
279
|
-
fail(`Invalid app id: ${String(appId)}.`,'ARCANE_USAGE');
|
|
280
|
-
}
|
|
282
|
+
const profile=await inspectWorkspaceProfile(workspaceRoot);
|
|
283
|
+
const apps=await discoverAppsInRoot(profile.workspaceRoot,profile.config,appId);
|
|
281
284
|
if(appId){
|
|
282
285
|
const selected=apps.find(app=>app.appId===appId);
|
|
283
|
-
if(!selected)fail(`Unknown app "${appId}"
|
|
286
|
+
if(!selected)fail(`Unknown app "${appId}".`);
|
|
284
287
|
return selected;
|
|
285
288
|
}
|
|
286
289
|
if(apps.length===0)fail('No Arcane applications were found under apps/.');
|
|
@@ -294,14 +297,11 @@ export async function resolveWorkspace({workspaceRoot=process.cwd(),appId}={}){
|
|
|
294
297
|
const profile=await inspectWorkspaceProfile(workspaceRoot);
|
|
295
298
|
const canonicalRoot=profile.workspaceRoot;
|
|
296
299
|
const config=profile.config;
|
|
297
|
-
const apps=await discoverAppsInRoot(canonicalRoot,config);
|
|
298
|
-
if(appId!==undefined&&(!is.string(appId)||!APP_ID_PATTERN.test(appId))){
|
|
299
|
-
fail(`Invalid app id: ${String(appId)}.`,'ARCANE_USAGE');
|
|
300
|
-
}
|
|
300
|
+
const apps=await discoverAppsInRoot(canonicalRoot,config,appId);
|
|
301
301
|
let app;
|
|
302
302
|
if(appId){
|
|
303
303
|
app=apps.find(item=>item.appId===appId);
|
|
304
|
-
if(!app)fail(`Unknown app "${appId}"
|
|
304
|
+
if(!app)fail(`Unknown app "${appId}".`);
|
|
305
305
|
}else if(apps.length===1){
|
|
306
306
|
[app]=apps;
|
|
307
307
|
}else if(apps.length===0){
|