feat: add standalone and HiveCast SDK demos
This commit is contained in:
parent
6f516fe2f8
commit
f3fd4e109f
33
README.md
33
README.md
@ -156,6 +156,37 @@ configure broker access, run actors, and invoke them without importing provider
|
||||
overlay packages into the SDK layer. Managed-host promotion is optional and is
|
||||
only exercised when `MATRIX_SDK_RUNTIME_HOST_BIN` is supplied.
|
||||
|
||||
## Demos
|
||||
|
||||
Standalone SDK demo, no provider account or key required:
|
||||
|
||||
```bash
|
||||
pnpm demo:standalone
|
||||
```
|
||||
|
||||
This builds the SDK and `examples/standalone-greeter`, starts the actor with
|
||||
`matrix run`, calls it with `matrix invoke`, and shuts it down.
|
||||
|
||||
HiveCast API-key login/config demo:
|
||||
|
||||
```bash
|
||||
export MATRIX_CLOUD=https://dev.hivecast.ai
|
||||
export MATRIX_SPACE=<your-space-root>
|
||||
export MATRIX_API_KEY=<your-api-key>
|
||||
pnpm demo:hivecast-login
|
||||
```
|
||||
|
||||
This validates the key with HiveCast and writes the SDK package-local
|
||||
`.matrix/config.json` plus `.matrix/credentials/matrix-api-key.json` shape
|
||||
without printing or committing the key. By default the demo uses a temporary
|
||||
home and deletes it after success.
|
||||
|
||||
Current boundary: this HiveCast demo proves SDK-side key validation and config
|
||||
storage. It does not yet prove a package running directly on a HiveCast-issued
|
||||
broker credential. That requires the provider-owned login/credential-exchange
|
||||
slice so `matrix login` can replace manual `matrix configure` and issue/store
|
||||
the broker credentials needed by the SDK transport.
|
||||
|
||||
## Repository Layout
|
||||
|
||||
```text
|
||||
@ -169,6 +200,8 @@ packages/
|
||||
omega-core/
|
||||
sdk/
|
||||
scripts/
|
||||
demo:standalone
|
||||
demo:hivecast-login
|
||||
prove-external-consumer.mjs
|
||||
prove-sdk-cli-uat.mjs
|
||||
```
|
||||
|
||||
@ -23,6 +23,13 @@ The SDK package surface is standalone enough for the current authoring proof:
|
||||
The proof script also checks that generated author-package files do not contain
|
||||
legacy monorepo paths or upper-layer package dependencies.
|
||||
|
||||
Checked-in demos now cover the same boundary in user-facing form:
|
||||
|
||||
- `pnpm demo:standalone` runs `examples/standalone-greeter` without provider
|
||||
credentials.
|
||||
- `pnpm demo:hivecast-login` validates a user-supplied HiveCast API key and
|
||||
writes package-local SDK config/credentials in a temporary demo home.
|
||||
|
||||
## Cleanup Completed
|
||||
|
||||
- Root README now describes this as a provider-neutral SDK, not a HiveCast
|
||||
@ -87,3 +94,14 @@ Expected:
|
||||
- `legacyMonorepoPathReferences` is `false`.
|
||||
- `managedHostProof` is skipped unless `MATRIX_SDK_RUNTIME_HOST_BIN` is supplied.
|
||||
- `prove` builds, tests, type-checks, and packs all workspace packages.
|
||||
|
||||
Demo checks:
|
||||
|
||||
```bash
|
||||
pnpm demo:standalone
|
||||
pnpm demo:hivecast-login -- --check
|
||||
```
|
||||
|
||||
`demo:hivecast-login -- --check` proves the demo wiring without requiring a
|
||||
secret. A real HiveCast proof requires `MATRIX_API_KEY`, `MATRIX_CLOUD`, and
|
||||
`MATRIX_SPACE` from the user.
|
||||
|
||||
5
examples/hivecast-login/.env.example
Normal file
5
examples/hivecast-login/.env.example
Normal file
@ -0,0 +1,5 @@
|
||||
# Copy this file outside git-tracked secrets handling or export these variables
|
||||
# in your shell. Do not commit real keys.
|
||||
MATRIX_CLOUD=https://dev.hivecast.ai
|
||||
MATRIX_SPACE=your-space-root
|
||||
MATRIX_API_KEY=hc_your_key_here
|
||||
3
examples/hivecast-login/.gitignore
vendored
Normal file
3
examples/hivecast-login/.gitignore
vendored
Normal file
@ -0,0 +1,3 @@
|
||||
.env
|
||||
.matrix/
|
||||
demo-home/
|
||||
42
examples/hivecast-login/README.md
Normal file
42
examples/hivecast-login/README.md
Normal file
@ -0,0 +1,42 @@
|
||||
# HiveCast API-Key Login Demo
|
||||
|
||||
This demo proves the SDK-side HiveCast credential shape without committing a
|
||||
secret.
|
||||
|
||||
It validates a user-supplied HiveCast API key against the configured HiveCast
|
||||
cloud, then writes the same package-local `.matrix` config/credential files that
|
||||
`matrix configure` writes. This is the current API-key login shape.
|
||||
|
||||
It does **not** prove hosted broker execution yet. The SDK still needs a
|
||||
provider-owned credential exchange/login command before a package can use a
|
||||
HiveCast-issued broker JWT directly from this repo.
|
||||
|
||||
## Run
|
||||
|
||||
```bash
|
||||
export MATRIX_CLOUD=https://dev.hivecast.ai
|
||||
export MATRIX_SPACE=<your-space-root>
|
||||
export MATRIX_API_KEY=<your-api-key>
|
||||
|
||||
pnpm demo:hivecast-login
|
||||
```
|
||||
|
||||
Optional:
|
||||
|
||||
```bash
|
||||
MATRIX_DEMO_HOME=/tmp/my-sdk-hivecast-demo pnpm demo:hivecast-login
|
||||
MATRIX_DEMO_KEEP=1 pnpm demo:hivecast-login
|
||||
```
|
||||
|
||||
The key is never printed. By default the temporary demo home is deleted after a
|
||||
successful run. Set `MATRIX_DEMO_KEEP=1` to inspect the generated `.matrix`
|
||||
files locally.
|
||||
|
||||
## Check Script Wiring Without A Key
|
||||
|
||||
```bash
|
||||
pnpm demo:hivecast-login -- --check
|
||||
```
|
||||
|
||||
This only verifies that the demo is installed and intentionally refuses to run
|
||||
without credentials.
|
||||
120
examples/hivecast-login/run-demo.mjs
Normal file
120
examples/hivecast-login/run-demo.mjs
Normal file
@ -0,0 +1,120 @@
|
||||
import { mkdtempSync, rmSync, existsSync, readFileSync } from 'node:fs';
|
||||
import { tmpdir } from 'node:os';
|
||||
import { resolve, join } from 'node:path';
|
||||
import { spawnSync } from 'node:child_process';
|
||||
|
||||
const args = new Set(process.argv.slice(2));
|
||||
const checkOnly = args.has('--check');
|
||||
const repoRoot = resolve(new URL('../..', import.meta.url).pathname);
|
||||
const matrixCli = resolve(repoRoot, 'packages', 'cli', 'dist', 'bin', 'matrix.js');
|
||||
|
||||
function envString(...names) {
|
||||
for (const name of names) {
|
||||
const value = process.env[name];
|
||||
if (typeof value === 'string' && value.trim()) return value.trim();
|
||||
}
|
||||
return undefined;
|
||||
}
|
||||
|
||||
function run(command, commandArgs, options = {}) {
|
||||
const result = spawnSync(command, commandArgs, {
|
||||
cwd: options.cwd ?? repoRoot,
|
||||
stdio: options.stdio ?? 'pipe',
|
||||
env: process.env,
|
||||
encoding: 'utf8',
|
||||
});
|
||||
if (result.error) throw result.error;
|
||||
if (result.status !== 0) {
|
||||
throw new Error(`${command} ${commandArgs.join(' ')} failed with exit ${result.status}\n${result.stderr}${result.stdout}`);
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
function resolveConfig() {
|
||||
const key = envString('MATRIX_API_KEY', 'HIVECAST_API_KEY', 'HIVECAST_TEST_KEY');
|
||||
const cloud = envString('MATRIX_CLOUD', 'HIVECAST_CLOUD', 'HIVECAST_TEST_CLOUD');
|
||||
const space = envString('MATRIX_SPACE', 'HIVECAST_SPACE', 'HIVECAST_TEST_SPACE');
|
||||
const provided = [key, cloud, space].filter(Boolean).length;
|
||||
if (provided > 0 && provided < 3) {
|
||||
throw new Error('Provide MATRIX_API_KEY, MATRIX_CLOUD, and MATRIX_SPACE together');
|
||||
}
|
||||
return key && cloud && space
|
||||
? { key, cloud: cloud.replace(/\/+$/g, ''), space }
|
||||
: null;
|
||||
}
|
||||
|
||||
async function validateHiveCastKey(config) {
|
||||
const response = await fetch(`${config.cloud}/api/install/key-info`, {
|
||||
method: 'POST',
|
||||
headers: {
|
||||
authorization: `Bearer ${config.key}`,
|
||||
'content-type': 'application/json',
|
||||
},
|
||||
body: JSON.stringify({ space: config.space }),
|
||||
});
|
||||
const text = await response.text();
|
||||
if (!response.ok) {
|
||||
throw new Error(`HiveCast key validation failed (${response.status}): ${text}`);
|
||||
}
|
||||
const body = text.trim() ? JSON.parse(text) : {};
|
||||
if (body?.ok !== true) {
|
||||
throw new Error(`HiveCast key validation did not return ok:true: ${text}`);
|
||||
}
|
||||
return {
|
||||
keyId: body.key?.id ?? body.id ?? null,
|
||||
fingerprint: body.key?.fingerprint ?? body.fingerprint ?? null,
|
||||
};
|
||||
}
|
||||
|
||||
const config = resolveConfig();
|
||||
if (!config) {
|
||||
const message = 'HiveCast demo requires MATRIX_API_KEY, MATRIX_CLOUD, and MATRIX_SPACE';
|
||||
if (checkOnly) {
|
||||
console.log(JSON.stringify({ ok: true, demo: 'hivecast-login', credentialsRequired: true, message }, null, 2));
|
||||
process.exit(0);
|
||||
}
|
||||
throw new Error(message);
|
||||
}
|
||||
if (checkOnly) {
|
||||
console.log(JSON.stringify({ ok: true, demo: 'hivecast-login', credentialsAvailable: true }, null, 2));
|
||||
process.exit(0);
|
||||
}
|
||||
|
||||
const demoHome = process.env.MATRIX_DEMO_HOME
|
||||
? resolve(process.env.MATRIX_DEMO_HOME)
|
||||
: mkdtempSync(join(tmpdir(), 'matrix-sdk-hivecast-login.'));
|
||||
const keep = process.env.MATRIX_DEMO_KEEP === '1' || Boolean(process.env.MATRIX_DEMO_HOME);
|
||||
|
||||
try {
|
||||
const validation = await validateHiveCastKey(config);
|
||||
run(process.execPath, [
|
||||
matrixCli, 'configure',
|
||||
'--dir', demoHome,
|
||||
'--key', config.key,
|
||||
'--cloud', config.cloud,
|
||||
'--space', config.space,
|
||||
]);
|
||||
|
||||
const credentialPath = join(demoHome, '.matrix', 'credentials', 'matrix-api-key.json');
|
||||
const configPath = join(demoHome, '.matrix', 'config.json');
|
||||
if (!existsSync(credentialPath)) throw new Error(`Credential file was not written: ${credentialPath}`);
|
||||
if (!existsSync(configPath)) throw new Error(`Config file was not written: ${configPath}`);
|
||||
const writtenCredential = JSON.parse(readFileSync(credentialPath, 'utf8'));
|
||||
if (writtenCredential.key !== config.key) throw new Error('Written credential key does not match input key');
|
||||
if (writtenCredential.cloud !== config.cloud) throw new Error('Written credential cloud does not match input cloud');
|
||||
if (writtenCredential.space !== config.space) throw new Error('Written credential space does not match input space');
|
||||
|
||||
console.log(JSON.stringify({
|
||||
ok: true,
|
||||
demo: 'hivecast-login',
|
||||
cloud: config.cloud,
|
||||
space: config.space,
|
||||
keyValidated: true,
|
||||
keyId: validation.keyId,
|
||||
fingerprint: validation.fingerprint,
|
||||
demoHome: keep ? demoHome : '(temporary, removed)',
|
||||
credentialPath: keep ? credentialPath : '(temporary, removed)',
|
||||
}, null, 2));
|
||||
} finally {
|
||||
if (!keep) rmSync(demoHome, { recursive: true, force: true });
|
||||
}
|
||||
2
examples/standalone-greeter/.gitignore
vendored
Normal file
2
examples/standalone-greeter/.gitignore
vendored
Normal file
@ -0,0 +1,2 @@
|
||||
.matrix/
|
||||
dist/
|
||||
20
examples/standalone-greeter/README.md
Normal file
20
examples/standalone-greeter/README.md
Normal file
@ -0,0 +1,20 @@
|
||||
# Standalone Greeter Demo
|
||||
|
||||
This demo proves the SDK can run without HiveCast, without a managed platform,
|
||||
and without committed credentials.
|
||||
|
||||
Run from the repository root:
|
||||
|
||||
```bash
|
||||
pnpm demo:standalone
|
||||
```
|
||||
|
||||
What it proves:
|
||||
|
||||
- the SDK packages build from this repo,
|
||||
- this package builds against `@open-matrix/core`,
|
||||
- `matrix run` starts the actor from the package manifest,
|
||||
- `matrix invoke demo.greeter echo ...` calls the actor over the SDK local
|
||||
runtime path,
|
||||
- all runtime state is written under the demo package's local `.matrix/`
|
||||
directory.
|
||||
28
examples/standalone-greeter/matrix.json
Normal file
28
examples/standalone-greeter/matrix.json
Normal file
@ -0,0 +1,28 @@
|
||||
{
|
||||
"name": "matrix-sdk-example-standalone-greeter",
|
||||
"version": "0.0.0",
|
||||
"runtime": {
|
||||
"language": "typescript",
|
||||
"entry": "./dist/index.js",
|
||||
"factory": {
|
||||
"kind": "factory",
|
||||
"export": "createStandaloneGreeterActor",
|
||||
"instance": {
|
||||
"id": "RUNTIME-HOST-DEMO-GREETER",
|
||||
"class": "service",
|
||||
"rootKind": "component",
|
||||
"componentType": "GreeterActor",
|
||||
"autoStart": true
|
||||
}
|
||||
}
|
||||
},
|
||||
"components": [
|
||||
{
|
||||
"type": "GreeterActor",
|
||||
"export": "GreeterActor",
|
||||
"mount": "demo.greeter",
|
||||
"surface": "headless",
|
||||
"accepts": ["echo", "getStatus"]
|
||||
}
|
||||
]
|
||||
}
|
||||
15
examples/standalone-greeter/package.json
Normal file
15
examples/standalone-greeter/package.json
Normal file
@ -0,0 +1,15 @@
|
||||
{
|
||||
"name": "matrix-sdk-example-standalone-greeter",
|
||||
"version": "0.0.0",
|
||||
"private": true,
|
||||
"type": "module",
|
||||
"scripts": {
|
||||
"build": "tsc -p tsconfig.json"
|
||||
},
|
||||
"dependencies": {
|
||||
"@open-matrix/core": "workspace:*"
|
||||
},
|
||||
"devDependencies": {
|
||||
"typescript": "^5.7.0"
|
||||
}
|
||||
}
|
||||
113
examples/standalone-greeter/run-demo.mjs
Normal file
113
examples/standalone-greeter/run-demo.mjs
Normal file
@ -0,0 +1,113 @@
|
||||
import { spawn, spawnSync } from 'node:child_process';
|
||||
import { createServer } from 'node:http';
|
||||
import { dirname, resolve } from 'node:path';
|
||||
import { fileURLToPath } from 'node:url';
|
||||
|
||||
const __dirname = dirname(fileURLToPath(import.meta.url));
|
||||
const repoRoot = resolve(__dirname, '..', '..');
|
||||
const demoDir = __dirname;
|
||||
const matrixCli = resolve(repoRoot, 'packages', 'cli', 'dist', 'bin', 'matrix.js');
|
||||
|
||||
function run(command, args, options = {}) {
|
||||
const result = spawnSync(command, args, {
|
||||
cwd: options.cwd ?? repoRoot,
|
||||
stdio: options.stdio ?? 'inherit',
|
||||
env: process.env,
|
||||
encoding: 'utf8',
|
||||
});
|
||||
if (result.error) throw result.error;
|
||||
if (result.status !== 0) {
|
||||
throw new Error(`${command} ${args.join(' ')} failed with exit ${result.status}`);
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
async function freePort() {
|
||||
return await new Promise((resolvePort, reject) => {
|
||||
const server = createServer();
|
||||
server.on('error', reject);
|
||||
server.listen(0, '127.0.0.1', () => {
|
||||
const address = server.address();
|
||||
if (!address || typeof address === 'string') {
|
||||
server.close(() => reject(new Error('Could not allocate demo port')));
|
||||
return;
|
||||
}
|
||||
const { port } = address;
|
||||
server.close(() => resolvePort(port));
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
async function waitForHealth(port, child) {
|
||||
const deadline = Date.now() + 10_000;
|
||||
let lastError;
|
||||
while (Date.now() < deadline) {
|
||||
if (child.exitCode !== null) throw new Error(`matrix run exited early with ${child.exitCode}`);
|
||||
try {
|
||||
const response = await fetch(`http://127.0.0.1:${port}/healthz`);
|
||||
if (response.ok) return;
|
||||
lastError = new Error(`healthz returned ${response.status}`);
|
||||
} catch (error) {
|
||||
lastError = error;
|
||||
}
|
||||
await new Promise((resolveDelay) => setTimeout(resolveDelay, 100));
|
||||
}
|
||||
throw lastError ?? new Error('Timed out waiting for matrix run healthz');
|
||||
}
|
||||
|
||||
function stop(child) {
|
||||
return new Promise((resolveStop) => {
|
||||
if (child.exitCode !== null) {
|
||||
resolveStop();
|
||||
return;
|
||||
}
|
||||
child.once('exit', () => resolveStop());
|
||||
child.kill('SIGTERM');
|
||||
setTimeout(() => {
|
||||
if (child.exitCode === null) child.kill('SIGKILL');
|
||||
}, 3000).unref();
|
||||
});
|
||||
}
|
||||
|
||||
const port = await freePort();
|
||||
let runner;
|
||||
|
||||
try {
|
||||
run('pnpm', ['run', 'build']);
|
||||
run('pnpm', ['--filter', 'matrix-sdk-example-standalone-greeter', 'run', 'build']);
|
||||
|
||||
runner = spawn(process.execPath, [
|
||||
matrixCli, 'run', demoDir,
|
||||
'--dir', demoDir,
|
||||
'--port', String(port),
|
||||
], {
|
||||
cwd: repoRoot,
|
||||
stdio: ['ignore', 'pipe', 'pipe'],
|
||||
env: process.env,
|
||||
});
|
||||
runner.stderr.on('data', (chunk) => process.stderr.write(chunk));
|
||||
await waitForHealth(port, runner);
|
||||
|
||||
const invoked = run(process.execPath, [
|
||||
matrixCli, 'invoke',
|
||||
'demo.greeter',
|
||||
'echo',
|
||||
'{"message":"hello-from-standalone-demo"}',
|
||||
'--dir', demoDir,
|
||||
'--port', String(port),
|
||||
], { cwd: repoRoot, stdio: 'pipe' });
|
||||
const body = JSON.parse(invoked.stdout.trim());
|
||||
if (body?.ok !== true || body?.result?.message !== 'hello-from-standalone-demo') {
|
||||
throw new Error(`Unexpected invoke result: ${invoked.stdout}`);
|
||||
}
|
||||
|
||||
console.log(JSON.stringify({
|
||||
ok: true,
|
||||
demo: 'standalone-greeter',
|
||||
mount: 'demo.greeter',
|
||||
port,
|
||||
invoke: body,
|
||||
}, null, 2));
|
||||
} finally {
|
||||
if (runner) await stop(runner);
|
||||
}
|
||||
24
examples/standalone-greeter/src/GreeterActor.ts
Normal file
24
examples/standalone-greeter/src/GreeterActor.ts
Normal file
@ -0,0 +1,24 @@
|
||||
import { MatrixActor } from '@open-matrix/core';
|
||||
|
||||
export class GreeterActor extends MatrixActor {
|
||||
static accepts = {
|
||||
echo: {},
|
||||
getStatus: {},
|
||||
};
|
||||
|
||||
onEcho(payload: { message?: string }) {
|
||||
return {
|
||||
ok: true,
|
||||
message: payload.message ?? null,
|
||||
actor: 'GreeterActor',
|
||||
};
|
||||
}
|
||||
|
||||
onGetStatus() {
|
||||
return {
|
||||
ok: true,
|
||||
actor: 'GreeterActor',
|
||||
mount: 'demo.greeter',
|
||||
};
|
||||
}
|
||||
}
|
||||
@ -0,0 +1,50 @@
|
||||
import { InMemoryBroker, InMemoryTransport, MatrixRuntime } from '@open-matrix/core';
|
||||
|
||||
import { GreeterActor } from './GreeterActor.js';
|
||||
|
||||
interface StandaloneBootContext {
|
||||
readonly root?: string;
|
||||
readonly mount?: string;
|
||||
}
|
||||
|
||||
interface StandaloneRunnerServices {
|
||||
readonly runtime?: MatrixRuntime;
|
||||
}
|
||||
|
||||
function readTrimmedString(value: unknown): string | undefined {
|
||||
if (typeof value !== 'string') return undefined;
|
||||
const trimmed = value.trim();
|
||||
return trimmed.length > 0 ? trimmed : undefined;
|
||||
}
|
||||
|
||||
function requiredStandaloneRoot(requestedRoot: string | undefined, runtime: MatrixRuntime): string {
|
||||
const runtimeRoot = readTrimmedString(runtime.transport.root);
|
||||
const root = requestedRoot ?? runtimeRoot;
|
||||
if (!root) throw new Error('createStandaloneGreeterActor requires bootContext.root or a runtime transport root');
|
||||
return root;
|
||||
}
|
||||
|
||||
export async function createStandaloneGreeterActor(
|
||||
_overrides: Record<string, unknown> = {},
|
||||
services?: StandaloneRunnerServices,
|
||||
_config?: unknown,
|
||||
bootContext: StandaloneBootContext = {},
|
||||
): Promise<{
|
||||
runtime: MatrixRuntime;
|
||||
actor: GreeterActor;
|
||||
root: string;
|
||||
mount: string;
|
||||
}> {
|
||||
const requestedRoot = readTrimmedString(bootContext.root);
|
||||
const runtime = services?.runtime ?? new MatrixRuntime({
|
||||
transport: new InMemoryTransport(new InMemoryBroker(), {
|
||||
name: 'demo.greeter-standalone',
|
||||
...(requestedRoot ? { root: requestedRoot } : {}),
|
||||
}),
|
||||
logging: false,
|
||||
});
|
||||
const root = requiredStandaloneRoot(requestedRoot, runtime);
|
||||
const mount = readTrimmedString(bootContext.mount) ?? 'demo.greeter';
|
||||
const actor = await runtime.createSupervised(GreeterActor, mount);
|
||||
return { runtime, actor, root, mount };
|
||||
}
|
||||
2
examples/standalone-greeter/src/index.ts
Normal file
2
examples/standalone-greeter/src/index.ts
Normal file
@ -0,0 +1,2 @@
|
||||
export { GreeterActor } from './GreeterActor.js';
|
||||
export { createStandaloneGreeterActor } from './create-standalone-GreeterActor.js';
|
||||
11
examples/standalone-greeter/tsconfig.json
Normal file
11
examples/standalone-greeter/tsconfig.json
Normal file
@ -0,0 +1,11 @@
|
||||
{
|
||||
"compilerOptions": {
|
||||
"target": "ES2022",
|
||||
"module": "NodeNext",
|
||||
"moduleResolution": "NodeNext",
|
||||
"strict": true,
|
||||
"skipLibCheck": true,
|
||||
"outDir": "dist"
|
||||
},
|
||||
"include": ["src/**/*.ts"]
|
||||
}
|
||||
@ -9,7 +9,9 @@
|
||||
"build": "pnpm -r --sort --if-present run build",
|
||||
"test": "pnpm -r --sort --if-present run test",
|
||||
"type-check": "pnpm -r --sort --if-present run type-check",
|
||||
"pack:all": "pnpm -r exec pnpm pack",
|
||||
"pack:all": "pnpm --filter './packages/*' -r exec pnpm pack",
|
||||
"demo:standalone": "node examples/standalone-greeter/run-demo.mjs",
|
||||
"demo:hivecast-login": "node examples/hivecast-login/run-demo.mjs",
|
||||
"prove:external-consumer": "node scripts/prove-external-consumer.mjs",
|
||||
"prove:cli-uat": "node scripts/prove-sdk-cli-uat.mjs",
|
||||
"prove": "pnpm run clean && pnpm run build && pnpm run test && pnpm run type-check && pnpm run pack:all"
|
||||
|
||||
10
pnpm-lock.yaml
generated
10
pnpm-lock.yaml
generated
@ -40,6 +40,16 @@ importers:
|
||||
specifier: ^5.7.0
|
||||
version: 5.9.3
|
||||
|
||||
examples/standalone-greeter:
|
||||
dependencies:
|
||||
'@open-matrix/core':
|
||||
specifier: workspace:*
|
||||
version: link:../../packages/core
|
||||
devDependencies:
|
||||
typescript:
|
||||
specifier: ^5.7.0
|
||||
version: 5.9.3
|
||||
|
||||
packages/browser-host:
|
||||
dependencies:
|
||||
'@open-matrix/contracts':
|
||||
|
||||
@ -1,2 +1,3 @@
|
||||
packages:
|
||||
- "packages/*"
|
||||
- "examples/*"
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user