@markii/host 0.17.0-next.2 → 0.17.0-next.3
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 +4 -2
- package/dist/browser-worker.js +36 -36
- package/dist/browser.d.ts +6 -2
- package/dist/browser.js +7 -2
- package/dist/host/adapter.d.ts +18 -23
- package/dist/host/conformance-runner.d.ts +4 -1
- package/dist/host/conformance-runner.js +4 -6
- package/dist/host/create-host.d.ts +4 -6
- package/dist/host/editor-behavior.d.ts +2 -6
- package/dist/host/editor-behavior.js +5 -9
- package/dist/host/export-behavior.d.ts +4 -6
- package/dist/host/labels.d.ts +1 -2
- package/dist/host/pack-archive.js +2 -8
- package/dist/host/pack-install.d.ts +1 -2
- package/dist/host/pack-install.js +4 -7
- package/dist/host/pack-load.d.ts +1 -2
- package/dist/host/pack-trust-behavior.js +1 -1
- package/dist/host/refresh-interval.d.ts +1 -3
- package/dist/host/refresh-interval.js +1 -3
- package/dist/host/run-behavior.d.ts +3 -4
- package/dist/host/run-behavior.js +23 -2
- package/dist/host/script-execution.d.ts +1 -1
- package/dist/index.js +1 -2
- package/dist/node-worker.js +20657 -0
- package/dist/node.d.ts +2 -1
- package/dist/node.js +1 -1
- package/dist/packs/discover.js +1 -1
- package/dist/packs/pack-diagnostics.d.ts +6 -8
- package/dist/packs/pack-diagnostics.js +6 -8
- package/dist/packs/pack-paths.js +1 -2
- package/dist/packs/pack-render-registry.d.ts +9 -10
- package/dist/run/browser-isolate.d.ts +5 -5
- package/dist/run/browser-isolate.js +5 -1
- package/dist/run/isolate.d.ts +3 -1
- package/dist/run/net-bridge.d.ts +5 -5
- package/dist/run/net-provider.d.ts +3 -1
- package/dist/run/net-provider.js +20 -6
- package/dist/run/node-isolate.d.ts +13 -21
- package/dist/run/node-isolate.js +31 -80
- package/dist/run/run-flow.d.ts +1 -2
- package/dist/run/run-host.d.ts +3 -3
- package/dist/run/worker-entry-browser.d.ts +24 -4
- package/dist/run/worker-entry-browser.js +99 -4
- package/dist/run/worker-entry.js +2 -0
- package/package.json +14 -11
package/dist/browser.d.ts
CHANGED
|
@@ -1,7 +1,9 @@
|
|
|
1
1
|
import type { NetProvider } from '@markii/lua';
|
|
2
2
|
import type { HostIsolate } from './host/adapter.js';
|
|
3
3
|
/** Builds the provider for one run from the job's host allowlist, byte cap and pin policy (the policy is meaningless in a browser and ignored). */
|
|
4
|
-
export type BrowserNetProviderFactory = (netAllowlist: string[], maxFetchBytes: number, netPolicy: unknown
|
|
4
|
+
export type BrowserNetProviderFactory = (netAllowlist: string[], maxFetchBytes: number, netPolicy: unknown,
|
|
5
|
+
/** Aborted when the isolate is killed or disposed. A provider cancels its in-flight requests on it. */
|
|
6
|
+
signal?: AbortSignal) => NetProvider;
|
|
5
7
|
export interface FetchNetProviderOptions {
|
|
6
8
|
/**
|
|
7
9
|
* The origins (`https://api.example.com`, `http://127.0.0.1:8080`) a
|
|
@@ -33,7 +35,9 @@ export interface FetchNetProviderOptions {
|
|
|
33
35
|
* manual redirect's target, so it cannot be checked against the allowlist,
|
|
34
36
|
* and a redirect is therefore a denial.
|
|
35
37
|
*
|
|
36
|
-
* Returns a factory because the byte cap arrives per job.
|
|
38
|
+
* Returns a factory because the byte cap arrives per job. Every request
|
|
39
|
+
* carries the run's `AbortSignal`, so killing the isolate cancels requests
|
|
40
|
+
* still in flight.
|
|
37
41
|
*/
|
|
38
42
|
export declare function createFetchNetProvider(options?: FetchNetProviderOptions): BrowserNetProviderFactory;
|
|
39
43
|
export interface BrowserHostIsolateOptions {
|
package/dist/browser.js
CHANGED
|
@@ -74,14 +74,16 @@ async function readCapped(response, maxBytes, denial) {
|
|
|
74
74
|
* manual redirect's target, so it cannot be checked against the allowlist,
|
|
75
75
|
* and a redirect is therefore a denial.
|
|
76
76
|
*
|
|
77
|
-
* Returns a factory because the byte cap arrives per job.
|
|
77
|
+
* Returns a factory because the byte cap arrives per job. Every request
|
|
78
|
+
* carries the run's `AbortSignal`, so killing the isolate cancels requests
|
|
79
|
+
* still in flight.
|
|
78
80
|
*/
|
|
79
81
|
export function createFetchNetProvider(options = {}) {
|
|
80
82
|
const allowed = new Set((options.allowedOrigins ?? [])
|
|
81
83
|
.map(originOf)
|
|
82
84
|
.filter((origin) => origin !== undefined));
|
|
83
85
|
const denial = options.denial ?? ((message) => new Error(message));
|
|
84
|
-
return (netAllowlist, maxFetchBytes) => {
|
|
86
|
+
return (netAllowlist, maxFetchBytes, _policy, signal) => {
|
|
85
87
|
// The run's granted hosts, re-checked here on the page side: the worker
|
|
86
88
|
// checks them too, but the worker is the isolate a hostile script runs
|
|
87
89
|
// in, so the page is the boundary (the same rule the Node provider
|
|
@@ -107,6 +109,8 @@ export function createFetchNetProvider(options = {}) {
|
|
|
107
109
|
if (!allowed.has(url.origin)) {
|
|
108
110
|
throw denial(`origin "${url.origin}" is not on the host's allowlist`);
|
|
109
111
|
}
|
|
112
|
+
if (signal?.aborted)
|
|
113
|
+
throw denial('the run has ended');
|
|
110
114
|
const doFetch = options.fetch ?? fetch;
|
|
111
115
|
let response;
|
|
112
116
|
try {
|
|
@@ -118,6 +122,7 @@ export function createFetchNetProvider(options = {}) {
|
|
|
118
122
|
redirect: 'manual',
|
|
119
123
|
credentials: 'omit',
|
|
120
124
|
referrerPolicy: 'no-referrer',
|
|
125
|
+
...(signal !== undefined ? { signal } : {}),
|
|
121
126
|
});
|
|
122
127
|
}
|
|
123
128
|
catch (error) {
|
package/dist/host/adapter.d.ts
CHANGED
|
@@ -3,8 +3,7 @@
|
|
|
3
3
|
* the CLI, or a future one) provides so `createMarkiiHost` can run every
|
|
4
4
|
* shared behavior once. Nothing in this file names a `vscode`, `obsidian`,
|
|
5
5
|
* Electron or TTY type — an adapter is built from injected dependencies,
|
|
6
|
-
* so a test can construct the REAL adapter over fakes
|
|
7
|
-
* `tmp/W11-adapter-design.md`, section 2).
|
|
6
|
+
* so a test can construct the REAL adapter over fakes.
|
|
8
7
|
*
|
|
9
8
|
* A capability group (`isolate`, `editor`, `packs`, `exports`) is absent
|
|
10
9
|
* when a host does not offer it. `createMarkiiHost` never assumes one is
|
|
@@ -23,9 +22,7 @@ export interface HostDirEntry {
|
|
|
23
22
|
}
|
|
24
23
|
/**
|
|
25
24
|
* One yes/no question. Every grant, consent, and replace prompt in the
|
|
26
|
-
* whole app surface routes through this single method
|
|
27
|
-
* nine near-identical prompt adapters across three apps collapse to one
|
|
28
|
-
* call each). `message`, `allowLabel`, and `denyLabel` are already fully
|
|
25
|
+
* whole app surface routes through this single method. `message`, `allowLabel`, and `denyLabel` are already fully
|
|
29
26
|
* built by `@markii/host`; the adapter only has to show them.
|
|
30
27
|
*/
|
|
31
28
|
export interface HostPromptRequest {
|
|
@@ -43,7 +40,7 @@ export interface HostPromptRequest {
|
|
|
43
40
|
}
|
|
44
41
|
/**
|
|
45
42
|
* A discriminated union: `workerPath` and `workerBytes` are mutually
|
|
46
|
-
* exclusive per host
|
|
43
|
+
* exclusive per host. A Node host (VS Code, the CLI)
|
|
47
44
|
* gives a synchronous path lookup; a host whose runtime cannot create
|
|
48
45
|
* worker threads (an Electron renderer, which is what the Obsidian plugin
|
|
49
46
|
* runs in) gives an async, disposable Web Worker spawner instead.
|
|
@@ -51,15 +48,14 @@ export interface HostPromptRequest {
|
|
|
51
48
|
export type HostIsolate = {
|
|
52
49
|
readonly kind: 'node';
|
|
53
50
|
/**
|
|
54
|
-
* The worker entry on disk. A host with
|
|
55
|
-
*
|
|
56
|
-
*
|
|
57
|
-
* adapter (the shared run path has no Node dependency to do it).
|
|
51
|
+
* The worker entry on disk. A host with its own bundled worker
|
|
52
|
+
* resolves it here. `createNodeHostIsolate()` from
|
|
53
|
+
* `@markii/host/node` supplies the packaged one.
|
|
58
54
|
*/
|
|
59
55
|
workerPath(): string;
|
|
60
56
|
/**
|
|
61
|
-
* Creates the worker-thread isolate
|
|
62
|
-
*
|
|
57
|
+
* Creates the worker-thread isolate: `workerThreadIsolate` from
|
|
58
|
+
* `@markii/host/node`. Injected so the shared run path imports
|
|
63
59
|
* nothing from `node:*`.
|
|
64
60
|
*/
|
|
65
61
|
readonly spawnIsolate: IsolateSpawner;
|
|
@@ -106,7 +102,7 @@ export interface HostEditor {
|
|
|
106
102
|
}
|
|
107
103
|
/**
|
|
108
104
|
* Pack POLICY (which folders are even candidates) is irreducibly
|
|
109
|
-
* host-specific
|
|
105
|
+
* host-specific; everything after the list exists is
|
|
110
106
|
* already shared in `../packs/discover.ts` and friends. The adapter
|
|
111
107
|
* supplies only the list and the install destination.
|
|
112
108
|
*/
|
|
@@ -124,12 +120,13 @@ export interface HostPackSource {
|
|
|
124
120
|
* `'device-list'`: a folder in `installRoot` loads only when the trust
|
|
125
121
|
* list in the adapter's `memento` names its namespace, and the host
|
|
126
122
|
* gains `installedPacks`, `enablePack` and `disablePack`. An install
|
|
127
|
-
* trusts the pack it installs. Requires `installRoot`. `'none'
|
|
128
|
-
*
|
|
129
|
-
*
|
|
130
|
-
*
|
|
123
|
+
* trusts the pack it installs. Requires `installRoot`. `'none'`: every
|
|
124
|
+
* folder this host's own policy authorizes loads, which is right for a
|
|
125
|
+
* host that trusts its own install store (VS Code, the CLI). A web host
|
|
126
|
+
* that installs packs from users picks `'device-list'`. Required: a
|
|
127
|
+
* host states its choice explicitly.
|
|
131
128
|
*/
|
|
132
|
-
readonly trust
|
|
129
|
+
readonly trust: 'device-list' | 'none';
|
|
133
130
|
/**
|
|
134
131
|
* Folders this host currently AUTHORIZES. Under `trust: 'device-list'`
|
|
135
132
|
* these are the folders beyond the install root (the host adds the
|
|
@@ -167,10 +164,8 @@ export interface HostExportCapabilities {
|
|
|
167
164
|
}
|
|
168
165
|
/**
|
|
169
166
|
* The wording nouns every shared behavior's message templates interpolate
|
|
170
|
-
* (`./labels.ts`).
|
|
171
|
-
*
|
|
172
|
-
* template plus these per-host nouns, instead of a per-host
|
|
173
|
-
* reimplementation of the sentence itself.
|
|
167
|
+
* (`./labels.ts`). One template plus these per-host nouns
|
|
168
|
+
* replaces a per-host copy of each sentence.
|
|
174
169
|
*/
|
|
175
170
|
export interface HostLabels {
|
|
176
171
|
/** "extension" | "plugin" | "command line tool" */
|
|
@@ -196,7 +191,7 @@ export interface HostLabels {
|
|
|
196
191
|
* Everything an adapter provides. An adapter is constructible from
|
|
197
192
|
* injected dependencies (no module-scope global reads), which is what
|
|
198
193
|
* lets a conformance test build the REAL adapter over a fake editor
|
|
199
|
-
|
|
194
|
+
*.
|
|
200
195
|
*/
|
|
201
196
|
export interface HostAdapter {
|
|
202
197
|
readonly id: 'vscode' | 'obsidian' | 'cli' | (string & {});
|
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
import type { ArchiveExtractFs } from './pack-archive.js';
|
|
1
2
|
import type { RunTrigger } from '@markii/runtime';
|
|
2
3
|
import type { HostAdapter } from './adapter.js';
|
|
3
4
|
/**
|
|
@@ -110,7 +111,7 @@ export declare function hostDeclaresCapability(adapter: HostAdapter, action: Hos
|
|
|
110
111
|
* `next()` THROWS once exhausted rather than returning a default: an
|
|
111
112
|
* unanswered prompt means the scenario and the implementation disagree
|
|
112
113
|
* about how many questions get asked, which must never be silently read
|
|
113
|
-
* as a deny
|
|
114
|
+
* as a deny.
|
|
114
115
|
*/
|
|
115
116
|
export declare function createAnswerQueue(scenario: HostScenario): {
|
|
116
117
|
next(): boolean;
|
|
@@ -134,6 +135,8 @@ export interface HostScenarioRunResult {
|
|
|
134
135
|
*/
|
|
135
136
|
export declare function runHostScenario(adapter: HostAdapter, scenario: HostScenario, noteText: string, scenarioDir: string, options?: {
|
|
136
137
|
readonly renderAnsi?: (text: string) => Promise<string>;
|
|
138
|
+
/** Where an installed pack archive is extracted. Defaults to the Node file system, which is right for an adapter that reads and writes real files. An adapter over another store (memory, a virtual file system) passes the matching writer. */
|
|
139
|
+
readonly archiveExtractFs?: ArchiveExtractFs;
|
|
137
140
|
}): Promise<HostScenarioRunResult>;
|
|
138
141
|
/** `expected[i]` compared against `actual[i]` for each index up to `expected`'s own length; a length mismatch is reported once rather than index-by-index noise. */
|
|
139
142
|
export declare function containsInOrder(actual: readonly string[], expected: readonly string[]): string[];
|
|
@@ -1,6 +1,5 @@
|
|
|
1
1
|
/**
|
|
2
|
-
* Executes one `conformance/host/<scenario>` case
|
|
3
|
-
* `tmp/W11-corpus-design.md`) against any real `HostAdapter`, so a single
|
|
2
|
+
* Executes one `conformance/host/<scenario>` case against any real `HostAdapter`, so a single
|
|
4
3
|
* plain-data corpus proves the three apps' adapters behave the same.
|
|
5
4
|
*
|
|
6
5
|
* `conformance/host/` itself stays plain data (no TypeScript, matching the
|
|
@@ -26,8 +25,7 @@
|
|
|
26
25
|
* pre-check here, over the same shared functions and the SAME
|
|
27
26
|
* `adapter.labels` a real call site would use, so the scenario proves
|
|
28
27
|
* wording parity across hosts without inventing a capability the contract
|
|
29
|
-
* does not have.
|
|
30
|
-
* finding, not a silent workaround.
|
|
28
|
+
* does not have. The scenario `10-scripts-disabled` holds the behavior.
|
|
31
29
|
*
|
|
32
30
|
* SIMULATED EXECUTION. A `run` action's `simulate` field (plain data) tells
|
|
33
31
|
* this module what the isolate would have produced, instead of spawning a
|
|
@@ -162,7 +160,7 @@ export function hostDeclaresCapability(adapter, action) {
|
|
|
162
160
|
* `next()` THROWS once exhausted rather than returning a default: an
|
|
163
161
|
* unanswered prompt means the scenario and the implementation disagree
|
|
164
162
|
* about how many questions get asked, which must never be silently read
|
|
165
|
-
* as a deny
|
|
163
|
+
* as a deny.
|
|
166
164
|
*/
|
|
167
165
|
export function createAnswerQueue(scenario) {
|
|
168
166
|
const answers = [];
|
|
@@ -264,7 +262,7 @@ export async function runHostScenario(adapter, scenario, noteText, scenarioDir,
|
|
|
264
262
|
// The runner is Node-only test tooling, so it supplies the real Node
|
|
265
263
|
// implementations of the seams the host layer takes by injection.
|
|
266
264
|
htmlEngine: createHtmlExportEngine(),
|
|
267
|
-
archiveExtractFs: createNodeArchiveExtractFs(),
|
|
265
|
+
archiveExtractFs: options.archiveExtractFs ?? createNodeArchiveExtractFs(),
|
|
268
266
|
spawnRun: (spawnOptions) => Promise.resolve(simulatedRunResult(currentSimulation, spawnOptions)),
|
|
269
267
|
...(options.renderAnsi ? { renderAnsi: options.renderAnsi } : {}),
|
|
270
268
|
});
|
|
@@ -3,13 +3,11 @@
|
|
|
3
3
|
* its own run/export/pack/editor wiring. Everything it touches (files, prompts,
|
|
4
4
|
* the isolate) arrives through the adapter, so the main entry stays
|
|
5
5
|
* environment-neutral. VS Code's webview imports only the pure pieces and
|
|
6
|
-
* never calls this function
|
|
6
|
+
* never calls this function.
|
|
7
7
|
*
|
|
8
|
-
*
|
|
9
|
-
*
|
|
10
|
-
*
|
|
11
|
-
* this same pass (`./export-behavior.js`, `./pack-install.js`,
|
|
12
|
-
* `./pack-load.js`, `./editor-behavior.js`). Every one of them still
|
|
8
|
+
* It provides `run`, `diagnostics`, `open`, `exportNote`, `installPack`, `loadPacks`, `completeAt`,
|
|
9
|
+
* `hoverAt`, and `insertComponent`, over the behavior modules (`./export-behavior.js`, `./pack-install.js`,
|
|
10
|
+
* `./pack-load.js`, `./editor-behavior.js`). Every one of them
|
|
13
11
|
* returns the shared `Unsupported` outcome, with one diagnostics line,
|
|
14
12
|
* when the adapter lacks the capability it needs — AGENTS.md's "clean is
|
|
15
13
|
* not silent": a decline is never a silent no-op.
|
|
@@ -4,12 +4,8 @@ import type { HostEditor, HostTextEdit } from './adapter.js';
|
|
|
4
4
|
export declare const STANDARD_ORIGIN_TAG = "standard";
|
|
5
5
|
export declare const LAYOUT_ORIGIN_TAG = "layout";
|
|
6
6
|
/**
|
|
7
|
-
*
|
|
8
|
-
*
|
|
9
|
-
* IDENTICAL function bodies, differing only in which locally-defined
|
|
10
|
-
* constant stood in for the standard/layout tag string. Both apps'
|
|
11
|
-
* constants held the same lower-case values (`'standard'`/`'layout'`),
|
|
12
|
-
* so there was never a wording difference to preserve.
|
|
7
|
+
* The origin tag a completion item carries: the lower-case
|
|
8
|
+
* `'standard'`/`'layout'` strings above, or the pack name.
|
|
13
9
|
*/
|
|
14
10
|
export declare function completionOriginTag(item: CompletionItem): string;
|
|
15
11
|
/** A small cache in front of `buildComponentCatalog` (`../insert/component-catalog.js`), so a completion/hover provider does not re-discover packs from disk on every keystroke. */
|
|
@@ -2,16 +2,16 @@
|
|
|
2
2
|
* The `completeAt`/`hoverAt`/`insertComponent` behaviors' shared half,
|
|
3
3
|
* merged from `apps/vscode/src/completion.ts` + `completion-catalog.ts`,
|
|
4
4
|
* `apps/obsidian/src/complete-component.ts`, and both apps'
|
|
5
|
-
* `insert-component.ts
|
|
5
|
+
* `insert-component.ts`.
|
|
6
6
|
*
|
|
7
|
-
* NODE-FREE by design
|
|
7
|
+
* NODE-FREE by design: re-exported
|
|
8
8
|
* from `../browser.ts` as well as `../index.ts`, so VS Code's webview
|
|
9
9
|
* bundle can read the origin-tag vocabulary and the pure completion math
|
|
10
10
|
* directly if a future slice needs to. `CatalogCache.get`'s injected
|
|
11
11
|
* `load` is the one thing that reaches disk, and it is always supplied by
|
|
12
12
|
* the caller (a main-entry-only pack-discovery call), never imported here.
|
|
13
13
|
*
|
|
14
|
-
* What stays app-side (deliberately
|
|
14
|
+
* What stays app-side (deliberately): VS
|
|
15
15
|
* Code's sectioned quick-pick presentation (`Standard`/`Layout`/`<pack>
|
|
16
16
|
* pack` separators) and Obsidian's flat fuzzy list are a genuine product
|
|
17
17
|
* difference, not duplication — this module returns the catalog and the
|
|
@@ -25,12 +25,8 @@ import { closesOpenContainerFence, completionAt, componentDocumentation, fenceEx
|
|
|
25
25
|
export const STANDARD_ORIGIN_TAG = 'standard';
|
|
26
26
|
export const LAYOUT_ORIGIN_TAG = 'layout';
|
|
27
27
|
/**
|
|
28
|
-
*
|
|
29
|
-
*
|
|
30
|
-
* IDENTICAL function bodies, differing only in which locally-defined
|
|
31
|
-
* constant stood in for the standard/layout tag string. Both apps'
|
|
32
|
-
* constants held the same lower-case values (`'standard'`/`'layout'`),
|
|
33
|
-
* so there was never a wording difference to preserve.
|
|
28
|
+
* The origin tag a completion item carries: the lower-case
|
|
29
|
+
* `'standard'`/`'layout'` strings above, or the pack name.
|
|
34
30
|
*/
|
|
35
31
|
export function completionOriginTag(item) {
|
|
36
32
|
if (item.kind !== 'component')
|
|
@@ -2,7 +2,7 @@
|
|
|
2
2
|
* The `exportNote` behavior: outcome shape, wording, and format gating,
|
|
3
3
|
* merged from `apps/vscode/src/export-html.ts`, the host-neutral half of
|
|
4
4
|
* `apps/obsidian/src/export-note.ts`, and `apps/cli/src/export-note.ts`'s
|
|
5
|
-
* `exportHtml
|
|
5
|
+
* `exportHtml`.
|
|
6
6
|
*
|
|
7
7
|
* `html` and `md-plain` are fully implemented here, over `../export/note-export.js`'s
|
|
8
8
|
* `buildNoteExport` (already host-neutral, already shared) and
|
|
@@ -12,20 +12,18 @@
|
|
|
12
12
|
* AGENTS.md's package boundaries), so it is rendered through the injected
|
|
13
13
|
* `renderAnsi` option; a host that omits it gets `Unsupported`.
|
|
14
14
|
*
|
|
15
|
-
* PDF stays a seam, never an implementation here,
|
|
16
|
-
* `tmp/W11-adapter-design.md` specifies: this module builds the same HTML
|
|
15
|
+
* PDF stays a seam, never an implementation here, this module builds the same HTML
|
|
17
16
|
* document `html` would have written and hands it to
|
|
18
17
|
* `adapter.exports.htmlToPdf`, but the DEGRADE-TO-HTML-ON-FAILURE product
|
|
19
18
|
* behavior Obsidian's own `exportNoteAsPdf` layers on top (falling back to
|
|
20
19
|
* writing the HTML file when printing is unavailable or fails, and
|
|
21
20
|
* reporting which of the two happened) is Obsidian-specific policy about
|
|
22
21
|
* what to do with a seam's failure, not the seam itself — it stays
|
|
23
|
-
* app-side.
|
|
22
|
+
* app-side.
|
|
24
23
|
*
|
|
25
24
|
* Cascade orchestration (multi-note export, `walkNoteCascade` +
|
|
26
25
|
* `assignCascadeFileNames` + `rewriteCascadeLinks` + `zipExportArchive`)
|
|
27
|
-
* is
|
|
28
|
-
* section for why, and what Phase 2 (or a follow-up) still needs to do.
|
|
26
|
+
* is not part of this module: it stays with each host.
|
|
29
27
|
*/
|
|
30
28
|
import type { StoredValue } from '@markii/runtime';
|
|
31
29
|
import type { OnDiagnostic, UnavailableComponent } from '@markii/stdlib';
|
package/dist/host/labels.d.ts
CHANGED
|
@@ -3,8 +3,7 @@
|
|
|
3
3
|
* (`./script-execution.ts`, `./refresh-interval.ts`) interpolates, and the
|
|
4
4
|
* one concrete record per app this repo ships. Each app's `HostAdapter`
|
|
5
5
|
* imports its record rather than inventing its own strings, which is what
|
|
6
|
-
*
|
|
7
|
-
* section A4) into one template.
|
|
6
|
+
* lets one template serve every host.
|
|
8
7
|
*
|
|
9
8
|
* Pure and dependency-free: re-exported from `../browser.ts` as well as
|
|
10
9
|
* `../index.ts` so VS Code's Node-free webview bundle can read it too.
|
|
@@ -1,13 +1,7 @@
|
|
|
1
1
|
/**
|
|
2
2
|
* `.mkp` pack archive handling, merged from `apps/vscode/src/packs/archive-packs.ts`
|
|
3
|
-
* and `apps/obsidian/src/packs/archive-packs.ts
|
|
4
|
-
*
|
|
5
|
-
* earlier, unverified guess) and found them functionally byte-identical:
|
|
6
|
-
* the same three exports (`describeArchiveError`, `writeArchiveContents`,
|
|
7
|
-
* `ArchiveExtractFs`), the same implementation, the same path-jail
|
|
8
|
-
* reasoning. They differed only in doc-comment wording (which host's
|
|
9
|
-
* install command they described) and one em dash in a comment, which
|
|
10
|
-
* carries no behavior. See `tmp/W11-phase1b.md` for the exact diff output.
|
|
3
|
+
* and `apps/obsidian/src/packs/archive-packs.ts`. It exports
|
|
4
|
+
* `describeArchiveError`, `writeArchiveContents` and `ArchiveExtractFs`.
|
|
11
5
|
*
|
|
12
6
|
* This module bridges `@markii/pack`'s in-memory archive reader
|
|
13
7
|
* (`openPackArchive`, never modified here) into the write a pack install
|
|
@@ -67,8 +67,7 @@ export declare function installConsentMessage(packName: string, labels: HostLabe
|
|
|
67
67
|
/**
|
|
68
68
|
* The collision confirmation's wording: a namespace already installed,
|
|
69
69
|
* asked before replacing it. CANONICAL WORDING: "removes" (VS Code's prior
|
|
70
|
-
* wording) over Obsidian's prior "deletes"
|
|
71
|
-
* before/after table for the exact strings this replaces.
|
|
70
|
+
* wording) over Obsidian's prior "deletes".
|
|
72
71
|
*/
|
|
73
72
|
export declare function installReplaceConfirmMessage(packName: string): string;
|
|
74
73
|
/**
|
|
@@ -1,11 +1,9 @@
|
|
|
1
1
|
/**
|
|
2
2
|
* The `.mkp` pack-install decision logic, merged from
|
|
3
3
|
* `apps/vscode/src/packs/install-pack.ts` and
|
|
4
|
-
* `apps/obsidian/src/packs/install-pack.ts
|
|
5
|
-
*
|
|
6
|
-
*
|
|
7
|
-
* Obsidian refuses a bundled-namespace archive before the consent prompt
|
|
8
|
-
* and VS Code has no such concept).
|
|
4
|
+
* `apps/obsidian/src/packs/install-pack.ts`. Obsidian refuses a
|
|
5
|
+
* bundled-namespace archive before the consent prompt and VS Code has no
|
|
6
|
+
* such concept.
|
|
9
7
|
*
|
|
10
8
|
* `reservedNamespaces` generalizes Obsidian's `bundledNamespaces`: it
|
|
11
9
|
* defaults to empty, so VS Code's behavior is byte-identical to before
|
|
@@ -131,8 +129,7 @@ export function installConsentMessage(packName, labels) {
|
|
|
131
129
|
/**
|
|
132
130
|
* The collision confirmation's wording: a namespace already installed,
|
|
133
131
|
* asked before replacing it. CANONICAL WORDING: "removes" (VS Code's prior
|
|
134
|
-
* wording) over Obsidian's prior "deletes"
|
|
135
|
-
* before/after table for the exact strings this replaces.
|
|
132
|
+
* wording) over Obsidian's prior "deletes".
|
|
136
133
|
*/
|
|
137
134
|
export function installReplaceConfirmMessage(packName) {
|
|
138
135
|
return `A pack named "${packName}" is already installed. Replacing it removes the installed copy and cannot be undone.`;
|
package/dist/host/pack-load.d.ts
CHANGED
|
@@ -1,8 +1,7 @@
|
|
|
1
1
|
/**
|
|
2
2
|
* The shared discovery path behind `loadPacks`, merged from
|
|
3
3
|
* `apps/vscode/src/packs/discover-configured-packs.ts` and
|
|
4
|
-
* `apps/obsidian/src/packs/discover-configured-packs.ts`
|
|
5
|
-
* A3) plus the discovery-and-namespace-collection half both apps'
|
|
4
|
+
* `apps/obsidian/src/packs/discover-configured-packs.ts` plus the discovery-and-namespace-collection half both apps'
|
|
6
5
|
* `packs/pack-context.ts` also duplicate on top of it.
|
|
7
6
|
*
|
|
8
7
|
* Pack POLICY — which folders are even candidates before any content is
|
|
@@ -12,7 +12,7 @@
|
|
|
12
12
|
* already asked), enabling a present folder asks the same prompt, and
|
|
13
13
|
* disabling or removing withdraws the entry.
|
|
14
14
|
*
|
|
15
|
-
* A host that declares `trust: 'none'`
|
|
15
|
+
* A host that declares `trust: 'none'` trusts every
|
|
16
16
|
* folder its own policy authorizes, and every function here is inert for
|
|
17
17
|
* it. Neutral on purpose: only the adapter's file and state primitives
|
|
18
18
|
* are used.
|
|
@@ -3,9 +3,7 @@
|
|
|
3
3
|
* merged from `apps/vscode/src/refresh-interval.ts` (the input-box
|
|
4
4
|
* parse/validate half) and `apps/obsidian/src/local-settings.ts`'s
|
|
5
5
|
* `refreshIntervalMsFromSeconds`/`MIN_REFRESH_INTERVAL_SECONDS` (the
|
|
6
|
-
* read-side clamp half)
|
|
7
|
-
* verbatim, with Obsidian's own comment noting it mirrors VS Code's, and
|
|
8
|
-
* the clamp-not-reject policy was duplicated as both prose and behavior.
|
|
6
|
+
* read-side clamp half).
|
|
9
7
|
*
|
|
10
8
|
* The policy: a positive value under `MIN_REFRESH_INTERVAL_SECONDS` is
|
|
11
9
|
* still ACCEPTED as typed (a host's own settings UI must not silently
|
|
@@ -3,9 +3,7 @@
|
|
|
3
3
|
* merged from `apps/vscode/src/refresh-interval.ts` (the input-box
|
|
4
4
|
* parse/validate half) and `apps/obsidian/src/local-settings.ts`'s
|
|
5
5
|
* `refreshIntervalMsFromSeconds`/`MIN_REFRESH_INTERVAL_SECONDS` (the
|
|
6
|
-
* read-side clamp half)
|
|
7
|
-
* verbatim, with Obsidian's own comment noting it mirrors VS Code's, and
|
|
8
|
-
* the clamp-not-reject policy was duplicated as both prose and behavior.
|
|
6
|
+
* read-side clamp half).
|
|
9
7
|
*
|
|
10
8
|
* The policy: a positive value under `MIN_REFRESH_INTERVAL_SECONDS` is
|
|
11
9
|
* still ACCEPTED as typed (a host's own settings UI must not silently
|
|
@@ -1,7 +1,6 @@
|
|
|
1
1
|
/**
|
|
2
2
|
* The `run` behavior's host-shaped seams, built from a `HostAdapter`:
|
|
3
|
-
*
|
|
4
|
-
* times over.
|
|
3
|
+
* the grant prompts and the isolate spawn live here once for every host.
|
|
5
4
|
*
|
|
6
5
|
* A1: `apps/vscode/src/preview-panel.ts`'s `promptHostAdapter` /
|
|
7
6
|
* `promptUnknownHostsAdapter` / `promptManyHostsAdapter`,
|
|
@@ -24,7 +23,7 @@
|
|
|
24
23
|
* `runOnce` (the existing, already-shared grant-flow-plus-spawn
|
|
25
24
|
* orchestration) and writes the `RunTrace` through `adapter.now()` rather
|
|
26
25
|
* than `Date.now()`, so a fixed clock in a test fake makes the trace
|
|
27
|
-
* byte-stable
|
|
26
|
+
* byte-stable.
|
|
28
27
|
*/
|
|
29
28
|
import type { RunTrigger } from '@markii/runtime';
|
|
30
29
|
import { type PromptHost, type PromptManyHosts, type PromptUnknownHosts } from '../run/grant-flow.js';
|
|
@@ -54,7 +53,7 @@ export declare function promptsFromAdapter(adapter: HostAdapter): {
|
|
|
54
53
|
};
|
|
55
54
|
/**
|
|
56
55
|
* The one `spawnRun` adapter every Node host (`apps/vscode`, `apps/cli`)
|
|
57
|
-
*
|
|
56
|
+
* needs, plus the browser-isolate path Obsidian's
|
|
58
57
|
* own `spawnRun` wrapper needed. Dispatches on `HostIsolate`'s
|
|
59
58
|
* discriminated union: a `'node'` host supplies only a worker path; a
|
|
60
59
|
* `'browser'` host supplies an async, disposable `IsolateSpawner` factory,
|
|
@@ -63,9 +63,23 @@ function noIsolateResult(cacheSnapshot) {
|
|
|
63
63
|
cacheSnapshot,
|
|
64
64
|
};
|
|
65
65
|
}
|
|
66
|
+
/** A synthetic `RunResult` for a node isolate whose worker file cannot be located. The run never throws. */
|
|
67
|
+
function workerMissingResult(cacheSnapshot, error) {
|
|
68
|
+
return {
|
|
69
|
+
values: {},
|
|
70
|
+
failures: [
|
|
71
|
+
{
|
|
72
|
+
name: '<document>',
|
|
73
|
+
message: `the script worker could not be located: ${error instanceof Error ? error.message : String(error)}`,
|
|
74
|
+
kind: 'capability-denied',
|
|
75
|
+
},
|
|
76
|
+
],
|
|
77
|
+
cacheSnapshot,
|
|
78
|
+
};
|
|
79
|
+
}
|
|
66
80
|
/**
|
|
67
81
|
* The one `spawnRun` adapter every Node host (`apps/vscode`, `apps/cli`)
|
|
68
|
-
*
|
|
82
|
+
* needs, plus the browser-isolate path Obsidian's
|
|
69
83
|
* own `spawnRun` wrapper needed. Dispatches on `HostIsolate`'s
|
|
70
84
|
* discriminated union: a `'node'` host supplies only a worker path; a
|
|
71
85
|
* `'browser'` host supplies an async, disposable `IsolateSpawner` factory,
|
|
@@ -75,9 +89,16 @@ export async function spawnRunViaAdapter(isolate, options) {
|
|
|
75
89
|
if (!isolate)
|
|
76
90
|
return noIsolateResult(options.cacheSnapshot);
|
|
77
91
|
if (isolate.kind === 'node') {
|
|
92
|
+
let workerPath;
|
|
93
|
+
try {
|
|
94
|
+
workerPath = isolate.workerPath();
|
|
95
|
+
}
|
|
96
|
+
catch (error) {
|
|
97
|
+
return workerMissingResult(options.cacheSnapshot, error);
|
|
98
|
+
}
|
|
78
99
|
return spawnRunHost({
|
|
79
100
|
...options,
|
|
80
|
-
workerPath
|
|
101
|
+
workerPath,
|
|
81
102
|
spawnIsolate: isolate.spawnIsolate,
|
|
82
103
|
});
|
|
83
104
|
}
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
/**
|
|
2
2
|
* The device-level script-execution switch and every sentence it can
|
|
3
3
|
* produce, merged from `apps/vscode/src/script-execution.ts` and
|
|
4
|
-
* `apps/obsidian/src/script-execution.ts` (
|
|
4
|
+
* `apps/obsidian/src/script-execution.ts` (same file
|
|
5
5
|
* name, same four exports, doc comments sharing the same "WHAT IT IS /
|
|
6
6
|
* WHY DEVICE-LOCAL / WHY THE WORDING LIVES HERE" structure, differing
|
|
7
7
|
* only in a handful of words).
|
package/dist/index.js
CHANGED
|
@@ -4,8 +4,7 @@
|
|
|
4
4
|
// `esbuild-wasm`, `@markii/react` or `@markii/html` at runtime
|
|
5
5
|
// (`apps/vscode/src/browser-entry.probe.test.ts` bundles it for a browser to
|
|
6
6
|
// prove it). What needs Node lives in `./node.ts`, published as
|
|
7
|
-
// `@markii/host/node`.
|
|
8
|
-
// never added to `build:dist`. See AGENTS.md's repo-layout entry for
|
|
7
|
+
// `@markii/host/node`. See AGENTS.md's repo-layout entry for
|
|
9
8
|
// `packages/markii-host` for the module-by-module breakdown.
|
|
10
9
|
//
|
|
11
10
|
// This is the security-critical layer (tier gating, the grant model,
|