arcane-os 0.16.1 → 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 CHANGED
@@ -1,5 +1,14 @@
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
+
3
12
  ## 0.16.1
4
13
 
5
14
  - Remove raw script elements and inline event-handler attributes at the
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.1` SDK contract. Applications pin one exact npm
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.1",
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",
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 apps=await discoverApps(workspaceRoot);
278
- if(appId!==undefined&&(!is.string(appId)||!APP_ID_PATTERN.test(appId))){
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}". Available apps: ${apps.map(app=>app.appId).join(', ')||'[none]'}.`);
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}". Available apps: ${apps.map(item=>item.appId).join(', ')||'[none]'}.`);
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){